1682ba0a41075c349aa3e67e655a8decd0cf1917
[pandora-kernel.git] / drivers / net / wireless / b43 / tables_phy_lcn.c
1 /*
2
3   Broadcom B43 wireless driver
4   IEEE 802.11n LCN-PHY data tables
5
6   Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; see the file COPYING.  If not, write to
20   the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
21   Boston, MA 02110-1301, USA.
22
23 */
24
25 #include "b43.h"
26 #include "tables_phy_lcn.h"
27 #include "phy_common.h"
28 #include "phy_lcn.h"
29
30 static const u16 b43_lcntab_0x02[] = {
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, 0x014d, 0x014d,
41         0x014d, 0x014d, 0x014d, 0x014d,
42 };
43
44 static const u16 b43_lcntab_0x01[] = {
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, 0x0000, 0x0000,
55         0x0000, 0x0000, 0x0000, 0x0000,
56 };
57
58 static const u32 b43_lcntab_0x0b[] = {
59         0x000141f8, 0x000021f8, 0x000021fb, 0x000041fb,
60         0x0001fedb, 0x0000217b, 0x00002133, 0x000040eb,
61         0x0001fea3, 0x0000024b,
62 };
63
64 static const u32 b43_lcntab_0x0c[] = {
65         0x00100001, 0x00200010, 0x00300001, 0x00400010,
66         0x00500022, 0x00600122, 0x00700222, 0x00800322,
67         0x00900422, 0x00a00522, 0x00b00622, 0x00c00722,
68         0x00d00822, 0x00f00922, 0x00100a22, 0x00200b22,
69         0x00300c22, 0x00400d22, 0x00500e22, 0x00600f22,
70 };
71
72 static const u32 b43_lcntab_0x0d[] = {
73         0x00000000, 0x00000000, 0x10000000, 0x00000000,
74         0x20000000, 0x00000000, 0x30000000, 0x00000000,
75         0x40000000, 0x00000000, 0x50000000, 0x00000000,
76         0x60000000, 0x00000000, 0x70000000, 0x00000000,
77         0x80000000, 0x00000000, 0x90000000, 0x00000008,
78         0xa0000000, 0x00000008, 0xb0000000, 0x00000008,
79         0xc0000000, 0x00000008, 0xd0000000, 0x00000008,
80         0xe0000000, 0x00000008, 0xf0000000, 0x00000008,
81         0x00000000, 0x00000009, 0x10000000, 0x00000009,
82         0x20000000, 0x00000019, 0x30000000, 0x00000019,
83         0x40000000, 0x00000019, 0x50000000, 0x00000019,
84         0x60000000, 0x00000019, 0x70000000, 0x00000019,
85         0x80000000, 0x00000019, 0x90000000, 0x00000019,
86         0xa0000000, 0x00000019, 0xb0000000, 0x00000019,
87         0xc0000000, 0x00000019, 0xd0000000, 0x00000019,
88         0xe0000000, 0x00000019, 0xf0000000, 0x00000019,
89         0x00000000, 0x0000001a, 0x10000000, 0x0000001a,
90         0x20000000, 0x0000001a, 0x30000000, 0x0000001a,
91         0x40000000, 0x0000001a, 0x50000000, 0x00000002,
92         0x60000000, 0x00000002, 0x70000000, 0x00000002,
93         0x80000000, 0x00000002, 0x90000000, 0x00000002,
94         0xa0000000, 0x00000002, 0xb0000000, 0x00000002,
95         0xc0000000, 0x0000000a, 0xd0000000, 0x0000000a,
96         0xe0000000, 0x0000000a, 0xf0000000, 0x0000000a,
97         0x00000000, 0x0000000b, 0x10000000, 0x0000000b,
98         0x20000000, 0x0000000b, 0x30000000, 0x0000000b,
99         0x40000000, 0x0000000b, 0x50000000, 0x0000001b,
100         0x60000000, 0x0000001b, 0x70000000, 0x0000001b,
101         0x80000000, 0x0000001b, 0x90000000, 0x0000001b,
102         0xa0000000, 0x0000001b, 0xb0000000, 0x0000001b,
103         0xc0000000, 0x0000001b, 0xd0000000, 0x0000001b,
104         0xe0000000, 0x0000001b, 0xf0000000, 0x0000001b,
105         0x00000000, 0x0000001c, 0x10000000, 0x0000001c,
106         0x20000000, 0x0000001c, 0x30000000, 0x0000001c,
107         0x40000000, 0x0000001c, 0x50000000, 0x0000001c,
108         0x60000000, 0x0000001c, 0x70000000, 0x0000001c,
109         0x80000000, 0x0000001c, 0x90000000, 0x0000001c,
110 };
111
112 static const u16 b43_lcntab_0x0e[] = {
113         0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
114         0x0407, 0x0408, 0x0409, 0x040a, 0x058b, 0x058c,
115         0x058d, 0x058e, 0x058f, 0x0090, 0x0091, 0x0092,
116         0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0198,
117         0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e,
118         0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4,
119         0x01a5, 0x0000,
120 };
121
122 static const u16 b43_lcntab_0x0f[] = {
123         0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
124         0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
125         0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
126         0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
127         0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
128         0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
129         0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
130         0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
131         0x000a, 0x0009, 0x0006, 0x0005, 0x000a, 0x0009,
132         0x0006, 0x0005, 0x000a, 0x0009, 0x0006, 0x0005,
133         0x000a, 0x0009, 0x0006, 0x0005,
134 };
135
136 static const u16 b43_lcntab_0x10[] = {
137         0x005f, 0x0036, 0x0029, 0x001f, 0x005f, 0x0036,
138         0x0029, 0x001f, 0x005f, 0x0036, 0x0029, 0x001f,
139         0x005f, 0x0036, 0x0029, 0x001f,
140 };
141
142 static const u16 b43_lcntab_0x11[] = {
143         0x0009, 0x000f, 0x0014, 0x0018, 0x00fe, 0x0007,
144         0x000b, 0x000f, 0x00fb, 0x00fe, 0x0001, 0x0005,
145         0x0008, 0x000b, 0x000e, 0x0011, 0x0014, 0x0017,
146         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
147         0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f,
148         0x0012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
149         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003,
150         0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015,
151         0x0018, 0x001b, 0x0000, 0x0000, 0x0000, 0x0000,
152         0x0000, 0x0000, 0x0003, 0x00eb, 0x0000, 0x0000,
153 };
154
155 static const u32 b43_lcntab_0x12[] = {
156         0x00000000, 0x00000000, 0x00000000, 0x00000000,
157         0x00000000, 0x00000000, 0x00000000, 0x00000000,
158         0x00000004, 0x00000000, 0x00000004, 0x00000008,
159         0x00000001, 0x00000005, 0x00000009, 0x0000000d,
160         0x0000004d, 0x0000008d, 0x0000000d, 0x0000004d,
161         0x0000008d, 0x000000cd, 0x0000004f, 0x0000008f,
162         0x000000cf, 0x000000d3, 0x00000113, 0x00000513,
163         0x00000913, 0x00000953, 0x00000d53, 0x00001153,
164         0x00001193, 0x00005193, 0x00009193, 0x0000d193,
165         0x00011193, 0x00000000, 0x00000000, 0x00000000,
166         0x00000000, 0x00000000, 0x00000000, 0x00000004,
167         0x00000000, 0x00000004, 0x00000008, 0x00000001,
168         0x00000005, 0x00000009, 0x0000000d, 0x0000004d,
169         0x0000008d, 0x0000000d, 0x0000004d, 0x0000008d,
170         0x000000cd, 0x0000004f, 0x0000008f, 0x000000cf,
171         0x000000d3, 0x00000113, 0x00000513, 0x00000913,
172         0x00000953, 0x00000d53, 0x00001153, 0x00005153,
173         0x00009153, 0x0000d153, 0x00011153, 0x00015153,
174         0x00019153, 0x0001d153, 0x00000000, 0x00000000,
175         0x00000000, 0x00000000, 0x00000000, 0x00000000,
176         0x00000000, 0x00000000, 0x00000000, 0x00000000,
177         0x00000000, 0x00000000, 0x00000000, 0x00000000,
178         0x00000000, 0x00000000, 0x00000000, 0x00000000,
179         0x00000000, 0x00000000, 0x00000000, 0x00000000,
180 };
181
182 static const u16 b43_lcntab_0x14[] = {
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         0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
188         0x0002, 0x0003, 0x0001, 0x0003, 0x0002, 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, 0x0001, 0x0001,
198         0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003,
199         0x0001, 0x0003, 0x0002, 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, 0x0001, 0x0001, 0x0001, 0x0001,
204         0x0001, 0x0001,
205 };
206
207 static const u16 b43_lcntab_0x17[] = {
208         0x001a, 0x0034, 0x004e, 0x0068, 0x009c, 0x00d0,
209         0x00ea, 0x0104, 0x0034, 0x0068, 0x009c, 0x00d0,
210         0x0138, 0x01a0, 0x01d4, 0x0208, 0x004e, 0x009c,
211         0x00ea, 0x0138, 0x01d4, 0x0270, 0x02be, 0x030c,
212         0x0068, 0x00d0, 0x0138, 0x01a0, 0x0270, 0x0340,
213         0x03a8, 0x0410, 0x0018, 0x009c, 0x00d0, 0x0104,
214         0x00ea, 0x0138, 0x0186, 0x00d0, 0x0104, 0x0104,
215         0x0138, 0x016c, 0x016c, 0x01a0, 0x0138, 0x0186,
216         0x0186, 0x01d4, 0x0222, 0x0222, 0x0270, 0x0104,
217         0x0138, 0x016c, 0x0138, 0x016c, 0x01a0, 0x01d4,
218         0x01a0, 0x01d4, 0x0208, 0x0208, 0x023c, 0x0186,
219         0x01d4, 0x0222, 0x01d4, 0x0222, 0x0270, 0x02be,
220         0x0270, 0x02be, 0x030c, 0x030c, 0x035a, 0x0036,
221         0x006c, 0x00a2, 0x00d8, 0x0144, 0x01b0, 0x01e6,
222         0x021c, 0x006c, 0x00d8, 0x0144, 0x01b0, 0x0288,
223         0x0360, 0x03cc, 0x0438, 0x00a2, 0x0144, 0x01e6,
224         0x0288, 0x03cc, 0x0510, 0x05b2, 0x0654, 0x00d8,
225         0x01b0, 0x0288, 0x0360, 0x0510, 0x06c0, 0x0798,
226         0x0870, 0x0018, 0x0144, 0x01b0, 0x021c, 0x01e6,
227         0x0288, 0x032a, 0x01b0, 0x021c, 0x021c, 0x0288,
228         0x02f4, 0x02f4, 0x0360, 0x0288, 0x032a, 0x032a,
229         0x03cc, 0x046e, 0x046e, 0x0510, 0x021c, 0x0288,
230         0x02f4, 0x0288, 0x02f4, 0x0360, 0x03cc, 0x0360,
231         0x03cc, 0x0438, 0x0438, 0x04a4, 0x032a, 0x03cc,
232         0x046e, 0x03cc, 0x046e, 0x0510, 0x05b2, 0x0510,
233         0x05b2, 0x0654, 0x0654, 0x06f6,
234 };
235
236 static const u16 b43_lcntab_0x00[] = {
237         0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00,
238         0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005,
239         0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
240         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
241         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
242         0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
243         0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003,
244         0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007,
245         0x2d07, 0x4007, 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, 0x0000, 0x0000, 0x0000,
251         0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
252         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
253         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
254         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
255 };
256
257 static const u32 b43_lcntab_0x18[] = {
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         0x00080000, 0x00080000, 0x00080000, 0x00080000,
298 };
299
300 const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = {
301         0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
302         0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
303         0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
304         0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
305         0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
306         0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
307         0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
308         0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
309         0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
310         0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
311         0x0002, 0x0008, 0x0004, 0x0001,
312 };
313
314 /**************************************************
315  * R/W ops.
316  **************************************************/
317
318 u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset)
319 {
320         u32 type, value;
321
322         type = offset & B43_LCNTAB_TYPEMASK;
323         offset &= ~B43_LCNTAB_TYPEMASK;
324         B43_WARN_ON(offset > 0xFFFF);
325
326         switch (type) {
327         case B43_LCNTAB_8BIT:
328                 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
329                 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO) & 0xFF;
330                 break;
331         case B43_LCNTAB_16BIT:
332                 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
333                 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
334                 break;
335         case B43_LCNTAB_32BIT:
336                 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
337                 value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
338                 value |= (b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI) << 16);
339                 break;
340         default:
341                 B43_WARN_ON(1);
342                 value = 0;
343         }
344
345         return value;
346 }
347
348 void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset,
349                           unsigned int nr_elements, void *_data)
350 {
351         u32 type;
352         u8 *data = _data;
353         unsigned int i;
354
355         type = offset & B43_LCNTAB_TYPEMASK;
356         offset &= ~B43_LCNTAB_TYPEMASK;
357         B43_WARN_ON(offset > 0xFFFF);
358
359         b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
360
361         for (i = 0; i < nr_elements; i++) {
362                 switch (type) {
363                 case B43_LCNTAB_8BIT:
364                         *data = b43_phy_read(dev,
365                                              B43_PHY_LCN_TABLE_DATALO) & 0xFF;
366                         data++;
367                         break;
368                 case B43_LCNTAB_16BIT:
369                         *((u16 *)data) = b43_phy_read(dev,
370                                                       B43_PHY_LCN_TABLE_DATALO);
371                         data += 2;
372                         break;
373                 case B43_LCNTAB_32BIT:
374                         *((u32 *)data) = b43_phy_read(dev,
375                                                 B43_PHY_LCN_TABLE_DATALO);
376                         *((u32 *)data) |= (b43_phy_read(dev,
377                                            B43_PHY_LCN_TABLE_DATAHI) << 16);
378                         data += 4;
379                         break;
380                 default:
381                         B43_WARN_ON(1);
382                 }
383         }
384 }
385
386 void b43_lcntab_write(struct b43_wldev *dev, u32 offset, u32 value)
387 {
388         u32 type;
389
390         type = offset & B43_LCNTAB_TYPEMASK;
391         offset &= 0xFFFF;
392
393         switch (type) {
394         case B43_LCNTAB_8BIT:
395                 B43_WARN_ON(value & ~0xFF);
396                 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
397                 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
398                 break;
399         case B43_LCNTAB_16BIT:
400                 B43_WARN_ON(value & ~0xFFFF);
401                 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
402                 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
403                 break;
404         case B43_LCNTAB_32BIT:
405                 b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
406                 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, value >> 16);
407                 b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value & 0xFFFF);
408                 break;
409         default:
410                 B43_WARN_ON(1);
411         }
412
413         return;
414 }
415
416 void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset,
417                            unsigned int nr_elements, const void *_data)
418 {
419         u32 type, value;
420         const u8 *data = _data;
421         unsigned int i;
422
423         type = offset & B43_LCNTAB_TYPEMASK;
424         offset &= ~B43_LCNTAB_TYPEMASK;
425         B43_WARN_ON(offset > 0xFFFF);
426
427         b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
428
429         for (i = 0; i < nr_elements; i++) {
430                 switch (type) {
431                 case B43_LCNTAB_8BIT:
432                         value = *data;
433                         data++;
434                         B43_WARN_ON(value & ~0xFF);
435                         b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
436                         break;
437                 case B43_LCNTAB_16BIT:
438                         value = *((u16 *)data);
439                         data += 2;
440                         B43_WARN_ON(value & ~0xFFFF);
441                         b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, value);
442                         break;
443                 case B43_LCNTAB_32BIT:
444                         value = *((u32 *)data);
445                         data += 4;
446                         b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI,
447                                       value >> 16);
448                         b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO,
449                                       value & 0xFFFF);
450                         break;
451                 default:
452                         B43_WARN_ON(1);
453                 }
454         }
455 }
456
457 /**************************************************
458  * Tables ops.
459  **************************************************/
460
461 #define lcntab_upload(dev, offset, data) do { \
462                 b43_lcntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
463         } while (0)
464 static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev)
465 {
466         lcntab_upload(dev, B43_LCNTAB16(0x02, 0), b43_lcntab_0x02);
467         lcntab_upload(dev, B43_LCNTAB16(0x01, 0), b43_lcntab_0x01);
468         lcntab_upload(dev, B43_LCNTAB32(0x0b, 0), b43_lcntab_0x0b);
469         lcntab_upload(dev, B43_LCNTAB32(0x0c, 0), b43_lcntab_0x0c);
470         lcntab_upload(dev, B43_LCNTAB32(0x0d, 0), b43_lcntab_0x0d);
471         lcntab_upload(dev, B43_LCNTAB16(0x0e, 0), b43_lcntab_0x0e);
472         lcntab_upload(dev, B43_LCNTAB16(0x0f, 0), b43_lcntab_0x0f);
473         lcntab_upload(dev, B43_LCNTAB16(0x10, 0), b43_lcntab_0x10);
474         lcntab_upload(dev, B43_LCNTAB16(0x11, 0), b43_lcntab_0x11);
475         lcntab_upload(dev, B43_LCNTAB32(0x12, 0), b43_lcntab_0x12);
476         lcntab_upload(dev, B43_LCNTAB16(0x14, 0), b43_lcntab_0x14);
477         lcntab_upload(dev, B43_LCNTAB16(0x17, 0), b43_lcntab_0x17);
478         lcntab_upload(dev, B43_LCNTAB16(0x00, 0), b43_lcntab_0x00);
479         lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18);
480 }
481
482 /* Not implemented in brcmsmac, noticed in wl in MMIO dump */
483 static void b43_phy_lcn_rewrite_tables(struct b43_wldev *dev)
484 {
485         int i;
486         u32 tmp;
487         for (i = 0; i < 128; i++) {
488                 tmp = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x240 + i));
489                 b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), tmp);
490         }
491 }
492
493 /* wlc_lcnphy_clear_papd_comptable */
494 static void b43_phy_lcn_clean_papd_comp_table(struct b43_wldev *dev)
495 {
496         u8 i;
497
498         for (i = 0; i < 0x80; i++)
499                 b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000);
500 }
501
502 void b43_phy_lcn_tables_init(struct b43_wldev *dev)
503 {
504         b43_phy_lcn_upload_static_tables(dev);
505         /* TODO: various tables ops here */
506
507         if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM &&
508             !(dev->dev->bus_sprom->boardflags_hi & B43_BFH_FEM_BT))
509                 b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0),
510                         ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0),
511                         b43_lcntab_sw_ctl_4313_epa_rev0);
512         else
513                 b43err(dev->wl, "SW ctl table is unknown for this card\n");
514
515         /* TODO: various tables ops here */
516         b43_phy_lcn_rewrite_tables(dev);
517         b43_phy_lcn_clean_papd_comp_table(dev);
518 }