commit e58bf000684bacf0cf23a88be10ed3ab926caef5 Author: MSVSphere Packaging Team Date: Mon Jul 24 14:40:05 2023 +0300 import kmod-redhat-rtw89-5.14.0_284.11.1_dup9.2-1.el9_2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..116fad3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/rtw89-redhat-5.14.0_284.11.1_dup9.2.tar.bz2 diff --git a/.kmod-redhat-rtw89.metadata b/.kmod-redhat-rtw89.metadata new file mode 100644 index 0000000..100d406 --- /dev/null +++ b/.kmod-redhat-rtw89.metadata @@ -0,0 +1 @@ +50cd245c5a9208cf5e19c9f656978fe77fadec76 SOURCES/rtw89-redhat-5.14.0_284.11.1_dup9.2.tar.bz2 diff --git a/SOURCES/0001-wifi-rtw89-8852b-add-BB-and-RF-tables-1-of-2.patch b/SOURCES/0001-wifi-rtw89-8852b-add-BB-and-RF-tables-1-of-2.patch new file mode 100644 index 0000000..e4fae72 --- /dev/null +++ b/SOURCES/0001-wifi-rtw89-8852b-add-BB-and-RF-tables-1-of-2.patch @@ -0,0 +1,13331 @@ +From 291d89874854d07ba2000dd4a4edc2f3b1de0b00 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:21 +0200 +Subject: [PATCH 001/142] wifi: rtw89: 8852b: add BB and RF tables (1 of 2) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit c8b5fc2e1d2f6a11fe2ba82da8b0c39bb379b529 +Author: Ping-Ke Shih +Date: Wed Sep 28 16:43:28 2022 +0800 + + wifi: rtw89: 8852b: add BB and RF tables (1 of 2) + + These tables contain BB and RF parameters that driver will load them into + registers. It also contains TX power according to country, band, rate and + so on. Increasing thermal can cause TX power degraded, so power tracking + tables are defined to compensate TX power. + + Internal version of these tables: + - HALRF_029_00_014 (R32) + - HALBB_027_046_05 + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + .../net/wireless/realtek/rtw89/rtw8852b_table.c | 13249 +++++++++++++++++++ + .../net/wireless/realtek/rtw89/rtw8852b_table.h | 30 + + 2 files changed, 13279 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_table.c + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_table.h + +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 0000000000000..f29bc5d8d5767 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c +@@ -0,0 +1,13249 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2020 Realtek Corporation ++ */ ++ ++#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}, ++}; +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 0000000000000..114337ac9fb00 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.h +@@ -0,0 +1,30 @@ ++/* 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_txpwr_table rtw89_8852b_byr_table; ++extern const struct rtw89_txpwr_track_cfg rtw89_8852b_trk_cfg; ++extern const u8 rtw89_8852b_tx_shape[RTW89_BAND_MAX][RTW89_RS_TX_SHAPE_NUM] ++ [RTW89_REGD_NUM]; ++extern 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]; ++extern 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]; ++extern const s8 rtw89_8852b_txpwr_lmt_ru_2g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_2G_CH_NUM]; ++extern const s8 rtw89_8852b_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] ++ [RTW89_REGD_NUM][RTW89_5G_CH_NUM]; ++ ++#endif +-- +2.13.6 + diff --git a/SOURCES/0002-wifi-rtw89-8852b-add-BB-and-RF-tables-2-of-2.patch b/SOURCES/0002-wifi-rtw89-8852b-add-BB-and-RF-tables-2-of-2.patch new file mode 100644 index 0000000..0ec87f0 --- /dev/null +++ b/SOURCES/0002-wifi-rtw89-8852b-add-BB-and-RF-tables-2-of-2.patch @@ -0,0 +1,9673 @@ +From 847d8a31f374c9ad5e6e1e442fd880d8778b2116 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:21 +0200 +Subject: [PATCH 002/142] wifi: rtw89: 8852b: add BB and RF tables (2 of 2) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3e65a0ae142a97bb9b2e0a988e1ddf55fe289cf0 +Author: Ping-Ke Shih +Date: Wed Sep 28 16:43:29 2022 +0800 + + wifi: rtw89: 8852b: add BB and RF tables (2 of 2) + + These tables contain BB and RF parameters that driver will load them into + registers. It also contains TX power according to country, band, rate and + so on. Increasing thermal can cause TX power degraded, so power tracking + tables are defined to compensate TX power. + + Internal version of these tables: + - HALRF_029_00_014 (R32) + - HALBB_027_046_05 + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + .../net/wireless/realtek/rtw89/rtw8852b_table.c | 9628 ++++++++++++++++++++ + 1 file changed, 9628 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c +index f29bc5d8d5767..a6734965361f7 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c +@@ -13247,3 +13247,9631 @@ static const struct rtw89_reg2_def rtw89_8852b_phy_radiob_regs[] = { + {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}; ++ ++const u8 rtw89_8852b_tx_shape[RTW89_BAND_MAX][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, ++}; ++ ++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] = 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] = 56, ++ [0][0][0][0][RTW89_WW][13] = 76, ++ [0][1][0][0][RTW89_WW][0] = 46, ++ [0][1][0][0][RTW89_WW][1] = 46, ++ [0][1][0][0][RTW89_WW][2] = 46, ++ [0][1][0][0][RTW89_WW][3] = 46, ++ [0][1][0][0][RTW89_WW][4] = 46, ++ [0][1][0][0][RTW89_WW][5] = 46, ++ [0][1][0][0][RTW89_WW][6] = 46, ++ [0][1][0][0][RTW89_WW][7] = 46, ++ [0][1][0][0][RTW89_WW][8] = 46, ++ [0][1][0][0][RTW89_WW][9] = 46, ++ [0][1][0][0][RTW89_WW][10] = 46, ++ [0][1][0][0][RTW89_WW][11] = 46, ++ [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] = 58, ++ [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] = 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] = 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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 58, ++ [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] = 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] = 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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 46, ++ [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] = 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] = 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] = 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] = 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] = 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] = 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, ++}; ++ ++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] = 78, ++ [0][0][1][0][RTW89_WW][50] = 78, ++ [0][0][1][0][RTW89_WW][52] = 78, ++ [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] = 56, ++ [0][1][1][0][RTW89_WW][50] = 56, ++ [0][1][1][0][RTW89_WW][52] = 56, ++ [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] = 58, ++ [0][1][2][0][RTW89_WW][50] = 58, ++ [0][1][2][0][RTW89_WW][52] = 58, ++ [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] = 58, ++ [0][1][2][1][RTW89_WW][50] = 58, ++ [0][1][2][1][RTW89_WW][52] = 58, ++ [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] = 68, ++ [1][1][2][0][RTW89_WW][51] = 66, ++ [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] = 68, ++ [1][1][2][1][RTW89_WW][51] = 66, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 60, ++ [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] = 60, ++ [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] = 60, ++ [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] = 60, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 48, ++ [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] = 48, ++ [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] = 48, ++ [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] = 48, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 36, ++ [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] = 36, ++ [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] = 36, ++ [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] = 36, ++ [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] = 72, ++ [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] = 72, ++ [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] = 72, ++ [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] = 76, ++ [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] = 76, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 70, ++ [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] = 74, ++ [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] = 127, ++ [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] = 127, ++ [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] = 70, ++ [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] = 74, ++ [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] = 127, ++ [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] = 127, ++ [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] = 70, ++ [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] = 74, ++ [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] = 127, ++ [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] = 127, ++ [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] = 70, ++ [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] = 127, ++ [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] = 70, ++ [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] = 127, ++ [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] = 70, ++ [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] = 127, ++ [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, ++}; ++ ++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, ++}; ++ ++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] = 0, ++ [0][1][RTW89_WW][2] = 4, ++ [0][1][RTW89_WW][4] = 0, ++ [0][1][RTW89_WW][6] = 0, ++ [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] = 20, ++ [0][1][RTW89_WW][50] = 20, ++ [0][1][RTW89_WW][52] = 20, ++ [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] = 32, ++ [1][1][RTW89_WW][50] = 32, ++ [1][1][RTW89_WW][52] = 32, ++ [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] = 44, ++ [2][1][RTW89_WW][50] = 44, ++ [2][1][RTW89_WW][52] = 44, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 0, ++ [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] = 0, ++ [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] = 0, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 74, ++ [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] = 74, ++ [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] = 74, ++ [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] = 74, ++ [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] = 74, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 76, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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] = 64, ++ [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] = 64, ++ [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] = 64, ++ [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] = 64, ++ [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] = 64, ++ [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] = 127, ++ [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] = 127, ++ [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] = 127, ++ [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 */ ++}; ++ ++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_txpwr_track_cfg rtw89_8852b_trk_cfg = { ++ .delta_swingidx_5gb_n = _txpwr_track_delta_swingidx_5gb_n, ++ .delta_swingidx_5gb_p = _txpwr_track_delta_swingidx_5gb_p, ++ .delta_swingidx_5ga_n = _txpwr_track_delta_swingidx_5ga_n, ++ .delta_swingidx_5ga_p = _txpwr_track_delta_swingidx_5ga_p, ++ .delta_swingidx_2gb_n = _txpwr_track_delta_swingidx_2gb_n, ++ .delta_swingidx_2gb_p = _txpwr_track_delta_swingidx_2gb_p, ++ .delta_swingidx_2ga_n = _txpwr_track_delta_swingidx_2ga_n, ++ .delta_swingidx_2ga_p = _txpwr_track_delta_swingidx_2ga_p, ++ .delta_swingidx_2g_cck_b_n = _txpwr_track_delta_swingidx_2g_cck_b_n, ++ .delta_swingidx_2g_cck_b_p = _txpwr_track_delta_swingidx_2g_cck_b_p, ++ .delta_swingidx_2g_cck_a_n = _txpwr_track_delta_swingidx_2g_cck_a_n, ++ .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, ++}; +-- +2.13.6 + diff --git a/SOURCES/0003-wifi-rtw89-8852b-add-tables-for-RFK.patch b/SOURCES/0003-wifi-rtw89-8852b-add-tables-for-RFK.patch new file mode 100644 index 0000000..8e7fc1c --- /dev/null +++ b/SOURCES/0003-wifi-rtw89-8852b-add-tables-for-RFK.patch @@ -0,0 +1,901 @@ +From be462322de77a0690eda74a1a631c3706a787469 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:21 +0200 +Subject: [PATCH 003/142] wifi: rtw89: 8852b: add tables for RFK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 2b379eb443e2a4bd6fb2cbd300e12aeff45cff57 +Author: Ping-Ke Shih +Date: Wed Sep 28 16:43:30 2022 +0800 + + wifi: rtw89: 8852b: add tables for RFK + + These tables are used by RFK to assist to configure PHY and RF registers. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + .../wireless/realtek/rtw89/rtw8852b_rfk_table.c | 794 +++++++++++++++++++++ + .../wireless/realtek/rtw89/rtw8852b_rfk_table.h | 62 ++ + 2 files changed, 856 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.c + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk_table.h + +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 0000000000000..0b8a210bb10b7 +--- /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 0000000000000..b4d6e9851ff99 +--- /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 +-- +2.13.6 + diff --git a/SOURCES/0004-wifi-rtw89-phy-make-generic-txpwr-setting-functions.patch b/SOURCES/0004-wifi-rtw89-phy-make-generic-txpwr-setting-functions.patch new file mode 100644 index 0000000..f0a24de --- /dev/null +++ b/SOURCES/0004-wifi-rtw89-phy-make-generic-txpwr-setting-functions.patch @@ -0,0 +1,699 @@ +From 5f1454c2fccfd32e630307f83558b11787376c37 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:21 +0200 +Subject: [PATCH 004/142] wifi: rtw89: phy: make generic txpwr setting + functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 9b43bd1ac0a8e29b678768f93645cc1b39571278 +Author: Zong-Zhe Yang +Date: Wed Sep 28 16:43:31 2022 +0800 + + wifi: rtw89: phy: make generic txpwr setting functions + + Previously, we thought control registers or setting things for TX power + series may change according to chip. So, setting functions are implemented + chip by chip. However, until now, the functions keep the same among chips, + at least 8852A, 8852C, and 8852B. There is a sufficient number of chips to + share generic setting functions. So, we now remake them including TX power + by rate, TX power offset, TX power limit, and TX power limit RU as generic + ones in phy.c. + + Besides, there are some code refinements in the generic ones, but almost + all of the logic doesn't change. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 4 + + drivers/net/wireless/realtek/rtw89/phy.c | 167 ++++++++++++++++++++++++-- + drivers/net/wireless/realtek/rtw89/phy.h | 25 ++-- + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 145 +--------------------- + drivers/net/wireless/realtek/rtw89/rtw8852a.h | 1 - + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 145 +--------------------- + drivers/net/wireless/realtek/rtw89/rtw8852c.h | 1 - + 7 files changed, 184 insertions(+), 304 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index db041b32a8c2c..be39d2200e054 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -490,6 +490,8 @@ enum rtw89_bandwidth_section_num { + RTW89_BW80_SEC_NUM = 2, + }; + ++#define RTW89_TXPWR_LMT_PAGE_SIZE 40 ++ + struct rtw89_txpwr_limit { + s8 cck_20m[RTW89_BF_NUM]; + s8 cck_40m[RTW89_BF_NUM]; +@@ -504,6 +506,8 @@ struct rtw89_txpwr_limit { + + #define RTW89_RU_SEC_NUM 8 + ++#define RTW89_TXPWR_LMT_RU_PAGE_SIZE 24 ++ + struct rtw89_txpwr_limit_ru { + s8 ru26[RTW89_RU_SEC_NUM]; + s8 ru52[RTW89_RU_SEC_NUM]; +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index c894a2b614eb1..ac3aa1da5bd1b 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -1443,23 +1443,21 @@ void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev, + } + EXPORT_SYMBOL(rtw89_phy_write_reg3_tbl); + +-const u8 rtw89_rs_idx_max[] = { ++static const u8 rtw89_rs_idx_max[] = { + [RTW89_RS_CCK] = RTW89_RATE_CCK_MAX, + [RTW89_RS_OFDM] = RTW89_RATE_OFDM_MAX, + [RTW89_RS_MCS] = RTW89_RATE_MCS_MAX, + [RTW89_RS_HEDCM] = RTW89_RATE_HEDCM_MAX, + [RTW89_RS_OFFSET] = RTW89_RATE_OFFSET_MAX, + }; +-EXPORT_SYMBOL(rtw89_rs_idx_max); + +-const u8 rtw89_rs_nss_max[] = { ++static const u8 rtw89_rs_nss_max[] = { + [RTW89_RS_CCK] = 1, + [RTW89_RS_OFDM] = 1, + [RTW89_RS_MCS] = RTW89_NSS_MAX, + [RTW89_RS_HEDCM] = RTW89_NSS_HEDCM_MAX, + [RTW89_RS_OFFSET] = 1, + }; +-EXPORT_SYMBOL(rtw89_rs_nss_max); + + static const u8 _byr_of_rs[] = { + [RTW89_RS_CCK] = offsetof(struct rtw89_txpwr_byrate, cck), +@@ -1501,6 +1499,7 @@ EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrate); + (txpwr_rf) >> (__c->txpwr_factor_rf - __c->txpwr_factor_mac); \ + }) + ++static + s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, + const struct rtw89_rate_desc *rate_desc) + { +@@ -1523,7 +1522,6 @@ s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, + + return _phy_txpwr_rf_to_mac(rtwdev, byr[idx]); + } +-EXPORT_SYMBOL(rtw89_phy_read_txpwr_byrate); + + static u8 rtw89_channel_6g_to_idx(struct rtw89_dev *rtwdev, u8 channel_6g) + { +@@ -1783,6 +1781,7 @@ static void rtw89_phy_fill_txpwr_limit_160m(struct rtw89_dev *rtwdev, + lmt->mcs_40m_2p5[i] = min_t(s8, val_2p5_n[i], val_2p5_p[i]); + } + ++static + void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + struct rtw89_txpwr_limit *lmt, +@@ -1813,7 +1812,6 @@ void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, + break; + } + } +-EXPORT_SYMBOL(rtw89_phy_fill_txpwr_limit); + + static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band, + u8 ru, u8 ntx, u8 ch) +@@ -1962,6 +1960,7 @@ rtw89_phy_fill_txpwr_limit_ru_160m(struct rtw89_dev *rtwdev, + } + } + ++static + void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + struct rtw89_txpwr_limit_ru *lmt_ru, +@@ -1992,7 +1991,161 @@ void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, + break; + } + } +-EXPORT_SYMBOL(rtw89_phy_fill_txpwr_limit_ru); ++ ++void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx) ++{ ++ 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_max[RTW89_RS_CCK] % 4); ++ BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_OFDM] % 4); ++ BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_MCS] % 4); ++ BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_HEDCM] % 4); ++ ++ addr = R_AX_PWR_BY_RATE; ++ for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { ++ for (i = 0; i < ARRAY_SIZE(rs); i++) { ++ if (cur.nss >= rtw89_rs_nss_max[rs[i]]) ++ continue; ++ ++ cur.rs = rs[i]; ++ for (cur.idx = 0; cur.idx < rtw89_rs_idx_max[rs[i]]; ++ cur.idx++) { ++ v[cur.idx % 4] = ++ rtw89_phy_read_txpwr_byrate(rtwdev, ++ band, ++ &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; ++ } ++ } ++ } ++} ++EXPORT_SYMBOL(rtw89_phy_set_txpwr_byrate); ++ ++void rtw89_phy_set_txpwr_offset(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_MAX] = {}; ++ u32 val; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); ++ ++ for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) ++ v[desc.idx] = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc); ++ ++ BUILD_BUG_ON(RTW89_RATE_OFFSET_MAX != 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); ++} ++EXPORT_SYMBOL(rtw89_phy_set_txpwr_offset); ++ ++void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx) ++{ ++ struct rtw89_txpwr_limit 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) != ++ RTW89_TXPWR_LMT_PAGE_SIZE); ++ ++ addr = R_AX_PWR_LMT; ++ for (i = 0; i < RTW89_NTX_NUM; i++) { ++ rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt, i); ++ ++ ptr = (s8 *)&lmt; ++ for (j = 0; j < RTW89_TXPWR_LMT_PAGE_SIZE; ++ 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); ++ } ++ } ++} ++EXPORT_SYMBOL(rtw89_phy_set_txpwr_limit); ++ ++void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx) ++{ ++ struct rtw89_txpwr_limit_ru 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) != ++ RTW89_TXPWR_LMT_RU_PAGE_SIZE); ++ ++ addr = R_AX_PWR_RU_LMT; ++ for (i = 0; i < RTW89_NTX_NUM; i++) { ++ rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru, i); ++ ++ ptr = (s8 *)&lmt_ru; ++ for (j = 0; j < RTW89_TXPWR_LMT_RU_PAGE_SIZE; ++ 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); ++ } ++ } ++} ++EXPORT_SYMBOL(rtw89_phy_set_txpwr_limit_ru); + + struct rtw89_phy_iter_ra_data { + struct rtw89_dev *rtwdev; +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +index ee3bc5e111e16..030a7c904a28d 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.h ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -317,9 +317,6 @@ struct rtw89_nbi_reg_def { + struct rtw89_reg_def notch2_en; + }; + +-extern const u8 rtw89_rs_idx_max[RTW89_RS_MAX]; +-extern const u8 rtw89_rs_nss_max[RTW89_RS_MAX]; +- + static inline void rtw89_phy_write8(struct rtw89_dev *rtwdev, + u32 addr, u8 data) + { +@@ -460,18 +457,20 @@ void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, + u32 data, enum rtw89_phy_idx phy_idx); + void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev, + const struct rtw89_txpwr_table *tbl); +-s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, +- const struct rtw89_rate_desc *rate_desc); +-void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- struct rtw89_txpwr_limit *lmt, +- u8 ntx); +-void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- struct rtw89_txpwr_limit_ru *lmt_ru, +- u8 ntx); + s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, + u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch); ++void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx); ++void rtw89_phy_set_txpwr_offset(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx); ++void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx); ++void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx); + void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta); + void rtw89_phy_ra_update(struct rtw89_dev *rtwdev); + void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 7841476803535..5678683ec02a5 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -1410,151 +1410,14 @@ static void rtw8852a_set_txpwr_ref(struct rtw89_dev *rtwdev, + phy_idx); + } + +-static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- enum rtw89_phy_idx phy_idx) +-{ +- u8 band = chan->band_type; +- u8 ch = chan->channel; +- static const u8 rs[] = { +- RTW89_RS_CCK, +- RTW89_RS_OFDM, +- RTW89_RS_MCS, +- RTW89_RS_HEDCM, +- }; +- s8 tmp; +- u8 i, j; +- u32 val, shf, addr = R_AX_PWR_BY_RATE; +- struct rtw89_rate_desc cur; +- +- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, +- "[TXPWR] set txpwr byrate with ch=%d\n", ch); +- +- for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { +- for (i = 0; i < ARRAY_SIZE(rs); i++) { +- if (cur.nss >= rtw89_rs_nss_max[rs[i]]) +- continue; +- +- val = 0; +- cur.rs = rs[i]; +- +- for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) { +- cur.idx = j; +- shf = (j % 4) * 8; +- tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band, +- &cur); +- val |= (tmp << shf); +- +- if ((j + 1) % 4) +- continue; +- +- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); +- val = 0; +- addr += 4; +- } +- } +- } +-} +- +-static void rtw8852a_set_txpwr_offset(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- enum rtw89_phy_idx phy_idx) +-{ +- u8 band = chan->band_type; +- struct rtw89_rate_desc desc = { +- .nss = RTW89_NSS_1, +- .rs = RTW89_RS_OFFSET, +- }; +- u32 val = 0; +- s8 v; +- +- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); +- +- for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) { +- v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc); +- val |= ((v & 0xf) << (4 * desc.idx)); +- } +- +- rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, +- GENMASK(19, 0), val); +-} +- +-static void rtw8852a_set_txpwr_limit(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- enum rtw89_phy_idx phy_idx) +-{ +-#define __MAC_TXPWR_LMT_PAGE_SIZE 40 +- u8 ch = chan->channel; +- u8 bw = chan->band_width; +- struct rtw89_txpwr_limit lmt[NTX_NUM_8852A]; +- u32 addr, val; +- const s8 *ptr; +- u8 i, j; +- +- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, +- "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); +- +- for (i = 0; i < NTX_NUM_8852A; i++) { +- rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i); +- +- for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) { +- addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i; +- ptr = (s8 *)&lmt[i] + j; +- +- 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); +- } +- } +-#undef __MAC_TXPWR_LMT_PAGE_SIZE +-} +- +-static void rtw8852a_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- enum rtw89_phy_idx phy_idx) +-{ +-#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24 +- u8 ch = chan->channel; +- u8 bw = chan->band_width; +- struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852A]; +- u32 addr, val; +- const s8 *ptr; +- u8 i, j; +- +- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, +- "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); +- +- for (i = 0; i < NTX_NUM_8852A; i++) { +- rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i); +- +- for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) { +- addr = R_AX_PWR_RU_LMT + j + +- __MAC_TXPWR_LMT_RU_PAGE_SIZE * i; +- ptr = (s8 *)&lmt_ru[i] + j; +- +- 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); +- } +- } +- +-#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE +-} +- + static void rtw8852a_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) + { +- rtw8852a_set_txpwr_byrate(rtwdev, chan, phy_idx); +- rtw8852a_set_txpwr_offset(rtwdev, chan, phy_idx); +- rtw8852a_set_txpwr_limit(rtwdev, chan, phy_idx); +- rtw8852a_set_txpwr_limit_ru(rtwdev, chan, 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, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.h b/drivers/net/wireless/realtek/rtw89/rtw8852a.h +index fcff1194c0096..ea82fed7b7bec 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.h +@@ -8,7 +8,6 @@ + #include "core.h" + + #define RF_PATH_NUM_8852A 2 +-#define NTX_NUM_8852A 2 + + enum rtw8852a_pmac_mode { + NONE_TEST, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index 67653b3e1a356..a6a9fe3d0b565 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2006,75 +2006,6 @@ static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev, + phy_idx); + } + +-static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- enum rtw89_phy_idx phy_idx) +-{ +- u8 band = chan->band_type; +- u8 ch = chan->channel; +- static const u8 rs[] = { +- RTW89_RS_CCK, +- RTW89_RS_OFDM, +- RTW89_RS_MCS, +- RTW89_RS_HEDCM, +- }; +- s8 tmp; +- u8 i, j; +- u32 val, shf, addr = R_AX_PWR_BY_RATE; +- struct rtw89_rate_desc cur; +- +- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, +- "[TXPWR] set txpwr byrate with ch=%d\n", ch); +- +- for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { +- for (i = 0; i < ARRAY_SIZE(rs); i++) { +- if (cur.nss >= rtw89_rs_nss_max[rs[i]]) +- continue; +- +- val = 0; +- cur.rs = rs[i]; +- +- for (j = 0; j < rtw89_rs_idx_max[rs[i]]; j++) { +- cur.idx = j; +- shf = (j % 4) * 8; +- tmp = rtw89_phy_read_txpwr_byrate(rtwdev, band, +- &cur); +- val |= (tmp << shf); +- +- if ((j + 1) % 4) +- continue; +- +- rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val); +- val = 0; +- addr += 4; +- } +- } +- } +-} +- +-static void rtw8852c_set_txpwr_offset(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- enum rtw89_phy_idx phy_idx) +-{ +- u8 band = chan->band_type; +- struct rtw89_rate_desc desc = { +- .nss = RTW89_NSS_1, +- .rs = RTW89_RS_OFFSET, +- }; +- u32 val = 0; +- s8 v; +- +- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n"); +- +- for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_MAX; desc.idx++) { +- v = rtw89_phy_read_txpwr_byrate(rtwdev, band, &desc); +- val |= ((v & 0xf) << (4 * desc.idx)); +- } +- +- rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL, +- GENMASK(19, 0), val); +-} +- + static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + u8 tx_shape_idx, + enum rtw89_phy_idx phy_idx) +@@ -2147,83 +2078,15 @@ static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev, + tx_shape_ofdm); + } + +-static void rtw8852c_set_txpwr_limit(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- enum rtw89_phy_idx phy_idx) +-{ +-#define __MAC_TXPWR_LMT_PAGE_SIZE 40 +- u8 ch = chan->channel; +- u8 bw = chan->band_width; +- struct rtw89_txpwr_limit lmt[NTX_NUM_8852C]; +- u32 addr, val; +- const s8 *ptr; +- u8 i, j; +- +- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, +- "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw); +- +- for (i = 0; i < NTX_NUM_8852C; i++) { +- rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt[i], i); +- +- for (j = 0; j < __MAC_TXPWR_LMT_PAGE_SIZE; j += 4) { +- addr = R_AX_PWR_LMT + j + __MAC_TXPWR_LMT_PAGE_SIZE * i; +- ptr = (s8 *)&lmt[i] + j; +- +- 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); +- } +- } +-#undef __MAC_TXPWR_LMT_PAGE_SIZE +-} +- +-static void rtw8852c_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, +- const struct rtw89_chan *chan, +- enum rtw89_phy_idx phy_idx) +-{ +-#define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24 +- u8 ch = chan->channel; +- u8 bw = chan->band_width; +- struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C]; +- u32 addr, val; +- const s8 *ptr; +- u8 i, j; +- +- rtw89_debug(rtwdev, RTW89_DBG_TXPWR, +- "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw); +- +- for (i = 0; i < NTX_NUM_8852C; i++) { +- rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru[i], i); +- +- for (j = 0; j < __MAC_TXPWR_LMT_RU_PAGE_SIZE; j += 4) { +- addr = R_AX_PWR_RU_LMT + j + +- __MAC_TXPWR_LMT_RU_PAGE_SIZE * i; +- ptr = (s8 *)&lmt_ru[i] + j; +- +- 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); +- } +- } +- +-#undef __MAC_TXPWR_LMT_RU_PAGE_SIZE +-} +- + static void rtw8852c_set_txpwr(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) + { +- rtw8852c_set_txpwr_byrate(rtwdev, chan, phy_idx); +- rtw8852c_set_txpwr_offset(rtwdev, chan, 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); +- rtw8852c_set_txpwr_limit(rtwdev, chan, phy_idx); +- rtw8852c_set_txpwr_limit_ru(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 rtw8852c_set_txpwr_ctrl(struct rtw89_dev *rtwdev, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.h b/drivers/net/wireless/realtek/rtw89/rtw8852c.h +index 558dd0f048f2b..ac642808a81ff 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.h +@@ -9,7 +9,6 @@ + + #define RF_PATH_NUM_8852C 2 + #define BB_PATH_NUM_8852C 2 +-#define NTX_NUM_8852C 2 + + struct rtw8852c_u_efuse { + u8 rsvd[0x38]; +-- +2.13.6 + diff --git a/SOURCES/0005-wifi-rtw89-debug-txpwr_table-considers-sign.patch b/SOURCES/0005-wifi-rtw89-debug-txpwr_table-considers-sign.patch new file mode 100644 index 0000000..5d9b12d --- /dev/null +++ b/SOURCES/0005-wifi-rtw89-debug-txpwr_table-considers-sign.patch @@ -0,0 +1,71 @@ +From 8095bfd12e379fa826d8ca4e8f12ea17f6e0c04b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:21 +0200 +Subject: [PATCH 005/142] wifi: rtw89: debug: txpwr_table considers sign +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit b902161645879ac820dfbb561667cd08be569538 +Author: Zong-Zhe Yang +Date: Wed Sep 28 16:43:32 2022 +0800 + + wifi: rtw89: debug: txpwr_table considers sign + + Previously, value of each field is just shown as unsigned. + Now, we start to show them with sign to make things more intuitive + during debugging. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/debug.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +index 730e83d54257f..f584fa57c82fa 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.c ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -464,7 +464,7 @@ static const struct txpwr_map __txpwr_map_lmt_ru = { + }; + + static u8 __print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent, +- const u8 *buf, const u8 cur) ++ const s8 *buf, const u8 cur) + { + char *fmt; + +@@ -493,8 +493,9 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev, + const struct txpwr_map *map) + { + u8 fct = rtwdev->chip->txpwr_factor_mac; +- u8 *buf, cur, i; + u32 val, addr; ++ s8 *buf, tmp; ++ u8 cur, i; + int ret; + + buf = vzalloc(map->addr_to - map->addr_from + 4); +@@ -507,8 +508,11 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev, + val = MASKDWORD; + + cur = addr - map->addr_from; +- for (i = 0; i < 4; i++, val >>= 8) +- buf[cur + i] = FIELD_GET(MASKBYTE0, val) >> fct; ++ for (i = 0; i < 4; i++, val >>= 8) { ++ /* signed 7 bits, and reserved BIT(7) */ ++ tmp = sign_extend32(val, 6); ++ buf[cur + i] = tmp >> fct; ++ } + } + + for (cur = 0, i = 0; i < map->size; i++) +-- +2.13.6 + diff --git a/SOURCES/0006-wifi-rtw89-8852b-add-chip_ops-set_txpwr.patch b/SOURCES/0006-wifi-rtw89-8852b-add-chip_ops-set_txpwr.patch new file mode 100644 index 0000000..bc39490 --- /dev/null +++ b/SOURCES/0006-wifi-rtw89-8852b-add-chip_ops-set_txpwr.patch @@ -0,0 +1,328 @@ +From f3719ccfd7a42d2da914ce04ca3d17da47fa3d9c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:22 +0200 +Subject: [PATCH 006/142] wifi: rtw89: 8852b: add chip_ops::set_txpwr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 08484e1f6e6fd670c722756baea4833436ca8fb5 +Author: Ping-Ke Shih +Date: Wed Sep 28 16:43:33 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops::set_txpwr + + This chip_ops is to set TX power according to country, channel, rate and + so on. Since shared code is used to configure TX power, we only implement + specific part in this patch. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 1 + + drivers/net/wireless/realtek/rtw89/reg.h | 5 + + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 200 +++++++++++++++++++++++++- + drivers/net/wireless/realtek/rtw89/rtw8852b.h | 13 ++ + 4 files changed, 218 insertions(+), 1 deletion(-) + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b.h + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 077fddc5fa1ea..0be7d2ac59397 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -4817,6 +4817,7 @@ int rtw89_mac_read_xtal_si(struct rtw89_dev *rtwdev, u8 offset, u8 *val) + + return 0; + } ++EXPORT_SYMBOL(rtw89_mac_read_xtal_si); + + static + void rtw89_mac_pkt_drop_sta(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index ca20bb024b407..6809ff812abb7 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -2991,6 +2991,7 @@ + + #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) + +@@ -3770,6 +3771,7 @@ + #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_TXPATH_SEL 0x458C +@@ -4003,6 +4005,9 @@ + #define B_TXPWRB_VAL GENMASK(27, 19) + #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_DPD_OFT_ADDR 0x5804 + #define B_DPD_OFT_ADDR GENMASK(31, 27) + #define R_TXPWRB_H 0x580c +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 9f9908418ee4e..ec6833080b80a 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -2,9 +2,14 @@ + /* Copyright(c) 2019-2022 Realtek Corporation + */ + +-#include "core.h" ++#include "coex.h" ++#include "fw.h" + #include "mac.h" ++#include "phy.h" + #include "reg.h" ++#include "rtw8852b.h" ++#include "rtw8852b_table.h" ++#include "txrx.h" + + static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6, +@@ -19,6 +24,195 @@ static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { + NULL}, + }; + ++static u32 rtw8852b_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 = 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 FIELD_PREP(B_DPD_TSSI_CW, tssi_ofst_cw) | ++ FIELD_PREP(B_DPD_PWR_CW, pwr_cw) | ++ FIELD_PREP(B_DPD_REF, ref); ++} ++ ++static void rtw8852b_set_txpwr_ref(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ static const u32 addr[RF_PATH_NUM_8852B] = {0x5800, 0x7800}; ++ 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 = rtw8852b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_ofdm); ++ ++ for (i = 0; i < RF_PATH_NUM_8852B; 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 = rtw8852b_bb_cal_txpwr_ref(rtwdev, phy_idx, ref_cck); ++ ++ for (i = 0; i < RF_PATH_NUM_8852B; i++) ++ rtw89_phy_write32_idx(rtwdev, addr[i] + ofst_cck, mask, val, ++ phy_idx); ++} ++ ++static void rtw8852b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, ++ 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); ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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 rtw8852b_set_tx_shape(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u8 band = chan->band_type; ++ u8 regd = rtw89_regd_get(rtwdev, band); ++ u8 tx_shape_cck = rtw89_8852b_tx_shape[band][RTW89_RS_CCK][regd]; ++ u8 tx_shape_ofdm = rtw89_8852b_tx_shape[band][RTW89_RS_OFDM][regd]; ++ ++ if (band == RTW89_BAND_2G) ++ rtw8852b_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); ++ ++ rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG, ++ tx_shape_ofdm); ++} ++ ++static void rtw8852b_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); ++ rtw8852b_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 rtw8852b_set_txpwr_ctrl(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ rtw8852b_set_txpwr_ref(rtwdev, phy_idx); ++} ++ ++static ++void rtw8852b_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(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(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(R_AX_PWR_UL_TB_2T, mac_idx); ++ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); ++} ++ ++static int ++rtw8852b_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; ++ ++ rtw8852b_set_txpwr_ul_tb_offset(rtwdev, 0, phy_idx == RTW89_PHY_1 ? ++ RTW89_MAC_1 : RTW89_MAC_0); ++ ++ return 0; ++} ++ + static int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) + { + int ret; +@@ -75,10 +269,14 @@ static int rtw8852b_mac_disable_bb_rf(struct rtw89_dev *rtwdev) + static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .enable_bb_rf = rtw8852b_mac_enable_bb_rf, + .disable_bb_rf = rtw8852b_mac_disable_bb_rf, ++ .set_txpwr = rtw8852b_set_txpwr, ++ .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, ++ .init_txpwr_unit = rtw8852b_init_txpwr_unit, + }; + + const struct rtw89_chip_info rtw8852b_chip_info = { + .chip_id = RTL8852B, ++ .ops = &rtw8852b_chip_ops, + .fifo_size = 196608, + .dle_scc_rsvd_size = 98304, + .dle_mem = rtw8852b_dle_mem_pcie, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.h b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +new file mode 100644 +index 0000000000000..a5ff269752a30 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +@@ -0,0 +1,13 @@ ++/* 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 ++ ++#endif +-- +2.13.6 + diff --git a/SOURCES/0007-wifi-rtw89-8852b-add-chip_ops-to-read-efuse.patch b/SOURCES/0007-wifi-rtw89-8852b-add-chip_ops-to-read-efuse.patch new file mode 100644 index 0000000..ad1942c --- /dev/null +++ b/SOURCES/0007-wifi-rtw89-8852b-add-chip_ops-to-read-efuse.patch @@ -0,0 +1,248 @@ +From f3987c9e9f194c32ce9d9581f7ff86012c88031f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:22 +0200 +Subject: [PATCH 007/142] wifi: rtw89: 8852b: add chip_ops to read efuse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 132dc4fe5b587c0a62fc90d78e7413944fa06669 +Author: Ping-Ke Shih +Date: Wed Sep 28 16:43:34 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops to read efuse + + efuse stores individual data about a chip itself, such as MAC address, + country code, RF and crystal calibration data, and so on. Define a struct + to help access efuse content, and copy them into a common struct. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-8-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 106 ++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b.h | 75 ++++++++++++++++++ + 2 files changed, 181 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index ec6833080b80a..b80102b1dd7fd 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -24,6 +24,105 @@ static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { + NULL}, + }; + ++static void rtw8852be_efuse_parsing(struct rtw89_efuse *efuse, ++ struct rtw8852b_efuse *map) ++{ ++ ether_addr_copy(efuse->addr, map->e.mac_addr); ++ efuse->rfe_type = map->rfe_type; ++ efuse->xtal_cap = map->xtal_k; ++} ++ ++static void rtw8852b_efuse_parsing_tssi(struct rtw89_dev *rtwdev, ++ struct rtw8852b_efuse *map) ++{ ++ struct rtw89_tssi_info *tssi = &rtwdev->tssi; ++ struct rtw8852b_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_8852B; 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(FIELD_GET(GENMASK(7, 4), data), 3); ++ if (low) ++ *low = sign_extend32(FIELD_GET(GENMASK(3, 0), data), 3); ++ ++ return data != 0xff; ++} ++ ++static void rtw8852b_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev, ++ struct rtw8852b_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 rtw8852b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map) ++{ ++ struct rtw89_efuse *efuse = &rtwdev->efuse; ++ struct rtw8852b_efuse *map; ++ ++ map = (struct rtw8852b_efuse *)log_map; ++ ++ efuse->country_code[0] = map->country_code[0]; ++ efuse->country_code[1] = map->country_code[1]; ++ rtw8852b_efuse_parsing_tssi(rtwdev, map); ++ rtw8852b_efuse_parsing_gain_offset(rtwdev, map); ++ ++ switch (rtwdev->hci.type) { ++ case RTW89_HCI_TYPE_PCIE: ++ rtw8852be_efuse_parsing(efuse, map); ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); ++ ++ return 0; ++} ++ + static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 ref) + { +@@ -269,6 +368,7 @@ static int rtw8852b_mac_disable_bb_rf(struct rtw89_dev *rtwdev) + static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .enable_bb_rf = rtw8852b_mac_enable_bb_rf, + .disable_bb_rf = rtw8852b_mac_disable_bb_rf, ++ .read_efuse = rtw8852b_read_efuse, + .set_txpwr = rtw8852b_set_txpwr, + .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852b_init_txpwr_unit, +@@ -280,6 +380,12 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .fifo_size = 196608, + .dle_scc_rsvd_size = 98304, + .dle_mem = rtw8852b_dle_mem_pcie, ++ .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, + .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), +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.h b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +index a5ff269752a30..578fe55b66957 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +@@ -10,4 +10,79 @@ + #define RF_PATH_NUM_8852B 2 + #define BB_PATH_NUM_8852B 2 + ++struct rtw8852b_u_efuse { ++ u8 rsvd[0x88]; ++ u8 mac_addr[ETH_ALEN]; ++}; ++ ++struct rtw8852b_e_efuse { ++ u8 mac_addr[ETH_ALEN]; ++}; ++ ++struct rtw8852b_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 rtw8852b_efuse { ++ u8 rsvd[0x210]; ++ struct rtw8852b_tssi_offset path_a_tssi; ++ u8 rsvd1[10]; ++ struct rtw8852b_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 rtw8852b_u_efuse u; ++ struct rtw8852b_e_efuse e; ++ }; ++} __packed; ++ + #endif +-- +2.13.6 + diff --git a/SOURCES/0008-wifi-rtw89-8852b-add-chip_ops-to-read-phy-cap.patch b/SOURCES/0008-wifi-rtw89-8852b-add-chip_ops-to-read-phy-cap.patch new file mode 100644 index 0000000..d2f47af --- /dev/null +++ b/SOURCES/0008-wifi-rtw89-8852b-add-chip_ops-to-read-phy-cap.patch @@ -0,0 +1,273 @@ +From fe46e3c810d0c4267e9c4e7d097bb7205b5ca9b6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:22 +0200 +Subject: [PATCH 008/142] wifi: rtw89: 8852b: add chip_ops to read phy cap +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 134cf7c01517d5cfaab940cacbb41525659de5f6 +Author: Ping-Ke Shih +Date: Wed Sep 28 16:43:35 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops to read phy cap + + This efuse region is to store PHY calibration, and it is a separated region + from the region that stores MAC address. Then, use these data to configure + via chip_ops::power_trim that is a calibration mechanism of TX power. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-9-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 4 + + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 184 ++++++++++++++++++++++++++ + 2 files changed, 188 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index be39d2200e054..51af91b30fc4d 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -84,6 +84,7 @@ enum rtw89_subband { + RTW89_CH_6G_BAND_IDX7, /* Ultra-high */ + + RTW89_SUBBAND_NR, ++ RTW89_SUBBAND_2GHZ_5GHZ_NR = RTW89_CH_5G_BAND_4 + 1, + }; + + enum rtw89_gain_offset { +@@ -2196,6 +2197,7 @@ struct rtw89_sta { + + struct rtw89_efuse { + bool valid; ++ bool power_k_valid; + u8 xtal_cap; + u8 addr[ETH_ALEN]; + u8 rfe_type; +@@ -3425,8 +3427,10 @@ struct rtw89_phy_bb_gain_info { + + struct rtw89_phy_efuse_gain { + bool offset_valid; ++ bool comp_valid; + s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */ + s8 offset_base[RTW89_PHY_MAX]; /* S(8, 4) */ ++ s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ + }; + + struct rtw89_dev { +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index b80102b1dd7fd..e9bcea35a72a2 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -123,6 +123,186 @@ static int rtw8852b_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map) + return 0; + } + ++static void rtw8852b_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 rtw8852b_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_8852B] = {0x5D6, 0x5AB}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ bool pg = false; ++ u32 ofst; ++ u8 i, j; ++ ++ for (i = 0; i < RF_PATH_NUM_8852B; 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_8852B; 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 rtw8852b_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_8852B] = {0x5DF, 0x5DC}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ u8 i; ++ ++ for (i = 0; i < RF_PATH_NUM_8852B; 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 rtw8852b_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_8852B; 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 rtw8852b_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_8852B] = {0x5DE, 0x5DB}; ++ u32 addr = rtwdev->chip->phycap_addr; ++ u8 i; ++ ++ for (i = 0; i < RF_PATH_NUM_8852B; 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 rtw8852b_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_8852B; 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 rtw8852b_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 rtw8852b_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map) ++{ ++ rtw8852b_phycap_parsing_power_cal(rtwdev, phycap_map); ++ rtw8852b_phycap_parsing_tssi(rtwdev, phycap_map); ++ rtw8852b_phycap_parsing_thermal_trim(rtwdev, phycap_map); ++ rtw8852b_phycap_parsing_pa_bias_trim(rtwdev, phycap_map); ++ rtw8852b_phycap_parsing_gain_comp(rtwdev, phycap_map); ++ ++ return 0; ++} ++ ++static void rtw8852b_power_trim(struct rtw89_dev *rtwdev) ++{ ++ rtw8852b_thermal_trim(rtwdev); ++ rtw8852b_pa_bias_trim(rtwdev); ++} ++ + static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 ref) + { +@@ -369,6 +549,8 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .enable_bb_rf = rtw8852b_mac_enable_bb_rf, + .disable_bb_rf = rtw8852b_mac_disable_bb_rf, + .read_efuse = rtw8852b_read_efuse, ++ .read_phycap = rtw8852b_read_phycap, ++ .power_trim = rtw8852b_power_trim, + .set_txpwr = rtw8852b_set_txpwr, + .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852b_init_txpwr_unit, +@@ -386,6 +568,8 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .limit_efuse_size = 1280, + .dav_phy_efuse_size = 96, + .dav_log_efuse_size = 16, ++ .phycap_addr = 0x580, ++ .phycap_size = 128, + .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), +-- +2.13.6 + diff --git a/SOURCES/0009-wifi-rtw89-8852be-add-8852BE-PCI-entry.patch b/SOURCES/0009-wifi-rtw89-8852be-add-8852BE-PCI-entry.patch new file mode 100644 index 0000000..8c25f11 --- /dev/null +++ b/SOURCES/0009-wifi-rtw89-8852be-add-8852BE-PCI-entry.patch @@ -0,0 +1,130 @@ +From 3d7faabd92cfdd785c6591608614bf2663147ee4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:22 +0200 +Subject: [PATCH 009/142] wifi: rtw89: 8852be: add 8852BE PCI entry +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 9695dc2e4be90315471ea4c672836929f5c403fe +Author: Ping-Ke Shih +Date: Wed Sep 28 16:43:36 2022 +0800 + + wifi: rtw89: 8852be: add 8852BE PCI entry + + 8852BE has two variants with different ID. One is 10ec:b852 that is a main + model with 2x2 antenna, and the other is 10ec:b85b that is a 1x1 model. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220928084336.34981-10-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.h | 2 + + drivers/net/wireless/realtek/rtw89/rtw8852be.c | 64 ++++++++++++++++++++++++++ + 2 files changed, 66 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.h b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +index 578fe55b66957..bc0a383c4a390 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +@@ -85,4 +85,6 @@ struct rtw8852b_efuse { + }; + } __packed; + ++extern const struct rtw89_chip_info rtw8852b_chip_info; ++ + #endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852be.c b/drivers/net/wireless/realtek/rtw89/rtw8852be.c +index 7bf95c38d3eb2..0ef2ca8efeb0e 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c +@@ -7,18 +7,82 @@ + + #include "pci.h" + #include "reg.h" ++#include "rtw8852b.h" + + static const struct rtw89_pci_info rtw8852b_pci_info = { ++ .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, ++ ++ .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_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, + .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, ++ ++ .ltr_set = rtw89_pci_ltr_set, ++ .fill_txaddr_info = rtw89_pci_fill_txaddr_info, ++ .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, ++}; ++ ++static const struct rtw89_driver_info rtw89_8852be_info = { ++ .chip = &rtw8852b_chip_info, ++ .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, ++ .driver.pm = &rtw89_pm_ops, + }; ++module_pci_driver(rtw89_8852be_driver); + + MODULE_AUTHOR("Realtek Corporation"); + MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE driver"); +-- +2.13.6 + diff --git a/SOURCES/0010-wifi-rtw89-8852c-correct-set-of-IQK-backup-registers.patch b/SOURCES/0010-wifi-rtw89-8852c-correct-set-of-IQK-backup-registers.patch new file mode 100644 index 0000000..e9a2845 --- /dev/null +++ b/SOURCES/0010-wifi-rtw89-8852c-correct-set-of-IQK-backup-registers.patch @@ -0,0 +1,48 @@ +From 956f19cd6c44e5f95bd8dd3d98f09f32b785d157 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:22 +0200 +Subject: [PATCH 010/142] wifi: rtw89: 8852c: correct set of IQK backup + registers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 68b0ce5bb4002cd657963cb876f0ff51729f9bfc +Author: Ping-Ke Shih +Date: Fri Sep 30 21:33:17 2022 +0800 + + wifi: rtw89: 8852c: correct set of IQK backup registers + + IQK can change the values of this register set, so need to backup and + restore the values. During we rewrite IQK, the policy is changed. Some + values are controlled and filled by IQK, and don't need to restore after + IQK. Therefore, remove this kind of registers from this array. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220930133318.6335-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +index 006c2cf931116..1e67a565a9e0c 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +@@ -22,8 +22,7 @@ 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[] = { +- 0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x823c, 0x8224, 0x8220, +- 0xc1d4, 0xc1d8, 0xc1e8 ++ 0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x8220, 0xc1d4, 0xc1d8, 0xc1e8 + }; + + static const u32 rtw8852c_backup_rf_regs[] = { +-- +2.13.6 + diff --git a/SOURCES/0011-wifi-rtw89-8852c-rfk-correct-miscoding-delay-of-DPK.patch b/SOURCES/0011-wifi-rtw89-8852c-rfk-correct-miscoding-delay-of-DPK.patch new file mode 100644 index 0000000..9273ab0 --- /dev/null +++ b/SOURCES/0011-wifi-rtw89-8852c-rfk-correct-miscoding-delay-of-DPK.patch @@ -0,0 +1,45 @@ +From 7e4a7fc82e2bcd305444cbf6ab3f5af6546ca0b6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:22 +0200 +Subject: [PATCH 011/142] wifi: rtw89: 8852c: rfk: correct miscoding delay of + DPK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3be11416204a7aecbdba8c843849f204c631b8e6 +Author: Ping-Ke Shih +Date: Fri Sep 30 21:33:18 2022 +0800 + + wifi: rtw89: 8852c: rfk: correct miscoding delay of DPK + + Using mdelay() can work well, but calibration causes too much time. Use + proper udelay() to get shorter time and the same result. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220930133318.6335-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +index 1e67a565a9e0c..b0672b906e7bc 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +@@ -1666,7 +1666,7 @@ static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + + ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, + 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); +- mdelay(10); ++ udelay(10); + rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, +-- +2.13.6 + diff --git a/SOURCES/0012-wifi-rtw89-8852c-update-BB-parameters-to-v28.patch b/SOURCES/0012-wifi-rtw89-8852c-update-BB-parameters-to-v28.patch new file mode 100644 index 0000000..e57732f --- /dev/null +++ b/SOURCES/0012-wifi-rtw89-8852c-update-BB-parameters-to-v28.patch @@ -0,0 +1,1458 @@ +From 46fcc5a1fd87e72d7f14d5e11744a550fdcb334e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:22 +0200 +Subject: [PATCH 012/142] wifi: rtw89: 8852c: update BB parameters to v28 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit a9ee25c32fd4569f63cd34def9a013fb3dad8e01 +Author: Ping-Ke Shih +Date: Fri Sep 30 21:36:58 2022 +0800 + + wifi: rtw89: 8852c: update BB parameters to v28 + + Update BB parameters along with internal tag HALBB_027_067_07. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220930133659.7789-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + .../net/wireless/realtek/rtw89/rtw8852c_table.c | 988 ++++++++++++++++++--- + 1 file changed, 879 insertions(+), 109 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c +index 11f35e7a7f0e7..96c264a057ff4 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c +@@ -10,6 +10,8 @@ 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}, +@@ -200,7 +202,7 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4264, 0x00000000}, + {0x4268, 0x00000000}, + {0x426C, 0x0418317C}, +- {0x46C0, 0x00000001}, ++ {0x46C0, 0x00000000}, + {0x4270, 0x00D6135C}, + {0x46C4, 0x00000033}, + {0x4274, 0x00000000}, +@@ -342,7 +344,7 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x442C, 0x00000000}, + {0x4430, 0x00000000}, + {0x4434, 0x00000000}, +- {0x4438, 0x590642D0}, ++ {0x4438, 0x59096398}, + {0x443C, 0x398668A0}, + {0x4440, 0x6C100808}, + {0x4444, 0x4A145344}, +@@ -566,9 +568,9 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4BA8, 0x002B6456}, + {0x45E0, 0x00000000}, + {0x45E4, 0x00000000}, +- {0x45E8, 0x00E2E1E1}, ++ {0x45E8, 0x00C8E1E1}, + {0x45EC, 0xCBCBB6B6}, +- {0x45F0, 0x59100FCA}, ++ {0x45F0, 0x5F900FCA}, + {0x4BAC, 0x12CAB6DE}, + {0x4BB0, 0x00001110}, + {0x45F4, 0x08882550}, +@@ -584,9 +586,17 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4660, 0x41250EF4}, + {0x4664, 0x6750E458}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x45DC, 0xE1CB38E8}, +- {0x4660, 0x4A2E1800}, +- {0x4664, 0x6750E462}, ++ {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}, +@@ -603,7 +613,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -612,6 +634,10 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -620,11 +646,17 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x46A8, 0x2212FF14}, + {0x46AC, 0x60423537}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x46A8, 0x649EFF14}, ++ {0x46AC, 0xA1B37C4E}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x46A8, 0x4D1E7F14}, + {0x46AC, 0x60B37C4E}, +- {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x46A8, 0x2212FF14}, +- {0x46AC, 0x60423537}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x46A8, 0x649EFF14}, ++ {0x46AC, 0xA1B37C4E}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x46A8, 0x649EFF14}, ++ {0x46AC, 0xA1B37C4E}, + {0xA0000000, 0x00000000}, + {0x46A8, 0x2212FF14}, + {0x46AC, 0x60423537}, +@@ -637,11 +669,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4720, 0x3FFFFD63}, + {0x4724, 0xB58D11FF}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x46BC, 0x5107C252}, +- {0x4720, 0x27795843}, ++ {0x46BC, 0x510FC252}, ++ {0x4720, 0x27795303}, + {0x4724, 0xB58D11F5}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x46BC, 0x5107C252}, ++ {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}, +@@ -656,11 +696,17 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4734, 0x00000020}, + {0x4738, 0x8325C500}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x4734, 0x003D4C20}, ++ {0x4734, 0x003D5420}, + {0x4738, 0x8F25C500}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4734, 0x003D4C20}, ++ {0x4738, 0x8F25C500}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4734, 0x003D5420}, +- {0x4738, 0x8725C500}, ++ {0x4738, 0x8F25C500}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4734, 0x003D5420}, ++ {0x4738, 0x8F25C500}, + {0xA0000000, 0x00000000}, + {0x4734, 0x00000020}, + {0x4738, 0x8325C500}, +@@ -678,8 +724,14 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4BB4, 0x05EBC8AF}, + {0x4BB8, 0x99543D24}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x4BB4, 0xFBD5B89F}, +- {0x4BB8, 0x99563918}, ++ {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}, +@@ -729,10 +781,10 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4C58, 0x00001146}, + {0x4C5C, 0x00000000}, + {0x4C60, 0x00000000}, +- {0x4C64, 0xE2E1E1DE}, ++ {0x4C64, 0xC8E1E1DE}, + {0x4C68, 0xB6B600B6}, + {0x4C6C, 0xCACBCBCA}, +- {0x4C70, 0x8091010F}, ++ {0x4C70, 0x80F9010F}, + {0x4C74, 0x00000B11}, + {0x46C8, 0x08882550}, + {0x46CC, 0x08CC2660}, +@@ -747,9 +799,17 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4744, 0x412504E8}, + {0x4748, 0x6850E459}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x4740, 0xE4CD38E8}, +- {0x4744, 0x4C321B04}, +- {0x4748, 0x6750E466}, ++ {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}, +@@ -766,7 +826,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -775,6 +847,10 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -783,11 +859,17 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4A5C, 0x2212FF14}, + {0x4A60, 0x60423537}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4A5C, 0x649EFF14}, ++ {0x4A60, 0xA1B37C4E}, ++ {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4A5C, 0x4D1E7F14}, + {0x4A60, 0x60B37C4E}, +- {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x4A5C, 0x2212FF14}, +- {0x4A60, 0x60423537}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4A5C, 0x649EFF14}, ++ {0x4A60, 0xA1B37C4E}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4A5C, 0x649EFF14}, ++ {0x4A60, 0xA1B37C4E}, + {0xA0000000, 0x00000000}, + {0x4A5C, 0x2212FF14}, + {0x4A60, 0x60423537}, +@@ -800,11 +882,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4A74, 0x3FFFFD63}, + {0x4A78, 0xB58D11FF}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x4A70, 0x5107C252}, +- {0x4A74, 0x27795843}, ++ {0x4A70, 0x510FC252}, ++ {0x4A74, 0x27795303}, + {0x4A78, 0xB58D11F5}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x4A70, 0x5107C252}, ++ {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}, +@@ -819,11 +909,17 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4AA0, 0x00000020}, + {0x4AA4, 0x8325C500}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x4AA0, 0x003D4C20}, ++ {0x4AA0, 0x003D5420}, + {0x4AA4, 0x8F25C500}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4AA0, 0x003D4C20}, ++ {0x4AA4, 0x8F25C500}, ++ {0x903500ff, 0x00000000}, {0x40000000, 0x00000000}, + {0x4AA0, 0x003D5420}, +- {0x4AA4, 0x8725C500}, ++ {0x4AA4, 0x8F25C500}, ++ {0x903600ff, 0x00000000}, {0x40000000, 0x00000000}, ++ {0x4AA0, 0x003D5420}, ++ {0x4AA4, 0x8F25C500}, + {0xA0000000, 0x00000000}, + {0x4AA0, 0x00000020}, + {0x4AA4, 0x8325C500}, +@@ -841,8 +937,14 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4C78, 0x07ECC9B0}, + {0x4C7C, 0x995B4126}, + {0x903400ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x4C78, 0xFBD5B89F}, +- {0x4C7C, 0x99563918}, ++ {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}, +@@ -907,17 +1009,46 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x47B4, 0x00000005}, + {0x4D2C, 0x0008C0C1}, + {0x47B8, 0x00001759}, +- {0x47BC, 0x4B702400}, +- {0x47C0, 0x831508BA}, ++ {0x47BC, 0x4B002402}, ++ {0x47C0, 0x831508BC}, + {0x4A14, 0x000000E9}, +- {0x4D30, 0x00000001}, ++ {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}, +@@ -942,7 +1073,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -967,7 +1110,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1014,7 +1169,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1039,7 +1206,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4DD0, 0x994C1502}, + {0x4DD4, 0x00017912}, + {0x4EE4, 0x00000001}, +- {0x4904, 0x00008A62}, ++ {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}, +@@ -1096,8 +1275,8 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x4988, 0x00000000}, + {0x498C, 0x00000000}, + {0x4E34, 0x00FC0000}, +- {0x4E38, 0x0000F800}, +- {0x4E3C, 0x00000001}, ++ {0x4E38, 0x00000000}, ++ {0x4E3C, 0x00000003}, + {0x4990, 0x00000000}, + {0x4994, 0x00000000}, + {0x4998, 0x00000000}, +@@ -1134,7 +1313,7 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x710, 0xEF810000}, + {0xC54, 0x1AE1436A}, + {0xC58, 0x41000000}, +- {0xC68, 0x10000050}, ++ {0xC68, 0x90000050}, + {0xC6C, 0x20061020}, + {0x704, 0x601E0100}, + {0xC74, 0x00000000}, +@@ -1225,12 +1404,12 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x328, 0xE000E000}, + {0x32C, 0x0041E000}, + {0x35C, 0x000004C4}, +- {0xC0D4, 0xA7C41460}, ++ {0xC0D4, 0xA7441460}, + {0xC0D8, 0xC6BA7F67}, + {0xC0DC, 0x30C52868}, + {0xC0E0, 0x75008128}, + {0xC0E4, 0x0000272B}, +- {0xC1D4, 0xA7C41460}, ++ {0xC1D4, 0xA7441460}, + {0xC1D8, 0xC6BA7F67}, + {0xC1DC, 0x30C52868}, + {0xC1E0, 0x75008128}, +@@ -1290,7 +1469,7 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0xC8C, 0x02F2FC08}, + {0xC70, 0x071BFC00}, + {0x980, 0x10002251}, +- {0x988, 0x3C3C4107}, ++ {0x988, 0x3C3C8107}, + {0x904, 0x00000005}, + {0x994, 0x00000010}, + {0x000, 0x0580801F}, +@@ -1359,7 +1538,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1393,7 +1584,7 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0xC60, 0x017FFFF3}, + {0xC70, 0x071BFE00}, + {0xC70, 0x071BFE60}, +- {0xC6C, 0x20061021}, ++ {0xC6C, 0x26061021}, + {0x58AC, 0x08000000}, + {0x78AC, 0x08000000}, + {0x8120, 0x10000000}, +@@ -1452,7 +1643,7 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {0x12A0, 0x24903056}, + {0x12AC, 0x12333121}, + {0x12B8, 0x30020000}, +- {0x2000, 0x18BBBF84}, ++ {0x2000, 0x20BBBF04}, + {0x2C14, 0x85000005}, + {0x3200, 0x00010142}, + {0x32A0, 0x24903056}, +@@ -1469,7 +1660,21 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1479,7 +1684,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1487,14 +1704,38 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1514,12 +1755,49 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1529,7 +1807,19 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1537,14 +1827,38 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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}, +@@ -1564,143 +1878,223 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_regs[] = { + {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, 0x00000018}, +- {0x0F8, 0x20220120}, ++ {0x0F4, 0x00000028}, ++ {0x0F8, 0x20220610}, + }; + + static const struct rtw89_reg2_def rtw89_8852c_phy_bb_reg_gain[] = { + {0xF0FF0000, 0x00000000}, + {0xF03300FF, 0x00000001}, +- {0x000, 0x01E3C39F}, +- {0x001, 0x00694727}, +- {0x002, 0x00005536}, +- {0x100, 0x02E3C39F}, +- {0x101, 0x0069472A}, ++ {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, 0x0EF4D1B9}, +- {0x10001, 0x00584125}, +- {0x10002, 0x00006750}, ++ {0x10000, 0x0BF1CEB6}, ++ {0x10001, 0x00434328}, ++ {0x10002, 0x00005050}, + {0xA0000000, 0x00000000}, +- {0x10000, 0x1A02E1C9}, +- {0x10001, 0x00644A30}, +- {0x10002, 0x00006750}, ++ {0x10000, 0x1D08E8D0}, ++ {0x10001, 0x00644C32}, ++ {0x10002, 0x00006650}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x10100, 0x1901E1C8}, + {0x10101, 0x0061482D}, + {0x10102, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x10100, 0x04E8C5AD}, +- {0x10101, 0x00594125}, +- {0x10102, 0x00006850}, ++ {0x10100, 0x0BF0CEB8}, ++ {0x10101, 0x00424227}, ++ {0x10102, 0x00005050}, + {0xA0000000, 0x00000000}, +- {0x10100, 0x1901E1C8}, +- {0x10101, 0x0061482D}, +- {0x10102, 0x00006750}, ++ {0x10100, 0x1F0AECD5}, ++ {0x10101, 0x00634B31}, ++ {0x10102, 0x00006550}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x20000, 0x1601E2CA}, + {0x20001, 0x005D452A}, + {0x20002, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x20000, 0x0EF4D3BB}, +- {0x20001, 0x00563F25}, +- {0x20002, 0x00006850}, ++ {0x20000, 0x0EF5D3BB}, ++ {0x20001, 0x00454529}, ++ {0x20002, 0x00005050}, + {0xA0000000, 0x00000000}, +- {0x20000, 0x1601E2CA}, +- {0x20001, 0x005D452A}, +- {0x20002, 0x00006750}, ++ {0x20000, 0x1904E6CE}, ++ {0x20001, 0x0060482D}, ++ {0x20002, 0x00006650}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x20100, 0x1901E1C8}, + {0x20101, 0x0061482D}, + {0x20102, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x20100, 0x0BF1CFB7}, +- {0x20101, 0x00574025}, +- {0x20102, 0x00006750}, ++ {0x20100, 0x12F8D7C1}, ++ {0x20101, 0x004A4A2E}, ++ {0x20102, 0x00005050}, + {0xA0000000, 0x00000000}, +- {0x20100, 0x1901E1C8}, ++ {0x20100, 0x1F0AECD5}, + {0x20101, 0x0061482D}, +- {0x20102, 0x00006750}, ++ {0x20102, 0x00006550}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x30000, 0x1700E1CA}, + {0x30001, 0x005E472B}, + {0x30002, 0x00006750}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x30000, 0x05EFCEB7}, +- {0x30001, 0x004B351A}, +- {0x30002, 0x00006850}, ++ {0x30000, 0x0DF6D5BE}, ++ {0x30001, 0x00414126}, ++ {0x30002, 0x00005050}, + {0xA0000000, 0x00000000}, +- {0x30000, 0x1700E1CA}, +- {0x30001, 0x005E472B}, +- {0x30002, 0x00006750}, ++ {0x30000, 0x14FEE0CA}, ++ {0x30001, 0x005C4328}, ++ {0x30002, 0x00006650}, + {0xB0000000, 0x00000000}, + {0x80ff0000, 0x00000000}, {0x40000000, 0x00000000}, + {0x30100, 0x14FEE0C9}, + {0x30101, 0x00594428}, + {0x30102, 0x00006650}, + {0x903300ff, 0x00000000}, {0x40000000, 0x00000000}, +- {0x30100, 0x0CF2D1B9}, +- {0x30101, 0x00563F24}, +- {0x30102, 0x00006750}, ++ {0x30100, 0x0EF5D5C0}, ++ {0x30101, 0x0045452A}, ++ {0x30102, 0x00005050}, + {0xA0000000, 0x00000000}, +- {0x30100, 0x14FEE0C9}, +- {0x30101, 0x00594428}, ++ {0x30100, 0x1F0AECD8}, ++ {0x30101, 0x00654C31}, + {0x30102, 0x00006650}, + {0xB0000000, 0x00000000}, +- {0x40000, 0x13FCDDC8}, +- {0x40001, 0x005D4328}, +- {0x40002, 0x00006850}, +- {0x40100, 0x14FEE3CF}, +- {0x40101, 0x00583E24}, +- {0x40102, 0x00006850}, +- {0x50000, 0x0DF4D6C6}, +- {0x50001, 0x00604227}, +- {0x50002, 0x00006850}, +- {0x50100, 0x1903E7D5}, +- {0x50101, 0x0061462B}, +- {0x50102, 0x00006850}, +- {0x60000, 0x0FF5D7C6}, +- {0x60001, 0x005D4429}, +- {0x60002, 0x00006850}, +- {0x60100, 0x12FADECF}, +- {0x60101, 0x005B4126}, +- {0x60102, 0x00006850}, +- {0x70000, 0x09F1D2C3}, +- {0x70001, 0x00554026}, +- {0x70002, 0x00006750}, +- {0x70100, 0x0CF5DACC}, +- {0x70101, 0x00563E25}, +- {0x70102, 0x00006750}, ++ {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}, +@@ -1709,30 +2103,102 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_reg_gain[] = { + {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}, +@@ -1765,6 +2231,310 @@ static const struct rtw89_reg2_def rtw89_8852c_phy_bb_reg_gain[] = { + {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[] = { +-- +2.13.6 + diff --git a/SOURCES/0013-wifi-rtw89-phy-ignore-warning-of-bb-gain-cfg_type-4.patch b/SOURCES/0013-wifi-rtw89-phy-ignore-warning-of-bb-gain-cfg_type-4.patch new file mode 100644 index 0000000..f50f59e --- /dev/null +++ b/SOURCES/0013-wifi-rtw89-phy-ignore-warning-of-bb-gain-cfg_type-4.patch @@ -0,0 +1,57 @@ +From 9eed2ff1a8c584acaf9b9553989e3925ad2a5b81 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:23 +0200 +Subject: [PATCH 013/142] wifi: rtw89: phy: ignore warning of bb gain cfg_type + 4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit c6a9d360874a41dc972c44c0949916da55199f85 +Author: Ping-Ke Shih +Date: Fri Sep 30 21:36:59 2022 +0800 + + wifi: rtw89: phy: ignore warning of bb gain cfg_type 4 + + The new BB parameters add new cfg_tpe 4 to improve performance of eFEM + modules (rfe_type >= 50), but we are using iFEM modules for now, so this + warning can be ignored. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220930133659.7789-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/phy.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index ac3aa1da5bd1b..5645aeb2a8d08 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -1036,6 +1036,7 @@ static void rtw89_phy_config_bb_gain(struct rtw89_dev *rtwdev, + { + 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; +@@ -1061,6 +1062,11 @@ static void rtw89_phy_config_bb_gain(struct rtw89_dev *rtwdev, + 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", +-- +2.13.6 + diff --git a/SOURCES/0014-wifi-rtw89-8852c-set-pin-MUX-to-enable-BT-firmware-l.patch b/SOURCES/0014-wifi-rtw89-8852c-set-pin-MUX-to-enable-BT-firmware-l.patch new file mode 100644 index 0000000..351d2e7 --- /dev/null +++ b/SOURCES/0014-wifi-rtw89-8852c-set-pin-MUX-to-enable-BT-firmware-l.patch @@ -0,0 +1,62 @@ +From 411927dca0d2432a83160930fc016d27c4b205b2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:23 +0200 +Subject: [PATCH 014/142] wifi: rtw89: 8852c: set pin MUX to enable BT firmware + log +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit d187691ab63f53f199a07904422e0911bc6f9390 +Author: Ping-Ke Shih +Date: Fri Sep 30 21:44:16 2022 +0800 + + wifi: rtw89: 8852c: set pin MUX to enable BT firmware log + + 8852CE is a combo chip, and WiFi driver controls pin MUX. To output BT + firmware log to specific hardware pin, set pin MUX to achieve. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220930134417.10282-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 4 ++++ + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 6809ff812abb7..874cca85eaadf 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -229,6 +229,10 @@ + + #define R_AX_GPIO0_7_FUNC_SEL 0x02D0 + ++#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) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index a6a9fe3d0b565..a5bcd3fcecb71 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -273,6 +273,9 @@ static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev) + 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; + } + +-- +2.13.6 + diff --git a/SOURCES/0015-wifi-rtw89-add-to-dump-TX-FIFO-0-1-for-8852C.patch b/SOURCES/0015-wifi-rtw89-add-to-dump-TX-FIFO-0-1-for-8852C.patch new file mode 100644 index 0000000..6dbc1bc --- /dev/null +++ b/SOURCES/0015-wifi-rtw89-add-to-dump-TX-FIFO-0-1-for-8852C.patch @@ -0,0 +1,110 @@ +From ae440308591d445eba5ce38d6404b3095fe11239 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:23 +0200 +Subject: [PATCH 015/142] wifi: rtw89: add to dump TX FIFO 0/1 for 8852C +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 732dd91db3d3a1b7a767598549ffed358c9fbb89 +Author: Ping-Ke Shih +Date: Fri Sep 30 21:44:17 2022 +0800 + + wifi: rtw89: add to dump TX FIFO 0/1 for 8852C + + MAC maintains TX FIFO to transmit packets with meta data to BB layer. To + debug abnormal transmission, we need to dump the content to dig problem. + Since FIFO of 8852C locates on different address with different size and + need additional switch to enable read operation, this patch adds the + changes accordingly. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20220930134417.10282-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/debug.c | 21 +++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/mac.c | 2 ++ + drivers/net/wireless/realtek/rtw89/mac.h | 4 ++++ + 3 files changed, 27 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +index f584fa57c82fa..8f27c883eeabb 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.c ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -774,13 +774,34 @@ rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v) + { + struct rtw89_debugfs_priv *debugfs_priv = m->private; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ bool grant_read = false; ++ ++ 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; ++ } ++ } + + mutex_lock(&rtwdev->mutex); + rtw89_leave_ps_mode(rtwdev); ++ if (grant_read) ++ rtw89_write32_set(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); + rtw89_debug_dump_mac_mem(m, rtwdev, + 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); + mutex_unlock(&rtwdev->mutex); + + return 0; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 0be7d2ac59397..598568c3f2750 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -31,6 +31,8 @@ const u32 rtw89_mac_mem_base_addrs[RTW89_MAC_MEM_NUM] = { + [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, +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 6f4ada1869a17..a9867ac351da7 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -245,6 +245,8 @@ enum rtw89_mac_dbg_port_sel { + #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 +@@ -271,6 +273,8 @@ enum rtw89_mac_mem_sel { + 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, + + /* keep last */ + RTW89_MAC_MEM_NUM, +-- +2.13.6 + diff --git a/SOURCES/0016-wifi-rtw89-coex-move-chip_ops-btc_bt_aci_imp-to-a-ge.patch b/SOURCES/0016-wifi-rtw89-coex-move-chip_ops-btc_bt_aci_imp-to-a-ge.patch new file mode 100644 index 0000000..71e9cac --- /dev/null +++ b/SOURCES/0016-wifi-rtw89-coex-move-chip_ops-btc_bt_aci_imp-to-a-ge.patch @@ -0,0 +1,138 @@ +From 9157b32cbe2524cfaea119ff7ac5789d7b2c08e5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:23 +0200 +Subject: [PATCH 016/142] wifi: rtw89: coex: move chip_ops::btc_bt_aci_imp to a + generic code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 127da1aa61859c1eb27d7fc2d5b936e9e528815d +Author: Ching-Te Ku +Date: Wed Oct 5 16:32:07 2022 +0800 + + wifi: rtw89: coex: move chip_ops::btc_bt_aci_imp to a generic code + + This chunk is to set fixed BT LNA2 at level5 when WiFi/BT shared BTG RFC + to improve BT anti-interference ability from adjacent channel. Since all + chips use the same setting, remove chip_ops::btc_bt_aci_imp. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221005083212.45683-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 9 +++++++-- + drivers/net/wireless/realtek/rtw89/core.h | 1 - + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 14 -------------- + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 14 -------------- + 4 files changed, 7 insertions(+), 31 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index bbdfa9ac203cc..f21c73310fdb6 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -1809,13 +1809,18 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev) + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; ++ struct rtw89_btc_bt_link_info *b = &bt->link_info; + struct rtw89_btc_rf_trx_para para; + u32 wl_stb_chg = 0; + u8 level_id = 0; + + if (!dm->freerun) { +- dm->trx_para_level = 0; +- chip->ops->btc_bt_aci_imp(rtwdev); ++ /* fix LNA2 = level-5 for BT ACI issue at BTG */ ++ if ((btc->dm.wl_btg_rx && b->profile_cnt.now != 0) || ++ dm->bt_only == 1) ++ dm->trx_para_level = 1; ++ else ++ dm->trx_para_level = 0; + } + + level_id = (u8)dm->trx_para_level; +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 51af91b30fc4d..b04e7a54b1e0a 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2363,7 +2363,6 @@ struct rtw89_chip_ops { + 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_bt_aci_imp)(struct rtw89_dev *rtwdev); + 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); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 5678683ec02a5..b5aa8697a0982 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -1871,19 +1871,6 @@ static struct rtw89_btc_fbtc_mreg rtw89_btc_8852a_mon_reg[] = { + }; + + static +-void rtw8852a_btc_bt_aci_imp(struct rtw89_dev *rtwdev) +-{ +- struct rtw89_btc *btc = &rtwdev->btc; +- struct rtw89_btc_dm *dm = &btc->dm; +- struct rtw89_btc_bt_info *bt = &btc->cx.bt; +- struct rtw89_btc_bt_link_info *b = &bt->link_info; +- +- /* fix LNA2 = level-5 for BT ACI issue at BTG */ +- if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0) +- dm->trx_para_level = 1; +-} +- +-static + void rtw8852a_btc_update_bt_cnt(struct rtw89_dev *rtwdev) + { + struct rtw89_btc *btc = &rtwdev->btc; +@@ -2041,7 +2028,6 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = { + .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_bt_aci_imp = rtw8852a_btc_bt_aci_imp, + .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, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index a5bcd3fcecb71..00f564be29e8d 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2685,19 +2685,6 @@ static const struct rtw89_btc_fbtc_mreg rtw89_btc_8852c_mon_reg[] = { + }; + + static +-void rtw8852c_btc_bt_aci_imp(struct rtw89_dev *rtwdev) +-{ +- struct rtw89_btc *btc = &rtwdev->btc; +- struct rtw89_btc_dm *dm = &btc->dm; +- struct rtw89_btc_bt_info *bt = &btc->cx.bt; +- struct rtw89_btc_bt_link_info *b = &bt->link_info; +- +- /* fix LNA2 = level-5 for BT ACI issue at BTG */ +- if (btc->dm.wl_btg_rx && b->profile_cnt.now != 0) +- dm->trx_para_level = 1; +-} +- +-static + void rtw8852c_btc_update_bt_cnt(struct rtw89_dev *rtwdev) + { + /* Feature move to firmware */ +@@ -2893,7 +2880,6 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = { + .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_bt_aci_imp = rtw8852c_btc_bt_aci_imp, + .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, +-- +2.13.6 + diff --git a/SOURCES/0017-wifi-rtw89-parse-PHY-status-only-when-PPDU-is-to_sel.patch b/SOURCES/0017-wifi-rtw89-parse-PHY-status-only-when-PPDU-is-to_sel.patch new file mode 100644 index 0000000..df44ba9 --- /dev/null +++ b/SOURCES/0017-wifi-rtw89-parse-PHY-status-only-when-PPDU-is-to_sel.patch @@ -0,0 +1,48 @@ +From 84c69de904c9c595ca903b373aac9dea6f93dcb6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:23 +0200 +Subject: [PATCH 017/142] wifi: rtw89: parse PHY status only when PPDU is + to_self +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 0935bb1527d711b1af8e89d4ba200c302fb5ab2b +Author: Eric Huang +Date: Wed Oct 5 16:32:08 2022 +0800 + + wifi: rtw89: parse PHY status only when PPDU is to_self + + Without this fix, some non-self packets are used to count CFO (center + frequency offset), and average CFO has unstable variation. Then, it causes + unexpected performance. + + Signed-off-by: Eric Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221005083212.45683-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index a703bb70b8f55..ee2214fd92d04 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -1255,6 +1255,9 @@ static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev, + if (phy_ppdu->ie < RTW89_CCK_PKT) + return -EINVAL; + ++ if (!phy_ppdu->to_self) ++ return 0; ++ + pos = (u8 *)phy_ppdu->buf + PHY_STS_HDR_LEN; + end = (u8 *)phy_ppdu->buf + phy_ppdu->len; + while (pos < end) { +-- +2.13.6 + diff --git a/SOURCES/0018-wifi-rtw89-8852b-set-proper-configuration-before-loa.patch b/SOURCES/0018-wifi-rtw89-8852b-set-proper-configuration-before-loa.patch new file mode 100644 index 0000000..952916a --- /dev/null +++ b/SOURCES/0018-wifi-rtw89-8852b-set-proper-configuration-before-loa.patch @@ -0,0 +1,79 @@ +From 096c34d9acbb90e410d5e31e1820fcddd513cdc3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:23 +0200 +Subject: [PATCH 018/142] wifi: rtw89: 8852b: set proper configuration before + loading NCTL +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit d0c820cc5bcf768598ca3e9f6e29f3e4e5589827 +Author: Ping-Ke Shih +Date: Wed Oct 5 16:32:09 2022 +0800 + + wifi: rtw89: 8852b: set proper configuration before loading NCTL + + Before loading RF NCTL table, we need to configure IQK/DPK clock and reset + them, and then polling NCTL state ready. Since 8852BE needs additional + one setting, add it by this patch. Also, give them proper names. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221005083212.45683-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/phy.c | 12 +++++++----- + drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index 5645aeb2a8d08..2db1209e6cd35 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -1368,13 +1368,15 @@ static void rtw89_phy_init_rf_nctl(struct rtw89_dev *rtwdev) + int ret; + + /* IQK/DPK clock & reset */ +- rtw89_phy_write32_set(rtwdev, 0x0c60, 0x3); +- rtw89_phy_write32_set(rtwdev, 0x0c6c, 0x1); +- rtw89_phy_write32_set(rtwdev, 0x58ac, 0x8000000); +- rtw89_phy_write32_set(rtwdev, 0x78ac, 0x8000000); ++ 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); ++ rtw89_phy_write32_set(rtwdev, R_P1_PATH_RST, 0x8000000); ++ if (chip->chip_id == RTL8852B) ++ rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x2); + + /* check 0x8080 */ +- rtw89_phy_write32(rtwdev, 0x8000, 0x8); ++ rtw89_phy_write32(rtwdev, R_NCTL_CFG, 0x8); + + ret = read_poll_timeout(rtw89_phy_nctl_poll, val, val == 0x4, 10, + 1000, false, rtwdev); +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 874cca85eaadf..82af17d7d8d31 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -4039,6 +4039,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 R_P0_TXDPD 0x58D4 + #define B_P0_TXDPD GENMASK(31, 28) + #define R_P0_TXPW_RSTB 0x58DC +@@ -4083,6 +4084,7 @@ + #define R_P1_RFCTM 0x7864 + #define R_P1_RFCTM_RDY BIT(26) + #define B_P1_RFCTM_VAL GENMASK(25, 20) ++#define R_P1_PATH_RST 0x78AC + #define R_P1_TXPW_RSTB 0x78DC + #define B_P1_TXPW_RSTB_MANON BIT(30) + #define B_P1_TXPW_RSTB_TSSI BIT(31) +-- +2.13.6 + diff --git a/SOURCES/0019-wifi-rtw89-8852b-add-HFC-quota-arrays.patch b/SOURCES/0019-wifi-rtw89-8852b-add-HFC-quota-arrays.patch new file mode 100644 index 0000000..c7e15d8 --- /dev/null +++ b/SOURCES/0019-wifi-rtw89-8852b-add-HFC-quota-arrays.patch @@ -0,0 +1,81 @@ +From 52976ab2fc78c32936c31a51972da79f46b8a424 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:23 +0200 +Subject: [PATCH 019/142] wifi: rtw89: 8852b: add HFC quota arrays +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3e870b4817333a1a4b01805073da3e00449acf43 +Author: Ping-Ke Shih +Date: Wed Oct 5 16:32:10 2022 +0800 + + wifi: rtw89: 8852b: add HFC quota arrays + + HFC is short for HCI flow control. These arrays are used to set quota + according to operating modes, which are SCC or download firmware. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221005083212.45683-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 32 +++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index e9bcea35a72a2..8424038d5338b 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -11,6 +11,37 @@ + #include "rtw8852b_table.h" + #include "txrx.h" + ++static const struct rtw89_hfc_ch_cfg rtw8852b_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 rtw8852b_hfc_pubcfg_pcie = { ++ 448, /* Group 0 */ ++ 0, /* Group 1 */ ++ 448, /* 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_dle_mem rtw8852b_dle_mem_pcie[] = { + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size6, + &rtw89_mac_size.ple_size6, &rtw89_mac_size.wde_qt6, +@@ -561,6 +592,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .ops = &rtw8852b_chip_ops, + .fifo_size = 196608, + .dle_scc_rsvd_size = 98304, ++ .hfc_param_ini = rtw8852b_hfc_param_ini_pcie, + .dle_mem = rtw8852b_dle_mem_pcie, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 1216, +-- +2.13.6 + diff --git a/SOURCES/0020-wifi-rtw89-make-generic-functions-to-convert-subband.patch b/SOURCES/0020-wifi-rtw89-make-generic-functions-to-convert-subband.patch new file mode 100644 index 0000000..fc73082 --- /dev/null +++ b/SOURCES/0020-wifi-rtw89-make-generic-functions-to-convert-subband.patch @@ -0,0 +1,158 @@ +From df14c12867748fd17be146dd3d4c8376bbf5812b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:24 +0200 +Subject: [PATCH 020/142] wifi: rtw89: make generic functions to convert + subband gain index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 6e5125bcbaf810520969c121c7f12f20b8f3987d +Author: Ping-Ke Shih +Date: Wed Oct 5 16:32:11 2022 +0800 + + wifi: rtw89: make generic functions to convert subband gain index + + The gain tables use different domain index, so we need to convert the index + from subband of chandef. Since these conversion functions can share with + 8852b, make generic functions for further use. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221005083212.45683-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/phy.h | 44 +++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 46 ++------------------------- + 2 files changed, 46 insertions(+), 44 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +index 030a7c904a28d..1129d462bfbdb 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.h ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -374,6 +374,50 @@ static inline u32 rtw89_phy_read32_mask(struct rtw89_dev *rtwdev, + return rtw89_read32_mask(rtwdev, addr | RTW89_PHY_ADDR_OFFSET, mask); + } + ++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; ++ } ++} ++ ++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; ++ } ++} ++ + enum rtw89_rfk_flag { + RTW89_RFK_F_WRF = 0, + RTW89_RFK_F_WM = 1, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index 00f564be29e8d..f6bcac8268166 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -788,40 +788,12 @@ static const struct rtw8852c_bb_gain_op1db bb_gain_op1db_a = { + .mask_tia0_lna6 = 0xff000000, + }; + +-static enum rtw89_phy_bb_gain_band +-rtw8852c_mapping_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 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; +- u8 gain_band = rtw8852c_mapping_gain_band(subband); ++ u8 gain_band = rtw89_subband_to_bb_gain_band(subband); + s32 val; + u32 reg; + u32 mask; +@@ -979,21 +951,7 @@ static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev, + rtw89_phy_write32_mask(rtwdev, R_RPL_OFST, B_RPL_OFST_MASK, tmp & 0x7f); + } + +- switch (chan->subband_type) { +- default: +- case RTW89_CH_2G: +- gain_band = RTW89_GAIN_OFFSET_2G_OFDM; +- break; +- case RTW89_CH_5G_BAND_1: +- gain_band = RTW89_GAIN_OFFSET_5G_LOW; +- break; +- case RTW89_CH_5G_BAND_3: +- gain_band = RTW89_GAIN_OFFSET_5G_MID; +- break; +- case RTW89_CH_5G_BAND_4: +- gain_band = RTW89_GAIN_OFFSET_5G_HIGH; +- break; +- } ++ 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]; +-- +2.13.6 + diff --git a/SOURCES/0021-wifi-rtw89-8852b-add-chip_ops-set_channel.patch b/SOURCES/0021-wifi-rtw89-8852b-add-chip_ops-set_channel.patch new file mode 100644 index 0000000..1aa009f --- /dev/null +++ b/SOURCES/0021-wifi-rtw89-8852b-add-chip_ops-set_channel.patch @@ -0,0 +1,1114 @@ +From 1447125017280fa3b2a9d82bde7b0c0448a56420 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:24 +0200 +Subject: [PATCH 021/142] wifi: rtw89: 8852b: add chip_ops::set_channel +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 6b0698984eb02f3e0dfd3c152df69f87c903e07f +Author: Ping-Ke Shih +Date: Wed Oct 5 16:32:12 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops::set_channel + + set_channel is main function to configure channel and bandwidth for all + layers, namely MAC, BB and RF. Additionally, MAC layer enables CCK rate + checking to avoid wrong rate from driver. BB layer configures SCO + (Sample Clock Offset) for CCK, TX gain error/offset, and reset baseband + hardware circuit after all configurations done. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221005083212.45683-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 1 + + drivers/net/wireless/realtek/rtw89/phy.c | 9 + + drivers/net/wireless/realtek/rtw89/phy.h | 2 + + drivers/net/wireless/realtek/rtw89/reg.h | 58 ++- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 564 ++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 256 ++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h | 14 + + 7 files changed, 903 insertions(+), 1 deletion(-) + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c + create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index b04e7a54b1e0a..0a0343608ba63 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -3429,6 +3429,7 @@ struct rtw89_phy_efuse_gain { + bool comp_valid; + s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */ + s8 offset_base[RTW89_PHY_MAX]; /* S(8, 4) */ ++ s8 rssi_base[RTW89_PHY_MAX]; /* S(8, 4) */ + s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ + }; + +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index 2db1209e6cd35..13b16ec0d8077 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -1427,6 +1427,15 @@ void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, + } + EXPORT_SYMBOL(rtw89_phy_write32_idx); + ++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) + { +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +index 1129d462bfbdb..1e122b1498ba1 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.h ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -499,6 +499,8 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev, + void rtw89_phy_dm_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); ++u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask, ++ enum rtw89_phy_idx phy_idx); + 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, +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 82af17d7d8d31..1539973296cd1 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3313,6 +3313,10 @@ + #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 +@@ -3448,14 +3452,31 @@ + #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_LOGEN 0xa3 + #define RR_LOGEN_RPT GENMASK(19, 16) ++#define RR_SX 0xaf ++#define RR_LDO 0xb1 ++#define RR_LDO_SEL GENMASK(8, 6) ++#define RR_VCO 0xb2 ++#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_LCKST 0xcf ++#define RR_LCKST_BIN BIT(0) + #define RR_LCK_TRG 0xd3 + #define RR_LCK_TRGSEL BIT(8) ++#define RR_MMD 0xd5 ++#define RR_MMD_RST_EN BIT(8) ++#define RR_MMD_RST_SYN BIT(6) + #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) +@@ -3624,6 +3645,8 @@ + #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_NRBW 0x12B8 + #define B_P0_NRBW_DBG BIT(30) + #define R_S0_RXDC 0x12D4 +@@ -3717,6 +3740,8 @@ + #define B_RXCCA_DIS_V1 BIT(0) + #define R_RXSC 0x237C + #define B_RXSC_EN BIT(0) ++#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 +@@ -3733,6 +3758,8 @@ + #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_DBGMOD 0x32B8 + #define B_P1_DBGMOD_ON BIT(30) + #define R_S1_RXDC 0x32D4 +@@ -3766,7 +3793,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 +@@ -3916,20 +3946,42 @@ + #define R_2P4G_BAND 0x4970 + #define B_2P4G_BAND_SEL BIT(1) + #define R_FC0_BW 0x4974 +-#define B_FC0_BW_INV GENMASK(6, 0) ++#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_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_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 +@@ -3940,8 +3992,10 @@ + #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 +@@ -3957,6 +4011,7 @@ + #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) +@@ -3970,6 +4025,7 @@ + #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) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 8424038d5338b..b50fff00b1393 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -8,6 +8,7 @@ + #include "phy.h" + #include "reg.h" + #include "rtw8852b.h" ++#include "rtw8852b_rfk.h" + #include "rtw8852b_table.h" + #include "txrx.h" + +@@ -334,6 +335,568 @@ static void rtw8852b_power_trim(struct rtw89_dev *rtwdev) + rtw8852b_pa_bias_trim(rtwdev); + } + ++static void rtw8852b_set_channel_mac(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ u8 mac_idx) ++{ ++ u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx); ++ u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE, mac_idx); ++ u32 chk_rate = rtw89_mac_reg_by_idx(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 rtw8852b_sco_barker_threshold[14] = { ++ 0x1cfea, 0x1d0e1, 0x1d1d7, 0x1d2cd, 0x1d3c3, 0x1d4b9, 0x1d5b0, 0x1d6a6, ++ 0x1d79c, 0x1d892, 0x1d988, 0x1da7f, 0x1db75, 0x1ddc4 ++}; ++ ++static const u32 rtw8852b_sco_cck_threshold[14] = { ++ 0x27de3, 0x27f35, 0x28088, 0x281da, 0x2832d, 0x2847f, 0x285d2, 0x28724, ++ 0x28877, 0x289c9, 0x28b1c, 0x28c6e, 0x28dc1, 0x290ed ++}; ++ ++static void rtw8852b_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, ++ rtw8852b_sco_barker_threshold[ch_element]); ++ rtw89_phy_write32_mask(rtwdev, R_RXSCOCCK, B_RXSCOCCK_TH, ++ rtw8852b_sco_cck_threshold[ch_element]); ++} ++ ++static u8 rtw8852b_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 rtw8852b_bb_gain { ++ u32 gain_g[BB_PATH_NUM_8852B]; ++ u32 gain_a[BB_PATH_NUM_8852B]; ++ u32 gain_mask; ++}; ++ ++static const struct rtw8852b_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 rtw8852b_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 rtw8852b_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; ++ 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 rtw8852b_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; ++ 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_8852B; 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]; ++ 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); ++ } ++} ++ ++static ++void rtw8852b_set_rxsc_rpl_comp(struct rtw89_dev *rtwdev, enum rtw89_subband subband) ++{ ++ const struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain; ++ u8 band = rtw89_subband_to_bb_gain_band(subband); ++ u32 val; ++ ++ val = FIELD_PREP(B_P0_RPL1_20_MASK, (gain->rpl_ofst_20[band][RF_PATH_A] + ++ gain->rpl_ofst_20[band][RF_PATH_B]) / 2) | ++ FIELD_PREP(B_P0_RPL1_40_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][0] + ++ gain->rpl_ofst_40[band][RF_PATH_B][0]) / 2) | ++ FIELD_PREP(B_P0_RPL1_41_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][1] + ++ gain->rpl_ofst_40[band][RF_PATH_B][1]) / 2); ++ 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 = FIELD_PREP(B_P0_RTL2_42_MASK, (gain->rpl_ofst_40[band][RF_PATH_A][2] + ++ gain->rpl_ofst_40[band][RF_PATH_B][2]) / 2) | ++ FIELD_PREP(B_P0_RTL2_80_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][0] + ++ gain->rpl_ofst_80[band][RF_PATH_B][0]) / 2) | ++ FIELD_PREP(B_P0_RTL2_81_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][1] + ++ gain->rpl_ofst_80[band][RF_PATH_B][1]) / 2) | ++ FIELD_PREP(B_P0_RTL2_8A_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][10] + ++ gain->rpl_ofst_80[band][RF_PATH_B][10]) / 2); ++ rtw89_phy_write32(rtwdev, R_P0_RPL2, val); ++ rtw89_phy_write32(rtwdev, R_P1_RPL2, val); ++ ++ val = FIELD_PREP(B_P0_RTL3_82_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][2] + ++ gain->rpl_ofst_80[band][RF_PATH_B][2]) / 2) | ++ FIELD_PREP(B_P0_RTL3_83_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][3] + ++ gain->rpl_ofst_80[band][RF_PATH_B][3]) / 2) | ++ FIELD_PREP(B_P0_RTL3_84_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][4] + ++ gain->rpl_ofst_80[band][RF_PATH_B][4]) / 2) | ++ FIELD_PREP(B_P0_RTL3_89_MASK, (gain->rpl_ofst_80[band][RF_PATH_A][9] + ++ gain->rpl_ofst_80[band][RF_PATH_B][9]) / 2); ++ rtw89_phy_write32(rtwdev, R_P0_RPL3, val); ++ rtw89_phy_write32(rtwdev, R_P1_RPL3, val); ++} ++ ++static void rtw8852b_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 = rtw8852b_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); ++ } ++ ++ rtw8852b_set_gain_error(rtwdev, subband, RF_PATH_A); ++ rtw8852b_set_gain_error(rtwdev, subband, RF_PATH_B); ++ rtw8852b_set_gain_offset(rtwdev, subband, phy_idx); ++ rtw8852b_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 rtw8852b_ctrl_bw(struct rtw89_dev *rtwdev, u8 pri_ch, u8 bw, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u32 rx_path_0; ++ ++ 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); ++ 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); ++ 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); ++ 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 A */ ++ rtw89_phy_write32_idx(rtwdev, R_P0_RFMODE_ORI_RX, ++ B_P0_RFMODE_ORI_RX_ALL, 0xaaa, phy_idx); ++ rtw89_phy_write32_idx(rtwdev, R_P1_RFMODE_ORI_RX, ++ B_P1_RFMODE_ORI_RX_ALL, 0xaaa, phy_idx); ++ break; ++ default: ++ rtw89_warn(rtwdev, "Fail to switch bw (bw:%d, pri ch:%d)\n", bw, ++ pri_ch); ++ } ++ ++ rtw8852b_bw_setting(rtwdev, bw, RF_PATH_A); ++ rtw8852b_bw_setting(rtwdev, bw, RF_PATH_B); ++ ++ rx_path_0 = rtw89_phy_read32_idx(rtwdev, R_CHBW_MOD_V1, B_ANT_RX_SEG0, ++ phy_idx); ++ 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 rtw8852b_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 rtw8852b_5m_mask(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx) ++{ ++ u8 pri_ch = chan->primary_channel; ++ 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 == 2; ++ break; ++ case RTW89_CHANNEL_WIDTH_80: ++ /* Prich=3: Mask 5M High, Prich=4: Mask 5M Low, Else: Disable */ ++ mask_5m_en = pri_ch == 3 || pri_ch == 4; ++ mask_5m_low = pri_ch == 4; ++ 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 rtw8852b_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 rtw8852b_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) ++ rtw8852b_ctrl_sco_cck(rtwdev, chan->primary_channel); ++ ++ rtw8852b_ctrl_ch(rtwdev, chan, phy_idx); ++ rtw8852b_ctrl_bw(rtwdev, pri_ch_idx, chan->band_width, phy_idx); ++ rtw8852b_ctrl_cck_en(rtwdev, cck_en); ++ 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_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); ++ } ++ rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, ++ chan->primary_channel); ++ rtw8852b_5m_mask(rtwdev, chan, phy_idx); ++ rtw8852b_bb_reset_all(rtwdev, phy_idx); ++} ++ ++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) ++{ ++ rtw8852b_set_channel_mac(rtwdev, chan, mac_idx); ++ rtw8852b_set_channel_bb(rtwdev, chan, phy_idx); ++ rtw8852b_set_channel_rf(rtwdev, chan, phy_idx); ++} ++ + static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 ref) + { +@@ -579,6 +1142,7 @@ static int rtw8852b_mac_disable_bb_rf(struct rtw89_dev *rtwdev) + static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .enable_bb_rf = rtw8852b_mac_enable_bb_rf, + .disable_bb_rf = rtw8852b_mac_disable_bb_rf, ++ .set_channel = rtw8852b_set_channel, + .read_efuse = rtw8852b_read_efuse, + .read_phycap = rtw8852b_read_phycap, + .power_trim = rtw8852b_power_trim, +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 0000000000000..761544b0dcca1 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -0,0 +1,256 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2019-2022 Realtek Corporation ++ */ ++ ++#include "coex.h" ++#include "debug.h" ++#include "mac.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw8852b.h" ++#include "rtw8852b_rfk.h" ++#include "rtw8852b_rfk_table.h" ++#include "rtw8852b_table.h" ++ ++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 _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); ++} +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 0000000000000..d54256bbc9a0a +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +@@ -0,0 +1,14 @@ ++/* 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_set_channel_rf(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, ++ enum rtw89_phy_idx phy_idx); ++ ++#endif +-- +2.13.6 + diff --git a/SOURCES/0022-wifi-rtw89-correct-6-GHz-scan-behavior.patch b/SOURCES/0022-wifi-rtw89-correct-6-GHz-scan-behavior.patch new file mode 100644 index 0000000..7e6fed9 --- /dev/null +++ b/SOURCES/0022-wifi-rtw89-correct-6-GHz-scan-behavior.patch @@ -0,0 +1,123 @@ +From 92197f95e056fedad7b200e093ceec5900979903 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:24 +0200 +Subject: [PATCH 022/142] wifi: rtw89: correct 6 GHz scan behavior +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 54997c24767b51bd762ff942431e8d37b535dc2e +Author: Po-Hao Huang +Date: Fri Oct 7 12:58:59 2022 +0800 + + wifi: rtw89: correct 6 GHz scan behavior + + Change active scan behavior to fit 6GHz requirements. There are many + different rules on active scan between 6GHz and 2GHz/5GHz, so if the + SSID is not specified, do fast passive scanning and limit number of + probe requests we send for now until new firmware can support all + rules. + + Signed-off-by: Po-Hao Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221007045900.10823-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 28 ++++++++++++++++++++++------ + drivers/net/wireless/realtek/rtw89/fw.h | 1 + + 2 files changed, 23 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 1d57a8c5e97df..dd2dc842681eb 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -2567,6 +2567,9 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, + struct rtw89_mac_chinfo *ch_info) + { + struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; ++ struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct cfg80211_scan_request *req = rtwvif->scan_req; + struct rtw89_pktofld_info *info; + u8 band, probe_count = 0; + +@@ -2578,13 +2581,13 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, + 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) { + ch_info->num_pkt = ssid_num; + band = rtw89_hw_to_nl80211_band(ch_info->ch_band); + + list_for_each_entry(info, &scan_info->pkt_list[band], list) { +- ch_info->probe_id = info->id; + ch_info->pkt_id[probe_count] = info->id; + if (++probe_count >= ssid_num) + break; +@@ -2593,9 +2596,16 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, + rtw89_err(rtwdev, "SSID num differs from list len\n"); + } + ++ if (ch_info->ch_band == RTW89_BAND_6G) { ++ if (ssid_num == 1 && req->ssids[0].ssid_len == 0) { ++ ch_info->tx_pkt = false; ++ if (!req->duration_mandatory) ++ ch_info->period -= RTW89_DWELL_TIME; ++ } ++ } ++ + switch (chan_type) { + case RTW89_CHAN_OPERATE: +- ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; + ch_info->central_ch = scan_info->op_chan; + ch_info->pri_ch = scan_info->op_pri_ch; + ch_info->ch_band = scan_info->op_band; +@@ -2604,8 +2614,9 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, + ch_info->num_pkt = 0; + break; + case RTW89_CHAN_DFS: +- ch_info->period = max_t(u8, ch_info->period, +- RTW89_DFS_CHAN_TIME); ++ 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: +@@ -2639,8 +2650,13 @@ static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev, + goto out; + } + +- ch_info->period = req->duration_mandatory ? +- req->duration : RTW89_CHANNEL_TIME; ++ if (req->duration_mandatory) ++ ch_info->period = req->duration; ++ else if (channel->band == NL80211_BAND_6GHZ) ++ ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_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; +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 0047d5d0e9b19..6ef392ef9c6fb 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -197,6 +197,7 @@ struct rtw89_h2creg_sch_tx_en { + + #define RTW89_H2C_MAX_SIZE 2048 + #define RTW89_CHANNEL_TIME 45 ++#define RTW89_CHANNEL_TIME_6G 20 + #define RTW89_DFS_CHAN_TIME 105 + #define RTW89_OFF_CHAN_TIME 100 + #define RTW89_DWELL_TIME 20 +-- +2.13.6 + diff --git a/SOURCES/0023-wifi-rtw89-fix-wrong-bandwidth-settings-after-scan.patch b/SOURCES/0023-wifi-rtw89-fix-wrong-bandwidth-settings-after-scan.patch new file mode 100644 index 0000000..428cee1 --- /dev/null +++ b/SOURCES/0023-wifi-rtw89-fix-wrong-bandwidth-settings-after-scan.patch @@ -0,0 +1,45 @@ +From 33f37d7827e0d87a8680566bcc3fd6f217761944 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:24 +0200 +Subject: [PATCH 023/142] wifi: rtw89: fix wrong bandwidth settings after scan +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 478132050360a5cf19cc1b3fc9fcf1e56a483481 +Author: Po-Hao Huang +Date: Fri Oct 7 12:59:00 2022 +0800 + + wifi: rtw89: fix wrong bandwidth settings after scan + + Set channel in driver side to configure Tx power and channel index + correctly after scan. Before this, beacons with bandwidth larger than + 20M bandwidth will be dropped by mac80211 due to frequency mismatch. + + Signed-off-by: Po-Hao Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221007045900.10823-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index dd2dc842681eb..d3500a70af4dd 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -2775,6 +2775,7 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + + if (rtwvif->net_type != RTW89_NET_TYPE_NO_LINK) + rtw89_store_op_chan(rtwdev, false); ++ rtw89_set_channel(rtwdev); + } + + void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) +-- +2.13.6 + diff --git a/SOURCES/0024-wifi-rtw89-8852b-add-chip_ops-set_channel_help.patch b/SOURCES/0024-wifi-rtw89-8852b-add-chip_ops-set_channel_help.patch new file mode 100644 index 0000000..532e45a --- /dev/null +++ b/SOURCES/0024-wifi-rtw89-8852b-add-chip_ops-set_channel_help.patch @@ -0,0 +1,143 @@ +From fb633de5bb45947abf4265e9617d65b71203385c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:24 +0200 +Subject: [PATCH 024/142] wifi: rtw89: 8852b: add chip_ops::set_channel_help +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit d0a95ef3ed86762d2356fd5443bebe7a6ef140c7 +Author: Ping-Ke Shih +Date: Sun Oct 9 20:53:55 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops::set_channel_help + + This chip_ops is to assist set_channel, because we need setup and restore + hardware before and after set_channel. + + Before set_channel, we stop transmitting, reset PPDU status, disable TSSI, + and disable ADC. After set_channel, do opposite things in reverse order. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 84 +++++++++++++++++++++++++++ + 1 file changed, 84 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index b50fff00b1393..af04a0284b560 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -854,6 +854,30 @@ static void rtw8852b_bb_reset_all(struct rtw89_dev *rtwdev, enum rtw89_phy_idx p + rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1, phy_idx); + } + ++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_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) + { +@@ -897,6 +921,65 @@ static void rtw8852b_set_channel(struct rtw89_dev *rtwdev, + 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 u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 ref) + { +@@ -1143,6 +1226,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .enable_bb_rf = rtw8852b_mac_enable_bb_rf, + .disable_bb_rf = rtw8852b_mac_disable_bb_rf, + .set_channel = rtw8852b_set_channel, ++ .set_channel_help = rtw8852b_set_channel_help, + .read_efuse = rtw8852b_read_efuse, + .read_phycap = rtw8852b_read_phycap, + .power_trim = rtw8852b_power_trim, +-- +2.13.6 + diff --git a/SOURCES/0025-wifi-rtw89-8852b-add-power-on-off-functions.patch b/SOURCES/0025-wifi-rtw89-8852b-add-power-on-off-functions.patch new file mode 100644 index 0000000..44afda4 --- /dev/null +++ b/SOURCES/0025-wifi-rtw89-8852b-add-power-on-off-functions.patch @@ -0,0 +1,335 @@ +From f655006252045c5f4009c8e9e5c82317d1a51d17 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:24 +0200 +Subject: [PATCH 025/142] wifi: rtw89: 8852b: add power on/off functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit b23b36efbdac603c491197dae1d27a3c5ac4b01c +Author: Ping-Ke Shih +Date: Sun Oct 9 20:53:56 2022 +0800 + + wifi: rtw89: 8852b: add power on/off functions + + We need power on function to enable hardware circuits of MAC/BB/RF, and + then download firmware and load PHY parameters. After more settings, it + starts to work. When it enters idle, use power off function to have the + lowest power consumption. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.h | 1 + + drivers/net/wireless/realtek/rtw89/reg.h | 18 +++ + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 192 ++++++++++++++++++++++++++ + 3 files changed, 211 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index a9867ac351da7..a6cbafb75a2b8 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -1014,6 +1014,7 @@ enum rtw89_mac_xtal_si_offset { + #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) + }; + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 1539973296cd1..376ce7135b388 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -34,6 +34,9 @@ + #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) +@@ -42,6 +45,9 @@ + #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) +@@ -118,6 +124,9 @@ + #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_WCPU_EN BIT(1) +@@ -125,6 +134,7 @@ + + #define R_AX_WLLPS_CTRL 0x0090 + #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) +@@ -229,6 +239,9 @@ + + #define R_AX_GPIO0_7_FUNC_SEL 0x02D0 + ++#define R_AX_EECS_EESK_FUNC_SEL 0x02D8 ++#define B_AX_PINMUX_EESK_FUNC_SEL_MASK GENMASK(7, 4) ++ + #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 +@@ -253,6 +266,10 @@ + #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_C3_L1_MASK GENMASK(5, 4) ++#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) +@@ -449,6 +466,7 @@ + #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) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index af04a0284b560..f54a4ea3c6b53 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -56,6 +56,194 @@ static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { + NULL}, + }; + ++static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) ++{ ++ u32 val32; ++ u32 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_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; ++ ++ 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); ++ 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); ++ ++ if (rtwdev->hal.cv == CHIP_CBV) { ++ 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; ++ u32 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_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 rtw8852be_efuse_parsing(struct rtw89_efuse *efuse, + struct rtw8852b_efuse *map) + { +@@ -1233,6 +1421,8 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .set_txpwr = rtw8852b_set_txpwr, + .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852b_init_txpwr_unit, ++ .pwr_on_func = rtw8852b_pwr_on_func, ++ .pwr_off_func = rtw8852b_pwr_off_func, + }; + + const struct rtw89_chip_info rtw8852b_chip_info = { +@@ -1242,6 +1432,8 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .dle_scc_rsvd_size = 98304, + .hfc_param_ini = rtw8852b_hfc_param_ini_pcie, + .dle_mem = rtw8852b_dle_mem_pcie, ++ .pwr_on_seq = NULL, ++ .pwr_off_seq = NULL, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 1216, + .logical_efuse_size = 2048, +-- +2.13.6 + diff --git a/SOURCES/0026-wifi-rtw89-8852b-add-basic-baseband-chip_ops.patch b/SOURCES/0026-wifi-rtw89-8852b-add-basic-baseband-chip_ops.patch new file mode 100644 index 0000000..03248a6 --- /dev/null +++ b/SOURCES/0026-wifi-rtw89-8852b-add-basic-baseband-chip_ops.patch @@ -0,0 +1,93 @@ +From e309aa380bd4b29305c760137b89bab98f920be5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:24 +0200 +Subject: [PATCH 026/142] wifi: rtw89: 8852b: add basic baseband chip_ops +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit a804479839e1cf502a76c407f3e07135ddbe5032 +Author: Ping-Ke Shih +Date: Sun Oct 9 20:53:57 2022 +0800 + + wifi: rtw89: 8852b: add basic baseband chip_ops + + chip_ops::bb_reset is to reset baseband state after loading parameters, + because its state could be unpredictable at that moment. The other is + chip_ops::bb_sethw that is to set some baseband settings not including in + parameter tables. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 42 +++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index f54a4ea3c6b53..f13c657f4d68d 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -1066,6 +1066,46 @@ static void rtw8852b_bb_reset_en(struct rtw89_dev *rtwdev, enum rtw89_band band, + } + } + ++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); ++ rtw8852b_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_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 rtw8852b_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); ++ ++ rtw8852b_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 rtw8852b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) + { +@@ -1413,6 +1453,8 @@ static int rtw8852b_mac_disable_bb_rf(struct rtw89_dev *rtwdev) + static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .enable_bb_rf = rtw8852b_mac_enable_bb_rf, + .disable_bb_rf = rtw8852b_mac_disable_bb_rf, ++ .bb_reset = rtw8852b_bb_reset, ++ .bb_sethw = rtw8852b_bb_sethw, + .set_channel = rtw8852b_set_channel, + .set_channel_help = rtw8852b_set_channel_help, + .read_efuse = rtw8852b_read_efuse, +-- +2.13.6 + diff --git a/SOURCES/0027-wifi-rtw89-8852b-add-chip_ops-to-get-thermal.patch b/SOURCES/0027-wifi-rtw89-8852b-add-chip_ops-to-get-thermal.patch new file mode 100644 index 0000000..5a7618a --- /dev/null +++ b/SOURCES/0027-wifi-rtw89-8852b-add-chip_ops-to-get-thermal.patch @@ -0,0 +1,67 @@ +From 5348102de57043c51fdad0841b87a652e2bbaa22 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:24 +0200 +Subject: [PATCH 027/142] wifi: rtw89: 8852b: add chip_ops to get thermal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 8f88474ce3eca2dd8fb4e08d4b6ab71e76312e3e +Author: Ping-Ke Shih +Date: Sun Oct 9 20:53:58 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops to get thermal + + Thermal value reflects temperature that will affect RF performance, so + we re-calibrate RF characteristics if delta of thermal over a threshold. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index f13c657f4d68d..09374b92f6617 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -1397,6 +1397,23 @@ rtw8852b_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + return 0; + } + ++static u8 rtw8852b_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 int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) + { + int ret; +@@ -1463,6 +1480,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .set_txpwr = rtw8852b_set_txpwr, + .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852b_init_txpwr_unit, ++ .get_thermal = rtw8852b_get_thermal, + .pwr_on_func = rtw8852b_pwr_on_func, + .pwr_off_func = rtw8852b_pwr_off_func, + }; +-- +2.13.6 + diff --git a/SOURCES/0028-wifi-rtw89-8852b-add-chip_ops-related-to-BT-coexiste.patch b/SOURCES/0028-wifi-rtw89-8852b-add-chip_ops-related-to-BT-coexiste.patch new file mode 100644 index 0000000..7558f68 --- /dev/null +++ b/SOURCES/0028-wifi-rtw89-8852b-add-chip_ops-related-to-BT-coexiste.patch @@ -0,0 +1,385 @@ +From 7b97ddc16bd5499e045d2398917c82763568e501 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:25 +0200 +Subject: [PATCH 028/142] wifi: rtw89: 8852b: add chip_ops related to BT + coexistence +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 98bf0ddf20fc2d70d11f1af6e041ee4fad1392ac +Author: Ping-Ke Shih +Date: Sun Oct 9 20:53:59 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops related to BT coexistence + + These chip_ops are used to assist BT coexistence module to control chip + specific operations, such as initial, pre-AGC, BT grant, set wifi priority + and tx power, RX gain, and get BT counter. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 305 ++++++++++++++++++++++++++ + 2 files changed, 306 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 376ce7135b388..570fb1aee80c3 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3151,6 +3151,7 @@ + #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 +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 09374b92f6617..ee5a29f35db25 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -56,6 +56,44 @@ static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { + NULL}, + }; + ++static const struct rtw89_reg3_def rtw8852b_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(rtw8852b_btc_preagc_en_defs); ++ ++static const struct rtw89_reg3_def rtw8852b_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(rtw8852b_btc_preagc_dis_defs); ++ + static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) + { + u32 val32; +@@ -1397,6 +1435,55 @@ rtw8852b_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + return 0; + } + ++static void rtw8852b_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en) ++{ ++ rtw89_phy_write_reg3_tbl(rtwdev, bt_en ? &rtw8852b_btc_preagc_en_defs_tbl : ++ &rtw8852b_btc_preagc_dis_defs_tbl); ++} ++ ++static void rtw8852b_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) ++{ ++ if (btg) { ++ 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 u8 rtw8852b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) + { + if (rtwdev->is_tssi_mode[rf_path]) { +@@ -1414,6 +1501,212 @@ static u8 rtw8852b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_p + return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); + } + ++static void rtw8852b_btc_set_rfe(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_module *module = &btc->mdinfo; ++ ++ module->rfe_type = rtwdev->efuse.rfe_type; ++ module->cv = rtwdev->hal.cv; ++ module->bt_solo = 0; ++ module->switch_type = BTC_SWITCH_INTERNAL; ++ ++ if (module->rfe_type > 0) ++ module->ant.num = module->rfe_type % 2 ? 2 : 3; ++ else ++ module->ant.num = 2; ++ ++ module->ant.diversity = 0; ++ module->ant.isolation = 10; ++ ++ if (module->ant.num == 3) { ++ module->ant.type = BTC_ANT_DEDICATED; ++ module->bt_pos = BTC_BT_ALONE; ++ } else { ++ module->ant.type = BTC_ANT_SHARED; ++ module->bt_pos = BTC_BT_BTG; ++ } ++} ++ ++static ++void rtw8852b_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 rtw8852b_btc_init_cfg(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_module *module = &btc->mdinfo; ++ 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 (module->ant.type == BTC_ANT_SHARED) { ++ rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff); ++ rtw8852b_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 */ ++ rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); ++ rtw8852b_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 */ ++ rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_SS_GROUP, 0x5df); ++ rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_SS_GROUP, 0x5df); ++ rtw8852b_set_trx_mask(rtwdev, RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff); ++ rtw8852b_set_trx_mask(rtwdev, RF_PATH_B, BTC_BT_TX_GROUP, 0x5ff); ++ } ++ ++ /* 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); ++ btc->cx.wl.status.map.init_ok = true; ++} ++ ++static ++void rtw8852b_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 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 ++s8 rtw8852b_btc_get_bt_rssi(struct rtw89_dev *rtwdev, s8 val) ++{ ++ return clamp_t(s8, val, -100, 0) + 100; ++} ++ ++static ++void rtw8852b_btc_update_bt_cnt(struct rtw89_dev *rtwdev) ++{ ++ /* Feature move to firmware */ ++} ++ ++static void rtw8852b_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, 0x579); ++ 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 rtw8852b_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) ++{ ++} ++ + static int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) + { + int ret; +@@ -1481,8 +1774,20 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, + .init_txpwr_unit = rtw8852b_init_txpwr_unit, + .get_thermal = rtw8852b_get_thermal, ++ .ctrl_btg = rtw8852b_ctrl_btg, ++ .bb_ctrl_btc_preagc = rtw8852b_bb_ctrl_btc_preagc, + .pwr_on_func = rtw8852b_pwr_on_func, + .pwr_off_func = rtw8852b_pwr_off_func, ++ ++ .btc_set_rfe = rtw8852b_btc_set_rfe, ++ .btc_init_cfg = rtw8852b_btc_init_cfg, ++ .btc_set_wl_pri = rtw8852b_btc_set_wl_pri, ++ .btc_set_wl_txpwr_ctrl = rtw8852b_btc_set_wl_txpwr_ctrl, ++ .btc_get_bt_rssi = rtw8852b_btc_get_bt_rssi, ++ .btc_update_bt_cnt = rtw8852b_btc_update_bt_cnt, ++ .btc_wl_s1_standby = rtw8852b_btc_wl_s1_standby, ++ .btc_set_wl_rx_gain = rtw8852b_btc_set_wl_rx_gain, ++ .btc_set_policy = rtw89_btc_set_policy, + }; + + const struct rtw89_chip_info rtw8852b_chip_info = { +-- +2.13.6 + diff --git a/SOURCES/0029-wifi-rtw89-8852b-add-chip_ops-to-query-PPDU.patch b/SOURCES/0029-wifi-rtw89-8852b-add-chip_ops-to-query-PPDU.patch new file mode 100644 index 0000000..bf1809a --- /dev/null +++ b/SOURCES/0029-wifi-rtw89-8852b-add-chip_ops-to-query-PPDU.patch @@ -0,0 +1,80 @@ +From e39ff157ac902c8fe9909db4a7b83c43adb04de3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:25 +0200 +Subject: [PATCH 029/142] wifi: rtw89: 8852b: add chip_ops to query PPDU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit bf958f76cf97663d79b4f90a08d38c5b9bb56082 +Author: Ping-Ke Shih +Date: Sun Oct 9 20:54:00 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops to query PPDU + + Add to parse PPDU to get frequency and RSSI of received packets. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 32 +++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index ee5a29f35db25..abb35553a2b04 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -1707,6 +1707,37 @@ static void rtw8852b_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) + { + } + ++static void rtw8852b_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 rtw8852b_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; ++ ++ 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) ++ rtw8852b_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); ++} ++ + static int rtw8852b_mac_enable_bb_rf(struct rtw89_dev *rtwdev) + { + int ret; +@@ -1775,6 +1806,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .init_txpwr_unit = rtw8852b_init_txpwr_unit, + .get_thermal = rtw8852b_get_thermal, + .ctrl_btg = rtw8852b_ctrl_btg, ++ .query_ppdu = rtw8852b_query_ppdu, + .bb_ctrl_btc_preagc = rtw8852b_bb_ctrl_btc_preagc, + .pwr_on_func = rtw8852b_pwr_on_func, + .pwr_off_func = rtw8852b_pwr_off_func, +-- +2.13.6 + diff --git a/SOURCES/0030-wifi-rtw89-8852b-add-chip_ops-to-configure-TX-RX-pat.patch b/SOURCES/0030-wifi-rtw89-8852b-add-chip_ops-to-configure-TX-RX-pat.patch new file mode 100644 index 0000000..66c5cb4 --- /dev/null +++ b/SOURCES/0030-wifi-rtw89-8852b-add-chip_ops-to-configure-TX-RX-pat.patch @@ -0,0 +1,198 @@ +From bca1ff917141a02a263f4e180b65d7690a526350 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:25 +0200 +Subject: [PATCH 030/142] wifi: rtw89: 8852b: add chip_ops to configure TX/RX + path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 8915a256538d0e81fe02c5f68368e5787df261d5 +Author: Ping-Ke Shih +Date: Sun Oct 9 20:54:01 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops to configure TX/RX path + + To support variant models, such as 1x1 or 1T2R, we need this chip_ops to + change the path accordingly. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-8-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 4 + + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 112 ++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b.h | 3 + + 3 files changed, 119 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 570fb1aee80c3..5482e32a72d55 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3666,6 +3666,8 @@ + #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 R_S0_RXDC 0x12D4 +@@ -3779,6 +3781,8 @@ + #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 +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index abb35553a2b04..a5156d7aca5b8 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -1484,6 +1484,117 @@ static void rtw8852b_ctrl_btg(struct rtw89_dev *rtwdev, bool btg) + } + } + ++void rtw8852b_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_SUB_ENTITY_0); ++ 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); ++ } ++ ++ rtw8852b_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)) ++ rtw8852b_ctrl_btg(rtwdev, true); ++ else ++ rtw8852b_ctrl_btg(rtwdev, false); ++ ++ 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 rtw8852b_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 rtw8852b_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_hal *hal = &rtwdev->hal; ++ enum rtw89_rf_path_bit rx_path = hal->antenna_rx ? hal->antenna_rx : RF_AB; ++ ++ rtw8852b_bb_ctrl_rx_path(rtwdev, rx_path); ++ rtw8852b_bb_ctrl_rf_mode_rx_path(rtwdev, rx_path); ++ ++ 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); ++ } 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 rtw8852b_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) + { + if (rtwdev->is_tssi_mode[rf_path]) { +@@ -1808,6 +1919,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .ctrl_btg = rtw8852b_ctrl_btg, + .query_ppdu = rtw8852b_query_ppdu, + .bb_ctrl_btc_preagc = rtw8852b_bb_ctrl_btc_preagc, ++ .cfg_txrx_path = rtw8852b_bb_cfg_txrx_path, + .pwr_on_func = rtw8852b_pwr_on_func, + .pwr_off_func = rtw8852b_pwr_off_func, + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.h b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +index bc0a383c4a390..33f621014e497 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +@@ -87,4 +87,7 @@ struct rtw8852b_efuse { + + extern const struct rtw89_chip_info rtw8852b_chip_info; + ++void rtw8852b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, ++ enum rtw89_rf_path_bit rx_path); ++ + #endif +-- +2.13.6 + diff --git a/SOURCES/0031-wifi-rtw89-8852b-add-functions-to-control-BB-to-assi.patch b/SOURCES/0031-wifi-rtw89-8852b-add-functions-to-control-BB-to-assi.patch new file mode 100644 index 0000000..b9b155b --- /dev/null +++ b/SOURCES/0031-wifi-rtw89-8852b-add-functions-to-control-BB-to-assi.patch @@ -0,0 +1,408 @@ +From a5974f763e36a066e086fb1ad963080d94ad6ecd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:25 +0200 +Subject: [PATCH 031/142] wifi: rtw89: 8852b: add functions to control BB to + assist RF calibrations +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 572fd2ab377b123e52b442d015f9605409a21ad9 +Author: Ping-Ke Shih +Date: Sun Oct 9 20:54:02 2022 +0800 + + wifi: rtw89: 8852b: add functions to control BB to assist RF calibrations + + When we are going to do RF calibrations, they need BB helpers to control + TX PLCP, power, path and mode. Also, it they need helpers to backup and + restore some registers before and after RF calibrations. Then, use flow of + RF calibrations will be like backup registers, configure calibration, + configure TX parameters, measure calibration result, and finally restore + registers. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-9-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 288 ++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b.h | 44 ++++ + 2 files changed, 332 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index a5156d7aca5b8..290d83cb83d5a 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -56,6 +56,129 @@ static const struct rtw89_dle_mem rtw8852b_dle_mem_pcie[] = { + NULL}, + }; + ++static const struct rtw89_reg3_def rtw8852b_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 rtw8852b_btc_preagc_en_defs[] = { + {0x46D0, GENMASK(1, 0), 0x3}, + {0x4790, GENMASK(1, 0), 0x3}, +@@ -1435,6 +1558,171 @@ rtw8852b_init_txpwr_unit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + return 0; + } + ++void rtw8852b_bb_set_plcp_tx(struct rtw89_dev *rtwdev) ++{ ++ const struct rtw89_reg3_def *def = rtw8852b_pmac_ht20_mcs7_tbl; ++ u8 i; ++ ++ for (i = 0; i < ARRAY_SIZE(rtw8852b_pmac_ht20_mcs7_tbl); i++, def++) ++ rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data); ++} ++ ++static void rtw8852b_stop_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852b_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 rtw8852b_start_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852b_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx) ++{ ++ enum rtw8852b_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 rtw8852b_bb_set_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852b_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ ++ if (!tx_info->en_pmac_tx) { ++ rtw8852b_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); ++ ++ rtw8852b_start_pmac_tx(rtwdev, tx_info, idx); ++} ++ ++void rtw8852b_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, ++ u16 tx_cnt, u16 period, u16 tx_time, ++ enum rtw89_phy_idx idx) ++{ ++ struct rtw8852b_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; ++ ++ rtw8852b_bb_set_pmac_tx(rtwdev, &tx_info, idx); ++} ++ ++void rtw8852b_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 rtw8852b_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"); ++ } ++} ++ ++void rtw8852b_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); ++} ++ ++void rtw8852b_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, ++ struct rtw8852b_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); ++} ++ ++void rtw8852b_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, ++ const struct rtw8852b_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 rtw8852b_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev, bool bt_en) + { + rtw89_phy_write_reg3_tbl(rtwdev, bt_en ? &rtw8852b_btc_preagc_en_defs_tbl : +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.h b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +index 33f621014e497..4f9b3d4768790 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.h +@@ -10,6 +10,13 @@ + #define RF_PATH_NUM_8852B 2 + #define BB_PATH_NUM_8852B 2 + ++enum rtw8852b_pmac_mode { ++ NONE_TEST, ++ PKTS_TX, ++ PKTS_RX, ++ CONT_TX ++}; ++ + struct rtw8852b_u_efuse { + u8 rsvd[0x88]; + u8 mac_addr[ETH_ALEN]; +@@ -85,9 +92,46 @@ struct rtw8852b_efuse { + }; + } __packed; + ++struct rtw8852b_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 rtw8852b_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 */ ++}; ++ + extern const struct rtw89_chip_info rtw8852b_chip_info; + ++void rtw8852b_bb_set_plcp_tx(struct rtw89_dev *rtwdev); ++void rtw8852b_bb_set_pmac_tx(struct rtw89_dev *rtwdev, ++ struct rtw8852b_bb_pmac_info *tx_info, ++ enum rtw89_phy_idx idx); ++void rtw8852b_bb_set_pmac_pkt_tx(struct rtw89_dev *rtwdev, u8 enable, ++ u16 tx_cnt, u16 period, u16 tx_time, ++ enum rtw89_phy_idx idx); ++void rtw8852b_bb_set_power(struct rtw89_dev *rtwdev, s16 pwr_dbm, ++ enum rtw89_phy_idx idx); ++void rtw8852b_bb_cfg_tx_path(struct rtw89_dev *rtwdev, u8 tx_path); + void rtw8852b_bb_ctrl_rx_path(struct rtw89_dev *rtwdev, + enum rtw89_rf_path_bit rx_path); ++void rtw8852b_bb_tx_mode_switch(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx idx, u8 mode); ++void rtw8852b_bb_backup_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, ++ struct rtw8852b_bb_tssi_bak *bak); ++void rtw8852b_bb_restore_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx idx, ++ const struct rtw8852b_bb_tssi_bak *bak); + + #endif +-- +2.13.6 + diff --git a/SOURCES/0032-wifi-rtw89-8852b-add-basic-attributes-of-chip_info.patch b/SOURCES/0032-wifi-rtw89-8852b-add-basic-attributes-of-chip_info.patch new file mode 100644 index 0000000..719f5fd --- /dev/null +++ b/SOURCES/0032-wifi-rtw89-8852b-add-basic-attributes-of-chip_info.patch @@ -0,0 +1,318 @@ +From 87292798d046a87163182c53f1f64b31118a2a78 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:25 +0200 +Subject: [PATCH 032/142] wifi: rtw89: 8852b: add basic attributes of chip_info +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit b8fe87b816851d08a31c7c9589855c8535672299 +Author: Ping-Ke Shih +Date: Sun Oct 9 20:54:03 2022 +0800 + + wifi: rtw89: 8852b: add basic attributes of chip_info + + Add 8852b specific constant tables and basic attributes containing + common chip_ops, firmware name, supported TX/RX NSS, number of CAM, + coexistence version, control register set, and so on. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221009125403.19662-10-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 235 ++++++++++++++++++++++++++ + 1 file changed, 235 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 290d83cb83d5a..0918b75ab1d94 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -217,6 +217,150 @@ static const struct rtw89_reg3_def rtw8852b_btc_preagc_dis_defs[] = { + + static DECLARE_PHY_REG3_TBL(rtw8852b_btc_preagc_dis_defs); + ++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 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_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, ++ .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_btc_rf_trx_para rtw89_btc_8852b_rf_ul[] = { ++ {15, 0, 0, 7}, /* 0 -> original */ ++ {15, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ ++ {15, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ ++ {15, 0, 0, 7}, /* 3- >reserved for shared-antenna */ ++ {15, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ ++ {15, 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 const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_dl[] = { ++ {15, 0, 0, 7}, /* 0 -> original */ ++ {15, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ ++ {15, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ ++ {15, 0, 0, 7}, /* 3- >reserved for shared-antenna */ ++ {15, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ ++ {15, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ ++ {15, 1, 0, 7}, ++ {15, 1, 0, 7}, ++ {15, 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_BT_MODEM, 4, 0x178), ++}; ++ ++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 int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev) + { + u32 val32; +@@ -2195,10 +2339,13 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .disable_bb_rf = rtw8852b_mac_disable_bb_rf, + .bb_reset = rtw8852b_bb_reset, + .bb_sethw = rtw8852b_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 = rtw8852b_read_efuse, + .read_phycap = rtw8852b_read_phycap, ++ .fem_setup = NULL, + .power_trim = rtw8852b_power_trim, + .set_txpwr = rtw8852b_set_txpwr, + .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, +@@ -2208,8 +2355,16 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .query_ppdu = rtw8852b_query_ppdu, + .bb_ctrl_btc_preagc = rtw8852b_bb_ctrl_btc_preagc, + .cfg_txrx_path = rtw8852b_bb_cfg_txrx_path, ++ .set_txpwr_ul_tb_offset = rtw8852b_set_txpwr_ul_tb_offset, + .pwr_on_func = rtw8852b_pwr_on_func, + .pwr_off_func = rtw8852b_pwr_off_func, ++ .fill_txdesc = rtw89_core_fill_txdesc, ++ .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, ++ .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, + + .btc_set_rfe = rtw8852b_btc_set_rfe, + .btc_init_cfg = rtw8852b_btc_init_cfg, +@@ -2225,12 +2380,46 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + const struct rtw89_chip_info rtw8852b_chip_info = { + .chip_id = RTL8852B, + .ops = &rtw8852b_chip_ops, ++ .fw_name = "rtw89/rtw8852b_fw.bin", + .fifo_size = 196608, + .dle_scc_rsvd_size = 98304, ++ .max_amsdu_limit = 3500, ++ .dis_2g_40m_ul_ofdma = true, ++ .rsvd_ple_ofst = 0x2f800, + .hfc_param_ini = rtw8852b_hfc_param_ini_pcie, + .dle_mem = rtw8852b_dle_mem_pcie, ++ .rf_base_addr = {0xe000, 0xf000}, + .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, ++ .byr_table = &rtw89_8852b_byr_table, ++ .txpwr_lmt_2g = &rtw89_8852b_txpwr_lmt_2g, ++ .txpwr_lmt_5g = &rtw89_8852b_txpwr_lmt_5g, ++ .txpwr_lmt_ru_2g = &rtw89_8852b_txpwr_lmt_ru_2g, ++ .txpwr_lmt_ru_5g = &rtw89_8852b_txpwr_lmt_ru_5g, ++ .txpwr_factor_rf = 2, ++ .txpwr_factor_mac = 1, ++ .dig_table = NULL, ++ .dig_regs = &rtw8852b_dig_regs, ++ .tssi_dbw_table = NULL, ++ .support_chanctx_num = 0, ++ .support_bands = BIT(NL80211_BAND_2GHZ) | ++ BIT(NL80211_BAND_5GHZ), ++ .support_bw160 = false, ++ .hw_sec_hdr = 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_v1 = false, + .sec_ctrl_efuse_size = 4, + .physical_efuse_size = 1216, + .logical_efuse_size = 2048, +@@ -2239,6 +2428,52 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .dav_log_efuse_size = 16, + .phycap_addr = 0x580, + .phycap_size = 128, ++ .para_ver = 0, ++ .wlcx_desired = 0x05050000, ++ .btcx_desired = 0x5, ++ .scbd = 0x1, ++ .mailbox = 0x1, ++ .btc_fwinfo_buf = 1024, ++ ++ .fcxbtcrpt_ver = 1, ++ .fcxtdma_ver = 1, ++ .fcxslots_ver = 1, ++ .fcxcysta_ver = 2, ++ .fcxstep_ver = 2, ++ .fcxnullsta_ver = 1, ++ .fcxmreg_ver = 1, ++ .fcxgpiodbg_ver = 1, ++ .fcxbtver_ver = 1, ++ .fcxbtscan_ver = 1, ++ .fcxbtafh_ver = 1, ++ .fcxbtdevinfo_ver = 1, ++ .afh_guard_ch = 6, ++ .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_num = ARRAY_SIZE(rtw89_btc_8852b_rf_ul), ++ .rf_para_ulink = rtw89_btc_8852b_rf_ul, ++ .rf_para_dlink_num = ARRAY_SIZE(rtw89_btc_8852b_rf_dl), ++ .rf_para_dlink = rtw89_btc_8852b_rf_dl, ++ .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), ++ .h2c_ctrl_reg = R_AX_H2CREG_CTRL, ++ .h2c_regs = rtw8852b_h2c_regs, ++ .c2h_ctrl_reg = R_AX_C2HREG_CTRL, ++ .c2h_regs = rtw8852b_c2h_regs, ++ .page_regs = &rtw8852b_page_regs, ++ .dcfo_comp = &rtw8852b_dcfo_comp, ++ .dcfo_comp_sft = 3, ++ .imr_info = &rtw8852b_imr_info, ++ .rrsr_cfgs = &rtw8852b_rrsr_cfgs, + .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), +-- +2.13.6 + diff --git a/SOURCES/0033-wifi-rtw89-8852b-rfk-add-DACK.patch b/SOURCES/0033-wifi-rtw89-8852b-rfk-add-DACK.patch new file mode 100644 index 0000000..051094a --- /dev/null +++ b/SOURCES/0033-wifi-rtw89-8852b-rfk-add-DACK.patch @@ -0,0 +1,559 @@ +From c699d8f44de1e938847d9039344ef0eeeb0a9eab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:25 +0200 +Subject: [PATCH 033/142] wifi: rtw89: 8852b: rfk: add DACK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 16be5e3be0e5794b5e7227c63b440f3fdb9c22ce +Author: Ping-Ke Shih +Date: Wed Oct 12 16:32:30 2022 +0800 + + wifi: rtw89: 8852b: rfk: add DACK + + DACK (digital-to-analog converters calibration) is used to calibrate DAC + to output good quality signals. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221012083234.20224-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 21 ++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 432 ++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h | 1 + + 3 files changed, 454 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 5482e32a72d55..40b66c071b27d 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3524,6 +3524,7 @@ + #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 +@@ -4378,6 +4379,8 @@ + #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_IDLE BIT(9) + #define B_DRCK_EN BIT(6) +@@ -4385,15 +4388,28 @@ + #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 R_P0_CFCH_BW1 0xC0D8 + #define B_P0_CFCH_BW1 GENMASK(8, 5) ++#define R_ADDCK0D 0xC0F0 ++#define B_ADDCK0D_VAL2 GENMASK(31, 26) ++#define B_ADDCK0D_VAL GENMASK(25, 16) + #define R_ADDCK0 0xC0F4 ++#define B_ADDCK0_TRG BIT(11) + #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) +@@ -4434,8 +4450,13 @@ + #define B_PATH0_BW_SEL_MSK_V1 GENMASK(8, 5) + #define R_PATH1_BW_SEL_V1 0xC1D8 + #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 +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +index 761544b0dcca1..5c35f4fb38ff5 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -12,6 +12,8 @@ + #include "rtw8852b_rfk_table.h" + #include "rtw8852b_table.h" + ++#define ADDC_T_AVG 100 ++ + static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + { + u8 val; +@@ -30,6 +32,436 @@ static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + return val; + } + ++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 += sign_extend32(FIELD_GET(0xfff000, tmp), 11); ++ dc_im += sign_extend32(FIELD_GET(0xfff, tmp), 11); ++ } ++ ++ 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"); ++} ++ ++void rtw8852b_dack(struct rtw89_dev *rtwdev) ++{ ++ u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0); ++ ++ 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); ++} ++ + static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw, bool dav) + { +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +index d54256bbc9a0a..bc2ff7380b927 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +@@ -7,6 +7,7 @@ + + #include "core.h" + ++void rtw8852b_dack(struct rtw89_dev *rtwdev); + void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +-- +2.13.6 + diff --git a/SOURCES/0034-wifi-rtw89-8852b-rfk-add-RCK.patch b/SOURCES/0034-wifi-rtw89-8852b-rfk-add-RCK.patch new file mode 100644 index 0000000..5da21ed --- /dev/null +++ b/SOURCES/0034-wifi-rtw89-8852b-rfk-add-RCK.patch @@ -0,0 +1,106 @@ +From f632e0efad2e9347aba7d5b1df4d0dbb8fa9564d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:25 +0200 +Subject: [PATCH 034/142] wifi: rtw89: 8852b: rfk: add RCK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 10298b53bff642e586e5b82616914c9fa3d9a906 +Author: Ping-Ke Shih +Date: Wed Oct 12 16:32:31 2022 +0800 + + wifi: rtw89: 8852b: rfk: add RCK + + RCK is synchronize RC calibration. Driver triggers this calibration and + sets the result to register. This calibration is needed once when interface + is going to up. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221012083234.20224-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 43 +++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h | 1 + + 2 files changed, 44 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +index 5c35f4fb38ff5..1dcb900ef7007 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -32,6 +32,41 @@ static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + return val; + } + ++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); +@@ -453,6 +488,14 @@ static void _dac_cal(struct rtw89_dev *rtwdev, bool force) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); + } + ++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) + { + u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +index bc2ff7380b927..84325abc7f2c2 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +@@ -7,6 +7,7 @@ + + #include "core.h" + ++void rtw8852b_rck(struct rtw89_dev *rtwdev); + void rtw8852b_dack(struct rtw89_dev *rtwdev); + void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, +-- +2.13.6 + diff --git a/SOURCES/0035-wifi-rtw89-8852b-rfk-add-RX-DCK.patch b/SOURCES/0035-wifi-rtw89-8852b-rfk-add-RX-DCK.patch new file mode 100644 index 0000000..9e8e562 --- /dev/null +++ b/SOURCES/0035-wifi-rtw89-8852b-rfk-add-RX-DCK.patch @@ -0,0 +1,152 @@ +From 9c5751f4eedd79a896915d7248106bb7e794b537 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 035/142] wifi: rtw89: 8852b: rfk: add RX DCK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 212671074ab2f3e33fd5e95392c7356410ad7f8d +Author: Ping-Ke Shih +Date: Wed Oct 12 16:32:32 2022 +0800 + + wifi: rtw89: 8852b: rfk: add RX DCK + + RX DCK is receiver DC calibration. With this calibration, we have proper + DC offset to reflect correct received signal strength indicator. Do this + calibration when bringing up interface and going to run on AP channel. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221012083234.20224-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 75 +++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h | 1 + + 2 files changed, 76 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +index 1dcb900ef7007..306f6a292c59a 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -12,6 +12,7 @@ + #include "rtw8852b_rfk_table.h" + #include "rtw8852b_table.h" + ++#define RTW8852B_RXDCK_VER 0x1 + #define ADDC_T_AVG 100 + + static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +@@ -32,6 +33,47 @@ static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + 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; +@@ -488,6 +530,24 @@ static void _dac_cal(struct rtw89_dev *rtwdev, bool force) + rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); + } + ++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); ++ } ++} ++ + void rtw8852b_rck(struct rtw89_dev *rtwdev) + { + u8 path; +@@ -505,6 +565,21 @@ void rtw8852b_dack(struct rtw89_dev *rtwdev) + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); + } + ++void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) ++{ ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ 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); ++} ++ + static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw, bool dav) + { +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +index 84325abc7f2c2..24e492484d274 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +@@ -9,6 +9,7 @@ + + void rtw8852b_rck(struct rtw89_dev *rtwdev); + void rtw8852b_dack(struct rtw89_dev *rtwdev); ++void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +-- +2.13.6 + diff --git a/SOURCES/0036-wifi-rtw89-8852b-rfk-add-IQK.patch b/SOURCES/0036-wifi-rtw89-8852b-rfk-add-IQK.patch new file mode 100644 index 0000000..0a77b24 --- /dev/null +++ b/SOURCES/0036-wifi-rtw89-8852b-rfk-add-IQK.patch @@ -0,0 +1,1221 @@ +From 274cf6c8419b74a015313e9bc95ec29de7f74c20 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 036/142] wifi: rtw89: 8852b: rfk: add IQK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit f2abe804e8230ff20a834e204bde529935df5467 +Author: Ping-Ke Shih +Date: Wed Oct 12 16:32:33 2022 +0800 + + wifi: rtw89: 8852b: rfk: add IQK + + IQ signal calibration is a very important calibration to yield good RF + performance. We do this calibration only if we are going to run on AP + channel. During scanning phase, without this calibration RF performance + is still acceptable because it transmits with low data rate at this phase. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221012083234.20224-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 19 + + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 1046 +++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h | 1 + + 3 files changed, 1066 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 40b66c071b27d..6dc078969d588 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3295,6 +3295,7 @@ + #define RR_MOD_IQK GENMASK(19, 4) + #define RR_MOD_DPK GENMASK(19, 5) + #define RR_MOD_MASK GENMASK(19, 16) ++#define RR_MOD_RGM GENMASK(13, 4) + #define RR_MOD_V_DOWN 0x0 + #define RR_MOD_V_STANDBY 0x1 + #define RR_MOD_V_TX 0x2 +@@ -3368,6 +3369,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 +@@ -3415,6 +3417,8 @@ + #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) +@@ -3438,7 +3442,9 @@ + #define RR_RXA2 0x8c + #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) +@@ -3450,6 +3456,7 @@ + #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_DONE GENMASK(7, 5) +@@ -3530,6 +3537,8 @@ + #define R_RFE_O_SEL_A2 0x0338 + #define R_RFE_SEL0_A2 0x033C + #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) +@@ -3777,6 +3786,11 @@ + #define B_P1_EN_SOUND_WO_NDP BIT(1) + #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) +@@ -4107,6 +4121,7 @@ + #define R_P0_TSSI_AVG 0x5820 + #define B_P0_TSSI_AVG GENMASK(15, 12) + #define R_P0_RFCTM 0x5864 ++#define B_P0_RFCTM_EN BIT(29) + #define B_P0_RFCTM_VAL GENMASK(25, 20) + #define R_P0_RFCTM_RDY BIT(26) + #define R_P0_TRSW 0x5868 +@@ -4266,6 +4281,7 @@ + #define B_COEF_SEL_MDPD BIT(8) + #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 +@@ -4322,6 +4338,9 @@ + #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_RXCFIR_P0C0 0x8D40 + #define R_RXCFIR_P0C1 0x8D84 + #define R_RXCFIR_P0C2 0x8DC8 +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +index 306f6a292c59a..466f908e0214a 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -13,8 +13,189 @@ + #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 ADDC_T_AVG 100 + ++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 _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 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; +@@ -530,6 +711,803 @@ static void _dac_cal(struct rtw89_dev *rtwdev, bool force) + 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 = 0x308 | (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 = 0x3; ++ ++ 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_iqk_info *iqk_info = &rtwdev->iqk; ++ bool is_fail1, is_fail2; ++ u32 vbuff_i; ++ u32 vbuff_q; ++ u32 core_i; ++ u32 core_q; ++ u32 tmp; ++ u8 ch; ++ ++ 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); ++ ch = (iqk_info->iqk_times / 2) % RTW89_IQK_CHS_NR; ++ ++ 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; ++ ++ iqk_info->thermal[path] = ++ ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); ++ iqk_info->thermal_rek_en = false; ++ ++ 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) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; ++ u32 reg_rf18; ++ u32 reg_35c; ++ u8 idx; ++ u8 get_empty_table = false; ++ ++ for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { ++ if (iqk_info->iqk_mcc_ch[idx][path] == 0) { ++ get_empty_table = true; ++ break; ++ } ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (1)idx = %x\n", idx); ++ ++ if (!get_empty_table) { ++ idx = iqk_info->iqk_table_idx[path] + 1; ++ if (idx > 1) ++ idx = 0; ++ } ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (2)idx = %x\n", idx); ++ ++ 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_iqk_info *iqk_info = &rtwdev->iqk; ++ u8 idx; ++ ++ idx = iqk_info->iqk_table_idx[path]; ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (3)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->thermal_rek_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; +@@ -548,6 +1526,58 @@ static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) + } + } + ++static void _doiqk(struct rtw89_dev *rtwdev, bool force, ++ enum rtw89_phy_idx phy_idx, u8 path) ++{ ++ 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); ++ ++ rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[IQK]==========IQK strat!!!!!==========\n"); ++ iqk_info->iqk_times++; ++ iqk_info->kcount = 0; ++ 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); ++ ++ _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) ++{ ++ u8 kpath = _kpath(rtwdev, phy_idx); ++ ++ switch (kpath) { ++ case RF_A: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); ++ break; ++ case RF_B: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_B); ++ break; ++ case RF_AB: ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_A); ++ _doiqk(rtwdev, force, phy_idx, RF_PATH_B); ++ break; ++ default: ++ break; ++ } ++} ++ + void rtw8852b_rck(struct rtw89_dev *rtwdev) + { + u8 path; +@@ -565,6 +1595,22 @@ void rtw8852b_dack(struct rtw89_dev *rtwdev) + 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) ++{ ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ 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); ++ ++ 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) + { + u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +index 24e492484d274..81eb9bddb6d7a 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +@@ -9,6 +9,7 @@ + + void rtw8852b_rck(struct rtw89_dev *rtwdev); + void rtw8852b_dack(struct rtw89_dev *rtwdev); ++void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, +-- +2.13.6 + diff --git a/SOURCES/0037-wifi-rtw89-8852b-rfk-add-TSSI.patch b/SOURCES/0037-wifi-rtw89-8852b-rfk-add-TSSI.patch new file mode 100644 index 0000000..d9daa02 --- /dev/null +++ b/SOURCES/0037-wifi-rtw89-8852b-rfk-add-TSSI.patch @@ -0,0 +1,1431 @@ +From dd30e12f363ed70d9e63ea90115a5cf8cdc6132f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 037/142] wifi: rtw89: 8852b: rfk: add TSSI +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 7f18a70d7b4d2a0e54ce542c222aeffc464ed9f3 +Author: Ping-Ke Shih +Date: Wed Oct 12 16:32:34 2022 +0800 + + wifi: rtw89: 8852b: rfk: add TSSI + + TSSI is transmitter signal strength indication, which is a close-loop + hardware circuit to feedback actual transmitting power as a reference for + next transmission. + + When we setup channel to connect an AP, it does full calibration. When + switching bands or channels, it needs to reset hardware status to prevent + use wrong feedback of previous transmission. + + To do TX power compensation reflecting current temperature, it loads tables + of compensation values into registers according to channel and band group. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221012083234.20224-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 15 + + drivers/net/wireless/realtek/rtw89/reg.h | 43 + + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 1174 +++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h | 4 + + 4 files changed, 1236 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 0a0343608ba63..856d9712f0ae7 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -3164,6 +3164,14 @@ struct rtw89_cfo_tracking_info { + u8 lock_cnt; + }; + ++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 +@@ -3174,6 +3182,8 @@ struct rtw89_cfo_tracking_info { + #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]; +@@ -3186,6 +3196,11 @@ struct rtw89_tssi_info { + 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]; ++ u32 tssi_alimk_time; + }; + + struct rtw89_power_trim_info { +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 6dc078969d588..4393b409cbe6f 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3389,6 +3389,8 @@ + #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) +@@ -3730,6 +3732,9 @@ + #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 +@@ -4092,6 +4097,20 @@ + #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_UPD_CLK 0x5670 + #define B_DAC_VAL BIT(31) + #define B_ACK_VAL GENMASK(30, 29) +@@ -4106,6 +4125,8 @@ + #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 +@@ -4114,11 +4135,15 @@ + #define B_P0_TMETER GENMASK(15, 10) + #define B_P0_TMETER_DIS BIT(16) + #define B_P0_TMETER_TRK 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_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_RFCTM_EN BIT(29) +@@ -4141,7 +4166,9 @@ + #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_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) +@@ -4166,25 +4193,41 @@ + #define B_S0_DACKQ8_K GENMASK(15, 8) + #define R_RPL_BIAS_COMP1 0x6DF0 + #define B_RPL_BIAS_COMP1_MASK GENMASK(7, 0) ++#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_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 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 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_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_TSSI_THOF 0x7C00 + #define R_S1_DACKI 0x7E00 + #define B_S1_DACKI_AR GENMASK(31, 28) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +index 466f908e0214a..d0ac883772c11 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -16,6 +16,9 @@ + #define RTW8852B_IQK_VER 0x2a + #define RTW8852B_IQK_SS 2 + #define RTW8852B_RXK_GROUP_NR 4 ++#define RTW8852B_TSSI_PATH_NR 2 ++ ++#define _TSSI_DE_MASK GENMASK(21, 12) + #define ADDC_T_AVG 100 + + enum rtw8852b_iqk_type { +@@ -35,6 +38,21 @@ enum rtw8852b_iqk_type { + 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}; +@@ -1526,6 +1544,15 @@ static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) + } + } + ++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) + { +@@ -1578,6 +1605,1027 @@ static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool forc + } + } + ++static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ++ enum rtw89_rf_path path) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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 = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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) ++{ ++#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; \ ++}) ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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 = rtw89_8852b_trk_cfg.delta_swingidx_2ga_p; ++ thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_2ga_n; ++ thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_2gb_p; ++ thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_2gb_n; ++ break; ++ case RTW89_CH_5G_BAND_1: ++ thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[0]; ++ thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[0]; ++ thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[0]; ++ thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[0]; ++ break; ++ case RTW89_CH_5G_BAND_3: ++ thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[1]; ++ thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[1]; ++ thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[1]; ++ thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[1]; ++ break; ++ case RTW89_CH_5G_BAND_4: ++ thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[2]; ++ thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[2]; ++ thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[2]; ++ thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_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 = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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 = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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); ++ 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); ++ trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i); ++ 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) ++{ ++ struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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) ++{ ++ 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) { ++ rtw8852b_bb_set_plcp_tx(rtwdev); ++ rtw8852b_bb_cfg_tx_path(rtwdev, path); ++ rtw8852b_bb_ctrl_rx_path(rtwdev, rx_path); ++ rtw8852b_bb_set_power(rtwdev, pwr_dbm, phy); ++ } ++ ++ rtw8852b_bb_set_pmac_pkt_tx(rtwdev, enable, cnt, period, 20, phy); ++} ++ ++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) ++{ ++ 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); ++ else ++ _tssi_hw_tx(rtwdev, phy, RF_PATH_ABCD, 100, 5000, power[j], true); ++ ++ 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); ++ 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); ++ ++ 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) ++{ ++ 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; ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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 rtw8852b_bb_tssi_bak tssi_bak; ++ s32 aliment_diff, tssi_cw_default; ++ u32 start_time, finish_time; ++ u32 bb_reg_backup[8] = {0}; ++ const s16 *power; ++ 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_ns(); ++ ++ 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; ++ ++ rtw8852b_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); ++ 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)); ++ rtw8852b_bb_restore_tssi(rtwdev, phy, &tssi_bak); ++ rtw8852b_bb_tx_mode_switch(rtwdev, phy, 0); ++ ++ finish_time = ktime_get_ns(); ++ tssi_info->tssi_alimk_time += finish_time - start_time; ++ ++ rtw89_debug(rtwdev, RTW89_DBG_RFK, ++ "[TSSI PA K] %s processing time = %d ms\n", __func__, ++ tssi_info->tssi_alimk_time); ++} ++ + void rtw8852b_rck(struct rtw89_dev *rtwdev) + { + u8 path; +@@ -1626,6 +2674,132 @@ void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); + } + ++void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en) ++{ ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB); ++ 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); ++ _tssi_set_sys(rtwdev, phy, i); ++ _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); ++ _tssi_set_dac_gain_tbl(rtwdev, phy, i); ++ _tssi_slope_cal_org(rtwdev, phy, i); ++ _tssi_alignment_default(rtwdev, phy, i, true); ++ _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); ++ _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); ++ ++ 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 = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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); ++ _tssi_set_sys(rtwdev, phy, i); ++ _tssi_set_tmeter_tbl(rtwdev, phy, i); ++ ++ if (tssi_info->alignment_done[i][band]) ++ _tssi_alimentk_done(rtwdev, phy, i); ++ else ++ _tssi_alignment_default(rtwdev, phy, i, true); ++ } ++ ++ _tssi_enable(rtwdev, phy); ++ _tssi_set_efuse_to_de(rtwdev, phy); ++} ++ ++static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy, bool enable) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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); ++ 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); ++ _tssi_alimentk_done(rtwdev, phy, RF_PATH_B); ++ ++ 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) ++{ ++ if (scan_start) ++ rtw8852b_tssi_default_txagc(rtwdev, phy_idx, true); ++ else ++ rtw8852b_tssi_default_txagc(rtwdev, phy_idx, false); ++} ++ + static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, + enum rtw89_bandwidth bw, bool dav) + { +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +index 81eb9bddb6d7a..e7402733d8480 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +@@ -11,6 +11,10 @@ void rtw8852b_rck(struct rtw89_dev *rtwdev); + void rtw8852b_dack(struct rtw89_dev *rtwdev); + void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); ++void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en); ++void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ++void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, ++ enum rtw89_phy_idx phy_idx); + void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx); +-- +2.13.6 + diff --git a/SOURCES/0038-wifi-rtw89-8852b-rfk-add-DPK.patch b/SOURCES/0038-wifi-rtw89-8852b-rfk-add-DPK.patch new file mode 100644 index 0000000..e370a23 --- /dev/null +++ b/SOURCES/0038-wifi-rtw89-8852b-rfk-add-DPK.patch @@ -0,0 +1,1354 @@ +From 4bb9879fe0994bf80746962d1ccf7347a1c45c2a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 038/142] wifi: rtw89: 8852b: rfk: add DPK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 5b8471ace5b1247b2eb6a824341e11a8e871080f +Author: Ping-Ke Shih +Date: Fri Oct 14 14:02:34 2022 +0800 + + wifi: rtw89: 8852b: rfk: add DPK + + DPK is short for digital pre-distortion calibration. It can adjusts digital + waveform according to PA linear characteristics dynamically to enhance + TX EVM. + + Do this calibration when we are going to run on AP channel. To prevent + power offset out of boundary, it monitors thermal and set proper boundary + to register. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221014060237.29050-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 1 + + drivers/net/wireless/realtek/rtw89/reg.h | 17 + + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 1148 +++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h | 3 + + 4 files changed, 1169 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 856d9712f0ae7..90bf7bdb60628 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -3049,6 +3049,7 @@ struct rtw89_dpk_bkup_para { + struct rtw89_dpk_info { + bool is_dpk_enable; + bool is_dpk_reload_en; ++ u8 dpk_gs[RTW89_PHY_MAX]; + 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]; +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 4393b409cbe6f..2b938d11d2381 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3298,6 +3298,7 @@ + #define RR_MOD_RGM GENMASK(13, 4) + #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 +@@ -3431,6 +3432,7 @@ + #define RR_RXBB_VOBUF GENMASK(15, 12) + #define RR_RXBB_C2G GENMASK(16, 10) + #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 +@@ -3441,7 +3443,9 @@ + #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_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) +@@ -3476,6 +3480,7 @@ + #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 +@@ -3851,6 +3856,9 @@ + #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_TXPATH_SEL 0x458C + #define B_TXPATH_SEL_MSK GENMASK(31, 28) + #define R_TXPWR 0x4594 +@@ -4297,6 +4305,7 @@ + #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_GAPK 0x80E0 + #define B_GAPK_ADR BIT(0) +@@ -4318,6 +4327,7 @@ + #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 B_COEF_SEL_IQC BIT(0) +@@ -4356,13 +4366,18 @@ + #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) +@@ -4462,6 +4477,7 @@ + #define R_P0_CFCH_BW0 0xC0D4 + #define B_P0_CFCH_BW0 GENMASK(27, 26) + #define R_P0_CFCH_BW1 0xC0D8 ++#define B_P0_CFCH_EX BIT(13) + #define B_P0_CFCH_BW1 GENMASK(8, 5) + #define R_ADDCK0D 0xC0F0 + #define B_ADDCK0D_VAL2 GENMASK(31, 26) +@@ -4511,6 +4527,7 @@ + #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) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +index d0ac883772c11..8fd01502ac5be 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -17,9 +17,49 @@ + #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 2 + + #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, +@@ -190,6 +230,24 @@ static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, + } + } + ++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; +@@ -1605,6 +1663,1069 @@ static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool forc + } + } + ++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, dpk->is_dpk_enable && !off ? "enable" : "disable"); ++} ++ ++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_RESOTRE" : "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) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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, ++ rtwdev->is_tssi_mode[path] ? "on" : "off", ++ rtwdev->dbcc_en ? "on" : "off", ++ 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) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ ++ 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) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ ++ 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) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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) ++{ ++ 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); ++ 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) ++{ ++ 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); ++ 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); ++ if (rtwdev->is_tssi_mode[path]) ++ _dpk_tssi_pause(rtwdev, path, true); ++ } ++ ++ _dpk_bb_afe_setting(rtwdev, phy, path, kpath); ++ ++ for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) { ++ is_fail = _dpk_main(rtwdev, phy, path, 1); ++ _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 < 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) ++{ ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ 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) ++{ ++ 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)) ++ _dpk_force_bypass(rtwdev, phy); ++ else ++ _dpk_cal_select(rtwdev, force, phy, RF_AB); ++} ++ ++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) + { +@@ -2626,6 +3747,11 @@ static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + 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; +@@ -2674,6 +3800,28 @@ void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + 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) ++{ ++ u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0); ++ 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); ++ ++ 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) + { + u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +index e7402733d8480..f528320656001 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.h +@@ -11,6 +11,9 @@ void rtw8852b_rck(struct rtw89_dev *rtwdev); + void rtw8852b_dack(struct rtw89_dev *rtwdev); + void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); + void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx); ++void rtw8852b_dpk_init(struct rtw89_dev *rtwdev); ++void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); ++void rtw8852b_dpk_track(struct rtw89_dev *rtwdev); + void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en); + void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy); + void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, +-- +2.13.6 + diff --git a/SOURCES/0039-wifi-rtw89-8852b-add-chip_ops-related-to-RF-calibrat.patch b/SOURCES/0039-wifi-rtw89-8852b-add-chip_ops-related-to-RF-calibrat.patch new file mode 100644 index 0000000..1d1445a --- /dev/null +++ b/SOURCES/0039-wifi-rtw89-8852b-add-chip_ops-related-to-RF-calibrat.patch @@ -0,0 +1,93 @@ +From facc5c5a95613e256dac7e121532ebc8d0278e8f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 039/142] wifi: rtw89: 8852b: add chip_ops related to RF + calibration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit ef8acbcac6816e4caf20934932b4881d775c6f37 +Author: Ping-Ke Shih +Date: Fri Oct 14 14:02:35 2022 +0800 + + wifi: rtw89: 8852b: add chip_ops related to RF calibration + + Since RF calibrations are added, add chip_ops to call them. These chip_ops + include initial, full calibration, configuration when switching band and + scanning, and track work in period of 2 seconds. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221014060237.29050-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 42 +++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 0918b75ab1d94..0df044b1c392a 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -1513,6 +1513,43 @@ static void rtw8852b_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + } + } + ++static void rtw8852b_rfk_init(struct rtw89_dev *rtwdev) ++{ ++ rtwdev->is_tssi_mode[RF_PATH_A] = false; ++ rtwdev->is_tssi_mode[RF_PATH_B] = false; ++ ++ rtw8852b_dpk_init(rtwdev); ++ rtw8852b_rck(rtwdev); ++ rtw8852b_dack(rtwdev); ++ rtw8852b_rx_dck(rtwdev, RTW89_PHY_0); ++} ++ ++static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev) ++{ ++ enum rtw89_phy_idx phy_idx = RTW89_PHY_0; ++ ++ rtw8852b_rx_dck(rtwdev, phy_idx); ++ rtw8852b_iqk(rtwdev, phy_idx); ++ rtw8852b_tssi(rtwdev, phy_idx, true); ++ rtw8852b_dpk(rtwdev, phy_idx); ++} ++ ++static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev, ++ enum rtw89_phy_idx phy_idx) ++{ ++ rtw8852b_tssi_scan(rtwdev, phy_idx); ++} ++ ++static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev, bool start) ++{ ++ rtw8852b_wifi_scan_notify(rtwdev, start, RTW89_PHY_0); ++} ++ ++static void rtw8852b_rfk_track(struct rtw89_dev *rtwdev) ++{ ++ rtw8852b_dpk_track(rtwdev); ++} ++ + static u32 rtw8852b_bb_cal_txpwr_ref(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, s16 ref) + { +@@ -2346,6 +2383,11 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .read_efuse = rtw8852b_read_efuse, + .read_phycap = rtw8852b_read_phycap, + .fem_setup = NULL, ++ .rfk_init = rtw8852b_rfk_init, ++ .rfk_channel = rtw8852b_rfk_channel, ++ .rfk_band_changed = rtw8852b_rfk_band_changed, ++ .rfk_scan = rtw8852b_rfk_scan, ++ .rfk_track = rtw8852b_rfk_track, + .power_trim = rtw8852b_power_trim, + .set_txpwr = rtw8852b_set_txpwr, + .set_txpwr_ctrl = rtw8852b_set_txpwr_ctrl, +-- +2.13.6 + diff --git a/SOURCES/0040-wifi-rtw89-phy-add-dummy-C2H-handler-to-avoid-warnin.patch b/SOURCES/0040-wifi-rtw89-phy-add-dummy-C2H-handler-to-avoid-warnin.patch new file mode 100644 index 0000000..40f2abd --- /dev/null +++ b/SOURCES/0040-wifi-rtw89-phy-add-dummy-C2H-handler-to-avoid-warnin.patch @@ -0,0 +1,70 @@ +From 70297ae944cd34309365bcfe5a061b0bb64b4aae Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 040/142] wifi: rtw89: phy: add dummy C2H handler to avoid + warning message +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3b66519b023b9de3239576b938bbdf43f95bc862 +Author: Ping-Ke Shih +Date: Fri Oct 14 14:02:36 2022 +0800 + + wifi: rtw89: phy: add dummy C2H handler to avoid warning message + + The C2H class 2 function 3 is to report retry count of low rate, but driver + doesn't implement yet, so add a dummy case to avoid message: + + rtw89_8852be 0000:03:00.0: c2h class 2 not support + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221014060237.29050-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/phy.c | 4 ++++ + drivers/net/wireless/realtek/rtw89/phy.h | 9 +++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index 13b16ec0d8077..0bd2a0cea7ff1 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -2276,6 +2276,10 @@ void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + if (func < RTW89_PHY_C2H_FUNC_RA_MAX) + handler = rtw89_phy_c2h_ra_handler[func]; + break; ++ case RTW89_PHY_C2H_CLASS_DM: ++ if (func == RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY) ++ return; ++ fallthrough; + default: + rtw89_info(rtwdev, "c2h class %d not support\n", class); + return; +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +index 1e122b1498ba1..995c13f6f906c 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.h ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -114,6 +114,15 @@ enum rtw89_phy_c2h_ra_func { + RTW89_PHY_C2H_FUNC_RA_MAX, + }; + ++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_NUM, ++}; ++ + enum rtw89_phy_c2h_class { + RTW89_PHY_C2H_CLASS_RUA, + RTW89_PHY_C2H_CLASS_RA, +-- +2.13.6 + diff --git a/SOURCES/0041-wifi-rtw89-8852b-add-8852be-to-Makefile-and-Kconfig.patch b/SOURCES/0041-wifi-rtw89-8852b-add-8852be-to-Makefile-and-Kconfig.patch new file mode 100644 index 0000000..78b8e51 --- /dev/null +++ b/SOURCES/0041-wifi-rtw89-8852b-add-8852be-to-Makefile-and-Kconfig.patch @@ -0,0 +1,88 @@ +From 1c92b04d8de44d85791160d5889ddc9e2b12e3de Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 041/142] wifi: rtw89: 8852b: add 8852be to Makefile and + Kconfig +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit b5db4ef38e21dd9b6b95ae96cea5032b00e04f24 +Author: Ping-Ke Shih +Date: Fri Oct 14 14:02:37 2022 +0800 + + wifi: rtw89: 8852b: add 8852be to Makefile and Kconfig + + Now, basic materials for 8852be are ready, so add 8852be to Kconfig and + Makefile. Current version can support STA, AP and monitor modes. + + We still fine tune some features, such as BT coexistence, performance, and + power consumption. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221014060237.29050-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/Kconfig | 14 ++++++++++++++ + drivers/net/wireless/realtek/rtw89/Makefile | 9 +++++++++ + 2 files changed, 23 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/Kconfig b/drivers/net/wireless/realtek/rtw89/Kconfig +index 93e09400aac49..2b20cf8bbf3aa 100644 +--- a/drivers/net/wireless/realtek/rtw89/Kconfig ++++ b/drivers/net/wireless/realtek/rtw89/Kconfig +@@ -19,6 +19,9 @@ config RTW89_PCI + config RTW89_8852A + tristate + ++config RTW89_8852B ++ tristate ++ + config RTW89_8852C + tristate + +@@ -33,6 +36,17 @@ config RTW89_8852AE + + 802.11ax PCIe 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 ++ help ++ Select this option will enable support for 8852BE 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 +diff --git a/drivers/net/wireless/realtek/rtw89/Makefile b/drivers/net/wireless/realtek/rtw89/Makefile +index a87f2aff4def2..ec0f5da65d6a1 100644 +--- a/drivers/net/wireless/realtek/rtw89/Makefile ++++ b/drivers/net/wireless/realtek/rtw89/Makefile +@@ -24,6 +24,15 @@ rtw89_8852a-objs := rtw8852a.o \ + obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o + rtw89_8852ae-objs := rtw8852ae.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_8852C) += rtw89_8852c.o + rtw89_8852c-objs := rtw8852c.o \ + rtw8852c_table.o \ +-- +2.13.6 + diff --git a/SOURCES/0042-wifi-rtw89-fw-adapt-to-new-firmware-format-of-dynami.patch b/SOURCES/0042-wifi-rtw89-fw-adapt-to-new-firmware-format-of-dynami.patch new file mode 100644 index 0000000..88ea309 --- /dev/null +++ b/SOURCES/0042-wifi-rtw89-fw-adapt-to-new-firmware-format-of-dynami.patch @@ -0,0 +1,128 @@ +From ebee051e5d5c1fae6266c442d53e72a2bb3988db Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 042/142] wifi: rtw89: fw: adapt to new firmware format of + dynamic header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 4feda7f317cb7e4b6fcdaffb0d1ad363ee28fdea +Author: Ping-Ke Shih +Date: Thu Oct 20 13:25:49 2022 +0800 + + wifi: rtw89: fw: adapt to new firmware format of dynamic header + + Since firmware size is limited, we create variant firmwares for variant + application areas. To help driver to know firmware's capabilities, firmware + dynamic header is introduced to have more information, such as firmware + features and firmware compile flags. + + Since this driver rtw89 only uses single one specific firmware at runtime, + this patch is just to ignore this dynamic header, not actually use the + content. + + This patch can be backward compatible, and no this kind of firmware is + added to linux-firmware yet, so I can prepare this in advance. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221020052549.33783-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 22 +++++++++++++++++++--- + drivers/net/wireless/realtek/rtw89/fw.h | 12 ++++++++++++ + 2 files changed, 31 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index d3500a70af4dd..e9f84d43ce0c9 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -85,15 +85,31 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, + { + struct rtw89_fw_hdr_section_info *section_info; + const u8 *fw_end = fw + len; ++ const u8 *fwdynhdr; + const u8 *bin; ++ u32 base_hdr_len; + u32 i; + + if (!info) + return -EINVAL; + + info->section_num = GET_FW_HDR_SEC_NUM(fw); +- info->hdr_len = RTW89_FW_HDR_SIZE + +- info->section_num * RTW89_FW_SECTION_HDR_SIZE; ++ base_hdr_len = RTW89_FW_HDR_SIZE + ++ info->section_num * RTW89_FW_SECTION_HDR_SIZE; ++ info->dynamic_hdr_en = GET_FW_HDR_DYN_HDR(fw); ++ ++ if (info->dynamic_hdr_en) { ++ info->hdr_len = GET_FW_HDR_LEN(fw); ++ info->dynamic_hdr_len = info->hdr_len - base_hdr_len; ++ fwdynhdr = fw + base_hdr_len; ++ if (GET_FW_DYNHDR_LEN(fwdynhdr) != 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; + +@@ -534,7 +550,7 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) + goto fwdl_err; + } + +- ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len); ++ ret = rtw89_fw_download_hdr(rtwdev, fw, info.hdr_len - info.dynamic_hdr_len); + if (ret) { + ret = -EBUSY; + goto fwdl_err; +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 6ef392ef9c6fb..8563efa5f6411 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -176,6 +176,8 @@ struct rtw89_fw_hdr_section_info { + struct rtw89_fw_bin_info { + u8 section_num; + u32 hdr_len; ++ bool dynamic_hdr_en; ++ u32 dynamic_hdr_len; + struct rtw89_fw_hdr_section_info section_info[FWDL_SECTION_MAX_NUM]; + }; + +@@ -495,6 +497,8 @@ static inline void RTW89_SET_EDCA_PARAM(void *cmd, u32 val) + le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 16)) + #define GET_FW_HDR_SUBINDEX(fwhdr) \ + le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(31, 24)) ++#define GET_FW_HDR_LEN(fwhdr) \ ++ le32_get_bits(*((const __le32 *)(fwhdr) + 3), GENMASK(23, 16)) + #define GET_FW_HDR_MONTH(fwhdr) \ + le32_get_bits(*((const __le32 *)(fwhdr) + 4), GENMASK(7, 0)) + #define GET_FW_HDR_DATE(fwhdr) \ +@@ -507,8 +511,16 @@ static inline void RTW89_SET_EDCA_PARAM(void *cmd, u32 val) + le32_get_bits(*((const __le32 *)(fwhdr) + 5), GENMASK(31, 0)) + #define GET_FW_HDR_SEC_NUM(fwhdr) \ + le32_get_bits(*((const __le32 *)(fwhdr) + 6), GENMASK(15, 8)) ++#define GET_FW_HDR_DYN_HDR(fwhdr) \ ++ le32_get_bits(*((const __le32 *)(fwhdr) + 7), BIT(16)) + #define GET_FW_HDR_CMD_VERSERION(fwhdr) \ + le32_get_bits(*((const __le32 *)(fwhdr) + 7), GENMASK(31, 24)) ++ ++#define GET_FW_DYNHDR_LEN(fwdynhdr) \ ++ le32_get_bits(*((const __le32 *)(fwdynhdr)), GENMASK(31, 0)) ++#define GET_FW_DYNHDR_COUNT(fwdynhdr) \ ++ le32_get_bits(*((const __le32 *)(fwdynhdr) + 1), GENMASK(31, 0)) ++ + static inline void SET_FW_HDR_PART_SIZE(void *fwhdr, u32 val) + { + le32p_replace_bits((__le32 *)fwhdr + 7, val, GENMASK(15, 0)); +-- +2.13.6 + diff --git a/SOURCES/0043-wifi-rtw89-declare-support-bands-with-const.patch b/SOURCES/0043-wifi-rtw89-declare-support-bands-with-const.patch new file mode 100644 index 0000000..8e0dc52 --- /dev/null +++ b/SOURCES/0043-wifi-rtw89-declare-support-bands-with-const.patch @@ -0,0 +1,64 @@ +From d7eadb913ff78209ccac0aa347d484478ea2388f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:26 +0200 +Subject: [PATCH 043/142] wifi: rtw89: declare support bands with const +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit a29dba478b6f4e8d3fbfe0b2f097cad1e0b93cf6 +Author: Zong-Zhe Yang +Date: Thu Oct 20 13:27:01 2022 +0800 + + wifi: rtw89: declare support bands with const + + They are just default declarations and we won't modify them directly. + Instead, we actually do moification on their memdup now. So, they + should be declared with const. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221020052702.33988-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index ee2214fd92d04..08bcdf5084743 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -171,7 +171,7 @@ bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitr + return true; + } + +-static struct ieee80211_supported_band rtw89_sband_2ghz = { ++static const struct ieee80211_supported_band rtw89_sband_2ghz = { + .band = NL80211_BAND_2GHZ, + .channels = rtw89_channels_2ghz, + .n_channels = ARRAY_SIZE(rtw89_channels_2ghz), +@@ -181,7 +181,7 @@ static struct ieee80211_supported_band rtw89_sband_2ghz = { + .vht_cap = {0}, + }; + +-static struct ieee80211_supported_band rtw89_sband_5ghz = { ++static const struct ieee80211_supported_band rtw89_sband_5ghz = { + .band = NL80211_BAND_5GHZ, + .channels = rtw89_channels_5ghz, + .n_channels = ARRAY_SIZE(rtw89_channels_5ghz), +@@ -193,7 +193,7 @@ static struct ieee80211_supported_band rtw89_sband_5ghz = { + .vht_cap = {0}, + }; + +-static struct ieee80211_supported_band rtw89_sband_6ghz = { ++static const struct ieee80211_supported_band rtw89_sband_6ghz = { + .band = NL80211_BAND_6GHZ, + .channels = rtw89_channels_6ghz, + .n_channels = ARRAY_SIZE(rtw89_channels_6ghz), +-- +2.13.6 + diff --git a/SOURCES/0044-wifi-rtw89-8852c-make-table-of-RU-mask-constant.patch b/SOURCES/0044-wifi-rtw89-8852c-make-table-of-RU-mask-constant.patch new file mode 100644 index 0000000..c1952f2 --- /dev/null +++ b/SOURCES/0044-wifi-rtw89-8852c-make-table-of-RU-mask-constant.patch @@ -0,0 +1,49 @@ +From 04d625bd28b099ff6205b5211c6514ce7b0bfd56 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:27 +0200 +Subject: [PATCH 044/142] wifi: rtw89: 8852c: make table of RU mask constant +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit e69ae29e00cec66609bd555398aa4f59f2a9ae84 +Author: Ping-Ke Shih +Date: Thu Oct 20 13:27:02 2022 +0800 + + wifi: rtw89: 8852c: make table of RU mask constant + + This table must be constant, so change it as expectation. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221020052702.33988-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index f6bcac8268166..7e208a8fdf4bb 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -1683,12 +1683,12 @@ 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; +- u32 ru_alloc_msk[2] = {B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY0, +- B_P80_AT_HIGH_FREQ_RU_ALLOC_PHY1}; + u8 ntx_path; + + if (chan->band_type == RTW89_BAND_2G) +-- +2.13.6 + diff --git a/SOURCES/0045-wifi-rtw89-add-BW-info-for-both-TX-and-RX-in-phy_inf.patch b/SOURCES/0045-wifi-rtw89-add-BW-info-for-both-TX-and-RX-in-phy_inf.patch new file mode 100644 index 0000000..ea7e074 --- /dev/null +++ b/SOURCES/0045-wifi-rtw89-add-BW-info-for-both-TX-and-RX-in-phy_inf.patch @@ -0,0 +1,79 @@ +From 8486f00b56da2f777031732bad52a3e68f308720 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:27 +0200 +Subject: [PATCH 045/142] wifi: rtw89: add BW info for both TX and RX in + phy_info +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 25f49617b5c9c9afa829030f14606be6351d4771 +Author: Eric Huang +Date: Fri Oct 21 17:16:01 2022 +0800 + + wifi: rtw89: add BW info for both TX and RX in phy_info + + In order to debug performance issue intuitively, add bandwidth information + into debugfs entry phy_info. After applying this patch, it looks like: + + TX rate [0]: HE 2SS MCS-11 GI:0.8 BW:80 (hw_rate=0x19b) ==> agg_wait=1 (3500) + RX rate [0]: HE 2SS MCS-9 GI:0.8 BW:80 (hw_rate=0x199) + + Signed-off-by: Eric Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221021091601.39884-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/debug.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +index 8f27c883eeabb..cd44d9aa37ca0 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.c ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -51,6 +51,22 @@ struct rtw89_debugfs_priv { + }; + }; + ++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 int rtw89_debugfs_single_show(struct seq_file *m, void *v) + { + struct rtw89_debugfs_priv *debugfs_priv = m->private; +@@ -2379,6 +2395,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) + else + seq_printf(m, "Legacy %d", rate->legacy); + seq_printf(m, "%s", rtwsta->ra_report.might_fallback_legacy ? " FB_G" : ""); ++ seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw)); + seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate); + seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait, + sta->deflink.agg.max_rc_amsdu_len); +@@ -2404,6 +2421,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta) + he_gi_str[rate->he_gi] : "N/A"); + break; + } ++ seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw)); + seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate); + + rssi = ewma_rssi_read(&rtwsta->avg_rssi); +-- +2.13.6 + diff --git a/SOURCES/0046-wifi-rtw89-check-if-sta-s-mac_id-is-valid-under-AP-T.patch b/SOURCES/0046-wifi-rtw89-check-if-sta-s-mac_id-is-valid-under-AP-T.patch new file mode 100644 index 0000000..62172a1 --- /dev/null +++ b/SOURCES/0046-wifi-rtw89-check-if-sta-s-mac_id-is-valid-under-AP-T.patch @@ -0,0 +1,46 @@ +From c332db533d9559a6da86939e1378ccfaedea3090 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:27 +0200 +Subject: [PATCH 046/142] wifi: rtw89: check if sta's mac_id is valid under + AP/TDLS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 46245bc42aff5e67b0498fa365a4baeaaaaeda86 +Author: Zong-Zhe Yang +Date: Fri Oct 21 17:18:28 2022 +0800 + + wifi: rtw89: check if sta's mac_id is valid under AP/TDLS + + Add boundary check of mac_id when adding sta under AP/TDLS. + And, return -ENOSPC if the acquired mac_id is invalid. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221021091828.40157-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 08bcdf5084743..45babf1a857d1 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2413,6 +2413,8 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, + } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { + rtwsta->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map, + RTW89_MAX_MAC_ID_NUM); ++ if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM) ++ return -ENOSPC; + } + + return 0; +-- +2.13.6 + diff --git a/SOURCES/0047-wifi-rtw89-collect-and-send-RF-parameters-to-firmwar.patch b/SOURCES/0047-wifi-rtw89-collect-and-send-RF-parameters-to-firmwar.patch new file mode 100644 index 0000000..f7c9f7a --- /dev/null +++ b/SOURCES/0047-wifi-rtw89-collect-and-send-RF-parameters-to-firmwar.patch @@ -0,0 +1,124 @@ +From ebf2cfc3ca05dfc0e9b0497f6412271efe4b87d1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:27 +0200 +Subject: [PATCH 047/142] wifi: rtw89: collect and send RF parameters to + firmware for WoWLAN +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit d9112042d9942648825d3ebe837dd33dbd7c6ddb +Author: Chih-Kang Chang +Date: Thu Oct 27 13:27:01 2022 +0800 + + wifi: rtw89: collect and send RF parameters to firmware for WoWLAN + + For WoWLAN mode, we only collect and send RF parameters to Firmware + without writing RF registers. So we add one function to practice it. + + Signed-off-by: Chih-Kang Chang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221027052707.14605-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 2 +- + drivers/net/wireless/realtek/rtw89/phy.c | 31 +++++++++++++++++++++++++++++-- + drivers/net/wireless/realtek/rtw89/phy.h | 2 +- + 3 files changed, 31 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 45babf1a857d1..c285707b21bb1 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2962,7 +2962,7 @@ int rtw89_core_start(struct rtw89_dev *rtwdev) + return ret; + + rtw89_phy_init_bb_reg(rtwdev); +- rtw89_phy_init_rf_reg(rtwdev); ++ rtw89_phy_init_rf_reg(rtwdev, false); + + rtw89_btc_ntfy_init(rtwdev, BTC_MODE_NORMAL); + +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index 0bd2a0cea7ff1..944bb0f2ee633 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -801,6 +801,11 @@ bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + } + EXPORT_SYMBOL(rtw89_phy_write_rf_v1); + ++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) + { +@@ -1123,6 +1128,24 @@ static int rtw89_phy_config_rf_reg_fw(struct rtw89_dev *rtwdev, + 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); ++} ++ + static void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, +@@ -1335,7 +1358,7 @@ static u32 rtw89_phy_nctl_poll(struct rtw89_dev *rtwdev) + return rtw89_phy_read32(rtwdev, 0x8080); + } + +-void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev) ++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); +@@ -1351,7 +1374,11 @@ void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev) + for (path = RF_PATH_A; path < chip->rf_path_num; path++) { + rf_table = chip->rf_table[path]; + rf_reg_info->rf_path = rf_table->rf_path; +- config = rf_table->config ? rf_table->config : rtw89_phy_config_rf_reg; ++ if (noio) ++ config = rtw89_phy_config_rf_reg_noio; ++ else ++ config = rf_table->config ? rf_table->config : ++ rtw89_phy_config_rf_reg; + rtw89_phy_init_reg(rtwdev, rf_table, config, (void *)rf_reg_info); + if (rtw89_phy_config_rf_reg_fw(rtwdev, rf_reg_info)) + rtw89_warn(rtwdev, "rf path %d reg h2c config failed\n", +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +index 995c13f6f906c..dac69a02e8687 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.h ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -500,7 +500,7 @@ bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, + bool rtw89_phy_write_rf_v1(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_rf_reg(struct rtw89_dev *rtwdev); ++void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio); + void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, +-- +2.13.6 + diff --git a/SOURCES/0048-wifi-rtw89-move-enable_cpu-disable_cpu-into-fw_downl.patch b/SOURCES/0048-wifi-rtw89-move-enable_cpu-disable_cpu-into-fw_downl.patch new file mode 100644 index 0000000..15d0d03 --- /dev/null +++ b/SOURCES/0048-wifi-rtw89-move-enable_cpu-disable_cpu-into-fw_downl.patch @@ -0,0 +1,101 @@ +From 472c46f9a617348fa8a8ba19dc50e1727c95a58e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:27 +0200 +Subject: [PATCH 048/142] wifi: rtw89: move enable_cpu/disable_cpu into + fw_download +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 5f05bdb0a770b5d03d3453c0b0743bb3dcd1a2ba +Author: Chih-Kang Chang +Date: Thu Oct 27 13:27:02 2022 +0800 + + wifi: rtw89: move enable_cpu/disable_cpu into fw_download + + For WoWLAN mode, we need to download WoWLAN firmware by calling + fw_download(). Another, to disable/enable WiFi CPU is needed before + calling fw_download. Since Firmware runs on WiFi CPU, it is intuitive + to combine enable_cpu/disable_cpu functions into fw_download. + + Signed-off-by: Chih-Kang Chang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221027052707.14605-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 5 +++++ + drivers/net/wireless/realtek/rtw89/mac.c | 10 ++-------- + drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ + 3 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index e9f84d43ce0c9..d09d593c1107a 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -531,6 +531,11 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) + u8 val; + int ret; + ++ rtw89_mac_disable_cpu(rtwdev); ++ ret = rtw89_mac_enable_cpu(rtwdev, 0, true); ++ if (ret) ++ return ret; ++ + if (!fw || !len) { + rtw89_err(rtwdev, "fw type %d isn't recognized\n", type); + return -ENOENT; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 598568c3f2750..54be8b24e3991 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3114,7 +3114,7 @@ static void rtw89_disable_fw_watchdog(struct rtw89_dev *rtwdev) + rtw89_mac_mem_write(rtwdev, R_AX_WDT_STATUS, val32, RTW89_MAC_MEM_CPU_LOCAL); + } + +-static void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) ++void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) + { + clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags); + +@@ -3129,8 +3129,7 @@ static void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev) + rtw89_write32_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); + } + +-static int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, +- bool dlfw) ++int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) + { + u32 val; + int ret; +@@ -3269,11 +3268,6 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev) + return ret; + } + +- rtw89_mac_disable_cpu(rtwdev); +- ret = rtw89_mac_enable_cpu(rtwdev, 0, true); +- if (ret) +- return ret; +- + ret = rtw89_fw_download(rtwdev, RTW89_FW_NORMAL); + if (ret) + return ret; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index a6cbafb75a2b8..6e03f5e4ae246 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -815,6 +815,8 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); + void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif); + int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); ++void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev); ++int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw); + int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev); + int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev); + +-- +2.13.6 + diff --git a/SOURCES/0049-wifi-rtw89-add-function-to-adjust-and-restore-PLE-qu.patch b/SOURCES/0049-wifi-rtw89-add-function-to-adjust-and-restore-PLE-qu.patch new file mode 100644 index 0000000..f478dc2 --- /dev/null +++ b/SOURCES/0049-wifi-rtw89-add-function-to-adjust-and-restore-PLE-qu.patch @@ -0,0 +1,134 @@ +From 288c91045ee2e42a86a159d788cda82682e4a6d9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:27 +0200 +Subject: [PATCH 049/142] wifi: rtw89: add function to adjust and restore PLE + quota +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 7a68ec3da79ea702fdeeb94c31f743fd37446a32 +Author: Chih-Kang Chang +Date: Thu Oct 27 13:27:03 2022 +0800 + + wifi: rtw89: add function to adjust and restore PLE quota + + PLE RX quota, which is the setting of RX buffer, is needed to be adjusted + dynamically for WoWLAN mode, and restored when back to normal mode. + The action is not needed for rtw8852c chip. + + Signed-off-by: Chih-Kang Chang + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221027052707.14605-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 1 + + drivers/net/wireless/realtek/rtw89/mac.c | 32 +++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 4 ++++ + 4 files changed, 39 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 90bf7bdb60628..10ccb047d6a06 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2389,6 +2389,7 @@ enum rtw89_dma_ch { + enum rtw89_qta_mode { + RTW89_QTA_SCC, + RTW89_QTA_DLFW, ++ RTW89_QTA_WOW, + + /* keep last */ + RTW89_QTA_INVALID, +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 54be8b24e3991..2ca500e11d3a3 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -1306,6 +1306,8 @@ const struct rtw89_mac_size_set rtw89_mac_size = { + .ple_qt47 = {525, 0, 32, 20, 1034, 13, 1199, 0, 1053, 62, 160, 1037,}, + /* PCIE 64 */ + .ple_qt58 = {147, 0, 16, 20, 157, 13, 229, 0, 172, 14, 24, 0,}, ++ /* 8852A PCIE WOW */ ++ .ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,}, + }; + EXPORT_SYMBOL(rtw89_mac_size); + +@@ -1476,6 +1478,36 @@ static void ple_quota_cfg(struct rtw89_dev *rtwdev, + 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 + + static void dle_quota_cfg(struct rtw89_dev *rtwdev, +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 6e03f5e4ae246..20211c4e62db5 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -719,6 +719,7 @@ struct rtw89_mac_size_set { + const struct rtw89_ple_quota ple_qt46; + const struct rtw89_ple_quota ple_qt47; + const struct rtw89_ple_quota ple_qt58; ++ const struct rtw89_ple_quota ple_qt_52a_wow; + }; + + extern const struct rtw89_mac_size_set rtw89_mac_size; +@@ -1026,5 +1027,6 @@ void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); + u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd); + int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, + struct rtw89_cpuio_ctrl *ctrl_para, bool wd); ++int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow); + + #endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index b5aa8697a0982..375e84f5fe5c1 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -48,6 +48,10 @@ static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = { + &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, +-- +2.13.6 + diff --git a/SOURCES/0050-wifi-rtw89-add-drop-tx-packet-function.patch b/SOURCES/0050-wifi-rtw89-add-drop-tx-packet-function.patch new file mode 100644 index 0000000..bee3845 --- /dev/null +++ b/SOURCES/0050-wifi-rtw89-add-drop-tx-packet-function.patch @@ -0,0 +1,290 @@ +From 6b51a4f8b619605160ba9dc387b391c87a8d879c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:28 +0200 +Subject: [PATCH 050/142] wifi: rtw89: add drop tx packet function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 41d567699283b86ce7443a5bf07114f1bde8e203 +Author: Chih-Kang Chang +Date: Thu Oct 27 13:27:04 2022 +0800 + + wifi: rtw89: add drop tx packet function + + When entering WoWLAN mode, we need to drop all transmit packets, + including those in mac buffer, to avoid memory leakage, so implement + the drop_tx function. + + Signed-off-by: Chih-Kang Chang + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221027052707.14605-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 3 ++ + drivers/net/wireless/realtek/rtw89/fw.c | 9 ++++ + drivers/net/wireless/realtek/rtw89/fw.h | 20 +++++++ + drivers/net/wireless/realtek/rtw89/mac.c | 75 +++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/mac.h | 13 +++++ + drivers/net/wireless/realtek/rtw89/reg.h | 13 +++++ + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 + + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 + + 8 files changed, 137 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 10ccb047d6a06..6b6bb3260fff4 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2624,6 +2624,8 @@ struct rtw89_chip_info { + u32 rsvd_ple_ofst; + const struct rtw89_hfc_param_ini *hfc_param_ini; + const struct rtw89_dle_mem *dle_mem; ++ u8 wde_qempty_acq_num; ++ u8 wde_qempty_mgq_sel; + u32 rf_base_addr[2]; + u8 support_chanctx_num; + u8 support_bands; +@@ -2949,6 +2951,7 @@ struct rtw89_pkt_drop_params { + u8 port; + u8 mbssid; + bool tf_trs; ++ u32 macid_band_sel[4]; + }; + + struct rtw89_pkt_stat { +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index d09d593c1107a..fa7439edec8f5 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -2902,6 +2902,7 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, + 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, +@@ -2917,6 +2918,14 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, + 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, +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 8563efa5f6411..3845581d5d284 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -1873,6 +1873,26 @@ static inline void RTW89_SET_FWCMD_PKT_DROP_ROLE_A_INFO_TF_TRS(void *cmd, u32 va + 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)); ++} ++ + enum rtw89_btc_btf_h2c_class { + BTFC_SET = 0x10, + BTFC_GET = 0x11, +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 2ca500e11d3a3..6bf6ad62ff7a6 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -1335,6 +1335,60 @@ static const struct rtw89_dle_mem *get_dle_mem_cfg(struct rtw89_dev *rtwdev, + return cfg; + } + ++static bool mac_is_txq_empty(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_mac_dle_dfi_qempty qempty; ++ u32 qnum, qtmp, val32, msk32; ++ int i, j, ret; ++ ++ qnum = rtwdev->chip->wde_qempty_acq_num; ++ qempty.dle_type = DLE_CTRL_TYPE_WDE; ++ ++ for (i = 0; i < qnum; i++) { ++ qempty.grpsel = i; ++ ret = dle_dfi_qempty(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 = FIELD_GET(QEMP_ACQ_GRP_QSEL_MASK, qtmp); ++ if (val32 != QEMP_ACQ_GRP_QSEL_MASK) ++ return false; ++ qtmp >>= QEMP_ACQ_GRP_QSEL_SH; ++ } ++ } ++ ++ qempty.grpsel = rtwdev->chip->wde_qempty_mgq_sel; ++ ret = dle_dfi_qempty(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_size *wde, + const struct rtw89_dle_size *ple) + { +@@ -4891,3 +4945,24 @@ void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + 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) ++{ ++ 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_fw_h2c_pkt_drop(rtwdev, ¶ms); ++ else ++ return 0; ++ } ++ return ret; ++} +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 20211c4e62db5..e3b4c7830f440 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -420,6 +420,17 @@ enum rtw89_mac_bf_rrsc_rate { + #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 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 +@@ -1028,5 +1039,7 @@ u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd); + int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, + struct rtw89_cpuio_ctrl *ctrl_para, bool wd); + 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); + + #endif +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 2b938d11d2381..33f2b67bfca37 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -545,6 +545,19 @@ + #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) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 375e84f5fe5c1..7995d720dc921 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -2049,6 +2049,8 @@ const struct rtw89_chip_info rtw8852a_chip_info = { + .rsvd_ple_ofst = 0x6f800, + .hfc_param_ini = rtw8852a_hfc_param_ini_pcie, + .dle_mem = rtw8852a_dle_mem_pcie, ++ .wde_qempty_acq_num = 16, ++ .wde_qempty_mgq_sel = 16, + .rf_base_addr = {0xc000, 0xd000}, + .pwr_on_seq = pwr_on_seq_8852a, + .pwr_off_seq = pwr_off_seq_8852a, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index 7e208a8fdf4bb..93332feabc44d 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2855,6 +2855,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = { + .rsvd_ple_ofst = 0x6f800, + .hfc_param_ini = rtw8852c_hfc_param_ini_pcie, + .dle_mem = rtw8852c_dle_mem_pcie, ++ .wde_qempty_acq_num = 16, ++ .wde_qempty_mgq_sel = 16, + .rf_base_addr = {0xe000, 0xf000}, + .pwr_on_seq = NULL, + .pwr_off_seq = NULL, +-- +2.13.6 + diff --git a/SOURCES/0051-wifi-rtw89-add-related-H2C-for-WoWLAN-mode.patch b/SOURCES/0051-wifi-rtw89-add-related-H2C-for-WoWLAN-mode.patch new file mode 100644 index 0000000..8a739de --- /dev/null +++ b/SOURCES/0051-wifi-rtw89-add-related-H2C-for-WoWLAN-mode.patch @@ -0,0 +1,531 @@ +From 7a7f454f262baf9e8b33235790d1ee482afbc1cd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:28 +0200 +Subject: [PATCH 051/142] wifi: rtw89: add related H2C for WoWLAN mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit ee88d748f1ace450cc0e8ca6a93cb11e7e8d6ad9 +Author: Chin-Yen Lee +Date: Thu Oct 27 13:27:05 2022 +0800 + + wifi: rtw89: add related H2C for WoWLAN mode + + In this patch we define some H2C, which will be called during suspend + flow, to enable WoWLAN function provided by WoWLAN firmware. + + These H2C includes keep alive used to send null packet to AP periodically + to avoid being disconnected by AP, disconnect detection used to configure + how we check if AP is offline, wake up control used to decide which WiFi + events could trigger resume flow, and global control used to enable WoWLAN + function. + + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221027052707.14605-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 30 ++++ + drivers/net/wireless/realtek/rtw89/fw.c | 229 ++++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/fw.h | 160 +++++++++++++++++++++ + 3 files changed, 419 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 6b6bb3260fff4..d20cb3ae89e98 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -477,6 +477,20 @@ enum rtw89_regulation_type { + RTW89_REGD_NUM, + }; + ++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_MAX]; + s8 ofdm[RTW89_RATE_OFDM_MAX]; +@@ -636,6 +650,13 @@ enum rtw89_sc_offset { + RTW89_SC_40_LOWER = 10, + }; + ++enum rtw89_wow_flags { ++ RTW89_WOW_FLAG_EN_MAGIC_PKT, ++ RTW89_WOW_FLAG_EN_REKEY_PKT, ++ RTW89_WOW_FLAG_EN_DISCONNECT, ++ RTW89_WOW_FLAG_NUM, ++}; ++ + struct rtw89_chan { + u8 channel; + u8 primary_channel; +@@ -3453,6 +3474,13 @@ struct rtw89_phy_efuse_gain { + s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ + }; + ++struct rtw89_wow_param { ++ struct ieee80211_vif *wow_vif; ++ DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); ++ u8 pattern_cnt; ++ struct list_head pkt_list; ++}; ++ + struct rtw89_dev { + struct ieee80211_hw *hw; + struct device *dev; +@@ -3541,6 +3569,8 @@ struct rtw89_dev { + enum rtw89_ps_mode ps_mode; + bool lps_enabled; + ++ struct rtw89_wow_param wow; ++ + /* napi structure */ + struct net_device netdev; + struct napi_struct napi; +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index fa7439edec8f5..c8f32a471e520 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -869,6 +869,56 @@ int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) + return ret; + } + ++static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ enum rtw89_fw_pkt_ofld_type type, ++ u8 *id) ++{ ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct rtw89_pktofld_info *info; ++ struct sk_buff *skb; ++ int ret; ++ ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ 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, -1, false); ++ break; ++ case RTW89_PKT_OFLD_TYPE_QOS_NULL: ++ skb = ieee80211_nullfunc_get(rtwdev->hw, vif, -1, true); ++ break; ++ default: ++ goto err; ++ } ++ ++ if (!skb) ++ goto err; ++ ++ list_add_tail(&info->list, &rtw_wow->pkt_list); ++ ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); ++ kfree_skb(skb); ++ ++ if (ret) ++ return ret; ++ ++ *id = info->id; ++ return 0; ++ ++err: ++ kfree(info); ++ return -ENOMEM; ++} ++ + #define H2C_GENERAL_PKT_LEN 6 + #define H2C_GENERAL_PKT_ID_UND 0xff + int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) +@@ -2945,3 +2995,182 @@ int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev, + 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 *rtwvif, ++ bool enable) ++{ ++ struct sk_buff *skb; ++ u8 pkt_id = 0; ++ int ret; ++ ++ if (enable) { ++ ret = rtw89_fw_h2c_add_wow_fw_ofld(rtwdev, rtwvif, ++ RTW89_PKT_OFLD_TYPE_NULL_DATA, &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->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; ++} ++ ++#define H2C_DISCONNECT_DETECT_LEN 8 ++int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool enable) ++{ ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct sk_buff *skb; ++ u8 macid = rtwvif->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; ++} ++ ++#define H2C_WOW_GLOBAL_LEN 8 ++int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ bool enable) ++{ ++ struct sk_buff *skb; ++ u8 macid = rtwvif->mac_id; ++ int ret; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_GLOBAL_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); ++ return -ENOMEM; ++ } ++ ++ skb_put(skb, H2C_WOW_GLOBAL_LEN); ++ ++ RTW89_SET_WOW_GLOBAL_ENABLE(skb->data, enable); ++ RTW89_SET_WOW_GLOBAL_MAC_ID(skb->data, macid); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_MAC_WOW, ++ H2C_FUNC_WOW_GLOBAL, 0, 1, ++ H2C_WOW_GLOBAL_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_WAKEUP_CTRL_LEN 4 ++int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ bool enable) ++{ ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct sk_buff *skb; ++ u8 macid = rtwvif->mac_id; ++ int ret; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); ++ return -ENOMEM; ++ } ++ ++ skb_put(skb, H2C_WAKEUP_CTRL_LEN); ++ ++ if (rtw_wow->pattern_cnt) ++ RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable); ++ if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) ++ RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable); ++ if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) ++ RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable); ++ ++ RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid); ++ ++ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ++ H2C_CAT_MAC, ++ H2C_CL_MAC_WOW, ++ H2C_FUNC_WAKEUP_CTRL, 0, 1, ++ H2C_WAKEUP_CTRL_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; ++} +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 3845581d5d284..25dd7bf8e730d 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -1893,6 +1893,146 @@ 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)); ++} ++ ++static inline void RTW89_SET_WOW_GLOBAL_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(0)); ++} ++ ++static inline void RTW89_SET_WOW_GLOBAL_DROP_ALL_PKT(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(1)); ++} ++ ++static inline void RTW89_SET_WOW_GLOBAL_RX_PARSE_AFTER_WAKE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(2)); ++} ++ ++static inline void RTW89_SET_WOW_GLOBAL_WAKE_BAR_PULLED(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(3)); ++} ++ ++static inline void RTW89_SET_WOW_GLOBAL_MAC_ID(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(15, 8)); ++} ++ ++static inline void RTW89_SET_WOW_GLOBAL_PAIRWISE_SEC_ALGO(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(23, 16)); ++} ++ ++static inline void RTW89_SET_WOW_GLOBAL_GROUP_SEC_ALGO(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); ++} ++ ++static inline void RTW89_SET_WOW_GLOBAL_REMOTECTRL_INFO_CONTENT(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)(h2c) + 1, val, GENMASK(31, 0)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(0)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(1)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_HW_UNICAST_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(2)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_FW_UNICAST_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(3)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(4)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_REKEYP_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(5)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_EAP_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(6)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_ALL_DATA_ENABLE(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(7)); ++} ++ ++static inline void RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); ++} ++ + enum rtw89_btc_btf_h2c_class { + BTFC_SET = 0x10, + BTFC_GET = 0x11, +@@ -2709,6 +2849,14 @@ struct rtw89_fw_h2c_rf_reg_info { + #define H2C_FUNC_LOG_CFG 0x0 + #define H2C_FUNC_MAC_GENERAL_PKT 0x1 + ++/* CLASS 1 - WOW */ ++#define H2C_CL_MAC_WOW 0x1 ++#define H2C_FUNC_KEEP_ALIVE 0x0 ++#define H2C_FUNC_DISCONNECT_DETECT 0x1 ++#define H2C_FUNC_WOW_GLOBAL 0x2 ++#define H2C_FUNC_WAKEUP_CTRL 0x8 ++#define H2C_FUNC_WOW_CAM_UPD 0xC ++ + /* CLASS 2 - PS */ + #define H2C_CL_MAC_PS 0x2 + #define H2C_FUNC_MAC_LPS_PARM 0x0 +@@ -2878,6 +3026,18 @@ int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, + u8 act, u8 noa_id); + int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + bool en); ++int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ bool enable); ++int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool enable); ++int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ bool enable); ++int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool enable); ++int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ bool enable); ++int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool enable); + + static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) + { +-- +2.13.6 + diff --git a/SOURCES/0052-wifi-rtw89-add-WoWLAN-function-support.patch b/SOURCES/0052-wifi-rtw89-add-WoWLAN-function-support.patch new file mode 100644 index 0000000..e6bc2ec --- /dev/null +++ b/SOURCES/0052-wifi-rtw89-add-WoWLAN-function-support.patch @@ -0,0 +1,1206 @@ +From a7c58d4f2b675d9a8425249b9c2e174085124d40 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:28 +0200 +Subject: [PATCH 052/142] wifi: rtw89: add WoWLAN function support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 19e28c7fcc7408be8479f91d47146245c8be293e +Author: Chin-Yen Lee +Date: Thu Oct 27 13:27:06 2022 +0800 + + wifi: rtw89: add WoWLAN function support + + WoWLAN is a feature which allows devices to be woken up from suspend + state through WLAN events. + + When user enables WoWLAN feature and then let the device enter suspend + state, WoWLAN firmware will be loaded by the driver and periodically + monitors WiFi packets. Power consumption of WiFi chip will be reduced + in this state. + + We now implement WoWLAN function in rtw8852ae and rtw8852ce chip. + Currently supported WLAN events include receiving magic packet, + rekey packet and deauth packet, and disconnecting from AP. + + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221027052707.14605-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/Makefile | 2 + + drivers/net/wireless/realtek/rtw89/core.c | 8 + + drivers/net/wireless/realtek/rtw89/core.h | 77 +++- + drivers/net/wireless/realtek/rtw89/debug.h | 1 + + drivers/net/wireless/realtek/rtw89/mac.c | 18 +- + drivers/net/wireless/realtek/rtw89/mac.h | 14 + + drivers/net/wireless/realtek/rtw89/mac80211.c | 55 +++ + drivers/net/wireless/realtek/rtw89/pci.c | 23 +- + drivers/net/wireless/realtek/rtw89/ps.c | 2 +- + drivers/net/wireless/realtek/rtw89/ps.h | 1 + + drivers/net/wireless/realtek/rtw89/reg.h | 8 + + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 9 + + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 9 + + drivers/net/wireless/realtek/rtw89/wow.c | 633 ++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/wow.h | 21 + + 15 files changed, 874 insertions(+), 7 deletions(-) + create mode 100644 drivers/net/wireless/realtek/rtw89/wow.c + create mode 100644 drivers/net/wireless/realtek/rtw89/wow.h + +diff --git a/drivers/net/wireless/realtek/rtw89/Makefile b/drivers/net/wireless/realtek/rtw89/Makefile +index ec0f5da65d6a1..2dc48fa10c6b6 100644 +--- a/drivers/net/wireless/realtek/rtw89/Makefile ++++ b/drivers/net/wireless/realtek/rtw89/Makefile +@@ -15,6 +15,8 @@ rtw89_core-y += core.o \ + chan.o \ + ser.o + ++rtw89_core-$(CONFIG_PM) += wow.o ++ + obj-$(CONFIG_RTW89_8852A) += rtw89_8852a.o + rtw89_8852a-objs := rtw8852a.o \ + rtw8852a_table.o \ +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index c285707b21bb1..1ebb2743ff4c4 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2204,6 +2204,9 @@ static void rtw89_track_work(struct work_struct *work) + track_work.work); + bool tfc_changed; + ++ if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags)) ++ return; ++ + mutex_lock(&rtwdev->mutex); + + if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags)) +@@ -3042,6 +3045,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) + continue; + INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]); + } ++ INIT_LIST_HEAD(&rtwdev->wow.pkt_list); + 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); +@@ -3276,6 +3280,10 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) + 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; ++#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); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index d20cb3ae89e98..9f80359e27aa2 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -178,7 +178,9 @@ enum rtw89_upd_mode { + RTW89_ROLE_REMOVE, + RTW89_ROLE_TYPE_CHANGE, + RTW89_ROLE_INFO_CHANGE, +- RTW89_ROLE_CON_DISCONN ++ RTW89_ROLE_CON_DISCONN, ++ RTW89_ROLE_BAND_SW, ++ RTW89_ROLE_FW_RESTORE, + }; + + enum rtw89_self_role { +@@ -2307,6 +2309,16 @@ struct rtw89_hci_ops { + */ + 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)(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 { +@@ -2748,6 +2760,7 @@ struct rtw89_chip_info { + const struct rtw89_imr_info *imr_info; + const struct rtw89_rrsr_cfgs *rrsr_cfgs; + u32 dma_ch_mask; ++ const struct wiphy_wowlan_support *wowlan_stub; + }; + + union rtw89_bus_info { +@@ -2944,6 +2957,8 @@ enum rtw89_flags { + RTW89_FLAG_LOW_POWER_MODE, + RTW89_FLAG_INACTIVE_PS, + RTW89_FLAG_CRASH_SIMULATING, ++ RTW89_FLAG_WOWLAN, ++ RTW89_FLAG_FORBIDDEN_TRACK_WROK, + + NUM_OF_RTW89_FLAGS, + }; +@@ -3653,6 +3668,66 @@ static inline void rtw89_hci_recovery_complete(struct rtw89_dev *rtwdev) + 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(struct rtw89_dev *rtwdev) ++{ ++ int ret = 0; ++ ++ if (rtwdev->hci.ops->poll_txdma_ch) ++ ret = rtwdev->hci.ops->poll_txdma_ch(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 u8 rtw89_read8(struct rtw89_dev *rtwdev, u32 addr) + { + return rtwdev->hci.ops->read8(rtwdev, addr); +diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h +index ee243aadde873..e7971583acbc9 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.h ++++ b/drivers/net/wireless/realtek/rtw89/debug.h +@@ -26,6 +26,7 @@ enum rtw89_debug_mask { + RTW89_DBG_HW_SCAN = BIT(15), + RTW89_DBG_SAR = BIT(16), + RTW89_DBG_STATE = BIT(17), ++ RTW89_DBG_WOW = BIT(18), + + RTW89_DBG_UNEXP = BIT(31), + }; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 6bf6ad62ff7a6..814ca4bc22587 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -1564,6 +1564,16 @@ int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow) + } + #undef SET_QUOTA + ++void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool enable) ++{ ++ u32 msk32 = B_AX_UC_MGNT_DEC | 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) +@@ -1913,10 +1923,10 @@ static int scheduler_init(struct rtw89_dev *rtwdev, u8 mac_idx) + return 0; + } + +-static int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, +- enum rtw89_machdr_frame_type type, +- enum rtw89_mac_fwd_target fwd_target, +- u8 mac_idx) ++int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, ++ enum rtw89_machdr_frame_type type, ++ enum rtw89_mac_fwd_target fwd_target, ++ u8 mac_idx) + { + u32 reg; + u32 val; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index e3b4c7830f440..34f7d51be3f97 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -980,6 +980,16 @@ static inline void rtw89_mac_ctrl_hci_dma_trx(struct rtw89_dev *rtwdev, + 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 *rtwsta, + bool resume, u32 tx_time); + int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta, +@@ -1038,8 +1048,12 @@ void rtw89_mac_pkt_drop_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); + u16 rtw89_mac_dle_buf_req(struct rtw89_dev *rtwdev, u16 buf_len, bool wd); + int rtw89_mac_set_cpuio(struct rtw89_dev *rtwdev, + struct rtw89_cpuio_ctrl *ctrl_para, bool wd); ++int rtw89_mac_typ_fltr_opt(struct rtw89_dev *rtwdev, ++ enum rtw89_machdr_frame_type type, ++ enum rtw89_mac_fwd_target fwd_target, u8 mac_idx); + 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); + + #endif +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +index a296bfa8188f2..6e79bf899901d 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -14,6 +14,7 @@ + #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, +@@ -916,6 +917,55 @@ static int rtw89_ops_set_tid_config(struct ieee80211_hw *hw, + return 0; + } + ++#ifdef CONFIG_PM ++static int rtw89_ops_suspend(struct ieee80211_hw *hw, ++ struct cfg80211_wowlan *wowlan) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ int ret; ++ ++ set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); ++ cancel_delayed_work_sync(&rtwdev->track_work); ++ ++ mutex_lock(&rtwdev->mutex); ++ ret = rtw89_wow_suspend(rtwdev, wowlan); ++ mutex_unlock(&rtwdev->mutex); ++ ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret); ++ clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int rtw89_ops_resume(struct ieee80211_hw *hw) ++{ ++ struct rtw89_dev *rtwdev = hw->priv; ++ int ret; ++ ++ mutex_lock(&rtwdev->mutex); ++ ret = rtw89_wow_resume(rtwdev); ++ if (ret) ++ rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret); ++ mutex_unlock(&rtwdev->mutex); ++ ++ clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags); ++ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, ++ RTW89_TRACK_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); ++} ++#endif ++ + const struct ieee80211_ops rtw89_ops = { + .tx = rtw89_ops_tx, + .wake_tx_queue = rtw89_ops_wake_tx_queue, +@@ -953,5 +1003,10 @@ const struct ieee80211_ops rtw89_ops = { + .set_sar_specs = rtw89_ops_set_sar_specs, + .sta_rc_update = rtw89_ops_sta_rc_update, + .set_tid_config = rtw89_ops_set_tid_config, ++#ifdef CONFIG_PM ++ .suspend = rtw89_ops_suspend, ++ .resume = rtw89_ops_resume, ++ .set_wakeup = rtw89_ops_set_wakeup, ++#endif + }; + EXPORT_SYMBOL(rtw89_ops); +diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c +index 5f8e19639362d..07a2e23759f0b 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.c ++++ b/drivers/net/wireless/realtek/rtw89/pci.c +@@ -186,6 +186,17 @@ static void rtw89_pci_ctrl_txdma_ch_pcie(struct rtw89_dev *rtwdev, bool enable) + } + } + ++static void rtw89_pci_ctrl_txdma_fw_ch_pcie(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, +@@ -2513,7 +2524,7 @@ static int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev) + + /* disable all channels except to FW CMD channel to download firmware */ + rtw89_pci_ctrl_txdma_ch_pcie(rtwdev, false); +- rtw89_write32_clr(rtwdev, info->dma_stop1.addr, B_AX_STOP_CH12); ++ rtw89_pci_ctrl_txdma_fw_ch_pcie(rtwdev, true); + + /* start DMA activities */ + rtw89_pci_ctrl_dma_all(rtwdev, true); +@@ -3771,6 +3782,16 @@ static const struct rtw89_hci_ops rtw89_pci_ops = { + + .recovery_start = rtw89_pci_ops_recovery_start, + .recovery_complete = rtw89_pci_ops_recovery_complete, ++ ++ .ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch_pcie, ++ .ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch_pcie, ++ .ctrl_trxhci = rtw89_pci_ctrl_dma_trx, ++ .poll_txdma_ch = rtw89_poll_txdma_ch_idle_pcie, ++ .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_rst_bdram_pcie, + }; + + int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c +index bf41a11416792..40498812205ea 100644 +--- a/drivers/net/wireless/realtek/rtw89/ps.c ++++ b/drivers/net/wireless/realtek/rtw89/ps.c +@@ -59,7 +59,7 @@ static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter) + rtw89_mac_power_mode_change(rtwdev, enter); + } + +-static void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + { + if (rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT) + return; +diff --git a/drivers/net/wireless/realtek/rtw89/ps.h b/drivers/net/wireless/realtek/rtw89/ps.h +index 0feae39916238..6ac1f7ea53394 100644 +--- a/drivers/net/wireless/realtek/rtw89/ps.h ++++ b/drivers/net/wireless/realtek/rtw89/ps.h +@@ -8,6 +8,7 @@ + void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); + 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, struct rtw89_vif *rtwvif); + 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); +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 33f2b67bfca37..2f6358244934f 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -952,6 +952,9 @@ + B_AX_STF_OQT_OVERFLOW_ERR_INT_EN | \ + B_AX_STF_OQT_UNDERFLOW_ERR_INT_EN) + ++#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) +@@ -1570,6 +1573,8 @@ + #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 + +@@ -1581,6 +1586,9 @@ + #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) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 7995d720dc921..becce3b48f518 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -1990,6 +1990,12 @@ static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev, + rtw8852a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); + } + ++#ifdef CONFIG_PM ++static const struct wiphy_wowlan_support rtw_wowlan_stub_8852a = { ++ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, ++}; ++#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, +@@ -2139,6 +2145,9 @@ const struct rtw89_chip_info rtw8852a_chip_info = { + .imr_info = &rtw8852a_imr_info, + .rrsr_cfgs = &rtw8852a_rrsr_cfgs, + .dma_ch_mask = 0, ++#ifdef CONFIG_PM ++ .wowlan_stub = &rtw_wowlan_stub_8852a, ++#endif + }; + EXPORT_SYMBOL(rtw8852a_chip_info); + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index 93332feabc44d..acb0e2e0adbac 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2796,6 +2796,12 @@ static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev) + return 0; + } + ++#ifdef CONFIG_PM ++static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = { ++ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, ++}; ++#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, +@@ -2949,6 +2955,9 @@ const struct rtw89_chip_info rtw8852c_chip_info = { + .imr_info = &rtw8852c_imr_info, + .rrsr_cfgs = &rtw8852c_rrsr_cfgs, + .dma_ch_mask = 0, ++#ifdef CONFIG_PM ++ .wowlan_stub = &rtw_wowlan_stub_8852c, ++#endif + }; + EXPORT_SYMBOL(rtw8852c_chip_info); + +diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c +new file mode 100644 +index 0000000000000..3d30083fcb9a8 +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/wow.c +@@ -0,0 +1,633 @@ ++// 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" ++ ++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) ++{ ++ struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; ++ ++ __rtw89_enter_ps_mode(rtwdev, rtwvif); ++} ++ ++static void rtw89_wow_enter_lps(struct rtw89_dev *rtwdev) ++{ ++ struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; ++ ++ rtw89_enter_lps(rtwdev, rtwvif); ++} ++ ++static void rtw89_wow_leave_lps(struct rtw89_dev *rtwdev) ++{ ++ rtw89_leave_lps(rtwdev); ++} ++ ++static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow) ++{ ++ 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_write32_clr(rtwdev, R_AX_RX_FLTR_OPT, 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); ++ } 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_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 void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable) ++{ ++ enum rtw89_mac_fwd_target fwd_target = enable ? ++ RTW89_FWD_DONT_CARE : ++ RTW89_FWD_TO_HOST; ++ ++ rtw89_mac_typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0); ++ rtw89_mac_typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0); ++ rtw89_mac_typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0); ++} ++ ++static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev) ++{ ++ enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; ++ struct cfg80211_wowlan_nd_info nd_info; ++ struct cfg80211_wowlan_wakeup wakeup = { ++ .pattern_idx = -1, ++ }; ++ u32 wow_reason_reg; ++ u8 reason; ++ ++ if (chip_id == RTL8852A || chip_id == RTL8852B) ++ wow_reason_reg = R_AX_C2HREG_DATA3 + 3; ++ else ++ wow_reason_reg = R_AX_C2HREG_DATA3_V1 + 3; ++ ++ reason = rtw89_read8(rtwdev, wow_reason_reg); ++ ++ switch (reason) { ++ 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: ++ /* Current firmware and driver don't report pattern index ++ * Use pattern_idx to 0 defaultly. ++ */ ++ wakeup.pattern_idx = 0; ++ 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(rtwdev->wow.wow_vif, NULL, ++ GFP_KERNEL); ++ return; ++ } ++ ++ ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup, ++ GFP_KERNEL); ++} ++ ++static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ ++ /* 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 RTW89_NET_TYPE_INFRA: ++ rtw_wow->wow_vif = vif; ++ break; ++ case RTW89_NET_TYPE_NO_LINK: ++ default: ++ break; ++ } ++} ++ ++static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ ++ rtw_wow->wow_vif = NULL; ++ rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM); ++ rtw_wow->pattern_cnt = 0; ++} ++ ++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 *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); ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_wow_vif_iter(rtwdev, rtwvif); ++ ++ if (!rtw_wow->wow_vif) ++ return -EPERM; ++ ++ return 0; ++} ++ ++static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) ++{ ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; ++ struct ieee80211_sta *wow_sta; ++ struct rtw89_sta *rtwsta = NULL; ++ bool is_conn = true; ++ int ret; ++ ++ wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid); ++ if (wow_sta) ++ rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; ++ else ++ is_conn = false; ++ ++ if (wow) { ++ if (rtw_wow->pattern_cnt) ++ rtwvif->wowlan_pattern = true; ++ if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) ++ rtwvif->wowlan_magic = true; ++ } else { ++ rtwvif->wowlan_pattern = false; ++ rtwvif->wowlan_magic = false; ++ } ++ ++ ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, 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, rtwsta); ++ if (ret) { ++ rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n", ++ ret); ++ return ret; ++ } ++ } ++ ++ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c join info\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c cam\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, 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) ++{ ++ u8 polling; ++ int ret; ++ ++ ret = read_poll_timeout_atomic(rtw89_read8_mask, polling, ++ wow_enable == !!polling, ++ 50, 50000, false, rtwdev, ++ R_AX_WOW_CTRL, B_AX_WOW_WOWEN); ++ if (ret) ++ rtw89_err(rtwdev, "failed to check wow status %s\n", ++ wow_enable ? "enabled" : "disabled"); ++ return ret; ++} ++ ++static void rtw89_wow_release_pkt_list(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct list_head *pkt_list = &rtw_wow->pkt_list; ++ struct rtw89_pktofld_info *info, *tmp; ++ ++ list_for_each_entry_safe(info, tmp, pkt_list, list) { ++ rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); ++ rtw89_core_release_bit_map(rtwdev->pkt_offload, ++ info->id); ++ list_del(&info->list); ++ kfree(info); ++ } ++} ++ ++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; ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; ++ struct ieee80211_sta *wow_sta; ++ struct rtw89_sta *rtwsta = NULL; ++ bool is_conn = true; ++ int ret; ++ ++ rtw89_hci_disable_intr(rtwdev); ++ ++ wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid); ++ if (wow_sta) ++ rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; ++ else ++ is_conn = false; ++ ++ ret = rtw89_fw_download(rtwdev, fw_type); ++ if (ret) { ++ rtw89_warn(rtwdev, "download fw failed\n"); ++ return ret; ++ } ++ ++ rtw89_phy_init_rf_reg(rtwdev, true); ++ ++ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, ++ RTW89_ROLE_FW_RESTORE); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c role maintain\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, wow_vif, wow_sta); ++ 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, rtwsta, !is_conn); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c join info\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c cam\n"); ++ return ret; ++ } ++ ++ if (is_conn) { ++ rtw89_phy_ra_assoc(rtwdev, wow_sta); ++ rtw89_phy_set_bss_color(rtwdev, wow_vif); ++ rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif); ++ } ++ ++ rtw89_mac_hw_mgnt_sec(rtwdev, wow); ++ rtw89_hci_enable_intr(rtwdev); ++ ++ 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(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(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; ++ } ++ rtw89_hci_enable_intr(rtwdev); ++ ++ return 0; ++} ++ ++static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev) ++{ ++ int ret; ++ ++ ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); ++ if (ret) ++ rtw89_err(rtwdev, "cfg ppdu status\n"); ++ ++ return ret; ++} ++ ++static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; ++ int ret; ++ ++ ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to enable keep alive\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, true); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n"); ++ goto out; ++ } ++ ++ ret = rtw89_wow_cfg_wake(rtwdev, true); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to config wake\n"); ++ goto out; ++ } ++ ++ ret = rtw89_wow_check_fw_status(rtwdev, true); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to check enable fw ready\n"); ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++ ++static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_wow_param *rtw_wow = &rtwdev->wow; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; ++ int ret; ++ ++ ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to disable keep alive\n"); ++ goto out; ++ } ++ ++ rtw89_wow_release_pkt_list(rtwdev); ++ ++ ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n"); ++ goto out; ++ } ++ ++ ret = rtw89_wow_cfg_wake(rtwdev, false); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to disable config wake\n"); ++ goto out; ++ } ++ ++ ret = rtw89_wow_check_fw_status(rtwdev, false); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to check disable fw ready\n"); ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++ ++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_wow_swap_fw(rtwdev, true); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to swap to wow fw\n"); ++ goto out; ++ } ++ ++ rtw89_wow_fw_start(rtwdev); ++ if (ret) { ++ rtw89_err(rtwdev, "wow: failed to let wow fw start\n"); ++ goto out; ++ } ++ ++ rtw89_wow_enter_lps(rtwdev); ++ ++ 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_lps(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; ++} ++ ++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"); ++ ++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_lps(rtwdev); ++ ++ 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 0000000000000..a2f7b2e3cdb4d +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw89/wow.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2019-2022 Realtek Corporation ++ */ ++ ++#ifndef __RTW89_WOW_H__ ++#define __RTW89_WOW_H__ ++ ++enum rtw89_wake_reason { ++ RTW89_WOW_RSN_RX_PTK_REKEY = 0x1, ++ RTW89_WOW_RSN_RX_GTK_REKEY = 0x2, ++ 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, ++}; ++ ++int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan); ++int rtw89_wow_resume(struct rtw89_dev *rtwdev); ++ ++#endif +-- +2.13.6 + diff --git a/SOURCES/0053-wifi-rtw89-add-WoWLAN-pattern-match-support.patch b/SOURCES/0053-wifi-rtw89-add-WoWLAN-pattern-match-support.patch new file mode 100644 index 0000000..4644fd7 --- /dev/null +++ b/SOURCES/0053-wifi-rtw89-add-WoWLAN-pattern-match-support.patch @@ -0,0 +1,528 @@ +From 88f0524e1cdff80fcf2f547400d9fa369190cff9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:28 +0200 +Subject: [PATCH 053/142] wifi: rtw89: add WoWLAN pattern match support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit d2b68e95b5bc97d81d150a46447167bf21bd555f +Author: Chin-Yen Lee +Date: Thu Oct 27 13:27:07 2022 +0800 + + wifi: rtw89: add WoWLAN pattern match support + + Pattern match is an option of WoWLAN to allow the device to be woken up + from suspend mode when receiving packets matched user-designed patterns. + + The patterns are written into hardware via WoWLAN firmware in suspend + flow if users have set up them. If packets matched designed pattern are + received, WoWLAN firmware will send an interrupt and then wake up the + device. + + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221027052707.14605-8-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 18 ++ + drivers/net/wireless/realtek/rtw89/fw.c | 52 ++++++ + drivers/net/wireless/realtek/rtw89/fw.h | 67 ++++++++ + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 3 + + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3 + + drivers/net/wireless/realtek/rtw89/util.h | 11 ++ + drivers/net/wireless/realtek/rtw89/wow.c | 228 +++++++++++++++++++++++++- + 7 files changed, 381 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 9f80359e27aa2..b60de6662548b 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -3489,9 +3489,27 @@ struct rtw89_phy_efuse_gain { + s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */ + }; + ++#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; ++ u32 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_param { + struct ieee80211_vif *wow_vif; + DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); ++ struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM]; + u8 pattern_cnt; + struct list_head pkt_list; + }; +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index c8f32a471e520..2763149586e27 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -3174,3 +3174,55 @@ int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, + + return ret; + } ++ ++#define H2C_WOW_CAM_UPD_LEN 24 ++int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, ++ struct rtw89_wow_cam_info *cam_info) ++{ ++ struct sk_buff *skb; ++ int ret; ++ ++ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WOW_CAM_UPD_LEN); ++ if (!skb) { ++ rtw89_err(rtwdev, "failed to alloc skb for keep alive\n"); ++ return -ENOMEM; ++ } ++ ++ skb_put(skb, H2C_WOW_CAM_UPD_LEN); ++ ++ RTW89_SET_WOW_CAM_UPD_R_W(skb->data, cam_info->r_w); ++ RTW89_SET_WOW_CAM_UPD_IDX(skb->data, cam_info->idx); ++ if (cam_info->valid) { ++ RTW89_SET_WOW_CAM_UPD_WKFM1(skb->data, cam_info->mask[0]); ++ RTW89_SET_WOW_CAM_UPD_WKFM2(skb->data, cam_info->mask[1]); ++ RTW89_SET_WOW_CAM_UPD_WKFM3(skb->data, cam_info->mask[2]); ++ RTW89_SET_WOW_CAM_UPD_WKFM4(skb->data, cam_info->mask[3]); ++ RTW89_SET_WOW_CAM_UPD_CRC(skb->data, cam_info->crc); ++ RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(skb->data, ++ cam_info->negative_pattern_match); ++ RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(skb->data, ++ cam_info->skip_mac_hdr); ++ RTW89_SET_WOW_CAM_UPD_UC(skb->data, cam_info->uc); ++ RTW89_SET_WOW_CAM_UPD_MC(skb->data, cam_info->mc); ++ RTW89_SET_WOW_CAM_UPD_BC(skb->data, cam_info->bc); ++ } ++ RTW89_SET_WOW_CAM_UPD_VALID(skb->data, cam_info->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, ++ H2C_WOW_CAM_UPD_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; ++} +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 25dd7bf8e730d..509a3eac5ffe3 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -2033,6 +2033,71 @@ static inline void RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(void *h2c, u32 val) + le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24)); + } + ++static inline void RTW89_SET_WOW_CAM_UPD_R_W(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, BIT(0)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_IDX(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 1)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_WKFM1(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 1, val, GENMASK(31, 0)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_WKFM2(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 2, val, GENMASK(31, 0)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_WKFM3(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 3, val, GENMASK(31, 0)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_WKFM4(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 4, val, GENMASK(31, 0)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_CRC(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 5, val, GENMASK(15, 0)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_NEGATIVE_PATTERN_MATCH(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(22)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_SKIP_MAC_HDR(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(23)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_UC(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(24)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_MC(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(25)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_BC(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(26)); ++} ++ ++static inline void RTW89_SET_WOW_CAM_UPD_VALID(void *h2c, u32 val) ++{ ++ le32p_replace_bits((__le32 *)h2c + 5, val, BIT(31)); ++} ++ + enum rtw89_btc_btf_h2c_class { + BTFC_SET = 0x10, + BTFC_GET = 0x11, +@@ -3039,6 +3104,8 @@ int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, bool enable); + ++int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, ++ struct rtw89_wow_cam_info *cam_info); + static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) + { + const struct rtw89_chip_info *chip = rtwdev->chip; +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index becce3b48f518..4cea5fb4327d7 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -1993,6 +1993,9 @@ static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev, + #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 + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index acb0e2e0adbac..6619ba7307199 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2799,6 +2799,9 @@ static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev) + #ifdef CONFIG_PM + static const struct wiphy_wowlan_support rtw_wowlan_stub_8852c = { + .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 + +diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h +index 1ae80b7561daa..e2ed4565025dd 100644 +--- a/drivers/net/wireless/realtek/rtw89/util.h ++++ b/drivers/net/wireless/realtek/rtw89/util.h +@@ -44,4 +44,15 @@ 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]; ++ } ++} ++ + #endif +diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c +index 3d30083fcb9a8..7de4dd047d6b3 100644 +--- a/drivers/net/wireless/realtek/rtw89/wow.c ++++ b/drivers/net/wireless/realtek/rtw89/wow.c +@@ -162,6 +162,227 @@ static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvi + } + } + ++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 *rtwvif, ++ 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->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 *rtwvif, ++ 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, 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 *rtwvif, ++ 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, ++ &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_fw_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_fw_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; +@@ -188,7 +409,8 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev, + if (!rtw_wow->wow_vif) + return -EPERM; + +- return 0; ++ rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; ++ return rtw89_wow_parse_patterns(rtwdev, rtwvif, wowlan); + } + + static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) +@@ -442,6 +664,8 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) + struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; + int ret; + ++ rtw89_wow_pattern_write(rtwdev); ++ + ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to enable keep alive\n"); +@@ -476,6 +700,8 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) + struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv; + int ret; + ++ rtw89_wow_pattern_clear(rtwdev); ++ + ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable keep alive\n"); +-- +2.13.6 + diff --git a/SOURCES/0054-wifi-rtw89-8852b-Fix-spelling-mistake-KIP_RESOTRE-KI.patch b/SOURCES/0054-wifi-rtw89-8852b-Fix-spelling-mistake-KIP_RESOTRE-KI.patch new file mode 100644 index 0000000..dcc3db4 --- /dev/null +++ b/SOURCES/0054-wifi-rtw89-8852b-Fix-spelling-mistake-KIP_RESOTRE-KI.patch @@ -0,0 +1,45 @@ +From 8e1bbb183af8e5f145278505297cf0f68415c33e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:28 +0200 +Subject: [PATCH 054/142] wifi: rtw89: 8852b: Fix spelling mistake KIP_RESOTRE + -> KIP_RESTORE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 8fa681703175ba0ea283dd564a64edaef3472ee6 +Author: Colin Ian King +Date: Thu Oct 20 08:26:46 2022 +0100 + + wifi: rtw89: 8852b: Fix spelling mistake KIP_RESOTRE -> KIP_RESTORE + + Ther is a spelling mistake in a rtw89_debug message. Fix it. + + Signed-off-by: Colin Ian King + Acked-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221020072646.1513307-1-colin.i.king@gmail.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +index 8fd01502ac5be..722ae34b09c1f 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +@@ -1754,7 +1754,7 @@ static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + id == 0x14 ? "PWR_CAL" : + id == 0x15 ? "DPK_RXAGC" : + id == 0x16 ? "KIP_PRESET" : +- id == 0x17 ? "KIP_RESOTRE" : "DPK_TXAGC", ++ id == 0x17 ? "KIP_RESTORE" : "DPK_TXAGC", + dpk_cmd); + } + +-- +2.13.6 + diff --git a/SOURCES/0055-wifi-rtw89-dump-dispatch-status-via-debug-port.patch b/SOURCES/0055-wifi-rtw89-dump-dispatch-status-via-debug-port.patch new file mode 100644 index 0000000..4227c17 --- /dev/null +++ b/SOURCES/0055-wifi-rtw89-dump-dispatch-status-via-debug-port.patch @@ -0,0 +1,726 @@ +From 2fe1e68742cda8fe71e1d59b14e34121d1f2a764 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:28 +0200 +Subject: [PATCH 055/142] wifi: rtw89: dump dispatch status via debug port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit d6197c9121dd72f35e5702aa55ee5c1583e0bfdb +Author: Chia-Yuan Li +Date: Wed Nov 2 09:42:59 2022 +0800 + + wifi: rtw89: dump dispatch status via debug port + + Dispatch is a component to decide packets forward to host, DMAC or + HAXIDMA. It contains CDT standing for CPU dispatcher, HDT standing + for host dispatcher, WDE standing for descriptor engine and PLE standing + for payload engine. STF is one kind of modes, it can be used if packet + send to hardware and doesn't need release report. + + These debug port information can help to clarify the reason if + packets stuck in dispatch. + + Signed-off-by: Chia-Yuan Li + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221102014300.14091-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/debug.c | 575 +++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/mac.h | 45 +++ + drivers/net/wireless/realtek/rtw89/reg.h | 5 + + 3 files changed, 625 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +index cd44d9aa37ca0..afd10e91d3ea5 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.c ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -1114,6 +1114,303 @@ static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c1 = { + .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, +@@ -1603,6 +1900,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, + struct rtw89_dev *rtwdev, u32 sel) + { + const struct rtw89_mac_dbg_port_info *info; ++ u32 index; + u32 val32; + u16 val16; + u8 val8; +@@ -1878,6 +2176,235 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, + info = &dbg_port_pktinfo; + seq_puts(m, "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); ++ seq_printf(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_printf(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_printf(m, "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); ++ seq_puts(m, "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); ++ seq_printf(m, "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); ++ seq_puts(m, "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); ++ seq_printf(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); ++ seq_puts(m, "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); +@@ -1956,6 +2483,10 @@ static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 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) +@@ -2026,6 +2557,50 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, + 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); +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 34f7d51be3f97..46d9cad2b5ec8 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -211,6 +211,51 @@ enum rtw89_mac_dbg_port_sel { + 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, +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 2f6358244934f..8a1cb8f4aa16c 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -952,6 +952,11 @@ + 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_RX_FUNCTION_STOP 0x8920 + #define B_AX_HDR_RX_STOP BIT(0) + +-- +2.13.6 + diff --git a/SOURCES/0056-wifi-rtw89-update-D-MAC-and-C-MAC-dump-to-diagnose-S.patch b/SOURCES/0056-wifi-rtw89-update-D-MAC-and-C-MAC-dump-to-diagnose-S.patch new file mode 100644 index 0000000..b8b299e --- /dev/null +++ b/SOURCES/0056-wifi-rtw89-update-D-MAC-and-C-MAC-dump-to-diagnose-S.patch @@ -0,0 +1,1399 @@ +From 70da8bd29b1d6b9638b7defa9dc37e97357fd6bc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:28 +0200 +Subject: [PATCH 056/142] wifi: rtw89: update D-MAC and C-MAC dump to diagnose + SER +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit f7333fc2135b96dc36965a8e711a9275432256df +Author: Chia-Yuan Li +Date: Wed Nov 2 09:43:00 2022 +0800 + + wifi: rtw89: update D-MAC and C-MAC dump to diagnose SER + + To detect TX or RX stuck, we implement SER (system error recovery) in + firmware to recover abnormal states of hardware, and report events to + driver. This kind of events could happen rarely per day. + + SER might be true-positive or false-negative cases, and it could be failed + to recover true-positive case. We dump related registers to kernel message + at that moment and collect them from users, because they occur rarely, + randomly and hard to make sure we reproduce the same symptom. To address + problems accurately, add more registers by this patch. + + It also might be false-positive cases that looks like TX or RX get stuck, + we need to dump registers from debugfs manually, so also add similar + things to debugfs as well. + + Signed-off-by: Chia-Yuan Li + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221102014300.14091-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/debug.c | 426 +++++++++++++++++++++++------ + drivers/net/wireless/realtek/rtw89/mac.c | 374 ++++++++++++++++++------- + drivers/net/wireless/realtek/rtw89/mac.h | 1 + + drivers/net/wireless/realtek/rtw89/pci.h | 12 + + drivers/net/wireless/realtek/rtw89/reg.h | 229 +++++++++++++++- + 5 files changed, 845 insertions(+), 197 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +index afd10e91d3ea5..8297e35bfa52b 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.c ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -8,6 +8,7 @@ + #include "debug.h" + #include "fw.h" + #include "mac.h" ++#include "pci.h" + #include "ps.h" + #include "reg.h" + #include "sar.h" +@@ -988,7 +989,9 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, + static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, + struct seq_file *m) + { +- int ret; ++ 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) { +@@ -996,98 +999,347 @@ static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, + return ret; + } + +- seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR)); +- seq_printf(m, "[0]R_AX_WDRLS_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); +- seq_printf(m, "[1]R_AX_SEC_ERR_IMR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_ERR_IMR_ISR)); +- seq_printf(m, "[2.1]R_AX_MPDU_TX_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); +- seq_printf(m, "[2.2]R_AX_MPDU_RX_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); +- seq_printf(m, "[3]R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); +- seq_printf(m, "[4]R_AX_WDE_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); +- seq_printf(m, "[5.1]R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); +- seq_printf(m, "[5.2]R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); +- seq_printf(m, "[6]R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); +- seq_printf(m, "[7]R_AX_PKTIN_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); +- seq_printf(m, "[8.1]R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); +- seq_printf(m, "[8.2]R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); +- seq_printf(m, "[8.3]R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); +- seq_printf(m, "[10]R_AX_CPUIO_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_CPUIO_ERR_ISR)); +- seq_printf(m, "[11.1]R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); +- seq_printf(m, "[11.2]R_AX_BBRPT_CHINFO_ERR_IMR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR_ISR)); +- seq_printf(m, "[11.3]R_AX_BBRPT_DFS_ERR_IMR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR_ISR)); +- seq_printf(m, "[11.4]R_AX_LA_ERRFLAG=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_LA_ERRFLAG)); ++ dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); ++ seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); ++ seq_printf(m, "R_AX_DMAC_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR)); ++ ++ if (dmac_err) { ++ seq_printf(m, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); ++ seq_printf(m, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1)); ++ if (chip->chip_id == RTL8852C) { ++ seq_printf(m, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); ++ seq_printf(m, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); ++ seq_printf(m, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); ++ seq_printf(m, "R_AX_PLE_DBGERR_STS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS)); ++ } ++ } ++ ++ if (dmac_err & B_AX_WDRLS_ERR_FLAG) { ++ seq_printf(m, "R_AX_WDRLS_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); ++ seq_printf(m, "R_AX_WDRLS_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); ++ if (chip->chip_id == RTL8852C) ++ seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1)); ++ else ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_SEC_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); ++ seq_printf(m, "R_AX_SEC_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); ++ seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); ++ seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); ++ seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); ++ seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); ++ seq_printf(m, "R_AX_SEC_DEBUG1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); ++ seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); ++ seq_printf(m, "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); ++ seq_printf(m, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", ++ i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2)); ++ } ++ } else { ++ seq_printf(m, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); ++ seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); ++ seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); ++ seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); ++ seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); ++ seq_printf(m, "R_AX_SEC_CAM_WDATA=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); ++ seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); ++ seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); ++ seq_printf(m, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); ++ seq_printf(m, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); ++ seq_printf(m, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); ++ seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); ++ seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); ++ seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); ++ seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); ++ seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR)); ++ } else { ++ seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); ++ seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); ++ seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); ++ seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); ++ seq_printf(m, "R_AX_WD_CPUQ_OP_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); ++ seq_printf(m, "R_AX_WD_CPUQ_OP_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); ++ seq_printf(m, "R_AX_WD_CPUQ_OP_2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); ++ seq_printf(m, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); ++ seq_printf(m, "R_AX_PL_CPUQ_OP_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); ++ seq_printf(m, "R_AX_PL_CPUQ_OP_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); ++ seq_printf(m, "R_AX_PL_CPUQ_OP_2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); ++ seq_printf(m, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); ++ if (chip->chip_id == RTL8852C) { ++ seq_printf(m, "R_AX_RX_CTRL0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RX_CTRL0)); ++ seq_printf(m, "R_AX_RX_CTRL1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RX_CTRL1)); ++ seq_printf(m, "R_AX_RX_CTRL2=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RX_CTRL2)); ++ } else { ++ seq_printf(m, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); ++ seq_printf(m, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_PKTIN_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); ++ seq_printf(m, "R_AX_PKTIN_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); ++ } ++ ++ if (dmac_err & B_AX_DISPATCH_ERR_FLAG) { ++ seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); ++ seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); ++ seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); ++ seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); ++ seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); ++ seq_printf(m, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); ++ seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); ++ seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); ++ seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); ++ seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); ++ } else { ++ seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); ++ seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); ++ seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); ++ seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); ++ seq_printf(m, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", ++ rtw89_read32(rtwdev, R_AX_HAXI_IDCT)); ++ } + + return 0; + } + +-static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, +- struct seq_file *m) ++static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev, ++ struct seq_file *m, ++ enum rtw89_mac_idx band) + { ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u32 offset = 0; ++ u32 cmac_err; + int ret; + +- ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL); ++ ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL); + if (ret) { +- seq_puts(m, "[CMAC] : CMAC 0 not enabled\n"); ++ if (band) ++ seq_puts(m, "[CMAC] : CMAC1 not enabled\n"); ++ else ++ seq_puts(m, "[CMAC] : CMAC0 not enabled\n"); + return ret; + } + +- seq_printf(m, "R_AX_CMAC_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR)); +- seq_printf(m, "[0]R_AX_SCHEDULE_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR)); +- seq_printf(m, "[1]R_AX_PTCL_ISR0=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PTCL_ISR0)); +- seq_printf(m, "[3]R_AX_DLE_CTRL=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_DLE_CTRL)); +- seq_printf(m, "[4]R_AX_PHYINFO_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR)); +- seq_printf(m, "[5]R_AX_TXPWR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_TXPWR_ISR)); +- seq_printf(m, "[6]R_AX_RMAC_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_RMAC_ERR_ISR)); +- seq_printf(m, "[7]R_AX_TMAC_ERR_IMR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR)); +- +- ret = rtw89_mac_check_mac_en(rtwdev, 1, RTW89_CMAC_SEL); +- if (ret) { +- seq_puts(m, "[CMAC] : CMAC 1 not enabled\n"); +- return ret; ++ if (band) ++ offset = RTW89_MAC_AX_BAND_REG_OFFSET; ++ ++ cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset); ++ seq_printf(m, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); ++ seq_printf(m, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); ++ seq_printf(m, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset)); + } + +- seq_printf(m, "R_AX_CMAC_ERR_ISR_C1=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR_C1)); +- seq_printf(m, "[0]R_AX_SCHEDULE_ERR_ISR_C1=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR_C1)); +- seq_printf(m, "[1]R_AX_PTCL_ISR0_C1=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PTCL_ISR0_C1)); +- seq_printf(m, "[3]R_AX_DLE_CTRL_C1=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_DLE_CTRL_C1)); +- seq_printf(m, "[4]R_AX_PHYINFO_ERR_ISR_C1=0x%02x\n", +- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR_C1)); +- seq_printf(m, "[5]R_AX_TXPWR_ISR_C1=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_TXPWR_ISR_C1)); +- seq_printf(m, "[6]R_AX_RMAC_ERR_ISR_C1=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_RMAC_ERR_ISR_C1)); +- seq_printf(m, "[7]R_AX_TMAC_ERR_IMR_ISR_C1=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR_C1)); ++ if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { ++ seq_printf(m, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); ++ seq_printf(m, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset)); ++ } else { ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); ++ seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); ++ } else { ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); ++ seq_printf(m, "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) { ++ seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset)); ++ seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset)); ++ } else { ++ seq_printf(m, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset)); ++ } ++ seq_printf(m, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset)); ++ } ++ ++ seq_printf(m, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, ++ rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); ++ ++ return 0; ++} ++ ++static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, ++ struct seq_file *m) ++{ ++ rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_0); ++ if (rtwdev->dbcc_en) ++ rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_1); + + return 0; + } +@@ -1821,7 +2073,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pktinfo = { + 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_DBG_SEL_MASK, ++ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x03, + .rd_addr = R_AX_DBG_PORT_SEL, +@@ -1832,7 +2084,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_txdma = { + 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_DBG_SEL_MASK, ++ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x04, + .rd_addr = R_AX_DBG_PORT_SEL, +@@ -1843,7 +2095,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_rxdma = { + 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_DBG_SEL_MASK, ++ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x01, + .rd_addr = R_AX_DBG_PORT_SEL, +@@ -1854,7 +2106,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cvt = { + 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_DBG_SEL_MASK, ++ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x05, + .rd_addr = R_AX_DBG_PORT_SEL, +@@ -1865,7 +2117,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cxpl = { + 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_DBG_SEL_MASK, ++ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x05, + .rd_addr = R_AX_DBG_PORT_SEL, +@@ -1876,7 +2128,7 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_io = { + 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_DBG_SEL_MASK, ++ .sel_msk = B_AX_PCIE_DBG_SEL_MASK, + .srt = 0x00, + .end = 0x06, + .rd_addr = R_AX_DBG_PORT_SEL, +@@ -2457,7 +2709,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m, + 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_DBG_SEL_MASK); ++ B_AX_PCIE_DBG_SEL_MASK); + rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16); + seq_puts(m, "Enable pcie misc2 dump.\n"); + break; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 814ca4bc22587..ecd603a881345 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -7,6 +7,7 @@ + #include "debug.h" + #include "fw.h" + #include "mac.h" ++#include "pci.h" + #include "ps.h" + #include "reg.h" + #include "util.h" +@@ -274,106 +275,163 @@ static void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev, + } + } + +-static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, +- enum mac_ax_err_info err) ++static void rtw89_mac_dump_dmac_err_status(struct rtw89_dev *rtwdev) + { +- u32 dmac_err, cmac_err; ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u32 dmac_err; ++ int i, ret; + +- 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) ++ ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL); ++ if (ret) { ++ rtw89_warn(rtwdev, "[DMAC] : DMAC not enabled\n"); + 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)); +- +- cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR); +- rtw89_info(rtwdev, "R_AX_CMAC_ERR_ISR =0x%08x\n", cmac_err); + 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_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 ", +- rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG)); +- rtw89_info(rtwdev, "R_AX_PLE_ERR_FLAG_CFG =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG)); ++ 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 ", ++ 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_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) { +- rtw89_info(rtwdev, "R_AX_SEC_ERR_IMR_ISR =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D00 =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D04 =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D10 =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D14 =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D18 =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D20 =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D24 =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D28 =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); +- rtw89_info(rtwdev, "SEC_local_Register 0x9D2C =0x%08x\n", +- rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); ++ 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 { ++ 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 ", ++ 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_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 ", ++ 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_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) { +- rtw89_info(rtwdev, "R_AX_STA_SCHEDULER_ERR_IMR =0x%08x ", ++ 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_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 ", ++ 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 ", ++ 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)); +- dump_err_status_dispatcher(rtwdev); + } + + if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) { +- 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 (chip->chip_id == RTL8852C) { ++ 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 ", ++ 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 ", ++ 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)); +@@ -393,86 +451,190 @@ static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); + rtw89_info(rtwdev, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", + rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); +- 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)); +- dump_err_status_dispatcher(rtwdev); ++ 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 ", +- 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)); +- rtw89_info(rtwdev, "R_AX_PKTIN_ERR_IMR =0x%08x ", ++ 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_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) +- dump_err_status_dispatcher(rtwdev); ++ if (dmac_err & B_AX_DISPATCH_ERR_FLAG) { ++ 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) { ++ 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 (dmac_err & B_AX_DLE_CPUIO_ERR_FLAG) { +- rtw89_info(rtwdev, "R_AX_CPUIO_ERR_IMR=0x%08x ", +- rtw89_read32(rtwdev, R_AX_CPUIO_ERR_IMR)); +- rtw89_info(rtwdev, "R_AX_CPUIO_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_CPUIO_ERR_ISR)); ++ if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && 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 & BIT(11)) { +- rtw89_info(rtwdev, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); ++static void rtw89_mac_dump_cmac_err_status(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=0x%08x ", +- rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR)); +- rtw89_info(rtwdev, "R_AX_SCHEDULE_ERR_ISR=0x%04x\n", +- rtw89_read16(rtwdev, R_AX_SCHEDULE_ERR_ISR)); ++ 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=0x%08x ", +- rtw89_read32(rtwdev, R_AX_PTCL_IMR0)); +- rtw89_info(rtwdev, "R_AX_PTCL_ISR0=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PTCL_ISR0)); ++ 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) { +- rtw89_info(rtwdev, "R_AX_DLE_CTRL=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_DLE_CTRL)); ++ 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_PHYINTF_ERR_IND) { +- rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_IMR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR)); ++ 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=0x%08x ", +- rtw89_read32(rtwdev, R_AX_TXPWR_IMR)); +- rtw89_info(rtwdev, "R_AX_TXPWR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_TXPWR_ISR)); +- } +- +- if (cmac_err & B_AX_WMAC_RX_ERR_IND) { +- rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL=0x%08x ", +- rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL)); +- rtw89_info(rtwdev, "R_AX_PHYINFO_ERR_ISR=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR)); ++ 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) { +- rtw89_info(rtwdev, "R_AX_TMAC_ERR_IMR_ISR=0x%08x ", +- rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR)); +- rtw89_info(rtwdev, "R_AX_DBGSEL_TRXPTCL=0x%08x\n", +- rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL)); ++ 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(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) ++ 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_mac_dump_dmac_err_status(rtwdev); ++ rtw89_mac_dump_cmac_err_status(rtwdev, RTW89_MAC_0); ++ if (rtwdev->dbcc_en) ++ rtw89_mac_dump_cmac_err_status(rtwdev, RTW89_MAC_1); ++ + rtwdev->hci.ops->dump_err_status(rtwdev); + + if (err == MAC_AX_ERR_L0_PROMOTE_TO_L1) +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 46d9cad2b5ec8..045e8ec61a41e 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -440,6 +440,7 @@ enum rtw89_mac_bf_rrsc_rate { + #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 PTCL_IDLE_POLL_CNT 10000 + #define SW_CVR_DUR_US 8 +diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h +index 179740607778a..7d033501d4d95 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.h ++++ b/drivers/net/wireless/realtek/rtw89/pci.h +@@ -202,6 +202,18 @@ + #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) +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 8a1cb8f4aa16c..dbe06542f443f 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -326,8 +326,7 @@ + + #define R_AX_PCIE_DBG_CTRL 0x11C0 + #define B_AX_DBG_DUMMY_MASK GENMASK(23, 16) +-#define B_AX_DBG_SEL_MASK GENMASK(15, 13) +-#define B_AX_PCIE_DBG_SEL BIT(12) ++#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) +@@ -574,6 +573,10 @@ + #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) +@@ -1041,7 +1044,13 @@ + #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 0x8C34 ++#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_RRDY_ERR_INT_EN BIT(27) +@@ -1225,7 +1234,59 @@ + #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_ERR_FLAG_CFG 0x9034 ++ ++#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) +@@ -1436,6 +1497,19 @@ + #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) +@@ -1487,6 +1561,9 @@ + #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) +@@ -1602,6 +1679,7 @@ + #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) +@@ -1631,12 +1709,21 @@ + #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) +@@ -1771,6 +1858,28 @@ + 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) +@@ -1818,6 +1927,28 @@ + 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_R_SYM_WLCMAC1_P4_PC_EN BIT(4) +@@ -2386,6 +2517,41 @@ + #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) +@@ -2408,6 +2574,49 @@ + 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 +@@ -2715,6 +2924,18 @@ + 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) +-- +2.13.6 + diff --git a/SOURCES/0057-wifi-rtw89-8852b-change-debug-mask-of-message-of-no-.patch b/SOURCES/0057-wifi-rtw89-8852b-change-debug-mask-of-message-of-no-.patch new file mode 100644 index 0000000..7dd6173 --- /dev/null +++ b/SOURCES/0057-wifi-rtw89-8852b-change-debug-mask-of-message-of-no-.patch @@ -0,0 +1,72 @@ +From 42a885f1bd88f81ea13cc0ab0db0533a9ac0e046 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:29 +0200 +Subject: [PATCH 057/142] wifi: rtw89: 8852b: change debug mask of message of + no TX resource +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 901c247f9687b5aecc950a931a3b0e1930d02bfd +Author: Ping-Ke Shih +Date: Tue Nov 8 09:42:30 2022 +0800 + + wifi: rtw89: 8852b: change debug mask of message of no TX resource + + 8852B has smaller TX FIFO than others in WiFi chip, so it would be buffer + full frequently, but it doesn't affect TX performance. However, it shows + verbose debug messages with RTW89_DBG_UNEXP mask that is used to indicate + abnormal behavior, so change debug mask to RTW89_DBG_TXRX for 8852B. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221108014230.11068-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/pci.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c +index 07a2e23759f0b..7aa0af18cdd50 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.c ++++ b/drivers/net/wireless/realtek/rtw89/pci.c +@@ -971,8 +971,10 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, + 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]; +@@ -996,10 +998,20 @@ static u32 __rtw89_pci_check_and_reclaim_tx_resource(struct rtw89_dev *rtwdev, + 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) +- rtw89_debug(rtwdev, rtwpci->low_power ? RTW89_DBG_TXRX : RTW89_DBG_UNEXP, ++ if (min_cnt == 0) { ++ /* This message can be frequently shown in low power mode or ++ * high traffic with 8852B, and we have recognized it as normal ++ * behavior, so print with mask RTW89_DBG_TXRX in these situations. ++ */ ++ if (rtwpci->low_power || chip->chip_id == RTL8852B) ++ 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); +-- +2.13.6 + diff --git a/SOURCES/0058-wifi-rtw89-Fix-some-error-handling-path-in-rtw89_wow.patch b/SOURCES/0058-wifi-rtw89-Fix-some-error-handling-path-in-rtw89_wow.patch new file mode 100644 index 0000000..8d42438 --- /dev/null +++ b/SOURCES/0058-wifi-rtw89-Fix-some-error-handling-path-in-rtw89_wow.patch @@ -0,0 +1,65 @@ +From bb94a58ca685310dad2072683b97365647dd4389 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:29 +0200 +Subject: [PATCH 058/142] wifi: rtw89: Fix some error handling path in + rtw89_wow_enable() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 61ec34dee266f1cea092986d861a2cb136571199 +Author: Christophe JAILLET +Date: Sun Nov 13 16:42:21 2022 +0100 + + wifi: rtw89: Fix some error handling path in rtw89_wow_enable() + + 'ret' is not updated after several function calls in rtw89_wow_enable(). + This prevent error handling from working. + + Add the missing assignments. + + Fixes: 19e28c7fcc74 ("wifi: rtw89: add WoWLAN function support") + Signed-off-by: Christophe JAILLET + Acked-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/32320176eeff1c635baeea25ef0e87d116859e65.1668354083.git.christophe.jaillet@wanadoo.fr + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/wow.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c +index 7de4dd047d6b3..b2b826b2e09ae 100644 +--- a/drivers/net/wireless/realtek/rtw89/wow.c ++++ b/drivers/net/wireless/realtek/rtw89/wow.c +@@ -744,13 +744,13 @@ static int rtw89_wow_enable(struct rtw89_dev *rtwdev) + goto out; + } + +- rtw89_wow_swap_fw(rtwdev, true); ++ ret = rtw89_wow_swap_fw(rtwdev, true); + if (ret) { + rtw89_err(rtwdev, "wow: failed to swap to wow fw\n"); + goto out; + } + +- rtw89_wow_fw_start(rtwdev); ++ ret = rtw89_wow_fw_start(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to let wow fw start\n"); + goto out; +@@ -758,7 +758,7 @@ static int rtw89_wow_enable(struct rtw89_dev *rtwdev) + + rtw89_wow_enter_lps(rtwdev); + +- rtw89_wow_enable_trx_post(rtwdev); ++ ret = rtw89_wow_enable_trx_post(rtwdev); + if (ret) { + rtw89_err(rtwdev, "wow: failed to enable trx_post\n"); + goto out; +-- +2.13.6 + diff --git a/SOURCES/0059-wifi-rtw89-8852b-correct-TX-power-controlled-by-BT-c.patch b/SOURCES/0059-wifi-rtw89-8852b-correct-TX-power-controlled-by-BT-c.patch new file mode 100644 index 0000000..37eb0c4 --- /dev/null +++ b/SOURCES/0059-wifi-rtw89-8852b-correct-TX-power-controlled-by-BT-c.patch @@ -0,0 +1,81 @@ +From 8cfacd18e7402d31dbab5b3c384000bc2ecac77e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:29 +0200 +Subject: [PATCH 059/142] wifi: rtw89: 8852b: correct TX power controlled by + BT-coexistence +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 79ca91a3c1f1e5d871f393791e7538f9386a7711 +Author: Ping-Ke Shih +Date: Thu Nov 17 14:18:32 2022 +0800 + + wifi: rtw89: 8852b: correct TX power controlled by BT-coexistence + + When coexistence mechanism is under free-run mode, it could adjust WiFi + and BT TX power to avoid interference with each other. For other cases, + it should keep original TX power from regular predefined tables, so + set correct values to 255 for these cases. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221117061832.42057-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 30 +++++++++++++-------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 0df044b1c392a..85dfc1ebb0d97 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -318,27 +318,27 @@ static const struct rtw89_dig_regs rtw8852b_dig_regs = { + }; + + static const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_ul[] = { +- {15, 0, 0, 7}, /* 0 -> original */ +- {15, 2, 0, 7}, /* 1 -> for BT-connected ACI issue && BTG co-rx */ +- {15, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ +- {15, 0, 0, 7}, /* 3- >reserved for shared-antenna */ +- {15, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ +- {15, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ ++ {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 const struct rtw89_btc_rf_trx_para rtw89_btc_8852b_rf_dl[] = { +- {15, 0, 0, 7}, /* 0 -> original */ +- {15, 2, 0, 7}, /* 1 -> reserved for shared-antenna */ +- {15, 0, 0, 7}, /* 2 ->reserved for shared-antenna */ +- {15, 0, 0, 7}, /* 3- >reserved for shared-antenna */ +- {15, 0, 0, 7}, /* 4 ->reserved for shared-antenna */ +- {15, 0, 0, 7}, /* the below id is for non-shared-antenna free-run */ +- {15, 1, 0, 7}, +- {15, 1, 0, 7}, +- {15, 1, 0, 7} ++ {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 struct rtw89_btc_fbtc_mreg rtw89_btc_8852b_mon_reg[] = { +-- +2.13.6 + diff --git a/SOURCES/0060-wifi-rtw89-read-CFO-from-FD-or-preamble-CFO-field-of.patch b/SOURCES/0060-wifi-rtw89-read-CFO-from-FD-or-preamble-CFO-field-of.patch new file mode 100644 index 0000000..a6afd3b --- /dev/null +++ b/SOURCES/0060-wifi-rtw89-read-CFO-from-FD-or-preamble-CFO-field-of.patch @@ -0,0 +1,121 @@ +From 13b86e2e28b89197dc98c888c343f221e0960b81 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:29 +0200 +Subject: [PATCH 060/142] wifi: rtw89: read CFO from FD or preamble CFO field + of phy status ie_type 1 accordingly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 10cd4092f67eaf0cade4f50c68ecb055d4ee3a93 +Author: Eric Huang +Date: Thu Nov 17 14:30:00 2022 +0800 + + wifi: rtw89: read CFO from FD or preamble CFO field of phy status ie_type 1 accordingly + + Add macro to get FD(frequency domain) CFO field from ie_type 1, and correct + the naming for preamble CFO field. Each IC could assign the CFO source to + either FD CFO or preamble CFO in chip_info. Based on the suggestion from HW + designer, rtw8852b and its derived versions will have better CFO tracking + performance with FD CFO. + + Signed-off-by: Eric Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221117063001.42967-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 6 +++++- + drivers/net/wireless/realtek/rtw89/core.h | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + + drivers/net/wireless/realtek/rtw89/txrx.h | 4 +++- + 6 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 1ebb2743ff4c4..f1bf4c4471039 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -1196,7 +1196,11 @@ static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, u8 *addr, + if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) + return; + /* sign conversion for S(12,2) */ +- cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_CFO(addr), 11); ++ if (rtwdev->chip->cfo_src_fd) ++ cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_FD_CFO(addr), 11); ++ else ++ cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_PREMB_CFO(addr), 11); ++ + rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu); + } + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index b60de6662548b..ba4ccbde5ecf9 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2755,6 +2755,7 @@ struct rtw89_chip_info { + u32 c2h_ctrl_reg; + const u32 *c2h_regs; + const struct rtw89_page_regs *page_regs; ++ bool cfo_src_fd; + const struct rtw89_reg_def *dcfo_comp; + u8 dcfo_comp_sft; + const struct rtw89_imr_info *imr_info; +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 4cea5fb4327d7..f38a330698e9a 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -2143,6 +2143,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { + .c2h_ctrl_reg = R_AX_C2HREG_CTRL, + .c2h_regs = rtw8852a_c2h_regs, + .page_regs = &rtw8852a_page_regs, ++ .cfo_src_fd = false, + .dcfo_comp = &rtw8852a_dcfo_comp, + .dcfo_comp_sft = 3, + .imr_info = &rtw8852a_imr_info, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 85dfc1ebb0d97..22b3c86ee7d86 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -2512,6 +2512,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .c2h_ctrl_reg = R_AX_C2HREG_CTRL, + .c2h_regs = rtw8852b_c2h_regs, + .page_regs = &rtw8852b_page_regs, ++ .cfo_src_fd = true, + .dcfo_comp = &rtw8852b_dcfo_comp, + .dcfo_comp_sft = 3, + .imr_info = &rtw8852b_imr_info, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index 6619ba7307199..01e6358fa1a29 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2953,6 +2953,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { + .c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1, + .c2h_regs = rtw8852c_c2h_regs, + .page_regs = &rtw8852c_page_regs, ++ .cfo_src_fd = false, + .dcfo_comp = &rtw8852c_dcfo_comp, + .dcfo_comp_sft = 5, + .imr_info = &rtw8852c_imr_info, +diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h +index b889e7bf34c0c..9d4c6b6fa1250 100644 +--- a/drivers/net/wireless/realtek/rtw89/txrx.h ++++ b/drivers/net/wireless/realtek/rtw89/txrx.h +@@ -298,7 +298,9 @@ + le32_get_bits(*((const __le32 *)ie), GENMASK(11, 5)) + #define RTW89_GET_PHY_STS_IE01_CH_IDX(ie) \ + le32_get_bits(*((const __le32 *)ie), GENMASK(23, 16)) +-#define RTW89_GET_PHY_STS_IE01_CFO(ie) \ ++#define RTW89_GET_PHY_STS_IE01_FD_CFO(ie) \ ++ le32_get_bits(*((const __le32 *)(ie) + 1), GENMASK(19, 8)) ++#define RTW89_GET_PHY_STS_IE01_PREMB_CFO(ie) \ + le32_get_bits(*((const __le32 *)(ie) + 1), GENMASK(31, 20)) + + enum rtw89_tx_channel { +-- +2.13.6 + diff --git a/SOURCES/0061-wifi-rtw89-switch-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch b/SOURCES/0061-wifi-rtw89-switch-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch new file mode 100644 index 0000000..34589aa --- /dev/null +++ b/SOURCES/0061-wifi-rtw89-switch-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch @@ -0,0 +1,334 @@ +From ea32d2f7300d94511f2c43afac2ce59ac395b30c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:29 +0200 +Subject: [PATCH 061/142] wifi: rtw89: switch BANDEDGE and TX_SHAPE based on + OFDMA trigger frame +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 29136c95fdc5d9bbfb56131408388fefdba4ed95 +Author: Eric Huang +Date: Thu Nov 17 14:30:01 2022 +0800 + + wifi: rtw89: switch BANDEDGE and TX_SHAPE based on OFDMA trigger frame + + There are some registers for transmit waveform control, two of them used + in this change are for BANDEDGE and TX_SHAPE control. BANDEDGE controls + whether to apply band edge filter to transmit waveform. TX_SHAPE controls + whether to apply triangular mask to transmit waveform. It is found for + some chip, these two should be turned off during OFDMA UL traffic for + better performance. + + Signed-off-by: Eric Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221117063001.42967-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 2 + + drivers/net/wireless/realtek/rtw89/core.h | 9 ++ + drivers/net/wireless/realtek/rtw89/debug.h | 1 + + drivers/net/wireless/realtek/rtw89/phy.c | 127 +++++++++++++++++++++++++- + drivers/net/wireless/realtek/rtw89/phy.h | 5 + + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + + 8 files changed, 146 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index f1bf4c4471039..2ea38376bd2bb 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2237,6 +2237,7 @@ static void rtw89_track_work(struct work_struct *work) + rtw89_phy_ra_update(rtwdev); + rtw89_phy_cfo_track(rtwdev); + rtw89_phy_tx_path_div_track(rtwdev); ++ rtw89_phy_ul_tb_ctrl_track(rtwdev); + + if (rtwdev->lps_enabled && !rtwdev->btc.lps) + rtw89_enter_lps_track(rtwdev); +@@ -2560,6 +2561,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, + rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, + BTC_ROLE_MSTS_STA_CONN_END); + rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); ++ rtw89_phy_ul_tb_assoc(rtwdev, rtwvif); + } + + return ret; +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index ba4ccbde5ecf9..62d834dbff67b 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2261,6 +2261,8 @@ struct rtw89_vif { + bool wowlan_magic; + bool is_hesta; + bool last_a_ctrl; ++ bool dyn_tb_bedge_en; ++ u8 def_tri_idx; + struct work_struct update_beacon_work; + struct rtw89_addr_cam_entry addr_cam; + struct rtw89_bssid_cam_entry bssid_cam; +@@ -2646,6 +2648,11 @@ struct rtw89_dig_regs { + struct rtw89_reg_def p1_s20_pagcugc_en; + }; + ++struct rtw89_phy_ul_tb_info { ++ bool dyn_tb_tri_en; ++ u8 def_if_bandedge; ++}; ++ + struct rtw89_chip_info { + enum rtw89_core_chip_id chip_id; + const struct rtw89_chip_ops *ops; +@@ -2663,6 +2670,7 @@ struct rtw89_chip_info { + u8 support_chanctx_num; + u8 support_bands; + bool support_bw160; ++ bool support_ul_tb_ctrl; + bool hw_sec_hdr; + u8 rf_path_num; + u8 tx_nss; +@@ -3585,6 +3593,7 @@ struct rtw89_dev { + struct rtw89_phy_ch_info ch_info; + struct rtw89_phy_bb_gain_info bb_gain; + struct rtw89_phy_efuse_gain efuse_gain; ++ struct rtw89_phy_ul_tb_info ul_tb_info; + + struct delayed_work track_work; + struct delayed_work coex_act1_work; +diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h +index e7971583acbc9..d1de5e600836c 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.h ++++ b/drivers/net/wireless/realtek/rtw89/debug.h +@@ -27,6 +27,7 @@ enum rtw89_debug_mask { + RTW89_DBG_SAR = BIT(16), + RTW89_DBG_STATE = BIT(17), + RTW89_DBG_WOW = BIT(18), ++ RTW89_DBG_UL_TB = BIT(19), + + RTW89_DBG_UNEXP = BIT(31), + }; +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index 944bb0f2ee633..017710c580c72 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -2,6 +2,7 @@ + /* Copyright(c) 2019-2020 Realtek Corporation + */ + ++#include "coex.h" + #include "debug.h" + #include "fw.h" + #include "mac.h" +@@ -9,7 +10,7 @@ + #include "ps.h" + #include "reg.h" + #include "sar.h" +-#include "coex.h" ++#include "util.h" + + static u16 get_max_amsdu_len(struct rtw89_dev *rtwdev, + const struct rtw89_ra_report *report) +@@ -2794,6 +2795,129 @@ void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, + cfo->packet_count++; + } + ++void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); ++ struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info; ++ ++ if (!chip->support_ul_tb_ctrl) ++ return; ++ ++ rtwvif->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->dyn_tb_bedge_en = false; ++ else if (chan->band_type >= RTW89_BAND_5G && ++ chan->band_width >= RTW89_CHANNEL_WIDTH_40) ++ rtwvif->dyn_tb_bedge_en = true; ++ else ++ rtwvif->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->def_tri_idx); ++ rtw89_debug(rtwdev, RTW89_DBG_UL_TB, ++ "[ULTB] dyn_tb_begde_en=%d, dyn_tb_tri_en=%d\n", ++ rtwvif->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; ++}; ++ ++static ++void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ struct rtw89_phy_ul_tb_check_data *ul_tb_data) ++{ ++ struct rtw89_traffic_stats *stats = &rtwdev->stats; ++ struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); ++ ++ if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION) ++ return; ++ ++ if (!vif->cfg.assoc) ++ return; ++ ++ 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->def_tri_idx; ++ ul_tb_data->dyn_tb_bedge_en = rtwvif->dyn_tb_bedge_en; ++} ++ ++void rtw89_phy_ul_tb_ctrl_track(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; ++ struct rtw89_phy_ul_tb_check_data ul_tb_data = {}; ++ struct rtw89_vif *rtwvif; ++ ++ if (!chip->support_ul_tb_ctrl) ++ return; ++ ++ if (rtwdev->total_sta_assoc != 1) ++ return; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif, &ul_tb_data); ++ ++ if (!ul_tb_data.valid) ++ 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); ++ } ++ } ++} ++ ++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->support_ul_tb_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_stat_thermal_update(struct rtw89_dev *rtwdev) + { + struct rtw89_phy_stat *phystat = &rtwdev->phystat; +@@ -3980,6 +4104,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) + rtw89_physts_parsing_init(rtwdev); + rtw89_phy_dig_init(rtwdev); + rtw89_phy_cfo_init(rtwdev); ++ rtw89_phy_ul_tb_info_init(rtwdev); + + rtw89_phy_init_rf_nctl(rtwdev); + rtw89_chip_rfk_init(rtwdev); +diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h +index dac69a02e8687..21233f094644b 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.h ++++ b/drivers/net/wireless/realtek/rtw89/phy.h +@@ -64,6 +64,9 @@ + #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 CCX_MAX_PERIOD 2097 + #define CCX_MAX_PERIOD_UNIT 32 + #define MS_TO_4US_RATIO 250 +@@ -550,5 +553,7 @@ void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif + 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 *rtwvif); ++void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev); + + #endif +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index f38a330698e9a..eff6519cf0191 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -2082,6 +2082,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ), + .support_bw160 = false, ++ .support_ul_tb_ctrl = false, + .hw_sec_hdr = false, + .rf_path_num = 2, + .tx_nss = 2, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 22b3c86ee7d86..2d4d572dc601f 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -2452,6 +2452,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .support_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ), + .support_bw160 = false, ++ .support_ul_tb_ctrl = true, + .hw_sec_hdr = false, + .rf_path_num = 2, + .tx_nss = 2, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index 01e6358fa1a29..9bc98fd5d4ac2 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2891,6 +2891,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { + BIT(NL80211_BAND_5GHZ) | + BIT(NL80211_BAND_6GHZ), + .support_bw160 = true, ++ .support_ul_tb_ctrl = false, + .hw_sec_hdr = true, + .rf_path_num = 2, + .tx_nss = 2, +-- +2.13.6 + diff --git a/SOURCES/0062-wifi-rtw89-avoid-inaccessible-IO-operations-during-d.patch b/SOURCES/0062-wifi-rtw89-avoid-inaccessible-IO-operations-during-d.patch new file mode 100644 index 0000000..8c4990d --- /dev/null +++ b/SOURCES/0062-wifi-rtw89-avoid-inaccessible-IO-operations-during-d.patch @@ -0,0 +1,95 @@ +From 100a5e9b3f924d1840b8be0134fb0fc7e93a9c1f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:29 +0200 +Subject: [PATCH 062/142] wifi: rtw89: avoid inaccessible IO operations during + doing change_interface() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit ac3a9f1838d8f5e5f9c8b6e2582b65c48a1e7bc1 +Author: Ping-Ke Shih +Date: Thu Nov 17 16:52:35 2022 +0800 + + wifi: rtw89: avoid inaccessible IO operations during doing change_interface() + + During doing change_interface(), hardware is power-off, so some components + are inaccessible and return error. This causes things unexpected, and we + don't have a warning message for that. So, ignore some IO operations in + this situation, and add a warning message to indicate something wrong. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221117085235.53777-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 1 + + drivers/net/wireless/realtek/rtw89/mac.c | 7 +++++++ + drivers/net/wireless/realtek/rtw89/mac80211.c | 11 ++++++++++- + 3 files changed, 18 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 62d834dbff67b..1b0acb1c5450e 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2968,6 +2968,7 @@ enum rtw89_flags { + RTW89_FLAG_CRASH_SIMULATING, + RTW89_FLAG_WOWLAN, + RTW89_FLAG_FORBIDDEN_TRACK_WROK, ++ RTW89_FLAG_CHANGING_INTERFACE, + + NUM_OF_RTW89_FLAGS, + }; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index ecd603a881345..6587cdf6ba624 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3600,6 +3600,13 @@ int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause) + 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; +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +index 6e79bf899901d..ce980d2f22c46 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -174,6 +174,9 @@ static int rtw89_ops_change_interface(struct ieee80211_hw *hw, + 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); +@@ -183,7 +186,13 @@ static int rtw89_ops_change_interface(struct ieee80211_hw *hw, + vif->type = type; + vif->p2p = p2p; + +- return rtw89_ops_add_interface(hw, vif); ++ 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, +-- +2.13.6 + diff --git a/SOURCES/0063-wifi-rtw89-enable-mac80211-virtual-monitor-interface.patch b/SOURCES/0063-wifi-rtw89-enable-mac80211-virtual-monitor-interface.patch new file mode 100644 index 0000000..ca3927d --- /dev/null +++ b/SOURCES/0063-wifi-rtw89-enable-mac80211-virtual-monitor-interface.patch @@ -0,0 +1,65 @@ +From 58994c76089440e2b4b4c24c565fcb6a2fa16ef8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:30 +0200 +Subject: [PATCH 063/142] wifi: rtw89: enable mac80211 virtual monitor + interface +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit cd9b6b3baf5278c73c91e242d41387684fc7f8d8 +Author: Zong-Zhe Yang +Date: Fri Nov 25 15:24:14 2022 +0800 + + wifi: rtw89: enable mac80211 virtual monitor interface + + For running with mac80211 channel context ops and using only as monitor, + we need to enable WANT_MONITOR_VIF to let mac80211 process virtual monitor + interface. Then, we are able to set channel on the monitor from user space. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221125072416.94752-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 2ea38376bd2bb..2db9eb6556565 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -1405,6 +1405,9 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + const u8 *bssid = iter_data->bssid; + ++ if (!vif->bss_conf.bssid) ++ return; ++ + if (ieee80211_is_trigger(hdr->frame_control)) { + rtw89_stats_trigger_frame(rtwdev, vif, skb); + return; +@@ -2386,6 +2389,8 @@ void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc) + rtwvif->self_role = RTW89_SELF_ROLE_CLIENT; + rtwvif->addr_cam.sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL; + break; ++ case NL80211_IFTYPE_MONITOR: ++ break; + default: + WARN_ON(1); + break; +@@ -3269,6 +3274,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) + 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); + + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP) | +-- +2.13.6 + diff --git a/SOURCES/0064-wifi-rtw89-add-HE-radiotap-for-monitor-mode.patch b/SOURCES/0064-wifi-rtw89-add-HE-radiotap-for-monitor-mode.patch new file mode 100644 index 0000000..9347cd8 --- /dev/null +++ b/SOURCES/0064-wifi-rtw89-add-HE-radiotap-for-monitor-mode.patch @@ -0,0 +1,124 @@ +From 77e1e15e7e995bfe5a34df7831f8772e4cd2a178 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:30 +0200 +Subject: [PATCH 064/142] wifi: rtw89: add HE radiotap for monitor mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 51e8ed4e44b5efcf8da2c1f3478e52120a12cdf8 +Author: Ping-Ke Shih +Date: Fri Nov 25 15:24:15 2022 +0800 + + wifi: rtw89: add HE radiotap for monitor mode + + With basic HE radiotap, we can check data rate in sniffer data. To store + the radiotap data, we reserve headroom of aligned 64 bytes, and then + update HE radiotap in monitor mode, so it doesn't affect performance in + normal mode. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221125072416.94752-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 22 ++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/core.h | 18 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/pci.c | 2 +- + 3 files changed, 41 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 2db9eb6556565..3647998014408 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -1480,6 +1480,27 @@ static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status) + rx_status->rate_idx -= 4; + } + ++static void rtw89_core_update_radiotap(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb, ++ struct ieee80211_rx_status *rx_status) ++{ ++ static const struct ieee80211_radiotap_he known_he = { ++ .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | ++ IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN), ++ .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN), ++ }; ++ struct ieee80211_radiotap_he *he; ++ ++ if (!(rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR)) ++ return; ++ ++ if (rx_status->encoding == RX_ENC_HE) { ++ rx_status->flag |= RX_FLAG_RADIOTAP_HE; ++ he = skb_push(skb, sizeof(*he)); ++ *he = known_he; ++ } ++} ++ + 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, +@@ -1494,6 +1515,7 @@ static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev, + + rtw89_core_hw_to_sband_rate(rx_status); + rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu); ++ rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status); + /* In low power mode, it does RX in thread context. */ + local_bh_disable(); + ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, napi); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 1b0acb1c5450e..0be8f7bd3ca2d 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -35,6 +35,7 @@ extern const struct ieee80211_ops rtw89_ops; + #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 RTW89_RADIOTAP_ROOM ALIGN(sizeof(struct ieee80211_radiotap_he), 64) + + #define RTW89_HTC_MASK_VARIANT GENMASK(1, 0) + #define RTW89_HTC_VARIANT_HE 3 +@@ -4383,6 +4384,23 @@ static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev, + 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); ++} ++ + 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, +diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c +index 7aa0af18cdd50..1c4500ba777c6 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.c ++++ b/drivers/net/wireless/realtek/rtw89/pci.c +@@ -267,7 +267,7 @@ static u32 rtw89_pci_rxbd_deliver_skbs(struct rtw89_dev *rtwdev, + + rtw89_core_query_rxdesc(rtwdev, desc_info, skb->data, rxinfo_size); + +- new = dev_alloc_skb(desc_info->pkt_size); ++ new = rtw89_alloc_skb_for_rx(rtwdev, desc_info->pkt_size); + if (!new) + goto err_sync_device; + +-- +2.13.6 + diff --git a/SOURCES/0065-wifi-rtw89-8852b-turn-off-PoP-function-in-monitor-mo.patch b/SOURCES/0065-wifi-rtw89-8852b-turn-off-PoP-function-in-monitor-mo.patch new file mode 100644 index 0000000..2ca6169 --- /dev/null +++ b/SOURCES/0065-wifi-rtw89-8852b-turn-off-PoP-function-in-monitor-mo.patch @@ -0,0 +1,73 @@ +From 3a1164abcbfc5ac67995674982d792986ed70d07 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:30 +0200 +Subject: [PATCH 065/142] wifi: rtw89: 8852b: turn off PoP function in monitor + mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit a215b2b7055f02d8f7666f457d442e77097bb604 +Author: Ping-Ke Shih +Date: Fri Nov 25 15:24:16 2022 +0800 + + wifi: rtw89: 8852b: turn off PoP function in monitor mode + + PoP stands for Packet on Packet that can improve performance in noisy + environment, but it could get RX stuck suddenly. In normal mode, firmware + can help to resolve the stuck, but firmware doesn't work in monitor mode. + Therefore, turn off PoP to avoid RX stuck. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221125072416.94752-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 7 +++++++ + 2 files changed, 9 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index dbe06542f443f..f2634062f377d 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -4236,6 +4236,8 @@ + #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 B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1 BIT(30) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 2d4d572dc601f..b635ac1d1ca2f 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -1411,6 +1411,12 @@ static void rtw8852b_bb_sethw(struct rtw89_dev *rtwdev) + rtw89_phy_read32_mask(rtwdev, R_P1_RPL1, B_P0_RPL1_BIAS_MASK); + } + ++static void rtw8852b_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 void rtw8852b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) + { +@@ -1441,6 +1447,7 @@ static void rtw8852b_set_channel_bb(struct rtw89_dev *rtwdev, const struct rtw89 + rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, + chan->primary_channel); + rtw8852b_5m_mask(rtwdev, chan, phy_idx); ++ rtw8852b_bb_set_pop(rtwdev); + rtw8852b_bb_reset_all(rtwdev, phy_idx); + } + +-- +2.13.6 + diff --git a/SOURCES/0066-wifi-rtw89-rfk-rename-rtw89_mcc_info-to-rtw89_rfk_mc.patch b/SOURCES/0066-wifi-rtw89-rfk-rename-rtw89_mcc_info-to-rtw89_rfk_mc.patch new file mode 100644 index 0000000..9685906 --- /dev/null +++ b/SOURCES/0066-wifi-rtw89-rfk-rename-rtw89_mcc_info-to-rtw89_rfk_mc.patch @@ -0,0 +1,164 @@ +From 667cb1ba6f6d0d5b9fa6de81270f9f60ff8ad71a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:30 +0200 +Subject: [PATCH 066/142] wifi: rtw89: rfk: rename rtw89_mcc_info to + rtw89_rfk_mcc_info +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 38f25dec521edfa289fa0b829676927b13fede91 +Author: Zong-Zhe Yang +Date: Tue Nov 29 16:31:25 2022 +0800 + + wifi: rtw89: rfk: rename rtw89_mcc_info to rtw89_rfk_mcc_info + + The `rtw89_mcc_info mcc` is only for RFK MCC stuffs instead of common + MCC management info. Replace it with `rtw89_rfk_mcc_info rfk_mcc` to + avoid confusion and reserve `struct rtw89_mcc_info mcc` for MCC management + code. + + (No logic changes.) + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221129083130.45708-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 4 ++-- + drivers/net/wireless/realtek/rtw89/fw.c | 10 +++++----- + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 4 ++-- + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 20 ++++++++++---------- + 4 files changed, 19 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 0be8f7bd3ca2d..d0efeeabcb773 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -3032,7 +3032,7 @@ struct rtw89_dack_info { + #define RTW89_IQK_CHS_NR 2 + #define RTW89_IQK_PATH_NR 4 + +-struct rtw89_mcc_info { ++struct rtw89_rfk_mcc_info { + u8 ch[RTW89_IQK_CHS_NR]; + u8 band[RTW89_IQK_CHS_NR]; + u8 table_idx; +@@ -3578,7 +3578,7 @@ struct rtw89_dev { + struct rtw89_dack_info dack; + struct rtw89_iqk_info iqk; + struct rtw89_dpk_info dpk; +- struct rtw89_mcc_info mcc; ++ 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]; +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 2763149586e27..315f5c3a51dfc 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -2263,7 +2263,7 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, + int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) + { + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); +- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; ++ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + struct rtw89_fw_h2c_rf_get_mccch *mccch; + struct sk_buff *skb; + int ret; +@@ -2276,10 +2276,10 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) + skb_put(skb, sizeof(*mccch)); + mccch = (struct rtw89_fw_h2c_rf_get_mccch *)skb->data; + +- mccch->ch_0 = cpu_to_le32(mcc_info->ch[0]); +- mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]); +- mccch->band_0 = cpu_to_le32(mcc_info->band[0]); +- mccch->band_1 = cpu_to_le32(mcc_info->band[1]); ++ mccch->ch_0 = cpu_to_le32(rfk_mcc->ch[0]); ++ mccch->ch_1 = cpu_to_le32(rfk_mcc->ch[1]); ++ mccch->band_0 = cpu_to_le32(rfk_mcc->band[0]); ++ mccch->band_1 = cpu_to_le32(rfk_mcc->band[1]); + mccch->current_channel = cpu_to_le32(chan->channel); + mccch->current_band_type = cpu_to_le32(chan->band_type); + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index 9bc98fd5d4ac2..a87482cc25f58 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -1832,11 +1832,11 @@ static void rtw8852c_set_channel_help(struct rtw89_dev *rtwdev, bool enter, + + static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev) + { +- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; ++ 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(mcc_info, 0, sizeof(*mcc_info)); ++ memset(rfk_mcc, 0, sizeof(*rfk_mcc)); + rtw8852c_lck_init(rtwdev); + + rtw8852c_rck(rtwdev); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +index b0672b906e7bc..60cd676fe22c9 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +@@ -1030,9 +1030,9 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, + + static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) + { +- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; ++ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; +- u8 idx = mcc_info->table_idx; ++ u8 idx = rfk_mcc->table_idx; + bool is_fail1, is_fail2; + u32 val; + u32 core_i; +@@ -1375,10 +1375,10 @@ static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, + + static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) + { +- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; ++ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + u8 idx = 0; + +- idx = mcc_info->table_idx; ++ 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); +@@ -3824,20 +3824,20 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, + void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + { + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); +- struct rtw89_mcc_info *mcc_info = &rtwdev->mcc; +- u8 idx = mcc_info->table_idx; ++ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; ++ u8 idx = rfk_mcc->table_idx; + int i; + + for (i = 0; i < RTW89_IQK_CHS_NR; i++) { +- if (mcc_info->ch[idx] == 0) ++ if (rfk_mcc->ch[idx] == 0) + break; + if (++idx >= RTW89_IQK_CHS_NR) + idx = 0; + } + +- mcc_info->table_idx = idx; +- mcc_info->ch[idx] = chan->channel; +- mcc_info->band[idx] = chan->band_type; ++ rfk_mcc->table_idx = idx; ++ rfk_mcc->ch[idx] = chan->channel; ++ rfk_mcc->band[idx] = chan->band_type; + } + + void rtw8852c_rck(struct rtw89_dev *rtwdev) +-- +2.13.6 + diff --git a/SOURCES/0067-wifi-rtw89-check-if-atomic-before-queuing-c2h.patch b/SOURCES/0067-wifi-rtw89-check-if-atomic-before-queuing-c2h.patch new file mode 100644 index 0000000..e78f3b0 --- /dev/null +++ b/SOURCES/0067-wifi-rtw89-check-if-atomic-before-queuing-c2h.patch @@ -0,0 +1,170 @@ +From 5e16e95dd7bc9379701e4f3c9ca091ca19149c26 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:30 +0200 +Subject: [PATCH 067/142] wifi: rtw89: check if atomic before queuing c2h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 860e8263ae92667a2002163886fd2ebd8c67f699 +Author: Zong-Zhe Yang +Date: Tue Nov 29 16:31:26 2022 +0800 + + wifi: rtw89: check if atomic before queuing c2h + + Before queuing C2H work, we check atomicity of the C2H's handler first now. + If atomic or lock-free, handle it directly; otherwise, handle it with mutex + in work as previous. This prepares for MAC MCC C2Hs which require to be + processed directly. And, their handlers will be functions which can be + considered atomic. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221129083130.45708-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 47 +++++++++++++++++++++++++++++--- + drivers/net/wireless/realtek/rtw89/fw.h | 14 ++++++++++ + drivers/net/wireless/realtek/rtw89/mac.c | 10 +++++++ + drivers/net/wireless/realtek/rtw89/mac.h | 1 + + 4 files changed, 68 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 315f5c3a51dfc..ce71fc1a04a02 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -11,6 +11,9 @@ + #include "phy.h" + #include "reg.h" + ++static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, ++ struct sk_buff *skb); ++ + static struct sk_buff *rtw89_fw_h2c_alloc_skb(struct rtw89_dev *rtwdev, u32 len, + bool header) + { +@@ -2382,8 +2385,43 @@ void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev) + mutex_unlock(&rtwdev->mutex); + } + ++static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h) ++{ ++ struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(c2h); ++ ++ attr->category = RTW89_GET_C2H_CATEGORY(c2h->data); ++ attr->class = RTW89_GET_C2H_CLASS(c2h->data); ++ attr->func = RTW89_GET_C2H_FUNC(c2h->data); ++ attr->len = RTW89_GET_C2H_LEN(c2h->data); ++} ++ ++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, 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); + ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work); + } +@@ -2391,10 +2429,11 @@ void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h) + static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, + struct sk_buff *skb) + { +- u8 category = RTW89_GET_C2H_CATEGORY(skb->data); +- u8 class = RTW89_GET_C2H_CLASS(skb->data); +- u8 func = RTW89_GET_C2H_FUNC(skb->data); +- u16 len = RTW89_GET_C2H_LEN(skb->data); ++ 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)) +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 509a3eac5ffe3..d76d0c80f0256 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -2778,6 +2778,20 @@ static inline void RTW89_SET_FWCMD_TSF32_TOGL_EARLY(void *cmd, u32 val) + #define RTW89_GET_C2H_LEN(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(13, 0)) + ++struct rtw89_fw_c2h_attr { ++ u8 category; ++ u8 class; ++ u8 func; ++ u16 len; ++}; ++ ++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; ++} ++ + #define RTW89_GET_C2H_LOG_SRT_PRT(c2h) (char *)((__le32 *)(c2h) + 2) + #define RTW89_GET_C2H_LOG_LEN(len) ((len) - RTW89_C2H_HEADER_LEN) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 6587cdf6ba624..098637a848953 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -4208,6 +4208,16 @@ void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev, + [RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt, + }; + ++bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func) ++{ ++ switch (class) { ++ default: ++ return false; ++ case RTW89_MAC_C2H_CLASS_MCC: ++ return true; ++ } ++} ++ + void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + u32 len, u8 class, u8 func) + { +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 045e8ec61a41e..82b9e81fe4744 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -894,6 +894,7 @@ static inline int rtw89_chip_disable_bb_rf(struct rtw89_dev *rtwdev) + + 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, 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); +-- +2.13.6 + diff --git a/SOURCES/0068-wifi-rtw89-introduce-helpers-to-wait-complete-on-con.patch b/SOURCES/0068-wifi-rtw89-introduce-helpers-to-wait-complete-on-con.patch new file mode 100644 index 0000000..f19526f --- /dev/null +++ b/SOURCES/0068-wifi-rtw89-introduce-helpers-to-wait-complete-on-con.patch @@ -0,0 +1,156 @@ +From 54cf47d424e54c02da1ac09766a86a09e13be7d9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:30 +0200 +Subject: [PATCH 068/142] wifi: rtw89: introduce helpers to wait/complete on + condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 22b10cdb73921cfb28ccde5ce8b47d7fc434e7c6 +Author: Zong-Zhe Yang +Date: Tue Nov 29 16:31:27 2022 +0800 + + wifi: rtw89: introduce helpers to wait/complete on condition + + MCC (multi-channel concurrency) related H2Cs (host to chip commands) + require to wait for C2H (chip to host events) responses to judge the + execution result and data. We introduce helpers to assist this process. + Besides, we would like the helpers to be generic for use in driver even + outside of MCC H2C/C2H, so we make a independent patch for them. + + In the following, I describe the things first. + ``` + (A) C2H is generated by FW, and then transferred upto driver. Hence, + driver cannot get it immediately without a bit waitting/blocking. + For this, we choose to use wait_for_completion_*() instead of + busy polling. + (B) From the driver management perspective, a scenario, e.g. MCC, + may have mulitple kind of H2C functions requiring this process + to wait for corresponding C2Hs. But, the driver management flow + uses mutex to protect each behavior. So, one scenario triggers + one H2C function at one time. To avoid rampant instances of + struct completion for each H2C function, we choose to use one + struct completion with one condition flag for one scenario. + (C) C2Hs, which H2Cs will be waitting for, cannot be ordered with + driver management flow, i.e. cannot enqueue work to the same + ordered workqueue and cannot lock by the same mutex, to prevent + H2C side from getting no C2H responses. So, those C2Hs are parsed + in interrupt context directly as done in previous commit. + (D) Following (C), the above underline H2Cs and C2Hs will be handled + in different contexts without sync. So, we use atomic_cmpxchg() + to compare and change the condition in atomic. + ``` + + So, we introduce struct rtw89_wait_info which combines struct completion + and atomic_t. Then, the below are the descriptions for helper functions. + * rtw89_wait_for_cond() to wait for a completion based on a condition. + * rtw89_complete_cond() to complete a given condition and carry data. + Each rtw89_wait_info instance independently determines the meaning of + its waitting conditions. But, RTW89_WAIT_COND_IDLE (UINT_MAX) is reserved. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221129083130.45708-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 35 +++++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/core.h | 25 ++++++++++++++++++++++ + 2 files changed, 60 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 3647998014408..4ec3c982ff4e0 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2974,6 +2974,41 @@ void rtw89_core_update_beacon_work(struct work_struct *work) + mutex_unlock(&rtwdev->mutex); + } + ++int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond) ++{ ++ struct completion *cmpl = &wait->completion; ++ unsigned long timeout; ++ unsigned int cur; ++ ++ cur = atomic_cmpxchg(&wait->cond, RTW89_WAIT_COND_IDLE, cond); ++ if (cur != RTW89_WAIT_COND_IDLE) ++ return -EBUSY; ++ ++ timeout = wait_for_completion_timeout(cmpl, RTW89_WAIT_FOR_COND_TIMEOUT); ++ if (timeout == 0) { ++ atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); ++ return -ETIMEDOUT; ++ } ++ ++ if (wait->data.err) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond, ++ const struct rtw89_completion_data *data) ++{ ++ unsigned int cur; ++ ++ cur = atomic_cmpxchg(&wait->cond, cond, RTW89_WAIT_COND_IDLE); ++ if (cur != cond) ++ return; ++ ++ wait->data = *data; ++ complete(&wait->completion); ++} ++ + int rtw89_core_start(struct rtw89_dev *rtwdev) + { + int ret; +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index d0efeeabcb773..a9b9b1c901c18 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2812,6 +2812,28 @@ struct rtw89_mac_info { + u8 cpwm_seq_num; + }; + ++#define RTW89_COMPLETION_BUF_SIZE 24 ++#define RTW89_WAIT_COND_IDLE UINT_MAX ++ ++struct rtw89_completion_data { ++ bool err; ++ u8 buf[RTW89_COMPLETION_BUF_SIZE]; ++}; ++ ++struct rtw89_wait_info { ++ atomic_t cond; ++ struct completion completion; ++ struct rtw89_completion_data data; ++}; ++ ++#define RTW89_WAIT_FOR_COND_TIMEOUT msecs_to_jiffies(100) ++ ++static inline void rtw89_init_wait(struct rtw89_wait_info *wait) ++{ ++ init_completion(&wait->completion); ++ atomic_set(&wait->cond, RTW89_WAIT_COND_IDLE); ++} ++ + enum rtw89_fw_type { + RTW89_FW_NORMAL = 1, + RTW89_FW_WOWLAN = 3, +@@ -4469,6 +4491,9 @@ int rtw89_regd_init(struct rtw89_dev *rtwdev, + void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request); + void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev, + struct rtw89_traffic_stats *stats); ++int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond); ++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 work_struct *work); +-- +2.13.6 + diff --git a/SOURCES/0069-wifi-rtw89-mac-process-MCC-related-C2H.patch b/SOURCES/0069-wifi-rtw89-mac-process-MCC-related-C2H.patch new file mode 100644 index 0000000..fa540d7 --- /dev/null +++ b/SOURCES/0069-wifi-rtw89-mac-process-MCC-related-C2H.patch @@ -0,0 +1,408 @@ +From 604e6fcc512294e76cc6f6f1ad8ca8d5e8c24e8c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:30 +0200 +Subject: [PATCH 069/142] wifi: rtw89: mac: process MCC related C2H +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit ef9dff4cb491210518ad3d249919a0971eff601b +Author: Zong-Zhe Yang +Date: Tue Nov 29 16:31:28 2022 +0800 + + wifi: rtw89: mac: process MCC related C2H + + Process C2H(s) related to MCC (multi-channel concurrency). These handling, + which either call rtw89_complete_cond() or show message in debug mode, can + be considered atomic/lock-free. So, they should be safe to be processed + directly after C2H pre-check in previous patch. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221129083130.45708-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 2 + + drivers/net/wireless/realtek/rtw89/core.h | 5 + + drivers/net/wireless/realtek/rtw89/fw.h | 68 ++++++++++++ + drivers/net/wireless/realtek/rtw89/mac.c | 171 ++++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/mac.h | 34 ++++++ + 5 files changed, 280 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 4ec3c982ff4e0..18b4361505229 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -3132,6 +3132,8 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) + mutex_init(&rtwdev->rf_mutex); + rtwdev->total_sta_assoc = 0; + ++ rtw89_init_wait(&rtwdev->mcc.wait); ++ + INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work); + INIT_WORK(&rtwdev->ips_work, rtw89_ips_work); + skb_queue_head_init(&rtwdev->c2h_queue); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index a9b9b1c901c18..f4603c2ce8f13 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -3547,6 +3547,10 @@ struct rtw89_wow_param { + struct list_head pkt_list; + }; + ++struct rtw89_mcc_info { ++ struct rtw89_wait_info wait; ++}; ++ + struct rtw89_dev { + struct ieee80211_hw *hw; + struct device *dev; +@@ -3557,6 +3561,7 @@ struct rtw89_dev { + const struct rtw89_chip_info *chip; + const struct rtw89_pci_info *pci_info; + struct rtw89_hal hal; ++ struct rtw89_mcc_info mcc; + struct rtw89_mac_info mac; + struct rtw89_fw_info fw; + struct rtw89_hci_info hci; +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index d76d0c80f0256..5fb8faad9c67f 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -2859,6 +2859,55 @@ static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb) + #define RTW89_GET_MAC_C2H_SCANOFLD_BAND(c2h) \ + le32_get_bits(*((const __le32 *)(c2h) + 5), GENMASK(25, 24)) + ++#define RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) ++#define RTW89_GET_MAC_C2H_MCC_RCV_ACK_H2C_FUNC(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) ++ ++#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_GROUP(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) ++#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_RETURN(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 2)) ++#define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) ++ ++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)), GENMASK(7, 0)) ++#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_MACID_Y(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) ++#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_GROUP(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(17, 16)) ++#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_X(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(31, 0)) ++#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_X(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 0)) ++#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_LOW_Y(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h) + 3), GENMASK(31, 0)) ++#define RTW89_GET_MAC_C2H_MCC_TSF_RPT_TSF_HIGH_Y(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) ++ ++#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_STATUS(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(5, 0)) ++#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_GROUP(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(7, 6)) ++#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_MACID(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h)), GENMASK(15, 8)) ++#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_LOW(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h) + 1), GENMASK(31, 0)) ++#define RTW89_GET_MAC_C2H_MCC_STATUS_RPT_TSF_HIGH(c2h) \ ++ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(31, 0)) ++ + #define RTW89_FW_HDR_SIZE 32 + #define RTW89_FW_SECTION_HDR_SIZE 16 + +@@ -2980,6 +3029,25 @@ struct rtw89_fw_h2c_rf_reg_info { + #define H2C_CL_BA_CAM 0xc + #define H2C_FUNC_MAC_BA_CAM 0x0 + ++/* 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)) ++ + #define H2C_CAT_OUTSRC 0x2 + + #define H2C_CL_OUTSRC_RA 0x1 +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 098637a848953..d80050c2e9b30 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -4187,6 +4187,164 @@ rtw89_mac_c2h_tsf32_toggle_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, + { + } + ++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_FW, ++ "invalid MCC C2H RCV ACK: func %d\n", func); ++ return; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "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_FW, ++ "invalid MCC C2H REQ ACK: func %d\n", func); ++ return; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "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); ++ ++ 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_FW, ++ "invalid MCC C2H STS RPT: status %d\n", status); ++ return; ++ } ++ ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "MCC C2H STS RPT: group %d, macid %d, status %d, tsf {%d, %d}\n", ++ group, macid, status, tsf_low, tsf_high); ++ ++ if (!rsp) ++ return; ++ ++ data.err = err; ++ cond = RTW89_MCC_WAIT_COND(group, func); ++ rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); ++} ++ + static + void (* const rtw89_mac_c2h_ofld_handler[])(struct rtw89_dev *rtwdev, + struct sk_buff *c2h, u32 len) = { +@@ -4208,6 +4366,15 @@ void (* const rtw89_mac_c2h_info_handler[])(struct rtw89_dev *rtwdev, + [RTW89_MAC_C2H_FUNC_BCN_CNT] = rtw89_mac_c2h_bcn_cnt, + }; + ++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, ++}; ++ + bool rtw89_mac_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func) + { + switch (class) { +@@ -4233,6 +4400,10 @@ void rtw89_mac_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb, + 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_FWDBG: + return; + default: +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 82b9e81fe4744..adb0c86a98d3e 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -368,6 +368,15 @@ enum rtw89_mac_c2h_info_func { + 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_class { + RTW89_MAC_C2H_CLASS_INFO, + RTW89_MAC_C2H_CLASS_OFLD, +@@ -378,6 +387,31 @@ enum rtw89_mac_c2h_class { + 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, ++}; ++ + struct rtw89_mac_ax_coex { + #define RTW89_MAC_AX_COEX_RTK_MODE 0 + #define RTW89_MAC_AX_COEX_CSR_MODE 1 +-- +2.13.6 + diff --git a/SOURCES/0070-wifi-rtw89-fw-implement-MCC-related-H2C.patch b/SOURCES/0070-wifi-rtw89-fw-implement-MCC-related-H2C.patch new file mode 100644 index 0000000..0a799cc --- /dev/null +++ b/SOURCES/0070-wifi-rtw89-fw-implement-MCC-related-H2C.patch @@ -0,0 +1,761 @@ +From c52fb5f9e8d95773c3aba11af16d1e198a54ad6b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:31 +0200 +Subject: [PATCH 070/142] wifi: rtw89: fw: implement MCC related H2C +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit c008c4b011baa26b9545f7be10e746c97409d45b +Author: Zong-Zhe Yang +Date: Tue Nov 29 16:31:29 2022 +0800 + + wifi: rtw89: fw: implement MCC related H2C + + These MCC H2C(s) require to wait for MCC C2H to determine if the + execution is successful. Through rtw89_wait_for_cond(), we make + them wait for either a completion with data from MCC C2H handlers, + which calls rtw89_complete_cond(), or timeout. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221129083130.45708-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 329 ++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/fw.h | 369 +++++++++++++++++++++++++++++++- + 2 files changed, 697 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index ce71fc1a04a02..cc8efd4ea57f8 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -3265,3 +3265,332 @@ int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, + + return ret; + } ++ ++static int rtw89_h2c_tx_and_wait(struct rtw89_dev *rtwdev, struct sk_buff *skb, ++ struct rtw89_wait_info *wait, unsigned int cond) ++{ ++ int ret; ++ ++ 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 rtw89_wait_for_cond(wait, cond); ++} ++ ++#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_bitamp(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); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 5fb8faad9c67f..46d57414f24e2 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -2767,6 +2767,355 @@ 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)); ++} ++ ++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)); ++} ++ + #define RTW89_C2H_HEADER_LEN 8 + + #define RTW89_GET_C2H_CATEGORY(c2h) \ +@@ -3185,9 +3534,27 @@ int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + bool enable); + int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, bool enable); +- + int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev, + struct rtw89_wow_cam_info *cam_info); ++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_bitamp(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); ++ + static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) + { + const struct rtw89_chip_info *chip = rtwdev->chip; +-- +2.13.6 + diff --git a/SOURCES/0071-wifi-rtw89-link-rtw89_vif-and-chanctx-stuffs.patch b/SOURCES/0071-wifi-rtw89-link-rtw89_vif-and-chanctx-stuffs.patch new file mode 100644 index 0000000..4b284b2 --- /dev/null +++ b/SOURCES/0071-wifi-rtw89-link-rtw89_vif-and-chanctx-stuffs.patch @@ -0,0 +1,215 @@ +From 6966dfe9d6fbe635c89a6ec969de064eac15e60e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:31 +0200 +Subject: [PATCH 071/142] wifi: rtw89: link rtw89_vif and chanctx stuffs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 75ee07b03fc6ec0a7ac7407f9ea7b3e981efb28f +Author: Zong-Zhe Yang +Date: Tue Nov 29 16:31:30 2022 +0800 + + wifi: rtw89: link rtw89_vif and chanctx stuffs + + First, introduce struct rtw89_sub_entity for chanctx related stuffs. + Second, add enum rtw89_sub_entity_idx to rtw89_vif for vif operation + to access its/right chanctx stuffs after future multi-channel support. + + Besides, RTW89_SUB_ENTITY_0 is the default chanctx entry throughout + driver, i.e. it's used for things which may not have a target chanctx + yet. So, we need to ensure that RTW89_SUB_ENTITY_0 is always working. + If there is at least one alive chanctx, then one of them must take + RTW89_SUB_ENTITY_0. If no alive chanctx, RTW89_SUB_ENTITY_0 will be + filled by rtw89_config_default_chandef(). + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221129083130.45708-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/chan.c | 40 ++++++++++++++++++++++++--- + drivers/net/wireless/realtek/rtw89/core.h | 20 +++++++++----- + drivers/net/wireless/realtek/rtw89/mac80211.c | 1 + + 3 files changed, 50 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c +index a4f61c2f65123..90596806bc93f 100644 +--- a/drivers/net/wireless/realtek/rtw89/chan.c ++++ b/drivers/net/wireless/realtek/rtw89/chan.c +@@ -4,6 +4,7 @@ + + #include "chan.h" + #include "debug.h" ++#include "util.h" + + static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band, + u8 center_chan) +@@ -108,8 +109,8 @@ bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev, + const struct rtw89_chan *new) + { + struct rtw89_hal *hal = &rtwdev->hal; +- struct rtw89_chan *chan = &hal->chan[idx]; +- struct rtw89_chan_rcd *rcd = &hal->chan_rcd[idx]; ++ struct rtw89_chan *chan = &hal->sub[idx].chan; ++ struct rtw89_chan_rcd *rcd = &hal->sub[idx].rcd; + bool band_changed; + + rcd->prev_primary_channel = chan->primary_channel; +@@ -127,7 +128,7 @@ static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev, + { + struct rtw89_hal *hal = &rtwdev->hal; + +- hal->chandef[idx] = *chandef; ++ hal->sub[idx].chandef = *chandef; + + if (from_stack) + set_bit(idx, hal->entity_map); +@@ -195,6 +196,7 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev, + rtw89_config_entity_chandef(rtwdev, idx, &ctx->def); + rtw89_set_channel(rtwdev); + cfg->idx = idx; ++ hal->sub[idx].cfg = cfg; + return 0; + } + +@@ -203,8 +205,34 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev, + { + struct rtw89_hal *hal = &rtwdev->hal; + struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; ++ struct rtw89_vif *rtwvif; ++ u8 drop, roll; + +- clear_bit(cfg->idx, hal->entity_map); ++ drop = cfg->idx; ++ if (drop != RTW89_SUB_ENTITY_0) ++ goto out; ++ ++ roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY, drop + 1); ++ ++ /* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */ ++ if (roll == NUM_OF_RTW89_SUB_ENTITY) ++ goto out; ++ ++ /* RTW89_SUB_ENTITY_0 is going to release, and another exists. ++ * Make another roll down to RTW89_SUB_ENTITY_0 to replace. ++ */ ++ hal->sub[roll].cfg->idx = RTW89_SUB_ENTITY_0; ++ hal->sub[RTW89_SUB_ENTITY_0] = hal->sub[roll]; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) { ++ if (rtwvif->sub_entity_idx == roll) ++ rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; ++ } ++ ++ drop = roll; ++ ++out: ++ clear_bit(drop, hal->entity_map); + rtw89_set_channel(rtwdev); + } + +@@ -225,6 +253,9 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct ieee80211_chanctx_conf *ctx) + { ++ struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv; ++ ++ rtwvif->sub_entity_idx = cfg->idx; + return 0; + } + +@@ -232,4 +263,5 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct ieee80211_chanctx_conf *ctx) + { ++ rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; + } +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index f4603c2ce8f13..2badb96d2ae35 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2240,6 +2240,8 @@ struct rtw89_phy_rate_pattern { + struct rtw89_vif { + struct list_head list; + struct rtw89_dev *rtwdev; ++ enum rtw89_sub_entity_idx sub_entity_idx; ++ + u8 mac_id; + u8 port; + u8 mac_addr[ETH_ALEN]; +@@ -2953,6 +2955,13 @@ enum rtw89_entity_mode { + RTW89_ENTITY_MODE_SCC, + }; + ++struct rtw89_sub_entity { ++ struct cfg80211_chan_def chandef; ++ struct rtw89_chan chan; ++ struct rtw89_chan_rcd rcd; ++ struct rtw89_chanctx_cfg *cfg; ++}; ++ + struct rtw89_hal { + u32 rx_fltr; + u8 cv; +@@ -2966,13 +2975,10 @@ struct rtw89_hal { + bool support_igi; + + DECLARE_BITMAP(entity_map, NUM_OF_RTW89_SUB_ENTITY); +- struct cfg80211_chan_def chandef[NUM_OF_RTW89_SUB_ENTITY]; ++ struct rtw89_sub_entity sub[NUM_OF_RTW89_SUB_ENTITY]; + + bool entity_active; + enum rtw89_entity_mode entity_mode; +- +- struct rtw89_chan chan[NUM_OF_RTW89_SUB_ENTITY]; +- struct rtw89_chan_rcd chan_rcd[NUM_OF_RTW89_SUB_ENTITY]; + }; + + #define RTW89_MAX_MAC_ID_NUM 128 +@@ -4138,7 +4144,7 @@ const struct cfg80211_chan_def *rtw89_chandef_get(struct rtw89_dev *rtwdev, + { + struct rtw89_hal *hal = &rtwdev->hal; + +- return &hal->chandef[idx]; ++ return &hal->sub[idx].chandef; + } + + static inline +@@ -4147,7 +4153,7 @@ const struct rtw89_chan *rtw89_chan_get(struct rtw89_dev *rtwdev, + { + struct rtw89_hal *hal = &rtwdev->hal; + +- return &hal->chan[idx]; ++ return &hal->sub[idx].chan; + } + + static inline +@@ -4156,7 +4162,7 @@ const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev, + { + struct rtw89_hal *hal = &rtwdev->hal; + +- return &hal->chan_rcd[idx]; ++ return &hal->sub[idx].rcd; + } + + static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev) +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +index ce980d2f22c46..1a99267d710d4 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -131,6 +131,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, + rtwvif->bcn_hit_cond = 0; + rtwvif->mac_idx = RTW89_MAC_0; + rtwvif->phy_idx = RTW89_PHY_0; ++ rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; + rtwvif->hit_rule = 0; + ether_addr_copy(rtwvif->mac_addr, vif->addr); + +-- +2.13.6 + diff --git a/SOURCES/0072-wifi-rtw89-don-t-request-partial-firmware-if-SECURIT.patch b/SOURCES/0072-wifi-rtw89-don-t-request-partial-firmware-if-SECURIT.patch new file mode 100644 index 0000000..f5cf65a --- /dev/null +++ b/SOURCES/0072-wifi-rtw89-don-t-request-partial-firmware-if-SECURIT.patch @@ -0,0 +1,139 @@ +From 0309d8097defcf106e57a2d235dae23de664a81e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:31 +0200 +Subject: [PATCH 072/142] wifi: rtw89: don't request partial firmware if + SECURITY_LOADPIN_ENFORCE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3ddfe3bdd3cf199676737fbd8cb7878b962acd2a +Author: Zong-Zhe Yang +Date: Fri Dec 2 14:05:20 2022 +0800 + + wifi: rtw89: don't request partial firmware if SECURITY_LOADPIN_ENFORCE + + Kernel logs on platform enabling SECURITY_LOADPIN_ENFORCE + ------ + ``` + LoadPin: firmware old-api-denied obj= pid=810 cmdline="modprobe -q -- rtw89_8852ce" + rtw89_8852ce 0000:01:00.0: loading /lib/firmware/rtw89/rtw8852c_fw.bin failed with error -1 + rtw89_8852ce 0000:01:00.0: Direct firmware load for rtw89/rtw8852c_fw.bin failed with error -1 + rtw89_8852ce 0000:01:00.0: failed to early request firmware: -1 + ``` + + Trace + ------ + ``` + request_partial_firmware_into_buf() + > _request_firmware() + >> fw_get_filesystem_firmware() + >>> kernel_read_file_from_path_initns() + >>>> kernel_read_file() + >>>>> security_kernel_read_file() + // It will iterate enabled LSMs' hooks for kernel_read_file. + // With loadpin, it hooks loadpin_read_file. + ``` + + If SECURITY_LOADPIN_ENFORCE is enabled, doing kernel_read_file() on partial + files will be denied and return -EPERM (-1). Then, the outer API based on it, + e.g. request_partial_firmware_into_buf(), will get the error. + + In the case, we cannot get the firmware stuffs right, even though there might + be no error other than a permission issue on reading a partial file. So we have + to request full firmware if SECURITY_LOADPIN_ENFORCE is enabled. It makes us + still have a chance to do early firmware work on this kind of platforms. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221202060521.501512-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 30 +++++++++++++++++++++--------- + drivers/net/wireless/realtek/rtw89/fw.h | 15 +++++++++++++++ + 2 files changed, 36 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index cc8efd4ea57f8..e81aac935721a 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -277,25 +277,37 @@ void rtw89_early_fw_feature_recognize(struct device *device, + const struct rtw89_chip_info *chip, + u32 *early_feat_map) + { +- union { +- struct rtw89_mfw_hdr mfw_hdr; +- u8 fw_hdr[RTW89_FW_HDR_SIZE]; +- } buf = {}; ++ union rtw89_compat_fw_hdr buf = {}; + const struct firmware *firmware; ++ bool full_req = false; + u32 ver_code; + int ret; + int i; + +- ret = request_partial_firmware_into_buf(&firmware, chip->fw_name, +- device, &buf, sizeof(buf), 0); ++ /* If SECURITY_LOADPIN_ENFORCE is enabled, reading partial files will ++ * be denied (-EPERM). Then, we don't get right firmware things as ++ * expected. So, in this case, we have to request full firmware here. ++ */ ++ if (IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE)) ++ full_req = true; ++ ++ if (full_req) ++ ret = request_firmware(&firmware, chip->fw_name, device); ++ else ++ ret = request_partial_firmware_into_buf(&firmware, chip->fw_name, ++ device, &buf, sizeof(buf), ++ 0); ++ + if (ret) { + dev_err(device, "failed to early request firmware: %d\n", ret); + return; + } + +- ver_code = buf.mfw_hdr.sig != RTW89_MFW_SIG ? +- RTW89_FW_HDR_VER_CODE(&buf.fw_hdr) : +- RTW89_MFW_HDR_VER_CODE(&buf.mfw_hdr); ++ if (full_req) ++ ver_code = rtw89_compat_fw_hdr_ver_code(firmware->data); ++ else ++ ver_code = rtw89_compat_fw_hdr_ver_code(&buf); ++ + if (!ver_code) + goto out; + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 46d57414f24e2..5c4c7de1b4f5d 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -3291,6 +3291,21 @@ struct fwcmd_hdr { + __le32 hdr1; + }; + ++union rtw89_compat_fw_hdr { ++ struct rtw89_mfw_hdr mfw_hdr; ++ u8 fw_hdr[RTW89_FW_HDR_SIZE]; ++}; ++ ++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); ++} ++ + #define RTW89_H2C_RF_PAGE_SIZE 500 + #define RTW89_H2C_RF_PAGE_NUM 3 + struct rtw89_fw_h2c_rf_reg_info { +-- +2.13.6 + diff --git a/SOURCES/0073-wifi-rtw89-request-full-firmware-only-once-if-it-s-e.patch b/SOURCES/0073-wifi-rtw89-request-full-firmware-only-once-if-it-s-e.patch new file mode 100644 index 0000000..16c472f --- /dev/null +++ b/SOURCES/0073-wifi-rtw89-request-full-firmware-only-once-if-it-s-e.patch @@ -0,0 +1,181 @@ +From 77ea9f18933b7c4dac76e658206be0153796566c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:31 +0200 +Subject: [PATCH 073/142] wifi: rtw89: request full firmware only once if it's + early requested +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 13eb07e0be1b95f1e1fab721fb0f38117edfe80b +Author: Zong-Zhe Yang +Date: Fri Dec 2 14:05:21 2022 +0800 + + wifi: rtw89: request full firmware only once if it's early requested + + Under some condition, we now have to do early request full firmware when + rtw89_early_fw_feature_recognize(). In this case, we can avoid requesting + full firmware twice during probing driver. So, we pass out full firmware + from rtw89_early_fw_feature_recognize() if it's requested successfully. + And then, if firmware is settled, we have no need to request full firmware + again during normal initizating flow. + + Setting firmware flow is updated to be as the following. + + platform | early recognizing | normally initizating + ----------------------------------------------------------------------- + deny reading | request full FW | (no more FW requesting) + partial file | | (obtain FW from early pahse) + ----------------------------------------------------------------------- + able to read | request partial FW | async request full FW + partial file | (quite small chunk) | + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221202060521.501512-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 6 +++++- + drivers/net/wireless/realtek/rtw89/fw.c | 28 +++++++++++++++++++++++----- + drivers/net/wireless/realtek/rtw89/fw.h | 7 ++++--- + 3 files changed, 32 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 18b4361505229..e99eccf11c762 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -3423,6 +3423,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, + u32 bus_data_size, + const struct rtw89_chip_info *chip) + { ++ const struct firmware *firmware; + struct ieee80211_hw *hw; + struct rtw89_dev *rtwdev; + struct ieee80211_ops *ops; +@@ -3430,7 +3431,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, + u32 early_feat_map = 0; + bool no_chanctx; + +- rtw89_early_fw_feature_recognize(device, chip, &early_feat_map); ++ firmware = rtw89_early_fw_feature_recognize(device, chip, &early_feat_map); + + ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL); + if (!ops) +@@ -3457,6 +3458,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, + rtwdev->dev = device; + rtwdev->ops = ops; + rtwdev->chip = chip; ++ rtwdev->fw.firmware = firmware; + + rtw89_debug(rtwdev, RTW89_DBG_FW, "probe driver %s chanctx\n", + no_chanctx ? "without" : "with"); +@@ -3465,6 +3467,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, + + err: + kfree(ops); ++ release_firmware(firmware); + return NULL; + } + EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw); +@@ -3472,6 +3475,7 @@ EXPORT_SYMBOL(rtw89_alloc_ieee80211_hw); + void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev) + { + kfree(rtwdev->ops); ++ release_firmware(rtwdev->fw.firmware); + ieee80211_free_hw(rtwdev->hw); + } + EXPORT_SYMBOL(rtw89_free_ieee80211_hw); +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index e81aac935721a..3b7af8faca505 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -273,9 +273,10 @@ static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) + } + } + +-void rtw89_early_fw_feature_recognize(struct device *device, +- const struct rtw89_chip_info *chip, +- u32 *early_feat_map) ++const struct firmware * ++rtw89_early_fw_feature_recognize(struct device *device, ++ const struct rtw89_chip_info *chip, ++ u32 *early_feat_map) + { + union rtw89_compat_fw_hdr buf = {}; + const struct firmware *firmware; +@@ -300,7 +301,7 @@ void rtw89_early_fw_feature_recognize(struct device *device, + + if (ret) { + dev_err(device, "failed to early request firmware: %d\n", ret); +- return; ++ return NULL; + } + + if (full_req) +@@ -322,7 +323,11 @@ void rtw89_early_fw_feature_recognize(struct device *device, + } + + out: ++ if (full_req) ++ return firmware; ++ + release_firmware(firmware); ++ return NULL; + } + + int rtw89_fw_recognize(struct rtw89_dev *rtwdev) +@@ -629,6 +634,13 @@ int rtw89_load_firmware(struct rtw89_dev *rtwdev) + fw->rtwdev = rtwdev; + init_completion(&fw->completion); + ++ if (fw->firmware) { ++ rtw89_debug(rtwdev, RTW89_DBG_FW, ++ "full firmware has been early requested\n"); ++ complete_all(&fw->completion); ++ return 0; ++ } ++ + ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, + GFP_KERNEL, fw, rtw89_load_firmware_cb); + if (ret) { +@@ -645,8 +657,14 @@ void rtw89_unload_firmware(struct rtw89_dev *rtwdev) + + rtw89_wait_firmware_completion(rtwdev); + +- if (fw->firmware) ++ if (fw->firmware) { + release_firmware(fw->firmware); ++ ++ /* assign NULL back in case rtw89_free_ieee80211_hw() ++ * try to release the same one again. ++ */ ++ fw->firmware = NULL; ++ } + } + + #define H2C_CAM_LEN 60 +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 5c4c7de1b4f5d..4d2f9ea9e0022 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -3444,9 +3444,10 @@ struct rtw89_fw_h2c_rf_get_mccch { + + int rtw89_fw_check_rdy(struct rtw89_dev *rtwdev); + int rtw89_fw_recognize(struct rtw89_dev *rtwdev); +-void rtw89_early_fw_feature_recognize(struct device *device, +- const struct rtw89_chip_info *chip, +- u32 *early_feat_map); ++const struct firmware * ++rtw89_early_fw_feature_recognize(struct device *device, ++ const struct rtw89_chip_info *chip, ++ u32 *early_feat_map); + int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type); + int rtw89_load_firmware(struct rtw89_dev *rtwdev); + void rtw89_unload_firmware(struct rtw89_dev *rtwdev); +-- +2.13.6 + diff --git a/SOURCES/0074-wifi-rtw89-add-mac-TSF-sync-function.patch b/SOURCES/0074-wifi-rtw89-add-mac-TSF-sync-function.patch new file mode 100644 index 0000000..1112011 --- /dev/null +++ b/SOURCES/0074-wifi-rtw89-add-mac-TSF-sync-function.patch @@ -0,0 +1,139 @@ +From b0fabf2886facde82214f4cc791db13b9020f242 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:31 +0200 +Subject: [PATCH 074/142] wifi: rtw89: add mac TSF sync function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit fb2b8cec81d75b2b20bdbc2fca7a60a68bc78aac +Author: Po-Hao Huang +Date: Fri Dec 2 14:15:24 2022 +0800 + + wifi: rtw89: add mac TSF sync function + + If the interface is in AP/P2P GO mode, we adjust the TSF with random + offset to avoid TBTT of different vifs to overlap and collide. + For every new interface added, we adjust the value and resync for all + interfaces. + + Signed-off-by: Po-Hao Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221202061527.505668-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 44 ++++++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ + drivers/net/wireless/realtek/rtw89/reg.h | 17 ++++++++++++ + 3 files changed, 63 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index d80050c2e9b30..a80690d0bf485 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3913,6 +3913,49 @@ static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev, + B_AX_TBTT_SHIFT_OFST_MASK, val); + } + ++static void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ struct rtw89_vif *rtwvif_src, u8 offset, ++ int *n_offset) ++{ ++ u32 val, reg; ++ ++ if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src) ++ return; ++ ++ /* adjust offset randomly to avoid beacon conflict */ ++ offset = offset - offset / 4 + get_random_u32() % (offset / 2); ++ val = RTW89_PORT_OFFSET_MS_TO_32US((*n_offset)++, offset); ++ reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, ++ rtwvif->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_resync_all(struct rtw89_dev *rtwdev) ++{ ++ struct rtw89_vif *src = NULL, *tmp; ++ u8 offset = 100, vif_aps = 0; ++ int n_offset = 1; ++ ++ rtw89_for_each_rtwvif(rtwdev, tmp) { ++ 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, tmp) ++ rtw89_mac_port_tsf_sync(rtwdev, tmp, src, offset, &n_offset); ++} ++ + int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + { + int ret; +@@ -3991,6 +4034,7 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif); + rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif); + rtw89_mac_port_cfg_func_en(rtwdev, rtwvif); ++ rtw89_mac_port_tsf_resync_all(rtwdev); + fsleep(BCN_ERLY_SET_DLY); + rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif); + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index adb0c86a98d3e..766ca6934d33a 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -168,6 +168,8 @@ enum rtw89_mac_ax_l0_to_l1_event { + MAC_AX_L0_TO_L1_EVENT_MAX = 15, + }; + ++#define RTW89_PORT_OFFSET_MS_TO_32US(n, shift_ms) ((n) * (shift_ms) * 1000 / 32) ++ + enum rtw89_mac_dbg_port_sel { + /* CMAC 0 related */ + RTW89_DBG_PORT_SEL_PTCL_C0 = 0, +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index f2634062f377d..5324e645728bb 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -2048,6 +2048,23 @@ + #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 +-- +2.13.6 + diff --git a/SOURCES/0075-wifi-rtw89-stop-mac-port-function-when-stop_ap.patch b/SOURCES/0075-wifi-rtw89-stop-mac-port-function-when-stop_ap.patch new file mode 100644 index 0000000..494b6eb --- /dev/null +++ b/SOURCES/0075-wifi-rtw89-stop-mac-port-function-when-stop_ap.patch @@ -0,0 +1,102 @@ +From 217bcd1810fc615699c139a8e771c909ecc6f530 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:31 +0200 +Subject: [PATCH 075/142] wifi: rtw89: stop mac port function when stop_ap() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit d592b9f742643f07db53ac34baf6bbd3ce9478dc +Author: Po-Hao Huang +Date: Fri Dec 2 14:15:25 2022 +0800 + + wifi: rtw89: stop mac port function when stop_ap() + + Disable hardware beacon related functions when ap stops. So hardware won't + transmit beacons while interface is already removed. + + Signed-off-by: Po-Hao Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221202061527.505668-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 16 +++++++++++++--- + drivers/net/wireless/realtek/rtw89/mac.h | 1 + + drivers/net/wireless/realtek/rtw89/mac80211.c | 1 + + 3 files changed, 15 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index a80690d0bf485..12cbf41590bbe 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3877,11 +3877,16 @@ static void rtw89_mac_port_cfg_hiq_drop(struct rtw89_dev *rtwdev, + } + + static void rtw89_mac_port_cfg_func_en(struct rtw89_dev *rtwdev, +- struct rtw89_vif *rtwvif) ++ struct rtw89_vif *rtwvif, bool enable) + { + const struct rtw89_port_reg *p = &rtw_port_base; + +- rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_PORT_FUNC_EN); ++ if (enable) ++ rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, ++ B_AX_PORT_FUNC_EN); ++ else ++ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, ++ B_AX_PORT_FUNC_EN); + } + + static void rtw89_mac_port_cfg_bcn_early(struct rtw89_dev *rtwdev, +@@ -4033,7 +4038,7 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + rtw89_mac_port_cfg_tbtt_shift(rtwdev, rtwvif); + rtw89_mac_port_cfg_bss_color(rtwdev, rtwvif); + rtw89_mac_port_cfg_mbssid(rtwdev, rtwvif); +- rtw89_mac_port_cfg_func_en(rtwdev, rtwvif); ++ rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, true); + rtw89_mac_port_tsf_resync_all(rtwdev); + fsleep(BCN_ERLY_SET_DLY); + rtw89_mac_port_cfg_bcn_early(rtwdev, rtwvif); +@@ -4085,6 +4090,11 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + rtw89_write32_set(rtwdev, reg, B_AX_RXTRIG_RU26_DIS); + } + ++void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ++{ ++ rtw89_mac_port_cfg_func_en(rtwdev, rtwvif, false); ++} ++ + int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + { + int ret; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 766ca6934d33a..f0b684b205f10 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -908,6 +908,7 @@ int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); + int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); + void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif); ++void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); + int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); + void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev); + int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw); +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +index 1a99267d710d4..0c86d416b7ad2 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -454,6 +454,7 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + + mutex_lock(&rtwdev->mutex); ++ rtw89_mac_stop_ap(rtwdev, rtwvif); + rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, NULL); + rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true); + mutex_unlock(&rtwdev->mutex); +-- +2.13.6 + diff --git a/SOURCES/0076-wifi-rtw89-fix-unsuccessful-interface_add-flow.patch b/SOURCES/0076-wifi-rtw89-fix-unsuccessful-interface_add-flow.patch new file mode 100644 index 0000000..61afc02 --- /dev/null +++ b/SOURCES/0076-wifi-rtw89-fix-unsuccessful-interface_add-flow.patch @@ -0,0 +1,52 @@ +From dc93a468c0aed51fde75346bbffc07f5ce74ee2a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:32 +0200 +Subject: [PATCH 076/142] wifi: rtw89: fix unsuccessful interface_add flow +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 8fc5d4338620b81b1b265c725b38aced8acf8d72 +Author: Po-Hao Huang +Date: Fri Dec 2 14:15:26 2022 +0800 + + wifi: rtw89: fix unsuccessful interface_add flow + + Remove according vifs from list if we couldn't set this interface up. + Otherwise the rtwvif_list could contain unreferenced objects. + + Signed-off-by: Po-Hao Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221202061527.505668-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac80211.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +index 0c86d416b7ad2..f9b95c52916bb 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -125,6 +125,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, + RTW89_PORT_NUM); + if (rtwvif->port == RTW89_PORT_NUM) { + ret = -ENOSPC; ++ list_del_init(&rtwvif->list); + goto out; + } + +@@ -138,6 +139,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, + ret = rtw89_mac_add_vif(rtwdev, rtwvif); + if (ret) { + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); ++ list_del_init(&rtwvif->list); + goto out; + } + +-- +2.13.6 + diff --git a/SOURCES/0077-wifi-rtw89-add-join-info-upon-create-interface.patch b/SOURCES/0077-wifi-rtw89-add-join-info-upon-create-interface.patch new file mode 100644 index 0000000..aea9a1d --- /dev/null +++ b/SOURCES/0077-wifi-rtw89-add-join-info-upon-create-interface.patch @@ -0,0 +1,47 @@ +From 8f22795cdfed6df6fa0533e3c2042533e63e46da Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:32 +0200 +Subject: [PATCH 077/142] wifi: rtw89: add join info upon create interface +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit a0e78d5c6082fc953fef5af7293be0145c67dba4 +Author: Po-Hao Huang +Date: Fri Dec 2 14:15:27 2022 +0800 + + wifi: rtw89: add join info upon create interface + + To support multiple vifs, fw need more information of each role. + Send this info to make things work as expected. + + Signed-off-by: Po-Hao Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221202061527.505668-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 12cbf41590bbe..cf9a0a3120a79 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3980,6 +3980,10 @@ int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + if (ret) + return ret; + ++ ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true); ++ if (ret) ++ return ret; ++ + ret = rtw89_cam_init(rtwdev, rtwvif); + if (ret) + return ret; +-- +2.13.6 + diff --git a/SOURCES/0078-wifi-rtw89-consider-ER-SU-as-a-TX-capability.patch b/SOURCES/0078-wifi-rtw89-consider-ER-SU-as-a-TX-capability.patch new file mode 100644 index 0000000..a81feea --- /dev/null +++ b/SOURCES/0078-wifi-rtw89-consider-ER-SU-as-a-TX-capability.patch @@ -0,0 +1,128 @@ +From fd4c8ece088984b50f2a64424be974cb4af96441 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:32 +0200 +Subject: [PATCH 078/142] wifi: rtw89: consider ER SU as a TX capability +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 25ed1a172298eed1cab329792d8e4d7363a411fc +Author: Ping-Ke Shih +Date: Fri Dec 9 09:21:10 2022 +0800 + + wifi: rtw89: consider ER SU as a TX capability + + ER (Extended Range) SU is to have a larger coverage. We set this as a RA + capability, and then firmware can choose ER SU to transmit packets to + reception at cell edge. For 8852C, it needs to fill this capability in + TXWD, so update rtw89_build_txwd_info0_v1(). + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221209012110.7242-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 13 ++++++++++++- + drivers/net/wireless/realtek/rtw89/core.h | 2 ++ + drivers/net/wireless/realtek/rtw89/phy.c | 1 + + drivers/net/wireless/realtek/rtw89/txrx.h | 2 ++ + 4 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index e99eccf11c762..2e4ba8e42d392 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -689,7 +689,9 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) + { + struct ieee80211_vif *vif = tx_req->vif; ++ struct ieee80211_sta *sta = tx_req->sta; + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); + struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; +@@ -707,6 +709,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, + desc_info->qsel = qsel; + desc_info->mac_id = rtw89_core_tx_get_mac_id(rtwdev, tx_req); + desc_info->port = desc_info->hiq ? rtwvif->port : 0; ++ desc_info->er_cap = rtwsta ? rtwsta->er_cap : false; + + /* enable wd_info for AMPDU */ + desc_info->en_wd_info = true; +@@ -1006,7 +1009,9 @@ static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) + static __le32 rtw89_build_txwd_info0_v1(struct rtw89_tx_desc_info *desc_info) + { + u32 dword = 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_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); + } +@@ -2585,6 +2590,12 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, + rtw89_mac_bf_monitor_calc(rtwdev, sta, false); + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { ++ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; ++ ++ if (bss_conf->he_support && ++ !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE)) ++ rtwsta->er_cap = true; ++ + rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, + BTC_ROLE_MSTS_STA_CONN_END); + rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 2badb96d2ae35..800ede1d69c75 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -816,6 +816,7 @@ struct rtw89_tx_desc_info { + #define RTW89_MGMT_HW_SEQ_MODE 1 + bool hiq; + u8 port; ++ bool er_cap; + }; + + struct rtw89_core_tx_request { +@@ -2194,6 +2195,7 @@ struct rtw89_sec_cam_entry { + struct rtw89_sta { + u8 mac_id; + bool disassoc; ++ bool er_cap; + struct rtw89_dev *rtwdev; + struct rtw89_vif *rtwvif; + struct rtw89_ra_info ra; +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index 017710c580c72..5dc617a0a47a7 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -367,6 +367,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, + } + + ra->bw_cap = bw_mode; ++ ra->er_cap = rtwsta->er_cap; + ra->mode_ctrl = mode; + ra->macid = rtwsta->mac_id; + ra->stbc_cap = stbc_en; +diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h +index 9d4c6b6fa1250..98eb9607cd218 100644 +--- a/drivers/net/wireless/realtek/rtw89/txrx.h ++++ b/drivers/net/wireless/realtek/rtw89/txrx.h +@@ -75,7 +75,9 @@ + #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_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 */ +-- +2.13.6 + diff --git a/SOURCES/0079-wifi-rtw89-fw-adapt-to-new-firmware-format-of-securi.patch b/SOURCES/0079-wifi-rtw89-fw-adapt-to-new-firmware-format-of-securi.patch new file mode 100644 index 0000000..db067cc --- /dev/null +++ b/SOURCES/0079-wifi-rtw89-fw-adapt-to-new-firmware-format-of-securi.patch @@ -0,0 +1,116 @@ +From 01cfb2843b75edc4f1589ecad4275590fa011446 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:32 +0200 +Subject: [PATCH 079/142] wifi: rtw89: fw: adapt to new firmware format of + security section +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 18ddf102d4b8768cd058105168f29f96cd0c6d2d +Author: Ping-Ke Shih +Date: Fri Dec 9 09:22:15 2022 +0800 + + wifi: rtw89: fw: adapt to new firmware format of security section + + Normally, system image should ensure firmware integrity, but we provide + an advance feature to ensure this by security section along with firmware. + To enable this feature, custom ID is programmed into efuse, and driver + will download proper security section to firmware. + + Since I don't have this kind hardware modules on hand yet, but new format + is used by newer firmware. Therefore, I prepare this patch in advance to + consider size of security section as a factor of checking rule of firmware + size, but don't actually download security section to firmware. + + This patch is backward compatible, so it will be safe to have this change + before adding an new format firmware to linux-firmware repository. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221209012215.7342-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 11 ++++++++++- + drivers/net/wireless/realtek/rtw89/fw.h | 13 +++++++++++-- + 2 files changed, 21 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 3b7af8faca505..fddad1c21e3d3 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -91,6 +91,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, + const u8 *fwdynhdr; + const u8 *bin; + u32 base_hdr_len; ++ u32 mssc_len = 0; + u32 i; + + if (!info) +@@ -120,6 +121,14 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, + fw += RTW89_FW_HDR_SIZE; + section_info = info->section_info; + for (i = 0; i < info->section_num; i++) { ++ section_info->type = GET_FWSECTION_HDR_SECTIONTYPE(fw); ++ if (section_info->type == FWDL_SECURITY_SECTION_TYPE) { ++ section_info->mssc = GET_FWSECTION_HDR_MSSC(fw); ++ mssc_len += section_info->mssc * FWDL_SECURITY_SIGLEN; ++ } else { ++ section_info->mssc = 0; ++ } ++ + section_info->len = GET_FWSECTION_HDR_SEC_SIZE(fw); + if (GET_FWSECTION_HDR_CHECKSUM(fw)) + section_info->len += FWDL_SECTION_CHKSUM_LEN; +@@ -132,7 +141,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, + section_info++; + } + +- if (fw_end != bin) { ++ if (fw_end != bin + mssc_len) { + rtw89_err(rtwdev, "[ERR]fw bin size\n"); + return -EINVAL; + } +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 4d2f9ea9e0022..4326e0ede54b8 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -171,6 +171,8 @@ struct rtw89_fw_hdr_section_info { + const u8 *addr; + u32 len; + u32 dladdr; ++ u32 mssc; ++ u8 type; + }; + + struct rtw89_fw_bin_info { +@@ -480,14 +482,21 @@ static inline void RTW89_SET_EDCA_PARAM(void *cmd, u32 val) + #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 GET_FWSECTION_HDR_DL_ADDR(fwhdr) \ ++ le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0)) ++#define GET_FWSECTION_HDR_SECTIONTYPE(fwhdr) \ ++ le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(27, 24)) + #define GET_FWSECTION_HDR_SEC_SIZE(fwhdr) \ + le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(23, 0)) + #define GET_FWSECTION_HDR_CHECKSUM(fwhdr) \ + le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(28)) + #define GET_FWSECTION_HDR_REDL(fwhdr) \ + le32_get_bits(*((const __le32 *)(fwhdr) + 1), BIT(29)) +-#define GET_FWSECTION_HDR_DL_ADDR(fwhdr) \ +- le32_get_bits(*((const __le32 *)(fwhdr)), GENMASK(31, 0)) ++#define GET_FWSECTION_HDR_MSSC(fwhdr) \ ++ le32_get_bits(*((const __le32 *)(fwhdr) + 2), GENMASK(31, 0)) + + #define GET_FW_HDR_MAJOR_VERSION(fwhdr) \ + le32_get_bits(*((const __le32 *)(fwhdr) + 1), GENMASK(7, 0)) +-- +2.13.6 + diff --git a/SOURCES/0080-wifi-rtw89-8852c-rfk-correct-DACK-setting.patch b/SOURCES/0080-wifi-rtw89-8852c-rfk-correct-DACK-setting.patch new file mode 100644 index 0000000..b0601c3 --- /dev/null +++ b/SOURCES/0080-wifi-rtw89-8852c-rfk-correct-DACK-setting.patch @@ -0,0 +1,46 @@ +From 33eaf6157fecb32ffff8b0ac1f75f19248825a45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:32 +0200 +Subject: [PATCH 080/142] wifi: rtw89: 8852c: rfk: correct DACK setting +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit b2bab7b14098dcf5d405fa8c76b2c3f6ce9184f9 +Author: Ping-Ke Shih +Date: Fri Dec 9 10:09:38 2022 +0800 + + wifi: rtw89: 8852c: rfk: correct DACK setting + + After filling calibration parameters, set BIT(0) to enable the hardware + circuit, but original set incorrect bit that affects a little TX + performance. + + Fixes: 76599a8d0b7d ("rtw89: 8852c: rfk: add DACK") + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221209020940.9573-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +index 60cd676fe22c9..f5b0b57f33207 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +@@ -337,7 +337,7 @@ static void _dack_reload_by_path(struct rtw89_dev *rtwdev, + (dack->dadck_d[path][index] << 14); + addr = 0xc210 + offset; + rtw89_phy_write32(rtwdev, addr, val32); +- rtw89_phy_write32_set(rtwdev, addr, BIT(1)); ++ rtw89_phy_write32_set(rtwdev, addr, BIT(0)); + } + + static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) +-- +2.13.6 + diff --git a/SOURCES/0081-wifi-rtw89-8852c-rfk-correct-DPK-settings.patch b/SOURCES/0081-wifi-rtw89-8852c-rfk-correct-DPK-settings.patch new file mode 100644 index 0000000..21df288 --- /dev/null +++ b/SOURCES/0081-wifi-rtw89-8852c-rfk-correct-DPK-settings.patch @@ -0,0 +1,67 @@ +From b78b8b0d588655977715ddcdb4c9fc4711b802ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:32 +0200 +Subject: [PATCH 081/142] wifi: rtw89: 8852c: rfk: correct DPK settings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 21b5f159a2ee47d30f418559f6ece0088c80199f +Author: Ping-Ke Shih +Date: Fri Dec 9 10:09:39 2022 +0800 + + wifi: rtw89: 8852c: rfk: correct DPK settings + + Some DPK settings are wrong, and causes bad TX performance occasionally. + So, fix them by internal suggestions. + + Fixes: da4cea16cb13 ("rtw89: 8852c: rfk: add DPK") + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221209020940.9573-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 2 ++ + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 9 ++++----- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 5324e645728bb..ca6f6c3e63095 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3671,6 +3671,8 @@ + #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_TXG GENMASK(15, 12) + #define RR_BIASA_TXA GENMASK(19, 16) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +index f5b0b57f33207..f3a07b0e672f7 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +@@ -1872,12 +1872,11 @@ static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, + 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) { ++ 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); +- } else { +- rtw89_write_rf(rtwdev, path, RR_LOGEN, RR_LOGEN_RPT, 0xd); +- } ++ ++ 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); +-- +2.13.6 + diff --git a/SOURCES/0082-wifi-rtw89-8852c-rfk-recover-RX-DCK-failure.patch b/SOURCES/0082-wifi-rtw89-8852c-rfk-recover-RX-DCK-failure.patch new file mode 100644 index 0000000..7511bb8 --- /dev/null +++ b/SOURCES/0082-wifi-rtw89-8852c-rfk-recover-RX-DCK-failure.patch @@ -0,0 +1,414 @@ +From d2ebebae70833bfb5314d046677361f5d622ce19 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:32 +0200 +Subject: [PATCH 082/142] wifi: rtw89: 8852c: rfk: recover RX DCK failure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 9c22d603e255ece73e61e3b3f93dae8ab82c17ff +Author: Ping-Ke Shih +Date: Fri Dec 9 10:09:40 2022 +0800 + + wifi: rtw89: 8852c: rfk: recover RX DCK failure + + RX DCK stands for RX DC calibration that affects CCA, so abnormal + calibration values resulted from calibration failure can cause TX get + stuck. + + To solve this, redo calibration if result is bad (over thresholds). When + retry count is over, do recovery that sets high gain fields of RX DCK + results from low gain fields. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221209020940.9573-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 10 + + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 253 +++++++++++++++++++++- + 2 files changed, 256 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index ca6f6c3e63095..ec5b8d5750364 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -3559,6 +3559,7 @@ + #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_V_DOWN 0x0 + #define RR_MOD_V_STANDBY 0x1 +@@ -3572,6 +3573,7 @@ + #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_M_TXPWR GENMASK(5, 0) + #define RR_WLSEL 0x02 +@@ -3638,6 +3640,7 @@ + #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) +@@ -3731,10 +3734,14 @@ + #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) +@@ -3783,11 +3790,14 @@ + #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_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 +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +index f3a07b0e672f7..b0ea23d9f81fb 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +@@ -59,6 +59,9 @@ static const u32 dpk_par_regs[RTW89_DPK_RF_PATH][4] = { + {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 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", +@@ -1536,6 +1539,155 @@ static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool forc + } + } + ++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; +@@ -1573,6 +1725,37 @@ static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 pat + } + } + ++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 >= 1 && 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 0x10 + #define RTW8852C_DPK_TH_AVG_NUM 4 +@@ -3874,11 +4057,14 @@ void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) + + #define RXDCK_VER_8852C 0xe + +-void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe) ++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, +@@ -3895,7 +4081,27 @@ void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_a + 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); +- _set_rx_dck(rtwdev, phy, path, is_afe); ++ 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); + +@@ -3905,15 +4111,31 @@ void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_a + } + } + +-#define RTW8852C_RX_DCK_TH 8 ++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) + { ++ const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); + 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); ++ 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]); +@@ -3923,11 +4145,28 @@ void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev) + "[RX_DCK] path=%d current thermal=0x%x delta=0x%x\n", + path, cur_thermal, delta); + +- if (delta >= RTW8852C_RX_DCK_TH) { +- rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false); +- return; +- } ++ 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(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) +-- +2.13.6 + diff --git a/SOURCES/0083-wifi-rtw89-coex-add-BTC-format-version-derived-from-.patch b/SOURCES/0083-wifi-rtw89-coex-add-BTC-format-version-derived-from-.patch new file mode 100644 index 0000000..2d2ea3d --- /dev/null +++ b/SOURCES/0083-wifi-rtw89-coex-add-BTC-format-version-derived-from-.patch @@ -0,0 +1,215 @@ +From 79bec555a8cc77b1d723fa2b22983e9070c21df8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:33 +0200 +Subject: [PATCH 083/142] wifi: rtw89: coex: add BTC format version derived + from firmware version +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 6140635a73c00c0b3a8a58d13890dcf27d0af32a +Author: Ping-Ke Shih +Date: Sat Dec 17 22:17:39 2022 +0800 + + wifi: rtw89: coex: add BTC format version derived from firmware version + + Originally, each chip maintains its own format version followed firmware + it uses. As new chip is added, firmware changes format of exchange + messages to have rich information to handle more conditions. + + When old chip is going to upgrade firmware, it could use new format and + driver needs to maintain compatibility with old firmware. So, add this + version array to achieve this goal. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221217141745.43291-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 95 +++++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/coex.h | 1 + + drivers/net/wireless/realtek/rtw89/core.h | 26 +++++++++ + drivers/net/wireless/realtek/rtw89/fw.c | 2 + + 4 files changed, 124 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index f21c73310fdb6..96aadd50f5fd6 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -120,6 +120,70 @@ static const u32 cxtbl[] = { + 0xfafadafa /* 19 */ + }; + ++static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { ++ /* firmware version must be in decreasing order for each chip */ ++ {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, ++ .info_buf = 1280, .max_role_num = 5, ++ }, ++ {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, ++ .info_buf = 1280, .max_role_num = 5, ++ }, ++ {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, ++ .info_buf = 1280, .max_role_num = 5, ++ }, ++ {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, ++ .info_buf = 1800, .max_role_num = 6, ++ }, ++ {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, ++ .info_buf = 1280, .max_role_num = 5, ++ }, ++ {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, ++ .info_buf = 1280, .max_role_num = 5, ++ }, ++ {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, ++ .info_buf = 1024, .max_role_num = 5, ++ }, ++ ++ /* 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, ++ .info_buf = 1024, .max_role_num = 5, ++ }, ++}; ++ ++#define RTW89_DEFAULT_BTC_VER_IDX (ARRAY_SIZE(rtw89_btc_ver_defs) - 1) ++ + struct rtw89_btc_btf_tlv { + u8 type; + u8 len; +@@ -7008,3 +7072,34 @@ void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) + else + _show_summary_v1(rtwdev, m); + } ++ ++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); ++} +diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h +index ca16afa97ec07..401fb55df82b0 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.h ++++ b/drivers/net/wireless/realtek/rtw89/coex.h +@@ -164,6 +164,7 @@ void rtw89_coex_rfk_chk_work(struct work_struct *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); + + static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 800ede1d69c75..151343ee7b763 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2019,9 +2019,35 @@ struct rtw89_btc_btf_fwinfo { + struct rtw89_btc_rpt_fbtc_btdev rpt_fbtc_btdev; + }; + ++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; ++ ++ u16 info_buf; ++ u8 max_role_num; ++}; ++ + #define RTW89_BTC_POLICY_MAXLEN 512 + + struct rtw89_btc { ++ const struct rtw89_btc_ver *ver; ++ + struct rtw89_btc_cx cx; + struct rtw89_btc_dm dm; + struct rtw89_btc_ctrl ctrl; +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index fddad1c21e3d3..ecf68912eac2a 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -352,6 +352,8 @@ int rtw89_fw_recognize(struct rtw89_dev *rtwdev) + + rtw89_fw_recognize_features(rtwdev); + ++ rtw89_coex_recognize_ver(rtwdev); ++ + return 0; + } + +-- +2.13.6 + diff --git a/SOURCES/0084-wifi-rtw89-coex-use-new-introduction-BTC-version-for.patch b/SOURCES/0084-wifi-rtw89-coex-use-new-introduction-BTC-version-for.patch new file mode 100644 index 0000000..c5b5648 --- /dev/null +++ b/SOURCES/0084-wifi-rtw89-coex-use-new-introduction-BTC-version-for.patch @@ -0,0 +1,417 @@ +From 26142ff54ec132d688a63cb645f293a00a30dc71 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:33 +0200 +Subject: [PATCH 084/142] wifi: rtw89: coex: use new introduction BTC version + format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 1fc4a874ff02ba8c07f8abf97c0bef686406f6df +Author: Ping-Ke Shih +Date: Sat Dec 17 22:17:40 2022 +0800 + + wifi: rtw89: coex: use new introduction BTC version format + + Previous patch has added format version derived from firmware version. + Use the format version, and remove constant version number from chip_info. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221217141745.43291-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 32 ++++++++++---------- + drivers/net/wireless/realtek/rtw89/core.h | 42 +++++++++------------------ + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 14 --------- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 15 +--------- + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 14 --------- + 5 files changed, 32 insertions(+), 85 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 96aadd50f5fd6..df3984ebba06e 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -976,6 +976,7 @@ static u32 _chk_btc_report(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_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; +@@ -1022,7 +1023,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pfinfo = &pfwinfo->rpt_ctrl.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo_v1); + } +- pcinfo->req_fver = chip->fcxbtcrpt_ver; ++ pcinfo->req_fver = ver->fcxbtcrpt; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1035,7 +1036,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo_v1); + } +- pcinfo->req_fver = chip->fcxtdma_ver; ++ pcinfo->req_fver = ver->fcxtdma; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1043,7 +1044,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_slots.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo); +- pcinfo->req_fver = chip->fcxslots_ver; ++ pcinfo->req_fver = ver->fcxslots; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1059,7 +1060,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo_v1); + } +- pcinfo->req_fver = chip->fcxcysta_ver; ++ pcinfo->req_fver = ver->fcxcysta; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1076,7 +1077,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + trace_step + + offsetof(struct rtw89_btc_fbtc_steps_v1, step); + } +- pcinfo->req_fver = chip->fcxstep_ver; ++ pcinfo->req_fver = ver->fcxstep; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1089,7 +1090,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo_v1; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo_v1); + } +- pcinfo->req_fver = chip->fcxnullsta_ver; ++ pcinfo->req_fver = ver->fcxnullsta; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1097,7 +1098,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo); +- pcinfo->req_fver = chip->fcxmreg_ver; ++ pcinfo->req_fver = ver->fcxmreg; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1105,7 +1106,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo); +- pcinfo->req_fver = chip->fcxgpiodbg_ver; ++ pcinfo->req_fver = ver->fcxgpiodbg; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1113,7 +1114,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_btver.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo); +- pcinfo->req_fver = chip->fcxbtver_ver; ++ pcinfo->req_fver = ver->fcxbtver; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1121,7 +1122,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo); +- pcinfo->req_fver = chip->fcxbtscan_ver; ++ pcinfo->req_fver = ver->fcxbtscan; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1129,7 +1130,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo); +- pcinfo->req_fver = chip->fcxbtafh_ver; ++ pcinfo->req_fver = ver->fcxbtafh; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1137,7 +1138,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo = &pfwinfo->rpt_fbtc_btdev.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_btdev.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btdev.finfo); +- pcinfo->req_fver = chip->fcxbtdevinfo_ver; ++ pcinfo->req_fver = ver->fcxbtdevinfo; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; + break; +@@ -1394,7 +1395,7 @@ static void _parse_btc_report(struct rtw89_dev *rtwdev, + struct rtw89_btc_btf_fwinfo *pfwinfo, + u8 *pbuf, u32 buf_len) + { +- const struct rtw89_chip_info *chip = rtwdev->chip; ++ const struct rtw89_btc_ver *ver = rtwdev->btc.ver; + struct rtw89_btc_prpt *btc_prpt = NULL; + u32 index = 0, rpt_len = 0; + +@@ -1404,7 +1405,7 @@ static void _parse_btc_report(struct rtw89_dev *rtwdev, + + while (pbuf) { + btc_prpt = (struct rtw89_btc_prpt *)&pbuf[index]; +- if (index + 2 >= chip->btc_fwinfo_buf) ++ if (index + 2 >= ver->info_buf) + break; + /* At least 3 bytes: type(1) & len(2) */ + rpt_len = le16_to_cpu(btc_prpt->len); +@@ -1424,6 +1425,7 @@ static void _append_tdma(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_btf_tlv *tlv; + struct rtw89_btc_fbtc_tdma *v; +@@ -1448,7 +1450,7 @@ static void _append_tdma(struct rtw89_dev *rtwdev) + } else { + tlv->len = sizeof(*v1); + v1 = (struct rtw89_btc_fbtc_tdma_v1 *)&tlv->val[0]; +- v1->fver = chip->fcxtdma_ver; ++ v1->fver = ver->fcxtdma; + v1->tdma = dm->tdma; + btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v1); + } +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 151343ee7b763..358bfcd9ece20 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1438,7 +1438,7 @@ struct rtw89_btc_cx { + }; + + struct rtw89_btc_fbtc_tdma { +- u8 type; /* chip_info::fcxtdma_ver */ ++ u8 type; /* btc_ver::fcxtdma */ + u8 rxflctrl; + u8 txpause; + u8 wtgle_n; +@@ -1449,7 +1449,7 @@ struct rtw89_btc_fbtc_tdma { + } __packed; + + struct rtw89_btc_fbtc_tdma_v1 { +- u8 fver; /* chip_info::fcxtdma_ver */ ++ u8 fver; /* btc_ver::fcxtdma */ + u8 rsvd; + __le16 rsvd1; + struct rtw89_btc_fbtc_tdma tdma; +@@ -1474,7 +1474,7 @@ enum rtw89_btc_bt_sta_counter { + }; + + struct rtw89_btc_fbtc_rpt_ctrl { +- u16 fver; /* chip_info::fcxbtcrpt_ver */ ++ 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; +@@ -1607,7 +1607,7 @@ enum { /* STEP TYPE */ + + #define BTC_DBG_MAX1 32 + struct rtw89_btc_fbtc_gpio_dbg { +- u8 fver; /* chip_info::fcxgpiodbg_ver */ ++ u8 fver; /* btc_ver::fcxgpiodbg */ + u8 rsvd; + u16 rsvd2; + u32 en_map; /* which debug signal (see btc_wl_gpio_debug) is enable */ +@@ -1616,7 +1616,7 @@ struct rtw89_btc_fbtc_gpio_dbg { + } __packed; + + struct rtw89_btc_fbtc_mreg_val { +- u8 fver; /* chip_info::fcxmreg_ver */ ++ u8 fver; /* btc_ver::fcxmreg */ + u8 reg_num; + __le16 rsvd; + __le32 mreg_val[CXMREG_MAX]; +@@ -1639,7 +1639,7 @@ struct rtw89_btc_fbtc_slot { + } __packed; + + struct rtw89_btc_fbtc_slots { +- u8 fver; /* chip_info::fcxslots_ver */ ++ u8 fver; /* btc_ver::fcxslots */ + u8 tbl_num; + __le16 rsvd; + __le32 update_map; +@@ -1653,7 +1653,7 @@ struct rtw89_btc_fbtc_step { + } __packed; + + struct rtw89_btc_fbtc_steps { +- u8 fver; /* chip_info::fcxstep_ver */ ++ u8 fver; /* btc_ver::fcxstep */ + u8 rsvd; + __le16 cnt; + __le16 pos_old; +@@ -1670,7 +1670,7 @@ struct rtw89_btc_fbtc_steps_v1 { + } __packed; + + struct rtw89_btc_fbtc_cysta { /* statistics for cycles */ +- u8 fver; /* chip_info::fcxcysta_ver */ ++ u8 fver; /* btc_ver::fcxcysta */ + u8 rsvd; + __le16 cycles; /* total cycle number */ + __le16 cycles_a2dp[CXT_FLCTRL_MAX]; +@@ -1750,7 +1750,7 @@ struct rtw89_btc_fbtc_cysta_v1 { /* statistics for cycles */ + } __packed; + + struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ +- u8 fver; /* chip_info::fcxnullsta_ver */ ++ u8 fver; /* btc_ver::fcxnullsta */ + u8 rsvd; + __le16 rsvd2; + __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ +@@ -1759,7 +1759,7 @@ struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ + } __packed; + + struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ +- u8 fver; /* chip_info::fcxnullsta_ver */ ++ u8 fver; /* btc_ver::fcxnullsta */ + u8 rsvd; + __le16 rsvd2; + __le32 max_t[2]; /* max_t for 0:null0/1:null1 */ +@@ -1768,7 +1768,7 @@ struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ + } __packed; + + struct rtw89_btc_fbtc_btver { +- u8 fver; /* chip_info::fcxbtver_ver */ ++ u8 fver; /* btc_ver::fcxbtver */ + u8 rsvd; + __le16 rsvd2; + __le32 coex_ver; /*bit[15:8]->shared, bit[7:0]->non-shared */ +@@ -1777,14 +1777,14 @@ struct rtw89_btc_fbtc_btver { + } __packed; + + struct rtw89_btc_fbtc_btscan { +- u8 fver; /* chip_info::fcxbtscan_ver */ ++ u8 fver; /* btc_ver::fcxbtscan */ + u8 rsvd; + __le16 rsvd2; + u8 scan[6]; + } __packed; + + struct rtw89_btc_fbtc_btafh { +- u8 fver; /* chip_info::fcxbtafh_ver */ ++ u8 fver; /* btc_ver::fcxbtafh */ + u8 rsvd; + __le16 rsvd2; + u8 afh_l[4]; /*bit0:2402, bit1: 2403.... bit31:2433 */ +@@ -1793,7 +1793,7 @@ struct rtw89_btc_fbtc_btafh { + } __packed; + + struct rtw89_btc_fbtc_btdevinfo { +- u8 fver; /* chip_info::fcxbtdevinfo_ver */ ++ u8 fver; /* btc_ver::fcxbtdevinfo */ + u8 rsvd; + __le16 vendor_id; + __le32 dev_name; /* only 24 bits valid */ +@@ -2756,20 +2756,6 @@ struct rtw89_chip_info { + u8 btcx_desired; + u8 scbd; + u8 mailbox; +- u16 btc_fwinfo_buf; +- +- u8 fcxbtcrpt_ver; +- u8 fcxtdma_ver; +- u8 fcxslots_ver; +- u8 fcxcysta_ver; +- u8 fcxstep_ver; +- u8 fcxnullsta_ver; +- u8 fcxmreg_ver; +- u8 fcxgpiodbg_ver; +- u8 fcxbtver_ver; +- u8 fcxbtscan_ver; +- u8 fcxbtafh_ver; +- u8 fcxbtdevinfo_ver; + + u8 afh_guard_ch; + const u8 *wl_rssi_thres; +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index eff6519cf0191..9a6f2f9f35a84 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -2106,20 +2106,6 @@ const struct rtw89_chip_info rtw8852a_chip_info = { + .btcx_desired = 0x7, + .scbd = 0x1, + .mailbox = 0x1, +- .btc_fwinfo_buf = 1024, +- +- .fcxbtcrpt_ver = 1, +- .fcxtdma_ver = 1, +- .fcxslots_ver = 1, +- .fcxcysta_ver = 2, +- .fcxstep_ver = 2, +- .fcxnullsta_ver = 1, +- .fcxmreg_ver = 1, +- .fcxgpiodbg_ver = 1, +- .fcxbtver_ver = 1, +- .fcxbtscan_ver = 1, +- .fcxbtafh_ver = 1, +- .fcxbtdevinfo_ver = 1, + + .afh_guard_ch = 6, + .wl_rssi_thres = rtw89_btc_8852a_wl_rssi_thres, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index b635ac1d1ca2f..498ae8616cd59 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -2483,20 +2483,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .btcx_desired = 0x5, + .scbd = 0x1, + .mailbox = 0x1, +- .btc_fwinfo_buf = 1024, +- +- .fcxbtcrpt_ver = 1, +- .fcxtdma_ver = 1, +- .fcxslots_ver = 1, +- .fcxcysta_ver = 2, +- .fcxstep_ver = 2, +- .fcxnullsta_ver = 1, +- .fcxmreg_ver = 1, +- .fcxgpiodbg_ver = 1, +- .fcxbtver_ver = 1, +- .fcxbtscan_ver = 1, +- .fcxbtafh_ver = 1, +- .fcxbtdevinfo_ver = 1, ++ + .afh_guard_ch = 6, + .wl_rssi_thres = rtw89_btc_8852b_wl_rssi_thres, + .bt_rssi_thres = rtw89_btc_8852b_bt_rssi_thres, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index a87482cc25f58..bacdc91d63e9f 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2915,20 +2915,6 @@ const struct rtw89_chip_info rtw8852c_chip_info = { + .btcx_desired = 0x7, + .scbd = 0x1, + .mailbox = 0x1, +- .btc_fwinfo_buf = 1280, +- +- .fcxbtcrpt_ver = 4, +- .fcxtdma_ver = 3, +- .fcxslots_ver = 1, +- .fcxcysta_ver = 3, +- .fcxstep_ver = 3, +- .fcxnullsta_ver = 2, +- .fcxmreg_ver = 1, +- .fcxgpiodbg_ver = 1, +- .fcxbtver_ver = 1, +- .fcxbtscan_ver = 1, +- .fcxbtafh_ver = 1, +- .fcxbtdevinfo_ver = 1, + + .afh_guard_ch = 6, + .wl_rssi_thres = rtw89_btc_8852c_wl_rssi_thres, +-- +2.13.6 + diff --git a/SOURCES/0085-wifi-rtw89-coex-Enable-Bluetooth-report-when-show-de.patch b/SOURCES/0085-wifi-rtw89-coex-Enable-Bluetooth-report-when-show-de.patch new file mode 100644 index 0000000..d1b7bec --- /dev/null +++ b/SOURCES/0085-wifi-rtw89-coex-Enable-Bluetooth-report-when-show-de.patch @@ -0,0 +1,98 @@ +From 39d7ebf1095575793ff50489d230734b357a30b7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:33 +0200 +Subject: [PATCH 085/142] wifi: rtw89: coex: Enable Bluetooth report when show + debug info +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit bc20f9235f644846520a68340ea0730d09022e0a +Author: Ching-Te Ku +Date: Sat Dec 17 22:17:41 2022 +0800 + + wifi: rtw89: coex: Enable Bluetooth report when show debug info + + Ask WiFi firmware to send Bluetooth version report when we want to show + Bluetooth debug info. If there is no request for debug log, driver will + not enable the report. This modification can save some C2H/H2C resources. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221217141745.43291-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 32 ++++++++++++++++++------------- + 1 file changed, 19 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index df3984ebba06e..b58c839e10d92 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -5066,11 +5066,6 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) + + a2dp->sink = btinfo.hb3.a2dp_sink; + +- if (b->profile_cnt.now || b->status.map.ble_connect) +- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, 1); +- else +- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, 0); +- + if (!a2dp->exist_last && a2dp->exist) { + a2dp->vendor_id = 0; + a2dp->flush_time = 0; +@@ -5080,12 +5075,6 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len) + RTW89_COEX_BT_DEVINFO_WORK_PERIOD); + } + +- if (a2dp->exist && (a2dp->flush_time == 0 || a2dp->vendor_id == 0 || +- a2dp->play_latency == 1)) +- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, 1); +- else +- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, 0); +- + _run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO); + } + +@@ -5218,8 +5207,7 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta + + if (rf_state == BTC_RFCTRL_WL_ON) { + btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; +- rtw89_btc_fw_en_rpt(rtwdev, +- RPT_EN_MREG | RPT_EN_BT_VER_INFO, true); ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true); + val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG; + _write_scbd(rtwdev, val, true); + _update_bt_scbd(rtwdev, true); +@@ -5866,6 +5854,24 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) + "[trx_req_cnt]", cx->cnt_bt[BTC_BCNT_HIPRI_RX], + cx->cnt_bt[BTC_BCNT_HIPRI_TX], cx->cnt_bt[BTC_BCNT_LOPRI_RX], + cx->cnt_bt[BTC_BCNT_LOPRI_TX], cx->cnt_bt[BTC_BCNT_POLUT]); ++ ++ if (bt->enable.now && bt->ver_info.fw == 0) ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true); ++ else ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, false); ++ ++ if (bt_linfo->profile_cnt.now || bt_linfo->status.map.ble_connect) ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, true); ++ else ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, false); ++ ++ if (bt_linfo->a2dp_desc.exist && ++ (bt_linfo->a2dp_desc.flush_time == 0 || ++ bt_linfo->a2dp_desc.vendor_id == 0 || ++ bt_linfo->a2dp_desc.play_latency == 1)) ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, true); ++ else ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, false); + } + + #define CASE_BTC_RSN_STR(e) case BTC_RSN_ ## e: return #e +-- +2.13.6 + diff --git a/SOURCES/0086-wifi-rtw89-coex-Update-BTC-firmware-report-bitmap-de.patch b/SOURCES/0086-wifi-rtw89-coex-Update-BTC-firmware-report-bitmap-de.patch new file mode 100644 index 0000000..49247fc --- /dev/null +++ b/SOURCES/0086-wifi-rtw89-coex-Update-BTC-firmware-report-bitmap-de.patch @@ -0,0 +1,243 @@ +From ac93364355ca02b02d5410de997a3a7c2f83d56e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:33 +0200 +Subject: [PATCH 086/142] wifi: rtw89: coex: Update BTC firmware report bitmap + definition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 52c7c983174cd8e2f92e157ef806be3629d5d73b +Author: Ching-Te Ku +Date: Sat Dec 17 22:17:42 2022 +0800 + + wifi: rtw89: coex: Update BTC firmware report bitmap definition + + The different version use different bit definition to enable firmware + report. WiFi firmware will report information from Bluetooth firmware or + some Wi-Fi firmware mechanism/status to driver by these bits. To solve the + difference, add a function to map bitmap and versions. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221217141745.43291-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 177 +++++++++++++++++++++++++++--- + 1 file changed, 164 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index b58c839e10d92..6840f0363d96c 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -191,16 +191,20 @@ struct rtw89_btc_btf_tlv { + } __packed; + + enum btc_btf_set_report_en { +- RPT_EN_TDMA = BIT(0), +- RPT_EN_CYCLE = BIT(1), +- RPT_EN_MREG = BIT(2), +- RPT_EN_BT_VER_INFO = BIT(3), +- RPT_EN_BT_SCAN_INFO = BIT(4), +- RPT_EN_BT_AFH_MAP = BIT(5), +- RPT_EN_BT_DEVICE_INFO = BIT(6), +- RPT_EN_WL_ALL = GENMASK(2, 0), +- RPT_EN_BT_ALL = GENMASK(6, 3), +- RPT_EN_ALL = GENMASK(6, 0), ++ 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_FW_STEP_INFO, ++ RPT_EN_TEST, ++ RPT_EN_WL_ALL, ++ RPT_EN_BT_ALL, ++ RPT_EN_ALL, ++ RPT_EN_MONITER, + }; + + #define BTF_SET_REPORT_VER 1 +@@ -1507,22 +1511,169 @@ static void _append_slot(struct rtw89_dev *rtwdev) + __func__, cnt); + } + ++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: ++ 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: ++ 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: ++ bit_map = BIT(7); ++ break; ++ default: ++ break; ++ } ++ break; ++ case RPT_EN_FW_STEP_INFO: ++ switch (ver->frptmap) { ++ case 1: ++ case 2: ++ bit_map = BIT(7); ++ break; ++ case 3: ++ bit_map = BIT(8); ++ break; ++ default: ++ break; ++ } ++ break; ++ case RPT_EN_TEST: ++ 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: ++ bit_map = GENMASK(2, 0) | BIT(8); ++ 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: ++ bit_map = GENMASK(7, 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; ++ 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: ++ bit_map = GENMASK(8, 2); ++ break; ++ default: ++ break; ++ } ++ break; ++ } ++ ++ return bit_map; ++} ++ + static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev, + u32 rpt_map, bool rpt_state) + { + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo; + struct rtw89_btc_btf_set_report r = {0}; +- u32 val = 0; ++ u32 val, bit_map; ++ ++ bit_map = rtw89_btc_fw_rpt_ver(rtwdev, rpt_map); + + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): rpt_map=%x, rpt_state=%x\n", + __func__, rpt_map, rpt_state); + + if (rpt_state) +- val = fwinfo->rpt_en_map | rpt_map; ++ val = fwinfo->rpt_en_map | bit_map; + else +- val = fwinfo->rpt_en_map & ~rpt_map; ++ val = fwinfo->rpt_en_map & ~bit_map; + + if (val == fwinfo->rpt_en_map) + return; +-- +2.13.6 + diff --git a/SOURCES/0087-wifi-rtw89-coex-Add-v2-BT-AFH-report-and-related-var.patch b/SOURCES/0087-wifi-rtw89-coex-Add-v2-BT-AFH-report-and-related-var.patch new file mode 100644 index 0000000..c52a2b3 --- /dev/null +++ b/SOURCES/0087-wifi-rtw89-coex-Add-v2-BT-AFH-report-and-related-var.patch @@ -0,0 +1,229 @@ +From 6923eab289962e6d28cbd997fdb8c24e5d79a880 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:33 +0200 +Subject: [PATCH 087/142] wifi: rtw89: coex: Add v2 BT AFH report and related + variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 0cdfcfce85b6f067f1639550a0aacf2c112a3441 +Author: Ching-Te Ku +Date: Sat Dec 17 22:17:43 2022 +0800 + + wifi: rtw89: coex: Add v2 BT AFH report and related variable + + Wi-Fi firmware update AFH report feature to version 2. If there is BT BLE + device connect to DUT, the mechanism will send H2C to request BT BLE + channel map, it will help to debug. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221217141745.43291-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 54 +++++++++++++++++++++++++++---- + drivers/net/wireless/realtek/rtw89/core.h | 26 ++++++++++++++- + 2 files changed, 72 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 6840f0363d96c..13764bfdd0bea 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -854,17 +854,18 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt) + 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.bt; + struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; + struct rtw89_btc_bt_a2dp_desc *a2dp = &bt_linfo->a2dp_desc; + struct rtw89_btc_fbtc_btver *pver = NULL; + struct rtw89_btc_fbtc_btscan *pscan = NULL; +- struct rtw89_btc_fbtc_btafh *pafh = NULL; ++ struct rtw89_btc_fbtc_btafh *pafh_v1 = NULL; ++ struct rtw89_btc_fbtc_btafh_v2 *pafh_v2 = NULL; + struct rtw89_btc_fbtc_btdevinfo *pdev = NULL; + + pver = (struct rtw89_btc_fbtc_btver *)pfinfo; + pscan = (struct rtw89_btc_fbtc_btscan *)pfinfo; +- pafh = (struct rtw89_btc_fbtc_btafh *)pfinfo; + pdev = (struct rtw89_btc_fbtc_btdevinfo *)pfinfo; + + rtw89_debug(rtwdev, RTW89_DBG_BTC, +@@ -881,9 +882,23 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo) + memcpy(bt->scan_info, pscan->scan, BTC_SCAN_MAX1); + break; + case BTC_RPT_TYPE_BT_AFH: +- memcpy(&bt_linfo->afh_map[0], pafh->afh_l, 4); +- memcpy(&bt_linfo->afh_map[4], pafh->afh_m, 4); +- memcpy(&bt_linfo->afh_map[8], pafh->afh_h, 2); ++ 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 == 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: + a2dp->device_name = le32_to_cpu(pdev->dev_name); +@@ -1132,8 +1147,15 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + break; + case BTC_RPT_TYPE_BT_AFH: + pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; +- pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo); ++ if (ver->fcxbtafh == 1) { ++ pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v1; ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v1); ++ } else if (ver->fcxbtafh == 2) { ++ pfinfo = &pfwinfo->rpt_fbtc_btafh.finfo.v2; ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btafh.finfo.v2); ++ } else { ++ goto err; ++ } + pcinfo->req_fver = ver->fcxbtafh; + pcinfo->rx_len = rpt_len; + pcinfo->rx_cnt++; +@@ -1393,6 +1415,11 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + _update_bt_report(rtwdev, rpt_type, pfinfo); + + 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, +@@ -5919,12 +5946,14 @@ static void _show_bt_profile_info(struct rtw89_dev *rtwdev, struct seq_file *m) + static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) + { + 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 = &cx->bt; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_module *module = &btc->mdinfo; + struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info; + 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; +@@ -5974,6 +6003,12 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) + 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) ++ seq_printf(m, ++ "LE[%02x%02x_%02x_%02x%02x]", ++ afh_le[0], afh_le[1], afh_le[2], ++ afh_le[3], afh_le[4]); ++ + seq_printf(m, "wl_ch_map[en:%d/ch:%d/bw:%d]\n", + wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw); + +@@ -6016,6 +6051,11 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) + else + rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, false); + ++ if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect) ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, true); ++ else ++ rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, false); ++ + if (bt_linfo->a2dp_desc.exist && + (bt_linfo->a2dp_desc.flush_time == 0 || + bt_linfo->a2dp_desc.vendor_id == 0 || +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 358bfcd9ece20..af42e67897b6e 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1264,6 +1264,7 @@ union rtw89_btc_bt_state_map { + + #define BTC_BT_RSSI_THMAX 4 + #define BTC_BT_AFH_GROUP 12 ++#define BTC_BT_AFH_LE_GROUP 5 + + struct rtw89_btc_bt_link_info { + struct rtw89_btc_u8_sta_chg profile_cnt; +@@ -1279,6 +1280,7 @@ struct rtw89_btc_bt_link_info { + 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]; + + u32 role_sw: 1; + u32 slave_role: 1; +@@ -1605,6 +1607,11 @@ enum { /* STEP TYPE */ + CXSTEP_MAX, + }; + ++enum rtw89_btc_afh_map_type { /*AFH MAP TYPE */ ++ RPT_BT_AFH_SEQ_LEGACY = 0x10, ++ RPT_BT_AFH_SEQ_LE = 0x20 ++}; ++ + #define BTC_DBG_MAX1 32 + struct rtw89_btc_fbtc_gpio_dbg { + u8 fver; /* btc_ver::fcxgpiodbg */ +@@ -1792,6 +1799,18 @@ struct rtw89_btc_fbtc_btafh { + 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_btdevinfo { + u8 fver; /* btc_ver::fcxbtdevinfo */ + u8 rsvd; +@@ -1912,6 +1931,11 @@ struct rtw89_btc_rpt_cmn_info { + 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_report_ctrl_state { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ + union { +@@ -1979,7 +2003,7 @@ struct rtw89_btc_rpt_fbtc_btscan { + + struct rtw89_btc_rpt_fbtc_btafh { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ +- struct rtw89_btc_fbtc_btafh finfo; /* info from fw */ ++ union rtw89_btc_fbtc_btafh_info finfo; + }; + + struct rtw89_btc_rpt_fbtc_btdev { +-- +2.13.6 + diff --git a/SOURCES/0088-wifi-rtw89-coex-refactor-_chk_btc_report-to-extend-m.patch b/SOURCES/0088-wifi-rtw89-coex-refactor-_chk_btc_report-to-extend-m.patch new file mode 100644 index 0000000..7d838d6 --- /dev/null +++ b/SOURCES/0088-wifi-rtw89-coex-refactor-_chk_btc_report-to-extend-m.patch @@ -0,0 +1,526 @@ +From 801d99e983d490176539afe34c6dfa277dbbf947 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:33 +0200 +Subject: [PATCH 088/142] wifi: rtw89: coex: refactor _chk_btc_report() to + extend more features +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 31f12cff9d262468a11dc02af48fd1e538e1223f +Author: Ching-Te Ku +Date: Sat Dec 17 22:17:44 2022 +0800 + + wifi: rtw89: coex: refactor _chk_btc_report() to extend more features + + Change the checking logic to switch case. Make the code more readable. + There are more feature including to common code, in order to commit the + following version of the features, switch case will make the logic more + clearly. This patch did not change logic. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221217141745.43291-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 365 ++++++++++++------------------ + 1 file changed, 143 insertions(+), 222 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 13764bfdd0bea..db0c694c4f92b 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -1006,7 +1006,6 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1 = NULL; + struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; + struct rtw89_btc_prpt *btc_prpt = NULL; +- struct rtw89_btc_fbtc_slot *rtp_slot = NULL; + void *rpt_content = NULL, *pfinfo = NULL; + u8 rpt_type = 0; + u16 wl_slot_set = 0, wl_slot_real = 0; +@@ -1043,8 +1042,6 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo_v1); + } + pcinfo->req_fver = ver->fcxbtcrpt; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_TDMA: + pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; +@@ -1056,16 +1053,12 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo_v1); + } + pcinfo->req_fver = ver->fcxtdma; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_SLOT: + pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_slots.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_slots.finfo); + pcinfo->req_fver = ver->fcxslots; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_CYSTA: + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; +@@ -1080,8 +1073,6 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo_v1); + } + pcinfo->req_fver = ver->fcxcysta; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_STEP: + pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; +@@ -1097,8 +1088,6 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + offsetof(struct rtw89_btc_fbtc_steps_v1, step); + } + pcinfo->req_fver = ver->fcxstep; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_NULLSTA: + pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; +@@ -1110,40 +1099,30 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo_v1); + } + pcinfo->req_fver = ver->fcxnullsta; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_MREG: + pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_mregval.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_mregval.finfo); + pcinfo->req_fver = ver->fcxmreg; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_GPIO_DBG: + pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_gpio_dbg.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_gpio_dbg.finfo); + pcinfo->req_fver = ver->fcxgpiodbg; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_BT_VER: + pcinfo = &pfwinfo->rpt_fbtc_btver.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_btver.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btver.finfo); + pcinfo->req_fver = ver->fcxbtver; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_BT_SCAN: + pcinfo = &pfwinfo->rpt_fbtc_btscan.cinfo; + pfinfo = &pfwinfo->rpt_fbtc_btscan.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_btscan.finfo); + pcinfo->req_fver = ver->fcxbtscan; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + break; + case BTC_RPT_TYPE_BT_AFH: + pcinfo = &pfwinfo->rpt_fbtc_btafh.cinfo; +@@ -1157,22 +1136,21 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + goto err; + } + pcinfo->req_fver = ver->fcxbtafh; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + 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); + pcinfo->req_fver = ver->fcxbtdevinfo; +- pcinfo->rx_len = rpt_len; +- pcinfo->rx_cnt++; + 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); +@@ -1193,227 +1171,170 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + memcpy(pfinfo, rpt_content, pcinfo->req_len); + pcinfo->valid = 1; + +- if (rpt_type == BTC_RPT_TYPE_TDMA && chip->chip_id == RTL8852A) { +- rtw89_debug(rtwdev, RTW89_DBG_BTC, +- "[BTC], %s(): check %d %zu\n", __func__, +- BTC_DCNT_TDMA_NONSYNC, sizeof(dm->tdma_now)); +- +- if (memcmp(&dm->tdma_now, &pfwinfo->rpt_fbtc_tdma.finfo, +- sizeof(dm->tdma_now)) != 0) { +- rtw89_debug(rtwdev, RTW89_DBG_BTC, +- "[BTC], %s(): %d tdma_now %x %x %x %x %x %x %x %x\n", +- __func__, BTC_DCNT_TDMA_NONSYNC, +- dm->tdma_now.type, dm->tdma_now.rxflctrl, +- dm->tdma_now.txpause, dm->tdma_now.wtgle_n, +- dm->tdma_now.leak_n, dm->tdma_now.ext_ctrl, +- dm->tdma_now.rxflctrl_role, +- dm->tdma_now.option_ctrl); +- +- rtw89_debug(rtwdev, RTW89_DBG_BTC, +- "[BTC], %s(): %d rpt_fbtc_tdma %x %x %x %x %x %x %x %x\n", +- __func__, BTC_DCNT_TDMA_NONSYNC, +- pfwinfo->rpt_fbtc_tdma.finfo.type, +- pfwinfo->rpt_fbtc_tdma.finfo.rxflctrl, +- pfwinfo->rpt_fbtc_tdma.finfo.txpause, +- pfwinfo->rpt_fbtc_tdma.finfo.wtgle_n, +- pfwinfo->rpt_fbtc_tdma.finfo.leak_n, +- pfwinfo->rpt_fbtc_tdma.finfo.ext_ctrl, +- pfwinfo->rpt_fbtc_tdma.finfo.rxflctrl_role, +- pfwinfo->rpt_fbtc_tdma.finfo.option_ctrl); +- } ++ switch (rpt_type) { ++ case BTC_RPT_TYPE_CTRL: ++ if (chip->chip_id == RTL8852A) { ++ prpt = &pfwinfo->rpt_ctrl.finfo; ++ btc->fwinfo.rpt_en_map = prpt->rpt_enable; ++ wl->ver_info.fw_coex = prpt->wl_fw_coex_ver; ++ wl->ver_info.fw = prpt->wl_fw_ver; ++ dm->wl_fw_cx_offload = !!prpt->wl_fw_cx_offload; ++ ++ _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, ++ 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_FREEZE, 0); ++ ++ btc->cx.cnt_bt[BTC_BCNT_POLUT] = ++ rtw89_mac_get_plt_cnt(rtwdev, ++ RTW89_MAC_0); ++ } ++ } else { ++ prpt_v1 = &pfwinfo->rpt_ctrl.finfo_v1; ++ btc->fwinfo.rpt_en_map = le32_to_cpu(prpt_v1->rpt_info.en); ++ wl->ver_info.fw_coex = le32_to_cpu(prpt_v1->wl_fw_info.cx_ver); ++ wl->ver_info.fw = le32_to_cpu(prpt_v1->wl_fw_info.fw_ver); ++ dm->wl_fw_cx_offload = !!le32_to_cpu(prpt_v1->wl_fw_info.cx_offload); ++ ++ for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) ++ memcpy(&dm->gnt.band[i], &prpt_v1->gnt_val[i], ++ sizeof(dm->gnt.band[i])); ++ ++ btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = ++ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_TX]); ++ btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = ++ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_RX]); ++ btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = ++ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_TX]); ++ btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = ++ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_RX]); ++ btc->cx.cnt_bt[BTC_BCNT_POLUT] = ++ le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_POLLUTED]); + +- _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, +- memcmp(&dm->tdma_now, +- &pfwinfo->rpt_fbtc_tdma.finfo, +- sizeof(dm->tdma_now))); +- } else if (rpt_type == 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 (memcmp(&dm->tdma_now, &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma, +- sizeof(dm->tdma_now)) != 0) { +- rtw89_debug(rtwdev, RTW89_DBG_BTC, +- "[BTC], %s(): %d tdma_now %x %x %x %x %x %x %x %x\n", +- __func__, BTC_DCNT_TDMA_NONSYNC, +- dm->tdma_now.type, dm->tdma_now.rxflctrl, +- dm->tdma_now.txpause, dm->tdma_now.wtgle_n, +- dm->tdma_now.leak_n, dm->tdma_now.ext_ctrl, +- dm->tdma_now.rxflctrl_role, +- dm->tdma_now.option_ctrl); +- rtw89_debug(rtwdev, RTW89_DBG_BTC, +- "[BTC], %s(): %d rpt_fbtc_tdma %x %x %x %x %x %x %x %x\n", +- __func__, BTC_DCNT_TDMA_NONSYNC, +- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.type, +- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.rxflctrl, +- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.txpause, +- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.wtgle_n, +- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.leak_n, +- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.ext_ctrl, +- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.rxflctrl_role, +- pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma.option_ctrl); +- } ++ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); ++ _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, ++ pfwinfo->event[BTF_EVNT_RPT]); + +- _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, +- memcmp(&dm->tdma_now, +- &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma, +- sizeof(dm->tdma_now))); +- } ++ if (le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) ++ bt->rfk_info.map.timeout = 1; ++ else ++ bt->rfk_info.map.timeout = 0; + +- if (rpt_type == BTC_RPT_TYPE_SLOT) { ++ dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; ++ } ++ 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 (chip->chip_id == RTL8852A) ++ _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, ++ memcmp(&dm->tdma_now, ++ &pfwinfo->rpt_fbtc_tdma.finfo_v1, ++ sizeof(dm->tdma_now))); ++ else ++ _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, ++ memcmp(&dm->tdma_now, ++ &pfwinfo->rpt_fbtc_tdma.finfo, ++ sizeof(dm->tdma_now))); ++ break; ++ case BTC_RPT_TYPE_SLOT: + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): check %d %zu\n", + __func__, BTC_DCNT_SLOT_NONSYNC, + sizeof(dm->slot_now)); +- +- if (memcmp(dm->slot_now, pfwinfo->rpt_fbtc_slots.finfo.slot, +- sizeof(dm->slot_now)) != 0) { +- for (i = 0; i < CXST_MAX; i++) { +- rtp_slot = +- &pfwinfo->rpt_fbtc_slots.finfo.slot[i]; +- if (memcmp(&dm->slot_now[i], rtp_slot, +- sizeof(dm->slot_now[i])) != 0) { +- rtw89_debug(rtwdev, RTW89_DBG_BTC, +- "[BTC], %s(): %d slot_now[%d] dur=0x%04x tbl=%08x type=0x%04x\n", +- __func__, +- BTC_DCNT_SLOT_NONSYNC, i, +- dm->slot_now[i].dur, +- dm->slot_now[i].cxtbl, +- dm->slot_now[i].cxtype); +- +- rtw89_debug(rtwdev, RTW89_DBG_BTC, +- "[BTC], %s(): %d rpt_fbtc_slots[%d] dur=0x%04x tbl=%08x type=0x%04x\n", +- __func__, +- BTC_DCNT_SLOT_NONSYNC, i, +- rtp_slot->dur, +- rtp_slot->cxtbl, +- rtp_slot->cxtype); +- } +- } +- } + _chk_btc_err(rtwdev, BTC_DCNT_SLOT_NONSYNC, + memcmp(dm->slot_now, + pfwinfo->rpt_fbtc_slots.finfo.slot, + sizeof(dm->slot_now))); +- } ++ break; ++ case BTC_RPT_TYPE_CYSTA: ++ if (chip->chip_id == RTL8852A) { ++ if (pcysta->cycles < BTC_CYSTA_CHK_PERIOD) ++ break; ++ /* Check Leak-AP */ ++ if (pcysta->slot_cnt[CXST_LK] != 0 && ++ pcysta->leakrx_cnt != 0 && dm->tdma_now.rxflctrl) { ++ if (pcysta->slot_cnt[CXST_LK] < ++ BTC_LEAK_AP_TH * pcysta->leakrx_cnt) ++ dm->leak_ap = 1; ++ } + +- if (rpt_type == BTC_RPT_TYPE_CYSTA && chip->chip_id == RTL8852A && +- pcysta->cycles >= BTC_CYSTA_CHK_PERIOD) { +- /* Check Leak-AP */ +- if (pcysta->slot_cnt[CXST_LK] != 0 && +- pcysta->leakrx_cnt != 0 && dm->tdma_now.rxflctrl) { +- if (pcysta->slot_cnt[CXST_LK] < +- BTC_LEAK_AP_TH * pcysta->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) ++ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_E2G].dur); ++ else ++ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); + +- /* Check diff time between WL slot and W1/E2G slot */ +- if (dm->tdma_now.type == CXTDMA_OFF && +- dm->tdma_now.ext_ctrl == CXECTL_EXT) +- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_E2G].dur); +- else +- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); ++ if (pcysta->tavg_cycle[CXT_WL] > wl_slot_set) { ++ diff_t = pcysta->tavg_cycle[CXT_WL] - wl_slot_set; ++ _chk_btc_err(rtwdev, ++ BTC_DCNT_WL_SLOT_DRIFT, diff_t); ++ } + +- if (pcysta->tavg_cycle[CXT_WL] > wl_slot_set) { +- diff_t = pcysta->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_FREEZE, ++ pcysta->slot_cnt[CXST_W1]); ++ _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, ++ pcysta->slot_cnt[CXST_B1]); ++ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, ++ (u32)pcysta->cycles); ++ } else { ++ if (le16_to_cpu(pcysta_v1->cycles) < BTC_CYSTA_CHK_PERIOD) ++ break; + +- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, pcysta->slot_cnt[CXST_W1]); +- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, pcysta->slot_cnt[CXST_B1]); +- _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, (u32)pcysta->cycles); +- } else if (rpt_type == BTC_RPT_TYPE_CYSTA && pcysta_v1 && +- le16_to_cpu(pcysta_v1->cycles) >= BTC_CYSTA_CHK_PERIOD) { +- cnt_leak_slot = le32_to_cpu(pcysta_v1->slot_cnt[CXST_LK]); +- cnt_rx_imr = le32_to_cpu(pcysta_v1->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; +- } ++ cnt_leak_slot = le32_to_cpu(pcysta_v1->slot_cnt[CXST_LK]); ++ cnt_rx_imr = le32_to_cpu(pcysta_v1->leak_slot.cnt_rximr); + +- /* Check diff time between real WL slot and W1 slot */ +- if (dm->tdma_now.type == CXTDMA_OFF) { +- wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); +- wl_slot_real = le16_to_cpu(pcysta_v1->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 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 BT slot and EBT/E5G slot */ +- if (dm->tdma_now.type == CXTDMA_OFF && +- dm->tdma_now.ext_ctrl == CXECTL_EXT && +- btc->bt_req_len != 0) { +- bt_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_BT]); + +- if (btc->bt_req_len > bt_slot_real) { +- diff_t = btc->bt_req_len - bt_slot_real; +- _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); ++ /* Check diff time between real WL slot and W1 slot */ ++ if (dm->tdma_now.type == CXTDMA_OFF) { ++ wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); ++ wl_slot_real = le16_to_cpu(pcysta_v1->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); ++ } + } +- } + +- _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, +- le32_to_cpu(pcysta_v1->slot_cnt[CXST_W1])); +- _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, +- le32_to_cpu(pcysta_v1->slot_cnt[CXST_B1])); +- _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, +- (u32)le16_to_cpu(pcysta_v1->cycles)); +- } +- +- if (rpt_type == BTC_RPT_TYPE_CTRL && chip->chip_id == RTL8852A) { +- prpt = &pfwinfo->rpt_ctrl.finfo; +- btc->fwinfo.rpt_en_map = prpt->rpt_enable; +- wl->ver_info.fw_coex = prpt->wl_fw_coex_ver; +- wl->ver_info.fw = prpt->wl_fw_ver; +- dm->wl_fw_cx_offload = !!prpt->wl_fw_cx_offload; ++ /* 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 != 0) { ++ bt_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_BT]); + +- _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, +- 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_FREEZE, 0); ++ if (btc->bt_req_len > bt_slot_real) { ++ diff_t = btc->bt_req_len - bt_slot_real; ++ _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); ++ } ++ } + +- btc->cx.cnt_bt[BTC_BCNT_POLUT] = +- rtw89_mac_get_plt_cnt(rtwdev, RTW89_MAC_0); ++ _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, ++ le32_to_cpu(pcysta_v1->slot_cnt[CXST_W1])); ++ _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, ++ le32_to_cpu(pcysta_v1->slot_cnt[CXST_B1])); ++ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, ++ (u32)le16_to_cpu(pcysta_v1->cycles)); + } +- } else if (rpt_type == BTC_RPT_TYPE_CTRL) { +- prpt_v1 = &pfwinfo->rpt_ctrl.finfo_v1; +- btc->fwinfo.rpt_en_map = le32_to_cpu(prpt_v1->rpt_info.en); +- wl->ver_info.fw_coex = le32_to_cpu(prpt_v1->wl_fw_info.cx_ver); +- wl->ver_info.fw = le32_to_cpu(prpt_v1->wl_fw_info.fw_ver); +- dm->wl_fw_cx_offload = !!le32_to_cpu(prpt_v1->wl_fw_info.cx_offload); +- +- for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) +- memcpy(&dm->gnt.band[i], &prpt_v1->gnt_val[i], +- sizeof(dm->gnt.band[i])); +- +- btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_TX]); +- btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_RX]); +- btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_TX]); +- btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_RX]); +- btc->cx.cnt_bt[BTC_BCNT_POLUT] = le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_POLLUTED]); +- +- _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); +- _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, +- pfwinfo->event[BTF_EVNT_RPT]); +- +- if (le32_to_cpu(prpt_v1->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; +- } +- +- if (rpt_type >= BTC_RPT_TYPE_BT_VER && +- rpt_type <= BTC_RPT_TYPE_BT_DEVICE) ++ 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: +-- +2.13.6 + diff --git a/SOURCES/0089-wifi-rtw89-coex-Change-TDMA-related-logic-to-version.patch b/SOURCES/0089-wifi-rtw89-coex-Change-TDMA-related-logic-to-version.patch new file mode 100644 index 0000000..950d6d8 --- /dev/null +++ b/SOURCES/0089-wifi-rtw89-coex-Change-TDMA-related-logic-to-version.patch @@ -0,0 +1,182 @@ +From cd06f0acb1dddf4daa8c162848ace05353d677b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:33 +0200 +Subject: [PATCH 089/142] wifi: rtw89: coex: Change TDMA related logic to + version separate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit e0097ac51e84243f0d0c065cbede1138f5e3aa9f +Author: Ching-Te Ku +Date: Sat Dec 17 22:17:45 2022 +0800 + + wifi: rtw89: coex: Change TDMA related logic to version separate + + In order to make different version of TDMA and coming update in the future + can all work well, use BTC format version to replace chip_id, because + format could change for specific chip_id. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221217141745.43291-8-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 47 ++++++++++++++++--------------- + drivers/net/wireless/realtek/rtw89/core.h | 12 ++++---- + 2 files changed, 32 insertions(+), 27 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index db0c694c4f92b..2cb7ed1636030 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -1045,12 +1045,14 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + break; + case BTC_RPT_TYPE_TDMA: + pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; +- if (chip->chip_id == RTL8852A) { +- pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo); ++ if (ver->fcxtdma == 1) { ++ pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v1; ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v1); ++ } else if (ver->fcxtdma == 3) { ++ pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo.v3; ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo.v3); + } else { +- pfinfo = &pfwinfo->rpt_fbtc_tdma.finfo_v1; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_tdma.finfo_v1); ++ goto err; + } + pcinfo->req_fver = ver->fcxtdma; + break; +@@ -1232,16 +1234,18 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + "[BTC], %s(): check %d %zu\n", __func__, + BTC_DCNT_TDMA_NONSYNC, + sizeof(dm->tdma_now)); +- if (chip->chip_id == RTL8852A) ++ if (ver->fcxtdma == 1) + _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, + memcmp(&dm->tdma_now, +- &pfwinfo->rpt_fbtc_tdma.finfo_v1, ++ &pfwinfo->rpt_fbtc_tdma.finfo.v1, + sizeof(dm->tdma_now))); +- else ++ else if (ver->fcxtdma == 3) + _chk_btc_err(rtwdev, BTC_DCNT_TDMA_NONSYNC, + memcmp(&dm->tdma_now, +- &pfwinfo->rpt_fbtc_tdma.finfo, ++ &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma, + sizeof(dm->tdma_now))); ++ else ++ goto err; + break; + case BTC_RPT_TYPE_SLOT: + rtw89_debug(rtwdev, RTW89_DBG_BTC, +@@ -1375,13 +1379,12 @@ static void _parse_btc_report(struct rtw89_dev *rtwdev, + + static void _append_tdma(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_btf_tlv *tlv; + struct rtw89_btc_fbtc_tdma *v; +- struct rtw89_btc_fbtc_tdma_v1 *v1; ++ struct rtw89_btc_fbtc_tdma_v3 *v3; + u16 len = btc->policy_len; + + if (!btc->update_policy_force && +@@ -1394,17 +1397,17 @@ static void _append_tdma(struct rtw89_dev *rtwdev) + + tlv = (struct rtw89_btc_btf_tlv *)&btc->policy[len]; + tlv->type = CXPOLICY_TDMA; +- if (chip->chip_id == RTL8852A) { ++ if (ver->fcxtdma == 1) { + v = (struct rtw89_btc_fbtc_tdma *)&tlv->val[0]; + tlv->len = sizeof(*v); + memcpy(v, &dm->tdma, sizeof(*v)); +- btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); ++ btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v); + } else { +- tlv->len = sizeof(*v1); +- v1 = (struct rtw89_btc_fbtc_tdma_v1 *)&tlv->val[0]; +- v1->fver = ver->fcxtdma; +- v1->tdma = dm->tdma; +- btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v1); ++ tlv->len = sizeof(*v3); ++ v3 = (struct rtw89_btc_fbtc_tdma_v3 *)&tlv->val[0]; ++ v3->fver = ver->fcxtdma; ++ memcpy(&v3->tdma, &dm->tdma, sizeof(v3->tdma)); ++ btc->policy_len += BTC_TLV_HDR_LEN + sizeof(*v3); + } + + rtw89_debug(rtwdev, RTW89_DBG_BTC, +@@ -6281,8 +6284,8 @@ static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) + + static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) + { +- 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_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_tdma *t = NULL; +@@ -6294,10 +6297,10 @@ static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) + if (!pcinfo->valid) + return; + +- if (chip->chip_id == RTL8852A) +- t = &pfwinfo->rpt_fbtc_tdma.finfo; ++ if (ver->fcxtdma == 1) ++ t = &pfwinfo->rpt_fbtc_tdma.finfo.v1; + else +- t = &pfwinfo->rpt_fbtc_tdma.finfo_v1.tdma; ++ t = &pfwinfo->rpt_fbtc_tdma.finfo.v3.tdma; + + seq_printf(m, + " %-15s : ", "[tdma_policy]"); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index af42e67897b6e..2d7b8c7182472 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1450,13 +1450,18 @@ struct rtw89_btc_fbtc_tdma { + u8 option_ctrl; + } __packed; + +-struct rtw89_btc_fbtc_tdma_v1 { ++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 FCXMAX_STEP 255 /*STEP trace record cnt, Max:65535, default:255*/ + #define BTC_CYCLE_SLOT_MAX 48 /* must be even number, non-zero */ +@@ -1946,10 +1951,7 @@ struct rtw89_btc_report_ctrl_state { + + struct rtw89_btc_rpt_fbtc_tdma { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ +- union { +- struct rtw89_btc_fbtc_tdma finfo; /* info from fw */ +- struct rtw89_btc_fbtc_tdma_v1 finfo_v1; /* info from fw for 52C*/ +- }; ++ union rtw89_btc_fbtc_tdma_le32 finfo; + }; + + struct rtw89_btc_rpt_fbtc_slots { +-- +2.13.6 + diff --git a/SOURCES/0090-wifi-rtw89-8852b-update-BSS-color-mapping-register.patch b/SOURCES/0090-wifi-rtw89-8852b-update-BSS-color-mapping-register.patch new file mode 100644 index 0000000..ed215a7 --- /dev/null +++ b/SOURCES/0090-wifi-rtw89-8852b-update-BSS-color-mapping-register.patch @@ -0,0 +1,126 @@ +From 90465a7002498c8740747dca519f0ecb3b10ad17 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:33 +0200 +Subject: [PATCH 090/142] wifi: rtw89: 8852b: update BSS color mapping register +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit a48f4fd05d5ea20c55afb212240972c1bd2c6ad3 +Author: Eric Huang +Date: Wed Dec 14 17:18:03 2022 +0800 + + wifi: rtw89: 8852b: update BSS color mapping register + + BSS color mapping register is different per IC, therefore, move this + register to chip_info and update the setting function. Without this patch, + wrong BSS color causes behavior abnormal, especially DL-OFDMA. + + Signed-off-by: Eric Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221214091803.41293-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 1 + + drivers/net/wireless/realtek/rtw89/phy.c | 9 +++++---- + drivers/net/wireless/realtek/rtw89/reg.h | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + + 6 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 2d7b8c7182472..04450a4938cad 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2811,6 +2811,7 @@ struct rtw89_chip_info { + u8 dcfo_comp_sft; + const struct rtw89_imr_info *imr_info; + const struct rtw89_rrsr_cfgs *rrsr_cfgs; ++ u32 bss_clr_map_reg; + u32 dma_ch_mask; + const struct wiphy_wowlan_support *wowlan_stub; + }; +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index 5dc617a0a47a7..ca2b5c17d6da0 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -4117,6 +4117,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev) + + void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif) + { ++ const struct rtw89_chip_info *chip = rtwdev->chip; + enum rtw89_phy_idx phy_idx = RTW89_PHY_0; + u8 bss_color; + +@@ -4125,11 +4126,11 @@ void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif + + bss_color = vif->bss_conf.he_bss_color.color; + +- rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0, 0x1, +- phy_idx); +- rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_TGT, bss_color, ++ rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_VLD0, 0x1, + phy_idx); +- rtw89_phy_write32_idx(rtwdev, R_BSS_CLR_MAP, B_BSS_CLR_MAP_STAID, ++ 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, + vif->cfg.aid, phy_idx); + } + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index ec5b8d5750364..578a1969afd61 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -4108,6 +4108,7 @@ + #define R_SEG0CSI_EN 0x42C4 + #define B_SEG0CSI_EN BIT(23) + #define R_BSS_CLR_MAP 0x43ac ++#define R_BSS_CLR_MAP_V1 0x43B0 + #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) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 9a6f2f9f35a84..1875c2537ddbd 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -2135,6 +2135,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { + .dcfo_comp_sft = 3, + .imr_info = &rtw8852a_imr_info, + .rrsr_cfgs = &rtw8852a_rrsr_cfgs, ++ .bss_clr_map_reg = R_BSS_CLR_MAP, + .dma_ch_mask = 0, + #ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8852a, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 498ae8616cd59..b9e5363e524b3 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -2512,6 +2512,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .dcfo_comp_sft = 3, + .imr_info = &rtw8852b_imr_info, + .rrsr_cfgs = &rtw8852b_rrsr_cfgs, ++ .bss_clr_map_reg = R_BSS_CLR_MAP_V1, + .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), +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index bacdc91d63e9f..00fbb65355061 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2945,6 +2945,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { + .dcfo_comp_sft = 5, + .imr_info = &rtw8852c_imr_info, + .rrsr_cfgs = &rtw8852c_rrsr_cfgs, ++ .bss_clr_map_reg = R_BSS_CLR_MAP, + .dma_ch_mask = 0, + #ifdef CONFIG_PM + .wowlan_stub = &rtw_wowlan_stub_8852c, +-- +2.13.6 + diff --git a/SOURCES/0091-wifi-rtw89-refine-6-GHz-scanning-dwell-time.patch b/SOURCES/0091-wifi-rtw89-refine-6-GHz-scanning-dwell-time.patch new file mode 100644 index 0000000..34b834c --- /dev/null +++ b/SOURCES/0091-wifi-rtw89-refine-6-GHz-scanning-dwell-time.patch @@ -0,0 +1,69 @@ +From 22f342a028752f58ff012e1688a12d2c02665092 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:34 +0200 +Subject: [PATCH 091/142] wifi: rtw89: refine 6 GHz scanning dwell time +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 08c93c0ca74c4223dce8fb68e4bb24f7426e55c8 +Author: Po-Hao Huang +Date: Wed Dec 14 17:19:52 2022 +0800 + + wifi: rtw89: refine 6 GHz scanning dwell time + + Reduce dwell time to improve scan duration in 6 GHz. This is required + for scan requests that does not include RNR parsing and does full + channel scan. + + Signed-off-by: Po-Hao Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221214091952.42792-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 5 +++-- + drivers/net/wireless/realtek/rtw89/fw.h | 1 + + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index ecf68912eac2a..466d8273bc2b1 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -2751,7 +2751,7 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, + if (ssid_num == 1 && req->ssids[0].ssid_len == 0) { + ch_info->tx_pkt = false; + if (!req->duration_mandatory) +- ch_info->period -= RTW89_DWELL_TIME; ++ ch_info->period -= RTW89_DWELL_TIME_6G; + } + } + +@@ -2804,7 +2804,8 @@ static int rtw89_hw_scan_add_chan_list(struct rtw89_dev *rtwdev, + if (req->duration_mandatory) + ch_info->period = req->duration; + else if (channel->band == NL80211_BAND_6GHZ) +- ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME; ++ ch_info->period = RTW89_CHANNEL_TIME_6G + ++ RTW89_DWELL_TIME_6G; + else + ch_info->period = RTW89_CHANNEL_TIME; + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 4326e0ede54b8..3ce59ac48f433 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -205,6 +205,7 @@ struct rtw89_h2creg_sch_tx_en { + #define RTW89_DFS_CHAN_TIME 105 + #define RTW89_OFF_CHAN_TIME 100 + #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 +-- +2.13.6 + diff --git a/SOURCES/0092-wifi-rtw89-8852c-rfk-refine-AGC-tuning-flow-of-DPK-f.patch b/SOURCES/0092-wifi-rtw89-8852c-rfk-refine-AGC-tuning-flow-of-DPK-f.patch new file mode 100644 index 0000000..666e5c4 --- /dev/null +++ b/SOURCES/0092-wifi-rtw89-8852c-rfk-refine-AGC-tuning-flow-of-DPK-f.patch @@ -0,0 +1,135 @@ +From 40c418f356774701b7ab0cfcab49677baf8bc3fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:34 +0200 +Subject: [PATCH 092/142] wifi: rtw89: 8852c: rfk: refine AGC tuning flow of + DPK for irregular PA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit ba1a6905c71898509fd3e8d1eb790b4e1213126f +Author: Chih-Kang Chang +Date: Fri Dec 16 13:29:39 2022 +0800 + + wifi: rtw89: 8852c: rfk: refine AGC tuning flow of DPK for irregular PA + + Some hardware modules don't have good RF characteristic as regular. + It could have RF PA characteristic that current code doesn't handle + properly, and it runs into wrong DPK flow that doesn't complete DPK + resulting in bad EVM. + + Signed-off-by: Chih-Kang Chang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221216052939.9991-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 38 ++++++++++++++++++----- + 1 file changed, 30 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +index b0ea23d9f81fb..3c5fa3bb2a8f4 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +@@ -26,7 +26,7 @@ static const u32 rtw8852c_backup_bb_regs[] = { + }; + + static const u32 rtw8852c_backup_rf_regs[] = { +- 0xdf, 0x8f, 0x97, 0xa3, 0x5, 0x10005 ++ 0xdf, 0x5f, 0x8f, 0x97, 0xa3, 0x5, 0x10005 + }; + + #define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852c_backup_bb_regs) +@@ -1757,7 +1757,7 @@ u8 _rx_dck_channel_calc(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) + } + + #define RTW8852C_RF_REL_VERSION 34 +-#define RTW8852C_DPK_VER 0x10 ++#define RTW8852C_DPK_VER 0xf + #define RTW8852C_DPK_TH_AVG_NUM 4 + #define RTW8852C_DPK_RF_PATH 2 + #define RTW8852C_DPK_KIP_REG_NUM 5 +@@ -1797,6 +1797,12 @@ enum dpk_agc_step { + 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) + { +@@ -2206,9 +2212,10 @@ static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + return _dpk_gainloss_read(rtwdev); + } + +-static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) ++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); +@@ -2239,15 +2246,25 @@ static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) + } + } + +- if (val1_i * val1_i + val1_q * val1_q >= (val2_i * val2_i + val2_q * val2_q) * 8 / 5) +- return true; ++ 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 false; ++ 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); +@@ -2285,6 +2302,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + 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; +@@ -2320,9 +2338,13 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, + + case DPK_AGC_STEP_GAIN_LOSS_IDX: + tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx); ++ pas = _dpk_pas_read(rtwdev, true); + +- if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || +- tmp_gl_idx >= 7) ++ 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; +-- +2.13.6 + diff --git a/SOURCES/0093-wifi-rtw89-Fix-a-typo-in-debug-message.patch b/SOURCES/0093-wifi-rtw89-Fix-a-typo-in-debug-message.patch new file mode 100644 index 0000000..757d6a6 --- /dev/null +++ b/SOURCES/0093-wifi-rtw89-Fix-a-typo-in-debug-message.patch @@ -0,0 +1,44 @@ +From 5e98cd761aa9768498e7364d74df9287e9917d18 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:34 +0200 +Subject: [PATCH 093/142] wifi: rtw89: Fix a typo in debug message +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit e20c9f656654f74c9234e6cd3231aed72f53d246 +Author: Masanari Iida +Date: Fri Dec 23 19:20:58 2022 +0900 + + wifi: rtw89: Fix a typo in debug message + + This patch fixes a spelling typo in debug message. + + Signed-off-by: Masanari Iida + Acked-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20221223102058.162179-1-standby24x7@gmail.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +index 582ff0d3a9ea0..cd6c39b7f8025 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c +@@ -1643,7 +1643,7 @@ static void _doiqk(struct rtw89_dev *rtwdev, bool force, + rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); + + rtw89_debug(rtwdev, RTW89_DBG_RFK, +- "[IQK]==========IQK strat!!!!!==========\n"); ++ "[IQK]==========IQK start!!!!!==========\n"); + iqk_info->iqk_times++; + iqk_info->kcount = 0; + iqk_info->version = RTW8852A_IQK_VER; +-- +2.13.6 + diff --git a/SOURCES/0094-wifi-rtw89-coex-Remove-le32-to-CPU-translator-at-fir.patch b/SOURCES/0094-wifi-rtw89-coex-Remove-le32-to-CPU-translator-at-fir.patch new file mode 100644 index 0000000..0931d37 --- /dev/null +++ b/SOURCES/0094-wifi-rtw89-coex-Remove-le32-to-CPU-translator-at-fir.patch @@ -0,0 +1,345 @@ +From b362cbf69c09642e8891fd1485bdb0a502b9ddb6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:34 +0200 +Subject: [PATCH 094/142] wifi: rtw89: coex: Remove le32 to CPU translator at + firmware cycle report +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit f643d08642b82eeb9b9654399dd04657050f7c6f +Author: Ching-Te Ku +Date: Tue Jan 3 22:02:32 2023 +0800 + + wifi: rtw89: coex: Remove le32 to CPU translator at firmware cycle report + + There are at least 2 version of cycle report format. If the code keep + translating the report to local variable, the numbers of variable in + check btc report function will out of maximum variable numbers. And + most of these variable are using only one time, it is not necessary + to store at memory. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230103140238.15601-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 190 ++++++++++-------------------- + 1 file changed, 60 insertions(+), 130 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 2cb7ed1636030..a594f5c729608 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -910,76 +910,6 @@ static void _update_bt_report(struct rtw89_dev *rtwdev, u8 rpt_type, u8 *pfinfo) + } + } + +-struct rtw89_btc_fbtc_cysta_cpu { +- u8 fver; +- u8 rsvd; +- u16 cycles; +- u16 cycles_a2dp[CXT_FLCTRL_MAX]; +- u16 a2dpept; +- u16 a2dpeptto; +- u16 tavg_cycle[CXT_MAX]; +- u16 tmax_cycle[CXT_MAX]; +- u16 tmaxdiff_cycle[CXT_MAX]; +- u16 tavg_a2dp[CXT_FLCTRL_MAX]; +- u16 tmax_a2dp[CXT_FLCTRL_MAX]; +- u16 tavg_a2dpept; +- u16 tmax_a2dpept; +- u16 tavg_lk; +- u16 tmax_lk; +- u32 slot_cnt[CXST_MAX]; +- u32 bcn_cnt[CXBCN_MAX]; +- u32 leakrx_cnt; +- u32 collision_cnt; +- u32 skip_cnt; +- u32 exception; +- u32 except_cnt; +- u16 tslot_cycle[BTC_CYCLE_SLOT_MAX]; +-}; +- +-static void rtw89_btc_fbtc_cysta_to_cpu(const struct rtw89_btc_fbtc_cysta *src, +- struct rtw89_btc_fbtc_cysta_cpu *dst) +-{ +- static_assert(sizeof(*src) == sizeof(*dst)); +- +-#define __CPY_U8(_x) ({dst->_x = src->_x; }) +-#define __CPY_LE16(_x) ({dst->_x = le16_to_cpu(src->_x); }) +-#define __CPY_LE16S(_x) ({int _i; for (_i = 0; _i < ARRAY_SIZE(dst->_x); _i++) \ +- dst->_x[_i] = le16_to_cpu(src->_x[_i]); }) +-#define __CPY_LE32(_x) ({dst->_x = le32_to_cpu(src->_x); }) +-#define __CPY_LE32S(_x) ({int _i; for (_i = 0; _i < ARRAY_SIZE(dst->_x); _i++) \ +- dst->_x[_i] = le32_to_cpu(src->_x[_i]); }) +- +- __CPY_U8(fver); +- __CPY_U8(rsvd); +- __CPY_LE16(cycles); +- __CPY_LE16S(cycles_a2dp); +- __CPY_LE16(a2dpept); +- __CPY_LE16(a2dpeptto); +- __CPY_LE16S(tavg_cycle); +- __CPY_LE16S(tmax_cycle); +- __CPY_LE16S(tmaxdiff_cycle); +- __CPY_LE16S(tavg_a2dp); +- __CPY_LE16S(tmax_a2dp); +- __CPY_LE16(tavg_a2dpept); +- __CPY_LE16(tmax_a2dpept); +- __CPY_LE16(tavg_lk); +- __CPY_LE16(tmax_lk); +- __CPY_LE32S(slot_cnt); +- __CPY_LE32S(bcn_cnt); +- __CPY_LE32(leakrx_cnt); +- __CPY_LE32(collision_cnt); +- __CPY_LE32(skip_cnt); +- __CPY_LE32(exception); +- __CPY_LE32(except_cnt); +- __CPY_LE16S(tslot_cycle); +- +-#undef __CPY_U8 +-#undef __CPY_LE16 +-#undef __CPY_LE16S +-#undef __CPY_LE32 +-#undef __CPY_LE32S +-} +- + #define BTC_LEAK_AP_TH 10 + #define BTC_CYSTA_CHK_PERIOD 100 + +@@ -1002,9 +932,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + struct rtw89_btc_bt_info *bt = &btc->cx.bt; + struct rtw89_btc_fbtc_rpt_ctrl *prpt; + struct rtw89_btc_fbtc_rpt_ctrl_v1 *prpt_v1; +- struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; ++ struct rtw89_btc_fbtc_cysta *pcysta = NULL; + struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1 = NULL; +- struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; + struct rtw89_btc_prpt *btc_prpt = NULL; + void *rpt_content = NULL, *pfinfo = NULL; + u8 rpt_type = 0; +@@ -1066,8 +995,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; + if (chip->chip_id == RTL8852A) { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo; +- pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; +- rtw89_btc_fbtc_cysta_to_cpu(pcysta_le32, pcysta); ++ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; + pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo); + } else { + pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo_v1; +@@ -1259,13 +1187,13 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + break; + case BTC_RPT_TYPE_CYSTA: + if (chip->chip_id == RTL8852A) { +- if (pcysta->cycles < BTC_CYSTA_CHK_PERIOD) ++ if (le16_to_cpu(pcysta->cycles) < BTC_CYSTA_CHK_PERIOD) + break; + /* Check Leak-AP */ +- if (pcysta->slot_cnt[CXST_LK] != 0 && +- pcysta->leakrx_cnt != 0 && dm->tdma_now.rxflctrl) { +- if (pcysta->slot_cnt[CXST_LK] < +- BTC_LEAK_AP_TH * pcysta->leakrx_cnt) ++ if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) != 0 && ++ le32_to_cpu(pcysta->leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) { ++ if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) < ++ BTC_LEAK_AP_TH * le32_to_cpu(pcysta->leakrx_cnt)) + dm->leak_ap = 1; + } + +@@ -1276,18 +1204,18 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + else + wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); + +- if (pcysta->tavg_cycle[CXT_WL] > wl_slot_set) { +- diff_t = pcysta->tavg_cycle[CXT_WL] - wl_slot_set; ++ if (le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) > wl_slot_set) { ++ diff_t = le16_to_cpu(pcysta->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_FREEZE, +- pcysta->slot_cnt[CXST_W1]); ++ le32_to_cpu(pcysta->slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, +- pcysta->slot_cnt[CXST_B1]); ++ le32_to_cpu(pcysta->slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, +- (u32)pcysta->cycles); ++ le16_to_cpu(pcysta->cycles)); + } else { + if (le16_to_cpu(pcysta_v1->cycles) < BTC_CYSTA_CHK_PERIOD) + break; +@@ -6385,7 +6313,6 @@ static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.link_info.a2dp_desc; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; +- struct rtw89_btc_fbtc_cysta_cpu pcysta[1]; + union rtw89_btc_fbtc_rxflct r; + u8 i, cnt = 0, slot_pair; + u16 cycle, c_begin, c_end, store_index; +@@ -6395,64 +6322,65 @@ static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) + return; + + pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; +- rtw89_btc_fbtc_cysta_to_cpu(pcysta_le32, pcysta); + seq_printf(m, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", +- "[cycle_cnt]", pcysta->cycles, pcysta->bcn_cnt[CXBCN_ALL], +- pcysta->bcn_cnt[CXBCN_ALL_OK], +- pcysta->bcn_cnt[CXBCN_BT_SLOT], +- pcysta->bcn_cnt[CXBCN_BT_OK]); ++ "[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 (!pcysta->slot_cnt[i]) ++ if (!le32_to_cpu(pcysta_le32->slot_cnt[i])) + continue; +- seq_printf(m, +- ", %d:%d", (u32)i, pcysta->slot_cnt[i]); ++ seq_printf(m, ", %d:%d", (u32)i, ++ le32_to_cpu(pcysta_le32->slot_cnt[i])); + } + + if (dm->tdma_now.rxflctrl) { +- seq_printf(m, +- ", leak_rx:%d", pcysta->leakrx_cnt); ++ seq_printf(m, ", leak_rx:%d", ++ le32_to_cpu(pcysta_le32->leakrx_cnt)); + } + +- if (pcysta->collision_cnt) { +- seq_printf(m, +- ", collision:%d", pcysta->collision_cnt); ++ if (le32_to_cpu(pcysta_le32->collision_cnt)) { ++ seq_printf(m, ", collision:%d", ++ le32_to_cpu(pcysta_le32->collision_cnt)); + } + +- if (pcysta->skip_cnt) { +- seq_printf(m, +- ", skip:%d", pcysta->skip_cnt); ++ if (le32_to_cpu(pcysta_le32->skip_cnt)) { ++ seq_printf(m, ", skip:%d", ++ le32_to_cpu(pcysta_le32->skip_cnt)); + } + seq_puts(m, "\n"); + + seq_printf(m, " %-15s : avg_t[wl:%d/bt:%d/lk:%d.%03d]", + "[cycle_time]", +- pcysta->tavg_cycle[CXT_WL], +- pcysta->tavg_cycle[CXT_BT], +- pcysta->tavg_lk / 1000, pcysta->tavg_lk % 1000); +- seq_printf(m, +- ", max_t[wl:%d/bt:%d/lk:%d.%03d]", +- pcysta->tmax_cycle[CXT_WL], +- pcysta->tmax_cycle[CXT_BT], +- pcysta->tmax_lk / 1000, pcysta->tmax_lk % 1000); +- seq_printf(m, +- ", maxdiff_t[wl:%d/bt:%d]\n", +- pcysta->tmaxdiff_cycle[CXT_WL], +- pcysta->tmaxdiff_cycle[CXT_BT]); +- +- if (pcysta->cycles == 0) ++ 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); ++ seq_printf(m, ", 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); ++ seq_printf(m, ", 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) == 0) + return; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ + slot_pair = BTC_CYCLE_SLOT_MAX / 2; + +- if (pcysta->cycles <= slot_pair) ++ if (le16_to_cpu(pcysta_le32->cycles) <= slot_pair) + c_begin = 1; + else +- c_begin = pcysta->cycles - slot_pair + 1; ++ c_begin = le16_to_cpu(pcysta_le32->cycles) - slot_pair + 1; + +- c_end = pcysta->cycles; ++ c_end = le16_to_cpu(pcysta_le32->cycles); + + for (cycle = c_begin; cycle <= c_end; cycle++) { + cnt++; +@@ -6461,13 +6389,13 @@ static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) + if (cnt % (BTC_CYCLE_SLOT_MAX / 4) == 1) + seq_printf(m, + " %-15s : ->b%02d->w%02d", "[cycle_step]", +- pcysta->tslot_cycle[store_index], +- pcysta->tslot_cycle[store_index + 1]); ++ le16_to_cpu(pcysta_le32->tslot_cycle[store_index]), ++ le16_to_cpu(pcysta_le32->tslot_cycle[store_index + 1])); + else + seq_printf(m, + "->b%02d->w%02d", +- pcysta->tslot_cycle[store_index], +- pcysta->tslot_cycle[store_index + 1]); ++ 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) + seq_puts(m, "\n"); + } +@@ -6476,28 +6404,30 @@ static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) + seq_printf(m, + " %-15s : a2dp_ept:%d, a2dp_late:%d", + "[a2dp_t_sta]", +- pcysta->a2dpept, pcysta->a2dpeptto); ++ le16_to_cpu(pcysta_le32->a2dpept), ++ le16_to_cpu(pcysta_le32->a2dpeptto)); + + seq_printf(m, + ", avg_t:%d, max_t:%d", +- pcysta->tavg_a2dpept, pcysta->tmax_a2dpept); ++ 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) { + seq_printf(m, + ", cycle[PSTDMA:%d/TDMA:%d], ", +- pcysta->cycles_a2dp[CXT_FLCTRL_ON], +- pcysta->cycles_a2dp[CXT_FLCTRL_OFF]); ++ le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_ON]), ++ le16_to_cpu(pcysta_le32->cycles_a2dp[CXT_FLCTRL_OFF])); + + seq_printf(m, + "avg_t[PSTDMA:%d/TDMA:%d], ", +- pcysta->tavg_a2dp[CXT_FLCTRL_ON], +- pcysta->tavg_a2dp[CXT_FLCTRL_OFF]); ++ le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_ON]), ++ le16_to_cpu(pcysta_le32->tavg_a2dp[CXT_FLCTRL_OFF])); + + seq_printf(m, + "max_t[PSTDMA:%d/TDMA:%d]", +- pcysta->tmax_a2dp[CXT_FLCTRL_ON], +- pcysta->tmax_a2dp[CXT_FLCTRL_OFF]); ++ le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_ON]), ++ le16_to_cpu(pcysta_le32->tmax_a2dp[CXT_FLCTRL_OFF])); + } + seq_puts(m, "\n"); + } +-- +2.13.6 + diff --git a/SOURCES/0095-wifi-rtw89-coex-Rename-BTC-firmware-cycle-report-by-.patch b/SOURCES/0095-wifi-rtw89-coex-Rename-BTC-firmware-cycle-report-by-.patch new file mode 100644 index 0000000..b7de04d --- /dev/null +++ b/SOURCES/0095-wifi-rtw89-coex-Rename-BTC-firmware-cycle-report-by-.patch @@ -0,0 +1,323 @@ +From 7f76d7d4b39317867e2e177b5b8d2395122d8aa6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:34 +0200 +Subject: [PATCH 095/142] wifi: rtw89: coex: Rename BTC firmware cycle report + by feature version +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit fab895b31982f8093afe807cb0a69805aaa97850 +Author: Ching-Te Ku +Date: Tue Jan 3 22:02:33 2023 +0800 + + wifi: rtw89: coex: Rename BTC firmware cycle report by feature version + + Because there are new report format in the upcoming patches, to make the + logic more readable, rename the related structure by their version number. + And to support the several version at the same time, add union definition + to include all the versions. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230103140238.15601-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 107 ++++++++++++++++-------------- + drivers/net/wireless/realtek/rtw89/core.h | 14 ++-- + 2 files changed, 64 insertions(+), 57 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index a594f5c729608..be5ab2c4eefb3 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -932,8 +932,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + struct rtw89_btc_bt_info *bt = &btc->cx.bt; + struct rtw89_btc_fbtc_rpt_ctrl *prpt; + struct rtw89_btc_fbtc_rpt_ctrl_v1 *prpt_v1; +- struct rtw89_btc_fbtc_cysta *pcysta = NULL; +- struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1 = 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; +@@ -993,14 +992,17 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + break; + case BTC_RPT_TYPE_CYSTA: + pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; +- if (chip->chip_id == RTL8852A) { +- pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo; +- pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo); ++ 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); ++ } 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); + } else { +- pfinfo = &pfwinfo->rpt_fbtc_cysta.finfo_v1; +- pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_cysta.finfo_v1); ++ goto err; + } + pcinfo->req_fver = ver->fcxcysta; + break; +@@ -1186,14 +1188,14 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + sizeof(dm->slot_now))); + break; + case BTC_RPT_TYPE_CYSTA: +- if (chip->chip_id == RTL8852A) { +- if (le16_to_cpu(pcysta->cycles) < BTC_CYSTA_CHK_PERIOD) ++ if (ver->fcxcysta == 2) { ++ if (le16_to_cpu(pcysta->v2.cycles) < BTC_CYSTA_CHK_PERIOD) + break; + /* Check Leak-AP */ +- if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) != 0 && +- le32_to_cpu(pcysta->leakrx_cnt) != 0 && dm->tdma_now.rxflctrl) { +- if (le32_to_cpu(pcysta->slot_cnt[CXST_LK]) < +- BTC_LEAK_AP_TH * le32_to_cpu(pcysta->leakrx_cnt)) ++ 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; + } + +@@ -1204,24 +1206,24 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + else + wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); + +- if (le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) > wl_slot_set) { +- diff_t = le16_to_cpu(pcysta->tavg_cycle[CXT_WL]) - wl_slot_set; ++ 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_FREEZE, +- le32_to_cpu(pcysta->slot_cnt[CXST_W1])); ++ le32_to_cpu(pcysta->v2.slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, +- le32_to_cpu(pcysta->slot_cnt[CXST_B1])); ++ le32_to_cpu(pcysta->v2.slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, +- le16_to_cpu(pcysta->cycles)); +- } else { +- if (le16_to_cpu(pcysta_v1->cycles) < BTC_CYSTA_CHK_PERIOD) ++ 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_v1->slot_cnt[CXST_LK]); +- cnt_rx_imr = le32_to_cpu(pcysta_v1->leak_slot.cnt_rximr); ++ 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 && +@@ -1233,7 +1235,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + /* Check diff time between real WL slot and W1 slot */ + if (dm->tdma_now.type == CXTDMA_OFF) { + wl_slot_set = le16_to_cpu(dm->slot_now[CXST_W1].dur); +- wl_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_WL]); ++ 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); +@@ -1244,8 +1246,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + if (dm->tdma_now.type == CXTDMA_OFF && + dm->tdma_now.ext_ctrl == CXECTL_EXT && + btc->bt_req_len != 0) { +- bt_slot_real = le16_to_cpu(pcysta_v1->cycle_time.tavg[CXT_BT]); +- ++ bt_slot_real = le16_to_cpu(pcysta->v3.cycle_time.tavg[CXT_BT]); + if (btc->bt_req_len > bt_slot_real) { + diff_t = btc->bt_req_len - bt_slot_real; + _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); +@@ -1253,11 +1254,13 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + } + + _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, +- le32_to_cpu(pcysta_v1->slot_cnt[CXST_W1])); ++ le32_to_cpu(pcysta->v3.slot_cnt[CXST_W1])); + _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, +- le32_to_cpu(pcysta_v1->slot_cnt[CXST_B1])); ++ le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, +- (u32)le16_to_cpu(pcysta_v1->cycles)); ++ le16_to_cpu(pcysta->v3.cycles)); ++ } else { ++ goto err; + } + break; + case BTC_RPT_TYPE_BT_VER: +@@ -6160,21 +6163,23 @@ static void _show_dm_info(struct rtw89_dev *rtwdev, struct seq_file *m) + + static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) + { +- 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_btf_fwinfo *pfwinfo = &btc->fwinfo; +- struct rtw89_btc_fbtc_cysta *pcysta; +- struct rtw89_btc_fbtc_cysta_v1 *pcysta_v1; ++ union rtw89_btc_fbtc_cysta_info *pcysta; + u32 except_cnt, exception_map; + +- if (chip->chip_id == RTL8852A) { +- pcysta = &pfwinfo->rpt_fbtc_cysta.finfo; +- except_cnt = le32_to_cpu(pcysta->except_cnt); +- exception_map = le32_to_cpu(pcysta->exception); ++ 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 { +- pcysta_v1 = &pfwinfo->rpt_fbtc_cysta.finfo_v1; +- except_cnt = le32_to_cpu(pcysta_v1->except_cnt); +- exception_map = le32_to_cpu(pcysta_v1->except_map); ++ return; + } + + if (pfwinfo->event[BTF_EVNT_BUF_OVERFLOW] == 0 && except_cnt == 0 && +@@ -6305,14 +6310,14 @@ static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) + } + } + +-static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) ++static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) + { + 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.bt.link_info.a2dp_desc; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; +- struct rtw89_btc_fbtc_cysta *pcysta_le32 = NULL; ++ struct rtw89_btc_fbtc_cysta_v2 *pcysta_le32 = NULL; + union rtw89_btc_fbtc_rxflct r; + u8 i, cnt = 0, slot_pair; + u16 cycle, c_begin, c_end, store_index; +@@ -6321,7 +6326,7 @@ static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) + if (!pcinfo->valid) + return; + +- pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo; ++ pcysta_le32 = &pfwinfo->rpt_fbtc_cysta.finfo.v2; + seq_printf(m, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", +@@ -6433,14 +6438,14 @@ static void _show_fbtc_cysta(struct rtw89_dev *rtwdev, struct seq_file *m) + } + } + +-static void _show_fbtc_cysta_v1(struct rtw89_dev *rtwdev, struct seq_file *m) ++static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) + { + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.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_v1 *pcysta; ++ 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; +@@ -6449,7 +6454,7 @@ static void _show_fbtc_cysta_v1(struct rtw89_dev *rtwdev, struct seq_file *m) + if (!pcinfo->valid) + return; + +- pcysta = &pfwinfo->rpt_fbtc_cysta.finfo_v1; ++ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v3; + seq_printf(m, + " %-15s : cycle:%d, bcn[all:%d/all_ok:%d/bt:%d/bt_ok:%d]", + "[cycle_cnt]", +@@ -6708,8 +6713,8 @@ static void _show_fbtc_step(struct rtw89_dev *rtwdev, struct seq_file *m) + + static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) + { +- const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_btc *btc = &rtwdev->btc; ++ const struct rtw89_btc_ver *ver = btc->ver; + + if (!(btc->dm.coex_info_map & BTC_COEX_INFO_DM)) + return; +@@ -6718,10 +6723,10 @@ static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) + _show_fbtc_tdma(rtwdev, m); + _show_fbtc_slots(rtwdev, m); + +- if (chip->chip_id == RTL8852A) +- _show_fbtc_cysta(rtwdev, m); +- else +- _show_fbtc_cysta_v1(rtwdev, m); ++ if (ver->fcxcysta == 2) ++ _show_fbtc_cysta_v2(rtwdev, m); ++ else if (ver->fcxcysta == 3) ++ _show_fbtc_cysta_v3(rtwdev, m); + + _show_fbtc_nullsta(rtwdev, m); + _show_fbtc_step(rtwdev, m); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 04450a4938cad..6af70eabb9080 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1681,7 +1681,7 @@ struct rtw89_btc_fbtc_steps_v1 { + struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; + } __packed; + +-struct rtw89_btc_fbtc_cysta { /* statistics for cycles */ ++struct rtw89_btc_fbtc_cysta_v2 { /* statistics for cycles */ + u8 fver; /* btc_ver::fcxcysta */ + u8 rsvd; + __le16 cycles; /* total cycle number */ +@@ -1743,7 +1743,7 @@ struct rtw89_btc_fbtc_cycle_leak_info { + __le16 tmax; /* max leak-slot time */ + } __packed; + +-struct rtw89_btc_fbtc_cysta_v1 { /* statistics for cycles */ ++struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */ + u8 fver; + u8 rsvd; + __le16 cycles; /* total cycle number */ +@@ -1761,6 +1761,11 @@ struct rtw89_btc_fbtc_cysta_v1 { /* statistics for cycles */ + __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_cynullsta { /* cycle null statistics */ + u8 fver; /* btc_ver::fcxnullsta */ + u8 rsvd; +@@ -1961,10 +1966,7 @@ struct rtw89_btc_rpt_fbtc_slots { + + struct rtw89_btc_rpt_fbtc_cysta { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ +- union { +- struct rtw89_btc_fbtc_cysta finfo; /* info from fw for 52A*/ +- struct rtw89_btc_fbtc_cysta_v1 finfo_v1; /* info from fw for 52C*/ +- }; ++ union rtw89_btc_fbtc_cysta_info finfo; + }; + + struct rtw89_btc_rpt_fbtc_step { +-- +2.13.6 + diff --git a/SOURCES/0096-wifi-rtw89-coex-Add-v4-version-firmware-cycle-report.patch b/SOURCES/0096-wifi-rtw89-coex-Add-v4-version-firmware-cycle-report.patch new file mode 100644 index 0000000..d09c7eb --- /dev/null +++ b/SOURCES/0096-wifi-rtw89-coex-Add-v4-version-firmware-cycle-report.patch @@ -0,0 +1,356 @@ +From 0f546e1925b08b58052d8016abae821586d6117b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:34 +0200 +Subject: [PATCH 096/142] wifi: rtw89: coex: Add v4 version firmware cycle + report +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 202c3b5c276f3f7525d9baabea7e8896d300ceff +Author: Ching-Te Ku +Date: Tue Jan 3 22:02:34 2023 +0800 + + wifi: rtw89: coex: Add v4 version firmware cycle report + + To support v4 version firmware cycle report, apply the related + structure and functions. v4 cycle report add a group of status + to show how the free-run/TDMA training goes to. It is a firmware + mechanism that can auto adjust coexistence mode between TDMA and + free run mechanism at 3 antenna solution. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230103140238.15601-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 185 ++++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/core.h | 67 +++++++++++ + 2 files changed, 252 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index be5ab2c4eefb3..b25329d1806a4 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -1001,6 +1001,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + 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); ++ } 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); + } else { + goto err; + } +@@ -1259,6 +1263,48 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + le32_to_cpu(pcysta->v3.slot_cnt[CXST_B1])); + _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, + 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) { ++ wl_slot_set = le16_to_cpu(dm->slot_now[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 != 0) { ++ bt_slot_real = le16_to_cpu(pcysta->v4.cycle_time.tavg[CXT_BT]); ++ ++ if (btc->bt_req_len > bt_slot_real) { ++ diff_t = btc->bt_req_len - bt_slot_real; ++ _chk_btc_err(rtwdev, BTC_DCNT_BT_SLOT_DRIFT, diff_t); ++ } ++ } ++ ++ _chk_btc_err(rtwdev, BTC_DCNT_W1_FREEZE, ++ le16_to_cpu(pcysta->v4.slot_cnt[CXST_W1])); ++ _chk_btc_err(rtwdev, BTC_DCNT_B1_FREEZE, ++ le16_to_cpu(pcysta->v4.slot_cnt[CXST_B1])); ++ _chk_btc_err(rtwdev, BTC_DCNT_CYCLE_FREEZE, ++ le16_to_cpu(pcysta->v4.cycles)); + } else { + goto err; + } +@@ -6178,6 +6224,10 @@ static void _show_error(struct rtw89_dev *rtwdev, struct seq_file *m) + 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 { + return; + } +@@ -6569,6 +6619,139 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) + } + } + ++static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ struct rtw89_btc *btc = &rtwdev->btc; ++ struct rtw89_btc_bt_a2dp_desc *a2dp = &btc->cx.bt.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; ++ ++ pcinfo = &pfwinfo->rpt_fbtc_cysta.cinfo; ++ if (!pcinfo->valid) ++ return; ++ ++ pcysta = &pfwinfo->rpt_fbtc_cysta.finfo.v4; ++ seq_printf(m, ++ " %-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; ++ ++ seq_printf(m, ", %s:%d", id_to_slot(i), ++ le16_to_cpu(pcysta->slot_cnt[i])); ++ } ++ ++ if (dm->tdma_now.rxflctrl) ++ seq_printf(m, ", leak_rx:%d", ++ le32_to_cpu(pcysta->leak_slot.cnt_rximr)); ++ ++ if (pcysta->collision_cnt) ++ seq_printf(m, ", collision:%d", pcysta->collision_cnt); ++ ++ if (le16_to_cpu(pcysta->skip_cnt)) ++ seq_printf(m, ", skip:%d", ++ le16_to_cpu(pcysta->skip_cnt)); ++ ++ seq_puts(m, "\n"); ++ ++ seq_printf(m, " %-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); ++ seq_printf(m, ++ ", 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); ++ seq_printf(m, ++ ", 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 == 0) ++ return; ++ ++ /* 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) { ++ seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); ++ } else { ++ seq_printf(m, "->b%02d", ++ le16_to_cpu(pcysta->slot_step_time[store_index])); ++ if (a2dp->exist) { ++ a2dp_trx = &pcysta->a2dp_trx[store_index]; ++ seq_printf(m, "(%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); ++ } ++ seq_printf(m, "->w%02d", ++ le16_to_cpu(pcysta->slot_step_time[store_index + 1])); ++ if (a2dp->exist) { ++ a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; ++ seq_printf(m, "(%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 % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) ++ seq_puts(m, "\n"); ++ } ++ ++ if (a2dp->exist) { ++ seq_printf(m, "%-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)); ++ ++ seq_printf(m, ", avg_t:%d, max_t:%d", ++ le16_to_cpu(pcysta->a2dp_ept.tavg), ++ le16_to_cpu(pcysta->a2dp_ept.tmax)); ++ ++ seq_puts(m, "\n"); ++ } ++} ++ + static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) + { + const struct rtw89_chip_info *chip = rtwdev->chip; +@@ -6727,6 +6910,8 @@ static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) + _show_fbtc_cysta_v2(rtwdev, m); + else if (ver->fcxcysta == 3) + _show_fbtc_cysta_v3(rtwdev, m); ++ else if (ver->fcxcysta == 4) ++ _show_fbtc_cysta_v4(rtwdev, m); + + _show_fbtc_nullsta(rtwdev, m); + _show_fbtc_step(rtwdev, m); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 6af70eabb9080..9f4cb83a8326f 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1730,6 +1730,17 @@ struct rtw89_btc_fbtc_a2dp_trx_stat { + 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*/ +@@ -1743,6 +1754,34 @@ struct rtw89_btc_fbtc_cycle_leak_info { + __le16 tmax; /* max leak-slot time */ + } __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_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; +@@ -1761,9 +1800,37 @@ struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */ + __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; ++ + 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_cynullsta { /* cycle null statistics */ +-- +2.13.6 + diff --git a/SOURCES/0097-wifi-rtw89-coex-Change-firmware-control-report-to-ve.patch b/SOURCES/0097-wifi-rtw89-coex-Change-firmware-control-report-to-ve.patch new file mode 100644 index 0000000..c1baf6b --- /dev/null +++ b/SOURCES/0097-wifi-rtw89-coex-Change-firmware-control-report-to-ve.patch @@ -0,0 +1,263 @@ +From cccdf6b4a31c2f1adc4fe88280118da42c6bfdb6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:34 +0200 +Subject: [PATCH 097/142] wifi: rtw89: coex: Change firmware control report to + version separate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit b02e3f5c344d62da86afbc6444638a9beb375f2e +Author: Ching-Te Ku +Date: Tue Jan 3 22:02:35 2023 +0800 + + wifi: rtw89: coex: Change firmware control report to version separate + + The rtw89 driver may support more than 1 version of Wi-Fi firmware for + certain chips. In order to support all the firmware, change to select logic + by firmware feature version code. Type control version 4 will monitor + Bluetooth PTA hardware counters at firmware and C2H to driver, but + version 1 will not do this. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230103140238.15601-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 76 ++++++++++++++++--------------- + drivers/net/wireless/realtek/rtw89/core.h | 14 +++--- + 2 files changed, 48 insertions(+), 42 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index b25329d1806a4..e5aa0d663cdd6 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -930,8 +930,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; +- struct rtw89_btc_fbtc_rpt_ctrl *prpt; +- struct rtw89_btc_fbtc_rpt_ctrl_v1 *prpt_v1; ++ 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; +@@ -962,12 +961,15 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + switch (rpt_type) { + case BTC_RPT_TYPE_CTRL: + pcinfo = &pfwinfo->rpt_ctrl.cinfo; +- if (chip->chip_id == RTL8852A) { +- pfinfo = &pfwinfo->rpt_ctrl.finfo; +- pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo); ++ prpt = &pfwinfo->rpt_ctrl.finfo; ++ if (ver->fcxbtcrpt == 1) { ++ pfinfo = &pfwinfo->rpt_ctrl.finfo.v1; ++ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v1); ++ } else if (ver->fcxbtcrpt == 4) { ++ pfinfo = &pfwinfo->rpt_ctrl.finfo.v4; ++ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v4); + } else { +- pfinfo = &pfwinfo->rpt_ctrl.finfo_v1; +- pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo_v1); ++ goto err; + } + pcinfo->req_fver = ver->fcxbtcrpt; + break; +@@ -1109,12 +1111,12 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + + switch (rpt_type) { + case BTC_RPT_TYPE_CTRL: +- if (chip->chip_id == RTL8852A) { +- prpt = &pfwinfo->rpt_ctrl.finfo; +- btc->fwinfo.rpt_en_map = prpt->rpt_enable; +- wl->ver_info.fw_coex = prpt->wl_fw_coex_ver; +- wl->ver_info.fw = prpt->wl_fw_ver; +- dm->wl_fw_cx_offload = !!prpt->wl_fw_cx_offload; ++ 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_FREEZE, + pfwinfo->event[BTF_EVNT_RPT]); +@@ -1129,38 +1131,40 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + rtw89_mac_get_plt_cnt(rtwdev, + RTW89_MAC_0); + } +- } else { +- prpt_v1 = &pfwinfo->rpt_ctrl.finfo_v1; +- btc->fwinfo.rpt_en_map = le32_to_cpu(prpt_v1->rpt_info.en); +- wl->ver_info.fw_coex = le32_to_cpu(prpt_v1->wl_fw_info.cx_ver); +- wl->ver_info.fw = le32_to_cpu(prpt_v1->wl_fw_info.fw_ver); +- dm->wl_fw_cx_offload = !!le32_to_cpu(prpt_v1->wl_fw_info.cx_offload); ++ } 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_MAX; i++) +- memcpy(&dm->gnt.band[i], &prpt_v1->gnt_val[i], ++ memcpy(&dm->gnt.band[i], &prpt->v4.gnt_val[i], + sizeof(dm->gnt.band[i])); + + btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = +- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_TX]); ++ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_TX]); + btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = +- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_HI_RX]); ++ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_RX]); + btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = +- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_TX]); ++ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_TX]); + btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = +- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_LO_RX]); ++ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_RX]); + btc->cx.cnt_bt[BTC_BCNT_POLUT] = +- le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_POLLUTED]); ++ le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_POLLUTED]); + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, + pfwinfo->event[BTF_EVNT_RPT]); + +- if (le32_to_cpu(prpt_v1->bt_cnt[BTC_BCNT_RFK_TIMEOUT]) > 0) ++ 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 { ++ goto err; + } + break; + case BTC_RPT_TYPE_TDMA: +@@ -7061,12 +7065,12 @@ static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) + seq_puts(m, "\n"); + } + +-static void _show_summary(struct rtw89_dev *rtwdev, struct seq_file *m) ++static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) + { + 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 *prptctrl = 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; +@@ -7081,7 +7085,7 @@ static void _show_summary(struct rtw89_dev *rtwdev, struct seq_file *m) + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { +- prptctrl = &pfwinfo->rpt_ctrl.finfo; ++ prptctrl = &pfwinfo->rpt_ctrl.finfo.v1; + + seq_printf(m, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", +@@ -7165,11 +7169,11 @@ static void _show_summary(struct rtw89_dev *rtwdev, struct seq_file *m) + cnt[BTC_NCNT_CUSTOMERIZE]); + } + +-static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) ++static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m) + { + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; +- struct rtw89_btc_fbtc_rpt_ctrl_v1 *prptctrl; ++ 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; +@@ -7185,7 +7189,7 @@ static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { +- prptctrl = &pfwinfo->rpt_ctrl.finfo_v1; ++ prptctrl = &pfwinfo->rpt_ctrl.finfo.v4; + + seq_printf(m, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d), ", +@@ -7279,9 +7283,9 @@ static void _show_summary_v1(struct rtw89_dev *rtwdev, struct seq_file *m) + + void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) + { +- const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; + 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 = &cx->bt; + +@@ -7310,10 +7314,10 @@ void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) + _show_dm_info(rtwdev, m); + _show_fw_dm_msg(rtwdev, m); + _show_mreg(rtwdev, m); +- if (chip->chip_id == RTL8852A) +- _show_summary(rtwdev, m); +- else ++ if (ver->fcxbtcrpt == 1) + _show_summary_v1(rtwdev, m); ++ else if (ver->fcxbtcrpt == 4) ++ _show_summary_v4(rtwdev, m); + } + + void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 9f4cb83a8326f..384eb9cb92240 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1480,7 +1480,7 @@ enum rtw89_btc_bt_sta_counter { + BTC_BCNT_STA_MAX + }; + +-struct rtw89_btc_fbtc_rpt_ctrl { ++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 */ +@@ -1533,7 +1533,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox { + struct rtw89_btc_fbtc_rpt_ctrl_a2dp_empty a2dp; + } __packed; + +-struct rtw89_btc_fbtc_rpt_ctrl_v1 { ++struct rtw89_btc_fbtc_rpt_ctrl_v4 { + u8 fver; + u8 rsvd; + __le16 rsvd1; +@@ -1544,6 +1544,11 @@ struct rtw89_btc_fbtc_rpt_ctrl_v1 { + struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_MAX]; + } __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; ++}; ++ + enum rtw89_fbtc_ext_ctrl_type { + CXECTL_OFF = 0x0, /* tdma off */ + CXECTL_B2 = 0x1, /* allow B2 (beacon-early) */ +@@ -2015,10 +2020,7 @@ union rtw89_btc_fbtc_btafh_info { + + struct rtw89_btc_report_ctrl_state { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ +- union { +- struct rtw89_btc_fbtc_rpt_ctrl finfo; /* info from fw for 52A*/ +- struct rtw89_btc_fbtc_rpt_ctrl_v1 finfo_v1; /* info from fw for 52C*/ +- }; ++ union rtw89_btc_fbtc_rpt_ctrl_ver_info finfo; + }; + + struct rtw89_btc_rpt_fbtc_tdma { +-- +2.13.6 + diff --git a/SOURCES/0098-wifi-rtw89-coex-Add-v5-firmware-control-report.patch b/SOURCES/0098-wifi-rtw89-coex-Add-v5-firmware-control-report.patch new file mode 100644 index 0000000..683b76a --- /dev/null +++ b/SOURCES/0098-wifi-rtw89-coex-Add-v5-firmware-control-report.patch @@ -0,0 +1,262 @@ +From ca948c733764cc5e27c0b067e1186aa4a53af585 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:35 +0200 +Subject: [PATCH 098/142] wifi: rtw89: coex: Add v5 firmware control report +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 0c06fd47335ab9bbcbca250267eb22227e98ffa4 +Author: Ching-Te Ku +Date: Tue Jan 3 22:02:36 2023 +0800 + + wifi: rtw89: coex: Add v5 firmware control report + + Comparing v5 control report to v4 version, v5 reduce some of variable's + size to reduce firmware code size. And change the grant signal report + format. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230103140238.15601-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 148 ++++++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/core.h | 27 ++++++ + 2 files changed, 175 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index e5aa0d663cdd6..21d1011d50c9d 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -968,6 +968,9 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + } else if (ver->fcxbtcrpt == 4) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v4; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v4); ++ } else if (ver->fcxbtcrpt == 5) { ++ pfinfo = &pfwinfo->rpt_ctrl.finfo.v5; ++ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v5); + } else { + goto err; + } +@@ -1163,6 +1166,33 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + 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_MAX; i++) ++ memcpy(&dm->gnt.band[i], &prpt->v5.gnt_val[i][0], ++ sizeof(dm->gnt.band[i])); ++ ++ btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = ++ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_TX]); ++ btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = ++ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_RX]); ++ btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = ++ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_TX]); ++ btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = ++ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_RX]); ++ btc->cx.cnt_bt[BTC_BCNT_POLUT] = ++ le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_POLLUTED]); ++ ++ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_FREEZE, 0); ++ _chk_btc_err(rtwdev, BTC_DCNT_RPT_FREEZE, ++ pfwinfo->event[BTF_EVNT_RPT]); ++ ++ dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; + } else { + goto err; + } +@@ -7281,6 +7311,122 @@ static void _show_summary_v4(struct rtw89_dev *rtwdev, struct seq_file *m) + cnt[BTC_NCNT_CUSTOMERIZE]); + } + ++static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ 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; ++ u8 i; ++ ++ if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) ++ return; ++ ++ seq_puts(m, "========== [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; ++ ++ seq_printf(m, ++ " %-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)); ++ ++ seq_printf(m, ++ "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) ++ seq_puts(m, " (WL FW Hang!!)"); ++ seq_puts(m, "\n"); ++ seq_printf(m, ++ " %-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)); ++ ++ seq_printf(m, ++ "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)); ++ ++ seq_printf(m, ++ " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", ++ "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], ++ cx->cnt_wl[BTC_WCNT_RFK_GO], ++ cx->cnt_wl[BTC_WCNT_RFK_REJECT], ++ cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); ++ ++ seq_printf(m, ++ ", bt_rfk[req:%d]", ++ le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); ++ ++ seq_printf(m, ++ ", 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 { ++ seq_puts(m, "\n"); ++ seq_printf(m, ++ " %-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]) { ++ seq_puts(m, "\n"); ++ seq_printf(m, ++ " %-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]; ++ ++ seq_puts(m, "\n"); ++ seq_printf(m, ++ " %-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]); ++ ++ seq_printf(m, ++ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", ++ 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]); ++ ++ seq_puts(m, "\n"); ++ seq_printf(m, ++ " %-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]); ++ ++ seq_printf(m, ++ "timer=%d, control=%d, customerize=%d", ++ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], ++ cnt[BTC_NCNT_CUSTOMERIZE]); ++} ++ + void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) + { + struct rtw89_fw_suit *fw_suit = &rtwdev->fw.normal; +@@ -7318,6 +7464,8 @@ void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) + _show_summary_v1(rtwdev, m); + else if (ver->fcxbtcrpt == 4) + _show_summary_v4(rtwdev, m); ++ else if (ver->fcxbtcrpt == 5) ++ _show_summary_v5(rtwdev, m); + } + + void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 384eb9cb92240..d0b4c00324572 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1512,6 +1512,20 @@ struct rtw89_btc_fbtc_rpt_ctrl_info { + __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_wl_fw_info { + __le32 cx_ver; /* match which driver's coex version */ + __le32 cx_offload; +@@ -1544,9 +1558,22 @@ struct rtw89_btc_fbtc_rpt_ctrl_v4 { + struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_MAX]; + } __packed; + ++struct rtw89_btc_fbtc_rpt_ctrl_v5 { ++ u8 fver; ++ u8 rsvd; ++ __le16 rsvd1; ++ ++ u8 gnt_val[RTW89_PHY_MAX][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; ++ + 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; + }; + + enum rtw89_fbtc_ext_ctrl_type { +-- +2.13.6 + diff --git a/SOURCES/0099-wifi-rtw89-coex-only-read-Bluetooth-counter-of-repor.patch b/SOURCES/0099-wifi-rtw89-coex-only-read-Bluetooth-counter-of-repor.patch new file mode 100644 index 0000000..453dff7 --- /dev/null +++ b/SOURCES/0099-wifi-rtw89-coex-only-read-Bluetooth-counter-of-repor.patch @@ -0,0 +1,52 @@ +From f13c8d03a85b8c05ec921969d6eaf0b92b2168f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:35 +0200 +Subject: [PATCH 099/142] wifi: rtw89: coex: only read Bluetooth counter of + report version 1 for RTL8852A +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 891b6a3f9407965436136319ad81f03bbf97310d +Author: Ching-Te Ku +Date: Tue Jan 3 22:02:37 2023 +0800 + + wifi: rtw89: coex: only read Bluetooth counter of report version 1 for RTL8852A + + Only when firmware control report version is 1, need to get the counter by + reading the register. The other version will monitor the counter at + firmware. And upstream branch only RTL8852A has this old version. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230103140238.15601-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 1875c2537ddbd..1800a56091be4 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -1878,9 +1878,13 @@ 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->cnt_bt[BTC_BCNT_HIPRI_TX] = FIELD_GET(B_AX_STATIS_BT_HI_TX_MASK, val); + cx->cnt_bt[BTC_BCNT_HIPRI_RX] = FIELD_GET(B_AX_STATIS_BT_HI_RX_MASK, val); +-- +2.13.6 + diff --git a/SOURCES/0100-wifi-rtw89-coex-Update-WiFi-role-info-H2C-report.patch b/SOURCES/0100-wifi-rtw89-coex-Update-WiFi-role-info-H2C-report.patch new file mode 100644 index 0000000..2df20c1 --- /dev/null +++ b/SOURCES/0100-wifi-rtw89-coex-Update-WiFi-role-info-H2C-report.patch @@ -0,0 +1,174 @@ +From df4e46aa49418fbcb942607bf55f022619bd93a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:35 +0200 +Subject: [PATCH 100/142] wifi: rtw89: coex: Update WiFi role info H2C report +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3f625adc61a0f015c2ce982bc49a84e163094a0c +Author: Ching-Te Ku +Date: Tue Jan 3 22:02:38 2023 +0800 + + wifi: rtw89: coex: Update WiFi role info H2C report + + Change style to feature version separate. And because there are + different WiFi roles number in the firmware, it will make structure + length longer or shorter, so update the length calculator to cover + the difference. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230103140238.15601-8-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 7 +++--- + drivers/net/wireless/realtek/rtw89/fw.c | 36 ++++++++++++++++++++----------- + 2 files changed, 27 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 21d1011d50c9d..f97ddbcb51046 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -1772,16 +1772,17 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type, + + static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 type) + { +- const struct rtw89_chip_info *chip = rtwdev->chip; ++ struct rtw89_btc *btc = &rtwdev->btc; ++ const struct rtw89_btc_ver *ver = btc->ver; + + switch (type) { + case CXDRVINFO_INIT: + rtw89_fw_h2c_cxdrv_init(rtwdev); + break; + case CXDRVINFO_ROLE: +- if (chip->chip_id == RTL8852A) ++ if (ver->fwlrole == 0) + rtw89_fw_h2c_cxdrv_role(rtwdev); +- else ++ else if (ver->fwlrole == 1) + rtw89_fw_h2c_cxdrv_role_v1(rtwdev); + break; + case CXDRVINFO_CTRL: +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 466d8273bc2b1..98cfadda8f45e 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -1818,33 +1818,36 @@ int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev) + + #define PORT_DATA_OFFSET 4 + #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12 +-#define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_PORT_NUM + H2C_LEN_CXDRVHDR) +-#define H2C_LEN_CXDRVINFO_ROLE_V1 (4 + 16 * RTW89_PORT_NUM + \ +- H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + \ +- H2C_LEN_CXDRVHDR) ++#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) + { + 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 *role_info = &wl->role_info; + struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; + struct rtw89_btc_wl_active_role *active = role_info->active_role; + struct sk_buff *skb; ++ u32 len; + u8 offset = 0; + u8 *cmd; + int ret; + int i; + +- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE); ++ 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, H2C_LEN_CXDRVINFO_ROLE); ++ skb_put(skb, len); + cmd = skb->data; + + RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); +- RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); + + RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); + RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); +@@ -1881,7 +1884,7 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev) + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, +- H2C_LEN_CXDRVINFO_ROLE); ++ len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { +@@ -1896,28 +1899,35 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev) + 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) + { + 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_v1 *role_info = &wl->role_info_v1; + struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role; + struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1; + struct sk_buff *skb; ++ u32 len; + u8 *cmd, offset; + int ret; + int i; + +- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE_V1); ++ 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, H2C_LEN_CXDRVINFO_ROLE_V1); ++ skb_put(skb, len); + cmd = skb->data; + + RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE); +- RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVHDR); ++ RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR); + + RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt); + RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode); +@@ -1953,7 +1963,7 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev) + RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset); + } + +- offset = H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; ++ offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN; + RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset); + RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset); + RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset); +@@ -1964,7 +1974,7 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev) + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_OUTSRC, BTFC_SET, + SET_DRV_INFO, 0, 0, +- H2C_LEN_CXDRVINFO_ROLE_V1); ++ len); + + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { +-- +2.13.6 + diff --git a/SOURCES/0101-wifi-rtw89-coex-Add-version-code-for-Wi-Fi-firmware-.patch b/SOURCES/0101-wifi-rtw89-coex-Add-version-code-for-Wi-Fi-firmware-.patch new file mode 100644 index 0000000..bf943e0 --- /dev/null +++ b/SOURCES/0101-wifi-rtw89-coex-Add-version-code-for-Wi-Fi-firmware-.patch @@ -0,0 +1,58 @@ +From 937edfd0fa982b99920f180db92a44d7f06ef4b5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:35 +0200 +Subject: [PATCH 101/142] wifi: rtw89: coex: Add version code for Wi-Fi + firmware coexistence control +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 72f8b0461b4aa1b90248c36f3d2ea4a58074672e +Author: Ching-Te Ku +Date: Fri Jan 6 20:08:38 2023 +0800 + + wifi: rtw89: coex: Add version code for Wi-Fi firmware coexistence control + + The newer Wi-Fi firmware are all changed to "Not to send H2C to + mention firmware how many call flow step should firmware trace". + The structure had removed the member, and define the steps number + at newer version firmware. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106120844.17441-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 98cfadda8f45e..85c7172e931bf 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -1992,8 +1992,8 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev) + #define H2C_LEN_CXDRVINFO_CTRL (4 + H2C_LEN_CXDRVHDR) + int rtw89_fw_h2c_cxdrv_ctrl(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_ctrl *ctrl = &btc->ctrl; + struct sk_buff *skb; + u8 *cmd; +@@ -2013,7 +2013,7 @@ int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev) + 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 (chip->chip_id == RTL8852A) ++ if (ver->fcxctrl == 0) + RTW89_SET_FWCMD_CXCTRL_TRACE_STEP(cmd, ctrl->trace_step); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, +-- +2.13.6 + diff --git a/SOURCES/0102-wifi-rtw89-coex-Change-Wi-Fi-Null-data-report-to-ver.patch b/SOURCES/0102-wifi-rtw89-coex-Change-Wi-Fi-Null-data-report-to-ver.patch new file mode 100644 index 0000000..bfa3695 --- /dev/null +++ b/SOURCES/0102-wifi-rtw89-coex-Change-Wi-Fi-Null-data-report-to-ver.patch @@ -0,0 +1,197 @@ +From eaf6c270b5d5d1cf092289c77a4496f2e1113f68 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:35 +0200 +Subject: [PATCH 102/142] wifi: rtw89: coex: Change Wi-Fi Null data report to + version separate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3d929f075d3bb6187ad73375f6aee7bcf0b51851 +Author: Ching-Te Ku +Date: Fri Jan 6 20:08:39 2023 +0800 + + wifi: rtw89: coex: Change Wi-Fi Null data report to version separate + + Coexistence need to send Null data to stop AP keeps TX packet to DUT + before DUT coexistence switch to Bluetooth time slot, or it will be an + interference to DUT BT and because DUT will not RX packet from AP + the packet retry may harmful to WL TP. Compare to v1 version, the newer + firmware report will also report Null TX data counter. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106120844.17441-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 57 +++++++++++++++---------------- + drivers/net/wireless/realtek/rtw89/core.h | 14 ++++---- + 2 files changed, 35 insertions(+), 36 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index f97ddbcb51046..eec1f5228c5dc 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -1032,12 +1032,14 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + break; + case BTC_RPT_TYPE_NULLSTA: + pcinfo = &pfwinfo->rpt_fbtc_nullsta.cinfo; +- if (chip->chip_id == RTL8852A) { ++ if (ver->fcxnullsta == 1) { + pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo); ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v1); ++ } else if (ver->fcxnullsta == 2) { ++ pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo.v2; ++ pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo.v2); + } else { +- pfinfo = &pfwinfo->rpt_fbtc_nullsta.finfo_v1; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_nullsta.finfo_v1); ++ goto err; + } + pcinfo->req_fver = ver->fcxnullsta; + break; +@@ -6789,12 +6791,11 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) + + static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) + { +- 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_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo; +- struct rtw89_btc_fbtc_cynullsta *ns; +- struct rtw89_btc_fbtc_cynullsta_v1 *ns_v1; ++ union rtw89_btc_fbtc_cynullsta_info *ns; + u8 i = 0; + + if (!btc->dm.tdma_now.rxflctrl) +@@ -6804,9 +6805,8 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) + if (!pcinfo->valid) + return; + +- if (chip->chip_id == RTL8852A) { +- ns = &pfwinfo->rpt_fbtc_nullsta.finfo; +- ++ ns = &pfwinfo->rpt_fbtc_nullsta.finfo; ++ if (ver->fcxnullsta == 1) { + seq_printf(m, " %-15s : ", "[null_sta]"); + + for (i = 0; i < 2; i++) { +@@ -6815,46 +6815,43 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) + else + seq_printf(m, "null-%d", i); + seq_printf(m, "[ok:%d/", +- le32_to_cpu(ns->result[i][1])); ++ le32_to_cpu(ns->v1.result[i][1])); + seq_printf(m, "fail:%d/", +- le32_to_cpu(ns->result[i][0])); ++ le32_to_cpu(ns->v1.result[i][0])); + seq_printf(m, "on_time:%d/", +- le32_to_cpu(ns->result[i][2])); ++ le32_to_cpu(ns->v1.result[i][2])); + seq_printf(m, "retry:%d/", +- le32_to_cpu(ns->result[i][3])); ++ le32_to_cpu(ns->v1.result[i][3])); + seq_printf(m, "avg_t:%d.%03d/", +- le32_to_cpu(ns->avg_t[i]) / 1000, +- le32_to_cpu(ns->avg_t[i]) % 1000); ++ le32_to_cpu(ns->v1.avg_t[i]) / 1000, ++ le32_to_cpu(ns->v1.avg_t[i]) % 1000); + seq_printf(m, "max_t:%d.%03d]", +- le32_to_cpu(ns->max_t[i]) / 1000, +- le32_to_cpu(ns->max_t[i]) % 1000); ++ le32_to_cpu(ns->v1.max_t[i]) / 1000, ++ le32_to_cpu(ns->v1.max_t[i]) % 1000); + } + } else { +- ns_v1 = &pfwinfo->rpt_fbtc_nullsta.finfo_v1; +- + seq_printf(m, " %-15s : ", "[null_sta]"); +- + for (i = 0; i < 2; i++) { + if (i != 0) + seq_printf(m, ", null-%d", i); + else + seq_printf(m, "null-%d", i); + seq_printf(m, "[Tx:%d/", +- le32_to_cpu(ns_v1->result[i][4])); ++ le32_to_cpu(ns->v2.result[i][4])); + seq_printf(m, "[ok:%d/", +- le32_to_cpu(ns_v1->result[i][1])); ++ le32_to_cpu(ns->v2.result[i][1])); + seq_printf(m, "fail:%d/", +- le32_to_cpu(ns_v1->result[i][0])); ++ le32_to_cpu(ns->v2.result[i][0])); + seq_printf(m, "on_time:%d/", +- le32_to_cpu(ns_v1->result[i][2])); ++ le32_to_cpu(ns->v2.result[i][2])); + seq_printf(m, "retry:%d/", +- le32_to_cpu(ns_v1->result[i][3])); ++ le32_to_cpu(ns->v2.result[i][3])); + seq_printf(m, "avg_t:%d.%03d/", +- le32_to_cpu(ns_v1->avg_t[i]) / 1000, +- le32_to_cpu(ns_v1->avg_t[i]) % 1000); ++ le32_to_cpu(ns->v2.avg_t[i]) / 1000, ++ le32_to_cpu(ns->v2.avg_t[i]) % 1000); + seq_printf(m, "max_t:%d.%03d]", +- le32_to_cpu(ns_v1->max_t[i]) / 1000, +- le32_to_cpu(ns_v1->max_t[i]) % 1000); ++ le32_to_cpu(ns->v2.max_t[i]) / 1000, ++ le32_to_cpu(ns->v2.max_t[i]) % 1000); + } + } + seq_puts(m, "\n"); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index d0b4c00324572..dfde8801e97bb 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1865,7 +1865,7 @@ union rtw89_btc_fbtc_cysta_info { + struct rtw89_btc_fbtc_cysta_v4 v4; + }; + +-struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ ++struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ + u8 fver; /* btc_ver::fcxnullsta */ + u8 rsvd; + __le16 rsvd2; +@@ -1874,7 +1874,7 @@ struct rtw89_btc_fbtc_cynullsta { /* cycle null statistics */ + __le32 result[2][4]; /* 0:fail, 1:ok, 2:on_time, 3:retry */ + } __packed; + +-struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ ++struct rtw89_btc_fbtc_cynullsta_v2 { /* cycle null statistics */ + u8 fver; /* btc_ver::fcxnullsta */ + u8 rsvd; + __le16 rsvd2; +@@ -1883,6 +1883,11 @@ struct rtw89_btc_fbtc_cynullsta_v1 { /* cycle null statistics */ + __le32 result[2][5]; /* 0:fail, 1:ok, 2:on_time, 3:retry, 4:tx */ + } __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_btver { + u8 fver; /* btc_ver::fcxbtver */ + u8 rsvd; +@@ -2075,10 +2080,7 @@ struct rtw89_btc_rpt_fbtc_step { + + struct rtw89_btc_rpt_fbtc_nullsta { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ +- union { +- struct rtw89_btc_fbtc_cynullsta finfo; /* info from fw */ +- struct rtw89_btc_fbtc_cynullsta_v1 finfo_v1; /* info from fw */ +- }; ++ union rtw89_btc_fbtc_cynullsta_info finfo; + }; + + struct rtw89_btc_rpt_fbtc_mreg { +-- +2.13.6 + diff --git a/SOURCES/0103-wifi-rtw89-coex-Change-firmware-steps-report-to-vers.patch b/SOURCES/0103-wifi-rtw89-coex-Change-firmware-steps-report-to-vers.patch new file mode 100644 index 0000000..0ec1b69 --- /dev/null +++ b/SOURCES/0103-wifi-rtw89-coex-Change-firmware-steps-report-to-vers.patch @@ -0,0 +1,309 @@ +From c5e58f0ec7bd83bf5a4b8e7fd979afea1c128644 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:35 +0200 +Subject: [PATCH 103/142] wifi: rtw89: coex: Change firmware steps report to + version separate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 2626ccefe615a1faa8fb6bfb07708089b103e428 +Author: Ching-Te Ku +Date: Fri Jan 6 20:08:40 2023 +0800 + + wifi: rtw89: coex: Change firmware steps report to version separate + + The report records the slots/events and their time cost about the code + call flow at firmware, ver 3 assign a reserved variable to recognize + the report is enabled or not. And add corresponding function to parsing + the report. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106120844.17441-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 124 ++++++++++++++++++++++++++---- + drivers/net/wireless/realtek/rtw89/core.h | 44 +++++++++-- + 2 files changed, 149 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index eec1f5228c5dc..5979efb5e465d 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -923,7 +923,6 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + struct rtw89_btc_btf_fwinfo *pfwinfo, + u8 *prptbuf, u32 index) + { +- 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; +@@ -1017,16 +1016,18 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, + break; + case BTC_RPT_TYPE_STEP: + pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; +- if (chip->chip_id == RTL8852A) { +- pfinfo = &pfwinfo->rpt_fbtc_step.finfo; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo.step[0]) * ++ 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, step); +- } else { +- pfinfo = &pfwinfo->rpt_fbtc_step.finfo_v1; +- pcinfo->req_len = sizeof(pfwinfo->rpt_fbtc_step.finfo_v1.step[0]) * ++ offsetof(struct rtw89_btc_fbtc_steps_v2, step); ++ } 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_v1, step); ++ offsetof(struct rtw89_btc_fbtc_steps_v3, step); ++ } else { ++ goto err; + } + pcinfo->req_fver = ver->fcxstep; + break; +@@ -6008,6 +6009,7 @@ static void _show_bt_info(struct rtw89_dev *rtwdev, struct seq_file *m) + #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 + + static const char *steps_to_str(u16 step) + { +@@ -6148,6 +6150,40 @@ static const char *id_to_slot(u32 id) + } + } + ++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 + void seq_print_segment(struct seq_file *m, const char *prefix, u16 *data, + u8 len, u8 seg_len, u8 start_idx, u8 ring_len) +@@ -6857,12 +6893,12 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) + seq_puts(m, "\n"); + } + +-static void _show_fbtc_step(struct rtw89_dev *rtwdev, struct seq_file *m) ++static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) + { + 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 *pstep = NULL; ++ struct rtw89_btc_fbtc_steps_v2 *pstep = NULL; + u8 type, val, cnt = 0, state = 0; + bool outloop = false; + u16 i, diff_t, n_start = 0, n_stop = 0; +@@ -6872,7 +6908,7 @@ static void _show_fbtc_step(struct rtw89_dev *rtwdev, struct seq_file *m) + if (!pcinfo->valid) + return; + +- pstep = &pfwinfo->rpt_fbtc_step.finfo; ++ pstep = &pfwinfo->rpt_fbtc_step.finfo.v2; + pos_old = le16_to_cpu(pstep->pos_old); + pos_new = le16_to_cpu(pstep->pos_new); + +@@ -6926,6 +6962,63 @@ static void _show_fbtc_step(struct rtw89_dev *rtwdev, struct seq_file *m) + } while (!outloop); + } + ++static void _show_fbtc_step_v3(struct rtw89_dev *rtwdev, struct seq_file *m) ++{ ++ 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; ++ u8 type, val; ++ u16 diff_t; ++ ++ if ((pfwinfo->rpt_en_map & ++ rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_FW_STEP_INFO)) == 0) ++ return; ++ ++ pcinfo = &pfwinfo->rpt_fbtc_step.cinfo; ++ if (!pcinfo->valid) ++ return; ++ ++ pstep = &pfwinfo->rpt_fbtc_step.finfo.v3; ++ if (pcinfo->req_fver != pstep->fver) ++ return; ++ ++ 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; ++ ++ /* 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) ++ seq_printf(m, " %-15s : ", "[steps]"); ++ ++ seq_printf(m, "-> %s(%02d)", ++ (type == CXSTEP_SLOT ? ++ id_to_slot((u32)val) : ++ id_to_evt((u32)val)), diff_t); ++ ++ if (cnt % 10 == 9) ++ seq_puts(m, "\n"); ++ ++ cnt++; ++ } ++} ++ + static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) + { + struct rtw89_btc *btc = &rtwdev->btc; +@@ -6946,7 +7039,12 @@ static void _show_fw_dm_msg(struct rtw89_dev *rtwdev, struct seq_file *m) + _show_fbtc_cysta_v4(rtwdev, m); + + _show_fbtc_nullsta(rtwdev, m); +- _show_fbtc_step(rtwdev, m); ++ ++ if (ver->fcxstep == 2) ++ _show_fbtc_step_v2(rtwdev, m); ++ else if (ver->fcxstep == 3) ++ _show_fbtc_step_v3(rtwdev, m); ++ + } + + static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg) +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index dfde8801e97bb..39c5a003e36cc 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -1611,6 +1611,36 @@ enum rtw89_btc_cxst_state { + 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, +@@ -1696,7 +1726,7 @@ struct rtw89_btc_fbtc_step { + __le16 difft; + } __packed; + +-struct rtw89_btc_fbtc_steps { ++struct rtw89_btc_fbtc_steps_v2 { + u8 fver; /* btc_ver::fcxstep */ + u8 rsvd; + __le16 cnt; +@@ -1705,7 +1735,7 @@ struct rtw89_btc_fbtc_steps { + struct rtw89_btc_fbtc_step step[FCXMAX_STEP]; + } __packed; + +-struct rtw89_btc_fbtc_steps_v1 { ++struct rtw89_btc_fbtc_steps_v3 { + u8 fver; + u8 en; + __le16 rsvd; +@@ -1713,6 +1743,11 @@ struct rtw89_btc_fbtc_steps_v1 { + 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; +@@ -2072,10 +2107,7 @@ struct rtw89_btc_rpt_fbtc_cysta { + + struct rtw89_btc_rpt_fbtc_step { + struct rtw89_btc_rpt_cmn_info cinfo; /* common info, by driver */ +- union { +- struct rtw89_btc_fbtc_steps finfo; /* info from fw */ +- struct rtw89_btc_fbtc_steps_v1 finfo_v1; /* info from fw */ +- }; ++ union rtw89_btc_fbtc_steps_info finfo; /* info from fw */ + }; + + struct rtw89_btc_rpt_fbtc_nullsta { +-- +2.13.6 + diff --git a/SOURCES/0104-wifi-rtw89-coex-refactor-debug-log-of-slot-list.patch b/SOURCES/0104-wifi-rtw89-coex-refactor-debug-log-of-slot-list.patch new file mode 100644 index 0000000..66c6256 --- /dev/null +++ b/SOURCES/0104-wifi-rtw89-coex-refactor-debug-log-of-slot-list.patch @@ -0,0 +1,114 @@ +From f1a0621da9f423ecc0866d32897d767d967f4999 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:35 +0200 +Subject: [PATCH 104/142] wifi: rtw89: coex: refactor debug log of slot list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 2ce43be348502703cf173fc31ea45bfe5ff43f90 +Author: Ching-Te Ku +Date: Fri Jan 6 20:08:41 2023 +0800 + + wifi: rtw89: coex: refactor debug log of slot list + + Slot list is to list the WiFi/Bluetooth PTA hardware priority setting. + Move the list parser to its function, not to append together with TDMA + parser. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106120844.17441-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 45 ++++--------------------------- + 1 file changed, 5 insertions(+), 40 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 5979efb5e465d..03872ac8cced0 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -6345,9 +6345,6 @@ static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_rpt_cmn_info *pcinfo = NULL; + struct rtw89_btc_fbtc_tdma *t = NULL; +- struct rtw89_btc_fbtc_slot *s = NULL; +- struct rtw89_btc_dm *dm = &btc->dm; +- u8 i, cnt = 0; + + pcinfo = &pfwinfo->rpt_fbtc_tdma.cinfo; + if (!pcinfo->valid) +@@ -6373,61 +6370,29 @@ static void _show_fbtc_tdma(struct rtw89_dev *rtwdev, struct seq_file *m) + "policy_type:%d", + (u32)btc->policy_type); + +- s = pfwinfo->rpt_fbtc_slots.finfo.slot; +- +- for (i = 0; i < CXST_MAX; i++) { +- if (dm->update_slot_map == BIT(CXST_MAX) - 1) +- break; +- +- if (!(dm->update_slot_map & BIT(i))) +- continue; +- +- if (cnt % 6 == 0) +- seq_printf(m, +- " %-15s : %d[%d/0x%x/%d]", +- "[slot_policy]", +- (u32)i, +- s[i].dur, s[i].cxtbl, s[i].cxtype); +- else +- seq_printf(m, +- ", %d[%d/0x%x/%d]", +- (u32)i, +- s[i].dur, s[i].cxtbl, s[i].cxtype); +- if (cnt % 6 == 5) +- seq_puts(m, "\n"); +- cnt++; +- } + seq_puts(m, "\n"); + } + + static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) + { + 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_slots *pslots = NULL; +- struct rtw89_btc_fbtc_slot s; ++ struct rtw89_btc_dm *dm = &btc->dm; ++ struct rtw89_btc_fbtc_slot *s; + u8 i = 0; + +- pcinfo = &pfwinfo->rpt_fbtc_slots.cinfo; +- if (!pcinfo->valid) +- return; +- +- pslots = &pfwinfo->rpt_fbtc_slots.finfo; +- + for (i = 0; i < CXST_MAX; i++) { +- s = pslots->slot[i]; ++ s = &dm->slot_now[i]; + if (i % 6 == 0) + seq_printf(m, + " %-15s : %02d[%03d/0x%x/%d]", + "[slot_list]", + (u32)i, +- s.dur, s.cxtbl, s.cxtype); ++ s->dur, s->cxtbl, s->cxtype); + else + seq_printf(m, + ", %02d[%03d/0x%x/%d]", + (u32)i, +- s.dur, s.cxtbl, s.cxtype); ++ s->dur, s->cxtbl, s->cxtype); + if (i % 6 == 5) + seq_puts(m, "\n"); + } +-- +2.13.6 + diff --git a/SOURCES/0105-wifi-rtw89-coex-Packet-traffic-arbitration-hardware-.patch b/SOURCES/0105-wifi-rtw89-coex-Packet-traffic-arbitration-hardware-.patch new file mode 100644 index 0000000..28404f7 --- /dev/null +++ b/SOURCES/0105-wifi-rtw89-coex-Packet-traffic-arbitration-hardware-.patch @@ -0,0 +1,83 @@ +From bf7a282d56a0765eea68faca8d743f1108fbce66 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:36 +0200 +Subject: [PATCH 105/142] wifi: rtw89: coex: Packet traffic arbitration + hardware owner monitor +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit ae4e1adbb1be65cadde793239a39fa947a3ff828 +Author: Ching-Te Ku +Date: Fri Jan 6 20:08:42 2023 +0800 + + wifi: rtw89: coex: Packet traffic arbitration hardware owner monitor + + Because the difference of the hardware design, RTL8852C can not get the + PTA owner by the same method with RTL8852B, RTL8852A. Modify the get owner + API and related logic. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106120844.17441-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 7 ++----- + drivers/net/wireless/realtek/rtw89/mac.c | 11 +++++++++-- + 2 files changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 03872ac8cced0..ec31dd0751cee 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -4873,7 +4873,7 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode) + _write_scbd(rtwdev, + BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true); + _update_bt_scbd(rtwdev, true); +- if (rtw89_mac_get_ctrl_path(rtwdev) && chip->chip_id == RTL8852A) { ++ if (rtw89_mac_get_ctrl_path(rtwdev)) { + rtw89_debug(rtwdev, RTW89_DBG_BTC, + "[BTC], %s(): PTA owner warning!!\n", + __func__); +@@ -7082,10 +7082,7 @@ static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) + + /* To avoid I/O if WL LPS or power-off */ + if (!wl->status.map.lps && !wl->status.map.rf_off) { +- if (chip->chip_id == RTL8852A) +- btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); +- else if (chip->chip_id == RTL8852C) +- btc->dm.pta_owner = 0; ++ btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev); + + _get_gnt(rtwdev, &gnt_cfg); + gnt = gnt_cfg.band[0]; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index cf9a0a3120a79..5ab0590485e0d 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -4865,9 +4865,16 @@ EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v1); + + bool rtw89_mac_get_ctrl_path(struct rtw89_dev *rtwdev) + { +- u8 val = rtw89_read8(rtwdev, R_AX_SYS_SDIO_CTRL + 3); ++ const struct rtw89_chip_info *chip = rtwdev->chip; ++ u8 val = 0; ++ ++ if (chip->chip_id == RTL8852C) ++ return false; ++ else if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B) ++ val = rtw89_read8_mask(rtwdev, R_AX_SYS_SDIO_CTRL + 3, ++ B_AX_LTE_MUX_CTRL_PATH >> 24); + +- return FIELD_GET(B_AX_LTE_MUX_CTRL_PATH >> 24, val); ++ return !!val; + } + + u16 rtw89_mac_get_plt_cnt(struct rtw89_dev *rtwdev, u8 band) +-- +2.13.6 + diff --git a/SOURCES/0106-wifi-rtw89-coex-Change-RTL8852B-use-v1-TDMA-policy.patch b/SOURCES/0106-wifi-rtw89-coex-Change-RTL8852B-use-v1-TDMA-policy.patch new file mode 100644 index 0000000..a135b10 --- /dev/null +++ b/SOURCES/0106-wifi-rtw89-coex-Change-RTL8852B-use-v1-TDMA-policy.patch @@ -0,0 +1,47 @@ +From 90bb28c3e1f5b2fb8b203e8ba91efe551b322492 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:36 +0200 +Subject: [PATCH 106/142] wifi: rtw89: coex: Change RTL8852B use v1 TDMA policy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 447a3267cbed55963bcd146ddebc72429b630dbf +Author: Ching-Te Ku +Date: Fri Jan 6 20:08:43 2023 +0800 + + wifi: rtw89: coex: Change RTL8852B use v1 TDMA policy + + RTL8852B support the new features like TDMA instant (Change TDMA mechanism + immediately), Co-RX feature (Wi-Fi/Bluetooth can RX in the same time) and + so on. The v1 TDMA policy will enable those newer mechanism. It will have + a better coexistence performance. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106120844.17441-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index b9e5363e524b3..e0f6dfe31bddd 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -2423,7 +2423,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = { + .btc_update_bt_cnt = rtw8852b_btc_update_bt_cnt, + .btc_wl_s1_standby = rtw8852b_btc_wl_s1_standby, + .btc_set_wl_rx_gain = rtw8852b_btc_set_wl_rx_gain, +- .btc_set_policy = rtw89_btc_set_policy, ++ .btc_set_policy = rtw89_btc_set_policy_v1, + }; + + const struct rtw89_chip_info rtw8852b_chip_info = { +-- +2.13.6 + diff --git a/SOURCES/0107-wifi-rtw89-coex-Change-Wi-Fi-role-info-related-logic.patch b/SOURCES/0107-wifi-rtw89-coex-Change-Wi-Fi-role-info-related-logic.patch new file mode 100644 index 0000000..2b36938 --- /dev/null +++ b/SOURCES/0107-wifi-rtw89-coex-Change-Wi-Fi-role-info-related-logic.patch @@ -0,0 +1,215 @@ +From 2c05ea9b6e2279e215310ad45c6ca97dcb5c2e80 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:36 +0200 +Subject: [PATCH 107/142] wifi: rtw89: coex: Change Wi-Fi role info related + logic to version separate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit fbc2caf19914371973f14b6ac7ef525c49e4b1f1 +Author: Ching-Te Ku +Date: Fri Jan 6 20:08:44 2023 +0800 + + wifi: rtw89: coex: Change Wi-Fi role info related logic to version separate + + The Wi-Fi role info structure will need to H2C to firmware, firmware + need these information to do some multi-role operation. v1 add DBCC + and NOA information in the structure. And driver side also need to + put/get values at the corresponding version of structure. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106120844.17441-8-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 39 ++++++++++++++++--------------- + 1 file changed, 20 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index ec31dd0751cee..d48ae25823ffa 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -2075,6 +2075,7 @@ static void _set_bt_afh_info(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_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_bt_info *bt = &btc->cx.bt; + struct rtw89_btc_bt_link_info *b = &bt->link_info; +@@ -2088,7 +2089,7 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev) + if (btc->ctrl.manual || wl->status.map.scan) + return; + +- if (chip->chip_id == RTL8852A) { ++ if (ver->fwlrole == 0) { + mode = wl_rinfo->link_mode; + connect_cnt = wl_rinfo->connect_cnt; + } else { +@@ -2107,13 +2108,13 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev) + r = &wl_rinfo->active_role[i]; + r1 = &wl_rinfo_v1->active_role_v1[i]; + +- if (chip->chip_id == RTL8852A && ++ if (ver->fwlrole == 0 && + (r->role == RTW89_WIFI_ROLE_P2P_GO || + r->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { + ch = r->ch; + bw = r->bw; + break; +- } else if (chip->chip_id != RTL8852A && ++ } else if (ver->fwlrole == 1 && + (r1->role == RTW89_WIFI_ROLE_P2P_GO || + r1->role == RTW89_WIFI_ROLE_P2P_CLIENT)) { + ch = r1->ch; +@@ -2128,12 +2129,12 @@ static void _set_bt_afh_info(struct rtw89_dev *rtwdev) + r = &wl_rinfo->active_role[i]; + r1 = &wl_rinfo_v1->active_role_v1[i]; + +- if (chip->chip_id == RTL8852A && ++ if (ver->fwlrole == 0 && + r->connected && r->band == RTW89_BAND_2G) { + ch = r->ch; + bw = r->bw; + break; +- } else if (chip->chip_id != RTL8852A && ++ } else if (ver->fwlrole == 1 && + r1->connected && r1->band == RTW89_BAND_2G) { + ch = r1->ch; + bw = r1->bw; +@@ -3581,8 +3582,8 @@ static void _action_wl_rfk(struct rtw89_dev *rtwdev) + + static void _set_btg_ctrl(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_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; +@@ -3593,7 +3594,7 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev) + if (btc->ctrl.manual) + return; + +- if (chip->chip_id == RTL8852A) ++ if (ver->fwlrole == 0) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; +@@ -3686,8 +3687,8 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta) + + static void _set_wl_tx_limit(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_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; +@@ -3707,7 +3708,7 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) + if (btc->ctrl.manual) + return; + +- if (chip->chip_id == RTL8852A) ++ if (ver->fwlrole == 0) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; +@@ -3755,8 +3756,8 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev) + + static void _set_bt_rx_agc(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_wl_info *wl = &btc->cx.wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; + struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1; +@@ -3764,7 +3765,7 @@ static void _set_bt_rx_agc(struct rtw89_dev *rtwdev) + bool bt_hi_lna_rx = false; + u8 mode; + +- if (chip->chip_id == RTL8852A) ++ if (ver->fwlrole == 0) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; +@@ -4628,8 +4629,8 @@ static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev) + static + void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) + { +- 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 = &rtwdev->btc.dm; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &btc->cx.wl; +@@ -4644,7 +4645,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) + _update_dm_step(rtwdev, reason); + _update_btc_state_map(rtwdev); + +- if (chip->chip_id == RTL8852A) ++ if (ver->fwlrole == 0) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; +@@ -4766,9 +4767,9 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) + break; + case BTC_WLINK_2G_SCC: + bt->scan_rx_low_pri = true; +- if (chip->chip_id == RTL8852A) ++ if (ver->fwlrole == 0) + _action_wl_2g_scc(rtwdev); +- else if (chip->chip_id == RTL8852C) ++ else if (ver->fwlrole == 1) + _action_wl_2g_scc_v1(rtwdev); + break; + case BTC_WLINK_2G_MCC: +@@ -5206,10 +5207,10 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif + struct rtw89_sta *rtwsta, enum btc_role_state state) + { + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); +- const struct rtw89_chip_info *chip = rtwdev->chip; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); + 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_link_info r = {0}; + struct rtw89_btc_wl_link_info *wlinfo = NULL; +@@ -5273,7 +5274,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif + wlinfo = &wl->link_info[r.pid]; + + memcpy(wlinfo, &r, sizeof(*wlinfo)); +- if (chip->chip_id == RTL8852A) ++ if (ver->fwlrole == 0) + _update_wl_info(rtwdev); + else + _update_wl_info_v1(rtwdev); +@@ -5789,8 +5790,8 @@ static void _show_wl_role_info(struct rtw89_dev *rtwdev, struct seq_file *m) + + static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) + { +- 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_cx *cx = &btc->cx; + struct rtw89_btc_wl_info *wl = &cx->wl; + struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info; +@@ -5802,7 +5803,7 @@ static void _show_wl_info(struct rtw89_dev *rtwdev, struct seq_file *m) + + seq_puts(m, "========== [WL Status] ==========\n"); + +- if (chip->chip_id == RTL8852A) ++ if (ver->fwlrole == 0) + mode = wl_rinfo->link_mode; + else + mode = wl_rinfo_v1->link_mode; +-- +2.13.6 + diff --git a/SOURCES/0108-wifi-rtw89-fix-null-vif-pointer-when-get-management-.patch b/SOURCES/0108-wifi-rtw89-fix-null-vif-pointer-when-get-management-.patch new file mode 100644 index 0000000..7d397ad --- /dev/null +++ b/SOURCES/0108-wifi-rtw89-fix-null-vif-pointer-when-get-management-.patch @@ -0,0 +1,48 @@ +From 125d96e892148519e6a4f6acbe4bfc305272b3e3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:36 +0200 +Subject: [PATCH 108/142] wifi: rtw89: fix null vif pointer when get management + frame date rate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 95dafeabe477d9692154e85140eda5124895ea4f +Author: Kuan-Chung Chen +Date: Fri Jan 6 20:15:16 2023 +0800 + + wifi: rtw89: fix null vif pointer when get management frame date rate + + When transmitting a packet that gets from ieee80211_nullfunc_get(), + the vif in tx_info->control was no assigned, which will cause + dereferencing a null pointer. + + Signed-off-by: Kuan-Chung Chen + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106121517.19841-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 2e4ba8e42d392..27f7a1860c9d0 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -498,7 +498,8 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); + u16 lowest_rate; + +- if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE || vif->p2p) ++ 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; +-- +2.13.6 + diff --git a/SOURCES/0109-wifi-rtw89-set-the-correct-mac_id-for-management-fra.patch b/SOURCES/0109-wifi-rtw89-set-the-correct-mac_id-for-management-fra.patch new file mode 100644 index 0000000..706f17a --- /dev/null +++ b/SOURCES/0109-wifi-rtw89-set-the-correct-mac_id-for-management-fra.patch @@ -0,0 +1,90 @@ +From 4c01a576da348143187464b0ac999363287490fb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:36 +0200 +Subject: [PATCH 109/142] wifi: rtw89: set the correct mac_id for management + frames +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 877287f971b145a3699ea8466333d48aff6204e5 +Author: Kuan-Chung Chen +Date: Fri Jan 6 20:15:17 2023 +0800 + + wifi: rtw89: set the correct mac_id for management frames + + The mac_id of management frames should follow rtwvif->mac_id or + rtwsta->mac_id. Add this patch to set the correct mac_id and + prevent unexpected behavior. + + Signed-off-by: Kuan-Chung Chen + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230106121517.19841-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 31 ++++++++++++++++--------------- + 1 file changed, 16 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 27f7a1860c9d0..4cf4a81ed4f79 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -512,6 +512,21 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, + return __ffs(vif->bss_conf.basic_rates) + lowest_rate; + } + ++static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, ++ struct rtw89_core_tx_request *tx_req) ++{ ++ struct ieee80211_vif *vif = tx_req->vif; ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; ++ struct ieee80211_sta *sta = tx_req->sta; ++ struct rtw89_sta *rtwsta; ++ ++ if (!sta) ++ return rtwvif->mac_id; ++ ++ rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ return rtwsta->mac_id; ++} ++ + static void + rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +@@ -528,6 +543,7 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, + desc_info->qsel = qsel; + desc_info->ch_dma = ch_dma; + desc_info->port = desc_info->hiq ? rtwvif->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; + +@@ -670,21 +686,6 @@ rtw89_core_tx_update_he_qos_htc(struct rtw89_dev *rtwdev, + desc_info->bk = true; + } + +-static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev, +- struct rtw89_core_tx_request *tx_req) +-{ +- struct ieee80211_vif *vif = tx_req->vif; +- struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; +- struct ieee80211_sta *sta = tx_req->sta; +- struct rtw89_sta *rtwsta; +- +- if (!sta) +- return rtwvif->mac_id; +- +- rtwsta = (struct rtw89_sta *)sta->drv_priv; +- return rtwsta->mac_id; +-} +- + static void + rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +-- +2.13.6 + diff --git a/SOURCES/0110-wifi-rtw89-correct-register-definitions-of-digital-C.patch b/SOURCES/0110-wifi-rtw89-correct-register-definitions-of-digital-C.patch new file mode 100644 index 0000000..c5e8f17 --- /dev/null +++ b/SOURCES/0110-wifi-rtw89-correct-register-definitions-of-digital-C.patch @@ -0,0 +1,81 @@ +From 12d11942d26ddf8cf2e94402a7dde71f85efdd12 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:36 +0200 +Subject: [PATCH 110/142] wifi: rtw89: correct register definitions of digital + CFO and spur elimination +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 15423743ae840977fe269ff907e37e20fe1c14df +Author: Eric Huang +Date: Fri Jan 13 17:06:29 2023 +0800 + + wifi: rtw89: correct register definitions of digital CFO and spur elimination + + This change fixes the precision of CFO and TX EVM, and it could imporve + performance in some cases. Also, use the correctted definition for 8852A. + + Signed-off-by: Eric Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230113090632.60957-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 4 ++-- + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 6 +++--- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 578a1969afd61..412a6918efd6c 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -4102,9 +4102,9 @@ + #define R_MUIC 0x40F8 + #define B_MUIC_EN BIT(0) + #define R_DCFO 0x4264 +-#define B_DCFO GENMASK(1, 0) ++#define B_DCFO GENMASK(7, 0) + #define R_SEG0CSI 0x42AC +-#define B_SEG0CSI_IDX GENMASK(11, 0) ++#define B_SEG0CSI_IDX GENMASK(10, 0) + #define R_SEG0CSI_EN 0x42C4 + #define B_SEG0CSI_EN BIT(23) + #define R_BSS_CLR_MAP 0x43ac +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 1800a56091be4..45119c512a051 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -1035,7 +1035,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch) + 0x210); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, + 0x210); +- rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x7c0); ++ 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, +@@ -1047,7 +1047,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch) + 0x210); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, + 0x210); +- rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x40); ++ 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, +@@ -1059,7 +1059,7 @@ static void rtw8852a_spur_elimination(struct rtw89_dev *rtwdev, u8 central_ch) + 0x2d0); + rtw89_phy_write32_mask(rtwdev, R_P1_NBIIDX, B_P1_NBIIDX_VAL, + 0x2d0); +- rtw89_phy_write32_mask(rtwdev, R_SEG0CSI, 0xfff, 0x740); ++ 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, +-- +2.13.6 + diff --git a/SOURCES/0111-wifi-rtw89-8852c-rfk-correct-ADC-clock-settings.patch b/SOURCES/0111-wifi-rtw89-8852c-rfk-correct-ADC-clock-settings.patch new file mode 100644 index 0000000..22c9454 --- /dev/null +++ b/SOURCES/0111-wifi-rtw89-8852c-rfk-correct-ADC-clock-settings.patch @@ -0,0 +1,197 @@ +From 1fc30cddfcaed3d1562f9162b326404ccbe6817a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:36 +0200 +Subject: [PATCH 111/142] wifi: rtw89: 8852c: rfk: correct ADC clock settings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3aa83062c3ec64dd757554a00653cc2d42179f12 +Author: Chih-Kang Chang +Date: Fri Jan 13 17:06:30 2023 +0800 + + wifi: rtw89: 8852c: rfk: correct ADC clock settings + + Some hardware modules don't have good RF characteristic as regular. + It could get ADC abnormal in low temperature, and it causes bad RX + performance and affects calibration result of DPK. + + Signed-off-by: Chih-Kang Chang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230113090632.60957-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/reg.h | 5 +++ + drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c | 51 +++++++++++++++++------ + 2 files changed, 44 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 412a6918efd6c..036953f0ec464 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -4738,6 +4738,7 @@ + #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) +@@ -4755,9 +4756,13 @@ + #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_ADCMOD 0xC0E8 ++#define B_ADCMOD_LP GENMASK(31, 16) + #define R_ADDCK0D 0xC0F0 + #define B_ADDCK0D_VAL2 GENMASK(31, 26) + #define B_ADDCK0D_VAL GENMASK(25, 16) +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +index 3c5fa3bb2a8f4..2c0bc3a4ab3b1 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +@@ -11,6 +11,15 @@ + #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}; +@@ -62,6 +71,10 @@ static const u32 dpk_par_regs[RTW89_DPK_RF_PATH][4] = { + 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", +@@ -440,6 +453,8 @@ static void rtw8852c_txck_force(struct rtw89_dev *rtwdev, u8 path, bool force, + 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) +@@ -447,6 +462,26 @@ static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force, + + 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) +@@ -630,8 +665,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) + 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_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); + 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; +@@ -639,8 +672,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) + 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_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); + 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; +@@ -648,8 +679,6 @@ static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) + 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_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); + 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; +@@ -1413,8 +1442,6 @@ static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, + 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_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); + 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); +@@ -1760,7 +1787,7 @@ u8 _rx_dck_channel_calc(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) + #define RTW8852C_DPK_VER 0xf + #define RTW8852C_DPK_TH_AVG_NUM 4 + #define RTW8852C_DPK_RF_PATH 2 +-#define RTW8852C_DPK_KIP_REG_NUM 5 ++#define RTW8852C_DPK_KIP_REG_NUM 7 + #define RTW8852C_DPK_RXSRAM_DBG 0 + + enum rtw8852c_dpk_id { +@@ -1919,8 +1946,6 @@ static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, + + /*4. Set ADC clk*/ + rtw8852c_rxck_force(rtwdev, path, true, ADC_1920M); +- 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); + 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); +@@ -2671,12 +2696,14 @@ static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, + enum rtw89_phy_idx phy, u8 kpath) + { + struct rtw89_dpk_info *dpk = &rtwdev->dpk; +- static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0d4, 0xc0d8}; ++ 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))) +-- +2.13.6 + diff --git a/SOURCES/0112-wifi-rtw89-fix-assignation-of-TX-BD-RAM-table.patch b/SOURCES/0112-wifi-rtw89-fix-assignation-of-TX-BD-RAM-table.patch new file mode 100644 index 0000000..f364e36 --- /dev/null +++ b/SOURCES/0112-wifi-rtw89-fix-assignation-of-TX-BD-RAM-table.patch @@ -0,0 +1,165 @@ +From bf664c1524a3f88dc6dcbb75dbe37aed537b6ada Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:36 +0200 +Subject: [PATCH 112/142] wifi: rtw89: fix assignation of TX BD RAM table +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 7f495de6ae7d31f098970fb45a038c9f69b1bf75 +Author: Zong-Zhe Yang +Date: Fri Jan 13 17:06:31 2023 +0800 + + wifi: rtw89: fix assignation of TX BD RAM table + + TX BD's RAM table describes how HW allocates usable buffer section + for each TX channel at fetch time. The total RAM size for TX BD is + chip-dependent. For 8852BE, it has only half size (32) for TX channels + of single band. Original table arrange total size (64) for dual band. + It will overflow on 8852BE circuit and cause section conflicts between + different TX channels. + + So, we do the changes below. + * add another table for single band chip and export both kind of tables + * point to the expected one in rtw89_pci_info by chip + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230113090632.60957-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/pci.c | 15 ++++++++++++++- + drivers/net/wireless/realtek/rtw89/pci.h | 15 +++++++++------ + drivers/net/wireless/realtek/rtw89/rtw8852ae.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852be.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852ce.c | 1 + + 5 files changed, 26 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c +index 1c4500ba777c6..0ea734c81b4f0 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.c ++++ b/drivers/net/wireless/realtek/rtw89/pci.c +@@ -1384,7 +1384,7 @@ static int rtw89_pci_ops_tx_write(struct rtw89_dev *rtwdev, struct rtw89_core_tx + return 0; + } + +-static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = { ++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}, +@@ -1399,11 +1399,24 @@ static const struct rtw89_pci_bd_ram bd_ram_table[RTW89_TXCH_NUM] = { + [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_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; +diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h +index 7d033501d4d95..1e19740db8c54 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.h ++++ b/drivers/net/wireless/realtek/rtw89/pci.h +@@ -750,6 +750,12 @@ struct rtw89_pci_ch_dma_addr_set { + 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_info { + enum mac_ax_bd_trunc_mode txbd_trunc_mode; + enum mac_ax_bd_trunc_mode rxbd_trunc_mode; +@@ -785,6 +791,7 @@ struct rtw89_pci_info { + 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, +@@ -798,12 +805,6 @@ struct rtw89_pci_info { + struct rtw89_pci_isrs *isrs); + }; + +-struct rtw89_pci_bd_ram { +- u8 start_idx; +- u8 max_num; +- u8 min_num; +-}; +- + struct rtw89_pci_tx_data { + dma_addr_t dma; + }; +@@ -1057,6 +1058,8 @@ static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val) + extern const struct dev_pm_ops rtw89_pm_ops; + 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_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]; + + struct pci_device_id; + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +index 0cd8c0c44d19d..d835a44a1d0d0 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +@@ -44,6 +44,7 @@ static const struct rtw89_pci_info rtw8852a_pci_info = { + .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, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852be.c b/drivers/net/wireless/realtek/rtw89/rtw8852be.c +index 0ef2ca8efeb0e..ecf39d2d9f81f 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c +@@ -46,6 +46,7 @@ static const struct rtw89_pci_info rtw8852b_pci_info = { + 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, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +index 35901f64d17de..80490a5437df6 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c +@@ -53,6 +53,7 @@ static const struct rtw89_pci_info rtw8852c_pci_info = { + .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, +-- +2.13.6 + diff --git a/SOURCES/0113-wifi-rtw89-8852b-fill-the-missing-configuration-abou.patch b/SOURCES/0113-wifi-rtw89-8852b-fill-the-missing-configuration-abou.patch new file mode 100644 index 0000000..0b98ae4 --- /dev/null +++ b/SOURCES/0113-wifi-rtw89-8852b-fill-the-missing-configuration-abou.patch @@ -0,0 +1,47 @@ +From 964b468a2a75a36becff335be9aa7dfb64769d6c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:37 +0200 +Subject: [PATCH 113/142] wifi: rtw89: 8852b: fill the missing configuration + about queue empty checking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit a3edb20146f000dfd5aba1f17e2dc0f363ff9446 +Author: Zong-Zhe Yang +Date: Fri Jan 13 17:06:32 2023 +0800 + + wifi: rtw89: 8852b: fill the missing configuration about queue empty checking + + The configurations, wde_qempty_acq_num and wde_qempty_mgq_sel, are used + when MAC checks if TX queues are empty. Fill the corresponding setting + for 8852B. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230113090632.60957-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index e0f6dfe31bddd..c6345228d049f 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -2437,6 +2437,8 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .rsvd_ple_ofst = 0x2f800, + .hfc_param_ini = rtw8852b_hfc_param_ini_pcie, + .dle_mem = rtw8852b_dle_mem_pcie, ++ .wde_qempty_acq_num = 4, ++ .wde_qempty_mgq_sel = 4, + .rf_base_addr = {0xe000, 0xf000}, + .pwr_on_seq = NULL, + .pwr_off_seq = NULL, +-- +2.13.6 + diff --git a/SOURCES/0114-wifi-rtw89-coex-Update-Wi-Fi-external-control-TDMA-p.patch b/SOURCES/0114-wifi-rtw89-coex-Update-Wi-Fi-external-control-TDMA-p.patch new file mode 100644 index 0000000..321612e --- /dev/null +++ b/SOURCES/0114-wifi-rtw89-coex-Update-Wi-Fi-external-control-TDMA-p.patch @@ -0,0 +1,130 @@ +From fbaeba7c966d9a6261960964f9e707f0b87b0577 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:37 +0200 +Subject: [PATCH 114/142] wifi: rtw89: coex: Update Wi-Fi external control TDMA + parameters/tables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 1742fbae7a49b067649b7c2958d9468711149e37 +Author: Ching-Te Ku +Date: Tue Jan 17 19:41:02 2023 +0800 + + wifi: rtw89: coex: Update Wi-Fi external control TDMA parameters/tables + + This patch update the external control (Wi-Fi firmware control) type of + TDMA related parameters, almost all of these case were related to Wi-Fi + multi-role situations & AP mode. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230117114109.4298-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 37 ++++++++++++++++++++----------- + 1 file changed, 24 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index d48ae25823ffa..a9db33e3bcade 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -63,7 +63,7 @@ struct btc_fbtc_1slot { + 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, 3, 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}, +@@ -80,21 +80,21 @@ 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(70, 0xea5a5aaa, 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(100, 0xe5555555, SLOT_MIX), ++ [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(250, 0x55555555, SLOT_MIX), +- [CXST_E2G] = __DEF_FBTC_SLOT(20, 0xea5a5a5a, SLOT_MIX), +- [CXST_E5G] = __DEF_FBTC_SLOT(20, 0xffffffff, SLOT_MIX), +- [CXST_EBT] = __DEF_FBTC_SLOT(20, 0xe5555555, SLOT_MIX), +- [CXST_ENULL] = __DEF_FBTC_SLOT(7, 0xaaaaaaaa, SLOT_ISO), ++ [CXST_BLK] = __DEF_FBTC_SLOT(500, 0x55555555, SLOT_MIX), ++ [CXST_E2G] = __DEF_FBTC_SLOT(0, 0xea5a5a5a, SLOT_MIX), ++ [CXST_E5G] = __DEF_FBTC_SLOT(0, 0xffffffff, SLOT_ISO), ++ [CXST_EBT] = __DEF_FBTC_SLOT(0, 0xe5555555, SLOT_MIX), ++ [CXST_ENULL] = __DEF_FBTC_SLOT(0, 0xaaaaaaaa, SLOT_ISO), + [CXST_WLK] = __DEF_FBTC_SLOT(250, 0xea5a5a5a, SLOT_MIX), +- [CXST_W1FDD] = __DEF_FBTC_SLOT(35, 0xfafafafa, SLOT_ISO), +- [CXST_B1FDD] = __DEF_FBTC_SLOT(100, 0xffffffff, SLOT_MIX), ++ [CXST_W1FDD] = __DEF_FBTC_SLOT(50, 0xffffffff, SLOT_ISO), ++ [CXST_B1FDD] = __DEF_FBTC_SLOT(50, 0xffffdfff, SLOT_ISO), + }; + + static const u32 cxtbl[] = { +@@ -117,7 +117,12 @@ static const u32 cxtbl[] = { + 0xfafafafa, /* 16 */ + 0xffffddff, /* 17 */ + 0xdaffdaff, /* 18 */ +- 0xfafadafa /* 19 */ ++ 0xfafadafa, /* 19 */ ++ 0xea6a6a6a, /* 20 */ ++ 0xea55556a, /* 21 */ ++ 0xaafafafa, /* 22 */ ++ 0xfafaaafa, /* 23 */ ++ 0xfafffaff /* 24 */ + }; + + static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { +@@ -2701,15 +2706,16 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) + 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[17]); ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[0]); + break; + case BTC_CXP_OFF_EQ3: +- _slot_set_tbl(btc, CXST_OFF, cxtbl[18]); ++ _slot_set_tbl(btc, CXST_OFF, cxtbl[24]); + break; + case BTC_CXP_OFF_BWB0: + _slot_set_tbl(btc, CXST_OFF, cxtbl[5]); +@@ -2765,6 +2771,7 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) + default: + break; + } ++ s[CXST_OFF] = s_def[CXST_OFF]; + break; + case BTC_CXP_FIX: /* TDMA Fix-Slot */ + _write_scbd(rtwdev, BTC_WSCB_TDMA, true); +@@ -2791,6 +2798,10 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type) + _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_TD4020: ++ _slot_set(btc, CXST_W1, 40, cxtbl[1], SLOT_MIX); ++ _slot_set(btc, CXST_B1, 20, tbl_b1, 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); +-- +2.13.6 + diff --git a/SOURCES/0115-wifi-rtw89-coex-Clear-Bluetooth-HW-PTA-counter-when-.patch b/SOURCES/0115-wifi-rtw89-coex-Clear-Bluetooth-HW-PTA-counter-when-.patch new file mode 100644 index 0000000..b5f04e6 --- /dev/null +++ b/SOURCES/0115-wifi-rtw89-coex-Clear-Bluetooth-HW-PTA-counter-when-.patch @@ -0,0 +1,55 @@ +From 4a2b3add123d3960c16b03a6cb0dd240cc5042f5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:37 +0200 +Subject: [PATCH 115/142] wifi: rtw89: coex: Clear Bluetooth HW PTA counter + when radio state change +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit aae256c0f2334691645d52e7cc965bf4241b599b +Author: Ching-Te Ku +Date: Tue Jan 17 19:41:03 2023 +0800 + + wifi: rtw89: coex: Clear Bluetooth HW PTA counter when radio state change + + Reset the counter no matter Wi-Fi is notified turning into power save or + not. With rest the counter coexistence will recognize Bluetooth is hanged + easily. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230117114109.4298-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index a9db33e3bcade..ee6b5fff4928b 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -5335,7 +5335,6 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta + } + + if (rf_state == BTC_RFCTRL_WL_ON) { +- btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; + rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true); + val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG; + _write_scbd(rtwdev, val, true); +@@ -5347,6 +5346,8 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta + _write_scbd(rtwdev, BTC_WSCB_ALL, false); + } + ++ btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; ++ + _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); + + wl->status.map.rf_off_pre = wl->status.map.rf_off; +-- +2.13.6 + diff --git a/SOURCES/0116-wifi-rtw89-coex-Force-to-update-TDMA-parameter-when-.patch b/SOURCES/0116-wifi-rtw89-coex-Force-to-update-TDMA-parameter-when-.patch new file mode 100644 index 0000000..4d2dc4a --- /dev/null +++ b/SOURCES/0116-wifi-rtw89-coex-Force-to-update-TDMA-parameter-when-.patch @@ -0,0 +1,60 @@ +From 526534bd7fc3ceb52ff4291b4c428abb5e156cb6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:37 +0200 +Subject: [PATCH 116/142] wifi: rtw89: coex: Force to update TDMA parameter + when radio state change +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3f857b23dd8dae2c7301476e8e183628edc694d1 +Author: Ching-Te Ku +Date: Tue Jan 17 19:41:04 2023 +0800 + + wifi: rtw89: coex: Force to update TDMA parameter when radio state change + + Force firmware to update TDMA parameter when enter/exit power saving. + The TDMA instant feature will make firmware force update TDMA parameter + immediately when the TDMA parameter H2C to firmware. Without this feature, + it will have a low fail rate trigger Bluetooth audio sound glitch when + Wi-Fi is under power saving. Or Wi-Fi fail to turn in to power save state. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230117114109.4298-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index ee6b5fff4928b..5d6d6230344b0 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -3818,6 +3818,7 @@ static void _action_common(struct rtw89_dev *rtwdev) + wl->scbd_change = false; + btc->cx.cnt_wl[BTC_WCNT_SCBDUPDATE]++; + } ++ btc->dm.tdma_instant_excute = 0; + } + + static void _action_by_bt(struct rtw89_dev *rtwdev) +@@ -5347,6 +5348,11 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta + } + + btc->dm.cnt_dm[BTC_DCNT_BTCNT_FREEZE] = 0; ++ if (wl->status.map.lps_pre == BTC_LPS_OFF && ++ wl->status.map.lps_pre != wl->status.map.lps) ++ btc->dm.tdma_instant_excute = 1; ++ else ++ btc->dm.tdma_instant_excute = 0; + + _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); + +-- +2.13.6 + diff --git a/SOURCES/0117-wifi-rtw89-coex-Refine-coexistence-log.patch b/SOURCES/0117-wifi-rtw89-coex-Refine-coexistence-log.patch new file mode 100644 index 0000000..f270af2 --- /dev/null +++ b/SOURCES/0117-wifi-rtw89-coex-Refine-coexistence-log.patch @@ -0,0 +1,299 @@ +From 4a546fef1a62b4b680149b940f0d8dacfde33843 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:37 +0200 +Subject: [PATCH 117/142] wifi: rtw89: coex: Refine coexistence log +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 7cd8200555d4f01183f0b9071e0760c389a51816 +Author: Ching-Te Ku +Date: Tue Jan 17 19:41:05 2023 +0800 + + wifi: rtw89: coex: Refine coexistence log + + Adjust the log format and correct variable reference to make the log + more readable. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230117114109.4298-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 158 ++++++++++++++---------------- + 1 file changed, 76 insertions(+), 82 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 5d6d6230344b0..33f369e4ff4cf 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -6401,20 +6401,21 @@ static void _show_fbtc_slots(struct rtw89_dev *rtwdev, struct seq_file *m) + + for (i = 0; i < CXST_MAX; i++) { + s = &dm->slot_now[i]; +- if (i % 6 == 0) ++ if (i % 5 == 0) + seq_printf(m, +- " %-15s : %02d[%03d/0x%x/%d]", ++ " %-15s : %5s[%03d/0x%x/%d]", + "[slot_list]", +- (u32)i, ++ id_to_slot((u32)i), + s->dur, s->cxtbl, s->cxtype); + else + seq_printf(m, +- ", %02d[%03d/0x%x/%d]", +- (u32)i, ++ ", %5s[%03d/0x%x/%d]", ++ id_to_slot((u32)i), + s->dur, s->cxtbl, s->cxtype); +- if (i % 6 == 5) ++ if (i % 5 == 4) + seq_puts(m, "\n"); + } ++ seq_puts(m, "\n"); + } + + static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) +@@ -6446,7 +6447,7 @@ static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) + for (i = 0; i < CXST_MAX; i++) { + if (!le32_to_cpu(pcysta_le32->slot_cnt[i])) + continue; +- seq_printf(m, ", %d:%d", (u32)i, ++ seq_printf(m, ", %s:%d", id_to_slot((u32)i), + le32_to_cpu(pcysta_le32->slot_cnt[i])); + } + +@@ -6481,7 +6482,7 @@ static void _show_fbtc_cysta_v2(struct rtw89_dev *rtwdev, struct seq_file *m) + 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) == 0) ++ if (le16_to_cpu(pcysta_le32->cycles) <= 1) + return; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ +@@ -6608,7 +6609,7 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); + + cycle = le16_to_cpu(pcysta->cycles); +- if (cycle == 0) ++ if (cycle <= 1) + return; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ +@@ -6630,40 +6631,39 @@ static void _show_fbtc_cysta_v3(struct rtw89_dev *rtwdev, struct seq_file *m) + cnt++; + store_index = ((cycle - 1) % slot_pair) * 2; + +- if (cnt % divide_cnt == 1) { +- seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); +- } else { +- seq_printf(m, "->b%02d", +- le16_to_cpu(pcysta->slot_step_time[store_index])); +- if (a2dp->exist) { +- a2dp_trx = &pcysta->a2dp_trx[store_index]; +- seq_printf(m, "(%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); +- } +- seq_printf(m, "->w%02d", +- le16_to_cpu(pcysta->slot_step_time[store_index + 1])); +- if (a2dp->exist) { +- a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; +- seq_printf(m, "(%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 == 1) ++ seq_printf(m, " %-15s : ", "[cycle_step]"); ++ ++ seq_printf(m, "->b%02d", ++ le16_to_cpu(pcysta->slot_step_time[store_index])); ++ if (a2dp->exist) { ++ a2dp_trx = &pcysta->a2dp_trx[store_index]; ++ seq_printf(m, "(%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 % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) ++ seq_printf(m, "->w%02d", ++ le16_to_cpu(pcysta->slot_step_time[store_index + 1])); ++ if (a2dp->exist) { ++ a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; ++ seq_printf(m, "(%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) + seq_puts(m, "\n"); + } + + if (a2dp->exist) { +- seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d", ++ seq_printf(m, " %-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)); +@@ -6741,7 +6741,7 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) + le16_to_cpu(pcysta->cycle_time.tmaxdiff[CXT_BT])); + + cycle = le16_to_cpu(pcysta->cycles); +- if (cycle == 0) ++ if (cycle <= 1) + return; + + /* 1 cycle record 1 wl-slot and 1 bt-slot */ +@@ -6763,40 +6763,39 @@ static void _show_fbtc_cysta_v4(struct rtw89_dev *rtwdev, struct seq_file *m) + cnt++; + store_index = ((cycle - 1) % slot_pair) * 2; + +- if (cnt % divide_cnt == 1) { +- seq_printf(m, "\n\r %-15s : ", "[cycle_step]"); +- } else { +- seq_printf(m, "->b%02d", +- le16_to_cpu(pcysta->slot_step_time[store_index])); +- if (a2dp->exist) { +- a2dp_trx = &pcysta->a2dp_trx[store_index]; +- seq_printf(m, "(%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); +- } +- seq_printf(m, "->w%02d", +- le16_to_cpu(pcysta->slot_step_time[store_index + 1])); +- if (a2dp->exist) { +- a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; +- seq_printf(m, "(%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 == 1) ++ seq_printf(m, " %-15s : ", "[cycle_step]"); ++ ++ seq_printf(m, "->b%02d", ++ le16_to_cpu(pcysta->slot_step_time[store_index])); ++ if (a2dp->exist) { ++ a2dp_trx = &pcysta->a2dp_trx[store_index]; ++ seq_printf(m, "(%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 % (BTC_CYCLE_SLOT_MAX / 4) == 0 || cnt == c_end) ++ seq_printf(m, "->w%02d", ++ le16_to_cpu(pcysta->slot_step_time[store_index + 1])); ++ if (a2dp->exist) { ++ a2dp_trx = &pcysta->a2dp_trx[store_index + 1]; ++ seq_printf(m, "(%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) + seq_puts(m, "\n"); + } + + if (a2dp->exist) { +- seq_printf(m, "%-15s : a2dp_ept:%d, a2dp_late:%d", ++ seq_printf(m, " %-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)); +@@ -6827,13 +6826,9 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) + + ns = &pfwinfo->rpt_fbtc_nullsta.finfo; + if (ver->fcxnullsta == 1) { +- seq_printf(m, " %-15s : ", "[null_sta]"); +- + for (i = 0; i < 2; i++) { +- if (i != 0) +- seq_printf(m, ", null-%d", i); +- else +- seq_printf(m, "null-%d", i); ++ seq_printf(m, " %-15s : ", "[NULL-STA]"); ++ seq_printf(m, "null-%d", i); + seq_printf(m, "[ok:%d/", + le32_to_cpu(ns->v1.result[i][1])); + seq_printf(m, "fail:%d/", +@@ -6845,17 +6840,14 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) + seq_printf(m, "avg_t:%d.%03d/", + le32_to_cpu(ns->v1.avg_t[i]) / 1000, + le32_to_cpu(ns->v1.avg_t[i]) % 1000); +- seq_printf(m, "max_t:%d.%03d]", ++ seq_printf(m, "max_t:%d.%03d]\n", + le32_to_cpu(ns->v1.max_t[i]) / 1000, + le32_to_cpu(ns->v1.max_t[i]) % 1000); + } + } else { +- seq_printf(m, " %-15s : ", "[null_sta]"); + for (i = 0; i < 2; i++) { +- if (i != 0) +- seq_printf(m, ", null-%d", i); +- else +- seq_printf(m, "null-%d", i); ++ seq_printf(m, " %-15s : ", "[NULL-STA]"); ++ seq_printf(m, "null-%d", i); + seq_printf(m, "[Tx:%d/", + le32_to_cpu(ns->v2.result[i][4])); + seq_printf(m, "[ok:%d/", +@@ -6869,12 +6861,11 @@ static void _show_fbtc_nullsta(struct rtw89_dev *rtwdev, struct seq_file *m) + seq_printf(m, "avg_t:%d.%03d/", + le32_to_cpu(ns->v2.avg_t[i]) / 1000, + le32_to_cpu(ns->v2.avg_t[i]) % 1000); +- seq_printf(m, "max_t:%d.%03d]", ++ seq_printf(m, "max_t:%d.%03d]\n", + le32_to_cpu(ns->v2.max_t[i]) / 1000, + le32_to_cpu(ns->v2.max_t[i]) % 1000); + } + } +- seq_puts(m, "\n"); + } + + static void _show_fbtc_step_v2(struct rtw89_dev *rtwdev, struct seq_file *m) +@@ -7147,6 +7138,9 @@ static void _show_mreg(struct rtw89_dev *rtwdev, struct seq_file *m) + if (cnt % 6 == 5) + seq_puts(m, "\n"); + cnt++; ++ ++ if (i >= pmreg->reg_num) ++ seq_puts(m, "\n"); + } + + pcinfo = &pfwinfo->rpt_fbtc_gpio_dbg.cinfo; +-- +2.13.6 + diff --git a/SOURCES/0118-wifi-rtw89-coex-Set-Bluetooth-background-scan-PTA-re.patch b/SOURCES/0118-wifi-rtw89-coex-Set-Bluetooth-background-scan-PTA-re.patch new file mode 100644 index 0000000..aed15e2 --- /dev/null +++ b/SOURCES/0118-wifi-rtw89-coex-Set-Bluetooth-background-scan-PTA-re.patch @@ -0,0 +1,48 @@ +From a68c9e193637392a65e94d6ff223bea35b8b705c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:37 +0200 +Subject: [PATCH 118/142] wifi: rtw89: coex: Set Bluetooth background scan PTA + request priority +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 6d2a479c1f9e957908d0fc9d56b9831a48f5ce80 +Author: Ching-Te Ku +Date: Tue Jan 17 19:41:06 2023 +0800 + + wifi: rtw89: coex: Set Bluetooth background scan PTA request priority + + When Wi-Fi is RX, set Bluetooth background scan to low-priority and + not to break Wi-Fi packet. Bluetooth can RX depend on hardware ability + even RX request has been rejected. This way can improve Wi-Fi RX + throughput performance. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230117114109.4298-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 33f369e4ff4cf..bfeef1069318c 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -4763,6 +4763,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason) + _action_wl_nc(rtwdev); + break; + case BTC_WLINK_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_2G_AP: +-- +2.13.6 + diff --git a/SOURCES/0119-wifi-rtw89-coex-Correct-A2DP-exist-variable-source.patch b/SOURCES/0119-wifi-rtw89-coex-Correct-A2DP-exist-variable-source.patch new file mode 100644 index 0000000..a32a108 --- /dev/null +++ b/SOURCES/0119-wifi-rtw89-coex-Correct-A2DP-exist-variable-source.patch @@ -0,0 +1,47 @@ +From ffdf20095b22a5430a5bd7d53399568913fdc894 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:37 +0200 +Subject: [PATCH 119/142] wifi: rtw89: coex: Correct A2DP exist variable source +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit c7d2b22f52bd0088cd39dba57bb7c1e8f3df5489 +Author: Ching-Te Ku +Date: Tue Jan 17 19:41:07 2023 +0800 + + wifi: rtw89: coex: Correct A2DP exist variable source + + When Wi-Fi enter and leave LPS, coexistence driver need to know + is there A2DP exist or not. And when Wi-Fi sleep in deep power save + state will not able to receive mailbox sent from Bluetooth. So update + the A2DP exist information from reading register. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230117114109.4298-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index bfeef1069318c..c0e8a0b2e0b75 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -4602,7 +4602,7 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update) + + bt->whql_test = !!(val & BTC_BSCB_WHQL); + bt->btg_type = val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE; +- bt->link_info.a2dp_desc.active = !!(val & BTC_BSCB_A2DP_ACT); ++ bt->link_info.a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT); + + /* if rfk run 1->0 */ + if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN)) +-- +2.13.6 + diff --git a/SOURCES/0120-wifi-rtw89-coex-Fix-test-fail-when-coexist-with-rasp.patch b/SOURCES/0120-wifi-rtw89-coex-Fix-test-fail-when-coexist-with-rasp.patch new file mode 100644 index 0000000..b6b37be --- /dev/null +++ b/SOURCES/0120-wifi-rtw89-coex-Fix-test-fail-when-coexist-with-rasp.patch @@ -0,0 +1,50 @@ +From 16bf91a80cdf7a47936fa053ae51b480934c716b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 120/142] wifi: rtw89: coex: Fix test fail when coexist with + raspberryPI A2DP idle +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 4b3e7e813bba53402af13ecd5343ac9667ca7608 +Author: Ching-Te Ku +Date: Tue Jan 17 19:41:08 2023 +0800 + + wifi: rtw89: coex: Fix test fail when coexist with raspberryPI A2DP idle + + The origin code will enable TDMA WL:BT = 50:50 to prevent Wi-Fi + throughput suddenly drop to 0 in the moment while A2DP pause. + And this protection just a short moment, and will turn to Bluetooth + idle case when A2DP turn into sniff mode. But the raspberryPI simulated + A2DP device will not turn into sniff mode. So the protection will bring + the throughput drop. + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230117114109.4298-8-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index c0e8a0b2e0b75..89214f2db9851 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -3847,7 +3847,7 @@ static void _action_by_bt(struct rtw89_dev *rtwdev) + case BTC_BT_NOPROFILE: + if (_check_freerun(rtwdev)) + _action_freerun(rtwdev); +- else if (a2dp.active || pan.active) ++ else if (pan.active) + _action_bt_pan(rtwdev); + else + _action_bt_idle(rtwdev); +-- +2.13.6 + diff --git a/SOURCES/0121-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch b/SOURCES/0121-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch new file mode 100644 index 0000000..6b6f076 --- /dev/null +++ b/SOURCES/0121-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch @@ -0,0 +1,48 @@ +From c6399409a8aac25081a7218823e369cc4f82de44 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 121/142] wifi: rtw89: coex: Update Wi-Fi Bluetooth coexistence + version to 7.0.0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit de06588cb95cb3bbece81e9838547c1a3c2aa023 +Author: Ching-Te Ku +Date: Tue Jan 17 19:41:09 2023 +0800 + + wifi: rtw89: coex: Update Wi-Fi Bluetooth coexistence version to 7.0.0 + + Should update the driver with the supported firmware version of the + below item. + Bluetooth firmware BT_Coex_Ver: 0x07 + Wi-Fi firmware version: RTL8852C->v0.27.56.10, RTL8852A->v0.24.36 + + Signed-off-by: Ching-Te Ku + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230117114109.4298-9-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/coex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c +index 89214f2db9851..bcf483cafd203 100644 +--- a/drivers/net/wireless/realtek/rtw89/coex.c ++++ b/drivers/net/wireless/realtek/rtw89/coex.c +@@ -9,7 +9,7 @@ + #include "ps.h" + #include "reg.h" + +-#define RTW89_COEX_VERSION 0x06030013 ++#define RTW89_COEX_VERSION 0x07000013 + #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ + + enum btc_fbtc_tdma_template { +-- +2.13.6 + diff --git a/SOURCES/0122-wifi-rtw89-correct-unit-for-port-offset-and-refine-m.patch b/SOURCES/0122-wifi-rtw89-correct-unit-for-port-offset-and-refine-m.patch new file mode 100644 index 0000000..5b1cab8 --- /dev/null +++ b/SOURCES/0122-wifi-rtw89-correct-unit-for-port-offset-and-refine-m.patch @@ -0,0 +1,66 @@ +From d6bee4e4bfb0f7eb09e14612db7c07e44d2cb01d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 122/142] wifi: rtw89: correct unit for port offset and refine + macro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 1120e6a6c5cd1144694209d6aa6a225af064950a +Author: Zong-Zhe Yang +Date: Thu Jan 19 14:24:51 2023 +0800 + + wifi: rtw89: correct unit for port offset and refine macro + + Strictly speaking, the unit of the offset should be TU instead of ms. + So, correct it and the macro for calculation. Then, to make the macro + generic, the factor n is moved outside. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230119062453.58341-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 4 +++- + drivers/net/wireless/realtek/rtw89/mac.h | 2 +- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 5ab0590485e0d..ea34b4df21a75 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3930,10 +3930,12 @@ static void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, + + /* adjust offset randomly to avoid beacon conflict */ + offset = offset - offset / 4 + get_random_u32() % (offset / 2); +- val = RTW89_PORT_OFFSET_MS_TO_32US((*n_offset)++, offset); ++ val = (*n_offset) * RTW89_PORT_OFFSET_TU_TO_32US(offset); + reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, + rtwvif->mac_idx); + ++ (*n_offset)++; ++ + 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); +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index f0b684b205f10..2556271597441 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -168,7 +168,7 @@ enum rtw89_mac_ax_l0_to_l1_event { + MAC_AX_L0_TO_L1_EVENT_MAX = 15, + }; + +-#define RTW89_PORT_OFFSET_MS_TO_32US(n, shift_ms) ((n) * (shift_ms) * 1000 / 32) ++#define RTW89_PORT_OFFSET_TU_TO_32US(shift_tu) ((shift_tu) * 1024 / 32) + + enum rtw89_mac_dbg_port_sel { + /* CMAC 0 related */ +-- +2.13.6 + diff --git a/SOURCES/0123-wifi-rtw89-split-out-generic-part-of-rtw89_mac_port_.patch b/SOURCES/0123-wifi-rtw89-split-out-generic-part-of-rtw89_mac_port_.patch new file mode 100644 index 0000000..8e6601c --- /dev/null +++ b/SOURCES/0123-wifi-rtw89-split-out-generic-part-of-rtw89_mac_port_.patch @@ -0,0 +1,115 @@ +From 939803986937ded2d8b264a3666479ef5710f0ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 123/142] wifi: rtw89: split out generic part of + rtw89_mac_port_tsf_sync() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 42db7edd5c0523b43a004779caf36e1ebac80b40 +Author: Zong-Zhe Yang +Date: Thu Jan 19 14:24:52 2023 +0800 + + wifi: rtw89: split out generic part of rtw89_mac_port_tsf_sync() + + Originally, rtw89_mac_port_tsf_sync() contains randomization logic + internally. However, not all situation, we need the randomization. + So, split out the generic part from it. And, make the full logic of + original one contained in rtw89_mac_port_tsf_sync_rand(). It will + still be used by its original caller as before. Then, the generic + one will be used in MCC (multi-channel concurrency) management flow. + MCC will implement its logic to decide the offset for TSF sync. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230119062453.58341-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 33 ++++++++++++++++++++------------ + drivers/net/wireless/realtek/rtw89/mac.h | 4 ++++ + 2 files changed, 25 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index ea34b4df21a75..c13edd33b1a48 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3918,27 +3918,36 @@ static void rtw89_mac_port_cfg_tbtt_shift(struct rtw89_dev *rtwdev, + B_AX_TBTT_SHIFT_OFST_MASK, val); + } + +-static void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, +- struct rtw89_vif *rtwvif, +- struct rtw89_vif *rtwvif_src, u8 offset, +- int *n_offset) ++void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ struct rtw89_vif *rtwvif_src, ++ u16 offset_tu) + { + u32 val, reg; + ++ val = RTW89_PORT_OFFSET_TU_TO_32US(offset_tu); ++ reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, ++ rtwvif->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 *rtwvif, ++ struct rtw89_vif *rtwvif_src, ++ u8 offset, int *n_offset) ++{ + if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE || rtwvif == rtwvif_src) + return; + + /* adjust offset randomly to avoid beacon conflict */ + offset = offset - offset / 4 + get_random_u32() % (offset / 2); +- val = (*n_offset) * RTW89_PORT_OFFSET_TU_TO_32US(offset); +- reg = rtw89_mac_reg_by_idx(R_AX_PORT0_TSF_SYNC + rtwvif->port * 4, +- rtwvif->mac_idx); ++ rtw89_mac_port_tsf_sync(rtwdev, rtwvif, rtwvif_src, ++ (*n_offset) * offset); + + (*n_offset)++; +- +- 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_resync_all(struct rtw89_dev *rtwdev) +@@ -3960,7 +3969,7 @@ static void rtw89_mac_port_tsf_resync_all(struct rtw89_dev *rtwdev) + offset /= (vif_aps + 1); + + rtw89_for_each_rtwvif(rtwdev, tmp) +- rtw89_mac_port_tsf_sync(rtwdev, tmp, src, offset, &n_offset); ++ rtw89_mac_port_tsf_sync_rand(rtwdev, tmp, src, offset, &n_offset); + } + + int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 2556271597441..4c50527aad61b 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -906,6 +906,10 @@ 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_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); + int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); ++void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, ++ struct rtw89_vif *rtwvif_src, ++ u16 offset_tu); + void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif); + void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +-- +2.13.6 + diff --git a/SOURCES/0124-wifi-rtw89-mac-add-function-to-get-TSF.patch b/SOURCES/0124-wifi-rtw89-mac-add-function-to-get-TSF.patch new file mode 100644 index 0000000..46df098 --- /dev/null +++ b/SOURCES/0124-wifi-rtw89-mac-add-function-to-get-TSF.patch @@ -0,0 +1,92 @@ +From 301000679a04a67264b8c24b9789e12e315e37f1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 124/142] wifi: rtw89: mac: add function to get TSF +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 76f478a34dafcee28165022b2f73d0ee1f0f47e5 +Author: Zong-Zhe Yang +Date: Thu Jan 19 14:24:53 2023 +0800 + + wifi: rtw89: mac: add function to get TSF + + Add mac function rtw89_mac_port_get_tsf() to get TSF by port. + It will be used when MCC (multi-channel concurrency) calculates + timing things. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230119062453.58341-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 18 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/mac.h | 11 +++++++++++ + 2 files changed, 29 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index c13edd33b1a48..9e73ef6f9bc6e 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -4061,6 +4061,24 @@ int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + return 0; + } + ++int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u64 *tsf) ++{ ++ const struct rtw89_port_reg *p = &rtw_port_base; ++ u32 tsf_low, tsf_high; ++ int ret; ++ ++ ret = rtw89_mac_check_mac_en(rtwdev, rtwvif->mac_idx, RTW89_CMAC_SEL); ++ if (ret) ++ return ret; ++ ++ tsf_low = rtw89_read32_port(rtwdev, rtwvif, p->tsftr_l); ++ tsf_high = rtw89_read32_port(rtwdev, rtwvif, 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) +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 4c50527aad61b..553b38a6d2c31 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -828,6 +828,15 @@ static inline u32 rtw89_mac_reg_by_port(u32 base, u8 port, u8 mac_idx) + } + + static inline u32 ++rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base) ++{ ++ u32 reg; ++ ++ reg = rtw89_mac_reg_by_port(base, rtwvif->port, rtwvif->mac_idx); ++ return rtw89_read32(rtwdev, reg); ++} ++ ++static inline u32 + rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + u32 base, u32 mask) + { +@@ -910,6 +919,8 @@ void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + struct rtw89_vif *rtwvif_src, + u16 offset_tu); ++int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u64 *tsf); + void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif); + void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +-- +2.13.6 + diff --git a/SOURCES/0125-wifi-rtw89-debug-avoid-invalid-access-on-RTW89_DBG_S.patch b/SOURCES/0125-wifi-rtw89-debug-avoid-invalid-access-on-RTW89_DBG_S.patch new file mode 100644 index 0000000..b93d086 --- /dev/null +++ b/SOURCES/0125-wifi-rtw89-debug-avoid-invalid-access-on-RTW89_DBG_S.patch @@ -0,0 +1,59 @@ +From 01fbf7685f349669d3f6dcc8c692ee09a21eaf2d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 125/142] wifi: rtw89: debug: avoid invalid access on + RTW89_DBG_SEL_MAC_30 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit c074da21dd346e0cfef5d08b0715078d7aea7f8d +Author: Zong-Zhe Yang +Date: Thu Jan 19 14:35:28 2023 +0800 + + wifi: rtw89: debug: avoid invalid access on RTW89_DBG_SEL_MAC_30 + + Only 8852C chip has valid pages on RTW89_DBG_SEL_MAC_30. To other chips, + this section is an address hole. It will lead to crash if trying to access + this section on chips except for 8852C. So, we avoid that. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230119063529.61563-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/debug.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +index 8297e35bfa52b..6730eea930ece 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.c ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -615,6 +615,7 @@ rtw89_debug_priv_mac_reg_dump_select(struct file *filp, + struct seq_file *m = (struct seq_file *)filp->private_data; + struct rtw89_debugfs_priv *debugfs_priv = m->private; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; ++ const struct rtw89_chip_info *chip = rtwdev->chip; + char buf[32]; + size_t buf_size; + int sel; +@@ -634,6 +635,12 @@ rtw89_debug_priv_mac_reg_dump_select(struct file *filp, + 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); + +-- +2.13.6 + diff --git a/SOURCES/0126-wifi-rtw89-deal-with-RXI300-error.patch b/SOURCES/0126-wifi-rtw89-deal-with-RXI300-error.patch new file mode 100644 index 0000000..53508b1 --- /dev/null +++ b/SOURCES/0126-wifi-rtw89-deal-with-RXI300-error.patch @@ -0,0 +1,87 @@ +From 1f26560fb8d204637311441addcb07de95a0a1f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 126/142] wifi: rtw89: deal with RXI300 error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit f5d98831badb89172515ac73015d0e7475a285c1 +Author: Zong-Zhe Yang +Date: Thu Jan 19 14:35:29 2023 +0800 + + wifi: rtw89: deal with RXI300 error + + RXI300 is a HW design to maintain stuffs across BUS, e.g. AXI, AHB, APB. + It will feedback an error when host does an invalid BUS operation. + For example, + * BUS master request without power/clock on. + * host reads/writes/accesses an invalid address. + + They might lead to problems such as BUS timeout, platform hang, etc. So, + once if RXI300 feedback an error, it notifies that driver need a L2 SER + (system error recovery) to reset things. + + Previously, driver did not parse the error scenario for RXI300. We add + it and assign a corresponding error code which will make SER flow do L2 + reset. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230119063529.61563-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 5 ++++- + drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 9e73ef6f9bc6e..05a5ad7c2439d 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -623,7 +623,8 @@ static void rtw89_mac_dump_err_status(struct rtw89_dev *rtwdev, + 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_L0_ERR_CMAC1 && ++ err != MAC_AX_ERR_RXI300) + return; + + rtw89_info(rtwdev, "--->\nerr=0x%x\n", err); +@@ -663,6 +664,8 @@ u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) + 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; + + rtw89_fw_st_dbg_dump(rtwdev); + rtw89_mac_dump_err_status(rtwdev, err); +diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h +index 553b38a6d2c31..8064d3953d7f2 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.h ++++ b/drivers/net/wireless/realtek/rtw89/mac.h +@@ -623,6 +623,7 @@ struct rtw89_mac_dle_dfi_qempty { + }; + + enum rtw89_mac_error_scenario { ++ RTW89_RXI300_ERROR = 1, + RTW89_WCPU_CPU_EXCEPTION = 2, + RTW89_WCPU_ASSERTION = 3, + }; +@@ -769,6 +770,7 @@ enum mac_ax_err_info { + 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, + +-- +2.13.6 + diff --git a/SOURCES/0127-wifi-rtw89-fix-parsing-offset-for-MCC-C2H.patch b/SOURCES/0127-wifi-rtw89-fix-parsing-offset-for-MCC-C2H.patch new file mode 100644 index 0000000..2cf9c35 --- /dev/null +++ b/SOURCES/0127-wifi-rtw89-fix-parsing-offset-for-MCC-C2H.patch @@ -0,0 +1,103 @@ +From b84cb5bed1a6928c51852ed1600cf466c99025de Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 127/142] wifi: rtw89: fix parsing offset for MCC C2H +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 24d72944d79e6795ba4330c114de0387386bf3aa +Author: Zong-Zhe Yang +Date: Thu Jan 19 14:43:41 2023 +0800 + + wifi: rtw89: fix parsing offset for MCC C2H + + A 8-byte offset is missed during parsing C2Hs (chip to host packets) + of MCC (multi-channel concurrent) series. + So, we fix it. + + Fixes: ef9dff4cb491 ("wifi: rtw89: mac: process MCC related C2H") + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230119064342.65391-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.h | 34 ++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 3ce59ac48f433..6cb578201b2a8 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -3219,16 +3219,16 @@ static inline struct rtw89_fw_c2h_attr *RTW89_SKB_C2H_CB(struct sk_buff *skb) + le32_get_bits(*((const __le32 *)(c2h) + 5), GENMASK(25, 24)) + + #define RTW89_GET_MAC_C2H_MCC_RCV_ACK_GROUP(c2h) \ +- le32_get_bits(*((const __le32 *)(c2h)), GENMASK(1, 0)) ++ 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)), GENMASK(15, 8)) ++ 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)), GENMASK(1, 0)) ++ 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)), GENMASK(7, 2)) ++ 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)), GENMASK(15, 8)) ++ le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) + + struct rtw89_mac_mcc_tsf_rpt { + u32 macid_x; +@@ -3242,30 +3242,30 @@ struct rtw89_mac_mcc_tsf_rpt { + 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)), GENMASK(7, 0)) ++ 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)), GENMASK(15, 8)) ++ 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)), GENMASK(17, 16)) ++ 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) + 1), GENMASK(31, 0)) ++ 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) + 2), GENMASK(31, 0)) ++ 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) + 3), GENMASK(31, 0)) ++ 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) + 4), GENMASK(31, 0)) ++ 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)), GENMASK(5, 0)) ++ 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)), GENMASK(7, 6)) ++ 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)), GENMASK(15, 8)) ++ 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) + 1), GENMASK(31, 0)) ++ 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) + 2), GENMASK(31, 0)) ++ le32_get_bits(*((const __le32 *)(c2h) + 4), GENMASK(31, 0)) + + #define RTW89_FW_HDR_SIZE 32 + #define RTW89_FW_SECTION_HDR_SIZE 16 +-- +2.13.6 + diff --git a/SOURCES/0128-wifi-rtw89-refine-MCC-C2H-debug-logs.patch b/SOURCES/0128-wifi-rtw89-refine-MCC-C2H-debug-logs.patch new file mode 100644 index 0000000..589f45e --- /dev/null +++ b/SOURCES/0128-wifi-rtw89-refine-MCC-C2H-debug-logs.patch @@ -0,0 +1,114 @@ +From 58dc54df808f49ac70bef3116e4785d5b4b85d5b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:38 +0200 +Subject: [PATCH 128/142] wifi: rtw89: refine MCC C2H debug logs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 214a98b151b14d3dbfa60136abcf99df5d347a80 +Author: Zong-Zhe Yang +Date: Thu Jan 19 14:43:42 2023 +0800 + + wifi: rtw89: refine MCC C2H debug logs + + To debug channel concurrency more centrally, we add a new debug flag, + RTW89_DBG_CHAN, for channel related things, especially channel concurrency. + Then, we change MCC (multi-channel concurrency) C2H (chip to host packets) + debug flag to it. + + Besides, refine debug logs to show TSF in u64 directly. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230119064342.65391-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/debug.h | 1 + + drivers/net/wireless/realtek/rtw89/mac.c | 21 +++++++++++++-------- + 2 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h +index d1de5e600836c..079269bb5251c 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.h ++++ b/drivers/net/wireless/realtek/rtw89/debug.h +@@ -28,6 +28,7 @@ enum rtw89_debug_mask { + RTW89_DBG_STATE = BIT(17), + RTW89_DBG_WOW = BIT(18), + RTW89_DBG_UL_TB = BIT(19), ++ RTW89_DBG_CHAN = BIT(20), + + RTW89_DBG_UNEXP = BIT(31), + }; +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 05a5ad7c2439d..8c622111e832e 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -4295,12 +4295,12 @@ rtw89_mac_c2h_mcc_rcv_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len + case H2C_FUNC_MCC_SET_DURATION: + break; + default: +- rtw89_debug(rtwdev, RTW89_DBG_FW, ++ rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "invalid MCC C2H RCV ACK: func %d\n", func); + return; + } + +- rtw89_debug(rtwdev, RTW89_DBG_FW, ++ rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC C2H RCV ACK: group %d, func %d\n", group, func); + } + +@@ -4328,12 +4328,12 @@ rtw89_mac_c2h_mcc_req_ack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len + case H2C_FUNC_DEL_MCC_GROUP: + case H2C_FUNC_RESET_MCC_GROUP: + default: +- rtw89_debug(rtwdev, RTW89_DBG_FW, ++ rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "invalid MCC C2H REQ ACK: func %d\n", func); + return; + } + +- rtw89_debug(rtwdev, RTW89_DBG_FW, ++ rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "MCC C2H REQ ACK: group %d, func %d, return code %d\n", + group, func, retcode); + +@@ -4361,6 +4361,11 @@ rtw89_mac_c2h_mcc_tsf_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len + 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); + } +@@ -4418,14 +4423,14 @@ rtw89_mac_c2h_mcc_status_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 + rsp = false; + break; + default: +- rtw89_debug(rtwdev, RTW89_DBG_FW, ++ rtw89_debug(rtwdev, RTW89_DBG_CHAN, + "invalid MCC C2H STS RPT: status %d\n", status); + return; + } + +- rtw89_debug(rtwdev, RTW89_DBG_FW, +- "MCC C2H STS RPT: group %d, macid %d, status %d, tsf {%d, %d}\n", +- group, macid, status, tsf_low, tsf_high); ++ 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; +-- +2.13.6 + diff --git a/SOURCES/0129-wifi-rtw89-disallow-enter-PS-mode-after-create-TDLS-.patch b/SOURCES/0129-wifi-rtw89-disallow-enter-PS-mode-after-create-TDLS-.patch new file mode 100644 index 0000000..946dbb1 --- /dev/null +++ b/SOURCES/0129-wifi-rtw89-disallow-enter-PS-mode-after-create-TDLS-.patch @@ -0,0 +1,84 @@ +From 53ef45c93cee683b0a67d5e6bc57f00eca2a9ca6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:39 +0200 +Subject: [PATCH 129/142] wifi: rtw89: disallow enter PS mode after create TDLS + link +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit d881d0a13c3843d213da23cde99bb73f27e53d1e +Author: Kuan-Chung Chen +Date: Thu Jan 19 14:46:31 2023 +0800 + + wifi: rtw89: disallow enter PS mode after create TDLS link + + Buffer STA on TDLS links are not currently supported. Therefore, it + is not allowed to enter the PS mode after TDLS link is established. + + Signed-off-by: Kuan-Chung Chen + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230119064631.66971-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 10 ++++++++-- + drivers/net/wireless/realtek/rtw89/core.h | 1 + + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 4cf4a81ed4f79..23550e193976d 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2206,8 +2206,9 @@ static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev) + + static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) + { +- if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && +- rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) ++ if ((rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION && ++ rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT) || ++ rtwvif->tdls_peer) + return; + + if (rtwvif->stats.tx_tfc_lv == RTW89_TFC_IDLE && +@@ -2466,9 +2467,12 @@ int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) + { ++ struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + + rtwdev->total_sta_assoc--; ++ if (sta->tdls) ++ rtwvif->tdls_peer--; + rtwsta->disassoc = true; + + return 0; +@@ -2587,6 +2591,8 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, + } + + rtwdev->total_sta_assoc++; ++ if (sta->tdls) ++ rtwvif->tdls_peer++; + rtw89_phy_ra_assoc(rtwdev, sta); + rtw89_mac_bf_assoc(rtwdev, vif, sta); + rtw89_mac_bf_monitor_calc(rtwdev, sta, false); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 39c5a003e36cc..a762eef699fa0 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2452,6 +2452,7 @@ struct rtw89_vif { + bool last_a_ctrl; + bool dyn_tb_bedge_en; + u8 def_tri_idx; ++ u32 tdls_peer; + struct work_struct update_beacon_work; + struct rtw89_addr_cam_entry addr_cam; + struct rtw89_bssid_cam_entry bssid_cam; +-- +2.13.6 + diff --git a/SOURCES/0130-wifi-rtw89-fix-potential-wrong-mapping-for-pkt-offlo.patch b/SOURCES/0130-wifi-rtw89-fix-potential-wrong-mapping-for-pkt-offlo.patch new file mode 100644 index 0000000..113cba6 --- /dev/null +++ b/SOURCES/0130-wifi-rtw89-fix-potential-wrong-mapping-for-pkt-offlo.patch @@ -0,0 +1,86 @@ +From 9342b906de5adf5a9a5821d84654bfd3e857139e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:39 +0200 +Subject: [PATCH 130/142] wifi: rtw89: fix potential wrong mapping for + pkt-offload +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit b8e8ff842b1bfe7602409fc71ee812db871ccce6 +Author: Chin-Yen Lee +Date: Mon Jan 23 14:53:56 2023 +0800 + + wifi: rtw89: fix potential wrong mapping for pkt-offload + + When driver fails to send H2C to firmware for pkt-offload, we should not + update the pkt_list of driver, and need to release allocated pkt index to + avoid wrong mapping between driver and firmware. + + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230123065401.14174-2-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/fw.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 85c7172e931bf..210785149801b 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -948,13 +948,13 @@ static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, + if (!skb) + goto err; + +- list_add_tail(&info->list, &rtw_wow->pkt_list); + ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); + kfree_skb(skb); + + if (ret) +- return ret; ++ goto err; + ++ list_add_tail(&info->list, &rtw_wow->pkt_list); + *id = info->id; + return 0; + +@@ -2133,6 +2133,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *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); +@@ -2151,6 +2152,7 @@ int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id, + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); ++ rtw89_core_release_bit_map(rtwdev->pkt_offload, alloc_id); + goto fail; + } + +@@ -2684,13 +2686,14 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, + goto out; + } + +- list_add_tail(&info->list, &scan_info->pkt_list[band]); + 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: +-- +2.13.6 + diff --git a/SOURCES/0131-wifi-rtw89-refine-packet-offload-flow.patch b/SOURCES/0131-wifi-rtw89-refine-packet-offload-flow.patch new file mode 100644 index 0000000..1e450b1 --- /dev/null +++ b/SOURCES/0131-wifi-rtw89-refine-packet-offload-flow.patch @@ -0,0 +1,327 @@ +From 42e89b498c2caef98bc9ee64ed1d6b170308e48b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:39 +0200 +Subject: [PATCH 131/142] wifi: rtw89: refine packet offload flow +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 5c12bb66b79d08b0f7aae99fc2677cab1141d4d2 +Author: Chin-Yen Lee +Date: Mon Jan 23 14:53:57 2023 +0800 + + wifi: rtw89: refine packet offload flow + + For upcoming firmware, driver needs to do packet offload to firmware to + ensure LPS protocol work properly, so we update current connection and + disconnect flow to maintain packet offload flow, and integrate with + current WoWLAN flow which also needs packet offload. + + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230123065401.14174-3-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 17 +++++---- + drivers/net/wireless/realtek/rtw89/core.h | 2 +- + drivers/net/wireless/realtek/rtw89/fw.c | 54 ++++++++++++++++++++++----- + drivers/net/wireless/realtek/rtw89/fw.h | 6 ++- + drivers/net/wireless/realtek/rtw89/mac80211.c | 1 + + drivers/net/wireless/realtek/rtw89/ser.c | 1 + + drivers/net/wireless/realtek/rtw89/wow.c | 26 +++++-------- + 7 files changed, 71 insertions(+), 36 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 23550e193976d..78ce64d1a387d 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2495,8 +2495,10 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, + if (sta->tdls) + rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam); + +- if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) ++ if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + rtw89_vif_type_mapping(vif, false); ++ rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, true); ++ } + + ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta); + if (ret) { +@@ -2584,12 +2586,6 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, + return ret; + } + +- ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwsta->mac_id); +- if (ret) { +- rtw89_warn(rtwdev, "failed to send h2c general packet\n"); +- return ret; +- } +- + rtwdev->total_sta_assoc++; + if (sta->tdls) + rtwvif->tdls_peer++; +@@ -2608,6 +2604,12 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, + BTC_ROLE_MSTS_STA_CONN_END); + rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template); + rtw89_phy_ul_tb_assoc(rtwdev, rtwvif); ++ ++ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c general packet\n"); ++ return ret; ++ } + } + + return ret; +@@ -3132,7 +3134,6 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) + continue; + INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]); + } +- INIT_LIST_HEAD(&rtwdev->wow.pkt_list); + 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); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index a762eef699fa0..505e3b20436ac 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2461,6 +2461,7 @@ struct rtw89_vif { + struct rtw89_phy_rate_pattern rate_pattern; + struct cfg80211_scan_request *scan_req; + struct ieee80211_scan_ies *scan_ies; ++ struct list_head general_pkt_list; + }; + + enum rtw89_lv1_rcvy_step { +@@ -3724,7 +3725,6 @@ struct rtw89_wow_param { + DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM); + struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM]; + u8 pattern_cnt; +- struct list_head pkt_list; + }; + + struct rtw89_mcc_info { +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 210785149801b..dc90074261244 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -10,6 +10,7 @@ + #include "mac.h" + #include "phy.h" + #include "reg.h" ++#include "util.h" + + static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev, + struct sk_buff *skb); +@@ -913,13 +914,12 @@ int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable) + return ret; + } + +-static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, ++static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif, + enum rtw89_fw_pkt_ofld_type type, + u8 *id) + { + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); +- struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + struct rtw89_pktofld_info *info; + struct sk_buff *skb; + int ret; +@@ -954,7 +954,7 @@ static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, + if (ret) + goto err; + +- list_add_tail(&info->list, &rtw_wow->pkt_list); ++ list_add_tail(&info->list, &rtwvif->general_pkt_list); + *id = info->id; + return 0; + +@@ -963,13 +963,48 @@ static int rtw89_fw_h2c_add_wow_fw_ofld(struct rtw89_dev *rtwdev, + return -ENOMEM; + } + ++void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, bool notify_fw) ++{ ++ struct list_head *pkt_list = &rtwvif->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); ++ 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 *rtwvif; ++ ++ rtw89_for_each_rtwvif(rtwdev, rtwvif) ++ rtw89_fw_release_general_pkt_list_vif(rtwdev, rtwvif, 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, u8 macid) ++int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, 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, ++ RTW89_PKT_OFLD_TYPE_PS_POLL, &pkt_id_ps_poll); ++ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, ++ RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id_null); ++ rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, ++ 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"); +@@ -978,9 +1013,9 @@ int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid) + 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, H2C_GENERAL_PKT_ID_UND); +- SET_GENERAL_PKT_NULL_ID(skb->data, H2C_GENERAL_PKT_ID_UND); +- SET_GENERAL_PKT_QOS_NULL_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, +@@ -3099,8 +3134,9 @@ int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, + int ret; + + if (enable) { +- ret = rtw89_fw_h2c_add_wow_fw_ofld(rtwdev, rtwvif, +- RTW89_PKT_OFLD_TYPE_NULL_DATA, &pkt_id); ++ ret = rtw89_fw_h2c_add_general_pkt(rtwdev, rtwvif, ++ RTW89_PKT_OFLD_TYPE_NULL_DATA, ++ &pkt_id); + if (ret) + return -EPERM; + } +diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h +index 6cb578201b2a8..cae07e325326d 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.h ++++ b/drivers/net/wireless/realtek/rtw89/fw.h +@@ -3518,7 +3518,11 @@ int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev, + 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); +-int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid); ++int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, ++ u8 macid); ++void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev, ++ struct rtw89_vif *rtwvif, 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_sta *rtwsta, + bool valid, struct ieee80211_ampdu_params *params); + void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev); +diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c +index f9b95c52916bb..d43281f7335b1 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -135,6 +135,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, + rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0; + rtwvif->hit_rule = 0; + ether_addr_copy(rtwvif->mac_addr, vif->addr); ++ INIT_LIST_HEAD(&rtwvif->general_pkt_list); + + ret = rtw89_mac_add_vif(rtwdev, rtwvif); + if (ret) { +diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c +index c1a4bc1c64d16..61db7189fdab8 100644 +--- a/drivers/net/wireless/realtek/rtw89/ser.c ++++ b/drivers/net/wireless/realtek/rtw89/ser.c +@@ -611,6 +611,7 @@ static void ser_l2_reset_st_pre_hdl(struct rtw89_ser *ser) + 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); + } + +diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c +index b2b826b2e09ae..92fa366ccfcf7 100644 +--- a/drivers/net/wireless/realtek/rtw89/wow.c ++++ b/drivers/net/wireless/realtek/rtw89/wow.c +@@ -490,21 +490,6 @@ static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable) + return ret; + } + +-static void rtw89_wow_release_pkt_list(struct rtw89_dev *rtwdev) +-{ +- struct rtw89_wow_param *rtw_wow = &rtwdev->wow; +- struct list_head *pkt_list = &rtw_wow->pkt_list; +- struct rtw89_pktofld_info *info, *tmp; +- +- list_for_each_entry_safe(info, tmp, pkt_list, list) { +- rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); +- rtw89_core_release_bit_map(rtwdev->pkt_offload, +- info->id); +- list_del(&info->list); +- kfree(info); +- } +-} +- + 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; +@@ -561,6 +546,11 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) + } + + if (is_conn) { ++ ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c general packet\n"); ++ return ret; ++ } + rtw89_phy_ra_assoc(rtwdev, wow_sta); + rtw89_phy_set_bss_color(rtwdev, wow_vif); + rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif); +@@ -708,8 +698,6 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) + goto out; + } + +- rtw89_wow_release_pkt_list(rtwdev); +- + ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n"); +@@ -744,6 +732,8 @@ static int rtw89_wow_enable(struct rtw89_dev *rtwdev) + 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"); +@@ -789,6 +779,8 @@ static int rtw89_wow_disable(struct rtw89_dev *rtwdev) + goto out; + } + ++ rtw89_fw_release_general_pkt_list(rtwdev, true); ++ + ret = rtw89_wow_swap_fw(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable trx_post\n"); +-- +2.13.6 + diff --git a/SOURCES/0132-wifi-rtw89-add-use-of-pkt_list-offload-to-debug-entr.patch b/SOURCES/0132-wifi-rtw89-add-use-of-pkt_list-offload-to-debug-entr.patch new file mode 100644 index 0000000..3f4c1f5 --- /dev/null +++ b/SOURCES/0132-wifi-rtw89-add-use-of-pkt_list-offload-to-debug-entr.patch @@ -0,0 +1,114 @@ +From 310410705b2c19a4fea9911a2e8bf0881522719b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:39 +0200 +Subject: [PATCH 132/142] wifi: rtw89: add use of pkt_list offload to debug + entry +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 5da5ba7e6ec4f13c2abba8de3578a3c197925243 +Author: Ping-Ke Shih +Date: Mon Jan 23 14:53:58 2023 +0800 + + wifi: rtw89: add use of pkt_list offload to debug entry + + Driver can prepare pkt_list for firmware that only uses them to send out + the packets in specific situations. To understand the usage of current + status, and to check if there is leakage problem, dump bitmap and the + indices used by certain function. + + An example looks like: + + map: + ... + pkt_ofld: 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... + [SCAN 0]: 3 + [SCAN 1]: 4 + [SCAN 3]: 5 + VIF [0] xx:xx:xx:xx:xx:xx + ... + pkt_ofld[GENERAL]: 0 1 2 + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230123065401.14174-4-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/debug.c | 36 ++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c +index 6730eea930ece..0e0e1483c099b 100644 +--- a/drivers/net/wireless/realtek/rtw89/debug.c ++++ b/drivers/net/wireless/realtek/rtw89/debug.c +@@ -3354,6 +3354,31 @@ static void rtw89_dump_addr_cam(struct seq_file *m, + } + } + ++__printf(3, 4) ++static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_list, ++ const char *fmt, ...) ++{ ++ struct rtw89_pktofld_info *info; ++ struct va_format vaf; ++ va_list args; ++ ++ if (list_empty(pkt_list)) ++ return; ++ ++ va_start(args, fmt); ++ vaf.va = &args; ++ vaf.fmt = fmt; ++ ++ seq_printf(m, "%pV", &vaf); ++ ++ va_end(args); ++ ++ list_for_each_entry(info, pkt_list, list) ++ seq_printf(m, "%d ", info->id); ++ ++ seq_puts(m, "\n"); ++} ++ + static + void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) + { +@@ -3364,6 +3389,7 @@ void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) + seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr); + seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx); + rtw89_dump_addr_cam(m, &rtwvif->addr_cam); ++ rtw89_dump_pkt_offload(m, &rtwvif->general_pkt_list, "\tpkt_ofld[GENERAL]: "); + } + + static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta) +@@ -3402,6 +3428,7 @@ static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v) + struct rtw89_debugfs_priv *debugfs_priv = m->private; + struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; ++ u8 idx; + + mutex_lock(&rtwdev->mutex); + +@@ -3416,6 +3443,15 @@ static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v) + cam_info->sec_cam_map); + seq_printf(m, "\tba_cam: %*ph\n", (int)sizeof(cam_info->ba_cam_map), + cam_info->ba_cam_map); ++ seq_printf(m, "\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; ++ rtw89_dump_pkt_offload(m, &rtwdev->scan_info.pkt_list[idx], ++ "\t\t[SCAN %u]: ", idx); ++ } + + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, + IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m); +-- +2.13.6 + diff --git a/SOURCES/0133-wifi-rtw89-8852b-reset-IDMEM-mode-to-default-value.patch b/SOURCES/0133-wifi-rtw89-8852b-reset-IDMEM-mode-to-default-value.patch new file mode 100644 index 0000000..1d1b73c --- /dev/null +++ b/SOURCES/0133-wifi-rtw89-8852b-reset-IDMEM-mode-to-default-value.patch @@ -0,0 +1,74 @@ +From 594b7e7ab1f22ea71fff9894aace17a5eef45715 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:39 +0200 +Subject: [PATCH 133/142] wifi: rtw89: 8852b: reset IDMEM mode to default value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 2e5a65f5952fe451777066e99531abc6bc684573 +Author: Ping-Ke Shih +Date: Mon Jan 23 14:53:59 2023 +0800 + + wifi: rtw89: 8852b: reset IDMEM mode to default value + + For different firmware type, it could use different IDMEM mode, so reset + it to default to avoid encountering error during we bisect firmware + version, like + + rtw89_8852be 0000:03:00.0: Firmware version 0.29.26.0, cmd version 0, type 5 + rtw89_8852be 0000:03:00.0: Firmware version 0.29.26.0, cmd version 0, type 3 + rtw89_8852be 0000:03:00.0: fw security fail + rtw89_8852be 0000:03:00.0: download firmware fail + rtw89_8852be 0000:03:00.0: [ERR]fwdl 0x1E0 = 0x62 + rtw89_8852be 0000:03:00.0: [ERR]fwdl 0x83F2 = 0x8 + rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb8931154 + rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb8931154 + rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb8931150 + rtw89_8852be 0000:03:00.0: [ERR]fw PC = 0xb8931154 + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230123065401.14174-5-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 5 +++++ + drivers/net/wireless/realtek/rtw89/reg.h | 3 +++ + 2 files changed, 8 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 8c622111e832e..99a42fc38e6ae 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -3414,6 +3414,11 @@ int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) + val |= B_AX_WCPU_FWDL_EN; + + rtw89_write32(rtwdev, R_AX_WCPU_FW_CTRL, val); ++ ++ if (rtwdev->chip->chip_id == RTL8852B) ++ 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); +diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h +index 036953f0ec464..600257909df27 100644 +--- a/drivers/net/wireless/realtek/rtw89/reg.h ++++ b/drivers/net/wireless/realtek/rtw89/reg.h +@@ -275,6 +275,9 @@ + #define B_AX_S1_LDO2PWRCUT_F BIT(23) + #define B_AX_S0_LDO_VSEL_F_MASK GENMASK(22, 21) + ++#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 +-- +2.13.6 + diff --git a/SOURCES/0134-wifi-rtw89-8852b-don-t-support-LPS-PG-mode-after-fir.patch b/SOURCES/0134-wifi-rtw89-8852b-don-t-support-LPS-PG-mode-after-fir.patch new file mode 100644 index 0000000..26310c2 --- /dev/null +++ b/SOURCES/0134-wifi-rtw89-8852b-don-t-support-LPS-PG-mode-after-fir.patch @@ -0,0 +1,90 @@ +From 0257ed1c04c87827e78bdd40ffe2b79e256fa8dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:39 +0200 +Subject: [PATCH 134/142] wifi: rtw89: 8852b: don't support LPS-PG mode after + firmware 0.29.26.0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit e5624482ba3e98f0c34fc72bca509c6017266253 +Author: Ping-Ke Shih +Date: Mon Jan 23 14:54:00 2023 +0800 + + wifi: rtw89: 8852b: don't support LPS-PG mode after firmware 0.29.26.0 + + Due to firmware size limit of 8852b, LPS-PG mode isn't supported after + 0.29.26.0, and then we have more space to support other features, such as + P2P-PS, hardware scan and so on. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230123065401.14174-6-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 6 ++++-- + drivers/net/wireless/realtek/rtw89/core.h | 1 + + drivers/net/wireless/realtek/rtw89/fw.c | 1 + + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 78ce64d1a387d..3ed2f3a966353 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -1764,7 +1764,8 @@ static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev) + 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)) ++ 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)) +@@ -3160,7 +3161,6 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) + rtw89_core_ppdu_sts_init(rtwdev); + rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); + +- rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); + rtwdev->hal.rx_fltr = DEFAULT_AX_RX_FLTR; + + INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work); +@@ -3316,6 +3316,8 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev) + if (ret) + return ret; + ++ rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev); ++ + return 0; + } + EXPORT_SYMBOL(rtw89_chip_info_setup); +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 505e3b20436ac..75705dcc0996e 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -3023,6 +3023,7 @@ enum rtw89_fw_feature { + RTW89_FW_FEATURE_CRASH_TRIGGER, + RTW89_FW_FEATURE_PACKET_DROP, + RTW89_FW_FEATURE_NO_DEEP_PS, ++ RTW89_FW_FEATURE_NO_LPS_PG, + }; + + struct rtw89_fw_suit { +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index dc90074261244..4da5eedbf8aac 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -255,6 +255,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), + __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 38, 0, PACKET_DROP), ++ __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP), + __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), + __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), +-- +2.13.6 + diff --git a/SOURCES/0135-wifi-rtw89-8852b-try-to-use-NORMAL_CE-type-firmware-.patch b/SOURCES/0135-wifi-rtw89-8852b-try-to-use-NORMAL_CE-type-firmware-.patch new file mode 100644 index 0000000..7cb17d8 --- /dev/null +++ b/SOURCES/0135-wifi-rtw89-8852b-try-to-use-NORMAL_CE-type-firmware-.patch @@ -0,0 +1,164 @@ +From 69555f8f2619955f9ed119e62f6fc6330e1a5fe0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:40 +0200 +Subject: [PATCH 135/142] wifi: rtw89: 8852b: try to use NORMAL_CE type + firmware first +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 7410bd727584ea9b3e1050c56fdf60d883398956 +Author: Ping-Ke Shih +Date: Mon Jan 23 14:54:01 2023 +0800 + + wifi: rtw89: 8852b: try to use NORMAL_CE type firmware first + + New firmware type NORMAL_CE is introduced to support P2P-PS and hardware + scan, but no LPS-PG mode. After this patch, old firmware with NORMAL type + can still work well. + + The use of this new type is the same as before, so we add new type to + avoid taking wrong firmware. Then, driver log can also give clear + information about this change: + + rtw89_8852be 0000:03:00.0: Firmware version 0.29.26.0, cmd version 0, type 5 + rtw89_8852be 0000:03:00.0: Firmware version 0.29.26.0, cmd version 0, type 3 + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230123065401.14174-7-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.h | 2 ++ + drivers/net/wireless/realtek/rtw89/fw.c | 22 ++++++++++++++++------ + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + + 5 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h +index 75705dcc0996e..41365ffb7e5ea 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.h ++++ b/drivers/net/wireless/realtek/rtw89/core.h +@@ -2848,6 +2848,7 @@ struct rtw89_chip_info { + enum rtw89_core_chip_id chip_id; + const struct rtw89_chip_ops *ops; + const char *fw_name; ++ bool try_ce_fw; + u32 fifo_size; + u32 dle_scc_rsvd_size; + u16 max_amsdu_limit; +@@ -3014,6 +3015,7 @@ static inline void rtw89_init_wait(struct rtw89_wait_info *wait) + enum rtw89_fw_type { + RTW89_FW_NORMAL = 1, + RTW89_FW_WOWLAN = 3, ++ RTW89_FW_NORMAL_CE = 5, + }; + + enum rtw89_fw_feature { +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index 4da5eedbf8aac..0b73dc2e9ad77 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -152,7 +152,7 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len, + + static + int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, +- struct rtw89_fw_suit *fw_suit) ++ struct rtw89_fw_suit *fw_suit, bool nowarn) + { + struct rtw89_fw_info *fw_info = &rtwdev->fw; + const u8 *mfw = fw_info->firmware->data; +@@ -183,7 +183,8 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, + return 0; + } + +- rtw89_err(rtwdev, "no suitable firmware found\n"); ++ if (!nowarn) ++ rtw89_err(rtwdev, "no suitable firmware found\n"); + return -ENOENT; + } + +@@ -211,12 +212,13 @@ static void rtw89_fw_update_ver(struct rtw89_dev *rtwdev, + } + + static +-int __rtw89_fw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) ++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); ++ ret = rtw89_mfw_recognize(rtwdev, type, fw_suit, nowarn); + if (ret) + return ret; + +@@ -343,14 +345,22 @@ rtw89_early_fw_feature_recognize(struct device *device, + + int rtw89_fw_recognize(struct rtw89_dev *rtwdev) + { ++ const struct rtw89_chip_info *chip = rtwdev->chip; + int ret; + +- ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL); ++ 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, RTW89_FW_NORMAL, false); + if (ret) + return ret; + ++normal_done: + /* It still works if wowlan firmware isn't existing. */ +- __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN); ++ __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false); + + rtw89_fw_recognize_features(rtwdev); + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +index 45119c512a051..9c42b6abd2232 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c +@@ -2055,6 +2055,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { + .chip_id = RTL8852A, + .ops = &rtw8852a_chip_ops, + .fw_name = "rtw89/rtw8852a_fw.bin", ++ .try_ce_fw = false, + .fifo_size = 458752, + .dle_scc_rsvd_size = 0, + .max_amsdu_limit = 3500, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index c6345228d049f..1c25540f776d0 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -2430,6 +2430,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { + .chip_id = RTL8852B, + .ops = &rtw8852b_chip_ops, + .fw_name = "rtw89/rtw8852b_fw.bin", ++ .try_ce_fw = true, + .fifo_size = 196608, + .dle_scc_rsvd_size = 98304, + .max_amsdu_limit = 3500, +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index 00fbb65355061..e6f5a0eb58964 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -2857,6 +2857,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { + .chip_id = RTL8852C, + .ops = &rtw8852c_chip_ops, + .fw_name = "rtw89/rtw8852c_fw.bin", ++ .try_ce_fw = false, + .fifo_size = 458752, + .dle_scc_rsvd_size = 0, + .max_amsdu_limit = 8000, +-- +2.13.6 + diff --git a/SOURCES/0136-wifi-rtw89-8852be-enable-CLKREQ-of-PCI-capability.patch b/SOURCES/0136-wifi-rtw89-8852be-enable-CLKREQ-of-PCI-capability.patch new file mode 100644 index 0000000..adae48d --- /dev/null +++ b/SOURCES/0136-wifi-rtw89-8852be-enable-CLKREQ-of-PCI-capability.patch @@ -0,0 +1,44 @@ +From a45f5e86d7bdf1ec96c04dcd2435869a6742da87 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:40 +0200 +Subject: [PATCH 136/142] wifi: rtw89: 8852be: enable CLKREQ of PCI capability +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 3712888e3dba5df2b4f3fb3ba87e20bac6afc7c0 +Author: Chin-Yen Lee +Date: Thu Jan 26 19:27:15 2023 +0800 + + wifi: rtw89: 8852be: enable CLKREQ of PCI capability + + Enable CLKREQ to reduce power consumption for 8852BE. + + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230126112715.5811-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c +index 0ea734c81b4f0..ec8bb5f10482e 100644 +--- a/drivers/net/wireless/realtek/rtw89/pci.c ++++ b/drivers/net/wireless/realtek/rtw89/pci.c +@@ -3398,7 +3398,7 @@ static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable) + if (ret) + rtw89_err(rtwdev, "failed to set CLKREQ Delay\n"); + +- if (chip_id == RTL8852A) { ++ if (chip_id == RTL8852A || chip_id == RTL8852B) { + if (enable) + ret = rtw89_pci_config_byte_set(rtwdev, + RTW89_PCIE_L1_CTRL, +-- +2.13.6 + diff --git a/SOURCES/0137-wifi-rtw89-use-passed-channel-in-set_tx_shape_dfir.patch b/SOURCES/0137-wifi-rtw89-use-passed-channel-in-set_tx_shape_dfir.patch new file mode 100644 index 0000000..80fb629 --- /dev/null +++ b/SOURCES/0137-wifi-rtw89-use-passed-channel-in-set_tx_shape_dfir.patch @@ -0,0 +1,98 @@ +From 9bbc9559017e841615a029d04a2f4e4be30da9a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:40 +0200 +Subject: [PATCH 137/142] wifi: rtw89: use passed channel in + set_tx_shape_dfir() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 764f07f4565da0c0f94f24d18f9d6f5ddb39ccd8 +Author: Zong-Zhe Yang +Date: Wed Feb 1 11:20:57 2023 +0800 + + wifi: rtw89: use passed channel in set_tx_shape_dfir() + + In path of setting channel and setting TX power, the rtw89_chan instance + to be used is controlled by top and passed down. The set_tx_shape_dfir() + is in path of setting TX power, so it should use the passed rtw89_chan + instead of querying it itself. Otherwise, it might encounter mismatch + between parameters if multi-channel. + + For example, + rtw89_8852ce 0000:04:00.0: set tx shape dfir by unknown ch: 155 on 2GHz + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230201032057.7349-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 4 ++-- + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 1c25540f776d0..1313c16ca9d32 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -1618,6 +1618,7 @@ static void rtw8852b_set_txpwr_ref(struct rtw89_dev *rtwdev, + } + + static void rtw8852b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, ++ const struct rtw89_chan *chan, + u8 tx_shape_idx, + enum rtw89_phy_idx phy_idx) + { +@@ -1637,7 +1638,6 @@ static void rtw8852b_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + __DECL_DFIR_PARAM(sharp_14, + 0x023B13FF, 0x001C42DE, 0x00FDB0AD, 0x00F60F6E, + 0x00FD8F92, 0x0602D011, 0x0001C02C, 0x00FFF00A); +- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); + u8 ch = chan->channel; + const u32 *param; + u32 addr; +@@ -1678,7 +1678,7 @@ static void rtw8852b_set_tx_shape(struct rtw89_dev *rtwdev, + u8 tx_shape_ofdm = rtw89_8852b_tx_shape[band][RTW89_RS_OFDM][regd]; + + if (band == RTW89_BAND_2G) +- rtw8852b_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); ++ rtw8852b_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); +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +index e6f5a0eb58964..d2dde21d3daf5 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c +@@ -1968,6 +1968,7 @@ static void rtw8852c_set_txpwr_ref(struct rtw89_dev *rtwdev, + } + + 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) + { +@@ -1991,7 +1992,6 @@ static void rtw8852c_bb_set_tx_shape_dfir(struct rtw89_dev *rtwdev, + __DECL_DFIR_ADDR(filter, + 0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0, + 0x45C4, 0x45C8); +- const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); + u8 ch = chan->channel; + const u32 *param; + int i; +@@ -2032,7 +2032,7 @@ static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev, + u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd]; + + if (band == RTW89_BAND_2G) +- rtw8852c_bb_set_tx_shape_dfir(rtwdev, tx_shape_cck, phy_idx); ++ 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, +-- +2.13.6 + diff --git a/SOURCES/0138-wifi-rtw89-8852b-correct-register-mask-name-of-TX-po.patch b/SOURCES/0138-wifi-rtw89-8852b-correct-register-mask-name-of-TX-po.patch new file mode 100644 index 0000000..e063c1a --- /dev/null +++ b/SOURCES/0138-wifi-rtw89-8852b-correct-register-mask-name-of-TX-po.patch @@ -0,0 +1,47 @@ +From e099a10c0168ad268c8f324cc2b551ba3d2c8655 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:40 +0200 +Subject: [PATCH 138/142] wifi: rtw89: 8852b: correct register mask name of TX + power offset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 5466ee9a7c63e18d3daea0bf80152944648218d2 +Author: Ping-Ke Shih +Date: Fri Feb 3 14:49:07 2023 +0800 + + wifi: rtw89: 8852b: correct register mask name of TX power offset + + For a packet with 1SS rate, it can also transmit via 2 antenna, called + 2T mode. For 2T TX power offset, mask should be 2T as well. Fortunately, + the mask of 2T and 1T are the same, so it can still work well without + this fix. + + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230203064907.8046-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +index 1313c16ca9d32..ee8dba7e0074a 100644 +--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c ++++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c +@@ -1720,7 +1720,7 @@ void rtw8852b_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev, + + pw_ofst = max_t(s8, pw_ofst - 3, -16); + reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx); +- rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_MASK, pw_ofst); ++ rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_MASK, pw_ofst); + } + + static int +-- +2.13.6 + diff --git a/SOURCES/0139-wifi-rtw89-phy-set-TX-power-according-to-RF-path-num.patch b/SOURCES/0139-wifi-rtw89-phy-set-TX-power-according-to-RF-path-num.patch new file mode 100644 index 0000000..11a5168 --- /dev/null +++ b/SOURCES/0139-wifi-rtw89-phy-set-TX-power-according-to-RF-path-num.patch @@ -0,0 +1,90 @@ +From 43ad0f51d78b5ddca2f7e7ae3251d6fa70a5c90c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:40 +0200 +Subject: [PATCH 139/142] wifi: rtw89: phy: set TX power according to RF path + number by chip +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit ddf9a2ead1676db46abe8acca3f689fd572a44d1 +Author: Zong-Zhe Yang +Date: Fri Feb 3 14:51:57 2023 +0800 + + wifi: rtw89: phy: set TX power according to RF path number by chip + + Previously, all supported chips had two RF paths. Therefore, these + codes used static number for TX power setting. Now, we are planning + to support a new chip which has only one RF path. So, we refine the + setting codes to refer to chip's RF path number at runtime. + + Signed-off-by: Zong-Zhe Yang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230203065157.8227-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/phy.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c +index ca2b5c17d6da0..d9f61ba3d1765 100644 +--- a/drivers/net/wireless/realtek/rtw89/phy.c ++++ b/drivers/net/wireless/realtek/rtw89/phy.c +@@ -2042,6 +2042,7 @@ void rtw89_phy_set_txpwr_byrate(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, +@@ -2064,7 +2065,7 @@ void rtw89_phy_set_txpwr_byrate(struct rtw89_dev *rtwdev, + BUILD_BUG_ON(rtw89_rs_idx_max[RTW89_RS_HEDCM] % 4); + + addr = R_AX_PWR_BY_RATE; +- for (cur.nss = 0; cur.nss <= RTW89_NSS_2; cur.nss++) { ++ 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_max[rs[i]]) + continue; +@@ -2127,6 +2128,7 @@ void rtw89_phy_set_txpwr_limit(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 lmt; + u8 ch = chan->channel; + u8 bw = chan->band_width; +@@ -2141,7 +2143,7 @@ void rtw89_phy_set_txpwr_limit(struct rtw89_dev *rtwdev, + RTW89_TXPWR_LMT_PAGE_SIZE); + + addr = R_AX_PWR_LMT; +- for (i = 0; i < RTW89_NTX_NUM; i++) { ++ for (i = 0; i < max_ntx_num; i++) { + rtw89_phy_fill_txpwr_limit(rtwdev, chan, &lmt, i); + + ptr = (s8 *)&lmt; +@@ -2162,6 +2164,7 @@ void rtw89_phy_set_txpwr_limit_ru(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 lmt_ru; + u8 ch = chan->channel; + u8 bw = chan->band_width; +@@ -2176,7 +2179,7 @@ void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev, + RTW89_TXPWR_LMT_RU_PAGE_SIZE); + + addr = R_AX_PWR_RU_LMT; +- for (i = 0; i < RTW89_NTX_NUM; i++) { ++ for (i = 0; i < max_ntx_num; i++) { + rtw89_phy_fill_txpwr_limit_ru(rtwdev, chan, &lmt_ru, i); + + ptr = (s8 *)&lmt_ru; +-- +2.13.6 + diff --git a/SOURCES/0140-wifi-rtw89-use-readable-return-0-in-rtw89_mac_cfg_pp.patch b/SOURCES/0140-wifi-rtw89-use-readable-return-0-in-rtw89_mac_cfg_pp.patch new file mode 100644 index 0000000..0ad7770 --- /dev/null +++ b/SOURCES/0140-wifi-rtw89-use-readable-return-0-in-rtw89_mac_cfg_pp.patch @@ -0,0 +1,68 @@ +From 6db3151e1b0eb5e1a3159dcb401c532df3252008 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:40 +0200 +Subject: [PATCH 140/142] wifi: rtw89: use readable return 0 in + rtw89_mac_cfg_ppdu_status() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 210871887208d1098d65b9bb597e7f9aa1c66900 +Author: Ping-Ke Shih +Date: Mon Feb 13 17:13:28 2023 +0800 + + wifi: rtw89: use readable return 0 in rtw89_mac_cfg_ppdu_status() + + For normal (successful) flow, it must return 0. The original code uses + 'return ret', and then we need to backward reference to initial value to + know 'ret = 0'. Changing them to 'return 0', because it will be more + readable and intuitive. This patch doesn't change logic at all. + + Reported-by: kernel test robot + Reported-by: Dan Carpenter + Link: https://lore.kernel.org/r/202302101023.ctlih5q0-lkp@intel.com/ + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230213091328.25481-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/mac.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c +index 99a42fc38e6ae..2e2a2b6eab09d 100644 +--- a/drivers/net/wireless/realtek/rtw89/mac.c ++++ b/drivers/net/wireless/realtek/rtw89/mac.c +@@ -4554,7 +4554,7 @@ EXPORT_SYMBOL(rtw89_mac_get_txpwr_cr); + int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) + { + u32 reg = rtw89_mac_reg_by_idx(R_AX_PPDU_STAT, mac_idx); +- int ret = 0; ++ int ret; + + ret = rtw89_mac_check_mac_en(rtwdev, mac_idx, RTW89_CMAC_SEL); + if (ret) +@@ -4562,7 +4562,7 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) + + if (!enable) { + rtw89_write32_clr(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN); +- return ret; ++ return 0; + } + + rtw89_write32(rtwdev, reg, B_AX_PPDU_STAT_RPT_EN | +@@ -4572,7 +4572,7 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable) + rtw89_write32_mask(rtwdev, R_AX_HW_RPT_FWD, B_AX_FWD_PPDU_STAT_MASK, + RTW89_PRPT_DEST_HOST); + +- return ret; ++ return 0; + } + EXPORT_SYMBOL(rtw89_mac_cfg_ppdu_status); + +-- +2.13.6 + diff --git a/SOURCES/0141-wifi-rtw89-move-H2C-of-del_pkt_offload-before-pollin.patch b/SOURCES/0141-wifi-rtw89-move-H2C-of-del_pkt_offload-before-pollin.patch new file mode 100644 index 0000000..c08dc5b --- /dev/null +++ b/SOURCES/0141-wifi-rtw89-move-H2C-of-del_pkt_offload-before-pollin.patch @@ -0,0 +1,56 @@ +From 7ff78adf4cef672ea8aeea5289981b4b150e01c6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:40 +0200 +Subject: [PATCH 141/142] wifi: rtw89: move H2C of del_pkt_offload before + polling FW status ready +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit ce1ba4d782d94fc8ed9116c774e2e5885626836b +Author: Chin-Yen Lee +Date: Tue Feb 14 19:43:14 2023 +0800 + + wifi: rtw89: move H2C of del_pkt_offload before polling FW status ready + + The H2C of del_pkt_offload must be called before polling FW status + ready, otherwise the following downloading normal FW will fail. + + Fixes: 5c12bb66b79d ("wifi: rtw89: refine packet offload flow") + Signed-off-by: Chin-Yen Lee + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230214114314.5268-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/wow.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c +index 92fa366ccfcf7..c78ee2ab732c9 100644 +--- a/drivers/net/wireless/realtek/rtw89/wow.c ++++ b/drivers/net/wireless/realtek/rtw89/wow.c +@@ -710,6 +710,8 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) + goto out; + } + ++ rtw89_fw_release_general_pkt_list(rtwdev, true); ++ + ret = rtw89_wow_check_fw_status(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to check disable fw ready\n"); +@@ -779,8 +781,6 @@ static int rtw89_wow_disable(struct rtw89_dev *rtwdev) + goto out; + } + +- rtw89_fw_release_general_pkt_list(rtwdev, true); +- + ret = rtw89_wow_swap_fw(rtwdev, false); + if (ret) { + rtw89_err(rtwdev, "wow: failed to disable trx_post\n"); +-- +2.13.6 + diff --git a/SOURCES/0142-wifi-rtw89-fix-AP-mode-authentication-transmission-f.patch b/SOURCES/0142-wifi-rtw89-fix-AP-mode-authentication-transmission-f.patch new file mode 100644 index 0000000..6c0a61a --- /dev/null +++ b/SOURCES/0142-wifi-rtw89-fix-AP-mode-authentication-transmission-f.patch @@ -0,0 +1,127 @@ +From d44a19d9cfa0ed1fcc25c65489f1336dbcbfb5d1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Wed, 24 May 2023 15:00:40 +0200 +Subject: [PATCH 142/142] wifi: rtw89: fix AP mode authentication transmission + failed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bugzilla: https://bugzilla.redhat.com/2207499 + +commit 0731d0b664f26f54b6293421af54da15b9eb1c8c +Author: Po-Hao Huang +Date: Thu Feb 16 16:28:07 2023 +0800 + + wifi: rtw89: fix AP mode authentication transmission failed + + For some ICs, packets can't be sent correctly without initializing + CMAC table first. Previous flow do this initialization after + associated, results in authentication response fails to transmit. + Move the initialization up front to a proper place to solve this. + + Signed-off-by: Po-Hao Huang + Signed-off-by: Ping-Ke Shih + Signed-off-by: Kalle Valo + Link: https://lore.kernel.org/r/20230216082807.22285-1-pkshih@realtek.com + +Signed-off-by: Íñigo Huguet +--- + drivers/net/wireless/realtek/rtw89/core.c | 47 +++++++++++++++++-------------- + 1 file changed, 26 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c +index 3ed2f3a966353..f09361bc4a4d1 100644 +--- a/drivers/net/wireless/realtek/rtw89/core.c ++++ b/drivers/net/wireless/realtek/rtw89/core.c +@@ -2435,6 +2435,7 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + int i; ++ int ret; + + rtwsta->rtwdev = rtwdev; + rtwsta->rtwvif = rtwvif; +@@ -2459,6 +2460,21 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, + RTW89_MAX_MAC_ID_NUM); + if (rtwsta->mac_id == RTW89_MAX_MAC_ID_NUM) + return -ENOSPC; ++ ++ ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false); ++ if (ret) { ++ rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id); ++ rtw89_warn(rtwdev, "failed to send h2c macid pause\n"); ++ return ret; ++ } ++ ++ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, ++ RTW89_ROLE_CREATE); ++ if (ret) { ++ rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id); ++ rtw89_warn(rtwdev, "failed to send h2c role info\n"); ++ return ret; ++ } + } + + return 0; +@@ -2513,14 +2529,6 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev, + return ret; + } + +- if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { +- ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, RTW89_ROLE_REMOVE); +- if (ret) { +- rtw89_warn(rtwdev, "failed to send h2c role info\n"); +- return ret; +- } +- } +- + /* update cam aid mac_id net_type */ + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); + if (ret) { +@@ -2541,18 +2549,6 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev, + int ret; + + if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { +- ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->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, rtwsta, RTW89_ROLE_CREATE); +- if (ret) { +- rtw89_warn(rtwdev, "failed to send h2c role info\n"); +- return ret; +- } +- + if (sta->tdls) { + ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, sta->addr); + if (ret) { +@@ -2622,13 +2618,22 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev, + { + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; ++ int ret; + + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) + rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta, + BTC_ROLE_MSTS_STA_DIS_CONN); +- else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) ++ else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) { + rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id); + ++ ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, ++ RTW89_ROLE_REMOVE); ++ if (ret) { ++ rtw89_warn(rtwdev, "failed to send h2c role info\n"); ++ return ret; ++ } ++ } ++ + return 0; + } + +-- +2.13.6 + diff --git a/SOURCES/9000-add-driver-version.patch b/SOURCES/9000-add-driver-version.patch new file mode 100644 index 0000000..66ec102 --- /dev/null +++ b/SOURCES/9000-add-driver-version.patch @@ -0,0 +1,36 @@ +Index: src/drivers/net/wireless/realtek/rtw89/core.c +=================================================================== +--- src.orig/drivers/net/wireless/realtek/rtw89/core.c 2023-05-30 10:16:49.910826005 +0200 ++++ src/drivers/net/wireless/realtek/rtw89/core.c 2023-05-30 10:24:44.602864833 +0200 +@@ -3510,3 +3510,4 @@ + MODULE_AUTHOR("Realtek Corporation"); + MODULE_DESCRIPTION("Realtek 802.11ax wireless core module"); + MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_VERSION("5.14.0_284.11.1_dup9.2"); +Index: src/drivers/net/wireless/realtek/rtw89/pci.c +=================================================================== +--- src.orig/drivers/net/wireless/realtek/rtw89/pci.c 2023-05-30 10:16:49.862826406 +0200 ++++ src/drivers/net/wireless/realtek/rtw89/pci.c 2023-05-30 10:24:55.391774803 +0200 +@@ -3926,3 +3926,4 @@ + MODULE_AUTHOR("Realtek Corporation"); + MODULE_DESCRIPTION("Realtek 802.11ax wireless PCI driver"); + MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_VERSION("5.14.0_284.11.1_dup9.2"); +Index: src/drivers/net/wireless/realtek/rtw89/rtw8852b.c +=================================================================== +--- src.orig/drivers/net/wireless/realtek/rtw89/rtw8852b.c 2023-05-30 10:16:49.878826272 +0200 ++++ src/drivers/net/wireless/realtek/rtw89/rtw8852b.c 2023-05-30 10:24:22.393050168 +0200 +@@ -2526,3 +2526,4 @@ + MODULE_AUTHOR("Realtek Corporation"); + MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852B driver"); + MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_VERSION("5.14.0_284.11.1_dup9.2"); +Index: src/drivers/net/wireless/realtek/rtw89/rtw8852be.c +=================================================================== +--- src.orig/drivers/net/wireless/realtek/rtw89/rtw8852be.c 2023-05-30 10:16:49.662828075 +0200 ++++ src/drivers/net/wireless/realtek/rtw89/rtw8852be.c 2023-05-30 10:24:30.895979213 +0200 +@@ -88,3 +88,4 @@ + MODULE_AUTHOR("Realtek Corporation"); + MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852BE driver"); + MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_VERSION("5.14.0_284.11.1_dup9.2"); diff --git a/SOURCES/9000-enable-Makefile-config.patch b/SOURCES/9000-enable-Makefile-config.patch new file mode 100644 index 0000000..b20ccb3 --- /dev/null +++ b/SOURCES/9000-enable-Makefile-config.patch @@ -0,0 +1,18 @@ +Index: src/drivers/net/wireless/realtek/rtw89/rtw8852a.c +=================================================================== +--- src.orig/drivers/net/wireless/realtek/rtw89/rtw8852a.c 2023-05-30 10:29:13.216623327 +0200 ++++ src/drivers/net/wireless/realtek/rtw89/rtw8852a.c 2023-05-30 10:31:38.065414604 +0200 +@@ -2152,3 +2152,4 @@ + MODULE_AUTHOR("Realtek Corporation"); + MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852A driver"); + MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_VERSION("5.14.0_284.11.1_dup9.2"); +Index: src/drivers/net/wireless/realtek/rtw89/rtw8852ae.c +=================================================================== +--- src.orig/drivers/net/wireless/realtek/rtw89/rtw8852ae.c 2023-05-30 10:29:13.025624920 +0200 ++++ src/drivers/net/wireless/realtek/rtw89/rtw8852ae.c 2023-05-30 10:35:33.298468483 +0200 +@@ -86,3 +86,4 @@ + MODULE_AUTHOR("Realtek Corporation"); + MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852AE driver"); + MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_VERSION("5.14.0_284.11.1_dup9.2"); diff --git a/SOURCES/9001-enable-Makefile-config.patch b/SOURCES/9001-enable-Makefile-config.patch new file mode 100644 index 0000000..7a7916c --- /dev/null +++ b/SOURCES/9001-enable-Makefile-config.patch @@ -0,0 +1,13 @@ +Index: src/drivers/net/wireless/realtek/rtw89/Makefile +=================================================================== +--- src.orig/drivers/net/wireless/realtek/rtw89/Makefile 2023-05-30 10:16:49.146832381 +0200 ++++ src/drivers/net/wireless/realtek/rtw89/Makefile 2023-05-30 10:23:05.287693590 +0200 +@@ -1,5 +1,8 @@ + # SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + ++CONFIG_RTW89_8852B := m ++CONFIG_RTW89_8852BE := m ++ + obj-$(CONFIG_RTW89_CORE) += rtw89_core.o + rtw89_core-y += core.o \ + mac80211.o \ diff --git a/SPECS/kmod-redhat-rtw89.spec b/SPECS/kmod-redhat-rtw89.spec new file mode 100644 index 0000000..ccb7872 --- /dev/null +++ b/SPECS/kmod-redhat-rtw89.spec @@ -0,0 +1,616 @@ +%define kmod_name rtw89 +%define kmod_vendor redhat +%define kmod_rpm_name kmod-redhat-rtw89 +%define kmod_driver_version 5.14.0_284.11.1_dup9.2 +%define kmod_driver_epoch %{nil} +%define kmod_rpm_release 1 +%define kmod_kernel_version 5.14.0-284.11.1.el9_2 +%define kmod_kernel_version_min 5.14.0-284 +%define kmod_kernel_version_dep 5.14.0-284.el9 +%define kmod_kbuild_dir drivers/net/wireless/realtek/rtw89 +%define kmod_dependencies %{nil} +%define kmod_dist_build_deps %{nil} +%define kmod_build_dependencies %{nil} +%define kmod_provides %{nil} +%define kmod_devel_package 1 +%define kmod_devel_src_paths %{nil} +%define kmod_install_path extra/kmod-redhat-rtw89 +%define kmod_files_package 0 +%define kmod_files_noarch 1 +%define kernel_pkg kernel +%define kernel_devel_pkg kernel-devel +%define kernel_modules_pkg kernel-modules + +%{!?dist: %define dist .el9_2} +%{!?make_build: %define make_build make} + +%if "%{kmod_kernel_version_dep}" == "" +%define kmod_kernel_version_dep %{kmod_kernel_version} +%endif + +%if "%{kmod_dist_build_deps}" == "" +%if (0%{?rhel} > 8) || (0%{?centos} > 8) +%define abi_list stablelist +%define kmod_dist_build_deps redhat-rpm-config kernel-abi-stablelists elfutils-libelf-devel kernel-rpm-macros kmod +%else +%if (0%{?rhel} > 7) || (0%{?centos} > 7) +%define abi_list whitelist +%define kmod_dist_build_deps redhat-rpm-config kernel-abi-whitelists elfutils-libelf-devel kernel-rpm-macros kmod +%else +%define abi_list whitelist +%define kmod_dist_build_deps redhat-rpm-config kernel-abi-whitelists +%endif +%endif +%endif + +Source0: %{kmod_name}-%{kmod_vendor}-%{kmod_driver_version}.tar.bz2 +# Source code patches +Patch0: 0001-wifi-rtw89-8852b-add-BB-and-RF-tables-1-of-2.patch +Patch1: 0002-wifi-rtw89-8852b-add-BB-and-RF-tables-2-of-2.patch +Patch2: 0003-wifi-rtw89-8852b-add-tables-for-RFK.patch +Patch3: 0004-wifi-rtw89-phy-make-generic-txpwr-setting-functions.patch +Patch4: 0005-wifi-rtw89-debug-txpwr_table-considers-sign.patch +Patch5: 0006-wifi-rtw89-8852b-add-chip_ops-set_txpwr.patch +Patch6: 0007-wifi-rtw89-8852b-add-chip_ops-to-read-efuse.patch +Patch7: 0008-wifi-rtw89-8852b-add-chip_ops-to-read-phy-cap.patch +Patch8: 0009-wifi-rtw89-8852be-add-8852BE-PCI-entry.patch +Patch9: 0010-wifi-rtw89-8852c-correct-set-of-IQK-backup-registers.patch +Patch10: 0011-wifi-rtw89-8852c-rfk-correct-miscoding-delay-of-DPK.patch +Patch11: 0012-wifi-rtw89-8852c-update-BB-parameters-to-v28.patch +Patch12: 0013-wifi-rtw89-phy-ignore-warning-of-bb-gain-cfg_type-4.patch +Patch13: 0014-wifi-rtw89-8852c-set-pin-MUX-to-enable-BT-firmware-l.patch +Patch14: 0015-wifi-rtw89-add-to-dump-TX-FIFO-0-1-for-8852C.patch +Patch15: 0016-wifi-rtw89-coex-move-chip_ops-btc_bt_aci_imp-to-a-ge.patch +Patch16: 0017-wifi-rtw89-parse-PHY-status-only-when-PPDU-is-to_sel.patch +Patch17: 0018-wifi-rtw89-8852b-set-proper-configuration-before-loa.patch +Patch18: 0019-wifi-rtw89-8852b-add-HFC-quota-arrays.patch +Patch19: 0020-wifi-rtw89-make-generic-functions-to-convert-subband.patch +Patch20: 0021-wifi-rtw89-8852b-add-chip_ops-set_channel.patch +Patch21: 0022-wifi-rtw89-correct-6-GHz-scan-behavior.patch +Patch22: 0023-wifi-rtw89-fix-wrong-bandwidth-settings-after-scan.patch +Patch23: 0024-wifi-rtw89-8852b-add-chip_ops-set_channel_help.patch +Patch24: 0025-wifi-rtw89-8852b-add-power-on-off-functions.patch +Patch25: 0026-wifi-rtw89-8852b-add-basic-baseband-chip_ops.patch +Patch26: 0027-wifi-rtw89-8852b-add-chip_ops-to-get-thermal.patch +Patch27: 0028-wifi-rtw89-8852b-add-chip_ops-related-to-BT-coexiste.patch +Patch28: 0029-wifi-rtw89-8852b-add-chip_ops-to-query-PPDU.patch +Patch29: 0030-wifi-rtw89-8852b-add-chip_ops-to-configure-TX-RX-pat.patch +Patch30: 0031-wifi-rtw89-8852b-add-functions-to-control-BB-to-assi.patch +Patch31: 0032-wifi-rtw89-8852b-add-basic-attributes-of-chip_info.patch +Patch32: 0033-wifi-rtw89-8852b-rfk-add-DACK.patch +Patch33: 0034-wifi-rtw89-8852b-rfk-add-RCK.patch +Patch34: 0035-wifi-rtw89-8852b-rfk-add-RX-DCK.patch +Patch35: 0036-wifi-rtw89-8852b-rfk-add-IQK.patch +Patch36: 0037-wifi-rtw89-8852b-rfk-add-TSSI.patch +Patch37: 0038-wifi-rtw89-8852b-rfk-add-DPK.patch +Patch38: 0039-wifi-rtw89-8852b-add-chip_ops-related-to-RF-calibrat.patch +Patch39: 0040-wifi-rtw89-phy-add-dummy-C2H-handler-to-avoid-warnin.patch +Patch40: 0041-wifi-rtw89-8852b-add-8852be-to-Makefile-and-Kconfig.patch +Patch41: 0042-wifi-rtw89-fw-adapt-to-new-firmware-format-of-dynami.patch +Patch42: 0043-wifi-rtw89-declare-support-bands-with-const.patch +Patch43: 0044-wifi-rtw89-8852c-make-table-of-RU-mask-constant.patch +Patch44: 0045-wifi-rtw89-add-BW-info-for-both-TX-and-RX-in-phy_inf.patch +Patch45: 0046-wifi-rtw89-check-if-sta-s-mac_id-is-valid-under-AP-T.patch +Patch46: 0047-wifi-rtw89-collect-and-send-RF-parameters-to-firmwar.patch +Patch47: 0048-wifi-rtw89-move-enable_cpu-disable_cpu-into-fw_downl.patch +Patch48: 0049-wifi-rtw89-add-function-to-adjust-and-restore-PLE-qu.patch +Patch49: 0050-wifi-rtw89-add-drop-tx-packet-function.patch +Patch50: 0051-wifi-rtw89-add-related-H2C-for-WoWLAN-mode.patch +Patch51: 0052-wifi-rtw89-add-WoWLAN-function-support.patch +Patch52: 0053-wifi-rtw89-add-WoWLAN-pattern-match-support.patch +Patch53: 0054-wifi-rtw89-8852b-Fix-spelling-mistake-KIP_RESOTRE-KI.patch +Patch54: 0055-wifi-rtw89-dump-dispatch-status-via-debug-port.patch +Patch55: 0056-wifi-rtw89-update-D-MAC-and-C-MAC-dump-to-diagnose-S.patch +Patch56: 0057-wifi-rtw89-8852b-change-debug-mask-of-message-of-no-.patch +Patch57: 0058-wifi-rtw89-Fix-some-error-handling-path-in-rtw89_wow.patch +Patch58: 0059-wifi-rtw89-8852b-correct-TX-power-controlled-by-BT-c.patch +Patch59: 0060-wifi-rtw89-read-CFO-from-FD-or-preamble-CFO-field-of.patch +Patch60: 0061-wifi-rtw89-switch-BANDEDGE-and-TX_SHAPE-based-on-OFD.patch +Patch61: 0062-wifi-rtw89-avoid-inaccessible-IO-operations-during-d.patch +Patch62: 0063-wifi-rtw89-enable-mac80211-virtual-monitor-interface.patch +Patch63: 0064-wifi-rtw89-add-HE-radiotap-for-monitor-mode.patch +Patch64: 0065-wifi-rtw89-8852b-turn-off-PoP-function-in-monitor-mo.patch +Patch65: 0066-wifi-rtw89-rfk-rename-rtw89_mcc_info-to-rtw89_rfk_mc.patch +Patch66: 0067-wifi-rtw89-check-if-atomic-before-queuing-c2h.patch +Patch67: 0068-wifi-rtw89-introduce-helpers-to-wait-complete-on-con.patch +Patch68: 0069-wifi-rtw89-mac-process-MCC-related-C2H.patch +Patch69: 0070-wifi-rtw89-fw-implement-MCC-related-H2C.patch +Patch70: 0071-wifi-rtw89-link-rtw89_vif-and-chanctx-stuffs.patch +Patch71: 0072-wifi-rtw89-don-t-request-partial-firmware-if-SECURIT.patch +Patch72: 0073-wifi-rtw89-request-full-firmware-only-once-if-it-s-e.patch +Patch73: 0074-wifi-rtw89-add-mac-TSF-sync-function.patch +Patch74: 0075-wifi-rtw89-stop-mac-port-function-when-stop_ap.patch +Patch75: 0076-wifi-rtw89-fix-unsuccessful-interface_add-flow.patch +Patch76: 0077-wifi-rtw89-add-join-info-upon-create-interface.patch +Patch77: 0078-wifi-rtw89-consider-ER-SU-as-a-TX-capability.patch +Patch78: 0079-wifi-rtw89-fw-adapt-to-new-firmware-format-of-securi.patch +Patch79: 0080-wifi-rtw89-8852c-rfk-correct-DACK-setting.patch +Patch80: 0081-wifi-rtw89-8852c-rfk-correct-DPK-settings.patch +Patch81: 0082-wifi-rtw89-8852c-rfk-recover-RX-DCK-failure.patch +Patch82: 0083-wifi-rtw89-coex-add-BTC-format-version-derived-from-.patch +Patch83: 0084-wifi-rtw89-coex-use-new-introduction-BTC-version-for.patch +Patch84: 0085-wifi-rtw89-coex-Enable-Bluetooth-report-when-show-de.patch +Patch85: 0086-wifi-rtw89-coex-Update-BTC-firmware-report-bitmap-de.patch +Patch86: 0087-wifi-rtw89-coex-Add-v2-BT-AFH-report-and-related-var.patch +Patch87: 0088-wifi-rtw89-coex-refactor-_chk_btc_report-to-extend-m.patch +Patch88: 0089-wifi-rtw89-coex-Change-TDMA-related-logic-to-version.patch +Patch89: 0090-wifi-rtw89-8852b-update-BSS-color-mapping-register.patch +Patch90: 0091-wifi-rtw89-refine-6-GHz-scanning-dwell-time.patch +Patch91: 0092-wifi-rtw89-8852c-rfk-refine-AGC-tuning-flow-of-DPK-f.patch +Patch92: 0093-wifi-rtw89-Fix-a-typo-in-debug-message.patch +Patch93: 0094-wifi-rtw89-coex-Remove-le32-to-CPU-translator-at-fir.patch +Patch94: 0095-wifi-rtw89-coex-Rename-BTC-firmware-cycle-report-by-.patch +Patch95: 0096-wifi-rtw89-coex-Add-v4-version-firmware-cycle-report.patch +Patch96: 0097-wifi-rtw89-coex-Change-firmware-control-report-to-ve.patch +Patch97: 0098-wifi-rtw89-coex-Add-v5-firmware-control-report.patch +Patch98: 0099-wifi-rtw89-coex-only-read-Bluetooth-counter-of-repor.patch +Patch99: 0100-wifi-rtw89-coex-Update-WiFi-role-info-H2C-report.patch +Patch100: 0101-wifi-rtw89-coex-Add-version-code-for-Wi-Fi-firmware-.patch +Patch101: 0102-wifi-rtw89-coex-Change-Wi-Fi-Null-data-report-to-ver.patch +Patch102: 0103-wifi-rtw89-coex-Change-firmware-steps-report-to-vers.patch +Patch103: 0104-wifi-rtw89-coex-refactor-debug-log-of-slot-list.patch +Patch104: 0105-wifi-rtw89-coex-Packet-traffic-arbitration-hardware-.patch +Patch105: 0106-wifi-rtw89-coex-Change-RTL8852B-use-v1-TDMA-policy.patch +Patch106: 0107-wifi-rtw89-coex-Change-Wi-Fi-role-info-related-logic.patch +Patch107: 0108-wifi-rtw89-fix-null-vif-pointer-when-get-management-.patch +Patch108: 0109-wifi-rtw89-set-the-correct-mac_id-for-management-fra.patch +Patch109: 0110-wifi-rtw89-correct-register-definitions-of-digital-C.patch +Patch110: 0111-wifi-rtw89-8852c-rfk-correct-ADC-clock-settings.patch +Patch111: 0112-wifi-rtw89-fix-assignation-of-TX-BD-RAM-table.patch +Patch112: 0113-wifi-rtw89-8852b-fill-the-missing-configuration-abou.patch +Patch113: 0114-wifi-rtw89-coex-Update-Wi-Fi-external-control-TDMA-p.patch +Patch114: 0115-wifi-rtw89-coex-Clear-Bluetooth-HW-PTA-counter-when-.patch +Patch115: 0116-wifi-rtw89-coex-Force-to-update-TDMA-parameter-when-.patch +Patch116: 0117-wifi-rtw89-coex-Refine-coexistence-log.patch +Patch117: 0118-wifi-rtw89-coex-Set-Bluetooth-background-scan-PTA-re.patch +Patch118: 0119-wifi-rtw89-coex-Correct-A2DP-exist-variable-source.patch +Patch119: 0120-wifi-rtw89-coex-Fix-test-fail-when-coexist-with-rasp.patch +Patch120: 0121-wifi-rtw89-coex-Update-Wi-Fi-Bluetooth-coexistence-v.patch +Patch121: 0122-wifi-rtw89-correct-unit-for-port-offset-and-refine-m.patch +Patch122: 0123-wifi-rtw89-split-out-generic-part-of-rtw89_mac_port_.patch +Patch123: 0124-wifi-rtw89-mac-add-function-to-get-TSF.patch +Patch124: 0125-wifi-rtw89-debug-avoid-invalid-access-on-RTW89_DBG_S.patch +Patch125: 0126-wifi-rtw89-deal-with-RXI300-error.patch +Patch126: 0127-wifi-rtw89-fix-parsing-offset-for-MCC-C2H.patch +Patch127: 0128-wifi-rtw89-refine-MCC-C2H-debug-logs.patch +Patch128: 0129-wifi-rtw89-disallow-enter-PS-mode-after-create-TDLS-.patch +Patch129: 0130-wifi-rtw89-fix-potential-wrong-mapping-for-pkt-offlo.patch +Patch130: 0131-wifi-rtw89-refine-packet-offload-flow.patch +Patch131: 0132-wifi-rtw89-add-use-of-pkt_list-offload-to-debug-entr.patch +Patch132: 0133-wifi-rtw89-8852b-reset-IDMEM-mode-to-default-value.patch +Patch133: 0134-wifi-rtw89-8852b-don-t-support-LPS-PG-mode-after-fir.patch +Patch134: 0135-wifi-rtw89-8852b-try-to-use-NORMAL_CE-type-firmware-.patch +Patch135: 0136-wifi-rtw89-8852be-enable-CLKREQ-of-PCI-capability.patch +Patch136: 0137-wifi-rtw89-use-passed-channel-in-set_tx_shape_dfir.patch +Patch137: 0138-wifi-rtw89-8852b-correct-register-mask-name-of-TX-po.patch +Patch138: 0139-wifi-rtw89-phy-set-TX-power-according-to-RF-path-num.patch +Patch139: 0140-wifi-rtw89-use-readable-return-0-in-rtw89_mac_cfg_pp.patch +Patch140: 0141-wifi-rtw89-move-H2C-of-del_pkt_offload-before-pollin.patch +Patch141: 0142-wifi-rtw89-fix-AP-mode-authentication-transmission-f.patch +Patch142: 9000-add-driver-version.patch +Patch143: 9001-enable-Makefile-config.patch +Patch144: 9000-enable-Makefile-config.patch + +%define findpat %( echo "%""P" ) +%define __find_requires /usr/lib/rpm/redhat/find-requires.ksyms +%define __find_provides /usr/lib/rpm/redhat/find-provides.ksyms %{kmod_name} %{?epoch:%{epoch}:}%{version}-%{release} +%define sbindir %( if [ -d "/sbin" -a \! -h "/sbin" ]; then echo "/sbin"; else echo %{_sbindir}; fi ) +%define dup_state_dir %{_localstatedir}/lib/rpm-state/kmod-dups +%define kver_state_dir %{dup_state_dir}/kver +%define kver_state_file %{kver_state_dir}/%{kmod_kernel_version}.%(arch) +%define dup_module_list %{dup_state_dir}/rpm-kmod-%{kmod_name}-modules + +Name: kmod-redhat-rtw89 +Version: %{kmod_driver_version} +Release: %{kmod_rpm_release}%{?dist} +%if "%{kmod_driver_epoch}" != "" +Epoch: %{kmod_driver_epoch} +%endif +Summary: rtw89 kernel module for Driver Update Program +Group: System/Kernel +License: GPLv2 +URL: https://www.kernel.org/ +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) +BuildRequires: %kernel_devel_pkg = %kmod_kernel_version +%if "%{kmod_dist_build_deps}" != "" +BuildRequires: %{kmod_dist_build_deps} +%endif +ExclusiveArch: x86_64 +%global kernel_source() /usr/src/kernels/%{kmod_kernel_version}.$(arch) + +%global _use_internal_dependency_generator 0 +%if "%{?kmod_kernel_version_min}" != "" +Provides: %kernel_modules_pkg >= %{kmod_kernel_version_min}.%{_target_cpu} +%else +Provides: %kernel_modules_pkg = %{kmod_kernel_version_dep}.%{_target_cpu} +%endif +Provides: kmod-%{kmod_name} = %{?epoch:%{epoch}:}%{version}-%{release} +Requires(post): %{sbindir}/weak-modules +Requires(postun): %{sbindir}/weak-modules +Requires: kernel >= 5.14.0-284 +%if 0 +Requires: firmware(%{kmod_name}) = ENTER_FIRMWARE_VERSION +%endif +%if "%{kmod_build_dependencies}" != "" +BuildRequires: %{kmod_build_dependencies} +%endif +%if "%{kmod_dependencies}" != "" +Requires: %{kmod_dependencies} +%endif +%if "%{kmod_provides}" != "" +Provides: %{kmod_provides} +%endif +# if there are multiple kmods for the same driver from different vendors, +# they should conflict with each other. +Conflicts: kmod-%{kmod_name} + +%description +rtw89 kernel module for Driver Update Program + +%if 0 + +%package -n kmod-redhat-rtw89-firmware +Version: ENTER_FIRMWARE_VERSION +Summary: rtw89 firmware for Driver Update Program +Provides: firmware(%{kmod_name}) = ENTER_FIRMWARE_VERSION +%if "%{kmod_kernel_version_min}" != "" +Provides: %kernel_modules_pkg >= %{kmod_kernel_version_min}.%{_target_cpu} +%else +Provides: %kernel_modules_pkg = %{kmod_kernel_version_dep}.%{_target_cpu} +%endif +%description -n kmod-redhat-rtw89-firmware +rtw89 firmware for Driver Update Program + + +%files -n kmod-redhat-rtw89-firmware +%defattr(644,root,root,755) +%{FIRMWARE_FILES} + +%endif + +# Development package +%if 0%{kmod_devel_package} +%package -n kmod-redhat-rtw89-devel +Version: %{kmod_driver_version} +Summary: rtw89 development files for Driver Update Program + +%description -n kmod-redhat-rtw89-devel +rtw89 development files for Driver Update Program + + +%files -n kmod-redhat-rtw89-devel +%defattr(644,root,root,755) +/lib/modules/%{kmod_rpm_name}-%{kmod_driver_version}/ +%endif + +# Extra files package +%if 0%{kmod_files_package} +%package -n kmod-redhat-rtw89-files +Version: %{kmod_driver_version} +Summary: rtw89 additional files for Driver Update Program +%if 0%{kmod_files_noarch} +BuildArch: noarch +%endif +%if "%{?kmod_kernel_version_min}" != "" +Provides: %kernel_modules_pkg >= %{kmod_kernel_version_min}.%{_target_cpu} +%else +Provides: %kernel_modules_pkg = %{kmod_kernel_version_dep}.%{_target_cpu} +%endif + +%description -n kmod-redhat-rtw89-files +rtw89 additional files for Driver Update Program + + +%files -n kmod-redhat-rtw89-files +%defattr(644,root,root,755) + + +%endif + +%post +modules=( $(find /lib/modules/%{kmod_kernel_version}.%(arch)/%{kmod_install_path} | grep '\.ko$') ) +printf '%s\n' "${modules[@]}" | %{sbindir}/weak-modules --add-modules --no-initramfs + +mkdir -p "%{kver_state_dir}" +touch "%{kver_state_file}" + +exit 0 + +%posttrans +# We have to re-implement part of weak-modules here because it doesn't allow +# calling initramfs regeneration separately +if [ -f "%{kver_state_file}" ]; then + kver_base="%{kmod_kernel_version_dep}" + kvers=$(ls -d "/lib/modules/${kver_base%%.*}"*) + + for k_dir in $kvers; do + k="${k_dir#/lib/modules/}" + + tmp_initramfs="/boot/initramfs-$k.tmp" + dst_initramfs="/boot/initramfs-$k.img" + + # The same check as in weak-modules: we assume that the kernel present + # if the symvers file exists. + if [ -e "/boot/symvers-$k.gz" ] || [ -e "$k_dir/symvers.gz" ]; then + /usr/bin/dracut -f "$tmp_initramfs" "$k" || exit 1 + cmp -s "$tmp_initramfs" "$dst_initramfs" + if [ "$?" = 1 ]; then + mv "$tmp_initramfs" "$dst_initramfs" + else + rm -f "$tmp_initramfs" + fi + fi + done + + rm -f "%{kver_state_file}" + rmdir "%{kver_state_dir}" 2> /dev/null +fi + +rmdir "%{dup_state_dir}" 2> /dev/null + +exit 0 + +%preun +if rpm -q --filetriggers kmod 2> /dev/null| grep -q "Trigger for weak-modules call on kmod removal"; then + mkdir -p "%{kver_state_dir}" + touch "%{kver_state_file}" +fi + +mkdir -p "%{dup_state_dir}" +rpm -ql kmod-redhat-rtw89-%{kmod_driver_version}-%{kmod_rpm_release}%{?dist}.$(arch) | \ + grep '\.ko$' > "%{dup_module_list}" + +%postun +if rpm -q --filetriggers kmod 2> /dev/null| grep -q "Trigger for weak-modules call on kmod removal"; then + initramfs_opt="--no-initramfs" +else + initramfs_opt="" +fi + +modules=( $(cat "%{dup_module_list}") ) +rm -f "%{dup_module_list}" +printf '%s\n' "${modules[@]}" | %{sbindir}/weak-modules --remove-modules $initramfs_opt + +rmdir "%{dup_state_dir}" 2> /dev/null + +exit 0 + +%files +%defattr(644,root,root,755) +/lib/modules/%{kmod_kernel_version}.%(arch) +/etc/depmod.d/%{kmod_name}.conf +%doc /usr/share/doc/%{kmod_rpm_name}/greylist.txt +%if !0%{kmod_files_package} + + +%endif + +%prep +%setup -n %{kmod_name}-%{kmod_vendor}-%{kmod_driver_version} + +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 +%patch76 -p1 +%patch77 -p1 +%patch78 -p1 +%patch79 -p1 +%patch80 -p1 +%patch81 -p1 +%patch82 -p1 +%patch83 -p1 +%patch84 -p1 +%patch85 -p1 +%patch86 -p1 +%patch87 -p1 +%patch88 -p1 +%patch89 -p1 +%patch90 -p1 +%patch91 -p1 +%patch92 -p1 +%patch93 -p1 +%patch94 -p1 +%patch95 -p1 +%patch96 -p1 +%patch97 -p1 +%patch98 -p1 +%patch99 -p1 +%patch100 -p1 +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch104 -p1 +%patch105 -p1 +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 +%patch109 -p1 +%patch110 -p1 +%patch111 -p1 +%patch112 -p1 +%patch113 -p1 +%patch114 -p1 +%patch115 -p1 +%patch116 -p1 +%patch117 -p1 +%patch118 -p1 +%patch119 -p1 +%patch120 -p1 +%patch121 -p1 +%patch122 -p1 +%patch123 -p1 +%patch124 -p1 +%patch125 -p1 +%patch126 -p1 +%patch127 -p1 +%patch128 -p1 +%patch129 -p1 +%patch130 -p1 +%patch131 -p1 +%patch132 -p1 +%patch133 -p1 +%patch134 -p1 +%patch135 -p1 +%patch136 -p1 +%patch137 -p1 +%patch138 -p1 +%patch139 -p1 +%patch140 -p1 +%patch141 -p1 +%patch142 -p1 +%patch143 -p1 +%patch144 -p1 +set -- * +mkdir source +mv "$@" source/ +mkdir obj + +%build +rm -rf obj +cp -r source obj + +PWD_PATH="$PWD" +%if "%{workaround_no_pwd_rel_path}" != "1" +PWD_PATH=$(realpath --relative-to="%{kernel_source}" . 2>/dev/null || echo "$PWD") +%endif +%{make_build} -C %{kernel_source} V=1 M="$PWD_PATH/obj/%{kmod_kbuild_dir}" \ + NOSTDINC_FLAGS="-I$PWD_PATH/obj/include -I$PWD_PATH/obj/include/uapi %{nil}" \ + EXTRA_CFLAGS="%{nil}" \ + %{nil} +# mark modules executable so that strip-to-file can strip them +find obj/%{kmod_kbuild_dir} -name "*.ko" -type f -exec chmod u+x '{}' + + +kabilist="/lib/modules/kabi-current/kabi_%{abi_list}_%{_target_cpu}" +for modules in $( find obj/%{kmod_kbuild_dir} -name "*.ko" -type f -printf "%{findpat}\n" | sed 's|\.ko$||' | sort -u ) ; do + # update depmod.conf + module_weak_path=$(echo "$modules" | sed 's/[\/]*[^\/]*$//') + if [ -z "$module_weak_path" ]; then + module_weak_path=%{name} + else + module_weak_path=%{name}/$module_weak_path + fi + echo "override $(echo $modules | sed 's/.*\///')" \ + "$(echo "%{kmod_kernel_version_dep}" | + sed 's/\.[^\.]*$//; + s/\([.+?^$\/\\|()\[]\|\]\)/\\\0/g').*" \ + "weak-updates/$module_weak_path" >> source/depmod.conf + + # update greylist + nm -u obj/%{kmod_kbuild_dir}/$modules.ko | sed 's/.*U //' | sed 's/^\.//' | sort -u | while read -r symbol; do + grep -q "^\s*$symbol\$" $kabilist || echo "$symbol" >> source/greylist + done +done +sort -u source/greylist | uniq > source/greylist.txt + +%install +export INSTALL_MOD_PATH=$RPM_BUILD_ROOT +export INSTALL_MOD_DIR=%{kmod_install_path} +PWD_PATH="$PWD" +%if "%{workaround_no_pwd_rel_path}" != "1" +PWD_PATH=$(realpath --relative-to="%{kernel_source}" . 2>/dev/null || echo "$PWD") +%endif +make -C %{kernel_source} modules_install \ + M=$PWD_PATH/obj/%{kmod_kbuild_dir} +# Cleanup unnecessary kernel-generated module dependency files. +find $INSTALL_MOD_PATH/lib/modules -iname 'modules.*' -exec rm {} \; + +install -m 644 -D source/depmod.conf $RPM_BUILD_ROOT/etc/depmod.d/%{kmod_name}.conf +install -m 644 -D source/greylist.txt $RPM_BUILD_ROOT/usr/share/doc/%{kmod_rpm_name}/greylist.txt +%if 0 +%{FIRMWARE_FILES_INSTALL} +%endif +%if 0%{kmod_devel_package} +install -m 644 -D $PWD/obj/%{kmod_kbuild_dir}/Module.symvers $RPM_BUILD_ROOT/lib/modules/%{kmod_rpm_name}-%{kmod_driver_version}/build/Module.symvers + +if [ -n "%{kmod_devel_src_paths}" ]; then + for i in %{kmod_devel_src_paths}; do + mkdir -p "$RPM_BUILD_ROOT/lib/modules/%{kmod_rpm_name}-%{kmod_driver_version}/build/$(dirname "$i")" + cp -rv "$PWD/source/$i" \ + "$RPM_BUILD_ROOT/lib/modules/%{kmod_rpm_name}-%{kmod_driver_version}/build/$i" + done +fi +%endif + + + +%clean +rm -rf $RPM_BUILD_ROOT + +%changelog +* Tue Jun 27 2023 Eugene Syromiatnikov 5.14.0_284.11.1_dup9.2-1 +- c8eb14f582ef9c529860817fbe91ba1a6a270315 +- rtw89 kernel module for Driver Update Program +- Resolves: #bz2214527