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 
29 static 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 
43 static 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 
57 static 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 
72 static 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?
90 static 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 */
109 static 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 */
121 static 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 */
191 static 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 */
293 static 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 */
374 static 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 
537 void 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 
585 void 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