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 */
29static 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 */
71static 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
331void 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
351const 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