1/*
2
3  Broadcom B43 wireless driver
4  IEEE 802.11n 2057 radio device data tables
5
6  Copyright (c) 2010 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_2057.h"
27#include "phy_common.h"
28
29static u16 r2057_rev4_init[][2] = {
30	{ 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
31	{ 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
32	{ 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
33	{ 0x8C, 0xf0 }, { 0x91, 0x3f }, { 0x92, 0x36 }, { 0xA4, 0x8c },
34	{ 0xA8, 0x55 }, { 0xAF, 0x01 }, { 0x10F, 0xf0 }, { 0x110, 0x10 },
35	{ 0x111, 0xf0 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x129, 0x8c },
36	{ 0x12D, 0x55 }, { 0x134, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 },
37	{ 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 },
38	{ 0x169, 0x02 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 },
39	{ 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 },
40	{ 0x1AB, 0x00 }, { 0x1AC, 0x00 },
41};
42
43static u16 r2057_rev5_init[][2] = {
44	{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
45	{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
46	{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
47	{ 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
48	{ 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 },
49	{ 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f },
50	{ 0x117, 0x36 }, { 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 },
51	{ 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 },
52	{ 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 },
53	{ 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 },
54	{ 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
55};
56
57static u16 r2057_rev5a_init[][2] = {
58	{ 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
59	{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
60	{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
61	{ 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
62	{ 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 },
63	{ 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f },
64	{ 0x117, 0x36 }, { 0x126, 0x20 }, { 0x14E, 0x01 }, { 0x15E, 0x00 },
65	{ 0x15F, 0x00 }, { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 },
66	{ 0x163, 0x00 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 },
67	{ 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 },
68	{ 0x1AB, 0x00 }, { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 },
69	{ 0x1C2, 0x80 },
70};
71
72static u16 r2057_rev7_init[][2] = {
73	{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
74	{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
75	{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
76	{ 0x66, 0xee }, { 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 },
77	{ 0x7C, 0x14 }, { 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f },
78	{ 0x92, 0x36 }, { 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 },
79	{ 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x13 }, { 0xEB, 0xee },
80	{ 0xF3, 0x58 }, { 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x14 },
81	{ 0x102, 0xee }, { 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 },
82	{ 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 },
83	{ 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 },
84	{ 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 },
85	{ 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
86	{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
87};
88
89/* TODO: Which devices should use it?
90static u16 r2057_rev8_init[][2] = {
91	{ 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
92	{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
93	{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
94	{ 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 }, { 0x7C, 0x0f },
95	{ 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
96	{ 0xA1, 0x20 }, { 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 },
97	{ 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0xF3, 0x58 },
98	{ 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x0f }, { 0x102, 0xee },
99	{ 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x126, 0x20 },
100	{ 0x14E, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 },
101	{ 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 },
102	{ 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 },
103	{ 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
104	{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
105};
106*/
107
108/* Extracted from MMIO dump of 6.30.223.141 */
109static u16 r2057_rev9_init[][2] = {
110	{ 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f },
111	{ 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 },
112	{ 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 },
113	{ 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 },
114	{ 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff },
115	{ 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 },
116	{ 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 },
117	{ 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 },
118};
119
120/* Extracted from MMIO dump of 6.30.223.248 */
121static u16 r2057_rev14_init[][2] = {
122	{ 0x011, 0xfc }, { 0x030, 0x24 }, { 0x040, 0x1c }, { 0x082, 0x08 },
123	{ 0x0b4, 0x44 }, { 0x0c8, 0x01 }, { 0x0c9, 0x01 }, { 0x107, 0x08 },
124	{ 0x14d, 0x01 }, { 0x14e, 0x01 }, { 0x1af, 0x40 }, { 0x1b0, 0x40 },
125	{ 0x1cc, 0x01 }, { 0x1cf, 0x10 }, { 0x1d0, 0x0f }, { 0x1d3, 0x10 },
126	{ 0x1d4, 0x0f },
127};
128
129#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
130		   r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
131		   r20, r21, r22, r23, r24, r25, r26, r27) \
132	.radio_vcocal_countval0			= r00,	\
133	.radio_vcocal_countval1			= r01,	\
134	.radio_rfpll_refmaster_sparextalsize	= r02,	\
135	.radio_rfpll_loopfilter_r1		= r03,	\
136	.radio_rfpll_loopfilter_c2		= r04,	\
137	.radio_rfpll_loopfilter_c1		= r05,	\
138	.radio_cp_kpd_idac			= r06,	\
139	.radio_rfpll_mmd0			= r07,	\
140	.radio_rfpll_mmd1			= r08,	\
141	.radio_vcobuf_tune			= r09,	\
142	.radio_logen_mx2g_tune			= r10,	\
143	.radio_logen_mx5g_tune			= r11,	\
144	.radio_logen_indbuf2g_tune		= r12,	\
145	.radio_logen_indbuf5g_tune		= r13,	\
146	.radio_txmix2g_tune_boost_pu_core0	= r14,	\
147	.radio_pad2g_tune_pus_core0		= r15,	\
148	.radio_pga_boost_tune_core0		= r16,	\
149	.radio_txmix5g_boost_tune_core0		= r17,	\
150	.radio_pad5g_tune_misc_pus_core0	= r18,	\
151	.radio_lna2g_tune_core0			= r19,	\
152	.radio_lna5g_tune_core0			= r20,	\
153	.radio_txmix2g_tune_boost_pu_core1	= r21,	\
154	.radio_pad2g_tune_pus_core1		= r22,	\
155	.radio_pga_boost_tune_core1		= r23,	\
156	.radio_txmix5g_boost_tune_core1		= r24,	\
157	.radio_pad5g_tune_misc_pus_core1	= r25,	\
158	.radio_lna2g_tune_core1			= r26,	\
159	.radio_lna5g_tune_core1			= r27
160
161#define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
162		      r10, r11, r12, r13, r14, r15, r16, r17) \
163	.radio_vcocal_countval0			= r00,	\
164	.radio_vcocal_countval1			= r01,	\
165	.radio_rfpll_refmaster_sparextalsize	= r02,	\
166	.radio_rfpll_loopfilter_r1		= r03,	\
167	.radio_rfpll_loopfilter_c2		= r04,	\
168	.radio_rfpll_loopfilter_c1		= r05,	\
169	.radio_cp_kpd_idac			= r06,	\
170	.radio_rfpll_mmd0			= r07,	\
171	.radio_rfpll_mmd1			= r08,	\
172	.radio_vcobuf_tune			= r09,	\
173	.radio_logen_mx2g_tune			= r10,	\
174	.radio_logen_indbuf2g_tune		= r11,	\
175	.radio_txmix2g_tune_boost_pu_core0	= r12,	\
176	.radio_pad2g_tune_pus_core0		= r13,	\
177	.radio_lna2g_tune_core0			= r14,	\
178	.radio_txmix2g_tune_boost_pu_core1	= r15,	\
179	.radio_pad2g_tune_pus_core1		= r16,	\
180	.radio_lna2g_tune_core1			= r17
181
182#define PHYREGS(r0, r1, r2, r3, r4, r5)	\
183	.phy_regs.phy_bw1a	= r0,	\
184	.phy_regs.phy_bw2	= r1,	\
185	.phy_regs.phy_bw3	= r2,	\
186	.phy_regs.phy_bw4	= r3,	\
187	.phy_regs.phy_bw5	= r4,	\
188	.phy_regs.phy_bw6	= r5
189
190/* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */
191static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev8_radio_rev5[] = {
192	{
193		.freq			= 2412,
194		RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
195			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
196			      0x03, 0xff),
197		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
198	},
199	{
200		.freq			= 2417,
201		RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
202			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
203			      0x03, 0xff),
204		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
205	},
206	{
207		.freq			= 2422,
208		RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
209			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
210			      0x03, 0xef),
211		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
212	},
213	{
214		.freq			= 2427,
215		RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
216			      0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
217			      0x03, 0xdf),
218		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
219	},
220	{
221		.freq			= 2432,
222		RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
223			      0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
224			      0x03, 0xcf),
225		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
226	},
227	{
228		.freq			= 2437,
229		RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
230			      0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
231			      0x03, 0xbf),
232		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
233	},
234	{
235		.freq			= 2442,
236		RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
237			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
238			      0x03, 0xaf),
239		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
240	},
241	{
242		.freq			= 2447,
243		RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
244			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
245			      0x03, 0x9f),
246		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
247	},
248	{
249		.freq			= 2452,
250		RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
251			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
252			      0x03, 0x8f),
253		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
254	},
255	{
256		.freq			= 2457,
257		RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
258			      0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
259			      0x03, 0x7f),
260		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
261	},
262	{
263		.freq			= 2462,
264		RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
265			      0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
266			      0x03, 0x6f),
267		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
268	},
269	{
270		.freq			= 2467,
271		RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
272			      0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
273			      0x03, 0x5f),
274		PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
275	},
276	{
277		.freq			= 2472,
278		RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
279			      0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
280			      0x03, 0x4f),
281		PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
282	},
283	{
284		.freq			= 2484,
285		RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
286			      0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
287			      0x03, 0x3f),
288		PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
289	}
290};
291
292/* Extracted from MMIO dump of 6.30.223.248 */
293static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev17_radio_rev14[] = {
294	{
295		.freq			= 2412,
296		RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c,
297			      0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21,
298			      0x53, 0xff),
299		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
300	},
301	{
302		.freq			= 2417,
303		RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71,
304			      0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
305			      0x53, 0xff),
306		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
307	},
308	{
309		.freq			= 2422,
310		RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76,
311			      0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
312			      0x53, 0xff),
313		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
314	},
315	{
316		.freq			= 2427,
317		RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b,
318			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
319			      0x53, 0xff),
320		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
321	},
322	{
323		.freq			= 2432,
324		RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80,
325			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
326			      0x53, 0xff),
327		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
328	},
329	{
330		.freq			= 2437,
331		RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85,
332			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
333			      0x53, 0xff),
334		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
335	},
336	{
337		.freq			= 2442,
338		RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a,
339			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
340			      0x43, 0xff),
341		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
342	},
343	{
344		.freq			= 2447,
345		RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f,
346			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
347			      0x43, 0xff),
348		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
349	},
350	{
351		.freq			= 2452,
352		RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94,
353			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
354			      0x43, 0xff),
355		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
356	},
357	{
358		.freq			= 2457,
359		RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99,
360			      0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21,
361			      0x43, 0xff),
362		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
363	},
364	{
365		.freq			= 2462,
366		RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e,
367			      0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01,
368			      0x43, 0xff),
369		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
370	},
371};
372
373/* Extracted from MMIO dump of 6.30.223.141 */
374static const struct b43_nphy_chantabent_rev7 b43_nphy_chantab_phy_rev16_radio_rev9[] = {
375	{
376		.freq			= 2412,
377		RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
378			   0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
379			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
380			   0x00, 0x00, 0xf0, 0x00),
381		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
382	},
383	{
384		.freq			= 2417,
385		RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
386			   0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
387			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
388			   0x00, 0x00, 0xf0, 0x00),
389		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
390	},
391	{
392		.freq			= 2422,
393		RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
394			   0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
395			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
396			   0x00, 0x00, 0xf0, 0x00),
397		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
398	},
399	{
400		.freq			= 2427,
401		RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
402			   0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
403			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
404			   0x00, 0x00, 0xf0, 0x00),
405		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
406	},
407	{
408		.freq			= 2432,
409		RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
410			   0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
411			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
412			   0x00, 0x00, 0xf0, 0x00),
413		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
414	},
415	{
416		.freq			= 2437,
417		RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
418			   0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
419			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
420			   0x00, 0x00, 0xf0, 0x00),
421		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
422	},
423	{
424		.freq			= 2442,
425		RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
426			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
427			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
428			   0x00, 0x00, 0xf0, 0x00),
429		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
430	},
431	{
432		.freq			= 2447,
433		RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
434			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
435			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
436			   0x00, 0x00, 0xf0, 0x00),
437		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
438	},
439	{
440		.freq			= 2452,
441		RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
442			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
443			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
444			   0x00, 0x00, 0xf0, 0x00),
445		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
446	},
447	{
448		.freq			= 2457,
449		RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
450			   0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
451			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
452			   0x00, 0x00, 0xf0, 0x00),
453		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
454	},
455	{
456		.freq			= 2462,
457		RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
458			   0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
459			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
460			   0x00, 0x00, 0xf0, 0x00),
461		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
462	},
463	{
464		.freq			= 5180,
465		RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
466			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
467			   0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f,
468			   0x3a, 0x83, 0x00, 0xfc),
469		PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
470	},
471	{
472		.freq			= 5200,
473		RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
474			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
475			   0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c,
476			   0x4a, 0x83, 0x00, 0xf8),
477		PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
478	},
479	{
480		.freq			= 5220,
481		RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
482			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
483			   0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d,
484			   0x2a, 0x73, 0x00, 0xf8),
485		PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
486	},
487	{
488		.freq			= 5240,
489		RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
490			   0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00,
491			   0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d,
492			   0x2b, 0x73, 0x00, 0xf8),
493		PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
494	},
495	{
496		.freq			= 5745,
497		RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
498			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
499			   0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06,
500			   0x02, 0x03, 0x00, 0x30),
501		PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
502	},
503	{
504		.freq			= 5765,
505		RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
506			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
507			   0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
508			   0x02, 0x03, 0x00, 0x00),
509		PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
510	},
511	{
512		.freq			= 5785,
513		RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
514			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
515			   0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
516			   0x21, 0x03, 0x00, 0x00),
517		PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
518	},
519	{
520		.freq			= 5805,
521		RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
522			   0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
523			   0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
524			   0x00, 0x03, 0x00, 0x00),
525		PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
526	},
527	{
528		.freq			= 5825,
529		RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
530			   0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00,
531			   0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
532			   0x00, 0x03, 0x00, 0x00),
533		PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
534	},
535};
536
537void r2057_upload_inittabs(struct b43_wldev *dev)
538{
539	struct b43_phy *phy = &dev->phy;
540	u16 *table = NULL;
541	u16 size, i;
542
543	switch (phy->rev) {
544	case 7:
545		table = r2057_rev4_init[0];
546		size = ARRAY_SIZE(r2057_rev4_init);
547		break;
548	case 8:
549		if (phy->radio_rev == 5) {
550			table = r2057_rev5_init[0];
551			size = ARRAY_SIZE(r2057_rev5_init);
552		} else if (phy->radio_rev == 7) {
553			table = r2057_rev7_init[0];
554			size = ARRAY_SIZE(r2057_rev7_init);
555		}
556		break;
557	case 9:
558		if (phy->radio_rev == 5) {
559			table = r2057_rev5a_init[0];
560			size = ARRAY_SIZE(r2057_rev5a_init);
561		}
562		break;
563	case 16:
564		if (phy->radio_rev == 9) {
565			table = r2057_rev9_init[0];
566			size = ARRAY_SIZE(r2057_rev9_init);
567		}
568		break;
569	case 17:
570		if (phy->radio_rev == 14) {
571			table = r2057_rev14_init[0];
572			size = ARRAY_SIZE(r2057_rev14_init);
573		}
574		break;
575	}
576
577	B43_WARN_ON(!table);
578
579	if (table) {
580		for (i = 0; i < size; i++, table += 2)
581			b43_radio_write(dev, table[0], table[1]);
582	}
583}
584
585void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
586			       const struct b43_nphy_chantabent_rev7 **tabent_r7,
587			       const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g)
588{
589	struct b43_phy *phy = &dev->phy;
590	const struct b43_nphy_chantabent_rev7 *e_r7 = NULL;
591	const struct b43_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
592	unsigned int len, i;
593
594	*tabent_r7 = NULL;
595	*tabent_r7_2g = NULL;
596
597	switch (phy->rev) {
598	case 8:
599		if (phy->radio_rev == 5) {
600			e_r7_2g = b43_nphy_chantab_phy_rev8_radio_rev5;
601			len = ARRAY_SIZE(b43_nphy_chantab_phy_rev8_radio_rev5);
602		}
603		break;
604	case 16:
605		if (phy->radio_rev == 9) {
606			e_r7 = b43_nphy_chantab_phy_rev16_radio_rev9;
607			len = ARRAY_SIZE(b43_nphy_chantab_phy_rev16_radio_rev9);
608		}
609		break;
610	case 17:
611		if (phy->radio_rev == 14) {
612			e_r7_2g = b43_nphy_chantab_phy_rev17_radio_rev14;
613			len = ARRAY_SIZE(b43_nphy_chantab_phy_rev17_radio_rev14);
614		}
615		break;
616	default:
617		break;
618	}
619
620	if (e_r7) {
621		for (i = 0; i < len; i++, e_r7++) {
622			if (e_r7->freq == freq) {
623				*tabent_r7 = e_r7;
624				return;
625			}
626		}
627	} else if (e_r7_2g) {
628		for (i = 0; i < len; i++, e_r7_2g++) {
629			if (e_r7_2g->freq == freq) {
630				*tabent_r7_2g = e_r7_2g;
631				return;
632			}
633		}
634	} else {
635		B43_WARN_ON(1);
636	}
637}
638