Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / net / wireless / broadcom / b43 / tables_phy_lcn.c
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
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
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
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
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)
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
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 */
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 */
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 */
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 */
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 }