1c888183bSBitterblue Smith // SPDX-License-Identifier: GPL-2.0-only
2c888183bSBitterblue Smith /*
3c888183bSBitterblue Smith * RTL8XXXU mac80211 USB driver - 8188f specific subdriver
4c888183bSBitterblue Smith *
5c888183bSBitterblue Smith * Copyright (c) 2022 Bitterblue Smith <rtl8821cerfe2@gmail.com>
6c888183bSBitterblue Smith *
7c888183bSBitterblue Smith * Portions copied from existing rtl8xxxu code:
8c888183bSBitterblue Smith * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
9c888183bSBitterblue Smith *
10c888183bSBitterblue Smith * Portions, notably calibration code:
11c888183bSBitterblue Smith * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
12c888183bSBitterblue Smith */
13c888183bSBitterblue Smith
14c888183bSBitterblue Smith #include <linux/init.h>
15c888183bSBitterblue Smith #include <linux/kernel.h>
16c888183bSBitterblue Smith #include <linux/sched.h>
17c888183bSBitterblue Smith #include <linux/errno.h>
18c888183bSBitterblue Smith #include <linux/slab.h>
19c888183bSBitterblue Smith #include <linux/module.h>
20c888183bSBitterblue Smith #include <linux/spinlock.h>
21c888183bSBitterblue Smith #include <linux/list.h>
22c888183bSBitterblue Smith #include <linux/usb.h>
23c888183bSBitterblue Smith #include <linux/netdevice.h>
24c888183bSBitterblue Smith #include <linux/etherdevice.h>
25c888183bSBitterblue Smith #include <linux/ethtool.h>
26c888183bSBitterblue Smith #include <linux/wireless.h>
27c888183bSBitterblue Smith #include <linux/firmware.h>
28c888183bSBitterblue Smith #include <linux/moduleparam.h>
29c888183bSBitterblue Smith #include <net/mac80211.h>
30c888183bSBitterblue Smith #include "rtl8xxxu.h"
31c888183bSBitterblue Smith #include "rtl8xxxu_regs.h"
32c888183bSBitterblue Smith
3379cac25eSBitterblue Smith static const struct rtl8xxxu_reg8val rtl8188f_mac_init_table[] = {
34c888183bSBitterblue Smith {0x024, 0xDF}, {0x025, 0x07}, {0x02B, 0x1C}, {0x283, 0x20},
35c888183bSBitterblue Smith {0x421, 0x0F}, {0x428, 0x0A}, {0x429, 0x10}, {0x430, 0x00},
36c888183bSBitterblue Smith {0x431, 0x00}, {0x432, 0x00}, {0x433, 0x01}, {0x434, 0x04},
37c888183bSBitterblue Smith {0x435, 0x05}, {0x436, 0x07}, {0x437, 0x08}, {0x43C, 0x04},
38c888183bSBitterblue Smith {0x43D, 0x05}, {0x43E, 0x07}, {0x43F, 0x08}, {0x440, 0x5D},
39c888183bSBitterblue Smith {0x441, 0x01}, {0x442, 0x00}, {0x444, 0x10}, {0x445, 0x00},
40c888183bSBitterblue Smith {0x446, 0x00}, {0x447, 0x00}, {0x448, 0x00}, {0x449, 0xF0},
41c888183bSBitterblue Smith {0x44A, 0x0F}, {0x44B, 0x3E}, {0x44C, 0x10}, {0x44D, 0x00},
42c888183bSBitterblue Smith {0x44E, 0x00}, {0x44F, 0x00}, {0x450, 0x00}, {0x451, 0xF0},
43c888183bSBitterblue Smith {0x452, 0x0F}, {0x453, 0x00}, {0x456, 0x5E}, {0x460, 0x44},
44c888183bSBitterblue Smith {0x461, 0x44}, {0x4BC, 0xC0}, {0x4C8, 0xFF}, {0x4C9, 0x08},
45c888183bSBitterblue Smith {0x4CC, 0xFF}, {0x4CD, 0xFF}, {0x4CE, 0x01}, {0x500, 0x26},
46c888183bSBitterblue Smith {0x501, 0xA2}, {0x502, 0x2F}, {0x503, 0x00}, {0x504, 0x28},
47c888183bSBitterblue Smith {0x505, 0xA3}, {0x506, 0x5E}, {0x507, 0x00}, {0x508, 0x2B},
48c888183bSBitterblue Smith {0x509, 0xA4}, {0x50A, 0x5E}, {0x50B, 0x00}, {0x50C, 0x4F},
49c888183bSBitterblue Smith {0x50D, 0xA4}, {0x50E, 0x00}, {0x50F, 0x00}, {0x512, 0x1C},
50c888183bSBitterblue Smith {0x514, 0x0A}, {0x516, 0x0A}, {0x525, 0x4F}, {0x550, 0x10},
51c888183bSBitterblue Smith {0x551, 0x10}, {0x559, 0x02}, {0x55C, 0x28}, {0x55D, 0xFF},
52c888183bSBitterblue Smith {0x605, 0x30}, {0x608, 0x0E}, {0x609, 0x2A}, {0x620, 0xFF},
53c888183bSBitterblue Smith {0x621, 0xFF}, {0x622, 0xFF}, {0x623, 0xFF}, {0x624, 0xFF},
54c888183bSBitterblue Smith {0x625, 0xFF}, {0x626, 0xFF}, {0x627, 0xFF}, {0x638, 0x28},
55c888183bSBitterblue Smith {0x63C, 0x0A}, {0x63D, 0x0A}, {0x63E, 0x0E}, {0x63F, 0x0E},
56c888183bSBitterblue Smith {0x640, 0x40}, {0x642, 0x40}, {0x643, 0x00}, {0x652, 0xC8},
57c888183bSBitterblue Smith {0x66E, 0x05}, {0x700, 0x21}, {0x701, 0x43}, {0x702, 0x65},
58c888183bSBitterblue Smith {0x703, 0x87}, {0x708, 0x21}, {0x709, 0x43}, {0x70A, 0x65},
59c888183bSBitterblue Smith {0x70B, 0x87},
60c888183bSBitterblue Smith {0xffff, 0xff},
61c888183bSBitterblue Smith };
62c888183bSBitterblue Smith
6379cac25eSBitterblue Smith static const struct rtl8xxxu_reg32val rtl8188fu_phy_init_table[] = {
64c888183bSBitterblue Smith {0x800, 0x80045700}, {0x804, 0x00000001},
65c888183bSBitterblue Smith {0x808, 0x0000FC00}, {0x80C, 0x0000000A},
66c888183bSBitterblue Smith {0x810, 0x10001331}, {0x814, 0x020C3D10},
67c888183bSBitterblue Smith {0x818, 0x00200385}, {0x81C, 0x00000000},
68c888183bSBitterblue Smith {0x820, 0x01000100}, {0x824, 0x00390204},
69c888183bSBitterblue Smith {0x828, 0x00000000}, {0x82C, 0x00000000},
70c888183bSBitterblue Smith {0x830, 0x00000000}, {0x834, 0x00000000},
71c888183bSBitterblue Smith {0x838, 0x00000000}, {0x83C, 0x00000000},
72c888183bSBitterblue Smith {0x840, 0x00010000}, {0x844, 0x00000000},
73c888183bSBitterblue Smith {0x848, 0x00000000}, {0x84C, 0x00000000},
74c888183bSBitterblue Smith {0x850, 0x00030000}, {0x854, 0x00000000},
75c888183bSBitterblue Smith {0x858, 0x569A569A}, {0x85C, 0x569A569A},
76c888183bSBitterblue Smith {0x860, 0x00000130}, {0x864, 0x00000000},
77c888183bSBitterblue Smith {0x868, 0x00000000}, {0x86C, 0x27272700},
78c888183bSBitterblue Smith {0x870, 0x00000000}, {0x874, 0x25004000},
79c888183bSBitterblue Smith {0x878, 0x00000808}, {0x87C, 0x004F0201},
80c888183bSBitterblue Smith {0x880, 0xB0000B1E}, {0x884, 0x00000007},
81c888183bSBitterblue Smith {0x888, 0x00000000}, {0x88C, 0xCCC000C0},
82c888183bSBitterblue Smith {0x890, 0x00000800}, {0x894, 0xFFFFFFFE},
83c888183bSBitterblue Smith {0x898, 0x40302010}, {0x89C, 0x00706050},
84c888183bSBitterblue Smith {0x900, 0x00000000}, {0x904, 0x00000023},
85c888183bSBitterblue Smith {0x908, 0x00000000}, {0x90C, 0x81121111},
86c888183bSBitterblue Smith {0x910, 0x00000002}, {0x914, 0x00000201},
87c888183bSBitterblue Smith {0x948, 0x99000000}, {0x94C, 0x00000010},
88c888183bSBitterblue Smith {0x950, 0x20003000}, {0x954, 0x4A880000},
89c888183bSBitterblue Smith {0x958, 0x4BC5D87A}, {0x95C, 0x04EB9B79},
90c888183bSBitterblue Smith {0x96C, 0x00000003}, {0xA00, 0x00D047C8},
91c888183bSBitterblue Smith {0xA04, 0x80FF800C}, {0xA08, 0x8C898300},
92c888183bSBitterblue Smith {0xA0C, 0x2E7F120F}, {0xA10, 0x9500BB78},
93c888183bSBitterblue Smith {0xA14, 0x1114D028}, {0xA18, 0x00881117},
94c888183bSBitterblue Smith {0xA1C, 0x89140F00}, {0xA20, 0xD1D80000},
95c888183bSBitterblue Smith {0xA24, 0x5A7DA0BD}, {0xA28, 0x0000223B},
96c888183bSBitterblue Smith {0xA2C, 0x00D30000}, {0xA70, 0x101FBF00},
97c888183bSBitterblue Smith {0xA74, 0x00000007}, {0xA78, 0x00000900},
98c888183bSBitterblue Smith {0xA7C, 0x225B0606}, {0xA80, 0x218075B1},
99c888183bSBitterblue Smith {0xA84, 0x00120000}, {0xA88, 0x040C0000},
100c888183bSBitterblue Smith {0xA8C, 0x12345678}, {0xA90, 0xABCDEF00},
101c888183bSBitterblue Smith {0xA94, 0x001B1B89}, {0xA98, 0x05100000},
102c888183bSBitterblue Smith {0xA9C, 0x3F000000}, {0xAA0, 0x00000000},
103c888183bSBitterblue Smith {0xB2C, 0x00000000}, {0xC00, 0x48071D40},
104c888183bSBitterblue Smith {0xC04, 0x03A05611}, {0xC08, 0x000000E4},
105c888183bSBitterblue Smith {0xC0C, 0x6C6C6C6C}, {0xC10, 0x18800000},
106c888183bSBitterblue Smith {0xC14, 0x40000100}, {0xC18, 0x08800000},
107c888183bSBitterblue Smith {0xC1C, 0x40000100}, {0xC20, 0x00000000},
108c888183bSBitterblue Smith {0xC24, 0x00000000}, {0xC28, 0x00000000},
109c888183bSBitterblue Smith {0xC2C, 0x00000000}, {0xC30, 0x69E9CC4A},
110c888183bSBitterblue Smith {0xC34, 0x31000040}, {0xC38, 0x21688080},
111c888183bSBitterblue Smith {0xC3C, 0x00001714}, {0xC40, 0x1F78403F},
112c888183bSBitterblue Smith {0xC44, 0x00010036}, {0xC48, 0xEC020107},
113c888183bSBitterblue Smith {0xC4C, 0x007F037F}, {0xC50, 0x69553420},
114c888183bSBitterblue Smith {0xC54, 0x43BC0094}, {0xC58, 0x00013169},
115c888183bSBitterblue Smith {0xC5C, 0x00250492}, {0xC60, 0x00000000},
116c888183bSBitterblue Smith {0xC64, 0x7112848B}, {0xC68, 0x47C07BFF},
117c888183bSBitterblue Smith {0xC6C, 0x00000036}, {0xC70, 0x2C7F000D},
118c888183bSBitterblue Smith {0xC74, 0x020600DB}, {0xC78, 0x0000001F},
119c888183bSBitterblue Smith {0xC7C, 0x00B91612}, {0xC80, 0x390000E4},
120c888183bSBitterblue Smith {0xC84, 0x11F60000},
121c888183bSBitterblue Smith {0xC88, 0x40000100}, {0xC8C, 0x20200000},
122c888183bSBitterblue Smith {0xC90, 0x00091521}, {0xC94, 0x00000000},
123c888183bSBitterblue Smith {0xC98, 0x00121820}, {0xC9C, 0x00007F7F},
124c888183bSBitterblue Smith {0xCA0, 0x00000000}, {0xCA4, 0x000300A0},
125c888183bSBitterblue Smith {0xCA8, 0x00000000}, {0xCAC, 0x00000000},
126c888183bSBitterblue Smith {0xCB0, 0x00000000}, {0xCB4, 0x00000000},
127c888183bSBitterblue Smith {0xCB8, 0x00000000}, {0xCBC, 0x28000000},
128c888183bSBitterblue Smith {0xCC0, 0x00000000}, {0xCC4, 0x00000000},
129c888183bSBitterblue Smith {0xCC8, 0x00000000}, {0xCCC, 0x00000000},
130c888183bSBitterblue Smith {0xCD0, 0x00000000}, {0xCD4, 0x00000000},
131c888183bSBitterblue Smith {0xCD8, 0x64B22427}, {0xCDC, 0x00766932},
132c888183bSBitterblue Smith {0xCE0, 0x00222222}, {0xCE4, 0x10000000},
133c888183bSBitterblue Smith {0xCE8, 0x37644302}, {0xCEC, 0x2F97D40C},
134c888183bSBitterblue Smith {0xD00, 0x04030740}, {0xD04, 0x40020401},
135c888183bSBitterblue Smith {0xD08, 0x0000907F}, {0xD0C, 0x20010201},
136c888183bSBitterblue Smith {0xD10, 0xA0633333}, {0xD14, 0x3333BC53},
137c888183bSBitterblue Smith {0xD18, 0x7A8F5B6F}, {0xD2C, 0xCB979975},
138c888183bSBitterblue Smith {0xD30, 0x00000000}, {0xD34, 0x80608000},
139c888183bSBitterblue Smith {0xD38, 0x98000000}, {0xD3C, 0x40127353},
140c888183bSBitterblue Smith {0xD40, 0x00000000}, {0xD44, 0x00000000},
141c888183bSBitterblue Smith {0xD48, 0x00000000}, {0xD4C, 0x00000000},
142c888183bSBitterblue Smith {0xD50, 0x6437140A}, {0xD54, 0x00000000},
143c888183bSBitterblue Smith {0xD58, 0x00000282}, {0xD5C, 0x30032064},
144c888183bSBitterblue Smith {0xD60, 0x4653DE68}, {0xD64, 0x04518A3C},
145c888183bSBitterblue Smith {0xD68, 0x00002101}, {0xD6C, 0x2A201C16},
146c888183bSBitterblue Smith {0xD70, 0x1812362E}, {0xD74, 0x322C2220},
147c888183bSBitterblue Smith {0xD78, 0x000E3C24}, {0xE00, 0x2D2D2D2D},
148c888183bSBitterblue Smith {0xE04, 0x2D2D2D2D}, {0xE08, 0x0390272D},
149c888183bSBitterblue Smith {0xE10, 0x2D2D2D2D}, {0xE14, 0x2D2D2D2D},
150c888183bSBitterblue Smith {0xE18, 0x2D2D2D2D}, {0xE1C, 0x2D2D2D2D},
151c888183bSBitterblue Smith {0xE28, 0x00000000}, {0xE30, 0x1000DC1F},
152c888183bSBitterblue Smith {0xE34, 0x10008C1F}, {0xE38, 0x02140102},
153c888183bSBitterblue Smith {0xE3C, 0x681604C2}, {0xE40, 0x01007C00},
154c888183bSBitterblue Smith {0xE44, 0x01004800}, {0xE48, 0xFB000000},
155c888183bSBitterblue Smith {0xE4C, 0x000028D1}, {0xE50, 0x1000DC1F},
156c888183bSBitterblue Smith {0xE54, 0x10008C1F}, {0xE58, 0x02140102},
157c888183bSBitterblue Smith {0xE5C, 0x28160D05}, {0xE60, 0x00000008},
158c888183bSBitterblue Smith {0xE60, 0x021400A0}, {0xE64, 0x281600A0},
159c888183bSBitterblue Smith {0xE6C, 0x01C00010}, {0xE70, 0x01C00010},
160c888183bSBitterblue Smith {0xE74, 0x02000010}, {0xE78, 0x02000010},
161c888183bSBitterblue Smith {0xE7C, 0x02000010}, {0xE80, 0x02000010},
162c888183bSBitterblue Smith {0xE84, 0x01C00010}, {0xE88, 0x02000010},
163c888183bSBitterblue Smith {0xE8C, 0x01C00010}, {0xED0, 0x01C00010},
164c888183bSBitterblue Smith {0xED4, 0x01C00010}, {0xED8, 0x01C00010},
165c888183bSBitterblue Smith {0xEDC, 0x00000010}, {0xEE0, 0x00000010},
166c888183bSBitterblue Smith {0xEEC, 0x03C00010}, {0xF14, 0x00000003},
167c888183bSBitterblue Smith {0xF4C, 0x00000000}, {0xF00, 0x00000300},
168c888183bSBitterblue Smith {0xffff, 0xffffffff},
169c888183bSBitterblue Smith };
170c888183bSBitterblue Smith
17179cac25eSBitterblue Smith static const struct rtl8xxxu_reg32val rtl8188f_agc_table[] = {
172c888183bSBitterblue Smith {0xC78, 0xFC000001}, {0xC78, 0xFB010001},
173c888183bSBitterblue Smith {0xC78, 0xFA020001}, {0xC78, 0xF9030001},
174c888183bSBitterblue Smith {0xC78, 0xF8040001}, {0xC78, 0xF7050001},
175c888183bSBitterblue Smith {0xC78, 0xF6060001}, {0xC78, 0xF5070001},
176c888183bSBitterblue Smith {0xC78, 0xF4080001}, {0xC78, 0xF3090001},
177c888183bSBitterblue Smith {0xC78, 0xF20A0001}, {0xC78, 0xF10B0001},
178c888183bSBitterblue Smith {0xC78, 0xF00C0001}, {0xC78, 0xEF0D0001},
179c888183bSBitterblue Smith {0xC78, 0xEE0E0001}, {0xC78, 0xED0F0001},
180c888183bSBitterblue Smith {0xC78, 0xEC100001}, {0xC78, 0xEB110001},
181c888183bSBitterblue Smith {0xC78, 0xEA120001}, {0xC78, 0xE9130001},
182c888183bSBitterblue Smith {0xC78, 0xE8140001}, {0xC78, 0xE7150001},
183c888183bSBitterblue Smith {0xC78, 0xE6160001}, {0xC78, 0xE5170001},
184c888183bSBitterblue Smith {0xC78, 0xE4180001}, {0xC78, 0xE3190001},
185c888183bSBitterblue Smith {0xC78, 0xE21A0001}, {0xC78, 0xE11B0001},
186c888183bSBitterblue Smith {0xC78, 0xE01C0001}, {0xC78, 0xC21D0001},
187c888183bSBitterblue Smith {0xC78, 0xC11E0001}, {0xC78, 0xC01F0001},
188c888183bSBitterblue Smith {0xC78, 0xA5200001}, {0xC78, 0xA4210001},
189c888183bSBitterblue Smith {0xC78, 0xA3220001}, {0xC78, 0xA2230001},
190c888183bSBitterblue Smith {0xC78, 0xA1240001}, {0xC78, 0xA0250001},
191c888183bSBitterblue Smith {0xC78, 0x65260001}, {0xC78, 0x64270001},
192c888183bSBitterblue Smith {0xC78, 0x63280001}, {0xC78, 0x62290001},
193c888183bSBitterblue Smith {0xC78, 0x612A0001}, {0xC78, 0x442B0001},
194c888183bSBitterblue Smith {0xC78, 0x432C0001}, {0xC78, 0x422D0001},
195c888183bSBitterblue Smith {0xC78, 0x412E0001}, {0xC78, 0x402F0001},
196c888183bSBitterblue Smith {0xC78, 0x21300001}, {0xC78, 0x20310001},
197c888183bSBitterblue Smith {0xC78, 0x05320001}, {0xC78, 0x04330001},
198c888183bSBitterblue Smith {0xC78, 0x03340001}, {0xC78, 0x02350001},
199c888183bSBitterblue Smith {0xC78, 0x01360001}, {0xC78, 0x00370001},
200c888183bSBitterblue Smith {0xC78, 0x00380001}, {0xC78, 0x00390001},
201c888183bSBitterblue Smith {0xC78, 0x003A0001}, {0xC78, 0x003B0001},
202c888183bSBitterblue Smith {0xC78, 0x003C0001}, {0xC78, 0x003D0001},
203c888183bSBitterblue Smith {0xC78, 0x003E0001}, {0xC78, 0x003F0001},
204c888183bSBitterblue Smith {0xC50, 0x69553422}, {0xC50, 0x69553420},
205c888183bSBitterblue Smith {0xffff, 0xffffffff}
206c888183bSBitterblue Smith };
207c888183bSBitterblue Smith
20879cac25eSBitterblue Smith static const struct rtl8xxxu_rfregval rtl8188fu_radioa_init_table[] = {
209c888183bSBitterblue Smith {0x00, 0x00030000}, {0x08, 0x00008400},
210c888183bSBitterblue Smith {0x18, 0x00000407}, {0x19, 0x00000012},
211c888183bSBitterblue Smith {0x1B, 0x00001C6C},
212c888183bSBitterblue Smith {0x1E, 0x00080009}, {0x1F, 0x00000880},
213c888183bSBitterblue Smith {0x2F, 0x0001A060}, {0x3F, 0x00028000},
214c888183bSBitterblue Smith {0x42, 0x000060C0}, {0x57, 0x000D0000},
215c888183bSBitterblue Smith {0x58, 0x000C0160}, {0x67, 0x00001552},
216c888183bSBitterblue Smith {0x83, 0x00000000}, {0xB0, 0x000FF9F0},
217c888183bSBitterblue Smith {0xB1, 0x00022218}, {0xB2, 0x00034C00},
218c888183bSBitterblue Smith {0xB4, 0x0004484B}, {0xB5, 0x0000112A},
219c888183bSBitterblue Smith {0xB6, 0x0000053E}, {0xB7, 0x00010408},
220c888183bSBitterblue Smith {0xB8, 0x00010200}, {0xB9, 0x00080001},
221c888183bSBitterblue Smith {0xBA, 0x00040001}, {0xBB, 0x00000400},
222c888183bSBitterblue Smith {0xBF, 0x000C0000}, {0xC2, 0x00002400},
223c888183bSBitterblue Smith {0xC3, 0x00000009}, {0xC4, 0x00040C91},
224c888183bSBitterblue Smith {0xC5, 0x00099999}, {0xC6, 0x000000A3},
225c888183bSBitterblue Smith {0xC7, 0x0008F820}, {0xC8, 0x00076C06},
226c888183bSBitterblue Smith {0xC9, 0x00000000}, {0xCA, 0x00080000},
227c888183bSBitterblue Smith {0xDF, 0x00000180}, {0xEF, 0x000001A0},
228c888183bSBitterblue Smith {0x51, 0x000E8333}, {0x52, 0x000FAC2C},
229c888183bSBitterblue Smith {0x53, 0x00000103}, {0x56, 0x000517F0},
230c888183bSBitterblue Smith {0x35, 0x00000099}, {0x35, 0x00000199},
231c888183bSBitterblue Smith {0x35, 0x00000299}, {0x36, 0x00000064},
232c888183bSBitterblue Smith {0x36, 0x00008064}, {0x36, 0x00010064},
233c888183bSBitterblue Smith {0x36, 0x00018064}, {0x18, 0x00000C07},
234c888183bSBitterblue Smith {0x5A, 0x00048000}, {0x19, 0x000739D0},
235c888183bSBitterblue Smith {0x34, 0x0000ADD6}, {0x34, 0x00009DD3},
236c888183bSBitterblue Smith {0x34, 0x00008CF4}, {0x34, 0x00007CF1},
237c888183bSBitterblue Smith {0x34, 0x00006CEE}, {0x34, 0x00005CEB},
238c888183bSBitterblue Smith {0x34, 0x00004CCE}, {0x34, 0x00003CCB},
239c888183bSBitterblue Smith {0x34, 0x00002CC8}, {0x34, 0x00001C4B},
240c888183bSBitterblue Smith {0x34, 0x00000C48},
241c888183bSBitterblue Smith {0x00, 0x00030159}, {0x84, 0x00048000},
242c888183bSBitterblue Smith {0x86, 0x0000002A}, {0x87, 0x00000025},
243c888183bSBitterblue Smith {0x8E, 0x00065540}, {0x8F, 0x00088000},
244c888183bSBitterblue Smith {0xEF, 0x000020A0}, {0x3B, 0x000F0F00},
245c888183bSBitterblue Smith {0x3B, 0x000E0B00}, {0x3B, 0x000D0900},
246c888183bSBitterblue Smith {0x3B, 0x000C0700}, {0x3B, 0x000B0600},
247c888183bSBitterblue Smith {0x3B, 0x000A0400}, {0x3B, 0x00090200},
248c888183bSBitterblue Smith {0x3B, 0x00080000}, {0x3B, 0x0007BF00},
249c888183bSBitterblue Smith {0x3B, 0x00060B00}, {0x3B, 0x0005C900},
250c888183bSBitterblue Smith {0x3B, 0x00040700}, {0x3B, 0x00030600},
251c888183bSBitterblue Smith {0x3B, 0x0002D500}, {0x3B, 0x00010200},
252c888183bSBitterblue Smith {0x3B, 0x0000E000}, {0xEF, 0x000000A0},
253c888183bSBitterblue Smith {0xEF, 0x00000010}, {0x3B, 0x0000C0A8},
254c888183bSBitterblue Smith {0x3B, 0x00010400}, {0xEF, 0x00000000},
255c888183bSBitterblue Smith {0xEF, 0x00080000}, {0x30, 0x00010000},
256c888183bSBitterblue Smith {0x31, 0x0000000F}, {0x32, 0x00007EFE},
257c888183bSBitterblue Smith {0xEF, 0x00000000}, {0x00, 0x00010159},
258c888183bSBitterblue Smith {0x18, 0x0000FC07}, {0xFE, 0x00000000},
259c888183bSBitterblue Smith {0xFE, 0x00000000}, {0x1F, 0x00080003},
260c888183bSBitterblue Smith {0xFE, 0x00000000}, {0xFE, 0x00000000},
261c888183bSBitterblue Smith {0x1E, 0x00000001}, {0x1F, 0x00080000},
262c888183bSBitterblue Smith {0x00, 0x00033D95},
263c888183bSBitterblue Smith {0xff, 0xffffffff}
264c888183bSBitterblue Smith };
265c888183bSBitterblue Smith
26679cac25eSBitterblue Smith static const struct rtl8xxxu_rfregval rtl8188fu_cut_b_radioa_init_table[] = {
267c888183bSBitterblue Smith {0x00, 0x00030000}, {0x08, 0x00008400},
268c888183bSBitterblue Smith {0x18, 0x00000407}, {0x19, 0x00000012},
269c888183bSBitterblue Smith {0x1B, 0x00001C6C},
270c888183bSBitterblue Smith {0x1E, 0x00080009}, {0x1F, 0x00000880},
271c888183bSBitterblue Smith {0x2F, 0x0001A060}, {0x3F, 0x00028000},
272c888183bSBitterblue Smith {0x42, 0x000060C0}, {0x57, 0x000D0000},
273c888183bSBitterblue Smith {0x58, 0x000C0160}, {0x67, 0x00001552},
274c888183bSBitterblue Smith {0x83, 0x00000000}, {0xB0, 0x000FF9F0},
275c888183bSBitterblue Smith {0xB1, 0x00022218}, {0xB2, 0x00034C00},
276c888183bSBitterblue Smith {0xB4, 0x0004484B}, {0xB5, 0x0000112A},
277c888183bSBitterblue Smith {0xB6, 0x0000053E}, {0xB7, 0x00010408},
278c888183bSBitterblue Smith {0xB8, 0x00010200}, {0xB9, 0x00080001},
279c888183bSBitterblue Smith {0xBA, 0x00040001}, {0xBB, 0x00000400},
280c888183bSBitterblue Smith {0xBF, 0x000C0000}, {0xC2, 0x00002400},
281c888183bSBitterblue Smith {0xC3, 0x00000009}, {0xC4, 0x00040C91},
282c888183bSBitterblue Smith {0xC5, 0x00099999}, {0xC6, 0x000000A3},
283c888183bSBitterblue Smith {0xC7, 0x0008F820}, {0xC8, 0x00076C06},
284c888183bSBitterblue Smith {0xC9, 0x00000000}, {0xCA, 0x00080000},
285c888183bSBitterblue Smith {0xDF, 0x00000180}, {0xEF, 0x000001A0},
286c888183bSBitterblue Smith {0x51, 0x000E8231}, {0x52, 0x000FAC2C},
287c888183bSBitterblue Smith {0x53, 0x00000141}, {0x56, 0x000517F0},
288c888183bSBitterblue Smith {0x35, 0x00000090}, {0x35, 0x00000190},
289c888183bSBitterblue Smith {0x35, 0x00000290}, {0x36, 0x00001064},
290c888183bSBitterblue Smith {0x36, 0x00009064}, {0x36, 0x00011064},
291c888183bSBitterblue Smith {0x36, 0x00019064}, {0x18, 0x00000C07},
292c888183bSBitterblue Smith {0x5A, 0x00048000}, {0x19, 0x000739D0},
293c888183bSBitterblue Smith {0x34, 0x0000ADD2}, {0x34, 0x00009DD0},
294c888183bSBitterblue Smith {0x34, 0x00008CF3}, {0x34, 0x00007CF0},
295c888183bSBitterblue Smith {0x34, 0x00006CED}, {0x34, 0x00005CD2},
296c888183bSBitterblue Smith {0x34, 0x00004CCF}, {0x34, 0x00003CCC},
297c888183bSBitterblue Smith {0x34, 0x00002CC9}, {0x34, 0x00001C4C},
298c888183bSBitterblue Smith {0x34, 0x00000C49},
299c888183bSBitterblue Smith {0x00, 0x00030159}, {0x84, 0x00048000},
300c888183bSBitterblue Smith {0x86, 0x0000002A}, {0x87, 0x00000025},
301c888183bSBitterblue Smith {0x8E, 0x00065540}, {0x8F, 0x00088000},
302c888183bSBitterblue Smith {0xEF, 0x000020A0}, {0x3B, 0x000F0F00},
303c888183bSBitterblue Smith {0x3B, 0x000E0B00}, {0x3B, 0x000D0900},
304c888183bSBitterblue Smith {0x3B, 0x000C0700}, {0x3B, 0x000B0600},
305c888183bSBitterblue Smith {0x3B, 0x000A0400}, {0x3B, 0x00090200},
306c888183bSBitterblue Smith {0x3B, 0x00080000}, {0x3B, 0x0007BF00},
307c888183bSBitterblue Smith {0x3B, 0x00060B00}, {0x3B, 0x0005C900},
308c888183bSBitterblue Smith {0x3B, 0x00040700}, {0x3B, 0x00030600},
309c888183bSBitterblue Smith {0x3B, 0x0002D500}, {0x3B, 0x00010200},
310c888183bSBitterblue Smith {0x3B, 0x0000E000}, {0xEF, 0x000000A0},
311c888183bSBitterblue Smith {0xEF, 0x00000010}, {0x3B, 0x0000C0A8},
312c888183bSBitterblue Smith {0x3B, 0x00010400}, {0xEF, 0x00000000},
313c888183bSBitterblue Smith {0xEF, 0x00080000}, {0x30, 0x00010000},
314c888183bSBitterblue Smith {0x31, 0x0000000F}, {0x32, 0x00007EFE},
315c888183bSBitterblue Smith {0xEF, 0x00000000}, {0x00, 0x00010159},
316c888183bSBitterblue Smith {0x18, 0x0000FC07}, {0xFE, 0x00000000},
317c888183bSBitterblue Smith {0xFE, 0x00000000}, {0x1F, 0x00080003},
318c888183bSBitterblue Smith {0xFE, 0x00000000}, {0xFE, 0x00000000},
319c888183bSBitterblue Smith {0x1E, 0x00000001}, {0x1F, 0x00080000},
320c888183bSBitterblue Smith {0x00, 0x00033D95},
321c888183bSBitterblue Smith {0xff, 0xffffffff}
322c888183bSBitterblue Smith };
323c888183bSBitterblue Smith
rtl8188fu_identify_chip(struct rtl8xxxu_priv * priv)32414566bbfSBitterblue Smith static int rtl8188fu_identify_chip(struct rtl8xxxu_priv *priv)
32514566bbfSBitterblue Smith {
32614566bbfSBitterblue Smith struct device *dev = &priv->udev->dev;
32714566bbfSBitterblue Smith u32 sys_cfg, vendor;
32814566bbfSBitterblue Smith int ret = 0;
32914566bbfSBitterblue Smith
3309b00565aSBitterblue Smith strscpy(priv->chip_name, "8188FU", sizeof(priv->chip_name));
33114566bbfSBitterblue Smith priv->rtl_chip = RTL8188F;
33214566bbfSBitterblue Smith priv->rf_paths = 1;
33314566bbfSBitterblue Smith priv->rx_paths = 1;
33414566bbfSBitterblue Smith priv->tx_paths = 1;
33514566bbfSBitterblue Smith priv->has_wifi = 1;
33614566bbfSBitterblue Smith
33714566bbfSBitterblue Smith sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG);
33860d18ddbSBitterblue Smith priv->chip_cut = u32_get_bits(sys_cfg, SYS_CFG_CHIP_VERSION_MASK);
33914566bbfSBitterblue Smith if (sys_cfg & SYS_CFG_TRP_VAUX_EN) {
34014566bbfSBitterblue Smith dev_info(dev, "Unsupported test chip\n");
34114566bbfSBitterblue Smith ret = -ENOTSUPP;
34214566bbfSBitterblue Smith goto out;
34314566bbfSBitterblue Smith }
34414566bbfSBitterblue Smith
34514566bbfSBitterblue Smith vendor = sys_cfg & SYS_CFG_VENDOR_EXT_MASK;
34614566bbfSBitterblue Smith rtl8xxxu_identify_vendor_2bits(priv, vendor);
34714566bbfSBitterblue Smith
34814566bbfSBitterblue Smith ret = rtl8xxxu_config_endpoints_no_sie(priv);
34914566bbfSBitterblue Smith
35014566bbfSBitterblue Smith out:
35114566bbfSBitterblue Smith return ret;
35214566bbfSBitterblue Smith }
35314566bbfSBitterblue Smith
rtl8188f_channel_to_group(int channel,int * group,int * cck_group)354c98411dcSBitterblue Smith void rtl8188f_channel_to_group(int channel, int *group, int *cck_group)
355c888183bSBitterblue Smith {
356c888183bSBitterblue Smith if (channel < 3)
357c888183bSBitterblue Smith *group = 0;
358c888183bSBitterblue Smith else if (channel < 6)
359c888183bSBitterblue Smith *group = 1;
360c888183bSBitterblue Smith else if (channel < 9)
361c888183bSBitterblue Smith *group = 2;
362c888183bSBitterblue Smith else if (channel < 12)
363c888183bSBitterblue Smith *group = 3;
364c888183bSBitterblue Smith else
365c888183bSBitterblue Smith *group = 4;
366c888183bSBitterblue Smith
367c888183bSBitterblue Smith if (channel == 14)
368c888183bSBitterblue Smith *cck_group = 5;
369c888183bSBitterblue Smith else
370c888183bSBitterblue Smith *cck_group = *group;
371c888183bSBitterblue Smith }
372c888183bSBitterblue Smith
3733dfb8e84SJes Sorensen void
rtl8188f_set_tx_power(struct rtl8xxxu_priv * priv,int channel,bool ht40)374c888183bSBitterblue Smith rtl8188f_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
375c888183bSBitterblue Smith {
376c888183bSBitterblue Smith u32 val32, ofdm, mcs;
377c888183bSBitterblue Smith u8 cck, ofdmbase, mcsbase;
378c888183bSBitterblue Smith int group, cck_group;
379c888183bSBitterblue Smith
380e948023dSBitterblue Smith rtl8188f_channel_to_group(channel, &group, &cck_group);
381c888183bSBitterblue Smith
382c888183bSBitterblue Smith cck = priv->cck_tx_power_index_A[cck_group];
383c888183bSBitterblue Smith
384c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_TX_AGC_A_CCK1_MCS32);
385c888183bSBitterblue Smith val32 &= 0xffff00ff;
386c888183bSBitterblue Smith val32 |= (cck << 8);
387c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_AGC_A_CCK1_MCS32, val32);
388c888183bSBitterblue Smith
389c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11);
390c888183bSBitterblue Smith val32 &= 0xff;
391c888183bSBitterblue Smith val32 |= ((cck << 8) | (cck << 16) | (cck << 24));
392c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_AGC_B_CCK11_A_CCK2_11, val32);
393c888183bSBitterblue Smith
394c888183bSBitterblue Smith ofdmbase = priv->ht40_1s_tx_power_index_A[group];
395c888183bSBitterblue Smith ofdmbase += priv->ofdm_tx_power_diff[0].a;
396c888183bSBitterblue Smith ofdm = ofdmbase | ofdmbase << 8 | ofdmbase << 16 | ofdmbase << 24;
397c888183bSBitterblue Smith
398c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE18_06, ofdm);
399c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_AGC_A_RATE54_24, ofdm);
400c888183bSBitterblue Smith
401c888183bSBitterblue Smith mcsbase = priv->ht40_1s_tx_power_index_A[group];
402c888183bSBitterblue Smith if (ht40)
403c888183bSBitterblue Smith /* This diff is always 0 - not used in 8188FU. */
404c888183bSBitterblue Smith mcsbase += priv->ht40_tx_power_diff[0].a;
405c888183bSBitterblue Smith else
406c888183bSBitterblue Smith mcsbase += priv->ht20_tx_power_diff[0].a;
407c888183bSBitterblue Smith mcs = mcsbase | mcsbase << 8 | mcsbase << 16 | mcsbase << 24;
408c888183bSBitterblue Smith
409c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS03_MCS00, mcs);
410c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS07_MCS04, mcs);
411c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS11_MCS08, mcs);
412c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12, mcs);
413c888183bSBitterblue Smith }
414c888183bSBitterblue Smith
415c888183bSBitterblue Smith /* A workaround to eliminate the 2400MHz, 2440MHz, 2480MHz spur of 8188F. */
rtl8188f_spur_calibration(struct rtl8xxxu_priv * priv,u8 channel)416c888183bSBitterblue Smith static void rtl8188f_spur_calibration(struct rtl8xxxu_priv *priv, u8 channel)
417c888183bSBitterblue Smith {
418c888183bSBitterblue Smith static const u32 frequencies[14 + 1] = {
419c888183bSBitterblue Smith [5] = 0xFCCD,
420c888183bSBitterblue Smith [6] = 0xFC4D,
421c888183bSBitterblue Smith [7] = 0xFFCD,
422c888183bSBitterblue Smith [8] = 0xFF4D,
423c888183bSBitterblue Smith [11] = 0xFDCD,
424c888183bSBitterblue Smith [13] = 0xFCCD,
425c888183bSBitterblue Smith [14] = 0xFF9A
426c888183bSBitterblue Smith };
427c888183bSBitterblue Smith
428c888183bSBitterblue Smith static const u32 reg_d40[14 + 1] = {
429c888183bSBitterblue Smith [5] = 0x06000000,
430c888183bSBitterblue Smith [6] = 0x00000600,
431c888183bSBitterblue Smith [13] = 0x06000000
432c888183bSBitterblue Smith };
433c888183bSBitterblue Smith
434c888183bSBitterblue Smith static const u32 reg_d44[14 + 1] = {
435c888183bSBitterblue Smith [11] = 0x04000000
436c888183bSBitterblue Smith };
437c888183bSBitterblue Smith
438c888183bSBitterblue Smith static const u32 reg_d4c[14 + 1] = {
439c888183bSBitterblue Smith [7] = 0x06000000,
440c888183bSBitterblue Smith [8] = 0x00000380,
441c888183bSBitterblue Smith [14] = 0x00180000
442c888183bSBitterblue Smith };
443c888183bSBitterblue Smith
444c888183bSBitterblue Smith const u8 threshold = 0x16;
44580e5acb6SColin Ian King bool do_notch, hw_ctrl, sw_ctrl, hw_ctrl_s1 = 0, sw_ctrl_s1 = 0;
446c888183bSBitterblue Smith u32 val32, initial_gain, reg948;
447c888183bSBitterblue Smith
448c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_RX_D_SYNC_PATH);
449c888183bSBitterblue Smith val32 |= GENMASK(28, 24);
450c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_RX_D_SYNC_PATH, val32);
451c888183bSBitterblue Smith
452c888183bSBitterblue Smith /* enable notch filter */
453c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_RX_D_SYNC_PATH);
454c888183bSBitterblue Smith val32 |= BIT(9);
455c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_RX_D_SYNC_PATH, val32);
456c888183bSBitterblue Smith
457c888183bSBitterblue Smith if (channel <= 14 && frequencies[channel] > 0) {
458c888183bSBitterblue Smith reg948 = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH);
459c888183bSBitterblue Smith hw_ctrl = reg948 & BIT(6);
460c888183bSBitterblue Smith sw_ctrl = !hw_ctrl;
461c888183bSBitterblue Smith
462c888183bSBitterblue Smith if (hw_ctrl) {
463c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_XB_RF_INT_OE);
464c888183bSBitterblue Smith val32 &= GENMASK(5, 3);
465c888183bSBitterblue Smith hw_ctrl_s1 = val32 == BIT(3);
466c888183bSBitterblue Smith } else if (sw_ctrl) {
467c888183bSBitterblue Smith sw_ctrl_s1 = !(reg948 & BIT(9));
468c888183bSBitterblue Smith }
469c888183bSBitterblue Smith
470c888183bSBitterblue Smith if (hw_ctrl_s1 || sw_ctrl_s1) {
471c888183bSBitterblue Smith initial_gain = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1);
472c888183bSBitterblue Smith
473c888183bSBitterblue Smith /* Disable CCK block */
474c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
475c888183bSBitterblue Smith val32 &= ~FPGA_RF_MODE_CCK;
476c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
477c888183bSBitterblue Smith
478c888183bSBitterblue Smith val32 = initial_gain & ~OFDM0_X_AGC_CORE1_IGI_MASK;
479c888183bSBitterblue Smith val32 |= 0x30;
480c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32);
481c888183bSBitterblue Smith
482c888183bSBitterblue Smith /* disable 3-wire */
483c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccf000c0);
484c888183bSBitterblue Smith
485c888183bSBitterblue Smith /* Setup PSD */
486c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_PSD_FUNC, frequencies[channel]);
487c888183bSBitterblue Smith
488c888183bSBitterblue Smith /* Start PSD */
489c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_PSD_FUNC, 0x400000 | frequencies[channel]);
490c888183bSBitterblue Smith
491c888183bSBitterblue Smith msleep(30);
492c888183bSBitterblue Smith
493c888183bSBitterblue Smith do_notch = rtl8xxxu_read32(priv, REG_FPGA0_PSD_REPORT) >= threshold;
494c888183bSBitterblue Smith
495c888183bSBitterblue Smith /* turn off PSD */
496c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_PSD_FUNC, frequencies[channel]);
497c888183bSBitterblue Smith
498c888183bSBitterblue Smith /* enable 3-wire */
499c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_ANALOG4, 0xccc000c0);
500c888183bSBitterblue Smith
501c888183bSBitterblue Smith /* Enable CCK block */
502c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
503c888183bSBitterblue Smith val32 |= FPGA_RF_MODE_CCK;
504c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
505c888183bSBitterblue Smith
506c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, initial_gain);
507c888183bSBitterblue Smith
508c888183bSBitterblue Smith if (do_notch) {
509c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM1_CSI_FIX_MASK1, reg_d40[channel]);
510c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM1_CSI_FIX_MASK2, reg_d44[channel]);
511c888183bSBitterblue Smith rtl8xxxu_write32(priv, 0xd48, 0x0);
512c888183bSBitterblue Smith rtl8xxxu_write32(priv, 0xd4c, reg_d4c[channel]);
513c888183bSBitterblue Smith
514c888183bSBitterblue Smith /* enable CSI mask */
515c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM1_CFO_TRACKING);
516c888183bSBitterblue Smith val32 |= BIT(28);
517c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM1_CFO_TRACKING, val32);
518c888183bSBitterblue Smith
519c888183bSBitterblue Smith return;
520c888183bSBitterblue Smith }
521c888183bSBitterblue Smith }
522c888183bSBitterblue Smith }
523c888183bSBitterblue Smith
524c888183bSBitterblue Smith /* disable CSI mask function */
525c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM1_CFO_TRACKING);
526c888183bSBitterblue Smith val32 &= ~BIT(28);
527c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM1_CFO_TRACKING, val32);
528c888183bSBitterblue Smith }
529c888183bSBitterblue Smith
rtl8188fu_config_channel(struct ieee80211_hw * hw)530c888183bSBitterblue Smith static void rtl8188fu_config_channel(struct ieee80211_hw *hw)
531c888183bSBitterblue Smith {
532c888183bSBitterblue Smith struct rtl8xxxu_priv *priv = hw->priv;
533c888183bSBitterblue Smith u32 val32;
534c888183bSBitterblue Smith u8 channel, subchannel;
535c888183bSBitterblue Smith bool sec_ch_above;
536c888183bSBitterblue Smith
537c888183bSBitterblue Smith channel = (u8)hw->conf.chandef.chan->hw_value;
538c888183bSBitterblue Smith
539c888183bSBitterblue Smith /* Set channel */
540c888183bSBitterblue Smith val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG);
541c888183bSBitterblue Smith val32 &= ~MODE_AG_CHANNEL_MASK;
542c888183bSBitterblue Smith val32 |= channel;
543c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32);
544c888183bSBitterblue Smith
545c888183bSBitterblue Smith /* Spur calibration */
546c888183bSBitterblue Smith rtl8188f_spur_calibration(priv, channel);
547c888183bSBitterblue Smith
548c888183bSBitterblue Smith /* Set bandwidth mode */
549c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
550c888183bSBitterblue Smith val32 &= ~FPGA_RF_MODE;
551c888183bSBitterblue Smith val32 |= hw->conf.chandef.width == NL80211_CHAN_WIDTH_40;
552c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
553c888183bSBitterblue Smith
554c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA1_RF_MODE);
555c888183bSBitterblue Smith val32 &= ~FPGA_RF_MODE;
556c888183bSBitterblue Smith val32 |= hw->conf.chandef.width == NL80211_CHAN_WIDTH_40;
557c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA1_RF_MODE, val32);
558c888183bSBitterblue Smith
559c888183bSBitterblue Smith /* RXADC CLK */
560c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
561c888183bSBitterblue Smith val32 |= GENMASK(10, 8);
562c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
563c888183bSBitterblue Smith
564c888183bSBitterblue Smith /* TXDAC CLK */
565c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
566c888183bSBitterblue Smith val32 |= BIT(14) | BIT(12);
567c888183bSBitterblue Smith val32 &= ~BIT(13);
568c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
569c888183bSBitterblue Smith
570c888183bSBitterblue Smith /* small BW */
571c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT);
572c888183bSBitterblue Smith val32 &= ~GENMASK(31, 30);
573c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32);
574c888183bSBitterblue Smith
575c888183bSBitterblue Smith /* adc buffer clk */
576c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT);
577c888183bSBitterblue Smith val32 &= ~BIT(29);
578c888183bSBitterblue Smith val32 |= BIT(28);
579c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_TX_PSDO_NOISE_WEIGHT, val32);
580c888183bSBitterblue Smith
581c888183bSBitterblue Smith /* adc buffer clk */
582c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_RX_AFE);
583c888183bSBitterblue Smith val32 &= ~BIT(29);
584c888183bSBitterblue Smith val32 |= BIT(28);
585c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_XA_RX_AFE, val32);
586c888183bSBitterblue Smith
587c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR);
588c888183bSBitterblue Smith val32 &= ~BIT(19);
589c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32);
590c888183bSBitterblue Smith
591c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM_RX_DFIR);
592c888183bSBitterblue Smith val32 &= ~GENMASK(23, 20);
593c888183bSBitterblue Smith val32 |= BIT(21);
594c888183bSBitterblue Smith if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20 ||
595c888183bSBitterblue Smith hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
596c888183bSBitterblue Smith val32 |= BIT(20);
597c888183bSBitterblue Smith else if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40)
598c888183bSBitterblue Smith val32 |= BIT(22);
599c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM_RX_DFIR, val32);
600c888183bSBitterblue Smith
601c888183bSBitterblue Smith if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) {
602c888183bSBitterblue Smith if (hw->conf.chandef.center_freq1 >
603c888183bSBitterblue Smith hw->conf.chandef.chan->center_freq) {
604c888183bSBitterblue Smith sec_ch_above = 1;
605c888183bSBitterblue Smith channel += 2;
606c888183bSBitterblue Smith } else {
607c888183bSBitterblue Smith sec_ch_above = 0;
608c888183bSBitterblue Smith channel -= 2;
609c888183bSBitterblue Smith }
610c888183bSBitterblue Smith
611c888183bSBitterblue Smith /* Set Control channel to upper or lower. */
612c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_CCK0_SYSTEM);
613c888183bSBitterblue Smith val32 &= ~CCK0_SIDEBAND;
614c888183bSBitterblue Smith if (!sec_ch_above)
615c888183bSBitterblue Smith val32 |= CCK0_SIDEBAND;
616c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_CCK0_SYSTEM, val32);
617c888183bSBitterblue Smith
618c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_DATA_SUBCHANNEL);
619c888183bSBitterblue Smith val32 &= ~GENMASK(3, 0);
620c888183bSBitterblue Smith if (sec_ch_above)
621c888183bSBitterblue Smith subchannel = 2;
622c888183bSBitterblue Smith else
623c888183bSBitterblue Smith subchannel = 1;
624c888183bSBitterblue Smith val32 |= subchannel;
625c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_DATA_SUBCHANNEL, val32);
626c888183bSBitterblue Smith
627c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_RESPONSE_RATE_SET);
628c888183bSBitterblue Smith val32 &= ~RSR_RSC_BANDWIDTH_40M;
629c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RESPONSE_RATE_SET, val32);
630c888183bSBitterblue Smith }
631c888183bSBitterblue Smith
632c888183bSBitterblue Smith /* RF TRX_BW */
633c888183bSBitterblue Smith val32 = channel;
634c888183bSBitterblue Smith if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20 ||
635c888183bSBitterblue Smith hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
636c888183bSBitterblue Smith val32 |= MODE_AG_BW_20MHZ_8723B;
637c888183bSBitterblue Smith else if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40)
638c888183bSBitterblue Smith val32 |= MODE_AG_BW_40MHZ_8723B;
639c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, val32);
640c888183bSBitterblue Smith
641c888183bSBitterblue Smith /* FILTER BW&RC Corner (ACPR) */
642c888183bSBitterblue Smith if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20 ||
643c888183bSBitterblue Smith hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
644c888183bSBitterblue Smith val32 = 0x00065;
645c888183bSBitterblue Smith else if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40)
646c888183bSBitterblue Smith val32 = 0x00025;
647c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RXG_MIX_SWBW, val32);
648c888183bSBitterblue Smith
649c888183bSBitterblue Smith if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20 ||
650c888183bSBitterblue Smith hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
651c888183bSBitterblue Smith val32 = 0x0;
652c888183bSBitterblue Smith else if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40)
653c888183bSBitterblue Smith val32 = 0x01000;
654c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RX_BB2, val32);
655c888183bSBitterblue Smith
656c888183bSBitterblue Smith /* RC Corner */
657103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x00140);
658c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RX_G2, 0x01c6c);
659c888183bSBitterblue Smith }
660c888183bSBitterblue Smith
rtl8188fu_init_aggregation(struct rtl8xxxu_priv * priv)661c888183bSBitterblue Smith static void rtl8188fu_init_aggregation(struct rtl8xxxu_priv *priv)
662c888183bSBitterblue Smith {
663c888183bSBitterblue Smith u8 agg_ctrl, rxdma_mode, usb_tx_agg_desc_num = 6;
664c888183bSBitterblue Smith u32 agg_rx, val32;
665c888183bSBitterblue Smith
666c888183bSBitterblue Smith /* TX aggregation */
667c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_DWBCN0_CTRL_8188F);
668c888183bSBitterblue Smith val32 &= ~(0xf << 4);
669c888183bSBitterblue Smith val32 |= usb_tx_agg_desc_num << 4;
670c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_DWBCN0_CTRL_8188F, val32);
671c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_DWBCN1_CTRL_8723B, usb_tx_agg_desc_num << 1);
672c888183bSBitterblue Smith
673c888183bSBitterblue Smith /* RX aggregation */
674c888183bSBitterblue Smith agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL);
675c888183bSBitterblue Smith agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN;
676c888183bSBitterblue Smith
677c888183bSBitterblue Smith agg_rx = rtl8xxxu_read32(priv, REG_RXDMA_AGG_PG_TH);
678c888183bSBitterblue Smith agg_rx &= ~RXDMA_USB_AGG_ENABLE;
679c888183bSBitterblue Smith agg_rx &= ~0xFF0F; /* reset agg size and timeout */
680c888183bSBitterblue Smith
681c888183bSBitterblue Smith rxdma_mode = rtl8xxxu_read8(priv, REG_RXDMA_PRO_8723B);
682c888183bSBitterblue Smith rxdma_mode &= ~BIT(1);
683c888183bSBitterblue Smith
684c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl);
685c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RXDMA_AGG_PG_TH, agg_rx);
686c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_RXDMA_PRO_8723B, rxdma_mode);
687c888183bSBitterblue Smith }
688c888183bSBitterblue Smith
rtl8188fu_init_statistics(struct rtl8xxxu_priv * priv)689c888183bSBitterblue Smith static void rtl8188fu_init_statistics(struct rtl8xxxu_priv *priv)
690c888183bSBitterblue Smith {
691c888183bSBitterblue Smith u32 val32;
692c888183bSBitterblue Smith
693c888183bSBitterblue Smith /* Time duration for NHM unit: 4us, 0xc350=200ms */
694c888183bSBitterblue Smith rtl8xxxu_write16(priv, REG_NHM_TIMER_8723B + 2, 0xc350);
695c888183bSBitterblue Smith rtl8xxxu_write16(priv, REG_NHM_TH9_TH10_8723B + 2, 0xffff);
696c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_NHM_TH3_TO_TH0_8723B, 0xffffff50);
697c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_NHM_TH7_TO_TH4_8723B, 0xffffffff);
698c888183bSBitterblue Smith
699c888183bSBitterblue Smith /* TH8 */
700c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
701c888183bSBitterblue Smith val32 |= 0xff;
702c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
703c888183bSBitterblue Smith
704c888183bSBitterblue Smith /* Enable CCK */
705c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_NHM_TH9_TH10_8723B);
706c888183bSBitterblue Smith val32 &= ~(BIT(8) | BIT(9) | BIT(10));
707c888183bSBitterblue Smith val32 |= BIT(8);
708c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_NHM_TH9_TH10_8723B, val32);
709c888183bSBitterblue Smith
710c888183bSBitterblue Smith /* Max power amongst all RX antennas */
711c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_FA_RSTC);
712c888183bSBitterblue Smith val32 |= BIT(7);
713c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_FA_RSTC, val32);
714c888183bSBitterblue Smith }
715c888183bSBitterblue Smith
716*0f6b8aedSMartin Kaistra #define TX_POWER_INDEX_MAX 0x3F
717*0f6b8aedSMartin Kaistra #define TX_POWER_INDEX_DEFAULT_CCK 0x22
718*0f6b8aedSMartin Kaistra #define TX_POWER_INDEX_DEFAULT_HT40 0x27
719*0f6b8aedSMartin Kaistra
rtl8188fu_parse_efuse(struct rtl8xxxu_priv * priv)720c888183bSBitterblue Smith static int rtl8188fu_parse_efuse(struct rtl8xxxu_priv *priv)
721c888183bSBitterblue Smith {
722c888183bSBitterblue Smith struct rtl8188fu_efuse *efuse = &priv->efuse_wifi.efuse8188fu;
723*0f6b8aedSMartin Kaistra int i;
724c888183bSBitterblue Smith
725c888183bSBitterblue Smith if (efuse->rtl_id != cpu_to_le16(0x8129))
726c888183bSBitterblue Smith return -EINVAL;
727c888183bSBitterblue Smith
728c888183bSBitterblue Smith ether_addr_copy(priv->mac_addr, efuse->mac_addr);
729c888183bSBitterblue Smith
730c888183bSBitterblue Smith memcpy(priv->cck_tx_power_index_A, efuse->tx_power_index_A.cck_base,
731c888183bSBitterblue Smith sizeof(efuse->tx_power_index_A.cck_base));
732c888183bSBitterblue Smith
733c888183bSBitterblue Smith memcpy(priv->ht40_1s_tx_power_index_A,
734c888183bSBitterblue Smith efuse->tx_power_index_A.ht40_base,
735c888183bSBitterblue Smith sizeof(efuse->tx_power_index_A.ht40_base));
736c888183bSBitterblue Smith
737*0f6b8aedSMartin Kaistra for (i = 0; i < ARRAY_SIZE(priv->cck_tx_power_index_A); i++) {
738*0f6b8aedSMartin Kaistra if (priv->cck_tx_power_index_A[i] > TX_POWER_INDEX_MAX)
739*0f6b8aedSMartin Kaistra priv->cck_tx_power_index_A[i] = TX_POWER_INDEX_DEFAULT_CCK;
740*0f6b8aedSMartin Kaistra }
741*0f6b8aedSMartin Kaistra
742*0f6b8aedSMartin Kaistra for (i = 0; i < ARRAY_SIZE(priv->ht40_1s_tx_power_index_A); i++) {
743*0f6b8aedSMartin Kaistra if (priv->ht40_1s_tx_power_index_A[i] > TX_POWER_INDEX_MAX)
744*0f6b8aedSMartin Kaistra priv->ht40_1s_tx_power_index_A[i] = TX_POWER_INDEX_DEFAULT_HT40;
745*0f6b8aedSMartin Kaistra }
746*0f6b8aedSMartin Kaistra
747c888183bSBitterblue Smith priv->ofdm_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.a;
748c888183bSBitterblue Smith priv->ht20_tx_power_diff[0].a = efuse->tx_power_index_A.ht20_ofdm_1s_diff.b;
749c888183bSBitterblue Smith
75057b328bcSBitterblue Smith priv->default_crystal_cap = efuse->xtal_k & 0x3f;
751c888183bSBitterblue Smith
752c888183bSBitterblue Smith return 0;
753c888183bSBitterblue Smith }
754c888183bSBitterblue Smith
rtl8188fu_load_firmware(struct rtl8xxxu_priv * priv)755c888183bSBitterblue Smith static int rtl8188fu_load_firmware(struct rtl8xxxu_priv *priv)
756c888183bSBitterblue Smith {
757d7a3705cSBitterblue Smith const char *fw_name;
758c888183bSBitterblue Smith int ret;
759c888183bSBitterblue Smith
760c888183bSBitterblue Smith fw_name = "rtlwifi/rtl8188fufw.bin";
761c888183bSBitterblue Smith
762c888183bSBitterblue Smith ret = rtl8xxxu_load_firmware(priv, fw_name);
763c888183bSBitterblue Smith
764c888183bSBitterblue Smith return ret;
765c888183bSBitterblue Smith }
766c888183bSBitterblue Smith
rtl8188fu_init_phy_bb(struct rtl8xxxu_priv * priv)767c888183bSBitterblue Smith static void rtl8188fu_init_phy_bb(struct rtl8xxxu_priv *priv)
768c888183bSBitterblue Smith {
769c888183bSBitterblue Smith u8 val8;
770c888183bSBitterblue Smith u16 val16;
771c888183bSBitterblue Smith
772c888183bSBitterblue Smith /* Enable BB and RF */
773c888183bSBitterblue Smith val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
774c888183bSBitterblue Smith val16 |= SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_DIO_RF;
775c888183bSBitterblue Smith rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
776c888183bSBitterblue Smith
777c888183bSBitterblue Smith /*
778c888183bSBitterblue Smith * Per vendor driver, run power sequence before init of RF
779c888183bSBitterblue Smith */
780c888183bSBitterblue Smith val8 = RF_ENABLE | RF_RSTB | RF_SDMRSTB;
781c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_RF_CTRL, val8);
782c888183bSBitterblue Smith
783c888183bSBitterblue Smith usleep_range(10, 20);
784c888183bSBitterblue Smith
785c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_IQADJ_G1, 0x780);
786c888183bSBitterblue Smith
787c888183bSBitterblue Smith val8 = SYS_FUNC_BB_GLB_RSTN | SYS_FUNC_BBRSTB | SYS_FUNC_USBA | SYS_FUNC_USBD;
788c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_SYS_FUNC, val8);
789c888183bSBitterblue Smith
790c888183bSBitterblue Smith rtl8xxxu_init_phy_regs(priv, rtl8188fu_phy_init_table);
791c888183bSBitterblue Smith rtl8xxxu_init_phy_regs(priv, rtl8188f_agc_table);
792c888183bSBitterblue Smith }
793c888183bSBitterblue Smith
rtl8188fu_init_phy_rf(struct rtl8xxxu_priv * priv)794c888183bSBitterblue Smith static int rtl8188fu_init_phy_rf(struct rtl8xxxu_priv *priv)
795c888183bSBitterblue Smith {
796c888183bSBitterblue Smith int ret;
797c888183bSBitterblue Smith
798c888183bSBitterblue Smith if (priv->chip_cut == 1)
799c888183bSBitterblue Smith ret = rtl8xxxu_init_phy_rf(priv, rtl8188fu_cut_b_radioa_init_table, RF_A);
800c888183bSBitterblue Smith else
801c888183bSBitterblue Smith ret = rtl8xxxu_init_phy_rf(priv, rtl8188fu_radioa_init_table, RF_A);
802c888183bSBitterblue Smith
803c888183bSBitterblue Smith return ret;
804c888183bSBitterblue Smith }
805c888183bSBitterblue Smith
rtl8188f_phy_lc_calibrate(struct rtl8xxxu_priv * priv)80670664495SBitterblue Smith void rtl8188f_phy_lc_calibrate(struct rtl8xxxu_priv *priv)
807c888183bSBitterblue Smith {
808c888183bSBitterblue Smith u32 val32;
809c888183bSBitterblue Smith u32 rf_amode, lstf;
810c888183bSBitterblue Smith int i;
811c888183bSBitterblue Smith
812c888183bSBitterblue Smith /* Check continuous TX and Packet TX */
813c888183bSBitterblue Smith lstf = rtl8xxxu_read32(priv, REG_OFDM1_LSTF);
814c888183bSBitterblue Smith
815c888183bSBitterblue Smith if (lstf & OFDM_LSTF_MASK) {
816c888183bSBitterblue Smith /* Disable all continuous TX */
817c888183bSBitterblue Smith val32 = lstf & ~OFDM_LSTF_MASK;
818c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM1_LSTF, val32);
819c888183bSBitterblue Smith } else {
820c888183bSBitterblue Smith /* Deal with Packet TX case */
821c888183bSBitterblue Smith /* block all queues */
822c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
823c888183bSBitterblue Smith }
824c888183bSBitterblue Smith
825c888183bSBitterblue Smith /* Read original RF mode Path A */
826c888183bSBitterblue Smith rf_amode = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG);
827c888183bSBitterblue Smith
828c888183bSBitterblue Smith /* Start LC calibration */
829c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, rf_amode | 0x08000);
830c888183bSBitterblue Smith
831c888183bSBitterblue Smith for (i = 0; i < 100; i++) {
832c888183bSBitterblue Smith if ((rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_MODE_AG) & 0x08000) == 0)
833c888183bSBitterblue Smith break;
834c888183bSBitterblue Smith msleep(10);
835c888183bSBitterblue Smith }
836c888183bSBitterblue Smith
837c888183bSBitterblue Smith if (i == 100)
838c888183bSBitterblue Smith dev_warn(&priv->udev->dev, "LC calibration timed out.\n");
839c888183bSBitterblue Smith
840c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_MODE_AG, rf_amode);
841c888183bSBitterblue Smith
842c888183bSBitterblue Smith /* Restore original parameters */
843c888183bSBitterblue Smith if (lstf & OFDM_LSTF_MASK)
844c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM1_LSTF, lstf);
845c888183bSBitterblue Smith else /* Deal with Packet TX case */
846c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00);
847c888183bSBitterblue Smith }
848c888183bSBitterblue Smith
rtl8188fu_iqk_path_a(struct rtl8xxxu_priv * priv,u32 * lok_result)849c888183bSBitterblue Smith static int rtl8188fu_iqk_path_a(struct rtl8xxxu_priv *priv, u32 *lok_result)
850c888183bSBitterblue Smith {
851c888183bSBitterblue Smith u32 reg_eac, reg_e94, reg_e9c, val32;
852c888183bSBitterblue Smith int result = 0;
853c888183bSBitterblue Smith
854c888183bSBitterblue Smith /*
855c888183bSBitterblue Smith * Leave IQK mode
856c888183bSBitterblue Smith */
857c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
858c888183bSBitterblue Smith val32 &= 0x000000ff;
859c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
860c888183bSBitterblue Smith
861c888183bSBitterblue Smith /*
862c888183bSBitterblue Smith * Enable path A PA in TX IQK mode
863c888183bSBitterblue Smith */
864c888183bSBitterblue Smith val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT);
865c888183bSBitterblue Smith val32 |= 0x80000;
866c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32);
867c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x20000);
868c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f);
869c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0x07ff7);
870c888183bSBitterblue Smith
871c888183bSBitterblue Smith /* PA,PAD gain adjust */
872103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980);
873103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x5102a);
874c888183bSBitterblue Smith
875c888183bSBitterblue Smith /* enter IQK mode */
876c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
877c888183bSBitterblue Smith val32 &= 0x000000ff;
878c888183bSBitterblue Smith val32 |= 0x80800000;
879c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
880c888183bSBitterblue Smith
881c888183bSBitterblue Smith /* path-A IQK setting */
882c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x18008c1c);
883c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x38008c1c);
884c888183bSBitterblue Smith
885c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x821403ff);
886c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160000);
887c888183bSBitterblue Smith
888c888183bSBitterblue Smith /* LO calibration setting */
889c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911);
890c888183bSBitterblue Smith
891c888183bSBitterblue Smith /* One shot, path A LOK & IQK */
892c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000);
893c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000);
894c888183bSBitterblue Smith
895c888183bSBitterblue Smith mdelay(25);
896c888183bSBitterblue Smith
897c888183bSBitterblue Smith /*
898c888183bSBitterblue Smith * Leave IQK mode
899c888183bSBitterblue Smith */
900c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
901c888183bSBitterblue Smith val32 &= 0x000000ff;
902c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
903c888183bSBitterblue Smith
904103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180);
905c888183bSBitterblue Smith
906c888183bSBitterblue Smith /* save LOK result */
907c888183bSBitterblue Smith *lok_result = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC);
908c888183bSBitterblue Smith
909c888183bSBitterblue Smith /* Check failed */
910c888183bSBitterblue Smith reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
911c888183bSBitterblue Smith reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A);
912c888183bSBitterblue Smith reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A);
913c888183bSBitterblue Smith
914c888183bSBitterblue Smith if (!(reg_eac & BIT(28)) &&
915c888183bSBitterblue Smith ((reg_e94 & 0x03ff0000) != 0x01420000) &&
916c888183bSBitterblue Smith ((reg_e9c & 0x03ff0000) != 0x00420000))
917c888183bSBitterblue Smith result |= 0x01;
918c888183bSBitterblue Smith
919c888183bSBitterblue Smith return result;
920c888183bSBitterblue Smith }
921c888183bSBitterblue Smith
rtl8188fu_rx_iqk_path_a(struct rtl8xxxu_priv * priv,u32 lok_result)922c888183bSBitterblue Smith static int rtl8188fu_rx_iqk_path_a(struct rtl8xxxu_priv *priv, u32 lok_result)
923c888183bSBitterblue Smith {
924c888183bSBitterblue Smith u32 reg_ea4, reg_eac, reg_e94, reg_e9c, val32;
925c888183bSBitterblue Smith int result = 0;
926c888183bSBitterblue Smith
927c888183bSBitterblue Smith /*
928c888183bSBitterblue Smith * Leave IQK mode
929c888183bSBitterblue Smith */
930c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
931c888183bSBitterblue Smith val32 &= 0x000000ff;
932c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
933c888183bSBitterblue Smith
934c888183bSBitterblue Smith /*
935c888183bSBitterblue Smith * Enable path A PA in TX IQK mode
936c888183bSBitterblue Smith */
937c888183bSBitterblue Smith val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT);
938c888183bSBitterblue Smith val32 |= 0x80000;
939c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32);
940c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000);
941c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f);
942c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf1173);
943c888183bSBitterblue Smith
944c888183bSBitterblue Smith /* PA,PAD gain adjust */
945103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980);
946103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x5102a);
947c888183bSBitterblue Smith
948c888183bSBitterblue Smith /*
949c888183bSBitterblue Smith * Enter IQK mode
950c888183bSBitterblue Smith */
951c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
952c888183bSBitterblue Smith val32 &= 0x000000ff;
953c888183bSBitterblue Smith val32 |= 0x80800000;
954c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
955c888183bSBitterblue Smith
956c888183bSBitterblue Smith /*
957c888183bSBitterblue Smith * Tx IQK setting
958c888183bSBitterblue Smith */
959c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00);
960c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
961c888183bSBitterblue Smith
962c888183bSBitterblue Smith /* path-A IQK setting */
963c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x10008c1c);
964c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x30008c1c);
965c888183bSBitterblue Smith
966c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160fff);
967c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x28160000);
968c888183bSBitterblue Smith
969c888183bSBitterblue Smith /* LO calibration setting */
970c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x00462911);
971c888183bSBitterblue Smith
972c888183bSBitterblue Smith /* One shot, path A LOK & IQK */
973c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000);
974c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000);
975c888183bSBitterblue Smith
976c888183bSBitterblue Smith mdelay(25);
977c888183bSBitterblue Smith
978c888183bSBitterblue Smith /*
979c888183bSBitterblue Smith * Leave IQK mode
980c888183bSBitterblue Smith */
981c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
982c888183bSBitterblue Smith val32 &= 0x000000ff;
983c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
984c888183bSBitterblue Smith
985103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180);
986c888183bSBitterblue Smith
987c888183bSBitterblue Smith /* Check failed */
988c888183bSBitterblue Smith reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
989c888183bSBitterblue Smith reg_e94 = rtl8xxxu_read32(priv, REG_TX_POWER_BEFORE_IQK_A);
990c888183bSBitterblue Smith reg_e9c = rtl8xxxu_read32(priv, REG_TX_POWER_AFTER_IQK_A);
991c888183bSBitterblue Smith
992c888183bSBitterblue Smith if (!(reg_eac & BIT(28)) &&
993c888183bSBitterblue Smith ((reg_e94 & 0x03ff0000) != 0x01420000) &&
994c888183bSBitterblue Smith ((reg_e9c & 0x03ff0000) != 0x00420000))
995c888183bSBitterblue Smith result |= 0x01;
996c888183bSBitterblue Smith else /* If TX not OK, ignore RX */
997c888183bSBitterblue Smith goto out;
998c888183bSBitterblue Smith
999c888183bSBitterblue Smith val32 = 0x80007c00 | (reg_e94 & 0x3ff0000) |
1000c888183bSBitterblue Smith ((reg_e9c & 0x3ff0000) >> 16);
1001c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK, val32);
1002c888183bSBitterblue Smith
1003c888183bSBitterblue Smith /*
1004c888183bSBitterblue Smith * Modify RX IQK mode table
1005c888183bSBitterblue Smith */
1006c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
1007c888183bSBitterblue Smith val32 &= 0x000000ff;
1008c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
1009c888183bSBitterblue Smith
1010c888183bSBitterblue Smith val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_WE_LUT);
1011c888183bSBitterblue Smith val32 |= 0x80000;
1012c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_WE_LUT, val32);
1013c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_RCK_OS, 0x30000);
1014c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G1, 0x0000f);
1015c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXPA_G2, 0xf7ff2);
1016c888183bSBitterblue Smith
1017c888183bSBitterblue Smith /*
1018c888183bSBitterblue Smith * PA, PAD setting
1019c888183bSBitterblue Smith */
1020103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x980);
1021103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_PAD_TXG, 0x51000);
1022c888183bSBitterblue Smith
1023c888183bSBitterblue Smith /*
1024c888183bSBitterblue Smith * Enter IQK mode
1025c888183bSBitterblue Smith */
1026c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
1027c888183bSBitterblue Smith val32 &= 0x000000ff;
1028c888183bSBitterblue Smith val32 |= 0x80800000;
1029c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
1030c888183bSBitterblue Smith
1031c888183bSBitterblue Smith /*
1032c888183bSBitterblue Smith * RX IQK setting
1033c888183bSBitterblue Smith */
1034c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
1035c888183bSBitterblue Smith
1036c888183bSBitterblue Smith /* path-A IQK setting */
1037c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x30008c1c);
1038c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x10008c1c);
1039c888183bSBitterblue Smith
1040c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK_PI_A, 0x82160000);
1041c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK_PI_A, 0x281613ff);
1042c888183bSBitterblue Smith
1043c888183bSBitterblue Smith /* LO calibration setting */
1044c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_RSP, 0x0046a911);
1045c888183bSBitterblue Smith
1046c888183bSBitterblue Smith /* One shot, path A LOK & IQK */
1047c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf9000000);
1048c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_IQK_AGC_PTS, 0xf8000000);
1049c888183bSBitterblue Smith
1050c888183bSBitterblue Smith mdelay(25);
1051c888183bSBitterblue Smith
1052c888183bSBitterblue Smith /*
1053c888183bSBitterblue Smith * Leave IQK mode
1054c888183bSBitterblue Smith */
1055c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
1056c888183bSBitterblue Smith val32 &= 0x000000ff;
1057c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
1058c888183bSBitterblue Smith
1059103d6e9dSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_GAIN_CCA, 0x180);
1060c888183bSBitterblue Smith
1061c888183bSBitterblue Smith /* reload LOK value */
1062c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_TXM_IDAC, lok_result);
1063c888183bSBitterblue Smith
1064c888183bSBitterblue Smith /* Check failed */
1065c888183bSBitterblue Smith reg_eac = rtl8xxxu_read32(priv, REG_RX_POWER_AFTER_IQK_A_2);
1066c888183bSBitterblue Smith reg_ea4 = rtl8xxxu_read32(priv, REG_RX_POWER_BEFORE_IQK_A_2);
1067c888183bSBitterblue Smith
1068c888183bSBitterblue Smith if (!(reg_eac & BIT(27)) &&
1069c888183bSBitterblue Smith ((reg_ea4 & 0x03ff0000) != 0x01320000) &&
1070c888183bSBitterblue Smith ((reg_eac & 0x03ff0000) != 0x00360000))
1071c888183bSBitterblue Smith result |= 0x02;
1072c888183bSBitterblue Smith
1073c888183bSBitterblue Smith out:
1074c888183bSBitterblue Smith return result;
1075c888183bSBitterblue Smith }
1076c888183bSBitterblue Smith
rtl8188fu_phy_iqcalibrate(struct rtl8xxxu_priv * priv,int result[][8],int t)1077c888183bSBitterblue Smith static void rtl8188fu_phy_iqcalibrate(struct rtl8xxxu_priv *priv,
1078c888183bSBitterblue Smith int result[][8], int t)
1079c888183bSBitterblue Smith {
1080c888183bSBitterblue Smith struct device *dev = &priv->udev->dev;
1081c888183bSBitterblue Smith u32 i, val32, rx_initial_gain, lok_result;
1082c888183bSBitterblue Smith u32 path_sel_bb, path_sel_rf;
1083c888183bSBitterblue Smith int path_a_ok;
1084c888183bSBitterblue Smith int retry = 2;
1085c888183bSBitterblue Smith static const u32 adda_regs[RTL8XXXU_ADDA_REGS] = {
1086c888183bSBitterblue Smith REG_FPGA0_XCD_SWITCH_CTRL, REG_BLUETOOTH,
1087c888183bSBitterblue Smith REG_RX_WAIT_CCA, REG_TX_CCK_RFON,
1088c888183bSBitterblue Smith REG_TX_CCK_BBON, REG_TX_OFDM_RFON,
1089c888183bSBitterblue Smith REG_TX_OFDM_BBON, REG_TX_TO_RX,
1090c888183bSBitterblue Smith REG_TX_TO_TX, REG_RX_CCK,
1091c888183bSBitterblue Smith REG_RX_OFDM, REG_RX_WAIT_RIFS,
1092c888183bSBitterblue Smith REG_RX_TO_RX, REG_STANDBY,
1093c888183bSBitterblue Smith REG_SLEEP, REG_PMPD_ANAEN
1094c888183bSBitterblue Smith };
1095c888183bSBitterblue Smith static const u32 iqk_mac_regs[RTL8XXXU_MAC_REGS] = {
1096c888183bSBitterblue Smith REG_TXPAUSE, REG_BEACON_CTRL,
1097c888183bSBitterblue Smith REG_BEACON_CTRL_1, REG_GPIO_MUXCFG
1098c888183bSBitterblue Smith };
1099c888183bSBitterblue Smith static const u32 iqk_bb_regs[RTL8XXXU_BB_REGS] = {
1100c888183bSBitterblue Smith REG_OFDM0_TRX_PATH_ENABLE, REG_OFDM0_TR_MUX_PAR,
1101c888183bSBitterblue Smith REG_FPGA0_XCD_RF_SW_CTRL, REG_CONFIG_ANT_A, REG_CONFIG_ANT_B,
1102c888183bSBitterblue Smith REG_FPGA0_XAB_RF_SW_CTRL, REG_FPGA0_XA_RF_INT_OE,
1103c888183bSBitterblue Smith REG_FPGA0_XB_RF_INT_OE, REG_FPGA0_RF_MODE
1104c888183bSBitterblue Smith };
1105c888183bSBitterblue Smith
1106c888183bSBitterblue Smith /*
1107c888183bSBitterblue Smith * Note: IQ calibration must be performed after loading
1108c888183bSBitterblue Smith * PHY_REG.txt , and radio_a, radio_b.txt
1109c888183bSBitterblue Smith */
1110c888183bSBitterblue Smith
1111c888183bSBitterblue Smith rx_initial_gain = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1);
1112c888183bSBitterblue Smith
1113c888183bSBitterblue Smith if (t == 0) {
1114c888183bSBitterblue Smith /* Save ADDA parameters, turn Path A ADDA on */
1115c888183bSBitterblue Smith rtl8xxxu_save_regs(priv, adda_regs, priv->adda_backup,
1116c888183bSBitterblue Smith RTL8XXXU_ADDA_REGS);
1117c888183bSBitterblue Smith rtl8xxxu_save_mac_regs(priv, iqk_mac_regs, priv->mac_backup);
1118c888183bSBitterblue Smith rtl8xxxu_save_regs(priv, iqk_bb_regs,
1119c888183bSBitterblue Smith priv->bb_backup, RTL8XXXU_BB_REGS);
1120c888183bSBitterblue Smith }
1121c888183bSBitterblue Smith
1122c888183bSBitterblue Smith rtl8xxxu_path_adda_on(priv, adda_regs, true);
1123c888183bSBitterblue Smith
1124c888183bSBitterblue Smith if (t == 0) {
1125c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_XA_HSSI_PARM1);
11269e32b4a7SBitterblue Smith priv->pi_enabled = u32_get_bits(val32, FPGA0_HSSI_PARM1_PI);
1127c888183bSBitterblue Smith }
1128c888183bSBitterblue Smith
1129c888183bSBitterblue Smith /* save RF path */
1130c888183bSBitterblue Smith path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH);
1131c888183bSBitterblue Smith path_sel_rf = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_S0S1);
1132c888183bSBitterblue Smith
1133c888183bSBitterblue Smith /* BB setting */
1134c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, 0x03a05600);
1135c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_TR_MUX_PAR, 0x000800e4);
1136c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_SW_CTRL, 0x25204000);
1137c888183bSBitterblue Smith
1138c888183bSBitterblue Smith /* MAC settings */
1139c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_TX_PTCL_CTRL);
1140c888183bSBitterblue Smith val32 |= 0x00ff0000;
1141c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_PTCL_CTRL, val32);
1142c888183bSBitterblue Smith
1143c888183bSBitterblue Smith /* IQ calibration setting */
1144c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
1145c888183bSBitterblue Smith val32 &= 0xff;
1146c888183bSBitterblue Smith val32 |= 0x80800000;
1147c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
1148c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK, 0x01007c00);
1149c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK, 0x01004800);
1150c888183bSBitterblue Smith
1151c888183bSBitterblue Smith for (i = 0; i < retry; i++) {
1152c888183bSBitterblue Smith path_a_ok = rtl8188fu_iqk_path_a(priv, &lok_result);
1153c888183bSBitterblue Smith if (path_a_ok == 0x01) {
1154c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
1155c888183bSBitterblue Smith val32 &= 0xff;
1156c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
1157c888183bSBitterblue Smith
1158c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv,
1159c888183bSBitterblue Smith REG_TX_POWER_BEFORE_IQK_A);
1160c888183bSBitterblue Smith result[t][0] = (val32 >> 16) & 0x3ff;
1161c888183bSBitterblue Smith
1162c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv,
1163c888183bSBitterblue Smith REG_TX_POWER_AFTER_IQK_A);
1164c888183bSBitterblue Smith result[t][1] = (val32 >> 16) & 0x3ff;
1165c888183bSBitterblue Smith break;
1166c888183bSBitterblue Smith }
1167c888183bSBitterblue Smith }
1168c888183bSBitterblue Smith
1169c888183bSBitterblue Smith for (i = 0; i < retry; i++) {
1170c888183bSBitterblue Smith path_a_ok = rtl8188fu_rx_iqk_path_a(priv, lok_result);
1171c888183bSBitterblue Smith if (path_a_ok == 0x03) {
1172c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv,
1173c888183bSBitterblue Smith REG_RX_POWER_BEFORE_IQK_A_2);
1174c888183bSBitterblue Smith result[t][2] = (val32 >> 16) & 0x3ff;
1175c888183bSBitterblue Smith
1176c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv,
1177c888183bSBitterblue Smith REG_RX_POWER_AFTER_IQK_A_2);
1178c888183bSBitterblue Smith result[t][3] = (val32 >> 16) & 0x3ff;
1179c888183bSBitterblue Smith break;
1180c888183bSBitterblue Smith }
1181c888183bSBitterblue Smith }
1182c888183bSBitterblue Smith
1183c888183bSBitterblue Smith if (!path_a_ok)
1184c888183bSBitterblue Smith dev_dbg(dev, "%s: Path A IQK failed!\n", __func__);
1185c888183bSBitterblue Smith
1186c888183bSBitterblue Smith /* Back to BB mode, load original value */
1187c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_FPGA0_IQK);
1188c888183bSBitterblue Smith val32 &= 0xff;
1189c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_IQK, val32);
1190c888183bSBitterblue Smith
1191c888183bSBitterblue Smith if (t == 0)
1192c888183bSBitterblue Smith return;
1193c888183bSBitterblue Smith
1194c888183bSBitterblue Smith if (!priv->pi_enabled) {
1195c888183bSBitterblue Smith /*
1196c888183bSBitterblue Smith * Switch back BB to SI mode after finishing
1197c888183bSBitterblue Smith * IQ Calibration
1198c888183bSBitterblue Smith */
1199c888183bSBitterblue Smith val32 = 0x01000000;
1200c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_XA_HSSI_PARM1, val32);
1201c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_FPGA0_XB_HSSI_PARM1, val32);
1202c888183bSBitterblue Smith }
1203c888183bSBitterblue Smith
1204c888183bSBitterblue Smith /* Reload ADDA power saving parameters */
1205c888183bSBitterblue Smith rtl8xxxu_restore_regs(priv, adda_regs, priv->adda_backup,
1206c888183bSBitterblue Smith RTL8XXXU_ADDA_REGS);
1207c888183bSBitterblue Smith
1208c888183bSBitterblue Smith /* Reload MAC parameters */
1209c888183bSBitterblue Smith rtl8xxxu_restore_mac_regs(priv, iqk_mac_regs, priv->mac_backup);
1210c888183bSBitterblue Smith
1211c888183bSBitterblue Smith /* Reload BB parameters */
1212c888183bSBitterblue Smith rtl8xxxu_restore_regs(priv, iqk_bb_regs,
1213c888183bSBitterblue Smith priv->bb_backup, RTL8XXXU_BB_REGS);
1214c888183bSBitterblue Smith
1215c888183bSBitterblue Smith /* Reload RF path */
1216c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb);
1217c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_S0S1, path_sel_rf);
1218c888183bSBitterblue Smith
1219c888183bSBitterblue Smith /* Restore RX initial gain */
1220c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1);
1221c888183bSBitterblue Smith val32 &= 0xffffff00;
1222c888183bSBitterblue Smith val32 |= 0x50;
1223c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32);
1224c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_XA_AGC_CORE1);
1225c888183bSBitterblue Smith val32 &= 0xffffff00;
1226c888183bSBitterblue Smith val32 |= rx_initial_gain & 0xff;
1227c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, val32);
1228c888183bSBitterblue Smith
1229c888183bSBitterblue Smith /* Load 0xe30 IQC default value */
1230c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TX_IQK_TONE_A, 0x01008c00);
1231c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_RX_IQK_TONE_A, 0x01008c00);
1232c888183bSBitterblue Smith }
1233c888183bSBitterblue Smith
rtl8188fu_phy_iq_calibrate(struct rtl8xxxu_priv * priv)1234c888183bSBitterblue Smith static void rtl8188fu_phy_iq_calibrate(struct rtl8xxxu_priv *priv)
1235c888183bSBitterblue Smith {
1236c888183bSBitterblue Smith struct device *dev = &priv->udev->dev;
1237c888183bSBitterblue Smith int result[4][8]; /* last is final result */
1238c888183bSBitterblue Smith int i, candidate;
1239c888183bSBitterblue Smith bool path_a_ok;
1240c888183bSBitterblue Smith u32 reg_e94, reg_e9c, reg_ea4, reg_eac;
1241c888183bSBitterblue Smith u32 reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1242c888183bSBitterblue Smith s32 reg_tmp = 0;
1243c888183bSBitterblue Smith bool simu;
1244c888183bSBitterblue Smith u32 path_sel_bb, path_sel_rf;
1245c888183bSBitterblue Smith
1246c888183bSBitterblue Smith /* Save RF path */
1247c888183bSBitterblue Smith path_sel_bb = rtl8xxxu_read32(priv, REG_S0S1_PATH_SWITCH);
1248c888183bSBitterblue Smith path_sel_rf = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_S0S1);
1249c888183bSBitterblue Smith
1250c888183bSBitterblue Smith memset(result, 0, sizeof(result));
1251c888183bSBitterblue Smith candidate = -1;
1252c888183bSBitterblue Smith
1253c888183bSBitterblue Smith path_a_ok = false;
1254c888183bSBitterblue Smith
1255c888183bSBitterblue Smith for (i = 0; i < 3; i++) {
1256c888183bSBitterblue Smith rtl8188fu_phy_iqcalibrate(priv, result, i);
1257c888183bSBitterblue Smith
1258c888183bSBitterblue Smith if (i == 1) {
1259c888183bSBitterblue Smith simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 1);
1260c888183bSBitterblue Smith if (simu) {
1261c888183bSBitterblue Smith candidate = 0;
1262c888183bSBitterblue Smith break;
1263c888183bSBitterblue Smith }
1264c888183bSBitterblue Smith }
1265c888183bSBitterblue Smith
1266c888183bSBitterblue Smith if (i == 2) {
1267c888183bSBitterblue Smith simu = rtl8xxxu_gen2_simularity_compare(priv, result, 0, 2);
1268c888183bSBitterblue Smith if (simu) {
1269c888183bSBitterblue Smith candidate = 0;
1270c888183bSBitterblue Smith break;
1271c888183bSBitterblue Smith }
1272c888183bSBitterblue Smith
1273c888183bSBitterblue Smith simu = rtl8xxxu_gen2_simularity_compare(priv, result, 1, 2);
1274c888183bSBitterblue Smith if (simu) {
1275c888183bSBitterblue Smith candidate = 1;
1276c888183bSBitterblue Smith } else {
1277c888183bSBitterblue Smith for (i = 0; i < 8; i++)
1278c888183bSBitterblue Smith reg_tmp += result[3][i];
1279c888183bSBitterblue Smith
1280c888183bSBitterblue Smith if (reg_tmp)
1281c888183bSBitterblue Smith candidate = 3;
1282c888183bSBitterblue Smith else
1283c888183bSBitterblue Smith candidate = -1;
1284c888183bSBitterblue Smith }
1285c888183bSBitterblue Smith }
1286c888183bSBitterblue Smith }
1287c888183bSBitterblue Smith
1288c888183bSBitterblue Smith for (i = 0; i < 4; i++) {
1289c888183bSBitterblue Smith reg_e94 = result[i][0];
1290c888183bSBitterblue Smith reg_e9c = result[i][1];
1291c888183bSBitterblue Smith reg_ea4 = result[i][2];
1292c888183bSBitterblue Smith reg_eac = result[i][3];
1293c888183bSBitterblue Smith reg_eb4 = result[i][4];
1294c888183bSBitterblue Smith reg_ebc = result[i][5];
1295c888183bSBitterblue Smith reg_ec4 = result[i][6];
1296c888183bSBitterblue Smith reg_ecc = result[i][7];
1297c888183bSBitterblue Smith }
1298c888183bSBitterblue Smith
1299c888183bSBitterblue Smith if (candidate >= 0) {
1300c888183bSBitterblue Smith reg_e94 = result[candidate][0];
1301c888183bSBitterblue Smith priv->rege94 = reg_e94;
1302c888183bSBitterblue Smith reg_e9c = result[candidate][1];
1303c888183bSBitterblue Smith priv->rege9c = reg_e9c;
1304c888183bSBitterblue Smith reg_ea4 = result[candidate][2];
1305c888183bSBitterblue Smith reg_eac = result[candidate][3];
1306c888183bSBitterblue Smith reg_eb4 = result[candidate][4];
1307c888183bSBitterblue Smith priv->regeb4 = reg_eb4;
1308c888183bSBitterblue Smith reg_ebc = result[candidate][5];
1309c888183bSBitterblue Smith priv->regebc = reg_ebc;
1310c888183bSBitterblue Smith reg_ec4 = result[candidate][6];
1311c888183bSBitterblue Smith reg_ecc = result[candidate][7];
1312c888183bSBitterblue Smith dev_dbg(dev, "%s: candidate is %x\n", __func__, candidate);
1313c888183bSBitterblue Smith dev_dbg(dev,
1314c888183bSBitterblue Smith "%s: e94 =%x e9c=%x ea4=%x eac=%x eb4=%x ebc=%x ec4=%x ecc=%x\n",
1315c888183bSBitterblue Smith __func__, reg_e94, reg_e9c,
1316c888183bSBitterblue Smith reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc);
1317c888183bSBitterblue Smith path_a_ok = true;
1318c888183bSBitterblue Smith } else {
1319c888183bSBitterblue Smith reg_e94 = reg_eb4 = priv->rege94 = priv->regeb4 = 0x100;
1320c888183bSBitterblue Smith reg_e9c = reg_ebc = priv->rege9c = priv->regebc = 0x0;
1321c888183bSBitterblue Smith }
1322c888183bSBitterblue Smith
1323c888183bSBitterblue Smith if (reg_e94 && candidate >= 0)
1324c888183bSBitterblue Smith rtl8xxxu_fill_iqk_matrix_a(priv, path_a_ok, result,
1325c888183bSBitterblue Smith candidate, (reg_ea4 == 0));
1326c888183bSBitterblue Smith
1327c888183bSBitterblue Smith rtl8xxxu_save_regs(priv, rtl8xxxu_iqk_phy_iq_bb_reg,
1328c888183bSBitterblue Smith priv->bb_recovery_backup, RTL8XXXU_BB_REGS);
1329c888183bSBitterblue Smith
1330c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, path_sel_bb);
1331c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_S0S1, path_sel_rf);
1332c888183bSBitterblue Smith }
1333c888183bSBitterblue Smith
rtl8188f_disabled_to_emu(struct rtl8xxxu_priv * priv)1334c888183bSBitterblue Smith static void rtl8188f_disabled_to_emu(struct rtl8xxxu_priv *priv)
1335c888183bSBitterblue Smith {
1336c888183bSBitterblue Smith u16 val8;
1337c888183bSBitterblue Smith
1338c888183bSBitterblue Smith /* 0x04[12:11] = 2b'01enable WL suspend */
1339c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
1340c888183bSBitterblue Smith val8 &= ~((APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND) >> 8);
1341c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
1342c888183bSBitterblue Smith
1343c888183bSBitterblue Smith /* 0xC4[4] <= 1, turn off USB APHY LDO under suspend mode */
1344c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, 0xc4);
1345c888183bSBitterblue Smith val8 &= ~BIT(4);
1346c888183bSBitterblue Smith rtl8xxxu_write8(priv, 0xc4, val8);
1347c888183bSBitterblue Smith }
1348c888183bSBitterblue Smith
rtl8188f_emu_to_active(struct rtl8xxxu_priv * priv)1349c888183bSBitterblue Smith static int rtl8188f_emu_to_active(struct rtl8xxxu_priv *priv)
1350c888183bSBitterblue Smith {
1351c888183bSBitterblue Smith u8 val8;
1352c888183bSBitterblue Smith u32 val32;
1353c888183bSBitterblue Smith int count, ret = 0;
1354c888183bSBitterblue Smith
1355c888183bSBitterblue Smith /* Disable SW LPS */
1356c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
1357c888183bSBitterblue Smith val8 &= ~(APS_FSMCO_SW_LPS >> 8);
1358c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
1359c888183bSBitterblue Smith
1360c888183bSBitterblue Smith /* wait till 0x04[17] = 1 power ready */
1361c888183bSBitterblue Smith for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
1362c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
1363c888183bSBitterblue Smith if (val32 & BIT(17))
1364c888183bSBitterblue Smith break;
1365c888183bSBitterblue Smith
1366c888183bSBitterblue Smith udelay(10);
1367c888183bSBitterblue Smith }
1368c888183bSBitterblue Smith
1369c888183bSBitterblue Smith if (!count) {
1370c888183bSBitterblue Smith ret = -EBUSY;
1371c888183bSBitterblue Smith goto exit;
1372c888183bSBitterblue Smith }
1373c888183bSBitterblue Smith
1374c888183bSBitterblue Smith /* Disable HWPDN */
1375c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
1376c888183bSBitterblue Smith val8 &= ~(APS_FSMCO_HW_POWERDOWN >> 8);
1377c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
1378c888183bSBitterblue Smith
1379c888183bSBitterblue Smith /* Disable WL suspend */
1380c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
1381c888183bSBitterblue Smith val8 &= ~(APS_FSMCO_HW_SUSPEND >> 8);
1382c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
1383c888183bSBitterblue Smith
1384c888183bSBitterblue Smith /* set, then poll until 0 */
1385c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
1386c888183bSBitterblue Smith val8 |= APS_FSMCO_MAC_ENABLE >> 8;
1387c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
1388c888183bSBitterblue Smith
1389c888183bSBitterblue Smith for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
1390c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
1391c888183bSBitterblue Smith if ((val32 & APS_FSMCO_MAC_ENABLE) == 0) {
1392c888183bSBitterblue Smith ret = 0;
1393c888183bSBitterblue Smith break;
1394c888183bSBitterblue Smith }
1395c888183bSBitterblue Smith udelay(10);
1396c888183bSBitterblue Smith }
1397c888183bSBitterblue Smith
1398c888183bSBitterblue Smith if (!count) {
1399c888183bSBitterblue Smith ret = -EBUSY;
1400c888183bSBitterblue Smith goto exit;
1401c888183bSBitterblue Smith }
1402c888183bSBitterblue Smith
1403c888183bSBitterblue Smith /* 0x27<=35 to reduce RF noise */
1404c888183bSBitterblue Smith val8 = rtl8xxxu_write8(priv, 0x27, 0x35);
1405c888183bSBitterblue Smith exit:
1406c888183bSBitterblue Smith return ret;
1407c888183bSBitterblue Smith }
1408c888183bSBitterblue Smith
rtl8188fu_active_to_emu(struct rtl8xxxu_priv * priv)1409c888183bSBitterblue Smith static int rtl8188fu_active_to_emu(struct rtl8xxxu_priv *priv)
1410c888183bSBitterblue Smith {
1411c888183bSBitterblue Smith u8 val8;
1412c888183bSBitterblue Smith u32 val32;
1413c888183bSBitterblue Smith int count, ret = 0;
1414c888183bSBitterblue Smith
1415c888183bSBitterblue Smith /* Turn off RF */
1416c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_RF_CTRL, 0);
1417c888183bSBitterblue Smith
1418c888183bSBitterblue Smith /* 0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */
1419c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, 0x4e);
1420c888183bSBitterblue Smith val8 &= ~BIT(7);
1421c888183bSBitterblue Smith rtl8xxxu_write8(priv, 0x4e, val8);
1422c888183bSBitterblue Smith
1423c888183bSBitterblue Smith /* 0x27 <= 34, xtal_qsel = 0 to xtal bring up */
1424c888183bSBitterblue Smith rtl8xxxu_write8(priv, 0x27, 0x34);
1425c888183bSBitterblue Smith
1426c888183bSBitterblue Smith /* 0x04[9] = 1 turn off MAC by HW state machine */
1427c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
1428c888183bSBitterblue Smith val8 |= APS_FSMCO_MAC_OFF >> 8;
1429c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
1430c888183bSBitterblue Smith
1431c888183bSBitterblue Smith for (count = RTL8XXXU_MAX_REG_POLL; count; count--) {
1432c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_APS_FSMCO);
1433c888183bSBitterblue Smith if ((val32 & APS_FSMCO_MAC_OFF) == 0) {
1434c888183bSBitterblue Smith ret = 0;
1435c888183bSBitterblue Smith break;
1436c888183bSBitterblue Smith }
1437c888183bSBitterblue Smith udelay(10);
1438c888183bSBitterblue Smith }
1439c888183bSBitterblue Smith
1440c888183bSBitterblue Smith if (!count) {
1441c888183bSBitterblue Smith ret = -EBUSY;
1442c888183bSBitterblue Smith goto exit;
1443c888183bSBitterblue Smith }
1444c888183bSBitterblue Smith
1445c888183bSBitterblue Smith exit:
1446c888183bSBitterblue Smith return ret;
1447c888183bSBitterblue Smith }
1448c888183bSBitterblue Smith
rtl8188fu_emu_to_disabled(struct rtl8xxxu_priv * priv)1449c888183bSBitterblue Smith static int rtl8188fu_emu_to_disabled(struct rtl8xxxu_priv *priv)
1450c888183bSBitterblue Smith {
1451c888183bSBitterblue Smith u8 val8;
1452c888183bSBitterblue Smith
1453c888183bSBitterblue Smith /* 0x04[12:11] = 2b'01 enable WL suspend */
1454c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1);
1455c888183bSBitterblue Smith val8 &= ~((APS_FSMCO_PCIE | APS_FSMCO_HW_SUSPEND) >> 8);
1456c888183bSBitterblue Smith val8 |= APS_FSMCO_HW_SUSPEND >> 8;
1457c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8);
1458c888183bSBitterblue Smith
1459c888183bSBitterblue Smith /* 0xC4[4] <= 1, turn off USB APHY LDO under suspend mode */
1460c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, 0xc4);
1461c888183bSBitterblue Smith val8 |= BIT(4);
1462c888183bSBitterblue Smith rtl8xxxu_write8(priv, 0xc4, val8);
1463c888183bSBitterblue Smith
1464c888183bSBitterblue Smith return 0;
1465c888183bSBitterblue Smith }
1466c888183bSBitterblue Smith
rtl8188fu_active_to_lps(struct rtl8xxxu_priv * priv)1467c888183bSBitterblue Smith static int rtl8188fu_active_to_lps(struct rtl8xxxu_priv *priv)
1468c888183bSBitterblue Smith {
1469c888183bSBitterblue Smith struct device *dev = &priv->udev->dev;
1470c888183bSBitterblue Smith u8 val8;
1471c888183bSBitterblue Smith u16 val16;
1472c888183bSBitterblue Smith u32 val32;
1473c888183bSBitterblue Smith int retry, retval;
1474c888183bSBitterblue Smith
1475c888183bSBitterblue Smith /* set RPWM IMR */
1476c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_FTIMR + 1);
1477c888183bSBitterblue Smith val8 |= IMR0_CPWM >> 8;
1478c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_FTIMR + 1, val8);
1479c888183bSBitterblue Smith
1480c888183bSBitterblue Smith /* Tx Pause */
1481c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff);
1482c888183bSBitterblue Smith
1483c888183bSBitterblue Smith retry = 100;
1484c888183bSBitterblue Smith retval = -EBUSY;
1485c888183bSBitterblue Smith
1486c888183bSBitterblue Smith /*
1487c888183bSBitterblue Smith * Poll 32 bit wide REG_SCH_TX_CMD for 0x00000000 to ensure no TX is pending.
1488c888183bSBitterblue Smith */
1489c888183bSBitterblue Smith do {
1490c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_SCH_TX_CMD);
1491c888183bSBitterblue Smith if (!val32) {
1492c888183bSBitterblue Smith retval = 0;
1493c888183bSBitterblue Smith break;
1494c888183bSBitterblue Smith }
1495c888183bSBitterblue Smith } while (retry--);
1496c888183bSBitterblue Smith
1497c888183bSBitterblue Smith if (!retry) {
1498c888183bSBitterblue Smith dev_warn(dev, "Failed to flush TX queue\n");
1499c888183bSBitterblue Smith retval = -EBUSY;
1500c888183bSBitterblue Smith goto out;
1501c888183bSBitterblue Smith }
1502c888183bSBitterblue Smith
1503c888183bSBitterblue Smith /* Disable CCK and OFDM, clock gated */
1504c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC);
1505c888183bSBitterblue Smith val8 &= ~SYS_FUNC_BBRSTB;
1506c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_SYS_FUNC, val8);
1507c888183bSBitterblue Smith
1508c888183bSBitterblue Smith udelay(2);
1509c888183bSBitterblue Smith
1510c888183bSBitterblue Smith /* Whole BB is reset */
1511c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_SYS_FUNC);
1512c888183bSBitterblue Smith val8 &= ~SYS_FUNC_BB_GLB_RSTN;
1513c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_SYS_FUNC, val8);
1514c888183bSBitterblue Smith
1515c888183bSBitterblue Smith /* Reset MAC TRX */
1516c888183bSBitterblue Smith val16 = rtl8xxxu_read16(priv, REG_CR);
1517c888183bSBitterblue Smith val16 |= 0x3f;
1518c888183bSBitterblue Smith val16 &= ~(CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE | CR_SECURITY_ENABLE);
1519c888183bSBitterblue Smith rtl8xxxu_write16(priv, REG_CR, val16);
1520c888183bSBitterblue Smith
1521c888183bSBitterblue Smith /* Respond TxOK to scheduler */
1522c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_DUAL_TSF_RST);
1523c888183bSBitterblue Smith val8 |= DUAL_TSF_TX_OK;
1524c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, val8);
1525c888183bSBitterblue Smith
1526c888183bSBitterblue Smith out:
1527c888183bSBitterblue Smith return retval;
1528c888183bSBitterblue Smith }
1529c888183bSBitterblue Smith
rtl8188fu_power_on(struct rtl8xxxu_priv * priv)1530c888183bSBitterblue Smith static int rtl8188fu_power_on(struct rtl8xxxu_priv *priv)
1531c888183bSBitterblue Smith {
1532c888183bSBitterblue Smith u16 val16;
1533c888183bSBitterblue Smith int ret;
1534c888183bSBitterblue Smith
1535c888183bSBitterblue Smith rtl8188f_disabled_to_emu(priv);
1536c888183bSBitterblue Smith
1537c888183bSBitterblue Smith ret = rtl8188f_emu_to_active(priv);
1538c888183bSBitterblue Smith if (ret)
1539c888183bSBitterblue Smith goto exit;
1540c888183bSBitterblue Smith
1541c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_CR, 0);
1542c888183bSBitterblue Smith
1543c888183bSBitterblue Smith val16 = rtl8xxxu_read16(priv, REG_CR);
1544c888183bSBitterblue Smith
1545c888183bSBitterblue Smith val16 |= (CR_HCI_TXDMA_ENABLE | CR_HCI_RXDMA_ENABLE |
1546c888183bSBitterblue Smith CR_TXDMA_ENABLE | CR_RXDMA_ENABLE |
1547c888183bSBitterblue Smith CR_PROTOCOL_ENABLE | CR_SCHEDULE_ENABLE |
1548c888183bSBitterblue Smith CR_SECURITY_ENABLE | CR_CALTIMER_ENABLE);
1549c888183bSBitterblue Smith rtl8xxxu_write16(priv, REG_CR, val16);
1550c888183bSBitterblue Smith
1551c888183bSBitterblue Smith exit:
1552c888183bSBitterblue Smith return ret;
1553c888183bSBitterblue Smith }
1554c888183bSBitterblue Smith
rtl8188fu_power_off(struct rtl8xxxu_priv * priv)1555c888183bSBitterblue Smith static void rtl8188fu_power_off(struct rtl8xxxu_priv *priv)
1556c888183bSBitterblue Smith {
1557c888183bSBitterblue Smith u8 val8;
1558c888183bSBitterblue Smith u16 val16;
1559c888183bSBitterblue Smith
1560c888183bSBitterblue Smith rtl8xxxu_flush_fifo(priv);
1561c888183bSBitterblue Smith
1562c888183bSBitterblue Smith val16 = rtl8xxxu_read16(priv, REG_GPIO_MUXCFG);
1563c888183bSBitterblue Smith val16 &= ~BIT(12);
1564c888183bSBitterblue Smith rtl8xxxu_write16(priv, REG_GPIO_MUXCFG, val16);
1565c888183bSBitterblue Smith
1566c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_HISR0, 0xFFFFFFFF);
1567c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_HISR1, 0xFFFFFFFF);
1568c888183bSBitterblue Smith
1569c888183bSBitterblue Smith /* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
1570c888183bSBitterblue Smith val8 = rtl8xxxu_read8(priv, REG_TX_REPORT_CTRL);
1571c888183bSBitterblue Smith val8 &= ~TX_REPORT_CTRL_TIMER_ENABLE;
1572c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_TX_REPORT_CTRL, val8);
1573c888183bSBitterblue Smith
1574c888183bSBitterblue Smith /* Turn off RF */
1575c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00);
1576c888183bSBitterblue Smith
1577c888183bSBitterblue Smith /* Reset Firmware if running in RAM */
1578c888183bSBitterblue Smith if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL)
1579c888183bSBitterblue Smith rtl8xxxu_firmware_self_reset(priv);
1580c888183bSBitterblue Smith
1581c888183bSBitterblue Smith rtl8188fu_active_to_lps(priv);
1582c888183bSBitterblue Smith
1583c888183bSBitterblue Smith /* Reset MCU */
1584c888183bSBitterblue Smith val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
1585c888183bSBitterblue Smith val16 &= ~SYS_FUNC_CPU_ENABLE;
1586c888183bSBitterblue Smith rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
1587c888183bSBitterblue Smith
1588c888183bSBitterblue Smith /* Reset MCU ready status */
1589c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
1590c888183bSBitterblue Smith
1591c888183bSBitterblue Smith rtl8188fu_active_to_emu(priv);
1592c888183bSBitterblue Smith rtl8188fu_emu_to_disabled(priv);
1593c888183bSBitterblue Smith }
1594c888183bSBitterblue Smith
1595c888183bSBitterblue Smith #define PPG_BB_GAIN_2G_TXA_OFFSET_8188F 0xee
1596c888183bSBitterblue Smith #define PPG_BB_GAIN_2G_TX_OFFSET_MASK 0x0f
1597c888183bSBitterblue Smith
rtl8188f_enable_rf(struct rtl8xxxu_priv * priv)1598c888183bSBitterblue Smith static void rtl8188f_enable_rf(struct rtl8xxxu_priv *priv)
1599c888183bSBitterblue Smith {
1600c888183bSBitterblue Smith u32 val32;
1601c888183bSBitterblue Smith u8 pg_pwrtrim = 0xff, val8;
1602c888183bSBitterblue Smith s8 bb_gain;
1603c888183bSBitterblue Smith
1604c888183bSBitterblue Smith /* Somehow this is not found in the efuse we read earlier. */
1605c888183bSBitterblue Smith rtl8xxxu_read_efuse8(priv, PPG_BB_GAIN_2G_TXA_OFFSET_8188F, &pg_pwrtrim);
1606c888183bSBitterblue Smith
1607c888183bSBitterblue Smith if (pg_pwrtrim != 0xff) {
1608c888183bSBitterblue Smith bb_gain = pg_pwrtrim & PPG_BB_GAIN_2G_TX_OFFSET_MASK;
1609c888183bSBitterblue Smith
1610c888183bSBitterblue Smith if (bb_gain == PPG_BB_GAIN_2G_TX_OFFSET_MASK)
1611c888183bSBitterblue Smith bb_gain = 0;
1612c888183bSBitterblue Smith else if (bb_gain & 1)
1613c888183bSBitterblue Smith bb_gain = bb_gain >> 1;
1614c888183bSBitterblue Smith else
1615c888183bSBitterblue Smith bb_gain = -(bb_gain >> 1);
1616c888183bSBitterblue Smith
1617c888183bSBitterblue Smith val8 = abs(bb_gain);
1618c888183bSBitterblue Smith if (bb_gain > 0)
1619c888183bSBitterblue Smith val8 |= BIT(5);
1620c888183bSBitterblue Smith
1621c888183bSBitterblue Smith val32 = rtl8xxxu_read_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_55);
1622c888183bSBitterblue Smith val32 &= ~0xfc000;
1623c888183bSBitterblue Smith val32 |= val8 << 14;
1624c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_UNKNOWN_55, val32);
1625c888183bSBitterblue Smith }
1626c888183bSBitterblue Smith
1627c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_RF_CTRL, RF_ENABLE | RF_RSTB | RF_SDMRSTB);
1628c888183bSBitterblue Smith
1629c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE);
1630c888183bSBitterblue Smith val32 &= ~(OFDM_RF_PATH_RX_MASK | OFDM_RF_PATH_TX_MASK);
1631c888183bSBitterblue Smith val32 |= OFDM_RF_PATH_RX_A | OFDM_RF_PATH_TX_A;
1632c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32);
1633c888183bSBitterblue Smith
1634c888183bSBitterblue Smith rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00);
1635c888183bSBitterblue Smith }
1636c888183bSBitterblue Smith
rtl8188f_disable_rf(struct rtl8xxxu_priv * priv)1637c888183bSBitterblue Smith static void rtl8188f_disable_rf(struct rtl8xxxu_priv *priv)
1638c888183bSBitterblue Smith {
1639c888183bSBitterblue Smith u32 val32;
1640c888183bSBitterblue Smith
1641c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_OFDM0_TRX_PATH_ENABLE);
1642c888183bSBitterblue Smith val32 &= ~OFDM_RF_PATH_TX_MASK;
1643c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_OFDM0_TRX_PATH_ENABLE, val32);
1644c888183bSBitterblue Smith
1645c888183bSBitterblue Smith /* Power down RF module */
1646c888183bSBitterblue Smith rtl8xxxu_write_rfreg(priv, RF_A, RF6052_REG_AC, 0);
1647c888183bSBitterblue Smith }
1648c888183bSBitterblue Smith
rtl8188f_usb_quirks(struct rtl8xxxu_priv * priv)1649c888183bSBitterblue Smith static void rtl8188f_usb_quirks(struct rtl8xxxu_priv *priv)
1650c888183bSBitterblue Smith {
1651c888183bSBitterblue Smith u16 val16;
1652c888183bSBitterblue Smith u32 val32;
1653c888183bSBitterblue Smith
1654c888183bSBitterblue Smith val16 = rtl8xxxu_read16(priv, REG_CR);
1655c888183bSBitterblue Smith val16 |= (CR_MAC_TX_ENABLE | CR_MAC_RX_ENABLE);
1656c888183bSBitterblue Smith rtl8xxxu_write16(priv, REG_CR, val16);
1657c888183bSBitterblue Smith
1658c888183bSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_TXDMA_OFFSET_CHK);
1659c888183bSBitterblue Smith val32 |= TXDMA_OFFSET_DROP_DATA_EN;
1660c888183bSBitterblue Smith rtl8xxxu_write32(priv, REG_TXDMA_OFFSET_CHK, val32);
1661c888183bSBitterblue Smith }
1662c888183bSBitterblue Smith
166357b328bcSBitterblue Smith #define XTAL1 GENMASK(22, 17)
166457b328bcSBitterblue Smith #define XTAL0 GENMASK(16, 11)
166557b328bcSBitterblue Smith
rtl8188f_set_crystal_cap(struct rtl8xxxu_priv * priv,u8 crystal_cap)16663dfb8e84SJes Sorensen void rtl8188f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap)
166757b328bcSBitterblue Smith {
166857b328bcSBitterblue Smith struct rtl8xxxu_cfo_tracking *cfo = &priv->cfo_tracking;
166957b328bcSBitterblue Smith u32 val32;
167057b328bcSBitterblue Smith
167157b328bcSBitterblue Smith if (crystal_cap == cfo->crystal_cap)
167257b328bcSBitterblue Smith return;
167357b328bcSBitterblue Smith
167457b328bcSBitterblue Smith val32 = rtl8xxxu_read32(priv, REG_AFE_XTAL_CTRL);
167557b328bcSBitterblue Smith
167657b328bcSBitterblue Smith dev_dbg(&priv->udev->dev,
167757b328bcSBitterblue Smith "%s: Adjusting crystal cap from 0x%x (actually 0x%lx 0x%lx) to 0x%x\n",
167857b328bcSBitterblue Smith __func__,
167957b328bcSBitterblue Smith cfo->crystal_cap,
168057b328bcSBitterblue Smith FIELD_GET(XTAL1, val32),
168157b328bcSBitterblue Smith FIELD_GET(XTAL0, val32),
168257b328bcSBitterblue Smith crystal_cap);
168357b328bcSBitterblue Smith
168457b328bcSBitterblue Smith val32 &= ~(XTAL1 | XTAL0);
168557b328bcSBitterblue Smith val32 |= FIELD_PREP(XTAL1, crystal_cap) |
168657b328bcSBitterblue Smith FIELD_PREP(XTAL0, crystal_cap);
168757b328bcSBitterblue Smith rtl8xxxu_write32(priv, REG_AFE_XTAL_CTRL, val32);
168857b328bcSBitterblue Smith
168957b328bcSBitterblue Smith cfo->crystal_cap = crystal_cap;
169057b328bcSBitterblue Smith }
169157b328bcSBitterblue Smith
rtl8188f_cck_rssi(struct rtl8xxxu_priv * priv,struct rtl8723au_phy_stats * phy_stats)169270664495SBitterblue Smith static s8 rtl8188f_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats)
16932ad2a813SBitterblue Smith {
169470664495SBitterblue Smith u8 cck_agc_rpt = phy_stats->cck_agc_rpt_ofdm_cfosho_a;
16952ad2a813SBitterblue Smith s8 rx_pwr_all = 0x00;
16962ad2a813SBitterblue Smith u8 vga_idx, lna_idx;
16972ad2a813SBitterblue Smith
1698b75289e8SBitterblue Smith lna_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_LNA_IDX_MASK);
1699b75289e8SBitterblue Smith vga_idx = u8_get_bits(cck_agc_rpt, CCK_AGC_RPT_VGA_IDX_MASK);
17002ad2a813SBitterblue Smith
17012ad2a813SBitterblue Smith switch (lna_idx) {
17022ad2a813SBitterblue Smith case 7:
17032ad2a813SBitterblue Smith if (vga_idx <= 27)
17042ad2a813SBitterblue Smith rx_pwr_all = -100 + 2 * (27 - vga_idx);
17052ad2a813SBitterblue Smith else
17062ad2a813SBitterblue Smith rx_pwr_all = -100;
17072ad2a813SBitterblue Smith break;
17082ad2a813SBitterblue Smith case 5:
17092ad2a813SBitterblue Smith rx_pwr_all = -74 + 2 * (21 - vga_idx);
17102ad2a813SBitterblue Smith break;
17112ad2a813SBitterblue Smith case 3:
17122ad2a813SBitterblue Smith rx_pwr_all = -60 + 2 * (20 - vga_idx);
17132ad2a813SBitterblue Smith break;
17142ad2a813SBitterblue Smith case 1:
17152ad2a813SBitterblue Smith rx_pwr_all = -44 + 2 * (19 - vga_idx);
17162ad2a813SBitterblue Smith break;
17172ad2a813SBitterblue Smith default:
17182ad2a813SBitterblue Smith break;
17192ad2a813SBitterblue Smith }
17202ad2a813SBitterblue Smith
17212ad2a813SBitterblue Smith return rx_pwr_all;
17222ad2a813SBitterblue Smith }
17232ad2a813SBitterblue Smith
1724c888183bSBitterblue Smith struct rtl8xxxu_fileops rtl8188fu_fops = {
172514566bbfSBitterblue Smith .identify_chip = rtl8188fu_identify_chip,
1726c888183bSBitterblue Smith .parse_efuse = rtl8188fu_parse_efuse,
1727c888183bSBitterblue Smith .load_firmware = rtl8188fu_load_firmware,
1728c888183bSBitterblue Smith .power_on = rtl8188fu_power_on,
1729c888183bSBitterblue Smith .power_off = rtl8188fu_power_off,
173070664495SBitterblue Smith .read_efuse = rtl8xxxu_read_efuse,
1731c888183bSBitterblue Smith .reset_8051 = rtl8xxxu_reset_8051,
1732c888183bSBitterblue Smith .llt_init = rtl8xxxu_auto_llt_table,
1733c888183bSBitterblue Smith .init_phy_bb = rtl8188fu_init_phy_bb,
1734c888183bSBitterblue Smith .init_phy_rf = rtl8188fu_init_phy_rf,
1735c888183bSBitterblue Smith .phy_init_antenna_selection = rtl8723bu_phy_init_antenna_selection,
1736c888183bSBitterblue Smith .phy_lc_calibrate = rtl8188f_phy_lc_calibrate,
1737c888183bSBitterblue Smith .phy_iq_calibrate = rtl8188fu_phy_iq_calibrate,
1738c888183bSBitterblue Smith .config_channel = rtl8188fu_config_channel,
1739c888183bSBitterblue Smith .parse_rx_desc = rtl8xxxu_parse_rxdesc24,
174070664495SBitterblue Smith .parse_phystats = rtl8723au_rx_parse_phystats,
1741c888183bSBitterblue Smith .init_aggregation = rtl8188fu_init_aggregation,
1742c888183bSBitterblue Smith .init_statistics = rtl8188fu_init_statistics,
1743bcfcb712SBitterblue Smith .init_burst = rtl8xxxu_init_burst,
1744c888183bSBitterblue Smith .enable_rf = rtl8188f_enable_rf,
1745c888183bSBitterblue Smith .disable_rf = rtl8188f_disable_rf,
1746c888183bSBitterblue Smith .usb_quirks = rtl8188f_usb_quirks,
1747c888183bSBitterblue Smith .set_tx_power = rtl8188f_set_tx_power,
1748c888183bSBitterblue Smith .update_rate_mask = rtl8xxxu_gen2_update_rate_mask,
1749c888183bSBitterblue Smith .report_connect = rtl8xxxu_gen2_report_connect,
17503922dc9fSBitterblue Smith .report_rssi = rtl8xxxu_gen2_report_rssi,
1751c888183bSBitterblue Smith .fill_txdesc = rtl8xxxu_fill_txdesc_v2,
175257b328bcSBitterblue Smith .set_crystal_cap = rtl8188f_set_crystal_cap,
17532ad2a813SBitterblue Smith .cck_rssi = rtl8188f_cck_rssi,
1754c888183bSBitterblue Smith .writeN_block_size = 128,
1755c888183bSBitterblue Smith .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24),
1756c888183bSBitterblue Smith .tx_desc_size = sizeof(struct rtl8xxxu_txdesc40),
1757c888183bSBitterblue Smith .has_s0s1 = 1,
1758c888183bSBitterblue Smith .has_tx_report = 1,
1759c888183bSBitterblue Smith .gen2_thermal_meter = 1,
1760c888183bSBitterblue Smith .needs_full_init = 1,
1761a5be45eaSBitterblue Smith .init_reg_rxfltmap = 1,
1762a5be45eaSBitterblue Smith .init_reg_pkt_life_time = 1,
1763a5be45eaSBitterblue Smith .init_reg_hmtfr = 1,
1764a5be45eaSBitterblue Smith .ampdu_max_time = 0x70,
1765a5be45eaSBitterblue Smith .ustime_tsf_edca = 0x28,
1766c98411dcSBitterblue Smith .max_aggr_num = 0x0c14,
1767b468481cSMartin Kaistra .supports_ap = 1,
1768b9a07c44SMartin Kaistra .max_macid_num = 16,
1769c888183bSBitterblue Smith .adda_1t_init = 0x03c00014,
1770c888183bSBitterblue Smith .adda_1t_path_on = 0x03c00014,
1771c888183bSBitterblue Smith .trxff_boundary = 0x3f7f,
1772c888183bSBitterblue Smith .pbp_rx = PBP_PAGE_SIZE_256,
1773c888183bSBitterblue Smith .pbp_tx = PBP_PAGE_SIZE_256,
1774c888183bSBitterblue Smith .mactable = rtl8188f_mac_init_table,
1775c888183bSBitterblue Smith .total_page_num = TX_TOTAL_PAGE_NUM_8188F,
1776c888183bSBitterblue Smith .page_num_hi = TX_PAGE_NUM_HI_PQ_8188F,
1777c888183bSBitterblue Smith .page_num_lo = TX_PAGE_NUM_LO_PQ_8188F,
1778c888183bSBitterblue Smith .page_num_norm = TX_PAGE_NUM_NORM_PQ_8188F,
1779c888183bSBitterblue Smith };
1780