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
17struct 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
29static 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
43static 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
57static const u32 b43_lcntab_0x0b[] = {
58	0x000141f8, 0x000021f8, 0x000021fb, 0x000041fb,
59	0x0001fedb, 0x0000217b, 0x00002133, 0x000040eb,
60	0x0001fea3, 0x0000024b,
61};
62
63static 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
71static 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
111static 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
121static 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
135static 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
141static 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
154static 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
181static 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
206static 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
235static 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
256static 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
303static 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
439static 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
457u32 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
487void 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
525void 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
555void 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)
603static 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
621static 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 */
648static 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 */
665static 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 */
676static 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 */
685void 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