1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3
4 Broadcom B43 wireless driver
5 IEEE 802.11n LCN-PHY data tables
6
7 Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
8
9
10 */
11
12 #include "b43.h"
13 #include "tables_phy_lcn.h"
14 #include "phy_common.h"
15 #include "phy_lcn.h"
16
17 struct b43_lcntab_tx_gain_tbl_entry {
18 u8 gm;
19 u8 pga;
20 u8 pad;
21 u8 dac;
22 u8 bb_mult;
23 };
24
25 /**************************************************
26 * Static tables.
27 **************************************************/
28
29 static const u16 b43_lcntab_0x02[] = {
30 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
31 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
32 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
33 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
34 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
35 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
36 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
37 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
38 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
39 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
40 0x014d, 0x014d, 0x014d, 0x014d,
41 };
42
43 static const u16 b43_lcntab_0x01[] = {
44 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
45 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
46 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
47 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
48 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
49 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
50 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
51 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
52 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
53 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
54 0x0000, 0x0000, 0x0000, 0x0000,
55 };
56
57 static const u32 b43_lcntab_0x0b[] = {
58 0x000141f8, 0x000021f8, 0x000021fb, 0x000041fb,
59 0x0001fedb, 0x0000217b, 0x00002133, 0x000040eb,
60 0x0001fea3, 0x0000024b,
61 };
62
63 static const u32 b43_lcntab_0x0c[] = {
64 0x00100001, 0x00200010, 0x00300001, 0x00400010,
65 0x00500022, 0x00600122, 0x00700222, 0x00800322,
66 0x00900422, 0x00a00522, 0x00b00622, 0x00c00722,
67 0x00d00822, 0x00f00922, 0x00100a22, 0x00200b22,
68 0x00300c22, 0x00400d22, 0x00500e22, 0x00600f22,
69 };
70
71 static const u32 b43_lcntab_0x0d[] = {
72 0x00000000, 0x00000000, 0x10000000, 0x00000000,
73 0x20000000, 0x00000000, 0x30000000, 0x00000000,
74 0x40000000, 0x00000000, 0x50000000, 0x00000000,
75 0x60000000, 0x00000000, 0x70000000, 0x00000000,
76 0x80000000, 0x00000000, 0x90000000, 0x00000008,
77 0xa0000000, 0x00000008, 0xb0000000, 0x00000008,
78 0xc0000000, 0x00000008, 0xd0000000, 0x00000008,
79 0xe0000000, 0x00000008, 0xf0000000, 0x00000008,
80 0x00000000, 0x00000009, 0x10000000, 0x00000009,
81 0x20000000, 0x00000019, 0x30000000, 0x00000019,
82 0x40000000, 0x00000019, 0x50000000, 0x00000019,
83 0x60000000, 0x00000019, 0x70000000, 0x00000019,
84 0x80000000, 0x00000019, 0x90000000, 0x00000019,
85 0xa0000000, 0x00000019, 0xb0000000, 0x00000019,
86 0xc0000000, 0x00000019, 0xd0000000, 0x00000019,
87 0xe0000000, 0x00000019, 0xf0000000, 0x00000019,
88 0x00000000, 0x0000001a, 0x10000000, 0x0000001a,
89 0x20000000, 0x0000001a, 0x30000000, 0x0000001a,
90 0x40000000, 0x0000001a, 0x50000000, 0x00000002,
91 0x60000000, 0x00000002, 0x70000000, 0x00000002,
92 0x80000000, 0x00000002, 0x90000000, 0x00000002,
93 0xa0000000, 0x00000002, 0xb0000000, 0x00000002,
94 0xc0000000, 0x0000000a, 0xd0000000, 0x0000000a,
95 0xe0000000, 0x0000000a, 0xf0000000, 0x0000000a,
96 0x00000000, 0x0000000b, 0x10000000, 0x0000000b,
97 0x20000000, 0x0000000b, 0x30000000, 0x0000000b,
98 0x40000000, 0x0000000b, 0x50000000, 0x0000001b,
99 0x60000000, 0x0000001b, 0x70000000, 0x0000001b,
100 0x80000000, 0x0000001b, 0x90000000, 0x0000001b,
101 0xa0000000, 0x0000001b, 0xb0000000, 0x0000001b,
102 0xc0000000, 0x0000001b, 0xd0000000, 0x0000001b,
103 0xe0000000, 0x0000001b, 0xf0000000, 0x0000001b,
104 0x00000000, 0x0000001c, 0x10000000, 0x0000001c,
105 0x20000000, 0x0000001c, 0x30000000, 0x0000001c,
106 0x40000000, 0x0000001c, 0x50000000, 0x0000001c,
107 0x60000000, 0x0000001c, 0x70000000, 0x0000001c,
108 0x80000000, 0x0000001c, 0x90000000, 0x0000001c,
109 };
110
111 static const u16 b43_lcntab_0x0e[] = {
112 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
113 0x0407, 0x0408, 0x0409, 0x040a, 0x058b, 0x058c,
114 0x058d, 0x058e, 0x058f, 0x0090, 0x0091, 0x0092,
115 0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0198,
116 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e,
117 0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4,
118 0x01a5, 0x0000,
119 };
120
121 static const u16 b43_lcntab_0x0f[] = {
122 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
123 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
124 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
125 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
126 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
127 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
128 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
129 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
130 0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
131 0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
132 0x000a, 0x0009, 0x0006, 0x0005,
133 };
134
135 static const u16 b43_lcntab_0x10[] = {
136 0x005f, 0x0036, 0x0029, 0x001f, 0x005f, 0x0036,
137 0x0029, 0x001f, 0x005f, 0x0036, 0x0029, 0x001f,
138 0x005f, 0x0036, 0x0029, 0x001f,
139 };
140
141 static const u16 b43_lcntab_0x11[] = {
142 0x0009, 0x000f, 0x0014, 0x0018, 0x00fe, 0x0007,
143 0x000b, 0x000f, 0x00fb, 0x00fe, 0x0001, 0x0005,
144 0x0008, 0x000b, 0x000e, 0x0011, 0x0014, 0x0017,
145 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
146 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f,
147 0x0012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
148 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003,
149 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015,
150 0x0018, 0x001b, 0x0000, 0x0000, 0x0000, 0x0000,
151 0x0000, 0x0000, 0x0003, 0x00eb, 0x0000, 0x0000,
152 };
153
154 static const u32 b43_lcntab_0x12[] = {
155 0x00000000, 0x00000000, 0x00000000, 0x00000000,
156 0x00000000, 0x00000000, 0x00000000, 0x00000000,
157 0x00000004, 0x00000000, 0x00000004, 0x00000008,
158 0x00000001, 0x00000005, 0x00000009, 0x0000000d,
159 0x0000004d, 0x0000008d, 0x0000000d, 0x0000004d,
160 0x0000008d, 0x000000cd, 0x0000004f, 0x0000008f,
161 0x000000cf, 0x000000d3, 0x00000113, 0x00000513,
162 0x00000913, 0x00000953, 0x00000d53, 0x00001153,
163 0x00001193, 0x00005193, 0x00009193, 0x0000d193,
164 0x00011193, 0x00000000, 0x00000000, 0x00000000,
165 0x00000000, 0x00000000, 0x00000000, 0x00000004,
166 0x00000000, 0x00000004, 0x00000008, 0x00000001,
167 0x00000005, 0x00000009, 0x0000000d, 0x0000004d,
168 0x0000008d, 0x0000000d, 0x0000004d, 0x0000008d,
169 0x000000cd, 0x0000004f, 0x0000008f, 0x000000cf,
170 0x000000d3, 0x00000113, 0x00000513, 0x00000913,
171 0x00000953, 0x00000d53, 0x00001153, 0x00005153,
172 0x00009153, 0x0000d153, 0x00011153, 0x00015153,
173 0x00019153, 0x0001d153, 0x00000000, 0x00000000,
174 0x00000000, 0x00000000, 0x00000000, 0x00000000,
175 0x00000000, 0x00000000, 0x00000000, 0x00000000,
176 0x00000000, 0x00000000, 0x00000000, 0x00000000,
177 0x00000000, 0x00000000, 0x00000000, 0x00000000,
178 0x00000000, 0x00000000, 0x00000000, 0x00000000,
179 };
180
181 static const u16 b43_lcntab_0x14[] = {
182 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
183 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
184 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
185 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
186 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
187 0x0002, 0x0003, 0x0001, 0x0003, 0x0002, 0x0001,
188 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
189 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
190 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
191 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
192 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
193 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
194 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
195 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
196 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
197 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003,
198 0x0001, 0x0003, 0x0002, 0x0001, 0x0001, 0x0001,
199 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
200 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
201 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
202 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
203 0x0001, 0x0001,
204 };
205
206 static const u16 b43_lcntab_0x17[] = {
207 0x001a, 0x0034, 0x004e, 0x0068, 0x009c, 0x00d0,
208 0x00ea, 0x0104, 0x0034, 0x0068, 0x009c, 0x00d0,
209 0x0138, 0x01a0, 0x01d4, 0x0208, 0x004e, 0x009c,
210 0x00ea, 0x0138, 0x01d4, 0x0270, 0x02be, 0x030c,
211 0x0068, 0x00d0, 0x0138, 0x01a0, 0x0270, 0x0340,
212 0x03a8, 0x0410, 0x0018, 0x009c, 0x00d0, 0x0104,
213 0x00ea, 0x0138, 0x0186, 0x00d0, 0x0104, 0x0104,
214 0x0138, 0x016c, 0x016c, 0x01a0, 0x0138, 0x0186,
215 0x0186, 0x01d4, 0x0222, 0x0222, 0x0270, 0x0104,
216 0x0138, 0x016c, 0x0138, 0x016c, 0x01a0, 0x01d4,
217 0x01a0, 0x01d4, 0x0208, 0x0208, 0x023c, 0x0186,
218 0x01d4, 0x0222, 0x01d4, 0x0222, 0x0270, 0x02be,
219 0x0270, 0x02be, 0x030c, 0x030c, 0x035a, 0x0036,
220 0x006c, 0x00a2, 0x00d8, 0x0144, 0x01b0, 0x01e6,
221 0x021c, 0x006c, 0x00d8, 0x0144, 0x01b0, 0x0288,
222 0x0360, 0x03cc, 0x0438, 0x00a2, 0x0144, 0x01e6,
223 0x0288, 0x03cc, 0x0510, 0x05b2, 0x0654, 0x00d8,
224 0x01b0, 0x0288, 0x0360, 0x0510, 0x06c0, 0x0798,
225 0x0870, 0x0018, 0x0144, 0x01b0, 0x021c, 0x01e6,
226 0x0288, 0x032a, 0x01b0, 0x021c, 0x021c, 0x0288,
227 0x02f4, 0x02f4, 0x0360, 0x0288, 0x032a, 0x032a,
228 0x03cc, 0x046e, 0x046e, 0x0510, 0x021c, 0x0288,
229 0x02f4, 0x0288, 0x02f4, 0x0360, 0x03cc, 0x0360,
230 0x03cc, 0x0438, 0x0438, 0x04a4, 0x032a, 0x03cc,
231 0x046e, 0x03cc, 0x046e, 0x0510, 0x05b2, 0x0510,
232 0x05b2, 0x0654, 0x0654, 0x06f6,
233 };
234
235 static const u16 b43_lcntab_0x00[] = {
236 0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00,
237 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005,
238 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
239 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
240 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
241 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
242 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003,
243 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007,
244 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
245 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
246 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
247 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
248 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
249 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
250 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
251 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
252 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
253 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
254 };
255
256 static const u32 b43_lcntab_0x18[] = {
257 0x00080000, 0x00080000, 0x00080000, 0x00080000,
258 0x00080000, 0x00080000, 0x00080000, 0x00080000,
259 0x00080000, 0x00080000, 0x00080000, 0x00080000,
260 0x00080000, 0x00080000, 0x00080000, 0x00080000,
261 0x00080000, 0x00080000, 0x00080000, 0x00080000,
262 0x00080000, 0x00080000, 0x00080000, 0x00080000,
263 0x00080000, 0x00080000, 0x00080000, 0x00080000,
264 0x00080000, 0x00080000, 0x00080000, 0x00080000,
265 0x00080000, 0x00080000, 0x00080000, 0x00080000,
266 0x00080000, 0x00080000, 0x00080000, 0x00080000,
267 0x00080000, 0x00080000, 0x00080000, 0x00080000,
268 0x00080000, 0x00080000, 0x00080000, 0x00080000,
269 0x00080000, 0x00080000, 0x00080000, 0x00080000,
270 0x00080000, 0x00080000, 0x00080000, 0x00080000,
271 0x00080000, 0x00080000, 0x00080000, 0x00080000,
272 0x00080000, 0x00080000, 0x00080000, 0x00080000,
273 0x00080000, 0x00080000, 0x00080000, 0x00080000,
274 0x00080000, 0x00080000, 0x00080000, 0x00080000,
275 0x00080000, 0x00080000, 0x00080000, 0x00080000,
276 0x00080000, 0x00080000, 0x00080000, 0x00080000,
277 0x00080000, 0x00080000, 0x00080000, 0x00080000,
278 0x00080000, 0x00080000, 0x00080000, 0x00080000,
279 0x00080000, 0x00080000, 0x00080000, 0x00080000,
280 0x00080000, 0x00080000, 0x00080000, 0x00080000,
281 0x00080000, 0x00080000, 0x00080000, 0x00080000,
282 0x00080000, 0x00080000, 0x00080000, 0x00080000,
283 0x00080000, 0x00080000, 0x00080000, 0x00080000,
284 0x00080000, 0x00080000, 0x00080000, 0x00080000,
285 0x00080000, 0x00080000, 0x00080000, 0x00080000,
286 0x00080000, 0x00080000, 0x00080000, 0x00080000,
287 0x00080000, 0x00080000, 0x00080000, 0x00080000,
288 0x00080000, 0x00080000, 0x00080000, 0x00080000,
289 0x00080000, 0x00080000, 0x00080000, 0x00080000,
290 0x00080000, 0x00080000, 0x00080000, 0x00080000,
291 0x00080000, 0x00080000, 0x00080000, 0x00080000,
292 0x00080000, 0x00080000, 0x00080000, 0x00080000,
293 0x00080000, 0x00080000, 0x00080000, 0x00080000,
294 0x00080000, 0x00080000, 0x00080000, 0x00080000,
295 0x00080000, 0x00080000, 0x00080000, 0x00080000,
296 0x00080000, 0x00080000, 0x00080000, 0x00080000,
297 };
298
299 /**************************************************
300 * TX gain.
301 **************************************************/
302
303 static const struct b43_lcntab_tx_gain_tbl_entry
304 b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0[B43_LCNTAB_TX_GAIN_SIZE] = {
305 { 0x03, 0x00, 0x1f, 0x0, 0x48 },
306 { 0x03, 0x00, 0x1f, 0x0, 0x46 },
307 { 0x03, 0x00, 0x1f, 0x0, 0x44 },
308 { 0x03, 0x00, 0x1e, 0x0, 0x43 },
309 { 0x03, 0x00, 0x1d, 0x0, 0x44 },
310 { 0x03, 0x00, 0x1c, 0x0, 0x44 },
311 { 0x03, 0x00, 0x1b, 0x0, 0x45 },
312 { 0x03, 0x00, 0x1a, 0x0, 0x46 },
313 { 0x03, 0x00, 0x19, 0x0, 0x46 },
314 { 0x03, 0x00, 0x18, 0x0, 0x47 },
315 { 0x03, 0x00, 0x17, 0x0, 0x48 },
316 { 0x03, 0x00, 0x17, 0x0, 0x46 },
317 { 0x03, 0x00, 0x16, 0x0, 0x47 },
318 { 0x03, 0x00, 0x15, 0x0, 0x48 },
319 { 0x03, 0x00, 0x15, 0x0, 0x46 },
320 { 0x03, 0x00, 0x15, 0x0, 0x44 },
321 { 0x03, 0x00, 0x15, 0x0, 0x42 },
322 { 0x03, 0x00, 0x15, 0x0, 0x40 },
323 { 0x03, 0x00, 0x15, 0x0, 0x3f },
324 { 0x03, 0x00, 0x14, 0x0, 0x40 },
325 { 0x03, 0x00, 0x13, 0x0, 0x41 },
326 { 0x03, 0x00, 0x13, 0x0, 0x40 },
327 { 0x03, 0x00, 0x12, 0x0, 0x41 },
328 { 0x03, 0x00, 0x12, 0x0, 0x40 },
329 { 0x03, 0x00, 0x11, 0x0, 0x41 },
330 { 0x03, 0x00, 0x11, 0x0, 0x40 },
331 { 0x03, 0x00, 0x10, 0x0, 0x41 },
332 { 0x03, 0x00, 0x10, 0x0, 0x40 },
333 { 0x03, 0x00, 0x10, 0x0, 0x3e },
334 { 0x03, 0x00, 0x10, 0x0, 0x3c },
335 { 0x03, 0x00, 0x10, 0x0, 0x3a },
336 { 0x03, 0x00, 0x0f, 0x0, 0x3d },
337 { 0x03, 0x00, 0x0f, 0x0, 0x3b },
338 { 0x03, 0x00, 0x0e, 0x0, 0x3d },
339 { 0x03, 0x00, 0x0e, 0x0, 0x3c },
340 { 0x03, 0x00, 0x0e, 0x0, 0x3a },
341 { 0x03, 0x00, 0x0d, 0x0, 0x3c },
342 { 0x03, 0x00, 0x0d, 0x0, 0x3b },
343 { 0x03, 0x00, 0x0c, 0x0, 0x3e },
344 { 0x03, 0x00, 0x0c, 0x0, 0x3c },
345 { 0x03, 0x00, 0x0c, 0x0, 0x3a },
346 { 0x03, 0x00, 0x0b, 0x0, 0x3e },
347 { 0x03, 0x00, 0x0b, 0x0, 0x3c },
348 { 0x03, 0x00, 0x0b, 0x0, 0x3b },
349 { 0x03, 0x00, 0x0b, 0x0, 0x39 },
350 { 0x03, 0x00, 0x0a, 0x0, 0x3d },
351 { 0x03, 0x00, 0x0a, 0x0, 0x3b },
352 { 0x03, 0x00, 0x0a, 0x0, 0x39 },
353 { 0x03, 0x00, 0x09, 0x0, 0x3e },
354 { 0x03, 0x00, 0x09, 0x0, 0x3c },
355 { 0x03, 0x00, 0x09, 0x0, 0x3a },
356 { 0x03, 0x00, 0x09, 0x0, 0x39 },
357 { 0x03, 0x00, 0x08, 0x0, 0x3e },
358 { 0x03, 0x00, 0x08, 0x0, 0x3c },
359 { 0x03, 0x00, 0x08, 0x0, 0x3a },
360 { 0x03, 0x00, 0x08, 0x0, 0x39 },
361 { 0x03, 0x00, 0x08, 0x0, 0x37 },
362 { 0x03, 0x00, 0x07, 0x0, 0x3d },
363 { 0x03, 0x00, 0x07, 0x0, 0x3c },
364 { 0x03, 0x00, 0x07, 0x0, 0x3a },
365 { 0x03, 0x00, 0x07, 0x0, 0x38 },
366 { 0x03, 0x00, 0x07, 0x0, 0x37 },
367 { 0x03, 0x00, 0x06, 0x0, 0x3e },
368 { 0x03, 0x00, 0x06, 0x0, 0x3c },
369 { 0x03, 0x00, 0x06, 0x0, 0x3a },
370 { 0x03, 0x00, 0x06, 0x0, 0x39 },
371 { 0x03, 0x00, 0x06, 0x0, 0x37 },
372 { 0x03, 0x00, 0x06, 0x0, 0x36 },
373 { 0x03, 0x00, 0x06, 0x0, 0x34 },
374 { 0x03, 0x00, 0x05, 0x0, 0x3d },
375 { 0x03, 0x00, 0x05, 0x0, 0x3b },
376 { 0x03, 0x00, 0x05, 0x0, 0x39 },
377 { 0x03, 0x00, 0x05, 0x0, 0x38 },
378 { 0x03, 0x00, 0x05, 0x0, 0x36 },
379 { 0x03, 0x00, 0x05, 0x0, 0x35 },
380 { 0x03, 0x00, 0x05, 0x0, 0x33 },
381 { 0x03, 0x00, 0x04, 0x0, 0x3e },
382 { 0x03, 0x00, 0x04, 0x0, 0x3c },
383 { 0x03, 0x00, 0x04, 0x0, 0x3a },
384 { 0x03, 0x00, 0x04, 0x0, 0x39 },
385 { 0x03, 0x00, 0x04, 0x0, 0x37 },
386 { 0x03, 0x00, 0x04, 0x0, 0x36 },
387 { 0x03, 0x00, 0x04, 0x0, 0x34 },
388 { 0x03, 0x00, 0x04, 0x0, 0x33 },
389 { 0x03, 0x00, 0x04, 0x0, 0x31 },
390 { 0x03, 0x00, 0x04, 0x0, 0x30 },
391 { 0x03, 0x00, 0x04, 0x0, 0x2e },
392 { 0x03, 0x00, 0x03, 0x0, 0x3c },
393 { 0x03, 0x00, 0x03, 0x0, 0x3a },
394 { 0x03, 0x00, 0x03, 0x0, 0x39 },
395 { 0x03, 0x00, 0x03, 0x0, 0x37 },
396 { 0x03, 0x00, 0x03, 0x0, 0x36 },
397 { 0x03, 0x00, 0x03, 0x0, 0x34 },
398 { 0x03, 0x00, 0x03, 0x0, 0x33 },
399 { 0x03, 0x00, 0x03, 0x0, 0x31 },
400 { 0x03, 0x00, 0x03, 0x0, 0x30 },
401 { 0x03, 0x00, 0x03, 0x0, 0x2e },
402 { 0x03, 0x00, 0x03, 0x0, 0x2d },
403 { 0x03, 0x00, 0x03, 0x0, 0x2c },
404 { 0x03, 0x00, 0x03, 0x0, 0x2b },
405 { 0x03, 0x00, 0x03, 0x0, 0x29 },
406 { 0x03, 0x00, 0x02, 0x0, 0x3d },
407 { 0x03, 0x00, 0x02, 0x0, 0x3b },
408 { 0x03, 0x00, 0x02, 0x0, 0x39 },
409 { 0x03, 0x00, 0x02, 0x0, 0x38 },
410 { 0x03, 0x00, 0x02, 0x0, 0x36 },
411 { 0x03, 0x00, 0x02, 0x0, 0x35 },
412 { 0x03, 0x00, 0x02, 0x0, 0x33 },
413 { 0x03, 0x00, 0x02, 0x0, 0x32 },
414 { 0x03, 0x00, 0x02, 0x0, 0x30 },
415 { 0x03, 0x00, 0x02, 0x0, 0x2f },
416 { 0x03, 0x00, 0x02, 0x0, 0x2e },
417 { 0x03, 0x00, 0x02, 0x0, 0x2c },
418 { 0x03, 0x00, 0x02, 0x0, 0x2b },
419 { 0x03, 0x00, 0x02, 0x0, 0x2a },
420 { 0x03, 0x00, 0x02, 0x0, 0x29 },
421 { 0x03, 0x00, 0x02, 0x0, 0x27 },
422 { 0x03, 0x00, 0x02, 0x0, 0x26 },
423 { 0x03, 0x00, 0x02, 0x0, 0x25 },
424 { 0x03, 0x00, 0x02, 0x0, 0x24 },
425 { 0x03, 0x00, 0x02, 0x0, 0x23 },
426 { 0x03, 0x00, 0x02, 0x0, 0x22 },
427 { 0x03, 0x00, 0x02, 0x0, 0x21 },
428 { 0x03, 0x00, 0x02, 0x0, 0x20 },
429 { 0x03, 0x00, 0x01, 0x0, 0x3f },
430 { 0x03, 0x00, 0x01, 0x0, 0x3d },
431 { 0x03, 0x00, 0x01, 0x0, 0x3b },
432 { 0x03, 0x00, 0x01, 0x0, 0x39 },
433 };
434
435 /**************************************************
436 * SW control.
437 **************************************************/
438
439 static const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = {
440 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
441 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
442 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
443 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
444 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
445 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
446 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
447 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
448 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
449 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
450 0x0002, 0x0008, 0x0004, 0x0001,
451 };
452
453 /**************************************************
454 * R/W ops.
455 **************************************************/
456
b43_lcntab_read(struct b43_wldev * dev,u32 offset)457 u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset)
458 {
459 u32 type, value;
460
461 type = offset & B43_LCNTAB_TYPEMASK;
462 offset &= ~B43_LCNTAB_TYPEMASK;
463 B43_WARN_ON(offset > 0xFFFF);
464
465 switch (type) {
466 case B43_LCNTAB_8BIT:
467 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
468 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO) & 0xFF;
469 break;
470 case B43_LCNTAB_16BIT:
471 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
472 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
473 break;
474 case B43_LCNTAB_32BIT:
475 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
476 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
477 value |= (b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI) << 16);
478 break;
479 default:
480 B43_WARN_ON(1);
481 value = 0;
482 }
483
484 return value;
485 }
486
b43_lcntab_read_bulk(struct b43_wldev * dev,u32 offset,unsigned int nr_elements,void * _data)487 void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset,
488 unsigned int nr_elements, void *_data)
489 {
490 u32 type;
491 u8 *data = _data;
492 unsigned int i;
493
494 type = offset & B43_LCNTAB_TYPEMASK;
495 offset &= ~B43_LCNTAB_TYPEMASK;
496 B43_WARN_ON(offset > 0xFFFF);
497
498 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
499
500 for (i = 0; i < nr_elements; i++) {
501 switch (type) {
502 case B43_LCNTAB_8BIT:
503 *data = b43_phy_read(dev,
504 B43_PHY_LCN_TABLE_DATALO) & 0xFF;
505 data++;
506 break;
507 case B43_LCNTAB_16BIT:
508 *((u16 *)data) = b43_phy_read(dev,
509 B43_PHY_LCN_TABLE_DATALO);
510 data += 2;
511 break;
512 case B43_LCNTAB_32BIT:
513 *((u32 *)data) = b43_phy_read(dev,
514 B43_PHY_LCN_TABLE_DATALO);
515 *((u32 *)data) |= (b43_phy_read(dev,
516 B43_PHY_LCN_TABLE_DATAHI) << 16);
517 data += 4;
518 break;
519 default:
520 B43_WARN_ON(1);
521 }
522 }
523 }
524
b43_lcntab_write(struct b43_wldev * dev,u32 offset,u32 value)525 void b43_lcntab_write(struct b43_wldev *dev, u32 offset, u32 value)
526 {
527 u32 type;
528
529 type = offset & B43_LCNTAB_TYPEMASK;
530 offset &= 0xFFFF;
531
532 switch (type) {
533 case B43_LCNTAB_8BIT:
534 B43_WARN_ON(value & ~0xFF);
535 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
536 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
537 break;
538 case B43_LCNTAB_16BIT:
539 B43_WARN_ON(value & ~0xFFFF);
540 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
541 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
542 break;
543 case B43_LCNTAB_32BIT:
544 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
545 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, value >> 16);
546 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value & 0xFFFF);
547 break;
548 default:
549 B43_WARN_ON(1);
550 }
551
552 return;
553 }
554
b43_lcntab_write_bulk(struct b43_wldev * dev,u32 offset,unsigned int nr_elements,const void * _data)555 void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset,
556 unsigned int nr_elements, const void *_data)
557 {
558 u32 type, value;
559 const u8 *data = _data;
560 unsigned int i;
561
562 type = offset & B43_LCNTAB_TYPEMASK;
563 offset &= ~B43_LCNTAB_TYPEMASK;
564 B43_WARN_ON(offset > 0xFFFF);
565
566 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
567
568 for (i = 0; i < nr_elements; i++) {
569 switch (type) {
570 case B43_LCNTAB_8BIT:
571 value = *data;
572 data++;
573 B43_WARN_ON(value & ~0xFF);
574 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
575 break;
576 case B43_LCNTAB_16BIT:
577 value = *((u16 *)data);
578 data += 2;
579 B43_WARN_ON(value & ~0xFFFF);
580 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
581 break;
582 case B43_LCNTAB_32BIT:
583 value = *((u32 *)data);
584 data += 4;
585 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI,
586 value >> 16);
587 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO,
588 value & 0xFFFF);
589 break;
590 default:
591 B43_WARN_ON(1);
592 }
593 }
594 }
595
596 /**************************************************
597 * Tables ops.
598 **************************************************/
599
600 #define lcntab_upload(dev, offset, data) do { \
601 b43_lcntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
602 } while (0)
b43_phy_lcn_upload_static_tables(struct b43_wldev * dev)603 static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev)
604 {
605 lcntab_upload(dev, B43_LCNTAB16(0x02, 0), b43_lcntab_0x02);
606 lcntab_upload(dev, B43_LCNTAB16(0x01, 0), b43_lcntab_0x01);
607 lcntab_upload(dev, B43_LCNTAB32(0x0b, 0), b43_lcntab_0x0b);
608 lcntab_upload(dev, B43_LCNTAB32(0x0c, 0), b43_lcntab_0x0c);
609 lcntab_upload(dev, B43_LCNTAB32(0x0d, 0), b43_lcntab_0x0d);
610 lcntab_upload(dev, B43_LCNTAB16(0x0e, 0), b43_lcntab_0x0e);
611 lcntab_upload(dev, B43_LCNTAB16(0x0f, 0), b43_lcntab_0x0f);
612 lcntab_upload(dev, B43_LCNTAB16(0x10, 0), b43_lcntab_0x10);
613 lcntab_upload(dev, B43_LCNTAB16(0x11, 0), b43_lcntab_0x11);
614 lcntab_upload(dev, B43_LCNTAB32(0x12, 0), b43_lcntab_0x12);
615 lcntab_upload(dev, B43_LCNTAB16(0x14, 0), b43_lcntab_0x14);
616 lcntab_upload(dev, B43_LCNTAB16(0x17, 0), b43_lcntab_0x17);
617 lcntab_upload(dev, B43_LCNTAB16(0x00, 0), b43_lcntab_0x00);
618 lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18);
619 }
620
b43_phy_lcn_load_tx_gain_tab(struct b43_wldev * dev,const struct b43_lcntab_tx_gain_tbl_entry * gain_table)621 static void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev,
622 const struct b43_lcntab_tx_gain_tbl_entry *gain_table)
623 {
624 u32 i;
625 u32 val;
626
627 u16 pa_gain = 0x70;
628 if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM)
629 pa_gain = 0x10;
630
631 for (i = 0; i < B43_LCNTAB_TX_GAIN_SIZE; i++) {
632 val = ((pa_gain << 24) |
633 (gain_table[i].pad << 16) |
634 (gain_table[i].pga << 8) |
635 gain_table[i].gm);
636 b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0xc0 + i), val);
637
638 /* brcmsmac doesn't maskset, we follow newer wl here */
639 val = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i));
640 val &= 0x000fffff;
641 val |= ((gain_table[i].dac << 28) |
642 (gain_table[i].bb_mult << 20));
643 b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x140 + i), val);
644 }
645 }
646
647 /* wlc_lcnphy_load_rfpower */
b43_phy_lcn_load_rfpower(struct b43_wldev * dev)648 static void b43_phy_lcn_load_rfpower(struct b43_wldev *dev)
649 {
650 u32 bbmult, rfgain;
651 u8 i;
652
653 for (i = 0; i < 128; i++) {
654 bbmult = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i));
655 bbmult >>= 20;
656 rfgain = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0xc0 + i));
657
658 /* TODO: calculate value for 0x240 + i table offset
659 * b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), val);
660 */
661 }
662 }
663
664 /* Not implemented in brcmsmac, noticed in wl in MMIO dump */
b43_phy_lcn_rewrite_rfpower_table(struct b43_wldev * dev)665 static void b43_phy_lcn_rewrite_rfpower_table(struct b43_wldev *dev)
666 {
667 int i;
668 u32 tmp;
669 for (i = 0; i < 128; i++) {
670 tmp = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x240 + i));
671 b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), tmp);
672 }
673 }
674
675 /* wlc_lcnphy_clear_papd_comptable */
b43_phy_lcn_clean_papd_comp_table(struct b43_wldev * dev)676 static void b43_phy_lcn_clean_papd_comp_table(struct b43_wldev *dev)
677 {
678 u8 i;
679
680 for (i = 0; i < 0x80; i++)
681 b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000);
682 }
683
684 /* wlc_lcnphy_tbl_init */
b43_phy_lcn_tables_init(struct b43_wldev * dev)685 void b43_phy_lcn_tables_init(struct b43_wldev *dev)
686 {
687 struct ssb_sprom *sprom = dev->dev->bus_sprom;
688
689 b43_phy_lcn_upload_static_tables(dev);
690
691 if (b43_current_band(dev->wl) == NL80211_BAND_2GHZ) {
692 if (sprom->boardflags_lo & B43_BFL_FEM)
693 b43_phy_lcn_load_tx_gain_tab(dev,
694 b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0);
695 else
696 b43err(dev->wl,
697 "TX gain table unknown for this card\n");
698 }
699
700 if (sprom->boardflags_lo & B43_BFL_FEM &&
701 !(sprom->boardflags_hi & B43_BFH_FEM_BT))
702 b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0),
703 ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0),
704 b43_lcntab_sw_ctl_4313_epa_rev0);
705 else
706 b43err(dev->wl, "SW ctl table is unknown for this card\n");
707
708 b43_phy_lcn_load_rfpower(dev);
709 b43_phy_lcn_rewrite_rfpower_table(dev);
710 b43_phy_lcn_clean_papd_comp_table(dev);
711 }
712