if_bwn_radio_2057.c revision 300190
1
2/*
3
4  Broadcom B43 wireless driver
5  IEEE 802.11n PHY data tables
6
7  Copyright (c) 2008 Michael Buesch <m@bues.ch>
8  Copyright (c) 2010 Rafa�� Mi��ecki <zajec5@gmail.com>
9
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with this program; see the file COPYING.  If not, write to
22  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
23  Boston, MA 02110-1301, USA.
24
25*/
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/gnu/dev/bwn/phy_n/if_bwn_radio_2057.c 300190 2016-05-19 04:45:50Z adrian $");
29
30/*
31 * The Broadcom Wireless LAN controller driver.
32 */
33
34#include "opt_wlan.h"
35#include "opt_bwn.h'
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/malloc.h>
41#include <sys/module.h>
42#include <sys/endian.h>
43#include <sys/errno.h>
44#include <sys/firmware.h>
45#include <sys/lock.h>
46#include <sys/mutex.h>
47#include <machine/bus.h>
48#include <machine/resource.h>
49#include <sys/bus.h>
50#include <sys/rman.h>
51#include <sys/socket.h>
52#include <sys/sockio.h>
53
54#include <net/ethernet.h>
55#include <net/if.h>
56#include <net/if_var.h>
57#include <net/if_arp.h>
58#include <net/if_dl.h>
59#include <net/if_llc.h>
60#include <net/if_media.h>
61#include <net/if_types.h>
62
63#include <dev/pci/pcivar.h>
64#include <dev/pci/pcireg.h>
65#include <dev/siba/siba_ids.h>
66#include <dev/siba/sibareg.h>
67#include <dev/siba/sibavar.h>
68
69#include <net80211/ieee80211_var.h>
70#include <net80211/ieee80211_radiotap.h>
71#include <net80211/ieee80211_regdomain.h>
72#include <net80211/ieee80211_phy.h>
73#include <net80211/ieee80211_ratectl.h>
74
75#include <dev/bwn/if_bwnreg.h>
76#include <dev/bwn/if_bwnvar.h>
77#include <dev/bwn/if_bwn_debug.h>
78
79#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_regs.h>
80#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h>
81#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.h>
82#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h>
83#include <gnu/dev/bwn/phy_n/if_bwn_radio_2057.h>
84
85static uint16_t r2057_rev4_init[][2] = {
86	{ 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
87	{ 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
88	{ 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
89	{ 0x8C, 0xf0 }, { 0x91, 0x3f }, { 0x92, 0x36 }, { 0xA4, 0x8c },
90	{ 0xA8, 0x55 }, { 0xAF, 0x01 }, { 0x10F, 0xf0 }, { 0x110, 0x10 },
91	{ 0x111, 0xf0 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x129, 0x8c },
92	{ 0x12D, 0x55 }, { 0x134, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 },
93	{ 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 },
94	{ 0x169, 0x02 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 },
95	{ 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 },
96	{ 0x1AB, 0x00 }, { 0x1AC, 0x00 },
97};
98
99static uint16_t r2057_rev5_init[][2] = {
100	{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
101	{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
102	{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
103	{ 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
104	{ 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 },
105	{ 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f },
106	{ 0x117, 0x36 }, { 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 },
107	{ 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 },
108	{ 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 },
109	{ 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 },
110	{ 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
111};
112
113static uint16_t r2057_rev5a_init[][2] = {
114	{ 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
115	{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
116	{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
117	{ 0x64, 0x0f }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
118	{ 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 }, { 0xE1, 0x20 },
119	{ 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0x106, 0x01 }, { 0x116, 0x3f },
120	{ 0x117, 0x36 }, { 0x126, 0x20 }, { 0x14E, 0x01 }, { 0x15E, 0x00 },
121	{ 0x15F, 0x00 }, { 0x160, 0x00 }, { 0x161, 0x00 }, { 0x162, 0x00 },
122	{ 0x163, 0x00 }, { 0x16A, 0x00 }, { 0x16B, 0x00 }, { 0x16C, 0x00 },
123	{ 0x1A4, 0x00 }, { 0x1A5, 0x00 }, { 0x1A6, 0x00 }, { 0x1AA, 0x00 },
124	{ 0x1AB, 0x00 }, { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 },
125	{ 0x1C2, 0x80 },
126};
127
128static uint16_t r2057_rev7_init[][2] = {
129	{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
130	{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
131	{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
132	{ 0x66, 0xee }, { 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 },
133	{ 0x7C, 0x14 }, { 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f },
134	{ 0x92, 0x36 }, { 0xA1, 0x20 }, { 0xD6, 0x70 }, { 0xDE, 0x88 },
135	{ 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x13 }, { 0xEB, 0xee },
136	{ 0xF3, 0x58 }, { 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x14 },
137	{ 0x102, 0xee }, { 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 },
138	{ 0x126, 0x20 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 },
139	{ 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 },
140	{ 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 },
141	{ 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
142	{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
143};
144
145/* TODO: Which devices should use it?
146static uint16_t r2057_rev8_init[][2] = {
147	{ 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
148	{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
149	{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
150	{ 0x6E, 0x58 }, { 0x75, 0x13 }, { 0x7B, 0x13 }, { 0x7C, 0x0f },
151	{ 0x7D, 0xee }, { 0x81, 0x01 }, { 0x91, 0x3f }, { 0x92, 0x36 },
152	{ 0xA1, 0x20 }, { 0xC9, 0x01 }, { 0xD6, 0x70 }, { 0xDE, 0x88 },
153	{ 0xE1, 0x20 }, { 0xE8, 0x0f }, { 0xE9, 0x0f }, { 0xF3, 0x58 },
154	{ 0xFA, 0x13 }, { 0x100, 0x13 }, { 0x101, 0x0f }, { 0x102, 0xee },
155	{ 0x106, 0x01 }, { 0x116, 0x3f }, { 0x117, 0x36 }, { 0x126, 0x20 },
156	{ 0x14E, 0x01 }, { 0x15E, 0x00 }, { 0x15F, 0x00 }, { 0x160, 0x00 },
157	{ 0x161, 0x00 }, { 0x162, 0x00 }, { 0x163, 0x00 }, { 0x16A, 0x00 },
158	{ 0x16B, 0x00 }, { 0x16C, 0x00 }, { 0x1A4, 0x00 }, { 0x1A5, 0x00 },
159	{ 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
160	{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
161};
162*/
163
164/* Extracted from MMIO dump of 6.30.223.141 */
165static uint16_t r2057_rev9_init[][2] = {
166	{ 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f },
167	{ 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 },
168	{ 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 },
169	{ 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 },
170	{ 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff },
171	{ 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 },
172	{ 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 },
173	{ 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 },
174};
175
176/* Extracted from MMIO dump of 6.30.223.248 */
177static uint16_t r2057_rev14_init[][2] = {
178	{ 0x011, 0xfc }, { 0x030, 0x24 }, { 0x040, 0x1c }, { 0x082, 0x08 },
179	{ 0x0b4, 0x44 }, { 0x0c8, 0x01 }, { 0x0c9, 0x01 }, { 0x107, 0x08 },
180	{ 0x14d, 0x01 }, { 0x14e, 0x01 }, { 0x1af, 0x40 }, { 0x1b0, 0x40 },
181	{ 0x1cc, 0x01 }, { 0x1cf, 0x10 }, { 0x1d0, 0x0f }, { 0x1d3, 0x10 },
182	{ 0x1d4, 0x0f },
183};
184
185#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
186		   r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
187		   r20, r21, r22, r23, r24, r25, r26, r27) \
188	.radio_vcocal_countval0			= r00,	\
189	.radio_vcocal_countval1			= r01,	\
190	.radio_rfpll_refmaster_sparextalsize	= r02,	\
191	.radio_rfpll_loopfilter_r1		= r03,	\
192	.radio_rfpll_loopfilter_c2		= r04,	\
193	.radio_rfpll_loopfilter_c1		= r05,	\
194	.radio_cp_kpd_idac			= r06,	\
195	.radio_rfpll_mmd0			= r07,	\
196	.radio_rfpll_mmd1			= r08,	\
197	.radio_vcobuf_tune			= r09,	\
198	.radio_logen_mx2g_tune			= r10,	\
199	.radio_logen_mx5g_tune			= r11,	\
200	.radio_logen_indbuf2g_tune		= r12,	\
201	.radio_logen_indbuf5g_tune		= r13,	\
202	.radio_txmix2g_tune_boost_pu_core0	= r14,	\
203	.radio_pad2g_tune_pus_core0		= r15,	\
204	.radio_pga_boost_tune_core0		= r16,	\
205	.radio_txmix5g_boost_tune_core0		= r17,	\
206	.radio_pad5g_tune_misc_pus_core0	= r18,	\
207	.radio_lna2g_tune_core0			= r19,	\
208	.radio_lna5g_tune_core0			= r20,	\
209	.radio_txmix2g_tune_boost_pu_core1	= r21,	\
210	.radio_pad2g_tune_pus_core1		= r22,	\
211	.radio_pga_boost_tune_core1		= r23,	\
212	.radio_txmix5g_boost_tune_core1		= r24,	\
213	.radio_pad5g_tune_misc_pus_core1	= r25,	\
214	.radio_lna2g_tune_core1			= r26,	\
215	.radio_lna5g_tune_core1			= r27
216
217#define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
218		      r10, r11, r12, r13, r14, r15, r16, r17) \
219	.radio_vcocal_countval0			= r00,	\
220	.radio_vcocal_countval1			= r01,	\
221	.radio_rfpll_refmaster_sparextalsize	= r02,	\
222	.radio_rfpll_loopfilter_r1		= r03,	\
223	.radio_rfpll_loopfilter_c2		= r04,	\
224	.radio_rfpll_loopfilter_c1		= r05,	\
225	.radio_cp_kpd_idac			= r06,	\
226	.radio_rfpll_mmd0			= r07,	\
227	.radio_rfpll_mmd1			= r08,	\
228	.radio_vcobuf_tune			= r09,	\
229	.radio_logen_mx2g_tune			= r10,	\
230	.radio_logen_indbuf2g_tune		= r11,	\
231	.radio_txmix2g_tune_boost_pu_core0	= r12,	\
232	.radio_pad2g_tune_pus_core0		= r13,	\
233	.radio_lna2g_tune_core0			= r14,	\
234	.radio_txmix2g_tune_boost_pu_core1	= r15,	\
235	.radio_pad2g_tune_pus_core1		= r16,	\
236	.radio_lna2g_tune_core1			= r17
237
238#define PHYREGS(r0, r1, r2, r3, r4, r5)	\
239	.phy_regs.phy_bw1a	= r0,	\
240	.phy_regs.phy_bw2	= r1,	\
241	.phy_regs.phy_bw3	= r2,	\
242	.phy_regs.phy_bw4	= r3,	\
243	.phy_regs.phy_bw5	= r4,	\
244	.phy_regs.phy_bw6	= r5
245
246/* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */
247static const struct bwn_nphy_chantabent_rev7_2g bwn_nphy_chantab_phy_rev8_radio_rev5[] = {
248	{
249		.freq			= 2412,
250		RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
251			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
252			      0x03, 0xff),
253		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
254	},
255	{
256		.freq			= 2417,
257		RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
258			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
259			      0x03, 0xff),
260		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
261	},
262	{
263		.freq			= 2422,
264		RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
265			      0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
266			      0x03, 0xef),
267		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
268	},
269	{
270		.freq			= 2427,
271		RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
272			      0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
273			      0x03, 0xdf),
274		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
275	},
276	{
277		.freq			= 2432,
278		RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
279			      0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
280			      0x03, 0xcf),
281		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
282	},
283	{
284		.freq			= 2437,
285		RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
286			      0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
287			      0x03, 0xbf),
288		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
289	},
290	{
291		.freq			= 2442,
292		RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
293			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
294			      0x03, 0xaf),
295		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
296	},
297	{
298		.freq			= 2447,
299		RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
300			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
301			      0x03, 0x9f),
302		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
303	},
304	{
305		.freq			= 2452,
306		RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
307			      0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
308			      0x03, 0x8f),
309		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
310	},
311	{
312		.freq			= 2457,
313		RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
314			      0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
315			      0x03, 0x7f),
316		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
317	},
318	{
319		.freq			= 2462,
320		RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
321			      0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
322			      0x03, 0x6f),
323		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
324	},
325	{
326		.freq			= 2467,
327		RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
328			      0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
329			      0x03, 0x5f),
330		PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
331	},
332	{
333		.freq			= 2472,
334		RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
335			      0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
336			      0x03, 0x4f),
337		PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
338	},
339	{
340		.freq			= 2484,
341		RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
342			      0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
343			      0x03, 0x3f),
344		PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
345	}
346};
347
348/* Extracted from MMIO dump of 6.30.223.248 */
349static const struct bwn_nphy_chantabent_rev7_2g bwn_nphy_chantab_phy_rev17_radio_rev14[] = {
350	{
351		.freq			= 2412,
352		RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c,
353			      0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21,
354			      0x53, 0xff),
355		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
356	},
357	{
358		.freq			= 2417,
359		RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71,
360			      0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
361			      0x53, 0xff),
362		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
363	},
364	{
365		.freq			= 2422,
366		RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76,
367			      0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
368			      0x53, 0xff),
369		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
370	},
371	{
372		.freq			= 2427,
373		RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b,
374			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
375			      0x53, 0xff),
376		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
377	},
378	{
379		.freq			= 2432,
380		RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80,
381			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
382			      0x53, 0xff),
383		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
384	},
385	{
386		.freq			= 2437,
387		RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85,
388			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
389			      0x53, 0xff),
390		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
391	},
392	{
393		.freq			= 2442,
394		RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a,
395			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
396			      0x43, 0xff),
397		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
398	},
399	{
400		.freq			= 2447,
401		RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f,
402			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
403			      0x43, 0xff),
404		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
405	},
406	{
407		.freq			= 2452,
408		RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94,
409			      0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
410			      0x43, 0xff),
411		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
412	},
413	{
414		.freq			= 2457,
415		RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99,
416			      0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21,
417			      0x43, 0xff),
418		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
419	},
420	{
421		.freq			= 2462,
422		RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e,
423			      0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01,
424			      0x43, 0xff),
425		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
426	},
427};
428
429/* Extracted from MMIO dump of 6.30.223.141 */
430static const struct bwn_nphy_chantabent_rev7 bwn_nphy_chantab_phy_rev16_radio_rev9[] = {
431	{
432		.freq			= 2412,
433		RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
434			   0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
435			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
436			   0x00, 0x00, 0xf0, 0x00),
437		PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
438	},
439	{
440		.freq			= 2417,
441		RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
442			   0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
443			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
444			   0x00, 0x00, 0xf0, 0x00),
445		PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
446	},
447	{
448		.freq			= 2422,
449		RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
450			   0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
451			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
452			   0x00, 0x00, 0xf0, 0x00),
453		PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
454	},
455	{
456		.freq			= 2427,
457		RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
458			   0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
459			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
460			   0x00, 0x00, 0xf0, 0x00),
461		PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
462	},
463	{
464		.freq			= 2432,
465		RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
466			   0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
467			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
468			   0x00, 0x00, 0xf0, 0x00),
469		PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
470	},
471	{
472		.freq			= 2437,
473		RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
474			   0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
475			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
476			   0x00, 0x00, 0xf0, 0x00),
477		PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
478	},
479	{
480		.freq			= 2442,
481		RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
482			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
483			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
484			   0x00, 0x00, 0xf0, 0x00),
485		PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
486	},
487	{
488		.freq			= 2447,
489		RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
490			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
491			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
492			   0x00, 0x00, 0xf0, 0x00),
493		PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
494	},
495	{
496		.freq			= 2452,
497		RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
498			   0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
499			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
500			   0x00, 0x00, 0xf0, 0x00),
501		PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
502	},
503	{
504		.freq			= 2457,
505		RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
506			   0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
507			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
508			   0x00, 0x00, 0xf0, 0x00),
509		PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
510	},
511	{
512		.freq			= 2462,
513		RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
514			   0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
515			   0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
516			   0x00, 0x00, 0xf0, 0x00),
517		PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
518	},
519	{
520		.freq			= 5180,
521		RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
522			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
523			   0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f,
524			   0x3a, 0x83, 0x00, 0xfc),
525		PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
526	},
527	{
528		.freq			= 5200,
529		RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
530			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
531			   0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c,
532			   0x4a, 0x83, 0x00, 0xf8),
533		PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
534	},
535	{
536		.freq			= 5220,
537		RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
538			   0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
539			   0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d,
540			   0x2a, 0x73, 0x00, 0xf8),
541		PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
542	},
543	{
544		.freq			= 5240,
545		RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
546			   0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00,
547			   0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d,
548			   0x2b, 0x73, 0x00, 0xf8),
549		PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
550	},
551	{
552		.freq			= 5745,
553		RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
554			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
555			   0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06,
556			   0x02, 0x03, 0x00, 0x30),
557		PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
558	},
559	{
560		.freq			= 5765,
561		RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
562			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
563			   0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
564			   0x02, 0x03, 0x00, 0x00),
565		PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
566	},
567	{
568		.freq			= 5785,
569		RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
570			   0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
571			   0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
572			   0x21, 0x03, 0x00, 0x00),
573		PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
574	},
575	{
576		.freq			= 5805,
577		RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
578			   0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
579			   0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
580			   0x00, 0x03, 0x00, 0x00),
581		PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
582	},
583	{
584		.freq			= 5825,
585		RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
586			   0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00,
587			   0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
588			   0x00, 0x03, 0x00, 0x00),
589		PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
590	},
591};
592
593void r2057_upload_inittabs(struct bwn_mac *mac)
594{
595	struct bwn_phy *phy = &mac->mac_phy;
596	uint16_t *table = NULL;
597	uint16_t size, i;
598
599	switch (phy->rev) {
600	case 7:
601		table = r2057_rev4_init[0];
602		size = nitems(r2057_rev4_init);
603		break;
604	case 8:
605		if (phy->rf_rev == 5) {
606			table = r2057_rev5_init[0];
607			size = nitems(r2057_rev5_init);
608		} else if (phy->rf_rev == 7) {
609			table = r2057_rev7_init[0];
610			size = nitems(r2057_rev7_init);
611		}
612		break;
613	case 9:
614		if (phy->rf_rev == 5) {
615			table = r2057_rev5a_init[0];
616			size = nitems(r2057_rev5a_init);
617		}
618		break;
619	case 16:
620		if (phy->rf_rev == 9) {
621			table = r2057_rev9_init[0];
622			size = nitems(r2057_rev9_init);
623		}
624		break;
625	case 17:
626		if (phy->rf_rev == 14) {
627			table = r2057_rev14_init[0];
628			size = nitems(r2057_rev14_init);
629		}
630		break;
631	}
632
633	if (! table) {
634		device_printf(mac->mac_sc->sc_dev,
635		    "%s: couldn't find a suitable table (phy ref=%d, rf_ref=%d)\n",
636		    __func__,
637		    phy->rev,
638		    phy->rf_rev);
639	}
640
641	if (table) {
642		for (i = 0; i < size; i++, table += 2)
643			BWN_RF_WRITE(mac, table[0], table[1]);
644	}
645}
646
647void r2057_get_chantabent_rev7(struct bwn_mac *mac, uint16_t freq,
648			       const struct bwn_nphy_chantabent_rev7 **tabent_r7,
649			       const struct bwn_nphy_chantabent_rev7_2g **tabent_r7_2g)
650{
651	struct bwn_phy *phy = &mac->mac_phy;
652	const struct bwn_nphy_chantabent_rev7 *e_r7 = NULL;
653	const struct bwn_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
654	unsigned int len, i;
655
656	*tabent_r7 = NULL;
657	*tabent_r7_2g = NULL;
658
659	switch (phy->rev) {
660	case 8:
661		if (phy->rf_rev == 5) {
662			e_r7_2g = bwn_nphy_chantab_phy_rev8_radio_rev5;
663			len = nitems(bwn_nphy_chantab_phy_rev8_radio_rev5);
664		}
665		break;
666	case 16:
667		if (phy->rf_rev == 9) {
668			e_r7 = bwn_nphy_chantab_phy_rev16_radio_rev9;
669			len = nitems(bwn_nphy_chantab_phy_rev16_radio_rev9);
670		}
671		break;
672	case 17:
673		if (phy->rf_rev == 14) {
674			e_r7_2g = bwn_nphy_chantab_phy_rev17_radio_rev14;
675			len = nitems(bwn_nphy_chantab_phy_rev17_radio_rev14);
676		}
677		break;
678	default:
679		break;
680	}
681
682	if (e_r7) {
683		for (i = 0; i < len; i++, e_r7++) {
684			if (e_r7->freq == freq) {
685				*tabent_r7 = e_r7;
686				return;
687			}
688		}
689	} else if (e_r7_2g) {
690		for (i = 0; i < len; i++, e_r7_2g++) {
691			if (e_r7_2g->freq == freq) {
692				*tabent_r7_2g = e_r7_2g;
693				return;
694			}
695		}
696	} else {
697		device_printf(mac->mac_sc->sc_dev,
698		    "%s: couldn't find a suitable chantab\n",
699		    __func__);
700	}
701}
702