1 /*
2 
3   Broadcom B43 wireless driver
4   IEEE 802.11n 2059 radio device 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 "radio_2059.h"
27 
28 /* Extracted from MMIO dump of 6.30.223.141 */
29 static u16 r2059_phy_rev1_init[][2] = {
30 	{ 0x051, 0x70 }, { 0x05a, 0x03 }, { 0x079, 0x01 }, { 0x082, 0x70 },
31 	{ 0x083, 0x00 }, { 0x084, 0x70 }, { 0x09a, 0x7f }, { 0x0b6, 0x10 },
32 	{ 0x188, 0x05 },
33 };
34 
35 #define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
36 		  r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
37 		  r20) \
38 	.radio_syn16			= r00,	\
39 	.radio_syn17			= r01,	\
40 	.radio_syn22			= r02,	\
41 	.radio_syn25			= r03,	\
42 	.radio_syn27			= r04,	\
43 	.radio_syn28			= r05,	\
44 	.radio_syn29			= r06,	\
45 	.radio_syn2c			= r07,	\
46 	.radio_syn2d			= r08,	\
47 	.radio_syn37			= r09,	\
48 	.radio_syn41			= r10,	\
49 	.radio_syn43			= r11,	\
50 	.radio_syn47			= r12,	\
51 	.radio_rxtx4a			= r13,	\
52 	.radio_rxtx58			= r14,	\
53 	.radio_rxtx5a			= r15,	\
54 	.radio_rxtx6a			= r16,	\
55 	.radio_rxtx6d			= r17,	\
56 	.radio_rxtx6e			= r18,	\
57 	.radio_rxtx92			= r19,	\
58 	.radio_rxtx98			= r20
59 
60 #define PHYREGS(r0, r1, r2, r3, r4, r5)	\
61 	.phy_regs.bw1	= r0,	\
62 	.phy_regs.bw2	= r1,	\
63 	.phy_regs.bw3	= r2,	\
64 	.phy_regs.bw4	= r3,	\
65 	.phy_regs.bw5	= r4,	\
66 	.phy_regs.bw6	= r5
67 
68 /* Extracted from MMIO dump of 6.30.223.141
69  * TODO: Values for channels 12 & 13 are outdated (from some old 5.x driver)!
70  */
71 static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = {
72 	{
73 		.freq			= 2412,
74 		RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
75 			  0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73,
76 			  0x00, 0x00, 0x00, 0xd0, 0x00),
77 		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
78 	},
79 	{
80 		.freq			= 2417,
81 		RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
82 			  0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73,
83 			  0x00, 0x00, 0x00, 0xd0, 0x00),
84 		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
85 	},
86 	{
87 		.freq			= 2422,
88 		RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
89 			  0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x73,
90 			  0x00, 0x00, 0x00, 0xd0, 0x00),
91 		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
92 	},
93 	{
94 		.freq			= 2427,
95 		RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
96 			  0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x73,
97 			  0x00, 0x00, 0x00, 0xa0, 0x00),
98 		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
99 	},
100 	{
101 		.freq			= 2432,
102 		RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
103 			  0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x73,
104 			  0x00, 0x00, 0x00, 0xa0, 0x00),
105 		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
106 	},
107 	{
108 		.freq			= 2437,
109 		RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
110 			  0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x73,
111 			  0x00, 0x00, 0x00, 0xa0, 0x00),
112 		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
113 	},
114 	{
115 		.freq			= 2442,
116 		RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
117 			  0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73,
118 			  0x00, 0x00, 0x00, 0x80, 0x00),
119 		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
120 	},
121 	{
122 		.freq			= 2447,
123 		RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
124 			  0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73,
125 			  0x00, 0x00, 0x00, 0x80, 0x00),
126 		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
127 	},
128 	{
129 		.freq			= 2452,
130 		RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
131 			  0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73,
132 			  0x00, 0x00, 0x00, 0x80, 0x00),
133 		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
134 	},
135 	{
136 		.freq			= 2457,
137 		RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
138 			  0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x73,
139 			  0x00, 0x00, 0x00, 0x60, 0x00),
140 		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
141 	},
142 	{
143 		.freq			= 2462,
144 		RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
145 			  0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x73,
146 			  0x00, 0x00, 0x00, 0x60, 0x00),
147 		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
148 	},
149   {	.freq			= 2467,
150 	RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
151 		  0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
152 		  0x00, 0x00, 0x00, 0xf0, 0x00),
153 	PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
154   },
155   {	.freq			= 2472,
156 	RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
157 		  0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
158 		  0x00, 0x00, 0x00, 0xf0, 0x00),
159 	PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
160   },
161 	{
162 		.freq			= 5180,
163 		RADIOREGS(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
164 			  0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00,
165 			  0x0f, 0x4f, 0xa3, 0x00, 0xfc),
166 		PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
167 	},
168 	{
169 		.freq			= 5200,
170 		RADIOREGS(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
171 			  0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00,
172 			  0x0f, 0x4f, 0x93, 0x00, 0xfb),
173 		PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
174 	},
175 	{
176 		.freq			= 5220,
177 		RADIOREGS(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
178 			  0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00,
179 			  0x0f, 0x4f, 0x93, 0x00, 0xea),
180 		PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
181 	},
182 	{
183 		.freq			= 5240,
184 		RADIOREGS(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
185 			  0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00,
186 			  0x0f, 0x4f, 0x93, 0x00, 0xda),
187 		PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
188 	},
189 	{
190 		.freq			= 5260,
191 		RADIOREGS(0xd9, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0e,
192 			  0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00,
193 			  0x0f, 0x4f, 0x93, 0x00, 0xca),
194 		PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
195 	},
196 	{
197 		.freq			= 5280,
198 		RADIOREGS(0xe0, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x10,
199 			  0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00,
200 			  0x0f, 0x4f, 0x93, 0x00, 0xb9),
201 		PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
202 	},
203 	{
204 		.freq			= 5300,
205 		RADIOREGS(0xe6, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x12,
206 			  0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00,
207 			  0x0f, 0x4c, 0x83, 0x00, 0xb8),
208 		PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
209 	},
210 	{
211 		.freq			= 5320,
212 		RADIOREGS(0xed, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x14,
213 			  0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00,
214 			  0x0f, 0x4c, 0x83, 0x00, 0xa8),
215 		PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
216 	},
217 	{
218 		.freq			= 5500,
219 		RADIOREGS(0x29, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x26,
220 			  0x02, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00,
221 			  0x0a, 0x46, 0x43, 0x00, 0x75),
222 		PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
223 	},
224 	{
225 		.freq			= 5520,
226 		RADIOREGS(0x30, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x28,
227 			  0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
228 			  0x0a, 0x46, 0x43, 0x00, 0x75),
229 		PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
230 	},
231 	{
232 		.freq			= 5540,
233 		RADIOREGS(0x36, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2a,
234 			  0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
235 			  0x0a, 0x46, 0x43, 0x00, 0x75),
236 		PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
237 	},
238 	{
239 		.freq			= 5560,
240 		RADIOREGS(0x3d, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2c,
241 			  0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
242 			  0x0a, 0x46, 0x43, 0x00, 0x75),
243 		PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
244 	},
245 	{
246 		.freq			= 5580,
247 		RADIOREGS(0x44, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2e,
248 			  0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
249 			  0x0a, 0x46, 0x43, 0x00, 0x74),
250 		PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
251 	},
252 	{
253 		.freq			= 5600,
254 		RADIOREGS(0x4a, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x30,
255 			  0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
256 			  0x09, 0x44, 0x23, 0x00, 0x54),
257 		PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
258 	},
259 	{
260 		.freq			= 5620,
261 		RADIOREGS(0x51, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x32,
262 			  0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
263 			  0x09, 0x44, 0x23, 0x00, 0x54),
264 		PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
265 	},
266 	{
267 		.freq			= 5640,
268 		RADIOREGS(0x58, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x34,
269 			  0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
270 			  0x09, 0x44, 0x23, 0x00, 0x43),
271 		PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
272 	},
273 	{
274 		.freq			= 5660,
275 		RADIOREGS(0x5e, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x36,
276 			  0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
277 			  0x09, 0x43, 0x23, 0x00, 0x43),
278 		PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
279 	},
280 	{
281 		.freq			= 5680,
282 		RADIOREGS(0x65, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x38,
283 			  0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
284 			  0x09, 0x42, 0x23, 0x00, 0x43),
285 		PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
286 	},
287 	{
288 		.freq			= 5700,
289 		RADIOREGS(0x6c, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x3a,
290 			  0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
291 			  0x08, 0x42, 0x13, 0x00, 0x32),
292 		PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
293 	},
294 	{
295 		.freq			= 5745,
296 		RADIOREGS(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
297 			  0x04, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00,
298 			  0x08, 0x42, 0x13, 0x00, 0x21),
299 		PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
300 	},
301 	{
302 		.freq			= 5765,
303 		RADIOREGS(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
304 			  0x04, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00,
305 			  0x08, 0x42, 0x13, 0x00, 0x11),
306 		PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
307 	},
308 	{
309 		.freq			= 5785,
310 		RADIOREGS(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
311 			  0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00,
312 			  0x08, 0x42, 0x13, 0x00, 0x00),
313 		PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
314 	},
315 	{
316 		.freq			= 5805,
317 		RADIOREGS(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
318 			  0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00,
319 			  0x06, 0x41, 0x03, 0x00, 0x00),
320 		PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
321 	},
322 	{
323 		.freq			= 5825,
324 		RADIOREGS(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
325 			  0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00,
326 			  0x06, 0x41, 0x03, 0x00, 0x00),
327 		PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
328 	},
329 };
330 
331 void r2059_upload_inittabs(struct b43_wldev *dev)
332 {
333 	struct b43_phy *phy = &dev->phy;
334 	u16 *table = NULL;
335 	u16 size, i;
336 
337 	switch (phy->rev) {
338 	case 1:
339 		table = r2059_phy_rev1_init[0];
340 		size = ARRAY_SIZE(r2059_phy_rev1_init);
341 		break;
342 	default:
343 		B43_WARN_ON(1);
344 		return;
345 	}
346 
347 	for (i = 0; i < size; i++, table += 2)
348 		b43_radio_write(dev, R2059_ALL | table[0], table[1]);
349 }
350 
351 const struct b43_phy_ht_channeltab_e_radio2059
352 *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq)
353 {
354 	const struct b43_phy_ht_channeltab_e_radio2059 *e;
355 	unsigned int i;
356 
357 	e = b43_phy_ht_channeltab_radio2059;
358 	for (i = 0; i < ARRAY_SIZE(b43_phy_ht_channeltab_radio2059); i++, e++) {
359 		if (e->freq == freq)
360 			return e;
361 	}
362 
363 	return NULL;
364 }
365