aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/brcm80211
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/brcm80211')
-rw-r--r--drivers/staging/brcm80211/Kconfig40
-rw-r--r--drivers/staging/brcm80211/Makefile24
-rw-r--r--drivers/staging/brcm80211/README1
-rw-r--r--drivers/staging/brcm80211/TODO13
-rw-r--r--drivers/staging/brcm80211/brcmfmac/Makefile39
-rw-r--r--drivers/staging/brcm80211/brcmfmac/bcmchip.h32
-rw-r--r--drivers/staging/brcm80211/brcmfmac/bcmsdh.c642
-rw-r--r--drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c1196
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd.h904
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_bus.h78
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_cdc.c502
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_common.c1196
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_dbg.h70
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_linux.c1736
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_proto.h75
-rw-r--r--drivers/staging/brcm80211/brcmfmac/dhd_sdio.c6772
-rw-r--r--drivers/staging/brcm80211/brcmfmac/sdio_host.h347
-rw-r--r--drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c4152
-rw-r--r--drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h356
-rw-r--r--drivers/staging/brcm80211/brcmsmac/Makefile58
-rw-r--r--drivers/staging/brcm80211/brcmsmac/aiutils.c2279
-rw-r--r--drivers/staging/brcm80211/brcmsmac/aiutils.h584
-rw-r--r--drivers/staging/brcm80211/brcmsmac/alloc.c275
-rw-r--r--drivers/staging/brcm80211/brcmsmac/alloc.h19
-rw-r--r--drivers/staging/brcm80211/brcmsmac/ampdu.c1219
-rw-r--r--drivers/staging/brcm80211/brcmsmac/ampdu.h30
-rw-r--r--drivers/staging/brcm80211/brcmsmac/antsel.c311
-rw-r--r--drivers/staging/brcm80211/brcmsmac/antsel.h29
-rw-r--r--drivers/staging/brcm80211/brcmsmac/bmac.c3593
-rw-r--r--drivers/staging/brcm80211/brcmsmac/bmac.h174
-rw-r--r--drivers/staging/brcm80211/brcmsmac/channel.c1559
-rw-r--r--drivers/staging/brcm80211/brcmsmac/channel.h132
-rw-r--r--drivers/staging/brcm80211/brcmsmac/d11.h1775
-rw-r--r--drivers/staging/brcm80211/brcmsmac/dma.c1917
-rw-r--r--drivers/staging/brcm80211/brcmsmac/dma.h250
-rw-r--r--drivers/staging/brcm80211/brcmsmac/mac80211_if.c1939
-rw-r--r--drivers/staging/brcm80211/brcmsmac/mac80211_if.h114
-rw-r--r--drivers/staging/brcm80211/brcmsmac/main.c6110
-rw-r--r--drivers/staging/brcm80211/brcmsmac/main.h1025
-rw-r--r--drivers/staging/brcm80211/brcmsmac/nicpci.c850
-rw-r--r--drivers/staging/brcm80211/brcmsmac/nicpci.h85
-rw-r--r--drivers/staging/brcm80211/brcmsmac/otp.c545
-rw-r--r--drivers/staging/brcm80211/brcmsmac/otp.h47
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c3225
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h294
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_int.h1235
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c5294
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h121
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_n.c29082
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c294
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h42
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h1533
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h167
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c3638
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h54
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c10629
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h40
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy_shim.c218
-rw-r--r--drivers/staging/brcm80211/brcmsmac/phy_shim.h164
-rw-r--r--drivers/staging/brcm80211/brcmsmac/pmu.c474
-rw-r--r--drivers/staging/brcm80211/brcmsmac/pmu.h52
-rw-r--r--drivers/staging/brcm80211/brcmsmac/pub.h665
-rw-r--r--drivers/staging/brcm80211/brcmsmac/rate.c498
-rw-r--r--drivers/staging/brcm80211/brcmsmac/rate.h173
-rw-r--r--drivers/staging/brcm80211/brcmsmac/scb.h85
-rw-r--r--drivers/staging/brcm80211/brcmsmac/srom.c1237
-rw-r--r--drivers/staging/brcm80211/brcmsmac/srom.h34
-rw-r--r--drivers/staging/brcm80211/brcmsmac/stf.c477
-rw-r--r--drivers/staging/brcm80211/brcmsmac/stf.h42
-rw-r--r--drivers/staging/brcm80211/brcmsmac/types.h399
-rw-r--r--drivers/staging/brcm80211/brcmsmac/ucode_loader.c115
-rw-r--r--drivers/staging/brcm80211/brcmsmac/ucode_loader.h52
-rw-r--r--drivers/staging/brcm80211/brcmutil/Makefile29
-rw-r--r--drivers/staging/brcm80211/brcmutil/utils.c787
-rw-r--r--drivers/staging/brcm80211/brcmutil/wifi.c131
-rw-r--r--drivers/staging/brcm80211/include/brcm_hw_ids.h59
-rw-r--r--drivers/staging/brcm80211/include/brcmu_utils.h301
-rw-r--r--drivers/staging/brcm80211/include/brcmu_wifi.h243
-rw-r--r--drivers/staging/brcm80211/include/chipcommon.h281
-rw-r--r--drivers/staging/brcm80211/include/defs.h112
-rw-r--r--drivers/staging/brcm80211/include/soc.h95
81 files changed, 105465 insertions, 0 deletions
diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig
new file mode 100644
index 00000000000..379cf16e89f
--- /dev/null
+++ b/drivers/staging/brcm80211/Kconfig
@@ -0,0 +1,40 @@
1config BRCMUTIL
2 tristate
3 default n
4
5config BRCMSMAC
6 tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
7 default n
8 depends on PCI
9 depends on WLAN && MAC80211
10 depends on X86 || MIPS
11 select BRCMUTIL
12 select FW_LOADER
13 select CRC_CCITT
14 ---help---
15 This module adds support for PCIe wireless adapters based on Broadcom
16 IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll
17 be called brcmsmac.ko.
18
19config BRCMFMAC
20 tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
21 default n
22 depends on MMC
23 depends on WLAN && CFG80211
24 depends on X86 || MIPS
25 select BRCMUTIL
26 select FW_LOADER
27 select WIRELESS_EXT
28 select WEXT_PRIV
29 ---help---
30 This module adds support for embedded wireless adapters based on
31 Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's
32 wireless extensions subsystem. If you choose to build a module,
33 it'll be called brcmfmac.ko.
34
35config BRCMDBG
36 bool "Broadcom driver debug functions"
37 default n
38 depends on BRCMSMAC || BRCMFMAC
39 ---help---
40 Selecting this enables additional code for debug purposes.
diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile
new file mode 100644
index 00000000000..8b01f5e7ba2
--- /dev/null
+++ b/drivers/staging/brcm80211/Makefile
@@ -0,0 +1,24 @@
1#
2# Makefile fragment for Broadcom 802.11n Networking Device Driver
3#
4# Copyright (c) 2010 Broadcom Corporation
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18# common flags
19subdir-ccflags-y := -DBCMDMA32
20subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG
21
22obj-$(CONFIG_BRCMUTIL) += brcmutil/
23obj-$(CONFIG_BRCMFMAC) += brcmfmac/
24obj-$(CONFIG_BRCMSMAC) += brcmsmac/
diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README
new file mode 100644
index 00000000000..bb86b1b3e58
--- /dev/null
+++ b/drivers/staging/brcm80211/README
@@ -0,0 +1 @@
refer to: http://linuxwireless.org/en/users/Drivers/brcm80211
diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO
new file mode 100644
index 00000000000..e2e2ef9bd7a
--- /dev/null
+++ b/drivers/staging/brcm80211/TODO
@@ -0,0 +1,13 @@
1To Do List for Broadcom Mac80211 driver before getting in mainline
2
3Bugs
4====
5- none known at this moment
6
7brcmfmac
8=====================
9- ASSERTS deprecated in mainline, replace by warning + error handling
10
11brcm80211 info page
12=====================
13http://linuxwireless.org/en/users/Drivers/brcm80211
diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile
new file mode 100644
index 00000000000..da3c8057590
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/Makefile
@@ -0,0 +1,39 @@
1#
2# Makefile fragment for Broadcom 802.11n Networking Device Driver
3#
4# Copyright (c) 2010 Broadcom Corporation
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18ccflags-y := \
19 -DBRCMF_FIRSTREAD=64 \
20 -DBRCMF_SDALIGN=64 \
21 -DMAX_HDR_READ=64
22
23ccflags-$(CONFIG_BRCMDBG) += -DSHOW_EVENTS
24
25ccflags-y += \
26 -Idrivers/staging/brcm80211/brcmfmac \
27 -Idrivers/staging/brcm80211/include
28
29DHDOFILES = \
30 wl_cfg80211.o \
31 dhd_cdc.o \
32 dhd_common.o \
33 dhd_sdio.o \
34 dhd_linux.o \
35 bcmsdh.o \
36 bcmsdh_sdmmc.o
37
38obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
39brcmfmac-objs += $(DHDOFILES)
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmchip.h b/drivers/staging/brcm80211/brcmfmac/bcmchip.h
new file mode 100644
index 00000000000..d7d3afd5a10
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/bcmchip.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _bcmchip_h_
18#define _bcmchip_h_
19
20/* bcm4329 */
21/* SDIO device core, ID 0x829 */
22#define BCM4329_CORE_BUS_BASE 0x18011000
23/* internal memory core, ID 0x80e */
24#define BCM4329_CORE_SOCRAM_BASE 0x18003000
25/* ARM Cortex M3 core, ID 0x82a */
26#define BCM4329_CORE_ARM_BASE 0x18002000
27#define BCM4329_RAMSIZE 0x48000
28/* firmware name */
29#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin"
30#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt"
31
32#endif /* _bcmchip_h_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
new file mode 100644
index 00000000000..f4e72ed126b
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
@@ -0,0 +1,642 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/* ****************** SDIO CARD Interface Functions **************************/
17
18#include <linux/types.h>
19#include <linux/netdevice.h>
20#include <linux/pci.h>
21#include <linux/pci_ids.h>
22#include <linux/sched.h>
23#include <linux/completion.h>
24
25#include <defs.h>
26#include <brcm_hw_ids.h>
27#include <brcmu_utils.h>
28#include <brcmu_wifi.h>
29#include <soc.h>
30#include "dhd.h"
31#include "dhd_bus.h"
32#include "sdio_host.h"
33
34#define SDIOH_API_ACCESS_RETRY_LIMIT 2
35
36#define BRCMF_SD_ERROR_VAL 0x0001 /* Error */
37#define BRCMF_SD_INFO_VAL 0x0002 /* Info */
38
39
40#ifdef BCMDBG
41#define BRCMF_SD_ERROR(x) \
42 do { \
43 if ((brcmf_sdio_msglevel & BRCMF_SD_ERROR_VAL) && \
44 net_ratelimit()) \
45 printk x; \
46 } while (0)
47#define BRCMF_SD_INFO(x) \
48 do { \
49 if ((brcmf_sdio_msglevel & BRCMF_SD_INFO_VAL) && \
50 net_ratelimit()) \
51 printk x; \
52 } while (0)
53#else /* BCMDBG */
54#define BRCMF_SD_ERROR(x)
55#define BRCMF_SD_INFO(x)
56#endif /* BCMDBG */
57
58/* debugging macros */
59#define SDLX_MSG(x)
60
61#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */
62#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */
63#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */
64
65#define SDIOH_DATA_PIO 0 /* PIO mode */
66#define SDIOH_DATA_DMA 1 /* DMA mode */
67
68struct brcmf_sdio_card {
69 bool init_success; /* underlying driver successfully attached */
70 void *sdioh; /* handler for sdioh */
71 u32 vendevid; /* Target Vendor and Device ID on SD bus */
72 bool regfail; /* Save status of last
73 reg_read/reg_write call */
74 u32 sbwad; /* Save backplane window address */
75};
76
77/**
78 * SDIO Host Controller info
79 */
80struct sdio_hc {
81 struct sdio_hc *next;
82 struct device *dev; /* platform device handle */
83 void *regs; /* SDIO Host Controller address */
84 struct brcmf_sdio_card *card;
85 void *ch;
86 unsigned int oob_irq;
87 unsigned long oob_flags; /* OOB Host specifiction
88 as edge and etc */
89 bool oob_irq_registered;
90};
91
92/* local copy of bcm sd handler */
93static struct brcmf_sdio_card *l_card;
94
95const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL;
96
97static struct sdio_hc *sdhcinfo;
98
99/* driver info, initialized when brcmf_sdio_register is called */
100static struct brcmf_sdioh_driver drvinfo = { NULL, NULL };
101
102/* Module parameters specific to each host-controller driver */
103
104module_param(sd_msglevel, uint, 0);
105
106extern uint sd_f2_blocksize;
107module_param(sd_f2_blocksize, int, 0);
108
109/* forward declarations */
110int brcmf_sdio_probe(struct device *dev);
111EXPORT_SYMBOL(brcmf_sdio_probe);
112
113int brcmf_sdio_remove(struct device *dev);
114EXPORT_SYMBOL(brcmf_sdio_remove);
115
116struct brcmf_sdio_card*
117brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq)
118{
119 struct brcmf_sdio_card *card;
120
121 card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC);
122 if (card == NULL) {
123 BRCMF_SD_ERROR(("sdcard_attach: out of memory"));
124 return NULL;
125 }
126
127 /* save the handler locally */
128 l_card = card;
129
130 card->sdioh = brcmf_sdioh_attach(cfghdl, irq);
131 if (!card->sdioh) {
132 brcmf_sdcard_detach(card);
133 return NULL;
134 }
135
136 card->init_success = true;
137
138 *regsva = SI_ENUM_BASE;
139
140 /* Report the BAR, to fix if needed */
141 card->sbwad = SI_ENUM_BASE;
142 return card;
143}
144
145int brcmf_sdcard_detach(struct brcmf_sdio_card *card)
146{
147 if (card != NULL) {
148 if (card->sdioh) {
149 brcmf_sdioh_detach(card->sdioh);
150 card->sdioh = NULL;
151 }
152 kfree(card);
153 }
154
155 l_card = NULL;
156 return 0;
157}
158
159int
160brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
161 void *params, int plen, void *arg, int len, bool set)
162{
163 return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg,
164 len, set);
165}
166
167int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card)
168{
169 return brcmf_sdioh_interrupt_set(card->sdioh, true);
170}
171
172int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card)
173{
174 return brcmf_sdioh_interrupt_set(card->sdioh, false);
175}
176
177int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
178 void (*fn)(void *), void *argh)
179{
180 return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh);
181}
182
183int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card)
184{
185 return brcmf_sdioh_interrupt_deregister(card->sdioh);
186}
187
188u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
189 int *err)
190{
191 int status;
192 s32 retry = 0;
193 u8 data = 0;
194
195 if (!card)
196 card = l_card;
197
198 do {
199 if (retry) /* wait for 1 ms till bus get settled down */
200 udelay(1000);
201 status =
202 brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr,
203 (u8 *) &data);
204 } while (status != 0
205 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
206 if (err)
207 *err = status;
208
209 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
210 __func__, fnc_num, addr, data));
211
212 return data;
213}
214
215void
216brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
217 u8 data, int *err)
218{
219 int status;
220 s32 retry = 0;
221
222 if (!card)
223 card = l_card;
224
225 do {
226 if (retry) /* wait for 1 ms till bus get settled down */
227 udelay(1000);
228 status =
229 brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr,
230 (u8 *) &data);
231 } while (status != 0
232 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
233 if (err)
234 *err = status;
235
236 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
237 __func__, fnc_num, addr, data));
238}
239
240u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
241 u32 addr, int *err)
242{
243 int status;
244 u32 data = 0;
245
246 if (!card)
247 card = l_card;
248
249 status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
250 SDIOH_READ, fnc_num, addr, &data, 4);
251
252 if (err)
253 *err = status;
254
255 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
256 __func__, fnc_num, addr, data));
257
258 return data;
259}
260
261void
262brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num,
263 u32 addr, u32 data, int *err)
264{
265 int status;
266
267 if (!card)
268 card = l_card;
269
270 status =
271 brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
272 SDIOH_WRITE, fnc_num, addr, &data, 4);
273
274 if (err)
275 *err = status;
276
277 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
278 __func__, fnc_num, addr, data));
279}
280
281int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis,
282 uint length)
283{
284 int status;
285
286 u8 *tmp_buf, *tmp_ptr;
287 u8 *ptr;
288 bool ascii = func & ~0xf;
289 func &= 0x7;
290
291 if (!card)
292 card = l_card;
293
294 status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length);
295
296 if (ascii) {
297 /* Move binary bits to tmp and format them
298 into the provided buffer. */
299 tmp_buf = kmalloc(length, GFP_ATOMIC);
300 if (tmp_buf == NULL) {
301 BRCMF_SD_ERROR(("%s: out of memory\n", __func__));
302 return -ENOMEM;
303 }
304 memcpy(tmp_buf, cis, length);
305 for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
306 tmp_ptr++) {
307 ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff);
308 if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
309 ptr += sprintf((char *)ptr, "\n");
310 }
311 kfree(tmp_buf);
312 }
313
314 return status;
315}
316
317static int
318brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address)
319{
320 int err = 0;
321 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
322 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
323 if (!err)
324 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
325 SBSDIO_FUNC1_SBADDRMID,
326 (address >> 16) & SBSDIO_SBADDRMID_MASK,
327 &err);
328 if (!err)
329 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
330 SBSDIO_FUNC1_SBADDRHIGH,
331 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
332 &err);
333
334 return err;
335}
336
337u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size)
338{
339 int status;
340 u32 word = 0;
341 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
342
343 BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
344
345 if (!card)
346 card = l_card;
347
348 if (bar0 != card->sbwad) {
349 if (brcmf_sdcard_set_sbaddr_window(card, bar0))
350 return 0xFFFFFFFF;
351
352 card->sbwad = bar0;
353 }
354
355 addr &= SBSDIO_SB_OFT_ADDR_MASK;
356 if (size == 4)
357 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
358
359 status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
360 SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
361
362 card->regfail = (status != 0);
363
364 BRCMF_SD_INFO(("u32data = 0x%x\n", word));
365
366 /* if ok, return appropriately masked word */
367 if (status == 0) {
368 switch (size) {
369 case sizeof(u8):
370 return word & 0xff;
371 case sizeof(u16):
372 return word & 0xffff;
373 case sizeof(u32):
374 return word;
375 default:
376 card->regfail = true;
377
378 }
379 }
380
381 /* otherwise, bad sdio access or invalid size */
382 BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
383 addr, size));
384 return 0xFFFFFFFF;
385}
386
387u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
388 u32 data)
389{
390 int status;
391 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
392 int err = 0;
393
394 BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
395 __func__, addr, size * 8, data));
396
397 if (!card)
398 card = l_card;
399
400 if (bar0 != card->sbwad) {
401 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
402 if (err)
403 return err;
404
405 card->sbwad = bar0;
406 }
407
408 addr &= SBSDIO_SB_OFT_ADDR_MASK;
409 if (size == 4)
410 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
411 status =
412 brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
413 SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
414 card->regfail = (status != 0);
415
416 if (status == 0)
417 return 0;
418
419 BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
420 __func__, data, addr, size));
421 return 0xFFFFFFFF;
422}
423
424bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card)
425{
426 return card->regfail;
427}
428
429int
430brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
431 uint flags,
432 u8 *buf, uint nbytes, struct sk_buff *pkt,
433 void (*complete)(void *handle, int status,
434 bool sync_waiting),
435 void *handle)
436{
437 int status;
438 uint incr_fix;
439 uint width;
440 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
441 int err = 0;
442
443 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
444 __func__, fn, addr, nbytes));
445
446 /* Async not implemented yet */
447 if (flags & SDIO_REQ_ASYNC)
448 return -ENOTSUPP;
449
450 if (bar0 != card->sbwad) {
451 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
452 if (err)
453 return err;
454
455 card->sbwad = bar0;
456 }
457
458 addr &= SBSDIO_SB_OFT_ADDR_MASK;
459
460 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
461 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
462 if (width == 4)
463 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
464
465 status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
466 incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
467
468 return status;
469}
470
471int
472brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
473 uint flags, u8 *buf, uint nbytes, void *pkt,
474 void (*complete)(void *handle, int status,
475 bool sync_waiting),
476 void *handle)
477{
478 uint incr_fix;
479 uint width;
480 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
481 int err = 0;
482
483 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
484 __func__, fn, addr, nbytes));
485
486 /* Async not implemented yet */
487 if (flags & SDIO_REQ_ASYNC)
488 return -ENOTSUPP;
489
490 if (bar0 != card->sbwad) {
491 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
492 if (err)
493 return err;
494
495 card->sbwad = bar0;
496 }
497
498 addr &= SBSDIO_SB_OFT_ADDR_MASK;
499
500 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
501 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
502 if (width == 4)
503 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
504
505 return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
506 incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
507}
508
509int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
510 u8 *buf, uint nbytes)
511{
512 addr &= SBSDIO_SB_OFT_ADDR_MASK;
513 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
514
515 return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
516 SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
517 addr, 4, nbytes, buf, NULL);
518}
519
520int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn)
521{
522 return brcmf_sdioh_abort(card->sdioh, fn);
523}
524
525int brcmf_sdcard_query_device(struct brcmf_sdio_card *card)
526{
527 card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
528 return card->vendevid;
529}
530
531u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card)
532{
533 if (!card)
534 card = l_card;
535
536 return card->sbwad;
537}
538
539int brcmf_sdio_probe(struct device *dev)
540{
541 struct sdio_hc *sdhc = NULL;
542 u32 regs = 0;
543 struct brcmf_sdio_card *card = NULL;
544 int irq = 0;
545 u32 vendevid;
546 unsigned long irq_flags = 0;
547
548 /* allocate SDIO Host Controller state info */
549 sdhc = kzalloc(sizeof(struct sdio_hc), GFP_ATOMIC);
550 if (!sdhc) {
551 SDLX_MSG(("%s: out of memory\n", __func__));
552 goto err;
553 }
554 sdhc->dev = (void *)dev;
555
556 card = brcmf_sdcard_attach((void *)0, &regs, irq);
557 if (!card) {
558 SDLX_MSG(("%s: attach failed\n", __func__));
559 goto err;
560 }
561
562 sdhc->card = card;
563 sdhc->oob_irq = irq;
564 sdhc->oob_flags = irq_flags;
565 sdhc->oob_irq_registered = false; /* to make sure.. */
566
567 /* chain SDIO Host Controller info together */
568 sdhc->next = sdhcinfo;
569 sdhcinfo = sdhc;
570 /* Read the vendor/device ID from the CIS */
571 vendevid = brcmf_sdcard_query_device(card);
572
573 /* try to attach to the target device */
574 sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
575 0, 0, 0, 0, regs, card);
576 if (!sdhc->ch) {
577 SDLX_MSG(("%s: device attach failed\n", __func__));
578 goto err;
579 }
580
581 return 0;
582
583 /* error handling */
584err:
585 if (sdhc) {
586 if (sdhc->card)
587 brcmf_sdcard_detach(sdhc->card);
588 kfree(sdhc);
589 }
590
591 return -ENODEV;
592}
593
594int brcmf_sdio_remove(struct device *dev)
595{
596 struct sdio_hc *sdhc, *prev;
597
598 sdhc = sdhcinfo;
599 drvinfo.detach(sdhc->ch);
600 brcmf_sdcard_detach(sdhc->card);
601 /* find the SDIO Host Controller state for this pdev
602 and take it out from the list */
603 for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
604 if (sdhc->dev == (void *)dev) {
605 if (prev)
606 prev->next = sdhc->next;
607 else
608 sdhcinfo = NULL;
609 break;
610 }
611 prev = sdhc;
612 }
613 if (!sdhc) {
614 SDLX_MSG(("%s: failed\n", __func__));
615 return 0;
616 }
617
618 /* release SDIO Host Controller info */
619 kfree(sdhc);
620 return 0;
621}
622
623int brcmf_sdio_register(struct brcmf_sdioh_driver *driver)
624{
625 drvinfo = *driver;
626
627 SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
628 return brcmf_sdio_function_init();
629}
630
631void brcmf_sdio_unregister(void)
632{
633 brcmf_sdio_function_cleanup();
634}
635
636void brcmf_sdio_wdtmr_enable(bool enable)
637{
638 if (enable)
639 brcmf_sdbrcm_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms);
640 else
641 brcmf_sdbrcm_wd_timer(sdhcinfo->ch, 0);
642}
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
new file mode 100644
index 00000000000..38bd9ba3096
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -0,0 +1,1196 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/types.h>
17#include <linux/netdevice.h>
18#include <linux/mmc/sdio.h>
19#include <linux/mmc/core.h>
20#include <linux/mmc/sdio_func.h>
21#include <linux/mmc/sdio_ids.h>
22#include <linux/mmc/card.h>
23#include <linux/suspend.h>
24#include <linux/errno.h>
25#include <linux/sched.h> /* request_irq() */
26#include <net/cfg80211.h>
27
28#include <defs.h>
29#include <brcm_hw_ids.h>
30#include <brcmu_utils.h>
31#include <brcmu_wifi.h>
32#include "sdio_host.h"
33#include "dhd.h"
34#include "dhd_dbg.h"
35#include "wl_cfg80211.h"
36
37#define BLOCK_SIZE_64 64
38#define BLOCK_SIZE_512 512
39#define BLOCK_SIZE_4318 64
40#define BLOCK_SIZE_4328 512
41
42/* private bus modes */
43#define SDIOH_MODE_SD4 2
44
45#define CLIENT_INTR 0x100 /* Get rid of this! */
46
47#if !defined(SDIO_VENDOR_ID_BROADCOM)
48#define SDIO_VENDOR_ID_BROADCOM 0x02d0
49#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */
50
51#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000
52
53#define DMA_ALIGN_MASK 0x03
54
55#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)
56#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */
57#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */
58#if !defined(SDIO_DEVICE_ID_BROADCOM_4325)
59#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493
60#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
61#if !defined(SDIO_DEVICE_ID_BROADCOM_4329)
62#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
63#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
64#if !defined(SDIO_DEVICE_ID_BROADCOM_4319)
65#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319
66#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
67
68/* Common msglevel constants */
69#define SDH_ERROR_VAL 0x0001 /* Error */
70#define SDH_TRACE_VAL 0x0002 /* Trace */
71#define SDH_INFO_VAL 0x0004 /* Info */
72#define SDH_DEBUG_VAL 0x0008 /* Debug */
73#define SDH_DATA_VAL 0x0010 /* Data */
74#define SDH_CTRL_VAL 0x0020 /* Control Regs */
75#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */
76#define SDH_DMA_VAL 0x0080 /* DMA */
77
78#ifdef BCMDBG
79#define sd_err(x) \
80 do { \
81 if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) \
82 printk x; \
83 } while (0)
84#define sd_trace(x) \
85 do { \
86 if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) \
87 printk x; \
88 } while (0)
89#define sd_info(x) \
90 do { \
91 if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) \
92 printk x; \
93 } while (0)
94#define sd_debug(x) \
95 do { \
96 if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) \
97 printk x; \
98 } while (0)
99#define sd_data(x) \
100 do { \
101 if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) \
102 printk x; \
103 } while (0)
104#define sd_ctrl(x) \
105 do { \
106 if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) \
107 printk x; \
108 } while (0)
109#else
110#define sd_err(x)
111#define sd_trace(x)
112#define sd_info(x)
113#define sd_debug(x)
114#define sd_data(x)
115#define sd_ctrl(x)
116#endif
117
118struct sdos_info {
119 struct sdioh_info *sd;
120 spinlock_t lock;
121};
122
123static void brcmf_sdioh_irqhandler(struct sdio_func *func);
124static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func);
125static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr);
126static int brcmf_ops_sdio_probe(struct sdio_func *func,
127 const struct sdio_device_id *id);
128static void brcmf_ops_sdio_remove(struct sdio_func *func);
129
130#ifdef CONFIG_PM
131static int brcmf_sdio_suspend(struct device *dev);
132static int brcmf_sdio_resume(struct device *dev);
133#endif /* CONFIG_PM */
134
135uint sd_f2_blocksize = 512; /* Default blocksize */
136
137uint sd_msglevel = 0x01;
138
139/* module param defaults */
140static int clockoverride;
141
142module_param(clockoverride, int, 0644);
143MODULE_PARM_DESC(clockoverride, "SDIO card clock override");
144
145struct brcmf_sdmmc_instance *gInstance;
146
147struct device sdmmc_dev;
148
149/* devices we support, null terminated */
150static const struct sdio_device_id brcmf_sdmmc_ids[] = {
151 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT)},
152 {SDIO_DEVICE
153 (SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)},
154 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325)},
155 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
156 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319)},
157 { /* end: all zeroes */ },
158};
159
160#ifdef CONFIG_PM
161static const struct dev_pm_ops brcmf_sdio_pm_ops = {
162 .suspend = brcmf_sdio_suspend,
163 .resume = brcmf_sdio_resume,
164};
165#endif /* CONFIG_PM */
166
167static struct sdio_driver brcmf_sdmmc_driver = {
168 .probe = brcmf_ops_sdio_probe,
169 .remove = brcmf_ops_sdio_remove,
170 .name = "brcmfmac",
171 .id_table = brcmf_sdmmc_ids,
172#ifdef CONFIG_PM
173 .drv = {
174 .pm = &brcmf_sdio_pm_ops,
175 },
176#endif /* CONFIG_PM */
177};
178
179MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
180
181BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait);
182BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_word_wait);
183BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait);
184BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait);
185
186static int
187brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr,
188 int regsize, u32 *data);
189
190static int brcmf_sdioh_enablefuncs(struct sdioh_info *sd)
191{
192 int err_ret;
193 u32 fbraddr;
194 u8 func;
195
196 sd_trace(("%s\n", __func__));
197
198 /* Get the Card's common CIS address */
199 sd->com_cis_ptr = brcmf_sdioh_get_cisaddr(sd, SDIO_CCCR_CIS);
200 sd->func_cis_ptr[0] = sd->com_cis_ptr;
201 sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__,
202 sd->com_cis_ptr));
203
204 /* Get the Card's function CIS (for each function) */
205 for (fbraddr = SDIO_FBR_BASE(1), func = 1;
206 func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
207 sd->func_cis_ptr[func] =
208 brcmf_sdioh_get_cisaddr(sd, SDIO_FBR_CIS + fbraddr);
209 sd_info(("%s: Function %d CIS Ptr = 0x%x\n", __func__, func,
210 sd->func_cis_ptr[func]));
211 }
212
213 sd->func_cis_ptr[0] = sd->com_cis_ptr;
214 sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__,
215 sd->com_cis_ptr));
216
217 /* Enable Function 1 */
218 sdio_claim_host(gInstance->func[1]);
219 err_ret = sdio_enable_func(gInstance->func[1]);
220 sdio_release_host(gInstance->func[1]);
221 if (err_ret) {
222 sd_err(("brcmf_sdioh_enablefuncs: Failed to enable F1 "
223 "Err: 0x%08x\n", err_ret));
224 }
225
226 return false;
227}
228
229/*
230 * Public entry points & extern's
231 */
232struct sdioh_info *brcmf_sdioh_attach(void *bar0, uint irq)
233{
234 struct sdioh_info *sd;
235 int err_ret;
236
237 sd_trace(("%s\n", __func__));
238
239 if (gInstance == NULL) {
240 sd_err(("%s: SDIO Device not present\n", __func__));
241 return NULL;
242 }
243
244 sd = kzalloc(sizeof(struct sdioh_info), GFP_ATOMIC);
245 if (sd == NULL) {
246 sd_err(("sdioh_attach: out of memory\n"));
247 return NULL;
248 }
249 if (brcmf_sdioh_osinit(sd) != 0) {
250 sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __func__));
251 kfree(sd);
252 return NULL;
253 }
254
255 sd->num_funcs = 2;
256 sd->use_client_ints = true;
257 sd->client_block_size[0] = 64;
258
259 gInstance->sd = sd;
260
261 /* Claim host controller */
262 sdio_claim_host(gInstance->func[1]);
263
264 sd->client_block_size[1] = 64;
265 err_ret = sdio_set_block_size(gInstance->func[1], 64);
266 if (err_ret)
267 sd_err(("brcmf_sdioh_attach: Failed to set F1 blocksize\n"));
268
269 /* Release host controller F1 */
270 sdio_release_host(gInstance->func[1]);
271
272 if (gInstance->func[2]) {
273 /* Claim host controller F2 */
274 sdio_claim_host(gInstance->func[2]);
275
276 sd->client_block_size[2] = sd_f2_blocksize;
277 err_ret =
278 sdio_set_block_size(gInstance->func[2], sd_f2_blocksize);
279 if (err_ret)
280 sd_err(("brcmf_sdioh_attach: Failed to set F2 blocksize"
281 " to %d\n", sd_f2_blocksize));
282
283 /* Release host controller F2 */
284 sdio_release_host(gInstance->func[2]);
285 }
286
287 brcmf_sdioh_enablefuncs(sd);
288
289 sd_trace(("%s: Done\n", __func__));
290 return sd;
291}
292
293extern int brcmf_sdioh_detach(struct sdioh_info *sd)
294{
295 sd_trace(("%s\n", __func__));
296
297 if (sd) {
298
299 /* Disable Function 2 */
300 sdio_claim_host(gInstance->func[2]);
301 sdio_disable_func(gInstance->func[2]);
302 sdio_release_host(gInstance->func[2]);
303
304 /* Disable Function 1 */
305 sdio_claim_host(gInstance->func[1]);
306 sdio_disable_func(gInstance->func[1]);
307 sdio_release_host(gInstance->func[1]);
308
309 /* deregister irq */
310 brcmf_sdioh_osfree(sd);
311
312 kfree(sd);
313 }
314 return 0;
315}
316
317/* Configure callback to client when we receive client interrupt */
318extern int
319brcmf_sdioh_interrupt_register(struct sdioh_info *sd, void (*fn)(void *),
320 void *argh)
321{
322 sd_trace(("%s: Entering\n", __func__));
323 if (fn == NULL) {
324 sd_err(("%s: interrupt handler is NULL, not registering\n",
325 __func__));
326 return -EINVAL;
327 }
328
329 sd->intr_handler = fn;
330 sd->intr_handler_arg = argh;
331 sd->intr_handler_valid = true;
332
333 /* register and unmask irq */
334 if (gInstance->func[2]) {
335 sdio_claim_host(gInstance->func[2]);
336 sdio_claim_irq(gInstance->func[2], brcmf_sdioh_irqhandler_f2);
337 sdio_release_host(gInstance->func[2]);
338 }
339
340 if (gInstance->func[1]) {
341 sdio_claim_host(gInstance->func[1]);
342 sdio_claim_irq(gInstance->func[1], brcmf_sdioh_irqhandler);
343 sdio_release_host(gInstance->func[1]);
344 }
345
346 return 0;
347}
348
349extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *sd)
350{
351 sd_trace(("%s: Entering\n", __func__));
352
353 if (gInstance->func[1]) {
354 /* register and unmask irq */
355 sdio_claim_host(gInstance->func[1]);
356 sdio_release_irq(gInstance->func[1]);
357 sdio_release_host(gInstance->func[1]);
358 }
359
360 if (gInstance->func[2]) {
361 /* Claim host controller F2 */
362 sdio_claim_host(gInstance->func[2]);
363 sdio_release_irq(gInstance->func[2]);
364 /* Release host controller F2 */
365 sdio_release_host(gInstance->func[2]);
366 }
367
368 sd->intr_handler_valid = false;
369 sd->intr_handler = NULL;
370 sd->intr_handler_arg = NULL;
371
372 return 0;
373}
374
375/* IOVar table */
376enum {
377 IOV_MSGLEVEL = 1,
378 IOV_BLOCKSIZE,
379 IOV_USEINTS,
380 IOV_NUMINTS,
381 IOV_DEVREG,
382 IOV_HCIREGS,
383 IOV_RXCHAIN
384};
385
386const struct brcmu_iovar sdioh_iovars[] = {
387 {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0},
388 {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0},/* ((fn << 16) |
389 size) */
390 {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0},
391 {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0},
392 {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)}
393 ,
394 {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0}
395 ,
396 {NULL, 0, 0, 0, 0}
397};
398
399int
400brcmf_sdioh_iovar_op(struct sdioh_info *si, const char *name,
401 void *params, int plen, void *arg, int len, bool set)
402{
403 const struct brcmu_iovar *vi = NULL;
404 int bcmerror = 0;
405 int val_size;
406 s32 int_val = 0;
407 bool bool_val;
408 u32 actionid;
409
410 if (name == NULL || len <= 0)
411 return -EINVAL;
412
413 /* Set does not take qualifiers */
414 if (set && (params || plen))
415 return -EINVAL;
416
417 /* Get must have return space;*/
418 if (!set && !(arg && len))
419 return -EINVAL;
420
421 sd_trace(("%s: Enter (%s %s)\n", __func__, (set ? "set" : "get"),
422 name));
423
424 vi = brcmu_iovar_lookup(sdioh_iovars, name);
425 if (vi == NULL) {
426 bcmerror = -ENOTSUPP;
427 goto exit;
428 }
429
430 bcmerror = brcmu_iovar_lencheck(vi, arg, len, set);
431 if (bcmerror != 0)
432 goto exit;
433
434 /* Set up params so get and set can share the convenience variables */
435 if (params == NULL) {
436 params = arg;
437 plen = len;
438 }
439
440 if (vi->type == IOVT_VOID)
441 val_size = 0;
442 else if (vi->type == IOVT_BUFFER)
443 val_size = len;
444 else
445 val_size = sizeof(int);
446
447 if (plen >= (int)sizeof(int_val))
448 memcpy(&int_val, params, sizeof(int_val));
449
450 bool_val = (int_val != 0) ? true : false;
451
452 actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
453 switch (actionid) {
454 case IOV_GVAL(IOV_MSGLEVEL):
455 int_val = (s32) sd_msglevel;
456 memcpy(arg, &int_val, val_size);
457 break;
458
459 case IOV_SVAL(IOV_MSGLEVEL):
460 sd_msglevel = int_val;
461 break;
462
463 case IOV_GVAL(IOV_BLOCKSIZE):
464 if ((u32) int_val > si->num_funcs) {
465 bcmerror = -EINVAL;
466 break;
467 }
468 int_val = (s32) si->client_block_size[int_val];
469 memcpy(arg, &int_val, val_size);
470 break;
471
472 case IOV_SVAL(IOV_BLOCKSIZE):
473 {
474 uint func = ((u32) int_val >> 16);
475 uint blksize = (u16) int_val;
476 uint maxsize;
477
478 if (func > si->num_funcs) {
479 bcmerror = -EINVAL;
480 break;
481 }
482
483 switch (func) {
484 case 0:
485 maxsize = 32;
486 break;
487 case 1:
488 maxsize = BLOCK_SIZE_4318;
489 break;
490 case 2:
491 maxsize = BLOCK_SIZE_4328;
492 break;
493 default:
494 maxsize = 0;
495 }
496 if (blksize > maxsize) {
497 bcmerror = -EINVAL;
498 break;
499 }
500 if (!blksize)
501 blksize = maxsize;
502
503 /* Now set it */
504 si->client_block_size[func] = blksize;
505
506 break;
507 }
508
509 case IOV_GVAL(IOV_RXCHAIN):
510 int_val = false;
511 memcpy(arg, &int_val, val_size);
512 break;
513
514 case IOV_GVAL(IOV_USEINTS):
515 int_val = (s32) si->use_client_ints;
516 memcpy(arg, &int_val, val_size);
517 break;
518
519 case IOV_SVAL(IOV_USEINTS):
520 si->use_client_ints = (bool) int_val;
521 if (si->use_client_ints)
522 si->intmask |= CLIENT_INTR;
523 else
524 si->intmask &= ~CLIENT_INTR;
525
526 break;
527
528 case IOV_GVAL(IOV_NUMINTS):
529 int_val = (s32) si->intrcount;
530 memcpy(arg, &int_val, val_size);
531 break;
532
533 case IOV_GVAL(IOV_DEVREG):
534 {
535 struct brcmf_sdreg *sd_ptr =
536 (struct brcmf_sdreg *) params;
537 u8 data = 0;
538
539 if (brcmf_sdioh_cfg_read
540 (si, sd_ptr->func, sd_ptr->offset, &data)) {
541 bcmerror = -EIO;
542 break;
543 }
544
545 int_val = (int)data;
546 memcpy(arg, &int_val, sizeof(int_val));
547 break;
548 }
549
550 case IOV_SVAL(IOV_DEVREG):
551 {
552 struct brcmf_sdreg *sd_ptr =
553 (struct brcmf_sdreg *) params;
554 u8 data = (u8) sd_ptr->value;
555
556 if (brcmf_sdioh_cfg_write
557 (si, sd_ptr->func, sd_ptr->offset, &data)) {
558 bcmerror = -EIO;
559 break;
560 }
561 break;
562 }
563
564 default:
565 bcmerror = -ENOTSUPP;
566 break;
567 }
568exit:
569
570 return bcmerror;
571}
572
573extern int
574brcmf_sdioh_cfg_read(struct sdioh_info *sd, uint fnc_num, u32 addr, u8 *data)
575{
576 int status;
577 /* No lock needed since brcmf_sdioh_request_byte does locking */
578 status = brcmf_sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
579 return status;
580}
581
582extern int
583brcmf_sdioh_cfg_write(struct sdioh_info *sd, uint fnc_num, u32 addr, u8 *data)
584{
585 /* No lock needed since brcmf_sdioh_request_byte does locking */
586 int status;
587 status = brcmf_sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
588 return status;
589}
590
591static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr)
592{
593 /* read 24 bits and return valid 17 bit addr */
594 int i;
595 u32 scratch, regdata;
596 u8 *ptr = (u8 *)&scratch;
597 for (i = 0; i < 3; i++) {
598 if ((brcmf_sdioh_card_regread(sd, 0, regaddr, 1, &regdata)) !=
599 SUCCESS)
600 sd_err(("%s: Can't read!\n", __func__));
601
602 *ptr++ = (u8) regdata;
603 regaddr++;
604 }
605
606 /* Only the lower 17-bits are valid */
607 scratch = le32_to_cpu(scratch);
608 scratch &= 0x0001FFFF;
609 return scratch;
610}
611
612extern int
613brcmf_sdioh_cis_read(struct sdioh_info *sd, uint func, u8 *cisd, u32 length)
614{
615 u32 count;
616 int offset;
617 u32 foo;
618 u8 *cis = cisd;
619
620 sd_trace(("%s: Func = %d\n", __func__, func));
621
622 if (!sd->func_cis_ptr[func]) {
623 memset(cis, 0, length);
624 sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func));
625 return -ENOTSUPP;
626 }
627
628 sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __func__, func,
629 sd->func_cis_ptr[func]));
630
631 for (count = 0; count < length; count++) {
632 offset = sd->func_cis_ptr[func] + count;
633 if (brcmf_sdioh_card_regread(sd, 0, offset, 1, &foo) < 0) {
634 sd_err(("%s: regread failed: Can't read CIS\n",
635 __func__));
636 return -EIO;
637 }
638
639 *cis = (u8) (foo & 0xff);
640 cis++;
641 }
642
643 return 0;
644}
645
646extern int
647brcmf_sdioh_request_byte(struct sdioh_info *sd, uint rw, uint func,
648 uint regaddr, u8 *byte)
649{
650 int err_ret;
651
652 sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __func__, rw, func,
653 regaddr));
654
655 BRCMF_PM_RESUME_WAIT(sdioh_request_byte_wait);
656 BRCMF_PM_RESUME_RETURN_ERROR(-EIO);
657 if (rw) { /* CMD52 Write */
658 if (func == 0) {
659 /* Can only directly write to some F0 registers.
660 * Handle F2 enable
661 * as a special case.
662 */
663 if (regaddr == SDIO_CCCR_IOEx) {
664 if (gInstance->func[2]) {
665 sdio_claim_host(gInstance->func[2]);
666 if (*byte & SDIO_FUNC_ENABLE_2) {
667 /* Enable Function 2 */
668 err_ret =
669 sdio_enable_func
670 (gInstance->func[2]);
671 if (err_ret)
672 sd_err(("request_byte: "
673 "enable F2 "
674 "failed:%d\n",
675 err_ret));
676 } else {
677 /* Disable Function 2 */
678 err_ret =
679 sdio_disable_func
680 (gInstance->func[2]);
681 if (err_ret)
682 sd_err(("request_byte: "
683 "Disab F2 "
684 "failed:%d\n",
685 err_ret));
686 }
687 sdio_release_host(gInstance->func[2]);
688 }
689 }
690 /* to allow abort command through F1 */
691 else if (regaddr == SDIO_CCCR_ABORT) {
692 sdio_claim_host(gInstance->func[func]);
693 /*
694 * this sdio_f0_writeb() can be replaced
695 * with another api
696 * depending upon MMC driver change.
697 * As of this time, this is temporaray one
698 */
699 sdio_writeb(gInstance->func[func], *byte,
700 regaddr, &err_ret);
701 sdio_release_host(gInstance->func[func]);
702 } else if (regaddr < 0xF0) {
703 sd_err(("brcmf: F0 Wr:0x%02x: write "
704 "disallowed\n", regaddr));
705 } else {
706 /* Claim host controller, perform F0 write,
707 and release */
708 sdio_claim_host(gInstance->func[func]);
709 sdio_f0_writeb(gInstance->func[func], *byte,
710 regaddr, &err_ret);
711 sdio_release_host(gInstance->func[func]);
712 }
713 } else {
714 /* Claim host controller, perform Fn write,
715 and release */
716 sdio_claim_host(gInstance->func[func]);
717 sdio_writeb(gInstance->func[func], *byte, regaddr,
718 &err_ret);
719 sdio_release_host(gInstance->func[func]);
720 }
721 } else { /* CMD52 Read */
722 /* Claim host controller, perform Fn read, and release */
723 sdio_claim_host(gInstance->func[func]);
724
725 if (func == 0) {
726 *byte =
727 sdio_f0_readb(gInstance->func[func], regaddr,
728 &err_ret);
729 } else {
730 *byte =
731 sdio_readb(gInstance->func[func], regaddr,
732 &err_ret);
733 }
734
735 sdio_release_host(gInstance->func[func]);
736 }
737
738 if (err_ret)
739 sd_err(("brcmf: Failed to %s byte F%d:@0x%05x=%02x, "
740 "Err: %d\n", rw ? "Write" : "Read", func, regaddr,
741 *byte, err_ret));
742
743 return err_ret;
744}
745
746extern int
747brcmf_sdioh_request_word(struct sdioh_info *sd, uint cmd_type, uint rw,
748 uint func, uint addr, u32 *word, uint nbytes)
749{
750 int err_ret = -EIO;
751
752 if (func == 0) {
753 sd_err(("%s: Only CMD52 allowed to F0.\n", __func__));
754 return -EINVAL;
755 }
756
757 sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
758 __func__, cmd_type, rw, func, addr, nbytes));
759
760 BRCMF_PM_RESUME_WAIT(sdioh_request_word_wait);
761 BRCMF_PM_RESUME_RETURN_ERROR(-EIO);
762 /* Claim host controller */
763 sdio_claim_host(gInstance->func[func]);
764
765 if (rw) { /* CMD52 Write */
766 if (nbytes == 4) {
767 sdio_writel(gInstance->func[func], *word, addr,
768 &err_ret);
769 } else if (nbytes == 2) {
770 sdio_writew(gInstance->func[func], (*word & 0xFFFF),
771 addr, &err_ret);
772 } else {
773 sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes));
774 }
775 } else { /* CMD52 Read */
776 if (nbytes == 4) {
777 *word =
778 sdio_readl(gInstance->func[func], addr, &err_ret);
779 } else if (nbytes == 2) {
780 *word =
781 sdio_readw(gInstance->func[func], addr,
782 &err_ret) & 0xFFFF;
783 } else {
784 sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes));
785 }
786 }
787
788 /* Release host controller */
789 sdio_release_host(gInstance->func[func]);
790
791 if (err_ret) {
792 sd_err(("brcmf: Failed to %s word, Err: 0x%08x\n",
793 rw ? "Write" : "Read", err_ret));
794 }
795
796 return err_ret;
797}
798
799static int
800brcmf_sdioh_request_packet(struct sdioh_info *sd, uint fix_inc, uint write,
801 uint func, uint addr, struct sk_buff *pkt)
802{
803 bool fifo = (fix_inc == SDIOH_DATA_FIX);
804 u32 SGCount = 0;
805 int err_ret = 0;
806
807 struct sk_buff *pnext;
808
809 sd_trace(("%s: Enter\n", __func__));
810
811 BRCMF_PM_RESUME_WAIT(sdioh_request_packet_wait);
812 BRCMF_PM_RESUME_RETURN_ERROR(-EIO);
813
814 /* Claim host controller */
815 sdio_claim_host(gInstance->func[func]);
816 for (pnext = pkt; pnext; pnext = pnext->next) {
817 uint pkt_len = pnext->len;
818 pkt_len += 3;
819 pkt_len &= 0xFFFFFFFC;
820
821 if ((write) && (!fifo)) {
822 err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
823 ((u8 *) (pnext->data)),
824 pkt_len);
825 } else if (write) {
826 err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
827 ((u8 *) (pnext->data)),
828 pkt_len);
829 } else if (fifo) {
830 err_ret = sdio_readsb(gInstance->func[func],
831 ((u8 *) (pnext->data)),
832 addr, pkt_len);
833 } else {
834 err_ret = sdio_memcpy_fromio(gInstance->func[func],
835 ((u8 *) (pnext->data)),
836 addr, pkt_len);
837 }
838
839 if (err_ret) {
840 sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d,"
841 "ERR=0x%08x\n", __func__,
842 (write) ? "TX" : "RX",
843 pnext, SGCount, addr, pkt_len, err_ret));
844 } else {
845 sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n",
846 __func__,
847 (write) ? "TX" : "RX",
848 pnext, SGCount, addr, pkt_len));
849 }
850
851 if (!fifo)
852 addr += pkt_len;
853 SGCount++;
854
855 }
856
857 /* Release host controller */
858 sdio_release_host(gInstance->func[func]);
859
860 sd_trace(("%s: Exit\n", __func__));
861 return err_ret;
862}
863
864/*
865 * This function takes a buffer or packet, and fixes everything up
866 * so that in the end, a DMA-able packet is created.
867 *
868 * A buffer does not have an associated packet pointer,
869 * and may or may not be aligned.
870 * A packet may consist of a single packet, or a packet chain.
871 * If it is a packet chain, then all the packets in the chain
872 * must be properly aligned.
873 *
874 * If the packet data is not aligned, then there may only be
875 * one packet, and in this case, it is copied to a new
876 * aligned packet.
877 *
878 */
879extern int
880brcmf_sdioh_request_buffer(struct sdioh_info *sd, uint pio_dma, uint fix_inc,
881 uint write, uint func, uint addr, uint reg_width,
882 uint buflen_u, u8 *buffer, struct sk_buff *pkt)
883{
884 int Status;
885 struct sk_buff *mypkt = NULL;
886
887 sd_trace(("%s: Enter\n", __func__));
888
889 BRCMF_PM_RESUME_WAIT(sdioh_request_buffer_wait);
890 BRCMF_PM_RESUME_RETURN_ERROR(-EIO);
891 /* Case 1: we don't have a packet. */
892 if (pkt == NULL) {
893 sd_data(("%s: Creating new %s Packet, len=%d\n",
894 __func__, write ? "TX" : "RX", buflen_u));
895 mypkt = brcmu_pkt_buf_get_skb(buflen_u);
896 if (!mypkt) {
897 sd_err(("%s: brcmu_pkt_buf_get_skb failed: len %d\n",
898 __func__, buflen_u));
899 return -EIO;
900 }
901
902 /* For a write, copy the buffer data into the packet. */
903 if (write)
904 memcpy(mypkt->data, buffer, buflen_u);
905
906 Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func,
907 addr, mypkt);
908
909 /* For a read, copy the packet data back to the buffer. */
910 if (!write)
911 memcpy(buffer, mypkt->data, buflen_u);
912
913 brcmu_pkt_buf_free_skb(mypkt);
914 } else if (((ulong) (pkt->data) & DMA_ALIGN_MASK) != 0) {
915 /*
916 * Case 2: We have a packet, but it is unaligned.
917 * In this case, we cannot have a chain (pkt->next == NULL)
918 */
919 sd_data(("%s: Creating aligned %s Packet, len=%d\n",
920 __func__, write ? "TX" : "RX", pkt->len));
921 mypkt = brcmu_pkt_buf_get_skb(pkt->len);
922 if (!mypkt) {
923 sd_err(("%s: brcmu_pkt_buf_get_skb failed: len %d\n",
924 __func__, pkt->len));
925 return -EIO;
926 }
927
928 /* For a write, copy the buffer data into the packet. */
929 if (write)
930 memcpy(mypkt->data, pkt->data, pkt->len);
931
932 Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func,
933 addr, mypkt);
934
935 /* For a read, copy the packet data back to the buffer. */
936 if (!write)
937 memcpy(pkt->data, mypkt->data, mypkt->len);
938
939 brcmu_pkt_buf_free_skb(mypkt);
940 } else { /* case 3: We have a packet and
941 it is aligned. */
942 sd_data(("%s: Aligned %s Packet, direct DMA\n",
943 __func__, write ? "Tx" : "Rx"));
944 Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func,
945 addr, pkt);
946 }
947
948 return Status;
949}
950
951/* this function performs "abort" for both of host & device */
952extern int brcmf_sdioh_abort(struct sdioh_info *sd, uint func)
953{
954 char t_func = (char)func;
955 sd_trace(("%s: Enter\n", __func__));
956
957 /* issue abort cmd52 command through F0 */
958 brcmf_sdioh_request_byte(sd, SDIOH_WRITE, SDIO_FUNC_0, SDIO_CCCR_ABORT,
959 &t_func);
960
961 sd_trace(("%s: Exit\n", __func__));
962 return 0;
963}
964
965/* Disable device interrupt */
966void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd)
967{
968 sd_trace(("%s: %d\n", __func__, sd->use_client_ints));
969 sd->intmask &= ~CLIENT_INTR;
970}
971
972/* Enable device interrupt */
973void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd)
974{
975 sd_trace(("%s: %d\n", __func__, sd->use_client_ints));
976 sd->intmask |= CLIENT_INTR;
977}
978
979/* Read client card reg */
980int
981brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr,
982 int regsize, u32 *data)
983{
984
985 if ((func == 0) || (regsize == 1)) {
986 u8 temp = 0;
987
988 brcmf_sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
989 *data = temp;
990 *data &= 0xff;
991 sd_data(("%s: byte read data=0x%02x\n", __func__, *data));
992 } else {
993 brcmf_sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data,
994 regsize);
995 if (regsize == 2)
996 *data &= 0xffff;
997
998 sd_data(("%s: word read data=0x%08x\n", __func__, *data));
999 }
1000
1001 return SUCCESS;
1002}
1003
1004static void brcmf_sdioh_irqhandler(struct sdio_func *func)
1005{
1006 struct sdioh_info *sd;
1007
1008 sd_trace(("brcmf: ***IRQHandler\n"));
1009 sd = gInstance->sd;
1010
1011 sdio_release_host(gInstance->func[0]);
1012
1013 if (sd->use_client_ints) {
1014 sd->intrcount++;
1015 (sd->intr_handler) (sd->intr_handler_arg);
1016 } else {
1017 sd_err(("brcmf: ***IRQHandler\n"));
1018
1019 sd_err(("%s: Not ready for intr: enabled %d, handler %p\n",
1020 __func__, sd->client_intr_enabled, sd->intr_handler));
1021 }
1022
1023 sdio_claim_host(gInstance->func[0]);
1024}
1025
1026/* interrupt handler for F2 (dummy handler) */
1027static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func)
1028{
1029 struct sdioh_info *sd;
1030
1031 sd_trace(("brcmf: ***IRQHandlerF2\n"));
1032
1033 sd = gInstance->sd;
1034}
1035
1036static int brcmf_ops_sdio_probe(struct sdio_func *func,
1037 const struct sdio_device_id *id)
1038{
1039 int ret = 0;
1040 static struct sdio_func sdio_func_0;
1041 sd_trace(("sdio_probe: %s Enter\n", __func__));
1042 sd_trace(("sdio_probe: func->class=%x\n", func->class));
1043 sd_trace(("sdio_vendor: 0x%04x\n", func->vendor));
1044 sd_trace(("sdio_device: 0x%04x\n", func->device));
1045 sd_trace(("Function#: 0x%04x\n", func->num));
1046
1047 if (func->num == 1) {
1048 sdio_func_0.num = 0;
1049 sdio_func_0.card = func->card;
1050 gInstance->func[0] = &sdio_func_0;
1051 if (func->device == 0x4) { /* 4318 */
1052 gInstance->func[2] = NULL;
1053 sd_trace(("NIC found, calling brcmf_sdio_probe...\n"));
1054 ret = brcmf_sdio_probe(&sdmmc_dev);
1055 }
1056 }
1057
1058 gInstance->func[func->num] = func;
1059
1060 if (func->num == 2) {
1061 brcmf_cfg80211_sdio_func(func);
1062 sd_trace(("F2 found, calling brcmf_sdio_probe...\n"));
1063 ret = brcmf_sdio_probe(&sdmmc_dev);
1064 }
1065
1066 return ret;
1067}
1068
1069static void brcmf_ops_sdio_remove(struct sdio_func *func)
1070{
1071 sd_trace(("%s Enter\n", __func__));
1072 sd_info(("func->class=%x\n", func->class));
1073 sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
1074 sd_info(("sdio_device: 0x%04x\n", func->device));
1075 sd_info(("Function#: 0x%04x\n", func->num));
1076
1077 if (func->num == 2) {
1078 sd_trace(("F2 found, calling brcmf_sdio_remove...\n"));
1079 brcmf_sdio_remove(&sdmmc_dev);
1080 }
1081}
1082
1083
1084#ifdef CONFIG_PM
1085static int brcmf_sdio_suspend(struct device *dev)
1086{
1087 mmc_pm_flag_t sdio_flags;
1088 int ret = 0;
1089
1090 sd_trace(("%s\n", __func__));
1091
1092 sdio_flags = sdio_get_host_pm_caps(gInstance->func[1]);
1093 if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
1094 sd_err(("Host can't keep power while suspended\n"));
1095 return -EINVAL;
1096 }
1097
1098 ret = sdio_set_host_pm_flags(gInstance->func[1], MMC_PM_KEEP_POWER);
1099 if (ret) {
1100 sd_err(("Failed to set pm_flags\n"));
1101 return ret;
1102 }
1103
1104 brcmf_sdio_wdtmr_enable(false);
1105
1106 return ret;
1107}
1108
1109static int brcmf_sdio_resume(struct device *dev)
1110{
1111 brcmf_sdio_wdtmr_enable(true);
1112 return 0;
1113}
1114#endif /* CONFIG_PM */
1115
1116int brcmf_sdioh_osinit(struct sdioh_info *sd)
1117{
1118 struct sdos_info *sdos;
1119
1120 sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC);
1121 sd->sdos_info = (void *)sdos;
1122 if (sdos == NULL)
1123 return -ENOMEM;
1124
1125 sdos->sd = sd;
1126 spin_lock_init(&sdos->lock);
1127 return 0;
1128}
1129
1130void brcmf_sdioh_osfree(struct sdioh_info *sd)
1131{
1132 struct sdos_info *sdos;
1133
1134 sdos = (struct sdos_info *)sd->sdos_info;
1135 kfree(sdos);
1136}
1137
1138/* Interrupt enable/disable */
1139int brcmf_sdioh_interrupt_set(struct sdioh_info *sd, bool enable)
1140{
1141 unsigned long flags;
1142 struct sdos_info *sdos;
1143
1144 sd_trace(("%s: %s\n", __func__, enable ? "Enabling" : "Disabling"));
1145
1146 sdos = (struct sdos_info *)sd->sdos_info;
1147
1148 if (enable && !(sd->intr_handler && sd->intr_handler_arg)) {
1149 sd_err(("%s: no handler registered, will not enable\n",
1150 __func__));
1151 return -EINVAL;
1152 }
1153
1154 /* Ensure atomicity for enable/disable calls */
1155 spin_lock_irqsave(&sdos->lock, flags);
1156
1157 sd->client_intr_enabled = enable;
1158 if (enable)
1159 brcmf_sdioh_dev_intr_on(sd);
1160 else
1161 brcmf_sdioh_dev_intr_off(sd);
1162
1163 spin_unlock_irqrestore(&sdos->lock, flags);
1164
1165 return 0;
1166}
1167
1168/*
1169 * module init
1170*/
1171int brcmf_sdio_function_init(void)
1172{
1173 int error = 0;
1174 sd_trace(("brcmf_sdio_function_init: %s Enter\n", __func__));
1175
1176 gInstance = kzalloc(sizeof(struct brcmf_sdmmc_instance), GFP_KERNEL);
1177 if (!gInstance)
1178 return -ENOMEM;
1179
1180 memset(&sdmmc_dev, 0, sizeof(sdmmc_dev));
1181 error = sdio_register_driver(&brcmf_sdmmc_driver);
1182
1183 return error;
1184}
1185
1186/*
1187 * module cleanup
1188*/
1189void brcmf_sdio_function_cleanup(void)
1190{
1191 sd_trace(("%s Enter\n", __func__));
1192
1193 sdio_unregister_driver(&brcmf_sdmmc_driver);
1194
1195 kfree(gInstance);
1196}
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h
new file mode 100644
index 00000000000..82bf04df16d
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/dhd.h
@@ -0,0 +1,904 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/****************
18 * Common types *
19 */
20
21#ifndef _BRCMF_H_
22#define _BRCMF_H_
23
24#define BRCMF_VERSION_STR "4.218.248.5"
25
26#define BRCMF_C_IOCTL_SMLEN 256 /* "small" ioctl buffer required */
27#define BRCMF_C_IOCTL_MEDLEN 1536 /* "med" ioctl buffer required */
28#define BRCMF_C_IOCTL_MAXLEN 8192
29
30#define BRCMF_C_UP 2
31#define BRCMF_C_SET_PROMISC 10
32#define BRCMF_C_GET_RATE 12
33#define BRCMF_C_GET_INFRA 19
34#define BRCMF_C_SET_INFRA 20
35#define BRCMF_C_GET_AUTH 21
36#define BRCMF_C_SET_AUTH 22
37#define BRCMF_C_GET_BSSID 23
38#define BRCMF_C_GET_SSID 25
39#define BRCMF_C_SET_SSID 26
40#define BRCMF_C_GET_CHANNEL 29
41#define BRCMF_C_GET_SRL 31
42#define BRCMF_C_GET_LRL 33
43#define BRCMF_C_GET_RADIO 37
44#define BRCMF_C_SET_RADIO 38
45#define BRCMF_C_GET_PHYTYPE 39
46#define BRCMF_C_SET_KEY 45
47#define BRCMF_C_SET_PASSIVE_SCAN 49
48#define BRCMF_C_SCAN 50
49#define BRCMF_C_SCAN_RESULTS 51
50#define BRCMF_C_DISASSOC 52
51#define BRCMF_C_REASSOC 53
52#define BRCMF_C_SET_ROAM_TRIGGER 55
53#define BRCMF_C_SET_ROAM_DELTA 57
54#define BRCMF_C_GET_DTIMPRD 77
55#define BRCMF_C_SET_COUNTRY 84
56#define BRCMF_C_GET_PM 85
57#define BRCMF_C_SET_PM 86
58#define BRCMF_C_GET_AP 117
59#define BRCMF_C_SET_AP 118
60#define BRCMF_C_GET_RSSI 127
61#define BRCMF_C_GET_WSEC 133
62#define BRCMF_C_SET_WSEC 134
63#define BRCMF_C_GET_PHY_NOISE 135
64#define BRCMF_C_GET_BSS_INFO 136
65#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
66#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
67#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
68#define BRCMF_C_GET_VALID_CHANNELS 217
69#define BRCMF_C_GET_KEY_PRIMARY 235
70#define BRCMF_C_SET_KEY_PRIMARY 236
71#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
72#define BRCMF_C_GET_VAR 262
73#define BRCMF_C_SET_VAR 263
74
75/* phy types (returned by WLC_GET_PHYTPE) */
76#define WLC_PHY_TYPE_A 0
77#define WLC_PHY_TYPE_B 1
78#define WLC_PHY_TYPE_G 2
79#define WLC_PHY_TYPE_N 4
80#define WLC_PHY_TYPE_LP 5
81#define WLC_PHY_TYPE_SSN 6
82#define WLC_PHY_TYPE_HT 7
83#define WLC_PHY_TYPE_LCN 8
84#define WLC_PHY_TYPE_NULL 0xf
85
86#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter, u)
87#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
88 offsetof(struct brcmf_pkt_filter_pattern, mask_and_pattern)
89
90#define BRCMF_EVENTING_MASK_LEN 16
91
92#define TOE_TX_CSUM_OL 0x00000001
93#define TOE_RX_CSUM_OL 0x00000002
94
95/* maximum channels returned by the get valid channels iovar */
96#define WL_NUMCHANNELS 64
97
98#define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */
99
100/* size of brcmf_scan_params not including variable length array */
101#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
102
103/* masks for channel and ssid count */
104#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
105#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
106
107#define BRCMF_SCAN_ACTION_START 1
108#define BRCMF_SCAN_ACTION_CONTINUE 2
109#define WL_SCAN_ACTION_ABORT 3
110
111#define BRCMF_ISCAN_REQ_VERSION 1
112
113/* brcmf_iscan_results status values */
114#define BRCMF_SCAN_RESULTS_SUCCESS 0
115#define BRCMF_SCAN_RESULTS_PARTIAL 1
116#define BRCMF_SCAN_RESULTS_PENDING 2
117#define BRCMF_SCAN_RESULTS_ABORTED 3
118#define BRCMF_SCAN_RESULTS_NO_MEM 4
119
120#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */
121#define BRCMF_PRIMARY_KEY (1 << 1) /* primary (ie tx) key */
122#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */
123#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */
124#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */
125
126/* For supporting multiple interfaces */
127#define BRCMF_MAX_IFS 16
128#define BRCMF_DEL_IF -0xe
129#define BRCMF_BAD_IF -0xf
130
131#define DOT11_BSSTYPE_ANY 2
132#define DOT11_MAX_DEFAULT_KEYS 4
133
134#define BRCMF_EVENT_MSG_LINK 0x01
135#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
136#define BRCMF_EVENT_MSG_GROUP 0x04
137
138struct brcmf_event_msg {
139 u16 version;
140 u16 flags;
141 u32 event_type;
142 u32 status;
143 u32 reason;
144 u32 auth_type;
145 u32 datalen;
146 u8 addr[ETH_ALEN];
147 char ifname[IFNAMSIZ];
148} __packed;
149
150struct brcm_ethhdr {
151 u16 subtype;
152 u16 length;
153 u8 version;
154 u8 oui[3];
155 u16 usr_subtype;
156} __packed;
157
158struct brcmf_event {
159 struct ethhdr eth;
160 struct brcm_ethhdr hdr;
161 struct brcmf_event_msg msg;
162} __packed;
163
164struct dngl_stats {
165 unsigned long rx_packets; /* total packets received */
166 unsigned long tx_packets; /* total packets transmitted */
167 unsigned long rx_bytes; /* total bytes received */
168 unsigned long tx_bytes; /* total bytes transmitted */
169 unsigned long rx_errors; /* bad packets received */
170 unsigned long tx_errors; /* packet transmit problems */
171 unsigned long rx_dropped; /* packets dropped by dongle */
172 unsigned long tx_dropped; /* packets dropped by dongle */
173 unsigned long multicast; /* multicast packets received */
174};
175
176#define BRCMF_E_SET_SSID 0
177#define BRCMF_E_JOIN 1
178#define BRCMF_E_START 2
179#define BRCMF_E_AUTH 3
180#define BRCMF_E_AUTH_IND 4
181#define BRCMF_E_DEAUTH 5
182#define BRCMF_E_DEAUTH_IND 6
183#define BRCMF_E_ASSOC 7
184#define BRCMF_E_ASSOC_IND 8
185#define BRCMF_E_REASSOC 9
186#define BRCMF_E_REASSOC_IND 10
187#define BRCMF_E_DISASSOC 11
188#define BRCMF_E_DISASSOC_IND 12
189#define BRCMF_E_QUIET_START 13
190#define BRCMF_E_QUIET_END 14
191#define BRCMF_E_BEACON_RX 15
192#define BRCMF_E_LINK 16
193#define BRCMF_E_MIC_ERROR 17
194#define BRCMF_E_NDIS_LINK 18
195#define BRCMF_E_ROAM 19
196#define BRCMF_E_TXFAIL 20
197#define BRCMF_E_PMKID_CACHE 21
198#define BRCMF_E_RETROGRADE_TSF 22
199#define BRCMF_E_PRUNE 23
200#define BRCMF_E_AUTOAUTH 24
201#define BRCMF_E_EAPOL_MSG 25
202#define BRCMF_E_SCAN_COMPLETE 26
203#define BRCMF_E_ADDTS_IND 27
204#define BRCMF_E_DELTS_IND 28
205#define BRCMF_E_BCNSENT_IND 29
206#define BRCMF_E_BCNRX_MSG 30
207#define BRCMF_E_BCNLOST_MSG 31
208#define BRCMF_E_ROAM_PREP 32
209#define BRCMF_E_PFN_NET_FOUND 33
210#define BRCMF_E_PFN_NET_LOST 34
211#define BRCMF_E_RESET_COMPLETE 35
212#define BRCMF_E_JOIN_START 36
213#define BRCMF_E_ROAM_START 37
214#define BRCMF_E_ASSOC_START 38
215#define BRCMF_E_IBSS_ASSOC 39
216#define BRCMF_E_RADIO 40
217#define BRCMF_E_PSM_WATCHDOG 41
218#define BRCMF_E_PROBREQ_MSG 44
219#define BRCMF_E_SCAN_CONFIRM_IND 45
220#define BRCMF_E_PSK_SUP 46
221#define BRCMF_E_COUNTRY_CODE_CHANGED 47
222#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48
223#define BRCMF_E_ICV_ERROR 49
224#define BRCMF_E_UNICAST_DECODE_ERROR 50
225#define BRCMF_E_MULTICAST_DECODE_ERROR 51
226#define BRCMF_E_TRACE 52
227#define BRCMF_E_IF 54
228#define BRCMF_E_RSSI 56
229#define BRCMF_E_PFN_SCAN_COMPLETE 57
230#define BRCMF_E_EXTLOG_MSG 58
231#define BRCMF_E_ACTION_FRAME 59
232#define BRCMF_E_ACTION_FRAME_COMPLETE 60
233#define BRCMF_E_PRE_ASSOC_IND 61
234#define BRCMF_E_PRE_REASSOC_IND 62
235#define BRCMF_E_CHANNEL_ADOPTED 63
236#define BRCMF_E_AP_STARTED 64
237#define BRCMF_E_DFS_AP_STOP 65
238#define BRCMF_E_DFS_AP_RESUME 66
239#define BRCMF_E_RESERVED1 67
240#define BRCMF_E_RESERVED2 68
241#define BRCMF_E_ESCAN_RESULT 69
242#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70
243#define BRCMF_E_DCS_REQUEST 73
244
245#define BRCMF_E_FIFO_CREDIT_MAP 74
246
247#define BRCMF_E_LAST 75
248
249#define BRCMF_E_STATUS_SUCCESS 0
250#define BRCMF_E_STATUS_FAIL 1
251#define BRCMF_E_STATUS_TIMEOUT 2
252#define BRCMF_E_STATUS_NO_NETWORKS 3
253#define BRCMF_E_STATUS_ABORT 4
254#define BRCMF_E_STATUS_NO_ACK 5
255#define BRCMF_E_STATUS_UNSOLICITED 6
256#define BRCMF_E_STATUS_ATTEMPT 7
257#define BRCMF_E_STATUS_PARTIAL 8
258#define BRCMF_E_STATUS_NEWSCAN 9
259#define BRCMF_E_STATUS_NEWASSOC 10
260#define BRCMF_E_STATUS_11HQUIET 11
261#define BRCMF_E_STATUS_SUPPRESS 12
262#define BRCMF_E_STATUS_NOCHANS 13
263#define BRCMF_E_STATUS_CS_ABORT 15
264#define BRCMF_E_STATUS_ERROR 16
265
266#define BRCMF_E_REASON_INITIAL_ASSOC 0
267#define BRCMF_E_REASON_LOW_RSSI 1
268#define BRCMF_E_REASON_DEAUTH 2
269#define BRCMF_E_REASON_DISASSOC 3
270#define BRCMF_E_REASON_BCNS_LOST 4
271#define BRCMF_E_REASON_MINTXRATE 9
272#define BRCMF_E_REASON_TXFAIL 10
273
274#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
275#define BRCMF_E_REASON_DIRECTED_ROAM 6
276#define BRCMF_E_REASON_TSPEC_REJECTED 7
277#define BRCMF_E_REASON_BETTER_AP 8
278
279#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
280#define BRCMF_E_PRUNE_BCAST_BSSID 2
281#define BRCMF_E_PRUNE_MAC_DENY 3
282#define BRCMF_E_PRUNE_MAC_NA 4
283#define BRCMF_E_PRUNE_REG_PASSV 5
284#define BRCMF_E_PRUNE_SPCT_MGMT 6
285#define BRCMF_E_PRUNE_RADAR 7
286#define BRCMF_E_RSN_MISMATCH 8
287#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
288#define BRCMF_E_PRUNE_BASIC_RATES 10
289#define BRCMF_E_PRUNE_CIPHER_NA 12
290#define BRCMF_E_PRUNE_KNOWN_STA 13
291#define BRCMF_E_PRUNE_WDS_PEER 15
292#define BRCMF_E_PRUNE_QBSS_LOAD 16
293#define BRCMF_E_PRUNE_HOME_AP 17
294
295#define BRCMF_E_SUP_OTHER 0
296#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
297#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
298#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
299#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
300#define BRCMF_E_SUP_PW_KEY_CIPHER 5
301#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
302#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
303#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
304#define BRCMF_E_SUP_MSG3_NO_GTK 9
305#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
306#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
307#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
308#define BRCMF_E_SUP_SEND_FAIL 13
309#define BRCMF_E_SUP_DEAUTH 14
310
311#define BRCMF_E_IF_ADD 1
312#define BRCMF_E_IF_DEL 2
313#define BRCMF_E_IF_CHANGE 3
314
315#define BRCMF_E_IF_ROLE_STA 0
316#define BRCMF_E_IF_ROLE_AP 1
317#define BRCMF_E_IF_ROLE_WDS 2
318
319#define BRCMF_E_LINK_BCN_LOSS 1
320#define BRCMF_E_LINK_DISASSOC 2
321#define BRCMF_E_LINK_ASSOC_REC 3
322#define BRCMF_E_LINK_BSSCFG_DIS 4
323
324/* The level of bus communication with the dongle */
325enum brcmf_bus_state {
326 BRCMF_BUS_DOWN, /* Not ready for frame transfers */
327 BRCMF_BUS_LOAD, /* Download access only (CPU reset) */
328 BRCMF_BUS_DATA /* Ready for frame transfers */
329};
330
331/* Pattern matching filter. Specifies an offset within received packets to
332 * start matching, the pattern to match, the size of the pattern, and a bitmask
333 * that indicates which bits within the pattern should be matched.
334 */
335struct brcmf_pkt_filter_pattern {
336 u32 offset; /* Offset within received packet to start pattern matching.
337 * Offset '0' is the first byte of the ethernet header.
338 */
339 u32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */
340 u8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts
341 * at offset 0. Pattern immediately follows mask.
342 */
343};
344
345/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
346struct brcmf_pkt_filter {
347 u32 id; /* Unique filter id, specified by app. */
348 u32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
349 u32 negate_match; /* Negate the result of filter matches */
350 union { /* Filter definitions */
351 struct brcmf_pkt_filter_pattern pattern; /* Filter pattern */
352 } u;
353};
354
355/* IOVAR "pkt_filter_enable" parameter. */
356struct brcmf_pkt_filter_enable {
357 u32 id; /* Unique filter id */
358 u32 enable; /* Enable/disable bool */
359};
360
361/* BSS info structure
362 * Applications MUST CHECK ie_offset field and length field to access IEs and
363 * next bss_info structure in a vector (in struct brcmf_scan_results)
364 */
365struct brcmf_bss_info {
366 u32 version; /* version field */
367 u32 length; /* byte length of data in this record,
368 * starting at version and including IEs
369 */
370 u8 BSSID[ETH_ALEN];
371 u16 beacon_period; /* units are Kusec */
372 u16 capability; /* Capability information */
373 u8 SSID_len;
374 u8 SSID[32];
375 struct {
376 uint count; /* # rates in this set */
377 u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
378 } rateset; /* supported rates */
379 chanspec_t chanspec; /* chanspec for bss */
380 u16 atim_window; /* units are Kusec */
381 u8 dtim_period; /* DTIM period */
382 s16 RSSI; /* receive signal strength (in dBm) */
383 s8 phy_noise; /* noise (in dBm) */
384
385 u8 n_cap; /* BSS is 802.11N Capable */
386 u32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */
387 u8 ctl_ch; /* 802.11N BSS control channel number */
388 u32 reserved32[1]; /* Reserved for expansion of BSS properties */
389 u8 flags; /* flags */
390 u8 reserved[3]; /* Reserved for expansion of BSS properties */
391 u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
392
393 u16 ie_offset; /* offset at which IEs start, from beginning */
394 u32 ie_length; /* byte length of Information Elements */
395 s16 SNR; /* average SNR of during frame reception */
396 /* Add new fields here */
397 /* variable length Information Elements */
398};
399
400struct brcmf_ssid {
401 u32 SSID_len;
402 unsigned char SSID[32];
403};
404
405struct brcmf_scan_params {
406 struct brcmf_ssid ssid; /* default: {0, ""} */
407 u8 bssid[ETH_ALEN]; /* default: bcast */
408 s8 bss_type; /* default: any,
409 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
410 */
411 u8 scan_type; /* flags, 0 use default */
412 s32 nprobes; /* -1 use default, number of probes per channel */
413 s32 active_time; /* -1 use default, dwell time per channel for
414 * active scanning
415 */
416 s32 passive_time; /* -1 use default, dwell time per channel
417 * for passive scanning
418 */
419 s32 home_time; /* -1 use default, dwell time for the home channel
420 * between channel scans
421 */
422 s32 channel_num; /* count of channels and ssids that follow
423 *
424 * low half is count of channels in
425 * channel_list, 0 means default (use all
426 * available channels)
427 *
428 * high half is entries in struct brcmf_ssid
429 * array that follows channel_list, aligned for
430 * s32 (4 bytes) meaning an odd channel count
431 * implies a 2-byte pad between end of
432 * channel_list and first ssid
433 *
434 * if ssid count is zero, single ssid in the
435 * fixed parameter portion is assumed, otherwise
436 * ssid in the fixed portion is ignored
437 */
438 u16 channel_list[1]; /* list of chanspecs */
439};
440
441/* incremental scan struct */
442struct brcmf_iscan_params {
443 u32 version;
444 u16 action;
445 u16 scan_duration;
446 struct brcmf_scan_params params;
447};
448
449/* 3 fields + size of brcmf_scan_params, not including variable length array */
450#define BRCMF_ISCAN_PARAMS_FIXED_SIZE \
451 (offsetof(struct brcmf_iscan_params, params) + \
452 sizeof(struct brcmf_ssid))
453
454struct brcmf_scan_results {
455 u32 buflen;
456 u32 version;
457 u32 count;
458 struct brcmf_bss_info bss_info[1];
459};
460
461/* used for association with a specific BSSID and chanspec list */
462struct brcmf_assoc_params {
463 u8 bssid[ETH_ALEN]; /* 00:00:00:00:00:00: broadcast scan */
464 s32 chanspec_num; /* 0: all available channels,
465 * otherwise count of chanspecs in chanspec_list
466 */
467 chanspec_t chanspec_list[1]; /* list of chanspecs */
468};
469#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
470 (sizeof(struct brcmf_assoc_params) - sizeof(chanspec_t))
471
472/* used for join with or without a specific bssid and channel list */
473struct brcmf_join_params {
474 struct brcmf_ssid ssid;
475 struct brcmf_assoc_params params;
476};
477
478/* size of brcmf_scan_results not including variable length array */
479#define BRCMF_SCAN_RESULTS_FIXED_SIZE \
480 (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info))
481
482/* incremental scan results struct */
483struct brcmf_iscan_results {
484 u32 status;
485 struct brcmf_scan_results results;
486};
487
488/* size of brcmf_iscan_results not including variable length array */
489#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
490 (BRCMF_SCAN_RESULTS_FIXED_SIZE + \
491 offsetof(struct brcmf_iscan_results, results))
492
493struct brcmf_wsec_key {
494 u32 index; /* key index */
495 u32 len; /* key length */
496 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
497 u32 pad_1[18];
498 u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
499 u32 flags; /* misc flags */
500 u32 pad_2[2];
501 int pad_3;
502 int iv_initialized; /* has IV been initialized already? */
503 int pad_4;
504 /* Rx IV */
505 struct {
506 u32 hi; /* upper 32 bits of IV */
507 u16 lo; /* lower 16 bits of IV */
508 } rxiv;
509 u32 pad_5[2];
510 u8 ea[ETH_ALEN]; /* per station */
511};
512
513/* Used to get specific STA parameters */
514struct brcmf_scb_val {
515 u32 val;
516 u8 ea[ETH_ALEN];
517};
518
519/* channel encoding */
520struct brcmf_channel_info {
521 int hw_channel;
522 int target_channel;
523 int scan_channel;
524};
525
526/* Linux network driver ioctl encoding */
527struct brcmf_ioctl {
528 uint cmd; /* common ioctl definition */
529 void *buf; /* pointer to user buffer */
530 uint len; /* length of user buffer */
531 u8 set; /* get or set request (optional) */
532 uint used; /* bytes read or written (optional) */
533 uint needed; /* bytes needed (optional) */
534};
535
536/* Forward decls for struct brcmf_pub (see below) */
537struct brcmf_bus; /* device bus info */
538struct brcmf_proto; /* device communication protocol info */
539struct brcmf_info; /* device driver info */
540
541/* Common structure for module and instance linkage */
542struct brcmf_pub {
543 /* Linkage ponters */
544 struct brcmf_bus *bus;
545 struct brcmf_proto *prot;
546 struct brcmf_info *info;
547
548 /* Internal brcmf items */
549 bool up; /* Driver up/down (to OS) */
550 bool txoff; /* Transmit flow-controlled */
551 bool dongle_reset; /* true = DEVRESET put dongle into reset */
552 enum brcmf_bus_state busstate;
553 uint hdrlen; /* Total BRCMF header length (proto + bus) */
554 uint maxctl; /* Max size rxctl request from proto to bus */
555 uint rxsz; /* Rx buffer size bus module should use */
556 u8 wme_dp; /* wme discard priority */
557
558 /* Dongle media info */
559 bool iswl; /* Dongle-resident driver is wl */
560 unsigned long drv_version; /* Version of dongle-resident driver */
561 u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
562 struct dngl_stats dstats; /* Stats for dongle-based data */
563
564 /* Additional stats for the bus level */
565 unsigned long tx_packets; /* Data packets sent to dongle */
566 unsigned long tx_multicast; /* Multicast data packets sent to dongle */
567 unsigned long tx_errors; /* Errors in sending data to dongle */
568 unsigned long tx_ctlpkts; /* Control packets sent to dongle */
569 unsigned long tx_ctlerrs; /* Errors sending control frames to dongle */
570 unsigned long rx_packets; /* Packets sent up the network interface */
571 unsigned long rx_multicast; /* Multicast packets sent up the network
572 interface */
573 unsigned long rx_errors; /* Errors processing rx data packets */
574 unsigned long rx_ctlpkts; /* Control frames processed from dongle */
575 unsigned long rx_ctlerrs; /* Errors in processing rx control frames */
576 unsigned long rx_dropped; /* Packets dropped locally (no memory) */
577 unsigned long rx_flushed; /* Packets flushed due to
578 unscheduled sendup thread */
579 unsigned long wd_dpc_sched; /* Number of times dpc scheduled by
580 watchdog timer */
581
582 unsigned long rx_readahead_cnt; /* Number of packets where header read-ahead
583 was used. */
584 unsigned long tx_realloc; /* Number of tx packets we had to realloc for
585 headroom */
586 unsigned long fc_packets; /* Number of flow control pkts recvd */
587
588 /* Last error return */
589 int bcmerror;
590 uint tickcnt;
591
592 /* Last error from dongle */
593 int dongle_error;
594
595 /* Suspend disable flag flag */
596 int suspend_disable_flag; /* "1" to disable all extra powersaving
597 during suspend */
598 int in_suspend; /* flag set to 1 when early suspend called */
599 int dtim_skip; /* dtim skip , default 0 means wake each dtim */
600
601 /* Pkt filter defination */
602 char *pktfilter[100];
603 int pktfilter_count;
604
605 u8 country_code[BRCM_CNTRY_BUF_SZ];
606 char eventmask[BRCMF_EVENTING_MASK_LEN];
607
608};
609
610struct brcmf_if_event {
611 u8 ifidx;
612 u8 action;
613 u8 flags;
614 u8 bssidx;
615};
616
617struct brcmf_timeout {
618 u32 limit; /* Expiration time (usec) */
619 u32 increment; /* Current expiration increment (usec) */
620 u32 elapsed; /* Current elapsed time (usec) */
621 u32 tick; /* O/S tick time (usec) */
622};
623
624struct bcmevent_name {
625 uint event;
626 const char *name;
627};
628
629#if defined(CONFIG_PM_SLEEP)
630extern atomic_t brcmf_mmc_suspend;
631#define BRCMF_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
632#define _BRCMF_PM_RESUME_WAIT(a, b) do { \
633 int retry = 0; \
634 while (atomic_read(&brcmf_mmc_suspend) && retry++ != b) { \
635 wait_event_timeout(a, false, HZ/100); \
636 } \
637 } while (0)
638#define BRCMF_PM_RESUME_WAIT(a) _BRCMF_PM_RESUME_WAIT(a, 30)
639#define BRCMF_PM_RESUME_RETURN_ERROR(a) \
640 do { if (atomic_read(&brcmf_mmc_suspend)) return a; } while (0)
641
642#define BRCMF_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
643#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \
644 uint countdown = (us) + 9999; \
645 while ((exp) && (countdown >= 10000)) { \
646 wait_event_timeout(a, false, HZ/100); \
647 countdown -= 10000; \
648 } \
649 } while (0)
650
651#else
652
653#define BRCMF_PM_RESUME_WAIT_INIT(a)
654#define BRCMF_PM_RESUME_WAIT(a)
655#define BRCMF_PM_RESUME_RETURN_ERROR(a)
656
657#define BRCMF_SPINWAIT_SLEEP_INIT(a)
658#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \
659 uint countdown = (us) + 9; \
660 while ((exp) && (countdown >= 10)) { \
661 udelay(10); \
662 countdown -= 10; \
663 } \
664 } while (0)
665
666#endif /* defined(CONFIG_PM_SLEEP) */
667
668/*
669 * Insmod parameters for debug/test
670 */
671
672/* Use interrupts */
673extern uint brcmf_intr;
674
675/* Use polling */
676extern uint brcmf_poll;
677
678/* ARP offload agent mode */
679extern uint brcmf_arp_mode;
680
681/* ARP offload enable */
682extern uint brcmf_arp_enable;
683
684/* Pkt filte enable control */
685extern uint brcmf_pkt_filter_enable;
686
687/* Pkt filter init setup */
688extern uint brcmf_pkt_filter_init;
689
690/* Pkt filter mode control */
691extern uint brcmf_master_mode;
692
693/* Roaming mode control */
694extern uint brcmf_roam;
695
696/* Roaming mode control */
697extern uint brcmf_radio_up;
698
699/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */
700extern int brcmf_idletime;
701#define BRCMF_IDLETIME_TICKS 1
702
703/* SDIO Drive Strength */
704extern uint brcmf_sdiod_drive_strength;
705
706/* Override to force tx queueing all the time */
707extern uint brcmf_force_tx_queueing;
708
709#ifdef SDTEST
710/* Echo packet generator (SDIO), pkts/s */
711extern uint brcmf_pktgen;
712
713/* Echo packet len (0 => sawtooth, max 1800) */
714extern uint brcmf_pktgen_len;
715#define BRCMF_MAX_PKTGEN_LEN 1800
716#endif
717
718extern const struct bcmevent_name bcmevent_names[];
719extern const int bcmevent_names_size;
720
721
722static inline void MUTEX_LOCK_INIT(struct brcmf_pub *drvr)
723{
724}
725
726static inline void MUTEX_LOCK(struct brcmf_pub *drvr)
727{
728}
729
730static inline void MUTEX_UNLOCK(struct brcmf_pub *drvr)
731{
732}
733
734static inline void MUTEX_LOCK_SOFTAP_SET_INIT(struct brcmf_pub *drvr)
735{
736}
737
738static inline void MUTEX_LOCK_SOFTAP_SET(struct brcmf_pub *drvr)
739{
740}
741
742static inline void MUTEX_UNLOCK_SOFTAP_SET(struct brcmf_pub *drvr)
743{
744}
745
746static inline void MUTEX_LOCK_WL_SCAN_SET_INIT(void)
747{
748}
749
750static inline void MUTEX_LOCK_WL_SCAN_SET(void)
751{
752}
753
754static inline void MUTEX_UNLOCK_WL_SCAN_SET(void)
755{
756}
757
758/* Indication from bus module regarding presence/insertion of dongle.
759 * Return struct brcmf_pub pointer, used as handle to OS module in later calls.
760 * Returned structure should have bus and prot pointers filled in.
761 * bus_hdrlen specifies required headroom for bus module header.
762 */
763extern struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus,
764 uint bus_hdrlen);
765extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx);
766extern int brcmf_netdev_wait_pend8021x(struct net_device *dev);
767
768/* Indication from bus module regarding removal/absence of dongle */
769extern void brcmf_detach(struct brcmf_pub *drvr);
770
771/* Indication from bus module to change flow-control state */
772extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on);
773
774extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
775 struct sk_buff *pkt, int prec);
776
777/* Receive frame for delivery to OS. Callee disposes of rxp. */
778extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
779 struct sk_buff *rxp, int numpkt);
780
781/* Return pointer to interface name */
782extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
783
784/* Notify tx completion */
785extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp,
786 bool success);
787
788/* Query ioctl */
789extern int brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx,
790 uint cmd, void *buf, uint len);
791
792/* OS independent layer functions */
793extern int brcmf_os_proto_block(struct brcmf_pub *drvr);
794extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr);
795extern int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition,
796 bool *pending);
797extern int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr);
798extern unsigned int brcmf_os_get_ioctl_resp_timeout(void);
799extern void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec);
800#ifdef BCMDBG
801extern int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size);
802#endif /* BCMDBG */
803
804extern void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec);
805extern int brcmf_timeout_expired(struct brcmf_timeout *tmo);
806
807extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name);
808extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx,
809 void *pktdata, struct brcmf_event_msg *,
810 void **data_ptr);
811
812extern void brcmf_c_init(void);
813
814extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle,
815 char *name, u8 *mac_addr, u32 flags, u8 bssidx);
816extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx);
817
818/* Send packet to dongle via data channel */
819extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
820 struct sk_buff *pkt);
821
822extern int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag);
823extern int brcmf_bus_start(struct brcmf_pub *drvr);
824
825extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
826extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
827 int enable, int master_mode);
828
829/* Linux network driver ioctl encoding */
830struct brcmf_c_ioctl {
831 uint cmd; /* common ioctl definition */
832 void *buf; /* pointer to user buffer */
833 uint len; /* length of user buffer */
834 bool set; /* get or set request (optional) */
835 uint used; /* bytes read or written (optional) */
836 uint needed; /* bytes needed (optional) */
837 uint driver; /* to identify target driver */
838};
839
840/* per-driver magic numbers */
841#define BRCMF_IOCTL_MAGIC 0x00444944
842
843/* bump this number if you change the ioctl interface */
844#define BRCMF_IOCTL_VERSION 1
845#define BRCMF_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */
846
847/* common ioctl definitions */
848#define BRCMF_GET_MAGIC 0
849#define BRCMF_GET_VERSION 1
850#define BRCMF_GET_VAR 2
851#define BRCMF_SET_VAR 3
852
853/* message levels */
854#define BRCMF_ERROR_VAL 0x0001
855#define BRCMF_TRACE_VAL 0x0002
856#define BRCMF_INFO_VAL 0x0004
857#define BRCMF_DATA_VAL 0x0008
858#define BRCMF_CTL_VAL 0x0010
859#define BRCMF_TIMER_VAL 0x0020
860#define BRCMF_HDRS_VAL 0x0040
861#define BRCMF_BYTES_VAL 0x0080
862#define BRCMF_INTR_VAL 0x0100
863#define BRCMF_GLOM_VAL 0x0400
864#define BRCMF_EVENT_VAL 0x0800
865#define BRCMF_BTA_VAL 0x1000
866#define BRCMF_ISCAN_VAL 0x2000
867
868#ifdef SDTEST
869/* For pktgen iovar */
870struct brcmf_pktgen {
871 uint version; /* To allow structure change tracking */
872 uint freq; /* Max ticks between tx/rx attempts */
873 uint count; /* Test packets to send/rcv each attempt */
874 uint print; /* Print counts every <print> attempts */
875 uint total; /* Total packets (or bursts) */
876 uint minlen; /* Minimum length of packets to send */
877 uint maxlen; /* Maximum length of packets to send */
878 uint numsent; /* Count of test packets sent */
879 uint numrcvd; /* Count of test packets received */
880 uint numfail; /* Count of test send failures */
881 uint mode; /* Test mode (type of test packets) */
882 uint stop; /* Stop after this many tx failures */
883};
884
885/* Version in case structure changes */
886#define BRCMF_PKTGEN_VERSION 2
887
888/* Type of test packets to use */
889#define BRCMF_PKTGEN_ECHO 1 /* Send echo requests */
890#define BRCMF_PKTGEN_SEND 2 /* Send discard packets */
891#define BRCMF_PKTGEN_RXBURST 3 /* Request dongle send N packets */
892#define BRCMF_PKTGEN_RECV 4 /* Continuous rx from continuous
893 tx dongle */
894#endif /* SDTEST */
895
896/* Enter idle immediately (no timeout) */
897#define BRCMF_IDLE_IMMEDIATE (-1)
898
899/* Values for idleclock iovar: other values are the sd_divisor to use
900 when idle */
901#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
902 when idle */
903
904#endif /* _BRCMF_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h
new file mode 100644
index 00000000000..653cf0daa0e
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h
@@ -0,0 +1,78 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMF_BUS_H_
18#define _BRCMF_BUS_H_
19
20/* Packet alignment for most efficient SDIO (can change based on platform) */
21#ifndef BRCMF_SDALIGN
22#define BRCMF_SDALIGN 32
23#endif
24#if !ISPOWEROF2(BRCMF_SDALIGN)
25#error BRCMF_SDALIGN is not a power of 2!
26#endif
27
28/*
29 * Exported from brcmf bus module (brcmf_usb, brcmf_sdio)
30 */
31
32/* dongle ram module parameter */
33extern int brcmf_dongle_memsize;
34
35/* Tx/Rx bounds module parameters */
36extern uint brcmf_txbound;
37extern uint brcmf_rxbound;
38
39/* Watchdog timer interval */
40extern uint brcmf_watchdog_ms;
41
42/* Indicate (dis)interest in finding dongles. */
43extern int brcmf_bus_register(void);
44extern void brcmf_bus_unregister(void);
45
46/* Stop bus module: clear pending frames, disable data flow */
47extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex);
48
49/* Initialize bus module: prepare for communication w/dongle */
50extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex);
51
52/* Send a data frame to the dongle. Callee disposes of txp. */
53extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp);
54
55/* Send/receive a control message to/from the dongle.
56 * Expects caller to enforce a single outstanding transaction.
57 */
58extern int
59brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
60
61extern int
62brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
63
64/* Check for and handle local prot-specific iovar commands */
65extern int brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name,
66 void *params, int plen, void *arg, int len,
67 bool set);
68
69/* Add bus dump output to a buffer */
70extern void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr,
71 struct brcmu_strbuf *strbuf);
72
73/* Clear any bus counters */
74extern void brcmf_bus_clearcounts(struct brcmf_pub *drvr);
75
76extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick);
77
78#endif /* _BRCMF_BUS_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
new file mode 100644
index 00000000000..345acabe935
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
@@ -0,0 +1,502 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/types.h>
18#include <linux/netdevice.h>
19#include <linux/sched.h>
20#include <defs.h>
21
22#include <brcmu_utils.h>
23#include <brcmu_wifi.h>
24
25#include "dhd.h"
26#include "dhd_proto.h"
27#include "dhd_bus.h"
28#include "dhd_dbg.h"
29
30struct brcmf_proto_cdc_ioctl {
31 u32 cmd; /* ioctl command value */
32 u32 len; /* lower 16: output buflen;
33 * upper 16: input buflen (excludes header) */
34 u32 flags; /* flag defns given below */
35 u32 status; /* status code returned from the device */
36};
37
38/* Max valid buffer size that can be sent to the dongle */
39#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
40
41/* CDC flag definitions */
42#define CDCF_IOC_ERROR 0x01 /* 1=ioctl cmd failed */
43#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */
44#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */
45#define CDCF_IOC_IF_SHIFT 12
46#define CDCF_IOC_ID_MASK 0xFFFF0000 /* id an ioctl pairing */
47#define CDCF_IOC_ID_SHIFT 16 /* ID Mask shift bits */
48#define CDC_IOC_ID(flags) \
49 (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
50#define CDC_SET_IF_IDX(hdr, idx) \
51 ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \
52 ((idx) << CDCF_IOC_IF_SHIFT)))
53
54/*
55 * BDC header - Broadcom specific extension of CDC.
56 * Used on data packets to convey priority across USB.
57 */
58#define BDC_HEADER_LEN 4
59#define BDC_PROTO_VER 1 /* Protocol version */
60#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
61#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
62#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
63#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
64#define BDC_PRIORITY_MASK 0x7
65#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
66#define BDC_FLAG2_IF_SHIFT 0
67
68#define BDC_GET_IF_IDX(hdr) \
69 ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
70#define BDC_SET_IF_IDX(hdr, idx) \
71 ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
72 ((idx) << BDC_FLAG2_IF_SHIFT)))
73
74struct brcmf_proto_bdc_header {
75 u8 flags;
76 u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */
77 u8 flags2;
78 u8 rssi;
79};
80
81
82#define RETRIES 2 /* # of retries to retrieve matching ioctl response */
83#define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE
84 * (amount of header tha might be added)
85 * plus any space that might be needed
86 * for alignment padding.
87 */
88#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for
89 * round off at the end of buffer
90 */
91
92struct brcmf_proto {
93 u16 reqid;
94 u8 pending;
95 u32 lastcmd;
96 u8 bus_header[BUS_HEADER_LEN];
97 struct brcmf_proto_cdc_ioctl msg;
98 unsigned char buf[BRCMF_C_IOCTL_MAXLEN + ROUND_UP_MARGIN];
99};
100
101static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
102{
103 struct brcmf_proto *prot = drvr->prot;
104 int len = le32_to_cpu(prot->msg.len) +
105 sizeof(struct brcmf_proto_cdc_ioctl);
106
107 BRCMF_TRACE(("%s: Enter\n", __func__));
108
109 /* NOTE : cdc->msg.len holds the desired length of the buffer to be
110 * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
111 * is actually sent to the dongle
112 */
113 if (len > CDC_MAX_MSG_SIZE)
114 len = CDC_MAX_MSG_SIZE;
115
116 /* Send request */
117 return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg,
118 len);
119}
120
121static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
122{
123 int ret;
124 struct brcmf_proto *prot = drvr->prot;
125
126 BRCMF_TRACE(("%s: Enter\n", __func__));
127
128 do {
129 ret = brcmf_sdbrcm_bus_rxctl(drvr->bus,
130 (unsigned char *)&prot->msg,
131 len + sizeof(struct brcmf_proto_cdc_ioctl));
132 if (ret < 0)
133 break;
134 } while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id);
135
136 return ret;
137}
138
139int
140brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd,
141 void *buf, uint len)
142{
143 struct brcmf_proto *prot = drvr->prot;
144 struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
145 void *info;
146 int ret = 0, retries = 0;
147 u32 id, flags = 0;
148
149 BRCMF_TRACE(("%s: Enter\n", __func__));
150 BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
151
152 /* Respond "bcmerror" and "bcmerrorstr" with local cache */
153 if (cmd == BRCMF_C_GET_VAR && buf) {
154 if (!strcmp((char *)buf, "bcmerrorstr")) {
155 strncpy((char *)buf, "bcm_error",
156 BCME_STRLEN);
157 goto done;
158 } else if (!strcmp((char *)buf, "bcmerror")) {
159 *(int *)buf = drvr->dongle_error;
160 goto done;
161 }
162 }
163
164 memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl));
165
166 msg->cmd = cpu_to_le32(cmd);
167 msg->len = cpu_to_le32(len);
168 msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
169 CDC_SET_IF_IDX(msg, ifidx);
170 msg->flags = cpu_to_le32(msg->flags);
171
172 if (buf)
173 memcpy(prot->buf, buf, len);
174
175 ret = brcmf_proto_cdc_msg(drvr);
176 if (ret < 0) {
177 BRCMF_ERROR(("brcmf_proto_cdc_query_ioctl: brcmf_proto_cdc_msg "
178 "failed w/status %d\n", ret));
179 goto done;
180 }
181
182retry:
183 /* wait for interrupt and get first fragment */
184 ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
185 if (ret < 0)
186 goto done;
187
188 flags = le32_to_cpu(msg->flags);
189 id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
190
191 if ((id < prot->reqid) && (++retries < RETRIES))
192 goto retry;
193 if (id != prot->reqid) {
194 BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
195 brcmf_ifname(drvr, ifidx), __func__, id,
196 prot->reqid));
197 ret = -EINVAL;
198 goto done;
199 }
200
201 /* Check info buffer */
202 info = (void *)&msg[1];
203
204 /* Copy info buffer */
205 if (buf) {
206 if (ret < (int)len)
207 len = ret;
208 memcpy(buf, info, len);
209 }
210
211 /* Check the ERROR flag */
212 if (flags & CDCF_IOC_ERROR) {
213 ret = le32_to_cpu(msg->status);
214 /* Cache error from dongle */
215 drvr->dongle_error = ret;
216 }
217
218done:
219 return ret;
220}
221
222int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd,
223 void *buf, uint len)
224{
225 struct brcmf_proto *prot = drvr->prot;
226 struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
227 int ret = 0;
228 u32 flags, id;
229
230 BRCMF_TRACE(("%s: Enter\n", __func__));
231 BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
232
233 memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl));
234
235 msg->cmd = cpu_to_le32(cmd);
236 msg->len = cpu_to_le32(len);
237 msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET;
238 CDC_SET_IF_IDX(msg, ifidx);
239 msg->flags = cpu_to_le32(msg->flags);
240
241 if (buf)
242 memcpy(prot->buf, buf, len);
243
244 ret = brcmf_proto_cdc_msg(drvr);
245 if (ret < 0)
246 goto done;
247
248 ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
249 if (ret < 0)
250 goto done;
251
252 flags = le32_to_cpu(msg->flags);
253 id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
254
255 if (id != prot->reqid) {
256 BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
257 brcmf_ifname(drvr, ifidx), __func__, id,
258 prot->reqid));
259 ret = -EINVAL;
260 goto done;
261 }
262
263 /* Check the ERROR flag */
264 if (flags & CDCF_IOC_ERROR) {
265 ret = le32_to_cpu(msg->status);
266 /* Cache error from dongle */
267 drvr->dongle_error = ret;
268 }
269
270done:
271 return ret;
272}
273
274int
275brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, struct brcmf_ioctl *ioc,
276 void *buf, int len)
277{
278 struct brcmf_proto *prot = drvr->prot;
279 int ret = -1;
280
281 if (drvr->busstate == BRCMF_BUS_DOWN) {
282 BRCMF_ERROR(("%s : bus is down. we have nothing to do\n",
283 __func__));
284 return ret;
285 }
286 brcmf_os_proto_block(drvr);
287
288 BRCMF_TRACE(("%s: Enter\n", __func__));
289
290 if (len > BRCMF_C_IOCTL_MAXLEN)
291 goto done;
292
293 if (prot->pending == true) {
294 BRCMF_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) "
295 "lastcmd=0x%x (%lu)\n",
296 ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
297 (unsigned long)prot->lastcmd));
298 if ((ioc->cmd == BRCMF_C_SET_VAR) ||
299 (ioc->cmd == BRCMF_C_GET_VAR))
300 BRCMF_TRACE(("iovar cmd=%s\n", (char *)buf));
301
302 goto done;
303 }
304
305 prot->pending = true;
306 prot->lastcmd = ioc->cmd;
307 if (ioc->set)
308 ret = brcmf_proto_cdc_set_ioctl(drvr, ifidx, ioc->cmd,
309 buf, len);
310 else {
311 ret = brcmf_proto_cdc_query_ioctl(drvr, ifidx, ioc->cmd,
312 buf, len);
313 if (ret > 0)
314 ioc->used = ret - sizeof(struct brcmf_proto_cdc_ioctl);
315 }
316
317 /* Too many programs assume ioctl() returns 0 on success */
318 if (ret >= 0)
319 ret = 0;
320 else {
321 struct brcmf_proto_cdc_ioctl *msg = &prot->msg;
322 /* len == needed when set/query fails from dongle */
323 ioc->needed = le32_to_cpu(msg->len);
324 }
325
326 /* Intercept the wme_dp ioctl here */
327 if (!ret && ioc->cmd == BRCMF_C_SET_VAR &&
328 !strcmp(buf, "wme_dp")) {
329 int slen, val = 0;
330
331 slen = strlen("wme_dp") + 1;
332 if (len >= (int)(slen + sizeof(int)))
333 memcpy(&val, (char *)buf + slen, sizeof(int));
334 drvr->wme_dp = (u8) le32_to_cpu(val);
335 }
336
337 prot->pending = false;
338
339done:
340 brcmf_os_proto_unblock(drvr);
341
342 return ret;
343}
344
345#define PKTSUMNEEDED(skb) \
346 (((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL)
347#define PKTSETSUMGOOD(skb, x) \
348 (((struct sk_buff *)(skb))->ip_summed = \
349 ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
350
351void brcmf_proto_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf)
352{
353 brcmu_bprintf(strbuf, "Protocol CDC: reqid %d\n", drvr->prot->reqid);
354}
355
356void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
357 struct sk_buff *pktbuf)
358{
359 struct brcmf_proto_bdc_header *h;
360
361 BRCMF_TRACE(("%s: Enter\n", __func__));
362
363 /* Push BDC header used to convey priority for buses that don't */
364
365 skb_push(pktbuf, BDC_HEADER_LEN);
366
367 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
368
369 h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
370 if (PKTSUMNEEDED(pktbuf))
371 h->flags |= BDC_FLAG_SUM_NEEDED;
372
373 h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
374 h->flags2 = 0;
375 h->rssi = 0;
376 BDC_SET_IF_IDX(h, ifidx);
377}
378
379int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx,
380 struct sk_buff *pktbuf)
381{
382 struct brcmf_proto_bdc_header *h;
383
384 BRCMF_TRACE(("%s: Enter\n", __func__));
385
386 /* Pop BDC header used to convey priority for buses that don't */
387
388 if (pktbuf->len < BDC_HEADER_LEN) {
389 BRCMF_ERROR(("%s: rx data too short (%d < %d)\n", __func__,
390 pktbuf->len, BDC_HEADER_LEN));
391 return -EBADE;
392 }
393
394 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
395
396 *ifidx = BDC_GET_IF_IDX(h);
397 if (*ifidx >= BRCMF_MAX_IFS) {
398 BRCMF_ERROR(("%s: rx data ifnum out of range (%d)\n",
399 __func__, *ifidx));
400 return -EBADE;
401 }
402
403 if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
404 BDC_PROTO_VER) {
405 BRCMF_ERROR(("%s: non-BDC packet received, flags 0x%x\n",
406 brcmf_ifname(drvr, *ifidx), h->flags));
407 return -EBADE;
408 }
409
410 if (h->flags & BDC_FLAG_SUM_GOOD) {
411 BRCMF_INFO(("%s: BDC packet received with good rx-csum, "
412 "flags 0x%x\n",
413 brcmf_ifname(drvr, *ifidx), h->flags));
414 PKTSETSUMGOOD(pktbuf, true);
415 }
416
417 pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
418
419 skb_pull(pktbuf, BDC_HEADER_LEN);
420
421 return 0;
422}
423
424int brcmf_proto_attach(struct brcmf_pub *drvr)
425{
426 struct brcmf_proto *cdc;
427
428 cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
429 if (!cdc) {
430 BRCMF_ERROR(("%s: kmalloc failed\n", __func__));
431 goto fail;
432 }
433
434 /* ensure that the msg buf directly follows the cdc msg struct */
435 if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
436 BRCMF_ERROR(("struct brcmf_proto is not correctly defined\n"));
437 goto fail;
438 }
439
440 drvr->prot = cdc;
441 drvr->hdrlen += BDC_HEADER_LEN;
442 drvr->maxctl = BRCMF_C_IOCTL_MAXLEN +
443 sizeof(struct brcmf_proto_cdc_ioctl) + ROUND_UP_MARGIN;
444 return 0;
445
446fail:
447 kfree(cdc);
448 return -ENOMEM;
449}
450
451/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
452void brcmf_proto_detach(struct brcmf_pub *drvr)
453{
454 kfree(drvr->prot);
455 drvr->prot = NULL;
456}
457
458void brcmf_proto_dstats(struct brcmf_pub *drvr)
459{
460 /* No stats from dongle added yet, copy bus stats */
461 drvr->dstats.tx_packets = drvr->tx_packets;
462 drvr->dstats.tx_errors = drvr->tx_errors;
463 drvr->dstats.rx_packets = drvr->rx_packets;
464 drvr->dstats.rx_errors = drvr->rx_errors;
465 drvr->dstats.rx_dropped = drvr->rx_dropped;
466 drvr->dstats.multicast = drvr->rx_multicast;
467 return;
468}
469
470int brcmf_proto_init(struct brcmf_pub *drvr)
471{
472 int ret = 0;
473 char buf[128];
474
475 BRCMF_TRACE(("%s: Enter\n", __func__));
476
477 brcmf_os_proto_block(drvr);
478
479 /* Get the device MAC address */
480 strcpy(buf, "cur_etheraddr");
481 ret = brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR,
482 buf, sizeof(buf));
483 if (ret < 0) {
484 brcmf_os_proto_unblock(drvr);
485 return ret;
486 }
487 memcpy(drvr->mac, buf, ETH_ALEN);
488
489 brcmf_os_proto_unblock(drvr);
490
491 ret = brcmf_c_preinit_ioctls(drvr);
492
493 /* Always assumes wl for now */
494 drvr->iswl = true;
495
496 return ret;
497}
498
499void brcmf_proto_stop(struct brcmf_pub *drvr)
500{
501 /* Nothing to do for CDC */
502}
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c
new file mode 100644
index 00000000000..fdec4683c42
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c
@@ -0,0 +1,1196 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/kernel.h>
17#include <linux/string.h>
18#include <linux/sched.h>
19#include <linux/netdevice.h>
20#include <asm/unaligned.h>
21#include <defs.h>
22#include <brcmu_wifi.h>
23#include <brcmu_utils.h>
24#include "dhd.h"
25#include "dhd_bus.h"
26#include "dhd_proto.h"
27#include "dhd_dbg.h"
28
29#define BRCM_OUI "\x00\x10\x18"
30#define DOT11_OUI_LEN 3
31#define BCMILCP_BCM_SUBTYPE_EVENT 1
32#define PKTFILTER_BUF_SIZE 2048
33
34int brcmf_msg_level;
35
36#define MSGTRACE_VERSION 1
37
38#ifdef BCMDBG
39const char brcmf_version[] =
40"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " __DATE__
41" at " __TIME__;
42#else
43const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR;
44#endif
45
46/* IOVar table */
47enum {
48 IOV_VERSION = 1,
49 IOV_MSGLEVEL,
50 IOV_BCMERRORSTR,
51 IOV_BCMERROR,
52 IOV_DUMP,
53 IOV_CLEARCOUNTS,
54 IOV_LOGDUMP,
55 IOV_LOGCAL,
56 IOV_LOGSTAMP,
57 IOV_GPIOOB,
58 IOV_IOCTLTIMEOUT,
59 IOV_LAST
60};
61
62const struct brcmu_iovar brcmf_iovars[] = {
63 {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(brcmf_version)}
64 ,
65#ifdef BCMDBG
66 {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0}
67 ,
68#endif /* BCMDBG */
69 {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN}
70 ,
71 {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0}
72 ,
73 {"dump", IOV_DUMP, 0, IOVT_BUFFER, BRCMF_IOCTL_MAXLEN}
74 ,
75 {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0}
76 ,
77 {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0}
78 ,
79 {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0}
80 ,
81 {NULL, 0, 0, 0, 0}
82};
83
84/* Message trace header */
85struct msgtrace_hdr {
86 u8 version;
87 u8 spare;
88 u16 len; /* Len of the trace */
89 u32 seqnum; /* Sequence number of message. Useful
90 * if the messsage has been lost
91 * because of DMA error or a bus reset
92 * (ex: SDIO Func2)
93 */
94 u32 discarded_bytes; /* Number of discarded bytes because of
95 trace overflow */
96 u32 discarded_printf; /* Number of discarded printf
97 because of trace overflow */
98} __packed;
99
100void brcmf_c_init(void)
101{
102 /* Init global variables at run-time, not as part of the declaration.
103 * This is required to support init/de-init of the driver.
104 * Initialization
105 * of globals as part of the declaration results in non-deterministic
106 * behaviour since the value of the globals may be different on the
107 * first time that the driver is initialized vs subsequent
108 * initializations.
109 */
110 brcmf_msg_level = BRCMF_ERROR_VAL;
111}
112
113static int brcmf_c_dump(struct brcmf_pub *drvr, char *buf, int buflen)
114{
115 struct brcmu_strbuf b;
116 struct brcmu_strbuf *strbuf = &b;
117
118 brcmu_binit(strbuf, buf, buflen);
119
120 /* Base info */
121 brcmu_bprintf(strbuf, "%s\n", brcmf_version);
122 brcmu_bprintf(strbuf, "\n");
123 brcmu_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n",
124 drvr->up, drvr->txoff, drvr->busstate);
125 brcmu_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n",
126 drvr->hdrlen, drvr->maxctl, drvr->rxsz);
127 brcmu_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %pM\n",
128 drvr->iswl, drvr->drv_version, &drvr->mac);
129 brcmu_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", drvr->bcmerror,
130 drvr->tickcnt);
131
132 brcmu_bprintf(strbuf, "dongle stats:\n");
133 brcmu_bprintf(strbuf,
134 "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n",
135 drvr->dstats.tx_packets, drvr->dstats.tx_bytes,
136 drvr->dstats.tx_errors, drvr->dstats.tx_dropped);
137 brcmu_bprintf(strbuf,
138 "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n",
139 drvr->dstats.rx_packets, drvr->dstats.rx_bytes,
140 drvr->dstats.rx_errors, drvr->dstats.rx_dropped);
141 brcmu_bprintf(strbuf, "multicast %ld\n", drvr->dstats.multicast);
142
143 brcmu_bprintf(strbuf, "bus stats:\n");
144 brcmu_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n",
145 drvr->tx_packets, drvr->tx_multicast, drvr->tx_errors);
146 brcmu_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n",
147 drvr->tx_ctlpkts, drvr->tx_ctlerrs);
148 brcmu_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld\n",
149 drvr->rx_packets, drvr->rx_multicast, drvr->rx_errors);
150 brcmu_bprintf(strbuf,
151 "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n",
152 drvr->rx_ctlpkts, drvr->rx_ctlerrs, drvr->rx_dropped,
153 drvr->rx_flushed);
154 brcmu_bprintf(strbuf,
155 "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n",
156 drvr->rx_readahead_cnt, drvr->tx_realloc, drvr->fc_packets);
157 brcmu_bprintf(strbuf, "wd_dpc_sched %ld\n", drvr->wd_dpc_sched);
158 brcmu_bprintf(strbuf, "\n");
159
160 /* Add any prot info */
161 brcmf_proto_dump(drvr, strbuf);
162 brcmu_bprintf(strbuf, "\n");
163
164 /* Add any bus info */
165 brcmf_sdbrcm_bus_dump(drvr, strbuf);
166
167 return !strbuf->size ? -EOVERFLOW : 0;
168}
169
170static int
171brcmf_c_doiovar(struct brcmf_pub *drvr, const struct brcmu_iovar *vi,
172 u32 actionid, const char *name, void *params, int plen,
173 void *arg, int len, int val_size)
174{
175 int bcmerror = 0;
176 s32 int_val = 0;
177
178 BRCMF_TRACE(("%s: Enter\n", __func__));
179
180 bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
181 if (bcmerror != 0)
182 goto exit;
183
184 if (plen >= (int)sizeof(int_val))
185 memcpy(&int_val, params, sizeof(int_val));
186
187 switch (actionid) {
188 case IOV_GVAL(IOV_VERSION):
189 /* Need to have checked buffer length */
190 strncpy((char *)arg, brcmf_version, len);
191 break;
192
193 case IOV_GVAL(IOV_MSGLEVEL):
194 int_val = (s32) brcmf_msg_level;
195 memcpy(arg, &int_val, val_size);
196 break;
197
198 case IOV_SVAL(IOV_MSGLEVEL):
199 brcmf_msg_level = int_val;
200 break;
201
202 case IOV_GVAL(IOV_BCMERRORSTR):
203 strncpy((char *)arg, "bcm_error",
204 BCME_STRLEN);
205 ((char *)arg)[BCME_STRLEN - 1] = 0x00;
206 break;
207
208 case IOV_GVAL(IOV_BCMERROR):
209 int_val = (s32) drvr->bcmerror;
210 memcpy(arg, &int_val, val_size);
211 break;
212
213 case IOV_GVAL(IOV_DUMP):
214 bcmerror = brcmf_c_dump(drvr, arg, len);
215 break;
216
217 case IOV_SVAL(IOV_CLEARCOUNTS):
218 drvr->tx_packets = drvr->rx_packets = 0;
219 drvr->tx_errors = drvr->rx_errors = 0;
220 drvr->tx_ctlpkts = drvr->rx_ctlpkts = 0;
221 drvr->tx_ctlerrs = drvr->rx_ctlerrs = 0;
222 drvr->rx_dropped = 0;
223 drvr->rx_readahead_cnt = 0;
224 drvr->tx_realloc = 0;
225 drvr->wd_dpc_sched = 0;
226 memset(&drvr->dstats, 0, sizeof(drvr->dstats));
227 brcmf_bus_clearcounts(drvr);
228 break;
229
230 case IOV_GVAL(IOV_IOCTLTIMEOUT):{
231 int_val = (s32) brcmf_os_get_ioctl_resp_timeout();
232 memcpy(arg, &int_val, sizeof(int_val));
233 break;
234 }
235
236 case IOV_SVAL(IOV_IOCTLTIMEOUT):{
237 if (int_val <= 0)
238 bcmerror = -EINVAL;
239 else
240 brcmf_os_set_ioctl_resp_timeout((unsigned int)
241 int_val);
242 break;
243 }
244
245 default:
246 bcmerror = -ENOTSUPP;
247 break;
248 }
249
250exit:
251 return bcmerror;
252}
253
254bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
255 struct sk_buff *pkt, int prec)
256{
257 struct sk_buff *p;
258 int eprec = -1; /* precedence to evict from */
259 bool discard_oldest;
260
261 /* Fast case, precedence queue is not full and we are also not
262 * exceeding total queue length
263 */
264 if (!pktq_pfull(q, prec) && !pktq_full(q)) {
265 brcmu_pktq_penq(q, prec, pkt);
266 return true;
267 }
268
269 /* Determine precedence from which to evict packet, if any */
270 if (pktq_pfull(q, prec))
271 eprec = prec;
272 else if (pktq_full(q)) {
273 p = brcmu_pktq_peek_tail(q, &eprec);
274 if (eprec > prec)
275 return false;
276 }
277
278 /* Evict if needed */
279 if (eprec >= 0) {
280 /* Detect queueing to unconfigured precedence */
281 discard_oldest = AC_BITMAP_TST(drvr->wme_dp, eprec);
282 if (eprec == prec && !discard_oldest)
283 return false; /* refuse newer (incoming) packet */
284 /* Evict packet according to discard policy */
285 p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
286 brcmu_pktq_pdeq_tail(q, eprec);
287 if (p == NULL) {
288 BRCMF_ERROR(("%s: brcmu_pktq_penq() failed, oldest %d.",
289 __func__, discard_oldest));
290 }
291 brcmu_pkt_buf_free_skb(p);
292 }
293
294 /* Enqueue */
295 p = brcmu_pktq_penq(q, prec, pkt);
296 if (p == NULL) {
297 BRCMF_ERROR(("%s: brcmu_pktq_penq() failed.", __func__));
298 }
299
300 return p != NULL;
301}
302
303static int
304brcmf_c_iovar_op(struct brcmf_pub *drvr, const char *name,
305 void *params, int plen, void *arg, int len, bool set)
306{
307 int bcmerror = 0;
308 int val_size;
309 const struct brcmu_iovar *vi = NULL;
310 u32 actionid;
311
312 BRCMF_TRACE(("%s: Enter\n", __func__));
313
314 if (name == NULL || len <= 0)
315 return -EINVAL;
316
317 /* Set does not take qualifiers */
318 if (set && (params || plen))
319 return -EINVAL;
320
321 /* Get must have return space;*/
322 if (!set && !(arg && len))
323 return -EINVAL;
324
325 vi = brcmu_iovar_lookup(brcmf_iovars, name);
326 if (vi == NULL) {
327 bcmerror = -ENOTSUPP;
328 goto exit;
329 }
330
331 BRCMF_CTL(("%s: %s %s, len %d plen %d\n", __func__,
332 name, (set ? "set" : "get"), len, plen));
333
334 /* set up 'params' pointer in case this is a set command so that
335 * the convenience int and bool code can be common to set and get
336 */
337 if (params == NULL) {
338 params = arg;
339 plen = len;
340 }
341
342 if (vi->type == IOVT_VOID)
343 val_size = 0;
344 else if (vi->type == IOVT_BUFFER)
345 val_size = len;
346 else
347 /* all other types are integer sized */
348 val_size = sizeof(int);
349
350 actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
351 bcmerror =
352 brcmf_c_doiovar(drvr, vi, actionid, name, params, plen, arg, len,
353 val_size);
354
355exit:
356 return bcmerror;
357}
358
359int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc, void *buf,
360 uint buflen)
361{
362 int bcmerror = 0;
363
364 BRCMF_TRACE(("%s: Enter\n", __func__));
365
366 if (!buf)
367 return -EINVAL;
368
369 switch (ioc->cmd) {
370 case BRCMF_GET_MAGIC:
371 if (buflen < sizeof(int))
372 bcmerror = -EOVERFLOW;
373 else
374 *(int *)buf = BRCMF_IOCTL_MAGIC;
375 break;
376
377 case BRCMF_GET_VERSION:
378 if (buflen < sizeof(int))
379 bcmerror = -EOVERFLOW;
380 else
381 *(int *)buf = BRCMF_IOCTL_VERSION;
382 break;
383
384 case BRCMF_GET_VAR:
385 case BRCMF_SET_VAR:{
386 char *arg;
387 uint arglen;
388
389 /* scan past the name to any arguments */
390 for (arg = buf, arglen = buflen; *arg && arglen;
391 arg++, arglen--)
392 ;
393
394 if (*arg) {
395 bcmerror = -EOVERFLOW;
396 break;
397 }
398
399 /* account for the NUL terminator */
400 arg++, arglen--;
401
402 /* call with the appropriate arguments */
403 if (ioc->cmd == BRCMF_GET_VAR)
404 bcmerror = brcmf_c_iovar_op(drvr, buf, arg,
405 arglen, buf, buflen, IOV_GET);
406 else
407 bcmerror =
408 brcmf_c_iovar_op(drvr, buf, NULL, 0, arg,
409 arglen, IOV_SET);
410 if (bcmerror != -ENOTSUPP)
411 break;
412
413 /* if still not found, try bus module */
414 if (ioc->cmd == BRCMF_GET_VAR)
415 bcmerror = brcmf_sdbrcm_bus_iovar_op(drvr,
416 buf, arg, arglen, buf, buflen,
417 IOV_GET);
418 else
419 bcmerror = brcmf_sdbrcm_bus_iovar_op(drvr,
420 buf, NULL, 0, arg, arglen,
421 IOV_SET);
422
423 break;
424 }
425
426 default:
427 bcmerror = -ENOTSUPP;
428 }
429
430 return bcmerror;
431}
432
433#ifdef SHOW_EVENTS
434static void
435brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
436{
437 uint i, status, reason;
438 bool group = false, flush_txq = false, link = false;
439 char *auth_str, *event_name;
440 unsigned char *buf;
441 char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
442 static struct {
443 uint event;
444 char *event_name;
445 } event_names[] = {
446 {
447 BRCMF_E_SET_SSID, "SET_SSID"}, {
448 BRCMF_E_JOIN, "JOIN"}, {
449 BRCMF_E_START, "START"}, {
450 BRCMF_E_AUTH, "AUTH"}, {
451 BRCMF_E_AUTH_IND, "AUTH_IND"}, {
452 BRCMF_E_DEAUTH, "DEAUTH"}, {
453 BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
454 BRCMF_E_ASSOC, "ASSOC"}, {
455 BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
456 BRCMF_E_REASSOC, "REASSOC"}, {
457 BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
458 BRCMF_E_DISASSOC, "DISASSOC"}, {
459 BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
460 BRCMF_E_QUIET_START, "START_QUIET"}, {
461 BRCMF_E_QUIET_END, "END_QUIET"}, {
462 BRCMF_E_BEACON_RX, "BEACON_RX"}, {
463 BRCMF_E_LINK, "LINK"}, {
464 BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
465 BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
466 BRCMF_E_ROAM, "ROAM"}, {
467 BRCMF_E_TXFAIL, "TXFAIL"}, {
468 BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
469 BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
470 BRCMF_E_PRUNE, "PRUNE"}, {
471 BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
472 BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
473 BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
474 BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
475 BRCMF_E_DELTS_IND, "DELTS_IND"}, {
476 BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
477 BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
478 BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
479 BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
480 BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
481 BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
482 BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
483 BRCMF_E_JOIN_START, "JOIN_START"}, {
484 BRCMF_E_ROAM_START, "ROAM_START"}, {
485 BRCMF_E_ASSOC_START, "ASSOC_START"}, {
486 BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
487 BRCMF_E_RADIO, "RADIO"}, {
488 BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
489 BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
490 BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
491 BRCMF_E_PSK_SUP, "PSK_SUP"}, {
492 BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
493 BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
494 BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
495 BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
496 BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
497 BRCMF_E_TRACE, "TRACE"}, {
498 BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
499 BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
500 BRCMF_E_IF, "IF"}, {
501 BRCMF_E_RSSI, "RSSI"}, {
502 BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
503 };
504 uint event_type, flags, auth_type, datalen;
505 event_type = be32_to_cpu(event->event_type);
506 flags = be16_to_cpu(event->flags);
507 status = be32_to_cpu(event->status);
508 reason = be32_to_cpu(event->reason);
509 auth_type = be32_to_cpu(event->auth_type);
510 datalen = be32_to_cpu(event->datalen);
511 /* debug dump of event messages */
512 sprintf(eabuf, "%pM", event->addr);
513
514 event_name = "UNKNOWN";
515 for (i = 0; i < ARRAY_SIZE(event_names); i++) {
516 if (event_names[i].event == event_type)
517 event_name = event_names[i].event_name;
518 }
519
520 BRCMF_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type));
521 BRCMF_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d"
522 " MAC %s\n", flags, status, reason, auth_type, eabuf));
523
524 if (flags & BRCMF_EVENT_MSG_LINK)
525 link = true;
526 if (flags & BRCMF_EVENT_MSG_GROUP)
527 group = true;
528 if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
529 flush_txq = true;
530
531 switch (event_type) {
532 case BRCMF_E_START:
533 case BRCMF_E_DEAUTH:
534 case BRCMF_E_DISASSOC:
535 BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
536 break;
537
538 case BRCMF_E_ASSOC_IND:
539 case BRCMF_E_REASSOC_IND:
540 BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
541 break;
542
543 case BRCMF_E_ASSOC:
544 case BRCMF_E_REASSOC:
545 if (status == BRCMF_E_STATUS_SUCCESS) {
546 BRCMF_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n",
547 event_name, eabuf));
548 } else if (status == BRCMF_E_STATUS_TIMEOUT) {
549 BRCMF_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n",
550 event_name, eabuf));
551 } else if (status == BRCMF_E_STATUS_FAIL) {
552 BRCMF_EVENT(("MACEVENT: %s, MAC %s, FAILURE,"
553 " reason %d\n", event_name, eabuf,
554 (int)reason));
555 } else {
556 BRCMF_EVENT(("MACEVENT: %s, MAC %s, unexpected status "
557 "%d\n", event_name, eabuf, (int)status));
558 }
559 break;
560
561 case BRCMF_E_DEAUTH_IND:
562 case BRCMF_E_DISASSOC_IND:
563 BRCMF_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name,
564 eabuf, (int)reason));
565 break;
566
567 case BRCMF_E_AUTH:
568 case BRCMF_E_AUTH_IND:
569 if (auth_type == WLAN_AUTH_OPEN)
570 auth_str = "Open System";
571 else if (auth_type == WLAN_AUTH_SHARED_KEY)
572 auth_str = "Shared Key";
573 else {
574 sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
575 auth_str = err_msg;
576 }
577 if (event_type == BRCMF_E_AUTH_IND) {
578 BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name,
579 eabuf, auth_str));
580 } else if (status == BRCMF_E_STATUS_SUCCESS) {
581 BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n",
582 event_name, eabuf, auth_str));
583 } else if (status == BRCMF_E_STATUS_TIMEOUT) {
584 BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
585 event_name, eabuf, auth_str));
586 } else if (status == BRCMF_E_STATUS_FAIL) {
587 BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, "
588 "reason %d\n",
589 event_name, eabuf, auth_str, (int)reason));
590 }
591
592 break;
593
594 case BRCMF_E_JOIN:
595 case BRCMF_E_ROAM:
596 case BRCMF_E_SET_SSID:
597 if (status == BRCMF_E_STATUS_SUCCESS) {
598 BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name,
599 eabuf));
600 } else if (status == BRCMF_E_STATUS_FAIL) {
601 BRCMF_EVENT(("MACEVENT: %s, failed\n", event_name));
602 } else if (status == BRCMF_E_STATUS_NO_NETWORKS) {
603 BRCMF_EVENT(("MACEVENT: %s, no networks found\n",
604 event_name));
605 } else {
606 BRCMF_EVENT(("MACEVENT: %s, unexpected status %d\n",
607 event_name, (int)status));
608 }
609 break;
610
611 case BRCMF_E_BEACON_RX:
612 if (status == BRCMF_E_STATUS_SUCCESS) {
613 BRCMF_EVENT(("MACEVENT: %s, SUCCESS\n", event_name));
614 } else if (status == BRCMF_E_STATUS_FAIL) {
615 BRCMF_EVENT(("MACEVENT: %s, FAIL\n", event_name));
616 } else {
617 BRCMF_EVENT(("MACEVENT: %s, status %d\n", event_name,
618 status));
619 }
620 break;
621
622 case BRCMF_E_LINK:
623 BRCMF_EVENT(("MACEVENT: %s %s\n", event_name,
624 link ? "UP" : "DOWN"));
625 break;
626
627 case BRCMF_E_MIC_ERROR:
628 BRCMF_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
629 event_name, eabuf, group, flush_txq));
630 break;
631
632 case BRCMF_E_ICV_ERROR:
633 case BRCMF_E_UNICAST_DECODE_ERROR:
634 case BRCMF_E_MULTICAST_DECODE_ERROR:
635 BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
636 break;
637
638 case BRCMF_E_TXFAIL:
639 BRCMF_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf));
640 break;
641
642 case BRCMF_E_SCAN_COMPLETE:
643 case BRCMF_E_PMKID_CACHE:
644 BRCMF_EVENT(("MACEVENT: %s\n", event_name));
645 break;
646
647 case BRCMF_E_PFN_NET_FOUND:
648 case BRCMF_E_PFN_NET_LOST:
649 case BRCMF_E_PFN_SCAN_COMPLETE:
650 BRCMF_EVENT(("PNOEVENT: %s\n", event_name));
651 break;
652
653 case BRCMF_E_PSK_SUP:
654 case BRCMF_E_PRUNE:
655 BRCMF_EVENT(("MACEVENT: %s, status %d, reason %d\n",
656 event_name, (int)status, (int)reason));
657 break;
658
659 case BRCMF_E_TRACE:
660 {
661 static u32 seqnum_prev;
662 struct msgtrace_hdr hdr;
663 u32 nblost;
664 char *s, *p;
665
666 buf = (unsigned char *) event_data;
667 memcpy(&hdr, buf, sizeof(struct msgtrace_hdr));
668
669 if (hdr.version != MSGTRACE_VERSION) {
670 BRCMF_ERROR(
671 ("\nMACEVENT: %s [unsupported version --> "
672 "brcmf version:%d dongle version:%d]\n",
673 event_name, MSGTRACE_VERSION, hdr.version)
674 );
675 /* Reset datalen to avoid display below */
676 datalen = 0;
677 break;
678 }
679
680 /* There are 2 bytes available at the end of data */
681 *(buf + sizeof(struct msgtrace_hdr)
682 + be16_to_cpu(hdr.len)) = '\0';
683
684 if (be32_to_cpu(hdr.discarded_bytes)
685 || be32_to_cpu(hdr.discarded_printf)) {
686 BRCMF_ERROR(
687 ("\nWLC_E_TRACE: [Discarded traces in dongle -->"
688 "discarded_bytes %d discarded_printf %d]\n",
689 be32_to_cpu(hdr.discarded_bytes),
690 be32_to_cpu(hdr.discarded_printf)));
691 }
692
693 nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
694 if (nblost > 0) {
695 BRCMF_ERROR(
696 ("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n",
697 be32_to_cpu(hdr.seqnum), nblost));
698 }
699 seqnum_prev = be32_to_cpu(hdr.seqnum);
700
701 /* Display the trace buffer. Advance from \n to \n to
702 * avoid display big
703 * printf (issue with Linux printk )
704 */
705 p = (char *)&buf[sizeof(struct msgtrace_hdr)];
706 while ((s = strstr(p, "\n")) != NULL) {
707 *s = '\0';
708 printk(KERN_DEBUG"%s\n", p);
709 p = s + 1;
710 }
711 printk(KERN_DEBUG "%s\n", p);
712
713 /* Reset datalen to avoid display below */
714 datalen = 0;
715 }
716 break;
717
718 case BRCMF_E_RSSI:
719 BRCMF_EVENT(("MACEVENT: %s %d\n", event_name,
720 be32_to_cpu(*((int *)event_data))));
721 break;
722
723 default:
724 BRCMF_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, "
725 "auth %d\n", event_name, event_type, eabuf,
726 (int)status, (int)reason, (int)auth_type));
727 break;
728 }
729
730 /* show any appended data */
731 if (datalen) {
732 buf = (unsigned char *) event_data;
733 BRCMF_EVENT((" data (%d) : ", datalen));
734 for (i = 0; i < datalen; i++)
735 BRCMF_EVENT((" 0x%02x ", *buf++));
736 BRCMF_EVENT(("\n"));
737 }
738}
739#endif /* SHOW_EVENTS */
740
741int
742brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata,
743 struct brcmf_event_msg *event, void **data_ptr)
744{
745 /* check whether packet is a BRCM event pkt */
746 struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
747 char *event_data;
748 u32 type, status;
749 u16 flags;
750 int evlen;
751
752 if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) {
753 BRCMF_ERROR(("%s: mismatched OUI, bailing\n", __func__));
754 return -EBADE;
755 }
756
757 /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
758 if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) !=
759 BCMILCP_BCM_SUBTYPE_EVENT) {
760 BRCMF_ERROR(("%s: mismatched subtype, bailing\n", __func__));
761 return -EBADE;
762 }
763
764 *data_ptr = &pvt_data[1];
765 event_data = *data_ptr;
766
767 /* memcpy since BRCM event pkt may be unaligned. */
768 memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg));
769
770 type = get_unaligned_be32(&event->event_type);
771 flags = get_unaligned_be16(&event->flags);
772 status = get_unaligned_be32(&event->status);
773 evlen = get_unaligned_be32(&event->datalen) +
774 sizeof(struct brcmf_event);
775
776 switch (type) {
777 case BRCMF_E_IF:
778 {
779 struct brcmf_if_event *ifevent =
780 (struct brcmf_if_event *) event_data;
781 BRCMF_TRACE(("%s: if event\n", __func__));
782
783 if (ifevent->ifidx > 0 &&
784 ifevent->ifidx < BRCMF_MAX_IFS) {
785 if (ifevent->action == BRCMF_E_IF_ADD)
786 brcmf_add_if(drvr_priv, ifevent->ifidx,
787 NULL, event->ifname,
788 pvt_data->eth.h_dest,
789 ifevent->flags,
790 ifevent->bssidx);
791 else
792 brcmf_del_if(drvr_priv, ifevent->ifidx);
793 } else {
794 BRCMF_ERROR(("%s: Invalid ifidx %d for %s\n",
795 __func__, ifevent->ifidx,
796 event->ifname));
797 }
798 }
799 /* send up the if event: btamp user needs it */
800 *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname);
801 break;
802
803 /* These are what external supplicant/authenticator wants */
804 case BRCMF_E_LINK:
805 case BRCMF_E_ASSOC_IND:
806 case BRCMF_E_REASSOC_IND:
807 case BRCMF_E_DISASSOC_IND:
808 case BRCMF_E_MIC_ERROR:
809 default:
810 /* Fall through: this should get _everything_ */
811
812 *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname);
813 BRCMF_TRACE(("%s: MAC event %d, flags %x, status %x\n",
814 __func__, type, flags, status));
815
816 /* put it back to BRCMF_E_NDIS_LINK */
817 if (type == BRCMF_E_NDIS_LINK) {
818 u32 temp;
819
820 temp = get_unaligned_be32(&event->event_type);
821 BRCMF_TRACE(("Converted to WLC_E_LINK type %d\n",
822 temp));
823
824 temp = be32_to_cpu(BRCMF_E_NDIS_LINK);
825 memcpy((void *)(&pvt_data->msg.event_type), &temp,
826 sizeof(pvt_data->msg.event_type));
827 }
828 break;
829 }
830
831#ifdef SHOW_EVENTS
832 brcmf_c_show_host_event(event, event_data);
833#endif /* SHOW_EVENTS */
834
835 return 0;
836}
837
838/* Convert user's input in hex pattern to byte-size mask */
839static int brcmf_c_pattern_atoh(char *src, char *dst)
840{
841 int i;
842 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
843 BRCMF_ERROR(("Mask invalid format. Needs to start with 0x\n"));
844 return -1;
845 }
846 src = src + 2; /* Skip past 0x */
847 if (strlen(src) % 2 != 0) {
848 BRCMF_ERROR(("Mask invalid format. Length must be even.\n"));
849 return -1;
850 }
851 for (i = 0; *src != '\0'; i++) {
852 char num[3];
853 strncpy(num, src, 2);
854 num[2] = '\0';
855 dst[i] = (u8) simple_strtoul(num, NULL, 16);
856 src += 2;
857 }
858 return i;
859}
860
861void
862brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
863 int master_mode)
864{
865 char *argv[8];
866 int i = 0;
867 const char *str;
868 int buf_len;
869 int str_len;
870 char *arg_save = 0, *arg_org = 0;
871 int rc;
872 char buf[128];
873 struct brcmf_pkt_filter_enable enable_parm;
874 struct brcmf_pkt_filter_enable *pkt_filterp;
875
876 arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
877 if (!arg_save) {
878 BRCMF_ERROR(("%s: kmalloc failed\n", __func__));
879 goto fail;
880 }
881 arg_org = arg_save;
882 memcpy(arg_save, arg, strlen(arg) + 1);
883
884 argv[i] = strsep(&arg_save, " ");
885
886 i = 0;
887 if (NULL == argv[i]) {
888 BRCMF_ERROR(("No args provided\n"));
889 goto fail;
890 }
891
892 str = "pkt_filter_enable";
893 str_len = strlen(str);
894 strncpy(buf, str, str_len);
895 buf[str_len] = '\0';
896 buf_len = str_len + 1;
897
898 pkt_filterp = (struct brcmf_pkt_filter_enable *) (buf + str_len + 1);
899
900 /* Parse packet filter id. */
901 enable_parm.id = simple_strtoul(argv[i], NULL, 0);
902
903 /* Parse enable/disable value. */
904 enable_parm.enable = enable;
905
906 buf_len += sizeof(enable_parm);
907 memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
908
909 /* Enable/disable the specified filter. */
910 rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
911 rc = rc >= 0 ? 0 : rc;
912 if (rc)
913 BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
914 __func__, arg, rc));
915 else
916 BRCMF_TRACE(("%s: successfully added pktfilter %s\n",
917 __func__, arg));
918
919 /* Contorl the master mode */
920 brcmu_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf,
921 sizeof(buf));
922 rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf,
923 sizeof(buf));
924 rc = rc >= 0 ? 0 : rc;
925 if (rc)
926 BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
927 __func__, arg, rc));
928
929fail:
930 kfree(arg_org);
931}
932
933void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
934{
935 const char *str;
936 struct brcmf_pkt_filter pkt_filter;
937 struct brcmf_pkt_filter *pkt_filterp;
938 int buf_len;
939 int str_len;
940 int rc;
941 u32 mask_size;
942 u32 pattern_size;
943 char *argv[8], *buf = 0;
944 int i = 0;
945 char *arg_save = 0, *arg_org = 0;
946
947 arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
948 if (!arg_save) {
949 BRCMF_ERROR(("%s: kmalloc failed\n", __func__));
950 goto fail;
951 }
952
953 arg_org = arg_save;
954
955 buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
956 if (!buf) {
957 BRCMF_ERROR(("%s: kmalloc failed\n", __func__));
958 goto fail;
959 }
960
961 strcpy(arg_save, arg);
962
963 argv[i] = strsep(&arg_save, " ");
964 while (argv[i++])
965 argv[i] = strsep(&arg_save, " ");
966
967 i = 0;
968 if (NULL == argv[i]) {
969 BRCMF_ERROR(("No args provided\n"));
970 goto fail;
971 }
972
973 str = "pkt_filter_add";
974 strcpy(buf, str);
975 str_len = strlen(str);
976 buf_len = str_len + 1;
977
978 pkt_filterp = (struct brcmf_pkt_filter *) (buf + str_len + 1);
979
980 /* Parse packet filter id. */
981 pkt_filter.id = simple_strtoul(argv[i], NULL, 0);
982
983 if (NULL == argv[++i]) {
984 BRCMF_ERROR(("Polarity not provided\n"));
985 goto fail;
986 }
987
988 /* Parse filter polarity. */
989 pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0);
990
991 if (NULL == argv[++i]) {
992 BRCMF_ERROR(("Filter type not provided\n"));
993 goto fail;
994 }
995
996 /* Parse filter type. */
997 pkt_filter.type = simple_strtoul(argv[i], NULL, 0);
998
999 if (NULL == argv[++i]) {
1000 BRCMF_ERROR(("Offset not provided\n"));
1001 goto fail;
1002 }
1003
1004 /* Parse pattern filter offset. */
1005 pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0);
1006
1007 if (NULL == argv[++i]) {
1008 BRCMF_ERROR(("Bitmask not provided\n"));
1009 goto fail;
1010 }
1011
1012 /* Parse pattern filter mask. */
1013 mask_size =
1014 brcmf_c_pattern_atoh
1015 (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
1016
1017 if (NULL == argv[++i]) {
1018 BRCMF_ERROR(("Pattern not provided\n"));
1019 goto fail;
1020 }
1021
1022 /* Parse pattern filter pattern. */
1023 pattern_size =
1024 brcmf_c_pattern_atoh(argv[i],
1025 (char *)&pkt_filterp->u.pattern.
1026 mask_and_pattern[mask_size]);
1027
1028 if (mask_size != pattern_size) {
1029 BRCMF_ERROR(("Mask and pattern not the same size\n"));
1030 goto fail;
1031 }
1032
1033 pkt_filter.u.pattern.size_bytes = mask_size;
1034 buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
1035 buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
1036
1037 /* Keep-alive attributes are set in local
1038 * variable (keep_alive_pkt), and
1039 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
1040 ** guarantee that the buffer is properly aligned.
1041 */
1042 memcpy((char *)pkt_filterp,
1043 &pkt_filter,
1044 BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);
1045
1046 rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
1047 rc = rc >= 0 ? 0 : rc;
1048
1049 if (rc)
1050 BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
1051 __func__, arg, rc));
1052 else
1053 BRCMF_TRACE(("%s: successfully added pktfilter %s\n",
1054 __func__, arg));
1055
1056fail:
1057 kfree(arg_org);
1058
1059 kfree(buf);
1060}
1061
1062void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
1063{
1064 char iovbuf[32];
1065 int retcode;
1066
1067 brcmu_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
1068 retcode = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR,
1069 iovbuf, sizeof(iovbuf));
1070 retcode = retcode >= 0 ? 0 : retcode;
1071 if (retcode)
1072 BRCMF_TRACE(("%s: failed to set ARP offload mode to 0x%x, "
1073 "retcode = %d\n", __func__, arp_mode, retcode));
1074 else
1075 BRCMF_TRACE(("%s: successfully set ARP offload mode to 0x%x\n",
1076 __func__, arp_mode));
1077}
1078
1079void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
1080{
1081 char iovbuf[32];
1082 int retcode;
1083
1084 brcmu_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf));
1085 retcode = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR,
1086 iovbuf, sizeof(iovbuf));
1087 retcode = retcode >= 0 ? 0 : retcode;
1088 if (retcode)
1089 BRCMF_TRACE(("%s: failed to enabe ARP offload to %d, "
1090 "retcode = %d\n", __func__, arp_enable, retcode));
1091 else
1092 BRCMF_TRACE(("%s: successfully enabed ARP offload to %d\n",
1093 __func__, arp_enable));
1094}
1095
1096int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr)
1097{
1098 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for
1099 "event_msgs" + '\0' + bitvec */
1100 uint up = 0;
1101 char buf[128], *ptr;
1102 uint power_mode = PM_FAST;
1103 u32 dongle_align = BRCMF_SDALIGN;
1104 u32 glom = 0;
1105 uint bcn_timeout = 3;
1106 int scan_assoc_time = 40;
1107 int scan_unassoc_time = 40;
1108 int i;
1109
1110 brcmf_os_proto_block(drvr);
1111
1112 /* Set Country code */
1113 if (drvr->country_code[0] != 0) {
1114 if (brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_COUNTRY,
1115 drvr->country_code,
1116 sizeof(drvr->country_code)) < 0) {
1117 BRCMF_ERROR(("%s: country code setting failed\n",
1118 __func__));
1119 }
1120 }
1121
1122 /* query for 'ver' to get version info from firmware */
1123 memset(buf, 0, sizeof(buf));
1124 ptr = buf;
1125 brcmu_mkiovar("ver", 0, 0, buf, sizeof(buf));
1126 brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
1127 strsep(&ptr, "\n");
1128 /* Print fw version info */
1129 BRCMF_ERROR(("Firmware version = %s\n", buf));
1130
1131 /* Set PowerSave mode */
1132 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_PM, (char *)&power_mode,
1133 sizeof(power_mode));
1134
1135 /* Match Host and Dongle rx alignment */
1136 brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
1137 sizeof(iovbuf));
1138 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
1139 sizeof(iovbuf));
1140
1141 /* disable glom option per default */
1142 brcmu_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
1143 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
1144 sizeof(iovbuf));
1145
1146 /* Setup timeout if Beacons are lost and roam is off to report
1147 link down */
1148 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
1149 sizeof(iovbuf));
1150 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
1151 sizeof(iovbuf));
1152
1153 /* Enable/Disable build-in roaming to allowed ext supplicant to take
1154 of romaing */
1155 brcmu_mkiovar("roam_off", (char *)&brcmf_roam, 4,
1156 iovbuf, sizeof(iovbuf));
1157 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
1158 sizeof(iovbuf));
1159
1160 /* Force STA UP */
1161 if (brcmf_radio_up)
1162 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_UP, (char *)&up,
1163 sizeof(up));
1164
1165 /* Setup event_msgs */
1166 brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
1167 iovbuf, sizeof(iovbuf));
1168 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
1169 sizeof(iovbuf));
1170
1171 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
1172 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
1173 brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
1174 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
1175
1176 /* Set and enable ARP offload feature */
1177 if (brcmf_arp_enable)
1178 brcmf_c_arp_offload_set(drvr, brcmf_arp_mode);
1179 brcmf_c_arp_offload_enable(drvr, brcmf_arp_enable);
1180
1181 /* Set up pkt filter */
1182 if (brcmf_pkt_filter_enable) {
1183 for (i = 0; i < drvr->pktfilter_count; i++) {
1184 brcmf_c_pktfilter_offload_set(drvr,
1185 drvr->pktfilter[i]);
1186 brcmf_c_pktfilter_offload_enable(drvr,
1187 drvr->pktfilter[i],
1188 brcmf_pkt_filter_init,
1189 brcmf_master_mode);
1190 }
1191 }
1192
1193 brcmf_os_proto_unblock(drvr);
1194
1195 return 0;
1196}
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
new file mode 100644
index 00000000000..5be4d7a609c
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMF_DBG_H_
18#define _BRCMF_DBG_H_
19
20#if defined(BCMDBG)
21
22#define BRCMF_ERROR(args) \
23 do {if ((brcmf_msg_level & BRCMF_ERROR_VAL) && (net_ratelimit())) \
24 printk args; } while (0)
25#define BRCMF_TRACE(args) do {if (brcmf_msg_level & BRCMF_TRACE_VAL) \
26 printk args; } while (0)
27#define BRCMF_INFO(args) do {if (brcmf_msg_level & BRCMF_INFO_VAL) \
28 printk args; } while (0)
29#define BRCMF_DATA(args) do {if (brcmf_msg_level & BRCMF_DATA_VAL) \
30 printk args; } while (0)
31#define BRCMF_CTL(args) do {if (brcmf_msg_level & BRCMF_CTL_VAL) \
32 printk args; } while (0)
33#define BRCMF_TIMER(args) do {if (brcmf_msg_level & BRCMF_TIMER_VAL) \
34 printk args; } while (0)
35#define BRCMF_INTR(args) do {if (brcmf_msg_level & BRCMF_INTR_VAL) \
36 printk args; } while (0)
37#define BRCMF_GLOM(args) do {if (brcmf_msg_level & BRCMF_GLOM_VAL) \
38 printk args; } while (0)
39#define BRCMF_EVENT(args) do {if (brcmf_msg_level & BRCMF_EVENT_VAL) \
40 printk args; } while (0)
41
42#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL)
43#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL)
44#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
45#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL)
46#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
47
48#else /* (defined BCMDBG) || (defined BCMDBG) */
49
50#define BRCMF_ERROR(args) do {if (net_ratelimit()) printk args; } while (0)
51#define BRCMF_TRACE(args)
52#define BRCMF_INFO(args)
53#define BRCMF_DATA(args)
54#define BRCMF_CTL(args)
55#define BRCMF_TIMER(args)
56#define BRCMF_INTR(args)
57#define BRCMF_GLOM(args)
58#define BRCMF_EVENT(args)
59
60#define BRCMF_DATA_ON() 0
61#define BRCMF_CTL_ON() 0
62#define BRCMF_HDRS_ON() 0
63#define BRCMF_BYTES_ON() 0
64#define BRCMF_GLOM_ON() 0
65
66#endif /* defined(BCMDBG) */
67
68extern int brcmf_msg_level;
69
70#endif /* _BRCMF_DBG_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
new file mode 100644
index 00000000000..05dada98eb6
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
@@ -0,0 +1,1736 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/kthread.h>
20#include <linux/slab.h>
21#include <linux/skbuff.h>
22#include <linux/netdevice.h>
23#include <linux/etherdevice.h>
24#include <linux/mmc/sdio_func.h>
25#include <linux/random.h>
26#include <linux/spinlock.h>
27#include <linux/ethtool.h>
28#include <linux/fcntl.h>
29#include <linux/fs.h>
30#include <linux/uaccess.h>
31#include <linux/interrupt.h>
32#include <linux/hardirq.h>
33#include <net/cfg80211.h>
34#include <defs.h>
35#include <brcmu_utils.h>
36#include <brcmu_wifi.h>
37
38#include "dhd.h"
39#include "dhd_bus.h"
40#include "dhd_proto.h"
41#include "dhd_dbg.h"
42#include "wl_cfg80211.h"
43#include "bcmchip.h"
44
45#if defined(CONFIG_PM_SLEEP)
46#include <linux/suspend.h>
47atomic_t brcmf_mmc_suspend;
48#endif /* defined(CONFIG_PM_SLEEP) */
49
50MODULE_AUTHOR("Broadcom Corporation");
51MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
52MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
53MODULE_LICENSE("Dual BSD/GPL");
54
55
56/* Interface control information */
57struct brcmf_if {
58 struct brcmf_info *info; /* back pointer to brcmf_info */
59 /* OS/stack specifics */
60 struct net_device *net;
61 struct net_device_stats stats;
62 int idx; /* iface idx in dongle */
63 int state; /* interface state */
64 uint subunit; /* subunit */
65 u8 mac_addr[ETH_ALEN]; /* assigned MAC address */
66 bool attached; /* Delayed attachment when unset */
67 bool txflowcontrol; /* Per interface flow control indicator */
68 char name[IFNAMSIZ]; /* linux interface name */
69};
70
71/* Local private structure (extension of pub) */
72struct brcmf_info {
73 struct brcmf_pub pub;
74
75 /* OS/stack specifics */
76 struct brcmf_if *iflist[BRCMF_MAX_IFS];
77
78 struct semaphore proto_sem;
79 wait_queue_head_t ioctl_resp_wait;
80
81 /* Thread to issue ioctl for multicast */
82 struct task_struct *sysioc_tsk;
83 struct semaphore sysioc_sem;
84 bool set_multicast;
85 bool set_macaddress;
86 u8 macvalue[ETH_ALEN];
87 atomic_t pend_8021x_cnt;
88};
89
90/* Error bits */
91module_param(brcmf_msg_level, int, 0);
92
93/* Spawn a thread for system ioctls (set mac, set mcast) */
94uint brcmf_sysioc = true;
95module_param(brcmf_sysioc, uint, 0);
96
97/* ARP offload agent mode : Enable ARP Host Auto-Reply
98and ARP Peer Auto-Reply */
99uint brcmf_arp_mode = 0xb;
100module_param(brcmf_arp_mode, uint, 0);
101
102/* ARP offload enable */
103uint brcmf_arp_enable = true;
104module_param(brcmf_arp_enable, uint, 0);
105
106/* Global Pkt filter enable control */
107uint brcmf_pkt_filter_enable = true;
108module_param(brcmf_pkt_filter_enable, uint, 0);
109
110/* Pkt filter init setup */
111uint brcmf_pkt_filter_init;
112module_param(brcmf_pkt_filter_init, uint, 0);
113
114/* Pkt filter mode control */
115uint brcmf_master_mode = true;
116module_param(brcmf_master_mode, uint, 0);
117
118module_param(brcmf_dongle_memsize, int, 0);
119
120/* Contorl fw roaming */
121uint brcmf_roam = 1;
122
123/* Control radio state */
124uint brcmf_radio_up = 1;
125
126/* Network inteface name */
127char iface_name[IFNAMSIZ] = "wlan";
128module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
129
130/* The following are specific to the SDIO dongle */
131
132/* IOCTL response timeout */
133int brcmf_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT;
134
135/* Idle timeout for backplane clock */
136int brcmf_idletime = BRCMF_IDLETIME_TICKS;
137module_param(brcmf_idletime, int, 0);
138
139/* Use polling */
140uint brcmf_poll;
141module_param(brcmf_poll, uint, 0);
142
143/* Use interrupts */
144uint brcmf_intr = true;
145module_param(brcmf_intr, uint, 0);
146
147/* SDIO Drive Strength (in milliamps) */
148uint brcmf_sdiod_drive_strength = 6;
149module_param(brcmf_sdiod_drive_strength, uint, 0);
150
151/* Tx/Rx bounds */
152module_param(brcmf_txbound, uint, 0);
153module_param(brcmf_rxbound, uint, 0);
154
155#ifdef SDTEST
156/* Echo packet generator (pkts/s) */
157uint brcmf_pktgen;
158module_param(brcmf_pktgen, uint, 0);
159
160/* Echo packet len (0 => sawtooth, max 2040) */
161uint brcmf_pktgen_len;
162module_param(brcmf_pktgen_len, uint, 0);
163#endif
164
165static int brcmf_toe_get(struct brcmf_info *drvr_priv, int idx, u32 *toe_ol);
166static int brcmf_toe_set(struct brcmf_info *drvr_priv, int idx, u32 toe_ol);
167static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata,
168 struct brcmf_event_msg *event_ptr,
169 void **data_ptr);
170
171/*
172 * Generalized timeout mechanism. Uses spin sleep with exponential
173 * back-off until
174 * the sleep time reaches one jiffy, then switches over to task delay. Usage:
175 *
176 * brcmf_timeout_start(&tmo, usec);
177 * while (!brcmf_timeout_expired(&tmo))
178 * if (poll_something())
179 * break;
180 * if (brcmf_timeout_expired(&tmo))
181 * fatal();
182 */
183
184void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec)
185{
186 tmo->limit = usec;
187 tmo->increment = 0;
188 tmo->elapsed = 0;
189 tmo->tick = 1000000 / HZ;
190}
191
192int brcmf_timeout_expired(struct brcmf_timeout *tmo)
193{
194 /* Does nothing the first call */
195 if (tmo->increment == 0) {
196 tmo->increment = 1;
197 return 0;
198 }
199
200 if (tmo->elapsed >= tmo->limit)
201 return 1;
202
203 /* Add the delay that's about to take place */
204 tmo->elapsed += tmo->increment;
205
206 if (tmo->increment < tmo->tick) {
207 udelay(tmo->increment);
208 tmo->increment *= 2;
209 if (tmo->increment > tmo->tick)
210 tmo->increment = tmo->tick;
211 } else {
212 wait_queue_head_t delay_wait;
213 DECLARE_WAITQUEUE(wait, current);
214 int pending;
215 init_waitqueue_head(&delay_wait);
216 add_wait_queue(&delay_wait, &wait);
217 set_current_state(TASK_INTERRUPTIBLE);
218 schedule_timeout(1);
219 pending = signal_pending(current);
220 remove_wait_queue(&delay_wait, &wait);
221 set_current_state(TASK_RUNNING);
222 if (pending)
223 return 1; /* Interrupted */
224 }
225
226 return 0;
227}
228
229static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *net)
230{
231 int i = 0;
232
233 while (i < BRCMF_MAX_IFS) {
234 if (drvr_priv->iflist[i] && (drvr_priv->iflist[i]->net == net))
235 return i;
236 i++;
237 }
238
239 return BRCMF_BAD_IF;
240}
241
242int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name)
243{
244 int i = BRCMF_MAX_IFS;
245
246 if (name == NULL || *name == '\0')
247 return 0;
248
249 while (--i > 0)
250 if (drvr_priv->iflist[i]
251 && !strncmp(drvr_priv->iflist[i]->name, name, IFNAMSIZ))
252 break;
253
254 BRCMF_TRACE(("%s: return idx %d for \"%s\"\n", __func__, i, name));
255
256 return i; /* default - the primary interface */
257}
258
259char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
260{
261 struct brcmf_info *drvr_priv = drvr->info;
262
263 if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
264 BRCMF_ERROR(("%s: ifidx %d out of range\n", __func__, ifidx));
265 return "<if_bad>";
266 }
267
268 if (drvr_priv->iflist[ifidx] == NULL) {
269 BRCMF_ERROR(("%s: null i/f %d\n", __func__, ifidx));
270 return "<if_null>";
271 }
272
273 if (drvr_priv->iflist[ifidx]->net)
274 return drvr_priv->iflist[ifidx]->net->name;
275
276 return "<if_none>";
277}
278
279static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx)
280{
281 struct net_device *dev;
282 struct netdev_hw_addr *ha;
283 u32 allmulti, cnt;
284
285 struct brcmf_ioctl ioc;
286 char *buf, *bufp;
287 uint buflen;
288 int ret;
289
290 dev = drvr_priv->iflist[ifidx]->net;
291 cnt = netdev_mc_count(dev);
292
293 /* Determine initial value of allmulti flag */
294 allmulti = (dev->flags & IFF_ALLMULTI) ? true : false;
295
296 /* Send down the multicast list first. */
297
298 buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
299 bufp = buf = kmalloc(buflen, GFP_ATOMIC);
300 if (!bufp) {
301 BRCMF_ERROR(("%s: out of memory for mcast_list, cnt %d\n",
302 brcmf_ifname(&drvr_priv->pub, ifidx), cnt));
303 return;
304 }
305
306 strcpy(bufp, "mcast_list");
307 bufp += strlen("mcast_list") + 1;
308
309 cnt = cpu_to_le32(cnt);
310 memcpy(bufp, &cnt, sizeof(cnt));
311 bufp += sizeof(cnt);
312
313 netdev_for_each_mc_addr(ha, dev) {
314 if (!cnt)
315 break;
316 memcpy(bufp, ha->addr, ETH_ALEN);
317 bufp += ETH_ALEN;
318 cnt--;
319 }
320
321 memset(&ioc, 0, sizeof(ioc));
322 ioc.cmd = BRCMF_C_SET_VAR;
323 ioc.buf = buf;
324 ioc.len = buflen;
325 ioc.set = true;
326
327 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
328 if (ret < 0) {
329 BRCMF_ERROR(("%s: set mcast_list failed, cnt %d\n",
330 brcmf_ifname(&drvr_priv->pub, ifidx), cnt));
331 allmulti = cnt ? true : allmulti;
332 }
333
334 kfree(buf);
335
336 /* Now send the allmulti setting. This is based on the setting in the
337 * net_device flags, but might be modified above to be turned on if we
338 * were trying to set some addresses and dongle rejected it...
339 */
340
341 buflen = sizeof("allmulti") + sizeof(allmulti);
342 buf = kmalloc(buflen, GFP_ATOMIC);
343 if (!buf) {
344 BRCMF_ERROR(("%s: out of memory for allmulti\n",
345 brcmf_ifname(&drvr_priv->pub, ifidx)));
346 return;
347 }
348 allmulti = cpu_to_le32(allmulti);
349
350 if (!brcmu_mkiovar
351 ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) {
352 BRCMF_ERROR(("%s: mkiovar failed for allmulti, datalen %d "
353 "buflen %u\n",
354 brcmf_ifname(&drvr_priv->pub, ifidx),
355 (int)sizeof(allmulti), buflen));
356 kfree(buf);
357 return;
358 }
359
360 memset(&ioc, 0, sizeof(ioc));
361 ioc.cmd = BRCMF_C_SET_VAR;
362 ioc.buf = buf;
363 ioc.len = buflen;
364 ioc.set = true;
365
366 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
367 if (ret < 0) {
368 BRCMF_ERROR(("%s: set allmulti %d failed\n",
369 brcmf_ifname(&drvr_priv->pub, ifidx),
370 le32_to_cpu(allmulti)));
371 }
372
373 kfree(buf);
374
375 /* Finally, pick up the PROMISC flag as well, like the NIC
376 driver does */
377
378 allmulti = (dev->flags & IFF_PROMISC) ? true : false;
379 allmulti = cpu_to_le32(allmulti);
380
381 memset(&ioc, 0, sizeof(ioc));
382 ioc.cmd = BRCMF_C_SET_PROMISC;
383 ioc.buf = &allmulti;
384 ioc.len = sizeof(allmulti);
385 ioc.set = true;
386
387 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
388 if (ret < 0) {
389 BRCMF_ERROR(("%s: set promisc %d failed\n",
390 brcmf_ifname(&drvr_priv->pub, ifidx),
391 le32_to_cpu(allmulti)));
392 }
393}
394
395static int _brcmf_set_mac_address(struct brcmf_info *drvr_priv, int ifidx, u8 *addr)
396{
397 char buf[32];
398 struct brcmf_ioctl ioc;
399 int ret;
400
401 BRCMF_TRACE(("%s enter\n", __func__));
402 if (!brcmu_mkiovar
403 ("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) {
404 BRCMF_ERROR(("%s: mkiovar failed for cur_etheraddr\n",
405 brcmf_ifname(&drvr_priv->pub, ifidx)));
406 return -1;
407 }
408 memset(&ioc, 0, sizeof(ioc));
409 ioc.cmd = BRCMF_C_SET_VAR;
410 ioc.buf = buf;
411 ioc.len = 32;
412 ioc.set = true;
413
414 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
415 if (ret < 0) {
416 BRCMF_ERROR(("%s: set cur_etheraddr failed\n",
417 brcmf_ifname(&drvr_priv->pub, ifidx)));
418 } else {
419 memcpy(drvr_priv->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN);
420 }
421
422 return ret;
423}
424
425#ifdef SOFTAP
426extern struct net_device *ap_net_dev;
427#endif
428
429/* Virtual interfaces only ((ifp && ifp->info && ifp->idx == true) */
430static void brcmf_op_if(struct brcmf_if *ifp)
431{
432 struct brcmf_info *drvr_priv;
433 int ret = 0, err = 0;
434
435 drvr_priv = ifp->info;
436
437 BRCMF_TRACE(("%s: idx %d, state %d\n", __func__, ifp->idx, ifp->state));
438
439 switch (ifp->state) {
440 case BRCMF_E_IF_ADD:
441 /*
442 * Delete the existing interface before overwriting it
443 * in case we missed the BRCMF_E_IF_DEL event.
444 */
445 if (ifp->net != NULL) {
446 BRCMF_ERROR(("%s: ERROR: netdev:%s already exists, "
447 "try free & unregister\n",
448 __func__, ifp->net->name));
449 netif_stop_queue(ifp->net);
450 unregister_netdev(ifp->net);
451 free_netdev(ifp->net);
452 }
453 /* Allocate etherdev, including space for private structure */
454 ifp->net = alloc_etherdev(sizeof(drvr_priv));
455 if (!ifp->net) {
456 BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
457 ret = -ENOMEM;
458 }
459 if (ret == 0) {
460 strcpy(ifp->net->name, ifp->name);
461 memcpy(netdev_priv(ifp->net), &drvr_priv, sizeof(drvr_priv));
462 err = brcmf_net_attach(&drvr_priv->pub, ifp->idx);
463 if (err != 0) {
464 BRCMF_ERROR(("%s: brcmf_net_attach failed, "
465 "err %d\n",
466 __func__, err));
467 ret = -EOPNOTSUPP;
468 } else {
469#ifdef SOFTAP
470 /* semaphore that the soft AP CODE
471 waits on */
472 extern struct semaphore ap_eth_sema;
473
474 /* save ptr to wl0.1 netdev for use
475 in wl_iw.c */
476 ap_net_dev = ifp->net;
477 /* signal to the SOFTAP 'sleeper' thread,
478 wl0.1 is ready */
479 up(&ap_eth_sema);
480#endif
481 BRCMF_TRACE(("\n ==== pid:%x, net_device for "
482 "if:%s created ===\n\n",
483 current->pid, ifp->net->name));
484 ifp->state = 0;
485 }
486 }
487 break;
488 case BRCMF_E_IF_DEL:
489 if (ifp->net != NULL) {
490 BRCMF_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n",
491 __func__));
492 netif_stop_queue(ifp->net);
493 unregister_netdev(ifp->net);
494 ret = BRCMF_DEL_IF; /* Make sure the free_netdev()
495 is called */
496 }
497 break;
498 default:
499 BRCMF_ERROR(("%s: bad op %d\n", __func__, ifp->state));
500 break;
501 }
502
503 if (ret < 0) {
504 if (ifp->net)
505 free_netdev(ifp->net);
506
507 drvr_priv->iflist[ifp->idx] = NULL;
508 kfree(ifp);
509#ifdef SOFTAP
510 if (ifp->net == ap_net_dev)
511 ap_net_dev = NULL; /* NULL SOFTAP global
512 wl0.1 as well */
513#endif /* SOFTAP */
514 }
515}
516
517static int _brcmf_sysioc_thread(void *data)
518{
519 struct brcmf_info *drvr_priv = (struct brcmf_info *) data;
520 int i;
521#ifdef SOFTAP
522 bool in_ap = false;
523#endif
524
525 allow_signal(SIGTERM);
526
527 while (down_interruptible(&drvr_priv->sysioc_sem) == 0) {
528 if (kthread_should_stop())
529 break;
530 for (i = 0; i < BRCMF_MAX_IFS; i++) {
531 struct brcmf_if *ifentry = drvr_priv->iflist[i];
532 if (ifentry) {
533#ifdef SOFTAP
534 in_ap = (ap_net_dev != NULL);
535#endif /* SOFTAP */
536 if (ifentry->state)
537 brcmf_op_if(ifentry);
538#ifdef SOFTAP
539 if (drvr_priv->iflist[i] == NULL) {
540 BRCMF_TRACE(("\n\n %s: interface %d "
541 "removed!\n", __func__,
542 i));
543 continue;
544 }
545
546 if (in_ap && drvr_priv->set_macaddress) {
547 BRCMF_TRACE(("attempt to set MAC for"
548 " %s in AP Mode,"
549 " blocked.\n",
550 ifentry->net->name));
551 drvr_priv->set_macaddress = false;
552 continue;
553 }
554
555 if (in_ap && drvr_priv->set_multicast) {
556 BRCMF_TRACE(("attempt to set MULTICAST "
557 "list for %s in AP Mode, "
558 "blocked.\n",
559 ifentry->net->name));
560 drvr_priv->set_multicast = false;
561 continue;
562 }
563#endif /* SOFTAP */
564 if (drvr_priv->set_multicast) {
565 drvr_priv->set_multicast = false;
566 _brcmf_set_multicast_list(drvr_priv, i);
567 }
568 if (drvr_priv->set_macaddress) {
569 drvr_priv->set_macaddress = false;
570 _brcmf_set_mac_address(drvr_priv, i,
571 drvr_priv->macvalue);
572 }
573 }
574 }
575 }
576 return 0;
577}
578
579static int brcmf_netdev_set_mac_address(struct net_device *dev, void *addr)
580{
581 int ret = 0;
582
583 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev);
584 struct sockaddr *sa = (struct sockaddr *)addr;
585 int ifidx;
586
587 ifidx = brcmf_net2idx(drvr_priv, dev);
588 if (ifidx == BRCMF_BAD_IF)
589 return -1;
590
591 memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN);
592 drvr_priv->set_macaddress = true;
593 up(&drvr_priv->sysioc_sem);
594
595 return ret;
596}
597
598static void brcmf_netdev_set_multicast_list(struct net_device *dev)
599{
600 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev);
601 int ifidx;
602
603 ifidx = brcmf_net2idx(drvr_priv, dev);
604 if (ifidx == BRCMF_BAD_IF)
605 return;
606
607 drvr_priv->set_multicast = true;
608 up(&drvr_priv->sysioc_sem);
609}
610
611int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
612{
613 struct brcmf_info *drvr_priv = drvr->info;
614
615 /* Reject if down */
616 if (!drvr->up || (drvr->busstate == BRCMF_BUS_DOWN))
617 return -ENODEV;
618
619 /* Update multicast statistic */
620 if (pktbuf->len >= ETH_ALEN) {
621 u8 *pktdata = (u8 *) (pktbuf->data);
622 struct ethhdr *eh = (struct ethhdr *)pktdata;
623
624 if (is_multicast_ether_addr(eh->h_dest))
625 drvr->tx_multicast++;
626 if (ntohs(eh->h_proto) == ETH_P_PAE)
627 atomic_inc(&drvr_priv->pend_8021x_cnt);
628 }
629
630 /* If the protocol uses a data header, apply it */
631 brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
632
633 /* Use bus module to send data frame */
634 return brcmf_sdbrcm_bus_txdata(drvr->bus, pktbuf);
635}
636
637static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *net)
638{
639 int ret;
640 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
641 int ifidx;
642
643 BRCMF_TRACE(("%s: Enter\n", __func__));
644
645 /* Reject if down */
646 if (!drvr_priv->pub.up || (drvr_priv->pub.busstate == BRCMF_BUS_DOWN)) {
647 BRCMF_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n",
648 __func__, drvr_priv->pub.up,
649 drvr_priv->pub.busstate));
650 netif_stop_queue(net);
651 return -ENODEV;
652 }
653
654 ifidx = brcmf_net2idx(drvr_priv, net);
655 if (ifidx == BRCMF_BAD_IF) {
656 BRCMF_ERROR(("%s: bad ifidx %d\n", __func__, ifidx));
657 netif_stop_queue(net);
658 return -ENODEV;
659 }
660
661 /* Make sure there's enough room for any header */
662 if (skb_headroom(skb) < drvr_priv->pub.hdrlen) {
663 struct sk_buff *skb2;
664
665 BRCMF_INFO(("%s: insufficient headroom\n",
666 brcmf_ifname(&drvr_priv->pub, ifidx)));
667 drvr_priv->pub.tx_realloc++;
668 skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen);
669 dev_kfree_skb(skb);
670 skb = skb2;
671 if (skb == NULL) {
672 BRCMF_ERROR(("%s: skb_realloc_headroom failed\n",
673 brcmf_ifname(&drvr_priv->pub, ifidx)));
674 ret = -ENOMEM;
675 goto done;
676 }
677 }
678
679 ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb);
680
681done:
682 if (ret)
683 drvr_priv->pub.dstats.tx_dropped++;
684 else
685 drvr_priv->pub.tx_packets++;
686
687 /* Return ok: we always eat the packet */
688 return 0;
689}
690
691void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state)
692{
693 struct net_device *net;
694 struct brcmf_info *drvr_priv = drvr->info;
695
696 BRCMF_TRACE(("%s: Enter\n", __func__));
697
698 drvr->txoff = state;
699 net = drvr_priv->iflist[ifidx]->net;
700 if (state == ON)
701 netif_stop_queue(net);
702 else
703 netif_wake_queue(net);
704}
705
706void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb,
707 int numpkt)
708{
709 struct brcmf_info *drvr_priv = drvr->info;
710 unsigned char *eth;
711 uint len;
712 void *data;
713 struct sk_buff *pnext, *save_pktbuf;
714 int i;
715 struct brcmf_if *ifp;
716 struct brcmf_event_msg event;
717
718 BRCMF_TRACE(("%s: Enter\n", __func__));
719
720 save_pktbuf = skb;
721
722 for (i = 0; skb && i < numpkt; i++, skb = pnext) {
723
724 pnext = skb->next;
725 skb->next = NULL;
726
727 /* Get the protocol, maintain skb around eth_type_trans()
728 * The main reason for this hack is for the limitation of
729 * Linux 2.4 where 'eth_type_trans' uses the
730 * 'net->hard_header_len'
731 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
732 * coping of the packet coming from the network stack to add
733 * BDC, Hardware header etc, during network interface
734 * registration
735 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
736 * required
737 * for BDC, Hardware header etc. and not just the ETH_HLEN
738 */
739 eth = skb->data;
740 len = skb->len;
741
742 ifp = drvr_priv->iflist[ifidx];
743 if (ifp == NULL)
744 ifp = drvr_priv->iflist[0];
745
746 skb->dev = ifp->net;
747 skb->protocol = eth_type_trans(skb, skb->dev);
748
749 if (skb->pkt_type == PACKET_MULTICAST)
750 drvr_priv->pub.rx_multicast++;
751
752 skb->data = eth;
753 skb->len = len;
754
755 /* Strip header, count, deliver upward */
756 skb_pull(skb, ETH_HLEN);
757
758 /* Process special event packets and then discard them */
759 if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
760 brcmf_host_event(drvr_priv, &ifidx,
761 skb_mac_header(skb),
762 &event, &data);
763
764 if (drvr_priv->iflist[ifidx] &&
765 !drvr_priv->iflist[ifidx]->state)
766 ifp = drvr_priv->iflist[ifidx];
767
768 if (ifp->net)
769 ifp->net->last_rx = jiffies;
770
771 drvr->dstats.rx_bytes += skb->len;
772 drvr->rx_packets++; /* Local count */
773
774 if (in_interrupt()) {
775 netif_rx(skb);
776 } else {
777 /* If the receive is not processed inside an ISR,
778 * the softirqd must be woken explicitly to service
779 * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled
780 * by netif_rx_ni(), but in earlier kernels, we need
781 * to do it manually.
782 */
783 netif_rx_ni(skb);
784 }
785 }
786}
787
788void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success)
789{
790 uint ifidx;
791 struct brcmf_info *drvr_priv = drvr->info;
792 struct ethhdr *eh;
793 u16 type;
794
795 brcmf_proto_hdrpull(drvr, &ifidx, txp);
796
797 eh = (struct ethhdr *)(txp->data);
798 type = ntohs(eh->h_proto);
799
800 if (type == ETH_P_PAE)
801 atomic_dec(&drvr_priv->pend_8021x_cnt);
802
803}
804
805static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *net)
806{
807 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
808 struct brcmf_if *ifp;
809 int ifidx;
810
811 BRCMF_TRACE(("%s: Enter\n", __func__));
812
813 ifidx = brcmf_net2idx(drvr_priv, net);
814 if (ifidx == BRCMF_BAD_IF)
815 return NULL;
816
817 ifp = drvr_priv->iflist[ifidx];
818
819 if (drvr_priv->pub.up) {
820 /* Use the protocol to get dongle stats */
821 brcmf_proto_dstats(&drvr_priv->pub);
822 }
823
824 /* Copy dongle stats to net device stats */
825 ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets;
826 ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets;
827 ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes;
828 ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes;
829 ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors;
830 ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors;
831 ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped;
832 ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped;
833 ifp->stats.multicast = drvr_priv->pub.dstats.multicast;
834
835 return &ifp->stats;
836}
837
838/* Retrieve current toe component enables, which are kept
839 as a bitmap in toe_ol iovar */
840static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol)
841{
842 struct brcmf_ioctl ioc;
843 char buf[32];
844 int ret;
845
846 memset(&ioc, 0, sizeof(ioc));
847
848 ioc.cmd = BRCMF_C_GET_VAR;
849 ioc.buf = buf;
850 ioc.len = (uint) sizeof(buf);
851 ioc.set = false;
852
853 strcpy(buf, "toe_ol");
854 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
855 if (ret < 0) {
856 /* Check for older dongle image that doesn't support toe_ol */
857 if (ret == -EIO) {
858 BRCMF_ERROR(("%s: toe not supported by device\n",
859 brcmf_ifname(&drvr_priv->pub, ifidx)));
860 return -EOPNOTSUPP;
861 }
862
863 BRCMF_INFO(("%s: could not get toe_ol: ret=%d\n",
864 brcmf_ifname(&drvr_priv->pub, ifidx), ret));
865 return ret;
866 }
867
868 memcpy(toe_ol, buf, sizeof(u32));
869 return 0;
870}
871
872/* Set current toe component enables in toe_ol iovar,
873 and set toe global enable iovar */
874static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol)
875{
876 struct brcmf_ioctl ioc;
877 char buf[32];
878 int toe, ret;
879
880 memset(&ioc, 0, sizeof(ioc));
881
882 ioc.cmd = BRCMF_C_SET_VAR;
883 ioc.buf = buf;
884 ioc.len = (uint) sizeof(buf);
885 ioc.set = true;
886
887 /* Set toe_ol as requested */
888
889 strcpy(buf, "toe_ol");
890 memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32));
891
892 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
893 if (ret < 0) {
894 BRCMF_ERROR(("%s: could not set toe_ol: ret=%d\n",
895 brcmf_ifname(&drvr_priv->pub, ifidx), ret));
896 return ret;
897 }
898
899 /* Enable toe globally only if any components are enabled. */
900
901 toe = (toe_ol != 0);
902
903 strcpy(buf, "toe");
904 memcpy(&buf[sizeof("toe")], &toe, sizeof(u32));
905
906 ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len);
907 if (ret < 0) {
908 BRCMF_ERROR(("%s: could not set toe: ret=%d\n",
909 brcmf_ifname(&drvr_priv->pub, ifidx), ret));
910 return ret;
911 }
912
913 return 0;
914}
915
916static void brcmf_ethtool_get_drvinfo(struct net_device *net,
917 struct ethtool_drvinfo *info)
918{
919 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
920
921 sprintf(info->driver, KBUILD_MODNAME);
922 sprintf(info->version, "%lu", drvr_priv->pub.drv_version);
923 sprintf(info->fw_version, "%s", BCM4329_FW_NAME);
924 sprintf(info->bus_info, "%s",
925 dev_name(&brcmf_cfg80211_get_sdio_func()->dev));
926}
927
928struct ethtool_ops brcmf_ethtool_ops = {
929 .get_drvinfo = brcmf_ethtool_get_drvinfo
930};
931
932static int brcmf_ethtool(struct brcmf_info *drvr_priv, void *uaddr)
933{
934 struct ethtool_drvinfo info;
935 char drvname[sizeof(info.driver)];
936 u32 cmd;
937 struct ethtool_value edata;
938 u32 toe_cmpnt, csum_dir;
939 int ret;
940
941 BRCMF_TRACE(("%s: Enter\n", __func__));
942
943 /* all ethtool calls start with a cmd word */
944 if (copy_from_user(&cmd, uaddr, sizeof(u32)))
945 return -EFAULT;
946
947 switch (cmd) {
948 case ETHTOOL_GDRVINFO:
949 /* Copy out any request driver name */
950 if (copy_from_user(&info, uaddr, sizeof(info)))
951 return -EFAULT;
952 strncpy(drvname, info.driver, sizeof(info.driver));
953 drvname[sizeof(info.driver) - 1] = '\0';
954
955 /* clear struct for return */
956 memset(&info, 0, sizeof(info));
957 info.cmd = cmd;
958
959 /* if requested, identify ourselves */
960 if (strcmp(drvname, "?dhd") == 0) {
961 sprintf(info.driver, "dhd");
962 strcpy(info.version, BRCMF_VERSION_STR);
963 }
964
965 /* otherwise, require dongle to be up */
966 else if (!drvr_priv->pub.up) {
967 BRCMF_ERROR(("%s: dongle is not up\n", __func__));
968 return -ENODEV;
969 }
970
971 /* finally, report dongle driver type */
972 else if (drvr_priv->pub.iswl)
973 sprintf(info.driver, "wl");
974 else
975 sprintf(info.driver, "xx");
976
977 sprintf(info.version, "%lu", drvr_priv->pub.drv_version);
978 if (copy_to_user(uaddr, &info, sizeof(info)))
979 return -EFAULT;
980 BRCMF_CTL(("%s: given %*s, returning %s\n", __func__,
981 (int)sizeof(drvname), drvname, info.driver));
982 break;
983
984 /* Get toe offload components from dongle */
985 case ETHTOOL_GRXCSUM:
986 case ETHTOOL_GTXCSUM:
987 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
988 if (ret < 0)
989 return ret;
990
991 csum_dir =
992 (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
993
994 edata.cmd = cmd;
995 edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
996
997 if (copy_to_user(uaddr, &edata, sizeof(edata)))
998 return -EFAULT;
999 break;
1000
1001 /* Set toe offload components in dongle */
1002 case ETHTOOL_SRXCSUM:
1003 case ETHTOOL_STXCSUM:
1004 if (copy_from_user(&edata, uaddr, sizeof(edata)))
1005 return -EFAULT;
1006
1007 /* Read the current settings, update and write back */
1008 ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt);
1009 if (ret < 0)
1010 return ret;
1011
1012 csum_dir =
1013 (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
1014
1015 if (edata.data != 0)
1016 toe_cmpnt |= csum_dir;
1017 else
1018 toe_cmpnt &= ~csum_dir;
1019
1020 ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt);
1021 if (ret < 0)
1022 return ret;
1023
1024 /* If setting TX checksum mode, tell Linux the new mode */
1025 if (cmd == ETHTOOL_STXCSUM) {
1026 if (edata.data)
1027 drvr_priv->iflist[0]->net->features |=
1028 NETIF_F_IP_CSUM;
1029 else
1030 drvr_priv->iflist[0]->net->features &=
1031 ~NETIF_F_IP_CSUM;
1032 }
1033
1034 break;
1035
1036 default:
1037 return -EOPNOTSUPP;
1038 }
1039
1040 return 0;
1041}
1042
1043static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr,
1044 int cmd)
1045{
1046 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
1047 struct brcmf_c_ioctl ioc;
1048 int bcmerror = 0;
1049 int buflen = 0;
1050 void *buf = NULL;
1051 uint driver = 0;
1052 int ifidx;
1053 bool is_set_key_cmd;
1054
1055 ifidx = brcmf_net2idx(drvr_priv, net);
1056 BRCMF_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __func__, ifidx, cmd));
1057
1058 if (ifidx == BRCMF_BAD_IF)
1059 return -1;
1060
1061 if (cmd == SIOCETHTOOL)
1062 return brcmf_ethtool(drvr_priv, (void *)ifr->ifr_data);
1063
1064 if (cmd != SIOCDEVPRIVATE)
1065 return -EOPNOTSUPP;
1066
1067 memset(&ioc, 0, sizeof(ioc));
1068
1069 /* Copy the ioc control structure part of ioctl request */
1070 if (copy_from_user(&ioc, ifr->ifr_data, sizeof(struct brcmf_ioctl))) {
1071 bcmerror = -EINVAL;
1072 goto done;
1073 }
1074
1075 /* Copy out any buffer passed */
1076 if (ioc.buf) {
1077 buflen = min_t(int, ioc.len, BRCMF_IOCTL_MAXLEN);
1078 /* optimization for direct ioctl calls from kernel */
1079 /*
1080 if (segment_eq(get_fs(), KERNEL_DS)) {
1081 buf = ioc.buf;
1082 } else {
1083 */
1084 {
1085 buf = kmalloc(buflen, GFP_ATOMIC);
1086 if (!buf) {
1087 bcmerror = -ENOMEM;
1088 goto done;
1089 }
1090 if (copy_from_user(buf, ioc.buf, buflen)) {
1091 bcmerror = -EINVAL;
1092 goto done;
1093 }
1094 }
1095 }
1096
1097 /* To differentiate read 4 more byes */
1098 if ((copy_from_user(&driver, (char *)ifr->ifr_data +
1099 sizeof(struct brcmf_ioctl), sizeof(uint)) != 0)) {
1100 bcmerror = -EINVAL;
1101 goto done;
1102 }
1103
1104 if (!capable(CAP_NET_ADMIN)) {
1105 bcmerror = -EPERM;
1106 goto done;
1107 }
1108
1109 /* check for local brcmf ioctl and handle it */
1110 if (driver == BRCMF_IOCTL_MAGIC) {
1111 bcmerror = brcmf_c_ioctl((void *)&drvr_priv->pub, &ioc, buf, buflen);
1112 if (bcmerror)
1113 drvr_priv->pub.bcmerror = bcmerror;
1114 goto done;
1115 }
1116
1117 /* send to dongle (must be up, and wl) */
1118 if ((drvr_priv->pub.busstate != BRCMF_BUS_DATA)) {
1119 BRCMF_ERROR(("%s DONGLE_DOWN,__func__\n", __func__));
1120 bcmerror = -EIO;
1121 goto done;
1122 }
1123
1124 if (!drvr_priv->pub.iswl) {
1125 bcmerror = -EIO;
1126 goto done;
1127 }
1128
1129 /*
1130 * Intercept BRCMF_C_SET_KEY IOCTL - serialize M4 send and
1131 * set key IOCTL to prevent M4 encryption.
1132 */
1133 is_set_key_cmd = ((ioc.cmd == BRCMF_C_SET_KEY) ||
1134 ((ioc.cmd == BRCMF_C_SET_VAR) &&
1135 !(strncmp("wsec_key", ioc.buf, 9))) ||
1136 ((ioc.cmd == BRCMF_C_SET_VAR) &&
1137 !(strncmp("bsscfg:wsec_key", ioc.buf, 15))));
1138 if (is_set_key_cmd)
1139 brcmf_netdev_wait_pend8021x(net);
1140
1141 bcmerror =
1142 brcmf_proto_ioctl(&drvr_priv->pub, ifidx, (struct brcmf_ioctl *)&ioc,
1143 buf, buflen);
1144
1145done:
1146 if (!bcmerror && buf && ioc.buf) {
1147 if (copy_to_user(ioc.buf, buf, buflen))
1148 bcmerror = -EFAULT;
1149 }
1150
1151 kfree(buf);
1152
1153 if (bcmerror > 0)
1154 bcmerror = 0;
1155
1156 return bcmerror;
1157}
1158
1159static int brcmf_netdev_stop(struct net_device *net)
1160{
1161#if !defined(IGNORE_ETH0_DOWN)
1162 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
1163
1164 BRCMF_TRACE(("%s: Enter\n", __func__));
1165 brcmf_cfg80211_down();
1166 if (drvr_priv->pub.up == 0)
1167 return 0;
1168
1169 /* Set state and stop OS transmissions */
1170 drvr_priv->pub.up = 0;
1171 netif_stop_queue(net);
1172#else
1173 BRCMF_ERROR(("BYPASS %s:due to BRCM compilation: under investigation\n",
1174 __func__));
1175#endif /* !defined(IGNORE_ETH0_DOWN) */
1176
1177 return 0;
1178}
1179
1180static int brcmf_netdev_open(struct net_device *net)
1181{
1182 struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net);
1183 u32 toe_ol;
1184 int ifidx = brcmf_net2idx(drvr_priv, net);
1185 s32 ret = 0;
1186
1187 BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx));
1188
1189 if (ifidx == 0) { /* do it only for primary eth0 */
1190
1191 /* try to bring up bus */
1192 ret = brcmf_bus_start(&drvr_priv->pub);
1193 if (ret != 0) {
1194 BRCMF_ERROR(("%s: failed with code %d\n",
1195 __func__, ret));
1196 return -1;
1197 }
1198 atomic_set(&drvr_priv->pend_8021x_cnt, 0);
1199
1200 memcpy(net->dev_addr, drvr_priv->pub.mac, ETH_ALEN);
1201
1202 /* Get current TOE mode from dongle */
1203 if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0
1204 && (toe_ol & TOE_TX_CSUM_OL) != 0)
1205 drvr_priv->iflist[ifidx]->net->features |=
1206 NETIF_F_IP_CSUM;
1207 else
1208 drvr_priv->iflist[ifidx]->net->features &=
1209 ~NETIF_F_IP_CSUM;
1210 }
1211 /* Allow transmit calls */
1212 netif_start_queue(net);
1213 drvr_priv->pub.up = 1;
1214 if (unlikely(brcmf_cfg80211_up())) {
1215 BRCMF_ERROR(("%s: failed to bring up cfg80211\n",
1216 __func__));
1217 return -1;
1218 }
1219
1220 return ret;
1221}
1222
1223int
1224brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, char *name,
1225 u8 *mac_addr, u32 flags, u8 bssidx)
1226{
1227 struct brcmf_if *ifp;
1228
1229 BRCMF_TRACE(("%s: idx %d, handle->%p\n", __func__, ifidx, handle));
1230
1231 ifp = drvr_priv->iflist[ifidx];
1232 if (!ifp) {
1233 ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC);
1234 if (!ifp) {
1235 BRCMF_ERROR(("%s: OOM - struct brcmf_if\n", __func__));
1236 return -ENOMEM;
1237 }
1238 }
1239
1240 memset(ifp, 0, sizeof(struct brcmf_if));
1241 ifp->info = drvr_priv;
1242 drvr_priv->iflist[ifidx] = ifp;
1243 strlcpy(ifp->name, name, IFNAMSIZ);
1244 if (mac_addr != NULL)
1245 memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
1246
1247 if (handle == NULL) {
1248 ifp->state = BRCMF_E_IF_ADD;
1249 ifp->idx = ifidx;
1250 up(&drvr_priv->sysioc_sem);
1251 } else
1252 ifp->net = (struct net_device *)handle;
1253
1254 return 0;
1255}
1256
1257void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx)
1258{
1259 struct brcmf_if *ifp;
1260
1261 BRCMF_TRACE(("%s: idx %d\n", __func__, ifidx));
1262
1263 ifp = drvr_priv->iflist[ifidx];
1264 if (!ifp) {
1265 BRCMF_ERROR(("%s: Null interface\n", __func__));
1266 return;
1267 }
1268
1269 ifp->state = BRCMF_E_IF_DEL;
1270 ifp->idx = ifidx;
1271 up(&drvr_priv->sysioc_sem);
1272}
1273
1274struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen)
1275{
1276 struct brcmf_info *drvr_priv = NULL;
1277 struct net_device *net;
1278
1279 BRCMF_TRACE(("%s: Enter\n", __func__));
1280
1281 /* Allocate etherdev, including space for private structure */
1282 net = alloc_etherdev(sizeof(drvr_priv));
1283 if (!net) {
1284 BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
1285 goto fail;
1286 }
1287
1288 /* Allocate primary brcmf_info */
1289 drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC);
1290 if (!drvr_priv) {
1291 BRCMF_ERROR(("%s: OOM - alloc brcmf_info\n", __func__));
1292 goto fail;
1293 }
1294
1295 /*
1296 * Save the brcmf_info into the priv
1297 */
1298 memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv));
1299
1300 /* Set network interface name if it was provided as module parameter */
1301 if (iface_name[0]) {
1302 int len;
1303 char ch;
1304 strncpy(net->name, iface_name, IFNAMSIZ);
1305 net->name[IFNAMSIZ - 1] = 0;
1306 len = strlen(net->name);
1307 ch = net->name[len - 1];
1308 if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2))
1309 strcat(net->name, "%d");
1310 }
1311
1312 if (brcmf_add_if(drvr_priv, 0, (void *)net, net->name, NULL, 0, 0) ==
1313 BRCMF_BAD_IF)
1314 goto fail;
1315
1316 net->netdev_ops = NULL;
1317 sema_init(&drvr_priv->proto_sem, 1);
1318 /* Initialize other structure content */
1319 init_waitqueue_head(&drvr_priv->ioctl_resp_wait);
1320
1321 /* Link to info module */
1322 drvr_priv->pub.info = drvr_priv;
1323
1324 /* Link to bus module */
1325 drvr_priv->pub.bus = bus;
1326 drvr_priv->pub.hdrlen = bus_hdrlen;
1327
1328 /* Attach and link in the protocol */
1329 if (brcmf_proto_attach(&drvr_priv->pub) != 0) {
1330 BRCMF_ERROR(("brcmf_prot_attach failed\n"));
1331 goto fail;
1332 }
1333
1334 /* Attach and link in the cfg80211 */
1335 if (unlikely(brcmf_cfg80211_attach(net, &drvr_priv->pub))) {
1336 BRCMF_ERROR(("wl_cfg80211_attach failed\n"));
1337 goto fail;
1338 }
1339
1340 if (brcmf_sysioc) {
1341 sema_init(&drvr_priv->sysioc_sem, 0);
1342 drvr_priv->sysioc_tsk = kthread_run(_brcmf_sysioc_thread, drvr_priv,
1343 "_brcmf_sysioc");
1344 if (IS_ERR(drvr_priv->sysioc_tsk)) {
1345 printk(KERN_WARNING
1346 "_brcmf_sysioc thread failed to start\n");
1347 drvr_priv->sysioc_tsk = NULL;
1348 }
1349 } else
1350 drvr_priv->sysioc_tsk = NULL;
1351
1352 /*
1353 * Save the brcmf_info into the priv
1354 */
1355 memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv));
1356
1357#if defined(CONFIG_PM_SLEEP)
1358 atomic_set(&brcmf_mmc_suspend, false);
1359#endif /* defined(CONFIG_PM_SLEEP) */
1360 return &drvr_priv->pub;
1361
1362fail:
1363 if (net)
1364 free_netdev(net);
1365 if (drvr_priv)
1366 brcmf_detach(&drvr_priv->pub);
1367
1368 return NULL;
1369}
1370
1371int brcmf_bus_start(struct brcmf_pub *drvr)
1372{
1373 int ret = -1;
1374 struct brcmf_info *drvr_priv = drvr->info;
1375 /* Room for "event_msgs" + '\0' + bitvec */
1376 char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
1377
1378 BRCMF_TRACE(("%s:\n", __func__));
1379
1380 /* Bring up the bus */
1381 ret = brcmf_sdbrcm_bus_init(&drvr_priv->pub, true);
1382 if (ret != 0) {
1383 BRCMF_ERROR(("%s, brcmf_sdbrcm_bus_init failed %d\n", __func__,
1384 ret));
1385 return ret;
1386 }
1387
1388 /* If bus is not ready, can't come up */
1389 if (drvr_priv->pub.busstate != BRCMF_BUS_DATA) {
1390 BRCMF_ERROR(("%s failed bus is not ready\n", __func__));
1391 return -ENODEV;
1392 }
1393
1394 brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
1395 iovbuf, sizeof(iovbuf));
1396 brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
1397 sizeof(iovbuf));
1398 memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
1399
1400 setbit(drvr->eventmask, BRCMF_E_SET_SSID);
1401 setbit(drvr->eventmask, BRCMF_E_PRUNE);
1402 setbit(drvr->eventmask, BRCMF_E_AUTH);
1403 setbit(drvr->eventmask, BRCMF_E_REASSOC);
1404 setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
1405 setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
1406 setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
1407 setbit(drvr->eventmask, BRCMF_E_DISASSOC);
1408 setbit(drvr->eventmask, BRCMF_E_JOIN);
1409 setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
1410 setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
1411 setbit(drvr->eventmask, BRCMF_E_LINK);
1412 setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
1413 setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
1414 setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
1415 setbit(drvr->eventmask, BRCMF_E_TXFAIL);
1416 setbit(drvr->eventmask, BRCMF_E_JOIN_START);
1417 setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
1418
1419/* enable dongle roaming event */
1420
1421 drvr->pktfilter_count = 1;
1422 /* Setup filter to allow only unicast */
1423 drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
1424
1425 /* Bus is ready, do any protocol initialization */
1426 ret = brcmf_proto_init(&drvr_priv->pub);
1427 if (ret < 0)
1428 return ret;
1429
1430 return 0;
1431}
1432
1433static struct net_device_ops brcmf_netdev_ops_pri = {
1434 .ndo_open = brcmf_netdev_open,
1435 .ndo_stop = brcmf_netdev_stop,
1436 .ndo_get_stats = brcmf_netdev_get_stats,
1437 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
1438 .ndo_start_xmit = brcmf_netdev_start_xmit,
1439 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
1440 .ndo_set_multicast_list = brcmf_netdev_set_multicast_list
1441};
1442
1443int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
1444{
1445 struct brcmf_info *drvr_priv = drvr->info;
1446 struct net_device *net;
1447 u8 temp_addr[ETH_ALEN] = {
1448 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
1449
1450 BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx));
1451
1452 net = drvr_priv->iflist[ifidx]->net;
1453 net->netdev_ops = &brcmf_netdev_ops_pri;
1454
1455 /*
1456 * We have to use the primary MAC for virtual interfaces
1457 */
1458 if (ifidx != 0) {
1459 /* for virtual interfaces use the primary MAC */
1460 memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN);
1461
1462 }
1463
1464 if (ifidx == 1) {
1465 BRCMF_TRACE(("%s ACCESS POINT MAC:\n", __func__));
1466 /* ACCESSPOINT INTERFACE CASE */
1467 temp_addr[0] |= 0X02; /* set bit 2 ,
1468 - Locally Administered address */
1469
1470 }
1471 net->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen;
1472 net->ethtool_ops = &brcmf_ethtool_ops;
1473
1474 drvr_priv->pub.rxsz = net->mtu + net->hard_header_len +
1475 drvr_priv->pub.hdrlen;
1476
1477 memcpy(net->dev_addr, temp_addr, ETH_ALEN);
1478
1479 if (register_netdev(net) != 0) {
1480 BRCMF_ERROR(("%s: couldn't register the net device\n",
1481 __func__));
1482 goto fail;
1483 }
1484
1485 BRCMF_INFO(("%s: Broadcom Dongle Host Driver\n", net->name));
1486
1487 return 0;
1488
1489fail:
1490 net->netdev_ops = NULL;
1491 return -EBADE;
1492}
1493
1494static void brcmf_bus_detach(struct brcmf_pub *drvr)
1495{
1496 struct brcmf_info *drvr_priv;
1497
1498 BRCMF_TRACE(("%s: Enter\n", __func__));
1499
1500 if (drvr) {
1501 drvr_priv = drvr->info;
1502 if (drvr_priv) {
1503 /* Stop the protocol module */
1504 brcmf_proto_stop(&drvr_priv->pub);
1505
1506 /* Stop the bus module */
1507 brcmf_sdbrcm_bus_stop(drvr_priv->pub.bus, true);
1508 }
1509 }
1510}
1511
1512void brcmf_detach(struct brcmf_pub *drvr)
1513{
1514 struct brcmf_info *drvr_priv;
1515
1516 BRCMF_TRACE(("%s: Enter\n", __func__));
1517
1518 if (drvr) {
1519 drvr_priv = drvr->info;
1520 if (drvr_priv) {
1521 struct brcmf_if *ifp;
1522 int i;
1523
1524 for (i = 1; i < BRCMF_MAX_IFS; i++)
1525 if (drvr_priv->iflist[i])
1526 brcmf_del_if(drvr_priv, i);
1527
1528 ifp = drvr_priv->iflist[0];
1529 if (ifp->net->netdev_ops == &brcmf_netdev_ops_pri) {
1530 brcmf_netdev_stop(ifp->net);
1531 unregister_netdev(ifp->net);
1532 }
1533
1534 if (drvr_priv->sysioc_tsk) {
1535 send_sig(SIGTERM, drvr_priv->sysioc_tsk, 1);
1536 kthread_stop(drvr_priv->sysioc_tsk);
1537 drvr_priv->sysioc_tsk = NULL;
1538 }
1539
1540 brcmf_bus_detach(drvr);
1541
1542 if (drvr->prot)
1543 brcmf_proto_detach(drvr);
1544
1545 brcmf_cfg80211_detach();
1546
1547 free_netdev(ifp->net);
1548 kfree(ifp);
1549 kfree(drvr_priv);
1550 }
1551 }
1552}
1553
1554static void __exit brcmf_module_cleanup(void)
1555{
1556 BRCMF_TRACE(("%s: Enter\n", __func__));
1557
1558 brcmf_bus_unregister();
1559}
1560
1561static int __init brcmf_module_init(void)
1562{
1563 int error;
1564
1565 BRCMF_TRACE(("%s: Enter\n", __func__));
1566
1567 error = brcmf_bus_register();
1568
1569 if (error) {
1570 BRCMF_ERROR(("%s: brcmf_bus_register failed\n", __func__));
1571 goto failed;
1572 }
1573 return 0;
1574
1575failed:
1576 return -EINVAL;
1577}
1578
1579module_init(brcmf_module_init);
1580module_exit(brcmf_module_cleanup);
1581
1582int brcmf_os_proto_block(struct brcmf_pub *drvr)
1583{
1584 struct brcmf_info *drvr_priv = drvr->info;
1585
1586 if (drvr_priv) {
1587 down(&drvr_priv->proto_sem);
1588 return 1;
1589 }
1590 return 0;
1591}
1592
1593int brcmf_os_proto_unblock(struct brcmf_pub *drvr)
1594{
1595 struct brcmf_info *drvr_priv = drvr->info;
1596
1597 if (drvr_priv) {
1598 up(&drvr_priv->proto_sem);
1599 return 1;
1600 }
1601
1602 return 0;
1603}
1604
1605unsigned int brcmf_os_get_ioctl_resp_timeout(void)
1606{
1607 return (unsigned int)brcmf_ioctl_timeout_msec;
1608}
1609
1610void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec)
1611{
1612 brcmf_ioctl_timeout_msec = (int)timeout_msec;
1613}
1614
1615int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition,
1616 bool *pending)
1617{
1618 struct brcmf_info *drvr_priv = drvr->info;
1619 DECLARE_WAITQUEUE(wait, current);
1620 int timeout = brcmf_ioctl_timeout_msec;
1621
1622 /* Convert timeout in millsecond to jiffies */
1623 timeout = timeout * HZ / 1000;
1624
1625 /* Wait until control frame is available */
1626 add_wait_queue(&drvr_priv->ioctl_resp_wait, &wait);
1627 set_current_state(TASK_INTERRUPTIBLE);
1628
1629 while (!(*condition) && (!signal_pending(current) && timeout))
1630 timeout = schedule_timeout(timeout);
1631
1632 if (signal_pending(current))
1633 *pending = true;
1634
1635 set_current_state(TASK_RUNNING);
1636 remove_wait_queue(&drvr_priv->ioctl_resp_wait, &wait);
1637
1638 return timeout;
1639}
1640
1641int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr)
1642{
1643 struct brcmf_info *drvr_priv = drvr->info;
1644
1645 if (waitqueue_active(&drvr_priv->ioctl_resp_wait))
1646 wake_up_interruptible(&drvr_priv->ioctl_resp_wait);
1647
1648 return 0;
1649}
1650
1651static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata,
1652 struct brcmf_event_msg *event, void **data)
1653{
1654 int bcmerror = 0;
1655
1656 bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data);
1657 if (bcmerror != 0)
1658 return bcmerror;
1659
1660 if (drvr_priv->iflist[*ifidx]->net)
1661 brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->net,
1662 event, *data);
1663
1664 return bcmerror;
1665}
1666
1667int brcmf_netdev_reset(struct net_device *dev, u8 flag)
1668{
1669 struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev);
1670
1671 brcmf_bus_devreset(&drvr_priv->pub, flag);
1672
1673 return 1;
1674}
1675
1676static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv)
1677{
1678 return atomic_read(&drvr_priv->pend_8021x_cnt);
1679}
1680
1681#define MAX_WAIT_FOR_8021X_TX 10
1682
1683int brcmf_netdev_wait_pend8021x(struct net_device *dev)
1684{
1685 struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev);
1686 int timeout = 10 * HZ / 1000;
1687 int ntimes = MAX_WAIT_FOR_8021X_TX;
1688 int pend = brcmf_get_pend_8021x_cnt(drvr_priv);
1689
1690 while (ntimes && pend) {
1691 if (pend) {
1692 set_current_state(TASK_INTERRUPTIBLE);
1693 schedule_timeout(timeout);
1694 set_current_state(TASK_RUNNING);
1695 ntimes--;
1696 }
1697 pend = brcmf_get_pend_8021x_cnt(drvr_priv);
1698 }
1699 return pend;
1700}
1701
1702#ifdef BCMDBG
1703int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size)
1704{
1705 int ret = 0;
1706 struct file *fp;
1707 mm_segment_t old_fs;
1708 loff_t pos = 0;
1709
1710 /* change to KERNEL_DS address limit */
1711 old_fs = get_fs();
1712 set_fs(KERNEL_DS);
1713
1714 /* open file to write */
1715 fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
1716 if (!fp) {
1717 BRCMF_ERROR(("%s: open file error\n", __func__));
1718 ret = -1;
1719 goto exit;
1720 }
1721
1722 /* Write buf to file */
1723 fp->f_op->write(fp, buf, size, &pos);
1724
1725exit:
1726 /* free buf before return */
1727 kfree(buf);
1728 /* close file before return */
1729 if (fp)
1730 filp_close(fp, current->files);
1731 /* restore previous address limit */
1732 set_fs(old_fs);
1733
1734 return ret;
1735}
1736#endif /* BCMDBG */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h
new file mode 100644
index 00000000000..ff788b37afd
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h
@@ -0,0 +1,75 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMF_PROTO_H_
18#define _BRCMF_PROTO_H_
19
20#ifndef IOCTL_RESP_TIMEOUT
21#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */
22#endif
23
24#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT
25#define IOCTL_CHIP_ACTIVE_TIMEOUT 10 /* In milli second */
26#endif
27
28/*
29 * Exported from the brcmf protocol module (brcmf_cdc)
30 */
31
32/* Linkage, sets prot link and updates hdrlen in pub */
33extern int brcmf_proto_attach(struct brcmf_pub *drvr);
34
35/* Unlink, frees allocated protocol memory (including brcmf_proto) */
36extern void brcmf_proto_detach(struct brcmf_pub *drvr);
37
38/* Initialize protocol: sync w/dongle state.
39 * Sets dongle media info (iswl, drv_version, mac address).
40 */
41extern int brcmf_proto_init(struct brcmf_pub *drvr);
42
43/* Stop protocol: sync w/dongle state. */
44extern void brcmf_proto_stop(struct brcmf_pub *drvr);
45
46/* Add any protocol-specific data header.
47 * Caller must reserve prot_hdrlen prepend space.
48 */
49extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
50 struct sk_buff *txp);
51
52/* Remove any protocol-specific data header. */
53extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx,
54 struct sk_buff *rxp);
55
56/* Use protocol to issue ioctl to dongle */
57extern int brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx,
58 struct brcmf_ioctl *ioc, void *buf, int len);
59
60/* Add prot dump output to a buffer */
61extern void brcmf_proto_dump(struct brcmf_pub *drvr,
62 struct brcmu_strbuf *strbuf);
63
64/* Update local copy of dongle statistics */
65extern void brcmf_proto_dstats(struct brcmf_pub *drvr);
66
67extern int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc,
68 void *buf, uint buflen);
69
70extern int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr);
71
72extern int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx,
73 uint cmd, void *buf, uint len);
74
75#endif /* _BRCMF_PROTO_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
new file mode 100644
index 00000000000..7fa95b6213c
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
@@ -0,0 +1,6772 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/kthread.h>
20#include <linux/printk.h>
21#include <linux/pci_ids.h>
22#include <linux/netdevice.h>
23#include <linux/interrupt.h>
24#include <linux/sched.h>
25#include <linux/mmc/sdio.h>
26#include <linux/mmc/sdio_func.h>
27#include <linux/semaphore.h>
28#include <linux/firmware.h>
29#include <asm/unaligned.h>
30#include <defs.h>
31#include <brcmu_wifi.h>
32#include <brcmu_utils.h>
33#include <brcm_hw_ids.h>
34#include <soc.h>
35#include "sdio_host.h"
36
37/* register access macros */
38#ifndef __BIG_ENDIAN
39#ifndef __mips__
40#define R_REG(r, typ) \
41 brcmf_sdcard_reg_read(NULL, (r), sizeof(typ))
42#else /* __mips__ */
43#define R_REG(r, typ) \
44 ({ \
45 __typeof(*(r)) __osl_v; \
46 __asm__ __volatile__("sync"); \
47 __osl_v = brcmf_sdcard_reg_read(NULL, (r),\
48 sizeof(typ)); \
49 __asm__ __volatile__("sync"); \
50 __osl_v; \
51 })
52#endif /* __mips__ */
53
54#else /* __BIG_ENDIAN */
55#define R_REG(r, typ) \
56 brcmf_sdcard_reg_read(NULL, (r), sizeof(typ))
57#endif /* __BIG_ENDIAN */
58
59#define OR_REG(r, v, typ) \
60 brcmf_sdcard_reg_write(NULL, (r), sizeof(typ), R_REG(r, typ) | (v))
61
62#ifdef BCMDBG
63
64/* ARM trap handling */
65
66/* Trap types defined by ARM (see arminc.h) */
67
68#if defined(__ARM_ARCH_4T__)
69#define MAX_TRAP_TYPE (TR_FIQ + 1)
70#elif defined(__ARM_ARCH_7M__)
71#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS)
72#endif /* __ARM_ARCH_7M__ */
73
74/* The trap structure is defined here as offsets for assembly */
75#define TR_TYPE 0x00
76#define TR_EPC 0x04
77#define TR_CPSR 0x08
78#define TR_SPSR 0x0c
79#define TR_REGS 0x10
80#define TR_REG(n) (TR_REGS + (n) * 4)
81#define TR_SP TR_REG(13)
82#define TR_LR TR_REG(14)
83#define TR_PC TR_REG(15)
84
85#define TRAP_T_SIZE 80
86
87struct brcmf_trap {
88 u32 type;
89 u32 epc;
90 u32 cpsr;
91 u32 spsr;
92 u32 r0;
93 u32 r1;
94 u32 r2;
95 u32 r3;
96 u32 r4;
97 u32 r5;
98 u32 r6;
99 u32 r7;
100 u32 r8;
101 u32 r9;
102 u32 r10;
103 u32 r11;
104 u32 r12;
105 u32 r13;
106 u32 r14;
107 u32 pc;
108};
109
110#define CBUF_LEN (128)
111
112struct rte_log {
113 u32 buf; /* Can't be pointer on (64-bit) hosts */
114 uint buf_size;
115 uint idx;
116 char *_buf_compat; /* Redundant pointer for backward compat. */
117};
118
119struct rte_console {
120 /* Virtual UART
121 * When there is no UART (e.g. Quickturn),
122 * the host should write a complete
123 * input line directly into cbuf and then write
124 * the length into vcons_in.
125 * This may also be used when there is a real UART
126 * (at risk of conflicting with
127 * the real UART). vcons_out is currently unused.
128 */
129 volatile uint vcons_in;
130 volatile uint vcons_out;
131
132 /* Output (logging) buffer
133 * Console output is written to a ring buffer log_buf at index log_idx.
134 * The host may read the output when it sees log_idx advance.
135 * Output will be lost if the output wraps around faster than the host
136 * polls.
137 */
138 struct rte_log log;
139
140 /* Console input line buffer
141 * Characters are read one at a time into cbuf
142 * until <CR> is received, then
143 * the buffer is processed as a command line.
144 * Also used for virtual UART.
145 */
146 uint cbuf_idx;
147 char cbuf[CBUF_LEN];
148};
149
150#endif /* BCMDBG */
151#include <chipcommon.h>
152
153#include "dhd.h"
154#include "dhd_bus.h"
155#include "dhd_proto.h"
156#include "dhd_dbg.h"
157#include <bcmchip.h>
158
159#define TXQLEN 2048 /* bulk tx queue length */
160#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */
161#define TXLOW (TXHI - 256) /* turn off flow control below TXLOW */
162#define PRIOMASK 7
163
164#define TXRETRIES 2 /* # of retries for tx frames */
165
166#define BRCMF_RXBOUND 50 /* Default for max rx frames in
167 one scheduling */
168
169#define BRCMF_TXBOUND 20 /* Default for max tx frames in
170 one scheduling */
171
172#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
173
174#define MEMBLOCK 2048 /* Block size used for downloading
175 of dongle image */
176#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold
177 biggest possible glom */
178
179#ifndef BRCMF_FIRSTREAD
180#define BRCMF_FIRSTREAD 32
181#endif
182
183#if !ISPOWEROF2(BRCMF_FIRSTREAD)
184#error BRCMF_FIRSTREAD is not a power of 2!
185#endif
186
187/* SBSDIO_DEVICE_CTL */
188#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when
189 * receiving CMD53
190 */
191#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is
192 * synchronous to the sdio clock
193 */
194#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host
195 * except the chipActive (rev 8)
196 */
197#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put
198 * external pads in tri-state; requires
199 * sdio bus power cycle to clear (rev 9)
200 */
201#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */
202#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */
203#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */
204#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */
205
206/* SBSDIO_FUNC1_CHIPCLKCSR */
207#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */
208#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */
209#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */
210#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */
211#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */
212#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */
213#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */
214#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */
215
216#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
217#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
218#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
219#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
220#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \
221 (alponly ? 1 : SBSDIO_HTAV(regval)))
222/* direct(mapped) cis space */
223#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */
224#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */
225#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */
226
227#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple,
228 * link bytes
229 */
230
231/* intstatus */
232#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
233#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
234#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */
235#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */
236#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */
237#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */
238#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */
239#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */
240#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */
241#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */
242#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */
243#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */
244#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */
245#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */
246#define I_PC (1 << 10) /* descriptor error */
247#define I_PD (1 << 11) /* data error */
248#define I_DE (1 << 12) /* Descriptor protocol Error */
249#define I_RU (1 << 13) /* Receive descriptor Underflow */
250#define I_RO (1 << 14) /* Receive fifo Overflow */
251#define I_XU (1 << 15) /* Transmit fifo Underflow */
252#define I_RI (1 << 16) /* Receive Interrupt */
253#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */
254#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */
255#define I_XI (1 << 24) /* Transmit Interrupt */
256#define I_RF_TERM (1 << 25) /* Read Frame Terminate */
257#define I_WF_TERM (1 << 26) /* Write Frame Terminate */
258#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */
259#define I_SBINT (1 << 28) /* sbintstatus Interrupt */
260#define I_CHIPACTIVE (1 << 29) /* chip from doze to active state */
261#define I_SRESET (1 << 30) /* CCCR RES interrupt */
262#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */
263#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)
264#define I_DMA (I_RI | I_XI | I_ERRORS)
265
266/* corecontrol */
267#define CC_CISRDY (1 << 0) /* CIS Ready */
268#define CC_BPRESEN (1 << 1) /* CCCR RES signal */
269#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */
270#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation */
271#define CC_XMTDATAAVAIL_MODE (1 << 4)
272#define CC_XMTDATAAVAIL_CTRL (1 << 5)
273
274/* SDA_FRAMECTRL */
275#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */
276#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */
277#define SFC_CRC4WOOS (1 << 2) /* CRC error for write out of sync */
278#define SFC_ABORTALL (1 << 3) /* Abort all in-progress frames */
279
280/* HW frame tag */
281#define SDPCM_FRAMETAG_LEN 4 /* 2 bytes len, 2 bytes check val */
282
283/* Total length of frame header for dongle protocol */
284#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
285#ifdef SDTEST
286#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + BRCMF_SDALIGN)
287#else
288#define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN)
289#endif
290
291/*
292 * Software allocation of To SB Mailbox resources
293 */
294
295/* tosbmailbox bits corresponding to intstatus bits */
296#define SMB_NAK (1 << 0) /* Frame NAK */
297#define SMB_INT_ACK (1 << 1) /* Host Interrupt ACK */
298#define SMB_USE_OOB (1 << 2) /* Use OOB Wakeup */
299#define SMB_DEV_INT (1 << 3) /* Miscellaneous Interrupt */
300
301/* tosbmailboxdata */
302#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version */
303
304/*
305 * Software allocation of To Host Mailbox resources
306 */
307
308/* intstatus bits */
309#define I_HMB_FC_STATE I_HMB_SW0 /* Flow Control State */
310#define I_HMB_FC_CHANGE I_HMB_SW1 /* Flow Control State Changed */
311#define I_HMB_FRAME_IND I_HMB_SW2 /* Frame Indication */
312#define I_HMB_HOST_INT I_HMB_SW3 /* Miscellaneous Interrupt */
313
314/* tohostmailboxdata */
315#define HMB_DATA_NAKHANDLED 1 /* retransmit NAK'd frame */
316#define HMB_DATA_DEVREADY 2 /* talk to host after enable */
317#define HMB_DATA_FC 4 /* per prio flowcontrol update flag */
318#define HMB_DATA_FWREADY 8 /* fw ready for protocol activity */
319
320#define HMB_DATA_FCDATA_MASK 0xff000000
321#define HMB_DATA_FCDATA_SHIFT 24
322
323#define HMB_DATA_VERSION_MASK 0x00ff0000
324#define HMB_DATA_VERSION_SHIFT 16
325
326/*
327 * Software-defined protocol header
328 */
329
330/* Current protocol version */
331#define SDPCM_PROT_VERSION 4
332
333/* SW frame header */
334#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff)
335
336#define SDPCM_CHANNEL_MASK 0x00000f00
337#define SDPCM_CHANNEL_SHIFT 8
338#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f)
339
340#define SDPCM_NEXTLEN_OFFSET 2
341
342/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
343#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */
344#define SDPCM_DOFFSET_VALUE(p) (((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
345#define SDPCM_DOFFSET_MASK 0xff000000
346#define SDPCM_DOFFSET_SHIFT 24
347#define SDPCM_FCMASK_OFFSET 4 /* Flow control */
348#define SDPCM_FCMASK_VALUE(p) (((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
349#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */
350#define SDPCM_WINDOW_VALUE(p) (((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
351
352#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */
353
354/* logical channel numbers */
355#define SDPCM_CONTROL_CHANNEL 0 /* Control channel Id */
356#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */
357#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */
358#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets */
359#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */
360
361#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for 8bit frame seq */
362
363#define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80)
364
365/* For TEST_CHANNEL packets, define another 4-byte header */
366#define SDPCM_TEST_HDRLEN 4 /*
367 * Generally: Cmd(1), Ext(1), Len(2);
368 * Semantics of Ext byte depend on
369 * command. Len is current or requested
370 * frame length, not including test
371 * header; sent little-endian.
372 */
373#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext:pattern id. */
374#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext:pattern id. */
375#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext:pattern id. */
376#define SDPCM_TEST_BURST 0x04 /*
377 * Receiver to send a burst.
378 * Ext is a frame count
379 */
380#define SDPCM_TEST_SEND 0x05 /*
381 * Receiver sets send mode.
382 * Ext is boolean on/off
383 */
384
385/* Handy macro for filling in datagen packets with a pattern */
386#define SDPCM_TEST_FILL(byteno, id) ((u8)(id + byteno))
387
388/*
389 * Shared structure between dongle and the host.
390 * The structure contains pointers to trap or assert information.
391 */
392#define SDPCM_SHARED_VERSION 0x0002
393#define SDPCM_SHARED_VERSION_MASK 0x00FF
394#define SDPCM_SHARED_ASSERT_BUILT 0x0100
395#define SDPCM_SHARED_ASSERT 0x0200
396#define SDPCM_SHARED_TRAP 0x0400
397
398
399/* Space for header read, limit for data packets */
400#ifndef MAX_HDR_READ
401#define MAX_HDR_READ 32
402#endif
403#if !ISPOWEROF2(MAX_HDR_READ)
404#error MAX_HDR_READ is not a power of 2!
405#endif
406
407#define MAX_RX_DATASZ 2048
408
409/* Maximum milliseconds to wait for F2 to come up */
410#define BRCMF_WAIT_F2RDY 3000
411
412/* Bump up limit on waiting for HT to account for first startup;
413 * if the image is doing a CRC calculation before programming the PMU
414 * for HT availability, it could take a couple hundred ms more, so
415 * max out at a 1 second (1000000us).
416 */
417#if (PMU_MAX_TRANSITION_DLY <= 1000000)
418#undef PMU_MAX_TRANSITION_DLY
419#define PMU_MAX_TRANSITION_DLY 1000000
420#endif
421
422/* Value for ChipClockCSR during initial setup */
423#define BRCMF_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | \
424 SBSDIO_ALP_AVAIL_REQ)
425
426/* Flags for SDH calls */
427#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
428
429/* sbimstate */
430#define SBIM_IBE 0x20000 /* inbanderror */
431#define SBIM_TO 0x40000 /* timeout */
432#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */
433#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */
434
435/* sbtmstatelow */
436#define SBTML_RESET 0x0001 /* reset */
437#define SBTML_REJ_MASK 0x0006 /* reject field */
438#define SBTML_REJ 0x0002 /* reject */
439#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */
440
441#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */
442
443/* sbtmstatehigh */
444#define SBTMH_SERR 0x0001 /* serror */
445#define SBTMH_INT 0x0002 /* interrupt */
446#define SBTMH_BUSY 0x0004 /* busy */
447#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */
448
449#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */
450
451/* sbidlow */
452#define SBIDL_INIT 0x80 /* initiator */
453
454/* sbidhigh */
455#define SBIDH_RC_MASK 0x000f /* revision code */
456#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */
457#define SBIDH_RCE_SHIFT 8
458#define SBCOREREV(sbidh) \
459 ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK))
460#define SBIDH_CC_MASK 0x8ff0 /* core code */
461#define SBIDH_CC_SHIFT 4
462#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
463#define SBIDH_VC_SHIFT 16
464
465/*
466 * Conversion of 802.1D priority to precedence level
467 */
468#define PRIO2PREC(prio) \
469 (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \
470 ((prio^2)) : (prio))
471
472BRCMF_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep);
473
474/*
475 * Core reg address translation.
476 * Both macro's returns a 32 bits byte address on the backplane bus.
477 */
478#define CORE_CC_REG(base, field) (base + offsetof(chipcregs_t, field))
479#define CORE_BUS_REG(base, field) \
480 (base + offsetof(struct sdpcmd_regs, field))
481#define CORE_SB(base, field) \
482 (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
483
484/* core registers */
485struct sdpcmd_regs {
486 u32 corecontrol; /* 0x00, rev8 */
487 u32 corestatus; /* rev8 */
488 u32 PAD[1];
489 u32 biststatus; /* rev8 */
490
491 /* PCMCIA access */
492 u16 pcmciamesportaladdr; /* 0x010, rev8 */
493 u16 PAD[1];
494 u16 pcmciamesportalmask; /* rev8 */
495 u16 PAD[1];
496 u16 pcmciawrframebc; /* rev8 */
497 u16 PAD[1];
498 u16 pcmciaunderflowtimer; /* rev8 */
499 u16 PAD[1];
500
501 /* interrupt */
502 u32 intstatus; /* 0x020, rev8 */
503 u32 hostintmask; /* rev8 */
504 u32 intmask; /* rev8 */
505 u32 sbintstatus; /* rev8 */
506 u32 sbintmask; /* rev8 */
507 u32 funcintmask; /* rev4 */
508 u32 PAD[2];
509 u32 tosbmailbox; /* 0x040, rev8 */
510 u32 tohostmailbox; /* rev8 */
511 u32 tosbmailboxdata; /* rev8 */
512 u32 tohostmailboxdata; /* rev8 */
513
514 /* synchronized access to registers in SDIO clock domain */
515 u32 sdioaccess; /* 0x050, rev8 */
516 u32 PAD[3];
517
518 /* PCMCIA frame control */
519 u8 pcmciaframectrl; /* 0x060, rev8 */
520 u8 PAD[3];
521 u8 pcmciawatermark; /* rev8 */
522 u8 PAD[155];
523
524 /* interrupt batching control */
525 u32 intrcvlazy; /* 0x100, rev8 */
526 u32 PAD[3];
527
528 /* counters */
529 u32 cmd52rd; /* 0x110, rev8 */
530 u32 cmd52wr; /* rev8 */
531 u32 cmd53rd; /* rev8 */
532 u32 cmd53wr; /* rev8 */
533 u32 abort; /* rev8 */
534 u32 datacrcerror; /* rev8 */
535 u32 rdoutofsync; /* rev8 */
536 u32 wroutofsync; /* rev8 */
537 u32 writebusy; /* rev8 */
538 u32 readwait; /* rev8 */
539 u32 readterm; /* rev8 */
540 u32 writeterm; /* rev8 */
541 u32 PAD[40];
542 u32 clockctlstatus; /* rev8 */
543 u32 PAD[7];
544
545 u32 PAD[128]; /* DMA engines */
546
547 /* SDIO/PCMCIA CIS region */
548 char cis[512]; /* 0x400-0x5ff, rev6 */
549
550 /* PCMCIA function control registers */
551 char pcmciafcr[256]; /* 0x600-6ff, rev6 */
552 u16 PAD[55];
553
554 /* PCMCIA backplane access */
555 u16 backplanecsr; /* 0x76E, rev6 */
556 u16 backplaneaddr0; /* rev6 */
557 u16 backplaneaddr1; /* rev6 */
558 u16 backplaneaddr2; /* rev6 */
559 u16 backplaneaddr3; /* rev6 */
560 u16 backplanedata0; /* rev6 */
561 u16 backplanedata1; /* rev6 */
562 u16 backplanedata2; /* rev6 */
563 u16 backplanedata3; /* rev6 */
564 u16 PAD[31];
565
566 /* sprom "size" & "blank" info */
567 u16 spromstatus; /* 0x7BE, rev2 */
568 u32 PAD[464];
569
570 u16 PAD[0x80];
571};
572
573#ifdef BCMDBG
574/* Device console log buffer state */
575struct brcmf_console {
576 uint count; /* Poll interval msec counter */
577 uint log_addr; /* Log struct address (fixed) */
578 struct rte_log log; /* Log struct (host copy) */
579 uint bufsize; /* Size of log buffer */
580 u8 *buf; /* Log buffer (host copy) */
581 uint last; /* Last buffer read index */
582};
583#endif /* BCMDBG */
584
585struct sdpcm_shared {
586 u32 flags;
587 u32 trap_addr;
588 u32 assert_exp_addr;
589 u32 assert_file_addr;
590 u32 assert_line;
591 u32 console_addr; /* Address of struct rte_console */
592 u32 msgtrace_addr;
593 u8 tag[32];
594};
595
596
597/* misc chip info needed by some of the routines */
598struct chip_info {
599 u32 chip;
600 u32 chiprev;
601 u32 cccorebase;
602 u32 ccrev;
603 u32 cccaps;
604 u32 buscorebase; /* 32 bits backplane bus address */
605 u32 buscorerev;
606 u32 buscoretype;
607 u32 ramcorebase;
608 u32 armcorebase;
609 u32 pmurev;
610 u32 ramsize;
611};
612
613/* Private data for SDIO bus interaction */
614struct brcmf_bus {
615 struct brcmf_pub *drvr;
616
617 struct brcmf_sdio_card *card; /* Handle for sdio card calls */
618 struct chip_info *ci; /* Chip info struct */
619 char *vars; /* Variables (from CIS and/or other) */
620 uint varsz; /* Size of variables buffer */
621
622 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */
623 u32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */
624
625 u32 bus; /* gSPI or SDIO bus */
626 u32 hostintmask; /* Copy of Host Interrupt Mask */
627 u32 intstatus; /* Intstatus bits (events) pending */
628 bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */
629 bool fcstate; /* State of dongle flow-control */
630
631 u16 cl_devid; /* cached devid for brcmf_sdio_probe_attach() */
632
633 uint blocksize; /* Block size of SDIO transfers */
634 uint roundup; /* Max roundup limit */
635
636 struct pktq txq; /* Queue length used for flow-control */
637 u8 flowcontrol; /* per prio flow control bitmask */
638 u8 tx_seq; /* Transmit sequence number (next) */
639 u8 tx_max; /* Maximum transmit sequence allowed */
640
641 u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
642 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
643 u16 nextlen; /* Next Read Len from last header */
644 u8 rx_seq; /* Receive sequence number (expected) */
645 bool rxskip; /* Skip receive (awaiting NAK ACK) */
646
647 struct sk_buff *glomd; /* Packet containing glomming descriptor */
648 struct sk_buff *glom; /* Packet chain for glommed superframe */
649 uint glomerr; /* Glom packet read errors */
650
651 u8 *rxbuf; /* Buffer for receiving control packets */
652 uint rxblen; /* Allocated length of rxbuf */
653 u8 *rxctl; /* Aligned pointer into rxbuf */
654 u8 *databuf; /* Buffer for receiving big glom packet */
655 u8 *dataptr; /* Aligned pointer into databuf */
656 uint rxlen; /* Length of valid data in buffer */
657
658 u8 sdpcm_ver; /* Bus protocol reported by dongle */
659
660 bool intr; /* Use interrupts */
661 bool poll; /* Use polling */
662 bool ipend; /* Device interrupt is pending */
663 bool intdis; /* Interrupts disabled by isr */
664 uint intrcount; /* Count of device interrupt callbacks */
665 uint lastintrs; /* Count as of last watchdog timer */
666 uint spurious; /* Count of spurious interrupts */
667 uint pollrate; /* Ticks between device polls */
668 uint polltick; /* Tick counter */
669 uint pollcnt; /* Count of active polls */
670
671#ifdef BCMDBG
672 struct brcmf_console console; /* Console output polling support */
673 uint console_addr; /* Console address from shared struct */
674#endif /* BCMDBG */
675
676 uint regfails; /* Count of R_REG failures */
677
678 uint clkstate; /* State of sd and backplane clock(s) */
679 bool activity; /* Activity flag for clock down */
680 s32 idletime; /* Control for activity timeout */
681 s32 idlecount; /* Activity timeout counter */
682 s32 idleclock; /* How to set bus driver when idle */
683 s32 sd_rxchain;
684 bool use_rxchain; /* If brcmf should use PKT chains */
685 bool sleeping; /* Is SDIO bus sleeping? */
686 bool rxflow_mode; /* Rx flow control mode */
687 bool rxflow; /* Is rx flow control on */
688 bool alp_only; /* Don't use HT clock (ALP only) */
689/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
690 bool usebufpool;
691
692#ifdef SDTEST
693 /* external loopback */
694 bool ext_loop;
695 u8 loopid;
696
697 /* pktgen configuration */
698 uint pktgen_freq; /* Ticks between bursts */
699 uint pktgen_count; /* Packets to send each burst */
700 uint pktgen_print; /* Bursts between count displays */
701 uint pktgen_total; /* Stop after this many */
702 uint pktgen_minlen; /* Minimum packet data len */
703 uint pktgen_maxlen; /* Maximum packet data len */
704 uint pktgen_mode; /* Configured mode: tx, rx, or echo */
705 uint pktgen_stop; /* Number of tx failures causing stop */
706
707 /* active pktgen fields */
708 uint pktgen_tick; /* Tick counter for bursts */
709 uint pktgen_ptick; /* Burst counter for printing */
710 uint pktgen_sent; /* Number of test packets generated */
711 uint pktgen_rcvd; /* Number of test packets received */
712 uint pktgen_fail; /* Number of failed send attempts */
713 u16 pktgen_len; /* Length of next packet to send */
714#endif /* SDTEST */
715
716 /* Some additional counters */
717 uint tx_sderrs; /* Count of tx attempts with sd errors */
718 uint fcqueued; /* Tx packets that got queued */
719 uint rxrtx; /* Count of rtx requests (NAK to dongle) */
720 uint rx_toolong; /* Receive frames too long to receive */
721 uint rxc_errors; /* SDIO errors when reading control frames */
722 uint rx_hdrfail; /* SDIO errors on header reads */
723 uint rx_badhdr; /* Bad received headers (roosync?) */
724 uint rx_badseq; /* Mismatched rx sequence number */
725 uint fc_rcvd; /* Number of flow-control events received */
726 uint fc_xoff; /* Number which turned on flow-control */
727 uint fc_xon; /* Number which turned off flow-control */
728 uint rxglomfail; /* Failed deglom attempts */
729 uint rxglomframes; /* Number of glom frames (superframes) */
730 uint rxglompkts; /* Number of packets from glom frames */
731 uint f2rxhdrs; /* Number of header reads */
732 uint f2rxdata; /* Number of frame data reads */
733 uint f2txdata; /* Number of f2 frame writes */
734 uint f1regdata; /* Number of f1 register accesses */
735
736 u8 *ctrl_frame_buf;
737 u32 ctrl_frame_len;
738 bool ctrl_frame_stat;
739
740 spinlock_t txqlock;
741 wait_queue_head_t ctrl_wait;
742
743 struct timer_list timer;
744 struct completion watchdog_wait;
745 struct task_struct *watchdog_tsk;
746 bool wd_timer_valid;
747
748 struct tasklet_struct tasklet;
749 struct task_struct *dpc_tsk;
750 struct completion dpc_wait;
751
752 bool threads_only;
753 struct semaphore sdsem;
754 spinlock_t sdlock;
755
756 const char *fw_name;
757 const struct firmware *firmware;
758 const char *nv_name;
759 u32 fw_ptr;
760};
761
762struct sbconfig {
763 u32 PAD[2];
764 u32 sbipsflag; /* initiator port ocp slave flag */
765 u32 PAD[3];
766 u32 sbtpsflag; /* target port ocp slave flag */
767 u32 PAD[11];
768 u32 sbtmerrloga; /* (sonics >= 2.3) */
769 u32 PAD;
770 u32 sbtmerrlog; /* (sonics >= 2.3) */
771 u32 PAD[3];
772 u32 sbadmatch3; /* address match3 */
773 u32 PAD;
774 u32 sbadmatch2; /* address match2 */
775 u32 PAD;
776 u32 sbadmatch1; /* address match1 */
777 u32 PAD[7];
778 u32 sbimstate; /* initiator agent state */
779 u32 sbintvec; /* interrupt mask */
780 u32 sbtmstatelow; /* target state */
781 u32 sbtmstatehigh; /* target state */
782 u32 sbbwa0; /* bandwidth allocation table0 */
783 u32 PAD;
784 u32 sbimconfiglow; /* initiator configuration */
785 u32 sbimconfighigh; /* initiator configuration */
786 u32 sbadmatch0; /* address match0 */
787 u32 PAD;
788 u32 sbtmconfiglow; /* target configuration */
789 u32 sbtmconfighigh; /* target configuration */
790 u32 sbbconfig; /* broadcast configuration */
791 u32 PAD;
792 u32 sbbstate; /* broadcast state */
793 u32 PAD[3];
794 u32 sbactcnfg; /* activate configuration */
795 u32 PAD[3];
796 u32 sbflagst; /* current sbflags */
797 u32 PAD[3];
798 u32 sbidlow; /* identification */
799 u32 sbidhigh; /* identification */
800};
801
802/* clkstate */
803#define CLK_NONE 0
804#define CLK_SDONLY 1
805#define CLK_PENDING 2 /* Not used yet */
806#define CLK_AVAIL 3
807
808#define BRCMF_NOPMU(brcmf) (false)
809
810#ifdef BCMDBG
811static int qcount[NUMPRIO];
812static int tx_packets[NUMPRIO];
813#endif /* BCMDBG */
814
815/* Deferred transmit */
816uint brcmf_deferred_tx = 1;
817module_param(brcmf_deferred_tx, uint, 0);
818
819/* Watchdog thread priority, -1 to use kernel timer */
820int brcmf_watchdog_prio = 97;
821module_param(brcmf_watchdog_prio, int, 0);
822
823/* Watchdog interval */
824uint brcmf_watchdog_ms = 10;
825module_param(brcmf_watchdog_ms, uint, 0);
826
827/* DPC thread priority, -1 to use tasklet */
828int brcmf_dpc_prio = 98;
829module_param(brcmf_dpc_prio, int, 0);
830
831#ifdef BCMDBG
832/* Console poll interval */
833uint brcmf_console_ms;
834module_param(brcmf_console_ms, uint, 0);
835#endif /* BCMDBG */
836
837/* Tx/Rx bounds */
838uint brcmf_txbound;
839uint brcmf_rxbound;
840uint brcmf_txminmax;
841
842/* override the RAM size if possible */
843#define DONGLE_MIN_MEMSIZE (128 * 1024)
844int brcmf_dongle_memsize;
845
846static bool brcmf_alignctl;
847
848static bool sd1idle;
849
850static bool retrydata;
851#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata)
852
853static const uint watermark = 8;
854static const uint firstread = BRCMF_FIRSTREAD;
855
856/* Retry count for register access failures */
857static const uint retry_limit = 2;
858
859/* Force even SD lengths (some host controllers mess up on odd bytes) */
860static bool forcealign;
861
862#define ALIGNMENT 4
863
864#define PKTALIGN(_p, _len, _align) \
865 do { \
866 uint datalign; \
867 datalign = (unsigned long)((_p)->data); \
868 datalign = roundup(datalign, (_align)) - datalign; \
869 if (datalign) \
870 skb_pull((_p), datalign); \
871 __skb_trim((_p), (_len)); \
872 } while (0)
873
874/* Limit on rounding up frames */
875static const uint max_roundup = 512;
876
877/* Try doing readahead */
878static bool brcmf_readahead;
879
880/* To check if there's window offered */
881#define DATAOK(bus) \
882 (((u8)(bus->tx_max - bus->tx_seq) != 0) && \
883 (((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
884
885/*
886 * Reads a register in the SDIO hardware block. This block occupies a series of
887 * adresses on the 32 bit backplane bus.
888 */
889static void
890r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar)
891{
892 *retryvar = 0;
893 do {
894 *regvar = R_REG(bus->ci->buscorebase + reg_offset, u32);
895 } while (brcmf_sdcard_regfail(bus->card) &&
896 (++(*retryvar) <= retry_limit));
897 if (*retryvar) {
898 bus->regfails += (*retryvar-1);
899 if (*retryvar > retry_limit) {
900 BRCMF_ERROR(("FAILED READ %Xh\n", reg_offset));
901 *regvar = 0;
902 }
903 }
904}
905
906static void
907w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar)
908{
909 *retryvar = 0;
910 do {
911 brcmf_sdcard_reg_write(NULL, bus->ci->buscorebase + reg_offset,
912 sizeof(u32), regval);
913 } while (brcmf_sdcard_regfail(bus->card) &&
914 (++(*retryvar) <= retry_limit));
915 if (*retryvar) {
916 bus->regfails += (*retryvar-1);
917 if (*retryvar > retry_limit)
918 BRCMF_ERROR(("FAILED REGISTER WRITE"
919 " %Xh\n", reg_offset));
920 }
921}
922
923#define BRCMF_BUS SDIO_BUS
924
925#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
926
927#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
928
929#ifdef SDTEST
930static void brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, void *pkt, uint seq);
931static void brcmf_sdbrcm_sdtest_set(struct brcmf_bus *bus, bool start);
932#endif
933
934#ifdef BCMDBG
935static int brcmf_sdbrcm_bus_console_in(struct brcmf_pub *drvr,
936 unsigned char *msg, uint msglen);
937static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size);
938static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus);
939#endif /* BCMDBG */
940static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter);
941
942static void brcmf_sdbrcm_release(struct brcmf_bus *bus);
943static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus);
944static void brcmf_sdbrcm_disconnect(void *ptr);
945static bool brcmf_sdbrcm_chipmatch(u16 chipid);
946static bool brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, void *card,
947 u32 regsva, u16 devid);
948static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card);
949static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card);
950static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus);
951
952static uint brcmf_process_nvram_vars(char *varbuf, uint len);
953
954static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size);
955static int brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, u32 addr, uint fn,
956 uint flags, u8 *buf, uint nbytes,
957 struct sk_buff *pkt,
958 void (*complete)(void *handle, int status,
959 bool sync_waiting),
960 void *handle);
961
962static bool brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus, void *card);
963static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus);
964
965static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus);
966static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus);
967
968static void
969brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_card *card, u32 corebase);
970
971static int brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs);
972
973static void
974brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_card *card, u32 corebase);
975
976static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus,
977 u32 drivestrength);
978static void brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus);
979static void brcmf_sdbrcm_wait_for_event(struct brcmf_bus *bus, bool *lockvar);
980static void brcmf_sdbrcm_wait_event_wakeup(struct brcmf_bus *bus);
981static void brcmf_sdbrcm_watchdog(unsigned long data);
982static int brcmf_sdbrcm_watchdog_thread(void *data);
983static int brcmf_sdbrcm_dpc_thread(void *data);
984static void brcmf_sdbrcm_dpc_tasklet(unsigned long data);
985static void brcmf_sdbrcm_sched_dpc(struct brcmf_bus *bus);
986static void brcmf_sdbrcm_sdlock(struct brcmf_bus *bus);
987static void brcmf_sdbrcm_sdunlock(struct brcmf_bus *bus);
988static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus);
989
990/* Packet free applicable unconditionally for sdio and sdspi.
991 * Conditional if bufpool was present for gspi bus.
992 */
993static void brcmf_sdbrcm_pktfree2(struct brcmf_bus *bus, struct sk_buff *pkt)
994{
995 if ((bus->bus != SPI_BUS) || bus->usebufpool)
996 brcmu_pkt_buf_free_skb(pkt);
997}
998
999static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size)
1000{
1001 s32 min_size = DONGLE_MIN_MEMSIZE;
1002 /* Restrict the memsize to user specified limit */
1003 BRCMF_ERROR(("user: Restrict the dongle ram size to %d, min %d\n",
1004 brcmf_dongle_memsize, min_size));
1005 if ((brcmf_dongle_memsize > min_size) &&
1006 (brcmf_dongle_memsize < (s32) bus->orig_ramsize))
1007 bus->ramsize = brcmf_dongle_memsize;
1008}
1009
1010static int brcmf_sdbrcm_set_siaddr_window(struct brcmf_bus *bus, u32 address)
1011{
1012 int err = 0;
1013 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
1014 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
1015 if (!err)
1016 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1,
1017 SBSDIO_FUNC1_SBADDRMID,
1018 (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
1019 if (!err)
1020 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1,
1021 SBSDIO_FUNC1_SBADDRHIGH,
1022 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
1023 &err);
1024 return err;
1025}
1026
1027/* Turn backplane clock on or off */
1028static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok)
1029{
1030 int err;
1031 u8 clkctl, clkreq, devctl;
1032 struct brcmf_sdio_card *card;
1033
1034 BRCMF_TRACE(("%s: Enter\n", __func__));
1035
1036 clkctl = 0;
1037 card = bus->card;
1038
1039 if (on) {
1040 /* Request HT Avail */
1041 clkreq =
1042 bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
1043
1044 if ((bus->ci->chip == BCM4329_CHIP_ID)
1045 && (bus->ci->chiprev == 0))
1046 clkreq |= SBSDIO_FORCE_ALP;
1047
1048 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1049 SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
1050 if (err) {
1051 BRCMF_ERROR(("%s: HT Avail request error: %d\n",
1052 __func__, err));
1053 return -EBADE;
1054 }
1055
1056 if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID)
1057 && (bus->ci->buscorerev == 9))) {
1058 u32 dummy, retries;
1059 r_sdreg32(bus, &dummy,
1060 offsetof(struct sdpcmd_regs, clockctlstatus),
1061 &retries);
1062 }
1063
1064 /* Check current status */
1065 clkctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
1066 SBSDIO_FUNC1_CHIPCLKCSR, &err);
1067 if (err) {
1068 BRCMF_ERROR(("%s: HT Avail read error: %d\n",
1069 __func__, err));
1070 return -EBADE;
1071 }
1072
1073 /* Go to pending and await interrupt if appropriate */
1074 if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
1075 /* Allow only clock-available interrupt */
1076 devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
1077 SBSDIO_DEVICE_CTL, &err);
1078 if (err) {
1079 BRCMF_ERROR(("%s: Devctl error setting CA:"
1080 " %d\n", __func__, err));
1081 return -EBADE;
1082 }
1083
1084 devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
1085 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1086 SBSDIO_DEVICE_CTL, devctl, &err);
1087 BRCMF_INFO(("CLKCTL: set PENDING\n"));
1088 bus->clkstate = CLK_PENDING;
1089
1090 return 0;
1091 } else if (bus->clkstate == CLK_PENDING) {
1092 /* Cancel CA-only interrupt filter */
1093 devctl =
1094 brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
1095 SBSDIO_DEVICE_CTL, &err);
1096 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
1097 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1098 SBSDIO_DEVICE_CTL, devctl, &err);
1099 }
1100
1101 /* Otherwise, wait here (polling) for HT Avail */
1102 if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
1103 BRCMF_SPINWAIT_SLEEP(sdioh_spinwait_sleep,
1104 ((clkctl =
1105 brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
1106 SBSDIO_FUNC1_CHIPCLKCSR,
1107 &err)),
1108 !SBSDIO_CLKAV(clkctl, bus->alp_only)),
1109 PMU_MAX_TRANSITION_DLY);
1110 }
1111 if (err) {
1112 BRCMF_ERROR(("%s: HT Avail request error: %d\n",
1113 __func__, err));
1114 return -EBADE;
1115 }
1116 if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
1117 BRCMF_ERROR(("%s: HT Avail timeout (%d): "
1118 "clkctl 0x%02x\n", __func__,
1119 PMU_MAX_TRANSITION_DLY, clkctl));
1120 return -EBADE;
1121 }
1122
1123 /* Mark clock available */
1124 bus->clkstate = CLK_AVAIL;
1125 BRCMF_INFO(("CLKCTL: turned ON\n"));
1126
1127#if defined(BCMDBG)
1128 if (bus->alp_only != true) {
1129 if (SBSDIO_ALPONLY(clkctl)) {
1130 BRCMF_ERROR(("%s: HT Clock should be on.\n",
1131 __func__));
1132 }
1133 }
1134#endif /* defined (BCMDBG) */
1135
1136 bus->activity = true;
1137 } else {
1138 clkreq = 0;
1139
1140 if (bus->clkstate == CLK_PENDING) {
1141 /* Cancel CA-only interrupt filter */
1142 devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
1143 SBSDIO_DEVICE_CTL, &err);
1144 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
1145 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1146 SBSDIO_DEVICE_CTL, devctl, &err);
1147 }
1148
1149 bus->clkstate = CLK_SDONLY;
1150 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1151 SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
1152 BRCMF_INFO(("CLKCTL: turned OFF\n"));
1153 if (err) {
1154 BRCMF_ERROR(("%s: Failed access turning clock off:"
1155 " %d\n", __func__, err));
1156 return -EBADE;
1157 }
1158 }
1159 return 0;
1160}
1161
1162/* Change idle/active SD state */
1163static int brcmf_sdbrcm_sdclk(struct brcmf_bus *bus, bool on)
1164{
1165 BRCMF_TRACE(("%s: Enter\n", __func__));
1166
1167 if (on)
1168 bus->clkstate = CLK_SDONLY;
1169 else
1170 bus->clkstate = CLK_NONE;
1171
1172 return 0;
1173}
1174
1175/* Transition SD and backplane clock readiness */
1176static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok)
1177{
1178#ifdef BCMDBG
1179 uint oldstate = bus->clkstate;
1180#endif /* BCMDBG */
1181
1182 BRCMF_TRACE(("%s: Enter\n", __func__));
1183
1184 /* Early exit if we're already there */
1185 if (bus->clkstate == target) {
1186 if (target == CLK_AVAIL) {
1187 brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms);
1188 bus->activity = true;
1189 }
1190 return 0;
1191 }
1192
1193 switch (target) {
1194 case CLK_AVAIL:
1195 /* Make sure SD clock is available */
1196 if (bus->clkstate == CLK_NONE)
1197 brcmf_sdbrcm_sdclk(bus, true);
1198 /* Now request HT Avail on the backplane */
1199 brcmf_sdbrcm_htclk(bus, true, pendok);
1200 brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms);
1201 bus->activity = true;
1202 break;
1203
1204 case CLK_SDONLY:
1205 /* Remove HT request, or bring up SD clock */
1206 if (bus->clkstate == CLK_NONE)
1207 brcmf_sdbrcm_sdclk(bus, true);
1208 else if (bus->clkstate == CLK_AVAIL)
1209 brcmf_sdbrcm_htclk(bus, false, false);
1210 else
1211 BRCMF_ERROR(("brcmf_sdbrcm_clkctl: request for %d -> %d"
1212 "\n", bus->clkstate, target));
1213 brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms);
1214 break;
1215
1216 case CLK_NONE:
1217 /* Make sure to remove HT request */
1218 if (bus->clkstate == CLK_AVAIL)
1219 brcmf_sdbrcm_htclk(bus, false, false);
1220 /* Now remove the SD clock */
1221 brcmf_sdbrcm_sdclk(bus, false);
1222 brcmf_sdbrcm_wd_timer(bus, 0);
1223 break;
1224 }
1225#ifdef BCMDBG
1226 BRCMF_INFO(("brcmf_sdbrcm_clkctl: %d -> %d\n",
1227 oldstate, bus->clkstate));
1228#endif /* BCMDBG */
1229
1230 return 0;
1231}
1232
1233int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep)
1234{
1235 struct brcmf_sdio_card *card = bus->card;
1236 uint retries = 0;
1237
1238 BRCMF_INFO(("brcmf_sdbrcm_bussleep: request %s (currently %s)\n",
1239 (sleep ? "SLEEP" : "WAKE"),
1240 (bus->sleeping ? "SLEEP" : "WAKE")));
1241
1242 /* Done if we're already in the requested state */
1243 if (sleep == bus->sleeping)
1244 return 0;
1245
1246 /* Going to sleep: set the alarm and turn off the lights... */
1247 if (sleep) {
1248 /* Don't sleep if something is pending */
1249 if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
1250 return -EBUSY;
1251
1252 /* Disable SDIO interrupts (no longer interested) */
1253 brcmf_sdcard_intr_disable(bus->card);
1254
1255 /* Make sure the controller has the bus up */
1256 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
1257
1258 /* Tell device to start using OOB wakeup */
1259 w_sdreg32(bus, SMB_USE_OOB,
1260 offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
1261 if (retries > retry_limit)
1262 BRCMF_ERROR(("CANNOT SIGNAL CHIP, "
1263 "WILL NOT WAKE UP!!\n"));
1264
1265 /* Turn off our contribution to the HT clock request */
1266 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
1267
1268 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1269 SBSDIO_FUNC1_CHIPCLKCSR,
1270 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
1271
1272 /* Isolate the bus */
1273 if (bus->ci->chip != BCM4329_CHIP_ID
1274 && bus->ci->chip != BCM4319_CHIP_ID) {
1275 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1276 SBSDIO_DEVICE_CTL,
1277 SBSDIO_DEVCTL_PADS_ISO, NULL);
1278 }
1279
1280 /* Change state */
1281 bus->sleeping = true;
1282
1283 } else {
1284 /* Waking up: bus power up is ok, set local state */
1285
1286 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1287 SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
1288
1289 /* Force pad isolation off if possible
1290 (in case power never toggled) */
1291 if ((bus->ci->buscoretype == PCMCIA_CORE_ID)
1292 && (bus->ci->buscorerev >= 10))
1293 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1294 SBSDIO_DEVICE_CTL, 0, NULL);
1295
1296 /* Make sure the controller has the bus up */
1297 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
1298
1299 /* Send misc interrupt to indicate OOB not needed */
1300 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata),
1301 &retries);
1302 if (retries <= retry_limit)
1303 w_sdreg32(bus, SMB_DEV_INT,
1304 offsetof(struct sdpcmd_regs, tosbmailbox),
1305 &retries);
1306
1307 if (retries > retry_limit)
1308 BRCMF_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"));
1309
1310 /* Make sure we have SD bus access */
1311 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
1312
1313 /* Change state */
1314 bus->sleeping = false;
1315
1316 /* Enable interrupts again */
1317 if (bus->intr && (bus->drvr->busstate == BRCMF_BUS_DATA)) {
1318 bus->intdis = false;
1319 brcmf_sdcard_intr_enable(bus->card);
1320 }
1321 }
1322
1323 return 0;
1324}
1325
1326#define BUS_WAKE(bus) \
1327 do { \
1328 if ((bus)->sleeping) \
1329 brcmf_sdbrcm_bussleep((bus), false); \
1330 } while (0);
1331
1332/* Writes a HW/SW header into the packet and sends it. */
1333/* Assumes: (a) header space already there, (b) caller holds lock */
1334static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt, uint chan,
1335 bool free_pkt)
1336{
1337 int ret;
1338 u8 *frame;
1339 u16 len, pad = 0;
1340 u32 swheader;
1341 uint retries = 0;
1342 struct brcmf_sdio_card *card;
1343 struct sk_buff *new;
1344 int i;
1345
1346 BRCMF_TRACE(("%s: Enter\n", __func__));
1347
1348 card = bus->card;
1349
1350 if (bus->drvr->dongle_reset) {
1351 ret = -EPERM;
1352 goto done;
1353 }
1354
1355 frame = (u8 *) (pkt->data);
1356
1357 /* Add alignment padding, allocate new packet if needed */
1358 pad = ((unsigned long)frame % BRCMF_SDALIGN);
1359 if (pad) {
1360 if (skb_headroom(pkt) < pad) {
1361 BRCMF_INFO(("%s: insufficient headroom %d for %d pad\n",
1362 __func__, skb_headroom(pkt), pad));
1363 bus->drvr->tx_realloc++;
1364 new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN);
1365 if (!new) {
1366 BRCMF_ERROR(("%s: couldn't allocate new "
1367 "%d-byte packet\n", __func__,
1368 pkt->len + BRCMF_SDALIGN));
1369 ret = -ENOMEM;
1370 goto done;
1371 }
1372
1373 PKTALIGN(new, pkt->len, BRCMF_SDALIGN);
1374 memcpy(new->data, pkt->data, pkt->len);
1375 if (free_pkt)
1376 brcmu_pkt_buf_free_skb(pkt);
1377 /* free the pkt if canned one is not used */
1378 free_pkt = true;
1379 pkt = new;
1380 frame = (u8 *) (pkt->data);
1381 /* precondition: (frame % BRCMF_SDALIGN) == 0) */
1382 pad = 0;
1383 } else {
1384 skb_push(pkt, pad);
1385 frame = (u8 *) (pkt->data);
1386 /* precondition: pad + SDPCM_HDRLEN <= pkt->len */
1387 memset(frame, 0, pad + SDPCM_HDRLEN);
1388 }
1389 }
1390 /* precondition: pad < BRCMF_SDALIGN */
1391
1392 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
1393 len = (u16) (pkt->len);
1394 *(u16 *) frame = cpu_to_le16(len);
1395 *(((u16 *) frame) + 1) = cpu_to_le16(~len);
1396
1397 /* Software tag: channel, sequence number, data offset */
1398 swheader =
1399 ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
1400 (((pad +
1401 SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
1402
1403 put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
1404 put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
1405
1406#ifdef BCMDBG
1407 tx_packets[pkt->priority]++;
1408 if (BRCMF_BYTES_ON() &&
1409 (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
1410 (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
1411 printk(KERN_DEBUG "Tx Frame:\n");
1412 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len);
1413 } else if (BRCMF_HDRS_ON()) {
1414 printk(KERN_DEBUG "TxHdr:\n");
1415 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1416 frame, min_t(u16, len, 16));
1417 }
1418#endif
1419
1420 /* Raise len to next SDIO block to eliminate tail command */
1421 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
1422 u16 pad = bus->blocksize - (len % bus->blocksize);
1423 if ((pad <= bus->roundup) && (pad < bus->blocksize))
1424 len += pad;
1425 } else if (len % BRCMF_SDALIGN) {
1426 len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
1427 }
1428
1429 /* Some controllers have trouble with odd bytes -- round to even */
1430 if (forcealign && (len & (ALIGNMENT - 1))) {
1431 len = roundup(len, ALIGNMENT);
1432 }
1433
1434 do {
1435 ret = brcmf_sdbrcm_send_buf(bus, brcmf_sdcard_cur_sbwad(card),
1436 SDIO_FUNC_2, F2SYNC, frame, len, pkt, NULL, NULL);
1437 bus->f2txdata++;
1438
1439 if (ret < 0) {
1440 /* On failure, abort the command
1441 and terminate the frame */
1442 BRCMF_INFO(("%s: sdio error %d, abort command and "
1443 "terminate frame.\n", __func__, ret));
1444 bus->tx_sderrs++;
1445
1446 brcmf_sdcard_abort(card, SDIO_FUNC_2);
1447 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1448 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
1449 NULL);
1450 bus->f1regdata++;
1451
1452 for (i = 0; i < 3; i++) {
1453 u8 hi, lo;
1454 hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
1455 SBSDIO_FUNC1_WFRAMEBCHI,
1456 NULL);
1457 lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
1458 SBSDIO_FUNC1_WFRAMEBCLO,
1459 NULL);
1460 bus->f1regdata += 2;
1461 if ((hi == 0) && (lo == 0))
1462 break;
1463 }
1464
1465 }
1466 if (ret == 0)
1467 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
1468
1469 } while ((ret < 0) && retrydata && retries++ < TXRETRIES);
1470
1471done:
1472 /* restore pkt buffer pointer before calling tx complete routine */
1473 skb_pull(pkt, SDPCM_HDRLEN + pad);
1474 brcmf_sdbrcm_sdunlock(bus);
1475 brcmf_txcomplete(bus->drvr, pkt, ret != 0);
1476 brcmf_sdbrcm_sdlock(bus);
1477
1478 if (free_pkt)
1479 brcmu_pkt_buf_free_skb(pkt);
1480
1481 return ret;
1482}
1483
1484int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *pkt)
1485{
1486 int ret = -EBADE;
1487 uint datalen, prec;
1488
1489 BRCMF_TRACE(("%s: Enter\n", __func__));
1490
1491 datalen = pkt->len;
1492
1493#ifdef SDTEST
1494 /* Push the test header if doing loopback */
1495 if (bus->ext_loop) {
1496 u8 *data;
1497 skb_push(pkt, SDPCM_TEST_HDRLEN);
1498 data = pkt->data;
1499 *data++ = SDPCM_TEST_ECHOREQ;
1500 *data++ = (u8) bus->loopid++;
1501 *data++ = (datalen >> 0);
1502 *data++ = (datalen >> 8);
1503 datalen += SDPCM_TEST_HDRLEN;
1504 }
1505#endif /* SDTEST */
1506
1507 /* Add space for the header */
1508 skb_push(pkt, SDPCM_HDRLEN);
1509 /* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */
1510
1511 prec = PRIO2PREC((pkt->priority & PRIOMASK));
1512
1513 /* Check for existing queue, current flow-control,
1514 pending event, or pending clock */
1515 if (brcmf_deferred_tx || bus->fcstate || pktq_len(&bus->txq)
1516 || bus->dpc_sched || (!DATAOK(bus))
1517 || (bus->flowcontrol & NBITVAL(prec))
1518 || (bus->clkstate != CLK_AVAIL)) {
1519 BRCMF_TRACE(("%s: deferring pktq len %d\n", __func__,
1520 pktq_len(&bus->txq)));
1521 bus->fcqueued++;
1522
1523 /* Priority based enq */
1524 spin_lock_bh(&bus->txqlock);
1525 if (brcmf_c_prec_enq(bus->drvr, &bus->txq, pkt, prec) == false) {
1526 skb_pull(pkt, SDPCM_HDRLEN);
1527 brcmf_txcomplete(bus->drvr, pkt, false);
1528 brcmu_pkt_buf_free_skb(pkt);
1529 BRCMF_ERROR(("%s: out of bus->txq !!!\n", __func__));
1530 ret = -ENOSR;
1531 } else {
1532 ret = 0;
1533 }
1534 spin_unlock_bh(&bus->txqlock);
1535
1536 if (pktq_len(&bus->txq) >= TXHI)
1537 brcmf_txflowcontrol(bus->drvr, 0, ON);
1538
1539#ifdef BCMDBG
1540 if (pktq_plen(&bus->txq, prec) > qcount[prec])
1541 qcount[prec] = pktq_plen(&bus->txq, prec);
1542#endif
1543 /* Schedule DPC if needed to send queued packet(s) */
1544 if (brcmf_deferred_tx && !bus->dpc_sched) {
1545 bus->dpc_sched = true;
1546 brcmf_sdbrcm_sched_dpc(bus);
1547 }
1548 } else {
1549 /* Lock: we're about to use shared data/code (and SDIO) */
1550 brcmf_sdbrcm_sdlock(bus);
1551
1552 /* Otherwise, send it now */
1553 BUS_WAKE(bus);
1554 /* Make sure back plane ht clk is on, no pending allowed */
1555 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true);
1556
1557#ifndef SDTEST
1558 BRCMF_TRACE(("%s: calling txpkt\n", __func__));
1559 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
1560#else
1561 ret = brcmf_sdbrcm_txpkt(bus, pkt,
1562 (bus->ext_loop ? SDPCM_TEST_CHANNEL :
1563 SDPCM_DATA_CHANNEL), true);
1564#endif
1565 if (ret)
1566 bus->drvr->tx_errors++;
1567 else
1568 bus->drvr->dstats.tx_bytes += datalen;
1569
1570 if (bus->idletime == BRCMF_IDLE_IMMEDIATE &&
1571 !bus->dpc_sched) {
1572 bus->activity = false;
1573 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
1574 }
1575
1576 brcmf_sdbrcm_sdunlock(bus);
1577 }
1578
1579 return ret;
1580}
1581
1582static uint brcmf_sdbrcm_sendfromq(struct brcmf_bus *bus, uint maxframes)
1583{
1584 struct sk_buff *pkt;
1585 u32 intstatus = 0;
1586 uint retries = 0;
1587 int ret = 0, prec_out;
1588 uint cnt = 0;
1589 uint datalen;
1590 u8 tx_prec_map;
1591
1592 struct brcmf_pub *drvr = bus->drvr;
1593
1594 BRCMF_TRACE(("%s: Enter\n", __func__));
1595
1596 tx_prec_map = ~bus->flowcontrol;
1597
1598 /* Send frames until the limit or some other event */
1599 for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) {
1600 spin_lock_bh(&bus->txqlock);
1601 pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
1602 if (pkt == NULL) {
1603 spin_unlock_bh(&bus->txqlock);
1604 break;
1605 }
1606 spin_unlock_bh(&bus->txqlock);
1607 datalen = pkt->len - SDPCM_HDRLEN;
1608
1609#ifndef SDTEST
1610 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
1611#else
1612 ret = brcmf_sdbrcm_txpkt(bus, pkt,
1613 (bus->ext_loop ? SDPCM_TEST_CHANNEL :
1614 SDPCM_DATA_CHANNEL), true);
1615#endif
1616 if (ret)
1617 bus->drvr->tx_errors++;
1618 else
1619 bus->drvr->dstats.tx_bytes += datalen;
1620
1621 /* In poll mode, need to check for other events */
1622 if (!bus->intr && cnt) {
1623 /* Check device status, signal pending interrupt */
1624 r_sdreg32(bus, &intstatus,
1625 offsetof(struct sdpcmd_regs, intstatus),
1626 &retries);
1627 bus->f2txdata++;
1628 if (brcmf_sdcard_regfail(bus->card))
1629 break;
1630 if (intstatus & bus->hostintmask)
1631 bus->ipend = true;
1632 }
1633 }
1634
1635 /* Deflow-control stack if needed */
1636 if (drvr->up && (drvr->busstate == BRCMF_BUS_DATA) &&
1637 drvr->txoff && (pktq_len(&bus->txq) < TXLOW))
1638 brcmf_txflowcontrol(drvr, 0, OFF);
1639
1640 return cnt;
1641}
1642
1643int
1644brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen)
1645{
1646 u8 *frame;
1647 u16 len;
1648 u32 swheader;
1649 uint retries = 0;
1650 struct brcmf_sdio_card *card = bus->card;
1651 u8 doff = 0;
1652 int ret = -1;
1653 int i;
1654
1655 BRCMF_TRACE(("%s: Enter\n", __func__));
1656
1657 if (bus->drvr->dongle_reset)
1658 return -EIO;
1659
1660 /* Back the pointer to make a room for bus header */
1661 frame = msg - SDPCM_HDRLEN;
1662 len = (msglen += SDPCM_HDRLEN);
1663
1664 /* Add alignment padding (optional for ctl frames) */
1665 if (brcmf_alignctl) {
1666 doff = ((unsigned long)frame % BRCMF_SDALIGN);
1667 if (doff) {
1668 frame -= doff;
1669 len += doff;
1670 msglen += doff;
1671 memset(frame, 0, doff + SDPCM_HDRLEN);
1672 }
1673 /* precondition: doff < BRCMF_SDALIGN */
1674 }
1675 doff += SDPCM_HDRLEN;
1676
1677 /* Round send length to next SDIO block */
1678 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
1679 u16 pad = bus->blocksize - (len % bus->blocksize);
1680 if ((pad <= bus->roundup) && (pad < bus->blocksize))
1681 len += pad;
1682 } else if (len % BRCMF_SDALIGN) {
1683 len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
1684 }
1685
1686 /* Satisfy length-alignment requirements */
1687 if (forcealign && (len & (ALIGNMENT - 1)))
1688 len = roundup(len, ALIGNMENT);
1689
1690 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
1691
1692 /* Need to lock here to protect txseq and SDIO tx calls */
1693 brcmf_sdbrcm_sdlock(bus);
1694
1695 BUS_WAKE(bus);
1696
1697 /* Make sure backplane clock is on */
1698 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
1699
1700 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
1701 *(u16 *) frame = cpu_to_le16((u16) msglen);
1702 *(((u16 *) frame) + 1) = cpu_to_le16(~msglen);
1703
1704 /* Software tag: channel, sequence number, data offset */
1705 swheader =
1706 ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
1707 SDPCM_CHANNEL_MASK)
1708 | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
1709 SDPCM_DOFFSET_MASK);
1710 put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
1711 put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
1712
1713 if (!DATAOK(bus)) {
1714 BRCMF_INFO(("%s: No bus credit bus->tx_max %d,"
1715 " bus->tx_seq %d\n", __func__,
1716 bus->tx_max, bus->tx_seq));
1717 bus->ctrl_frame_stat = true;
1718 /* Send from dpc */
1719 bus->ctrl_frame_buf = frame;
1720 bus->ctrl_frame_len = len;
1721
1722 brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat);
1723
1724 if (bus->ctrl_frame_stat == false) {
1725 BRCMF_INFO(("%s: ctrl_frame_stat == false\n",
1726 __func__));
1727 ret = 0;
1728 } else {
1729 BRCMF_INFO(("%s: ctrl_frame_stat == true\n", __func__));
1730 ret = -1;
1731 }
1732 }
1733
1734 if (ret == -1) {
1735#ifdef BCMDBG
1736 if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
1737 printk(KERN_DEBUG "Tx Frame:\n");
1738 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1739 frame, len);
1740 } else if (BRCMF_HDRS_ON()) {
1741 printk(KERN_DEBUG "TxHdr:\n");
1742 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
1743 frame, min_t(u16, len, 16));
1744 }
1745#endif
1746
1747 do {
1748 bus->ctrl_frame_stat = false;
1749 ret = brcmf_sdbrcm_send_buf(bus,
1750 brcmf_sdcard_cur_sbwad(card), SDIO_FUNC_2,
1751 F2SYNC, frame, len, NULL, NULL, NULL);
1752
1753 if (ret < 0) {
1754 /* On failure, abort the command and
1755 terminate the frame */
1756 BRCMF_INFO(("%s: sdio error %d, abort command "
1757 "and terminate frame.\n",
1758 __func__, ret));
1759 bus->tx_sderrs++;
1760
1761 brcmf_sdcard_abort(card, SDIO_FUNC_2);
1762
1763 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
1764 SBSDIO_FUNC1_FRAMECTRL,
1765 SFC_WF_TERM, NULL);
1766 bus->f1regdata++;
1767
1768 for (i = 0; i < 3; i++) {
1769 u8 hi, lo;
1770 hi = brcmf_sdcard_cfg_read(card,
1771 SDIO_FUNC_1,
1772 SBSDIO_FUNC1_WFRAMEBCHI,
1773 NULL);
1774 lo = brcmf_sdcard_cfg_read(card,
1775 SDIO_FUNC_1,
1776 SBSDIO_FUNC1_WFRAMEBCLO,
1777 NULL);
1778 bus->f1regdata += 2;
1779 if ((hi == 0) && (lo == 0))
1780 break;
1781 }
1782
1783 }
1784 if (ret == 0) {
1785 bus->tx_seq =
1786 (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
1787 }
1788 } while ((ret < 0) && retries++ < TXRETRIES);
1789 }
1790
1791 if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
1792 bus->activity = false;
1793 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
1794 }
1795
1796 brcmf_sdbrcm_sdunlock(bus);
1797
1798 if (ret)
1799 bus->drvr->tx_ctlerrs++;
1800 else
1801 bus->drvr->tx_ctlpkts++;
1802
1803 return ret ? -EIO : 0;
1804}
1805
1806int brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen)
1807{
1808 int timeleft;
1809 uint rxlen = 0;
1810 bool pending;
1811
1812 BRCMF_TRACE(("%s: Enter\n", __func__));
1813
1814 if (bus->drvr->dongle_reset)
1815 return -EIO;
1816
1817 /* Wait until control frame is available */
1818 timeleft = brcmf_os_ioctl_resp_wait(bus->drvr, &bus->rxlen, &pending);
1819
1820 brcmf_sdbrcm_sdlock(bus);
1821 rxlen = bus->rxlen;
1822 memcpy(msg, bus->rxctl, min(msglen, rxlen));
1823 bus->rxlen = 0;
1824 brcmf_sdbrcm_sdunlock(bus);
1825
1826 if (rxlen) {
1827 BRCMF_CTL(("%s: resumed on rxctl frame, got %d expected %d\n",
1828 __func__, rxlen, msglen));
1829 } else if (timeleft == 0) {
1830 BRCMF_ERROR(("%s: resumed on timeout\n", __func__));
1831#ifdef BCMDBG
1832 brcmf_sdbrcm_sdlock(bus);
1833 brcmf_sdbrcm_checkdied(bus, NULL, 0);
1834 brcmf_sdbrcm_sdunlock(bus);
1835#endif /* BCMDBG */
1836 } else if (pending == true) {
1837 BRCMF_CTL(("%s: cancelled\n", __func__));
1838 return -ERESTARTSYS;
1839 } else {
1840 BRCMF_CTL(("%s: resumed for unknown reason?\n", __func__));
1841#ifdef BCMDBG
1842 brcmf_sdbrcm_sdlock(bus);
1843 brcmf_sdbrcm_checkdied(bus, NULL, 0);
1844 brcmf_sdbrcm_sdunlock(bus);
1845#endif /* BCMDBG */
1846 }
1847
1848 if (rxlen)
1849 bus->drvr->rx_ctlpkts++;
1850 else
1851 bus->drvr->rx_ctlerrs++;
1852
1853 return rxlen ? (int)rxlen : -ETIMEDOUT;
1854}
1855
1856/* IOVar table */
1857enum {
1858 IOV_INTR = 1,
1859 IOV_POLLRATE,
1860 IOV_SDREG,
1861 IOV_SBREG,
1862 IOV_SDCIS,
1863 IOV_MEMBYTES,
1864 IOV_MEMSIZE,
1865#ifdef BCMDBG
1866 IOV_CHECKDIED,
1867 IOV_CONS,
1868 IOV_DCONSOLE_POLL,
1869#endif
1870 IOV_DOWNLOAD,
1871 IOV_FORCEEVEN,
1872 IOV_SDIOD_DRIVE,
1873 IOV_READAHEAD,
1874 IOV_SDRXCHAIN,
1875 IOV_ALIGNCTL,
1876 IOV_SDALIGN,
1877 IOV_DEVRESET,
1878 IOV_CPU,
1879#ifdef SDTEST
1880 IOV_PKTGEN,
1881 IOV_EXTLOOP,
1882#endif /* SDTEST */
1883 IOV_SPROM,
1884 IOV_TXBOUND,
1885 IOV_RXBOUND,
1886 IOV_TXMINMAX,
1887 IOV_IDLETIME,
1888 IOV_IDLECLOCK,
1889 IOV_SD1IDLE,
1890 IOV_SLEEP,
1891 IOV_WDTICK,
1892 IOV_VARS
1893};
1894
1895const struct brcmu_iovar brcmf_sdio_iovars[] = {
1896 {"intr", IOV_INTR, 0, IOVT_BOOL, 0},
1897 {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0},
1898 {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0},
1899 {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0},
1900 {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0},
1901 {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0},
1902 {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int)},
1903 {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0},
1904 {"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0},
1905 {"vars", IOV_VARS, 0, IOVT_BUFFER, 0},
1906 {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0},
1907 {"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0},
1908 {"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0},
1909 {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0},
1910 {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0},
1911 {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0},
1912 {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0},
1913#ifdef BCMDBG
1914 {"cons", IOV_CONS, 0, IOVT_BUFFER, 0}
1915 ,
1916 {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0}
1917 ,
1918 {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)}
1919 ,
1920 {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)}
1921 ,
1922 {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, BRCMF_IOCTL_MAXLEN}
1923 ,
1924 {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0}
1925 ,
1926 {"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0}
1927 ,
1928 {"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0}
1929 ,
1930 {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0}
1931 ,
1932 {"cpu", IOV_CPU, 0, IOVT_BOOL, 0}
1933 ,
1934 {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0}
1935 ,
1936#endif /* BCMDBG */
1937#ifdef SDTEST
1938 {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0}
1939 ,
1940 {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(struct brcmf_pktgen)}
1941 ,
1942#endif /* SDTEST */
1943
1944 {NULL, 0, 0, 0, 0}
1945};
1946
1947static void
1948brcmf_dump_pct(struct brcmu_strbuf *strbuf, char *desc, uint num, uint div)
1949{
1950 uint q1, q2;
1951
1952 if (!div) {
1953 brcmu_bprintf(strbuf, "%s N/A", desc);
1954 } else {
1955 q1 = num / div;
1956 q2 = (100 * (num - (q1 * div))) / div;
1957 brcmu_bprintf(strbuf, "%s %d.%02d", desc, q1, q2);
1958 }
1959}
1960
1961void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf)
1962{
1963 struct brcmf_bus *bus = drvr->bus;
1964
1965 brcmu_bprintf(strbuf, "Bus SDIO structure:\n");
1966 brcmu_bprintf(strbuf,
1967 "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n",
1968 bus->hostintmask, bus->intstatus, bus->sdpcm_ver);
1969 brcmu_bprintf(strbuf,
1970 "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n",
1971 bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max,
1972 bus->rxskip, bus->rxlen, bus->rx_seq);
1973 brcmu_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n",
1974 bus->intr, bus->intrcount, bus->lastintrs, bus->spurious);
1975 brcmu_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n",
1976 bus->pollrate, bus->pollcnt, bus->regfails);
1977
1978 brcmu_bprintf(strbuf, "\nAdditional counters:\n");
1979 brcmu_bprintf(strbuf,
1980 "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n",
1981 bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong,
1982 bus->rxc_errors);
1983 brcmu_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n",
1984 bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq);
1985 brcmu_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n",
1986 bus->fc_rcvd, bus->fc_xoff, bus->fc_xon);
1987 brcmu_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n",
1988 bus->rxglomfail, bus->rxglomframes, bus->rxglompkts);
1989 brcmu_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs"
1990 " %d\n",
1991 (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs,
1992 bus->f2rxdata, bus->f2txdata, bus->f1regdata);
1993 {
1994 brcmf_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->drvr->rx_packets,
1995 (bus->f2rxhdrs + bus->f2rxdata));
1996 brcmf_dump_pct(strbuf, ", pkts/f1sd", bus->drvr->rx_packets,
1997 bus->f1regdata);
1998 brcmf_dump_pct(strbuf, ", pkts/sd", bus->drvr->rx_packets,
1999 (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata));
2000 brcmf_dump_pct(strbuf, ", pkts/int", bus->drvr->rx_packets,
2001 bus->intrcount);
2002 brcmu_bprintf(strbuf, "\n");
2003
2004 brcmf_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts),
2005 bus->drvr->rx_packets);
2006 brcmf_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts,
2007 bus->rxglomframes);
2008 brcmu_bprintf(strbuf, "\n");
2009
2010 brcmf_dump_pct(strbuf, "Tx: pkts/f2wr", bus->drvr->tx_packets,
2011 bus->f2txdata);
2012 brcmf_dump_pct(strbuf, ", pkts/f1sd", bus->drvr->tx_packets,
2013 bus->f1regdata);
2014 brcmf_dump_pct(strbuf, ", pkts/sd", bus->drvr->tx_packets,
2015 (bus->f2txdata + bus->f1regdata));
2016 brcmf_dump_pct(strbuf, ", pkts/int", bus->drvr->tx_packets,
2017 bus->intrcount);
2018 brcmu_bprintf(strbuf, "\n");
2019
2020 brcmf_dump_pct(strbuf, "Total: pkts/f2rw",
2021 (bus->drvr->tx_packets + bus->drvr->rx_packets),
2022 (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata));
2023 brcmf_dump_pct(strbuf, ", pkts/f1sd",
2024 (bus->drvr->tx_packets + bus->drvr->rx_packets),
2025 bus->f1regdata);
2026 brcmf_dump_pct(strbuf, ", pkts/sd",
2027 (bus->drvr->tx_packets + bus->drvr->rx_packets),
2028 (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata +
2029 bus->f1regdata));
2030 brcmf_dump_pct(strbuf, ", pkts/int",
2031 (bus->drvr->tx_packets + bus->drvr->rx_packets),
2032 bus->intrcount);
2033 brcmu_bprintf(strbuf, "\n\n");
2034 }
2035
2036#ifdef SDTEST
2037 if (bus->pktgen_count) {
2038 brcmu_bprintf(strbuf, "pktgen config and count:\n");
2039 brcmu_bprintf(strbuf,
2040 "freq %d count %d print %d total %d min %d len %d\n",
2041 bus->pktgen_freq, bus->pktgen_count,
2042 bus->pktgen_print, bus->pktgen_total,
2043 bus->pktgen_minlen, bus->pktgen_maxlen);
2044 brcmu_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n",
2045 bus->pktgen_sent, bus->pktgen_rcvd,
2046 bus->pktgen_fail);
2047 }
2048#endif /* SDTEST */
2049#ifdef BCMDBG
2050 brcmu_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n",
2051 bus->dpc_sched, " not ");
2052 brcmu_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize,
2053 bus->roundup);
2054#endif /* BCMDBG */
2055 brcmu_bprintf(strbuf,
2056 "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n",
2057 bus->clkstate, bus->activity, bus->idletime, bus->idlecount,
2058 bus->sleeping);
2059}
2060
2061void brcmf_bus_clearcounts(struct brcmf_pub *drvr)
2062{
2063 struct brcmf_bus *bus = (struct brcmf_bus *) drvr->bus;
2064
2065 bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0;
2066 bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0;
2067 bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0;
2068 bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0;
2069 bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0;
2070 bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0;
2071}
2072
2073#ifdef SDTEST
2074static int brcmf_sdbrcm_pktgen_get(struct brcmf_bus *bus, u8 *arg)
2075{
2076 struct brcmf_pktgen pktgen;
2077
2078 pktgen.version = BRCMF_PKTGEN_VERSION;
2079 pktgen.freq = bus->pktgen_freq;
2080 pktgen.count = bus->pktgen_count;
2081 pktgen.print = bus->pktgen_print;
2082 pktgen.total = bus->pktgen_total;
2083 pktgen.minlen = bus->pktgen_minlen;
2084 pktgen.maxlen = bus->pktgen_maxlen;
2085 pktgen.numsent = bus->pktgen_sent;
2086 pktgen.numrcvd = bus->pktgen_rcvd;
2087 pktgen.numfail = bus->pktgen_fail;
2088 pktgen.mode = bus->pktgen_mode;
2089 pktgen.stop = bus->pktgen_stop;
2090
2091 memcpy(arg, &pktgen, sizeof(pktgen));
2092
2093 return 0;
2094}
2095
2096static int brcmf_sdbrcm_pktgen_set(struct brcmf_bus *bus, u8 *arg)
2097{
2098 struct brcmf_pktgen pktgen;
2099 uint oldcnt, oldmode;
2100
2101 memcpy(&pktgen, arg, sizeof(pktgen));
2102 if (pktgen.version != BRCMF_PKTGEN_VERSION)
2103 return -EINVAL;
2104
2105 oldcnt = bus->pktgen_count;
2106 oldmode = bus->pktgen_mode;
2107
2108 bus->pktgen_freq = pktgen.freq;
2109 bus->pktgen_count = pktgen.count;
2110 bus->pktgen_print = pktgen.print;
2111 bus->pktgen_total = pktgen.total;
2112 bus->pktgen_minlen = pktgen.minlen;
2113 bus->pktgen_maxlen = pktgen.maxlen;
2114 bus->pktgen_mode = pktgen.mode;
2115 bus->pktgen_stop = pktgen.stop;
2116
2117 bus->pktgen_tick = bus->pktgen_ptick = 0;
2118 bus->pktgen_len = max(bus->pktgen_len, bus->pktgen_minlen);
2119 bus->pktgen_len = min(bus->pktgen_len, bus->pktgen_maxlen);
2120
2121 /* Clear counts for a new pktgen (mode change, or was stopped) */
2122 if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode))
2123 bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0;
2124
2125 return 0;
2126}
2127#endif /* SDTEST */
2128
2129static int
2130brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data,
2131 uint size)
2132{
2133 int bcmerror = 0;
2134 u32 sdaddr;
2135 uint dsize;
2136
2137 /* Determine initial transfer parameters */
2138 sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
2139 if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
2140 dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
2141 else
2142 dsize = size;
2143
2144 /* Set the backplane window to include the start address */
2145 bcmerror = brcmf_sdbrcm_set_siaddr_window(bus, address);
2146 if (bcmerror) {
2147 BRCMF_ERROR(("%s: window change failed\n", __func__));
2148 goto xfer_done;
2149 }
2150
2151 /* Do the transfer(s) */
2152 while (size) {
2153 BRCMF_INFO(("%s: %s %d bytes at offset 0x%08x in window"
2154 " 0x%08x\n", __func__, (write ? "write" : "read"),
2155 dsize, sdaddr, (address & SBSDIO_SBWINDOW_MASK)));
2156 bcmerror =
2157 brcmf_sdcard_rwdata(bus->card, write, sdaddr, data, dsize);
2158 if (bcmerror) {
2159 BRCMF_ERROR(("%s: membytes transfer failed\n",
2160 __func__));
2161 break;
2162 }
2163
2164 /* Adjust for next transfer (if any) */
2165 size -= dsize;
2166 if (size) {
2167 data += dsize;
2168 address += dsize;
2169 bcmerror = brcmf_sdbrcm_set_siaddr_window(bus, address);
2170 if (bcmerror) {
2171 BRCMF_ERROR(("%s: window change failed\n",
2172 __func__));
2173 break;
2174 }
2175 sdaddr = 0;
2176 dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
2177 }
2178 }
2179
2180xfer_done:
2181 /* Return the window to backplane enumeration space for core access */
2182 if (brcmf_sdbrcm_set_siaddr_window(bus,
2183 brcmf_sdcard_cur_sbwad(bus->card))) {
2184 BRCMF_ERROR(("%s: FAILED to set window back to 0x%x\n",
2185 __func__, brcmf_sdcard_cur_sbwad(bus->card)));
2186 }
2187
2188 return bcmerror;
2189}
2190
2191#ifdef BCMDBG
2192static int brcmf_sdbrcm_readshared(struct brcmf_bus *bus, struct sdpcm_shared *sh)
2193{
2194 u32 addr;
2195 int rv;
2196
2197 /* Read last word in memory to determine address of
2198 sdpcm_shared structure */
2199 rv = brcmf_sdbrcm_membytes(bus, false, bus->ramsize - 4, (u8 *)&addr,
2200 4);
2201 if (rv < 0)
2202 return rv;
2203
2204 addr = le32_to_cpu(addr);
2205
2206 BRCMF_INFO(("sdpcm_shared address 0x%08X\n", addr));
2207
2208 /*
2209 * Check if addr is valid.
2210 * NVRAM length at the end of memory should have been overwritten.
2211 */
2212 if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) {
2213 BRCMF_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n",
2214 __func__, addr));
2215 return -EBADE;
2216 }
2217
2218 /* Read rte_shared structure */
2219 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *) sh,
2220 sizeof(struct sdpcm_shared));
2221 if (rv < 0)
2222 return rv;
2223
2224 /* Endianness */
2225 sh->flags = le32_to_cpu(sh->flags);
2226 sh->trap_addr = le32_to_cpu(sh->trap_addr);
2227 sh->assert_exp_addr = le32_to_cpu(sh->assert_exp_addr);
2228 sh->assert_file_addr = le32_to_cpu(sh->assert_file_addr);
2229 sh->assert_line = le32_to_cpu(sh->assert_line);
2230 sh->console_addr = le32_to_cpu(sh->console_addr);
2231 sh->msgtrace_addr = le32_to_cpu(sh->msgtrace_addr);
2232
2233 if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
2234 BRCMF_ERROR(("%s: sdpcm_shared version %d in brcmf "
2235 "is different than sdpcm_shared version %d in dongle\n",
2236 __func__, SDPCM_SHARED_VERSION,
2237 sh->flags & SDPCM_SHARED_VERSION_MASK));
2238 return -EBADE;
2239 }
2240
2241 return 0;
2242}
2243
2244static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size)
2245{
2246 int bcmerror = 0;
2247 uint msize = 512;
2248 char *mbuffer = NULL;
2249 uint maxstrlen = 256;
2250 char *str = NULL;
2251 struct brcmf_trap tr;
2252 struct sdpcm_shared sdpcm_shared;
2253 struct brcmu_strbuf strbuf;
2254
2255 BRCMF_TRACE(("%s: Enter\n", __func__));
2256
2257 if (data == NULL) {
2258 /*
2259 * Called after a rx ctrl timeout. "data" is NULL.
2260 * allocate memory to trace the trap or assert.
2261 */
2262 size = msize;
2263 mbuffer = data = kmalloc(msize, GFP_ATOMIC);
2264 if (mbuffer == NULL) {
2265 BRCMF_ERROR(("%s: kmalloc(%d) failed\n", __func__,
2266 msize));
2267 bcmerror = -ENOMEM;
2268 goto done;
2269 }
2270 }
2271
2272 str = kmalloc(maxstrlen, GFP_ATOMIC);
2273 if (str == NULL) {
2274 BRCMF_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen));
2275 bcmerror = -ENOMEM;
2276 goto done;
2277 }
2278
2279 bcmerror = brcmf_sdbrcm_readshared(bus, &sdpcm_shared);
2280 if (bcmerror < 0)
2281 goto done;
2282
2283 brcmu_binit(&strbuf, data, size);
2284
2285 brcmu_bprintf(&strbuf,
2286 "msgtrace address : 0x%08X\nconsole address : 0x%08X\n",
2287 sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr);
2288
2289 if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
2290 /* NOTE: Misspelled assert is intentional - DO NOT FIX.
2291 * (Avoids conflict with real asserts for programmatic
2292 * parsing of output.)
2293 */
2294 brcmu_bprintf(&strbuf, "Assrt not built in dongle\n");
2295 }
2296
2297 if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) ==
2298 0) {
2299 /* NOTE: Misspelled assert is intentional - DO NOT FIX.
2300 * (Avoids conflict with real asserts for programmatic
2301 * parsing of output.)
2302 */
2303 brcmu_bprintf(&strbuf, "No trap%s in dongle",
2304 (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT)
2305 ? "/assrt" : "");
2306 } else {
2307 if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) {
2308 /* Download assert */
2309 brcmu_bprintf(&strbuf, "Dongle assert");
2310 if (sdpcm_shared.assert_exp_addr != 0) {
2311 str[0] = '\0';
2312 bcmerror = brcmf_sdbrcm_membytes(bus, false,
2313 sdpcm_shared.assert_exp_addr,
2314 (u8 *) str, maxstrlen);
2315 if (bcmerror < 0)
2316 goto done;
2317
2318 str[maxstrlen - 1] = '\0';
2319 brcmu_bprintf(&strbuf, " expr \"%s\"", str);
2320 }
2321
2322 if (sdpcm_shared.assert_file_addr != 0) {
2323 str[0] = '\0';
2324 bcmerror = brcmf_sdbrcm_membytes(bus, false,
2325 sdpcm_shared.assert_file_addr,
2326 (u8 *) str, maxstrlen);
2327 if (bcmerror < 0)
2328 goto done;
2329
2330 str[maxstrlen - 1] = '\0';
2331 brcmu_bprintf(&strbuf, " file \"%s\"", str);
2332 }
2333
2334 brcmu_bprintf(&strbuf, " line %d ",
2335 sdpcm_shared.assert_line);
2336 }
2337
2338 if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
2339 bcmerror = brcmf_sdbrcm_membytes(bus, false,
2340 sdpcm_shared.trap_addr, (u8 *)&tr,
2341 sizeof(struct brcmf_trap));
2342 if (bcmerror < 0)
2343 goto done;
2344
2345 brcmu_bprintf(&strbuf,
2346 "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x,"
2347 "lp 0x%x, rpc 0x%x Trap offset 0x%x, "
2348 "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n",
2349 tr.type, tr.epc, tr.cpsr, tr.spsr, tr.r13,
2350 tr.r14, tr.pc, sdpcm_shared.trap_addr,
2351 tr.r0, tr.r1, tr.r2, tr.r3, tr.r4, tr.r5,
2352 tr.r6, tr.r7);
2353 }
2354 }
2355
2356 if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP))
2357 BRCMF_ERROR(("%s: %s\n", __func__, strbuf.origbuf));
2358
2359#ifdef BCMDBG
2360 if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
2361 /* Mem dump to a file on device */
2362 brcmf_sdbrcm_mem_dump(bus);
2363 }
2364#endif /* BCMDBG */
2365
2366done:
2367 kfree(mbuffer);
2368 kfree(str);
2369
2370 return bcmerror;
2371}
2372
2373static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus)
2374{
2375 int ret = 0;
2376 int size; /* Full mem size */
2377 int start = 0; /* Start address */
2378 int read_size = 0; /* Read size of each iteration */
2379 u8 *buf = NULL, *databuf = NULL;
2380
2381 /* Get full mem size */
2382 size = bus->ramsize;
2383 buf = kmalloc(size, GFP_ATOMIC);
2384 if (!buf) {
2385 BRCMF_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size));
2386 return -1;
2387 }
2388
2389 /* Read mem content */
2390 printk(KERN_DEBUG "Dump dongle memory");
2391 databuf = buf;
2392 while (size) {
2393 read_size = min(MEMBLOCK, size);
2394 ret = brcmf_sdbrcm_membytes(bus, false, start, databuf,
2395 read_size);
2396 if (ret) {
2397 BRCMF_ERROR(("%s: Error membytes %d\n", __func__, ret));
2398 kfree(buf);
2399 return -1;
2400 }
2401 printk(".");
2402
2403 /* Decrement size and increment start address */
2404 size -= read_size;
2405 start += read_size;
2406 databuf += read_size;
2407 }
2408 printk(KERN_DEBUG "Done\n");
2409
2410 /* free buf before return !!! */
2411 if (brcmf_write_to_file(bus->drvr, buf, bus->ramsize)) {
2412 BRCMF_ERROR(("%s: Error writing to files\n", __func__));
2413 return -1;
2414 }
2415
2416 /* buf free handled in brcmf_write_to_file, not here */
2417 return 0;
2418}
2419
2420#define CONSOLE_LINE_MAX 192
2421
2422static int brcmf_sdbrcm_readconsole(struct brcmf_bus *bus)
2423{
2424 struct brcmf_console *c = &bus->console;
2425 u8 line[CONSOLE_LINE_MAX], ch;
2426 u32 n, idx, addr;
2427 int rv;
2428
2429 /* Don't do anything until FWREADY updates console address */
2430 if (bus->console_addr == 0)
2431 return 0;
2432
2433 /* Read console log struct */
2434 addr = bus->console_addr + offsetof(struct rte_console, log);
2435 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log,
2436 sizeof(c->log));
2437 if (rv < 0)
2438 return rv;
2439
2440 /* Allocate console buffer (one time only) */
2441 if (c->buf == NULL) {
2442 c->bufsize = le32_to_cpu(c->log.buf_size);
2443 c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
2444 if (c->buf == NULL)
2445 return -ENOMEM;
2446 }
2447
2448 idx = le32_to_cpu(c->log.idx);
2449
2450 /* Protect against corrupt value */
2451 if (idx > c->bufsize)
2452 return -EBADE;
2453
2454 /* Skip reading the console buffer if the index pointer
2455 has not moved */
2456 if (idx == c->last)
2457 return 0;
2458
2459 /* Read the console buffer */
2460 addr = le32_to_cpu(c->log.buf);
2461 rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize);
2462 if (rv < 0)
2463 return rv;
2464
2465 while (c->last != idx) {
2466 for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
2467 if (c->last == idx) {
2468 /* This would output a partial line.
2469 * Instead, back up
2470 * the buffer pointer and output this
2471 * line next time around.
2472 */
2473 if (c->last >= n)
2474 c->last -= n;
2475 else
2476 c->last = c->bufsize - n;
2477 goto break2;
2478 }
2479 ch = c->buf[c->last];
2480 c->last = (c->last + 1) % c->bufsize;
2481 if (ch == '\n')
2482 break;
2483 line[n] = ch;
2484 }
2485
2486 if (n > 0) {
2487 if (line[n - 1] == '\r')
2488 n--;
2489 line[n] = 0;
2490 printk(KERN_DEBUG "CONSOLE: %s\n", line);
2491 }
2492 }
2493break2:
2494
2495 return 0;
2496}
2497#endif /* BCMDBG */
2498
2499int brcmf_sdbrcm_downloadvars(struct brcmf_bus *bus, void *arg, int len)
2500{
2501 int bcmerror = 0;
2502
2503 BRCMF_TRACE(("%s: Enter\n", __func__));
2504
2505 /* Basic sanity checks */
2506 if (bus->drvr->up) {
2507 bcmerror = -EISCONN;
2508 goto err;
2509 }
2510 if (!len) {
2511 bcmerror = -EOVERFLOW;
2512 goto err;
2513 }
2514
2515 /* Free the old ones and replace with passed variables */
2516 kfree(bus->vars);
2517
2518 bus->vars = kmalloc(len, GFP_ATOMIC);
2519 bus->varsz = bus->vars ? len : 0;
2520 if (bus->vars == NULL) {
2521 bcmerror = -ENOMEM;
2522 goto err;
2523 }
2524
2525 /* Copy the passed variables, which should include the
2526 terminating double-null */
2527 memcpy(bus->vars, arg, bus->varsz);
2528err:
2529 return bcmerror;
2530}
2531
2532static int
2533brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 actionid,
2534 const char *name, void *params, int plen, void *arg, int len,
2535 int val_size)
2536{
2537 int bcmerror = 0;
2538 s32 int_val = 0;
2539 bool bool_val = 0;
2540
2541 BRCMF_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p "
2542 "len %d val_size %d\n", __func__, actionid, name, params,
2543 plen, arg, len, val_size));
2544
2545 bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
2546 if (bcmerror != 0)
2547 goto exit;
2548
2549 if (plen >= (int)sizeof(int_val))
2550 memcpy(&int_val, params, sizeof(int_val));
2551
2552 bool_val = (int_val != 0) ? true : false;
2553
2554 /* Some ioctls use the bus */
2555 brcmf_sdbrcm_sdlock(bus);
2556
2557 /* Check if dongle is in reset. If so, only allow DEVRESET iovars */
2558 if (bus->drvr->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) ||
2559 actionid == IOV_GVAL(IOV_DEVRESET))) {
2560 bcmerror = -EPERM;
2561 goto exit;
2562 }
2563
2564 /* Handle sleep stuff before any clock mucking */
2565 if (vi->varid == IOV_SLEEP) {
2566 if (IOV_ISSET(actionid)) {
2567 bcmerror = brcmf_sdbrcm_bussleep(bus, bool_val);
2568 } else {
2569 int_val = (s32) bus->sleeping;
2570 memcpy(arg, &int_val, val_size);
2571 }
2572 goto exit;
2573 }
2574
2575 /* Request clock to allow SDIO accesses */
2576 if (!bus->drvr->dongle_reset) {
2577 BUS_WAKE(bus);
2578 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2579 }
2580
2581 switch (actionid) {
2582 case IOV_GVAL(IOV_INTR):
2583 int_val = (s32) bus->intr;
2584 memcpy(arg, &int_val, val_size);
2585 break;
2586
2587 case IOV_SVAL(IOV_INTR):
2588 bus->intr = bool_val;
2589 bus->intdis = false;
2590 if (bus->drvr->up) {
2591 BRCMF_INTR(("%s: %s SDIO interrupts\n", __func__,
2592 bus->intr ? "enable" : "disable"));
2593 if (bus->intr) {
2594 brcmf_sdcard_intr_enable(bus->card);
2595 } else {
2596 brcmf_sdcard_intr_disable(bus->card);
2597 }
2598 }
2599 break;
2600
2601 case IOV_GVAL(IOV_POLLRATE):
2602 int_val = (s32) bus->pollrate;
2603 memcpy(arg, &int_val, val_size);
2604 break;
2605
2606 case IOV_SVAL(IOV_POLLRATE):
2607 bus->pollrate = (uint) int_val;
2608 bus->poll = (bus->pollrate != 0);
2609 break;
2610
2611 case IOV_GVAL(IOV_IDLETIME):
2612 int_val = bus->idletime;
2613 memcpy(arg, &int_val, val_size);
2614 break;
2615
2616 case IOV_SVAL(IOV_IDLETIME):
2617 if ((int_val < 0) && (int_val != BRCMF_IDLE_IMMEDIATE))
2618 bcmerror = -EINVAL;
2619 else
2620 bus->idletime = int_val;
2621 break;
2622
2623 case IOV_GVAL(IOV_IDLECLOCK):
2624 int_val = (s32) bus->idleclock;
2625 memcpy(arg, &int_val, val_size);
2626 break;
2627
2628 case IOV_SVAL(IOV_IDLECLOCK):
2629 bus->idleclock = int_val;
2630 break;
2631
2632 case IOV_GVAL(IOV_SD1IDLE):
2633 int_val = (s32) sd1idle;
2634 memcpy(arg, &int_val, val_size);
2635 break;
2636
2637 case IOV_SVAL(IOV_SD1IDLE):
2638 sd1idle = bool_val;
2639 break;
2640
2641 case IOV_SVAL(IOV_MEMBYTES):
2642 case IOV_GVAL(IOV_MEMBYTES):
2643 {
2644 u32 address;
2645 uint size, dsize;
2646 u8 *data;
2647
2648 bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
2649
2650 address = (u32) int_val;
2651 memcpy(&int_val, (char *)params + sizeof(int_val),
2652 sizeof(int_val));
2653 size = (uint) int_val;
2654
2655 /* Do some validation */
2656 dsize = set ? plen - (2 * sizeof(int)) : len;
2657 if (dsize < size) {
2658 BRCMF_ERROR(("%s: error on %s membytes, addr "
2659 "0x%08x size %d dsize %d\n",
2660 __func__, (set ? "set" : "get"),
2661 address, size, dsize));
2662 bcmerror = -EINVAL;
2663 break;
2664 }
2665
2666 BRCMF_INFO(("%s: Request to %s %d bytes at address "
2667 "0x%08x\n", __func__,
2668 (set ? "write" : "read"), size, address));
2669
2670 /* If we know about SOCRAM, check for a fit */
2671 if ((bus->orig_ramsize) &&
2672 ((address > bus->orig_ramsize)
2673 || (address + size > bus->orig_ramsize))) {
2674 BRCMF_ERROR(("%s: ramsize 0x%08x doesn't have"
2675 " %d bytes at 0x%08x\n", __func__,
2676 bus->orig_ramsize, size, address));
2677 bcmerror = -EINVAL;
2678 break;
2679 }
2680
2681 /* Generate the actual data pointer */
2682 data =
2683 set ? (u8 *) params +
2684 2 * sizeof(int) : (u8 *) arg;
2685
2686 /* Call to do the transfer */
2687 bcmerror = brcmf_sdbrcm_membytes(bus, set, address,
2688 data, size);
2689
2690 break;
2691 }
2692
2693 case IOV_GVAL(IOV_MEMSIZE):
2694 int_val = (s32) bus->ramsize;
2695 memcpy(arg, &int_val, val_size);
2696 break;
2697
2698 case IOV_GVAL(IOV_SDIOD_DRIVE):
2699 int_val = (s32) brcmf_sdiod_drive_strength;
2700 memcpy(arg, &int_val, val_size);
2701 break;
2702
2703 case IOV_SVAL(IOV_SDIOD_DRIVE):
2704 brcmf_sdiod_drive_strength = int_val;
2705 brcmf_sdbrcm_sdiod_drive_strength_init(bus,
2706 brcmf_sdiod_drive_strength);
2707 break;
2708
2709 case IOV_SVAL(IOV_DOWNLOAD):
2710 bcmerror = brcmf_sdbrcm_download_state(bus, bool_val);
2711 break;
2712
2713 case IOV_SVAL(IOV_VARS):
2714 bcmerror = brcmf_sdbrcm_downloadvars(bus, arg, len);
2715 break;
2716
2717 case IOV_GVAL(IOV_READAHEAD):
2718 int_val = (s32) brcmf_readahead;
2719 memcpy(arg, &int_val, val_size);
2720 break;
2721
2722 case IOV_SVAL(IOV_READAHEAD):
2723 if (bool_val && !brcmf_readahead)
2724 bus->nextlen = 0;
2725 brcmf_readahead = bool_val;
2726 break;
2727
2728 case IOV_GVAL(IOV_SDRXCHAIN):
2729 int_val = (s32) bus->use_rxchain;
2730 memcpy(arg, &int_val, val_size);
2731 break;
2732
2733 case IOV_SVAL(IOV_SDRXCHAIN):
2734 if (bool_val && !bus->sd_rxchain)
2735 bcmerror = -ENOTSUPP;
2736 else
2737 bus->use_rxchain = bool_val;
2738 break;
2739 case IOV_GVAL(IOV_ALIGNCTL):
2740 int_val = (s32) brcmf_alignctl;
2741 memcpy(arg, &int_val, val_size);
2742 break;
2743
2744 case IOV_SVAL(IOV_ALIGNCTL):
2745 brcmf_alignctl = bool_val;
2746 break;
2747
2748 case IOV_GVAL(IOV_SDALIGN):
2749 int_val = BRCMF_SDALIGN;
2750 memcpy(arg, &int_val, val_size);
2751 break;
2752
2753#ifdef BCMDBG
2754 case IOV_GVAL(IOV_VARS):
2755 if (bus->varsz < (uint) len)
2756 memcpy(arg, bus->vars, bus->varsz);
2757 else
2758 bcmerror = -EOVERFLOW;
2759 break;
2760#endif /* BCMDBG */
2761
2762#ifdef BCMDBG
2763 case IOV_GVAL(IOV_DCONSOLE_POLL):
2764 int_val = (s32) brcmf_console_ms;
2765 memcpy(arg, &int_val, val_size);
2766 break;
2767
2768 case IOV_SVAL(IOV_DCONSOLE_POLL):
2769 brcmf_console_ms = (uint) int_val;
2770 break;
2771
2772 case IOV_SVAL(IOV_CONS):
2773 if (len > 0)
2774 bcmerror = brcmf_sdbrcm_bus_console_in(bus->drvr,
2775 arg, len - 1);
2776 break;
2777
2778 case IOV_GVAL(IOV_SDREG):
2779 {
2780 struct brcmf_sdreg *sd_ptr;
2781 u32 addr, size;
2782
2783 sd_ptr = (struct brcmf_sdreg *) params;
2784
2785 addr = bus->ci->buscorebase + sd_ptr->offset;
2786 size = sd_ptr->func;
2787 int_val = (s32) brcmf_sdcard_reg_read(bus->card, addr,
2788 size);
2789 if (brcmf_sdcard_regfail(bus->card))
2790 bcmerror = -EIO;
2791 memcpy(arg, &int_val, sizeof(s32));
2792 break;
2793 }
2794
2795 case IOV_SVAL(IOV_SDREG):
2796 {
2797 struct brcmf_sdreg *sd_ptr;
2798 u32 addr, size;
2799
2800 sd_ptr = (struct brcmf_sdreg *) params;
2801
2802 addr = bus->ci->buscorebase + sd_ptr->offset;
2803 size = sd_ptr->func;
2804 brcmf_sdcard_reg_write(bus->card, addr, size,
2805 sd_ptr->value);
2806 if (brcmf_sdcard_regfail(bus->card))
2807 bcmerror = -EIO;
2808 break;
2809 }
2810
2811 /* Same as above, but offset is not backplane
2812 (not SDIO core) */
2813 case IOV_GVAL(IOV_SBREG):
2814 {
2815 struct brcmf_sdreg sdreg;
2816 u32 addr, size;
2817
2818 memcpy(&sdreg, params, sizeof(sdreg));
2819
2820 addr = SI_ENUM_BASE + sdreg.offset;
2821 size = sdreg.func;
2822 int_val = (s32) brcmf_sdcard_reg_read(bus->card, addr,
2823 size);
2824 if (brcmf_sdcard_regfail(bus->card))
2825 bcmerror = -EIO;
2826 memcpy(arg, &int_val, sizeof(s32));
2827 break;
2828 }
2829
2830 case IOV_SVAL(IOV_SBREG):
2831 {
2832 struct brcmf_sdreg sdreg;
2833 u32 addr, size;
2834
2835 memcpy(&sdreg, params, sizeof(sdreg));
2836
2837 addr = SI_ENUM_BASE + sdreg.offset;
2838 size = sdreg.func;
2839 brcmf_sdcard_reg_write(bus->card, addr, size,
2840 sdreg.value);
2841 if (brcmf_sdcard_regfail(bus->card))
2842 bcmerror = -EIO;
2843 break;
2844 }
2845
2846 case IOV_GVAL(IOV_SDCIS):
2847 {
2848 *(char *)arg = 0;
2849
2850 strcat(arg, "\nFunc 0\n");
2851 brcmf_sdcard_cis_read(bus->card, 0x10,
2852 (u8 *) arg + strlen(arg),
2853 SBSDIO_CIS_SIZE_LIMIT);
2854 strcat(arg, "\nFunc 1\n");
2855 brcmf_sdcard_cis_read(bus->card, 0x11,
2856 (u8 *) arg + strlen(arg),
2857 SBSDIO_CIS_SIZE_LIMIT);
2858 strcat(arg, "\nFunc 2\n");
2859 brcmf_sdcard_cis_read(bus->card, 0x12,
2860 (u8 *) arg + strlen(arg),
2861 SBSDIO_CIS_SIZE_LIMIT);
2862 break;
2863 }
2864
2865 case IOV_GVAL(IOV_FORCEEVEN):
2866 int_val = (s32) forcealign;
2867 memcpy(arg, &int_val, val_size);
2868 break;
2869
2870 case IOV_SVAL(IOV_FORCEEVEN):
2871 forcealign = bool_val;
2872 break;
2873
2874 case IOV_GVAL(IOV_TXBOUND):
2875 int_val = (s32) brcmf_txbound;
2876 memcpy(arg, &int_val, val_size);
2877 break;
2878
2879 case IOV_SVAL(IOV_TXBOUND):
2880 brcmf_txbound = (uint) int_val;
2881 break;
2882
2883 case IOV_GVAL(IOV_RXBOUND):
2884 int_val = (s32) brcmf_rxbound;
2885 memcpy(arg, &int_val, val_size);
2886 break;
2887
2888 case IOV_SVAL(IOV_RXBOUND):
2889 brcmf_rxbound = (uint) int_val;
2890 break;
2891
2892 case IOV_GVAL(IOV_TXMINMAX):
2893 int_val = (s32) brcmf_txminmax;
2894 memcpy(arg, &int_val, val_size);
2895 break;
2896
2897 case IOV_SVAL(IOV_TXMINMAX):
2898 brcmf_txminmax = (uint) int_val;
2899 break;
2900#endif /* BCMDBG */
2901
2902#ifdef SDTEST
2903 case IOV_GVAL(IOV_EXTLOOP):
2904 int_val = (s32) bus->ext_loop;
2905 memcpy(arg, &int_val, val_size);
2906 break;
2907
2908 case IOV_SVAL(IOV_EXTLOOP):
2909 bus->ext_loop = bool_val;
2910 break;
2911
2912 case IOV_GVAL(IOV_PKTGEN):
2913 bcmerror = brcmf_sdbrcm_pktgen_get(bus, arg);
2914 break;
2915
2916 case IOV_SVAL(IOV_PKTGEN):
2917 bcmerror = brcmf_sdbrcm_pktgen_set(bus, arg);
2918 break;
2919#endif /* SDTEST */
2920
2921 case IOV_SVAL(IOV_DEVRESET):
2922 BRCMF_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d "
2923 "busstate=%d\n",
2924 __func__, bool_val, bus->drvr->dongle_reset,
2925 bus->drvr->busstate));
2926
2927 brcmf_bus_devreset(bus->drvr, (u8) bool_val);
2928
2929 break;
2930
2931 case IOV_GVAL(IOV_DEVRESET):
2932 BRCMF_TRACE(("%s: Called get IOV_DEVRESET\n", __func__));
2933
2934 /* Get its status */
2935 int_val = (bool) bus->drvr->dongle_reset;
2936 memcpy(arg, &int_val, val_size);
2937
2938 break;
2939
2940 case IOV_GVAL(IOV_WDTICK):
2941 int_val = (s32) brcmf_watchdog_ms;
2942 memcpy(arg, &int_val, val_size);
2943 break;
2944
2945 case IOV_SVAL(IOV_WDTICK):
2946 if (!bus->drvr->up) {
2947 bcmerror = -ENOLINK;
2948 break;
2949 }
2950 brcmf_sdbrcm_wd_timer(bus, (uint) int_val);
2951 break;
2952
2953 default:
2954 bcmerror = -ENOTSUPP;
2955 break;
2956 }
2957
2958exit:
2959 if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
2960 bus->activity = false;
2961 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
2962 }
2963
2964 brcmf_sdbrcm_sdunlock(bus);
2965
2966 if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == false)
2967 brcmf_c_preinit_ioctls(bus->drvr);
2968
2969 return bcmerror;
2970}
2971
2972static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus)
2973{
2974 int bcmerror = 0;
2975 u32 varsize;
2976 u32 varaddr;
2977 u8 *vbuffer;
2978 u32 varsizew;
2979#ifdef BCMDBG
2980 char *nvram_ularray;
2981#endif /* BCMDBG */
2982
2983 /* Even if there are no vars are to be written, we still
2984 need to set the ramsize. */
2985 varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
2986 varaddr = (bus->ramsize - 4) - varsize;
2987
2988 if (bus->vars) {
2989 vbuffer = kzalloc(varsize, GFP_ATOMIC);
2990 if (!vbuffer)
2991 return -ENOMEM;
2992
2993 memcpy(vbuffer, bus->vars, bus->varsz);
2994
2995 /* Write the vars list */
2996 bcmerror =
2997 brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
2998#ifdef BCMDBG
2999 /* Verify NVRAM bytes */
3000 BRCMF_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize));
3001 nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
3002 if (!nvram_ularray)
3003 return -ENOMEM;
3004
3005 /* Upload image to verify downloaded contents. */
3006 memset(nvram_ularray, 0xaa, varsize);
3007
3008 /* Read the vars list to temp buffer for comparison */
3009 bcmerror =
3010 brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
3011 varsize);
3012 if (bcmerror) {
3013 BRCMF_ERROR(("%s: error %d on reading %d nvram bytes"
3014 " at 0x%08x\n", __func__, bcmerror,
3015 varsize, varaddr));
3016 }
3017 /* Compare the org NVRAM with the one read from RAM */
3018 if (memcmp(vbuffer, nvram_ularray, varsize)) {
3019 BRCMF_ERROR(("%s: Downloaded NVRAM image is "
3020 "corrupted.\n", __func__));
3021 } else
3022 BRCMF_ERROR(("%s: Download/Upload/Compare of"
3023 " NVRAM ok.\n", __func__));
3024
3025 kfree(nvram_ularray);
3026#endif /* BCMDBG */
3027
3028 kfree(vbuffer);
3029 }
3030
3031 /* adjust to the user specified RAM */
3032 BRCMF_INFO(("Physical memory size: %d, usable memory size: %d\n",
3033 bus->orig_ramsize, bus->ramsize));
3034 BRCMF_INFO(("Vars are at %d, orig varsize is %d\n", varaddr, varsize));
3035 varsize = ((bus->orig_ramsize - 4) - varaddr);
3036
3037 /*
3038 * Determine the length token:
3039 * Varsize, converted to words, in lower 16-bits, checksum
3040 * in upper 16-bits.
3041 */
3042 if (bcmerror) {
3043 varsizew = 0;
3044 } else {
3045 varsizew = varsize / 4;
3046 varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
3047 varsizew = cpu_to_le32(varsizew);
3048 }
3049
3050 BRCMF_INFO(("New varsize is %d, length token=0x%08x\n", varsize,
3051 varsizew));
3052
3053 /* Write the length token to the last word */
3054 bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->orig_ramsize - 4),
3055 (u8 *)&varsizew, 4);
3056
3057 return bcmerror;
3058}
3059
3060static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter)
3061{
3062 uint retries;
3063 u32 regdata;
3064 int bcmerror = 0;
3065
3066 /* To enter download state, disable ARM and reset SOCRAM.
3067 * To exit download state, simply reset ARM (default is RAM boot).
3068 */
3069 if (enter) {
3070 bus->alp_only = true;
3071
3072 brcmf_sdbrcm_chip_disablecore(bus->card, bus->ci->armcorebase);
3073
3074 brcmf_sdbrcm_chip_resetcore(bus->card, bus->ci->ramcorebase);
3075
3076 /* Clear the top bit of memory */
3077 if (bus->ramsize) {
3078 u32 zeros = 0;
3079 brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4,
3080 (u8 *)&zeros, 4);
3081 }
3082 } else {
3083 regdata = brcmf_sdcard_reg_read(bus->card,
3084 CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4);
3085 regdata &= (SBTML_RESET | SBTML_REJ_MASK |
3086 (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
3087 if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) {
3088 BRCMF_ERROR(("%s: SOCRAM core is down after reset?\n",
3089 __func__));
3090 bcmerror = -EBADE;
3091 goto fail;
3092 }
3093
3094 bcmerror = brcmf_sdbrcm_write_vars(bus);
3095 if (bcmerror) {
3096 BRCMF_ERROR(("%s: no vars written to RAM\n", __func__));
3097 bcmerror = 0;
3098 }
3099
3100 w_sdreg32(bus, 0xFFFFFFFF,
3101 offsetof(struct sdpcmd_regs, intstatus), &retries);
3102
3103 brcmf_sdbrcm_chip_resetcore(bus->card, bus->ci->armcorebase);
3104
3105 /* Allow HT Clock now that the ARM is running. */
3106 bus->alp_only = false;
3107
3108 bus->drvr->busstate = BRCMF_BUS_LOAD;
3109 }
3110fail:
3111 return bcmerror;
3112}
3113
3114int
3115brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name,
3116 void *params, int plen, void *arg, int len, bool set)
3117{
3118 struct brcmf_bus *bus = drvr->bus;
3119 const struct brcmu_iovar *vi = NULL;
3120 int bcmerror = 0;
3121 int val_size;
3122 u32 actionid;
3123
3124 BRCMF_TRACE(("%s: Enter\n", __func__));
3125
3126 if (name == NULL || len <= 0)
3127 return -EINVAL;
3128
3129 /* Set does not take qualifiers */
3130 if (set && (params || plen))
3131 return -EINVAL;
3132
3133 /* Get must have return space;*/
3134 if (!set && !(arg && len))
3135 return -EINVAL;
3136
3137 /* Look up var locally; if not found pass to host driver */
3138 vi = brcmu_iovar_lookup(brcmf_sdio_iovars, name);
3139 if (vi == NULL) {
3140 brcmf_sdbrcm_sdlock(bus);
3141
3142 BUS_WAKE(bus);
3143
3144 /* Turn on clock in case SD command needs backplane */
3145 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3146
3147 bcmerror = brcmf_sdcard_iovar_op(bus->card, name, params, plen,
3148 arg, len, set);
3149
3150 /* Similar check for blocksize change */
3151 if (set && strcmp(name, "sd_blocksize") == 0) {
3152 s32 fnum = 2;
3153 if (brcmf_sdcard_iovar_op
3154 (bus->card, "sd_blocksize", &fnum, sizeof(s32),
3155 &bus->blocksize, sizeof(s32),
3156 false) != 0) {
3157 bus->blocksize = 0;
3158 BRCMF_ERROR(("%s: fail on %s get\n", __func__,
3159 "sd_blocksize"));
3160 } else {
3161 BRCMF_INFO(("%s: noted sd_blocksize update,"
3162 " value now %d\n", __func__,
3163 bus->blocksize));
3164 }
3165 }
3166 bus->roundup = min(max_roundup, bus->blocksize);
3167
3168 if (bus->idletime == BRCMF_IDLE_IMMEDIATE &&
3169 !bus->dpc_sched) {
3170 bus->activity = false;
3171 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
3172 }
3173
3174 brcmf_sdbrcm_sdunlock(bus);
3175 goto exit;
3176 }
3177
3178 BRCMF_CTL(("%s: %s %s, len %d plen %d\n", __func__,
3179 name, (set ? "set" : "get"), len, plen));
3180
3181 /* set up 'params' pointer in case this is a set command so that
3182 * the convenience int and bool code can be common to set and get
3183 */
3184 if (params == NULL) {
3185 params = arg;
3186 plen = len;
3187 }
3188
3189 if (vi->type == IOVT_VOID)
3190 val_size = 0;
3191 else if (vi->type == IOVT_BUFFER)
3192 val_size = len;
3193 else
3194 /* all other types are integer sized */
3195 val_size = sizeof(int);
3196
3197 actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
3198 bcmerror = brcmf_sdbrcm_doiovar(bus, vi, actionid, name, params, plen,
3199 arg, len, val_size);
3200
3201exit:
3202 return bcmerror;
3203}
3204
3205void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex)
3206{
3207 u32 local_hostintmask;
3208 u8 saveclk;
3209 uint retries;
3210 int err;
3211
3212 BRCMF_TRACE(("%s: Enter\n", __func__));
3213
3214 if (enforce_mutex)
3215 brcmf_sdbrcm_sdlock(bus);
3216
3217 BUS_WAKE(bus);
3218
3219 /* Enable clock for device interrupts */
3220 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3221
3222 if (bus->watchdog_tsk) {
3223 send_sig(SIGTERM, bus->watchdog_tsk, 1);
3224 kthread_stop(bus->watchdog_tsk);
3225 bus->watchdog_tsk = NULL;
3226 }
3227
3228 if (bus->dpc_tsk) {
3229 send_sig(SIGTERM, bus->dpc_tsk, 1);
3230 kthread_stop(bus->dpc_tsk);
3231 bus->dpc_tsk = NULL;
3232 } else
3233 tasklet_kill(&bus->tasklet);
3234
3235 /* Disable and clear interrupts at the chip level also */
3236 w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries);
3237 local_hostintmask = bus->hostintmask;
3238 bus->hostintmask = 0;
3239
3240 /* Change our idea of bus state */
3241 bus->drvr->busstate = BRCMF_BUS_DOWN;
3242
3243 /* Force clocks on backplane to be sure F2 interrupt propagates */
3244 saveclk = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1,
3245 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3246 if (!err) {
3247 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1,
3248 SBSDIO_FUNC1_CHIPCLKCSR,
3249 (saveclk | SBSDIO_FORCE_HT), &err);
3250 }
3251 if (err) {
3252 BRCMF_ERROR(("%s: Failed to force clock for F2: err %d\n",
3253 __func__, err));
3254 }
3255
3256 /* Turn off the bus (F2), free any pending packets */
3257 BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__));
3258 brcmf_sdcard_intr_disable(bus->card);
3259 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx,
3260 SDIO_FUNC_ENABLE_1, NULL);
3261
3262 /* Clear any pending interrupts now that F2 is disabled */
3263 w_sdreg32(bus, local_hostintmask,
3264 offsetof(struct sdpcmd_regs, intstatus), &retries);
3265
3266 /* Turn off the backplane clock (only) */
3267 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
3268
3269 /* Clear the data packet queues */
3270 brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
3271
3272 /* Clear any held glomming stuff */
3273 if (bus->glomd)
3274 brcmu_pkt_buf_free_skb(bus->glomd);
3275
3276 if (bus->glom)
3277 brcmu_pkt_buf_free_skb(bus->glom);
3278
3279 bus->glom = bus->glomd = NULL;
3280
3281 /* Clear rx control and wake any waiters */
3282 bus->rxlen = 0;
3283 brcmf_os_ioctl_resp_wake(bus->drvr);
3284
3285 /* Reset some F2 state stuff */
3286 bus->rxskip = false;
3287 bus->tx_seq = bus->rx_seq = 0;
3288
3289 if (enforce_mutex)
3290 brcmf_sdbrcm_sdunlock(bus);
3291}
3292
3293int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex)
3294{
3295 struct brcmf_bus *bus = drvr->bus;
3296 struct brcmf_timeout tmo;
3297 uint retries = 0;
3298 u8 ready, enable;
3299 int err, ret = 0;
3300 u8 saveclk;
3301
3302 BRCMF_TRACE(("%s: Enter\n", __func__));
3303
3304 /* try to download image and nvram to the dongle */
3305 if (drvr->busstate == BRCMF_BUS_DOWN) {
3306 if (!(brcmf_sdbrcm_download_firmware(bus, bus->card)))
3307 return -1;
3308 }
3309
3310 if (!bus->drvr)
3311 return 0;
3312
3313 /* Start the watchdog timer */
3314 bus->drvr->tickcnt = 0;
3315 brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms);
3316
3317 if (enforce_mutex)
3318 brcmf_sdbrcm_sdlock(bus);
3319
3320 /* Make sure backplane clock is on, needed to generate F2 interrupt */
3321 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
3322 if (bus->clkstate != CLK_AVAIL)
3323 goto exit;
3324
3325 /* Force clocks on backplane to be sure F2 interrupt propagates */
3326 saveclk =
3327 brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1,
3328 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3329 if (!err) {
3330 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1,
3331 SBSDIO_FUNC1_CHIPCLKCSR,
3332 (saveclk | SBSDIO_FORCE_HT), &err);
3333 }
3334 if (err) {
3335 BRCMF_ERROR(("%s: Failed to force clock for F2: err %d\n",
3336 __func__, err));
3337 goto exit;
3338 }
3339
3340 /* Enable function 2 (frame transfers) */
3341 w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
3342 offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries);
3343 enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
3344
3345 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, enable,
3346 NULL);
3347
3348 /* Give the dongle some time to do its thing and set IOR2 */
3349 brcmf_timeout_start(&tmo, BRCMF_WAIT_F2RDY * 1000);
3350
3351 ready = 0;
3352 while (ready != enable && !brcmf_timeout_expired(&tmo))
3353 ready = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_0,
3354 SDIO_CCCR_IORx, NULL);
3355
3356 BRCMF_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n",
3357 __func__, enable, ready, tmo.elapsed));
3358
3359 /* If F2 successfully enabled, set core and enable interrupts */
3360 if (ready == enable) {
3361 /* Set up the interrupt mask and enable interrupts */
3362 bus->hostintmask = HOSTINTMASK;
3363 w_sdreg32(bus, bus->hostintmask,
3364 offsetof(struct sdpcmd_regs, hostintmask), &retries);
3365
3366 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_WATERMARK,
3367 (u8) watermark, &err);
3368
3369 /* Set bus state according to enable result */
3370 drvr->busstate = BRCMF_BUS_DATA;
3371
3372 bus->intdis = false;
3373 if (bus->intr) {
3374 BRCMF_INTR(("%s: enable SDIO device interrupts\n",
3375 __func__));
3376 brcmf_sdcard_intr_enable(bus->card);
3377 } else {
3378 BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__));
3379 brcmf_sdcard_intr_disable(bus->card);
3380 }
3381
3382 }
3383
3384 else {
3385 /* Disable F2 again */
3386 enable = SDIO_FUNC_ENABLE_1;
3387 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx,
3388 enable, NULL);
3389 }
3390
3391 /* Restore previous clock setting */
3392 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
3393 saveclk, &err);
3394
3395#if defined(OOB_INTR_ONLY)
3396 /* Host registration for OOB interrupt */
3397 if (brcmf_sdio_register_oob_intr(bus->dhd)) {
3398 brcmf_sdbrcm_wd_timer(bus, 0);
3399 BRCMF_ERROR(("%s Host failed to resgister for OOB\n",
3400 __func__));
3401 ret = -ENODEV;
3402 goto exit;
3403 }
3404
3405 /* Enable oob at firmware */
3406 brcmf_sdbrcm_enable_oob_intr(bus, true);
3407#endif /* defined(OOB_INTR_ONLY) */
3408
3409 /* If we didn't come up, turn off backplane clock */
3410 if (drvr->busstate != BRCMF_BUS_DATA)
3411 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3412
3413exit:
3414 if (enforce_mutex)
3415 brcmf_sdbrcm_sdunlock(bus);
3416
3417 return ret;
3418}
3419
3420static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx)
3421{
3422 struct brcmf_sdio_card *card = bus->card;
3423 uint retries = 0;
3424 u16 lastrbc;
3425 u8 hi, lo;
3426 int err;
3427
3428 BRCMF_ERROR(("%s: %sterminate frame%s\n", __func__,
3429 (abort ? "abort command, " : ""),
3430 (rtx ? ", send NAK" : "")));
3431
3432 if (abort)
3433 brcmf_sdcard_abort(card, SDIO_FUNC_2);
3434
3435 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL,
3436 SFC_RF_TERM, &err);
3437 bus->f1regdata++;
3438
3439 /* Wait until the packet has been flushed (device/FIFO stable) */
3440 for (lastrbc = retries = 0xffff; retries > 0; retries--) {
3441 hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
3442 SBSDIO_FUNC1_RFRAMEBCHI, NULL);
3443 lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
3444 SBSDIO_FUNC1_RFRAMEBCLO, NULL);
3445 bus->f1regdata += 2;
3446
3447 if ((hi == 0) && (lo == 0))
3448 break;
3449
3450 if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
3451 BRCMF_ERROR(("%s: count growing: last 0x%04x now "
3452 "0x%04x\n",
3453 __func__, lastrbc, ((hi << 8) + lo)));
3454 }
3455 lastrbc = (hi << 8) + lo;
3456 }
3457
3458 if (!retries) {
3459 BRCMF_ERROR(("%s: count never zeroed: last 0x%04x\n",
3460 __func__, lastrbc));
3461 } else {
3462 BRCMF_INFO(("%s: flush took %d iterations\n", __func__,
3463 (0xffff - retries)));
3464 }
3465
3466 if (rtx) {
3467 bus->rxrtx++;
3468 w_sdreg32(bus, SMB_NAK,
3469 offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
3470
3471 bus->f1regdata++;
3472 if (retries <= retry_limit)
3473 bus->rxskip = true;
3474 }
3475
3476 /* Clear partial in any case */
3477 bus->nextlen = 0;
3478
3479 /* If we can't reach the device, signal failure */
3480 if (err || brcmf_sdcard_regfail(card))
3481 bus->drvr->busstate = BRCMF_BUS_DOWN;
3482}
3483
3484static void
3485brcmf_sdbrcm_read_control(struct brcmf_bus *bus, u8 *hdr, uint len, uint doff)
3486{
3487 struct brcmf_sdio_card *card = bus->card;
3488 uint rdlen, pad;
3489
3490 int sdret;
3491
3492 BRCMF_TRACE(("%s: Enter\n", __func__));
3493
3494 /* Control data already received in aligned rxctl */
3495 if ((bus->bus == SPI_BUS) && (!bus->usebufpool))
3496 goto gotpkt;
3497
3498 /* Set rxctl for frame (w/optional alignment) */
3499 bus->rxctl = bus->rxbuf;
3500 if (brcmf_alignctl) {
3501 bus->rxctl += firstread;
3502 pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN);
3503 if (pad)
3504 bus->rxctl += (BRCMF_SDALIGN - pad);
3505 bus->rxctl -= firstread;
3506 }
3507
3508 /* Copy the already-read portion over */
3509 memcpy(bus->rxctl, hdr, firstread);
3510 if (len <= firstread)
3511 goto gotpkt;
3512
3513 /* Copy the full data pkt in gSPI case and process ioctl. */
3514 if (bus->bus == SPI_BUS) {
3515 memcpy(bus->rxctl, hdr, len);
3516 goto gotpkt;
3517 }
3518
3519 /* Raise rdlen to next SDIO block to avoid tail command */
3520 rdlen = len - firstread;
3521 if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
3522 pad = bus->blocksize - (rdlen % bus->blocksize);
3523 if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
3524 ((len + pad) < bus->drvr->maxctl))
3525 rdlen += pad;
3526 } else if (rdlen % BRCMF_SDALIGN) {
3527 rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
3528 }
3529
3530 /* Satisfy length-alignment requirements */
3531 if (forcealign && (rdlen & (ALIGNMENT - 1)))
3532 rdlen = roundup(rdlen, ALIGNMENT);
3533
3534 /* Drop if the read is too big or it exceeds our maximum */
3535 if ((rdlen + firstread) > bus->drvr->maxctl) {
3536 BRCMF_ERROR(("%s: %d-byte control read exceeds %d-byte"
3537 " buffer\n", __func__, rdlen, bus->drvr->maxctl));
3538 bus->drvr->rx_errors++;
3539 brcmf_sdbrcm_rxfail(bus, false, false);
3540 goto done;
3541 }
3542
3543 if ((len - doff) > bus->drvr->maxctl) {
3544 BRCMF_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds "
3545 "%d-byte limit\n",
3546 __func__, len, (len - doff), bus->drvr->maxctl));
3547 bus->drvr->rx_errors++;
3548 bus->rx_toolong++;
3549 brcmf_sdbrcm_rxfail(bus, false, false);
3550 goto done;
3551 }
3552
3553 /* Read remainder of frame body into the rxctl buffer */
3554 sdret = brcmf_sdcard_recv_buf(card, brcmf_sdcard_cur_sbwad(card),
3555 SDIO_FUNC_2,
3556 F2SYNC, (bus->rxctl + firstread), rdlen,
3557 NULL, NULL, NULL);
3558 bus->f2rxdata++;
3559
3560 /* Control frame failures need retransmission */
3561 if (sdret < 0) {
3562 BRCMF_ERROR(("%s: read %d control bytes failed: %d\n",
3563 __func__, rdlen, sdret));
3564 bus->rxc_errors++;
3565 brcmf_sdbrcm_rxfail(bus, true, true);
3566 goto done;
3567 }
3568
3569gotpkt:
3570
3571#ifdef BCMDBG
3572 if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
3573 printk(KERN_DEBUG "RxCtrl:\n");
3574 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len);
3575 }
3576#endif
3577
3578 /* Point to valid data and indicate its length */
3579 bus->rxctl += doff;
3580 bus->rxlen = len - doff;
3581
3582done:
3583 /* Awake any waiters */
3584 brcmf_os_ioctl_resp_wake(bus->drvr);
3585}
3586
3587static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
3588{
3589 u16 dlen, totlen;
3590 u8 *dptr, num = 0;
3591
3592 u16 sublen, check;
3593 struct sk_buff *pfirst, *plast, *pnext, *save_pfirst;
3594
3595 int errcode;
3596 u8 chan, seq, doff, sfdoff;
3597 u8 txmax;
3598
3599 int ifidx = 0;
3600 bool usechain = bus->use_rxchain;
3601
3602 /* If packets, issue read(s) and send up packet chain */
3603 /* Return sequence numbers consumed? */
3604
3605 BRCMF_TRACE(("brcmf_sdbrcm_rxglom: start: glomd %p glom %p\n",
3606 bus->glomd, bus->glom));
3607
3608 /* If there's a descriptor, generate the packet chain */
3609 if (bus->glomd) {
3610 pfirst = plast = pnext = NULL;
3611 dlen = (u16) (bus->glomd->len);
3612 dptr = bus->glomd->data;
3613 if (!dlen || (dlen & 1)) {
3614 BRCMF_ERROR(("%s: bad glomd len(%d),"
3615 " ignore descriptor\n",
3616 __func__, dlen));
3617 dlen = 0;
3618 }
3619
3620 for (totlen = num = 0; dlen; num++) {
3621 /* Get (and move past) next length */
3622 sublen = get_unaligned_le16(dptr);
3623 dlen -= sizeof(u16);
3624 dptr += sizeof(u16);
3625 if ((sublen < SDPCM_HDRLEN) ||
3626 ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
3627 BRCMF_ERROR(("%s: descriptor len %d bad: %d\n",
3628 __func__, num, sublen));
3629 pnext = NULL;
3630 break;
3631 }
3632 if (sublen % BRCMF_SDALIGN) {
3633 BRCMF_ERROR(("%s: sublen %d not multiple of"
3634 " %d\n", __func__, sublen,
3635 BRCMF_SDALIGN));
3636 usechain = false;
3637 }
3638 totlen += sublen;
3639
3640 /* For last frame, adjust read len so total
3641 is a block multiple */
3642 if (!dlen) {
3643 sublen +=
3644 (roundup(totlen, bus->blocksize) - totlen);
3645 totlen = roundup(totlen, bus->blocksize);
3646 }
3647
3648 /* Allocate/chain packet for next subframe */
3649 pnext = brcmu_pkt_buf_get_skb(sublen + BRCMF_SDALIGN);
3650 if (pnext == NULL) {
3651 BRCMF_ERROR(("%s: bcm_pkt_buf_get_skb failed, "
3652 "num %d len %d\n", __func__,
3653 num, sublen));
3654 break;
3655 }
3656 if (!pfirst) {
3657 pfirst = plast = pnext;
3658 } else {
3659 plast->next = pnext;
3660 plast = pnext;
3661 }
3662
3663 /* Adhere to start alignment requirements */
3664 PKTALIGN(pnext, sublen, BRCMF_SDALIGN);
3665 }
3666
3667 /* If all allocations succeeded, save packet chain
3668 in bus structure */
3669 if (pnext) {
3670 BRCMF_GLOM(("%s: allocated %d-byte packet chain for %d "
3671 "subframes\n", __func__, totlen, num));
3672 if (BRCMF_GLOM_ON() && bus->nextlen) {
3673 if (totlen != bus->nextlen) {
3674 BRCMF_GLOM(("%s: glomdesc mismatch: "
3675 "nextlen %d glomdesc %d "
3676 "rxseq %d\n", __func__,
3677 bus->nextlen,
3678 totlen, rxseq));
3679 }
3680 }
3681 bus->glom = pfirst;
3682 pfirst = pnext = NULL;
3683 } else {
3684 if (pfirst)
3685 brcmu_pkt_buf_free_skb(pfirst);
3686 bus->glom = NULL;
3687 num = 0;
3688 }
3689
3690 /* Done with descriptor packet */
3691 brcmu_pkt_buf_free_skb(bus->glomd);
3692 bus->glomd = NULL;
3693 bus->nextlen = 0;
3694 }
3695
3696 /* Ok -- either we just generated a packet chain,
3697 or had one from before */
3698 if (bus->glom) {
3699 if (BRCMF_GLOM_ON()) {
3700 BRCMF_GLOM(("%s: try superframe read, packet chain:\n",
3701 __func__));
3702 for (pnext = bus->glom; pnext; pnext = pnext->next) {
3703 BRCMF_GLOM((" %p: %p len 0x%04x (%d)\n",
3704 pnext, (u8 *) (pnext->data),
3705 pnext->len, pnext->len));
3706 }
3707 }
3708
3709 pfirst = bus->glom;
3710 dlen = (u16) brcmu_pkttotlen(pfirst);
3711
3712 /* Do an SDIO read for the superframe. Configurable iovar to
3713 * read directly into the chained packet, or allocate a large
3714 * packet and and copy into the chain.
3715 */
3716 if (usechain) {
3717 errcode = brcmf_sdcard_recv_buf(bus->card,
3718 brcmf_sdcard_cur_sbwad(bus->card),
3719 SDIO_FUNC_2,
3720 F2SYNC, (u8 *) pfirst->data, dlen,
3721 pfirst, NULL, NULL);
3722 } else if (bus->dataptr) {
3723 errcode = brcmf_sdcard_recv_buf(bus->card,
3724 brcmf_sdcard_cur_sbwad(bus->card),
3725 SDIO_FUNC_2,
3726 F2SYNC, bus->dataptr, dlen,
3727 NULL, NULL, NULL);
3728 sublen = (u16) brcmu_pktfrombuf(pfirst, 0, dlen,
3729 bus->dataptr);
3730 if (sublen != dlen) {
3731 BRCMF_ERROR(("%s: FAILED TO COPY, dlen %d "
3732 "sublen %d\n",
3733 __func__, dlen, sublen));
3734 errcode = -1;
3735 }
3736 pnext = NULL;
3737 } else {
3738 BRCMF_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, "
3739 "FORCE FAILURE\n", dlen));
3740 errcode = -1;
3741 }
3742 bus->f2rxdata++;
3743
3744 /* On failure, kill the superframe, allow a couple retries */
3745 if (errcode < 0) {
3746 BRCMF_ERROR(("%s: glom read of %d bytes failed: %d\n",
3747 __func__, dlen, errcode));
3748 bus->drvr->rx_errors++;
3749
3750 if (bus->glomerr++ < 3) {
3751 brcmf_sdbrcm_rxfail(bus, true, true);
3752 } else {
3753 bus->glomerr = 0;
3754 brcmf_sdbrcm_rxfail(bus, true, false);
3755 brcmu_pkt_buf_free_skb(bus->glom);
3756 bus->rxglomfail++;
3757 bus->glom = NULL;
3758 }
3759 return 0;
3760 }
3761#ifdef BCMDBG
3762 if (BRCMF_GLOM_ON()) {
3763 printk(KERN_DEBUG "SUPERFRAME:\n");
3764 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
3765 pfirst->data, min_t(int, pfirst->len, 48));
3766 }
3767#endif
3768
3769 /* Validate the superframe header */
3770 dptr = (u8 *) (pfirst->data);
3771 sublen = get_unaligned_le16(dptr);
3772 check = get_unaligned_le16(dptr + sizeof(u16));
3773
3774 chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
3775 seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
3776 bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
3777 if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
3778 BRCMF_INFO(("%s: nextlen too large (%d) seq %d\n",
3779 __func__, bus->nextlen, seq));
3780 bus->nextlen = 0;
3781 }
3782 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
3783 txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
3784
3785 errcode = 0;
3786 if ((u16)~(sublen ^ check)) {
3787 BRCMF_ERROR(("%s (superframe): HW hdr error: len/check "
3788 "0x%04x/0x%04x\n", __func__, sublen,
3789 check));
3790 errcode = -1;
3791 } else if (roundup(sublen, bus->blocksize) != dlen) {
3792 BRCMF_ERROR(("%s (superframe): len 0x%04x, rounded "
3793 "0x%04x, expect 0x%04x\n",
3794 __func__, sublen,
3795 roundup(sublen, bus->blocksize), dlen));
3796 errcode = -1;
3797 } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
3798 SDPCM_GLOM_CHANNEL) {
3799 BRCMF_ERROR(("%s (superframe): bad channel %d\n",
3800 __func__,
3801 SDPCM_PACKET_CHANNEL(&dptr
3802 [SDPCM_FRAMETAG_LEN])));
3803 errcode = -1;
3804 } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
3805 BRCMF_ERROR(("%s (superframe): got 2nd descriptor?\n",
3806 __func__));
3807 errcode = -1;
3808 } else if ((doff < SDPCM_HDRLEN) ||
3809 (doff > (pfirst->len - SDPCM_HDRLEN))) {
3810 BRCMF_ERROR(("%s (superframe): Bad data offset %d: "
3811 "HW %d pkt %d min %d\n",
3812 __func__, doff, sublen,
3813 pfirst->len, SDPCM_HDRLEN));
3814 errcode = -1;
3815 }
3816
3817 /* Check sequence number of superframe SW header */
3818 if (rxseq != seq) {
3819 BRCMF_INFO(("%s: (superframe) rx_seq %d, expected %d\n",
3820 __func__, seq, rxseq));
3821 bus->rx_badseq++;
3822 rxseq = seq;
3823 }
3824
3825 /* Check window for sanity */
3826 if ((u8) (txmax - bus->tx_seq) > 0x40) {
3827 BRCMF_ERROR(("%s: unlikely tx max %d with tx_seq %d\n",
3828 __func__, txmax, bus->tx_seq));
3829 txmax = bus->tx_seq + 2;
3830 }
3831 bus->tx_max = txmax;
3832
3833 /* Remove superframe header, remember offset */
3834 skb_pull(pfirst, doff);
3835 sfdoff = doff;
3836
3837 /* Validate all the subframe headers */
3838 for (num = 0, pnext = pfirst; pnext && !errcode;
3839 num++, pnext = pnext->next) {
3840 dptr = (u8 *) (pnext->data);
3841 dlen = (u16) (pnext->len);
3842 sublen = get_unaligned_le16(dptr);
3843 check = get_unaligned_le16(dptr + sizeof(u16));
3844 chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
3845 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
3846#ifdef BCMDBG
3847 if (BRCMF_GLOM_ON()) {
3848 printk(KERN_DEBUG "subframe:\n");
3849 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
3850 dptr, 32);
3851 }
3852#endif
3853
3854 if ((u16)~(sublen ^ check)) {
3855 BRCMF_ERROR(("%s (subframe %d): HW hdr error: "
3856 "len/check 0x%04x/0x%04x\n",
3857 __func__, num, sublen, check));
3858 errcode = -1;
3859 } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
3860 BRCMF_ERROR(("%s (subframe %d): length mismatch"
3861 ": len 0x%04x, expect 0x%04x\n",
3862 __func__, num, sublen, dlen));
3863 errcode = -1;
3864 } else if ((chan != SDPCM_DATA_CHANNEL) &&
3865 (chan != SDPCM_EVENT_CHANNEL)) {
3866 BRCMF_ERROR(("%s (subframe %d): bad channel"
3867 " %d\n", __func__, num, chan));
3868 errcode = -1;
3869 } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
3870 BRCMF_ERROR(("%s (subframe %d): Bad data offset"
3871 " %d: HW %d min %d\n",
3872 __func__, num, doff, sublen,
3873 SDPCM_HDRLEN));
3874 errcode = -1;
3875 }
3876 }
3877
3878 if (errcode) {
3879 /* Terminate frame on error, request
3880 a couple retries */
3881 if (bus->glomerr++ < 3) {
3882 /* Restore superframe header space */
3883 skb_push(pfirst, sfdoff);
3884 brcmf_sdbrcm_rxfail(bus, true, true);
3885 } else {
3886 bus->glomerr = 0;
3887 brcmf_sdbrcm_rxfail(bus, true, false);
3888 brcmu_pkt_buf_free_skb(bus->glom);
3889 bus->rxglomfail++;
3890 bus->glom = NULL;
3891 }
3892 bus->nextlen = 0;
3893 return 0;
3894 }
3895
3896 /* Basic SD framing looks ok - process each packet (header) */
3897 save_pfirst = pfirst;
3898 bus->glom = NULL;
3899 plast = NULL;
3900
3901 for (num = 0; pfirst; rxseq++, pfirst = pnext) {
3902 pnext = pfirst->next;
3903 pfirst->next = NULL;
3904
3905 dptr = (u8 *) (pfirst->data);
3906 sublen = get_unaligned_le16(dptr);
3907 chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
3908 seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
3909 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
3910
3911 BRCMF_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d "
3912 "chan %d seq %d\n",
3913 __func__, num, pfirst, pfirst->data,
3914 pfirst->len, sublen, chan, seq));
3915
3916 /* precondition: chan == SDPCM_DATA_CHANNEL ||
3917 chan == SDPCM_EVENT_CHANNEL */
3918
3919 if (rxseq != seq) {
3920 BRCMF_GLOM(("%s: rx_seq %d, expected %d\n",
3921 __func__, seq, rxseq));
3922 bus->rx_badseq++;
3923 rxseq = seq;
3924 }
3925#ifdef BCMDBG
3926 if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
3927 printk(KERN_DEBUG "Rx Subframe Data:\n");
3928 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
3929 dptr, dlen);
3930 }
3931#endif
3932
3933 __skb_trim(pfirst, sublen);
3934 skb_pull(pfirst, doff);
3935
3936 if (pfirst->len == 0) {
3937 brcmu_pkt_buf_free_skb(pfirst);
3938 if (plast) {
3939 plast->next = pnext;
3940 } else {
3941 save_pfirst = pnext;
3942 }
3943 continue;
3944 } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pfirst)
3945 != 0) {
3946 BRCMF_ERROR(("%s: rx protocol error\n",
3947 __func__));
3948 bus->drvr->rx_errors++;
3949 brcmu_pkt_buf_free_skb(pfirst);
3950 if (plast) {
3951 plast->next = pnext;
3952 } else {
3953 save_pfirst = pnext;
3954 }
3955 continue;
3956 }
3957
3958 /* this packet will go up, link back into
3959 chain and count it */
3960 pfirst->next = pnext;
3961 plast = pfirst;
3962 num++;
3963
3964#ifdef BCMDBG
3965 if (BRCMF_GLOM_ON()) {
3966 BRCMF_GLOM(("%s subframe %d to stack, %p"
3967 "(%p/%d) nxt/lnk %p/%p\n",
3968 __func__, num, pfirst, pfirst->data,
3969 pfirst->len, pfirst->next,
3970 pfirst->prev));
3971 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
3972 pfirst->data,
3973 min_t(int, pfirst->len, 32));
3974 }
3975#endif /* BCMDBG */
3976 }
3977 if (num) {
3978 brcmf_sdbrcm_sdunlock(bus);
3979 brcmf_rx_frame(bus->drvr, ifidx, save_pfirst, num);
3980 brcmf_sdbrcm_sdlock(bus);
3981 }
3982
3983 bus->rxglomframes++;
3984 bus->rxglompkts += num;
3985 }
3986 return num;
3987}
3988
3989/* Return true if there may be more frames to read */
3990static uint
3991brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished)
3992{
3993 struct brcmf_sdio_card *card = bus->card;
3994
3995 u16 len, check; /* Extracted hardware header fields */
3996 u8 chan, seq, doff; /* Extracted software header fields */
3997 u8 fcbits; /* Extracted fcbits from software header */
3998
3999 struct sk_buff *pkt; /* Packet for event or data frames */
4000 u16 pad; /* Number of pad bytes to read */
4001 u16 rdlen; /* Total number of bytes to read */
4002 u8 rxseq; /* Next sequence number to expect */
4003 uint rxleft = 0; /* Remaining number of frames allowed */
4004 int sdret; /* Return code from calls */
4005 u8 txmax; /* Maximum tx sequence offered */
4006 bool len_consistent; /* Result of comparing readahead len and
4007 len from hw-hdr */
4008 u8 *rxbuf;
4009 int ifidx = 0;
4010 uint rxcount = 0; /* Total frames read */
4011
4012#if defined(BCMDBG) || defined(SDTEST)
4013 bool sdtest = false; /* To limit message spew from test mode */
4014#endif
4015
4016 BRCMF_TRACE(("%s: Enter\n", __func__));
4017
4018#ifdef SDTEST
4019 /* Allow pktgen to override maxframes */
4020 if (bus->pktgen_count && (bus->pktgen_mode == BRCMF_PKTGEN_RECV)) {
4021 maxframes = bus->pktgen_count;
4022 sdtest = true;
4023 }
4024#endif
4025
4026 /* Not finished unless we encounter no more frames indication */
4027 *finished = false;
4028
4029 for (rxseq = bus->rx_seq, rxleft = maxframes;
4030 !bus->rxskip && rxleft && bus->drvr->busstate != BRCMF_BUS_DOWN;
4031 rxseq++, rxleft--) {
4032
4033 /* Handle glomming separately */
4034 if (bus->glom || bus->glomd) {
4035 u8 cnt;
4036 BRCMF_GLOM(("%s: calling rxglom: glomd %p, glom %p\n",
4037 __func__, bus->glomd, bus->glom));
4038 cnt = brcmf_sdbrcm_rxglom(bus, rxseq);
4039 BRCMF_GLOM(("%s: rxglom returned %d\n", __func__, cnt));
4040 rxseq += cnt - 1;
4041 rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
4042 continue;
4043 }
4044
4045 /* Try doing single read if we can */
4046 if (brcmf_readahead && bus->nextlen) {
4047 u16 nextlen = bus->nextlen;
4048 bus->nextlen = 0;
4049
4050 if (bus->bus == SPI_BUS) {
4051 rdlen = len = nextlen;
4052 } else {
4053 rdlen = len = nextlen << 4;
4054
4055 /* Pad read to blocksize for efficiency */
4056 if (bus->roundup && bus->blocksize
4057 && (rdlen > bus->blocksize)) {
4058 pad =
4059 bus->blocksize -
4060 (rdlen % bus->blocksize);
4061 if ((pad <= bus->roundup)
4062 && (pad < bus->blocksize)
4063 && ((rdlen + pad + firstread) <
4064 MAX_RX_DATASZ))
4065 rdlen += pad;
4066 } else if (rdlen % BRCMF_SDALIGN) {
4067 rdlen +=
4068 BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
4069 }
4070 }
4071
4072 /* We use bus->rxctl buffer in WinXP for initial
4073 * control pkt receives.
4074 * Later we use buffer-poll for data as well
4075 * as control packets.
4076 * This is required because dhd receives full
4077 * frame in gSPI unlike SDIO.
4078 * After the frame is received we have to
4079 * distinguish whether it is data
4080 * or non-data frame.
4081 */
4082 /* Allocate a packet buffer */
4083 pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN);
4084 if (!pkt) {
4085 if (bus->bus == SPI_BUS) {
4086 bus->usebufpool = false;
4087 bus->rxctl = bus->rxbuf;
4088 if (brcmf_alignctl) {
4089 bus->rxctl += firstread;
4090 pad = ((unsigned long)bus->rxctl %
4091 BRCMF_SDALIGN);
4092 if (pad)
4093 bus->rxctl +=
4094 (BRCMF_SDALIGN - pad);
4095 bus->rxctl -= firstread;
4096 }
4097 rxbuf = bus->rxctl;
4098 /* Read the entire frame */
4099 sdret = brcmf_sdcard_recv_buf(card,
4100 brcmf_sdcard_cur_sbwad(card),
4101 SDIO_FUNC_2, F2SYNC,
4102 rxbuf, rdlen,
4103 NULL, NULL, NULL);
4104 bus->f2rxdata++;
4105
4106 /* Control frame failures need
4107 retransmission */
4108 if (sdret < 0) {
4109 BRCMF_ERROR(("%s: read %d "
4110 "control bytes "
4111 "failed: %d\n",
4112 __func__,
4113 rdlen, sdret));
4114 /* dhd.rx_ctlerrs is higher */
4115 bus->rxc_errors++;
4116 brcmf_sdbrcm_rxfail(bus, true,
4117 (bus->bus ==
4118 SPI_BUS) ? false
4119 : true);
4120 continue;
4121 }
4122 } else {
4123 /* Give up on data,
4124 request rtx of events */
4125 BRCMF_ERROR(("%s (nextlen): "
4126 "brcmu_pkt_buf_get_skb "
4127 "failed:"
4128 " len %d rdlen %d expected"
4129 " rxseq %d\n", __func__,
4130 len, rdlen, rxseq));
4131 continue;
4132 }
4133 } else {
4134 if (bus->bus == SPI_BUS)
4135 bus->usebufpool = true;
4136
4137 PKTALIGN(pkt, rdlen, BRCMF_SDALIGN);
4138 rxbuf = (u8 *) (pkt->data);
4139 /* Read the entire frame */
4140 sdret = brcmf_sdcard_recv_buf(card,
4141 brcmf_sdcard_cur_sbwad(card),
4142 SDIO_FUNC_2, F2SYNC,
4143 rxbuf, rdlen,
4144 pkt, NULL, NULL);
4145 bus->f2rxdata++;
4146
4147 if (sdret < 0) {
4148 BRCMF_ERROR(("%s (nextlen): read %d"
4149 " bytes failed: %d\n",
4150 __func__, rdlen, sdret));
4151 brcmu_pkt_buf_free_skb(pkt);
4152 bus->drvr->rx_errors++;
4153 /* Force retry w/normal header read.
4154 * Don't attempt NAK for
4155 * gSPI
4156 */
4157 brcmf_sdbrcm_rxfail(bus, true,
4158 (bus->bus ==
4159 SPI_BUS) ? false :
4160 true);
4161 continue;
4162 }
4163 }
4164
4165 /* Now check the header */
4166 memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
4167
4168 /* Extract hardware header fields */
4169 len = get_unaligned_le16(bus->rxhdr);
4170 check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
4171
4172 /* All zeros means readahead info was bad */
4173 if (!(len | check)) {
4174 BRCMF_INFO(("%s (nextlen): read zeros in HW "
4175 "header???\n", __func__));
4176 brcmf_sdbrcm_pktfree2(bus, pkt);
4177 continue;
4178 }
4179
4180 /* Validate check bytes */
4181 if ((u16)~(len ^ check)) {
4182 BRCMF_ERROR(("%s (nextlen): HW hdr error:"
4183 " nextlen/len/check"
4184 " 0x%04x/0x%04x/0x%04x\n",
4185 __func__, nextlen, len, check));
4186 bus->rx_badhdr++;
4187 brcmf_sdbrcm_rxfail(bus, false, false);
4188 brcmf_sdbrcm_pktfree2(bus, pkt);
4189 continue;
4190 }
4191
4192 /* Validate frame length */
4193 if (len < SDPCM_HDRLEN) {
4194 BRCMF_ERROR(("%s (nextlen): HW hdr length "
4195 "invalid: %d\n", __func__, len));
4196 brcmf_sdbrcm_pktfree2(bus, pkt);
4197 continue;
4198 }
4199
4200 /* Check for consistency withreadahead info */
4201 len_consistent = (nextlen != (roundup(len, 16) >> 4));
4202 if (len_consistent) {
4203 /* Mismatch, force retry w/normal
4204 header (may be >4K) */
4205 BRCMF_ERROR(("%s (nextlen): mismatch, "
4206 "nextlen %d len %d rnd %d; "
4207 "expected rxseq %d\n",
4208 __func__, nextlen,
4209 len, roundup(len, 16), rxseq));
4210 brcmf_sdbrcm_rxfail(bus, true,
4211 bus->bus != SPI_BUS);
4212 brcmf_sdbrcm_pktfree2(bus, pkt);
4213 continue;
4214 }
4215
4216 /* Extract software header fields */
4217 chan = SDPCM_PACKET_CHANNEL(
4218 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4219 seq = SDPCM_PACKET_SEQUENCE(
4220 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4221 doff = SDPCM_DOFFSET_VALUE(
4222 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4223 txmax = SDPCM_WINDOW_VALUE(
4224 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4225
4226 bus->nextlen =
4227 bus->rxhdr[SDPCM_FRAMETAG_LEN +
4228 SDPCM_NEXTLEN_OFFSET];
4229 if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
4230 BRCMF_INFO(("%s (nextlen): got frame w/nextlen"
4231 " too large (%d), seq %d\n",
4232 __func__, bus->nextlen, seq));
4233 bus->nextlen = 0;
4234 }
4235
4236 bus->drvr->rx_readahead_cnt++;
4237
4238 /* Handle Flow Control */
4239 fcbits = SDPCM_FCMASK_VALUE(
4240 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4241
4242 if (bus->flowcontrol != fcbits) {
4243 if (~bus->flowcontrol & fcbits)
4244 bus->fc_xoff++;
4245
4246 if (bus->flowcontrol & ~fcbits)
4247 bus->fc_xon++;
4248
4249 bus->fc_rcvd++;
4250 bus->flowcontrol = fcbits;
4251 }
4252
4253 /* Check and update sequence number */
4254 if (rxseq != seq) {
4255 BRCMF_INFO(("%s (nextlen): rx_seq %d, expected "
4256 "%d\n", __func__, seq, rxseq));
4257 bus->rx_badseq++;
4258 rxseq = seq;
4259 }
4260
4261 /* Check window for sanity */
4262 if ((u8) (txmax - bus->tx_seq) > 0x40) {
4263 BRCMF_ERROR(("%s: got unlikely tx max %d with "
4264 "tx_seq %d\n",
4265 __func__, txmax, bus->tx_seq));
4266 txmax = bus->tx_seq + 2;
4267 }
4268 bus->tx_max = txmax;
4269
4270#ifdef BCMDBG
4271 if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
4272 printk(KERN_DEBUG "Rx Data:\n");
4273 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
4274 rxbuf, len);
4275 } else if (BRCMF_HDRS_ON()) {
4276 printk(KERN_DEBUG "RxHdr:\n");
4277 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
4278 bus->rxhdr, SDPCM_HDRLEN);
4279 }
4280#endif
4281
4282 if (chan == SDPCM_CONTROL_CHANNEL) {
4283 if (bus->bus == SPI_BUS) {
4284 brcmf_sdbrcm_read_control(bus, rxbuf,
4285 len, doff);
4286 } else {
4287 BRCMF_ERROR(("%s (nextlen): readahead"
4288 " on control packet %d?\n",
4289 __func__, seq));
4290 /* Force retry w/normal header read */
4291 bus->nextlen = 0;
4292 brcmf_sdbrcm_rxfail(bus, false, true);
4293 }
4294 brcmf_sdbrcm_pktfree2(bus, pkt);
4295 continue;
4296 }
4297
4298 if ((bus->bus == SPI_BUS) && !bus->usebufpool) {
4299 BRCMF_ERROR(("Received %d bytes on %d channel."
4300 " Running out of " "rx pktbuf's or"
4301 " not yet malloced.\n",
4302 len, chan));
4303 continue;
4304 }
4305
4306 /* Validate data offset */
4307 if ((doff < SDPCM_HDRLEN) || (doff > len)) {
4308 BRCMF_ERROR(("%s (nextlen): bad data offset %d:"
4309 " HW len %d min %d\n", __func__,
4310 doff, len, SDPCM_HDRLEN));
4311 brcmf_sdbrcm_rxfail(bus, false, false);
4312 brcmf_sdbrcm_pktfree2(bus, pkt);
4313 continue;
4314 }
4315
4316 /* All done with this one -- now deliver the packet */
4317 goto deliver;
4318 }
4319 /* gSPI frames should not be handled in fractions */
4320 if (bus->bus == SPI_BUS)
4321 break;
4322
4323 /* Read frame header (hardware and software) */
4324 sdret = brcmf_sdcard_recv_buf(card,
4325 brcmf_sdcard_cur_sbwad(card),
4326 SDIO_FUNC_2, F2SYNC, bus->rxhdr, firstread,
4327 NULL, NULL, NULL);
4328 bus->f2rxhdrs++;
4329
4330 if (sdret < 0) {
4331 BRCMF_ERROR(("%s: RXHEADER FAILED: %d\n", __func__,
4332 sdret));
4333 bus->rx_hdrfail++;
4334 brcmf_sdbrcm_rxfail(bus, true, true);
4335 continue;
4336 }
4337#ifdef BCMDBG
4338 if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) {
4339 printk(KERN_DEBUG "RxHdr:\n");
4340 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
4341 bus->rxhdr, SDPCM_HDRLEN);
4342 }
4343#endif
4344
4345 /* Extract hardware header fields */
4346 len = get_unaligned_le16(bus->rxhdr);
4347 check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
4348
4349 /* All zeros means no more frames */
4350 if (!(len | check)) {
4351 *finished = true;
4352 break;
4353 }
4354
4355 /* Validate check bytes */
4356 if ((u16) ~(len ^ check)) {
4357 BRCMF_ERROR(("%s: HW hdr err: len/check "
4358 "0x%04x/0x%04x\n", __func__, len, check));
4359 bus->rx_badhdr++;
4360 brcmf_sdbrcm_rxfail(bus, false, false);
4361 continue;
4362 }
4363
4364 /* Validate frame length */
4365 if (len < SDPCM_HDRLEN) {
4366 BRCMF_ERROR(("%s: HW hdr length invalid: %d\n",
4367 __func__, len));
4368 continue;
4369 }
4370
4371 /* Extract software header fields */
4372 chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4373 seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4374 doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4375 txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4376
4377 /* Validate data offset */
4378 if ((doff < SDPCM_HDRLEN) || (doff > len)) {
4379 BRCMF_ERROR(("%s: Bad data offset %d: HW len %d,"
4380 " min %d seq %d\n", __func__, doff,
4381 len, SDPCM_HDRLEN, seq));
4382 bus->rx_badhdr++;
4383 brcmf_sdbrcm_rxfail(bus, false, false);
4384 continue;
4385 }
4386
4387 /* Save the readahead length if there is one */
4388 bus->nextlen =
4389 bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
4390 if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
4391 BRCMF_INFO(("%s (nextlen): got frame w/nextlen too"
4392 " large (%d), seq %d\n",
4393 __func__, bus->nextlen, seq));
4394 bus->nextlen = 0;
4395 }
4396
4397 /* Handle Flow Control */
4398 fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
4399
4400 if (bus->flowcontrol != fcbits) {
4401 if (~bus->flowcontrol & fcbits)
4402 bus->fc_xoff++;
4403
4404 if (bus->flowcontrol & ~fcbits)
4405 bus->fc_xon++;
4406
4407 bus->fc_rcvd++;
4408 bus->flowcontrol = fcbits;
4409 }
4410
4411 /* Check and update sequence number */
4412 if (rxseq != seq) {
4413 BRCMF_INFO(("%s: rx_seq %d, expected %d\n", __func__,
4414 seq, rxseq));
4415 bus->rx_badseq++;
4416 rxseq = seq;
4417 }
4418
4419 /* Check window for sanity */
4420 if ((u8) (txmax - bus->tx_seq) > 0x40) {
4421 BRCMF_ERROR(("%s: unlikely tx max %d with tx_seq %d\n",
4422 __func__, txmax, bus->tx_seq));
4423 txmax = bus->tx_seq + 2;
4424 }
4425 bus->tx_max = txmax;
4426
4427 /* Call a separate function for control frames */
4428 if (chan == SDPCM_CONTROL_CHANNEL) {
4429 brcmf_sdbrcm_read_control(bus, bus->rxhdr, len, doff);
4430 continue;
4431 }
4432
4433 /* precondition: chan is either SDPCM_DATA_CHANNEL,
4434 SDPCM_EVENT_CHANNEL, SDPCM_TEST_CHANNEL or
4435 SDPCM_GLOM_CHANNEL */
4436
4437 /* Length to read */
4438 rdlen = (len > firstread) ? (len - firstread) : 0;
4439
4440 /* May pad read to blocksize for efficiency */
4441 if (bus->roundup && bus->blocksize &&
4442 (rdlen > bus->blocksize)) {
4443 pad = bus->blocksize - (rdlen % bus->blocksize);
4444 if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
4445 ((rdlen + pad + firstread) < MAX_RX_DATASZ))
4446 rdlen += pad;
4447 } else if (rdlen % BRCMF_SDALIGN) {
4448 rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
4449 }
4450
4451 /* Satisfy length-alignment requirements */
4452 if (forcealign && (rdlen & (ALIGNMENT - 1)))
4453 rdlen = roundup(rdlen, ALIGNMENT);
4454
4455 if ((rdlen + firstread) > MAX_RX_DATASZ) {
4456 /* Too long -- skip this frame */
4457 BRCMF_ERROR(("%s: too long: len %d rdlen %d\n",
4458 __func__, len, rdlen));
4459 bus->drvr->rx_errors++;
4460 bus->rx_toolong++;
4461 brcmf_sdbrcm_rxfail(bus, false, false);
4462 continue;
4463 }
4464
4465 pkt = brcmu_pkt_buf_get_skb(rdlen + firstread + BRCMF_SDALIGN);
4466 if (!pkt) {
4467 /* Give up on data, request rtx of events */
4468 BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed:"
4469 " rdlen %d chan %d\n", __func__, rdlen,
4470 chan));
4471 bus->drvr->rx_dropped++;
4472 brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan));
4473 continue;
4474 }
4475
4476 /* Leave room for what we already read, and align remainder */
4477 skb_pull(pkt, firstread);
4478 PKTALIGN(pkt, rdlen, BRCMF_SDALIGN);
4479
4480 /* Read the remaining frame data */
4481 sdret = brcmf_sdcard_recv_buf(card,
4482 brcmf_sdcard_cur_sbwad(card),
4483 SDIO_FUNC_2, F2SYNC, ((u8 *) (pkt->data)),
4484 rdlen, pkt, NULL, NULL);
4485 bus->f2rxdata++;
4486
4487 if (sdret < 0) {
4488 BRCMF_ERROR(("%s: read %d %s bytes failed: %d\n",
4489 __func__, rdlen,
4490 ((chan == SDPCM_EVENT_CHANNEL) ? "event"
4491 : ((chan == SDPCM_DATA_CHANNEL) ? "data"
4492 : "test")), sdret));
4493 brcmu_pkt_buf_free_skb(pkt);
4494 bus->drvr->rx_errors++;
4495 brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan));
4496 continue;
4497 }
4498
4499 /* Copy the already-read portion */
4500 skb_push(pkt, firstread);
4501 memcpy(pkt->data, bus->rxhdr, firstread);
4502
4503#ifdef BCMDBG
4504 if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
4505 printk(KERN_DEBUG "Rx Data:\n");
4506 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
4507 pkt->data, len);
4508 }
4509#endif
4510
4511deliver:
4512 /* Save superframe descriptor and allocate packet frame */
4513 if (chan == SDPCM_GLOM_CHANNEL) {
4514 if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
4515 BRCMF_GLOM(("%s: glom descriptor, %d bytes:\n",
4516 __func__, len));
4517#ifdef BCMDBG
4518 if (BRCMF_GLOM_ON()) {
4519 printk(KERN_DEBUG "Glom Data:\n");
4520 print_hex_dump_bytes("",
4521 DUMP_PREFIX_OFFSET,
4522 pkt->data, len);
4523 }
4524#endif
4525 __skb_trim(pkt, len);
4526 skb_pull(pkt, SDPCM_HDRLEN);
4527 bus->glomd = pkt;
4528 } else {
4529 BRCMF_ERROR(("%s: glom superframe w/o "
4530 "descriptor!\n", __func__));
4531 brcmf_sdbrcm_rxfail(bus, false, false);
4532 }
4533 continue;
4534 }
4535
4536 /* Fill in packet len and prio, deliver upward */
4537 __skb_trim(pkt, len);
4538 skb_pull(pkt, doff);
4539
4540#ifdef SDTEST
4541 /* Test channel packets are processed separately */
4542 if (chan == SDPCM_TEST_CHANNEL) {
4543 brcmf_sdbrcm_checkdied(bus, pkt, seq);
4544 continue;
4545 }
4546#endif /* SDTEST */
4547
4548 if (pkt->len == 0) {
4549 brcmu_pkt_buf_free_skb(pkt);
4550 continue;
4551 } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pkt) != 0) {
4552 BRCMF_ERROR(("%s: rx protocol error\n", __func__));
4553 brcmu_pkt_buf_free_skb(pkt);
4554 bus->drvr->rx_errors++;
4555 continue;
4556 }
4557
4558 /* Unlock during rx call */
4559 brcmf_sdbrcm_sdunlock(bus);
4560 brcmf_rx_frame(bus->drvr, ifidx, pkt, 1);
4561 brcmf_sdbrcm_sdlock(bus);
4562 }
4563 rxcount = maxframes - rxleft;
4564#ifdef BCMDBG
4565 /* Message if we hit the limit */
4566 if (!rxleft && !sdtest)
4567 BRCMF_DATA(("%s: hit rx limit of %d frames\n", __func__,
4568 maxframes));
4569 else
4570#endif /* BCMDBG */
4571 BRCMF_DATA(("%s: processed %d frames\n", __func__, rxcount));
4572 /* Back off rxseq if awaiting rtx, update rx_seq */
4573 if (bus->rxskip)
4574 rxseq--;
4575 bus->rx_seq = rxseq;
4576
4577 return rxcount;
4578}
4579
4580static u32 brcmf_sdbrcm_hostmail(struct brcmf_bus *bus)
4581{
4582 u32 intstatus = 0;
4583 u32 hmb_data;
4584 u8 fcbits;
4585 uint retries = 0;
4586
4587 BRCMF_TRACE(("%s: Enter\n", __func__));
4588
4589 /* Read mailbox data and ack that we did so */
4590 r_sdreg32(bus, &hmb_data,
4591 offsetof(struct sdpcmd_regs, tohostmailboxdata), &retries);
4592
4593 if (retries <= retry_limit)
4594 w_sdreg32(bus, SMB_INT_ACK,
4595 offsetof(struct sdpcmd_regs, tosbmailbox), &retries);
4596 bus->f1regdata += 2;
4597
4598 /* Dongle recomposed rx frames, accept them again */
4599 if (hmb_data & HMB_DATA_NAKHANDLED) {
4600 BRCMF_INFO(("Dongle reports NAK handled, expect rtx of %d\n",
4601 bus->rx_seq));
4602 if (!bus->rxskip)
4603 BRCMF_ERROR(("%s: unexpected NAKHANDLED!\n", __func__));
4604
4605 bus->rxskip = false;
4606 intstatus |= I_HMB_FRAME_IND;
4607 }
4608
4609 /*
4610 * DEVREADY does not occur with gSPI.
4611 */
4612 if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
4613 bus->sdpcm_ver =
4614 (hmb_data & HMB_DATA_VERSION_MASK) >>
4615 HMB_DATA_VERSION_SHIFT;
4616 if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
4617 BRCMF_ERROR(("Version mismatch, dongle reports %d, "
4618 "expecting %d\n",
4619 bus->sdpcm_ver, SDPCM_PROT_VERSION));
4620 else
4621 BRCMF_INFO(("Dongle ready, protocol version %d\n",
4622 bus->sdpcm_ver));
4623 }
4624
4625 /*
4626 * Flow Control has been moved into the RX headers and this out of band
4627 * method isn't used any more.
4628 * remaining backward compatible with older dongles.
4629 */
4630 if (hmb_data & HMB_DATA_FC) {
4631 fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
4632 HMB_DATA_FCDATA_SHIFT;
4633
4634 if (fcbits & ~bus->flowcontrol)
4635 bus->fc_xoff++;
4636
4637 if (bus->flowcontrol & ~fcbits)
4638 bus->fc_xon++;
4639
4640 bus->fc_rcvd++;
4641 bus->flowcontrol = fcbits;
4642 }
4643
4644 /* Shouldn't be any others */
4645 if (hmb_data & ~(HMB_DATA_DEVREADY |
4646 HMB_DATA_NAKHANDLED |
4647 HMB_DATA_FC |
4648 HMB_DATA_FWREADY |
4649 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) {
4650 BRCMF_ERROR(("Unknown mailbox data content: 0x%02x\n",
4651 hmb_data));
4652 }
4653
4654 return intstatus;
4655}
4656
4657static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus)
4658{
4659 struct brcmf_sdio_card *card = bus->card;
4660 u32 intstatus, newstatus = 0;
4661 uint retries = 0;
4662 uint rxlimit = brcmf_rxbound; /* Rx frames to read before resched */
4663 uint txlimit = brcmf_txbound; /* Tx frames to send before resched */
4664 uint framecnt = 0; /* Temporary counter of tx/rx frames */
4665 bool rxdone = true; /* Flag for no more read data */
4666 bool resched = false; /* Flag indicating resched wanted */
4667
4668 BRCMF_TRACE(("%s: Enter\n", __func__));
4669
4670 /* Start with leftover status bits */
4671 intstatus = bus->intstatus;
4672
4673 brcmf_sdbrcm_sdlock(bus);
4674
4675 /* If waiting for HTAVAIL, check status */
4676 if (bus->clkstate == CLK_PENDING) {
4677 int err;
4678 u8 clkctl, devctl = 0;
4679
4680#ifdef BCMDBG
4681 /* Check for inconsistent device control */
4682 devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
4683 SBSDIO_DEVICE_CTL, &err);
4684 if (err) {
4685 BRCMF_ERROR(("%s: error reading DEVCTL: %d\n",
4686 __func__, err));
4687 bus->drvr->busstate = BRCMF_BUS_DOWN;
4688 }
4689#endif /* BCMDBG */
4690
4691 /* Read CSR, if clock on switch to AVAIL, else ignore */
4692 clkctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
4693 SBSDIO_FUNC1_CHIPCLKCSR, &err);
4694 if (err) {
4695 BRCMF_ERROR(("%s: error reading CSR: %d\n", __func__,
4696 err));
4697 bus->drvr->busstate = BRCMF_BUS_DOWN;
4698 }
4699
4700 BRCMF_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
4701 devctl, clkctl));
4702
4703 if (SBSDIO_HTAV(clkctl)) {
4704 devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
4705 SBSDIO_DEVICE_CTL, &err);
4706 if (err) {
4707 BRCMF_ERROR(("%s: error reading DEVCTL: %d\n",
4708 __func__, err));
4709 bus->drvr->busstate = BRCMF_BUS_DOWN;
4710 }
4711 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
4712 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
4713 SBSDIO_DEVICE_CTL, devctl, &err);
4714 if (err) {
4715 BRCMF_ERROR(("%s: error writing DEVCTL: %d\n",
4716 __func__, err));
4717 bus->drvr->busstate = BRCMF_BUS_DOWN;
4718 }
4719 bus->clkstate = CLK_AVAIL;
4720 } else {
4721 goto clkwait;
4722 }
4723 }
4724
4725 BUS_WAKE(bus);
4726
4727 /* Make sure backplane clock is on */
4728 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true);
4729 if (bus->clkstate == CLK_PENDING)
4730 goto clkwait;
4731
4732 /* Pending interrupt indicates new device status */
4733 if (bus->ipend) {
4734 bus->ipend = false;
4735 r_sdreg32(bus, &newstatus,
4736 offsetof(struct sdpcmd_regs, intstatus), &retries);
4737 bus->f1regdata++;
4738 if (brcmf_sdcard_regfail(bus->card))
4739 newstatus = 0;
4740 newstatus &= bus->hostintmask;
4741 bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
4742 if (newstatus) {
4743 w_sdreg32(bus, newstatus,
4744 offsetof(struct sdpcmd_regs, intstatus),
4745 &retries);
4746 bus->f1regdata++;
4747 }
4748 }
4749
4750 /* Merge new bits with previous */
4751 intstatus |= newstatus;
4752 bus->intstatus = 0;
4753
4754 /* Handle flow-control change: read new state in case our ack
4755 * crossed another change interrupt. If change still set, assume
4756 * FC ON for safety, let next loop through do the debounce.
4757 */
4758 if (intstatus & I_HMB_FC_CHANGE) {
4759 intstatus &= ~I_HMB_FC_CHANGE;
4760 w_sdreg32(bus, I_HMB_FC_CHANGE,
4761 offsetof(struct sdpcmd_regs, intstatus), &retries);
4762
4763 r_sdreg32(bus, &newstatus,
4764 offsetof(struct sdpcmd_regs, intstatus), &retries);
4765 bus->f1regdata += 2;
4766 bus->fcstate =
4767 !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
4768 intstatus |= (newstatus & bus->hostintmask);
4769 }
4770
4771 /* Handle host mailbox indication */
4772 if (intstatus & I_HMB_HOST_INT) {
4773 intstatus &= ~I_HMB_HOST_INT;
4774 intstatus |= brcmf_sdbrcm_hostmail(bus);
4775 }
4776
4777 /* Generally don't ask for these, can get CRC errors... */
4778 if (intstatus & I_WR_OOSYNC) {
4779 BRCMF_ERROR(("Dongle reports WR_OOSYNC\n"));
4780 intstatus &= ~I_WR_OOSYNC;
4781 }
4782
4783 if (intstatus & I_RD_OOSYNC) {
4784 BRCMF_ERROR(("Dongle reports RD_OOSYNC\n"));
4785 intstatus &= ~I_RD_OOSYNC;
4786 }
4787
4788 if (intstatus & I_SBINT) {
4789 BRCMF_ERROR(("Dongle reports SBINT\n"));
4790 intstatus &= ~I_SBINT;
4791 }
4792
4793 /* Would be active due to wake-wlan in gSPI */
4794 if (intstatus & I_CHIPACTIVE) {
4795 BRCMF_INFO(("Dongle reports CHIPACTIVE\n"));
4796 intstatus &= ~I_CHIPACTIVE;
4797 }
4798
4799 /* Ignore frame indications if rxskip is set */
4800 if (bus->rxskip)
4801 intstatus &= ~I_HMB_FRAME_IND;
4802
4803 /* On frame indication, read available frames */
4804 if (PKT_AVAILABLE()) {
4805 framecnt = brcmf_sdbrcm_readframes(bus, rxlimit, &rxdone);
4806 if (rxdone || bus->rxskip)
4807 intstatus &= ~I_HMB_FRAME_IND;
4808 rxlimit -= min(framecnt, rxlimit);
4809 }
4810
4811 /* Keep still-pending events for next scheduling */
4812 bus->intstatus = intstatus;
4813
4814clkwait:
4815 /* Re-enable interrupts to detect new device events (mailbox, rx frame)
4816 * or clock availability. (Allows tx loop to check ipend if desired.)
4817 * (Unless register access seems hosed, as we may not be able to ACK...)
4818 */
4819 if (bus->intr && bus->intdis && !brcmf_sdcard_regfail(card)) {
4820 BRCMF_INTR(("%s: enable SDIO interrupts, rxdone %d"
4821 " framecnt %d\n", __func__, rxdone, framecnt));
4822 bus->intdis = false;
4823 brcmf_sdcard_intr_enable(card);
4824 }
4825
4826 if (DATAOK(bus) && bus->ctrl_frame_stat &&
4827 (bus->clkstate == CLK_AVAIL)) {
4828 int ret, i;
4829
4830 ret = brcmf_sdbrcm_send_buf(bus, brcmf_sdcard_cur_sbwad(card),
4831 SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf,
4832 (u32) bus->ctrl_frame_len, NULL, NULL, NULL);
4833
4834 if (ret < 0) {
4835 /* On failure, abort the command and
4836 terminate the frame */
4837 BRCMF_INFO(("%s: sdio error %d, abort command and "
4838 "terminate frame.\n", __func__, ret));
4839 bus->tx_sderrs++;
4840
4841 brcmf_sdcard_abort(card, SDIO_FUNC_2);
4842
4843 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
4844 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
4845 NULL);
4846 bus->f1regdata++;
4847
4848 for (i = 0; i < 3; i++) {
4849 u8 hi, lo;
4850 hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
4851 SBSDIO_FUNC1_WFRAMEBCHI,
4852 NULL);
4853 lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
4854 SBSDIO_FUNC1_WFRAMEBCLO,
4855 NULL);
4856 bus->f1regdata += 2;
4857 if ((hi == 0) && (lo == 0))
4858 break;
4859 }
4860
4861 }
4862 if (ret == 0)
4863 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
4864
4865 BRCMF_INFO(("Return_dpc value is : %d\n", ret));
4866 bus->ctrl_frame_stat = false;
4867 brcmf_sdbrcm_wait_event_wakeup(bus);
4868 }
4869 /* Send queued frames (limit 1 if rx may still be pending) */
4870 else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
4871 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
4872 && DATAOK(bus)) {
4873 framecnt = rxdone ? txlimit : min(txlimit, brcmf_txminmax);
4874 framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt);
4875 txlimit -= framecnt;
4876 }
4877
4878 /* Resched if events or tx frames are pending,
4879 else await next interrupt */
4880 /* On failed register access, all bets are off:
4881 no resched or interrupts */
4882 if ((bus->drvr->busstate == BRCMF_BUS_DOWN) ||
4883 brcmf_sdcard_regfail(card)) {
4884 BRCMF_ERROR(("%s: failed backplane access over SDIO, halting "
4885 "operation %d\n", __func__,
4886 brcmf_sdcard_regfail(card)));
4887 bus->drvr->busstate = BRCMF_BUS_DOWN;
4888 bus->intstatus = 0;
4889 } else if (bus->clkstate == CLK_PENDING) {
4890 BRCMF_INFO(("%s: rescheduled due to CLK_PENDING awaiting "
4891 "I_CHIPACTIVE interrupt\n", __func__));
4892 resched = true;
4893 } else if (bus->intstatus || bus->ipend ||
4894 (!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)
4895 && DATAOK(bus)) || PKT_AVAILABLE()) {
4896 resched = true;
4897 }
4898
4899 bus->dpc_sched = resched;
4900
4901 /* If we're done for now, turn off clock request. */
4902 if ((bus->clkstate != CLK_PENDING)
4903 && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
4904 bus->activity = false;
4905 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
4906 }
4907
4908 brcmf_sdbrcm_sdunlock(bus);
4909
4910 return resched;
4911}
4912
4913void brcmf_sdbrcm_isr(void *arg)
4914{
4915 struct brcmf_bus *bus = (struct brcmf_bus *) arg;
4916 struct brcmf_sdio_card *card;
4917
4918 BRCMF_TRACE(("%s: Enter\n", __func__));
4919
4920 if (!bus) {
4921 BRCMF_ERROR(("%s : bus is null pointer , exit\n", __func__));
4922 return;
4923 }
4924 card = bus->card;
4925
4926 if (bus->drvr->busstate == BRCMF_BUS_DOWN) {
4927 BRCMF_ERROR(("%s : bus is down. we have nothing to do\n",
4928 __func__));
4929 return;
4930 }
4931 /* Count the interrupt call */
4932 bus->intrcount++;
4933 bus->ipend = true;
4934
4935 /* Shouldn't get this interrupt if we're sleeping? */
4936 if (bus->sleeping) {
4937 BRCMF_ERROR(("INTERRUPT WHILE SLEEPING??\n"));
4938 return;
4939 }
4940
4941 /* Disable additional interrupts (is this needed now)? */
4942 if (bus->intr)
4943 BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__));
4944 else
4945 BRCMF_ERROR(("brcmf_sdbrcm_isr() w/o interrupt configured!\n"));
4946
4947 brcmf_sdcard_intr_disable(card);
4948 bus->intdis = true;
4949
4950#if defined(SDIO_ISR_THREAD)
4951 BRCMF_TRACE(("Calling brcmf_sdbrcm_dpc() from %s\n", __func__));
4952 while (brcmf_sdbrcm_dpc(bus))
4953 ;
4954#else
4955 bus->dpc_sched = true;
4956 brcmf_sdbrcm_sched_dpc(bus);
4957#endif
4958
4959}
4960
4961#ifdef SDTEST
4962static void brcmf_sdbrcm_pktgen_init(struct brcmf_bus *bus)
4963{
4964 /* Default to specified length, or full range */
4965 if (brcmf_pktgen_len) {
4966 bus->pktgen_maxlen = min(brcmf_pktgen_len,
4967 BRCMF_MAX_PKTGEN_LEN);
4968 bus->pktgen_minlen = bus->pktgen_maxlen;
4969 } else {
4970 bus->pktgen_maxlen = BRCMF_MAX_PKTGEN_LEN;
4971 bus->pktgen_minlen = 0;
4972 }
4973 bus->pktgen_len = (u16) bus->pktgen_minlen;
4974
4975 /* Default to per-watchdog burst with 10s print time */
4976 bus->pktgen_freq = 1;
4977 bus->pktgen_print = 10000 / brcmf_watchdog_ms;
4978 bus->pktgen_count = (brcmf_pktgen * brcmf_watchdog_ms + 999) / 1000;
4979
4980 /* Default to echo mode */
4981 bus->pktgen_mode = BRCMF_PKTGEN_ECHO;
4982 bus->pktgen_stop = 1;
4983}
4984
4985static void brcmf_sdbrcm_pktgen(struct brcmf_bus *bus)
4986{
4987 struct sk_buff *pkt;
4988 u8 *data;
4989 uint pktcount;
4990 uint fillbyte;
4991 u16 len;
4992
4993 /* Display current count if appropriate */
4994 if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) {
4995 bus->pktgen_ptick = 0;
4996 printk(KERN_DEBUG "%s: send attempts %d rcvd %d\n",
4997 __func__, bus->pktgen_sent, bus->pktgen_rcvd);
4998 }
4999
5000 /* For recv mode, just make sure dongle has started sending */
5001 if (bus->pktgen_mode == BRCMF_PKTGEN_RECV) {
5002 if (!bus->pktgen_rcvd)
5003 brcmf_sdbrcm_sdtest_set(bus, true);
5004 return;
5005 }
5006
5007 /* Otherwise, generate or request the specified number of packets */
5008 for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) {
5009 /* Stop if total has been reached */
5010 if (bus->pktgen_total
5011 && (bus->pktgen_sent >= bus->pktgen_total)) {
5012 bus->pktgen_count = 0;
5013 break;
5014 }
5015
5016 /* Allocate an appropriate-sized packet */
5017 len = bus->pktgen_len;
5018 pkt = brcmu_pkt_buf_get_skb(
5019 len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + BRCMF_SDALIGN,
5020 true);
5021 if (!pkt) {
5022 BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed!\n",
5023 __func__));
5024 break;
5025 }
5026 PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN),
5027 BRCMF_SDALIGN);
5028 data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
5029
5030 /* Write test header cmd and extra based on mode */
5031 switch (bus->pktgen_mode) {
5032 case BRCMF_PKTGEN_ECHO:
5033 *data++ = SDPCM_TEST_ECHOREQ;
5034 *data++ = (u8) bus->pktgen_sent;
5035 break;
5036
5037 case BRCMF_PKTGEN_SEND:
5038 *data++ = SDPCM_TEST_DISCARD;
5039 *data++ = (u8) bus->pktgen_sent;
5040 break;
5041
5042 case BRCMF_PKTGEN_RXBURST:
5043 *data++ = SDPCM_TEST_BURST;
5044 *data++ = (u8) bus->pktgen_count;
5045 break;
5046
5047 default:
5048 BRCMF_ERROR(("Unrecognized pktgen mode %d\n",
5049 bus->pktgen_mode));
5050 brcmu_pkt_buf_free_skb(pkt, true);
5051 bus->pktgen_count = 0;
5052 return;
5053 }
5054
5055 /* Write test header length field */
5056 *data++ = (len >> 0);
5057 *data++ = (len >> 8);
5058
5059 /* Then fill in the remainder -- N/A for burst,
5060 but who cares... */
5061 for (fillbyte = 0; fillbyte < len; fillbyte++)
5062 *data++ =
5063 SDPCM_TEST_FILL(fillbyte, (u8) bus->pktgen_sent);
5064
5065#ifdef BCMDBG
5066 if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
5067 data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
5068 printk(KERN_DEBUG "brcmf_sdbrcm_pktgen: Tx Data:\n");
5069 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data,
5070 pkt->len - SDPCM_HDRLEN);
5071 }
5072#endif
5073
5074 /* Send it */
5075 if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) {
5076 bus->pktgen_fail++;
5077 if (bus->pktgen_stop
5078 && bus->pktgen_stop == bus->pktgen_fail)
5079 bus->pktgen_count = 0;
5080 }
5081 bus->pktgen_sent++;
5082
5083 /* Bump length if not fixed, wrap at max */
5084 if (++bus->pktgen_len > bus->pktgen_maxlen)
5085 bus->pktgen_len = (u16) bus->pktgen_minlen;
5086
5087 /* Special case for burst mode: just send one request! */
5088 if (bus->pktgen_mode == BRCMF_PKTGEN_RXBURST)
5089 break;
5090 }
5091}
5092
5093static void brcmf_sdbrcm_sdtest_set(struct brcmf_bus *bus, bool start)
5094{
5095 struct sk_buff *pkt;
5096 u8 *data;
5097
5098 /* Allocate the packet */
5099 pkt = brcmu_pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN +
5100 BRCMF_SDALIGN, true);
5101 if (!pkt) {
5102 BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed!\n", __func__));
5103 return;
5104 }
5105 PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), BRCMF_SDALIGN);
5106 data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
5107
5108 /* Fill in the test header */
5109 *data++ = SDPCM_TEST_SEND;
5110 *data++ = start;
5111 *data++ = (bus->pktgen_maxlen >> 0);
5112 *data++ = (bus->pktgen_maxlen >> 8);
5113
5114 /* Send it */
5115 if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true))
5116 bus->pktgen_fail++;
5117}
5118
5119static void
5120brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, struct sk_buff *pkt, uint seq)
5121{
5122 u8 *data;
5123 uint pktlen;
5124
5125 u8 cmd;
5126 u8 extra;
5127 u16 len;
5128 u16 offset;
5129
5130 /* Check for min length */
5131 pktlen = pkt->len;
5132 if (pktlen < SDPCM_TEST_HDRLEN) {
5133 BRCMF_ERROR(("brcmf_sdbrcm_checkdied: toss runt frame, pktlen "
5134 "%d\n", pktlen));
5135 brcmu_pkt_buf_free_skb(pkt, false);
5136 return;
5137 }
5138
5139 /* Extract header fields */
5140 data = pkt->data;
5141 cmd = *data++;
5142 extra = *data++;
5143 len = *data++;
5144 len += *data++ << 8;
5145
5146 /* Check length for relevant commands */
5147 if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ
5148 || cmd == SDPCM_TEST_ECHORSP) {
5149 if (pktlen != len + SDPCM_TEST_HDRLEN) {
5150 BRCMF_ERROR(("brcmf_sdbrcm_checkdied: frame length "
5151 "mismatch, pktlen %d seq %d"
5152 " cmd %d extra %d len %d\n",
5153 pktlen, seq, cmd, extra, len));
5154 brcmu_pkt_buf_free_skb(pkt, false);
5155 return;
5156 }
5157 }
5158
5159 /* Process as per command */
5160 switch (cmd) {
5161 case SDPCM_TEST_ECHOREQ:
5162 /* Rx->Tx turnaround ok (even on NDIS w/current
5163 implementation) */
5164 *(u8 *) (pkt->data) = SDPCM_TEST_ECHORSP;
5165 if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true) == 0)
5166 bus->pktgen_sent++;
5167 else {
5168 bus->pktgen_fail++;
5169 brcmu_pkt_buf_free_skb(pkt, false);
5170 }
5171 bus->pktgen_rcvd++;
5172 break;
5173
5174 case SDPCM_TEST_ECHORSP:
5175 if (bus->ext_loop) {
5176 brcmu_pkt_buf_free_skb(pkt, false);
5177 bus->pktgen_rcvd++;
5178 break;
5179 }
5180
5181 for (offset = 0; offset < len; offset++, data++) {
5182 if (*data != SDPCM_TEST_FILL(offset, extra)) {
5183 BRCMF_ERROR(("brcmf_sdbrcm_checkdied: echo"
5184 " data mismatch: "
5185 "offset %d (len %d) "
5186 "expect 0x%02x rcvd 0x%02x\n",
5187 offset, len,
5188 SDPCM_TEST_FILL(offset, extra),
5189 *data));
5190 break;
5191 }
5192 }
5193 brcmu_pkt_buf_free_skb(pkt, false);
5194 bus->pktgen_rcvd++;
5195 break;
5196
5197 case SDPCM_TEST_DISCARD:
5198 brcmu_pkt_buf_free_skb(pkt, false);
5199 bus->pktgen_rcvd++;
5200 break;
5201
5202 case SDPCM_TEST_BURST:
5203 case SDPCM_TEST_SEND:
5204 default:
5205 BRCMF_INFO(("brcmf_sdbrcm_checkdied: unsupported or unknown "
5206 "command, pktlen %d seq %d" " cmd %d extra %d"
5207 " len %d\n", pktlen, seq, cmd, extra, len));
5208 brcmu_pkt_buf_free_skb(pkt, false);
5209 break;
5210 }
5211
5212 /* For recv mode, stop at limie (and tell dongle to stop sending) */
5213 if (bus->pktgen_mode == BRCMF_PKTGEN_RECV) {
5214 if (bus->pktgen_total
5215 && (bus->pktgen_rcvd >= bus->pktgen_total)) {
5216 bus->pktgen_count = 0;
5217 brcmf_sdbrcm_sdtest_set(bus, false);
5218 }
5219 }
5220}
5221#endif /* SDTEST */
5222
5223extern bool brcmf_sdbrcm_bus_watchdog(struct brcmf_pub *drvr)
5224{
5225 struct brcmf_bus *bus;
5226
5227 BRCMF_TIMER(("%s: Enter\n", __func__));
5228
5229 bus = drvr->bus;
5230
5231 if (bus->drvr->dongle_reset)
5232 return false;
5233
5234 /* Ignore the timer if simulating bus down */
5235 if (bus->sleeping)
5236 return false;
5237
5238 brcmf_sdbrcm_sdlock(bus);
5239
5240 /* Poll period: check device if appropriate. */
5241 if (bus->poll && (++bus->polltick >= bus->pollrate)) {
5242 u32 intstatus = 0;
5243
5244 /* Reset poll tick */
5245 bus->polltick = 0;
5246
5247 /* Check device if no interrupts */
5248 if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
5249
5250 if (!bus->dpc_sched) {
5251 u8 devpend;
5252 devpend = brcmf_sdcard_cfg_read(bus->card,
5253 SDIO_FUNC_0, SDIO_CCCR_INTx,
5254 NULL);
5255 intstatus =
5256 devpend & (INTR_STATUS_FUNC1 |
5257 INTR_STATUS_FUNC2);
5258 }
5259
5260 /* If there is something, make like the ISR and
5261 schedule the DPC */
5262 if (intstatus) {
5263 bus->pollcnt++;
5264 bus->ipend = true;
5265 if (bus->intr)
5266 brcmf_sdcard_intr_disable(bus->card);
5267
5268 bus->dpc_sched = true;
5269 brcmf_sdbrcm_sched_dpc(bus);
5270
5271 }
5272 }
5273
5274 /* Update interrupt tracking */
5275 bus->lastintrs = bus->intrcount;
5276 }
5277#ifdef BCMDBG
5278 /* Poll for console output periodically */
5279 if (drvr->busstate == BRCMF_BUS_DATA && brcmf_console_ms != 0) {
5280 bus->console.count += brcmf_watchdog_ms;
5281 if (bus->console.count >= brcmf_console_ms) {
5282 bus->console.count -= brcmf_console_ms;
5283 /* Make sure backplane clock is on */
5284 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
5285 if (brcmf_sdbrcm_readconsole(bus) < 0)
5286 brcmf_console_ms = 0; /* On error,
5287 stop trying */
5288 }
5289 }
5290#endif /* BCMDBG */
5291
5292#ifdef SDTEST
5293 /* Generate packets if configured */
5294 if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) {
5295 /* Make sure backplane clock is on */
5296 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
5297 bus->pktgen_tick = 0;
5298 brcmf_sdbrcm_pktgen(bus);
5299 }
5300#endif
5301
5302 /* On idle timeout clear activity flag and/or turn off clock */
5303 if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
5304 if (++bus->idlecount >= bus->idletime) {
5305 bus->idlecount = 0;
5306 if (bus->activity) {
5307 bus->activity = false;
5308 brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms);
5309 } else {
5310 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
5311 }
5312 }
5313 }
5314
5315 brcmf_sdbrcm_sdunlock(bus);
5316
5317 return bus->ipend;
5318}
5319
5320#ifdef BCMDBG
5321static int brcmf_sdbrcm_bus_console_in(struct brcmf_pub *drvr,
5322 unsigned char *msg, uint msglen)
5323{
5324 struct brcmf_bus *bus = drvr->bus;
5325 u32 addr, val;
5326 int rv;
5327 struct sk_buff *pkt;
5328
5329 /* Address could be zero if CONSOLE := 0 in dongle Makefile */
5330 if (bus->console_addr == 0)
5331 return -ENOTSUPP;
5332
5333 /* Exclusive bus access */
5334 brcmf_sdbrcm_sdlock(bus);
5335
5336 /* Don't allow input if dongle is in reset */
5337 if (bus->drvr->dongle_reset) {
5338 brcmf_sdbrcm_sdunlock(bus);
5339 return -EPERM;
5340 }
5341
5342 /* Request clock to allow SDIO accesses */
5343 BUS_WAKE(bus);
5344 /* No pend allowed since txpkt is called later, ht clk has to be on */
5345 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
5346
5347 /* Zero cbuf_index */
5348 addr = bus->console_addr + offsetof(struct rte_console, cbuf_idx);
5349 val = cpu_to_le32(0);
5350 rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
5351 if (rv < 0)
5352 goto done;
5353
5354 /* Write message into cbuf */
5355 addr = bus->console_addr + offsetof(struct rte_console, cbuf);
5356 rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)msg, msglen);
5357 if (rv < 0)
5358 goto done;
5359
5360 /* Write length into vcons_in */
5361 addr = bus->console_addr + offsetof(struct rte_console, vcons_in);
5362 val = cpu_to_le32(msglen);
5363 rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
5364 if (rv < 0)
5365 goto done;
5366
5367 /* Bump dongle by sending an empty event pkt.
5368 * sdpcm_sendup (RX) checks for virtual console input.
5369 */
5370 pkt = brcmu_pkt_buf_get_skb(4 + SDPCM_RESERVE);
5371 if ((pkt != NULL) && bus->clkstate == CLK_AVAIL)
5372 brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true);
5373
5374done:
5375 if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
5376 bus->activity = false;
5377 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
5378 }
5379
5380 brcmf_sdbrcm_sdunlock(bus);
5381
5382 return rv;
5383}
5384#endif /* BCMDBG */
5385
5386static bool brcmf_sdbrcm_chipmatch(u16 chipid)
5387{
5388 if (chipid == BCM4325_CHIP_ID)
5389 return true;
5390 if (chipid == BCM4329_CHIP_ID)
5391 return true;
5392 if (chipid == BCM4319_CHIP_ID)
5393 return true;
5394 return false;
5395}
5396
5397static void *brcmf_sdbrcm_probe(u16 venid, u16 devid, u16 bus_no,
5398 u16 slot, u16 func, uint bustype, u32 regsva,
5399 void *card)
5400{
5401 int ret;
5402 struct brcmf_bus *bus;
5403
5404 /* Init global variables at run-time, not as part of the declaration.
5405 * This is required to support init/de-init of the driver.
5406 * Initialization
5407 * of globals as part of the declaration results in non-deterministic
5408 * behavior since the value of the globals may be different on the
5409 * first time that the driver is initialized vs subsequent
5410 * initializations.
5411 */
5412 brcmf_txbound = BRCMF_TXBOUND;
5413 brcmf_rxbound = BRCMF_RXBOUND;
5414 brcmf_alignctl = true;
5415 sd1idle = true;
5416 brcmf_readahead = true;
5417 retrydata = false;
5418 brcmf_dongle_memsize = 0;
5419 brcmf_txminmax = BRCMF_TXMINMAX;
5420
5421 forcealign = true;
5422
5423 brcmf_c_init();
5424
5425 BRCMF_TRACE(("%s: Enter\n", __func__));
5426 BRCMF_INFO(("%s: venid 0x%04x devid 0x%04x\n", __func__, venid, devid));
5427
5428 /* We make an assumption about address window mappings:
5429 * regsva == SI_ENUM_BASE*/
5430
5431 /* SDIO car passes venid and devid based on CIS parsing -- but
5432 * low-power start
5433 * means early parse could fail, so here we should get either an ID
5434 * we recognize OR (-1) indicating we must request power first.
5435 */
5436 /* Check the Vendor ID */
5437 switch (venid) {
5438 case 0x0000:
5439 case PCI_VENDOR_ID_BROADCOM:
5440 break;
5441 default:
5442 BRCMF_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid));
5443 return NULL;
5444 }
5445
5446 /* Check the Device ID and make sure it's one that we support */
5447 switch (devid) {
5448 case BCM4325_D11DUAL_ID: /* 4325 802.11a/g id */
5449 case BCM4325_D11G_ID: /* 4325 802.11g 2.4Ghz band id */
5450 case BCM4325_D11A_ID: /* 4325 802.11a 5Ghz band id */
5451 BRCMF_INFO(("%s: found 4325 Dongle\n", __func__));
5452 break;
5453 case BCM4329_D11NDUAL_ID: /* 4329 802.11n dualband device */
5454 case BCM4329_D11N2G_ID: /* 4329 802.11n 2.4G device */
5455 case BCM4329_D11N5G_ID: /* 4329 802.11n 5G device */
5456 case 0x4329:
5457 BRCMF_INFO(("%s: found 4329 Dongle\n", __func__));
5458 break;
5459 case BCM4319_D11N_ID: /* 4319 802.11n id */
5460 case BCM4319_D11N2G_ID: /* 4319 802.11n2g id */
5461 case BCM4319_D11N5G_ID: /* 4319 802.11n5g id */
5462 BRCMF_INFO(("%s: found 4319 Dongle\n", __func__));
5463 break;
5464 case 0:
5465 BRCMF_INFO(("%s: allow device id 0, will check chip"
5466 " internals\n", __func__));
5467 break;
5468
5469 default:
5470 BRCMF_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n",
5471 __func__, venid, devid));
5472 return NULL;
5473 }
5474
5475 /* Allocate private bus interface state */
5476 bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
5477 if (!bus) {
5478 BRCMF_ERROR(("%s: kmalloc of struct dhd_bus failed\n",
5479 __func__));
5480 goto fail;
5481 }
5482 bus->card = card;
5483 bus->cl_devid = (u16) devid;
5484 bus->bus = BRCMF_BUS;
5485 bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
5486 bus->usebufpool = false; /* Use bufpool if allocated,
5487 else use locally malloced rxbuf */
5488
5489 /* attempt to attach to the dongle */
5490 if (!(brcmf_sdbrcm_probe_attach(bus, card, regsva, devid))) {
5491 BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_attach failed\n",
5492 __func__));
5493 goto fail;
5494 }
5495
5496 spin_lock_init(&bus->txqlock);
5497 init_waitqueue_head(&bus->ctrl_wait);
5498
5499 /* Set up the watchdog timer */
5500 init_timer(&bus->timer);
5501 bus->timer.data = (unsigned long)bus;
5502 bus->timer.function = brcmf_sdbrcm_watchdog;
5503
5504 /* Initialize thread based operation and lock */
5505 if ((brcmf_watchdog_prio >= 0) && (brcmf_dpc_prio >= 0)) {
5506 bus->threads_only = true;
5507 sema_init(&bus->sdsem, 1);
5508 } else {
5509 bus->threads_only = false;
5510 spin_lock_init(&bus->sdlock);
5511 }
5512
5513 if (brcmf_dpc_prio >= 0) {
5514 /* Initialize watchdog thread */
5515 init_completion(&bus->watchdog_wait);
5516 bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
5517 bus, "brcmf_watchdog");
5518 if (IS_ERR(bus->watchdog_tsk)) {
5519 printk(KERN_WARNING
5520 "brcmf_watchdog thread failed to start\n");
5521 bus->watchdog_tsk = NULL;
5522 }
5523 } else
5524 bus->watchdog_tsk = NULL;
5525
5526 /* Set up the bottom half handler */
5527 if (brcmf_dpc_prio >= 0) {
5528 /* Initialize DPC thread */
5529 init_completion(&bus->dpc_wait);
5530 bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
5531 bus, "brcmf_dpc");
5532 if (IS_ERR(bus->dpc_tsk)) {
5533 printk(KERN_WARNING
5534 "brcmf_dpc thread failed to start\n");
5535 bus->dpc_tsk = NULL;
5536 }
5537 } else {
5538 tasklet_init(&bus->tasklet, brcmf_sdbrcm_dpc_tasklet,
5539 (unsigned long)bus);
5540 bus->dpc_tsk = NULL;
5541 }
5542
5543 /* Attach to the brcmf/OS/network interface */
5544 bus->drvr = brcmf_attach(bus, SDPCM_RESERVE);
5545 if (!bus->drvr) {
5546 BRCMF_ERROR(("%s: brcmf_attach failed\n", __func__));
5547 goto fail;
5548 }
5549
5550 /* Allocate buffers */
5551 if (!(brcmf_sdbrcm_probe_malloc(bus, card))) {
5552 BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_malloc failed\n",
5553 __func__));
5554 goto fail;
5555 }
5556
5557 if (!(brcmf_sdbrcm_probe_init(bus, card))) {
5558 BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_init failed\n", __func__));
5559 goto fail;
5560 }
5561
5562 /* Register interrupt callback, but mask it (not operational yet). */
5563 BRCMF_INTR(("%s: disable SDIO interrupts (not interested yet)\n",
5564 __func__));
5565 brcmf_sdcard_intr_disable(card);
5566 ret = brcmf_sdcard_intr_reg(card, brcmf_sdbrcm_isr, bus);
5567 if (ret != 0) {
5568 BRCMF_ERROR(("%s: FAILED: sdcard_intr_reg returned %d\n",
5569 __func__, ret));
5570 goto fail;
5571 }
5572 BRCMF_INTR(("%s: registered SDIO interrupt function ok\n", __func__));
5573
5574 BRCMF_INFO(("%s: completed!!\n", __func__));
5575
5576 /* if firmware path present try to download and bring up bus */
5577 ret = brcmf_bus_start(bus->drvr);
5578 if (ret != 0) {
5579 if (ret == -ENOLINK) {
5580 BRCMF_ERROR(("%s: dongle is not responding\n",
5581 __func__));
5582 goto fail;
5583 }
5584 }
5585 /* Ok, have the per-port tell the stack we're open for business */
5586 if (brcmf_net_attach(bus->drvr, 0) != 0) {
5587 BRCMF_ERROR(("%s: Net attach failed!!\n", __func__));
5588 goto fail;
5589 }
5590
5591 return bus;
5592
5593fail:
5594 brcmf_sdbrcm_release(bus);
5595 return NULL;
5596}
5597
5598static bool
5599brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, void *card, u32 regsva,
5600 u16 devid)
5601{
5602 u8 clkctl = 0;
5603 int err = 0;
5604
5605 bus->alp_only = true;
5606
5607 /* Return the window to backplane enumeration space for core access */
5608 if (brcmf_sdbrcm_set_siaddr_window(bus, SI_ENUM_BASE))
5609 BRCMF_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n",
5610 __func__));
5611
5612#ifdef BCMDBG
5613 printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n",
5614 brcmf_sdcard_reg_read(bus->card, SI_ENUM_BASE, 4));
5615
5616#endif /* BCMDBG */
5617
5618 /*
5619 * Force PLL off until brcmf_sdbrcm_chip_attach()
5620 * programs PLL control regs
5621 */
5622
5623 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
5624 BRCMF_INIT_CLKCTL1, &err);
5625 if (!err)
5626 clkctl =
5627 brcmf_sdcard_cfg_read(card, SDIO_FUNC_1,
5628 SBSDIO_FUNC1_CHIPCLKCSR, &err);
5629
5630 if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
5631 BRCMF_ERROR(("brcmf_sdbrcm_probe: ChipClkCSR access: err %d"
5632 " wrote 0x%02x read 0x%02x\n",
5633 err, BRCMF_INIT_CLKCTL1, clkctl));
5634 goto fail;
5635 }
5636
5637 if (brcmf_sdbrcm_chip_attach(bus, regsva)) {
5638 BRCMF_ERROR(("%s: brcmf_sdbrcm_chip_attach failed!\n",
5639 __func__));
5640 goto fail;
5641 }
5642
5643 if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) {
5644 BRCMF_ERROR(("%s: unsupported chip: 0x%04x\n",
5645 __func__, bus->ci->chip));
5646 goto fail;
5647 }
5648
5649 brcmf_sdbrcm_sdiod_drive_strength_init(bus, brcmf_sdiod_drive_strength);
5650
5651 /* Get info on the ARM and SOCRAM cores... */
5652 if (!BRCMF_NOPMU(bus)) {
5653 brcmf_sdcard_reg_read(bus->card,
5654 CORE_SB(bus->ci->armcorebase, sbidhigh), 4);
5655 bus->orig_ramsize = bus->ci->ramsize;
5656 if (!(bus->orig_ramsize)) {
5657 BRCMF_ERROR(("%s: failed to find SOCRAM memory!\n",
5658 __func__));
5659 goto fail;
5660 }
5661 bus->ramsize = bus->orig_ramsize;
5662 if (brcmf_dongle_memsize)
5663 brcmf_sdbrcm_setmemsize(bus, brcmf_dongle_memsize);
5664
5665 BRCMF_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n",
5666 bus->ramsize, bus->orig_ramsize));
5667 }
5668
5669 /* Set core control so an SDIO reset does a backplane reset */
5670 OR_REG(bus->ci->buscorebase + offsetof(struct sdpcmd_regs,
5671 corecontrol),
5672 CC_BPRESEN, u32);
5673
5674 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
5675
5676 /* Locate an appropriately-aligned portion of hdrbuf */
5677 bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
5678 BRCMF_SDALIGN);
5679
5680 /* Set the poll and/or interrupt flags */
5681 bus->intr = (bool) brcmf_intr;
5682 bus->poll = (bool) brcmf_poll;
5683 if (bus->poll)
5684 bus->pollrate = 1;
5685
5686 return true;
5687
5688fail:
5689 return false;
5690}
5691
5692static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card)
5693{
5694 BRCMF_TRACE(("%s: Enter\n", __func__));
5695
5696 if (bus->drvr->maxctl) {
5697 bus->rxblen =
5698 roundup((bus->drvr->maxctl + SDPCM_HDRLEN),
5699 ALIGNMENT) + BRCMF_SDALIGN;
5700 bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
5701 if (!(bus->rxbuf)) {
5702 BRCMF_ERROR(("%s: kmalloc of %d-byte rxbuf failed\n",
5703 __func__, bus->rxblen));
5704 goto fail;
5705 }
5706 }
5707
5708 /* Allocate buffer to receive glomed packet */
5709 bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
5710 if (!(bus->databuf)) {
5711 BRCMF_ERROR(("%s: kmalloc of %d-byte databuf failed\n",
5712 __func__, MAX_DATA_BUF));
5713 /* release rxbuf which was already located as above */
5714 if (!bus->rxblen)
5715 kfree(bus->rxbuf);
5716 goto fail;
5717 }
5718
5719 /* Align the buffer */
5720 if ((unsigned long)bus->databuf % BRCMF_SDALIGN)
5721 bus->dataptr = bus->databuf + (BRCMF_SDALIGN -
5722 ((unsigned long)bus->databuf % BRCMF_SDALIGN));
5723 else
5724 bus->dataptr = bus->databuf;
5725
5726 return true;
5727
5728fail:
5729 return false;
5730}
5731
5732static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card)
5733{
5734 s32 fnum;
5735
5736 BRCMF_TRACE(("%s: Enter\n", __func__));
5737
5738#ifdef SDTEST
5739 brcmf_sdbrcm_pktgen_init(bus);
5740#endif /* SDTEST */
5741
5742 /* Disable F2 to clear any intermediate frame state on the dongle */
5743 brcmf_sdcard_cfg_write(card, SDIO_FUNC_0, SDIO_CCCR_IOEx,
5744 SDIO_FUNC_ENABLE_1, NULL);
5745
5746 bus->drvr->busstate = BRCMF_BUS_DOWN;
5747 bus->sleeping = false;
5748 bus->rxflow = false;
5749
5750 /* Done with backplane-dependent accesses, can drop clock... */
5751 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0,
5752 NULL);
5753
5754 /* ...and initialize clock/power states */
5755 bus->clkstate = CLK_SDONLY;
5756 bus->idletime = (s32) brcmf_idletime;
5757 bus->idleclock = BRCMF_IDLE_ACTIVE;
5758
5759 /* Query the F2 block size, set roundup accordingly */
5760 fnum = 2;
5761 if (brcmf_sdcard_iovar_op(card, "sd_blocksize", &fnum, sizeof(s32),
5762 &bus->blocksize, sizeof(s32), false) != 0) {
5763 bus->blocksize = 0;
5764 BRCMF_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize"));
5765 } else {
5766 BRCMF_INFO(("%s: Initial value for %s is %d\n",
5767 __func__, "sd_blocksize", bus->blocksize));
5768 }
5769 bus->roundup = min(max_roundup, bus->blocksize);
5770
5771 /* Query if bus module supports packet chaining,
5772 default to use if supported */
5773 if (brcmf_sdcard_iovar_op(card, "sd_rxchain", NULL, 0,
5774 &bus->sd_rxchain, sizeof(s32),
5775 false) != 0) {
5776 bus->sd_rxchain = false;
5777 } else {
5778 BRCMF_INFO(("%s: bus module (through sdiocard API) %s"
5779 " chaining\n", __func__, bus->sd_rxchain
5780 ? "supports" : "does not support"));
5781 }
5782 bus->use_rxchain = (bool) bus->sd_rxchain;
5783
5784 return true;
5785}
5786
5787static bool
5788brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus, void *card)
5789{
5790 bool ret;
5791
5792 /* Download the firmware */
5793 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
5794
5795 ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
5796
5797 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
5798
5799 return ret;
5800}
5801
5802/* Detach and free everything */
5803static void brcmf_sdbrcm_release(struct brcmf_bus *bus)
5804{
5805 BRCMF_TRACE(("%s: Enter\n", __func__));
5806
5807 if (bus) {
5808 /* De-register interrupt handler */
5809 brcmf_sdcard_intr_disable(bus->card);
5810 brcmf_sdcard_intr_dereg(bus->card);
5811
5812 if (bus->drvr) {
5813 brcmf_detach(bus->drvr);
5814 brcmf_sdbrcm_release_dongle(bus);
5815 bus->drvr = NULL;
5816 }
5817
5818 brcmf_sdbrcm_release_malloc(bus);
5819
5820 kfree(bus);
5821 }
5822
5823 BRCMF_TRACE(("%s: Disconnected\n", __func__));
5824}
5825
5826static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus)
5827{
5828 BRCMF_TRACE(("%s: Enter\n", __func__));
5829
5830 if (bus->drvr && bus->drvr->dongle_reset)
5831 return;
5832
5833 kfree(bus->rxbuf);
5834 bus->rxctl = bus->rxbuf = NULL;
5835 bus->rxlen = 0;
5836
5837 kfree(bus->databuf);
5838 bus->databuf = NULL;
5839}
5840
5841static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus)
5842{
5843 BRCMF_TRACE(("%s: Enter\n", __func__));
5844
5845 if (bus->drvr && bus->drvr->dongle_reset)
5846 return;
5847
5848 if (bus->ci) {
5849 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
5850 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
5851 brcmf_sdbrcm_chip_detach(bus);
5852 if (bus->vars && bus->varsz)
5853 kfree(bus->vars);
5854 bus->vars = NULL;
5855 }
5856
5857 BRCMF_TRACE(("%s: Disconnected\n", __func__));
5858}
5859
5860static void brcmf_sdbrcm_disconnect(void *ptr)
5861{
5862 struct brcmf_bus *bus = (struct brcmf_bus *)ptr;
5863
5864 BRCMF_TRACE(("%s: Enter\n", __func__));
5865
5866 if (bus) {
5867 brcmf_sdbrcm_release(bus);
5868 }
5869
5870 BRCMF_TRACE(("%s: Disconnected\n", __func__));
5871}
5872
5873/* Register/Unregister functions are called by the main DHD entry
5874 * point (e.g. module insertion) to link with the bus driver, in
5875 * order to look for or await the device.
5876 */
5877
5878static struct brcmf_sdioh_driver brcmf_sdio = {
5879 brcmf_sdbrcm_probe,
5880 brcmf_sdbrcm_disconnect
5881};
5882
5883int brcmf_bus_register(void)
5884{
5885 BRCMF_TRACE(("%s: Enter\n", __func__));
5886
5887 /* Sanity check on the module parameters */
5888 do {
5889 /* Both watchdog and DPC as tasklets are ok */
5890 if ((brcmf_watchdog_prio < 0) && (brcmf_dpc_prio < 0))
5891 break;
5892
5893 /* If both watchdog and DPC are threads, TX must be deferred */
5894 if ((brcmf_watchdog_prio >= 0) && (brcmf_dpc_prio >= 0)
5895 && brcmf_deferred_tx)
5896 break;
5897
5898 BRCMF_ERROR(("Invalid module parameters.\n"));
5899 return -EINVAL;
5900 } while (0);
5901
5902 return brcmf_sdio_register(&brcmf_sdio);
5903}
5904
5905void brcmf_bus_unregister(void)
5906{
5907 BRCMF_TRACE(("%s: Enter\n", __func__));
5908
5909 brcmf_sdio_unregister();
5910}
5911
5912static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus)
5913{
5914 int offset = 0;
5915 uint len;
5916 u8 *memblock = NULL, *memptr;
5917 int ret;
5918
5919 BRCMF_INFO(("%s: Enter\n", __func__));
5920
5921 bus->fw_name = BCM4329_FW_NAME;
5922 ret = request_firmware(&bus->firmware, bus->fw_name,
5923 &gInstance->func[2]->dev);
5924 if (ret) {
5925 BRCMF_ERROR(("%s: Fail to request firmware %d\n",
5926 __func__, ret));
5927 return ret;
5928 }
5929 bus->fw_ptr = 0;
5930
5931 memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC);
5932 if (memblock == NULL) {
5933 BRCMF_ERROR(("%s: Failed to allocate memory %d bytes\n",
5934 __func__, MEMBLOCK));
5935 ret = -ENOMEM;
5936 goto err;
5937 }
5938 if ((u32)(unsigned long)memblock % BRCMF_SDALIGN)
5939 memptr += (BRCMF_SDALIGN -
5940 ((u32)(unsigned long)memblock % BRCMF_SDALIGN));
5941
5942 /* Download image */
5943 while ((len =
5944 brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) {
5945 ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len);
5946 if (ret) {
5947 BRCMF_ERROR(("%s: error %d on writing %d membytes at "
5948 "0x%08x\n", __func__, ret, MEMBLOCK,
5949 offset));
5950 goto err;
5951 }
5952
5953 offset += MEMBLOCK;
5954 }
5955
5956err:
5957 kfree(memblock);
5958
5959 release_firmware(bus->firmware);
5960 bus->fw_ptr = 0;
5961
5962 return ret;
5963}
5964
5965/*
5966 * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
5967 * and ending in a NUL.
5968 * Removes carriage returns, empty lines, comment lines, and converts
5969 * newlines to NULs.
5970 * Shortens buffer as needed and pads with NULs. End of buffer is marked
5971 * by two NULs.
5972*/
5973
5974static uint brcmf_process_nvram_vars(char *varbuf, uint len)
5975{
5976 char *dp;
5977 bool findNewline;
5978 int column;
5979 uint buf_len, n;
5980
5981 dp = varbuf;
5982
5983 findNewline = false;
5984 column = 0;
5985
5986 for (n = 0; n < len; n++) {
5987 if (varbuf[n] == 0)
5988 break;
5989 if (varbuf[n] == '\r')
5990 continue;
5991 if (findNewline && varbuf[n] != '\n')
5992 continue;
5993 findNewline = false;
5994 if (varbuf[n] == '#') {
5995 findNewline = true;
5996 continue;
5997 }
5998 if (varbuf[n] == '\n') {
5999 if (column == 0)
6000 continue;
6001 *dp++ = 0;
6002 column = 0;
6003 continue;
6004 }
6005 *dp++ = varbuf[n];
6006 column++;
6007 }
6008 buf_len = dp - varbuf;
6009
6010 while (dp < varbuf + n)
6011 *dp++ = 0;
6012
6013 return buf_len;
6014}
6015
6016static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus)
6017{
6018 uint len;
6019 char *memblock = NULL;
6020 char *bufp;
6021 int ret;
6022
6023 bus->nv_name = BCM4329_NV_NAME;
6024 ret = request_firmware(&bus->firmware, bus->nv_name,
6025 &gInstance->func[2]->dev);
6026 if (ret) {
6027 BRCMF_ERROR(("%s: Fail to request nvram %d\n", __func__, ret));
6028 return ret;
6029 }
6030 bus->fw_ptr = 0;
6031
6032 memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
6033 if (memblock == NULL) {
6034 BRCMF_ERROR(("%s: Failed to allocate memory %d bytes\n",
6035 __func__, MEMBLOCK));
6036 ret = -ENOMEM;
6037 goto err;
6038 }
6039
6040 len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);
6041
6042 if (len > 0 && len < MEMBLOCK) {
6043 bufp = (char *)memblock;
6044 bufp[len] = 0;
6045 len = brcmf_process_nvram_vars(bufp, len);
6046 bufp += len;
6047 *bufp++ = 0;
6048 if (len)
6049 ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
6050 if (ret)
6051 BRCMF_ERROR(("%s: error downloading vars: %d\n",
6052 __func__, ret));
6053 } else {
6054 BRCMF_ERROR(("%s: error reading nvram file: %d\n",
6055 __func__, len));
6056 ret = -EIO;
6057 }
6058
6059err:
6060 kfree(memblock);
6061
6062 release_firmware(bus->firmware);
6063 bus->fw_ptr = 0;
6064
6065 return ret;
6066}
6067
6068static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus)
6069{
6070 int bcmerror = -1;
6071
6072 /* Keep arm in reset */
6073 if (brcmf_sdbrcm_download_state(bus, true)) {
6074 BRCMF_ERROR(("%s: error placing ARM core in reset\n",
6075 __func__));
6076 goto err;
6077 }
6078
6079 /* External image takes precedence if specified */
6080 if (brcmf_sdbrcm_download_code_file(bus)) {
6081 BRCMF_ERROR(("%s: dongle image file download failed\n",
6082 __func__));
6083 goto err;
6084 }
6085
6086 /* External nvram takes precedence if specified */
6087 if (brcmf_sdbrcm_download_nvram(bus)) {
6088 BRCMF_ERROR(("%s: dongle nvram file download failed\n",
6089 __func__));
6090 }
6091
6092 /* Take arm out of reset */
6093 if (brcmf_sdbrcm_download_state(bus, false)) {
6094 BRCMF_ERROR(("%s: error getting out of ARM core reset\n",
6095 __func__));
6096 goto err;
6097 }
6098
6099 bcmerror = 0;
6100
6101err:
6102 return bcmerror;
6103}
6104
6105
6106static int
6107brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, u32 addr, uint fn, uint flags,
6108 u8 *buf, uint nbytes, struct sk_buff *pkt,
6109 void (*complete)(void *handle, int status,
6110 bool sync_waiting),
6111 void *handle)
6112{
6113 return brcmf_sdcard_send_buf
6114 (bus->card, addr, fn, flags, buf, nbytes, pkt, complete,
6115 handle);
6116}
6117
6118int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag)
6119{
6120 int bcmerror = 0;
6121 struct brcmf_bus *bus;
6122
6123 bus = drvr->bus;
6124
6125 if (flag == true) {
6126 brcmf_sdbrcm_wd_timer(bus, 0);
6127 if (!bus->drvr->dongle_reset) {
6128 /* Expect app to have torn down any
6129 connection before calling */
6130 /* Stop the bus, disable F2 */
6131 brcmf_sdbrcm_bus_stop(bus, false);
6132
6133 /* Clean tx/rx buffer pointers,
6134 detach from the dongle */
6135 brcmf_sdbrcm_release_dongle(bus);
6136
6137 bus->drvr->dongle_reset = true;
6138 bus->drvr->up = false;
6139
6140 BRCMF_TRACE(("%s: WLAN OFF DONE\n", __func__));
6141 /* App can now remove power from device */
6142 } else
6143 bcmerror = -EIO;
6144 } else {
6145 /* App must have restored power to device before calling */
6146
6147 BRCMF_TRACE(("\n\n%s: == WLAN ON ==\n", __func__));
6148
6149 if (bus->drvr->dongle_reset) {
6150 /* Turn on WLAN */
6151
6152 /* Attempt to re-attach & download */
6153 if (brcmf_sdbrcm_probe_attach(bus, bus->card,
6154 SI_ENUM_BASE,
6155 bus->cl_devid)) {
6156 /* Attempt to download binary to the dongle */
6157 if (brcmf_sdbrcm_probe_init(bus, bus->card)) {
6158 /* Re-init bus, enable F2 transfer */
6159 brcmf_sdbrcm_bus_init(bus->drvr, false);
6160
6161 bus->drvr->dongle_reset = false;
6162 bus->drvr->up = true;
6163
6164 BRCMF_TRACE(("%s: WLAN ON DONE\n",
6165 __func__));
6166 } else
6167 bcmerror = -EIO;
6168 } else
6169 bcmerror = -EIO;
6170 } else {
6171 bcmerror = -EISCONN;
6172 BRCMF_ERROR(("%s: Set DEVRESET=false invoked when"
6173 " device is on\n", __func__));
6174 bcmerror = -EIO;
6175 }
6176 brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms);
6177 }
6178 return bcmerror;
6179}
6180
6181static int
6182brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_card *card,
6183 struct chip_info *ci, u32 regs)
6184{
6185 u32 regdata;
6186
6187 /*
6188 * Get CC core rev
6189 * Chipid is assume to be at offset 0 from regs arg
6190 * For different chiptypes or old sdio hosts w/o chipcommon,
6191 * other ways of recognition should be added here.
6192 */
6193 ci->cccorebase = regs;
6194 regdata = brcmf_sdcard_reg_read(card,
6195 CORE_CC_REG(ci->cccorebase, chipid), 4);
6196 ci->chip = regdata & CID_ID_MASK;
6197 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
6198
6199 BRCMF_INFO(("%s: chipid=0x%x chiprev=%d\n",
6200 __func__, ci->chip, ci->chiprev));
6201
6202 /* Address of cores for new chips should be added here */
6203 switch (ci->chip) {
6204 case BCM4329_CHIP_ID:
6205 ci->buscorebase = BCM4329_CORE_BUS_BASE;
6206 ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE;
6207 ci->armcorebase = BCM4329_CORE_ARM_BASE;
6208 ci->ramsize = BCM4329_RAMSIZE;
6209 break;
6210 default:
6211 BRCMF_ERROR(("%s: chipid 0x%x is not supported\n",
6212 __func__, ci->chip));
6213 return -ENODEV;
6214 }
6215
6216 regdata = brcmf_sdcard_reg_read(card,
6217 CORE_SB(ci->cccorebase, sbidhigh), 4);
6218 ci->ccrev = SBCOREREV(regdata);
6219
6220 regdata = brcmf_sdcard_reg_read(card,
6221 CORE_CC_REG(ci->cccorebase, pmucapabilities), 4);
6222 ci->pmurev = regdata & PCAP_REV_MASK;
6223
6224 regdata = brcmf_sdcard_reg_read(card,
6225 CORE_SB(ci->buscorebase, sbidhigh), 4);
6226 ci->buscorerev = SBCOREREV(regdata);
6227 ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
6228
6229 BRCMF_INFO(("%s: ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
6230 __func__, ci->ccrev, ci->pmurev,
6231 ci->buscorerev, ci->buscoretype));
6232
6233 /* get chipcommon capabilites */
6234 ci->cccaps = brcmf_sdcard_reg_read(card,
6235 CORE_CC_REG(ci->cccorebase, capabilities), 4);
6236
6237 return 0;
6238}
6239
6240static void
6241brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_card *card, u32 corebase)
6242{
6243 u32 regdata;
6244
6245 regdata = brcmf_sdcard_reg_read(card,
6246 CORE_SB(corebase, sbtmstatelow), 4);
6247 if (regdata & SBTML_RESET)
6248 return;
6249
6250 regdata = brcmf_sdcard_reg_read(card,
6251 CORE_SB(corebase, sbtmstatelow), 4);
6252 if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) {
6253 /*
6254 * set target reject and spin until busy is clear
6255 * (preserve core-specific bits)
6256 */
6257 regdata = brcmf_sdcard_reg_read(card,
6258 CORE_SB(corebase, sbtmstatelow), 4);
6259 brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4,
6260 regdata | SBTML_REJ);
6261
6262 regdata = brcmf_sdcard_reg_read(card,
6263 CORE_SB(corebase, sbtmstatelow), 4);
6264 udelay(1);
6265 SPINWAIT((brcmf_sdcard_reg_read(card,
6266 CORE_SB(corebase, sbtmstatehigh), 4) &
6267 SBTMH_BUSY), 100000);
6268
6269 regdata = brcmf_sdcard_reg_read(card,
6270 CORE_SB(corebase, sbtmstatehigh), 4);
6271 if (regdata & SBTMH_BUSY)
6272 BRCMF_ERROR(("%s: ARM core still busy\n", __func__));
6273
6274 regdata = brcmf_sdcard_reg_read(card,
6275 CORE_SB(corebase, sbidlow), 4);
6276 if (regdata & SBIDL_INIT) {
6277 regdata = brcmf_sdcard_reg_read(card,
6278 CORE_SB(corebase, sbimstate), 4) |
6279 SBIM_RJ;
6280 brcmf_sdcard_reg_write(card,
6281 CORE_SB(corebase, sbimstate), 4,
6282 regdata);
6283 regdata = brcmf_sdcard_reg_read(card,
6284 CORE_SB(corebase, sbimstate), 4);
6285 udelay(1);
6286 SPINWAIT((brcmf_sdcard_reg_read(card,
6287 CORE_SB(corebase, sbimstate), 4) &
6288 SBIM_BY), 100000);
6289 }
6290
6291 /* set reset and reject while enabling the clocks */
6292 brcmf_sdcard_reg_write(card,
6293 CORE_SB(corebase, sbtmstatelow), 4,
6294 (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
6295 SBTML_REJ | SBTML_RESET));
6296 regdata = brcmf_sdcard_reg_read(card,
6297 CORE_SB(corebase, sbtmstatelow), 4);
6298 udelay(10);
6299
6300 /* clear the initiator reject bit */
6301 regdata = brcmf_sdcard_reg_read(card,
6302 CORE_SB(corebase, sbidlow), 4);
6303 if (regdata & SBIDL_INIT) {
6304 regdata = brcmf_sdcard_reg_read(card,
6305 CORE_SB(corebase, sbimstate), 4) &
6306 ~SBIM_RJ;
6307 brcmf_sdcard_reg_write(card,
6308 CORE_SB(corebase, sbimstate), 4,
6309 regdata);
6310 }
6311 }
6312
6313 /* leave reset and reject asserted */
6314 brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4,
6315 (SBTML_REJ | SBTML_RESET));
6316 udelay(1);
6317}
6318
6319static int
6320brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs)
6321{
6322 struct chip_info *ci;
6323 int err;
6324 u8 clkval, clkset;
6325
6326 BRCMF_TRACE(("%s: Enter\n", __func__));
6327
6328 /* alloc chip_info_t */
6329 ci = kmalloc(sizeof(struct chip_info), GFP_ATOMIC);
6330 if (NULL == ci) {
6331 BRCMF_ERROR(("%s: malloc failed!\n", __func__));
6332 return -ENOMEM;
6333 }
6334
6335 memset((unsigned char *)ci, 0, sizeof(struct chip_info));
6336
6337 /* bus/core/clk setup for register access */
6338 /* Try forcing SDIO core to do ALPAvail request only */
6339 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
6340 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
6341 clkset, &err);
6342 if (err) {
6343 BRCMF_ERROR(("%s: error writing for HT off\n", __func__));
6344 goto fail;
6345 }
6346
6347 /* If register supported, wait for ALPAvail and then force ALP */
6348 /* This may take up to 15 milliseconds */
6349 clkval = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1,
6350 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
6351 if ((clkval & ~SBSDIO_AVBITS) == clkset) {
6352 SPINWAIT(((clkval =
6353 brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1,
6354 SBSDIO_FUNC1_CHIPCLKCSR,
6355 NULL)),
6356 !SBSDIO_ALPAV(clkval)),
6357 PMU_MAX_TRANSITION_DLY);
6358 if (!SBSDIO_ALPAV(clkval)) {
6359 BRCMF_ERROR(("%s: timeout on ALPAV wait,"
6360 " clkval 0x%02x\n", __func__, clkval));
6361 err = -EBUSY;
6362 goto fail;
6363 }
6364 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF |
6365 SBSDIO_FORCE_ALP;
6366 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1,
6367 SBSDIO_FUNC1_CHIPCLKCSR,
6368 clkset, &err);
6369 udelay(65);
6370 } else {
6371 BRCMF_ERROR(("%s: ChipClkCSR access: wrote 0x%02x"
6372 " read 0x%02x\n", __func__, clkset, clkval));
6373 err = -EACCES;
6374 goto fail;
6375 }
6376
6377 /* Also, disable the extra SDIO pull-ups */
6378 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP,
6379 0, NULL);
6380
6381 err = brcmf_sdbrcm_chip_recognition(bus->card, ci, regs);
6382 if (err)
6383 goto fail;
6384
6385 /*
6386 * Make sure any on-chip ARM is off (in case strapping is wrong),
6387 * or downloaded code was already running.
6388 */
6389 brcmf_sdbrcm_chip_disablecore(bus->card, ci->armcorebase);
6390
6391 brcmf_sdcard_reg_write(bus->card,
6392 CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0);
6393 brcmf_sdcard_reg_write(bus->card,
6394 CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0);
6395
6396 /* Disable F2 to clear any intermediate frame state on the dongle */
6397 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx,
6398 SDIO_FUNC_ENABLE_1, NULL);
6399
6400 /* WAR: cmd52 backplane read so core HW will drop ALPReq */
6401 clkval = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1,
6402 0, NULL);
6403
6404 /* Done with backplane-dependent accesses, can drop clock... */
6405 brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
6406 0, NULL);
6407
6408 bus->ci = ci;
6409 return 0;
6410fail:
6411 bus->ci = NULL;
6412 kfree(ci);
6413 return err;
6414}
6415
6416static void
6417brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_card *card, u32 corebase)
6418{
6419 u32 regdata;
6420
6421 /*
6422 * Must do the disable sequence first to work for
6423 * arbitrary current core state.
6424 */
6425 brcmf_sdbrcm_chip_disablecore(card, corebase);
6426
6427 /*
6428 * Now do the initialization sequence.
6429 * set reset while enabling the clock and
6430 * forcing them on throughout the core
6431 */
6432 brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4,
6433 ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
6434 SBTML_RESET);
6435 udelay(1);
6436
6437 regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatehigh),
6438 4);
6439 if (regdata & SBTMH_SERR)
6440 brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatehigh),
6441 4, 0);
6442
6443 regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbimstate), 4);
6444 if (regdata & (SBIM_IBE | SBIM_TO))
6445 brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbimstate), 4,
6446 regdata & ~(SBIM_IBE | SBIM_TO));
6447
6448 /* clear reset and allow it to propagate throughout the core */
6449 brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4,
6450 (SICF_FGC << SBTML_SICF_SHIFT) |
6451 (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
6452 udelay(1);
6453
6454 /* leave clock enabled */
6455 brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4,
6456 (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
6457 udelay(1);
6458}
6459
6460/* SDIO Pad drive strength to select value mappings */
6461struct sdiod_drive_str {
6462 u8 strength; /* Pad Drive Strength in mA */
6463 u8 sel; /* Chip-specific select value */
6464};
6465
6466/* SDIO Drive Strength to sel value table for PMU Rev 1 */
6467static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
6468 {
6469 4, 0x2}, {
6470 2, 0x3}, {
6471 1, 0x0}, {
6472 0, 0x0}
6473 };
6474
6475/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
6476static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
6477 {
6478 12, 0x7}, {
6479 10, 0x6}, {
6480 8, 0x5}, {
6481 6, 0x4}, {
6482 4, 0x2}, {
6483 2, 0x1}, {
6484 0, 0x0}
6485 };
6486
6487/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
6488static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
6489 {
6490 32, 0x7}, {
6491 26, 0x6}, {
6492 22, 0x5}, {
6493 16, 0x4}, {
6494 12, 0x3}, {
6495 8, 0x2}, {
6496 4, 0x1}, {
6497 0, 0x0}
6498 };
6499
6500#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
6501
6502static void
6503brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, u32 drivestrength) {
6504 struct sdiod_drive_str *str_tab = NULL;
6505 u32 str_mask = 0;
6506 u32 str_shift = 0;
6507 char chn[8];
6508
6509 if (!(bus->ci->cccaps & CC_CAP_PMU))
6510 return;
6511
6512 switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) {
6513 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
6514 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
6515 str_mask = 0x30000000;
6516 str_shift = 28;
6517 break;
6518 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
6519 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
6520 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
6521 str_mask = 0x00003800;
6522 str_shift = 11;
6523 break;
6524 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
6525 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
6526 str_mask = 0x00003800;
6527 str_shift = 11;
6528 break;
6529 default:
6530 BRCMF_ERROR(("No SDIO Drive strength init"
6531 "done for chip %s rev %d pmurev %d\n",
6532 brcmu_chipname(bus->ci->chip, chn, 8),
6533 bus->ci->chiprev, bus->ci->pmurev));
6534 break;
6535 }
6536
6537 if (str_tab != NULL) {
6538 u32 drivestrength_sel = 0;
6539 u32 cc_data_temp;
6540 int i;
6541
6542 for (i = 0; str_tab[i].strength != 0; i++) {
6543 if (drivestrength >= str_tab[i].strength) {
6544 drivestrength_sel = str_tab[i].sel;
6545 break;
6546 }
6547 }
6548
6549 brcmf_sdcard_reg_write(bus->card,
6550 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
6551 4, 1);
6552 cc_data_temp = brcmf_sdcard_reg_read(bus->card,
6553 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4);
6554 cc_data_temp &= ~str_mask;
6555 drivestrength_sel <<= str_shift;
6556 cc_data_temp |= drivestrength_sel;
6557 brcmf_sdcard_reg_write(bus->card,
6558 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
6559 4, cc_data_temp);
6560
6561 BRCMF_INFO(("SDIO: %dmA drive strength selected, "
6562 "set to 0x%08x\n", drivestrength, cc_data_temp));
6563 }
6564}
6565
6566static void
6567brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus)
6568{
6569 BRCMF_TRACE(("%s: Enter\n", __func__));
6570
6571 kfree(bus->ci);
6572 bus->ci = NULL;
6573}
6574
6575static void
6576brcmf_sdbrcm_wait_for_event(struct brcmf_bus *bus, bool *lockvar)
6577{
6578 brcmf_sdbrcm_sdunlock(bus);
6579 wait_event_interruptible_timeout(bus->ctrl_wait,
6580 (*lockvar == false), HZ * 2);
6581 brcmf_sdbrcm_sdlock(bus);
6582 return;
6583}
6584
6585static void
6586brcmf_sdbrcm_wait_event_wakeup(struct brcmf_bus *bus)
6587{
6588 if (waitqueue_active(&bus->ctrl_wait))
6589 wake_up_interruptible(&bus->ctrl_wait);
6590 return;
6591}
6592
6593static int
6594brcmf_sdbrcm_watchdog_thread(void *data)
6595{
6596 struct brcmf_bus *bus = (struct brcmf_bus *)data;
6597
6598 /* This thread doesn't need any user-level access,
6599 * so get rid of all our resources
6600 */
6601 if (brcmf_watchdog_prio > 0) {
6602 struct sched_param param;
6603 param.sched_priority = (brcmf_watchdog_prio < MAX_RT_PRIO) ?
6604 brcmf_watchdog_prio : (MAX_RT_PRIO - 1);
6605 sched_setscheduler(current, SCHED_FIFO, &param);
6606 }
6607
6608 allow_signal(SIGTERM);
6609 /* Run until signal received */
6610 while (1) {
6611 if (kthread_should_stop())
6612 break;
6613 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) {
6614 if (bus->drvr->dongle_reset == false)
6615 brcmf_sdbrcm_bus_watchdog(bus->drvr);
6616 /* Count the tick for reference */
6617 bus->drvr->tickcnt++;
6618 } else
6619 break;
6620 }
6621 return 0;
6622}
6623
6624static void
6625brcmf_sdbrcm_watchdog(unsigned long data)
6626{
6627 struct brcmf_bus *bus = (struct brcmf_bus *)data;
6628
6629 if (brcmf_watchdog_prio >= 0) {
6630 if (bus->watchdog_tsk)
6631 complete(&bus->watchdog_wait);
6632 else
6633 return;
6634 } else {
6635 brcmf_sdbrcm_bus_watchdog(bus->drvr);
6636
6637 /* Count the tick for reference */
6638 bus->drvr->tickcnt++;
6639 }
6640
6641 /* Reschedule the watchdog */
6642 if (bus->wd_timer_valid)
6643 mod_timer(&bus->timer, jiffies + brcmf_watchdog_ms * HZ / 1000);
6644}
6645
6646void
6647brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick)
6648{
6649 static uint save_ms;
6650
6651 /* don't start the wd until fw is loaded */
6652 if (bus->drvr->busstate == BRCMF_BUS_DOWN)
6653 return;
6654
6655 /* Totally stop the timer */
6656 if (!wdtick && bus->wd_timer_valid == true) {
6657 del_timer_sync(&bus->timer);
6658 bus->wd_timer_valid = false;
6659 save_ms = wdtick;
6660 return;
6661 }
6662
6663 if (wdtick) {
6664 brcmf_watchdog_ms = (uint) wdtick;
6665
6666 if (save_ms != brcmf_watchdog_ms) {
6667 if (bus->wd_timer_valid == true)
6668 /* Stop timer and restart at new value */
6669 del_timer_sync(&bus->timer);
6670
6671 /* Create timer again when watchdog period is
6672 dynamically changed or in the first instance
6673 */
6674 bus->timer.expires =
6675 jiffies + brcmf_watchdog_ms * HZ / 1000;
6676 add_timer(&bus->timer);
6677
6678 } else {
6679 /* Re arm the timer, at last watchdog period */
6680 mod_timer(&bus->timer,
6681 jiffies + brcmf_watchdog_ms * HZ / 1000);
6682 }
6683
6684 bus->wd_timer_valid = true;
6685 save_ms = wdtick;
6686 }
6687}
6688
6689static int brcmf_sdbrcm_dpc_thread(void *data)
6690{
6691 struct brcmf_bus *bus = (struct brcmf_bus *) data;
6692
6693 /* This thread doesn't need any user-level access,
6694 * so get rid of all our resources
6695 */
6696 if (brcmf_dpc_prio > 0) {
6697 struct sched_param param;
6698 param.sched_priority = (brcmf_dpc_prio < MAX_RT_PRIO) ?
6699 brcmf_dpc_prio : (MAX_RT_PRIO - 1);
6700 sched_setscheduler(current, SCHED_FIFO, &param);
6701 }
6702
6703 allow_signal(SIGTERM);
6704 /* Run until signal received */
6705 while (1) {
6706 if (kthread_should_stop())
6707 break;
6708 if (!wait_for_completion_interruptible(&bus->dpc_wait)) {
6709 /* Call bus dpc unless it indicated down
6710 (then clean stop) */
6711 if (bus->drvr->busstate != BRCMF_BUS_DOWN) {
6712 if (brcmf_sdbrcm_dpc(bus))
6713 complete(&bus->dpc_wait);
6714 } else {
6715 brcmf_sdbrcm_bus_stop(bus, true);
6716 }
6717 } else
6718 break;
6719 }
6720 return 0;
6721}
6722
6723static void brcmf_sdbrcm_dpc_tasklet(unsigned long data)
6724{
6725 struct brcmf_bus *bus = (struct brcmf_bus *) data;
6726
6727 /* Call bus dpc unless it indicated down (then clean stop) */
6728 if (bus->drvr->busstate != BRCMF_BUS_DOWN) {
6729 if (brcmf_sdbrcm_dpc(bus))
6730 tasklet_schedule(&bus->tasklet);
6731 } else
6732 brcmf_sdbrcm_bus_stop(bus, true);
6733}
6734
6735static void brcmf_sdbrcm_sched_dpc(struct brcmf_bus *bus)
6736{
6737 if (bus->dpc_tsk) {
6738 complete(&bus->dpc_wait);
6739 return;
6740 }
6741
6742 tasklet_schedule(&bus->tasklet);
6743}
6744
6745static void brcmf_sdbrcm_sdlock(struct brcmf_bus *bus)
6746{
6747 if (bus->threads_only)
6748 down(&bus->sdsem);
6749 else
6750 spin_lock_bh(&bus->sdlock);
6751}
6752
6753static void brcmf_sdbrcm_sdunlock(struct brcmf_bus *bus)
6754{
6755 if (bus->threads_only)
6756 up(&bus->sdsem);
6757 else
6758 spin_unlock_bh(&bus->sdlock);
6759}
6760
6761static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus)
6762{
6763 if (bus->firmware->size < bus->fw_ptr + len)
6764 len = bus->firmware->size - bus->fw_ptr;
6765
6766 memcpy(buf, &bus->firmware->data[bus->fw_ptr], len);
6767 bus->fw_ptr += len;
6768 return len;
6769}
6770
6771MODULE_FIRMWARE(BCM4329_FW_NAME);
6772MODULE_FIRMWARE(BCM4329_NV_NAME);
diff --git a/drivers/staging/brcm80211/brcmfmac/sdio_host.h b/drivers/staging/brcm80211/brcmfmac/sdio_host.h
new file mode 100644
index 00000000000..d3454721506
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/sdio_host.h
@@ -0,0 +1,347 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SDH_H_
18#define _BRCM_SDH_H_
19
20#include <linux/skbuff.h>
21extern const uint brcmf_sdio_msglevel;
22
23#define SDIO_FUNC_0 0
24#define SDIO_FUNC_1 1
25#define SDIO_FUNC_2 2
26
27#define SDIOD_FBR_SIZE 0x100
28
29/* io_en */
30#define SDIO_FUNC_ENABLE_1 0x02
31#define SDIO_FUNC_ENABLE_2 0x04
32
33/* io_rdys */
34#define SDIO_FUNC_READY_1 0x02
35#define SDIO_FUNC_READY_2 0x04
36
37/* intr_status */
38#define INTR_STATUS_FUNC1 0x2
39#define INTR_STATUS_FUNC2 0x4
40
41/* Maximum number of I/O funcs */
42#define SDIOD_MAX_IOFUNCS 7
43
44#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */
45
46/* function 1 miscellaneous registers */
47#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */
48#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */
49#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */
50#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */
51#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */
52#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */
53#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */
54#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */
55#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */
56#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */
57
58/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */
59#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */
60#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */
61#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */
62#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */
63#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */
64#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */
65#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */
66#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */
67#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */
68#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */
69
70#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */
71#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */
72
73/* function 1 OCP space */
74#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */
75#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
76#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */
77
78/* some duplication with sbsdpcmdev.h here */
79/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
80#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */
81#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */
82#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */
83#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */
84
85#define SDIOH_READ 0 /* Read request */
86#define SDIOH_WRITE 1 /* Write request */
87
88#define SDIOH_DATA_FIX 0 /* Fixed addressing */
89#define SDIOH_DATA_INC 1 /* Incremental addressing */
90
91/* internal return code */
92#define SUCCESS 0
93#define ERROR 1
94
95/* forward declarations */
96struct brcmf_sdio_card;
97
98struct brcmf_sdreg {
99 int func;
100 int offset;
101 int value;
102};
103
104struct sdioh_info {
105 struct osl_info *osh; /* osh handler */
106 bool client_intr_enabled; /* interrupt connnected flag */
107 bool intr_handler_valid; /* client driver interrupt handler valid */
108 void (*intr_handler)(void *); /* registered interrupt handler */
109 void *intr_handler_arg; /* argument to call interrupt handler */
110 u16 intmask; /* Current active interrupts */
111 void *sdos_info; /* Pointer to per-OS private data */
112
113 uint irq; /* Client irq */
114 int intrcount; /* Client interrupts */
115 bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */
116 /* Must be on for sd_multiblock to be effective */
117 bool use_client_ints; /* If this is false, make sure to restore */
118 int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
119 u8 num_funcs; /* Supported funcs on client */
120 u32 com_cis_ptr;
121 u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
122 uint max_dma_len;
123 uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */
124 /* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */
125};
126
127struct brcmf_sdmmc_instance {
128 struct sdioh_info *sd;
129 struct sdio_func *func[SDIOD_MAX_IOFUNCS];
130 u32 host_claimed;
131};
132
133/* Attach and build an interface to the underlying SD host driver.
134 * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by
135 * brcmf_sdcard.
136 * - Returns the sdio card handle and virtual address base for register access.
137 * The returned handle should be used in all subsequent calls, but the bcmsh
138 * implementation may maintain a single "default" handle (e.g. the first or
139 * most recent one) to enable single-instance implementations to pass NULL.
140 */
141extern struct brcmf_sdio_card*
142brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq);
143
144/* Detach - freeup resources allocated in attach */
145extern int brcmf_sdcard_detach(struct brcmf_sdio_card *card);
146
147/* Enable/disable SD interrupt */
148extern int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card);
149extern int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card);
150
151/* Register/deregister device interrupt handler. */
152extern int
153brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
154 void (*fn)(void *), void *argh);
155
156extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card);
157
158/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
159 * fn: function number
160 * addr: unmodified SDIO-space address
161 * data: data byte to write
162 * err: pointer to error code (or NULL)
163 */
164extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint func,
165 u32 addr, int *err);
166extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint func,
167 u32 addr, u8 data, int *err);
168
169/* Read/Write 4bytes from/to cfg space */
170extern u32
171brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
172 u32 addr, int *err);
173
174extern void brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card,
175 uint fnc_num, u32 addr,
176 u32 data, int *err);
177
178/* Read CIS content for specified function.
179 * fn: function whose CIS is being requested (0 is common CIS)
180 * cis: pointer to memory location to place results
181 * length: number of bytes to read
182 * Internally, this routine uses the values from the cis base regs (0x9-0xB)
183 * to form an SDIO-space address to read the data from.
184 */
185extern int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func,
186 u8 *cis, uint length);
187
188/* Synchronous access to device (client) core registers via CMD53 to F1.
189 * addr: backplane address (i.e. >= regsva from attach)
190 * size: register width in bytes (2 or 4)
191 * data: data for register write
192 */
193extern u32
194brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size);
195
196extern u32
197brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
198 u32 data);
199
200/* Indicate if last reg read/write failed */
201extern bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card);
202
203/* Buffer transfer to/from device (client) core via cmd53.
204 * fn: function number
205 * addr: backplane address (i.e. >= regsva from attach)
206 * flags: backplane width, address increment, sync/async
207 * buf: pointer to memory data buffer
208 * nbytes: number of bytes to transfer to/from buf
209 * pkt: pointer to packet associated with buf (if any)
210 * complete: callback function for command completion (async only)
211 * handle: handle for completion callback (first arg in callback)
212 * Returns 0 or error code.
213 * NOTE: Async operation is not currently supported.
214 */
215extern int
216brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
217 uint flags, u8 *buf, uint nbytes, void *pkt,
218 void (*complete)(void *handle, int status,
219 bool sync_waiting),
220 void *handle);
221extern int
222brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
223 uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt,
224 void (*complete)(void *handle, int status,
225 bool sync_waiting),
226 void *handle);
227
228/* Flags bits */
229#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */
230#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */
231#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */
232
233/* Pending (non-error) return code */
234#define BCME_PENDING 1
235
236/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
237 * rw: read or write (0/1)
238 * addr: direct SDIO address
239 * buf: pointer to memory data buffer
240 * nbytes: number of bytes to transfer to/from buf
241 * Returns 0 or error code.
242 */
243extern int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
244 u8 *buf, uint nbytes);
245
246/* Issue an abort to the specified function */
247extern int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn);
248
249/* Returns the "Device ID" of target device on the SDIO bus. */
250extern int brcmf_sdcard_query_device(struct brcmf_sdio_card *card);
251
252/* Miscellaneous knob tweaker. */
253extern int brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
254 void *params, int plen, void *arg, int len,
255 bool set);
256
257/* helper functions */
258
259/* callback functions */
260struct brcmf_sdioh_driver {
261 /* attach to device */
262 void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot,
263 u16 func, uint bustype, u32 regsva, void *param);
264 /* detach from device */
265 void (*detach) (void *ch);
266};
267
268struct sdioh_info;
269
270/* platform specific/high level functions */
271extern int brcmf_sdio_function_init(void);
272extern int brcmf_sdio_register(struct brcmf_sdioh_driver *driver);
273extern void brcmf_sdio_unregister(void);
274extern void brcmf_sdio_function_cleanup(void);
275extern int brcmf_sdio_probe(struct device *dev);
276extern int brcmf_sdio_remove(struct device *dev);
277
278/* Function to return current window addr */
279extern u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card);
280
281/* Allocate/init/free per-OS private data */
282extern int brcmf_sdioh_osinit(struct sdioh_info *sd);
283extern void brcmf_sdioh_osfree(struct sdioh_info *sd);
284
285/* Core interrupt enable/disable of device interrupts */
286extern void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd);
287extern void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd);
288
289/* attach, return handler on success, NULL if failed.
290 * The handler shall be provided by all subsequent calls. No local cache
291 * cfghdl points to the starting address of pci device mapped memory
292 */
293extern struct sdioh_info *brcmf_sdioh_attach(void *cfghdl, uint irq);
294extern int brcmf_sdioh_detach(struct sdioh_info *si);
295
296extern int
297brcmf_sdioh_interrupt_register(struct sdioh_info *si,
298 void (*sdioh_cb_fn)(void *), void *argh);
299
300extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *si);
301
302/* enable or disable SD interrupt */
303extern int
304brcmf_sdioh_interrupt_set(struct sdioh_info *si, bool enable_disable);
305
306/* read or write one byte using cmd52 */
307extern int
308brcmf_sdioh_request_byte(struct sdioh_info *si, uint rw, uint fnc, uint addr,
309 u8 *byte);
310
311/* read or write 2/4 bytes using cmd53 */
312extern int
313brcmf_sdioh_request_word(struct sdioh_info *si, uint cmd_type,
314 uint rw, uint fnc, uint addr,
315 u32 *word, uint nbyte);
316
317/* read or write any buffer using cmd53 */
318extern int
319brcmf_sdioh_request_buffer(struct sdioh_info *si, uint pio_dma,
320 uint fix_inc, uint rw, uint fnc_num,
321 u32 addr, uint regwidth,
322 u32 buflen, u8 *buffer, struct sk_buff *pkt);
323
324/* get cis data */
325extern int
326brcmf_sdioh_cis_read(struct sdioh_info *si, uint fuc, u8 *cis, u32 length);
327
328extern int
329brcmf_sdioh_cfg_read(struct sdioh_info *si, uint fuc, u32 addr, u8 *data);
330extern int
331brcmf_sdioh_cfg_write(struct sdioh_info *si, uint fuc, u32 addr, u8 *data);
332
333/* handle iovars */
334extern int brcmf_sdioh_iovar_op(struct sdioh_info *si, const char *name,
335 void *params, int plen, void *arg, int len, bool set);
336
337/* Issue abort to the specified function and clear controller as needed */
338extern int brcmf_sdioh_abort(struct sdioh_info *si, uint fnc);
339
340/* Watchdog timer interface for pm ops */
341extern void brcmf_sdio_wdtmr_enable(bool enable);
342
343extern uint sd_msglevel; /* Debug message level */
344
345extern struct brcmf_sdmmc_instance *gInstance;
346
347#endif /* _BRCM_SDH_H_ */
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
new file mode 100644
index 00000000000..821206d3e53
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
@@ -0,0 +1,4152 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/if_arp.h>
19#include <linux/sched.h>
20#include <linux/kthread.h>
21#include <linux/netdevice.h>
22#include <linux/sched.h>
23#include <linux/etherdevice.h>
24#include <linux/wireless.h>
25#include <linux/ieee80211.h>
26#include <linux/mmc/sdio_func.h>
27#include <linux/uaccess.h>
28#include <net/cfg80211.h>
29#include <net/rtnetlink.h>
30
31#include <brcmu_utils.h>
32#include <defs.h>
33#include <brcmu_wifi.h>
34#include "dhd.h"
35#include "wl_cfg80211.h"
36
37static struct sdio_func *cfg80211_sdio_func;
38static struct brcmf_cfg80211_dev *cfg80211_dev;
39static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
40
41u32 brcmf_dbg_level = WL_DBG_ERR;
42
43/*
44** cfg80211_ops api/callback list
45*/
46static s32 brcmf_cfg80211_change_iface(struct wiphy *wiphy,
47 struct net_device *ndev,
48 enum nl80211_iftype type, u32 *flags,
49 struct vif_params *params);
50static s32 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
51 struct cfg80211_scan_request *request,
52 struct cfg80211_ssid *this_ssid);
53static s32 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
54 struct cfg80211_scan_request *request);
55static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
56static s32 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
57 struct cfg80211_ibss_params *params);
58static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy,
59 struct net_device *dev);
60static s32 brcmf_cfg80211_get_station(struct wiphy *wiphy,
61 struct net_device *dev, u8 *mac,
62 struct station_info *sinfo);
63static s32 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy,
64 struct net_device *dev, bool enabled,
65 s32 timeout);
66static s32 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
67 struct net_device *dev,
68 const u8 *addr,
69 const struct cfg80211_bitrate_mask
70 *mask);
71static int brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
72 struct cfg80211_connect_params *sme);
73static s32 brcmf_cfg80211_disconnect(struct wiphy *wiphy,
74 struct net_device *dev,
75 u16 reason_code);
76static s32 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
77 enum nl80211_tx_power_setting type,
78 s32 dbm);
79static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
80static s32 brcmf_cfg80211_config_default_key(struct wiphy *wiphy,
81 struct net_device *dev, u8 key_idx,
82 bool unicast, bool multicast);
83static s32 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
84 u8 key_idx, bool pairwise, const u8 *mac_addr,
85 struct key_params *params);
86static s32 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
87 u8 key_idx, bool pairwise, const u8 *mac_addr);
88static s32 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
89 u8 key_idx, bool pairwise, const u8 *mac_addr,
90 void *cookie, void (*callback) (void *cookie,
91 struct
92 key_params *
93 params));
94static s32 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
95 struct net_device *dev,
96 u8 key_idx);
97static s32 brcmf_cfg80211_resume(struct wiphy *wiphy);
98static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
99 struct cfg80211_wowlan *wow);
100static s32 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
101 struct cfg80211_pmksa *pmksa);
102static s32 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
103 struct cfg80211_pmksa *pmksa);
104static s32 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy,
105 struct net_device *dev);
106/*
107** event & event Q handlers for cfg80211 interfaces
108*/
109static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv);
110static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv);
111static s32 brcmf_event_handler(void *data);
112static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv);
113static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv);
114static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv);
115static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv);
116static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv);
117static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el);
118static struct brcmf_cfg80211_event_q *
119brcmf_deq_event(struct brcmf_cfg80211_priv *cfg_priv);
120static s32 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 type,
121 const struct brcmf_event_msg *msg, void *data);
122static void brcmf_put_event(struct brcmf_cfg80211_event_q *e);
123static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv);
124static s32 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
125 struct net_device *ndev,
126 const struct brcmf_event_msg *e,
127 void *data);
128static s32 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
129 struct net_device *ndev,
130 const struct brcmf_event_msg *e,
131 void *data);
132static s32 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
133 struct net_device *ndev,
134 const struct brcmf_event_msg *e,
135 void *data);
136static s32 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
137 struct net_device *ndev,
138 const struct brcmf_event_msg *e, void *data,
139 bool completed);
140static s32 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
141 struct net_device *ndev,
142 const struct brcmf_event_msg *e, void *data);
143static s32 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
144 struct net_device *ndev,
145 const struct brcmf_event_msg *e, void *data);
146
147/*
148** register/deregister sdio function
149*/
150static void brcmf_clear_sdio_func(void);
151
152/*
153** ioctl utilites
154*/
155static s32 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
156 s32 buf_len);
157static __used s32 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name,
158 s8 *buf, s32 len);
159static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
160static s32 brcmf_dev_intvar_get(struct net_device *dev, s8 *name,
161 s32 *retval);
162static s32 brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
163 u32 len);
164
165/*
166** cfg80211 set_wiphy_params utilities
167*/
168static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold);
169static s32 brcmf_set_rts(struct net_device *dev, u32 frag_threshold);
170static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l);
171
172/*
173** wl profile utilities
174*/
175static s32 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
176 const struct brcmf_event_msg *e,
177 void *data, s32 item);
178static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item);
179static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof);
180
181/*
182** cfg80211 connect utilites
183*/
184static s32 brcmf_set_wpa_version(struct net_device *dev,
185 struct cfg80211_connect_params *sme);
186static s32 brcmf_set_auth_type(struct net_device *dev,
187 struct cfg80211_connect_params *sme);
188static s32 brcmf_set_set_cipher(struct net_device *dev,
189 struct cfg80211_connect_params *sme);
190static s32 brcmf_set_key_mgmt(struct net_device *dev,
191 struct cfg80211_connect_params *sme);
192static s32 brcmf_set_set_sharedkey(struct net_device *dev,
193 struct cfg80211_connect_params *sme);
194static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv);
195static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv);
196static void brcmf_ch_to_chanspec(int ch,
197 struct brcmf_join_params *join_params, size_t *join_params_size);
198
199/*
200** information element utilities
201*/
202static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
203 u8 t, u8 l, u8 *v);
204static s32 brcmf_mode_to_nl80211_iftype(s32 mode);
205static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
206 struct device *dev);
207static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv);
208static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv);
209static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
210 struct brcmf_bss_info *bi);
211static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv);
212static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
213 u8 key_idx, const u8 *mac_addr,
214 struct key_params *params);
215
216/*
217** key indianess swap utilities
218*/
219static void swap_key_from_BE(struct brcmf_wsec_key *key);
220static void swap_key_to_BE(struct brcmf_wsec_key *key);
221
222/*
223** brcmf_cfg80211_priv memory init/deinit utilities
224*/
225static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv);
226static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv);
227
228static void brcmf_delay(u32 ms);
229
230/*
231** store/restore cfg80211 instance data
232*/
233static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data);
234static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev);
235
236/*
237** ibss mode utilities
238*/
239static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv);
240
241/*
242** dongle up/down , default configuration utilities
243*/
244static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
245 const struct brcmf_event_msg *e);
246static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
247 const struct brcmf_event_msg *e);
248static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
249 const struct brcmf_event_msg *e);
250static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv);
251static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype);
252static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv);
253static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv);
254static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv);
255static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf);
256
257/*
258** dongle configuration utilities
259*/
260static s32 brcmf_dongle_eventmsg(struct net_device *ndev);
261static s32 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
262 s32 scan_unassoc_time, s32 scan_passive_time);
263static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv,
264 bool need_lock);
265static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar,
266 u32 bcn_timeout);
267
268/*
269** iscan handler
270*/
271static void brcmf_iscan_timer(unsigned long data);
272static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv);
273static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv);
274static s32 brcmf_iscan_thread(void *data);
275static s32 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
276 void *param, s32 paramlen, void *bufptr,
277 s32 buflen);
278static s32 brcmf_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
279 void *param, s32 paramlen, void *bufptr,
280 s32 buflen);
281static s32 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
282 struct brcmf_ssid *ssid, u16 action);
283static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv);
284static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan);
285static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv);
286static s32 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan,
287 u32 *status,
288 struct brcmf_scan_results **bss_list);
289static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
290 bool aborted);
291static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el);
292static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv);
293static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv);
294static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv);
295static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv);
296
297/*
298* find most significant bit set
299*/
300static __used u32 brcmf_find_msb(u16 bit16);
301
302/*
303* update pmklist to dongle
304*/
305static __used s32 brcmf_update_pmklist(struct net_device *dev,
306 struct brcmf_cfg80211_pmk_list *pmk_list,
307 s32 err);
308
309static void brcmf_set_mpc(struct net_device *ndev, int mpc);
310
311/*
312* debufs support
313*/
314static int
315brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv);
316static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv);
317
318#define WL_PRIV_GET() \
319 ({ \
320 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg80211_dev); \
321 if (unlikely(!ci)) { \
322 WL_ERR("wl_cfg80211_dev is unavailable\n"); \
323 BUG(); \
324 } \
325 ci->cfg_priv; \
326})
327
328#define CHECK_SYS_UP() \
329do { \
330 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); \
331 if (unlikely(!test_bit(WL_STATUS_READY, &cfg_priv->status))) { \
332 WL_INFO("device is not ready : status (%d)\n", \
333 (int)cfg_priv->status); \
334 return -EIO; \
335 } \
336} while (0)
337
338#define CHAN2G(_channel, _freq, _flags) { \
339 .band = IEEE80211_BAND_2GHZ, \
340 .center_freq = (_freq), \
341 .hw_value = (_channel), \
342 .flags = (_flags), \
343 .max_antenna_gain = 0, \
344 .max_power = 30, \
345}
346
347#define CHAN5G(_channel, _flags) { \
348 .band = IEEE80211_BAND_5GHZ, \
349 .center_freq = 5000 + (5 * (_channel)), \
350 .hw_value = (_channel), \
351 .flags = (_flags), \
352 .max_antenna_gain = 0, \
353 .max_power = 30, \
354}
355
356#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
357#define RATETAB_ENT(_rateid, _flags) \
358 { \
359 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
360 .hw_value = (_rateid), \
361 .flags = (_flags), \
362 }
363
364static struct ieee80211_rate __wl_rates[] = {
365 RATETAB_ENT(BRCM_RATE_1M, 0),
366 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
367 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
368 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
369 RATETAB_ENT(BRCM_RATE_6M, 0),
370 RATETAB_ENT(BRCM_RATE_9M, 0),
371 RATETAB_ENT(BRCM_RATE_12M, 0),
372 RATETAB_ENT(BRCM_RATE_18M, 0),
373 RATETAB_ENT(BRCM_RATE_24M, 0),
374 RATETAB_ENT(BRCM_RATE_36M, 0),
375 RATETAB_ENT(BRCM_RATE_48M, 0),
376 RATETAB_ENT(BRCM_RATE_54M, 0),
377};
378
379#define wl_a_rates (__wl_rates + 4)
380#define wl_a_rates_size 8
381#define wl_g_rates (__wl_rates + 0)
382#define wl_g_rates_size 12
383
384static struct ieee80211_channel __wl_2ghz_channels[] = {
385 CHAN2G(1, 2412, 0),
386 CHAN2G(2, 2417, 0),
387 CHAN2G(3, 2422, 0),
388 CHAN2G(4, 2427, 0),
389 CHAN2G(5, 2432, 0),
390 CHAN2G(6, 2437, 0),
391 CHAN2G(7, 2442, 0),
392 CHAN2G(8, 2447, 0),
393 CHAN2G(9, 2452, 0),
394 CHAN2G(10, 2457, 0),
395 CHAN2G(11, 2462, 0),
396 CHAN2G(12, 2467, 0),
397 CHAN2G(13, 2472, 0),
398 CHAN2G(14, 2484, 0),
399};
400
401static struct ieee80211_channel __wl_5ghz_a_channels[] = {
402 CHAN5G(34, 0), CHAN5G(36, 0),
403 CHAN5G(38, 0), CHAN5G(40, 0),
404 CHAN5G(42, 0), CHAN5G(44, 0),
405 CHAN5G(46, 0), CHAN5G(48, 0),
406 CHAN5G(52, 0), CHAN5G(56, 0),
407 CHAN5G(60, 0), CHAN5G(64, 0),
408 CHAN5G(100, 0), CHAN5G(104, 0),
409 CHAN5G(108, 0), CHAN5G(112, 0),
410 CHAN5G(116, 0), CHAN5G(120, 0),
411 CHAN5G(124, 0), CHAN5G(128, 0),
412 CHAN5G(132, 0), CHAN5G(136, 0),
413 CHAN5G(140, 0), CHAN5G(149, 0),
414 CHAN5G(153, 0), CHAN5G(157, 0),
415 CHAN5G(161, 0), CHAN5G(165, 0),
416 CHAN5G(184, 0), CHAN5G(188, 0),
417 CHAN5G(192, 0), CHAN5G(196, 0),
418 CHAN5G(200, 0), CHAN5G(204, 0),
419 CHAN5G(208, 0), CHAN5G(212, 0),
420 CHAN5G(216, 0),
421};
422
423static struct ieee80211_channel __wl_5ghz_n_channels[] = {
424 CHAN5G(32, 0), CHAN5G(34, 0),
425 CHAN5G(36, 0), CHAN5G(38, 0),
426 CHAN5G(40, 0), CHAN5G(42, 0),
427 CHAN5G(44, 0), CHAN5G(46, 0),
428 CHAN5G(48, 0), CHAN5G(50, 0),
429 CHAN5G(52, 0), CHAN5G(54, 0),
430 CHAN5G(56, 0), CHAN5G(58, 0),
431 CHAN5G(60, 0), CHAN5G(62, 0),
432 CHAN5G(64, 0), CHAN5G(66, 0),
433 CHAN5G(68, 0), CHAN5G(70, 0),
434 CHAN5G(72, 0), CHAN5G(74, 0),
435 CHAN5G(76, 0), CHAN5G(78, 0),
436 CHAN5G(80, 0), CHAN5G(82, 0),
437 CHAN5G(84, 0), CHAN5G(86, 0),
438 CHAN5G(88, 0), CHAN5G(90, 0),
439 CHAN5G(92, 0), CHAN5G(94, 0),
440 CHAN5G(96, 0), CHAN5G(98, 0),
441 CHAN5G(100, 0), CHAN5G(102, 0),
442 CHAN5G(104, 0), CHAN5G(106, 0),
443 CHAN5G(108, 0), CHAN5G(110, 0),
444 CHAN5G(112, 0), CHAN5G(114, 0),
445 CHAN5G(116, 0), CHAN5G(118, 0),
446 CHAN5G(120, 0), CHAN5G(122, 0),
447 CHAN5G(124, 0), CHAN5G(126, 0),
448 CHAN5G(128, 0), CHAN5G(130, 0),
449 CHAN5G(132, 0), CHAN5G(134, 0),
450 CHAN5G(136, 0), CHAN5G(138, 0),
451 CHAN5G(140, 0), CHAN5G(142, 0),
452 CHAN5G(144, 0), CHAN5G(145, 0),
453 CHAN5G(146, 0), CHAN5G(147, 0),
454 CHAN5G(148, 0), CHAN5G(149, 0),
455 CHAN5G(150, 0), CHAN5G(151, 0),
456 CHAN5G(152, 0), CHAN5G(153, 0),
457 CHAN5G(154, 0), CHAN5G(155, 0),
458 CHAN5G(156, 0), CHAN5G(157, 0),
459 CHAN5G(158, 0), CHAN5G(159, 0),
460 CHAN5G(160, 0), CHAN5G(161, 0),
461 CHAN5G(162, 0), CHAN5G(163, 0),
462 CHAN5G(164, 0), CHAN5G(165, 0),
463 CHAN5G(166, 0), CHAN5G(168, 0),
464 CHAN5G(170, 0), CHAN5G(172, 0),
465 CHAN5G(174, 0), CHAN5G(176, 0),
466 CHAN5G(178, 0), CHAN5G(180, 0),
467 CHAN5G(182, 0), CHAN5G(184, 0),
468 CHAN5G(186, 0), CHAN5G(188, 0),
469 CHAN5G(190, 0), CHAN5G(192, 0),
470 CHAN5G(194, 0), CHAN5G(196, 0),
471 CHAN5G(198, 0), CHAN5G(200, 0),
472 CHAN5G(202, 0), CHAN5G(204, 0),
473 CHAN5G(206, 0), CHAN5G(208, 0),
474 CHAN5G(210, 0), CHAN5G(212, 0),
475 CHAN5G(214, 0), CHAN5G(216, 0),
476 CHAN5G(218, 0), CHAN5G(220, 0),
477 CHAN5G(222, 0), CHAN5G(224, 0),
478 CHAN5G(226, 0), CHAN5G(228, 0),
479};
480
481static struct ieee80211_supported_band __wl_band_2ghz = {
482 .band = IEEE80211_BAND_2GHZ,
483 .channels = __wl_2ghz_channels,
484 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
485 .bitrates = wl_g_rates,
486 .n_bitrates = wl_g_rates_size,
487};
488
489static struct ieee80211_supported_band __wl_band_5ghz_a = {
490 .band = IEEE80211_BAND_5GHZ,
491 .channels = __wl_5ghz_a_channels,
492 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
493 .bitrates = wl_a_rates,
494 .n_bitrates = wl_a_rates_size,
495};
496
497static struct ieee80211_supported_band __wl_band_5ghz_n = {
498 .band = IEEE80211_BAND_5GHZ,
499 .channels = __wl_5ghz_n_channels,
500 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
501 .bitrates = wl_a_rates,
502 .n_bitrates = wl_a_rates_size,
503};
504
505static const u32 __wl_cipher_suites[] = {
506 WLAN_CIPHER_SUITE_WEP40,
507 WLAN_CIPHER_SUITE_WEP104,
508 WLAN_CIPHER_SUITE_TKIP,
509 WLAN_CIPHER_SUITE_CCMP,
510 WLAN_CIPHER_SUITE_AES_CMAC,
511};
512
513static void swap_key_from_BE(struct brcmf_wsec_key *key)
514{
515 key->index = cpu_to_le32(key->index);
516 key->len = cpu_to_le32(key->len);
517 key->algo = cpu_to_le32(key->algo);
518 key->flags = cpu_to_le32(key->flags);
519 key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
520 key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
521 key->iv_initialized = cpu_to_le32(key->iv_initialized);
522}
523
524static void swap_key_to_BE(struct brcmf_wsec_key *key)
525{
526 key->index = le32_to_cpu(key->index);
527 key->len = le32_to_cpu(key->len);
528 key->algo = le32_to_cpu(key->algo);
529 key->flags = le32_to_cpu(key->flags);
530 key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
531 key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
532 key->iv_initialized = le32_to_cpu(key->iv_initialized);
533}
534
535static s32
536brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
537{
538 struct ifreq ifr;
539 struct brcmf_ioctl ioc;
540 mm_segment_t fs;
541 s32 err = 0;
542
543 memset(&ioc, 0, sizeof(ioc));
544 ioc.cmd = cmd;
545 ioc.buf = arg;
546 ioc.len = len;
547 strcpy(ifr.ifr_name, dev->name);
548 ifr.ifr_data = (caddr_t)&ioc;
549
550 fs = get_fs();
551 set_fs(get_ds());
552 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
553 set_fs(fs);
554
555 return err;
556}
557
558static s32
559brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
560 enum nl80211_iftype type, u32 *flags,
561 struct vif_params *params)
562{
563 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
564 struct wireless_dev *wdev;
565 s32 infra = 0;
566 s32 err = 0;
567
568 WL_TRACE("Enter\n");
569 CHECK_SYS_UP();
570
571 switch (type) {
572 case NL80211_IFTYPE_MONITOR:
573 case NL80211_IFTYPE_WDS:
574 WL_ERR("type (%d) : currently we do not support this type\n",
575 type);
576 return -EOPNOTSUPP;
577 case NL80211_IFTYPE_ADHOC:
578 cfg_priv->conf->mode = WL_MODE_IBSS;
579 infra = 0;
580 break;
581 case NL80211_IFTYPE_STATION:
582 cfg_priv->conf->mode = WL_MODE_BSS;
583 infra = 1;
584 break;
585 default:
586 err = -EINVAL;
587 goto done;
588 }
589
590 infra = cpu_to_le32(infra);
591 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
592 if (unlikely(err)) {
593 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
594 err = -EAGAIN;
595 } else {
596 wdev = ndev->ieee80211_ptr;
597 wdev->iftype = type;
598 }
599
600 WL_INFO("IF Type = %s\n",
601 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
602
603done:
604 WL_TRACE("Exit\n");
605
606 return err;
607}
608
609static void wl_iscan_prep(struct brcmf_scan_params *params,
610 struct brcmf_ssid *ssid)
611{
612 memcpy(params->bssid, ether_bcast, ETH_ALEN);
613 params->bss_type = DOT11_BSSTYPE_ANY;
614 params->scan_type = 0;
615 params->nprobes = -1;
616 params->active_time = -1;
617 params->passive_time = -1;
618 params->home_time = -1;
619 params->channel_num = 0;
620
621 params->nprobes = cpu_to_le32(params->nprobes);
622 params->active_time = cpu_to_le32(params->active_time);
623 params->passive_time = cpu_to_le32(params->passive_time);
624 params->home_time = cpu_to_le32(params->home_time);
625 if (ssid && ssid->SSID_len)
626 memcpy(&params->ssid, ssid, sizeof(struct brcmf_ssid));
627
628}
629
630static s32
631brcmf_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
632 s32 paramlen, void *bufptr, s32 buflen)
633{
634 s32 iolen;
635
636 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
637 BUG_ON(!iolen);
638
639 return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, bufptr, iolen);
640}
641
642static s32
643brcmf_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
644 s32 paramlen, void *bufptr, s32 buflen)
645{
646 s32 iolen;
647
648 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
649 BUG_ON(!iolen);
650
651 return brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, bufptr, buflen);
652}
653
654static s32
655brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
656 struct brcmf_ssid *ssid, u16 action)
657{
658 s32 params_size = (BRCMF_SCAN_PARAMS_FIXED_SIZE +
659 offsetof(struct brcmf_iscan_params, params));
660 struct brcmf_iscan_params *params;
661 s32 err = 0;
662
663 if (ssid && ssid->SSID_len)
664 params_size += sizeof(struct brcmf_ssid);
665 params = kzalloc(params_size, GFP_KERNEL);
666 if (unlikely(!params))
667 return -ENOMEM;
668 BUG_ON(params_size >= BRCMF_C_IOCTL_SMLEN);
669
670 wl_iscan_prep(&params->params, ssid);
671
672 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
673 params->action = cpu_to_le16(action);
674 params->scan_duration = cpu_to_le16(0);
675
676 /* params_size += offsetof(struct brcmf_iscan_params, params); */
677 err = brcmf_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
678 iscan->ioctl_buf, BRCMF_C_IOCTL_SMLEN);
679 if (unlikely(err)) {
680 if (err == -EBUSY) {
681 WL_INFO("system busy : iscan canceled\n");
682 } else {
683 WL_ERR("error (%d)\n", err);
684 }
685 }
686 kfree(params);
687 return err;
688}
689
690static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
691{
692 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
693 struct net_device *ndev = cfg_to_ndev(cfg_priv);
694 struct brcmf_ssid ssid;
695 s32 passive_scan;
696 s32 err = 0;
697
698 /* Broadcast scan by default */
699 memset(&ssid, 0, sizeof(ssid));
700
701 iscan->state = WL_ISCAN_STATE_SCANING;
702
703 passive_scan = cfg_priv->active_scan ? 0 : 1;
704 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
705 &passive_scan, sizeof(passive_scan));
706 if (unlikely(err)) {
707 WL_ERR("error (%d)\n", err);
708 return err;
709 }
710 brcmf_set_mpc(ndev, 0);
711 cfg_priv->iscan_kickstart = true;
712 brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
713 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
714 iscan->timer_on = 1;
715
716 return err;
717}
718
719static s32
720__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
721 struct cfg80211_scan_request *request,
722 struct cfg80211_ssid *this_ssid)
723{
724 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
725 struct cfg80211_ssid *ssids;
726 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
727 s32 passive_scan;
728 bool iscan_req;
729 bool spec_scan;
730 s32 err = 0;
731
732 if (unlikely(test_bit(WL_STATUS_SCANNING, &cfg_priv->status))) {
733 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
734 return -EAGAIN;
735 }
736 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status))) {
737 WL_ERR("Scanning being aborted : status (%lu)\n",
738 cfg_priv->status);
739 return -EAGAIN;
740 }
741 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
742 WL_ERR("Connecting : status (%lu)\n",
743 cfg_priv->status);
744 return -EAGAIN;
745 }
746
747 iscan_req = false;
748 spec_scan = false;
749 if (request) {
750 /* scan bss */
751 ssids = request->ssids;
752 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
753 iscan_req = true;
754 } else {
755 /* scan in ibss */
756 /* we don't do iscan in ibss */
757 ssids = this_ssid;
758 }
759
760 cfg_priv->scan_request = request;
761 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
762 if (iscan_req) {
763 err = brcmf_do_iscan(cfg_priv);
764 if (likely(!err))
765 return err;
766 else
767 goto scan_out;
768 } else {
769 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
770 ssids->ssid, ssids->ssid_len);
771 memset(&sr->ssid, 0, sizeof(sr->ssid));
772 sr->ssid.SSID_len =
773 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
774 if (sr->ssid.SSID_len) {
775 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
776 sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
777 spec_scan = true;
778 } else {
779 WL_SCAN("Broadcast scan\n");
780 }
781
782 passive_scan = cfg_priv->active_scan ? 0 : 1;
783 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_PASSIVE_SCAN,
784 &passive_scan, sizeof(passive_scan));
785 if (unlikely(err)) {
786 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
787 goto scan_out;
788 }
789 brcmf_set_mpc(ndev, 0);
790 err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN, &sr->ssid,
791 sizeof(sr->ssid));
792 if (err) {
793 if (err == -EBUSY) {
794 WL_INFO("system busy : scan for \"%s\" canceled\n",
795 sr->ssid.SSID);
796 } else {
797 WL_ERR("WLC_SCAN error (%d)\n", err);
798 }
799 brcmf_set_mpc(ndev, 1);
800 goto scan_out;
801 }
802 }
803
804 return 0;
805
806scan_out:
807 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
808 cfg_priv->scan_request = NULL;
809 return err;
810}
811
812static s32
813brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
814 struct cfg80211_scan_request *request)
815{
816 s32 err = 0;
817
818 WL_TRACE("Enter\n");
819
820 CHECK_SYS_UP();
821
822 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
823 if (unlikely(err))
824 WL_ERR("scan error (%d)\n", err);
825
826 WL_TRACE("Exit\n");
827 return err;
828}
829
830static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
831{
832 s8 buf[BRCMF_C_IOCTL_SMLEN];
833 u32 len;
834 s32 err = 0;
835
836 val = cpu_to_le32(val);
837 len = brcmu_mkiovar(name, (char *)(&val), sizeof(val), buf,
838 sizeof(buf));
839 BUG_ON(!len);
840
841 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, buf, len);
842 if (unlikely(err))
843 WL_ERR("error (%d)\n", err);
844
845 return err;
846}
847
848static s32
849brcmf_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
850{
851 union {
852 s8 buf[BRCMF_C_IOCTL_SMLEN];
853 s32 val;
854 } var;
855 u32 len;
856 u32 data_null;
857 s32 err = 0;
858
859 len =
860 brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
861 sizeof(var.buf));
862 BUG_ON(!len);
863 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, &var, len);
864 if (unlikely(err))
865 WL_ERR("error (%d)\n", err);
866
867 *retval = le32_to_cpu(var.val);
868
869 return err;
870}
871
872static s32 brcmf_set_rts(struct net_device *dev, u32 rts_threshold)
873{
874 s32 err = 0;
875
876 err = brcmf_dev_intvar_set(dev, "rtsthresh", rts_threshold);
877 if (unlikely(err))
878 WL_ERR("Error (%d)\n", err);
879
880 return err;
881}
882
883static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold)
884{
885 s32 err = 0;
886
887 err = brcmf_dev_intvar_set(dev, "fragthresh", frag_threshold);
888 if (unlikely(err))
889 WL_ERR("Error (%d)\n", err);
890
891 return err;
892}
893
894static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l)
895{
896 s32 err = 0;
897 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
898
899 retry = cpu_to_le32(retry);
900 err = brcmf_dev_ioctl(dev, cmd, &retry, sizeof(retry));
901 if (unlikely(err)) {
902 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
903 return err;
904 }
905 return err;
906}
907
908static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
909{
910 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
911 struct net_device *ndev = cfg_to_ndev(cfg_priv);
912 s32 err = 0;
913
914 WL_TRACE("Enter\n");
915 CHECK_SYS_UP();
916
917 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
918 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
919 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
920 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
921 if (!err)
922 goto done;
923 }
924 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
925 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
926 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
927 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
928 if (!err)
929 goto done;
930 }
931 if (changed & WIPHY_PARAM_RETRY_LONG
932 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
933 cfg_priv->conf->retry_long = wiphy->retry_long;
934 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
935 if (!err)
936 goto done;
937 }
938 if (changed & WIPHY_PARAM_RETRY_SHORT
939 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
940 cfg_priv->conf->retry_short = wiphy->retry_short;
941 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
942 if (!err)
943 goto done;
944 }
945
946done:
947 WL_TRACE("Exit\n");
948 return err;
949}
950
951static s32
952brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
953 struct cfg80211_ibss_params *params)
954{
955 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
956 struct brcmf_join_params join_params;
957 size_t join_params_size = 0;
958 s32 err = 0;
959 s32 wsec = 0;
960 s32 bcnprd;
961
962 WL_TRACE("Enter\n");
963 CHECK_SYS_UP();
964
965 if (params->ssid)
966 WL_CONN("SSID: %s\n", params->ssid);
967 else {
968 WL_CONN("SSID: NULL, Not supported\n");
969 return -EOPNOTSUPP;
970 }
971
972 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
973
974 if (params->bssid)
975 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
976 params->bssid[0], params->bssid[1], params->bssid[2],
977 params->bssid[3], params->bssid[4], params->bssid[5]);
978 else
979 WL_CONN("No BSSID specified\n");
980
981 if (params->channel)
982 WL_CONN("channel: %d\n", params->channel->center_freq);
983 else
984 WL_CONN("no channel specified\n");
985
986 if (params->channel_fixed)
987 WL_CONN("fixed channel required\n");
988 else
989 WL_CONN("no fixed channel required\n");
990
991 if (params->ie && params->ie_len)
992 WL_CONN("ie len: %d\n", params->ie_len);
993 else
994 WL_CONN("no ie specified\n");
995
996 if (params->beacon_interval)
997 WL_CONN("beacon interval: %d\n", params->beacon_interval);
998 else
999 WL_CONN("no beacon interval specified\n");
1000
1001 if (params->basic_rates)
1002 WL_CONN("basic rates: %08X\n", params->basic_rates);
1003 else
1004 WL_CONN("no basic rates specified\n");
1005
1006 if (params->privacy)
1007 WL_CONN("privacy required\n");
1008 else
1009 WL_CONN("no privacy required\n");
1010
1011 /* Configure Privacy for starter */
1012 if (params->privacy)
1013 wsec |= WEP_ENABLED;
1014
1015 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1016 if (unlikely(err)) {
1017 WL_ERR("wsec failed (%d)\n", err);
1018 goto done;
1019 }
1020
1021 /* Configure Beacon Interval for starter */
1022 if (params->beacon_interval)
1023 bcnprd = cpu_to_le32(params->beacon_interval);
1024 else
1025 bcnprd = cpu_to_le32(100);
1026
1027 err = brcmf_dev_ioctl(dev, BRCM_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
1028 if (unlikely(err)) {
1029 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1030 goto done;
1031 }
1032
1033 /* Configure required join parameter */
1034 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1035
1036 /* SSID */
1037 join_params.ssid.SSID_len =
1038 (params->ssid_len > 32) ? 32 : params->ssid_len;
1039 memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
1040 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1041 join_params_size = sizeof(join_params.ssid);
1042 brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID);
1043
1044 /* BSSID */
1045 if (params->bssid) {
1046 memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
1047 join_params_size = sizeof(join_params.ssid) +
1048 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1049 } else {
1050 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1051 }
1052 brcmf_update_prof(cfg_priv, NULL,
1053 &join_params.params.bssid, WL_PROF_BSSID);
1054
1055 /* Channel */
1056 if (params->channel) {
1057 u32 target_channel;
1058
1059 cfg_priv->channel =
1060 ieee80211_frequency_to_channel(
1061 params->channel->center_freq);
1062 if (params->channel_fixed) {
1063 /* adding chanspec */
1064 brcmf_ch_to_chanspec(cfg_priv->channel,
1065 &join_params, &join_params_size);
1066 }
1067
1068 /* set channel for starter */
1069 target_channel = cpu_to_le32(cfg_priv->channel);
1070 err = brcmf_dev_ioctl(dev, BRCM_SET_CHANNEL,
1071 &target_channel, sizeof(target_channel));
1072 if (unlikely(err)) {
1073 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1074 goto done;
1075 }
1076 } else
1077 cfg_priv->channel = 0;
1078
1079 cfg_priv->ibss_starter = false;
1080
1081
1082 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID,
1083 &join_params, join_params_size);
1084 if (unlikely(err)) {
1085 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1086 goto done;
1087 }
1088
1089done:
1090 if (err)
1091 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1092 WL_TRACE("Exit\n");
1093 return err;
1094}
1095
1096static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1097{
1098 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1099 s32 err = 0;
1100
1101 WL_TRACE("Enter\n");
1102 CHECK_SYS_UP();
1103
1104 brcmf_link_down(cfg_priv);
1105
1106 WL_TRACE("Exit\n");
1107
1108 return err;
1109}
1110
1111static s32
1112brcmf_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1113{
1114 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1115 struct brcmf_cfg80211_security *sec;
1116 s32 val = 0;
1117 s32 err = 0;
1118
1119 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1120 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1121 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1122 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1123 else
1124 val = WPA_AUTH_DISABLED;
1125 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1126 err = brcmf_dev_intvar_set(dev, "wpa_auth", val);
1127 if (unlikely(err)) {
1128 WL_ERR("set wpa_auth failed (%d)\n", err);
1129 return err;
1130 }
1131 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1132 sec->wpa_versions = sme->crypto.wpa_versions;
1133 return err;
1134}
1135
1136static s32
1137brcmf_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1138{
1139 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1140 struct brcmf_cfg80211_security *sec;
1141 s32 val = 0;
1142 s32 err = 0;
1143
1144 switch (sme->auth_type) {
1145 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1146 val = 0;
1147 WL_CONN("open system\n");
1148 break;
1149 case NL80211_AUTHTYPE_SHARED_KEY:
1150 val = 1;
1151 WL_CONN("shared key\n");
1152 break;
1153 case NL80211_AUTHTYPE_AUTOMATIC:
1154 val = 2;
1155 WL_CONN("automatic\n");
1156 break;
1157 case NL80211_AUTHTYPE_NETWORK_EAP:
1158 WL_CONN("network eap\n");
1159 default:
1160 val = 2;
1161 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1162 break;
1163 }
1164
1165 err = brcmf_dev_intvar_set(dev, "auth", val);
1166 if (unlikely(err)) {
1167 WL_ERR("set auth failed (%d)\n", err);
1168 return err;
1169 }
1170 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1171 sec->auth_type = sme->auth_type;
1172 return err;
1173}
1174
1175static s32
1176brcmf_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1177{
1178 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1179 struct brcmf_cfg80211_security *sec;
1180 s32 pval = 0;
1181 s32 gval = 0;
1182 s32 err = 0;
1183
1184 if (sme->crypto.n_ciphers_pairwise) {
1185 switch (sme->crypto.ciphers_pairwise[0]) {
1186 case WLAN_CIPHER_SUITE_WEP40:
1187 case WLAN_CIPHER_SUITE_WEP104:
1188 pval = WEP_ENABLED;
1189 break;
1190 case WLAN_CIPHER_SUITE_TKIP:
1191 pval = TKIP_ENABLED;
1192 break;
1193 case WLAN_CIPHER_SUITE_CCMP:
1194 pval = AES_ENABLED;
1195 break;
1196 case WLAN_CIPHER_SUITE_AES_CMAC:
1197 pval = AES_ENABLED;
1198 break;
1199 default:
1200 WL_ERR("invalid cipher pairwise (%d)\n",
1201 sme->crypto.ciphers_pairwise[0]);
1202 return -EINVAL;
1203 }
1204 }
1205 if (sme->crypto.cipher_group) {
1206 switch (sme->crypto.cipher_group) {
1207 case WLAN_CIPHER_SUITE_WEP40:
1208 case WLAN_CIPHER_SUITE_WEP104:
1209 gval = WEP_ENABLED;
1210 break;
1211 case WLAN_CIPHER_SUITE_TKIP:
1212 gval = TKIP_ENABLED;
1213 break;
1214 case WLAN_CIPHER_SUITE_CCMP:
1215 gval = AES_ENABLED;
1216 break;
1217 case WLAN_CIPHER_SUITE_AES_CMAC:
1218 gval = AES_ENABLED;
1219 break;
1220 default:
1221 WL_ERR("invalid cipher group (%d)\n",
1222 sme->crypto.cipher_group);
1223 return -EINVAL;
1224 }
1225 }
1226
1227 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1228 err = brcmf_dev_intvar_set(dev, "wsec", pval | gval);
1229 if (unlikely(err)) {
1230 WL_ERR("error (%d)\n", err);
1231 return err;
1232 }
1233
1234 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1235 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1236 sec->cipher_group = sme->crypto.cipher_group;
1237
1238 return err;
1239}
1240
1241static s32
1242brcmf_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1243{
1244 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1245 struct brcmf_cfg80211_security *sec;
1246 s32 val = 0;
1247 s32 err = 0;
1248
1249 if (sme->crypto.n_akm_suites) {
1250 err = brcmf_dev_intvar_get(dev, "wpa_auth", &val);
1251 if (unlikely(err)) {
1252 WL_ERR("could not get wpa_auth (%d)\n", err);
1253 return err;
1254 }
1255 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1256 switch (sme->crypto.akm_suites[0]) {
1257 case WLAN_AKM_SUITE_8021X:
1258 val = WPA_AUTH_UNSPECIFIED;
1259 break;
1260 case WLAN_AKM_SUITE_PSK:
1261 val = WPA_AUTH_PSK;
1262 break;
1263 default:
1264 WL_ERR("invalid cipher group (%d)\n",
1265 sme->crypto.cipher_group);
1266 return -EINVAL;
1267 }
1268 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1269 switch (sme->crypto.akm_suites[0]) {
1270 case WLAN_AKM_SUITE_8021X:
1271 val = WPA2_AUTH_UNSPECIFIED;
1272 break;
1273 case WLAN_AKM_SUITE_PSK:
1274 val = WPA2_AUTH_PSK;
1275 break;
1276 default:
1277 WL_ERR("invalid cipher group (%d)\n",
1278 sme->crypto.cipher_group);
1279 return -EINVAL;
1280 }
1281 }
1282
1283 WL_CONN("setting wpa_auth to %d\n", val);
1284 err = brcmf_dev_intvar_set(dev, "wpa_auth", val);
1285 if (unlikely(err)) {
1286 WL_ERR("could not set wpa_auth (%d)\n", err);
1287 return err;
1288 }
1289 }
1290 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1291 sec->wpa_auth = sme->crypto.akm_suites[0];
1292
1293 return err;
1294}
1295
1296static s32
1297brcmf_set_set_sharedkey(struct net_device *dev,
1298 struct cfg80211_connect_params *sme)
1299{
1300 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1301 struct brcmf_cfg80211_security *sec;
1302 struct brcmf_wsec_key key;
1303 s32 val;
1304 s32 err = 0;
1305
1306 WL_CONN("key len (%d)\n", sme->key_len);
1307 if (sme->key_len) {
1308 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1309 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1310 sec->wpa_versions, sec->cipher_pairwise);
1311 if (!
1312 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1313 NL80211_WPA_VERSION_2))
1314&& (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1315 WLAN_CIPHER_SUITE_WEP104))) {
1316 memset(&key, 0, sizeof(key));
1317 key.len = (u32) sme->key_len;
1318 key.index = (u32) sme->key_idx;
1319 if (unlikely(key.len > sizeof(key.data))) {
1320 WL_ERR("Too long key length (%u)\n", key.len);
1321 return -EINVAL;
1322 }
1323 memcpy(key.data, sme->key, key.len);
1324 key.flags = BRCMF_PRIMARY_KEY;
1325 switch (sec->cipher_pairwise) {
1326 case WLAN_CIPHER_SUITE_WEP40:
1327 key.algo = CRYPTO_ALGO_WEP1;
1328 break;
1329 case WLAN_CIPHER_SUITE_WEP104:
1330 key.algo = CRYPTO_ALGO_WEP128;
1331 break;
1332 default:
1333 WL_ERR("Invalid algorithm (%d)\n",
1334 sme->crypto.ciphers_pairwise[0]);
1335 return -EINVAL;
1336 }
1337 /* Set the new key/index */
1338 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1339 key.len, key.index, key.algo);
1340 WL_CONN("key \"%s\"\n", key.data);
1341 swap_key_from_BE(&key);
1342 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key,
1343 sizeof(key));
1344 if (unlikely(err)) {
1345 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1346 return err;
1347 }
1348 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1349 WL_CONN("set auth_type to shared key\n");
1350 val = 1; /* shared key */
1351 err = brcmf_dev_intvar_set(dev, "auth", val);
1352 if (unlikely(err)) {
1353 WL_ERR("set auth failed (%d)\n", err);
1354 return err;
1355 }
1356 }
1357 }
1358 }
1359 return err;
1360}
1361
1362static s32
1363brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1364 struct cfg80211_connect_params *sme)
1365{
1366 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1367 struct ieee80211_channel *chan = sme->channel;
1368 struct brcmf_join_params join_params;
1369 size_t join_params_size;
1370
1371 s32 err = 0;
1372
1373 WL_TRACE("Enter\n");
1374 CHECK_SYS_UP();
1375
1376 if (unlikely(!sme->ssid)) {
1377 WL_ERR("Invalid ssid\n");
1378 return -EOPNOTSUPP;
1379 }
1380
1381 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1382
1383 if (chan) {
1384 cfg_priv->channel =
1385 ieee80211_frequency_to_channel(chan->center_freq);
1386 WL_CONN("channel (%d), center_req (%d)\n",
1387 cfg_priv->channel, chan->center_freq);
1388 } else
1389 cfg_priv->channel = 0;
1390
1391 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1392
1393 err = brcmf_set_wpa_version(dev, sme);
1394 if (err) {
1395 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1396 goto done;
1397 }
1398
1399 err = brcmf_set_auth_type(dev, sme);
1400 if (err) {
1401 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1402 goto done;
1403 }
1404
1405 err = brcmf_set_set_cipher(dev, sme);
1406 if (err) {
1407 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1408 goto done;
1409 }
1410
1411 err = brcmf_set_key_mgmt(dev, sme);
1412 if (err) {
1413 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1414 goto done;
1415 }
1416
1417 err = brcmf_set_set_sharedkey(dev, sme);
1418 if (err) {
1419 WL_ERR("wl_set_set_sharedkey failed (%d)\n", err);
1420 goto done;
1421 }
1422
1423 brcmf_update_prof(cfg_priv, NULL, sme->bssid, WL_PROF_BSSID);
1424 /*
1425 ** Join with specific BSSID and cached SSID
1426 ** If SSID is zero join based on BSSID only
1427 */
1428 memset(&join_params, 0, sizeof(join_params));
1429 join_params_size = sizeof(join_params.ssid);
1430
1431 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1432 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1433 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1434 brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID);
1435
1436 if (sme->bssid)
1437 memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN);
1438 else
1439 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1440
1441 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1442 WL_CONN("ssid \"%s\", len (%d)\n",
1443 join_params.ssid.SSID, join_params.ssid.SSID_len);
1444 }
1445
1446 brcmf_ch_to_chanspec(cfg_priv->channel,
1447 &join_params, &join_params_size);
1448 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID,
1449 &join_params, join_params_size);
1450 if (err)
1451 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1452
1453done:
1454 if (err)
1455 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1456 WL_TRACE("Exit\n");
1457 return err;
1458}
1459
1460static s32
1461brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1462 u16 reason_code)
1463{
1464 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1465 struct brcmf_scb_val scbval;
1466 s32 err = 0;
1467
1468 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1469 CHECK_SYS_UP();
1470
1471 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1472
1473 scbval.val = reason_code;
1474 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1475 scbval.val = cpu_to_le32(scbval.val);
1476 err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, &scbval,
1477 sizeof(struct brcmf_scb_val));
1478 if (unlikely(err))
1479 WL_ERR("error (%d)\n", err);
1480
1481 cfg_priv->link_up = false;
1482
1483 WL_TRACE("Exit\n");
1484 return err;
1485}
1486
1487static s32
1488brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1489 enum nl80211_tx_power_setting type, s32 dbm)
1490{
1491
1492 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1493 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1494 u16 txpwrmw;
1495 s32 err = 0;
1496 s32 disable = 0;
1497
1498 WL_TRACE("Enter\n");
1499 CHECK_SYS_UP();
1500
1501 switch (type) {
1502 case NL80211_TX_POWER_AUTOMATIC:
1503 break;
1504 case NL80211_TX_POWER_LIMITED:
1505 if (dbm < 0) {
1506 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1507 err = -EINVAL;
1508 goto done;
1509 }
1510 break;
1511 case NL80211_TX_POWER_FIXED:
1512 if (dbm < 0) {
1513 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1514 err = -EINVAL;
1515 goto done;
1516 }
1517 break;
1518 }
1519 /* Make sure radio is off or on as far as software is concerned */
1520 disable = WL_RADIO_SW_DISABLE << 16;
1521 disable = cpu_to_le32(disable);
1522 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_RADIO, &disable, sizeof(disable));
1523 if (unlikely(err))
1524 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1525
1526 if (dbm > 0xffff)
1527 txpwrmw = 0xffff;
1528 else
1529 txpwrmw = (u16) dbm;
1530 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1531 (s32) (brcmu_mw_to_qdbm(txpwrmw)));
1532 if (unlikely(err))
1533 WL_ERR("qtxpower error (%d)\n", err);
1534 cfg_priv->conf->tx_power = dbm;
1535
1536done:
1537 WL_TRACE("Exit\n");
1538 return err;
1539}
1540
1541static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1542{
1543 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1544 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1545 s32 txpwrdbm;
1546 u8 result;
1547 s32 err = 0;
1548
1549 WL_TRACE("Enter\n");
1550 CHECK_SYS_UP();
1551
1552 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1553 if (unlikely(err)) {
1554 WL_ERR("error (%d)\n", err);
1555 goto done;
1556 }
1557
1558 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1559 *dbm = (s32) brcmu_qdbm_to_mw(result);
1560
1561done:
1562 WL_TRACE("Exit\n");
1563 return err;
1564}
1565
1566static s32
1567brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1568 u8 key_idx, bool unicast, bool multicast)
1569{
1570 u32 index;
1571 s32 wsec;
1572 s32 err = 0;
1573
1574 WL_TRACE("Enter\n");
1575 WL_CONN("key index (%d)\n", key_idx);
1576 CHECK_SYS_UP();
1577
1578 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1579 if (unlikely(err)) {
1580 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1581 goto done;
1582 }
1583
1584 wsec = le32_to_cpu(wsec);
1585 if (wsec & WEP_ENABLED) {
1586 /* Just select a new current key */
1587 index = (u32) key_idx;
1588 index = cpu_to_le32(index);
1589 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY_PRIMARY, &index,
1590 sizeof(index));
1591 if (unlikely(err))
1592 WL_ERR("error (%d)\n", err);
1593 }
1594done:
1595 WL_TRACE("Exit\n");
1596 return err;
1597}
1598
1599static s32
1600brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1601 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1602{
1603 struct brcmf_wsec_key key;
1604 s32 err = 0;
1605
1606 memset(&key, 0, sizeof(key));
1607 key.index = (u32) key_idx;
1608 /* Instead of bcast for ea address for default wep keys,
1609 driver needs it to be Null */
1610 if (!is_multicast_ether_addr(mac_addr))
1611 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1612 key.len = (u32) params->key_len;
1613 /* check for key index change */
1614 if (key.len == 0) {
1615 /* key delete */
1616 swap_key_from_BE(&key);
1617 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1618 if (unlikely(err)) {
1619 WL_ERR("key delete error (%d)\n", err);
1620 return err;
1621 }
1622 } else {
1623 if (key.len > sizeof(key.data)) {
1624 WL_ERR("Invalid key length (%d)\n", key.len);
1625 return -EINVAL;
1626 }
1627
1628 WL_CONN("Setting the key index %d\n", key.index);
1629 memcpy(key.data, params->key, key.len);
1630
1631 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1632 u8 keybuf[8];
1633 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1634 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1635 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1636 }
1637
1638 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1639 if (params->seq && params->seq_len == 6) {
1640 /* rx iv */
1641 u8 *ivptr;
1642 ivptr = (u8 *) params->seq;
1643 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1644 (ivptr[3] << 8) | ivptr[2];
1645 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1646 key.iv_initialized = true;
1647 }
1648
1649 switch (params->cipher) {
1650 case WLAN_CIPHER_SUITE_WEP40:
1651 key.algo = CRYPTO_ALGO_WEP1;
1652 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1653 break;
1654 case WLAN_CIPHER_SUITE_WEP104:
1655 key.algo = CRYPTO_ALGO_WEP128;
1656 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1657 break;
1658 case WLAN_CIPHER_SUITE_TKIP:
1659 key.algo = CRYPTO_ALGO_TKIP;
1660 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1661 break;
1662 case WLAN_CIPHER_SUITE_AES_CMAC:
1663 key.algo = CRYPTO_ALGO_AES_CCM;
1664 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1665 break;
1666 case WLAN_CIPHER_SUITE_CCMP:
1667 key.algo = CRYPTO_ALGO_AES_CCM;
1668 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1669 break;
1670 default:
1671 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1672 return -EINVAL;
1673 }
1674 swap_key_from_BE(&key);
1675
1676 brcmf_netdev_wait_pend8021x(dev);
1677 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1678 if (unlikely(err)) {
1679 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1680 return err;
1681 }
1682 }
1683 return err;
1684}
1685
1686static s32
1687brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1688 u8 key_idx, bool pairwise, const u8 *mac_addr,
1689 struct key_params *params)
1690{
1691 struct brcmf_wsec_key key;
1692 s32 val;
1693 s32 wsec;
1694 s32 err = 0;
1695 u8 keybuf[8];
1696
1697 WL_TRACE("Enter\n");
1698 WL_CONN("key index (%d)\n", key_idx);
1699 CHECK_SYS_UP();
1700
1701 if (mac_addr) {
1702 WL_TRACE("Exit");
1703 return brcmf_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1704 }
1705 memset(&key, 0, sizeof(key));
1706
1707 key.len = (u32) params->key_len;
1708 key.index = (u32) key_idx;
1709
1710 if (unlikely(key.len > sizeof(key.data))) {
1711 WL_ERR("Too long key length (%u)\n", key.len);
1712 err = -EINVAL;
1713 goto done;
1714 }
1715 memcpy(key.data, params->key, key.len);
1716
1717 key.flags = BRCMF_PRIMARY_KEY;
1718 switch (params->cipher) {
1719 case WLAN_CIPHER_SUITE_WEP40:
1720 key.algo = CRYPTO_ALGO_WEP1;
1721 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1722 break;
1723 case WLAN_CIPHER_SUITE_WEP104:
1724 key.algo = CRYPTO_ALGO_WEP128;
1725 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1726 break;
1727 case WLAN_CIPHER_SUITE_TKIP:
1728 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1729 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1730 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1731 key.algo = CRYPTO_ALGO_TKIP;
1732 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1733 break;
1734 case WLAN_CIPHER_SUITE_AES_CMAC:
1735 key.algo = CRYPTO_ALGO_AES_CCM;
1736 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1737 break;
1738 case WLAN_CIPHER_SUITE_CCMP:
1739 key.algo = CRYPTO_ALGO_AES_CCM;
1740 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1741 break;
1742 default:
1743 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1744 err = -EINVAL;
1745 goto done;
1746 }
1747
1748 /* Set the new key/index */
1749 swap_key_from_BE(&key);
1750 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1751 if (unlikely(err)) {
1752 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1753 goto done;
1754 }
1755
1756 val = WEP_ENABLED;
1757 err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1758 if (unlikely(err)) {
1759 WL_ERR("get wsec error (%d)\n", err);
1760 goto done;
1761 }
1762 wsec &= ~(WEP_ENABLED);
1763 wsec |= val;
1764 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1765 if (unlikely(err)) {
1766 WL_ERR("set wsec error (%d)\n", err);
1767 goto done;
1768 }
1769
1770 val = 1; /* assume shared key. otherwise 0 */
1771 val = cpu_to_le32(val);
1772 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1773 if (unlikely(err))
1774 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1775done:
1776 WL_TRACE("Exit\n");
1777 return err;
1778}
1779
1780static s32
1781brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1782 u8 key_idx, bool pairwise, const u8 *mac_addr)
1783{
1784 struct brcmf_wsec_key key;
1785 s32 err = 0;
1786 s32 val;
1787 s32 wsec;
1788
1789 WL_TRACE("Enter\n");
1790 CHECK_SYS_UP();
1791 memset(&key, 0, sizeof(key));
1792
1793 key.index = (u32) key_idx;
1794 key.flags = BRCMF_PRIMARY_KEY;
1795 key.algo = CRYPTO_ALGO_OFF;
1796
1797 WL_CONN("key index (%d)\n", key_idx);
1798 /* Set the new key/index */
1799 swap_key_from_BE(&key);
1800 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1801 if (unlikely(err)) {
1802 if (err == -EINVAL) {
1803 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1804 /* we ignore this key index in this case */
1805 WL_ERR("invalid key index (%d)\n", key_idx);
1806 } else
1807 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1808
1809 /* Ignore this error, may happen during DISASSOC */
1810 err = -EAGAIN;
1811 goto done;
1812 }
1813
1814 val = 0;
1815 err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1816 if (unlikely(err)) {
1817 WL_ERR("get wsec error (%d)\n", err);
1818 /* Ignore this error, may happen during DISASSOC */
1819 err = -EAGAIN;
1820 goto done;
1821 }
1822 wsec &= ~(WEP_ENABLED);
1823 wsec |= val;
1824 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1825 if (unlikely(err)) {
1826 WL_ERR("set wsec error (%d)\n", err);
1827 /* Ignore this error, may happen during DISASSOC */
1828 err = -EAGAIN;
1829 goto done;
1830 }
1831
1832 val = 0; /* assume open key. otherwise 1 */
1833 val = cpu_to_le32(val);
1834 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1835 if (unlikely(err)) {
1836 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1837 /* Ignore this error, may happen during DISASSOC */
1838 err = -EAGAIN;
1839 }
1840done:
1841 WL_TRACE("Exit\n");
1842 return err;
1843}
1844
1845static s32
1846brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1847 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1848 void (*callback) (void *cookie, struct key_params * params))
1849{
1850 struct key_params params;
1851 struct brcmf_wsec_key key;
1852 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1853 struct brcmf_cfg80211_security *sec;
1854 s32 wsec;
1855 s32 err = 0;
1856
1857 WL_TRACE("Enter\n");
1858 WL_CONN("key index (%d)\n", key_idx);
1859 CHECK_SYS_UP();
1860
1861 memset(&key, 0, sizeof(key));
1862 key.index = key_idx;
1863 swap_key_to_BE(&key);
1864 memset(&params, 0, sizeof(params));
1865 params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
1866 memcpy(params.key, key.data, params.key_len);
1867
1868 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1869 if (unlikely(err)) {
1870 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1871 /* Ignore this error, may happen during DISASSOC */
1872 err = -EAGAIN;
1873 goto done;
1874 }
1875 wsec = le32_to_cpu(wsec);
1876 switch (wsec) {
1877 case WEP_ENABLED:
1878 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1879 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1880 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1881 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1882 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1883 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1884 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1885 }
1886 break;
1887 case TKIP_ENABLED:
1888 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1889 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1890 break;
1891 case AES_ENABLED:
1892 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1893 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1894 break;
1895 default:
1896 WL_ERR("Invalid algo (0x%x)\n", wsec);
1897 err = -EINVAL;
1898 goto done;
1899 }
1900 callback(cookie, &params);
1901
1902done:
1903 WL_TRACE("Exit\n");
1904 return err;
1905}
1906
1907static s32
1908brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1909 struct net_device *dev, u8 key_idx)
1910{
1911 WL_INFO("Not supported\n");
1912
1913 CHECK_SYS_UP();
1914 return -EOPNOTSUPP;
1915}
1916
1917static s32
1918brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1919 u8 *mac, struct station_info *sinfo)
1920{
1921 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1922 struct brcmf_scb_val scb_val;
1923 int rssi;
1924 s32 rate;
1925 s32 err = 0;
1926 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1927
1928 WL_TRACE("Enter\n");
1929 CHECK_SYS_UP();
1930
1931 if (unlikely
1932 (memcmp(mac, bssid, ETH_ALEN))) {
1933 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1934 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1935 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1936 bssid[0], bssid[1], bssid[2], bssid[3],
1937 bssid[4], bssid[5]);
1938 err = -ENOENT;
1939 goto done;
1940 }
1941
1942 /* Report the current tx rate */
1943 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RATE, &rate, sizeof(rate));
1944 if (err) {
1945 WL_ERR("Could not get rate (%d)\n", err);
1946 } else {
1947 rate = le32_to_cpu(rate);
1948 sinfo->filled |= STATION_INFO_TX_BITRATE;
1949 sinfo->txrate.legacy = rate * 5;
1950 WL_CONN("Rate %d Mbps\n", rate / 2);
1951 }
1952
1953 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1954 scb_val.val = 0;
1955 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RSSI, &scb_val,
1956 sizeof(struct brcmf_scb_val));
1957 if (unlikely(err)) {
1958 WL_ERR("Could not get rssi (%d)\n", err);
1959 }
1960 rssi = le32_to_cpu(scb_val.val);
1961 sinfo->filled |= STATION_INFO_SIGNAL;
1962 sinfo->signal = rssi;
1963 WL_CONN("RSSI %d dBm\n", rssi);
1964 }
1965
1966done:
1967 WL_TRACE("Exit\n");
1968 return err;
1969}
1970
1971static s32
1972brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1973 bool enabled, s32 timeout)
1974{
1975 s32 pm;
1976 s32 err = 0;
1977
1978 WL_TRACE("Enter\n");
1979 CHECK_SYS_UP();
1980
1981 pm = enabled ? PM_FAST : PM_OFF;
1982 pm = cpu_to_le32(pm);
1983 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1984
1985 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_PM, &pm, sizeof(pm));
1986 if (unlikely(err)) {
1987 if (err == -ENODEV)
1988 WL_ERR("net_device is not ready yet\n");
1989 else
1990 WL_ERR("error (%d)\n", err);
1991 }
1992 WL_TRACE("Exit\n");
1993 return err;
1994}
1995
1996static __used u32 brcmf_find_msb(u16 bit16)
1997{
1998 u32 ret = 0;
1999
2000 if (bit16 & 0xff00) {
2001 ret += 8;
2002 bit16 >>= 8;
2003 }
2004
2005 if (bit16 & 0xf0) {
2006 ret += 4;
2007 bit16 >>= 4;
2008 }
2009
2010 if (bit16 & 0xc) {
2011 ret += 2;
2012 bit16 >>= 2;
2013 }
2014
2015 if (bit16 & 2)
2016 ret += bit16 & 2;
2017 else if (bit16)
2018 ret += bit16;
2019
2020 return ret;
2021}
2022
2023static s32
2024brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
2025 const u8 *addr,
2026 const struct cfg80211_bitrate_mask *mask)
2027{
2028 struct wl_rateset rateset;
2029 s32 rate;
2030 s32 val;
2031 s32 err_bg;
2032 s32 err_a;
2033 u32 legacy;
2034 s32 err = 0;
2035
2036 WL_TRACE("Enter\n");
2037 CHECK_SYS_UP();
2038
2039 /* addr param is always NULL. ignore it */
2040 /* Get current rateset */
2041 err = brcmf_dev_ioctl(dev, BRCM_GET_CURR_RATESET, &rateset,
2042 sizeof(rateset));
2043 if (unlikely(err)) {
2044 WL_ERR("could not get current rateset (%d)\n", err);
2045 goto done;
2046 }
2047
2048 rateset.count = le32_to_cpu(rateset.count);
2049
2050 legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
2051 if (!legacy)
2052 legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
2053
2054 val = wl_g_rates[legacy - 1].bitrate * 100000;
2055
2056 if (val < rateset.count)
2057 /* Select rate by rateset index */
2058 rate = rateset.rates[val] & 0x7f;
2059 else
2060 /* Specified rate in bps */
2061 rate = val / 500000;
2062
2063 WL_CONN("rate %d mbps\n", rate / 2);
2064
2065 /*
2066 *
2067 * Set rate override,
2068 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2069 */
2070 err_bg = brcmf_dev_intvar_set(dev, "bg_rate", rate);
2071 err_a = brcmf_dev_intvar_set(dev, "a_rate", rate);
2072 if (unlikely(err_bg && err_a)) {
2073 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2074 err = err_bg | err_a;
2075 }
2076
2077done:
2078 WL_TRACE("Exit\n");
2079 return err;
2080}
2081
2082static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2083{
2084 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2085
2086 /*
2087 * Check for WL_STATUS_READY before any function call which
2088 * could result is bus access. Don't block the resume for
2089 * any driver error conditions
2090 */
2091 WL_TRACE("Enter\n");
2092
2093#if defined(CONFIG_PM_SLEEP)
2094 atomic_set(&brcmf_mmc_suspend, false);
2095#endif /* defined(CONFIG_PM_SLEEP) */
2096
2097 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2098 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2099
2100 WL_TRACE("Exit\n");
2101 return 0;
2102}
2103
2104static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2105 struct cfg80211_wowlan *wow)
2106{
2107 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2108 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2109
2110 WL_TRACE("Enter\n");
2111
2112 /*
2113 * Check for WL_STATUS_READY before any function call which
2114 * could result is bus access. Don't block the suspend for
2115 * any driver error conditions
2116 */
2117
2118 /*
2119 * While going to suspend if associated with AP disassociate
2120 * from AP to save power while system is in suspended state
2121 */
2122 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2123 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2124 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2125 WL_INFO("Disassociating from AP"
2126 " while entering suspend state\n");
2127 brcmf_link_down(cfg_priv);
2128
2129 /*
2130 * Make sure WPA_Supplicant receives all the event
2131 * generated due to DISASSOC call to the fw to keep
2132 * the state fw and WPA_Supplicant state consistent
2133 */
2134 rtnl_unlock();
2135 brcmf_delay(500);
2136 rtnl_lock();
2137 }
2138
2139 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2140 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2141 brcmf_term_iscan(cfg_priv);
2142
2143 if (cfg_priv->scan_request) {
2144 /* Indidate scan abort to cfg80211 layer */
2145 WL_INFO("Terminating scan in progress\n");
2146 cfg80211_scan_done(cfg_priv->scan_request, true);
2147 cfg_priv->scan_request = NULL;
2148 }
2149 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2150 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2151
2152 /* Turn off watchdog timer */
2153 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2154 WL_INFO("Enable MPC\n");
2155 brcmf_set_mpc(ndev, 1);
2156 }
2157
2158#if defined(CONFIG_PM_SLEEP)
2159 atomic_set(&brcmf_mmc_suspend, true);
2160#endif /* defined(CONFIG_PM_SLEEP) */
2161
2162 WL_TRACE("Exit\n");
2163
2164 return 0;
2165}
2166
2167static __used s32
2168brcmf_update_pmklist(struct net_device *dev,
2169 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2170{
2171 int i, j;
2172
2173 WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2174 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2175 WL_CONN("PMKID[%d]: %pM =\n", i,
2176 &pmk_list->pmkids.pmkid[i].BSSID);
2177 for (j = 0; j < WLAN_PMKID_LEN; j++)
2178 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2179 }
2180
2181 if (likely(!err))
2182 brcmf_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2183 sizeof(*pmk_list));
2184
2185 return err;
2186}
2187
2188static s32
2189brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2190 struct cfg80211_pmksa *pmksa)
2191{
2192 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2193 struct _pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2194 s32 err = 0;
2195 int i;
2196
2197 WL_TRACE("Enter\n");
2198 CHECK_SYS_UP();
2199
2200 for (i = 0; i < pmkids->npmkid; i++)
2201 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2202 break;
2203 if (i < WL_NUM_PMKIDS_MAX) {
2204 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2205 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2206 if (i == pmkids->npmkid)
2207 pmkids->npmkid++;
2208 } else
2209 err = -EINVAL;
2210
2211 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2212 pmkids->pmkid[pmkids->npmkid].BSSID);
2213 for (i = 0; i < WLAN_PMKID_LEN; i++)
2214 WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
2215
2216 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2217
2218 WL_TRACE("Exit\n");
2219 return err;
2220}
2221
2222static s32
2223brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2224 struct cfg80211_pmksa *pmksa)
2225{
2226 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2227 struct _pmkid_list pmkid;
2228 s32 err = 0;
2229 int i;
2230
2231 WL_TRACE("Enter\n");
2232 CHECK_SYS_UP();
2233 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2234 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2235
2236 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2237 &pmkid.pmkid[0].BSSID);
2238 for (i = 0; i < WLAN_PMKID_LEN; i++)
2239 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2240
2241 for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
2242 if (!memcmp
2243 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2244 ETH_ALEN))
2245 break;
2246
2247 if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
2248 && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
2249 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2250 sizeof(pmkid_t));
2251 for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
2252 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2253 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2254 ETH_ALEN);
2255 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2256 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2257 WLAN_PMKID_LEN);
2258 }
2259 cfg_priv->pmk_list->pmkids.npmkid--;
2260 } else
2261 err = -EINVAL;
2262
2263 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2264
2265 WL_TRACE("Exit\n");
2266 return err;
2267
2268}
2269
2270static s32
2271brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2272{
2273 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2274 s32 err = 0;
2275
2276 WL_TRACE("Enter\n");
2277 CHECK_SYS_UP();
2278
2279 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2280 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2281
2282 WL_TRACE("Exit\n");
2283 return err;
2284
2285}
2286
2287static struct cfg80211_ops wl_cfg80211_ops = {
2288 .change_virtual_intf = brcmf_cfg80211_change_iface,
2289 .scan = brcmf_cfg80211_scan,
2290 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2291 .join_ibss = brcmf_cfg80211_join_ibss,
2292 .leave_ibss = brcmf_cfg80211_leave_ibss,
2293 .get_station = brcmf_cfg80211_get_station,
2294 .set_tx_power = brcmf_cfg80211_set_tx_power,
2295 .get_tx_power = brcmf_cfg80211_get_tx_power,
2296 .add_key = brcmf_cfg80211_add_key,
2297 .del_key = brcmf_cfg80211_del_key,
2298 .get_key = brcmf_cfg80211_get_key,
2299 .set_default_key = brcmf_cfg80211_config_default_key,
2300 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2301 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2302 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2303 .connect = brcmf_cfg80211_connect,
2304 .disconnect = brcmf_cfg80211_disconnect,
2305 .suspend = brcmf_cfg80211_suspend,
2306 .resume = brcmf_cfg80211_resume,
2307 .set_pmksa = brcmf_cfg80211_set_pmksa,
2308 .del_pmksa = brcmf_cfg80211_del_pmksa,
2309 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2310};
2311
2312static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2313{
2314 s32 err = 0;
2315
2316 switch (mode) {
2317 case WL_MODE_BSS:
2318 return NL80211_IFTYPE_STATION;
2319 case WL_MODE_IBSS:
2320 return NL80211_IFTYPE_ADHOC;
2321 default:
2322 return NL80211_IFTYPE_UNSPECIFIED;
2323 }
2324
2325 return err;
2326}
2327
2328static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2329 struct device *dev)
2330{
2331 struct wireless_dev *wdev;
2332 s32 err = 0;
2333
2334 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2335 if (unlikely(!wdev)) {
2336 WL_ERR("Could not allocate wireless device\n");
2337 return ERR_PTR(-ENOMEM);
2338 }
2339 wdev->wiphy =
2340 wiphy_new(&wl_cfg80211_ops,
2341 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2342 if (unlikely(!wdev->wiphy)) {
2343 WL_ERR("Couldn not allocate wiphy device\n");
2344 err = -ENOMEM;
2345 goto wiphy_new_out;
2346 }
2347 set_wiphy_dev(wdev->wiphy, dev);
2348 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2349 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2350 wdev->wiphy->interface_modes =
2351 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2352 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2353 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2354 * it as 11a by default.
2355 * This will be updated with
2356 * 11n phy tables in
2357 * "ifconfig up"
2358 * if phy has 11n capability
2359 */
2360 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2361 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2362 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2363#ifndef WL_POWERSAVE_DISABLED
2364 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2365 * save mode
2366 * by default
2367 */
2368#else
2369 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2370#endif /* !WL_POWERSAVE_DISABLED */
2371 err = wiphy_register(wdev->wiphy);
2372 if (unlikely(err < 0)) {
2373 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2374 goto wiphy_register_out;
2375 }
2376 return wdev;
2377
2378wiphy_register_out:
2379 wiphy_free(wdev->wiphy);
2380
2381wiphy_new_out:
2382 kfree(wdev);
2383
2384 return ERR_PTR(err);
2385}
2386
2387static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2388{
2389 struct wireless_dev *wdev = cfg_to_wdev(cfg_priv);
2390
2391 if (unlikely(!wdev)) {
2392 WL_ERR("wdev is invalid\n");
2393 return;
2394 }
2395 wiphy_unregister(wdev->wiphy);
2396 wiphy_free(wdev->wiphy);
2397 kfree(wdev);
2398 cfg_to_wdev(cfg_priv) = NULL;
2399}
2400
2401static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2402{
2403 struct brcmf_scan_results *bss_list;
2404 struct brcmf_bss_info *bi = NULL; /* must be initialized */
2405 s32 err = 0;
2406 int i;
2407
2408 bss_list = cfg_priv->bss_list;
2409 if (unlikely(bss_list->version != BRCMF_BSS_INFO_VERSION)) {
2410 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2411 bss_list->version);
2412 return -EOPNOTSUPP;
2413 }
2414 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2415 bi = next_bss(bss_list, bi);
2416 for_each_bss(bss_list, bi, i) {
2417 err = brcmf_inform_single_bss(cfg_priv, bi);
2418 if (unlikely(err))
2419 break;
2420 }
2421 return err;
2422}
2423
2424
2425static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
2426 struct brcmf_bss_info *bi)
2427{
2428 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2429 struct ieee80211_channel *notify_channel;
2430 struct cfg80211_bss *bss;
2431 struct ieee80211_supported_band *band;
2432 s32 err = 0;
2433 u16 channel;
2434 u32 freq;
2435 u64 notify_timestamp;
2436 u16 notify_capability;
2437 u16 notify_interval;
2438 u8 *notify_ie;
2439 size_t notify_ielen;
2440 s32 notify_signal;
2441
2442 if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
2443 WL_ERR("Bss info is larger than buffer. Discarding\n");
2444 return 0;
2445 }
2446
2447 channel = bi->ctl_ch ? bi->ctl_ch :
2448 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2449
2450 if (channel <= CH_MAX_2G_CHANNEL)
2451 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2452 else
2453 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2454
2455 freq = ieee80211_channel_to_frequency(channel, band->band);
2456 notify_channel = ieee80211_get_channel(wiphy, freq);
2457
2458 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2459 notify_capability = le16_to_cpu(bi->capability);
2460 notify_interval = le16_to_cpu(bi->beacon_period);
2461 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2462 notify_ielen = le16_to_cpu(bi->ie_length);
2463 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2464
2465 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2466 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2467 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2468 WL_CONN("Channel: %d(%d)\n", channel, freq);
2469 WL_CONN("Capability: %X\n", notify_capability);
2470 WL_CONN("Beacon interval: %d\n", notify_interval);
2471 WL_CONN("Signal: %d\n", notify_signal);
2472 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2473
2474 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2475 notify_timestamp, notify_capability, notify_interval, notify_ie,
2476 notify_ielen, notify_signal, GFP_KERNEL);
2477
2478 if (unlikely(!bss)) {
2479 WL_ERR("cfg80211_inform_bss_frame error\n");
2480 return -EINVAL;
2481 }
2482
2483 return err;
2484}
2485
2486static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2487 struct net_device *dev, const u8 *bssid)
2488{
2489 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2490 struct ieee80211_channel *notify_channel;
2491 struct brcmf_bss_info *bi = NULL;
2492 struct ieee80211_supported_band *band;
2493 u8 *buf = NULL;
2494 s32 err = 0;
2495 u16 channel;
2496 u32 freq;
2497 u64 notify_timestamp;
2498 u16 notify_capability;
2499 u16 notify_interval;
2500 u8 *notify_ie;
2501 size_t notify_ielen;
2502 s32 notify_signal;
2503
2504 WL_TRACE("Enter\n");
2505
2506 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2507 if (buf == NULL) {
2508 WL_ERR("kzalloc() failed\n");
2509 err = -ENOMEM;
2510 goto CleanUp;
2511 }
2512
2513 *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2514
2515 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2516 if (unlikely(err)) {
2517 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2518 goto CleanUp;
2519 }
2520
2521 bi = (struct brcmf_bss_info *)(buf + 4);
2522
2523 channel = bi->ctl_ch ? bi->ctl_ch :
2524 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2525
2526 if (channel <= CH_MAX_2G_CHANNEL)
2527 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2528 else
2529 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2530
2531 freq = ieee80211_channel_to_frequency(channel, band->band);
2532 notify_channel = ieee80211_get_channel(wiphy, freq);
2533
2534 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2535 notify_capability = le16_to_cpu(bi->capability);
2536 notify_interval = le16_to_cpu(bi->beacon_period);
2537 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2538 notify_ielen = le16_to_cpu(bi->ie_length);
2539 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2540
2541 WL_CONN("channel: %d(%d)\n", channel, freq);
2542 WL_CONN("capability: %X\n", notify_capability);
2543 WL_CONN("beacon interval: %d\n", notify_interval);
2544 WL_CONN("signal: %d\n", notify_signal);
2545 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2546
2547 cfg80211_inform_bss(wiphy, notify_channel, bssid,
2548 notify_timestamp, notify_capability, notify_interval,
2549 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2550
2551CleanUp:
2552
2553 kfree(buf);
2554
2555 WL_TRACE("Exit\n");
2556
2557 return err;
2558}
2559
2560static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2561 const struct brcmf_event_msg *e)
2562{
2563 u32 event = be32_to_cpu(e->event_type);
2564 u32 status = be32_to_cpu(e->status);
2565
2566 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2567 WL_CONN("Processing set ssid\n");
2568 cfg_priv->link_up = true;
2569 return true;
2570 }
2571
2572 return false;
2573}
2574
2575static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2576 const struct brcmf_event_msg *e)
2577{
2578 u32 event = be32_to_cpu(e->event_type);
2579 u16 flags = be16_to_cpu(e->flags);
2580
2581 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2582 WL_CONN("Processing link down\n");
2583 return true;
2584 }
2585 return false;
2586}
2587
2588static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2589 const struct brcmf_event_msg *e)
2590{
2591 u32 event = be32_to_cpu(e->event_type);
2592 u32 status = be32_to_cpu(e->status);
2593
2594 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2595 WL_CONN("Processing Link %s & no network found\n",
2596 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2597 "up" : "down");
2598 return true;
2599 }
2600
2601 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2602 WL_CONN("Processing connecting & no network found\n");
2603 return true;
2604 }
2605
2606 return false;
2607}
2608
2609static s32
2610brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2611 struct net_device *ndev,
2612 const struct brcmf_event_msg *e, void *data)
2613{
2614 s32 err = 0;
2615
2616 if (brcmf_is_linkup(cfg_priv, e)) {
2617 WL_CONN("Linkup\n");
2618 if (brcmf_is_ibssmode(cfg_priv)) {
2619 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2620 WL_PROF_BSSID);
2621 wl_inform_ibss(cfg_priv, ndev, e->addr);
2622 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2623 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2624 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2625 } else
2626 brcmf_bss_connect_done(cfg_priv, ndev, e, data, true);
2627 } else if (brcmf_is_linkdown(cfg_priv, e)) {
2628 WL_CONN("Linkdown\n");
2629 if (brcmf_is_ibssmode(cfg_priv)) {
2630 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2631 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2632 &cfg_priv->status))
2633 brcmf_link_down(cfg_priv);
2634 } else {
2635 brcmf_bss_connect_done(cfg_priv, ndev, e, data, false);
2636 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2637 &cfg_priv->status)) {
2638 cfg80211_disconnected(ndev, 0, NULL, 0,
2639 GFP_KERNEL);
2640 brcmf_link_down(cfg_priv);
2641 }
2642 }
2643 brcmf_init_prof(cfg_priv->profile);
2644 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2645 if (brcmf_is_ibssmode(cfg_priv))
2646 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2647 else
2648 brcmf_bss_connect_done(cfg_priv, ndev, e, data, false);
2649 }
2650
2651 return err;
2652}
2653
2654static s32
2655brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2656 struct net_device *ndev,
2657 const struct brcmf_event_msg *e, void *data)
2658{
2659 s32 err = 0;
2660 u32 event = be32_to_cpu(e->event_type);
2661 u32 status = be32_to_cpu(e->status);
2662
2663 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2664 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2665 brcmf_bss_roaming_done(cfg_priv, ndev, e, data);
2666 else
2667 brcmf_bss_connect_done(cfg_priv, ndev, e, data, true);
2668 }
2669
2670 return err;
2671}
2672
2673static __used s32
2674brcmf_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2675{
2676 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2677 u32 buflen;
2678
2679 buflen = brcmu_mkiovar(name, buf, len, cfg_priv->ioctl_buf,
2680 WL_IOCTL_LEN_MAX);
2681 BUG_ON(!buflen);
2682
2683 return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, cfg_priv->ioctl_buf,
2684 buflen);
2685}
2686
2687static s32
2688brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2689 s32 buf_len)
2690{
2691 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2692 u32 len;
2693 s32 err = 0;
2694
2695 len = brcmu_mkiovar(name, NULL, 0, cfg_priv->ioctl_buf,
2696 WL_IOCTL_LEN_MAX);
2697 BUG_ON(!len);
2698 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, (void *)cfg_priv->ioctl_buf,
2699 WL_IOCTL_LEN_MAX);
2700 if (unlikely(err)) {
2701 WL_ERR("error (%d)\n", err);
2702 return err;
2703 }
2704 memcpy(buf, cfg_priv->ioctl_buf, buf_len);
2705
2706 return err;
2707}
2708
2709static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2710{
2711 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2712 struct brcmf_cfg80211_assoc_ielen *assoc_info;
2713 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2714 u32 req_len;
2715 u32 resp_len;
2716 s32 err = 0;
2717
2718 brcmf_clear_assoc_ies(cfg_priv);
2719
2720 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2721 WL_ASSOC_INFO_MAX);
2722 if (unlikely(err)) {
2723 WL_ERR("could not get assoc info (%d)\n", err);
2724 return err;
2725 }
2726 assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2727 req_len = assoc_info->req_len;
2728 resp_len = assoc_info->resp_len;
2729 if (req_len) {
2730 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2731 cfg_priv->extra_buf,
2732 WL_ASSOC_INFO_MAX);
2733 if (unlikely(err)) {
2734 WL_ERR("could not get assoc req (%d)\n", err);
2735 return err;
2736 }
2737 conn_info->req_ie_len = req_len;
2738 conn_info->req_ie =
2739 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2740 GFP_KERNEL);
2741 } else {
2742 conn_info->req_ie_len = 0;
2743 conn_info->req_ie = NULL;
2744 }
2745 if (resp_len) {
2746 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2747 cfg_priv->extra_buf,
2748 WL_ASSOC_INFO_MAX);
2749 if (unlikely(err)) {
2750 WL_ERR("could not get assoc resp (%d)\n", err);
2751 return err;
2752 }
2753 conn_info->resp_ie_len = resp_len;
2754 conn_info->resp_ie =
2755 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2756 GFP_KERNEL);
2757 } else {
2758 conn_info->resp_ie_len = 0;
2759 conn_info->resp_ie = NULL;
2760 }
2761 WL_CONN("req len (%d) resp len (%d)\n",
2762 conn_info->req_ie_len, conn_info->resp_ie_len);
2763
2764 return err;
2765}
2766
2767static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2768{
2769 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2770
2771 kfree(conn_info->req_ie);
2772 conn_info->req_ie = NULL;
2773 conn_info->req_ie_len = 0;
2774 kfree(conn_info->resp_ie);
2775 conn_info->resp_ie = NULL;
2776 conn_info->resp_ie_len = 0;
2777}
2778
2779
2780static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
2781 size_t *join_params_size)
2782{
2783 chanspec_t chanspec = 0;
2784
2785 if (ch != 0) {
2786 join_params->params.chanspec_num = 1;
2787 join_params->params.chanspec_list[0] = ch;
2788
2789 if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
2790 chanspec |= WL_CHANSPEC_BAND_2G;
2791 else
2792 chanspec |= WL_CHANSPEC_BAND_5G;
2793
2794 chanspec |= WL_CHANSPEC_BW_20;
2795 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2796
2797 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
2798 join_params->params.chanspec_num * sizeof(chanspec_t);
2799
2800 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2801 join_params->params.chanspec_list[0] |= chanspec;
2802 join_params->params.chanspec_list[0] =
2803 cpu_to_le16(join_params->params.chanspec_list[0]);
2804
2805 join_params->params.chanspec_num =
2806 cpu_to_le32(join_params->params.chanspec_num);
2807
2808 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2809 "channel %d, chanspec %#X\n",
2810 join_params->params.chanspec_list[0], ch, chanspec);
2811 }
2812}
2813
2814static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2815{
2816 struct brcmf_bss_info *bi;
2817 struct brcmf_ssid *ssid;
2818 struct brcmu_tlv *tim;
2819 u16 beacon_interval;
2820 u8 dtim_period;
2821 size_t ie_len;
2822 u8 *ie;
2823 s32 err = 0;
2824
2825 WL_TRACE("Enter\n");
2826 if (brcmf_is_ibssmode(cfg_priv))
2827 return err;
2828
2829 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2830
2831 *(u32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2832 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2833 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2834 if (unlikely(err)) {
2835 WL_ERR("Could not get bss info %d\n", err);
2836 goto update_bss_info_out;
2837 }
2838
2839 bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2840 err = brcmf_inform_single_bss(cfg_priv, bi);
2841 if (unlikely(err))
2842 goto update_bss_info_out;
2843
2844 ie = ((u8 *)bi) + bi->ie_offset;
2845 ie_len = bi->ie_length;
2846 beacon_interval = cpu_to_le16(bi->beacon_period);
2847
2848 tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2849 if (tim)
2850 dtim_period = tim->data[1];
2851 else {
2852 /*
2853 * active scan was done so we could not get dtim
2854 * information out of probe response.
2855 * so we speficially query dtim information to dongle.
2856 */
2857 u32 var;
2858 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2859 "dtim_assoc", &var);
2860 if (unlikely(err)) {
2861 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2862 goto update_bss_info_out;
2863 }
2864 dtim_period = (u8)var;
2865 }
2866
2867 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2868 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2869
2870update_bss_info_out:
2871 WL_TRACE("Exit");
2872 return err;
2873}
2874
2875static s32
2876brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2877 struct net_device *ndev,
2878 const struct brcmf_event_msg *e, void *data)
2879{
2880 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2881 s32 err = 0;
2882
2883 WL_TRACE("Enter\n");
2884
2885 brcmf_get_assoc_ies(cfg_priv);
2886 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2887 brcmf_update_bss_info(cfg_priv);
2888
2889 cfg80211_roamed(ndev, NULL,
2890 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2891 conn_info->req_ie, conn_info->req_ie_len,
2892 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2893 WL_CONN("Report roaming result\n");
2894
2895 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2896 WL_TRACE("Exit\n");
2897 return err;
2898}
2899
2900static s32
2901brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2902 struct net_device *ndev, const struct brcmf_event_msg *e,
2903 void *data, bool completed)
2904{
2905 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2906 s32 err = 0;
2907
2908 WL_TRACE("Enter\n");
2909
2910 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2911 if (completed) {
2912 brcmf_get_assoc_ies(cfg_priv);
2913 brcmf_update_prof(cfg_priv, NULL, &e->addr,
2914 WL_PROF_BSSID);
2915 brcmf_update_bss_info(cfg_priv);
2916 }
2917 cfg80211_connect_result(ndev,
2918 (u8 *)brcmf_read_prof(cfg_priv,
2919 WL_PROF_BSSID),
2920 conn_info->req_ie,
2921 conn_info->req_ie_len,
2922 conn_info->resp_ie,
2923 conn_info->resp_ie_len,
2924 completed ? WLAN_STATUS_SUCCESS :
2925 WLAN_STATUS_AUTH_TIMEOUT,
2926 GFP_KERNEL);
2927 if (completed)
2928 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2929 WL_CONN("Report connect result - connection %s\n",
2930 completed ? "succeeded" : "failed");
2931 }
2932 WL_TRACE("Exit\n");
2933 return err;
2934}
2935
2936static s32
2937brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2938 struct net_device *ndev,
2939 const struct brcmf_event_msg *e, void *data)
2940{
2941 u16 flags = be16_to_cpu(e->flags);
2942 enum nl80211_key_type key_type;
2943
2944 rtnl_lock();
2945 if (flags & BRCMF_EVENT_MSG_GROUP)
2946 key_type = NL80211_KEYTYPE_GROUP;
2947 else
2948 key_type = NL80211_KEYTYPE_PAIRWISE;
2949
2950 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2951 NULL, GFP_KERNEL);
2952 rtnl_unlock();
2953
2954 return 0;
2955}
2956
2957static s32
2958brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
2959 struct net_device *ndev,
2960 const struct brcmf_event_msg *e, void *data)
2961{
2962 struct brcmf_channel_info channel_inform;
2963 struct brcmf_scan_results *bss_list;
2964 u32 len = WL_SCAN_BUF_MAX;
2965 s32 err = 0;
2966 bool scan_abort = false;
2967
2968 WL_TRACE("Enter\n");
2969
2970 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
2971 WL_TRACE("Exit\n");
2972 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
2973 }
2974
2975 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
2976 &cfg_priv->status))) {
2977 WL_ERR("Scan complete while device not scanning\n");
2978 scan_abort = true;
2979 err = -EINVAL;
2980 goto scan_done_out;
2981 }
2982
2983 err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_inform,
2984 sizeof(channel_inform));
2985 if (unlikely(err)) {
2986 WL_ERR("scan busy (%d)\n", err);
2987 scan_abort = true;
2988 goto scan_done_out;
2989 }
2990 channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
2991 if (unlikely(channel_inform.scan_channel)) {
2992
2993 WL_CONN("channel_inform.scan_channel (%d)\n",
2994 channel_inform.scan_channel);
2995 }
2996 cfg_priv->bss_list = cfg_priv->scan_results;
2997 bss_list = cfg_priv->bss_list;
2998 memset(bss_list, 0, len);
2999 bss_list->buflen = cpu_to_le32(len);
3000
3001 err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN_RESULTS, bss_list, len);
3002 if (unlikely(err)) {
3003 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3004 err = -EINVAL;
3005 scan_abort = true;
3006 goto scan_done_out;
3007 }
3008 bss_list->buflen = le32_to_cpu(bss_list->buflen);
3009 bss_list->version = le32_to_cpu(bss_list->version);
3010 bss_list->count = le32_to_cpu(bss_list->count);
3011
3012 err = brcmf_inform_bss(cfg_priv);
3013 if (err) {
3014 scan_abort = true;
3015 goto scan_done_out;
3016 }
3017
3018scan_done_out:
3019 if (cfg_priv->scan_request) {
3020 WL_SCAN("calling cfg80211_scan_done\n");
3021 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3022 brcmf_set_mpc(ndev, 1);
3023 cfg_priv->scan_request = NULL;
3024 }
3025
3026 WL_TRACE("Exit\n");
3027
3028 return err;
3029}
3030
3031static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3032{
3033 conf->mode = (u32)-1;
3034 conf->frag_threshold = (u32)-1;
3035 conf->rts_threshold = (u32)-1;
3036 conf->retry_short = (u32)-1;
3037 conf->retry_long = (u32)-1;
3038 conf->tx_power = -1;
3039}
3040
3041static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
3042{
3043 memset(prof, 0, sizeof(*prof));
3044}
3045
3046static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3047{
3048 memset(el, 0, sizeof(*el));
3049 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3050 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3051 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3052 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3053 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3054}
3055
3056static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3057{
3058 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3059 if (unlikely(!cfg_priv->scan_results)) {
3060 WL_ERR("Scan results alloc failed\n");
3061 goto init_priv_mem_out;
3062 }
3063 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3064 if (unlikely(!cfg_priv->conf)) {
3065 WL_ERR("wl_conf alloc failed\n");
3066 goto init_priv_mem_out;
3067 }
3068 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3069 if (unlikely(!cfg_priv->profile)) {
3070 WL_ERR("wl_profile alloc failed\n");
3071 goto init_priv_mem_out;
3072 }
3073 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3074 if (unlikely(!cfg_priv->bss_info)) {
3075 WL_ERR("Bss information alloc failed\n");
3076 goto init_priv_mem_out;
3077 }
3078 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3079 GFP_KERNEL);
3080 if (unlikely(!cfg_priv->scan_req_int)) {
3081 WL_ERR("Scan req alloc failed\n");
3082 goto init_priv_mem_out;
3083 }
3084 cfg_priv->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
3085 if (unlikely(!cfg_priv->ioctl_buf)) {
3086 WL_ERR("Ioctl buf alloc failed\n");
3087 goto init_priv_mem_out;
3088 }
3089 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3090 if (unlikely(!cfg_priv->extra_buf)) {
3091 WL_ERR("Extra buf alloc failed\n");
3092 goto init_priv_mem_out;
3093 }
3094 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3095 if (unlikely(!cfg_priv->iscan)) {
3096 WL_ERR("Iscan buf alloc failed\n");
3097 goto init_priv_mem_out;
3098 }
3099 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3100 if (unlikely(!cfg_priv->pmk_list)) {
3101 WL_ERR("pmk list alloc failed\n");
3102 goto init_priv_mem_out;
3103 }
3104
3105 return 0;
3106
3107init_priv_mem_out:
3108 brcmf_deinit_priv_mem(cfg_priv);
3109
3110 return -ENOMEM;
3111}
3112
3113static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3114{
3115 kfree(cfg_priv->scan_results);
3116 cfg_priv->scan_results = NULL;
3117 kfree(cfg_priv->bss_info);
3118 cfg_priv->bss_info = NULL;
3119 kfree(cfg_priv->conf);
3120 cfg_priv->conf = NULL;
3121 kfree(cfg_priv->profile);
3122 cfg_priv->profile = NULL;
3123 kfree(cfg_priv->scan_req_int);
3124 cfg_priv->scan_req_int = NULL;
3125 kfree(cfg_priv->ioctl_buf);
3126 cfg_priv->ioctl_buf = NULL;
3127 kfree(cfg_priv->extra_buf);
3128 cfg_priv->extra_buf = NULL;
3129 kfree(cfg_priv->iscan);
3130 cfg_priv->iscan = NULL;
3131 kfree(cfg_priv->pmk_list);
3132 cfg_priv->pmk_list = NULL;
3133}
3134
3135static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3136{
3137 sema_init(&cfg_priv->event_sync, 0);
3138 cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv,
3139 "wl_event_handler");
3140 if (IS_ERR(cfg_priv->event_tsk)) {
3141 cfg_priv->event_tsk = NULL;
3142 WL_ERR("failed to create event thread\n");
3143 return -ENOMEM;
3144 }
3145 return 0;
3146}
3147
3148static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3149{
3150 if (cfg_priv->event_tsk) {
3151 send_sig(SIGTERM, cfg_priv->event_tsk, 1);
3152 kthread_stop(cfg_priv->event_tsk);
3153 cfg_priv->event_tsk = NULL;
3154 }
3155}
3156
3157static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3158{
3159 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3160
3161 if (cfg_priv->iscan_on && iscan->tsk) {
3162 iscan->state = WL_ISCAN_STATE_IDLE;
3163 send_sig(SIGTERM, iscan->tsk, 1);
3164 kthread_stop(iscan->tsk);
3165 iscan->tsk = NULL;
3166 }
3167}
3168
3169static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
3170 bool aborted)
3171{
3172 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
3173 struct net_device *ndev = cfg_to_ndev(cfg_priv);
3174
3175 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
3176 &cfg_priv->status))) {
3177 WL_ERR("Scan complete while device not scanning\n");
3178 return;
3179 }
3180 if (likely(cfg_priv->scan_request)) {
3181 WL_SCAN("ISCAN Completed scan: %s\n",
3182 aborted ? "Aborted" : "Done");
3183 cfg80211_scan_done(cfg_priv->scan_request, aborted);
3184 brcmf_set_mpc(ndev, 1);
3185 cfg_priv->scan_request = NULL;
3186 }
3187 cfg_priv->iscan_kickstart = false;
3188}
3189
3190static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
3191{
3192 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
3193 WL_SCAN("wake up iscan\n");
3194 up(&iscan->sync);
3195 return 0;
3196 }
3197
3198 return -EIO;
3199}
3200
3201static s32
3202brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
3203 struct brcmf_scan_results **bss_list)
3204{
3205 struct brcmf_iscan_results list;
3206 struct brcmf_scan_results *results;
3207 struct brcmf_iscan_results *list_buf;
3208 s32 err = 0;
3209
3210 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
3211 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
3212 results = &list_buf->results;
3213 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
3214 results->version = 0;
3215 results->count = 0;
3216
3217 memset(&list, 0, sizeof(list));
3218 list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
3219 err = brcmf_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
3220 BRCMF_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
3221 WL_ISCAN_BUF_MAX);
3222 if (unlikely(err)) {
3223 WL_ERR("error (%d)\n", err);
3224 return err;
3225 }
3226 results->buflen = le32_to_cpu(results->buflen);
3227 results->version = le32_to_cpu(results->version);
3228 results->count = le32_to_cpu(results->count);
3229 WL_SCAN("results->count = %d\n", results->count);
3230 WL_SCAN("results->buflen = %d\n", results->buflen);
3231 *status = le32_to_cpu(list_buf->status);
3232 *bss_list = results;
3233
3234 return err;
3235}
3236
3237static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
3238{
3239 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3240 s32 err = 0;
3241
3242 iscan->state = WL_ISCAN_STATE_IDLE;
3243 rtnl_lock();
3244 brcmf_inform_bss(cfg_priv);
3245 brcmf_notify_iscan_complete(iscan, false);
3246 rtnl_unlock();
3247
3248 return err;
3249}
3250
3251static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
3252{
3253 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3254 s32 err = 0;
3255
3256 /* Reschedule the timer */
3257 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3258 iscan->timer_on = 1;
3259
3260 return err;
3261}
3262
3263static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
3264{
3265 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3266 s32 err = 0;
3267
3268 rtnl_lock();
3269 brcmf_inform_bss(cfg_priv);
3270 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
3271 rtnl_unlock();
3272 /* Reschedule the timer */
3273 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3274 iscan->timer_on = 1;
3275
3276 return err;
3277}
3278
3279static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
3280{
3281 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3282 s32 err = 0;
3283
3284 iscan->state = WL_ISCAN_STATE_IDLE;
3285 rtnl_lock();
3286 brcmf_notify_iscan_complete(iscan, true);
3287 rtnl_unlock();
3288
3289 return err;
3290}
3291
3292static s32 brcmf_iscan_thread(void *data)
3293{
3294 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3295 struct brcmf_cfg80211_iscan_ctrl *iscan =
3296 (struct brcmf_cfg80211_iscan_ctrl *)data;
3297 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
3298 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
3299 u32 status;
3300 int err = 0;
3301
3302 sched_setscheduler(current, SCHED_FIFO, &param);
3303 allow_signal(SIGTERM);
3304 status = BRCMF_SCAN_RESULTS_PARTIAL;
3305 while (likely(!down_interruptible(&iscan->sync))) {
3306 if (kthread_should_stop())
3307 break;
3308 if (iscan->timer_on) {
3309 del_timer_sync(&iscan->timer);
3310 iscan->timer_on = 0;
3311 }
3312 rtnl_lock();
3313 err = brcmf_get_iscan_results(iscan, &status,
3314 &cfg_priv->bss_list);
3315 if (unlikely(err)) {
3316 status = BRCMF_SCAN_RESULTS_ABORTED;
3317 WL_ERR("Abort iscan\n");
3318 }
3319 rtnl_unlock();
3320 el->handler[status](cfg_priv);
3321 }
3322 if (iscan->timer_on) {
3323 del_timer_sync(&iscan->timer);
3324 iscan->timer_on = 0;
3325 }
3326 WL_SCAN("ISCAN thread terminated\n");
3327
3328 return 0;
3329}
3330
3331static void brcmf_iscan_timer(unsigned long data)
3332{
3333 struct brcmf_cfg80211_iscan_ctrl *iscan =
3334 (struct brcmf_cfg80211_iscan_ctrl *)data;
3335
3336 if (iscan) {
3337 iscan->timer_on = 0;
3338 WL_SCAN("timer expired\n");
3339 brcmf_wakeup_iscan(iscan);
3340 }
3341}
3342
3343static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3344{
3345 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3346 int err = 0;
3347
3348 if (cfg_priv->iscan_on && !iscan->tsk) {
3349 iscan->state = WL_ISCAN_STATE_IDLE;
3350 sema_init(&iscan->sync, 0);
3351 iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan");
3352 if (IS_ERR(iscan->tsk)) {
3353 WL_ERR("Could not create iscan thread\n");
3354 iscan->tsk = NULL;
3355 return -ENOMEM;
3356 }
3357 }
3358
3359 return err;
3360}
3361
3362static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
3363{
3364 memset(el, 0, sizeof(*el));
3365 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
3366 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
3367 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
3368 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
3369 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
3370}
3371
3372static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3373{
3374 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3375 int err = 0;
3376
3377 if (cfg_priv->iscan_on) {
3378 iscan->dev = cfg_to_ndev(cfg_priv);
3379 iscan->state = WL_ISCAN_STATE_IDLE;
3380 brcmf_init_iscan_eloop(&iscan->el);
3381 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3382 init_timer(&iscan->timer);
3383 iscan->timer.data = (unsigned long) iscan;
3384 iscan->timer.function = brcmf_iscan_timer;
3385 sema_init(&iscan->sync, 0);
3386 iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan");
3387 if (IS_ERR(iscan->tsk)) {
3388 WL_ERR("Could not create iscan thread\n");
3389 iscan->tsk = NULL;
3390 return -ENOMEM;
3391 }
3392 iscan->data = cfg_priv;
3393 }
3394
3395 return err;
3396}
3397
3398static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3399{
3400 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
3401 s32 err = 0;
3402
3403 cfg_priv->scan_request = NULL;
3404 cfg_priv->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3405 cfg_priv->iscan_on = true; /* iscan on & off switch.
3406 we enable iscan per default */
3407 cfg_priv->roam_on = false; /* roam on & off switch.
3408 we enable roam per default */
3409
3410 cfg_priv->iscan_kickstart = false;
3411 cfg_priv->active_scan = true; /* we do active scan for
3412 specific scan per default */
3413 cfg_priv->dongle_up = false; /* dongle is not up yet */
3414 brcmf_init_eq(cfg_priv);
3415 err = brcmf_init_priv_mem(cfg_priv);
3416 if (unlikely(err))
3417 return err;
3418 if (unlikely(brcmf_create_event_handler(cfg_priv)))
3419 return -ENOMEM;
3420 brcmf_init_eloop_handler(&cfg_priv->el);
3421 mutex_init(&cfg_priv->usr_sync);
3422 err = brcmf_init_iscan(cfg_priv);
3423 if (unlikely(err))
3424 return err;
3425 brcmf_init_conf(cfg_priv->conf);
3426 brcmf_init_prof(cfg_priv->profile);
3427 brcmf_link_down(cfg_priv);
3428
3429 return err;
3430}
3431
3432static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3433{
3434 brcmf_destroy_event_handler(cfg_priv);
3435 cfg_priv->dongle_up = false; /* dongle down */
3436 brcmf_flush_eq(cfg_priv);
3437 brcmf_link_down(cfg_priv);
3438 brcmf_term_iscan(cfg_priv);
3439 brcmf_deinit_priv_mem(cfg_priv);
3440}
3441
3442s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data)
3443{
3444 struct wireless_dev *wdev;
3445 struct brcmf_cfg80211_priv *cfg_priv;
3446 struct brcmf_cfg80211_iface *ci;
3447 s32 err = 0;
3448
3449 if (unlikely(!ndev)) {
3450 WL_ERR("ndev is invalid\n");
3451 return -ENODEV;
3452 }
3453 cfg80211_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3454 if (unlikely(!cfg80211_dev)) {
3455 WL_ERR("wl_cfg80211_dev is invalid\n");
3456 return -ENOMEM;
3457 }
3458 WL_INFO("func %p\n", brcmf_cfg80211_get_sdio_func());
3459 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface),
3460 &brcmf_cfg80211_get_sdio_func()->dev);
3461 if (IS_ERR(wdev))
3462 return -ENOMEM;
3463
3464 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3465 cfg_priv = wdev_to_cfg(wdev);
3466 cfg_priv->wdev = wdev;
3467 cfg_priv->pub = data;
3468 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3469 ci->cfg_priv = cfg_priv;
3470 ndev->ieee80211_ptr = wdev;
3471 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3472 wdev->netdev = ndev;
3473 err = wl_init_priv(cfg_priv);
3474 if (unlikely(err)) {
3475 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3476 goto cfg80211_attach_out;
3477 }
3478 brcmf_set_drvdata(cfg80211_dev, ci);
3479
3480 return err;
3481
3482cfg80211_attach_out:
3483 brcmf_free_wdev(cfg_priv);
3484 return err;
3485}
3486
3487void brcmf_cfg80211_detach(void)
3488{
3489 struct brcmf_cfg80211_priv *cfg_priv;
3490
3491 cfg_priv = WL_PRIV_GET();
3492
3493 wl_deinit_priv(cfg_priv);
3494 brcmf_free_wdev(cfg_priv);
3495 brcmf_set_drvdata(cfg80211_dev, NULL);
3496 kfree(cfg80211_dev);
3497 cfg80211_dev = NULL;
3498 brcmf_clear_sdio_func();
3499}
3500
3501static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv)
3502{
3503 up(&cfg_priv->event_sync);
3504}
3505
3506static s32 brcmf_event_handler(void *data)
3507{
3508 struct brcmf_cfg80211_priv *cfg_priv =
3509 (struct brcmf_cfg80211_priv *)data;
3510 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3511 struct brcmf_cfg80211_event_q *e;
3512
3513 sched_setscheduler(current, SCHED_FIFO, &param);
3514 allow_signal(SIGTERM);
3515 while (likely(!down_interruptible(&cfg_priv->event_sync))) {
3516 if (kthread_should_stop())
3517 break;
3518 e = brcmf_deq_event(cfg_priv);
3519 if (unlikely(!e)) {
3520 WL_ERR("event queue empty...\n");
3521 BUG();
3522 }
3523 WL_INFO("event type (%d)\n", e->etype);
3524 if (cfg_priv->el.handler[e->etype]) {
3525 cfg_priv->el.handler[e->etype](cfg_priv,
3526 cfg_to_ndev(cfg_priv),
3527 &e->emsg, e->edata);
3528 } else {
3529 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3530 }
3531 brcmf_put_event(e);
3532 }
3533 WL_INFO("was terminated\n");
3534 return 0;
3535}
3536
3537void
3538brcmf_cfg80211_event(struct net_device *ndev,
3539 const struct brcmf_event_msg *e, void *data)
3540{
3541 u32 event_type = be32_to_cpu(e->event_type);
3542 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3543
3544 if (likely(!brcmf_enq_event(cfg_priv, event_type, e, data)))
3545 brcmf_wakeup_event(cfg_priv);
3546}
3547
3548static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3549{
3550 brcmf_init_eq_lock(cfg_priv);
3551 INIT_LIST_HEAD(&cfg_priv->eq_list);
3552}
3553
3554static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3555{
3556 struct brcmf_cfg80211_event_q *e;
3557
3558 brcmf_lock_eq(cfg_priv);
3559 while (!list_empty(&cfg_priv->eq_list)) {
3560 e = list_first_entry(&cfg_priv->eq_list,
3561 struct brcmf_cfg80211_event_q, eq_list);
3562 list_del(&e->eq_list);
3563 kfree(e);
3564 }
3565 brcmf_unlock_eq(cfg_priv);
3566}
3567
3568/*
3569* retrieve first queued event from head
3570*/
3571
3572static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3573 struct brcmf_cfg80211_priv *cfg_priv)
3574{
3575 struct brcmf_cfg80211_event_q *e = NULL;
3576
3577 brcmf_lock_eq(cfg_priv);
3578 if (likely(!list_empty(&cfg_priv->eq_list))) {
3579 e = list_first_entry(&cfg_priv->eq_list,
3580 struct brcmf_cfg80211_event_q, eq_list);
3581 list_del(&e->eq_list);
3582 }
3583 brcmf_unlock_eq(cfg_priv);
3584
3585 return e;
3586}
3587
3588/*
3589** push event to tail of the queue
3590*/
3591
3592static s32
3593brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3594 const struct brcmf_event_msg *msg, void *data)
3595{
3596 struct brcmf_cfg80211_event_q *e;
3597 s32 err = 0;
3598
3599 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3600 if (unlikely(!e)) {
3601 WL_ERR("event alloc failed\n");
3602 return -ENOMEM;
3603 }
3604
3605 e->etype = event;
3606 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3607
3608 brcmf_lock_eq(cfg_priv);
3609 list_add_tail(&e->eq_list, &cfg_priv->eq_list);
3610 brcmf_unlock_eq(cfg_priv);
3611
3612 return err;
3613}
3614
3615static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3616{
3617 kfree(e);
3618}
3619
3620void brcmf_cfg80211_sdio_func(void *func)
3621{
3622 cfg80211_sdio_func = (struct sdio_func *)func;
3623}
3624
3625static void brcmf_clear_sdio_func(void)
3626{
3627 cfg80211_sdio_func = NULL;
3628}
3629
3630struct sdio_func *brcmf_cfg80211_get_sdio_func(void)
3631{
3632 return cfg80211_sdio_func;
3633}
3634
3635static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3636{
3637 s32 infra = 0;
3638 s32 err = 0;
3639
3640 switch (iftype) {
3641 case NL80211_IFTYPE_MONITOR:
3642 case NL80211_IFTYPE_WDS:
3643 WL_ERR("type (%d) : currently we do not support this mode\n",
3644 iftype);
3645 err = -EINVAL;
3646 return err;
3647 case NL80211_IFTYPE_ADHOC:
3648 infra = 0;
3649 break;
3650 case NL80211_IFTYPE_STATION:
3651 infra = 1;
3652 break;
3653 default:
3654 err = -EINVAL;
3655 WL_ERR("invalid type (%d)\n", iftype);
3656 return err;
3657 }
3658 infra = cpu_to_le32(infra);
3659 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
3660 if (unlikely(err)) {
3661 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3662 return err;
3663 }
3664
3665 return 0;
3666}
3667
3668static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3669{
3670 /* Room for "event_msgs" + '\0' + bitvec */
3671 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3672 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3673 s32 err = 0;
3674
3675 WL_TRACE("Enter\n");
3676
3677 /* Setup event_msgs */
3678 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3679 sizeof(iovbuf));
3680 err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3681 if (unlikely(err)) {
3682 WL_ERR("Get event_msgs error (%d)\n", err);
3683 goto dongle_eventmsg_out;
3684 }
3685 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3686
3687 setbit(eventmask, BRCMF_E_SET_SSID);
3688 setbit(eventmask, BRCMF_E_ROAM);
3689 setbit(eventmask, BRCMF_E_PRUNE);
3690 setbit(eventmask, BRCMF_E_AUTH);
3691 setbit(eventmask, BRCMF_E_REASSOC);
3692 setbit(eventmask, BRCMF_E_REASSOC_IND);
3693 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3694 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3695 setbit(eventmask, BRCMF_E_DISASSOC);
3696 setbit(eventmask, BRCMF_E_JOIN);
3697 setbit(eventmask, BRCMF_E_ASSOC_IND);
3698 setbit(eventmask, BRCMF_E_PSK_SUP);
3699 setbit(eventmask, BRCMF_E_LINK);
3700 setbit(eventmask, BRCMF_E_NDIS_LINK);
3701 setbit(eventmask, BRCMF_E_MIC_ERROR);
3702 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3703 setbit(eventmask, BRCMF_E_TXFAIL);
3704 setbit(eventmask, BRCMF_E_JOIN_START);
3705 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3706
3707 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3708 sizeof(iovbuf));
3709 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3710 if (unlikely(err)) {
3711 WL_ERR("Set event_msgs error (%d)\n", err);
3712 goto dongle_eventmsg_out;
3713 }
3714
3715dongle_eventmsg_out:
3716 WL_TRACE("Exit\n");
3717 return err;
3718}
3719
3720static s32
3721brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3722{
3723 s8 iovbuf[32];
3724 s32 roamtrigger[2];
3725 s32 roam_delta[2];
3726 s32 err = 0;
3727
3728 /*
3729 * Setup timeout if Beacons are lost and roam is
3730 * off to report link down
3731 */
3732 if (roamvar) {
3733 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3734 sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3735 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR,
3736 iovbuf, sizeof(iovbuf));
3737 if (unlikely(err)) {
3738 WL_ERR("bcn_timeout error (%d)\n", err);
3739 goto dongle_rom_out;
3740 }
3741 }
3742
3743 /*
3744 * Enable/Disable built-in roaming to allow supplicant
3745 * to take care of roaming
3746 */
3747 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3748 brcmu_mkiovar("roam_off", (char *)&roamvar,
3749 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3750 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3751 if (unlikely(err)) {
3752 WL_ERR("roam_off error (%d)\n", err);
3753 goto dongle_rom_out;
3754 }
3755
3756 roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3757 roamtrigger[1] = BRCM_BAND_ALL;
3758 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3759 (void *)roamtrigger, sizeof(roamtrigger));
3760 if (unlikely(err)) {
3761 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3762 goto dongle_rom_out;
3763 }
3764
3765 roam_delta[0] = WL_ROAM_DELTA;
3766 roam_delta[1] = BRCM_BAND_ALL;
3767 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_DELTA,
3768 (void *)roam_delta, sizeof(roam_delta));
3769 if (unlikely(err)) {
3770 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3771 goto dongle_rom_out;
3772 }
3773
3774dongle_rom_out:
3775 return err;
3776}
3777
3778static s32
3779brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3780 s32 scan_unassoc_time, s32 scan_passive_time)
3781{
3782 s32 err = 0;
3783
3784 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3785 &scan_assoc_time, sizeof(scan_assoc_time));
3786 if (err) {
3787 if (err == -EOPNOTSUPP)
3788 WL_INFO("Scan assoc time is not supported\n");
3789 else
3790 WL_ERR("Scan assoc time error (%d)\n", err);
3791 goto dongle_scantime_out;
3792 }
3793 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3794 &scan_unassoc_time, sizeof(scan_unassoc_time));
3795 if (err) {
3796 if (err == -EOPNOTSUPP)
3797 WL_INFO("Scan unassoc time is not supported\n");
3798 else
3799 WL_ERR("Scan unassoc time error (%d)\n", err);
3800 goto dongle_scantime_out;
3801 }
3802
3803 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3804 &scan_passive_time, sizeof(scan_passive_time));
3805 if (err) {
3806 if (err == -EOPNOTSUPP)
3807 WL_INFO("Scan passive time is not supported\n");
3808 else
3809 WL_ERR("Scan passive time error (%d)\n", err);
3810 goto dongle_scantime_out;
3811 }
3812
3813dongle_scantime_out:
3814 return err;
3815}
3816
3817s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv, bool need_lock)
3818{
3819 struct net_device *ndev;
3820 struct wireless_dev *wdev;
3821 s32 err = 0;
3822
3823 if (cfg_priv->dongle_up)
3824 return err;
3825
3826 ndev = cfg_to_ndev(cfg_priv);
3827 wdev = ndev->ieee80211_ptr;
3828 if (need_lock)
3829 rtnl_lock();
3830
3831 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3832 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3833
3834 err = brcmf_dongle_eventmsg(ndev);
3835 if (unlikely(err))
3836 goto default_conf_out;
3837 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3838 WL_BEACON_TIMEOUT);
3839 if (unlikely(err))
3840 goto default_conf_out;
3841 err = brcmf_dongle_mode(ndev, wdev->iftype);
3842 if (unlikely(err && err != -EINPROGRESS))
3843 goto default_conf_out;
3844 err = brcmf_dongle_probecap(cfg_priv);
3845 if (unlikely(err))
3846 goto default_conf_out;
3847
3848 /* -EINPROGRESS: Call commit handler */
3849
3850default_conf_out:
3851 if (need_lock)
3852 rtnl_unlock();
3853
3854 cfg_priv->dongle_up = true;
3855
3856 return err;
3857
3858}
3859
3860static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3861{
3862 struct wiphy *wiphy;
3863 s32 phy_list;
3864 s8 phy;
3865 s32 err = 0;
3866
3867 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3868 &phy_list, sizeof(phy_list));
3869 if (unlikely(err)) {
3870 WL_ERR("error (%d)\n", err);
3871 return err;
3872 }
3873
3874 phy = ((char *)&phy_list)[1];
3875 WL_INFO("%c phy\n", phy);
3876 if (phy == 'n' || phy == 'a') {
3877 wiphy = cfg_to_wiphy(cfg_priv);
3878 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3879 }
3880
3881 return err;
3882}
3883
3884static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3885{
3886 s32 err = 0;
3887
3888 set_bit(WL_STATUS_READY, &cfg_priv->status);
3889
3890 brcmf_debugfs_add_netdev_params(cfg_priv);
3891
3892 err = brcmf_config_dongle(cfg_priv, false);
3893 if (unlikely(err))
3894 return err;
3895
3896 brcmf_invoke_iscan(cfg_priv);
3897
3898 return err;
3899}
3900
3901static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3902{
3903 /*
3904 * While going down, if associated with AP disassociate
3905 * from AP to save power
3906 */
3907 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3908 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3909 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3910 WL_INFO("Disassociating from AP");
3911 brcmf_link_down(cfg_priv);
3912
3913 /* Make sure WPA_Supplicant receives all the event
3914 generated due to DISASSOC call to the fw to keep
3915 the state fw and WPA_Supplicant state consistent
3916 */
3917 rtnl_unlock();
3918 brcmf_delay(500);
3919 rtnl_lock();
3920 }
3921
3922 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3923 brcmf_term_iscan(cfg_priv);
3924 if (cfg_priv->scan_request) {
3925 cfg80211_scan_done(cfg_priv->scan_request, true);
3926 /* May need to perform this to cover rmmod */
3927 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3928 cfg_priv->scan_request = NULL;
3929 }
3930 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3931 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3932 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3933
3934 brcmf_debugfs_remove_netdev(cfg_priv);
3935
3936 return 0;
3937}
3938
3939s32 brcmf_cfg80211_up(void)
3940{
3941 struct brcmf_cfg80211_priv *cfg_priv;
3942 s32 err = 0;
3943
3944 cfg_priv = WL_PRIV_GET();
3945 mutex_lock(&cfg_priv->usr_sync);
3946 err = __brcmf_cfg80211_up(cfg_priv);
3947 mutex_unlock(&cfg_priv->usr_sync);
3948
3949 return err;
3950}
3951
3952s32 brcmf_cfg80211_down(void)
3953{
3954 struct brcmf_cfg80211_priv *cfg_priv;
3955 s32 err = 0;
3956
3957 cfg_priv = WL_PRIV_GET();
3958 mutex_lock(&cfg_priv->usr_sync);
3959 err = __brcmf_cfg80211_down(cfg_priv);
3960 mutex_unlock(&cfg_priv->usr_sync);
3961
3962 return err;
3963}
3964
3965static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3966{
3967 return wl_update_wiphybands(cfg_priv);
3968}
3969
3970static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
3971{
3972 switch (item) {
3973 case WL_PROF_SEC:
3974 return &cfg_priv->profile->sec;
3975 case WL_PROF_BSSID:
3976 return &cfg_priv->profile->bssid;
3977 case WL_PROF_SSID:
3978 return &cfg_priv->profile->ssid;
3979 }
3980 WL_ERR("invalid item (%d)\n", item);
3981 return NULL;
3982}
3983
3984static s32
3985brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
3986 const struct brcmf_event_msg *e, void *data, s32 item)
3987{
3988 s32 err = 0;
3989 struct brcmf_ssid *ssid;
3990
3991 switch (item) {
3992 case WL_PROF_SSID:
3993 ssid = (struct brcmf_ssid *) data;
3994 memset(cfg_priv->profile->ssid.SSID, 0,
3995 sizeof(cfg_priv->profile->ssid.SSID));
3996 memcpy(cfg_priv->profile->ssid.SSID,
3997 ssid->SSID, ssid->SSID_len);
3998 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
3999 break;
4000 case WL_PROF_BSSID:
4001 if (data)
4002 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
4003 else
4004 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
4005 break;
4006 case WL_PROF_SEC:
4007 memcpy(&cfg_priv->profile->sec, data,
4008 sizeof(cfg_priv->profile->sec));
4009 break;
4010 case WL_PROF_BEACONINT:
4011 cfg_priv->profile->beacon_interval = *(u16 *)data;
4012 break;
4013 case WL_PROF_DTIMPERIOD:
4014 cfg_priv->profile->dtim_period = *(u8 *)data;
4015 break;
4016 default:
4017 WL_ERR("unsupported item (%d)\n", item);
4018 err = -EOPNOTSUPP;
4019 break;
4020 }
4021
4022 return err;
4023}
4024
4025static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
4026{
4027 return cfg_priv->conf->mode == WL_MODE_IBSS;
4028}
4029
4030static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
4031 u8 t, u8 l, u8 *v)
4032{
4033 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
4034 s32 err = 0;
4035
4036 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
4037 WL_ERR("ei crosses buffer boundary\n");
4038 return -ENOSPC;
4039 }
4040 ie->buf[ie->offset] = t;
4041 ie->buf[ie->offset + 1] = l;
4042 memcpy(&ie->buf[ie->offset + 2], v, l);
4043 ie->offset += l + 2;
4044
4045 return err;
4046}
4047
4048static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
4049{
4050 struct net_device *dev = NULL;
4051 s32 err = 0;
4052
4053 WL_TRACE("Enter\n");
4054
4055 if (cfg_priv->link_up) {
4056 dev = cfg_to_ndev(cfg_priv);
4057 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
4058 err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, NULL, 0);
4059 if (unlikely(err))
4060 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
4061 cfg_priv->link_up = false;
4062 }
4063 WL_TRACE("Exit\n");
4064}
4065
4066static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv)
4067{
4068 spin_lock_irq(&cfg_priv->eq_lock);
4069}
4070
4071static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv)
4072{
4073 spin_unlock_irq(&cfg_priv->eq_lock);
4074}
4075
4076static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv)
4077{
4078 spin_lock_init(&cfg_priv->eq_lock);
4079}
4080
4081static void brcmf_delay(u32 ms)
4082{
4083 if (ms < 1000 / HZ) {
4084 cond_resched();
4085 mdelay(ms);
4086 } else {
4087 msleep(ms);
4088 }
4089}
4090
4091static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
4092{
4093 dev->driver_data = data;
4094}
4095
4096static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
4097{
4098 void *data = NULL;
4099
4100 if (dev)
4101 data = dev->driver_data;
4102 return data;
4103}
4104
4105static void brcmf_set_mpc(struct net_device *ndev, int mpc)
4106{
4107 s32 err = 0;
4108 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
4109
4110 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
4111 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
4112 if (unlikely(err)) {
4113 WL_ERR("fail to set mpc\n");
4114 return;
4115 }
4116 WL_INFO("MPC : %d\n", mpc);
4117 }
4118}
4119
4120static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
4121{
4122 char buf[10+IFNAMSIZ];
4123 struct dentry *fd;
4124 s32 err = 0;
4125
4126 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
4127 cfg_priv->debugfsdir = debugfs_create_dir(buf,
4128 cfg_to_wiphy(cfg_priv)->debugfsdir);
4129
4130 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
4131 (u16 *)&cfg_priv->profile->beacon_interval);
4132 if (!fd) {
4133 err = -ENOMEM;
4134 goto err_out;
4135 }
4136
4137 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
4138 (u8 *)&cfg_priv->profile->dtim_period);
4139 if (!fd) {
4140 err = -ENOMEM;
4141 goto err_out;
4142 }
4143
4144err_out:
4145 return err;
4146}
4147
4148static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
4149{
4150 debugfs_remove_recursive(cfg_priv->debugfsdir);
4151 cfg_priv->debugfsdir = NULL;
4152}
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
new file mode 100644
index 00000000000..f26d08793ca
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
@@ -0,0 +1,356 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _wl_cfg80211_h_
18#define _wl_cfg80211_h_
19
20struct brcmf_cfg80211_conf;
21struct brcmf_cfg80211_iface;
22struct brcmf_cfg80211_priv;
23struct brcmf_cfg80211_security;
24struct brcmf_cfg80211_ibss;
25
26#define WL_DBG_NONE 0
27#define WL_DBG_CONN (1 << 5)
28#define WL_DBG_SCAN (1 << 4)
29#define WL_DBG_TRACE (1 << 3)
30#define WL_DBG_INFO (1 << 1)
31#define WL_DBG_ERR (1 << 0)
32#define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
33 (WL_DBG_SCAN) | (WL_DBG_CONN))
34
35#define WL_ERR(fmt, args...) \
36do { \
37 if (brcmf_dbg_level & WL_DBG_ERR) { \
38 if (net_ratelimit()) { \
39 printk(KERN_ERR "ERROR @%s : " fmt, \
40 __func__, ##args); \
41 } \
42 } \
43} while (0)
44
45#if (defined BCMDBG)
46#define WL_INFO(fmt, args...) \
47do { \
48 if (brcmf_dbg_level & WL_DBG_INFO) { \
49 if (net_ratelimit()) { \
50 printk(KERN_ERR "INFO @%s : " fmt, \
51 __func__, ##args); \
52 } \
53 } \
54} while (0)
55
56#define WL_TRACE(fmt, args...) \
57do { \
58 if (brcmf_dbg_level & WL_DBG_TRACE) { \
59 if (net_ratelimit()) { \
60 printk(KERN_ERR "TRACE @%s : " fmt, \
61 __func__, ##args); \
62 } \
63 } \
64} while (0)
65
66#define WL_SCAN(fmt, args...) \
67do { \
68 if (brcmf_dbg_level & WL_DBG_SCAN) { \
69 if (net_ratelimit()) { \
70 printk(KERN_ERR "SCAN @%s : " fmt, \
71 __func__, ##args); \
72 } \
73 } \
74} while (0)
75
76#define WL_CONN(fmt, args...) \
77do { \
78 if (brcmf_dbg_level & WL_DBG_CONN) { \
79 if (net_ratelimit()) { \
80 printk(KERN_ERR "CONN @%s : " fmt, \
81 __func__, ##args); \
82 } \
83 } \
84} while (0)
85
86#else /* (defined BCMDBG) */
87#define WL_INFO(fmt, args...)
88#define WL_TRACE(fmt, args...)
89#define WL_SCAN(fmt, args...)
90#define WL_CONN(fmt, args...)
91#endif /* (defined BCMDBG) */
92
93#define WL_NUM_SCAN_MAX 1
94#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used
95 * for 2.6.33 kernel
96 * or later
97 */
98#define WL_SCAN_BUF_MAX (1024 * 8)
99#define WL_TLV_INFO_MAX 1024
100#define WL_BSS_INFO_MAX 2048
101#define WL_ASSOC_INFO_MAX 512 /*
102 * needs to grab assoc info from dongle to
103 * report it to cfg80211 through "connect"
104 * event
105 */
106#define WL_IOCTL_LEN_MAX 1024
107#define WL_EXTRA_BUF_MAX 2048
108#define WL_ISCAN_BUF_MAX 2048 /*
109 * the buf length can be BRCMF_C_IOCTL_MAXLEN
110 * to reduce iteration
111 */
112#define WL_ISCAN_TIMER_INTERVAL_MS 3000
113#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1)
114#define WL_AP_MAX 256 /* virtually unlimitted as long
115 * as kernel memory allows
116 */
117
118#define WL_ROAM_TRIGGER_LEVEL -75
119#define WL_ROAM_DELTA 20
120#define WL_BEACON_TIMEOUT 3
121
122#define WL_SCAN_CHANNEL_TIME 40
123#define WL_SCAN_UNASSOC_TIME 40
124#define WL_SCAN_PASSIVE_TIME 120
125
126/* dongle status */
127enum wl_status {
128 WL_STATUS_READY,
129 WL_STATUS_SCANNING,
130 WL_STATUS_SCAN_ABORTING,
131 WL_STATUS_CONNECTING,
132 WL_STATUS_CONNECTED
133};
134
135/* wi-fi mode */
136enum wl_mode {
137 WL_MODE_BSS,
138 WL_MODE_IBSS,
139 WL_MODE_AP
140};
141
142/* dongle profile list */
143enum wl_prof_list {
144 WL_PROF_MODE,
145 WL_PROF_SSID,
146 WL_PROF_SEC,
147 WL_PROF_IBSS,
148 WL_PROF_BAND,
149 WL_PROF_BSSID,
150 WL_PROF_ACT,
151 WL_PROF_BEACONINT,
152 WL_PROF_DTIMPERIOD
153};
154
155/* dongle iscan state */
156enum wl_iscan_state {
157 WL_ISCAN_STATE_IDLE,
158 WL_ISCAN_STATE_SCANING
159};
160
161/* dongle configuration */
162struct brcmf_cfg80211_conf {
163 u32 mode; /* adhoc , infrastructure or ap */
164 u32 frag_threshold;
165 u32 rts_threshold;
166 u32 retry_short;
167 u32 retry_long;
168 s32 tx_power;
169 struct ieee80211_channel channel;
170};
171
172/* cfg80211 main event loop */
173struct brcmf_cfg80211_event_loop {
174 s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
175 struct net_device *ndev,
176 const struct brcmf_event_msg *e,
177 void *data);
178};
179
180/* representing interface of cfg80211 plane */
181struct brcmf_cfg80211_iface {
182 struct brcmf_cfg80211_priv *cfg_priv;
183};
184
185struct brcmf_cfg80211_dev {
186 void *driver_data; /* to store cfg80211 object information */
187};
188
189/* basic structure of scan request */
190struct brcmf_cfg80211_scan_req {
191 struct brcmf_ssid ssid;
192};
193
194/* basic structure of information element */
195struct brcmf_cfg80211_ie {
196 u16 offset;
197 u8 buf[WL_TLV_INFO_MAX];
198};
199
200/* event queue for cfg80211 main event */
201struct brcmf_cfg80211_event_q {
202 struct list_head eq_list;
203 u32 etype;
204 struct brcmf_event_msg emsg;
205 s8 edata[1];
206};
207
208/* security information with currently associated ap */
209struct brcmf_cfg80211_security {
210 u32 wpa_versions;
211 u32 auth_type;
212 u32 cipher_pairwise;
213 u32 cipher_group;
214 u32 wpa_auth;
215};
216
217/* ibss information for currently joined ibss network */
218struct brcmf_cfg80211_ibss {
219 u8 beacon_interval; /* in millisecond */
220 u8 atim; /* in millisecond */
221 s8 join_only;
222 u8 band;
223 u8 channel;
224};
225
226/* dongle profile */
227struct brcmf_cfg80211_profile {
228 u32 mode;
229 struct brcmf_ssid ssid;
230 u8 bssid[ETH_ALEN];
231 u16 beacon_interval;
232 u8 dtim_period;
233 struct brcmf_cfg80211_security sec;
234 struct brcmf_cfg80211_ibss ibss;
235 s32 band;
236};
237
238/* dongle iscan event loop */
239struct brcmf_cfg80211_iscan_eloop {
240 s32 (*handler[WL_SCAN_ERSULTS_LAST])
241 (struct brcmf_cfg80211_priv *cfg_priv);
242};
243
244/* dongle iscan controller */
245struct brcmf_cfg80211_iscan_ctrl {
246 struct net_device *dev;
247 struct timer_list timer;
248 u32 timer_ms;
249 u32 timer_on;
250 s32 state;
251 struct task_struct *tsk;
252 struct semaphore sync;
253 struct brcmf_cfg80211_iscan_eloop el;
254 void *data;
255 s8 ioctl_buf[BRCMF_C_IOCTL_SMLEN];
256 s8 scan_buf[WL_ISCAN_BUF_MAX];
257};
258
259/* association inform */
260struct brcmf_cfg80211_connect_info {
261 u8 *req_ie;
262 s32 req_ie_len;
263 u8 *resp_ie;
264 s32 resp_ie_len;
265};
266
267/* assoc ie length */
268struct brcmf_cfg80211_assoc_ielen {
269 u32 req_len;
270 u32 resp_len;
271};
272
273/* wpa2 pmk list */
274struct brcmf_cfg80211_pmk_list {
275 pmkid_list_t pmkids;
276 pmkid_t foo[MAXPMKID - 1];
277};
278
279/* dongle private data of cfg80211 interface */
280struct brcmf_cfg80211_priv {
281 struct wireless_dev *wdev; /* representing wl cfg80211 device */
282 struct brcmf_cfg80211_conf *conf; /* dongle configuration */
283 struct cfg80211_scan_request *scan_request; /* scan request
284 object */
285 struct brcmf_cfg80211_event_loop el; /* main event loop */
286 struct list_head eq_list; /* used for event queue */
287 spinlock_t eq_lock; /* for event queue synchronization */
288 struct mutex usr_sync; /* maily for dongle up/down synchronization */
289 struct brcmf_scan_results *bss_list; /* bss_list holding scanned
290 ap information */
291 struct brcmf_scan_results *scan_results;
292 struct brcmf_cfg80211_scan_req *scan_req_int; /* scan request object
293 for internal purpose */
294 struct wl_cfg80211_bss_info *bss_info; /* bss information for
295 cfg80211 layer */
296 struct brcmf_cfg80211_ie ie; /* information element object for
297 internal purpose */
298 struct semaphore event_sync; /* for synchronization of main event
299 thread */
300 struct brcmf_cfg80211_profile *profile; /* holding dongle profile */
301 struct brcmf_cfg80211_iscan_ctrl *iscan; /* iscan controller */
302 struct brcmf_cfg80211_connect_info conn_info; /* association info */
303 struct brcmf_cfg80211_pmk_list *pmk_list; /* wpa2 pmk list */
304 struct task_struct *event_tsk; /* task of main event handler thread */
305 unsigned long status; /* current dongle status */
306 void *pub;
307 u32 channel; /* current channel */
308 bool iscan_on; /* iscan on/off switch */
309 bool iscan_kickstart; /* indicate iscan already started */
310 bool active_scan; /* current scan mode */
311 bool ibss_starter; /* indicates this sta is ibss starter */
312 bool link_up; /* link/connection up flag */
313 bool pwr_save; /* indicate whether dongle to support
314 power save mode */
315 bool dongle_up; /* indicate whether dongle up or not */
316 bool roam_on; /* on/off switch for dongle self-roaming */
317 bool scan_tried; /* indicates if first scan attempted */
318 u8 *ioctl_buf; /* ioctl buffer */
319 u8 *extra_buf; /* maily to grab assoc information */
320 struct dentry *debugfsdir;
321 u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
322};
323
324#define cfg_to_wiphy(w) (w->wdev->wiphy)
325#define wiphy_to_cfg(w) ((struct brcmf_cfg80211_priv *)(wiphy_priv(w)))
326#define cfg_to_wdev(w) (w->wdev)
327#define wdev_to_cfg(w) ((struct brcmf_cfg80211_priv *)(wdev_priv(w)))
328#define cfg_to_ndev(w) (w->wdev->netdev)
329#define ndev_to_cfg(n) (wdev_to_cfg(n->ieee80211_ptr))
330#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
331#define cfg_to_iscan(w) (w->iscan)
332#define cfg_to_conn(w) (&w->conn_info)
333
334static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list,
335 struct brcmf_bss_info *bss)
336{
337 return bss = bss ?
338 (struct brcmf_bss_info *)((unsigned long)bss +
339 le32_to_cpu(bss->length)) :
340 list->bss_info;
341}
342
343#define for_each_bss(list, bss, __i) \
344 for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
345
346extern s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data);
347extern void brcmf_cfg80211_detach(void);
348/* event handler from dongle */
349extern void brcmf_cfg80211_event(struct net_device *ndev,
350 const struct brcmf_event_msg *e, void *data);
351extern void brcmf_cfg80211_sdio_func(void *func); /* set sdio function info */
352extern struct sdio_func *brcmf_cfg80211_get_sdio_func(void);
353extern s32 brcmf_cfg80211_up(void); /* dongle up */
354extern s32 brcmf_cfg80211_down(void); /* dongle down */
355
356#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile
new file mode 100644
index 00000000000..1ea3e0c48f3
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/Makefile
@@ -0,0 +1,58 @@
1#
2# Makefile fragment for Broadcom 802.11n Networking Device Driver
3#
4# Copyright (c) 2010 Broadcom Corporation
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18ccflags-y := \
19 -DWLC_HIGH \
20 -DWLC_LOW \
21 -DSTA \
22 -DWME \
23 -DWL11N \
24 -DDBAND \
25 -DBCMNVRAMR \
26 -Idrivers/staging/brcm80211/brcmsmac \
27 -Idrivers/staging/brcm80211/brcmsmac/phy \
28 -Idrivers/staging/brcm80211/include
29
30BRCMSMAC_OFILES := \
31 mac80211_if.o \
32 ucode_loader.o \
33 alloc.o \
34 ampdu.o \
35 antsel.o \
36 bmac.o \
37 channel.o \
38 main.o \
39 phy_shim.o \
40 pmu.o \
41 rate.o \
42 stf.o \
43 aiutils.o \
44 phy/phy_cmn.o \
45 phy/phy_lcn.o \
46 phy/phy_n.o \
47 phy/phytbl_lcn.o \
48 phy/phytbl_n.o \
49 phy/phy_qmath.o \
50 otp.o \
51 srom.o \
52 dma.o \
53 nicpci.o
54
55MODULEPFX := brcmsmac
56
57obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
58$(MODULEPFX)-objs = $(BRCMSMAC_OFILES)
diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.c b/drivers/staging/brcm80211/brcmsmac/aiutils.c
new file mode 100644
index 00000000000..a25901e9981
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/aiutils.c
@@ -0,0 +1,2279 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/delay.h>
17#include <linux/pci.h>
18
19#include <defs.h>
20#include <chipcommon.h>
21#include <brcmu_utils.h>
22#include <brcm_hw_ids.h>
23#include "types.h"
24#include "pub.h"
25#include "pmu.h"
26#include "srom.h"
27#include "nicpci.h"
28#include "aiutils.h"
29
30/* slow_clk_ctl */
31#define SCC_SS_MASK 0x00000007 /* slow clock source mask */
32#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */
33#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */
34#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */
35#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
36#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled,
37 * 0: LPO is enabled
38 */
39#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock,
40 * 0: power logic control
41 */
42#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors
43 * PLL clock disable requests from core
44 */
45#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't
46 * disable crystal when appropriate
47 */
48#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
49#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
50#define SCC_CD_SHIFT 16
51
52/* system_clk_ctl */
53#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */
54#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */
55#define SYCC_FP 0x00000004 /* ForcePLLOn */
56#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */
57#define SYCC_HR 0x00000010 /* Force HT */
58#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */
59#define SYCC_CD_SHIFT 16
60
61#define CST4329_SPROM_OTP_SEL_MASK 0x00000003
62#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
63#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
64#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */
65#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */
66#define CST4329_SPI_SDIO_MODE_MASK 0x00000004
67#define CST4329_SPI_SDIO_MODE_SHIFT 2
68
69/* 43224 chip-specific ChipControl register bits */
70#define CCTRL43224_GPIO_TOGGLE 0x8000
71#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */
72#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */
73
74/* 43236 Chip specific ChipStatus register bits */
75#define CST43236_SFLASH_MASK 0x00000040
76#define CST43236_OTP_MASK 0x00000080
77#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */
78#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */
79#define CST43236_BOOT_MASK 0x00001800
80#define CST43236_BOOT_SHIFT 11
81#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */
82#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */
83#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */
84#define CST43236_BOOT_FROM_INVALID 3
85
86/* 4331 chip-specific ChipControl register bits */
87#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */
88#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */
89#define CCTRL4331_EXT_LNA (1<<2) /* 0 disable */
90#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */
91#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */
92#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */
93#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */
94#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */
95#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */
96#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */
97#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */
98#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */
99#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */
100#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */
101
102/* 4331 Chip specific ChipStatus register bits */
103#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */
104#define CST4331_SPROM_PRESENT 0x00000002
105#define CST4331_OTP_PRESENT 0x00000004
106#define CST4331_LDO_RF 0x00000008
107#define CST4331_LDO_PAR 0x00000010
108
109/* 4319 chip-specific ChipStatus register bits */
110#define CST4319_SPI_CPULESSUSB 0x00000001
111#define CST4319_SPI_CLK_POL 0x00000002
112#define CST4319_SPI_CLK_PH 0x00000008
113#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */
114#define CST4319_SPROM_OTP_SEL_SHIFT 6
115#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */
116#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */
117#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */
118#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */
119#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */
120#define CST4319_REMAP_SEL_MASK 0x00000600
121#define CST4319_ILPDIV_EN 0x00000800
122#define CST4319_XTAL_PD_POL 0x00001000
123#define CST4319_LPO_SEL 0x00002000
124#define CST4319_RES_INIT_MODE 0x0000c000
125#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */
126#define CST4319_CBUCK_MODE_MASK 0x00060000
127#define CST4319_CBUCK_MODE_BURST 0x00020000
128#define CST4319_CBUCK_MODE_LPBURST 0x00060000
129#define CST4319_RCAL_VALID 0x01000000
130#define CST4319_RCAL_VALUE_MASK 0x3e000000
131#define CST4319_RCAL_VALUE_SHIFT 25
132
133/* 4336 chip-specific ChipStatus register bits */
134#define CST4336_SPI_MODE_MASK 0x00000001
135#define CST4336_SPROM_PRESENT 0x00000002
136#define CST4336_OTP_PRESENT 0x00000004
137#define CST4336_ARMREMAP_0 0x00000008
138#define CST4336_ILPDIV_EN_MASK 0x00000010
139#define CST4336_ILPDIV_EN_SHIFT 4
140#define CST4336_XTAL_PD_POL_MASK 0x00000020
141#define CST4336_XTAL_PD_POL_SHIFT 5
142#define CST4336_LPO_SEL_MASK 0x00000040
143#define CST4336_LPO_SEL_SHIFT 6
144#define CST4336_RES_INIT_MODE_MASK 0x00000180
145#define CST4336_RES_INIT_MODE_SHIFT 7
146#define CST4336_CBUCK_MODE_MASK 0x00000600
147#define CST4336_CBUCK_MODE_SHIFT 9
148
149/* 4313 chip-specific ChipStatus register bits */
150#define CST4313_SPROM_PRESENT 1
151#define CST4313_OTP_PRESENT 2
152#define CST4313_SPROM_OTP_SEL_MASK 0x00000002
153#define CST4313_SPROM_OTP_SEL_SHIFT 0
154
155/* 4313 Chip specific ChipControl register bits */
156#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */
157
158#define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \
159 (sih->chiprev == 0) && \
160 (sii->coreid[sii->curidx] == MIPS74K_CORE_ID))
161
162/* Manufacturer Ids */
163#define MFGID_ARM 0x43b
164#define MFGID_BRCM 0x4bf
165#define MFGID_MIPS 0x4a7
166
167/* Enumeration ROM registers */
168#define ER_EROMENTRY 0x000
169#define ER_REMAPCONTROL 0xe00
170#define ER_REMAPSELECT 0xe04
171#define ER_MASTERSELECT 0xe10
172#define ER_ITCR 0xf00
173#define ER_ITIP 0xf04
174
175/* Erom entries */
176#define ER_TAG 0xe
177#define ER_TAG1 0x6
178#define ER_VALID 1
179#define ER_CI 0
180#define ER_MP 2
181#define ER_ADD 4
182#define ER_END 0xe
183#define ER_BAD 0xffffffff
184
185/* EROM CompIdentA */
186#define CIA_MFG_MASK 0xfff00000
187#define CIA_MFG_SHIFT 20
188#define CIA_CID_MASK 0x000fff00
189#define CIA_CID_SHIFT 8
190#define CIA_CCL_MASK 0x000000f0
191#define CIA_CCL_SHIFT 4
192
193/* EROM CompIdentB */
194#define CIB_REV_MASK 0xff000000
195#define CIB_REV_SHIFT 24
196#define CIB_NSW_MASK 0x00f80000
197#define CIB_NSW_SHIFT 19
198#define CIB_NMW_MASK 0x0007c000
199#define CIB_NMW_SHIFT 14
200#define CIB_NSP_MASK 0x00003e00
201#define CIB_NSP_SHIFT 9
202#define CIB_NMP_MASK 0x000001f0
203#define CIB_NMP_SHIFT 4
204
205/* EROM AddrDesc */
206#define AD_ADDR_MASK 0xfffff000
207#define AD_SP_MASK 0x00000f00
208#define AD_SP_SHIFT 8
209#define AD_ST_MASK 0x000000c0
210#define AD_ST_SHIFT 6
211#define AD_ST_SLAVE 0x00000000
212#define AD_ST_BRIDGE 0x00000040
213#define AD_ST_SWRAP 0x00000080
214#define AD_ST_MWRAP 0x000000c0
215#define AD_SZ_MASK 0x00000030
216#define AD_SZ_SHIFT 4
217#define AD_SZ_4K 0x00000000
218#define AD_SZ_8K 0x00000010
219#define AD_SZ_16K 0x00000020
220#define AD_SZ_SZD 0x00000030
221#define AD_AG32 0x00000008
222#define AD_ADDR_ALIGN 0x00000fff
223#define AD_SZ_BASE 0x00001000 /* 4KB */
224
225/* EROM SizeDesc */
226#define SD_SZ_MASK 0xfffff000
227#define SD_SG32 0x00000008
228#define SD_SZ_ALIGN 0x00000fff
229
230#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
231#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */
232#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */
233
234/* power control defines */
235#define PLL_DELAY 150 /* us pll on delay */
236#define FREF_DELAY 200 /* us fref change delay */
237#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
238
239/* resetctrl */
240#define AIRC_RESET 1
241
242struct aidmp {
243 u32 oobselina30; /* 0x000 */
244 u32 oobselina74; /* 0x004 */
245 u32 PAD[6];
246 u32 oobselinb30; /* 0x020 */
247 u32 oobselinb74; /* 0x024 */
248 u32 PAD[6];
249 u32 oobselinc30; /* 0x040 */
250 u32 oobselinc74; /* 0x044 */
251 u32 PAD[6];
252 u32 oobselind30; /* 0x060 */
253 u32 oobselind74; /* 0x064 */
254 u32 PAD[38];
255 u32 oobselouta30; /* 0x100 */
256 u32 oobselouta74; /* 0x104 */
257 u32 PAD[6];
258 u32 oobseloutb30; /* 0x120 */
259 u32 oobseloutb74; /* 0x124 */
260 u32 PAD[6];
261 u32 oobseloutc30; /* 0x140 */
262 u32 oobseloutc74; /* 0x144 */
263 u32 PAD[6];
264 u32 oobseloutd30; /* 0x160 */
265 u32 oobseloutd74; /* 0x164 */
266 u32 PAD[38];
267 u32 oobsynca; /* 0x200 */
268 u32 oobseloutaen; /* 0x204 */
269 u32 PAD[6];
270 u32 oobsyncb; /* 0x220 */
271 u32 oobseloutben; /* 0x224 */
272 u32 PAD[6];
273 u32 oobsyncc; /* 0x240 */
274 u32 oobseloutcen; /* 0x244 */
275 u32 PAD[6];
276 u32 oobsyncd; /* 0x260 */
277 u32 oobseloutden; /* 0x264 */
278 u32 PAD[38];
279 u32 oobaextwidth; /* 0x300 */
280 u32 oobainwidth; /* 0x304 */
281 u32 oobaoutwidth; /* 0x308 */
282 u32 PAD[5];
283 u32 oobbextwidth; /* 0x320 */
284 u32 oobbinwidth; /* 0x324 */
285 u32 oobboutwidth; /* 0x328 */
286 u32 PAD[5];
287 u32 oobcextwidth; /* 0x340 */
288 u32 oobcinwidth; /* 0x344 */
289 u32 oobcoutwidth; /* 0x348 */
290 u32 PAD[5];
291 u32 oobdextwidth; /* 0x360 */
292 u32 oobdinwidth; /* 0x364 */
293 u32 oobdoutwidth; /* 0x368 */
294 u32 PAD[37];
295 u32 ioctrlset; /* 0x400 */
296 u32 ioctrlclear; /* 0x404 */
297 u32 ioctrl; /* 0x408 */
298 u32 PAD[61];
299 u32 iostatus; /* 0x500 */
300 u32 PAD[127];
301 u32 ioctrlwidth; /* 0x700 */
302 u32 iostatuswidth; /* 0x704 */
303 u32 PAD[62];
304 u32 resetctrl; /* 0x800 */
305 u32 resetstatus; /* 0x804 */
306 u32 resetreadid; /* 0x808 */
307 u32 resetwriteid; /* 0x80c */
308 u32 PAD[60];
309 u32 errlogctrl; /* 0x900 */
310 u32 errlogdone; /* 0x904 */
311 u32 errlogstatus; /* 0x908 */
312 u32 errlogaddrlo; /* 0x90c */
313 u32 errlogaddrhi; /* 0x910 */
314 u32 errlogid; /* 0x914 */
315 u32 errloguser; /* 0x918 */
316 u32 errlogflags; /* 0x91c */
317 u32 PAD[56];
318 u32 intstatus; /* 0xa00 */
319 u32 PAD[127];
320 u32 config; /* 0xe00 */
321 u32 PAD[63];
322 u32 itcr; /* 0xf00 */
323 u32 PAD[3];
324 u32 itipooba; /* 0xf10 */
325 u32 itipoobb; /* 0xf14 */
326 u32 itipoobc; /* 0xf18 */
327 u32 itipoobd; /* 0xf1c */
328 u32 PAD[4];
329 u32 itipoobaout; /* 0xf30 */
330 u32 itipoobbout; /* 0xf34 */
331 u32 itipoobcout; /* 0xf38 */
332 u32 itipoobdout; /* 0xf3c */
333 u32 PAD[4];
334 u32 itopooba; /* 0xf50 */
335 u32 itopoobb; /* 0xf54 */
336 u32 itopoobc; /* 0xf58 */
337 u32 itopoobd; /* 0xf5c */
338 u32 PAD[4];
339 u32 itopoobain; /* 0xf70 */
340 u32 itopoobbin; /* 0xf74 */
341 u32 itopoobcin; /* 0xf78 */
342 u32 itopoobdin; /* 0xf7c */
343 u32 PAD[4];
344 u32 itopreset; /* 0xf90 */
345 u32 PAD[15];
346 u32 peripherialid4; /* 0xfd0 */
347 u32 peripherialid5; /* 0xfd4 */
348 u32 peripherialid6; /* 0xfd8 */
349 u32 peripherialid7; /* 0xfdc */
350 u32 peripherialid0; /* 0xfe0 */
351 u32 peripherialid1; /* 0xfe4 */
352 u32 peripherialid2; /* 0xfe8 */
353 u32 peripherialid3; /* 0xfec */
354 u32 componentid0; /* 0xff0 */
355 u32 componentid1; /* 0xff4 */
356 u32 componentid2; /* 0xff8 */
357 u32 componentid3; /* 0xffc */
358};
359
360/* EROM parsing */
361
362static u32
363get_erom_ent(struct si_pub *sih, u32 **eromptr, u32 mask, u32 match)
364{
365 u32 ent;
366 uint inv = 0, nom = 0;
367
368 while (true) {
369 ent = R_REG(*eromptr);
370 (*eromptr)++;
371
372 if (mask == 0)
373 break;
374
375 if ((ent & ER_VALID) == 0) {
376 inv++;
377 continue;
378 }
379
380 if (ent == (ER_END | ER_VALID))
381 break;
382
383 if ((ent & mask) == match)
384 break;
385
386 nom++;
387 }
388
389 SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent));
390 if (inv + nom) {
391 SI_VMSG((" after %d invalid and %d non-matching entries\n",
392 inv, nom));
393 }
394 return ent;
395}
396
397static u32
398get_asd(struct si_pub *sih, u32 **eromptr, uint sp, uint ad, uint st,
399 u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh)
400{
401 u32 asd, sz, szd;
402
403 asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
404 if (((asd & ER_TAG1) != ER_ADD) ||
405 (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
406 ((asd & AD_ST_MASK) != st)) {
407 /* This is not what we want, "push" it back */
408 (*eromptr)--;
409 return 0;
410 }
411 *addrl = asd & AD_ADDR_MASK;
412 if (asd & AD_AG32)
413 *addrh = get_erom_ent(sih, eromptr, 0, 0);
414 else
415 *addrh = 0;
416 *sizeh = 0;
417 sz = asd & AD_SZ_MASK;
418 if (sz == AD_SZ_SZD) {
419 szd = get_erom_ent(sih, eromptr, 0, 0);
420 *sizel = szd & SD_SZ_MASK;
421 if (szd & SD_SG32)
422 *sizeh = get_erom_ent(sih, eromptr, 0, 0);
423 } else
424 *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
425
426 SI_VMSG((" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
427 sp, ad, st, *sizeh, *sizel, *addrh, *addrl));
428
429 return asd;
430}
431
432static void ai_hwfixup(struct si_info *sii)
433{
434}
435
436/* parse the enumeration rom to identify all cores */
437void ai_scan(struct si_pub *sih, void *regs)
438{
439 struct si_info *sii = SI_INFO(sih);
440 chipcregs_t *cc = (chipcregs_t *) regs;
441 u32 erombase, *eromptr, *eromlim;
442
443 erombase = R_REG(&cc->eromptr);
444
445 switch (sih->bustype) {
446 case SI_BUS:
447 eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE);
448 break;
449
450 case PCI_BUS:
451 /* Set wrappers address */
452 sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE);
453
454 /* Now point the window at the erom */
455 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase);
456 eromptr = regs;
457 break;
458
459 case SPI_BUS:
460 case SDIO_BUS:
461 eromptr = (u32 *)(unsigned long)erombase;
462 break;
463
464 default:
465 SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n",
466 sih->bustype));
467 return;
468 }
469 eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32));
470
471 SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim));
472 while (eromptr < eromlim) {
473 u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
474 u32 mpd, asd, addrl, addrh, sizel, sizeh;
475 u32 *base;
476 uint i, j, idx;
477 bool br;
478
479 br = false;
480
481 /* Grok a component */
482 cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
483 if (cia == (ER_END | ER_VALID)) {
484 SI_VMSG(("Found END of erom after %d cores\n",
485 sii->numcores));
486 ai_hwfixup(sii);
487 return;
488 }
489 base = eromptr - 1;
490 cib = get_erom_ent(sih, &eromptr, 0, 0);
491
492 if ((cib & ER_TAG) != ER_CI) {
493 SI_ERROR(("CIA not followed by CIB\n"));
494 goto error;
495 }
496
497 cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
498 mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
499 crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
500 nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
501 nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
502 nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
503 nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
504
505 SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp));
506
507 if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
508 continue;
509 if ((nmw + nsw == 0)) {
510 /* A component which is not a core */
511 if (cid == OOB_ROUTER_CORE_ID) {
512 asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
513 &addrl, &addrh, &sizel, &sizeh);
514 if (asd != 0) {
515 sii->oob_router = addrl;
516 }
517 }
518 continue;
519 }
520
521 idx = sii->numcores;
522/* sii->eromptr[idx] = base; */
523 sii->cia[idx] = cia;
524 sii->cib[idx] = cib;
525 sii->coreid[idx] = cid;
526
527 for (i = 0; i < nmp; i++) {
528 mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
529 if ((mpd & ER_TAG) != ER_MP) {
530 SI_ERROR(("Not enough MP entries for component 0x%x\n", cid));
531 goto error;
532 }
533 SI_VMSG((" Master port %d, mp: %d id: %d\n", i,
534 (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
535 (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT));
536 }
537
538 /* First Slave Address Descriptor should be port 0:
539 * the main register space for the core
540 */
541 asd =
542 get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh,
543 &sizel, &sizeh);
544 if (asd == 0) {
545 /* Try again to see if it is a bridge */
546 asd =
547 get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl,
548 &addrh, &sizel, &sizeh);
549 if (asd != 0)
550 br = true;
551 else if ((addrh != 0) || (sizeh != 0)
552 || (sizel != SI_CORE_SIZE)) {
553 SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd));
554 goto error;
555 }
556 }
557 sii->coresba[idx] = addrl;
558 sii->coresba_size[idx] = sizel;
559 /* Get any more ASDs in port 0 */
560 j = 1;
561 do {
562 asd =
563 get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl,
564 &addrh, &sizel, &sizeh);
565 if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
566 sii->coresba2[idx] = addrl;
567 sii->coresba2_size[idx] = sizel;
568 }
569 j++;
570 } while (asd != 0);
571
572 /* Go through the ASDs for other slave ports */
573 for (i = 1; i < nsp; i++) {
574 j = 0;
575 do {
576 asd =
577 get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE,
578 &addrl, &addrh, &sizel, &sizeh);
579 } while (asd != 0);
580 if (j == 0) {
581 SI_ERROR((" SP %d has no address descriptors\n",
582 i));
583 goto error;
584 }
585 }
586
587 /* Now get master wrappers */
588 for (i = 0; i < nmw; i++) {
589 asd =
590 get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl,
591 &addrh, &sizel, &sizeh);
592 if (asd == 0) {
593 SI_ERROR(("Missing descriptor for MW %d\n", i));
594 goto error;
595 }
596 if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
597 SI_ERROR(("Master wrapper %d is not 4KB\n", i));
598 goto error;
599 }
600 if (i == 0)
601 sii->wrapba[idx] = addrl;
602 }
603
604 /* And finally slave wrappers */
605 for (i = 0; i < nsw; i++) {
606 uint fwp = (nsp == 1) ? 0 : 1;
607 asd =
608 get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP,
609 &addrl, &addrh, &sizel, &sizeh);
610 if (asd == 0) {
611 SI_ERROR(("Missing descriptor for SW %d\n", i));
612 goto error;
613 }
614 if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
615 SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
616 goto error;
617 }
618 if ((nmw == 0) && (i == 0))
619 sii->wrapba[idx] = addrl;
620 }
621
622 /* Don't record bridges */
623 if (br)
624 continue;
625
626 /* Done with core */
627 sii->numcores++;
628 }
629
630 SI_ERROR(("Reached end of erom without finding END"));
631
632 error:
633 sii->numcores = 0;
634 return;
635}
636
637/* This function changes the logical "focus" to the indicated core.
638 * Return the current core's virtual address.
639 */
640void *ai_setcoreidx(struct si_pub *sih, uint coreidx)
641{
642 struct si_info *sii = SI_INFO(sih);
643 u32 addr = sii->coresba[coreidx];
644 u32 wrap = sii->wrapba[coreidx];
645 void *regs;
646
647 if (coreidx >= sii->numcores)
648 return NULL;
649
650 switch (sih->bustype) {
651 case SI_BUS:
652 /* map new one */
653 if (!sii->regs[coreidx]) {
654 sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE);
655 }
656 sii->curmap = regs = sii->regs[coreidx];
657 if (!sii->wrappers[coreidx]) {
658 sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
659 }
660 sii->curwrap = sii->wrappers[coreidx];
661 break;
662
663 case PCI_BUS:
664 /* point bar0 window */
665 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr);
666 regs = sii->curmap;
667 /* point bar0 2nd 4KB window */
668 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap);
669 break;
670
671 case SPI_BUS:
672 case SDIO_BUS:
673 sii->curmap = regs = (void *)(unsigned long)addr;
674 sii->curwrap = (void *)(unsigned long)wrap;
675 break;
676
677 default:
678 regs = NULL;
679 break;
680 }
681
682 sii->curmap = regs;
683 sii->curidx = coreidx;
684
685 return regs;
686}
687
688/* Return the number of address spaces in current core */
689int ai_numaddrspaces(struct si_pub *sih)
690{
691 return 2;
692}
693
694/* Return the address of the nth address space in the current core */
695u32 ai_addrspace(struct si_pub *sih, uint asidx)
696{
697 struct si_info *sii;
698 uint cidx;
699
700 sii = SI_INFO(sih);
701 cidx = sii->curidx;
702
703 if (asidx == 0)
704 return sii->coresba[cidx];
705 else if (asidx == 1)
706 return sii->coresba2[cidx];
707 else {
708 SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
709 return 0;
710 }
711}
712
713/* Return the size of the nth address space in the current core */
714u32 ai_addrspacesize(struct si_pub *sih, uint asidx)
715{
716 struct si_info *sii;
717 uint cidx;
718
719 sii = SI_INFO(sih);
720 cidx = sii->curidx;
721
722 if (asidx == 0)
723 return sii->coresba_size[cidx];
724 else if (asidx == 1)
725 return sii->coresba2_size[cidx];
726 else {
727 SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
728 return 0;
729 }
730}
731
732uint ai_flag(struct si_pub *sih)
733{
734 struct si_info *sii;
735 struct aidmp *ai;
736
737 sii = SI_INFO(sih);
738 if (BCM47162_DMP()) {
739 SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__));
740 return sii->curidx;
741 }
742 ai = sii->curwrap;
743
744 return R_REG(&ai->oobselouta30) & 0x1f;
745}
746
747void ai_setint(struct si_pub *sih, int siflag)
748{
749}
750
751uint ai_corevendor(struct si_pub *sih)
752{
753 struct si_info *sii;
754 u32 cia;
755
756 sii = SI_INFO(sih);
757 cia = sii->cia[sii->curidx];
758 return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
759}
760
761uint ai_corerev(struct si_pub *sih)
762{
763 struct si_info *sii;
764 u32 cib;
765
766 sii = SI_INFO(sih);
767 cib = sii->cib[sii->curidx];
768 return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
769}
770
771bool ai_iscoreup(struct si_pub *sih)
772{
773 struct si_info *sii;
774 struct aidmp *ai;
775
776 sii = SI_INFO(sih);
777 ai = sii->curwrap;
778
779 return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) ==
780 SICF_CLOCK_EN)
781 && ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0));
782}
783
784void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val)
785{
786 struct si_info *sii;
787 struct aidmp *ai;
788 u32 w;
789
790 sii = SI_INFO(sih);
791
792 if (BCM47162_DMP()) {
793 SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
794 __func__));
795 return;
796 }
797
798 ai = sii->curwrap;
799
800 if (mask || val) {
801 w = ((R_REG(&ai->ioctrl) & ~mask) | val);
802 W_REG(&ai->ioctrl, w);
803 }
804}
805
806u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val)
807{
808 struct si_info *sii;
809 struct aidmp *ai;
810 u32 w;
811
812 sii = SI_INFO(sih);
813 if (BCM47162_DMP()) {
814 SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
815 __func__));
816 return 0;
817 }
818
819 ai = sii->curwrap;
820
821 if (mask || val) {
822 w = ((R_REG(&ai->ioctrl) & ~mask) | val);
823 W_REG(&ai->ioctrl, w);
824 }
825
826 return R_REG(&ai->ioctrl);
827}
828
829u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val)
830{
831 struct si_info *sii;
832 struct aidmp *ai;
833 u32 w;
834
835 sii = SI_INFO(sih);
836 if (BCM47162_DMP()) {
837 SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__));
838 return 0;
839 }
840
841 ai = sii->curwrap;
842
843 if (mask || val) {
844 w = ((R_REG(&ai->iostatus) & ~mask) | val);
845 W_REG(&ai->iostatus, w);
846 }
847
848 return R_REG(&ai->iostatus);
849}
850
851/* *************** from siutils.c ************** */
852/* local prototypes */
853static struct si_info *ai_doattach(struct si_info *sii, void *regs,
854 uint bustype, void *sdh, char **vars,
855 uint *varsz);
856static bool ai_buscore_prep(struct si_info *sii, uint bustype);
857static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype,
858 u32 savewin, uint *origidx, void *regs);
859static void ai_nvram_process(struct si_info *sii, char *pvars);
860
861/* dev path concatenation util */
862static char *ai_devpathvar(struct si_pub *sih, char *var, int len,
863 const char *name);
864static bool _ai_clkctl_cc(struct si_info *sii, uint mode);
865static bool ai_ispcie(struct si_info *sii);
866
867/* global variable to indicate reservation/release of gpio's */
868static u32 ai_gpioreservation;
869
870/*
871 * Allocate a si handle.
872 * devid - pci device id (used to determine chip#)
873 * osh - opaque OS handle
874 * regs - virtual address of initial core registers
875 * bustype - pci/sb/sdio/etc
876 * vars - pointer to a pointer area for "environment" variables
877 * varsz - pointer to int to return the size of the vars
878 */
879struct si_pub *ai_attach(void *regs, uint bustype,
880 void *sdh, char **vars, uint *varsz)
881{
882 struct si_info *sii;
883
884 /* alloc struct si_info */
885 sii = kmalloc(sizeof(struct si_info), GFP_ATOMIC);
886 if (sii == NULL) {
887 SI_ERROR(("si_attach: malloc failed!\n"));
888 return NULL;
889 }
890
891 if (ai_doattach(sii, regs, bustype, sdh, vars, varsz) ==
892 NULL) {
893 kfree(sii);
894 return NULL;
895 }
896 sii->vars = vars ? *vars : NULL;
897 sii->varsz = varsz ? *varsz : 0;
898
899 return (struct si_pub *) sii;
900}
901
902/* global kernel resource */
903static struct si_info ksii;
904
905static bool ai_buscore_prep(struct si_info *sii, uint bustype)
906{
907 /* kludge to enable the clock on the 4306 which lacks a slowclock */
908 if (bustype == PCI_BUS && !ai_ispcie(sii))
909 ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
910 return true;
911}
912
913static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype,
914 u32 savewin, uint *origidx, void *regs)
915{
916 bool pci, pcie;
917 uint i;
918 uint pciidx, pcieidx, pcirev, pcierev;
919
920 cc = ai_setcoreidx(&sii->pub, SI_CC_IDX);
921
922 /* get chipcommon rev */
923 sii->pub.ccrev = (int)ai_corerev(&sii->pub);
924
925 /* get chipcommon chipstatus */
926 if (sii->pub.ccrev >= 11)
927 sii->pub.chipst = R_REG(&cc->chipstatus);
928
929 /* get chipcommon capabilites */
930 sii->pub.cccaps = R_REG(&cc->capabilities);
931 /* get chipcommon extended capabilities */
932
933 if (sii->pub.ccrev >= 35)
934 sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
935
936 /* get pmu rev and caps */
937 if (sii->pub.cccaps & CC_CAP_PMU) {
938 sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
939 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
940 }
941
942 /* figure out bus/orignal core idx */
943 sii->pub.buscoretype = NODEV_CORE_ID;
944 sii->pub.buscorerev = NOREV;
945 sii->pub.buscoreidx = BADIDX;
946
947 pci = pcie = false;
948 pcirev = pcierev = NOREV;
949 pciidx = pcieidx = BADIDX;
950
951 for (i = 0; i < sii->numcores; i++) {
952 uint cid, crev;
953
954 ai_setcoreidx(&sii->pub, i);
955 cid = ai_coreid(&sii->pub);
956 crev = ai_corerev(&sii->pub);
957
958 /* Display cores found */
959 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
960 i, cid, crev, sii->coresba[i], sii->regs[i]));
961
962 if (bustype == PCI_BUS) {
963 if (cid == PCI_CORE_ID) {
964 pciidx = i;
965 pcirev = crev;
966 pci = true;
967 } else if (cid == PCIE_CORE_ID) {
968 pcieidx = i;
969 pcierev = crev;
970 pcie = true;
971 }
972 }
973
974 /* find the core idx before entering this func. */
975 if ((savewin && (savewin == sii->coresba[i])) ||
976 (regs == sii->regs[i]))
977 *origidx = i;
978 }
979
980 if (pci && pcie) {
981 if (ai_ispcie(sii))
982 pci = false;
983 else
984 pcie = false;
985 }
986 if (pci) {
987 sii->pub.buscoretype = PCI_CORE_ID;
988 sii->pub.buscorerev = pcirev;
989 sii->pub.buscoreidx = pciidx;
990 } else if (pcie) {
991 sii->pub.buscoretype = PCIE_CORE_ID;
992 sii->pub.buscorerev = pcierev;
993 sii->pub.buscoreidx = pcieidx;
994 }
995
996 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
997 sii->pub.buscoretype, sii->pub.buscorerev));
998
999 /* fixup necessary chip/core configurations */
1000 if (sii->pub.bustype == PCI_BUS) {
1001 if (SI_FAST(sii)) {
1002 if (!sii->pch) {
1003 sii->pch = (void *)pcicore_init(
1004 &sii->pub, sii->pbus,
1005 (void *)PCIEREGS(sii));
1006 if (sii->pch == NULL)
1007 return false;
1008 }
1009 }
1010 if (ai_pci_fixcfg(&sii->pub)) {
1011 SI_ERROR(("si_doattach: si_pci_fixcfg failed\n"));
1012 return false;
1013 }
1014 }
1015
1016 /* return to the original core */
1017 ai_setcoreidx(&sii->pub, *origidx);
1018
1019 return true;
1020}
1021
1022static __used void ai_nvram_process(struct si_info *sii, char *pvars)
1023{
1024 uint w = 0;
1025
1026 /* get boardtype and boardrev */
1027 switch (sii->pub.bustype) {
1028 case PCI_BUS:
1029 /* do a pci config read to get subsystem id and subvendor id */
1030 pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w);
1031 /* Let nvram variables override subsystem Vend/ID */
1032 sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub,
1033 "boardvendor");
1034 if (sii->pub.boardvendor == 0)
1035 sii->pub.boardvendor = w & 0xffff;
1036 else
1037 SI_ERROR(("Overriding boardvendor: 0x%x instead of "
1038 "0x%x\n", sii->pub.boardvendor, w & 0xffff));
1039 sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub,
1040 "boardtype");
1041 if (sii->pub.boardtype == 0)
1042 sii->pub.boardtype = (w >> 16) & 0xffff;
1043 else
1044 SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n"
1045 , sii->pub.boardtype, (w >> 16) & 0xffff));
1046 break;
1047
1048 sii->pub.boardvendor = getintvar(pvars, "manfid");
1049 sii->pub.boardtype = getintvar(pvars, "prodid");
1050 break;
1051
1052 case SI_BUS:
1053 case JTAG_BUS:
1054 sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM;
1055 sii->pub.boardtype = getintvar(pvars, "prodid");
1056 if (pvars == NULL || (sii->pub.boardtype == 0)) {
1057 sii->pub.boardtype = getintvar(NULL, "boardtype");
1058 if (sii->pub.boardtype == 0)
1059 sii->pub.boardtype = 0xffff;
1060 }
1061 break;
1062 }
1063
1064 if (sii->pub.boardtype == 0) {
1065 SI_ERROR(("si_doattach: unknown board type\n"));
1066 }
1067
1068 sii->pub.boardflags = getintvar(pvars, "boardflags");
1069}
1070
1071static struct si_info *ai_doattach(struct si_info *sii,
1072 void *regs, uint bustype, void *pbus,
1073 char **vars, uint *varsz)
1074{
1075 struct si_pub *sih = &sii->pub;
1076 u32 w, savewin;
1077 chipcregs_t *cc;
1078 char *pvars = NULL;
1079 uint socitype;
1080 uint origidx;
1081
1082 memset((unsigned char *) sii, 0, sizeof(struct si_info));
1083
1084 savewin = 0;
1085
1086 sih->buscoreidx = BADIDX;
1087
1088 sii->curmap = regs;
1089 sii->pbus = pbus;
1090
1091 /* check to see if we are a si core mimic'ing a pci core */
1092 if (bustype == PCI_BUS) {
1093 pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL, &w);
1094 if (w == 0xffffffff) {
1095 SI_ERROR(("%s: incoming bus is PCI but it's a lie, "
1096 " switching to SI devid:0x%x\n",
1097 __func__, devid));
1098 bustype = SI_BUS;
1099 }
1100 }
1101
1102 /* find Chipcommon address */
1103 if (bustype == PCI_BUS) {
1104 pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
1105 if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
1106 savewin = SI_ENUM_BASE;
1107 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
1108 SI_ENUM_BASE);
1109 cc = (chipcregs_t *) regs;
1110 } else {
1111 cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
1112 }
1113
1114 sih->bustype = bustype;
1115
1116 /* bus/core/clk setup for register access */
1117 if (!ai_buscore_prep(sii, bustype)) {
1118 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
1119 bustype));
1120 return NULL;
1121 }
1122
1123 /*
1124 * ChipID recognition.
1125 * We assume we can read chipid at offset 0 from the regs arg.
1126 * If we add other chiptypes (or if we need to support old sdio
1127 * hosts w/o chipcommon), some way of recognizing them needs to
1128 * be added here.
1129 */
1130 w = R_REG(&cc->chipid);
1131 socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
1132 /* Might as wll fill in chip id rev & pkg */
1133 sih->chip = w & CID_ID_MASK;
1134 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
1135 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
1136
1137 sih->issim = IS_SIM(sih->chippkg);
1138
1139 /* scan for cores */
1140 if (socitype == SOCI_AI) {
1141 SI_MSG(("Found chip type AI (0x%08x)\n", w));
1142 /* pass chipc address instead of original core base */
1143 ai_scan(&sii->pub, (void *)cc);
1144 } else {
1145 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
1146 return NULL;
1147 }
1148 /* no cores found, bail out */
1149 if (sii->numcores == 0) {
1150 SI_ERROR(("si_doattach: could not find any cores\n"));
1151 return NULL;
1152 }
1153 /* bus/core/clk setup */
1154 origidx = SI_CC_IDX;
1155 if (!ai_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
1156 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
1157 goto exit;
1158 }
1159
1160 /* Init nvram from sprom/otp if they exist */
1161 if (srom_var_init
1162 (&sii->pub, bustype, regs, vars, varsz)) {
1163 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
1164 goto exit;
1165 }
1166 pvars = vars ? *vars : NULL;
1167 ai_nvram_process(sii, pvars);
1168
1169 /* === NVRAM, clock is ready === */
1170 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1171 W_REG(&cc->gpiopullup, 0);
1172 W_REG(&cc->gpiopulldown, 0);
1173 ai_setcoreidx(sih, origidx);
1174
1175 /* PMU specific initializations */
1176 if (PMUCTL_ENAB(sih)) {
1177 u32 xtalfreq;
1178 si_pmu_init(sih);
1179 si_pmu_chip_init(sih);
1180 xtalfreq = getintvar(pvars, "xtalfreq");
1181 /* If xtalfreq var not available, try to measure it */
1182 if (xtalfreq == 0)
1183 xtalfreq = si_pmu_measure_alpclk(sih);
1184 si_pmu_pll_init(sih, xtalfreq);
1185 si_pmu_res_init(sih);
1186 si_pmu_swreg_init(sih);
1187 }
1188
1189 /* setup the GPIO based LED powersave register */
1190 w = getintvar(pvars, "leddc");
1191 if (w == 0)
1192 w = DEFAULT_GPIOTIMERVAL;
1193 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
1194
1195 if (PCIE(sii)) {
1196 pcicore_attach(sii->pch, pvars, SI_DOATTACH);
1197 }
1198
1199 if (sih->chip == BCM43224_CHIP_ID) {
1200 /*
1201 * enable 12 mA drive strenth for 43224 and
1202 * set chipControl register bit 15
1203 */
1204 if (sih->chiprev == 0) {
1205 SI_MSG(("Applying 43224A0 WARs\n"));
1206 ai_corereg(sih, SI_CC_IDX,
1207 offsetof(chipcregs_t, chipcontrol),
1208 CCTRL43224_GPIO_TOGGLE,
1209 CCTRL43224_GPIO_TOGGLE);
1210 si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
1211 CCTRL_43224A0_12MA_LED_DRIVE);
1212 }
1213 if (sih->chiprev >= 1) {
1214 SI_MSG(("Applying 43224B0+ WARs\n"));
1215 si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
1216 CCTRL_43224B0_12MA_LED_DRIVE);
1217 }
1218 }
1219
1220 if (sih->chip == BCM4313_CHIP_ID) {
1221 /*
1222 * enable 12 mA drive strenth for 4313 and
1223 * set chipControl register bit 1
1224 */
1225 SI_MSG(("Applying 4313 WARs\n"));
1226 si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
1227 CCTRL_4313_12MA_LED_DRIVE);
1228 }
1229
1230 return sii;
1231 exit:
1232 if (sih->bustype == PCI_BUS) {
1233 if (sii->pch)
1234 pcicore_deinit(sii->pch);
1235 sii->pch = NULL;
1236 }
1237
1238 return NULL;
1239}
1240
1241/* may be called with core in reset */
1242void ai_detach(struct si_pub *sih)
1243{
1244 struct si_info *sii;
1245 uint idx;
1246
1247 struct si_pub *si_local = NULL;
1248 memcpy(&si_local, &sih, sizeof(struct si_pub **));
1249
1250 sii = SI_INFO(sih);
1251
1252 if (sii == NULL)
1253 return;
1254
1255 if (sih->bustype == SI_BUS)
1256 for (idx = 0; idx < SI_MAXCORES; idx++)
1257 if (sii->regs[idx]) {
1258 iounmap(sii->regs[idx]);
1259 sii->regs[idx] = NULL;
1260 }
1261
1262 if (sih->bustype == PCI_BUS) {
1263 if (sii->pch)
1264 pcicore_deinit(sii->pch);
1265 sii->pch = NULL;
1266 }
1267
1268 if (sii != &ksii)
1269 kfree(sii);
1270}
1271
1272/* register driver interrupt disabling and restoring callback functions */
1273void
1274ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
1275 void *intrsrestore_fn,
1276 void *intrsenabled_fn, void *intr_arg)
1277{
1278 struct si_info *sii;
1279
1280 sii = SI_INFO(sih);
1281 sii->intr_arg = intr_arg;
1282 sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
1283 sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
1284 sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
1285 /* save current core id. when this function called, the current core
1286 * must be the core which provides driver functions(il, et, wl, etc.)
1287 */
1288 sii->dev_coreid = sii->coreid[sii->curidx];
1289}
1290
1291void ai_deregister_intr_callback(struct si_pub *sih)
1292{
1293 struct si_info *sii;
1294
1295 sii = SI_INFO(sih);
1296 sii->intrsoff_fn = NULL;
1297}
1298
1299uint ai_coreid(struct si_pub *sih)
1300{
1301 struct si_info *sii;
1302
1303 sii = SI_INFO(sih);
1304 return sii->coreid[sii->curidx];
1305}
1306
1307uint ai_coreidx(struct si_pub *sih)
1308{
1309 struct si_info *sii;
1310
1311 sii = SI_INFO(sih);
1312 return sii->curidx;
1313}
1314
1315bool ai_backplane64(struct si_pub *sih)
1316{
1317 return (sih->cccaps & CC_CAP_BKPLN64) != 0;
1318}
1319
1320/* return index of coreid or BADIDX if not found */
1321uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit)
1322{
1323 struct si_info *sii;
1324 uint found;
1325 uint i;
1326
1327 sii = SI_INFO(sih);
1328
1329 found = 0;
1330
1331 for (i = 0; i < sii->numcores; i++)
1332 if (sii->coreid[i] == coreid) {
1333 if (found == coreunit)
1334 return i;
1335 found++;
1336 }
1337
1338 return BADIDX;
1339}
1340
1341/*
1342 * This function changes logical "focus" to the indicated core;
1343 * must be called with interrupts off.
1344 * Moreover, callers should keep interrupts off during switching
1345 * out of and back to d11 core.
1346 */
1347void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit)
1348{
1349 uint idx;
1350
1351 idx = ai_findcoreidx(sih, coreid, coreunit);
1352 if (!GOODIDX(idx))
1353 return NULL;
1354
1355 return ai_setcoreidx(sih, idx);
1356}
1357
1358/* Turn off interrupt as required by ai_setcore, before switch core */
1359void *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx,
1360 uint *intr_val)
1361{
1362 void *cc;
1363 struct si_info *sii;
1364
1365 sii = SI_INFO(sih);
1366
1367 if (SI_FAST(sii)) {
1368 /* Overloading the origidx variable to remember the coreid,
1369 * this works because the core ids cannot be confused with
1370 * core indices.
1371 */
1372 *origidx = coreid;
1373 if (coreid == CC_CORE_ID)
1374 return (void *)CCREGS_FAST(sii);
1375 else if (coreid == sih->buscoretype)
1376 return (void *)PCIEREGS(sii);
1377 }
1378 INTR_OFF(sii, *intr_val);
1379 *origidx = sii->curidx;
1380 cc = ai_setcore(sih, coreid, 0);
1381 return cc;
1382}
1383
1384/* restore coreidx and restore interrupt */
1385void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val)
1386{
1387 struct si_info *sii;
1388
1389 sii = SI_INFO(sih);
1390 if (SI_FAST(sii)
1391 && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
1392 return;
1393
1394 ai_setcoreidx(sih, coreid);
1395 INTR_RESTORE(sii, intr_val);
1396}
1397
1398void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val)
1399{
1400 struct si_info *sii = SI_INFO(sih);
1401 u32 *w = (u32 *) sii->curwrap;
1402 W_REG(w + (offset / 4), val);
1403 return;
1404}
1405
1406/*
1407 * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set
1408 * operation, switch back to the original core, and return the new value.
1409 *
1410 * When using the silicon backplane, no fiddling with interrupts or core
1411 * switches is needed.
1412 *
1413 * Also, when using pci/pcie, we can optimize away the core switching for pci
1414 * registers and (on newer pci cores) chipcommon registers.
1415 */
1416uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
1417 uint val)
1418{
1419 uint origidx = 0;
1420 u32 *r = NULL;
1421 uint w;
1422 uint intr_val = 0;
1423 bool fast = false;
1424 struct si_info *sii;
1425
1426 sii = SI_INFO(sih);
1427
1428 if (coreidx >= SI_MAXCORES)
1429 return 0;
1430
1431 if (sih->bustype == SI_BUS) {
1432 /* If internal bus, we can always get at everything */
1433 fast = true;
1434 /* map if does not exist */
1435 if (!sii->regs[coreidx]) {
1436 sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
1437 SI_CORE_SIZE);
1438 }
1439 r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff);
1440 } else if (sih->bustype == PCI_BUS) {
1441 /*
1442 * If pci/pcie, we can get at pci/pcie regs
1443 * and on newer cores to chipc
1444 */
1445 if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
1446 /* Chipc registers are mapped at 12KB */
1447
1448 fast = true;
1449 r = (u32 *) ((char *)sii->curmap +
1450 PCI_16KB0_CCREGS_OFFSET + regoff);
1451 } else if (sii->pub.buscoreidx == coreidx) {
1452 /*
1453 * pci registers are at either in the last 2KB of
1454 * an 8KB window or, in pcie and pci rev 13 at 8KB
1455 */
1456 fast = true;
1457 if (SI_FAST(sii))
1458 r = (u32 *) ((char *)sii->curmap +
1459 PCI_16KB0_PCIREGS_OFFSET +
1460 regoff);
1461 else
1462 r = (u32 *) ((char *)sii->curmap +
1463 ((regoff >= SBCONFIGOFF) ?
1464 PCI_BAR0_PCISBR_OFFSET :
1465 PCI_BAR0_PCIREGS_OFFSET) +
1466 regoff);
1467 }
1468 }
1469
1470 if (!fast) {
1471 INTR_OFF(sii, intr_val);
1472
1473 /* save current core index */
1474 origidx = ai_coreidx(&sii->pub);
1475
1476 /* switch core */
1477 r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx)
1478 + regoff);
1479 }
1480
1481 /* mask and set */
1482 if (mask || val) {
1483 w = (R_REG(r) & ~mask) | val;
1484 W_REG(r, w);
1485 }
1486
1487 /* readback */
1488 w = R_REG(r);
1489
1490 if (!fast) {
1491 /* restore core index */
1492 if (origidx != coreidx)
1493 ai_setcoreidx(&sii->pub, origidx);
1494
1495 INTR_RESTORE(sii, intr_val);
1496 }
1497
1498 return w;
1499}
1500
1501void ai_core_disable(struct si_pub *sih, u32 bits)
1502{
1503 struct si_info *sii;
1504 u32 dummy;
1505 struct aidmp *ai;
1506
1507 sii = SI_INFO(sih);
1508
1509 ai = sii->curwrap;
1510
1511 /* if core is already in reset, just return */
1512 if (R_REG(&ai->resetctrl) & AIRC_RESET)
1513 return;
1514
1515 W_REG(&ai->ioctrl, bits);
1516 dummy = R_REG(&ai->ioctrl);
1517 udelay(10);
1518
1519 W_REG(&ai->resetctrl, AIRC_RESET);
1520 udelay(1);
1521}
1522
1523/* reset and re-enable a core
1524 * inputs:
1525 * bits - core specific bits that are set during and after reset sequence
1526 * resetbits - core specific bits that are set only during reset sequence
1527 */
1528void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits)
1529{
1530 struct si_info *sii;
1531 struct aidmp *ai;
1532 u32 dummy;
1533
1534 sii = SI_INFO(sih);
1535 ai = sii->curwrap;
1536
1537 /*
1538 * Must do the disable sequence first to work
1539 * for arbitrary current core state.
1540 */
1541 ai_core_disable(sih, (bits | resetbits));
1542
1543 /*
1544 * Now do the initialization sequence.
1545 */
1546 W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
1547 dummy = R_REG(&ai->ioctrl);
1548 W_REG(&ai->resetctrl, 0);
1549 udelay(1);
1550
1551 W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN));
1552 dummy = R_REG(&ai->ioctrl);
1553 udelay(1);
1554}
1555
1556/* return the slow clock source - LPO, XTAL, or PCI */
1557static uint ai_slowclk_src(struct si_info *sii)
1558{
1559 chipcregs_t *cc;
1560 u32 val;
1561
1562 if (sii->pub.ccrev < 6) {
1563 if (sii->pub.bustype == PCI_BUS) {
1564 pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
1565 &val);
1566 if (val & PCI_CFG_GPIO_SCS)
1567 return SCC_SS_PCI;
1568 }
1569 return SCC_SS_XTAL;
1570 } else if (sii->pub.ccrev < 10) {
1571 cc = (chipcregs_t *) ai_setcoreidx(&sii->pub, sii->curidx);
1572 return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
1573 } else /* Insta-clock */
1574 return SCC_SS_XTAL;
1575}
1576
1577/*
1578* return the ILP (slowclock) min or max frequency
1579* precondition: we've established the chip has dynamic clk control
1580*/
1581static uint ai_slowclk_freq(struct si_info *sii, bool max_freq, chipcregs_t *cc)
1582{
1583 u32 slowclk;
1584 uint div;
1585
1586 slowclk = ai_slowclk_src(sii);
1587 if (sii->pub.ccrev < 6) {
1588 if (slowclk == SCC_SS_PCI)
1589 return max_freq ? (PCIMAXFREQ / 64)
1590 : (PCIMINFREQ / 64);
1591 else
1592 return max_freq ? (XTALMAXFREQ / 32)
1593 : (XTALMINFREQ / 32);
1594 } else if (sii->pub.ccrev < 10) {
1595 div = 4 *
1596 (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
1597 SCC_CD_SHIFT) + 1);
1598 if (slowclk == SCC_SS_LPO)
1599 return max_freq ? LPOMAXFREQ : LPOMINFREQ;
1600 else if (slowclk == SCC_SS_XTAL)
1601 return max_freq ? (XTALMAXFREQ / div)
1602 : (XTALMINFREQ / div);
1603 else if (slowclk == SCC_SS_PCI)
1604 return max_freq ? (PCIMAXFREQ / div)
1605 : (PCIMINFREQ / div);
1606 } else {
1607 /* Chipc rev 10 is InstaClock */
1608 div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1609 div = 4 * (div + 1);
1610 return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
1611 }
1612 return 0;
1613}
1614
1615static void ai_clkctl_setdelay(struct si_info *sii, void *chipcregs)
1616{
1617 chipcregs_t *cc = (chipcregs_t *) chipcregs;
1618 uint slowmaxfreq, pll_delay, slowclk;
1619 uint pll_on_delay, fref_sel_delay;
1620
1621 pll_delay = PLL_DELAY;
1622
1623 /*
1624 * If the slow clock is not sourced by the xtal then
1625 * add the xtal_on_delay since the xtal will also be
1626 * powered down by dynamic clk control logic.
1627 */
1628
1629 slowclk = ai_slowclk_src(sii);
1630 if (slowclk != SCC_SS_XTAL)
1631 pll_delay += XTAL_ON_DELAY;
1632
1633 /* Starting with 4318 it is ILP that is used for the delays */
1634 slowmaxfreq =
1635 ai_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
1636
1637 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1638 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1639
1640 W_REG(&cc->pll_on_delay, pll_on_delay);
1641 W_REG(&cc->fref_sel_delay, fref_sel_delay);
1642}
1643
1644/* initialize power control delay registers */
1645void ai_clkctl_init(struct si_pub *sih)
1646{
1647 struct si_info *sii;
1648 uint origidx = 0;
1649 chipcregs_t *cc;
1650 bool fast;
1651
1652 if (!CCCTL_ENAB(sih))
1653 return;
1654
1655 sii = SI_INFO(sih);
1656 fast = SI_FAST(sii);
1657 if (!fast) {
1658 origidx = sii->curidx;
1659 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1660 if (cc == NULL)
1661 return;
1662 } else {
1663 cc = (chipcregs_t *) CCREGS_FAST(sii);
1664 if (cc == NULL)
1665 return;
1666 }
1667
1668 /* set all Instaclk chip ILP to 1 MHz */
1669 if (sih->ccrev >= 10)
1670 SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
1671 (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1672
1673 ai_clkctl_setdelay(sii, (void *)cc);
1674
1675 if (!fast)
1676 ai_setcoreidx(sih, origidx);
1677}
1678
1679/*
1680 * return the value suitable for writing to the
1681 * dot11 core FAST_PWRUP_DELAY register
1682 */
1683u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
1684{
1685 struct si_info *sii;
1686 uint origidx = 0;
1687 chipcregs_t *cc;
1688 uint slowminfreq;
1689 u16 fpdelay;
1690 uint intr_val = 0;
1691 bool fast;
1692
1693 sii = SI_INFO(sih);
1694 if (PMUCTL_ENAB(sih)) {
1695 INTR_OFF(sii, intr_val);
1696 fpdelay = si_pmu_fast_pwrup_delay(sih);
1697 INTR_RESTORE(sii, intr_val);
1698 return fpdelay;
1699 }
1700
1701 if (!CCCTL_ENAB(sih))
1702 return 0;
1703
1704 fast = SI_FAST(sii);
1705 fpdelay = 0;
1706 if (!fast) {
1707 origidx = sii->curidx;
1708 INTR_OFF(sii, intr_val);
1709 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1710 if (cc == NULL)
1711 goto done;
1712 } else {
1713 cc = (chipcregs_t *) CCREGS_FAST(sii);
1714 if (cc == NULL)
1715 goto done;
1716 }
1717
1718 slowminfreq = ai_slowclk_freq(sii, false, cc);
1719 fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
1720 (slowminfreq - 1)) / slowminfreq;
1721
1722 done:
1723 if (!fast) {
1724 ai_setcoreidx(sih, origidx);
1725 INTR_RESTORE(sii, intr_val);
1726 }
1727 return fpdelay;
1728}
1729
1730/* turn primary xtal and/or pll off/on */
1731int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on)
1732{
1733 struct si_info *sii;
1734 u32 in, out, outen;
1735
1736 sii = SI_INFO(sih);
1737
1738 switch (sih->bustype) {
1739
1740 case PCI_BUS:
1741 /* pcie core doesn't have any mapping to control the xtal pu */
1742 if (PCIE(sii))
1743 return -1;
1744
1745 pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
1746 pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
1747 pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
1748
1749 /*
1750 * Avoid glitching the clock if GPRS is already using it.
1751 * We can't actually read the state of the PLLPD so we infer it
1752 * by the value of XTAL_PU which *is* readable via gpioin.
1753 */
1754 if (on && (in & PCI_CFG_GPIO_XTAL))
1755 return 0;
1756
1757 if (what & XTAL)
1758 outen |= PCI_CFG_GPIO_XTAL;
1759 if (what & PLL)
1760 outen |= PCI_CFG_GPIO_PLL;
1761
1762 if (on) {
1763 /* turn primary xtal on */
1764 if (what & XTAL) {
1765 out |= PCI_CFG_GPIO_XTAL;
1766 if (what & PLL)
1767 out |= PCI_CFG_GPIO_PLL;
1768 pci_write_config_dword(sii->pbus,
1769 PCI_GPIO_OUT, out);
1770 pci_write_config_dword(sii->pbus,
1771 PCI_GPIO_OUTEN, outen);
1772 udelay(XTAL_ON_DELAY);
1773 }
1774
1775 /* turn pll on */
1776 if (what & PLL) {
1777 out &= ~PCI_CFG_GPIO_PLL;
1778 pci_write_config_dword(sii->pbus,
1779 PCI_GPIO_OUT, out);
1780 mdelay(2);
1781 }
1782 } else {
1783 if (what & XTAL)
1784 out &= ~PCI_CFG_GPIO_XTAL;
1785 if (what & PLL)
1786 out |= PCI_CFG_GPIO_PLL;
1787 pci_write_config_dword(sii->pbus,
1788 PCI_GPIO_OUT, out);
1789 pci_write_config_dword(sii->pbus,
1790 PCI_GPIO_OUTEN, outen);
1791 }
1792
1793 default:
1794 return -1;
1795 }
1796
1797 return 0;
1798}
1799
1800/*
1801 * clock control policy function throught chipcommon
1802 *
1803 * set dynamic clk control mode (forceslow, forcefast, dynamic)
1804 * returns true if we are forcing fast clock
1805 * this is a wrapper over the next internal function
1806 * to allow flexible policy settings for outside caller
1807 */
1808bool ai_clkctl_cc(struct si_pub *sih, uint mode)
1809{
1810 struct si_info *sii;
1811
1812 sii = SI_INFO(sih);
1813
1814 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1815 if (sih->ccrev < 6)
1816 return false;
1817
1818 if (PCI_FORCEHT(sii))
1819 return mode == CLK_FAST;
1820
1821 return _ai_clkctl_cc(sii, mode);
1822}
1823
1824/* clk control mechanism through chipcommon, no policy checking */
1825static bool _ai_clkctl_cc(struct si_info *sii, uint mode)
1826{
1827 uint origidx = 0;
1828 chipcregs_t *cc;
1829 u32 scc;
1830 uint intr_val = 0;
1831 bool fast = SI_FAST(sii);
1832
1833 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1834 if (sii->pub.ccrev < 6)
1835 return false;
1836
1837 if (!fast) {
1838 INTR_OFF(sii, intr_val);
1839 origidx = sii->curidx;
1840
1841 if ((sii->pub.bustype == SI_BUS) &&
1842 ai_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
1843 (ai_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
1844 goto done;
1845
1846 cc = (chipcregs_t *) ai_setcore(&sii->pub, CC_CORE_ID, 0);
1847 } else {
1848 cc = (chipcregs_t *) CCREGS_FAST(sii);
1849 if (cc == NULL)
1850 goto done;
1851 }
1852
1853 if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
1854 goto done;
1855
1856 switch (mode) {
1857 case CLK_FAST: /* FORCEHT, fast (pll) clock */
1858 if (sii->pub.ccrev < 10) {
1859 /*
1860 * don't forget to force xtal back
1861 * on before we clear SCC_DYN_XTAL..
1862 */
1863 ai_clkctl_xtal(&sii->pub, XTAL, ON);
1864 SET_REG(&cc->slow_clk_ctl,
1865 (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
1866 } else if (sii->pub.ccrev < 20) {
1867 OR_REG(&cc->system_clk_ctl, SYCC_HR);
1868 } else {
1869 OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
1870 }
1871
1872 /* wait for the PLL */
1873 if (PMUCTL_ENAB(&sii->pub)) {
1874 u32 htavail = CCS_HTAVAIL;
1875 SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
1876 == 0), PMU_MAX_TRANSITION_DLY);
1877 } else {
1878 udelay(PLL_DELAY);
1879 }
1880 break;
1881
1882 case CLK_DYNAMIC: /* enable dynamic clock control */
1883 if (sii->pub.ccrev < 10) {
1884 scc = R_REG(&cc->slow_clk_ctl);
1885 scc &= ~(SCC_FS | SCC_IP | SCC_XC);
1886 if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
1887 scc |= SCC_XC;
1888 W_REG(&cc->slow_clk_ctl, scc);
1889
1890 /*
1891 * for dynamic control, we have to
1892 * release our xtal_pu "force on"
1893 */
1894 if (scc & SCC_XC)
1895 ai_clkctl_xtal(&sii->pub, XTAL, OFF);
1896 } else if (sii->pub.ccrev < 20) {
1897 /* Instaclock */
1898 AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
1899 } else {
1900 AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
1901 }
1902 break;
1903
1904 default:
1905 break;
1906 }
1907
1908 done:
1909 if (!fast) {
1910 ai_setcoreidx(&sii->pub, origidx);
1911 INTR_RESTORE(sii, intr_val);
1912 }
1913 return mode == CLK_FAST;
1914}
1915
1916/* Build device path. Support SI, PCI, and JTAG for now. */
1917int ai_devpath(struct si_pub *sih, char *path, int size)
1918{
1919 int slen;
1920
1921 if (!path || size <= 0)
1922 return -1;
1923
1924 switch (sih->bustype) {
1925 case SI_BUS:
1926 case JTAG_BUS:
1927 slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih));
1928 break;
1929 case PCI_BUS:
1930 slen = snprintf(path, (size_t) size, "pci/%u/%u/",
1931 ((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number,
1932 PCI_SLOT(
1933 ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn));
1934 break;
1935
1936 default:
1937 slen = -1;
1938 break;
1939 }
1940
1941 if (slen < 0 || slen >= size) {
1942 path[0] = '\0';
1943 return -1;
1944 }
1945
1946 return 0;
1947}
1948
1949/* Get a variable, but only if it has a devpath prefix */
1950char *ai_getdevpathvar(struct si_pub *sih, const char *name)
1951{
1952 char varname[SI_DEVPATH_BUFSZ + 32];
1953
1954 ai_devpathvar(sih, varname, sizeof(varname), name);
1955
1956 return getvar(NULL, varname);
1957}
1958
1959/* Get a variable, but only if it has a devpath prefix */
1960int ai_getdevpathintvar(struct si_pub *sih, const char *name)
1961{
1962#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
1963 return getintvar(NULL, name);
1964#else
1965 char varname[SI_DEVPATH_BUFSZ + 32];
1966
1967 ai_devpathvar(sih, varname, sizeof(varname), name);
1968
1969 return getintvar(NULL, varname);
1970#endif
1971}
1972
1973char *ai_getnvramflvar(struct si_pub *sih, const char *name)
1974{
1975 return getvar(NULL, name);
1976}
1977
1978/* Concatenate the dev path with a varname into the given 'var' buffer
1979 * and return the 'var' pointer. Nothing is done to the arguments if
1980 * len == 0 or var is NULL, var is still returned. On overflow, the
1981 * first char will be set to '\0'.
1982 */
1983static char *ai_devpathvar(struct si_pub *sih, char *var, int len,
1984 const char *name)
1985{
1986 uint path_len;
1987
1988 if (!var || len <= 0)
1989 return var;
1990
1991 if (ai_devpath(sih, var, len) == 0) {
1992 path_len = strlen(var);
1993
1994 if (strlen(name) + 1 > (uint) (len - path_len))
1995 var[0] = '\0';
1996 else
1997 strncpy(var + path_len, name, len - path_len - 1);
1998 }
1999
2000 return var;
2001}
2002
2003/* return true if PCIE capability exists in the pci config space */
2004static bool ai_ispcie(struct si_info *sii)
2005{
2006 u8 cap_ptr;
2007
2008 if (sii->pub.bustype != PCI_BUS)
2009 return false;
2010
2011 cap_ptr =
2012 pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL,
2013 NULL);
2014 if (!cap_ptr)
2015 return false;
2016
2017 return true;
2018}
2019
2020bool ai_pci_war16165(struct si_pub *sih)
2021{
2022 struct si_info *sii;
2023
2024 sii = SI_INFO(sih);
2025
2026 return PCI(sii) && (sih->buscorerev <= 10);
2027}
2028
2029void ai_pci_up(struct si_pub *sih)
2030{
2031 struct si_info *sii;
2032
2033 sii = SI_INFO(sih);
2034
2035 /* if not pci bus, we're done */
2036 if (sih->bustype != PCI_BUS)
2037 return;
2038
2039 if (PCI_FORCEHT(sii))
2040 _ai_clkctl_cc(sii, CLK_FAST);
2041
2042 if (PCIE(sii))
2043 pcicore_up(sii->pch, SI_PCIUP);
2044
2045}
2046
2047/* Unconfigure and/or apply various WARs when system is going to sleep mode */
2048void ai_pci_sleep(struct si_pub *sih)
2049{
2050 struct si_info *sii;
2051
2052 sii = SI_INFO(sih);
2053
2054 pcicore_sleep(sii->pch);
2055}
2056
2057/* Unconfigure and/or apply various WARs when going down */
2058void ai_pci_down(struct si_pub *sih)
2059{
2060 struct si_info *sii;
2061
2062 sii = SI_INFO(sih);
2063
2064 /* if not pci bus, we're done */
2065 if (sih->bustype != PCI_BUS)
2066 return;
2067
2068 /* release FORCEHT since chip is going to "down" state */
2069 if (PCI_FORCEHT(sii))
2070 _ai_clkctl_cc(sii, CLK_DYNAMIC);
2071
2072 pcicore_down(sii->pch, SI_PCIDOWN);
2073}
2074
2075/*
2076 * Configure the pci core for pci client (NIC) action
2077 * coremask is the bitvec of cores by index to be enabled.
2078 */
2079void ai_pci_setup(struct si_pub *sih, uint coremask)
2080{
2081 struct si_info *sii;
2082 void *regs = NULL;
2083 u32 siflag = 0, w;
2084 uint idx = 0;
2085
2086 sii = SI_INFO(sih);
2087
2088 if (sii->pub.bustype != PCI_BUS)
2089 return;
2090
2091 if (PCI(sii)) {
2092 /* get current core index */
2093 idx = sii->curidx;
2094
2095 /* we interrupt on this backplane flag number */
2096 siflag = ai_flag(sih);
2097
2098 /* switch over to pci core */
2099 regs = ai_setcoreidx(sih, sii->pub.buscoreidx);
2100 }
2101
2102 /*
2103 * Enable sb->pci interrupts. Assume
2104 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
2105 */
2106 if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
2107 /* pci config write to set this core bit in PCIIntMask */
2108 pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
2109 w |= (coremask << PCI_SBIM_SHIFT);
2110 pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
2111 } else {
2112 /* set sbintvec bit for our flag number */
2113 ai_setint(sih, siflag);
2114 }
2115
2116 if (PCI(sii)) {
2117 pcicore_pci_setup(sii->pch, regs);
2118
2119 /* switch back to previous core */
2120 ai_setcoreidx(sih, idx);
2121 }
2122}
2123
2124/*
2125 * Fixup SROMless PCI device's configuration.
2126 * The current core may be changed upon return.
2127 */
2128int ai_pci_fixcfg(struct si_pub *sih)
2129{
2130 uint origidx;
2131 void *regs = NULL;
2132
2133 struct si_info *sii = SI_INFO(sih);
2134
2135 /* Fixup PI in SROM shadow area to enable the correct PCI core access */
2136 /* save the current index */
2137 origidx = ai_coreidx(&sii->pub);
2138
2139 /* check 'pi' is correct and fix it if not */
2140 regs = ai_setcore(&sii->pub, sii->pub.buscoretype, 0);
2141 pcicore_fixcfg(sii->pch, regs);
2142
2143 /* restore the original index */
2144 ai_setcoreidx(&sii->pub, origidx);
2145
2146 pcicore_hwup(sii->pch);
2147 return 0;
2148}
2149
2150/* mask&set gpiocontrol bits */
2151u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority)
2152{
2153 uint regoff;
2154
2155 regoff = 0;
2156
2157 /* gpios could be shared on router platforms
2158 * ignore reservation if it's high priority (e.g., test apps)
2159 */
2160 if ((priority != GPIO_HI_PRIORITY) &&
2161 (sih->bustype == SI_BUS) && (val || mask)) {
2162 mask = priority ? (ai_gpioreservation & mask) :
2163 ((ai_gpioreservation | mask) & ~(ai_gpioreservation));
2164 val &= mask;
2165 }
2166
2167 regoff = offsetof(chipcregs_t, gpiocontrol);
2168 return ai_corereg(sih, SI_CC_IDX, regoff, mask, val);
2169}
2170
2171void ai_chipcontrl_epa4331(struct si_pub *sih, bool on)
2172{
2173 struct si_info *sii;
2174 chipcregs_t *cc;
2175 uint origidx;
2176 u32 val;
2177
2178 sii = SI_INFO(sih);
2179 origidx = ai_coreidx(sih);
2180
2181 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
2182
2183 val = R_REG(&cc->chipcontrol);
2184
2185 if (on) {
2186 if (sih->chippkg == 9 || sih->chippkg == 0xb) {
2187 /* Ext PA Controls for 4331 12x9 Package */
2188 W_REG(&cc->chipcontrol, val |
2189 (CCTRL4331_EXTPA_EN |
2190 CCTRL4331_EXTPA_ON_GPIO2_5));
2191 } else {
2192 /* Ext PA Controls for 4331 12x12 Package */
2193 W_REG(&cc->chipcontrol,
2194 val | (CCTRL4331_EXTPA_EN));
2195 }
2196 } else {
2197 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
2198 W_REG(&cc->chipcontrol, val);
2199 }
2200
2201 ai_setcoreidx(sih, origidx);
2202}
2203
2204/* Enable BT-COEX & Ex-PA for 4313 */
2205void ai_epa_4313war(struct si_pub *sih)
2206{
2207 struct si_info *sii;
2208 chipcregs_t *cc;
2209 uint origidx;
2210
2211 sii = SI_INFO(sih);
2212 origidx = ai_coreidx(sih);
2213
2214 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
2215
2216 /* EPA Fix */
2217 W_REG(&cc->gpiocontrol,
2218 R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
2219
2220 ai_setcoreidx(sih, origidx);
2221}
2222
2223/* check if the device is removed */
2224bool ai_deviceremoved(struct si_pub *sih)
2225{
2226 u32 w;
2227 struct si_info *sii;
2228
2229 sii = SI_INFO(sih);
2230
2231 switch (sih->bustype) {
2232 case PCI_BUS:
2233 pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w);
2234 if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
2235 return true;
2236 break;
2237 }
2238 return false;
2239}
2240
2241bool ai_is_sprom_available(struct si_pub *sih)
2242{
2243 if (sih->ccrev >= 31) {
2244 struct si_info *sii;
2245 uint origidx;
2246 chipcregs_t *cc;
2247 u32 sromctrl;
2248
2249 if ((sih->cccaps & CC_CAP_SROM) == 0)
2250 return false;
2251
2252 sii = SI_INFO(sih);
2253 origidx = sii->curidx;
2254 cc = ai_setcoreidx(sih, SI_CC_IDX);
2255 sromctrl = R_REG(&cc->sromcontrol);
2256 ai_setcoreidx(sih, origidx);
2257 return sromctrl & SRC_PRESENT;
2258 }
2259
2260 switch (sih->chip) {
2261 case BCM4313_CHIP_ID:
2262 return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
2263 default:
2264 return true;
2265 }
2266}
2267
2268bool ai_is_otp_disabled(struct si_pub *sih)
2269{
2270 switch (sih->chip) {
2271 case BCM4313_CHIP_ID:
2272 return (sih->chipst & CST4313_OTP_PRESENT) == 0;
2273 /* These chips always have their OTP on */
2274 case BCM43224_CHIP_ID:
2275 case BCM43225_CHIP_ID:
2276 default:
2277 return false;
2278 }
2279}
diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.h b/drivers/staging/brcm80211/brcmsmac/aiutils.h
new file mode 100644
index 00000000000..e245c278beb
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/aiutils.h
@@ -0,0 +1,584 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_AIUTILS_H_
18#define _BRCM_AIUTILS_H_
19
20#include "types.h"
21
22/*
23 * SOC Interconnect Address Map.
24 * All regions may not exist on all chips.
25 */
26/* Physical SDRAM */
27#define SI_SDRAM_BASE 0x00000000
28/* Host Mode sb2pcitranslation0 (64 MB) */
29#define SI_PCI_MEM 0x08000000
30#define SI_PCI_MEM_SZ (64 * 1024 * 1024)
31/* Host Mode sb2pcitranslation1 (64 MB) */
32#define SI_PCI_CFG 0x0c000000
33/* Byteswapped Physical SDRAM */
34#define SI_SDRAM_SWAPPED 0x10000000
35/* Region 2 for sdram (512 MB) */
36#define SI_SDRAM_R2 0x80000000
37
38#ifdef SI_ENUM_BASE_VARIABLE
39#define SI_ENUM_BASE (sii->pub.si_enum_base)
40#else
41#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
42#endif /* SI_ENUM_BASE_VARIABLE */
43
44/* Wrapper space base */
45#define SI_WRAP_BASE 0x18100000
46/* each core gets 4Kbytes for registers */
47#define SI_CORE_SIZE 0x1000
48/*
49 * Max cores (this is arbitrary, for software
50 * convenience and could be changed if we
51 * make any larger chips
52 */
53#define SI_MAXCORES 16
54
55/* On-chip RAM on chips that also have DDR */
56#define SI_FASTRAM 0x19000000
57#define SI_FASTRAM_SWAPPED 0x19800000
58
59/* Flash Region 2 (region 1 shadowed here) */
60#define SI_FLASH2 0x1c000000
61/* Size of Flash Region 2 */
62#define SI_FLASH2_SZ 0x02000000
63/* ARM Cortex-M3 ROM */
64#define SI_ARMCM3_ROM 0x1e000000
65/* MIPS Flash Region 1 */
66#define SI_FLASH1 0x1fc00000
67/* MIPS Size of Flash Region 1 */
68#define SI_FLASH1_SZ 0x00400000
69/* ARM7TDMI-S ROM */
70#define SI_ARM7S_ROM 0x20000000
71/* ARM Cortex-M3 SRAM Region 2 */
72#define SI_ARMCM3_SRAM2 0x60000000
73/* ARM7TDMI-S SRAM Region 2 */
74#define SI_ARM7S_SRAM2 0x80000000
75/* ARM Flash Region 1 */
76#define SI_ARM_FLASH1 0xffff0000
77/* ARM Size of Flash Region 1 */
78#define SI_ARM_FLASH1_SZ 0x00010000
79
80/* Client Mode sb2pcitranslation2 (1 GB) */
81#define SI_PCI_DMA 0x40000000
82/* Client Mode sb2pcitranslation2 (1 GB) */
83#define SI_PCI_DMA2 0x80000000
84/* Client Mode sb2pcitranslation2 size in bytes */
85#define SI_PCI_DMA_SZ 0x40000000
86/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
87#define SI_PCIE_DMA_L32 0x00000000
88/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
89#define SI_PCIE_DMA_H32 0x80000000
90
91/* core codes */
92#define NODEV_CORE_ID 0x700 /* Invalid coreid */
93#define CC_CORE_ID 0x800 /* chipcommon core */
94#define ILINE20_CORE_ID 0x801 /* iline20 core */
95#define SRAM_CORE_ID 0x802 /* sram core */
96#define SDRAM_CORE_ID 0x803 /* sdram core */
97#define PCI_CORE_ID 0x804 /* pci core */
98#define MIPS_CORE_ID 0x805 /* mips core */
99#define ENET_CORE_ID 0x806 /* enet mac core */
100#define CODEC_CORE_ID 0x807 /* v90 codec core */
101#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
102#define ADSL_CORE_ID 0x809 /* ADSL core */
103#define ILINE100_CORE_ID 0x80a /* iline100 core */
104#define IPSEC_CORE_ID 0x80b /* ipsec core */
105#define UTOPIA_CORE_ID 0x80c /* utopia core */
106#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
107#define SOCRAM_CORE_ID 0x80e /* internal memory core */
108#define MEMC_CORE_ID 0x80f /* memc sdram core */
109#define OFDM_CORE_ID 0x810 /* OFDM phy core */
110#define EXTIF_CORE_ID 0x811 /* external interface core */
111#define D11_CORE_ID 0x812 /* 802.11 MAC core */
112#define APHY_CORE_ID 0x813 /* 802.11a phy core */
113#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
114#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
115#define MIPS33_CORE_ID 0x816 /* mips3302 core */
116#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
117#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
118#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
119#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
120#define SDIOH_CORE_ID 0x81b /* sdio host core */
121#define ROBO_CORE_ID 0x81c /* roboswitch core */
122#define ATA100_CORE_ID 0x81d /* parallel ATA core */
123#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
124#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
125#define PCIE_CORE_ID 0x820 /* pci express core */
126#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
127#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
128#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
129#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
130#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
131#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
132#define PMU_CORE_ID 0x827 /* PMU core */
133#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
134#define SDIOD_CORE_ID 0x829 /* SDIO device core */
135#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
136#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
137#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
138#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
139#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
140#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
141#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
142#define SC_CORE_ID 0x831 /* shared common core */
143#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
144#define SPIH_CORE_ID 0x833 /* SPI host core */
145#define I2S_CORE_ID 0x834 /* I2S core */
146#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
147#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
148#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
149#define DEF_AI_COMP 0xfff /* Default component, in ai chips it
150 * maps all unused address ranges
151 */
152
153/* chipcommon being the first core: */
154#define SI_CC_IDX 0
155
156/* SOC Interconnect types (aka chip types) */
157#define SOCI_AI 1
158
159/* Common core control flags */
160#define SICF_BIST_EN 0x8000
161#define SICF_PME_EN 0x4000
162#define SICF_CORE_BITS 0x3ffc
163#define SICF_FGC 0x0002
164#define SICF_CLOCK_EN 0x0001
165
166/* Common core status flags */
167#define SISF_BIST_DONE 0x8000
168#define SISF_BIST_ERROR 0x4000
169#define SISF_GATED_CLK 0x2000
170#define SISF_DMA64 0x1000
171#define SISF_CORE_BITS 0x0fff
172
173/* A register that is common to all cores to
174 * communicate w/PMU regarding clock control.
175 */
176#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */
177
178/* clk_ctl_st register */
179#define CCS_FORCEALP 0x00000001 /* force ALP request */
180#define CCS_FORCEHT 0x00000002 /* force HT request */
181#define CCS_FORCEILP 0x00000004 /* force ILP request */
182#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
183#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
184#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
185#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */
186#define CCS_ERSRC_REQ_SHIFT 8
187#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
188#define CCS_HTAVAIL 0x00020000 /* HT is available */
189#define CCS_BP_ON_APL 0x00040000 /* RO: running on ALP clock */
190#define CCS_BP_ON_HT 0x00080000 /* RO: running on HT clock */
191#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */
192#define CCS_ERSRC_STS_SHIFT 24
193
194/* HT avail in chipc and pcmcia on 4328a0 */
195#define CCS0_HTAVAIL 0x00010000
196/* ALP avail in chipc and pcmcia on 4328a0 */
197#define CCS0_ALPAVAIL 0x00020000
198
199/* Not really related to SOC Interconnect, but a couple of software
200 * conventions for the use the flash space:
201 */
202
203/* Minumum amount of flash we support */
204#define FLASH_MIN 0x00020000 /* Minimum flash size */
205
206/* A boot/binary may have an embedded block that describes its size */
207#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */
208#define BISZ_MAGIC 0x4249535a /* Marked with value: 'BISZ' */
209#define BISZ_MAGIC_IDX 0 /* Word 0: magic */
210#define BISZ_TXTST_IDX 1 /* 1: text start */
211#define BISZ_TXTEND_IDX 2 /* 2: text end */
212#define BISZ_DATAST_IDX 3 /* 3: data start */
213#define BISZ_DATAEND_IDX 4 /* 4: data end */
214#define BISZ_BSSST_IDX 5 /* 5: bss start */
215#define BISZ_BSSEND_IDX 6 /* 6: bss end */
216#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */
217
218#define CC_SROM_OTP 0x800 /* SROM/OTP address space */
219
220/* gpiotimerval */
221#define GPIO_ONTIME_SHIFT 16
222
223/* Fields in clkdiv */
224#define CLKD_OTP 0x000f0000
225#define CLKD_OTP_SHIFT 16
226
227/* When Srom support present, fields in sromcontrol */
228#define SRC_START 0x80000000
229#define SRC_BUSY 0x80000000
230#define SRC_OPCODE 0x60000000
231#define SRC_OP_READ 0x00000000
232#define SRC_OP_WRITE 0x20000000
233#define SRC_OP_WRDIS 0x40000000
234#define SRC_OP_WREN 0x60000000
235#define SRC_OTPSEL 0x00000010
236#define SRC_LOCK 0x00000008
237#define SRC_SIZE_MASK 0x00000006
238#define SRC_SIZE_1K 0x00000000
239#define SRC_SIZE_4K 0x00000002
240#define SRC_SIZE_16K 0x00000004
241#define SRC_SIZE_SHIFT 1
242#define SRC_PRESENT 0x00000001
243
244/* 4330 chip-specific ChipStatus register bits */
245#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */
246#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */
247#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */
248#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */
249#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */
250#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */
251#define CST4330_OTP_PRESENT 0x00000010
252#define CST4330_LPO_AUTODET_EN 0x00000020
253#define CST4330_ARMREMAP_0 0x00000040
254#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */
255#define CST4330_ILPDIV_EN 0x00000100
256#define CST4330_LPO_SEL 0x00000200
257#define CST4330_RES_INIT_MODE_SHIFT 10
258#define CST4330_RES_INIT_MODE_MASK 0x00000c00
259#define CST4330_CBUCK_MODE_SHIFT 12
260#define CST4330_CBUCK_MODE_MASK 0x00003000
261#define CST4330_CBUCK_POWER_OK 0x00004000
262#define CST4330_BB_PLL_LOCKED 0x00008000
263
264/* Package IDs */
265#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */
266#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */
267#define BCM4717_PKG_ID 9 /* 4717 package id */
268#define BCM4718_PKG_ID 10 /* 4718 package id */
269#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
270#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
271#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */
272
273/* these are router chips */
274#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */
275#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */
276#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */
277#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */
278#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */
279
280
281#define SI_INFO(sih) ((struct si_info *)sih)
282
283#define GOODCOREADDR(x, b) \
284 (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
285 IS_ALIGNED((x), SI_CORE_SIZE))
286#define GOODREGS(regs) \
287 ((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE))
288#define BADCOREADDR 0
289#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES)
290#define NOREV -1 /* Invalid rev */
291
292/* Newer chips can access PCI/PCIE and CC core without requiring to change
293 * PCI BAR0 WIN
294 */
295#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \
296 (((si)->pub.buscoretype == PCI_CORE_ID) && \
297 (si)->pub.buscorerev >= 13))
298
299#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET))
300#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
301
302/*
303 * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts
304 * before after core switching to avoid invalid register accesss inside ISR.
305 */
306#define INTR_OFF(si, intr_val) \
307 if ((si)->intrsoff_fn && \
308 (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
309 intr_val = (*(si)->intrsoff_fn)((si)->intr_arg)
310#define INTR_RESTORE(si, intr_val) \
311 if ((si)->intrsrestore_fn && \
312 (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
313 (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val)
314
315/* dynamic clock control defines */
316#define LPOMINFREQ 25000 /* low power oscillator min */
317#define LPOMAXFREQ 43000 /* low power oscillator max */
318#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
319#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
320#define PCIMINFREQ 25000000 /* 25 MHz */
321#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
322
323#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
324#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
325
326#define PCI(si) (((si)->pub.bustype == PCI_BUS) && \
327 ((si)->pub.buscoretype == PCI_CORE_ID))
328#define PCIE(si) (((si)->pub.bustype == PCI_BUS) && \
329 ((si)->pub.buscoretype == PCIE_CORE_ID))
330#define PCI_FORCEHT(si) \
331 (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))
332
333/* GPIO Based LED powersave defines */
334#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
335#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
336
337#ifndef DEFAULT_GPIOTIMERVAL
338#define DEFAULT_GPIOTIMERVAL \
339 ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
340#endif
341
342/*
343 * Data structure to export all chip specific common variables
344 * public (read-only) portion of aiutils handle returned by si_attach()
345 */
346struct si_pub {
347 uint bustype; /* SI_BUS, PCI_BUS */
348 uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
349 uint buscorerev; /* buscore rev */
350 uint buscoreidx; /* buscore index */
351 int ccrev; /* chip common core rev */
352 u32 cccaps; /* chip common capabilities */
353 u32 cccaps_ext; /* chip common capabilities extension */
354 int pmurev; /* pmu core rev */
355 u32 pmucaps; /* pmu capabilities */
356 uint boardtype; /* board type */
357 uint boardvendor; /* board vendor */
358 uint boardflags; /* board flags */
359 uint boardflags2; /* board flags2 */
360 uint chip; /* chip number */
361 uint chiprev; /* chip revision */
362 uint chippkg; /* chip package option */
363 u32 chipst; /* chip status */
364 bool issim; /* chip is in simulation or emulation */
365 uint socirev; /* SOC interconnect rev */
366 bool pci_pr32414;
367
368};
369
370/*
371 * Many of the routines below take an 'sih' handle as their first arg.
372 * Allocate this by calling si_attach(). Free it by calling si_detach().
373 * At any one time, the sih is logically focused on one particular si core
374 * (the "current core").
375 * Use si_setcore() or si_setcoreidx() to change the association to another core
376 */
377
378#define BADIDX (SI_MAXCORES + 1)
379
380/* clkctl xtal what flags */
381#define XTAL 0x1 /* primary crystal oscillator (2050) */
382#define PLL 0x2 /* main chip pll */
383
384/* clkctl clk mode */
385#define CLK_FAST 0 /* force fast (pll) clock */
386#define CLK_DYNAMIC 2 /* enable dynamic clock control */
387
388/* GPIO usage priorities */
389#define GPIO_DRV_PRIORITY 0 /* Driver */
390#define GPIO_APP_PRIORITY 1 /* Application */
391#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO
392 * reservation
393 */
394
395/* GPIO pull up/down */
396#define GPIO_PULLUP 0
397#define GPIO_PULLDN 1
398
399/* GPIO event regtype */
400#define GPIO_REGEVT 0 /* GPIO register event */
401#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
402#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
403
404/* device path */
405#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
406
407/* SI routine enumeration: to be used by update function with multiple hooks */
408#define SI_DOATTACH 1
409#define SI_PCIDOWN 2
410#define SI_PCIUP 3
411
412/* PMU clock/power control */
413#if defined(BCMPMUCTL)
414#define PMUCTL_ENAB(sih) (BCMPMUCTL)
415#else
416#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU)
417#endif
418
419/* chipcommon clock/power control (exclusive with PMU's) */
420#if defined(BCMPMUCTL) && BCMPMUCTL
421#define CCCTL_ENAB(sih) (0)
422#define CCPLL_ENAB(sih) (0)
423#else
424#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL)
425#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK)
426#endif
427
428typedef void (*gpio_handler_t) (u32 stat, void *arg);
429
430/* External PA enable mask */
431#define GPIO_CTRL_EPA_EN_MASK 0x40
432
433#define SI_ERROR(args)
434
435#ifdef BCMDBG
436#define SI_MSG(args) printk args
437#else
438#define SI_MSG(args)
439#endif /* BCMDBG */
440
441/* Define SI_VMSG to printf for verbose debugging, but don't check it in */
442#define SI_VMSG(args)
443
444#define IS_SIM(chippkg) \
445 ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
446
447typedef u32(*si_intrsoff_t) (void *intr_arg);
448typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg);
449typedef bool(*si_intrsenabled_t) (void *intr_arg);
450
451struct gpioh_item {
452 void *arg;
453 bool level;
454 gpio_handler_t handler;
455 u32 event;
456 struct gpioh_item *next;
457};
458
459/* misc si info needed by some of the routines */
460struct si_info {
461 struct si_pub pub; /* back plane public state (must be first) */
462 void *pbus; /* handle to bus (pci/sdio/..) */
463 uint dev_coreid; /* the core provides driver functions */
464 void *intr_arg; /* interrupt callback function arg */
465 si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */
466 si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
467 si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
468
469 void *pch; /* PCI/E core handle */
470
471 char *vars;
472 uint varsz;
473
474 void *curmap; /* current regs va */
475 void *regs[SI_MAXCORES]; /* other regs va */
476
477 uint curidx; /* current core index */
478 uint numcores; /* # discovered cores */
479 uint coreid[SI_MAXCORES]; /* id of each core */
480 u32 coresba[SI_MAXCORES]; /* backplane address of each core */
481 void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
482 u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
483 u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
484 u32 coresba2_size[SI_MAXCORES]; /* second address space size */
485
486 void *curwrap; /* current wrapper va */
487 void *wrappers[SI_MAXCORES]; /* other cores wrapper va */
488 u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */
489
490 u32 cia[SI_MAXCORES]; /* erom cia entry for each core */
491 u32 cib[SI_MAXCORES]; /* erom cia entry for each core */
492 u32 oob_router; /* oob router registers for axi */
493};
494
495/* AMBA Interconnect exported externs */
496extern void ai_scan(struct si_pub *sih, void *regs);
497
498extern uint ai_flag(struct si_pub *sih);
499extern void ai_setint(struct si_pub *sih, int siflag);
500extern uint ai_coreidx(struct si_pub *sih);
501extern uint ai_corevendor(struct si_pub *sih);
502extern uint ai_corerev(struct si_pub *sih);
503extern bool ai_iscoreup(struct si_pub *sih);
504extern void *ai_setcoreidx(struct si_pub *sih, uint coreidx);
505extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
506extern void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val);
507extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
508extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
509 uint val);
510extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
511extern void ai_core_disable(struct si_pub *sih, u32 bits);
512extern int ai_numaddrspaces(struct si_pub *sih);
513extern u32 ai_addrspace(struct si_pub *sih, uint asidx);
514extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx);
515extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val);
516
517/* === exported functions === */
518extern struct si_pub *ai_attach(void *regs, uint bustype,
519 void *sdh, char **vars, uint *varsz);
520
521extern void ai_detach(struct si_pub *sih);
522extern bool ai_pci_war16165(struct si_pub *sih);
523
524extern uint ai_coreid(struct si_pub *sih);
525extern uint ai_corerev(struct si_pub *sih);
526extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
527 uint val);
528extern void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val);
529extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
530extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
531extern bool ai_iscoreup(struct si_pub *sih);
532extern uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit);
533extern void *ai_setcoreidx(struct si_pub *sih, uint coreidx);
534extern void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit);
535extern void *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx,
536 uint *intr_val);
537extern void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val);
538extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
539extern void ai_core_disable(struct si_pub *sih, u32 bits);
540extern u32 ai_alp_clock(struct si_pub *sih);
541extern u32 ai_ilp_clock(struct si_pub *sih);
542extern void ai_pci_setup(struct si_pub *sih, uint coremask);
543extern void ai_setint(struct si_pub *sih, int siflag);
544extern bool ai_backplane64(struct si_pub *sih);
545extern void ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
546 void *intrsrestore_fn,
547 void *intrsenabled_fn, void *intr_arg);
548extern void ai_deregister_intr_callback(struct si_pub *sih);
549extern void ai_clkctl_init(struct si_pub *sih);
550extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
551extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
552extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on);
553extern bool ai_deviceremoved(struct si_pub *sih);
554extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val,
555 u8 priority);
556
557/* OTP status */
558extern bool ai_is_otp_disabled(struct si_pub *sih);
559
560/* SPROM availability */
561extern bool ai_is_sprom_available(struct si_pub *sih);
562
563/*
564 * Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
565 * The returned path is NULL terminated and has trailing '/'.
566 * Return 0 on success, nonzero otherwise.
567 */
568extern int ai_devpath(struct si_pub *sih, char *path, int size);
569/* Read variable with prepending the devpath to the name */
570extern char *ai_getdevpathvar(struct si_pub *sih, const char *name);
571extern int ai_getdevpathintvar(struct si_pub *sih, const char *name);
572
573extern void ai_pci_sleep(struct si_pub *sih);
574extern void ai_pci_down(struct si_pub *sih);
575extern void ai_pci_up(struct si_pub *sih);
576extern int ai_pci_fixcfg(struct si_pub *sih);
577
578extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
579/* Enable Ex-PA for 4313 */
580extern void ai_epa_4313war(struct si_pub *sih);
581
582char *ai_getnvramflvar(struct si_pub *sih, const char *name);
583
584#endif /* _BRCM_AIUTILS_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/alloc.c b/drivers/staging/brcm80211/brcmsmac/alloc.c
new file mode 100644
index 00000000000..7f8dd7b396b
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/alloc.c
@@ -0,0 +1,275 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <brcmu_utils.h>
18#include "types.h"
19#include "pub.h"
20#include "main.h"
21#include "alloc.h"
22
23static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit);
24static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg);
25static struct brcms_pub *brcms_c_pub_malloc(uint unit,
26 uint *err, uint devid);
27static void brcms_c_pub_mfree(struct brcms_pub *pub);
28static void brcms_c_tunables_init(struct brcms_tunables *tunables, uint devid);
29
30static void brcms_c_tunables_init(struct brcms_tunables *tunables, uint devid)
31{
32 tunables->ntxd = NTXD;
33 tunables->nrxd = NRXD;
34 tunables->rxbufsz = RXBUFSZ;
35 tunables->nrxbufpost = NRXBUFPOST;
36 tunables->maxscb = MAXSCB;
37 tunables->ampdunummpdu = AMPDU_NUM_MPDU;
38 tunables->maxpktcb = MAXPKTCB;
39 tunables->maxucodebss = BRCMS_MAX_UCODE_BSS;
40 tunables->maxucodebss4 = BRCMS_MAX_UCODE_BSS4;
41 tunables->maxbss = MAXBSS;
42 tunables->datahiwat = BRCMS_DATAHIWAT;
43 tunables->ampdudatahiwat = BRCMS_AMPDUDATAHIWAT;
44 tunables->rxbnd = RXBND;
45 tunables->txsbnd = TXSBND;
46}
47
48static struct brcms_pub *brcms_c_pub_malloc(uint unit, uint *err, uint devid)
49{
50 struct brcms_pub *pub;
51
52 pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
53 if (pub == NULL) {
54 *err = 1001;
55 goto fail;
56 }
57
58 pub->tunables = kzalloc(sizeof(struct brcms_tunables), GFP_ATOMIC);
59 if (pub->tunables == NULL) {
60 *err = 1028;
61 goto fail;
62 }
63
64 /* need to init the tunables now */
65 brcms_c_tunables_init(pub->tunables, devid);
66
67 pub->multicast = kzalloc(ETH_ALEN * MAXMULTILIST, GFP_ATOMIC);
68 if (pub->multicast == NULL) {
69 *err = 1003;
70 goto fail;
71 }
72
73 return pub;
74
75 fail:
76 brcms_c_pub_mfree(pub);
77 return NULL;
78}
79
80static void brcms_c_pub_mfree(struct brcms_pub *pub)
81{
82 if (pub == NULL)
83 return;
84
85 kfree(pub->multicast);
86 kfree(pub->tunables);
87 kfree(pub);
88}
89
90static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
91{
92 struct brcms_bss_cfg *cfg;
93
94 cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
95 if (cfg == NULL)
96 goto fail;
97
98 cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
99 if (cfg->current_bss == NULL)
100 goto fail;
101
102 return cfg;
103
104 fail:
105 brcms_c_bsscfg_mfree(cfg);
106 return NULL;
107}
108
109static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
110{
111 if (cfg == NULL)
112 return;
113
114 kfree(cfg->maclist);
115 kfree(cfg->current_bss);
116 kfree(cfg);
117}
118
119static void brcms_c_bsscfg_ID_assign(struct brcms_c_info *wlc,
120 struct brcms_bss_cfg *bsscfg)
121{
122 bsscfg->ID = wlc->next_bsscfg_ID;
123 wlc->next_bsscfg_ID++;
124}
125
126/*
127 * The common driver entry routine. Error codes should be unique
128 */
129struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err, uint devid)
130{
131 struct brcms_c_info *wlc;
132
133 wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
134 if (wlc == NULL) {
135 *err = 1002;
136 goto fail;
137 }
138
139 /* allocate struct brcms_c_pub state structure */
140 wlc->pub = brcms_c_pub_malloc(unit, err, devid);
141 if (wlc->pub == NULL) {
142 *err = 1003;
143 goto fail;
144 }
145 wlc->pub->wlc = wlc;
146
147 /* allocate struct brcms_hardware state structure */
148
149 wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
150 if (wlc->hw == NULL) {
151 *err = 1005;
152 goto fail;
153 }
154 wlc->hw->wlc = wlc;
155
156 wlc->hw->bandstate[0] =
157 kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC);
158 if (wlc->hw->bandstate[0] == NULL) {
159 *err = 1006;
160 goto fail;
161 } else {
162 int i;
163
164 for (i = 1; i < MAXBANDS; i++) {
165 wlc->hw->bandstate[i] = (struct brcms_hw_band *)
166 ((unsigned long)wlc->hw->bandstate[0] +
167 (sizeof(struct brcms_hw_band) * i));
168 }
169 }
170
171 wlc->modulecb =
172 kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC);
173 if (wlc->modulecb == NULL) {
174 *err = 1009;
175 goto fail;
176 }
177
178 wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
179 if (wlc->default_bss == NULL) {
180 *err = 1010;
181 goto fail;
182 }
183
184 wlc->cfg = brcms_c_bsscfg_malloc(unit);
185 if (wlc->cfg == NULL) {
186 *err = 1011;
187 goto fail;
188 }
189 brcms_c_bsscfg_ID_assign(wlc, wlc->cfg);
190
191 wlc->wsec_def_keys[0] =
192 kzalloc(sizeof(struct wsec_key) * BRCMS_DEFAULT_KEYS,
193 GFP_ATOMIC);
194 if (wlc->wsec_def_keys[0] == NULL) {
195 *err = 1015;
196 goto fail;
197 } else {
198 int i;
199 for (i = 1; i < BRCMS_DEFAULT_KEYS; i++) {
200 wlc->wsec_def_keys[i] = (struct wsec_key *)
201 ((unsigned long)wlc->wsec_def_keys[0] +
202 (sizeof(struct wsec_key) * i));
203 }
204 }
205
206 wlc->protection = kzalloc(sizeof(struct brcms_protection),
207 GFP_ATOMIC);
208 if (wlc->protection == NULL) {
209 *err = 1016;
210 goto fail;
211 }
212
213 wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
214 if (wlc->stf == NULL) {
215 *err = 1017;
216 goto fail;
217 }
218
219 wlc->bandstate[0] =
220 kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC);
221 if (wlc->bandstate[0] == NULL) {
222 *err = 1025;
223 goto fail;
224 } else {
225 int i;
226
227 for (i = 1; i < MAXBANDS; i++) {
228 wlc->bandstate[i] = (struct brcms_band *)
229 ((unsigned long)wlc->bandstate[0]
230 + (sizeof(struct brcms_band)*i));
231 }
232 }
233
234 wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
235 if (wlc->corestate == NULL) {
236 *err = 1026;
237 goto fail;
238 }
239
240 wlc->corestate->macstat_snapshot =
241 kzalloc(sizeof(struct macstat), GFP_ATOMIC);
242 if (wlc->corestate->macstat_snapshot == NULL) {
243 *err = 1027;
244 goto fail;
245 }
246
247 return wlc;
248
249 fail:
250 brcms_c_detach_mfree(wlc);
251 return NULL;
252}
253
254void brcms_c_detach_mfree(struct brcms_c_info *wlc)
255{
256 if (wlc == NULL)
257 return;
258
259 brcms_c_bsscfg_mfree(wlc->cfg);
260 brcms_c_pub_mfree(wlc->pub);
261 kfree(wlc->modulecb);
262 kfree(wlc->default_bss);
263 kfree(wlc->wsec_def_keys[0]);
264 kfree(wlc->protection);
265 kfree(wlc->stf);
266 kfree(wlc->bandstate[0]);
267 kfree(wlc->corestate->macstat_snapshot);
268 kfree(wlc->corestate);
269 kfree(wlc->hw->bandstate[0]);
270 kfree(wlc->hw);
271
272 /* free the wlc */
273 kfree(wlc);
274 wlc = NULL;
275}
diff --git a/drivers/staging/brcm80211/brcmsmac/alloc.h b/drivers/staging/brcm80211/brcmsmac/alloc.h
new file mode 100644
index 00000000000..f465d304303
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/alloc.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17extern struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err,
18 uint devid);
19extern void brcms_c_detach_mfree(struct brcms_c_info *wlc);
diff --git a/drivers/staging/brcm80211/brcmsmac/ampdu.c b/drivers/staging/brcm80211/brcmsmac/ampdu.c
new file mode 100644
index 00000000000..fcaf61e3b13
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/ampdu.c
@@ -0,0 +1,1219 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <net/mac80211.h>
17
18#include "rate.h"
19#include "scb.h"
20#include "phy/phy_hal.h"
21#include "antsel.h"
22#include "main.h"
23#include "ampdu.h"
24
25#define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */
26#define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */
27#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
28#define AMPDU_TX_BA_DEF_WSIZE 64 /* default Tx ba window size (in pdu) */
29#define AMPDU_RX_BA_DEF_WSIZE 64 /* max Rx ba window size (in pdu) */
30#define AMPDU_RX_BA_MAX_WSIZE 64 /* default Rx ba window size (in pdu) */
31#define AMPDU_MAX_DUR 5 /* max dur of tx ampdu (in msec) */
32#define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit */
33#define AMPDU_DEF_RR_RETRY_LIMIT 2 /* default tx retry limit at reg rate */
34#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default weight of ampdu in txfifo */
35#define AMPDU_DEF_FFPLD_RSVD 2048 /* default ffpld reserved bytes */
36#define AMPDU_INI_FREE 10 /* # of inis to be freed on detach */
37#define AMPDU_SCB_MAX_RELEASE 20 /* max # of mpdus released at a time */
38
39#define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */
40#define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu
41 * without underflows
42 */
43#define FFPLD_MPDU_SIZE 1800 /* estimate of maximum mpdu size */
44#define FFPLD_MAX_MCS 23 /* we don't deal with mcs 32 */
45#define FFPLD_PLD_INCR 1000 /* increments in bytes */
46#define FFPLD_MAX_AMPDU_CNT 5000 /* maximum number of ampdu we
47 * accumulate between resets.
48 */
49
50#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
51
52/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
53#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
54 AMPDU_DELIMITER_LEN + 3\
55 + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
56
57/* structure to hold tx fifo information and pre-loading state
58 * counters specific to tx underflows of ampdus
59 * some counters might be redundant with the ones in wlc or ampdu structures.
60 * This allows to maintain a specific state independently of
61 * how often and/or when the wlc counters are updated.
62 */
63struct brcms_fifo_info {
64 u16 ampdu_pld_size; /* number of bytes to be pre-loaded */
65 u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; /* per-mcs max # of mpdus in an ampdu */
66 u16 prev_txfunfl; /* num of underflows last read from the HW macstats counter */
67 u32 accum_txfunfl; /* num of underflows since we modified pld params */
68 u32 accum_txampdu; /* num of tx ampdu since we modified pld params */
69 u32 prev_txampdu; /* previous reading of tx ampdu */
70 u32 dmaxferrate; /* estimated dma avg xfer rate in kbits/sec */
71};
72
73/* AMPDU module specific state */
74struct ampdu_info {
75 struct brcms_c_info *wlc; /* pointer to main wlc structure */
76 int scb_handle; /* scb cubby handle to retrieve data from scb */
77 u8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */
78 u8 ba_tx_wsize; /* Tx ba window size (in pdu) */
79 u8 ba_rx_wsize; /* Rx ba window size (in pdu) */
80 u8 retry_limit; /* mpdu transmit retry limit */
81 u8 rr_retry_limit; /* mpdu transmit retry limit at regular rate */
82 u8 retry_limit_tid[AMPDU_MAX_SCB_TID]; /* per-tid mpdu transmit retry limit */
83 /* per-tid mpdu transmit retry limit at regular rate */
84 u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
85 u8 mpdu_density; /* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */
86 s8 max_pdu; /* max pdus allowed in ampdu */
87 u8 dur; /* max duration of an ampdu (in msec) */
88 u8 txpkt_weight; /* weight of ampdu in txfifo; reduces rate lag */
89 u8 rx_factor; /* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */
90 u32 ffpld_rsvd; /* number of bytes to reserve for preload */
91 u32 max_txlen[MCS_TABLE_SIZE][2][2]; /* max size of ampdu per mcs, bw and sgi */
92 void *ini_free[AMPDU_INI_FREE]; /* array of ini's to be freed on detach */
93 bool mfbr; /* enable multiple fallback rate */
94 u32 tx_max_funl; /* underflows should be kept such that
95 * (tx_max_funfl*underflows) < tx frames
96 */
97 /* table of fifo infos */
98 struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
99
100};
101
102/* used for flushing ampdu packets */
103struct cb_del_ampdu_pars {
104 struct ieee80211_sta *sta;
105 u16 tid;
106};
107
108#define AMPDU_CLEANUPFLAG_RX (0x1)
109#define AMPDU_CLEANUPFLAG_TX (0x2)
110
111#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu))
112#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid]))
113
114static void brcms_c_ffpld_init(struct ampdu_info *ampdu);
115static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int f);
116static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f);
117
118static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu,
119 u8 dur);
120static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
121 struct scb *scb);
122static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu);
123
124#define brcms_c_ampdu_txflowcontrol(a, b, c) do {} while (0)
125
126static void
127brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu,
128 struct scb *scb,
129 struct sk_buff *p, struct tx_status *txs,
130 u32 frmtxstatus, u32 frmtxstatus2);
131
132static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu);
133static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on);
134
135struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
136{
137 struct ampdu_info *ampdu;
138 int i;
139
140 ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
141 if (!ampdu) {
142 wiphy_err(wlc->wiphy, "wl%d: brcms_c_ampdu_attach: out of mem"
143 "\n", wlc->pub->unit);
144 return NULL;
145 }
146 ampdu->wlc = wlc;
147
148 for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
149 ampdu->ini_enable[i] = true;
150 /* Disable ampdu for VO by default */
151 ampdu->ini_enable[PRIO_8021D_VO] = false;
152 ampdu->ini_enable[PRIO_8021D_NC] = false;
153
154 /* Disable ampdu for BK by default since not enough fifo space */
155 ampdu->ini_enable[PRIO_8021D_NONE] = false;
156 ampdu->ini_enable[PRIO_8021D_BK] = false;
157
158 ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
159 ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
160 ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
161 ampdu->max_pdu = AUTO;
162 ampdu->dur = AMPDU_MAX_DUR;
163 ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
164
165 ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
166 /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */
167 if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
168 ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
169 else
170 ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
171 ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
172 ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
173
174 for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
175 ampdu->retry_limit_tid[i] = ampdu->retry_limit;
176 ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
177 }
178
179 brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
180 ampdu->mfbr = false;
181 /* try to set ampdu to the default value */
182 brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
183
184 ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
185 brcms_c_ffpld_init(ampdu);
186
187 return ampdu;
188}
189
190void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
191{
192 int i;
193
194 if (!ampdu)
195 return;
196
197 /* free all ini's which were to be freed on callbacks which were never called */
198 for (i = 0; i < AMPDU_INI_FREE; i++) {
199 kfree(ampdu->ini_free[i]);
200 }
201
202 brcms_c_module_unregister(ampdu->wlc->pub, "ampdu", ampdu);
203 kfree(ampdu);
204}
205
206static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
207 struct scb *scb)
208{
209 struct scb_ampdu *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
210 int i;
211
212 scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu;
213
214 /* go back to legacy size if some preloading is occurring */
215 for (i = 0; i < NUM_FFPLD_FIFO; i++) {
216 if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
217 scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
218 }
219
220 /* apply user override */
221 if (ampdu->max_pdu != AUTO)
222 scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
223
224 scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE);
225
226 if (scb_ampdu->max_rx_ampdu_bytes)
227 scb_ampdu->release = min_t(u8, scb_ampdu->release,
228 scb_ampdu->max_rx_ampdu_bytes / 1600);
229
230 scb_ampdu->release = min(scb_ampdu->release,
231 ampdu->fifo_tb[TX_AC_BE_FIFO].
232 mcs2ampdu_table[FFPLD_MAX_MCS]);
233}
234
235static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
236{
237 brcms_c_scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb);
238}
239
240static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
241{
242 int i, j;
243 struct brcms_fifo_info *fifo;
244
245 for (j = 0; j < NUM_FFPLD_FIFO; j++) {
246 fifo = (ampdu->fifo_tb + j);
247 fifo->ampdu_pld_size = 0;
248 for (i = 0; i <= FFPLD_MAX_MCS; i++)
249 fifo->mcs2ampdu_table[i] = 255;
250 fifo->dmaxferrate = 0;
251 fifo->accum_txampdu = 0;
252 fifo->prev_txfunfl = 0;
253 fifo->accum_txfunfl = 0;
254
255 }
256}
257
258/* evaluate the dma transfer rate using the tx underflows as feedback.
259 * If necessary, increase tx fifo preloading. If not enough,
260 * decrease maximum ampdu size for each mcs till underflows stop
261 * Return 1 if pre-loading not active, -1 if not an underflow event,
262 * 0 if pre-loading module took care of the event.
263 */
264static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
265{
266 struct ampdu_info *ampdu = wlc->ampdu;
267 u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false);
268 u32 txunfl_ratio;
269 u8 max_mpdu;
270 u32 current_ampdu_cnt = 0;
271 u16 max_pld_size;
272 u32 new_txunfl;
273 struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
274 uint xmtfifo_sz;
275 u16 cur_txunfl;
276
277 /* return if we got here for a different reason than underflows */
278 cur_txunfl = brcms_c_read_shm(wlc,
279 M_UCODE_MACSTAT +
280 offsetof(struct macstat, txfunfl[fid]));
281 new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
282 if (new_txunfl == 0) {
283 BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
284 return -1;
285 }
286 fifo->prev_txfunfl = cur_txunfl;
287
288 if (!ampdu->tx_max_funl)
289 return 1;
290
291 /* check if fifo is big enough */
292 if (brcms_c_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz))
293 return -1;
294
295 if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
296 return 1;
297
298 max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
299 fifo->accum_txfunfl += new_txunfl;
300
301 /* we need to wait for at least 10 underflows */
302 if (fifo->accum_txfunfl < 10)
303 return 0;
304
305 BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n",
306 current_ampdu_cnt, fifo->accum_txfunfl);
307
308 /*
309 compute the current ratio of tx unfl per ampdu.
310 When the current ampdu count becomes too
311 big while the ratio remains small, we reset
312 the current count in order to not
313 introduce too big of a latency in detecting a
314 large amount of tx underflows later.
315 */
316
317 txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
318
319 if (txunfl_ratio > ampdu->tx_max_funl) {
320 if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) {
321 fifo->accum_txfunfl = 0;
322 }
323 return 0;
324 }
325 max_mpdu =
326 min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY);
327
328 /* In case max value max_pdu is already lower than
329 the fifo depth, there is nothing more we can do.
330 */
331
332 if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
333 fifo->accum_txfunfl = 0;
334 return 0;
335 }
336
337 if (fifo->ampdu_pld_size < max_pld_size) {
338
339 /* increment by TX_FIFO_PLD_INC bytes */
340 fifo->ampdu_pld_size += FFPLD_PLD_INCR;
341 if (fifo->ampdu_pld_size > max_pld_size)
342 fifo->ampdu_pld_size = max_pld_size;
343
344 /* update scb release size */
345 brcms_c_scb_ampdu_update_config_all(ampdu);
346
347 /*
348 compute a new dma xfer rate for max_mpdu @ max mcs.
349 This is the minimum dma rate that
350 can achieve no underflow condition for the current mpdu size.
351 */
352 /* note : we divide/multiply by 100 to avoid integer overflows */
353 fifo->dmaxferrate =
354 (((phy_rate / 100) *
355 (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
356 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
357
358 BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
359 "pre-load size %d\n",
360 fifo->dmaxferrate, fifo->ampdu_pld_size);
361 } else {
362
363 /* decrease ampdu size */
364 if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
365 if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
366 fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
367 AMPDU_NUM_MPDU_LEGACY - 1;
368 else
369 fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
370
371 /* recompute the table */
372 brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
373
374 /* update scb release size */
375 brcms_c_scb_ampdu_update_config_all(ampdu);
376 }
377 }
378 fifo->accum_txfunfl = 0;
379 return 0;
380}
381
382static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
383{
384 int i;
385 u32 phy_rate, dma_rate, tmp;
386 u8 max_mpdu;
387 struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
388
389 /* recompute the dma rate */
390 /* note : we divide/multiply by 100 to avoid integer overflows */
391 max_mpdu =
392 min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY);
393 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false);
394 dma_rate =
395 (((phy_rate / 100) *
396 (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
397 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
398 fifo->dmaxferrate = dma_rate;
399
400 /* fill up the mcs2ampdu table; do not recalc the last mcs */
401 dma_rate = dma_rate >> 7;
402 for (i = 0; i < FFPLD_MAX_MCS; i++) {
403 /* shifting to keep it within integer range */
404 phy_rate = MCS_RATE(i, true, false) >> 7;
405 if (phy_rate > dma_rate) {
406 tmp = ((fifo->ampdu_pld_size * phy_rate) /
407 ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
408 tmp = min_t(u32, tmp, 255);
409 fifo->mcs2ampdu_table[i] = (u8) tmp;
410 }
411 }
412}
413
414void
415brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
416 u8 ba_wsize, /* negotiated ba window size (in pdu) */
417 uint max_rx_ampdu_bytes) /* from ht_cap in beacon */
418{
419 struct scb_ampdu *scb_ampdu;
420 struct scb_ampdu_tid_ini *ini;
421 struct ampdu_info *ampdu = wlc->ampdu;
422 struct scb *scb = wlc->pub->global_scb;
423 scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
424
425 if (!ampdu->ini_enable[tid]) {
426 wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
427 __func__, tid);
428 return;
429 }
430
431 ini = SCB_AMPDU_INI(scb_ampdu, tid);
432 ini->tid = tid;
433 ini->scb = scb_ampdu->scb;
434 ini->ba_wsize = ba_wsize;
435 scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
436}
437
438int
439brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
440 struct sk_buff **pdu, int prec)
441{
442 struct brcms_c_info *wlc;
443 struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
444 u8 tid, ndelim;
445 int err = 0;
446 u8 preamble_type = BRCMS_GF_PREAMBLE;
447 u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
448 u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
449 u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
450
451 bool rr = true, fbr = false;
452 uint i, count = 0, fifo, seg_cnt = 0;
453 u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
454 u32 ampdu_len, max_ampdu_bytes = 0;
455 struct d11txh *txh = NULL;
456 u8 *plcp;
457 struct ieee80211_hdr *h;
458 struct scb *scb;
459 struct scb_ampdu *scb_ampdu;
460 struct scb_ampdu_tid_ini *ini;
461 u8 mcs = 0;
462 bool use_rts = false, use_cts = false;
463 ratespec_t rspec = 0, rspec_fallback = 0;
464 ratespec_t rts_rspec = 0, rts_rspec_fallback = 0;
465 u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
466 struct ieee80211_rts *rts;
467 u8 rr_retry_limit;
468 struct brcms_fifo_info *f;
469 bool fbr_iscck;
470 struct ieee80211_tx_info *tx_info;
471 u16 qlen;
472 struct wiphy *wiphy;
473
474 wlc = ampdu->wlc;
475 wiphy = wlc->wiphy;
476 p = *pdu;
477
478 tid = (u8) (p->priority);
479
480 f = ampdu->fifo_tb + prio2fifo[tid];
481
482 scb = wlc->pub->global_scb;
483 scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
484 ini = &scb_ampdu->ini[tid];
485
486 /* Let pressure continue to build ... */
487 qlen = pktq_plen(&qi->q, prec);
488 if (ini->tx_in_transit > 0 &&
489 qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) {
490 /* Collect multiple MPDU's to be sent in the next AMPDU */
491 return -EBUSY;
492 }
493
494 /* at this point we intend to transmit an AMPDU */
495 rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
496 ampdu_len = 0;
497 dma_len = 0;
498 while (p) {
499 struct ieee80211_tx_rate *txrate;
500
501 tx_info = IEEE80211_SKB_CB(p);
502 txrate = tx_info->status.rates;
503
504 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
505 err = brcms_c_prep_pdu(wlc, p, &fifo);
506 } else {
507 wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
508 *pdu = NULL;
509 err = 0;
510 break;
511 }
512
513 if (err) {
514 if (err == -EBUSY) {
515 wiphy_err(wiphy, "wl%d: sendampdu: "
516 "prep_xdu retry; seq 0x%x\n",
517 wlc->pub->unit, seq);
518 *pdu = p;
519 break;
520 }
521
522 /* error in the packet; reject it */
523 wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
524 "rejected; seq 0x%x\n", wlc->pub->unit, seq);
525 *pdu = NULL;
526 break;
527 }
528
529 /* pkt is good to be aggregated */
530 txh = (struct d11txh *) p->data;
531 plcp = (u8 *) (txh + 1);
532 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
533 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
534 index = TX_SEQ_TO_INDEX(seq);
535
536 /* check mcl fields and test whether it can be agg'd */
537 mcl = le16_to_cpu(txh->MacTxControlLow);
538 mcl &= ~TXC_AMPDU_MASK;
539 fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
540 txh->PreloadSize = 0; /* always default to 0 */
541
542 /* Handle retry limits */
543 if (txrate[0].count <= rr_retry_limit) {
544 txrate[0].count++;
545 rr = true;
546 fbr = false;
547 } else {
548 fbr = true;
549 rr = false;
550 txrate[1].count++;
551 }
552
553 /* extract the length info */
554 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
555 : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
556
557 /* retrieve null delimiter count */
558 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
559 seg_cnt += 1;
560
561 BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
562 wlc->pub->unit, count, len);
563
564 /*
565 * aggregateable mpdu. For ucode/hw agg,
566 * test whether need to break or change the epoch
567 */
568 if (count == 0) {
569 mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
570 /* refill the bits since might be a retx mpdu */
571 mcl |= TXC_STARTMSDU;
572 rts = (struct ieee80211_rts *)&txh->rts_frame;
573
574 if (ieee80211_is_rts(rts->frame_control)) {
575 mcl |= TXC_SENDRTS;
576 use_rts = true;
577 }
578 if (ieee80211_is_cts(rts->frame_control)) {
579 mcl |= TXC_SENDCTS;
580 use_cts = true;
581 }
582 } else {
583 mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
584 mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
585 }
586
587 len = roundup(len, 4);
588 ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
589
590 dma_len += (u16) brcmu_pkttotlen(p);
591
592 BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
593 " seg_cnt %d null delim %d\n",
594 wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
595
596 txh->MacTxControlLow = cpu_to_le16(mcl);
597
598 /* this packet is added */
599 pkt[count++] = p;
600
601 /* patch the first MPDU */
602 if (count == 1) {
603 u8 plcp0, plcp3, is40, sgi;
604 struct ieee80211_sta *sta;
605
606 sta = tx_info->control.sta;
607
608 if (rr) {
609 plcp0 = plcp[0];
610 plcp3 = plcp[3];
611 } else {
612 plcp0 = txh->FragPLCPFallback[0];
613 plcp3 = txh->FragPLCPFallback[3];
614
615 }
616 is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
617 sgi = PLCP3_ISSGI(plcp3) ? 1 : 0;
618 mcs = plcp0 & ~MIMO_PLCP_40MHZ;
619 max_ampdu_bytes =
620 min(scb_ampdu->max_rx_ampdu_bytes,
621 ampdu->max_txlen[mcs][is40][sgi]);
622
623 if (is40)
624 mimo_ctlchbw =
625 CHSPEC_SB_UPPER(BRCMS_BAND_PI_RADIO_CHANSPEC)
626 ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
627
628 /* rebuild the rspec and rspec_fallback */
629 rspec = RSPEC_MIMORATE;
630 rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
631 if (plcp[0] & MIMO_PLCP_40MHZ)
632 rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
633
634 if (fbr_iscck) /* CCK */
635 rspec_fallback =
636 CCK_RSPEC(CCK_PHY2MAC_RATE
637 (txh->FragPLCPFallback[0]));
638 else { /* MIMO */
639 rspec_fallback = RSPEC_MIMORATE;
640 rspec_fallback |=
641 txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
642 if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
643 rspec_fallback |=
644 (PHY_TXC1_BW_40MHZ <<
645 RSPEC_BW_SHIFT);
646 }
647
648 if (use_rts || use_cts) {
649 rts_rspec =
650 brcms_c_rspec_to_rts_rspec(wlc,
651 rspec, false, mimo_ctlchbw);
652 rts_rspec_fallback =
653 brcms_c_rspec_to_rts_rspec(wlc,
654 rspec_fallback, false, mimo_ctlchbw);
655 }
656 }
657
658 /* if (first mpdu for host agg) */
659 /* test whether to add more */
660 if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) &&
661 (count == f->mcs2ampdu_table[mcs])) {
662 BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
663 " ampdu at %d for mcs %d\n",
664 wlc->pub->unit, count, mcs);
665 break;
666 }
667
668 if (count == scb_ampdu->max_pdu) {
669 break;
670 }
671
672 /* check to see if the next pkt is a candidate for aggregation */
673 p = pktq_ppeek(&qi->q, prec);
674 tx_info = IEEE80211_SKB_CB(p); /* tx_info must be checked with current p */
675
676 if (p) {
677 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
678 ((u8) (p->priority) == tid)) {
679
680 plen = brcmu_pkttotlen(p) +
681 AMPDU_MAX_MPDU_OVERHEAD;
682 plen = max(scb_ampdu->min_len, plen);
683
684 if ((plen + ampdu_len) > max_ampdu_bytes) {
685 p = NULL;
686 continue;
687 }
688
689 /* check if there are enough descriptors available */
690 if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) {
691 wiphy_err(wiphy, "%s: No fifo space "
692 "!!\n", __func__);
693 p = NULL;
694 continue;
695 }
696 p = brcmu_pktq_pdeq(&qi->q, prec);
697 } else {
698 p = NULL;
699 }
700 }
701 } /* end while(p) */
702
703 ini->tx_in_transit += count;
704
705 if (count) {
706 /* patch up the last txh */
707 txh = (struct d11txh *) pkt[count - 1]->data;
708 mcl = le16_to_cpu(txh->MacTxControlLow);
709 mcl &= ~TXC_AMPDU_MASK;
710 mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
711 txh->MacTxControlLow = cpu_to_le16(mcl);
712
713 /* remove the null delimiter after last mpdu */
714 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
715 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
716 ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
717
718 /* remove the pad len from last mpdu */
719 fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
720 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
721 : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
722 ampdu_len -= roundup(len, 4) - len;
723
724 /* patch up the first txh & plcp */
725 txh = (struct d11txh *) pkt[0]->data;
726 plcp = (u8 *) (txh + 1);
727
728 BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
729 /* mark plcp to indicate ampdu */
730 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
731
732 /* reset the mixed mode header durations */
733 if (txh->MModeLen) {
734 u16 mmodelen =
735 brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
736 txh->MModeLen = cpu_to_le16(mmodelen);
737 preamble_type = BRCMS_MM_PREAMBLE;
738 }
739 if (txh->MModeFbrLen) {
740 u16 mmfbrlen =
741 brcms_c_calc_lsig_len(wlc, rspec_fallback,
742 ampdu_len);
743 txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
744 fbr_preamble_type = BRCMS_MM_PREAMBLE;
745 }
746
747 /* set the preload length */
748 if (MCS_RATE(mcs, true, false) >= f->dmaxferrate) {
749 dma_len = min(dma_len, f->ampdu_pld_size);
750 txh->PreloadSize = cpu_to_le16(dma_len);
751 } else
752 txh->PreloadSize = 0;
753
754 mch = le16_to_cpu(txh->MacTxControlHigh);
755
756 /* update RTS dur fields */
757 if (use_rts || use_cts) {
758 u16 durid;
759 rts = (struct ieee80211_rts *)&txh->rts_frame;
760 if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
761 TXC_PREAMBLE_RTS_MAIN_SHORT)
762 rts_preamble_type = BRCMS_SHORT_PREAMBLE;
763
764 if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
765 TXC_PREAMBLE_RTS_FB_SHORT)
766 rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
767
768 durid =
769 brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
770 rspec, rts_preamble_type,
771 preamble_type, ampdu_len,
772 true);
773 rts->duration = cpu_to_le16(durid);
774 durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
775 rts_rspec_fallback,
776 rspec_fallback,
777 rts_fbr_preamble_type,
778 fbr_preamble_type,
779 ampdu_len, true);
780 txh->RTSDurFallback = cpu_to_le16(durid);
781 /* set TxFesTimeNormal */
782 txh->TxFesTimeNormal = rts->duration;
783 /* set fallback rate version of TxFesTimeNormal */
784 txh->TxFesTimeFallback = txh->RTSDurFallback;
785 }
786
787 /* set flag and plcp for fallback rate */
788 if (fbr) {
789 mch |= TXC_AMPDU_FBR;
790 txh->MacTxControlHigh = cpu_to_le16(mch);
791 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
792 BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
793 }
794
795 BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
796 wlc->pub->unit, count, ampdu_len);
797
798 /* inform rate_sel if it this is a rate probe pkt */
799 frameid = le16_to_cpu(txh->TxFrameID);
800 if (frameid & TXFID_RATE_PROBE_MASK) {
801 wiphy_err(wiphy, "%s: XXX what to do with "
802 "TXFID_RATE_PROBE_MASK!?\n", __func__);
803 }
804 for (i = 0; i < count; i++)
805 brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
806 ampdu->txpkt_weight);
807
808 }
809 /* endif (count) */
810 return err;
811}
812
813void
814brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
815 struct sk_buff *p, struct tx_status *txs)
816{
817 struct scb_ampdu *scb_ampdu;
818 struct brcms_c_info *wlc = ampdu->wlc;
819 struct scb_ampdu_tid_ini *ini;
820 u32 s1 = 0, s2 = 0;
821 struct ieee80211_tx_info *tx_info;
822
823 tx_info = IEEE80211_SKB_CB(p);
824
825 /* BMAC_NOTE: For the split driver, second level txstatus comes later
826 * So if the ACK was received then wait for the second level else just
827 * call the first one
828 */
829 if (txs->status & TX_STATUS_ACK_RCV) {
830 u8 status_delay = 0;
831
832 /* wait till the next 8 bytes of txstatus is available */
833 while (((s1 = R_REG(&wlc->regs->frmtxstatus)) & TXS_V) == 0) {
834 udelay(1);
835 status_delay++;
836 if (status_delay > 10) {
837 return; /* error condition */
838 }
839 }
840
841 s2 = R_REG(&wlc->regs->frmtxstatus2);
842 }
843
844 if (likely(scb)) {
845 scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
846 ini = SCB_AMPDU_INI(scb_ampdu, p->priority);
847 brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
848 } else {
849 /* loop through all pkts and free */
850 u8 queue = txs->frameid & TXFID_QUEUE_MASK;
851 struct d11txh *txh;
852 u16 mcl;
853 while (p) {
854 tx_info = IEEE80211_SKB_CB(p);
855 txh = (struct d11txh *) p->data;
856 mcl = le16_to_cpu(txh->MacTxControlLow);
857 brcmu_pkt_buf_free_skb(p);
858 /* break out if last packet of ampdu */
859 if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
860 TXC_AMPDU_LAST)
861 break;
862 p = GETNEXTTXP(wlc, queue);
863 }
864 brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
865 }
866 brcms_c_ampdu_txflowcontrol(wlc, scb_ampdu, ini);
867}
868
869static void
870brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
871 struct ieee80211_tx_info *tx_info,
872 struct tx_status *txs, u8 mcs)
873{
874 struct ieee80211_tx_rate *txrate = tx_info->status.rates;
875 int i;
876
877 /* clear the rest of the rates */
878 for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
879 txrate[i].idx = -1;
880 txrate[i].count = 0;
881 }
882}
883
884#define SHORTNAME "AMPDU status"
885
886static void
887brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
888 struct sk_buff *p, struct tx_status *txs,
889 u32 s1, u32 s2)
890{
891 struct scb_ampdu *scb_ampdu;
892 struct brcms_c_info *wlc = ampdu->wlc;
893 struct scb_ampdu_tid_ini *ini;
894 u8 bitmap[8], queue, tid;
895 struct d11txh *txh;
896 u8 *plcp;
897 struct ieee80211_hdr *h;
898 u16 seq, start_seq = 0, bindex, index, mcl;
899 u8 mcs = 0;
900 bool ba_recd = false, ack_recd = false;
901 u8 suc_mpdu = 0, tot_mpdu = 0;
902 uint supr_status;
903 bool update_rate = true, retry = true, tx_error = false;
904 u16 mimoantsel = 0;
905 u8 antselid = 0;
906 u8 retry_limit, rr_retry_limit;
907 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
908 struct wiphy *wiphy = wlc->wiphy;
909
910#ifdef BCMDBG
911 u8 hole[AMPDU_MAX_MPDU];
912 memset(hole, 0, sizeof(hole));
913#endif
914
915 scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
916 tid = (u8) (p->priority);
917
918 ini = SCB_AMPDU_INI(scb_ampdu, tid);
919 retry_limit = ampdu->retry_limit_tid[tid];
920 rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
921 memset(bitmap, 0, sizeof(bitmap));
922 queue = txs->frameid & TXFID_QUEUE_MASK;
923 supr_status = txs->status & TX_STATUS_SUPR_MASK;
924
925 if (txs->status & TX_STATUS_ACK_RCV) {
926 if (TX_STATUS_SUPR_UF == supr_status) {
927 update_rate = false;
928 }
929
930 WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
931 start_seq = txs->sequence >> SEQNUM_SHIFT;
932 bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
933 TX_STATUS_BA_BMAP03_SHIFT;
934
935 WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
936 WARN_ON(!(s1 & TX_STATUS_AMPDU));
937
938 bitmap[0] |=
939 (s1 & TX_STATUS_BA_BMAP47_MASK) <<
940 TX_STATUS_BA_BMAP47_SHIFT;
941 bitmap[1] = (s1 >> 8) & 0xff;
942 bitmap[2] = (s1 >> 16) & 0xff;
943 bitmap[3] = (s1 >> 24) & 0xff;
944
945 bitmap[4] = s2 & 0xff;
946 bitmap[5] = (s2 >> 8) & 0xff;
947 bitmap[6] = (s2 >> 16) & 0xff;
948 bitmap[7] = (s2 >> 24) & 0xff;
949
950 ba_recd = true;
951 } else {
952 if (supr_status) {
953 update_rate = false;
954 if (supr_status == TX_STATUS_SUPR_BADCH) {
955 wiphy_err(wiphy, "%s: Pkt tx suppressed, "
956 "illegal channel possibly %d\n",
957 __func__, CHSPEC_CHANNEL(
958 wlc->default_bss->chanspec));
959 } else {
960 if (supr_status != TX_STATUS_SUPR_FRAG)
961 wiphy_err(wiphy, "%s:"
962 "supr_status 0x%x\n",
963 __func__, supr_status);
964 }
965 /* no need to retry for badch; will fail again */
966 if (supr_status == TX_STATUS_SUPR_BADCH ||
967 supr_status == TX_STATUS_SUPR_EXPTIME) {
968 retry = false;
969 } else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
970 /* TX underflow : try tuning pre-loading or ampdu size */
971 } else if (supr_status == TX_STATUS_SUPR_FRAG) {
972 /* if there were underflows, but pre-loading is not active,
973 notify rate adaptation.
974 */
975 if (brcms_c_ffpld_check_txfunfl(wlc,
976 prio2fifo[tid]) > 0) {
977 tx_error = true;
978 }
979 }
980 } else if (txs->phyerr) {
981 update_rate = false;
982 wiphy_err(wiphy, "wl%d: ampdu tx phy "
983 "error (0x%x)\n", wlc->pub->unit,
984 txs->phyerr);
985
986 if (WL_ERROR_ON()) {
987 brcmu_prpkt("txpkt (AMPDU)", p);
988 brcms_c_print_txdesc((struct d11txh *) p->data);
989 }
990 brcms_c_print_txstatus(txs);
991 }
992 }
993
994 /* loop through all pkts and retry if not acked */
995 while (p) {
996 tx_info = IEEE80211_SKB_CB(p);
997 txh = (struct d11txh *) p->data;
998 mcl = le16_to_cpu(txh->MacTxControlLow);
999 plcp = (u8 *) (txh + 1);
1000 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
1001 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
1002
1003 if (tot_mpdu == 0) {
1004 mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
1005 mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
1006 }
1007
1008 index = TX_SEQ_TO_INDEX(seq);
1009 ack_recd = false;
1010 if (ba_recd) {
1011 bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
1012 BCMMSG(wlc->wiphy, "tid %d seq %d,"
1013 " start_seq %d, bindex %d set %d, index %d\n",
1014 tid, seq, start_seq, bindex,
1015 isset(bitmap, bindex), index);
1016 /* if acked then clear bit and free packet */
1017 if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
1018 && isset(bitmap, bindex)) {
1019 ini->tx_in_transit--;
1020 ini->txretry[index] = 0;
1021
1022 /* ampdu_ack_len: number of acked aggregated frames */
1023 /* ampdu_len: number of aggregated frames */
1024 brcms_c_ampdu_rate_status(wlc, tx_info, txs,
1025 mcs);
1026 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1027 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1028 tx_info->status.ampdu_ack_len =
1029 tx_info->status.ampdu_len = 1;
1030
1031 skb_pull(p, D11_PHY_HDR_LEN);
1032 skb_pull(p, D11_TXH_LEN);
1033
1034 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1035 p);
1036 ack_recd = true;
1037 suc_mpdu++;
1038 }
1039 }
1040 /* either retransmit or send bar if ack not recd */
1041 if (!ack_recd) {
1042 struct ieee80211_tx_rate *txrate =
1043 tx_info->status.rates;
1044 if (retry && (txrate[0].count < (int)retry_limit)) {
1045 ini->txretry[index]++;
1046 ini->tx_in_transit--;
1047 /* Use high prededence for retransmit to give some punch */
1048 /* brcms_c_txq_enq(wlc, scb, p,
1049 * BRCMS_PRIO_TO_PREC(tid)); */
1050 brcms_c_txq_enq(wlc, scb, p,
1051 BRCMS_PRIO_TO_HI_PREC(tid));
1052 } else {
1053 /* Retry timeout */
1054 ini->tx_in_transit--;
1055 ieee80211_tx_info_clear_status(tx_info);
1056 tx_info->status.ampdu_ack_len = 0;
1057 tx_info->status.ampdu_len = 1;
1058 tx_info->flags |=
1059 IEEE80211_TX_STAT_AMPDU_NO_BACK;
1060 skb_pull(p, D11_PHY_HDR_LEN);
1061 skb_pull(p, D11_TXH_LEN);
1062 wiphy_err(wiphy, "%s: BA Timeout, seq %d, in_"
1063 "transit %d\n", SHORTNAME, seq,
1064 ini->tx_in_transit);
1065 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1066 p);
1067 }
1068 }
1069 tot_mpdu++;
1070
1071 /* break out if last packet of ampdu */
1072 if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1073 TXC_AMPDU_LAST)
1074 break;
1075
1076 p = GETNEXTTXP(wlc, queue);
1077 }
1078 brcms_c_send_q(wlc);
1079
1080 /* update rate state */
1081 antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
1082
1083 brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
1084}
1085
1086static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
1087{
1088 struct brcms_c_info *wlc = ampdu->wlc;
1089
1090 wlc->pub->_ampdu = false;
1091
1092 if (on) {
1093 if (!N_ENAB(wlc->pub)) {
1094 wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
1095 "nmode enabled\n", wlc->pub->unit);
1096 return -ENOTSUPP;
1097 }
1098 if (!brcms_c_ampdu_cap(ampdu)) {
1099 wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
1100 "ampdu capable\n", wlc->pub->unit);
1101 return -ENOTSUPP;
1102 }
1103 wlc->pub->_ampdu = on;
1104 }
1105
1106 return 0;
1107}
1108
1109static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
1110{
1111 if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
1112 return true;
1113 else
1114 return false;
1115}
1116
1117static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
1118{
1119 u32 rate, mcs;
1120
1121 for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
1122 /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
1123 /* 20MHz, No SGI */
1124 rate = MCS_RATE(mcs, false, false);
1125 ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
1126 /* 40 MHz, No SGI */
1127 rate = MCS_RATE(mcs, true, false);
1128 ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
1129 /* 20MHz, SGI */
1130 rate = MCS_RATE(mcs, false, true);
1131 ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
1132 /* 40 MHz, SGI */
1133 rate = MCS_RATE(mcs, true, true);
1134 ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
1135 }
1136}
1137
1138void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
1139{
1140 char template[T_RAM_ACCESS_SZ * 2];
1141
1142 /* driver needs to write the ta in the template; ta is at offset 16 */
1143 memset(template, 0, sizeof(template));
1144 memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
1145 brcms_c_write_template_ram(wlc, (T_BA_TPL_BASE + 16),
1146 (T_RAM_ACCESS_SZ * 2),
1147 template);
1148}
1149
1150bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
1151{
1152 return wlc->ampdu->ini_enable[tid];
1153}
1154
1155void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
1156{
1157 struct brcms_c_info *wlc = ampdu->wlc;
1158
1159 /* Extend ucode internal watchdog timer to match larger received frames */
1160 if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
1161 IEEE80211_HT_MAX_AMPDU_64K) {
1162 brcms_c_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
1163 brcms_c_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
1164 } else {
1165 brcms_c_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
1166 brcms_c_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
1167 }
1168}
1169
1170/*
1171 * callback function that helps flushing ampdu packets from a priority queue
1172 */
1173static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
1174{
1175 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
1176 struct cb_del_ampdu_pars *ampdu_pars =
1177 (struct cb_del_ampdu_pars *)arg_a;
1178 bool rc;
1179
1180 rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
1181 rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL ||
1182 tx_info->control.sta == ampdu_pars->sta);
1183 rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
1184 return rc;
1185}
1186
1187/*
1188 * callback function that helps invalidating ampdu packets in a DMA queue
1189 */
1190static void dma_cb_fn_ampdu(void *txi, void *arg_a)
1191{
1192 struct ieee80211_sta *sta = arg_a;
1193 struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
1194
1195 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1196 (tx_info->control.sta == sta || sta == NULL))
1197 tx_info->control.sta = NULL;
1198}
1199
1200/*
1201 * When a remote party is no longer available for ampdu communication, any
1202 * pending tx ampdu packets in the driver have to be flushed.
1203 */
1204void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
1205 struct ieee80211_sta *sta, u16 tid)
1206{
1207 struct brcms_txq_info *qi = wlc->pkt_queue;
1208 struct pktq *pq = &qi->q;
1209 int prec;
1210 struct cb_del_ampdu_pars ampdu_pars;
1211
1212 ampdu_pars.sta = sta;
1213 ampdu_pars.tid = tid;
1214 for (prec = 0; prec < pq->num_prec; prec++) {
1215 brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
1216 (void *)&ampdu_pars);
1217 }
1218 brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
1219}
diff --git a/drivers/staging/brcm80211/brcmsmac/ampdu.h b/drivers/staging/brcm80211/brcmsmac/ampdu.h
new file mode 100644
index 00000000000..421f4ba7c63
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/ampdu.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_AMPDU_H_
18#define _BRCM_AMPDU_H_
19
20extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
21extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
22extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
23 struct brcms_txq_info *qi,
24 struct sk_buff **aggp, int prec);
25extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
26 struct sk_buff *p, struct tx_status *txs);
27extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
28extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
29
30#endif /* _BRCM_AMPDU_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/antsel.c b/drivers/staging/brcm80211/brcmsmac/antsel.c
new file mode 100644
index 00000000000..c4e76c093ae
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/antsel.c
@@ -0,0 +1,311 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/slab.h>
18#include <net/mac80211.h>
19
20#include "types.h"
21#include "bmac.h"
22#include "main.h"
23#include "phy_shim.h"
24#include "antsel.h"
25
26#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
27#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
28#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */
29#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */
30#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */
31#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */
32
33/* useful macros */
34#define BRCMS_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
35#define BRCMS_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf)
36#define BRCMS_ANTIDX_11N(ant) (((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
37 (BRCMS_ANTSEL_11N_1(ant)))
38#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
39#define BRCMS_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK)
40
41/* antenna switch */
42/* defines for no boardlevel antenna diversity */
43#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */
44
45/* 2x3 antdiv defines and tables for GPIO communication */
46#define ANT_SELCFG_NUM_2x3 3
47#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */
48
49/* 2x4 antdiv rev4 defines and tables for GPIO communication */
50#define ANT_SELCFG_NUM_2x4 4
51#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */
52
53/* static functions */
54static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
55 struct brcms_antselcfg *antsel);
56static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id);
57static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg);
58static void brcms_c_antsel_init_cfg(struct antsel_info *asi,
59 struct brcms_antselcfg *antsel,
60 bool auto_sel);
61
62const u16 mimo_2x4_div_antselpat_tbl[] = {
63 0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */
64 0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */
65 0, 0, 0, 0, /* n.a. */
66 0, 0, 0, 0 /* n.a. */
67};
68
69const u8 mimo_2x4_div_antselid_tbl[16] = {
70 0, 0, 0, 0, 0, 2, 3, 0,
71 0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */
72};
73
74const u16 mimo_2x3_div_antselpat_tbl[] = {
75 16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */
76 16, 16, 16, 16, /* n.a. */
77 16, 2, 16, 16, /* ant0: 2 ant1: 1 */
78 16, 16, 16, 16 /* n.a. */
79};
80
81const u8 mimo_2x3_div_antselid_tbl[16] = {
82 0, 1, 2, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */
84};
85
86struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
87{
88 struct antsel_info *asi;
89
90 asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
91 if (!asi) {
92 wiphy_err(wlc->wiphy, "wl%d: brcms_c_antsel_attach: out of "
93 "mem\n", wlc->pub->unit);
94 return NULL;
95 }
96
97 asi->wlc = wlc;
98 asi->pub = wlc->pub;
99 asi->antsel_type = ANTSEL_NA;
100 asi->antsel_avail = false;
101 asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch");
102
103 if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
104 switch (asi->antsel_antswitch) {
105 case ANTSWITCH_TYPE_1:
106 case ANTSWITCH_TYPE_2:
107 case ANTSWITCH_TYPE_3:
108 /* 4321/2 board with 2x3 switch logic */
109 asi->antsel_type = ANTSEL_2x3;
110 /* Antenna selection availability */
111 if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) ||
112 ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) {
113 asi->antsel_avail = true;
114 } else
115 if (((u16) getintvar(asi->pub->vars, "aa2g") ==
116 3)
117 || ((u16) getintvar(asi->pub->vars, "aa5g")
118 == 3)) {
119 asi->antsel_avail = false;
120 } else {
121 asi->antsel_avail = false;
122 wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
123 "board cfg invalid\n");
124 }
125 break;
126 default:
127 break;
128 }
129 } else if ((asi->pub->sromrev == 4) &&
130 ((u16) getintvar(asi->pub->vars, "aa2g") == 7) &&
131 ((u16) getintvar(asi->pub->vars, "aa5g") == 0)) {
132 /* hack to match old 4321CB2 cards with 2of3 antenna switch */
133 asi->antsel_type = ANTSEL_2x3;
134 asi->antsel_avail = true;
135 } else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
136 asi->antsel_type = ANTSEL_2x4;
137 asi->antsel_avail = true;
138 }
139
140 /* Set the antenna selection type for the low driver */
141 brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
142
143 /* Init (auto/manual) antenna selection */
144 brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
145 brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
146
147 return asi;
148}
149
150void brcms_c_antsel_detach(struct antsel_info *asi)
151{
152 kfree(asi);
153}
154
155void brcms_c_antsel_init(struct antsel_info *asi)
156{
157 if ((asi->antsel_type == ANTSEL_2x3) ||
158 (asi->antsel_type == ANTSEL_2x4))
159 brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
160}
161
162/* boardlevel antenna selection: init antenna selection structure */
163static void
164brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
165 bool auto_sel)
166{
167 if (asi->antsel_type == ANTSEL_2x3) {
168 u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
169 ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
170 antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
171 antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
172 antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
173 antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
174 antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
175
176 } else if (asi->antsel_type == ANTSEL_2x4) {
177
178 antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
179 antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
180 antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
181 antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
182 antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
183
184 } else { /* no antenna selection available */
185
186 antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
187 antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
188 antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
189 antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
190 antsel->num_antcfg = 0;
191 }
192}
193
194void
195brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
196 u8 antselid, u8 fbantselid, u8 *antcfg,
197 u8 *fbantcfg)
198{
199 u8 ant;
200
201 /* if use default, assign it and return */
202 if (usedef) {
203 *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
204 *fbantcfg = *antcfg;
205 return;
206 }
207
208 if (!sel) {
209 *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
210 *fbantcfg = *antcfg;
211
212 } else {
213 ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
214 if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
215 *antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
216 *fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
217 } else {
218 *antcfg =
219 asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
220 *fbantcfg = *antcfg;
221 }
222 }
223 return;
224}
225
226/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
227u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
228{
229 u8 antselid = 0;
230
231 if (asi->antsel_type == ANTSEL_2x4) {
232 /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
233 antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
234 return antselid;
235
236 } else if (asi->antsel_type == ANTSEL_2x3) {
237 /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
238 antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
239 return antselid;
240 }
241
242 return antselid;
243}
244
245/* boardlevel antenna selection: convert id to ant_cfg */
246static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
247{
248 u8 antcfg = ANT_SELCFG_DEF_2x2;
249
250 if (asi->antsel_type == ANTSEL_2x4) {
251 /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
252 antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
253 return antcfg;
254
255 } else if (asi->antsel_type == ANTSEL_2x3) {
256 /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
257 antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
258 return antcfg;
259 }
260
261 return antcfg;
262}
263
264/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */
265static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
266{
267 u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
268 u16 mimo_antsel = 0;
269
270 if (asi->antsel_type == ANTSEL_2x4) {
271 /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
272 mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
273 return mimo_antsel;
274
275 } else if (asi->antsel_type == ANTSEL_2x3) {
276 /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
277 mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
278 return mimo_antsel;
279 }
280
281 return mimo_antsel;
282}
283
284/* boardlevel antenna selection: ucode interface control */
285static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
286 struct brcms_antselcfg *antsel)
287{
288 struct brcms_c_info *wlc = asi->wlc;
289 u8 ant_cfg;
290 u16 mimo_antsel;
291
292 /* 1) Update TX antconfig for all frames that are not unicast data
293 * (aka default TX)
294 */
295 ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
296 mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
297 brcms_c_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
298 /* Update driver stats for currently selected default tx/rx antenna config */
299 asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
300
301 /* 2) Update RX antconfig for all frames that are not unicast data
302 * (aka default RX)
303 */
304 ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
305 mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
306 brcms_c_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
307 /* Update driver stats for currently selected default tx/rx antenna config */
308 asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
309
310 return 0;
311}
diff --git a/drivers/staging/brcm80211/brcmsmac/antsel.h b/drivers/staging/brcm80211/brcmsmac/antsel.h
new file mode 100644
index 00000000000..97ea3881a8e
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/antsel.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_ANTSEL_H_
18#define _BRCM_ANTSEL_H_
19
20extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
21extern void brcms_c_antsel_detach(struct antsel_info *asi);
22extern void brcms_c_antsel_init(struct antsel_info *asi);
23extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
24 bool sel,
25 u8 id, u8 fbid, u8 *antcfg,
26 u8 *fbantcfg);
27extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
28
29#endif /* _BRCM_ANTSEL_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/bmac.c b/drivers/staging/brcm80211/brcmsmac/bmac.c
new file mode 100644
index 00000000000..b25c5170556
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/bmac.c
@@ -0,0 +1,3593 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/pci.h>
17#include <net/mac80211.h>
18
19#include <brcm_hw_ids.h>
20#include <aiutils.h>
21#include <chipcommon.h>
22#include "types.h"
23#include "rate.h"
24#include "phy/phy_hal.h"
25#include "channel.h"
26#include "main.h"
27#include "ucode_loader.h"
28#include "mac80211_if.h"
29#include "bmac.h"
30
31#define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */
32
33#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */
34#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us, default */
35#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us, default */
36#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */
37
38#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */
39
40#ifndef BMAC_DUP_TO_REMOVE
41
42#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */
43
44#endif /* BMAC_DUP_TO_REMOVE */
45
46#define DMAREG(wlc_hw, direction, fifonum) \
47 ((direction == DMA_TX) ? \
48 (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmaxmt) : \
49 (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmarcv))
50
51#define APHY_SLOT_TIME 9
52#define BPHY_SLOT_TIME 20
53
54/*
55 * The following table lists the buffer memory allocated to xmt fifos in HW.
56 * the size is in units of 256bytes(one block), total size is HW dependent
57 * ucode has default fifo partition, sw can overwrite if necessary
58 *
59 * This is documented in twiki under the topic UcodeTxFifo. Please ensure
60 * the twiki is updated before making changes.
61 */
62
63#define XMTFIFOTBL_STARTREV 20 /* Starting corerev for the fifo size table */
64
65static u16 xmtfifo_sz[][NFIFO] = {
66 {20, 192, 192, 21, 17, 5}, /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
67 {9, 58, 22, 14, 14, 5}, /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
68 {20, 192, 192, 21, 17, 5}, /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
69 {20, 192, 192, 21, 17, 5}, /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
70 {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
71};
72
73static void brcms_b_clkctl_clk(struct brcms_hardware *wlc, uint mode);
74static void brcms_b_coreinit(struct brcms_c_info *wlc);
75
76/* used by wlc_wakeucode_init() */
77static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
78 const struct d11init *inits);
79static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[],
80 const uint nbytes);
81static void brcms_ucode_download(struct brcms_hardware *wlc);
82static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw);
83
84/* used by brcms_c_dpc() */
85static bool brcms_b_dotxstatus(struct brcms_hardware *wlc,
86 struct tx_status *txs, u32 s2);
87static bool brcms_b_txstatus(struct brcms_hardware *wlc, bool bound,
88 bool *fatal);
89static bool brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound);
90
91/* used by brcms_c_down() */
92static void brcms_c_flushqueues(struct brcms_c_info *wlc);
93
94static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs);
95static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw);
96static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw);
97static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw,
98 uint tx_fifo);
99static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
100 uint tx_fifo);
101static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
102 uint tx_fifo);
103
104/* Low Level Prototypes */
105static int brcms_b_bandtype(struct brcms_hardware *wlc_hw);
106static void brcms_b_info_init(struct brcms_hardware *wlc_hw);
107static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want);
108static u16 brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset,
109 u32 sel);
110static void brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset,
111 u16 v, u32 sel);
112static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk);
113static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme);
114static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw);
115static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw);
116static bool brcms_c_validboardtype(struct brcms_hardware *wlc);
117static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw);
118static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw);
119static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw);
120static void brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init);
121static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw);
122static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool want,
123 mbool flags);
124static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw);
125static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw);
126static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc);
127static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask);
128static void brcms_c_gpio_init(struct brcms_c_info *wlc);
129static void brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw,
130 void *bcn, int len);
131static void brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw,
132 void *bcn, int len);
133static void brcms_b_bsinit(struct brcms_c_info *wlc, chanspec_t chanspec);
134static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit);
135static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
136 chanspec_t chanspec);
137static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
138 bool shortslot);
139static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw);
140static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
141 u8 rate);
142
143/* === Low Level functions === */
144
145void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
146{
147 wlc_hw->shortslot = shortslot;
148
149 if (BAND_2G(brcms_b_bandtype(wlc_hw)) && wlc_hw->up) {
150 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
151 brcms_b_update_slot_timing(wlc_hw, shortslot);
152 brcms_c_enable_mac(wlc_hw->wlc);
153 }
154}
155
156/*
157 * Update the slot timing for standard 11b/g (20us slots)
158 * or shortslot 11g (9us slots)
159 * The PSM needs to be suspended for this call.
160 */
161static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
162 bool shortslot)
163{
164 d11regs_t *regs;
165
166 regs = wlc_hw->regs;
167
168 if (shortslot) {
169 /* 11g short slot: 11a timing */
170 W_REG(&regs->ifs_slot, 0x0207); /* APHY_SLOT_TIME */
171 brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
172 } else {
173 /* 11g long slot: 11b timing */
174 W_REG(&regs->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */
175 brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
176 }
177}
178
179static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
180{
181 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
182
183 /* init microcode host flags */
184 brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
185
186 /* do band-specific ucode IHR, SHM, and SCR inits */
187 if (D11REV_IS(wlc_hw->corerev, 23)) {
188 if (BRCMS_ISNPHY(wlc_hw->band)) {
189 brcms_c_write_inits(wlc_hw, d11n0bsinitvals16);
190 } else {
191 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
192 " %d\n", __func__, wlc_hw->unit,
193 wlc_hw->corerev);
194 }
195 } else {
196 if (D11REV_IS(wlc_hw->corerev, 24)) {
197 if (BRCMS_ISLCNPHY(wlc_hw->band)) {
198 brcms_c_write_inits(wlc_hw,
199 d11lcn0bsinitvals24);
200 } else
201 wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
202 " core rev %d\n", __func__,
203 wlc_hw->unit, wlc_hw->corerev);
204 } else {
205 wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
206 __func__, wlc_hw->unit, wlc_hw->corerev);
207 }
208 }
209}
210
211/* switch to new band but leave it inactive */
212static u32 brcms_c_setband_inact(struct brcms_c_info *wlc,
213 uint bandunit)
214{
215 struct brcms_hardware *wlc_hw = wlc->hw;
216 u32 macintmask;
217
218 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
219
220 WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
221
222 /* disable interrupts */
223 macintmask = brcms_intrsoff(wlc->wl);
224
225 /* radio off */
226 wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
227
228 brcms_b_core_phy_clk(wlc_hw, OFF);
229
230 brcms_c_setxband(wlc_hw, bandunit);
231
232 return macintmask;
233}
234
235/* Process received frames */
236/*
237 * Return true if more frames need to be processed. false otherwise.
238 * Param 'bound' indicates max. # frames to process before break out.
239 */
240static bool
241brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
242{
243 struct sk_buff *p;
244 struct sk_buff *head = NULL;
245 struct sk_buff *tail = NULL;
246 uint n = 0;
247 uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1;
248 struct brcms_d11rxhdr *wlc_rxhdr = NULL;
249
250 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
251 /* gather received frames */
252 while ((p = dma_rx(wlc_hw->di[fifo]))) {
253
254 if (!tail)
255 head = tail = p;
256 else {
257 tail->prev = p;
258 tail = p;
259 }
260
261 /* !give others some time to run! */
262 if (++n >= bound_limit)
263 break;
264 }
265
266 /* post more rbufs */
267 dma_rxfill(wlc_hw->di[fifo]);
268
269 /* process each frame */
270 while ((p = head) != NULL) {
271 head = head->prev;
272 p->prev = NULL;
273
274 wlc_rxhdr = (struct brcms_d11rxhdr *) p->data;
275
276 /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */
277 wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr);
278
279 brcms_c_recv(wlc_hw->wlc, p);
280 }
281
282 return n >= bound_limit;
283}
284
285/* second-level interrupt processing
286 * Return true if another dpc needs to be re-scheduled. false otherwise.
287 * Param 'bounded' indicates if applicable loops should be bounded.
288 */
289bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
290{
291 u32 macintstatus;
292 struct brcms_hardware *wlc_hw = wlc->hw;
293 d11regs_t *regs = wlc_hw->regs;
294 bool fatal = false;
295 struct wiphy *wiphy = wlc->wiphy;
296
297 if (DEVICEREMOVED(wlc)) {
298 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
299 __func__);
300 brcms_down(wlc->wl);
301 return false;
302 }
303
304 /* grab and clear the saved software intstatus bits */
305 macintstatus = wlc->macintstatus;
306 wlc->macintstatus = 0;
307
308 BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
309 wlc_hw->unit, macintstatus);
310
311 WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
312
313 /* BCN template is available */
314 /* ZZZ: Use AP_ACTIVE ? */
315 if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub))
316 && (macintstatus & MI_BCNTPL)) {
317 brcms_c_update_beacon(wlc);
318 }
319
320 /* tx status */
321 if (macintstatus & MI_TFS) {
322 if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
323 wlc->macintstatus |= MI_TFS;
324 if (fatal) {
325 wiphy_err(wiphy, "MI_TFS: fatal\n");
326 goto fatal;
327 }
328 }
329
330 if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
331 brcms_c_tbtt(wlc);
332
333 /* ATIM window end */
334 if (macintstatus & MI_ATIMWINEND) {
335 BCMMSG(wlc->wiphy, "end of ATIM window\n");
336 OR_REG(&regs->maccommand, wlc->qvalid);
337 wlc->qvalid = 0;
338 }
339
340 /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */
341 if (macintstatus & MI_DMAINT)
342 if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
343 wlc->macintstatus |= MI_DMAINT;
344
345 /* TX FIFO suspend/flush completion */
346 if (macintstatus & MI_TXSTOP)
347 brcms_b_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO);
348
349 /* noise sample collected */
350 if (macintstatus & MI_BG_NOISE) {
351 wlc_phy_noise_sample_intr(wlc_hw->band->pi);
352 }
353
354 if (macintstatus & MI_GP0) {
355 wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
356 "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
357
358 printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
359 __func__, wlc_hw->sih->chip,
360 wlc_hw->sih->chiprev);
361 /* big hammer */
362 brcms_init(wlc->wl);
363 }
364
365 /* gptimer timeout */
366 if (macintstatus & MI_TO) {
367 W_REG(&regs->gptimer, 0);
368 }
369
370 if (macintstatus & MI_RFDISABLE) {
371 BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
372 " RF Disable Input\n", wlc_hw->unit);
373 brcms_rfkill_set_hw_state(wlc->wl);
374 }
375
376 /* send any enq'd tx packets. Just makes sure to jump start tx */
377 if (!pktq_empty(&wlc->pkt_queue->q))
378 brcms_c_send_q(wlc);
379
380 /* it isn't done and needs to be resched if macintstatus is non-zero */
381 return wlc->macintstatus != 0;
382
383 fatal:
384 brcms_init(wlc->wl);
385 return wlc->macintstatus != 0;
386}
387
388/* common low-level watchdog code */
389void brcms_b_watchdog(void *arg)
390{
391 struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
392 struct brcms_hardware *wlc_hw = wlc->hw;
393
394 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
395
396 if (!wlc_hw->up)
397 return;
398
399 /* increment second count */
400 wlc_hw->now++;
401
402 /* Check for FIFO error interrupts */
403 brcms_b_fifoerrors(wlc_hw);
404
405 /* make sure RX dma has buffers */
406 dma_rxfill(wlc->hw->di[RX_FIFO]);
407
408 wlc_phy_watchdog(wlc_hw->band->pi);
409}
410
411void
412brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, chanspec_t chanspec,
413 bool mute, struct txpwr_limits *txpwr)
414{
415 uint bandunit;
416
417 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
418
419 wlc_hw->chanspec = chanspec;
420
421 /* Switch bands if necessary */
422 if (NBANDS_HW(wlc_hw) > 1) {
423 bandunit = CHSPEC_BANDUNIT(chanspec);
424 if (wlc_hw->band->bandunit != bandunit) {
425 /* brcms_b_setband disables other bandunit,
426 * use light band switch if not up yet
427 */
428 if (wlc_hw->up) {
429 wlc_phy_chanspec_radio_set(wlc_hw->
430 bandstate[bandunit]->
431 pi, chanspec);
432 brcms_b_setband(wlc_hw, bandunit, chanspec);
433 } else {
434 brcms_c_setxband(wlc_hw, bandunit);
435 }
436 }
437 }
438
439 wlc_phy_initcal_enable(wlc_hw->band->pi, !mute);
440
441 if (!wlc_hw->up) {
442 if (wlc_hw->clk)
443 wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
444 chanspec);
445 wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
446 } else {
447 wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
448 wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
449
450 /* Update muting of the channel */
451 brcms_b_mute(wlc_hw, mute, 0);
452 }
453}
454
455int brcms_b_state_get(struct brcms_hardware *wlc_hw,
456 struct brcms_b_state *state)
457{
458 state->machwcap = wlc_hw->machwcap;
459
460 return 0;
461}
462
463static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
464{
465 uint i;
466 char name[8];
467 /* ucode host flag 2 needed for pio mode, independent of band and fifo */
468 u16 pio_mhf2 = 0;
469 struct brcms_hardware *wlc_hw = wlc->hw;
470 uint unit = wlc_hw->unit;
471 struct brcms_tunables *tune = wlc->pub->tunables;
472 struct wiphy *wiphy = wlc->wiphy;
473
474 /* name and offsets for dma_attach */
475 snprintf(name, sizeof(name), "wl%d", unit);
476
477 if (wlc_hw->di[0] == 0) { /* Init FIFOs */
478 uint addrwidth;
479 int dma_attach_err = 0;
480 /* Find out the DMA addressing capability and let OS know
481 * All the channels within one DMA core have 'common-minimum' same
482 * capability
483 */
484 addrwidth =
485 dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0));
486
487 if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) {
488 wiphy_err(wiphy, "wl%d: wlc_attach: alloc_dma_"
489 "resources failed\n", unit);
490 return false;
491 }
492
493 /*
494 * FIFO 0
495 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
496 * RX: RX_FIFO (RX data packets)
497 */
498 wlc_hw->di[0] = dma_attach(name, wlc_hw->sih,
499 (wme ? DMAREG(wlc_hw, DMA_TX, 0) :
500 NULL), DMAREG(wlc_hw, DMA_RX, 0),
501 (wme ? tune->ntxd : 0), tune->nrxd,
502 tune->rxbufsz, -1, tune->nrxbufpost,
503 BRCMS_HWRXOFF, &brcm_msg_level);
504 dma_attach_err |= (NULL == wlc_hw->di[0]);
505
506 /*
507 * FIFO 1
508 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
509 * (legacy) TX_DATA_FIFO (TX data packets)
510 * RX: UNUSED
511 */
512 wlc_hw->di[1] = dma_attach(name, wlc_hw->sih,
513 DMAREG(wlc_hw, DMA_TX, 1), NULL,
514 tune->ntxd, 0, 0, -1, 0, 0,
515 &brcm_msg_level);
516 dma_attach_err |= (NULL == wlc_hw->di[1]);
517
518 /*
519 * FIFO 2
520 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
521 * RX: UNUSED
522 */
523 wlc_hw->di[2] = dma_attach(name, wlc_hw->sih,
524 DMAREG(wlc_hw, DMA_TX, 2), NULL,
525 tune->ntxd, 0, 0, -1, 0, 0,
526 &brcm_msg_level);
527 dma_attach_err |= (NULL == wlc_hw->di[2]);
528 /*
529 * FIFO 3
530 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
531 * (legacy) TX_CTL_FIFO (TX control & mgmt packets)
532 */
533 wlc_hw->di[3] = dma_attach(name, wlc_hw->sih,
534 DMAREG(wlc_hw, DMA_TX, 3),
535 NULL, tune->ntxd, 0, 0, -1,
536 0, 0, &brcm_msg_level);
537 dma_attach_err |= (NULL == wlc_hw->di[3]);
538/* Cleaner to leave this as if with AP defined */
539
540 if (dma_attach_err) {
541 wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
542 "\n", unit);
543 return false;
544 }
545
546 /* get pointer to dma engine tx flow control variable */
547 for (i = 0; i < NFIFO; i++)
548 if (wlc_hw->di[i])
549 wlc_hw->txavail[i] =
550 (uint *) dma_getvar(wlc_hw->di[i],
551 "&txavail");
552 }
553
554 /* initial ucode host flags */
555 brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
556
557 return true;
558}
559
560static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw)
561{
562 uint j;
563
564 for (j = 0; j < NFIFO; j++) {
565 if (wlc_hw->di[j]) {
566 dma_detach(wlc_hw->di[j]);
567 wlc_hw->di[j] = NULL;
568 }
569 }
570}
571
572/* low level attach
573 * run backplane attach, init nvram
574 * run phy attach
575 * initialize software state for each core and band
576 * put the whole chip in reset(driver down state), no clock
577 */
578int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device, uint unit,
579 bool piomode, void *regsva, uint bustype, void *btparam)
580{
581 struct brcms_hardware *wlc_hw;
582 d11regs_t *regs;
583 char *macaddr = NULL;
584 char *vars;
585 uint err = 0;
586 uint j;
587 bool wme = false;
588 struct shared_phy_params sha_params;
589 struct wiphy *wiphy = wlc->wiphy;
590
591 BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor,
592 device);
593
594 wme = true;
595
596 wlc_hw = wlc->hw;
597 wlc_hw->wlc = wlc;
598 wlc_hw->unit = unit;
599 wlc_hw->band = wlc_hw->bandstate[0];
600 wlc_hw->_piomode = piomode;
601
602 /* populate struct brcms_hardware with default values */
603 brcms_b_info_init(wlc_hw);
604
605 /*
606 * Do the hardware portion of the attach.
607 * Also initialize software state that depends on the particular hardware
608 * we are running.
609 */
610 wlc_hw->sih = ai_attach(regsva, bustype, btparam,
611 &wlc_hw->vars, &wlc_hw->vars_size);
612 if (wlc_hw->sih == NULL) {
613 wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n",
614 unit);
615 err = 11;
616 goto fail;
617 }
618 vars = wlc_hw->vars;
619
620 /*
621 * Get vendid/devid nvram overwrites, which could be different
622 * than those the BIOS recognizes for devices on PCMCIA_BUS,
623 * SDIO_BUS, and SROMless devices on PCI_BUS.
624 */
625#ifdef BCMBUSTYPE
626 bustype = BCMBUSTYPE;
627#endif
628 if (bustype != SI_BUS) {
629 char *var;
630
631 var = getvar(vars, "vendid");
632 if (var) {
633 vendor = (u16) simple_strtoul(var, NULL, 0);
634 wiphy_err(wiphy, "Overriding vendor id = 0x%x\n",
635 vendor);
636 }
637 var = getvar(vars, "devid");
638 if (var) {
639 u16 devid = (u16) simple_strtoul(var, NULL, 0);
640 if (devid != 0xffff) {
641 device = devid;
642 wiphy_err(wiphy, "Overriding device id = 0x%x"
643 "\n", device);
644 }
645 }
646
647 /* verify again the device is supported */
648 if (!brcms_c_chipmatch(vendor, device)) {
649 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
650 "vendor/device (0x%x/0x%x)\n",
651 unit, vendor, device);
652 err = 12;
653 goto fail;
654 }
655 }
656
657 wlc_hw->vendorid = vendor;
658 wlc_hw->deviceid = device;
659
660 /* set bar0 window to point at D11 core */
661 wlc_hw->regs = (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
662 wlc_hw->corerev = ai_corerev(wlc_hw->sih);
663
664 regs = wlc_hw->regs;
665
666 wlc->regs = wlc_hw->regs;
667
668 /* validate chip, chiprev and corerev */
669 if (!brcms_c_isgoodchip(wlc_hw)) {
670 err = 13;
671 goto fail;
672 }
673
674 /* initialize power control registers */
675 ai_clkctl_init(wlc_hw->sih);
676
677 /* request fastclock and force fastclock for the rest of attach
678 * bring the d11 core out of reset.
679 * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false;
680 * But it will be called again inside wlc_corereset, after d11 is out of reset.
681 */
682 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
683 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
684
685 if (!brcms_b_validate_chip_access(wlc_hw)) {
686 wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access "
687 "failed\n", unit);
688 err = 14;
689 goto fail;
690 }
691
692 /* get the board rev, used just below */
693 j = getintvar(vars, "boardrev");
694 /* promote srom boardrev of 0xFF to 1 */
695 if (j == BOARDREV_PROMOTABLE)
696 j = BOARDREV_PROMOTED;
697 wlc_hw->boardrev = (u16) j;
698 if (!brcms_c_validboardtype(wlc_hw)) {
699 wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom "
700 "board type (0x%x)" " or revision level (0x%x)\n",
701 unit, wlc_hw->sih->boardtype, wlc_hw->boardrev);
702 err = 15;
703 goto fail;
704 }
705 wlc_hw->sromrev = (u8) getintvar(vars, "sromrev");
706 wlc_hw->boardflags = (u32) getintvar(vars, "boardflags");
707 wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2");
708
709 if (wlc_hw->boardflags & BFL_NOPLLDOWN)
710 brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
711
712 if ((wlc_hw->sih->bustype == PCI_BUS)
713 && (ai_pci_war16165(wlc_hw->sih)))
714 wlc->war16165 = true;
715
716 /* check device id(srom, nvram etc.) to set bands */
717 if (wlc_hw->deviceid == BCM43224_D11N_ID ||
718 wlc_hw->deviceid == BCM43224_D11N_ID_VEN1) {
719 /* Dualband boards */
720 wlc_hw->_nbands = 2;
721 } else
722 wlc_hw->_nbands = 1;
723
724 if ((wlc_hw->sih->chip == BCM43225_CHIP_ID))
725 wlc_hw->_nbands = 1;
726
727 /* BMAC_NOTE: remove init of pub values when brcms_c_attach()
728 * unconditionally does the init of these values
729 */
730 wlc->vendorid = wlc_hw->vendorid;
731 wlc->deviceid = wlc_hw->deviceid;
732 wlc->pub->sih = wlc_hw->sih;
733 wlc->pub->corerev = wlc_hw->corerev;
734 wlc->pub->sromrev = wlc_hw->sromrev;
735 wlc->pub->boardrev = wlc_hw->boardrev;
736 wlc->pub->boardflags = wlc_hw->boardflags;
737 wlc->pub->boardflags2 = wlc_hw->boardflags2;
738 wlc->pub->_nbands = wlc_hw->_nbands;
739
740 wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
741
742 if (wlc_hw->physhim == NULL) {
743 wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach "
744 "failed\n", unit);
745 err = 25;
746 goto fail;
747 }
748
749 /* pass all the parameters to wlc_phy_shared_attach in one struct */
750 sha_params.sih = wlc_hw->sih;
751 sha_params.physhim = wlc_hw->physhim;
752 sha_params.unit = unit;
753 sha_params.corerev = wlc_hw->corerev;
754 sha_params.vars = vars;
755 sha_params.vid = wlc_hw->vendorid;
756 sha_params.did = wlc_hw->deviceid;
757 sha_params.chip = wlc_hw->sih->chip;
758 sha_params.chiprev = wlc_hw->sih->chiprev;
759 sha_params.chippkg = wlc_hw->sih->chippkg;
760 sha_params.sromrev = wlc_hw->sromrev;
761 sha_params.boardtype = wlc_hw->sih->boardtype;
762 sha_params.boardrev = wlc_hw->boardrev;
763 sha_params.boardvendor = wlc_hw->sih->boardvendor;
764 sha_params.boardflags = wlc_hw->boardflags;
765 sha_params.boardflags2 = wlc_hw->boardflags2;
766 sha_params.bustype = wlc_hw->sih->bustype;
767 sha_params.buscorerev = wlc_hw->sih->buscorerev;
768
769 /* alloc and save pointer to shared phy state area */
770 wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
771 if (!wlc_hw->phy_sh) {
772 err = 16;
773 goto fail;
774 }
775
776 /* initialize software state for each core and band */
777 for (j = 0; j < NBANDS_HW(wlc_hw); j++) {
778 /*
779 * band0 is always 2.4Ghz
780 * band1, if present, is 5Ghz
781 */
782
783 /* So if this is a single band 11a card, use band 1 */
784 if (IS_SINGLEBAND_5G(wlc_hw->deviceid))
785 j = BAND_5G_INDEX;
786
787 brcms_c_setxband(wlc_hw, j);
788
789 wlc_hw->band->bandunit = j;
790 wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
791 wlc->band->bandunit = j;
792 wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
793 wlc->core->coreidx = ai_coreidx(wlc_hw->sih);
794
795 wlc_hw->machwcap = R_REG(&regs->machwcap);
796 wlc_hw->machwcap_backup = wlc_hw->machwcap;
797
798 /* init tx fifo size */
799 wlc_hw->xmtfifo_sz =
800 xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
801
802 /* Get a phy for this band */
803 wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh,
804 (void *)regs, brcms_b_bandtype(wlc_hw), vars,
805 wlc->wiphy);
806 if (wlc_hw->band->pi == NULL) {
807 wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_"
808 "attach failed\n", unit);
809 err = 17;
810 goto fail;
811 }
812
813 wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
814
815 wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
816 &wlc_hw->band->phyrev,
817 &wlc_hw->band->radioid,
818 &wlc_hw->band->radiorev);
819 wlc_hw->band->abgphy_encore =
820 wlc_phy_get_encore(wlc_hw->band->pi);
821 wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
822 wlc_hw->band->core_flags =
823 wlc_phy_get_coreflags(wlc_hw->band->pi);
824
825 /* verify good phy_type & supported phy revision */
826 if (BRCMS_ISNPHY(wlc_hw->band)) {
827 if (NCONF_HAS(wlc_hw->band->phyrev))
828 goto good_phy;
829 else
830 goto bad_phy;
831 } else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
832 if (LCNCONF_HAS(wlc_hw->band->phyrev))
833 goto good_phy;
834 else
835 goto bad_phy;
836 } else {
837 bad_phy:
838 wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported "
839 "phy type/rev (%d/%d)\n", unit,
840 wlc_hw->band->phytype, wlc_hw->band->phyrev);
841 err = 18;
842 goto fail;
843 }
844
845 good_phy:
846 /* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the
847 * high level attach. However we can not make that change until all low level access
848 * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping
849 * wlc_hw->band->pi as well for incremental update of low level fns, and cut over
850 * low only init when all fns updated.
851 */
852 wlc->band->pi = wlc_hw->band->pi;
853 wlc->band->phytype = wlc_hw->band->phytype;
854 wlc->band->phyrev = wlc_hw->band->phyrev;
855 wlc->band->radioid = wlc_hw->band->radioid;
856 wlc->band->radiorev = wlc_hw->band->radiorev;
857
858 /* default contention windows size limits */
859 wlc_hw->band->CWmin = APHY_CWMIN;
860 wlc_hw->band->CWmax = PHY_CWMAX;
861
862 if (!brcms_b_attach_dmapio(wlc, j, wme)) {
863 err = 19;
864 goto fail;
865 }
866 }
867
868 /* disable core to match driver "down" state */
869 brcms_c_coredisable(wlc_hw);
870
871 /* Match driver "down" state */
872 if (wlc_hw->sih->bustype == PCI_BUS)
873 ai_pci_down(wlc_hw->sih);
874
875 /* register sb interrupt callback functions */
876 ai_register_intr_callback(wlc_hw->sih, (void *)brcms_c_wlintrsoff,
877 (void *)brcms_c_wlintrsrestore, NULL, wlc);
878
879 /* turn off pll and xtal to match driver "down" state */
880 brcms_b_xtal(wlc_hw, OFF);
881
882 /* *********************************************************************
883 * The hardware is in the DOWN state at this point. D11 core
884 * or cores are in reset with clocks off, and the board PLLs
885 * are off if possible.
886 *
887 * Beyond this point, wlc->sbclk == false and chip registers
888 * should not be touched.
889 *********************************************************************
890 */
891
892 /* init etheraddr state variables */
893 macaddr = brcms_c_get_macaddr(wlc_hw);
894 if (macaddr == NULL) {
895 wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n",
896 unit);
897 err = 21;
898 goto fail;
899 }
900 brcmu_ether_atoe(macaddr, wlc_hw->etheraddr);
901 if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
902 is_zero_ether_addr(wlc_hw->etheraddr)) {
903 wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n",
904 unit, macaddr);
905 err = 22;
906 goto fail;
907 }
908
909 BCMMSG(wlc->wiphy,
910 "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
911 wlc_hw->deviceid, wlc_hw->_nbands,
912 wlc_hw->sih->boardtype, macaddr);
913
914 return err;
915
916 fail:
917 wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit,
918 err);
919 return err;
920}
921
922/*
923 * Initialize brcms_c_info default values ...
924 * may get overrides later in this function
925 * BMAC_NOTES, move low out and resolve the dangling ones
926 */
927static void brcms_b_info_init(struct brcms_hardware *wlc_hw)
928{
929 struct brcms_c_info *wlc = wlc_hw->wlc;
930
931 /* set default sw macintmask value */
932 wlc->defmacintmask = DEF_MACINTMASK;
933
934 /* various 802.11g modes */
935 wlc_hw->shortslot = false;
936
937 wlc_hw->SFBL = RETRY_SHORT_FB;
938 wlc_hw->LFBL = RETRY_LONG_FB;
939
940 /* default mac retry limits */
941 wlc_hw->SRL = RETRY_SHORT_DEF;
942 wlc_hw->LRL = RETRY_LONG_DEF;
943 wlc_hw->chanspec = CH20MHZ_CHSPEC(1);
944}
945
946/*
947 * low level detach
948 */
949int brcms_b_detach(struct brcms_c_info *wlc)
950{
951 uint i;
952 struct brcms_hw_band *band;
953 struct brcms_hardware *wlc_hw = wlc->hw;
954 int callbacks;
955
956 callbacks = 0;
957
958 if (wlc_hw->sih) {
959 /* detach interrupt sync mechanism since interrupt is disabled and per-port
960 * interrupt object may has been freed. this must be done before sb core switch
961 */
962 ai_deregister_intr_callback(wlc_hw->sih);
963
964 if (wlc_hw->sih->bustype == PCI_BUS)
965 ai_pci_sleep(wlc_hw->sih);
966 }
967
968 brcms_b_detach_dmapio(wlc_hw);
969
970 band = wlc_hw->band;
971 for (i = 0; i < NBANDS_HW(wlc_hw); i++) {
972 if (band->pi) {
973 /* Detach this band's phy */
974 wlc_phy_detach(band->pi);
975 band->pi = NULL;
976 }
977 band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
978 }
979
980 /* Free shared phy state */
981 kfree(wlc_hw->phy_sh);
982
983 wlc_phy_shim_detach(wlc_hw->physhim);
984
985 /* free vars */
986 kfree(wlc_hw->vars);
987 wlc_hw->vars = NULL;
988
989 if (wlc_hw->sih) {
990 ai_detach(wlc_hw->sih);
991 wlc_hw->sih = NULL;
992 }
993
994 return callbacks;
995
996}
997
998void brcms_b_reset(struct brcms_hardware *wlc_hw)
999{
1000 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1001
1002 /* reset the core */
1003 if (!DEVICEREMOVED(wlc_hw->wlc))
1004 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
1005
1006 /* purge the dma rings */
1007 brcms_c_flushqueues(wlc_hw->wlc);
1008
1009 brcms_c_reset_bmac_done(wlc_hw->wlc);
1010}
1011
1012void
1013brcms_b_init(struct brcms_hardware *wlc_hw, chanspec_t chanspec,
1014 bool mute) {
1015 u32 macintmask;
1016 bool fastclk;
1017 struct brcms_c_info *wlc = wlc_hw->wlc;
1018
1019 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1020
1021 /* request FAST clock if not on */
1022 fastclk = wlc_hw->forcefastclk;
1023 if (!fastclk)
1024 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
1025
1026 /* disable interrupts */
1027 macintmask = brcms_intrsoff(wlc->wl);
1028
1029 /* set up the specified band and chanspec */
1030 brcms_c_setxband(wlc_hw, CHSPEC_BANDUNIT(chanspec));
1031 wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
1032
1033 /* do one-time phy inits and calibration */
1034 wlc_phy_cal_init(wlc_hw->band->pi);
1035
1036 /* core-specific initialization */
1037 brcms_b_coreinit(wlc);
1038
1039 /* suspend the tx fifos and mute the phy for preism cac time */
1040 if (mute)
1041 brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM);
1042
1043 /* band-specific inits */
1044 brcms_b_bsinit(wlc, chanspec);
1045
1046 /* restore macintmask */
1047 brcms_intrsrestore(wlc->wl, macintmask);
1048
1049 /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac
1050 * is suspended and brcms_c_enable_mac() will clear this override bit.
1051 */
1052 mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
1053
1054 /*
1055 * initialize mac_suspend_depth to 1 to match ucode initial suspended state
1056 */
1057 wlc_hw->mac_suspend_depth = 1;
1058
1059 /* restore the clk */
1060 if (!fastclk)
1061 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
1062}
1063
1064int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
1065{
1066 uint coremask;
1067
1068 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1069
1070 /*
1071 * Enable pll and xtal, initialize the power control registers,
1072 * and force fastclock for the remainder of brcms_c_up().
1073 */
1074 brcms_b_xtal(wlc_hw, ON);
1075 ai_clkctl_init(wlc_hw->sih);
1076 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
1077
1078 /*
1079 * Configure pci/pcmcia here instead of in brcms_c_attach()
1080 * to allow mfg hotswap: down, hotswap (chip power cycle), up.
1081 */
1082 coremask = (1 << wlc_hw->wlc->core->coreidx);
1083
1084 if (wlc_hw->sih->bustype == PCI_BUS)
1085 ai_pci_setup(wlc_hw->sih, coremask);
1086
1087 /*
1088 * Need to read the hwradio status here to cover the case where the system
1089 * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
1090 */
1091 if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
1092 /* put SB PCI in down state again */
1093 if (wlc_hw->sih->bustype == PCI_BUS)
1094 ai_pci_down(wlc_hw->sih);
1095 brcms_b_xtal(wlc_hw, OFF);
1096 return -ENOMEDIUM;
1097 }
1098
1099 if (wlc_hw->sih->bustype == PCI_BUS)
1100 ai_pci_up(wlc_hw->sih);
1101
1102 /* reset the d11 core */
1103 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
1104
1105 return 0;
1106}
1107
1108int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
1109{
1110 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1111
1112 wlc_hw->up = true;
1113 wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
1114
1115 /* FULLY enable dynamic power control and d11 core interrupt */
1116 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
1117 brcms_intrson(wlc_hw->wlc->wl);
1118 return 0;
1119}
1120
1121int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
1122{
1123 bool dev_gone;
1124 uint callbacks = 0;
1125
1126 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1127
1128 if (!wlc_hw->up)
1129 return callbacks;
1130
1131 dev_gone = DEVICEREMOVED(wlc_hw->wlc);
1132
1133 /* disable interrupts */
1134 if (dev_gone)
1135 wlc_hw->wlc->macintmask = 0;
1136 else {
1137 /* now disable interrupts */
1138 brcms_intrsoff(wlc_hw->wlc->wl);
1139
1140 /* ensure we're running on the pll clock again */
1141 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
1142 }
1143 /* down phy at the last of this stage */
1144 callbacks += wlc_phy_down(wlc_hw->band->pi);
1145
1146 return callbacks;
1147}
1148
1149int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
1150{
1151 uint callbacks = 0;
1152 bool dev_gone;
1153
1154 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1155
1156 if (!wlc_hw->up)
1157 return callbacks;
1158
1159 wlc_hw->up = false;
1160 wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
1161
1162 dev_gone = DEVICEREMOVED(wlc_hw->wlc);
1163
1164 if (dev_gone) {
1165 wlc_hw->sbclk = false;
1166 wlc_hw->clk = false;
1167 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
1168
1169 /* reclaim any posted packets */
1170 brcms_c_flushqueues(wlc_hw->wlc);
1171 } else {
1172
1173 /* Reset and disable the core */
1174 if (ai_iscoreup(wlc_hw->sih)) {
1175 if (R_REG(&wlc_hw->regs->maccontrol) &
1176 MCTL_EN_MAC)
1177 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
1178 callbacks += brcms_reset(wlc_hw->wlc->wl);
1179 brcms_c_coredisable(wlc_hw);
1180 }
1181
1182 /* turn off primary xtal and pll */
1183 if (!wlc_hw->noreset) {
1184 if (wlc_hw->sih->bustype == PCI_BUS)
1185 ai_pci_down(wlc_hw->sih);
1186 brcms_b_xtal(wlc_hw, OFF);
1187 }
1188 }
1189
1190 return callbacks;
1191}
1192
1193void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
1194{
1195 /* delay before first read of ucode state */
1196 udelay(40);
1197
1198 /* wait until ucode is no longer asleep */
1199 SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) ==
1200 DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
1201}
1202
1203void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw, u8 *ea)
1204{
1205 memcpy(ea, wlc_hw->etheraddr, ETH_ALEN);
1206}
1207
1208static int brcms_b_bandtype(struct brcms_hardware *wlc_hw)
1209{
1210 return wlc_hw->band->bandtype;
1211}
1212
1213/* control chip clock to save power, enable dynamic clock or force fast clock */
1214static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode)
1215{
1216 if (PMUCTL_ENAB(wlc_hw->sih)) {
1217 /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane,
1218 * but mac core will still run on ALP(not HT) when it enters powersave mode,
1219 * which means the FCA bit may not be set.
1220 * should wakeup mac if driver wants it to run on HT.
1221 */
1222
1223 if (wlc_hw->clk) {
1224 if (mode == CLK_FAST) {
1225 OR_REG(&wlc_hw->regs->clk_ctl_st,
1226 CCS_FORCEHT);
1227
1228 udelay(64);
1229
1230 SPINWAIT(((R_REG
1231 (&wlc_hw->regs->
1232 clk_ctl_st) & CCS_HTAVAIL) == 0),
1233 PMU_MAX_TRANSITION_DLY);
1234 WARN_ON(!(R_REG
1235 (&wlc_hw->regs->
1236 clk_ctl_st) & CCS_HTAVAIL));
1237 } else {
1238 if ((wlc_hw->sih->pmurev == 0) &&
1239 (R_REG
1240 (&wlc_hw->regs->
1241 clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ)))
1242 SPINWAIT(((R_REG
1243 (&wlc_hw->regs->
1244 clk_ctl_st) & CCS_HTAVAIL)
1245 == 0),
1246 PMU_MAX_TRANSITION_DLY);
1247 AND_REG(&wlc_hw->regs->clk_ctl_st,
1248 ~CCS_FORCEHT);
1249 }
1250 }
1251 wlc_hw->forcefastclk = (mode == CLK_FAST);
1252 } else {
1253
1254 /* old chips w/o PMU, force HT through cc,
1255 * then use FCA to verify mac is running fast clock
1256 */
1257
1258 wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
1259
1260 /* check fast clock is available (if core is not in reset) */
1261 if (wlc_hw->forcefastclk && wlc_hw->clk)
1262 WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) &
1263 SISF_FCLKA));
1264
1265 /* keep the ucode wake bit on if forcefastclk is on
1266 * since we do not want ucode to put us back to slow clock
1267 * when it dozes for PM mode.
1268 * Code below matches the wake override bit with current forcefastclk state
1269 * Only setting bit in wake_override instead of waking ucode immediately
1270 * since old code (wlc.c 1.4499) had this behavior. Older code set
1271 * wlc->forcefastclk but only had the wake happen if the wakup_ucode work
1272 * (protected by an up check) was executed just below.
1273 */
1274 if (wlc_hw->forcefastclk)
1275 mboolset(wlc_hw->wake_override,
1276 BRCMS_WAKE_OVERRIDE_FORCEFAST);
1277 else
1278 mboolclr(wlc_hw->wake_override,
1279 BRCMS_WAKE_OVERRIDE_FORCEFAST);
1280 }
1281}
1282
1283/* set initial host flags value */
1284static void
1285brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init)
1286{
1287 struct brcms_hardware *wlc_hw = wlc->hw;
1288
1289 memset(mhfs, 0, MHFMAX * sizeof(u16));
1290
1291 mhfs[MHF2] |= mhf2_init;
1292
1293 /* prohibit use of slowclock on multifunction boards */
1294 if (wlc_hw->boardflags & BFL_NOPLLDOWN)
1295 mhfs[MHF1] |= MHF1_FORCEFASTCLK;
1296
1297 if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
1298 mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
1299 mhfs[MHF1] |= MHF1_IQSWAP_WAR;
1300 }
1301}
1302
1303/* set or clear ucode host flag bits
1304 * it has an optimization for no-change write
1305 * it only writes through shared memory when the core has clock;
1306 * pre-CLK changes should use wlc_write_mhf to get around the optimization
1307 *
1308 *
1309 * bands values are: BRCM_BAND_AUTO <--- Current band only
1310 * BRCM_BAND_5G <--- 5G band only
1311 * BRCM_BAND_2G <--- 2G band only
1312 * BRCM_BAND_ALL <--- All bands
1313 */
1314void
1315brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
1316 int bands)
1317{
1318 u16 save;
1319 u16 addr[MHFMAX] = {
1320 M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
1321 M_HOST_FLAGS5
1322 };
1323 struct brcms_hw_band *band;
1324
1325 if ((val & ~mask) || idx >= MHFMAX)
1326 return; /* error condition */
1327
1328 switch (bands) {
1329 /* Current band only or all bands,
1330 * then set the band to current band
1331 */
1332 case BRCM_BAND_AUTO:
1333 case BRCM_BAND_ALL:
1334 band = wlc_hw->band;
1335 break;
1336 case BRCM_BAND_5G:
1337 band = wlc_hw->bandstate[BAND_5G_INDEX];
1338 break;
1339 case BRCM_BAND_2G:
1340 band = wlc_hw->bandstate[BAND_2G_INDEX];
1341 break;
1342 default:
1343 band = NULL; /* error condition */
1344 }
1345
1346 if (band) {
1347 save = band->mhfs[idx];
1348 band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
1349
1350 /* optimization: only write through if changed, and
1351 * changed band is the current band
1352 */
1353 if (wlc_hw->clk && (band->mhfs[idx] != save)
1354 && (band == wlc_hw->band))
1355 brcms_b_write_shm(wlc_hw, addr[idx],
1356 (u16) band->mhfs[idx]);
1357 }
1358
1359 if (bands == BRCM_BAND_ALL) {
1360 wlc_hw->bandstate[0]->mhfs[idx] =
1361 (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
1362 wlc_hw->bandstate[1]->mhfs[idx] =
1363 (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
1364 }
1365}
1366
1367u16 brcms_b_mhf_get(struct brcms_hardware *wlc_hw, u8 idx, int bands)
1368{
1369 struct brcms_hw_band *band;
1370
1371 if (idx >= MHFMAX)
1372 return 0; /* error condition */
1373 switch (bands) {
1374 case BRCM_BAND_AUTO:
1375 band = wlc_hw->band;
1376 break;
1377 case BRCM_BAND_5G:
1378 band = wlc_hw->bandstate[BAND_5G_INDEX];
1379 break;
1380 case BRCM_BAND_2G:
1381 band = wlc_hw->bandstate[BAND_2G_INDEX];
1382 break;
1383 default:
1384 band = NULL; /* error condition */
1385 }
1386
1387 if (!band)
1388 return 0;
1389
1390 return band->mhfs[idx];
1391}
1392
1393static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
1394{
1395 u8 idx;
1396 u16 addr[] = {
1397 M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
1398 M_HOST_FLAGS5
1399 };
1400
1401 for (idx = 0; idx < MHFMAX; idx++) {
1402 brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]);
1403 }
1404}
1405
1406/* set the maccontrol register to desired reset state and
1407 * initialize the sw cache of the register
1408 */
1409static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw)
1410{
1411 /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
1412 wlc_hw->maccontrol = 0;
1413 wlc_hw->suspended_fifos = 0;
1414 wlc_hw->wake_override = 0;
1415 wlc_hw->mute_override = 0;
1416 brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
1417}
1418
1419/* set or clear maccontrol bits */
1420void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val)
1421{
1422 u32 maccontrol;
1423 u32 new_maccontrol;
1424
1425 if (val & ~mask)
1426 return; /* error condition */
1427 maccontrol = wlc_hw->maccontrol;
1428 new_maccontrol = (maccontrol & ~mask) | val;
1429
1430 /* if the new maccontrol value is the same as the old, nothing to do */
1431 if (new_maccontrol == maccontrol)
1432 return;
1433
1434 /* something changed, cache the new value */
1435 wlc_hw->maccontrol = new_maccontrol;
1436
1437 /* write the new values with overrides applied */
1438 brcms_c_mctrl_write(wlc_hw);
1439}
1440
1441/* write the software state of maccontrol and overrides to the maccontrol register */
1442static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw)
1443{
1444 u32 maccontrol = wlc_hw->maccontrol;
1445
1446 /* OR in the wake bit if overridden */
1447 if (wlc_hw->wake_override)
1448 maccontrol |= MCTL_WAKE;
1449
1450 /* set AP and INFRA bits for mute if needed */
1451 if (wlc_hw->mute_override) {
1452 maccontrol &= ~(MCTL_AP);
1453 maccontrol |= MCTL_INFRA;
1454 }
1455
1456 W_REG(&wlc_hw->regs->maccontrol, maccontrol);
1457}
1458
1459void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
1460 u32 override_bit)
1461{
1462 if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
1463 mboolset(wlc_hw->wake_override, override_bit);
1464 return;
1465 }
1466
1467 mboolset(wlc_hw->wake_override, override_bit);
1468
1469 brcms_c_mctrl_write(wlc_hw);
1470 brcms_b_wait_for_wake(wlc_hw);
1471
1472 return;
1473}
1474
1475void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
1476 u32 override_bit)
1477{
1478 mboolclr(wlc_hw->wake_override, override_bit);
1479
1480 if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
1481 return;
1482
1483 brcms_c_mctrl_write(wlc_hw);
1484
1485 return;
1486}
1487
1488/* When driver needs ucode to stop beaconing, it has to make sure that
1489 * MCTL_AP is clear and MCTL_INFRA is set
1490 * Mode MCTL_AP MCTL_INFRA
1491 * AP 1 1
1492 * STA 0 1 <--- This will ensure no beacons
1493 * IBSS 0 0
1494 */
1495static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw)
1496{
1497 wlc_hw->mute_override = 1;
1498
1499 /* if maccontrol already has AP == 0 and INFRA == 1 without this
1500 * override, then there is no change to write
1501 */
1502 if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
1503 return;
1504
1505 brcms_c_mctrl_write(wlc_hw);
1506
1507 return;
1508}
1509
1510/* Clear the override on AP and INFRA bits */
1511static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw)
1512{
1513 if (wlc_hw->mute_override == 0)
1514 return;
1515
1516 wlc_hw->mute_override = 0;
1517
1518 /* if maccontrol already has AP == 0 and INFRA == 1 without this
1519 * override, then there is no change to write
1520 */
1521 if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
1522 return;
1523
1524 brcms_c_mctrl_write(wlc_hw);
1525}
1526
1527/*
1528 * Write a MAC address to the given match reg offset in the RXE match engine.
1529 */
1530void
1531brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
1532 const u8 *addr)
1533{
1534 d11regs_t *regs;
1535 u16 mac_l;
1536 u16 mac_m;
1537 u16 mac_h;
1538
1539 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n",
1540 wlc_hw->unit);
1541
1542 regs = wlc_hw->regs;
1543 mac_l = addr[0] | (addr[1] << 8);
1544 mac_m = addr[2] | (addr[3] << 8);
1545 mac_h = addr[4] | (addr[5] << 8);
1546
1547 /* enter the MAC addr into the RXE match registers */
1548 W_REG(&regs->rcm_ctl, RCM_INC_DATA | match_reg_offset);
1549 W_REG(&regs->rcm_mat_data, mac_l);
1550 W_REG(&regs->rcm_mat_data, mac_m);
1551 W_REG(&regs->rcm_mat_data, mac_h);
1552
1553}
1554
1555void
1556brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
1557 void *buf)
1558{
1559 d11regs_t *regs;
1560 u32 word;
1561 bool be_bit;
1562 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1563
1564 regs = wlc_hw->regs;
1565 W_REG(&regs->tplatewrptr, offset);
1566
1567 /* if MCTL_BIGEND bit set in mac control register,
1568 * the chip swaps data in fifo, as well as data in
1569 * template ram
1570 */
1571 be_bit = (R_REG(&regs->maccontrol) & MCTL_BIGEND) != 0;
1572
1573 while (len > 0) {
1574 memcpy(&word, buf, sizeof(u32));
1575
1576 if (be_bit)
1577 word = cpu_to_be32(word);
1578 else
1579 word = cpu_to_le32(word);
1580
1581 W_REG(&regs->tplatewrdata, word);
1582
1583 buf = (u8 *) buf + sizeof(u32);
1584 len -= sizeof(u32);
1585 }
1586}
1587
1588void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin)
1589{
1590 wlc_hw->band->CWmin = newmin;
1591
1592 W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN);
1593 (void)R_REG(&wlc_hw->regs->objaddr);
1594 W_REG(&wlc_hw->regs->objdata, newmin);
1595}
1596
1597void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax)
1598{
1599 wlc_hw->band->CWmax = newmax;
1600
1601 W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX);
1602 (void)R_REG(&wlc_hw->regs->objaddr);
1603 W_REG(&wlc_hw->regs->objdata, newmax);
1604}
1605
1606void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
1607{
1608 bool fastclk;
1609
1610 /* request FAST clock if not on */
1611 fastclk = wlc_hw->forcefastclk;
1612 if (!fastclk)
1613 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
1614
1615 wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
1616
1617 brcms_b_phy_reset(wlc_hw);
1618 wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
1619
1620 /* restore the clk */
1621 if (!fastclk)
1622 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
1623}
1624
1625static void
1626brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw, void *bcn,
1627 int len)
1628{
1629 d11regs_t *regs = wlc_hw->regs;
1630
1631 brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3,
1632 bcn);
1633 /* write beacon length to SCR */
1634 brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
1635 /* mark beacon0 valid */
1636 OR_REG(&regs->maccommand, MCMD_BCN0VLD);
1637}
1638
1639static void
1640brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw, void *bcn,
1641 int len)
1642{
1643 d11regs_t *regs = wlc_hw->regs;
1644
1645 brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3,
1646 bcn);
1647 /* write beacon length to SCR */
1648 brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
1649 /* mark beacon1 valid */
1650 OR_REG(&regs->maccommand, MCMD_BCN1VLD);
1651}
1652
1653/* mac is assumed to be suspended at this point */
1654void
1655brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw, void *bcn,
1656 int len, bool both)
1657{
1658 d11regs_t *regs = wlc_hw->regs;
1659
1660 if (both) {
1661 brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len);
1662 brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len);
1663 } else {
1664 /* bcn 0 */
1665 if (!(R_REG(&regs->maccommand) & MCMD_BCN0VLD))
1666 brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len);
1667 /* bcn 1 */
1668 else if (!
1669 (R_REG(&regs->maccommand) & MCMD_BCN1VLD))
1670 brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len);
1671 }
1672}
1673
1674static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
1675{
1676 u16 v;
1677 struct brcms_c_info *wlc = wlc_hw->wlc;
1678 /* update SYNTHPU_DLY */
1679
1680 if (BRCMS_ISLCNPHY(wlc->band)) {
1681 v = SYNTHPU_DLY_LPPHY_US;
1682 } else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) {
1683 v = SYNTHPU_DLY_NPHY_US;
1684 } else {
1685 v = SYNTHPU_DLY_BPHY_US;
1686 }
1687
1688 brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
1689}
1690
1691/* band-specific init */
1692static void
1693brcms_b_bsinit(struct brcms_c_info *wlc, chanspec_t chanspec)
1694{
1695 struct brcms_hardware *wlc_hw = wlc->hw;
1696
1697 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
1698 wlc_hw->band->bandunit);
1699
1700 brcms_c_ucode_bsinit(wlc_hw);
1701
1702 wlc_phy_init(wlc_hw->band->pi, chanspec);
1703
1704 brcms_c_ucode_txant_set(wlc_hw);
1705
1706 /* cwmin is band-specific, update hardware with value for current band */
1707 brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
1708 brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
1709
1710 brcms_b_update_slot_timing(wlc_hw,
1711 BAND_5G(wlc_hw->band->
1712 bandtype) ? true : wlc_hw->
1713 shortslot);
1714
1715 /* write phytype and phyvers */
1716 brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
1717 brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
1718
1719 /* initialize the txphyctl1 rate table since shmem is shared between bands */
1720 brcms_upd_ofdm_pctl1_table(wlc_hw);
1721
1722 brcms_b_upd_synthpu(wlc_hw);
1723}
1724
1725static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
1726{
1727 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
1728
1729 wlc_hw->phyclk = clk;
1730
1731 if (OFF == clk) { /* clear gmode bit, put phy into reset */
1732
1733 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE),
1734 (SICF_PRST | SICF_FGC));
1735 udelay(1);
1736 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST);
1737 udelay(1);
1738
1739 } else { /* take phy out of reset */
1740
1741 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC);
1742 udelay(1);
1743 ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0);
1744 udelay(1);
1745
1746 }
1747}
1748
1749/* Perform a soft reset of the PHY PLL */
1750void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
1751{
1752 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1753
1754 ai_corereg(wlc_hw->sih, SI_CC_IDX,
1755 offsetof(chipcregs_t, chipcontrol_addr), ~0, 0);
1756 udelay(1);
1757 ai_corereg(wlc_hw->sih, SI_CC_IDX,
1758 offsetof(chipcregs_t, chipcontrol_data), 0x4, 0);
1759 udelay(1);
1760 ai_corereg(wlc_hw->sih, SI_CC_IDX,
1761 offsetof(chipcregs_t, chipcontrol_data), 0x4, 4);
1762 udelay(1);
1763 ai_corereg(wlc_hw->sih, SI_CC_IDX,
1764 offsetof(chipcregs_t, chipcontrol_data), 0x4, 0);
1765 udelay(1);
1766}
1767
1768/* light way to turn on phy clock without reset for NPHY only
1769 * refer to brcms_b_core_phy_clk for full version
1770 */
1771void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk)
1772{
1773 /* support(necessary for NPHY and HYPHY) only */
1774 if (!BRCMS_ISNPHY(wlc_hw->band))
1775 return;
1776
1777 if (ON == clk)
1778 ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC);
1779 else
1780 ai_core_cflags(wlc_hw->sih, SICF_FGC, 0);
1781
1782}
1783
1784void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk)
1785{
1786 if (ON == clk)
1787 ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE);
1788 else
1789 ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0);
1790}
1791
1792void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
1793{
1794 struct brcms_phy_pub *pih = wlc_hw->band->pi;
1795 u32 phy_bw_clkbits;
1796 bool phy_in_reset = false;
1797
1798 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
1799
1800 if (pih == NULL)
1801 return;
1802
1803 phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
1804
1805 /* Specific reset sequence required for NPHY rev 3 and 4 */
1806 if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
1807 NREV_LE(wlc_hw->band->phyrev, 4)) {
1808 /* Set the PHY bandwidth */
1809 ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits);
1810
1811 udelay(1);
1812
1813 /* Perform a soft reset of the PHY PLL */
1814 brcms_b_core_phypll_reset(wlc_hw);
1815
1816 /* reset the PHY */
1817 ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE),
1818 (SICF_PRST | SICF_PCLKE));
1819 phy_in_reset = true;
1820 } else {
1821
1822 ai_core_cflags(wlc_hw->sih,
1823 (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
1824 (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
1825 }
1826
1827 udelay(2);
1828 brcms_b_core_phy_clk(wlc_hw, ON);
1829
1830 if (pih)
1831 wlc_phy_anacore(pih, ON);
1832}
1833
1834/* switch to and initialize new band */
1835static void
1836brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
1837 chanspec_t chanspec) {
1838 struct brcms_c_info *wlc = wlc_hw->wlc;
1839 u32 macintmask;
1840
1841 /* Enable the d11 core before accessing it */
1842 if (!ai_iscoreup(wlc_hw->sih)) {
1843 ai_core_reset(wlc_hw->sih, 0, 0);
1844 brcms_c_mctrl_reset(wlc_hw);
1845 }
1846
1847 macintmask = brcms_c_setband_inact(wlc, bandunit);
1848
1849 if (!wlc_hw->up)
1850 return;
1851
1852 brcms_b_core_phy_clk(wlc_hw, ON);
1853
1854 /* band-specific initializations */
1855 brcms_b_bsinit(wlc, chanspec);
1856
1857 /*
1858 * If there are any pending software interrupt bits,
1859 * then replace these with a harmless nonzero value
1860 * so brcms_c_dpc() will re-enable interrupts when done.
1861 */
1862 if (wlc->macintstatus)
1863 wlc->macintstatus = MI_DMAINT;
1864
1865 /* restore macintmask */
1866 brcms_intrsrestore(wlc->wl, macintmask);
1867
1868 /* ucode should still be suspended.. */
1869 WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
1870}
1871
1872/* low-level band switch utility routine */
1873void brcms_c_setxband(struct brcms_hardware *wlc_hw,
1874 uint bandunit)
1875{
1876 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
1877 bandunit);
1878
1879 wlc_hw->band = wlc_hw->bandstate[bandunit];
1880
1881 /* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */
1882 wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
1883
1884 /* set gmode core flag */
1885 if (wlc_hw->sbclk && !wlc_hw->noreset) {
1886 ai_core_cflags(wlc_hw->sih, SICF_GMODE,
1887 ((bandunit == 0) ? SICF_GMODE : 0));
1888 }
1889}
1890
1891static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
1892{
1893
1894 /* reject unsupported corerev */
1895 if (!VALID_COREREV(wlc_hw->corerev)) {
1896 wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
1897 wlc_hw->corerev);
1898 return false;
1899 }
1900
1901 return true;
1902}
1903
1904/* Validate some board info parameters */
1905static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
1906{
1907 uint boardrev = wlc_hw->boardrev;
1908
1909 /* 4 bits each for board type, major, minor, and tiny version */
1910 uint brt = (boardrev & 0xf000) >> 12;
1911 uint b0 = (boardrev & 0xf00) >> 8;
1912 uint b1 = (boardrev & 0xf0) >> 4;
1913 uint b2 = boardrev & 0xf;
1914
1915 /* voards from other vendors are always considered valid */
1916 if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM)
1917 return true;
1918
1919 /* do some boardrev sanity checks when boardvendor is Broadcom */
1920 if (boardrev == 0)
1921 return false;
1922
1923 if (boardrev <= 0xff)
1924 return true;
1925
1926 if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
1927 || (b2 > 9))
1928 return false;
1929
1930 return true;
1931}
1932
1933static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw)
1934{
1935 const char *varname = "macaddr";
1936 char *macaddr;
1937
1938 /* If macaddr exists, use it (Sromrev4, CIS, ...). */
1939 macaddr = getvar(wlc_hw->vars, varname);
1940 if (macaddr != NULL)
1941 return macaddr;
1942
1943 if (NBANDS_HW(wlc_hw) > 1)
1944 varname = "et1macaddr";
1945 else
1946 varname = "il0macaddr";
1947
1948 macaddr = getvar(wlc_hw->vars, varname);
1949 if (macaddr == NULL) {
1950 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr "
1951 "getvar(%s) not found\n", wlc_hw->unit, varname);
1952 }
1953
1954 return macaddr;
1955}
1956
1957/*
1958 * Return true if radio is disabled, otherwise false.
1959 * hw radio disable signal is an external pin, users activate it asynchronously
1960 * this function could be called when driver is down and w/o clock
1961 * it operates on different registers depending on corerev and boardflag.
1962 */
1963bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw)
1964{
1965 bool v, clk, xtal;
1966 u32 resetbits = 0, flags = 0;
1967
1968 xtal = wlc_hw->sbclk;
1969 if (!xtal)
1970 brcms_b_xtal(wlc_hw, ON);
1971
1972 /* may need to take core out of reset first */
1973 clk = wlc_hw->clk;
1974 if (!clk) {
1975 /*
1976 * mac no longer enables phyclk automatically when driver
1977 * accesses phyreg throughput mac. This can be skipped since
1978 * only mac reg is accessed below
1979 */
1980 flags |= SICF_PCLKE;
1981
1982 /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
1983 if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
1984 (wlc_hw->sih->chip == BCM43225_CHIP_ID))
1985 wlc_hw->regs =
1986 (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
1987 0);
1988 ai_core_reset(wlc_hw->sih, flags, resetbits);
1989 brcms_c_mctrl_reset(wlc_hw);
1990 }
1991
1992 v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0);
1993
1994 /* put core back into reset */
1995 if (!clk)
1996 ai_core_disable(wlc_hw->sih, 0);
1997
1998 if (!xtal)
1999 brcms_b_xtal(wlc_hw, OFF);
2000
2001 return v;
2002}
2003
2004/* Initialize just the hardware when coming out of POR or S3/S5 system states */
2005void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
2006{
2007 if (wlc_hw->wlc->pub->hw_up)
2008 return;
2009
2010 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2011
2012 /*
2013 * Enable pll and xtal, initialize the power control registers,
2014 * and force fastclock for the remainder of brcms_c_up().
2015 */
2016 brcms_b_xtal(wlc_hw, ON);
2017 ai_clkctl_init(wlc_hw->sih);
2018 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
2019
2020 if (wlc_hw->sih->bustype == PCI_BUS) {
2021 ai_pci_fixcfg(wlc_hw->sih);
2022
2023 /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
2024 if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
2025 (wlc_hw->sih->chip == BCM43225_CHIP_ID))
2026 wlc_hw->regs =
2027 (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
2028 0);
2029 }
2030
2031 /* Inform phy that a POR reset has occurred so it does a complete phy init */
2032 wlc_phy_por_inform(wlc_hw->band->pi);
2033
2034 wlc_hw->ucode_loaded = false;
2035 wlc_hw->wlc->pub->hw_up = true;
2036
2037 if ((wlc_hw->boardflags & BFL_FEM)
2038 && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
2039 if (!
2040 (wlc_hw->boardrev >= 0x1250
2041 && (wlc_hw->boardflags & BFL_FEM_BT)))
2042 ai_epa_4313war(wlc_hw->sih);
2043 }
2044}
2045
2046static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo)
2047{
2048 struct dma_pub *di = wlc_hw->di[fifo];
2049 return dma_rxreset(di);
2050}
2051
2052/* d11 core reset
2053 * ensure fask clock during reset
2054 * reset dma
2055 * reset d11(out of reset)
2056 * reset phy(out of reset)
2057 * clear software macintstatus for fresh new start
2058 * one testing hack wlc_hw->noreset will bypass the d11/phy reset
2059 */
2060void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
2061{
2062 d11regs_t *regs;
2063 uint i;
2064 bool fastclk;
2065 u32 resetbits = 0;
2066
2067 if (flags == BRCMS_USE_COREFLAGS)
2068 flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
2069
2070 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2071
2072 regs = wlc_hw->regs;
2073
2074 /* request FAST clock if not on */
2075 fastclk = wlc_hw->forcefastclk;
2076 if (!fastclk)
2077 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
2078
2079 /* reset the dma engines except first time thru */
2080 if (ai_iscoreup(wlc_hw->sih)) {
2081 for (i = 0; i < NFIFO; i++)
2082 if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) {
2083 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
2084 "dma_txreset[%d]: cannot stop dma\n",
2085 wlc_hw->unit, __func__, i);
2086 }
2087
2088 if ((wlc_hw->di[RX_FIFO])
2089 && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) {
2090 wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
2091 "[%d]: cannot stop dma\n",
2092 wlc_hw->unit, __func__, RX_FIFO);
2093 }
2094 }
2095 /* if noreset, just stop the psm and return */
2096 if (wlc_hw->noreset) {
2097 wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */
2098 brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
2099 return;
2100 }
2101
2102 /*
2103 * mac no longer enables phyclk automatically when driver accesses
2104 * phyreg throughput mac, AND phy_reset is skipped at early stage when
2105 * band->pi is invalid. need to enable PHY CLK
2106 */
2107 flags |= SICF_PCLKE;
2108
2109 /* reset the core
2110 * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which
2111 * is cleared by the core_reset. have to re-request it.
2112 * This adds some delay and we can optimize it by also requesting fastclk through
2113 * chipcommon during this period if necessary. But that has to work coordinate
2114 * with other driver like mips/arm since they may touch chipcommon as well.
2115 */
2116 wlc_hw->clk = false;
2117 ai_core_reset(wlc_hw->sih, flags, resetbits);
2118 wlc_hw->clk = true;
2119 if (wlc_hw->band && wlc_hw->band->pi)
2120 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
2121
2122 brcms_c_mctrl_reset(wlc_hw);
2123
2124 if (PMUCTL_ENAB(wlc_hw->sih))
2125 brcms_b_clkctl_clk(wlc_hw, CLK_FAST);
2126
2127 brcms_b_phy_reset(wlc_hw);
2128
2129 /* turn on PHY_PLL */
2130 brcms_b_core_phypll_ctl(wlc_hw, true);
2131
2132 /* clear sw intstatus */
2133 wlc_hw->wlc->macintstatus = 0;
2134
2135 /* restore the clk setting */
2136 if (!fastclk)
2137 brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC);
2138}
2139
2140/* txfifo sizes needs to be modified(increased) since the newer cores
2141 * have more memory.
2142 */
2143static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw)
2144{
2145 d11regs_t *regs = wlc_hw->regs;
2146 u16 fifo_nu;
2147 u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
2148 u16 txfifo_def, txfifo_def1;
2149 u16 txfifo_cmd;
2150
2151 /* tx fifos start at TXFIFO_START_BLK from the Base address */
2152 txfifo_startblk = TXFIFO_START_BLK;
2153
2154 /* sequence of operations: reset fifo, set fifo size, reset fifo */
2155 for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
2156
2157 txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
2158 txfifo_def = (txfifo_startblk & 0xff) |
2159 (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
2160 txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
2161 ((((txfifo_endblk -
2162 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
2163 txfifo_cmd =
2164 TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
2165
2166 W_REG(&regs->xmtfifocmd, txfifo_cmd);
2167 W_REG(&regs->xmtfifodef, txfifo_def);
2168 W_REG(&regs->xmtfifodef1, txfifo_def1);
2169
2170 W_REG(&regs->xmtfifocmd, txfifo_cmd);
2171
2172 txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
2173 }
2174 /*
2175 * need to propagate to shm location to be in sync since ucode/hw won't
2176 * do this
2177 */
2178 brcms_b_write_shm(wlc_hw, M_FIFOSIZE0,
2179 wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
2180 brcms_b_write_shm(wlc_hw, M_FIFOSIZE1,
2181 wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
2182 brcms_b_write_shm(wlc_hw, M_FIFOSIZE2,
2183 ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
2184 xmtfifo_sz[TX_AC_BK_FIFO]));
2185 brcms_b_write_shm(wlc_hw, M_FIFOSIZE3,
2186 ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
2187 xmtfifo_sz[TX_BCMC_FIFO]));
2188}
2189
2190/* d11 core init
2191 * reset PSM
2192 * download ucode/PCM
2193 * let ucode run to suspended
2194 * download ucode inits
2195 * config other core registers
2196 * init dma
2197 */
2198static void brcms_b_coreinit(struct brcms_c_info *wlc)
2199{
2200 struct brcms_hardware *wlc_hw = wlc->hw;
2201 d11regs_t *regs;
2202 u32 sflags;
2203 uint bcnint_us;
2204 uint i = 0;
2205 bool fifosz_fixup = false;
2206 int err = 0;
2207 u16 buf[NFIFO];
2208 struct wiphy *wiphy = wlc->wiphy;
2209
2210 regs = wlc_hw->regs;
2211
2212 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
2213
2214 /* reset PSM */
2215 brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
2216
2217 brcms_ucode_download(wlc_hw);
2218 /*
2219 * FIFOSZ fixup. driver wants to controls the fifo allocation.
2220 */
2221 fifosz_fixup = true;
2222
2223 /* let the PSM run to the suspended state, set mode to BSS STA */
2224 W_REG(&regs->macintstatus, -1);
2225 brcms_b_mctrl(wlc_hw, ~0,
2226 (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
2227
2228 /* wait for ucode to self-suspend after auto-init */
2229 SPINWAIT(((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0),
2230 1000 * 1000);
2231 if ((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0)
2232 wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
2233 "suspend!\n", wlc_hw->unit);
2234
2235 brcms_c_gpio_init(wlc);
2236
2237 sflags = ai_core_sflags(wlc_hw->sih, 0, 0);
2238
2239 if (D11REV_IS(wlc_hw->corerev, 23)) {
2240 if (BRCMS_ISNPHY(wlc_hw->band))
2241 brcms_c_write_inits(wlc_hw, d11n0initvals16);
2242 else
2243 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
2244 " %d\n", __func__, wlc_hw->unit,
2245 wlc_hw->corerev);
2246 } else if (D11REV_IS(wlc_hw->corerev, 24)) {
2247 if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2248 brcms_c_write_inits(wlc_hw, d11lcn0initvals24);
2249 } else {
2250 wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
2251 " %d\n", __func__, wlc_hw->unit,
2252 wlc_hw->corerev);
2253 }
2254 } else {
2255 wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
2256 __func__, wlc_hw->unit, wlc_hw->corerev);
2257 }
2258
2259 /* For old ucode, txfifo sizes needs to be modified(increased) */
2260 if (fifosz_fixup == true) {
2261 brcms_b_corerev_fifofixup(wlc_hw);
2262 }
2263
2264 /* check txfifo allocations match between ucode and driver */
2265 buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0);
2266 if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
2267 i = TX_AC_BE_FIFO;
2268 err = -1;
2269 }
2270 buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1);
2271 if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
2272 i = TX_AC_VI_FIFO;
2273 err = -1;
2274 }
2275 buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2);
2276 buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
2277 buf[TX_AC_BK_FIFO] &= 0xff;
2278 if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
2279 i = TX_AC_BK_FIFO;
2280 err = -1;
2281 }
2282 if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
2283 i = TX_AC_VO_FIFO;
2284 err = -1;
2285 }
2286 buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3);
2287 buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
2288 buf[TX_BCMC_FIFO] &= 0xff;
2289 if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
2290 i = TX_BCMC_FIFO;
2291 err = -1;
2292 }
2293 if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
2294 i = TX_ATIM_FIFO;
2295 err = -1;
2296 }
2297 if (err != 0) {
2298 wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
2299 " driver size %d index %d\n", buf[i],
2300 wlc_hw->xmtfifo_sz[i], i);
2301 }
2302
2303 /* make sure we can still talk to the mac */
2304 WARN_ON(R_REG(&regs->maccontrol) == 0xffffffff);
2305
2306 /* band-specific inits done by wlc_bsinit() */
2307
2308 /* Set up frame burst size and antenna swap threshold init values */
2309 brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
2310 brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
2311
2312 /* enable one rx interrupt per received frame */
2313 W_REG(&regs->intrcvlazy[0], (1 << IRL_FC_SHIFT));
2314
2315 /* set the station mode (BSS STA) */
2316 brcms_b_mctrl(wlc_hw,
2317 (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
2318 (MCTL_INFRA | MCTL_DISCARD_PMQ));
2319
2320 /* set up Beacon interval */
2321 bcnint_us = 0x8000 << 10;
2322 W_REG(&regs->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT));
2323 W_REG(&regs->tsf_cfpstart, bcnint_us);
2324 W_REG(&regs->macintstatus, MI_GP1);
2325
2326 /* write interrupt mask */
2327 W_REG(&regs->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK);
2328
2329 /* allow the MAC to control the PHY clock (dynamic on/off) */
2330 brcms_b_macphyclk_set(wlc_hw, ON);
2331
2332 /* program dynamic clock control fast powerup delay register */
2333 wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
2334 W_REG(&regs->scc_fastpwrup_dly, wlc->fastpwrup_dly);
2335
2336 /* tell the ucode the corerev */
2337 brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
2338
2339 /* tell the ucode MAC capabilities */
2340 brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L,
2341 (u16) (wlc_hw->machwcap & 0xffff));
2342 brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H,
2343 (u16) ((wlc_hw->
2344 machwcap >> 16) & 0xffff));
2345
2346 /* write retry limits to SCR, this done after PSM init */
2347 W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
2348 (void)R_REG(&regs->objaddr);
2349 W_REG(&regs->objdata, wlc_hw->SRL);
2350 W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
2351 (void)R_REG(&regs->objaddr);
2352 W_REG(&regs->objdata, wlc_hw->LRL);
2353
2354 /* write rate fallback retry limits */
2355 brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
2356 brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
2357
2358 AND_REG(&regs->ifs_ctl, 0x0FFF);
2359 W_REG(&regs->ifs_aifsn, EDCF_AIFSN_MIN);
2360
2361 /* dma initializations */
2362 wlc->txpend16165war = 0;
2363
2364 /* init the tx dma engines */
2365 for (i = 0; i < NFIFO; i++) {
2366 if (wlc_hw->di[i])
2367 dma_txinit(wlc_hw->di[i]);
2368 }
2369
2370 /* init the rx dma engine(s) and post receive buffers */
2371 dma_rxinit(wlc_hw->di[RX_FIFO]);
2372 dma_rxfill(wlc_hw->di[RX_FIFO]);
2373}
2374
2375/* This function is used for changing the tsf frac register
2376 * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
2377 * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
2378 * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
2379 * HTPHY Formula is 2^26/freq(MHz) e.g.
2380 * For spuron2 - 126MHz -> 2^26/126 = 532610.0
2381 * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
2382 * For spuron: 123MHz -> 2^26/123 = 545600.5
2383 * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
2384 * For spur off: 120MHz -> 2^26/120 = 559240.5
2385 * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
2386 */
2387
2388void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
2389{
2390 d11regs_t *regs;
2391 regs = wlc_hw->regs;
2392
2393 if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
2394 (wlc_hw->sih->chip == BCM43225_CHIP_ID)) {
2395 if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */
2396 W_REG(&regs->tsf_clk_frac_l, 0x2082);
2397 W_REG(&regs->tsf_clk_frac_h, 0x8);
2398 } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */
2399 W_REG(&regs->tsf_clk_frac_l, 0x5341);
2400 W_REG(&regs->tsf_clk_frac_h, 0x8);
2401 } else { /* 120Mhz */
2402 W_REG(&regs->tsf_clk_frac_l, 0x8889);
2403 W_REG(&regs->tsf_clk_frac_h, 0x8);
2404 }
2405 } else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2406 if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */
2407 W_REG(&regs->tsf_clk_frac_l, 0x7CE0);
2408 W_REG(&regs->tsf_clk_frac_h, 0xC);
2409 } else { /* 80Mhz */
2410 W_REG(&regs->tsf_clk_frac_l, 0xCCCD);
2411 W_REG(&regs->tsf_clk_frac_h, 0xC);
2412 }
2413 }
2414}
2415
2416/* Initialize GPIOs that are controlled by D11 core */
2417static void brcms_c_gpio_init(struct brcms_c_info *wlc)
2418{
2419 struct brcms_hardware *wlc_hw = wlc->hw;
2420 d11regs_t *regs;
2421 u32 gc, gm;
2422
2423 regs = wlc_hw->regs;
2424
2425 /* use GPIO select 0 to get all gpio signals from the gpio out reg */
2426 brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
2427
2428 /*
2429 * Common GPIO setup:
2430 * G0 = LED 0 = WLAN Activity
2431 * G1 = LED 1 = WLAN 2.4 GHz Radio State
2432 * G2 = LED 2 = WLAN 5 GHz Radio State
2433 * G4 = radio disable input (HI enabled, LO disabled)
2434 */
2435
2436 gc = gm = 0;
2437
2438 /* Allocate GPIOs for mimo antenna diversity feature */
2439 if (wlc_hw->antsel_type == ANTSEL_2x3) {
2440 /* Enable antenna diversity, use 2x3 mode */
2441 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
2442 MHF3_ANTSEL_EN, BRCM_BAND_ALL);
2443 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
2444 MHF3_ANTSEL_MODE, BRCM_BAND_ALL);
2445
2446 /* init superswitch control */
2447 wlc_phy_antsel_init(wlc_hw->band->pi, false);
2448
2449 } else if (wlc_hw->antsel_type == ANTSEL_2x4) {
2450 gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
2451 /*
2452 * The board itself is powered by these GPIOs
2453 * (when not sending pattern) so set them high
2454 */
2455 OR_REG(&regs->psm_gpio_oe,
2456 (BOARD_GPIO_12 | BOARD_GPIO_13));
2457 OR_REG(&regs->psm_gpio_out,
2458 (BOARD_GPIO_12 | BOARD_GPIO_13));
2459
2460 /* Enable antenna diversity, use 2x4 mode */
2461 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
2462 MHF3_ANTSEL_EN, BRCM_BAND_ALL);
2463 brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
2464 BRCM_BAND_ALL);
2465
2466 /* Configure the desired clock to be 4Mhz */
2467 brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
2468 ANTSEL_CLKDIV_4MHZ);
2469 }
2470
2471 /* gpio 9 controls the PA. ucode is responsible for wiggling out and oe */
2472 if (wlc_hw->boardflags & BFL_PACTRL)
2473 gm |= gc |= BOARD_GPIO_PACTRL;
2474
2475 /* apply to gpiocontrol register */
2476 ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
2477}
2478
2479static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
2480{
2481 struct brcms_c_info *wlc;
2482 wlc = wlc_hw->wlc;
2483
2484 if (wlc_hw->ucode_loaded)
2485 return;
2486
2487 if (D11REV_IS(wlc_hw->corerev, 23)) {
2488 if (BRCMS_ISNPHY(wlc_hw->band)) {
2489 brcms_ucode_write(wlc_hw, bcm43xx_16_mimo,
2490 bcm43xx_16_mimosz);
2491 wlc_hw->ucode_loaded = true;
2492 } else
2493 wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
2494 "corerev %d\n",
2495 __func__, wlc_hw->unit, wlc_hw->corerev);
2496 } else if (D11REV_IS(wlc_hw->corerev, 24)) {
2497 if (BRCMS_ISLCNPHY(wlc_hw->band)) {
2498 brcms_ucode_write(wlc_hw, bcm43xx_24_lcn,
2499 bcm43xx_24_lcnsz);
2500 wlc_hw->ucode_loaded = true;
2501 } else {
2502 wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
2503 "corerev %d\n",
2504 __func__, wlc_hw->unit, wlc_hw->corerev);
2505 }
2506 }
2507}
2508
2509static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[],
2510 const uint nbytes) {
2511 d11regs_t *regs = wlc_hw->regs;
2512 uint i;
2513 uint count;
2514
2515 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2516
2517 count = (nbytes / sizeof(u32));
2518
2519 W_REG(&regs->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL));
2520 (void)R_REG(&regs->objaddr);
2521 for (i = 0; i < count; i++)
2522 W_REG(&regs->objdata, ucode[i]);
2523}
2524
2525static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
2526 const struct d11init *inits)
2527{
2528 int i;
2529 volatile u8 *base;
2530
2531 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
2532
2533 base = (volatile u8 *)wlc_hw->regs;
2534
2535 for (i = 0; inits[i].addr != 0xffff; i++) {
2536 if (inits[i].size == 2)
2537 W_REG((u16 *)(base + inits[i].addr),
2538 inits[i].value);
2539 else if (inits[i].size == 4)
2540 W_REG((u32 *)(base + inits[i].addr),
2541 inits[i].value);
2542 }
2543}
2544
2545static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw)
2546{
2547 u16 phyctl;
2548 u16 phytxant = wlc_hw->bmac_phytxant;
2549 u16 mask = PHY_TXC_ANT_MASK;
2550
2551 /* set the Probe Response frame phy control word */
2552 phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
2553 phyctl = (phyctl & ~mask) | phytxant;
2554 brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
2555
2556 /* set the Response (ACK/CTS) frame phy control word */
2557 phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD);
2558 phyctl = (phyctl & ~mask) | phytxant;
2559 brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
2560}
2561
2562void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant)
2563{
2564 /* update sw state */
2565 wlc_hw->bmac_phytxant = phytxant;
2566
2567 /* push to ucode if up */
2568 if (!wlc_hw->up)
2569 return;
2570 brcms_c_ucode_txant_set(wlc_hw);
2571
2572}
2573
2574u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw)
2575{
2576 return (u16) wlc_hw->wlc->stf->txant;
2577}
2578
2579void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
2580{
2581 wlc_hw->antsel_type = antsel_type;
2582
2583 /* Update the antsel type for phy module to use */
2584 wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
2585}
2586
2587void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
2588{
2589 bool fatal = false;
2590 uint unit;
2591 uint intstatus, idx;
2592 d11regs_t *regs = wlc_hw->regs;
2593 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
2594
2595 unit = wlc_hw->unit;
2596
2597 for (idx = 0; idx < NFIFO; idx++) {
2598 /* read intstatus register and ignore any non-error bits */
2599 intstatus =
2600 R_REG(&regs->intctrlregs[idx].intstatus) & I_ERRORS;
2601 if (!intstatus)
2602 continue;
2603
2604 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
2605 unit, idx, intstatus);
2606
2607 if (intstatus & I_RO) {
2608 wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
2609 "overflow\n", unit, idx);
2610 fatal = true;
2611 }
2612
2613 if (intstatus & I_PC) {
2614 wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
2615 unit, idx);
2616 fatal = true;
2617 }
2618
2619 if (intstatus & I_PD) {
2620 wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
2621 idx);
2622 fatal = true;
2623 }
2624
2625 if (intstatus & I_DE) {
2626 wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
2627 "error\n", unit, idx);
2628 fatal = true;
2629 }
2630
2631 if (intstatus & I_RU) {
2632 wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
2633 "underflow\n", idx, unit);
2634 }
2635
2636 if (intstatus & I_XU) {
2637 wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
2638 "underflow\n", idx, unit);
2639 fatal = true;
2640 }
2641
2642 if (fatal) {
2643 brcms_c_fatal_error(wlc_hw->wlc); /* big hammer */
2644 break;
2645 } else
2646 W_REG(&regs->intctrlregs[idx].intstatus,
2647 intstatus);
2648 }
2649}
2650
2651void brcms_c_intrson(struct brcms_c_info *wlc)
2652{
2653 struct brcms_hardware *wlc_hw = wlc->hw;
2654 wlc->macintmask = wlc->defmacintmask;
2655 W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
2656}
2657
2658/* callback for siutils.c, which has only wlc handler, no wl
2659 * they both check up, not only because there is no need to off/restore d11 interrupt
2660 * but also because per-port code may require sync with valid interrupt.
2661 */
2662
2663static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc)
2664{
2665 if (!wlc->hw->up)
2666 return 0;
2667
2668 return brcms_intrsoff(wlc->wl);
2669}
2670
2671static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask)
2672{
2673 if (!wlc->hw->up)
2674 return;
2675
2676 brcms_intrsrestore(wlc->wl, macintmask);
2677}
2678
2679u32 brcms_c_intrsoff(struct brcms_c_info *wlc)
2680{
2681 struct brcms_hardware *wlc_hw = wlc->hw;
2682 u32 macintmask;
2683
2684 if (!wlc_hw->clk)
2685 return 0;
2686
2687 macintmask = wlc->macintmask; /* isr can still happen */
2688
2689 W_REG(&wlc_hw->regs->macintmask, 0);
2690 (void)R_REG(&wlc_hw->regs->macintmask); /* sync readback */
2691 udelay(1); /* ensure int line is no longer driven */
2692 wlc->macintmask = 0;
2693
2694 /* return previous macintmask; resolve race between us and our isr */
2695 return wlc->macintstatus ? 0 : macintmask;
2696}
2697
2698void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
2699{
2700 struct brcms_hardware *wlc_hw = wlc->hw;
2701 if (!wlc_hw->clk)
2702 return;
2703
2704 wlc->macintmask = macintmask;
2705 W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
2706}
2707
2708static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, mbool flags)
2709{
2710 u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
2711
2712 if (on) {
2713 /* suspend tx fifos */
2714 brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
2715 brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
2716 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
2717 brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
2718
2719 /* zero the address match register so we do not send ACKs */
2720 brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
2721 null_ether_addr);
2722 } else {
2723 /* resume tx fifos */
2724 if (!wlc_hw->wlc->tx_suspended) {
2725 brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
2726 }
2727 brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
2728 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
2729 brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
2730
2731 /* Restore address */
2732 brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
2733 wlc_hw->etheraddr);
2734 }
2735
2736 wlc_phy_mute_upd(wlc_hw->band->pi, on, flags);
2737
2738 if (on)
2739 brcms_c_ucode_mute_override_set(wlc_hw);
2740 else
2741 brcms_c_ucode_mute_override_clear(wlc_hw);
2742}
2743
2744int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
2745 uint *blocks)
2746{
2747 if (fifo >= NFIFO)
2748 return -EINVAL;
2749
2750 *blocks = wlc_hw->xmtfifo_sz[fifo];
2751
2752 return 0;
2753}
2754
2755/* brcms_b_tx_fifo_suspended:
2756 * Check the MAC's tx suspend status for a tx fifo.
2757 *
2758 * When the MAC acknowledges a tx suspend, it indicates that no more
2759 * packets will be transmitted out the radio. This is independent of
2760 * DMA channel suspension---the DMA may have finished suspending, or may still
2761 * be pulling data into a tx fifo, by the time the MAC acks the suspend
2762 * request.
2763 */
2764static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw,
2765 uint tx_fifo)
2766{
2767 /* check that a suspend has been requested and is no longer pending */
2768
2769 /*
2770 * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine,
2771 * and the tx fifo suspend at the lower end of the MAC is acknowledged in the
2772 * chnstatus register.
2773 * The tx fifo suspend completion is independent of the DMA suspend completion and
2774 * may be acked before or after the DMA is suspended.
2775 */
2776 if (dma_txsuspended(wlc_hw->di[tx_fifo]) &&
2777 (R_REG(&wlc_hw->regs->chnstatus) &
2778 (1 << tx_fifo)) == 0)
2779 return true;
2780
2781 return false;
2782}
2783
2784static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
2785 uint tx_fifo)
2786{
2787 u8 fifo = 1 << tx_fifo;
2788
2789 /* Two clients of this code, 11h Quiet period and scanning. */
2790
2791 /* only suspend if not already suspended */
2792 if ((wlc_hw->suspended_fifos & fifo) == fifo)
2793 return;
2794
2795 /* force the core awake only if not already */
2796 if (wlc_hw->suspended_fifos == 0)
2797 brcms_c_ucode_wake_override_set(wlc_hw,
2798 BRCMS_WAKE_OVERRIDE_TXFIFO);
2799
2800 wlc_hw->suspended_fifos |= fifo;
2801
2802 if (wlc_hw->di[tx_fifo]) {
2803 /* Suspending AMPDU transmissions in the middle can cause underflow
2804 * which may result in mismatch between ucode and driver
2805 * so suspend the mac before suspending the FIFO
2806 */
2807 if (BRCMS_PHY_11N_CAP(wlc_hw->band))
2808 brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
2809
2810 dma_txsuspend(wlc_hw->di[tx_fifo]);
2811
2812 if (BRCMS_PHY_11N_CAP(wlc_hw->band))
2813 brcms_c_enable_mac(wlc_hw->wlc);
2814 }
2815}
2816
2817static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
2818 uint tx_fifo)
2819{
2820 /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case
2821 * but need to be done here for PIO otherwise the watchdog will catch
2822 * the inconsistency and fire
2823 */
2824 /* Two clients of this code, 11h Quiet period and scanning. */
2825 if (wlc_hw->di[tx_fifo])
2826 dma_txresume(wlc_hw->di[tx_fifo]);
2827
2828 /* allow core to sleep again */
2829 if (wlc_hw->suspended_fifos == 0)
2830 return;
2831 else {
2832 wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
2833 if (wlc_hw->suspended_fifos == 0)
2834 brcms_c_ucode_wake_override_clear(wlc_hw,
2835 BRCMS_WAKE_OVERRIDE_TXFIFO);
2836 }
2837}
2838
2839/*
2840 * Read and clear macintmask and macintstatus and intstatus registers.
2841 * This routine should be called with interrupts off
2842 * Return:
2843 * -1 if DEVICEREMOVED(wlc) evaluates to true;
2844 * 0 if the interrupt is not for us, or we are in some special cases;
2845 * device interrupt status bits otherwise.
2846 */
2847static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
2848{
2849 struct brcms_hardware *wlc_hw = wlc->hw;
2850 d11regs_t *regs = wlc_hw->regs;
2851 u32 macintstatus;
2852
2853 /* macintstatus includes a DMA interrupt summary bit */
2854 macintstatus = R_REG(&regs->macintstatus);
2855
2856 BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
2857 macintstatus);
2858
2859 /* detect cardbus removed, in power down(suspend) and in reset */
2860 if (DEVICEREMOVED(wlc))
2861 return -1;
2862
2863 /* DEVICEREMOVED succeeds even when the core is still resetting,
2864 * handle that case here.
2865 */
2866 if (macintstatus == 0xffffffff)
2867 return 0;
2868
2869 /* defer unsolicited interrupts */
2870 macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
2871
2872 /* if not for us */
2873 if (macintstatus == 0)
2874 return 0;
2875
2876 /* interrupts are already turned off for CFE build
2877 * Caution: For CFE Turning off the interrupts again has some undesired
2878 * consequences
2879 */
2880 /* turn off the interrupts */
2881 W_REG(&regs->macintmask, 0);
2882 (void)R_REG(&regs->macintmask); /* sync readback */
2883 wlc->macintmask = 0;
2884
2885 /* clear device interrupts */
2886 W_REG(&regs->macintstatus, macintstatus);
2887
2888 /* MI_DMAINT is indication of non-zero intstatus */
2889 if (macintstatus & MI_DMAINT) {
2890 /*
2891 * only fifo interrupt enabled is I_RI in
2892 * RX_FIFO. If MI_DMAINT is set, assume it
2893 * is set and clear the interrupt.
2894 */
2895 W_REG(&regs->intctrlregs[RX_FIFO].intstatus,
2896 DEF_RXINTMASK);
2897 }
2898
2899 return macintstatus;
2900}
2901
2902/* Update wlc->macintstatus and wlc->intstatus[]. */
2903/* Return true if they are updated successfully. false otherwise */
2904bool brcms_c_intrsupd(struct brcms_c_info *wlc)
2905{
2906 u32 macintstatus;
2907
2908 /* read and clear macintstatus and intstatus registers */
2909 macintstatus = wlc_intstatus(wlc, false);
2910
2911 /* device is removed */
2912 if (macintstatus == 0xffffffff)
2913 return false;
2914
2915 /* update interrupt status in software */
2916 wlc->macintstatus |= macintstatus;
2917
2918 return true;
2919}
2920
2921/*
2922 * First-level interrupt processing.
2923 * Return true if this was our interrupt, false otherwise.
2924 * *wantdpc will be set to true if further brcms_c_dpc() processing is required,
2925 * false otherwise.
2926 */
2927bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
2928{
2929 struct brcms_hardware *wlc_hw = wlc->hw;
2930 u32 macintstatus;
2931
2932 *wantdpc = false;
2933
2934 if (!wlc_hw->up || !wlc->macintmask)
2935 return false;
2936
2937 /* read and clear macintstatus and intstatus registers */
2938 macintstatus = wlc_intstatus(wlc, true);
2939
2940 if (macintstatus == 0xffffffff)
2941 wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
2942 " path\n");
2943
2944 /* it is not for us */
2945 if (macintstatus == 0)
2946 return false;
2947
2948 *wantdpc = true;
2949
2950 /* save interrupt status bits */
2951 wlc->macintstatus = macintstatus;
2952
2953 return true;
2954
2955}
2956
2957static bool
2958brcms_b_dotxstatus(struct brcms_hardware *wlc_hw, struct tx_status *txs,
2959 u32 s2)
2960{
2961 /* discard intermediate indications for ucode with one legitimate case:
2962 * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
2963 * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
2964 * transmission count)
2965 */
2966 if (!(txs->status & TX_STATUS_AMPDU)
2967 && (txs->status & TX_STATUS_INTERMEDIATE)) {
2968 return false;
2969 }
2970
2971 return brcms_c_dotxstatus(wlc_hw->wlc, txs, s2);
2972}
2973
2974/* process tx completion events in BMAC
2975 * Return true if more tx status need to be processed. false otherwise.
2976 */
2977static bool
2978brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
2979{
2980 bool morepending = false;
2981 struct brcms_c_info *wlc = wlc_hw->wlc;
2982 d11regs_t *regs;
2983 struct tx_status txstatus, *txs;
2984 u32 s1, s2;
2985 uint n = 0;
2986 /*
2987 * Param 'max_tx_num' indicates max. # tx status to process before
2988 * break out.
2989 */
2990 uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1;
2991
2992 BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
2993
2994 txs = &txstatus;
2995 regs = wlc_hw->regs;
2996 while (!(*fatal)
2997 && (s1 = R_REG(&regs->frmtxstatus)) & TXS_V) {
2998
2999 if (s1 == 0xffffffff) {
3000 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
3001 wlc_hw->unit, __func__);
3002 return morepending;
3003 }
3004
3005 s2 = R_REG(&regs->frmtxstatus2);
3006
3007 txs->status = s1 & TXS_STATUS_MASK;
3008 txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
3009 txs->sequence = s2 & TXS_SEQ_MASK;
3010 txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
3011 txs->lasttxtime = 0;
3012
3013 *fatal = brcms_b_dotxstatus(wlc_hw, txs, s2);
3014
3015 /* !give others some time to run! */
3016 if (++n >= max_tx_num)
3017 break;
3018 }
3019
3020 if (*fatal)
3021 return 0;
3022
3023 if (n >= max_tx_num)
3024 morepending = true;
3025
3026 if (!pktq_empty(&wlc->pkt_queue->q))
3027 brcms_c_send_q(wlc);
3028
3029 return morepending;
3030}
3031
3032void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
3033{
3034 struct brcms_hardware *wlc_hw = wlc->hw;
3035 d11regs_t *regs = wlc_hw->regs;
3036 u32 mc, mi;
3037 struct wiphy *wiphy = wlc->wiphy;
3038
3039 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
3040 wlc_hw->band->bandunit);
3041
3042 /*
3043 * Track overlapping suspend requests
3044 */
3045 wlc_hw->mac_suspend_depth++;
3046 if (wlc_hw->mac_suspend_depth > 1)
3047 return;
3048
3049 /* force the core awake */
3050 brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
3051
3052 mc = R_REG(&regs->maccontrol);
3053
3054 if (mc == 0xffffffff) {
3055 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
3056 __func__);
3057 brcms_down(wlc->wl);
3058 return;
3059 }
3060 WARN_ON(mc & MCTL_PSM_JMP_0);
3061 WARN_ON(!(mc & MCTL_PSM_RUN));
3062 WARN_ON(!(mc & MCTL_EN_MAC));
3063
3064 mi = R_REG(&regs->macintstatus);
3065 if (mi == 0xffffffff) {
3066 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
3067 __func__);
3068 brcms_down(wlc->wl);
3069 return;
3070 }
3071 WARN_ON(mi & MI_MACSSPNDD);
3072
3073 brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0);
3074
3075 SPINWAIT(!(R_REG(&regs->macintstatus) & MI_MACSSPNDD),
3076 BRCMS_MAX_MAC_SUSPEND);
3077
3078 if (!(R_REG(&regs->macintstatus) & MI_MACSSPNDD)) {
3079 wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
3080 " and MI_MACSSPNDD is still not on.\n",
3081 wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
3082 wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
3083 "psm_brc 0x%04x\n", wlc_hw->unit,
3084 R_REG(&regs->psmdebug),
3085 R_REG(&regs->phydebug),
3086 R_REG(&regs->psm_brc));
3087 }
3088
3089 mc = R_REG(&regs->maccontrol);
3090 if (mc == 0xffffffff) {
3091 wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
3092 __func__);
3093 brcms_down(wlc->wl);
3094 return;
3095 }
3096 WARN_ON(mc & MCTL_PSM_JMP_0);
3097 WARN_ON(!(mc & MCTL_PSM_RUN));
3098 WARN_ON(mc & MCTL_EN_MAC);
3099}
3100
3101void brcms_c_enable_mac(struct brcms_c_info *wlc)
3102{
3103 struct brcms_hardware *wlc_hw = wlc->hw;
3104 d11regs_t *regs = wlc_hw->regs;
3105 u32 mc, mi;
3106
3107 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
3108 wlc->band->bandunit);
3109
3110 /*
3111 * Track overlapping suspend requests
3112 */
3113 wlc_hw->mac_suspend_depth--;
3114 if (wlc_hw->mac_suspend_depth > 0)
3115 return;
3116
3117 mc = R_REG(&regs->maccontrol);
3118 WARN_ON(mc & MCTL_PSM_JMP_0);
3119 WARN_ON(mc & MCTL_EN_MAC);
3120 WARN_ON(!(mc & MCTL_PSM_RUN));
3121
3122 brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
3123 W_REG(&regs->macintstatus, MI_MACSSPNDD);
3124
3125 mc = R_REG(&regs->maccontrol);
3126 WARN_ON(mc & MCTL_PSM_JMP_0);
3127 WARN_ON(!(mc & MCTL_EN_MAC));
3128 WARN_ON(!(mc & MCTL_PSM_RUN));
3129
3130 mi = R_REG(&regs->macintstatus);
3131 WARN_ON(mi & MI_MACSSPNDD);
3132
3133 brcms_c_ucode_wake_override_clear(wlc_hw,
3134 BRCMS_WAKE_OVERRIDE_MACSUSPEND);
3135}
3136
3137static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw)
3138{
3139 u8 rate;
3140 u8 rates[8] = {
3141 BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M,
3142 BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M
3143 };
3144 u16 entry_ptr;
3145 u16 pctl1;
3146 uint i;
3147
3148 if (!BRCMS_PHY_11N_CAP(wlc_hw->band))
3149 return;
3150
3151 /* walk the phy rate table and update the entries */
3152 for (i = 0; i < ARRAY_SIZE(rates); i++) {
3153 rate = rates[i];
3154
3155 entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate);
3156
3157 /* read the SHM Rate Table entry OFDM PCTL1 values */
3158 pctl1 =
3159 brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
3160
3161 /* modify the value */
3162 pctl1 &= ~PHY_TXC1_MODE_MASK;
3163 pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
3164
3165 /* Update the SHM Rate Table entry OFDM PCTL1 values */
3166 brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
3167 pctl1);
3168 }
3169}
3170
3171static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
3172 u8 rate)
3173{
3174 uint i;
3175 u8 plcp_rate = 0;
3176 struct plcp_signal_rate_lookup {
3177 u8 rate;
3178 u8 signal_rate;
3179 };
3180 /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
3181 const struct plcp_signal_rate_lookup rate_lookup[] = {
3182 {BRCM_RATE_6M, 0xB},
3183 {BRCM_RATE_9M, 0xF},
3184 {BRCM_RATE_12M, 0xA},
3185 {BRCM_RATE_18M, 0xE},
3186 {BRCM_RATE_24M, 0x9},
3187 {BRCM_RATE_36M, 0xD},
3188 {BRCM_RATE_48M, 0x8},
3189 {BRCM_RATE_54M, 0xC}
3190 };
3191
3192 for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
3193 if (rate == rate_lookup[i].rate) {
3194 plcp_rate = rate_lookup[i].signal_rate;
3195 break;
3196 }
3197 }
3198
3199 /* Find the SHM pointer to the rate table entry by looking in the
3200 * Direct-map Table
3201 */
3202 return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
3203}
3204
3205void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode)
3206{
3207 wlc_hw->hw_stf_ss_opmode = stf_mode;
3208
3209 if (wlc_hw->clk)
3210 brcms_upd_ofdm_pctl1_table(wlc_hw);
3211}
3212
3213void
3214brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
3215 u32 *tsf_h_ptr)
3216{
3217 d11regs_t *regs = wlc_hw->regs;
3218
3219 /* read the tsf timer low, then high to get an atomic read */
3220 *tsf_l_ptr = R_REG(&regs->tsf_timerlow);
3221 *tsf_h_ptr = R_REG(&regs->tsf_timerhigh);
3222
3223 return;
3224}
3225
3226static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
3227{
3228 d11regs_t *regs;
3229 u32 w, val;
3230 struct wiphy *wiphy = wlc_hw->wlc->wiphy;
3231
3232 BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
3233
3234 regs = wlc_hw->regs;
3235
3236 /* Validate dchip register access */
3237
3238 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
3239 (void)R_REG(&regs->objaddr);
3240 w = R_REG(&regs->objdata);
3241
3242 /* Can we write and read back a 32bit register? */
3243 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
3244 (void)R_REG(&regs->objaddr);
3245 W_REG(&regs->objdata, (u32) 0xaa5555aa);
3246
3247 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
3248 (void)R_REG(&regs->objaddr);
3249 val = R_REG(&regs->objdata);
3250 if (val != (u32) 0xaa5555aa) {
3251 wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
3252 "expected 0xaa5555aa\n", wlc_hw->unit, val);
3253 return false;
3254 }
3255
3256 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
3257 (void)R_REG(&regs->objaddr);
3258 W_REG(&regs->objdata, (u32) 0x55aaaa55);
3259
3260 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
3261 (void)R_REG(&regs->objaddr);
3262 val = R_REG(&regs->objdata);
3263 if (val != (u32) 0x55aaaa55) {
3264 wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
3265 "expected 0x55aaaa55\n", wlc_hw->unit, val);
3266 return false;
3267 }
3268
3269 W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
3270 (void)R_REG(&regs->objaddr);
3271 W_REG(&regs->objdata, w);
3272
3273 /* clear CFPStart */
3274 W_REG(&regs->tsf_cfpstart, 0);
3275
3276 w = R_REG(&regs->maccontrol);
3277 if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
3278 (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
3279 wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
3280 "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
3281 (MCTL_IHR_EN | MCTL_WAKE),
3282 (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
3283 return false;
3284 }
3285
3286 return true;
3287}
3288
3289#define PHYPLL_WAIT_US 100000
3290
3291void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
3292{
3293 d11regs_t *regs;
3294 u32 tmp;
3295
3296 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3297
3298 tmp = 0;
3299 regs = wlc_hw->regs;
3300
3301 if (on) {
3302 if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
3303 OR_REG(&regs->clk_ctl_st,
3304 (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL |
3305 CCS_ERSRC_REQ_PHYPLL));
3306 SPINWAIT((R_REG(&regs->clk_ctl_st) &
3307 (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT),
3308 PHYPLL_WAIT_US);
3309
3310 tmp = R_REG(&regs->clk_ctl_st);
3311 if ((tmp & (CCS_ERSRC_AVAIL_HT)) !=
3312 (CCS_ERSRC_AVAIL_HT)) {
3313 wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
3314 " PLL failed\n", __func__);
3315 }
3316 } else {
3317 OR_REG(&regs->clk_ctl_st,
3318 (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL));
3319 SPINWAIT((R_REG(&regs->clk_ctl_st) &
3320 (CCS_ERSRC_AVAIL_D11PLL |
3321 CCS_ERSRC_AVAIL_PHYPLL)) !=
3322 (CCS_ERSRC_AVAIL_D11PLL |
3323 CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
3324
3325 tmp = R_REG(&regs->clk_ctl_st);
3326 if ((tmp &
3327 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
3328 !=
3329 (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) {
3330 wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
3331 "PHY PLL failed\n", __func__);
3332 }
3333 }
3334 } else {
3335 /* Since the PLL may be shared, other cores can still be requesting it;
3336 * so we'll deassert the request but not wait for status to comply.
3337 */
3338 AND_REG(&regs->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL);
3339 tmp = R_REG(&regs->clk_ctl_st);
3340 }
3341}
3342
3343void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
3344{
3345 bool dev_gone;
3346
3347 BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
3348
3349 dev_gone = DEVICEREMOVED(wlc_hw->wlc);
3350
3351 if (dev_gone)
3352 return;
3353
3354 if (wlc_hw->noreset)
3355 return;
3356
3357 /* radio off */
3358 wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
3359
3360 /* turn off analog core */
3361 wlc_phy_anacore(wlc_hw->band->pi, OFF);
3362
3363 /* turn off PHYPLL to save power */
3364 brcms_b_core_phypll_ctl(wlc_hw, false);
3365
3366 /* No need to set wlc->pub->radio_active = OFF
3367 * because this function needs down capability and
3368 * radio_active is designed for BCMNODOWN.
3369 */
3370
3371 /* remove gpio controls */
3372 if (wlc_hw->ucode_dbgsel)
3373 ai_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY);
3374
3375 wlc_hw->clk = false;
3376 ai_core_disable(wlc_hw->sih, 0);
3377 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
3378}
3379
3380/* power both the pll and external oscillator on/off */
3381static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
3382{
3383 BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
3384
3385 /* dont power down if plldown is false or we must poll hw radio disable */
3386 if (!want && wlc_hw->pllreq)
3387 return;
3388
3389 if (wlc_hw->sih)
3390 ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
3391
3392 wlc_hw->sbclk = want;
3393 if (!wlc_hw->sbclk) {
3394 wlc_hw->clk = false;
3395 if (wlc_hw->band && wlc_hw->band->pi)
3396 wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
3397 }
3398}
3399
3400static void brcms_c_flushqueues(struct brcms_c_info *wlc)
3401{
3402 struct brcms_hardware *wlc_hw = wlc->hw;
3403 uint i;
3404
3405 wlc->txpend16165war = 0;
3406
3407 /* free any posted tx packets */
3408 for (i = 0; i < NFIFO; i++)
3409 if (wlc_hw->di[i]) {
3410 dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
3411 TXPKTPENDCLR(wlc, i);
3412 BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
3413 }
3414
3415 /* free any posted rx packets */
3416 dma_rxreclaim(wlc_hw->di[RX_FIFO]);
3417}
3418
3419u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset)
3420{
3421 return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
3422}
3423
3424void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v)
3425{
3426 brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
3427}
3428
3429static u16
3430brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
3431{
3432 d11regs_t *regs = wlc_hw->regs;
3433 volatile u16 *objdata_lo = (volatile u16 *)&regs->objdata;
3434 volatile u16 *objdata_hi = objdata_lo + 1;
3435 u16 v;
3436
3437 W_REG(&regs->objaddr, sel | (offset >> 2));
3438 (void)R_REG(&regs->objaddr);
3439 if (offset & 2) {
3440 v = R_REG(objdata_hi);
3441 } else {
3442 v = R_REG(objdata_lo);
3443 }
3444
3445 return v;
3446}
3447
3448static void
3449brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
3450 u32 sel)
3451{
3452 d11regs_t *regs = wlc_hw->regs;
3453 volatile u16 *objdata_lo = (volatile u16 *)&regs->objdata;
3454 volatile u16 *objdata_hi = objdata_lo + 1;
3455
3456 W_REG(&regs->objaddr, sel | (offset >> 2));
3457 (void)R_REG(&regs->objaddr);
3458 if (offset & 2) {
3459 W_REG(objdata_hi, v);
3460 } else {
3461 W_REG(objdata_lo, v);
3462 }
3463}
3464
3465/* Copy a buffer to shared memory of specified type .
3466 * SHM 'offset' needs to be an even address and
3467 * Buffer length 'len' must be an even number of bytes
3468 * 'sel' selects the type of memory
3469 */
3470void
3471brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
3472 const void *buf, int len, u32 sel)
3473{
3474 u16 v;
3475 const u8 *p = (const u8 *)buf;
3476 int i;
3477
3478 if (len <= 0 || (offset & 1) || (len & 1))
3479 return;
3480
3481 for (i = 0; i < len; i += 2) {
3482 v = p[i] | (p[i + 1] << 8);
3483 brcms_b_write_objmem(wlc_hw, offset + i, v, sel);
3484 }
3485}
3486
3487/* Copy a piece of shared memory of specified type to a buffer .
3488 * SHM 'offset' needs to be an even address and
3489 * Buffer length 'len' must be an even number of bytes
3490 * 'sel' selects the type of memory
3491 */
3492void
3493brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
3494 int len, u32 sel)
3495{
3496 u16 v;
3497 u8 *p = (u8 *) buf;
3498 int i;
3499
3500 if (len <= 0 || (offset & 1) || (len & 1))
3501 return;
3502
3503 for (i = 0; i < len; i += 2) {
3504 v = brcms_b_read_objmem(wlc_hw, offset + i, sel);
3505 p[i] = v & 0xFF;
3506 p[i + 1] = (v >> 8) & 0xFF;
3507 }
3508}
3509
3510void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf,
3511 uint *len)
3512{
3513 BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n",
3514 wlc_hw->vars_size);
3515
3516 *buf = wlc_hw->vars;
3517 *len = wlc_hw->vars_size;
3518}
3519
3520void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL, u16 LRL)
3521{
3522 wlc_hw->SRL = SRL;
3523 wlc_hw->LRL = LRL;
3524
3525 /* write retry limit to SCR, shouldn't need to suspend */
3526 if (wlc_hw->up) {
3527 W_REG(&wlc_hw->regs->objaddr,
3528 OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
3529 (void)R_REG(&wlc_hw->regs->objaddr);
3530 W_REG(&wlc_hw->regs->objdata, wlc_hw->SRL);
3531 W_REG(&wlc_hw->regs->objaddr,
3532 OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
3533 (void)R_REG(&wlc_hw->regs->objaddr);
3534 W_REG(&wlc_hw->regs->objdata, wlc_hw->LRL);
3535 }
3536}
3537
3538void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, mbool req_bit)
3539{
3540 if (set) {
3541 if (mboolisset(wlc_hw->pllreq, req_bit))
3542 return;
3543
3544 mboolset(wlc_hw->pllreq, req_bit);
3545
3546 if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
3547 if (!wlc_hw->sbclk) {
3548 brcms_b_xtal(wlc_hw, ON);
3549 }
3550 }
3551 } else {
3552 if (!mboolisset(wlc_hw->pllreq, req_bit))
3553 return;
3554
3555 mboolclr(wlc_hw->pllreq, req_bit);
3556
3557 if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
3558 if (wlc_hw->sbclk) {
3559 brcms_b_xtal(wlc_hw, OFF);
3560 }
3561 }
3562 }
3563
3564 return;
3565}
3566
3567u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
3568{
3569 u16 table_ptr;
3570 u8 phy_rate, index;
3571
3572 /* get the phy specific rate encoding for the PLCP SIGNAL field */
3573 if (IS_OFDM(rate))
3574 table_ptr = M_RT_DIRMAP_A;
3575 else
3576 table_ptr = M_RT_DIRMAP_B;
3577
3578 /* for a given rate, the LS-nibble of the PLCP SIGNAL field is
3579 * the index into the rate table.
3580 */
3581 phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
3582 index = phy_rate & 0xf;
3583
3584 /* Find the SHM pointer to the rate table entry by looking in the
3585 * Direct-map Table
3586 */
3587 return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
3588}
3589
3590void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
3591{
3592 wlc_hw->antsel_avail = antsel_avail;
3593}
diff --git a/drivers/staging/brcm80211/brcmsmac/bmac.h b/drivers/staging/brcm80211/brcmsmac/bmac.h
new file mode 100644
index 00000000000..3c9ad4f3bd2
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/bmac.h
@@ -0,0 +1,174 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef _BRCM_BOTTOM_MAC_H_
17#define _BRCM_BOTTOM_MAC_H_
18
19#include <brcmu_wifi.h>
20#include "types.h"
21
22/* dup state between BMAC(struct brcms_hardware) and HIGH(struct brcms_c_info)
23 driver */
24struct brcms_b_state {
25 u32 machwcap; /* mac hw capibility */
26 u32 preamble_ovr; /* preamble override */
27};
28
29enum {
30 IOV_BMAC_DIAG,
31 IOV_BMAC_SBGPIOTIMERVAL,
32 IOV_BMAC_SBGPIOOUT,
33 IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */
34 IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */
35 IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */
36 IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */
37 IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */
38 IOV_BMAC_OTPDUMP,
39 IOV_BMAC_OTPSTAT,
40 IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */
41 IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */
42 IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */
43 IOV_BMAC_PCIELCREG, /* PCIE LCREG */
44 IOV_BMAC_SBGPIOTIMERMASK,
45 IOV_BMAC_RFDISABLEDLY,
46 IOV_BMAC_PCIEREG, /* PCIE REG */
47 IOV_BMAC_PCICFGREG, /* PCI Config register */
48 IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */
49 IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */
50 IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */
51 IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */
52 IOV_BMAC_DMALPBK,
53 IOV_BMAC_CCREG,
54 IOV_BMAC_COREREG,
55 IOV_BMAC_SDCIS,
56 IOV_BMAC_SDIO_DRIVE,
57 IOV_BMAC_OTPW,
58 IOV_BMAC_NVOTPW,
59 IOV_BMAC_SROM,
60 IOV_BMAC_SRCRC,
61 IOV_BMAC_CIS_SOURCE,
62 IOV_BMAC_CISVAR,
63 IOV_BMAC_OTPLOCK,
64 IOV_BMAC_OTP_CHIPID,
65 IOV_BMAC_CUSTOMVAR1,
66 IOV_BMAC_BOARDFLAGS,
67 IOV_BMAC_BOARDFLAGS2,
68 IOV_BMAC_WPSLED,
69 IOV_BMAC_NVRAM_SOURCE,
70 IOV_BMAC_OTP_RAW_READ,
71 IOV_BMAC_LAST
72};
73
74extern int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device,
75 uint unit, bool piomode, void *regsva, uint bustype,
76 void *btparam);
77extern int brcms_b_detach(struct brcms_c_info *wlc);
78extern void brcms_b_watchdog(void *arg);
79
80/* up/down, reset, clk */
81extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw,
82 uint offset, const void *buf, int len,
83 u32 sel);
84extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
85 void *buf, int len, u32 sel);
86#define brcms_b_copyfrom_shm(wlc_hw, offset, buf, len) \
87 brcms_b_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
88#define brcms_b_copyto_shm(wlc_hw, offset, buf, len) \
89 brcms_b_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
90
91extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
92extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
93extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
94extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
95extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
96extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
97extern void brcms_b_reset(struct brcms_hardware *wlc_hw);
98extern void brcms_b_init(struct brcms_hardware *wlc_hw, chanspec_t chanspec,
99 bool mute);
100extern int brcms_b_up_prep(struct brcms_hardware *wlc_hw);
101extern int brcms_b_up_finish(struct brcms_hardware *wlc_hw);
102extern int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw);
103extern int brcms_b_down_finish(struct brcms_hardware *wlc_hw);
104extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
105
106/* chanspec, ucode interface */
107extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
108 chanspec_t chanspec,
109 bool mute, struct txpwr_limits *txpwr);
110
111extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
112 uint *blocks);
113extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
114 u16 val, int bands);
115extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
116extern u16 brcms_b_mhf_get(struct brcms_hardware *wlc_hw, u8 idx, int bands);
117extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
118extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
119extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
120 u8 antsel_type);
121extern int brcms_b_state_get(struct brcms_hardware *wlc_hw,
122 struct brcms_b_state *state);
123extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
124 u16 v);
125extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
126extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw,
127 int offset, int len, void *buf);
128extern void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf,
129 uint *len);
130
131extern void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw,
132 u8 *ea);
133
134extern bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw);
135extern void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw,
136 bool shortslot);
137extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
138 u8 stf_mode);
139
140extern void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw);
141
142extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
143 u32 override_bit);
144extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
145 u32 override_bit);
146
147extern void brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw,
148 int match_reg_offset,
149 const u8 *addr);
150extern void brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw,
151 void *bcn, int len, bool both);
152
153extern void brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
154 u32 *tsf_h_ptr);
155extern void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin);
156extern void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax);
157
158extern void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL,
159 u16 LRL);
160
161extern void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw);
162
163
164/* API for BMAC driver (e.g. wlc_phy.c etc) */
165
166extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
167extern void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set,
168 mbool req_bit);
169extern void brcms_b_hw_up(struct brcms_hardware *wlc_hw);
170extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
171extern void brcms_b_antsel_set(struct brcms_hardware *wlc_hw,
172 u32 antsel_avail);
173
174#endif /* _BRCM_BOTTOM_MAC_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/channel.c b/drivers/staging/brcm80211/brcmsmac/channel.c
new file mode 100644
index 00000000000..f59693e1d8a
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/channel.c
@@ -0,0 +1,1559 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/types.h>
18#include <net/mac80211.h>
19
20#include <defs.h>
21#include "pub.h"
22#include "phy/phy_hal.h"
23#include "bmac.h"
24#include "main.h"
25#include "stf.h"
26#include "channel.h"
27
28#define VALID_CHANNEL20_DB(wlc, val) brcms_c_valid_channel20_db((wlc)->cmi, val)
29#define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \
30 brcms_c_valid_channel20_in_band((wlc)->cmi, bandunit, val)
31#define VALID_CHANNEL20(wlc, val) brcms_c_valid_channel20((wlc)->cmi, val)
32
33struct brcms_cm_band {
34 u8 locale_flags; /* struct locale_info flags */
35 chanvec_t valid_channels; /* List of valid channels in the country */
36 const chanvec_t *restricted_channels; /* List of restricted use channels */
37 const chanvec_t *radar_channels; /* List of radar sensitive channels */
38 u8 PAD[8];
39};
40
41struct brcms_cm_info {
42 struct brcms_pub *pub;
43 struct brcms_c_info *wlc;
44 char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */
45 uint srom_regrev; /* Regulatory Rev for the SROM ccode */
46 const struct country_info *country; /* current country def */
47 char ccode[BRCM_CNTRY_BUF_SZ]; /* current internal Country Code */
48 uint regrev; /* current Regulatory Revision */
49 char country_abbrev[BRCM_CNTRY_BUF_SZ]; /* current advertised ccode */
50 /* per-band state (one per phy/radio) */
51 struct brcms_cm_band bandstate[MAXBANDS];
52 /* quiet channels currently for radar sensitivity or 11h support */
53 chanvec_t quiet_channels; /* channels on which we cannot transmit */
54};
55
56static int brcms_c_channels_init(struct brcms_cm_info *wlc_cm,
57 const struct country_info *country);
58static void brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
59 const char *country_abbrev,
60 const char *ccode, uint regrev,
61 const struct country_info *country);
62static int brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm,
63 const char *ccode);
64static int brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm,
65 const char *country_abbrev,
66 const char *ccode, int regrev);
67static int brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm,
68 const char *ccode,
69 char *mapped_ccode, uint *mapped_regrev);
70
71static const struct country_info *
72brcms_c_country_lookup_direct(const char *ccode, uint regrev);
73
74static const struct country_info *
75brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm,
76 const char *ccode, char *mapped_ccode,
77 uint *mapped_regrev);
78
79static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm);
80static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm);
81static bool brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm,
82 chanspec_t chspec);
83static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val);
84static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
85 uint bandunit, uint val);
86static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val);
87
88static const struct country_info *
89brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode);
90
91static void brcms_c_locale_get_channels(const struct locale_info *locale,
92 chanvec_t *valid_channels);
93static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx);
94static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx);
95static bool brcms_c_japan(struct brcms_c_info *wlc);
96static bool brcms_c_japan_ccode(const char *ccode);
97static void brcms_c_channel_min_txpower_limits_with_local_constraint(
98 struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
99 u8 local_constraint_qdbm);
100static void brcms_c_locale_add_channels(chanvec_t *target,
101 const chanvec_t *channels);
102static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx);
103static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx);
104
105/* QDB() macro takes a dB value and converts to a quarter dB value */
106#ifdef QDB
107#undef QDB
108#endif
109#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
110
111/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
112
113/*
114 * Some common channel sets
115 */
116
117/* No channels */
118static const chanvec_t chanvec_none = {
119 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00}
123};
124
125/* All 2.4 GHz HW channels */
126const chanvec_t chanvec_all_2G = {
127 {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00}
131};
132
133/* All 5 GHz HW channels */
134const chanvec_t chanvec_all_5G = {
135 {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
136 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
137 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
138 0x11, 0x11, 0x11, 0x01}
139};
140
141/*
142 * Radar channel sets
143 */
144
145/* No radar */
146#define radar_set_none chanvec_none
147
148static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */
149 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */
150 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */
151 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */
152 0x00, 0x00, 0x00, 0x00}
153};
154
155/*
156 * Restricted channel sets
157 */
158
159#define restricted_set_none chanvec_none
160
161/* Channels 34, 38, 42, 46 */
162static const chanvec_t restricted_set_japan_legacy = {
163 {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00}
167};
168
169/* Channels 12, 13 */
170static const chanvec_t restricted_set_2g_short = {
171 {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00}
175};
176
177/* Channel 165 */
178static const chanvec_t restricted_chan_165 = {
179 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00}
183};
184
185/* Channels 36 - 48 & 149 - 165 */
186static const chanvec_t restricted_low_hi = {
187 {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00}
191};
192
193/* Channels 12 - 14 */
194static const chanvec_t restricted_set_12_13_14 = {
195 {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x00, 0x00, 0x00}
199};
200
201#define LOCALE_CHAN_01_11 (1<<0)
202#define LOCALE_CHAN_12_13 (1<<1)
203#define LOCALE_CHAN_14 (1<<2)
204#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */
205#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */
206#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */
207#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */
208#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */
209#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */
210#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */
211#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */
212#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */
213#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */
214#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */
215#define LOCALE_CHAN_52_140_ALL (1<<14)
216#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */
217
218#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
219#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
220#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
221#define LOCALE_CHAN_100_140 \
222 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
223#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
224#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4
225
226#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14)
227
228#define LOCALE_RADAR_SET_NONE 0
229#define LOCALE_RADAR_SET_1 1
230
231#define LOCALE_RESTRICTED_NONE 0
232#define LOCALE_RESTRICTED_SET_2G_SHORT 1
233#define LOCALE_RESTRICTED_CHAN_165 2
234#define LOCALE_CHAN_ALL_5G 3
235#define LOCALE_RESTRICTED_JAPAN_LEGACY 4
236#define LOCALE_RESTRICTED_11D_2G 5
237#define LOCALE_RESTRICTED_11D_5G 6
238#define LOCALE_RESTRICTED_LOW_HI 7
239#define LOCALE_RESTRICTED_12_13_14 8
240
241/* global memory to provide working buffer for expanded locale */
242
243static const chanvec_t *g_table_radar_set[] = {
244 &chanvec_none,
245 &radar_set1
246};
247
248static const chanvec_t *g_table_restricted_chan[] = {
249 &chanvec_none, /* restricted_set_none */
250 &restricted_set_2g_short,
251 &restricted_chan_165,
252 &chanvec_all_5G,
253 &restricted_set_japan_legacy,
254 &chanvec_all_2G, /* restricted_set_11d_2G */
255 &chanvec_all_5G, /* restricted_set_11d_5G */
256 &restricted_low_hi,
257 &restricted_set_12_13_14
258};
259
260static const chanvec_t locale_2g_01_11 = {
261 {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x00}
265};
266
267static const chanvec_t locale_2g_12_13 = {
268 {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 0x00, 0x00, 0x00, 0x00}
272};
273
274static const chanvec_t locale_2g_14 = {
275 {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
278 0x00, 0x00, 0x00, 0x00}
279};
280
281static const chanvec_t locale_5g_LOW_JP1 = {
282 {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x00}
286};
287
288static const chanvec_t locale_5g_LOW_JP2 = {
289 {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00}
293};
294
295static const chanvec_t locale_5g_LOW1 = {
296 {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00}
300};
301
302static const chanvec_t locale_5g_LOW2 = {
303 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00}
307};
308
309static const chanvec_t locale_5g_LOW3 = {
310 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
311 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00}
314};
315
316static const chanvec_t locale_5g_MID1 = {
317 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00}
321};
322
323static const chanvec_t locale_5g_MID2 = {
324 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00}
328};
329
330static const chanvec_t locale_5g_MID3 = {
331 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00}
335};
336
337static const chanvec_t locale_5g_HIGH1 = {
338 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00}
342};
343
344static const chanvec_t locale_5g_HIGH2 = {
345 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00}
349};
350
351static const chanvec_t locale_5g_HIGH3 = {
352 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00}
356};
357
358static const chanvec_t locale_5g_52_140_ALL = {
359 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
360 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
361 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00}
363};
364
365static const chanvec_t locale_5g_HIGH4 = {
366 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
369 0x11, 0x11, 0x11, 0x11}
370};
371
372static const chanvec_t *g_table_locale_base[] = {
373 &locale_2g_01_11,
374 &locale_2g_12_13,
375 &locale_2g_14,
376 &locale_5g_LOW_JP1,
377 &locale_5g_LOW_JP2,
378 &locale_5g_LOW1,
379 &locale_5g_LOW2,
380 &locale_5g_LOW3,
381 &locale_5g_MID1,
382 &locale_5g_MID2,
383 &locale_5g_MID3,
384 &locale_5g_HIGH1,
385 &locale_5g_HIGH2,
386 &locale_5g_HIGH3,
387 &locale_5g_52_140_ALL,
388 &locale_5g_HIGH4
389};
390
391static void brcms_c_locale_add_channels(chanvec_t *target,
392 const chanvec_t *channels)
393{
394 u8 i;
395 for (i = 0; i < sizeof(chanvec_t); i++) {
396 target->vec[i] |= channels->vec[i];
397 }
398}
399
400static void brcms_c_locale_get_channels(const struct locale_info *locale,
401 chanvec_t *channels)
402{
403 u8 i;
404
405 memset(channels, 0, sizeof(chanvec_t));
406
407 for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) {
408 if (locale->valid_channels & (1 << i)) {
409 brcms_c_locale_add_channels(channels,
410 g_table_locale_base[i]);
411 }
412 }
413}
414
415/*
416 * Locale Definitions - 2.4 GHz
417 */
418static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */
419 LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
420 LOCALE_RADAR_SET_NONE,
421 LOCALE_RESTRICTED_SET_2G_SHORT,
422 {QDB(19), QDB(19), QDB(19),
423 QDB(19), QDB(19), QDB(19)},
424 {20, 20, 20, 0},
425 BRCMS_EIRP
426};
427
428/*
429 * Locale Definitions - 5 GHz
430 */
431static const struct locale_info locale_11 = {
432 /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
433 LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
434 LOCALE_RADAR_SET_1,
435 LOCALE_RESTRICTED_NONE,
436 {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
437 {23, 23, 23, 30, 30},
438 BRCMS_EIRP | BRCMS_DFS_EU
439};
440
441#define LOCALE_2G_IDX_i 0
442static const struct locale_info *g_locale_2g_table[] = {
443 &locale_i
444};
445
446#define LOCALE_5G_IDX_11 0
447static const struct locale_info *g_locale_5g_table[] = {
448 &locale_11
449};
450
451/*
452 * MIMO Locale Definitions - 2.4 GHz
453 */
454static const struct locale_mimo_info locale_bn = {
455 {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
456 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
457 QDB(13), QDB(13), QDB(13)},
458 {0, 0, QDB(13), QDB(13), QDB(13),
459 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
460 QDB(13), 0, 0},
461 0
462};
463
464/* locale mimo 2g indexes */
465#define LOCALE_MIMO_IDX_bn 0
466
467static const struct locale_mimo_info *g_mimo_2g_table[] = {
468 &locale_bn
469};
470
471/*
472 * MIMO Locale Definitions - 5 GHz
473 */
474static const struct locale_mimo_info locale_11n = {
475 { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
476 {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
477 0
478};
479
480#define LOCALE_MIMO_IDX_11n 0
481static const struct locale_mimo_info *g_mimo_5g_table[] = {
482 &locale_11n
483};
484
485#ifdef LC
486#undef LC
487#endif
488#define LC(id) LOCALE_MIMO_IDX_ ## id
489
490#ifdef LC_2G
491#undef LC_2G
492#endif
493#define LC_2G(id) LOCALE_2G_IDX_ ## id
494
495#ifdef LC_5G
496#undef LC_5G
497#endif
498#define LC_5G(id) LOCALE_5G_IDX_ ## id
499
500#define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
501
502static const struct {
503 char abbrev[BRCM_CNTRY_BUF_SZ]; /* country abbreviation */
504 struct country_info country;
505} cntry_locales[] = {
506 {
507 "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */
508};
509
510#ifdef SUPPORT_40MHZ
511/* 20MHz channel info for 40MHz pairing support */
512struct chan20_info {
513 u8 sb;
514 u8 adj_sbs;
515};
516
517/* indicates adjacent channels that are allowed for a 40 Mhz channel and
518 * those that permitted by the HT
519 */
520struct chan20_info chan20_info[] = {
521 /* 11b/11g */
522/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
523/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
524/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
525/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
526/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
527/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
528/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
529/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
530/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
531/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
532/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
533/* 11 */ {12, (CH_LOWER_SB)},
534/* 12 */ {13, (CH_LOWER_SB)},
535/* 13 */ {14, (CH_LOWER_SB)},
536
537/* 11a japan high */
538/* 14 */ {34, (CH_UPPER_SB)},
539/* 15 */ {38, (CH_LOWER_SB)},
540/* 16 */ {42, (CH_LOWER_SB)},
541/* 17 */ {46, (CH_LOWER_SB)},
542
543/* 11a usa low */
544/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
545/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
546/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
547/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
548/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
549/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
550/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
551/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
552
553/* 11a Europe */
554/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
555/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
556/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
557/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
558/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
559/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
560/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
561/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
562/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
563/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
564/* 36 */ {140, (CH_LOWER_SB)},
565
566/* 11a usa high, ref5 only */
567/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
568/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
569/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
570/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
571/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
572/* 41 */ {165, (CH_LOWER_SB)},
573
574/* 11a japan */
575/* 42 */ {184, (CH_UPPER_SB)},
576/* 43 */ {188, (CH_LOWER_SB)},
577/* 44 */ {192, (CH_UPPER_SB)},
578/* 45 */ {196, (CH_LOWER_SB)},
579/* 46 */ {200, (CH_UPPER_SB)},
580/* 47 */ {204, (CH_LOWER_SB)},
581/* 48 */ {208, (CH_UPPER_SB)},
582/* 49 */ {212, (CH_LOWER_SB)},
583/* 50 */ {216, (CH_LOWER_SB)}
584};
585#endif /* SUPPORT_40MHZ */
586
587static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx)
588{
589 if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) {
590 return NULL; /* error condition */
591 }
592 return g_locale_2g_table[locale_idx];
593}
594
595static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx)
596{
597 if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) {
598 return NULL; /* error condition */
599 }
600 return g_locale_5g_table[locale_idx];
601}
602
603static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx)
604{
605 if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) {
606 return NULL;
607 }
608 return g_mimo_2g_table[locale_idx];
609}
610
611static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx)
612{
613 if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) {
614 return NULL;
615 }
616 return g_mimo_5g_table[locale_idx];
617}
618
619struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
620{
621 struct brcms_cm_info *wlc_cm;
622 char country_abbrev[BRCM_CNTRY_BUF_SZ];
623 const struct country_info *country;
624 struct brcms_pub *pub = wlc->pub;
625 char *ccode;
626
627 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
628
629 wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
630 if (wlc_cm == NULL) {
631 wiphy_err(wlc->wiphy, "wl%d: %s: out of memory", pub->unit,
632 __func__);
633 return NULL;
634 }
635 wlc_cm->pub = pub;
636 wlc_cm->wlc = wlc;
637 wlc->cmi = wlc_cm;
638
639 /* store the country code for passing up as a regulatory hint */
640 ccode = getvar(wlc->pub->vars, "ccode");
641 if (ccode) {
642 strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
643 }
644
645 /* internal country information which must match regulatory constraints in firmware */
646 memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
647 strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
648 country = brcms_c_country_lookup(wlc, country_abbrev);
649
650 /* save default country for exiting 11d regulatory mode */
651 strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
652
653 /* initialize autocountry_default to driver default */
654 strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1);
655
656 brcms_c_set_countrycode(wlc_cm, country_abbrev);
657
658 return wlc_cm;
659}
660
661void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm)
662{
663 kfree(wlc_cm);
664}
665
666u8
667brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
668 uint bandunit)
669{
670 return wlc_cm->bandstate[bandunit].locale_flags;
671}
672
673/* set the driver's current country and regulatory information using a country code
674 * as the source. Lookup built in country information found with the country code.
675 */
676static int
677brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode)
678{
679 char country_abbrev[BRCM_CNTRY_BUF_SZ];
680 strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ);
681 return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
682}
683
684static int
685brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm,
686 const char *country_abbrev,
687 const char *ccode, int regrev)
688{
689 const struct country_info *country;
690 char mapped_ccode[BRCM_CNTRY_BUF_SZ];
691 uint mapped_regrev;
692
693 /* if regrev is -1, lookup the mapped country code,
694 * otherwise use the ccode and regrev directly
695 */
696 if (regrev == -1) {
697 /* map the country code to a built-in country code, regrev, and country_info */
698 country =
699 brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode,
700 &mapped_regrev);
701 } else {
702 /* find the matching built-in country definition */
703 country = brcms_c_country_lookup_direct(ccode, regrev);
704 strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
705 mapped_regrev = regrev;
706 }
707
708 if (country == NULL)
709 return -EINVAL;
710
711 /* set the driver state for the country */
712 brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
713 mapped_regrev, country);
714
715 return 0;
716}
717
718/* set the driver's current country and regulatory information using a country code
719 * as the source. Look up built in country information found with the country code.
720 */
721static void
722brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
723 const char *country_abbrev,
724 const char *ccode, uint regrev,
725 const struct country_info *country)
726{
727 const struct locale_mimo_info *li_mimo;
728 const struct locale_info *locale;
729 struct brcms_c_info *wlc = wlc_cm->wlc;
730 char prev_country_abbrev[BRCM_CNTRY_BUF_SZ];
731
732 /* save current country state */
733 wlc_cm->country = country;
734
735 memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
736 strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
737 BRCM_CNTRY_BUF_SZ - 1);
738
739 strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
740 strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
741 wlc_cm->regrev = regrev;
742
743 /* disable/restore nmode based on country regulations */
744 li_mimo = brcms_c_get_mimo_2g(country->locale_mimo_2G);
745 if (li_mimo && (li_mimo->flags & BRCMS_NO_MIMO)) {
746 brcms_c_set_nmode(wlc, OFF);
747 wlc->stf->no_cddstbc = true;
748 } else {
749 wlc->stf->no_cddstbc = false;
750 if (N_ENAB(wlc->pub) != wlc->protection->nmode_user)
751 brcms_c_set_nmode(wlc, wlc->protection->nmode_user);
752 }
753
754 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
755 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
756 /* set or restore gmode as required by regulatory */
757 locale = brcms_c_get_locale_2g(country->locale_2G);
758 if (locale && (locale->flags & BRCMS_NO_OFDM)) {
759 brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
760 } else {
761 brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
762 }
763
764 brcms_c_channels_init(wlc_cm, country);
765
766 return;
767}
768
769/* Lookup a country info structure from a null terminated country code
770 * The lookup is case sensitive.
771 */
772static const struct country_info *
773brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode)
774{
775 const struct country_info *country;
776 char mapped_ccode[BRCM_CNTRY_BUF_SZ];
777 uint mapped_regrev;
778
779 /* map the country code to a built-in country code, regrev, and country_info struct */
780 country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode,
781 &mapped_regrev);
782
783 return country;
784}
785
786static const struct country_info *
787brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode,
788 char *mapped_ccode, uint *mapped_regrev)
789{
790 struct brcms_c_info *wlc = wlc_cm->wlc;
791 const struct country_info *country;
792 uint srom_regrev = wlc_cm->srom_regrev;
793 const char *srom_ccode = wlc_cm->srom_ccode;
794 int mapped;
795
796 /* check for currently supported ccode size */
797 if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) {
798 wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
799 "match\n", wlc->pub->unit, __func__, ccode);
800 return NULL;
801 }
802
803 /* default mapping is the given ccode and regrev 0 */
804 strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
805 *mapped_regrev = 0;
806
807 /* If the desired country code matches the srom country code,
808 * then the mapped country is the srom regulatory rev.
809 * Otherwise look for an aggregate mapping.
810 */
811 if (!strcmp(srom_ccode, ccode)) {
812 *mapped_regrev = srom_regrev;
813 mapped = 0;
814 wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
815 } else {
816 mapped =
817 brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
818 mapped_regrev);
819 }
820
821 /* find the matching built-in country definition */
822 country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
823
824 /* if there is not an exact rev match, default to rev zero */
825 if (country == NULL && *mapped_regrev != 0) {
826 *mapped_regrev = 0;
827 country =
828 brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
829 }
830
831 return country;
832}
833
834static int
835brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode,
836 char *mapped_ccode, uint *mapped_regrev)
837{
838 return false;
839}
840
841/* Lookup a country info structure from a null terminated country
842 * abbreviation and regrev directly with no translation.
843 */
844static const struct country_info *
845brcms_c_country_lookup_direct(const char *ccode, uint regrev)
846{
847 uint size, i;
848
849 /* Should just return 0 for single locale driver. */
850 /* Keep it this way in case we add more locales. (for now anyway) */
851
852 /* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */
853 if (regrev > 0)
854 return NULL;
855
856 /* find matched table entry from country code */
857 size = ARRAY_SIZE(cntry_locales);
858 for (i = 0; i < size; i++) {
859 if (strcmp(ccode, cntry_locales[i].abbrev) == 0) {
860 return &cntry_locales[i].country;
861 }
862 }
863 return NULL;
864}
865
866static int
867brcms_c_channels_init(struct brcms_cm_info *wlc_cm,
868 const struct country_info *country)
869{
870 struct brcms_c_info *wlc = wlc_cm->wlc;
871 uint i, j;
872 struct brcms_band *band;
873 const struct locale_info *li;
874 chanvec_t sup_chan;
875 const struct locale_mimo_info *li_mimo;
876
877 band = wlc->band;
878 for (i = 0; i < NBANDS(wlc);
879 i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
880
881 li = BAND_5G(band->bandtype) ?
882 brcms_c_get_locale_5g(country->locale_5G) :
883 brcms_c_get_locale_2g(country->locale_2G);
884 wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
885 li_mimo = BAND_5G(band->bandtype) ?
886 brcms_c_get_mimo_5g(country->locale_mimo_5G) :
887 brcms_c_get_mimo_2g(country->locale_mimo_2G);
888
889 /* merge the mimo non-mimo locale flags */
890 wlc_cm->bandstate[band->bandunit].locale_flags |=
891 li_mimo->flags;
892
893 wlc_cm->bandstate[band->bandunit].restricted_channels =
894 g_table_restricted_chan[li->restricted_channels];
895 wlc_cm->bandstate[band->bandunit].radar_channels =
896 g_table_radar_set[li->radar_channels];
897
898 /* set the channel availability,
899 * masking out the channels that may not be supported on this phy
900 */
901 wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
902 &sup_chan);
903 brcms_c_locale_get_channels(li,
904 &wlc_cm->bandstate[band->bandunit].
905 valid_channels);
906 for (j = 0; j < sizeof(chanvec_t); j++)
907 wlc_cm->bandstate[band->bandunit].valid_channels.
908 vec[j] &= sup_chan.vec[j];
909 }
910
911 brcms_c_quiet_channels_reset(wlc_cm);
912 brcms_c_channels_commit(wlc_cm);
913
914 return 0;
915}
916
917/* Update the radio state (enable/disable) and tx power targets
918 * based on a new set of channel/regulatory information
919 */
920static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm)
921{
922 struct brcms_c_info *wlc = wlc_cm->wlc;
923 uint chan;
924 struct txpwr_limits txpwr;
925
926 /* search for the existence of any valid channel */
927 for (chan = 0; chan < MAXCHANNEL; chan++) {
928 if (VALID_CHANNEL20_DB(wlc, chan)) {
929 break;
930 }
931 }
932 if (chan == MAXCHANNEL)
933 chan = INVCHANNEL;
934
935 /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */
936 if (chan == INVCHANNEL) {
937 /* country/locale with no valid channels, set the radio disable bit */
938 mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
939 wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
940 "nbands %d bandlocked %d\n", wlc->pub->unit,
941 __func__, wlc_cm->country_abbrev, NBANDS(wlc),
942 wlc->bandlocked);
943 } else
944 if (mboolisset(wlc->pub->radio_disabled,
945 WL_RADIO_COUNTRY_DISABLE)) {
946 /* country/locale with valid channel, clear the radio disable bit */
947 mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
948 }
949
950 /* Now that the country abbreviation is set, if the radio supports 2G, then
951 * set channel 14 restrictions based on the new locale.
952 */
953 if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) {
954 wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
955 brcms_c_japan(wlc) ? true :
956 false);
957 }
958
959 if (wlc->pub->up && chan != INVCHANNEL) {
960 brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
961 brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm,
962 &txpwr, BRCMS_TXPWR_MAX);
963 wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
964 }
965}
966
967/* reset the quiet channels vector to the union of the restricted and radar channel sets */
968static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm)
969{
970 struct brcms_c_info *wlc = wlc_cm->wlc;
971 uint i, j;
972 struct brcms_band *band;
973 const chanvec_t *chanvec;
974
975 memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t));
976
977 band = wlc->band;
978 for (i = 0; i < NBANDS(wlc);
979 i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
980
981 /* initialize quiet channels for restricted channels */
982 chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
983 for (j = 0; j < sizeof(chanvec_t); j++)
984 wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
985
986 }
987}
988
989static bool
990brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, chanspec_t chspec)
991{
992 return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ?
993 (isset
994 (wlc_cm->quiet_channels.vec,
995 LOWER_20_SB(CHSPEC_CHANNEL(chspec)))
996 || isset(wlc_cm->quiet_channels.vec,
997 UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm->
998 quiet_channels.
999 vec,
1000 CHSPEC_CHANNEL
1001 (chspec));
1002}
1003
1004/* Is the channel valid for the current locale? (but don't consider channels not
1005 * available due to bandlocking)
1006 */
1007static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val)
1008{
1009 struct brcms_c_info *wlc = wlc_cm->wlc;
1010
1011 return VALID_CHANNEL20(wlc, val) ||
1012 (!wlc->bandlocked
1013 && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val));
1014}
1015
1016/* Is the channel valid for the current locale and specified band? */
1017static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
1018 uint bandunit, uint val)
1019{
1020 return ((val < MAXCHANNEL)
1021 && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
1022}
1023
1024/* Is the channel valid for the current locale and current band? */
1025static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val)
1026{
1027 struct brcms_c_info *wlc = wlc_cm->wlc;
1028
1029 return ((val < MAXCHANNEL) &&
1030 isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
1031 val));
1032}
1033
1034static void
1035brcms_c_channel_min_txpower_limits_with_local_constraint(
1036 struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
1037 u8 local_constraint_qdbm)
1038{
1039 int j;
1040
1041 /* CCK Rates */
1042 for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) {
1043 txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
1044 }
1045
1046 /* 20 MHz Legacy OFDM SISO */
1047 for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) {
1048 txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
1049 }
1050
1051 /* 20 MHz Legacy OFDM CDD */
1052 for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) {
1053 txpwr->ofdm_cdd[j] =
1054 min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
1055 }
1056
1057 /* 40 MHz Legacy OFDM SISO */
1058 for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) {
1059 txpwr->ofdm_40_siso[j] =
1060 min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
1061 }
1062
1063 /* 40 MHz Legacy OFDM CDD */
1064 for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) {
1065 txpwr->ofdm_40_cdd[j] =
1066 min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
1067 }
1068
1069 /* 20MHz MCS 0-7 SISO */
1070 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) {
1071 txpwr->mcs_20_siso[j] =
1072 min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
1073 }
1074
1075 /* 20MHz MCS 0-7 CDD */
1076 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) {
1077 txpwr->mcs_20_cdd[j] =
1078 min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
1079 }
1080
1081 /* 20MHz MCS 0-7 STBC */
1082 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) {
1083 txpwr->mcs_20_stbc[j] =
1084 min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
1085 }
1086
1087 /* 20MHz MCS 8-15 MIMO */
1088 for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
1089 txpwr->mcs_20_mimo[j] =
1090 min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
1091
1092 /* 40MHz MCS 0-7 SISO */
1093 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) {
1094 txpwr->mcs_40_siso[j] =
1095 min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
1096 }
1097
1098 /* 40MHz MCS 0-7 CDD */
1099 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) {
1100 txpwr->mcs_40_cdd[j] =
1101 min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
1102 }
1103
1104 /* 40MHz MCS 0-7 STBC */
1105 for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) {
1106 txpwr->mcs_40_stbc[j] =
1107 min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
1108 }
1109
1110 /* 40MHz MCS 8-15 MIMO */
1111 for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
1112 txpwr->mcs_40_mimo[j] =
1113 min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
1114
1115 /* 40MHz MCS 32 */
1116 txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
1117
1118}
1119
1120void
1121brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, chanspec_t chanspec,
1122 u8 local_constraint_qdbm)
1123{
1124 struct brcms_c_info *wlc = wlc_cm->wlc;
1125 struct txpwr_limits txpwr;
1126
1127 brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
1128
1129 brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr,
1130 local_constraint_qdbm);
1131
1132 brcms_b_set_chanspec(wlc->hw, chanspec,
1133 (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0),
1134 &txpwr);
1135}
1136
1137#ifdef POWER_DBG
1138static void wlc_phy_txpower_limits_dump(struct txpwr_limits *txpwr)
1139{
1140 int i;
1141 char buf[80];
1142 char fraction[4][4] = { " ", ".25", ".5 ", ".75" };
1143
1144 sprintf(buf, "CCK ");
1145 for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) {
1146 sprintf(buf[strlen(buf)], " %2d%s",
1147 txpwr->cck[i] / BRCMS_TXPWR_DB_FACTOR,
1148 fraction[txpwr->cck[i] % BRCMS_TXPWR_DB_FACTOR]);
1149 }
1150 printk(KERN_DEBUG "%s\n", buf);
1151
1152 sprintf(buf, "20 MHz OFDM SISO ");
1153 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
1154 sprintf(buf[strlen(buf)], " %2d%s",
1155 txpwr->ofdm[i] / BRCMS_TXPWR_DB_FACTOR,
1156 fraction[txpwr->ofdm[i] % BRCMS_TXPWR_DB_FACTOR]);
1157 }
1158 printk(KERN_DEBUG "%s\n", buf);
1159
1160 sprintf(buf, "20 MHz OFDM CDD ");
1161 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
1162 sprintf(buf[strlen(buf)], " %2d%s",
1163 txpwr->ofdm_cdd[i] / BRCMS_TXPWR_DB_FACTOR,
1164 fraction[txpwr->ofdm_cdd[i] % BRCMS_TXPWR_DB_FACTOR]);
1165 }
1166 printk(KERN_DEBUG "%s\n", buf);
1167
1168 sprintf(buf, "40 MHz OFDM SISO ");
1169 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
1170 sprintf(buf[strlen(buf)], " %2d%s",
1171 txpwr->ofdm_40_siso[i] / BRCMS_TXPWR_DB_FACTOR,
1172 fraction[txpwr->ofdm_40_siso[i] %
1173 BRCMS_TXPWR_DB_FACTOR]);
1174 }
1175 printk(KERN_DEBUG "%s\n", buf);
1176
1177 sprintf(buf, "40 MHz OFDM CDD ");
1178 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
1179 sprintf(buf[strlen(buf)], " %2d%s",
1180 txpwr->ofdm_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR,
1181 fraction[txpwr->ofdm_40_cdd[i] %
1182 BRCMS_TXPWR_DB_FACTOR]);
1183 }
1184 printk(KERN_DEBUG "%s\n", buf);
1185
1186 sprintf(buf, "20 MHz MCS0-7 SISO ");
1187 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1188 sprintf(buf[strlen(buf)], " %2d%s",
1189 txpwr->mcs_20_siso[i] / BRCMS_TXPWR_DB_FACTOR,
1190 fraction[txpwr->mcs_20_siso[i] %
1191 BRCMS_TXPWR_DB_FACTOR]);
1192 }
1193 printk(KERN_DEBUG "%s\n", buf);
1194
1195 sprintf(buf, "20 MHz MCS0-7 CDD ");
1196 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1197 sprintf(buf[strlen(buf)], " %2d%s",
1198 txpwr->mcs_20_cdd[i] / BRCMS_TXPWR_DB_FACTOR,
1199 fraction[txpwr->mcs_20_cdd[i] %
1200 BRCMS_TXPWR_DB_FACTOR]);
1201 }
1202 printk(KERN_DEBUG "%s\n", buf);
1203
1204 sprintf(buf, "20 MHz MCS0-7 STBC ");
1205 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1206 sprintf(buf[strlen(buf)], " %2d%s",
1207 txpwr->mcs_20_stbc[i] / BRCMS_TXPWR_DB_FACTOR,
1208 fraction[txpwr->mcs_20_stbc[i] %
1209 BRCMS_TXPWR_DB_FACTOR]);
1210 }
1211 printk(KERN_DEBUG "%s\n", buf);
1212
1213 sprintf(buf, "20 MHz MCS8-15 SDM ");
1214 for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
1215 sprintf(buf[strlen(buf)], " %2d%s",
1216 txpwr->mcs_20_mimo[i] / BRCMS_TXPWR_DB_FACTOR,
1217 fraction[txpwr->mcs_20_mimo[i] %
1218 BRCMS_TXPWR_DB_FACTOR]);
1219 }
1220 printk(KERN_DEBUG "%s\n", buf);
1221
1222 sprintf(buf, "40 MHz MCS0-7 SISO ");
1223 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1224 sprintf(buf[strlen(buf)], " %2d%s",
1225 txpwr->mcs_40_siso[i] / BRCMS_TXPWR_DB_FACTOR,
1226 fraction[txpwr->mcs_40_siso[i] %
1227 BRCMS_TXPWR_DB_FACTOR]);
1228 }
1229 printk(KERN_DEBUG "%s\n", buf);
1230
1231 sprintf(buf, "40 MHz MCS0-7 CDD ");
1232 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1233 sprintf(buf[strlen(buf)], " %2d%s",
1234 txpwr->mcs_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR,
1235 fraction[txpwr->mcs_40_cdd[i] %
1236 BRCMS_TXPWR_DB_FACTOR]);
1237 }
1238 printk(KERN_DEBUG "%s\n", buf);
1239
1240 sprintf(buf, "40 MHz MCS0-7 STBC ");
1241 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1242 sprintf(buf[strlen(buf)], " %2d%s",
1243 txpwr->mcs_40_stbc[i] / BRCMS_TXPWR_DB_FACTOR,
1244 fraction[txpwr->mcs_40_stbc[i] %
1245 BRCMS_TXPWR_DB_FACTOR]);
1246 }
1247 printk(KERN_DEBUG "%s\n", buf);
1248
1249 sprintf(buf, "40 MHz MCS8-15 SDM ");
1250 for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
1251 sprintf(buf[strlen(buf)], " %2d%s",
1252 txpwr->mcs_40_mimo[i] / BRCMS_TXPWR_DB_FACTOR,
1253 fraction[txpwr->mcs_40_mimo[i] %
1254 BRCMS_TXPWR_DB_FACTOR]);
1255 }
1256 printk(KERN_DEBUG "%s\n", buf);
1257
1258 printk(KERN_DEBUG "MCS32 %2d%s\n",
1259 txpwr->mcs32 / BRCMS_TXPWR_DB_FACTOR,
1260 fraction[txpwr->mcs32 % BRCMS_TXPWR_DB_FACTOR]);
1261}
1262#endif /* POWER_DBG */
1263
1264void
1265brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec,
1266 struct txpwr_limits *txpwr)
1267{
1268 struct brcms_c_info *wlc = wlc_cm->wlc;
1269 uint i;
1270 uint chan;
1271 int maxpwr;
1272 int delta;
1273 const struct country_info *country;
1274 struct brcms_band *band;
1275 const struct locale_info *li;
1276 int conducted_max;
1277 int conducted_ofdm_max;
1278 const struct locale_mimo_info *li_mimo;
1279 int maxpwr20, maxpwr40;
1280 int maxpwr_idx;
1281 uint j;
1282
1283 memset(txpwr, 0, sizeof(struct txpwr_limits));
1284
1285 if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) {
1286 country = brcms_c_country_lookup(wlc, wlc->autocountry_default);
1287 if (country == NULL)
1288 return;
1289 } else {
1290 country = wlc_cm->country;
1291 }
1292
1293 chan = CHSPEC_CHANNEL(chanspec);
1294 band = wlc->bandstate[CHSPEC_BANDUNIT(chanspec)];
1295 li = BAND_5G(band->bandtype) ?
1296 brcms_c_get_locale_5g(country->locale_5G) :
1297 brcms_c_get_locale_2g(country->locale_2G);
1298
1299 li_mimo = BAND_5G(band->bandtype) ?
1300 brcms_c_get_mimo_5g(country->locale_mimo_5G) :
1301 brcms_c_get_mimo_2g(country->locale_mimo_2G);
1302
1303 if (li->flags & BRCMS_EIRP) {
1304 delta = band->antgain;
1305 } else {
1306 delta = 0;
1307 if (band->antgain > QDB(6))
1308 delta = band->antgain - QDB(6); /* Excess over 6 dB */
1309 }
1310
1311 if (li == &locale_i) {
1312 conducted_max = QDB(22);
1313 conducted_ofdm_max = QDB(22);
1314 }
1315
1316 /* CCK txpwr limits for 2.4G band */
1317 if (BAND_2G(band->bandtype)) {
1318 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
1319
1320 maxpwr = maxpwr - delta;
1321 maxpwr = max(maxpwr, 0);
1322 maxpwr = min(maxpwr, conducted_max);
1323
1324 for (i = 0; i < BRCMS_NUM_RATES_CCK; i++)
1325 txpwr->cck[i] = (u8) maxpwr;
1326 }
1327
1328 /* OFDM txpwr limits for 2.4G or 5G bands */
1329 if (BAND_2G(band->bandtype)) {
1330 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
1331
1332 } else {
1333 maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
1334 }
1335
1336 maxpwr = maxpwr - delta;
1337 maxpwr = max(maxpwr, 0);
1338 maxpwr = min(maxpwr, conducted_ofdm_max);
1339
1340 /* Keep OFDM lmit below CCK limit */
1341 if (BAND_2G(band->bandtype))
1342 maxpwr = min_t(int, maxpwr, txpwr->cck[0]);
1343
1344 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
1345 txpwr->ofdm[i] = (u8) maxpwr;
1346
1347 for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
1348 /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless
1349 * overriden by the locale specific code. We set this value to 0 as a
1350 * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value
1351 * to the 40 MHz value if it wasn't explicitly set.
1352 */
1353 txpwr->ofdm_40_siso[i] = 0;
1354
1355 txpwr->ofdm_cdd[i] = (u8) maxpwr;
1356
1357 txpwr->ofdm_40_cdd[i] = 0;
1358 }
1359
1360 /* MIMO/HT specific limits */
1361 if (li_mimo->flags & BRCMS_EIRP) {
1362 delta = band->antgain;
1363 } else {
1364 delta = 0;
1365 if (band->antgain > QDB(6))
1366 delta = band->antgain - QDB(6); /* Excess over 6 dB */
1367 }
1368
1369 if (BAND_2G(band->bandtype))
1370 maxpwr_idx = (chan - 1);
1371 else
1372 maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
1373
1374 maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
1375 maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
1376
1377 maxpwr20 = maxpwr20 - delta;
1378 maxpwr20 = max(maxpwr20, 0);
1379 maxpwr40 = maxpwr40 - delta;
1380 maxpwr40 = max(maxpwr40, 0);
1381
1382 /* Fill in the MCS 0-7 (SISO) rates */
1383 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1384
1385 /* 20 MHz has the same power as the corresponding OFDM rate unless
1386 * overriden by the locale specific code.
1387 */
1388 txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
1389 txpwr->mcs_40_siso[i] = 0;
1390 }
1391
1392 /* Fill in the MCS 0-7 CDD rates */
1393 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1394 txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
1395 txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
1396 }
1397
1398 /* These locales have SISO expressed in the table and override CDD later */
1399 if (li_mimo == &locale_bn) {
1400 if (li_mimo == &locale_bn) {
1401 maxpwr20 = QDB(16);
1402 maxpwr40 = 0;
1403
1404 if (chan >= 3 && chan <= 11) {
1405 maxpwr40 = QDB(16);
1406 }
1407 }
1408
1409 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1410 txpwr->mcs_20_siso[i] = (u8) maxpwr20;
1411 txpwr->mcs_40_siso[i] = (u8) maxpwr40;
1412 }
1413 }
1414
1415 /* Fill in the MCS 0-7 STBC rates */
1416 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1417 txpwr->mcs_20_stbc[i] = 0;
1418 txpwr->mcs_40_stbc[i] = 0;
1419 }
1420
1421 /* Fill in the MCS 8-15 SDM rates */
1422 for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
1423 txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
1424 txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
1425 }
1426
1427 /* Fill in MCS32 */
1428 txpwr->mcs32 = (u8) maxpwr40;
1429
1430 for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
1431 if (txpwr->ofdm_40_cdd[i] == 0)
1432 txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
1433 if (i == 0) {
1434 i = i + 1;
1435 if (txpwr->ofdm_40_cdd[i] == 0)
1436 txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
1437 }
1438 }
1439
1440 /* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't
1441 * provided explicitly.
1442 */
1443
1444 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1445 if (txpwr->mcs_40_siso[i] == 0)
1446 txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
1447 }
1448
1449 for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
1450 if (txpwr->ofdm_40_siso[i] == 0)
1451 txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
1452 if (i == 0) {
1453 i = i + 1;
1454 if (txpwr->ofdm_40_siso[i] == 0)
1455 txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
1456 }
1457 }
1458
1459 /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't
1460 * provided explicitly.
1461 */
1462 for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
1463 if (txpwr->mcs_20_stbc[i] == 0)
1464 txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
1465
1466 if (txpwr->mcs_40_stbc[i] == 0)
1467 txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
1468 }
1469
1470#ifdef POWER_DBG
1471 wlc_phy_txpower_limits_dump(txpwr);
1472#endif
1473 return;
1474}
1475
1476/* Returns true if currently set country is Japan or variant */
1477static bool brcms_c_japan(struct brcms_c_info *wlc)
1478{
1479 return brcms_c_japan_ccode(wlc->cmi->country_abbrev);
1480}
1481
1482/* JP, J1 - J10 are Japan ccodes */
1483static bool brcms_c_japan_ccode(const char *ccode)
1484{
1485 return (ccode[0] == 'J' &&
1486 (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
1487}
1488
1489/*
1490 * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands
1491 * are valid 20MZH channels in this locale and they are also a legal HT combination
1492 */
1493static bool
1494brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, chanspec_t chspec,
1495 bool dualband)
1496{
1497 struct brcms_c_info *wlc = wlc_cm->wlc;
1498 u8 channel = CHSPEC_CHANNEL(chspec);
1499
1500 /* check the chanspec */
1501 if (brcmu_chspec_malformed(chspec)) {
1502 wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
1503 wlc->pub->unit, chspec);
1504 return false;
1505 }
1506
1507 if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
1508 CHSPEC_BANDUNIT(chspec))
1509 return false;
1510
1511 /* Check a 20Mhz channel */
1512 if (CHSPEC_IS20(chspec)) {
1513 if (dualband)
1514 return VALID_CHANNEL20_DB(wlc_cm->wlc, channel);
1515 else
1516 return VALID_CHANNEL20(wlc_cm->wlc, channel);
1517 }
1518#ifdef SUPPORT_40MHZ
1519 /* We know we are now checking a 40MHZ channel, so we should only be here
1520 * for NPHYS
1521 */
1522 if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) {
1523 u8 upper_sideband = 0, idx;
1524 u8 num_ch20_entries =
1525 sizeof(chan20_info) / sizeof(struct chan20_info);
1526
1527 if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_BANDUNIT(chspec)))
1528 return false;
1529
1530 if (dualband) {
1531 if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) ||
1532 !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel)))
1533 return false;
1534 } else {
1535 if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) ||
1536 !VALID_CHANNEL20(wlc, UPPER_20_SB(channel)))
1537 return false;
1538 }
1539
1540 /* find the lower sideband info in the sideband array */
1541 for (idx = 0; idx < num_ch20_entries; idx++) {
1542 if (chan20_info[idx].sb == LOWER_20_SB(channel))
1543 upper_sideband = chan20_info[idx].adj_sbs;
1544 }
1545 /* check that the lower sideband allows an upper sideband */
1546 if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) ==
1547 (CH_UPPER_SB | CH_EWA_VALID))
1548 return true;
1549 return false;
1550 }
1551#endif /* 40 MHZ */
1552
1553 return false;
1554}
1555
1556bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, chanspec_t chspec)
1557{
1558 return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true);
1559}
diff --git a/drivers/staging/brcm80211/brcmsmac/channel.h b/drivers/staging/brcm80211/brcmsmac/channel.h
new file mode 100644
index 00000000000..d22f2f5f592
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/channel.h
@@ -0,0 +1,132 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_CHANNEL_H_
18#define _BRCM_CHANNEL_H_
19
20/* conversion for phy txpwr calculations that use .25 dB units */
21#define BRCMS_TXPWR_DB_FACTOR 4
22
23
24/* maxpwr mapping to 5GHz band channels:
25 * maxpwr[0] - channels [34-48]
26 * maxpwr[1] - channels [52-60]
27 * maxpwr[2] - channels [62-64]
28 * maxpwr[3] - channels [100-140]
29 * maxpwr[4] - channels [149-165]
30 */
31#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */
32
33/* power level in group of 2.4GHz band channels:
34 * maxpwr[0] - CCK channels [1]
35 * maxpwr[1] - CCK channels [2-10]
36 * maxpwr[2] - CCK channels [11-14]
37 * maxpwr[3] - OFDM channels [1]
38 * maxpwr[4] - OFDM channels [2-10]
39 * maxpwr[5] - OFDM channels [11-14]
40 */
41
42/* macro to get 2.4 GHz channel group index for tx power */
43#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) /* cck index */
44#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* ofdm index */
45
46/* macro to get 5 GHz channel group index for tx power */
47#define CHANNEL_POWER_IDX_5G(c) \
48 (((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4))))
49
50/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
51#define BRCMS_MAXPWR_TBL_SIZE 6
52/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
53#define BRCMS_MAXPWR_MIMO_TBL_SIZE 14
54
55#define NBANDS(wlc) ((wlc)->pub->_nbands)
56#define NBANDS_PUB(pub) ((pub)->_nbands)
57#define NBANDS_HW(hw) ((hw)->_nbands)
58
59#define IS_SINGLEBAND_5G(device) 0
60
61/* locale channel and power info. */
62struct locale_info {
63 u32 valid_channels;
64 /* List of radar sensitive channels */
65 u8 radar_channels;
66 /* List of channels used only if APs are detected */
67 u8 restricted_channels;
68 /* Max tx pwr in qdBm for each sub-band */
69 s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE];
70 s8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm
71 * per sub-band
72 */
73 u8 flags;
74};
75
76/* bits for locale_info flags */
77#define BRCMS_PEAK_CONDUCTED 0x00 /* Peak for locals */
78#define BRCMS_EIRP 0x01 /* Flag for EIRP */
79#define BRCMS_DFS_TPC 0x02 /* Flag for DFS TPC */
80#define BRCMS_NO_OFDM 0x04 /* Flag for No OFDM */
81#define BRCMS_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */
82#define BRCMS_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */
83#define BRCMS_RADAR_TYPE_EU 0x20 /* Flag for EU */
84#define BRCMS_DFS_FCC BRCMS_DFS_TPC /* Flag for DFS FCC */
85#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
86
87#define ISDFS_EU(fl) (((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU)
88
89/* locale per-channel tx power limits for MIMO frames
90 * maxpwr arrays are index by channel for 2.4 GHz limits, and
91 * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
92 */
93struct locale_mimo_info {
94 /* tx 20 MHz power limits, qdBm units */
95 s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
96 /* tx 40 MHz power limits, qdBm units */
97 s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
98 u8 flags;
99};
100
101extern const chanvec_t chanvec_all_2G;
102extern const chanvec_t chanvec_all_5G;
103
104/*
105 * Country names and abbreviations with locale defined from ISO 3166
106 */
107struct country_info {
108 const u8 locale_2G; /* 2.4G band locale */
109 const u8 locale_5G; /* 5G band locale */
110 const u8 locale_mimo_2G; /* 2.4G mimo info */
111 const u8 locale_mimo_5G; /* 5G mimo info */
112};
113
114extern struct brcms_cm_info *
115brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
116
117extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
118
119extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
120 uint bandunit);
121
122extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
123 chanspec_t chspec);
124
125extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
126 chanspec_t chanspec,
127 struct txpwr_limits *txpwr);
128extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
129 chanspec_t chanspec,
130 u8 local_constraint_qdbm);
131
132#endif /* _WLC_CHANNEL_H */
diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h
new file mode 100644
index 00000000000..e7ff0e6f28e
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/d11.h
@@ -0,0 +1,1775 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_D11_H_
18#define _BRCM_D11_H_
19
20#include <linux/ieee80211.h>
21
22#include <defs.h>
23#include "pub.h"
24#include "dma.h"
25
26#define BCN_TMPL_LEN 512 /* length of the BCN template area */
27
28/* RX FIFO numbers */
29#define RX_FIFO 0 /* data and ctl frames */
30#define RX_TXSTATUS_FIFO 3 /* RX fifo for tx status packages */
31
32/* TX FIFO numbers using WME Access Classes */
33#define TX_AC_BK_FIFO 0 /* Access Category Background TX FIFO */
34#define TX_AC_BE_FIFO 1 /* Access Category Best-Effort TX FIFO */
35#define TX_AC_VI_FIFO 2 /* Access Class Video TX FIFO */
36#define TX_AC_VO_FIFO 3 /* Access Class Voice TX FIFO */
37#define TX_BCMC_FIFO 4 /* Broadcast/Multicast TX FIFO */
38#define TX_ATIM_FIFO 5 /* TX fifo for ATIM window info */
39
40/* Addr is byte address used by SW; offset is word offset used by uCode */
41
42/* Per AC TX limit settings */
43#define M_AC_TXLMT_BASE_ADDR (0x180 * 2)
44#define M_AC_TXLMT_ADDR(_ac) (M_AC_TXLMT_BASE_ADDR + (2 * (_ac)))
45
46/* Legacy TX FIFO numbers */
47#define TX_DATA_FIFO TX_AC_BE_FIFO
48#define TX_CTL_FIFO TX_AC_VO_FIFO
49
50#ifndef WL_RSSI_ANT_MAX
51#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */
52#elif WL_RSSI_ANT_MAX != 4
53#error "WL_RSSI_ANT_MAX does not match"
54#endif
55
56struct intctrlregs {
57 u32 intstatus;
58 u32 intmask;
59};
60
61/* PIO structure,
62 * support two PIO format: 2 bytes access and 4 bytes access
63 * basic FIFO register set is per channel(transmit or receive)
64 * a pair of channels is defined for convenience
65 */
66/* 2byte-wide pio register set per channel(xmt or rcv) */
67struct pio2regs {
68 u16 fifocontrol;
69 u16 fifodata;
70 u16 fifofree; /* only valid in xmt channel, not in rcv channel */
71 u16 PAD;
72};
73
74/* a pair of pio channels(tx and rx) */
75struct pio2regp {
76 pio2regs_t tx;
77 pio2regs_t rx;
78};
79
80/* 4byte-wide pio register set per channel(xmt or rcv) */
81struct pio4regs {
82 u32 fifocontrol;
83 u32 fifodata;
84};
85
86/* a pair of pio channels(tx and rx) */
87struct pio4regp {
88 pio4regs_t tx;
89 pio4regs_t rx;
90};
91
92/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
93 * write: only low 16b-it half can be written
94 */
95union pmqreg {
96 u32 pmqhostdata; /* read only! */
97 struct {
98 u16 pmqctrlstatus; /* read/write */
99 u16 PAD;
100 } w;
101};
102
103struct fifo64 {
104 dma64regs_t dmaxmt; /* dma tx */
105 pio4regs_t piotx; /* pio tx */
106 dma64regs_t dmarcv; /* dma rx */
107 pio4regs_t piorx; /* pio rx */
108};
109
110/*
111 * Host Interface Registers
112 */
113struct d11regs {
114 /* Device Control ("semi-standard host registers") */
115 u32 PAD[3]; /* 0x0 - 0x8 */
116 u32 biststatus; /* 0xC */
117 u32 biststatus2; /* 0x10 */
118 u32 PAD; /* 0x14 */
119 u32 gptimer; /* 0x18 */
120 u32 usectimer; /* 0x1c *//* for corerev >= 26 */
121
122 /* Interrupt Control *//* 0x20 */
123 intctrlregs_t intctrlregs[8];
124
125 u32 PAD[40]; /* 0x60 - 0xFC */
126
127 u32 intrcvlazy[4]; /* 0x100 - 0x10C */
128
129 u32 PAD[4]; /* 0x110 - 0x11c */
130
131 u32 maccontrol; /* 0x120 */
132 u32 maccommand; /* 0x124 */
133 u32 macintstatus; /* 0x128 */
134 u32 macintmask; /* 0x12C */
135
136 /* Transmit Template Access */
137 u32 tplatewrptr; /* 0x130 */
138 u32 tplatewrdata; /* 0x134 */
139 u32 PAD[2]; /* 0x138 - 0x13C */
140
141 /* PMQ registers */
142 pmqreg_t pmqreg; /* 0x140 */
143 u32 pmqpatl; /* 0x144 */
144 u32 pmqpath; /* 0x148 */
145 u32 PAD; /* 0x14C */
146
147 u32 chnstatus; /* 0x150 */
148 u32 psmdebug; /* 0x154 */
149 u32 phydebug; /* 0x158 */
150 u32 machwcap; /* 0x15C */
151
152 /* Extended Internal Objects */
153 u32 objaddr; /* 0x160 */
154 u32 objdata; /* 0x164 */
155 u32 PAD[2]; /* 0x168 - 0x16c */
156
157 u32 frmtxstatus; /* 0x170 */
158 u32 frmtxstatus2; /* 0x174 */
159 u32 PAD[2]; /* 0x178 - 0x17c */
160
161 /* TSF host access */
162 u32 tsf_timerlow; /* 0x180 */
163 u32 tsf_timerhigh; /* 0x184 */
164 u32 tsf_cfprep; /* 0x188 */
165 u32 tsf_cfpstart; /* 0x18c */
166 u32 tsf_cfpmaxdur32; /* 0x190 */
167 u32 PAD[3]; /* 0x194 - 0x19c */
168
169 u32 maccontrol1; /* 0x1a0 */
170 u32 machwcap1; /* 0x1a4 */
171 u32 PAD[14]; /* 0x1a8 - 0x1dc */
172
173 /* Clock control and hardware workarounds*/
174 u32 clk_ctl_st; /* 0x1e0 */
175 u32 hw_war;
176 u32 d11_phypllctl; /* the phypll request/avail bits are
177 * moved to clk_ctl_st
178 */
179 u32 PAD[5]; /* 0x1ec - 0x1fc */
180
181 /* 0x200-0x37F dma/pio registers */
182 fifo64_t fifo64regs[6];
183
184 /* FIFO diagnostic port access */
185 dma32diag_t dmafifo; /* 0x380 - 0x38C */
186
187 u32 aggfifocnt; /* 0x390 */
188 u32 aggfifodata; /* 0x394 */
189 u32 PAD[16]; /* 0x398 - 0x3d4 */
190 u16 radioregaddr; /* 0x3d8 */
191 u16 radioregdata; /* 0x3da */
192
193 /*
194 * time delay between the change on rf disable input and
195 * radio shutdown
196 */
197 u32 rfdisabledly; /* 0x3DC */
198
199 /* PHY register access */
200 u16 phyversion; /* 0x3e0 - 0x0 */
201 u16 phybbconfig; /* 0x3e2 - 0x1 */
202 u16 phyadcbias; /* 0x3e4 - 0x2 Bphy only */
203 u16 phyanacore; /* 0x3e6 - 0x3 pwwrdwn on aphy */
204 u16 phyrxstatus0; /* 0x3e8 - 0x4 */
205 u16 phyrxstatus1; /* 0x3ea - 0x5 */
206 u16 phycrsth; /* 0x3ec - 0x6 */
207 u16 phytxerror; /* 0x3ee - 0x7 */
208 u16 phychannel; /* 0x3f0 - 0x8 */
209 u16 PAD[1]; /* 0x3f2 - 0x9 */
210 u16 phytest; /* 0x3f4 - 0xa */
211 u16 phy4waddr; /* 0x3f6 - 0xb */
212 u16 phy4wdatahi; /* 0x3f8 - 0xc */
213 u16 phy4wdatalo; /* 0x3fa - 0xd */
214 u16 phyregaddr; /* 0x3fc - 0xe */
215 u16 phyregdata; /* 0x3fe - 0xf */
216
217 /* IHR *//* 0x400 - 0x7FE */
218
219 /* RXE Block */
220 u16 PAD[3]; /* 0x400 - 0x406 */
221 u16 rcv_fifo_ctl; /* 0x406 */
222 u16 PAD; /* 0x408 - 0x40a */
223 u16 rcv_frm_cnt; /* 0x40a */
224 u16 PAD[4]; /* 0x40a - 0x414 */
225 u16 rssi; /* 0x414 */
226 u16 PAD[5]; /* 0x414 - 0x420 */
227 u16 rcm_ctl; /* 0x420 */
228 u16 rcm_mat_data; /* 0x422 */
229 u16 rcm_mat_mask; /* 0x424 */
230 u16 rcm_mat_dly; /* 0x426 */
231 u16 rcm_cond_mask_l; /* 0x428 */
232 u16 rcm_cond_mask_h; /* 0x42A */
233 u16 rcm_cond_dly; /* 0x42C */
234 u16 PAD[1]; /* 0x42E */
235 u16 ext_ihr_addr; /* 0x430 */
236 u16 ext_ihr_data; /* 0x432 */
237 u16 rxe_phyrs_2; /* 0x434 */
238 u16 rxe_phyrs_3; /* 0x436 */
239 u16 phy_mode; /* 0x438 */
240 u16 rcmta_ctl; /* 0x43a */
241 u16 rcmta_size; /* 0x43c */
242 u16 rcmta_addr0; /* 0x43e */
243 u16 rcmta_addr1; /* 0x440 */
244 u16 rcmta_addr2; /* 0x442 */
245 u16 PAD[30]; /* 0x444 - 0x480 */
246
247 /* PSM Block *//* 0x480 - 0x500 */
248
249 u16 PAD; /* 0x480 */
250 u16 psm_maccontrol_h; /* 0x482 */
251 u16 psm_macintstatus_l; /* 0x484 */
252 u16 psm_macintstatus_h; /* 0x486 */
253 u16 psm_macintmask_l; /* 0x488 */
254 u16 psm_macintmask_h; /* 0x48A */
255 u16 PAD; /* 0x48C */
256 u16 psm_maccommand; /* 0x48E */
257 u16 psm_brc; /* 0x490 */
258 u16 psm_phy_hdr_param; /* 0x492 */
259 u16 psm_postcard; /* 0x494 */
260 u16 psm_pcard_loc_l; /* 0x496 */
261 u16 psm_pcard_loc_h; /* 0x498 */
262 u16 psm_gpio_in; /* 0x49A */
263 u16 psm_gpio_out; /* 0x49C */
264 u16 psm_gpio_oe; /* 0x49E */
265
266 u16 psm_bred_0; /* 0x4A0 */
267 u16 psm_bred_1; /* 0x4A2 */
268 u16 psm_bred_2; /* 0x4A4 */
269 u16 psm_bred_3; /* 0x4A6 */
270 u16 psm_brcl_0; /* 0x4A8 */
271 u16 psm_brcl_1; /* 0x4AA */
272 u16 psm_brcl_2; /* 0x4AC */
273 u16 psm_brcl_3; /* 0x4AE */
274 u16 psm_brpo_0; /* 0x4B0 */
275 u16 psm_brpo_1; /* 0x4B2 */
276 u16 psm_brpo_2; /* 0x4B4 */
277 u16 psm_brpo_3; /* 0x4B6 */
278 u16 psm_brwk_0; /* 0x4B8 */
279 u16 psm_brwk_1; /* 0x4BA */
280 u16 psm_brwk_2; /* 0x4BC */
281 u16 psm_brwk_3; /* 0x4BE */
282
283 u16 psm_base_0; /* 0x4C0 */
284 u16 psm_base_1; /* 0x4C2 */
285 u16 psm_base_2; /* 0x4C4 */
286 u16 psm_base_3; /* 0x4C6 */
287 u16 psm_base_4; /* 0x4C8 */
288 u16 psm_base_5; /* 0x4CA */
289 u16 psm_base_6; /* 0x4CC */
290 u16 psm_pc_reg_0; /* 0x4CE */
291 u16 psm_pc_reg_1; /* 0x4D0 */
292 u16 psm_pc_reg_2; /* 0x4D2 */
293 u16 psm_pc_reg_3; /* 0x4D4 */
294 u16 PAD[0xD]; /* 0x4D6 - 0x4DE */
295 u16 psm_corectlsts; /* 0x4f0 *//* Corerev >= 13 */
296 u16 PAD[0x7]; /* 0x4f2 - 0x4fE */
297
298 /* TXE0 Block *//* 0x500 - 0x580 */
299 u16 txe_ctl; /* 0x500 */
300 u16 txe_aux; /* 0x502 */
301 u16 txe_ts_loc; /* 0x504 */
302 u16 txe_time_out; /* 0x506 */
303 u16 txe_wm_0; /* 0x508 */
304 u16 txe_wm_1; /* 0x50A */
305 u16 txe_phyctl; /* 0x50C */
306 u16 txe_status; /* 0x50E */
307 u16 txe_mmplcp0; /* 0x510 */
308 u16 txe_mmplcp1; /* 0x512 */
309 u16 txe_phyctl1; /* 0x514 */
310
311 u16 PAD[0x05]; /* 0x510 - 0x51E */
312
313 /* Transmit control */
314 u16 xmtfifodef; /* 0x520 */
315 u16 xmtfifo_frame_cnt; /* 0x522 *//* Corerev >= 16 */
316 u16 xmtfifo_byte_cnt; /* 0x524 *//* Corerev >= 16 */
317 u16 xmtfifo_head; /* 0x526 *//* Corerev >= 16 */
318 u16 xmtfifo_rd_ptr; /* 0x528 *//* Corerev >= 16 */
319 u16 xmtfifo_wr_ptr; /* 0x52A *//* Corerev >= 16 */
320 u16 xmtfifodef1; /* 0x52C *//* Corerev >= 16 */
321
322 u16 PAD[0x09]; /* 0x52E - 0x53E */
323
324 u16 xmtfifocmd; /* 0x540 */
325 u16 xmtfifoflush; /* 0x542 */
326 u16 xmtfifothresh; /* 0x544 */
327 u16 xmtfifordy; /* 0x546 */
328 u16 xmtfifoprirdy; /* 0x548 */
329 u16 xmtfiforqpri; /* 0x54A */
330 u16 xmttplatetxptr; /* 0x54C */
331 u16 PAD; /* 0x54E */
332 u16 xmttplateptr; /* 0x550 */
333 u16 smpl_clct_strptr; /* 0x552 *//* Corerev >= 22 */
334 u16 smpl_clct_stpptr; /* 0x554 *//* Corerev >= 22 */
335 u16 smpl_clct_curptr; /* 0x556 *//* Corerev >= 22 */
336 u16 PAD[0x04]; /* 0x558 - 0x55E */
337 u16 xmttplatedatalo; /* 0x560 */
338 u16 xmttplatedatahi; /* 0x562 */
339
340 u16 PAD[2]; /* 0x564 - 0x566 */
341
342 u16 xmtsel; /* 0x568 */
343 u16 xmttxcnt; /* 0x56A */
344 u16 xmttxshmaddr; /* 0x56C */
345
346 u16 PAD[0x09]; /* 0x56E - 0x57E */
347
348 /* TXE1 Block */
349 u16 PAD[0x40]; /* 0x580 - 0x5FE */
350
351 /* TSF Block */
352 u16 PAD[0X02]; /* 0x600 - 0x602 */
353 u16 tsf_cfpstrt_l; /* 0x604 */
354 u16 tsf_cfpstrt_h; /* 0x606 */
355 u16 PAD[0X05]; /* 0x608 - 0x610 */
356 u16 tsf_cfppretbtt; /* 0x612 */
357 u16 PAD[0XD]; /* 0x614 - 0x62C */
358 u16 tsf_clk_frac_l; /* 0x62E */
359 u16 tsf_clk_frac_h; /* 0x630 */
360 u16 PAD[0X14]; /* 0x632 - 0x658 */
361 u16 tsf_random; /* 0x65A */
362 u16 PAD[0x05]; /* 0x65C - 0x664 */
363 /* GPTimer 2 registers */
364 u16 tsf_gpt2_stat; /* 0x666 */
365 u16 tsf_gpt2_ctr_l; /* 0x668 */
366 u16 tsf_gpt2_ctr_h; /* 0x66A */
367 u16 tsf_gpt2_val_l; /* 0x66C */
368 u16 tsf_gpt2_val_h; /* 0x66E */
369 u16 tsf_gptall_stat; /* 0x670 */
370 u16 PAD[0x07]; /* 0x672 - 0x67E */
371
372 /* IFS Block */
373 u16 ifs_sifs_rx_tx_tx; /* 0x680 */
374 u16 ifs_sifs_nav_tx; /* 0x682 */
375 u16 ifs_slot; /* 0x684 */
376 u16 PAD; /* 0x686 */
377 u16 ifs_ctl; /* 0x688 */
378 u16 PAD[0x3]; /* 0x68a - 0x68F */
379 u16 ifsstat; /* 0x690 */
380 u16 ifsmedbusyctl; /* 0x692 */
381 u16 iftxdur; /* 0x694 */
382 u16 PAD[0x3]; /* 0x696 - 0x69b */
383 /* EDCF support in dot11macs */
384 u16 ifs_aifsn; /* 0x69c */
385 u16 ifs_ctl1; /* 0x69e */
386
387 /* slow clock registers */
388 u16 scc_ctl; /* 0x6a0 */
389 u16 scc_timer_l; /* 0x6a2 */
390 u16 scc_timer_h; /* 0x6a4 */
391 u16 scc_frac; /* 0x6a6 */
392 u16 scc_fastpwrup_dly; /* 0x6a8 */
393 u16 scc_per; /* 0x6aa */
394 u16 scc_per_frac; /* 0x6ac */
395 u16 scc_cal_timer_l; /* 0x6ae */
396 u16 scc_cal_timer_h; /* 0x6b0 */
397 u16 PAD; /* 0x6b2 */
398
399 u16 PAD[0x26];
400
401 /* NAV Block */
402 u16 nav_ctl; /* 0x700 */
403 u16 navstat; /* 0x702 */
404 u16 PAD[0x3e]; /* 0x702 - 0x77E */
405
406 /* WEP/PMQ Block *//* 0x780 - 0x7FE */
407 u16 PAD[0x20]; /* 0x780 - 0x7BE */
408
409 u16 wepctl; /* 0x7C0 */
410 u16 wepivloc; /* 0x7C2 */
411 u16 wepivkey; /* 0x7C4 */
412 u16 wepwkey; /* 0x7C6 */
413
414 u16 PAD[4]; /* 0x7C8 - 0x7CE */
415 u16 pcmctl; /* 0X7D0 */
416 u16 pcmstat; /* 0X7D2 */
417 u16 PAD[6]; /* 0x7D4 - 0x7DE */
418
419 u16 pmqctl; /* 0x7E0 */
420 u16 pmqstatus; /* 0x7E2 */
421 u16 pmqpat0; /* 0x7E4 */
422 u16 pmqpat1; /* 0x7E6 */
423 u16 pmqpat2; /* 0x7E8 */
424
425 u16 pmqdat; /* 0x7EA */
426 u16 pmqdator; /* 0x7EC */
427 u16 pmqhst; /* 0x7EE */
428 u16 pmqpath0; /* 0x7F0 */
429 u16 pmqpath1; /* 0x7F2 */
430 u16 pmqpath2; /* 0x7F4 */
431 u16 pmqdath; /* 0x7F6 */
432
433 u16 PAD[0x04]; /* 0x7F8 - 0x7FE */
434
435 /* SHM *//* 0x800 - 0xEFE */
436 u16 PAD[0x380]; /* 0x800 - 0xEFE */
437};
438
439#define PIHR_BASE 0x0400 /* byte address of packed IHR region */
440
441/* biststatus */
442#define BT_DONE (1U << 31) /* bist done */
443#define BT_B2S (1 << 30) /* bist2 ram summary bit */
444
445/* intstatus and intmask */
446#define I_PC (1 << 10) /* pci descriptor error */
447#define I_PD (1 << 11) /* pci data error */
448#define I_DE (1 << 12) /* descriptor protocol error */
449#define I_RU (1 << 13) /* receive descriptor underflow */
450#define I_RO (1 << 14) /* receive fifo overflow */
451#define I_XU (1 << 15) /* transmit fifo underflow */
452#define I_RI (1 << 16) /* receive interrupt */
453#define I_XI (1 << 24) /* transmit interrupt */
454
455/* interrupt receive lazy */
456#define IRL_TO_MASK 0x00ffffff /* timeout */
457#define IRL_FC_MASK 0xff000000 /* frame count */
458#define IRL_FC_SHIFT 24 /* frame count */
459
460/* maccontrol register */
461#define MCTL_GMODE (1U << 31)
462#define MCTL_DISCARD_PMQ (1 << 30)
463#define MCTL_WAKE (1 << 26)
464#define MCTL_HPS (1 << 25)
465#define MCTL_PROMISC (1 << 24)
466#define MCTL_KEEPBADFCS (1 << 23)
467#define MCTL_KEEPCONTROL (1 << 22)
468#define MCTL_PHYLOCK (1 << 21)
469#define MCTL_BCNS_PROMISC (1 << 20)
470#define MCTL_LOCK_RADIO (1 << 19)
471#define MCTL_AP (1 << 18)
472#define MCTL_INFRA (1 << 17)
473#define MCTL_BIGEND (1 << 16)
474#define MCTL_GPOUT_SEL_MASK (3 << 14)
475#define MCTL_GPOUT_SEL_SHIFT 14
476#define MCTL_EN_PSMDBG (1 << 13)
477#define MCTL_IHR_EN (1 << 10)
478#define MCTL_SHM_UPPER (1 << 9)
479#define MCTL_SHM_EN (1 << 8)
480#define MCTL_PSM_JMP_0 (1 << 2)
481#define MCTL_PSM_RUN (1 << 1)
482#define MCTL_EN_MAC (1 << 0)
483
484/* maccommand register */
485#define MCMD_BCN0VLD (1 << 0)
486#define MCMD_BCN1VLD (1 << 1)
487#define MCMD_DIRFRMQVAL (1 << 2)
488#define MCMD_CCA (1 << 3)
489#define MCMD_BG_NOISE (1 << 4)
490#define MCMD_SKIP_SHMINIT (1 << 5) /* only used for simulation */
491#define MCMD_SAMPLECOLL MCMD_SKIP_SHMINIT /* reuse for sample collect */
492
493/* macintstatus/macintmask */
494#define MI_MACSSPNDD (1 << 0) /* MAC has gracefully suspended */
495#define MI_BCNTPL (1 << 1) /* beacon template available */
496#define MI_TBTT (1 << 2) /* TBTT indication */
497#define MI_BCNSUCCESS (1 << 3) /* beacon successfully tx'd */
498#define MI_BCNCANCLD (1 << 4) /* beacon canceled (IBSS) */
499#define MI_ATIMWINEND (1 << 5) /* end of ATIM-window (IBSS) */
500#define MI_PMQ (1 << 6) /* PMQ entries available */
501#define MI_NSPECGEN_0 (1 << 7) /* non-specific gen-stat bits that are set by PSM */
502#define MI_NSPECGEN_1 (1 << 8) /* non-specific gen-stat bits that are set by PSM */
503#define MI_MACTXERR (1 << 9) /* MAC level Tx error */
504#define MI_NSPECGEN_3 (1 << 10) /* non-specific gen-stat bits that are set by PSM */
505#define MI_PHYTXERR (1 << 11) /* PHY Tx error */
506#define MI_PME (1 << 12) /* Power Management Event */
507#define MI_GP0 (1 << 13) /* General-purpose timer0 */
508#define MI_GP1 (1 << 14) /* General-purpose timer1 */
509#define MI_DMAINT (1 << 15) /* (ORed) DMA-interrupts */
510#define MI_TXSTOP (1 << 16) /* MAC has completed a TX FIFO Suspend/Flush */
511#define MI_CCA (1 << 17) /* MAC has completed a CCA measurement */
512#define MI_BG_NOISE (1 << 18) /* MAC has collected background noise samples */
513#define MI_DTIM_TBTT (1 << 19) /* MBSS DTIM TBTT indication */
514#define MI_PRQ (1 << 20) /* Probe response queue needs attention */
515#define MI_PWRUP (1 << 21) /* Radio/PHY has been powered back up. */
516#define MI_RESERVED3 (1 << 22)
517#define MI_RESERVED2 (1 << 23)
518#define MI_RESERVED1 (1 << 25)
519/* MAC detected change on RF Disable input*/
520#define MI_RFDISABLE (1 << 28)
521#define MI_TFS (1 << 29) /* MAC has completed a TX */
522#define MI_PHYCHANGED (1 << 30) /* A phy status change wrt G mode */
523#define MI_TO (1U << 31) /* general purpose timeout */
524
525/* Mac capabilities registers */
526/* machwcap */
527#define MCAP_TKIPMIC 0x80000000 /* TKIP MIC hardware present */
528
529/* pmqhost data */
530#define PMQH_DATA_MASK 0xffff0000 /* data entry of head pmq entry */
531#define PMQH_BSSCFG 0x00100000 /* PM entry for BSS config */
532#define PMQH_PMOFF 0x00010000 /* PM Mode OFF: power save off */
533#define PMQH_PMON 0x00020000 /* PM Mode ON: power save on */
534#define PMQH_DASAT 0x00040000 /* Dis-associated or De-authenticated */
535#define PMQH_ATIMFAIL 0x00080000 /* ATIM not acknowledged */
536#define PMQH_DEL_ENTRY 0x00000001 /* delete head entry */
537#define PMQH_DEL_MULT 0x00000002 /* delete head entry to cur read pointer -1 */
538#define PMQH_OFLO 0x00000004 /* pmq overflow indication */
539#define PMQH_NOT_EMPTY 0x00000008 /* entries are present in pmq */
540
541/* phydebug */
542#define PDBG_CRS (1 << 0) /* phy is asserting carrier sense */
543#define PDBG_TXA (1 << 1) /* phy is taking xmit byte from mac this cycle */
544#define PDBG_TXF (1 << 2) /* mac is instructing the phy to transmit a frame */
545#define PDBG_TXE (1 << 3) /* phy is signalling a transmit Error to the mac */
546#define PDBG_RXF (1 << 4) /* phy detected the end of a valid frame preamble */
547#define PDBG_RXS (1 << 5) /* phy detected the end of a valid PLCP header */
548#define PDBG_RXFRG (1 << 6) /* rx start not asserted */
549#define PDBG_RXV (1 << 7) /* mac is taking receive byte from phy this cycle */
550#define PDBG_RFD (1 << 16) /* RF portion of the radio is disabled */
551
552/* objaddr register */
553#define OBJADDR_SEL_MASK 0x000F0000
554#define OBJADDR_UCM_SEL 0x00000000
555#define OBJADDR_SHM_SEL 0x00010000
556#define OBJADDR_SCR_SEL 0x00020000
557#define OBJADDR_IHR_SEL 0x00030000
558#define OBJADDR_RCMTA_SEL 0x00040000
559#define OBJADDR_SRCHM_SEL 0x00060000
560#define OBJADDR_WINC 0x01000000
561#define OBJADDR_RINC 0x02000000
562#define OBJADDR_AUTO_INC 0x03000000
563
564#define WEP_PCMADDR 0x07d4
565#define WEP_PCMDATA 0x07d6
566
567/* frmtxstatus */
568#define TXS_V (1 << 0) /* valid bit */
569#define TXS_STATUS_MASK 0xffff
570#define TXS_FID_MASK 0xffff0000
571#define TXS_FID_SHIFT 16
572
573/* frmtxstatus2 */
574#define TXS_SEQ_MASK 0xffff
575#define TXS_PTX_MASK 0xff0000
576#define TXS_PTX_SHIFT 16
577#define TXS_MU_MASK 0x01000000
578#define TXS_MU_SHIFT 24
579
580/* clk_ctl_st */
581#define CCS_ERSRC_REQ_D11PLL 0x00000100 /* d11 core pll request */
582#define CCS_ERSRC_REQ_PHYPLL 0x00000200 /* PHY pll request */
583#define CCS_ERSRC_AVAIL_D11PLL 0x01000000 /* d11 core pll available */
584#define CCS_ERSRC_AVAIL_PHYPLL 0x02000000 /* PHY pll available */
585
586/* HT Cloclk Ctrl and Clock Avail for 4313 */
587#define CCS_ERSRC_REQ_HT 0x00000010 /* HT avail request */
588#define CCS_ERSRC_AVAIL_HT 0x00020000 /* HT clock available */
589
590/* tsf_cfprep register */
591#define CFPREP_CBI_MASK 0xffffffc0
592#define CFPREP_CBI_SHIFT 6
593#define CFPREP_CFPP 0x00000001
594
595/* tx fifo sizes values are in terms of 256 byte blocks */
596#define TXFIFOCMD_RESET_MASK (1 << 15) /* reset */
597#define TXFIFOCMD_FIFOSEL_SHIFT 8 /* fifo */
598#define TXFIFO_FIFOTOP_SHIFT 8 /* fifo start */
599
600#define TXFIFO_START_BLK16 65 /* Base address + 32 * 512 B/P */
601#define TXFIFO_START_BLK 6 /* Base address + 6 * 256 B */
602#define TXFIFO_SIZE_UNIT 256 /* one unit corresponds to 256 bytes */
603#define MBSS16_TEMPLMEM_MINBLKS 65 /* one unit corresponds to 256 bytes */
604
605/* phy versions, PhyVersion:Revision field */
606#define PV_AV_MASK 0xf000 /* analog block version */
607#define PV_AV_SHIFT 12 /* analog block version bitfield offset */
608#define PV_PT_MASK 0x0f00 /* phy type */
609#define PV_PT_SHIFT 8 /* phy type bitfield offset */
610#define PV_PV_MASK 0x000f /* phy version */
611#define PHY_TYPE(v) ((v & PV_PT_MASK) >> PV_PT_SHIFT)
612
613/* phy types, PhyVersion:PhyType field */
614#define PHY_TYPE_N 4 /* N-Phy value */
615#define PHY_TYPE_SSN 6 /* SSLPN-Phy value */
616#define PHY_TYPE_LCN 8 /* LCN-Phy value */
617#define PHY_TYPE_LCNXN 9 /* LCNXN-Phy value */
618#define PHY_TYPE_NULL 0xf /* Invalid Phy value */
619
620/* analog types, PhyVersion:AnalogType field */
621#define ANA_11N_013 5
622
623/* 802.11a PLCP header def */
624struct ofdm_phy_hdr {
625 u8 rlpt[3]; /* rate, length, parity, tail */
626 u16 service;
627 u8 pad;
628} __packed;
629
630#define D11A_PHY_HDR_GRATE(phdr) ((phdr)->rlpt[0] & 0x0f)
631#define D11A_PHY_HDR_GRES(phdr) (((phdr)->rlpt[0] >> 4) & 0x01)
632#define D11A_PHY_HDR_GLENGTH(phdr) (((u32 *)((phdr)->rlpt) >> 5) & 0x0fff)
633#define D11A_PHY_HDR_GPARITY(phdr) (((phdr)->rlpt[3] >> 1) & 0x01)
634#define D11A_PHY_HDR_GTAIL(phdr) (((phdr)->rlpt[3] >> 2) & 0x3f)
635
636/* rate encoded per 802.11a-1999 sec 17.3.4.1 */
637#define D11A_PHY_HDR_SRATE(phdr, rate) \
638 ((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf))
639/* set reserved field to zero */
640#define D11A_PHY_HDR_SRES(phdr) ((phdr)->rlpt[0] &= 0xef)
641/* length is number of octets in PSDU */
642#define D11A_PHY_HDR_SLENGTH(phdr, length) \
643 (*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \
644 (((length) & 0x0fff) << 5))
645/* set the tail to all zeros */
646#define D11A_PHY_HDR_STAIL(phdr) ((phdr)->rlpt[3] &= 0x03)
647
648#define D11A_PHY_HDR_LEN_L 3 /* low-rate part of PLCP header */
649#define D11A_PHY_HDR_LEN_R 2 /* high-rate part of PLCP header */
650
651#define D11A_PHY_TX_DELAY (2) /* 2.1 usec */
652
653#define D11A_PHY_HDR_TIME (4) /* low-rate part of PLCP header */
654#define D11A_PHY_PRE_TIME (16)
655#define D11A_PHY_PREHDR_TIME (D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
656
657/* 802.11b PLCP header def */
658struct cck_phy_hdr {
659 u8 signal;
660 u8 service;
661 u16 length;
662 u16 crc;
663} __packed;
664
665#define D11B_PHY_HDR_LEN 6
666
667#define D11B_PHY_TX_DELAY (3) /* 3.4 usec */
668
669#define D11B_PHY_LHDR_TIME (D11B_PHY_HDR_LEN << 3)
670#define D11B_PHY_LPRE_TIME (144)
671#define D11B_PHY_LPREHDR_TIME (D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME)
672
673#define D11B_PHY_SHDR_TIME (D11B_PHY_LHDR_TIME >> 1)
674#define D11B_PHY_SPRE_TIME (D11B_PHY_LPRE_TIME >> 1)
675#define D11B_PHY_SPREHDR_TIME (D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME)
676
677#define D11B_PLCP_SIGNAL_LOCKED (1 << 2)
678#define D11B_PLCP_SIGNAL_LE (1 << 7)
679
680#define MIMO_PLCP_MCS_MASK 0x7f /* mcs index */
681#define MIMO_PLCP_40MHZ 0x80 /* 40 Hz frame */
682#define MIMO_PLCP_AMPDU 0x08 /* ampdu */
683
684#define BRCMS_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
685#define BRCMS_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
686#define BRCMS_SET_MIMO_PLCP_LEN(plcp, len) \
687 do { \
688 plcp[1] = len & 0xff; \
689 plcp[2] = ((len >> 8) & 0xff); \
690 } while (0);
691
692#define BRCMS_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
693#define BRCMS_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
694#define BRCMS_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
695
696/* The dot11a PLCP header is 5 bytes. To simplify the software (so that we
697 * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header has
698 * padding added in the ucode.
699 */
700#define D11_PHY_HDR_LEN 6
701
702/* TX DMA buffer header */
703struct d11txh {
704 u16 MacTxControlLow; /* 0x0 */
705 u16 MacTxControlHigh; /* 0x1 */
706 u16 MacFrameControl; /* 0x2 */
707 u16 TxFesTimeNormal; /* 0x3 */
708 u16 PhyTxControlWord; /* 0x4 */
709 u16 PhyTxControlWord_1; /* 0x5 */
710 u16 PhyTxControlWord_1_Fbr; /* 0x6 */
711 u16 PhyTxControlWord_1_Rts; /* 0x7 */
712 u16 PhyTxControlWord_1_FbrRts; /* 0x8 */
713 u16 MainRates; /* 0x9 */
714 u16 XtraFrameTypes; /* 0xa */
715 u8 IV[16]; /* 0x0b - 0x12 */
716 u8 TxFrameRA[6]; /* 0x13 - 0x15 */
717 u16 TxFesTimeFallback; /* 0x16 */
718 u8 RTSPLCPFallback[6]; /* 0x17 - 0x19 */
719 u16 RTSDurFallback; /* 0x1a */
720 u8 FragPLCPFallback[6]; /* 0x1b - 1d */
721 u16 FragDurFallback; /* 0x1e */
722 u16 MModeLen; /* 0x1f */
723 u16 MModeFbrLen; /* 0x20 */
724 u16 TstampLow; /* 0x21 */
725 u16 TstampHigh; /* 0x22 */
726 u16 ABI_MimoAntSel; /* 0x23 */
727 u16 PreloadSize; /* 0x24 */
728 u16 AmpduSeqCtl; /* 0x25 */
729 u16 TxFrameID; /* 0x26 */
730 u16 TxStatus; /* 0x27 */
731 u16 MaxNMpdus; /* 0x28 */
732 u16 MaxABytes_MRT; /* 0x29 */
733 u16 MaxABytes_FBR; /* 0x2a */
734 u16 MinMBytes; /* 0x2b */
735 u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */
736 struct ieee80211_rts rts_frame; /* 0x2f - 0x36 */
737 u16 PAD; /* 0x37 */
738} __packed;
739
740#define D11_TXH_LEN 112 /* bytes */
741
742/* Frame Types */
743#define FT_CCK 0
744#define FT_OFDM 1
745#define FT_HT 2
746#define FT_N 3
747
748/* Position of MPDU inside A-MPDU; indicated with bits 10:9 of MacTxControlLow */
749#define TXC_AMPDU_SHIFT 9 /* shift for ampdu settings */
750#define TXC_AMPDU_NONE 0 /* Regular MPDU, not an A-MPDU */
751#define TXC_AMPDU_FIRST 1 /* first MPDU of an A-MPDU */
752#define TXC_AMPDU_MIDDLE 2 /* intermediate MPDU of an A-MPDU */
753#define TXC_AMPDU_LAST 3 /* last (or single) MPDU of an A-MPDU */
754
755/* MacTxControlLow */
756#define TXC_AMIC 0x8000
757#define TXC_SENDCTS 0x0800
758#define TXC_AMPDU_MASK 0x0600
759#define TXC_BW_40 0x0100
760#define TXC_FREQBAND_5G 0x0080
761#define TXC_DFCS 0x0040
762#define TXC_IGNOREPMQ 0x0020
763#define TXC_HWSEQ 0x0010
764#define TXC_STARTMSDU 0x0008
765#define TXC_SENDRTS 0x0004
766#define TXC_LONGFRAME 0x0002
767#define TXC_IMMEDACK 0x0001
768
769/* MacTxControlHigh */
770#define TXC_PREAMBLE_RTS_FB_SHORT 0x8000 /* RTS fallback preamble type 1 = SHORT 0 = LONG */
771#define TXC_PREAMBLE_RTS_MAIN_SHORT 0x4000 /* RTS main rate preamble type 1 = SHORT 0 = LONG */
772#define TXC_PREAMBLE_DATA_FB_SHORT 0x2000 /* Main fallback rate preamble type
773 * 1 = SHORT for OFDM/GF for MIMO
774 * 0 = LONG for CCK/MM for MIMO
775 */
776/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */
777#define TXC_AMPDU_FBR 0x1000 /* use fallback rate for this AMPDU */
778#define TXC_SECKEY_MASK 0x0FF0
779#define TXC_SECKEY_SHIFT 4
780#define TXC_ALT_TXPWR 0x0008 /* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
781#define TXC_SECTYPE_MASK 0x0007
782#define TXC_SECTYPE_SHIFT 0
783
784/* Null delimiter for Fallback rate */
785#define AMPDU_FBR_NULL_DELIM 5 /* Location of Null delimiter count for AMPDU */
786
787/* PhyTxControl for Mimophy */
788#define PHY_TXC_PWR_MASK 0xFC00
789#define PHY_TXC_PWR_SHIFT 10
790#define PHY_TXC_ANT_MASK 0x03C0 /* bit 6, 7, 8, 9 */
791#define PHY_TXC_ANT_SHIFT 6
792#define PHY_TXC_ANT_0_1 0x00C0 /* auto, last rx */
793#define PHY_TXC_LCNPHY_ANT_LAST 0x0000
794#define PHY_TXC_ANT_3 0x0200 /* virtual antenna 3 */
795#define PHY_TXC_ANT_2 0x0100 /* virtual antenna 2 */
796#define PHY_TXC_ANT_1 0x0080 /* virtual antenna 1 */
797#define PHY_TXC_ANT_0 0x0040 /* virtual antenna 0 */
798#define PHY_TXC_SHORT_HDR 0x0010
799
800#define PHY_TXC_OLD_ANT_0 0x0000
801#define PHY_TXC_OLD_ANT_1 0x0100
802#define PHY_TXC_OLD_ANT_LAST 0x0300
803
804/* PhyTxControl_1 for Mimophy */
805#define PHY_TXC1_BW_MASK 0x0007
806#define PHY_TXC1_BW_10MHZ 0
807#define PHY_TXC1_BW_10MHZ_UP 1
808#define PHY_TXC1_BW_20MHZ 2
809#define PHY_TXC1_BW_20MHZ_UP 3
810#define PHY_TXC1_BW_40MHZ 4
811#define PHY_TXC1_BW_40MHZ_DUP 5
812#define PHY_TXC1_MODE_SHIFT 3
813#define PHY_TXC1_MODE_MASK 0x0038
814#define PHY_TXC1_MODE_SISO 0
815#define PHY_TXC1_MODE_CDD 1
816#define PHY_TXC1_MODE_STBC 2
817#define PHY_TXC1_MODE_SDM 3
818
819/* PhyTxControl for HTphy that are different from Mimophy */
820#define PHY_TXC_HTANT_MASK 0x3fC0 /* bit 6, 7, 8, 9, 10, 11, 12, 13 */
821
822/* XtraFrameTypes */
823#define XFTS_RTS_FT_SHIFT 2
824#define XFTS_FBRRTS_FT_SHIFT 4
825#define XFTS_CHANNEL_SHIFT 8
826
827/* Antenna diversity bit in ant_wr_settle */
828#define PHY_AWS_ANTDIV 0x2000
829
830/* IFS ctl */
831#define IFS_USEEDCF (1 << 2)
832
833/* IFS ctl1 */
834#define IFS_CTL1_EDCRS (1 << 3)
835#define IFS_CTL1_EDCRS_20L (1 << 4)
836#define IFS_CTL1_EDCRS_40 (1 << 5)
837
838/* ABI_MimoAntSel */
839#define ABI_MAS_ADDR_BMP_IDX_MASK 0x0f00
840#define ABI_MAS_ADDR_BMP_IDX_SHIFT 8
841#define ABI_MAS_FBR_ANT_PTN_MASK 0x00f0
842#define ABI_MAS_FBR_ANT_PTN_SHIFT 4
843#define ABI_MAS_MRT_ANT_PTN_MASK 0x000f
844
845/* tx status packet */
846struct tx_status {
847 u16 framelen;
848 u16 PAD;
849 u16 frameid;
850 u16 status;
851 u16 lasttxtime;
852 u16 sequence;
853 u16 phyerr;
854 u16 ackphyrxsh;
855} __packed;
856
857#define TXSTATUS_LEN 16
858
859/* status field bit definitions */
860#define TX_STATUS_FRM_RTX_MASK 0xF000
861#define TX_STATUS_FRM_RTX_SHIFT 12
862#define TX_STATUS_RTS_RTX_MASK 0x0F00
863#define TX_STATUS_RTS_RTX_SHIFT 8
864#define TX_STATUS_MASK 0x00FE
865#define TX_STATUS_PMINDCTD (1 << 7) /* PM mode indicated to AP */
866#define TX_STATUS_INTERMEDIATE (1 << 6) /* intermediate or 1st ampdu pkg */
867#define TX_STATUS_AMPDU (1 << 5) /* AMPDU status */
868#define TX_STATUS_SUPR_MASK 0x1C /* suppress status bits (4:2) */
869#define TX_STATUS_SUPR_SHIFT 2
870#define TX_STATUS_ACK_RCV (1 << 1) /* ACK received */
871#define TX_STATUS_VALID (1 << 0) /* Tx status valid */
872#define TX_STATUS_NO_ACK 0
873
874/* suppress status reason codes */
875#define TX_STATUS_SUPR_PMQ (1 << 2) /* PMQ entry */
876#define TX_STATUS_SUPR_FLUSH (2 << 2) /* flush request */
877#define TX_STATUS_SUPR_FRAG (3 << 2) /* previous frag failure */
878#define TX_STATUS_SUPR_TBTT (3 << 2) /* SHARED: Probe response supr for TBTT */
879#define TX_STATUS_SUPR_BADCH (4 << 2) /* channel mismatch */
880#define TX_STATUS_SUPR_EXPTIME (5 << 2) /* lifetime expiry */
881#define TX_STATUS_SUPR_UF (6 << 2) /* underflow */
882
883/* Unexpected tx status for rate update */
884#define TX_STATUS_UNEXP(status) \
885 ((((status) & TX_STATUS_INTERMEDIATE) != 0) && \
886 TX_STATUS_UNEXP_AMPDU(status))
887
888/* Unexpected tx status for A-MPDU rate update */
889#define TX_STATUS_UNEXP_AMPDU(status) \
890 ((((status) & TX_STATUS_SUPR_MASK) != 0) && \
891 (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME))
892
893#define TX_STATUS_BA_BMAP03_MASK 0xF000 /* ba bitmap 0:3 in 1st pkg */
894#define TX_STATUS_BA_BMAP03_SHIFT 12 /* ba bitmap 0:3 in 1st pkg */
895#define TX_STATUS_BA_BMAP47_MASK 0x001E /* ba bitmap 4:7 in 2nd pkg */
896#define TX_STATUS_BA_BMAP47_SHIFT 3 /* ba bitmap 4:7 in 2nd pkg */
897
898/* RXE (Receive Engine) */
899
900/* RCM_CTL */
901#define RCM_INC_MASK_H 0x0080
902#define RCM_INC_MASK_L 0x0040
903#define RCM_INC_DATA 0x0020
904#define RCM_INDEX_MASK 0x001F
905#define RCM_SIZE 15
906
907#define RCM_MAC_OFFSET 0 /* current MAC address */
908#define RCM_BSSID_OFFSET 3 /* current BSSID address */
909#define RCM_F_BSSID_0_OFFSET 6 /* foreign BSS CFP tracking */
910#define RCM_F_BSSID_1_OFFSET 9 /* foreign BSS CFP tracking */
911#define RCM_F_BSSID_2_OFFSET 12 /* foreign BSS CFP tracking */
912
913#define RCM_WEP_TA0_OFFSET 16
914#define RCM_WEP_TA1_OFFSET 19
915#define RCM_WEP_TA2_OFFSET 22
916#define RCM_WEP_TA3_OFFSET 25
917
918/* PSM Block */
919
920/* psm_phy_hdr_param bits */
921#define MAC_PHY_RESET 1
922#define MAC_PHY_CLOCK_EN 2
923#define MAC_PHY_FORCE_CLK 4
924
925/* WEP Block */
926
927/* WEP_WKEY */
928#define WKEY_START (1 << 8)
929#define WKEY_SEL_MASK 0x1F
930
931/* WEP data formats */
932
933/* the number of RCMTA entries */
934#define RCMTA_SIZE 50
935
936#define M_ADDR_BMP_BLK (0x37e * 2)
937#define M_ADDR_BMP_BLK_SZ 12
938
939#define ADDR_BMP_RA (1 << 0) /* Receiver Address (RA) */
940#define ADDR_BMP_TA (1 << 1) /* Transmitter Address (TA) */
941#define ADDR_BMP_BSSID (1 << 2) /* BSSID */
942#define ADDR_BMP_AP (1 << 3) /* Infra-BSS Access Point (AP) */
943#define ADDR_BMP_STA (1 << 4) /* Infra-BSS Station (STA) */
944#define ADDR_BMP_RESERVED1 (1 << 5)
945#define ADDR_BMP_RESERVED2 (1 << 6)
946#define ADDR_BMP_RESERVED3 (1 << 7)
947#define ADDR_BMP_BSS_IDX_MASK (3 << 8) /* BSS control block index */
948#define ADDR_BMP_BSS_IDX_SHIFT 8
949
950#define WSEC_MAX_RCMTA_KEYS 54
951
952/* max keys in M_TKMICKEYS_BLK */
953#define WSEC_MAX_TKMIC_ENGINE_KEYS 12 /* 8 + 4 default */
954
955/* max RXE match registers */
956#define WSEC_MAX_RXE_KEYS 4
957
958/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */
959/* SKL (Security Key Lookup) */
960#define SKL_ALGO_MASK 0x0007
961#define SKL_ALGO_SHIFT 0
962#define SKL_KEYID_MASK 0x0008
963#define SKL_KEYID_SHIFT 3
964#define SKL_INDEX_MASK 0x03F0
965#define SKL_INDEX_SHIFT 4
966#define SKL_GRP_ALGO_MASK 0x1c00
967#define SKL_GRP_ALGO_SHIFT 10
968
969/* additional bits defined for IBSS group key support */
970#define SKL_IBSS_INDEX_MASK 0x01F0
971#define SKL_IBSS_INDEX_SHIFT 4
972#define SKL_IBSS_KEYID1_MASK 0x0600
973#define SKL_IBSS_KEYID1_SHIFT 9
974#define SKL_IBSS_KEYID2_MASK 0x1800
975#define SKL_IBSS_KEYID2_SHIFT 11
976#define SKL_IBSS_KEYALGO_MASK 0xE000
977#define SKL_IBSS_KEYALGO_SHIFT 13
978
979#define WSEC_MODE_OFF 0
980#define WSEC_MODE_HW 1
981#define WSEC_MODE_SW 2
982
983#define WSEC_ALGO_OFF 0
984#define WSEC_ALGO_WEP1 1
985#define WSEC_ALGO_TKIP 2
986#define WSEC_ALGO_AES 3
987#define WSEC_ALGO_WEP128 4
988#define WSEC_ALGO_AES_LEGACY 5
989#define WSEC_ALGO_NALG 6
990
991#define AES_MODE_NONE 0
992#define AES_MODE_CCM 1
993
994/* WEP_CTL (Rev 0) */
995#define WECR0_KEYREG_SHIFT 0
996#define WECR0_KEYREG_MASK 0x7
997#define WECR0_DECRYPT (1 << 3)
998#define WECR0_IVINLINE (1 << 4)
999#define WECR0_WEPALG_SHIFT 5
1000#define WECR0_WEPALG_MASK (0x7 << 5)
1001#define WECR0_WKEYSEL_SHIFT 8
1002#define WECR0_WKEYSEL_MASK (0x7 << 8)
1003#define WECR0_WKEYSTART (1 << 11)
1004#define WECR0_WEPINIT (1 << 14)
1005#define WECR0_ICVERR (1 << 15)
1006
1007/* Frame template map byte offsets */
1008#define T_ACTS_TPL_BASE (0)
1009#define T_NULL_TPL_BASE (0xc * 2)
1010#define T_QNULL_TPL_BASE (0x1c * 2)
1011#define T_RR_TPL_BASE (0x2c * 2)
1012#define T_BCN0_TPL_BASE (0x34 * 2)
1013#define T_PRS_TPL_BASE (0x134 * 2)
1014#define T_BCN1_TPL_BASE (0x234 * 2)
1015#define T_TX_FIFO_TXRAM_BASE (T_ACTS_TPL_BASE + (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT))
1016
1017#define T_BA_TPL_BASE T_QNULL_TPL_BASE /* template area for BA */
1018
1019#define T_RAM_ACCESS_SZ 4 /* template ram is 4 byte access only */
1020
1021/* Shared Mem byte offsets */
1022
1023/* Location where the ucode expects the corerev */
1024#define M_MACHW_VER (0x00b * 2)
1025
1026/* Location where the ucode expects the MAC capabilities */
1027#define M_MACHW_CAP_L (0x060 * 2)
1028#define M_MACHW_CAP_H (0x061 * 2)
1029
1030/* WME shared memory */
1031#define M_EDCF_STATUS_OFF (0x007 * 2)
1032#define M_TXF_CUR_INDEX (0x018 * 2)
1033#define M_EDCF_QINFO (0x120 * 2)
1034
1035/* PS-mode related parameters */
1036#define M_DOT11_SLOT (0x008 * 2)
1037#define M_DOT11_DTIMPERIOD (0x009 * 2)
1038#define M_NOSLPZNATDTIM (0x026 * 2)
1039
1040/* Beacon-related parameters */
1041#define M_BCN0_FRM_BYTESZ (0x00c * 2) /* Bcn 0 template length */
1042#define M_BCN1_FRM_BYTESZ (0x00d * 2) /* Bcn 1 template length */
1043#define M_BCN_TXTSF_OFFSET (0x00e * 2)
1044#define M_TIMBPOS_INBEACON (0x00f * 2)
1045#define M_SFRMTXCNTFBRTHSD (0x022 * 2)
1046#define M_LFRMTXCNTFBRTHSD (0x023 * 2)
1047#define M_BCN_PCTLWD (0x02a * 2)
1048#define M_BCN_LI (0x05b * 2) /* beacon listen interval */
1049
1050/* MAX Rx Frame len */
1051#define M_MAXRXFRM_LEN (0x010 * 2)
1052
1053/* ACK/CTS related params */
1054#define M_RSP_PCTLWD (0x011 * 2)
1055
1056/* Hardware Power Control */
1057#define M_TXPWR_N (0x012 * 2)
1058#define M_TXPWR_TARGET (0x013 * 2)
1059#define M_TXPWR_MAX (0x014 * 2)
1060#define M_TXPWR_CUR (0x019 * 2)
1061
1062/* Rx-related parameters */
1063#define M_RX_PAD_DATA_OFFSET (0x01a * 2)
1064
1065/* WEP Shared mem data */
1066#define M_SEC_DEFIVLOC (0x01e * 2)
1067#define M_SEC_VALNUMSOFTMCHTA (0x01f * 2)
1068#define M_PHYVER (0x028 * 2)
1069#define M_PHYTYPE (0x029 * 2)
1070#define M_SECRXKEYS_PTR (0x02b * 2)
1071#define M_TKMICKEYS_PTR (0x059 * 2)
1072#define M_SECKINDXALGO_BLK (0x2ea * 2)
1073#define M_SECKINDXALGO_BLK_SZ 54
1074#define M_SECPSMRXTAMCH_BLK (0x2fa * 2)
1075#define M_TKIP_TSC_TTAK (0x18c * 2)
1076#define D11_MAX_KEY_SIZE 16
1077
1078#define M_MAX_ANTCNT (0x02e * 2) /* antenna swap threshold */
1079
1080/* Probe response related parameters */
1081#define M_SSIDLEN (0x024 * 2)
1082#define M_PRB_RESP_FRM_LEN (0x025 * 2)
1083#define M_PRS_MAXTIME (0x03a * 2)
1084#define M_SSID (0xb0 * 2)
1085#define M_CTXPRS_BLK (0xc0 * 2)
1086#define C_CTX_PCTLWD_POS (0x4 * 2)
1087
1088/* Delta between OFDM and CCK power in CCK power boost mode */
1089#define M_OFDM_OFFSET (0x027 * 2)
1090
1091/* TSSI for last 4 11b/g CCK packets transmitted */
1092#define M_B_TSSI_0 (0x02c * 2)
1093#define M_B_TSSI_1 (0x02d * 2)
1094
1095/* Host flags to turn on ucode options */
1096#define M_HOST_FLAGS1 (0x02f * 2)
1097#define M_HOST_FLAGS2 (0x030 * 2)
1098#define M_HOST_FLAGS3 (0x031 * 2)
1099#define M_HOST_FLAGS4 (0x03c * 2)
1100#define M_HOST_FLAGS5 (0x06a * 2)
1101#define M_HOST_FLAGS_SZ 16
1102
1103#define M_RADAR_REG (0x033 * 2)
1104
1105/* TSSI for last 4 11a OFDM packets transmitted */
1106#define M_A_TSSI_0 (0x034 * 2)
1107#define M_A_TSSI_1 (0x035 * 2)
1108
1109/* noise interference measurement */
1110#define M_NOISE_IF_COUNT (0x034 * 2)
1111#define M_NOISE_IF_TIMEOUT (0x035 * 2)
1112
1113#define M_RF_RX_SP_REG1 (0x036 * 2)
1114
1115/* TSSI for last 4 11g OFDM packets transmitted */
1116#define M_G_TSSI_0 (0x038 * 2)
1117#define M_G_TSSI_1 (0x039 * 2)
1118
1119/* Background noise measure */
1120#define M_JSSI_0 (0x44 * 2)
1121#define M_JSSI_1 (0x45 * 2)
1122#define M_JSSI_AUX (0x46 * 2)
1123
1124#define M_CUR_2050_RADIOCODE (0x47 * 2)
1125
1126/* TX fifo sizes */
1127#define M_FIFOSIZE0 (0x4c * 2)
1128#define M_FIFOSIZE1 (0x4d * 2)
1129#define M_FIFOSIZE2 (0x4e * 2)
1130#define M_FIFOSIZE3 (0x4f * 2)
1131#define D11_MAX_TX_FRMS 32 /* max frames allowed in tx fifo */
1132
1133/* Current channel number plus upper bits */
1134#define M_CURCHANNEL (0x50 * 2)
1135#define D11_CURCHANNEL_5G 0x0100;
1136#define D11_CURCHANNEL_40 0x0200;
1137#define D11_CURCHANNEL_MAX 0x00FF;
1138
1139/* last posted frameid on the bcmc fifo */
1140#define M_BCMC_FID (0x54 * 2)
1141#define INVALIDFID 0xffff
1142
1143/* extended beacon phyctl bytes for 11N */
1144#define M_BCN_PCTL1WD (0x058 * 2)
1145
1146/* idle busy ratio to duty_cycle requirement */
1147#define M_TX_IDLE_BUSY_RATIO_X_16_CCK (0x52 * 2)
1148#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
1149
1150/* CW RSSI for LCNPHY */
1151#define M_LCN_RSSI_0 0x1332
1152#define M_LCN_RSSI_1 0x1338
1153#define M_LCN_RSSI_2 0x133e
1154#define M_LCN_RSSI_3 0x1344
1155
1156/* SNR for LCNPHY */
1157#define M_LCN_SNR_A_0 0x1334
1158#define M_LCN_SNR_B_0 0x1336
1159
1160#define M_LCN_SNR_A_1 0x133a
1161#define M_LCN_SNR_B_1 0x133c
1162
1163#define M_LCN_SNR_A_2 0x1340
1164#define M_LCN_SNR_B_2 0x1342
1165
1166#define M_LCN_SNR_A_3 0x1346
1167#define M_LCN_SNR_B_3 0x1348
1168
1169#define M_LCN_LAST_RESET (81*2)
1170#define M_LCN_LAST_LOC (63*2)
1171#define M_LCNPHY_RESET_STATUS (4902)
1172#define M_LCNPHY_DSC_TIME (0x98d*2)
1173#define M_LCNPHY_RESET_CNT_DSC (0x98b*2)
1174#define M_LCNPHY_RESET_CNT (0x98c*2)
1175
1176/* Rate table offsets */
1177#define M_RT_DIRMAP_A (0xe0 * 2)
1178#define M_RT_BBRSMAP_A (0xf0 * 2)
1179#define M_RT_DIRMAP_B (0x100 * 2)
1180#define M_RT_BBRSMAP_B (0x110 * 2)
1181
1182/* Rate table entry offsets */
1183#define M_RT_PRS_PLCP_POS 10
1184#define M_RT_PRS_DUR_POS 16
1185#define M_RT_OFDM_PCTL1_POS 18
1186
1187#define M_20IN40_IQ (0x380 * 2)
1188
1189/* SHM locations where ucode stores the current power index */
1190#define M_CURR_IDX1 (0x384 * 2)
1191#define M_CURR_IDX2 (0x387 * 2)
1192
1193#define M_BSCALE_ANT0 (0x5e * 2)
1194#define M_BSCALE_ANT1 (0x5f * 2)
1195
1196/* Antenna Diversity Testing */
1197#define M_MIMO_ANTSEL_RXDFLT (0x63 * 2)
1198#define M_ANTSEL_CLKDIV (0x61 * 2)
1199#define M_MIMO_ANTSEL_TXDFLT (0x64 * 2)
1200
1201#define M_MIMO_MAXSYM (0x5d * 2)
1202#define MIMO_MAXSYM_DEF 0x8000 /* 32k */
1203#define MIMO_MAXSYM_MAX 0xffff /* 64k */
1204
1205#define M_WATCHDOG_8TU (0x1e * 2)
1206#define WATCHDOG_8TU_DEF 5
1207#define WATCHDOG_8TU_MAX 10
1208
1209/* Manufacturing Test Variables */
1210#define M_PKTENG_CTRL (0x6c * 2) /* PER test mode */
1211#define M_PKTENG_IFS (0x6d * 2) /* IFS for TX mode */
1212#define M_PKTENG_FRMCNT_LO (0x6e * 2) /* Lower word of tx frmcnt/rx lostcnt */
1213#define M_PKTENG_FRMCNT_HI (0x6f * 2) /* Upper word of tx frmcnt/rx lostcnt */
1214
1215/* Index variation in vbat ripple */
1216#define M_LCN_PWR_IDX_MAX (0x67 * 2) /* highest index read by ucode */
1217#define M_LCN_PWR_IDX_MIN (0x66 * 2) /* lowest index read by ucode */
1218
1219/* M_PKTENG_CTRL bit definitions */
1220#define M_PKTENG_MODE_TX 0x0001
1221#define M_PKTENG_MODE_TX_RIFS 0x0004
1222#define M_PKTENG_MODE_TX_CTS 0x0008
1223#define M_PKTENG_MODE_RX 0x0002
1224#define M_PKTENG_MODE_RX_WITH_ACK 0x0402
1225#define M_PKTENG_MODE_MASK 0x0003
1226#define M_PKTENG_FRMCNT_VLD 0x0100 /* TX frames indicated in the frmcnt reg */
1227
1228/* Sample Collect parameters (bitmap and type) */
1229#define M_SMPL_COL_BMP (0x37d * 2) /* Trigger bitmap for sample collect */
1230#define M_SMPL_COL_CTL (0x3b2 * 2) /* Sample collect type */
1231
1232#define ANTSEL_CLKDIV_4MHZ 6
1233#define MIMO_ANTSEL_BUSY 0x4000 /* bit 14 (busy) */
1234#define MIMO_ANTSEL_SEL 0x8000 /* bit 15 write the value */
1235#define MIMO_ANTSEL_WAIT 50 /* 50us wait */
1236#define MIMO_ANTSEL_OVERRIDE 0x8000 /* flag */
1237
1238struct shm_acparams {
1239 u16 txop;
1240 u16 cwmin;
1241 u16 cwmax;
1242 u16 cwcur;
1243 u16 aifs;
1244 u16 bslots;
1245 u16 reggap;
1246 u16 status;
1247 u16 rsvd[8];
1248} __packed;
1249#define M_EDCF_QLEN (16 * 2)
1250
1251#define WME_STATUS_NEWAC (1 << 8)
1252
1253/* M_HOST_FLAGS */
1254#define MHFMAX 5 /* Number of valid hostflag half-word (u16) */
1255#define MHF1 0 /* Hostflag 1 index */
1256#define MHF2 1 /* Hostflag 2 index */
1257#define MHF3 2 /* Hostflag 3 index */
1258#define MHF4 3 /* Hostflag 4 index */
1259#define MHF5 4 /* Hostflag 5 index */
1260
1261/* Flags in M_HOST_FLAGS */
1262#define MHF1_ANTDIV 0x0001 /* Enable ucode antenna diversity help */
1263#define MHF1_EDCF 0x0100 /* Enable EDCF access control */
1264#define MHF1_IQSWAP_WAR 0x0200
1265#define MHF1_FORCEFASTCLK 0x0400 /* Disable Slow clock request, for corerev < 11 */
1266
1267/* Flags in M_HOST_FLAGS2 */
1268#define MHF2_PCISLOWCLKWAR 0x0008 /* PR16165WAR : Enable ucode PCI slow clock WAR */
1269#define MHF2_TXBCMC_NOW 0x0040 /* Flush BCMC FIFO immediately */
1270#define MHF2_HWPWRCTL 0x0080 /* Enable ucode/hw power control */
1271#define MHF2_NPHY40MHZ_WAR 0x0800
1272
1273/* Flags in M_HOST_FLAGS3 */
1274#define MHF3_ANTSEL_EN 0x0001 /* enabled mimo antenna selection */
1275#define MHF3_ANTSEL_MODE 0x0002 /* antenna selection mode: 0: 2x3, 1: 2x4 */
1276#define MHF3_RESERVED1 0x0004
1277#define MHF3_RESERVED2 0x0008
1278#define MHF3_NPHY_MLADV_WAR 0x0010
1279
1280/* Flags in M_HOST_FLAGS4 */
1281#define MHF4_BPHY_TXCORE0 0x0080 /* force bphy Tx on core 0 (board level WAR) */
1282#define MHF4_EXTPA_ENABLE 0x4000 /* for 4313A0 FEM boards */
1283
1284/* Flags in M_HOST_FLAGS5 */
1285#define MHF5_4313_GPIOCTRL 0x0001
1286#define MHF5_RESERVED1 0x0002
1287#define MHF5_RESERVED2 0x0004
1288/* Radio power setting for ucode */
1289#define M_RADIO_PWR (0x32 * 2)
1290
1291/* phy noise recorded by ucode right after tx */
1292#define M_PHY_NOISE (0x037 * 2)
1293#define PHY_NOISE_MASK 0x00ff
1294
1295/* Receive Frame Data Header for 802.11b DCF-only frames */
1296struct d11rxhdr {
1297 u16 RxFrameSize; /* Actual byte length of the frame data received */
1298 u16 PAD;
1299 u16 PhyRxStatus_0; /* PhyRxStatus 15:0 */
1300 u16 PhyRxStatus_1; /* PhyRxStatus 31:16 */
1301 u16 PhyRxStatus_2; /* PhyRxStatus 47:32 */
1302 u16 PhyRxStatus_3; /* PhyRxStatus 63:48 */
1303 u16 PhyRxStatus_4; /* PhyRxStatus 79:64 */
1304 u16 PhyRxStatus_5; /* PhyRxStatus 95:80 */
1305 u16 RxStatus1; /* MAC Rx Status */
1306 u16 RxStatus2; /* extended MAC Rx status */
1307 u16 RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */
1308 u16 RxChan; /* gain code, channel radio code, and phy type */
1309} __packed;
1310
1311#define RXHDR_LEN 24 /* sizeof struct d11rxhdr */
1312#define FRAMELEN(h) ((h)->RxFrameSize)
1313
1314struct brcms_d11rxhdr {
1315 struct d11rxhdr rxhdr;
1316 u32 tsf_l; /* TSF_L reading */
1317 s8 rssi; /* computed instanteneous rssi in BMAC */
1318 s8 rxpwr0; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */
1319 s8 rxpwr1; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */
1320 s8 do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */
1321 s8 rxpwr[WL_RSSI_ANT_MAX]; /* rssi for supported antennas */
1322} __packed;
1323
1324/* PhyRxStatus_0: */
1325#define PRXS0_FT_MASK 0x0003 /* NPHY only: CCK, OFDM, preN, N */
1326#define PRXS0_CLIP_MASK 0x000C /* NPHY only: clip count adjustment steps by AGC */
1327#define PRXS0_CLIP_SHIFT 2
1328#define PRXS0_UNSRATE 0x0010 /* PHY received a frame with unsupported rate */
1329#define PRXS0_RXANT_UPSUBBAND 0x0020 /* GPHY: rx ant, NPHY: upper sideband */
1330#define PRXS0_LCRS 0x0040 /* CCK frame only: lost crs during cck frame reception */
1331#define PRXS0_SHORTH 0x0080 /* Short Preamble */
1332#define PRXS0_PLCPFV 0x0100 /* PLCP violation */
1333#define PRXS0_PLCPHCF 0x0200 /* PLCP header integrity check failed */
1334#define PRXS0_GAIN_CTL 0x4000 /* legacy PHY gain control */
1335#define PRXS0_ANTSEL_MASK 0xF000 /* NPHY: Antennas used for received frame, bitmask */
1336#define PRXS0_ANTSEL_SHIFT 0x12
1337
1338/* subfield PRXS0_FT_MASK */
1339#define PRXS0_CCK 0x0000
1340#define PRXS0_OFDM 0x0001 /* valid only for G phy, use rxh->RxChan for A phy */
1341#define PRXS0_PREN 0x0002
1342#define PRXS0_STDN 0x0003
1343
1344/* subfield PRXS0_ANTSEL_MASK */
1345#define PRXS0_ANTSEL_0 0x0 /* antenna 0 is used */
1346#define PRXS0_ANTSEL_1 0x2 /* antenna 1 is used */
1347#define PRXS0_ANTSEL_2 0x4 /* antenna 2 is used */
1348#define PRXS0_ANTSEL_3 0x8 /* antenna 3 is used */
1349
1350/* PhyRxStatus_1: */
1351#define PRXS1_JSSI_MASK 0x00FF
1352#define PRXS1_JSSI_SHIFT 0
1353#define PRXS1_SQ_MASK 0xFF00
1354#define PRXS1_SQ_SHIFT 8
1355
1356/* nphy PhyRxStatus_1: */
1357#define PRXS1_nphy_PWR0_MASK 0x00FF
1358#define PRXS1_nphy_PWR1_MASK 0xFF00
1359
1360/* HTPHY Rx Status defines */
1361/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */
1362#define PRXS0_BAND 0x0400 /* 0 = 2.4G, 1 = 5G */
1363#define PRXS0_RSVD 0x0800 /* reserved; set to 0 */
1364#define PRXS0_UNUSED 0xF000 /* unused and not defined; set to 0 */
1365
1366/* htphy PhyRxStatus_1: */
1367#define PRXS1_HTPHY_CORE_MASK 0x000F /* core enables for {3..0}, 0=disabled, 1=enabled */
1368#define PRXS1_HTPHY_ANTCFG_MASK 0x00F0 /* antenna configation */
1369#define PRXS1_HTPHY_MMPLCPLenL_MASK 0xFF00 /* Mixmode PLCP Length low byte mask */
1370
1371/* htphy PhyRxStatus_2: */
1372#define PRXS2_HTPHY_MMPLCPLenH_MASK 0x000F /* Mixmode PLCP Length high byte maskw */
1373#define PRXS2_HTPHY_MMPLCH_RATE_MASK 0x00F0 /* Mixmode PLCP rate mask */
1374#define PRXS2_HTPHY_RXPWR_ANT0 0xFF00 /* Rx power on core 0 */
1375
1376/* htphy PhyRxStatus_3: */
1377#define PRXS3_HTPHY_RXPWR_ANT1 0x00FF /* Rx power on core 1 */
1378#define PRXS3_HTPHY_RXPWR_ANT2 0xFF00 /* Rx power on core 2 */
1379
1380/* htphy PhyRxStatus_4: */
1381#define PRXS4_HTPHY_RXPWR_ANT3 0x00FF /* Rx power on core 3 */
1382#define PRXS4_HTPHY_CFO 0xFF00 /* Coarse frequency offset */
1383
1384/* htphy PhyRxStatus_5: */
1385#define PRXS5_HTPHY_FFO 0x00FF /* Fine frequency offset */
1386#define PRXS5_HTPHY_AR 0xFF00 /* Advance Retard */
1387
1388#define HTPHY_MMPLCPLen(rxs) ((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \
1389 (((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8))
1390/* Get Rx power on core 0 */
1391#define HTPHY_RXPWR_ANT0(rxs) ((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8)
1392/* Get Rx power on core 1 */
1393#define HTPHY_RXPWR_ANT1(rxs) (((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1)
1394/* Get Rx power on core 2 */
1395#define HTPHY_RXPWR_ANT2(rxs) ((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8)
1396
1397/* ucode RxStatus1: */
1398#define RXS_BCNSENT 0x8000
1399#define RXS_SECKINDX_MASK 0x07e0
1400#define RXS_SECKINDX_SHIFT 5
1401#define RXS_DECERR (1 << 4)
1402#define RXS_DECATMPT (1 << 3)
1403#define RXS_PBPRES (1 << 2) /* PAD bytes to make IP data 4 bytes aligned */
1404#define RXS_RESPFRAMETX (1 << 1)
1405#define RXS_FCSERR (1 << 0)
1406
1407/* ucode RxStatus2: */
1408#define RXS_AMSDU_MASK 1
1409#define RXS_AGGTYPE_MASK 0x6
1410#define RXS_AGGTYPE_SHIFT 1
1411#define RXS_PHYRXST_VALID (1 << 8)
1412#define RXS_RXANT_MASK 0x3
1413#define RXS_RXANT_SHIFT 12
1414
1415/* RxChan */
1416#define RXS_CHAN_40 0x1000
1417#define RXS_CHAN_5G 0x0800
1418#define RXS_CHAN_ID_MASK 0x07f8
1419#define RXS_CHAN_ID_SHIFT 3
1420#define RXS_CHAN_PHYTYPE_MASK 0x0007
1421#define RXS_CHAN_PHYTYPE_SHIFT 0
1422
1423/* Index of attenuations used during ucode power control. */
1424#define M_PWRIND_BLKS (0x184 * 2)
1425#define M_PWRIND_MAP0 (M_PWRIND_BLKS + 0x0)
1426#define M_PWRIND_MAP1 (M_PWRIND_BLKS + 0x2)
1427#define M_PWRIND_MAP2 (M_PWRIND_BLKS + 0x4)
1428#define M_PWRIND_MAP3 (M_PWRIND_BLKS + 0x6)
1429/* M_PWRIND_MAP(core) macro */
1430#define M_PWRIND_MAP(core) (M_PWRIND_BLKS + ((core)<<1))
1431
1432/* PSM SHM variable offsets */
1433#define M_PSM_SOFT_REGS 0x0
1434#define M_BOM_REV_MAJOR (M_PSM_SOFT_REGS + 0x0)
1435#define M_BOM_REV_MINOR (M_PSM_SOFT_REGS + 0x2)
1436#define M_UCODE_DBGST (M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */
1437#define M_UCODE_MACSTAT (M_PSM_SOFT_REGS + 0xE0) /* macstat counters */
1438
1439#define M_AGING_THRSH (0x3e * 2) /* max time waiting for medium before tx */
1440#define M_MBURST_SIZE (0x40 * 2) /* max frames in a frameburst */
1441#define M_MBURST_TXOP (0x41 * 2) /* max frameburst TXOP in unit of us */
1442#define M_SYNTHPU_DLY (0x4a * 2) /* pre-wakeup for synthpu, default: 500 */
1443#define M_PRETBTT (0x4b * 2)
1444
1445#define M_ALT_TXPWR_IDX (M_PSM_SOFT_REGS + (0x3b * 2)) /* offset to the target txpwr */
1446#define M_PHY_TX_FLT_PTR (M_PSM_SOFT_REGS + (0x3d * 2))
1447#define M_CTS_DURATION (M_PSM_SOFT_REGS + (0x5c * 2))
1448#define M_LP_RCCAL_OVR (M_PSM_SOFT_REGS + (0x6b * 2))
1449
1450/* PKTENG Rx Stats Block */
1451#define M_RXSTATS_BLK_PTR (M_PSM_SOFT_REGS + (0x65 * 2))
1452
1453/* ucode debug status codes */
1454#define DBGST_INACTIVE 0 /* not valid really */
1455#define DBGST_INIT 1 /* after zeroing SHM, before suspending at init */
1456#define DBGST_ACTIVE 2 /* "normal" state */
1457#define DBGST_SUSPENDED 3 /* suspended */
1458#define DBGST_ASLEEP 4 /* asleep (PS mode) */
1459
1460/* Scratch Reg defs */
1461enum _ePsmScratchPadRegDefinitions {
1462 S_RSV0 = 0,
1463 S_RSV1,
1464 S_RSV2,
1465
1466 /* scratch registers for Dot11-contants */
1467 S_DOT11_CWMIN, /* CW-minimum 0x03 */
1468 S_DOT11_CWMAX, /* CW-maximum 0x04 */
1469 S_DOT11_CWCUR, /* CW-current 0x05 */
1470 S_DOT11_SRC_LMT, /* short retry count limit 0x06 */
1471 S_DOT11_LRC_LMT, /* long retry count limit 0x07 */
1472 S_DOT11_DTIMCOUNT, /* DTIM-count 0x08 */
1473
1474 /* Tx-side scratch registers */
1475 S_SEQ_NUM, /* hardware sequence number reg 0x09 */
1476 S_SEQ_NUM_FRAG, /* seq-num for frags (Set at the start os MSDU 0x0A */
1477 S_FRMRETX_CNT, /* frame retx count 0x0B */
1478 S_SSRC, /* Station short retry count 0x0C */
1479 S_SLRC, /* Station long retry count 0x0D */
1480 S_EXP_RSP, /* Expected response frame 0x0E */
1481 S_OLD_BREM, /* Remaining backoff ctr 0x0F */
1482 S_OLD_CWWIN, /* saved-off CW-cur 0x10 */
1483 S_TXECTL, /* TXE-Ctl word constructed in scr-pad 0x11 */
1484 S_CTXTST, /* frm type-subtype as read from Tx-descr 0x12 */
1485
1486 /* Rx-side scratch registers */
1487 S_RXTST, /* Type and subtype in Rxframe 0x13 */
1488
1489 /* Global state register */
1490 S_STREG, /* state storage actual bit maps below 0x14 */
1491
1492 S_TXPWR_SUM, /* Tx power control: accumulator 0x15 */
1493 S_TXPWR_ITER, /* Tx power control: iteration 0x16 */
1494 S_RX_FRMTYPE, /* Rate and PHY type for frames 0x17 */
1495 S_THIS_AGG, /* Size of this AGG (A-MSDU) 0x18 */
1496
1497 S_KEYINDX, /* 0x19 */
1498 S_RXFRMLEN, /* Receive MPDU length in bytes 0x1A */
1499
1500 /* Receive TSF time stored in SCR */
1501 S_RXTSFTMRVAL_WD3, /* TSF value at the start of rx 0x1B */
1502 S_RXTSFTMRVAL_WD2, /* TSF value at the start of rx 0x1C */
1503 S_RXTSFTMRVAL_WD1, /* TSF value at the start of rx 0x1D */
1504 S_RXTSFTMRVAL_WD0, /* TSF value at the start of rx 0x1E */
1505 S_RXSSN, /* Received start seq number for A-MPDU BA 0x1F */
1506 S_RXQOSFLD, /* Rx-QoS field (if present) 0x20 */
1507
1508 /* Scratch pad regs used in microcode as temp storage */
1509 S_TMP0, /* stmp0 0x21 */
1510 S_TMP1, /* stmp1 0x22 */
1511 S_TMP2, /* stmp2 0x23 */
1512 S_TMP3, /* stmp3 0x24 */
1513 S_TMP4, /* stmp4 0x25 */
1514 S_TMP5, /* stmp5 0x26 */
1515 S_PRQPENALTY_CTR, /* Probe response queue penalty counter 0x27 */
1516 S_ANTCNT, /* unsuccessful attempts on current ant. 0x28 */
1517 S_SYMBOL, /* flag for possible symbol ctl frames 0x29 */
1518 S_RXTP, /* rx frame type 0x2A */
1519 S_STREG2, /* extra state storage 0x2B */
1520 S_STREG3, /* even more extra state storage 0x2C */
1521 S_STREG4, /* ... 0x2D */
1522 S_STREG5, /* remember to initialize it to zero 0x2E */
1523
1524 S_ADJPWR_IDX,
1525 S_CUR_PTR, /* Temp pointer for A-MPDU re-Tx SHM table 0x32 */
1526 S_REVID4, /* 0x33 */
1527 S_INDX, /* 0x34 */
1528 S_ADDR0, /* 0x35 */
1529 S_ADDR1, /* 0x36 */
1530 S_ADDR2, /* 0x37 */
1531 S_ADDR3, /* 0x38 */
1532 S_ADDR4, /* 0x39 */
1533 S_ADDR5, /* 0x3A */
1534 S_TMP6, /* 0x3B */
1535 S_KEYINDX_BU, /* Backup for Key index 0x3C */
1536 S_MFGTEST_TMP0, /* Temp register used for RX test calculations 0x3D */
1537 S_RXESN, /* Received end sequence number for A-MPDU BA 0x3E */
1538 S_STREG6, /* 0x3F */
1539};
1540
1541#define S_BEACON_INDX S_OLD_BREM
1542#define S_PRS_INDX S_OLD_CWWIN
1543#define S_PHYTYPE S_SSRC
1544#define S_PHYVER S_SLRC
1545
1546/* IHR SLOW_CTRL values */
1547#define SLOW_CTRL_PDE (1 << 0)
1548#define SLOW_CTRL_FD (1 << 8)
1549
1550/* ucode mac statistic counters in shared memory */
1551struct macstat {
1552 u16 txallfrm; /* 0x80 */
1553 u16 txrtsfrm; /* 0x82 */
1554 u16 txctsfrm; /* 0x84 */
1555 u16 txackfrm; /* 0x86 */
1556 u16 txdnlfrm; /* 0x88 */
1557 u16 txbcnfrm; /* 0x8a */
1558 u16 txfunfl[8]; /* 0x8c - 0x9b */
1559 u16 txtplunfl; /* 0x9c */
1560 u16 txphyerr; /* 0x9e */
1561 u16 pktengrxducast; /* 0xa0 */
1562 u16 pktengrxdmcast; /* 0xa2 */
1563 u16 rxfrmtoolong; /* 0xa4 */
1564 u16 rxfrmtooshrt; /* 0xa6 */
1565 u16 rxinvmachdr; /* 0xa8 */
1566 u16 rxbadfcs; /* 0xaa */
1567 u16 rxbadplcp; /* 0xac */
1568 u16 rxcrsglitch; /* 0xae */
1569 u16 rxstrt; /* 0xb0 */
1570 u16 rxdfrmucastmbss; /* 0xb2 */
1571 u16 rxmfrmucastmbss; /* 0xb4 */
1572 u16 rxcfrmucast; /* 0xb6 */
1573 u16 rxrtsucast; /* 0xb8 */
1574 u16 rxctsucast; /* 0xba */
1575 u16 rxackucast; /* 0xbc */
1576 u16 rxdfrmocast; /* 0xbe */
1577 u16 rxmfrmocast; /* 0xc0 */
1578 u16 rxcfrmocast; /* 0xc2 */
1579 u16 rxrtsocast; /* 0xc4 */
1580 u16 rxctsocast; /* 0xc6 */
1581 u16 rxdfrmmcast; /* 0xc8 */
1582 u16 rxmfrmmcast; /* 0xca */
1583 u16 rxcfrmmcast; /* 0xcc */
1584 u16 rxbeaconmbss; /* 0xce */
1585 u16 rxdfrmucastobss; /* 0xd0 */
1586 u16 rxbeaconobss; /* 0xd2 */
1587 u16 rxrsptmout; /* 0xd4 */
1588 u16 bcntxcancl; /* 0xd6 */
1589 u16 PAD;
1590 u16 rxf0ovfl; /* 0xda */
1591 u16 rxf1ovfl; /* 0xdc */
1592 u16 rxf2ovfl; /* 0xde */
1593 u16 txsfovfl; /* 0xe0 */
1594 u16 pmqovfl; /* 0xe2 */
1595 u16 rxcgprqfrm; /* 0xe4 */
1596 u16 rxcgprsqovfl; /* 0xe6 */
1597 u16 txcgprsfail; /* 0xe8 */
1598 u16 txcgprssuc; /* 0xea */
1599 u16 prs_timeout; /* 0xec */
1600 u16 rxnack;
1601 u16 frmscons;
1602 u16 txnack;
1603 u16 txglitch_nack;
1604 u16 txburst; /* 0xf6 # tx bursts */
1605 u16 bphy_rxcrsglitch; /* bphy rx crs glitch */
1606 u16 phywatchdog; /* 0xfa # of phy watchdog events */
1607 u16 PAD;
1608 u16 bphy_badplcp; /* bphy bad plcp */
1609};
1610
1611/* dot11 core-specific control flags */
1612#define SICF_PCLKE 0x0004 /* PHY clock enable */
1613#define SICF_PRST 0x0008 /* PHY reset */
1614#define SICF_MPCLKE 0x0010 /* MAC PHY clockcontrol enable */
1615#define SICF_FREF 0x0020 /* PLL FreqRefSelect */
1616/* NOTE: the following bw bits only apply when the core is attached
1617 * to a NPHY
1618 */
1619#define SICF_BWMASK 0x00c0 /* phy clock mask (b6 & b7) */
1620#define SICF_BW40 0x0080 /* 40MHz BW (160MHz phyclk) */
1621#define SICF_BW20 0x0040 /* 20MHz BW (80MHz phyclk) */
1622#define SICF_BW10 0x0000 /* 10MHz BW (40MHz phyclk) */
1623#define SICF_GMODE 0x2000 /* gmode enable */
1624
1625/* dot11 core-specific status flags */
1626#define SISF_2G_PHY 0x0001 /* 2.4G capable phy */
1627#define SISF_5G_PHY 0x0002 /* 5G capable phy */
1628#define SISF_FCLKA 0x0004 /* FastClkAvailable */
1629#define SISF_DB_PHY 0x0008 /* Dualband phy */
1630
1631/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg, radio and LPPHY regs are separated === */
1632
1633#define BPHY_REG_OFT_BASE 0x0
1634/* offsets for indirect access to bphy registers */
1635#define BPHY_BB_CONFIG 0x01
1636#define BPHY_ADCBIAS 0x02
1637#define BPHY_ANACORE 0x03
1638#define BPHY_PHYCRSTH 0x06
1639#define BPHY_TEST 0x0a
1640#define BPHY_PA_TX_TO 0x10
1641#define BPHY_SYNTH_DC_TO 0x11
1642#define BPHY_PA_TX_TIME_UP 0x12
1643#define BPHY_RX_FLTR_TIME_UP 0x13
1644#define BPHY_TX_POWER_OVERRIDE 0x14
1645#define BPHY_RF_OVERRIDE 0x15
1646#define BPHY_RF_TR_LOOKUP1 0x16
1647#define BPHY_RF_TR_LOOKUP2 0x17
1648#define BPHY_COEFFS 0x18
1649#define BPHY_PLL_OUT 0x19
1650#define BPHY_REFRESH_MAIN 0x1a
1651#define BPHY_REFRESH_TO0 0x1b
1652#define BPHY_REFRESH_TO1 0x1c
1653#define BPHY_RSSI_TRESH 0x20
1654#define BPHY_IQ_TRESH_HH 0x21
1655#define BPHY_IQ_TRESH_H 0x22
1656#define BPHY_IQ_TRESH_L 0x23
1657#define BPHY_IQ_TRESH_LL 0x24
1658#define BPHY_GAIN 0x25
1659#define BPHY_LNA_GAIN_RANGE 0x26
1660#define BPHY_JSSI 0x27
1661#define BPHY_TSSI_CTL 0x28
1662#define BPHY_TSSI 0x29
1663#define BPHY_TR_LOSS_CTL 0x2a
1664#define BPHY_LO_LEAKAGE 0x2b
1665#define BPHY_LO_RSSI_ACC 0x2c
1666#define BPHY_LO_IQMAG_ACC 0x2d
1667#define BPHY_TX_DC_OFF1 0x2e
1668#define BPHY_TX_DC_OFF2 0x2f
1669#define BPHY_PEAK_CNT_THRESH 0x30
1670#define BPHY_FREQ_OFFSET 0x31
1671#define BPHY_DIVERSITY_CTL 0x32
1672#define BPHY_PEAK_ENERGY_LO 0x33
1673#define BPHY_PEAK_ENERGY_HI 0x34
1674#define BPHY_SYNC_CTL 0x35
1675#define BPHY_TX_PWR_CTRL 0x36
1676#define BPHY_TX_EST_PWR 0x37
1677#define BPHY_STEP 0x38
1678#define BPHY_WARMUP 0x39
1679#define BPHY_LMS_CFF_READ 0x3a
1680#define BPHY_LMS_COEFF_I 0x3b
1681#define BPHY_LMS_COEFF_Q 0x3c
1682#define BPHY_SIG_POW 0x3d
1683#define BPHY_RFDC_CANCEL_CTL 0x3e
1684#define BPHY_HDR_TYPE 0x40
1685#define BPHY_SFD_TO 0x41
1686#define BPHY_SFD_CTL 0x42
1687#define BPHY_DEBUG 0x43
1688#define BPHY_RX_DELAY_COMP 0x44
1689#define BPHY_CRS_DROP_TO 0x45
1690#define BPHY_SHORT_SFD_NZEROS 0x46
1691#define BPHY_DSSS_COEFF1 0x48
1692#define BPHY_DSSS_COEFF2 0x49
1693#define BPHY_CCK_COEFF1 0x4a
1694#define BPHY_CCK_COEFF2 0x4b
1695#define BPHY_TR_CORR 0x4c
1696#define BPHY_ANGLE_SCALE 0x4d
1697#define BPHY_TX_PWR_BASE_IDX 0x4e
1698#define BPHY_OPTIONAL_MODES2 0x4f
1699#define BPHY_CCK_LMS_STEP 0x50
1700#define BPHY_BYPASS 0x51
1701#define BPHY_CCK_DELAY_LONG 0x52
1702#define BPHY_CCK_DELAY_SHORT 0x53
1703#define BPHY_PPROC_CHAN_DELAY 0x54
1704#define BPHY_DDFS_ENABLE 0x58
1705#define BPHY_PHASE_SCALE 0x59
1706#define BPHY_FREQ_CONTROL 0x5a
1707#define BPHY_LNA_GAIN_RANGE_10 0x5b
1708#define BPHY_LNA_GAIN_RANGE_32 0x5c
1709#define BPHY_OPTIONAL_MODES 0x5d
1710#define BPHY_RX_STATUS2 0x5e
1711#define BPHY_RX_STATUS3 0x5f
1712#define BPHY_DAC_CONTROL 0x60
1713#define BPHY_ANA11G_FILT_CTRL 0x62
1714#define BPHY_REFRESH_CTRL 0x64
1715#define BPHY_RF_OVERRIDE2 0x65
1716#define BPHY_SPUR_CANCEL_CTRL 0x66
1717#define BPHY_FINE_DIGIGAIN_CTRL 0x67
1718#define BPHY_RSSI_LUT 0x88
1719#define BPHY_RSSI_LUT_END 0xa7
1720#define BPHY_TSSI_LUT 0xa8
1721#define BPHY_TSSI_LUT_END 0xc7
1722#define BPHY_TSSI2PWR_LUT 0x380
1723#define BPHY_TSSI2PWR_LUT_END 0x39f
1724#define BPHY_LOCOMP_LUT 0x3a0
1725#define BPHY_LOCOMP_LUT_END 0x3bf
1726#define BPHY_TXGAIN_LUT 0x3c0
1727#define BPHY_TXGAIN_LUT_END 0x3ff
1728
1729/* Bits in BB_CONFIG: */
1730#define PHY_BBC_ANT_MASK 0x0180
1731#define PHY_BBC_ANT_SHIFT 7
1732#define BB_DARWIN 0x1000
1733#define BBCFG_RESETCCA 0x4000
1734#define BBCFG_RESETRX 0x8000
1735
1736/* Bits in phytest(0x0a): */
1737#define TST_DDFS 0x2000
1738#define TST_TXFILT1 0x0800
1739#define TST_UNSCRAM 0x0400
1740#define TST_CARR_SUPP 0x0200
1741#define TST_DC_COMP_LOOP 0x0100
1742#define TST_LOOPBACK 0x0080
1743#define TST_TXFILT0 0x0040
1744#define TST_TXTEST_ENABLE 0x0020
1745#define TST_TXTEST_RATE 0x0018
1746#define TST_TXTEST_PHASE 0x0007
1747
1748/* phytest txTestRate values */
1749#define TST_TXTEST_RATE_1MBPS 0
1750#define TST_TXTEST_RATE_2MBPS 1
1751#define TST_TXTEST_RATE_5_5MBPS 2
1752#define TST_TXTEST_RATE_11MBPS 3
1753#define TST_TXTEST_RATE_SHIFT 3
1754
1755#define SHM_BYT_CNT 0x2 /* IHR location */
1756#define MAX_BYT_CNT 0x600 /* Maximum frame len */
1757
1758struct d11cnt {
1759 u32 txfrag;
1760 u32 txmulti;
1761 u32 txfail;
1762 u32 txretry;
1763 u32 txretrie;
1764 u32 rxdup;
1765 u32 txrts;
1766 u32 txnocts;
1767 u32 txnoack;
1768 u32 rxfrag;
1769 u32 rxmulti;
1770 u32 rxcrc;
1771 u32 txfrmsnt;
1772 u32 rxundec;
1773};
1774
1775#endif /* _BRCM_D11_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/dma.c b/drivers/staging/brcm80211/brcmsmac/dma.c
new file mode 100644
index 00000000000..ea17671efb6
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/dma.c
@@ -0,0 +1,1917 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/slab.h>
17#include <linux/skbuff.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#if defined(__mips__)
22#include <asm/addrspace.h>
23#endif
24
25#include <brcmu_utils.h>
26#include <aiutils.h>
27#include "types.h"
28#include "dma.h"
29
30/*
31 * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical address.
32 */
33#define D64RINGALIGN_BITS 13
34#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS)
35#define D64RINGALIGN (1 << D64RINGALIGN_BITS)
36
37#define D64MAXDD (D64MAXRINGSZ / sizeof(struct dma64desc))
38
39/* transmit channel control */
40#define D64_XC_XE 0x00000001 /* transmit enable */
41#define D64_XC_SE 0x00000002 /* transmit suspend request */
42#define D64_XC_LE 0x00000004 /* loopback enable */
43#define D64_XC_FL 0x00000010 /* flush request */
44#define D64_XC_PD 0x00000800 /* parity check disable */
45#define D64_XC_AE 0x00030000 /* address extension bits */
46#define D64_XC_AE_SHIFT 16
47
48/* transmit descriptor table pointer */
49#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */
50
51/* transmit channel status */
52#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
53#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
54#define D64_XS0_XS_SHIFT 28
55#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
56#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
57#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
58#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
59#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
60
61#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */
62#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
63#define D64_XS1_XE_SHIFT 28
64#define D64_XS1_XE_NOERR 0x00000000 /* no error */
65#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
66#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
67#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
68#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
69#define D64_XS1_XE_COREE 0x50000000 /* core error */
70
71/* receive channel control */
72#define D64_RC_RE 0x00000001 /* receive enable */
73#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */
74#define D64_RC_RO_SHIFT 1
75#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */
76#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */
77#define D64_RC_OC 0x00000400 /* overflow continue */
78#define D64_RC_PD 0x00000800 /* parity check disable */
79#define D64_RC_AE 0x00030000 /* address extension bits */
80#define D64_RC_AE_SHIFT 16
81
82/* flags for dma controller */
83#define DMA_CTRL_PEN (1 << 0) /* partity enable */
84#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */
85#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */
86#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */
87
88/* receive descriptor table pointer */
89#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */
90
91/* receive channel status */
92#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
93#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
94#define D64_RS0_RS_SHIFT 28
95#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
96#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
97#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
98#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
99#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
100
101#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
102#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
103#define D64_RS1_RE_SHIFT 28
104#define D64_RS1_RE_NOERR 0x00000000 /* no error */
105#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
106#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
107#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
108#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
109#define D64_RS1_RE_COREE 0x50000000 /* core error */
110
111/* fifoaddr */
112#define D64_FA_OFF_MASK 0xffff /* offset */
113#define D64_FA_SEL_MASK 0xf0000 /* select */
114#define D64_FA_SEL_SHIFT 16
115#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
116#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
117#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
118#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
119#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
120#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
121#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
122#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
123#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
124#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
125
126/* descriptor control flags 1 */
127#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */
128#define D64_CTRL1_EOT ((u32)1 << 28) /* end of descriptor table */
129#define D64_CTRL1_IOC ((u32)1 << 29) /* interrupt on completion */
130#define D64_CTRL1_EOF ((u32)1 << 30) /* end of frame */
131#define D64_CTRL1_SOF ((u32)1 << 31) /* start of frame */
132
133/* descriptor control flags 2 */
134#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */
135#define D64_CTRL2_AE 0x00030000 /* address extension bits */
136#define D64_CTRL2_AE_SHIFT 16
137#define D64_CTRL2_PARITY 0x00040000 /* parity bit */
138
139/* control flags in the range [27:20] are core-specific and not defined here */
140#define D64_CTRL_CORE_MASK 0x0ff00000
141
142#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */
143#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */
144#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1 */
145#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */
146
147#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */
148#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */
149#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */
150#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */
151
152/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF).
153 * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL.
154 * There is a compile time check in wlc.c which ensure that this value is at least as big
155 * as TXOFF. This value is used in dma_rxfill (dma.c).
156 */
157
158#define BCMEXTRAHDROOM 172
159
160/* debug/trace */
161#ifdef BCMDBG
162#define DMA_ERROR(args) \
163 do { \
164 if (!(*di->msg_level & 1)) \
165 ; \
166 else \
167 printk args; \
168 } while (0)
169#define DMA_TRACE(args) \
170 do { \
171 if (!(*di->msg_level & 2)) \
172 ; \
173 else \
174 printk args; \
175 } while (0)
176#else
177#define DMA_ERROR(args)
178#define DMA_TRACE(args)
179#endif /* BCMDBG */
180
181#define DMA_NONE(args)
182
183typedef unsigned long dmaaddr_t;
184#define PHYSADDRHI(_pa) (0)
185#define PHYSADDRHISET(_pa, _val)
186#define PHYSADDRLO(_pa) ((_pa))
187#define PHYSADDRLOSET(_pa, _val) \
188 do { \
189 (_pa) = (_val); \
190 } while (0)
191
192#define d64txregs dregs.d64_u.txregs_64
193#define d64rxregs dregs.d64_u.rxregs_64
194#define txd64 dregs.d64_u.txd_64
195#define rxd64 dregs.d64_u.rxd_64
196
197/* default dma message level (if input msg_level pointer is null in dma_attach()) */
198static uint dma_msg_level;
199
200#define MAXNAMEL 8 /* 8 char names */
201
202#define DI_INFO(dmah) ((dma_info_t *)dmah)
203
204#define R_SM(r) (*(r))
205#define W_SM(r, v) (*(r) = (v))
206
207/* One physical DMA segment */
208struct dma_seg {
209 dmaaddr_t addr;
210 u32 length;
211};
212
213struct dma_seg_map {
214 void *oshdmah; /* Opaque handle for OSL to store its information */
215 uint origsize; /* Size of the virtual packet */
216 uint nsegs;
217 struct dma_seg segs[MAX_DMA_SEGS];
218};
219
220/*
221 * DMA Descriptor
222 * Descriptors are only read by the hardware, never written back.
223 */
224struct dma64desc {
225 u32 ctrl1; /* misc control bits & bufcount */
226 u32 ctrl2; /* buffer count and address extension */
227 u32 addrlow; /* memory address of the date buffer, bits 31:0 */
228 u32 addrhigh; /* memory address of the date buffer, bits 63:32 */
229};
230
231/* dma engine software state */
232struct dma_info {
233 struct dma_pub dma; /* exported structure */
234 uint *msg_level; /* message level pointer */
235 char name[MAXNAMEL]; /* callers name for diag msgs */
236
237 void *pbus; /* bus handle */
238
239 bool dma64; /* this dma engine is operating in 64-bit mode */
240 bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
241
242 union {
243 struct {
244 dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */
245 dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */
246 /* pointer to dma64 tx descriptor ring */
247 struct dma64desc *txd_64;
248 /* pointer to dma64 rx descriptor ring */
249 struct dma64desc *rxd_64;
250 } d64_u;
251 } dregs;
252
253 u16 dmadesc_align; /* alignment requirement for dma descriptors */
254
255 u16 ntxd; /* # tx descriptors tunable */
256 u16 txin; /* index of next descriptor to reclaim */
257 u16 txout; /* index of next descriptor to post */
258 void **txp; /* pointer to parallel array of pointers to packets */
259 struct dma_seg_map *txp_dmah; /* DMA MAP meta-data handle */
260 dmaaddr_t txdpa; /* Aligned physical address of descriptor ring */
261 dmaaddr_t txdpaorig; /* Original physical address of descriptor ring */
262 u16 txdalign; /* #bytes added to alloc'd mem to align txd */
263 u32 txdalloc; /* #bytes allocated for the ring */
264 u32 xmtptrbase; /* When using unaligned descriptors, the ptr register
265 * is not just an index, it needs all 13 bits to be
266 * an offset from the addr register.
267 */
268
269 u16 nrxd; /* # rx descriptors tunable */
270 u16 rxin; /* index of next descriptor to reclaim */
271 u16 rxout; /* index of next descriptor to post */
272 void **rxp; /* pointer to parallel array of pointers to packets */
273 struct dma_seg_map *rxp_dmah; /* DMA MAP meta-data handle */
274 dmaaddr_t rxdpa; /* Aligned physical address of descriptor ring */
275 dmaaddr_t rxdpaorig; /* Original physical address of descriptor ring */
276 u16 rxdalign; /* #bytes added to alloc'd mem to align rxd */
277 u32 rxdalloc; /* #bytes allocated for the ring */
278 u32 rcvptrbase; /* Base for ptr reg when using unaligned descriptors */
279
280 /* tunables */
281 unsigned int rxbufsize; /* rx buffer size in bytes,
282 * not including the extra headroom
283 */
284 uint rxextrahdrroom; /* extra rx headroom, reverseved to assist upper stack
285 * e.g. some rx pkt buffers will be bridged to tx side
286 * without byte copying. The extra headroom needs to be
287 * large enough to fit txheader needs.
288 * Some dongle driver may not need it.
289 */
290 uint nrxpost; /* # rx buffers to keep posted */
291 unsigned int rxoffset; /* rxcontrol offset */
292 uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
293 uint ddoffsethigh; /* high 32 bits */
294 uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
295 uint dataoffsethigh; /* high 32 bits */
296 bool aligndesc_4k; /* descriptor base need to be aligned or not */
297};
298
299/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */
300#ifdef BCMDMASGLISTOSL
301#define DMASGLIST_ENAB true
302#else
303#define DMASGLIST_ENAB false
304#endif /* BCMDMASGLISTOSL */
305
306/* descriptor bumping macros */
307#define XXD(x, n) ((x) & ((n) - 1)) /* faster than %, but n must be power of 2 */
308#define TXD(x) XXD((x), di->ntxd)
309#define RXD(x) XXD((x), di->nrxd)
310#define NEXTTXD(i) TXD((i) + 1)
311#define PREVTXD(i) TXD((i) - 1)
312#define NEXTRXD(i) RXD((i) + 1)
313#define PREVRXD(i) RXD((i) - 1)
314
315#define NTXDACTIVE(h, t) TXD((t) - (h))
316#define NRXDACTIVE(h, t) RXD((t) - (h))
317
318/* macros to convert between byte offsets and indexes */
319#define B2I(bytes, type) ((bytes) / sizeof(type))
320#define I2B(index, type) ((index) * sizeof(type))
321
322#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
323#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */
324
325#define PCI64ADDR_HIGH 0x80000000 /* address[63] */
326#define PCI64ADDR_HIGH_SHIFT 31 /* address[63] */
327
328/* Common prototypes */
329static bool _dma_isaddrext(struct dma_info *di);
330static bool _dma_descriptor_align(struct dma_info *di);
331static bool _dma_alloc(struct dma_info *di, uint direction);
332static void _dma_detach(struct dma_info *di);
333static void _dma_ddtable_init(struct dma_info *di, uint direction,
334 dmaaddr_t pa);
335static void _dma_rxinit(struct dma_info *di);
336static void *_dma_rx(struct dma_info *di);
337static bool _dma_rxfill(struct dma_info *di);
338static void _dma_rxreclaim(struct dma_info *di);
339static void _dma_rxenable(struct dma_info *di);
340static void *_dma_getnextrxp(struct dma_info *di, bool forceall);
341static void _dma_rx_param_get(struct dma_info *di, u16 *rxoffset,
342 u16 *rxbufsize);
343
344static void _dma_txblock(struct dma_info *di);
345static void _dma_txunblock(struct dma_info *di);
346static uint _dma_txactive(struct dma_info *di);
347static uint _dma_rxactive(struct dma_info *di);
348static uint _dma_txpending(struct dma_info *di);
349static uint _dma_txcommitted(struct dma_info *di);
350
351static void *_dma_peeknexttxp(struct dma_info *di);
352static void *_dma_peeknextrxp(struct dma_info *di);
353static unsigned long _dma_getvar(struct dma_info *di, const char *name);
354static void _dma_counterreset(struct dma_info *di);
355static void _dma_fifoloopbackenable(struct dma_info *di);
356static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags);
357static u8 dma_align_sizetobits(uint size);
358static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
359 u16 *alignbits, uint *alloced,
360 dmaaddr_t *descpa);
361
362/* Prototypes for 64-bit routines */
363static bool dma64_alloc(struct dma_info *di, uint direction);
364static bool dma64_txreset(struct dma_info *di);
365static bool dma64_rxreset(struct dma_info *di);
366static bool dma64_txsuspendedidle(struct dma_info *di);
367static int dma64_txfast(struct dma_info *di, struct sk_buff *p0, bool commit);
368static int dma64_txunframed(struct dma_info *di, void *p0, uint len,
369 bool commit);
370static void *dma64_getpos(struct dma_info *di, bool direction);
371static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range);
372static void *dma64_getnextrxp(struct dma_info *di, bool forceall);
373static void dma64_txrotate(struct dma_info *di);
374
375static bool dma64_rxidle(struct dma_info *di);
376static void dma64_txinit(struct dma_info *di);
377static bool dma64_txenabled(struct dma_info *di);
378static void dma64_txsuspend(struct dma_info *di);
379static void dma64_txresume(struct dma_info *di);
380static bool dma64_txsuspended(struct dma_info *di);
381static void dma64_txreclaim(struct dma_info *di, enum txd_range range);
382static bool dma64_txstopped(struct dma_info *di);
383static bool dma64_rxstopped(struct dma_info *di);
384static bool dma64_rxenabled(struct dma_info *di);
385static bool _dma64_addrext(dma64regs_t *dma64regs);
386
387static inline u32 parity32(u32 data);
388
389const struct di_fcn_s dma64proc = {
390 (di_detach_t) _dma_detach,
391 (di_txinit_t) dma64_txinit,
392 (di_txreset_t) dma64_txreset,
393 (di_txenabled_t) dma64_txenabled,
394 (di_txsuspend_t) dma64_txsuspend,
395 (di_txresume_t) dma64_txresume,
396 (di_txsuspended_t) dma64_txsuspended,
397 (di_txsuspendedidle_t) dma64_txsuspendedidle,
398 (di_txfast_t) dma64_txfast,
399 (di_txunframed_t) dma64_txunframed,
400 (di_getpos_t) dma64_getpos,
401 (di_txstopped_t) dma64_txstopped,
402 (di_txreclaim_t) dma64_txreclaim,
403 (di_getnexttxp_t) dma64_getnexttxp,
404 (di_peeknexttxp_t) _dma_peeknexttxp,
405 (di_txblock_t) _dma_txblock,
406 (di_txunblock_t) _dma_txunblock,
407 (di_txactive_t) _dma_txactive,
408 (di_txrotate_t) dma64_txrotate,
409
410 (di_rxinit_t) _dma_rxinit,
411 (di_rxreset_t) dma64_rxreset,
412 (di_rxidle_t) dma64_rxidle,
413 (di_rxstopped_t) dma64_rxstopped,
414 (di_rxenable_t) _dma_rxenable,
415 (di_rxenabled_t) dma64_rxenabled,
416 (di_rx_t) _dma_rx,
417 (di_rxfill_t) _dma_rxfill,
418 (di_rxreclaim_t) _dma_rxreclaim,
419 (di_getnextrxp_t) _dma_getnextrxp,
420 (di_peeknextrxp_t) _dma_peeknextrxp,
421 (di_rxparam_get_t) _dma_rx_param_get,
422
423 (di_fifoloopbackenable_t) _dma_fifoloopbackenable,
424 (di_getvar_t) _dma_getvar,
425 (di_counterreset_t) _dma_counterreset,
426 (di_ctrlflags_t) _dma_ctrlflags,
427 NULL,
428 NULL,
429 NULL,
430 (di_rxactive_t) _dma_rxactive,
431 (di_txpending_t) _dma_txpending,
432 (di_txcommitted_t) _dma_txcommitted,
433 39
434};
435
436struct dma_pub *dma_attach(char *name, struct si_pub *sih,
437 void *dmaregstx, void *dmaregsrx, uint ntxd,
438 uint nrxd, uint rxbufsize, int rxextheadroom,
439 uint nrxpost, uint rxoffset, uint *msg_level)
440{
441 struct dma_info *di;
442 uint size;
443
444 /* allocate private info structure */
445 di = kzalloc(sizeof(struct dma_info), GFP_ATOMIC);
446 if (di == NULL) {
447#ifdef BCMDBG
448 printk(KERN_ERR "dma_attach: out of memory\n");
449#endif
450 return NULL;
451 }
452
453 di->msg_level = msg_level ? msg_level : &dma_msg_level;
454
455
456 di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
457
458 /* init dma reg pointer */
459 di->d64txregs = (dma64regs_t *) dmaregstx;
460 di->d64rxregs = (dma64regs_t *) dmaregsrx;
461 di->dma.di_fn = (const struct di_fcn_s *)&dma64proc;
462
463 /* Default flags (which can be changed by the driver calling dma_ctrlflags
464 * before enable): For backwards compatibility both Rx Overflow Continue
465 * and Parity are DISABLED.
466 * supports it.
467 */
468 di->dma.di_fn->ctrlflags(&di->dma, DMA_CTRL_ROC | DMA_CTRL_PEN,
469 0);
470
471 DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d "
472 "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
473 "dmaregstx %p dmaregsrx %p\n", name, "DMA64",
474 di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
475 rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
476
477 /* make a private copy of our callers name */
478 strncpy(di->name, name, MAXNAMEL);
479 di->name[MAXNAMEL - 1] = '\0';
480
481 di->pbus = ((struct si_info *)sih)->pbus;
482
483 /* save tunables */
484 di->ntxd = (u16) ntxd;
485 di->nrxd = (u16) nrxd;
486
487 /* the actual dma size doesn't include the extra headroom */
488 di->rxextrahdrroom =
489 (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
490 if (rxbufsize > BCMEXTRAHDROOM)
491 di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
492 else
493 di->rxbufsize = (u16) rxbufsize;
494
495 di->nrxpost = (u16) nrxpost;
496 di->rxoffset = (u8) rxoffset;
497
498 /*
499 * figure out the DMA physical address offset for dd and data
500 * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
501 * Other bus: use zero
502 * SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
503 */
504 di->ddoffsetlow = 0;
505 di->dataoffsetlow = 0;
506 /* for pci bus, add offset */
507 if (sih->bustype == PCI_BUS) {
508 /* pcie with DMA64 */
509 di->ddoffsetlow = 0;
510 di->ddoffsethigh = SI_PCIE_DMA_H32;
511 di->dataoffsetlow = di->ddoffsetlow;
512 di->dataoffsethigh = di->ddoffsethigh;
513 }
514#if defined(__mips__) && defined(IL_BIGENDIAN)
515 di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED;
516#endif /* defined(__mips__) && defined(IL_BIGENDIAN) */
517 /* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
518 if ((ai_coreid(sih) == SDIOD_CORE_ID)
519 && ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2)))
520 di->addrext = 0;
521 else if ((ai_coreid(sih) == I2S_CORE_ID) &&
522 ((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1)))
523 di->addrext = 0;
524 else
525 di->addrext = _dma_isaddrext(di);
526
527 /* does the descriptors need to be aligned and if yes, on 4K/8K or not */
528 di->aligndesc_4k = _dma_descriptor_align(di);
529 if (di->aligndesc_4k) {
530 di->dmadesc_align = D64RINGALIGN_BITS;
531 if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
532 /* for smaller dd table, HW relax alignment reqmnt */
533 di->dmadesc_align = D64RINGALIGN_BITS - 1;
534 }
535 } else
536 di->dmadesc_align = 4; /* 16 byte alignment */
537
538 DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
539 di->aligndesc_4k, di->dmadesc_align));
540
541 /* allocate tx packet pointer vector */
542 if (ntxd) {
543 size = ntxd * sizeof(void *);
544 di->txp = kzalloc(size, GFP_ATOMIC);
545 if (di->txp == NULL) {
546 DMA_ERROR(("%s: dma_attach: out of tx memory\n", di->name));
547 goto fail;
548 }
549 }
550
551 /* allocate rx packet pointer vector */
552 if (nrxd) {
553 size = nrxd * sizeof(void *);
554 di->rxp = kzalloc(size, GFP_ATOMIC);
555 if (di->rxp == NULL) {
556 DMA_ERROR(("%s: dma_attach: out of rx memory\n", di->name));
557 goto fail;
558 }
559 }
560
561 /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
562 if (ntxd) {
563 if (!_dma_alloc(di, DMA_TX))
564 goto fail;
565 }
566
567 /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
568 if (nrxd) {
569 if (!_dma_alloc(di, DMA_RX))
570 goto fail;
571 }
572
573 if ((di->ddoffsetlow != 0) && !di->addrext) {
574 if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) {
575 DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->txdpa)));
576 goto fail;
577 }
578 if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) {
579 DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->rxdpa)));
580 goto fail;
581 }
582 }
583
584 DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
585
586 /* allocate DMA mapping vectors */
587 if (DMASGLIST_ENAB) {
588 if (ntxd) {
589 size = ntxd * sizeof(struct dma_seg_map);
590 di->txp_dmah = kzalloc(size, GFP_ATOMIC);
591 if (di->txp_dmah == NULL)
592 goto fail;
593 }
594
595 if (nrxd) {
596 size = nrxd * sizeof(struct dma_seg_map);
597 di->rxp_dmah = kzalloc(size, GFP_ATOMIC);
598 if (di->rxp_dmah == NULL)
599 goto fail;
600 }
601 }
602
603 return (struct dma_pub *) di;
604
605 fail:
606 _dma_detach(di);
607 return NULL;
608}
609
610/* Check for odd number of 1's */
611static inline u32 parity32(u32 data)
612{
613 data ^= data >> 16;
614 data ^= data >> 8;
615 data ^= data >> 4;
616 data ^= data >> 2;
617 data ^= data >> 1;
618
619 return data & 1;
620}
621
622#define DMA64_DD_PARITY(dd) parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2)
623
624static inline void
625dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring,
626 dmaaddr_t pa, uint outidx, u32 *flags, u32 bufcount)
627{
628 u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
629
630 /* PCI bus with big(>1G) physical address, use address extension */
631#if defined(__mips__) && defined(IL_BIGENDIAN)
632 if ((di->dataoffsetlow == SI_SDRAM_SWAPPED)
633 || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
634#else
635 if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
636#endif /* defined(__mips__) && defined(IL_BIGENDIAN) */
637
638 W_SM(&ddring[outidx].addrlow,
639 BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
640 W_SM(&ddring[outidx].addrhigh,
641 BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh));
642 W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
643 W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
644 } else {
645 /* address extension for 32-bit PCI */
646 u32 ae;
647
648 ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
649 PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
650
651 ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
652 W_SM(&ddring[outidx].addrlow,
653 BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
654 W_SM(&ddring[outidx].addrhigh,
655 BUS_SWAP32(0 + di->dataoffsethigh));
656 W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
657 W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
658 }
659 if (di->dma.dmactrlflags & DMA_CTRL_PEN) {
660 if (DMA64_DD_PARITY(&ddring[outidx])) {
661 W_SM(&ddring[outidx].ctrl2,
662 BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY));
663 }
664 }
665}
666
667static bool _dma_alloc(struct dma_info *di, uint direction)
668{
669 return dma64_alloc(di, direction);
670}
671
672void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits,
673 uint *alloced, unsigned long *pap)
674{
675 if (align_bits) {
676 u16 align = (1 << align_bits);
677 if (!IS_ALIGNED(PAGE_SIZE, align))
678 size += align;
679 *alloced = size;
680 }
681 return pci_alloc_consistent(pdev, size, (dma_addr_t *) pap);
682}
683
684/* !! may be called with core in reset */
685static void _dma_detach(struct dma_info *di)
686{
687
688 DMA_TRACE(("%s: dma_detach\n", di->name));
689
690 /* free dma descriptor rings */
691 if (di->txd64)
692 pci_free_consistent(di->pbus, di->txdalloc,
693 ((s8 *)di->txd64 - di->txdalign),
694 (di->txdpaorig));
695 if (di->rxd64)
696 pci_free_consistent(di->pbus, di->rxdalloc,
697 ((s8 *)di->rxd64 - di->rxdalign),
698 (di->rxdpaorig));
699
700 /* free packet pointer vectors */
701 kfree(di->txp);
702 kfree(di->rxp);
703
704 /* free tx packet DMA handles */
705 kfree(di->txp_dmah);
706
707 /* free rx packet DMA handles */
708 kfree(di->rxp_dmah);
709
710 /* free our private info structure */
711 kfree(di);
712
713}
714
715static bool _dma_descriptor_align(struct dma_info *di)
716{
717 u32 addrl;
718
719 /* Check to see if the descriptors need to be aligned on 4K/8K or not */
720 if (di->d64txregs != NULL) {
721 W_REG(&di->d64txregs->addrlow, 0xff0);
722 addrl = R_REG(&di->d64txregs->addrlow);
723 if (addrl != 0)
724 return false;
725 } else if (di->d64rxregs != NULL) {
726 W_REG(&di->d64rxregs->addrlow, 0xff0);
727 addrl = R_REG(&di->d64rxregs->addrlow);
728 if (addrl != 0)
729 return false;
730 }
731 return true;
732}
733
734/* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */
735static bool _dma_isaddrext(struct dma_info *di)
736{
737 /* DMA64 supports full 32- or 64-bit operation. AE is always valid */
738
739 /* not all tx or rx channel are available */
740 if (di->d64txregs != NULL) {
741 if (!_dma64_addrext(di->d64txregs)) {
742 DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have "
743 "AE set\n", di->name));
744 }
745 return true;
746 } else if (di->d64rxregs != NULL) {
747 if (!_dma64_addrext(di->d64rxregs)) {
748 DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have "
749 "AE set\n", di->name));
750 }
751 return true;
752 }
753 return false;
754}
755
756/* initialize descriptor table base address */
757static void _dma_ddtable_init(struct dma_info *di, uint direction, dmaaddr_t pa)
758{
759 if (!di->aligndesc_4k) {
760 if (direction == DMA_TX)
761 di->xmtptrbase = PHYSADDRLO(pa);
762 else
763 di->rcvptrbase = PHYSADDRLO(pa);
764 }
765
766 if ((di->ddoffsetlow == 0)
767 || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
768 if (direction == DMA_TX) {
769 W_REG(&di->d64txregs->addrlow,
770 (PHYSADDRLO(pa) + di->ddoffsetlow));
771 W_REG(&di->d64txregs->addrhigh,
772 (PHYSADDRHI(pa) + di->ddoffsethigh));
773 } else {
774 W_REG(&di->d64rxregs->addrlow,
775 (PHYSADDRLO(pa) + di->ddoffsetlow));
776 W_REG(&di->d64rxregs->addrhigh,
777 (PHYSADDRHI(pa) + di->ddoffsethigh));
778 }
779 } else {
780 /* DMA64 32bits address extension */
781 u32 ae;
782
783 /* shift the high bit(s) from pa to ae */
784 ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
785 PCI32ADDR_HIGH_SHIFT;
786 PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
787
788 if (direction == DMA_TX) {
789 W_REG(&di->d64txregs->addrlow,
790 (PHYSADDRLO(pa) + di->ddoffsetlow));
791 W_REG(&di->d64txregs->addrhigh,
792 di->ddoffsethigh);
793 SET_REG(&di->d64txregs->control,
794 D64_XC_AE, (ae << D64_XC_AE_SHIFT));
795 } else {
796 W_REG(&di->d64rxregs->addrlow,
797 (PHYSADDRLO(pa) + di->ddoffsetlow));
798 W_REG(&di->d64rxregs->addrhigh,
799 di->ddoffsethigh);
800 SET_REG(&di->d64rxregs->control,
801 D64_RC_AE, (ae << D64_RC_AE_SHIFT));
802 }
803 }
804}
805
806static void _dma_fifoloopbackenable(struct dma_info *di)
807{
808 DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
809
810 OR_REG(&di->d64txregs->control, D64_XC_LE);
811}
812
813static void _dma_rxinit(struct dma_info *di)
814{
815 DMA_TRACE(("%s: dma_rxinit\n", di->name));
816
817 if (di->nrxd == 0)
818 return;
819
820 di->rxin = di->rxout = 0;
821
822 /* clear rx descriptor ring */
823 memset((void *)di->rxd64, '\0',
824 (di->nrxd * sizeof(struct dma64desc)));
825
826 /* DMA engine with out alignment requirement requires table to be inited
827 * before enabling the engine
828 */
829 if (!di->aligndesc_4k)
830 _dma_ddtable_init(di, DMA_RX, di->rxdpa);
831
832 _dma_rxenable(di);
833
834 if (di->aligndesc_4k)
835 _dma_ddtable_init(di, DMA_RX, di->rxdpa);
836}
837
838static void _dma_rxenable(struct dma_info *di)
839{
840 uint dmactrlflags = di->dma.dmactrlflags;
841 u32 control;
842
843 DMA_TRACE(("%s: dma_rxenable\n", di->name));
844
845 control =
846 (R_REG(&di->d64rxregs->control) & D64_RC_AE) |
847 D64_RC_RE;
848
849 if ((dmactrlflags & DMA_CTRL_PEN) == 0)
850 control |= D64_RC_PD;
851
852 if (dmactrlflags & DMA_CTRL_ROC)
853 control |= D64_RC_OC;
854
855 W_REG(&di->d64rxregs->control,
856 ((di->rxoffset << D64_RC_RO_SHIFT) | control));
857}
858
859static void
860_dma_rx_param_get(struct dma_info *di, u16 *rxoffset, u16 *rxbufsize)
861{
862 /* the normal values fit into 16 bits */
863 *rxoffset = (u16) di->rxoffset;
864 *rxbufsize = (u16) di->rxbufsize;
865}
866
867/* !! rx entry routine
868 * returns a pointer to the next frame received, or NULL if there are no more
869 * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported
870 * with pkts chain
871 * otherwise, it's treated as giant pkt and will be tossed.
872 * The DMA scattering starts with normal DMA header, followed by first buffer data.
873 * After it reaches the max size of buffer, the data continues in next DMA descriptor
874 * buffer WITHOUT DMA header
875 */
876static void *_dma_rx(struct dma_info *di)
877{
878 struct sk_buff *p, *head, *tail;
879 uint len;
880 uint pkt_len;
881 int resid = 0;
882
883 next_frame:
884 head = _dma_getnextrxp(di, false);
885 if (head == NULL)
886 return NULL;
887
888 len = le16_to_cpu(*(u16 *) (head->data));
889 DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
890 dma_spin_for_len(len, head);
891
892 /* set actual length */
893 pkt_len = min((di->rxoffset + len), di->rxbufsize);
894 __skb_trim(head, pkt_len);
895 resid = len - (di->rxbufsize - di->rxoffset);
896
897 /* check for single or multi-buffer rx */
898 if (resid > 0) {
899 tail = head;
900 while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
901 tail->next = p;
902 pkt_len = min(resid, (int)di->rxbufsize);
903 __skb_trim(p, pkt_len);
904
905 tail = p;
906 resid -= di->rxbufsize;
907 }
908
909#ifdef BCMDBG
910 if (resid > 0) {
911 uint cur;
912 cur =
913 B2I(((R_REG(&di->d64rxregs->status0) &
914 D64_RS0_CD_MASK) -
915 di->rcvptrbase) & D64_RS0_CD_MASK,
916 struct dma64desc);
917 DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n",
918 di->rxin, di->rxout, cur));
919 }
920#endif /* BCMDBG */
921
922 if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
923 DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
924 di->name, len));
925 brcmu_pkt_buf_free_skb(head);
926 di->dma.rxgiants++;
927 goto next_frame;
928 }
929 }
930
931 return head;
932}
933
934/* post receive buffers
935 * return false is refill failed completely and ring is empty
936 * this will stall the rx dma and user might want to call rxfill again asap
937 * This unlikely happens on memory-rich NIC, but often on memory-constrained dongle
938 */
939static bool _dma_rxfill(struct dma_info *di)
940{
941 struct sk_buff *p;
942 u16 rxin, rxout;
943 u32 flags = 0;
944 uint n;
945 uint i;
946 dmaaddr_t pa;
947 uint extra_offset = 0;
948 bool ring_empty;
949
950 ring_empty = false;
951
952 /*
953 * Determine how many receive buffers we're lacking
954 * from the full complement, allocate, initialize,
955 * and post them, then update the chip rx lastdscr.
956 */
957
958 rxin = di->rxin;
959 rxout = di->rxout;
960
961 n = di->nrxpost - NRXDACTIVE(rxin, rxout);
962
963 DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
964
965 if (di->rxbufsize > BCMEXTRAHDROOM)
966 extra_offset = di->rxextrahdrroom;
967
968 for (i = 0; i < n; i++) {
969 /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
970 size to be allocated
971 */
972
973 p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset);
974
975 if (p == NULL) {
976 DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
977 di->name));
978 if (i == 0 && dma64_rxidle(di)) {
979 DMA_ERROR(("%s: rxfill64: ring is empty !\n",
980 di->name));
981 ring_empty = true;
982 }
983 di->dma.rxnobuf++;
984 break;
985 }
986 /* reserve an extra headroom, if applicable */
987 if (extra_offset)
988 skb_pull(p, extra_offset);
989
990 /* Do a cached write instead of uncached write since DMA_MAP
991 * will flush the cache.
992 */
993 *(u32 *) (p->data) = 0;
994
995 if (DMASGLIST_ENAB)
996 memset(&di->rxp_dmah[rxout], 0,
997 sizeof(struct dma_seg_map));
998
999 pa = pci_map_single(di->pbus, p->data,
1000 di->rxbufsize, PCI_DMA_FROMDEVICE);
1001
1002 /* save the free packet pointer */
1003 di->rxp[rxout] = p;
1004
1005 /* reset flags for each descriptor */
1006 flags = 0;
1007 if (rxout == (di->nrxd - 1))
1008 flags = D64_CTRL1_EOT;
1009
1010 dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
1011 di->rxbufsize);
1012 rxout = NEXTRXD(rxout);
1013 }
1014
1015 di->rxout = rxout;
1016
1017 /* update the chip lastdscr pointer */
1018 W_REG(&di->d64rxregs->ptr,
1019 di->rcvptrbase + I2B(rxout, struct dma64desc));
1020
1021 return ring_empty;
1022}
1023
1024/* like getnexttxp but no reclaim */
1025static void *_dma_peeknexttxp(struct dma_info *di)
1026{
1027 uint end, i;
1028
1029 if (di->ntxd == 0)
1030 return NULL;
1031
1032 end =
1033 B2I(((R_REG(&di->d64txregs->status0) &
1034 D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
1035 struct dma64desc);
1036
1037 for (i = di->txin; i != end; i = NEXTTXD(i))
1038 if (di->txp[i])
1039 return di->txp[i];
1040
1041 return NULL;
1042}
1043
1044/* like getnextrxp but not take off the ring */
1045static void *_dma_peeknextrxp(struct dma_info *di)
1046{
1047 uint end, i;
1048
1049 if (di->nrxd == 0)
1050 return NULL;
1051
1052 end =
1053 B2I(((R_REG(&di->d64rxregs->status0) &
1054 D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK,
1055 struct dma64desc);
1056
1057 for (i = di->rxin; i != end; i = NEXTRXD(i))
1058 if (di->rxp[i])
1059 return di->rxp[i];
1060
1061 return NULL;
1062}
1063
1064static void _dma_rxreclaim(struct dma_info *di)
1065{
1066 void *p;
1067
1068 DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
1069
1070 while ((p = _dma_getnextrxp(di, true)))
1071 brcmu_pkt_buf_free_skb(p);
1072}
1073
1074static void *_dma_getnextrxp(struct dma_info *di, bool forceall)
1075{
1076 if (di->nrxd == 0)
1077 return NULL;
1078
1079 return dma64_getnextrxp(di, forceall);
1080}
1081
1082static void _dma_txblock(struct dma_info *di)
1083{
1084 di->dma.txavail = 0;
1085}
1086
1087static void _dma_txunblock(struct dma_info *di)
1088{
1089 di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1090}
1091
1092static uint _dma_txactive(struct dma_info *di)
1093{
1094 return NTXDACTIVE(di->txin, di->txout);
1095}
1096
1097static uint _dma_txpending(struct dma_info *di)
1098{
1099 uint curr;
1100
1101 curr =
1102 B2I(((R_REG(&di->d64txregs->status0) &
1103 D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
1104 struct dma64desc);
1105
1106 return NTXDACTIVE(curr, di->txout);
1107}
1108
1109static uint _dma_txcommitted(struct dma_info *di)
1110{
1111 uint ptr;
1112 uint txin = di->txin;
1113
1114 if (txin == di->txout)
1115 return 0;
1116
1117 ptr = B2I(R_REG(&di->d64txregs->ptr), struct dma64desc);
1118
1119 return NTXDACTIVE(di->txin, ptr);
1120}
1121
1122static uint _dma_rxactive(struct dma_info *di)
1123{
1124 return NRXDACTIVE(di->rxin, di->rxout);
1125}
1126
1127static void _dma_counterreset(struct dma_info *di)
1128{
1129 /* reset all software counter */
1130 di->dma.rxgiants = 0;
1131 di->dma.rxnobuf = 0;
1132 di->dma.txnobuf = 0;
1133}
1134
1135static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
1136{
1137 uint dmactrlflags = di->dma.dmactrlflags;
1138
1139 if (di == NULL) {
1140 DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
1141 return 0;
1142 }
1143
1144 dmactrlflags &= ~mask;
1145 dmactrlflags |= flags;
1146
1147 /* If trying to enable parity, check if parity is actually supported */
1148 if (dmactrlflags & DMA_CTRL_PEN) {
1149 u32 control;
1150
1151 control = R_REG(&di->d64txregs->control);
1152 W_REG(&di->d64txregs->control,
1153 control | D64_XC_PD);
1154 if (R_REG(&di->d64txregs->control) & D64_XC_PD) {
1155 /* We *can* disable it so it is supported,
1156 * restore control register
1157 */
1158 W_REG(&di->d64txregs->control,
1159 control);
1160 } else {
1161 /* Not supported, don't allow it to be enabled */
1162 dmactrlflags &= ~DMA_CTRL_PEN;
1163 }
1164 }
1165
1166 di->dma.dmactrlflags = dmactrlflags;
1167
1168 return dmactrlflags;
1169}
1170
1171/* get the address of the var in order to change later */
1172static unsigned long _dma_getvar(struct dma_info *di, const char *name)
1173{
1174 if (!strcmp(name, "&txavail"))
1175 return (unsigned long)&(di->dma.txavail);
1176 return 0;
1177}
1178
1179static
1180u8 dma_align_sizetobits(uint size)
1181{
1182 u8 bitpos = 0;
1183 while (size >>= 1) {
1184 bitpos++;
1185 }
1186 return bitpos;
1187}
1188
1189/* This function ensures that the DMA descriptor ring will not get allocated
1190 * across Page boundary. If the allocation is done across the page boundary
1191 * at the first time, then it is freed and the allocation is done at
1192 * descriptor ring size aligned location. This will ensure that the ring will
1193 * not cross page boundary
1194 */
1195static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
1196 u16 *alignbits, uint *alloced,
1197 dmaaddr_t *descpa)
1198{
1199 void *va;
1200 u32 desc_strtaddr;
1201 u32 alignbytes = 1 << *alignbits;
1202
1203 va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa);
1204
1205 if (NULL == va)
1206 return NULL;
1207
1208 desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
1209 if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
1210 & boundary)) {
1211 *alignbits = dma_align_sizetobits(size);
1212 pci_free_consistent(di->pbus, size, va, *descpa);
1213 va = dma_alloc_consistent(di->pbus, size, *alignbits,
1214 alloced, descpa);
1215 }
1216 return va;
1217}
1218
1219/* 64-bit DMA functions */
1220
1221static void dma64_txinit(struct dma_info *di)
1222{
1223 u32 control = D64_XC_XE;
1224
1225 DMA_TRACE(("%s: dma_txinit\n", di->name));
1226
1227 if (di->ntxd == 0)
1228 return;
1229
1230 di->txin = di->txout = 0;
1231 di->dma.txavail = di->ntxd - 1;
1232
1233 /* clear tx descriptor ring */
1234 memset((void *)di->txd64, '\0', (di->ntxd * sizeof(struct dma64desc)));
1235
1236 /* DMA engine with out alignment requirement requires table to be inited
1237 * before enabling the engine
1238 */
1239 if (!di->aligndesc_4k)
1240 _dma_ddtable_init(di, DMA_TX, di->txdpa);
1241
1242 if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0)
1243 control |= D64_XC_PD;
1244 OR_REG(&di->d64txregs->control, control);
1245
1246 /* DMA engine with alignment requirement requires table to be inited
1247 * before enabling the engine
1248 */
1249 if (di->aligndesc_4k)
1250 _dma_ddtable_init(di, DMA_TX, di->txdpa);
1251}
1252
1253static bool dma64_txenabled(struct dma_info *di)
1254{
1255 u32 xc;
1256
1257 /* If the chip is dead, it is not enabled :-) */
1258 xc = R_REG(&di->d64txregs->control);
1259 return (xc != 0xffffffff) && (xc & D64_XC_XE);
1260}
1261
1262static void dma64_txsuspend(struct dma_info *di)
1263{
1264 DMA_TRACE(("%s: dma_txsuspend\n", di->name));
1265
1266 if (di->ntxd == 0)
1267 return;
1268
1269 OR_REG(&di->d64txregs->control, D64_XC_SE);
1270}
1271
1272static void dma64_txresume(struct dma_info *di)
1273{
1274 DMA_TRACE(("%s: dma_txresume\n", di->name));
1275
1276 if (di->ntxd == 0)
1277 return;
1278
1279 AND_REG(&di->d64txregs->control, ~D64_XC_SE);
1280}
1281
1282static bool dma64_txsuspended(struct dma_info *di)
1283{
1284 return (di->ntxd == 0) ||
1285 ((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
1286 D64_XC_SE);
1287}
1288
1289static void dma64_txreclaim(struct dma_info *di, enum txd_range range)
1290{
1291 void *p;
1292
1293 DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
1294 (range == DMA_RANGE_ALL) ? "all" :
1295 ((range ==
1296 DMA_RANGE_TRANSMITTED) ? "transmitted" :
1297 "transferred")));
1298
1299 if (di->txin == di->txout)
1300 return;
1301
1302 while ((p = dma64_getnexttxp(di, range))) {
1303 /* For unframed data, we don't have any packets to free */
1304 if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED))
1305 brcmu_pkt_buf_free_skb(p);
1306 }
1307}
1308
1309static bool dma64_txstopped(struct dma_info *di)
1310{
1311 return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
1312 D64_XS0_XS_STOPPED);
1313}
1314
1315static bool dma64_rxstopped(struct dma_info *di)
1316{
1317 return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
1318 D64_RS0_RS_STOPPED);
1319}
1320
1321static bool dma64_alloc(struct dma_info *di, uint direction)
1322{
1323 u16 size;
1324 uint ddlen;
1325 void *va;
1326 uint alloced = 0;
1327 u16 align;
1328 u16 align_bits;
1329
1330 ddlen = sizeof(struct dma64desc);
1331
1332 size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
1333 align_bits = di->dmadesc_align;
1334 align = (1 << align_bits);
1335
1336 if (direction == DMA_TX) {
1337 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
1338 &alloced, &di->txdpaorig);
1339 if (va == NULL) {
1340 DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
1341 return false;
1342 }
1343 align = (1 << align_bits);
1344 di->txd64 = (struct dma64desc *)
1345 roundup((unsigned long)va, align);
1346 di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
1347 PHYSADDRLOSET(di->txdpa,
1348 PHYSADDRLO(di->txdpaorig) + di->txdalign);
1349 PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig));
1350 di->txdalloc = alloced;
1351 } else {
1352 va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
1353 &alloced, &di->rxdpaorig);
1354 if (va == NULL) {
1355 DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
1356 return false;
1357 }
1358 align = (1 << align_bits);
1359 di->rxd64 = (struct dma64desc *)
1360 roundup((unsigned long)va, align);
1361 di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
1362 PHYSADDRLOSET(di->rxdpa,
1363 PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
1364 PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig));
1365 di->rxdalloc = alloced;
1366 }
1367
1368 return true;
1369}
1370
1371static bool dma64_txreset(struct dma_info *di)
1372{
1373 u32 status;
1374
1375 if (di->ntxd == 0)
1376 return true;
1377
1378 /* suspend tx DMA first */
1379 W_REG(&di->d64txregs->control, D64_XC_SE);
1380 SPINWAIT(((status =
1381 (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
1382 != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
1383 && (status != D64_XS0_XS_STOPPED), 10000);
1384
1385 W_REG(&di->d64txregs->control, 0);
1386 SPINWAIT(((status =
1387 (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
1388 != D64_XS0_XS_DISABLED), 10000);
1389
1390 /* wait for the last transaction to complete */
1391 udelay(300);
1392
1393 return status == D64_XS0_XS_DISABLED;
1394}
1395
1396static bool dma64_rxidle(struct dma_info *di)
1397{
1398 DMA_TRACE(("%s: dma_rxidle\n", di->name));
1399
1400 if (di->nrxd == 0)
1401 return true;
1402
1403 return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
1404 (R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
1405}
1406
1407static bool dma64_rxreset(struct dma_info *di)
1408{
1409 u32 status;
1410
1411 if (di->nrxd == 0)
1412 return true;
1413
1414 W_REG(&di->d64rxregs->control, 0);
1415 SPINWAIT(((status =
1416 (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
1417 != D64_RS0_RS_DISABLED), 10000);
1418
1419 return status == D64_RS0_RS_DISABLED;
1420}
1421
1422static bool dma64_rxenabled(struct dma_info *di)
1423{
1424 u32 rc;
1425
1426 rc = R_REG(&di->d64rxregs->control);
1427 return (rc != 0xffffffff) && (rc & D64_RC_RE);
1428}
1429
1430static bool dma64_txsuspendedidle(struct dma_info *di)
1431{
1432
1433 if (di->ntxd == 0)
1434 return true;
1435
1436 if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
1437 return 0;
1438
1439 if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
1440 D64_XS0_XS_IDLE)
1441 return 1;
1442
1443 return 0;
1444}
1445
1446/* Useful when sending unframed data. This allows us to get a progress report from the DMA.
1447 * We return a pointer to the beginning of the DATA buffer of the current descriptor.
1448 * If DMA is idle, we return NULL.
1449 */
1450static void *dma64_getpos(struct dma_info *di, bool direction)
1451{
1452 void *va;
1453 bool idle;
1454 u32 cd_offset;
1455
1456 if (direction == DMA_TX) {
1457 cd_offset =
1458 R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK;
1459 idle = !NTXDACTIVE(di->txin, di->txout);
1460 va = di->txp[B2I(cd_offset, struct dma64desc)];
1461 } else {
1462 cd_offset =
1463 R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK;
1464 idle = !NRXDACTIVE(di->rxin, di->rxout);
1465 va = di->rxp[B2I(cd_offset, struct dma64desc)];
1466 }
1467
1468 /* If DMA is IDLE, return NULL */
1469 if (idle) {
1470 DMA_TRACE(("%s: DMA idle, return NULL\n", __func__));
1471 va = NULL;
1472 }
1473
1474 return va;
1475}
1476
1477/* TX of unframed data
1478 *
1479 * Adds a DMA ring descriptor for the data pointed to by "buf".
1480 * This is for DMA of a buffer of data and is unlike other dma TX functions
1481 * that take a pointer to a "packet"
1482 * Each call to this is results in a single descriptor being added for "len" bytes of
1483 * data starting at "buf", it doesn't handle chained buffers.
1484 */
1485static int
1486dma64_txunframed(struct dma_info *di, void *buf, uint len, bool commit)
1487{
1488 u16 txout;
1489 u32 flags = 0;
1490 dmaaddr_t pa; /* phys addr */
1491
1492 txout = di->txout;
1493
1494 /* return nonzero if out of tx descriptors */
1495 if (NEXTTXD(txout) == di->txin)
1496 goto outoftxd;
1497
1498 if (len == 0)
1499 return 0;
1500
1501 pa = pci_map_single(di->pbus, buf, len, PCI_DMA_TODEVICE);
1502
1503 flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF);
1504
1505 if (txout == (di->ntxd - 1))
1506 flags |= D64_CTRL1_EOT;
1507
1508 dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
1509
1510 /* save the buffer pointer - used by dma_getpos */
1511 di->txp[txout] = buf;
1512
1513 txout = NEXTTXD(txout);
1514 /* bump the tx descriptor index */
1515 di->txout = txout;
1516
1517 /* kick the chip */
1518 if (commit) {
1519 W_REG(&di->d64txregs->ptr,
1520 di->xmtptrbase + I2B(txout, struct dma64desc));
1521 }
1522
1523 /* tx flow control */
1524 di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1525
1526 return 0;
1527
1528 outoftxd:
1529 DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__));
1530 di->dma.txavail = 0;
1531 di->dma.txnobuf++;
1532 return -1;
1533}
1534
1535/* !! tx entry routine
1536 * WARNING: call must check the return value for error.
1537 * the error(toss frames) could be fatal and cause many subsequent hard to debug problems
1538 */
1539static int dma64_txfast(struct dma_info *di, struct sk_buff *p0,
1540 bool commit)
1541{
1542 struct sk_buff *p, *next;
1543 unsigned char *data;
1544 uint len;
1545 u16 txout;
1546 u32 flags = 0;
1547 dmaaddr_t pa;
1548
1549 DMA_TRACE(("%s: dma_txfast\n", di->name));
1550
1551 txout = di->txout;
1552
1553 /*
1554 * Walk the chain of packet buffers
1555 * allocating and initializing transmit descriptor entries.
1556 */
1557 for (p = p0; p; p = next) {
1558 uint nsegs, j;
1559 struct dma_seg_map *map;
1560
1561 data = p->data;
1562 len = p->len;
1563 next = p->next;
1564
1565 /* return nonzero if out of tx descriptors */
1566 if (NEXTTXD(txout) == di->txin)
1567 goto outoftxd;
1568
1569 if (len == 0)
1570 continue;
1571
1572 /* get physical address of buffer start */
1573 if (DMASGLIST_ENAB)
1574 memset(&di->txp_dmah[txout], 0,
1575 sizeof(struct dma_seg_map));
1576
1577 pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
1578
1579 if (DMASGLIST_ENAB) {
1580 map = &di->txp_dmah[txout];
1581
1582 /* See if all the segments can be accounted for */
1583 if (map->nsegs >
1584 (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
1585 1))
1586 goto outoftxd;
1587
1588 nsegs = map->nsegs;
1589 } else
1590 nsegs = 1;
1591
1592 for (j = 1; j <= nsegs; j++) {
1593 flags = 0;
1594 if (p == p0 && j == 1)
1595 flags |= D64_CTRL1_SOF;
1596
1597 /* With a DMA segment list, Descriptor table is filled
1598 * using the segment list instead of looping over
1599 * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
1600 * end of segment list is reached.
1601 */
1602 if ((!DMASGLIST_ENAB && next == NULL) ||
1603 (DMASGLIST_ENAB && j == nsegs))
1604 flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
1605 if (txout == (di->ntxd - 1))
1606 flags |= D64_CTRL1_EOT;
1607
1608 if (DMASGLIST_ENAB) {
1609 len = map->segs[j - 1].length;
1610 pa = map->segs[j - 1].addr;
1611 }
1612 dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
1613
1614 txout = NEXTTXD(txout);
1615 }
1616
1617 /* See above. No need to loop over individual buffers */
1618 if (DMASGLIST_ENAB)
1619 break;
1620 }
1621
1622 /* if last txd eof not set, fix it */
1623 if (!(flags & D64_CTRL1_EOF))
1624 W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
1625 BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
1626
1627 /* save the packet */
1628 di->txp[PREVTXD(txout)] = p0;
1629
1630 /* bump the tx descriptor index */
1631 di->txout = txout;
1632
1633 /* kick the chip */
1634 if (commit)
1635 W_REG(&di->d64txregs->ptr,
1636 di->xmtptrbase + I2B(txout, struct dma64desc));
1637
1638 /* tx flow control */
1639 di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1640
1641 return 0;
1642
1643 outoftxd:
1644 DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
1645 brcmu_pkt_buf_free_skb(p0);
1646 di->dma.txavail = 0;
1647 di->dma.txnobuf++;
1648 return -1;
1649}
1650
1651/*
1652 * Reclaim next completed txd (txds if using chained buffers) in the range
1653 * specified and return associated packet.
1654 * If range is DMA_RANGE_TRANSMITTED, reclaim descriptors that have be
1655 * transmitted as noted by the hardware "CurrDescr" pointer.
1656 * If range is DMA_RANGE_TRANSFERED, reclaim descriptors that have be
1657 * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
1658 * If range is DMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
1659 * return associated packet regardless of the value of hardware pointers.
1660 */
1661static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range)
1662{
1663 u16 start, end, i;
1664 u16 active_desc;
1665 void *txp;
1666
1667 DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
1668 (range == DMA_RANGE_ALL) ? "all" :
1669 ((range ==
1670 DMA_RANGE_TRANSMITTED) ? "transmitted" :
1671 "transferred")));
1672
1673 if (di->ntxd == 0)
1674 return NULL;
1675
1676 txp = NULL;
1677
1678 start = di->txin;
1679 if (range == DMA_RANGE_ALL)
1680 end = di->txout;
1681 else {
1682 dma64regs_t *dregs = di->d64txregs;
1683
1684 end = (u16) (B2I(((R_REG(&dregs->status0) &
1685 D64_XS0_CD_MASK) -
1686 di->xmtptrbase) & D64_XS0_CD_MASK,
1687 struct dma64desc));
1688
1689 if (range == DMA_RANGE_TRANSFERED) {
1690 active_desc =
1691 (u16) (R_REG(&dregs->status1) &
1692 D64_XS1_AD_MASK);
1693 active_desc =
1694 (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
1695 active_desc = B2I(active_desc, struct dma64desc);
1696 if (end != active_desc)
1697 end = PREVTXD(active_desc);
1698 }
1699 }
1700
1701 if ((start == 0) && (end > di->txout))
1702 goto bogus;
1703
1704 for (i = start; i != end && !txp; i = NEXTTXD(i)) {
1705 dmaaddr_t pa;
1706 struct dma_seg_map *map = NULL;
1707 uint size, j, nsegs;
1708
1709 PHYSADDRLOSET(pa,
1710 (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) -
1711 di->dataoffsetlow));
1712 PHYSADDRHISET(pa,
1713 (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) -
1714 di->dataoffsethigh));
1715
1716 if (DMASGLIST_ENAB) {
1717 map = &di->txp_dmah[i];
1718 size = map->origsize;
1719 nsegs = map->nsegs;
1720 } else {
1721 size =
1722 (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) &
1723 D64_CTRL2_BC_MASK);
1724 nsegs = 1;
1725 }
1726
1727 for (j = nsegs; j > 0; j--) {
1728 W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
1729 W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
1730
1731 txp = di->txp[i];
1732 di->txp[i] = NULL;
1733 if (j > 1)
1734 i = NEXTTXD(i);
1735 }
1736
1737 pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
1738 }
1739
1740 di->txin = i;
1741
1742 /* tx flow control */
1743 di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1744
1745 return txp;
1746
1747 bogus:
1748 DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
1749 return NULL;
1750}
1751
1752static void *dma64_getnextrxp(struct dma_info *di, bool forceall)
1753{
1754 uint i, curr;
1755 void *rxp;
1756 dmaaddr_t pa;
1757
1758 i = di->rxin;
1759
1760 /* return if no packets posted */
1761 if (i == di->rxout)
1762 return NULL;
1763
1764 curr =
1765 B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
1766 di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc);
1767
1768 /* ignore curr if forceall */
1769 if (!forceall && (i == curr))
1770 return NULL;
1771
1772 /* get the packet pointer that corresponds to the rx descriptor */
1773 rxp = di->rxp[i];
1774 di->rxp[i] = NULL;
1775
1776 PHYSADDRLOSET(pa,
1777 (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) -
1778 di->dataoffsetlow));
1779 PHYSADDRHISET(pa,
1780 (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) -
1781 di->dataoffsethigh));
1782
1783 /* clear this packet from the descriptor ring */
1784 pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE);
1785
1786 W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
1787 W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
1788
1789 di->rxin = NEXTRXD(i);
1790
1791 return rxp;
1792}
1793
1794static bool _dma64_addrext(dma64regs_t *dma64regs)
1795{
1796 u32 w;
1797 OR_REG(&dma64regs->control, D64_XC_AE);
1798 w = R_REG(&dma64regs->control);
1799 AND_REG(&dma64regs->control, ~D64_XC_AE);
1800 return (w & D64_XC_AE) == D64_XC_AE;
1801}
1802
1803/*
1804 * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
1805 */
1806static void dma64_txrotate(struct dma_info *di)
1807{
1808 u16 ad;
1809 uint nactive;
1810 uint rot;
1811 u16 old, new;
1812 u32 w;
1813 u16 first, last;
1814
1815 nactive = _dma_txactive(di);
1816 ad = (u16) (B2I((((R_REG(&di->d64txregs->status1) &
1817 D64_XS1_AD_MASK) - di->xmtptrbase) &
1818 D64_XS1_AD_MASK), struct dma64desc));
1819 rot = TXD(ad - di->txin);
1820
1821 /* full-ring case is a lot harder - don't worry about this */
1822 if (rot >= (di->ntxd - nactive)) {
1823 DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
1824 return;
1825 }
1826
1827 first = di->txin;
1828 last = PREVTXD(di->txout);
1829
1830 /* move entries starting at last and moving backwards to first */
1831 for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
1832 new = TXD(old + rot);
1833
1834 /*
1835 * Move the tx dma descriptor.
1836 * EOT is set only in the last entry in the ring.
1837 */
1838 w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
1839 if (new == (di->ntxd - 1))
1840 w |= D64_CTRL1_EOT;
1841 W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
1842
1843 w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
1844 W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
1845
1846 W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
1847 W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
1848
1849 /* zap the old tx dma descriptor address field */
1850 W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
1851 W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
1852
1853 /* move the corresponding txp[] entry */
1854 di->txp[new] = di->txp[old];
1855
1856 /* Move the map */
1857 if (DMASGLIST_ENAB) {
1858 memcpy(&di->txp_dmah[new], &di->txp_dmah[old],
1859 sizeof(struct dma_seg_map));
1860 memset(&di->txp_dmah[old], 0,
1861 sizeof(struct dma_seg_map));
1862 }
1863
1864 di->txp[old] = NULL;
1865 }
1866
1867 /* update txin and txout */
1868 di->txin = ad;
1869 di->txout = TXD(di->txout + rot);
1870 di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
1871
1872 /* kick the chip */
1873 W_REG(&di->d64txregs->ptr,
1874 di->xmtptrbase + I2B(di->txout, struct dma64desc));
1875}
1876
1877uint dma_addrwidth(struct si_pub *sih, void *dmaregs)
1878{
1879 /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */
1880 /* DMA engine is 64-bit capable */
1881 if ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) {
1882 /* backplane are 64-bit capable */
1883 if (ai_backplane64(sih))
1884 /* If bus is System Backplane or PCIE then we can access 64-bits */
1885 if ((sih->bustype == SI_BUS) ||
1886 ((sih->bustype == PCI_BUS) &&
1887 (sih->buscoretype == PCIE_CORE_ID)))
1888 return DMADDRWIDTH_64;
1889 }
1890 /* DMA hardware not supported by this driver*/
1891 return DMADDRWIDTH_64;
1892}
1893
1894/*
1895 * Mac80211 initiated actions sometimes require packets in the DMA queue to be
1896 * modified. The modified portion of the packet is not under control of the DMA
1897 * engine. This function calls a caller-supplied function for each packet in
1898 * the caller specified dma chain.
1899 */
1900void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
1901 (void *pkt, void *arg_a), void *arg_a)
1902{
1903 struct dma_info *di = (struct dma_info *) dmah;
1904 uint i = di->txin;
1905 uint end = di->txout;
1906 struct sk_buff *skb;
1907 struct ieee80211_tx_info *tx_info;
1908
1909 while (i != end) {
1910 skb = (struct sk_buff *)di->txp[i];
1911 if (skb != NULL) {
1912 tx_info = (struct ieee80211_tx_info *)skb->cb;
1913 (callback_fnc)(tx_info, arg_a);
1914 }
1915 i = NEXTTXD(i);
1916 }
1917}
diff --git a/drivers/staging/brcm80211/brcmsmac/dma.h b/drivers/staging/brcm80211/brcmsmac/dma.h
new file mode 100644
index 00000000000..9c8b9a6a557
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/dma.h
@@ -0,0 +1,250 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_DMA_H_
18#define _BRCM_DMA_H_
19
20#include "types.h" /* forward structure declarations */
21
22/* DMA structure:
23 * support two DMA engines: 32 bits address or 64 bit addressing
24 * basic DMA register set is per channel(transmit or receive)
25 * a pair of channels is defined for convenience
26 */
27
28/* 32 bits addressing */
29
30struct dma32diag { /* diag access */
31 u32 fifoaddr; /* diag address */
32 u32 fifodatalow; /* low 32bits of data */
33 u32 fifodatahigh; /* high 32bits of data */
34 u32 pad; /* reserved */
35};
36
37/* 64 bits addressing */
38
39/* dma registers per channel(xmt or rcv) */
40struct dma64regs {
41 u32 control; /* enable, et al */
42 u32 ptr; /* last descriptor posted to chip */
43 u32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
44 u32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
45 u32 status0; /* current descriptor, xmt state */
46 u32 status1; /* active descriptor, xmt error */
47};
48
49/* map/unmap direction */
50#define DMA_TX 1 /* TX direction for DMA */
51#define DMA_RX 2 /* RX direction for DMA */
52#define BUS_SWAP32(v) (v)
53
54/* range param for dma_getnexttxp() and dma_txreclaim */
55enum txd_range {
56 DMA_RANGE_ALL = 1,
57 DMA_RANGE_TRANSMITTED,
58 DMA_RANGE_TRANSFERED
59};
60
61/* dma function type */
62typedef void (*di_detach_t) (struct dma_pub *dmah);
63typedef bool(*di_txreset_t) (struct dma_pub *dmah);
64typedef bool(*di_rxreset_t) (struct dma_pub *dmah);
65typedef bool(*di_rxidle_t) (struct dma_pub *dmah);
66typedef void (*di_txinit_t) (struct dma_pub *dmah);
67typedef bool(*di_txenabled_t) (struct dma_pub *dmah);
68typedef void (*di_rxinit_t) (struct dma_pub *dmah);
69typedef void (*di_txsuspend_t) (struct dma_pub *dmah);
70typedef void (*di_txresume_t) (struct dma_pub *dmah);
71typedef bool(*di_txsuspended_t) (struct dma_pub *dmah);
72typedef bool(*di_txsuspendedidle_t) (struct dma_pub *dmah);
73typedef int (*di_txfast_t) (struct dma_pub *dmah, struct sk_buff *p,
74 bool commit);
75typedef int (*di_txunframed_t) (struct dma_pub *dmah, void *p, uint len,
76 bool commit);
77typedef void *(*di_getpos_t) (struct dma_pub *di, bool direction);
78typedef void (*di_fifoloopbackenable_t) (struct dma_pub *dmah);
79typedef bool(*di_txstopped_t) (struct dma_pub *dmah);
80typedef bool(*di_rxstopped_t) (struct dma_pub *dmah);
81typedef bool(*di_rxenable_t) (struct dma_pub *dmah);
82typedef bool(*di_rxenabled_t) (struct dma_pub *dmah);
83typedef void *(*di_rx_t) (struct dma_pub *dmah);
84typedef bool(*di_rxfill_t) (struct dma_pub *dmah);
85typedef void (*di_txreclaim_t) (struct dma_pub *dmah, enum txd_range range);
86typedef void (*di_rxreclaim_t) (struct dma_pub *dmah);
87typedef unsigned long (*di_getvar_t) (struct dma_pub *dmah,
88 const char *name);
89typedef void *(*di_getnexttxp_t) (struct dma_pub *dmah, enum txd_range range);
90typedef void *(*di_getnextrxp_t) (struct dma_pub *dmah, bool forceall);
91typedef void *(*di_peeknexttxp_t) (struct dma_pub *dmah);
92typedef void *(*di_peeknextrxp_t) (struct dma_pub *dmah);
93typedef void (*di_rxparam_get_t) (struct dma_pub *dmah, u16 *rxoffset,
94 u16 *rxbufsize);
95typedef void (*di_txblock_t) (struct dma_pub *dmah);
96typedef void (*di_txunblock_t) (struct dma_pub *dmah);
97typedef uint(*di_txactive_t) (struct dma_pub *dmah);
98typedef void (*di_txrotate_t) (struct dma_pub *dmah);
99typedef void (*di_counterreset_t) (struct dma_pub *dmah);
100typedef uint(*di_ctrlflags_t) (struct dma_pub *dmah, uint mask, uint flags);
101typedef char *(*di_dump_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
102 bool dumpring);
103typedef char *(*di_dumptx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
104 bool dumpring);
105typedef char *(*di_dumprx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b,
106 bool dumpring);
107typedef uint(*di_rxactive_t) (struct dma_pub *dmah);
108typedef uint(*di_txpending_t) (struct dma_pub *dmah);
109typedef uint(*di_txcommitted_t) (struct dma_pub *dmah);
110
111/* dma opsvec */
112struct di_fcn_s {
113 di_detach_t detach;
114 di_txinit_t txinit;
115 di_txreset_t txreset;
116 di_txenabled_t txenabled;
117 di_txsuspend_t txsuspend;
118 di_txresume_t txresume;
119 di_txsuspended_t txsuspended;
120 di_txsuspendedidle_t txsuspendedidle;
121 di_txfast_t txfast;
122 di_txunframed_t txunframed;
123 di_getpos_t getpos;
124 di_txstopped_t txstopped;
125 di_txreclaim_t txreclaim;
126 di_getnexttxp_t getnexttxp;
127 di_peeknexttxp_t peeknexttxp;
128 di_txblock_t txblock;
129 di_txunblock_t txunblock;
130 di_txactive_t txactive;
131 di_txrotate_t txrotate;
132
133 di_rxinit_t rxinit;
134 di_rxreset_t rxreset;
135 di_rxidle_t rxidle;
136 di_rxstopped_t rxstopped;
137 di_rxenable_t rxenable;
138 di_rxenabled_t rxenabled;
139 di_rx_t rx;
140 di_rxfill_t rxfill;
141 di_rxreclaim_t rxreclaim;
142 di_getnextrxp_t getnextrxp;
143 di_peeknextrxp_t peeknextrxp;
144 di_rxparam_get_t rxparam_get;
145
146 di_fifoloopbackenable_t fifoloopbackenable;
147 di_getvar_t d_getvar;
148 di_counterreset_t counterreset;
149 di_ctrlflags_t ctrlflags;
150 di_dump_t dump;
151 di_dumptx_t dumptx;
152 di_dumprx_t dumprx;
153 di_rxactive_t rxactive;
154 di_txpending_t txpending;
155 di_txcommitted_t txcommitted;
156 uint endnum;
157};
158
159/*
160 * Exported data structure (read-only)
161 */
162/* export structure */
163struct dma_pub {
164 const struct di_fcn_s *di_fn; /* DMA function pointers */
165 uint txavail; /* # free tx descriptors */
166 uint dmactrlflags; /* dma control flags */
167
168 /* rx error counters */
169 uint rxgiants; /* rx giant frames */
170 uint rxnobuf; /* rx out of dma descriptors */
171 /* tx error counters */
172 uint txnobuf; /* tx out of dma descriptors */
173};
174
175extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
176 void *dmaregstx, void *dmaregsrx, uint ntxd,
177 uint nrxd, uint rxbufsize, int rxextheadroom,
178 uint nrxpost, uint rxoffset, uint *msg_level);
179
180extern const struct di_fcn_s dma64proc;
181
182#define dma_detach(di) (dma64proc.detach(di))
183#define dma_txreset(di) (dma64proc.txreset(di))
184#define dma_rxreset(di) (dma64proc.rxreset(di))
185#define dma_rxidle(di) (dma64proc.rxidle(di))
186#define dma_txinit(di) (dma64proc.txinit(di))
187#define dma_txenabled(di) (dma64proc.txenabled(di))
188#define dma_rxinit(di) (dma64proc.rxinit(di))
189#define dma_txsuspend(di) (dma64proc.txsuspend(di))
190#define dma_txresume(di) (dma64proc.txresume(di))
191#define dma_txsuspended(di) (dma64proc.txsuspended(di))
192#define dma_txsuspendedidle(di) (dma64proc.txsuspendedidle(di))
193#define dma_txfast(di, p, commit) (dma64proc.txfast(di, p, commit))
194#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit))
195#define dma_getpos(di, dir) (dma64proc.getpos(di, dir))
196#define dma_fifoloopbackenable(di) (dma64proc.fifoloopbackenable(di))
197#define dma_txstopped(di) (dma64proc.txstopped(di))
198#define dma_rxstopped(di) (dma64proc.rxstopped(di))
199#define dma_rxenable(di) (dma64proc.rxenable(di))
200#define dma_rxenabled(di) (dma64proc.rxenabled(di))
201#define dma_rx(di) (dma64proc.rx(di))
202#define dma_rxfill(di) (dma64proc.rxfill(di))
203#define dma_txreclaim(di, range) (dma64proc.txreclaim(di, range))
204#define dma_rxreclaim(di) (dma64proc.rxreclaim(di))
205#define dma_getvar(di, name) (dma64proc.d_getvar(di, name))
206#define dma_getnexttxp(di, range) (dma64proc.getnexttxp(di, range))
207#define dma_getnextrxp(di, forceall) (dma64proc.getnextrxp(di, forceall))
208#define dma_peeknexttxp(di) (dma64proc.peeknexttxp(di))
209#define dma_peeknextrxp(di) (dma64proc.peeknextrxp(di))
210#define dma_rxparam_get(di, off, bufs) (dma64proc.rxparam_get(di, off, bufs))
211
212#define dma_txblock(di) (dma64proc.txblock(di))
213#define dma_txunblock(di) (dma64proc.txunblock(di))
214#define dma_txactive(di) (dma64proc.txactive(di))
215#define dma_rxactive(di) (dma64proc.rxactive(di))
216#define dma_txrotate(di) (dma64proc.txrotate(di))
217#define dma_counterreset(di) (dma64proc.counterreset(di))
218#define dma_ctrlflags(di, mask, flags) (dma64proc.ctrlflags((di), (mask), (flags)))
219#define dma_txpending(di) (dma64proc.txpending(di))
220#define dma_txcommitted(di) (dma64proc.txcommitted(di))
221
222
223/* return addresswidth allowed
224 * This needs to be done after SB attach but before dma attach.
225 * SB attach provides ability to probe backplane and dma core capabilities
226 * This info is needed by DMA_ALLOC_CONSISTENT in dma attach
227 */
228extern uint dma_addrwidth(struct si_pub *sih, void *dmaregs);
229void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
230 (void *pkt, void *arg_a), void *arg_a);
231
232/*
233 * DMA(Bug) on some chips seems to declare that the packet is ready, but the
234 * packet length is not updated yet (by DMA) on the expected time.
235 * Workaround is to hold processor till DMA updates the length, and stay off
236 * the bus to allow DMA update the length in buffer
237 */
238static inline void dma_spin_for_len(uint len, struct sk_buff *head)
239{
240#if defined(__mips__)
241 if (!len) {
242 while (!(len = *(u16 *) KSEG1ADDR(head->data)))
243 udelay(1);
244
245 *(u16 *) (head->data) = cpu_to_le16((u16) len);
246 }
247#endif /* defined(__mips__) */
248}
249
250#endif /* _BRCM_DMA_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/mac80211_if.c b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c
new file mode 100644
index 00000000000..3cb92fc0391
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c
@@ -0,0 +1,1939 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#define __UNDEF_NO_VERSION__
18
19#include <linux/etherdevice.h>
20#include <linux/pci.h>
21#include <linux/sched.h>
22#include <linux/firmware.h>
23#include <linux/interrupt.h>
24#include <net/mac80211.h>
25#include <defs.h>
26#include "nicpci.h"
27#include "phy/phy_int.h"
28#include "d11.h"
29#include "channel.h"
30#include "scb.h"
31#include "pub.h"
32#include "ucode_loader.h"
33#include "mac80211_if.h"
34
35#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
36
37#define LOCK(wl) spin_lock_bh(&(wl)->lock)
38#define UNLOCK(wl) spin_unlock_bh(&(wl)->lock)
39
40/* locking from inside brcms_isr */
41#define ISR_LOCK(wl, flags)\
42 do {\
43 spin_lock(&(wl)->isr_lock);\
44 (void)(flags); } \
45 while (0)
46
47#define ISR_UNLOCK(wl, flags)\
48 do {\
49 spin_unlock(&(wl)->isr_lock);\
50 (void)(flags); } \
51 while (0)
52
53/* locking under LOCK() to synchronize with brcms_isr */
54#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags)
55#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags)
56
57static void brcms_timer(unsigned long data);
58static void _brcms_timer(struct brcms_timer *t);
59
60
61static int ieee_hw_init(struct ieee80211_hw *hw);
62static int ieee_hw_rate_init(struct ieee80211_hw *hw);
63
64static int wl_linux_watchdog(void *ctx);
65
66/* Flags we support */
67#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
68 FIF_ALLMULTI | \
69 FIF_FCSFAIL | \
70 FIF_PLCPFAIL | \
71 FIF_CONTROL | \
72 FIF_OTHER_BSS | \
73 FIF_BCN_PRBRESP_PROMISC)
74
75static int n_adapters_found;
76
77static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev);
78static void brcms_release_fw(struct brcms_info *wl);
79
80/* local prototypes */
81static void brcms_dpc(unsigned long data);
82static irqreturn_t brcms_isr(int irq, void *dev_id);
83
84static int __devinit brcms_pci_probe(struct pci_dev *pdev,
85 const struct pci_device_id *ent);
86static void brcms_remove(struct pci_dev *pdev);
87static void brcms_free(struct brcms_info *wl);
88static void brcms_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br);
89
90MODULE_AUTHOR("Broadcom Corporation");
91MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
92MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
93MODULE_LICENSE("Dual BSD/GPL");
94
95/* recognized PCI IDs */
96static DEFINE_PCI_DEVICE_TABLE(brcms_pci_id_table) = {
97 {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */
98 {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */
99 {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */
100 /* 43224 Ven */
101 {PCI_VENDOR_ID_BROADCOM, 0x0576, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
102 {0}
103};
104
105MODULE_DEVICE_TABLE(pci, brcms_pci_id_table);
106
107#ifdef BCMDBG
108static int msglevel = 0xdeadbeef;
109module_param(msglevel, int, 0);
110static int phymsglevel = 0xdeadbeef;
111module_param(phymsglevel, int, 0);
112#endif /* BCMDBG */
113
114#define HW_TO_WL(hw) (hw->priv)
115#define WL_TO_HW(wl) (wl->pub->ieee_hw)
116
117/* MAC80211 callback functions */
118static int brcms_ops_start(struct ieee80211_hw *hw);
119static void brcms_ops_stop(struct ieee80211_hw *hw);
120static int brcms_ops_add_interface(struct ieee80211_hw *hw,
121 struct ieee80211_vif *vif);
122static void brcms_ops_remove_interface(struct ieee80211_hw *hw,
123 struct ieee80211_vif *vif);
124static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed);
125static void brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
126 struct ieee80211_vif *vif,
127 struct ieee80211_bss_conf *info,
128 u32 changed);
129static void brcms_ops_configure_filter(struct ieee80211_hw *hw,
130 unsigned int changed_flags,
131 unsigned int *total_flags, u64 multicast);
132static int brcms_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
133 bool set);
134static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw);
135static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw);
136static void brcms_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf);
137static int brcms_ops_get_stats(struct ieee80211_hw *hw,
138 struct ieee80211_low_level_stats *stats);
139static void brcms_ops_sta_notify(struct ieee80211_hw *hw,
140 struct ieee80211_vif *vif,
141 enum sta_notify_cmd cmd,
142 struct ieee80211_sta *sta);
143static int brcms_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
144 const struct ieee80211_tx_queue_params *params);
145static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw);
146static int brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
147 struct ieee80211_sta *sta);
148static int brcms_ops_sta_remove(struct ieee80211_hw *hw,
149 struct ieee80211_vif *vif,
150 struct ieee80211_sta *sta);
151static int brcms_ops_ampdu_action(struct ieee80211_hw *hw,
152 struct ieee80211_vif *vif,
153 enum ieee80211_ampdu_mlme_action action,
154 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
155 u8 buf_size);
156static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw);
157static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop);
158
159static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
160{
161 struct brcms_info *wl = hw->priv;
162
163 LOCK(wl);
164 if (!wl->pub->up) {
165 wiphy_err(wl->wiphy, "ops->tx called while down\n");
166 kfree_skb(skb);
167 goto done;
168 }
169 brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
170 done:
171 UNLOCK(wl);
172}
173
174static int brcms_ops_start(struct ieee80211_hw *hw)
175{
176 struct brcms_info *wl = hw->priv;
177 bool blocked;
178 /*
179 struct ieee80211_channel *curchan = hw->conf.channel;
180 */
181
182 ieee80211_wake_queues(hw);
183 LOCK(wl);
184 blocked = brcms_rfkill_set_hw_state(wl);
185 UNLOCK(wl);
186 if (!blocked)
187 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
188
189 return 0;
190}
191
192static void brcms_ops_stop(struct ieee80211_hw *hw)
193{
194 ieee80211_stop_queues(hw);
195}
196
197static int
198brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
199{
200 struct brcms_info *wl;
201 int err;
202
203 /* Just STA for now */
204 if (vif->type != NL80211_IFTYPE_AP &&
205 vif->type != NL80211_IFTYPE_MESH_POINT &&
206 vif->type != NL80211_IFTYPE_STATION &&
207 vif->type != NL80211_IFTYPE_WDS &&
208 vif->type != NL80211_IFTYPE_ADHOC) {
209 wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
210 " STA for now\n", __func__, vif->type);
211 return -EOPNOTSUPP;
212 }
213
214 wl = HW_TO_WL(hw);
215 LOCK(wl);
216 err = brcms_up(wl);
217 UNLOCK(wl);
218
219 if (err != 0) {
220 wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
221 err);
222 }
223 return err;
224}
225
226static void
227brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
228{
229 struct brcms_info *wl;
230
231 wl = HW_TO_WL(hw);
232
233 /* put driver in down state */
234 LOCK(wl);
235 brcms_down(wl);
236 UNLOCK(wl);
237}
238
239/*
240 * precondition: perimeter lock has been acquired
241 */
242static int
243ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
244 enum nl80211_channel_type type)
245{
246 struct brcms_info *wl = HW_TO_WL(hw);
247 int err = 0;
248
249 switch (type) {
250 case NL80211_CHAN_HT20:
251 case NL80211_CHAN_NO_HT:
252 err = brcms_c_set(wl->wlc, BRCM_SET_CHANNEL, chan->hw_value);
253 break;
254 case NL80211_CHAN_HT40MINUS:
255 case NL80211_CHAN_HT40PLUS:
256 wiphy_err(hw->wiphy,
257 "%s: Need to implement 40 Mhz Channels!\n", __func__);
258 err = 1;
259 break;
260 }
261
262 if (err)
263 return -EIO;
264 return err;
265}
266
267static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
268{
269 struct ieee80211_conf *conf = &hw->conf;
270 struct brcms_info *wl = HW_TO_WL(hw);
271 int err = 0;
272 int new_int;
273 struct wiphy *wiphy = hw->wiphy;
274
275 LOCK(wl);
276 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
277 if (brcms_c_set_par(wl->wlc, IOV_BCN_LI_BCN,
278 conf->listen_interval) < 0) {
279 wiphy_err(wiphy, "%s: Error setting listen_interval\n",
280 __func__);
281 err = -EIO;
282 goto config_out;
283 }
284 brcms_c_get_par(wl->wlc, IOV_BCN_LI_BCN, &new_int);
285 }
286 if (changed & IEEE80211_CONF_CHANGE_MONITOR)
287 wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n",
288 __func__, conf->flags & IEEE80211_CONF_MONITOR ?
289 "true" : "false");
290 if (changed & IEEE80211_CONF_CHANGE_PS)
291 wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
292 __func__, conf->flags & IEEE80211_CONF_PS ?
293 "true" : "false");
294
295 if (changed & IEEE80211_CONF_CHANGE_POWER) {
296 if (brcms_c_set_par(wl->wlc, IOV_QTXPOWER,
297 conf->power_level * 4) < 0) {
298 wiphy_err(wiphy, "%s: Error setting power_level\n",
299 __func__);
300 err = -EIO;
301 goto config_out;
302 }
303 brcms_c_get_par(wl->wlc, IOV_QTXPOWER, &new_int);
304 if (new_int != (conf->power_level * 4))
305 wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
306 "\n", __func__, conf->power_level * 4,
307 new_int);
308 }
309 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
310 err = ieee_set_channel(hw, conf->channel, conf->channel_type);
311 }
312 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
313 if (brcms_c_set
314 (wl->wlc, BRCM_SET_SRL,
315 conf->short_frame_max_tx_count) < 0) {
316 wiphy_err(wiphy, "%s: Error setting srl\n", __func__);
317 err = -EIO;
318 goto config_out;
319 }
320 if (brcms_c_set(wl->wlc, BRCM_SET_LRL,
321 conf->long_frame_max_tx_count) < 0) {
322 wiphy_err(wiphy, "%s: Error setting lrl\n", __func__);
323 err = -EIO;
324 goto config_out;
325 }
326 }
327
328 config_out:
329 UNLOCK(wl);
330 return err;
331}
332
333static void
334brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
335 struct ieee80211_vif *vif,
336 struct ieee80211_bss_conf *info, u32 changed)
337{
338 struct brcms_info *wl = HW_TO_WL(hw);
339 struct wiphy *wiphy = hw->wiphy;
340 int val;
341
342 if (changed & BSS_CHANGED_ASSOC) {
343 /* association status changed (associated/disassociated)
344 * also implies a change in the AID.
345 */
346 wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
347 __func__, info->assoc ? "" : "dis");
348 LOCK(wl);
349 brcms_c_associate_upd(wl->wlc, info->assoc);
350 UNLOCK(wl);
351 }
352 if (changed & BSS_CHANGED_ERP_SLOT) {
353 /* slot timing changed */
354 if (info->use_short_slot)
355 val = 1;
356 else
357 val = 0;
358 LOCK(wl);
359 brcms_c_set(wl->wlc, BRCMS_SET_SHORTSLOT_OVERRIDE, val);
360 UNLOCK(wl);
361 }
362
363 if (changed & BSS_CHANGED_HT) {
364 /* 802.11n parameters changed */
365 u16 mode = info->ht_operation_mode;
366
367 LOCK(wl);
368 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG,
369 mode & IEEE80211_HT_OP_MODE_PROTECTION);
370 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF,
371 mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
372 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS,
373 mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
374 UNLOCK(wl);
375 }
376 if (changed & BSS_CHANGED_BASIC_RATES) {
377 struct ieee80211_supported_band *bi;
378 u32 br_mask, i;
379 u16 rate;
380 struct wl_rateset rs;
381 int error;
382
383 /* retrieve the current rates */
384 LOCK(wl);
385 error = brcms_c_ioctl(wl->wlc, BRCM_GET_CURR_RATESET,
386 &rs, sizeof(rs), NULL);
387 UNLOCK(wl);
388 if (error) {
389 wiphy_err(wiphy, "%s: retrieve rateset failed: %d\n",
390 __func__, error);
391 return;
392 }
393 br_mask = info->basic_rates;
394 bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)];
395 for (i = 0; i < bi->n_bitrates; i++) {
396 /* convert to internal rate value */
397 rate = (bi->bitrates[i].bitrate << 1) / 10;
398
399 /* set/clear basic rate flag */
400 brcms_set_basic_rate(&rs, rate, br_mask & 1);
401 br_mask >>= 1;
402 }
403
404 /* update the rate set */
405 LOCK(wl);
406 brcms_c_ioctl(wl->wlc, BRCM_SET_RATESET, &rs, sizeof(rs), NULL);
407 UNLOCK(wl);
408 }
409 if (changed & BSS_CHANGED_BEACON_INT) {
410 /* Beacon interval changed */
411 LOCK(wl);
412 brcms_c_set(wl->wlc, BRCM_SET_BCNPRD, info->beacon_int);
413 UNLOCK(wl);
414 }
415 if (changed & BSS_CHANGED_BSSID) {
416 /* BSSID changed, for whatever reason (IBSS and managed mode) */
417 LOCK(wl);
418 brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
419 info->bssid);
420 UNLOCK(wl);
421 }
422 if (changed & BSS_CHANGED_BEACON) {
423 /* Beacon data changed, retrieve new beacon (beaconing modes) */
424 wiphy_err(wiphy, "%s: beacon changed\n", __func__);
425 }
426 if (changed & BSS_CHANGED_BEACON_ENABLED) {
427 /* Beaconing should be enabled/disabled (beaconing modes) */
428 wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
429 info->enable_beacon ? "true" : "false");
430 }
431 if (changed & BSS_CHANGED_CQM) {
432 /* Connection quality monitor config changed */
433 wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
434 " (implement)\n", __func__, info->cqm_rssi_thold,
435 info->cqm_rssi_hyst);
436 }
437 if (changed & BSS_CHANGED_IBSS) {
438 /* IBSS join status changed */
439 wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
440 info->ibss_joined ? "true" : "false");
441 }
442 if (changed & BSS_CHANGED_ARP_FILTER) {
443 /* Hardware ARP filter address list or state changed */
444 wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
445 " (implement)\n", __func__, info->arp_filter_enabled ?
446 "true" : "false", info->arp_addr_cnt);
447 }
448 if (changed & BSS_CHANGED_QOS) {
449 /*
450 * QoS for this association was enabled/disabled.
451 * Note that it is only ever disabled for station mode.
452 */
453 wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
454 info->qos ? "true" : "false");
455 }
456 return;
457}
458
459static void
460brcms_ops_configure_filter(struct ieee80211_hw *hw,
461 unsigned int changed_flags,
462 unsigned int *total_flags, u64 multicast)
463{
464 struct brcms_info *wl = hw->priv;
465 struct wiphy *wiphy = hw->wiphy;
466
467 changed_flags &= MAC_FILTERS;
468 *total_flags &= MAC_FILTERS;
469 if (changed_flags & FIF_PROMISC_IN_BSS)
470 wiphy_err(wiphy, "FIF_PROMISC_IN_BSS\n");
471 if (changed_flags & FIF_ALLMULTI)
472 wiphy_err(wiphy, "FIF_ALLMULTI\n");
473 if (changed_flags & FIF_FCSFAIL)
474 wiphy_err(wiphy, "FIF_FCSFAIL\n");
475 if (changed_flags & FIF_PLCPFAIL)
476 wiphy_err(wiphy, "FIF_PLCPFAIL\n");
477 if (changed_flags & FIF_CONTROL)
478 wiphy_err(wiphy, "FIF_CONTROL\n");
479 if (changed_flags & FIF_OTHER_BSS)
480 wiphy_err(wiphy, "FIF_OTHER_BSS\n");
481 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
482 LOCK(wl);
483 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
484 wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
485 brcms_c_mac_bcn_promisc_change(wl->wlc, 1);
486 } else {
487 brcms_c_mac_bcn_promisc_change(wl->wlc, 0);
488 wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
489 }
490 UNLOCK(wl);
491 }
492 return;
493}
494
495static int
496brcms_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
497{
498 return 0;
499}
500
501static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw)
502{
503 struct brcms_info *wl = hw->priv;
504 LOCK(wl);
505 brcms_c_scan_start(wl->wlc);
506 UNLOCK(wl);
507 return;
508}
509
510static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw)
511{
512 struct brcms_info *wl = hw->priv;
513 LOCK(wl);
514 brcms_c_scan_stop(wl->wlc);
515 UNLOCK(wl);
516 return;
517}
518
519static void brcms_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
520{
521 wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
522 return;
523}
524
525static int
526brcms_ops_get_stats(struct ieee80211_hw *hw,
527 struct ieee80211_low_level_stats *stats)
528{
529 struct brcms_info *wl = hw->priv;
530 struct wl_cnt *cnt;
531
532 LOCK(wl);
533 cnt = wl->pub->_cnt;
534 stats->dot11ACKFailureCount = 0;
535 stats->dot11RTSFailureCount = 0;
536 stats->dot11FCSErrorCount = 0;
537 stats->dot11RTSSuccessCount = 0;
538 UNLOCK(wl);
539 return 0;
540}
541
542static void
543brcms_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
544 enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
545{
546 switch (cmd) {
547 default:
548 wiphy_err(hw->wiphy, "%s: Unknown cmd = %d\n", __func__,
549 cmd);
550 break;
551 }
552 return;
553}
554
555static int
556brcms_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
557 const struct ieee80211_tx_queue_params *params)
558{
559 struct brcms_info *wl = hw->priv;
560
561 LOCK(wl);
562 brcms_c_wme_setparams(wl->wlc, queue, params, true);
563 UNLOCK(wl);
564
565 return 0;
566}
567
568static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw)
569{
570 wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
571 return 0;
572}
573
574static int
575brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
576 struct ieee80211_sta *sta)
577{
578 struct scb *scb;
579
580 int i;
581 struct brcms_info *wl = hw->priv;
582
583 /* Init the scb */
584 scb = (struct scb *)sta->drv_priv;
585 memset(scb, 0, sizeof(struct scb));
586 for (i = 0; i < NUMPRIO; i++)
587 scb->seqctl[i] = 0xFFFF;
588 scb->seqctl_nonqos = 0xFFFF;
589 scb->magic = SCB_MAGIC;
590
591 wl->pub->global_scb = scb;
592 wl->pub->global_ampdu = &(scb->scb_ampdu);
593 wl->pub->global_ampdu->scb = scb;
594 wl->pub->global_ampdu->max_pdu = 16;
595 brcmu_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
596 AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT);
597
598 sta->ht_cap.ht_supported = true;
599 sta->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
600 sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY;
601 sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD |
602 IEEE80211_HT_CAP_SGI_20 |
603 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT;
604
605 /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */
606 return 0;
607}
608
609static int
610brcms_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
611 struct ieee80211_sta *sta)
612{
613 return 0;
614}
615
616static int
617brcms_ops_ampdu_action(struct ieee80211_hw *hw,
618 struct ieee80211_vif *vif,
619 enum ieee80211_ampdu_mlme_action action,
620 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
621 u8 buf_size)
622{
623 struct scb *scb = (struct scb *)sta->drv_priv;
624 struct brcms_info *wl = hw->priv;
625 int status;
626
627 if (WARN_ON(scb->magic != SCB_MAGIC))
628 return -EIDRM;
629 switch (action) {
630 case IEEE80211_AMPDU_RX_START:
631 break;
632 case IEEE80211_AMPDU_RX_STOP:
633 break;
634 case IEEE80211_AMPDU_TX_START:
635 LOCK(wl);
636 status = brcms_c_aggregatable(wl->wlc, tid);
637 UNLOCK(wl);
638 if (!status) {
639 wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
640 tid);
641 return -EINVAL;
642 }
643 /* Future improvement: Use the starting sequence number provided ... */
644 *ssn = 0;
645 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
646 break;
647
648 case IEEE80211_AMPDU_TX_STOP:
649 LOCK(wl);
650 brcms_c_ampdu_flush(wl->wlc, sta, tid);
651 UNLOCK(wl);
652 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
653 break;
654 case IEEE80211_AMPDU_TX_OPERATIONAL:
655 /*
656 * BA window size from ADDBA response ('buf_size') defines how
657 * many outstanding MPDUs are allowed for the BA stream by
658 * recipient and traffic class. 'ampdu_factor' gives maximum
659 * AMPDU size.
660 */
661 LOCK(wl);
662 brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size,
663 (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
664 sta->ht_cap.ampdu_factor)) - 1);
665 UNLOCK(wl);
666 /* Power save wakeup */
667 break;
668 default:
669 wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
670 __func__);
671 }
672
673 return 0;
674}
675
676static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)
677{
678 struct brcms_info *wl = HW_TO_WL(hw);
679 bool blocked;
680
681 LOCK(wl);
682 blocked = brcms_c_check_radio_disabled(wl->wlc);
683 UNLOCK(wl);
684
685 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
686}
687
688static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
689{
690 struct brcms_info *wl = HW_TO_WL(hw);
691
692 no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
693
694 /* wait for packet queue and dma fifos to run empty */
695 LOCK(wl);
696 brcms_c_wait_for_tx_completion(wl->wlc, drop);
697 UNLOCK(wl);
698}
699
700static const struct ieee80211_ops brcms_ops = {
701 .tx = brcms_ops_tx,
702 .start = brcms_ops_start,
703 .stop = brcms_ops_stop,
704 .add_interface = brcms_ops_add_interface,
705 .remove_interface = brcms_ops_remove_interface,
706 .config = brcms_ops_config,
707 .bss_info_changed = brcms_ops_bss_info_changed,
708 .configure_filter = brcms_ops_configure_filter,
709 .set_tim = brcms_ops_set_tim,
710 .sw_scan_start = brcms_ops_sw_scan_start,
711 .sw_scan_complete = brcms_ops_sw_scan_complete,
712 .set_tsf = brcms_ops_set_tsf,
713 .get_stats = brcms_ops_get_stats,
714 .sta_notify = brcms_ops_sta_notify,
715 .conf_tx = brcms_ops_conf_tx,
716 .get_tsf = brcms_ops_get_tsf,
717 .sta_add = brcms_ops_sta_add,
718 .sta_remove = brcms_ops_sta_remove,
719 .ampdu_action = brcms_ops_ampdu_action,
720 .rfkill_poll = brcms_ops_rfkill_poll,
721 .flush = brcms_ops_flush,
722};
723
724/*
725 * is called in brcms_pci_probe() context, therefore no locking required.
726 */
727static int brcms_set_hint(struct brcms_info *wl, char *abbrev)
728{
729 return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
730}
731
732/**
733 * attach to the WL device.
734 *
735 * Attach to the WL device identified by vendor and device parameters.
736 * regs is a host accessible memory address pointing to WL device registers.
737 *
738 * brcms_attach is not defined as static because in the case where no bus
739 * is defined, wl_attach will never be called, and thus, gcc will issue
740 * a warning that this function is defined but not used if we declare
741 * it as static.
742 *
743 *
744 * is called in brcms_pci_probe() context, therefore no locking required.
745 */
746static struct brcms_info *brcms_attach(u16 vendor, u16 device,
747 unsigned long regs,
748 uint bustype, void *btparam, uint irq)
749{
750 struct brcms_info *wl = NULL;
751 int unit, err;
752 unsigned long base_addr;
753 struct ieee80211_hw *hw;
754 u8 perm[ETH_ALEN];
755
756 unit = n_adapters_found;
757 err = 0;
758
759 if (unit < 0) {
760 return NULL;
761 }
762
763 /* allocate private info */
764 hw = pci_get_drvdata(btparam); /* btparam == pdev */
765 if (hw != NULL)
766 wl = hw->priv;
767 if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
768 return NULL;
769 wl->wiphy = hw->wiphy;
770
771 atomic_set(&wl->callbacks, 0);
772
773 /* setup the bottom half handler */
774 tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
775
776
777
778 base_addr = regs;
779
780 if (bustype == PCI_BUS || bustype == RPC_BUS) {
781 /* Do nothing */
782 } else {
783 bustype = PCI_BUS;
784 BCMMSG(wl->wiphy, "force to PCI\n");
785 }
786 wl->bcm_bustype = bustype;
787
788 wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
789 if (wl->regsva == NULL) {
790 wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit);
791 goto fail;
792 }
793 spin_lock_init(&wl->lock);
794 spin_lock_init(&wl->isr_lock);
795
796 /* prepare ucode */
797 if (brcms_request_fw(wl, (struct pci_dev *)btparam) < 0) {
798 wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
799 "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
800 brcms_release_fw(wl);
801 brcms_remove((struct pci_dev *)btparam);
802 return NULL;
803 }
804
805 /* common load-time initialization */
806 wl->wlc = brcms_c_attach((void *)wl, vendor, device, unit, false,
807 wl->regsva, wl->bcm_bustype, btparam, &err);
808 brcms_release_fw(wl);
809 if (!wl->wlc) {
810 wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
811 KBUILD_MODNAME, err);
812 goto fail;
813 }
814 wl->pub = brcms_c_pub(wl->wlc);
815
816 wl->pub->ieee_hw = hw;
817
818 if (brcms_c_set_par(wl->wlc, IOV_MPC, 0) < 0) {
819 wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n",
820 unit);
821 }
822
823 /* register our interrupt handler */
824 if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
825 wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
826 goto fail;
827 }
828 wl->irq = irq;
829
830 /* register module */
831 brcms_c_module_register(wl->pub, "linux", wl, wl_linux_watchdog, NULL);
832
833 if (ieee_hw_init(hw)) {
834 wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
835 __func__);
836 goto fail;
837 }
838
839 memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
840 if (WARN_ON(!is_valid_ether_addr(perm)))
841 goto fail;
842 SET_IEEE80211_PERM_ADDR(hw, perm);
843
844 err = ieee80211_register_hw(hw);
845 if (err) {
846 wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
847 "%d\n", __func__, err);
848 }
849
850 if (wl->pub->srom_ccode[0])
851 err = brcms_set_hint(wl, wl->pub->srom_ccode);
852 else
853 err = brcms_set_hint(wl, "US");
854 if (err) {
855 wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
856 __func__, err);
857 }
858
859 n_adapters_found++;
860 return wl;
861
862fail:
863 brcms_free(wl);
864 return NULL;
865}
866
867
868
869#define CHAN2GHZ(channel, freqency, chflags) { \
870 .band = IEEE80211_BAND_2GHZ, \
871 .center_freq = (freqency), \
872 .hw_value = (channel), \
873 .flags = chflags, \
874 .max_antenna_gain = 0, \
875 .max_power = 19, \
876}
877
878static struct ieee80211_channel brcms_2ghz_chantable[] = {
879 CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
880 CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
881 CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
882 CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
883 CHAN2GHZ(5, 2432, 0),
884 CHAN2GHZ(6, 2437, 0),
885 CHAN2GHZ(7, 2442, 0),
886 CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
887 CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
888 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
889 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
890 CHAN2GHZ(12, 2467,
891 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
892 IEEE80211_CHAN_NO_HT40PLUS),
893 CHAN2GHZ(13, 2472,
894 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
895 IEEE80211_CHAN_NO_HT40PLUS),
896 CHAN2GHZ(14, 2484,
897 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
898 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
899};
900
901#define CHAN5GHZ(channel, chflags) { \
902 .band = IEEE80211_BAND_5GHZ, \
903 .center_freq = 5000 + 5*(channel), \
904 .hw_value = (channel), \
905 .flags = chflags, \
906 .max_antenna_gain = 0, \
907 .max_power = 21, \
908}
909
910static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
911 /* UNII-1 */
912 CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
913 CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
914 CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
915 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
916 /* UNII-2 */
917 CHAN5GHZ(52,
918 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
919 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
920 CHAN5GHZ(56,
921 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
922 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
923 CHAN5GHZ(60,
924 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
925 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
926 CHAN5GHZ(64,
927 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
928 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
929 /* MID */
930 CHAN5GHZ(100,
931 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
932 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
933 CHAN5GHZ(104,
934 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
935 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
936 CHAN5GHZ(108,
937 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
938 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
939 CHAN5GHZ(112,
940 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
941 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
942 CHAN5GHZ(116,
943 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
944 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
945 CHAN5GHZ(120,
946 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
947 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
948 CHAN5GHZ(124,
949 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
950 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
951 CHAN5GHZ(128,
952 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
953 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
954 CHAN5GHZ(132,
955 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
956 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
957 CHAN5GHZ(136,
958 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
959 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
960 CHAN5GHZ(140,
961 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
962 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
963 IEEE80211_CHAN_NO_HT40MINUS),
964 /* UNII-3 */
965 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
966 CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
967 CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
968 CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
969 CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
970};
971
972#define RATE(rate100m, _flags) { \
973 .bitrate = (rate100m), \
974 .flags = (_flags), \
975 .hw_value = (rate100m / 5), \
976}
977
978/*
979 * The rate table is used for both 2.4G and 5G rates. The
980 * latter being a subset as it does not support CCK rates.
981 */
982static struct ieee80211_rate legacy_ratetable[] = {
983 RATE(10, 0),
984 RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
985 RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
986 RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
987 RATE(60, 0),
988 RATE(90, 0),
989 RATE(120, 0),
990 RATE(180, 0),
991 RATE(240, 0),
992 RATE(360, 0),
993 RATE(480, 0),
994 RATE(540, 0),
995};
996
997static struct ieee80211_supported_band brcms_band_2GHz_nphy = {
998 .band = IEEE80211_BAND_2GHZ,
999 .channels = brcms_2ghz_chantable,
1000 .n_channels = ARRAY_SIZE(brcms_2ghz_chantable),
1001 .bitrates = legacy_ratetable,
1002 .n_bitrates = ARRAY_SIZE(legacy_ratetable),
1003 .ht_cap = {
1004 /* from include/linux/ieee80211.h */
1005 .cap = IEEE80211_HT_CAP_GRN_FLD |
1006 IEEE80211_HT_CAP_SGI_20 |
1007 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,
1008 .ht_supported = true,
1009 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
1010 .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
1011 .mcs = {
1012 /* placeholders for now */
1013 .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
1014 .rx_highest = 500,
1015 .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
1016 }
1017};
1018
1019static struct ieee80211_supported_band brcms_band_5GHz_nphy = {
1020 .band = IEEE80211_BAND_5GHZ,
1021 .channels = brcms_5ghz_nphy_chantable,
1022 .n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable),
1023 .bitrates = legacy_ratetable + BRCMS_LEGACY_5G_RATE_OFFSET,
1024 .n_bitrates = ARRAY_SIZE(legacy_ratetable) -
1025 BRCMS_LEGACY_5G_RATE_OFFSET,
1026 .ht_cap = {
1027 /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */
1028 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */
1029 .ht_supported = true,
1030 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
1031 .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
1032 .mcs = {
1033 /* placeholders for now */
1034 .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
1035 .rx_highest = 500,
1036 .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
1037 }
1038};
1039
1040/*
1041 * is called in brcms_pci_probe() context, therefore no locking required.
1042 */
1043static int ieee_hw_rate_init(struct ieee80211_hw *hw)
1044{
1045 struct brcms_info *wl = HW_TO_WL(hw);
1046 int has_5g;
1047 char phy_list[4];
1048
1049 has_5g = 0;
1050
1051 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
1052 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
1053
1054 if (brcms_c_get(wl->wlc, BRCM_GET_PHYLIST, (int *)&phy_list) < 0)
1055 wiphy_err(hw->wiphy, "Phy list failed\n");
1056
1057 if (phy_list[0] == 'n' || phy_list[0] == 'c') {
1058 if (phy_list[0] == 'c') {
1059 /* Single stream */
1060 brcms_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0;
1061 brcms_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72;
1062 }
1063 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &brcms_band_2GHz_nphy;
1064 } else {
1065 return -EPERM;
1066 }
1067
1068 /* Assume all bands use the same phy. True for 11n devices. */
1069 if (NBANDS_PUB(wl->pub) > 1) {
1070 has_5g++;
1071 if (phy_list[0] == 'n' || phy_list[0] == 'c') {
1072 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1073 &brcms_band_5GHz_nphy;
1074 } else {
1075 return -EPERM;
1076 }
1077 }
1078 return 0;
1079}
1080
1081/*
1082 * is called in brcms_pci_probe() context, therefore no locking required.
1083 */
1084static int ieee_hw_init(struct ieee80211_hw *hw)
1085{
1086 hw->flags = IEEE80211_HW_SIGNAL_DBM
1087 /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */
1088 | IEEE80211_HW_REPORTS_TX_ACK_STATUS
1089 | IEEE80211_HW_AMPDU_AGGREGATION;
1090
1091 hw->extra_tx_headroom = brcms_c_get_header_len();
1092 hw->queues = N_TX_QUEUES;
1093 hw->max_rates = 2; /* Primary rate and 1 fallback rate */
1094
1095 hw->channel_change_time = 7 * 1000; /* channel change time is dependent on chip and band */
1096 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1097
1098 hw->rate_control_algorithm = "minstrel_ht";
1099
1100 hw->sta_data_size = sizeof(struct scb);
1101 return ieee_hw_rate_init(hw);
1102}
1103
1104/**
1105 * determines if a device is a WL device, and if so, attaches it.
1106 *
1107 * This function determines if a device pointed to by pdev is a WL device,
1108 * and if so, performs a brcms_attach() on it.
1109 *
1110 * Perimeter lock is initialized in the course of this function.
1111 */
1112static int __devinit
1113brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1114{
1115 int rc;
1116 struct brcms_info *wl;
1117 struct ieee80211_hw *hw;
1118 u32 val;
1119
1120 dev_info(&pdev->dev, "bus %d slot %d func %d irq %d\n",
1121 pdev->bus->number, PCI_SLOT(pdev->devfn),
1122 PCI_FUNC(pdev->devfn), pdev->irq);
1123
1124 if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
1125 ((pdev->device != 0x0576) &&
1126 ((pdev->device & 0xff00) != 0x4300) &&
1127 ((pdev->device & 0xff00) != 0x4700) &&
1128 ((pdev->device < 43000) || (pdev->device > 43999))))
1129 return -ENODEV;
1130
1131 rc = pci_enable_device(pdev);
1132 if (rc) {
1133 pr_err("%s: Cannot enable device %d-%d_%d\n",
1134 __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
1135 PCI_FUNC(pdev->devfn));
1136 return -ENODEV;
1137 }
1138 pci_set_master(pdev);
1139
1140 pci_read_config_dword(pdev, 0x40, &val);
1141 if ((val & 0x0000ff00) != 0)
1142 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1143
1144 hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops);
1145 if (!hw) {
1146 pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
1147 return -ENOMEM;
1148 }
1149
1150 SET_IEEE80211_DEV(hw, &pdev->dev);
1151
1152 pci_set_drvdata(pdev, hw);
1153
1154 memset(hw->priv, 0, sizeof(*wl));
1155
1156 wl = brcms_attach(pdev->vendor, pdev->device,
1157 pci_resource_start(pdev, 0), PCI_BUS, pdev,
1158 pdev->irq);
1159
1160 if (!wl) {
1161 pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME,
1162 __func__);
1163 return -ENODEV;
1164 }
1165 return 0;
1166}
1167
1168static int brcms_suspend(struct pci_dev *pdev, pm_message_t state)
1169{
1170 struct brcms_info *wl;
1171 struct ieee80211_hw *hw;
1172
1173 hw = pci_get_drvdata(pdev);
1174 wl = HW_TO_WL(hw);
1175 if (!wl) {
1176 wiphy_err(wl->wiphy,
1177 "brcms_suspend: pci_get_drvdata failed\n");
1178 return -ENODEV;
1179 }
1180
1181 /* only need to flag hw is down for proper resume */
1182 LOCK(wl);
1183 wl->pub->hw_up = false;
1184 UNLOCK(wl);
1185
1186 pci_save_state(pdev);
1187 pci_disable_device(pdev);
1188 return pci_set_power_state(pdev, PCI_D3hot);
1189}
1190
1191static int brcms_resume(struct pci_dev *pdev)
1192{
1193 struct brcms_info *wl;
1194 struct ieee80211_hw *hw;
1195 int err = 0;
1196 u32 val;
1197
1198 hw = pci_get_drvdata(pdev);
1199 wl = HW_TO_WL(hw);
1200 if (!wl) {
1201 wiphy_err(wl->wiphy,
1202 "wl: brcms_resume: pci_get_drvdata failed\n");
1203 return -ENODEV;
1204 }
1205
1206 err = pci_set_power_state(pdev, PCI_D0);
1207 if (err)
1208 return err;
1209
1210 pci_restore_state(pdev);
1211
1212 err = pci_enable_device(pdev);
1213 if (err)
1214 return err;
1215
1216 pci_set_master(pdev);
1217
1218 pci_read_config_dword(pdev, 0x40, &val);
1219 if ((val & 0x0000ff00) != 0)
1220 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1221
1222 /*
1223 * done. driver will be put in up state
1224 * in brcms_ops_add_interface() call.
1225 */
1226 return err;
1227}
1228
1229/*
1230* called from both kernel as from this kernel module.
1231* precondition: perimeter lock is not acquired.
1232*/
1233static void brcms_remove(struct pci_dev *pdev)
1234{
1235 struct brcms_info *wl;
1236 struct ieee80211_hw *hw;
1237 int status;
1238
1239 hw = pci_get_drvdata(pdev);
1240 wl = HW_TO_WL(hw);
1241 if (!wl) {
1242 pr_err("wl: brcms_remove: pci_get_drvdata failed\n");
1243 return;
1244 }
1245
1246 LOCK(wl);
1247 status = brcms_c_chipmatch(pdev->vendor, pdev->device);
1248 UNLOCK(wl);
1249 if (!status) {
1250 wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch "
1251 "failed\n");
1252 return;
1253 }
1254 if (wl->wlc) {
1255 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
1256 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
1257 ieee80211_unregister_hw(hw);
1258 LOCK(wl);
1259 brcms_down(wl);
1260 UNLOCK(wl);
1261 }
1262 pci_disable_device(pdev);
1263
1264 brcms_free(wl);
1265
1266 pci_set_drvdata(pdev, NULL);
1267 ieee80211_free_hw(hw);
1268}
1269
1270static struct pci_driver brcms_pci_driver = {
1271 .name = KBUILD_MODNAME,
1272 .probe = brcms_pci_probe,
1273 .suspend = brcms_suspend,
1274 .resume = brcms_resume,
1275 .remove = __devexit_p(brcms_remove),
1276 .id_table = brcms_pci_id_table,
1277};
1278
1279/**
1280 * This is the main entry point for the WL driver.
1281 *
1282 * This function determines if a device pointed to by pdev is a WL device,
1283 * and if so, performs a brcms_attach() on it.
1284 *
1285 */
1286static int __init brcms_module_init(void)
1287{
1288 int error = -ENODEV;
1289
1290#ifdef BCMDBG
1291 if (msglevel != 0xdeadbeef)
1292 brcm_msg_level = msglevel;
1293 if (phymsglevel != 0xdeadbeef)
1294 phyhal_msg_level = phymsglevel;
1295#endif /* BCMDBG */
1296
1297 error = pci_register_driver(&brcms_pci_driver);
1298 if (!error)
1299 return 0;
1300
1301
1302
1303 return error;
1304}
1305
1306/**
1307 * This function unloads the WL driver from the system.
1308 *
1309 * This function unconditionally unloads the WL driver module from the
1310 * system.
1311 *
1312 */
1313static void __exit brcms_module_exit(void)
1314{
1315 pci_unregister_driver(&brcms_pci_driver);
1316
1317}
1318
1319module_init(brcms_module_init);
1320module_exit(brcms_module_exit);
1321
1322/**
1323 * This function frees the WL per-device resources.
1324 *
1325 * This function frees resources owned by the WL device pointed to
1326 * by the wl parameter.
1327 *
1328 * precondition: can both be called locked and unlocked
1329 *
1330 */
1331static void brcms_free(struct brcms_info *wl)
1332{
1333 struct brcms_timer *t, *next;
1334
1335 /* free ucode data */
1336 if (wl->fw.fw_cnt)
1337 brcms_ucode_data_free();
1338 if (wl->irq)
1339 free_irq(wl->irq, wl);
1340
1341 /* kill dpc */
1342 tasklet_kill(&wl->tasklet);
1343
1344 if (wl->pub) {
1345 brcms_c_module_unregister(wl->pub, "linux", wl);
1346 }
1347
1348 /* free common resources */
1349 if (wl->wlc) {
1350 brcms_c_detach(wl->wlc);
1351 wl->wlc = NULL;
1352 wl->pub = NULL;
1353 }
1354
1355 /* virtual interface deletion is deferred so we cannot spinwait */
1356
1357 /* wait for all pending callbacks to complete */
1358 while (atomic_read(&wl->callbacks) > 0)
1359 schedule();
1360
1361 /* free timers */
1362 for (t = wl->timers; t; t = next) {
1363 next = t->next;
1364#ifdef BCMDBG
1365 kfree(t->name);
1366#endif
1367 kfree(t);
1368 }
1369
1370 /*
1371 * unregister_netdev() calls get_stats() which may read chip registers
1372 * so we cannot unmap the chip registers until after calling unregister_netdev() .
1373 */
1374 if (wl->regsva && wl->bcm_bustype != SDIO_BUS &&
1375 wl->bcm_bustype != JTAG_BUS) {
1376 iounmap((void *)wl->regsva);
1377 }
1378 wl->regsva = NULL;
1379}
1380
1381/* flags the given rate in rateset as requested */
1382static void brcms_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br)
1383{
1384 u32 i;
1385
1386 for (i = 0; i < rs->count; i++) {
1387 if (rate != (rs->rates[i] & 0x7f))
1388 continue;
1389
1390 if (is_br)
1391 rs->rates[i] |= BRCMS_RATE_FLAG;
1392 else
1393 rs->rates[i] &= BRCMS_RATE_MASK;
1394 return;
1395 }
1396}
1397
1398/*
1399 * precondition: perimeter lock has been acquired
1400 */
1401void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
1402 bool state, int prio)
1403{
1404 wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
1405}
1406
1407/*
1408 * precondition: perimeter lock has been acquired
1409 */
1410void brcms_init(struct brcms_info *wl)
1411{
1412 BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit);
1413 brcms_reset(wl);
1414
1415 brcms_c_init(wl->wlc);
1416}
1417
1418/*
1419 * precondition: perimeter lock has been acquired
1420 */
1421uint brcms_reset(struct brcms_info *wl)
1422{
1423 BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit);
1424 brcms_c_reset(wl->wlc);
1425
1426 /* dpc will not be rescheduled */
1427 wl->resched = 0;
1428
1429 return 0;
1430}
1431
1432/*
1433 * These are interrupt on/off entry points. Disable interrupts
1434 * during interrupt state transition.
1435 */
1436void brcms_intrson(struct brcms_info *wl)
1437{
1438 unsigned long flags;
1439
1440 INT_LOCK(wl, flags);
1441 brcms_c_intrson(wl->wlc);
1442 INT_UNLOCK(wl, flags);
1443}
1444
1445/*
1446 * precondition: perimeter lock has been acquired
1447 */
1448bool wl_alloc_dma_resources(struct brcms_info *wl, uint addrwidth)
1449{
1450 return true;
1451}
1452
1453u32 brcms_intrsoff(struct brcms_info *wl)
1454{
1455 unsigned long flags;
1456 u32 status;
1457
1458 INT_LOCK(wl, flags);
1459 status = brcms_c_intrsoff(wl->wlc);
1460 INT_UNLOCK(wl, flags);
1461 return status;
1462}
1463
1464void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask)
1465{
1466 unsigned long flags;
1467
1468 INT_LOCK(wl, flags);
1469 brcms_c_intrsrestore(wl->wlc, macintmask);
1470 INT_UNLOCK(wl, flags);
1471}
1472
1473/*
1474 * precondition: perimeter lock has been acquired
1475 */
1476int brcms_up(struct brcms_info *wl)
1477{
1478 int error = 0;
1479
1480 if (wl->pub->up)
1481 return 0;
1482
1483 error = brcms_c_up(wl->wlc);
1484
1485 return error;
1486}
1487
1488/*
1489 * precondition: perimeter lock has been acquired
1490 */
1491void brcms_down(struct brcms_info *wl)
1492{
1493 uint callbacks, ret_val = 0;
1494
1495 /* call common down function */
1496 ret_val = brcms_c_down(wl->wlc);
1497 callbacks = atomic_read(&wl->callbacks) - ret_val;
1498
1499 /* wait for down callbacks to complete */
1500 UNLOCK(wl);
1501
1502 /* For HIGH_only driver, it's important to actually schedule other work,
1503 * not just spin wait since everything runs at schedule level
1504 */
1505 SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
1506
1507 LOCK(wl);
1508}
1509
1510static irqreturn_t brcms_isr(int irq, void *dev_id)
1511{
1512 struct brcms_info *wl;
1513 bool ours, wantdpc;
1514 unsigned long flags;
1515
1516 wl = (struct brcms_info *) dev_id;
1517
1518 ISR_LOCK(wl, flags);
1519
1520 /* call common first level interrupt handler */
1521 ours = brcms_c_isr(wl->wlc, &wantdpc);
1522 if (ours) {
1523 /* if more to do... */
1524 if (wantdpc) {
1525
1526 /* ...and call the second level interrupt handler */
1527 /* schedule dpc */
1528 tasklet_schedule(&wl->tasklet);
1529 }
1530 }
1531
1532 ISR_UNLOCK(wl, flags);
1533
1534 return IRQ_RETVAL(ours);
1535}
1536
1537static void brcms_dpc(unsigned long data)
1538{
1539 struct brcms_info *wl;
1540
1541 wl = (struct brcms_info *) data;
1542
1543 LOCK(wl);
1544
1545 /* call the common second level interrupt handler */
1546 if (wl->pub->up) {
1547 if (wl->resched) {
1548 unsigned long flags;
1549
1550 INT_LOCK(wl, flags);
1551 brcms_c_intrsupd(wl->wlc);
1552 INT_UNLOCK(wl, flags);
1553 }
1554
1555 wl->resched = brcms_c_dpc(wl->wlc, true);
1556 }
1557
1558 /* brcms_c_dpc() may bring the driver down */
1559 if (!wl->pub->up)
1560 goto done;
1561
1562 /* re-schedule dpc */
1563 if (wl->resched)
1564 tasklet_schedule(&wl->tasklet);
1565 else {
1566 /* re-enable interrupts */
1567 brcms_intrson(wl);
1568 }
1569
1570 done:
1571 UNLOCK(wl);
1572}
1573
1574/*
1575 * is called by the kernel from software irq context
1576 */
1577static void brcms_timer(unsigned long data)
1578{
1579 _brcms_timer((struct brcms_timer *) data);
1580}
1581
1582/*
1583* precondition: perimeter lock is not acquired
1584 */
1585static void _brcms_timer(struct brcms_timer *t)
1586{
1587 LOCK(t->wl);
1588
1589 if (t->set) {
1590 if (t->periodic) {
1591 t->timer.expires = jiffies + t->ms * HZ / 1000;
1592 atomic_inc(&t->wl->callbacks);
1593 add_timer(&t->timer);
1594 t->set = true;
1595 } else
1596 t->set = false;
1597
1598 t->fn(t->arg);
1599 }
1600
1601 atomic_dec(&t->wl->callbacks);
1602
1603 UNLOCK(t->wl);
1604}
1605
1606/*
1607 * Adds a timer to the list. Caller supplies a timer function.
1608 * Is called from wlc.
1609 *
1610 * precondition: perimeter lock has been acquired
1611 */
1612struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
1613 void (*fn) (void *arg),
1614 void *arg, const char *name)
1615{
1616 struct brcms_timer *t;
1617
1618 t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC);
1619 if (!t) {
1620 wiphy_err(wl->wiphy, "wl%d: brcms_init_timer: out of memory\n",
1621 wl->pub->unit);
1622 return 0;
1623 }
1624
1625 init_timer(&t->timer);
1626 t->timer.data = (unsigned long) t;
1627 t->timer.function = brcms_timer;
1628 t->wl = wl;
1629 t->fn = fn;
1630 t->arg = arg;
1631 t->next = wl->timers;
1632 wl->timers = t;
1633
1634#ifdef BCMDBG
1635 t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
1636 if (t->name)
1637 strcpy(t->name, name);
1638#endif
1639
1640 return t;
1641}
1642
1643/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
1644 * as well as it's easier to make it periodic
1645 *
1646 * precondition: perimeter lock has been acquired
1647 */
1648void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *t, uint ms,
1649 int periodic)
1650{
1651#ifdef BCMDBG
1652 if (t->set) {
1653 wiphy_err(wl->wiphy, "%s: Already set. Name: %s, per %d\n",
1654 __func__, t->name, periodic);
1655 }
1656#endif
1657 t->ms = ms;
1658 t->periodic = (bool) periodic;
1659 t->set = true;
1660 t->timer.expires = jiffies + ms * HZ / 1000;
1661
1662 atomic_inc(&wl->callbacks);
1663 add_timer(&t->timer);
1664}
1665
1666/*
1667 * return true if timer successfully deleted, false if still pending
1668 *
1669 * precondition: perimeter lock has been acquired
1670 */
1671bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *t)
1672{
1673 if (t->set) {
1674 t->set = false;
1675 if (!del_timer(&t->timer)) {
1676 return false;
1677 }
1678 atomic_dec(&wl->callbacks);
1679 }
1680
1681 return true;
1682}
1683
1684/*
1685 * precondition: perimeter lock has been acquired
1686 */
1687void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *t)
1688{
1689 struct brcms_timer *tmp;
1690
1691 /* delete the timer in case it is active */
1692 brcms_del_timer(wl, t);
1693
1694 if (wl->timers == t) {
1695 wl->timers = wl->timers->next;
1696#ifdef BCMDBG
1697 kfree(t->name);
1698#endif
1699 kfree(t);
1700 return;
1701
1702 }
1703
1704 tmp = wl->timers;
1705 while (tmp) {
1706 if (tmp->next == t) {
1707 tmp->next = t->next;
1708#ifdef BCMDBG
1709 kfree(t->name);
1710#endif
1711 kfree(t);
1712 return;
1713 }
1714 tmp = tmp->next;
1715 }
1716
1717}
1718
1719/*
1720 * runs in software irq context
1721 *
1722 * precondition: perimeter lock is not acquired
1723 */
1724static int wl_linux_watchdog(void *ctx)
1725{
1726 return 0;
1727}
1728
1729struct firmware_hdr {
1730 u32 offset;
1731 u32 len;
1732 u32 idx;
1733};
1734
1735char *brcms_firmwares[MAX_FW_IMAGES] = {
1736 "brcm/bcm43xx",
1737 NULL
1738};
1739
1740/*
1741 * precondition: perimeter lock has been acquired
1742 */
1743int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
1744{
1745 int i, entry;
1746 const u8 *pdata;
1747 struct firmware_hdr *hdr;
1748 for (i = 0; i < wl->fw.fw_cnt; i++) {
1749 hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
1750 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
1751 entry++, hdr++) {
1752 if (hdr->idx == idx) {
1753 pdata = wl->fw.fw_bin[i]->data + hdr->offset;
1754 *pbuf = kmalloc(hdr->len, GFP_ATOMIC);
1755 if (*pbuf == NULL) {
1756 wiphy_err(wl->wiphy, "fail to alloc %d"
1757 " bytes\n", hdr->len);
1758 goto fail;
1759 }
1760 memcpy(*pbuf, pdata, hdr->len);
1761 return 0;
1762 }
1763 }
1764 }
1765 wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
1766 idx);
1767 *pbuf = NULL;
1768fail:
1769 return -ENODATA;
1770}
1771
1772/*
1773 * Precondition: Since this function is called in brcms_pci_probe() context,
1774 * no locking is required.
1775 */
1776int brcms_ucode_init_uint(struct brcms_info *wl, u32 *data, u32 idx)
1777{
1778 int i, entry;
1779 const u8 *pdata;
1780 struct firmware_hdr *hdr;
1781 for (i = 0; i < wl->fw.fw_cnt; i++) {
1782 hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
1783 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
1784 entry++, hdr++) {
1785 if (hdr->idx == idx) {
1786 pdata = wl->fw.fw_bin[i]->data + hdr->offset;
1787 if (hdr->len != 4) {
1788 wiphy_err(wl->wiphy,
1789 "ERROR: fw hdr len\n");
1790 return -ENOMSG;
1791 }
1792 *data = *((u32 *) pdata);
1793 return 0;
1794 }
1795 }
1796 }
1797 wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
1798 return -ENOMSG;
1799}
1800
1801/*
1802 * Precondition: Since this function is called in brcms_pci_probe() context,
1803 * no locking is required.
1804 */
1805static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev)
1806{
1807 int status;
1808 struct device *device = &pdev->dev;
1809 char fw_name[100];
1810 int i;
1811
1812 memset((void *)&wl->fw, 0, sizeof(struct brcms_firmware));
1813 for (i = 0; i < MAX_FW_IMAGES; i++) {
1814 if (brcms_firmwares[i] == NULL)
1815 break;
1816 sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
1817 UCODE_LOADER_API_VER);
1818 status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
1819 if (status) {
1820 wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
1821 KBUILD_MODNAME, fw_name);
1822 return status;
1823 }
1824 sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
1825 UCODE_LOADER_API_VER);
1826 status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
1827 if (status) {
1828 wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
1829 KBUILD_MODNAME, fw_name);
1830 return status;
1831 }
1832 wl->fw.hdr_num_entries[i] =
1833 wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
1834 }
1835 wl->fw.fw_cnt = i;
1836 return brcms_ucode_data_init(wl);
1837}
1838
1839/*
1840 * precondition: can both be called locked and unlocked
1841 */
1842void brcms_ucode_free_buf(void *p)
1843{
1844 kfree(p);
1845}
1846
1847/*
1848 * Precondition: Since this function is called in brcms_pci_probe() context,
1849 * no locking is required.
1850 */
1851static void brcms_release_fw(struct brcms_info *wl)
1852{
1853 int i;
1854 for (i = 0; i < MAX_FW_IMAGES; i++) {
1855 release_firmware(wl->fw.fw_bin[i]);
1856 release_firmware(wl->fw.fw_hdr[i]);
1857 }
1858}
1859
1860
1861/*
1862 * checks validity of all firmware images loaded from user space
1863 *
1864 * Precondition: Since this function is called in brcms_pci_probe() context,
1865 * no locking is required.
1866 */
1867int brcms_check_firmwares(struct brcms_info *wl)
1868{
1869 int i;
1870 int entry;
1871 int rc = 0;
1872 const struct firmware *fw;
1873 const struct firmware *fw_hdr;
1874 struct firmware_hdr *ucode_hdr;
1875 for (i = 0; i < MAX_FW_IMAGES && rc == 0; i++) {
1876 fw = wl->fw.fw_bin[i];
1877 fw_hdr = wl->fw.fw_hdr[i];
1878 if (fw == NULL && fw_hdr == NULL) {
1879 break;
1880 } else if (fw == NULL || fw_hdr == NULL) {
1881 wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
1882 __func__);
1883 rc = -EBADF;
1884 } else if (fw_hdr->size % sizeof(struct firmware_hdr)) {
1885 wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
1886 "size %zu/%zu\n", __func__, fw_hdr->size,
1887 sizeof(struct firmware_hdr));
1888 rc = -EBADF;
1889 } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
1890 wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
1891 "%zu\n", __func__, fw->size);
1892 rc = -EBADF;
1893 } else {
1894 /* check if ucode section overruns firmware image */
1895 ucode_hdr = (struct firmware_hdr *)fw_hdr->data;
1896 for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
1897 !rc; entry++, ucode_hdr++) {
1898 if (ucode_hdr->offset + ucode_hdr->len >
1899 fw->size) {
1900 wiphy_err(wl->wiphy,
1901 "%s: conflicting bin/hdr\n",
1902 __func__);
1903 rc = -EBADF;
1904 }
1905 }
1906 }
1907 }
1908 if (rc == 0 && wl->fw.fw_cnt != i) {
1909 wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
1910 wl->fw.fw_cnt);
1911 rc = -EBADF;
1912 }
1913 return rc;
1914}
1915
1916/*
1917 * precondition: perimeter lock has been acquired
1918 */
1919bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
1920{
1921 bool blocked = brcms_c_check_radio_disabled(wl->wlc);
1922
1923 UNLOCK(wl);
1924 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
1925 if (blocked)
1926 wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy);
1927 LOCK(wl);
1928 return blocked;
1929}
1930
1931/*
1932 * precondition: perimeter lock has been acquired
1933 */
1934void brcms_msleep(struct brcms_info *wl, uint ms)
1935{
1936 UNLOCK(wl);
1937 msleep(ms);
1938 LOCK(wl);
1939}
diff --git a/drivers/staging/brcm80211/brcmsmac/mac80211_if.h b/drivers/staging/brcm80211/brcmsmac/mac80211_if.h
new file mode 100644
index 00000000000..3be8655c57e
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.h
@@ -0,0 +1,114 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_MAC80211_IF_H_
18#define _BRCM_MAC80211_IF_H_
19
20#include <linux/timer.h>
21#include <linux/interrupt.h>
22
23/*
24 * Starting index for 5G rates in the
25 * legacy rate table.
26 */
27#define BRCMS_LEGACY_5G_RATE_OFFSET 4
28
29/* softmac ioctl definitions */
30#define BRCMS_SET_SHORTSLOT_OVERRIDE 146
31
32
33/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and
34 * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be
35 * submitted to workqueue instead of being on kernel timer
36 */
37struct brcms_timer {
38 struct timer_list timer;
39 struct brcms_info *wl;
40 void (*fn) (void *);
41 void *arg; /* argument to fn */
42 uint ms;
43 bool periodic;
44 bool set;
45 struct brcms_timer *next;
46#ifdef BCMDBG
47 char *name; /* Description of the timer */
48#endif
49};
50
51struct brcms_if {
52 uint subunit; /* WDS/BSS unit */
53 struct pci_dev *pci_dev;
54};
55
56#define MAX_FW_IMAGES 4
57struct brcms_firmware {
58 u32 fw_cnt;
59 const struct firmware *fw_bin[MAX_FW_IMAGES];
60 const struct firmware *fw_hdr[MAX_FW_IMAGES];
61 u32 hdr_num_entries[MAX_FW_IMAGES];
62};
63
64struct brcms_info {
65 struct brcms_pub *pub; /* pointer to public wlc state */
66 void *wlc; /* pointer to private common os-independent data */
67 u32 magic;
68
69 int irq;
70
71 spinlock_t lock; /* per-device perimeter lock */
72 spinlock_t isr_lock; /* per-device ISR synchronization lock */
73
74 /* bus type and regsva for unmap in brcms_free() */
75 uint bcm_bustype; /* bus type */
76 void *regsva; /* opaque chip registers virtual address */
77
78 /* timer related fields */
79 atomic_t callbacks; /* # outstanding callback functions */
80 struct brcms_timer *timers; /* timer cleanup queue */
81
82 struct tasklet_struct tasklet; /* dpc tasklet */
83 bool resched; /* dpc needs to be and is rescheduled */
84#ifdef LINUXSTA_PS
85 u32 pci_psstate[16]; /* pci ps-state save/restore */
86#endif
87 struct brcms_firmware fw;
88 struct wiphy *wiphy;
89};
90
91/* misc callbacks */
92extern void brcms_init(struct brcms_info *wl);
93extern uint brcms_reset(struct brcms_info *wl);
94extern void brcms_intrson(struct brcms_info *wl);
95extern u32 brcms_intrsoff(struct brcms_info *wl);
96extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
97extern int brcms_up(struct brcms_info *wl);
98extern void brcms_down(struct brcms_info *wl);
99extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
100 bool state, int prio);
101extern bool wl_alloc_dma_resources(struct brcms_info *wl, uint dmaddrwidth);
102extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
103
104/* timer functions */
105extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
106 void (*fn) (void *arg), void *arg,
107 const char *name);
108extern void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *timer);
109extern void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *timer,
110 uint ms, int periodic);
111extern bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *timer);
112extern void brcms_msleep(struct brcms_info *wl, uint ms);
113
114#endif /* _BRCM_MAC80211_IF_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/main.c b/drivers/staging/brcm80211/brcmsmac/main.c
new file mode 100644
index 00000000000..96541630aad
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/main.c
@@ -0,0 +1,6110 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/pci_ids.h>
18#include <net/mac80211.h>
19
20#include <brcm_hw_ids.h>
21#include <aiutils.h>
22#include "rate.h"
23#include "scb.h"
24#include "phy/phy_hal.h"
25#include "channel.h"
26#include "bmac.h"
27#include "antsel.h"
28#include "stf.h"
29#include "ampdu.h"
30#include "alloc.h"
31#include "mac80211_if.h"
32#include "main.h"
33
34/*
35 * WPA(2) definitions
36 */
37#define RSN_CAP_4_REPLAY_CNTRS 2
38#define RSN_CAP_16_REPLAY_CNTRS 3
39
40#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS
41#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS
42
43/*
44 * Indication for txflowcontrol that all priority bits in
45 * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
46 */
47#define ALLPRIO -1
48
49/*
50 * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
51 */
52#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1)
53
54#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */
55#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */
56
57/* Max MPC timeout, in unit of watchdog */
58#ifndef BRCMS_MPC_MAX_DELAYCNT
59#define BRCMS_MPC_MAX_DELAYCNT 10
60#endif
61
62/* Min MPC timeout, in unit of watchdog */
63#define BRCMS_MPC_MIN_DELAYCNT 1
64#define BRCMS_MPC_THRESHOLD 3 /* MPC count threshold level */
65
66#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */
67#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */
68
69/* Scale down delays to accommodate QT slow speed */
70#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */
71#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */
72
73#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */
74
75/* Software feature flag defines used by wlfeatureflag */
76#define WL_SWFL_NOHWRADIO 0x0004
77#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */
78#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */
79
80/* n-mode support capability */
81/* 2x2 includes both 1x1 & 2x2 devices
82 * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
83 * control it independently
84 */
85#define WL_11N_2x2 1
86#define WL_11N_3x3 3
87#define WL_11N_4x4 4
88
89/* define 11n feature disable flags */
90#define WLFEATURE_DISABLE_11N 0x00000001
91#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002
92#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004
93#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008
94#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010
95#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020
96#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040
97#define WLFEATURE_DISABLE_11N_GF 0x00000080
98
99#define EDCF_ACI_MASK 0x60
100#define EDCF_ACI_SHIFT 5
101#define EDCF_ECWMIN_MASK 0x0f
102#define EDCF_ECWMAX_SHIFT 4
103#define EDCF_AIFSN_MASK 0x0f
104#define EDCF_AIFSN_MAX 15
105#define EDCF_ECWMAX_MASK 0xf0
106
107#define EDCF_AC_BE_TXOP_STA 0x0000
108#define EDCF_AC_BK_TXOP_STA 0x0000
109#define EDCF_AC_VO_ACI_STA 0x62
110#define EDCF_AC_VO_ECW_STA 0x32
111#define EDCF_AC_VI_ACI_STA 0x42
112#define EDCF_AC_VI_ECW_STA 0x43
113#define EDCF_AC_BK_ECW_STA 0xA4
114#define EDCF_AC_VI_TXOP_STA 0x005e
115#define EDCF_AC_VO_TXOP_STA 0x002f
116#define EDCF_AC_BE_ACI_STA 0x03
117#define EDCF_AC_BE_ECW_STA 0xA4
118#define EDCF_AC_BK_ACI_STA 0x27
119#define EDCF_AC_VO_TXOP_AP 0x002f
120
121#define EDCF_TXOP2USEC(txop) ((txop) << 5)
122#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1)
123
124#define APHY_SYMBOL_TIME 4
125#define APHY_PREAMBLE_TIME 16
126#define APHY_SIGNAL_TIME 4
127#define APHY_SIFS_TIME 16
128#define APHY_SERVICE_NBITS 16
129#define APHY_TAIL_NBITS 6
130#define BPHY_SIFS_TIME 10
131#define BPHY_PLCP_SHORT_TIME 96
132
133#define PREN_PREAMBLE 24
134#define PREN_MM_EXT 12
135#define PREN_PREAMBLE_EXT 4
136
137#define DOT11_MAC_HDR_LEN 24
138#define DOT11_ACK_LEN 10
139#define DOT11_BA_LEN 4
140#define DOT11_OFDM_SIGNAL_EXTENSION 6
141#define DOT11_MIN_FRAG_LEN 256
142#define DOT11_RTS_LEN 16
143#define DOT11_CTS_LEN 10
144#define DOT11_BA_BITMAP_LEN 128
145#define DOT11_MIN_BEACON_PERIOD 1
146#define DOT11_MAX_BEACON_PERIOD 0xFFFF
147#define DOT11_MAXNUMFRAGS 16
148#define DOT11_MAX_FRAG_LEN 2346
149
150#define BPHY_PLCP_TIME 192
151#define RIFS_11N_TIME 2
152
153#define WME_VER 1
154#define WME_SUBTYPE_PARAM_IE 1
155#define WME_TYPE 2
156#define WME_OUI "\x00\x50\xf2"
157
158#define AC_BE 0
159#define AC_BK 1
160#define AC_VI 2
161#define AC_VO 3
162
163/*
164 * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft
165 * watchdog) it is not a wall clock and won't increment when driver is in "down" state
166 * this low resolution driver tick can be used for maintenance tasks such as phy
167 * calibration and scb update
168 */
169
170/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */
171#define BCMCFID(wlc, fid) brcms_b_write_shm((wlc)->hw, M_BCMC_FID, (fid))
172
173#define BRCMS_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \
174 (!AP_ENAB(wlc->pub)) && (wlc->war16165))
175
176/* debug/trace */
177uint brcm_msg_level =
178#if defined(BCMDBG)
179 LOG_ERROR_VAL;
180#else
181 0;
182#endif /* BCMDBG */
183
184/* Find basic rate for a given rate */
185#define BRCMS_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \
186 (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \
187 (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK])
188
189#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM))
190
191#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */
192
193#define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */
194
195#define SCAN_IN_PROGRESS(x) 0
196
197#define EPI_VERSION_NUM 0x054b0b00
198
199#ifdef BCMDBG
200/* pointer to most recently allocated wl/wlc */
201static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
202#endif
203
204const u8 prio2fifo[NUMPRIO] = {
205 TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */
206 TX_AC_BK_FIFO, /* 1 BK AC_BK Background */
207 TX_AC_BK_FIFO, /* 2 -- AC_BK Background */
208 TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */
209 TX_AC_VI_FIFO, /* 4 CL AC_VI Video */
210 TX_AC_VI_FIFO, /* 5 VI AC_VI Video */
211 TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */
212 TX_AC_VO_FIFO /* 7 NC AC_VO Voice */
213};
214
215/* precedences numbers for wlc queues. These are twice as may levels as
216 * 802.1D priorities.
217 * Odd numbers are used for HI priority traffic at same precedence levels
218 * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere.
219 */
220#define _BRCMS_PREC_NONE 0 /* None = - */
221#define _BRCMS_PREC_BK 2 /* BK - Background */
222#define _BRCMS_PREC_BE 4 /* BE - Best-effort */
223#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */
224#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */
225#define _BRCMS_PREC_VI 10 /* Vi - Video */
226#define _BRCMS_PREC_VO 12 /* Vo - Voice */
227#define _BRCMS_PREC_NC 14 /* NC - Network Control */
228
229#define MAXMACLIST 64 /* max # source MAC matches */
230#define BCN_TEMPLATE_COUNT 2
231
232/* The BSS is generating beacons in HW */
233#define BRCMS_BSSCFG_HW_BCN 0x20
234
235#define HWBCN_ENAB(cfg) (((cfg)->flags & BRCMS_BSSCFG_HW_BCN) != 0)
236
237#define MBSS_BCN_ENAB(cfg) 0
238#define MBSS_PRB_ENAB(cfg) 0
239#define SOFTBCN_ENAB(pub) (0)
240
241/* 802.1D Priority to precedence queue mapping */
242const u8 wlc_prio2prec_map[] = {
243 _BRCMS_PREC_BE, /* 0 BE - Best-effort */
244 _BRCMS_PREC_BK, /* 1 BK - Background */
245 _BRCMS_PREC_NONE, /* 2 None = - */
246 _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */
247 _BRCMS_PREC_CL, /* 4 CL - Controlled Load */
248 _BRCMS_PREC_VI, /* 5 Vi - Video */
249 _BRCMS_PREC_VO, /* 6 Vo - Voice */
250 _BRCMS_PREC_NC, /* 7 NC - Network Control */
251};
252
253/* Check if a particular BSS config is AP or STA */
254#define BSSCFG_AP(cfg) (0)
255#define BSSCFG_STA(cfg) (1)
256#define BSSCFG_IBSS(cfg) (!(cfg)->BSS)
257
258/* As above for all non-NULL BSS configs */
259#define FOREACH_BSS(wlc, idx, cfg) \
260 for (idx = 0; (int) idx < BRCMS_MAXBSSCFG; idx++) \
261 if ((cfg = (wlc)->bsscfg[idx]))
262
263/* TX FIFO number to WME/802.1E Access Category */
264const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };
265
266/* WME/802.1E Access Category to TX FIFO number */
267static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 };
268
269static bool in_send_q;
270
271/* Shared memory location index for various AC params */
272#define wme_shmemacindex(ac) wme_ac2fifo[ac]
273
274#ifdef BCMDBG
275static const char * const fifo_names[] = {
276 "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
277#else
278static const char fifo_names[6][0];
279#endif
280
281static const u8 acbitmap2maxprio[] = {
282 PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK,
283 PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI,
284 PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO,
285 PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO
286};
287
288/* currently the best mechanism for determining SIFS is the band in use */
289#define SIFS(band) ((band)->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME : \
290 BPHY_SIFS_TIME);
291
292/* local prototypes */
293static u16 brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc,
294 struct ieee80211_hw *hw,
295 struct sk_buff *p,
296 struct scb *scb, uint frag,
297 uint nfrags, uint queue,
298 uint next_frag_len,
299 struct wsec_key *key,
300 ratespec_t rspec_override);
301static void brcms_c_bss_default_init(struct brcms_c_info *wlc);
302static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc);
303static ratespec_t mac80211_wlc_set_nrate(struct brcms_c_info *wlc,
304 struct brcms_band *cur_band,
305 u32 int_val);
306static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc);
307static void brcms_c_watchdog(void *arg);
308static void brcms_c_watchdog_by_timer(void *arg);
309static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate);
310static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg);
311static u8 brcms_c_local_constraint_qdbm(struct brcms_c_info *wlc);
312
313/* send and receive */
314static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc);
315static void brcms_c_txq_free(struct brcms_c_info *wlc,
316 struct brcms_txq_info *qi);
317static void brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
318 struct brcms_txq_info *qi,
319 bool on, int prio);
320static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc);
321static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rate,
322 uint length, u8 *plcp);
323static void brcms_c_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp);
324static void brcms_c_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp);
325static u16 brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate,
326 u8 preamble_type, uint next_frag_len);
327static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
328 struct brcms_d11rxhdr *rxh);
329static void brcms_c_recvctl(struct brcms_c_info *wlc,
330 struct d11rxhdr *rxh, struct sk_buff *p);
331static uint brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t rate,
332 u8 preamble_type, uint dur);
333static uint brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rate,
334 u8 preamble_type);
335static uint brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rate,
336 u8 preamble_type);
337/* interrupt, up/down, band */
338static void brcms_c_setband(struct brcms_c_info *wlc, uint bandunit);
339static chanspec_t brcms_c_init_chanspec(struct brcms_c_info *wlc);
340static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
341 chanspec_t chanspec);
342static void brcms_c_bsinit(struct brcms_c_info *wlc);
343static int brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle,
344 bool isOFDM, bool writeToShm);
345static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc);
346static bool brcms_c_radio_monitor_start(struct brcms_c_info *wlc);
347static void brcms_c_radio_timer(void *arg);
348static void brcms_c_radio_enable(struct brcms_c_info *wlc);
349static void brcms_c_radio_upd(struct brcms_c_info *wlc);
350
351/* scan, association, BSS */
352static uint brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rate,
353 u8 preamble_type);
354static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap);
355static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val);
356static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val);
357static void brcms_c_war16165(struct brcms_c_info *wlc, bool tx);
358
359static void brcms_c_wme_retries_write(struct brcms_c_info *wlc);
360static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc);
361static uint brcms_c_attach_module(struct brcms_c_info *wlc);
362static void brcms_c_detach_module(struct brcms_c_info *wlc);
363static void brcms_c_timers_deinit(struct brcms_c_info *wlc);
364static void brcms_c_down_led_upd(struct brcms_c_info *wlc);
365static uint brcms_c_down_del_timer(struct brcms_c_info *wlc);
366static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc);
367static int _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len,
368 struct brcms_c_if *wlcif);
369
370/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful
371 */
372bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
373{
374 int idx;
375 struct brcms_bss_cfg *cfg;
376
377 /* disallow PS when one of the following global conditions meets */
378 if (!wlc->pub->associated)
379 return false;
380
381 /* disallow PS when one of these meets when not scanning */
382 if (AP_ACTIVE(wlc) || wlc->monitor)
383 return false;
384
385 for (idx = 0; idx < BRCMS_MAXBSSCFG; idx++) {
386 cfg = wlc->bsscfg[idx];
387 if (cfg && BSSCFG_STA(cfg) && cfg->associated) {
388 /*
389 * disallow PS when one of the following
390 * bsscfg specific conditions meets
391 */
392 if (!cfg->BSS || !BRCMS_PORTOPEN(cfg))
393 return false;
394
395 if (!cfg->dtim_programmed)
396 return false;
397 }
398 }
399
400 return true;
401}
402
403void brcms_c_reset(struct brcms_c_info *wlc)
404{
405 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
406
407 /* slurp up hw mac counters before core reset */
408 brcms_c_statsupd(wlc);
409
410 /* reset our snapshot of macstat counters */
411 memset((char *)wlc->core->macstat_snapshot, 0,
412 sizeof(struct macstat));
413
414 brcms_b_reset(wlc->hw);
415}
416
417void brcms_c_fatal_error(struct brcms_c_info *wlc)
418{
419 wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
420 wlc->pub->unit);
421 brcms_init(wlc->wl);
422}
423
424/* Return the channel the driver should initialize during brcms_c_init.
425 * the channel may have to be changed from the currently configured channel
426 * if other configurations are in conflict (bandlocked, 11n mode disabled,
427 * invalid channel for current country, etc.)
428 */
429static chanspec_t brcms_c_init_chanspec(struct brcms_c_info *wlc)
430{
431 chanspec_t chanspec =
432 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
433 WL_CHANSPEC_BAND_2G;
434
435 return chanspec;
436}
437
438struct scb global_scb;
439
440static void brcms_c_init_scb(struct brcms_c_info *wlc, struct scb *scb)
441{
442 int i;
443 scb->flags = SCB_WMECAP | SCB_HTCAP;
444 for (i = 0; i < NUMPRIO; i++)
445 scb->seqnum[i] = 0;
446}
447
448void brcms_c_init(struct brcms_c_info *wlc)
449{
450 d11regs_t *regs;
451 chanspec_t chanspec;
452 int i;
453 struct brcms_bss_cfg *bsscfg;
454 bool mute = false;
455
456 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
457
458 regs = wlc->regs;
459
460 /* This will happen if a big-hammer was executed. In that case, we want to go back
461 * to the channel that we were on and not new channel
462 */
463 if (wlc->pub->associated)
464 chanspec = wlc->home_chanspec;
465 else
466 chanspec = brcms_c_init_chanspec(wlc);
467
468 brcms_b_init(wlc->hw, chanspec, mute);
469
470 /* update beacon listen interval */
471 brcms_c_bcn_li_upd(wlc);
472
473 /* the world is new again, so is our reported rate */
474 brcms_c_reprate_init(wlc);
475
476 /* write ethernet address to core */
477 FOREACH_BSS(wlc, i, bsscfg) {
478 brcms_c_set_mac(bsscfg);
479 brcms_c_set_bssid(bsscfg);
480 }
481
482 /* Update tsf_cfprep if associated and up */
483 if (wlc->pub->associated) {
484 FOREACH_BSS(wlc, i, bsscfg) {
485 if (bsscfg->up) {
486 u32 bi;
487
488 /* get beacon period and convert to uS */
489 bi = bsscfg->current_bss->beacon_period << 10;
490 /*
491 * update since init path would reset
492 * to default value
493 */
494 W_REG(&regs->tsf_cfprep,
495 (bi << CFPREP_CBI_SHIFT));
496
497 /* Update maccontrol PM related bits */
498 brcms_c_set_ps_ctrl(wlc);
499
500 break;
501 }
502 }
503 }
504
505 brcms_c_bandinit_ordered(wlc, chanspec);
506
507 brcms_c_init_scb(wlc, &global_scb);
508
509 /* init probe response timeout */
510 brcms_c_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout);
511
512 /* init max burst txop (framebursting) */
513 brcms_c_write_shm(wlc, M_MBURST_TXOP,
514 (wlc->
515 _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
516
517 /* initialize maximum allowed duty cycle */
518 brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
519 brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
520
521 /* Update some shared memory locations related to max AMPDU size allowed to received */
522 brcms_c_ampdu_shm_upd(wlc->ampdu);
523
524 /* band-specific inits */
525 brcms_c_bsinit(wlc);
526
527 /* Enable EDCF mode (while the MAC is suspended) */
528 if (EDCF_ENAB(wlc->pub)) {
529 OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
530 brcms_c_edcf_setparams(wlc, false);
531 }
532
533 /* Init precedence maps for empty FIFOs */
534 brcms_c_tx_prec_map_init(wlc);
535
536 /* read the ucode version if we have not yet done so */
537 if (wlc->ucode_rev == 0) {
538 wlc->ucode_rev =
539 brcms_c_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16);
540 wlc->ucode_rev |= brcms_c_read_shm(wlc, M_BOM_REV_MINOR);
541 }
542
543 /* ..now really unleash hell (allow the MAC out of suspend) */
544 brcms_c_enable_mac(wlc);
545
546 /* clear tx flow control */
547 brcms_c_txflowcontrol_reset(wlc);
548
549 /* clear tx data fifo suspends */
550 wlc->tx_suspended = false;
551
552 /* enable the RF Disable Delay timer */
553 W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
554
555 /* initialize mpc delay */
556 wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
557
558 /*
559 * Initialize WME parameters; if they haven't been set by some other
560 * mechanism (IOVar, etc) then read them from the hardware.
561 */
562 if (BRCMS_WME_RETRY_SHORT_GET(wlc, 0) == 0) {
563 /* Uninitialized; read from HW */
564 int ac;
565
566 for (ac = 0; ac < AC_COUNT; ac++) {
567 wlc->wme_retries[ac] =
568 brcms_c_read_shm(wlc, M_AC_TXLMT_ADDR(ac));
569 }
570 }
571}
572
573void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc)
574{
575 wlc->bcnmisc_monitor = promisc;
576 brcms_c_mac_bcn_promisc(wlc);
577}
578
579void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc)
580{
581 if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) ||
582 wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor)
583 brcms_c_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
584 else
585 brcms_c_mctrl(wlc, MCTL_BCNS_PROMISC, 0);
586}
587
588/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
589void brcms_c_mac_promisc(struct brcms_c_info *wlc)
590{
591 u32 promisc_bits = 0;
592
593 /* promiscuous mode just sets MCTL_PROMISC
594 * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit
595 * since all BSS data traffic is directed at the AP
596 */
597 if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub))
598 promisc_bits |= MCTL_PROMISC;
599
600 /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
601 * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
602 * handled in brcms_c_mac_bcn_promisc()
603 */
604 if (MONITOR_ENAB(wlc))
605 promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
606
607 brcms_c_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
608}
609
610/* push sw hps and wake state through hardware */
611void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
612{
613 u32 v1, v2;
614 bool hps;
615 bool awake_before;
616
617 hps = PS_ALLOWED(wlc);
618
619 BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
620
621 v1 = R_REG(&wlc->regs->maccontrol);
622 v2 = MCTL_WAKE;
623 if (hps)
624 v2 |= MCTL_HPS;
625
626 brcms_c_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2);
627
628 awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
629
630 if (!awake_before)
631 brcms_b_wait_for_wake(wlc->hw);
632
633}
634
635/*
636 * Write this BSS config's MAC address to core.
637 * Updates RXE match engine.
638 */
639int brcms_c_set_mac(struct brcms_bss_cfg *cfg)
640{
641 int err = 0;
642 struct brcms_c_info *wlc = cfg->wlc;
643
644 if (cfg == wlc->cfg) {
645 /* enter the MAC addr into the RXE match registers */
646 brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr);
647 }
648
649 brcms_c_ampdu_macaddr_upd(wlc);
650
651 return err;
652}
653
654/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
655 * Updates RXE match engine.
656 */
657void brcms_c_set_bssid(struct brcms_bss_cfg *cfg)
658{
659 struct brcms_c_info *wlc = cfg->wlc;
660
661 /* if primary config, we need to update BSSID in RXE match registers */
662 if (cfg == wlc->cfg) {
663 brcms_c_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID);
664 }
665#ifdef SUPPORT_HWKEYS
666 else if (BSSCFG_STA(cfg) && cfg->BSS) {
667 brcms_c_rcmta_add_bssid(wlc, cfg);
668 }
669#endif
670}
671
672/*
673 * Suspend the the MAC and update the slot timing
674 * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
675 */
676void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
677{
678 int idx;
679 struct brcms_bss_cfg *cfg;
680
681 /* use the override if it is set */
682 if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
683 shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON);
684
685 if (wlc->shortslot == shortslot)
686 return;
687
688 wlc->shortslot = shortslot;
689
690 /* update the capability based on current shortslot mode */
691 FOREACH_BSS(wlc, idx, cfg) {
692 if (!cfg->associated)
693 continue;
694 cfg->current_bss->capability &=
695 ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
696 if (wlc->shortslot)
697 cfg->current_bss->capability |=
698 WLAN_CAPABILITY_SHORT_SLOT_TIME;
699 }
700
701 brcms_b_set_shortslot(wlc->hw, shortslot);
702}
703
704static u8 brcms_c_local_constraint_qdbm(struct brcms_c_info *wlc)
705{
706 u8 local;
707 s16 local_max;
708
709 local = BRCMS_TXPWR_MAX;
710 if (wlc->pub->associated &&
711 (brcmu_chspec_ctlchan(wlc->chanspec) ==
712 brcmu_chspec_ctlchan(wlc->home_chanspec))) {
713
714 /* get the local power constraint if we are on the AP's
715 * channel [802.11h, 7.3.2.13]
716 */
717 /* Clamp the value between 0 and BRCMS_TXPWR_MAX w/o
718 * overflowing the target */
719 local_max =
720 (wlc->txpwr_local_max -
721 wlc->txpwr_local_constraint) * BRCMS_TXPWR_DB_FACTOR;
722 if (local_max > 0 && local_max < BRCMS_TXPWR_MAX)
723 return (u8) local_max;
724 if (local_max < 0)
725 return 0;
726 }
727
728 return local;
729}
730
731/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */
732void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec)
733{
734 if (wlc->home_chanspec != chanspec) {
735 int idx;
736 struct brcms_bss_cfg *cfg;
737
738 wlc->home_chanspec = chanspec;
739
740 FOREACH_BSS(wlc, idx, cfg) {
741 if (!cfg->associated)
742 continue;
743
744 cfg->current_bss->chanspec = chanspec;
745 }
746
747 }
748}
749
750static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
751 chanspec_t chanspec)
752{
753 /* Save our copy of the chanspec */
754 wlc->chanspec = chanspec;
755
756 /* Set the chanspec and power limits for this locale after computing
757 * any 11h local tx power constraints.
758 */
759 brcms_c_channel_set_chanspec(wlc->cmi, chanspec,
760 brcms_c_local_constraint_qdbm(wlc));
761
762 if (wlc->stf->ss_algosel_auto)
763 brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
764 chanspec);
765
766 brcms_c_stf_ss_update(wlc, wlc->band);
767
768}
769
770void brcms_c_set_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec)
771{
772 uint bandunit;
773 bool switchband = false;
774 chanspec_t old_chanspec = wlc->chanspec;
775
776 if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
777 wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
778 wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
779 return;
780 }
781
782 /* Switch bands if necessary */
783 if (NBANDS(wlc) > 1) {
784 bandunit = CHSPEC_BANDUNIT(chanspec);
785 if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
786 switchband = true;
787 if (wlc->bandlocked) {
788 wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
789 "band is locked!\n",
790 wlc->pub->unit, __func__,
791 CHSPEC_CHANNEL(chanspec));
792 return;
793 }
794 /*
795 * should the setband call come after the
796 * brcms_b_chanspec() ? if the setband updates
797 * (brcms_c_bsinit) use low level calls to inspect and
798 * set state, the state inspected may be from the wrong
799 * band, or the following brcms_b_set_chanspec() may
800 * undo the work.
801 */
802 brcms_c_setband(wlc, bandunit);
803 }
804 }
805
806 /* sync up phy/radio chanspec */
807 brcms_c_set_phy_chanspec(wlc, chanspec);
808
809 /* init antenna selection */
810 if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) {
811 brcms_c_antsel_init(wlc->asi);
812
813 /* Fix the hardware rateset based on bw.
814 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
815 */
816 brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
817 wlc->band->
818 mimo_cap_40 ? CHSPEC_WLC_BW(chanspec)
819 : 0);
820 }
821
822 /* update some mac configuration since chanspec changed */
823 brcms_c_ucode_mac_upd(wlc);
824}
825
826ratespec_t brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc,
827 wlc_rateset_t *rs)
828{
829 ratespec_t lowest_basic_rspec;
830 uint i;
831
832 /* Use the lowest basic rate */
833 lowest_basic_rspec = rs->rates[0] & BRCMS_RATE_MASK;
834 for (i = 0; i < rs->count; i++) {
835 if (rs->rates[i] & BRCMS_RATE_FLAG) {
836 lowest_basic_rspec = rs->rates[i] & BRCMS_RATE_MASK;
837 break;
838 }
839 }
840#if NCONF
841 /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */
842 if (IS_OFDM(lowest_basic_rspec)) {
843 lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
844 }
845#endif
846
847 return lowest_basic_rspec;
848}
849
850/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant
851 * setting as per this table:
852 * ratespec CCK ant = wlc->stf->txant
853 * OFDM ant = 3
854 */
855void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
856 ratespec_t bcn_rspec)
857{
858 u16 phyctl;
859 u16 phytxant = wlc->stf->phytxant;
860 u16 mask = PHY_TXC_ANT_MASK;
861
862 /* for non-siso rates or default setting, use the available chains */
863 if (BRCMS_PHY_11N_CAP(wlc->band))
864 phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec);
865
866 phyctl = brcms_c_read_shm(wlc, M_BCN_PCTLWD);
867 phyctl = (phyctl & ~mask) | phytxant;
868 brcms_c_write_shm(wlc, M_BCN_PCTLWD, phyctl);
869}
870
871/* centralized protection config change function to simplify debugging, no consistency checking
872 * this should be called only on changes to avoid overhead in periodic function
873*/
874void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
875{
876 BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
877
878 switch (idx) {
879 case BRCMS_PROT_G_SPEC:
880 wlc->protection->_g = (bool) val;
881 break;
882 case BRCMS_PROT_G_OVR:
883 wlc->protection->g_override = (s8) val;
884 break;
885 case BRCMS_PROT_G_USER:
886 wlc->protection->gmode_user = (u8) val;
887 break;
888 case BRCMS_PROT_OVERLAP:
889 wlc->protection->overlap = (s8) val;
890 break;
891 case BRCMS_PROT_N_USER:
892 wlc->protection->nmode_user = (s8) val;
893 break;
894 case BRCMS_PROT_N_CFG:
895 wlc->protection->n_cfg = (s8) val;
896 break;
897 case BRCMS_PROT_N_CFG_OVR:
898 wlc->protection->n_cfg_override = (s8) val;
899 break;
900 case BRCMS_PROT_N_NONGF:
901 wlc->protection->nongf = (bool) val;
902 break;
903 case BRCMS_PROT_N_NONGF_OVR:
904 wlc->protection->nongf_override = (s8) val;
905 break;
906 case BRCMS_PROT_N_PAM_OVR:
907 wlc->protection->n_pam_override = (s8) val;
908 break;
909 case BRCMS_PROT_N_OBSS:
910 wlc->protection->n_obss = (bool) val;
911 break;
912
913 default:
914 break;
915 }
916
917}
918
919static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
920{
921 wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 |
922 IEEE80211_HT_CAP_SGI_40);
923 wlc->ht_cap.cap_info |= (val & BRCMS_N_SGI_20) ?
924 IEEE80211_HT_CAP_SGI_20 : 0;
925 wlc->ht_cap.cap_info |= (val & BRCMS_N_SGI_40) ?
926 IEEE80211_HT_CAP_SGI_40 : 0;
927
928 if (wlc->pub->up) {
929 brcms_c_update_beacon(wlc);
930 brcms_c_update_probe_resp(wlc, true);
931 }
932}
933
934static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
935{
936 wlc->stf->ldpc = val;
937
938 wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING;
939 if (wlc->stf->ldpc != OFF)
940 wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
941
942 if (wlc->pub->up) {
943 brcms_c_update_beacon(wlc);
944 brcms_c_update_probe_resp(wlc, true);
945 wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
946 }
947}
948
949/*
950 * ucode, hwmac update
951 * Channel dependent updates for ucode and hw
952 */
953static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
954{
955 /* enable or disable any active IBSSs depending on whether or not
956 * we are on the home channel
957 */
958 if (wlc->home_chanspec == BRCMS_BAND_PI_RADIO_CHANSPEC) {
959 if (wlc->pub->associated) {
960 /* BMAC_NOTE: This is something that should be fixed in ucode inits.
961 * I think that the ucode inits set up the bcn templates and shm values
962 * with a bogus beacon. This should not be done in the inits. If ucode needs
963 * to set up a beacon for testing, the test routines should write it down,
964 * not expect the inits to populate a bogus beacon.
965 */
966 if (BRCMS_PHY_11N_CAP(wlc->band)) {
967 brcms_c_write_shm(wlc, M_BCN_TXTSF_OFFSET,
968 wlc->band->bcntsfoff);
969 }
970 }
971 } else {
972 /* disable an active IBSS if we are not on the home channel */
973 }
974
975 /* update the various promisc bits */
976 brcms_c_mac_bcn_promisc(wlc);
977 brcms_c_mac_promisc(wlc);
978}
979
980static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
981 chanspec_t chanspec)
982{
983 wlc_rateset_t default_rateset;
984 uint parkband;
985 uint i, band_order[2];
986
987 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
988 /*
989 * We might have been bandlocked during down and the chip power-cycled (hibernate).
990 * figure out the right band to park on
991 */
992 if (wlc->bandlocked || NBANDS(wlc) == 1) {
993 /* updated in brcms_c_bandlock() */
994 parkband = wlc->band->bandunit;
995 band_order[0] = band_order[1] = parkband;
996 } else {
997 /* park on the band of the specified chanspec */
998 parkband = CHSPEC_BANDUNIT(chanspec);
999
1000 /* order so that parkband initialize last */
1001 band_order[0] = parkband ^ 1;
1002 band_order[1] = parkband;
1003 }
1004
1005 /* make each band operational, software state init */
1006 for (i = 0; i < NBANDS(wlc); i++) {
1007 uint j = band_order[i];
1008
1009 wlc->band = wlc->bandstate[j];
1010
1011 brcms_default_rateset(wlc, &default_rateset);
1012
1013 /* fill in hw_rate */
1014 brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
1015 false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
1016 (bool) N_ENAB(wlc->pub));
1017
1018 /* init basic rate lookup */
1019 brcms_c_rate_lookup_init(wlc, &default_rateset);
1020 }
1021
1022 /* sync up phy/radio chanspec */
1023 brcms_c_set_phy_chanspec(wlc, chanspec);
1024}
1025
1026/* band-specific init */
1027static void brcms_c_bsinit(struct brcms_c_info *wlc)
1028{
1029 BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
1030 wlc->pub->unit, wlc->band->bandunit);
1031
1032 /* write ucode ACK/CTS rate table */
1033 brcms_c_set_ratetable(wlc);
1034
1035 /* update some band specific mac configuration */
1036 brcms_c_ucode_mac_upd(wlc);
1037
1038 /* init antenna selection */
1039 brcms_c_antsel_init(wlc->asi);
1040
1041}
1042
1043/* switch to and initialize new band */
1044static void brcms_c_setband(struct brcms_c_info *wlc,
1045 uint bandunit)
1046{
1047 int idx;
1048 struct brcms_bss_cfg *cfg;
1049
1050 wlc->band = wlc->bandstate[bandunit];
1051
1052 if (!wlc->pub->up)
1053 return;
1054
1055 /* wait for at least one beacon before entering sleeping state */
1056 for (idx = 0; idx < BRCMS_MAXBSSCFG; idx++) {
1057 cfg = wlc->bsscfg[idx];
1058 if (cfg && BSSCFG_STA(cfg) && cfg->associated)
1059 cfg->PMawakebcn = true;
1060 }
1061 brcms_c_set_ps_ctrl(wlc);
1062
1063 /* band-specific initializations */
1064 brcms_c_bsinit(wlc);
1065}
1066
1067/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */
1068void
1069brcms_c_wme_initparams_sta(struct brcms_c_info *wlc, struct wme_param_ie *pe)
1070{
1071 static const struct wme_param_ie stadef = {
1072 WME_OUI,
1073 WME_TYPE,
1074 WME_SUBTYPE_PARAM_IE,
1075 WME_VER,
1076 0,
1077 0,
1078 {
1079 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA,
1080 cpu_to_le16(EDCF_AC_BE_TXOP_STA)},
1081 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA,
1082 cpu_to_le16(EDCF_AC_BK_TXOP_STA)},
1083 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA,
1084 cpu_to_le16(EDCF_AC_VI_TXOP_STA)},
1085 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA,
1086 cpu_to_le16(EDCF_AC_VO_TXOP_STA)}
1087 }
1088 };
1089 memcpy(pe, &stadef, sizeof(*pe));
1090}
1091
1092void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
1093 const struct ieee80211_tx_queue_params *params,
1094 bool suspend)
1095{
1096 int i;
1097 struct shm_acparams acp_shm;
1098 u16 *shm_entry;
1099
1100 /* Only apply params if the core is out of reset and has clocks */
1101 if (!wlc->clk) {
1102 wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
1103 __func__);
1104 return;
1105 }
1106
1107 do {
1108 memset((char *)&acp_shm, 0, sizeof(struct shm_acparams));
1109 /* fill in shm ac params struct */
1110 acp_shm.txop = le16_to_cpu(params->txop);
1111 /* convert from units of 32us to us for ucode */
1112 wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
1113 EDCF_TXOP2USEC(acp_shm.txop);
1114 acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
1115
1116 if (aci == AC_VI && acp_shm.txop == 0
1117 && acp_shm.aifs < EDCF_AIFSN_MAX)
1118 acp_shm.aifs++;
1119
1120 if (acp_shm.aifs < EDCF_AIFSN_MIN
1121 || acp_shm.aifs > EDCF_AIFSN_MAX) {
1122 wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad "
1123 "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
1124 continue;
1125 }
1126
1127 acp_shm.cwmin = params->cw_min;
1128 acp_shm.cwmax = params->cw_max;
1129 acp_shm.cwcur = acp_shm.cwmin;
1130 acp_shm.bslots =
1131 R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
1132 acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
1133 /* Indicate the new params to the ucode */
1134 acp_shm.status = brcms_c_read_shm(wlc, (M_EDCF_QINFO +
1135 wme_shmemacindex(aci) *
1136 M_EDCF_QLEN +
1137 M_EDCF_STATUS_OFF));
1138 acp_shm.status |= WME_STATUS_NEWAC;
1139
1140 /* Fill in shm acparam table */
1141 shm_entry = (u16 *) &acp_shm;
1142 for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2)
1143 brcms_c_write_shm(wlc,
1144 M_EDCF_QINFO +
1145 wme_shmemacindex(aci) * M_EDCF_QLEN + i,
1146 *shm_entry++);
1147
1148 } while (0);
1149
1150 if (suspend)
1151 brcms_c_suspend_mac_and_wait(wlc);
1152
1153 if (suspend)
1154 brcms_c_enable_mac(wlc);
1155
1156}
1157
1158void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
1159{
1160 u16 aci;
1161 int i_ac;
1162 struct edcf_acparam *edcf_acp;
1163
1164 struct ieee80211_tx_queue_params txq_pars;
1165 struct ieee80211_tx_queue_params *params = &txq_pars;
1166
1167 /*
1168 * AP uses AC params from wme_param_ie_ap.
1169 * AP advertises AC params from wme_param_ie.
1170 * STA uses AC params from wme_param_ie.
1171 */
1172
1173 edcf_acp = (struct edcf_acparam *) &wlc->wme_param_ie.acparam[0];
1174
1175 for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) {
1176 /* find out which ac this set of params applies to */
1177 aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
1178
1179 /* fill in shm ac params struct */
1180 params->txop = edcf_acp->TXOP;
1181 params->aifs = edcf_acp->ACI;
1182
1183 /* CWmin = 2^(ECWmin) - 1 */
1184 params->cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
1185 /* CWmax = 2^(ECWmax) - 1 */
1186 params->cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
1187 >> EDCF_ECWMAX_SHIFT);
1188 brcms_c_wme_setparams(wlc, aci, params, suspend);
1189 }
1190
1191 if (suspend)
1192 brcms_c_suspend_mac_and_wait(wlc);
1193
1194 if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) {
1195 brcms_c_update_beacon(wlc);
1196 brcms_c_update_probe_resp(wlc, false);
1197 }
1198
1199 if (suspend)
1200 brcms_c_enable_mac(wlc);
1201
1202}
1203
1204bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
1205{
1206 wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
1207 wlc, "watchdog");
1208 if (!wlc->wdtimer) {
1209 wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for wdtimer "
1210 "failed\n", unit);
1211 goto fail;
1212 }
1213
1214 wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer,
1215 wlc, "radio");
1216 if (!wlc->radio_timer) {
1217 wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for radio_timer "
1218 "failed\n", unit);
1219 goto fail;
1220 }
1221
1222 return true;
1223
1224 fail:
1225 return false;
1226}
1227
1228/*
1229 * Initialize brcms_c_info default values ...
1230 * may get overrides later in this function
1231 */
1232void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
1233{
1234 int i;
1235 /* Assume the device is there until proven otherwise */
1236 wlc->device_present = true;
1237
1238 /* Save our copy of the chanspec */
1239 wlc->chanspec = CH20MHZ_CHSPEC(1);
1240
1241 /* various 802.11g modes */
1242 wlc->shortslot = false;
1243 wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO;
1244
1245 brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO);
1246 brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false);
1247
1248 brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR,
1249 BRCMS_PROTECTION_AUTO);
1250 brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF);
1251 brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR,
1252 BRCMS_PROTECTION_AUTO);
1253 brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false);
1254 brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO);
1255
1256 brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP,
1257 BRCMS_PROTECTION_CTL_OVERLAP);
1258
1259 /* 802.11g draft 4.0 NonERP elt advertisement */
1260 wlc->include_legacy_erp = true;
1261
1262 wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
1263 wlc->stf->txant = ANT_TX_DEF;
1264
1265 wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT;
1266
1267 wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
1268 for (i = 0; i < NFIFO; i++)
1269 wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
1270 wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
1271
1272 /* default rate fallback retry limits */
1273 wlc->SFBL = RETRY_SHORT_FB;
1274 wlc->LFBL = RETRY_LONG_FB;
1275
1276 /* default mac retry limits */
1277 wlc->SRL = RETRY_SHORT_DEF;
1278 wlc->LRL = RETRY_LONG_DEF;
1279
1280 /* Set flag to indicate that hw keys should be used when available. */
1281 wlc->wsec_swkeys = false;
1282
1283 /* init the 4 static WEP default keys */
1284 for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
1285 wlc->wsec_keys[i] = wlc->wsec_def_keys[i];
1286 wlc->wsec_keys[i]->idx = (u8) i;
1287 }
1288
1289 /* WME QoS mode is Auto by default */
1290 wlc->pub->_wme = AUTO;
1291
1292#ifdef BCMSDIODEV_ENABLED
1293 wlc->pub->_priofc = true; /* enable priority flow control for sdio dongle */
1294#endif
1295
1296 wlc->pub->_ampdu = AMPDU_AGG_HOST;
1297 wlc->pub->bcmerror = 0;
1298 wlc->pub->_coex = ON;
1299
1300 /* initialize mpc delay */
1301 wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
1302}
1303
1304static bool brcms_c_state_bmac_sync(struct brcms_c_info *wlc)
1305{
1306 struct brcms_b_state state_bmac;
1307
1308 if (brcms_b_state_get(wlc->hw, &state_bmac) != 0)
1309 return false;
1310
1311 wlc->machwcap = state_bmac.machwcap;
1312 brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR,
1313 (s8) state_bmac.preamble_ovr);
1314
1315 return true;
1316}
1317
1318static uint brcms_c_attach_module(struct brcms_c_info *wlc)
1319{
1320 uint err = 0;
1321 uint unit;
1322 unit = wlc->pub->unit;
1323
1324 wlc->asi = brcms_c_antsel_attach(wlc);
1325 if (wlc->asi == NULL) {
1326 wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach "
1327 "failed\n", unit);
1328 err = 44;
1329 goto fail;
1330 }
1331
1332 wlc->ampdu = brcms_c_ampdu_attach(wlc);
1333 if (wlc->ampdu == NULL) {
1334 wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach "
1335 "failed\n", unit);
1336 err = 50;
1337 goto fail;
1338 }
1339
1340 if ((brcms_c_stf_attach(wlc) != 0)) {
1341 wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach "
1342 "failed\n", unit);
1343 err = 68;
1344 goto fail;
1345 }
1346 fail:
1347 return err;
1348}
1349
1350struct brcms_pub *brcms_c_pub(void *wlc)
1351{
1352 return ((struct brcms_c_info *) wlc)->pub;
1353}
1354
1355#define CHIP_SUPPORTS_11N(wlc) 1
1356
1357/*
1358 * The common driver entry routine. Error codes should be unique
1359 */
1360void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
1361 bool piomode, void *regsva, uint bustype, void *btparam,
1362 uint *perr)
1363{
1364 struct brcms_c_info *wlc;
1365 uint err = 0;
1366 uint j;
1367 struct brcms_pub *pub;
1368 uint n_disabled;
1369
1370 /* allocate struct brcms_c_info state and its substructures */
1371 wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, device);
1372 if (wlc == NULL)
1373 goto fail;
1374 wlc->wiphy = wl->wiphy;
1375 pub = wlc->pub;
1376
1377#if defined(BCMDBG)
1378 wlc_info_dbg = wlc;
1379#endif
1380
1381 wlc->band = wlc->bandstate[0];
1382 wlc->core = wlc->corestate;
1383 wlc->wl = wl;
1384 pub->unit = unit;
1385 pub->_piomode = piomode;
1386 wlc->bandinit_pending = false;
1387
1388 /* populate struct brcms_c_info with default values */
1389 brcms_c_info_init(wlc, unit);
1390
1391 /* update sta/ap related parameters */
1392 brcms_c_ap_upd(wlc);
1393
1394 /* 11n_disable nvram */
1395 n_disabled = getintvar(pub->vars, "11n_disable");
1396
1397 /*
1398 * low level attach steps(all hw accesses go
1399 * inside, no more in rest of the attach)
1400 */
1401 err = brcms_b_attach(wlc, vendor, device, unit, piomode, regsva,
1402 bustype, btparam);
1403 if (err)
1404 goto fail;
1405
1406 /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split,
1407 * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver
1408 */
1409 if (!brcms_c_state_bmac_sync(wlc)) {
1410 err = 20;
1411 goto fail;
1412 }
1413
1414 pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
1415
1416 /* propagate *vars* from BMAC driver to high driver */
1417 brcms_b_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size);
1418
1419
1420 /* set maximum allowed duty cycle */
1421 wlc->tx_duty_cycle_ofdm =
1422 (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm");
1423 wlc->tx_duty_cycle_cck =
1424 (u16) getintvar(pub->vars, "tx_duty_cycle_cck");
1425
1426 brcms_c_stf_phy_chain_calc(wlc);
1427
1428 /* txchain 1: txant 0, txchain 2: txant 1 */
1429 if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
1430 wlc->stf->txant = wlc->stf->hw_txchain - 1;
1431
1432 /* push to BMAC driver */
1433 wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
1434 wlc->stf->hw_rxchain);
1435
1436 /* pull up some info resulting from the low attach */
1437 {
1438 int i;
1439 for (i = 0; i < NFIFO; i++)
1440 wlc->core->txavail[i] = wlc->hw->txavail[i];
1441 }
1442
1443 brcms_b_hw_etheraddr(wlc->hw, wlc->perm_etheraddr);
1444
1445 memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN);
1446
1447 for (j = 0; j < NBANDS(wlc); j++) {
1448 /* Use band 1 for single band 11a */
1449 if (IS_SINGLEBAND_5G(wlc->deviceid))
1450 j = BAND_5G_INDEX;
1451
1452 wlc->band = wlc->bandstate[j];
1453
1454 if (!brcms_c_attach_stf_ant_init(wlc)) {
1455 err = 24;
1456 goto fail;
1457 }
1458
1459 /* default contention windows size limits */
1460 wlc->band->CWmin = APHY_CWMIN;
1461 wlc->band->CWmax = PHY_CWMAX;
1462
1463 /* init gmode value */
1464 if (BAND_2G(wlc->band->bandtype)) {
1465 wlc->band->gmode = GMODE_AUTO;
1466 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
1467 wlc->band->gmode);
1468 }
1469
1470 /* init _n_enab supported mode */
1471 if (BRCMS_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) {
1472 if (n_disabled & WLFEATURE_DISABLE_11N) {
1473 pub->_n_enab = OFF;
1474 brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
1475 OFF);
1476 } else {
1477 pub->_n_enab = SUPPORT_11N;
1478 brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
1479 ((pub->_n_enab ==
1480 SUPPORT_11N) ? WL_11N_2x2 :
1481 WL_11N_3x3));
1482 }
1483 }
1484
1485 /* init per-band default rateset, depend on band->gmode */
1486 brcms_default_rateset(wlc, &wlc->band->defrateset);
1487
1488 /* fill in hw_rateset (used early by BRCM_SET_RATESET) */
1489 brcms_c_rateset_filter(&wlc->band->defrateset,
1490 &wlc->band->hw_rateset, false,
1491 BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
1492 (bool) N_ENAB(wlc->pub));
1493 }
1494
1495 /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */
1496 brcms_c_stf_phy_txant_upd(wlc);
1497
1498 /* attach each modules */
1499 err = brcms_c_attach_module(wlc);
1500 if (err != 0)
1501 goto fail;
1502
1503 if (!brcms_c_timers_init(wlc, unit)) {
1504 wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
1505 __func__);
1506 err = 32;
1507 goto fail;
1508 }
1509
1510 /* depend on rateset, gmode */
1511 wlc->cmi = brcms_c_channel_mgr_attach(wlc);
1512 if (!wlc->cmi) {
1513 wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
1514 "\n", unit, __func__);
1515 err = 33;
1516 goto fail;
1517 }
1518
1519 /* init default when all parameters are ready, i.e. ->rateset */
1520 brcms_c_bss_default_init(wlc);
1521
1522 /*
1523 * Complete the wlc default state initializations..
1524 */
1525
1526 /* allocate our initial queue */
1527 wlc->pkt_queue = brcms_c_txq_alloc(wlc);
1528 if (wlc->pkt_queue == NULL) {
1529 wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
1530 unit, __func__);
1531 err = 100;
1532 goto fail;
1533 }
1534
1535 wlc->bsscfg[0] = wlc->cfg;
1536 wlc->cfg->_idx = 0;
1537 wlc->cfg->wlc = wlc;
1538 pub->txmaxpkts = MAXTXPKTS;
1539
1540 brcms_c_wme_initparams_sta(wlc, &wlc->wme_param_ie);
1541
1542 wlc->mimoft = FT_HT;
1543 wlc->ht_cap.cap_info = HT_CAP;
1544 if (HT_ENAB(wlc->pub))
1545 wlc->stf->ldpc = AUTO;
1546
1547 wlc->mimo_40txbw = AUTO;
1548 wlc->ofdm_40txbw = AUTO;
1549 wlc->cck_40txbw = AUTO;
1550 brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
1551
1552 /* Set default values of SGI */
1553 if (BRCMS_SGI_CAP_PHY(wlc)) {
1554 brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
1555 BRCMS_N_SGI_40));
1556 wlc->sgi_tx = AUTO;
1557 } else if (BRCMS_ISSSLPNPHY(wlc->band)) {
1558 brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
1559 BRCMS_N_SGI_40));
1560 wlc->sgi_tx = AUTO;
1561 } else {
1562 brcms_c_ht_update_sgi_rx(wlc, 0);
1563 wlc->sgi_tx = OFF;
1564 }
1565
1566 /* *******nvram 11n config overrides Start ********* */
1567
1568 /* apply the sgi override from nvram conf */
1569 if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX)
1570 wlc->sgi_tx = OFF;
1571
1572 if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX)
1573 brcms_c_ht_update_sgi_rx(wlc, 0);
1574
1575 /* apply the stbc override from nvram conf */
1576 if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) {
1577 wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
1578 wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
1579 wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
1580 }
1581 if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX)
1582 brcms_c_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO);
1583
1584 /* apply the GF override from nvram conf */
1585 if (n_disabled & WLFEATURE_DISABLE_11N_GF)
1586 wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD;
1587
1588 /* initialize radio_mpc_disable according to wlc->mpc */
1589 brcms_c_radio_mpc_upd(wlc);
1590 brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
1591
1592 if (perr)
1593 *perr = 0;
1594
1595 return (void *)wlc;
1596
1597 fail:
1598 wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
1599 unit, __func__, err);
1600 if (wlc)
1601 brcms_c_detach(wlc);
1602
1603 if (perr)
1604 *perr = err;
1605 return NULL;
1606}
1607
1608static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
1609{
1610 uint unit;
1611 unit = wlc->pub->unit;
1612
1613 if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
1614 /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
1615 wlc->band->antgain = 8;
1616 } else if (wlc->band->antgain == -1) {
1617 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
1618 " srom, using 2dB\n", unit, __func__);
1619 wlc->band->antgain = 8;
1620 } else {
1621 s8 gain, fract;
1622 /* Older sroms specified gain in whole dbm only. In order
1623 * be able to specify qdbm granularity and remain backward compatible
1624 * the whole dbms are now encoded in only low 6 bits and remaining qdbms
1625 * are encoded in the hi 2 bits. 6 bit signed number ranges from
1626 * -32 - 31. Examples: 0x1 = 1 db,
1627 * 0xc1 = 1.75 db (1 + 3 quarters),
1628 * 0x3f = -1 (-1 + 0 quarters),
1629 * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm.
1630 * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm.
1631 */
1632 gain = wlc->band->antgain & 0x3f;
1633 gain <<= 2; /* Sign extend */
1634 gain >>= 2;
1635 fract = (wlc->band->antgain & 0xc0) >> 6;
1636 wlc->band->antgain = 4 * gain + fract;
1637 }
1638}
1639
1640static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
1641{
1642 int aa;
1643 uint unit;
1644 char *vars;
1645 int bandtype;
1646
1647 unit = wlc->pub->unit;
1648 vars = wlc->pub->vars;
1649 bandtype = wlc->band->bandtype;
1650
1651 /* get antennas available */
1652 aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g"));
1653 if (aa == 0)
1654 aa = (s8) getintvar(vars,
1655 (BAND_5G(bandtype) ? "aa1" : "aa0"));
1656 if ((aa < 1) || (aa > 15)) {
1657 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
1658 " srom (0x%x), using 3\n", unit, __func__, aa);
1659 aa = 3;
1660 }
1661
1662 /* reset the defaults if we have a single antenna */
1663 if (aa == 1) {
1664 wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
1665 wlc->stf->txant = ANT_TX_FORCE_0;
1666 } else if (aa == 2) {
1667 wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
1668 wlc->stf->txant = ANT_TX_FORCE_1;
1669 } else {
1670 }
1671
1672 /* Compute Antenna Gain */
1673 wlc->band->antgain =
1674 (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0"));
1675 brcms_c_attach_antgain_init(wlc);
1676
1677 return true;
1678}
1679
1680
1681static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
1682{
1683 /* free timer state */
1684 if (wlc->wdtimer) {
1685 brcms_free_timer(wlc->wl, wlc->wdtimer);
1686 wlc->wdtimer = NULL;
1687 }
1688 if (wlc->radio_timer) {
1689 brcms_free_timer(wlc->wl, wlc->radio_timer);
1690 wlc->radio_timer = NULL;
1691 }
1692}
1693
1694static void brcms_c_detach_module(struct brcms_c_info *wlc)
1695{
1696 if (wlc->asi) {
1697 brcms_c_antsel_detach(wlc->asi);
1698 wlc->asi = NULL;
1699 }
1700
1701 if (wlc->ampdu) {
1702 brcms_c_ampdu_detach(wlc->ampdu);
1703 wlc->ampdu = NULL;
1704 }
1705
1706 brcms_c_stf_detach(wlc);
1707}
1708
1709/*
1710 * Return a count of the number of driver callbacks still pending.
1711 *
1712 * General policy is that brcms_c_detach can only dealloc/free software states.
1713 * It can NOT touch hardware registers since the d11core may be in reset and
1714 * clock may not be available.
1715 * One exception is sb register access, which is possible if crystal is turned
1716 * on after "down" state, driver should avoid software timer with the exception
1717 * of radio_monitor.
1718 */
1719uint brcms_c_detach(struct brcms_c_info *wlc)
1720{
1721 uint callbacks = 0;
1722
1723 if (wlc == NULL)
1724 return 0;
1725
1726 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
1727
1728 callbacks += brcms_b_detach(wlc);
1729
1730 /* delete software timers */
1731 if (!brcms_c_radio_monitor_stop(wlc))
1732 callbacks++;
1733
1734 brcms_c_channel_mgr_detach(wlc->cmi);
1735
1736 brcms_c_timers_deinit(wlc);
1737
1738 brcms_c_detach_module(wlc);
1739
1740
1741 while (wlc->tx_queues != NULL)
1742 brcms_c_txq_free(wlc, wlc->tx_queues);
1743
1744 brcms_c_detach_mfree(wlc);
1745 return callbacks;
1746}
1747
1748/* update state that depends on the current value of "ap" */
1749void brcms_c_ap_upd(struct brcms_c_info *wlc)
1750{
1751 if (AP_ENAB(wlc->pub))
1752 /* AP: short not allowed, but not enforced */
1753 wlc->PLCPHdr_override = BRCMS_PLCP_AUTO;
1754 else
1755 /* STA-BSS; short capable */
1756 wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
1757
1758 /* fixup mpc */
1759 wlc->mpc = true;
1760}
1761
1762/* read hwdisable state and propagate to wlc flag */
1763static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
1764{
1765 if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off)
1766 return;
1767
1768 if (brcms_b_radio_read_hwdisabled(wlc->hw)) {
1769 mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
1770 } else {
1771 mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
1772 }
1773}
1774
1775/* return true if Minimum Power Consumption should be entered, false otherwise */
1776bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc)
1777{
1778 return false;
1779}
1780
1781bool brcms_c_ismpc(struct brcms_c_info *wlc)
1782{
1783 return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc));
1784}
1785
1786void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc)
1787{
1788 bool mpc_radio, radio_state;
1789
1790 /*
1791 * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
1792 * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
1793 * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
1794 * the radio is going down.
1795 */
1796 if (!wlc->mpc) {
1797 if (!wlc->pub->radio_disabled)
1798 return;
1799 mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
1800 brcms_c_radio_upd(wlc);
1801 if (!wlc->pub->radio_disabled)
1802 brcms_c_radio_monitor_stop(wlc);
1803 return;
1804 }
1805
1806 /*
1807 * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled
1808 * to go ON, always call radio_upd synchronously
1809 * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog)
1810 */
1811 radio_state =
1812 (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
1813 ON);
1814 mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON;
1815
1816 if (radio_state == ON && mpc_radio == OFF)
1817 wlc->mpc_delay_off = wlc->mpc_dlycnt;
1818 else if (radio_state == OFF && mpc_radio == ON) {
1819 mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
1820 brcms_c_radio_upd(wlc);
1821 if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD)
1822 wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT;
1823 else
1824 wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
1825 wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts;
1826 }
1827 /* Below logic is meant to capture the transition from mpc off to mpc on for reasons
1828 * other than wlc->mpc_delay_off keeping the mpc off. In that case reset
1829 * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
1830 */
1831 if ((wlc->prev_non_delay_mpc == false) &&
1832 (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) {
1833 wlc->mpc_delay_off = wlc->mpc_dlycnt;
1834 }
1835 wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc);
1836}
1837
1838/*
1839 * centralized radio disable/enable function,
1840 * invoke radio enable/disable after updating hwradio status
1841 */
1842static void brcms_c_radio_upd(struct brcms_c_info *wlc)
1843{
1844 if (wlc->pub->radio_disabled) {
1845 brcms_c_radio_disable(wlc);
1846 } else {
1847 brcms_c_radio_enable(wlc);
1848 }
1849}
1850
1851/* maintain LED behavior in down state */
1852static void brcms_c_down_led_upd(struct brcms_c_info *wlc)
1853{
1854 /* maintain LEDs while in down state, turn on sbclk if not available yet */
1855 /* turn on sbclk if necessary */
1856 if (!AP_ENAB(wlc->pub)) {
1857 brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_FLIP);
1858
1859 brcms_c_pllreq(wlc, false, BRCMS_PLLREQ_FLIP);
1860 }
1861}
1862
1863/* update hwradio status and return it */
1864bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
1865{
1866 brcms_c_radio_hwdisable_upd(wlc);
1867
1868 return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false;
1869}
1870
1871void brcms_c_radio_disable(struct brcms_c_info *wlc)
1872{
1873 if (!wlc->pub->up) {
1874 brcms_c_down_led_upd(wlc);
1875 return;
1876 }
1877
1878 brcms_c_radio_monitor_start(wlc);
1879 brcms_down(wlc->wl);
1880}
1881
1882static void brcms_c_radio_enable(struct brcms_c_info *wlc)
1883{
1884 if (wlc->pub->up)
1885 return;
1886
1887 if (DEVICEREMOVED(wlc))
1888 return;
1889
1890 brcms_up(wlc->wl);
1891}
1892
1893/* periodical query hw radio button while driver is "down" */
1894static void brcms_c_radio_timer(void *arg)
1895{
1896 struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
1897
1898 if (DEVICEREMOVED(wlc)) {
1899 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
1900 __func__);
1901 brcms_down(wlc->wl);
1902 return;
1903 }
1904
1905 /* cap mpc off count */
1906 if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT)
1907 wlc->mpc_offcnt++;
1908
1909 brcms_c_radio_hwdisable_upd(wlc);
1910 brcms_c_radio_upd(wlc);
1911}
1912
1913static bool brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
1914{
1915 /* Don't start the timer if HWRADIO feature is disabled */
1916 if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO))
1917 return true;
1918
1919 wlc->radio_monitor = true;
1920 brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_RADIO_MON);
1921 brcms_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK,
1922 true);
1923 return true;
1924}
1925
1926bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
1927{
1928 if (!wlc->radio_monitor)
1929 return true;
1930
1931 wlc->radio_monitor = false;
1932 brcms_c_pllreq(wlc, false, BRCMS_PLLREQ_RADIO_MON);
1933 return brcms_del_timer(wlc->wl, wlc->radio_timer);
1934}
1935
1936static void brcms_c_watchdog_by_timer(void *arg)
1937{
1938 brcms_c_watchdog(arg);
1939}
1940
1941/* common watchdog code */
1942static void brcms_c_watchdog(void *arg)
1943{
1944 struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
1945 int i;
1946 struct brcms_bss_cfg *cfg;
1947
1948 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
1949
1950 if (!wlc->pub->up)
1951 return;
1952
1953 if (DEVICEREMOVED(wlc)) {
1954 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
1955 __func__);
1956 brcms_down(wlc->wl);
1957 return;
1958 }
1959
1960 /* increment second count */
1961 wlc->pub->now++;
1962
1963 /* delay radio disable */
1964 if (wlc->mpc_delay_off) {
1965 if (--wlc->mpc_delay_off == 0) {
1966 mboolset(wlc->pub->radio_disabled,
1967 WL_RADIO_MPC_DISABLE);
1968 if (wlc->mpc && brcms_c_ismpc(wlc))
1969 wlc->mpc_offcnt = 0;
1970 wlc->mpc_laston_ts = OSL_SYSUPTIME();
1971 }
1972 }
1973
1974 /* mpc sync */
1975 brcms_c_radio_mpc_upd(wlc);
1976 /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
1977 brcms_c_radio_hwdisable_upd(wlc);
1978 brcms_c_radio_upd(wlc);
1979 /* if radio is disable, driver may be down, quit here */
1980 if (wlc->pub->radio_disabled)
1981 return;
1982
1983 brcms_b_watchdog(wlc);
1984
1985 /* occasionally sample mac stat counters to detect 16-bit counter wrap */
1986 if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
1987 brcms_c_statsupd(wlc);
1988
1989 /* Manage TKIP countermeasures timers */
1990 FOREACH_BSS(wlc, i, cfg) {
1991 if (cfg->tk_cm_dt) {
1992 cfg->tk_cm_dt--;
1993 }
1994 if (cfg->tk_cm_bt) {
1995 cfg->tk_cm_bt--;
1996 }
1997 }
1998
1999 /* Call any registered watchdog handlers */
2000 for (i = 0; i < BRCMS_MAXMODULES; i++) {
2001 if (wlc->modulecb[i].watchdog_fn)
2002 wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl);
2003 }
2004
2005 if (BRCMS_ISNPHY(wlc->band) && !wlc->pub->tempsense_disable &&
2006 ((wlc->pub->now - wlc->tempsense_lasttime) >=
2007 BRCMS_TEMPSENSE_PERIOD)) {
2008 wlc->tempsense_lasttime = wlc->pub->now;
2009 brcms_c_tempsense_upd(wlc);
2010 }
2011}
2012
2013/* make interface operational */
2014int brcms_c_up(struct brcms_c_info *wlc)
2015{
2016 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
2017
2018 /* HW is turned off so don't try to access it */
2019 if (wlc->pub->hw_off || DEVICEREMOVED(wlc))
2020 return -ENOMEDIUM;
2021
2022 if (!wlc->pub->hw_up) {
2023 brcms_b_hw_up(wlc->hw);
2024 wlc->pub->hw_up = true;
2025 }
2026
2027 if ((wlc->pub->boardflags & BFL_FEM)
2028 && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) {
2029 if (wlc->pub->boardrev >= 0x1250
2030 && (wlc->pub->boardflags & BFL_FEM_BT)) {
2031 brcms_c_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL,
2032 MHF5_4313_GPIOCTRL, BRCM_BAND_ALL);
2033 } else {
2034 brcms_c_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE,
2035 MHF4_EXTPA_ENABLE, BRCM_BAND_ALL);
2036 }
2037 }
2038
2039 /*
2040 * Need to read the hwradio status here to cover the case where the system
2041 * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
2042 * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS)
2043 * don't call radio_update to avoid looping brcms_c_up.
2044 *
2045 * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
2046 */
2047 if (!wlc->pub->radio_disabled) {
2048 int status = brcms_b_up_prep(wlc->hw);
2049 if (status == -ENOMEDIUM) {
2050 if (!mboolisset
2051 (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
2052 int idx;
2053 struct brcms_bss_cfg *bsscfg;
2054 mboolset(wlc->pub->radio_disabled,
2055 WL_RADIO_HW_DISABLE);
2056
2057 FOREACH_BSS(wlc, idx, bsscfg) {
2058 if (!BSSCFG_STA(bsscfg)
2059 || !bsscfg->enable || !bsscfg->BSS)
2060 continue;
2061 wiphy_err(wlc->wiphy, "wl%d.%d: up"
2062 ": rfdisable -> "
2063 "bsscfg_disable()\n",
2064 wlc->pub->unit, idx);
2065 }
2066 }
2067 }
2068 }
2069
2070 if (wlc->pub->radio_disabled) {
2071 brcms_c_radio_monitor_start(wlc);
2072 return 0;
2073 }
2074
2075 /* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
2076 wlc->clk = true;
2077
2078 brcms_c_radio_monitor_stop(wlc);
2079
2080 /* Set EDCF hostflags */
2081 if (EDCF_ENAB(wlc->pub)) {
2082 brcms_c_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL);
2083 } else {
2084 brcms_c_mhf(wlc, MHF1, MHF1_EDCF, 0, BRCM_BAND_ALL);
2085 }
2086
2087 if (BRCMS_WAR16165(wlc))
2088 brcms_c_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR,
2089 BRCM_BAND_ALL);
2090
2091 brcms_init(wlc->wl);
2092 wlc->pub->up = true;
2093
2094 if (wlc->bandinit_pending) {
2095 brcms_c_suspend_mac_and_wait(wlc);
2096 brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
2097 wlc->bandinit_pending = false;
2098 brcms_c_enable_mac(wlc);
2099 }
2100
2101 brcms_b_up_finish(wlc->hw);
2102
2103 /* other software states up after ISR is running */
2104 /* start APs that were to be brought up but are not up yet */
2105 /* if (AP_ENAB(wlc->pub)) brcms_c_restart_ap(wlc->ap); */
2106
2107 /* Program the TX wme params with the current settings */
2108 brcms_c_wme_retries_write(wlc);
2109
2110 /* start one second watchdog timer */
2111 brcms_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
2112 wlc->WDarmed = true;
2113
2114 /* ensure antenna config is up to date */
2115 brcms_c_stf_phy_txant_upd(wlc);
2116 /* ensure LDPC config is in sync */
2117 brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc);
2118
2119 return 0;
2120}
2121
2122/* Initialize the base precedence map for dequeueing from txq based on WME settings */
2123static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
2124{
2125 wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
2126 memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
2127
2128 /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences
2129 * if either is full.
2130 */
2131 if (!EDCF_ENAB(wlc->pub)) {
2132 wlc->fifo2prec_map[TX_DATA_FIFO] = BRCMS_PREC_BMP_ALL;
2133 wlc->fifo2prec_map[TX_CTL_FIFO] = BRCMS_PREC_BMP_ALL;
2134 } else {
2135 wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
2136 wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
2137 wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
2138 wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
2139 }
2140}
2141
2142static uint brcms_c_down_del_timer(struct brcms_c_info *wlc)
2143{
2144 uint callbacks = 0;
2145
2146 return callbacks;
2147}
2148
2149/*
2150 * Mark the interface nonoperational, stop the software mechanisms,
2151 * disable the hardware, free any transient buffer state.
2152 * Return a count of the number of driver callbacks still pending.
2153 */
2154uint brcms_c_down(struct brcms_c_info *wlc)
2155{
2156
2157 uint callbacks = 0;
2158 int i;
2159 bool dev_gone = false;
2160 struct brcms_txq_info *qi;
2161
2162 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
2163
2164 /* check if we are already in the going down path */
2165 if (wlc->going_down) {
2166 wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
2167 "\n", wlc->pub->unit, __func__);
2168 return 0;
2169 }
2170 if (!wlc->pub->up)
2171 return callbacks;
2172
2173 /* in between, mpc could try to bring down again.. */
2174 wlc->going_down = true;
2175
2176 callbacks += brcms_b_bmac_down_prep(wlc->hw);
2177
2178 dev_gone = DEVICEREMOVED(wlc);
2179
2180 /* Call any registered down handlers */
2181 for (i = 0; i < BRCMS_MAXMODULES; i++) {
2182 if (wlc->modulecb[i].down_fn)
2183 callbacks +=
2184 wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
2185 }
2186
2187 /* cancel the watchdog timer */
2188 if (wlc->WDarmed) {
2189 if (!brcms_del_timer(wlc->wl, wlc->wdtimer))
2190 callbacks++;
2191 wlc->WDarmed = false;
2192 }
2193 /* cancel all other timers */
2194 callbacks += brcms_c_down_del_timer(wlc);
2195
2196 wlc->pub->up = false;
2197
2198 wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
2199
2200 /* clear txq flow control */
2201 brcms_c_txflowcontrol_reset(wlc);
2202
2203 /* flush tx queues */
2204 for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
2205 brcmu_pktq_flush(&qi->q, true, NULL, NULL);
2206 }
2207
2208 callbacks += brcms_b_down_finish(wlc->hw);
2209
2210 /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
2211 wlc->clk = false;
2212
2213 wlc->going_down = false;
2214 return callbacks;
2215}
2216
2217/* Set the current gmode configuration */
2218int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
2219{
2220 int ret = 0;
2221 uint i;
2222 wlc_rateset_t rs;
2223 /* Default to 54g Auto */
2224 /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
2225 s8 shortslot = BRCMS_SHORTSLOT_AUTO;
2226 bool shortslot_restrict = false; /* Restrict association to stations that support shortslot
2227 */
2228 bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */
2229 /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
2230 int preamble = BRCMS_PLCP_LONG;
2231 bool preamble_restrict = false; /* Restrict association to stations that support short
2232 * preambles
2233 */
2234 struct brcms_band *band;
2235
2236 /* if N-support is enabled, allow Gmode set as long as requested
2237 * Gmode is not GMODE_LEGACY_B
2238 */
2239 if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B)
2240 return -ENOTSUPP;
2241
2242 /* verify that we are dealing with 2G band and grab the band pointer */
2243 if (wlc->band->bandtype == BRCM_BAND_2G)
2244 band = wlc->band;
2245 else if ((NBANDS(wlc) > 1) &&
2246 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G))
2247 band = wlc->bandstate[OTHERBANDUNIT(wlc)];
2248 else
2249 return -EINVAL;
2250
2251 /* Legacy or bust when no OFDM is supported by regulatory */
2252 if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
2253 BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
2254 return -EINVAL;
2255
2256 /* update configuration value */
2257 if (config == true)
2258 brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
2259
2260 /* Clear supported rates filter */
2261 memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t));
2262
2263 /* Clear rateset override */
2264 memset(&rs, 0, sizeof(wlc_rateset_t));
2265
2266 switch (gmode) {
2267 case GMODE_LEGACY_B:
2268 shortslot = BRCMS_SHORTSLOT_OFF;
2269 brcms_c_rateset_copy(&gphy_legacy_rates, &rs);
2270
2271 break;
2272
2273 case GMODE_LRS:
2274 if (AP_ENAB(wlc->pub))
2275 brcms_c_rateset_copy(&cck_rates,
2276 &wlc->sup_rates_override);
2277 break;
2278
2279 case GMODE_AUTO:
2280 /* Accept defaults */
2281 break;
2282
2283 case GMODE_ONLY:
2284 ofdm_basic = true;
2285 preamble = BRCMS_PLCP_SHORT;
2286 preamble_restrict = true;
2287 break;
2288
2289 case GMODE_PERFORMANCE:
2290 if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */
2291 brcms_c_rateset_copy(&cck_ofdm_rates,
2292 &wlc->sup_rates_override);
2293
2294 shortslot = BRCMS_SHORTSLOT_ON;
2295 shortslot_restrict = true;
2296 ofdm_basic = true;
2297 preamble = BRCMS_PLCP_SHORT;
2298 preamble_restrict = true;
2299 break;
2300
2301 default:
2302 /* Error */
2303 wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
2304 wlc->pub->unit, __func__, gmode);
2305 return -ENOTSUPP;
2306 }
2307
2308 /*
2309 * If we are switching to gmode == GMODE_LEGACY_B,
2310 * clean up rate info that may refer to OFDM rates.
2311 */
2312 if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) {
2313 band->gmode = gmode;
2314 if (band->rspec_override && !IS_CCK(band->rspec_override)) {
2315 band->rspec_override = 0;
2316 brcms_c_reprate_init(wlc);
2317 }
2318 if (band->mrspec_override && !IS_CCK(band->mrspec_override)) {
2319 band->mrspec_override = 0;
2320 }
2321 }
2322
2323 band->gmode = gmode;
2324
2325 wlc->shortslot_override = shortslot;
2326
2327 if (AP_ENAB(wlc->pub)) {
2328 /* wlc->ap->shortslot_restrict = shortslot_restrict; */
2329 wlc->PLCPHdr_override =
2330 (preamble !=
2331 BRCMS_PLCP_LONG) ? BRCMS_PLCP_SHORT : BRCMS_PLCP_AUTO;
2332 }
2333
2334 if ((AP_ENAB(wlc->pub) && preamble != BRCMS_PLCP_LONG)
2335 || preamble == BRCMS_PLCP_SHORT)
2336 wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
2337 else
2338 wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE;
2339
2340 /* Update shortslot capability bit for AP and IBSS */
2341 if ((AP_ENAB(wlc->pub) && shortslot == BRCMS_SHORTSLOT_AUTO) ||
2342 shortslot == BRCMS_SHORTSLOT_ON)
2343 wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
2344 else
2345 wlc->default_bss->capability &=
2346 ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
2347
2348 /* Use the default 11g rateset */
2349 if (!rs.count)
2350 brcms_c_rateset_copy(&cck_ofdm_rates, &rs);
2351
2352 if (ofdm_basic) {
2353 for (i = 0; i < rs.count; i++) {
2354 if (rs.rates[i] == BRCM_RATE_6M
2355 || rs.rates[i] == BRCM_RATE_12M
2356 || rs.rates[i] == BRCM_RATE_24M)
2357 rs.rates[i] |= BRCMS_RATE_FLAG;
2358 }
2359 }
2360
2361 /* Set default bss rateset */
2362 wlc->default_bss->rateset.count = rs.count;
2363 memcpy(wlc->default_bss->rateset.rates, rs.rates,
2364 sizeof(wlc->default_bss->rateset.rates));
2365
2366 return ret;
2367}
2368
2369static int brcms_c_nmode_validate(struct brcms_c_info *wlc, s32 nmode)
2370{
2371 int err = 0;
2372
2373 switch (nmode) {
2374
2375 case OFF:
2376 break;
2377
2378 case AUTO:
2379 case WL_11N_2x2:
2380 case WL_11N_3x3:
2381 if (!(BRCMS_PHY_11N_CAP(wlc->band)))
2382 err = -EINVAL;
2383 break;
2384
2385 default:
2386 err = -EINVAL;
2387 break;
2388 }
2389
2390 return err;
2391}
2392
2393int brcms_c_set_nmode(struct brcms_c_info *wlc, s32 nmode)
2394{
2395 uint i;
2396 int err;
2397
2398 err = brcms_c_nmode_validate(wlc, nmode);
2399 if (err)
2400 return err;
2401
2402 switch (nmode) {
2403 case OFF:
2404 wlc->pub->_n_enab = OFF;
2405 wlc->default_bss->flags &= ~BRCMS_BSS_HT;
2406 /* delete the mcs rates from the default and hw ratesets */
2407 brcms_c_rateset_mcs_clear(&wlc->default_bss->rateset);
2408 for (i = 0; i < NBANDS(wlc); i++) {
2409 memset(wlc->bandstate[i]->hw_rateset.mcs, 0,
2410 MCSSET_LEN);
2411 if (IS_MCS(wlc->band->rspec_override)) {
2412 wlc->bandstate[i]->rspec_override = 0;
2413 brcms_c_reprate_init(wlc);
2414 }
2415 if (IS_MCS(wlc->band->mrspec_override))
2416 wlc->bandstate[i]->mrspec_override = 0;
2417 }
2418 break;
2419
2420 case AUTO:
2421 if (wlc->stf->txstreams == WL_11N_3x3)
2422 nmode = WL_11N_3x3;
2423 else
2424 nmode = WL_11N_2x2;
2425 case WL_11N_2x2:
2426 case WL_11N_3x3:
2427 /* force GMODE_AUTO if NMODE is ON */
2428 brcms_c_set_gmode(wlc, GMODE_AUTO, true);
2429 if (nmode == WL_11N_3x3)
2430 wlc->pub->_n_enab = SUPPORT_HT;
2431 else
2432 wlc->pub->_n_enab = SUPPORT_11N;
2433 wlc->default_bss->flags |= BRCMS_BSS_HT;
2434 /* add the mcs rates to the default and hw ratesets */
2435 brcms_c_rateset_mcs_build(&wlc->default_bss->rateset,
2436 wlc->stf->txstreams);
2437 for (i = 0; i < NBANDS(wlc); i++)
2438 memcpy(wlc->bandstate[i]->hw_rateset.mcs,
2439 wlc->default_bss->rateset.mcs, MCSSET_LEN);
2440 break;
2441
2442 default:
2443 break;
2444 }
2445
2446 return err;
2447}
2448
2449static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg)
2450{
2451 wlc_rateset_t rs, new;
2452 uint bandunit;
2453
2454 memcpy(&rs, rs_arg, sizeof(wlc_rateset_t));
2455
2456 /* check for bad count value */
2457 if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES))
2458 return -EINVAL;
2459
2460 /* try the current band */
2461 bandunit = wlc->band->bandunit;
2462 memcpy(&new, &rs, sizeof(wlc_rateset_t));
2463 if (brcms_c_rate_hwrs_filter_sort_validate
2464 (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
2465 wlc->stf->txstreams))
2466 goto good;
2467
2468 /* try the other band */
2469 if (IS_MBAND_UNLOCKED(wlc)) {
2470 bandunit = OTHERBANDUNIT(wlc);
2471 memcpy(&new, &rs, sizeof(wlc_rateset_t));
2472 if (brcms_c_rate_hwrs_filter_sort_validate(&new,
2473 &wlc->
2474 bandstate[bandunit]->
2475 hw_rateset, true,
2476 wlc->stf->txstreams))
2477 goto good;
2478 }
2479
2480 return -EBADE;
2481
2482 good:
2483 /* apply new rateset */
2484 memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t));
2485 memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
2486 sizeof(wlc_rateset_t));
2487 return 0;
2488}
2489
2490/* simplified integer set interface for common ioctl handler */
2491int brcms_c_set(struct brcms_c_info *wlc, int cmd, int arg)
2492{
2493 return brcms_c_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL);
2494}
2495
2496/* simplified integer get interface for common ioctl handler */
2497int brcms_c_get(struct brcms_c_info *wlc, int cmd, int *arg)
2498{
2499 return brcms_c_ioctl(wlc, cmd, arg, sizeof(int), NULL);
2500}
2501
2502static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
2503{
2504 u8 r;
2505 bool war = false;
2506
2507 if (wlc->cfg->associated)
2508 r = wlc->cfg->current_bss->rateset.rates[0];
2509 else
2510 r = wlc->default_bss->rateset.rates[0];
2511
2512 wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
2513
2514 return;
2515}
2516
2517int
2518brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len,
2519 struct brcms_c_if *wlcif)
2520{
2521 return _brcms_c_ioctl(wlc, cmd, arg, len, wlcif);
2522}
2523
2524/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */
2525static int
2526_brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len,
2527 struct brcms_c_if *wlcif)
2528{
2529 int val, *pval;
2530 bool bool_val;
2531 int bcmerror;
2532 struct scb *nextscb;
2533 bool ta_ok;
2534 uint band;
2535 struct brcms_bss_cfg *bsscfg;
2536 struct brcms_bss_info *current_bss;
2537
2538 /* update bsscfg pointer */
2539 bsscfg = wlc->cfg;
2540 current_bss = bsscfg->current_bss;
2541
2542 /* initialize the following to get rid of compiler warning */
2543 nextscb = NULL;
2544 ta_ok = false;
2545 band = 0;
2546
2547 /* If the device is turned off, then it's not "removed" */
2548 if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) {
2549 wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
2550 __func__);
2551 brcms_down(wlc->wl);
2552 return -EBADE;
2553 }
2554
2555 /* default argument is generic integer */
2556 pval = arg ? (int *)arg : NULL;
2557
2558 /* This will prevent the misaligned access */
2559 if (pval && (u32) len >= sizeof(val))
2560 memcpy(&val, pval, sizeof(val));
2561 else
2562 val = 0;
2563
2564 /* bool conversion to avoid duplication below */
2565 bool_val = val != 0;
2566 bcmerror = 0;
2567
2568 if ((arg == NULL) || (len <= 0)) {
2569 wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs arguments\n",
2570 wlc->pub->unit, __func__, cmd);
2571 bcmerror = -EINVAL;
2572 goto done;
2573 }
2574
2575 switch (cmd) {
2576
2577 case BRCM_SET_CHANNEL:{
2578 chanspec_t chspec = CH20MHZ_CHSPEC(val);
2579
2580 if (val < 0 || val > MAXCHANNEL) {
2581 bcmerror = -EINVAL;
2582 break;
2583 }
2584
2585 if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec)) {
2586 bcmerror = -EINVAL;
2587 break;
2588 }
2589
2590 if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) {
2591 if (wlc->band->bandunit !=
2592 CHSPEC_BANDUNIT(chspec))
2593 wlc->bandinit_pending = true;
2594 else
2595 wlc->bandinit_pending = false;
2596 }
2597
2598 wlc->default_bss->chanspec = chspec;
2599 /* brcms_c_BSSinit() will sanitize the rateset before
2600 * using it.. */
2601 if (wlc->pub->up &&
2602 (BRCMS_BAND_PI_RADIO_CHANSPEC != chspec)) {
2603 brcms_c_set_home_chanspec(wlc, chspec);
2604 brcms_c_suspend_mac_and_wait(wlc);
2605 brcms_c_set_chanspec(wlc, chspec);
2606 brcms_c_enable_mac(wlc);
2607 }
2608 break;
2609 }
2610
2611 case BRCM_SET_SRL:
2612 if (val >= 1 && val <= RETRY_SHORT_MAX) {
2613 int ac;
2614 wlc->SRL = (u16) val;
2615
2616 brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
2617
2618 for (ac = 0; ac < AC_COUNT; ac++) {
2619 BRCMS_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL);
2620 }
2621 brcms_c_wme_retries_write(wlc);
2622 } else
2623 bcmerror = -EINVAL;
2624 break;
2625
2626 case BRCM_SET_LRL:
2627 if (val >= 1 && val <= 255) {
2628 int ac;
2629 wlc->LRL = (u16) val;
2630
2631 brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
2632
2633 for (ac = 0; ac < AC_COUNT; ac++) {
2634 BRCMS_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL);
2635 }
2636 brcms_c_wme_retries_write(wlc);
2637 } else
2638 bcmerror = -EINVAL;
2639 break;
2640
2641 case BRCM_GET_CURR_RATESET:{
2642 wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
2643 wlc_rateset_t *rs;
2644
2645 if (wlc->pub->associated)
2646 rs = &current_bss->rateset;
2647 else
2648 rs = &wlc->default_bss->rateset;
2649
2650 if (len < (int)(rs->count + sizeof(rs->count))) {
2651 bcmerror = -EOVERFLOW;
2652 break;
2653 }
2654
2655 /* Copy only legacy rateset section */
2656 ret_rs->count = rs->count;
2657 memcpy(&ret_rs->rates, &rs->rates, rs->count);
2658 break;
2659 }
2660
2661 case BRCM_SET_RATESET:{
2662 wlc_rateset_t rs;
2663 wl_rateset_t *in_rs = (wl_rateset_t *) arg;
2664
2665 if (len < (int)(in_rs->count + sizeof(in_rs->count))) {
2666 bcmerror = -EOVERFLOW;
2667 break;
2668 }
2669
2670 if (in_rs->count > BRCMS_NUMRATES) {
2671 bcmerror = -ENOBUFS;
2672 break;
2673 }
2674
2675 memset(&rs, 0, sizeof(wlc_rateset_t));
2676
2677 /* Copy only legacy rateset section */
2678 rs.count = in_rs->count;
2679 memcpy(&rs.rates, &in_rs->rates, rs.count);
2680
2681 /* merge rateset coming in with the current mcsset */
2682 if (N_ENAB(wlc->pub)) {
2683 if (bsscfg->associated)
2684 memcpy(rs.mcs,
2685 &current_bss->rateset.mcs[0],
2686 MCSSET_LEN);
2687 else
2688 memcpy(rs.mcs,
2689 &wlc->default_bss->rateset.mcs[0],
2690 MCSSET_LEN);
2691 }
2692
2693 bcmerror = brcms_c_set_rateset(wlc, &rs);
2694
2695 if (!bcmerror)
2696 brcms_c_ofdm_rateset_war(wlc);
2697
2698 break;
2699 }
2700
2701 case BRCM_SET_BCNPRD:
2702 /* range [1, 0xffff] */
2703 if (val >= DOT11_MIN_BEACON_PERIOD
2704 && val <= DOT11_MAX_BEACON_PERIOD)
2705 wlc->default_bss->beacon_period = (u16) val;
2706 else
2707 bcmerror = -EINVAL;
2708 break;
2709
2710 case BRCM_GET_PHYLIST:
2711 {
2712 unsigned char *cp = arg;
2713 if (len < 3) {
2714 bcmerror = -EOVERFLOW;
2715 break;
2716 }
2717
2718 if (BRCMS_ISNPHY(wlc->band))
2719 *cp++ = 'n';
2720 else if (BRCMS_ISLCNPHY(wlc->band))
2721 *cp++ = 'c';
2722 else if (BRCMS_ISSSLPNPHY(wlc->band))
2723 *cp++ = 's';
2724 *cp = '\0';
2725 break;
2726 }
2727
2728 case BRCMS_SET_SHORTSLOT_OVERRIDE:
2729 if (val != BRCMS_SHORTSLOT_AUTO && val != BRCMS_SHORTSLOT_OFF &&
2730 val != BRCMS_SHORTSLOT_ON) {
2731 bcmerror = -EINVAL;
2732 break;
2733 }
2734
2735 wlc->shortslot_override = (s8) val;
2736
2737 /* shortslot is an 11g feature, so no more work if we are
2738 * currently on the 5G band
2739 */
2740 if (BAND_5G(wlc->band->bandtype))
2741 break;
2742
2743 if (wlc->pub->up && wlc->pub->associated) {
2744 /* let watchdog or beacon processing update shortslot */
2745 } else if (wlc->pub->up) {
2746 /* unassociated shortslot is off */
2747 brcms_c_switch_shortslot(wlc, false);
2748 } else {
2749 /* driver is down, so just update the brcms_c_info
2750 * value */
2751 if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO) {
2752 wlc->shortslot = false;
2753 } else {
2754 wlc->shortslot =
2755 (wlc->shortslot_override ==
2756 BRCMS_SHORTSLOT_ON);
2757 }
2758 }
2759
2760 break;
2761
2762 }
2763 done:
2764
2765 if (bcmerror)
2766 wlc->pub->bcmerror = bcmerror;
2767
2768 return bcmerror;
2769}
2770
2771/*
2772 * register watchdog and down handlers.
2773 */
2774int brcms_c_module_register(struct brcms_pub *pub,
2775 const char *name, void *hdl,
2776 watchdog_fn_t w_fn, down_fn_t d_fn)
2777{
2778 struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
2779 int i;
2780
2781 /* find an empty entry and just add, no duplication check! */
2782 for (i = 0; i < BRCMS_MAXMODULES; i++) {
2783 if (wlc->modulecb[i].name[0] == '\0') {
2784 strncpy(wlc->modulecb[i].name, name,
2785 sizeof(wlc->modulecb[i].name) - 1);
2786 wlc->modulecb[i].hdl = hdl;
2787 wlc->modulecb[i].watchdog_fn = w_fn;
2788 wlc->modulecb[i].down_fn = d_fn;
2789 return 0;
2790 }
2791 }
2792
2793 return -ENOSR;
2794}
2795
2796/* unregister module callbacks */
2797int
2798brcms_c_module_unregister(struct brcms_pub *pub, const char *name, void *hdl)
2799{
2800 struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
2801 int i;
2802
2803 if (wlc == NULL)
2804 return -ENODATA;
2805
2806 for (i = 0; i < BRCMS_MAXMODULES; i++) {
2807 if (!strcmp(wlc->modulecb[i].name, name) &&
2808 (wlc->modulecb[i].hdl == hdl)) {
2809 memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
2810 return 0;
2811 }
2812 }
2813
2814 /* table not found! */
2815 return -ENODATA;
2816}
2817
2818/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */
2819static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
2820{
2821 int ac;
2822
2823 /* Need clock to do this */
2824 if (!wlc->clk)
2825 return;
2826
2827 for (ac = 0; ac < AC_COUNT; ac++) {
2828 brcms_c_write_shm(wlc, M_AC_TXLMT_ADDR(ac),
2829 wlc->wme_retries[ac]);
2830 }
2831}
2832
2833#ifdef BCMDBG
2834static const char * const supr_reason[] = {
2835 "None", "PMQ Entry", "Flush request",
2836 "Previous frag failure", "Channel mismatch",
2837 "Lifetime Expiry", "Underflow"
2838};
2839
2840static void brcms_c_print_txs_status(u16 s)
2841{
2842 printk(KERN_DEBUG "[15:12] %d frame attempts\n",
2843 (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
2844 printk(KERN_DEBUG " [11:8] %d rts attempts\n",
2845 (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
2846 printk(KERN_DEBUG " [7] %d PM mode indicated\n",
2847 ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
2848 printk(KERN_DEBUG " [6] %d intermediate status\n",
2849 ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
2850 printk(KERN_DEBUG " [5] %d AMPDU\n",
2851 (s & TX_STATUS_AMPDU) ? 1 : 0);
2852 printk(KERN_DEBUG " [4:2] %d Frame Suppressed Reason (%s)\n",
2853 ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
2854 supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
2855 printk(KERN_DEBUG " [1] %d acked\n",
2856 ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
2857}
2858#endif /* BCMDBG */
2859
2860void brcms_c_print_txstatus(struct tx_status *txs)
2861{
2862#if defined(BCMDBG)
2863 u16 s = txs->status;
2864 u16 ackphyrxsh = txs->ackphyrxsh;
2865
2866 printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");
2867
2868 printk(KERN_DEBUG "FrameID: %04x ", txs->frameid);
2869 printk(KERN_DEBUG "TxStatus: %04x", s);
2870 printk(KERN_DEBUG "\n");
2871
2872 brcms_c_print_txs_status(s);
2873
2874 printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
2875 printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
2876 printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
2877 printk(KERN_DEBUG "RxAckRSSI: %04x ",
2878 (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
2879 printk(KERN_DEBUG "RxAckSQ: %04x",
2880 (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
2881 printk(KERN_DEBUG "\n");
2882#endif /* defined(BCMDBG) */
2883}
2884
2885void brcms_c_statsupd(struct brcms_c_info *wlc)
2886{
2887 int i;
2888 struct macstat macstats;
2889#ifdef BCMDBG
2890 u16 delta;
2891 u16 rxf0ovfl;
2892 u16 txfunfl[NFIFO];
2893#endif /* BCMDBG */
2894
2895 /* if driver down, make no sense to update stats */
2896 if (!wlc->pub->up)
2897 return;
2898
2899#ifdef BCMDBG
2900 /* save last rx fifo 0 overflow count */
2901 rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
2902
2903 /* save last tx fifo underflow count */
2904 for (i = 0; i < NFIFO; i++)
2905 txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
2906#endif /* BCMDBG */
2907
2908 /* Read mac stats from contiguous shared memory */
2909 brcms_b_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT,
2910 &macstats, sizeof(struct macstat));
2911
2912#ifdef BCMDBG
2913 /* check for rx fifo 0 overflow */
2914 delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
2915 if (delta)
2916 wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
2917 wlc->pub->unit, delta);
2918
2919 /* check for tx fifo underflows */
2920 for (i = 0; i < NFIFO; i++) {
2921 delta =
2922 (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
2923 txfunfl[i]);
2924 if (delta)
2925 wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
2926 "\n", wlc->pub->unit, delta, i);
2927 }
2928#endif /* BCMDBG */
2929
2930 /* merge counters from dma module */
2931 for (i = 0; i < NFIFO; i++) {
2932 if (wlc->hw->di[i]) {
2933 dma_counterreset(wlc->hw->di[i]);
2934 }
2935 }
2936}
2937
2938bool brcms_c_chipmatch(u16 vendor, u16 device)
2939{
2940 if (vendor != PCI_VENDOR_ID_BROADCOM) {
2941 pr_err("chipmatch: unknown vendor id %04x\n", vendor);
2942 return false;
2943 }
2944
2945 if (device == BCM43224_D11N_ID_VEN1)
2946 return true;
2947 if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
2948 return true;
2949 if (device == BCM4313_D11N2G_ID)
2950 return true;
2951 if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
2952 return true;
2953
2954 pr_err("chipmatch: unknown device id %04x\n", device);
2955 return false;
2956}
2957
2958#if defined(BCMDBG)
2959void brcms_c_print_txdesc(struct d11txh *txh)
2960{
2961 u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
2962 u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
2963 u16 mfc = le16_to_cpu(txh->MacFrameControl);
2964 u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
2965 u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
2966 u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
2967 u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
2968 u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
2969 u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
2970 u16 mainrates = le16_to_cpu(txh->MainRates);
2971 u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
2972 u8 *iv = txh->IV;
2973 u8 *ra = txh->TxFrameRA;
2974 u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
2975 u8 *rtspfb = txh->RTSPLCPFallback;
2976 u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
2977 u8 *fragpfb = txh->FragPLCPFallback;
2978 u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
2979 u16 mmodelen = le16_to_cpu(txh->MModeLen);
2980 u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
2981 u16 tfid = le16_to_cpu(txh->TxFrameID);
2982 u16 txs = le16_to_cpu(txh->TxStatus);
2983 u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
2984 u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
2985 u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
2986 u16 mmbyte = le16_to_cpu(txh->MinMBytes);
2987
2988 u8 *rtsph = txh->RTSPhyHeader;
2989 struct ieee80211_rts rts = txh->rts_frame;
2990 char hexbuf[256];
2991
2992 /* add plcp header along with txh descriptor */
2993 printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
2994 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
2995 txh, sizeof(struct d11txh) + 48);
2996
2997 printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
2998 printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
2999 printk(KERN_DEBUG "FC: %04x ", mfc);
3000 printk(KERN_DEBUG "FES Time: %04x\n", tfest);
3001 printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
3002 (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
3003 printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
3004 printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
3005 printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
3006 printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
3007 printk(KERN_DEBUG "MainRates: %04x ", mainrates);
3008 printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
3009 printk(KERN_DEBUG "\n");
3010
3011 brcmu_format_hex(hexbuf, iv, sizeof(txh->IV));
3012 printk(KERN_DEBUG "SecIV: %s\n", hexbuf);
3013 brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA));
3014 printk(KERN_DEBUG "RA: %s\n", hexbuf);
3015
3016 printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
3017 brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback));
3018 printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
3019 printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
3020 brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback));
3021 printk(KERN_DEBUG "PLCP: %s ", hexbuf);
3022 printk(KERN_DEBUG "DUR: %04x", fragdfb);
3023 printk(KERN_DEBUG "\n");
3024
3025 printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
3026 printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);
3027
3028 printk(KERN_DEBUG "FrameID: %04x\n", tfid);
3029 printk(KERN_DEBUG "TxStatus: %04x\n", txs);
3030
3031 printk(KERN_DEBUG "MaxNumMpdu: %04x\n", mnmpdu);
3032 printk(KERN_DEBUG "MaxAggbyte: %04x\n", mabyte);
3033 printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f);
3034 printk(KERN_DEBUG "MinByte: %04x\n", mmbyte);
3035
3036 brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader));
3037 printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
3038 brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame));
3039 printk(KERN_DEBUG "RTS Frame: %s", hexbuf);
3040 printk(KERN_DEBUG "\n");
3041}
3042#endif /* defined(BCMDBG) */
3043
3044#if defined(BCMDBG)
3045void brcms_c_print_rxh(struct d11rxhdr *rxh)
3046{
3047 u16 len = rxh->RxFrameSize;
3048 u16 phystatus_0 = rxh->PhyRxStatus_0;
3049 u16 phystatus_1 = rxh->PhyRxStatus_1;
3050 u16 phystatus_2 = rxh->PhyRxStatus_2;
3051 u16 phystatus_3 = rxh->PhyRxStatus_3;
3052 u16 macstatus1 = rxh->RxStatus1;
3053 u16 macstatus2 = rxh->RxStatus2;
3054 char flagstr[64];
3055 char lenbuf[20];
3056 static const struct brcmu_bit_desc macstat_flags[] = {
3057 {RXS_FCSERR, "FCSErr"},
3058 {RXS_RESPFRAMETX, "Reply"},
3059 {RXS_PBPRES, "PADDING"},
3060 {RXS_DECATMPT, "DeCr"},
3061 {RXS_DECERR, "DeCrErr"},
3062 {RXS_BCNSENT, "Bcn"},
3063 {0, NULL}
3064 };
3065
3066 printk(KERN_DEBUG "Raw RxDesc:\n");
3067 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh,
3068 sizeof(struct d11rxhdr));
3069
3070 brcmu_format_flags(macstat_flags, macstatus1, flagstr, 64);
3071
3072 snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
3073
3074 printk(KERN_DEBUG "RxFrameSize: %6s (%d)%s\n", lenbuf, len,
3075 (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
3076 printk(KERN_DEBUG "RxPHYStatus: %04x %04x %04x %04x\n",
3077 phystatus_0, phystatus_1, phystatus_2, phystatus_3);
3078 printk(KERN_DEBUG "RxMACStatus: %x %s\n", macstatus1, flagstr);
3079 printk(KERN_DEBUG "RXMACaggtype: %x\n",
3080 (macstatus2 & RXS_AGGTYPE_MASK));
3081 printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime);
3082}
3083#endif /* defined(BCMDBG) */
3084
3085static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate)
3086{
3087 return brcms_b_rate_shm_offset(wlc->hw, rate);
3088}
3089
3090/* Callback for device removed */
3091
3092/*
3093 * Attempts to queue a packet onto a multiple-precedence queue,
3094 * if necessary evicting a lower precedence packet from the queue.
3095 *
3096 * 'prec' is the precedence number that has already been mapped
3097 * from the packet priority.
3098 *
3099 * Returns true if packet consumed (queued), false if not.
3100 */
3101bool
3102brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, void *pkt, int prec)
3103{
3104 return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
3105}
3106
3107bool
3108brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
3109 struct sk_buff *pkt, int prec, bool head)
3110{
3111 struct sk_buff *p;
3112 int eprec = -1; /* precedence to evict from */
3113
3114 /* Determine precedence from which to evict packet, if any */
3115 if (pktq_pfull(q, prec))
3116 eprec = prec;
3117 else if (pktq_full(q)) {
3118 p = brcmu_pktq_peek_tail(q, &eprec);
3119 if (eprec > prec) {
3120 wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
3121 "\n", __func__, eprec, prec);
3122 return false;
3123 }
3124 }
3125
3126 /* Evict if needed */
3127 if (eprec >= 0) {
3128 bool discard_oldest;
3129
3130 discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec);
3131
3132 /* Refuse newer packet unless configured to discard oldest */
3133 if (eprec == prec && !discard_oldest) {
3134 wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
3135 "\n", __func__, prec);
3136 return false;
3137 }
3138
3139 /* Evict packet according to discard policy */
3140 p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
3141 brcmu_pktq_pdeq_tail(q, eprec);
3142 brcmu_pkt_buf_free_skb(p);
3143 }
3144
3145 /* Enqueue */
3146 if (head)
3147 p = brcmu_pktq_penq_head(q, prec, pkt);
3148 else
3149 p = brcmu_pktq_penq(q, prec, pkt);
3150
3151 return true;
3152}
3153
3154void brcms_c_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
3155 uint prec)
3156{
3157 struct brcms_c_info *wlc = (struct brcms_c_info *) ctx;
3158 struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */
3159 struct pktq *q = &qi->q;
3160 int prio;
3161
3162 prio = sdu->priority;
3163
3164 if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
3165 if (!EDCF_ENAB(wlc->pub)
3166 || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL))
3167 wiphy_err(wlc->wiphy, "wl%d: txq_enq: txq overflow"
3168 "\n", wlc->pub->unit);
3169
3170 /*
3171 * we might hit this condtion in case
3172 * packet flooding from mac80211 stack
3173 */
3174 brcmu_pkt_buf_free_skb(sdu);
3175 }
3176
3177 /* Check if flow control needs to be turned on after enqueuing the packet
3178 * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what
3179 * to drop instead of relying on stack to make the right decision
3180 */
3181 if (!EDCF_ENAB(wlc->pub)
3182 || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
3183 if (pktq_len(q) >= wlc->pub->tunables->datahiwat) {
3184 brcms_c_txflowcontrol(wlc, qi, ON, ALLPRIO);
3185 }
3186 } else if (wlc->pub->_priofc) {
3187 if (pktq_plen(q, wlc_prio2prec_map[prio]) >=
3188 wlc->pub->tunables->datahiwat) {
3189 brcms_c_txflowcontrol(wlc, qi, ON, prio);
3190 }
3191 }
3192}
3193
3194bool
3195brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
3196 struct ieee80211_hw *hw)
3197{
3198 u8 prio;
3199 uint fifo;
3200 void *pkt;
3201 struct scb *scb = &global_scb;
3202 struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
3203
3204 /* 802.11 standard requires management traffic to go at highest priority */
3205 prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
3206 MAXPRIO;
3207 fifo = prio2fifo[prio];
3208 pkt = sdu;
3209 if (unlikely
3210 (brcms_c_d11hdrs_mac80211(
3211 wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
3212 return -EINVAL;
3213 brcms_c_txq_enq(wlc, scb, pkt, BRCMS_PRIO_TO_PREC(prio));
3214 brcms_c_send_q(wlc);
3215 return 0;
3216}
3217
3218void brcms_c_send_q(struct brcms_c_info *wlc)
3219{
3220 struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
3221 int prec;
3222 u16 prec_map;
3223 int err = 0, i, count;
3224 uint fifo;
3225 struct brcms_txq_info *qi = wlc->pkt_queue;
3226 struct pktq *q = &qi->q;
3227 struct ieee80211_tx_info *tx_info;
3228
3229 if (in_send_q)
3230 return;
3231 else
3232 in_send_q = true;
3233
3234 prec_map = wlc->tx_prec_map;
3235
3236 /* Send all the enq'd pkts that we can.
3237 * Dequeue packets with precedence with empty HW fifo only
3238 */
3239 while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
3240 tx_info = IEEE80211_SKB_CB(pkt[0]);
3241 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
3242 err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
3243 } else {
3244 count = 1;
3245 err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
3246 if (!err) {
3247 for (i = 0; i < count; i++) {
3248 brcms_c_txfifo(wlc, fifo, pkt[i], true,
3249 1);
3250 }
3251 }
3252 }
3253
3254 if (err == -EBUSY) {
3255 brcmu_pktq_penq_head(q, prec, pkt[0]);
3256 /* If send failed due to any other reason than a change in
3257 * HW FIFO condition, quit. Otherwise, read the new prec_map!
3258 */
3259 if (prec_map == wlc->tx_prec_map)
3260 break;
3261 prec_map = wlc->tx_prec_map;
3262 }
3263 }
3264
3265 /* Check if flow control needs to be turned off after sending the packet */
3266 if (!EDCF_ENAB(wlc->pub)
3267 || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
3268 if (brcms_c_txflowcontrol_prio_isset(wlc, qi, ALLPRIO)
3269 && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) {
3270 brcms_c_txflowcontrol(wlc, qi, OFF, ALLPRIO);
3271 }
3272 } else if (wlc->pub->_priofc) {
3273 int prio;
3274 for (prio = MAXPRIO; prio >= 0; prio--) {
3275 if (brcms_c_txflowcontrol_prio_isset(wlc, qi, prio) &&
3276 (pktq_plen(q, wlc_prio2prec_map[prio]) <
3277 wlc->pub->tunables->datahiwat / 2)) {
3278 brcms_c_txflowcontrol(wlc, qi, OFF, prio);
3279 }
3280 }
3281 }
3282 in_send_q = false;
3283}
3284
3285/*
3286 * bcmc_fid_generate:
3287 * Generate frame ID for a BCMC packet. The frag field is not used
3288 * for MC frames so is used as part of the sequence number.
3289 */
3290static inline u16
3291bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
3292 struct d11txh *txh)
3293{
3294 u16 frameid;
3295
3296 frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
3297 TXFID_QUEUE_MASK);
3298 frameid |=
3299 (((wlc->
3300 mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
3301 TX_BCMC_FIFO;
3302
3303 return frameid;
3304}
3305
3306void
3307brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
3308 bool commit, s8 txpktpend)
3309{
3310 u16 frameid = INVALIDFID;
3311 struct d11txh *txh;
3312
3313 txh = (struct d11txh *) (p->data);
3314
3315 /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update
3316 * ucode or BSS info as appropriate.
3317 */
3318 if (fifo == TX_BCMC_FIFO) {
3319 frameid = le16_to_cpu(txh->TxFrameID);
3320
3321 }
3322
3323 if (BRCMS_WAR16165(wlc))
3324 brcms_c_war16165(wlc, true);
3325
3326
3327 /* Bump up pending count for if not using rpc. If rpc is used, this will be handled
3328 * in brcms_b_txfifo()
3329 */
3330 if (commit) {
3331 TXPKTPENDINC(wlc, fifo, txpktpend);
3332 BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
3333 txpktpend, TXPKTPENDGET(wlc, fifo));
3334 }
3335
3336 /* Commit BCMC sequence number in the SHM frame ID location */
3337 if (frameid != INVALIDFID)
3338 BCMCFID(wlc, frameid);
3339
3340 if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) {
3341 wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
3342 }
3343}
3344
3345void
3346brcms_c_compute_plcp(struct brcms_c_info *wlc, ratespec_t rspec,
3347 uint length, u8 *plcp)
3348{
3349 if (IS_MCS(rspec)) {
3350 brcms_c_compute_mimo_plcp(rspec, length, plcp);
3351 } else if (IS_OFDM(rspec)) {
3352 brcms_c_compute_ofdm_plcp(rspec, length, plcp);
3353 } else {
3354 brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
3355 }
3356 return;
3357}
3358
3359/* Rate: 802.11 rate code, length: PSDU length in octets */
3360static void brcms_c_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp)
3361{
3362 u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
3363 plcp[0] = mcs;
3364 if (RSPEC_IS40MHZ(rspec) || (mcs == 32))
3365 plcp[0] |= MIMO_PLCP_40MHZ;
3366 BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
3367 plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */
3368 plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
3369 plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
3370 plcp[5] = 0;
3371}
3372
3373/* Rate: 802.11 rate code, length: PSDU length in octets */
3374static void
3375brcms_c_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp)
3376{
3377 u8 rate_signal;
3378 u32 tmp = 0;
3379 int rate = RSPEC2RATE(rspec);
3380
3381 /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */
3382 rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
3383 memset(plcp, 0, D11_PHY_HDR_LEN);
3384 D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
3385
3386 tmp = (length & 0xfff) << 5;
3387 plcp[2] |= (tmp >> 16) & 0xff;
3388 plcp[1] |= (tmp >> 8) & 0xff;
3389 plcp[0] |= tmp & 0xff;
3390
3391 return;
3392}
3393
3394/*
3395 * Compute PLCP, but only requires actual rate and length of pkt.
3396 * Rate is given in the driver standard multiple of 500 kbps.
3397 * le is set for 11 Mbps rate if necessary.
3398 * Broken out for PRQ.
3399 */
3400
3401static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
3402 uint length, u8 *plcp)
3403{
3404 u16 usec = 0;
3405 u8 le = 0;
3406
3407 switch (rate_500) {
3408 case BRCM_RATE_1M:
3409 usec = length << 3;
3410 break;
3411 case BRCM_RATE_2M:
3412 usec = length << 2;
3413 break;
3414 case BRCM_RATE_5M5:
3415 usec = (length << 4) / 11;
3416 if ((length << 4) - (usec * 11) > 0)
3417 usec++;
3418 break;
3419 case BRCM_RATE_11M:
3420 usec = (length << 3) / 11;
3421 if ((length << 3) - (usec * 11) > 0) {
3422 usec++;
3423 if ((usec * 11) - (length << 3) >= 8)
3424 le = D11B_PLCP_SIGNAL_LE;
3425 }
3426 break;
3427
3428 default:
3429 wiphy_err(wlc->wiphy, "brcms_c_cck_plcp_set: unsupported rate %d"
3430 "\n", rate_500);
3431 rate_500 = BRCM_RATE_1M;
3432 usec = length << 3;
3433 break;
3434 }
3435 /* PLCP signal byte */
3436 plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */
3437 /* PLCP service byte */
3438 plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
3439 /* PLCP length u16, little endian */
3440 plcp[2] = usec & 0xff;
3441 plcp[3] = (usec >> 8) & 0xff;
3442 /* PLCP CRC16 */
3443 plcp[4] = 0;
3444 plcp[5] = 0;
3445}
3446
3447/* Rate: 802.11 rate code, length: PSDU length in octets */
3448static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rspec,
3449 uint length, u8 *plcp)
3450{
3451 int rate = RSPEC2RATE(rspec);
3452
3453 brcms_c_cck_plcp_set(wlc, rate, length, plcp);
3454}
3455
3456/* brcms_c_compute_frame_dur()
3457 *
3458 * Calculate the 802.11 MAC header DUR field for MPDU
3459 * DUR for a single frame = 1 SIFS + 1 ACK
3460 * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
3461 *
3462 * rate MPDU rate in unit of 500kbps
3463 * next_frag_len next MPDU length in bytes
3464 * preamble_type use short/GF or long/MM PLCP header
3465 */
3466static u16
3467brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate,
3468 u8 preamble_type, uint next_frag_len)
3469{
3470 u16 dur, sifs;
3471
3472 sifs = SIFS(wlc->band);
3473
3474 dur = sifs;
3475 dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type);
3476
3477 if (next_frag_len) {
3478 /* Double the current DUR to get 2 SIFS + 2 ACKs */
3479 dur *= 2;
3480 /* add another SIFS and the frag time */
3481 dur += sifs;
3482 dur +=
3483 (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type,
3484 next_frag_len);
3485 }
3486 return dur;
3487}
3488
3489/* brcms_c_compute_rtscts_dur()
3490 *
3491 * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
3492 * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
3493 * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK
3494 *
3495 * cts cts-to-self or rts/cts
3496 * rts_rate rts or cts rate in unit of 500kbps
3497 * rate next MPDU rate in unit of 500kbps
3498 * frame_len next MPDU frame length in bytes
3499 */
3500u16
3501brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
3502 ratespec_t rts_rate,
3503 ratespec_t frame_rate, u8 rts_preamble_type,
3504 u8 frame_preamble_type, uint frame_len, bool ba)
3505{
3506 u16 dur, sifs;
3507
3508 sifs = SIFS(wlc->band);
3509
3510 if (!cts_only) { /* RTS/CTS */
3511 dur = 3 * sifs;
3512 dur +=
3513 (u16) brcms_c_calc_cts_time(wlc, rts_rate,
3514 rts_preamble_type);
3515 } else { /* CTS-TO-SELF */
3516 dur = 2 * sifs;
3517 }
3518
3519 dur +=
3520 (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
3521 frame_len);
3522 if (ba)
3523 dur +=
3524 (u16) brcms_c_calc_ba_time(wlc, frame_rate,
3525 BRCMS_SHORT_PREAMBLE);
3526 else
3527 dur +=
3528 (u16) brcms_c_calc_ack_time(wlc, frame_rate,
3529 frame_preamble_type);
3530 return dur;
3531}
3532
3533u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec)
3534{
3535 u16 phyctl1 = 0;
3536 u16 bw;
3537
3538 if (BRCMS_ISLCNPHY(wlc->band)) {
3539 bw = PHY_TXC1_BW_20MHZ;
3540 } else {
3541 bw = RSPEC_GET_BW(rspec);
3542 /* 10Mhz is not supported yet */
3543 if (bw < PHY_TXC1_BW_20MHZ) {
3544 wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
3545 "not supported yet, set to 20L\n", bw);
3546 bw = PHY_TXC1_BW_20MHZ;
3547 }
3548 }
3549
3550 if (IS_MCS(rspec)) {
3551 uint mcs = rspec & RSPEC_RATE_MASK;
3552
3553 /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */
3554 phyctl1 = RSPEC_PHYTXBYTE2(rspec);
3555 /* set the upper byte of phyctl1 */
3556 phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
3557 } else if (IS_CCK(rspec) && !BRCMS_ISLCNPHY(wlc->band)
3558 && !BRCMS_ISSSLPNPHY(wlc->band)) {
3559 /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
3560 /* Eventually MIMOPHY would also be converted to this format */
3561 /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
3562 phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
3563 } else { /* legacy OFDM/CCK */
3564 s16 phycfg;
3565 /* get the phyctl byte from rate phycfg table */
3566 phycfg = brcms_c_rate_legacy_phyctl(RSPEC2RATE(rspec));
3567 if (phycfg == -1) {
3568 wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
3569 "legacy OFDM/CCK rate\n");
3570 phycfg = 0;
3571 }
3572 /* set the upper byte of phyctl1 */
3573 phyctl1 =
3574 (bw | (phycfg << 8) |
3575 (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
3576 }
3577 return phyctl1;
3578}
3579
3580ratespec_t
3581brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, ratespec_t rspec,
3582 bool use_rspec, u16 mimo_ctlchbw)
3583{
3584 ratespec_t rts_rspec = 0;
3585
3586 if (use_rspec) {
3587 /* use frame rate as rts rate */
3588 rts_rspec = rspec;
3589
3590 } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) {
3591 /* Use 11Mbps as the g protection RTS target rate and fallback.
3592 * Use the BRCMS_BASIC_RATE() lookup to find the best basic rate
3593 * under the target in case 11 Mbps is not Basic.
3594 * 6 and 9 Mbps are not usually selected by rate selection, but even
3595 * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust.
3596 */
3597 rts_rspec = BRCMS_BASIC_RATE(wlc, BRCM_RATE_11M);
3598 } else {
3599 /* calculate RTS rate and fallback rate based on the frame rate
3600 * RTS must be sent at a basic rate since it is a
3601 * control frame, sec 9.6 of 802.11 spec
3602 */
3603 rts_rspec = BRCMS_BASIC_RATE(wlc, rspec);
3604 }
3605
3606 if (BRCMS_PHY_11N_CAP(wlc->band)) {
3607 /* set rts txbw to correct side band */
3608 rts_rspec &= ~RSPEC_BW_MASK;
3609
3610 /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel
3611 * (DUP), otherwise send RTS on control channel
3612 */
3613 if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec))
3614 rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
3615 else
3616 rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
3617
3618 /* pick siso/cdd as default for ofdm */
3619 if (IS_OFDM(rts_rspec)) {
3620 rts_rspec &= ~RSPEC_STF_MASK;
3621 rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
3622 }
3623 }
3624 return rts_rspec;
3625}
3626
3627/*
3628 * Add struct d11txh, struct cck_phy_hdr.
3629 *
3630 * 'p' data must start with 802.11 MAC header
3631 * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
3632 *
3633 * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
3634 *
3635 */
3636static u16
3637brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
3638 struct sk_buff *p, struct scb *scb, uint frag,
3639 uint nfrags, uint queue, uint next_frag_len,
3640 struct wsec_key *key, ratespec_t rspec_override)
3641{
3642 struct ieee80211_hdr *h;
3643 struct d11txh *txh;
3644 u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
3645 int len, phylen, rts_phylen;
3646 u16 mch, phyctl, xfts, mainrates;
3647 u16 seq = 0, mcl = 0, status = 0, frameid = 0;
3648 ratespec_t rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M }, rts_rspec[2] = {
3649 BRCM_RATE_1M, BRCM_RATE_1M};
3650 bool use_rts = false;
3651 bool use_cts = false;
3652 bool use_rifs = false;
3653 bool short_preamble[2] = { false, false };
3654 u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
3655 u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
3656 u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
3657 struct ieee80211_rts *rts = NULL;
3658 bool qos;
3659 uint ac;
3660 u32 rate_val[2];
3661 bool hwtkmic = false;
3662 u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
3663#define ANTCFG_NONE 0xFF
3664 u8 antcfg = ANTCFG_NONE;
3665 u8 fbantcfg = ANTCFG_NONE;
3666 uint phyctl1_stf = 0;
3667 u16 durid = 0;
3668 struct ieee80211_tx_rate *txrate[2];
3669 int k;
3670 struct ieee80211_tx_info *tx_info;
3671 bool is_mcs[2];
3672 u16 mimo_txbw;
3673 u8 mimo_preamble_type;
3674
3675 /* locate 802.11 MAC header */
3676 h = (struct ieee80211_hdr *)(p->data);
3677 qos = ieee80211_is_data_qos(h->frame_control);
3678
3679 /* compute length of frame in bytes for use in PLCP computations */
3680 len = brcmu_pkttotlen(p);
3681 phylen = len + FCS_LEN;
3682
3683 /* If WEP enabled, add room in phylen for the additional bytes of
3684 * ICV which MAC generates. We do NOT add the additional bytes to
3685 * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN
3686 * in this case
3687 */
3688 if (key) {
3689 phylen += key->icv_len;
3690 }
3691
3692 /* Get tx_info */
3693 tx_info = IEEE80211_SKB_CB(p);
3694
3695 /* add PLCP */
3696 plcp = skb_push(p, D11_PHY_HDR_LEN);
3697
3698 /* add Broadcom tx descriptor header */
3699 txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
3700 memset(txh, 0, D11_TXH_LEN);
3701
3702 /* setup frameid */
3703 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
3704 /* non-AP STA should never use BCMC queue */
3705 if (queue == TX_BCMC_FIFO) {
3706 wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
3707 "TX_BCMC!\n", BRCMS_UNIT(wlc), __func__);
3708 frameid = bcmc_fid_generate(wlc, NULL, txh);
3709 } else {
3710 /* Increment the counter for first fragment */
3711 if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
3712 SCB_SEQNUM(scb, p->priority)++;
3713 }
3714
3715 /* extract fragment number from frame first */
3716 seq = le16_to_cpu(seq) & FRAGNUM_MASK;
3717 seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT);
3718 h->seq_ctrl = cpu_to_le16(seq);
3719
3720 frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
3721 (queue & TXFID_QUEUE_MASK);
3722 }
3723 }
3724 frameid |= queue & TXFID_QUEUE_MASK;
3725
3726 /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
3727 if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control))
3728 mcl |= TXC_IGNOREPMQ;
3729
3730 txrate[0] = tx_info->control.rates;
3731 txrate[1] = txrate[0] + 1;
3732
3733 /* if rate control algorithm didn't give us a fallback rate, use the primary rate */
3734 if (txrate[1]->idx < 0) {
3735 txrate[1] = txrate[0];
3736 }
3737
3738 for (k = 0; k < hw->max_rates; k++) {
3739 is_mcs[k] =
3740 txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
3741 if (!is_mcs[k]) {
3742 if ((txrate[k]->idx >= 0)
3743 && (txrate[k]->idx <
3744 hw->wiphy->bands[tx_info->band]->n_bitrates)) {
3745 rate_val[k] =
3746 hw->wiphy->bands[tx_info->band]->
3747 bitrates[txrate[k]->idx].hw_value;
3748 short_preamble[k] =
3749 txrate[k]->
3750 flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
3751 true : false;
3752 } else {
3753 rate_val[k] = BRCM_RATE_1M;
3754 }
3755 } else {
3756 rate_val[k] = txrate[k]->idx;
3757 }
3758 /* Currently only support same setting for primay and fallback rates.
3759 * Unify flags for each rate into a single value for the frame
3760 */
3761 use_rts |=
3762 txrate[k]->
3763 flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
3764 use_cts |=
3765 txrate[k]->
3766 flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
3767
3768 if (is_mcs[k])
3769 rate_val[k] |= NRATE_MCS_INUSE;
3770
3771 rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]);
3772
3773 /* (1) RATE: determine and validate primary rate and fallback rates */
3774 if (!RSPEC_ACTIVE(rspec[k])) {
3775 rspec[k] = BRCM_RATE_1M;
3776 } else {
3777 if (!is_multicast_ether_addr(h->addr1)) {
3778 /* set tx antenna config */
3779 brcms_c_antsel_antcfg_get(wlc->asi, false,
3780 false, 0, 0, &antcfg, &fbantcfg);
3781 }
3782 }
3783 }
3784
3785 phyctl1_stf = wlc->stf->ss_opmode;
3786
3787 if (N_ENAB(wlc->pub)) {
3788 for (k = 0; k < hw->max_rates; k++) {
3789 /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */
3790 if (((IS_MCS(rspec[k]) &&
3791 IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) ||
3792 IS_OFDM(rspec[k]))
3793 && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
3794 || !(rspec[k] & RSPEC_OVERRIDE))) {
3795 rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
3796
3797 /* For SISO MCS use STBC if possible */
3798 if (IS_MCS(rspec[k])
3799 && BRCMS_STF_SS_STBC_TX(wlc, scb)) {
3800 u8 stc;
3801
3802 stc = 1; /* Nss for single stream is always 1 */
3803 rspec[k] |=
3804 (PHY_TXC1_MODE_STBC <<
3805 RSPEC_STF_SHIFT) | (stc <<
3806 RSPEC_STC_SHIFT);
3807 } else
3808 rspec[k] |=
3809 (phyctl1_stf << RSPEC_STF_SHIFT);
3810 }
3811
3812 /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */
3813 if (CHSPEC_WLC_BW(wlc->chanspec) == BRCMS_40_MHZ) {
3814 /* default txbw is 20in40 SB */
3815 mimo_ctlchbw = mimo_txbw =
3816 CHSPEC_SB_UPPER(BRCMS_BAND_PI_RADIO_CHANSPEC)
3817 ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
3818
3819 if (IS_MCS(rspec[k])) {
3820 /* mcs 32 must be 40b/w DUP */
3821 if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
3822 mimo_txbw =
3823 PHY_TXC1_BW_40MHZ_DUP;
3824 /* use override */
3825 } else if (wlc->mimo_40txbw != AUTO)
3826 mimo_txbw = wlc->mimo_40txbw;
3827 /* else check if dst is using 40 Mhz */
3828 else if (scb->flags & SCB_IS40)
3829 mimo_txbw = PHY_TXC1_BW_40MHZ;
3830 } else if (IS_OFDM(rspec[k])) {
3831 if (wlc->ofdm_40txbw != AUTO)
3832 mimo_txbw = wlc->ofdm_40txbw;
3833 } else {
3834 if (wlc->cck_40txbw != AUTO)
3835 mimo_txbw = wlc->cck_40txbw;
3836 }
3837 } else {
3838 /* mcs32 is 40 b/w only.
3839 * This is possible for probe packets on a STA during SCAN
3840 */
3841 if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
3842 /* mcs 0 */
3843 rspec[k] = RSPEC_MIMORATE;
3844 }
3845 mimo_txbw = PHY_TXC1_BW_20MHZ;
3846 }
3847
3848 /* Set channel width */
3849 rspec[k] &= ~RSPEC_BW_MASK;
3850 if ((k == 0) || ((k > 0) && IS_MCS(rspec[k])))
3851 rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
3852 else
3853 rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
3854
3855 /* Set Short GI */
3856#ifdef NOSGIYET
3857 if (IS_MCS(rspec[k])
3858 && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
3859 rspec[k] |= RSPEC_SHORT_GI;
3860 else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
3861 rspec[k] &= ~RSPEC_SHORT_GI;
3862#else
3863 rspec[k] &= ~RSPEC_SHORT_GI;
3864#endif
3865
3866 mimo_preamble_type = BRCMS_MM_PREAMBLE;
3867 if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
3868 mimo_preamble_type = BRCMS_GF_PREAMBLE;
3869
3870 if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
3871 && (!IS_MCS(rspec[k]))) {
3872 wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
3873 "RC_MCS != IS_MCS(rspec)\n",
3874 BRCMS_UNIT(wlc), __func__);
3875 }
3876
3877 if (IS_MCS(rspec[k])) {
3878 preamble_type[k] = mimo_preamble_type;
3879
3880 /* if SGI is selected, then forced mm for single stream */
3881 if ((rspec[k] & RSPEC_SHORT_GI)
3882 && IS_SINGLE_STREAM(rspec[k] &
3883 RSPEC_RATE_MASK)) {
3884 preamble_type[k] = BRCMS_MM_PREAMBLE;
3885 }
3886 }
3887
3888 /* should be better conditionalized */
3889 if (!IS_MCS(rspec[0])
3890 && (tx_info->control.rates[0].
3891 flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
3892 preamble_type[k] = BRCMS_SHORT_PREAMBLE;
3893 }
3894 } else {
3895 for (k = 0; k < hw->max_rates; k++) {
3896 /* Set ctrlchbw as 20Mhz */
3897 rspec[k] &= ~RSPEC_BW_MASK;
3898 rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
3899
3900 /* for nphy, stf of ofdm frames must follow policies */
3901 if (BRCMS_ISNPHY(wlc->band) && IS_OFDM(rspec[k])) {
3902 rspec[k] &= ~RSPEC_STF_MASK;
3903 rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
3904 }
3905 }
3906 }
3907
3908 /* Reset these for use with AMPDU's */
3909 txrate[0]->count = 0;
3910 txrate[1]->count = 0;
3911
3912 /* (2) PROTECTION, may change rspec */
3913 if ((ieee80211_is_data(h->frame_control) ||
3914 ieee80211_is_mgmt(h->frame_control)) &&
3915 (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
3916 use_rts = true;
3917
3918 /* (3) PLCP: determine PLCP header and MAC duration,
3919 * fill struct d11txh */
3920 brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp);
3921 brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
3922 memcpy(&txh->FragPLCPFallback,
3923 plcp_fallback, sizeof(txh->FragPLCPFallback));
3924
3925 /* Length field now put in CCK FBR CRC field */
3926 if (IS_CCK(rspec[1])) {
3927 txh->FragPLCPFallback[4] = phylen & 0xff;
3928 txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
3929 }
3930
3931 /* MIMO-RATE: need validation ?? */
3932 mainrates = IS_OFDM(rspec[0]) ?
3933 D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) :
3934 plcp[0];
3935
3936 /* DUR field for main rate */
3937 if (!ieee80211_is_pspoll(h->frame_control) &&
3938 !is_multicast_ether_addr(h->addr1) && !use_rifs) {
3939 durid =
3940 brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0],
3941 next_frag_len);
3942 h->duration_id = cpu_to_le16(durid);
3943 } else if (use_rifs) {
3944 /* NAV protect to end of next max packet size */
3945 durid =
3946 (u16) brcms_c_calc_frame_time(wlc, rspec[0],
3947 preamble_type[0],
3948 DOT11_MAX_FRAG_LEN);
3949 durid += RIFS_11N_TIME;
3950 h->duration_id = cpu_to_le16(durid);
3951 }
3952
3953 /* DUR field for fallback rate */
3954 if (ieee80211_is_pspoll(h->frame_control))
3955 txh->FragDurFallback = h->duration_id;
3956 else if (is_multicast_ether_addr(h->addr1) || use_rifs)
3957 txh->FragDurFallback = 0;
3958 else {
3959 durid = brcms_c_compute_frame_dur(wlc, rspec[1],
3960 preamble_type[1], next_frag_len);
3961 txh->FragDurFallback = cpu_to_le16(durid);
3962 }
3963
3964 /* (4) MAC-HDR: MacTxControlLow */
3965 if (frag == 0)
3966 mcl |= TXC_STARTMSDU;
3967
3968 if (!is_multicast_ether_addr(h->addr1))
3969 mcl |= TXC_IMMEDACK;
3970
3971 if (BAND_5G(wlc->band->bandtype))
3972 mcl |= TXC_FREQBAND_5G;
3973
3974 if (CHSPEC_IS40(BRCMS_BAND_PI_RADIO_CHANSPEC))
3975 mcl |= TXC_BW_40;
3976
3977 /* set AMIC bit if using hardware TKIP MIC */
3978 if (hwtkmic)
3979 mcl |= TXC_AMIC;
3980
3981 txh->MacTxControlLow = cpu_to_le16(mcl);
3982
3983 /* MacTxControlHigh */
3984 mch = 0;
3985
3986 /* Set fallback rate preamble type */
3987 if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) ||
3988 (preamble_type[1] == BRCMS_GF_PREAMBLE)) {
3989 if (RSPEC2RATE(rspec[1]) != BRCM_RATE_1M)
3990 mch |= TXC_PREAMBLE_DATA_FB_SHORT;
3991 }
3992
3993 /* MacFrameControl */
3994 memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
3995 txh->TxFesTimeNormal = cpu_to_le16(0);
3996
3997 txh->TxFesTimeFallback = cpu_to_le16(0);
3998
3999 /* TxFrameRA */
4000 memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
4001
4002 /* TxFrameID */
4003 txh->TxFrameID = cpu_to_le16(frameid);
4004
4005 /* TxStatus, Note the case of recreating the first frag of a suppressed frame
4006 * then we may need to reset the retry cnt's via the status reg
4007 */
4008 txh->TxStatus = cpu_to_le16(status);
4009
4010 /* extra fields for ucode AMPDU aggregation, the new fields are added to
4011 * the END of previous structure so that it's compatible in driver.
4012 */
4013 txh->MaxNMpdus = cpu_to_le16(0);
4014 txh->MaxABytes_MRT = cpu_to_le16(0);
4015 txh->MaxABytes_FBR = cpu_to_le16(0);
4016 txh->MinMBytes = cpu_to_le16(0);
4017
4018 /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
4019 * furnish struct d11txh */
4020 /* RTS PLCP header and RTS frame */
4021 if (use_rts || use_cts) {
4022 if (use_rts && use_cts)
4023 use_cts = false;
4024
4025 for (k = 0; k < 2; k++) {
4026 rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k],
4027 false,
4028 mimo_ctlchbw);
4029 }
4030
4031 if (!IS_OFDM(rts_rspec[0]) &&
4032 !((RSPEC2RATE(rts_rspec[0]) == BRCM_RATE_1M) ||
4033 (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
4034 rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE;
4035 mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
4036 }
4037
4038 if (!IS_OFDM(rts_rspec[1]) &&
4039 !((RSPEC2RATE(rts_rspec[1]) == BRCM_RATE_1M) ||
4040 (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
4041 rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE;
4042 mch |= TXC_PREAMBLE_RTS_FB_SHORT;
4043 }
4044
4045 /* RTS/CTS additions to MacTxControlLow */
4046 if (use_cts) {
4047 txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
4048 } else {
4049 txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
4050 txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
4051 }
4052
4053 /* RTS PLCP header */
4054 rts_plcp = txh->RTSPhyHeader;
4055 if (use_cts)
4056 rts_phylen = DOT11_CTS_LEN + FCS_LEN;
4057 else
4058 rts_phylen = DOT11_RTS_LEN + FCS_LEN;
4059
4060 brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
4061
4062 /* fallback rate version of RTS PLCP header */
4063 brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen,
4064 rts_plcp_fallback);
4065 memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
4066 sizeof(txh->RTSPLCPFallback));
4067
4068 /* RTS frame fields... */
4069 rts = (struct ieee80211_rts *)&txh->rts_frame;
4070
4071 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
4072 rspec[0], rts_preamble_type[0],
4073 preamble_type[0], phylen, false);
4074 rts->duration = cpu_to_le16(durid);
4075 /* fallback rate version of RTS DUR field */
4076 durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
4077 rts_rspec[1], rspec[1],
4078 rts_preamble_type[1],
4079 preamble_type[1], phylen, false);
4080 txh->RTSDurFallback = cpu_to_le16(durid);
4081
4082 if (use_cts) {
4083 rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
4084 IEEE80211_STYPE_CTS);
4085
4086 memcpy(&rts->ra, &h->addr2, ETH_ALEN);
4087 } else {
4088 rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
4089 IEEE80211_STYPE_RTS);
4090
4091 memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
4092 }
4093
4094 /* mainrate
4095 * low 8 bits: main frag rate/mcs,
4096 * high 8 bits: rts/cts rate/mcs
4097 */
4098 mainrates |= (IS_OFDM(rts_rspec[0]) ?
4099 D11A_PHY_HDR_GRATE(
4100 (struct ofdm_phy_hdr *) rts_plcp) :
4101 rts_plcp[0]) << 8;
4102 } else {
4103 memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
4104 memset((char *)&txh->rts_frame, 0,
4105 sizeof(struct ieee80211_rts));
4106 memset((char *)txh->RTSPLCPFallback, 0,
4107 sizeof(txh->RTSPLCPFallback));
4108 txh->RTSDurFallback = 0;
4109 }
4110
4111#ifdef SUPPORT_40MHZ
4112 /* add null delimiter count */
4113 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) {
4114 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
4115 brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
4116 }
4117#endif
4118
4119 /* Now that RTS/RTS FB preamble types are updated, write the final value */
4120 txh->MacTxControlHigh = cpu_to_le16(mch);
4121
4122 /* MainRates (both the rts and frag plcp rates have been calculated now) */
4123 txh->MainRates = cpu_to_le16(mainrates);
4124
4125 /* XtraFrameTypes */
4126 xfts = FRAMETYPE(rspec[1], wlc->mimoft);
4127 xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
4128 xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
4129 xfts |=
4130 CHSPEC_CHANNEL(BRCMS_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT;
4131 txh->XtraFrameTypes = cpu_to_le16(xfts);
4132
4133 /* PhyTxControlWord */
4134 phyctl = FRAMETYPE(rspec[0], wlc->mimoft);
4135 if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) ||
4136 (preamble_type[0] == BRCMS_GF_PREAMBLE)) {
4137 if (RSPEC2RATE(rspec[0]) != BRCM_RATE_1M)
4138 phyctl |= PHY_TXC_SHORT_HDR;
4139 }
4140
4141 /* phytxant is properly bit shifted */
4142 phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
4143 txh->PhyTxControlWord = cpu_to_le16(phyctl);
4144
4145 /* PhyTxControlWord_1 */
4146 if (BRCMS_PHY_11N_CAP(wlc->band)) {
4147 u16 phyctl1 = 0;
4148
4149 phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]);
4150 txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
4151 phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]);
4152 txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
4153
4154 if (use_rts || use_cts) {
4155 phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]);
4156 txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
4157 phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]);
4158 txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
4159 }
4160
4161 /*
4162 * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set,
4163 * fill in non-zero MModeLen and/or MModeFbrLen
4164 * it will be unnecessary if they are separated
4165 */
4166 if (IS_MCS(rspec[0]) &&
4167 (preamble_type[0] == BRCMS_MM_PREAMBLE)) {
4168 u16 mmodelen =
4169 brcms_c_calc_lsig_len(wlc, rspec[0], phylen);
4170 txh->MModeLen = cpu_to_le16(mmodelen);
4171 }
4172
4173 if (IS_MCS(rspec[1]) &&
4174 (preamble_type[1] == BRCMS_MM_PREAMBLE)) {
4175 u16 mmodefbrlen =
4176 brcms_c_calc_lsig_len(wlc, rspec[1], phylen);
4177 txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
4178 }
4179 }
4180
4181 ac = skb_get_queue_mapping(p);
4182 if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) {
4183 uint frag_dur, dur, dur_fallback;
4184
4185 /* WME: Update TXOP threshold */
4186 if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) {
4187 frag_dur =
4188 brcms_c_calc_frame_time(wlc, rspec[0],
4189 preamble_type[0], phylen);
4190
4191 if (rts) {
4192 /* 1 RTS or CTS-to-self frame */
4193 dur =
4194 brcms_c_calc_cts_time(wlc, rts_rspec[0],
4195 rts_preamble_type[0]);
4196 dur_fallback =
4197 brcms_c_calc_cts_time(wlc, rts_rspec[1],
4198 rts_preamble_type[1]);
4199 /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
4200 dur += le16_to_cpu(rts->duration);
4201 dur_fallback +=
4202 le16_to_cpu(txh->RTSDurFallback);
4203 } else if (use_rifs) {
4204 dur = frag_dur;
4205 dur_fallback = 0;
4206 } else {
4207 /* frame + SIFS + ACK */
4208 dur = frag_dur;
4209 dur +=
4210 brcms_c_compute_frame_dur(wlc, rspec[0],
4211 preamble_type[0], 0);
4212
4213 dur_fallback =
4214 brcms_c_calc_frame_time(wlc, rspec[1],
4215 preamble_type[1],
4216 phylen);
4217 dur_fallback +=
4218 brcms_c_compute_frame_dur(wlc, rspec[1],
4219 preamble_type[1], 0);
4220 }
4221 /* NEED to set TxFesTimeNormal (hard) */
4222 txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
4223 /* NEED to set fallback rate version of TxFesTimeNormal (hard) */
4224 txh->TxFesTimeFallback =
4225 cpu_to_le16((u16) dur_fallback);
4226
4227 /* update txop byte threshold (txop minus intraframe overhead) */
4228 if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
4229 {
4230 uint newfragthresh;
4231
4232 newfragthresh =
4233 brcms_c_calc_frame_len(wlc,
4234 rspec[0], preamble_type[0],
4235 (wlc->edcf_txop[ac] -
4236 (dur - frag_dur)));
4237 /* range bound the fragthreshold */
4238 if (newfragthresh < DOT11_MIN_FRAG_LEN)
4239 newfragthresh =
4240 DOT11_MIN_FRAG_LEN;
4241 else if (newfragthresh >
4242 wlc->usr_fragthresh)
4243 newfragthresh =
4244 wlc->usr_fragthresh;
4245 /* update the fragthresh and do txc update */
4246 if (wlc->fragthresh[queue] !=
4247 (u16) newfragthresh) {
4248 wlc->fragthresh[queue] =
4249 (u16) newfragthresh;
4250 }
4251 }
4252 } else
4253 wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
4254 "for rate %d\n",
4255 wlc->pub->unit, fifo_names[queue],
4256 RSPEC2RATE(rspec[0]));
4257
4258 if (dur > wlc->edcf_txop[ac])
4259 wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
4260 "exceeded phylen %d/%d dur %d/%d\n",
4261 wlc->pub->unit, __func__,
4262 fifo_names[queue],
4263 phylen, wlc->fragthresh[queue],
4264 dur, wlc->edcf_txop[ac]);
4265 }
4266 }
4267
4268 return 0;
4269}
4270
4271void brcms_c_tbtt(struct brcms_c_info *wlc)
4272{
4273 struct brcms_bss_cfg *cfg = wlc->cfg;
4274
4275 if (!cfg->BSS) {
4276 /* DirFrmQ is now valid...defer setting until end of ATIM window */
4277 wlc->qvalid |= MCMD_DIRFRMQVAL;
4278 }
4279}
4280
4281static void brcms_c_war16165(struct brcms_c_info *wlc, bool tx)
4282{
4283 if (tx) {
4284 /* the post-increment is used in STAY_AWAKE macro */
4285 if (wlc->txpend16165war++ == 0)
4286 brcms_c_set_ps_ctrl(wlc);
4287 } else {
4288 wlc->txpend16165war--;
4289 if (wlc->txpend16165war == 0)
4290 brcms_c_set_ps_ctrl(wlc);
4291 }
4292}
4293
4294/* process an individual struct tx_status */
4295bool
4296brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs, u32 frm_tx2)
4297{
4298 struct sk_buff *p;
4299 uint queue;
4300 struct d11txh *txh;
4301 struct scb *scb = NULL;
4302 bool free_pdu;
4303 int tx_rts, tx_frame_count, tx_rts_count;
4304 uint totlen, supr_status;
4305 bool lastframe;
4306 struct ieee80211_hdr *h;
4307 u16 mcl;
4308 struct ieee80211_tx_info *tx_info;
4309 struct ieee80211_tx_rate *txrate;
4310 int i;
4311
4312 (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */
4313
4314 /* discard intermediate indications for ucode with one legitimate case:
4315 * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
4316 * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
4317 * transmission count)
4318 */
4319 if (!(txs->status & TX_STATUS_AMPDU)
4320 && (txs->status & TX_STATUS_INTERMEDIATE)) {
4321 wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
4322 __func__);
4323 return false;
4324 }
4325
4326 queue = txs->frameid & TXFID_QUEUE_MASK;
4327 if (queue >= NFIFO) {
4328 p = NULL;
4329 goto fatal;
4330 }
4331
4332 p = GETNEXTTXP(wlc, queue);
4333 if (BRCMS_WAR16165(wlc))
4334 brcms_c_war16165(wlc, false);
4335 if (p == NULL)
4336 goto fatal;
4337
4338 txh = (struct d11txh *) (p->data);
4339 mcl = le16_to_cpu(txh->MacTxControlLow);
4340
4341 if (txs->phyerr) {
4342 if (WL_ERROR_ON()) {
4343 wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
4344 txs->phyerr, txh->MainRates);
4345 brcms_c_print_txdesc(txh);
4346 }
4347 brcms_c_print_txstatus(txs);
4348 }
4349
4350 if (txs->frameid != cpu_to_le16(txh->TxFrameID))
4351 goto fatal;
4352 tx_info = IEEE80211_SKB_CB(p);
4353 h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
4354
4355 if (tx_info->control.sta)
4356 scb = (struct scb *)tx_info->control.sta->drv_priv;
4357
4358 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
4359 brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
4360 return false;
4361 }
4362
4363 supr_status = txs->status & TX_STATUS_SUPR_MASK;
4364 if (supr_status == TX_STATUS_SUPR_BADCH)
4365 BCMMSG(wlc->wiphy,
4366 "%s: Pkt tx suppressed, possibly channel %d\n",
4367 __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
4368
4369 tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS;
4370 tx_frame_count =
4371 (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
4372 tx_rts_count =
4373 (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
4374
4375 lastframe = !ieee80211_has_morefrags(h->frame_control);
4376
4377 if (!lastframe) {
4378 wiphy_err(wlc->wiphy, "Not last frame!\n");
4379 } else {
4380 /*
4381 * Set information to be consumed by Minstrel ht.
4382 *
4383 * The "fallback limit" is the number of tx attempts a given
4384 * MPDU is sent at the "primary" rate. Tx attempts beyond that
4385 * limit are sent at the "secondary" rate.
4386 * A 'short frame' does not exceed RTS treshold.
4387 */
4388 u16 sfbl, /* Short Frame Rate Fallback Limit */
4389 lfbl, /* Long Frame Rate Fallback Limit */
4390 fbl;
4391
4392 if (queue < AC_COUNT) {
4393 sfbl = BRCMS_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]);
4394 lfbl = BRCMS_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]);
4395 } else {
4396 sfbl = wlc->SFBL;
4397 lfbl = wlc->LFBL;
4398 }
4399
4400 txrate = tx_info->status.rates;
4401 if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
4402 fbl = lfbl;
4403 else
4404 fbl = sfbl;
4405
4406 ieee80211_tx_info_clear_status(tx_info);
4407
4408 if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) {
4409 /* rate selection requested a fallback rate and we used it */
4410 txrate[0].count = fbl;
4411 txrate[1].count = tx_frame_count - fbl;
4412 } else {
4413 /* rate selection did not request fallback rate, or we didn't need it */
4414 txrate[0].count = tx_frame_count;
4415 /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */
4416 txrate[1].idx = -1;
4417 txrate[1].count = 0;
4418 }
4419
4420 /* clear the rest of the rates */
4421 for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
4422 txrate[i].idx = -1;
4423 txrate[i].count = 0;
4424 }
4425
4426 if (txs->status & TX_STATUS_ACK_RCV)
4427 tx_info->flags |= IEEE80211_TX_STAT_ACK;
4428 }
4429
4430 totlen = brcmu_pkttotlen(p);
4431 free_pdu = true;
4432
4433 brcms_c_txfifo_complete(wlc, queue, 1);
4434
4435 if (lastframe) {
4436 p->next = NULL;
4437 p->prev = NULL;
4438 /* remove PLCP & Broadcom tx descriptor header */
4439 skb_pull(p, D11_PHY_HDR_LEN);
4440 skb_pull(p, D11_TXH_LEN);
4441 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
4442 } else {
4443 wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
4444 "tx_status\n", __func__);
4445 }
4446
4447 return false;
4448
4449 fatal:
4450 if (p)
4451 brcmu_pkt_buf_free_skb(p);
4452
4453 return true;
4454
4455}
4456
4457void
4458brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
4459{
4460 TXPKTPENDDEC(wlc, fifo, txpktpend);
4461 BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
4462 TXPKTPENDGET(wlc, fifo));
4463
4464 /* There is more room; mark precedences related to this FIFO sendable */
4465 BRCMS_TX_FIFO_ENAB(wlc, fifo);
4466
4467 /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */
4468 if (AP_ENAB(wlc->pub) &&
4469 !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) {
4470 brcms_c_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, BRCM_BAND_AUTO);
4471 }
4472
4473 /* figure out which bsscfg is being worked on... */
4474}
4475
4476/* Update beacon listen interval in shared memory */
4477void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
4478{
4479 if (AP_ENAB(wlc->pub))
4480 return;
4481
4482 /* wake up every DTIM is the default */
4483 if (wlc->bcn_li_dtim == 1)
4484 brcms_c_write_shm(wlc, M_BCN_LI, 0);
4485 else
4486 brcms_c_write_shm(wlc, M_BCN_LI,
4487 (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
4488}
4489
4490/*
4491 * recover 64bit TSF value from the 16bit TSF value in the rx header
4492 * given the assumption that the TSF passed in header is within 65ms
4493 * of the current tsf.
4494 *
4495 * 6 5 4 4 3 2 1
4496 * 3.......6.......8.......0.......2.......4.......6.......8......0
4497 * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
4498 *
4499 * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
4500 * tsf_l is filled in by brcms_b_recv, which is done earlier in the
4501 * receive call sequence after rx interrupt. Only the higher 16 bits
4502 * are used. Finally, the tsf_h is read from the tsf register.
4503 */
4504static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
4505 struct brcms_d11rxhdr *rxh)
4506{
4507 u32 tsf_h, tsf_l;
4508 u16 rx_tsf_0_15, rx_tsf_16_31;
4509
4510 brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
4511
4512 rx_tsf_16_31 = (u16)(tsf_l >> 16);
4513 rx_tsf_0_15 = rxh->rxhdr.RxTSFTime;
4514
4515 /*
4516 * a greater tsf time indicates the low 16 bits of
4517 * tsf_l wrapped, so decrement the high 16 bits.
4518 */
4519 if ((u16)tsf_l < rx_tsf_0_15) {
4520 rx_tsf_16_31 -= 1;
4521 if (rx_tsf_16_31 == 0xffff)
4522 tsf_h -= 1;
4523 }
4524
4525 return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
4526}
4527
4528static void
4529prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
4530 struct sk_buff *p,
4531 struct ieee80211_rx_status *rx_status)
4532{
4533 struct brcms_d11rxhdr *wlc_rxh = (struct brcms_d11rxhdr *) rxh;
4534 int preamble;
4535 int channel;
4536 ratespec_t rspec;
4537 unsigned char *plcp;
4538
4539 /* fill in TSF and flag its presence */
4540 rx_status->mactime = brcms_c_recover_tsf64(wlc, wlc_rxh);
4541 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
4542
4543 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
4544
4545 if (channel > 14) {
4546 rx_status->band = IEEE80211_BAND_5GHZ;
4547 rx_status->freq = ieee80211_ofdm_chan_to_freq(
4548 WF_CHAN_FACTOR_5_G/2, channel);
4549
4550 } else {
4551 rx_status->band = IEEE80211_BAND_2GHZ;
4552 rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
4553 }
4554
4555 rx_status->signal = wlc_rxh->rssi; /* signal */
4556
4557 /* noise */
4558 /* qual */
4559 rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */
4560
4561 plcp = p->data;
4562
4563 rspec = brcms_c_compute_rspec(rxh, plcp);
4564 if (IS_MCS(rspec)) {
4565 rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
4566 rx_status->flag |= RX_FLAG_HT;
4567 if (RSPEC_IS40MHZ(rspec))
4568 rx_status->flag |= RX_FLAG_40MHZ;
4569 } else {
4570 switch (RSPEC2RATE(rspec)) {
4571 case BRCM_RATE_1M:
4572 rx_status->rate_idx = 0;
4573 break;
4574 case BRCM_RATE_2M:
4575 rx_status->rate_idx = 1;
4576 break;
4577 case BRCM_RATE_5M5:
4578 rx_status->rate_idx = 2;
4579 break;
4580 case BRCM_RATE_11M:
4581 rx_status->rate_idx = 3;
4582 break;
4583 case BRCM_RATE_6M:
4584 rx_status->rate_idx = 4;
4585 break;
4586 case BRCM_RATE_9M:
4587 rx_status->rate_idx = 5;
4588 break;
4589 case BRCM_RATE_12M:
4590 rx_status->rate_idx = 6;
4591 break;
4592 case BRCM_RATE_18M:
4593 rx_status->rate_idx = 7;
4594 break;
4595 case BRCM_RATE_24M:
4596 rx_status->rate_idx = 8;
4597 break;
4598 case BRCM_RATE_36M:
4599 rx_status->rate_idx = 9;
4600 break;
4601 case BRCM_RATE_48M:
4602 rx_status->rate_idx = 10;
4603 break;
4604 case BRCM_RATE_54M:
4605 rx_status->rate_idx = 11;
4606 break;
4607 default:
4608 wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
4609 }
4610
4611 /*
4612 * For 5GHz, we should decrease the index as it is
4613 * a subset of the 2.4G rates. See bitrates field
4614 * of brcms_band_5GHz_nphy (in mac80211_if.c).
4615 */
4616 if (rx_status->band == IEEE80211_BAND_5GHZ)
4617 rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
4618
4619 /* Determine short preamble and rate_idx */
4620 preamble = 0;
4621 if (IS_CCK(rspec)) {
4622 if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
4623 rx_status->flag |= RX_FLAG_SHORTPRE;
4624 } else if (IS_OFDM(rspec)) {
4625 rx_status->flag |= RX_FLAG_SHORTPRE;
4626 } else {
4627 wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
4628 __func__);
4629 }
4630 }
4631
4632 if (PLCP3_ISSGI(plcp[3]))
4633 rx_status->flag |= RX_FLAG_SHORT_GI;
4634
4635 if (rxh->RxStatus1 & RXS_DECERR) {
4636 rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
4637 wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n",
4638 __func__);
4639 }
4640 if (rxh->RxStatus1 & RXS_FCSERR) {
4641 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
4642 wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n",
4643 __func__);
4644 }
4645}
4646
4647static void
4648brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
4649 struct sk_buff *p)
4650{
4651 int len_mpdu;
4652 struct ieee80211_rx_status rx_status;
4653
4654 memset(&rx_status, 0, sizeof(rx_status));
4655 prep_mac80211_status(wlc, rxh, p, &rx_status);
4656
4657 /* mac header+body length, exclude CRC and plcp header */
4658 len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
4659 skb_pull(p, D11_PHY_HDR_LEN);
4660 __skb_trim(p, len_mpdu);
4661
4662 memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
4663 ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
4664 return;
4665}
4666
4667/* Process received frames */
4668/*
4669 * Return true if more frames need to be processed. false otherwise.
4670 * Param 'bound' indicates max. # frames to process before break out.
4671 */
4672void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
4673{
4674 struct d11rxhdr *rxh;
4675 struct ieee80211_hdr *h;
4676 uint len;
4677 bool is_amsdu;
4678
4679 BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
4680
4681 /* frame starts with rxhdr */
4682 rxh = (struct d11rxhdr *) (p->data);
4683
4684 /* strip off rxhdr */
4685 skb_pull(p, BRCMS_HWRXOFF);
4686
4687 /* fixup rx header endianness */
4688 rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize);
4689 rxh->PhyRxStatus_0 = le16_to_cpu(rxh->PhyRxStatus_0);
4690 rxh->PhyRxStatus_1 = le16_to_cpu(rxh->PhyRxStatus_1);
4691 rxh->PhyRxStatus_2 = le16_to_cpu(rxh->PhyRxStatus_2);
4692 rxh->PhyRxStatus_3 = le16_to_cpu(rxh->PhyRxStatus_3);
4693 rxh->PhyRxStatus_4 = le16_to_cpu(rxh->PhyRxStatus_4);
4694 rxh->PhyRxStatus_5 = le16_to_cpu(rxh->PhyRxStatus_5);
4695 rxh->RxStatus1 = le16_to_cpu(rxh->RxStatus1);
4696 rxh->RxStatus2 = le16_to_cpu(rxh->RxStatus2);
4697 rxh->RxTSFTime = le16_to_cpu(rxh->RxTSFTime);
4698 rxh->RxChan = le16_to_cpu(rxh->RxChan);
4699
4700 /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
4701 if (rxh->RxStatus1 & RXS_PBPRES) {
4702 if (p->len < 2) {
4703 wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
4704 "len %d\n", wlc->pub->unit, p->len);
4705 goto toss;
4706 }
4707 skb_pull(p, 2);
4708 }
4709
4710 h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
4711 len = p->len;
4712
4713 if (rxh->RxStatus1 & RXS_FCSERR) {
4714 if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
4715 wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
4716 " tossing\n");
4717 goto toss;
4718 } else {
4719 wiphy_err(wlc->wiphy, "RCSERR!!!\n");
4720 goto toss;
4721 }
4722 }
4723
4724 /* check received pkt has at least frame control field */
4725 if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) {
4726 goto toss;
4727 }
4728
4729 is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
4730
4731 /* explicitly test bad src address to avoid sending bad deauth */
4732 if (!is_amsdu) {
4733 /* CTS and ACK CTL frames are w/o a2 */
4734
4735 if (ieee80211_is_data(h->frame_control) ||
4736 ieee80211_is_mgmt(h->frame_control)) {
4737 if ((is_zero_ether_addr(h->addr2) ||
4738 is_multicast_ether_addr(h->addr2))) {
4739 wiphy_err(wlc->wiphy, "wl%d: %s: dropping a "
4740 "frame with invalid src mac address,"
4741 " a2: %pM\n",
4742 wlc->pub->unit, __func__, h->addr2);
4743 goto toss;
4744 }
4745 }
4746 }
4747
4748 /* due to sheer numbers, toss out probe reqs for now */
4749 if (ieee80211_is_probe_req(h->frame_control))
4750 goto toss;
4751
4752 if (is_amsdu)
4753 goto toss;
4754
4755 brcms_c_recvctl(wlc, rxh, p);
4756 return;
4757
4758 toss:
4759 brcmu_pkt_buf_free_skb(p);
4760}
4761
4762/* calculate frame duration for Mixed-mode L-SIG spoofing, return
4763 * number of bytes goes in the length field
4764 *
4765 * Formula given by HT PHY Spec v 1.13
4766 * len = 3(nsyms + nstream + 3) - 3
4767 */
4768u16
4769brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec,
4770 uint mac_len)
4771{
4772 uint nsyms, len = 0, kNdps;
4773
4774 BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
4775 wlc->pub->unit, RSPEC2RATE(ratespec), mac_len);
4776
4777 if (IS_MCS(ratespec)) {
4778 uint mcs = ratespec & RSPEC_RATE_MASK;
4779 /* MCS_TXS(mcs) returns num tx streams - 1 */
4780 int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec);
4781
4782 /* the payload duration calculation matches that of regular ofdm */
4783 /* 1000Ndbps = kbps * 4 */
4784 kNdps =
4785 MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
4786 RSPEC_ISSGI(ratespec)) * 4;
4787
4788 if (RSPEC_STC(ratespec) == 0)
4789 /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
4790 nsyms =
4791 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
4792 APHY_TAIL_NBITS) * 1000, kNdps);
4793 else
4794 /* STBC needs to have even number of symbols */
4795 nsyms =
4796 2 *
4797 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
4798 APHY_TAIL_NBITS) * 1000, 2 * kNdps);
4799
4800 nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */
4801 /* 3 bytes/symbol @ legacy 6Mbps rate */
4802 len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */
4803 }
4804
4805 return (u16) len;
4806}
4807
4808/* calculate frame duration of a given rate and length, return time in usec unit */
4809uint
4810brcms_c_calc_frame_time(struct brcms_c_info *wlc, ratespec_t ratespec,
4811 u8 preamble_type, uint mac_len)
4812{
4813 uint nsyms, dur = 0, Ndps, kNdps;
4814 uint rate = RSPEC2RATE(ratespec);
4815
4816 if (rate == 0) {
4817 wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
4818 wlc->pub->unit);
4819 rate = BRCM_RATE_1M;
4820 }
4821
4822 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
4823 wlc->pub->unit, ratespec, preamble_type, mac_len);
4824
4825 if (IS_MCS(ratespec)) {
4826 uint mcs = ratespec & RSPEC_RATE_MASK;
4827 int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
4828
4829 dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
4830 if (preamble_type == BRCMS_MM_PREAMBLE)
4831 dur += PREN_MM_EXT;
4832 /* 1000Ndbps = kbps * 4 */
4833 kNdps =
4834 MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
4835 RSPEC_ISSGI(ratespec)) * 4;
4836
4837 if (RSPEC_STC(ratespec) == 0)
4838 /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
4839 nsyms =
4840 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
4841 APHY_TAIL_NBITS) * 1000, kNdps);
4842 else
4843 /* STBC needs to have even number of symbols */
4844 nsyms =
4845 2 *
4846 CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
4847 APHY_TAIL_NBITS) * 1000, 2 * kNdps);
4848
4849 dur += APHY_SYMBOL_TIME * nsyms;
4850 if (BAND_2G(wlc->band->bandtype))
4851 dur += DOT11_OFDM_SIGNAL_EXTENSION;
4852 } else if (IS_OFDM(rate)) {
4853 dur = APHY_PREAMBLE_TIME;
4854 dur += APHY_SIGNAL_TIME;
4855 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
4856 Ndps = rate * 2;
4857 /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
4858 nsyms =
4859 CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
4860 Ndps);
4861 dur += APHY_SYMBOL_TIME * nsyms;
4862 if (BAND_2G(wlc->band->bandtype))
4863 dur += DOT11_OFDM_SIGNAL_EXTENSION;
4864 } else {
4865 /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */
4866 mac_len = mac_len * 8 * 2;
4867 /* calc ceiling of bits/rate = microseconds of air time */
4868 dur = (mac_len + rate - 1) / rate;
4869 if (preamble_type & BRCMS_SHORT_PREAMBLE)
4870 dur += BPHY_PLCP_SHORT_TIME;
4871 else
4872 dur += BPHY_PLCP_TIME;
4873 }
4874 return dur;
4875}
4876
4877/* The opposite of brcms_c_calc_frame_time */
4878static uint
4879brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t ratespec,
4880 u8 preamble_type, uint dur)
4881{
4882 uint nsyms, mac_len, Ndps, kNdps;
4883 uint rate = RSPEC2RATE(ratespec);
4884
4885 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
4886 wlc->pub->unit, ratespec, preamble_type, dur);
4887
4888 if (IS_MCS(ratespec)) {
4889 uint mcs = ratespec & RSPEC_RATE_MASK;
4890 int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
4891 dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
4892 /* payload calculation matches that of regular ofdm */
4893 if (BAND_2G(wlc->band->bandtype))
4894 dur -= DOT11_OFDM_SIGNAL_EXTENSION;
4895 /* kNdbps = kbps * 4 */
4896 kNdps =
4897 MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
4898 RSPEC_ISSGI(ratespec)) * 4;
4899 nsyms = dur / APHY_SYMBOL_TIME;
4900 mac_len =
4901 ((nsyms * kNdps) -
4902 ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
4903 } else if (IS_OFDM(ratespec)) {
4904 dur -= APHY_PREAMBLE_TIME;
4905 dur -= APHY_SIGNAL_TIME;
4906 /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
4907 Ndps = rate * 2;
4908 nsyms = dur / APHY_SYMBOL_TIME;
4909 mac_len =
4910 ((nsyms * Ndps) -
4911 (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
4912 } else {
4913 if (preamble_type & BRCMS_SHORT_PREAMBLE)
4914 dur -= BPHY_PLCP_SHORT_TIME;
4915 else
4916 dur -= BPHY_PLCP_TIME;
4917 mac_len = dur * rate;
4918 /* divide out factor of 2 in rate (1/2 mbps) */
4919 mac_len = mac_len / 8 / 2;
4920 }
4921 return mac_len;
4922}
4923
4924static uint
4925brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rspec,
4926 u8 preamble_type)
4927{
4928 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
4929 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
4930 /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
4931 * or equal to the rate of the immediately previous frame in the FES
4932 */
4933 rspec = BRCMS_BASIC_RATE(wlc, rspec);
4934 /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
4935 return brcms_c_calc_frame_time(wlc, rspec, preamble_type,
4936 (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
4937 FCS_LEN));
4938}
4939
4940static uint
4941brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rspec,
4942 u8 preamble_type)
4943{
4944 uint dur = 0;
4945
4946 BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
4947 wlc->pub->unit, rspec, preamble_type);
4948 /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
4949 * or equal to the rate of the immediately previous frame in the FES
4950 */
4951 rspec = BRCMS_BASIC_RATE(wlc, rspec);
4952 /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
4953 dur =
4954 brcms_c_calc_frame_time(wlc, rspec, preamble_type,
4955 (DOT11_ACK_LEN + FCS_LEN));
4956 return dur;
4957}
4958
4959static uint
4960brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rspec,
4961 u8 preamble_type)
4962{
4963 BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
4964 wlc->pub->unit, rspec, preamble_type);
4965 return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
4966}
4967
4968/* derive wlc->band->basic_rate[] table from 'rateset' */
4969void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, wlc_rateset_t *rateset)
4970{
4971 u8 rate;
4972 u8 mandatory;
4973 u8 cck_basic = 0;
4974 u8 ofdm_basic = 0;
4975 u8 *br = wlc->band->basic_rate;
4976 uint i;
4977
4978 /* incoming rates are in 500kbps units as in 802.11 Supported Rates */
4979 memset(br, 0, BRCM_MAXRATE + 1);
4980
4981 /* For each basic rate in the rates list, make an entry in the
4982 * best basic lookup.
4983 */
4984 for (i = 0; i < rateset->count; i++) {
4985 /* only make an entry for a basic rate */
4986 if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
4987 continue;
4988
4989 /* mask off basic bit */
4990 rate = (rateset->rates[i] & BRCMS_RATE_MASK);
4991
4992 if (rate > BRCM_MAXRATE) {
4993 wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
4994 "invalid rate 0x%X in rate set\n",
4995 rateset->rates[i]);
4996 continue;
4997 }
4998
4999 br[rate] = rate;
5000 }
5001
5002 /* The rate lookup table now has non-zero entries for each
5003 * basic rate, equal to the basic rate: br[basicN] = basicN
5004 *
5005 * To look up the best basic rate corresponding to any
5006 * particular rate, code can use the basic_rate table
5007 * like this
5008 *
5009 * basic_rate = wlc->band->basic_rate[tx_rate]
5010 *
5011 * Make sure there is a best basic rate entry for
5012 * every rate by walking up the table from low rates
5013 * to high, filling in holes in the lookup table
5014 */
5015
5016 for (i = 0; i < wlc->band->hw_rateset.count; i++) {
5017 rate = wlc->band->hw_rateset.rates[i];
5018
5019 if (br[rate] != 0) {
5020 /* This rate is a basic rate.
5021 * Keep track of the best basic rate so far by
5022 * modulation type.
5023 */
5024 if (IS_OFDM(rate))
5025 ofdm_basic = rate;
5026 else
5027 cck_basic = rate;
5028
5029 continue;
5030 }
5031
5032 /* This rate is not a basic rate so figure out the
5033 * best basic rate less than this rate and fill in
5034 * the hole in the table
5035 */
5036
5037 br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic;
5038
5039 if (br[rate] != 0)
5040 continue;
5041
5042 if (IS_OFDM(rate)) {
5043 /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */
5044 if (rate >= BRCM_RATE_24M)
5045 mandatory = BRCM_RATE_24M;
5046 else if (rate >= BRCM_RATE_12M)
5047 mandatory = BRCM_RATE_12M;
5048 else
5049 mandatory = BRCM_RATE_6M;
5050 } else {
5051 /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */
5052 mandatory = rate;
5053 }
5054
5055 br[rate] = mandatory;
5056 }
5057}
5058
5059static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
5060 u8 basic_rate)
5061{
5062 u8 phy_rate, index;
5063 u8 basic_phy_rate, basic_index;
5064 u16 dir_table, basic_table;
5065 u16 basic_ptr;
5066
5067 /* Shared memory address for the table we are reading */
5068 dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
5069
5070 /* Shared memory address for the table we are writing */
5071 basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
5072
5073 /*
5074 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
5075 * the index into the rate table.
5076 */
5077 phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
5078 basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
5079 index = phy_rate & 0xf;
5080 basic_index = basic_phy_rate & 0xf;
5081
5082 /* Find the SHM pointer to the ACK rate entry by looking in the
5083 * Direct-map Table
5084 */
5085 basic_ptr = brcms_c_read_shm(wlc, (dir_table + basic_index * 2));
5086
5087 /* Update the SHM BSS-basic-rate-set mapping table with the pointer
5088 * to the correct basic rate for the given incoming rate
5089 */
5090 brcms_c_write_shm(wlc, (basic_table + index * 2), basic_ptr);
5091}
5092
5093static const wlc_rateset_t *brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
5094{
5095 const wlc_rateset_t *rs_dflt;
5096
5097 if (BRCMS_PHY_11N_CAP(wlc->band)) {
5098 if (BAND_5G(wlc->band->bandtype))
5099 rs_dflt = &ofdm_mimo_rates;
5100 else
5101 rs_dflt = &cck_ofdm_mimo_rates;
5102 } else if (wlc->band->gmode)
5103 rs_dflt = &cck_ofdm_rates;
5104 else
5105 rs_dflt = &cck_rates;
5106
5107 return rs_dflt;
5108}
5109
5110void brcms_c_set_ratetable(struct brcms_c_info *wlc)
5111{
5112 const wlc_rateset_t *rs_dflt;
5113 wlc_rateset_t rs;
5114 u8 rate, basic_rate;
5115 uint i;
5116
5117 rs_dflt = brcms_c_rateset_get_hwrs(wlc);
5118
5119 brcms_c_rateset_copy(rs_dflt, &rs);
5120 brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
5121
5122 /* walk the phy rate table and update SHM basic rate lookup table */
5123 for (i = 0; i < rs.count; i++) {
5124 rate = rs.rates[i] & BRCMS_RATE_MASK;
5125
5126 /* for a given rate BRCMS_BASIC_RATE returns the rate at
5127 * which a response ACK/CTS should be sent.
5128 */
5129 basic_rate = BRCMS_BASIC_RATE(wlc, rate);
5130 if (basic_rate == 0) {
5131 /* This should only happen if we are using a
5132 * restricted rateset.
5133 */
5134 basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
5135 }
5136
5137 brcms_c_write_rate_shm(wlc, rate, basic_rate);
5138 }
5139}
5140
5141/*
5142 * Return true if the specified rate is supported by the specified band.
5143 * BRCM_BAND_AUTO indicates the current band.
5144 */
5145bool brcms_c_valid_rate(struct brcms_c_info *wlc, ratespec_t rspec, int band,
5146 bool verbose)
5147{
5148 wlc_rateset_t *hw_rateset;
5149 uint i;
5150
5151 if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype)) {
5152 hw_rateset = &wlc->band->hw_rateset;
5153 } else if (NBANDS(wlc) > 1) {
5154 hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
5155 } else {
5156 /* other band specified and we are a single band device */
5157 return false;
5158 }
5159
5160 /* check if this is a mimo rate */
5161 if (IS_MCS(rspec)) {
5162 if (!VALID_MCS((rspec & RSPEC_RATE_MASK)))
5163 goto error;
5164
5165 return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
5166 }
5167
5168 for (i = 0; i < hw_rateset->count; i++)
5169 if (hw_rateset->rates[i] == RSPEC2RATE(rspec))
5170 return true;
5171 error:
5172 if (verbose) {
5173 wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
5174 "not in hw_rateset\n", wlc->pub->unit, rspec);
5175 }
5176
5177 return false;
5178}
5179
5180static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
5181{
5182 uint i;
5183 struct brcms_band *band;
5184
5185 for (i = 0; i < NBANDS(wlc); i++) {
5186 if (IS_SINGLEBAND_5G(wlc->deviceid))
5187 i = BAND_5G_INDEX;
5188 band = wlc->bandstate[i];
5189 if (band->bandtype == BRCM_BAND_5G) {
5190 if ((bwcap == BRCMS_N_BW_40ALL)
5191 || (bwcap == BRCMS_N_BW_20IN2G_40IN5G))
5192 band->mimo_cap_40 = true;
5193 else
5194 band->mimo_cap_40 = false;
5195 } else {
5196 if (bwcap == BRCMS_N_BW_40ALL)
5197 band->mimo_cap_40 = true;
5198 else
5199 band->mimo_cap_40 = false;
5200 }
5201 }
5202}
5203
5204void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
5205{
5206 const wlc_rateset_t *rs_dflt;
5207 wlc_rateset_t rs;
5208 u8 rate;
5209 u16 entry_ptr;
5210 u8 plcp[D11_PHY_HDR_LEN];
5211 u16 dur, sifs;
5212 uint i;
5213
5214 sifs = SIFS(wlc->band);
5215
5216 rs_dflt = brcms_c_rateset_get_hwrs(wlc);
5217
5218 brcms_c_rateset_copy(rs_dflt, &rs);
5219 brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
5220
5221 /* walk the phy rate table and update MAC core SHM basic rate table entries */
5222 for (i = 0; i < rs.count; i++) {
5223 rate = rs.rates[i] & BRCMS_RATE_MASK;
5224
5225 entry_ptr = brcms_c_rate_shm_offset(wlc, rate);
5226
5227 /* Calculate the Probe Response PLCP for the given rate */
5228 brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
5229
5230 /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */
5231 dur = (u16) brcms_c_calc_frame_time(wlc, rate,
5232 BRCMS_LONG_PREAMBLE, frame_len);
5233 dur += sifs;
5234
5235 /* Update the SHM Rate Table entry Probe Response values */
5236 brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS,
5237 (u16) (plcp[0] + (plcp[1] << 8)));
5238 brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2,
5239 (u16) (plcp[2] + (plcp[3] << 8)));
5240 brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur);
5241 }
5242}
5243
5244/* Max buffering needed for beacon template/prb resp template is 142 bytes.
5245 *
5246 * PLCP header is 6 bytes.
5247 * 802.11 A3 header is 24 bytes.
5248 * Max beacon frame body template length is 112 bytes.
5249 * Max probe resp frame body template length is 110 bytes.
5250 *
5251 * *len on input contains the max length of the packet available.
5252 *
5253 * The *len value is set to the number of bytes in buf used, and starts with the PLCP
5254 * and included up to, but not including, the 4 byte FCS.
5255 */
5256static void
5257brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
5258 ratespec_t bcn_rspec,
5259 struct brcms_bss_cfg *cfg, u16 *buf, int *len)
5260{
5261 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
5262 struct cck_phy_hdr *plcp;
5263 struct ieee80211_mgmt *h;
5264 int hdr_len, body_len;
5265
5266 if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
5267 hdr_len = DOT11_MAC_HDR_LEN;
5268 else
5269 hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
5270 body_len = *len - hdr_len; /* calc buffer size provided for frame body */
5271
5272 *len = hdr_len + body_len; /* return actual size */
5273
5274 /* format PHY and MAC headers */
5275 memset((char *)buf, 0, hdr_len);
5276
5277 plcp = (struct cck_phy_hdr *) buf;
5278
5279 /* PLCP for Probe Response frames are filled in from core's rate table */
5280 if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) {
5281 /* fill in PLCP */
5282 brcms_c_compute_plcp(wlc, bcn_rspec,
5283 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
5284 (u8 *) plcp);
5285
5286 }
5287 /* "Regular" and 16 MBSS but not for 4 MBSS */
5288 /* Update the phytxctl for the beacon based on the rspec */
5289 if (!SOFTBCN_ENAB(cfg))
5290 brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
5291
5292 if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
5293 h = (struct ieee80211_mgmt *)&plcp[0];
5294 else
5295 h = (struct ieee80211_mgmt *)&plcp[1];
5296
5297 /* fill in 802.11 header */
5298 h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
5299
5300 /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
5301 /* A1 filled in by MAC for prb resp, broadcast for bcn */
5302 if (type == IEEE80211_STYPE_BEACON)
5303 memcpy(&h->da, &ether_bcast, ETH_ALEN);
5304 memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
5305 memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
5306
5307 /* SEQ filled in by MAC */
5308
5309 return;
5310}
5311
5312int brcms_c_get_header_len()
5313{
5314 return TXOFF;
5315}
5316
5317/* Update a beacon for a particular BSS
5318 * For MBSS, this updates the software template and sets "latest" to the index of the
5319 * template updated.
5320 * Otherwise, it updates the hardware template.
5321 */
5322void brcms_c_bss_update_beacon(struct brcms_c_info *wlc,
5323 struct brcms_bss_cfg *cfg)
5324{
5325 int len = BCN_TMPL_LEN;
5326
5327 /* Clear the soft intmask */
5328 wlc->defmacintmask &= ~MI_BCNTPL;
5329
5330 if (!cfg->up) { /* Only allow updates on an UP bss */
5331 return;
5332 }
5333
5334 /* Optimize: Some of if/else could be combined */
5335 if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) {
5336 /* Hardware beaconing for this config */
5337 u16 bcn[BCN_TMPL_LEN / 2];
5338 u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
5339 d11regs_t *regs = wlc->regs;
5340
5341 /* Check if both templates are in use, if so sched. an interrupt
5342 * that will call back into this routine
5343 */
5344 if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
5345 /* clear any previous status */
5346 W_REG(&regs->macintstatus, MI_BCNTPL);
5347 }
5348 /* Check that after scheduling the interrupt both of the
5349 * templates are still busy. if not clear the int. & remask
5350 */
5351 if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
5352 wlc->defmacintmask |= MI_BCNTPL;
5353 return;
5354 }
5355
5356 wlc->bcn_rspec =
5357 brcms_c_lowest_basic_rspec(wlc, &cfg->current_bss->rateset);
5358 /* update the template and ucode shm */
5359 brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON,
5360 wlc->bcn_rspec, cfg, bcn, &len);
5361 brcms_c_write_hw_bcntemplates(wlc, bcn, len, false);
5362 }
5363}
5364
5365/*
5366 * Update all beacons for the system.
5367 */
5368void brcms_c_update_beacon(struct brcms_c_info *wlc)
5369{
5370 int idx;
5371 struct brcms_bss_cfg *bsscfg;
5372
5373 /* update AP or IBSS beacons */
5374 FOREACH_BSS(wlc, idx, bsscfg) {
5375 if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
5376 brcms_c_bss_update_beacon(wlc, bsscfg);
5377 }
5378}
5379
5380/* Write ssid into shared memory */
5381void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
5382{
5383 u8 *ssidptr = cfg->SSID;
5384 u16 base = M_SSID;
5385 u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
5386
5387 /* padding the ssid with zero and copy it into shm */
5388 memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
5389 memcpy(ssidbuf, ssidptr, cfg->SSID_len);
5390
5391 brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
5392
5393 if (!MBSS_BCN_ENAB(cfg))
5394 brcms_c_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len);
5395}
5396
5397void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
5398{
5399 int idx;
5400 struct brcms_bss_cfg *bsscfg;
5401
5402 /* update AP or IBSS probe responses */
5403 FOREACH_BSS(wlc, idx, bsscfg) {
5404 if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
5405 brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
5406 }
5407}
5408
5409void
5410brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
5411 struct brcms_bss_cfg *cfg,
5412 bool suspend)
5413{
5414 u16 prb_resp[BCN_TMPL_LEN / 2];
5415 int len = BCN_TMPL_LEN;
5416
5417 /* write the probe response to hardware, or save in the config structure */
5418 if (!MBSS_PRB_ENAB(cfg)) {
5419
5420 /* create the probe response template */
5421 brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
5422 cfg, prb_resp, &len);
5423
5424 if (suspend)
5425 brcms_c_suspend_mac_and_wait(wlc);
5426
5427 /* write the probe response into the template region */
5428 brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
5429 (len + 3) & ~3, prb_resp);
5430
5431 /* write the length of the probe response frame (+PLCP/-FCS) */
5432 brcms_c_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len);
5433
5434 /* write the SSID and SSID length */
5435 brcms_c_shm_ssid_upd(wlc, cfg);
5436
5437 /*
5438 * Write PLCP headers and durations for probe response frames at all rates.
5439 * Use the actual frame length covered by the PLCP header for the call to
5440 * brcms_c_mod_prb_rsp_rate_table() by subtracting the PLCP len
5441 * and adding the FCS.
5442 */
5443 len += (-D11_PHY_HDR_LEN + FCS_LEN);
5444 brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
5445
5446 if (suspend)
5447 brcms_c_enable_mac(wlc);
5448 } else { /* Generating probe resp in sw; update local template */
5449 /* error: No software probe response support without MBSS */
5450 }
5451}
5452
5453/* prepares pdu for transmission. returns BCM error codes */
5454int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
5455{
5456 uint fifo;
5457 struct d11txh *txh;
5458 struct ieee80211_hdr *h;
5459 struct scb *scb;
5460
5461 txh = (struct d11txh *) (pdu->data);
5462 h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
5463
5464 /* get the pkt queue info. This was put at brcms_c_sendctl or
5465 * brcms_c_send for PDU */
5466 fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
5467
5468 scb = NULL;
5469
5470 *fifop = fifo;
5471
5472 /* return if insufficient dma resources */
5473 if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) {
5474 /* Mark precedences related to this FIFO, unsendable */
5475 BRCMS_TX_FIFO_CLEAR(wlc, fifo);
5476 return -EBUSY;
5477 }
5478 return 0;
5479}
5480
5481/* init tx reported rate mechanism */
5482void brcms_c_reprate_init(struct brcms_c_info *wlc)
5483{
5484 int i;
5485 struct brcms_bss_cfg *bsscfg;
5486
5487 FOREACH_BSS(wlc, i, bsscfg) {
5488 brcms_c_bsscfg_reprate_init(bsscfg);
5489 }
5490}
5491
5492/* per bsscfg init tx reported rate mechanism */
5493void brcms_c_bsscfg_reprate_init(struct brcms_bss_cfg *bsscfg)
5494{
5495 bsscfg->txrspecidx = 0;
5496 memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec));
5497}
5498
5499void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs)
5500{
5501 brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
5502 wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
5503 (bool) N_ENAB(wlc->pub),
5504 CHSPEC_WLC_BW(wlc->default_bss->chanspec),
5505 wlc->stf->txstreams);
5506}
5507
5508static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
5509{
5510 chanspec_t chanspec;
5511 struct brcms_band *band;
5512 struct brcms_bss_info *bi = wlc->default_bss;
5513
5514 /* init default and target BSS with some sane initial values */
5515 memset((char *)(bi), 0, sizeof(struct brcms_bss_info));
5516 bi->beacon_period = BEACON_INTERVAL_DEFAULT;
5517 bi->dtim_period = DTIM_INTERVAL_DEFAULT;
5518
5519 /* fill the default channel as the first valid channel
5520 * starting from the 2G channels
5521 */
5522 chanspec = CH20MHZ_CHSPEC(1);
5523 wlc->home_chanspec = bi->chanspec = chanspec;
5524
5525 /* find the band of our default channel */
5526 band = wlc->band;
5527 if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_BANDUNIT(chanspec))
5528 band = wlc->bandstate[OTHERBANDUNIT(wlc)];
5529
5530 /* init bss rates to the band specific default rate set */
5531 brcms_c_rateset_default(&bi->rateset, NULL, band->phytype,
5532 band->bandtype, false, BRCMS_RATE_MASK_FULL,
5533 (bool) N_ENAB(wlc->pub), CHSPEC_WLC_BW(chanspec),
5534 wlc->stf->txstreams);
5535
5536 if (N_ENAB(wlc->pub))
5537 bi->flags |= BRCMS_BSS_HT;
5538}
5539
5540static ratespec_t
5541mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
5542 u32 int_val)
5543{
5544 u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
5545 u8 rate = int_val & NRATE_RATE_MASK;
5546 ratespec_t rspec;
5547 bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
5548 bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
5549 bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
5550 == NRATE_OVERRIDE_MCS_ONLY);
5551 int bcmerror = 0;
5552
5553 if (!ismcs) {
5554 return (ratespec_t) rate;
5555 }
5556
5557 /* validate the combination of rate/mcs/stf is allowed */
5558 if (N_ENAB(wlc->pub) && ismcs) {
5559 /* mcs only allowed when nmode */
5560 if (stf > PHY_TXC1_MODE_SDM) {
5561 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
5562 BRCMS_UNIT(wlc), __func__);
5563 bcmerror = -EINVAL;
5564 goto done;
5565 }
5566
5567 /* mcs 32 is a special case, DUP mode 40 only */
5568 if (rate == 32) {
5569 if (!CHSPEC_IS40(wlc->home_chanspec) ||
5570 ((stf != PHY_TXC1_MODE_SISO)
5571 && (stf != PHY_TXC1_MODE_CDD))) {
5572 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
5573 "32\n", BRCMS_UNIT(wlc), __func__);
5574 bcmerror = -EINVAL;
5575 goto done;
5576 }
5577 /* mcs > 7 must use stf SDM */
5578 } else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
5579 /* mcs > 7 must use stf SDM */
5580 if (stf != PHY_TXC1_MODE_SDM) {
5581 BCMMSG(wlc->wiphy, "wl%d: enabling "
5582 "SDM mode for mcs %d\n",
5583 BRCMS_UNIT(wlc), rate);
5584 stf = PHY_TXC1_MODE_SDM;
5585 }
5586 } else {
5587 /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */
5588 if ((stf > PHY_TXC1_MODE_STBC) ||
5589 (!BRCMS_STBC_CAP_PHY(wlc)
5590 && (stf == PHY_TXC1_MODE_STBC))) {
5591 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
5592 "\n", BRCMS_UNIT(wlc), __func__);
5593 bcmerror = -EINVAL;
5594 goto done;
5595 }
5596 }
5597 } else if (IS_OFDM(rate)) {
5598 if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
5599 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
5600 BRCMS_UNIT(wlc), __func__);
5601 bcmerror = -EINVAL;
5602 goto done;
5603 }
5604 } else if (IS_CCK(rate)) {
5605 if ((cur_band->bandtype != BRCM_BAND_2G)
5606 || (stf != PHY_TXC1_MODE_SISO)) {
5607 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
5608 BRCMS_UNIT(wlc), __func__);
5609 bcmerror = -EINVAL;
5610 goto done;
5611 }
5612 } else {
5613 wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
5614 BRCMS_UNIT(wlc), __func__);
5615 bcmerror = -EINVAL;
5616 goto done;
5617 }
5618 /* make sure multiple antennae are available for non-siso rates */
5619 if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
5620 wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
5621 "request\n", BRCMS_UNIT(wlc), __func__);
5622 bcmerror = -EINVAL;
5623 goto done;
5624 }
5625
5626 rspec = rate;
5627 if (ismcs) {
5628 rspec |= RSPEC_MIMORATE;
5629 /* For STBC populate the STC field of the ratespec */
5630 if (stf == PHY_TXC1_MODE_STBC) {
5631 u8 stc;
5632 stc = 1; /* Nss for single stream is always 1 */
5633 rspec |= (stc << RSPEC_STC_SHIFT);
5634 }
5635 }
5636
5637 rspec |= (stf << RSPEC_STF_SHIFT);
5638
5639 if (override_mcs_only)
5640 rspec |= RSPEC_OVERRIDE_MCS_ONLY;
5641
5642 if (issgi)
5643 rspec |= RSPEC_SHORT_GI;
5644
5645 if ((rate != 0)
5646 && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true)) {
5647 return rate;
5648 }
5649
5650 return rspec;
5651done:
5652 return rate;
5653}
5654
5655/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
5656static int
5657brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
5658 bool writeToShm)
5659{
5660 int idle_busy_ratio_x_16 = 0;
5661 uint offset =
5662 isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
5663 M_TX_IDLE_BUSY_RATIO_X_16_CCK;
5664 if (duty_cycle > 100 || duty_cycle < 0) {
5665 wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n",
5666 wlc->pub->unit);
5667 return -EINVAL;
5668 }
5669 if (duty_cycle)
5670 idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
5671 /* Only write to shared memory when wl is up */
5672 if (writeToShm)
5673 brcms_c_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16);
5674
5675 if (isOFDM)
5676 wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
5677 else
5678 wlc->tx_duty_cycle_cck = (u16) duty_cycle;
5679
5680 return 0;
5681}
5682
5683/* Read a single u16 from shared memory.
5684 * SHM 'offset' needs to be an even address
5685 */
5686u16 brcms_c_read_shm(struct brcms_c_info *wlc, uint offset)
5687{
5688 return brcms_b_read_shm(wlc->hw, offset);
5689}
5690
5691/* Write a single u16 to shared memory.
5692 * SHM 'offset' needs to be an even address
5693 */
5694void brcms_c_write_shm(struct brcms_c_info *wlc, uint offset, u16 v)
5695{
5696 brcms_b_write_shm(wlc->hw, offset, v);
5697}
5698
5699/* Copy a buffer to shared memory.
5700 * SHM 'offset' needs to be an even address and
5701 * Buffer length 'len' must be an even number of bytes
5702 */
5703void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset, const void *buf,
5704 int len)
5705{
5706 /* offset and len need to be even */
5707 if (len <= 0 || (offset & 1) || (len & 1))
5708 return;
5709
5710 brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
5711
5712}
5713
5714/* wrapper BMAC functions to for HIGH driver access */
5715void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val)
5716{
5717 brcms_b_mctrl(wlc->hw, mask, val);
5718}
5719
5720void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val, int bands)
5721{
5722 brcms_b_mhf(wlc->hw, idx, mask, val, bands);
5723}
5724
5725int brcms_c_xmtfifo_sz_get(struct brcms_c_info *wlc, uint fifo, uint *blocks)
5726{
5727 return brcms_b_xmtfifo_sz_get(wlc->hw, fifo, blocks);
5728}
5729
5730void brcms_c_write_template_ram(struct brcms_c_info *wlc, int offset, int len,
5731 void *buf)
5732{
5733 brcms_b_write_template_ram(wlc->hw, offset, len, buf);
5734}
5735
5736void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, void *bcn, int len,
5737 bool both)
5738{
5739 brcms_b_write_hw_bcntemplates(wlc->hw, bcn, len, both);
5740}
5741
5742void
5743brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
5744 const u8 *addr)
5745{
5746 brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
5747 if (match_reg_offset == RCM_BSSID_OFFSET)
5748 memcpy(wlc->cfg->BSSID, addr, ETH_ALEN);
5749}
5750
5751void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, mbool req_bit)
5752{
5753 brcms_b_pllreq(wlc->hw, set, req_bit);
5754}
5755
5756void brcms_c_reset_bmac_done(struct brcms_c_info *wlc)
5757{
5758}
5759
5760/* check for the particular priority flow control bit being set */
5761bool
5762brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc,
5763 struct brcms_txq_info *q,
5764 int prio)
5765{
5766 uint prio_mask;
5767
5768 if (prio == ALLPRIO) {
5769 prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
5770 } else {
5771 prio_mask = NBITVAL(prio);
5772 }
5773
5774 return (q->stopped & prio_mask) == prio_mask;
5775}
5776
5777/* propagate the flow control to all interfaces using the given tx queue */
5778void brcms_c_txflowcontrol(struct brcms_c_info *wlc,
5779 struct brcms_txq_info *qi,
5780 bool on, int prio)
5781{
5782 uint prio_bits;
5783 uint cur_bits;
5784
5785 BCMMSG(wlc->wiphy, "flow control kicks in\n");
5786
5787 if (prio == ALLPRIO) {
5788 prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
5789 } else {
5790 prio_bits = NBITVAL(prio);
5791 }
5792
5793 cur_bits = qi->stopped & prio_bits;
5794
5795 /* Check for the case of no change and return early
5796 * Otherwise update the bit and continue
5797 */
5798 if (on) {
5799 if (cur_bits == prio_bits) {
5800 return;
5801 }
5802 mboolset(qi->stopped, prio_bits);
5803 } else {
5804 if (cur_bits == 0) {
5805 return;
5806 }
5807 mboolclr(qi->stopped, prio_bits);
5808 }
5809
5810 /* If there is a flow control override we will not change the external
5811 * flow control state.
5812 */
5813 if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) {
5814 return;
5815 }
5816
5817 brcms_c_txflowcontrol_signal(wlc, qi, on, prio);
5818}
5819
5820void
5821brcms_c_txflowcontrol_override(struct brcms_c_info *wlc,
5822 struct brcms_txq_info *qi,
5823 bool on, uint override)
5824{
5825 uint prev_override;
5826
5827 prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);
5828
5829 /* Update the flow control bits and do an early return if there is
5830 * no change in the external flow control state.
5831 */
5832 if (on) {
5833 mboolset(qi->stopped, override);
5834 /* if there was a previous override bit on, then setting this
5835 * makes no difference.
5836 */
5837 if (prev_override) {
5838 return;
5839 }
5840
5841 brcms_c_txflowcontrol_signal(wlc, qi, ON, ALLPRIO);
5842 } else {
5843 mboolclr(qi->stopped, override);
5844 /* clearing an override bit will only make a difference for
5845 * flow control if it was the only bit set. For any other
5846 * override setting, just return
5847 */
5848 if (prev_override != override) {
5849 return;
5850 }
5851
5852 if (qi->stopped == 0) {
5853 brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
5854 } else {
5855 int prio;
5856
5857 for (prio = MAXPRIO; prio >= 0; prio--) {
5858 if (!mboolisset(qi->stopped, NBITVAL(prio)))
5859 brcms_c_txflowcontrol_signal(
5860 wlc, qi, OFF, prio);
5861 }
5862 }
5863 }
5864}
5865
5866static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
5867{
5868 struct brcms_txq_info *qi;
5869
5870 for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
5871 if (qi->stopped) {
5872 brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
5873 qi->stopped = 0;
5874 }
5875 }
5876}
5877
5878static void
5879brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
5880 struct brcms_txq_info *qi, bool on, int prio)
5881{
5882#ifdef NON_FUNCTIONAL
5883 /* wlcif_list is never filled so this function is not functional */
5884 struct brcms_c_if *wlcif;
5885
5886 for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) {
5887 if (wlcif->qi == qi && wlcif->flags & BRCMS_IF_LINKED)
5888 brcms_txflowcontrol(wlc->wl, wlcif->wlif, on, prio);
5889 }
5890#endif
5891}
5892
5893static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
5894{
5895 struct brcms_txq_info *qi, *p;
5896
5897 qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
5898 if (qi != NULL) {
5899 /*
5900 * Have enough room for control packets along with HI watermark
5901 * Also, add room to txq for total psq packets if all the SCBs
5902 * leave PS mode. The watermark for flowcontrol to OS packets
5903 * will remain the same
5904 */
5905 brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
5906 (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT
5907 + wlc->pub->psq_pkts_total);
5908
5909 /* add this queue to the the global list */
5910 p = wlc->tx_queues;
5911 if (p == NULL) {
5912 wlc->tx_queues = qi;
5913 } else {
5914 while (p->next != NULL)
5915 p = p->next;
5916 p->next = qi;
5917 }
5918 }
5919 return qi;
5920}
5921
5922static void brcms_c_txq_free(struct brcms_c_info *wlc,
5923 struct brcms_txq_info *qi)
5924{
5925 struct brcms_txq_info *p;
5926
5927 if (qi == NULL)
5928 return;
5929
5930 /* remove the queue from the linked list */
5931 p = wlc->tx_queues;
5932 if (p == qi)
5933 wlc->tx_queues = p->next;
5934 else {
5935 while (p != NULL && p->next != qi)
5936 p = p->next;
5937 if (p != NULL)
5938 p->next = p->next->next;
5939 }
5940
5941 kfree(qi);
5942}
5943
5944/*
5945 * Flag 'scan in progress' to withhold dynamic phy calibration
5946 */
5947void brcms_c_scan_start(struct brcms_c_info *wlc)
5948{
5949 wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
5950}
5951
5952void brcms_c_scan_stop(struct brcms_c_info *wlc)
5953{
5954 wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
5955}
5956
5957void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
5958{
5959 wlc->pub->associated = state;
5960 wlc->cfg->associated = state;
5961}
5962
5963/*
5964 * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
5965 * AMPDU traffic, packets pending in hardware have to be invalidated so that
5966 * when later on hardware releases them, they can be handled appropriately.
5967 */
5968void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
5969 struct ieee80211_sta *sta,
5970 void (*dma_callback_fn))
5971{
5972 struct dma_pub *dmah;
5973 int i;
5974 for (i = 0; i < NFIFO; i++) {
5975 dmah = hw->di[i];
5976 if (dmah != NULL)
5977 dma_walk_packets(dmah, dma_callback_fn, sta);
5978 }
5979}
5980
5981int brcms_c_get_curband(struct brcms_c_info *wlc)
5982{
5983 return wlc->band->bandunit;
5984}
5985
5986void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
5987{
5988 /* flush packet queue when requested */
5989 if (drop)
5990 brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
5991
5992 /* wait for queue and DMA fifos to run dry */
5993 while (!pktq_empty(&wlc->pkt_queue->q) ||
5994 TXPKTPENDTOT(wlc) > 0) {
5995 brcms_msleep(wlc->wl, 1);
5996 }
5997}
5998
5999int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
6000 int int_val)
6001{
6002 int err = 0;
6003
6004 switch (par_id) {
6005 case IOV_BCN_LI_BCN:
6006 wlc->bcn_li_bcn = (u8) int_val;
6007 if (wlc->pub->up)
6008 brcms_c_bcn_li_upd(wlc);
6009 break;
6010 /* As long as override is false, this only sets the *user*
6011 targets. User can twiddle this all he wants with no harm.
6012 wlc_phy_txpower_set() explicitly sets override to false if
6013 not internal or test.
6014 */
6015 case IOV_QTXPOWER:{
6016 u8 qdbm;
6017 bool override;
6018
6019 /* Remove override bit and clip to max qdbm value */
6020 qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff);
6021 /* Extract override setting */
6022 override = (int_val & WL_TXPWR_OVERRIDE) ? true : false;
6023 err =
6024 wlc_phy_txpower_set(wlc->band->pi, qdbm, override);
6025 break;
6026 }
6027 case IOV_MPC:
6028 wlc->mpc = (bool)int_val;
6029 brcms_c_radio_mpc_upd(wlc);
6030 break;
6031 default:
6032 err = -ENOTSUPP;
6033 }
6034 return err;
6035}
6036
6037int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
6038 int *ret_int_ptr)
6039{
6040 int err = 0;
6041
6042 switch (par_id) {
6043 case IOV_BCN_LI_BCN:
6044 *ret_int_ptr = wlc->bcn_li_bcn;
6045 break;
6046 case IOV_QTXPOWER: {
6047 uint qdbm;
6048 bool override;
6049
6050 err = wlc_phy_txpower_get(wlc->band->pi, &qdbm,
6051 &override);
6052 if (err != 0)
6053 return err;
6054
6055 /* Return qdbm units */
6056 *ret_int_ptr =
6057 qdbm | (override ? WL_TXPWR_OVERRIDE : 0);
6058 break;
6059 }
6060 case IOV_MPC:
6061 *ret_int_ptr = (s32) wlc->mpc;
6062 break;
6063 default:
6064 err = -ENOTSUPP;
6065 }
6066 return err;
6067}
6068
6069/*
6070 * Search the name=value vars for a specific one and return its value.
6071 * Returns NULL if not found.
6072 */
6073char *getvar(char *vars, const char *name)
6074{
6075 char *s;
6076 int len;
6077
6078 if (!name)
6079 return NULL;
6080
6081 len = strlen(name);
6082 if (len == 0)
6083 return NULL;
6084
6085 /* first look in vars[] */
6086 for (s = vars; s && *s;) {
6087 if ((memcmp(s, name, len) == 0) && (s[len] == '='))
6088 return &s[len + 1];
6089
6090 while (*s++)
6091 ;
6092 }
6093 /* nothing found */
6094 return NULL;
6095}
6096
6097/*
6098 * Search the vars for a specific one and return its value as
6099 * an integer. Returns 0 if not found.
6100 */
6101int getintvar(char *vars, const char *name)
6102{
6103 char *val;
6104
6105 val = getvar(vars, name);
6106 if (val == NULL)
6107 return 0;
6108
6109 return simple_strtoul(val, NULL, 0);
6110}
diff --git a/drivers/staging/brcm80211/brcmsmac/main.h b/drivers/staging/brcm80211/brcmsmac/main.h
new file mode 100644
index 00000000000..f204b1f4747
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/main.h
@@ -0,0 +1,1025 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_MAIN_H_
18#define _BRCM_MAIN_H_
19
20#include <linux/etherdevice.h>
21
22#include <brcmu_utils.h>
23#include "types.h"
24#include "d11.h"
25
26#define MA_WINDOW_SZ 8 /* moving average window size */
27#define BRCMS_HWRXOFF 38 /* chip rx buffer offset */
28#define INVCHANNEL 255 /* invalid channel */
29/* max # supported core revisions (0 .. MAXCOREREV - 1) */
30#define MAXCOREREV 28
31/* max # brcms_c_module_register() calls */
32#define BRCMS_MAXMODULES 22
33
34#define SEQNUM_SHIFT 4
35#define AMPDU_DELIMITER_LEN 4
36#define SEQNUM_MAX 0x1000
37
38#define APHY_CWMIN 15
39#define PHY_CWMAX 1023
40
41#define EDCF_AIFSN_MIN 1
42#define FRAGNUM_MASK 0xF
43
44#define NTXRATE 64 /* # tx MPDUs rate is reported for */
45
46#define BRCMS_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8))
47
48/* Maximum wait time for a MAC suspend */
49/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
50#define BRCMS_MAX_MAC_SUSPEND 83000
51
52/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable
53 */
54#define BRCMS_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */
55
56/* transmit buffer max headroom for protocol headers */
57#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
58
59#define AC_COUNT 4
60
61/* Macros for doing definition and get/set of bitfields
62 * Usage example, e.g. a three-bit field (bits 4-6):
63 * #define <NAME>_M BITFIELD_MASK(3)
64 * #define <NAME>_S 4
65 * ...
66 * regval = R_REG(osh, &regs->regfoo);
67 * field = GFIELD(regval, <NAME>);
68 * regval = SFIELD(regval, <NAME>, 1);
69 * W_REG(osh, &regs->regfoo, regval);
70 */
71#define BITFIELD_MASK(width) \
72 (((unsigned)1 << (width)) - 1)
73#define GFIELD(val, field) \
74 (((val) >> field ## _S) & field ## _M)
75#define SFIELD(val, field, bits) \
76 (((val) & (~(field ## _M << field ## _S))) | \
77 ((unsigned)(bits) << field ## _S))
78
79#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */
80
81/* Double check that unsupported cores are not enabled */
82#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
83#error "Configuration for D11CONF includes unsupported versions."
84#endif /* Bad versions */
85
86#define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev)
87
88/* values for shortslot_override */
89#define BRCMS_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */
90#define BRCMS_SHORTSLOT_OFF 0 /* Turn off short slot */
91#define BRCMS_SHORTSLOT_ON 1 /* Turn on short slot */
92
93/* value for short/long and mixmode/greenfield preamble */
94#define BRCMS_LONG_PREAMBLE (0)
95#define BRCMS_SHORT_PREAMBLE (1 << 0)
96#define BRCMS_GF_PREAMBLE (1 << 1)
97#define BRCMS_MM_PREAMBLE (1 << 2)
98#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \
99 ((_pre) == BRCMS_MM_PREAMBLE))
100
101/* values for barker_preamble */
102#define BRCMS_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */
103
104/* A fifo is full. Clear precedences related to that FIFO */
105#define BRCMS_TX_FIFO_CLEAR(wlc, fifo) \
106 ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo])
107
108/* Fifo is NOT full. Enable precedences for that FIFO */
109#define BRCMS_TX_FIFO_ENAB(wlc, fifo) \
110 ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo])
111
112/* TxFrameID */
113/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
114/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
115#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */
116#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */
117#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */
118#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */
119#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */
120#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */
121
122/* promote boardrev */
123#define BOARDREV_PROMOTABLE 0xFF /* from */
124#define BOARDREV_PROMOTED 1 /* to */
125
126/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true
127 */
128#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
129#define BRCMS_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \
130 ((bsscfg)->wsec & WSEC_SWFLAG)))
131
132#define BRCMS_PORTOPEN(cfg) \
133 (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \
134 (cfg)->wsec_portopen : true)
135
136#define PS_ALLOWED(wlc) brcms_c_ps_allowed(wlc)
137
138#define DATA_BLOCK_TX_SUPR (1 << 4)
139
140/* 802.1D Priority to TX FIFO number for wme */
141extern const u8 prio2fifo[];
142
143/* Ucode MCTL_WAKE override bits */
144#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01
145#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02
146#define BRCMS_WAKE_OVERRIDE_MACSUSPEND 0x04
147#define BRCMS_WAKE_OVERRIDE_TXFIFO 0x08
148#define BRCMS_WAKE_OVERRIDE_FORCEFAST 0x10
149
150/* stuff pulled in from wlc.c */
151
152/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other
153 * times; and if we run out, constant I_RU interrupts may cause lockup. We
154 * will still get error counts from rx0ovfl.
155 */
156#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU)
157/* default software intmasks */
158#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */
159#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
160 MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
161 MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
162
163#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */
164#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */
165#define RETRY_LONG_DEF 4 /* Default Long retry count */
166#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */
167#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */
168
169#define MAXTXPKTS 6 /* max # pkts pending */
170
171/* frameburst */
172#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */
173#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */
174
175/* Per-AC retry limit register definitions; uses defs.h bitfield macros */
176#define EDCF_SHORT_S 0
177#define EDCF_SFB_S 4
178#define EDCF_LONG_S 8
179#define EDCF_LFB_S 12
180#define EDCF_SHORT_M BITFIELD_MASK(4)
181#define EDCF_SFB_M BITFIELD_MASK(4)
182#define EDCF_LONG_M BITFIELD_MASK(4)
183#define EDCF_LFB_M BITFIELD_MASK(4)
184
185#define NFIFO 6 /* # tx/rx fifopairs */
186
187#define BRCMS_WME_RETRY_SHORT_GET(wlc, ac) \
188 GFIELD(wlc->wme_retries[ac], EDCF_SHORT)
189#define BRCMS_WME_RETRY_SFB_GET(wlc, ac) \
190 GFIELD(wlc->wme_retries[ac], EDCF_SFB)
191#define BRCMS_WME_RETRY_LONG_GET(wlc, ac) \
192 GFIELD(wlc->wme_retries[ac], EDCF_LONG)
193#define BRCMS_WME_RETRY_LFB_GET(wlc, ac) \
194 GFIELD(wlc->wme_retries[ac], EDCF_LFB)
195
196#define BRCMS_WME_RETRY_SHORT_SET(wlc, ac, val) \
197 (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val))
198#define BRCMS_WME_RETRY_SFB_SET(wlc, ac, val) \
199 (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val))
200#define BRCMS_WME_RETRY_LONG_SET(wlc, ac, val) \
201 (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val))
202#define BRCMS_WME_RETRY_LFB_SET(wlc, ac, val) \
203 (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val))
204
205/* PLL requests */
206
207/* pll is shared on old chips */
208#define BRCMS_PLLREQ_SHARED 0x1
209/* hold pll for radio monitor register checking */
210#define BRCMS_PLLREQ_RADIO_MON 0x2
211/* hold/release pll for some short operation */
212#define BRCMS_PLLREQ_FLIP 0x4
213
214/*
215 * Macros to check if AP or STA is active.
216 * AP Active means more than just configured: driver and BSS are "up";
217 * that is, we are beaconing/responding as an AP (aps_associated).
218 * STA Active similarly means the driver is up and a configured STA BSS
219 * is up: either associated (stas_associated) or trying.
220 *
221 * Macro definitions vary as per AP/STA ifdefs, allowing references to
222 * ifdef'd structure fields and constant values (0) for optimization.
223 * Make sure to enclose blocks of code such that any routines they
224 * reference can also be unused and optimized out by the linker.
225 */
226/* NOTE: References structure fields defined in wlc.h */
227#define AP_ACTIVE(wlc) (0)
228
229/*
230 * Detect Card removed.
231 * Even checking an sbconfig register read will not false trigger when the core is in reset.
232 * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy
233 * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern
234 * (some platforms return all 0).
235 * If clocks are present, call the sb routine which will figure out if the device is removed.
236 */
237#define DEVICEREMOVED(wlc) \
238 ((wlc->hw->clk) ? \
239 ((R_REG(&wlc->hw->regs->maccontrol) & \
240 (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \
241 (ai_deviceremoved(wlc->hw->sih)))
242
243#define BRCMS_UNIT(wlc) ((wlc)->pub->unit)
244
245struct brcms_protection {
246 bool _g; /* use g spec protection, driver internal */
247 s8 g_override; /* override for use of g spec protection */
248 u8 gmode_user; /* user config gmode, operating band->gmode is different */
249 s8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */
250 s8 nmode_user; /* user config nmode, operating pub->nmode is different */
251 s8 n_cfg; /* use OFDM protection on MIMO frames */
252 s8 n_cfg_override; /* override for use of N protection */
253 bool nongf; /* non-GF present protection */
254 s8 nongf_override; /* override for use of GF protection */
255 s8 n_pam_override; /* override for preamble: MM or GF */
256 bool n_obss; /* indicated OBSS Non-HT STA present */
257};
258
259/* anything affects the single/dual streams/antenna operation */
260struct brcms_stf {
261 u8 hw_txchain; /* HW txchain bitmap cfg */
262 u8 txchain; /* txchain bitmap being used */
263 u8 txstreams; /* number of txchains being used */
264
265 u8 hw_rxchain; /* HW rxchain bitmap cfg */
266 u8 rxchain; /* rxchain bitmap being used */
267 u8 rxstreams; /* number of rxchains being used */
268
269 u8 ant_rx_ovr; /* rx antenna override */
270 s8 txant; /* userTx antenna setting */
271 u16 phytxant; /* phyTx antenna setting in txheader */
272
273 u8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */
274 bool ss_algosel_auto; /* if true, use wlc->stf->ss_algo_channel; */
275 /* else use wlc->band->stf->ss_mode_band; */
276 u16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */
277 u8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */
278
279 u8 rxchain_restore_delay; /* delay time to restore default rxchain */
280
281 s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */
282 u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */
283 s8 spatial_policy;
284};
285
286#define BRCMS_STF_SS_STBC_TX(wlc, scb) \
287 (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \
288 (SCB_STBC_CAP((scb)) && \
289 (wlc)->band->band_stf_stbc_tx == AUTO && \
290 isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
291
292#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \
293 NREV_GE(wlc->band->phyrev, 3))
294
295#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \
296 NREV_GE(wlc->band->phyrev, 3)) || \
297 BRCMS_ISLCNPHY(wlc->band))
298
299#define BRCMS_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) \
300 >> RXS_CHAN_PHYTYPE_SHIFT)
301#define BRCMS_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) \
302 >> RXS_CHAN_ID_SHIFT)
303#define BRCMS_RX_CHANNEL(rxh) (BRCMS_CHAN_CHANNEL((rxh)->RxChan))
304
305/* brcms_bss_info flag bit values */
306#define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */
307
308/* Flags used in brcms_c_txq_info.stopped */
309#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */
310#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */
311#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */
312
313#define BRCMS_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */
314#define BRCMS_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */
315
316/* Maximum # of keys that wl driver supports in S/W.
317 * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS.
318 */
319#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */
320#define BRCMS_DEFAULT_KEYS 4 /* Default # of keys */
321
322/*
323* Max # of keys currently supported:
324*
325* s/w keys if WSEC_SW(wlc->wsec).
326* h/w keys otherwise.
327*/
328#define BRCMS_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS
329
330/* number of 802.11 default (non-paired, group keys) */
331#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */
332
333struct wsec_iv {
334 u32 hi; /* upper 32 bits of IV */
335 u16 lo; /* lower 16 bits of IV */
336};
337
338#define BRCMS_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */
339
340struct wsec_key {
341 u8 ea[ETH_ALEN]; /* per station */
342 u8 idx; /* key index in wsec_keys array */
343 u8 id; /* key ID [0-3] */
344 u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
345 u8 rcmta; /* rcmta entry index, same as idx by default */
346 u16 flags; /* misc flags */
347 u8 algo_hw; /* cache for hw register */
348 u8 aes_mode; /* cache for hw register */
349 s8 iv_len; /* IV length */
350 s8 icv_len; /* ICV length */
351 u32 len; /* key length..don't move this var */
352 /* data is 4byte aligned */
353 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
354 struct wsec_iv rxiv[BRCMS_NUMRXIVS]; /* Rx IV (one per TID) */
355 struct wsec_iv txiv; /* Tx IV */
356};
357
358/*
359 * core state (mac)
360 */
361struct brcms_core {
362 uint coreidx; /* # sb enumerated core */
363
364 /* fifo */
365 uint *txavail[NFIFO]; /* # tx descriptors available */
366 s16 txpktpend[NFIFO]; /* tx admission control */
367
368 struct macstat *macstat_snapshot; /* mac hw prev read values */
369};
370
371/*
372 * band state (phy+ana+radio)
373 */
374struct brcms_band {
375 int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
376 uint bandunit; /* bandstate[] index */
377
378 u16 phytype; /* phytype */
379 u16 phyrev;
380 u16 radioid;
381 u16 radiorev;
382 struct brcms_phy_pub *pi; /* pointer to phy specific information */
383 bool abgphy_encore;
384
385 u8 gmode; /* currently active gmode */
386
387 struct scb *hwrs_scb; /* permanent scb for hw rateset */
388
389 wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */
390
391 ratespec_t rspec_override; /* 802.11 rate override */
392 ratespec_t mrspec_override; /* multicast rate override */
393 u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */
394 s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */
395 wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */
396 u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */
397 bool mimo_cap_40; /* 40 MHz cap enabled on this band */
398 s8 antgain; /* antenna gain from srom */
399
400 u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */
401 u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */
402 u16 bcntsfoff; /* beacon tsf offset */
403};
404
405/* tx completion callback takes 3 args */
406typedef void (*pkcb_fn_t) (struct brcms_c_info *wlc, uint txstatus, void *arg);
407
408struct pkt_cb {
409 pkcb_fn_t fn; /* function to call when tx frame completes */
410 void *arg; /* void arg for fn */
411 u8 nextidx; /* index of next call back if threading */
412 bool entered; /* recursion check */
413};
414
415/* module control blocks */
416struct modulecb {
417 char name[32]; /* module name : NULL indicates empty array member */
418 const struct brcmu_iovar *iovars; /* iovar table */
419 void *hdl; /* handle passed when handler 'doiovar' is called */
420 watchdog_fn_t watchdog_fn; /* watchdog handler */
421 iovar_fn_t iovar_fn; /* iovar handler */
422 down_fn_t down_fn; /* down handler. Note: the int returned
423 * by the down function is a count of the
424 * number of timers that could not be
425 * freed.
426 */
427};
428
429/* dump control blocks */
430struct dumpcb_s {
431 const char *name; /* dump name */
432 dump_fn_t dump_fn; /* 'wl dump' handler */
433 void *dump_fn_arg;
434 struct dumpcb_s *next;
435};
436
437struct edcf_acparam {
438 u8 ACI;
439 u8 ECW;
440 u16 TXOP;
441} __packed;
442
443struct wme_param_ie {
444 u8 oui[3];
445 u8 type;
446 u8 subtype;
447 u8 version;
448 u8 qosinfo;
449 u8 rsvd;
450 struct edcf_acparam acparam[AC_COUNT];
451} __packed;
452
453/* virtual interface */
454struct brcms_c_if {
455 struct brcms_c_if *next;
456 u8 type; /* BSS or WDS */
457 u8 index; /* assigned in wl_add_if(), index of the wlif if any,
458 * not necessarily corresponding to bsscfg._idx or
459 * AID2PVBMAP(scb).
460 */
461 u8 flags; /* flags for the interface */
462 struct brcms_if *wlif; /* pointer to wlif */
463 struct brcms_txq_info *qi; /* pointer to associated tx queue */
464 union {
465 /* pointer to scb if WDS */
466 struct scb *scb;
467 /* pointer to bsscfg if BSS */
468 struct brcms_bss_cfg *bsscfg;
469 } u;
470};
471
472/* flags for the interface, this interface is linked to a brcms_if */
473#define BRCMS_IF_LINKED 0x02
474
475struct brcms_hw_band {
476 int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
477 uint bandunit; /* bandstate[] index */
478 u16 mhfs[MHFMAX]; /* MHF array shadow */
479 u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */
480 u16 CWmin;
481 u16 CWmax;
482 u32 core_flags;
483
484 u16 phytype; /* phytype */
485 u16 phyrev;
486 u16 radioid;
487 u16 radiorev;
488 struct brcms_phy_pub *pi; /* pointer to phy specific information */
489 bool abgphy_encore;
490};
491
492struct brcms_hardware {
493 bool _piomode; /* true if pio mode */
494 struct brcms_c_info *wlc;
495
496 /* fifo */
497 struct dma_pub *di[NFIFO]; /* dma handles, per fifo */
498
499 uint unit; /* device instance number */
500
501 /* version info */
502 u16 vendorid; /* PCI vendor id */
503 u16 deviceid; /* PCI device id */
504 uint corerev; /* core revision */
505 u8 sromrev; /* version # of the srom */
506 u16 boardrev; /* version # of particular board */
507 u32 boardflags; /* Board specific flags from srom */
508 u32 boardflags2; /* More board flags if sromrev >= 4 */
509 u32 machwcap; /* MAC capabilities */
510 u32 machwcap_backup; /* backup of machwcap */
511 u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */
512
513 struct si_pub *sih; /* SI handle (cookie for siutils calls) */
514 char *vars; /* "environment" name=value */
515 uint vars_size; /* size of vars, free vars on detach */
516 d11regs_t *regs; /* pointer to device registers */
517 void *physhim; /* phy shim layer handler */
518 void *phy_sh; /* pointer to shared phy state */
519 struct brcms_hw_band *band;/* pointer to active per-band state */
520 /* band state per phy/radio */
521 struct brcms_hw_band *bandstate[MAXBANDS];
522 u16 bmac_phytxant; /* cache of high phytxant state */
523 bool shortslot; /* currently using 11g ShortSlot timing */
524 u16 SRL; /* 802.11 dot11ShortRetryLimit */
525 u16 LRL; /* 802.11 dot11LongRetryLimit */
526 u16 SFBL; /* Short Frame Rate Fallback Limit */
527 u16 LFBL; /* Long Frame Rate Fallback Limit */
528
529 bool up; /* d11 hardware up and running */
530 uint now; /* # elapsed seconds */
531 uint _nbands; /* # bands supported */
532 chanspec_t chanspec; /* bmac chanspec shadow */
533
534 uint *txavail[NFIFO]; /* # tx descriptors available */
535 u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */
536
537 mbool pllreq; /* pll requests to keep PLL on */
538
539 u8 suspended_fifos; /* Which TX fifo to remain awake for */
540 u32 maccontrol; /* Cached value of maccontrol */
541 uint mac_suspend_depth; /* current depth of mac_suspend levels */
542 u32 wake_override; /* Various conditions to force MAC to WAKE mode */
543 u32 mute_override; /* Prevent ucode from sending beacons */
544 u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */
545 u32 led_gpio_mask; /* LED GPIO Mask */
546 bool noreset; /* true= do not reset hw, used by WLC_OUT */
547 bool forcefastclk; /* true if the h/w is forcing the use of fast clk */
548 bool clk; /* core is out of reset and has clock */
549 bool sbclk; /* sb has clock */
550 struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */
551 bool phyclk; /* phy is out of reset and has clock */
552 bool dma_lpbk; /* core is in DMA loopback */
553
554 bool ucode_loaded; /* true after ucode downloaded */
555
556
557 u8 hw_stf_ss_opmode; /* STF single stream operation mode */
558 u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
559 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
560 */
561 u32 antsel_avail; /*
562 * put struct antsel_info here if more info is
563 * needed
564 */
565};
566
567/* TX Queue information
568 *
569 * Each flow of traffic out of the device has a TX Queue with independent
570 * flow control. Several interfaces may be associated with a single TX Queue
571 * if they belong to the same flow of traffic from the device. For multi-channel
572 * operation there are independent TX Queues for each channel.
573 */
574struct brcms_txq_info {
575 struct brcms_txq_info *next;
576 struct pktq q;
577 uint stopped; /* tx flow control bits */
578};
579
580/*
581 * Principal common (os-independent) software data structure.
582 */
583struct brcms_c_info {
584 struct brcms_pub *pub; /* pointer to wlc public state */
585 struct brcms_info *wl; /* pointer to os-specific private state */
586 d11regs_t *regs; /* pointer to device registers */
587
588 /* HW related state used primarily by BMAC */
589 struct brcms_hardware *hw;
590
591 /* clock */
592 int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */
593 u16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */
594
595 /* interrupt */
596 u32 macintstatus; /* bit channel between isr and dpc */
597 u32 macintmask; /* sw runtime master macintmask value */
598 u32 defmacintmask; /* default "on" macintmask value */
599
600 /* up and down */
601 bool device_present; /* (removable) device is present */
602
603 bool clk; /* core is out of reset and has clock */
604
605 /* multiband */
606 struct brcms_core *core; /* pointer to active io core */
607 struct brcms_band *band; /* pointer to active per-band state */
608 struct brcms_core *corestate; /* per-core state (one per hw core) */
609 /* per-band state (one per phy/radio): */
610 struct brcms_band *bandstate[MAXBANDS];
611
612 bool war16165; /* PCI slow clock 16165 war flag */
613
614 bool tx_suspended; /* data fifos need to remain suspended */
615
616 uint txpend16165war;
617
618 /* packet queue */
619 uint qvalid; /* DirFrmQValid and BcMcFrmQValid */
620
621 /* Regulatory power limits */
622 s8 txpwr_local_max; /* regulatory local txpwr max */
623 u8 txpwr_local_constraint; /* local power contraint in dB */
624
625
626 struct ampdu_info *ampdu; /* ampdu module handler */
627 struct antsel_info *asi; /* antsel module handler */
628 struct brcms_cm_info *cmi; /* channel manager module handler */
629
630 uint vars_size; /* size of vars, free vars on detach */
631
632 u16 vendorid; /* PCI vendor id */
633 u16 deviceid; /* PCI device id */
634 uint ucode_rev; /* microcode revision */
635
636 u32 machwcap; /* MAC capabilities, BMAC shadow */
637
638 u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */
639
640 bool bandlocked; /* disable auto multi-band switching */
641 bool bandinit_pending; /* track band init in auto band */
642
643 bool radio_monitor; /* radio timer is running */
644 bool going_down; /* down path intermediate variable */
645
646 bool mpc; /* enable minimum power consumption */
647 u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */
648 u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */
649 u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */
650 u8 prev_non_delay_mpc; /* prev state brcms_c_is_non_delay_mpc */
651
652 /* timer for watchdog routine */
653 struct brcms_timer *wdtimer;
654 /* timer for hw radio button monitor routine */
655 struct brcms_timer *radio_timer;
656
657 /* promiscuous */
658 bool monitor; /* monitor (MPDU sniffing) mode */
659 bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */
660 bool bcnmisc_scan; /* bcns promisc mode override for scan */
661 bool bcnmisc_monitor; /* bcns promisc mode override for monitor */
662
663 /* driver feature */
664 bool _rifs; /* enable per-packet rifs */
665 s8 sgi_tx; /* sgi tx */
666
667 /* AP-STA synchronization, power save */
668 u8 bcn_li_bcn; /* beacon listen interval in # beacons */
669 u8 bcn_li_dtim; /* beacon listen interval in # dtims */
670
671 bool WDarmed; /* watchdog timer is armed */
672 u32 WDlast; /* last time wlc_watchdog() was called */
673
674 /* WME */
675 ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */
676 u16 edcf_txop[AC_COUNT]; /* current txop for each ac */
677
678 /*
679 * WME parameter info element, which on STA contains parameters in use
680 * locally, and on AP contains parameters advertised to STA in beacons
681 * and assoc responses.
682 */
683 struct wme_param_ie wme_param_ie;
684 u16 wme_retries[AC_COUNT]; /* per-AC retry limits */
685
686 u16 tx_prec_map; /* Precedence map based on HW FIFO space */
687 u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */
688
689 /*
690 * BSS Configurations set of BSS configurations, idx 0 is default and
691 * always valid
692 */
693 struct brcms_bss_cfg *bsscfg[BRCMS_MAXBSSCFG];
694 struct brcms_bss_cfg *cfg; /* the primary bsscfg (can be AP or STA) */
695
696 /* tx queue */
697 struct brcms_txq_info *tx_queues; /* common TX Queue list */
698
699 /* security */
700 struct wsec_key *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */
701 /* default key storage */
702 struct wsec_key *wsec_def_keys[BRCMS_DEFAULT_KEYS];
703 bool wsec_swkeys; /* indicates that all keys should be
704 * treated as sw keys (used for debugging)
705 */
706 struct modulecb *modulecb;
707
708 u8 mimoft; /* SIGN or 11N */
709 s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */
710 s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */
711 s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */
712 /* HT CAP IE being advertised by this node: */
713 struct ieee80211_ht_cap ht_cap;
714
715 struct brcms_bss_info *default_bss; /* configured BSS parameters */
716
717 u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */
718
719 /* saved country for leaving 802.11d auto-country mode */
720 char country_default[BRCM_CNTRY_BUF_SZ];
721 /* initial country for 802.11d auto-country mode */
722 char autocountry_default[BRCM_CNTRY_BUF_SZ];
723 u16 prb_resp_timeout; /* do not send prb resp if request older than this,
724 * 0 = disable
725 */
726
727 wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if
728 * specifed
729 */
730
731 chanspec_t home_chanspec; /* shared home chanspec */
732
733 /* PHY parameters */
734 chanspec_t chanspec; /* target operational channel */
735 u16 usr_fragthresh; /* user configured fragmentation threshold */
736 u16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */
737 u16 RTSThresh; /* 802.11 dot11RTSThreshold */
738 u16 SRL; /* 802.11 dot11ShortRetryLimit */
739 u16 LRL; /* 802.11 dot11LongRetryLimit */
740 u16 SFBL; /* Short Frame Rate Fallback Limit */
741 u16 LFBL; /* Long Frame Rate Fallback Limit */
742
743 /* network config */
744 bool shortslot; /* currently using 11g ShortSlot timing */
745 s8 shortslot_override; /* 11g ShortSlot override */
746 bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */
747
748 struct brcms_protection *protection;
749 s8 PLCPHdr_override; /* 802.11b Preamble Type override */
750
751 struct brcms_stf *stf;
752
753 ratespec_t bcn_rspec; /* save bcn ratespec purpose */
754
755 uint tempsense_lasttime;
756
757 u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */
758 u16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */
759
760 u16 next_bsscfg_ID;
761
762 struct brcms_txq_info *pkt_queue; /* txq for transmit packets */
763 u32 mpc_dur; /* total time (ms) in mpc mode except for the
764 * portion since radio is turned off last time
765 */
766 u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last
767 * time
768 */
769 struct wiphy *wiphy;
770};
771
772/* antsel module specific state */
773struct antsel_info {
774 struct brcms_c_info *wlc; /* pointer to main wlc structure */
775 struct brcms_pub *pub; /* pointer to public fn */
776 u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
777 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
778 */
779 u8 antsel_antswitch; /* board level antenna switch type */
780 bool antsel_avail; /* Ant selection availability (SROM based) */
781 struct brcms_antselcfg antcfg_11n; /* antenna configuration */
782 struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
783};
784
785/* BSS configuration state */
786struct brcms_bss_cfg {
787 struct brcms_c_info *wlc; /* wlc to which this bsscfg belongs to. */
788 bool up; /* is this configuration up operational */
789 bool enable; /* is this configuration enabled */
790 bool associated; /* is BSS in ASSOCIATED state */
791 bool BSS; /* infraustructure or adhac */
792 bool dtim_programmed;
793
794 u8 SSID_len; /* the length of SSID */
795 u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */
796 struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */
797 s8 _idx; /* the index of this bsscfg,
798 * assigned at wlc_bsscfg_alloc()
799 */
800 /* MAC filter */
801 uint nmac; /* # of entries on maclist array */
802 int macmode; /* allow/deny stations on maclist array */
803 struct ether_addr *maclist; /* list of source MAC addrs to match */
804
805 /* security */
806 u32 wsec; /* wireless security bitvec */
807 s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */
808 s16 openshared; /* try Open auth first, then Shared Key */
809 bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */
810 bool eap_restrict; /* restrict data until 802.1X auth succeeds */
811 u16 WPA_auth; /* WPA: authenticated key management */
812 bool wpa2_preauth; /* default is true, wpa_cap sets value */
813 bool wsec_portopen; /* indicates keys are plumbed */
814 /* global txiv for WPA_NONE, tkip and aes */
815 struct wsec_iv wpa_none_txiv;
816 int wsec_index; /* 0-3: default tx key, -1: not set */
817 /* default key storage: */
818 struct wsec_key *bss_def_keys[BRCMS_DEFAULT_KEYS];
819
820 /* TKIP countermeasures */
821 bool tkip_countermeasures; /* flags TKIP no-assoc period */
822 u32 tk_cm_dt; /* detect timer */
823 u32 tk_cm_bt; /* blocking timer */
824 u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */
825 bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */
826
827 u8 BSSID[ETH_ALEN]; /* BSSID (associated) */
828 u8 cur_etheraddr[ETH_ALEN]; /* h/w address */
829 u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */
830 u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */
831
832 u32 flags; /* BSSCFG flags; see below */
833
834 u8 *bcn; /* AP beacon */
835 uint bcn_len; /* AP beacon length */
836 bool ar_disassoc; /* disassociated in associated recreation */
837
838 int auth_atmptd; /* auth type (open/shared) attempted */
839
840 pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */
841 uint npmkid_cand; /* num PMKID candidates */
842 pmkid_t pmkid[MAXPMKID]; /* PMKID cache */
843 uint npmkid; /* num cached PMKIDs */
844
845 struct brcms_bss_info *current_bss; /* BSS parms in ASSOCIATED state */
846
847 /* PM states */
848 bool PMawakebcn; /* bcn recvd during current waking state */
849 bool PMpending; /* waiting for tx status with PM indicated set */
850 bool priorPMstate; /* Detecting PM state transitions */
851 bool PSpoll; /* whether there is an outstanding PS-Poll frame */
852
853 /* BSSID entry in RCMTA, use the wsec key management infrastructure to
854 * manage the RCMTA entries.
855 */
856 struct wsec_key *rcmta;
857
858 /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */
859 u16 ID;
860
861 uint txrspecidx; /* index into tx rate circular buffer */
862 ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */
863};
864
865#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
866#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
867
868#define IS_MBAND_UNLOCKED(wlc) \
869 ((NBANDS(wlc) > 1) && !(wlc)->bandlocked)
870
871#define BRCMS_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi)
872
873/* sum the individual fifo tx pending packet counts */
874#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \
875 (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3])
876#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)])
877#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val))
878#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val))
879#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0)
880#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)])
881#define GETNEXTTXP(wlc, _queue) \
882 dma_getnexttxp((wlc)->hw->di[(_queue)], DMA_RANGE_TRANSMITTED)
883
884#define BRCMS_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \
885 ((len1 == len2) && !memcmp(ssid1, ssid2, len1))
886
887extern void brcms_c_fatal_error(struct brcms_c_info *wlc);
888extern void brcms_b_rpc_watchdog(struct brcms_c_info *wlc);
889extern void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p);
890extern bool brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs,
891 u32 frm_tx2);
892extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
893 struct sk_buff *p,
894 bool commit, s8 txpktpend);
895extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
896 s8 txpktpend);
897extern void brcms_c_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
898 uint prec);
899extern void brcms_c_info_init(struct brcms_c_info *wlc, int unit);
900extern void brcms_c_print_txstatus(struct tx_status *txs);
901extern int brcms_c_xmtfifo_sz_get(struct brcms_c_info *wlc, uint fifo,
902 uint *blocks);
903extern void brcms_c_write_template_ram(struct brcms_c_info *wlc, int offset,
904 int len, void *buf);
905extern void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, void *bcn,
906 int len, bool both);
907extern void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, mbool req_bit);
908extern void brcms_c_reset_bmac_done(struct brcms_c_info *wlc);
909
910#if defined(BCMDBG)
911extern void brcms_c_print_rxh(struct d11rxhdr *rxh);
912extern void brcms_c_print_txdesc(struct d11txh *txh);
913#else
914#define brcms_c_print_txdesc(a)
915#endif
916
917extern void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit);
918extern void brcms_c_coredisable(struct brcms_hardware *wlc_hw);
919
920extern bool brcms_c_valid_rate(struct brcms_c_info *wlc, ratespec_t rate,
921 int band, bool verbose);
922extern void brcms_c_ap_upd(struct brcms_c_info *wlc);
923
924/* helper functions */
925extern void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc,
926 struct brcms_bss_cfg *cfg);
927extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
928
929extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
930 bool promisc);
931extern void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc);
932extern void brcms_c_mac_promisc(struct brcms_c_info *wlc);
933extern void brcms_c_txflowcontrol(struct brcms_c_info *wlc,
934 struct brcms_txq_info *qi,
935 bool on, int prio);
936extern void brcms_c_txflowcontrol_override(struct brcms_c_info *wlc,
937 struct brcms_txq_info *qi,
938 bool on, uint override);
939extern bool brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc,
940 struct brcms_txq_info *qi,
941 int prio);
942extern void brcms_c_send_q(struct brcms_c_info *wlc);
943extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
944 uint *fifo);
945
946extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec,
947 uint mac_len);
948extern ratespec_t brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
949 ratespec_t rspec,
950 bool use_rspec, u16 mimo_ctlchbw);
951extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
952 ratespec_t rts_rate,
953 ratespec_t frame_rate,
954 u8 rts_preamble_type,
955 u8 frame_preamble_type, uint frame_len,
956 bool ba);
957
958extern void brcms_c_tbtt(struct brcms_c_info *wlc);
959extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
960 struct ieee80211_sta *sta,
961 void (*dma_callback_fn));
962
963extern void brcms_c_reprate_init(struct brcms_c_info *wlc);
964extern void brcms_c_bsscfg_reprate_init(struct brcms_bss_cfg *bsscfg);
965
966/* Shared memory access */
967extern void brcms_c_write_shm(struct brcms_c_info *wlc, uint offset, u16 v);
968extern u16 brcms_c_read_shm(struct brcms_c_info *wlc, uint offset);
969extern void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
970 const void *buf, int len);
971
972extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
973extern void brcms_c_bss_update_beacon(struct brcms_c_info *wlc,
974 struct brcms_bss_cfg *bsscfg);
975
976extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
977extern void brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
978 struct brcms_bss_cfg *cfg,
979 bool suspend);
980extern bool brcms_c_ismpc(struct brcms_c_info *wlc);
981extern bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc);
982extern void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc);
983extern bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
984 void *pkt, int prec);
985extern bool brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
986 struct sk_buff *pkt, int prec, bool head);
987extern u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec);
988extern void brcms_c_compute_plcp(struct brcms_c_info *wlc, ratespec_t rate,
989 uint length, u8 *plcp);
990extern uint brcms_c_calc_frame_time(struct brcms_c_info *wlc,
991 ratespec_t ratespec,
992 u8 preamble_type, uint mac_len);
993
994extern void brcms_c_set_chanspec(struct brcms_c_info *wlc,
995 chanspec_t chanspec);
996
997extern bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit);
998
999extern int brcms_c_set_nmode(struct brcms_c_info *wlc, s32 nmode);
1000extern void brcms_c_mimops_action_ht_send(struct brcms_c_info *wlc,
1001 struct brcms_bss_cfg *bsscfg,
1002 u8 mimops_mode);
1003
1004extern void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot);
1005extern void brcms_c_set_bssid(struct brcms_bss_cfg *cfg);
1006extern void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend);
1007
1008extern void brcms_c_set_ratetable(struct brcms_c_info *wlc);
1009extern int brcms_c_set_mac(struct brcms_bss_cfg *cfg);
1010extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
1011 ratespec_t bcn_rate);
1012extern void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc,
1013 uint frame_len);
1014extern ratespec_t brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc,
1015 wlc_rateset_t *rs);
1016extern void brcms_c_radio_disable(struct brcms_c_info *wlc);
1017extern void brcms_c_bcn_li_upd(struct brcms_c_info *wlc);
1018extern void brcms_c_set_home_chanspec(struct brcms_c_info *wlc,
1019 chanspec_t chanspec);
1020extern bool brcms_c_ps_allowed(struct brcms_c_info *wlc);
1021extern bool brcms_c_stay_awake(struct brcms_c_info *wlc);
1022extern void brcms_c_wme_initparams_sta(struct brcms_c_info *wlc,
1023 struct wme_param_ie *pe);
1024
1025#endif /* _BRCM_MAIN_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.c b/drivers/staging/brcm80211/brcmsmac/nicpci.c
new file mode 100644
index 00000000000..3d71c590fce
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/nicpci.c
@@ -0,0 +1,850 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include <linux/pci.h>
20
21#include <defs.h>
22#include <soc.h>
23#include <chipcommon.h>
24#include "aiutils.h"
25#include "pub.h"
26#include "nicpci.h"
27
28/* SPROM offsets */
29#define SRSH_ASPM_OFFSET 4 /* word 4 */
30#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */
31#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */
32#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */
33
34#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */
35#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */
36#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */
37#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */
38#define SRSH_BD_OFFSET 6 /* word 6 */
39
40/* chipcontrol */
41#define CHIPCTRL_4321_PLL_DOWN 0x800000/* serdes PLL down override */
42
43/* MDIO control */
44#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
45#define MDIOCTL_DIVISOR_VAL 0x2
46#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
47#define MDIOCTL_ACCESS_DONE 0x100 /* Transaction complete */
48
49/* MDIO Data */
50#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
51#define MDIODATA_TA 0x00020000 /* Turnaround */
52
53#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
54#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
55#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
56#define MDIODATA_DEVADDR_MASK 0x0f800000
57 /* Physmedia devaddr Mask */
58
59/* MDIO Data for older revisions < 10 */
60#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift */
61#define MDIODATA_REGADDR_MASK_OLD 0x003c0000
62 /* Regaddr Mask */
63#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift */
64#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000
65 /* Physmedia devaddr Mask */
66
67/* Transactions flags */
68#define MDIODATA_WRITE 0x10000000
69#define MDIODATA_READ 0x20000000
70#define MDIODATA_START 0x40000000
71
72#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
73#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
74
75/* serdes regs (rev < 10) */
76#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
77#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
78#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
79
80/* SERDES RX registers */
81#define SERDES_RX_CTRL 1 /* Rx cntrl */
82#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
83#define SERDES_RX_CDR 6 /* CDR */
84#define SERDES_RX_CDRBW 7 /* CDR BW */
85/* SERDES RX control register */
86#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
87#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
88
89/* SERDES PLL registers */
90#define SERDES_PLL_CTRL 1 /* PLL control reg */
91#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
92
93/* Linkcontrol reg offset in PCIE Cap */
94#define PCIE_CAP_LINKCTRL_OFFSET 16 /* offset in pcie cap */
95#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */
96#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */
97#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */
98
99#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */
100#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */
101#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */
102#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */
103
104/* Power management threshold */
105#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */
106#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */
107#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */
108#define PCIE_ASPMTIMER_EXTEND 0x01000000
109 /* > rev7:
110 * enable extend ASPM timer
111 */
112
113/* different register spaces to access thru pcie indirect access */
114#define PCIE_CONFIGREGS 1 /* Access to config space */
115#define PCIE_PCIEREGS 2 /* Access to pcie registers */
116
117/* PCIE protocol PHY diagnostic registers */
118#define PCIE_PLP_STATUSREG 0x204 /* Status */
119
120/* Status reg PCIE_PLP_STATUSREG */
121#define PCIE_PLP_POLARITYINV_STAT 0x10
122
123/* PCIE protocol DLLP diagnostic registers */
124#define PCIE_DLLP_LCREG 0x100 /* Link Control */
125#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
126
127/* PCIE protocol TLP diagnostic registers */
128#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
129
130/* Sonics side: PCI core and host control registers */
131struct sbpciregs {
132 u32 control; /* PCI control */
133 u32 PAD[3];
134 u32 arbcontrol; /* PCI arbiter control */
135 u32 clkrun; /* Clkrun Control (>=rev11) */
136 u32 PAD[2];
137 u32 intstatus; /* Interrupt status */
138 u32 intmask; /* Interrupt mask */
139 u32 sbtopcimailbox; /* Sonics to PCI mailbox */
140 u32 PAD[9];
141 u32 bcastaddr; /* Sonics broadcast address */
142 u32 bcastdata; /* Sonics broadcast data */
143 u32 PAD[2];
144 u32 gpioin; /* ro: gpio input (>=rev2) */
145 u32 gpioout; /* rw: gpio output (>=rev2) */
146 u32 gpioouten; /* rw: gpio output enable (>= rev2) */
147 u32 gpiocontrol; /* rw: gpio control (>= rev2) */
148 u32 PAD[36];
149 u32 sbtopci0; /* Sonics to PCI translation 0 */
150 u32 sbtopci1; /* Sonics to PCI translation 1 */
151 u32 sbtopci2; /* Sonics to PCI translation 2 */
152 u32 PAD[189];
153 u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
154 u16 sprom[36]; /* SPROM shadow Area */
155 u32 PAD[46];
156};
157
158/* SB side: PCIE core and host control registers */
159struct sbpcieregs {
160 u32 control; /* host mode only */
161 u32 PAD[2];
162 u32 biststatus; /* bist Status: 0x00C */
163 u32 gpiosel; /* PCIE gpio sel: 0x010 */
164 u32 gpioouten; /* PCIE gpio outen: 0x14 */
165 u32 PAD[2];
166 u32 intstatus; /* Interrupt status: 0x20 */
167 u32 intmask; /* Interrupt mask: 0x24 */
168 u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
169 u32 PAD[53];
170 u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
171 u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
172 u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
173 u32 PAD[5];
174
175 /* pcie core supports in direct access to config space */
176 u32 configaddr; /* pcie config space access: Address field: 0x120 */
177 u32 configdata; /* pcie config space access: Data field: 0x124 */
178
179 /* mdio access to serdes */
180 u32 mdiocontrol; /* controls the mdio access: 0x128 */
181 u32 mdiodata; /* Data to the mdio access: 0x12c */
182
183 /* pcie protocol phy/dllp/tlp register indirect access mechanism */
184 u32 pcieindaddr; /* indirect access to
185 * the internal register: 0x130
186 */
187 u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */
188
189 u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */
190 u32 PAD[177];
191 u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */
192 u16 sprom[64]; /* SPROM shadow Area */
193};
194
195struct pcicore_info {
196 union {
197 struct sbpcieregs *pcieregs;
198 struct sbpciregs *pciregs;
199 } regs; /* Memory mapped register to the core */
200
201 struct si_pub *sih; /* System interconnect handle */
202 struct pci_dev *dev;
203 u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
204 * in the config space
205 */
206 bool pcie_pr42767;
207 u8 pcie_polarity;
208 u8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */
209
210 u8 pmecap_offset; /* PM Capability offset in the config space */
211 bool pmecap; /* Capable of generating PME */
212};
213
214/* debug/trace */
215#define PCI_ERROR(args)
216#define PCIE_PUB(sih) \
217 (((sih)->bustype == PCI_BUS) && \
218 ((sih)->buscoretype == PCIE_CORE_ID))
219
220/* routines to access mdio slave device registers */
221static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk);
222static int pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr,
223 bool write, uint *val);
224static int pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint readdr,
225 uint val);
226static int pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint readdr,
227 uint *ret_val);
228
229static void pcie_extendL1timer(struct pcicore_info *pi, bool extend);
230static void pcie_clkreq_upd(struct pcicore_info *pi, uint state);
231
232static void pcie_war_aspm_clkreq(struct pcicore_info *pi);
233static void pcie_war_serdes(struct pcicore_info *pi);
234static void pcie_war_noplldown(struct pcicore_info *pi);
235static void pcie_war_polarity(struct pcicore_info *pi);
236static void pcie_war_pci_setup(struct pcicore_info *pi);
237
238#define PCIE_ASPM(sih) \
239 ((PCIE_PUB(sih)) && \
240 (((sih)->buscorerev >= 3) && \
241 ((sih)->buscorerev <= 5)))
242
243
244/* delay needed between the mdio control/ mdiodata register data access */
245#define PR28829_DELAY() udelay(10)
246
247/* Initialize the PCI core.
248 * It's caller's responsibility to make sure that this is done only once
249 */
250void *pcicore_init(struct si_pub *sih, void *pdev, void *regs)
251{
252 struct pcicore_info *pi;
253
254 /* alloc struct pcicore_info */
255 pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
256 if (pi == NULL) {
257 PCI_ERROR(("pci_attach: malloc failed!\n"));
258 return NULL;
259 }
260
261 pi->sih = sih;
262 pi->dev = pdev;
263
264 if (sih->buscoretype == PCIE_CORE_ID) {
265 u8 cap_ptr;
266 pi->regs.pcieregs = regs;
267 cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
268 NULL, NULL);
269 pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
270 } else
271 pi->regs.pciregs = regs;
272
273 return pi;
274}
275
276void pcicore_deinit(void *pch)
277{
278 kfree(pch);
279}
280
281/* return cap_offset if requested capability exists in the PCI config space */
282/* Note that it's caller's responsibility to make sure it's a pci bus */
283u8
284pcicore_find_pci_capability(void *dev, u8 req_cap_id,
285 unsigned char *buf, u32 *buflen)
286{
287 u8 cap_id;
288 u8 cap_ptr = 0;
289 u32 bufsize;
290 u8 byte_val;
291
292 /* check for Header type 0 */
293 pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
294 if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
295 goto end;
296
297 /* check if the capability pointer field exists */
298 pci_read_config_byte(dev, PCI_STATUS, &byte_val);
299 if (!(byte_val & PCI_STATUS_CAP_LIST))
300 goto end;
301
302 pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
303 /* check if the capability pointer is 0x00 */
304 if (cap_ptr == 0x00)
305 goto end;
306
307 /* loop thru the capability list
308 * and see if the pcie capability exists
309 */
310
311 pci_read_config_byte(dev, cap_ptr, &cap_id);
312
313 while (cap_id != req_cap_id) {
314 pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
315 if (cap_ptr == 0x00)
316 break;
317 pci_read_config_byte(dev, cap_ptr, &cap_id);
318 }
319 if (cap_id != req_cap_id)
320 goto end;
321
322 /* found the caller requested capability */
323 if (buf != NULL && buflen != NULL) {
324 u8 cap_data;
325
326 bufsize = *buflen;
327 if (!bufsize)
328 goto end;
329 *buflen = 0;
330 /* copy the capability data excluding cap ID and next ptr */
331 cap_data = cap_ptr + 2;
332 if ((bufsize + cap_data) > PCI_SZPCR)
333 bufsize = PCI_SZPCR - cap_data;
334 *buflen = bufsize;
335 while (bufsize--) {
336 pci_read_config_byte(dev, cap_data, buf);
337 cap_data++;
338 buf++;
339 }
340 }
341end:
342 return cap_ptr;
343}
344
345/* ***** Register Access API */
346static uint
347pcie_readreg(struct sbpcieregs *pcieregs, uint addrtype, uint offset)
348{
349 uint retval = 0xFFFFFFFF;
350
351 switch (addrtype) {
352 case PCIE_CONFIGREGS:
353 W_REG(&pcieregs->configaddr, offset);
354 (void)R_REG((&pcieregs->configaddr));
355 retval = R_REG(&pcieregs->configdata);
356 break;
357 case PCIE_PCIEREGS:
358 W_REG(&pcieregs->pcieindaddr, offset);
359 (void)R_REG(&pcieregs->pcieindaddr);
360 retval = R_REG(&pcieregs->pcieinddata);
361 break;
362 }
363
364 return retval;
365}
366
367static uint
368pcie_writereg(struct sbpcieregs *pcieregs, uint addrtype, uint offset, uint val)
369{
370 switch (addrtype) {
371 case PCIE_CONFIGREGS:
372 W_REG((&pcieregs->configaddr), offset);
373 W_REG((&pcieregs->configdata), val);
374 break;
375 case PCIE_PCIEREGS:
376 W_REG((&pcieregs->pcieindaddr), offset);
377 W_REG((&pcieregs->pcieinddata), val);
378 break;
379 default:
380 break;
381 }
382 return 0;
383}
384
385static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
386{
387 struct sbpcieregs *pcieregs = pi->regs.pcieregs;
388 uint mdiodata, i = 0;
389 uint pcie_serdes_spinwait = 200;
390
391 mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
392 (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
393 (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
394 (blk << 4));
395 W_REG(&pcieregs->mdiodata, mdiodata);
396
397 PR28829_DELAY();
398 /* retry till the transaction is complete */
399 while (i < pcie_serdes_spinwait) {
400 if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE)
401 break;
402 udelay(1000);
403 i++;
404 }
405
406 if (i >= pcie_serdes_spinwait) {
407 PCI_ERROR(("pcie_mdiosetblock: timed out\n"));
408 return false;
409 }
410
411 return true;
412}
413
414static int
415pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
416 uint *val)
417{
418 struct sbpcieregs *pcieregs = pi->regs.pcieregs;
419 uint mdiodata;
420 uint i = 0;
421 uint pcie_serdes_spinwait = 10;
422
423 /* enable mdio access to SERDES */
424 W_REG(&pcieregs->mdiocontrol, MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
425
426 if (pi->sih->buscorerev >= 10) {
427 /* new serdes is slower in rw,
428 * using two layers of reg address mapping
429 */
430 if (!pcie_mdiosetblock(pi, physmedia))
431 return 1;
432 mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
433 (regaddr << MDIODATA_REGADDR_SHF));
434 pcie_serdes_spinwait *= 20;
435 } else {
436 mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
437 (regaddr << MDIODATA_REGADDR_SHF_OLD));
438 }
439
440 if (!write)
441 mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
442 else
443 mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
444 *val);
445
446 W_REG(&pcieregs->mdiodata, mdiodata);
447
448 PR28829_DELAY();
449
450 /* retry till the transaction is complete */
451 while (i < pcie_serdes_spinwait) {
452 if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) {
453 if (!write) {
454 PR28829_DELAY();
455 *val = (R_REG(&pcieregs->mdiodata) &
456 MDIODATA_MASK);
457 }
458 /* Disable mdio access to SERDES */
459 W_REG(&pcieregs->mdiocontrol, 0);
460 return 0;
461 }
462 udelay(1000);
463 i++;
464 }
465
466 PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
467 /* Disable mdio access to SERDES */
468 W_REG(&pcieregs->mdiocontrol, 0);
469 return 1;
470}
471
472/* use the mdio interface to read from mdio slaves */
473static int
474pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
475 uint *regval)
476{
477 return pcie_mdioop(pi, physmedia, regaddr, false, regval);
478}
479
480/* use the mdio interface to write to mdio slaves */
481static int
482pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
483{
484 return pcie_mdioop(pi, physmedia, regaddr, true, &val);
485}
486
487/* ***** Support functions ***** */
488static u8 pcie_clkreq(void *pch, u32 mask, u32 val)
489{
490 struct pcicore_info *pi = pch;
491 u32 reg_val;
492 u8 offset;
493
494 offset = pi->pciecap_lcreg_offset;
495 if (!offset)
496 return 0;
497
498 pci_read_config_dword(pi->dev, offset, &reg_val);
499 /* set operation */
500 if (mask) {
501 if (val)
502 reg_val |= PCIE_CLKREQ_ENAB;
503 else
504 reg_val &= ~PCIE_CLKREQ_ENAB;
505 pci_write_config_dword(pi->dev, offset, reg_val);
506 pci_read_config_dword(pi->dev, offset, &reg_val);
507 }
508 if (reg_val & PCIE_CLKREQ_ENAB)
509 return 1;
510 else
511 return 0;
512}
513
514static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
515{
516 u32 w;
517 struct si_pub *sih = pi->sih;
518 struct sbpcieregs *pcieregs = pi->regs.pcieregs;
519
520 if (!PCIE_PUB(sih) || sih->buscorerev < 7)
521 return;
522
523 w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
524 if (extend)
525 w |= PCIE_ASPMTIMER_EXTEND;
526 else
527 w &= ~PCIE_ASPMTIMER_EXTEND;
528 pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
529 w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
530}
531
532/* centralized clkreq control policy */
533static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
534{
535 struct si_pub *sih = pi->sih;
536
537 switch (state) {
538 case SI_DOATTACH:
539 if (PCIE_ASPM(sih))
540 pcie_clkreq((void *)pi, 1, 0);
541 break;
542 case SI_PCIDOWN:
543 if (sih->buscorerev == 6) { /* turn on serdes PLL down */
544 ai_corereg(sih, SI_CC_IDX,
545 offsetof(chipcregs_t, chipcontrol_addr),
546 ~0, 0);
547 ai_corereg(sih, SI_CC_IDX,
548 offsetof(chipcregs_t, chipcontrol_data),
549 ~0x40, 0);
550 } else if (pi->pcie_pr42767) {
551 pcie_clkreq((void *)pi, 1, 1);
552 }
553 break;
554 case SI_PCIUP:
555 if (sih->buscorerev == 6) { /* turn off serdes PLL down */
556 ai_corereg(sih, SI_CC_IDX,
557 offsetof(chipcregs_t, chipcontrol_addr),
558 ~0, 0);
559 ai_corereg(sih, SI_CC_IDX,
560 offsetof(chipcregs_t, chipcontrol_data),
561 ~0x40, 0x40);
562 } else if (PCIE_ASPM(sih)) { /* disable clkreq */
563 pcie_clkreq((void *)pi, 1, 0);
564 }
565 break;
566 }
567}
568
569/* ***** PCI core WARs ***** */
570/* Done only once at attach time */
571static void pcie_war_polarity(struct pcicore_info *pi)
572{
573 u32 w;
574
575 if (pi->pcie_polarity != 0)
576 return;
577
578 w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
579
580 /* Detect the current polarity at attach and force that polarity and
581 * disable changing the polarity
582 */
583 if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
584 pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
585 else
586 pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
587 SERDES_RX_CTRL_POLARITY);
588}
589
590/* enable ASPM and CLKREQ if srom doesn't have it */
591/* Needs to happen when update to shadow SROM is needed
592 * : Coming out of 'standby'/'hibernate'
593 * : If pcie_war_aspm_ovr state changed
594 */
595static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
596{
597 struct sbpcieregs *pcieregs = pi->regs.pcieregs;
598 struct si_pub *sih = pi->sih;
599 u16 val16, *reg16;
600 u32 w;
601
602 if (!PCIE_ASPM(sih))
603 return;
604
605 /* bypass this on QT or VSIM */
606 reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
607 val16 = R_REG(reg16);
608
609 val16 &= ~SRSH_ASPM_ENB;
610 if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
611 val16 |= SRSH_ASPM_ENB;
612 else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
613 val16 |= SRSH_ASPM_L1_ENB;
614 else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
615 val16 |= SRSH_ASPM_L0s_ENB;
616
617 W_REG(reg16, val16);
618
619 pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
620 w &= ~PCIE_ASPM_ENAB;
621 w |= pi->pcie_war_aspm_ovr;
622 pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
623
624 reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
625 val16 = R_REG(reg16);
626
627 if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
628 val16 |= SRSH_CLKREQ_ENB;
629 pi->pcie_pr42767 = true;
630 } else
631 val16 &= ~SRSH_CLKREQ_ENB;
632
633 W_REG(reg16, val16);
634}
635
636/* Apply the polarity determined at the start */
637/* Needs to happen when coming out of 'standby'/'hibernate' */
638static void pcie_war_serdes(struct pcicore_info *pi)
639{
640 u32 w = 0;
641
642 if (pi->pcie_polarity != 0)
643 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
644 pi->pcie_polarity);
645
646 pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
647 if (w & PLL_CTRL_FREQDET_EN) {
648 w &= ~PLL_CTRL_FREQDET_EN;
649 pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
650 }
651}
652
653/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
654/* Needs to happen when coming out of 'standby'/'hibernate' */
655static void pcie_misc_config_fixup(struct pcicore_info *pi)
656{
657 struct sbpcieregs *pcieregs = pi->regs.pcieregs;
658 u16 val16, *reg16;
659
660 reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
661 val16 = R_REG(reg16);
662
663 if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
664 val16 |= SRSH_L23READY_EXIT_NOPERST;
665 W_REG(reg16, val16);
666 }
667}
668
669/* quick hack for testing */
670/* Needs to happen when coming out of 'standby'/'hibernate' */
671static void pcie_war_noplldown(struct pcicore_info *pi)
672{
673 struct sbpcieregs *pcieregs = pi->regs.pcieregs;
674 u16 *reg16;
675
676 /* turn off serdes PLL down */
677 ai_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol),
678 CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
679
680 /* clear srom shadow backdoor */
681 reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
682 W_REG(reg16, 0);
683}
684
685/* Needs to happen when coming out of 'standby'/'hibernate' */
686static void pcie_war_pci_setup(struct pcicore_info *pi)
687{
688 struct si_pub *sih = pi->sih;
689 struct sbpcieregs *pcieregs = pi->regs.pcieregs;
690 u32 w;
691
692 if (sih->buscorerev == 0 || sih->buscorerev == 1) {
693 w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
694 PCIE_TLP_WORKAROUNDSREG);
695 w |= 0x8;
696 pcie_writereg(pcieregs, PCIE_PCIEREGS,
697 PCIE_TLP_WORKAROUNDSREG, w);
698 }
699
700 if (sih->buscorerev == 1) {
701 w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
702 w |= 0x40;
703 pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
704 }
705
706 if (sih->buscorerev == 0) {
707 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
708 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
709 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
710 } else if (PCIE_ASPM(sih)) {
711 /* Change the L1 threshold for better performance */
712 w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
713 PCIE_DLLP_PMTHRESHREG);
714 w &= ~PCIE_L1THRESHOLDTIME_MASK;
715 w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
716 pcie_writereg(pcieregs, PCIE_PCIEREGS,
717 PCIE_DLLP_PMTHRESHREG, w);
718
719 pcie_war_serdes(pi);
720
721 pcie_war_aspm_clkreq(pi);
722 } else if (pi->sih->buscorerev == 7)
723 pcie_war_noplldown(pi);
724
725 /* Note that the fix is actually in the SROM,
726 * that's why this is open-ended
727 */
728 if (pi->sih->buscorerev >= 6)
729 pcie_misc_config_fixup(pi);
730}
731
732/* ***** Functions called during driver state changes ***** */
733void pcicore_attach(void *pch, char *pvars, int state)
734{
735 struct pcicore_info *pi = pch;
736 struct si_pub *sih = pi->sih;
737
738 /* Determine if this board needs override */
739 if (PCIE_ASPM(sih)) {
740 if ((u32)getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR)
741 pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
742 else
743 pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
744 }
745
746 /* These need to happen in this order only */
747 pcie_war_polarity(pi);
748
749 pcie_war_serdes(pi);
750
751 pcie_war_aspm_clkreq(pi);
752
753 pcie_clkreq_upd(pi, state);
754
755}
756
757void pcicore_hwup(void *pch)
758{
759 struct pcicore_info *pi = pch;
760
761 if (!pi || !PCIE_PUB(pi->sih))
762 return;
763
764 pcie_war_pci_setup(pi);
765}
766
767void pcicore_up(void *pch, int state)
768{
769 struct pcicore_info *pi = pch;
770
771 if (!pi || !PCIE_PUB(pi->sih))
772 return;
773
774 /* Restore L1 timer for better performance */
775 pcie_extendL1timer(pi, true);
776
777 pcie_clkreq_upd(pi, state);
778}
779
780/* When the device is going to enter D3 state
781 * (or the system is going to enter S3/S4 states)
782 */
783void pcicore_sleep(void *pch)
784{
785 struct pcicore_info *pi = pch;
786 u32 w;
787
788 if (!pi || !PCIE_ASPM(pi->sih))
789 return;
790
791 pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
792 w &= ~PCIE_CAP_LCREG_ASPML1;
793 pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
794
795 pi->pcie_pr42767 = false;
796}
797
798void pcicore_down(void *pch, int state)
799{
800 struct pcicore_info *pi = pch;
801
802 if (!pi || !PCIE_PUB(pi->sih))
803 return;
804
805 pcie_clkreq_upd(pi, state);
806
807 /* Reduce L1 timer for better power savings */
808 pcie_extendL1timer(pi, false);
809}
810
811/* precondition: current core is sii->buscoretype */
812void pcicore_fixcfg(void *pch, void *regs)
813{
814 struct pcicore_info *pi = pch;
815 struct si_info *sii = SI_INFO(pi->sih);
816 struct sbpciregs *pciregs = regs;
817 struct sbpcieregs *pcieregs = regs;
818 u16 val16, *reg16 = NULL;
819 uint pciidx;
820
821 /* check 'pi' is correct and fix it if not */
822 if (sii->pub.buscoretype == PCIE_CORE_ID)
823 reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
824 else if (sii->pub.buscoretype == PCI_CORE_ID)
825 reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
826 pciidx = ai_coreidx(&sii->pub);
827 val16 = R_REG(reg16);
828 if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) {
829 val16 = (u16)(pciidx << SRSH_PI_SHIFT) |
830 (val16 & ~SRSH_PI_MASK);
831 W_REG(reg16, val16);
832 }
833}
834
835/* precondition: current core is pci core */
836void pcicore_pci_setup(void *pch, void *regs)
837{
838 struct pcicore_info *pi = pch;
839 struct sbpciregs *pciregs = regs;
840 u32 w;
841
842 OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST);
843
844 if (SI_INFO(pi->sih)->pub.buscorerev >= 11) {
845 OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
846 w = R_REG(&pciregs->clkrun);
847 W_REG(&pciregs->clkrun, w | PCI_CLKRUN_DSBL);
848 w = R_REG(&pciregs->clkrun);
849 }
850}
diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.h b/drivers/staging/brcm80211/brcmsmac/nicpci.h
new file mode 100644
index 00000000000..f71f842a215
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/nicpci.h
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_NICPCI_H_
18#define _BRCM_NICPCI_H_
19
20#include "types.h"
21
22/* PCI configuration address space size */
23#define PCI_SZPCR 256
24
25/* Brcm PCI configuration registers */
26/* backplane address space accessed by BAR0 */
27#define PCI_BAR0_WIN 0x80
28/* sprom property control */
29#define PCI_SPROM_CONTROL 0x88
30/* mask of PCI and other cores interrupts */
31#define PCI_INT_MASK 0x94
32/* backplane core interrupt mask bits offset */
33#define PCI_SBIM_SHIFT 8
34/* backplane address space accessed by second 4KB of BAR0 */
35#define PCI_BAR0_WIN2 0xac
36/* pci config space gpio input (>=rev3) */
37#define PCI_GPIO_IN 0xb0
38/* pci config space gpio output (>=rev3) */
39#define PCI_GPIO_OUT 0xb4
40/* pci config space gpio output enable (>=rev3) */
41#define PCI_GPIO_OUTEN 0xb8
42
43/* bar0 + 4K accesses external sprom */
44#define PCI_BAR0_SPROM_OFFSET (4 * 1024)
45/* bar0 + 6K accesses pci core registers */
46#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024)
47/*
48 * pci core SB registers are at the end of the
49 * 8KB window, so their address is the "regular"
50 * address plus 4K
51 */
52#define PCI_BAR0_PCISBR_OFFSET (4 * 1024)
53/* bar0 window size Match with corerev 13 */
54#define PCI_BAR0_WINSZ (16 * 1024)
55/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
56/* bar0 + 8K accesses pci/pcie core registers */
57#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)
58/* bar0 + 12K accesses chipc core registers */
59#define PCI_16KB0_CCREGS_OFFSET (12 * 1024)
60
61#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */
62
63/* Sonics to PCI translation types */
64#define SBTOPCI_PREF 0x4 /* prefetch enable */
65#define SBTOPCI_BURST 0x8 /* burst enable */
66#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
67
68/* PCI core index in SROM shadow area */
69#define SRSH_PI_OFFSET 0 /* first word */
70#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
71#define SRSH_PI_SHIFT 12 /* bit 15:12 */
72
73extern void *pcicore_init(struct si_pub *sih, void *pdev, void *regs);
74extern void pcicore_deinit(void *pch);
75extern void pcicore_attach(void *pch, char *pvars, int state);
76extern void pcicore_hwup(void *pch);
77extern void pcicore_up(void *pch, int state);
78extern void pcicore_sleep(void *pch);
79extern void pcicore_down(void *pch, int state);
80extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id,
81 unsigned char *buf, u32 *buflen);
82extern void pcicore_fixcfg(void *pch, void *regs);
83extern void pcicore_pci_setup(void *pch, void *regs);
84
85#endif /* _BRCM_NICPCI_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/otp.c b/drivers/staging/brcm80211/brcmsmac/otp.c
new file mode 100644
index 00000000000..4a70180eba5
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/otp.c
@@ -0,0 +1,545 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/io.h>
18#include <linux/errno.h>
19#include <linux/string.h>
20
21#include <brcm_hw_ids.h>
22#include <chipcommon.h>
23#include "aiutils.h"
24#include "otp.h"
25
26#define OTPS_GUP_MASK 0x00000f00
27#define OTPS_GUP_SHIFT 8
28#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */
29#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */
30#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */
31#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */
32
33/* Fields in otpprog in rev >= 21 */
34#define OTPP_COL_MASK 0x000000ff
35#define OTPP_COL_SHIFT 0
36#define OTPP_ROW_MASK 0x0000ff00
37#define OTPP_ROW_SHIFT 8
38#define OTPP_OC_MASK 0x0f000000
39#define OTPP_OC_SHIFT 24
40#define OTPP_READERR 0x10000000
41#define OTPP_VALUE_MASK 0x20000000
42#define OTPP_VALUE_SHIFT 29
43#define OTPP_START_BUSY 0x80000000
44#define OTPP_READ 0x40000000
45
46/* Opcodes for OTPP_OC field */
47#define OTPPOC_READ 0
48#define OTPPOC_BIT_PROG 1
49#define OTPPOC_VERIFY 3
50#define OTPPOC_INIT 4
51#define OTPPOC_SET 5
52#define OTPPOC_RESET 6
53#define OTPPOC_OCST 7
54#define OTPPOC_ROW_LOCK 8
55#define OTPPOC_PRESCN_TEST 9
56
57#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
58
59#define OTPP_TRIES 10000000 /* # of tries for OTPP */
60
61#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
62
63/* OTP common function type */
64typedef int (*otp_status_t) (void *oh);
65typedef int (*otp_size_t) (void *oh);
66typedef void *(*otp_init_t) (struct si_pub *sih);
67typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
68typedef int (*otp_read_region_t) (struct si_pub *sih, int region, u16 *data,
69 uint *wlen);
70typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
71
72/* OTP function struct */
73struct otp_fn_s {
74 otp_size_t size;
75 otp_read_bit_t read_bit;
76 otp_init_t init;
77 otp_read_region_t read_region;
78 otp_nvread_t nvread;
79 otp_status_t status;
80};
81
82struct otpinfo {
83 uint ccrev; /* chipc revision */
84 struct otp_fn_s *fn; /* OTP functions */
85 struct si_pub *sih; /* Saved sb handle */
86
87 /* IPX OTP section */
88 u16 wsize; /* Size of otp in words */
89 u16 rows; /* Geometry */
90 u16 cols; /* Geometry */
91 u32 status; /* Flag bits (lock/prog/rv).
92 * (Reflected only when OTP is power cycled)
93 */
94 u16 hwbase; /* hardware subregion offset */
95 u16 hwlim; /* hardware subregion boundary */
96 u16 swbase; /* software subregion offset */
97 u16 swlim; /* software subregion boundary */
98 u16 fbase; /* fuse subregion offset */
99 u16 flim; /* fuse subregion boundary */
100 int otpgu_base; /* offset to General Use Region */
101};
102
103static struct otpinfo otpinfo;
104
105/*
106 * IPX OTP Code
107 *
108 * Exported functions:
109 * ipxotp_status()
110 * ipxotp_size()
111 * ipxotp_init()
112 * ipxotp_read_bit()
113 * ipxotp_read_region()
114 * ipxotp_nvread()
115 *
116 */
117
118#define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
119
120/* OTP layout */
121/* CC revs 21, 24 and 27 OTP General Use Region word offset */
122#define REVA4_OTPGU_BASE 12
123
124/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
125#define REVB8_OTPGU_BASE 20
126
127/* CC rev 36 OTP General Use Region word offset */
128#define REV36_OTPGU_BASE 12
129
130/* Subregion word offsets in General Use region */
131#define OTPGU_HSB_OFF 0
132#define OTPGU_SFB_OFF 1
133#define OTPGU_CI_OFF 2
134#define OTPGU_P_OFF 3
135#define OTPGU_SROM_OFF 4
136
137/* Flag bit offsets in General Use region */
138#define OTPGU_HWP_OFF 60
139#define OTPGU_SWP_OFF 61
140#define OTPGU_CIP_OFF 62
141#define OTPGU_FUSEP_OFF 63
142#define OTPGU_CIP_MSK 0x4000
143#define OTPGU_P_MSK 0xf000
144#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
145
146/* OTP Size */
147#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */
148#define OTP_SZ_FU_288 (288/8) /* 288 bits */
149#define OTP_SZ_FU_216 (216/8) /* 216 bits */
150#define OTP_SZ_FU_72 (72/8) /* 72 bits */
151#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
152#define OTP4315_SWREG_SZ 178 /* 178 bytes */
153#define OTP_SZ_FU_144 (144/8) /* 144 bits */
154
155static int ipxotp_status(void *oh)
156{
157 struct otpinfo *oi = (struct otpinfo *) oh;
158 return (int)(oi->status);
159}
160
161/* Return size in bytes */
162static int ipxotp_size(void *oh)
163{
164 struct otpinfo *oi = (struct otpinfo *) oh;
165 return (int)oi->wsize * 2;
166}
167
168static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
169{
170 struct otpinfo *oi;
171
172 oi = (struct otpinfo *) oh;
173
174 return R_REG(&cc->sromotp[wn]);
175}
176
177static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
178{
179 struct otpinfo *oi = (struct otpinfo *) oh;
180 uint k, row, col;
181 u32 otpp, st;
182
183 row = off / oi->cols;
184 col = off % oi->cols;
185
186 otpp = OTPP_START_BUSY |
187 ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
188 ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
189 ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
190 W_REG(&cc->otpprog, otpp);
191
192 for (k = 0;
193 ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
194 && (k < OTPP_TRIES); k++)
195 ;
196 if (k >= OTPP_TRIES) {
197 return 0xffff;
198 }
199 if (st & OTPP_READERR) {
200 return 0xffff;
201 }
202 st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
203
204 return (int)st;
205}
206
207/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
208 * osizew is oi->wsize (OTP size - GU size) in words
209 */
210static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
211{
212 int ret = 0;
213
214 switch (sih->chip) {
215 case BCM43224_CHIP_ID:
216 case BCM43225_CHIP_ID:
217 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
218 break;
219 case BCM4313_CHIP_ID:
220 ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
221 break;
222 default:
223 break; /* Don't know about this chip */
224 }
225
226 return ret;
227}
228
229static void _ipxotp_init(struct otpinfo *oi, chipcregs_t *cc)
230{
231 uint k;
232 u32 otpp, st;
233
234 /* record word offset of General Use Region for various chipcommon revs */
235 if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
236 || oi->sih->ccrev == 27) {
237 oi->otpgu_base = REVA4_OTPGU_BASE;
238 } else if (oi->sih->ccrev == 36) {
239 /* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
240 if (oi->wsize >= 128)
241 oi->otpgu_base = REVB8_OTPGU_BASE;
242 else
243 oi->otpgu_base = REV36_OTPGU_BASE;
244 } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
245 oi->otpgu_base = REVB8_OTPGU_BASE;
246 }
247
248 /* First issue an init command so the status is up to date */
249 otpp =
250 OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
251
252 W_REG(&cc->otpprog, otpp);
253 for (k = 0;
254 ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
255 && (k < OTPP_TRIES); k++)
256 ;
257 if (k >= OTPP_TRIES) {
258 return;
259 }
260
261 /* Read OTP lock bits and subregion programmed indication bits */
262 oi->status = R_REG(&cc->otpstatus);
263
264 if ((oi->sih->chip == BCM43224_CHIP_ID)
265 || (oi->sih->chip == BCM43225_CHIP_ID)) {
266 u32 p_bits;
267 p_bits =
268 (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
269 OTPGU_P_MSK)
270 >> OTPGU_P_SHIFT;
271 oi->status |= (p_bits << OTPS_GUP_SHIFT);
272 }
273
274 /*
275 * h/w region base and fuse region limit are fixed to the top and
276 * the bottom of the general use region. Everything else can be flexible.
277 */
278 oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
279 oi->hwlim = oi->wsize;
280 if (oi->status & OTPS_GUP_HW) {
281 oi->hwlim =
282 ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
283 oi->swbase = oi->hwlim;
284 } else
285 oi->swbase = oi->hwbase;
286
287 /* subtract fuse and checksum from beginning */
288 oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
289
290 if (oi->status & OTPS_GUP_SW) {
291 oi->swlim =
292 ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
293 oi->fbase = oi->swlim;
294 } else
295 oi->fbase = oi->swbase;
296
297 oi->flim = oi->wsize;
298}
299
300static void *ipxotp_init(struct si_pub *sih)
301{
302 uint idx;
303 chipcregs_t *cc;
304 struct otpinfo *oi;
305
306 /* Make sure we're running IPX OTP */
307 if (!OTPTYPE_IPX(sih->ccrev))
308 return NULL;
309
310 /* Make sure OTP is not disabled */
311 if (ai_is_otp_disabled(sih))
312 return NULL;
313
314 /* OTP is always powered */
315 oi = &otpinfo;
316
317 /* Check for otp size */
318 switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
319 case 0:
320 /* Nothing there */
321 return NULL;
322 case 1: /* 32x64 */
323 oi->rows = 32;
324 oi->cols = 64;
325 oi->wsize = 128;
326 break;
327 case 2: /* 64x64 */
328 oi->rows = 64;
329 oi->cols = 64;
330 oi->wsize = 256;
331 break;
332 case 5: /* 96x64 */
333 oi->rows = 96;
334 oi->cols = 64;
335 oi->wsize = 384;
336 break;
337 case 7: /* 16x64 *//* 1024 bits */
338 oi->rows = 16;
339 oi->cols = 64;
340 oi->wsize = 64;
341 break;
342 default:
343 /* Don't know the geometry */
344 return NULL;
345 }
346
347 /* Retrieve OTP region info */
348 idx = ai_coreidx(sih);
349 cc = ai_setcoreidx(sih, SI_CC_IDX);
350
351 _ipxotp_init(oi, cc);
352
353 ai_setcoreidx(sih, idx);
354
355 return (void *)oi;
356}
357
358static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
359{
360 struct otpinfo *oi = (struct otpinfo *) oh;
361 uint idx;
362 chipcregs_t *cc;
363 uint base, i, sz;
364
365 /* Validate region selection */
366 switch (region) {
367 case OTP_HW_RGN:
368 sz = (uint) oi->hwlim - oi->hwbase;
369 if (!(oi->status & OTPS_GUP_HW)) {
370 *wlen = sz;
371 return -ENODATA;
372 }
373 if (*wlen < sz) {
374 *wlen = sz;
375 return -EOVERFLOW;
376 }
377 base = oi->hwbase;
378 break;
379 case OTP_SW_RGN:
380 sz = ((uint) oi->swlim - oi->swbase);
381 if (!(oi->status & OTPS_GUP_SW)) {
382 *wlen = sz;
383 return -ENODATA;
384 }
385 if (*wlen < sz) {
386 *wlen = sz;
387 return -EOVERFLOW;
388 }
389 base = oi->swbase;
390 break;
391 case OTP_CI_RGN:
392 sz = OTPGU_CI_SZ;
393 if (!(oi->status & OTPS_GUP_CI)) {
394 *wlen = sz;
395 return -ENODATA;
396 }
397 if (*wlen < sz) {
398 *wlen = sz;
399 return -EOVERFLOW;
400 }
401 base = oi->otpgu_base + OTPGU_CI_OFF;
402 break;
403 case OTP_FUSE_RGN:
404 sz = (uint) oi->flim - oi->fbase;
405 if (!(oi->status & OTPS_GUP_FUSE)) {
406 *wlen = sz;
407 return -ENODATA;
408 }
409 if (*wlen < sz) {
410 *wlen = sz;
411 return -EOVERFLOW;
412 }
413 base = oi->fbase;
414 break;
415 case OTP_ALL_RGN:
416 sz = ((uint) oi->flim - oi->hwbase);
417 if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
418 *wlen = sz;
419 return -ENODATA;
420 }
421 if (*wlen < sz) {
422 *wlen = sz;
423 return -EOVERFLOW;
424 }
425 base = oi->hwbase;
426 break;
427 default:
428 return -EINVAL;
429 }
430
431 idx = ai_coreidx(oi->sih);
432 cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
433
434 /* Read the data */
435 for (i = 0; i < sz; i++)
436 data[i] = ipxotp_otpr(oh, cc, base + i);
437
438 ai_setcoreidx(oi->sih, idx);
439 *wlen = sz;
440 return 0;
441}
442
443static int ipxotp_nvread(void *oh, char *data, uint *len)
444{
445 return -ENOTSUPP;
446}
447
448static struct otp_fn_s ipxotp_fn = {
449 (otp_size_t) ipxotp_size,
450 (otp_read_bit_t) ipxotp_read_bit,
451
452 (otp_init_t) ipxotp_init,
453 (otp_read_region_t) ipxotp_read_region,
454 (otp_nvread_t) ipxotp_nvread,
455
456 (otp_status_t) ipxotp_status
457};
458
459/*
460 * otp_status()
461 * otp_size()
462 * otp_read_bit()
463 * otp_init()
464 * otp_read_region()
465 * otp_nvread()
466 */
467
468int otp_status(void *oh)
469{
470 struct otpinfo *oi = (struct otpinfo *) oh;
471
472 return oi->fn->status(oh);
473}
474
475int otp_size(void *oh)
476{
477 struct otpinfo *oi = (struct otpinfo *) oh;
478
479 return oi->fn->size(oh);
480}
481
482u16 otp_read_bit(void *oh, uint offset)
483{
484 struct otpinfo *oi = (struct otpinfo *) oh;
485 uint idx = ai_coreidx(oi->sih);
486 chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
487 u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
488 ai_setcoreidx(oi->sih, idx);
489 return readBit;
490}
491
492void *otp_init(struct si_pub *sih)
493{
494 struct otpinfo *oi;
495 void *ret = NULL;
496
497 oi = &otpinfo;
498 memset(oi, 0, sizeof(struct otpinfo));
499
500 oi->ccrev = sih->ccrev;
501
502 if (OTPTYPE_IPX(oi->ccrev))
503 oi->fn = &ipxotp_fn;
504
505 if (oi->fn == NULL) {
506 return NULL;
507 }
508
509 oi->sih = sih;
510
511 ret = (oi->fn->init) (sih);
512
513 return ret;
514}
515
516int
517otp_read_region(struct si_pub *sih, int region, u16 *data,
518 uint *wlen) {
519 void *oh;
520 int err = 0;
521
522 if (ai_is_otp_disabled(sih)) {
523 err = -EPERM;
524 goto out;
525 }
526
527 oh = otp_init(sih);
528 if (oh == NULL) {
529 err = -EBADE;
530 goto out;
531 }
532
533 err = (((struct otpinfo *) oh)->fn->read_region)
534 (oh, region, data, wlen);
535
536 out:
537 return err;
538}
539
540int otp_nvread(void *oh, char *data, uint *len)
541{
542 struct otpinfo *oi = (struct otpinfo *) oh;
543
544 return oi->fn->nvread(oh, data, len);
545}
diff --git a/drivers/staging/brcm80211/brcmsmac/otp.h b/drivers/staging/brcm80211/brcmsmac/otp.h
new file mode 100644
index 00000000000..f6d3a56acf1
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/otp.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_OTP_H_
18#define _BRCM_OTP_H_
19
20#include "types.h"
21
22/* OTP regions */
23#define OTP_HW_RGN 1
24#define OTP_SW_RGN 2
25#define OTP_CI_RGN 4
26#define OTP_FUSE_RGN 8
27#define OTP_ALL_RGN 0xf /* From h/w region to end of OTP including checksum */
28
29/* OTP Size */
30#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */
31
32/* Fixed size subregions sizes in words */
33#define OTPGU_CI_SZ 2
34
35/* OTP usage */
36#define OTP4325_FM_DISABLED_OFFSET 188
37
38/* Exported functions */
39extern int otp_status(void *oh);
40extern int otp_size(void *oh);
41extern u16 otp_read_bit(void *oh, uint offset);
42extern void *otp_init(struct si_pub *sih);
43extern int otp_read_region(struct si_pub *sih, int region, u16 *data,
44 uint *wlen);
45extern int otp_nvread(void *oh, char *data, uint *len);
46
47#endif /* _BRCM_OTP_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c
new file mode 100644
index 00000000000..17012fbe9c9
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c
@@ -0,0 +1,3225 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/delay.h>
18
19#include <brcm_hw_ids.h>
20#include <chipcommon.h>
21#include <aiutils.h>
22#include <d11.h>
23#include <phy_shim.h>
24#include "phy_hal.h"
25#include "phy_int.h"
26#include "phy_radio.h"
27#include "phy_lcn.h"
28#include "phyreg_n.h"
29
30u32 phyhal_msg_level = PHYHAL_ERROR;
31
32struct chan_info_basic {
33 u16 chan;
34 u16 freq;
35};
36
37static struct chan_info_basic chan_info_all[] = {
38 {1, 2412},
39 {2, 2417},
40 {3, 2422},
41 {4, 2427},
42 {5, 2432},
43 {6, 2437},
44 {7, 2442},
45 {8, 2447},
46 {9, 2452},
47 {10, 2457},
48 {11, 2462},
49 {12, 2467},
50 {13, 2472},
51 {14, 2484},
52
53 {34, 5170},
54 {38, 5190},
55 {42, 5210},
56 {46, 5230},
57
58 {36, 5180},
59 {40, 5200},
60 {44, 5220},
61 {48, 5240},
62 {52, 5260},
63 {56, 5280},
64 {60, 5300},
65 {64, 5320},
66
67 {100, 5500},
68 {104, 5520},
69 {108, 5540},
70 {112, 5560},
71 {116, 5580},
72 {120, 5600},
73 {124, 5620},
74 {128, 5640},
75 {132, 5660},
76 {136, 5680},
77 {140, 5700},
78
79 {149, 5745},
80 {153, 5765},
81 {157, 5785},
82 {161, 5805},
83 {165, 5825},
84
85 {184, 4920},
86 {188, 4940},
87 {192, 4960},
88 {196, 4980},
89 {200, 5000},
90 {204, 5020},
91 {208, 5040},
92 {212, 5060},
93 {216, 50800}
94};
95
96u16 ltrn_list[PHY_LTRN_LIST_LEN] = {
97 0x18f9, 0x0d01, 0x00e4, 0xdef4, 0x06f1, 0x0ffc,
98 0xfa27, 0x1dff, 0x10f0, 0x0918, 0xf20a, 0xe010,
99 0x1417, 0x1104, 0xf114, 0xf2fa, 0xf7db, 0xe2fc,
100 0xe1fb, 0x13ee, 0xff0d, 0xe91c, 0x171a, 0x0318,
101 0xda00, 0x03e8, 0x17e6, 0xe9e4, 0xfff3, 0x1312,
102 0xe105, 0xe204, 0xf725, 0xf206, 0xf1ec, 0x11fc,
103 0x14e9, 0xe0f0, 0xf2f6, 0x09e8, 0x1010, 0x1d01,
104 0xfad9, 0x0f04, 0x060f, 0xde0c, 0x001c, 0x0dff,
105 0x1807, 0xf61a, 0xe40e, 0x0f16, 0x05f9, 0x18ec,
106 0x0a1b, 0xff1e, 0x2600, 0xffe2, 0x0ae5, 0x1814,
107 0x0507, 0x0fea, 0xe4f2, 0xf6e6
108};
109
110const u8 ofdm_rate_lookup[] = {
111
112 BRCM_RATE_48M,
113 BRCM_RATE_24M,
114 BRCM_RATE_12M,
115 BRCM_RATE_6M,
116 BRCM_RATE_54M,
117 BRCM_RATE_36M,
118 BRCM_RATE_18M,
119 BRCM_RATE_9M
120};
121
122#define PHY_WREG_LIMIT 24
123
124static void wlc_set_phy_uninitted(struct brcms_phy *pi);
125static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi);
126static void wlc_phy_timercb_phycal(void *arg);
127
128static bool wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr,
129 s8 *pwr_ant);
130
131static void wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi,
132 uint delay);
133
134static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm);
135static void wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason,
136 u8 ch);
137
138static void wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi,
139 struct txpwr_limits *tp, chanspec_t);
140static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi);
141
142static s8 wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan,
143 u32 band, u8 rate);
144static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band);
145static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi);
146static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi);
147
148char *phy_getvar(struct brcms_phy *pi, const char *name)
149{
150 char *vars = pi->vars;
151 char *s;
152 int len;
153
154 if (!name)
155 return NULL;
156
157 len = strlen(name);
158 if (len == 0)
159 return NULL;
160
161 for (s = vars; s && *s;) {
162 if ((memcmp(s, name, len) == 0) && (s[len] == '='))
163 return &s[len + 1];
164
165 while (*s++)
166 ;
167 }
168
169 return NULL;
170}
171
172int phy_getintvar(struct brcms_phy *pi, const char *name)
173{
174 char *val;
175
176 val = PHY_GETVAR(pi, name);
177 if (val == NULL)
178 return 0;
179
180 return simple_strtoul(val, NULL, 0);
181}
182
183void wlc_phyreg_enter(struct brcms_phy_pub *pih)
184{
185 struct brcms_phy *pi = (struct brcms_phy *) pih;
186 wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
187}
188
189void wlc_phyreg_exit(struct brcms_phy_pub *pih)
190{
191 struct brcms_phy *pi = (struct brcms_phy *) pih;
192 wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
193}
194
195void wlc_radioreg_enter(struct brcms_phy_pub *pih)
196{
197 struct brcms_phy *pi = (struct brcms_phy *) pih;
198 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
199
200 udelay(10);
201}
202
203void wlc_radioreg_exit(struct brcms_phy_pub *pih)
204{
205 struct brcms_phy *pi = (struct brcms_phy *) pih;
206 volatile u16 dummy;
207
208 dummy = R_REG(&pi->regs->phyversion);
209 pi->phy_wreg = 0;
210 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
211}
212
213u16 read_radio_reg(struct brcms_phy *pi, u16 addr)
214{
215 u16 data;
216
217 if ((addr == RADIO_IDCODE))
218 return 0xffff;
219
220 if (NORADIO_ENAB(pi->pubpi))
221 return NORADIO_IDCODE & 0xffff;
222
223 switch (pi->pubpi.phy_type) {
224 case PHY_TYPE_N:
225 CASECHECK(PHYTYPE, PHY_TYPE_N);
226 if (NREV_GE(pi->pubpi.phy_rev, 7))
227 addr |= RADIO_2057_READ_OFF;
228 else
229 addr |= RADIO_2055_READ_OFF;
230 break;
231
232 case PHY_TYPE_LCN:
233 CASECHECK(PHYTYPE, PHY_TYPE_LCN);
234 addr |= RADIO_2064_READ_OFF;
235 break;
236
237 default:
238 break;
239 }
240
241 if ((D11REV_GE(pi->sh->corerev, 24)) ||
242 (D11REV_IS(pi->sh->corerev, 22)
243 && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
244 W_REG_FLUSH(&pi->regs->radioregaddr, addr);
245 data = R_REG(&pi->regs->radioregdata);
246 } else {
247 W_REG_FLUSH(&pi->regs->phy4waddr, addr);
248
249#ifdef __ARM_ARCH_4T__
250 __asm__(" .align 4 ");
251 __asm__(" nop ");
252 data = R_REG(&pi->regs->phy4wdatalo);
253#else
254 data = R_REG(&pi->regs->phy4wdatalo);
255#endif
256
257 }
258 pi->phy_wreg = 0;
259
260 return data;
261}
262
263void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
264{
265 if (NORADIO_ENAB(pi->pubpi))
266 return;
267
268 if ((D11REV_GE(pi->sh->corerev, 24)) ||
269 (D11REV_IS(pi->sh->corerev, 22)
270 && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
271
272 W_REG_FLUSH(&pi->regs->radioregaddr, addr);
273 W_REG(&pi->regs->radioregdata, val);
274 } else {
275 W_REG_FLUSH(&pi->regs->phy4waddr, addr);
276 W_REG(&pi->regs->phy4wdatalo, val);
277 }
278
279 if (pi->sh->bustype == PCI_BUS) {
280 if (++pi->phy_wreg >= pi->phy_wreg_limit) {
281 (void)R_REG(&pi->regs->maccontrol);
282 pi->phy_wreg = 0;
283 }
284 }
285}
286
287static u32 read_radio_id(struct brcms_phy *pi)
288{
289 u32 id;
290
291 if (NORADIO_ENAB(pi->pubpi))
292 return NORADIO_IDCODE;
293
294 if (D11REV_GE(pi->sh->corerev, 24)) {
295 u32 b0, b1, b2;
296
297 W_REG_FLUSH(&pi->regs->radioregaddr, 0);
298 b0 = (u32) R_REG(&pi->regs->radioregdata);
299 W_REG_FLUSH(&pi->regs->radioregaddr, 1);
300 b1 = (u32) R_REG(&pi->regs->radioregdata);
301 W_REG_FLUSH(&pi->regs->radioregaddr, 2);
302 b2 = (u32) R_REG(&pi->regs->radioregdata);
303
304 id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
305 & 0xf);
306 } else {
307 W_REG_FLUSH(&pi->regs->phy4waddr, RADIO_IDCODE);
308 id = (u32) R_REG(&pi->regs->phy4wdatalo);
309 id |= (u32) R_REG(&pi->regs->phy4wdatahi) << 16;
310 }
311 pi->phy_wreg = 0;
312 return id;
313}
314
315void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
316{
317 u16 rval;
318
319 if (NORADIO_ENAB(pi->pubpi))
320 return;
321
322 rval = read_radio_reg(pi, addr);
323 write_radio_reg(pi, addr, (rval & val));
324}
325
326void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
327{
328 u16 rval;
329
330 if (NORADIO_ENAB(pi->pubpi))
331 return;
332
333 rval = read_radio_reg(pi, addr);
334 write_radio_reg(pi, addr, (rval | val));
335}
336
337void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask)
338{
339 u16 rval;
340
341 if (NORADIO_ENAB(pi->pubpi))
342 return;
343
344 rval = read_radio_reg(pi, addr);
345 write_radio_reg(pi, addr, (rval ^ mask));
346}
347
348void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
349{
350 u16 rval;
351
352 if (NORADIO_ENAB(pi->pubpi))
353 return;
354
355 rval = read_radio_reg(pi, addr);
356 write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
357}
358
359void write_phy_channel_reg(struct brcms_phy *pi, uint val)
360{
361 W_REG(&pi->regs->phychannel, val);
362}
363
364u16 read_phy_reg(struct brcms_phy *pi, u16 addr)
365{
366 d11regs_t *regs;
367
368 regs = pi->regs;
369
370 W_REG_FLUSH(&regs->phyregaddr, addr);
371
372 pi->phy_wreg = 0;
373 return R_REG(&regs->phyregdata);
374}
375
376void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
377{
378 d11regs_t *regs;
379
380 regs = pi->regs;
381
382#ifdef __mips__
383 W_REG_FLUSH(&regs->phyregaddr, addr);
384 W_REG(&regs->phyregdata, val);
385 if (addr == 0x72)
386 (void)R_REG(&regs->phyregdata);
387#else
388 W_REG((u32 *)(&regs->phyregaddr),
389 addr | (val << 16));
390 if (pi->sh->bustype == PCI_BUS) {
391 if (++pi->phy_wreg >= pi->phy_wreg_limit) {
392 pi->phy_wreg = 0;
393 (void)R_REG(&regs->phyversion);
394 }
395 }
396#endif
397}
398
399void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
400{
401 d11regs_t *regs;
402
403 regs = pi->regs;
404
405 W_REG_FLUSH(&regs->phyregaddr, addr);
406
407 W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) & val));
408 pi->phy_wreg = 0;
409}
410
411void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
412{
413 d11regs_t *regs;
414
415 regs = pi->regs;
416
417 W_REG_FLUSH(&regs->phyregaddr, addr);
418
419 W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) | val));
420 pi->phy_wreg = 0;
421}
422
423void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
424{
425 d11regs_t *regs;
426
427 regs = pi->regs;
428
429 W_REG_FLUSH(&regs->phyregaddr, addr);
430
431 W_REG(&regs->phyregdata,
432 ((R_REG(&regs->phyregdata) & ~mask) | (val & mask)));
433 pi->phy_wreg = 0;
434}
435
436static void wlc_set_phy_uninitted(struct brcms_phy *pi)
437{
438 int i, j;
439
440 pi->initialized = false;
441
442 pi->tx_vos = 0xffff;
443 pi->nrssi_table_delta = 0x7fffffff;
444 pi->rc_cal = 0xffff;
445 pi->mintxbias = 0xffff;
446 pi->txpwridx = -1;
447 if (ISNPHY(pi)) {
448 pi->phy_spuravoid = SPURAVOID_DISABLE;
449
450 if (NREV_GE(pi->pubpi.phy_rev, 3)
451 && NREV_LT(pi->pubpi.phy_rev, 7))
452 pi->phy_spuravoid = SPURAVOID_AUTO;
453
454 pi->nphy_papd_skip = 0;
455 pi->nphy_papd_epsilon_offset[0] = 0xf588;
456 pi->nphy_papd_epsilon_offset[1] = 0xf588;
457 pi->nphy_txpwr_idx[0] = 128;
458 pi->nphy_txpwr_idx[1] = 128;
459 pi->nphy_txpwrindex[0].index_internal = 40;
460 pi->nphy_txpwrindex[1].index_internal = 40;
461 pi->phy_pabias = 0;
462 } else {
463 pi->phy_spuravoid = SPURAVOID_AUTO;
464 }
465 pi->radiopwr = 0xffff;
466 for (i = 0; i < STATIC_NUM_RF; i++) {
467 for (j = 0; j < STATIC_NUM_BB; j++) {
468 pi->stats_11b_txpower[i][j] = -1;
469 }
470 }
471}
472
473struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
474{
475 struct shared_phy *sh;
476
477 sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC);
478 if (sh == NULL) {
479 return NULL;
480 }
481
482 sh->sih = shp->sih;
483 sh->physhim = shp->physhim;
484 sh->unit = shp->unit;
485 sh->corerev = shp->corerev;
486
487 sh->vid = shp->vid;
488 sh->did = shp->did;
489 sh->chip = shp->chip;
490 sh->chiprev = shp->chiprev;
491 sh->chippkg = shp->chippkg;
492 sh->sromrev = shp->sromrev;
493 sh->boardtype = shp->boardtype;
494 sh->boardrev = shp->boardrev;
495 sh->boardvendor = shp->boardvendor;
496 sh->boardflags = shp->boardflags;
497 sh->boardflags2 = shp->boardflags2;
498 sh->bustype = shp->bustype;
499 sh->buscorerev = shp->buscorerev;
500
501 sh->fast_timer = PHY_SW_TIMER_FAST;
502 sh->slow_timer = PHY_SW_TIMER_SLOW;
503 sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
504
505 sh->rssi_mode = RSSI_ANT_MERGE_MAX;
506
507 return sh;
508}
509
510struct brcms_phy_pub *
511wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype,
512 char *vars, struct wiphy *wiphy)
513{
514 struct brcms_phy *pi;
515 u32 sflags = 0;
516 uint phyversion;
517 u32 idcode;
518 int i;
519
520 if (D11REV_IS(sh->corerev, 4))
521 sflags = SISF_2G_PHY | SISF_5G_PHY;
522 else
523 sflags = ai_core_sflags(sh->sih, 0, 0);
524
525 if (BAND_5G(bandtype)) {
526 if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) {
527 return NULL;
528 }
529 }
530
531 pi = sh->phy_head;
532 if ((sflags & SISF_DB_PHY) && pi) {
533
534 wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
535 pi->refcnt++;
536 return &pi->pubpi_ro;
537 }
538
539 pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC);
540 if (pi == NULL) {
541 return NULL;
542 }
543 pi->wiphy = wiphy;
544 pi->regs = (d11regs_t *) regs;
545 pi->sh = sh;
546 pi->phy_init_por = true;
547 pi->phy_wreg_limit = PHY_WREG_LIMIT;
548
549 pi->vars = vars;
550
551 pi->txpwr_percent = 100;
552
553 pi->do_initcal = true;
554
555 pi->phycal_tempdelta = 0;
556
557 if (BAND_2G(bandtype) && (sflags & SISF_2G_PHY)) {
558
559 pi->pubpi.coreflags = SICF_GMODE;
560 }
561
562 wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
563 phyversion = R_REG(&pi->regs->phyversion);
564
565 pi->pubpi.phy_type = PHY_TYPE(phyversion);
566 pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
567
568 if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
569 pi->pubpi.phy_type = PHY_TYPE_N;
570 pi->pubpi.phy_rev += LCNXN_BASEREV;
571 }
572 pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
573 pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
574
575 if (!VALID_PHYTYPE(pi->pubpi.phy_type)) {
576 goto err;
577 }
578 if (BAND_5G(bandtype)) {
579 if (!ISNPHY(pi)) {
580 goto err;
581 }
582 } else {
583 if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
584 goto err;
585 }
586 }
587
588 wlc_phy_anacore((struct brcms_phy_pub *) pi, ON);
589
590 idcode = wlc_phy_get_radio_ver(pi);
591 pi->pubpi.radioid =
592 (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
593 pi->pubpi.radiorev =
594 (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
595 pi->pubpi.radiover =
596 (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
597 if (!VALID_RADIO(pi, pi->pubpi.radioid))
598 goto err;
599
600 wlc_phy_switch_radio((struct brcms_phy_pub *) pi, OFF);
601
602 wlc_set_phy_uninitted(pi);
603
604 pi->bw = WL_CHANSPEC_BW_20;
605 pi->radio_chanspec =
606 BAND_2G(bandtype) ? CH20MHZ_CHSPEC(1) : CH20MHZ_CHSPEC(36);
607
608 pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
609 pi->rxiq_antsel = ANT_RX_DIV_DEF;
610
611 pi->watchdog_override = true;
612
613 pi->cal_type_override = PHY_PERICAL_AUTO;
614
615 pi->nphy_saved_noisevars.bufcount = 0;
616
617 if (ISNPHY(pi))
618 pi->min_txpower = PHY_TXPWR_MIN_NPHY;
619 else
620 pi->min_txpower = PHY_TXPWR_MIN;
621
622 pi->sh->phyrxchain = 0x3;
623
624 pi->rx2tx_biasentry = -1;
625
626 pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
627 pi->phy_txcore_enable_temp =
628 PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
629 pi->phy_tempsense_offset = 0;
630 pi->phy_txcore_heatedup = false;
631
632 pi->nphy_lastcal_temp = -50;
633
634 pi->phynoise_polling = true;
635 if (ISNPHY(pi) || ISLCNPHY(pi))
636 pi->phynoise_polling = false;
637
638 for (i = 0; i < TXP_NUM_RATES; i++) {
639 pi->txpwr_limit[i] = BRCMS_TXPWR_MAX;
640 pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
641 pi->tx_user_target[i] = BRCMS_TXPWR_MAX;
642 }
643
644 pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
645
646 pi->user_txpwr_at_rfport = false;
647
648 if (ISNPHY(pi)) {
649
650 pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
651 wlc_phy_timercb_phycal,
652 pi, "phycal");
653 if (!pi->phycal_timer) {
654 goto err;
655 }
656
657 if (!wlc_phy_attach_nphy(pi))
658 goto err;
659
660 } else if (ISLCNPHY(pi)) {
661 if (!wlc_phy_attach_lcnphy(pi))
662 goto err;
663
664 } else {
665
666 }
667
668 pi->refcnt++;
669 pi->next = pi->sh->phy_head;
670 sh->phy_head = pi;
671
672 pi->vars = (char *)&pi->vars;
673
674 memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(struct brcms_phy_pub));
675
676 return &pi->pubpi_ro;
677
678 err:
679 kfree(pi);
680 return NULL;
681}
682
683void wlc_phy_detach(struct brcms_phy_pub *pih)
684{
685 struct brcms_phy *pi = (struct brcms_phy *) pih;
686
687 if (pih) {
688 if (--pi->refcnt) {
689 return;
690 }
691
692 if (pi->phycal_timer) {
693 wlapi_free_timer(pi->sh->physhim, pi->phycal_timer);
694 pi->phycal_timer = NULL;
695 }
696
697 if (pi->sh->phy_head == pi)
698 pi->sh->phy_head = pi->next;
699 else if (pi->sh->phy_head->next == pi)
700 pi->sh->phy_head->next = NULL;
701
702 if (pi->pi_fptr.detach)
703 (pi->pi_fptr.detach) (pi);
704
705 kfree(pi);
706 }
707}
708
709bool
710wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev,
711 u16 *radioid, u16 *radiover)
712{
713 struct brcms_phy *pi = (struct brcms_phy *) pih;
714 *phytype = (u16) pi->pubpi.phy_type;
715 *phyrev = (u16) pi->pubpi.phy_rev;
716 *radioid = pi->pubpi.radioid;
717 *radiover = pi->pubpi.radiorev;
718
719 return true;
720}
721
722bool wlc_phy_get_encore(struct brcms_phy_pub *pih)
723{
724 struct brcms_phy *pi = (struct brcms_phy *) pih;
725 return pi->pubpi.abgphy_encore;
726}
727
728u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih)
729{
730 struct brcms_phy *pi = (struct brcms_phy *) pih;
731 return pi->pubpi.coreflags;
732}
733
734static void wlc_phy_timercb_phycal(void *arg)
735{
736 struct brcms_phy *pi = (struct brcms_phy *) arg;
737 uint delay = 5;
738
739 if (PHY_PERICAL_MPHASE_PENDING(pi)) {
740 if (!pi->sh->up) {
741 wlc_phy_cal_perical_mphase_reset(pi);
742 return;
743 }
744
745 if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
746
747 delay = 1000;
748 wlc_phy_cal_perical_mphase_restart(pi);
749 } else
750 wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
751 wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
752 return;
753 }
754
755}
756
757void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on)
758{
759 struct brcms_phy *pi = (struct brcms_phy *) pih;
760
761 if (ISNPHY(pi)) {
762 if (on) {
763 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
764 write_phy_reg(pi, 0xa6, 0x0d);
765 write_phy_reg(pi, 0x8f, 0x0);
766 write_phy_reg(pi, 0xa7, 0x0d);
767 write_phy_reg(pi, 0xa5, 0x0);
768 } else {
769 write_phy_reg(pi, 0xa5, 0x0);
770 }
771 } else {
772 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
773 write_phy_reg(pi, 0x8f, 0x07ff);
774 write_phy_reg(pi, 0xa6, 0x0fd);
775 write_phy_reg(pi, 0xa5, 0x07ff);
776 write_phy_reg(pi, 0xa7, 0x0fd);
777 } else {
778 write_phy_reg(pi, 0xa5, 0x7fff);
779 }
780 }
781 } else if (ISLCNPHY(pi)) {
782 if (on) {
783 and_phy_reg(pi, 0x43b,
784 ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
785 } else {
786 or_phy_reg(pi, 0x43c,
787 (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
788 or_phy_reg(pi, 0x43b,
789 (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
790 }
791 }
792}
793
794u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih)
795{
796 struct brcms_phy *pi = (struct brcms_phy *) pih;
797
798 u32 phy_bw_clkbits = 0;
799
800 if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
801 switch (pi->bw) {
802 case WL_CHANSPEC_BW_10:
803 phy_bw_clkbits = SICF_BW10;
804 break;
805 case WL_CHANSPEC_BW_20:
806 phy_bw_clkbits = SICF_BW20;
807 break;
808 case WL_CHANSPEC_BW_40:
809 phy_bw_clkbits = SICF_BW40;
810 break;
811 default:
812 break;
813 }
814 }
815
816 return phy_bw_clkbits;
817}
818
819void wlc_phy_por_inform(struct brcms_phy_pub *ppi)
820{
821 struct brcms_phy *pi = (struct brcms_phy *) ppi;
822
823 pi->phy_init_por = true;
824}
825
826void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock)
827{
828 struct brcms_phy *pi = (struct brcms_phy *) pih;
829
830 pi->edcrs_threshold_lock = lock;
831
832 write_phy_reg(pi, 0x22c, 0x46b);
833 write_phy_reg(pi, 0x22d, 0x46b);
834 write_phy_reg(pi, 0x22e, 0x3c0);
835 write_phy_reg(pi, 0x22f, 0x3c0);
836}
837
838void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal)
839{
840 struct brcms_phy *pi = (struct brcms_phy *) pih;
841
842 pi->do_initcal = initcal;
843}
844
845void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate)
846{
847 struct brcms_phy *pi = (struct brcms_phy *) pih;
848
849 if (!pi || !pi->sh)
850 return;
851
852 pi->sh->clk = newstate;
853}
854
855void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate)
856{
857 struct brcms_phy *pi = (struct brcms_phy *) pih;
858
859 if (!pi || !pi->sh)
860 return;
861
862 pi->sh->up = newstate;
863}
864
865void wlc_phy_init(struct brcms_phy_pub *pih, chanspec_t chanspec)
866{
867 u32 mc;
868 initfn_t phy_init = NULL;
869 struct brcms_phy *pi = (struct brcms_phy *) pih;
870
871 if (pi->init_in_progress)
872 return;
873
874 pi->init_in_progress = true;
875
876 pi->radio_chanspec = chanspec;
877
878 mc = R_REG(&pi->regs->maccontrol);
879 if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
880 return;
881
882 if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
883 pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
884 }
885
886 if (WARN(!(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA),
887 "HW error SISF_FCLKA\n"))
888 return;
889
890 phy_init = pi->pi_fptr.init;
891
892 if (phy_init == NULL) {
893 return;
894 }
895
896 wlc_phy_anacore(pih, ON);
897
898 if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
899 wlapi_bmac_bw_set(pi->sh->physhim,
900 CHSPEC_BW(pi->radio_chanspec));
901
902 pi->nphy_gain_boost = true;
903
904 wlc_phy_switch_radio((struct brcms_phy_pub *) pi, ON);
905
906 (*phy_init) (pi);
907
908 pi->phy_init_por = false;
909
910 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
911 wlc_phy_do_dummy_tx(pi, true, OFF);
912
913 if (!(ISNPHY(pi)))
914 wlc_phy_txpower_update_shm(pi);
915
916 wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, pi->sh->rx_antdiv);
917
918 pi->init_in_progress = false;
919}
920
921void wlc_phy_cal_init(struct brcms_phy_pub *pih)
922{
923 struct brcms_phy *pi = (struct brcms_phy *) pih;
924 initfn_t cal_init = NULL;
925
926 if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0,
927 "HW error: MAC enabled during phy cal\n"))
928 return;
929
930 if (!pi->initialized) {
931 cal_init = pi->pi_fptr.calinit;
932 if (cal_init)
933 (*cal_init) (pi);
934
935 pi->initialized = true;
936 }
937}
938
939int wlc_phy_down(struct brcms_phy_pub *pih)
940{
941 struct brcms_phy *pi = (struct brcms_phy *) pih;
942 int callbacks = 0;
943
944 if (pi->phycal_timer
945 && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer))
946 callbacks++;
947
948 pi->nphy_iqcal_chanspec_2G = 0;
949 pi->nphy_iqcal_chanspec_5G = 0;
950
951 return callbacks;
952}
953
954static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi)
955{
956 u32 ver;
957
958 ver = read_radio_id(pi);
959
960 return ver;
961}
962
963void
964wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset,
965 u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
966{
967 write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
968
969 pi->tbl_data_hi = tblDataHi;
970 pi->tbl_data_lo = tblDataLo;
971
972 if (pi->sh->chip == BCM43224_CHIP_ID &&
973 pi->sh->chiprev == 1) {
974 pi->tbl_addr = tblAddr;
975 pi->tbl_save_id = tbl_id;
976 pi->tbl_save_offset = tbl_offset;
977 }
978}
979
980void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val)
981{
982 if ((pi->sh->chip == BCM43224_CHIP_ID) &&
983 (pi->sh->chiprev == 1) &&
984 (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
985 read_phy_reg(pi, pi->tbl_data_lo);
986
987 write_phy_reg(pi, pi->tbl_addr,
988 (pi->tbl_save_id << 10) | pi->tbl_save_offset);
989 pi->tbl_save_offset++;
990 }
991
992 if (width == 32) {
993
994 write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16));
995 write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
996 } else {
997
998 write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
999 }
1000}
1001
1002void
1003wlc_phy_write_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
1004 u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
1005{
1006 uint idx;
1007 uint tbl_id = ptbl_info->tbl_id;
1008 uint tbl_offset = ptbl_info->tbl_offset;
1009 uint tbl_width = ptbl_info->tbl_width;
1010 const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr;
1011 const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
1012 const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
1013
1014 write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
1015
1016 for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
1017
1018 if ((pi->sh->chip == BCM43224_CHIP_ID) &&
1019 (pi->sh->chiprev == 1) &&
1020 (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
1021 read_phy_reg(pi, tblDataLo);
1022
1023 write_phy_reg(pi, tblAddr,
1024 (tbl_id << 10) | (tbl_offset + idx));
1025 }
1026
1027 if (tbl_width == 32) {
1028
1029 write_phy_reg(pi, tblDataHi,
1030 (u16) (ptbl_32b[idx] >> 16));
1031 write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]);
1032 } else if (tbl_width == 16) {
1033
1034 write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
1035 } else {
1036
1037 write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
1038 }
1039 }
1040}
1041
1042void
1043wlc_phy_read_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
1044 u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
1045{
1046 uint idx;
1047 uint tbl_id = ptbl_info->tbl_id;
1048 uint tbl_offset = ptbl_info->tbl_offset;
1049 uint tbl_width = ptbl_info->tbl_width;
1050 u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr;
1051 u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
1052 u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
1053
1054 write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
1055
1056 for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
1057
1058 if ((pi->sh->chip == BCM43224_CHIP_ID) &&
1059 (pi->sh->chiprev == 1)) {
1060 (void)read_phy_reg(pi, tblDataLo);
1061
1062 write_phy_reg(pi, tblAddr,
1063 (tbl_id << 10) | (tbl_offset + idx));
1064 }
1065
1066 if (tbl_width == 32) {
1067
1068 ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
1069 ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
1070 } else if (tbl_width == 16) {
1071
1072 ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
1073 } else {
1074
1075 ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo);
1076 }
1077 }
1078}
1079
1080uint
1081wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
1082 struct radio_20xx_regs *radioregs)
1083{
1084 uint i = 0;
1085
1086 do {
1087 if (radioregs[i].do_init) {
1088 write_radio_reg(pi, radioregs[i].address,
1089 (u16) radioregs[i].init);
1090 }
1091
1092 i++;
1093 } while (radioregs[i].address != 0xffff);
1094
1095 return i;
1096}
1097
1098uint
1099wlc_phy_init_radio_regs(struct brcms_phy *pi, struct radio_regs *radioregs,
1100 u16 core_offset)
1101{
1102 uint i = 0;
1103 uint count = 0;
1104
1105 do {
1106 if (CHSPEC_IS5G(pi->radio_chanspec)) {
1107 if (radioregs[i].do_init_a) {
1108 write_radio_reg(pi,
1109 radioregs[i].
1110 address | core_offset,
1111 (u16) radioregs[i].init_a);
1112 if (ISNPHY(pi) && (++count % 4 == 0))
1113 BRCMS_PHY_WAR_PR51571(pi);
1114 }
1115 } else {
1116 if (radioregs[i].do_init_g) {
1117 write_radio_reg(pi,
1118 radioregs[i].
1119 address | core_offset,
1120 (u16) radioregs[i].init_g);
1121 if (ISNPHY(pi) && (++count % 4 == 0))
1122 BRCMS_PHY_WAR_PR51571(pi);
1123 }
1124 }
1125
1126 i++;
1127 } while (radioregs[i].address != 0xffff);
1128
1129 return i;
1130}
1131
1132void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
1133{
1134#define DUMMY_PKT_LEN 20
1135 d11regs_t *regs = pi->regs;
1136 int i, count;
1137 u8 ofdmpkt[DUMMY_PKT_LEN] = {
1138 0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
1139 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
1140 };
1141 u8 cckpkt[DUMMY_PKT_LEN] = {
1142 0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
1143 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
1144 };
1145 u32 *dummypkt;
1146
1147 dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
1148 wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
1149 dummypkt);
1150
1151 W_REG(&regs->xmtsel, 0);
1152
1153 if (D11REV_GE(pi->sh->corerev, 11))
1154 W_REG(&regs->wepctl, 0x100);
1155 else
1156 W_REG(&regs->wepctl, 0);
1157
1158 W_REG(&regs->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
1159 if (ISNPHY(pi) || ISLCNPHY(pi)) {
1160 W_REG(&regs->txe_phyctl1, 0x1A02);
1161 }
1162
1163 W_REG(&regs->txe_wm_0, 0);
1164 W_REG(&regs->txe_wm_1, 0);
1165
1166 W_REG(&regs->xmttplatetxptr, 0);
1167 W_REG(&regs->xmttxcnt, DUMMY_PKT_LEN);
1168
1169 W_REG(&regs->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2));
1170
1171 W_REG(&regs->txe_ctl, 0);
1172
1173 if (!pa_on) {
1174 if (ISNPHY(pi))
1175 wlc_phy_pa_override_nphy(pi, OFF);
1176 }
1177
1178 if (ISNPHY(pi) || ISLCNPHY(pi))
1179 W_REG(&regs->txe_aux, 0xD0);
1180 else
1181 W_REG(&regs->txe_aux, ((1 << 5) | (1 << 4)));
1182
1183 (void)R_REG(&regs->txe_aux);
1184
1185 i = 0;
1186 count = ofdm ? 30 : 250;
1187 while ((i++ < count)
1188 && (R_REG(&regs->txe_status) & (1 << 7))) {
1189 udelay(10);
1190 }
1191
1192 i = 0;
1193
1194 while ((i++ < 10)
1195 && ((R_REG(&regs->txe_status) & (1 << 10)) == 0)) {
1196 udelay(10);
1197 }
1198
1199 i = 0;
1200
1201 while ((i++ < 10) && ((R_REG(&regs->ifsstat) & (1 << 8))))
1202 udelay(10);
1203
1204 if (!pa_on) {
1205 if (ISNPHY(pi))
1206 wlc_phy_pa_override_nphy(pi, ON);
1207 }
1208}
1209
1210void wlc_phy_hold_upd(struct brcms_phy_pub *pih, mbool id, bool set)
1211{
1212 struct brcms_phy *pi = (struct brcms_phy *) pih;
1213
1214 if (set) {
1215 mboolset(pi->measure_hold, id);
1216 } else {
1217 mboolclr(pi->measure_hold, id);
1218 }
1219
1220 return;
1221}
1222
1223void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, mbool flags)
1224{
1225 struct brcms_phy *pi = (struct brcms_phy *) pih;
1226
1227 if (mute) {
1228 mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
1229 } else {
1230 mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
1231 }
1232
1233 if (!mute && (flags & PHY_MUTE_FOR_PREISM))
1234 pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
1235 return;
1236}
1237
1238void wlc_phy_clear_tssi(struct brcms_phy_pub *pih)
1239{
1240 struct brcms_phy *pi = (struct brcms_phy *) pih;
1241
1242 if (ISNPHY(pi)) {
1243 return;
1244 } else {
1245 wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
1246 wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
1247 wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
1248 wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
1249 }
1250}
1251
1252static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi)
1253{
1254 return false;
1255}
1256
1257void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
1258{
1259 struct brcms_phy *pi = (struct brcms_phy *) pih;
1260
1261 if (NORADIO_ENAB(pi->pubpi))
1262 return;
1263
1264 {
1265 uint mc;
1266
1267 mc = R_REG(&pi->regs->maccontrol);
1268 }
1269
1270 if (ISNPHY(pi)) {
1271 wlc_phy_switch_radio_nphy(pi, on);
1272
1273 } else if (ISLCNPHY(pi)) {
1274 if (on) {
1275 and_phy_reg(pi, 0x44c,
1276 ~((0x1 << 8) |
1277 (0x1 << 9) |
1278 (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
1279 and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
1280 and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
1281 } else {
1282 and_phy_reg(pi, 0x44d,
1283 ~((0x1 << 10) |
1284 (0x1 << 11) |
1285 (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
1286 or_phy_reg(pi, 0x44c,
1287 (0x1 << 8) |
1288 (0x1 << 9) |
1289 (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
1290
1291 and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
1292 and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
1293 or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
1294 and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
1295 or_phy_reg(pi, 0x4f9, (0x1 << 3));
1296 }
1297 }
1298}
1299
1300u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi)
1301{
1302 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1303
1304 return pi->bw;
1305}
1306
1307void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw)
1308{
1309 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1310
1311 pi->bw = bw;
1312}
1313
1314void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, chanspec_t newch)
1315{
1316 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1317 pi->radio_chanspec = newch;
1318
1319}
1320
1321chanspec_t wlc_phy_chanspec_get(struct brcms_phy_pub *ppi)
1322{
1323 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1324
1325 return pi->radio_chanspec;
1326}
1327
1328void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, chanspec_t chanspec)
1329{
1330 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1331 u16 m_cur_channel;
1332 chansetfn_t chanspec_set = NULL;
1333
1334 m_cur_channel = CHSPEC_CHANNEL(chanspec);
1335 if (CHSPEC_IS5G(chanspec))
1336 m_cur_channel |= D11_CURCHANNEL_5G;
1337 if (CHSPEC_IS40(chanspec))
1338 m_cur_channel |= D11_CURCHANNEL_40;
1339 wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
1340
1341 chanspec_set = pi->pi_fptr.chanset;
1342 if (chanspec_set)
1343 (*chanspec_set) (pi, chanspec);
1344
1345}
1346
1347int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
1348{
1349 int range = -1;
1350
1351 if (freq < 2500)
1352 range = WL_CHAN_FREQ_RANGE_2G;
1353 else if (freq <= 5320)
1354 range = WL_CHAN_FREQ_RANGE_5GL;
1355 else if (freq <= 5700)
1356 range = WL_CHAN_FREQ_RANGE_5GM;
1357 else
1358 range = WL_CHAN_FREQ_RANGE_5GH;
1359
1360 return range;
1361}
1362
1363int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, chanspec_t chanspec)
1364{
1365 int range = -1;
1366 uint channel = CHSPEC_CHANNEL(chanspec);
1367 uint freq = wlc_phy_channel2freq(channel);
1368
1369 if (ISNPHY(pi)) {
1370 range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
1371 } else if (ISLCNPHY(pi)) {
1372 range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
1373 }
1374
1375 return range;
1376}
1377
1378void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
1379 bool wide_filter)
1380{
1381 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1382
1383 pi->channel_14_wide_filter = wide_filter;
1384
1385}
1386
1387int wlc_phy_channel2freq(uint channel)
1388{
1389 uint i;
1390
1391 for (i = 0; i < ARRAY_SIZE(chan_info_all); i++)
1392 if (chan_info_all[i].chan == channel)
1393 return chan_info_all[i].freq;
1394 return 0;
1395}
1396
1397void
1398wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
1399 chanvec_t *channels)
1400{
1401 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1402 uint i;
1403 uint channel;
1404
1405 memset(channels, 0, sizeof(chanvec_t));
1406
1407 for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
1408 channel = chan_info_all[i].chan;
1409
1410 if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
1411 && (channel <= LAST_REF5_CHANNUM))
1412 continue;
1413
1414 if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
1415 (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
1416 setbit(channels->vec, channel);
1417 }
1418}
1419
1420chanspec_t wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band)
1421{
1422 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1423 uint i;
1424 uint channel;
1425 chanspec_t chspec;
1426
1427 for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
1428 channel = chan_info_all[i].chan;
1429
1430 if (ISNPHY(pi) && IS40MHZ(pi)) {
1431 uint j;
1432
1433 for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) {
1434 if (chan_info_all[j].chan ==
1435 channel + CH_10MHZ_APART)
1436 break;
1437 }
1438
1439 if (j == ARRAY_SIZE(chan_info_all))
1440 continue;
1441
1442 channel = UPPER_20_SB(channel);
1443 chspec =
1444 channel | WL_CHANSPEC_BW_40 |
1445 WL_CHANSPEC_CTL_SB_LOWER;
1446 if (band == BRCM_BAND_2G)
1447 chspec |= WL_CHANSPEC_BAND_2G;
1448 else
1449 chspec |= WL_CHANSPEC_BAND_5G;
1450 } else
1451 chspec = CH20MHZ_CHSPEC(channel);
1452
1453 if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
1454 && (channel <= LAST_REF5_CHANNUM))
1455 continue;
1456
1457 if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
1458 (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
1459 return chspec;
1460 }
1461
1462 return (chanspec_t) INVCHANSPEC;
1463}
1464
1465int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override)
1466{
1467 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1468
1469 *qdbm = pi->tx_user_target[0];
1470 if (override != NULL)
1471 *override = pi->txpwroverride;
1472 return 0;
1473}
1474
1475void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
1476 struct txpwr_limits *txpwr)
1477{
1478 bool mac_enabled = false;
1479 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1480
1481 memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
1482 &txpwr->cck[0], BRCMS_NUM_RATES_CCK);
1483
1484 memcpy(&pi->tx_user_target[TXP_FIRST_OFDM],
1485 &txpwr->ofdm[0], BRCMS_NUM_RATES_OFDM);
1486 memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
1487 &txpwr->ofdm_cdd[0], BRCMS_NUM_RATES_OFDM);
1488
1489 memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO],
1490 &txpwr->ofdm_40_siso[0], BRCMS_NUM_RATES_OFDM);
1491 memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD],
1492 &txpwr->ofdm_40_cdd[0], BRCMS_NUM_RATES_OFDM);
1493
1494 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
1495 &txpwr->mcs_20_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1496 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
1497 &txpwr->mcs_20_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1498 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
1499 &txpwr->mcs_20_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1500 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
1501 &txpwr->mcs_20_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
1502
1503 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
1504 &txpwr->mcs_40_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1505 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
1506 &txpwr->mcs_40_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1507 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
1508 &txpwr->mcs_40_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
1509 memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
1510 &txpwr->mcs_40_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
1511
1512 if (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)
1513 mac_enabled = true;
1514
1515 if (mac_enabled)
1516 wlapi_suspend_mac_and_wait(pi->sh->physhim);
1517
1518 wlc_phy_txpower_recalc_target(pi);
1519 wlc_phy_cal_txpower_recalc_sw(pi);
1520
1521 if (mac_enabled)
1522 wlapi_enable_mac(pi->sh->physhim);
1523}
1524
1525int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override)
1526{
1527 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1528 int i;
1529
1530 if (qdbm > 127)
1531 return 5;
1532
1533 for (i = 0; i < TXP_NUM_RATES; i++)
1534 pi->tx_user_target[i] = (u8) qdbm;
1535
1536 pi->txpwroverride = false;
1537
1538 if (pi->sh->up) {
1539 if (!SCAN_INPROG_PHY(pi)) {
1540 bool suspend;
1541
1542 suspend =
1543 (0 ==
1544 (R_REG(&pi->regs->maccontrol) &
1545 MCTL_EN_MAC));
1546
1547 if (!suspend)
1548 wlapi_suspend_mac_and_wait(pi->sh->physhim);
1549
1550 wlc_phy_txpower_recalc_target(pi);
1551 wlc_phy_cal_txpower_recalc_sw(pi);
1552
1553 if (!suspend)
1554 wlapi_enable_mac(pi->sh->physhim);
1555 }
1556 }
1557 return 0;
1558}
1559
1560void
1561wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr,
1562 u8 *max_pwr, int txp_rate_idx)
1563{
1564 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1565 uint i;
1566
1567 *min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR;
1568
1569 if (ISNPHY(pi)) {
1570 if (txp_rate_idx < 0)
1571 txp_rate_idx = TXP_FIRST_CCK;
1572 wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
1573 (u8) txp_rate_idx);
1574
1575 } else if ((channel <= CH_MAX_2G_CHANNEL)) {
1576 if (txp_rate_idx < 0)
1577 txp_rate_idx = TXP_FIRST_CCK;
1578 *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
1579 } else {
1580
1581 *max_pwr = BRCMS_TXPWR_MAX;
1582
1583 if (txp_rate_idx < 0)
1584 txp_rate_idx = TXP_FIRST_OFDM;
1585
1586 for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
1587 if (channel == chan_info_all[i].chan) {
1588 break;
1589 }
1590 }
1591
1592 if (pi->hwtxpwr) {
1593 *max_pwr = pi->hwtxpwr[i];
1594 } else {
1595
1596 if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
1597 *max_pwr =
1598 pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
1599 if ((i >= FIRST_HIGH_5G_CHAN)
1600 && (i <= LAST_HIGH_5G_CHAN))
1601 *max_pwr =
1602 pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
1603 if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
1604 *max_pwr =
1605 pi->tx_srom_max_rate_5g_low[txp_rate_idx];
1606 }
1607 }
1608}
1609
1610void
1611wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan,
1612 u8 *max_txpwr, u8 *min_txpwr)
1613{
1614 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1615 u8 tx_pwr_max = 0;
1616 u8 tx_pwr_min = 255;
1617 u8 max_num_rate;
1618 u8 maxtxpwr, mintxpwr, rate, pactrl;
1619
1620 pactrl = 0;
1621
1622 max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
1623 ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1);
1624
1625 for (rate = 0; rate < max_num_rate; rate++) {
1626
1627 wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
1628 rate);
1629
1630 maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
1631
1632 maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
1633
1634 tx_pwr_max = max(tx_pwr_max, maxtxpwr);
1635 tx_pwr_min = min(tx_pwr_min, maxtxpwr);
1636 }
1637 *max_txpwr = tx_pwr_max;
1638 *min_txpwr = tx_pwr_min;
1639}
1640
1641void
1642wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit,
1643 s32 *max_pwr, s32 *min_pwr, u32 *step_pwr)
1644{
1645 return;
1646}
1647
1648u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi)
1649{
1650 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1651
1652 return pi->tx_power_min;
1653}
1654
1655u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi)
1656{
1657 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1658
1659 return pi->tx_power_max;
1660}
1661
1662void wlc_phy_txpower_recalc_target(struct brcms_phy *pi)
1663{
1664 u8 maxtxpwr, mintxpwr, rate, pactrl;
1665 uint target_chan;
1666 u8 tx_pwr_target[TXP_NUM_RATES];
1667 u8 tx_pwr_max = 0;
1668 u8 tx_pwr_min = 255;
1669 u8 tx_pwr_max_rate_ind = 0;
1670 u8 max_num_rate;
1671 u8 start_rate = 0;
1672 chanspec_t chspec;
1673 u32 band = CHSPEC2BAND(pi->radio_chanspec);
1674 initfn_t txpwr_recalc_fn = NULL;
1675
1676 chspec = pi->radio_chanspec;
1677 if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
1678 target_chan = CHSPEC_CHANNEL(chspec);
1679 else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
1680 target_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
1681 else
1682 target_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
1683
1684 pactrl = 0;
1685 if (ISLCNPHY(pi)) {
1686 u32 offset_mcs, i;
1687
1688 if (CHSPEC_IS40(pi->radio_chanspec)) {
1689 offset_mcs = pi->mcs40_po;
1690 for (i = TXP_FIRST_SISO_MCS_20;
1691 i <= TXP_LAST_SISO_MCS_20; i++) {
1692 pi->tx_srom_max_rate_2g[i - 8] =
1693 pi->tx_srom_max_2g -
1694 ((offset_mcs & 0xf) * 2);
1695 offset_mcs >>= 4;
1696 }
1697 } else {
1698 offset_mcs = pi->mcs20_po;
1699 for (i = TXP_FIRST_SISO_MCS_20;
1700 i <= TXP_LAST_SISO_MCS_20; i++) {
1701 pi->tx_srom_max_rate_2g[i - 8] =
1702 pi->tx_srom_max_2g -
1703 ((offset_mcs & 0xf) * 2);
1704 offset_mcs >>= 4;
1705 }
1706 }
1707 }
1708#if WL11N
1709 max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
1710 ((ISLCNPHY(pi)) ?
1711 (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
1712#else
1713 max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : (TXP_LAST_OFDM + 1));
1714#endif
1715
1716 wlc_phy_upd_env_txpwr_rate_limits(pi, band);
1717
1718 for (rate = start_rate; rate < max_num_rate; rate++) {
1719
1720 tx_pwr_target[rate] = pi->tx_user_target[rate];
1721
1722 if (pi->user_txpwr_at_rfport) {
1723 tx_pwr_target[rate] +=
1724 wlc_user_txpwr_antport_to_rfport(pi, target_chan,
1725 band, rate);
1726 }
1727
1728 {
1729
1730 wlc_phy_txpower_sromlimit((struct brcms_phy_pub *) pi,
1731 target_chan,
1732 &mintxpwr, &maxtxpwr, rate);
1733
1734 maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]);
1735
1736 maxtxpwr =
1737 (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
1738
1739 maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
1740
1741 maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]);
1742
1743 if (pi->txpwr_percent <= 100)
1744 maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
1745
1746 tx_pwr_target[rate] = max(maxtxpwr, mintxpwr);
1747 }
1748
1749 tx_pwr_target[rate] =
1750 min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
1751
1752 if (tx_pwr_target[rate] > tx_pwr_max)
1753 tx_pwr_max_rate_ind = rate;
1754
1755 tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]);
1756 tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]);
1757 }
1758
1759 memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset));
1760 pi->tx_power_max = tx_pwr_max;
1761 pi->tx_power_min = tx_pwr_min;
1762 pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
1763 for (rate = 0; rate < max_num_rate; rate++) {
1764
1765 pi->tx_power_target[rate] = tx_pwr_target[rate];
1766
1767 if (!pi->hwpwrctrl || ISNPHY(pi)) {
1768 pi->tx_power_offset[rate] =
1769 pi->tx_power_max - pi->tx_power_target[rate];
1770 } else {
1771 pi->tx_power_offset[rate] =
1772 pi->tx_power_target[rate] - pi->tx_power_min;
1773 }
1774 }
1775
1776 txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
1777 if (txpwr_recalc_fn)
1778 (*txpwr_recalc_fn) (pi);
1779}
1780
1781void
1782wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr,
1783 chanspec_t chanspec)
1784{
1785 u8 tmp_txpwr_limit[2 * BRCMS_NUM_RATES_OFDM];
1786 u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
1787 int rate_start_index = 0, rate1, rate2, k;
1788
1789 for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
1790 rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
1791 pi->txpwr_limit[rate1] = txpwr->cck[rate2];
1792
1793 for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
1794 rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
1795 pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
1796
1797 if (ISNPHY(pi)) {
1798
1799 for (k = 0; k < 4; k++) {
1800 switch (k) {
1801 case 0:
1802
1803 txpwr_ptr1 = txpwr->mcs_20_siso;
1804 txpwr_ptr2 = txpwr->ofdm;
1805 rate_start_index = WL_TX_POWER_OFDM_FIRST;
1806 break;
1807 case 1:
1808
1809 txpwr_ptr1 = txpwr->mcs_20_cdd;
1810 txpwr_ptr2 = txpwr->ofdm_cdd;
1811 rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
1812 break;
1813 case 2:
1814
1815 txpwr_ptr1 = txpwr->mcs_40_siso;
1816 txpwr_ptr2 = txpwr->ofdm_40_siso;
1817 rate_start_index =
1818 WL_TX_POWER_OFDM40_SISO_FIRST;
1819 break;
1820 case 3:
1821
1822 txpwr_ptr1 = txpwr->mcs_40_cdd;
1823 txpwr_ptr2 = txpwr->ofdm_40_cdd;
1824 rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
1825 break;
1826 }
1827
1828 for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; rate2++) {
1829 tmp_txpwr_limit[rate2] = 0;
1830 tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
1831 txpwr_ptr1[rate2];
1832 }
1833 wlc_phy_mcs_to_ofdm_powers_nphy(tmp_txpwr_limit, 0,
1834 BRCMS_NUM_RATES_OFDM - 1, BRCMS_NUM_RATES_OFDM);
1835 for (rate1 = rate_start_index, rate2 = 0;
1836 rate2 < BRCMS_NUM_RATES_OFDM; rate1++, rate2++)
1837 pi->txpwr_limit[rate1] =
1838 min(txpwr_ptr2[rate2],
1839 tmp_txpwr_limit[rate2]);
1840 }
1841
1842 for (k = 0; k < 4; k++) {
1843 switch (k) {
1844 case 0:
1845
1846 txpwr_ptr1 = txpwr->ofdm;
1847 txpwr_ptr2 = txpwr->mcs_20_siso;
1848 rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
1849 break;
1850 case 1:
1851
1852 txpwr_ptr1 = txpwr->ofdm_cdd;
1853 txpwr_ptr2 = txpwr->mcs_20_cdd;
1854 rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
1855 break;
1856 case 2:
1857
1858 txpwr_ptr1 = txpwr->ofdm_40_siso;
1859 txpwr_ptr2 = txpwr->mcs_40_siso;
1860 rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
1861 break;
1862 case 3:
1863
1864 txpwr_ptr1 = txpwr->ofdm_40_cdd;
1865 txpwr_ptr2 = txpwr->mcs_40_cdd;
1866 rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
1867 break;
1868 }
1869 for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; rate2++) {
1870 tmp_txpwr_limit[rate2] = 0;
1871 tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
1872 txpwr_ptr1[rate2];
1873 }
1874 wlc_phy_ofdm_to_mcs_powers_nphy(tmp_txpwr_limit, 0,
1875 BRCMS_NUM_RATES_OFDM - 1, BRCMS_NUM_RATES_OFDM);
1876 for (rate1 = rate_start_index, rate2 = 0;
1877 rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
1878 rate1++, rate2++)
1879 pi->txpwr_limit[rate1] =
1880 min(txpwr_ptr2[rate2],
1881 tmp_txpwr_limit[rate2]);
1882 }
1883
1884 for (k = 0; k < 2; k++) {
1885 switch (k) {
1886 case 0:
1887
1888 rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
1889 txpwr_ptr1 = txpwr->mcs_20_stbc;
1890 break;
1891 case 1:
1892
1893 rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
1894 txpwr_ptr1 = txpwr->mcs_40_stbc;
1895 break;
1896 }
1897 for (rate1 = rate_start_index, rate2 = 0;
1898 rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
1899 rate1++, rate2++)
1900 pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
1901 }
1902
1903 for (k = 0; k < 2; k++) {
1904 switch (k) {
1905 case 0:
1906
1907 rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
1908 txpwr_ptr1 = txpwr->mcs_20_mimo;
1909 break;
1910 case 1:
1911
1912 rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
1913 txpwr_ptr1 = txpwr->mcs_40_mimo;
1914 break;
1915 }
1916 for (rate1 = rate_start_index, rate2 = 0;
1917 rate2 < BRCMS_NUM_RATES_MCS_2_STREAM;
1918 rate1++, rate2++)
1919 pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
1920 }
1921
1922 pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
1923
1924 pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
1925 min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
1926 pi->txpwr_limit[WL_TX_POWER_MCS_32]);
1927 pi->txpwr_limit[WL_TX_POWER_MCS_32] =
1928 pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
1929 }
1930}
1931
1932void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent)
1933{
1934 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1935
1936 pi->txpwr_percent = txpwr_percent;
1937}
1938
1939void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap)
1940{
1941 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1942
1943 pi->sh->machwcap = machwcap;
1944}
1945
1946void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end)
1947{
1948 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1949 u16 rxc;
1950 rxc = 0;
1951
1952 if (start_end == ON) {
1953 if (!ISNPHY(pi))
1954 return;
1955
1956 if (NREV_IS(pi->pubpi.phy_rev, 3)
1957 || NREV_IS(pi->pubpi.phy_rev, 4)) {
1958 W_REG(&pi->regs->phyregaddr, 0xa0);
1959 (void)R_REG(&pi->regs->phyregaddr);
1960 rxc = R_REG(&pi->regs->phyregdata);
1961 W_REG(&pi->regs->phyregdata,
1962 (0x1 << 15) | rxc);
1963 }
1964 } else {
1965 if (NREV_IS(pi->pubpi.phy_rev, 3)
1966 || NREV_IS(pi->pubpi.phy_rev, 4)) {
1967 W_REG(&pi->regs->phyregaddr, 0xa0);
1968 (void)R_REG(&pi->regs->phyregaddr);
1969 W_REG(&pi->regs->phyregdata, rxc);
1970 }
1971
1972 wlc_phy_por_inform(ppi);
1973 }
1974}
1975
1976void
1977wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr,
1978 chanspec_t chanspec)
1979{
1980 struct brcms_phy *pi = (struct brcms_phy *) ppi;
1981
1982 wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
1983
1984 if (ISLCNPHY(pi)) {
1985 int i, j;
1986 for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
1987 j < BRCMS_NUM_RATES_MCS_1_STREAM; i++, j++) {
1988 if (txpwr->mcs_20_siso[j])
1989 pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
1990 else
1991 pi->txpwr_limit[i] = txpwr->ofdm[j];
1992 }
1993 }
1994
1995 wlapi_suspend_mac_and_wait(pi->sh->physhim);
1996
1997 wlc_phy_txpower_recalc_target(pi);
1998 wlc_phy_cal_txpower_recalc_sw(pi);
1999 wlapi_enable_mac(pi->sh->physhim);
2000}
2001
2002void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war)
2003{
2004 struct brcms_phy *pi = (struct brcms_phy *) pih;
2005
2006 pi->ofdm_rateset_war = war;
2007}
2008
2009void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt)
2010{
2011 struct brcms_phy *pi = (struct brcms_phy *) pih;
2012
2013 pi->bf_preempt_4306 = bf_preempt;
2014}
2015
2016void wlc_phy_txpower_update_shm(struct brcms_phy *pi)
2017{
2018 int j;
2019 if (ISNPHY(pi)) {
2020 return;
2021 }
2022
2023 if (!pi->sh->clk)
2024 return;
2025
2026 if (pi->hwpwrctrl) {
2027 u16 offset;
2028
2029 wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
2030 wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
2031 1 << NUM_TSSI_FRAMES);
2032
2033 wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
2034 pi->tx_power_min << NUM_TSSI_FRAMES);
2035
2036 wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
2037 pi->hwpwr_txcur);
2038
2039 for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
2040 const u8 ucode_ofdm_rates[] = {
2041 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
2042 };
2043 offset = wlapi_bmac_rate_shm_offset(pi->sh->physhim,
2044 ucode_ofdm_rates[j -
2045 TXP_FIRST_OFDM]);
2046 wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
2047 pi->tx_power_offset[j]);
2048 wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
2049 -(pi->tx_power_offset[j] / 2));
2050 }
2051
2052 wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
2053 MHF2_HWPWRCTL, BRCM_BAND_ALL);
2054 } else {
2055 int i;
2056
2057 for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
2058 pi->tx_power_offset[i] =
2059 (u8) roundup(pi->tx_power_offset[i], 8);
2060 wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
2061 (u16) ((pi->
2062 tx_power_offset[TXP_FIRST_OFDM]
2063 + 7) >> 3));
2064 }
2065}
2066
2067bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi)
2068{
2069 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2070
2071 if (ISNPHY(pi)) {
2072 return pi->nphy_txpwrctrl;
2073 } else {
2074 return pi->hwpwrctrl;
2075 }
2076}
2077
2078void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl)
2079{
2080 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2081 bool cur_hwpwrctrl = pi->hwpwrctrl;
2082 bool suspend;
2083
2084 if (!pi->hwpwrctrl_capable) {
2085 return;
2086 }
2087
2088 pi->hwpwrctrl = hwpwrctrl;
2089 pi->nphy_txpwrctrl = hwpwrctrl;
2090 pi->txpwrctrl = hwpwrctrl;
2091
2092 if (ISNPHY(pi)) {
2093 suspend =
2094 (0 ==
2095 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
2096 if (!suspend)
2097 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2098
2099 wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
2100 if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
2101 wlc_phy_txpwr_fixpower_nphy(pi);
2102 } else {
2103
2104 mod_phy_reg(pi, 0x1e7, (0x7f << 0),
2105 pi->saved_txpwr_idx);
2106 }
2107
2108 if (!suspend)
2109 wlapi_enable_mac(pi->sh->physhim);
2110 } else if (hwpwrctrl != cur_hwpwrctrl) {
2111
2112 return;
2113 }
2114}
2115
2116void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi)
2117{
2118
2119 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
2120 pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
2121 pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
2122 } else {
2123 pi->ipa2g_on = false;
2124 pi->ipa5g_on = false;
2125 }
2126}
2127
2128static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi);
2129
2130static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi)
2131{
2132 s16 tx0_status, tx1_status;
2133 u16 estPower1, estPower2;
2134 u8 pwr0, pwr1, adj_pwr0, adj_pwr1;
2135 u32 est_pwr;
2136
2137 estPower1 = read_phy_reg(pi, 0x118);
2138 estPower2 = read_phy_reg(pi, 0x119);
2139
2140 if ((estPower1 & (0x1 << 8))
2141 == (0x1 << 8)) {
2142 pwr0 = (u8) (estPower1 & (0xff << 0))
2143 >> 0;
2144 } else {
2145 pwr0 = 0x80;
2146 }
2147
2148 if ((estPower2 & (0x1 << 8))
2149 == (0x1 << 8)) {
2150 pwr1 = (u8) (estPower2 & (0xff << 0))
2151 >> 0;
2152 } else {
2153 pwr1 = 0x80;
2154 }
2155
2156 tx0_status = read_phy_reg(pi, 0x1ed);
2157 tx1_status = read_phy_reg(pi, 0x1ee);
2158
2159 if ((tx0_status & (0x1 << 15))
2160 == (0x1 << 15)) {
2161 adj_pwr0 = (u8) (tx0_status & (0xff << 0))
2162 >> 0;
2163 } else {
2164 adj_pwr0 = 0x80;
2165 }
2166 if ((tx1_status & (0x1 << 15))
2167 == (0x1 << 15)) {
2168 adj_pwr1 = (u8) (tx1_status & (0xff << 0))
2169 >> 0;
2170 } else {
2171 adj_pwr1 = 0x80;
2172 }
2173
2174 est_pwr =
2175 (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) | adj_pwr1);
2176 return est_pwr;
2177}
2178
2179void
2180wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power,
2181 uint channel)
2182{
2183 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2184 uint rate, num_rates;
2185 u8 min_pwr, max_pwr;
2186
2187#if WL_TX_POWER_RATES != TXP_NUM_RATES
2188#error "struct tx_power out of sync with this fn"
2189#endif
2190
2191 if (ISNPHY(pi)) {
2192 power->rf_cores = 2;
2193 power->flags |= (WL_TX_POWER_F_MIMO);
2194 if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
2195 power->flags |=
2196 (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
2197 } else if (ISLCNPHY(pi)) {
2198 power->rf_cores = 1;
2199 power->flags |= (WL_TX_POWER_F_SISO);
2200 if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
2201 power->flags |= WL_TX_POWER_F_ENABLED;
2202 if (pi->hwpwrctrl)
2203 power->flags |= WL_TX_POWER_F_HW;
2204 }
2205
2206 num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
2207 ((ISLCNPHY(pi)) ?
2208 (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
2209
2210 for (rate = 0; rate < num_rates; rate++) {
2211 power->user_limit[rate] = pi->tx_user_target[rate];
2212 wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
2213 rate);
2214 power->board_limit[rate] = (u8) max_pwr;
2215 power->target[rate] = pi->tx_power_target[rate];
2216 }
2217
2218 if (ISNPHY(pi)) {
2219 u32 est_pout;
2220
2221 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2222 wlc_phyreg_enter((struct brcms_phy_pub *) pi);
2223 est_pout = wlc_phy_txpower_est_power_nphy(pi);
2224 wlc_phyreg_exit((struct brcms_phy_pub *) pi);
2225 wlapi_enable_mac(pi->sh->physhim);
2226
2227 power->est_Pout[0] = (est_pout >> 8) & 0xff;
2228 power->est_Pout[1] = est_pout & 0xff;
2229
2230 power->est_Pout_act[0] = est_pout >> 24;
2231 power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
2232
2233 if (power->est_Pout[0] == 0x80)
2234 power->est_Pout[0] = 0;
2235 if (power->est_Pout[1] == 0x80)
2236 power->est_Pout[1] = 0;
2237
2238 if (power->est_Pout_act[0] == 0x80)
2239 power->est_Pout_act[0] = 0;
2240 if (power->est_Pout_act[1] == 0x80)
2241 power->est_Pout_act[1] = 0;
2242
2243 power->est_Pout_cck = 0;
2244
2245 power->tx_power_max[0] = pi->tx_power_max;
2246 power->tx_power_max[1] = pi->tx_power_max;
2247
2248 power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
2249 power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
2250 } else if (pi->hwpwrctrl && pi->sh->up) {
2251
2252 wlc_phyreg_enter(ppi);
2253 if (ISLCNPHY(pi)) {
2254
2255 power->tx_power_max[0] = pi->tx_power_max;
2256 power->tx_power_max[1] = pi->tx_power_max;
2257
2258 power->tx_power_max_rate_ind[0] =
2259 pi->tx_power_max_rate_ind;
2260 power->tx_power_max_rate_ind[1] =
2261 pi->tx_power_max_rate_ind;
2262
2263 if (wlc_phy_tpc_isenabled_lcnphy(pi))
2264 power->flags |=
2265 (WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED);
2266 else
2267 power->flags &=
2268 ~(WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED);
2269
2270 wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0],
2271 (s8 *) &power->est_Pout_cck);
2272 }
2273 wlc_phyreg_exit(ppi);
2274 }
2275}
2276
2277void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type)
2278{
2279 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2280
2281 pi->antsel_type = antsel_type;
2282}
2283
2284bool wlc_phy_test_ison(struct brcms_phy_pub *ppi)
2285{
2286 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2287
2288 return pi->phytest_on;
2289}
2290
2291void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val)
2292{
2293 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2294 bool suspend;
2295
2296 pi->sh->rx_antdiv = val;
2297
2298 if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
2299 if (val > ANT_RX_DIV_FORCE_1)
2300 wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
2301 MHF1_ANTDIV, BRCM_BAND_ALL);
2302 else
2303 wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
2304 BRCM_BAND_ALL);
2305 }
2306
2307 if (ISNPHY(pi)) {
2308
2309 return;
2310 }
2311
2312 if (!pi->sh->clk)
2313 return;
2314
2315 suspend =
2316 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
2317 if (!suspend)
2318 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2319
2320 if (ISLCNPHY(pi)) {
2321 if (val > ANT_RX_DIV_FORCE_1) {
2322 mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
2323 mod_phy_reg(pi, 0x410,
2324 (0x1 << 0),
2325 ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
2326 } else {
2327 mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
2328 mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
2329 }
2330 }
2331
2332 if (!suspend)
2333 wlapi_enable_mac(pi->sh->physhim);
2334
2335 return;
2336}
2337
2338static bool
2339wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant)
2340{
2341 s8 cmplx_pwr_dbm[PHY_CORE_MAX];
2342 u8 i;
2343
2344 memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
2345 wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
2346
2347 for (i = 0; i < pi->pubpi.phy_corenum; i++) {
2348 if (NREV_GE(pi->pubpi.phy_rev, 3))
2349 cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322;
2350 else
2351
2352 cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70);
2353 }
2354
2355 for (i = 0; i < pi->pubpi.phy_corenum; i++) {
2356 pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
2357 pwr_ant[i] = cmplx_pwr_dbm[i];
2358 }
2359 pi->nphy_noise_index =
2360 MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
2361 return true;
2362}
2363
2364static void
2365wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
2366{
2367 struct brcms_phy *pi = (struct brcms_phy *) pih;
2368 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2369 bool sampling_in_progress = (pi->phynoise_state != 0);
2370 bool wait_for_intr = true;
2371
2372 if (NORADIO_ENAB(pi->pubpi)) {
2373 return;
2374 }
2375
2376 switch (reason) {
2377 case PHY_NOISE_SAMPLE_MON:
2378
2379 pi->phynoise_chan_watchdog = ch;
2380 pi->phynoise_state |= PHY_NOISE_STATE_MON;
2381
2382 break;
2383
2384 case PHY_NOISE_SAMPLE_EXTERNAL:
2385
2386 pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
2387 break;
2388
2389 default:
2390 break;
2391 }
2392
2393 if (sampling_in_progress)
2394 return;
2395
2396 pi->phynoise_now = pi->sh->now;
2397
2398 if (pi->phy_fixed_noise) {
2399 if (ISNPHY(pi)) {
2400 pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
2401 PHY_NOISE_FIXED_VAL_NPHY;
2402 pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
2403 PHY_NOISE_FIXED_VAL_NPHY;
2404 pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
2405 PHY_NOISE_WINDOW_SZ);
2406
2407 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2408 } else {
2409
2410 noise_dbm = PHY_NOISE_FIXED_VAL;
2411 }
2412
2413 wait_for_intr = false;
2414 goto done;
2415 }
2416
2417 if (ISLCNPHY(pi)) {
2418 if (!pi->phynoise_polling
2419 || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
2420 wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
2421 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
2422 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
2423 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
2424 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
2425
2426 OR_REG(&pi->regs->maccommand,
2427 MCMD_BG_NOISE);
2428 } else {
2429 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2430 wlc_lcnphy_deaf_mode(pi, (bool) 0);
2431 noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20);
2432 wlc_lcnphy_deaf_mode(pi, (bool) 1);
2433 wlapi_enable_mac(pi->sh->physhim);
2434 wait_for_intr = false;
2435 }
2436 } else if (ISNPHY(pi)) {
2437 if (!pi->phynoise_polling
2438 || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
2439
2440 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
2441 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
2442 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
2443 wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
2444
2445 OR_REG(&pi->regs->maccommand,
2446 MCMD_BG_NOISE);
2447 } else {
2448 struct phy_iq_est est[PHY_CORE_MAX];
2449 u32 cmplx_pwr[PHY_CORE_MAX];
2450 s8 noise_dbm_ant[PHY_CORE_MAX];
2451 u16 log_num_samps, num_samps, classif_state = 0;
2452 u8 wait_time = 32;
2453 u8 wait_crs = 0;
2454 u8 i;
2455
2456 memset((u8 *) est, 0, sizeof(est));
2457 memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
2458 memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
2459
2460 log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
2461 num_samps = 1 << log_num_samps;
2462
2463 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2464 classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
2465 wlc_phy_classifier_nphy(pi, 3, 0);
2466 wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
2467 wait_crs);
2468 wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
2469 wlapi_enable_mac(pi->sh->physhim);
2470
2471 for (i = 0; i < pi->pubpi.phy_corenum; i++)
2472 cmplx_pwr[i] =
2473 (est[i].i_pwr +
2474 est[i].q_pwr) >> log_num_samps;
2475
2476 wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
2477
2478 for (i = 0; i < pi->pubpi.phy_corenum; i++) {
2479 pi->nphy_noise_win[i][pi->nphy_noise_index] =
2480 noise_dbm_ant[i];
2481
2482 if (noise_dbm_ant[i] > noise_dbm)
2483 noise_dbm = noise_dbm_ant[i];
2484 }
2485 pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
2486 PHY_NOISE_WINDOW_SZ);
2487
2488 wait_for_intr = false;
2489 }
2490 }
2491
2492 done:
2493
2494 if (!wait_for_intr)
2495 wlc_phy_noise_cb(pi, ch, noise_dbm);
2496
2497}
2498
2499void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *pih)
2500{
2501 u8 channel;
2502
2503 channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
2504
2505 wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
2506}
2507
2508static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm)
2509{
2510 if (!pi->phynoise_state)
2511 return;
2512
2513 if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
2514 if (pi->phynoise_chan_watchdog == channel) {
2515 pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
2516 noise_dbm;
2517 pi->sh->phy_noise_index =
2518 MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
2519 }
2520 pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
2521 }
2522
2523 if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL) {
2524 pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
2525 }
2526
2527}
2528
2529static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi)
2530{
2531 u32 cmplx_pwr[PHY_CORE_MAX];
2532 s8 noise_dbm_ant[PHY_CORE_MAX];
2533 u16 lo, hi;
2534 u32 cmplx_pwr_tot = 0;
2535 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2536 u8 idx, core;
2537
2538 memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
2539 memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
2540
2541 for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, core++) {
2542 lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
2543 hi = wlapi_bmac_read_shm(pi->sh->physhim,
2544 M_PWRIND_MAP(idx + 1));
2545 cmplx_pwr[core] = (hi << 16) + lo;
2546 cmplx_pwr_tot += cmplx_pwr[core];
2547 if (cmplx_pwr[core] == 0) {
2548 noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
2549 } else
2550 cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
2551 }
2552
2553 if (cmplx_pwr_tot != 0)
2554 wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
2555
2556 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
2557 pi->nphy_noise_win[core][pi->nphy_noise_index] =
2558 noise_dbm_ant[core];
2559
2560 if (noise_dbm_ant[core] > noise_dbm)
2561 noise_dbm = noise_dbm_ant[core];
2562 }
2563 pi->nphy_noise_index =
2564 MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
2565
2566 return noise_dbm;
2567
2568}
2569
2570void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih)
2571{
2572 struct brcms_phy *pi = (struct brcms_phy *) pih;
2573 u16 jssi_aux;
2574 u8 channel = 0;
2575 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2576
2577 if (ISLCNPHY(pi)) {
2578 u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
2579 u16 lo, hi;
2580 s32 pwr_offset_dB, gain_dB;
2581 u16 status_0, status_1;
2582
2583 jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
2584 channel = jssi_aux & D11_CURCHANNEL_MAX;
2585
2586 lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
2587 hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
2588 cmplx_pwr0 = (hi << 16) + lo;
2589
2590 lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
2591 hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
2592 cmplx_pwr1 = (hi << 16) + lo;
2593 cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
2594
2595 status_0 = 0x44;
2596 status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
2597 if ((cmplx_pwr > 0 && cmplx_pwr < 500)
2598 && ((status_1 & 0xc000) == 0x4000)) {
2599
2600 wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
2601 pi->pubpi.phy_corenum);
2602 pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
2603 if (pwr_offset_dB > 127)
2604 pwr_offset_dB -= 256;
2605
2606 noise_dbm += (s8) (pwr_offset_dB - 30);
2607
2608 gain_dB = (status_0 & 0x1ff);
2609 noise_dbm -= (s8) (gain_dB);
2610 } else {
2611 noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
2612 }
2613 } else if (ISNPHY(pi)) {
2614
2615 jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
2616 channel = jssi_aux & D11_CURCHANNEL_MAX;
2617
2618 noise_dbm = wlc_phy_noise_read_shmem(pi);
2619 }
2620
2621 wlc_phy_noise_cb(pi, channel, noise_dbm);
2622
2623}
2624
2625s8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
2626 8,
2627 8,
2628 8,
2629 8,
2630 8,
2631 8,
2632 8,
2633 9,
2634 10,
2635 8,
2636 8,
2637 7,
2638 7,
2639 1,
2640 2,
2641 2,
2642 2,
2643 2,
2644 2,
2645 2,
2646 2,
2647 2,
2648 2,
2649 2,
2650 2,
2651 2,
2652 2,
2653 2,
2654 2,
2655 2,
2656 2,
2657 2,
2658 1,
2659 1,
2660 0,
2661 0,
2662 0,
2663 0
2664};
2665
2666void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
2667{
2668 u8 msb, secondmsb, i;
2669 u32 tmp;
2670
2671 for (i = 0; i < core; i++) {
2672 secondmsb = 0;
2673 tmp = cmplx_pwr[i];
2674 msb = fls(tmp);
2675 if (msb)
2676 secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
2677 p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
2678 }
2679}
2680
2681void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx)
2682{
2683 struct brcms_d11rxhdr *wlc_rxhdr = (struct brcms_d11rxhdr *) ctx;
2684 struct d11rxhdr *rxh = &wlc_rxhdr->rxhdr;
2685 int rssi = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK;
2686 uint radioid = pih->radioid;
2687 struct brcms_phy *pi = (struct brcms_phy *) pih;
2688
2689 if (NORADIO_ENAB(pi->pubpi)) {
2690 rssi = BRCMS_RSSI_INVALID;
2691 goto end;
2692 }
2693
2694 if ((pi->sh->corerev >= 11)
2695 && !(le16_to_cpu(rxh->RxStatus2) & RXS_PHYRXST_VALID)) {
2696 rssi = BRCMS_RSSI_INVALID;
2697 goto end;
2698 }
2699
2700 if (ISLCNPHY(pi)) {
2701 u8 gidx = (le16_to_cpu(rxh->PhyRxStatus_2) & 0xFC00) >> 10;
2702 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2703
2704 if (rssi > 127)
2705 rssi -= 256;
2706
2707 rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
2708 if ((rssi > -46) && (gidx > 18))
2709 rssi = rssi + 7;
2710
2711 rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
2712
2713 rssi = rssi + 2;
2714
2715 }
2716
2717 if (ISLCNPHY(pi)) {
2718
2719 if (rssi > 127)
2720 rssi -= 256;
2721 } else if (radioid == BCM2055_ID || radioid == BCM2056_ID
2722 || radioid == BCM2057_ID) {
2723 rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr);
2724 }
2725
2726 end:
2727 wlc_rxhdr->rssi = (s8) rssi;
2728}
2729
2730void wlc_phy_freqtrack_start(struct brcms_phy_pub *pih)
2731{
2732 return;
2733}
2734
2735void wlc_phy_freqtrack_end(struct brcms_phy_pub *pih)
2736{
2737 return;
2738}
2739
2740void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag)
2741{
2742 struct brcms_phy *pi;
2743 pi = (struct brcms_phy *) ppi;
2744
2745 if (ISLCNPHY(pi))
2746 wlc_lcnphy_deaf_mode(pi, true);
2747 else if (ISNPHY(pi))
2748 wlc_nphy_deaf_mode(pi, true);
2749}
2750
2751void wlc_phy_watchdog(struct brcms_phy_pub *pih)
2752{
2753 struct brcms_phy *pi = (struct brcms_phy *) pih;
2754 bool delay_phy_cal = false;
2755 pi->sh->now++;
2756
2757 if (!pi->watchdog_override)
2758 return;
2759
2760 if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) {
2761 wlc_phy_noise_sample_request((struct brcms_phy_pub *) pi,
2762 PHY_NOISE_SAMPLE_MON,
2763 CHSPEC_CHANNEL(pi->
2764 radio_chanspec));
2765 }
2766
2767 if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5) {
2768 pi->phynoise_state = 0;
2769 }
2770
2771 if ((!pi->phycal_txpower) ||
2772 ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
2773
2774 if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi)) {
2775 pi->phycal_txpower = pi->sh->now;
2776 }
2777 }
2778
2779 if (NORADIO_ENAB(pi->pubpi))
2780 return;
2781
2782 if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
2783 || ASSOC_INPROG_PHY(pi)))
2784 return;
2785
2786 if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
2787
2788 if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
2789 (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
2790 ((pi->sh->now - pi->nphy_perical_last) >=
2791 pi->sh->glacial_timer))
2792 wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
2793 PHY_PERICAL_WATCHDOG);
2794
2795 wlc_phy_txpwr_papd_cal_nphy(pi);
2796 }
2797
2798 if (ISLCNPHY(pi)) {
2799 if (pi->phy_forcecal ||
2800 ((pi->sh->now - pi->phy_lastcal) >=
2801 pi->sh->glacial_timer)) {
2802 if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
2803 wlc_lcnphy_calib_modes(pi,
2804 LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
2805 if (!
2806 (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
2807 || ASSOC_INPROG_PHY(pi)
2808 || pi->carrier_suppr_disable
2809 || pi->disable_percal))
2810 wlc_lcnphy_calib_modes(pi,
2811 PHY_PERICAL_WATCHDOG);
2812 }
2813 }
2814}
2815
2816void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi)
2817{
2818 struct brcms_phy *pi = (struct brcms_phy *) pih;
2819 uint i;
2820 uint k;
2821
2822 for (i = 0; i < MA_WINDOW_SZ; i++) {
2823 pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff);
2824 }
2825 if (ISLCNPHY(pi)) {
2826 for (i = 0; i < MA_WINDOW_SZ; i++)
2827 pi->sh->phy_noise_window[i] =
2828 PHY_NOISE_FIXED_VAL_LCNPHY;
2829 }
2830 pi->sh->phy_noise_index = 0;
2831
2832 for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
2833 for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
2834 pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
2835 }
2836 pi->nphy_noise_index = 0;
2837}
2838
2839void
2840wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)
2841{
2842 *eps_imag = (epsilon >> 13);
2843 if (*eps_imag > 0xfff)
2844 *eps_imag -= 0x2000;
2845
2846 *eps_real = (epsilon & 0x1fff);
2847 if (*eps_real > 0xfff)
2848 *eps_real -= 0x2000;
2849}
2850
2851static const fixed AtanTbl[] = {
2852 2949120,
2853 1740967,
2854 919879,
2855 466945,
2856 234379,
2857 117304,
2858 58666,
2859 29335,
2860 14668,
2861 7334,
2862 3667,
2863 1833,
2864 917,
2865 458,
2866 229,
2867 115,
2868 57,
2869 29
2870};
2871
2872void wlc_phy_cordic(fixed theta, cs32 *val)
2873{
2874 fixed angle, valtmp;
2875 unsigned iter;
2876 int signx = 1;
2877 int signtheta;
2878
2879 val[0].i = CORDIC_AG;
2880 val[0].q = 0;
2881 angle = 0;
2882
2883 signtheta = (theta < 0) ? -1 : 1;
2884 theta =
2885 ((theta + FIXED(180) * signtheta) % FIXED(360)) -
2886 FIXED(180) * signtheta;
2887
2888 if (FLOAT(theta) > 90) {
2889 theta -= FIXED(180);
2890 signx = -1;
2891 } else if (FLOAT(theta) < -90) {
2892 theta += FIXED(180);
2893 signx = -1;
2894 }
2895
2896 for (iter = 0; iter < CORDIC_NI; iter++) {
2897 if (theta > angle) {
2898 valtmp = val[0].i - (val[0].q >> iter);
2899 val[0].q = (val[0].i >> iter) + val[0].q;
2900 val[0].i = valtmp;
2901 angle += AtanTbl[iter];
2902 } else {
2903 valtmp = val[0].i + (val[0].q >> iter);
2904 val[0].q = -(val[0].i >> iter) + val[0].q;
2905 val[0].i = valtmp;
2906 angle -= AtanTbl[iter];
2907 }
2908 }
2909
2910 val[0].i = val[0].i * signx;
2911 val[0].q = val[0].q * signx;
2912}
2913
2914void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi)
2915{
2916 wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
2917
2918 pi->cal_type_override = PHY_PERICAL_AUTO;
2919 pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
2920 pi->mphase_txcal_cmdidx = 0;
2921}
2922
2923static void
2924wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, uint delay)
2925{
2926
2927 if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
2928 (pi->nphy_perical != PHY_PERICAL_MANUAL))
2929 return;
2930
2931 wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
2932
2933 pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
2934 wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
2935}
2936
2937void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason)
2938{
2939 s16 nphy_currtemp = 0;
2940 s16 delta_temp = 0;
2941 bool do_periodic_cal = true;
2942 struct brcms_phy *pi = (struct brcms_phy *) pih;
2943
2944 if (!ISNPHY(pi))
2945 return;
2946
2947 if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
2948 (pi->nphy_perical == PHY_PERICAL_MANUAL))
2949 return;
2950
2951 switch (reason) {
2952 case PHY_PERICAL_DRIVERUP:
2953 break;
2954
2955 case PHY_PERICAL_PHYINIT:
2956 if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
2957 if (PHY_PERICAL_MPHASE_PENDING(pi)) {
2958 wlc_phy_cal_perical_mphase_reset(pi);
2959 }
2960 wlc_phy_cal_perical_mphase_schedule(pi,
2961 PHY_PERICAL_INIT_DELAY);
2962 }
2963 break;
2964
2965 case PHY_PERICAL_JOIN_BSS:
2966 case PHY_PERICAL_START_IBSS:
2967 case PHY_PERICAL_UP_BSS:
2968 if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
2969 PHY_PERICAL_MPHASE_PENDING(pi)) {
2970 wlc_phy_cal_perical_mphase_reset(pi);
2971 }
2972
2973 pi->first_cal_after_assoc = true;
2974
2975 pi->cal_type_override = PHY_PERICAL_FULL;
2976
2977 if (pi->phycal_tempdelta) {
2978 pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
2979 }
2980 wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
2981 break;
2982
2983 case PHY_PERICAL_WATCHDOG:
2984 if (pi->phycal_tempdelta) {
2985 nphy_currtemp = wlc_phy_tempsense_nphy(pi);
2986 delta_temp =
2987 (nphy_currtemp > pi->nphy_lastcal_temp) ?
2988 nphy_currtemp - pi->nphy_lastcal_temp :
2989 pi->nphy_lastcal_temp - nphy_currtemp;
2990
2991 if ((delta_temp < (s16) pi->phycal_tempdelta) &&
2992 (pi->nphy_txiqlocal_chanspec ==
2993 pi->radio_chanspec)) {
2994 do_periodic_cal = false;
2995 } else {
2996 pi->nphy_lastcal_temp = nphy_currtemp;
2997 }
2998 }
2999
3000 if (do_periodic_cal) {
3001
3002 if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
3003
3004 if (!PHY_PERICAL_MPHASE_PENDING(pi))
3005 wlc_phy_cal_perical_mphase_schedule(pi,
3006 PHY_PERICAL_WDOG_DELAY);
3007 } else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
3008 wlc_phy_cal_perical_nphy_run(pi,
3009 PHY_PERICAL_AUTO);
3010 }
3011 break;
3012 default:
3013 break;
3014 }
3015}
3016
3017void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi)
3018{
3019 pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
3020 pi->mphase_txcal_cmdidx = 0;
3021}
3022
3023u8 wlc_phy_nbits(s32 value)
3024{
3025 s32 abs_val;
3026 u8 nbits = 0;
3027
3028 abs_val = ABS(value);
3029 while ((abs_val >> nbits) > 0)
3030 nbits++;
3031
3032 return nbits;
3033}
3034
3035void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
3036{
3037 struct brcms_phy *pi = (struct brcms_phy *) pih;
3038
3039 pi->sh->hw_phytxchain = txchain;
3040 pi->sh->hw_phyrxchain = rxchain;
3041 pi->sh->phytxchain = txchain;
3042 pi->sh->phyrxchain = rxchain;
3043 pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain);
3044}
3045
3046void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
3047{
3048 struct brcms_phy *pi = (struct brcms_phy *) pih;
3049
3050 pi->sh->phytxchain = txchain;
3051
3052 if (ISNPHY(pi)) {
3053 wlc_phy_rxcore_setstate_nphy(pih, rxchain);
3054 }
3055 pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain);
3056}
3057
3058void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain)
3059{
3060 struct brcms_phy *pi = (struct brcms_phy *) pih;
3061
3062 *txchain = pi->sh->phytxchain;
3063 *rxchain = pi->sh->phyrxchain;
3064}
3065
3066u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih)
3067{
3068 s16 nphy_currtemp;
3069 u8 active_bitmap;
3070 struct brcms_phy *pi = (struct brcms_phy *) pih;
3071
3072 active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
3073
3074 if (!pi->watchdog_override)
3075 return active_bitmap;
3076
3077 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
3078 wlapi_suspend_mac_and_wait(pi->sh->physhim);
3079 nphy_currtemp = wlc_phy_tempsense_nphy(pi);
3080 wlapi_enable_mac(pi->sh->physhim);
3081
3082 if (!pi->phy_txcore_heatedup) {
3083 if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
3084 active_bitmap &= 0xFD;
3085 pi->phy_txcore_heatedup = true;
3086 }
3087 } else {
3088 if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
3089 active_bitmap |= 0x2;
3090 pi->phy_txcore_heatedup = false;
3091 }
3092 }
3093 }
3094
3095 return active_bitmap;
3096}
3097
3098s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, chanspec_t chanspec)
3099{
3100 struct brcms_phy *pi = (struct brcms_phy *) pih;
3101 u8 siso_mcs_id, cdd_mcs_id;
3102
3103 siso_mcs_id =
3104 (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
3105 TXP_FIRST_MCS_20_SISO;
3106 cdd_mcs_id =
3107 (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
3108 TXP_FIRST_MCS_20_CDD;
3109
3110 if (pi->tx_power_target[siso_mcs_id] >
3111 (pi->tx_power_target[cdd_mcs_id] + 12))
3112 return PHY_TXC1_MODE_SISO;
3113 else
3114 return PHY_TXC1_MODE_CDD;
3115}
3116
3117const u8 *wlc_phy_get_ofdm_rate_lookup(void)
3118{
3119 return ofdm_rate_lookup;
3120}
3121
3122void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode)
3123{
3124 if ((pi->sh->chip == BCM4313_CHIP_ID) &&
3125 (pi->sh->boardflags & BFL_FEM)) {
3126 if (mode) {
3127 u16 txant = 0;
3128 txant = wlapi_bmac_get_txant(pi->sh->physhim);
3129 if (txant == 1) {
3130 mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
3131
3132 mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
3133
3134 }
3135 ai_corereg(pi->sh->sih, SI_CC_IDX,
3136 offsetof(chipcregs_t, gpiocontrol), ~0x0,
3137 0x0);
3138 ai_corereg(pi->sh->sih, SI_CC_IDX,
3139 offsetof(chipcregs_t, gpioout), 0x40, 0x40);
3140 ai_corereg(pi->sh->sih, SI_CC_IDX,
3141 offsetof(chipcregs_t, gpioouten), 0x40,
3142 0x40);
3143 } else {
3144 mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
3145
3146 mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
3147
3148 ai_corereg(pi->sh->sih, SI_CC_IDX,
3149 offsetof(chipcregs_t, gpioout), 0x40, 0x00);
3150 ai_corereg(pi->sh->sih, SI_CC_IDX,
3151 offsetof(chipcregs_t, gpioouten), 0x40, 0x0);
3152 ai_corereg(pi->sh->sih, SI_CC_IDX,
3153 offsetof(chipcregs_t, gpiocontrol), ~0x0,
3154 0x40);
3155 }
3156 }
3157}
3158
3159static s8
3160wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band,
3161 u8 rate)
3162{
3163 s8 offset = 0;
3164
3165 if (!pi->user_txpwr_at_rfport)
3166 return offset;
3167 return offset;
3168}
3169
3170static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi)
3171{
3172 if (ISLCNPHY(pi))
3173 return wlc_lcnphy_vbatsense(pi, 0);
3174 else
3175 return 0;
3176}
3177
3178static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi)
3179{
3180 if (ISLCNPHY(pi))
3181 return wlc_lcnphy_tempsense_degree(pi, 0);
3182 else
3183 return 0;
3184}
3185
3186static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band)
3187{
3188 u8 i;
3189 s8 temp, vbat;
3190
3191 for (i = 0; i < TXP_NUM_RATES; i++)
3192 pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
3193
3194 vbat = wlc_phy_env_measure_vbat(pi);
3195 temp = wlc_phy_env_measure_temperature(pi);
3196
3197}
3198
3199void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool ldpc)
3200{
3201 return;
3202}
3203
3204void
3205wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset)
3206{
3207 *cckoffset = 0;
3208 *ofdmoffset = 0;
3209}
3210
3211s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, chanspec_t chanspec)
3212{
3213
3214 return rssi;
3215}
3216
3217bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi)
3218{
3219 struct brcms_phy *pi = (struct brcms_phy *) ppi;
3220
3221 if (ISNPHY(pi))
3222 return wlc_phy_n_txpower_ipa_ison(pi);
3223 else
3224 return 0;
3225}
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h
new file mode 100644
index 00000000000..e27d9e95a2d
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h
@@ -0,0 +1,294 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * phy_hal.h: functionality exported from the phy to higher layers
19 */
20
21#ifndef _BRCM_PHY_HAL_H_
22#define _BRCM_PHY_HAL_H_
23
24#include <brcmu_utils.h>
25#include <brcmu_wifi.h>
26#include <phy_shim.h>
27
28#define IDCODE_VER_MASK 0x0000000f
29#define IDCODE_VER_SHIFT 0
30#define IDCODE_MFG_MASK 0x00000fff
31#define IDCODE_MFG_SHIFT 0
32#define IDCODE_ID_MASK 0x0ffff000
33#define IDCODE_ID_SHIFT 12
34#define IDCODE_REV_MASK 0xf0000000
35#define IDCODE_REV_SHIFT 28
36
37#define NORADIO_ID 0xe4f5
38#define NORADIO_IDCODE 0x4e4f5246
39
40#define BCM2055_ID 0x2055
41#define BCM2055_IDCODE 0x02055000
42#define BCM2055A0_IDCODE 0x1205517f
43
44#define BCM2056_ID 0x2056
45#define BCM2056_IDCODE 0x02056000
46#define BCM2056A0_IDCODE 0x1205617f
47
48#define BCM2057_ID 0x2057
49#define BCM2057_IDCODE 0x02057000
50#define BCM2057A0_IDCODE 0x1205717f
51
52#define BCM2064_ID 0x2064
53#define BCM2064_IDCODE 0x02064000
54#define BCM2064A0_IDCODE 0x0206417f
55
56#define PHY_TPC_HW_OFF false
57#define PHY_TPC_HW_ON true
58
59#define PHY_PERICAL_DRIVERUP 1
60#define PHY_PERICAL_WATCHDOG 2
61#define PHY_PERICAL_PHYINIT 3
62#define PHY_PERICAL_JOIN_BSS 4
63#define PHY_PERICAL_START_IBSS 5
64#define PHY_PERICAL_UP_BSS 6
65#define PHY_PERICAL_CHAN 7
66#define PHY_FULLCAL 8
67
68#define PHY_PERICAL_DISABLE 0
69#define PHY_PERICAL_SPHASE 1
70#define PHY_PERICAL_MPHASE 2
71#define PHY_PERICAL_MANUAL 3
72
73#define PHY_HOLD_FOR_ASSOC 1
74#define PHY_HOLD_FOR_SCAN 2
75#define PHY_HOLD_FOR_RM 4
76#define PHY_HOLD_FOR_PLT 8
77#define PHY_HOLD_FOR_MUTE 16
78#define PHY_HOLD_FOR_NOT_ASSOC 0x20
79
80#define PHY_MUTE_FOR_PREISM 1
81#define PHY_MUTE_ALL 0xffffffff
82
83#define PHY_NOISE_FIXED_VAL (-95)
84#define PHY_NOISE_FIXED_VAL_NPHY (-92)
85#define PHY_NOISE_FIXED_VAL_LCNPHY (-92)
86
87#define PHY_MODE_CAL 0x0002
88#define PHY_MODE_NOISEM 0x0004
89
90#define BRCMS_TXPWR_DB_FACTOR 4
91
92/* a large TX Power as an init value to factor out of min() calculations,
93 * keep low enough to fit in an s8, units are .25 dBm
94 */
95#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
96
97#define BRCMS_NUM_RATES_CCK 4
98#define BRCMS_NUM_RATES_OFDM 8
99#define BRCMS_NUM_RATES_MCS_1_STREAM 8
100#define BRCMS_NUM_RATES_MCS_2_STREAM 8
101#define BRCMS_NUM_RATES_MCS_3_STREAM 8
102#define BRCMS_NUM_RATES_MCS_4_STREAM 8
103
104#define BRCMS_RSSI_INVALID 0 /* invalid RSSI value */
105
106struct txpwr_limits {
107 u8 cck[BRCMS_NUM_RATES_CCK];
108 u8 ofdm[BRCMS_NUM_RATES_OFDM];
109
110 u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
111
112 u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
113 u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
114
115 u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
116 u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
117 u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
118 u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
119
120 u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
121 u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
122 u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
123 u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
124 u8 mcs32;
125};
126
127struct tx_power {
128 u32 flags;
129 chanspec_t chanspec; /* txpwr report for this channel */
130 chanspec_t local_chanspec; /* channel on which we are associated */
131 u8 local_max; /* local max according to the AP */
132 u8 local_constraint; /* local constraint according to the AP */
133 s8 antgain[2]; /* Ant gain for each band - from SROM */
134 u8 rf_cores; /* count of RF Cores being reported */
135 u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
136 u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain
137 * without adjustment
138 */
139 u8 est_Pout_cck; /* Latest CCK tx power out estimate */
140 u8 tx_power_max[4]; /* Maximum target power among all rates */
141 u8 tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */
142 u8 user_limit[WL_TX_POWER_RATES]; /* User limit */
143 u8 reg_limit[WL_TX_POWER_RATES]; /* Regulatory power limit */
144 u8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */
145 u8 target[WL_TX_POWER_RATES]; /* Latest target power */
146};
147
148struct tx_inst_power {
149 u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
150 u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
151};
152
153struct chanvec {
154 u8 vec[MAXCHANNEL / NBBY];
155};
156
157struct shared_phy_params {
158 struct si_pub *sih;
159 void *physhim;
160 uint unit;
161 uint corerev;
162 uint bustype;
163 uint buscorerev;
164 char *vars;
165 u16 vid;
166 u16 did;
167 uint chip;
168 uint chiprev;
169 uint chippkg;
170 uint sromrev;
171 uint boardtype;
172 uint boardrev;
173 uint boardvendor;
174 u32 boardflags;
175 u32 boardflags2;
176};
177
178
179extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
180extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh, void *regs,
181 int bandtype, char *vars, struct wiphy *wiphy);
182extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
183
184extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
185 u16 *phyrev, u16 *radioid,
186 u16 *radiover);
187extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
188extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
189
190extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
191extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
192extern void wlc_phy_init(struct brcms_phy_pub *ppi, chanspec_t chanspec);
193extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
194extern int wlc_phy_down(struct brcms_phy_pub *ppi);
195extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
196extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
197extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
198
199extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi,
200 chanspec_t chanspec);
201extern chanspec_t wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
202extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
203 chanspec_t newch);
204extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
205extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
206
207extern void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx);
208extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
209extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
210extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
211
212extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
213
214extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
215extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
216
217
218extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
219
220extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
221 bool wide_filter);
222extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
223 chanvec_t *channels);
224extern chanspec_t wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi,
225 uint band);
226
227extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan,
228 u8 *_min_, u8 *_max_, int rate);
229extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi,
230 uint chan, u8 *_max_, u8 *_min_);
231extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi,
232 uint band, s32 *, s32 *, u32 *);
233extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi,
234 struct txpwr_limits *,
235 chanspec_t chanspec);
236extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm,
237 bool *override);
238extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm,
239 bool override);
240extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
241 struct txpwr_limits *);
242extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
243extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi,
244 bool hwpwrctrl);
245extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
246extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
247extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
248
249extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain,
250 u8 rxchain);
251extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain,
252 u8 rxchain);
253extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain,
254 u8 *rxchain);
255extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
256extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih,
257 chanspec_t chanspec);
258extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
259
260extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
261extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
262extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
263extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
264
265extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
266extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
267extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, mbool id, bool val);
268extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, mbool flags);
269
270extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
271
272extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
273 struct tx_power *power, uint channel);
274
275extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
276extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
277extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi,
278 u8 txpwr_percent);
279extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
280extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih,
281 bool bf_preempt);
282extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
283
284extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
285
286extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
287extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
288
289extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
290
291extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
292 u8 mcs_offset);
293extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
294#endif /* _BRCM_PHY_HAL_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h
new file mode 100644
index 00000000000..a01b01ccd9f
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h
@@ -0,0 +1,1235 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_PHY_INT_H_
18#define _BRCM_PHY_INT_H_
19
20#include <types.h>
21#include <brcmu_utils.h>
22#include <brcmu_wifi.h>
23
24#define PHY_VERSION { 1, 82, 8, 0 }
25
26#define PHYHAL_ERROR 0x0001
27#define PHYHAL_TRACE 0x0002
28#define PHYHAL_INFORM 0x0004
29
30extern u32 phyhal_msg_level;
31
32#define PHY_INFORM_ON() (phyhal_msg_level & PHYHAL_INFORM)
33#define PHY_THERMAL_ON() (phyhal_msg_level & PHYHAL_THERMAL)
34#define PHY_CAL_ON() (phyhal_msg_level & PHYHAL_CAL)
35
36#ifdef BOARD_TYPE
37#define BOARDTYPE(_type) BOARD_TYPE
38#else
39#define BOARDTYPE(_type) _type
40#endif
41
42#define LCNXN_BASEREV 16
43
44struct brcms_phy_srom_fem {
45 u8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */
46 u8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
47 u8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */
48 u8 triso; /* TR switch isolation */
49 u8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */
50};
51
52typedef void (*initfn_t) (struct brcms_phy *);
53typedef void (*chansetfn_t) (struct brcms_phy *, chanspec_t);
54typedef int (*longtrnfn_t) (struct brcms_phy *, int);
55typedef void (*txiqccgetfn_t) (struct brcms_phy *, u16 *, u16 *);
56typedef void (*txiqccsetfn_t) (struct brcms_phy *, u16, u16);
57typedef u16(*txloccgetfn_t) (struct brcms_phy *);
58typedef void (*radioloftgetfn_t) (struct brcms_phy *, u8 *, u8 *, u8 *,
59 u8 *);
60typedef s32(*rxsigpwrfn_t) (struct brcms_phy *, s32);
61typedef void (*detachfn_t) (struct brcms_phy *);
62
63#undef ISNPHY
64#undef ISLCNPHY
65#define ISNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
66#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
67
68#define ISPHY_11N_CAP(pi) (ISNPHY(pi) || ISLCNPHY(pi))
69
70#define IS20MHZ(pi) ((pi)->bw == WL_CHANSPEC_BW_20)
71#define IS40MHZ(pi) ((pi)->bw == WL_CHANSPEC_BW_40)
72
73#define PHY_GET_RFATTN(rfgain) ((rfgain) & 0x0f)
74#define PHY_GET_PADMIX(rfgain) (((rfgain) & 0x10) >> 4)
75#define PHY_GET_RFGAINID(rfattn, padmix, width) ((rfattn) + ((padmix)*(width)))
76#define PHY_SAT(x, n) ((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \
77 ((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x)))
78#define PHY_SHIFT_ROUND(x, n) ((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n))
79#define PHY_HW_ROUND(x, s) ((x >> s) + ((x >> (s-1)) & (s != 0)))
80
81#define CH_5G_GROUP 3
82#define A_LOW_CHANS 0
83#define A_MID_CHANS 1
84#define A_HIGH_CHANS 2
85#define CH_2G_GROUP 1
86#define G_ALL_CHANS 0
87
88#define FIRST_REF5_CHANNUM 149
89#define LAST_REF5_CHANNUM 165
90#define FIRST_5G_CHAN 14
91#define LAST_5G_CHAN 50
92#define FIRST_MID_5G_CHAN 14
93#define LAST_MID_5G_CHAN 35
94#define FIRST_HIGH_5G_CHAN 36
95#define LAST_HIGH_5G_CHAN 41
96#define FIRST_LOW_5G_CHAN 42
97#define LAST_LOW_5G_CHAN 50
98
99#define BASE_LOW_5G_CHAN 4900
100#define BASE_MID_5G_CHAN 5100
101#define BASE_HIGH_5G_CHAN 5500
102
103#define CHAN5G_FREQ(chan) (5000 + chan*5)
104#define CHAN2G_FREQ(chan) (2407 + chan*5)
105
106#define TXP_FIRST_CCK 0
107#define TXP_LAST_CCK 3
108#define TXP_FIRST_OFDM 4
109#define TXP_LAST_OFDM 11
110#define TXP_FIRST_OFDM_20_CDD 12
111#define TXP_LAST_OFDM_20_CDD 19
112#define TXP_FIRST_MCS_20_SISO 20
113#define TXP_LAST_MCS_20_SISO 27
114#define TXP_FIRST_MCS_20_CDD 28
115#define TXP_LAST_MCS_20_CDD 35
116#define TXP_FIRST_MCS_20_STBC 36
117#define TXP_LAST_MCS_20_STBC 43
118#define TXP_FIRST_MCS_20_SDM 44
119#define TXP_LAST_MCS_20_SDM 51
120#define TXP_FIRST_OFDM_40_SISO 52
121#define TXP_LAST_OFDM_40_SISO 59
122#define TXP_FIRST_OFDM_40_CDD 60
123#define TXP_LAST_OFDM_40_CDD 67
124#define TXP_FIRST_MCS_40_SISO 68
125#define TXP_LAST_MCS_40_SISO 75
126#define TXP_FIRST_MCS_40_CDD 76
127#define TXP_LAST_MCS_40_CDD 83
128#define TXP_FIRST_MCS_40_STBC 84
129#define TXP_LAST_MCS_40_STBC 91
130#define TXP_FIRST_MCS_40_SDM 92
131#define TXP_LAST_MCS_40_SDM 99
132#define TXP_MCS_32 100
133#define TXP_NUM_RATES 101
134#define ADJ_PWR_TBL_LEN 84
135
136#define TXP_FIRST_SISO_MCS_20 20
137#define TXP_LAST_SISO_MCS_20 27
138
139#define PHY_CORE_NUM_1 1
140#define PHY_CORE_NUM_2 2
141#define PHY_CORE_NUM_3 3
142#define PHY_CORE_NUM_4 4
143#define PHY_CORE_MAX PHY_CORE_NUM_4
144#define PHY_CORE_0 0
145#define PHY_CORE_1 1
146#define PHY_CORE_2 2
147#define PHY_CORE_3 3
148
149#define MA_WINDOW_SZ 8
150
151#define PHY_NOISE_SAMPLE_MON 1
152#define PHY_NOISE_SAMPLE_EXTERNAL 2
153#define PHY_NOISE_WINDOW_SZ 16
154#define PHY_NOISE_GLITCH_INIT_MA 10
155#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10
156#define PHY_NOISE_STATE_MON 0x1
157#define PHY_NOISE_STATE_EXTERNAL 0x2
158#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY 10
159#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE 9
160
161#define PHY_NOISE_OFFSETFACT_4322 (-103)
162#define PHY_NOISE_MA_WINDOW_SZ 2
163
164#define PHY_RSSI_TABLE_SIZE 64
165#define RSSI_ANT_MERGE_MAX 0
166#define RSSI_ANT_MERGE_MIN 1
167#define RSSI_ANT_MERGE_AVG 2
168
169#define PHY_TSSI_TABLE_SIZE 64
170#define APHY_TSSI_TABLE_SIZE 256
171#define TX_GAIN_TABLE_LENGTH 64
172#define DEFAULT_11A_TXP_IDX 24
173#define NUM_TSSI_FRAMES 4
174#define NULL_TSSI 0x7f
175#define NULL_TSSI_W 0x7f7f
176
177#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64
178
179#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9
180
181#define PHY_TXPWR_MIN 10
182#define PHY_TXPWR_MIN_NPHY 8
183#define RADIOPWR_OVERRIDE_DEF (-1)
184
185#define PWRTBL_NUM_COEFF 3
186
187#define SPURAVOID_DISABLE 0
188#define SPURAVOID_AUTO 1
189#define SPURAVOID_FORCEON 2
190#define SPURAVOID_FORCEON2 3
191
192#define PHY_SW_TIMER_FAST 15
193#define PHY_SW_TIMER_SLOW 60
194#define PHY_SW_TIMER_GLACIAL 120
195
196#define PHY_PERICAL_AUTO 0
197#define PHY_PERICAL_FULL 1
198#define PHY_PERICAL_PARTIAL 2
199
200#define PHY_PERICAL_NODELAY 0
201#define PHY_PERICAL_INIT_DELAY 5
202#define PHY_PERICAL_ASSOC_DELAY 5
203#define PHY_PERICAL_WDOG_DELAY 5
204
205#define MPHASE_TXCAL_NUMCMDS 2
206#define PHY_PERICAL_MPHASE_PENDING(pi) (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE)
207
208enum {
209 MPHASE_CAL_STATE_IDLE = 0,
210 MPHASE_CAL_STATE_INIT = 1,
211 MPHASE_CAL_STATE_TXPHASE0,
212 MPHASE_CAL_STATE_TXPHASE1,
213 MPHASE_CAL_STATE_TXPHASE2,
214 MPHASE_CAL_STATE_TXPHASE3,
215 MPHASE_CAL_STATE_TXPHASE4,
216 MPHASE_CAL_STATE_TXPHASE5,
217 MPHASE_CAL_STATE_PAPDCAL,
218 MPHASE_CAL_STATE_RXCAL,
219 MPHASE_CAL_STATE_RSSICAL,
220 MPHASE_CAL_STATE_IDLETSSI
221};
222
223enum phy_cal_mode {
224 CAL_FULL,
225 CAL_RECAL,
226 CAL_CURRECAL,
227 CAL_DIGCAL,
228 CAL_GCTRL,
229 CAL_SOFT,
230 CAL_DIGLO
231};
232
233#define RDR_NTIERS 1
234#define RDR_TIER_SIZE 64
235#define RDR_LIST_SIZE (512/3)
236#define RDR_EPOCH_SIZE 40
237#define RDR_NANTENNAS 2
238#define RDR_NTIER_SIZE RDR_LIST_SIZE
239#define RDR_LP_BUFFER_SIZE 64
240#define LP_LEN_HIS_SIZE 10
241
242#define STATIC_NUM_RF 32
243#define STATIC_NUM_BB 9
244
245#define BB_MULT_MASK 0x0000ffff
246#define BB_MULT_VALID_MASK 0x80000000
247
248#define CORDIC_AG 39797
249#define CORDIC_NI 18
250#define FIXED(X) ((s32)((X) << 16))
251#define FLOAT(X) (((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
252
253#define PHY_CHAIN_TX_DISABLE_TEMP 115
254#define PHY_HYSTERESIS_DELTATEMP 5
255
256#define PHY_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8))
257
258#define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \
259 mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \
260 (value) << phy_type##_##reg_name##_##field##_##SHIFT);
261#define READ_PHY_REG(pi, phy_type, reg_name, field) \
262 ((read_phy_reg(pi, phy_type##_##reg_name) & phy_type##_##reg_name##_##field##_##MASK)\
263 >> phy_type##_##reg_name##_##field##_##SHIFT)
264
265#define VALID_PHYTYPE(phytype) (((uint)phytype == PHY_TYPE_N) || \
266 ((uint)phytype == PHY_TYPE_LCN))
267
268#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || (radioid == BCM2056_ID) || \
269 (radioid == BCM2057_ID))
270#define VALID_LCN_RADIO(radioid) (radioid == BCM2064_ID)
271
272#define VALID_RADIO(pi, radioid) (\
273 (ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \
274 (ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false))
275
276#define SCAN_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN))
277#define RM_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_RM))
278#define PLT_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT))
279#define ASSOC_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC))
280#define SCAN_RM_IN_PROGRESS(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM))
281#define PHY_MUTED(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE))
282#define PUB_NOT_ASSOC(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC))
283
284#if defined(EXT_CBALL)
285#define NORADIO_ENAB(pub) ((pub).radioid == NORADIO_ID)
286#else
287#define NORADIO_ENAB(pub) 0
288#endif
289
290#define PHY_LTRN_LIST_LEN 64
291extern u16 ltrn_list[PHY_LTRN_LIST_LEN];
292
293struct phy_table_info {
294 uint table;
295 int q;
296 uint max;
297};
298
299struct phytbl_info {
300 const void *tbl_ptr;
301 u32 tbl_len;
302 u32 tbl_id;
303 u32 tbl_offset;
304 u32 tbl_width;
305};
306
307struct interference_info {
308 u8 curr_home_channel;
309 u16 crsminpwrthld_40_stored;
310 u16 crsminpwrthld_20L_stored;
311 u16 crsminpwrthld_20U_stored;
312 u16 init_gain_code_core1_stored;
313 u16 init_gain_code_core2_stored;
314 u16 init_gain_codeb_core1_stored;
315 u16 init_gain_codeb_core2_stored;
316 u16 init_gain_table_stored[4];
317
318 u16 clip1_hi_gain_code_core1_stored;
319 u16 clip1_hi_gain_code_core2_stored;
320 u16 clip1_hi_gain_codeb_core1_stored;
321 u16 clip1_hi_gain_codeb_core2_stored;
322 u16 nb_clip_thresh_core1_stored;
323 u16 nb_clip_thresh_core2_stored;
324 u16 init_ofdmlna2gainchange_stored[4];
325 u16 init_ccklna2gainchange_stored[4];
326 u16 clip1_lo_gain_code_core1_stored;
327 u16 clip1_lo_gain_code_core2_stored;
328 u16 clip1_lo_gain_codeb_core1_stored;
329 u16 clip1_lo_gain_codeb_core2_stored;
330 u16 w1_clip_thresh_core1_stored;
331 u16 w1_clip_thresh_core2_stored;
332 u16 radio_2056_core1_rssi_gain_stored;
333 u16 radio_2056_core2_rssi_gain_stored;
334 u16 energy_drop_timeout_len_stored;
335
336 u16 ed_crs40_assertthld0_stored;
337 u16 ed_crs40_assertthld1_stored;
338 u16 ed_crs40_deassertthld0_stored;
339 u16 ed_crs40_deassertthld1_stored;
340 u16 ed_crs20L_assertthld0_stored;
341 u16 ed_crs20L_assertthld1_stored;
342 u16 ed_crs20L_deassertthld0_stored;
343 u16 ed_crs20L_deassertthld1_stored;
344 u16 ed_crs20U_assertthld0_stored;
345 u16 ed_crs20U_assertthld1_stored;
346 u16 ed_crs20U_deassertthld0_stored;
347 u16 ed_crs20U_deassertthld1_stored;
348
349 u16 badplcp_ma;
350 u16 badplcp_ma_previous;
351 u16 badplcp_ma_total;
352 u16 badplcp_ma_list[MA_WINDOW_SZ];
353 int badplcp_ma_index;
354 s16 pre_badplcp_cnt;
355 s16 bphy_pre_badplcp_cnt;
356
357 u16 init_gain_core1;
358 u16 init_gain_core2;
359 u16 init_gainb_core1;
360 u16 init_gainb_core2;
361 u16 init_gain_rfseq[4];
362
363 u16 crsminpwr0;
364 u16 crsminpwrl0;
365 u16 crsminpwru0;
366
367 s16 crsminpwr_index;
368
369 u16 radio_2057_core1_rssi_wb1a_gc_stored;
370 u16 radio_2057_core2_rssi_wb1a_gc_stored;
371 u16 radio_2057_core1_rssi_wb1g_gc_stored;
372 u16 radio_2057_core2_rssi_wb1g_gc_stored;
373 u16 radio_2057_core1_rssi_wb2_gc_stored;
374 u16 radio_2057_core2_rssi_wb2_gc_stored;
375 u16 radio_2057_core1_rssi_nb_gc_stored;
376 u16 radio_2057_core2_rssi_nb_gc_stored;
377};
378
379struct aci_save_gphy {
380 u16 rc_cal_ovr;
381 u16 phycrsth1;
382 u16 phycrsth2;
383 u16 init_n1p1_gain;
384 u16 p1_p2_gain;
385 u16 n1_n2_gain;
386 u16 n1_p1_gain;
387 u16 div_search_gain;
388 u16 div_p1_p2_gain;
389 u16 div_search_gn_change;
390 u16 table_7_2;
391 u16 table_7_3;
392 u16 cckshbits_gnref;
393 u16 clip_thresh;
394 u16 clip2_thresh;
395 u16 clip3_thresh;
396 u16 clip_p2_thresh;
397 u16 clip_pwdn_thresh;
398 u16 clip_n1p1_thresh;
399 u16 clip_n1_pwdn_thresh;
400 u16 bbconfig;
401 u16 cthr_sthr_shdin;
402 u16 energy;
403 u16 clip_p1_p2_thresh;
404 u16 threshold;
405 u16 reg15;
406 u16 reg16;
407 u16 reg17;
408 u16 div_srch_idx;
409 u16 div_srch_p1_p2;
410 u16 div_srch_gn_back;
411 u16 ant_dwell;
412 u16 ant_wr_settle;
413};
414
415struct lo_complex_abgphy_info {
416 s8 i;
417 s8 q;
418};
419
420struct nphy_iq_comp {
421 s16 a0;
422 s16 b0;
423 s16 a1;
424 s16 b1;
425};
426
427struct nphy_txpwrindex {
428 s8 index;
429 s8 index_internal;
430 s8 index_internal_save;
431 u16 AfectrlOverride;
432 u16 AfeCtrlDacGain;
433 u16 rad_gain;
434 u8 bbmult;
435 u16 iqcomp_a;
436 u16 iqcomp_b;
437 u16 locomp;
438};
439
440struct txiqcal_cache {
441
442 u16 txcal_coeffs_2G[8];
443 u16 txcal_radio_regs_2G[8];
444 struct nphy_iq_comp rxcal_coeffs_2G;
445
446 u16 txcal_coeffs_5G[8];
447 u16 txcal_radio_regs_5G[8];
448 struct nphy_iq_comp rxcal_coeffs_5G;
449};
450
451struct nphy_pwrctrl {
452 s8 max_pwr_2g;
453 s8 idle_targ_2g;
454 s16 pwrdet_2g_a1;
455 s16 pwrdet_2g_b0;
456 s16 pwrdet_2g_b1;
457 s8 max_pwr_5gm;
458 s8 idle_targ_5gm;
459 s8 max_pwr_5gh;
460 s8 max_pwr_5gl;
461 s16 pwrdet_5gm_a1;
462 s16 pwrdet_5gm_b0;
463 s16 pwrdet_5gm_b1;
464 s16 pwrdet_5gl_a1;
465 s16 pwrdet_5gl_b0;
466 s16 pwrdet_5gl_b1;
467 s16 pwrdet_5gh_a1;
468 s16 pwrdet_5gh_b0;
469 s16 pwrdet_5gh_b1;
470 s8 idle_targ_5gl;
471 s8 idle_targ_5gh;
472 s8 idle_tssi_2g;
473 s8 idle_tssi_5g;
474 s8 idle_tssi;
475 s16 a1;
476 s16 b0;
477 s16 b1;
478};
479
480struct nphy_txgains {
481 u16 txlpf[2];
482 u16 txgm[2];
483 u16 pga[2];
484 u16 pad[2];
485 u16 ipa[2];
486};
487
488#define PHY_NOISEVAR_BUFSIZE 10
489
490struct nphy_noisevar_buf {
491 int bufcount;
492 int tone_id[PHY_NOISEVAR_BUFSIZE];
493 u32 noise_vars[PHY_NOISEVAR_BUFSIZE];
494 u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
495};
496
497struct rssical_cache {
498 u16 rssical_radio_regs_2G[2];
499 u16 rssical_phyregs_2G[12];
500
501 u16 rssical_radio_regs_5G[2];
502 u16 rssical_phyregs_5G[12];
503};
504
505struct lcnphy_cal_results {
506
507 u16 txiqlocal_a;
508 u16 txiqlocal_b;
509 u16 txiqlocal_didq;
510 u8 txiqlocal_ei0;
511 u8 txiqlocal_eq0;
512 u8 txiqlocal_fi0;
513 u8 txiqlocal_fq0;
514
515 u16 txiqlocal_bestcoeffs[11];
516 u16 txiqlocal_bestcoeffs_valid;
517
518 u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY];
519 u16 analog_gain_ref;
520 u16 lut_begin;
521 u16 lut_end;
522 u16 lut_step;
523 u16 rxcompdbm;
524 u16 papdctrl;
525 u16 sslpnCalibClkEnCtrl;
526
527 u16 rxiqcal_coeff_a0;
528 u16 rxiqcal_coeff_b0;
529};
530
531struct shared_phy {
532 struct brcms_phy *phy_head;
533 uint unit;
534 struct si_pub *sih;
535 void *physhim;
536 uint corerev;
537 u32 machwcap;
538 bool up;
539 bool clk;
540 uint now;
541 u16 vid;
542 u16 did;
543 uint chip;
544 uint chiprev;
545 uint chippkg;
546 uint sromrev;
547 uint boardtype;
548 uint boardrev;
549 uint boardvendor;
550 u32 boardflags;
551 u32 boardflags2;
552 uint bustype;
553 uint buscorerev;
554 uint fast_timer;
555 uint slow_timer;
556 uint glacial_timer;
557 u8 rx_antdiv;
558 s8 phy_noise_window[MA_WINDOW_SZ];
559 uint phy_noise_index;
560 u8 hw_phytxchain;
561 u8 hw_phyrxchain;
562 u8 phytxchain;
563 u8 phyrxchain;
564 u8 rssi_mode;
565 bool _rifs_phy;
566};
567
568struct brcms_phy_pub {
569 uint phy_type;
570 uint phy_rev;
571 u8 phy_corenum;
572 u16 radioid;
573 u8 radiorev;
574 u8 radiover;
575
576 uint coreflags;
577 uint ana_rev;
578 bool abgphy_encore;
579};
580
581struct phy_func_ptr {
582 initfn_t init;
583 initfn_t calinit;
584 chansetfn_t chanset;
585 initfn_t txpwrrecalc;
586 longtrnfn_t longtrn;
587 txiqccgetfn_t txiqccget;
588 txiqccsetfn_t txiqccset;
589 txloccgetfn_t txloccget;
590 radioloftgetfn_t radioloftget;
591 initfn_t carrsuppr;
592 rxsigpwrfn_t rxsigpwr;
593 detachfn_t detach;
594};
595
596struct brcms_phy {
597 struct brcms_phy_pub pubpi_ro;
598 struct shared_phy *sh;
599 struct phy_func_ptr pi_fptr;
600 void *pi_ptr;
601
602 union {
603 struct brcms_phy_lcnphy *pi_lcnphy;
604 } u;
605 bool user_txpwr_at_rfport;
606
607 d11regs_t *regs;
608 struct brcms_phy *next;
609 char *vars;
610 struct brcms_phy_pub pubpi;
611
612 bool do_initcal;
613 bool phytest_on;
614 bool ofdm_rateset_war;
615 bool bf_preempt_4306;
616 chanspec_t radio_chanspec;
617 u8 antsel_type;
618 u16 bw;
619 u8 txpwr_percent;
620 bool phy_init_por;
621
622 bool init_in_progress;
623 bool initialized;
624 bool sbtml_gm;
625 uint refcnt;
626 bool watchdog_override;
627 u8 phynoise_state;
628 uint phynoise_now;
629 int phynoise_chan_watchdog;
630 bool phynoise_polling;
631 bool disable_percal;
632 mbool measure_hold;
633
634 s16 txpa_2g[PWRTBL_NUM_COEFF];
635 s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF];
636 s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF];
637 s16 txpa_5g_low[PWRTBL_NUM_COEFF];
638 s16 txpa_5g_mid[PWRTBL_NUM_COEFF];
639 s16 txpa_5g_hi[PWRTBL_NUM_COEFF];
640
641 u8 tx_srom_max_2g;
642 u8 tx_srom_max_5g_low;
643 u8 tx_srom_max_5g_mid;
644 u8 tx_srom_max_5g_hi;
645 u8 tx_srom_max_rate_2g[TXP_NUM_RATES];
646 u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES];
647 u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES];
648 u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES];
649 u8 tx_user_target[TXP_NUM_RATES];
650 s8 tx_power_offset[TXP_NUM_RATES];
651 u8 tx_power_target[TXP_NUM_RATES];
652
653 struct brcms_phy_srom_fem srom_fem2g;
654 struct brcms_phy_srom_fem srom_fem5g;
655
656 u8 tx_power_max;
657 u8 tx_power_max_rate_ind;
658 bool hwpwrctrl;
659 u8 nphy_txpwrctrl;
660 s8 nphy_txrx_chain;
661 bool phy_5g_pwrgain;
662
663 u16 phy_wreg;
664 u16 phy_wreg_limit;
665
666 s8 n_preamble_override;
667 u8 antswitch;
668 u8 aa2g, aa5g;
669
670 s8 idle_tssi[CH_5G_GROUP];
671 s8 target_idle_tssi;
672 s8 txpwr_est_Pout;
673 u8 tx_power_min;
674 u8 txpwr_limit[TXP_NUM_RATES];
675 u8 txpwr_env_limit[TXP_NUM_RATES];
676 u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN];
677
678 bool channel_14_wide_filter;
679
680 bool txpwroverride;
681 bool txpwridx_override_aphy;
682 s16 radiopwr_override;
683 u16 hwpwr_txcur;
684 u8 saved_txpwr_idx;
685
686 bool edcrs_threshold_lock;
687
688 u32 tr_R_gain_val;
689 u32 tr_T_gain_val;
690
691 s16 ofdm_analog_filt_bw_override;
692 s16 cck_analog_filt_bw_override;
693 s16 ofdm_rccal_override;
694 s16 cck_rccal_override;
695 u16 extlna_type;
696
697 uint interference_mode_crs_time;
698 u16 crsglitch_prev;
699 bool interference_mode_crs;
700
701 u32 phy_tx_tone_freq;
702 uint phy_lastcal;
703 bool phy_forcecal;
704 bool phy_fixed_noise;
705 u32 xtalfreq;
706 u8 pdiv;
707 s8 carrier_suppr_disable;
708
709 bool phy_bphy_evm;
710 bool phy_bphy_rfcs;
711 s8 phy_scraminit;
712 u8 phy_gpiosel;
713
714 s16 phy_txcore_disable_temp;
715 s16 phy_txcore_enable_temp;
716 s8 phy_tempsense_offset;
717 bool phy_txcore_heatedup;
718
719 u16 radiopwr;
720 u16 bb_atten;
721 u16 txctl1;
722
723 u16 mintxbias;
724 u16 mintxmag;
725 struct lo_complex_abgphy_info gphy_locomp_iq
726 [STATIC_NUM_RF][STATIC_NUM_BB];
727 s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
728 u16 gain_table[TX_GAIN_TABLE_LENGTH];
729 bool loopback_gain;
730 s16 max_lpback_gain_hdB;
731 s16 trsw_rx_gain_hdB;
732 u8 power_vec[8];
733
734 u16 rc_cal;
735 int nrssi_table_delta;
736 int nrssi_slope_scale;
737 int nrssi_slope_offset;
738 int min_rssi;
739 int max_rssi;
740
741 s8 txpwridx;
742 u8 min_txpower;
743
744 u8 a_band_high_disable;
745
746 u16 tx_vos;
747 u16 global_tx_bb_dc_bias_loft;
748
749 int rf_max;
750 int bb_max;
751 int rf_list_size;
752 int bb_list_size;
753 u16 *rf_attn_list;
754 u16 *bb_attn_list;
755 u16 padmix_mask;
756 u16 padmix_reg;
757 u16 *txmag_list;
758 uint txmag_len;
759 bool txmag_enable;
760
761 s8 *a_tssi_to_dbm;
762 s8 *m_tssi_to_dbm;
763 s8 *l_tssi_to_dbm;
764 s8 *h_tssi_to_dbm;
765 u8 *hwtxpwr;
766
767 u16 freqtrack_saved_regs[2];
768 int cur_interference_mode;
769 bool hwpwrctrl_capable;
770 bool temppwrctrl_capable;
771
772 uint phycal_nslope;
773 uint phycal_noffset;
774 uint phycal_mlo;
775 uint phycal_txpower;
776
777 u8 phy_aa2g;
778
779 bool nphy_tableloaded;
780 s8 nphy_rssisel;
781 u32 nphy_bb_mult_save;
782 u16 nphy_txiqlocal_bestc[11];
783 bool nphy_txiqlocal_coeffsvalid;
784 struct nphy_txpwrindex nphy_txpwrindex[PHY_CORE_NUM_2];
785 struct nphy_pwrctrl nphy_pwrctrl_info[PHY_CORE_NUM_2];
786 u16 cck2gpo;
787 u32 ofdm2gpo;
788 u32 ofdm5gpo;
789 u32 ofdm5glpo;
790 u32 ofdm5ghpo;
791 u8 bw402gpo;
792 u8 bw405gpo;
793 u8 bw405glpo;
794 u8 bw405ghpo;
795 u8 cdd2gpo;
796 u8 cdd5gpo;
797 u8 cdd5glpo;
798 u8 cdd5ghpo;
799 u8 stbc2gpo;
800 u8 stbc5gpo;
801 u8 stbc5glpo;
802 u8 stbc5ghpo;
803 u8 bwdup2gpo;
804 u8 bwdup5gpo;
805 u8 bwdup5glpo;
806 u8 bwdup5ghpo;
807 u16 mcs2gpo[8];
808 u16 mcs5gpo[8];
809 u16 mcs5glpo[8];
810 u16 mcs5ghpo[8];
811 u32 nphy_rxcalparams;
812
813 u8 phy_spuravoid;
814 bool phy_isspuravoid;
815
816 u8 phy_pabias;
817 u8 nphy_papd_skip;
818 u8 nphy_tssi_slope;
819
820 s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ];
821 u8 nphy_noise_index;
822
823 u8 nphy_txpid2g[PHY_CORE_NUM_2];
824 u8 nphy_txpid5g[PHY_CORE_NUM_2];
825 u8 nphy_txpid5gl[PHY_CORE_NUM_2];
826 u8 nphy_txpid5gh[PHY_CORE_NUM_2];
827
828 bool nphy_gain_boost;
829 bool nphy_elna_gain_config;
830 u16 old_bphy_test;
831 u16 old_bphy_testcontrol;
832
833 bool phyhang_avoid;
834
835 bool rssical_nphy;
836 u8 nphy_perical;
837 uint nphy_perical_last;
838 u8 cal_type_override;
839 u8 mphase_cal_phase_id;
840 u8 mphase_txcal_cmdidx;
841 u8 mphase_txcal_numcmds;
842 u16 mphase_txcal_bestcoeffs[11];
843 chanspec_t nphy_txiqlocal_chanspec;
844 chanspec_t nphy_iqcal_chanspec_2G;
845 chanspec_t nphy_iqcal_chanspec_5G;
846 chanspec_t nphy_rssical_chanspec_2G;
847 chanspec_t nphy_rssical_chanspec_5G;
848 struct wlapi_timer *phycal_timer;
849 bool use_int_tx_iqlo_cal_nphy;
850 bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
851 s16 nphy_lastcal_temp;
852
853 struct txiqcal_cache calibration_cache;
854 struct rssical_cache rssical_cache;
855
856 u8 nphy_txpwr_idx[2];
857 u8 nphy_papd_cal_type;
858 uint nphy_papd_last_cal;
859 u16 nphy_papd_tx_gain_at_last_cal[2];
860 u8 nphy_papd_cal_gain_index[2];
861 s16 nphy_papd_epsilon_offset[2];
862 bool nphy_papd_recal_enable;
863 u32 nphy_papd_recal_counter;
864 bool nphy_force_papd_cal;
865 bool nphy_papdcomp;
866 bool ipa2g_on;
867 bool ipa5g_on;
868
869 u16 classifier_state;
870 u16 clip_state[2];
871 uint nphy_deaf_count;
872 u8 rxiq_samps;
873 u8 rxiq_antsel;
874
875 u16 rfctrlIntc1_save;
876 u16 rfctrlIntc2_save;
877 bool first_cal_after_assoc;
878 u16 tx_rx_cal_radio_saveregs[22];
879 u16 tx_rx_cal_phy_saveregs[15];
880
881 u8 nphy_cal_orig_pwr_idx[2];
882 u8 nphy_txcal_pwr_idx[2];
883 u8 nphy_rxcal_pwr_idx[2];
884 u16 nphy_cal_orig_tx_gain[2];
885 struct nphy_txgains nphy_cal_target_gain;
886 u16 nphy_txcal_bbmult;
887 u16 nphy_gmval;
888
889 u16 nphy_saved_bbconf;
890
891 bool nphy_gband_spurwar_en;
892 bool nphy_gband_spurwar2_en;
893 bool nphy_aband_spurwar_en;
894 u16 nphy_rccal_value;
895 u16 nphy_crsminpwr[3];
896 struct nphy_noisevar_buf nphy_saved_noisevars;
897 bool nphy_anarxlpf_adjusted;
898 bool nphy_crsminpwr_adjusted;
899 bool nphy_noisevars_adjusted;
900
901 bool nphy_rxcal_active;
902 u16 radar_percal_mask;
903 bool dfs_lp_buffer_nphy;
904
905 u16 nphy_fineclockgatecontrol;
906
907 s8 rx2tx_biasentry;
908
909 u16 crsminpwr0;
910 u16 crsminpwrl0;
911 u16 crsminpwru0;
912 s16 noise_crsminpwr_index;
913 u16 init_gain_core1;
914 u16 init_gain_core2;
915 u16 init_gainb_core1;
916 u16 init_gainb_core2;
917 u8 aci_noise_curr_channel;
918 u16 init_gain_rfseq[4];
919
920 bool radio_is_on;
921
922 bool nphy_sample_play_lpf_bw_ctl_ovr;
923
924 u16 tbl_data_hi;
925 u16 tbl_data_lo;
926 u16 tbl_addr;
927
928 uint tbl_save_id;
929 uint tbl_save_offset;
930
931 u8 txpwrctrl;
932 s8 txpwrindex[PHY_CORE_MAX];
933
934 u8 phycal_tempdelta;
935 u32 mcs20_po;
936 u32 mcs40_po;
937 struct wiphy *wiphy;
938};
939
940struct _cs32 {
941 fixed q;
942 fixed i;
943};
944
945struct radio_regs {
946 u16 address;
947 u32 init_a;
948 u32 init_g;
949 u8 do_init_a;
950 u8 do_init_g;
951};
952
953struct radio_20xx_regs {
954 u16 address;
955 u8 init;
956 u8 do_init;
957};
958
959struct lcnphy_radio_regs {
960 u16 address;
961 u8 init_a;
962 u8 init_g;
963 u8 do_init_a;
964 u8 do_init_g;
965};
966
967extern struct lcnphy_radio_regs lcnphy_radio_regs_2064[];
968extern struct lcnphy_radio_regs lcnphy_radio_regs_2066[];
969extern struct radio_regs regs_2055[], regs_SYN_2056[], regs_TX_2056[],
970 regs_RX_2056[];
971extern struct radio_regs regs_SYN_2056_A1[], regs_TX_2056_A1[],
972 regs_RX_2056_A1[];
973extern struct radio_regs regs_SYN_2056_rev5[], regs_TX_2056_rev5[],
974 regs_RX_2056_rev5[];
975extern struct radio_regs regs_SYN_2056_rev6[], regs_TX_2056_rev6[],
976 regs_RX_2056_rev6[];
977extern struct radio_regs regs_SYN_2056_rev7[], regs_TX_2056_rev7[],
978 regs_RX_2056_rev7[];
979extern struct radio_regs regs_SYN_2056_rev8[], regs_TX_2056_rev8[],
980 regs_RX_2056_rev8[];
981extern struct radio_20xx_regs regs_2057_rev4[], regs_2057_rev5[],
982 regs_2057_rev5v1[];
983extern struct radio_20xx_regs regs_2057_rev7[], regs_2057_rev8[];
984
985extern char *phy_getvar(struct brcms_phy *pi, const char *name);
986extern int phy_getintvar(struct brcms_phy *pi, const char *name);
987#define PHY_GETVAR(pi, name) phy_getvar(pi, name)
988#define PHY_GETINTVAR(pi, name) phy_getintvar(pi, name)
989
990extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr);
991extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
992extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
993extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
994extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val);
995
996extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr);
997extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
998extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
999extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask,
1000 u16 val);
1001extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask);
1002
1003extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
1004
1005extern void wlc_phyreg_enter(struct brcms_phy_pub *pih);
1006extern void wlc_phyreg_exit(struct brcms_phy_pub *pih);
1007extern void wlc_radioreg_enter(struct brcms_phy_pub *pih);
1008extern void wlc_radioreg_exit(struct brcms_phy_pub *pih);
1009
1010extern void wlc_phy_read_table(struct brcms_phy *pi,
1011 const struct phytbl_info *ptbl_info,
1012 u16 tblAddr, u16 tblDataHi,
1013 u16 tblDatalo);
1014extern void wlc_phy_write_table(struct brcms_phy *pi,
1015 const struct phytbl_info *ptbl_info,
1016 u16 tblAddr, u16 tblDataHi, u16 tblDatalo);
1017extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id,
1018 uint tbl_offset, u16 tblAddr, u16 tblDataHi,
1019 u16 tblDataLo);
1020extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val);
1021
1022extern void write_phy_channel_reg(struct brcms_phy *pi, uint val);
1023extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi);
1024
1025extern void wlc_phy_cordic(fixed theta, cs32 *val);
1026extern u8 wlc_phy_nbits(s32 value);
1027extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
1028
1029extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
1030 struct radio_20xx_regs *radioregs);
1031extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi,
1032 struct radio_regs *radioregs,
1033 u16 core_offset);
1034
1035extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi);
1036
1037extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on);
1038extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real,
1039 s32 *eps_imag);
1040
1041extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi);
1042extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi);
1043
1044extern bool wlc_phy_attach_nphy(struct brcms_phy *pi);
1045extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi);
1046
1047extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi);
1048
1049extern void wlc_phy_init_nphy(struct brcms_phy *pi);
1050extern void wlc_phy_init_lcnphy(struct brcms_phy *pi);
1051
1052extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi);
1053extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi);
1054
1055extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi,
1056 chanspec_t chanspec);
1057extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi,
1058 chanspec_t chanspec);
1059extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi,
1060 chanspec_t chanspec);
1061extern int wlc_phy_channel2freq(uint channel);
1062extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
1063extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, chanspec_t);
1064
1065extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode);
1066extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi);
1067
1068extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi);
1069extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi);
1070extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi);
1071
1072extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index);
1073extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable);
1074extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi);
1075extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz,
1076 u16 max_val, bool iqcalmode);
1077
1078extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan,
1079 u8 *max_pwr, u8 rate_id);
1080extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
1081 u8 rate_mcs_end,
1082 u8 rate_ofdm_start);
1083extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power,
1084 u8 rate_ofdm_start,
1085 u8 rate_ofdm_end,
1086 u8 rate_mcs_start);
1087
1088extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode);
1089extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode);
1090extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode);
1091extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode);
1092extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi);
1093extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel);
1094extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode);
1095extern void wlc_2064_vco_cal(struct brcms_phy *pi);
1096
1097extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi);
1098
1099#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18
1100#define LCNPHY_TX_POWER_TABLE_SIZE 128
1101#define LCNPHY_MAX_TX_POWER_INDEX (LCNPHY_TX_POWER_TABLE_SIZE - 1)
1102#define LCNPHY_TBL_ID_TXPWRCTL 0x07
1103#define LCNPHY_TX_PWR_CTRL_OFF 0
1104#define LCNPHY_TX_PWR_CTRL_SW (0x1 << 15)
1105#define LCNPHY_TX_PWR_CTRL_HW ((0x1 << 15) | \
1106 (0x1 << 14) | \
1107 (0x1 << 13))
1108
1109#define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001
1110
1111extern void wlc_lcnphy_write_table(struct brcms_phy *pi,
1112 const struct phytbl_info *pti);
1113extern void wlc_lcnphy_read_table(struct brcms_phy *pi,
1114 struct phytbl_info *pti);
1115extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b);
1116extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq);
1117extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b);
1118extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi);
1119extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0,
1120 u8 *eq0, u8 *fi0, u8 *fq0);
1121extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode);
1122extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode);
1123extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi);
1124extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi);
1125extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1);
1126extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr,
1127 s8 *cck_pwr);
1128extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi);
1129
1130extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index);
1131
1132#define NPHY_MAX_HPVGA1_INDEX 10
1133#define NPHY_DEF_HPVGA1_INDEXLIMIT 7
1134
1135struct phy_iq_est {
1136 s32 iq_prod;
1137 u32 i_pwr;
1138 u32 q_pwr;
1139};
1140
1141extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi,
1142 bool enable);
1143extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode);
1144
1145#define wlc_phy_write_table_nphy(pi, pti) wlc_phy_write_table(pi, pti, 0x72, \
1146 0x74, 0x73)
1147#define wlc_phy_read_table_nphy(pi, pti) wlc_phy_read_table(pi, pti, 0x72, \
1148 0x74, 0x73)
1149#define wlc_nphy_table_addr(pi, id, off) wlc_phy_table_addr((pi), (id), (off), \
1150 0x72, 0x74, 0x73)
1151#define wlc_nphy_table_data_write(pi, w, v) wlc_phy_table_data_write((pi), (w), (v))
1152
1153extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o,
1154 u32 w, void *d);
1155extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32,
1156 u32, const void *);
1157
1158#define PHY_IPA(pi) \
1159 ((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
1160 (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
1161
1162#define BRCMS_PHY_WAR_PR51571(pi) \
1163 if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \
1164 (void)R_REG(&(pi)->regs->maccontrol)
1165
1166extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype);
1167extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi);
1168extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en);
1169
1170extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan);
1171extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on);
1172
1173extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi);
1174
1175extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd);
1176extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi);
1177
1178extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val);
1179
1180extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
1181 u16 num_samps, u8 wait_time,
1182 u8 wait_for_crs);
1183
1184extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
1185 struct nphy_iq_comp *comp);
1186extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi);
1187
1188extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih,
1189 u8 rxcore_bitmask);
1190extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih);
1191
1192extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type);
1193extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi);
1194extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi);
1195extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi);
1196extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi);
1197
1198extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi);
1199extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi,
1200 struct nphy_txgains target_gain,
1201 bool full, bool m);
1202extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi,
1203 struct nphy_txgains target_gain,
1204 u8 type, bool d);
1205extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask,
1206 s8 txpwrindex, bool res);
1207extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type);
1208extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type,
1209 s32 *rssi_buf, u8 nsamps);
1210extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi);
1211extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi);
1212extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi,
1213 s32 dBm_targetpower, bool debug);
1214extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
1215 u8 mode, u8, bool);
1216extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi);
1217extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf,
1218 u8 num_samps);
1219extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi);
1220
1221extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi,
1222 struct brcms_d11rxhdr *wlc_rxh);
1223
1224#define NPHY_TESTPATTERN_BPHY_EVM 0
1225#define NPHY_TESTPATTERN_BPHY_RFCS 1
1226
1227extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs);
1228
1229void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset,
1230 s8 *ofdmoffset);
1231extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi,
1232 chanspec_t chanspec);
1233
1234extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih);
1235#endif /* _BRCM_PHY_INT_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c
new file mode 100644
index 00000000000..6a3fbe67302
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -0,0 +1,5294 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/delay.h>
18
19#include <pmu.h>
20#include <d11.h>
21#include <phy_shim.h>
22#include "phy_qmath.h"
23#include "phy_hal.h"
24#include "phy_radio.h"
25#include "phytbl_lcn.h"
26#include "phy_lcn.h"
27
28#define PLL_2064_NDIV 90
29#define PLL_2064_LOW_END_VCO 3000
30#define PLL_2064_LOW_END_KVCO 27
31#define PLL_2064_HIGH_END_VCO 4200
32#define PLL_2064_HIGH_END_KVCO 68
33#define PLL_2064_LOOP_BW_DOUBLER 200
34#define PLL_2064_D30_DOUBLER 10500
35#define PLL_2064_LOOP_BW 260
36#define PLL_2064_D30 8000
37#define PLL_2064_CAL_REF_TO 8
38#define PLL_2064_MHZ 1000000
39#define PLL_2064_OPEN_LOOP_DELAY 5
40
41#define TEMPSENSE 1
42#define VBATSENSE 2
43
44#define NOISE_IF_UPD_CHK_INTERVAL 1
45#define NOISE_IF_UPD_RST_INTERVAL 60
46#define NOISE_IF_UPD_THRESHOLD_CNT 1
47#define NOISE_IF_UPD_TRHRESHOLD 50
48#define NOISE_IF_UPD_TIMEOUT 1000
49#define NOISE_IF_OFF 0
50#define NOISE_IF_CHK 1
51#define NOISE_IF_ON 2
52
53#define PAPD_BLANKING_PROFILE 3
54#define PAPD2LUT 0
55#define PAPD_CORR_NORM 0
56#define PAPD_BLANKING_THRESHOLD 0
57#define PAPD_STOP_AFTER_LAST_UPDATE 0
58
59#define LCN_TARGET_PWR 60
60
61#define LCN_VBAT_OFFSET_433X 34649679
62#define LCN_VBAT_SLOPE_433X 8258032
63
64#define LCN_VBAT_SCALE_NOM 53
65#define LCN_VBAT_SCALE_DEN 432
66
67#define LCN_TEMPSENSE_OFFSET 80812
68#define LCN_TEMPSENSE_DEN 2647
69
70#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \
71 (0 + 8)
72#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \
73 (0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT)
74
75#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \
76 (0 + 8)
77#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \
78 (0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT)
79
80#define wlc_lcnphy_enable_tx_gain_override(pi) \
81 wlc_lcnphy_set_tx_gain_override(pi, true)
82#define wlc_lcnphy_disable_tx_gain_override(pi) \
83 wlc_lcnphy_set_tx_gain_override(pi, false)
84
85#define wlc_lcnphy_iqcal_active(pi) \
86 (read_phy_reg((pi), 0x451) & \
87 ((0x1 << 15) | (0x1 << 14)))
88
89#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13))
90#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \
91 (pi->temppwrctrl_capable)
92#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \
93 (pi->hwpwrctrl_capable)
94
95#define SWCTRL_BT_TX 0x18
96#define SWCTRL_OVR_DISABLE 0x40
97
98#define AFE_CLK_INIT_MODE_TXRX2X 1
99#define AFE_CLK_INIT_MODE_PAPD 0
100
101#define LCNPHY_TBL_ID_IQLOCAL 0x00
102
103#define LCNPHY_TBL_ID_RFSEQ 0x08
104#define LCNPHY_TBL_ID_GAIN_IDX 0x0d
105#define LCNPHY_TBL_ID_SW_CTRL 0x0f
106#define LCNPHY_TBL_ID_GAIN_TBL 0x12
107#define LCNPHY_TBL_ID_SPUR 0x14
108#define LCNPHY_TBL_ID_SAMPLEPLAY 0x15
109#define LCNPHY_TBL_ID_SAMPLEPLAY1 0x16
110
111#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 832
112#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 128
113#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 192
114#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET 320
115#define LCNPHY_TX_PWR_CTRL_LO_OFFSET 448
116#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET 576
117
118#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313 140
119
120#define LCNPHY_TX_PWR_CTRL_START_NPT 1
121#define LCNPHY_TX_PWR_CTRL_MAX_NPT 7
122
123#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000
124
125#define LCNPHY_ACI_DETECT_START 1
126#define LCNPHY_ACI_DETECT_PROGRESS 2
127#define LCNPHY_ACI_DETECT_STOP 3
128
129#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100
130#define LCNPHY_ACI_GLITCH_TRSH 2000
131#define LCNPHY_ACI_TMOUT 250
132#define LCNPHY_ACI_DETECT_TIMEOUT 2
133#define LCNPHY_ACI_START_DELAY 0
134
135#define wlc_lcnphy_tx_gain_override_enabled(pi) \
136 (0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6)))
137
138#define wlc_lcnphy_total_tx_frames(pi) \
139 wlapi_bmac_read_shm((pi)->sh->physhim, \
140 M_UCODE_MACSTAT + offsetof(struct macstat, txallfrm))
141
142struct lcnphy_txgains {
143 u16 gm_gain;
144 u16 pga_gain;
145 u16 pad_gain;
146 u16 dac_gain;
147};
148
149enum lcnphy_cal_mode {
150 LCNPHY_CAL_FULL,
151 LCNPHY_CAL_RECAL,
152 LCNPHY_CAL_CURRECAL,
153 LCNPHY_CAL_DIGCAL,
154 LCNPHY_CAL_GCTRL
155};
156
157struct lcnphy_rx_iqcomp {
158 u8 chan;
159 s16 a;
160 s16 b;
161};
162
163struct lcnphy_spb_tone {
164 s16 re;
165 s16 im;
166};
167
168struct lcnphy_unsign16_struct {
169 u16 re;
170 u16 im;
171};
172
173struct lcnphy_iq_est {
174 u32 iq_prod;
175 u32 i_pwr;
176 u32 q_pwr;
177};
178
179struct lcnphy_sfo_cfg {
180 u16 ptcentreTs20;
181 u16 ptcentreFactor;
182};
183
184enum lcnphy_papd_cal_type {
185 LCNPHY_PAPD_CAL_CW,
186 LCNPHY_PAPD_CAL_OFDM
187};
188
189typedef u16 iqcal_gain_params_lcnphy[9];
190
191static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = {
192 {0, 0, 0, 0, 0, 0, 0, 0, 0},
193};
194
195static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
196 tbl_iqcal_gainparams_lcnphy_2G,
197};
198
199static const u16 iqcal_gainparams_numgains_lcnphy[1] = {
200 sizeof(tbl_iqcal_gainparams_lcnphy_2G) /
201 sizeof(*tbl_iqcal_gainparams_lcnphy_2G),
202};
203
204static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = {
205 {965, 1087},
206 {967, 1085},
207 {969, 1082},
208 {971, 1080},
209 {973, 1078},
210 {975, 1076},
211 {977, 1073},
212 {979, 1071},
213 {981, 1069},
214 {983, 1067},
215 {985, 1065},
216 {987, 1063},
217 {989, 1060},
218 {994, 1055}
219};
220
221static const
222u16 lcnphy_iqcal_loft_gainladder[] = {
223 ((2 << 8) | 0),
224 ((3 << 8) | 0),
225 ((4 << 8) | 0),
226 ((6 << 8) | 0),
227 ((8 << 8) | 0),
228 ((11 << 8) | 0),
229 ((16 << 8) | 0),
230 ((16 << 8) | 1),
231 ((16 << 8) | 2),
232 ((16 << 8) | 3),
233 ((16 << 8) | 4),
234 ((16 << 8) | 5),
235 ((16 << 8) | 6),
236 ((16 << 8) | 7),
237 ((23 << 8) | 7),
238 ((32 << 8) | 7),
239 ((45 << 8) | 7),
240 ((64 << 8) | 7),
241 ((91 << 8) | 7),
242 ((128 << 8) | 7)
243};
244
245static const
246u16 lcnphy_iqcal_ir_gainladder[] = {
247 ((1 << 8) | 0),
248 ((2 << 8) | 0),
249 ((4 << 8) | 0),
250 ((6 << 8) | 0),
251 ((8 << 8) | 0),
252 ((11 << 8) | 0),
253 ((16 << 8) | 0),
254 ((23 << 8) | 0),
255 ((32 << 8) | 0),
256 ((45 << 8) | 0),
257 ((64 << 8) | 0),
258 ((64 << 8) | 1),
259 ((64 << 8) | 2),
260 ((64 << 8) | 3),
261 ((64 << 8) | 4),
262 ((64 << 8) | 5),
263 ((64 << 8) | 6),
264 ((64 << 8) | 7),
265 ((91 << 8) | 7),
266 ((128 << 8) | 7)
267};
268
269static const
270struct lcnphy_spb_tone lcnphy_spb_tone_3750[] = {
271 {88, 0},
272 {73, 49},
273 {34, 81},
274 {-17, 86},
275 {-62, 62},
276 {-86, 17},
277 {-81, -34},
278 {-49, -73},
279 {0, -88},
280 {49, -73},
281 {81, -34},
282 {86, 17},
283 {62, 62},
284 {17, 86},
285 {-34, 81},
286 {-73, 49},
287 {-88, 0},
288 {-73, -49},
289 {-34, -81},
290 {17, -86},
291 {62, -62},
292 {86, -17},
293 {81, 34},
294 {49, 73},
295 {0, 88},
296 {-49, 73},
297 {-81, 34},
298 {-86, -17},
299 {-62, -62},
300 {-17, -86},
301 {34, -81},
302 {73, -49},
303};
304
305static const
306u16 iqlo_loopback_rf_regs[20] = {
307 RADIO_2064_REG036,
308 RADIO_2064_REG11A,
309 RADIO_2064_REG03A,
310 RADIO_2064_REG025,
311 RADIO_2064_REG028,
312 RADIO_2064_REG005,
313 RADIO_2064_REG112,
314 RADIO_2064_REG0FF,
315 RADIO_2064_REG11F,
316 RADIO_2064_REG00B,
317 RADIO_2064_REG113,
318 RADIO_2064_REG007,
319 RADIO_2064_REG0FC,
320 RADIO_2064_REG0FD,
321 RADIO_2064_REG012,
322 RADIO_2064_REG057,
323 RADIO_2064_REG059,
324 RADIO_2064_REG05C,
325 RADIO_2064_REG078,
326 RADIO_2064_REG092,
327};
328
329static const
330u16 tempsense_phy_regs[14] = {
331 0x503,
332 0x4a4,
333 0x4d0,
334 0x4d9,
335 0x4da,
336 0x4a6,
337 0x938,
338 0x939,
339 0x4d8,
340 0x4d0,
341 0x4d7,
342 0x4a5,
343 0x40d,
344 0x4a2,
345};
346
347static const
348u16 rxiq_cal_rf_reg[11] = {
349 RADIO_2064_REG098,
350 RADIO_2064_REG116,
351 RADIO_2064_REG12C,
352 RADIO_2064_REG06A,
353 RADIO_2064_REG00B,
354 RADIO_2064_REG01B,
355 RADIO_2064_REG113,
356 RADIO_2064_REG01D,
357 RADIO_2064_REG114,
358 RADIO_2064_REG02E,
359 RADIO_2064_REG12A,
360};
361
362static const
363struct lcnphy_rx_iqcomp lcnphy_rx_iqcomp_table_rev0[] = {
364 {1, 0, 0},
365 {2, 0, 0},
366 {3, 0, 0},
367 {4, 0, 0},
368 {5, 0, 0},
369 {6, 0, 0},
370 {7, 0, 0},
371 {8, 0, 0},
372 {9, 0, 0},
373 {10, 0, 0},
374 {11, 0, 0},
375 {12, 0, 0},
376 {13, 0, 0},
377 {14, 0, 0},
378 {34, 0, 0},
379 {38, 0, 0},
380 {42, 0, 0},
381 {46, 0, 0},
382 {36, 0, 0},
383 {40, 0, 0},
384 {44, 0, 0},
385 {48, 0, 0},
386 {52, 0, 0},
387 {56, 0, 0},
388 {60, 0, 0},
389 {64, 0, 0},
390 {100, 0, 0},
391 {104, 0, 0},
392 {108, 0, 0},
393 {112, 0, 0},
394 {116, 0, 0},
395 {120, 0, 0},
396 {124, 0, 0},
397 {128, 0, 0},
398 {132, 0, 0},
399 {136, 0, 0},
400 {140, 0, 0},
401 {149, 0, 0},
402 {153, 0, 0},
403 {157, 0, 0},
404 {161, 0, 0},
405 {165, 0, 0},
406 {184, 0, 0},
407 {188, 0, 0},
408 {192, 0, 0},
409 {196, 0, 0},
410 {200, 0, 0},
411 {204, 0, 0},
412 {208, 0, 0},
413 {212, 0, 0},
414 {216, 0, 0},
415};
416
417static const u32 lcnphy_23bitgaincode_table[] = {
418 0x200100,
419 0x200200,
420 0x200004,
421 0x200014,
422 0x200024,
423 0x200034,
424 0x200134,
425 0x200234,
426 0x200334,
427 0x200434,
428 0x200037,
429 0x200137,
430 0x200237,
431 0x200337,
432 0x200437,
433 0x000035,
434 0x000135,
435 0x000235,
436 0x000037,
437 0x000137,
438 0x000237,
439 0x000337,
440 0x00013f,
441 0x00023f,
442 0x00033f,
443 0x00034f,
444 0x00044f,
445 0x00144f,
446 0x00244f,
447 0x00254f,
448 0x00354f,
449 0x00454f,
450 0x00464f,
451 0x01464f,
452 0x02464f,
453 0x03464f,
454 0x04464f,
455};
456
457static const s8 lcnphy_gain_table[] = {
458 -16,
459 -13,
460 10,
461 7,
462 4,
463 0,
464 3,
465 6,
466 9,
467 12,
468 15,
469 18,
470 21,
471 24,
472 27,
473 30,
474 33,
475 36,
476 39,
477 42,
478 45,
479 48,
480 50,
481 53,
482 56,
483 59,
484 62,
485 65,
486 68,
487 71,
488 74,
489 77,
490 80,
491 83,
492 86,
493 89,
494 92,
495};
496
497static const s8 lcnphy_gain_index_offset_for_rssi[] = {
498 7,
499 7,
500 7,
501 7,
502 7,
503 7,
504 7,
505 8,
506 7,
507 7,
508 6,
509 7,
510 7,
511 4,
512 4,
513 4,
514 4,
515 4,
516 4,
517 4,
518 4,
519 3,
520 3,
521 3,
522 3,
523 3,
524 3,
525 4,
526 2,
527 2,
528 2,
529 2,
530 2,
531 2,
532 -1,
533 -2,
534 -2,
535 -2
536};
537
538struct chan_info_2064_lcnphy {
539 uint chan;
540 uint freq;
541 u8 logen_buftune;
542 u8 logen_rccr_tx;
543 u8 txrf_mix_tune_ctrl;
544 u8 pa_input_tune_g;
545 u8 logen_rccr_rx;
546 u8 pa_rxrf_lna1_freq_tune;
547 u8 pa_rxrf_lna2_freq_tune;
548 u8 rxrf_rxrf_spare1;
549};
550
551static struct chan_info_2064_lcnphy chan_info_2064_lcnphy[] = {
552 {1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
553 {2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
554 {3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
555 {4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
556 {5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
557 {6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
558 {7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
559 {8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
560 {9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
561 {10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
562 {11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
563 {12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
564 {13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
565 {14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
566};
567
568struct lcnphy_radio_regs lcnphy_radio_regs_2064[] = {
569 {0x00, 0, 0, 0, 0},
570 {0x01, 0x64, 0x64, 0, 0},
571 {0x02, 0x20, 0x20, 0, 0},
572 {0x03, 0x66, 0x66, 0, 0},
573 {0x04, 0xf8, 0xf8, 0, 0},
574 {0x05, 0, 0, 0, 0},
575 {0x06, 0x10, 0x10, 0, 0},
576 {0x07, 0, 0, 0, 0},
577 {0x08, 0, 0, 0, 0},
578 {0x09, 0, 0, 0, 0},
579 {0x0A, 0x37, 0x37, 0, 0},
580 {0x0B, 0x6, 0x6, 0, 0},
581 {0x0C, 0x55, 0x55, 0, 0},
582 {0x0D, 0x8b, 0x8b, 0, 0},
583 {0x0E, 0, 0, 0, 0},
584 {0x0F, 0x5, 0x5, 0, 0},
585 {0x10, 0, 0, 0, 0},
586 {0x11, 0xe, 0xe, 0, 0},
587 {0x12, 0, 0, 0, 0},
588 {0x13, 0xb, 0xb, 0, 0},
589 {0x14, 0x2, 0x2, 0, 0},
590 {0x15, 0x12, 0x12, 0, 0},
591 {0x16, 0x12, 0x12, 0, 0},
592 {0x17, 0xc, 0xc, 0, 0},
593 {0x18, 0xc, 0xc, 0, 0},
594 {0x19, 0xc, 0xc, 0, 0},
595 {0x1A, 0x8, 0x8, 0, 0},
596 {0x1B, 0x2, 0x2, 0, 0},
597 {0x1C, 0, 0, 0, 0},
598 {0x1D, 0x1, 0x1, 0, 0},
599 {0x1E, 0x12, 0x12, 0, 0},
600 {0x1F, 0x6e, 0x6e, 0, 0},
601 {0x20, 0x2, 0x2, 0, 0},
602 {0x21, 0x23, 0x23, 0, 0},
603 {0x22, 0x8, 0x8, 0, 0},
604 {0x23, 0, 0, 0, 0},
605 {0x24, 0, 0, 0, 0},
606 {0x25, 0xc, 0xc, 0, 0},
607 {0x26, 0x33, 0x33, 0, 0},
608 {0x27, 0x55, 0x55, 0, 0},
609 {0x28, 0, 0, 0, 0},
610 {0x29, 0x30, 0x30, 0, 0},
611 {0x2A, 0xb, 0xb, 0, 0},
612 {0x2B, 0x1b, 0x1b, 0, 0},
613 {0x2C, 0x3, 0x3, 0, 0},
614 {0x2D, 0x1b, 0x1b, 0, 0},
615 {0x2E, 0, 0, 0, 0},
616 {0x2F, 0x20, 0x20, 0, 0},
617 {0x30, 0xa, 0xa, 0, 0},
618 {0x31, 0, 0, 0, 0},
619 {0x32, 0x62, 0x62, 0, 0},
620 {0x33, 0x19, 0x19, 0, 0},
621 {0x34, 0x33, 0x33, 0, 0},
622 {0x35, 0x77, 0x77, 0, 0},
623 {0x36, 0, 0, 0, 0},
624 {0x37, 0x70, 0x70, 0, 0},
625 {0x38, 0x3, 0x3, 0, 0},
626 {0x39, 0xf, 0xf, 0, 0},
627 {0x3A, 0x6, 0x6, 0, 0},
628 {0x3B, 0xcf, 0xcf, 0, 0},
629 {0x3C, 0x1a, 0x1a, 0, 0},
630 {0x3D, 0x6, 0x6, 0, 0},
631 {0x3E, 0x42, 0x42, 0, 0},
632 {0x3F, 0, 0, 0, 0},
633 {0x40, 0xfb, 0xfb, 0, 0},
634 {0x41, 0x9a, 0x9a, 0, 0},
635 {0x42, 0x7a, 0x7a, 0, 0},
636 {0x43, 0x29, 0x29, 0, 0},
637 {0x44, 0, 0, 0, 0},
638 {0x45, 0x8, 0x8, 0, 0},
639 {0x46, 0xce, 0xce, 0, 0},
640 {0x47, 0x27, 0x27, 0, 0},
641 {0x48, 0x62, 0x62, 0, 0},
642 {0x49, 0x6, 0x6, 0, 0},
643 {0x4A, 0x58, 0x58, 0, 0},
644 {0x4B, 0xf7, 0xf7, 0, 0},
645 {0x4C, 0, 0, 0, 0},
646 {0x4D, 0xb3, 0xb3, 0, 0},
647 {0x4E, 0, 0, 0, 0},
648 {0x4F, 0x2, 0x2, 0, 0},
649 {0x50, 0, 0, 0, 0},
650 {0x51, 0x9, 0x9, 0, 0},
651 {0x52, 0x5, 0x5, 0, 0},
652 {0x53, 0x17, 0x17, 0, 0},
653 {0x54, 0x38, 0x38, 0, 0},
654 {0x55, 0, 0, 0, 0},
655 {0x56, 0, 0, 0, 0},
656 {0x57, 0xb, 0xb, 0, 0},
657 {0x58, 0, 0, 0, 0},
658 {0x59, 0, 0, 0, 0},
659 {0x5A, 0, 0, 0, 0},
660 {0x5B, 0, 0, 0, 0},
661 {0x5C, 0, 0, 0, 0},
662 {0x5D, 0, 0, 0, 0},
663 {0x5E, 0x88, 0x88, 0, 0},
664 {0x5F, 0xcc, 0xcc, 0, 0},
665 {0x60, 0x74, 0x74, 0, 0},
666 {0x61, 0x74, 0x74, 0, 0},
667 {0x62, 0x74, 0x74, 0, 0},
668 {0x63, 0x44, 0x44, 0, 0},
669 {0x64, 0x77, 0x77, 0, 0},
670 {0x65, 0x44, 0x44, 0, 0},
671 {0x66, 0x77, 0x77, 0, 0},
672 {0x67, 0x55, 0x55, 0, 0},
673 {0x68, 0x77, 0x77, 0, 0},
674 {0x69, 0x77, 0x77, 0, 0},
675 {0x6A, 0, 0, 0, 0},
676 {0x6B, 0x7f, 0x7f, 0, 0},
677 {0x6C, 0x8, 0x8, 0, 0},
678 {0x6D, 0, 0, 0, 0},
679 {0x6E, 0x88, 0x88, 0, 0},
680 {0x6F, 0x66, 0x66, 0, 0},
681 {0x70, 0x66, 0x66, 0, 0},
682 {0x71, 0x28, 0x28, 0, 0},
683 {0x72, 0x55, 0x55, 0, 0},
684 {0x73, 0x4, 0x4, 0, 0},
685 {0x74, 0, 0, 0, 0},
686 {0x75, 0, 0, 0, 0},
687 {0x76, 0, 0, 0, 0},
688 {0x77, 0x1, 0x1, 0, 0},
689 {0x78, 0xd6, 0xd6, 0, 0},
690 {0x79, 0, 0, 0, 0},
691 {0x7A, 0, 0, 0, 0},
692 {0x7B, 0, 0, 0, 0},
693 {0x7C, 0, 0, 0, 0},
694 {0x7D, 0, 0, 0, 0},
695 {0x7E, 0, 0, 0, 0},
696 {0x7F, 0, 0, 0, 0},
697 {0x80, 0, 0, 0, 0},
698 {0x81, 0, 0, 0, 0},
699 {0x82, 0, 0, 0, 0},
700 {0x83, 0xb4, 0xb4, 0, 0},
701 {0x84, 0x1, 0x1, 0, 0},
702 {0x85, 0x20, 0x20, 0, 0},
703 {0x86, 0x5, 0x5, 0, 0},
704 {0x87, 0xff, 0xff, 0, 0},
705 {0x88, 0x7, 0x7, 0, 0},
706 {0x89, 0x77, 0x77, 0, 0},
707 {0x8A, 0x77, 0x77, 0, 0},
708 {0x8B, 0x77, 0x77, 0, 0},
709 {0x8C, 0x77, 0x77, 0, 0},
710 {0x8D, 0x8, 0x8, 0, 0},
711 {0x8E, 0xa, 0xa, 0, 0},
712 {0x8F, 0x8, 0x8, 0, 0},
713 {0x90, 0x18, 0x18, 0, 0},
714 {0x91, 0x5, 0x5, 0, 0},
715 {0x92, 0x1f, 0x1f, 0, 0},
716 {0x93, 0x10, 0x10, 0, 0},
717 {0x94, 0x3, 0x3, 0, 0},
718 {0x95, 0, 0, 0, 0},
719 {0x96, 0, 0, 0, 0},
720 {0x97, 0xaa, 0xaa, 0, 0},
721 {0x98, 0, 0, 0, 0},
722 {0x99, 0x23, 0x23, 0, 0},
723 {0x9A, 0x7, 0x7, 0, 0},
724 {0x9B, 0xf, 0xf, 0, 0},
725 {0x9C, 0x10, 0x10, 0, 0},
726 {0x9D, 0x3, 0x3, 0, 0},
727 {0x9E, 0x4, 0x4, 0, 0},
728 {0x9F, 0x20, 0x20, 0, 0},
729 {0xA0, 0, 0, 0, 0},
730 {0xA1, 0, 0, 0, 0},
731 {0xA2, 0, 0, 0, 0},
732 {0xA3, 0, 0, 0, 0},
733 {0xA4, 0x1, 0x1, 0, 0},
734 {0xA5, 0x77, 0x77, 0, 0},
735 {0xA6, 0x77, 0x77, 0, 0},
736 {0xA7, 0x77, 0x77, 0, 0},
737 {0xA8, 0x77, 0x77, 0, 0},
738 {0xA9, 0x8c, 0x8c, 0, 0},
739 {0xAA, 0x88, 0x88, 0, 0},
740 {0xAB, 0x78, 0x78, 0, 0},
741 {0xAC, 0x57, 0x57, 0, 0},
742 {0xAD, 0x88, 0x88, 0, 0},
743 {0xAE, 0, 0, 0, 0},
744 {0xAF, 0x8, 0x8, 0, 0},
745 {0xB0, 0x88, 0x88, 0, 0},
746 {0xB1, 0, 0, 0, 0},
747 {0xB2, 0x1b, 0x1b, 0, 0},
748 {0xB3, 0x3, 0x3, 0, 0},
749 {0xB4, 0x24, 0x24, 0, 0},
750 {0xB5, 0x3, 0x3, 0, 0},
751 {0xB6, 0x1b, 0x1b, 0, 0},
752 {0xB7, 0x24, 0x24, 0, 0},
753 {0xB8, 0x3, 0x3, 0, 0},
754 {0xB9, 0, 0, 0, 0},
755 {0xBA, 0xaa, 0xaa, 0, 0},
756 {0xBB, 0, 0, 0, 0},
757 {0xBC, 0x4, 0x4, 0, 0},
758 {0xBD, 0, 0, 0, 0},
759 {0xBE, 0x8, 0x8, 0, 0},
760 {0xBF, 0x11, 0x11, 0, 0},
761 {0xC0, 0, 0, 0, 0},
762 {0xC1, 0, 0, 0, 0},
763 {0xC2, 0x62, 0x62, 0, 0},
764 {0xC3, 0x1e, 0x1e, 0, 0},
765 {0xC4, 0x33, 0x33, 0, 0},
766 {0xC5, 0x37, 0x37, 0, 0},
767 {0xC6, 0, 0, 0, 0},
768 {0xC7, 0x70, 0x70, 0, 0},
769 {0xC8, 0x1e, 0x1e, 0, 0},
770 {0xC9, 0x6, 0x6, 0, 0},
771 {0xCA, 0x4, 0x4, 0, 0},
772 {0xCB, 0x2f, 0x2f, 0, 0},
773 {0xCC, 0xf, 0xf, 0, 0},
774 {0xCD, 0, 0, 0, 0},
775 {0xCE, 0xff, 0xff, 0, 0},
776 {0xCF, 0x8, 0x8, 0, 0},
777 {0xD0, 0x3f, 0x3f, 0, 0},
778 {0xD1, 0x3f, 0x3f, 0, 0},
779 {0xD2, 0x3f, 0x3f, 0, 0},
780 {0xD3, 0, 0, 0, 0},
781 {0xD4, 0, 0, 0, 0},
782 {0xD5, 0, 0, 0, 0},
783 {0xD6, 0xcc, 0xcc, 0, 0},
784 {0xD7, 0, 0, 0, 0},
785 {0xD8, 0x8, 0x8, 0, 0},
786 {0xD9, 0x8, 0x8, 0, 0},
787 {0xDA, 0x8, 0x8, 0, 0},
788 {0xDB, 0x11, 0x11, 0, 0},
789 {0xDC, 0, 0, 0, 0},
790 {0xDD, 0x87, 0x87, 0, 0},
791 {0xDE, 0x88, 0x88, 0, 0},
792 {0xDF, 0x8, 0x8, 0, 0},
793 {0xE0, 0x8, 0x8, 0, 0},
794 {0xE1, 0x8, 0x8, 0, 0},
795 {0xE2, 0, 0, 0, 0},
796 {0xE3, 0, 0, 0, 0},
797 {0xE4, 0, 0, 0, 0},
798 {0xE5, 0xf5, 0xf5, 0, 0},
799 {0xE6, 0x30, 0x30, 0, 0},
800 {0xE7, 0x1, 0x1, 0, 0},
801 {0xE8, 0, 0, 0, 0},
802 {0xE9, 0xff, 0xff, 0, 0},
803 {0xEA, 0, 0, 0, 0},
804 {0xEB, 0, 0, 0, 0},
805 {0xEC, 0x22, 0x22, 0, 0},
806 {0xED, 0, 0, 0, 0},
807 {0xEE, 0, 0, 0, 0},
808 {0xEF, 0, 0, 0, 0},
809 {0xF0, 0x3, 0x3, 0, 0},
810 {0xF1, 0x1, 0x1, 0, 0},
811 {0xF2, 0, 0, 0, 0},
812 {0xF3, 0, 0, 0, 0},
813 {0xF4, 0, 0, 0, 0},
814 {0xF5, 0, 0, 0, 0},
815 {0xF6, 0, 0, 0, 0},
816 {0xF7, 0x6, 0x6, 0, 0},
817 {0xF8, 0, 0, 0, 0},
818 {0xF9, 0, 0, 0, 0},
819 {0xFA, 0x40, 0x40, 0, 0},
820 {0xFB, 0, 0, 0, 0},
821 {0xFC, 0x1, 0x1, 0, 0},
822 {0xFD, 0x80, 0x80, 0, 0},
823 {0xFE, 0x2, 0x2, 0, 0},
824 {0xFF, 0x10, 0x10, 0, 0},
825 {0x100, 0x2, 0x2, 0, 0},
826 {0x101, 0x1e, 0x1e, 0, 0},
827 {0x102, 0x1e, 0x1e, 0, 0},
828 {0x103, 0, 0, 0, 0},
829 {0x104, 0x1f, 0x1f, 0, 0},
830 {0x105, 0, 0x8, 0, 1},
831 {0x106, 0x2a, 0x2a, 0, 0},
832 {0x107, 0xf, 0xf, 0, 0},
833 {0x108, 0, 0, 0, 0},
834 {0x109, 0, 0, 0, 0},
835 {0x10A, 0, 0, 0, 0},
836 {0x10B, 0, 0, 0, 0},
837 {0x10C, 0, 0, 0, 0},
838 {0x10D, 0, 0, 0, 0},
839 {0x10E, 0, 0, 0, 0},
840 {0x10F, 0, 0, 0, 0},
841 {0x110, 0, 0, 0, 0},
842 {0x111, 0, 0, 0, 0},
843 {0x112, 0, 0, 0, 0},
844 {0x113, 0, 0, 0, 0},
845 {0x114, 0, 0, 0, 0},
846 {0x115, 0, 0, 0, 0},
847 {0x116, 0, 0, 0, 0},
848 {0x117, 0, 0, 0, 0},
849 {0x118, 0, 0, 0, 0},
850 {0x119, 0, 0, 0, 0},
851 {0x11A, 0, 0, 0, 0},
852 {0x11B, 0, 0, 0, 0},
853 {0x11C, 0x1, 0x1, 0, 0},
854 {0x11D, 0, 0, 0, 0},
855 {0x11E, 0, 0, 0, 0},
856 {0x11F, 0, 0, 0, 0},
857 {0x120, 0, 0, 0, 0},
858 {0x121, 0, 0, 0, 0},
859 {0x122, 0x80, 0x80, 0, 0},
860 {0x123, 0, 0, 0, 0},
861 {0x124, 0xf8, 0xf8, 0, 0},
862 {0x125, 0, 0, 0, 0},
863 {0x126, 0, 0, 0, 0},
864 {0x127, 0, 0, 0, 0},
865 {0x128, 0, 0, 0, 0},
866 {0x129, 0, 0, 0, 0},
867 {0x12A, 0, 0, 0, 0},
868 {0x12B, 0, 0, 0, 0},
869 {0x12C, 0, 0, 0, 0},
870 {0x12D, 0, 0, 0, 0},
871 {0x12E, 0, 0, 0, 0},
872 {0x12F, 0, 0, 0, 0},
873 {0x130, 0, 0, 0, 0},
874 {0xFFFF, 0, 0, 0, 0}
875};
876
877#define LCNPHY_NUM_DIG_FILT_COEFFS 16
878#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13
879
880u16 LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK]
881 [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
882 {0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64,
883 128, 64,},
884 {1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93,
885 167, 93,},
886 {2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64,
887 128, 64,},
888 {3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760,
889 170, 340, 170,},
890 {20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760,
891 256, 185, 256,},
892 {21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760,
893 256, 273, 256,},
894 {22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760,
895 256, 352, 256,},
896 {23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760,
897 128, 233, 128,},
898 {24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256,
899 1881, 256,},
900 {25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256,
901 1881, 256,},
902 {26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128,
903 384, 288,},
904 {27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864,
905 128, 384, 288,},
906 {30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760,
907 170, 340, 170,},
908};
909
910#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3
911u16 LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM]
912 [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
913 {0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0,
914 0x278, 0xfea0, 0x80, 0x100, 0x80,},
915 {1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50,
916 750, 0xFE2B, 212, 0xFFCE, 212,},
917 {2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
918 0xFEF2, 128, 0xFFE2, 128}
919};
920
921#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \
922 mod_phy_reg(pi, 0x4a4, \
923 (0x1ff << 0), \
924 (u16)(idx) << 0)
925
926#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \
927 mod_phy_reg(pi, 0x4a5, \
928 (0x7 << 8), \
929 (u16)(npt) << 8)
930
931#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \
932 (read_phy_reg((pi), 0x4a4) & \
933 ((0x1 << 15) | \
934 (0x1 << 14) | \
935 (0x1 << 13)))
936
937#define wlc_lcnphy_get_tx_pwr_npt(pi) \
938 ((read_phy_reg(pi, 0x4a5) & \
939 (0x7 << 8)) >> \
940 8)
941
942#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \
943 (read_phy_reg(pi, 0x473) & 0x1ff)
944
945#define wlc_lcnphy_get_target_tx_pwr(pi) \
946 ((read_phy_reg(pi, 0x4a7) & \
947 (0xff << 0)) >> \
948 0)
949
950#define wlc_lcnphy_set_target_tx_pwr(pi, target) \
951 mod_phy_reg(pi, 0x4a7, \
952 (0xff << 0), \
953 (u16)(target) << 0)
954
955#define wlc_radio_2064_rcal_done(pi) (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20))
956#define tempsense_done(pi) (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000))
957
958#define LCNPHY_IQLOCC_READ(val) ((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f)))
959#define FIXED_TXPWR 78
960#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val))
961
962static u32 wlc_lcnphy_qdiv_roundup(u32 divident, u32 divisor,
963 u8 precision);
964static void wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
965 u16 ext_lna, u16 trsw,
966 u16 biq2, u16 biq1,
967 u16 tia, u16 lna2,
968 u16 lna1);
969static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi);
970static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain);
971static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx,
972 bool rx);
973static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0);
974static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi);
975static void wlc_lcnphy_get_tx_gain(struct brcms_phy *pi,
976 struct lcnphy_txgains *gains);
977static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable);
978static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi);
979static void wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi,
980 bool enable);
981static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
982 struct lcnphy_txgains *target_gains);
983static bool wlc_lcnphy_rx_iq_est(struct brcms_phy *pi, u16 num_samps,
984 u8 wait_time, struct lcnphy_iq_est *iq_est);
985static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps);
986static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi);
987static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode);
988static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi);
989static void wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi,
990 u8 channel);
991
992static void wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
993 const struct lcnphy_tx_gain_tbl_entry *g);
994
995static void wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo,
996 u16 thresh, s16 *ptr, int mode);
997static int wlc_lcnphy_calc_floor(s16 coeff, int type);
998static void wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi,
999 u16 *values_to_save);
1000static void wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi,
1001 u16 *values_to_save);
1002static void wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x,
1003 s16 coeff_y);
1004static struct lcnphy_unsign16_struct wlc_lcnphy_get_cc(struct brcms_phy *pi,
1005 int cal_type);
1006static void wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type,
1007 int num_levels, int step_size_lg2);
1008static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi);
1009
1010static void wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi,
1011 chanspec_t chanspec);
1012static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi);
1013static void wlc_lcnphy_temp_adj(struct brcms_phy *pi);
1014static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi);
1015static void wlc_lcnphy_baseband_init(struct brcms_phy *pi);
1016static void wlc_lcnphy_radio_init(struct brcms_phy *pi);
1017static void wlc_lcnphy_rc_cal(struct brcms_phy *pi);
1018static void wlc_lcnphy_rcal(struct brcms_phy *pi);
1019static void wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi,
1020 bool enable);
1021static int wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm,
1022 s16 filt_type);
1023static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b);
1024
1025void wlc_lcnphy_write_table(struct brcms_phy *pi, const struct phytbl_info *pti)
1026{
1027 wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456);
1028}
1029
1030void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti)
1031{
1032 wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456);
1033}
1034
1035static void
1036wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id,
1037 const void *tbl_ptr, u32 tbl_len,
1038 u32 tbl_width, u32 tbl_offset)
1039{
1040 struct phytbl_info tab;
1041 tab.tbl_id = tbl_id;
1042 tab.tbl_ptr = tbl_ptr;
1043 tab.tbl_len = tbl_len;
1044 tab.tbl_width = tbl_width;
1045 tab.tbl_offset = tbl_offset;
1046 wlc_lcnphy_read_table(pi, &tab);
1047}
1048
1049static void
1050wlc_lcnphy_common_write_table(struct brcms_phy *pi, u32 tbl_id,
1051 const void *tbl_ptr, u32 tbl_len,
1052 u32 tbl_width, u32 tbl_offset)
1053{
1054
1055 struct phytbl_info tab;
1056 tab.tbl_id = tbl_id;
1057 tab.tbl_ptr = tbl_ptr;
1058 tab.tbl_len = tbl_len;
1059 tab.tbl_width = tbl_width;
1060 tab.tbl_offset = tbl_offset;
1061 wlc_lcnphy_write_table(pi, &tab);
1062}
1063
1064static u32
1065wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
1066{
1067 u32 quotient, remainder, roundup, rbit;
1068
1069 quotient = dividend / divisor;
1070 remainder = dividend % divisor;
1071 rbit = divisor & 1;
1072 roundup = (divisor >> 1) + rbit;
1073
1074 while (precision--) {
1075 quotient <<= 1;
1076 if (remainder >= roundup) {
1077 quotient++;
1078 remainder = ((remainder - roundup) << 1) + rbit;
1079 } else {
1080 remainder <<= 1;
1081 }
1082 }
1083
1084 if (remainder >= roundup)
1085 quotient++;
1086
1087 return quotient;
1088}
1089
1090static int wlc_lcnphy_calc_floor(s16 coeff_x, int type)
1091{
1092 int k;
1093 k = 0;
1094 if (type == 0) {
1095 if (coeff_x < 0) {
1096 k = (coeff_x - 1) / 2;
1097 } else {
1098 k = coeff_x / 2;
1099 }
1100 }
1101 if (type == 1) {
1102 if ((coeff_x + 1) < 0)
1103 k = (coeff_x) / 2;
1104 else
1105 k = (coeff_x + 1) / 2;
1106 }
1107 return k;
1108}
1109
1110s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi)
1111{
1112 s8 index;
1113 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1114
1115 if (txpwrctrl_off(pi))
1116 index = pi_lcn->lcnphy_current_index;
1117 else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
1118 index =
1119 (s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi)
1120 / 2);
1121 else
1122 index = pi_lcn->lcnphy_current_index;
1123 return index;
1124}
1125
1126static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
1127{
1128 struct lcnphy_iq_est iq_est = { 0, 0, 0 };
1129
1130 if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est))
1131 return 0;
1132 return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
1133}
1134
1135void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel)
1136{
1137 u16 afectrlovr, afectrlovrval;
1138 afectrlovr = read_phy_reg(pi, 0x43b);
1139 afectrlovrval = read_phy_reg(pi, 0x43c);
1140 if (channel != 0) {
1141 mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1);
1142
1143 mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1);
1144
1145 mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4);
1146
1147 mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6);
1148
1149 write_phy_reg(pi, 0x44b, 0xffff);
1150 wlc_lcnphy_tx_pu(pi, 1);
1151
1152 mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8);
1153
1154 or_phy_reg(pi, 0x6da, 0x0080);
1155
1156 or_phy_reg(pi, 0x00a, 0x228);
1157 } else {
1158 and_phy_reg(pi, 0x00a, ~(0x228));
1159
1160 and_phy_reg(pi, 0x6da, 0xFF7F);
1161 write_phy_reg(pi, 0x43b, afectrlovr);
1162 write_phy_reg(pi, 0x43c, afectrlovrval);
1163 }
1164}
1165
1166static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi)
1167{
1168 u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr;
1169
1170 save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c);
1171 save_AfeCtrlOvr = read_phy_reg(pi, 0x43b);
1172
1173 write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1);
1174 write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1);
1175
1176 write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe);
1177 write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe);
1178
1179 write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal);
1180 write_phy_reg(pi, 0x43b, save_AfeCtrlOvr);
1181}
1182
1183static void
1184wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, bool enable)
1185{
1186 if (enable) {
1187 write_phy_reg(pi, 0x942, 0x7);
1188 write_phy_reg(pi, 0x93b, ((1 << 13) + 23));
1189 write_phy_reg(pi, 0x93c, ((1 << 13) + 1989));
1190
1191 write_phy_reg(pi, 0x44a, 0x084);
1192 write_phy_reg(pi, 0x44a, 0x080);
1193 write_phy_reg(pi, 0x6d3, 0x2222);
1194 write_phy_reg(pi, 0x6d3, 0x2220);
1195 } else {
1196 write_phy_reg(pi, 0x942, 0x0);
1197 write_phy_reg(pi, 0x93b, ((0 << 13) + 23));
1198 write_phy_reg(pi, 0x93c, ((0 << 13) + 1989));
1199 }
1200 wlapi_switch_macfreq(pi->sh->physhim, enable);
1201}
1202
1203void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, chanspec_t chanspec)
1204{
1205 u8 channel = CHSPEC_CHANNEL(chanspec);
1206
1207 wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
1208
1209 wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
1210
1211 or_phy_reg(pi, 0x44a, 0x44);
1212 write_phy_reg(pi, 0x44a, 0x80);
1213
1214 if (!NORADIO_ENAB(pi->pubpi)) {
1215 wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
1216 udelay(1000);
1217 }
1218
1219 wlc_lcnphy_toggle_afe_pwdn(pi);
1220
1221 write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
1222 write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
1223
1224 if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
1225 mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
1226
1227 wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
1228 } else {
1229 mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
1230
1231 wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
1232 }
1233
1234 wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
1235
1236 mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
1237
1238}
1239
1240static void wlc_lcnphy_set_dac_gain(struct brcms_phy *pi, u16 dac_gain)
1241{
1242 u16 dac_ctrl;
1243
1244 dac_ctrl = (read_phy_reg(pi, 0x439) >> 0);
1245 dac_ctrl = dac_ctrl & 0xc7f;
1246 dac_ctrl = dac_ctrl | (dac_gain << 7);
1247 mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0);
1248
1249}
1250
1251static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable)
1252{
1253 u16 bit = bEnable ? 1 : 0;
1254
1255 mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7);
1256
1257 mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14);
1258
1259 mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6);
1260}
1261
1262static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi)
1263{
1264 u16 pa_gain;
1265
1266 pa_gain = (read_phy_reg(pi, 0x4fb) &
1267 LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >>
1268 LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT;
1269
1270 return pa_gain;
1271}
1272
1273static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
1274 struct lcnphy_txgains *target_gains)
1275{
1276 u16 pa_gain = wlc_lcnphy_get_pa_gain(pi);
1277
1278 mod_phy_reg(pi, 0x4b5,
1279 (0xffff << 0),
1280 ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) <<
1281 0);
1282 mod_phy_reg(pi, 0x4fb,
1283 (0x7fff << 0),
1284 ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
1285
1286 mod_phy_reg(pi, 0x4fc,
1287 (0xffff << 0),
1288 ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) <<
1289 0);
1290 mod_phy_reg(pi, 0x4fd,
1291 (0x7fff << 0),
1292 ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
1293
1294 wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain);
1295
1296 wlc_lcnphy_enable_tx_gain_override(pi);
1297}
1298
1299static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0)
1300{
1301 u16 m0m1 = (u16) m0 << 8;
1302 struct phytbl_info tab;
1303
1304 tab.tbl_ptr = &m0m1;
1305 tab.tbl_len = 1;
1306 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
1307 tab.tbl_offset = 87;
1308 tab.tbl_width = 16;
1309 wlc_lcnphy_write_table(pi, &tab);
1310}
1311
1312static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi)
1313{
1314 u32 data_buf[64];
1315 struct phytbl_info tab;
1316
1317 memset(data_buf, 0, sizeof(data_buf));
1318
1319 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
1320 tab.tbl_width = 32;
1321 tab.tbl_ptr = data_buf;
1322
1323 if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
1324
1325 tab.tbl_len = 30;
1326 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
1327 wlc_lcnphy_write_table(pi, &tab);
1328 }
1329
1330 tab.tbl_len = 64;
1331 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET;
1332 wlc_lcnphy_write_table(pi, &tab);
1333}
1334
1335enum lcnphy_tssi_mode {
1336 LCNPHY_TSSI_PRE_PA,
1337 LCNPHY_TSSI_POST_PA,
1338 LCNPHY_TSSI_EXT
1339};
1340
1341static void
1342wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
1343{
1344 mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0);
1345
1346 mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6);
1347
1348 if (LCNPHY_TSSI_POST_PA == pos) {
1349 mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2);
1350
1351 mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3);
1352
1353 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
1354 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
1355 } else {
1356 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
1357 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
1358 }
1359 } else {
1360 mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
1361
1362 mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3);
1363
1364 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
1365 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
1366 } else {
1367 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
1368 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
1369 }
1370 }
1371 mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14);
1372
1373 if (LCNPHY_TSSI_EXT == pos) {
1374 write_radio_reg(pi, RADIO_2064_REG07F, 1);
1375 mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2);
1376 mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7);
1377 mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3);
1378 }
1379}
1380
1381static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(struct brcms_phy *pi)
1382{
1383 u16 N1, N2, N3, N4, N5, N6, N;
1384 N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0))
1385 >> 0);
1386 N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12))
1387 >> 12);
1388 N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0))
1389 >> 0);
1390 N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8))
1391 >> 8);
1392 N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0))
1393 >> 0);
1394 N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8))
1395 >> 8);
1396 N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80;
1397 if (N < 1600)
1398 N = 1600;
1399 return N;
1400}
1401
1402static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
1403{
1404 u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp;
1405 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1406
1407 auxpga_vmid =
1408 (2 << 8) | (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf;
1409 auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4;
1410 auxpga_gain_temp = 2;
1411
1412 mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0);
1413
1414 mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1);
1415
1416 mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3);
1417
1418 mod_phy_reg(pi, 0x4db,
1419 (0x3ff << 0) |
1420 (0x7 << 12),
1421 (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
1422
1423 mod_phy_reg(pi, 0x4dc,
1424 (0x3ff << 0) |
1425 (0x7 << 12),
1426 (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
1427
1428 mod_phy_reg(pi, 0x40a,
1429 (0x3ff << 0) |
1430 (0x7 << 12),
1431 (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
1432
1433 mod_phy_reg(pi, 0x40b,
1434 (0x3ff << 0) |
1435 (0x7 << 12),
1436 (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
1437
1438 mod_phy_reg(pi, 0x40c,
1439 (0x3ff << 0) |
1440 (0x7 << 12),
1441 (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
1442
1443 mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
1444}
1445
1446static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
1447{
1448 struct phytbl_info tab;
1449 u32 rfseq, ind;
1450
1451 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
1452 tab.tbl_width = 32;
1453 tab.tbl_ptr = &ind;
1454 tab.tbl_len = 1;
1455 tab.tbl_offset = 0;
1456 for (ind = 0; ind < 128; ind++) {
1457 wlc_lcnphy_write_table(pi, &tab);
1458 tab.tbl_offset++;
1459 }
1460 tab.tbl_offset = 704;
1461 for (ind = 0; ind < 128; ind++) {
1462 wlc_lcnphy_write_table(pi, &tab);
1463 tab.tbl_offset++;
1464 }
1465 mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
1466
1467 mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
1468
1469 mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
1470
1471 wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
1472 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
1473
1474 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
1475
1476 mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
1477
1478 mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0);
1479
1480 mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
1481
1482 mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
1483
1484 mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
1485
1486 mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
1487
1488 mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8);
1489
1490 mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
1491
1492 mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8);
1493
1494 mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6);
1495
1496 mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0);
1497
1498 wlc_lcnphy_clear_tx_power_offsets(pi);
1499
1500 mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
1501
1502 mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0);
1503
1504 mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
1505
1506 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
1507 mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
1508 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
1509 } else {
1510 mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
1511 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
1512 }
1513
1514 write_radio_reg(pi, RADIO_2064_REG025, 0xc);
1515
1516 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
1517 mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
1518 } else {
1519 if (CHSPEC_IS2G(pi->radio_chanspec))
1520 mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
1521 else
1522 mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1);
1523 }
1524
1525 if (LCNREV_IS(pi->pubpi.phy_rev, 2))
1526 mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
1527 else
1528 mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2);
1529
1530 mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0);
1531
1532 mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3);
1533
1534 if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
1535 mod_phy_reg(pi, 0x4d7,
1536 (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12);
1537 }
1538
1539 rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
1540 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
1541 tab.tbl_width = 16;
1542 tab.tbl_ptr = &rfseq;
1543 tab.tbl_len = 1;
1544 tab.tbl_offset = 6;
1545 wlc_lcnphy_write_table(pi, &tab);
1546
1547 mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
1548
1549 mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
1550
1551 mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
1552
1553 mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2);
1554
1555 mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
1556
1557 wlc_lcnphy_pwrctrl_rssiparams(pi);
1558}
1559
1560void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi)
1561{
1562 u16 tx_cnt, tx_total, npt;
1563 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1564
1565 tx_total = wlc_lcnphy_total_tx_frames(pi);
1566 tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt;
1567 npt = wlc_lcnphy_get_tx_pwr_npt(pi);
1568
1569 if (tx_cnt > (1 << npt)) {
1570
1571 pi_lcn->lcnphy_tssi_tx_cnt = tx_total;
1572
1573 pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi);
1574 pi_lcn->lcnphy_tssi_npt = npt;
1575
1576 }
1577}
1578
1579s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1)
1580{
1581 s32 a, b, p;
1582
1583 a = 32768 + (a1 * tssi);
1584 b = (1024 * b0) + (64 * b1 * tssi);
1585 p = ((2 * b) + a) / (2 * a);
1586
1587 return p;
1588}
1589
1590static void wlc_lcnphy_txpower_reset_npt(struct brcms_phy *pi)
1591{
1592 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1593 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
1594 return;
1595
1596 pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313;
1597 pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT;
1598}
1599
1600void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi)
1601{
1602 struct phytbl_info tab;
1603 u32 rate_table[BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM +
1604 BRCMS_NUM_RATES_MCS_1_STREAM];
1605 uint i, j;
1606 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
1607 return;
1608
1609 for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) {
1610
1611 if (i == BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM)
1612 j = TXP_FIRST_MCS_20_SISO;
1613
1614 rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j]));
1615 }
1616
1617 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
1618 tab.tbl_width = 32;
1619 tab.tbl_len = ARRAY_SIZE(rate_table);
1620 tab.tbl_ptr = rate_table;
1621 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
1622 wlc_lcnphy_write_table(pi, &tab);
1623
1624 if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) {
1625 wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min);
1626
1627 wlc_lcnphy_txpower_reset_npt(pi);
1628 }
1629}
1630
1631static void wlc_lcnphy_set_tx_pwr_soft_ctrl(struct brcms_phy *pi, s8 index)
1632{
1633 u32 cck_offset[4] = { 22, 22, 22, 22 };
1634 u32 ofdm_offset, reg_offset_cck;
1635 int i;
1636 u16 index2;
1637 struct phytbl_info tab;
1638
1639 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
1640 return;
1641
1642 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
1643
1644 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14);
1645
1646 or_phy_reg(pi, 0x6da, 0x0040);
1647
1648 reg_offset_cck = 0;
1649 for (i = 0; i < 4; i++)
1650 cck_offset[i] -= reg_offset_cck;
1651 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
1652 tab.tbl_width = 32;
1653 tab.tbl_len = 4;
1654 tab.tbl_ptr = cck_offset;
1655 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
1656 wlc_lcnphy_write_table(pi, &tab);
1657 ofdm_offset = 0;
1658 tab.tbl_len = 1;
1659 tab.tbl_ptr = &ofdm_offset;
1660 for (i = 836; i < 862; i++) {
1661 tab.tbl_offset = i;
1662 wlc_lcnphy_write_table(pi, &tab);
1663 }
1664
1665 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15);
1666
1667 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
1668
1669 mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13);
1670
1671 mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7);
1672
1673 mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6);
1674
1675 mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15);
1676
1677 index2 = (u16) (index * 2);
1678 mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
1679
1680 mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4);
1681
1682}
1683
1684static s8 wlc_lcnphy_tempcompensated_txpwrctrl(struct brcms_phy *pi)
1685{
1686 s8 index, delta_brd, delta_temp, new_index, tempcorrx;
1687 s16 manp, meas_temp, temp_diff;
1688 bool neg = 0;
1689 u16 temp;
1690 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1691
1692 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
1693 return pi_lcn->lcnphy_current_index;
1694
1695 index = FIXED_TXPWR;
1696
1697 if (NORADIO_ENAB(pi->pubpi))
1698 return index;
1699
1700 if (pi_lcn->lcnphy_tempsense_slope == 0) {
1701 return index;
1702 }
1703 temp = (u16) wlc_lcnphy_tempsense(pi, 0);
1704 meas_temp = LCNPHY_TEMPSENSE(temp);
1705
1706 if (pi->tx_power_min != 0) {
1707 delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min);
1708 } else {
1709 delta_brd = 0;
1710 }
1711
1712 manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
1713 temp_diff = manp - meas_temp;
1714 if (temp_diff < 0) {
1715
1716 neg = 1;
1717
1718 temp_diff = -temp_diff;
1719 }
1720
1721 delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192),
1722 (u32) (pi_lcn->
1723 lcnphy_tempsense_slope
1724 * 10), 0);
1725 if (neg)
1726 delta_temp = -delta_temp;
1727
1728 if (pi_lcn->lcnphy_tempsense_option == 3
1729 && LCNREV_IS(pi->pubpi.phy_rev, 0))
1730 delta_temp = 0;
1731 if (pi_lcn->lcnphy_tempcorrx > 31)
1732 tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64);
1733 else
1734 tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx;
1735 if (LCNREV_IS(pi->pubpi.phy_rev, 1))
1736 tempcorrx = 4;
1737 new_index =
1738 index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr;
1739 new_index += tempcorrx;
1740
1741 if (LCNREV_IS(pi->pubpi.phy_rev, 1))
1742 index = 127;
1743 if (new_index < 0 || new_index > 126) {
1744 return index;
1745 }
1746 return new_index;
1747}
1748
1749static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(struct brcms_phy *pi, u16 mode)
1750{
1751
1752 u16 current_mode = mode;
1753 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
1754 mode == LCNPHY_TX_PWR_CTRL_HW)
1755 current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED;
1756 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
1757 mode == LCNPHY_TX_PWR_CTRL_TEMPBASED)
1758 current_mode = LCNPHY_TX_PWR_CTRL_HW;
1759 return current_mode;
1760}
1761
1762void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode)
1763{
1764 u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi);
1765 s8 index;
1766 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1767
1768 mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
1769 old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
1770
1771 mod_phy_reg(pi, 0x6da, (0x1 << 6),
1772 ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6);
1773
1774 mod_phy_reg(pi, 0x6a3, (0x1 << 4),
1775 ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4);
1776
1777 if (old_mode != mode) {
1778 if (LCNPHY_TX_PWR_CTRL_HW == old_mode) {
1779
1780 wlc_lcnphy_tx_pwr_update_npt(pi);
1781
1782 wlc_lcnphy_clear_tx_power_offsets(pi);
1783 }
1784 if (LCNPHY_TX_PWR_CTRL_HW == mode) {
1785
1786 wlc_lcnphy_txpower_recalc_target(pi);
1787
1788 wlc_lcnphy_set_start_tx_pwr_idx(pi,
1789 pi_lcn->
1790 lcnphy_tssi_idx);
1791 wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt);
1792 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0);
1793
1794 pi_lcn->lcnphy_tssi_tx_cnt =
1795 wlc_lcnphy_total_tx_frames(pi);
1796
1797 wlc_lcnphy_disable_tx_gain_override(pi);
1798 pi_lcn->lcnphy_tx_power_idx_override = -1;
1799 } else
1800 wlc_lcnphy_enable_tx_gain_override(pi);
1801
1802 mod_phy_reg(pi, 0x4a4,
1803 ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode);
1804 if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) {
1805 index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
1806 wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index);
1807 pi_lcn->lcnphy_current_index = (s8)
1808 ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
1809 }
1810 }
1811}
1812
1813static bool wlc_lcnphy_iqcal_wait(struct brcms_phy *pi)
1814{
1815 uint delay_count = 0;
1816
1817 while (wlc_lcnphy_iqcal_active(pi)) {
1818 udelay(100);
1819 delay_count++;
1820
1821 if (delay_count > (10 * 500))
1822 break;
1823 }
1824
1825 return (0 == wlc_lcnphy_iqcal_active(pi));
1826}
1827
1828static void
1829wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi,
1830 struct lcnphy_txgains *target_gains,
1831 enum lcnphy_cal_mode cal_mode, bool keep_tone)
1832{
1833
1834 struct lcnphy_txgains cal_gains, temp_gains;
1835 u16 hash;
1836 u8 band_idx;
1837 int j;
1838 u16 ncorr_override[5];
1839 u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1840 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1841 };
1842
1843 u16 commands_fullcal[] = {
1844 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 };
1845
1846 u16 commands_recal[] = {
1847 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 };
1848
1849 u16 command_nums_fullcal[] = {
1850 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 };
1851
1852 u16 command_nums_recal[] = {
1853 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 };
1854 u16 *command_nums = command_nums_fullcal;
1855
1856 u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start;
1857 u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2;
1858 u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl;
1859 bool tx_gain_override_old;
1860 struct lcnphy_txgains old_gains;
1861 uint i, n_cal_cmds = 0, n_cal_start = 0;
1862 u16 *values_to_save;
1863 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
1864
1865 if (NORADIO_ENAB(pi->pubpi))
1866 return;
1867
1868 values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
1869 if (NULL == values_to_save) {
1870 return;
1871 }
1872
1873 save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
1874 save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
1875
1876 or_phy_reg(pi, 0x6da, 0x40);
1877 or_phy_reg(pi, 0x6db, 0x3);
1878
1879 switch (cal_mode) {
1880 case LCNPHY_CAL_FULL:
1881 start_coeffs = syst_coeffs;
1882 cal_cmds = commands_fullcal;
1883 n_cal_cmds = ARRAY_SIZE(commands_fullcal);
1884 break;
1885
1886 case LCNPHY_CAL_RECAL:
1887 start_coeffs = syst_coeffs;
1888 cal_cmds = commands_recal;
1889 n_cal_cmds = ARRAY_SIZE(commands_recal);
1890 command_nums = command_nums_recal;
1891 break;
1892
1893 default:
1894 break;
1895 }
1896
1897 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
1898 start_coeffs, 11, 16, 64);
1899
1900 write_phy_reg(pi, 0x6da, 0xffff);
1901 mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3);
1902
1903 tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi);
1904
1905 mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
1906
1907 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
1908
1909 save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db);
1910
1911 mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0);
1912
1913 mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12);
1914
1915 wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save);
1916
1917 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
1918 if (tx_gain_override_old)
1919 wlc_lcnphy_get_tx_gain(pi, &old_gains);
1920
1921 if (!target_gains) {
1922 if (!tx_gain_override_old)
1923 wlc_lcnphy_set_tx_pwr_by_index(pi,
1924 pi_lcn->lcnphy_tssi_idx);
1925 wlc_lcnphy_get_tx_gain(pi, &temp_gains);
1926 target_gains = &temp_gains;
1927 }
1928
1929 hash = (target_gains->gm_gain << 8) |
1930 (target_gains->pga_gain << 4) | (target_gains->pad_gain);
1931
1932 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
1933
1934 cal_gains = *target_gains;
1935 memset(ncorr_override, 0, sizeof(ncorr_override));
1936 for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) {
1937 if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) {
1938 cal_gains.gm_gain =
1939 tbl_iqcal_gainparams_lcnphy[band_idx][j][1];
1940 cal_gains.pga_gain =
1941 tbl_iqcal_gainparams_lcnphy[band_idx][j][2];
1942 cal_gains.pad_gain =
1943 tbl_iqcal_gainparams_lcnphy[band_idx][j][3];
1944 memcpy(ncorr_override,
1945 &tbl_iqcal_gainparams_lcnphy[band_idx][j][3],
1946 sizeof(ncorr_override));
1947 break;
1948 }
1949 }
1950
1951 wlc_lcnphy_set_tx_gain(pi, &cal_gains);
1952
1953 write_phy_reg(pi, 0x453, 0xaa9);
1954 write_phy_reg(pi, 0x93d, 0xc0);
1955
1956 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
1957 (const void *)
1958 lcnphy_iqcal_loft_gainladder,
1959 ARRAY_SIZE(lcnphy_iqcal_loft_gainladder),
1960 16, 0);
1961
1962 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
1963 (const void *)lcnphy_iqcal_ir_gainladder,
1964 ARRAY_SIZE(lcnphy_iqcal_ir_gainladder), 16,
1965 32);
1966
1967 if (pi->phy_tx_tone_freq) {
1968
1969 wlc_lcnphy_stop_tx_tone(pi);
1970 udelay(5);
1971 wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
1972 } else {
1973 wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
1974 }
1975
1976 write_phy_reg(pi, 0x6da, 0xffff);
1977
1978 for (i = n_cal_start; i < n_cal_cmds; i++) {
1979 u16 zero_diq = 0;
1980 u16 best_coeffs[11];
1981 u16 command_num;
1982
1983 cal_type = (cal_cmds[i] & 0x0f00) >> 8;
1984
1985 command_num = command_nums[i];
1986 if (ncorr_override[cal_type])
1987 command_num =
1988 ncorr_override[cal_type] << 8 | (command_num &
1989 0xff);
1990
1991 write_phy_reg(pi, 0x452, command_num);
1992
1993 if ((cal_type == 3) || (cal_type == 4)) {
1994
1995 wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
1996 &diq_start, 1, 16, 69);
1997
1998 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
1999 &zero_diq, 1, 16, 69);
2000 }
2001
2002 write_phy_reg(pi, 0x451, cal_cmds[i]);
2003
2004 if (!wlc_lcnphy_iqcal_wait(pi)) {
2005
2006 goto cleanup;
2007 }
2008
2009 wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2010 best_coeffs,
2011 ARRAY_SIZE(best_coeffs), 16, 96);
2012 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2013 best_coeffs,
2014 ARRAY_SIZE(best_coeffs), 16, 64);
2015
2016 if ((cal_type == 3) || (cal_type == 4)) {
2017 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2018 &diq_start, 1, 16, 69);
2019 }
2020 wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2021 pi_lcn->lcnphy_cal_results.
2022 txiqlocal_bestcoeffs,
2023 ARRAY_SIZE(pi_lcn->
2024 lcnphy_cal_results.
2025 txiqlocal_bestcoeffs),
2026 16, 96);
2027 }
2028
2029 wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2030 pi_lcn->lcnphy_cal_results.
2031 txiqlocal_bestcoeffs,
2032 ARRAY_SIZE(pi_lcn->lcnphy_cal_results.
2033 txiqlocal_bestcoeffs), 16, 96);
2034 pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true;
2035
2036 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2037 &pi_lcn->lcnphy_cal_results.
2038 txiqlocal_bestcoeffs[0], 4, 16, 80);
2039
2040 wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
2041 &pi_lcn->lcnphy_cal_results.
2042 txiqlocal_bestcoeffs[5], 2, 16, 85);
2043
2044 cleanup:
2045 wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save);
2046 kfree(values_to_save);
2047
2048 if (!keep_tone)
2049 wlc_lcnphy_stop_tx_tone(pi);
2050
2051 write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2);
2052
2053 write_phy_reg(pi, 0x453, 0);
2054
2055 if (tx_gain_override_old)
2056 wlc_lcnphy_set_tx_gain(pi, &old_gains);
2057 wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old);
2058
2059 write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl);
2060 write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl);
2061
2062}
2063
2064static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2065{
2066 bool suspend, tx_gain_override_old;
2067 struct lcnphy_txgains old_gains;
2068 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2069 u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
2070 idleTssi0_regvalue_2C;
2071 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
2072 u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112);
2073 u16 SAVE_jtag_bb_afe_switch =
2074 read_radio_reg(pi, RADIO_2064_REG007) & 1;
2075 u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
2076 u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
2077 idleTssi = read_phy_reg(pi, 0x4ab);
2078 suspend =
2079 (0 ==
2080 (R_REG(&((struct brcms_phy *) pi)->regs->maccontrol) &
2081 MCTL_EN_MAC));
2082 if (!suspend)
2083 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2084 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
2085
2086 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
2087 wlc_lcnphy_get_tx_gain(pi, &old_gains);
2088
2089 wlc_lcnphy_enable_tx_gain_override(pi);
2090 wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
2091 write_radio_reg(pi, RADIO_2064_REG112, 0x6);
2092 mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1);
2093 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
2094 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
2095 wlc_lcnphy_tssi_setup(pi);
2096 wlc_phy_do_dummy_tx(pi, true, OFF);
2097 idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
2098 >> 0);
2099
2100 idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0))
2101 >> 0);
2102
2103 if (idleTssi0_2C >= 256)
2104 idleTssi0_OB = idleTssi0_2C - 256;
2105 else
2106 idleTssi0_OB = idleTssi0_2C + 256;
2107
2108 idleTssi0_regvalue_OB = idleTssi0_OB;
2109 if (idleTssi0_regvalue_OB >= 256)
2110 idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256;
2111 else
2112 idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256;
2113 mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0);
2114
2115 mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
2116
2117 wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
2118 wlc_lcnphy_set_tx_gain(pi, &old_gains);
2119 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
2120
2121 write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain);
2122 mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch);
2123 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga);
2124 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en);
2125 mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7);
2126 if (!suspend)
2127 wlapi_enable_mac(pi->sh->physhim);
2128}
2129
2130static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode)
2131{
2132 bool suspend;
2133 u16 save_txpwrCtrlEn;
2134 u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
2135 u16 auxpga_vmid;
2136 struct phytbl_info tab;
2137 u32 val;
2138 u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025,
2139 save_reg112;
2140 u16 values_to_save[14];
2141 s8 index;
2142 int i;
2143 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2144 udelay(999);
2145
2146 save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007);
2147 save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF);
2148 save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F);
2149 save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005);
2150 save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025);
2151 save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112);
2152
2153 for (i = 0; i < 14; i++)
2154 values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
2155 suspend =
2156 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
2157 if (!suspend)
2158 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2159 save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
2160
2161 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
2162 index = pi_lcn->lcnphy_current_index;
2163 wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
2164 mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1);
2165 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4);
2166 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2);
2167 mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
2168
2169 mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
2170
2171 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
2172
2173 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15);
2174
2175 mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
2176
2177 mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
2178
2179 mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
2180
2181 mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
2182
2183 mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
2184
2185 mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8);
2186
2187 mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
2188
2189 mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8);
2190
2191 mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4);
2192
2193 mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8);
2194
2195 mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12);
2196
2197 mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12);
2198
2199 mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13);
2200
2201 mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
2202
2203 write_radio_reg(pi, RADIO_2064_REG025, 0xC);
2204
2205 mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3);
2206
2207 mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
2208
2209 mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
2210
2211 mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
2212
2213 val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
2214 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
2215 tab.tbl_width = 16;
2216 tab.tbl_len = 1;
2217 tab.tbl_ptr = &val;
2218 tab.tbl_offset = 6;
2219 wlc_lcnphy_write_table(pi, &tab);
2220 if (mode == TEMPSENSE) {
2221 mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
2222
2223 mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12);
2224
2225 auxpga_vmidcourse = 8;
2226 auxpga_vmidfine = 0x4;
2227 auxpga_gain = 2;
2228 mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5);
2229 } else {
2230 mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
2231
2232 mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12);
2233
2234 auxpga_vmidcourse = 7;
2235 auxpga_vmidfine = 0xa;
2236 auxpga_gain = 2;
2237 }
2238 auxpga_vmid =
2239 (u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
2240 mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0);
2241
2242 mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2);
2243
2244 mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1);
2245
2246 mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12);
2247
2248 mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5);
2249
2250 write_radio_reg(pi, RADIO_2064_REG112, 0x6);
2251
2252 wlc_phy_do_dummy_tx(pi, true, OFF);
2253 if (!tempsense_done(pi))
2254 udelay(10);
2255
2256 write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007);
2257 write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF);
2258 write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F);
2259 write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005);
2260 write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025);
2261 write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112);
2262 for (i = 0; i < 14; i++)
2263 write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]);
2264 wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index);
2265
2266 write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn);
2267 if (!suspend)
2268 wlapi_enable_mac(pi->sh->physhim);
2269 udelay(999);
2270}
2271
2272static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
2273{
2274 struct lcnphy_txgains tx_gains;
2275 u8 bbmult;
2276 struct phytbl_info tab;
2277 s32 a1, b0, b1;
2278 s32 tssi, pwr, maxtargetpwr, mintargetpwr;
2279 bool suspend;
2280 struct brcms_phy *pi = (struct brcms_phy *) ppi;
2281
2282 suspend =
2283 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
2284 if (!suspend)
2285 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2286
2287 if (NORADIO_ENAB(pi->pubpi)) {
2288 wlc_lcnphy_set_bbmult(pi, 0x30);
2289 if (!suspend)
2290 wlapi_enable_mac(pi->sh->physhim);
2291 return;
2292 }
2293
2294 if (!pi->hwpwrctrl_capable) {
2295 if (CHSPEC_IS2G(pi->radio_chanspec)) {
2296 tx_gains.gm_gain = 4;
2297 tx_gains.pga_gain = 12;
2298 tx_gains.pad_gain = 12;
2299 tx_gains.dac_gain = 0;
2300
2301 bbmult = 150;
2302 } else {
2303 tx_gains.gm_gain = 7;
2304 tx_gains.pga_gain = 15;
2305 tx_gains.pad_gain = 14;
2306 tx_gains.dac_gain = 0;
2307
2308 bbmult = 150;
2309 }
2310 wlc_lcnphy_set_tx_gain(pi, &tx_gains);
2311 wlc_lcnphy_set_bbmult(pi, bbmult);
2312 wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
2313 } else {
2314
2315 wlc_lcnphy_idle_tssi_est(ppi);
2316
2317 wlc_lcnphy_clear_tx_power_offsets(pi);
2318
2319 b0 = pi->txpa_2g[0];
2320 b1 = pi->txpa_2g[1];
2321 a1 = pi->txpa_2g[2];
2322 maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
2323 mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
2324
2325 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
2326 tab.tbl_width = 32;
2327 tab.tbl_ptr = &pwr;
2328 tab.tbl_len = 1;
2329 tab.tbl_offset = 0;
2330 for (tssi = 0; tssi < 128; tssi++) {
2331 pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
2332
2333 pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
2334 wlc_lcnphy_write_table(pi, &tab);
2335 tab.tbl_offset++;
2336 }
2337
2338 mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
2339
2340 write_phy_reg(pi, 0x4a8, 10);
2341
2342 wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR);
2343
2344 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
2345 }
2346 if (!suspend)
2347 wlapi_enable_mac(pi->sh->physhim);
2348}
2349
2350static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
2351{
2352 u16 m0m1;
2353 struct phytbl_info tab;
2354
2355 tab.tbl_ptr = &m0m1;
2356 tab.tbl_len = 1;
2357 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
2358 tab.tbl_offset = 87;
2359 tab.tbl_width = 16;
2360 wlc_lcnphy_read_table(pi, &tab);
2361
2362 return (u8) ((m0m1 & 0xff00) >> 8);
2363}
2364
2365static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain)
2366{
2367 mod_phy_reg(pi, 0x4fb,
2368 LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK,
2369 gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT);
2370 mod_phy_reg(pi, 0x4fd,
2371 LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK,
2372 gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT);
2373}
2374
2375void
2376wlc_lcnphy_get_radio_loft(struct brcms_phy *pi,
2377 u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0)
2378{
2379 *ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089));
2380 *eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A));
2381 *fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B));
2382 *fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C));
2383}
2384
2385static void
2386wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, struct lcnphy_txgains *gains)
2387{
2388 u16 dac_gain;
2389
2390 dac_gain = read_phy_reg(pi, 0x439) >> 0;
2391 gains->dac_gain = (dac_gain & 0x380) >> 7;
2392
2393 {
2394 u16 rfgain0, rfgain1;
2395
2396 rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0;
2397 rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0;
2398
2399 gains->gm_gain = rfgain0 & 0xff;
2400 gains->pga_gain = (rfgain0 >> 8) & 0xff;
2401 gains->pad_gain = rfgain1 & 0xff;
2402 }
2403}
2404
2405void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b)
2406{
2407 struct phytbl_info tab;
2408 u16 iqcc[2];
2409
2410 iqcc[0] = a;
2411 iqcc[1] = b;
2412
2413 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
2414 tab.tbl_width = 16;
2415 tab.tbl_ptr = iqcc;
2416 tab.tbl_len = 2;
2417 tab.tbl_offset = 80;
2418 wlc_lcnphy_write_table(pi, &tab);
2419}
2420
2421void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq)
2422{
2423 struct phytbl_info tab;
2424
2425 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
2426 tab.tbl_width = 16;
2427 tab.tbl_ptr = &didq;
2428 tab.tbl_len = 1;
2429 tab.tbl_offset = 85;
2430 wlc_lcnphy_write_table(pi, &tab);
2431}
2432
2433void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index)
2434{
2435 struct phytbl_info tab;
2436 u16 a, b;
2437 u8 bb_mult;
2438 u32 bbmultiqcomp, txgain, locoeffs, rfpower;
2439 struct lcnphy_txgains gains;
2440 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2441
2442 pi_lcn->lcnphy_tx_power_idx_override = (s8) index;
2443 pi_lcn->lcnphy_current_index = (u8) index;
2444
2445 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
2446 tab.tbl_width = 32;
2447 tab.tbl_len = 1;
2448
2449 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
2450
2451 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
2452 tab.tbl_ptr = &bbmultiqcomp;
2453 wlc_lcnphy_read_table(pi, &tab);
2454
2455 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
2456 tab.tbl_width = 32;
2457 tab.tbl_ptr = &txgain;
2458 wlc_lcnphy_read_table(pi, &tab);
2459
2460 gains.gm_gain = (u16) (txgain & 0xff);
2461 gains.pga_gain = (u16) (txgain >> 8) & 0xff;
2462 gains.pad_gain = (u16) (txgain >> 16) & 0xff;
2463 gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07;
2464 wlc_lcnphy_set_tx_gain(pi, &gains);
2465 wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f);
2466
2467 bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff);
2468 wlc_lcnphy_set_bbmult(pi, bb_mult);
2469
2470 wlc_lcnphy_enable_tx_gain_override(pi);
2471
2472 if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
2473
2474 a = (u16) ((bbmultiqcomp >> 10) & 0x3ff);
2475 b = (u16) (bbmultiqcomp & 0x3ff);
2476 wlc_lcnphy_set_tx_iqcc(pi, a, b);
2477
2478 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index;
2479 tab.tbl_ptr = &locoeffs;
2480 wlc_lcnphy_read_table(pi, &tab);
2481
2482 wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs);
2483
2484 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
2485 tab.tbl_ptr = &rfpower;
2486 wlc_lcnphy_read_table(pi, &tab);
2487 mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0);
2488
2489 }
2490}
2491
2492static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, bool rx)
2493{
2494
2495 mod_phy_reg(pi, 0x44d,
2496 (0x1 << 1) |
2497 (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0));
2498
2499 or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0));
2500}
2501
2502static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi)
2503{
2504 u32 j;
2505 struct phytbl_info tab;
2506 u32 temp_offset[128];
2507 tab.tbl_ptr = temp_offset;
2508 tab.tbl_len = 128;
2509 tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL;
2510 tab.tbl_width = 32;
2511 tab.tbl_offset = 0;
2512
2513 memset(temp_offset, 0, sizeof(temp_offset));
2514 for (j = 1; j < 128; j += 2)
2515 temp_offset[j] = 0x80000;
2516
2517 wlc_lcnphy_write_table(pi, &tab);
2518 return;
2519}
2520
2521static void
2522wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
2523 u16 trsw,
2524 u16 ext_lna,
2525 u16 biq2,
2526 u16 biq1,
2527 u16 tia, u16 lna2, u16 lna1)
2528{
2529 u16 gain0_15, gain16_19;
2530
2531 gain16_19 = biq2 & 0xf;
2532 gain0_15 = ((biq1 & 0xf) << 12) |
2533 ((tia & 0xf) << 8) |
2534 ((lna2 & 0x3) << 6) |
2535 ((lna2 & 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
2536
2537 mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
2538 mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
2539 mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
2540
2541 if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
2542 mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
2543 mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
2544 } else {
2545 mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10);
2546
2547 mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15);
2548
2549 mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
2550 }
2551
2552 mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
2553
2554}
2555
2556static void
2557wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, bool enable)
2558{
2559 u16 ebit = enable ? 1 : 0;
2560
2561 mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8);
2562
2563 mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0);
2564
2565 if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
2566 mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4);
2567 mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6);
2568 mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
2569 mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6);
2570 } else {
2571 mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12);
2572 mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13);
2573 mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
2574 }
2575
2576 if (CHSPEC_IS2G(pi->radio_chanspec)) {
2577 mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10);
2578 mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3);
2579 }
2580}
2581
2582void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable)
2583{
2584 if (!bEnable) {
2585
2586 and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4)));
2587
2588 mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1);
2589
2590 and_phy_reg(pi, 0x44c,
2591 ~(u16) ((0x1 << 3) |
2592 (0x1 << 5) |
2593 (0x1 << 12) |
2594 (0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
2595
2596 and_phy_reg(pi, 0x44d,
2597 ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14)));
2598 mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2);
2599
2600 mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0));
2601
2602 and_phy_reg(pi, 0x4f9,
2603 ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
2604
2605 and_phy_reg(pi, 0x4fa,
2606 ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
2607 } else {
2608
2609 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
2610 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
2611
2612 mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4);
2613 mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6);
2614
2615 mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
2616 mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
2617
2618 wlc_lcnphy_set_trsw_override(pi, true, false);
2619
2620 mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2);
2621 mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2);
2622
2623 if (CHSPEC_IS2G(pi->radio_chanspec)) {
2624
2625 mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
2626 mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3);
2627
2628 mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
2629 mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5);
2630
2631 mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
2632 mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1);
2633
2634 mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
2635 mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2);
2636
2637 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
2638 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0);
2639 } else {
2640
2641 mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
2642 mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3);
2643
2644 mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
2645 mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5);
2646
2647 mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
2648 mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1);
2649
2650 mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
2651 mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2);
2652
2653 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
2654 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
2655 }
2656 }
2657}
2658
2659static void
2660wlc_lcnphy_run_samples(struct brcms_phy *pi,
2661 u16 num_samps,
2662 u16 num_loops, u16 wait, bool iqcalmode)
2663{
2664
2665 or_phy_reg(pi, 0x6da, 0x8080);
2666
2667 mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0);
2668 if (num_loops != 0xffff)
2669 num_loops--;
2670 mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0);
2671
2672 mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0);
2673
2674 if (iqcalmode) {
2675
2676 and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15));
2677 or_phy_reg(pi, 0x453, (0x1 << 15));
2678 } else {
2679 write_phy_reg(pi, 0x63f, 1);
2680 wlc_lcnphy_tx_pu(pi, 1);
2681 }
2682
2683 or_radio_reg(pi, RADIO_2064_REG112, 0x6);
2684}
2685
2686void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode)
2687{
2688
2689 u8 phybw40;
2690 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
2691
2692 if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
2693 mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
2694 mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
2695 } else {
2696 mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
2697 mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
2698 }
2699
2700 if (phybw40 == 0) {
2701 mod_phy_reg((pi), 0x410,
2702 (0x1 << 6) |
2703 (0x1 << 5),
2704 ((CHSPEC_IS2G(pi->radio_chanspec)) ? (!mode) : 0) <<
2705 6 | (!mode) << 5);
2706 mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7);
2707 }
2708}
2709
2710void
2711wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val,
2712 bool iqcalmode)
2713{
2714 u8 phy_bw;
2715 u16 num_samps, t, k;
2716 u32 bw;
2717 fixed theta = 0, rot = 0;
2718 cs32 tone_samp;
2719 u32 data_buf[64];
2720 u16 i_samp, q_samp;
2721 struct phytbl_info tab;
2722 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2723
2724 pi->phy_tx_tone_freq = f_kHz;
2725
2726 wlc_lcnphy_deaf_mode(pi, true);
2727
2728 phy_bw = 40;
2729 if (pi_lcn->lcnphy_spurmod) {
2730 write_phy_reg(pi, 0x942, 0x2);
2731 write_phy_reg(pi, 0x93b, 0x0);
2732 write_phy_reg(pi, 0x93c, 0x0);
2733 wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
2734 }
2735
2736 if (f_kHz) {
2737 k = 1;
2738 do {
2739 bw = phy_bw * 1000 * k;
2740 num_samps = bw / ABS(f_kHz);
2741 k++;
2742 } while ((num_samps * (u32) (ABS(f_kHz))) != bw);
2743 } else
2744 num_samps = 2;
2745
2746 rot = FIXED((f_kHz * 36) / phy_bw) / 100;
2747 theta = 0;
2748
2749 for (t = 0; t < num_samps; t++) {
2750
2751 wlc_phy_cordic(theta, &tone_samp);
2752
2753 theta += rot;
2754
2755 i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
2756 q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
2757 data_buf[t] = (i_samp << 10) | q_samp;
2758 }
2759
2760 mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0);
2761
2762 mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3);
2763
2764 tab.tbl_ptr = data_buf;
2765 tab.tbl_len = num_samps;
2766 tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY;
2767 tab.tbl_offset = 0;
2768 tab.tbl_width = 32;
2769 wlc_lcnphy_write_table(pi, &tab);
2770
2771 wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode);
2772}
2773
2774void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi)
2775{
2776 s16 playback_status;
2777 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2778
2779 pi->phy_tx_tone_freq = 0;
2780 if (pi_lcn->lcnphy_spurmod) {
2781 write_phy_reg(pi, 0x942, 0x7);
2782 write_phy_reg(pi, 0x93b, 0x2017);
2783 write_phy_reg(pi, 0x93c, 0x27c5);
2784 wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
2785 }
2786
2787 playback_status = read_phy_reg(pi, 0x644);
2788 if (playback_status & (0x1 << 0)) {
2789 wlc_lcnphy_tx_pu(pi, 0);
2790 mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1);
2791 } else if (playback_status & (0x1 << 1))
2792 mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15);
2793
2794 mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0);
2795
2796 mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3);
2797
2798 mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7);
2799
2800 and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9);
2801
2802 wlc_lcnphy_deaf_mode(pi, false);
2803}
2804
2805static void wlc_lcnphy_clear_trsw_override(struct brcms_phy *pi)
2806{
2807
2808 and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0)));
2809}
2810
2811void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b)
2812{
2813 u16 iqcc[2];
2814 struct phytbl_info tab;
2815
2816 tab.tbl_ptr = iqcc;
2817 tab.tbl_len = 2;
2818 tab.tbl_id = 0;
2819 tab.tbl_offset = 80;
2820 tab.tbl_width = 16;
2821 wlc_lcnphy_read_table(pi, &tab);
2822
2823 *a = iqcc[0];
2824 *b = iqcc[1];
2825}
2826
2827u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi)
2828{
2829 struct phytbl_info tab;
2830 u16 didq;
2831
2832 tab.tbl_id = 0;
2833 tab.tbl_width = 16;
2834 tab.tbl_ptr = &didq;
2835 tab.tbl_len = 1;
2836 tab.tbl_offset = 85;
2837 wlc_lcnphy_read_table(pi, &tab);
2838
2839 return didq;
2840}
2841
2842static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
2843{
2844
2845 struct lcnphy_txgains target_gains, old_gains;
2846 u8 save_bb_mult;
2847 u16 a, b, didq, save_pa_gain = 0;
2848 uint idx, SAVE_txpwrindex = 0xFF;
2849 u32 val;
2850 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
2851 struct phytbl_info tab;
2852 u8 ei0, eq0, fi0, fq0;
2853 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
2854
2855 wlc_lcnphy_get_tx_gain(pi, &old_gains);
2856 save_pa_gain = wlc_lcnphy_get_pa_gain(pi);
2857
2858 save_bb_mult = wlc_lcnphy_get_bbmult(pi);
2859
2860 if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF)
2861 SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi);
2862
2863 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
2864
2865 target_gains.gm_gain = 7;
2866 target_gains.pga_gain = 0;
2867 target_gains.pad_gain = 21;
2868 target_gains.dac_gain = 0;
2869 wlc_lcnphy_set_tx_gain(pi, &target_gains);
2870 wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
2871
2872 if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
2873
2874 wlc_lcnphy_set_tx_pwr_by_index(pi, 30);
2875
2876 wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
2877 (pi_lcn->
2878 lcnphy_recal ? LCNPHY_CAL_RECAL :
2879 LCNPHY_CAL_FULL), false);
2880 } else {
2881
2882 wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
2883 }
2884
2885 wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0);
2886 if ((ABS((s8) fi0) == 15) && (ABS((s8) fq0) == 15)) {
2887 if (CHSPEC_IS5G(pi->radio_chanspec)) {
2888 target_gains.gm_gain = 255;
2889 target_gains.pga_gain = 255;
2890 target_gains.pad_gain = 0xf0;
2891 target_gains.dac_gain = 0;
2892 } else {
2893 target_gains.gm_gain = 7;
2894 target_gains.pga_gain = 45;
2895 target_gains.pad_gain = 186;
2896 target_gains.dac_gain = 0;
2897 }
2898
2899 if (LCNREV_IS(pi->pubpi.phy_rev, 1)
2900 || pi_lcn->lcnphy_hw_iqcal_en) {
2901
2902 target_gains.pga_gain = 0;
2903 target_gains.pad_gain = 30;
2904 wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
2905 wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
2906 LCNPHY_CAL_FULL, false);
2907 } else {
2908
2909 wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
2910 }
2911
2912 }
2913
2914 wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
2915
2916 didq = wlc_lcnphy_get_tx_locc(pi);
2917
2918 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
2919 tab.tbl_width = 32;
2920 tab.tbl_ptr = &val;
2921
2922 tab.tbl_len = 1;
2923 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
2924
2925 for (idx = 0; idx < 128; idx++) {
2926 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx;
2927
2928 wlc_lcnphy_read_table(pi, &tab);
2929 val = (val & 0xfff00000) |
2930 ((u32) (a & 0x3FF) << 10) | (b & 0x3ff);
2931 wlc_lcnphy_write_table(pi, &tab);
2932
2933 val = didq;
2934 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx;
2935 wlc_lcnphy_write_table(pi, &tab);
2936 }
2937
2938 pi_lcn->lcnphy_cal_results.txiqlocal_a = a;
2939 pi_lcn->lcnphy_cal_results.txiqlocal_b = b;
2940 pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq;
2941 pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0;
2942 pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0;
2943 pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0;
2944 pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0;
2945
2946 wlc_lcnphy_set_bbmult(pi, save_bb_mult);
2947 wlc_lcnphy_set_pa_gain(pi, save_pa_gain);
2948 wlc_lcnphy_set_tx_gain(pi, &old_gains);
2949
2950 if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF)
2951 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
2952 else
2953 wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex);
2954}
2955
2956s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode)
2957{
2958 u16 tempsenseval1, tempsenseval2;
2959 s16 avg = 0;
2960 bool suspend = 0;
2961
2962 if (NORADIO_ENAB(pi->pubpi))
2963 return -1;
2964
2965 if (mode == 1) {
2966 suspend =
2967 (0 ==
2968 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
2969 if (!suspend)
2970 wlapi_suspend_mac_and_wait(pi->sh->physhim);
2971 wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
2972 }
2973 tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
2974 tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
2975
2976 if (tempsenseval1 > 255)
2977 avg = (s16) (tempsenseval1 - 512);
2978 else
2979 avg = (s16) tempsenseval1;
2980
2981 if (tempsenseval2 > 255)
2982 avg += (s16) (tempsenseval2 - 512);
2983 else
2984 avg += (s16) tempsenseval2;
2985
2986 avg /= 2;
2987
2988 if (mode == 1) {
2989
2990 mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
2991
2992 udelay(100);
2993 mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
2994
2995 if (!suspend)
2996 wlapi_enable_mac(pi->sh->physhim);
2997 }
2998 return avg;
2999}
3000
3001u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode)
3002{
3003 u16 tempsenseval1, tempsenseval2;
3004 s32 avg = 0;
3005 bool suspend = 0;
3006 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
3007 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3008
3009 if (NORADIO_ENAB(pi->pubpi))
3010 return -1;
3011
3012 if (mode == 1) {
3013 suspend =
3014 (0 ==
3015 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
3016 if (!suspend)
3017 wlapi_suspend_mac_and_wait(pi->sh->physhim);
3018 wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
3019 }
3020 tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
3021 tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
3022
3023 if (tempsenseval1 > 255)
3024 avg = (int)(tempsenseval1 - 512);
3025 else
3026 avg = (int)tempsenseval1;
3027
3028 if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) {
3029 if (tempsenseval2 > 255)
3030 avg = (int)(avg - tempsenseval2 + 512);
3031 else
3032 avg = (int)(avg - tempsenseval2);
3033 } else {
3034 if (tempsenseval2 > 255)
3035 avg = (int)(avg + tempsenseval2 - 512);
3036 else
3037 avg = (int)(avg + tempsenseval2);
3038 avg = avg / 2;
3039 }
3040 if (avg < 0)
3041 avg = avg + 512;
3042
3043 if (pi_lcn->lcnphy_tempsense_option == 2)
3044 avg = tempsenseval1;
3045
3046 if (mode)
3047 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
3048
3049 if (mode == 1) {
3050
3051 mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
3052
3053 udelay(100);
3054 mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
3055
3056 if (!suspend)
3057 wlapi_enable_mac(pi->sh->physhim);
3058 }
3059 return (u16) avg;
3060}
3061
3062s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode)
3063{
3064 s32 degree = wlc_lcnphy_tempsense_new(pi, mode);
3065 degree =
3066 ((degree << 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1))
3067 / LCN_TEMPSENSE_DEN;
3068 return (s8) degree;
3069}
3070
3071s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode)
3072{
3073 u16 vbatsenseval;
3074 s32 avg = 0;
3075 bool suspend = 0;
3076
3077 if (NORADIO_ENAB(pi->pubpi))
3078 return -1;
3079
3080 if (mode == 1) {
3081 suspend =
3082 (0 ==
3083 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
3084 if (!suspend)
3085 wlapi_suspend_mac_and_wait(pi->sh->physhim);
3086 wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
3087 }
3088
3089 vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF;
3090
3091 if (vbatsenseval > 255)
3092 avg = (s32) (vbatsenseval - 512);
3093 else
3094 avg = (s32) vbatsenseval;
3095
3096 avg =
3097 (avg * LCN_VBAT_SCALE_NOM +
3098 (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN;
3099
3100 if (mode == 1) {
3101 if (!suspend)
3102 wlapi_enable_mac(pi->sh->physhim);
3103 }
3104 return (s8) avg;
3105}
3106
3107static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode)
3108{
3109 u8 phybw40;
3110 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
3111
3112 mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7);
3113
3114 if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) ||
3115 (mode == AFE_CLK_INIT_MODE_TXRX2X))
3116 write_phy_reg(pi, 0x6d0, 0x7);
3117
3118 wlc_lcnphy_toggle_afe_pwdn(pi);
3119}
3120
3121static bool
3122wlc_lcnphy_rx_iq_est(struct brcms_phy *pi,
3123 u16 num_samps,
3124 u8 wait_time, struct lcnphy_iq_est *iq_est)
3125{
3126 int wait_count = 0;
3127 bool result = true;
3128 u8 phybw40;
3129 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
3130
3131 mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5);
3132
3133 mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3);
3134
3135 mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0);
3136
3137 mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0);
3138
3139 mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8);
3140
3141 mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9);
3142
3143 while (read_phy_reg(pi, 0x481) & (0x1 << 9)) {
3144
3145 if (wait_count > (10 * 500)) {
3146 result = false;
3147 goto cleanup;
3148 }
3149 udelay(100);
3150 wait_count++;
3151 }
3152
3153 iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) |
3154 (u32) read_phy_reg(pi, 0x484);
3155 iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) |
3156 (u32) read_phy_reg(pi, 0x486);
3157 iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) |
3158 (u32) read_phy_reg(pi, 0x488);
3159
3160 cleanup:
3161 mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3);
3162
3163 mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5);
3164
3165 return result;
3166}
3167
3168static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps)
3169{
3170#define LCNPHY_MIN_RXIQ_PWR 2
3171 bool result;
3172 u16 a0_new, b0_new;
3173 struct lcnphy_iq_est iq_est = { 0, 0, 0 };
3174 s32 a, b, temp;
3175 s16 iq_nbits, qq_nbits, arsh, brsh;
3176 s32 iq;
3177 u32 ii, qq;
3178 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3179
3180 a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0);
3181 b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0);
3182 mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2);
3183
3184 mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6);
3185
3186 wlc_lcnphy_set_rx_iq_comp(pi, 0, 0);
3187
3188 result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est);
3189 if (!result)
3190 goto cleanup;
3191
3192 iq = (s32) iq_est.iq_prod;
3193 ii = iq_est.i_pwr;
3194 qq = iq_est.q_pwr;
3195
3196 if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) {
3197 result = false;
3198 goto cleanup;
3199 }
3200
3201 iq_nbits = wlc_phy_nbits(iq);
3202 qq_nbits = wlc_phy_nbits(qq);
3203
3204 arsh = 10 - (30 - iq_nbits);
3205 if (arsh >= 0) {
3206 a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
3207 temp = (s32) (ii >> arsh);
3208 if (temp == 0) {
3209 return false;
3210 }
3211 } else {
3212 a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
3213 temp = (s32) (ii << -arsh);
3214 if (temp == 0) {
3215 return false;
3216 }
3217 }
3218 a /= temp;
3219 brsh = qq_nbits - 31 + 20;
3220 if (brsh >= 0) {
3221 b = (qq << (31 - qq_nbits));
3222 temp = (s32) (ii >> brsh);
3223 if (temp == 0) {
3224 return false;
3225 }
3226 } else {
3227 b = (qq << (31 - qq_nbits));
3228 temp = (s32) (ii << -brsh);
3229 if (temp == 0) {
3230 return false;
3231 }
3232 }
3233 b /= temp;
3234 b -= a * a;
3235 b = (s32) int_sqrt((unsigned long) b);
3236 b -= (1 << 10);
3237 a0_new = (u16) (a & 0x3ff);
3238 b0_new = (u16) (b & 0x3ff);
3239 cleanup:
3240
3241 wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new);
3242
3243 mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0);
3244
3245 mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3);
3246
3247 pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new;
3248 pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new;
3249
3250 return result;
3251}
3252
3253static bool
3254wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
3255 const struct lcnphy_rx_iqcomp *iqcomp,
3256 int iqcomp_sz, bool tx_switch, bool rx_switch, int module,
3257 int tx_gain_idx)
3258{
3259 struct lcnphy_txgains old_gains;
3260 u16 tx_pwr_ctrl;
3261 u8 tx_gain_index_old = 0;
3262 bool result = false, tx_gain_override_old = false;
3263 u16 i, Core1TxControl_old, RFOverride0_old,
3264 RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
3265 rfoverride3_old, rfoverride3val_old, rfoverride4_old,
3266 rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
3267 int tia_gain;
3268 u32 received_power, rx_pwr_threshold;
3269 u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
3270 u16 values_to_save[11];
3271 s16 *ptr;
3272 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3273
3274 ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
3275 if (NULL == ptr) {
3276 return false;
3277 }
3278 if (module == 2) {
3279 while (iqcomp_sz--) {
3280 if (iqcomp[iqcomp_sz].chan ==
3281 CHSPEC_CHANNEL(pi->radio_chanspec)) {
3282
3283 wlc_lcnphy_set_rx_iq_comp(pi,
3284 (u16)
3285 iqcomp[iqcomp_sz].a,
3286 (u16)
3287 iqcomp[iqcomp_sz].b);
3288 result = true;
3289 break;
3290 }
3291 }
3292 goto cal_done;
3293 }
3294
3295 if (module == 1) {
3296
3297 tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
3298 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
3299
3300 for (i = 0; i < 11; i++) {
3301 values_to_save[i] =
3302 read_radio_reg(pi, rxiq_cal_rf_reg[i]);
3303 }
3304 Core1TxControl_old = read_phy_reg(pi, 0x631);
3305
3306 or_phy_reg(pi, 0x631, 0x0015);
3307
3308 RFOverride0_old = read_phy_reg(pi, 0x44c);
3309 RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
3310 rfoverride2_old = read_phy_reg(pi, 0x4b0);
3311 rfoverride2val_old = read_phy_reg(pi, 0x4b1);
3312 rfoverride3_old = read_phy_reg(pi, 0x4f9);
3313 rfoverride3val_old = read_phy_reg(pi, 0x4fa);
3314 rfoverride4_old = read_phy_reg(pi, 0x938);
3315 rfoverride4val_old = read_phy_reg(pi, 0x939);
3316 afectrlovr_old = read_phy_reg(pi, 0x43b);
3317 afectrlovrval_old = read_phy_reg(pi, 0x43c);
3318 old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
3319 old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
3320
3321 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
3322 if (tx_gain_override_old) {
3323 wlc_lcnphy_get_tx_gain(pi, &old_gains);
3324 tx_gain_index_old = pi_lcn->lcnphy_current_index;
3325 }
3326
3327 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
3328
3329 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
3330 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
3331
3332 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
3333 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
3334
3335 write_radio_reg(pi, RADIO_2064_REG116, 0x06);
3336 write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
3337 write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
3338 write_radio_reg(pi, RADIO_2064_REG098, 0x03);
3339 write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
3340 mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
3341 write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
3342 write_radio_reg(pi, RADIO_2064_REG114, 0x01);
3343 write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
3344 write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
3345
3346 mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
3347 mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
3348 mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
3349 mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
3350 mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
3351 mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
3352 mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
3353 mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
3354 mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
3355 mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
3356
3357 mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
3358 mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
3359
3360 wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
3361 write_phy_reg(pi, 0x6da, 0xffff);
3362 or_phy_reg(pi, 0x6db, 0x3);
3363 wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
3364 wlc_lcnphy_rx_gain_override_enable(pi, true);
3365
3366 tia_gain = 8;
3367 rx_pwr_threshold = 950;
3368 while (tia_gain > 0) {
3369 tia_gain -= 1;
3370 wlc_lcnphy_set_rx_gain_by_distribution(pi,
3371 0, 0, 2, 2,
3372 (u16)
3373 tia_gain, 1, 0);
3374 udelay(500);
3375
3376 received_power =
3377 wlc_lcnphy_measure_digital_power(pi, 2000);
3378 if (received_power < rx_pwr_threshold)
3379 break;
3380 }
3381 result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
3382
3383 wlc_lcnphy_stop_tx_tone(pi);
3384
3385 write_phy_reg(pi, 0x631, Core1TxControl_old);
3386
3387 write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
3388 write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
3389 write_phy_reg(pi, 0x4b0, rfoverride2_old);
3390 write_phy_reg(pi, 0x4b1, rfoverride2val_old);
3391 write_phy_reg(pi, 0x4f9, rfoverride3_old);
3392 write_phy_reg(pi, 0x4fa, rfoverride3val_old);
3393 write_phy_reg(pi, 0x938, rfoverride4_old);
3394 write_phy_reg(pi, 0x939, rfoverride4val_old);
3395 write_phy_reg(pi, 0x43b, afectrlovr_old);
3396 write_phy_reg(pi, 0x43c, afectrlovrval_old);
3397 write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
3398 write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
3399
3400 wlc_lcnphy_clear_trsw_override(pi);
3401
3402 mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
3403
3404 for (i = 0; i < 11; i++) {
3405 write_radio_reg(pi, rxiq_cal_rf_reg[i],
3406 values_to_save[i]);
3407 }
3408
3409 if (tx_gain_override_old) {
3410 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
3411 } else
3412 wlc_lcnphy_disable_tx_gain_override(pi);
3413 wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
3414
3415 wlc_lcnphy_rx_gain_override_enable(pi, false);
3416 }
3417
3418 cal_done:
3419 kfree(ptr);
3420 return result;
3421}
3422
3423static void wlc_lcnphy_temp_adj(struct brcms_phy *pi)
3424{
3425 if (NORADIO_ENAB(pi->pubpi))
3426 return;
3427}
3428
3429static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi)
3430{
3431 bool suspend;
3432 s8 index;
3433 u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
3434 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3435 suspend =
3436 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
3437 if (!suspend)
3438 wlapi_suspend_mac_and_wait(pi->sh->physhim);
3439 wlc_lcnphy_deaf_mode(pi, true);
3440 pi->phy_lastcal = pi->sh->now;
3441 pi->phy_forcecal = false;
3442 index = pi_lcn->lcnphy_current_index;
3443
3444 wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
3445
3446 wlc_lcnphy_set_tx_pwr_by_index(pi, index);
3447 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
3448 wlc_lcnphy_deaf_mode(pi, false);
3449 if (!suspend)
3450 wlapi_enable_mac(pi->sh->physhim);
3451
3452}
3453
3454static void wlc_lcnphy_periodic_cal(struct brcms_phy *pi)
3455{
3456 bool suspend, full_cal;
3457 const struct lcnphy_rx_iqcomp *rx_iqcomp;
3458 int rx_iqcomp_sz;
3459 u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
3460 s8 index;
3461 struct phytbl_info tab;
3462 s32 a1, b0, b1;
3463 s32 tssi, pwr, maxtargetpwr, mintargetpwr;
3464 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3465
3466 if (NORADIO_ENAB(pi->pubpi))
3467 return;
3468
3469 pi->phy_lastcal = pi->sh->now;
3470 pi->phy_forcecal = false;
3471 full_cal =
3472 (pi_lcn->lcnphy_full_cal_channel !=
3473 CHSPEC_CHANNEL(pi->radio_chanspec));
3474 pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
3475 index = pi_lcn->lcnphy_current_index;
3476
3477 suspend =
3478 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
3479 if (!suspend) {
3480
3481 wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
3482 wlapi_suspend_mac_and_wait(pi->sh->physhim);
3483 }
3484 wlc_lcnphy_deaf_mode(pi, true);
3485
3486 wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
3487
3488 rx_iqcomp = lcnphy_rx_iqcomp_table_rev0;
3489 rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0);
3490
3491 if (LCNREV_IS(pi->pubpi.phy_rev, 1))
3492 wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40);
3493 else
3494 wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127);
3495
3496 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
3497
3498 wlc_lcnphy_idle_tssi_est((struct brcms_phy_pub *) pi);
3499
3500 b0 = pi->txpa_2g[0];
3501 b1 = pi->txpa_2g[1];
3502 a1 = pi->txpa_2g[2];
3503 maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
3504 mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
3505
3506 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
3507 tab.tbl_width = 32;
3508 tab.tbl_ptr = &pwr;
3509 tab.tbl_len = 1;
3510 tab.tbl_offset = 0;
3511 for (tssi = 0; tssi < 128; tssi++) {
3512 pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
3513 pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
3514 wlc_lcnphy_write_table(pi, &tab);
3515 tab.tbl_offset++;
3516 }
3517 }
3518
3519 wlc_lcnphy_set_tx_pwr_by_index(pi, index);
3520 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
3521 wlc_lcnphy_deaf_mode(pi, false);
3522 if (!suspend)
3523 wlapi_enable_mac(pi->sh->physhim);
3524}
3525
3526void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode)
3527{
3528 u16 temp_new;
3529 int temp1, temp2, temp_diff;
3530 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3531
3532 switch (mode) {
3533 case PHY_PERICAL_CHAN:
3534
3535 break;
3536 case PHY_FULLCAL:
3537 wlc_lcnphy_periodic_cal(pi);
3538 break;
3539 case PHY_PERICAL_PHYINIT:
3540 wlc_lcnphy_periodic_cal(pi);
3541 break;
3542 case PHY_PERICAL_WATCHDOG:
3543 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
3544 temp_new = wlc_lcnphy_tempsense(pi, 0);
3545 temp1 = LCNPHY_TEMPSENSE(temp_new);
3546 temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper);
3547 temp_diff = temp1 - temp2;
3548 if ((pi_lcn->lcnphy_cal_counter > 90) ||
3549 (temp_diff > 60) || (temp_diff < -60)) {
3550 wlc_lcnphy_glacial_timer_based_cal(pi);
3551 wlc_2064_vco_cal(pi);
3552 pi_lcn->lcnphy_cal_temper = temp_new;
3553 pi_lcn->lcnphy_cal_counter = 0;
3554 } else
3555 pi_lcn->lcnphy_cal_counter++;
3556 }
3557 break;
3558 case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL:
3559 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
3560 wlc_lcnphy_tx_power_adjustment(
3561 (struct brcms_phy_pub *) pi);
3562 break;
3563 }
3564}
3565
3566void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr)
3567{
3568 s8 cck_offset;
3569 u16 status;
3570 status = (read_phy_reg(pi, 0x4ab));
3571 if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
3572 (status & (0x1 << 15))) {
3573 *ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
3574 >> 0) >> 1);
3575
3576 if (wlc_phy_tpc_isenabled_lcnphy(pi))
3577 cck_offset = pi->tx_power_offset[TXP_FIRST_CCK];
3578 else
3579 cck_offset = 0;
3580
3581 *cck_pwr = *ofdm_pwr + cck_offset;
3582 } else {
3583 *cck_pwr = 0;
3584 *ofdm_pwr = 0;
3585 }
3586}
3587
3588void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi)
3589{
3590 return;
3591
3592}
3593
3594static void
3595wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, chanspec_t chanspec)
3596{
3597 u8 channel = CHSPEC_CHANNEL(chanspec);
3598 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3599
3600 if (NORADIO_ENAB(pi->pubpi))
3601 return;
3602
3603 if (channel == 14) {
3604 mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
3605
3606 } else {
3607 mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
3608
3609 }
3610 pi_lcn->lcnphy_bandedge_corr = 2;
3611 if (channel == 1)
3612 pi_lcn->lcnphy_bandedge_corr = 4;
3613
3614 if (channel == 1 || channel == 2 || channel == 3 ||
3615 channel == 4 || channel == 9 ||
3616 channel == 10 || channel == 11 || channel == 12) {
3617 si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04);
3618 si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0);
3619 si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0);
3620
3621 si_pmu_pllupd(pi->sh->sih);
3622 write_phy_reg(pi, 0x942, 0);
3623 wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
3624 pi_lcn->lcnphy_spurmod = 0;
3625 mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
3626
3627 write_phy_reg(pi, 0x425, 0x5907);
3628 } else {
3629 si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04);
3630 si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333);
3631 si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820);
3632
3633 si_pmu_pllupd(pi->sh->sih);
3634 write_phy_reg(pi, 0x942, 0);
3635 wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
3636
3637 pi_lcn->lcnphy_spurmod = 0;
3638 mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
3639
3640 write_phy_reg(pi, 0x425, 0x590a);
3641 }
3642
3643 or_phy_reg(pi, 0x44a, 0x44);
3644 write_phy_reg(pi, 0x44a, 0x80);
3645}
3646
3647void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi)
3648{
3649 s8 index;
3650 u16 index2;
3651 struct brcms_phy *pi = (struct brcms_phy *) ppi;
3652 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3653 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
3654 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && SAVE_txpwrctrl) {
3655 index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
3656 index2 = (u16) (index * 2);
3657 mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
3658
3659 pi_lcn->lcnphy_current_index = (s8)
3660 ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
3661 }
3662}
3663
3664static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b)
3665{
3666 mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0);
3667
3668 mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0);
3669
3670 mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0);
3671
3672 mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0);
3673
3674 mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0);
3675
3676 mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0);
3677
3678}
3679
3680void wlc_phy_init_lcnphy(struct brcms_phy *pi)
3681{
3682 u8 phybw40;
3683 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3684 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
3685
3686 pi_lcn->lcnphy_cal_counter = 0;
3687 pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense;
3688
3689 or_phy_reg(pi, 0x44a, 0x80);
3690 and_phy_reg(pi, 0x44a, 0x7f);
3691
3692 wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X);
3693
3694 write_phy_reg(pi, 0x60a, 160);
3695
3696 write_phy_reg(pi, 0x46a, 25);
3697
3698 wlc_lcnphy_baseband_init(pi);
3699
3700 wlc_lcnphy_radio_init(pi);
3701
3702 if (CHSPEC_IS2G(pi->radio_chanspec))
3703 wlc_lcnphy_tx_pwr_ctrl_init((struct brcms_phy_pub *) pi);
3704
3705 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
3706
3707 si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9);
3708
3709 si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD);
3710
3711 if ((pi->sh->boardflags & BFL_FEM)
3712 && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
3713 wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR);
3714
3715 wlc_lcnphy_agc_temp_init(pi);
3716
3717 wlc_lcnphy_temp_adj(pi);
3718
3719 mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
3720
3721 udelay(100);
3722 mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
3723
3724 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
3725 pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT;
3726 wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT);
3727}
3728
3729static void
3730wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save)
3731{
3732 u16 vmid;
3733 int i;
3734 for (i = 0; i < 20; i++) {
3735 values_to_save[i] =
3736 read_radio_reg(pi, iqlo_loopback_rf_regs[i]);
3737 }
3738
3739 mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
3740 mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
3741
3742 mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11);
3743 mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13);
3744
3745 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
3746 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
3747
3748 mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
3749 mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
3750
3751 if (LCNREV_IS(pi->pubpi.phy_rev, 2))
3752 and_radio_reg(pi, RADIO_2064_REG03A, 0xFD);
3753 else
3754 and_radio_reg(pi, RADIO_2064_REG03A, 0xF9);
3755 or_radio_reg(pi, RADIO_2064_REG11A, 0x1);
3756
3757 or_radio_reg(pi, RADIO_2064_REG036, 0x01);
3758 or_radio_reg(pi, RADIO_2064_REG11A, 0x18);
3759 udelay(20);
3760
3761 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
3762 if (CHSPEC_IS5G(pi->radio_chanspec))
3763 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
3764 else
3765 or_radio_reg(pi, RADIO_2064_REG03A, 1);
3766 } else {
3767 if (CHSPEC_IS5G(pi->radio_chanspec))
3768 mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1);
3769 else
3770 or_radio_reg(pi, RADIO_2064_REG03A, 0x3);
3771 }
3772
3773 udelay(20);
3774
3775 write_radio_reg(pi, RADIO_2064_REG025, 0xF);
3776 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
3777 if (CHSPEC_IS5G(pi->radio_chanspec))
3778 mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4);
3779 else
3780 mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6);
3781 } else {
3782 if (CHSPEC_IS5G(pi->radio_chanspec))
3783 mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1);
3784 else
3785 mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1);
3786 }
3787
3788 udelay(20);
3789
3790 write_radio_reg(pi, RADIO_2064_REG005, 0x8);
3791 or_radio_reg(pi, RADIO_2064_REG112, 0x80);
3792 udelay(20);
3793
3794 or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
3795 or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
3796 udelay(20);
3797
3798 or_radio_reg(pi, RADIO_2064_REG00B, 0x7);
3799 or_radio_reg(pi, RADIO_2064_REG113, 0x10);
3800 udelay(20);
3801
3802 write_radio_reg(pi, RADIO_2064_REG007, 0x1);
3803 udelay(20);
3804
3805 vmid = 0x2A6;
3806 mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3);
3807 write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff));
3808 or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
3809 udelay(20);
3810
3811 or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
3812 udelay(20);
3813 write_radio_reg(pi, RADIO_2064_REG012, 0x02);
3814 or_radio_reg(pi, RADIO_2064_REG112, 0x06);
3815 write_radio_reg(pi, RADIO_2064_REG036, 0x11);
3816 write_radio_reg(pi, RADIO_2064_REG059, 0xcc);
3817 write_radio_reg(pi, RADIO_2064_REG05C, 0x2e);
3818 write_radio_reg(pi, RADIO_2064_REG078, 0xd7);
3819 write_radio_reg(pi, RADIO_2064_REG092, 0x15);
3820}
3821
3822static void
3823wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh,
3824 s16 *ptr, int mode)
3825{
3826 u32 curval1, curval2, stpptr, curptr, strptr, val;
3827 u16 sslpnCalibClkEnCtrl, timer;
3828 u16 old_sslpnCalibClkEnCtrl;
3829 s16 imag, real;
3830 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
3831
3832 timer = 0;
3833 old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
3834
3835 curval1 = R_REG(&pi->regs->psm_corectlsts);
3836 ptr[130] = 0;
3837 W_REG(&pi->regs->psm_corectlsts, ((1 << 6) | curval1));
3838
3839 W_REG(&pi->regs->smpl_clct_strptr, 0x7E00);
3840 W_REG(&pi->regs->smpl_clct_stpptr, 0x8000);
3841 udelay(20);
3842 curval2 = R_REG(&pi->regs->psm_phy_hdr_param);
3843 W_REG(&pi->regs->psm_phy_hdr_param, curval2 | 0x30);
3844
3845 write_phy_reg(pi, 0x555, 0x0);
3846 write_phy_reg(pi, 0x5a6, 0x5);
3847
3848 write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6));
3849 write_phy_reg(pi, 0x5cf, 3);
3850 write_phy_reg(pi, 0x5a5, 0x3);
3851 write_phy_reg(pi, 0x583, 0x0);
3852 write_phy_reg(pi, 0x584, 0x0);
3853 write_phy_reg(pi, 0x585, 0x0fff);
3854 write_phy_reg(pi, 0x586, 0x0000);
3855
3856 write_phy_reg(pi, 0x580, 0x4501);
3857
3858 sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
3859 write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008));
3860 stpptr = R_REG(&pi->regs->smpl_clct_stpptr);
3861 curptr = R_REG(&pi->regs->smpl_clct_curptr);
3862 do {
3863 udelay(10);
3864 curptr = R_REG(&pi->regs->smpl_clct_curptr);
3865 timer++;
3866 } while ((curptr != stpptr) && (timer < 500));
3867
3868 W_REG(&pi->regs->psm_phy_hdr_param, 0x2);
3869 strptr = 0x7E00;
3870 W_REG(&pi->regs->tplatewrptr, strptr);
3871 while (strptr < 0x8000) {
3872 val = R_REG(&pi->regs->tplatewrdata);
3873 imag = ((val >> 16) & 0x3ff);
3874 real = ((val) & 0x3ff);
3875 if (imag > 511) {
3876 imag -= 1024;
3877 }
3878 if (real > 511) {
3879 real -= 1024;
3880 }
3881 if (pi_lcn->lcnphy_iqcal_swp_dis)
3882 ptr[(strptr - 0x7E00) / 4] = real;
3883 else
3884 ptr[(strptr - 0x7E00) / 4] = imag;
3885 if (clip_detect_algo) {
3886 if (imag > thresh || imag < -thresh) {
3887 strptr = 0x8000;
3888 ptr[130] = 1;
3889 }
3890 }
3891 strptr += 4;
3892 }
3893
3894 write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
3895 W_REG(&pi->regs->psm_phy_hdr_param, curval2);
3896 W_REG(&pi->regs->psm_corectlsts, curval1);
3897}
3898
3899static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi)
3900{
3901 struct lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4;
3902
3903 wlc_lcnphy_set_cc(pi, 0, 0, 0);
3904 wlc_lcnphy_set_cc(pi, 2, 0, 0);
3905 wlc_lcnphy_set_cc(pi, 3, 0, 0);
3906 wlc_lcnphy_set_cc(pi, 4, 0, 0);
3907
3908 wlc_lcnphy_a1(pi, 4, 0, 0);
3909 wlc_lcnphy_a1(pi, 3, 0, 0);
3910 wlc_lcnphy_a1(pi, 2, 3, 2);
3911 wlc_lcnphy_a1(pi, 0, 5, 8);
3912 wlc_lcnphy_a1(pi, 2, 2, 1);
3913 wlc_lcnphy_a1(pi, 0, 4, 3);
3914
3915 iqcc0 = wlc_lcnphy_get_cc(pi, 0);
3916 locc2 = wlc_lcnphy_get_cc(pi, 2);
3917 locc3 = wlc_lcnphy_get_cc(pi, 3);
3918 locc4 = wlc_lcnphy_get_cc(pi, 4);
3919}
3920
3921static void
3922wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y)
3923{
3924 u16 di0dq0;
3925 u16 x, y, data_rf;
3926 int k;
3927 switch (cal_type) {
3928 case 0:
3929 wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y);
3930 break;
3931 case 2:
3932 di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff);
3933 wlc_lcnphy_set_tx_locc(pi, di0dq0);
3934 break;
3935 case 3:
3936 k = wlc_lcnphy_calc_floor(coeff_x, 0);
3937 y = 8 + k;
3938 k = wlc_lcnphy_calc_floor(coeff_x, 1);
3939 x = 8 - k;
3940 data_rf = (x * 16 + y);
3941 write_radio_reg(pi, RADIO_2064_REG089, data_rf);
3942 k = wlc_lcnphy_calc_floor(coeff_y, 0);
3943 y = 8 + k;
3944 k = wlc_lcnphy_calc_floor(coeff_y, 1);
3945 x = 8 - k;
3946 data_rf = (x * 16 + y);
3947 write_radio_reg(pi, RADIO_2064_REG08A, data_rf);
3948 break;
3949 case 4:
3950 k = wlc_lcnphy_calc_floor(coeff_x, 0);
3951 y = 8 + k;
3952 k = wlc_lcnphy_calc_floor(coeff_x, 1);
3953 x = 8 - k;
3954 data_rf = (x * 16 + y);
3955 write_radio_reg(pi, RADIO_2064_REG08B, data_rf);
3956 k = wlc_lcnphy_calc_floor(coeff_y, 0);
3957 y = 8 + k;
3958 k = wlc_lcnphy_calc_floor(coeff_y, 1);
3959 x = 8 - k;
3960 data_rf = (x * 16 + y);
3961 write_radio_reg(pi, RADIO_2064_REG08C, data_rf);
3962 break;
3963 }
3964}
3965
3966static struct lcnphy_unsign16_struct
3967wlc_lcnphy_get_cc(struct brcms_phy *pi, int cal_type)
3968{
3969 u16 a, b, didq;
3970 u8 di0, dq0, ei, eq, fi, fq;
3971 struct lcnphy_unsign16_struct cc;
3972 cc.re = 0;
3973 cc.im = 0;
3974 switch (cal_type) {
3975 case 0:
3976 wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
3977 cc.re = a;
3978 cc.im = b;
3979 break;
3980 case 2:
3981 didq = wlc_lcnphy_get_tx_locc(pi);
3982 di0 = (((didq & 0xff00) << 16) >> 24);
3983 dq0 = (((didq & 0x00ff) << 24) >> 24);
3984 cc.re = (u16) di0;
3985 cc.im = (u16) dq0;
3986 break;
3987 case 3:
3988 wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
3989 cc.re = (u16) ei;
3990 cc.im = (u16) eq;
3991 break;
3992 case 4:
3993 wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
3994 cc.re = (u16) fi;
3995 cc.im = (u16) fq;
3996 break;
3997 }
3998 return cc;
3999}
4000
4001static void
4002wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels,
4003 int step_size_lg2)
4004{
4005 const struct lcnphy_spb_tone *phy_c1;
4006 struct lcnphy_spb_tone phy_c2;
4007 struct lcnphy_unsign16_struct phy_c3;
4008 int phy_c4, phy_c5, k, l, j, phy_c6;
4009 u16 phy_c7, phy_c8, phy_c9;
4010 s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16;
4011 s16 *ptr, phy_c17;
4012 s32 phy_c18, phy_c19;
4013 u32 phy_c20, phy_c21;
4014 bool phy_c22, phy_c23, phy_c24, phy_c25;
4015 u16 phy_c26, phy_c27;
4016 u16 phy_c28, phy_c29, phy_c30;
4017 u16 phy_c31;
4018 u16 *phy_c32;
4019 phy_c21 = 0;
4020 phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0;
4021 ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
4022 if (NULL == ptr) {
4023 return;
4024 }
4025
4026 phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
4027 if (NULL == phy_c32) {
4028 kfree(ptr);
4029 return;
4030 }
4031 phy_c26 = read_phy_reg(pi, 0x6da);
4032 phy_c27 = read_phy_reg(pi, 0x6db);
4033 phy_c31 = read_radio_reg(pi, RADIO_2064_REG026);
4034 write_phy_reg(pi, 0x93d, 0xC0);
4035
4036 wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0);
4037 write_phy_reg(pi, 0x6da, 0xffff);
4038 or_phy_reg(pi, 0x6db, 0x3);
4039
4040 wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32);
4041 udelay(500);
4042 phy_c28 = read_phy_reg(pi, 0x938);
4043 phy_c29 = read_phy_reg(pi, 0x4d7);
4044 phy_c30 = read_phy_reg(pi, 0x4d8);
4045 or_phy_reg(pi, 0x938, 0x1 << 2);
4046 or_phy_reg(pi, 0x4d7, 0x1 << 2);
4047 or_phy_reg(pi, 0x4d7, 0x1 << 3);
4048 mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12);
4049 or_phy_reg(pi, 0x4d8, 1 << 0);
4050 or_phy_reg(pi, 0x4d8, 1 << 1);
4051 mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2);
4052 mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12);
4053 phy_c1 = &lcnphy_spb_tone_3750[0];
4054 phy_c4 = 32;
4055
4056 if (num_levels == 0) {
4057 if (cal_type != 0) {
4058 num_levels = 4;
4059 } else {
4060 num_levels = 9;
4061 }
4062 }
4063 if (step_size_lg2 == 0) {
4064 if (cal_type != 0) {
4065 step_size_lg2 = 3;
4066 } else {
4067 step_size_lg2 = 8;
4068 }
4069 }
4070
4071 phy_c7 = (1 << step_size_lg2);
4072 phy_c3 = wlc_lcnphy_get_cc(pi, cal_type);
4073 phy_c15 = (s16) phy_c3.re;
4074 phy_c16 = (s16) phy_c3.im;
4075 if (cal_type == 2) {
4076 if (phy_c3.re > 127)
4077 phy_c15 = phy_c3.re - 256;
4078 if (phy_c3.im > 127)
4079 phy_c16 = phy_c3.im - 256;
4080 }
4081 wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
4082 udelay(20);
4083 for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
4084 phy_c23 = 1;
4085 phy_c22 = 0;
4086 switch (cal_type) {
4087 case 0:
4088 phy_c10 = 511;
4089 break;
4090 case 2:
4091 phy_c10 = 127;
4092 break;
4093 case 3:
4094 phy_c10 = 15;
4095 break;
4096 case 4:
4097 phy_c10 = 15;
4098 break;
4099 }
4100
4101 phy_c9 = read_phy_reg(pi, 0x93d);
4102 phy_c9 = 2 * phy_c9;
4103 phy_c24 = 0;
4104 phy_c5 = 7;
4105 phy_c25 = 1;
4106 while (1) {
4107 write_radio_reg(pi, RADIO_2064_REG026,
4108 (phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
4109 udelay(50);
4110 phy_c22 = 0;
4111 ptr[130] = 0;
4112 wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
4113 if (ptr[130] == 1)
4114 phy_c22 = 1;
4115 if (phy_c22)
4116 phy_c5 -= 1;
4117 if ((phy_c22 != phy_c24) && (!phy_c25))
4118 break;
4119 if (!phy_c22)
4120 phy_c5 += 1;
4121 if (phy_c5 <= 0 || phy_c5 >= 7)
4122 break;
4123 phy_c24 = phy_c22;
4124 phy_c25 = 0;
4125 }
4126
4127 if (phy_c5 < 0)
4128 phy_c5 = 0;
4129 else if (phy_c5 > 7)
4130 phy_c5 = 7;
4131
4132 for (k = -phy_c7; k <= phy_c7; k += phy_c7) {
4133 for (l = -phy_c7; l <= phy_c7; l += phy_c7) {
4134 phy_c11 = phy_c15 + k;
4135 phy_c12 = phy_c16 + l;
4136
4137 if (phy_c11 < -phy_c10)
4138 phy_c11 = -phy_c10;
4139 else if (phy_c11 > phy_c10)
4140 phy_c11 = phy_c10;
4141 if (phy_c12 < -phy_c10)
4142 phy_c12 = -phy_c10;
4143 else if (phy_c12 > phy_c10)
4144 phy_c12 = phy_c10;
4145 wlc_lcnphy_set_cc(pi, cal_type, phy_c11,
4146 phy_c12);
4147 udelay(20);
4148 wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2);
4149
4150 phy_c18 = 0;
4151 phy_c19 = 0;
4152 for (j = 0; j < 128; j++) {
4153 if (cal_type != 0) {
4154 phy_c6 = j % phy_c4;
4155 } else {
4156 phy_c6 = (2 * j) % phy_c4;
4157 }
4158 phy_c2.re = phy_c1[phy_c6].re;
4159 phy_c2.im = phy_c1[phy_c6].im;
4160 phy_c17 = ptr[j];
4161 phy_c18 = phy_c18 + phy_c17 * phy_c2.re;
4162 phy_c19 = phy_c19 + phy_c17 * phy_c2.im;
4163 }
4164
4165 phy_c18 = phy_c18 >> 10;
4166 phy_c19 = phy_c19 >> 10;
4167 phy_c20 =
4168 ((phy_c18 * phy_c18) + (phy_c19 * phy_c19));
4169
4170 if (phy_c23 || phy_c20 < phy_c21) {
4171 phy_c21 = phy_c20;
4172 phy_c13 = phy_c11;
4173 phy_c14 = phy_c12;
4174 }
4175 phy_c23 = 0;
4176 }
4177 }
4178 phy_c23 = 1;
4179 phy_c15 = phy_c13;
4180 phy_c16 = phy_c14;
4181 phy_c7 = phy_c7 >> 1;
4182 wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
4183 udelay(20);
4184 }
4185 goto cleanup;
4186 cleanup:
4187 wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32);
4188 wlc_lcnphy_stop_tx_tone(pi);
4189 write_phy_reg(pi, 0x6da, phy_c26);
4190 write_phy_reg(pi, 0x6db, phy_c27);
4191 write_phy_reg(pi, 0x938, phy_c28);
4192 write_phy_reg(pi, 0x4d7, phy_c29);
4193 write_phy_reg(pi, 0x4d8, phy_c30);
4194 write_radio_reg(pi, RADIO_2064_REG026, phy_c31);
4195
4196 kfree(phy_c32);
4197 kfree(ptr);
4198}
4199
4200static void
4201wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save)
4202{
4203 int i;
4204
4205 and_phy_reg(pi, 0x44c, 0x0 >> 11);
4206
4207 and_phy_reg(pi, 0x43b, 0xC);
4208
4209 for (i = 0; i < 20; i++) {
4210 write_radio_reg(pi, iqlo_loopback_rf_regs[i],
4211 values_to_save[i]);
4212 }
4213}
4214
4215static void
4216wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
4217 const struct lcnphy_tx_gain_tbl_entry *gain_table) {
4218 u32 j;
4219 struct phytbl_info tab;
4220 u32 val;
4221 u16 pa_gain;
4222 u16 gm_gain;
4223
4224 if (CHSPEC_IS5G(pi->radio_chanspec))
4225 pa_gain = 0x70;
4226 else
4227 pa_gain = 0x70;
4228
4229 if (pi->sh->boardflags & BFL_FEM)
4230 pa_gain = 0x10;
4231 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
4232 tab.tbl_width = 32;
4233 tab.tbl_len = 1;
4234 tab.tbl_ptr = &val;
4235
4236 for (j = 0; j < 128; j++) {
4237 gm_gain = gain_table[j].gm;
4238 val = (((u32) pa_gain << 24) |
4239 (gain_table[j].pad << 16) |
4240 (gain_table[j].pga << 8) | gm_gain);
4241
4242 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j;
4243 wlc_lcnphy_write_table(pi, &tab);
4244
4245 val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20);
4246 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j;
4247 wlc_lcnphy_write_table(pi, &tab);
4248 }
4249}
4250
4251static void wlc_lcnphy_load_rfpower(struct brcms_phy *pi)
4252{
4253 struct phytbl_info tab;
4254 u32 val, bbmult, rfgain;
4255 u8 index;
4256 u8 scale_factor = 1;
4257 s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift;
4258
4259 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
4260 tab.tbl_width = 32;
4261 tab.tbl_len = 1;
4262
4263 for (index = 0; index < 128; index++) {
4264 tab.tbl_ptr = &bbmult;
4265 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
4266 wlc_lcnphy_read_table(pi, &tab);
4267 bbmult = bbmult >> 20;
4268
4269 tab.tbl_ptr = &rfgain;
4270 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
4271 wlc_lcnphy_read_table(pi, &tab);
4272
4273 qm_log10((s32) (bbmult), 0, &temp1, &qQ1);
4274 qm_log10((s32) (1 << 6), 0, &temp2, &qQ2);
4275
4276 if (qQ1 < qQ2) {
4277 temp2 = qm_shr16(temp2, qQ2 - qQ1);
4278 qQ = qQ1;
4279 } else {
4280 temp1 = qm_shr16(temp1, qQ1 - qQ2);
4281 qQ = qQ2;
4282 }
4283 temp = qm_sub16(temp1, temp2);
4284
4285 if (qQ >= 4)
4286 shift = qQ - 4;
4287 else
4288 shift = 4 - qQ;
4289
4290 val = (((index << shift) + (5 * temp) +
4291 (1 << (scale_factor + shift - 3))) >> (scale_factor +
4292 shift - 2));
4293
4294 tab.tbl_ptr = &val;
4295 tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
4296 wlc_lcnphy_write_table(pi, &tab);
4297 }
4298}
4299
4300static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
4301{
4302 uint idx;
4303 u8 phybw40;
4304 struct phytbl_info tab;
4305 u32 val;
4306
4307 phybw40 = CHSPEC_IS40(pi->radio_chanspec);
4308
4309 for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++) {
4310 wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]);
4311 }
4312
4313 if (pi->sh->boardflags & BFL_FEM_BT) {
4314 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
4315 tab.tbl_width = 16;
4316 tab.tbl_ptr = &val;
4317 tab.tbl_len = 1;
4318 val = 100;
4319 tab.tbl_offset = 4;
4320 wlc_lcnphy_write_table(pi, &tab);
4321 }
4322
4323 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
4324 tab.tbl_width = 16;
4325 tab.tbl_ptr = &val;
4326 tab.tbl_len = 1;
4327
4328 val = 114;
4329 tab.tbl_offset = 0;
4330 wlc_lcnphy_write_table(pi, &tab);
4331
4332 val = 130;
4333 tab.tbl_offset = 1;
4334 wlc_lcnphy_write_table(pi, &tab);
4335
4336 val = 6;
4337 tab.tbl_offset = 8;
4338 wlc_lcnphy_write_table(pi, &tab);
4339
4340 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4341 if (pi->sh->boardflags & BFL_FEM)
4342 wlc_lcnphy_load_tx_gain_table(pi,
4343 dot11lcnphy_2GHz_extPA_gaintable_rev0);
4344 else
4345 wlc_lcnphy_load_tx_gain_table(pi,
4346 dot11lcnphy_2GHz_gaintable_rev0);
4347 }
4348
4349 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
4350 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4351 for (idx = 0;
4352 idx < dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
4353 idx++)
4354 if (pi->sh->boardflags & BFL_EXTLNA)
4355 wlc_lcnphy_write_table(pi,
4356 &dot11lcnphytbl_rx_gain_info_extlna_2G_rev2
4357 [idx]);
4358 else
4359 wlc_lcnphy_write_table(pi,
4360 &dot11lcnphytbl_rx_gain_info_2G_rev2
4361 [idx]);
4362 } else {
4363 for (idx = 0;
4364 idx < dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
4365 idx++)
4366 if (pi->sh->boardflags & BFL_EXTLNA_5GHz)
4367 wlc_lcnphy_write_table(pi,
4368 &dot11lcnphytbl_rx_gain_info_extlna_5G_rev2
4369 [idx]);
4370 else
4371 wlc_lcnphy_write_table(pi,
4372 &dot11lcnphytbl_rx_gain_info_5G_rev2
4373 [idx]);
4374 }
4375 }
4376
4377 if ((pi->sh->boardflags & BFL_FEM)
4378 && !(pi->sh->boardflags & BFL_FEM_BT))
4379 wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
4380 else if (pi->sh->boardflags & BFL_FEM_BT) {
4381 if (pi->sh->boardrev < 0x1250)
4382 wlc_lcnphy_write_table(pi,
4383 &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
4384 else
4385 wlc_lcnphy_write_table(pi,
4386 &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
4387 } else
4388 wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
4389
4390 wlc_lcnphy_load_rfpower(pi);
4391
4392 wlc_lcnphy_clear_papd_comptable(pi);
4393}
4394
4395static void wlc_lcnphy_rev0_baseband_init(struct brcms_phy *pi)
4396{
4397 u16 afectrl1;
4398 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4399
4400 write_radio_reg(pi, RADIO_2064_REG11C, 0x0);
4401
4402 write_phy_reg(pi, 0x43b, 0x0);
4403 write_phy_reg(pi, 0x43c, 0x0);
4404 write_phy_reg(pi, 0x44c, 0x0);
4405 write_phy_reg(pi, 0x4e6, 0x0);
4406 write_phy_reg(pi, 0x4f9, 0x0);
4407 write_phy_reg(pi, 0x4b0, 0x0);
4408 write_phy_reg(pi, 0x938, 0x0);
4409 write_phy_reg(pi, 0x4b0, 0x0);
4410 write_phy_reg(pi, 0x44e, 0);
4411
4412 or_phy_reg(pi, 0x567, 0x03);
4413
4414 or_phy_reg(pi, 0x44a, 0x44);
4415 write_phy_reg(pi, 0x44a, 0x80);
4416
4417 if (!(pi->sh->boardflags & BFL_FEM))
4418 wlc_lcnphy_set_tx_pwr_by_index(pi, 52);
4419
4420 if (0) {
4421 afectrl1 = 0;
4422 afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) |
4423 (pi_lcn->lcnphy_rssi_vc << 4) | (pi_lcn->
4424 lcnphy_rssi_gs
4425 << 10));
4426 write_phy_reg(pi, 0x43e, afectrl1);
4427 }
4428
4429 mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0);
4430 if (pi->sh->boardflags & BFL_FEM) {
4431 mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0);
4432
4433 write_phy_reg(pi, 0x910, 0x1);
4434 }
4435
4436 mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8);
4437 mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0);
4438 mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0);
4439
4440}
4441
4442static void wlc_lcnphy_rev2_baseband_init(struct brcms_phy *pi)
4443{
4444 if (CHSPEC_IS5G(pi->radio_chanspec)) {
4445 mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0);
4446
4447 mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8);
4448 }
4449}
4450
4451static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi)
4452{
4453 s16 temp;
4454 struct phytbl_info tab;
4455 u32 tableBuffer[2];
4456 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4457
4458 if (NORADIO_ENAB(pi->pubpi))
4459 return;
4460
4461 temp = (s16) read_phy_reg(pi, 0x4df);
4462 pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0;
4463
4464 if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127)
4465 pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256;
4466
4467 pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8;
4468
4469 if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127)
4470 pi_lcn->lcnphy_dsssgainidxtableoffset -= 256;
4471
4472 tab.tbl_ptr = tableBuffer;
4473 tab.tbl_len = 2;
4474 tab.tbl_id = 17;
4475 tab.tbl_offset = 59;
4476 tab.tbl_width = 32;
4477 wlc_lcnphy_read_table(pi, &tab);
4478
4479 if (tableBuffer[0] > 63)
4480 tableBuffer[0] -= 128;
4481 pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0];
4482
4483 if (tableBuffer[1] > 63)
4484 tableBuffer[1] -= 128;
4485 pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1];
4486
4487 temp = (s16) (read_phy_reg(pi, 0x434)
4488 & (0xff << 0));
4489 if (temp > 127)
4490 temp -= 256;
4491 pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp;
4492
4493 pi_lcn->lcnphy_Med_Low_Gain_db = (read_phy_reg(pi, 0x424)
4494 & (0xff << 8))
4495 >> 8;
4496 pi_lcn->lcnphy_Very_Low_Gain_db = (read_phy_reg(pi, 0x425)
4497 & (0xff << 0))
4498 >> 0;
4499
4500 tab.tbl_ptr = tableBuffer;
4501 tab.tbl_len = 2;
4502 tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX;
4503 tab.tbl_offset = 28;
4504 tab.tbl_width = 32;
4505 wlc_lcnphy_read_table(pi, &tab);
4506
4507 pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0];
4508 pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1];
4509
4510}
4511
4512static void wlc_lcnphy_bu_tweaks(struct brcms_phy *pi)
4513{
4514 if (NORADIO_ENAB(pi->pubpi))
4515 return;
4516
4517 or_phy_reg(pi, 0x805, 0x1);
4518
4519 mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0);
4520
4521 mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0);
4522
4523 write_phy_reg(pi, 0x414, 0x1e10);
4524 write_phy_reg(pi, 0x415, 0x0640);
4525
4526 mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8);
4527
4528 or_phy_reg(pi, 0x44a, 0x44);
4529 write_phy_reg(pi, 0x44a, 0x80);
4530 mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0);
4531
4532 mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0);
4533
4534 if (!(pi->sh->boardrev < 0x1204))
4535 mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0);
4536
4537 write_phy_reg(pi, 0x7d6, 0x0902);
4538 mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0);
4539
4540 mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4);
4541
4542 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
4543 mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0);
4544
4545 mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0);
4546
4547 mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0);
4548
4549 mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0);
4550
4551 mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
4552
4553 mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4);
4554 mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0);
4555 mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90);
4556 mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2);
4557 mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0);
4558
4559 mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2);
4560
4561 wlc_lcnphy_clear_tx_power_offsets(pi);
4562 mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6);
4563
4564 }
4565}
4566
4567static void wlc_lcnphy_baseband_init(struct brcms_phy *pi)
4568{
4569
4570 wlc_lcnphy_tbl_init(pi);
4571 wlc_lcnphy_rev0_baseband_init(pi);
4572 if (LCNREV_IS(pi->pubpi.phy_rev, 2))
4573 wlc_lcnphy_rev2_baseband_init(pi);
4574 wlc_lcnphy_bu_tweaks(pi);
4575}
4576
4577static void wlc_radio_2064_init(struct brcms_phy *pi)
4578{
4579 u32 i;
4580 struct lcnphy_radio_regs *lcnphyregs = NULL;
4581
4582 lcnphyregs = lcnphy_radio_regs_2064;
4583
4584 for (i = 0; lcnphyregs[i].address != 0xffff; i++)
4585 if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a)
4586 write_radio_reg(pi,
4587 ((lcnphyregs[i].address & 0x3fff) |
4588 RADIO_DEFAULT_CORE),
4589 (u16) lcnphyregs[i].init_a);
4590 else if (lcnphyregs[i].do_init_g)
4591 write_radio_reg(pi,
4592 ((lcnphyregs[i].address & 0x3fff) |
4593 RADIO_DEFAULT_CORE),
4594 (u16) lcnphyregs[i].init_g);
4595
4596 write_radio_reg(pi, RADIO_2064_REG032, 0x62);
4597 write_radio_reg(pi, RADIO_2064_REG033, 0x19);
4598
4599 write_radio_reg(pi, RADIO_2064_REG090, 0x10);
4600
4601 write_radio_reg(pi, RADIO_2064_REG010, 0x00);
4602
4603 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
4604
4605 write_radio_reg(pi, RADIO_2064_REG060, 0x7f);
4606 write_radio_reg(pi, RADIO_2064_REG061, 0x72);
4607 write_radio_reg(pi, RADIO_2064_REG062, 0x7f);
4608 }
4609
4610 write_radio_reg(pi, RADIO_2064_REG01D, 0x02);
4611 write_radio_reg(pi, RADIO_2064_REG01E, 0x06);
4612
4613 mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0);
4614
4615 mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3);
4616
4617 mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6);
4618
4619 mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9);
4620
4621 mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12);
4622
4623 write_phy_reg(pi, 0x4ea, 0x4688);
4624
4625 mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
4626
4627 mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
4628
4629 mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0);
4630
4631 wlc_lcnphy_set_tx_locc(pi, 0);
4632
4633 wlc_lcnphy_rcal(pi);
4634
4635 wlc_lcnphy_rc_cal(pi);
4636}
4637
4638static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
4639{
4640 if (NORADIO_ENAB(pi->pubpi))
4641 return;
4642
4643 wlc_radio_2064_init(pi);
4644}
4645
4646static void wlc_lcnphy_rcal(struct brcms_phy *pi)
4647{
4648 u8 rcal_value;
4649
4650 if (NORADIO_ENAB(pi->pubpi))
4651 return;
4652
4653 and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
4654
4655 or_radio_reg(pi, RADIO_2064_REG004, 0x40);
4656 or_radio_reg(pi, RADIO_2064_REG120, 0x10);
4657
4658 or_radio_reg(pi, RADIO_2064_REG078, 0x80);
4659 or_radio_reg(pi, RADIO_2064_REG129, 0x02);
4660
4661 or_radio_reg(pi, RADIO_2064_REG057, 0x01);
4662
4663 or_radio_reg(pi, RADIO_2064_REG05B, 0x02);
4664 mdelay(5);
4665 SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000);
4666
4667 if (wlc_radio_2064_rcal_done(pi)) {
4668 rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C);
4669 rcal_value = rcal_value & 0x1f;
4670 }
4671
4672 and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
4673
4674 and_radio_reg(pi, RADIO_2064_REG057, 0xFE);
4675}
4676
4677static void wlc_lcnphy_rc_cal(struct brcms_phy *pi)
4678{
4679 u8 dflt_rc_cal_val;
4680 u16 flt_val;
4681
4682 if (NORADIO_ENAB(pi->pubpi))
4683 return;
4684
4685 dflt_rc_cal_val = 7;
4686 if (LCNREV_IS(pi->pubpi.phy_rev, 1))
4687 dflt_rc_cal_val = 11;
4688 flt_val =
4689 (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) |
4690 (dflt_rc_cal_val);
4691 write_phy_reg(pi, 0x933, flt_val);
4692 write_phy_reg(pi, 0x934, flt_val);
4693 write_phy_reg(pi, 0x935, flt_val);
4694 write_phy_reg(pi, 0x936, flt_val);
4695 write_phy_reg(pi, 0x937, (flt_val & 0x1FF));
4696
4697 return;
4698}
4699
4700static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
4701{
4702 s8 txpwr = 0;
4703 int i;
4704 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4705
4706 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4707 u16 cckpo = 0;
4708 u32 offset_ofdm, offset_mcs;
4709
4710 pi_lcn->lcnphy_tr_isolation_mid =
4711 (u8) PHY_GETINTVAR(pi, "triso2g");
4712
4713 pi_lcn->lcnphy_rx_power_offset =
4714 (u8) PHY_GETINTVAR(pi, "rxpo2g");
4715
4716 pi->txpa_2g[0] = (s16) PHY_GETINTVAR(pi, "pa0b0");
4717 pi->txpa_2g[1] = (s16) PHY_GETINTVAR(pi, "pa0b1");
4718 pi->txpa_2g[2] = (s16) PHY_GETINTVAR(pi, "pa0b2");
4719
4720 pi_lcn->lcnphy_rssi_vf = (u8) PHY_GETINTVAR(pi, "rssismf2g");
4721 pi_lcn->lcnphy_rssi_vc = (u8) PHY_GETINTVAR(pi, "rssismc2g");
4722 pi_lcn->lcnphy_rssi_gs = (u8) PHY_GETINTVAR(pi, "rssisav2g");
4723
4724 {
4725 pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
4726 pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
4727 pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs;
4728
4729 pi_lcn->lcnphy_rssi_vf_hightemp =
4730 pi_lcn->lcnphy_rssi_vf;
4731 pi_lcn->lcnphy_rssi_vc_hightemp =
4732 pi_lcn->lcnphy_rssi_vc;
4733 pi_lcn->lcnphy_rssi_gs_hightemp =
4734 pi_lcn->lcnphy_rssi_gs;
4735 }
4736
4737 txpwr = (s8) PHY_GETINTVAR(pi, "maxp2ga0");
4738 pi->tx_srom_max_2g = txpwr;
4739
4740 for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
4741 pi->txpa_2g_low_temp[i] = pi->txpa_2g[i];
4742 pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
4743 }
4744
4745 cckpo = (u16) PHY_GETINTVAR(pi, "cck2gpo");
4746 if (cckpo) {
4747 uint max_pwr_chan = txpwr;
4748
4749 for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
4750 pi->tx_srom_max_rate_2g[i] = max_pwr_chan -
4751 ((cckpo & 0xf) * 2);
4752 cckpo >>= 4;
4753 }
4754
4755 offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
4756 for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
4757 pi->tx_srom_max_rate_2g[i] = max_pwr_chan -
4758 ((offset_ofdm & 0xf) * 2);
4759 offset_ofdm >>= 4;
4760 }
4761 } else {
4762 u8 opo = 0;
4763
4764 opo = (u8) PHY_GETINTVAR(pi, "opo");
4765
4766 for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
4767 pi->tx_srom_max_rate_2g[i] = txpwr;
4768 }
4769
4770 offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
4771
4772 for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
4773 pi->tx_srom_max_rate_2g[i] = txpwr -
4774 ((offset_ofdm & 0xf) * 2);
4775 offset_ofdm >>= 4;
4776 }
4777 offset_mcs =
4778 ((u16) PHY_GETINTVAR(pi, "mcs2gpo1") << 16) |
4779 (u16) PHY_GETINTVAR(pi, "mcs2gpo0");
4780 pi_lcn->lcnphy_mcs20_po = offset_mcs;
4781 for (i = TXP_FIRST_SISO_MCS_20;
4782 i <= TXP_LAST_SISO_MCS_20; i++) {
4783 pi->tx_srom_max_rate_2g[i] =
4784 txpwr - ((offset_mcs & 0xf) * 2);
4785 offset_mcs >>= 4;
4786 }
4787 }
4788
4789 pi_lcn->lcnphy_rawtempsense =
4790 (u16) PHY_GETINTVAR(pi, "rawtempsense");
4791 pi_lcn->lcnphy_measPower =
4792 (u8) PHY_GETINTVAR(pi, "measpower");
4793 pi_lcn->lcnphy_tempsense_slope =
4794 (u8) PHY_GETINTVAR(pi, "tempsense_slope");
4795 pi_lcn->lcnphy_hw_iqcal_en =
4796 (bool) PHY_GETINTVAR(pi, "hw_iqcal_en");
4797 pi_lcn->lcnphy_iqcal_swp_dis =
4798 (bool) PHY_GETINTVAR(pi, "iqcal_swp_dis");
4799 pi_lcn->lcnphy_tempcorrx =
4800 (u8) PHY_GETINTVAR(pi, "tempcorrx");
4801 pi_lcn->lcnphy_tempsense_option =
4802 (u8) PHY_GETINTVAR(pi, "tempsense_option");
4803 pi_lcn->lcnphy_freqoffset_corr =
4804 (u8) PHY_GETINTVAR(pi, "freqoffset_corr");
4805 if ((u8) getintvar(pi->vars, "aa2g") > 1)
4806 wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi,
4807 (u8) getintvar(pi->vars,
4808 "aa2g"));
4809 }
4810 pi_lcn->lcnphy_cck_dig_filt_type = -1;
4811 if (PHY_GETVAR(pi, "cckdigfilttype")) {
4812 s16 temp;
4813 temp = (s16) PHY_GETINTVAR(pi, "cckdigfilttype");
4814 if (temp >= 0) {
4815 pi_lcn->lcnphy_cck_dig_filt_type = temp;
4816 }
4817 }
4818
4819 return true;
4820}
4821
4822void wlc_2064_vco_cal(struct brcms_phy *pi)
4823{
4824 u8 calnrst;
4825
4826 mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3);
4827 calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8;
4828 write_radio_reg(pi, RADIO_2064_REG056, calnrst);
4829 udelay(1);
4830 write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03);
4831 udelay(1);
4832 write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07);
4833 udelay(300);
4834 mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0);
4835}
4836
4837static void
4838wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
4839{
4840 uint i;
4841 const struct chan_info_2064_lcnphy *ci;
4842 u8 rfpll_doubler = 0;
4843 u8 pll_pwrup, pll_pwrup_ovr;
4844 fixed qFxtal, qFref, qFvco, qFcal;
4845 u8 d15, d16, f16, e44, e45;
4846 u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div;
4847 u16 loop_bw, d30, setCount;
4848 if (NORADIO_ENAB(pi->pubpi))
4849 return;
4850 ci = &chan_info_2064_lcnphy[0];
4851 rfpll_doubler = 1;
4852
4853 mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
4854
4855 write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
4856 if (!rfpll_doubler) {
4857 loop_bw = PLL_2064_LOOP_BW;
4858 d30 = PLL_2064_D30;
4859 } else {
4860 loop_bw = PLL_2064_LOOP_BW_DOUBLER;
4861 d30 = PLL_2064_D30_DOUBLER;
4862 }
4863
4864 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4865 for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++)
4866 if (chan_info_2064_lcnphy[i].chan == channel)
4867 break;
4868
4869 if (i >= ARRAY_SIZE(chan_info_2064_lcnphy)) {
4870 return;
4871 }
4872
4873 ci = &chan_info_2064_lcnphy[i];
4874 }
4875
4876 write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune);
4877
4878 mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx);
4879
4880 mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl);
4881
4882 mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g);
4883
4884 mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2,
4885 (ci->logen_rccr_rx) << 2);
4886
4887 mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune);
4888
4889 mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4,
4890 (ci->pa_rxrf_lna2_freq_tune) << 4);
4891
4892 write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1);
4893
4894 pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044);
4895 pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B);
4896
4897 or_radio_reg(pi, RADIO_2064_REG044, 0x07);
4898
4899 or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1);
4900 e44 = 0;
4901 e45 = 0;
4902
4903 fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
4904 if (pi->xtalfreq > 26000000)
4905 e44 = 1;
4906 if (pi->xtalfreq > 52000000)
4907 e45 = 1;
4908 if (e44 == 0)
4909 fcal_div = 1;
4910 else if (e45 == 0)
4911 fcal_div = 2;
4912 else
4913 fcal_div = 4;
4914 fvco3 = (ci->freq * 3);
4915 fref3 = 2 * fpfd;
4916
4917 qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16);
4918 qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16);
4919 qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ;
4920 qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16);
4921
4922 write_radio_reg(pi, RADIO_2064_REG04F, 0x02);
4923
4924 d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1;
4925 write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2)));
4926 write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5);
4927
4928 d16 = (qFcal * 8 / (d15 + 1)) - 1;
4929 write_radio_reg(pi, RADIO_2064_REG051, d16);
4930
4931 f16 = ((d16 + 1) * (d15 + 1)) / qFcal;
4932 setCount = f16 * 3 * (ci->freq) / 32 - 1;
4933 mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0),
4934 (u8) (setCount >> 8));
4935
4936 or_radio_reg(pi, RADIO_2064_REG053, 0x10);
4937 write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff));
4938
4939 div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4;
4940
4941 div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4;
4942 while (div_frac >= fref3) {
4943 div_int++;
4944 div_frac -= fref3;
4945 }
4946 div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20);
4947
4948 mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0),
4949 (u8) (div_int >> 4));
4950 mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4),
4951 (u8) (div_int << 4));
4952 mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0),
4953 (u8) (div_frac >> 16));
4954 write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff);
4955 write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff);
4956
4957 write_radio_reg(pi, RADIO_2064_REG040, 0xfb);
4958
4959 write_radio_reg(pi, RADIO_2064_REG041, 0x9A);
4960 write_radio_reg(pi, RADIO_2064_REG042, 0xA3);
4961 write_radio_reg(pi, RADIO_2064_REG043, 0x0C);
4962
4963 {
4964 u8 h29, h23, c28, d29, h28_ten, e30, h30_ten, cp_current;
4965 u16 c29, c38, c30, g30, d28;
4966 c29 = loop_bw;
4967 d29 = 200;
4968 c38 = 1250;
4969 h29 = d29 / c29;
4970 h23 = 1;
4971 c28 = 30;
4972 d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) *
4973 (fvco3 / 2 - PLL_2064_LOW_END_VCO)) /
4974 (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO))
4975 + PLL_2064_LOW_END_KVCO;
4976 h28_ten = (d28 * 10) / c28;
4977 c30 = 2640;
4978 e30 = (d30 - 680) / 490;
4979 g30 = 680 + (e30 * 490);
4980 h30_ten = (g30 * 10) / c30;
4981 cp_current = ((c38 * h29 * h23 * 100) / h28_ten) / h30_ten;
4982 mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current);
4983 }
4984 if (channel >= 1 && channel <= 5)
4985 write_radio_reg(pi, RADIO_2064_REG03C, 0x8);
4986 else
4987 write_radio_reg(pi, RADIO_2064_REG03C, 0x7);
4988 write_radio_reg(pi, RADIO_2064_REG03D, 0x3);
4989
4990 mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c);
4991 udelay(1);
4992
4993 wlc_2064_vco_cal(pi);
4994
4995 write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup);
4996 write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr);
4997 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
4998 write_radio_reg(pi, RADIO_2064_REG038, 3);
4999 write_radio_reg(pi, RADIO_2064_REG091, 7);
5000 }
5001}
5002
5003bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi)
5004{
5005 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
5006 return 0;
5007 else
5008 return (LCNPHY_TX_PWR_CTRL_HW ==
5009 wlc_lcnphy_get_tx_pwr_ctrl((pi)));
5010}
5011
5012void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi)
5013{
5014 u16 pwr_ctrl;
5015 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
5016 wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
5017 } else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
5018
5019 pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
5020 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
5021 wlc_lcnphy_txpower_recalc_target(pi);
5022
5023 wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl);
5024 } else
5025 return;
5026}
5027
5028void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
5029{
5030 kfree(pi->u.pi_lcnphy);
5031}
5032
5033bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
5034{
5035 struct brcms_phy_lcnphy *pi_lcn;
5036
5037 pi->u.pi_lcnphy = kzalloc(sizeof(struct brcms_phy_lcnphy), GFP_ATOMIC);
5038 if (pi->u.pi_lcnphy == NULL) {
5039 return false;
5040 }
5041
5042 pi_lcn = pi->u.pi_lcnphy;
5043
5044 if ((0 == (pi->sh->boardflags & BFL_NOPA)) && !NORADIO_ENAB(pi->pubpi)) {
5045 pi->hwpwrctrl = true;
5046 pi->hwpwrctrl_capable = true;
5047 }
5048
5049 pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih);
5050 pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
5051
5052 pi->pi_fptr.init = wlc_phy_init_lcnphy;
5053 pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy;
5054 pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy;
5055 pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy;
5056 pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc;
5057 pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc;
5058 pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc;
5059 pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft;
5060 pi->pi_fptr.detach = wlc_phy_detach_lcnphy;
5061
5062 if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
5063 return false;
5064
5065 if ((pi->sh->boardflags & BFL_FEM) && (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
5066 if (pi_lcn->lcnphy_tempsense_option == 3) {
5067 pi->hwpwrctrl = true;
5068 pi->hwpwrctrl_capable = true;
5069 pi->temppwrctrl_capable = false;
5070 } else {
5071 pi->hwpwrctrl = false;
5072 pi->hwpwrctrl_capable = false;
5073 pi->temppwrctrl_capable = true;
5074 }
5075 }
5076
5077 return true;
5078}
5079
5080static void wlc_lcnphy_set_rx_gain(struct brcms_phy *pi, u32 gain)
5081{
5082 u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19;
5083
5084 trsw = (gain & ((u32) 1 << 28)) ? 0 : 1;
5085 ext_lna = (u16) (gain >> 29) & 0x01;
5086 lna1 = (u16) (gain >> 0) & 0x0f;
5087 lna2 = (u16) (gain >> 4) & 0x0f;
5088 tia = (u16) (gain >> 8) & 0xf;
5089 biq0 = (u16) (gain >> 12) & 0xf;
5090 biq1 = (u16) (gain >> 16) & 0xf;
5091
5092 gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) |
5093 ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) |
5094 ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12));
5095 gain16_19 = biq1;
5096
5097 mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0);
5098 mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
5099 mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
5100 mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
5101 mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
5102
5103 if (CHSPEC_IS2G(pi->radio_chanspec)) {
5104 mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
5105 mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
5106 }
5107 wlc_lcnphy_rx_gain_override_enable(pi, true);
5108}
5109
5110static u32 wlc_lcnphy_get_receive_power(struct brcms_phy *pi, s32 *gain_index)
5111{
5112 u32 received_power = 0;
5113 s32 max_index = 0;
5114 u32 gain_code = 0;
5115 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
5116
5117 max_index = 36;
5118 if (*gain_index >= 0)
5119 gain_code = lcnphy_23bitgaincode_table[*gain_index];
5120
5121 if (-1 == *gain_index) {
5122 *gain_index = 0;
5123 while ((*gain_index <= (s32) max_index)
5124 && (received_power < 700)) {
5125 wlc_lcnphy_set_rx_gain(pi,
5126 lcnphy_23bitgaincode_table
5127 [*gain_index]);
5128 received_power =
5129 wlc_lcnphy_measure_digital_power(pi,
5130 pi_lcn->
5131 lcnphy_noise_samples);
5132 (*gain_index)++;
5133 }
5134 (*gain_index)--;
5135 } else {
5136 wlc_lcnphy_set_rx_gain(pi, gain_code);
5137 received_power =
5138 wlc_lcnphy_measure_digital_power(pi,
5139 pi_lcn->
5140 lcnphy_noise_samples);
5141 }
5142
5143 return received_power;
5144}
5145
5146s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index)
5147{
5148 s32 gain = 0;
5149 s32 nominal_power_db;
5150 s32 log_val, gain_mismatch, desired_gain, input_power_offset_db,
5151 input_power_db;
5152 s32 received_power, temperature;
5153 uint freq;
5154 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
5155
5156 received_power = wlc_lcnphy_get_receive_power(pi, &gain_index);
5157
5158 gain = lcnphy_gain_table[gain_index];
5159
5160 nominal_power_db = read_phy_reg(pi, 0x425) >> 8;
5161
5162 {
5163 u32 power = (received_power * 16);
5164 u32 msb1, msb2, val1, val2, diff1, diff2;
5165 msb1 = ffs(power) - 1;
5166 msb2 = msb1 + 1;
5167 val1 = 1 << msb1;
5168 val2 = 1 << msb2;
5169 diff1 = (power - val1);
5170 diff2 = (val2 - power);
5171 if (diff1 < diff2)
5172 log_val = msb1;
5173 else
5174 log_val = msb2;
5175 }
5176
5177 log_val = log_val * 3;
5178
5179 gain_mismatch = (nominal_power_db / 2) - (log_val);
5180
5181 desired_gain = gain + gain_mismatch;
5182
5183 input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF;
5184
5185 if (input_power_offset_db > 127)
5186 input_power_offset_db -= 256;
5187
5188 input_power_db = input_power_offset_db - desired_gain;
5189
5190 input_power_db =
5191 input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index];
5192
5193 freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec));
5194 if ((freq > 2427) && (freq <= 2467))
5195 input_power_db = input_power_db - 1;
5196
5197 temperature = pi_lcn->lcnphy_lastsensed_temperature;
5198
5199 if ((temperature - 15) < -30) {
5200 input_power_db =
5201 input_power_db + (((temperature - 10 - 25) * 286) >> 12) -
5202 7;
5203 } else if ((temperature - 15) < 4) {
5204 input_power_db =
5205 input_power_db + (((temperature - 10 - 25) * 286) >> 12) -
5206 3;
5207 } else {
5208 input_power_db =
5209 input_power_db + (((temperature - 10 - 25) * 286) >> 12);
5210 }
5211
5212 wlc_lcnphy_rx_gain_override_enable(pi, 0);
5213
5214 return input_power_db;
5215}
5216
5217static int
5218wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type)
5219{
5220 s16 filt_index = -1;
5221 int j;
5222
5223 u16 addr[] = {
5224 0x910,
5225 0x91e,
5226 0x91f,
5227 0x924,
5228 0x925,
5229 0x926,
5230 0x920,
5231 0x921,
5232 0x927,
5233 0x928,
5234 0x929,
5235 0x922,
5236 0x923,
5237 0x930,
5238 0x931,
5239 0x932
5240 };
5241
5242 u16 addr_ofdm[] = {
5243 0x90f,
5244 0x900,
5245 0x901,
5246 0x906,
5247 0x907,
5248 0x908,
5249 0x902,
5250 0x903,
5251 0x909,
5252 0x90a,
5253 0x90b,
5254 0x904,
5255 0x905,
5256 0x90c,
5257 0x90d,
5258 0x90e
5259 };
5260
5261 if (!is_ofdm) {
5262 for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) {
5263 if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) {
5264 filt_index = (s16) j;
5265 break;
5266 }
5267 }
5268
5269 if (filt_index != -1) {
5270 for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
5271 write_phy_reg(pi, addr[j],
5272 LCNPHY_txdigfiltcoeffs_cck
5273 [filt_index][j + 1]);
5274 }
5275 }
5276 } else {
5277 for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) {
5278 if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) {
5279 filt_index = (s16) j;
5280 break;
5281 }
5282 }
5283
5284 if (filt_index != -1) {
5285 for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
5286 write_phy_reg(pi, addr_ofdm[j],
5287 LCNPHY_txdigfiltcoeffs_ofdm
5288 [filt_index][j + 1]);
5289 }
5290 }
5291 }
5292
5293 return (filt_index != -1) ? 0 : -1;
5294}
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h
new file mode 100644
index 00000000000..f4a8ab09da4
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h
@@ -0,0 +1,121 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_PHY_LCN_H_
18#define _BRCM_PHY_LCN_H_
19
20#include <types.h>
21
22struct brcms_phy_lcnphy {
23 int lcnphy_txrf_sp_9_override;
24 u8 lcnphy_full_cal_channel;
25 u8 lcnphy_cal_counter;
26 u16 lcnphy_cal_temper;
27 bool lcnphy_recal;
28
29 u8 lcnphy_rc_cap;
30 u32 lcnphy_mcs20_po;
31
32 u8 lcnphy_tr_isolation_mid;
33 u8 lcnphy_tr_isolation_low;
34 u8 lcnphy_tr_isolation_hi;
35
36 u8 lcnphy_bx_arch;
37 u8 lcnphy_rx_power_offset;
38 u8 lcnphy_rssi_vf;
39 u8 lcnphy_rssi_vc;
40 u8 lcnphy_rssi_gs;
41 u8 lcnphy_tssi_val;
42 u8 lcnphy_rssi_vf_lowtemp;
43 u8 lcnphy_rssi_vc_lowtemp;
44 u8 lcnphy_rssi_gs_lowtemp;
45
46 u8 lcnphy_rssi_vf_hightemp;
47 u8 lcnphy_rssi_vc_hightemp;
48 u8 lcnphy_rssi_gs_hightemp;
49
50 s16 lcnphy_pa0b0;
51 s16 lcnphy_pa0b1;
52 s16 lcnphy_pa0b2;
53
54 u16 lcnphy_rawtempsense;
55 u8 lcnphy_measPower;
56 u8 lcnphy_tempsense_slope;
57 u8 lcnphy_freqoffset_corr;
58 u8 lcnphy_tempsense_option;
59 u8 lcnphy_tempcorrx;
60 bool lcnphy_iqcal_swp_dis;
61 bool lcnphy_hw_iqcal_en;
62 uint lcnphy_bandedge_corr;
63 bool lcnphy_spurmod;
64 u16 lcnphy_tssi_tx_cnt;
65 u16 lcnphy_tssi_idx;
66 u16 lcnphy_tssi_npt;
67
68 u16 lcnphy_target_tx_freq;
69 s8 lcnphy_tx_power_idx_override;
70 u16 lcnphy_noise_samples;
71
72 u32 lcnphy_papdRxGnIdx;
73 u32 lcnphy_papd_rxGnCtrl_init;
74
75 u32 lcnphy_gain_idx_14_lowword;
76 u32 lcnphy_gain_idx_14_hiword;
77 u32 lcnphy_gain_idx_27_lowword;
78 u32 lcnphy_gain_idx_27_hiword;
79 s16 lcnphy_ofdmgainidxtableoffset;
80 s16 lcnphy_dsssgainidxtableoffset;
81 u32 lcnphy_tr_R_gain_val;
82 u32 lcnphy_tr_T_gain_val;
83 s8 lcnphy_input_pwr_offset_db;
84 u16 lcnphy_Med_Low_Gain_db;
85 u16 lcnphy_Very_Low_Gain_db;
86 s8 lcnphy_lastsensed_temperature;
87 s8 lcnphy_pkteng_rssi_slope;
88 u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
89 u8 lcnphy_volt_winner;
90 u8 lcnphy_volt_low;
91 u8 lcnphy_54_48_36_24mbps_backoff;
92 u8 lcnphy_11n_backoff;
93 u8 lcnphy_lowerofdm;
94 u8 lcnphy_cck;
95 u8 lcnphy_psat_2pt3_detected;
96 s32 lcnphy_lowest_Re_div_Im;
97 s8 lcnphy_final_papd_cal_idx;
98 u16 lcnphy_extstxctrl4;
99 u16 lcnphy_extstxctrl0;
100 u16 lcnphy_extstxctrl1;
101 s16 lcnphy_cck_dig_filt_type;
102 s16 lcnphy_ofdm_dig_filt_type;
103 struct lcnphy_cal_results lcnphy_cal_results;
104
105 u8 lcnphy_psat_pwr;
106 u8 lcnphy_psat_indx;
107 s32 lcnphy_min_phase;
108 u8 lcnphy_final_idx;
109 u8 lcnphy_start_idx;
110 u8 lcnphy_current_index;
111 u16 lcnphy_logen_buf_1;
112 u16 lcnphy_local_ovr_2;
113 u16 lcnphy_local_oval_6;
114 u16 lcnphy_local_oval_5;
115 u16 lcnphy_logen_mixer_1;
116
117 u8 lcnphy_aci_stat;
118 uint lcnphy_aci_start_time;
119 s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
120};
121#endif /* _BRCM_PHY_LCN_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c
new file mode 100644
index 00000000000..f8e41923942
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c
@@ -0,0 +1,29082 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/delay.h>
18
19#include <brcm_hw_ids.h>
20#include <aiutils.h>
21#include <chipcommon.h>
22#include <pmu.h>
23#include <d11.h>
24#include <phy_shim.h>
25#include "phy_int.h"
26#include "phy_hal.h"
27#include "phy_radio.h"
28#include "phyreg_n.h"
29#include "phytbl_n.h"
30
31#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \
32 read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
33 ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1))
34#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \
35 write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
36 ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1), value);
37#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \
38 write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value);
39
40#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \
41 read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \
42 radio_type##_##jspace##1##_##reg_name));
43#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \
44 write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \
45 radio_type##_##jspace##1##_##reg_name), value);
46#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \
47 read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \
48 radio_type##_##reg_name##_##jspace##1));
49#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \
50 write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \
51 radio_type##_##reg_name##_##jspace##1), value);
52
53#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40
54#define NPHY_ACI_CHANNEL_DELTA 5
55#define NPHY_ACI_CHANNEL_SKIP 4
56#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6
57#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5
58#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6
59#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5
60#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4
61#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3
62
63#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2
64
65#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8
66
67#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2
68
69#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8
70
71#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2
72
73#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8
74
75#define NPHY_NOISE_NOASSOC_ENTER_TH 400
76
77#define NPHY_NOISE_ASSOC_ENTER_TH 400
78
79#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH 400
80
81#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44
82#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56
83
84#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16
85
86#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8
87
88#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5)
89
90#define NPHY_RSSICAL_MAXREAD 31
91
92#define NPHY_RSSICAL_NPOLL 8
93#define NPHY_RSSICAL_MAXD (1<<20)
94#define NPHY_MIN_RXIQ_PWR 2
95
96#define NPHY_RSSICAL_W1_TARGET 25
97#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET
98#define NPHY_RSSICAL_NB_TARGET 0
99
100#define NPHY_RSSICAL_W1_TARGET_REV3 29
101#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3
102
103#define NPHY_CALSANITY_RSSI_NB_MAX_POS 9
104#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9
105#define NPHY_CALSANITY_RSSI_W1_MAX_POS 12
106#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - NPHY_RSSICAL_MAXREAD)
107#define NPHY_CALSANITY_RSSI_W2_MAX_POS NPHY_CALSANITY_RSSI_W1_MAX_POS
108#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - NPHY_RSSICAL_MAXREAD)
109#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f)))
110#define NPHY_RSSI_NB_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \
111 ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG))
112#define NPHY_RSSI_W1_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \
113 ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG))
114#define NPHY_RSSI_W2_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \
115 ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG))
116
117#define NPHY_IQCAL_NUMGAINS 9
118#define NPHY_N_GCTL 0x66
119
120#define NPHY_PAPD_EPS_TBL_SIZE 64
121#define NPHY_PAPD_SCL_TBL_SIZE 64
122#define NPHY_NUM_DIG_FILT_COEFFS 15
123
124#define NPHY_PAPD_COMP_OFF 0
125#define NPHY_PAPD_COMP_ON 1
126
127#define NPHY_SROM_TEMPSHIFT 32
128#define NPHY_SROM_MAXTEMPOFFSET 16
129#define NPHY_SROM_MINTEMPOFFSET -16
130
131#define NPHY_CAL_MAXTEMPDELTA 64
132
133#define NPHY_NOISEVAR_TBLLEN40 256
134#define NPHY_NOISEVAR_TBLLEN20 128
135
136#define NPHY_ANARXLPFBW_REDUCTIONFACT 7
137
138#define NPHY_ADJUSTED_MINCRSPOWER 0x1e
139
140/* 5357 Chip specific ChipControl register bits */
141#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */
142#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */
143
144struct nphy_iqcal_params {
145 u16 txlpf;
146 u16 txgm;
147 u16 pga;
148 u16 pad;
149 u16 ipa;
150 u16 cal_gain;
151 u16 ncorr[5];
152};
153
154struct nphy_txiqcal_ladder {
155 u8 percent;
156 u8 g_env;
157};
158
159struct nphy_ipa_txcalgains {
160 struct nphy_txgains gains;
161 bool useindex;
162 u8 index;
163};
164
165struct nphy_papd_restore_state {
166 u16 fbmix[2];
167 u16 vga_master[2];
168 u16 intpa_master[2];
169 u16 afectrl[2];
170 u16 afeoverride[2];
171 u16 pwrup[2];
172 u16 atten[2];
173 u16 mm;
174};
175
176struct nphy_ipa_txrxgain {
177 u16 hpvga;
178 u16 lpf_biq1;
179 u16 lpf_biq0;
180 u16 lna2;
181 u16 lna1;
182 s8 txpwrindex;
183};
184
185#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1)
186
187struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100},
188{0, 0, 0, 0, 0, 50},
189{0, 0, 0, 0, 0, -1},
190{0, 0, 0, 3, 0, -1},
191{0, 0, 3, 3, 0, -1},
192{0, 2, 3, 3, 0, -1}
193};
194
195struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128},
196{0, 0, 0, 0, 0, 70},
197{0, 0, 0, 0, 0, 20},
198{0, 0, 0, 3, 0, 20},
199{0, 0, 3, 3, 0, 20},
200{0, 2, 3, 3, 0, 20}
201};
202
203struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = {
204{0, 0, 0, 0, 0, 100},
205{0, 0, 0, 0, 0, 50},
206{0, 0, 0, 0, 0, -1},
207{0, 0, 0, 3, 0, -1},
208{0, 0, 3, 3, 0, -1},
209{0, 0, 5, 3, 0, -1}
210};
211
212struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = {
213{0, 0, 0, 0, 0, 10},
214{0, 0, 0, 1, 0, 10},
215{0, 0, 1, 2, 0, 10},
216{0, 0, 1, 3, 0, 10},
217{0, 0, 4, 3, 0, 10},
218{0, 0, 6, 3, 0, 10}
219};
220
221#define NPHY_RXCAL_TONEAMP 181
222#define NPHY_RXCAL_TONEFREQ_40MHz 4000
223#define NPHY_RXCAL_TONEFREQ_20MHz 2000
224
225enum {
226 NPHY_RXCAL_GAIN_INIT = 0,
227 NPHY_RXCAL_GAIN_UP,
228 NPHY_RXCAL_GAIN_DOWN
229};
230
231#define wlc_phy_get_papd_nphy(pi) \
232 (read_phy_reg((pi), 0x1e7) & \
233 ((0x1 << 15) | \
234 (0x1 << 14) | \
235 (0x1 << 13)))
236
237#define TXFILT_SHAPING_OFDM20 0
238#define TXFILT_SHAPING_OFDM40 1
239#define TXFILT_SHAPING_CCK 2
240#define TXFILT_DEFAULT_OFDM20 3
241#define TXFILT_DEFAULT_OFDM40 4
242
243u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = {
244 {-377, 137, -407, 208, -1527, 956, 93, 186, 93,
245 230, -44, 230, 201, -191, 201},
246 {-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5,
247 26, 34, -32, 34},
248 {-360, 164, -376, 164, -1533, 576, 308, -314, 308,
249 121, -73, 121, 91, 124, 91},
250 {-295, 200, -363, 142, -1391, 826, 151, 301, 151,
251 151, 301, 151, 602, -752, 602},
252 {-92, 58, -96, 49, -104, 44, 17, 35, 17,
253 12, 25, 12, 13, 27, 13},
254 {-375, 136, -399, 209, -1479, 949, 130, 260, 130,
255 230, -44, 230, 201, -191, 201},
256 {0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97,
257 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a}
258};
259
260struct chan_info_nphy_2055 {
261 u16 chan;
262 u16 freq;
263 uint unknown;
264 u8 RF_pll_ref;
265 u8 RF_rf_pll_mod1;
266 u8 RF_rf_pll_mod0;
267 u8 RF_vco_cap_tail;
268 u8 RF_vco_cal1;
269 u8 RF_vco_cal2;
270 u8 RF_pll_lf_c1;
271 u8 RF_pll_lf_r1;
272 u8 RF_pll_lf_c2;
273 u8 RF_lgbuf_cen_buf;
274 u8 RF_lgen_tune1;
275 u8 RF_lgen_tune2;
276 u8 RF_core1_lgbuf_a_tune;
277 u8 RF_core1_lgbuf_g_tune;
278 u8 RF_core1_rxrf_reg1;
279 u8 RF_core1_tx_pga_pad_tn;
280 u8 RF_core1_tx_mx_bgtrim;
281 u8 RF_core2_lgbuf_a_tune;
282 u8 RF_core2_lgbuf_g_tune;
283 u8 RF_core2_rxrf_reg1;
284 u8 RF_core2_tx_pga_pad_tn;
285 u8 RF_core2_tx_mx_bgtrim;
286 u16 PHY_BW1a;
287 u16 PHY_BW2;
288 u16 PHY_BW3;
289 u16 PHY_BW4;
290 u16 PHY_BW5;
291 u16 PHY_BW6;
292};
293
294struct chan_info_nphy_radio205x {
295 u16 chan;
296 u16 freq;
297 u8 RF_SYN_pll_vcocal1;
298 u8 RF_SYN_pll_vcocal2;
299 u8 RF_SYN_pll_refdiv;
300 u8 RF_SYN_pll_mmd2;
301 u8 RF_SYN_pll_mmd1;
302 u8 RF_SYN_pll_loopfilter1;
303 u8 RF_SYN_pll_loopfilter2;
304 u8 RF_SYN_pll_loopfilter3;
305 u8 RF_SYN_pll_loopfilter4;
306 u8 RF_SYN_pll_loopfilter5;
307 u8 RF_SYN_reserved_addr27;
308 u8 RF_SYN_reserved_addr28;
309 u8 RF_SYN_reserved_addr29;
310 u8 RF_SYN_logen_VCOBUF1;
311 u8 RF_SYN_logen_MIXER2;
312 u8 RF_SYN_logen_BUF3;
313 u8 RF_SYN_logen_BUF4;
314 u8 RF_RX0_lnaa_tune;
315 u8 RF_RX0_lnag_tune;
316 u8 RF_TX0_intpaa_boost_tune;
317 u8 RF_TX0_intpag_boost_tune;
318 u8 RF_TX0_pada_boost_tune;
319 u8 RF_TX0_padg_boost_tune;
320 u8 RF_TX0_pgaa_boost_tune;
321 u8 RF_TX0_pgag_boost_tune;
322 u8 RF_TX0_mixa_boost_tune;
323 u8 RF_TX0_mixg_boost_tune;
324 u8 RF_RX1_lnaa_tune;
325 u8 RF_RX1_lnag_tune;
326 u8 RF_TX1_intpaa_boost_tune;
327 u8 RF_TX1_intpag_boost_tune;
328 u8 RF_TX1_pada_boost_tune;
329 u8 RF_TX1_padg_boost_tune;
330 u8 RF_TX1_pgaa_boost_tune;
331 u8 RF_TX1_pgag_boost_tune;
332 u8 RF_TX1_mixa_boost_tune;
333 u8 RF_TX1_mixg_boost_tune;
334 u16 PHY_BW1a;
335 u16 PHY_BW2;
336 u16 PHY_BW3;
337 u16 PHY_BW4;
338 u16 PHY_BW5;
339 u16 PHY_BW6;
340};
341
342struct chan_info_nphy_radio2057 {
343 u16 chan;
344 u16 freq;
345 u8 RF_vcocal_countval0;
346 u8 RF_vcocal_countval1;
347 u8 RF_rfpll_refmaster_sparextalsize;
348 u8 RF_rfpll_loopfilter_r1;
349 u8 RF_rfpll_loopfilter_c2;
350 u8 RF_rfpll_loopfilter_c1;
351 u8 RF_cp_kpd_idac;
352 u8 RF_rfpll_mmd0;
353 u8 RF_rfpll_mmd1;
354 u8 RF_vcobuf_tune;
355 u8 RF_logen_mx2g_tune;
356 u8 RF_logen_mx5g_tune;
357 u8 RF_logen_indbuf2g_tune;
358 u8 RF_logen_indbuf5g_tune;
359 u8 RF_txmix2g_tune_boost_pu_core0;
360 u8 RF_pad2g_tune_pus_core0;
361 u8 RF_pga_boost_tune_core0;
362 u8 RF_txmix5g_boost_tune_core0;
363 u8 RF_pad5g_tune_misc_pus_core0;
364 u8 RF_lna2g_tune_core0;
365 u8 RF_lna5g_tune_core0;
366 u8 RF_txmix2g_tune_boost_pu_core1;
367 u8 RF_pad2g_tune_pus_core1;
368 u8 RF_pga_boost_tune_core1;
369 u8 RF_txmix5g_boost_tune_core1;
370 u8 RF_pad5g_tune_misc_pus_core1;
371 u8 RF_lna2g_tune_core1;
372 u8 RF_lna5g_tune_core1;
373 u16 PHY_BW1a;
374 u16 PHY_BW2;
375 u16 PHY_BW3;
376 u16 PHY_BW4;
377 u16 PHY_BW5;
378 u16 PHY_BW6;
379};
380
381struct chan_info_nphy_radio2057_rev5 {
382 u16 chan;
383 u16 freq;
384 u8 RF_vcocal_countval0;
385 u8 RF_vcocal_countval1;
386 u8 RF_rfpll_refmaster_sparextalsize;
387 u8 RF_rfpll_loopfilter_r1;
388 u8 RF_rfpll_loopfilter_c2;
389 u8 RF_rfpll_loopfilter_c1;
390 u8 RF_cp_kpd_idac;
391 u8 RF_rfpll_mmd0;
392 u8 RF_rfpll_mmd1;
393 u8 RF_vcobuf_tune;
394 u8 RF_logen_mx2g_tune;
395 u8 RF_logen_indbuf2g_tune;
396 u8 RF_txmix2g_tune_boost_pu_core0;
397 u8 RF_pad2g_tune_pus_core0;
398 u8 RF_lna2g_tune_core0;
399 u8 RF_txmix2g_tune_boost_pu_core1;
400 u8 RF_pad2g_tune_pus_core1;
401 u8 RF_lna2g_tune_core1;
402 u16 PHY_BW1a;
403 u16 PHY_BW2;
404 u16 PHY_BW3;
405 u16 PHY_BW4;
406 u16 PHY_BW5;
407 u16 PHY_BW6;
408};
409
410struct nphy_sfo_cfg {
411 u16 PHY_BW1a;
412 u16 PHY_BW2;
413 u16 PHY_BW3;
414 u16 PHY_BW4;
415 u16 PHY_BW5;
416 u16 PHY_BW6;
417};
418
419static struct chan_info_nphy_2055 chan_info_nphy_2055[] = {
420 {
421 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
422 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
423 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216},
424 {
425 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
426 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
427 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215},
428 {
429 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
430 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
431 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214},
432 {
433 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
434 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
435 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213},
436 {
437 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
438 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
439 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212},
440 {
441 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
442 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
443 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211},
444 {
445 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
446 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
447 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F},
448 {
449 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
450 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
451 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E},
452 {
453 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
454 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
455 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D},
456 {
457 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
458 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
459 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C},
460 {
461 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
462 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
463 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B},
464 {
465 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
466 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
467 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A},
468 {
469 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
470 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
471 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209},
472 {
473 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
474 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
475 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208},
476 {
477 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
478 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
479 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207},
480 {
481 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
482 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
483 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206},
484 {
485 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
486 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
487 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205},
488 {
489 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
490 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
491 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204},
492 {
493 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
494 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
495 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203},
496 {
497 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
498 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
499 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202},
500 {
501 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
502 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
503 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201},
504 {
505 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
506 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
507 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200},
508 {
509 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
510 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C,
511 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF},
512 {
513 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
514 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
515 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD},
516 {
517 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
518 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
519 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC},
520 {
521 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
522 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
523 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB},
524 {
525 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
526 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
527 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA},
528 {
529 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
530 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
531 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9},
532 {
533 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
534 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
535 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8},
536 {
537 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
538 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
539 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7},
540 {
541 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
542 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
543 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6},
544 {
545 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
546 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
547 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5},
548 {
549 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
550 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
551 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4},
552 {
553 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
554 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
555 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3},
556 {
557 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
558 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
559 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2},
560 {
561 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
562 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
563 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1},
564 {
565 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
566 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
567 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0},
568 {
569 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
570 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
571 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0},
572 {
573 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
574 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
575 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF},
576 {
577 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
578 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
579 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE},
580 {
581 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
582 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
583 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED},
584 {
585 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
586 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
587 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC},
588 {
589 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
590 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
591 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB},
592 {
593 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
594 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
595 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA},
596 {
597 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
598 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
599 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9},
600 {
601 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
602 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
603 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8},
604 {
605 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
606 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
607 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7},
608 {
609 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
610 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
611 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6},
612 {
613 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
614 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
615 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5},
616 {
617 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
618 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
619 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5},
620 {
621 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
622 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
623 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4},
624 {
625 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
626 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
627 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3},
628 {
629 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
630 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
631 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2},
632 {
633 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
634 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
635 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1},
636 {
637 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
638 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
639 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0},
640 {
641 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
642 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
643 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF},
644 {
645 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
646 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
647 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE},
648 {
649 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
650 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
651 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD},
652 {
653 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
654 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
655 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD},
656 {
657 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
658 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
659 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC},
660 {
661 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
662 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
663 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB},
664 {
665 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
666 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
667 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA},
668 {
669 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
670 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
671 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9},
672 {
673 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
674 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
675 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8},
676 {
677 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
678 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
679 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7},
680 {
681 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
682 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
683 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7},
684 {
685 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
686 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
687 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6},
688 {
689 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
690 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
691 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5},
692 {
693 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
694 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
695 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4},
696 {
697 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
698 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
699 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3},
700 {
701 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
702 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
703 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2},
704 {
705 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
706 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
707 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2},
708 {
709 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
710 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
711 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1},
712 {
713 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
714 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
715 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0},
716 {
717 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
718 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
719 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF},
720 {
721 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
722 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
723 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE},
724 {
725 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
726 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
727 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE},
728 {
729 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
730 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
731 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD},
732 {
733 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
734 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
735 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC},
736 {
737 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
738 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
739 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB},
740 {
741 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
742 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
743 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB},
744 {
745 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
746 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
747 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA},
748 {
749 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
750 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
751 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA},
752 {
753 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
754 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
755 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9},
756 {
757 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
758 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
759 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9},
760 {
761 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
762 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
763 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9},
764 {
765 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
766 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
767 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8},
768 {
769 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
770 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
771 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8},
772 {
773 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
774 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
775 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8},
776 {
777 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
778 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
779 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7},
780 {
781 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
782 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
783 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7},
784 {
785 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
786 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
787 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6},
788 {
789 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
790 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
791 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6},
792 {
793 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
794 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
795 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6},
796 {
797 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
798 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
799 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5},
800 {
801 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
802 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
803 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5},
804 {
805 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
806 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
807 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4},
808 {
809 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
810 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
811 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4},
812 {
813 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
814 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
815 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4},
816 {
817 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
818 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
819 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3},
820 {
821 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
822 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
823 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3},
824 {
825 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
826 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
827 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2},
828 {
829 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
830 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
831 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2},
832 {
833 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
834 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
835 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1},
836 {
837 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
838 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
839 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0},
840 {
841 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
842 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
843 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF},
844 {
845 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
846 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
847 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF},
848 {
849 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
850 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
851 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE},
852 {
853 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
854 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
855 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD},
856 {
857 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
858 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
859 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC},
860 {
861 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
862 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D,
863 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443},
864 {
865 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
866 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C,
867 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441},
868 {
869 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
870 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
871 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F},
872 {
873 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
874 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
875 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D},
876 {
877 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
878 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C,
879 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A},
880 {
881 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
882 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B,
883 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438},
884 {
885 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
886 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A,
887 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436},
888 {
889 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
890 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A,
891 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434},
892 {
893 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
894 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09,
895 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431},
896 {
897 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
898 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08,
899 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F},
900 {
901 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
902 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08,
903 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D},
904 {
905 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
906 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08,
907 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B},
908 {
909 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
910 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07,
911 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429},
912 {
913 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
914 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07,
915 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424}
916};
917
918static struct chan_info_nphy_radio205x chan_info_nphyrev3_2056[] = {
919 {
920 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
921 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
922 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
923 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
924 {
925 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
926 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
927 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
928 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
929 {
930 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
931 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
932 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
933 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
934 {
935 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
936 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
937 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
938 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
939 {
940 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
941 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
942 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
943 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
944 {
945 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
946 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
947 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
948 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
949 {
950 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
951 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
952 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
953 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
954 {
955 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
956 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
957 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
958 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
959 {
960 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
961 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
962 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
963 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
964 {
965 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
966 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
967 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
968 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
969 {
970 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
971 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
972 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
973 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
974 {
975 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
976 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
977 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
978 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
979 {
980 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
981 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
982 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
983 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
984 {
985 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
986 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
987 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
988 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
989 {
990 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
991 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
992 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
993 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
994 {
995 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
996 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
997 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
998 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
999 {
1000 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
1001 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1002 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1003 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
1004 {
1005 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
1006 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1007 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1008 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
1009 {
1010 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
1011 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1012 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1013 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
1014 {
1015 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
1016 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1017 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1018 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
1019 {
1020 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
1021 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1022 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1023 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
1024 {
1025 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
1026 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1027 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1028 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
1029 {
1030 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
1031 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1032 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1033 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
1034 {
1035 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
1036 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1037 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1038 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
1039 {
1040 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
1041 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
1042 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1043 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
1044 {
1045 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
1046 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
1047 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1048 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
1049 {
1050 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
1051 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
1052 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
1053 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
1054 {
1055 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
1056 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f,
1057 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1058 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
1059 {
1060 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
1061 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
1062 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1063 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
1064 {
1065 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1066 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
1067 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1068 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
1069 {
1070 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1071 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
1072 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1073 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
1074 {
1075 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1076 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
1077 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1078 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
1079 {
1080 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1081 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
1082 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1083 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
1084 {
1085 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1086 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
1087 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1088 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
1089 {
1090 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1091 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
1092 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1093 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
1094 {
1095 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
1096 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
1097 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1098 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
1099 {
1100 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
1101 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
1102 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
1103 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
1104 {
1105 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
1106 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
1107 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1108 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
1109 {
1110 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
1111 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
1112 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1113 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
1114 {
1115 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
1116 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
1117 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1118 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
1119 {
1120 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
1121 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
1122 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1123 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
1124 {
1125 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
1126 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
1127 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1128 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
1129 {
1130 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
1131 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
1132 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1133 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
1134 {
1135 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
1136 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
1137 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1138 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
1139 {
1140 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
1141 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
1142 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1143 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
1144 {
1145 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1146 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
1147 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1148 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
1149 {
1150 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1151 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f,
1152 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
1153 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
1154 {
1155 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1156 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
1157 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1158 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
1159 {
1160 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1161 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
1162 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1163 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
1164 {
1165 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1166 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
1167 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1168 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
1169 {
1170 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1171 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
1172 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1173 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
1174 {
1175 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
1176 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f,
1177 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1178 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
1179 {
1180 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
1181 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f,
1182 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1183 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
1184 {
1185 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
1186 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
1187 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1188 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
1189 {
1190 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
1191 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
1192 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1193 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
1194 {
1195 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
1196 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f,
1197 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1198 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
1199 {
1200 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
1201 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f,
1202 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
1203 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
1204 {
1205 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
1206 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f,
1207 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1208 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
1209 {
1210 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
1211 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
1212 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1213 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
1214 {
1215 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
1216 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
1217 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1218 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
1219 {
1220 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
1221 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
1222 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1223 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
1224 {
1225 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1226 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
1227 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1228 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
1229 {
1230 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1231 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
1232 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1233 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
1234 {
1235 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1236 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f,
1237 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1238 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
1239 {
1240 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1241 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f,
1242 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1243 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
1244 {
1245 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1246 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
1247 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1248 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
1249 {
1250 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1251 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
1252 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1253 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
1254 {
1255 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
1256 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f,
1257 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1258 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
1259 {
1260 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
1261 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
1262 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1263 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
1264 {
1265 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
1266 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
1267 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1268 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
1269 {
1270 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
1271 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
1272 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1273 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
1274 {
1275 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
1276 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
1277 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1278 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
1279 {
1280 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
1281 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
1282 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1283 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
1284 {
1285 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
1286 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
1287 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1288 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
1289 {
1290 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
1291 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
1292 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1293 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
1294 {
1295 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
1296 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
1297 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1298 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
1299 {
1300 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
1301 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f,
1302 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
1303 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
1304 {
1305 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1306 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
1307 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1308 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
1309 {
1310 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1311 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
1312 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1313 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
1314 {
1315 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1316 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
1317 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1318 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
1319 {
1320 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
1321 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1322 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1323 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
1324 {
1325 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1326 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1327 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1328 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
1329 {
1330 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
1331 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1332 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1333 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
1334 {
1335 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1336 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1337 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1338 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
1339 {
1340 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
1341 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1342 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1343 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
1344 {
1345 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1346 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
1347 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1348 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
1349 {
1350 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
1351 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1352 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1353 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
1354 {
1355 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
1356 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1357 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1358 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
1359 {
1360 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
1361 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1362 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1363 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
1364 {
1365 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
1366 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1367 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1368 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
1369 {
1370 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
1371 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1372 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1373 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
1374 {
1375 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
1376 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
1377 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1378 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
1379 {
1380 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
1381 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
1382 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1383 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
1384 {
1385 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
1386 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
1387 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1388 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
1389 {
1390 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
1391 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
1392 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
1393 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
1394 {
1395 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
1396 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
1397 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1398 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
1399 {
1400 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
1401 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
1402 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1403 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
1404 {
1405 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
1406 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
1407 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1408 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
1409 {
1410 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
1411 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
1412 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1413 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
1414 {
1415 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
1416 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1417 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1418 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
1419 {
1420 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
1421 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1422 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1423 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
1424 {
1425 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
1426 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1427 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1428 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
1429 {
1430 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
1431 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1432 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1433 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
1434 {
1435 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
1436 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1437 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1438 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
1439 {
1440 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1441 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
1442 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1443 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
1444 {
1445 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1446 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
1447 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1448 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
1449 {
1450 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1451 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
1452 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1453 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
1454 {
1455 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1456 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
1457 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
1458 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
1459 {
1460 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1461 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
1462 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
1463 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
1464 {
1465 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1466 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
1467 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
1468 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
1469 {
1470 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
1471 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
1472 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
1473 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
1474 {
1475 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
1476 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
1477 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
1478 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
1479 {
1480 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
1481 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
1482 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
1483 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
1484 {
1485 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
1486 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00,
1487 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
1488 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
1489 {
1490 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
1491 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00,
1492 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
1493 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
1494 {
1495 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
1496 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00,
1497 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
1498 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
1499 {
1500 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
1501 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00,
1502 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
1503 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
1504 {
1505 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
1506 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00,
1507 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
1508 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
1509 {
1510 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
1511 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00,
1512 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
1513 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
1514 {
1515 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
1516 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00,
1517 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
1518 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
1519 {
1520 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
1521 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00,
1522 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
1523 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
1524 {
1525 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
1526 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00,
1527 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
1528 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
1529 {
1530 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
1531 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00,
1532 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
1533 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
1534 {
1535 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
1536 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00,
1537 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
1538 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
1539};
1540
1541static struct chan_info_nphy_radio205x chan_info_nphyrev4_2056_A1[] = {
1542 {
1543 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
1544 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1545 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1546 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
1547 {
1548 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
1549 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1550 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1551 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
1552 {
1553 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
1554 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1555 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1556 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
1557 {
1558 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
1559 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1560 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1561 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
1562 {
1563 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
1564 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1565 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1566 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
1567 {
1568 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
1569 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1570 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1571 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
1572 {
1573 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
1574 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1575 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1576 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
1577 {
1578 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
1579 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
1580 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
1581 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
1582 {
1583 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
1584 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1585 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1586 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
1587 {
1588 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
1589 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1590 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1591 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
1592 {
1593 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
1594 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1595 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1596 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
1597 {
1598 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
1599 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1600 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1601 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
1602 {
1603 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
1604 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1605 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1606 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
1607 {
1608 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
1609 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1610 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1611 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
1612 {
1613 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
1614 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1615 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1616 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
1617 {
1618 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
1619 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1620 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1621 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
1622 {
1623 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
1624 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1625 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1626 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
1627 {
1628 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
1629 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
1630 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
1631 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
1632 {
1633 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
1634 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1635 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1636 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
1637 {
1638 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
1639 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1640 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1641 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
1642 {
1643 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
1644 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1645 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1646 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
1647 {
1648 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
1649 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1650 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1651 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
1652 {
1653 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
1654 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1655 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1656 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
1657 {
1658 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
1659 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1660 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1661 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
1662 {
1663 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
1664 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
1665 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1666 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
1667 {
1668 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
1669 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
1670 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1671 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
1672 {
1673 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
1674 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
1675 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
1676 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
1677 {
1678 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
1679 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f,
1680 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1681 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
1682 {
1683 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
1684 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
1685 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1686 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
1687 {
1688 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1689 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
1690 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1691 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
1692 {
1693 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1694 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
1695 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1696 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
1697 {
1698 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1699 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
1700 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1701 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
1702 {
1703 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1704 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
1705 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1706 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
1707 {
1708 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1709 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
1710 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1711 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
1712 {
1713 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1714 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
1715 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1716 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
1717 {
1718 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
1719 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
1720 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1721 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
1722 {
1723 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
1724 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
1725 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
1726 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
1727 {
1728 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
1729 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
1730 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1731 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
1732 {
1733 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
1734 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
1735 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1736 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
1737 {
1738 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
1739 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
1740 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1741 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
1742 {
1743 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
1744 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
1745 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1746 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
1747 {
1748 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
1749 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
1750 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1751 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
1752 {
1753 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
1754 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
1755 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1756 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
1757 {
1758 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
1759 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
1760 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1761 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
1762 {
1763 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
1764 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
1765 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1766 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
1767 {
1768 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1769 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
1770 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1771 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
1772 {
1773 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1774 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f,
1775 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
1776 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
1777 {
1778 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1779 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
1780 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1781 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
1782 {
1783 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1784 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
1785 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1786 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
1787 {
1788 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1789 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
1790 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1791 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
1792 {
1793 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1794 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
1795 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1796 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
1797 {
1798 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
1799 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f,
1800 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1801 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
1802 {
1803 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
1804 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f,
1805 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1806 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
1807 {
1808 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
1809 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
1810 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1811 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
1812 {
1813 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
1814 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
1815 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1816 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
1817 {
1818 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
1819 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f,
1820 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1821 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
1822 {
1823 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
1824 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f,
1825 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
1826 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
1827 {
1828 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
1829 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f,
1830 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1831 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
1832 {
1833 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
1834 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
1835 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1836 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
1837 {
1838 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
1839 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
1840 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1841 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
1842 {
1843 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
1844 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
1845 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1846 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
1847 {
1848 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1849 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
1850 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1851 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
1852 {
1853 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1854 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
1855 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1856 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
1857 {
1858 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1859 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f,
1860 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1861 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
1862 {
1863 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1864 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f,
1865 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1866 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
1867 {
1868 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1869 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
1870 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1871 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
1872 {
1873 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1874 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
1875 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
1876 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
1877 {
1878 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
1879 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f,
1880 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1881 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
1882 {
1883 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
1884 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
1885 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1886 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
1887 {
1888 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
1889 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
1890 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1891 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
1892 {
1893 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
1894 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
1895 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1896 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
1897 {
1898 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
1899 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
1900 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1901 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
1902 {
1903 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
1904 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
1905 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1906 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
1907 {
1908 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
1909 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
1910 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1911 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
1912 {
1913 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
1914 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
1915 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1916 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
1917 {
1918 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
1919 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
1920 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1921 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
1922 {
1923 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
1924 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f,
1925 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
1926 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
1927 {
1928 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
1929 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
1930 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1931 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
1932 {
1933 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
1934 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
1935 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1936 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
1937 {
1938 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
1939 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
1940 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1941 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
1942 {
1943 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
1944 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1945 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1946 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
1947 {
1948 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
1949 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1950 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1951 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
1952 {
1953 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
1954 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1955 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1956 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
1957 {
1958 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
1959 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1960 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1961 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
1962 {
1963 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
1964 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1965 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1966 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
1967 {
1968 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
1969 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
1970 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1971 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
1972 {
1973 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
1974 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
1975 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1976 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
1977 {
1978 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
1979 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
1980 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1981 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
1982 {
1983 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
1984 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
1985 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1986 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
1987 {
1988 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
1989 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
1990 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1991 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
1992 {
1993 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
1994 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
1995 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
1996 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
1997 {
1998 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
1999 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
2000 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2001 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
2002 {
2003 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
2004 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
2005 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2006 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
2007 {
2008 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
2009 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
2010 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2011 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
2012 {
2013 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
2014 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
2015 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
2016 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
2017 {
2018 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
2019 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
2020 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2021 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
2022 {
2023 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
2024 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
2025 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2026 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
2027 {
2028 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
2029 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
2030 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2031 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
2032 {
2033 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
2034 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
2035 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2036 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
2037 {
2038 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
2039 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2040 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2041 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
2042 {
2043 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
2044 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2045 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2046 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
2047 {
2048 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
2049 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2050 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2051 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
2052 {
2053 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
2054 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2055 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2056 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
2057 {
2058 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
2059 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2060 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2061 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
2062 {
2063 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2064 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
2065 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2066 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
2067 {
2068 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2069 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
2070 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2071 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
2072 {
2073 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2074 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
2075 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2076 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
2077 {
2078 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2079 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
2080 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
2081 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
2082 {
2083 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2084 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
2085 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
2086 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
2087 {
2088 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2089 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
2090 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
2091 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
2092 {
2093 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
2094 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
2095 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
2096 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
2097 {
2098 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
2099 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
2100 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
2101 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
2102 {
2103 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
2104 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
2105 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
2106 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
2107 {
2108 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
2109 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00,
2110 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
2111 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
2112 {
2113 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
2114 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00,
2115 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
2116 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
2117 {
2118 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
2119 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
2120 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
2121 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
2122 {
2123 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
2124 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00,
2125 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
2126 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
2127 {
2128 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
2129 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00,
2130 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
2131 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
2132 {
2133 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
2134 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
2135 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
2136 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
2137 {
2138 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
2139 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00,
2140 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
2141 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
2142 {
2143 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
2144 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00,
2145 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
2146 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
2147 {
2148 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
2149 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00,
2150 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
2151 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
2152 {
2153 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
2154 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00,
2155 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
2156 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
2157 {
2158 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
2159 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00,
2160 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
2161 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
2162};
2163
2164static struct chan_info_nphy_radio205x chan_info_nphyrev5_2056v5[] = {
2165 {
2166 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
2167 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
2168 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
2169 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
2170 {
2171 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
2172 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
2173 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
2174 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
2175 {
2176 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
2177 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
2178 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
2179 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
2180 {
2181 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
2182 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
2183 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
2184 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
2185 {
2186 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
2187 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2188 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
2189 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
2190 {
2191 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
2192 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2193 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2194 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
2195 {
2196 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
2197 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2198 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2199 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
2200 {
2201 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
2202 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2203 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2204 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
2205 {
2206 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
2207 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2208 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2209 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
2210 {
2211 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
2212 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
2213 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
2214 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
2215 {
2216 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
2217 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
2218 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
2219 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
2220 {
2221 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
2222 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
2223 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
2224 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
2225 {
2226 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
2227 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
2228 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
2229 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
2230 {
2231 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
2232 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
2233 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
2234 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
2235 {
2236 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
2237 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
2238 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
2239 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
2240 {
2241 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
2242 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
2243 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2244 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
2245 {
2246 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
2247 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2248 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2249 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
2250 {
2251 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
2252 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2253 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2254 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
2255 {
2256 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
2257 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2258 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2259 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
2260 {
2261 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
2262 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2263 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2264 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
2265 {
2266 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
2267 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
2268 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
2269 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
2270 {
2271 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
2272 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
2273 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
2274 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
2275 {
2276 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
2277 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
2278 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
2279 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
2280 {
2281 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
2282 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
2283 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
2284 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
2285 {
2286 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
2287 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
2288 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2289 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
2290 {
2291 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
2292 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2293 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2294 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
2295 {
2296 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
2297 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2298 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2299 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
2300 {
2301 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
2302 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2303 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2304 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
2305 {
2306 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
2307 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2308 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2309 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
2310 {
2311 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2312 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
2313 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
2314 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
2315 {
2316 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2317 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70,
2318 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
2319 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
2320 {
2321 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2322 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
2323 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
2324 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
2325 {
2326 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2327 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
2328 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
2329 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
2330 {
2331 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2332 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70,
2333 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
2334 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
2335 {
2336 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2337 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70,
2338 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2339 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
2340 {
2341 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
2342 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
2343 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2344 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
2345 {
2346 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
2347 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
2348 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2349 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
2350 {
2351 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
2352 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
2353 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2354 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
2355 {
2356 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
2357 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
2358 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2359 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
2360 {
2361 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
2362 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70,
2363 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2364 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
2365 {
2366 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
2367 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70,
2368 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
2369 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
2370 {
2371 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
2372 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70,
2373 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
2374 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
2375 {
2376 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
2377 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70,
2378 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2379 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
2380 {
2381 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
2382 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
2383 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2384 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
2385 {
2386 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
2387 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
2388 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2389 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
2390 {
2391 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2392 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70,
2393 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2394 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
2395 {
2396 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2397 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70,
2398 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2399 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
2400 {
2401 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2402 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
2403 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
2404 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
2405 {
2406 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2407 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
2408 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
2409 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
2410 {
2411 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2412 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
2413 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
2414 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
2415 {
2416 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2417 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70,
2418 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
2419 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
2420 {
2421 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
2422 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
2423 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
2424 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
2425 {
2426 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
2427 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
2428 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
2429 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
2430 {
2431 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
2432 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
2433 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
2434 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
2435 {
2436 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
2437 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70,
2438 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2439 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
2440 {
2441 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
2442 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
2443 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2444 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
2445 {
2446 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
2447 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
2448 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2449 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
2450 {
2451 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
2452 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
2453 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2454 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
2455 {
2456 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
2457 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
2458 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2459 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
2460 {
2461 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
2462 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
2463 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
2464 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
2465 {
2466 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
2467 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70,
2468 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
2469 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
2470 {
2471 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2472 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
2473 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
2474 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
2475 {
2476 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2477 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
2478 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
2479 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
2480 {
2481 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2482 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
2483 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
2484 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
2485 {
2486 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2487 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
2488 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2489 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
2490 {
2491 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2492 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
2493 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2494 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
2495 {
2496 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2497 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70,
2498 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2499 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
2500 {
2501 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
2502 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2503 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2504 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
2505 {
2506 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
2507 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2508 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2509 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
2510 {
2511 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
2512 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2513 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2514 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
2515 {
2516 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
2517 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2518 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2519 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
2520 {
2521 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
2522 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
2523 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
2524 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
2525 {
2526 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
2527 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
2528 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2529 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
2530 {
2531 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
2532 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
2533 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2534 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
2535 {
2536 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
2537 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
2538 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2539 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
2540 {
2541 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
2542 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
2543 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2544 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
2545 {
2546 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
2547 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
2548 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2549 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
2550 {
2551 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2552 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
2553 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2554 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
2555 {
2556 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2557 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
2558 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2559 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
2560 {
2561 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2562 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
2563 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2564 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
2565 {
2566 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
2567 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
2568 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2569 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
2570 {
2571 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2572 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2573 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
2574 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
2575 {
2576 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
2577 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2578 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2579 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
2580 {
2581 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2582 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2583 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2584 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
2585 {
2586 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
2587 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2588 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2589 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
2590 {
2591 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2592 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2593 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2594 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
2595 {
2596 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
2597 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
2598 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2599 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
2600 {
2601 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
2602 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
2603 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2604 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
2605 {
2606 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
2607 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
2608 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2609 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
2610 {
2611 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
2612 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
2613 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2614 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
2615 {
2616 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
2617 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
2618 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2619 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
2620 {
2621 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
2622 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
2623 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2624 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
2625 {
2626 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
2627 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
2628 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2629 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
2630 {
2631 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
2632 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
2633 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2634 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
2635 {
2636 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
2637 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
2638 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2639 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
2640 {
2641 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
2642 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2643 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2644 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
2645 {
2646 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
2647 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2648 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2649 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
2650 {
2651 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
2652 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2653 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2654 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
2655 {
2656 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
2657 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2658 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2659 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
2660 {
2661 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
2662 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2663 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2664 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
2665 {
2666 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
2667 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2668 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2669 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
2670 {
2671 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
2672 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2673 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2674 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
2675 {
2676 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
2677 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
2678 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2679 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
2680 {
2681 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
2682 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2683 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2684 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
2685 {
2686 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2687 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2688 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2689 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
2690 {
2691 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2692 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2693 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2694 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
2695 {
2696 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2697 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2698 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2699 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
2700 {
2701 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2702 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
2703 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2704 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
2705 {
2706 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2707 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
2708 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2709 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
2710 {
2711 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2712 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
2713 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
2714 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
2715 {
2716 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
2717 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
2718 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
2719 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
2720 {
2721 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
2722 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
2723 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
2724 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
2725 {
2726 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
2727 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
2728 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
2729 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
2730 {
2731 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
2732 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00,
2733 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
2734 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
2735 {
2736 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
2737 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
2738 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
2739 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
2740 {
2741 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
2742 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00,
2743 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
2744 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
2745 {
2746 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
2747 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00,
2748 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
2749 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
2750 {
2751 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
2752 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
2753 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
2754 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
2755 {
2756 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
2757 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00,
2758 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
2759 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
2760 {
2761 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
2762 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
2763 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
2764 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
2765 {
2766 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
2767 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
2768 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
2769 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
2770 {
2771 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
2772 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
2773 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
2774 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
2775 {
2776 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
2777 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
2778 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
2779 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
2780 {
2781 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
2782 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
2783 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
2784 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
2785};
2786
2787static struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v6[] = {
2788 {
2789 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
2790 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2791 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2792 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
2793 {
2794 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
2795 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2796 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2797 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
2798 {
2799 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
2800 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2801 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2802 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
2803 {
2804 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
2805 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2806 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2807 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
2808 {
2809 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
2810 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2811 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2812 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
2813 {
2814 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
2815 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2816 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2817 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
2818 {
2819 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
2820 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2821 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2822 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
2823 {
2824 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
2825 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2826 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2827 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
2828 {
2829 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
2830 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2831 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2832 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
2833 {
2834 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
2835 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2836 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2837 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
2838 {
2839 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
2840 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2841 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2842 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
2843 {
2844 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
2845 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2846 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2847 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
2848 {
2849 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
2850 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2851 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2852 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
2853 {
2854 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
2855 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2856 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2857 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
2858 {
2859 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
2860 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
2861 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2862 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
2863 {
2864 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
2865 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
2866 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2867 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
2868 {
2869 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
2870 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
2871 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2872 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
2873 {
2874 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
2875 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
2876 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
2877 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
2878 {
2879 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
2880 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
2881 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2882 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
2883 {
2884 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
2885 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
2886 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2887 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
2888 {
2889 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
2890 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
2891 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2892 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
2893 {
2894 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
2895 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
2896 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2897 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
2898 {
2899 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
2900 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
2901 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
2902 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
2903 {
2904 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
2905 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
2906 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
2907 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
2908 {
2909 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
2910 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
2911 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
2912 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
2913 {
2914 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
2915 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
2916 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
2917 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
2918 {
2919 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
2920 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
2921 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
2922 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
2923 {
2924 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
2925 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
2926 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2927 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
2928 {
2929 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
2930 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
2931 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2932 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
2933 {
2934 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
2935 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
2936 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2937 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
2938 {
2939 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
2940 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
2941 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2942 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
2943 {
2944 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
2945 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
2946 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2947 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
2948 {
2949 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
2950 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
2951 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
2952 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
2953 {
2954 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
2955 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
2956 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
2957 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
2958 {
2959 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
2960 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
2961 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
2962 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
2963 {
2964 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
2965 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
2966 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
2967 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
2968 {
2969 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
2970 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
2971 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
2972 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
2973 {
2974 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
2975 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
2976 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
2977 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
2978 {
2979 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
2980 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
2981 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
2982 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
2983 {
2984 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
2985 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
2986 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
2987 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
2988 {
2989 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
2990 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
2991 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
2992 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
2993 {
2994 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
2995 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
2996 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
2997 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
2998 {
2999 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
3000 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
3001 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
3002 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
3003 {
3004 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
3005 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
3006 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3007 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
3008 {
3009 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
3010 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
3011 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3012 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
3013 {
3014 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3015 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
3016 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3017 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
3018 {
3019 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3020 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
3021 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3022 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
3023 {
3024 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3025 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
3026 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
3027 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
3028 {
3029 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3030 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
3031 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
3032 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
3033 {
3034 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3035 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
3036 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
3037 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
3038 {
3039 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3040 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
3041 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
3042 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
3043 {
3044 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
3045 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
3046 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
3047 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
3048 {
3049 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
3050 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
3051 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
3052 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
3053 {
3054 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
3055 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
3056 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
3057 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
3058 {
3059 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
3060 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
3061 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
3062 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
3063 {
3064 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
3065 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
3066 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3067 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
3068 {
3069 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
3070 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
3071 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3072 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
3073 {
3074 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
3075 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
3076 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3077 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
3078 {
3079 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
3080 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
3081 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3082 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
3083 {
3084 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
3085 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
3086 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3087 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
3088 {
3089 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
3090 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
3091 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3092 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
3093 {
3094 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3095 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
3096 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3097 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
3098 {
3099 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3100 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
3101 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3102 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
3103 {
3104 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3105 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
3106 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3107 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
3108 {
3109 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3110 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
3111 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
3112 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
3113 {
3114 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3115 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
3116 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
3117 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
3118 {
3119 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3120 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
3121 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
3122 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
3123 {
3124 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
3125 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
3126 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
3127 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
3128 {
3129 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
3130 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
3131 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
3132 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
3133 {
3134 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
3135 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
3136 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
3137 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
3138 {
3139 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
3140 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
3141 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
3142 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
3143 {
3144 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
3145 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
3146 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
3147 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
3148 {
3149 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
3150 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
3151 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
3152 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
3153 {
3154 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
3155 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
3156 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3157 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
3158 {
3159 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
3160 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
3161 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3162 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
3163 {
3164 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
3165 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3166 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3167 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
3168 {
3169 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
3170 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3171 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3172 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
3173 {
3174 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3175 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3176 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3177 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
3178 {
3179 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3180 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3181 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3182 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
3183 {
3184 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3185 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3186 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3187 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
3188 {
3189 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
3190 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
3191 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3192 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
3193 {
3194 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3195 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
3196 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3197 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
3198 {
3199 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
3200 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
3201 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3202 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
3203 {
3204 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3205 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
3206 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3207 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
3208 {
3209 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
3210 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
3211 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
3212 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
3213 {
3214 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3215 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
3216 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3217 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
3218 {
3219 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
3220 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
3221 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3222 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
3223 {
3224 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
3225 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
3226 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3227 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
3228 {
3229 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
3230 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
3231 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3232 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
3233 {
3234 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
3235 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
3236 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3237 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
3238 {
3239 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
3240 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
3241 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3242 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
3243 {
3244 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
3245 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
3246 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3247 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
3248 {
3249 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
3250 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
3251 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3252 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
3253 {
3254 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
3255 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
3256 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3257 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
3258 {
3259 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
3260 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3261 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3262 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
3263 {
3264 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
3265 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3266 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3267 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
3268 {
3269 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
3270 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3271 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3272 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
3273 {
3274 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
3275 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3276 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3277 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
3278 {
3279 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
3280 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3281 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3282 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
3283 {
3284 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
3285 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3286 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3287 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
3288 {
3289 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
3290 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3291 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3292 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
3293 {
3294 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
3295 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3296 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
3297 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
3298 {
3299 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
3300 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3301 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3302 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
3303 {
3304 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
3305 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3306 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3307 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
3308 {
3309 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3310 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3311 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3312 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
3313 {
3314 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3315 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3316 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3317 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
3318 {
3319 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3320 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3321 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3322 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
3323 {
3324 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3325 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3326 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3327 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
3328 {
3329 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3330 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3331 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3332 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
3333 {
3334 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3335 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
3336 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
3337 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
3338 {
3339 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
3340 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
3341 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
3342 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
3343 {
3344 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
3345 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
3346 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
3347 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
3348 {
3349 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
3350 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
3351 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
3352 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
3353 {
3354 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
3355 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
3356 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
3357 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
3358 {
3359 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
3360 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
3361 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
3362 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
3363 {
3364 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
3365 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
3366 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
3367 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
3368 {
3369 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
3370 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
3371 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
3372 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
3373 {
3374 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
3375 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
3376 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
3377 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
3378 {
3379 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
3380 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
3381 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
3382 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
3383 {
3384 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
3385 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
3386 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
3387 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
3388 {
3389 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
3390 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
3391 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
3392 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
3393 {
3394 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
3395 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
3396 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
3397 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
3398 {
3399 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
3400 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
3401 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
3402 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
3403 {
3404 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
3405 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3406 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
3407 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
3408};
3409
3410static struct chan_info_nphy_radio205x chan_info_nphyrev5n6_2056v7[] = {
3411 {
3412 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
3413 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
3414 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
3415 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
3416 {
3417 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
3418 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
3419 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
3420 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
3421 {
3422 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
3423 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
3424 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
3425 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
3426 {
3427 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
3428 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
3429 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
3430 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
3431 {
3432 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
3433 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3434 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
3435 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
3436 {
3437 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
3438 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3439 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3440 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
3441 {
3442 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
3443 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3444 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3445 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
3446 {
3447 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
3448 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3449 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3450 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
3451 {
3452 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
3453 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3454 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3455 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
3456 {
3457 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
3458 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
3459 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
3460 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
3461 {
3462 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
3463 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
3464 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
3465 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
3466 {
3467 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
3468 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
3469 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
3470 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
3471 {
3472 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
3473 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
3474 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
3475 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
3476 {
3477 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
3478 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
3479 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
3480 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
3481 {
3482 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
3483 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
3484 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
3485 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
3486 {
3487 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
3488 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
3489 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3490 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
3491 {
3492 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
3493 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3494 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3495 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
3496 {
3497 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
3498 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3499 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3500 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
3501 {
3502 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
3503 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3504 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3505 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
3506 {
3507 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
3508 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3509 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3510 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
3511 {
3512 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
3513 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
3514 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
3515 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
3516 {
3517 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
3518 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
3519 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
3520 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
3521 {
3522 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
3523 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
3524 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
3525 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
3526 {
3527 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
3528 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
3529 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
3530 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
3531 {
3532 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
3533 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
3534 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3535 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
3536 {
3537 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
3538 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
3539 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3540 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
3541 {
3542 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
3543 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
3544 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3545 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
3546 {
3547 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
3548 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
3549 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3550 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
3551 {
3552 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
3553 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
3554 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3555 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
3556 {
3557 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3558 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70,
3559 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
3560 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
3561 {
3562 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3563 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70,
3564 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
3565 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
3566 {
3567 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3568 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70,
3569 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
3570 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
3571 {
3572 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3573 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70,
3574 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
3575 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
3576 {
3577 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3578 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70,
3579 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
3580 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
3581 {
3582 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3583 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70,
3584 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3585 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
3586 {
3587 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
3588 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
3589 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3590 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
3591 {
3592 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
3593 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
3594 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3595 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
3596 {
3597 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
3598 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
3599 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3600 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
3601 {
3602 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
3603 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
3604 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3605 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
3606 {
3607 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
3608 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70,
3609 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3610 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
3611 {
3612 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
3613 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70,
3614 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
3615 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
3616 {
3617 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
3618 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70,
3619 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
3620 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
3621 {
3622 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
3623 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70,
3624 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3625 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
3626 {
3627 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
3628 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
3629 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3630 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
3631 {
3632 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
3633 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
3634 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3635 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
3636 {
3637 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3638 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70,
3639 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3640 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
3641 {
3642 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3643 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
3644 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3645 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
3646 {
3647 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3648 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
3649 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
3650 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
3651 {
3652 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3653 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70,
3654 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
3655 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
3656 {
3657 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3658 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70,
3659 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
3660 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
3661 {
3662 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3663 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70,
3664 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
3665 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
3666 {
3667 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
3668 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70,
3669 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
3670 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
3671 {
3672 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
3673 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
3674 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
3675 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
3676 {
3677 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
3678 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
3679 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
3680 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
3681 {
3682 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
3683 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70,
3684 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3685 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
3686 {
3687 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
3688 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
3689 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3690 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
3691 {
3692 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
3693 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70,
3694 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3695 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
3696 {
3697 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
3698 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
3699 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3700 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
3701 {
3702 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
3703 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
3704 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3705 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
3706 {
3707 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
3708 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70,
3709 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
3710 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
3711 {
3712 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
3713 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70,
3714 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
3715 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
3716 {
3717 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3718 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70,
3719 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
3720 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
3721 {
3722 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3723 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
3724 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
3725 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
3726 {
3727 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3728 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
3729 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
3730 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
3731 {
3732 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3733 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70,
3734 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3735 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
3736 {
3737 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3738 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70,
3739 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3740 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
3741 {
3742 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3743 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3744 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3745 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
3746 {
3747 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
3748 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3749 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3750 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
3751 {
3752 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
3753 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3754 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3755 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
3756 {
3757 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
3758 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3759 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3760 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
3761 {
3762 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
3763 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
3764 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3765 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
3766 {
3767 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
3768 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70,
3769 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
3770 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
3771 {
3772 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
3773 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
3774 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3775 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
3776 {
3777 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
3778 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
3779 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3780 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
3781 {
3782 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
3783 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
3784 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3785 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
3786 {
3787 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
3788 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3789 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3790 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
3791 {
3792 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
3793 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3794 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3795 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
3796 {
3797 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3798 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3799 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3800 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
3801 {
3802 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3803 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3804 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3805 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
3806 {
3807 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3808 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3809 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3810 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
3811 {
3812 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
3813 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
3814 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3815 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
3816 {
3817 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3818 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3819 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
3820 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
3821 {
3822 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
3823 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3824 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3825 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
3826 {
3827 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3828 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3829 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3830 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
3831 {
3832 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
3833 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3834 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3835 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
3836 {
3837 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3838 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
3839 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3840 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
3841 {
3842 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
3843 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70,
3844 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3845 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
3846 {
3847 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
3848 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
3849 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3850 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
3851 {
3852 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
3853 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
3854 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3855 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
3856 {
3857 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
3858 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
3859 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3860 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
3861 {
3862 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
3863 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
3864 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3865 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
3866 {
3867 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
3868 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70,
3869 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3870 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
3871 {
3872 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
3873 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3874 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3875 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
3876 {
3877 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
3878 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3879 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3880 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
3881 {
3882 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
3883 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3884 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3885 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
3886 {
3887 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
3888 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3889 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3890 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
3891 {
3892 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
3893 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3894 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3895 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
3896 {
3897 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
3898 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3899 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3900 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
3901 {
3902 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
3903 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3904 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3905 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
3906 {
3907 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
3908 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3909 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3910 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
3911 {
3912 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
3913 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3914 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3915 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
3916 {
3917 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
3918 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3919 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3920 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
3921 {
3922 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
3923 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
3924 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3925 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
3926 {
3927 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
3928 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3929 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3930 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
3931 {
3932 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
3933 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3934 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3935 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
3936 {
3937 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
3938 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3939 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3940 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
3941 {
3942 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
3943 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3944 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3945 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
3946 {
3947 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
3948 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3949 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3950 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
3951 {
3952 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
3953 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3954 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3955 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
3956 {
3957 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
3958 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
3959 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
3960 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
3961 {
3962 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
3963 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
3964 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
3965 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
3966 {
3967 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
3968 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
3969 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
3970 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
3971 {
3972 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
3973 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
3974 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
3975 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
3976 {
3977 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
3978 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
3979 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
3980 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
3981 {
3982 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
3983 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00,
3984 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
3985 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
3986 {
3987 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
3988 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00,
3989 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
3990 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
3991 {
3992 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
3993 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00,
3994 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
3995 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
3996 {
3997 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
3998 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00,
3999 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
4000 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
4001 {
4002 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
4003 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
4004 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
4005 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
4006 {
4007 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
4008 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
4009 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
4010 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
4011 {
4012 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
4013 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
4014 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
4015 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
4016 {
4017 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
4018 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00,
4019 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
4020 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
4021 {
4022 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
4023 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
4024 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
4025 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
4026 {
4027 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
4028 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
4029 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
4030 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
4031};
4032
4033static struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v8[] = {
4034 {
4035 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
4036 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4037 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4038 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
4039 {
4040 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
4041 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4042 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4043 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
4044 {
4045 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
4046 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4047 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4048 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
4049 {
4050 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
4051 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4052 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4053 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
4054 {
4055 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
4056 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4057 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4058 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
4059 {
4060 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
4061 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4062 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4063 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
4064 {
4065 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
4066 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4067 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4068 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
4069 {
4070 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
4071 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4072 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4073 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
4074 {
4075 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
4076 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4077 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4078 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
4079 {
4080 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
4081 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4082 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4083 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
4084 {
4085 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
4086 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4087 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4088 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
4089 {
4090 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
4091 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4092 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4093 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
4094 {
4095 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
4096 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4097 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4098 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
4099 {
4100 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
4101 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4102 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4103 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
4104 {
4105 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
4106 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4107 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4108 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
4109 {
4110 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
4111 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4112 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4113 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
4114 {
4115 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
4116 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4117 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4118 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
4119 {
4120 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
4121 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4122 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4123 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
4124 {
4125 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
4126 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
4127 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4128 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
4129 {
4130 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
4131 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4132 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4133 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
4134 {
4135 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
4136 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4137 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4138 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
4139 {
4140 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
4141 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4142 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4143 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
4144 {
4145 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
4146 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
4147 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4148 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
4149 {
4150 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
4151 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
4152 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
4153 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
4154 {
4155 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
4156 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
4157 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
4158 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
4159 {
4160 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
4161 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
4162 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
4163 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
4164 {
4165 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
4166 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
4167 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
4168 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
4169 {
4170 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
4171 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
4172 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4173 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
4174 {
4175 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
4176 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
4177 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4178 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
4179 {
4180 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4181 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
4182 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4183 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
4184 {
4185 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4186 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
4187 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4188 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
4189 {
4190 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4191 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
4192 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4193 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
4194 {
4195 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4196 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
4197 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4198 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
4199 {
4200 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4201 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
4202 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
4203 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
4204 {
4205 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4206 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
4207 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
4208 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
4209 {
4210 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
4211 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4212 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4213 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
4214 {
4215 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
4216 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4217 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4218 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
4219 {
4220 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
4221 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4222 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4223 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
4224 {
4225 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
4226 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4227 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4228 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
4229 {
4230 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
4231 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
4232 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4233 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
4234 {
4235 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
4236 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
4237 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4238 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
4239 {
4240 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
4241 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
4242 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4243 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
4244 {
4245 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
4246 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
4247 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4248 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
4249 {
4250 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
4251 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
4252 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4253 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
4254 {
4255 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
4256 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
4257 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4258 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
4259 {
4260 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4261 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
4262 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4263 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
4264 {
4265 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4266 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
4267 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4268 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
4269 {
4270 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4271 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
4272 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4273 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
4274 {
4275 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4276 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
4277 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4278 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
4279 {
4280 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4281 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
4282 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4283 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
4284 {
4285 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4286 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
4287 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4288 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
4289 {
4290 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
4291 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
4292 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
4293 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
4294 {
4295 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
4296 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
4297 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4298 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
4299 {
4300 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
4301 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
4302 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4303 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
4304 {
4305 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
4306 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
4307 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4308 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
4309 {
4310 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
4311 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
4312 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4313 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
4314 {
4315 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
4316 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
4317 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4318 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
4319 {
4320 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
4321 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
4322 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4323 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
4324 {
4325 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
4326 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
4327 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4328 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
4329 {
4330 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
4331 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
4332 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4333 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
4334 {
4335 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
4336 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
4337 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4338 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
4339 {
4340 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4341 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
4342 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4343 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
4344 {
4345 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4346 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
4347 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4348 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
4349 {
4350 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4351 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
4352 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4353 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
4354 {
4355 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4356 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
4357 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4358 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
4359 {
4360 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4361 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
4362 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4363 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
4364 {
4365 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4366 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
4367 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4368 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
4369 {
4370 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
4371 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
4372 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4373 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
4374 {
4375 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
4376 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
4377 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4378 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
4379 {
4380 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
4381 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
4382 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
4383 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
4384 {
4385 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
4386 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
4387 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
4388 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
4389 {
4390 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
4391 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
4392 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
4393 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
4394 {
4395 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
4396 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
4397 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
4398 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
4399 {
4400 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
4401 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
4402 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4403 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
4404 {
4405 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
4406 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
4407 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4408 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
4409 {
4410 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
4411 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4412 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4413 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
4414 {
4415 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
4416 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4417 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4418 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
4419 {
4420 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4421 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4422 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4423 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
4424 {
4425 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4426 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4427 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4428 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
4429 {
4430 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4431 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4432 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4433 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
4434 {
4435 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
4436 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
4437 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4438 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
4439 {
4440 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4441 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
4442 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4443 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
4444 {
4445 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
4446 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
4447 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4448 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
4449 {
4450 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4451 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
4452 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4453 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
4454 {
4455 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
4456 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
4457 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
4458 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
4459 {
4460 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4461 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
4462 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4463 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
4464 {
4465 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
4466 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
4467 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4468 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
4469 {
4470 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
4471 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
4472 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4473 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
4474 {
4475 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
4476 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
4477 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4478 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
4479 {
4480 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
4481 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
4482 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4483 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
4484 {
4485 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
4486 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
4487 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4488 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
4489 {
4490 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
4491 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
4492 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4493 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
4494 {
4495 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
4496 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
4497 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4498 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
4499 {
4500 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
4501 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
4502 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4503 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
4504 {
4505 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
4506 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4507 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4508 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
4509 {
4510 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
4511 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4512 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4513 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
4514 {
4515 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
4516 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4517 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4518 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
4519 {
4520 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
4521 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4522 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4523 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
4524 {
4525 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
4526 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4527 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4528 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
4529 {
4530 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
4531 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4532 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4533 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
4534 {
4535 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
4536 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4537 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4538 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
4539 {
4540 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
4541 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4542 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
4543 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
4544 {
4545 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
4546 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4547 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4548 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
4549 {
4550 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
4551 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4552 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4553 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
4554 {
4555 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
4556 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4557 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4558 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
4559 {
4560 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
4561 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4562 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4563 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
4564 {
4565 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
4566 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4567 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4568 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
4569 {
4570 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
4571 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4572 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4573 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
4574 {
4575 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
4576 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4577 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4578 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
4579 {
4580 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
4581 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
4582 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
4583 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
4584 {
4585 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
4586 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
4587 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
4588 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
4589 {
4590 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
4591 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
4592 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
4593 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
4594 {
4595 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
4596 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
4597 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
4598 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
4599 {
4600 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
4601 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
4602 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
4603 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
4604 {
4605 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
4606 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
4607 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
4608 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
4609 {
4610 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
4611 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
4612 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
4613 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
4614 {
4615 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
4616 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
4617 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
4618 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
4619 {
4620 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
4621 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
4622 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
4623 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
4624 {
4625 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
4626 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
4627 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
4628 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
4629 {
4630 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
4631 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
4632 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
4633 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
4634 {
4635 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
4636 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
4637 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
4638 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
4639 {
4640 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
4641 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
4642 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
4643 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
4644 {
4645 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
4646 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
4647 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
4648 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
4649 {
4650 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
4651 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
4652 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
4653 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
4654};
4655
4656static struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v11[] = {
4657 {
4658 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01,
4659 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4660 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4661 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
4662 {
4663 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01,
4664 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4665 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4666 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
4667 {
4668 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01,
4669 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4670 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4671 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
4672 {
4673 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01,
4674 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4675 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4676 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
4677 {
4678 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01,
4679 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4680 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4681 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
4682 {
4683 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01,
4684 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4685 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4686 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
4687 {
4688 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01,
4689 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4690 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4691 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
4692 {
4693 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01,
4694 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4695 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4696 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
4697 {
4698 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01,
4699 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4700 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4701 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
4702 {
4703 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01,
4704 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4705 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4706 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
4707 {
4708 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01,
4709 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4710 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4711 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
4712 {
4713 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01,
4714 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4715 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4716 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
4717 {
4718 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01,
4719 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4720 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4721 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
4722 {
4723 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01,
4724 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4725 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4726 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
4727 {
4728 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01,
4729 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
4730 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4731 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
4732 {
4733 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01,
4734 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4735 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4736 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
4737 {
4738 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01,
4739 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4740 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4741 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
4742 {
4743 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01,
4744 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
4745 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
4746 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
4747 {
4748 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01,
4749 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
4750 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4751 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
4752 {
4753 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01,
4754 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4755 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4756 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
4757 {
4758 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01,
4759 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4760 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4761 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
4762 {
4763 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01,
4764 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
4765 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4766 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
4767 {
4768 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01,
4769 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
4770 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
4771 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
4772 {
4773 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01,
4774 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
4775 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
4776 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
4777 {
4778 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01,
4779 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
4780 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
4781 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
4782 {
4783 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01,
4784 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
4785 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
4786 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
4787 {
4788 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01,
4789 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
4790 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
4791 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
4792 {
4793 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01,
4794 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
4795 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4796 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
4797 {
4798 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01,
4799 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
4800 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4801 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
4802 {
4803 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01,
4804 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
4805 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4806 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
4807 {
4808 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01,
4809 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
4810 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4811 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
4812 {
4813 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01,
4814 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
4815 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4816 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
4817 {
4818 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01,
4819 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
4820 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
4821 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
4822 {
4823 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01,
4824 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
4825 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
4826 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
4827 {
4828 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01,
4829 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
4830 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
4831 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
4832 {
4833 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01,
4834 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4835 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4836 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
4837 {
4838 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01,
4839 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4840 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4841 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
4842 {
4843 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01,
4844 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4845 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4846 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
4847 {
4848 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01,
4849 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
4850 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4851 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
4852 {
4853 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01,
4854 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
4855 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
4856 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
4857 {
4858 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01,
4859 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
4860 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4861 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
4862 {
4863 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01,
4864 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
4865 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4866 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
4867 {
4868 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01,
4869 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
4870 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
4871 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
4872 {
4873 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01,
4874 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
4875 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4876 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
4877 {
4878 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01,
4879 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
4880 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4881 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
4882 {
4883 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01,
4884 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
4885 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4886 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
4887 {
4888 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01,
4889 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
4890 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4891 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
4892 {
4893 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01,
4894 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
4895 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
4896 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
4897 {
4898 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01,
4899 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
4900 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4901 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
4902 {
4903 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01,
4904 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
4905 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4906 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
4907 {
4908 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01,
4909 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
4910 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
4911 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
4912 {
4913 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01,
4914 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
4915 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
4916 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
4917 {
4918 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01,
4919 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
4920 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4921 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
4922 {
4923 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01,
4924 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
4925 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4926 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
4927 {
4928 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01,
4929 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
4930 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
4931 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
4932 {
4933 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01,
4934 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
4935 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4936 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
4937 {
4938 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01,
4939 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
4940 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4941 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
4942 {
4943 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01,
4944 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
4945 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4946 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
4947 {
4948 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01,
4949 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
4950 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4951 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
4952 {
4953 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01,
4954 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
4955 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4956 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
4957 {
4958 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01,
4959 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
4960 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4961 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
4962 {
4963 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01,
4964 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
4965 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4966 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
4967 {
4968 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01,
4969 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
4970 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4971 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
4972 {
4973 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01,
4974 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
4975 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4976 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
4977 {
4978 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01,
4979 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
4980 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
4981 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
4982 {
4983 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01,
4984 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
4985 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4986 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
4987 {
4988 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01,
4989 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
4990 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4991 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
4992 {
4993 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01,
4994 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
4995 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
4996 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
4997 {
4998 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01,
4999 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
5000 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
5001 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
5002 {
5003 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01,
5004 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
5005 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
5006 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
5007 {
5008 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01,
5009 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
5010 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
5011 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
5012 {
5013 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01,
5014 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
5015 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
5016 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
5017 {
5018 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01,
5019 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
5020 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
5021 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
5022 {
5023 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01,
5024 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
5025 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5026 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
5027 {
5028 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01,
5029 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
5030 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5031 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
5032 {
5033 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01,
5034 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5035 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5036 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
5037 {
5038 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01,
5039 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5040 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5041 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
5042 {
5043 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01,
5044 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5045 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5046 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
5047 {
5048 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01,
5049 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5050 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5051 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
5052 {
5053 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01,
5054 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5055 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5056 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
5057 {
5058 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01,
5059 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
5060 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5061 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
5062 {
5063 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01,
5064 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
5065 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5066 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
5067 {
5068 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01,
5069 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
5070 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5071 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
5072 {
5073 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01,
5074 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
5075 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5076 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
5077 {
5078 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01,
5079 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
5080 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
5081 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
5082 {
5083 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01,
5084 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
5085 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5086 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
5087 {
5088 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01,
5089 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
5090 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5091 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
5092 {
5093 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01,
5094 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
5095 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5096 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
5097 {
5098 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01,
5099 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
5100 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5101 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
5102 {
5103 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01,
5104 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
5105 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5106 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
5107 {
5108 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01,
5109 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
5110 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5111 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
5112 {
5113 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01,
5114 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
5115 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5116 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
5117 {
5118 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01,
5119 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
5120 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5121 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
5122 {
5123 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01,
5124 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
5125 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5126 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
5127 {
5128 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01,
5129 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5130 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5131 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
5132 {
5133 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01,
5134 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5135 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5136 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
5137 {
5138 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01,
5139 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5140 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5141 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
5142 {
5143 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01,
5144 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5145 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5146 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
5147 {
5148 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01,
5149 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5150 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5151 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
5152 {
5153 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01,
5154 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5155 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5156 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
5157 {
5158 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01,
5159 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5160 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5161 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
5162 {
5163 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01,
5164 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5165 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
5166 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
5167 {
5168 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01,
5169 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5170 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5171 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
5172 {
5173 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01,
5174 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5175 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5176 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
5177 {
5178 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01,
5179 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5180 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5181 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
5182 {
5183 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01,
5184 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5185 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5186 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
5187 {
5188 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01,
5189 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5190 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5191 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
5192 {
5193 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01,
5194 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5195 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5196 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
5197 {
5198 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01,
5199 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5200 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5201 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
5202 {
5203 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01,
5204 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
5205 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
5206 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
5207 {
5208 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01,
5209 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
5210 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
5211 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
5212 {
5213 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01,
5214 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
5215 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
5216 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
5217 {
5218 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01,
5219 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
5220 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
5221 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
5222 {
5223 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01,
5224 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
5225 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
5226 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
5227 {
5228 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01,
5229 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
5230 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
5231 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
5232 {
5233 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01,
5234 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
5235 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
5236 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
5237 {
5238 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01,
5239 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
5240 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
5241 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
5242 {
5243 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01,
5244 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
5245 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
5246 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
5247 {
5248 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01,
5249 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
5250 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
5251 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
5252 {
5253 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01,
5254 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
5255 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
5256 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
5257 {
5258 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01,
5259 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
5260 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
5261 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
5262 {
5263 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01,
5264 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
5265 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
5266 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
5267 {
5268 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01,
5269 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
5270 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
5271 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
5272 {
5273 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01,
5274 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
5275 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
5276 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
5277};
5278
5279static struct chan_info_nphy_radio2057 chan_info_nphyrev7_2057_rev4[] = {
5280 {
5281 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
5282 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5283 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214,
5284 0x0215,
5285 0x0216,
5286 },
5287 {
5288 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
5289 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5290 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213,
5291 0x0214,
5292 0x0215,
5293 },
5294 {
5295 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
5296 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5297 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212,
5298 0x0213,
5299 0x0214,
5300 },
5301 {
5302 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
5303 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5304 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211,
5305 0x0212,
5306 0x0213,
5307 },
5308 {
5309 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
5310 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5311 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f,
5312 0x0211,
5313 0x0212,
5314 },
5315 {
5316 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
5317 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5318 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e,
5319 0x020f,
5320 0x0211,
5321 },
5322 {
5323 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
5324 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5325 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d,
5326 0x020e,
5327 0x020f,
5328 },
5329 {
5330 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
5331 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5332 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c,
5333 0x020d,
5334 0x020e,
5335 },
5336 {
5337 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
5338 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5339 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b,
5340 0x020c,
5341 0x020d,
5342 },
5343 {
5344 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
5345 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5346 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a,
5347 0x020b,
5348 0x020c,
5349 },
5350 {
5351 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
5352 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5353 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209,
5354 0x020a,
5355 0x020b,
5356 },
5357 {
5358 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
5359 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5360 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208,
5361 0x0209,
5362 0x020a,
5363 },
5364 {
5365 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
5366 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5367 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207,
5368 0x0208,
5369 0x0209,
5370 },
5371 {
5372 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
5373 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
5374 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206,
5375 0x0207,
5376 0x0208,
5377 },
5378 {
5379 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
5380 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00,
5381 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205,
5382 0x0206,
5383 0x0207,
5384 },
5385 {
5386 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
5387 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
5388 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204,
5389 0x0205,
5390 0x0206,
5391 },
5392 {
5393 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
5394 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
5395 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203,
5396 0x0204,
5397 0x0205,
5398 },
5399 {
5400 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
5401 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5402 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202,
5403 0x0203,
5404 0x0204,
5405 },
5406 {
5407 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
5408 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5409 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201,
5410 0x0202,
5411 0x0203,
5412 },
5413 {
5414 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
5415 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5416 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200,
5417 0x0201,
5418 0x0202,
5419 },
5420 {
5421 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
5422 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5423 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff,
5424 0x0200,
5425 0x0201,
5426 },
5427 {
5428 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
5429 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
5430 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe,
5431 0x01ff,
5432 0x0200,
5433 },
5434 {
5435 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
5436 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
5437 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd,
5438 0x01fe,
5439 0x01ff,
5440 },
5441 {
5442 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
5443 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
5444 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb,
5445 0x01fc,
5446 0x01fd,
5447 },
5448 {
5449 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
5450 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
5451 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa,
5452 0x01fb,
5453 0x01fc,
5454 },
5455 {
5456 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
5457 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5458 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9,
5459 0x01fa,
5460 0x01fb,
5461 },
5462 {
5463 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
5464 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5465 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8,
5466 0x01f9,
5467 0x01fa,
5468 },
5469 {
5470 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
5471 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5472 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7,
5473 0x01f8,
5474 0x01f9,
5475 },
5476 {
5477 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
5478 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5479 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6,
5480 0x01f7,
5481 0x01f8,
5482 },
5483 {
5484 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
5485 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5486 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5,
5487 0x01f6,
5488 0x01f7,
5489 },
5490 {
5491 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
5492 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5493 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4,
5494 0x01f5,
5495 0x01f6,
5496 },
5497 {
5498 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
5499 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5500 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3,
5501 0x01f4,
5502 0x01f5,
5503 },
5504 {
5505 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
5506 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
5507 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2,
5508 0x01f3,
5509 0x01f4,
5510 },
5511 {
5512 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
5513 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
5514 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1,
5515 0x01f2,
5516 0x01f3,
5517 },
5518 {
5519 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
5520 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
5521 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0,
5522 0x01f1,
5523 0x01f2,
5524 },
5525 {
5526 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
5527 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5528 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0,
5529 0x01f0,
5530 0x01f1,
5531 },
5532 {
5533 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
5534 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5535 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef,
5536 0x01f0,
5537 0x01f0,
5538 },
5539 {
5540 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
5541 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5542 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee,
5543 0x01ef,
5544 0x01f0,
5545 },
5546 {
5547 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
5548 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5549 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed,
5550 0x01ee,
5551 0x01ef,
5552 },
5553 {
5554 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
5555 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5556 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec,
5557 0x01ed,
5558 0x01ee,
5559 },
5560 {
5561 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
5562 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
5563 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb,
5564 0x01ec,
5565 0x01ed,
5566 },
5567 {
5568 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
5569 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00,
5570 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea,
5571 0x01eb,
5572 0x01ec,
5573 },
5574 {
5575 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
5576 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
5577 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9,
5578 0x01ea,
5579 0x01eb,
5580 },
5581 {
5582 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
5583 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
5584 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8,
5585 0x01e9,
5586 0x01ea,
5587 },
5588 {
5589 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
5590 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
5591 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7,
5592 0x01e8,
5593 0x01e9,
5594 },
5595 {
5596 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
5597 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
5598 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6,
5599 0x01e7,
5600 0x01e8,
5601 },
5602 {
5603 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
5604 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00,
5605 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5,
5606 0x01e6,
5607 0x01e7,
5608 },
5609 {
5610 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
5611 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
5612 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5,
5613 0x01e5,
5614 0x01e6,
5615 },
5616 {
5617 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
5618 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
5619 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4,
5620 0x01e5,
5621 0x01e5,
5622 },
5623 {
5624 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
5625 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00,
5626 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3,
5627 0x01e4,
5628 0x01e5,
5629 },
5630 {
5631 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
5632 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
5633 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2,
5634 0x01e3,
5635 0x01e4,
5636 },
5637 {
5638 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
5639 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
5640 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1,
5641 0x01e2,
5642 0x01e3,
5643 },
5644 {
5645 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
5646 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
5647 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0,
5648 0x01e1,
5649 0x01e2,
5650 },
5651 {
5652 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
5653 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00,
5654 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df,
5655 0x01e0,
5656 0x01e1,
5657 },
5658 {
5659 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
5660 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00,
5661 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de,
5662 0x01df,
5663 0x01e0,
5664 },
5665 {
5666 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
5667 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
5668 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd,
5669 0x01de,
5670 0x01df,
5671 },
5672 {
5673 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
5674 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
5675 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd,
5676 0x01dd,
5677 0x01de,
5678 },
5679 {
5680 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
5681 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
5682 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc,
5683 0x01dd,
5684 0x01dd,
5685 },
5686 {
5687 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
5688 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
5689 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db,
5690 0x01dc,
5691 0x01dd,
5692 },
5693 {
5694 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
5695 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
5696 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da,
5697 0x01db,
5698 0x01dc,
5699 },
5700 {
5701 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
5702 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
5703 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
5704 0x01da,
5705 0x01db,
5706 },
5707 {
5708 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
5709 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
5710 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
5711 0x01d9,
5712 0x01da,
5713 },
5714 {
5715 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
5716 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
5717 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
5718 0x01d8,
5719 0x01d9,
5720 },
5721 {
5722 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
5723 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
5724 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
5725 0x01d7,
5726 0x01d8,
5727 },
5728 {
5729 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
5730 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
5731 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
5732 0x01d7,
5733 0x01d7,
5734 },
5735 {
5736 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
5737 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00,
5738 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
5739 0x01d6,
5740 0x01d7,
5741 },
5742 {
5743 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
5744 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00,
5745 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
5746 0x01d5,
5747 0x01d6,
5748 },
5749 {
5750 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
5751 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00,
5752 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
5753 0x01d4,
5754 0x01d5,
5755 },
5756 {
5757 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
5758 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
5759 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
5760 0x01d3,
5761 0x01d4,
5762 },
5763 {
5764 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
5765 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
5766 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
5767 0x01d2,
5768 0x01d3,
5769 },
5770 {
5771 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
5772 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
5773 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
5774 0x01d2,
5775 0x01d2,
5776 },
5777 {
5778 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
5779 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
5780 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
5781 0x01d1,
5782 0x01d2,
5783 },
5784 {
5785 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
5786 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
5787 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
5788 0x01d0,
5789 0x01d1,
5790 },
5791 {
5792 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
5793 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
5794 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
5795 0x01cf,
5796 0x01d0,
5797 },
5798 {
5799 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
5800 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00,
5801 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
5802 0x01ce,
5803 0x01cf,
5804 },
5805 {
5806 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
5807 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5808 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
5809 0x01ce,
5810 0x01ce,
5811 },
5812 {
5813 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
5814 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5815 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
5816 0x01cd,
5817 0x01ce,
5818 },
5819 {
5820 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
5821 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5822 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
5823 0x01cc,
5824 0x01cd,
5825 },
5826 {
5827 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
5828 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5829 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
5830 0x01cb,
5831 0x01cc,
5832 },
5833 {
5834 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
5835 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
5836 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
5837 0x01ca,
5838 0x01cb,
5839 },
5840 {
5841 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
5842 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00,
5843 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
5844 0x01ca,
5845 0x01cb,
5846 },
5847 {
5848 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
5849 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5850 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
5851 0x01c9,
5852 0x01ca,
5853 },
5854 {
5855 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
5856 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5857 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
5858 0x01c9,
5859 0x01ca,
5860 },
5861 {
5862 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
5863 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5864 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
5865 0x01c9,
5866 0x01c9,
5867 },
5868 {
5869 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
5870 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5871 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
5872 0x01c8,
5873 0x01c9,
5874 },
5875 {
5876 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
5877 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5878 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
5879 0x01c8,
5880 0x01c9,
5881 },
5882 {
5883 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
5884 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
5885 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
5886 0x01c8,
5887 0x01c8,
5888 },
5889 {
5890 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
5891 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
5892 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
5893 0x01c7,
5894 0x01c8,
5895 },
5896 {
5897 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
5898 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
5899 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
5900 0x01c7,
5901 0x01c8,
5902 },
5903 {
5904 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
5905 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
5906 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
5907 0x01c6,
5908 0x01c7,
5909 },
5910 {
5911 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
5912 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
5913 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
5914 0x01c6,
5915 0x01c7,
5916 },
5917 {
5918 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
5919 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00,
5920 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
5921 0x01c6,
5922 0x01c6,
5923 },
5924 {
5925 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
5926 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5927 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
5928 0x01c5,
5929 0x01c6,
5930 },
5931 {
5932 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
5933 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5934 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
5935 0x01c5,
5936 0x01c6,
5937 },
5938 {
5939 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
5940 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5941 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
5942 0x01c4,
5943 0x01c5,
5944 },
5945 {
5946 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
5947 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5948 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
5949 0x01c4,
5950 0x01c5,
5951 },
5952 {
5953 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
5954 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5955 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
5956 0x01c4,
5957 0x01c4,
5958 },
5959 {
5960 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
5961 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5962 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
5963 0x01c3,
5964 0x01c4,
5965 },
5966 {
5967 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
5968 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5969 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
5970 0x01c3,
5971 0x01c4,
5972 },
5973 {
5974 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
5975 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5976 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
5977 0x01c2,
5978 0x01c3,
5979 },
5980 {
5981 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
5982 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5983 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
5984 0x01c2,
5985 0x01c3,
5986 },
5987 {
5988 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
5989 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5990 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
5991 0x01c2,
5992 0x01c2,
5993 },
5994 {
5995 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
5996 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
5997 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
5998 0x01c1,
5999 0x01c2,
6000 },
6001 {
6002 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
6003 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6004 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
6005 0x01c0,
6006 0x01c1,
6007 },
6008 {
6009 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
6010 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6011 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
6012 0x01bf,
6013 0x01c0,
6014 },
6015 {
6016 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
6017 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6018 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
6019 0x01bf,
6020 0x01bf,
6021 },
6022 {
6023 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
6024 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6025 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
6026 0x01be,
6027 0x01bf,
6028 },
6029 {
6030 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
6031 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6032 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
6033 0x01bd,
6034 0x01be,
6035 },
6036 {
6037 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
6038 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
6039 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
6040 0x01bc,
6041 0x01bd,
6042 },
6043 {
6044 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
6045 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
6046 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
6047 0x043f,
6048 0x0443,
6049 },
6050 {
6051 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
6052 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
6053 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
6054 0x043d,
6055 0x0441,
6056 },
6057 {
6058 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
6059 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
6060 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
6061 0x043a,
6062 0x043f,
6063 },
6064 {
6065 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
6066 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
6067 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
6068 0x0438,
6069 0x043d,
6070 },
6071 {
6072 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
6073 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
6074 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
6075 0x0436,
6076 0x043a,
6077 },
6078 {
6079 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
6080 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
6081 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
6082 0x0434,
6083 0x0438,
6084 },
6085 {
6086 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
6087 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
6088 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
6089 0x0431,
6090 0x0436,
6091 },
6092 {
6093 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
6094 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
6095 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
6096 0x042f,
6097 0x0434,
6098 },
6099 {
6100 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
6101 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
6102 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
6103 0x042d,
6104 0x0431,
6105 },
6106 {
6107 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
6108 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
6109 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
6110 0x042b,
6111 0x042f,
6112 },
6113 {
6114 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
6115 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
6116 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
6117 0x0429,
6118 0x042d,
6119 },
6120 {
6121 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
6122 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
6123 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
6124 0x0427,
6125 0x042b,
6126 },
6127 {
6128 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
6129 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
6130 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
6131 0x0424,
6132 0x0429,
6133 },
6134 {
6135 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
6136 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11,
6137 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
6138 0x041f,
6139 0x0424}
6140};
6141
6142static struct chan_info_nphy_radio2057_rev5 chan_info_nphyrev8_2057_rev5[] = {
6143 {
6144 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
6145 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
6146 0x043a, 0x043f, 0x0443},
6147 {
6148 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
6149 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
6150 0x0438, 0x043d, 0x0441},
6151 {
6152 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
6153 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
6154 0x0436, 0x043a, 0x043f},
6155 {
6156 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
6157 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
6158 0x0434, 0x0438, 0x043d},
6159 {
6160 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
6161 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
6162 0x0431, 0x0436, 0x043a},
6163 {
6164 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
6165 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
6166 0x042f, 0x0434, 0x0438},
6167 {
6168 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
6169 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
6170 0x042d, 0x0431, 0x0436},
6171 {
6172 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
6173 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
6174 0x042b, 0x042f, 0x0434},
6175 {
6176 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
6177 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
6178 0x0429, 0x042d, 0x0431},
6179 {
6180 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
6181 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
6182 0x0427, 0x042b, 0x042f},
6183 {
6184 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
6185 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
6186 0x0424, 0x0429, 0x042d},
6187 {
6188 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
6189 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
6190 0x0422, 0x0427, 0x042b},
6191 {
6192 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
6193 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
6194 0x0420, 0x0424, 0x0429},
6195 {
6196 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
6197 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
6198 0x041b, 0x041f, 0x0424}
6199};
6200
6201static struct chan_info_nphy_radio2057_rev5 chan_info_nphyrev9_2057_rev5v1[] = {
6202 {
6203 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
6204 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
6205 0x043a, 0x043f, 0x0443},
6206 {
6207 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
6208 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
6209 0x0438, 0x043d, 0x0441},
6210 {
6211 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
6212 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
6213 0x0436, 0x043a, 0x043f},
6214 {
6215 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
6216 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
6217 0x0434, 0x0438, 0x043d},
6218 {
6219 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
6220 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
6221 0x0431, 0x0436, 0x043a},
6222 {
6223 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
6224 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
6225 0x042f, 0x0434, 0x0438},
6226 {
6227 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
6228 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
6229 0x042d, 0x0431, 0x0436},
6230 {
6231 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
6232 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
6233 0x042b, 0x042f, 0x0434},
6234 {
6235 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
6236 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
6237 0x0429, 0x042d, 0x0431},
6238 {
6239 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
6240 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
6241 0x0427, 0x042b, 0x042f},
6242 {
6243 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
6244 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
6245 0x0424, 0x0429, 0x042d},
6246 {
6247 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
6248 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
6249 0x0422, 0x0427, 0x042b},
6250 {
6251 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
6252 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
6253 0x0420, 0x0424, 0x0429},
6254 {
6255 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
6256 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
6257 0x041b, 0x041f, 0x0424}
6258};
6259
6260static struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev7[] = {
6261 {
6262 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
6263 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6264 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214,
6265 0x0215,
6266 0x0216},
6267 {
6268 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
6269 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6270 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
6271 0x0214,
6272 0x0215},
6273 {
6274 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
6275 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6276 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
6277 0x0213,
6278 0x0214},
6279 {
6280 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
6281 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6282 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
6283 0x0212,
6284 0x0213},
6285 {
6286 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
6287 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6288 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
6289 0x0211,
6290 0x0212},
6291 {
6292 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
6293 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6294 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
6295 0x020f,
6296 0x0211},
6297 {
6298 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
6299 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6300 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
6301 0x020e,
6302 0x020f},
6303 {
6304 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
6305 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
6306 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
6307 0x020d,
6308 0x020e},
6309 {
6310 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
6311 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6312 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
6313 0x020c,
6314 0x020d},
6315 {
6316 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
6317 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6318 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
6319 0x020b,
6320 0x020c},
6321 {
6322 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
6323 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6324 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
6325 0x020a,
6326 0x020b},
6327 {
6328 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
6329 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6330 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
6331 0x0209,
6332 0x020a},
6333 {
6334 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
6335 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6336 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
6337 0x0208,
6338 0x0209},
6339 {
6340 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
6341 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6342 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
6343 0x0207,
6344 0x0208},
6345 {
6346 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
6347 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6348 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
6349 0x0206,
6350 0x0207},
6351 {
6352 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
6353 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6354 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
6355 0x0205,
6356 0x0206},
6357 {
6358 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
6359 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6360 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
6361 0x0204,
6362 0x0205},
6363 {
6364 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
6365 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
6366 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
6367 0x0203,
6368 0x0204},
6369 {
6370 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
6371 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6372 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
6373 0x0202,
6374 0x0203},
6375 {
6376 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
6377 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6378 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
6379 0x0201,
6380 0x0202},
6381 {
6382 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
6383 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6384 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
6385 0x0200,
6386 0x0201},
6387 {
6388 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
6389 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6390 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
6391 0x01ff,
6392 0x0200},
6393 {
6394 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
6395 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6396 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
6397 0x01fe,
6398 0x01ff},
6399 {
6400 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
6401 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6402 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
6403 0x01fc,
6404 0x01fd},
6405 {
6406 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
6407 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6408 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
6409 0x01fb,
6410 0x01fc},
6411 {
6412 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
6413 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6414 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
6415 0x01fa,
6416 0x01fb},
6417 {
6418 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
6419 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
6420 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
6421 0x01f9,
6422 0x01fa},
6423 {
6424 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
6425 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6426 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
6427 0x01f8,
6428 0x01f9},
6429 {
6430 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
6431 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6432 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
6433 0x01f7,
6434 0x01f8},
6435 {
6436 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
6437 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6438 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
6439 0x01f6,
6440 0x01f7},
6441 {
6442 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
6443 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6444 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
6445 0x01f5,
6446 0x01f6},
6447 {
6448 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
6449 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6450 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
6451 0x01f4,
6452 0x01f5},
6453 {
6454 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
6455 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6456 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
6457 0x01f3,
6458 0x01f4},
6459 {
6460 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
6461 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6462 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
6463 0x01f2,
6464 0x01f3},
6465 {
6466 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
6467 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6468 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
6469 0x01f1,
6470 0x01f2},
6471 {
6472 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
6473 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6474 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
6475 0x01f0,
6476 0x01f1},
6477 {
6478 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
6479 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
6480 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
6481 0x01f0,
6482 0x01f0},
6483 {
6484 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
6485 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6486 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
6487 0x01ef,
6488 0x01f0},
6489 {
6490 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
6491 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6492 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
6493 0x01ee,
6494 0x01ef},
6495 {
6496 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
6497 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6498 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
6499 0x01ed,
6500 0x01ee},
6501 {
6502 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
6503 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6504 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
6505 0x01ec,
6506 0x01ed},
6507 {
6508 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
6509 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6510 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
6511 0x01eb,
6512 0x01ec},
6513 {
6514 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
6515 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6516 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
6517 0x01ea,
6518 0x01eb},
6519 {
6520 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
6521 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6522 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
6523 0x01e9,
6524 0x01ea},
6525 {
6526 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
6527 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6528 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
6529 0x01e8,
6530 0x01e9},
6531 {
6532 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
6533 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6534 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
6535 0x01e7,
6536 0x01e8},
6537 {
6538 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
6539 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
6540 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
6541 0x01e6,
6542 0x01e7},
6543 {
6544 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
6545 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6546 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
6547 0x01e5,
6548 0x01e6},
6549 {
6550 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
6551 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6552 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
6553 0x01e5,
6554 0x01e5},
6555 {
6556 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
6557 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6558 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
6559 0x01e4,
6560 0x01e5},
6561 {
6562 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
6563 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6564 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
6565 0x01e3,
6566 0x01e4},
6567 {
6568 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
6569 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6570 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
6571 0x01e2,
6572 0x01e3},
6573 {
6574 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
6575 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6576 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
6577 0x01e1,
6578 0x01e2},
6579 {
6580 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
6581 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6582 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
6583 0x01e0,
6584 0x01e1},
6585 {
6586 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
6587 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6588 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
6589 0x01df,
6590 0x01e0},
6591 {
6592 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
6593 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6594 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
6595 0x01de,
6596 0x01df},
6597 {
6598 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
6599 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
6600 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
6601 0x01dd,
6602 0x01de},
6603 {
6604 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
6605 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6606 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
6607 0x01dd,
6608 0x01dd},
6609 {
6610 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
6611 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6612 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
6613 0x01dc,
6614 0x01dd},
6615 {
6616 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
6617 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6618 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
6619 0x01db,
6620 0x01dc},
6621 {
6622 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
6623 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6624 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
6625 0x01da,
6626 0x01db},
6627 {
6628 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
6629 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6630 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
6631 0x01d9,
6632 0x01da},
6633 {
6634 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
6635 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6636 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
6637 0x01d8,
6638 0x01d9},
6639 {
6640 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
6641 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6642 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
6643 0x01d7,
6644 0x01d8},
6645 {
6646 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
6647 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6648 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
6649 0x01d7,
6650 0x01d7},
6651 {
6652 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
6653 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6654 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
6655 0x01d6,
6656 0x01d7},
6657 {
6658 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
6659 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
6660 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
6661 0x01d5,
6662 0x01d6},
6663 {
6664 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
6665 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6666 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
6667 0x01d4,
6668 0x01d5},
6669 {
6670 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
6671 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6672 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
6673 0x01d3,
6674 0x01d4},
6675 {
6676 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
6677 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6678 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
6679 0x01d2,
6680 0x01d3},
6681 {
6682 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
6683 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6684 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
6685 0x01d2,
6686 0x01d2},
6687 {
6688 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
6689 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
6690 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
6691 0x01d1,
6692 0x01d2},
6693 {
6694 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
6695 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
6696 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
6697 0x01d0,
6698 0x01d1},
6699 {
6700 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
6701 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
6702 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
6703 0x01cf,
6704 0x01d0},
6705 {
6706 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
6707 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
6708 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
6709 0x01ce,
6710 0x01cf},
6711 {
6712 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
6713 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
6714 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
6715 0x01ce,
6716 0x01ce},
6717 {
6718 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
6719 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
6720 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
6721 0x01cd,
6722 0x01ce},
6723 {
6724 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
6725 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6726 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
6727 0x01cc,
6728 0x01cd},
6729 {
6730 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
6731 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6732 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
6733 0x01cb,
6734 0x01cc},
6735 {
6736 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
6737 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6738 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
6739 0x01ca,
6740 0x01cb},
6741 {
6742 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
6743 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6744 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
6745 0x01ca,
6746 0x01cb},
6747 {
6748 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
6749 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6750 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
6751 0x01c9,
6752 0x01ca},
6753 {
6754 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
6755 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6756 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
6757 0x01c9,
6758 0x01ca},
6759 {
6760 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
6761 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6762 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
6763 0x01c9,
6764 0x01c9},
6765 {
6766 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
6767 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
6768 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
6769 0x01c8,
6770 0x01c9},
6771 {
6772 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
6773 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6774 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
6775 0x01c8,
6776 0x01c9},
6777 {
6778 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
6779 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6780 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
6781 0x01c8,
6782 0x01c8},
6783 {
6784 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
6785 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6786 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
6787 0x01c7,
6788 0x01c8},
6789 {
6790 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
6791 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6792 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
6793 0x01c7,
6794 0x01c8},
6795 {
6796 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
6797 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6798 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
6799 0x01c6,
6800 0x01c7},
6801 {
6802 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
6803 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6804 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
6805 0x01c6,
6806 0x01c7},
6807 {
6808 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
6809 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6810 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
6811 0x01c6,
6812 0x01c6},
6813 {
6814 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
6815 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6816 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
6817 0x01c5,
6818 0x01c6},
6819 {
6820 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
6821 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6822 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
6823 0x01c5,
6824 0x01c6},
6825 {
6826 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
6827 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
6828 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
6829 0x01c4,
6830 0x01c5},
6831 {
6832 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
6833 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
6834 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
6835 0x01c4,
6836 0x01c5},
6837 {
6838 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
6839 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6840 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
6841 0x01c4,
6842 0x01c4},
6843 {
6844 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
6845 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6846 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
6847 0x01c3,
6848 0x01c4},
6849 {
6850 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
6851 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6852 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
6853 0x01c3,
6854 0x01c4},
6855 {
6856 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
6857 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6858 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
6859 0x01c2,
6860 0x01c3},
6861 {
6862 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
6863 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6864 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
6865 0x01c2,
6866 0x01c3},
6867 {
6868 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
6869 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6870 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
6871 0x01c2,
6872 0x01c2},
6873 {
6874 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
6875 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6876 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
6877 0x01c1,
6878 0x01c2},
6879 {
6880 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
6881 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6882 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
6883 0x01c0,
6884 0x01c1},
6885 {
6886 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
6887 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6888 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
6889 0x01bf,
6890 0x01c0},
6891 {
6892 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
6893 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6894 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
6895 0x01bf,
6896 0x01bf},
6897 {
6898 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
6899 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6900 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
6901 0x01be,
6902 0x01bf},
6903 {
6904 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
6905 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6906 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
6907 0x01bd,
6908 0x01be},
6909 {
6910 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
6911 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
6912 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
6913 0x01bc,
6914 0x01bd},
6915 {
6916 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
6917 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6918 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
6919 0x043f,
6920 0x0443},
6921 {
6922 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
6923 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6924 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
6925 0x043d,
6926 0x0441},
6927 {
6928 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
6929 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6930 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
6931 0x043a,
6932 0x043f},
6933 {
6934 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
6935 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6936 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
6937 0x0438,
6938 0x043d},
6939 {
6940 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
6941 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6942 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
6943 0x0436,
6944 0x043a},
6945 {
6946 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
6947 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6948 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
6949 0x0434,
6950 0x0438},
6951 {
6952 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
6953 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6954 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
6955 0x0431,
6956 0x0436},
6957 {
6958 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
6959 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6960 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
6961 0x042f,
6962 0x0434},
6963 {
6964 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
6965 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6966 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
6967 0x042d,
6968 0x0431},
6969 {
6970 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
6971 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6972 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
6973 0x042b,
6974 0x042f},
6975 {
6976 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
6977 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6978 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
6979 0x0429,
6980 0x042d},
6981 {
6982 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
6983 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6984 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
6985 0x0427,
6986 0x042b},
6987 {
6988 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
6989 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
6990 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
6991 0x0424,
6992 0x0429},
6993 {
6994 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
6995 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
6996 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
6997 0x041f,
6998 0x0424}
6999};
7000
7001static struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev8[] = {
7002 {
7003 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
7004 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7005 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
7006 0x0214,
7007 0x0215},
7008 {
7009 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
7010 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7011 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
7012 0x0213,
7013 0x0214},
7014 {
7015 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
7016 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7017 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
7018 0x0212,
7019 0x0213},
7020 {
7021 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
7022 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7023 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
7024 0x0211,
7025 0x0212},
7026 {
7027 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
7028 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7029 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
7030 0x020f,
7031 0x0211},
7032 {
7033 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
7034 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7035 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
7036 0x020e,
7037 0x020f},
7038 {
7039 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
7040 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
7041 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
7042 0x020d,
7043 0x020e},
7044 {
7045 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
7046 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7047 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
7048 0x020c,
7049 0x020d},
7050 {
7051 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
7052 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7053 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
7054 0x020b,
7055 0x020c},
7056 {
7057 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
7058 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7059 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
7060 0x020a,
7061 0x020b},
7062 {
7063 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
7064 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7065 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
7066 0x0209,
7067 0x020a},
7068 {
7069 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
7070 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7071 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
7072 0x0208,
7073 0x0209},
7074 {
7075 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
7076 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7077 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
7078 0x0207,
7079 0x0208},
7080 {
7081 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
7082 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7083 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
7084 0x0206,
7085 0x0207},
7086 {
7087 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
7088 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7089 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
7090 0x0205,
7091 0x0206},
7092 {
7093 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
7094 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7095 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
7096 0x0204,
7097 0x0205},
7098 {
7099 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
7100 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
7101 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
7102 0x0203,
7103 0x0204},
7104 {
7105 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
7106 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7107 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
7108 0x0202,
7109 0x0203},
7110 {
7111 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
7112 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7113 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
7114 0x0201,
7115 0x0202},
7116 {
7117 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
7118 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7119 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
7120 0x0200,
7121 0x0201},
7122 {
7123 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
7124 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7125 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
7126 0x01ff,
7127 0x0200},
7128 {
7129 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
7130 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7131 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
7132 0x01fe,
7133 0x01ff},
7134 {
7135 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
7136 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7137 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
7138 0x01fc,
7139 0x01fd},
7140 {
7141 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
7142 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7143 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
7144 0x01fb,
7145 0x01fc},
7146 {
7147 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
7148 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7149 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
7150 0x01fa,
7151 0x01fb},
7152 {
7153 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
7154 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
7155 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
7156 0x01f9,
7157 0x01fa},
7158 {
7159 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
7160 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7161 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
7162 0x01f8,
7163 0x01f9},
7164 {
7165 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
7166 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7167 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
7168 0x01f7,
7169 0x01f8},
7170 {
7171 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
7172 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7173 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
7174 0x01f6,
7175 0x01f7},
7176 {
7177 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
7178 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7179 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
7180 0x01f5,
7181 0x01f6},
7182 {
7183 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
7184 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7185 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
7186 0x01f4,
7187 0x01f5},
7188 {
7189 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
7190 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7191 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
7192 0x01f3,
7193 0x01f4},
7194 {
7195 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
7196 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7197 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
7198 0x01f2,
7199 0x01f3},
7200 {
7201 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
7202 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7203 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
7204 0x01f1,
7205 0x01f2},
7206 {
7207 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
7208 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7209 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
7210 0x01f0,
7211 0x01f1},
7212 {
7213 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
7214 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
7215 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
7216 0x01f0,
7217 0x01f0},
7218 {
7219 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
7220 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7221 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
7222 0x01ef,
7223 0x01f0},
7224 {
7225 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
7226 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7227 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
7228 0x01ee,
7229 0x01ef},
7230 {
7231 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
7232 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7233 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
7234 0x01ed,
7235 0x01ee},
7236 {
7237 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
7238 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7239 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
7240 0x01ec,
7241 0x01ed},
7242 {
7243 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
7244 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7245 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
7246 0x01eb,
7247 0x01ec},
7248 {
7249 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
7250 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7251 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
7252 0x01ea,
7253 0x01eb},
7254 {
7255 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
7256 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7257 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
7258 0x01e9,
7259 0x01ea},
7260 {
7261 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
7262 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7263 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
7264 0x01e8,
7265 0x01e9},
7266 {
7267 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
7268 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7269 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
7270 0x01e7,
7271 0x01e8},
7272 {
7273 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
7274 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
7275 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
7276 0x01e6,
7277 0x01e7},
7278 {
7279 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
7280 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7281 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
7282 0x01e5,
7283 0x01e6},
7284 {
7285 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
7286 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7287 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
7288 0x01e5,
7289 0x01e5},
7290 {
7291 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
7292 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7293 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
7294 0x01e4,
7295 0x01e5},
7296 {
7297 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
7298 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7299 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
7300 0x01e3,
7301 0x01e4},
7302 {
7303 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
7304 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7305 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
7306 0x01e2,
7307 0x01e3},
7308 {
7309 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
7310 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7311 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
7312 0x01e1,
7313 0x01e2},
7314 {
7315 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
7316 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7317 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
7318 0x01e0,
7319 0x01e1},
7320 {
7321 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
7322 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7323 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
7324 0x01df,
7325 0x01e0},
7326 {
7327 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
7328 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7329 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
7330 0x01de,
7331 0x01df},
7332 {
7333 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
7334 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
7335 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
7336 0x01dd,
7337 0x01de},
7338 {
7339 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
7340 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7341 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
7342 0x01dd,
7343 0x01dd},
7344 {
7345 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
7346 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7347 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
7348 0x01dc,
7349 0x01dd},
7350 {
7351 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
7352 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7353 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
7354 0x01db,
7355 0x01dc},
7356 {
7357 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
7358 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7359 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
7360 0x01da,
7361 0x01db},
7362 {
7363 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
7364 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7365 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
7366 0x01d9,
7367 0x01da},
7368 {
7369 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
7370 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7371 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
7372 0x01d8,
7373 0x01d9},
7374 {
7375 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
7376 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7377 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
7378 0x01d7,
7379 0x01d8},
7380 {
7381 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
7382 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7383 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
7384 0x01d7,
7385 0x01d7},
7386 {
7387 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
7388 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7389 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
7390 0x01d6,
7391 0x01d7},
7392 {
7393 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
7394 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
7395 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
7396 0x01d5,
7397 0x01d6},
7398 {
7399 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
7400 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7401 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
7402 0x01d4,
7403 0x01d5},
7404 {
7405 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
7406 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7407 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
7408 0x01d3,
7409 0x01d4},
7410 {
7411 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
7412 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7413 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
7414 0x01d2,
7415 0x01d3},
7416 {
7417 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
7418 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7419 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
7420 0x01d2,
7421 0x01d2},
7422 {
7423 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
7424 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
7425 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
7426 0x01d1,
7427 0x01d2},
7428 {
7429 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
7430 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
7431 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
7432 0x01d0,
7433 0x01d1},
7434 {
7435 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
7436 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
7437 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
7438 0x01cf,
7439 0x01d0},
7440 {
7441 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
7442 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
7443 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
7444 0x01ce,
7445 0x01cf},
7446 {
7447 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
7448 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
7449 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
7450 0x01ce,
7451 0x01ce},
7452 {
7453 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
7454 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
7455 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
7456 0x01cd,
7457 0x01ce},
7458 {
7459 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
7460 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7461 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
7462 0x01cc,
7463 0x01cd},
7464 {
7465 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
7466 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7467 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
7468 0x01cb,
7469 0x01cc},
7470 {
7471 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
7472 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7473 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
7474 0x01ca,
7475 0x01cb},
7476 {
7477 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
7478 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7479 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
7480 0x01ca,
7481 0x01cb},
7482 {
7483 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
7484 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7485 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
7486 0x01c9,
7487 0x01ca},
7488 {
7489 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
7490 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7491 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
7492 0x01c9,
7493 0x01ca},
7494 {
7495 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
7496 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7497 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
7498 0x01c9,
7499 0x01c9},
7500 {
7501 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
7502 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
7503 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
7504 0x01c8,
7505 0x01c9},
7506 {
7507 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
7508 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7509 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
7510 0x01c8,
7511 0x01c9},
7512 {
7513 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
7514 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7515 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
7516 0x01c8,
7517 0x01c8},
7518 {
7519 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
7520 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7521 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
7522 0x01c7,
7523 0x01c8},
7524 {
7525 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
7526 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7527 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
7528 0x01c7,
7529 0x01c8},
7530 {
7531 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
7532 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7533 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
7534 0x01c6,
7535 0x01c7},
7536 {
7537 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
7538 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7539 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
7540 0x01c6,
7541 0x01c7},
7542 {
7543 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
7544 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7545 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
7546 0x01c6,
7547 0x01c6},
7548 {
7549 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
7550 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7551 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
7552 0x01c5,
7553 0x01c6},
7554 {
7555 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
7556 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7557 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
7558 0x01c5,
7559 0x01c6},
7560 {
7561 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
7562 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
7563 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
7564 0x01c4,
7565 0x01c5},
7566 {
7567 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
7568 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
7569 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
7570 0x01c4,
7571 0x01c5},
7572 {
7573 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
7574 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7575 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
7576 0x01c4,
7577 0x01c4},
7578 {
7579 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
7580 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7581 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
7582 0x01c3,
7583 0x01c4},
7584 {
7585 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
7586 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7587 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
7588 0x01c3,
7589 0x01c4},
7590 {
7591 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
7592 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7593 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
7594 0x01c2,
7595 0x01c3},
7596 {
7597 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
7598 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7599 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
7600 0x01c2,
7601 0x01c3},
7602 {
7603 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
7604 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7605 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
7606 0x01c2,
7607 0x01c2},
7608 {
7609 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
7610 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7611 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
7612 0x01c1,
7613 0x01c2},
7614 {
7615 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
7616 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7617 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
7618 0x01c0,
7619 0x01c1},
7620 {
7621 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
7622 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7623 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
7624 0x01bf,
7625 0x01c0},
7626 {
7627 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
7628 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7629 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
7630 0x01bf,
7631 0x01bf},
7632 {
7633 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
7634 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7635 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
7636 0x01be,
7637 0x01bf},
7638 {
7639 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
7640 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7641 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
7642 0x01bd,
7643 0x01be},
7644 {
7645 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
7646 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
7647 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
7648 0x01bc,
7649 0x01bd},
7650 {
7651 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
7652 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7653 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
7654 0x043f,
7655 0x0443},
7656 {
7657 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
7658 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7659 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
7660 0x043d,
7661 0x0441},
7662 {
7663 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
7664 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7665 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
7666 0x043a,
7667 0x043f},
7668 {
7669 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
7670 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7671 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
7672 0x0438,
7673 0x043d},
7674 {
7675 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
7676 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7677 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
7678 0x0436,
7679 0x043a},
7680 {
7681 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
7682 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7683 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
7684 0x0434,
7685 0x0438},
7686 {
7687 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
7688 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7689 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
7690 0x0431,
7691 0x0436},
7692 {
7693 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
7694 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7695 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
7696 0x042f,
7697 0x0434},
7698 {
7699 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
7700 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7701 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
7702 0x042d,
7703 0x0431},
7704 {
7705 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
7706 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7707 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
7708 0x042b,
7709 0x042f},
7710 {
7711 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
7712 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7713 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
7714 0x0429,
7715 0x042d},
7716 {
7717 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
7718 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7719 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
7720 0x0427,
7721 0x042b},
7722 {
7723 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
7724 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
7725 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
7726 0x0424,
7727 0x0429},
7728 {
7729 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
7730 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
7731 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
7732 0x041f,
7733 0x0424}
7734};
7735
7736struct radio_regs regs_2055[] = {
7737 {0x02, 0x80, 0x80, 0, 0},
7738 {0x03, 0, 0, 0, 0},
7739 {0x04, 0x27, 0x27, 0, 0},
7740 {0x05, 0, 0, 0, 0},
7741 {0x06, 0x27, 0x27, 0, 0},
7742 {0x07, 0x7f, 0x7f, 1, 1},
7743 {0x08, 0x7, 0x7, 1, 1},
7744 {0x09, 0x7f, 0x7f, 1, 1},
7745 {0x0A, 0x7, 0x7, 1, 1},
7746 {0x0B, 0x15, 0x15, 0, 0},
7747 {0x0C, 0x15, 0x15, 0, 0},
7748 {0x0D, 0x4f, 0x4f, 1, 1},
7749 {0x0E, 0x5, 0x5, 1, 1},
7750 {0x0F, 0x4f, 0x4f, 1, 1},
7751 {0x10, 0x5, 0x5, 1, 1},
7752 {0x11, 0xd0, 0xd0, 0, 0},
7753 {0x12, 0x2, 0x2, 0, 0},
7754 {0x13, 0, 0, 0, 0},
7755 {0x14, 0x40, 0x40, 0, 0},
7756 {0x15, 0, 0, 0, 0},
7757 {0x16, 0, 0, 0, 0},
7758 {0x17, 0, 0, 0, 0},
7759 {0x18, 0, 0, 0, 0},
7760 {0x19, 0, 0, 0, 0},
7761 {0x1A, 0, 0, 0, 0},
7762 {0x1B, 0, 0, 0, 0},
7763 {0x1C, 0, 0, 0, 0},
7764 {0x1D, 0xc0, 0xc0, 0, 0},
7765 {0x1E, 0xff, 0xff, 0, 0},
7766 {0x1F, 0xc0, 0xc0, 0, 0},
7767 {0x20, 0xff, 0xff, 0, 0},
7768 {0x21, 0xc0, 0xc0, 0, 0},
7769 {0x22, 0, 0, 0, 0},
7770 {0x23, 0x2c, 0x2c, 0, 0},
7771 {0x24, 0, 0, 0, 0},
7772 {0x25, 0, 0, 0, 0},
7773 {0x26, 0, 0, 0, 0},
7774 {0x27, 0, 0, 0, 0},
7775 {0x28, 0, 0, 0, 0},
7776 {0x29, 0, 0, 0, 0},
7777 {0x2A, 0, 0, 0, 0},
7778 {0x2B, 0, 0, 0, 0},
7779 {0x2C, 0, 0, 0, 0},
7780 {0x2D, 0xa4, 0xa4, 0, 0},
7781 {0x2E, 0x38, 0x38, 0, 0},
7782 {0x2F, 0, 0, 0, 0},
7783 {0x30, 0x4, 0x4, 1, 1},
7784 {0x31, 0, 0, 0, 0},
7785 {0x32, 0xa, 0xa, 0, 0},
7786 {0x33, 0x87, 0x87, 0, 0},
7787 {0x34, 0x9, 0x9, 0, 0},
7788 {0x35, 0x70, 0x70, 0, 0},
7789 {0x36, 0x11, 0x11, 0, 0},
7790 {0x37, 0x18, 0x18, 1, 1},
7791 {0x38, 0x6, 0x6, 0, 0},
7792 {0x39, 0x4, 0x4, 1, 1},
7793 {0x3A, 0x6, 0x6, 0, 0},
7794 {0x3B, 0x9e, 0x9e, 0, 0},
7795 {0x3C, 0x9, 0x9, 0, 0},
7796 {0x3D, 0xc8, 0xc8, 1, 1},
7797 {0x3E, 0x88, 0x88, 0, 0},
7798 {0x3F, 0, 0, 0, 0},
7799 {0x40, 0, 0, 0, 0},
7800 {0x41, 0, 0, 0, 0},
7801 {0x42, 0x1, 0x1, 0, 0},
7802 {0x43, 0x2, 0x2, 0, 0},
7803 {0x44, 0x96, 0x96, 0, 0},
7804 {0x45, 0x3e, 0x3e, 0, 0},
7805 {0x46, 0x3e, 0x3e, 0, 0},
7806 {0x47, 0x13, 0x13, 0, 0},
7807 {0x48, 0x2, 0x2, 0, 0},
7808 {0x49, 0x15, 0x15, 0, 0},
7809 {0x4A, 0x7, 0x7, 0, 0},
7810 {0x4B, 0, 0, 0, 0},
7811 {0x4C, 0, 0, 0, 0},
7812 {0x4D, 0, 0, 0, 0},
7813 {0x4E, 0, 0, 0, 0},
7814 {0x4F, 0, 0, 0, 0},
7815 {0x50, 0x8, 0x8, 0, 0},
7816 {0x51, 0x8, 0x8, 0, 0},
7817 {0x52, 0x6, 0x6, 0, 0},
7818 {0x53, 0x84, 0x84, 1, 1},
7819 {0x54, 0xc3, 0xc3, 0, 0},
7820 {0x55, 0x8f, 0x8f, 0, 0},
7821 {0x56, 0xff, 0xff, 0, 0},
7822 {0x57, 0xff, 0xff, 0, 0},
7823 {0x58, 0x88, 0x88, 0, 0},
7824 {0x59, 0x88, 0x88, 0, 0},
7825 {0x5A, 0, 0, 0, 0},
7826 {0x5B, 0xcc, 0xcc, 0, 0},
7827 {0x5C, 0x6, 0x6, 0, 0},
7828 {0x5D, 0x80, 0x80, 0, 0},
7829 {0x5E, 0x80, 0x80, 0, 0},
7830 {0x5F, 0xf8, 0xf8, 0, 0},
7831 {0x60, 0x88, 0x88, 0, 0},
7832 {0x61, 0x88, 0x88, 0, 0},
7833 {0x62, 0x88, 0x8, 1, 1},
7834 {0x63, 0x88, 0x88, 0, 0},
7835 {0x64, 0, 0, 0, 0},
7836 {0x65, 0x1, 0x1, 1, 1},
7837 {0x66, 0x8a, 0x8a, 0, 0},
7838 {0x67, 0x8, 0x8, 0, 0},
7839 {0x68, 0x83, 0x83, 0, 0},
7840 {0x69, 0x6, 0x6, 0, 0},
7841 {0x6A, 0xa0, 0xa0, 0, 0},
7842 {0x6B, 0xa, 0xa, 0, 0},
7843 {0x6C, 0x87, 0x87, 1, 1},
7844 {0x6D, 0x2a, 0x2a, 0, 0},
7845 {0x6E, 0x2a, 0x2a, 0, 0},
7846 {0x6F, 0x2a, 0x2a, 0, 0},
7847 {0x70, 0x2a, 0x2a, 0, 0},
7848 {0x71, 0x18, 0x18, 0, 0},
7849 {0x72, 0x6a, 0x6a, 1, 1},
7850 {0x73, 0xab, 0xab, 1, 1},
7851 {0x74, 0x13, 0x13, 1, 1},
7852 {0x75, 0xc1, 0xc1, 1, 1},
7853 {0x76, 0xaa, 0xaa, 1, 1},
7854 {0x77, 0x87, 0x87, 1, 1},
7855 {0x78, 0, 0, 0, 0},
7856 {0x79, 0x6, 0x6, 0, 0},
7857 {0x7A, 0x7, 0x7, 0, 0},
7858 {0x7B, 0x7, 0x7, 0, 0},
7859 {0x7C, 0x15, 0x15, 0, 0},
7860 {0x7D, 0x55, 0x55, 0, 0},
7861 {0x7E, 0x97, 0x97, 1, 1},
7862 {0x7F, 0x8, 0x8, 0, 0},
7863 {0x80, 0x14, 0x14, 1, 1},
7864 {0x81, 0x33, 0x33, 0, 0},
7865 {0x82, 0x88, 0x88, 0, 0},
7866 {0x83, 0x6, 0x6, 0, 0},
7867 {0x84, 0x3, 0x3, 1, 1},
7868 {0x85, 0xa, 0xa, 0, 0},
7869 {0x86, 0x3, 0x3, 1, 1},
7870 {0x87, 0x2a, 0x2a, 0, 0},
7871 {0x88, 0xa4, 0xa4, 0, 0},
7872 {0x89, 0x18, 0x18, 0, 0},
7873 {0x8A, 0x28, 0x28, 0, 0},
7874 {0x8B, 0, 0, 0, 0},
7875 {0x8C, 0x4a, 0x4a, 0, 0},
7876 {0x8D, 0, 0, 0, 0},
7877 {0x8E, 0xf8, 0xf8, 0, 0},
7878 {0x8F, 0x88, 0x88, 0, 0},
7879 {0x90, 0x88, 0x88, 0, 0},
7880 {0x91, 0x88, 0x8, 1, 1},
7881 {0x92, 0x88, 0x88, 0, 0},
7882 {0x93, 0, 0, 0, 0},
7883 {0x94, 0x1, 0x1, 1, 1},
7884 {0x95, 0x8a, 0x8a, 0, 0},
7885 {0x96, 0x8, 0x8, 0, 0},
7886 {0x97, 0x83, 0x83, 0, 0},
7887 {0x98, 0x6, 0x6, 0, 0},
7888 {0x99, 0xa0, 0xa0, 0, 0},
7889 {0x9A, 0xa, 0xa, 0, 0},
7890 {0x9B, 0x87, 0x87, 1, 1},
7891 {0x9C, 0x2a, 0x2a, 0, 0},
7892 {0x9D, 0x2a, 0x2a, 0, 0},
7893 {0x9E, 0x2a, 0x2a, 0, 0},
7894 {0x9F, 0x2a, 0x2a, 0, 0},
7895 {0xA0, 0x18, 0x18, 0, 0},
7896 {0xA1, 0x6a, 0x6a, 1, 1},
7897 {0xA2, 0xab, 0xab, 1, 1},
7898 {0xA3, 0x13, 0x13, 1, 1},
7899 {0xA4, 0xc1, 0xc1, 1, 1},
7900 {0xA5, 0xaa, 0xaa, 1, 1},
7901 {0xA6, 0x87, 0x87, 1, 1},
7902 {0xA7, 0, 0, 0, 0},
7903 {0xA8, 0x6, 0x6, 0, 0},
7904 {0xA9, 0x7, 0x7, 0, 0},
7905 {0xAA, 0x7, 0x7, 0, 0},
7906 {0xAB, 0x15, 0x15, 0, 0},
7907 {0xAC, 0x55, 0x55, 0, 0},
7908 {0xAD, 0x97, 0x97, 1, 1},
7909 {0xAE, 0x8, 0x8, 0, 0},
7910 {0xAF, 0x14, 0x14, 1, 1},
7911 {0xB0, 0x33, 0x33, 0, 0},
7912 {0xB1, 0x88, 0x88, 0, 0},
7913 {0xB2, 0x6, 0x6, 0, 0},
7914 {0xB3, 0x3, 0x3, 1, 1},
7915 {0xB4, 0xa, 0xa, 0, 0},
7916 {0xB5, 0x3, 0x3, 1, 1},
7917 {0xB6, 0x2a, 0x2a, 0, 0},
7918 {0xB7, 0xa4, 0xa4, 0, 0},
7919 {0xB8, 0x18, 0x18, 0, 0},
7920 {0xB9, 0x28, 0x28, 0, 0},
7921 {0xBA, 0, 0, 0, 0},
7922 {0xBB, 0x4a, 0x4a, 0, 0},
7923 {0xBC, 0, 0, 0, 0},
7924 {0xBD, 0x71, 0x71, 0, 0},
7925 {0xBE, 0x72, 0x72, 0, 0},
7926 {0xBF, 0x73, 0x73, 0, 0},
7927 {0xC0, 0x74, 0x74, 0, 0},
7928 {0xC1, 0x75, 0x75, 0, 0},
7929 {0xC2, 0x76, 0x76, 0, 0},
7930 {0xC3, 0x77, 0x77, 0, 0},
7931 {0xC4, 0x78, 0x78, 0, 0},
7932 {0xC5, 0x79, 0x79, 0, 0},
7933 {0xC6, 0x7a, 0x7a, 0, 0},
7934 {0xC7, 0, 0, 0, 0},
7935 {0xC8, 0, 0, 0, 0},
7936 {0xC9, 0, 0, 0, 0},
7937 {0xCA, 0, 0, 0, 0},
7938 {0xCB, 0, 0, 0, 0},
7939 {0xCC, 0, 0, 0, 0},
7940 {0xCD, 0, 0, 0, 0},
7941 {0xCE, 0x6, 0x6, 0, 0},
7942 {0xCF, 0, 0, 0, 0},
7943 {0xD0, 0, 0, 0, 0},
7944 {0xD1, 0x18, 0x18, 0, 0},
7945 {0xD2, 0x88, 0x88, 0, 0},
7946 {0xD3, 0, 0, 0, 0},
7947 {0xD4, 0, 0, 0, 0},
7948 {0xD5, 0, 0, 0, 0},
7949 {0xD6, 0, 0, 0, 0},
7950 {0xD7, 0, 0, 0, 0},
7951 {0xD8, 0, 0, 0, 0},
7952 {0xD9, 0, 0, 0, 0},
7953 {0xDA, 0x6, 0x6, 0, 0},
7954 {0xDB, 0, 0, 0, 0},
7955 {0xDC, 0, 0, 0, 0},
7956 {0xDD, 0x18, 0x18, 0, 0},
7957 {0xDE, 0x88, 0x88, 0, 0},
7958 {0xDF, 0, 0, 0, 0},
7959 {0xE0, 0, 0, 0, 0},
7960 {0xE1, 0, 0, 0, 0},
7961 {0xE2, 0, 0, 0, 0},
7962 {0xFFFF, 0, 0, 0, 0},
7963};
7964
7965struct radio_regs regs_SYN_2056[] = {
7966 {0x02, 0, 0, 0, 0},
7967 {0x03, 0, 0, 0, 0},
7968 {0x04, 0, 0, 0, 0},
7969 {0x05, 0, 0, 0, 0},
7970 {0x06, 0, 0, 0, 0},
7971 {0x07, 0, 0, 0, 0},
7972 {0x08, 0, 0, 0, 0},
7973 {0x09, 0x1, 0x1, 0, 0},
7974 {0x0A, 0, 0, 0, 0},
7975 {0x0B, 0, 0, 0, 0},
7976 {0x0C, 0, 0, 0, 0},
7977 {0x0D, 0, 0, 0, 0},
7978 {0x0E, 0, 0, 0, 0},
7979 {0x0F, 0, 0, 0, 0},
7980 {0x10, 0, 0, 0, 0},
7981 {0x11, 0, 0, 0, 0},
7982 {0x12, 0, 0, 0, 0},
7983 {0x13, 0, 0, 0, 0},
7984 {0x14, 0, 0, 0, 0},
7985 {0x15, 0, 0, 0, 0},
7986 {0x16, 0, 0, 0, 0},
7987 {0x17, 0, 0, 0, 0},
7988 {0x18, 0, 0, 0, 0},
7989 {0x19, 0, 0, 0, 0},
7990 {0x1A, 0, 0, 0, 0},
7991 {0x1B, 0, 0, 0, 0},
7992 {0x1C, 0, 0, 0, 0},
7993 {0x1D, 0, 0, 0, 0},
7994 {0x1E, 0, 0, 0, 0},
7995 {0x1F, 0, 0, 0, 0},
7996 {0x20, 0, 0, 0, 0},
7997 {0x21, 0, 0, 0, 0},
7998 {0x22, 0x60, 0x60, 0, 0},
7999 {0x23, 0x6, 0x6, 0, 0},
8000 {0x24, 0xc, 0xc, 0, 0},
8001 {0x25, 0, 0, 0, 0},
8002 {0x26, 0, 0, 0, 0},
8003 {0x27, 0, 0, 0, 0},
8004 {0x28, 0x1, 0x1, 0, 0},
8005 {0x29, 0, 0, 0, 0},
8006 {0x2A, 0, 0, 0, 0},
8007 {0x2B, 0, 0, 0, 0},
8008 {0x2C, 0, 0, 0, 0},
8009 {0x2D, 0, 0, 0, 0},
8010 {0x2E, 0xd, 0xd, 0, 0},
8011 {0x2F, 0x1f, 0x1f, 0, 0},
8012 {0x30, 0x15, 0x15, 0, 0},
8013 {0x31, 0xf, 0xf, 0, 0},
8014 {0x32, 0, 0, 0, 0},
8015 {0x33, 0, 0, 0, 0},
8016 {0x34, 0, 0, 0, 0},
8017 {0x35, 0, 0, 0, 0},
8018 {0x36, 0, 0, 0, 0},
8019 {0x37, 0, 0, 0, 0},
8020 {0x38, 0, 0, 0, 0},
8021 {0x39, 0, 0, 0, 0},
8022 {0x3A, 0, 0, 0, 0},
8023 {0x3B, 0, 0, 0, 0},
8024 {0x3C, 0x13, 0x13, 0, 0},
8025 {0x3D, 0xf, 0xf, 0, 0},
8026 {0x3E, 0x18, 0x18, 0, 0},
8027 {0x3F, 0, 0, 0, 0},
8028 {0x40, 0, 0, 0, 0},
8029 {0x41, 0x20, 0x20, 0, 0},
8030 {0x42, 0x20, 0x20, 0, 0},
8031 {0x43, 0, 0, 0, 0},
8032 {0x44, 0x77, 0x77, 0, 0},
8033 {0x45, 0x7, 0x7, 0, 0},
8034 {0x46, 0x1, 0x1, 0, 0},
8035 {0x47, 0x4, 0x4, 0, 0},
8036 {0x48, 0xf, 0xf, 0, 0},
8037 {0x49, 0x30, 0x30, 0, 0},
8038 {0x4A, 0x32, 0x32, 0, 0},
8039 {0x4B, 0xd, 0xd, 0, 0},
8040 {0x4C, 0xd, 0xd, 0, 0},
8041 {0x4D, 0x4, 0x4, 0, 0},
8042 {0x4E, 0x6, 0x6, 0, 0},
8043 {0x4F, 0x1, 0x1, 0, 0},
8044 {0x50, 0x1c, 0x1c, 0, 0},
8045 {0x51, 0x2, 0x2, 0, 0},
8046 {0x52, 0x2, 0x2, 0, 0},
8047 {0x53, 0xf7, 0xf7, 1, 1},
8048 {0x54, 0xb4, 0xb4, 0, 0},
8049 {0x55, 0xd2, 0xd2, 0, 0},
8050 {0x56, 0, 0, 0, 0},
8051 {0x57, 0, 0, 0, 0},
8052 {0x58, 0x4, 0x4, 0, 0},
8053 {0x59, 0x96, 0x96, 0, 0},
8054 {0x5A, 0x3e, 0x3e, 0, 0},
8055 {0x5B, 0x3e, 0x3e, 0, 0},
8056 {0x5C, 0x13, 0x13, 0, 0},
8057 {0x5D, 0x2, 0x2, 0, 0},
8058 {0x5E, 0, 0, 0, 0},
8059 {0x5F, 0x7, 0x7, 0, 0},
8060 {0x60, 0x7, 0x7, 1, 1},
8061 {0x61, 0x8, 0x8, 0, 0},
8062 {0x62, 0x3, 0x3, 0, 0},
8063 {0x63, 0, 0, 0, 0},
8064 {0x64, 0, 0, 0, 0},
8065 {0x65, 0, 0, 0, 0},
8066 {0x66, 0, 0, 0, 0},
8067 {0x67, 0, 0, 0, 0},
8068 {0x68, 0x40, 0x40, 0, 0},
8069 {0x69, 0, 0, 0, 0},
8070 {0x6A, 0, 0, 0, 0},
8071 {0x6B, 0, 0, 0, 0},
8072 {0x6C, 0, 0, 0, 0},
8073 {0x6D, 0x1, 0x1, 0, 0},
8074 {0x6E, 0, 0, 0, 0},
8075 {0x6F, 0, 0, 0, 0},
8076 {0x70, 0x60, 0x60, 0, 0},
8077 {0x71, 0x66, 0x66, 0, 0},
8078 {0x72, 0xc, 0xc, 0, 0},
8079 {0x73, 0x66, 0x66, 0, 0},
8080 {0x74, 0x8f, 0x8f, 1, 1},
8081 {0x75, 0, 0, 0, 0},
8082 {0x76, 0xcc, 0xcc, 0, 0},
8083 {0x77, 0x1, 0x1, 0, 0},
8084 {0x78, 0x66, 0x66, 0, 0},
8085 {0x79, 0x66, 0x66, 0, 0},
8086 {0x7A, 0, 0, 0, 0},
8087 {0x7B, 0, 0, 0, 0},
8088 {0x7C, 0, 0, 0, 0},
8089 {0x7D, 0, 0, 0, 0},
8090 {0x7E, 0, 0, 0, 0},
8091 {0x7F, 0, 0, 0, 0},
8092 {0x80, 0, 0, 0, 0},
8093 {0x81, 0, 0, 0, 0},
8094 {0x82, 0, 0, 0, 0},
8095 {0x83, 0, 0, 0, 0},
8096 {0x84, 0, 0, 0, 0},
8097 {0x85, 0xff, 0xff, 0, 0},
8098 {0x86, 0, 0, 0, 0},
8099 {0x87, 0, 0, 0, 0},
8100 {0x88, 0, 0, 0, 0},
8101 {0x89, 0, 0, 0, 0},
8102 {0x8A, 0, 0, 0, 0},
8103 {0x8B, 0, 0, 0, 0},
8104 {0x8C, 0, 0, 0, 0},
8105 {0x8D, 0, 0, 0, 0},
8106 {0x8E, 0, 0, 0, 0},
8107 {0x8F, 0, 0, 0, 0},
8108 {0x90, 0, 0, 0, 0},
8109 {0x91, 0, 0, 0, 0},
8110 {0x92, 0, 0, 0, 0},
8111 {0x93, 0, 0, 0, 0},
8112 {0x94, 0, 0, 0, 0},
8113 {0x95, 0, 0, 0, 0},
8114 {0x96, 0, 0, 0, 0},
8115 {0x97, 0, 0, 0, 0},
8116 {0x98, 0, 0, 0, 0},
8117 {0x99, 0, 0, 0, 0},
8118 {0x9A, 0, 0, 0, 0},
8119 {0x9B, 0, 0, 0, 0},
8120 {0x9C, 0, 0, 0, 0},
8121 {0x9D, 0, 0, 0, 0},
8122 {0x9E, 0, 0, 0, 0},
8123 {0x9F, 0x6, 0x6, 0, 0},
8124 {0xA0, 0x66, 0x66, 0, 0},
8125 {0xA1, 0x66, 0x66, 0, 0},
8126 {0xA2, 0x66, 0x66, 0, 0},
8127 {0xA3, 0x66, 0x66, 0, 0},
8128 {0xA4, 0x66, 0x66, 0, 0},
8129 {0xA5, 0x66, 0x66, 0, 0},
8130 {0xA6, 0x66, 0x66, 0, 0},
8131 {0xA7, 0x66, 0x66, 0, 0},
8132 {0xA8, 0x66, 0x66, 0, 0},
8133 {0xA9, 0x66, 0x66, 0, 0},
8134 {0xAA, 0x66, 0x66, 0, 0},
8135 {0xAB, 0x66, 0x66, 0, 0},
8136 {0xAC, 0x66, 0x66, 0, 0},
8137 {0xAD, 0x66, 0x66, 0, 0},
8138 {0xAE, 0x66, 0x66, 0, 0},
8139 {0xAF, 0x66, 0x66, 0, 0},
8140 {0xB0, 0x66, 0x66, 0, 0},
8141 {0xB1, 0x66, 0x66, 0, 0},
8142 {0xB2, 0x66, 0x66, 0, 0},
8143 {0xB3, 0xa, 0xa, 0, 0},
8144 {0xB4, 0, 0, 0, 0},
8145 {0xB5, 0, 0, 0, 0},
8146 {0xB6, 0, 0, 0, 0},
8147 {0xFFFF, 0, 0, 0, 0}
8148};
8149
8150struct radio_regs regs_TX_2056[] = {
8151 {0x02, 0, 0, 0, 0},
8152 {0x03, 0, 0, 0, 0},
8153 {0x04, 0, 0, 0, 0},
8154 {0x05, 0, 0, 0, 0},
8155 {0x06, 0, 0, 0, 0},
8156 {0x07, 0, 0, 0, 0},
8157 {0x08, 0, 0, 0, 0},
8158 {0x09, 0, 0, 0, 0},
8159 {0x0A, 0, 0, 0, 0},
8160 {0x0B, 0, 0, 0, 0},
8161 {0x0C, 0, 0, 0, 0},
8162 {0x0D, 0, 0, 0, 0},
8163 {0x0E, 0, 0, 0, 0},
8164 {0x0F, 0, 0, 0, 0},
8165 {0x10, 0, 0, 0, 0},
8166 {0x11, 0, 0, 0, 0},
8167 {0x12, 0, 0, 0, 0},
8168 {0x13, 0, 0, 0, 0},
8169 {0x14, 0, 0, 0, 0},
8170 {0x15, 0, 0, 0, 0},
8171 {0x16, 0, 0, 0, 0},
8172 {0x17, 0, 0, 0, 0},
8173 {0x18, 0, 0, 0, 0},
8174 {0x19, 0, 0, 0, 0},
8175 {0x1A, 0, 0, 0, 0},
8176 {0x1B, 0, 0, 0, 0},
8177 {0x1C, 0, 0, 0, 0},
8178 {0x1D, 0, 0, 0, 0},
8179 {0x1E, 0, 0, 0, 0},
8180 {0x1F, 0, 0, 0, 0},
8181 {0x20, 0, 0, 0, 0},
8182 {0x21, 0x88, 0x88, 0, 0},
8183 {0x22, 0x88, 0x88, 0, 0},
8184 {0x23, 0x88, 0x88, 0, 0},
8185 {0x24, 0x88, 0x88, 0, 0},
8186 {0x25, 0xc, 0xc, 0, 0},
8187 {0x26, 0, 0, 0, 0},
8188 {0x27, 0x3, 0x3, 0, 0},
8189 {0x28, 0, 0, 0, 0},
8190 {0x29, 0x3, 0x3, 0, 0},
8191 {0x2A, 0x37, 0x37, 0, 0},
8192 {0x2B, 0x3, 0x3, 0, 0},
8193 {0x2C, 0, 0, 0, 0},
8194 {0x2D, 0, 0, 0, 0},
8195 {0x2E, 0x1, 0x1, 0, 0},
8196 {0x2F, 0x1, 0x1, 0, 0},
8197 {0x30, 0, 0, 0, 0},
8198 {0x31, 0, 0, 0, 0},
8199 {0x32, 0, 0, 0, 0},
8200 {0x33, 0x11, 0x11, 0, 0},
8201 {0x34, 0x11, 0x11, 0, 0},
8202 {0x35, 0, 0, 0, 0},
8203 {0x36, 0, 0, 0, 0},
8204 {0x37, 0x3, 0x3, 0, 0},
8205 {0x38, 0xf, 0xf, 0, 0},
8206 {0x39, 0, 0, 0, 0},
8207 {0x3A, 0x2d, 0x2d, 0, 0},
8208 {0x3B, 0, 0, 0, 0},
8209 {0x3C, 0x6e, 0x6e, 0, 0},
8210 {0x3D, 0xf0, 0xf0, 1, 1},
8211 {0x3E, 0, 0, 0, 0},
8212 {0x3F, 0, 0, 0, 0},
8213 {0x40, 0, 0, 0, 0},
8214 {0x41, 0x3, 0x3, 0, 0},
8215 {0x42, 0x3, 0x3, 0, 0},
8216 {0x43, 0, 0, 0, 0},
8217 {0x44, 0x1e, 0x1e, 0, 0},
8218 {0x45, 0, 0, 0, 0},
8219 {0x46, 0x6e, 0x6e, 0, 0},
8220 {0x47, 0xf0, 0xf0, 1, 1},
8221 {0x48, 0, 0, 0, 0},
8222 {0x49, 0x2, 0x2, 0, 0},
8223 {0x4A, 0xff, 0xff, 1, 1},
8224 {0x4B, 0xc, 0xc, 0, 0},
8225 {0x4C, 0, 0, 0, 0},
8226 {0x4D, 0x38, 0x38, 0, 0},
8227 {0x4E, 0x70, 0x70, 1, 1},
8228 {0x4F, 0x2, 0x2, 0, 0},
8229 {0x50, 0x88, 0x88, 0, 0},
8230 {0x51, 0xc, 0xc, 0, 0},
8231 {0x52, 0, 0, 0, 0},
8232 {0x53, 0x8, 0x8, 0, 0},
8233 {0x54, 0x70, 0x70, 1, 1},
8234 {0x55, 0x2, 0x2, 0, 0},
8235 {0x56, 0xff, 0xff, 1, 1},
8236 {0x57, 0, 0, 0, 0},
8237 {0x58, 0x83, 0x83, 0, 0},
8238 {0x59, 0x77, 0x77, 1, 1},
8239 {0x5A, 0, 0, 0, 0},
8240 {0x5B, 0x2, 0x2, 0, 0},
8241 {0x5C, 0x88, 0x88, 0, 0},
8242 {0x5D, 0, 0, 0, 0},
8243 {0x5E, 0x8, 0x8, 0, 0},
8244 {0x5F, 0x77, 0x77, 1, 1},
8245 {0x60, 0x1, 0x1, 0, 0},
8246 {0x61, 0, 0, 0, 0},
8247 {0x62, 0x7, 0x7, 0, 0},
8248 {0x63, 0, 0, 0, 0},
8249 {0x64, 0x7, 0x7, 0, 0},
8250 {0x65, 0, 0, 0, 0},
8251 {0x66, 0, 0, 0, 0},
8252 {0x67, 0x74, 0x74, 1, 1},
8253 {0x68, 0, 0, 0, 0},
8254 {0x69, 0xa, 0xa, 0, 0},
8255 {0x6A, 0, 0, 0, 0},
8256 {0x6B, 0, 0, 0, 0},
8257 {0x6C, 0, 0, 0, 0},
8258 {0x6D, 0, 0, 0, 0},
8259 {0x6E, 0, 0, 0, 0},
8260 {0x6F, 0, 0, 0, 0},
8261 {0x70, 0, 0, 0, 0},
8262 {0x71, 0x2, 0x2, 0, 0},
8263 {0x72, 0, 0, 0, 0},
8264 {0x73, 0, 0, 0, 0},
8265 {0x74, 0xe, 0xe, 0, 0},
8266 {0x75, 0xe, 0xe, 0, 0},
8267 {0x76, 0xe, 0xe, 0, 0},
8268 {0x77, 0x13, 0x13, 0, 0},
8269 {0x78, 0x13, 0x13, 0, 0},
8270 {0x79, 0x1b, 0x1b, 0, 0},
8271 {0x7A, 0x1b, 0x1b, 0, 0},
8272 {0x7B, 0x55, 0x55, 0, 0},
8273 {0x7C, 0x5b, 0x5b, 0, 0},
8274 {0x7D, 0, 0, 0, 0},
8275 {0x7E, 0, 0, 0, 0},
8276 {0x7F, 0, 0, 0, 0},
8277 {0x80, 0, 0, 0, 0},
8278 {0x81, 0, 0, 0, 0},
8279 {0x82, 0, 0, 0, 0},
8280 {0x83, 0, 0, 0, 0},
8281 {0x84, 0, 0, 0, 0},
8282 {0x85, 0, 0, 0, 0},
8283 {0x86, 0, 0, 0, 0},
8284 {0x87, 0, 0, 0, 0},
8285 {0x88, 0, 0, 0, 0},
8286 {0x89, 0, 0, 0, 0},
8287 {0x8A, 0, 0, 0, 0},
8288 {0x8B, 0, 0, 0, 0},
8289 {0x8C, 0, 0, 0, 0},
8290 {0x8D, 0, 0, 0, 0},
8291 {0x8E, 0, 0, 0, 0},
8292 {0x8F, 0, 0, 0, 0},
8293 {0x90, 0, 0, 0, 0},
8294 {0x91, 0, 0, 0, 0},
8295 {0x92, 0, 0, 0, 0},
8296 {0xFFFF, 0, 0, 0, 0}
8297};
8298
8299struct radio_regs regs_RX_2056[] = {
8300 {0x02, 0, 0, 0, 0},
8301 {0x03, 0, 0, 0, 0},
8302 {0x04, 0, 0, 0, 0},
8303 {0x05, 0, 0, 0, 0},
8304 {0x06, 0, 0, 0, 0},
8305 {0x07, 0, 0, 0, 0},
8306 {0x08, 0, 0, 0, 0},
8307 {0x09, 0, 0, 0, 0},
8308 {0x0A, 0, 0, 0, 0},
8309 {0x0B, 0, 0, 0, 0},
8310 {0x0C, 0, 0, 0, 0},
8311 {0x0D, 0, 0, 0, 0},
8312 {0x0E, 0, 0, 0, 0},
8313 {0x0F, 0, 0, 0, 0},
8314 {0x10, 0, 0, 0, 0},
8315 {0x11, 0, 0, 0, 0},
8316 {0x12, 0, 0, 0, 0},
8317 {0x13, 0, 0, 0, 0},
8318 {0x14, 0, 0, 0, 0},
8319 {0x15, 0, 0, 0, 0},
8320 {0x16, 0, 0, 0, 0},
8321 {0x17, 0, 0, 0, 0},
8322 {0x18, 0, 0, 0, 0},
8323 {0x19, 0, 0, 0, 0},
8324 {0x1A, 0, 0, 0, 0},
8325 {0x1B, 0, 0, 0, 0},
8326 {0x1C, 0, 0, 0, 0},
8327 {0x1D, 0, 0, 0, 0},
8328 {0x1E, 0, 0, 0, 0},
8329 {0x1F, 0, 0, 0, 0},
8330 {0x20, 0x3, 0x3, 0, 0},
8331 {0x21, 0, 0, 0, 0},
8332 {0x22, 0, 0, 0, 0},
8333 {0x23, 0x90, 0x90, 0, 0},
8334 {0x24, 0x55, 0x55, 0, 0},
8335 {0x25, 0x15, 0x15, 0, 0},
8336 {0x26, 0x5, 0x5, 0, 0},
8337 {0x27, 0x15, 0x15, 0, 0},
8338 {0x28, 0x5, 0x5, 0, 0},
8339 {0x29, 0x20, 0x20, 0, 0},
8340 {0x2A, 0x11, 0x11, 0, 0},
8341 {0x2B, 0x90, 0x90, 0, 0},
8342 {0x2C, 0, 0, 0, 0},
8343 {0x2D, 0x88, 0x88, 0, 0},
8344 {0x2E, 0x32, 0x32, 0, 0},
8345 {0x2F, 0x77, 0x77, 0, 0},
8346 {0x30, 0x17, 0x17, 1, 1},
8347 {0x31, 0xff, 0xff, 1, 1},
8348 {0x32, 0x20, 0x20, 0, 0},
8349 {0x33, 0, 0, 0, 0},
8350 {0x34, 0x88, 0x88, 0, 0},
8351 {0x35, 0x32, 0x32, 0, 0},
8352 {0x36, 0x77, 0x77, 0, 0},
8353 {0x37, 0x17, 0x17, 1, 1},
8354 {0x38, 0xf0, 0xf0, 1, 1},
8355 {0x39, 0x20, 0x20, 0, 0},
8356 {0x3A, 0x8, 0x8, 0, 0},
8357 {0x3B, 0x99, 0x99, 0, 0},
8358 {0x3C, 0, 0, 0, 0},
8359 {0x3D, 0x44, 0x44, 1, 1},
8360 {0x3E, 0, 0, 0, 0},
8361 {0x3F, 0x44, 0x44, 0, 0},
8362 {0x40, 0xf, 0xf, 1, 1},
8363 {0x41, 0x6, 0x6, 0, 0},
8364 {0x42, 0x4, 0x4, 0, 0},
8365 {0x43, 0x50, 0x50, 1, 1},
8366 {0x44, 0x8, 0x8, 0, 0},
8367 {0x45, 0x99, 0x99, 0, 0},
8368 {0x46, 0, 0, 0, 0},
8369 {0x47, 0x11, 0x11, 0, 0},
8370 {0x48, 0, 0, 0, 0},
8371 {0x49, 0x44, 0x44, 0, 0},
8372 {0x4A, 0x7, 0x7, 0, 0},
8373 {0x4B, 0x6, 0x6, 0, 0},
8374 {0x4C, 0x4, 0x4, 0, 0},
8375 {0x4D, 0, 0, 0, 0},
8376 {0x4E, 0, 0, 0, 0},
8377 {0x4F, 0x66, 0x66, 0, 0},
8378 {0x50, 0x66, 0x66, 0, 0},
8379 {0x51, 0x57, 0x57, 0, 0},
8380 {0x52, 0x57, 0x57, 0, 0},
8381 {0x53, 0x44, 0x44, 0, 0},
8382 {0x54, 0, 0, 0, 0},
8383 {0x55, 0, 0, 0, 0},
8384 {0x56, 0x8, 0x8, 0, 0},
8385 {0x57, 0x8, 0x8, 0, 0},
8386 {0x58, 0x7, 0x7, 0, 0},
8387 {0x59, 0x22, 0x22, 0, 0},
8388 {0x5A, 0x22, 0x22, 0, 0},
8389 {0x5B, 0x2, 0x2, 0, 0},
8390 {0x5C, 0x23, 0x23, 0, 0},
8391 {0x5D, 0x7, 0x7, 0, 0},
8392 {0x5E, 0x55, 0x55, 0, 0},
8393 {0x5F, 0x23, 0x23, 0, 0},
8394 {0x60, 0x41, 0x41, 0, 0},
8395 {0x61, 0x1, 0x1, 0, 0},
8396 {0x62, 0xa, 0xa, 0, 0},
8397 {0x63, 0, 0, 0, 0},
8398 {0x64, 0, 0, 0, 0},
8399 {0x65, 0, 0, 0, 0},
8400 {0x66, 0, 0, 0, 0},
8401 {0x67, 0, 0, 0, 0},
8402 {0x68, 0, 0, 0, 0},
8403 {0x69, 0, 0, 0, 0},
8404 {0x6A, 0, 0, 0, 0},
8405 {0x6B, 0xc, 0xc, 0, 0},
8406 {0x6C, 0, 0, 0, 0},
8407 {0x6D, 0, 0, 0, 0},
8408 {0x6E, 0, 0, 0, 0},
8409 {0x6F, 0, 0, 0, 0},
8410 {0x70, 0, 0, 0, 0},
8411 {0x71, 0, 0, 0, 0},
8412 {0x72, 0x22, 0x22, 0, 0},
8413 {0x73, 0x22, 0x22, 0, 0},
8414 {0x74, 0x2, 0x2, 0, 0},
8415 {0x75, 0xa, 0xa, 0, 0},
8416 {0x76, 0x1, 0x1, 0, 0},
8417 {0x77, 0x22, 0x22, 0, 0},
8418 {0x78, 0x30, 0x30, 0, 0},
8419 {0x79, 0, 0, 0, 0},
8420 {0x7A, 0, 0, 0, 0},
8421 {0x7B, 0, 0, 0, 0},
8422 {0x7C, 0, 0, 0, 0},
8423 {0x7D, 0, 0, 0, 0},
8424 {0x7E, 0, 0, 0, 0},
8425 {0x7F, 0, 0, 0, 0},
8426 {0x80, 0, 0, 0, 0},
8427 {0x81, 0, 0, 0, 0},
8428 {0x82, 0, 0, 0, 0},
8429 {0x83, 0, 0, 0, 0},
8430 {0x84, 0, 0, 0, 0},
8431 {0x85, 0, 0, 0, 0},
8432 {0x86, 0, 0, 0, 0},
8433 {0x87, 0, 0, 0, 0},
8434 {0x88, 0, 0, 0, 0},
8435 {0x89, 0, 0, 0, 0},
8436 {0x8A, 0, 0, 0, 0},
8437 {0x8B, 0, 0, 0, 0},
8438 {0x8C, 0, 0, 0, 0},
8439 {0x8D, 0, 0, 0, 0},
8440 {0x8E, 0, 0, 0, 0},
8441 {0x8F, 0, 0, 0, 0},
8442 {0x90, 0, 0, 0, 0},
8443 {0x91, 0, 0, 0, 0},
8444 {0x92, 0, 0, 0, 0},
8445 {0x93, 0, 0, 0, 0},
8446 {0x94, 0, 0, 0, 0},
8447 {0xFFFF, 0, 0, 0, 0}
8448};
8449
8450struct radio_regs regs_SYN_2056_A1[] = {
8451 {0x02, 0, 0, 0, 0},
8452 {0x03, 0, 0, 0, 0},
8453 {0x04, 0, 0, 0, 0},
8454 {0x05, 0, 0, 0, 0},
8455 {0x06, 0, 0, 0, 0},
8456 {0x07, 0, 0, 0, 0},
8457 {0x08, 0, 0, 0, 0},
8458 {0x09, 0x1, 0x1, 0, 0},
8459 {0x0A, 0, 0, 0, 0},
8460 {0x0B, 0, 0, 0, 0},
8461 {0x0C, 0, 0, 0, 0},
8462 {0x0D, 0, 0, 0, 0},
8463 {0x0E, 0, 0, 0, 0},
8464 {0x0F, 0, 0, 0, 0},
8465 {0x10, 0, 0, 0, 0},
8466 {0x11, 0, 0, 0, 0},
8467 {0x12, 0, 0, 0, 0},
8468 {0x13, 0, 0, 0, 0},
8469 {0x14, 0, 0, 0, 0},
8470 {0x15, 0, 0, 0, 0},
8471 {0x16, 0, 0, 0, 0},
8472 {0x17, 0, 0, 0, 0},
8473 {0x18, 0, 0, 0, 0},
8474 {0x19, 0, 0, 0, 0},
8475 {0x1A, 0, 0, 0, 0},
8476 {0x1B, 0, 0, 0, 0},
8477 {0x1C, 0, 0, 0, 0},
8478 {0x1D, 0, 0, 0, 0},
8479 {0x1E, 0, 0, 0, 0},
8480 {0x1F, 0, 0, 0, 0},
8481 {0x20, 0, 0, 0, 0},
8482 {0x21, 0, 0, 0, 0},
8483 {0x22, 0x60, 0x60, 0, 0},
8484 {0x23, 0x6, 0x6, 0, 0},
8485 {0x24, 0xc, 0xc, 0, 0},
8486 {0x25, 0, 0, 0, 0},
8487 {0x26, 0, 0, 0, 0},
8488 {0x27, 0, 0, 0, 0},
8489 {0x28, 0x1, 0x1, 0, 0},
8490 {0x29, 0, 0, 0, 0},
8491 {0x2A, 0, 0, 0, 0},
8492 {0x2B, 0, 0, 0, 0},
8493 {0x2C, 0, 0, 0, 0},
8494 {0x2D, 0, 0, 0, 0},
8495 {0x2E, 0xd, 0xd, 0, 0},
8496 {0x2F, 0x1f, 0x1f, 0, 0},
8497 {0x30, 0x15, 0x15, 0, 0},
8498 {0x31, 0xf, 0xf, 0, 0},
8499 {0x32, 0, 0, 0, 0},
8500 {0x33, 0, 0, 0, 0},
8501 {0x34, 0, 0, 0, 0},
8502 {0x35, 0, 0, 0, 0},
8503 {0x36, 0, 0, 0, 0},
8504 {0x37, 0, 0, 0, 0},
8505 {0x38, 0, 0, 0, 0},
8506 {0x39, 0, 0, 0, 0},
8507 {0x3A, 0, 0, 0, 0},
8508 {0x3B, 0, 0, 0, 0},
8509 {0x3C, 0x13, 0x13, 0, 0},
8510 {0x3D, 0xf, 0xf, 0, 0},
8511 {0x3E, 0x18, 0x18, 0, 0},
8512 {0x3F, 0, 0, 0, 0},
8513 {0x40, 0, 0, 0, 0},
8514 {0x41, 0x20, 0x20, 0, 0},
8515 {0x42, 0x20, 0x20, 0, 0},
8516 {0x43, 0, 0, 0, 0},
8517 {0x44, 0x77, 0x77, 0, 0},
8518 {0x45, 0x7, 0x7, 0, 0},
8519 {0x46, 0x1, 0x1, 0, 0},
8520 {0x47, 0x4, 0x4, 0, 0},
8521 {0x48, 0xf, 0xf, 0, 0},
8522 {0x49, 0x30, 0x30, 0, 0},
8523 {0x4A, 0x32, 0x32, 0, 0},
8524 {0x4B, 0xd, 0xd, 0, 0},
8525 {0x4C, 0xd, 0xd, 0, 0},
8526 {0x4D, 0x4, 0x4, 0, 0},
8527 {0x4E, 0x6, 0x6, 0, 0},
8528 {0x4F, 0x1, 0x1, 0, 0},
8529 {0x50, 0x1c, 0x1c, 0, 0},
8530 {0x51, 0x2, 0x2, 0, 0},
8531 {0x52, 0x2, 0x2, 0, 0},
8532 {0x53, 0xf7, 0xf7, 1, 1},
8533 {0x54, 0xb4, 0xb4, 0, 0},
8534 {0x55, 0xd2, 0xd2, 0, 0},
8535 {0x56, 0, 0, 0, 0},
8536 {0x57, 0, 0, 0, 0},
8537 {0x58, 0x4, 0x4, 0, 0},
8538 {0x59, 0x96, 0x96, 0, 0},
8539 {0x5A, 0x3e, 0x3e, 0, 0},
8540 {0x5B, 0x3e, 0x3e, 0, 0},
8541 {0x5C, 0x13, 0x13, 0, 0},
8542 {0x5D, 0x2, 0x2, 0, 0},
8543 {0x5E, 0, 0, 0, 0},
8544 {0x5F, 0x7, 0x7, 0, 0},
8545 {0x60, 0x7, 0x7, 1, 1},
8546 {0x61, 0x8, 0x8, 0, 0},
8547 {0x62, 0x3, 0x3, 0, 0},
8548 {0x63, 0, 0, 0, 0},
8549 {0x64, 0, 0, 0, 0},
8550 {0x65, 0, 0, 0, 0},
8551 {0x66, 0, 0, 0, 0},
8552 {0x67, 0, 0, 0, 0},
8553 {0x68, 0x40, 0x40, 0, 0},
8554 {0x69, 0, 0, 0, 0},
8555 {0x6A, 0, 0, 0, 0},
8556 {0x6B, 0, 0, 0, 0},
8557 {0x6C, 0, 0, 0, 0},
8558 {0x6D, 0x1, 0x1, 0, 0},
8559 {0x6E, 0, 0, 0, 0},
8560 {0x6F, 0, 0, 0, 0},
8561 {0x70, 0x60, 0x60, 0, 0},
8562 {0x71, 0x66, 0x66, 0, 0},
8563 {0x72, 0xc, 0xc, 0, 0},
8564 {0x73, 0x66, 0x66, 0, 0},
8565 {0x74, 0x8f, 0x8f, 1, 1},
8566 {0x75, 0, 0, 0, 0},
8567 {0x76, 0xcc, 0xcc, 0, 0},
8568 {0x77, 0x1, 0x1, 0, 0},
8569 {0x78, 0x66, 0x66, 0, 0},
8570 {0x79, 0x66, 0x66, 0, 0},
8571 {0x7A, 0, 0, 0, 0},
8572 {0x7B, 0, 0, 0, 0},
8573 {0x7C, 0, 0, 0, 0},
8574 {0x7D, 0, 0, 0, 0},
8575 {0x7E, 0, 0, 0, 0},
8576 {0x7F, 0, 0, 0, 0},
8577 {0x80, 0, 0, 0, 0},
8578 {0x81, 0, 0, 0, 0},
8579 {0x82, 0, 0, 0, 0},
8580 {0x83, 0, 0, 0, 0},
8581 {0x84, 0, 0, 0, 0},
8582 {0x85, 0xff, 0xff, 0, 0},
8583 {0x86, 0, 0, 0, 0},
8584 {0x87, 0, 0, 0, 0},
8585 {0x88, 0, 0, 0, 0},
8586 {0x89, 0, 0, 0, 0},
8587 {0x8A, 0, 0, 0, 0},
8588 {0x8B, 0, 0, 0, 0},
8589 {0x8C, 0, 0, 0, 0},
8590 {0x8D, 0, 0, 0, 0},
8591 {0x8E, 0, 0, 0, 0},
8592 {0x8F, 0, 0, 0, 0},
8593 {0x90, 0, 0, 0, 0},
8594 {0x91, 0, 0, 0, 0},
8595 {0x92, 0, 0, 0, 0},
8596 {0x93, 0, 0, 0, 0},
8597 {0x94, 0, 0, 0, 0},
8598 {0x95, 0, 0, 0, 0},
8599 {0x96, 0, 0, 0, 0},
8600 {0x97, 0, 0, 0, 0},
8601 {0x98, 0, 0, 0, 0},
8602 {0x99, 0, 0, 0, 0},
8603 {0x9A, 0, 0, 0, 0},
8604 {0x9B, 0, 0, 0, 0},
8605 {0x9C, 0, 0, 0, 0},
8606 {0x9D, 0, 0, 0, 0},
8607 {0x9E, 0, 0, 0, 0},
8608 {0x9F, 0x6, 0x6, 0, 0},
8609 {0xA0, 0x66, 0x66, 0, 0},
8610 {0xA1, 0x66, 0x66, 0, 0},
8611 {0xA2, 0x66, 0x66, 0, 0},
8612 {0xA3, 0x66, 0x66, 0, 0},
8613 {0xA4, 0x66, 0x66, 0, 0},
8614 {0xA5, 0x66, 0x66, 0, 0},
8615 {0xA6, 0x66, 0x66, 0, 0},
8616 {0xA7, 0x66, 0x66, 0, 0},
8617 {0xA8, 0x66, 0x66, 0, 0},
8618 {0xA9, 0x66, 0x66, 0, 0},
8619 {0xAA, 0x66, 0x66, 0, 0},
8620 {0xAB, 0x66, 0x66, 0, 0},
8621 {0xAC, 0x66, 0x66, 0, 0},
8622 {0xAD, 0x66, 0x66, 0, 0},
8623 {0xAE, 0x66, 0x66, 0, 0},
8624 {0xAF, 0x66, 0x66, 0, 0},
8625 {0xB0, 0x66, 0x66, 0, 0},
8626 {0xB1, 0x66, 0x66, 0, 0},
8627 {0xB2, 0x66, 0x66, 0, 0},
8628 {0xB3, 0xa, 0xa, 0, 0},
8629 {0xB4, 0, 0, 0, 0},
8630 {0xB5, 0, 0, 0, 0},
8631 {0xB6, 0, 0, 0, 0},
8632 {0xFFFF, 0, 0, 0, 0}
8633};
8634
8635struct radio_regs regs_TX_2056_A1[] = {
8636 {0x02, 0, 0, 0, 0},
8637 {0x03, 0, 0, 0, 0},
8638 {0x04, 0, 0, 0, 0},
8639 {0x05, 0, 0, 0, 0},
8640 {0x06, 0, 0, 0, 0},
8641 {0x07, 0, 0, 0, 0},
8642 {0x08, 0, 0, 0, 0},
8643 {0x09, 0, 0, 0, 0},
8644 {0x0A, 0, 0, 0, 0},
8645 {0x0B, 0, 0, 0, 0},
8646 {0x0C, 0, 0, 0, 0},
8647 {0x0D, 0, 0, 0, 0},
8648 {0x0E, 0, 0, 0, 0},
8649 {0x0F, 0, 0, 0, 0},
8650 {0x10, 0, 0, 0, 0},
8651 {0x11, 0, 0, 0, 0},
8652 {0x12, 0, 0, 0, 0},
8653 {0x13, 0, 0, 0, 0},
8654 {0x14, 0, 0, 0, 0},
8655 {0x15, 0, 0, 0, 0},
8656 {0x16, 0, 0, 0, 0},
8657 {0x17, 0, 0, 0, 0},
8658 {0x18, 0, 0, 0, 0},
8659 {0x19, 0, 0, 0, 0},
8660 {0x1A, 0, 0, 0, 0},
8661 {0x1B, 0, 0, 0, 0},
8662 {0x1C, 0, 0, 0, 0},
8663 {0x1D, 0, 0, 0, 0},
8664 {0x1E, 0, 0, 0, 0},
8665 {0x1F, 0, 0, 0, 0},
8666 {0x20, 0, 0, 0, 0},
8667 {0x21, 0x88, 0x88, 0, 0},
8668 {0x22, 0x88, 0x88, 0, 0},
8669 {0x23, 0x88, 0x88, 0, 0},
8670 {0x24, 0x88, 0x88, 0, 0},
8671 {0x25, 0xc, 0xc, 0, 0},
8672 {0x26, 0, 0, 0, 0},
8673 {0x27, 0x3, 0x3, 0, 0},
8674 {0x28, 0, 0, 0, 0},
8675 {0x29, 0x3, 0x3, 0, 0},
8676 {0x2A, 0x37, 0x37, 0, 0},
8677 {0x2B, 0x3, 0x3, 0, 0},
8678 {0x2C, 0, 0, 0, 0},
8679 {0x2D, 0, 0, 0, 0},
8680 {0x2E, 0x1, 0x1, 0, 0},
8681 {0x2F, 0x1, 0x1, 0, 0},
8682 {0x30, 0, 0, 0, 0},
8683 {0x31, 0, 0, 0, 0},
8684 {0x32, 0, 0, 0, 0},
8685 {0x33, 0x11, 0x11, 0, 0},
8686 {0x34, 0x11, 0x11, 0, 0},
8687 {0x35, 0, 0, 0, 0},
8688 {0x36, 0, 0, 0, 0},
8689 {0x37, 0x3, 0x3, 0, 0},
8690 {0x38, 0xf, 0xf, 0, 0},
8691 {0x39, 0, 0, 0, 0},
8692 {0x3A, 0x2d, 0x2d, 0, 0},
8693 {0x3B, 0, 0, 0, 0},
8694 {0x3C, 0x6e, 0x6e, 0, 0},
8695 {0x3D, 0xf0, 0xf0, 1, 1},
8696 {0x3E, 0, 0, 0, 0},
8697 {0x3F, 0, 0, 0, 0},
8698 {0x40, 0, 0, 0, 0},
8699 {0x41, 0x3, 0x3, 0, 0},
8700 {0x42, 0x3, 0x3, 0, 0},
8701 {0x43, 0, 0, 0, 0},
8702 {0x44, 0x1e, 0x1e, 0, 0},
8703 {0x45, 0, 0, 0, 0},
8704 {0x46, 0x6e, 0x6e, 0, 0},
8705 {0x47, 0xf0, 0xf0, 1, 1},
8706 {0x48, 0, 0, 0, 0},
8707 {0x49, 0x2, 0x2, 0, 0},
8708 {0x4A, 0xff, 0xff, 1, 1},
8709 {0x4B, 0xc, 0xc, 0, 0},
8710 {0x4C, 0, 0, 0, 0},
8711 {0x4D, 0x38, 0x38, 0, 0},
8712 {0x4E, 0x70, 0x70, 1, 1},
8713 {0x4F, 0x2, 0x2, 0, 0},
8714 {0x50, 0x88, 0x88, 0, 0},
8715 {0x51, 0xc, 0xc, 0, 0},
8716 {0x52, 0, 0, 0, 0},
8717 {0x53, 0x8, 0x8, 0, 0},
8718 {0x54, 0x70, 0x70, 1, 1},
8719 {0x55, 0x2, 0x2, 0, 0},
8720 {0x56, 0xff, 0xff, 1, 1},
8721 {0x57, 0, 0, 0, 0},
8722 {0x58, 0x83, 0x83, 0, 0},
8723 {0x59, 0x77, 0x77, 1, 1},
8724 {0x5A, 0, 0, 0, 0},
8725 {0x5B, 0x2, 0x2, 0, 0},
8726 {0x5C, 0x88, 0x88, 0, 0},
8727 {0x5D, 0, 0, 0, 0},
8728 {0x5E, 0x8, 0x8, 0, 0},
8729 {0x5F, 0x77, 0x77, 1, 1},
8730 {0x60, 0x1, 0x1, 0, 0},
8731 {0x61, 0, 0, 0, 0},
8732 {0x62, 0x7, 0x7, 0, 0},
8733 {0x63, 0, 0, 0, 0},
8734 {0x64, 0x7, 0x7, 0, 0},
8735 {0x65, 0, 0, 0, 0},
8736 {0x66, 0, 0, 0, 0},
8737 {0x67, 0x72, 0x72, 1, 1},
8738 {0x68, 0, 0, 0, 0},
8739 {0x69, 0xa, 0xa, 0, 0},
8740 {0x6A, 0, 0, 0, 0},
8741 {0x6B, 0, 0, 0, 0},
8742 {0x6C, 0, 0, 0, 0},
8743 {0x6D, 0, 0, 0, 0},
8744 {0x6E, 0, 0, 0, 0},
8745 {0x6F, 0, 0, 0, 0},
8746 {0x70, 0, 0, 0, 0},
8747 {0x71, 0x2, 0x2, 0, 0},
8748 {0x72, 0, 0, 0, 0},
8749 {0x73, 0, 0, 0, 0},
8750 {0x74, 0xe, 0xe, 0, 0},
8751 {0x75, 0xe, 0xe, 0, 0},
8752 {0x76, 0xe, 0xe, 0, 0},
8753 {0x77, 0x13, 0x13, 0, 0},
8754 {0x78, 0x13, 0x13, 0, 0},
8755 {0x79, 0x1b, 0x1b, 0, 0},
8756 {0x7A, 0x1b, 0x1b, 0, 0},
8757 {0x7B, 0x55, 0x55, 0, 0},
8758 {0x7C, 0x5b, 0x5b, 0, 0},
8759 {0x7D, 0, 0, 0, 0},
8760 {0x7E, 0, 0, 0, 0},
8761 {0x7F, 0, 0, 0, 0},
8762 {0x80, 0, 0, 0, 0},
8763 {0x81, 0, 0, 0, 0},
8764 {0x82, 0, 0, 0, 0},
8765 {0x83, 0, 0, 0, 0},
8766 {0x84, 0, 0, 0, 0},
8767 {0x85, 0, 0, 0, 0},
8768 {0x86, 0, 0, 0, 0},
8769 {0x87, 0, 0, 0, 0},
8770 {0x88, 0, 0, 0, 0},
8771 {0x89, 0, 0, 0, 0},
8772 {0x8A, 0, 0, 0, 0},
8773 {0x8B, 0, 0, 0, 0},
8774 {0x8C, 0, 0, 0, 0},
8775 {0x8D, 0, 0, 0, 0},
8776 {0x8E, 0, 0, 0, 0},
8777 {0x8F, 0, 0, 0, 0},
8778 {0x90, 0, 0, 0, 0},
8779 {0x91, 0, 0, 0, 0},
8780 {0x92, 0, 0, 0, 0},
8781 {0xFFFF, 0, 0, 0, 0}
8782};
8783
8784struct radio_regs regs_RX_2056_A1[] = {
8785 {0x02, 0, 0, 0, 0},
8786 {0x03, 0, 0, 0, 0},
8787 {0x04, 0, 0, 0, 0},
8788 {0x05, 0, 0, 0, 0},
8789 {0x06, 0, 0, 0, 0},
8790 {0x07, 0, 0, 0, 0},
8791 {0x08, 0, 0, 0, 0},
8792 {0x09, 0, 0, 0, 0},
8793 {0x0A, 0, 0, 0, 0},
8794 {0x0B, 0, 0, 0, 0},
8795 {0x0C, 0, 0, 0, 0},
8796 {0x0D, 0, 0, 0, 0},
8797 {0x0E, 0, 0, 0, 0},
8798 {0x0F, 0, 0, 0, 0},
8799 {0x10, 0, 0, 0, 0},
8800 {0x11, 0, 0, 0, 0},
8801 {0x12, 0, 0, 0, 0},
8802 {0x13, 0, 0, 0, 0},
8803 {0x14, 0, 0, 0, 0},
8804 {0x15, 0, 0, 0, 0},
8805 {0x16, 0, 0, 0, 0},
8806 {0x17, 0, 0, 0, 0},
8807 {0x18, 0, 0, 0, 0},
8808 {0x19, 0, 0, 0, 0},
8809 {0x1A, 0, 0, 0, 0},
8810 {0x1B, 0, 0, 0, 0},
8811 {0x1C, 0, 0, 0, 0},
8812 {0x1D, 0, 0, 0, 0},
8813 {0x1E, 0, 0, 0, 0},
8814 {0x1F, 0, 0, 0, 0},
8815 {0x20, 0x3, 0x3, 0, 0},
8816 {0x21, 0, 0, 0, 0},
8817 {0x22, 0, 0, 0, 0},
8818 {0x23, 0x90, 0x90, 0, 0},
8819 {0x24, 0x55, 0x55, 0, 0},
8820 {0x25, 0x15, 0x15, 0, 0},
8821 {0x26, 0x5, 0x5, 0, 0},
8822 {0x27, 0x15, 0x15, 0, 0},
8823 {0x28, 0x5, 0x5, 0, 0},
8824 {0x29, 0x20, 0x20, 0, 0},
8825 {0x2A, 0x11, 0x11, 0, 0},
8826 {0x2B, 0x90, 0x90, 0, 0},
8827 {0x2C, 0, 0, 0, 0},
8828 {0x2D, 0x88, 0x88, 0, 0},
8829 {0x2E, 0x32, 0x32, 0, 0},
8830 {0x2F, 0x77, 0x77, 0, 0},
8831 {0x30, 0x17, 0x17, 1, 1},
8832 {0x31, 0xff, 0xff, 1, 1},
8833 {0x32, 0x20, 0x20, 0, 0},
8834 {0x33, 0, 0, 0, 0},
8835 {0x34, 0x88, 0x88, 0, 0},
8836 {0x35, 0x32, 0x32, 0, 0},
8837 {0x36, 0x77, 0x77, 0, 0},
8838 {0x37, 0x17, 0x17, 1, 1},
8839 {0x38, 0xf0, 0xf0, 1, 1},
8840 {0x39, 0x20, 0x20, 0, 0},
8841 {0x3A, 0x8, 0x8, 0, 0},
8842 {0x3B, 0x55, 0x55, 1, 1},
8843 {0x3C, 0, 0, 0, 0},
8844 {0x3D, 0x44, 0x44, 1, 1},
8845 {0x3E, 0, 0, 0, 0},
8846 {0x3F, 0x44, 0x44, 0, 0},
8847 {0x40, 0xf, 0xf, 1, 1},
8848 {0x41, 0x6, 0x6, 0, 0},
8849 {0x42, 0x4, 0x4, 0, 0},
8850 {0x43, 0x50, 0x50, 1, 1},
8851 {0x44, 0x8, 0x8, 0, 0},
8852 {0x45, 0x55, 0x55, 1, 1},
8853 {0x46, 0, 0, 0, 0},
8854 {0x47, 0x11, 0x11, 0, 0},
8855 {0x48, 0, 0, 0, 0},
8856 {0x49, 0x44, 0x44, 0, 0},
8857 {0x4A, 0x7, 0x7, 0, 0},
8858 {0x4B, 0x6, 0x6, 0, 0},
8859 {0x4C, 0x4, 0x4, 0, 0},
8860 {0x4D, 0, 0, 0, 0},
8861 {0x4E, 0, 0, 0, 0},
8862 {0x4F, 0x26, 0x26, 1, 1},
8863 {0x50, 0x26, 0x26, 1, 1},
8864 {0x51, 0xf, 0xf, 1, 1},
8865 {0x52, 0xf, 0xf, 1, 1},
8866 {0x53, 0x44, 0x44, 0, 0},
8867 {0x54, 0, 0, 0, 0},
8868 {0x55, 0, 0, 0, 0},
8869 {0x56, 0x8, 0x8, 0, 0},
8870 {0x57, 0x8, 0x8, 0, 0},
8871 {0x58, 0x7, 0x7, 0, 0},
8872 {0x59, 0x22, 0x22, 0, 0},
8873 {0x5A, 0x22, 0x22, 0, 0},
8874 {0x5B, 0x2, 0x2, 0, 0},
8875 {0x5C, 0x2f, 0x2f, 1, 1},
8876 {0x5D, 0x7, 0x7, 0, 0},
8877 {0x5E, 0x55, 0x55, 0, 0},
8878 {0x5F, 0x23, 0x23, 0, 0},
8879 {0x60, 0x41, 0x41, 0, 0},
8880 {0x61, 0x1, 0x1, 0, 0},
8881 {0x62, 0xa, 0xa, 0, 0},
8882 {0x63, 0, 0, 0, 0},
8883 {0x64, 0, 0, 0, 0},
8884 {0x65, 0, 0, 0, 0},
8885 {0x66, 0, 0, 0, 0},
8886 {0x67, 0, 0, 0, 0},
8887 {0x68, 0, 0, 0, 0},
8888 {0x69, 0, 0, 0, 0},
8889 {0x6A, 0, 0, 0, 0},
8890 {0x6B, 0xc, 0xc, 0, 0},
8891 {0x6C, 0, 0, 0, 0},
8892 {0x6D, 0, 0, 0, 0},
8893 {0x6E, 0, 0, 0, 0},
8894 {0x6F, 0, 0, 0, 0},
8895 {0x70, 0, 0, 0, 0},
8896 {0x71, 0, 0, 0, 0},
8897 {0x72, 0x22, 0x22, 0, 0},
8898 {0x73, 0x22, 0x22, 0, 0},
8899 {0x74, 0, 0, 1, 1},
8900 {0x75, 0xa, 0xa, 0, 0},
8901 {0x76, 0x1, 0x1, 0, 0},
8902 {0x77, 0x22, 0x22, 0, 0},
8903 {0x78, 0x30, 0x30, 0, 0},
8904 {0x79, 0, 0, 0, 0},
8905 {0x7A, 0, 0, 0, 0},
8906 {0x7B, 0, 0, 0, 0},
8907 {0x7C, 0, 0, 0, 0},
8908 {0x7D, 0, 0, 0, 0},
8909 {0x7E, 0, 0, 0, 0},
8910 {0x7F, 0, 0, 0, 0},
8911 {0x80, 0, 0, 0, 0},
8912 {0x81, 0, 0, 0, 0},
8913 {0x82, 0, 0, 0, 0},
8914 {0x83, 0, 0, 0, 0},
8915 {0x84, 0, 0, 0, 0},
8916 {0x85, 0, 0, 0, 0},
8917 {0x86, 0, 0, 0, 0},
8918 {0x87, 0, 0, 0, 0},
8919 {0x88, 0, 0, 0, 0},
8920 {0x89, 0, 0, 0, 0},
8921 {0x8A, 0, 0, 0, 0},
8922 {0x8B, 0, 0, 0, 0},
8923 {0x8C, 0, 0, 0, 0},
8924 {0x8D, 0, 0, 0, 0},
8925 {0x8E, 0, 0, 0, 0},
8926 {0x8F, 0, 0, 0, 0},
8927 {0x90, 0, 0, 0, 0},
8928 {0x91, 0, 0, 0, 0},
8929 {0x92, 0, 0, 0, 0},
8930 {0x93, 0, 0, 0, 0},
8931 {0x94, 0, 0, 0, 0},
8932 {0xFFFF, 0, 0, 0, 0}
8933};
8934
8935struct radio_regs regs_SYN_2056_rev5[] = {
8936 {0x02, 0, 0, 0, 0},
8937 {0x03, 0, 0, 0, 0},
8938 {0x04, 0, 0, 0, 0},
8939 {0x05, 0, 0, 0, 0},
8940 {0x06, 0, 0, 0, 0},
8941 {0x07, 0, 0, 0, 0},
8942 {0x08, 0, 0, 0, 0},
8943 {0x09, 0x1, 0x1, 0, 0},
8944 {0x0A, 0, 0, 0, 0},
8945 {0x0B, 0, 0, 0, 0},
8946 {0x0C, 0, 0, 0, 0},
8947 {0x0D, 0, 0, 0, 0},
8948 {0x0E, 0, 0, 0, 0},
8949 {0x0F, 0, 0, 0, 0},
8950 {0x10, 0, 0, 0, 0},
8951 {0x11, 0, 0, 0, 0},
8952 {0x12, 0, 0, 0, 0},
8953 {0x13, 0, 0, 0, 0},
8954 {0x14, 0, 0, 0, 0},
8955 {0x15, 0, 0, 0, 0},
8956 {0x16, 0, 0, 0, 0},
8957 {0x17, 0, 0, 0, 0},
8958 {0x18, 0, 0, 0, 0},
8959 {0x19, 0, 0, 0, 0},
8960 {0x1A, 0, 0, 0, 0},
8961 {0x1B, 0, 0, 0, 0},
8962 {0x1C, 0, 0, 0, 0},
8963 {0x1D, 0, 0, 0, 0},
8964 {0x1E, 0, 0, 0, 0},
8965 {0x1F, 0, 0, 0, 0},
8966 {0x20, 0, 0, 0, 0},
8967 {0x21, 0, 0, 0, 0},
8968 {0x22, 0x60, 0x60, 0, 0},
8969 {0x23, 0x6, 0x6, 0, 0},
8970 {0x24, 0xc, 0xc, 0, 0},
8971 {0x25, 0, 0, 0, 0},
8972 {0x26, 0, 0, 0, 0},
8973 {0x27, 0, 0, 0, 0},
8974 {0x28, 0x1, 0x1, 0, 0},
8975 {0x29, 0, 0, 0, 0},
8976 {0x2A, 0, 0, 0, 0},
8977 {0x2B, 0, 0, 0, 0},
8978 {0x2C, 0, 0, 0, 0},
8979 {0x2D, 0, 0, 0, 0},
8980 {0x2E, 0, 0, 0, 0},
8981 {0x2F, 0x1f, 0x1f, 0, 0},
8982 {0x30, 0x15, 0x15, 0, 0},
8983 {0x31, 0xf, 0xf, 0, 0},
8984 {0x32, 0, 0, 0, 0},
8985 {0x33, 0, 0, 0, 0},
8986 {0x34, 0, 0, 0, 0},
8987 {0x35, 0, 0, 0, 0},
8988 {0x36, 0, 0, 0, 0},
8989 {0x37, 0, 0, 0, 0},
8990 {0x38, 0, 0, 0, 0},
8991 {0x39, 0, 0, 0, 0},
8992 {0x3A, 0, 0, 0, 0},
8993 {0x3B, 0, 0, 0, 0},
8994 {0x3C, 0x13, 0x13, 0, 0},
8995 {0x3D, 0xf, 0xf, 0, 0},
8996 {0x3E, 0x18, 0x18, 0, 0},
8997 {0x3F, 0, 0, 0, 0},
8998 {0x40, 0, 0, 0, 0},
8999 {0x41, 0x20, 0x20, 0, 0},
9000 {0x42, 0x20, 0x20, 0, 0},
9001 {0x43, 0, 0, 0, 0},
9002 {0x44, 0x77, 0x77, 0, 0},
9003 {0x45, 0x7, 0x7, 0, 0},
9004 {0x46, 0x1, 0x1, 0, 0},
9005 {0x47, 0x4, 0x4, 0, 0},
9006 {0x48, 0xf, 0xf, 0, 0},
9007 {0x49, 0x30, 0x30, 0, 0},
9008 {0x4A, 0x32, 0x32, 0, 0},
9009 {0x4B, 0xd, 0xd, 0, 0},
9010 {0x4C, 0xd, 0xd, 0, 0},
9011 {0x4D, 0x4, 0x4, 0, 0},
9012 {0x4E, 0x6, 0x6, 0, 0},
9013 {0x4F, 0x1, 0x1, 0, 0},
9014 {0x50, 0x1c, 0x1c, 0, 0},
9015 {0x51, 0x2, 0x2, 0, 0},
9016 {0x52, 0x2, 0x2, 0, 0},
9017 {0x53, 0xf7, 0xf7, 1, 1},
9018 {0x54, 0xb4, 0xb4, 0, 0},
9019 {0x55, 0xd2, 0xd2, 0, 0},
9020 {0x56, 0, 0, 0, 0},
9021 {0x57, 0, 0, 0, 0},
9022 {0x58, 0x4, 0x4, 0, 0},
9023 {0x59, 0x96, 0x96, 0, 0},
9024 {0x5A, 0x3e, 0x3e, 0, 0},
9025 {0x5B, 0x3e, 0x3e, 0, 0},
9026 {0x5C, 0x13, 0x13, 0, 0},
9027 {0x5D, 0x2, 0x2, 0, 0},
9028 {0x5E, 0, 0, 0, 0},
9029 {0x5F, 0x7, 0x7, 0, 0},
9030 {0x60, 0x7, 0x7, 1, 1},
9031 {0x61, 0x8, 0x8, 0, 0},
9032 {0x62, 0x3, 0x3, 0, 0},
9033 {0x63, 0, 0, 0, 0},
9034 {0x64, 0, 0, 0, 0},
9035 {0x65, 0, 0, 0, 0},
9036 {0x66, 0, 0, 0, 0},
9037 {0x67, 0, 0, 0, 0},
9038 {0x68, 0x40, 0x40, 0, 0},
9039 {0x69, 0, 0, 0, 0},
9040 {0x6A, 0, 0, 0, 0},
9041 {0x6B, 0, 0, 0, 0},
9042 {0x6C, 0, 0, 0, 0},
9043 {0x6D, 0x1, 0x1, 0, 0},
9044 {0x6E, 0, 0, 0, 0},
9045 {0x6F, 0, 0, 0, 0},
9046 {0x70, 0x60, 0x60, 0, 0},
9047 {0x71, 0x66, 0x66, 0, 0},
9048 {0x72, 0xc, 0xc, 0, 0},
9049 {0x73, 0x66, 0x66, 0, 0},
9050 {0x74, 0x8f, 0x8f, 1, 1},
9051 {0x75, 0, 0, 0, 0},
9052 {0x76, 0xcc, 0xcc, 0, 0},
9053 {0x77, 0x1, 0x1, 0, 0},
9054 {0x78, 0x66, 0x66, 0, 0},
9055 {0x79, 0x66, 0x66, 0, 0},
9056 {0x7A, 0, 0, 0, 0},
9057 {0x7B, 0, 0, 0, 0},
9058 {0x7C, 0, 0, 0, 0},
9059 {0x7D, 0, 0, 0, 0},
9060 {0x7E, 0, 0, 0, 0},
9061 {0x7F, 0, 0, 0, 0},
9062 {0x80, 0, 0, 0, 0},
9063 {0x81, 0, 0, 0, 0},
9064 {0x82, 0, 0, 0, 0},
9065 {0x83, 0, 0, 0, 0},
9066 {0x84, 0, 0, 0, 0},
9067 {0x85, 0xff, 0xff, 0, 0},
9068 {0x86, 0, 0, 0, 0},
9069 {0x87, 0, 0, 0, 0},
9070 {0x88, 0, 0, 0, 0},
9071 {0x89, 0, 0, 0, 0},
9072 {0x8A, 0, 0, 0, 0},
9073 {0x8B, 0, 0, 0, 0},
9074 {0x8C, 0, 0, 0, 0},
9075 {0x8D, 0, 0, 0, 0},
9076 {0x8E, 0, 0, 0, 0},
9077 {0x8F, 0, 0, 0, 0},
9078 {0x90, 0, 0, 0, 0},
9079 {0x91, 0, 0, 0, 0},
9080 {0x92, 0, 0, 0, 0},
9081 {0x93, 0, 0, 0, 0},
9082 {0x94, 0, 0, 0, 0},
9083 {0x95, 0, 0, 0, 0},
9084 {0x96, 0, 0, 0, 0},
9085 {0x97, 0, 0, 0, 0},
9086 {0x98, 0, 0, 0, 0},
9087 {0x99, 0, 0, 0, 0},
9088 {0x9A, 0, 0, 0, 0},
9089 {0x9B, 0, 0, 0, 0},
9090 {0x9C, 0, 0, 0, 0},
9091 {0x9D, 0, 0, 0, 0},
9092 {0x9E, 0, 0, 0, 0},
9093 {0x9F, 0x6, 0x6, 0, 0},
9094 {0xA0, 0x66, 0x66, 0, 0},
9095 {0xA1, 0x66, 0x66, 0, 0},
9096 {0xA2, 0x66, 0x66, 0, 0},
9097 {0xA3, 0x66, 0x66, 0, 0},
9098 {0xA4, 0x66, 0x66, 0, 0},
9099 {0xA5, 0x66, 0x66, 0, 0},
9100 {0xA6, 0x66, 0x66, 0, 0},
9101 {0xA7, 0x66, 0x66, 0, 0},
9102 {0xA8, 0x66, 0x66, 0, 0},
9103 {0xA9, 0x66, 0x66, 0, 0},
9104 {0xAA, 0x66, 0x66, 0, 0},
9105 {0xAB, 0x66, 0x66, 0, 0},
9106 {0xAC, 0x66, 0x66, 0, 0},
9107 {0xAD, 0x66, 0x66, 0, 0},
9108 {0xAE, 0x66, 0x66, 0, 0},
9109 {0xAF, 0x66, 0x66, 0, 0},
9110 {0xB0, 0x66, 0x66, 0, 0},
9111 {0xB1, 0x66, 0x66, 0, 0},
9112 {0xB2, 0x66, 0x66, 0, 0},
9113 {0xB3, 0xa, 0xa, 0, 0},
9114 {0xB4, 0, 0, 0, 0},
9115 {0xB5, 0, 0, 0, 0},
9116 {0xB6, 0, 0, 0, 0},
9117 {0xFFFF, 0, 0, 0, 0}
9118};
9119
9120struct radio_regs regs_TX_2056_rev5[] = {
9121 {0x02, 0, 0, 0, 0},
9122 {0x03, 0, 0, 0, 0},
9123 {0x04, 0, 0, 0, 0},
9124 {0x05, 0, 0, 0, 0},
9125 {0x06, 0, 0, 0, 0},
9126 {0x07, 0, 0, 0, 0},
9127 {0x08, 0, 0, 0, 0},
9128 {0x09, 0, 0, 0, 0},
9129 {0x0A, 0, 0, 0, 0},
9130 {0x0B, 0, 0, 0, 0},
9131 {0x0C, 0, 0, 0, 0},
9132 {0x0D, 0, 0, 0, 0},
9133 {0x0E, 0, 0, 0, 0},
9134 {0x0F, 0, 0, 0, 0},
9135 {0x10, 0, 0, 0, 0},
9136 {0x11, 0, 0, 0, 0},
9137 {0x12, 0, 0, 0, 0},
9138 {0x13, 0, 0, 0, 0},
9139 {0x14, 0, 0, 0, 0},
9140 {0x15, 0, 0, 0, 0},
9141 {0x16, 0, 0, 0, 0},
9142 {0x17, 0, 0, 0, 0},
9143 {0x18, 0, 0, 0, 0},
9144 {0x19, 0, 0, 0, 0},
9145 {0x1A, 0, 0, 0, 0},
9146 {0x1B, 0, 0, 0, 0},
9147 {0x1C, 0, 0, 0, 0},
9148 {0x1D, 0, 0, 0, 0},
9149 {0x1E, 0, 0, 0, 0},
9150 {0x1F, 0, 0, 0, 0},
9151 {0x20, 0, 0, 0, 0},
9152 {0x21, 0x88, 0x88, 0, 0},
9153 {0x22, 0x88, 0x88, 0, 0},
9154 {0x23, 0x88, 0x88, 0, 0},
9155 {0x24, 0x88, 0x88, 0, 0},
9156 {0x25, 0xc, 0xc, 0, 0},
9157 {0x26, 0, 0, 0, 0},
9158 {0x27, 0x3, 0x3, 0, 0},
9159 {0x28, 0, 0, 0, 0},
9160 {0x29, 0x3, 0x3, 0, 0},
9161 {0x2A, 0x37, 0x37, 0, 0},
9162 {0x2B, 0x3, 0x3, 0, 0},
9163 {0x2C, 0, 0, 0, 0},
9164 {0x2D, 0, 0, 0, 0},
9165 {0x2E, 0x1, 0x1, 0, 0},
9166 {0x2F, 0x1, 0x1, 0, 0},
9167 {0x30, 0, 0, 0, 0},
9168 {0x31, 0, 0, 0, 0},
9169 {0x32, 0, 0, 0, 0},
9170 {0x33, 0x11, 0x11, 0, 0},
9171 {0x34, 0x11, 0x11, 0, 0},
9172 {0x35, 0, 0, 0, 0},
9173 {0x36, 0, 0, 0, 0},
9174 {0x37, 0x3, 0x3, 0, 0},
9175 {0x38, 0xf, 0xf, 0, 0},
9176 {0x39, 0, 0, 0, 0},
9177 {0x3A, 0x2d, 0x2d, 0, 0},
9178 {0x3B, 0, 0, 0, 0},
9179 {0x3C, 0x6e, 0x6e, 0, 0},
9180 {0x3D, 0xf0, 0xf0, 1, 1},
9181 {0x3E, 0, 0, 0, 0},
9182 {0x3F, 0, 0, 0, 0},
9183 {0x40, 0, 0, 0, 0},
9184 {0x41, 0x3, 0x3, 0, 0},
9185 {0x42, 0x3, 0x3, 0, 0},
9186 {0x43, 0, 0, 0, 0},
9187 {0x44, 0x1e, 0x1e, 0, 0},
9188 {0x45, 0, 0, 0, 0},
9189 {0x46, 0x6e, 0x6e, 0, 0},
9190 {0x47, 0xf0, 0xf0, 1, 1},
9191 {0x48, 0, 0, 0, 0},
9192 {0x49, 0x2, 0x2, 0, 0},
9193 {0x4A, 0xff, 0xff, 1, 1},
9194 {0x4B, 0xc, 0xc, 0, 0},
9195 {0x4C, 0, 0, 0, 0},
9196 {0x4D, 0x38, 0x38, 0, 0},
9197 {0x4E, 0x70, 0x70, 1, 1},
9198 {0x4F, 0x2, 0x2, 0, 0},
9199 {0x50, 0x88, 0x88, 0, 0},
9200 {0x51, 0xc, 0xc, 0, 0},
9201 {0x52, 0, 0, 0, 0},
9202 {0x53, 0x8, 0x8, 0, 0},
9203 {0x54, 0x70, 0x70, 1, 1},
9204 {0x55, 0x2, 0x2, 0, 0},
9205 {0x56, 0xff, 0xff, 1, 1},
9206 {0x57, 0, 0, 0, 0},
9207 {0x58, 0x83, 0x83, 0, 0},
9208 {0x59, 0x77, 0x77, 1, 1},
9209 {0x5A, 0, 0, 0, 0},
9210 {0x5B, 0x2, 0x2, 0, 0},
9211 {0x5C, 0x88, 0x88, 0, 0},
9212 {0x5D, 0, 0, 0, 0},
9213 {0x5E, 0x8, 0x8, 0, 0},
9214 {0x5F, 0x77, 0x77, 1, 1},
9215 {0x60, 0x1, 0x1, 0, 0},
9216 {0x61, 0, 0, 0, 0},
9217 {0x62, 0x7, 0x7, 0, 0},
9218 {0x63, 0, 0, 0, 0},
9219 {0x64, 0x7, 0x7, 0, 0},
9220 {0x65, 0, 0, 0, 0},
9221 {0x66, 0, 0, 0, 0},
9222 {0x67, 0, 0, 1, 1},
9223 {0x68, 0, 0, 0, 0},
9224 {0x69, 0xa, 0xa, 0, 0},
9225 {0x6A, 0, 0, 0, 0},
9226 {0x6B, 0, 0, 0, 0},
9227 {0x6C, 0, 0, 0, 0},
9228 {0x6D, 0, 0, 0, 0},
9229 {0x6E, 0, 0, 0, 0},
9230 {0x6F, 0, 0, 0, 0},
9231 {0x70, 0, 0, 0, 0},
9232 {0x71, 0x2, 0x2, 0, 0},
9233 {0x72, 0, 0, 0, 0},
9234 {0x73, 0, 0, 0, 0},
9235 {0x74, 0xe, 0xe, 0, 0},
9236 {0x75, 0xe, 0xe, 0, 0},
9237 {0x76, 0xe, 0xe, 0, 0},
9238 {0x77, 0x13, 0x13, 0, 0},
9239 {0x78, 0x13, 0x13, 0, 0},
9240 {0x79, 0x1b, 0x1b, 0, 0},
9241 {0x7A, 0x1b, 0x1b, 0, 0},
9242 {0x7B, 0x55, 0x55, 0, 0},
9243 {0x7C, 0x5b, 0x5b, 0, 0},
9244 {0x7D, 0, 0, 0, 0},
9245 {0x7E, 0, 0, 0, 0},
9246 {0x7F, 0, 0, 0, 0},
9247 {0x80, 0, 0, 0, 0},
9248 {0x81, 0, 0, 0, 0},
9249 {0x82, 0, 0, 0, 0},
9250 {0x83, 0, 0, 0, 0},
9251 {0x84, 0, 0, 0, 0},
9252 {0x85, 0, 0, 0, 0},
9253 {0x86, 0, 0, 0, 0},
9254 {0x87, 0, 0, 0, 0},
9255 {0x88, 0, 0, 0, 0},
9256 {0x89, 0, 0, 0, 0},
9257 {0x8A, 0, 0, 0, 0},
9258 {0x8B, 0, 0, 0, 0},
9259 {0x8C, 0, 0, 0, 0},
9260 {0x8D, 0, 0, 0, 0},
9261 {0x8E, 0, 0, 0, 0},
9262 {0x8F, 0, 0, 0, 0},
9263 {0x90, 0, 0, 0, 0},
9264 {0x91, 0, 0, 0, 0},
9265 {0x92, 0, 0, 0, 0},
9266 {0x93, 0x70, 0x70, 0, 0},
9267 {0x94, 0x70, 0x70, 0, 0},
9268 {0x95, 0x71, 0x71, 1, 1},
9269 {0x96, 0x71, 0x71, 1, 1},
9270 {0x97, 0x72, 0x72, 1, 1},
9271 {0x98, 0x73, 0x73, 1, 1},
9272 {0x99, 0x74, 0x74, 1, 1},
9273 {0x9A, 0x75, 0x75, 1, 1},
9274 {0xFFFF, 0, 0, 0, 0}
9275};
9276
9277struct radio_regs regs_RX_2056_rev5[] = {
9278 {0x02, 0, 0, 0, 0},
9279 {0x03, 0, 0, 0, 0},
9280 {0x04, 0, 0, 0, 0},
9281 {0x05, 0, 0, 0, 0},
9282 {0x06, 0, 0, 0, 0},
9283 {0x07, 0, 0, 0, 0},
9284 {0x08, 0, 0, 0, 0},
9285 {0x09, 0, 0, 0, 0},
9286 {0x0A, 0, 0, 0, 0},
9287 {0x0B, 0, 0, 0, 0},
9288 {0x0C, 0, 0, 0, 0},
9289 {0x0D, 0, 0, 0, 0},
9290 {0x0E, 0, 0, 0, 0},
9291 {0x0F, 0, 0, 0, 0},
9292 {0x10, 0, 0, 0, 0},
9293 {0x11, 0, 0, 0, 0},
9294 {0x12, 0, 0, 0, 0},
9295 {0x13, 0, 0, 0, 0},
9296 {0x14, 0, 0, 0, 0},
9297 {0x15, 0, 0, 0, 0},
9298 {0x16, 0, 0, 0, 0},
9299 {0x17, 0, 0, 0, 0},
9300 {0x18, 0, 0, 0, 0},
9301 {0x19, 0, 0, 0, 0},
9302 {0x1A, 0, 0, 0, 0},
9303 {0x1B, 0, 0, 0, 0},
9304 {0x1C, 0, 0, 0, 0},
9305 {0x1D, 0, 0, 0, 0},
9306 {0x1E, 0, 0, 0, 0},
9307 {0x1F, 0, 0, 0, 0},
9308 {0x20, 0x3, 0x3, 0, 0},
9309 {0x21, 0, 0, 0, 0},
9310 {0x22, 0, 0, 0, 0},
9311 {0x23, 0x90, 0x90, 0, 0},
9312 {0x24, 0x55, 0x55, 0, 0},
9313 {0x25, 0x15, 0x15, 0, 0},
9314 {0x26, 0x5, 0x5, 0, 0},
9315 {0x27, 0x15, 0x15, 0, 0},
9316 {0x28, 0x5, 0x5, 0, 0},
9317 {0x29, 0x20, 0x20, 0, 0},
9318 {0x2A, 0x11, 0x11, 0, 0},
9319 {0x2B, 0x90, 0x90, 0, 0},
9320 {0x2C, 0, 0, 0, 0},
9321 {0x2D, 0x88, 0x88, 0, 0},
9322 {0x2E, 0x32, 0x32, 0, 0},
9323 {0x2F, 0x77, 0x77, 0, 0},
9324 {0x30, 0x17, 0x17, 1, 1},
9325 {0x31, 0xff, 0xff, 1, 1},
9326 {0x32, 0x20, 0x20, 0, 0},
9327 {0x33, 0, 0, 0, 0},
9328 {0x34, 0x88, 0x88, 0, 0},
9329 {0x35, 0x32, 0x32, 0, 0},
9330 {0x36, 0x77, 0x77, 0, 0},
9331 {0x37, 0x17, 0x17, 1, 1},
9332 {0x38, 0xf0, 0xf0, 1, 1},
9333 {0x39, 0x20, 0x20, 0, 0},
9334 {0x3A, 0x8, 0x8, 0, 0},
9335 {0x3B, 0x55, 0x55, 1, 1},
9336 {0x3C, 0, 0, 0, 0},
9337 {0x3D, 0x88, 0x88, 1, 1},
9338 {0x3E, 0, 0, 0, 0},
9339 {0x3F, 0, 0, 1, 1},
9340 {0x40, 0x7, 0x7, 1, 1},
9341 {0x41, 0x6, 0x6, 0, 0},
9342 {0x42, 0x4, 0x4, 0, 0},
9343 {0x43, 0, 0, 0, 0},
9344 {0x44, 0x8, 0x8, 0, 0},
9345 {0x45, 0x55, 0x55, 1, 1},
9346 {0x46, 0, 0, 0, 0},
9347 {0x47, 0x11, 0x11, 0, 0},
9348 {0x48, 0, 0, 0, 0},
9349 {0x49, 0, 0, 1, 1},
9350 {0x4A, 0x7, 0x7, 0, 0},
9351 {0x4B, 0x6, 0x6, 0, 0},
9352 {0x4C, 0x4, 0x4, 0, 0},
9353 {0x4D, 0, 0, 0, 0},
9354 {0x4E, 0, 0, 0, 0},
9355 {0x4F, 0x26, 0x26, 1, 1},
9356 {0x50, 0x26, 0x26, 1, 1},
9357 {0x51, 0xf, 0xf, 1, 1},
9358 {0x52, 0xf, 0xf, 1, 1},
9359 {0x53, 0x44, 0x44, 0, 0},
9360 {0x54, 0, 0, 0, 0},
9361 {0x55, 0, 0, 0, 0},
9362 {0x56, 0x8, 0x8, 0, 0},
9363 {0x57, 0x8, 0x8, 0, 0},
9364 {0x58, 0x7, 0x7, 0, 0},
9365 {0x59, 0x22, 0x22, 0, 0},
9366 {0x5A, 0x22, 0x22, 0, 0},
9367 {0x5B, 0x2, 0x2, 0, 0},
9368 {0x5C, 0x4, 0x4, 1, 1},
9369 {0x5D, 0x7, 0x7, 0, 0},
9370 {0x5E, 0x55, 0x55, 0, 0},
9371 {0x5F, 0x23, 0x23, 0, 0},
9372 {0x60, 0x41, 0x41, 0, 0},
9373 {0x61, 0x1, 0x1, 0, 0},
9374 {0x62, 0xa, 0xa, 0, 0},
9375 {0x63, 0, 0, 0, 0},
9376 {0x64, 0, 0, 0, 0},
9377 {0x65, 0, 0, 0, 0},
9378 {0x66, 0, 0, 0, 0},
9379 {0x67, 0, 0, 0, 0},
9380 {0x68, 0, 0, 0, 0},
9381 {0x69, 0, 0, 0, 0},
9382 {0x6A, 0, 0, 0, 0},
9383 {0x6B, 0xc, 0xc, 0, 0},
9384 {0x6C, 0, 0, 0, 0},
9385 {0x6D, 0, 0, 0, 0},
9386 {0x6E, 0, 0, 0, 0},
9387 {0x6F, 0, 0, 0, 0},
9388 {0x70, 0, 0, 0, 0},
9389 {0x71, 0, 0, 0, 0},
9390 {0x72, 0x22, 0x22, 0, 0},
9391 {0x73, 0x22, 0x22, 0, 0},
9392 {0x74, 0, 0, 1, 1},
9393 {0x75, 0xa, 0xa, 0, 0},
9394 {0x76, 0x1, 0x1, 0, 0},
9395 {0x77, 0x22, 0x22, 0, 0},
9396 {0x78, 0x30, 0x30, 0, 0},
9397 {0x79, 0, 0, 0, 0},
9398 {0x7A, 0, 0, 0, 0},
9399 {0x7B, 0, 0, 0, 0},
9400 {0x7C, 0, 0, 0, 0},
9401 {0x7D, 0, 0, 0, 0},
9402 {0x7E, 0, 0, 0, 0},
9403 {0x7F, 0, 0, 0, 0},
9404 {0x80, 0, 0, 0, 0},
9405 {0x81, 0, 0, 0, 0},
9406 {0x82, 0, 0, 0, 0},
9407 {0x83, 0, 0, 0, 0},
9408 {0x84, 0, 0, 0, 0},
9409 {0x85, 0, 0, 0, 0},
9410 {0x86, 0, 0, 0, 0},
9411 {0x87, 0, 0, 0, 0},
9412 {0x88, 0, 0, 0, 0},
9413 {0x89, 0, 0, 0, 0},
9414 {0x8A, 0, 0, 0, 0},
9415 {0x8B, 0, 0, 0, 0},
9416 {0x8C, 0, 0, 0, 0},
9417 {0x8D, 0, 0, 0, 0},
9418 {0x8E, 0, 0, 0, 0},
9419 {0x8F, 0, 0, 0, 0},
9420 {0x90, 0, 0, 0, 0},
9421 {0x91, 0, 0, 0, 0},
9422 {0x92, 0, 0, 0, 0},
9423 {0x93, 0, 0, 0, 0},
9424 {0x94, 0, 0, 0, 0},
9425 {0xFFFF, 0, 0, 0, 0}
9426};
9427
9428struct radio_regs regs_SYN_2056_rev6[] = {
9429 {0x02, 0, 0, 0, 0},
9430 {0x03, 0, 0, 0, 0},
9431 {0x04, 0, 0, 0, 0},
9432 {0x05, 0, 0, 0, 0},
9433 {0x06, 0, 0, 0, 0},
9434 {0x07, 0, 0, 0, 0},
9435 {0x08, 0, 0, 0, 0},
9436 {0x09, 0x1, 0x1, 0, 0},
9437 {0x0A, 0, 0, 0, 0},
9438 {0x0B, 0, 0, 0, 0},
9439 {0x0C, 0, 0, 0, 0},
9440 {0x0D, 0, 0, 0, 0},
9441 {0x0E, 0, 0, 0, 0},
9442 {0x0F, 0, 0, 0, 0},
9443 {0x10, 0, 0, 0, 0},
9444 {0x11, 0, 0, 0, 0},
9445 {0x12, 0, 0, 0, 0},
9446 {0x13, 0, 0, 0, 0},
9447 {0x14, 0, 0, 0, 0},
9448 {0x15, 0, 0, 0, 0},
9449 {0x16, 0, 0, 0, 0},
9450 {0x17, 0, 0, 0, 0},
9451 {0x18, 0, 0, 0, 0},
9452 {0x19, 0, 0, 0, 0},
9453 {0x1A, 0, 0, 0, 0},
9454 {0x1B, 0, 0, 0, 0},
9455 {0x1C, 0, 0, 0, 0},
9456 {0x1D, 0, 0, 0, 0},
9457 {0x1E, 0, 0, 0, 0},
9458 {0x1F, 0, 0, 0, 0},
9459 {0x20, 0, 0, 0, 0},
9460 {0x21, 0, 0, 0, 0},
9461 {0x22, 0x60, 0x60, 0, 0},
9462 {0x23, 0x6, 0x6, 0, 0},
9463 {0x24, 0xc, 0xc, 0, 0},
9464 {0x25, 0, 0, 0, 0},
9465 {0x26, 0, 0, 0, 0},
9466 {0x27, 0, 0, 0, 0},
9467 {0x28, 0x1, 0x1, 0, 0},
9468 {0x29, 0, 0, 0, 0},
9469 {0x2A, 0, 0, 0, 0},
9470 {0x2B, 0, 0, 0, 0},
9471 {0x2C, 0, 0, 0, 0},
9472 {0x2D, 0, 0, 0, 0},
9473 {0x2E, 0, 0, 0, 0},
9474 {0x2F, 0x1f, 0x1f, 0, 0},
9475 {0x30, 0x15, 0x15, 0, 0},
9476 {0x31, 0xf, 0xf, 0, 0},
9477 {0x32, 0, 0, 0, 0},
9478 {0x33, 0, 0, 0, 0},
9479 {0x34, 0, 0, 0, 0},
9480 {0x35, 0, 0, 0, 0},
9481 {0x36, 0, 0, 0, 0},
9482 {0x37, 0, 0, 0, 0},
9483 {0x38, 0, 0, 0, 0},
9484 {0x39, 0, 0, 0, 0},
9485 {0x3A, 0, 0, 0, 0},
9486 {0x3B, 0, 0, 0, 0},
9487 {0x3C, 0x13, 0x13, 0, 0},
9488 {0x3D, 0xf, 0xf, 0, 0},
9489 {0x3E, 0x18, 0x18, 0, 0},
9490 {0x3F, 0, 0, 0, 0},
9491 {0x40, 0, 0, 0, 0},
9492 {0x41, 0x20, 0x20, 0, 0},
9493 {0x42, 0x20, 0x20, 0, 0},
9494 {0x43, 0, 0, 0, 0},
9495 {0x44, 0x77, 0x77, 0, 0},
9496 {0x45, 0x7, 0x7, 0, 0},
9497 {0x46, 0x1, 0x1, 0, 0},
9498 {0x47, 0x4, 0x4, 0, 0},
9499 {0x48, 0xf, 0xf, 0, 0},
9500 {0x49, 0x30, 0x30, 0, 0},
9501 {0x4A, 0x32, 0x32, 0, 0},
9502 {0x4B, 0xd, 0xd, 0, 0},
9503 {0x4C, 0xd, 0xd, 0, 0},
9504 {0x4D, 0x4, 0x4, 0, 0},
9505 {0x4E, 0x6, 0x6, 0, 0},
9506 {0x4F, 0x1, 0x1, 0, 0},
9507 {0x50, 0x1c, 0x1c, 0, 0},
9508 {0x51, 0x2, 0x2, 0, 0},
9509 {0x52, 0x2, 0x2, 0, 0},
9510 {0x53, 0xf7, 0xf7, 1, 1},
9511 {0x54, 0xb4, 0xb4, 0, 0},
9512 {0x55, 0xd2, 0xd2, 0, 0},
9513 {0x56, 0, 0, 0, 0},
9514 {0x57, 0, 0, 0, 0},
9515 {0x58, 0x4, 0x4, 0, 0},
9516 {0x59, 0x96, 0x96, 0, 0},
9517 {0x5A, 0x3e, 0x3e, 0, 0},
9518 {0x5B, 0x3e, 0x3e, 0, 0},
9519 {0x5C, 0x13, 0x13, 0, 0},
9520 {0x5D, 0x2, 0x2, 0, 0},
9521 {0x5E, 0, 0, 0, 0},
9522 {0x5F, 0x7, 0x7, 0, 0},
9523 {0x60, 0x7, 0x7, 1, 1},
9524 {0x61, 0x8, 0x8, 0, 0},
9525 {0x62, 0x3, 0x3, 0, 0},
9526 {0x63, 0, 0, 0, 0},
9527 {0x64, 0, 0, 0, 0},
9528 {0x65, 0, 0, 0, 0},
9529 {0x66, 0, 0, 0, 0},
9530 {0x67, 0, 0, 0, 0},
9531 {0x68, 0x40, 0x40, 0, 0},
9532 {0x69, 0, 0, 0, 0},
9533 {0x6A, 0, 0, 0, 0},
9534 {0x6B, 0, 0, 0, 0},
9535 {0x6C, 0, 0, 0, 0},
9536 {0x6D, 0x1, 0x1, 0, 0},
9537 {0x6E, 0, 0, 0, 0},
9538 {0x6F, 0, 0, 0, 0},
9539 {0x70, 0x60, 0x60, 0, 0},
9540 {0x71, 0x66, 0x66, 0, 0},
9541 {0x72, 0xc, 0xc, 0, 0},
9542 {0x73, 0x66, 0x66, 0, 0},
9543 {0x74, 0x8f, 0x8f, 1, 1},
9544 {0x75, 0, 0, 0, 0},
9545 {0x76, 0xcc, 0xcc, 0, 0},
9546 {0x77, 0x1, 0x1, 0, 0},
9547 {0x78, 0x66, 0x66, 0, 0},
9548 {0x79, 0x66, 0x66, 0, 0},
9549 {0x7A, 0, 0, 0, 0},
9550 {0x7B, 0, 0, 0, 0},
9551 {0x7C, 0, 0, 0, 0},
9552 {0x7D, 0, 0, 0, 0},
9553 {0x7E, 0, 0, 0, 0},
9554 {0x7F, 0, 0, 0, 0},
9555 {0x80, 0, 0, 0, 0},
9556 {0x81, 0, 0, 0, 0},
9557 {0x82, 0, 0, 0, 0},
9558 {0x83, 0, 0, 0, 0},
9559 {0x84, 0, 0, 0, 0},
9560 {0x85, 0xff, 0xff, 0, 0},
9561 {0x86, 0, 0, 0, 0},
9562 {0x87, 0, 0, 0, 0},
9563 {0x88, 0, 0, 0, 0},
9564 {0x89, 0, 0, 0, 0},
9565 {0x8A, 0, 0, 0, 0},
9566 {0x8B, 0, 0, 0, 0},
9567 {0x8C, 0, 0, 0, 0},
9568 {0x8D, 0, 0, 0, 0},
9569 {0x8E, 0, 0, 0, 0},
9570 {0x8F, 0, 0, 0, 0},
9571 {0x90, 0, 0, 0, 0},
9572 {0x91, 0, 0, 0, 0},
9573 {0x92, 0, 0, 0, 0},
9574 {0x93, 0, 0, 0, 0},
9575 {0x94, 0, 0, 0, 0},
9576 {0x95, 0, 0, 0, 0},
9577 {0x96, 0, 0, 0, 0},
9578 {0x97, 0, 0, 0, 0},
9579 {0x98, 0, 0, 0, 0},
9580 {0x99, 0, 0, 0, 0},
9581 {0x9A, 0, 0, 0, 0},
9582 {0x9B, 0, 0, 0, 0},
9583 {0x9C, 0, 0, 0, 0},
9584 {0x9D, 0, 0, 0, 0},
9585 {0x9E, 0, 0, 0, 0},
9586 {0x9F, 0x6, 0x6, 0, 0},
9587 {0xA0, 0x66, 0x66, 0, 0},
9588 {0xA1, 0x66, 0x66, 0, 0},
9589 {0xA2, 0x66, 0x66, 0, 0},
9590 {0xA3, 0x66, 0x66, 0, 0},
9591 {0xA4, 0x66, 0x66, 0, 0},
9592 {0xA5, 0x66, 0x66, 0, 0},
9593 {0xA6, 0x66, 0x66, 0, 0},
9594 {0xA7, 0x66, 0x66, 0, 0},
9595 {0xA8, 0x66, 0x66, 0, 0},
9596 {0xA9, 0x66, 0x66, 0, 0},
9597 {0xAA, 0x66, 0x66, 0, 0},
9598 {0xAB, 0x66, 0x66, 0, 0},
9599 {0xAC, 0x66, 0x66, 0, 0},
9600 {0xAD, 0x66, 0x66, 0, 0},
9601 {0xAE, 0x66, 0x66, 0, 0},
9602 {0xAF, 0x66, 0x66, 0, 0},
9603 {0xB0, 0x66, 0x66, 0, 0},
9604 {0xB1, 0x66, 0x66, 0, 0},
9605 {0xB2, 0x66, 0x66, 0, 0},
9606 {0xB3, 0xa, 0xa, 0, 0},
9607 {0xB4, 0, 0, 0, 0},
9608 {0xB5, 0, 0, 0, 0},
9609 {0xB6, 0, 0, 0, 0},
9610 {0xFFFF, 0, 0, 0, 0}
9611};
9612
9613struct radio_regs regs_TX_2056_rev6[] = {
9614 {0x02, 0, 0, 0, 0},
9615 {0x03, 0, 0, 0, 0},
9616 {0x04, 0, 0, 0, 0},
9617 {0x05, 0, 0, 0, 0},
9618 {0x06, 0, 0, 0, 0},
9619 {0x07, 0, 0, 0, 0},
9620 {0x08, 0, 0, 0, 0},
9621 {0x09, 0, 0, 0, 0},
9622 {0x0A, 0, 0, 0, 0},
9623 {0x0B, 0, 0, 0, 0},
9624 {0x0C, 0, 0, 0, 0},
9625 {0x0D, 0, 0, 0, 0},
9626 {0x0E, 0, 0, 0, 0},
9627 {0x0F, 0, 0, 0, 0},
9628 {0x10, 0, 0, 0, 0},
9629 {0x11, 0, 0, 0, 0},
9630 {0x12, 0, 0, 0, 0},
9631 {0x13, 0, 0, 0, 0},
9632 {0x14, 0, 0, 0, 0},
9633 {0x15, 0, 0, 0, 0},
9634 {0x16, 0, 0, 0, 0},
9635 {0x17, 0, 0, 0, 0},
9636 {0x18, 0, 0, 0, 0},
9637 {0x19, 0, 0, 0, 0},
9638 {0x1A, 0, 0, 0, 0},
9639 {0x1B, 0, 0, 0, 0},
9640 {0x1C, 0, 0, 0, 0},
9641 {0x1D, 0, 0, 0, 0},
9642 {0x1E, 0, 0, 0, 0},
9643 {0x1F, 0, 0, 0, 0},
9644 {0x20, 0, 0, 0, 0},
9645 {0x21, 0x88, 0x88, 0, 0},
9646 {0x22, 0x88, 0x88, 0, 0},
9647 {0x23, 0x88, 0x88, 0, 0},
9648 {0x24, 0x88, 0x88, 0, 0},
9649 {0x25, 0xc, 0xc, 0, 0},
9650 {0x26, 0, 0, 0, 0},
9651 {0x27, 0x3, 0x3, 0, 0},
9652 {0x28, 0, 0, 0, 0},
9653 {0x29, 0x3, 0x3, 0, 0},
9654 {0x2A, 0x37, 0x37, 0, 0},
9655 {0x2B, 0x3, 0x3, 0, 0},
9656 {0x2C, 0, 0, 0, 0},
9657 {0x2D, 0, 0, 0, 0},
9658 {0x2E, 0x1, 0x1, 0, 0},
9659 {0x2F, 0x1, 0x1, 0, 0},
9660 {0x30, 0, 0, 0, 0},
9661 {0x31, 0, 0, 0, 0},
9662 {0x32, 0, 0, 0, 0},
9663 {0x33, 0x11, 0x11, 0, 0},
9664 {0x34, 0xee, 0xee, 1, 1},
9665 {0x35, 0, 0, 0, 0},
9666 {0x36, 0, 0, 0, 0},
9667 {0x37, 0x3, 0x3, 0, 0},
9668 {0x38, 0x50, 0x50, 1, 1},
9669 {0x39, 0, 0, 0, 0},
9670 {0x3A, 0x50, 0x50, 1, 1},
9671 {0x3B, 0, 0, 0, 0},
9672 {0x3C, 0x6e, 0x6e, 0, 0},
9673 {0x3D, 0xf0, 0xf0, 1, 1},
9674 {0x3E, 0, 0, 0, 0},
9675 {0x3F, 0, 0, 0, 0},
9676 {0x40, 0, 0, 0, 0},
9677 {0x41, 0x3, 0x3, 0, 0},
9678 {0x42, 0x3, 0x3, 0, 0},
9679 {0x43, 0, 0, 0, 0},
9680 {0x44, 0x1e, 0x1e, 0, 0},
9681 {0x45, 0, 0, 0, 0},
9682 {0x46, 0x6e, 0x6e, 0, 0},
9683 {0x47, 0xf0, 0xf0, 1, 1},
9684 {0x48, 0, 0, 0, 0},
9685 {0x49, 0x2, 0x2, 0, 0},
9686 {0x4A, 0xff, 0xff, 1, 1},
9687 {0x4B, 0xc, 0xc, 0, 0},
9688 {0x4C, 0, 0, 0, 0},
9689 {0x4D, 0x38, 0x38, 0, 0},
9690 {0x4E, 0x70, 0x70, 1, 1},
9691 {0x4F, 0x2, 0x2, 0, 0},
9692 {0x50, 0x88, 0x88, 0, 0},
9693 {0x51, 0xc, 0xc, 0, 0},
9694 {0x52, 0, 0, 0, 0},
9695 {0x53, 0x8, 0x8, 0, 0},
9696 {0x54, 0x70, 0x70, 1, 1},
9697 {0x55, 0x2, 0x2, 0, 0},
9698 {0x56, 0xff, 0xff, 1, 1},
9699 {0x57, 0, 0, 0, 0},
9700 {0x58, 0x83, 0x83, 0, 0},
9701 {0x59, 0x77, 0x77, 1, 1},
9702 {0x5A, 0, 0, 0, 0},
9703 {0x5B, 0x2, 0x2, 0, 0},
9704 {0x5C, 0x88, 0x88, 0, 0},
9705 {0x5D, 0, 0, 0, 0},
9706 {0x5E, 0x8, 0x8, 0, 0},
9707 {0x5F, 0x77, 0x77, 1, 1},
9708 {0x60, 0x1, 0x1, 0, 0},
9709 {0x61, 0, 0, 0, 0},
9710 {0x62, 0x7, 0x7, 0, 0},
9711 {0x63, 0, 0, 0, 0},
9712 {0x64, 0x7, 0x7, 0, 0},
9713 {0x65, 0, 0, 0, 0},
9714 {0x66, 0, 0, 0, 0},
9715 {0x67, 0, 0, 1, 1},
9716 {0x68, 0, 0, 0, 0},
9717 {0x69, 0xa, 0xa, 0, 0},
9718 {0x6A, 0, 0, 0, 0},
9719 {0x6B, 0, 0, 0, 0},
9720 {0x6C, 0, 0, 0, 0},
9721 {0x6D, 0, 0, 0, 0},
9722 {0x6E, 0, 0, 0, 0},
9723 {0x6F, 0, 0, 0, 0},
9724 {0x70, 0, 0, 0, 0},
9725 {0x71, 0x2, 0x2, 0, 0},
9726 {0x72, 0, 0, 0, 0},
9727 {0x73, 0, 0, 0, 0},
9728 {0x74, 0xe, 0xe, 0, 0},
9729 {0x75, 0xe, 0xe, 0, 0},
9730 {0x76, 0xe, 0xe, 0, 0},
9731 {0x77, 0x13, 0x13, 0, 0},
9732 {0x78, 0x13, 0x13, 0, 0},
9733 {0x79, 0x1b, 0x1b, 0, 0},
9734 {0x7A, 0x1b, 0x1b, 0, 0},
9735 {0x7B, 0x55, 0x55, 0, 0},
9736 {0x7C, 0x5b, 0x5b, 0, 0},
9737 {0x7D, 0x30, 0x30, 1, 1},
9738 {0x7E, 0, 0, 0, 0},
9739 {0x7F, 0, 0, 0, 0},
9740 {0x80, 0, 0, 0, 0},
9741 {0x81, 0, 0, 0, 0},
9742 {0x82, 0, 0, 0, 0},
9743 {0x83, 0, 0, 0, 0},
9744 {0x84, 0, 0, 0, 0},
9745 {0x85, 0, 0, 0, 0},
9746 {0x86, 0, 0, 0, 0},
9747 {0x87, 0, 0, 0, 0},
9748 {0x88, 0, 0, 0, 0},
9749 {0x89, 0, 0, 0, 0},
9750 {0x8A, 0, 0, 0, 0},
9751 {0x8B, 0, 0, 0, 0},
9752 {0x8C, 0, 0, 0, 0},
9753 {0x8D, 0, 0, 0, 0},
9754 {0x8E, 0, 0, 0, 0},
9755 {0x8F, 0, 0, 0, 0},
9756 {0x90, 0, 0, 0, 0},
9757 {0x91, 0, 0, 0, 0},
9758 {0x92, 0, 0, 0, 0},
9759 {0x93, 0x70, 0x70, 0, 0},
9760 {0x94, 0x70, 0x70, 0, 0},
9761 {0x95, 0x70, 0x70, 0, 0},
9762 {0x96, 0x70, 0x70, 0, 0},
9763 {0x97, 0x70, 0x70, 0, 0},
9764 {0x98, 0x70, 0x70, 0, 0},
9765 {0x99, 0x70, 0x70, 0, 0},
9766 {0x9A, 0x70, 0x70, 0, 0},
9767 {0xFFFF, 0, 0, 0, 0}
9768};
9769
9770struct radio_regs regs_RX_2056_rev6[] = {
9771 {0x02, 0, 0, 0, 0},
9772 {0x03, 0, 0, 0, 0},
9773 {0x04, 0, 0, 0, 0},
9774 {0x05, 0, 0, 0, 0},
9775 {0x06, 0, 0, 0, 0},
9776 {0x07, 0, 0, 0, 0},
9777 {0x08, 0, 0, 0, 0},
9778 {0x09, 0, 0, 0, 0},
9779 {0x0A, 0, 0, 0, 0},
9780 {0x0B, 0, 0, 0, 0},
9781 {0x0C, 0, 0, 0, 0},
9782 {0x0D, 0, 0, 0, 0},
9783 {0x0E, 0, 0, 0, 0},
9784 {0x0F, 0, 0, 0, 0},
9785 {0x10, 0, 0, 0, 0},
9786 {0x11, 0, 0, 0, 0},
9787 {0x12, 0, 0, 0, 0},
9788 {0x13, 0, 0, 0, 0},
9789 {0x14, 0, 0, 0, 0},
9790 {0x15, 0, 0, 0, 0},
9791 {0x16, 0, 0, 0, 0},
9792 {0x17, 0, 0, 0, 0},
9793 {0x18, 0, 0, 0, 0},
9794 {0x19, 0, 0, 0, 0},
9795 {0x1A, 0, 0, 0, 0},
9796 {0x1B, 0, 0, 0, 0},
9797 {0x1C, 0, 0, 0, 0},
9798 {0x1D, 0, 0, 0, 0},
9799 {0x1E, 0, 0, 0, 0},
9800 {0x1F, 0, 0, 0, 0},
9801 {0x20, 0x3, 0x3, 0, 0},
9802 {0x21, 0, 0, 0, 0},
9803 {0x22, 0, 0, 0, 0},
9804 {0x23, 0x90, 0x90, 0, 0},
9805 {0x24, 0x55, 0x55, 0, 0},
9806 {0x25, 0x15, 0x15, 0, 0},
9807 {0x26, 0x5, 0x5, 0, 0},
9808 {0x27, 0x15, 0x15, 0, 0},
9809 {0x28, 0x5, 0x5, 0, 0},
9810 {0x29, 0x20, 0x20, 0, 0},
9811 {0x2A, 0x11, 0x11, 0, 0},
9812 {0x2B, 0x90, 0x90, 0, 0},
9813 {0x2C, 0, 0, 0, 0},
9814 {0x2D, 0x88, 0x88, 0, 0},
9815 {0x2E, 0x32, 0x32, 0, 0},
9816 {0x2F, 0x77, 0x77, 0, 0},
9817 {0x30, 0x17, 0x17, 1, 1},
9818 {0x31, 0xff, 0xff, 1, 1},
9819 {0x32, 0x20, 0x20, 0, 0},
9820 {0x33, 0, 0, 0, 0},
9821 {0x34, 0x88, 0x88, 0, 0},
9822 {0x35, 0x32, 0x32, 0, 0},
9823 {0x36, 0x77, 0x77, 0, 0},
9824 {0x37, 0x17, 0x17, 1, 1},
9825 {0x38, 0xf0, 0xf0, 1, 1},
9826 {0x39, 0x20, 0x20, 0, 0},
9827 {0x3A, 0x8, 0x8, 0, 0},
9828 {0x3B, 0x55, 0x55, 1, 1},
9829 {0x3C, 0, 0, 0, 0},
9830 {0x3D, 0x88, 0x88, 1, 1},
9831 {0x3E, 0, 0, 0, 0},
9832 {0x3F, 0x44, 0x44, 0, 0},
9833 {0x40, 0x7, 0x7, 1, 1},
9834 {0x41, 0x6, 0x6, 0, 0},
9835 {0x42, 0x4, 0x4, 0, 0},
9836 {0x43, 0, 0, 0, 0},
9837 {0x44, 0x8, 0x8, 0, 0},
9838 {0x45, 0x55, 0x55, 1, 1},
9839 {0x46, 0, 0, 0, 0},
9840 {0x47, 0x11, 0x11, 0, 0},
9841 {0x48, 0, 0, 0, 0},
9842 {0x49, 0x44, 0x44, 0, 0},
9843 {0x4A, 0x7, 0x7, 0, 0},
9844 {0x4B, 0x6, 0x6, 0, 0},
9845 {0x4C, 0x4, 0x4, 0, 0},
9846 {0x4D, 0, 0, 0, 0},
9847 {0x4E, 0, 0, 0, 0},
9848 {0x4F, 0x26, 0x26, 1, 1},
9849 {0x50, 0x26, 0x26, 1, 1},
9850 {0x51, 0xf, 0xf, 1, 1},
9851 {0x52, 0xf, 0xf, 1, 1},
9852 {0x53, 0x44, 0x44, 0, 0},
9853 {0x54, 0, 0, 0, 0},
9854 {0x55, 0, 0, 0, 0},
9855 {0x56, 0x8, 0x8, 0, 0},
9856 {0x57, 0x8, 0x8, 0, 0},
9857 {0x58, 0x7, 0x7, 0, 0},
9858 {0x59, 0x22, 0x22, 0, 0},
9859 {0x5A, 0x22, 0x22, 0, 0},
9860 {0x5B, 0x2, 0x2, 0, 0},
9861 {0x5C, 0x4, 0x4, 1, 1},
9862 {0x5D, 0x7, 0x7, 0, 0},
9863 {0x5E, 0x55, 0x55, 0, 0},
9864 {0x5F, 0x23, 0x23, 0, 0},
9865 {0x60, 0x41, 0x41, 0, 0},
9866 {0x61, 0x1, 0x1, 0, 0},
9867 {0x62, 0xa, 0xa, 0, 0},
9868 {0x63, 0, 0, 0, 0},
9869 {0x64, 0, 0, 0, 0},
9870 {0x65, 0, 0, 0, 0},
9871 {0x66, 0, 0, 0, 0},
9872 {0x67, 0, 0, 0, 0},
9873 {0x68, 0, 0, 0, 0},
9874 {0x69, 0, 0, 0, 0},
9875 {0x6A, 0, 0, 0, 0},
9876 {0x6B, 0xc, 0xc, 0, 0},
9877 {0x6C, 0, 0, 0, 0},
9878 {0x6D, 0, 0, 0, 0},
9879 {0x6E, 0, 0, 0, 0},
9880 {0x6F, 0, 0, 0, 0},
9881 {0x70, 0, 0, 0, 0},
9882 {0x71, 0, 0, 0, 0},
9883 {0x72, 0x22, 0x22, 0, 0},
9884 {0x73, 0x22, 0x22, 0, 0},
9885 {0x74, 0, 0, 1, 1},
9886 {0x75, 0xa, 0xa, 0, 0},
9887 {0x76, 0x1, 0x1, 0, 0},
9888 {0x77, 0x22, 0x22, 0, 0},
9889 {0x78, 0x30, 0x30, 0, 0},
9890 {0x79, 0, 0, 0, 0},
9891 {0x7A, 0, 0, 0, 0},
9892 {0x7B, 0, 0, 0, 0},
9893 {0x7C, 0, 0, 0, 0},
9894 {0x7D, 0x5, 0x5, 1, 1},
9895 {0x7E, 0, 0, 0, 0},
9896 {0x7F, 0, 0, 0, 0},
9897 {0x80, 0, 0, 0, 0},
9898 {0x81, 0, 0, 0, 0},
9899 {0x82, 0, 0, 0, 0},
9900 {0x83, 0, 0, 0, 0},
9901 {0x84, 0, 0, 0, 0},
9902 {0x85, 0, 0, 0, 0},
9903 {0x86, 0, 0, 0, 0},
9904 {0x87, 0, 0, 0, 0},
9905 {0x88, 0, 0, 0, 0},
9906 {0x89, 0, 0, 0, 0},
9907 {0x8A, 0, 0, 0, 0},
9908 {0x8B, 0, 0, 0, 0},
9909 {0x8C, 0, 0, 0, 0},
9910 {0x8D, 0, 0, 0, 0},
9911 {0x8E, 0, 0, 0, 0},
9912 {0x8F, 0, 0, 0, 0},
9913 {0x90, 0, 0, 0, 0},
9914 {0x91, 0, 0, 0, 0},
9915 {0x92, 0, 0, 0, 0},
9916 {0x93, 0, 0, 0, 0},
9917 {0x94, 0, 0, 0, 0},
9918 {0xFFFF, 0, 0, 0, 0}
9919};
9920
9921struct radio_regs regs_SYN_2056_rev7[] = {
9922 {0x02, 0, 0, 0, 0},
9923 {0x03, 0, 0, 0, 0},
9924 {0x04, 0, 0, 0, 0},
9925 {0x05, 0, 0, 0, 0},
9926 {0x06, 0, 0, 0, 0},
9927 {0x07, 0, 0, 0, 0},
9928 {0x08, 0, 0, 0, 0},
9929 {0x09, 0x1, 0x1, 0, 0},
9930 {0x0A, 0, 0, 0, 0},
9931 {0x0B, 0, 0, 0, 0},
9932 {0x0C, 0, 0, 0, 0},
9933 {0x0D, 0, 0, 0, 0},
9934 {0x0E, 0, 0, 0, 0},
9935 {0x0F, 0, 0, 0, 0},
9936 {0x10, 0, 0, 0, 0},
9937 {0x11, 0, 0, 0, 0},
9938 {0x12, 0, 0, 0, 0},
9939 {0x13, 0, 0, 0, 0},
9940 {0x14, 0, 0, 0, 0},
9941 {0x15, 0, 0, 0, 0},
9942 {0x16, 0, 0, 0, 0},
9943 {0x17, 0, 0, 0, 0},
9944 {0x18, 0, 0, 0, 0},
9945 {0x19, 0, 0, 0, 0},
9946 {0x1A, 0, 0, 0, 0},
9947 {0x1B, 0, 0, 0, 0},
9948 {0x1C, 0, 0, 0, 0},
9949 {0x1D, 0, 0, 0, 0},
9950 {0x1E, 0, 0, 0, 0},
9951 {0x1F, 0, 0, 0, 0},
9952 {0x20, 0, 0, 0, 0},
9953 {0x21, 0, 0, 0, 0},
9954 {0x22, 0x60, 0x60, 0, 0},
9955 {0x23, 0x6, 0x6, 0, 0},
9956 {0x24, 0xc, 0xc, 0, 0},
9957 {0x25, 0, 0, 0, 0},
9958 {0x26, 0, 0, 0, 0},
9959 {0x27, 0, 0, 0, 0},
9960 {0x28, 0x1, 0x1, 0, 0},
9961 {0x29, 0, 0, 0, 0},
9962 {0x2A, 0, 0, 0, 0},
9963 {0x2B, 0, 0, 0, 0},
9964 {0x2C, 0, 0, 0, 0},
9965 {0x2D, 0, 0, 0, 0},
9966 {0x2E, 0, 0, 0, 0},
9967 {0x2F, 0x1f, 0x1f, 0, 0},
9968 {0x30, 0x15, 0x15, 0, 0},
9969 {0x31, 0xf, 0xf, 0, 0},
9970 {0x32, 0, 0, 0, 0},
9971 {0x33, 0, 0, 0, 0},
9972 {0x34, 0, 0, 0, 0},
9973 {0x35, 0, 0, 0, 0},
9974 {0x36, 0, 0, 0, 0},
9975 {0x37, 0, 0, 0, 0},
9976 {0x38, 0, 0, 0, 0},
9977 {0x39, 0, 0, 0, 0},
9978 {0x3A, 0, 0, 0, 0},
9979 {0x3B, 0, 0, 0, 0},
9980 {0x3C, 0x13, 0x13, 0, 0},
9981 {0x3D, 0xf, 0xf, 0, 0},
9982 {0x3E, 0x18, 0x18, 0, 0},
9983 {0x3F, 0, 0, 0, 0},
9984 {0x40, 0, 0, 0, 0},
9985 {0x41, 0x20, 0x20, 0, 0},
9986 {0x42, 0x20, 0x20, 0, 0},
9987 {0x43, 0, 0, 0, 0},
9988 {0x44, 0x77, 0x77, 0, 0},
9989 {0x45, 0x7, 0x7, 0, 0},
9990 {0x46, 0x1, 0x1, 0, 0},
9991 {0x47, 0x4, 0x4, 0, 0},
9992 {0x48, 0xf, 0xf, 0, 0},
9993 {0x49, 0x30, 0x30, 0, 0},
9994 {0x4A, 0x32, 0x32, 0, 0},
9995 {0x4B, 0xd, 0xd, 0, 0},
9996 {0x4C, 0xd, 0xd, 0, 0},
9997 {0x4D, 0x4, 0x4, 0, 0},
9998 {0x4E, 0x6, 0x6, 0, 0},
9999 {0x4F, 0x1, 0x1, 0, 0},
10000 {0x50, 0x1c, 0x1c, 0, 0},
10001 {0x51, 0x2, 0x2, 0, 0},
10002 {0x52, 0x2, 0x2, 0, 0},
10003 {0x53, 0xf7, 0xf7, 1, 1},
10004 {0x54, 0xb4, 0xb4, 0, 0},
10005 {0x55, 0xd2, 0xd2, 0, 0},
10006 {0x56, 0, 0, 0, 0},
10007 {0x57, 0, 0, 0, 0},
10008 {0x58, 0x4, 0x4, 0, 0},
10009 {0x59, 0x96, 0x96, 0, 0},
10010 {0x5A, 0x3e, 0x3e, 0, 0},
10011 {0x5B, 0x3e, 0x3e, 0, 0},
10012 {0x5C, 0x13, 0x13, 0, 0},
10013 {0x5D, 0x2, 0x2, 0, 0},
10014 {0x5E, 0, 0, 0, 0},
10015 {0x5F, 0x7, 0x7, 0, 0},
10016 {0x60, 0x7, 0x7, 1, 1},
10017 {0x61, 0x8, 0x8, 0, 0},
10018 {0x62, 0x3, 0x3, 0, 0},
10019 {0x63, 0, 0, 0, 0},
10020 {0x64, 0, 0, 0, 0},
10021 {0x65, 0, 0, 0, 0},
10022 {0x66, 0, 0, 0, 0},
10023 {0x67, 0, 0, 0, 0},
10024 {0x68, 0x40, 0x40, 0, 0},
10025 {0x69, 0, 0, 0, 0},
10026 {0x6A, 0, 0, 0, 0},
10027 {0x6B, 0, 0, 0, 0},
10028 {0x6C, 0, 0, 0, 0},
10029 {0x6D, 0x1, 0x1, 0, 0},
10030 {0x6E, 0, 0, 0, 0},
10031 {0x6F, 0, 0, 0, 0},
10032 {0x70, 0x60, 0x60, 0, 0},
10033 {0x71, 0x66, 0x66, 0, 0},
10034 {0x72, 0xc, 0xc, 0, 0},
10035 {0x73, 0x66, 0x66, 0, 0},
10036 {0x74, 0x8f, 0x8f, 1, 1},
10037 {0x75, 0, 0, 0, 0},
10038 {0x76, 0xcc, 0xcc, 0, 0},
10039 {0x77, 0x1, 0x1, 0, 0},
10040 {0x78, 0x66, 0x66, 0, 0},
10041 {0x79, 0x66, 0x66, 0, 0},
10042 {0x7A, 0, 0, 0, 0},
10043 {0x7B, 0, 0, 0, 0},
10044 {0x7C, 0, 0, 0, 0},
10045 {0x7D, 0, 0, 0, 0},
10046 {0x7E, 0, 0, 0, 0},
10047 {0x7F, 0, 0, 0, 0},
10048 {0x80, 0, 0, 0, 0},
10049 {0x81, 0, 0, 0, 0},
10050 {0x82, 0, 0, 0, 0},
10051 {0x83, 0, 0, 0, 0},
10052 {0x84, 0, 0, 0, 0},
10053 {0x85, 0xff, 0xff, 0, 0},
10054 {0x86, 0, 0, 0, 0},
10055 {0x87, 0, 0, 0, 0},
10056 {0x88, 0, 0, 0, 0},
10057 {0x89, 0, 0, 0, 0},
10058 {0x8A, 0, 0, 0, 0},
10059 {0x8B, 0, 0, 0, 0},
10060 {0x8C, 0, 0, 0, 0},
10061 {0x8D, 0, 0, 0, 0},
10062 {0x8E, 0, 0, 0, 0},
10063 {0x8F, 0, 0, 0, 0},
10064 {0x90, 0, 0, 0, 0},
10065 {0x91, 0, 0, 0, 0},
10066 {0x92, 0, 0, 0, 0},
10067 {0x93, 0, 0, 0, 0},
10068 {0x94, 0, 0, 0, 0},
10069 {0x95, 0, 0, 0, 0},
10070 {0x96, 0, 0, 0, 0},
10071 {0x97, 0, 0, 0, 0},
10072 {0x98, 0, 0, 0, 0},
10073 {0x99, 0, 0, 0, 0},
10074 {0x9A, 0, 0, 0, 0},
10075 {0x9B, 0, 0, 0, 0},
10076 {0x9C, 0, 0, 0, 0},
10077 {0x9D, 0, 0, 0, 0},
10078 {0x9E, 0, 0, 0, 0},
10079 {0x9F, 0x6, 0x6, 0, 0},
10080 {0xA0, 0x66, 0x66, 0, 0},
10081 {0xA1, 0x66, 0x66, 0, 0},
10082 {0xA2, 0x66, 0x66, 0, 0},
10083 {0xA3, 0x66, 0x66, 0, 0},
10084 {0xA4, 0x66, 0x66, 0, 0},
10085 {0xA5, 0x66, 0x66, 0, 0},
10086 {0xA6, 0x66, 0x66, 0, 0},
10087 {0xA7, 0x66, 0x66, 0, 0},
10088 {0xA8, 0x66, 0x66, 0, 0},
10089 {0xA9, 0x66, 0x66, 0, 0},
10090 {0xAA, 0x66, 0x66, 0, 0},
10091 {0xAB, 0x66, 0x66, 0, 0},
10092 {0xAC, 0x66, 0x66, 0, 0},
10093 {0xAD, 0x66, 0x66, 0, 0},
10094 {0xAE, 0x66, 0x66, 0, 0},
10095 {0xAF, 0x66, 0x66, 0, 0},
10096 {0xB0, 0x66, 0x66, 0, 0},
10097 {0xB1, 0x66, 0x66, 0, 0},
10098 {0xB2, 0x66, 0x66, 0, 0},
10099 {0xB3, 0xa, 0xa, 0, 0},
10100 {0xB4, 0, 0, 0, 0},
10101 {0xB5, 0, 0, 0, 0},
10102 {0xB6, 0, 0, 0, 0},
10103 {0xFFFF, 0, 0, 0, 0},
10104};
10105
10106struct radio_regs regs_TX_2056_rev7[] = {
10107 {0x02, 0, 0, 0, 0},
10108 {0x03, 0, 0, 0, 0},
10109 {0x04, 0, 0, 0, 0},
10110 {0x05, 0, 0, 0, 0},
10111 {0x06, 0, 0, 0, 0},
10112 {0x07, 0, 0, 0, 0},
10113 {0x08, 0, 0, 0, 0},
10114 {0x09, 0, 0, 0, 0},
10115 {0x0A, 0, 0, 0, 0},
10116 {0x0B, 0, 0, 0, 0},
10117 {0x0C, 0, 0, 0, 0},
10118 {0x0D, 0, 0, 0, 0},
10119 {0x0E, 0, 0, 0, 0},
10120 {0x0F, 0, 0, 0, 0},
10121 {0x10, 0, 0, 0, 0},
10122 {0x11, 0, 0, 0, 0},
10123 {0x12, 0, 0, 0, 0},
10124 {0x13, 0, 0, 0, 0},
10125 {0x14, 0, 0, 0, 0},
10126 {0x15, 0, 0, 0, 0},
10127 {0x16, 0, 0, 0, 0},
10128 {0x17, 0, 0, 0, 0},
10129 {0x18, 0, 0, 0, 0},
10130 {0x19, 0, 0, 0, 0},
10131 {0x1A, 0, 0, 0, 0},
10132 {0x1B, 0, 0, 0, 0},
10133 {0x1C, 0, 0, 0, 0},
10134 {0x1D, 0, 0, 0, 0},
10135 {0x1E, 0, 0, 0, 0},
10136 {0x1F, 0, 0, 0, 0},
10137 {0x20, 0, 0, 0, 0},
10138 {0x21, 0x88, 0x88, 0, 0},
10139 {0x22, 0x88, 0x88, 0, 0},
10140 {0x23, 0x88, 0x88, 0, 0},
10141 {0x24, 0x88, 0x88, 0, 0},
10142 {0x25, 0xc, 0xc, 0, 0},
10143 {0x26, 0, 0, 0, 0},
10144 {0x27, 0x3, 0x3, 0, 0},
10145 {0x28, 0, 0, 0, 0},
10146 {0x29, 0x3, 0x3, 0, 0},
10147 {0x2A, 0x37, 0x37, 0, 0},
10148 {0x2B, 0x3, 0x3, 0, 0},
10149 {0x2C, 0, 0, 0, 0},
10150 {0x2D, 0, 0, 0, 0},
10151 {0x2E, 0x1, 0x1, 0, 0},
10152 {0x2F, 0x1, 0x1, 0, 0},
10153 {0x30, 0, 0, 0, 0},
10154 {0x31, 0, 0, 0, 0},
10155 {0x32, 0, 0, 0, 0},
10156 {0x33, 0x11, 0x11, 0, 0},
10157 {0x34, 0xee, 0xee, 1, 1},
10158 {0x35, 0, 0, 0, 0},
10159 {0x36, 0, 0, 0, 0},
10160 {0x37, 0x3, 0x3, 0, 0},
10161 {0x38, 0x50, 0x50, 1, 1},
10162 {0x39, 0, 0, 0, 0},
10163 {0x3A, 0x50, 0x50, 1, 1},
10164 {0x3B, 0, 0, 0, 0},
10165 {0x3C, 0x6e, 0x6e, 0, 0},
10166 {0x3D, 0xf0, 0xf0, 1, 1},
10167 {0x3E, 0, 0, 0, 0},
10168 {0x3F, 0, 0, 0, 0},
10169 {0x40, 0, 0, 0, 0},
10170 {0x41, 0x3, 0x3, 0, 0},
10171 {0x42, 0x3, 0x3, 0, 0},
10172 {0x43, 0, 0, 0, 0},
10173 {0x44, 0x1e, 0x1e, 0, 0},
10174 {0x45, 0, 0, 0, 0},
10175 {0x46, 0x6e, 0x6e, 0, 0},
10176 {0x47, 0xf0, 0xf0, 1, 1},
10177 {0x48, 0, 0, 0, 0},
10178 {0x49, 0x2, 0x2, 0, 0},
10179 {0x4A, 0xff, 0xff, 1, 1},
10180 {0x4B, 0xc, 0xc, 0, 0},
10181 {0x4C, 0, 0, 0, 0},
10182 {0x4D, 0x38, 0x38, 0, 0},
10183 {0x4E, 0x70, 0x70, 1, 1},
10184 {0x4F, 0x2, 0x2, 0, 0},
10185 {0x50, 0x88, 0x88, 0, 0},
10186 {0x51, 0xc, 0xc, 0, 0},
10187 {0x52, 0, 0, 0, 0},
10188 {0x53, 0x8, 0x8, 0, 0},
10189 {0x54, 0x70, 0x70, 1, 1},
10190 {0x55, 0x2, 0x2, 0, 0},
10191 {0x56, 0xff, 0xff, 1, 1},
10192 {0x57, 0, 0, 0, 0},
10193 {0x58, 0x83, 0x83, 0, 0},
10194 {0x59, 0x77, 0x77, 1, 1},
10195 {0x5A, 0, 0, 0, 0},
10196 {0x5B, 0x2, 0x2, 0, 0},
10197 {0x5C, 0x88, 0x88, 0, 0},
10198 {0x5D, 0, 0, 0, 0},
10199 {0x5E, 0x8, 0x8, 0, 0},
10200 {0x5F, 0x77, 0x77, 1, 1},
10201 {0x60, 0x1, 0x1, 0, 0},
10202 {0x61, 0, 0, 0, 0},
10203 {0x62, 0x7, 0x7, 0, 0},
10204 {0x63, 0, 0, 0, 0},
10205 {0x64, 0x7, 0x7, 0, 0},
10206 {0x65, 0, 0, 0, 0},
10207 {0x66, 0, 0, 0, 0},
10208 {0x67, 0, 0, 1, 1},
10209 {0x68, 0, 0, 0, 0},
10210 {0x69, 0xa, 0xa, 0, 0},
10211 {0x6A, 0, 0, 0, 0},
10212 {0x6B, 0, 0, 0, 0},
10213 {0x6C, 0, 0, 0, 0},
10214 {0x6D, 0, 0, 0, 0},
10215 {0x6E, 0, 0, 0, 0},
10216 {0x6F, 0, 0, 0, 0},
10217 {0x70, 0, 0, 0, 0},
10218 {0x71, 0x2, 0x2, 0, 0},
10219 {0x72, 0, 0, 0, 0},
10220 {0x73, 0, 0, 0, 0},
10221 {0x74, 0xe, 0xe, 0, 0},
10222 {0x75, 0xe, 0xe, 0, 0},
10223 {0x76, 0xe, 0xe, 0, 0},
10224 {0x77, 0x13, 0x13, 0, 0},
10225 {0x78, 0x13, 0x13, 0, 0},
10226 {0x79, 0x1b, 0x1b, 0, 0},
10227 {0x7A, 0x1b, 0x1b, 0, 0},
10228 {0x7B, 0x55, 0x55, 0, 0},
10229 {0x7C, 0x5b, 0x5b, 0, 0},
10230 {0x7D, 0x30, 0x30, 1, 1},
10231 {0x7E, 0, 0, 0, 0},
10232 {0x7F, 0, 0, 0, 0},
10233 {0x80, 0, 0, 0, 0},
10234 {0x81, 0, 0, 0, 0},
10235 {0x82, 0, 0, 0, 0},
10236 {0x83, 0, 0, 0, 0},
10237 {0x84, 0, 0, 0, 0},
10238 {0x85, 0, 0, 0, 0},
10239 {0x86, 0, 0, 0, 0},
10240 {0x87, 0, 0, 0, 0},
10241 {0x88, 0, 0, 0, 0},
10242 {0x89, 0, 0, 0, 0},
10243 {0x8A, 0, 0, 0, 0},
10244 {0x8B, 0, 0, 0, 0},
10245 {0x8C, 0, 0, 0, 0},
10246 {0x8D, 0, 0, 0, 0},
10247 {0x8E, 0, 0, 0, 0},
10248 {0x8F, 0, 0, 0, 0},
10249 {0x90, 0, 0, 0, 0},
10250 {0x91, 0, 0, 0, 0},
10251 {0x92, 0, 0, 0, 0},
10252 {0x93, 0x70, 0x70, 0, 0},
10253 {0x94, 0x70, 0x70, 0, 0},
10254 {0x95, 0x71, 0x71, 1, 1},
10255 {0x96, 0x71, 0x71, 1, 1},
10256 {0x97, 0x72, 0x72, 1, 1},
10257 {0x98, 0x73, 0x73, 1, 1},
10258 {0x99, 0x74, 0x74, 1, 1},
10259 {0x9A, 0x75, 0x75, 1, 1},
10260 {0xFFFF, 0, 0, 0, 0},
10261};
10262
10263struct radio_regs regs_RX_2056_rev7[] = {
10264 {0x02, 0, 0, 0, 0},
10265 {0x03, 0, 0, 0, 0},
10266 {0x04, 0, 0, 0, 0},
10267 {0x05, 0, 0, 0, 0},
10268 {0x06, 0, 0, 0, 0},
10269 {0x07, 0, 0, 0, 0},
10270 {0x08, 0, 0, 0, 0},
10271 {0x09, 0, 0, 0, 0},
10272 {0x0A, 0, 0, 0, 0},
10273 {0x0B, 0, 0, 0, 0},
10274 {0x0C, 0, 0, 0, 0},
10275 {0x0D, 0, 0, 0, 0},
10276 {0x0E, 0, 0, 0, 0},
10277 {0x0F, 0, 0, 0, 0},
10278 {0x10, 0, 0, 0, 0},
10279 {0x11, 0, 0, 0, 0},
10280 {0x12, 0, 0, 0, 0},
10281 {0x13, 0, 0, 0, 0},
10282 {0x14, 0, 0, 0, 0},
10283 {0x15, 0, 0, 0, 0},
10284 {0x16, 0, 0, 0, 0},
10285 {0x17, 0, 0, 0, 0},
10286 {0x18, 0, 0, 0, 0},
10287 {0x19, 0, 0, 0, 0},
10288 {0x1A, 0, 0, 0, 0},
10289 {0x1B, 0, 0, 0, 0},
10290 {0x1C, 0, 0, 0, 0},
10291 {0x1D, 0, 0, 0, 0},
10292 {0x1E, 0, 0, 0, 0},
10293 {0x1F, 0, 0, 0, 0},
10294 {0x20, 0x3, 0x3, 0, 0},
10295 {0x21, 0, 0, 0, 0},
10296 {0x22, 0, 0, 0, 0},
10297 {0x23, 0x90, 0x90, 0, 0},
10298 {0x24, 0x55, 0x55, 0, 0},
10299 {0x25, 0x15, 0x15, 0, 0},
10300 {0x26, 0x5, 0x5, 0, 0},
10301 {0x27, 0x15, 0x15, 0, 0},
10302 {0x28, 0x5, 0x5, 0, 0},
10303 {0x29, 0x20, 0x20, 0, 0},
10304 {0x2A, 0x11, 0x11, 0, 0},
10305 {0x2B, 0x90, 0x90, 0, 0},
10306 {0x2C, 0, 0, 0, 0},
10307 {0x2D, 0x88, 0x88, 0, 0},
10308 {0x2E, 0x32, 0x32, 0, 0},
10309 {0x2F, 0x77, 0x77, 0, 0},
10310 {0x30, 0x17, 0x17, 1, 1},
10311 {0x31, 0xff, 0xff, 1, 1},
10312 {0x32, 0x20, 0x20, 0, 0},
10313 {0x33, 0, 0, 0, 0},
10314 {0x34, 0x88, 0x88, 0, 0},
10315 {0x35, 0x32, 0x32, 0, 0},
10316 {0x36, 0x77, 0x77, 0, 0},
10317 {0x37, 0x17, 0x17, 1, 1},
10318 {0x38, 0xf0, 0xf0, 1, 1},
10319 {0x39, 0x20, 0x20, 0, 0},
10320 {0x3A, 0x8, 0x8, 0, 0},
10321 {0x3B, 0x55, 0x55, 1, 1},
10322 {0x3C, 0, 0, 0, 0},
10323 {0x3D, 0x88, 0x88, 1, 1},
10324 {0x3E, 0, 0, 0, 0},
10325 {0x3F, 0, 0, 1, 1},
10326 {0x40, 0x7, 0x7, 1, 1},
10327 {0x41, 0x6, 0x6, 0, 0},
10328 {0x42, 0x4, 0x4, 0, 0},
10329 {0x43, 0, 0, 0, 0},
10330 {0x44, 0x8, 0x8, 0, 0},
10331 {0x45, 0x55, 0x55, 1, 1},
10332 {0x46, 0, 0, 0, 0},
10333 {0x47, 0x11, 0x11, 0, 0},
10334 {0x48, 0, 0, 0, 0},
10335 {0x49, 0, 0, 1, 1},
10336 {0x4A, 0x7, 0x7, 0, 0},
10337 {0x4B, 0x6, 0x6, 0, 0},
10338 {0x4C, 0x4, 0x4, 0, 0},
10339 {0x4D, 0, 0, 0, 0},
10340 {0x4E, 0, 0, 0, 0},
10341 {0x4F, 0x26, 0x26, 1, 1},
10342 {0x50, 0x26, 0x26, 1, 1},
10343 {0x51, 0xf, 0xf, 1, 1},
10344 {0x52, 0xf, 0xf, 1, 1},
10345 {0x53, 0x44, 0x44, 0, 0},
10346 {0x54, 0, 0, 0, 0},
10347 {0x55, 0, 0, 0, 0},
10348 {0x56, 0x8, 0x8, 0, 0},
10349 {0x57, 0x8, 0x8, 0, 0},
10350 {0x58, 0x7, 0x7, 0, 0},
10351 {0x59, 0x22, 0x22, 0, 0},
10352 {0x5A, 0x22, 0x22, 0, 0},
10353 {0x5B, 0x2, 0x2, 0, 0},
10354 {0x5C, 0x4, 0x4, 1, 1},
10355 {0x5D, 0x7, 0x7, 0, 0},
10356 {0x5E, 0x55, 0x55, 0, 0},
10357 {0x5F, 0x23, 0x23, 0, 0},
10358 {0x60, 0x41, 0x41, 0, 0},
10359 {0x61, 0x1, 0x1, 0, 0},
10360 {0x62, 0xa, 0xa, 0, 0},
10361 {0x63, 0, 0, 0, 0},
10362 {0x64, 0, 0, 0, 0},
10363 {0x65, 0, 0, 0, 0},
10364 {0x66, 0, 0, 0, 0},
10365 {0x67, 0, 0, 0, 0},
10366 {0x68, 0, 0, 0, 0},
10367 {0x69, 0, 0, 0, 0},
10368 {0x6A, 0, 0, 0, 0},
10369 {0x6B, 0xc, 0xc, 0, 0},
10370 {0x6C, 0, 0, 0, 0},
10371 {0x6D, 0, 0, 0, 0},
10372 {0x6E, 0, 0, 0, 0},
10373 {0x6F, 0, 0, 0, 0},
10374 {0x70, 0, 0, 0, 0},
10375 {0x71, 0, 0, 0, 0},
10376 {0x72, 0x22, 0x22, 0, 0},
10377 {0x73, 0x22, 0x22, 0, 0},
10378 {0x74, 0, 0, 1, 1},
10379 {0x75, 0xa, 0xa, 0, 0},
10380 {0x76, 0x1, 0x1, 0, 0},
10381 {0x77, 0x22, 0x22, 0, 0},
10382 {0x78, 0x30, 0x30, 0, 0},
10383 {0x79, 0, 0, 0, 0},
10384 {0x7A, 0, 0, 0, 0},
10385 {0x7B, 0, 0, 0, 0},
10386 {0x7C, 0, 0, 0, 0},
10387 {0x7D, 0, 0, 0, 0},
10388 {0x7E, 0, 0, 0, 0},
10389 {0x7F, 0, 0, 0, 0},
10390 {0x80, 0, 0, 0, 0},
10391 {0x81, 0, 0, 0, 0},
10392 {0x82, 0, 0, 0, 0},
10393 {0x83, 0, 0, 0, 0},
10394 {0x84, 0, 0, 0, 0},
10395 {0x85, 0, 0, 0, 0},
10396 {0x86, 0, 0, 0, 0},
10397 {0x87, 0, 0, 0, 0},
10398 {0x88, 0, 0, 0, 0},
10399 {0x89, 0, 0, 0, 0},
10400 {0x8A, 0, 0, 0, 0},
10401 {0x8B, 0, 0, 0, 0},
10402 {0x8C, 0, 0, 0, 0},
10403 {0x8D, 0, 0, 0, 0},
10404 {0x8E, 0, 0, 0, 0},
10405 {0x8F, 0, 0, 0, 0},
10406 {0x90, 0, 0, 0, 0},
10407 {0x91, 0, 0, 0, 0},
10408 {0x92, 0, 0, 0, 0},
10409 {0x93, 0, 0, 0, 0},
10410 {0x94, 0, 0, 0, 0},
10411 {0xFFFF, 0, 0, 0, 0},
10412};
10413
10414struct radio_regs regs_SYN_2056_rev8[] = {
10415 {0x02, 0, 0, 0, 0},
10416 {0x03, 0, 0, 0, 0},
10417 {0x04, 0, 0, 0, 0},
10418 {0x05, 0, 0, 0, 0},
10419 {0x06, 0, 0, 0, 0},
10420 {0x07, 0, 0, 0, 0},
10421 {0x08, 0, 0, 0, 0},
10422 {0x09, 0x1, 0x1, 0, 0},
10423 {0x0A, 0, 0, 0, 0},
10424 {0x0B, 0, 0, 0, 0},
10425 {0x0C, 0, 0, 0, 0},
10426 {0x0D, 0, 0, 0, 0},
10427 {0x0E, 0, 0, 0, 0},
10428 {0x0F, 0, 0, 0, 0},
10429 {0x10, 0, 0, 0, 0},
10430 {0x11, 0, 0, 0, 0},
10431 {0x12, 0, 0, 0, 0},
10432 {0x13, 0, 0, 0, 0},
10433 {0x14, 0, 0, 0, 0},
10434 {0x15, 0, 0, 0, 0},
10435 {0x16, 0, 0, 0, 0},
10436 {0x17, 0, 0, 0, 0},
10437 {0x18, 0, 0, 0, 0},
10438 {0x19, 0, 0, 0, 0},
10439 {0x1A, 0, 0, 0, 0},
10440 {0x1B, 0, 0, 0, 0},
10441 {0x1C, 0, 0, 0, 0},
10442 {0x1D, 0, 0, 0, 0},
10443 {0x1E, 0, 0, 0, 0},
10444 {0x1F, 0, 0, 0, 0},
10445 {0x20, 0, 0, 0, 0},
10446 {0x21, 0, 0, 0, 0},
10447 {0x22, 0x60, 0x60, 0, 0},
10448 {0x23, 0x6, 0x6, 0, 0},
10449 {0x24, 0xc, 0xc, 0, 0},
10450 {0x25, 0, 0, 0, 0},
10451 {0x26, 0, 0, 0, 0},
10452 {0x27, 0, 0, 0, 0},
10453 {0x28, 0x1, 0x1, 0, 0},
10454 {0x29, 0, 0, 0, 0},
10455 {0x2A, 0, 0, 0, 0},
10456 {0x2B, 0, 0, 0, 0},
10457 {0x2C, 0, 0, 0, 0},
10458 {0x2D, 0, 0, 0, 0},
10459 {0x2E, 0, 0, 0, 0},
10460 {0x2F, 0x1f, 0x1f, 0, 0},
10461 {0x30, 0x15, 0x15, 0, 0},
10462 {0x31, 0xf, 0xf, 0, 0},
10463 {0x32, 0, 0, 0, 0},
10464 {0x33, 0, 0, 0, 0},
10465 {0x34, 0, 0, 0, 0},
10466 {0x35, 0, 0, 0, 0},
10467 {0x36, 0, 0, 0, 0},
10468 {0x37, 0, 0, 0, 0},
10469 {0x38, 0, 0, 0, 0},
10470 {0x39, 0, 0, 0, 0},
10471 {0x3A, 0, 0, 0, 0},
10472 {0x3B, 0, 0, 0, 0},
10473 {0x3C, 0x13, 0x13, 0, 0},
10474 {0x3D, 0xf, 0xf, 0, 0},
10475 {0x3E, 0x18, 0x18, 0, 0},
10476 {0x3F, 0, 0, 0, 0},
10477 {0x40, 0, 0, 0, 0},
10478 {0x41, 0x20, 0x20, 0, 0},
10479 {0x42, 0x20, 0x20, 0, 0},
10480 {0x43, 0, 0, 0, 0},
10481 {0x44, 0x77, 0x77, 0, 0},
10482 {0x45, 0x7, 0x7, 0, 0},
10483 {0x46, 0x1, 0x1, 0, 0},
10484 {0x47, 0x4, 0x4, 0, 0},
10485 {0x48, 0xf, 0xf, 0, 0},
10486 {0x49, 0x30, 0x30, 0, 0},
10487 {0x4A, 0x32, 0x32, 0, 0},
10488 {0x4B, 0xd, 0xd, 0, 0},
10489 {0x4C, 0xd, 0xd, 0, 0},
10490 {0x4D, 0x4, 0x4, 0, 0},
10491 {0x4E, 0x6, 0x6, 0, 0},
10492 {0x4F, 0x1, 0x1, 0, 0},
10493 {0x50, 0x1c, 0x1c, 0, 0},
10494 {0x51, 0x2, 0x2, 0, 0},
10495 {0x52, 0x2, 0x2, 0, 0},
10496 {0x53, 0xf7, 0xf7, 1, 1},
10497 {0x54, 0xb4, 0xb4, 0, 0},
10498 {0x55, 0xd2, 0xd2, 0, 0},
10499 {0x56, 0, 0, 0, 0},
10500 {0x57, 0, 0, 0, 0},
10501 {0x58, 0x4, 0x4, 0, 0},
10502 {0x59, 0x96, 0x96, 0, 0},
10503 {0x5A, 0x3e, 0x3e, 0, 0},
10504 {0x5B, 0x3e, 0x3e, 0, 0},
10505 {0x5C, 0x13, 0x13, 0, 0},
10506 {0x5D, 0x2, 0x2, 0, 0},
10507 {0x5E, 0, 0, 0, 0},
10508 {0x5F, 0x7, 0x7, 0, 0},
10509 {0x60, 0x7, 0x7, 1, 1},
10510 {0x61, 0x8, 0x8, 0, 0},
10511 {0x62, 0x3, 0x3, 0, 0},
10512 {0x63, 0, 0, 0, 0},
10513 {0x64, 0, 0, 0, 0},
10514 {0x65, 0, 0, 0, 0},
10515 {0x66, 0, 0, 0, 0},
10516 {0x67, 0, 0, 0, 0},
10517 {0x68, 0x40, 0x40, 0, 0},
10518 {0x69, 0, 0, 0, 0},
10519 {0x6A, 0, 0, 0, 0},
10520 {0x6B, 0, 0, 0, 0},
10521 {0x6C, 0, 0, 0, 0},
10522 {0x6D, 0x1, 0x1, 0, 0},
10523 {0x6E, 0, 0, 0, 0},
10524 {0x6F, 0, 0, 0, 0},
10525 {0x70, 0x60, 0x60, 0, 0},
10526 {0x71, 0x66, 0x66, 0, 0},
10527 {0x72, 0xc, 0xc, 0, 0},
10528 {0x73, 0x66, 0x66, 0, 0},
10529 {0x74, 0x8f, 0x8f, 1, 1},
10530 {0x75, 0, 0, 0, 0},
10531 {0x76, 0xcc, 0xcc, 0, 0},
10532 {0x77, 0x1, 0x1, 0, 0},
10533 {0x78, 0x66, 0x66, 0, 0},
10534 {0x79, 0x66, 0x66, 0, 0},
10535 {0x7A, 0, 0, 0, 0},
10536 {0x7B, 0, 0, 0, 0},
10537 {0x7C, 0, 0, 0, 0},
10538 {0x7D, 0, 0, 0, 0},
10539 {0x7E, 0, 0, 0, 0},
10540 {0x7F, 0, 0, 0, 0},
10541 {0x80, 0, 0, 0, 0},
10542 {0x81, 0, 0, 0, 0},
10543 {0x82, 0, 0, 0, 0},
10544 {0x83, 0, 0, 0, 0},
10545 {0x84, 0, 0, 0, 0},
10546 {0x85, 0xff, 0xff, 0, 0},
10547 {0x86, 0, 0, 0, 0},
10548 {0x87, 0, 0, 0, 0},
10549 {0x88, 0, 0, 0, 0},
10550 {0x89, 0, 0, 0, 0},
10551 {0x8A, 0, 0, 0, 0},
10552 {0x8B, 0, 0, 0, 0},
10553 {0x8C, 0, 0, 0, 0},
10554 {0x8D, 0, 0, 0, 0},
10555 {0x8E, 0, 0, 0, 0},
10556 {0x8F, 0, 0, 0, 0},
10557 {0x90, 0, 0, 0, 0},
10558 {0x91, 0, 0, 0, 0},
10559 {0x92, 0, 0, 0, 0},
10560 {0x93, 0, 0, 0, 0},
10561 {0x94, 0, 0, 0, 0},
10562 {0x95, 0, 0, 0, 0},
10563 {0x96, 0, 0, 0, 0},
10564 {0x97, 0, 0, 0, 0},
10565 {0x98, 0, 0, 0, 0},
10566 {0x99, 0, 0, 0, 0},
10567 {0x9A, 0, 0, 0, 0},
10568 {0x9B, 0, 0, 0, 0},
10569 {0x9C, 0, 0, 0, 0},
10570 {0x9D, 0, 0, 0, 0},
10571 {0x9E, 0, 0, 0, 0},
10572 {0x9F, 0x6, 0x6, 0, 0},
10573 {0xA0, 0x66, 0x66, 0, 0},
10574 {0xA1, 0x66, 0x66, 0, 0},
10575 {0xA2, 0x66, 0x66, 0, 0},
10576 {0xA3, 0x66, 0x66, 0, 0},
10577 {0xA4, 0x66, 0x66, 0, 0},
10578 {0xA5, 0x66, 0x66, 0, 0},
10579 {0xA6, 0x66, 0x66, 0, 0},
10580 {0xA7, 0x66, 0x66, 0, 0},
10581 {0xA8, 0x66, 0x66, 0, 0},
10582 {0xA9, 0x66, 0x66, 0, 0},
10583 {0xAA, 0x66, 0x66, 0, 0},
10584 {0xAB, 0x66, 0x66, 0, 0},
10585 {0xAC, 0x66, 0x66, 0, 0},
10586 {0xAD, 0x66, 0x66, 0, 0},
10587 {0xAE, 0x66, 0x66, 0, 0},
10588 {0xAF, 0x66, 0x66, 0, 0},
10589 {0xB0, 0x66, 0x66, 0, 0},
10590 {0xB1, 0x66, 0x66, 0, 0},
10591 {0xB2, 0x66, 0x66, 0, 0},
10592 {0xB3, 0xa, 0xa, 0, 0},
10593 {0xB4, 0, 0, 0, 0},
10594 {0xB5, 0, 0, 0, 0},
10595 {0xB6, 0, 0, 0, 0},
10596 {0xFFFF, 0, 0, 0, 0},
10597};
10598
10599struct radio_regs regs_TX_2056_rev8[] = {
10600 {0x02, 0, 0, 0, 0},
10601 {0x03, 0, 0, 0, 0},
10602 {0x04, 0, 0, 0, 0},
10603 {0x05, 0, 0, 0, 0},
10604 {0x06, 0, 0, 0, 0},
10605 {0x07, 0, 0, 0, 0},
10606 {0x08, 0, 0, 0, 0},
10607 {0x09, 0, 0, 0, 0},
10608 {0x0A, 0, 0, 0, 0},
10609 {0x0B, 0, 0, 0, 0},
10610 {0x0C, 0, 0, 0, 0},
10611 {0x0D, 0, 0, 0, 0},
10612 {0x0E, 0, 0, 0, 0},
10613 {0x0F, 0, 0, 0, 0},
10614 {0x10, 0, 0, 0, 0},
10615 {0x11, 0, 0, 0, 0},
10616 {0x12, 0, 0, 0, 0},
10617 {0x13, 0, 0, 0, 0},
10618 {0x14, 0, 0, 0, 0},
10619 {0x15, 0, 0, 0, 0},
10620 {0x16, 0, 0, 0, 0},
10621 {0x17, 0, 0, 0, 0},
10622 {0x18, 0, 0, 0, 0},
10623 {0x19, 0, 0, 0, 0},
10624 {0x1A, 0, 0, 0, 0},
10625 {0x1B, 0, 0, 0, 0},
10626 {0x1C, 0, 0, 0, 0},
10627 {0x1D, 0, 0, 0, 0},
10628 {0x1E, 0, 0, 0, 0},
10629 {0x1F, 0, 0, 0, 0},
10630 {0x20, 0, 0, 0, 0},
10631 {0x21, 0x88, 0x88, 0, 0},
10632 {0x22, 0x88, 0x88, 0, 0},
10633 {0x23, 0x88, 0x88, 0, 0},
10634 {0x24, 0x88, 0x88, 0, 0},
10635 {0x25, 0xc, 0xc, 0, 0},
10636 {0x26, 0, 0, 0, 0},
10637 {0x27, 0x3, 0x3, 0, 0},
10638 {0x28, 0, 0, 0, 0},
10639 {0x29, 0x3, 0x3, 0, 0},
10640 {0x2A, 0x37, 0x37, 0, 0},
10641 {0x2B, 0x3, 0x3, 0, 0},
10642 {0x2C, 0, 0, 0, 0},
10643 {0x2D, 0, 0, 0, 0},
10644 {0x2E, 0x1, 0x1, 0, 0},
10645 {0x2F, 0x1, 0x1, 0, 0},
10646 {0x30, 0, 0, 0, 0},
10647 {0x31, 0, 0, 0, 0},
10648 {0x32, 0, 0, 0, 0},
10649 {0x33, 0x11, 0x11, 0, 0},
10650 {0x34, 0xee, 0xee, 1, 1},
10651 {0x35, 0, 0, 0, 0},
10652 {0x36, 0, 0, 0, 0},
10653 {0x37, 0x3, 0x3, 0, 0},
10654 {0x38, 0x50, 0x50, 1, 1},
10655 {0x39, 0, 0, 0, 0},
10656 {0x3A, 0x50, 0x50, 1, 1},
10657 {0x3B, 0, 0, 0, 0},
10658 {0x3C, 0x6e, 0x6e, 0, 0},
10659 {0x3D, 0xf0, 0xf0, 1, 1},
10660 {0x3E, 0, 0, 0, 0},
10661 {0x3F, 0, 0, 0, 0},
10662 {0x40, 0, 0, 0, 0},
10663 {0x41, 0x3, 0x3, 0, 0},
10664 {0x42, 0x3, 0x3, 0, 0},
10665 {0x43, 0, 0, 0, 0},
10666 {0x44, 0x1e, 0x1e, 0, 0},
10667 {0x45, 0, 0, 0, 0},
10668 {0x46, 0x6e, 0x6e, 0, 0},
10669 {0x47, 0xf0, 0xf0, 1, 1},
10670 {0x48, 0, 0, 0, 0},
10671 {0x49, 0x2, 0x2, 0, 0},
10672 {0x4A, 0xff, 0xff, 1, 1},
10673 {0x4B, 0xc, 0xc, 0, 0},
10674 {0x4C, 0, 0, 0, 0},
10675 {0x4D, 0x38, 0x38, 0, 0},
10676 {0x4E, 0x70, 0x70, 1, 1},
10677 {0x4F, 0x2, 0x2, 0, 0},
10678 {0x50, 0x88, 0x88, 0, 0},
10679 {0x51, 0xc, 0xc, 0, 0},
10680 {0x52, 0, 0, 0, 0},
10681 {0x53, 0x8, 0x8, 0, 0},
10682 {0x54, 0x70, 0x70, 1, 1},
10683 {0x55, 0x2, 0x2, 0, 0},
10684 {0x56, 0xff, 0xff, 1, 1},
10685 {0x57, 0, 0, 0, 0},
10686 {0x58, 0x83, 0x83, 0, 0},
10687 {0x59, 0x77, 0x77, 1, 1},
10688 {0x5A, 0, 0, 0, 0},
10689 {0x5B, 0x2, 0x2, 0, 0},
10690 {0x5C, 0x88, 0x88, 0, 0},
10691 {0x5D, 0, 0, 0, 0},
10692 {0x5E, 0x8, 0x8, 0, 0},
10693 {0x5F, 0x77, 0x77, 1, 1},
10694 {0x60, 0x1, 0x1, 0, 0},
10695 {0x61, 0, 0, 0, 0},
10696 {0x62, 0x7, 0x7, 0, 0},
10697 {0x63, 0, 0, 0, 0},
10698 {0x64, 0x7, 0x7, 0, 0},
10699 {0x65, 0, 0, 0, 0},
10700 {0x66, 0, 0, 0, 0},
10701 {0x67, 0, 0, 1, 1},
10702 {0x68, 0, 0, 0, 0},
10703 {0x69, 0xa, 0xa, 0, 0},
10704 {0x6A, 0, 0, 0, 0},
10705 {0x6B, 0, 0, 0, 0},
10706 {0x6C, 0, 0, 0, 0},
10707 {0x6D, 0, 0, 0, 0},
10708 {0x6E, 0, 0, 0, 0},
10709 {0x6F, 0, 0, 0, 0},
10710 {0x70, 0, 0, 0, 0},
10711 {0x71, 0x2, 0x2, 0, 0},
10712 {0x72, 0, 0, 0, 0},
10713 {0x73, 0, 0, 0, 0},
10714 {0x74, 0xe, 0xe, 0, 0},
10715 {0x75, 0xe, 0xe, 0, 0},
10716 {0x76, 0xe, 0xe, 0, 0},
10717 {0x77, 0x13, 0x13, 0, 0},
10718 {0x78, 0x13, 0x13, 0, 0},
10719 {0x79, 0x1b, 0x1b, 0, 0},
10720 {0x7A, 0x1b, 0x1b, 0, 0},
10721 {0x7B, 0x55, 0x55, 0, 0},
10722 {0x7C, 0x5b, 0x5b, 0, 0},
10723 {0x7D, 0x30, 0x30, 1, 1},
10724 {0x7E, 0, 0, 0, 0},
10725 {0x7F, 0, 0, 0, 0},
10726 {0x80, 0, 0, 0, 0},
10727 {0x81, 0, 0, 0, 0},
10728 {0x82, 0, 0, 0, 0},
10729 {0x83, 0, 0, 0, 0},
10730 {0x84, 0, 0, 0, 0},
10731 {0x85, 0, 0, 0, 0},
10732 {0x86, 0, 0, 0, 0},
10733 {0x87, 0, 0, 0, 0},
10734 {0x88, 0, 0, 0, 0},
10735 {0x89, 0, 0, 0, 0},
10736 {0x8A, 0, 0, 0, 0},
10737 {0x8B, 0, 0, 0, 0},
10738 {0x8C, 0, 0, 0, 0},
10739 {0x8D, 0, 0, 0, 0},
10740 {0x8E, 0, 0, 0, 0},
10741 {0x8F, 0, 0, 0, 0},
10742 {0x90, 0, 0, 0, 0},
10743 {0x91, 0, 0, 0, 0},
10744 {0x92, 0, 0, 0, 0},
10745 {0x93, 0x70, 0x70, 0, 0},
10746 {0x94, 0x70, 0x70, 0, 0},
10747 {0x95, 0x70, 0x70, 0, 0},
10748 {0x96, 0x70, 0x70, 0, 0},
10749 {0x97, 0x70, 0x70, 0, 0},
10750 {0x98, 0x70, 0x70, 0, 0},
10751 {0x99, 0x70, 0x70, 0, 0},
10752 {0x9A, 0x70, 0x70, 0, 0},
10753 {0xFFFF, 0, 0, 0, 0},
10754};
10755
10756struct radio_regs regs_RX_2056_rev8[] = {
10757 {0x02, 0, 0, 0, 0},
10758 {0x03, 0, 0, 0, 0},
10759 {0x04, 0, 0, 0, 0},
10760 {0x05, 0, 0, 0, 0},
10761 {0x06, 0, 0, 0, 0},
10762 {0x07, 0, 0, 0, 0},
10763 {0x08, 0, 0, 0, 0},
10764 {0x09, 0, 0, 0, 0},
10765 {0x0A, 0, 0, 0, 0},
10766 {0x0B, 0, 0, 0, 0},
10767 {0x0C, 0, 0, 0, 0},
10768 {0x0D, 0, 0, 0, 0},
10769 {0x0E, 0, 0, 0, 0},
10770 {0x0F, 0, 0, 0, 0},
10771 {0x10, 0, 0, 0, 0},
10772 {0x11, 0, 0, 0, 0},
10773 {0x12, 0, 0, 0, 0},
10774 {0x13, 0, 0, 0, 0},
10775 {0x14, 0, 0, 0, 0},
10776 {0x15, 0, 0, 0, 0},
10777 {0x16, 0, 0, 0, 0},
10778 {0x17, 0, 0, 0, 0},
10779 {0x18, 0, 0, 0, 0},
10780 {0x19, 0, 0, 0, 0},
10781 {0x1A, 0, 0, 0, 0},
10782 {0x1B, 0, 0, 0, 0},
10783 {0x1C, 0, 0, 0, 0},
10784 {0x1D, 0, 0, 0, 0},
10785 {0x1E, 0, 0, 0, 0},
10786 {0x1F, 0, 0, 0, 0},
10787 {0x20, 0x3, 0x3, 0, 0},
10788 {0x21, 0, 0, 0, 0},
10789 {0x22, 0, 0, 0, 0},
10790 {0x23, 0x90, 0x90, 0, 0},
10791 {0x24, 0x55, 0x55, 0, 0},
10792 {0x25, 0x15, 0x15, 0, 0},
10793 {0x26, 0x5, 0x5, 0, 0},
10794 {0x27, 0x15, 0x15, 0, 0},
10795 {0x28, 0x5, 0x5, 0, 0},
10796 {0x29, 0x20, 0x20, 0, 0},
10797 {0x2A, 0x11, 0x11, 0, 0},
10798 {0x2B, 0x90, 0x90, 0, 0},
10799 {0x2C, 0, 0, 0, 0},
10800 {0x2D, 0x88, 0x88, 0, 0},
10801 {0x2E, 0x32, 0x32, 0, 0},
10802 {0x2F, 0x77, 0x77, 0, 0},
10803 {0x30, 0x17, 0x17, 1, 1},
10804 {0x31, 0xff, 0xff, 1, 1},
10805 {0x32, 0x20, 0x20, 0, 0},
10806 {0x33, 0, 0, 0, 0},
10807 {0x34, 0x88, 0x88, 0, 0},
10808 {0x35, 0x32, 0x32, 0, 0},
10809 {0x36, 0x77, 0x77, 0, 0},
10810 {0x37, 0x17, 0x17, 1, 1},
10811 {0x38, 0xf0, 0xf0, 1, 1},
10812 {0x39, 0x20, 0x20, 0, 0},
10813 {0x3A, 0x8, 0x8, 0, 0},
10814 {0x3B, 0x55, 0x55, 1, 1},
10815 {0x3C, 0, 0, 0, 0},
10816 {0x3D, 0x88, 0x88, 1, 1},
10817 {0x3E, 0, 0, 0, 0},
10818 {0x3F, 0x44, 0x44, 0, 0},
10819 {0x40, 0x7, 0x7, 1, 1},
10820 {0x41, 0x6, 0x6, 0, 0},
10821 {0x42, 0x4, 0x4, 0, 0},
10822 {0x43, 0, 0, 0, 0},
10823 {0x44, 0x8, 0x8, 0, 0},
10824 {0x45, 0x55, 0x55, 1, 1},
10825 {0x46, 0, 0, 0, 0},
10826 {0x47, 0x11, 0x11, 0, 0},
10827 {0x48, 0, 0, 0, 0},
10828 {0x49, 0x44, 0x44, 0, 0},
10829 {0x4A, 0x7, 0x7, 0, 0},
10830 {0x4B, 0x6, 0x6, 0, 0},
10831 {0x4C, 0x4, 0x4, 0, 0},
10832 {0x4D, 0, 0, 0, 0},
10833 {0x4E, 0, 0, 0, 0},
10834 {0x4F, 0x26, 0x26, 1, 1},
10835 {0x50, 0x26, 0x26, 1, 1},
10836 {0x51, 0xf, 0xf, 1, 1},
10837 {0x52, 0xf, 0xf, 1, 1},
10838 {0x53, 0x44, 0x44, 0, 0},
10839 {0x54, 0, 0, 0, 0},
10840 {0x55, 0, 0, 0, 0},
10841 {0x56, 0x8, 0x8, 0, 0},
10842 {0x57, 0x8, 0x8, 0, 0},
10843 {0x58, 0x7, 0x7, 0, 0},
10844 {0x59, 0x22, 0x22, 0, 0},
10845 {0x5A, 0x22, 0x22, 0, 0},
10846 {0x5B, 0x2, 0x2, 0, 0},
10847 {0x5C, 0x4, 0x4, 1, 1},
10848 {0x5D, 0x7, 0x7, 0, 0},
10849 {0x5E, 0x55, 0x55, 0, 0},
10850 {0x5F, 0x23, 0x23, 0, 0},
10851 {0x60, 0x41, 0x41, 0, 0},
10852 {0x61, 0x1, 0x1, 0, 0},
10853 {0x62, 0xa, 0xa, 0, 0},
10854 {0x63, 0, 0, 0, 0},
10855 {0x64, 0, 0, 0, 0},
10856 {0x65, 0, 0, 0, 0},
10857 {0x66, 0, 0, 0, 0},
10858 {0x67, 0, 0, 0, 0},
10859 {0x68, 0, 0, 0, 0},
10860 {0x69, 0, 0, 0, 0},
10861 {0x6A, 0, 0, 0, 0},
10862 {0x6B, 0xc, 0xc, 0, 0},
10863 {0x6C, 0, 0, 0, 0},
10864 {0x6D, 0, 0, 0, 0},
10865 {0x6E, 0, 0, 0, 0},
10866 {0x6F, 0, 0, 0, 0},
10867 {0x70, 0, 0, 0, 0},
10868 {0x71, 0, 0, 0, 0},
10869 {0x72, 0x22, 0x22, 0, 0},
10870 {0x73, 0x22, 0x22, 0, 0},
10871 {0x74, 0, 0, 1, 1},
10872 {0x75, 0xa, 0xa, 0, 0},
10873 {0x76, 0x1, 0x1, 0, 0},
10874 {0x77, 0x22, 0x22, 0, 0},
10875 {0x78, 0x30, 0x30, 0, 0},
10876 {0x79, 0, 0, 0, 0},
10877 {0x7A, 0, 0, 0, 0},
10878 {0x7B, 0, 0, 0, 0},
10879 {0x7C, 0, 0, 0, 0},
10880 {0x7D, 0x5, 0x5, 1, 1},
10881 {0x7E, 0, 0, 0, 0},
10882 {0x7F, 0, 0, 0, 0},
10883 {0x80, 0, 0, 0, 0},
10884 {0x81, 0, 0, 0, 0},
10885 {0x82, 0, 0, 0, 0},
10886 {0x83, 0, 0, 0, 0},
10887 {0x84, 0, 0, 0, 0},
10888 {0x85, 0, 0, 0, 0},
10889 {0x86, 0, 0, 0, 0},
10890 {0x87, 0, 0, 0, 0},
10891 {0x88, 0, 0, 0, 0},
10892 {0x89, 0, 0, 0, 0},
10893 {0x8A, 0, 0, 0, 0},
10894 {0x8B, 0, 0, 0, 0},
10895 {0x8C, 0, 0, 0, 0},
10896 {0x8D, 0, 0, 0, 0},
10897 {0x8E, 0, 0, 0, 0},
10898 {0x8F, 0, 0, 0, 0},
10899 {0x90, 0, 0, 0, 0},
10900 {0x91, 0, 0, 0, 0},
10901 {0x92, 0, 0, 0, 0},
10902 {0x93, 0, 0, 0, 0},
10903 {0x94, 0, 0, 0, 0},
10904 {0xFFFF, 0, 0, 0, 0},
10905};
10906
10907struct radio_regs regs_SYN_2056_rev11[] = {
10908 {0x02, 0, 0, 0, 0},
10909 {0x03, 0, 0, 0, 0},
10910 {0x04, 0, 0, 0, 0},
10911 {0x05, 0, 0, 0, 0},
10912 {0x06, 0, 0, 0, 0},
10913 {0x07, 0, 0, 0, 0},
10914 {0x08, 0, 0, 0, 0},
10915 {0x09, 0x1, 0x1, 0, 0},
10916 {0x0A, 0, 0, 0, 0},
10917 {0x0B, 0, 0, 0, 0},
10918 {0x0C, 0, 0, 0, 0},
10919 {0x0D, 0, 0, 0, 0},
10920 {0x0E, 0, 0, 0, 0},
10921 {0x0F, 0, 0, 0, 0},
10922 {0x10, 0, 0, 0, 0},
10923 {0x11, 0, 0, 0, 0},
10924 {0x12, 0, 0, 0, 0},
10925 {0x13, 0, 0, 0, 0},
10926 {0x14, 0, 0, 0, 0},
10927 {0x15, 0, 0, 0, 0},
10928 {0x16, 0, 0, 0, 0},
10929 {0x17, 0, 0, 0, 0},
10930 {0x18, 0, 0, 0, 0},
10931 {0x19, 0, 0, 0, 0},
10932 {0x1A, 0, 0, 0, 0},
10933 {0x1B, 0, 0, 0, 0},
10934 {0x1C, 0, 0, 0, 0},
10935 {0x1D, 0, 0, 0, 0},
10936 {0x1E, 0, 0, 0, 0},
10937 {0x1F, 0, 0, 0, 0},
10938 {0x20, 0, 0, 0, 0},
10939 {0x21, 0, 0, 0, 0},
10940 {0x22, 0x60, 0x60, 0, 0},
10941 {0x23, 0x6, 0x6, 0, 0},
10942 {0x24, 0xc, 0xc, 0, 0},
10943 {0x25, 0, 0, 0, 0},
10944 {0x26, 0, 0, 0, 0},
10945 {0x27, 0, 0, 0, 0},
10946 {0x28, 0x1, 0x1, 0, 0},
10947 {0x29, 0, 0, 0, 0},
10948 {0x2A, 0, 0, 0, 0},
10949 {0x2B, 0, 0, 0, 0},
10950 {0x2C, 0, 0, 0, 0},
10951 {0x2D, 0, 0, 0, 0},
10952 {0x2E, 0, 0, 0, 0},
10953 {0x2F, 0x1f, 0x1f, 0, 0},
10954 {0x30, 0x15, 0x15, 0, 0},
10955 {0x31, 0xf, 0xf, 0, 0},
10956 {0x32, 0, 0, 0, 0},
10957 {0x33, 0, 0, 0, 0},
10958 {0x34, 0, 0, 0, 0},
10959 {0x35, 0, 0, 0, 0},
10960 {0x36, 0, 0, 0, 0},
10961 {0x37, 0, 0, 0, 0},
10962 {0x38, 0, 0, 0, 0},
10963 {0x39, 0, 0, 0, 0},
10964 {0x3A, 0, 0, 0, 0},
10965 {0x3B, 0, 0, 0, 0},
10966 {0x3C, 0x13, 0x13, 0, 0},
10967 {0x3D, 0xf, 0xf, 0, 0},
10968 {0x3E, 0x18, 0x18, 0, 0},
10969 {0x3F, 0, 0, 0, 0},
10970 {0x40, 0, 0, 0, 0},
10971 {0x41, 0x20, 0x20, 0, 0},
10972 {0x42, 0x20, 0x20, 0, 0},
10973 {0x43, 0, 0, 0, 0},
10974 {0x44, 0x77, 0x77, 0, 0},
10975 {0x45, 0x7, 0x7, 0, 0},
10976 {0x46, 0x1, 0x1, 0, 0},
10977 {0x47, 0x6, 0x6, 1, 1},
10978 {0x48, 0xf, 0xf, 0, 0},
10979 {0x49, 0x3f, 0x3f, 1, 1},
10980 {0x4A, 0x32, 0x32, 0, 0},
10981 {0x4B, 0x6, 0x6, 1, 1},
10982 {0x4C, 0x6, 0x6, 1, 1},
10983 {0x4D, 0x4, 0x4, 0, 0},
10984 {0x4E, 0x2b, 0x2b, 1, 1},
10985 {0x4F, 0x1, 0x1, 0, 0},
10986 {0x50, 0x1c, 0x1c, 0, 0},
10987 {0x51, 0x2, 0x2, 0, 0},
10988 {0x52, 0x2, 0x2, 0, 0},
10989 {0x53, 0xf7, 0xf7, 1, 1},
10990 {0x54, 0xb4, 0xb4, 0, 0},
10991 {0x55, 0xd2, 0xd2, 0, 0},
10992 {0x56, 0, 0, 0, 0},
10993 {0x57, 0, 0, 0, 0},
10994 {0x58, 0x4, 0x4, 0, 0},
10995 {0x59, 0x96, 0x96, 0, 0},
10996 {0x5A, 0x3e, 0x3e, 0, 0},
10997 {0x5B, 0x3e, 0x3e, 0, 0},
10998 {0x5C, 0x13, 0x13, 0, 0},
10999 {0x5D, 0x2, 0x2, 0, 0},
11000 {0x5E, 0, 0, 0, 0},
11001 {0x5F, 0x7, 0x7, 0, 0},
11002 {0x60, 0x7, 0x7, 1, 1},
11003 {0x61, 0x8, 0x8, 0, 0},
11004 {0x62, 0x3, 0x3, 0, 0},
11005 {0x63, 0, 0, 0, 0},
11006 {0x64, 0, 0, 0, 0},
11007 {0x65, 0, 0, 0, 0},
11008 {0x66, 0, 0, 0, 0},
11009 {0x67, 0, 0, 0, 0},
11010 {0x68, 0x40, 0x40, 0, 0},
11011 {0x69, 0, 0, 0, 0},
11012 {0x6A, 0, 0, 0, 0},
11013 {0x6B, 0, 0, 0, 0},
11014 {0x6C, 0, 0, 0, 0},
11015 {0x6D, 0x1, 0x1, 0, 0},
11016 {0x6E, 0, 0, 0, 0},
11017 {0x6F, 0, 0, 0, 0},
11018 {0x70, 0x60, 0x60, 0, 0},
11019 {0x71, 0x66, 0x66, 0, 0},
11020 {0x72, 0xc, 0xc, 0, 0},
11021 {0x73, 0x66, 0x66, 0, 0},
11022 {0x74, 0x8f, 0x8f, 1, 1},
11023 {0x75, 0, 0, 0, 0},
11024 {0x76, 0xcc, 0xcc, 0, 0},
11025 {0x77, 0x1, 0x1, 0, 0},
11026 {0x78, 0x66, 0x66, 0, 0},
11027 {0x79, 0x66, 0x66, 0, 0},
11028 {0x7A, 0, 0, 0, 0},
11029 {0x7B, 0, 0, 0, 0},
11030 {0x7C, 0, 0, 0, 0},
11031 {0x7D, 0, 0, 0, 0},
11032 {0x7E, 0, 0, 0, 0},
11033 {0x7F, 0, 0, 0, 0},
11034 {0x80, 0, 0, 0, 0},
11035 {0x81, 0, 0, 0, 0},
11036 {0x82, 0, 0, 0, 0},
11037 {0x83, 0, 0, 0, 0},
11038 {0x84, 0, 0, 0, 0},
11039 {0x85, 0xff, 0xff, 0, 0},
11040 {0x86, 0, 0, 0, 0},
11041 {0x87, 0, 0, 0, 0},
11042 {0x88, 0, 0, 0, 0},
11043 {0x89, 0, 0, 0, 0},
11044 {0x8A, 0, 0, 0, 0},
11045 {0x8B, 0, 0, 0, 0},
11046 {0x8C, 0, 0, 0, 0},
11047 {0x8D, 0, 0, 0, 0},
11048 {0x8E, 0, 0, 0, 0},
11049 {0x8F, 0, 0, 0, 0},
11050 {0x90, 0, 0, 0, 0},
11051 {0x91, 0, 0, 0, 0},
11052 {0x92, 0, 0, 0, 0},
11053 {0x93, 0, 0, 0, 0},
11054 {0x94, 0, 0, 0, 0},
11055 {0x95, 0, 0, 0, 0},
11056 {0x96, 0, 0, 0, 0},
11057 {0x97, 0, 0, 0, 0},
11058 {0x98, 0, 0, 0, 0},
11059 {0x99, 0, 0, 0, 0},
11060 {0x9A, 0, 0, 0, 0},
11061 {0x9B, 0, 0, 0, 0},
11062 {0x9C, 0, 0, 0, 0},
11063 {0x9D, 0, 0, 0, 0},
11064 {0x9E, 0, 0, 0, 0},
11065 {0x9F, 0x6, 0x6, 0, 0},
11066 {0xA0, 0x66, 0x66, 0, 0},
11067 {0xA1, 0x66, 0x66, 0, 0},
11068 {0xA2, 0x66, 0x66, 0, 0},
11069 {0xA3, 0x66, 0x66, 0, 0},
11070 {0xA4, 0x66, 0x66, 0, 0},
11071 {0xA5, 0x66, 0x66, 0, 0},
11072 {0xA6, 0x66, 0x66, 0, 0},
11073 {0xA7, 0x66, 0x66, 0, 0},
11074 {0xA8, 0x66, 0x66, 0, 0},
11075 {0xA9, 0x66, 0x66, 0, 0},
11076 {0xAA, 0x66, 0x66, 0, 0},
11077 {0xAB, 0x66, 0x66, 0, 0},
11078 {0xAC, 0x66, 0x66, 0, 0},
11079 {0xAD, 0x66, 0x66, 0, 0},
11080 {0xAE, 0x66, 0x66, 0, 0},
11081 {0xAF, 0x66, 0x66, 0, 0},
11082 {0xB0, 0x66, 0x66, 0, 0},
11083 {0xB1, 0x66, 0x66, 0, 0},
11084 {0xB2, 0x66, 0x66, 0, 0},
11085 {0xB3, 0xa, 0xa, 0, 0},
11086 {0xB4, 0, 0, 0, 0},
11087 {0xB5, 0, 0, 0, 0},
11088 {0xB6, 0, 0, 0, 0},
11089 {0xFFFF, 0, 0, 0, 0},
11090};
11091
11092struct radio_regs regs_TX_2056_rev11[] = {
11093 {0x02, 0, 0, 0, 0},
11094 {0x03, 0, 0, 0, 0},
11095 {0x04, 0, 0, 0, 0},
11096 {0x05, 0, 0, 0, 0},
11097 {0x06, 0, 0, 0, 0},
11098 {0x07, 0, 0, 0, 0},
11099 {0x08, 0, 0, 0, 0},
11100 {0x09, 0, 0, 0, 0},
11101 {0x0A, 0, 0, 0, 0},
11102 {0x0B, 0, 0, 0, 0},
11103 {0x0C, 0, 0, 0, 0},
11104 {0x0D, 0, 0, 0, 0},
11105 {0x0E, 0, 0, 0, 0},
11106 {0x0F, 0, 0, 0, 0},
11107 {0x10, 0, 0, 0, 0},
11108 {0x11, 0, 0, 0, 0},
11109 {0x12, 0, 0, 0, 0},
11110 {0x13, 0, 0, 0, 0},
11111 {0x14, 0, 0, 0, 0},
11112 {0x15, 0, 0, 0, 0},
11113 {0x16, 0, 0, 0, 0},
11114 {0x17, 0, 0, 0, 0},
11115 {0x18, 0, 0, 0, 0},
11116 {0x19, 0, 0, 0, 0},
11117 {0x1A, 0, 0, 0, 0},
11118 {0x1B, 0, 0, 0, 0},
11119 {0x1C, 0, 0, 0, 0},
11120 {0x1D, 0, 0, 0, 0},
11121 {0x1E, 0, 0, 0, 0},
11122 {0x1F, 0, 0, 0, 0},
11123 {0x20, 0, 0, 0, 0},
11124 {0x21, 0x88, 0x88, 0, 0},
11125 {0x22, 0x88, 0x88, 0, 0},
11126 {0x23, 0x88, 0x88, 0, 0},
11127 {0x24, 0x88, 0x88, 0, 0},
11128 {0x25, 0xc, 0xc, 0, 0},
11129 {0x26, 0, 0, 0, 0},
11130 {0x27, 0x3, 0x3, 0, 0},
11131 {0x28, 0, 0, 0, 0},
11132 {0x29, 0x3, 0x3, 0, 0},
11133 {0x2A, 0x37, 0x37, 0, 0},
11134 {0x2B, 0x3, 0x3, 0, 0},
11135 {0x2C, 0, 0, 0, 0},
11136 {0x2D, 0, 0, 0, 0},
11137 {0x2E, 0x1, 0x1, 0, 0},
11138 {0x2F, 0x1, 0x1, 0, 0},
11139 {0x30, 0, 0, 0, 0},
11140 {0x31, 0, 0, 0, 0},
11141 {0x32, 0, 0, 0, 0},
11142 {0x33, 0x11, 0x11, 0, 0},
11143 {0x34, 0xee, 0xee, 1, 1},
11144 {0x35, 0, 0, 0, 0},
11145 {0x36, 0, 0, 0, 0},
11146 {0x37, 0x3, 0x3, 0, 0},
11147 {0x38, 0x50, 0x50, 1, 1},
11148 {0x39, 0, 0, 0, 0},
11149 {0x3A, 0x50, 0x50, 1, 1},
11150 {0x3B, 0, 0, 0, 0},
11151 {0x3C, 0x6e, 0x6e, 0, 0},
11152 {0x3D, 0xf0, 0xf0, 1, 1},
11153 {0x3E, 0, 0, 0, 0},
11154 {0x3F, 0, 0, 0, 0},
11155 {0x40, 0, 0, 0, 0},
11156 {0x41, 0x3, 0x3, 0, 0},
11157 {0x42, 0x3, 0x3, 0, 0},
11158 {0x43, 0, 0, 0, 0},
11159 {0x44, 0x1e, 0x1e, 0, 0},
11160 {0x45, 0, 0, 0, 0},
11161 {0x46, 0x6e, 0x6e, 0, 0},
11162 {0x47, 0xf0, 0xf0, 1, 1},
11163 {0x48, 0, 0, 0, 0},
11164 {0x49, 0x2, 0x2, 0, 0},
11165 {0x4A, 0xff, 0xff, 1, 1},
11166 {0x4B, 0xc, 0xc, 0, 0},
11167 {0x4C, 0, 0, 0, 0},
11168 {0x4D, 0x38, 0x38, 0, 0},
11169 {0x4E, 0x70, 0x70, 1, 1},
11170 {0x4F, 0x2, 0x2, 0, 0},
11171 {0x50, 0x88, 0x88, 0, 0},
11172 {0x51, 0xc, 0xc, 0, 0},
11173 {0x52, 0, 0, 0, 0},
11174 {0x53, 0x8, 0x8, 0, 0},
11175 {0x54, 0x70, 0x70, 1, 1},
11176 {0x55, 0x2, 0x2, 0, 0},
11177 {0x56, 0xff, 0xff, 1, 1},
11178 {0x57, 0, 0, 0, 0},
11179 {0x58, 0x83, 0x83, 0, 0},
11180 {0x59, 0x77, 0x77, 1, 1},
11181 {0x5A, 0, 0, 0, 0},
11182 {0x5B, 0x2, 0x2, 0, 0},
11183 {0x5C, 0x88, 0x88, 0, 0},
11184 {0x5D, 0, 0, 0, 0},
11185 {0x5E, 0x8, 0x8, 0, 0},
11186 {0x5F, 0x77, 0x77, 1, 1},
11187 {0x60, 0x1, 0x1, 0, 0},
11188 {0x61, 0, 0, 0, 0},
11189 {0x62, 0x7, 0x7, 0, 0},
11190 {0x63, 0, 0, 0, 0},
11191 {0x64, 0x7, 0x7, 0, 0},
11192 {0x65, 0, 0, 0, 0},
11193 {0x66, 0, 0, 0, 0},
11194 {0x67, 0, 0, 1, 1},
11195 {0x68, 0, 0, 0, 0},
11196 {0x69, 0xa, 0xa, 0, 0},
11197 {0x6A, 0, 0, 0, 0},
11198 {0x6B, 0, 0, 0, 0},
11199 {0x6C, 0, 0, 0, 0},
11200 {0x6D, 0, 0, 0, 0},
11201 {0x6E, 0, 0, 0, 0},
11202 {0x6F, 0, 0, 0, 0},
11203 {0x70, 0, 0, 0, 0},
11204 {0x71, 0x2, 0x2, 0, 0},
11205 {0x72, 0, 0, 0, 0},
11206 {0x73, 0, 0, 0, 0},
11207 {0x74, 0xe, 0xe, 0, 0},
11208 {0x75, 0xe, 0xe, 0, 0},
11209 {0x76, 0xe, 0xe, 0, 0},
11210 {0x77, 0x13, 0x13, 0, 0},
11211 {0x78, 0x13, 0x13, 0, 0},
11212 {0x79, 0x1b, 0x1b, 0, 0},
11213 {0x7A, 0x1b, 0x1b, 0, 0},
11214 {0x7B, 0x55, 0x55, 0, 0},
11215 {0x7C, 0x5b, 0x5b, 0, 0},
11216 {0x7D, 0x30, 0x30, 1, 1},
11217 {0x7E, 0, 0, 0, 0},
11218 {0x7F, 0, 0, 0, 0},
11219 {0x80, 0, 0, 0, 0},
11220 {0x81, 0, 0, 0, 0},
11221 {0x82, 0, 0, 0, 0},
11222 {0x83, 0, 0, 0, 0},
11223 {0x84, 0, 0, 0, 0},
11224 {0x85, 0, 0, 0, 0},
11225 {0x86, 0, 0, 0, 0},
11226 {0x87, 0, 0, 0, 0},
11227 {0x88, 0, 0, 0, 0},
11228 {0x89, 0, 0, 0, 0},
11229 {0x8A, 0, 0, 0, 0},
11230 {0x8B, 0, 0, 0, 0},
11231 {0x8C, 0, 0, 0, 0},
11232 {0x8D, 0, 0, 0, 0},
11233 {0x8E, 0, 0, 0, 0},
11234 {0x8F, 0, 0, 0, 0},
11235 {0x90, 0, 0, 0, 0},
11236 {0x91, 0, 0, 0, 0},
11237 {0x92, 0, 0, 0, 0},
11238 {0x93, 0x70, 0x70, 0, 0},
11239 {0x94, 0x70, 0x70, 0, 0},
11240 {0x95, 0x70, 0x70, 0, 0},
11241 {0x96, 0x70, 0x70, 0, 0},
11242 {0x97, 0x70, 0x70, 0, 0},
11243 {0x98, 0x70, 0x70, 0, 0},
11244 {0x99, 0x70, 0x70, 0, 0},
11245 {0x9A, 0x70, 0x70, 0, 0},
11246 {0xFFFF, 0, 0, 0, 0},
11247};
11248
11249struct radio_regs regs_RX_2056_rev11[] = {
11250 {0x02, 0, 0, 0, 0},
11251 {0x03, 0, 0, 0, 0},
11252 {0x04, 0, 0, 0, 0},
11253 {0x05, 0, 0, 0, 0},
11254 {0x06, 0, 0, 0, 0},
11255 {0x07, 0, 0, 0, 0},
11256 {0x08, 0, 0, 0, 0},
11257 {0x09, 0, 0, 0, 0},
11258 {0x0A, 0, 0, 0, 0},
11259 {0x0B, 0, 0, 0, 0},
11260 {0x0C, 0, 0, 0, 0},
11261 {0x0D, 0, 0, 0, 0},
11262 {0x0E, 0, 0, 0, 0},
11263 {0x0F, 0, 0, 0, 0},
11264 {0x10, 0, 0, 0, 0},
11265 {0x11, 0, 0, 0, 0},
11266 {0x12, 0, 0, 0, 0},
11267 {0x13, 0, 0, 0, 0},
11268 {0x14, 0, 0, 0, 0},
11269 {0x15, 0, 0, 0, 0},
11270 {0x16, 0, 0, 0, 0},
11271 {0x17, 0, 0, 0, 0},
11272 {0x18, 0, 0, 0, 0},
11273 {0x19, 0, 0, 0, 0},
11274 {0x1A, 0, 0, 0, 0},
11275 {0x1B, 0, 0, 0, 0},
11276 {0x1C, 0, 0, 0, 0},
11277 {0x1D, 0, 0, 0, 0},
11278 {0x1E, 0, 0, 0, 0},
11279 {0x1F, 0, 0, 0, 0},
11280 {0x20, 0x3, 0x3, 0, 0},
11281 {0x21, 0, 0, 0, 0},
11282 {0x22, 0, 0, 0, 0},
11283 {0x23, 0x90, 0x90, 0, 0},
11284 {0x24, 0x55, 0x55, 0, 0},
11285 {0x25, 0x15, 0x15, 0, 0},
11286 {0x26, 0x5, 0x5, 0, 0},
11287 {0x27, 0x15, 0x15, 0, 0},
11288 {0x28, 0x5, 0x5, 0, 0},
11289 {0x29, 0x20, 0x20, 0, 0},
11290 {0x2A, 0x11, 0x11, 0, 0},
11291 {0x2B, 0x90, 0x90, 0, 0},
11292 {0x2C, 0, 0, 0, 0},
11293 {0x2D, 0x88, 0x88, 0, 0},
11294 {0x2E, 0x32, 0x32, 0, 0},
11295 {0x2F, 0x77, 0x77, 0, 0},
11296 {0x30, 0x17, 0x17, 1, 1},
11297 {0x31, 0xff, 0xff, 1, 1},
11298 {0x32, 0x20, 0x20, 0, 0},
11299 {0x33, 0, 0, 0, 0},
11300 {0x34, 0x88, 0x88, 0, 0},
11301 {0x35, 0x32, 0x32, 0, 0},
11302 {0x36, 0x77, 0x77, 0, 0},
11303 {0x37, 0x17, 0x17, 1, 1},
11304 {0x38, 0xf0, 0xf0, 1, 1},
11305 {0x39, 0x20, 0x20, 0, 0},
11306 {0x3A, 0x8, 0x8, 0, 0},
11307 {0x3B, 0x55, 0x55, 1, 1},
11308 {0x3C, 0, 0, 0, 0},
11309 {0x3D, 0x88, 0x88, 1, 1},
11310 {0x3E, 0, 0, 0, 0},
11311 {0x3F, 0x44, 0x44, 0, 0},
11312 {0x40, 0x7, 0x7, 1, 1},
11313 {0x41, 0x6, 0x6, 0, 0},
11314 {0x42, 0x4, 0x4, 0, 0},
11315 {0x43, 0, 0, 0, 0},
11316 {0x44, 0x8, 0x8, 0, 0},
11317 {0x45, 0x55, 0x55, 1, 1},
11318 {0x46, 0, 0, 0, 0},
11319 {0x47, 0x11, 0x11, 0, 0},
11320 {0x48, 0, 0, 0, 0},
11321 {0x49, 0x44, 0x44, 0, 0},
11322 {0x4A, 0x7, 0x7, 0, 0},
11323 {0x4B, 0x6, 0x6, 0, 0},
11324 {0x4C, 0x4, 0x4, 0, 0},
11325 {0x4D, 0, 0, 0, 0},
11326 {0x4E, 0, 0, 0, 0},
11327 {0x4F, 0x26, 0x26, 1, 1},
11328 {0x50, 0x26, 0x26, 1, 1},
11329 {0x51, 0xf, 0xf, 1, 1},
11330 {0x52, 0xf, 0xf, 1, 1},
11331 {0x53, 0x44, 0x44, 0, 0},
11332 {0x54, 0, 0, 0, 0},
11333 {0x55, 0, 0, 0, 0},
11334 {0x56, 0x8, 0x8, 0, 0},
11335 {0x57, 0x8, 0x8, 0, 0},
11336 {0x58, 0x7, 0x7, 0, 0},
11337 {0x59, 0x22, 0x22, 0, 0},
11338 {0x5A, 0x22, 0x22, 0, 0},
11339 {0x5B, 0x2, 0x2, 0, 0},
11340 {0x5C, 0x4, 0x4, 1, 1},
11341 {0x5D, 0x7, 0x7, 0, 0},
11342 {0x5E, 0x55, 0x55, 0, 0},
11343 {0x5F, 0x23, 0x23, 0, 0},
11344 {0x60, 0x41, 0x41, 0, 0},
11345 {0x61, 0x1, 0x1, 0, 0},
11346 {0x62, 0xa, 0xa, 0, 0},
11347 {0x63, 0, 0, 0, 0},
11348 {0x64, 0, 0, 0, 0},
11349 {0x65, 0, 0, 0, 0},
11350 {0x66, 0, 0, 0, 0},
11351 {0x67, 0, 0, 0, 0},
11352 {0x68, 0, 0, 0, 0},
11353 {0x69, 0, 0, 0, 0},
11354 {0x6A, 0, 0, 0, 0},
11355 {0x6B, 0xc, 0xc, 0, 0},
11356 {0x6C, 0, 0, 0, 0},
11357 {0x6D, 0, 0, 0, 0},
11358 {0x6E, 0, 0, 0, 0},
11359 {0x6F, 0, 0, 0, 0},
11360 {0x70, 0, 0, 0, 0},
11361 {0x71, 0, 0, 0, 0},
11362 {0x72, 0x22, 0x22, 0, 0},
11363 {0x73, 0x22, 0x22, 0, 0},
11364 {0x74, 0, 0, 1, 1},
11365 {0x75, 0xa, 0xa, 0, 0},
11366 {0x76, 0x1, 0x1, 0, 0},
11367 {0x77, 0x22, 0x22, 0, 0},
11368 {0x78, 0x30, 0x30, 0, 0},
11369 {0x79, 0, 0, 0, 0},
11370 {0x7A, 0, 0, 0, 0},
11371 {0x7B, 0, 0, 0, 0},
11372 {0x7C, 0, 0, 0, 0},
11373 {0x7D, 0x5, 0x5, 1, 1},
11374 {0x7E, 0, 0, 0, 0},
11375 {0x7F, 0, 0, 0, 0},
11376 {0x80, 0, 0, 0, 0},
11377 {0x81, 0, 0, 0, 0},
11378 {0x82, 0, 0, 0, 0},
11379 {0x83, 0, 0, 0, 0},
11380 {0x84, 0, 0, 0, 0},
11381 {0x85, 0, 0, 0, 0},
11382 {0x86, 0, 0, 0, 0},
11383 {0x87, 0, 0, 0, 0},
11384 {0x88, 0, 0, 0, 0},
11385 {0x89, 0, 0, 0, 0},
11386 {0x8A, 0, 0, 0, 0},
11387 {0x8B, 0, 0, 0, 0},
11388 {0x8C, 0, 0, 0, 0},
11389 {0x8D, 0, 0, 0, 0},
11390 {0x8E, 0, 0, 0, 0},
11391 {0x8F, 0, 0, 0, 0},
11392 {0x90, 0, 0, 0, 0},
11393 {0x91, 0, 0, 0, 0},
11394 {0x92, 0, 0, 0, 0},
11395 {0x93, 0, 0, 0, 0},
11396 {0x94, 0, 0, 0, 0},
11397 {0xFFFF, 0, 0, 0, 0},
11398};
11399
11400struct radio_20xx_regs regs_2057_rev4[] = {
11401 {0x00, 0x84, 0},
11402 {0x01, 0, 0},
11403 {0x02, 0x60, 0},
11404 {0x03, 0x1f, 0},
11405 {0x04, 0x4, 0},
11406 {0x05, 0x2, 0},
11407 {0x06, 0x1, 0},
11408 {0x07, 0x1, 0},
11409 {0x08, 0x1, 0},
11410 {0x09, 0x69, 0},
11411 {0x0A, 0x66, 0},
11412 {0x0B, 0x6, 0},
11413 {0x0C, 0x18, 0},
11414 {0x0D, 0x3, 0},
11415 {0x0E, 0x20, 1},
11416 {0x0F, 0x20, 0},
11417 {0x10, 0, 0},
11418 {0x11, 0x7c, 0},
11419 {0x12, 0x42, 0},
11420 {0x13, 0xbd, 0},
11421 {0x14, 0x7, 0},
11422 {0x15, 0xf7, 0},
11423 {0x16, 0x8, 0},
11424 {0x17, 0x17, 0},
11425 {0x18, 0x7, 0},
11426 {0x19, 0, 0},
11427 {0x1A, 0x2, 0},
11428 {0x1B, 0x13, 0},
11429 {0x1C, 0x3e, 0},
11430 {0x1D, 0x3e, 0},
11431 {0x1E, 0x96, 0},
11432 {0x1F, 0x4, 0},
11433 {0x20, 0, 0},
11434 {0x21, 0, 0},
11435 {0x22, 0x17, 0},
11436 {0x23, 0x4, 0},
11437 {0x24, 0x1, 0},
11438 {0x25, 0x6, 0},
11439 {0x26, 0x4, 0},
11440 {0x27, 0xd, 0},
11441 {0x28, 0xd, 0},
11442 {0x29, 0x30, 0},
11443 {0x2A, 0x32, 0},
11444 {0x2B, 0x8, 0},
11445 {0x2C, 0x1c, 0},
11446 {0x2D, 0x2, 0},
11447 {0x2E, 0x4, 0},
11448 {0x2F, 0x7f, 0},
11449 {0x30, 0x27, 0},
11450 {0x31, 0, 1},
11451 {0x32, 0, 1},
11452 {0x33, 0, 1},
11453 {0x34, 0, 0},
11454 {0x35, 0x26, 1},
11455 {0x36, 0x18, 0},
11456 {0x37, 0x7, 0},
11457 {0x38, 0x66, 0},
11458 {0x39, 0x66, 0},
11459 {0x3A, 0x66, 0},
11460 {0x3B, 0x66, 0},
11461 {0x3C, 0xff, 1},
11462 {0x3D, 0xff, 1},
11463 {0x3E, 0xff, 1},
11464 {0x3F, 0xff, 1},
11465 {0x40, 0x16, 0},
11466 {0x41, 0x7, 0},
11467 {0x42, 0x19, 0},
11468 {0x43, 0x7, 0},
11469 {0x44, 0x6, 0},
11470 {0x45, 0x3, 0},
11471 {0x46, 0x1, 0},
11472 {0x47, 0x7, 0},
11473 {0x48, 0x33, 0},
11474 {0x49, 0x5, 0},
11475 {0x4A, 0x77, 0},
11476 {0x4B, 0x66, 0},
11477 {0x4C, 0x66, 0},
11478 {0x4D, 0, 0},
11479 {0x4E, 0x4, 0},
11480 {0x4F, 0xc, 0},
11481 {0x50, 0, 0},
11482 {0x51, 0x75, 0},
11483 {0x56, 0x7, 0},
11484 {0x57, 0, 0},
11485 {0x58, 0, 0},
11486 {0x59, 0xa8, 0},
11487 {0x5A, 0, 0},
11488 {0x5B, 0x1f, 0},
11489 {0x5C, 0x30, 0},
11490 {0x5D, 0x1, 0},
11491 {0x5E, 0x30, 0},
11492 {0x5F, 0x70, 0},
11493 {0x60, 0, 0},
11494 {0x61, 0, 0},
11495 {0x62, 0x33, 1},
11496 {0x63, 0x19, 0},
11497 {0x64, 0x62, 0},
11498 {0x65, 0, 0},
11499 {0x66, 0x11, 0},
11500 {0x69, 0, 0},
11501 {0x6A, 0x7e, 0},
11502 {0x6B, 0x3f, 0},
11503 {0x6C, 0x7f, 0},
11504 {0x6D, 0x78, 0},
11505 {0x6E, 0xc8, 0},
11506 {0x6F, 0x88, 0},
11507 {0x70, 0x8, 0},
11508 {0x71, 0xf, 0},
11509 {0x72, 0xbc, 0},
11510 {0x73, 0x8, 0},
11511 {0x74, 0x60, 0},
11512 {0x75, 0x1e, 0},
11513 {0x76, 0x70, 0},
11514 {0x77, 0, 0},
11515 {0x78, 0, 0},
11516 {0x79, 0, 0},
11517 {0x7A, 0x33, 0},
11518 {0x7B, 0x1e, 0},
11519 {0x7C, 0x62, 0},
11520 {0x7D, 0x11, 0},
11521 {0x80, 0x3c, 0},
11522 {0x81, 0x9c, 0},
11523 {0x82, 0xa, 0},
11524 {0x83, 0x9d, 0},
11525 {0x84, 0xa, 0},
11526 {0x85, 0, 0},
11527 {0x86, 0x40, 0},
11528 {0x87, 0x40, 0},
11529 {0x88, 0x88, 0},
11530 {0x89, 0x10, 0},
11531 {0x8A, 0xf0, 1},
11532 {0x8B, 0x10, 1},
11533 {0x8C, 0xf0, 1},
11534 {0x8D, 0, 0},
11535 {0x8E, 0, 0},
11536 {0x8F, 0x10, 0},
11537 {0x90, 0x55, 0},
11538 {0x91, 0x3f, 1},
11539 {0x92, 0x36, 1},
11540 {0x93, 0, 0},
11541 {0x94, 0, 0},
11542 {0x95, 0, 0},
11543 {0x96, 0x87, 0},
11544 {0x97, 0x11, 0},
11545 {0x98, 0, 0},
11546 {0x99, 0x33, 0},
11547 {0x9A, 0x88, 0},
11548 {0x9B, 0, 0},
11549 {0x9C, 0x87, 0},
11550 {0x9D, 0x11, 0},
11551 {0x9E, 0, 0},
11552 {0x9F, 0x33, 0},
11553 {0xA0, 0x88, 0},
11554 {0xA1, 0xe1, 0},
11555 {0xA2, 0x3f, 0},
11556 {0xA3, 0x44, 0},
11557 {0xA4, 0x8c, 1},
11558 {0xA5, 0x6d, 0},
11559 {0xA6, 0x22, 0},
11560 {0xA7, 0xbe, 0},
11561 {0xA8, 0x55, 1},
11562 {0xA9, 0xc, 0},
11563 {0xAA, 0xc, 0},
11564 {0xAB, 0xaa, 0},
11565 {0xAC, 0x2, 0},
11566 {0xAD, 0, 0},
11567 {0xAE, 0x10, 0},
11568 {0xAF, 0x1, 1},
11569 {0xB0, 0, 0},
11570 {0xB1, 0, 0},
11571 {0xB2, 0x80, 0},
11572 {0xB3, 0x60, 0},
11573 {0xB4, 0x44, 0},
11574 {0xB5, 0x55, 0},
11575 {0xB6, 0x1, 0},
11576 {0xB7, 0x55, 0},
11577 {0xB8, 0x1, 0},
11578 {0xB9, 0x5, 0},
11579 {0xBA, 0x55, 0},
11580 {0xBB, 0x55, 0},
11581 {0xC1, 0, 0},
11582 {0xC2, 0, 0},
11583 {0xC3, 0, 0},
11584 {0xC4, 0, 0},
11585 {0xC5, 0, 0},
11586 {0xC6, 0, 0},
11587 {0xC7, 0, 0},
11588 {0xC8, 0, 0},
11589 {0xC9, 0, 0},
11590 {0xCA, 0, 0},
11591 {0xCB, 0, 0},
11592 {0xCC, 0, 0},
11593 {0xCD, 0, 0},
11594 {0xCE, 0x5e, 0},
11595 {0xCF, 0xc, 0},
11596 {0xD0, 0xc, 0},
11597 {0xD1, 0xc, 0},
11598 {0xD2, 0, 0},
11599 {0xD3, 0x2b, 0},
11600 {0xD4, 0xc, 0},
11601 {0xD5, 0, 0},
11602 {0xD6, 0x75, 0},
11603 {0xDB, 0x7, 0},
11604 {0xDC, 0, 0},
11605 {0xDD, 0, 0},
11606 {0xDE, 0xa8, 0},
11607 {0xDF, 0, 0},
11608 {0xE0, 0x1f, 0},
11609 {0xE1, 0x30, 0},
11610 {0xE2, 0x1, 0},
11611 {0xE3, 0x30, 0},
11612 {0xE4, 0x70, 0},
11613 {0xE5, 0, 0},
11614 {0xE6, 0, 0},
11615 {0xE7, 0x33, 0},
11616 {0xE8, 0x19, 0},
11617 {0xE9, 0x62, 0},
11618 {0xEA, 0, 0},
11619 {0xEB, 0x11, 0},
11620 {0xEE, 0, 0},
11621 {0xEF, 0x7e, 0},
11622 {0xF0, 0x3f, 0},
11623 {0xF1, 0x7f, 0},
11624 {0xF2, 0x78, 0},
11625 {0xF3, 0xc8, 0},
11626 {0xF4, 0x88, 0},
11627 {0xF5, 0x8, 0},
11628 {0xF6, 0xf, 0},
11629 {0xF7, 0xbc, 0},
11630 {0xF8, 0x8, 0},
11631 {0xF9, 0x60, 0},
11632 {0xFA, 0x1e, 0},
11633 {0xFB, 0x70, 0},
11634 {0xFC, 0, 0},
11635 {0xFD, 0, 0},
11636 {0xFE, 0, 0},
11637 {0xFF, 0x33, 0},
11638 {0x100, 0x1e, 0},
11639 {0x101, 0x62, 0},
11640 {0x102, 0x11, 0},
11641 {0x105, 0x3c, 0},
11642 {0x106, 0x9c, 0},
11643 {0x107, 0xa, 0},
11644 {0x108, 0x9d, 0},
11645 {0x109, 0xa, 0},
11646 {0x10A, 0, 0},
11647 {0x10B, 0x40, 0},
11648 {0x10C, 0x40, 0},
11649 {0x10D, 0x88, 0},
11650 {0x10E, 0x10, 0},
11651 {0x10F, 0xf0, 1},
11652 {0x110, 0x10, 1},
11653 {0x111, 0xf0, 1},
11654 {0x112, 0, 0},
11655 {0x113, 0, 0},
11656 {0x114, 0x10, 0},
11657 {0x115, 0x55, 0},
11658 {0x116, 0x3f, 1},
11659 {0x117, 0x36, 1},
11660 {0x118, 0, 0},
11661 {0x119, 0, 0},
11662 {0x11A, 0, 0},
11663 {0x11B, 0x87, 0},
11664 {0x11C, 0x11, 0},
11665 {0x11D, 0, 0},
11666 {0x11E, 0x33, 0},
11667 {0x11F, 0x88, 0},
11668 {0x120, 0, 0},
11669 {0x121, 0x87, 0},
11670 {0x122, 0x11, 0},
11671 {0x123, 0, 0},
11672 {0x124, 0x33, 0},
11673 {0x125, 0x88, 0},
11674 {0x126, 0xe1, 0},
11675 {0x127, 0x3f, 0},
11676 {0x128, 0x44, 0},
11677 {0x129, 0x8c, 1},
11678 {0x12A, 0x6d, 0},
11679 {0x12B, 0x22, 0},
11680 {0x12C, 0xbe, 0},
11681 {0x12D, 0x55, 1},
11682 {0x12E, 0xc, 0},
11683 {0x12F, 0xc, 0},
11684 {0x130, 0xaa, 0},
11685 {0x131, 0x2, 0},
11686 {0x132, 0, 0},
11687 {0x133, 0x10, 0},
11688 {0x134, 0x1, 1},
11689 {0x135, 0, 0},
11690 {0x136, 0, 0},
11691 {0x137, 0x80, 0},
11692 {0x138, 0x60, 0},
11693 {0x139, 0x44, 0},
11694 {0x13A, 0x55, 0},
11695 {0x13B, 0x1, 0},
11696 {0x13C, 0x55, 0},
11697 {0x13D, 0x1, 0},
11698 {0x13E, 0x5, 0},
11699 {0x13F, 0x55, 0},
11700 {0x140, 0x55, 0},
11701 {0x146, 0, 0},
11702 {0x147, 0, 0},
11703 {0x148, 0, 0},
11704 {0x149, 0, 0},
11705 {0x14A, 0, 0},
11706 {0x14B, 0, 0},
11707 {0x14C, 0, 0},
11708 {0x14D, 0, 0},
11709 {0x14E, 0, 0},
11710 {0x14F, 0, 0},
11711 {0x150, 0, 0},
11712 {0x151, 0, 0},
11713 {0x152, 0, 0},
11714 {0x153, 0, 0},
11715 {0x154, 0xc, 0},
11716 {0x155, 0xc, 0},
11717 {0x156, 0xc, 0},
11718 {0x157, 0, 0},
11719 {0x158, 0x2b, 0},
11720 {0x159, 0x84, 0},
11721 {0x15A, 0x15, 0},
11722 {0x15B, 0xf, 0},
11723 {0x15C, 0, 0},
11724 {0x15D, 0, 0},
11725 {0x15E, 0, 1},
11726 {0x15F, 0, 1},
11727 {0x160, 0, 1},
11728 {0x161, 0, 1},
11729 {0x162, 0, 1},
11730 {0x163, 0, 1},
11731 {0x164, 0, 0},
11732 {0x165, 0, 0},
11733 {0x166, 0, 0},
11734 {0x167, 0, 0},
11735 {0x168, 0, 0},
11736 {0x169, 0x2, 1},
11737 {0x16A, 0, 1},
11738 {0x16B, 0, 1},
11739 {0x16C, 0, 1},
11740 {0x16D, 0, 0},
11741 {0x170, 0, 0},
11742 {0x171, 0x77, 0},
11743 {0x172, 0x77, 0},
11744 {0x173, 0x77, 0},
11745 {0x174, 0x77, 0},
11746 {0x175, 0, 0},
11747 {0x176, 0x3, 0},
11748 {0x177, 0x37, 0},
11749 {0x178, 0x3, 0},
11750 {0x179, 0, 0},
11751 {0x17A, 0x21, 0},
11752 {0x17B, 0x21, 0},
11753 {0x17C, 0, 0},
11754 {0x17D, 0xaa, 0},
11755 {0x17E, 0, 0},
11756 {0x17F, 0xaa, 0},
11757 {0x180, 0, 0},
11758 {0x190, 0, 0},
11759 {0x191, 0x77, 0},
11760 {0x192, 0x77, 0},
11761 {0x193, 0x77, 0},
11762 {0x194, 0x77, 0},
11763 {0x195, 0, 0},
11764 {0x196, 0x3, 0},
11765 {0x197, 0x37, 0},
11766 {0x198, 0x3, 0},
11767 {0x199, 0, 0},
11768 {0x19A, 0x21, 0},
11769 {0x19B, 0x21, 0},
11770 {0x19C, 0, 0},
11771 {0x19D, 0xaa, 0},
11772 {0x19E, 0, 0},
11773 {0x19F, 0xaa, 0},
11774 {0x1A0, 0, 0},
11775 {0x1A1, 0x2, 0},
11776 {0x1A2, 0xf, 0},
11777 {0x1A3, 0xf, 0},
11778 {0x1A4, 0, 1},
11779 {0x1A5, 0, 1},
11780 {0x1A6, 0, 1},
11781 {0x1A7, 0x2, 0},
11782 {0x1A8, 0xf, 0},
11783 {0x1A9, 0xf, 0},
11784 {0x1AA, 0, 1},
11785 {0x1AB, 0, 1},
11786 {0x1AC, 0, 1},
11787 {0xFFFF, 0, 0},
11788};
11789
11790struct radio_20xx_regs regs_2057_rev5[] = {
11791 {0x00, 0, 1},
11792 {0x01, 0x57, 1},
11793 {0x02, 0x20, 1},
11794 {0x03, 0x1f, 0},
11795 {0x04, 0x4, 0},
11796 {0x05, 0x2, 0},
11797 {0x06, 0x1, 0},
11798 {0x07, 0x1, 0},
11799 {0x08, 0x1, 0},
11800 {0x09, 0x69, 0},
11801 {0x0A, 0x66, 0},
11802 {0x0B, 0x6, 0},
11803 {0x0C, 0x18, 0},
11804 {0x0D, 0x3, 0},
11805 {0x0E, 0x20, 0},
11806 {0x0F, 0x20, 0},
11807 {0x10, 0, 0},
11808 {0x11, 0x7c, 0},
11809 {0x12, 0x42, 0},
11810 {0x13, 0xbd, 0},
11811 {0x14, 0x7, 0},
11812 {0x15, 0x87, 0},
11813 {0x16, 0x8, 0},
11814 {0x17, 0x17, 0},
11815 {0x18, 0x7, 0},
11816 {0x19, 0, 0},
11817 {0x1A, 0x2, 0},
11818 {0x1B, 0x13, 0},
11819 {0x1C, 0x3e, 0},
11820 {0x1D, 0x3e, 0},
11821 {0x1E, 0x96, 0},
11822 {0x1F, 0x4, 0},
11823 {0x20, 0, 0},
11824 {0x21, 0, 0},
11825 {0x22, 0x17, 0},
11826 {0x23, 0x6, 1},
11827 {0x24, 0x1, 0},
11828 {0x25, 0x6, 0},
11829 {0x26, 0x4, 0},
11830 {0x27, 0xd, 0},
11831 {0x28, 0xd, 0},
11832 {0x29, 0x30, 0},
11833 {0x2A, 0x32, 0},
11834 {0x2B, 0x8, 0},
11835 {0x2C, 0x1c, 0},
11836 {0x2D, 0x2, 0},
11837 {0x2E, 0x4, 0},
11838 {0x2F, 0x7f, 0},
11839 {0x30, 0x27, 0},
11840 {0x31, 0, 1},
11841 {0x32, 0, 1},
11842 {0x33, 0, 1},
11843 {0x34, 0, 0},
11844 {0x35, 0x20, 0},
11845 {0x36, 0x18, 0},
11846 {0x37, 0x7, 0},
11847 {0x38, 0x66, 0},
11848 {0x39, 0x66, 0},
11849 {0x3C, 0xff, 0},
11850 {0x3D, 0xff, 0},
11851 {0x40, 0x16, 0},
11852 {0x41, 0x7, 0},
11853 {0x45, 0x3, 0},
11854 {0x46, 0x1, 0},
11855 {0x47, 0x7, 0},
11856 {0x4B, 0x66, 0},
11857 {0x4C, 0x66, 0},
11858 {0x4D, 0, 0},
11859 {0x4E, 0x4, 0},
11860 {0x4F, 0xc, 0},
11861 {0x50, 0, 0},
11862 {0x51, 0x70, 1},
11863 {0x56, 0x7, 0},
11864 {0x57, 0, 0},
11865 {0x58, 0, 0},
11866 {0x59, 0x88, 1},
11867 {0x5A, 0, 0},
11868 {0x5B, 0x1f, 0},
11869 {0x5C, 0x20, 1},
11870 {0x5D, 0x1, 0},
11871 {0x5E, 0x30, 0},
11872 {0x5F, 0x70, 0},
11873 {0x60, 0, 0},
11874 {0x61, 0, 0},
11875 {0x62, 0x33, 1},
11876 {0x63, 0xf, 1},
11877 {0x64, 0xf, 1},
11878 {0x65, 0, 0},
11879 {0x66, 0x11, 0},
11880 {0x80, 0x3c, 0},
11881 {0x81, 0x1, 1},
11882 {0x82, 0xa, 0},
11883 {0x85, 0, 0},
11884 {0x86, 0x40, 0},
11885 {0x87, 0x40, 0},
11886 {0x88, 0x88, 0},
11887 {0x89, 0x10, 0},
11888 {0x8A, 0xf0, 0},
11889 {0x8B, 0x10, 0},
11890 {0x8C, 0xf0, 0},
11891 {0x8F, 0x10, 0},
11892 {0x90, 0x55, 0},
11893 {0x91, 0x3f, 1},
11894 {0x92, 0x36, 1},
11895 {0x93, 0, 0},
11896 {0x94, 0, 0},
11897 {0x95, 0, 0},
11898 {0x96, 0x87, 0},
11899 {0x97, 0x11, 0},
11900 {0x98, 0, 0},
11901 {0x99, 0x33, 0},
11902 {0x9A, 0x88, 0},
11903 {0xA1, 0x20, 1},
11904 {0xA2, 0x3f, 0},
11905 {0xA3, 0x44, 0},
11906 {0xA4, 0x8c, 0},
11907 {0xA5, 0x6c, 0},
11908 {0xA6, 0x22, 0},
11909 {0xA7, 0xbe, 0},
11910 {0xA8, 0x55, 0},
11911 {0xAA, 0xc, 0},
11912 {0xAB, 0xaa, 0},
11913 {0xAC, 0x2, 0},
11914 {0xAD, 0, 0},
11915 {0xAE, 0x10, 0},
11916 {0xAF, 0x1, 0},
11917 {0xB0, 0, 0},
11918 {0xB1, 0, 0},
11919 {0xB2, 0x80, 0},
11920 {0xB3, 0x60, 0},
11921 {0xB4, 0x44, 0},
11922 {0xB5, 0x55, 0},
11923 {0xB6, 0x1, 0},
11924 {0xB7, 0x55, 0},
11925 {0xB8, 0x1, 0},
11926 {0xB9, 0x5, 0},
11927 {0xBA, 0x55, 0},
11928 {0xBB, 0x55, 0},
11929 {0xC3, 0, 0},
11930 {0xC4, 0, 0},
11931 {0xC5, 0, 0},
11932 {0xC6, 0, 0},
11933 {0xC7, 0, 0},
11934 {0xC8, 0, 0},
11935 {0xC9, 0, 0},
11936 {0xCA, 0, 0},
11937 {0xCB, 0, 0},
11938 {0xCD, 0, 0},
11939 {0xCE, 0x5e, 0},
11940 {0xCF, 0xc, 0},
11941 {0xD0, 0xc, 0},
11942 {0xD1, 0xc, 0},
11943 {0xD2, 0, 0},
11944 {0xD3, 0x2b, 0},
11945 {0xD4, 0xc, 0},
11946 {0xD5, 0, 0},
11947 {0xD6, 0x70, 1},
11948 {0xDB, 0x7, 0},
11949 {0xDC, 0, 0},
11950 {0xDD, 0, 0},
11951 {0xDE, 0x88, 1},
11952 {0xDF, 0, 0},
11953 {0xE0, 0x1f, 0},
11954 {0xE1, 0x20, 1},
11955 {0xE2, 0x1, 0},
11956 {0xE3, 0x30, 0},
11957 {0xE4, 0x70, 0},
11958 {0xE5, 0, 0},
11959 {0xE6, 0, 0},
11960 {0xE7, 0x33, 0},
11961 {0xE8, 0xf, 1},
11962 {0xE9, 0xf, 1},
11963 {0xEA, 0, 0},
11964 {0xEB, 0x11, 0},
11965 {0x105, 0x3c, 0},
11966 {0x106, 0x1, 1},
11967 {0x107, 0xa, 0},
11968 {0x10A, 0, 0},
11969 {0x10B, 0x40, 0},
11970 {0x10C, 0x40, 0},
11971 {0x10D, 0x88, 0},
11972 {0x10E, 0x10, 0},
11973 {0x10F, 0xf0, 0},
11974 {0x110, 0x10, 0},
11975 {0x111, 0xf0, 0},
11976 {0x114, 0x10, 0},
11977 {0x115, 0x55, 0},
11978 {0x116, 0x3f, 1},
11979 {0x117, 0x36, 1},
11980 {0x118, 0, 0},
11981 {0x119, 0, 0},
11982 {0x11A, 0, 0},
11983 {0x11B, 0x87, 0},
11984 {0x11C, 0x11, 0},
11985 {0x11D, 0, 0},
11986 {0x11E, 0x33, 0},
11987 {0x11F, 0x88, 0},
11988 {0x126, 0x20, 1},
11989 {0x127, 0x3f, 0},
11990 {0x128, 0x44, 0},
11991 {0x129, 0x8c, 0},
11992 {0x12A, 0x6c, 0},
11993 {0x12B, 0x22, 0},
11994 {0x12C, 0xbe, 0},
11995 {0x12D, 0x55, 0},
11996 {0x12F, 0xc, 0},
11997 {0x130, 0xaa, 0},
11998 {0x131, 0x2, 0},
11999 {0x132, 0, 0},
12000 {0x133, 0x10, 0},
12001 {0x134, 0x1, 0},
12002 {0x135, 0, 0},
12003 {0x136, 0, 0},
12004 {0x137, 0x80, 0},
12005 {0x138, 0x60, 0},
12006 {0x139, 0x44, 0},
12007 {0x13A, 0x55, 0},
12008 {0x13B, 0x1, 0},
12009 {0x13C, 0x55, 0},
12010 {0x13D, 0x1, 0},
12011 {0x13E, 0x5, 0},
12012 {0x13F, 0x55, 0},
12013 {0x140, 0x55, 0},
12014 {0x148, 0, 0},
12015 {0x149, 0, 0},
12016 {0x14A, 0, 0},
12017 {0x14B, 0, 0},
12018 {0x14C, 0, 0},
12019 {0x14D, 0, 0},
12020 {0x14E, 0, 0},
12021 {0x14F, 0, 0},
12022 {0x150, 0, 0},
12023 {0x154, 0xc, 0},
12024 {0x155, 0xc, 0},
12025 {0x156, 0xc, 0},
12026 {0x157, 0, 0},
12027 {0x158, 0x2b, 0},
12028 {0x159, 0x84, 0},
12029 {0x15A, 0x15, 0},
12030 {0x15B, 0xf, 0},
12031 {0x15C, 0, 0},
12032 {0x15D, 0, 0},
12033 {0x15E, 0, 1},
12034 {0x15F, 0, 1},
12035 {0x160, 0, 1},
12036 {0x161, 0, 1},
12037 {0x162, 0, 1},
12038 {0x163, 0, 1},
12039 {0x164, 0, 0},
12040 {0x165, 0, 0},
12041 {0x166, 0, 0},
12042 {0x167, 0, 0},
12043 {0x168, 0, 0},
12044 {0x169, 0, 0},
12045 {0x16A, 0, 1},
12046 {0x16B, 0, 1},
12047 {0x16C, 0, 1},
12048 {0x16D, 0, 0},
12049 {0x170, 0, 0},
12050 {0x171, 0x77, 0},
12051 {0x172, 0x77, 0},
12052 {0x173, 0x77, 0},
12053 {0x174, 0x77, 0},
12054 {0x175, 0, 0},
12055 {0x176, 0x3, 0},
12056 {0x177, 0x37, 0},
12057 {0x178, 0x3, 0},
12058 {0x179, 0, 0},
12059 {0x17B, 0x21, 0},
12060 {0x17C, 0, 0},
12061 {0x17D, 0xaa, 0},
12062 {0x17E, 0, 0},
12063 {0x190, 0, 0},
12064 {0x191, 0x77, 0},
12065 {0x192, 0x77, 0},
12066 {0x193, 0x77, 0},
12067 {0x194, 0x77, 0},
12068 {0x195, 0, 0},
12069 {0x196, 0x3, 0},
12070 {0x197, 0x37, 0},
12071 {0x198, 0x3, 0},
12072 {0x199, 0, 0},
12073 {0x19B, 0x21, 0},
12074 {0x19C, 0, 0},
12075 {0x19D, 0xaa, 0},
12076 {0x19E, 0, 0},
12077 {0x1A1, 0x2, 0},
12078 {0x1A2, 0xf, 0},
12079 {0x1A3, 0xf, 0},
12080 {0x1A4, 0, 1},
12081 {0x1A5, 0, 1},
12082 {0x1A6, 0, 1},
12083 {0x1A7, 0x2, 0},
12084 {0x1A8, 0xf, 0},
12085 {0x1A9, 0xf, 0},
12086 {0x1AA, 0, 1},
12087 {0x1AB, 0, 1},
12088 {0x1AC, 0, 1},
12089 {0x1AD, 0x84, 0},
12090 {0x1AE, 0x60, 0},
12091 {0x1AF, 0x47, 0},
12092 {0x1B0, 0x47, 0},
12093 {0x1B1, 0, 0},
12094 {0x1B2, 0, 0},
12095 {0x1B3, 0, 0},
12096 {0x1B4, 0, 0},
12097 {0x1B5, 0, 0},
12098 {0x1B6, 0, 0},
12099 {0x1B7, 0xc, 1},
12100 {0x1B8, 0, 0},
12101 {0x1B9, 0, 0},
12102 {0x1BA, 0, 0},
12103 {0x1BB, 0, 0},
12104 {0x1BC, 0, 0},
12105 {0x1BD, 0, 0},
12106 {0x1BE, 0, 0},
12107 {0x1BF, 0, 0},
12108 {0x1C0, 0, 0},
12109 {0x1C1, 0x1, 1},
12110 {0x1C2, 0x80, 1},
12111 {0x1C3, 0, 0},
12112 {0x1C4, 0, 0},
12113 {0x1C5, 0, 0},
12114 {0x1C6, 0, 0},
12115 {0x1C7, 0, 0},
12116 {0x1C8, 0, 0},
12117 {0x1C9, 0, 0},
12118 {0x1CA, 0, 0},
12119 {0xFFFF, 0, 0}
12120};
12121
12122struct radio_20xx_regs regs_2057_rev5v1[] = {
12123 {0x00, 0x15, 1},
12124 {0x01, 0x57, 1},
12125 {0x02, 0x20, 1},
12126 {0x03, 0x1f, 0},
12127 {0x04, 0x4, 0},
12128 {0x05, 0x2, 0},
12129 {0x06, 0x1, 0},
12130 {0x07, 0x1, 0},
12131 {0x08, 0x1, 0},
12132 {0x09, 0x69, 0},
12133 {0x0A, 0x66, 0},
12134 {0x0B, 0x6, 0},
12135 {0x0C, 0x18, 0},
12136 {0x0D, 0x3, 0},
12137 {0x0E, 0x20, 0},
12138 {0x0F, 0x20, 0},
12139 {0x10, 0, 0},
12140 {0x11, 0x7c, 0},
12141 {0x12, 0x42, 0},
12142 {0x13, 0xbd, 0},
12143 {0x14, 0x7, 0},
12144 {0x15, 0x87, 0},
12145 {0x16, 0x8, 0},
12146 {0x17, 0x17, 0},
12147 {0x18, 0x7, 0},
12148 {0x19, 0, 0},
12149 {0x1A, 0x2, 0},
12150 {0x1B, 0x13, 0},
12151 {0x1C, 0x3e, 0},
12152 {0x1D, 0x3e, 0},
12153 {0x1E, 0x96, 0},
12154 {0x1F, 0x4, 0},
12155 {0x20, 0, 0},
12156 {0x21, 0, 0},
12157 {0x22, 0x17, 0},
12158 {0x23, 0x6, 1},
12159 {0x24, 0x1, 0},
12160 {0x25, 0x6, 0},
12161 {0x26, 0x4, 0},
12162 {0x27, 0xd, 0},
12163 {0x28, 0xd, 0},
12164 {0x29, 0x30, 0},
12165 {0x2A, 0x32, 0},
12166 {0x2B, 0x8, 0},
12167 {0x2C, 0x1c, 0},
12168 {0x2D, 0x2, 0},
12169 {0x2E, 0x4, 0},
12170 {0x2F, 0x7f, 0},
12171 {0x30, 0x27, 0},
12172 {0x31, 0, 1},
12173 {0x32, 0, 1},
12174 {0x33, 0, 1},
12175 {0x34, 0, 0},
12176 {0x35, 0x20, 0},
12177 {0x36, 0x18, 0},
12178 {0x37, 0x7, 0},
12179 {0x38, 0x66, 0},
12180 {0x39, 0x66, 0},
12181 {0x3C, 0xff, 0},
12182 {0x3D, 0xff, 0},
12183 {0x40, 0x16, 0},
12184 {0x41, 0x7, 0},
12185 {0x45, 0x3, 0},
12186 {0x46, 0x1, 0},
12187 {0x47, 0x7, 0},
12188 {0x4B, 0x66, 0},
12189 {0x4C, 0x66, 0},
12190 {0x4D, 0, 0},
12191 {0x4E, 0x4, 0},
12192 {0x4F, 0xc, 0},
12193 {0x50, 0, 0},
12194 {0x51, 0x70, 1},
12195 {0x56, 0x7, 0},
12196 {0x57, 0, 0},
12197 {0x58, 0, 0},
12198 {0x59, 0x88, 1},
12199 {0x5A, 0, 0},
12200 {0x5B, 0x1f, 0},
12201 {0x5C, 0x20, 1},
12202 {0x5D, 0x1, 0},
12203 {0x5E, 0x30, 0},
12204 {0x5F, 0x70, 0},
12205 {0x60, 0, 0},
12206 {0x61, 0, 0},
12207 {0x62, 0x33, 1},
12208 {0x63, 0xf, 1},
12209 {0x64, 0xf, 1},
12210 {0x65, 0, 0},
12211 {0x66, 0x11, 0},
12212 {0x80, 0x3c, 0},
12213 {0x81, 0x1, 1},
12214 {0x82, 0xa, 0},
12215 {0x85, 0, 0},
12216 {0x86, 0x40, 0},
12217 {0x87, 0x40, 0},
12218 {0x88, 0x88, 0},
12219 {0x89, 0x10, 0},
12220 {0x8A, 0xf0, 0},
12221 {0x8B, 0x10, 0},
12222 {0x8C, 0xf0, 0},
12223 {0x8F, 0x10, 0},
12224 {0x90, 0x55, 0},
12225 {0x91, 0x3f, 1},
12226 {0x92, 0x36, 1},
12227 {0x93, 0, 0},
12228 {0x94, 0, 0},
12229 {0x95, 0, 0},
12230 {0x96, 0x87, 0},
12231 {0x97, 0x11, 0},
12232 {0x98, 0, 0},
12233 {0x99, 0x33, 0},
12234 {0x9A, 0x88, 0},
12235 {0xA1, 0x20, 1},
12236 {0xA2, 0x3f, 0},
12237 {0xA3, 0x44, 0},
12238 {0xA4, 0x8c, 0},
12239 {0xA5, 0x6c, 0},
12240 {0xA6, 0x22, 0},
12241 {0xA7, 0xbe, 0},
12242 {0xA8, 0x55, 0},
12243 {0xAA, 0xc, 0},
12244 {0xAB, 0xaa, 0},
12245 {0xAC, 0x2, 0},
12246 {0xAD, 0, 0},
12247 {0xAE, 0x10, 0},
12248 {0xAF, 0x1, 0},
12249 {0xB0, 0, 0},
12250 {0xB1, 0, 0},
12251 {0xB2, 0x80, 0},
12252 {0xB3, 0x60, 0},
12253 {0xB4, 0x44, 0},
12254 {0xB5, 0x55, 0},
12255 {0xB6, 0x1, 0},
12256 {0xB7, 0x55, 0},
12257 {0xB8, 0x1, 0},
12258 {0xB9, 0x5, 0},
12259 {0xBA, 0x55, 0},
12260 {0xBB, 0x55, 0},
12261 {0xC3, 0, 0},
12262 {0xC4, 0, 0},
12263 {0xC5, 0, 0},
12264 {0xC6, 0, 0},
12265 {0xC7, 0, 0},
12266 {0xC8, 0, 0},
12267 {0xC9, 0x1, 1},
12268 {0xCA, 0, 0},
12269 {0xCB, 0, 0},
12270 {0xCD, 0, 0},
12271 {0xCE, 0x5e, 0},
12272 {0xCF, 0xc, 0},
12273 {0xD0, 0xc, 0},
12274 {0xD1, 0xc, 0},
12275 {0xD2, 0, 0},
12276 {0xD3, 0x2b, 0},
12277 {0xD4, 0xc, 0},
12278 {0xD5, 0, 0},
12279 {0xD6, 0x70, 1},
12280 {0xDB, 0x7, 0},
12281 {0xDC, 0, 0},
12282 {0xDD, 0, 0},
12283 {0xDE, 0x88, 1},
12284 {0xDF, 0, 0},
12285 {0xE0, 0x1f, 0},
12286 {0xE1, 0x20, 1},
12287 {0xE2, 0x1, 0},
12288 {0xE3, 0x30, 0},
12289 {0xE4, 0x70, 0},
12290 {0xE5, 0, 0},
12291 {0xE6, 0, 0},
12292 {0xE7, 0x33, 0},
12293 {0xE8, 0xf, 1},
12294 {0xE9, 0xf, 1},
12295 {0xEA, 0, 0},
12296 {0xEB, 0x11, 0},
12297 {0x105, 0x3c, 0},
12298 {0x106, 0x1, 1},
12299 {0x107, 0xa, 0},
12300 {0x10A, 0, 0},
12301 {0x10B, 0x40, 0},
12302 {0x10C, 0x40, 0},
12303 {0x10D, 0x88, 0},
12304 {0x10E, 0x10, 0},
12305 {0x10F, 0xf0, 0},
12306 {0x110, 0x10, 0},
12307 {0x111, 0xf0, 0},
12308 {0x114, 0x10, 0},
12309 {0x115, 0x55, 0},
12310 {0x116, 0x3f, 1},
12311 {0x117, 0x36, 1},
12312 {0x118, 0, 0},
12313 {0x119, 0, 0},
12314 {0x11A, 0, 0},
12315 {0x11B, 0x87, 0},
12316 {0x11C, 0x11, 0},
12317 {0x11D, 0, 0},
12318 {0x11E, 0x33, 0},
12319 {0x11F, 0x88, 0},
12320 {0x126, 0x20, 1},
12321 {0x127, 0x3f, 0},
12322 {0x128, 0x44, 0},
12323 {0x129, 0x8c, 0},
12324 {0x12A, 0x6c, 0},
12325 {0x12B, 0x22, 0},
12326 {0x12C, 0xbe, 0},
12327 {0x12D, 0x55, 0},
12328 {0x12F, 0xc, 0},
12329 {0x130, 0xaa, 0},
12330 {0x131, 0x2, 0},
12331 {0x132, 0, 0},
12332 {0x133, 0x10, 0},
12333 {0x134, 0x1, 0},
12334 {0x135, 0, 0},
12335 {0x136, 0, 0},
12336 {0x137, 0x80, 0},
12337 {0x138, 0x60, 0},
12338 {0x139, 0x44, 0},
12339 {0x13A, 0x55, 0},
12340 {0x13B, 0x1, 0},
12341 {0x13C, 0x55, 0},
12342 {0x13D, 0x1, 0},
12343 {0x13E, 0x5, 0},
12344 {0x13F, 0x55, 0},
12345 {0x140, 0x55, 0},
12346 {0x148, 0, 0},
12347 {0x149, 0, 0},
12348 {0x14A, 0, 0},
12349 {0x14B, 0, 0},
12350 {0x14C, 0, 0},
12351 {0x14D, 0, 0},
12352 {0x14E, 0x1, 1},
12353 {0x14F, 0, 0},
12354 {0x150, 0, 0},
12355 {0x154, 0xc, 0},
12356 {0x155, 0xc, 0},
12357 {0x156, 0xc, 0},
12358 {0x157, 0, 0},
12359 {0x158, 0x2b, 0},
12360 {0x159, 0x84, 0},
12361 {0x15A, 0x15, 0},
12362 {0x15B, 0xf, 0},
12363 {0x15C, 0, 0},
12364 {0x15D, 0, 0},
12365 {0x15E, 0, 1},
12366 {0x15F, 0, 1},
12367 {0x160, 0, 1},
12368 {0x161, 0, 1},
12369 {0x162, 0, 1},
12370 {0x163, 0, 1},
12371 {0x164, 0, 0},
12372 {0x165, 0, 0},
12373 {0x166, 0, 0},
12374 {0x167, 0, 0},
12375 {0x168, 0, 0},
12376 {0x169, 0, 0},
12377 {0x16A, 0, 1},
12378 {0x16B, 0, 1},
12379 {0x16C, 0, 1},
12380 {0x16D, 0, 0},
12381 {0x170, 0, 0},
12382 {0x171, 0x77, 0},
12383 {0x172, 0x77, 0},
12384 {0x173, 0x77, 0},
12385 {0x174, 0x77, 0},
12386 {0x175, 0, 0},
12387 {0x176, 0x3, 0},
12388 {0x177, 0x37, 0},
12389 {0x178, 0x3, 0},
12390 {0x179, 0, 0},
12391 {0x17B, 0x21, 0},
12392 {0x17C, 0, 0},
12393 {0x17D, 0xaa, 0},
12394 {0x17E, 0, 0},
12395 {0x190, 0, 0},
12396 {0x191, 0x77, 0},
12397 {0x192, 0x77, 0},
12398 {0x193, 0x77, 0},
12399 {0x194, 0x77, 0},
12400 {0x195, 0, 0},
12401 {0x196, 0x3, 0},
12402 {0x197, 0x37, 0},
12403 {0x198, 0x3, 0},
12404 {0x199, 0, 0},
12405 {0x19B, 0x21, 0},
12406 {0x19C, 0, 0},
12407 {0x19D, 0xaa, 0},
12408 {0x19E, 0, 0},
12409 {0x1A1, 0x2, 0},
12410 {0x1A2, 0xf, 0},
12411 {0x1A3, 0xf, 0},
12412 {0x1A4, 0, 1},
12413 {0x1A5, 0, 1},
12414 {0x1A6, 0, 1},
12415 {0x1A7, 0x2, 0},
12416 {0x1A8, 0xf, 0},
12417 {0x1A9, 0xf, 0},
12418 {0x1AA, 0, 1},
12419 {0x1AB, 0, 1},
12420 {0x1AC, 0, 1},
12421 {0x1AD, 0x84, 0},
12422 {0x1AE, 0x60, 0},
12423 {0x1AF, 0x47, 0},
12424 {0x1B0, 0x47, 0},
12425 {0x1B1, 0, 0},
12426 {0x1B2, 0, 0},
12427 {0x1B3, 0, 0},
12428 {0x1B4, 0, 0},
12429 {0x1B5, 0, 0},
12430 {0x1B6, 0, 0},
12431 {0x1B7, 0xc, 1},
12432 {0x1B8, 0, 0},
12433 {0x1B9, 0, 0},
12434 {0x1BA, 0, 0},
12435 {0x1BB, 0, 0},
12436 {0x1BC, 0, 0},
12437 {0x1BD, 0, 0},
12438 {0x1BE, 0, 0},
12439 {0x1BF, 0, 0},
12440 {0x1C0, 0, 0},
12441 {0x1C1, 0x1, 1},
12442 {0x1C2, 0x80, 1},
12443 {0x1C3, 0, 0},
12444 {0x1C4, 0, 0},
12445 {0x1C5, 0, 0},
12446 {0x1C6, 0, 0},
12447 {0x1C7, 0, 0},
12448 {0x1C8, 0, 0},
12449 {0x1C9, 0, 0},
12450 {0x1CA, 0, 0},
12451 {0xFFFF, 0, 0}
12452};
12453
12454struct radio_20xx_regs regs_2057_rev7[] = {
12455 {0x00, 0, 1},
12456 {0x01, 0x57, 1},
12457 {0x02, 0x20, 1},
12458 {0x03, 0x1f, 0},
12459 {0x04, 0x4, 0},
12460 {0x05, 0x2, 0},
12461 {0x06, 0x1, 0},
12462 {0x07, 0x1, 0},
12463 {0x08, 0x1, 0},
12464 {0x09, 0x69, 0},
12465 {0x0A, 0x66, 0},
12466 {0x0B, 0x6, 0},
12467 {0x0C, 0x18, 0},
12468 {0x0D, 0x3, 0},
12469 {0x0E, 0x20, 0},
12470 {0x0F, 0x20, 0},
12471 {0x10, 0, 0},
12472 {0x11, 0x7c, 0},
12473 {0x12, 0x42, 0},
12474 {0x13, 0xbd, 0},
12475 {0x14, 0x7, 0},
12476 {0x15, 0x87, 0},
12477 {0x16, 0x8, 0},
12478 {0x17, 0x17, 0},
12479 {0x18, 0x7, 0},
12480 {0x19, 0, 0},
12481 {0x1A, 0x2, 0},
12482 {0x1B, 0x13, 0},
12483 {0x1C, 0x3e, 0},
12484 {0x1D, 0x3e, 0},
12485 {0x1E, 0x96, 0},
12486 {0x1F, 0x4, 0},
12487 {0x20, 0, 0},
12488 {0x21, 0, 0},
12489 {0x22, 0x17, 0},
12490 {0x23, 0x6, 0},
12491 {0x24, 0x1, 0},
12492 {0x25, 0x6, 0},
12493 {0x26, 0x4, 0},
12494 {0x27, 0xd, 0},
12495 {0x28, 0xd, 0},
12496 {0x29, 0x30, 0},
12497 {0x2A, 0x32, 0},
12498 {0x2B, 0x8, 0},
12499 {0x2C, 0x1c, 0},
12500 {0x2D, 0x2, 0},
12501 {0x2E, 0x4, 0},
12502 {0x2F, 0x7f, 0},
12503 {0x30, 0x27, 0},
12504 {0x31, 0, 1},
12505 {0x32, 0, 1},
12506 {0x33, 0, 1},
12507 {0x34, 0, 0},
12508 {0x35, 0x20, 0},
12509 {0x36, 0x18, 0},
12510 {0x37, 0x7, 0},
12511 {0x38, 0x66, 0},
12512 {0x39, 0x66, 0},
12513 {0x3A, 0x66, 0},
12514 {0x3B, 0x66, 0},
12515 {0x3C, 0xff, 0},
12516 {0x3D, 0xff, 0},
12517 {0x3E, 0xff, 0},
12518 {0x3F, 0xff, 0},
12519 {0x40, 0x16, 0},
12520 {0x41, 0x7, 0},
12521 {0x42, 0x19, 0},
12522 {0x43, 0x7, 0},
12523 {0x44, 0x6, 0},
12524 {0x45, 0x3, 0},
12525 {0x46, 0x1, 0},
12526 {0x47, 0x7, 0},
12527 {0x48, 0x33, 0},
12528 {0x49, 0x5, 0},
12529 {0x4A, 0x77, 0},
12530 {0x4B, 0x66, 0},
12531 {0x4C, 0x66, 0},
12532 {0x4D, 0, 0},
12533 {0x4E, 0x4, 0},
12534 {0x4F, 0xc, 0},
12535 {0x50, 0, 0},
12536 {0x51, 0x70, 1},
12537 {0x56, 0x7, 0},
12538 {0x57, 0, 0},
12539 {0x58, 0, 0},
12540 {0x59, 0x88, 1},
12541 {0x5A, 0, 0},
12542 {0x5B, 0x1f, 0},
12543 {0x5C, 0x20, 1},
12544 {0x5D, 0x1, 0},
12545 {0x5E, 0x30, 0},
12546 {0x5F, 0x70, 0},
12547 {0x60, 0, 0},
12548 {0x61, 0, 0},
12549 {0x62, 0x33, 1},
12550 {0x63, 0xf, 1},
12551 {0x64, 0x13, 1},
12552 {0x65, 0, 0},
12553 {0x66, 0xee, 1},
12554 {0x69, 0, 0},
12555 {0x6A, 0x7e, 0},
12556 {0x6B, 0x3f, 0},
12557 {0x6C, 0x7f, 0},
12558 {0x6D, 0x78, 0},
12559 {0x6E, 0x58, 1},
12560 {0x6F, 0x88, 0},
12561 {0x70, 0x8, 0},
12562 {0x71, 0xf, 0},
12563 {0x72, 0xbc, 0},
12564 {0x73, 0x8, 0},
12565 {0x74, 0x60, 0},
12566 {0x75, 0x13, 1},
12567 {0x76, 0x70, 0},
12568 {0x77, 0, 0},
12569 {0x78, 0, 0},
12570 {0x79, 0, 0},
12571 {0x7A, 0x33, 0},
12572 {0x7B, 0x13, 1},
12573 {0x7C, 0x14, 1},
12574 {0x7D, 0xee, 1},
12575 {0x80, 0x3c, 0},
12576 {0x81, 0x1, 1},
12577 {0x82, 0xa, 0},
12578 {0x83, 0x9d, 0},
12579 {0x84, 0xa, 0},
12580 {0x85, 0, 0},
12581 {0x86, 0x40, 0},
12582 {0x87, 0x40, 0},
12583 {0x88, 0x88, 0},
12584 {0x89, 0x10, 0},
12585 {0x8A, 0xf0, 0},
12586 {0x8B, 0x10, 0},
12587 {0x8C, 0xf0, 0},
12588 {0x8D, 0, 0},
12589 {0x8E, 0, 0},
12590 {0x8F, 0x10, 0},
12591 {0x90, 0x55, 0},
12592 {0x91, 0x3f, 1},
12593 {0x92, 0x36, 1},
12594 {0x93, 0, 0},
12595 {0x94, 0, 0},
12596 {0x95, 0, 0},
12597 {0x96, 0x87, 0},
12598 {0x97, 0x11, 0},
12599 {0x98, 0, 0},
12600 {0x99, 0x33, 0},
12601 {0x9A, 0x88, 0},
12602 {0x9B, 0, 0},
12603 {0x9C, 0x87, 0},
12604 {0x9D, 0x11, 0},
12605 {0x9E, 0, 0},
12606 {0x9F, 0x33, 0},
12607 {0xA0, 0x88, 0},
12608 {0xA1, 0x20, 1},
12609 {0xA2, 0x3f, 0},
12610 {0xA3, 0x44, 0},
12611 {0xA4, 0x8c, 0},
12612 {0xA5, 0x6c, 0},
12613 {0xA6, 0x22, 0},
12614 {0xA7, 0xbe, 0},
12615 {0xA8, 0x55, 0},
12616 {0xAA, 0xc, 0},
12617 {0xAB, 0xaa, 0},
12618 {0xAC, 0x2, 0},
12619 {0xAD, 0, 0},
12620 {0xAE, 0x10, 0},
12621 {0xAF, 0x1, 0},
12622 {0xB0, 0, 0},
12623 {0xB1, 0, 0},
12624 {0xB2, 0x80, 0},
12625 {0xB3, 0x60, 0},
12626 {0xB4, 0x44, 0},
12627 {0xB5, 0x55, 0},
12628 {0xB6, 0x1, 0},
12629 {0xB7, 0x55, 0},
12630 {0xB8, 0x1, 0},
12631 {0xB9, 0x5, 0},
12632 {0xBA, 0x55, 0},
12633 {0xBB, 0x55, 0},
12634 {0xC1, 0, 0},
12635 {0xC2, 0, 0},
12636 {0xC3, 0, 0},
12637 {0xC4, 0, 0},
12638 {0xC5, 0, 0},
12639 {0xC6, 0, 0},
12640 {0xC7, 0, 0},
12641 {0xC8, 0, 0},
12642 {0xC9, 0, 0},
12643 {0xCA, 0, 0},
12644 {0xCB, 0, 0},
12645 {0xCC, 0, 0},
12646 {0xCD, 0, 0},
12647 {0xCE, 0x5e, 0},
12648 {0xCF, 0xc, 0},
12649 {0xD0, 0xc, 0},
12650 {0xD1, 0xc, 0},
12651 {0xD2, 0, 0},
12652 {0xD3, 0x2b, 0},
12653 {0xD4, 0xc, 0},
12654 {0xD5, 0, 0},
12655 {0xD6, 0x70, 1},
12656 {0xDB, 0x7, 0},
12657 {0xDC, 0, 0},
12658 {0xDD, 0, 0},
12659 {0xDE, 0x88, 1},
12660 {0xDF, 0, 0},
12661 {0xE0, 0x1f, 0},
12662 {0xE1, 0x20, 1},
12663 {0xE2, 0x1, 0},
12664 {0xE3, 0x30, 0},
12665 {0xE4, 0x70, 0},
12666 {0xE5, 0, 0},
12667 {0xE6, 0, 0},
12668 {0xE7, 0x33, 0},
12669 {0xE8, 0xf, 1},
12670 {0xE9, 0x13, 1},
12671 {0xEA, 0, 0},
12672 {0xEB, 0xee, 1},
12673 {0xEE, 0, 0},
12674 {0xEF, 0x7e, 0},
12675 {0xF0, 0x3f, 0},
12676 {0xF1, 0x7f, 0},
12677 {0xF2, 0x78, 0},
12678 {0xF3, 0x58, 1},
12679 {0xF4, 0x88, 0},
12680 {0xF5, 0x8, 0},
12681 {0xF6, 0xf, 0},
12682 {0xF7, 0xbc, 0},
12683 {0xF8, 0x8, 0},
12684 {0xF9, 0x60, 0},
12685 {0xFA, 0x13, 1},
12686 {0xFB, 0x70, 0},
12687 {0xFC, 0, 0},
12688 {0xFD, 0, 0},
12689 {0xFE, 0, 0},
12690 {0xFF, 0x33, 0},
12691 {0x100, 0x13, 1},
12692 {0x101, 0x14, 1},
12693 {0x102, 0xee, 1},
12694 {0x105, 0x3c, 0},
12695 {0x106, 0x1, 1},
12696 {0x107, 0xa, 0},
12697 {0x108, 0x9d, 0},
12698 {0x109, 0xa, 0},
12699 {0x10A, 0, 0},
12700 {0x10B, 0x40, 0},
12701 {0x10C, 0x40, 0},
12702 {0x10D, 0x88, 0},
12703 {0x10E, 0x10, 0},
12704 {0x10F, 0xf0, 0},
12705 {0x110, 0x10, 0},
12706 {0x111, 0xf0, 0},
12707 {0x112, 0, 0},
12708 {0x113, 0, 0},
12709 {0x114, 0x10, 0},
12710 {0x115, 0x55, 0},
12711 {0x116, 0x3f, 1},
12712 {0x117, 0x36, 1},
12713 {0x118, 0, 0},
12714 {0x119, 0, 0},
12715 {0x11A, 0, 0},
12716 {0x11B, 0x87, 0},
12717 {0x11C, 0x11, 0},
12718 {0x11D, 0, 0},
12719 {0x11E, 0x33, 0},
12720 {0x11F, 0x88, 0},
12721 {0x120, 0, 0},
12722 {0x121, 0x87, 0},
12723 {0x122, 0x11, 0},
12724 {0x123, 0, 0},
12725 {0x124, 0x33, 0},
12726 {0x125, 0x88, 0},
12727 {0x126, 0x20, 1},
12728 {0x127, 0x3f, 0},
12729 {0x128, 0x44, 0},
12730 {0x129, 0x8c, 0},
12731 {0x12A, 0x6c, 0},
12732 {0x12B, 0x22, 0},
12733 {0x12C, 0xbe, 0},
12734 {0x12D, 0x55, 0},
12735 {0x12F, 0xc, 0},
12736 {0x130, 0xaa, 0},
12737 {0x131, 0x2, 0},
12738 {0x132, 0, 0},
12739 {0x133, 0x10, 0},
12740 {0x134, 0x1, 0},
12741 {0x135, 0, 0},
12742 {0x136, 0, 0},
12743 {0x137, 0x80, 0},
12744 {0x138, 0x60, 0},
12745 {0x139, 0x44, 0},
12746 {0x13A, 0x55, 0},
12747 {0x13B, 0x1, 0},
12748 {0x13C, 0x55, 0},
12749 {0x13D, 0x1, 0},
12750 {0x13E, 0x5, 0},
12751 {0x13F, 0x55, 0},
12752 {0x140, 0x55, 0},
12753 {0x146, 0, 0},
12754 {0x147, 0, 0},
12755 {0x148, 0, 0},
12756 {0x149, 0, 0},
12757 {0x14A, 0, 0},
12758 {0x14B, 0, 0},
12759 {0x14C, 0, 0},
12760 {0x14D, 0, 0},
12761 {0x14E, 0, 0},
12762 {0x14F, 0, 0},
12763 {0x150, 0, 0},
12764 {0x151, 0, 0},
12765 {0x154, 0xc, 0},
12766 {0x155, 0xc, 0},
12767 {0x156, 0xc, 0},
12768 {0x157, 0, 0},
12769 {0x158, 0x2b, 0},
12770 {0x159, 0x84, 0},
12771 {0x15A, 0x15, 0},
12772 {0x15B, 0xf, 0},
12773 {0x15C, 0, 0},
12774 {0x15D, 0, 0},
12775 {0x15E, 0, 1},
12776 {0x15F, 0, 1},
12777 {0x160, 0, 1},
12778 {0x161, 0, 1},
12779 {0x162, 0, 1},
12780 {0x163, 0, 1},
12781 {0x164, 0, 0},
12782 {0x165, 0, 0},
12783 {0x166, 0, 0},
12784 {0x167, 0, 0},
12785 {0x168, 0, 0},
12786 {0x169, 0, 0},
12787 {0x16A, 0, 1},
12788 {0x16B, 0, 1},
12789 {0x16C, 0, 1},
12790 {0x16D, 0, 0},
12791 {0x170, 0, 0},
12792 {0x171, 0x77, 0},
12793 {0x172, 0x77, 0},
12794 {0x173, 0x77, 0},
12795 {0x174, 0x77, 0},
12796 {0x175, 0, 0},
12797 {0x176, 0x3, 0},
12798 {0x177, 0x37, 0},
12799 {0x178, 0x3, 0},
12800 {0x179, 0, 0},
12801 {0x17A, 0x21, 0},
12802 {0x17B, 0x21, 0},
12803 {0x17C, 0, 0},
12804 {0x17D, 0xaa, 0},
12805 {0x17E, 0, 0},
12806 {0x17F, 0xaa, 0},
12807 {0x180, 0, 0},
12808 {0x190, 0, 0},
12809 {0x191, 0x77, 0},
12810 {0x192, 0x77, 0},
12811 {0x193, 0x77, 0},
12812 {0x194, 0x77, 0},
12813 {0x195, 0, 0},
12814 {0x196, 0x3, 0},
12815 {0x197, 0x37, 0},
12816 {0x198, 0x3, 0},
12817 {0x199, 0, 0},
12818 {0x19A, 0x21, 0},
12819 {0x19B, 0x21, 0},
12820 {0x19C, 0, 0},
12821 {0x19D, 0xaa, 0},
12822 {0x19E, 0, 0},
12823 {0x19F, 0xaa, 0},
12824 {0x1A0, 0, 0},
12825 {0x1A1, 0x2, 0},
12826 {0x1A2, 0xf, 0},
12827 {0x1A3, 0xf, 0},
12828 {0x1A4, 0, 1},
12829 {0x1A5, 0, 1},
12830 {0x1A6, 0, 1},
12831 {0x1A7, 0x2, 0},
12832 {0x1A8, 0xf, 0},
12833 {0x1A9, 0xf, 0},
12834 {0x1AA, 0, 1},
12835 {0x1AB, 0, 1},
12836 {0x1AC, 0, 1},
12837 {0x1AD, 0x84, 0},
12838 {0x1AE, 0x60, 0},
12839 {0x1AF, 0x47, 0},
12840 {0x1B0, 0x47, 0},
12841 {0x1B1, 0, 0},
12842 {0x1B2, 0, 0},
12843 {0x1B3, 0, 0},
12844 {0x1B4, 0, 0},
12845 {0x1B5, 0, 0},
12846 {0x1B6, 0, 0},
12847 {0x1B7, 0x5, 1},
12848 {0x1B8, 0, 0},
12849 {0x1B9, 0, 0},
12850 {0x1BA, 0, 0},
12851 {0x1BB, 0, 0},
12852 {0x1BC, 0, 0},
12853 {0x1BD, 0, 0},
12854 {0x1BE, 0, 0},
12855 {0x1BF, 0, 0},
12856 {0x1C0, 0, 0},
12857 {0x1C1, 0, 0},
12858 {0x1C2, 0xa0, 1},
12859 {0x1C3, 0, 0},
12860 {0x1C4, 0, 0},
12861 {0x1C5, 0, 0},
12862 {0x1C6, 0, 0},
12863 {0x1C7, 0, 0},
12864 {0x1C8, 0, 0},
12865 {0x1C9, 0, 0},
12866 {0x1CA, 0, 0},
12867 {0xFFFF, 0, 0}
12868};
12869
12870struct radio_20xx_regs regs_2057_rev8[] = {
12871 {0x00, 0x8, 1},
12872 {0x01, 0x57, 1},
12873 {0x02, 0x20, 1},
12874 {0x03, 0x1f, 0},
12875 {0x04, 0x4, 0},
12876 {0x05, 0x2, 0},
12877 {0x06, 0x1, 0},
12878 {0x07, 0x1, 0},
12879 {0x08, 0x1, 0},
12880 {0x09, 0x69, 0},
12881 {0x0A, 0x66, 0},
12882 {0x0B, 0x6, 0},
12883 {0x0C, 0x18, 0},
12884 {0x0D, 0x3, 0},
12885 {0x0E, 0x20, 0},
12886 {0x0F, 0x20, 0},
12887 {0x10, 0, 0},
12888 {0x11, 0x7c, 0},
12889 {0x12, 0x42, 0},
12890 {0x13, 0xbd, 0},
12891 {0x14, 0x7, 0},
12892 {0x15, 0x87, 0},
12893 {0x16, 0x8, 0},
12894 {0x17, 0x17, 0},
12895 {0x18, 0x7, 0},
12896 {0x19, 0, 0},
12897 {0x1A, 0x2, 0},
12898 {0x1B, 0x13, 0},
12899 {0x1C, 0x3e, 0},
12900 {0x1D, 0x3e, 0},
12901 {0x1E, 0x96, 0},
12902 {0x1F, 0x4, 0},
12903 {0x20, 0, 0},
12904 {0x21, 0, 0},
12905 {0x22, 0x17, 0},
12906 {0x23, 0x6, 0},
12907 {0x24, 0x1, 0},
12908 {0x25, 0x6, 0},
12909 {0x26, 0x4, 0},
12910 {0x27, 0xd, 0},
12911 {0x28, 0xd, 0},
12912 {0x29, 0x30, 0},
12913 {0x2A, 0x32, 0},
12914 {0x2B, 0x8, 0},
12915 {0x2C, 0x1c, 0},
12916 {0x2D, 0x2, 0},
12917 {0x2E, 0x4, 0},
12918 {0x2F, 0x7f, 0},
12919 {0x30, 0x27, 0},
12920 {0x31, 0, 1},
12921 {0x32, 0, 1},
12922 {0x33, 0, 1},
12923 {0x34, 0, 0},
12924 {0x35, 0x20, 0},
12925 {0x36, 0x18, 0},
12926 {0x37, 0x7, 0},
12927 {0x38, 0x66, 0},
12928 {0x39, 0x66, 0},
12929 {0x3A, 0x66, 0},
12930 {0x3B, 0x66, 0},
12931 {0x3C, 0xff, 0},
12932 {0x3D, 0xff, 0},
12933 {0x3E, 0xff, 0},
12934 {0x3F, 0xff, 0},
12935 {0x40, 0x16, 0},
12936 {0x41, 0x7, 0},
12937 {0x42, 0x19, 0},
12938 {0x43, 0x7, 0},
12939 {0x44, 0x6, 0},
12940 {0x45, 0x3, 0},
12941 {0x46, 0x1, 0},
12942 {0x47, 0x7, 0},
12943 {0x48, 0x33, 0},
12944 {0x49, 0x5, 0},
12945 {0x4A, 0x77, 0},
12946 {0x4B, 0x66, 0},
12947 {0x4C, 0x66, 0},
12948 {0x4D, 0, 0},
12949 {0x4E, 0x4, 0},
12950 {0x4F, 0xc, 0},
12951 {0x50, 0, 0},
12952 {0x51, 0x70, 1},
12953 {0x56, 0x7, 0},
12954 {0x57, 0, 0},
12955 {0x58, 0, 0},
12956 {0x59, 0x88, 1},
12957 {0x5A, 0, 0},
12958 {0x5B, 0x1f, 0},
12959 {0x5C, 0x20, 1},
12960 {0x5D, 0x1, 0},
12961 {0x5E, 0x30, 0},
12962 {0x5F, 0x70, 0},
12963 {0x60, 0, 0},
12964 {0x61, 0, 0},
12965 {0x62, 0x33, 1},
12966 {0x63, 0xf, 1},
12967 {0x64, 0xf, 1},
12968 {0x65, 0, 0},
12969 {0x66, 0x11, 0},
12970 {0x69, 0, 0},
12971 {0x6A, 0x7e, 0},
12972 {0x6B, 0x3f, 0},
12973 {0x6C, 0x7f, 0},
12974 {0x6D, 0x78, 0},
12975 {0x6E, 0x58, 1},
12976 {0x6F, 0x88, 0},
12977 {0x70, 0x8, 0},
12978 {0x71, 0xf, 0},
12979 {0x72, 0xbc, 0},
12980 {0x73, 0x8, 0},
12981 {0x74, 0x60, 0},
12982 {0x75, 0x13, 1},
12983 {0x76, 0x70, 0},
12984 {0x77, 0, 0},
12985 {0x78, 0, 0},
12986 {0x79, 0, 0},
12987 {0x7A, 0x33, 0},
12988 {0x7B, 0x13, 1},
12989 {0x7C, 0xf, 1},
12990 {0x7D, 0xee, 1},
12991 {0x80, 0x3c, 0},
12992 {0x81, 0x1, 1},
12993 {0x82, 0xa, 0},
12994 {0x83, 0x9d, 0},
12995 {0x84, 0xa, 0},
12996 {0x85, 0, 0},
12997 {0x86, 0x40, 0},
12998 {0x87, 0x40, 0},
12999 {0x88, 0x88, 0},
13000 {0x89, 0x10, 0},
13001 {0x8A, 0xf0, 0},
13002 {0x8B, 0x10, 0},
13003 {0x8C, 0xf0, 0},
13004 {0x8D, 0, 0},
13005 {0x8E, 0, 0},
13006 {0x8F, 0x10, 0},
13007 {0x90, 0x55, 0},
13008 {0x91, 0x3f, 1},
13009 {0x92, 0x36, 1},
13010 {0x93, 0, 0},
13011 {0x94, 0, 0},
13012 {0x95, 0, 0},
13013 {0x96, 0x87, 0},
13014 {0x97, 0x11, 0},
13015 {0x98, 0, 0},
13016 {0x99, 0x33, 0},
13017 {0x9A, 0x88, 0},
13018 {0x9B, 0, 0},
13019 {0x9C, 0x87, 0},
13020 {0x9D, 0x11, 0},
13021 {0x9E, 0, 0},
13022 {0x9F, 0x33, 0},
13023 {0xA0, 0x88, 0},
13024 {0xA1, 0x20, 1},
13025 {0xA2, 0x3f, 0},
13026 {0xA3, 0x44, 0},
13027 {0xA4, 0x8c, 0},
13028 {0xA5, 0x6c, 0},
13029 {0xA6, 0x22, 0},
13030 {0xA7, 0xbe, 0},
13031 {0xA8, 0x55, 0},
13032 {0xAA, 0xc, 0},
13033 {0xAB, 0xaa, 0},
13034 {0xAC, 0x2, 0},
13035 {0xAD, 0, 0},
13036 {0xAE, 0x10, 0},
13037 {0xAF, 0x1, 0},
13038 {0xB0, 0, 0},
13039 {0xB1, 0, 0},
13040 {0xB2, 0x80, 0},
13041 {0xB3, 0x60, 0},
13042 {0xB4, 0x44, 0},
13043 {0xB5, 0x55, 0},
13044 {0xB6, 0x1, 0},
13045 {0xB7, 0x55, 0},
13046 {0xB8, 0x1, 0},
13047 {0xB9, 0x5, 0},
13048 {0xBA, 0x55, 0},
13049 {0xBB, 0x55, 0},
13050 {0xC1, 0, 0},
13051 {0xC2, 0, 0},
13052 {0xC3, 0, 0},
13053 {0xC4, 0, 0},
13054 {0xC5, 0, 0},
13055 {0xC6, 0, 0},
13056 {0xC7, 0, 0},
13057 {0xC8, 0, 0},
13058 {0xC9, 0x1, 1},
13059 {0xCA, 0, 0},
13060 {0xCB, 0, 0},
13061 {0xCC, 0, 0},
13062 {0xCD, 0, 0},
13063 {0xCE, 0x5e, 0},
13064 {0xCF, 0xc, 0},
13065 {0xD0, 0xc, 0},
13066 {0xD1, 0xc, 0},
13067 {0xD2, 0, 0},
13068 {0xD3, 0x2b, 0},
13069 {0xD4, 0xc, 0},
13070 {0xD5, 0, 0},
13071 {0xD6, 0x70, 1},
13072 {0xDB, 0x7, 0},
13073 {0xDC, 0, 0},
13074 {0xDD, 0, 0},
13075 {0xDE, 0x88, 1},
13076 {0xDF, 0, 0},
13077 {0xE0, 0x1f, 0},
13078 {0xE1, 0x20, 1},
13079 {0xE2, 0x1, 0},
13080 {0xE3, 0x30, 0},
13081 {0xE4, 0x70, 0},
13082 {0xE5, 0, 0},
13083 {0xE6, 0, 0},
13084 {0xE7, 0x33, 0},
13085 {0xE8, 0xf, 1},
13086 {0xE9, 0xf, 1},
13087 {0xEA, 0, 0},
13088 {0xEB, 0x11, 0},
13089 {0xEE, 0, 0},
13090 {0xEF, 0x7e, 0},
13091 {0xF0, 0x3f, 0},
13092 {0xF1, 0x7f, 0},
13093 {0xF2, 0x78, 0},
13094 {0xF3, 0x58, 1},
13095 {0xF4, 0x88, 0},
13096 {0xF5, 0x8, 0},
13097 {0xF6, 0xf, 0},
13098 {0xF7, 0xbc, 0},
13099 {0xF8, 0x8, 0},
13100 {0xF9, 0x60, 0},
13101 {0xFA, 0x13, 1},
13102 {0xFB, 0x70, 0},
13103 {0xFC, 0, 0},
13104 {0xFD, 0, 0},
13105 {0xFE, 0, 0},
13106 {0xFF, 0x33, 0},
13107 {0x100, 0x13, 1},
13108 {0x101, 0xf, 1},
13109 {0x102, 0xee, 1},
13110 {0x105, 0x3c, 0},
13111 {0x106, 0x1, 1},
13112 {0x107, 0xa, 0},
13113 {0x108, 0x9d, 0},
13114 {0x109, 0xa, 0},
13115 {0x10A, 0, 0},
13116 {0x10B, 0x40, 0},
13117 {0x10C, 0x40, 0},
13118 {0x10D, 0x88, 0},
13119 {0x10E, 0x10, 0},
13120 {0x10F, 0xf0, 0},
13121 {0x110, 0x10, 0},
13122 {0x111, 0xf0, 0},
13123 {0x112, 0, 0},
13124 {0x113, 0, 0},
13125 {0x114, 0x10, 0},
13126 {0x115, 0x55, 0},
13127 {0x116, 0x3f, 1},
13128 {0x117, 0x36, 1},
13129 {0x118, 0, 0},
13130 {0x119, 0, 0},
13131 {0x11A, 0, 0},
13132 {0x11B, 0x87, 0},
13133 {0x11C, 0x11, 0},
13134 {0x11D, 0, 0},
13135 {0x11E, 0x33, 0},
13136 {0x11F, 0x88, 0},
13137 {0x120, 0, 0},
13138 {0x121, 0x87, 0},
13139 {0x122, 0x11, 0},
13140 {0x123, 0, 0},
13141 {0x124, 0x33, 0},
13142 {0x125, 0x88, 0},
13143 {0x126, 0x20, 1},
13144 {0x127, 0x3f, 0},
13145 {0x128, 0x44, 0},
13146 {0x129, 0x8c, 0},
13147 {0x12A, 0x6c, 0},
13148 {0x12B, 0x22, 0},
13149 {0x12C, 0xbe, 0},
13150 {0x12D, 0x55, 0},
13151 {0x12F, 0xc, 0},
13152 {0x130, 0xaa, 0},
13153 {0x131, 0x2, 0},
13154 {0x132, 0, 0},
13155 {0x133, 0x10, 0},
13156 {0x134, 0x1, 0},
13157 {0x135, 0, 0},
13158 {0x136, 0, 0},
13159 {0x137, 0x80, 0},
13160 {0x138, 0x60, 0},
13161 {0x139, 0x44, 0},
13162 {0x13A, 0x55, 0},
13163 {0x13B, 0x1, 0},
13164 {0x13C, 0x55, 0},
13165 {0x13D, 0x1, 0},
13166 {0x13E, 0x5, 0},
13167 {0x13F, 0x55, 0},
13168 {0x140, 0x55, 0},
13169 {0x146, 0, 0},
13170 {0x147, 0, 0},
13171 {0x148, 0, 0},
13172 {0x149, 0, 0},
13173 {0x14A, 0, 0},
13174 {0x14B, 0, 0},
13175 {0x14C, 0, 0},
13176 {0x14D, 0, 0},
13177 {0x14E, 0x1, 1},
13178 {0x14F, 0, 0},
13179 {0x150, 0, 0},
13180 {0x151, 0, 0},
13181 {0x154, 0xc, 0},
13182 {0x155, 0xc, 0},
13183 {0x156, 0xc, 0},
13184 {0x157, 0, 0},
13185 {0x158, 0x2b, 0},
13186 {0x159, 0x84, 0},
13187 {0x15A, 0x15, 0},
13188 {0x15B, 0xf, 0},
13189 {0x15C, 0, 0},
13190 {0x15D, 0, 0},
13191 {0x15E, 0, 1},
13192 {0x15F, 0, 1},
13193 {0x160, 0, 1},
13194 {0x161, 0, 1},
13195 {0x162, 0, 1},
13196 {0x163, 0, 1},
13197 {0x164, 0, 0},
13198 {0x165, 0, 0},
13199 {0x166, 0, 0},
13200 {0x167, 0, 0},
13201 {0x168, 0, 0},
13202 {0x169, 0, 0},
13203 {0x16A, 0, 1},
13204 {0x16B, 0, 1},
13205 {0x16C, 0, 1},
13206 {0x16D, 0, 0},
13207 {0x170, 0, 0},
13208 {0x171, 0x77, 0},
13209 {0x172, 0x77, 0},
13210 {0x173, 0x77, 0},
13211 {0x174, 0x77, 0},
13212 {0x175, 0, 0},
13213 {0x176, 0x3, 0},
13214 {0x177, 0x37, 0},
13215 {0x178, 0x3, 0},
13216 {0x179, 0, 0},
13217 {0x17A, 0x21, 0},
13218 {0x17B, 0x21, 0},
13219 {0x17C, 0, 0},
13220 {0x17D, 0xaa, 0},
13221 {0x17E, 0, 0},
13222 {0x17F, 0xaa, 0},
13223 {0x180, 0, 0},
13224 {0x190, 0, 0},
13225 {0x191, 0x77, 0},
13226 {0x192, 0x77, 0},
13227 {0x193, 0x77, 0},
13228 {0x194, 0x77, 0},
13229 {0x195, 0, 0},
13230 {0x196, 0x3, 0},
13231 {0x197, 0x37, 0},
13232 {0x198, 0x3, 0},
13233 {0x199, 0, 0},
13234 {0x19A, 0x21, 0},
13235 {0x19B, 0x21, 0},
13236 {0x19C, 0, 0},
13237 {0x19D, 0xaa, 0},
13238 {0x19E, 0, 0},
13239 {0x19F, 0xaa, 0},
13240 {0x1A0, 0, 0},
13241 {0x1A1, 0x2, 0},
13242 {0x1A2, 0xf, 0},
13243 {0x1A3, 0xf, 0},
13244 {0x1A4, 0, 1},
13245 {0x1A5, 0, 1},
13246 {0x1A6, 0, 1},
13247 {0x1A7, 0x2, 0},
13248 {0x1A8, 0xf, 0},
13249 {0x1A9, 0xf, 0},
13250 {0x1AA, 0, 1},
13251 {0x1AB, 0, 1},
13252 {0x1AC, 0, 1},
13253 {0x1AD, 0x84, 0},
13254 {0x1AE, 0x60, 0},
13255 {0x1AF, 0x47, 0},
13256 {0x1B0, 0x47, 0},
13257 {0x1B1, 0, 0},
13258 {0x1B2, 0, 0},
13259 {0x1B3, 0, 0},
13260 {0x1B4, 0, 0},
13261 {0x1B5, 0, 0},
13262 {0x1B6, 0, 0},
13263 {0x1B7, 0x5, 1},
13264 {0x1B8, 0, 0},
13265 {0x1B9, 0, 0},
13266 {0x1BA, 0, 0},
13267 {0x1BB, 0, 0},
13268 {0x1BC, 0, 0},
13269 {0x1BD, 0, 0},
13270 {0x1BE, 0, 0},
13271 {0x1BF, 0, 0},
13272 {0x1C0, 0, 0},
13273 {0x1C1, 0, 0},
13274 {0x1C2, 0xa0, 1},
13275 {0x1C3, 0, 0},
13276 {0x1C4, 0, 0},
13277 {0x1C5, 0, 0},
13278 {0x1C6, 0, 0},
13279 {0x1C7, 0, 0},
13280 {0x1C8, 0, 0},
13281 {0x1C9, 0, 0},
13282 {0x1CA, 0, 0},
13283 {0xFFFF, 0, 0}
13284};
13285
13286static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 };
13287
13288static s32 nphy_lnagain_est0[] = { -315, 40370 };
13289static s32 nphy_lnagain_est1[] = { -224, 23242 };
13290
13291static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = {
13292 {
13293 {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69},
13294 {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69},
13295 {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68},
13296 {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67},
13297 {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66},
13298 {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65},
13299 {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65},
13300 {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65},
13301 {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65}
13302 },
13303 {
13304 {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
13305 {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
13306 {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79},
13307 {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78},
13308 {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78},
13309 {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78},
13310 {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78},
13311 {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78},
13312 {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78}
13313 }
13314};
13315
13316static const u32 nphy_tpc_txgain[] = {
13317 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
13318 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
13319 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
13320 0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
13321 0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
13322 0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
13323 0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
13324 0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
13325 0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
13326 0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
13327 0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
13328 0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
13329 0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
13330 0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
13331 0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
13332 0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
13333 0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
13334 0x03902942, 0x03902844, 0x03902842, 0x03902744,
13335 0x03902742, 0x03902644, 0x03902642, 0x03902544,
13336 0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
13337 0x03802a42, 0x03802944, 0x03802942, 0x03802844,
13338 0x03802842, 0x03802744, 0x03802742, 0x03802644,
13339 0x03802642, 0x03802544, 0x03802542, 0x03802444,
13340 0x03802442, 0x03802344, 0x03802342, 0x03802244,
13341 0x03802242, 0x03802144, 0x03802142, 0x03802044,
13342 0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
13343 0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
13344 0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
13345 0x03801a42, 0x03801944, 0x03801942, 0x03801844,
13346 0x03801842, 0x03801744, 0x03801742, 0x03801644,
13347 0x03801642, 0x03801544, 0x03801542, 0x03801444,
13348 0x03801442, 0x03801344, 0x03801342, 0x00002b00
13349};
13350
13351static const u16 nphy_tpc_loscale[] = {
13352 256, 256, 271, 271, 287, 256, 256, 271,
13353 271, 287, 287, 304, 304, 256, 256, 271,
13354 271, 287, 287, 304, 304, 322, 322, 341,
13355 341, 362, 362, 383, 383, 256, 256, 271,
13356 271, 287, 287, 304, 304, 322, 322, 256,
13357 256, 271, 271, 287, 287, 304, 304, 322,
13358 322, 341, 341, 362, 362, 256, 256, 271,
13359 271, 287, 287, 304, 304, 322, 322, 256,
13360 256, 271, 271, 287, 287, 304, 304, 322,
13361 322, 341, 341, 362, 362, 256, 256, 271,
13362 271, 287, 287, 304, 304, 322, 322, 341,
13363 341, 362, 362, 383, 383, 406, 406, 430,
13364 430, 455, 455, 482, 482, 511, 511, 541,
13365 541, 573, 573, 607, 607, 643, 643, 681,
13366 681, 722, 722, 764, 764, 810, 810, 858,
13367 858, 908, 908, 962, 962, 1019, 1019, 256
13368};
13369
13370static u32 nphy_tpc_txgain_ipa[] = {
13371 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
13372 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
13373 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
13374 0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
13375 0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
13376 0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
13377 0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
13378 0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
13379 0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
13380 0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
13381 0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
13382 0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
13383 0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
13384 0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
13385 0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
13386 0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
13387 0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
13388 0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
13389 0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
13390 0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
13391 0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
13392 0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
13393 0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
13394 0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
13395 0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
13396 0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
13397 0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
13398 0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
13399 0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
13400 0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
13401 0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
13402 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025
13403};
13404
13405static u32 nphy_tpc_txgain_ipa_rev5[] = {
13406 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
13407 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
13408 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
13409 0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
13410 0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
13411 0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
13412 0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
13413 0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
13414 0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
13415 0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
13416 0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
13417 0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
13418 0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
13419 0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
13420 0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
13421 0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
13422 0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
13423 0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
13424 0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
13425 0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
13426 0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
13427 0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
13428 0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
13429 0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
13430 0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
13431 0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
13432 0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
13433 0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
13434 0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
13435 0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
13436 0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
13437 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025
13438};
13439
13440static u32 nphy_tpc_txgain_ipa_rev6[] = {
13441 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
13442 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
13443 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
13444 0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
13445 0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
13446 0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
13447 0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
13448 0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
13449 0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
13450 0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
13451 0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
13452 0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
13453 0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
13454 0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
13455 0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
13456 0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
13457 0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
13458 0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
13459 0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
13460 0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
13461 0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
13462 0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
13463 0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
13464 0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
13465 0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
13466 0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
13467 0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
13468 0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
13469 0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
13470 0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
13471 0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
13472 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025
13473};
13474
13475static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = {
13476 0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039,
13477 0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032,
13478 0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d,
13479 0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c,
13480 0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d,
13481 0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a,
13482 0x70570028, 0x704f002a, 0x7047002c, 0x7047002a,
13483 0x70470028, 0x70470026, 0x70470024, 0x70470022,
13484 0x7047001f, 0x70370027, 0x70370024, 0x70370022,
13485 0x70370020, 0x7037001f, 0x7037001d, 0x7037001b,
13486 0x7037001a, 0x70370018, 0x70370017, 0x7027001e,
13487 0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022,
13488 0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b,
13489 0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015,
13490 0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011,
13491 0x70170019, 0x70170018, 0x70170016, 0x70170015,
13492 0x70170014, 0x70170013, 0x70170012, 0x70170010,
13493 0x70170010, 0x7017000f, 0x700f001d, 0x700f001b,
13494 0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015,
13495 0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011,
13496 0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e,
13497 0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b,
13498 0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009,
13499 0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007,
13500 0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006,
13501 0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004,
13502 0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004,
13503 0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003,
13504 0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002,
13505 0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001,
13506 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001,
13507 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001
13508};
13509
13510static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = {
13511 0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039,
13512 0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032,
13513 0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d,
13514 0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c,
13515 0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d,
13516 0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a,
13517 0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a,
13518 0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022,
13519 0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022,
13520 0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b,
13521 0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e,
13522 0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022,
13523 0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b,
13524 0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015,
13525 0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011,
13526 0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015,
13527 0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010,
13528 0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b,
13529 0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015,
13530 0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011,
13531 0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e,
13532 0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b,
13533 0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009,
13534 0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007,
13535 0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006,
13536 0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004,
13537 0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004,
13538 0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003,
13539 0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002,
13540 0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001,
13541 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001,
13542 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001
13543};
13544
13545static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = {
13546 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
13547 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
13548 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
13549 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
13550 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
13551 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
13552 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
13553 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
13554 0x30270027, 0x30270025, 0x30270023, 0x301f002c,
13555 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
13556 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
13557 0x30170028, 0x30170026, 0x30170024, 0x30170022,
13558 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
13559 0x3017001a, 0x30170018, 0x30170017, 0x30170015,
13560 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
13561 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
13562 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
13563 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
13564 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
13565 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13566 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13567 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13568 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13569 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13570 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13571 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13572 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13573 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13574 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13575 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13576 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13577 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
13578};
13579
13580static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = {
13581 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
13582 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
13583 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
13584 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
13585 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
13586 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
13587 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
13588 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
13589 0x30270027, 0x30270025, 0x30270023, 0x301f002c,
13590 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
13591 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
13592 0x30170028, 0x30170026, 0x30170024, 0x30170022,
13593 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
13594 0x3017001a, 0x30170018, 0x30170017, 0x30170015,
13595 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
13596 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
13597 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
13598 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
13599 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
13600 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13601 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13602 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13603 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13604 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13605 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13606 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13607 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13608 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13609 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13610 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13611 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
13612 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
13613};
13614
13615static u32 nphy_tpc_txgain_ipa_5g[] = {
13616 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
13617 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
13618 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
13619 0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
13620 0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
13621 0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
13622 0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
13623 0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
13624 0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
13625 0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
13626 0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
13627 0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
13628 0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
13629 0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
13630 0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
13631 0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
13632 0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
13633 0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
13634 0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
13635 0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
13636 0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
13637 0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
13638 0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
13639 0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
13640 0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
13641 0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
13642 0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
13643 0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
13644 0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
13645 0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
13646 0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
13647 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f
13648};
13649
13650static u32 nphy_tpc_txgain_ipa_5g_2057[] = {
13651 0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039,
13652 0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035,
13653 0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033,
13654 0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a,
13655 0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039,
13656 0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038,
13657 0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038,
13658 0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037,
13659 0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036,
13660 0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037,
13661 0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036,
13662 0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035,
13663 0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033,
13664 0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034,
13665 0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032,
13666 0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028,
13667 0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020,
13668 0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019,
13669 0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014,
13670 0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010,
13671 0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d,
13672 0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a,
13673 0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008,
13674 0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006,
13675 0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005,
13676 0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004,
13677 0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
13678 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
13679 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
13680 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
13681 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
13682 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001
13683};
13684
13685static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = {
13686 0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a,
13687 0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a,
13688 0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028,
13689 0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e,
13690 0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e,
13691 0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e,
13692 0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d,
13693 0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d,
13694 0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c,
13695 0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b,
13696 0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b,
13697 0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a,
13698 0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029,
13699 0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029,
13700 0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027,
13701 0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020,
13702 0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019,
13703 0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014,
13704 0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f,
13705 0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c,
13706 0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a,
13707 0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008,
13708 0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006,
13709 0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005,
13710 0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004,
13711 0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003,
13712 0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002,
13713 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
13714 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
13715 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
13716 0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001,
13717 0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001
13718};
13719
13720static s8 nphy_papd_pga_gain_delta_ipa_2g[] = {
13721 -114, -108, -98, -91, -84, -78, -70, -62,
13722 -54, -46, -39, -31, -23, -15, -8, 0
13723};
13724
13725static s8 nphy_papd_pga_gain_delta_ipa_5g[] = {
13726 -100, -95, -89, -83, -77, -70, -63, -56,
13727 -48, -41, -33, -25, -19, -12, -6, 0
13728};
13729
13730static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = {
13731 -159, -113, -86, -72, -62, -54, -48, -43,
13732 -39, -35, -31, -28, -25, -23, -20, -18,
13733 -17, -15, -13, -11, -10, -8, -7, -6,
13734 -5, -4, -3, -3, -2, -1, -1, 0
13735};
13736
13737static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = {
13738 -109, -109, -82, -68, -58, -50, -44, -39,
13739 -35, -31, -28, -26, -23, -21, -19, -17,
13740 -16, -14, -13, -11, -10, -9, -8, -7,
13741 -5, -5, -4, -3, -2, -1, -1, 0
13742};
13743
13744static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = {
13745 -122, -122, -95, -80, -69, -61, -54, -49,
13746 -43, -39, -35, -32, -28, -26, -23, -21,
13747 -18, -16, -15, -13, -11, -10, -8, -7,
13748 -6, -5, -4, -3, -2, -1, -1, 0
13749};
13750
13751static s8 nphy_papd_pgagain_dlt_5g_2057[] = {
13752 -107, -101, -92, -85, -78, -71, -62, -55,
13753 -47, -39, -32, -24, -19, -12, -6, 0
13754};
13755
13756static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = {
13757 -110, -104, -95, -88, -81, -74, -66, -58,
13758 -50, -44, -36, -28, -23, -15, -8, 0
13759};
13760
13761static u8 pad_gain_codes_used_2057rev5[] = {
13762 20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
13763 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
13764};
13765
13766static u8 pad_gain_codes_used_2057rev7[] = {
13767 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
13768 5, 4, 3, 2, 1
13769};
13770
13771static u8 pad_all_gain_codes_2057[] = {
13772 31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
13773 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
13774 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
13775 1, 0
13776};
13777
13778static u8 pga_all_gain_codes_2057[] = {
13779 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
13780};
13781
13782static u32 nphy_papd_scaltbl[] = {
13783 0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038,
13784 0x0887003c, 0x081f003f, 0x07a20043, 0x07340047,
13785 0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059,
13786 0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070,
13787 0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d,
13788 0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2,
13789 0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0,
13790 0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a,
13791 0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162,
13792 0x015d0177, 0x0149018e, 0x013701a5, 0x012601be,
13793 0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232,
13794 0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3,
13795 0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a,
13796 0x008b03af, 0x008303e7, 0x007c0422, 0x00750461,
13797 0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583,
13798 0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1
13799};
13800
13801static u32 nphy_tpc_txgain_rev3[] = {
13802 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
13803 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
13804 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
13805 0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
13806 0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
13807 0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
13808 0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
13809 0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
13810 0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
13811 0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
13812 0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
13813 0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
13814 0x19410044, 0x19410042, 0x19410040, 0x1941003e,
13815 0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
13816 0x18410044, 0x18410042, 0x18410040, 0x1841003e,
13817 0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
13818 0x17410044, 0x17410042, 0x17410040, 0x1741003e,
13819 0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
13820 0x16410044, 0x16410042, 0x16410040, 0x1641003e,
13821 0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
13822 0x15410044, 0x15410042, 0x15410040, 0x1541003e,
13823 0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
13824 0x14410044, 0x14410042, 0x14410040, 0x1441003e,
13825 0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
13826 0x13410044, 0x13410042, 0x13410040, 0x1341003e,
13827 0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
13828 0x12410044, 0x12410042, 0x12410040, 0x1241003e,
13829 0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
13830 0x11410044, 0x11410042, 0x11410040, 0x1141003e,
13831 0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
13832 0x10410044, 0x10410042, 0x10410040, 0x1041003e,
13833 0x1041003c, 0x1041003b, 0x10410039, 0x10410037
13834};
13835
13836static u32 nphy_tpc_txgain_HiPwrEPA[] = {
13837 0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
13838 0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
13839 0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
13840 0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
13841 0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
13842 0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
13843 0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
13844 0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
13845 0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
13846 0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
13847 0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
13848 0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
13849 0x09410044, 0x09410042, 0x09410040, 0x0941003e,
13850 0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
13851 0x08410044, 0x08410042, 0x08410040, 0x0841003e,
13852 0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
13853 0x07410044, 0x07410042, 0x07410040, 0x0741003e,
13854 0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
13855 0x06410044, 0x06410042, 0x06410040, 0x0641003e,
13856 0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
13857 0x05410044, 0x05410042, 0x05410040, 0x0541003e,
13858 0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
13859 0x04410044, 0x04410042, 0x04410040, 0x0441003e,
13860 0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
13861 0x03410044, 0x03410042, 0x03410040, 0x0341003e,
13862 0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
13863 0x02410044, 0x02410042, 0x02410040, 0x0241003e,
13864 0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
13865 0x01410044, 0x01410042, 0x01410040, 0x0141003e,
13866 0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
13867 0x00410044, 0x00410042, 0x00410040, 0x0041003e,
13868 0x0041003c, 0x0041003b, 0x00410039, 0x00410037
13869};
13870
13871static u32 nphy_tpc_txgain_epa_2057rev3[] = {
13872 0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d,
13873 0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b,
13874 0x8091003b, 0x8089003a, 0x8081003a, 0x80790039,
13875 0x80710039, 0x8069003a, 0x8061003b, 0x8059003d,
13876 0x8051003f, 0x80490042, 0x8049003e, 0x8049003b,
13877 0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b,
13878 0x80390038, 0x80390035, 0x8031003a, 0x80310036,
13879 0x80310033, 0x8029003a, 0x80290037, 0x80290034,
13880 0x80290031, 0x80210039, 0x80210036, 0x80210033,
13881 0x80210030, 0x8019003c, 0x80190039, 0x80190036,
13882 0x80190033, 0x80190030, 0x8019002d, 0x8019002b,
13883 0x80190028, 0x8011003a, 0x80110036, 0x80110033,
13884 0x80110030, 0x8011002e, 0x8011002b, 0x80110029,
13885 0x80110027, 0x80110024, 0x80110022, 0x80110020,
13886 0x8011001f, 0x8011001d, 0x8009003a, 0x80090037,
13887 0x80090034, 0x80090031, 0x8009002e, 0x8009002c,
13888 0x80090029, 0x80090027, 0x80090025, 0x80090023,
13889 0x80090021, 0x8009001f, 0x8009001d, 0x8009011d,
13890 0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d,
13891 0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d,
13892 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13893 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13894 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13895 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13896 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13897 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13898 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13899 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13900 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13901 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13902 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
13903 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d
13904};
13905
13906static u32 nphy_tpc_txgain_epa_2057rev5[] = {
13907 0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
13908 0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
13909 0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
13910 0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
13911 0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
13912 0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
13913 0x10390038, 0x10390035, 0x1031003a, 0x10310036,
13914 0x10310033, 0x1029003a, 0x10290037, 0x10290034,
13915 0x10290031, 0x10210039, 0x10210036, 0x10210033,
13916 0x10210030, 0x1019003c, 0x10190039, 0x10190036,
13917 0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
13918 0x10190028, 0x1011003a, 0x10110036, 0x10110033,
13919 0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
13920 0x10110027, 0x10110024, 0x10110022, 0x10110020,
13921 0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
13922 0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
13923 0x10090029, 0x10090027, 0x10090025, 0x10090023,
13924 0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
13925 0x1009001a, 0x10090018, 0x10090017, 0x10090016,
13926 0x10090015, 0x10090013, 0x10090012, 0x10090011,
13927 0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
13928 0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
13929 0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
13930 0x10090008, 0x10090008, 0x10090007, 0x10090007,
13931 0x10090007, 0x10090006, 0x10090006, 0x10090005,
13932 0x10090005, 0x10090005, 0x10090005, 0x10090004,
13933 0x10090004, 0x10090004, 0x10090004, 0x10090003,
13934 0x10090003, 0x10090003, 0x10090003, 0x10090003,
13935 0x10090003, 0x10090002, 0x10090002, 0x10090002,
13936 0x10090002, 0x10090002, 0x10090002, 0x10090002,
13937 0x10090002, 0x10090002, 0x10090001, 0x10090001,
13938 0x10090001, 0x10090001, 0x10090001, 0x10090001
13939};
13940
13941static u32 nphy_tpc_5GHz_txgain_rev3[] = {
13942 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
13943 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
13944 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
13945 0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
13946 0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
13947 0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
13948 0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
13949 0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
13950 0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
13951 0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
13952 0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
13953 0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
13954 0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
13955 0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
13956 0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
13957 0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
13958 0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
13959 0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
13960 0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
13961 0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
13962 0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
13963 0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
13964 0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
13965 0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
13966 0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
13967 0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
13968 0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
13969 0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
13970 0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
13971 0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
13972 0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
13973 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037
13974};
13975
13976static u32 nphy_tpc_5GHz_txgain_rev4[] = {
13977 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
13978 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
13979 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
13980 0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
13981 0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
13982 0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
13983 0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
13984 0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
13985 0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
13986 0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
13987 0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
13988 0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
13989 0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
13990 0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
13991 0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
13992 0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
13993 0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
13994 0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
13995 0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
13996 0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
13997 0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
13998 0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
13999 0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
14000 0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
14001 0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
14002 0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
14003 0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
14004 0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
14005 0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
14006 0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
14007 0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
14008 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034
14009};
14010
14011static u32 nphy_tpc_5GHz_txgain_rev5[] = {
14012 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
14013 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
14014 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
14015 0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
14016 0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
14017 0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
14018 0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
14019 0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
14020 0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
14021 0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
14022 0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
14023 0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
14024 0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
14025 0x09620039, 0x09620037, 0x09620035, 0x09620033,
14026 0x08620044, 0x08620042, 0x08620040, 0x0862003e,
14027 0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
14028 0x07620043, 0x07620042, 0x07620040, 0x0762003f,
14029 0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
14030 0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
14031 0x06620039, 0x06620037, 0x06620035, 0x06620033,
14032 0x05620046, 0x05620044, 0x05620042, 0x05620040,
14033 0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
14034 0x04620044, 0x04620042, 0x04620040, 0x0462003e,
14035 0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
14036 0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
14037 0x03620038, 0x03620037, 0x03620035, 0x03620033,
14038 0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
14039 0x02620046, 0x02620044, 0x02620043, 0x02620042,
14040 0x0162004a, 0x01620048, 0x01620046, 0x01620044,
14041 0x01620043, 0x01620042, 0x01620041, 0x01620040,
14042 0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
14043 0x0062003b, 0x00620039, 0x00620037, 0x00620035
14044};
14045
14046static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = {
14047 0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
14048 0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
14049 0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
14050 0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
14051 0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
14052 0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
14053 0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
14054 0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
14055 0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
14056 0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
14057 0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
14058 0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
14059 0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
14060 0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
14061 0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
14062 0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
14063 0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
14064 0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
14065 0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
14066 0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
14067 0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
14068 0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
14069 0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
14070 0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
14071 0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
14072 0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
14073 0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
14074 0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
14075 0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
14076 0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
14077 0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
14078 0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
14079};
14080
14081static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 };
14082static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 };
14083static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = {
14084 0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a };
14085static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
14086 0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 };
14087
14088static bool wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f,
14089 struct chan_info_nphy_radio2057 **t0,
14090 struct chan_info_nphy_radio205x **t1,
14091 struct chan_info_nphy_radio2057_rev5 **t2,
14092 struct chan_info_nphy_2055 **t3);
14093static void wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chans,
14094 const struct nphy_sfo_cfg *c);
14095
14096static void wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi,
14097 u16 reduction_factr);
14098static void wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi,
14099 int ntones, int *, u32 *buf);
14100static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr);
14101static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi);
14102static void wlc_phy_spurwar_nphy(struct brcms_phy *pi);
14103
14104static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi);
14105static void wlc_phy_radio_init_2055(struct brcms_phy *pi);
14106static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi);
14107static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi);
14108static void wlc_phy_radio_init_2056(struct brcms_phy *pi);
14109static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi);
14110static void wlc_phy_radio_init_2057(struct brcms_phy *pi);
14111static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi);
14112static void wlc_phy_workarounds_nphy(struct brcms_phy *pi);
14113static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi);
14114static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi);
14115static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi);
14116static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi);
14117
14118static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi);
14119static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi);
14120static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi);
14121static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi,
14122 struct nphy_txgains tg, u8 type, bool d);
14123static void wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rxcore,
14124 u16 *rg, u8 type);
14125static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble);
14126static void wlc_phy_savecal_nphy(struct brcms_phy *pi);
14127static void wlc_phy_restorecal_nphy(struct brcms_phy *pi);
14128static void wlc_phy_resetcca_nphy(struct brcms_phy *pi);
14129
14130static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi);
14131static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi);
14132static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi);
14133static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core);
14134
14135static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi);
14136static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi);
14137static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi);
14138static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi);
14139static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1);
14140static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi);
14141
14142static void wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32,
14143 u32 e);
14144static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core);
14145static void wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *,
14146 enum phy_cal_mode, u8);
14147static void wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi,
14148 struct nphy_papd_restore_state *state);
14149static void wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi,
14150 struct nphy_papd_restore_state *state, u8);
14151
14152static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals);
14153
14154static void wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *evts,
14155 u8 *dlys, u8 len);
14156
14157static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset);
14158
14159static void
14160wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value,
14161 u8 core_mask, u8 off,
14162 u8 override_id);
14163
14164static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type);
14165static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi);
14166
14167static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi);
14168static void wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max,
14169 u16 *pwr_offset,
14170 u8 tmp_max_pwr, u8 rate_start,
14171 u8 rate_end);
14172
14173static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi);
14174static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi);
14175static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi);
14176static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi);
14177
14178static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi);
14179static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core);
14180static void wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0,
14181 u8 idx1);
14182static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal);
14183
14184static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi);
14185
14186static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi);
14187
14188static u16 wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz,
14189 u16 max_val,
14190 u8 dac_test_mode);
14191static void wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, cs32 *tone_buf,
14192 u16 num_samps);
14193static void wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 n, u16 lps,
14194 u16 wait, u8 iq, u8 dac_test_mode,
14195 bool modify_bbmult);
14196
14197bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih)
14198{
14199 struct brcms_phy *pi = (struct brcms_phy *) pih;
14200 u32 phybist0, phybist1, phybist2, phybist3, phybist4;
14201
14202 if (NREV_GE(pi->pubpi.phy_rev, 16))
14203 return true;
14204
14205 phybist0 = read_phy_reg(pi, 0x0e);
14206 phybist1 = read_phy_reg(pi, 0x0f);
14207 phybist2 = read_phy_reg(pi, 0xea);
14208 phybist3 = read_phy_reg(pi, 0xeb);
14209 phybist4 = read_phy_reg(pi, 0x156);
14210
14211 if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) &&
14212 (phybist3 == 0) && (phybist4 == 0)) {
14213 return true;
14214 }
14215
14216 return false;
14217}
14218
14219static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi)
14220{
14221 u16 addr, val;
14222
14223 val = 0x1e1f;
14224 for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
14225 addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
14226 write_phy_reg(pi, addr, val);
14227 if (addr == (NPHY_TO_BPHY_OFF + 0x97))
14228 val = 0x3e3f;
14229 else
14230 val -= 0x0202;
14231 }
14232
14233 if (NORADIO_ENAB(pi->pubpi)) {
14234
14235 write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_PHYCRSTH, 0x3206);
14236
14237 write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_RSSI_TRESH, 0x281e);
14238
14239 or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_LNA_GAIN_RANGE, 0x1a);
14240
14241 } else {
14242
14243 write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
14244 }
14245}
14246
14247void
14248wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
14249 u32 width, const void *data)
14250{
14251 struct phytbl_info tbl;
14252
14253 tbl.tbl_id = id;
14254 tbl.tbl_len = len;
14255 tbl.tbl_offset = offset;
14256 tbl.tbl_width = width;
14257 tbl.tbl_ptr = data;
14258 wlc_phy_write_table_nphy(pi, &tbl);
14259}
14260
14261void
14262wlc_phy_table_read_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
14263 u32 width, void *data)
14264{
14265 struct phytbl_info tbl;
14266
14267 tbl.tbl_id = id;
14268 tbl.tbl_len = len;
14269 tbl.tbl_offset = offset;
14270 tbl.tbl_width = width;
14271 tbl.tbl_ptr = data;
14272 wlc_phy_read_table_nphy(pi, &tbl);
14273}
14274
14275static void
14276wlc_phy_static_table_download_nphy(struct brcms_phy *pi)
14277{
14278 uint idx;
14279
14280 if (NREV_GE(pi->pubpi.phy_rev, 16)) {
14281 for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++)
14282 wlc_phy_write_table_nphy(pi,
14283 &mimophytbl_info_rev16[idx]);
14284 } else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14285 for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++)
14286 wlc_phy_write_table_nphy(pi,
14287 &mimophytbl_info_rev7[idx]);
14288 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14289 for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++)
14290 wlc_phy_write_table_nphy(pi,
14291 &mimophytbl_info_rev3[idx]);
14292 } else {
14293 for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++)
14294 wlc_phy_write_table_nphy(pi,
14295 &mimophytbl_info_rev0[idx]);
14296 }
14297}
14298
14299static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi)
14300{
14301 uint idx = 0;
14302 u8 antswctrllut;
14303
14304 if (pi->phy_init_por)
14305 wlc_phy_static_table_download_nphy(pi);
14306
14307 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14308
14309 antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
14310 pi->srom_fem2g.antswctrllut : pi->srom_fem5g.antswctrllut;
14311
14312 switch (antswctrllut) {
14313 case 0:
14314
14315 break;
14316
14317 case 1:
14318
14319 if (pi->aa2g == 7) {
14320
14321 wlc_phy_table_write_nphy(pi,
14322 NPHY_TBL_ID_ANTSWCTRLLUT,
14323 2, 0x21, 8,
14324 &ant_sw_ctrl_tbl_rev8_2o3
14325 [0]);
14326 } else {
14327 wlc_phy_table_write_nphy(pi,
14328 NPHY_TBL_ID_ANTSWCTRLLUT,
14329 2, 0x21, 8,
14330 &ant_sw_ctrl_tbl_rev8
14331 [0]);
14332 }
14333 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14334 2, 0x25, 8,
14335 &ant_sw_ctrl_tbl_rev8[2]);
14336 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14337 2, 0x29, 8,
14338 &ant_sw_ctrl_tbl_rev8[4]);
14339 break;
14340
14341 case 2:
14342
14343 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14344 2, 0x1, 8,
14345 &ant_sw_ctrl_tbl_rev8_2057v7_core0
14346 [0]);
14347 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14348 2, 0x5, 8,
14349 &ant_sw_ctrl_tbl_rev8_2057v7_core0
14350 [2]);
14351 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14352 2, 0x9, 8,
14353 &ant_sw_ctrl_tbl_rev8_2057v7_core0
14354 [4]);
14355
14356 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14357 2, 0x21, 8,
14358 &ant_sw_ctrl_tbl_rev8_2057v7_core1
14359 [0]);
14360 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14361 2, 0x25, 8,
14362 &ant_sw_ctrl_tbl_rev8_2057v7_core1
14363 [2]);
14364 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
14365 2, 0x29, 8,
14366 &ant_sw_ctrl_tbl_rev8_2057v7_core1
14367 [4]);
14368 break;
14369
14370 default:
14371 break;
14372 }
14373
14374 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14375 for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) {
14376
14377 if (idx == ANT_SWCTRL_TBL_REV3_IDX) {
14378 antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
14379 pi->srom_fem2g.antswctrllut : pi->
14380 srom_fem5g.antswctrllut;
14381 switch (antswctrllut) {
14382 case 0:
14383 wlc_phy_write_table_nphy(pi,
14384 &mimophytbl_info_rev3_volatile
14385 [idx]);
14386 break;
14387 case 1:
14388 wlc_phy_write_table_nphy(pi,
14389 &mimophytbl_info_rev3_volatile1
14390 [idx]);
14391 break;
14392 case 2:
14393 wlc_phy_write_table_nphy(pi,
14394 &mimophytbl_info_rev3_volatile2
14395 [idx]);
14396 break;
14397 case 3:
14398 wlc_phy_write_table_nphy(pi,
14399 &mimophytbl_info_rev3_volatile3
14400 [idx]);
14401 break;
14402 default:
14403 break;
14404 }
14405 } else {
14406 wlc_phy_write_table_nphy(pi,
14407 &mimophytbl_info_rev3_volatile
14408 [idx]);
14409 }
14410 }
14411 } else {
14412 for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++) {
14413 wlc_phy_write_table_nphy(pi,
14414 &mimophytbl_info_rev0_volatile
14415 [idx]);
14416 }
14417 }
14418}
14419
14420static void
14421wlc_phy_write_txmacreg_nphy(struct brcms_phy *pi, u16 holdoff, u16 delay)
14422{
14423 write_phy_reg(pi, 0x77, holdoff);
14424 write_phy_reg(pi, 0xb4, delay);
14425}
14426
14427void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs)
14428{
14429 u16 holdoff, delay;
14430
14431 if (rifs) {
14432
14433 holdoff = 0x10;
14434 delay = 0x258;
14435 } else {
14436
14437 holdoff = 0x15;
14438 delay = 0x320;
14439 }
14440
14441 wlc_phy_write_txmacreg_nphy(pi, holdoff, delay);
14442
14443 if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) {
14444 pi->sh->_rifs_phy = rifs;
14445 }
14446}
14447
14448bool wlc_phy_attach_nphy(struct brcms_phy *pi)
14449{
14450 uint i;
14451
14452 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6)) {
14453 pi->phyhang_avoid = true;
14454 }
14455
14456 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
14457
14458 pi->nphy_gband_spurwar_en = true;
14459
14460 if (pi->sh->boardflags2 & BFL2_SPUR_WAR) {
14461 pi->nphy_aband_spurwar_en = true;
14462 }
14463 }
14464 if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) {
14465
14466 if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR) {
14467 pi->nphy_gband_spurwar2_en = true;
14468 }
14469 }
14470
14471 pi->n_preamble_override = AUTO;
14472 if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4))
14473 pi->n_preamble_override = BRCMS_N_PREAMBLE_MIXEDMODE;
14474
14475 pi->nphy_txrx_chain = AUTO;
14476 pi->phy_scraminit = AUTO;
14477
14478 pi->nphy_rxcalparams = 0x010100B5;
14479
14480 pi->nphy_perical = PHY_PERICAL_MPHASE;
14481 pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
14482 pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS;
14483
14484 pi->nphy_gain_boost = true;
14485 pi->nphy_elna_gain_config = false;
14486 pi->radio_is_on = false;
14487
14488 for (i = 0; i < pi->pubpi.phy_corenum; i++) {
14489 pi->nphy_txpwrindex[i].index = AUTO;
14490 }
14491
14492 wlc_phy_txpwrctrl_config_nphy(pi);
14493 if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
14494 pi->hwpwrctrl_capable = true;
14495
14496 pi->pi_fptr.init = wlc_phy_init_nphy;
14497 pi->pi_fptr.calinit = wlc_phy_cal_init_nphy;
14498 pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy;
14499 pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy;
14500
14501 if (!wlc_phy_txpwr_srom_read_nphy(pi))
14502 return false;
14503
14504 return true;
14505}
14506
14507static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi)
14508{
14509
14510 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14511 pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
14512 pi->phy_5g_pwrgain = true;
14513 return;
14514 }
14515
14516 pi->nphy_txpwrctrl = PHY_TPC_HW_OFF;
14517 pi->phy_5g_pwrgain = false;
14518
14519 if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) &&
14520 NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4))
14521 pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
14522 else if ((pi->sh->sromrev >= 4)
14523 && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN))
14524 pi->phy_5g_pwrgain = true;
14525}
14526
14527void wlc_phy_init_nphy(struct brcms_phy *pi)
14528{
14529 u16 val;
14530 u16 clip1_ths[2];
14531 struct nphy_txgains target_gain;
14532 u8 tx_pwr_ctrl_state;
14533 bool do_nphy_cal = false;
14534 uint core;
14535 uint origidx, intr_val;
14536 d11regs_t *regs;
14537 u32 d11_clk_ctl_st;
14538
14539 core = 0;
14540
14541 if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
14542 pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
14543 }
14544
14545 if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) &&
14546 ((pi->sh->chippkg == BCM4717_PKG_ID) ||
14547 (pi->sh->chippkg == BCM4718_PKG_ID))) {
14548 if ((pi->sh->boardflags & BFL_EXTLNA) &&
14549 (CHSPEC_IS2G(pi->radio_chanspec))) {
14550 ai_corereg(pi->sh->sih, SI_CC_IDX,
14551 offsetof(chipcregs_t, chipcontrol), 0x40,
14552 0x40);
14553 }
14554 }
14555
14556 if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
14557 CHSPEC_IS40(pi->radio_chanspec)) {
14558
14559 regs = (d11regs_t *) ai_switch_core(pi->sh->sih, D11_CORE_ID,
14560 &origidx, &intr_val);
14561 d11_clk_ctl_st = R_REG(&regs->clk_ctl_st);
14562 AND_REG(&regs->clk_ctl_st,
14563 ~(CCS_FORCEHT | CCS_HTAREQ));
14564
14565 W_REG(&regs->clk_ctl_st, d11_clk_ctl_st);
14566
14567 ai_restore_core(pi->sh->sih, origidx, intr_val);
14568 }
14569
14570 pi->use_int_tx_iqlo_cal_nphy =
14571 (PHY_IPA(pi) ||
14572 (NREV_GE(pi->pubpi.phy_rev, 7) ||
14573 (NREV_GE(pi->pubpi.phy_rev, 5)
14574 && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL)));
14575
14576 pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false;
14577
14578 pi->nphy_deaf_count = 0;
14579
14580 wlc_phy_tbl_init_nphy(pi);
14581
14582 pi->nphy_crsminpwr_adjusted = false;
14583 pi->nphy_noisevars_adjusted = false;
14584
14585 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14586 write_phy_reg(pi, 0xe7, 0);
14587 write_phy_reg(pi, 0xec, 0);
14588 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14589 write_phy_reg(pi, 0x342, 0);
14590 write_phy_reg(pi, 0x343, 0);
14591 write_phy_reg(pi, 0x346, 0);
14592 write_phy_reg(pi, 0x347, 0);
14593 }
14594 write_phy_reg(pi, 0xe5, 0);
14595 write_phy_reg(pi, 0xe6, 0);
14596 } else {
14597 write_phy_reg(pi, 0xec, 0);
14598 }
14599
14600 write_phy_reg(pi, 0x91, 0);
14601 write_phy_reg(pi, 0x92, 0);
14602 if (NREV_LT(pi->pubpi.phy_rev, 6)) {
14603 write_phy_reg(pi, 0x93, 0);
14604 write_phy_reg(pi, 0x94, 0);
14605 }
14606
14607 and_phy_reg(pi, 0xa1, ~3);
14608
14609 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14610 write_phy_reg(pi, 0x8f, 0);
14611 write_phy_reg(pi, 0xa5, 0);
14612 } else {
14613 write_phy_reg(pi, 0xa5, 0);
14614 }
14615
14616 if (NREV_IS(pi->pubpi.phy_rev, 2))
14617 mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
14618 else if (NREV_LT(pi->pubpi.phy_rev, 2))
14619 mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
14620
14621 write_phy_reg(pi, 0x203, 32);
14622 write_phy_reg(pi, 0x201, 32);
14623
14624 if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD)
14625 write_phy_reg(pi, 0x20d, 160);
14626 else
14627 write_phy_reg(pi, 0x20d, 184);
14628
14629 write_phy_reg(pi, 0x13a, 200);
14630
14631 write_phy_reg(pi, 0x70, 80);
14632
14633 write_phy_reg(pi, 0x1ff, 48);
14634
14635 if (NREV_LT(pi->pubpi.phy_rev, 8)) {
14636 wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override);
14637 }
14638
14639 wlc_phy_stf_chain_upd_nphy(pi);
14640
14641 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
14642 write_phy_reg(pi, 0x180, 0xaa8);
14643 write_phy_reg(pi, 0x181, 0x9a4);
14644 }
14645
14646 if (PHY_IPA(pi)) {
14647 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
14648
14649 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
14650 0x29b, (0x1 << 0), (1) << 0);
14651
14652 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 :
14653 0x29c, (0x1ff << 7),
14654 (pi->nphy_papd_epsilon_offset[core]) << 7);
14655
14656 }
14657
14658 wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
14659 } else {
14660
14661 if (NREV_GE(pi->pubpi.phy_rev, 5)) {
14662 wlc_phy_extpa_set_tx_digi_filts_nphy(pi);
14663 }
14664 }
14665
14666 wlc_phy_workarounds_nphy(pi);
14667
14668 wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
14669
14670 val = read_phy_reg(pi, 0x01);
14671 write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
14672 write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
14673 wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
14674
14675 wlapi_bmac_macphyclk_set(pi->sh->physhim, ON);
14676
14677 wlc_phy_pa_override_nphy(pi, OFF);
14678 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
14679 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
14680 wlc_phy_pa_override_nphy(pi, ON);
14681
14682 wlc_phy_classifier_nphy(pi, 0, 0);
14683 wlc_phy_clip_det_nphy(pi, 0, clip1_ths);
14684
14685 if (CHSPEC_IS2G(pi->radio_chanspec))
14686 wlc_phy_bphy_init_nphy(pi);
14687
14688 tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
14689 wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
14690
14691 wlc_phy_txpwr_fixpower_nphy(pi);
14692
14693 wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
14694
14695 wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
14696
14697 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14698 u32 *tx_pwrctrl_tbl = NULL;
14699 u16 idx;
14700 s16 pga_gn = 0;
14701 s16 pad_gn = 0;
14702 s32 rfpwr_offset = 0;
14703
14704 if (PHY_IPA(pi)) {
14705 tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi);
14706 } else {
14707 if (CHSPEC_IS5G(pi->radio_chanspec)) {
14708 if (NREV_IS(pi->pubpi.phy_rev, 3)) {
14709 tx_pwrctrl_tbl =
14710 nphy_tpc_5GHz_txgain_rev3;
14711 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
14712 tx_pwrctrl_tbl =
14713 (pi->srom_fem5g.extpagain == 3) ?
14714 nphy_tpc_5GHz_txgain_HiPwrEPA :
14715 nphy_tpc_5GHz_txgain_rev4;
14716 } else {
14717 tx_pwrctrl_tbl =
14718 nphy_tpc_5GHz_txgain_rev5;
14719 }
14720
14721 } else {
14722 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14723 if (pi->pubpi.radiorev == 5) {
14724 tx_pwrctrl_tbl =
14725 nphy_tpc_txgain_epa_2057rev5;
14726 } else if (pi->pubpi.radiorev == 3) {
14727 tx_pwrctrl_tbl =
14728 nphy_tpc_txgain_epa_2057rev3;
14729 }
14730
14731 } else {
14732 if (NREV_GE(pi->pubpi.phy_rev, 5) &&
14733 (pi->srom_fem2g.extpagain == 3)) {
14734 tx_pwrctrl_tbl =
14735 nphy_tpc_txgain_HiPwrEPA;
14736 } else {
14737 tx_pwrctrl_tbl =
14738 nphy_tpc_txgain_rev3;
14739 }
14740 }
14741 }
14742 }
14743
14744 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
14745 192, 32, tx_pwrctrl_tbl);
14746 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
14747 192, 32, tx_pwrctrl_tbl);
14748
14749 pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000);
14750
14751 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14752
14753 for (idx = 0; idx < 128; idx++) {
14754 pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
14755 pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f;
14756
14757 if (CHSPEC_IS2G(pi->radio_chanspec)) {
14758 if ((pi->pubpi.radiorev == 3) ||
14759 (pi->pubpi.radiorev == 4) ||
14760 (pi->pubpi.radiorev == 6)) {
14761 rfpwr_offset = (s16)
14762 nphy_papd_padgain_dlt_2g_2057rev3n4
14763 [pad_gn];
14764 } else if (pi->pubpi.radiorev == 5) {
14765 rfpwr_offset = (s16)
14766 nphy_papd_padgain_dlt_2g_2057rev5
14767 [pad_gn];
14768 } else if ((pi->pubpi.radiorev == 7)
14769 || (pi->pubpi.radiorev ==
14770 8)) {
14771 rfpwr_offset = (s16)
14772 nphy_papd_padgain_dlt_2g_2057rev7
14773 [pad_gn];
14774 }
14775 } else {
14776 if ((pi->pubpi.radiorev == 3) ||
14777 (pi->pubpi.radiorev == 4) ||
14778 (pi->pubpi.radiorev == 6)) {
14779 rfpwr_offset = (s16)
14780 nphy_papd_pgagain_dlt_5g_2057
14781 [pga_gn];
14782 } else if ((pi->pubpi.radiorev == 7)
14783 || (pi->pubpi.radiorev ==
14784 8)) {
14785 rfpwr_offset = (s16)
14786 nphy_papd_pgagain_dlt_5g_2057rev7
14787 [pga_gn];
14788 }
14789 }
14790 wlc_phy_table_write_nphy(pi,
14791 NPHY_TBL_ID_CORE1TXPWRCTL,
14792 1, 576 + idx, 32,
14793 &rfpwr_offset);
14794 wlc_phy_table_write_nphy(pi,
14795 NPHY_TBL_ID_CORE2TXPWRCTL,
14796 1, 576 + idx, 32,
14797 &rfpwr_offset);
14798 }
14799 } else {
14800
14801 for (idx = 0; idx < 128; idx++) {
14802 pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
14803 if (CHSPEC_IS2G(pi->radio_chanspec)) {
14804 rfpwr_offset = (s16)
14805 nphy_papd_pga_gain_delta_ipa_2g
14806 [pga_gn];
14807 } else {
14808 rfpwr_offset = (s16)
14809 nphy_papd_pga_gain_delta_ipa_5g
14810 [pga_gn];
14811 }
14812
14813 wlc_phy_table_write_nphy(pi,
14814 NPHY_TBL_ID_CORE1TXPWRCTL,
14815 1, 576 + idx, 32,
14816 &rfpwr_offset);
14817 wlc_phy_table_write_nphy(pi,
14818 NPHY_TBL_ID_CORE2TXPWRCTL,
14819 1, 576 + idx, 32,
14820 &rfpwr_offset);
14821 }
14822
14823 }
14824 } else {
14825
14826 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
14827 192, 32, nphy_tpc_txgain);
14828 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
14829 192, 32, nphy_tpc_txgain);
14830 }
14831
14832 if (pi->sh->phyrxchain != 0x3) {
14833 wlc_phy_rxcore_setstate_nphy((struct brcms_phy_pub *) pi,
14834 pi->sh->phyrxchain);
14835 }
14836
14837 if (PHY_PERICAL_MPHASE_PENDING(pi)) {
14838 wlc_phy_cal_perical_mphase_restart(pi);
14839 }
14840
14841 if (!NORADIO_ENAB(pi->pubpi)) {
14842 bool do_rssi_cal = false;
14843
14844 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14845 do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
14846 (pi->nphy_rssical_chanspec_2G == 0) :
14847 (pi->nphy_rssical_chanspec_5G == 0);
14848
14849 if (do_rssi_cal) {
14850 wlc_phy_rssi_cal_nphy(pi);
14851 } else {
14852 wlc_phy_restore_rssical_nphy(pi);
14853 }
14854 } else {
14855 wlc_phy_rssi_cal_nphy(pi);
14856 }
14857
14858 if (!SCAN_RM_IN_PROGRESS(pi)) {
14859 do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
14860 (pi->nphy_iqcal_chanspec_2G == 0) :
14861 (pi->nphy_iqcal_chanspec_5G == 0);
14862 }
14863
14864 if (!pi->do_initcal)
14865 do_nphy_cal = false;
14866
14867 if (do_nphy_cal) {
14868
14869 target_gain = wlc_phy_get_tx_gain_nphy(pi);
14870
14871 if (pi->antsel_type == ANTSEL_2x3)
14872 wlc_phy_antsel_init((struct brcms_phy_pub *) pi,
14873 true);
14874
14875 if (pi->nphy_perical != PHY_PERICAL_MPHASE) {
14876 wlc_phy_rssi_cal_nphy(pi);
14877
14878 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14879 pi->nphy_cal_orig_pwr_idx[0] =
14880 pi->nphy_txpwrindex[PHY_CORE_0].
14881 index_internal;
14882 pi->nphy_cal_orig_pwr_idx[1] =
14883 pi->nphy_txpwrindex[PHY_CORE_1].
14884 index_internal;
14885
14886 wlc_phy_precal_txgain_nphy(pi);
14887 target_gain =
14888 wlc_phy_get_tx_gain_nphy(pi);
14889 }
14890
14891 if (wlc_phy_cal_txiqlo_nphy
14892 (pi, target_gain, true, false) == 0) {
14893 if (wlc_phy_cal_rxiq_nphy
14894 (pi, target_gain, 2,
14895 false) == 0) {
14896 wlc_phy_savecal_nphy(pi);
14897
14898 }
14899 }
14900 } else if (pi->mphase_cal_phase_id ==
14901 MPHASE_CAL_STATE_IDLE) {
14902
14903 wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
14904 PHY_PERICAL_PHYINIT);
14905 }
14906 } else {
14907 wlc_phy_restorecal_nphy(pi);
14908 }
14909 }
14910
14911 wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
14912
14913 wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
14914
14915 wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy);
14916
14917 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6))
14918
14919 write_phy_reg(pi, 0x70, 50);
14920
14921 wlc_phy_txlpfbw_nphy(pi);
14922
14923 wlc_phy_spurwar_nphy(pi);
14924
14925}
14926
14927static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble)
14928{
14929 bool gf_preamble = false;
14930 u16 val;
14931
14932 if (preamble == BRCMS_N_PREAMBLE_GF)
14933 gf_preamble = true;
14934
14935 val = read_phy_reg(pi, 0xed);
14936
14937 val |= RX_GF_MM_AUTO;
14938 val &= ~RX_GF_OR_MM;
14939 if (gf_preamble)
14940 val |= RX_GF_OR_MM;
14941
14942 write_phy_reg(pi, 0xed, val);
14943}
14944
14945static void wlc_phy_resetcca_nphy(struct brcms_phy *pi)
14946{
14947 u16 val;
14948
14949 wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
14950
14951 val = read_phy_reg(pi, 0x01);
14952 write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
14953 udelay(1);
14954 write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
14955
14956 wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
14957
14958 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
14959}
14960
14961void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en)
14962{
14963 u16 rfctrlintc_override_val;
14964
14965 if (!en) {
14966
14967 pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91);
14968 pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92);
14969
14970 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
14971 rfctrlintc_override_val = 0x1480;
14972 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
14973 rfctrlintc_override_val =
14974 CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480;
14975 } else {
14976 rfctrlintc_override_val =
14977 CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
14978 }
14979
14980 write_phy_reg(pi, 0x91, rfctrlintc_override_val);
14981 write_phy_reg(pi, 0x92, rfctrlintc_override_val);
14982 } else {
14983
14984 write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save);
14985 write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save);
14986 }
14987
14988}
14989
14990void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi)
14991{
14992
14993 u16 txrx_chain =
14994 (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1);
14995 bool CoreActv_override = false;
14996
14997 if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN0) {
14998 txrx_chain = NPHY_RfseqCoreActv_TxRxChain0;
14999 CoreActv_override = true;
15000
15001 if (NREV_LE(pi->pubpi.phy_rev, 2)) {
15002 and_phy_reg(pi, 0xa0, ~0x20);
15003 }
15004 } else if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN1) {
15005 txrx_chain = NPHY_RfseqCoreActv_TxRxChain1;
15006 CoreActv_override = true;
15007
15008 if (NREV_LE(pi->pubpi.phy_rev, 2)) {
15009 or_phy_reg(pi, 0xa0, 0x20);
15010 }
15011 }
15012
15013 mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain);
15014
15015 if (CoreActv_override) {
15016
15017 pi->nphy_perical = PHY_PERICAL_DISABLE;
15018 or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
15019 } else {
15020 pi->nphy_perical = PHY_PERICAL_MPHASE;
15021 and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override);
15022 }
15023}
15024
15025void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask)
15026{
15027 u16 regval;
15028 u16 tbl_buf[16];
15029 uint i;
15030 struct brcms_phy *pi = (struct brcms_phy *) pih;
15031 u16 tbl_opcode;
15032 bool suspend;
15033
15034 pi->sh->phyrxchain = rxcore_bitmask;
15035
15036 if (!pi->sh->clk)
15037 return;
15038
15039 suspend =
15040 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
15041 if (!suspend)
15042 wlapi_suspend_mac_and_wait(pi->sh->physhim);
15043
15044 if (pi->phyhang_avoid)
15045 wlc_phy_stay_in_carriersearch_nphy(pi, true);
15046
15047 regval = read_phy_reg(pi, 0xa2);
15048 regval &= ~(0xf << 4);
15049 regval |= ((u16) (rxcore_bitmask & 0x3)) << 4;
15050 write_phy_reg(pi, 0xa2, regval);
15051
15052 if ((rxcore_bitmask & 0x3) != 0x3) {
15053
15054 write_phy_reg(pi, 0x20e, 1);
15055
15056 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
15057 if (pi->rx2tx_biasentry == -1) {
15058 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ,
15059 ARRAY_SIZE(tbl_buf), 80,
15060 16, tbl_buf);
15061
15062 for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) {
15063 if (tbl_buf[i] ==
15064 NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) {
15065
15066 pi->rx2tx_biasentry = (u8) i;
15067 tbl_opcode =
15068 NPHY_REV3_RFSEQ_CMD_NOP;
15069 wlc_phy_table_write_nphy(pi,
15070 NPHY_TBL_ID_RFSEQ,
15071 1, i,
15072 16,
15073 &tbl_opcode);
15074 break;
15075 } else if (tbl_buf[i] ==
15076 NPHY_REV3_RFSEQ_CMD_END) {
15077 break;
15078 }
15079 }
15080 }
15081 }
15082 } else {
15083
15084 write_phy_reg(pi, 0x20e, 30);
15085
15086 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
15087 if (pi->rx2tx_biasentry != -1) {
15088 tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS;
15089 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15090 1, pi->rx2tx_biasentry,
15091 16, &tbl_opcode);
15092 pi->rx2tx_biasentry = -1;
15093 }
15094 }
15095 }
15096
15097 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
15098
15099 if (pi->phyhang_avoid)
15100 wlc_phy_stay_in_carriersearch_nphy(pi, false);
15101
15102 if (!suspend)
15103 wlapi_enable_mac(pi->sh->physhim);
15104}
15105
15106u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih)
15107{
15108 u16 regval, rxen_bits;
15109 struct brcms_phy *pi = (struct brcms_phy *) pih;
15110
15111 regval = read_phy_reg(pi, 0xa2);
15112 rxen_bits = (regval >> 4) & 0xf;
15113
15114 return (u8) rxen_bits;
15115}
15116
15117bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pi)
15118{
15119 return PHY_IPA(pi);
15120}
15121
15122static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi)
15123{
15124 u8 idx, idx2, i, delta_ind;
15125
15126 for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++) {
15127 pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx];
15128 }
15129
15130 for (i = 0; i < 4; i++) {
15131 idx2 = 0;
15132
15133 delta_ind = 0;
15134
15135 switch (i) {
15136 case 0:
15137
15138 if (CHSPEC_IS40(pi->radio_chanspec)
15139 && NPHY_IS_SROM_REINTERPRET) {
15140 idx = TXP_FIRST_MCS_40_SISO;
15141 } else {
15142 idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
15143 TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM;
15144 delta_ind = 1;
15145 }
15146 break;
15147
15148 case 1:
15149
15150 idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
15151 TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD;
15152 break;
15153
15154 case 2:
15155
15156 idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
15157 TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC;
15158 break;
15159
15160 case 3:
15161
15162 idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
15163 TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM;
15164 break;
15165 }
15166
15167 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15168 pi->tx_power_offset[idx];
15169 idx = idx + delta_ind;
15170 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15171 pi->tx_power_offset[idx];
15172 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15173 pi->tx_power_offset[idx];
15174 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15175 pi->tx_power_offset[idx++];
15176
15177 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15178 pi->tx_power_offset[idx++];
15179 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15180 pi->tx_power_offset[idx];
15181 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15182 pi->tx_power_offset[idx];
15183 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15184 pi->tx_power_offset[idx++];
15185
15186 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15187 pi->tx_power_offset[idx++];
15188 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15189 pi->tx_power_offset[idx];
15190 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15191 pi->tx_power_offset[idx];
15192 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15193 pi->tx_power_offset[idx++];
15194
15195 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15196 pi->tx_power_offset[idx];
15197 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15198 pi->tx_power_offset[idx++];
15199 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15200 pi->tx_power_offset[idx];
15201 idx = idx + 1 - delta_ind;
15202 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15203 pi->tx_power_offset[idx];
15204
15205 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15206 pi->tx_power_offset[idx];
15207 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15208 pi->tx_power_offset[idx];
15209 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15210 pi->tx_power_offset[idx];
15211 pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
15212 pi->tx_power_offset[idx];
15213 }
15214}
15215
15216void wlc_phy_cal_init_nphy(struct brcms_phy *pi)
15217{
15218}
15219
15220static void
15221wlc_phy_war_force_trsw_to_R_cliplo_nphy(struct brcms_phy *pi, u8 core)
15222{
15223 if (core == PHY_CORE_0) {
15224 write_phy_reg(pi, 0x38, 0x4);
15225 if (CHSPEC_IS2G(pi->radio_chanspec)) {
15226 write_phy_reg(pi, 0x37, 0x0060);
15227 } else {
15228 write_phy_reg(pi, 0x37, 0x1080);
15229 }
15230 } else if (core == PHY_CORE_1) {
15231 write_phy_reg(pi, 0x2ae, 0x4);
15232 if (CHSPEC_IS2G(pi->radio_chanspec)) {
15233 write_phy_reg(pi, 0x2ad, 0x0060);
15234 } else {
15235 write_phy_reg(pi, 0x2ad, 0x1080);
15236 }
15237 }
15238}
15239
15240static void wlc_phy_war_txchain_upd_nphy(struct brcms_phy *pi, u8 txchain)
15241{
15242 u8 txchain0, txchain1;
15243
15244 txchain0 = txchain & 0x1;
15245 txchain1 = (txchain & 0x2) >> 1;
15246 if (!txchain0) {
15247 wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
15248 }
15249
15250 if (!txchain1) {
15251 wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
15252 }
15253}
15254
15255static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
15256{
15257 u8 rfseq_rx2tx_events[] = {
15258 NPHY_RFSEQ_CMD_NOP,
15259 NPHY_RFSEQ_CMD_RXG_FBW,
15260 NPHY_RFSEQ_CMD_TR_SWITCH,
15261 NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
15262 NPHY_RFSEQ_CMD_RXPD_TXPD,
15263 NPHY_RFSEQ_CMD_TX_GAIN,
15264 NPHY_RFSEQ_CMD_EXT_PA
15265 };
15266 u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
15267 u8 rfseq_tx2rx_events[] = {
15268 NPHY_RFSEQ_CMD_NOP,
15269 NPHY_RFSEQ_CMD_EXT_PA,
15270 NPHY_RFSEQ_CMD_TX_GAIN,
15271 NPHY_RFSEQ_CMD_RXPD_TXPD,
15272 NPHY_RFSEQ_CMD_TR_SWITCH,
15273 NPHY_RFSEQ_CMD_RXG_FBW,
15274 NPHY_RFSEQ_CMD_CLR_HIQ_DIS
15275 };
15276 u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
15277 u8 rfseq_tx2rx_events_rev3[] = {
15278 NPHY_REV3_RFSEQ_CMD_EXT_PA,
15279 NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
15280 NPHY_REV3_RFSEQ_CMD_TX_GAIN,
15281 NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
15282 NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
15283 NPHY_REV3_RFSEQ_CMD_RXG_FBW,
15284 NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
15285 NPHY_REV3_RFSEQ_CMD_END
15286 };
15287 u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
15288 u8 rfseq_rx2tx_events_rev3[] = {
15289 NPHY_REV3_RFSEQ_CMD_NOP,
15290 NPHY_REV3_RFSEQ_CMD_RXG_FBW,
15291 NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
15292 NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
15293 NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
15294 NPHY_REV3_RFSEQ_CMD_TX_GAIN,
15295 NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
15296 NPHY_REV3_RFSEQ_CMD_EXT_PA,
15297 NPHY_REV3_RFSEQ_CMD_END
15298 };
15299 u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
15300
15301 u8 rfseq_rx2tx_events_rev3_ipa[] = {
15302 NPHY_REV3_RFSEQ_CMD_NOP,
15303 NPHY_REV3_RFSEQ_CMD_RXG_FBW,
15304 NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
15305 NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
15306 NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
15307 NPHY_REV3_RFSEQ_CMD_TX_GAIN,
15308 NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
15309 NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
15310 NPHY_REV3_RFSEQ_CMD_END
15311 };
15312 u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
15313 u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
15314
15315 s16 alpha0, alpha1, alpha2;
15316 s16 beta0, beta1, beta2;
15317 u32 leg_data_weights, ht_data_weights, nss1_data_weights,
15318 stbc_data_weights;
15319 u8 chan_freq_range = 0;
15320 u16 dac_control = 0x0002;
15321 u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
15322 u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
15323 u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
15324 u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
15325 u16 *aux_adc_vmid;
15326 u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
15327 u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
15328 u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
15329 u16 *aux_adc_gain;
15330 u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
15331 u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
15332 s32 min_nvar_val = 0x18d;
15333 s32 min_nvar_offset_6mbps = 20;
15334 u8 pdetrange;
15335 u8 triso;
15336 u16 regval;
15337 u16 afectrl_adc_ctrl1_rev7 = 0x20;
15338 u16 afectrl_adc_ctrl2_rev7 = 0x0;
15339 u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
15340 u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
15341 u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
15342 u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
15343 u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
15344 u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
15345 u16 ipalvlshift_3p3_war_en = 0;
15346 u16 rccal_bcap_val, rccal_scap_val;
15347 u16 rccal_tx20_11b_bcap = 0;
15348 u16 rccal_tx20_11b_scap = 0;
15349 u16 rccal_tx20_11n_bcap = 0;
15350 u16 rccal_tx20_11n_scap = 0;
15351 u16 rccal_tx40_11n_bcap = 0;
15352 u16 rccal_tx40_11n_scap = 0;
15353 u16 rx2tx_lpf_rc_lut_tx20_11b = 0;
15354 u16 rx2tx_lpf_rc_lut_tx20_11n = 0;
15355 u16 rx2tx_lpf_rc_lut_tx40_11n = 0;
15356 u16 tx_lpf_bw_ofdm_20mhz = 0;
15357 u16 tx_lpf_bw_ofdm_40mhz = 0;
15358 u16 tx_lpf_bw_11b = 0;
15359 u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt;
15360 u16 txgm_idac_bleed = 0;
15361 bool rccal_ovrd = false;
15362 u16 freq;
15363 int coreNum;
15364
15365 if (CHSPEC_IS5G(pi->radio_chanspec)) {
15366 wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
15367 } else {
15368 wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
15369 }
15370
15371 if (pi->phyhang_avoid)
15372 wlc_phy_stay_in_carriersearch_nphy(pi, true);
15373
15374 or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
15375
15376 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
15377
15378 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
15379 mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
15380
15381 mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
15382 mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
15383 mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
15384 mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
15385 mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
15386 mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
15387 mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
15388 mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
15389 mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
15390 mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
15391 mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
15392 mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
15393 mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
15394 mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
15395 mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
15396 mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
15397 }
15398
15399 if (NREV_LE(pi->pubpi.phy_rev, 8)) {
15400 write_phy_reg(pi, 0x23f, 0x1b0);
15401 write_phy_reg(pi, 0x240, 0x1b0);
15402 }
15403
15404 if (NREV_GE(pi->pubpi.phy_rev, 8)) {
15405 mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
15406 }
15407
15408 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
15409 &dac_control);
15410 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
15411 &dac_control);
15412
15413 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
15414 1, 0, 32, &leg_data_weights);
15415 leg_data_weights = leg_data_weights & 0xffffff;
15416 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
15417 1, 0, 32, &leg_data_weights);
15418
15419 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15420 2, 0x15e, 16,
15421 rfseq_rx2tx_dacbufpu_rev7);
15422 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
15423 rfseq_rx2tx_dacbufpu_rev7);
15424
15425 if (PHY_IPA(pi)) {
15426 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
15427 rfseq_rx2tx_events_rev3_ipa,
15428 rfseq_rx2tx_dlys_rev3_ipa,
15429 sizeof
15430 (rfseq_rx2tx_events_rev3_ipa) /
15431 sizeof
15432 (rfseq_rx2tx_events_rev3_ipa
15433 [0]));
15434 }
15435
15436 mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
15437 mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
15438
15439 tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
15440 tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
15441 tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
15442
15443 if (PHY_IPA(pi)) {
15444
15445 if (((pi->pubpi.radiorev == 5)
15446 && (CHSPEC_IS40(pi->radio_chanspec) == 1))
15447 || (pi->pubpi.radiorev == 7)
15448 || (pi->pubpi.radiorev == 8)) {
15449
15450 rccal_bcap_val =
15451 read_radio_reg(pi,
15452 RADIO_2057_RCCAL_BCAP_VAL);
15453 rccal_scap_val =
15454 read_radio_reg(pi,
15455 RADIO_2057_RCCAL_SCAP_VAL);
15456
15457 rccal_tx20_11b_bcap = rccal_bcap_val;
15458 rccal_tx20_11b_scap = rccal_scap_val;
15459
15460 if ((pi->pubpi.radiorev == 5) &&
15461 (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
15462
15463 rccal_tx20_11n_bcap = rccal_bcap_val;
15464 rccal_tx20_11n_scap = rccal_scap_val;
15465 rccal_tx40_11n_bcap = 0xc;
15466 rccal_tx40_11n_scap = 0xc;
15467
15468 rccal_ovrd = true;
15469
15470 } else if ((pi->pubpi.radiorev == 7)
15471 || (pi->pubpi.radiorev == 8)) {
15472
15473 tx_lpf_bw_ofdm_20mhz = 4;
15474 tx_lpf_bw_11b = 1;
15475
15476 if (CHSPEC_IS2G(pi->radio_chanspec)) {
15477 rccal_tx20_11n_bcap = 0xc;
15478 rccal_tx20_11n_scap = 0xc;
15479 rccal_tx40_11n_bcap = 0xa;
15480 rccal_tx40_11n_scap = 0xa;
15481 } else {
15482 rccal_tx20_11n_bcap = 0x14;
15483 rccal_tx20_11n_scap = 0x14;
15484 rccal_tx40_11n_bcap = 0xf;
15485 rccal_tx40_11n_scap = 0xf;
15486 }
15487
15488 rccal_ovrd = true;
15489 }
15490 }
15491
15492 } else {
15493
15494 if (pi->pubpi.radiorev == 5) {
15495
15496 tx_lpf_bw_ofdm_20mhz = 1;
15497 tx_lpf_bw_ofdm_40mhz = 3;
15498
15499 rccal_bcap_val =
15500 read_radio_reg(pi,
15501 RADIO_2057_RCCAL_BCAP_VAL);
15502 rccal_scap_val =
15503 read_radio_reg(pi,
15504 RADIO_2057_RCCAL_SCAP_VAL);
15505
15506 rccal_tx20_11b_bcap = rccal_bcap_val;
15507 rccal_tx20_11b_scap = rccal_scap_val;
15508
15509 rccal_tx20_11n_bcap = 0x13;
15510 rccal_tx20_11n_scap = 0x11;
15511 rccal_tx40_11n_bcap = 0x13;
15512 rccal_tx40_11n_scap = 0x11;
15513
15514 rccal_ovrd = true;
15515 }
15516 }
15517
15518 if (rccal_ovrd) {
15519
15520 rx2tx_lpf_rc_lut_tx20_11b = (rccal_tx20_11b_bcap << 8) |
15521 (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b;
15522 rx2tx_lpf_rc_lut_tx20_11n = (rccal_tx20_11n_bcap << 8) |
15523 (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz;
15524 rx2tx_lpf_rc_lut_tx40_11n = (rccal_tx40_11n_bcap << 8) |
15525 (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz;
15526
15527 for (coreNum = 0; coreNum <= 1; coreNum++) {
15528 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15529 1,
15530 0x152 + coreNum * 0x10,
15531 16,
15532 &rx2tx_lpf_rc_lut_tx20_11b);
15533 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15534 1,
15535 0x153 + coreNum * 0x10,
15536 16,
15537 &rx2tx_lpf_rc_lut_tx20_11n);
15538 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15539 1,
15540 0x154 + coreNum * 0x10,
15541 16,
15542 &rx2tx_lpf_rc_lut_tx20_11n);
15543 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15544 1,
15545 0x155 + coreNum * 0x10,
15546 16,
15547 &rx2tx_lpf_rc_lut_tx40_11n);
15548 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15549 1,
15550 0x156 + coreNum * 0x10,
15551 16,
15552 &rx2tx_lpf_rc_lut_tx40_11n);
15553 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15554 1,
15555 0x157 + coreNum * 0x10,
15556 16,
15557 &rx2tx_lpf_rc_lut_tx40_11n);
15558 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15559 1,
15560 0x158 + coreNum * 0x10,
15561 16,
15562 &rx2tx_lpf_rc_lut_tx40_11n);
15563 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
15564 1,
15565 0x159 + coreNum * 0x10,
15566 16,
15567 &rx2tx_lpf_rc_lut_tx40_11n);
15568 }
15569
15570 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4),
15571 1, 0x3, 0,
15572 NPHY_REV7_RFCTRLOVERRIDE_ID2);
15573 }
15574
15575 if (!NORADIO_ENAB(pi->pubpi)) {
15576 write_phy_reg(pi, 0x32f, 0x3);
15577 }
15578
15579 if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) {
15580 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
15581 1, 0x3, 0,
15582 NPHY_REV7_RFCTRLOVERRIDE_ID0);
15583 }
15584
15585 if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
15586 (pi->pubpi.radiorev == 6)) {
15587 if ((pi->sh->sromrev >= 8)
15588 && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
15589 ipalvlshift_3p3_war_en = 1;
15590
15591 if (ipalvlshift_3p3_war_en) {
15592 write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
15593 0x5);
15594 write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
15595 0x30);
15596 write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
15597 or_radio_reg(pi,
15598 RADIO_2057_RXTXBIAS_CONFIG_CORE0,
15599 0x1);
15600 or_radio_reg(pi,
15601 RADIO_2057_RXTXBIAS_CONFIG_CORE1,
15602 0x1);
15603
15604 ipa2g_mainbias = 0x1f;
15605
15606 ipa2g_casconv = 0x6f;
15607
15608 ipa2g_biasfilt = 0xaa;
15609 } else {
15610
15611 ipa2g_mainbias = 0x2b;
15612
15613 ipa2g_casconv = 0x7f;
15614
15615 ipa2g_biasfilt = 0xee;
15616 }
15617
15618 if (CHSPEC_IS2G(pi->radio_chanspec)) {
15619 for (coreNum = 0; coreNum <= 1; coreNum++) {
15620 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
15621 coreNum, IPA2G_IMAIN,
15622 ipa2g_mainbias);
15623 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
15624 coreNum, IPA2G_CASCONV,
15625 ipa2g_casconv);
15626 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
15627 coreNum,
15628 IPA2G_BIAS_FILTER,
15629 ipa2g_biasfilt);
15630 }
15631 }
15632 }
15633
15634 if (PHY_IPA(pi)) {
15635 if (CHSPEC_IS2G(pi->radio_chanspec)) {
15636 if ((pi->pubpi.radiorev == 3)
15637 || (pi->pubpi.radiorev == 4)
15638 || (pi->pubpi.radiorev == 6)) {
15639
15640 txgm_idac_bleed = 0x7f;
15641 }
15642
15643 for (coreNum = 0; coreNum <= 1; coreNum++) {
15644 if (txgm_idac_bleed != 0)
15645 WRITE_RADIO_REG4(pi, RADIO_2057,
15646 CORE, coreNum,
15647 TXGM_IDAC_BLEED,
15648 txgm_idac_bleed);
15649 }
15650
15651 if (pi->pubpi.radiorev == 5) {
15652
15653 for (coreNum = 0; coreNum <= 1;
15654 coreNum++) {
15655 WRITE_RADIO_REG4(pi, RADIO_2057,
15656 CORE, coreNum,
15657 IPA2G_CASCONV,
15658 0x13);
15659 WRITE_RADIO_REG4(pi, RADIO_2057,
15660 CORE, coreNum,
15661 IPA2G_IMAIN,
15662 0x1f);
15663 WRITE_RADIO_REG4(pi, RADIO_2057,
15664 CORE, coreNum,
15665 IPA2G_BIAS_FILTER,
15666 0xee);
15667 WRITE_RADIO_REG4(pi, RADIO_2057,
15668 CORE, coreNum,
15669 PAD2G_IDACS,
15670 0x8a);
15671 WRITE_RADIO_REG4(pi, RADIO_2057,
15672 CORE, coreNum,
15673 PAD_BIAS_FILTER_BWS,
15674 0x3e);
15675 }
15676
15677 } else if ((pi->pubpi.radiorev == 7)
15678 || (pi->pubpi.radiorev == 8)) {
15679
15680 if (CHSPEC_IS40(pi->radio_chanspec) ==
15681 0) {
15682 WRITE_RADIO_REG4(pi, RADIO_2057,
15683 CORE, 0,
15684 IPA2G_IMAIN,
15685 0x14);
15686 WRITE_RADIO_REG4(pi, RADIO_2057,
15687 CORE, 1,
15688 IPA2G_IMAIN,
15689 0x12);
15690 } else {
15691 WRITE_RADIO_REG4(pi, RADIO_2057,
15692 CORE, 0,
15693 IPA2G_IMAIN,
15694 0x16);
15695 WRITE_RADIO_REG4(pi, RADIO_2057,
15696 CORE, 1,
15697 IPA2G_IMAIN,
15698 0x16);
15699 }
15700 }
15701
15702 } else {
15703 freq =
15704 CHAN5G_FREQ(CHSPEC_CHANNEL
15705 (pi->radio_chanspec));
15706 if (((freq >= 5180) && (freq <= 5230))
15707 || ((freq >= 5745) && (freq <= 5805))) {
15708 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
15709 0, IPA5G_BIAS_FILTER,
15710 0xff);
15711 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
15712 1, IPA5G_BIAS_FILTER,
15713 0xff);
15714 }
15715 }
15716 } else {
15717
15718 if (pi->pubpi.radiorev != 5) {
15719 for (coreNum = 0; coreNum <= 1; coreNum++) {
15720 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
15721 coreNum,
15722 TXMIX2G_TUNE_BOOST_PU,
15723 0x61);
15724 WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
15725 coreNum,
15726 TXGM_IDAC_BLEED, 0x70);
15727 }
15728 }
15729 }
15730
15731 if (pi->pubpi.radiorev == 4) {
15732 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
15733 0x05, 16,
15734 &afectrl_adc_ctrl1_rev7);
15735 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
15736 0x15, 16,
15737 &afectrl_adc_ctrl1_rev7);
15738
15739 for (coreNum = 0; coreNum <= 1; coreNum++) {
15740 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
15741 AFE_VCM_CAL_MASTER, 0x0);
15742 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
15743 AFE_SET_VCM_I, 0x3f);
15744 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
15745 AFE_SET_VCM_Q, 0x3f);
15746 }
15747 } else {
15748 mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
15749 mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
15750 mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
15751 mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
15752
15753 mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
15754 mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
15755 mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
15756 mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
15757
15758 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
15759 0x05, 16,
15760 &afectrl_adc_ctrl2_rev7);
15761 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
15762 0x15, 16,
15763 &afectrl_adc_ctrl2_rev7);
15764
15765 mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
15766 mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
15767 mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
15768 mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
15769 }
15770
15771 write_phy_reg(pi, 0x6a, 0x2);
15772
15773 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
15774 &min_nvar_offset_6mbps);
15775
15776 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
15777 &rfseq_pktgn_lpf_hpc_rev7);
15778
15779 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
15780 &rfseq_pktgn_lpf_h_hpc_rev7);
15781
15782 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
15783 &rfseq_htpktgn_lpf_hpc_rev7);
15784
15785 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
15786 &rfseq_cckpktgn_lpf_hpc_rev7);
15787
15788 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
15789 &rfseq_tx2rx_lpf_h_hpc_rev7);
15790
15791 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
15792 &rfseq_rx2tx_lpf_h_hpc_rev7);
15793
15794 if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
15795 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
15796 32, &min_nvar_val);
15797 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
15798 127, 32, &min_nvar_val);
15799 } else {
15800 min_nvar_val = noise_var_tbl_rev7[3];
15801 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
15802 32, &min_nvar_val);
15803
15804 min_nvar_val = noise_var_tbl_rev7[127];
15805 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
15806 127, 32, &min_nvar_val);
15807 }
15808
15809 wlc_phy_workarounds_nphy_gainctrl(pi);
15810
15811 pdetrange =
15812 (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
15813 pdetrange : pi->srom_fem2g.pdetrange;
15814
15815 if (pdetrange == 0) {
15816 chan_freq_range =
15817 wlc_phy_get_chan_freq_range_nphy(pi, 0);
15818 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
15819 aux_adc_vmid_rev7_core0[3] = 0x70;
15820 aux_adc_vmid_rev7_core1[3] = 0x70;
15821 aux_adc_gain_rev7[3] = 2;
15822 } else {
15823 aux_adc_vmid_rev7_core0[3] = 0x80;
15824 aux_adc_vmid_rev7_core1[3] = 0x80;
15825 aux_adc_gain_rev7[3] = 3;
15826 }
15827 } else if (pdetrange == 1) {
15828 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
15829 aux_adc_vmid_rev7_core0[3] = 0x7c;
15830 aux_adc_vmid_rev7_core1[3] = 0x7c;
15831 aux_adc_gain_rev7[3] = 2;
15832 } else {
15833 aux_adc_vmid_rev7_core0[3] = 0x8c;
15834 aux_adc_vmid_rev7_core1[3] = 0x8c;
15835 aux_adc_gain_rev7[3] = 1;
15836 }
15837 } else if (pdetrange == 2) {
15838 if (pi->pubpi.radioid == BCM2057_ID) {
15839 if ((pi->pubpi.radiorev == 5)
15840 || (pi->pubpi.radiorev == 7)
15841 || (pi->pubpi.radiorev == 8)) {
15842 if (chan_freq_range ==
15843 WL_CHAN_FREQ_RANGE_2G) {
15844 aux_adc_vmid_rev7_core0[3] =
15845 0x8c;
15846 aux_adc_vmid_rev7_core1[3] =
15847 0x8c;
15848 aux_adc_gain_rev7[3] = 0;
15849 } else {
15850 aux_adc_vmid_rev7_core0[3] =
15851 0x96;
15852 aux_adc_vmid_rev7_core1[3] =
15853 0x96;
15854 aux_adc_gain_rev7[3] = 0;
15855 }
15856 }
15857 }
15858
15859 } else if (pdetrange == 3) {
15860 if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
15861 aux_adc_vmid_rev7_core0[3] = 0x89;
15862 aux_adc_vmid_rev7_core1[3] = 0x89;
15863 aux_adc_gain_rev7[3] = 0;
15864 }
15865
15866 } else if (pdetrange == 5) {
15867
15868 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
15869 aux_adc_vmid_rev7_core0[3] = 0x80;
15870 aux_adc_vmid_rev7_core1[3] = 0x80;
15871 aux_adc_gain_rev7[3] = 3;
15872 } else {
15873 aux_adc_vmid_rev7_core0[3] = 0x70;
15874 aux_adc_vmid_rev7_core1[3] = 0x70;
15875 aux_adc_gain_rev7[3] = 2;
15876 }
15877 }
15878
15879 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
15880 &aux_adc_vmid_rev7_core0);
15881 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
15882 &aux_adc_vmid_rev7_core1);
15883 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
15884 &aux_adc_gain_rev7);
15885 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
15886 &aux_adc_gain_rev7);
15887
15888 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
15889
15890 write_phy_reg(pi, 0x23f, 0x1f8);
15891 write_phy_reg(pi, 0x240, 0x1f8);
15892
15893 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
15894 1, 0, 32, &leg_data_weights);
15895 leg_data_weights = leg_data_weights & 0xffffff;
15896 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
15897 1, 0, 32, &leg_data_weights);
15898
15899 alpha0 = 293;
15900 alpha1 = 435;
15901 alpha2 = 261;
15902 beta0 = 366;
15903 beta1 = 205;
15904 beta2 = 32;
15905 write_phy_reg(pi, 0x145, alpha0);
15906 write_phy_reg(pi, 0x146, alpha1);
15907 write_phy_reg(pi, 0x147, alpha2);
15908 write_phy_reg(pi, 0x148, beta0);
15909 write_phy_reg(pi, 0x149, beta1);
15910 write_phy_reg(pi, 0x14a, beta2);
15911
15912 write_phy_reg(pi, 0x38, 0xC);
15913 write_phy_reg(pi, 0x2ae, 0xC);
15914
15915 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
15916 rfseq_tx2rx_events_rev3,
15917 rfseq_tx2rx_dlys_rev3,
15918 sizeof(rfseq_tx2rx_events_rev3) /
15919 sizeof(rfseq_tx2rx_events_rev3[0]));
15920
15921 if (PHY_IPA(pi)) {
15922 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
15923 rfseq_rx2tx_events_rev3_ipa,
15924 rfseq_rx2tx_dlys_rev3_ipa,
15925 sizeof
15926 (rfseq_rx2tx_events_rev3_ipa) /
15927 sizeof
15928 (rfseq_rx2tx_events_rev3_ipa
15929 [0]));
15930 }
15931
15932 if ((pi->sh->hw_phyrxchain != 0x3) &&
15933 (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
15934
15935 if (PHY_IPA(pi)) {
15936 rfseq_rx2tx_dlys_rev3[5] = 59;
15937 rfseq_rx2tx_dlys_rev3[6] = 1;
15938 rfseq_rx2tx_events_rev3[7] =
15939 NPHY_REV3_RFSEQ_CMD_END;
15940 }
15941
15942 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
15943 rfseq_rx2tx_events_rev3,
15944 rfseq_rx2tx_dlys_rev3,
15945 sizeof(rfseq_rx2tx_events_rev3) /
15946 sizeof(rfseq_rx2tx_events_rev3
15947 [0]));
15948 }
15949
15950 if (CHSPEC_IS2G(pi->radio_chanspec)) {
15951 write_phy_reg(pi, 0x6a, 0x2);
15952 } else {
15953 write_phy_reg(pi, 0x6a, 0x9c40);
15954 }
15955
15956 mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
15957
15958 if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
15959 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
15960 32, &min_nvar_val);
15961 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
15962 127, 32, &min_nvar_val);
15963 } else {
15964 min_nvar_val = noise_var_tbl_rev3[3];
15965 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
15966 32, &min_nvar_val);
15967
15968 min_nvar_val = noise_var_tbl_rev3[127];
15969 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
15970 127, 32, &min_nvar_val);
15971 }
15972
15973 wlc_phy_workarounds_nphy_gainctrl(pi);
15974
15975 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
15976 &dac_control);
15977 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
15978 &dac_control);
15979
15980 pdetrange =
15981 (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
15982 pdetrange : pi->srom_fem2g.pdetrange;
15983
15984 if (pdetrange == 0) {
15985 if (NREV_GE(pi->pubpi.phy_rev, 4)) {
15986 aux_adc_vmid = aux_adc_vmid_rev4;
15987 aux_adc_gain = aux_adc_gain_rev4;
15988 } else {
15989 aux_adc_vmid = aux_adc_vmid_rev3;
15990 aux_adc_gain = aux_adc_gain_rev3;
15991 }
15992 chan_freq_range =
15993 wlc_phy_get_chan_freq_range_nphy(pi, 0);
15994 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
15995 switch (chan_freq_range) {
15996 case WL_CHAN_FREQ_RANGE_5GL:
15997 aux_adc_vmid[3] = 0x89;
15998 aux_adc_gain[3] = 0;
15999 break;
16000 case WL_CHAN_FREQ_RANGE_5GM:
16001 aux_adc_vmid[3] = 0x89;
16002 aux_adc_gain[3] = 0;
16003 break;
16004 case WL_CHAN_FREQ_RANGE_5GH:
16005 aux_adc_vmid[3] = 0x89;
16006 aux_adc_gain[3] = 0;
16007 break;
16008 default:
16009 break;
16010 }
16011 }
16012 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16013 0x08, 16, aux_adc_vmid);
16014 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16015 0x18, 16, aux_adc_vmid);
16016 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16017 0x0c, 16, aux_adc_gain);
16018 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16019 0x1c, 16, aux_adc_gain);
16020 } else if (pdetrange == 1) {
16021 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16022 0x08, 16, sk_adc_vmid);
16023 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16024 0x18, 16, sk_adc_vmid);
16025 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16026 0x0c, 16, sk_adc_gain);
16027 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16028 0x1c, 16, sk_adc_gain);
16029 } else if (pdetrange == 2) {
16030
16031 u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
16032 u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
16033
16034 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
16035 chan_freq_range =
16036 wlc_phy_get_chan_freq_range_nphy(pi, 0);
16037 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
16038 bcm_adc_vmid[3] = 0x8e;
16039 bcm_adc_gain[3] = 0x03;
16040 } else {
16041 bcm_adc_vmid[3] = 0x94;
16042 bcm_adc_gain[3] = 0x03;
16043 }
16044 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
16045 bcm_adc_vmid[3] = 0x84;
16046 bcm_adc_gain[3] = 0x02;
16047 }
16048
16049 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16050 0x08, 16, bcm_adc_vmid);
16051 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16052 0x18, 16, bcm_adc_vmid);
16053 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16054 0x0c, 16, bcm_adc_gain);
16055 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16056 0x1c, 16, bcm_adc_gain);
16057 } else if (pdetrange == 3) {
16058 chan_freq_range =
16059 wlc_phy_get_chan_freq_range_nphy(pi, 0);
16060 if ((NREV_GE(pi->pubpi.phy_rev, 4))
16061 && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
16062
16063 u16 auxadc_vmid[] = {
16064 0xa2, 0xb4, 0xb4, 0x270 };
16065 u16 auxadc_gain[] = {
16066 0x02, 0x02, 0x02, 0x00 };
16067
16068 wlc_phy_table_write_nphy(pi,
16069 NPHY_TBL_ID_AFECTRL, 4,
16070 0x08, 16, auxadc_vmid);
16071 wlc_phy_table_write_nphy(pi,
16072 NPHY_TBL_ID_AFECTRL, 4,
16073 0x18, 16, auxadc_vmid);
16074 wlc_phy_table_write_nphy(pi,
16075 NPHY_TBL_ID_AFECTRL, 4,
16076 0x0c, 16, auxadc_gain);
16077 wlc_phy_table_write_nphy(pi,
16078 NPHY_TBL_ID_AFECTRL, 4,
16079 0x1c, 16, auxadc_gain);
16080 }
16081 } else if ((pdetrange == 4) || (pdetrange == 5)) {
16082 u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
16083 u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
16084 u16 Vmid[2], Av[2];
16085
16086 chan_freq_range =
16087 wlc_phy_get_chan_freq_range_nphy(pi, 0);
16088 if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
16089 Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
16090 Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
16091 Av[0] = (pdetrange == 4) ? 2 : 0;
16092 Av[1] = (pdetrange == 4) ? 2 : 0;
16093 } else {
16094 Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
16095 Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
16096 Av[0] = (pdetrange == 4) ? 2 : 0;
16097 Av[1] = (pdetrange == 4) ? 2 : 0;
16098 }
16099
16100 bcm_adc_vmid[3] = Vmid[0];
16101 bcm_adc_gain[3] = Av[0];
16102 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16103 0x08, 16, bcm_adc_vmid);
16104 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16105 0x0c, 16, bcm_adc_gain);
16106
16107 bcm_adc_vmid[3] = Vmid[1];
16108 bcm_adc_gain[3] = Av[1];
16109 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16110 0x18, 16, bcm_adc_vmid);
16111 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
16112 0x1c, 16, bcm_adc_gain);
16113 }
16114
16115 write_radio_reg(pi,
16116 (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
16117 0x0);
16118 write_radio_reg(pi,
16119 (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
16120 0x0);
16121
16122 write_radio_reg(pi,
16123 (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
16124 0x6);
16125 write_radio_reg(pi,
16126 (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
16127 0x6);
16128
16129 write_radio_reg(pi,
16130 (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
16131 0x7);
16132 write_radio_reg(pi,
16133 (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
16134 0x7);
16135
16136 write_radio_reg(pi,
16137 (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
16138 0x88);
16139 write_radio_reg(pi,
16140 (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
16141 0x88);
16142
16143 write_radio_reg(pi,
16144 (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
16145 0x0);
16146 write_radio_reg(pi,
16147 (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
16148 0x0);
16149
16150 write_radio_reg(pi,
16151 (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
16152 0x0);
16153 write_radio_reg(pi,
16154 (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
16155 0x0);
16156
16157 triso =
16158 (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
16159 triso : pi->srom_fem2g.triso;
16160 if (triso == 7) {
16161 wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
16162 wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
16163 }
16164
16165 wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
16166
16167 if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
16168 (CHSPEC_IS5G(pi->radio_chanspec))) ||
16169 (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
16170 (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
16171 (CHSPEC_IS2G(pi->radio_chanspec)))) {
16172 nss1_data_weights = 0x00088888;
16173 ht_data_weights = 0x00088888;
16174 stbc_data_weights = 0x00088888;
16175 } else {
16176 nss1_data_weights = 0x88888888;
16177 ht_data_weights = 0x88888888;
16178 stbc_data_weights = 0x88888888;
16179 }
16180 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
16181 1, 1, 32, &nss1_data_weights);
16182 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
16183 1, 2, 32, &ht_data_weights);
16184 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
16185 1, 3, 32, &stbc_data_weights);
16186
16187 if (NREV_IS(pi->pubpi.phy_rev, 4)) {
16188 if (CHSPEC_IS5G(pi->radio_chanspec)) {
16189 write_radio_reg(pi,
16190 RADIO_2056_TX_GMBB_IDAC |
16191 RADIO_2056_TX0, 0x70);
16192 write_radio_reg(pi,
16193 RADIO_2056_TX_GMBB_IDAC |
16194 RADIO_2056_TX1, 0x70);
16195 }
16196 }
16197
16198 if (!pi->edcrs_threshold_lock) {
16199 write_phy_reg(pi, 0x224, 0x3eb);
16200 write_phy_reg(pi, 0x225, 0x3eb);
16201 write_phy_reg(pi, 0x226, 0x341);
16202 write_phy_reg(pi, 0x227, 0x341);
16203 write_phy_reg(pi, 0x228, 0x42b);
16204 write_phy_reg(pi, 0x229, 0x42b);
16205 write_phy_reg(pi, 0x22a, 0x381);
16206 write_phy_reg(pi, 0x22b, 0x381);
16207 write_phy_reg(pi, 0x22c, 0x42b);
16208 write_phy_reg(pi, 0x22d, 0x42b);
16209 write_phy_reg(pi, 0x22e, 0x381);
16210 write_phy_reg(pi, 0x22f, 0x381);
16211 }
16212
16213 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
16214
16215 if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) {
16216 wlapi_bmac_mhf(pi->sh->physhim, MHF4,
16217 MHF4_BPHY_TXCORE0,
16218 MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
16219 }
16220 }
16221 } else {
16222
16223 if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
16224 (pi->sh->boardtype == 0x8b)) {
16225 uint i;
16226 u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
16227 for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
16228 rfseq_rx2tx_dlys[i] = war_dlys[i];
16229 }
16230
16231 if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
16232 and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
16233 and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
16234 } else {
16235 or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
16236 or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
16237 }
16238
16239 regval = 0x000a;
16240 wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
16241 wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
16242
16243 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
16244 regval = 0xcdaa;
16245 wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
16246 wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
16247 }
16248
16249 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
16250 regval = 0x0000;
16251 wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
16252 wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
16253
16254 regval = 0x7aab;
16255 wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
16256 wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
16257
16258 regval = 0x0800;
16259 wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
16260 wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
16261 }
16262
16263 write_phy_reg(pi, 0xf8, 0x02d8);
16264 write_phy_reg(pi, 0xf9, 0x0301);
16265 write_phy_reg(pi, 0xfa, 0x02d8);
16266 write_phy_reg(pi, 0xfb, 0x0301);
16267
16268 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
16269 rfseq_rx2tx_dlys,
16270 sizeof(rfseq_rx2tx_events) /
16271 sizeof(rfseq_rx2tx_events[0]));
16272
16273 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
16274 rfseq_tx2rx_dlys,
16275 sizeof(rfseq_tx2rx_events) /
16276 sizeof(rfseq_tx2rx_events[0]));
16277
16278 wlc_phy_workarounds_nphy_gainctrl(pi);
16279
16280 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
16281
16282 if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
16283 wlapi_bmac_mhf(pi->sh->physhim, MHF3,
16284 MHF3_NPHY_MLADV_WAR,
16285 MHF3_NPHY_MLADV_WAR,
16286 BRCM_BAND_ALL);
16287
16288 } else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
16289 write_phy_reg(pi, 0x1e3, 0x0);
16290 write_phy_reg(pi, 0x1e4, 0x0);
16291 }
16292
16293 if (NREV_LT(pi->pubpi.phy_rev, 2))
16294 mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
16295
16296 alpha0 = 293;
16297 alpha1 = 435;
16298 alpha2 = 261;
16299 beta0 = 366;
16300 beta1 = 205;
16301 beta2 = 32;
16302 write_phy_reg(pi, 0x145, alpha0);
16303 write_phy_reg(pi, 0x146, alpha1);
16304 write_phy_reg(pi, 0x147, alpha2);
16305 write_phy_reg(pi, 0x148, beta0);
16306 write_phy_reg(pi, 0x149, beta1);
16307 write_phy_reg(pi, 0x14a, beta2);
16308
16309 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
16310 mod_phy_reg(pi, 0x142, (0xf << 12), 0);
16311
16312 write_phy_reg(pi, 0x192, 0xb5);
16313 write_phy_reg(pi, 0x193, 0xa4);
16314 write_phy_reg(pi, 0x194, 0x0);
16315 }
16316
16317 if (NREV_IS(pi->pubpi.phy_rev, 2)) {
16318 mod_phy_reg(pi, 0x221,
16319 NPHY_FORCESIG_DECODEGATEDCLKS,
16320 NPHY_FORCESIG_DECODEGATEDCLKS);
16321 }
16322 }
16323
16324 if (pi->phyhang_avoid)
16325 wlc_phy_stay_in_carriersearch_nphy(pi, false);
16326}
16327
16328static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
16329{
16330 u16 w1th, hpf_code, currband;
16331 int ctr;
16332 u8 rfseq_updategainu_events[] = {
16333 NPHY_RFSEQ_CMD_RX_GAIN,
16334 NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
16335 NPHY_RFSEQ_CMD_SET_HPF_BW
16336 };
16337 u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
16338 s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
16339 s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
16340 s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
16341 s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
16342 s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
16343 s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
16344 s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
16345 s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
16346 s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
16347 s8 *lna1_gain_db = NULL;
16348 s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
16349 s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
16350 s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
16351 s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
16352 s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
16353 s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
16354 s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
16355 s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
16356 s8 *lna2_gain_db = NULL;
16357 s8 tiaG_gain_db[] = {
16358 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
16359 s8 tiaA_gain_db[] = {
16360 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
16361 s8 tiaA_gain_db_rev4[] = {
16362 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
16363 s8 tiaA_gain_db_rev5[] = {
16364 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
16365 s8 tiaA_gain_db_rev6[] = {
16366 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
16367 s8 *tia_gain_db;
16368 s8 tiaG_gainbits[] = {
16369 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
16370 s8 tiaA_gainbits[] = {
16371 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
16372 s8 tiaA_gainbits_rev4[] = {
16373 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
16374 s8 tiaA_gainbits_rev5[] = {
16375 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
16376 s8 tiaA_gainbits_rev6[] = {
16377 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
16378 s8 *tia_gainbits;
16379 s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
16380 s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
16381 u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
16382 u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
16383 u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
16384 u16 rfseqG_init_gain_rev5_elna[] = {
16385 0x013f, 0x013f, 0x013f, 0x013f };
16386 u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
16387 u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
16388 u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
16389 u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
16390 u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
16391 u16 rfseqA_init_gain_rev4_elna[] = {
16392 0x314f, 0x314f, 0x314f, 0x314f };
16393 u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
16394 u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
16395 u16 *rfseq_init_gain;
16396 u16 initG_gaincode = 0x627e;
16397 u16 initG_gaincode_rev4 = 0x527e;
16398 u16 initG_gaincode_rev5 = 0x427e;
16399 u16 initG_gaincode_rev5_elna = 0x027e;
16400 u16 initG_gaincode_rev6 = 0x527e;
16401 u16 initG_gaincode_rev6_224B0 = 0x427e;
16402 u16 initG_gaincode_rev6_elna = 0x127e;
16403 u16 initA_gaincode = 0x52de;
16404 u16 initA_gaincode_rev4 = 0x629e;
16405 u16 initA_gaincode_rev4_elna = 0x329e;
16406 u16 initA_gaincode_rev5 = 0x729e;
16407 u16 initA_gaincode_rev6 = 0x729e;
16408 u16 init_gaincode;
16409 u16 clip1hiG_gaincode = 0x107e;
16410 u16 clip1hiG_gaincode_rev4 = 0x007e;
16411 u16 clip1hiG_gaincode_rev5 = 0x1076;
16412 u16 clip1hiG_gaincode_rev6 = 0x007e;
16413 u16 clip1hiA_gaincode = 0x00de;
16414 u16 clip1hiA_gaincode_rev4 = 0x029e;
16415 u16 clip1hiA_gaincode_rev5 = 0x029e;
16416 u16 clip1hiA_gaincode_rev6 = 0x029e;
16417 u16 clip1hi_gaincode;
16418 u16 clip1mdG_gaincode = 0x0066;
16419 u16 clip1mdA_gaincode = 0x00ca;
16420 u16 clip1mdA_gaincode_rev4 = 0x1084;
16421 u16 clip1mdA_gaincode_rev5 = 0x2084;
16422 u16 clip1mdA_gaincode_rev6 = 0x2084;
16423 u16 clip1md_gaincode = 0;
16424 u16 clip1loG_gaincode = 0x0074;
16425 u16 clip1loG_gaincode_rev5[] = {
16426 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
16427 };
16428 u16 clip1loG_gaincode_rev6[] = {
16429 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
16430 };
16431 u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
16432 u16 clip1loA_gaincode = 0x00cc;
16433 u16 clip1loA_gaincode_rev4 = 0x0086;
16434 u16 clip1loA_gaincode_rev5 = 0x2086;
16435 u16 clip1loA_gaincode_rev6 = 0x2086;
16436 u16 clip1lo_gaincode;
16437 u8 crsminG_th = 0x18;
16438 u8 crsminG_th_rev5 = 0x18;
16439 u8 crsminG_th_rev6 = 0x18;
16440 u8 crsminA_th = 0x1e;
16441 u8 crsminA_th_rev4 = 0x24;
16442 u8 crsminA_th_rev5 = 0x24;
16443 u8 crsminA_th_rev6 = 0x24;
16444 u8 crsmin_th;
16445 u8 crsminlG_th = 0x18;
16446 u8 crsminlG_th_rev5 = 0x18;
16447 u8 crsminlG_th_rev6 = 0x18;
16448 u8 crsminlA_th = 0x1e;
16449 u8 crsminlA_th_rev4 = 0x24;
16450 u8 crsminlA_th_rev5 = 0x24;
16451 u8 crsminlA_th_rev6 = 0x24;
16452 u8 crsminl_th = 0;
16453 u8 crsminuG_th = 0x18;
16454 u8 crsminuG_th_rev5 = 0x18;
16455 u8 crsminuG_th_rev6 = 0x18;
16456 u8 crsminuA_th = 0x1e;
16457 u8 crsminuA_th_rev4 = 0x24;
16458 u8 crsminuA_th_rev5 = 0x24;
16459 u8 crsminuA_th_rev6 = 0x24;
16460 u8 crsminuA_th_rev6_224B0 = 0x2d;
16461 u8 crsminu_th;
16462 u16 nbclipG_th = 0x20d;
16463 u16 nbclipG_th_rev4 = 0x1a1;
16464 u16 nbclipG_th_rev5 = 0x1d0;
16465 u16 nbclipG_th_rev6 = 0x1d0;
16466 u16 nbclipA_th = 0x1a1;
16467 u16 nbclipA_th_rev4 = 0x107;
16468 u16 nbclipA_th_rev5 = 0x0a9;
16469 u16 nbclipA_th_rev6 = 0x0f0;
16470 u16 nbclip_th = 0;
16471 u8 w1clipG_th = 5;
16472 u8 w1clipG_th_rev5 = 9;
16473 u8 w1clipG_th_rev6 = 5;
16474 u8 w1clipA_th = 25, w1clip_th;
16475 u8 rssi_gain_default = 0x50;
16476 u8 rssiG_gain_rev6_224B0 = 0x50;
16477 u8 rssiA_gain_rev5 = 0x90;
16478 u8 rssiA_gain_rev6 = 0x90;
16479 u8 rssi_gain;
16480 u16 regval[21];
16481 u8 triso;
16482
16483 triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso :
16484 pi->srom_fem2g.triso;
16485
16486 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
16487 if (pi->pubpi.radiorev == 5) {
16488
16489 wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi);
16490 } else if (pi->pubpi.radiorev == 7) {
16491 wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
16492
16493 mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0));
16494 mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0));
16495
16496 } else if ((pi->pubpi.radiorev == 3)
16497 || (pi->pubpi.radiorev == 8)) {
16498 wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
16499
16500 if (pi->pubpi.radiorev == 8) {
16501 mod_phy_reg(pi, 0x283,
16502 (0xff << 0), (0x44 << 0));
16503 mod_phy_reg(pi, 0x280,
16504 (0xff << 0), (0x44 << 0));
16505 }
16506 } else {
16507 wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
16508 }
16509 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
16510
16511 mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6));
16512
16513 mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
16514 mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
16515
16516 currband =
16517 read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
16518 if (currband == 0) {
16519 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
16520 if (pi->pubpi.radiorev == 11) {
16521 lna1_gain_db = lna1G_gain_db_rev6_224B0;
16522 lna2_gain_db = lna2G_gain_db_rev6_224B0;
16523 rfseq_init_gain =
16524 rfseqG_init_gain_rev6_224B0;
16525 init_gaincode =
16526 initG_gaincode_rev6_224B0;
16527 clip1hi_gaincode =
16528 clip1hiG_gaincode_rev6;
16529 clip1lo_gaincode =
16530 clip1loG_gaincode_rev6_224B0;
16531 nbclip_th = nbclipG_th_rev6;
16532 w1clip_th = w1clipG_th_rev6;
16533 crsmin_th = crsminG_th_rev6;
16534 crsminl_th = crsminlG_th_rev6;
16535 crsminu_th = crsminuG_th_rev6;
16536 rssi_gain = rssiG_gain_rev6_224B0;
16537 } else {
16538 lna1_gain_db = lna1G_gain_db_rev6;
16539 lna2_gain_db = lna2G_gain_db_rev6;
16540 if (pi->sh->boardflags & BFL_EXTLNA) {
16541
16542 rfseq_init_gain =
16543 rfseqG_init_gain_rev6_elna;
16544 init_gaincode =
16545 initG_gaincode_rev6_elna;
16546 } else {
16547 rfseq_init_gain =
16548 rfseqG_init_gain_rev6;
16549 init_gaincode =
16550 initG_gaincode_rev6;
16551 }
16552 clip1hi_gaincode =
16553 clip1hiG_gaincode_rev6;
16554 switch (triso) {
16555 case 0:
16556 clip1lo_gaincode =
16557 clip1loG_gaincode_rev6[0];
16558 break;
16559 case 1:
16560 clip1lo_gaincode =
16561 clip1loG_gaincode_rev6[1];
16562 break;
16563 case 2:
16564 clip1lo_gaincode =
16565 clip1loG_gaincode_rev6[2];
16566 break;
16567 case 3:
16568 default:
16569
16570 clip1lo_gaincode =
16571 clip1loG_gaincode_rev6[3];
16572 break;
16573 case 4:
16574 clip1lo_gaincode =
16575 clip1loG_gaincode_rev6[4];
16576 break;
16577 case 5:
16578 clip1lo_gaincode =
16579 clip1loG_gaincode_rev6[5];
16580 break;
16581 case 6:
16582 clip1lo_gaincode =
16583 clip1loG_gaincode_rev6[6];
16584 break;
16585 case 7:
16586 clip1lo_gaincode =
16587 clip1loG_gaincode_rev6[7];
16588 break;
16589 }
16590 nbclip_th = nbclipG_th_rev6;
16591 w1clip_th = w1clipG_th_rev6;
16592 crsmin_th = crsminG_th_rev6;
16593 crsminl_th = crsminlG_th_rev6;
16594 crsminu_th = crsminuG_th_rev6;
16595 rssi_gain = rssi_gain_default;
16596 }
16597 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
16598 lna1_gain_db = lna1G_gain_db_rev5;
16599 lna2_gain_db = lna2G_gain_db_rev5;
16600 if (pi->sh->boardflags & BFL_EXTLNA) {
16601
16602 rfseq_init_gain =
16603 rfseqG_init_gain_rev5_elna;
16604 init_gaincode =
16605 initG_gaincode_rev5_elna;
16606 } else {
16607 rfseq_init_gain = rfseqG_init_gain_rev5;
16608 init_gaincode = initG_gaincode_rev5;
16609 }
16610 clip1hi_gaincode = clip1hiG_gaincode_rev5;
16611 switch (triso) {
16612 case 0:
16613 clip1lo_gaincode =
16614 clip1loG_gaincode_rev5[0];
16615 break;
16616 case 1:
16617 clip1lo_gaincode =
16618 clip1loG_gaincode_rev5[1];
16619 break;
16620 case 2:
16621 clip1lo_gaincode =
16622 clip1loG_gaincode_rev5[2];
16623 break;
16624 case 3:
16625
16626 clip1lo_gaincode =
16627 clip1loG_gaincode_rev5[3];
16628 break;
16629 case 4:
16630 clip1lo_gaincode =
16631 clip1loG_gaincode_rev5[4];
16632 break;
16633 case 5:
16634 clip1lo_gaincode =
16635 clip1loG_gaincode_rev5[5];
16636 break;
16637 case 6:
16638 clip1lo_gaincode =
16639 clip1loG_gaincode_rev5[6];
16640 break;
16641 case 7:
16642 clip1lo_gaincode =
16643 clip1loG_gaincode_rev5[7];
16644 break;
16645 default:
16646 clip1lo_gaincode =
16647 clip1loG_gaincode_rev5[3];
16648 break;
16649 }
16650 nbclip_th = nbclipG_th_rev5;
16651 w1clip_th = w1clipG_th_rev5;
16652 crsmin_th = crsminG_th_rev5;
16653 crsminl_th = crsminlG_th_rev5;
16654 crsminu_th = crsminuG_th_rev5;
16655 rssi_gain = rssi_gain_default;
16656 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
16657 lna1_gain_db = lna1G_gain_db_rev4;
16658 lna2_gain_db = lna2G_gain_db;
16659 rfseq_init_gain = rfseqG_init_gain_rev4;
16660 init_gaincode = initG_gaincode_rev4;
16661 clip1hi_gaincode = clip1hiG_gaincode_rev4;
16662 clip1lo_gaincode = clip1loG_gaincode;
16663 nbclip_th = nbclipG_th_rev4;
16664 w1clip_th = w1clipG_th;
16665 crsmin_th = crsminG_th;
16666 crsminl_th = crsminlG_th;
16667 crsminu_th = crsminuG_th;
16668 rssi_gain = rssi_gain_default;
16669 } else {
16670 lna1_gain_db = lna1G_gain_db;
16671 lna2_gain_db = lna2G_gain_db;
16672 rfseq_init_gain = rfseqG_init_gain;
16673 init_gaincode = initG_gaincode;
16674 clip1hi_gaincode = clip1hiG_gaincode;
16675 clip1lo_gaincode = clip1loG_gaincode;
16676 nbclip_th = nbclipG_th;
16677 w1clip_th = w1clipG_th;
16678 crsmin_th = crsminG_th;
16679 crsminl_th = crsminlG_th;
16680 crsminu_th = crsminuG_th;
16681 rssi_gain = rssi_gain_default;
16682 }
16683 tia_gain_db = tiaG_gain_db;
16684 tia_gainbits = tiaG_gainbits;
16685 clip1md_gaincode = clip1mdG_gaincode;
16686 } else {
16687 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
16688 lna1_gain_db = lna1A_gain_db_rev6;
16689 lna2_gain_db = lna2A_gain_db_rev6;
16690 tia_gain_db = tiaA_gain_db_rev6;
16691 tia_gainbits = tiaA_gainbits_rev6;
16692 rfseq_init_gain = rfseqA_init_gain_rev6;
16693 init_gaincode = initA_gaincode_rev6;
16694 clip1hi_gaincode = clip1hiA_gaincode_rev6;
16695 clip1md_gaincode = clip1mdA_gaincode_rev6;
16696 clip1lo_gaincode = clip1loA_gaincode_rev6;
16697 crsmin_th = crsminA_th_rev6;
16698 crsminl_th = crsminlA_th_rev6;
16699 if ((pi->pubpi.radiorev == 11) &&
16700 (CHSPEC_IS40(pi->radio_chanspec) == 0)) {
16701 crsminu_th = crsminuA_th_rev6_224B0;
16702 } else {
16703 crsminu_th = crsminuA_th_rev6;
16704 }
16705 nbclip_th = nbclipA_th_rev6;
16706 rssi_gain = rssiA_gain_rev6;
16707 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
16708 lna1_gain_db = lna1A_gain_db_rev5;
16709 lna2_gain_db = lna2A_gain_db_rev5;
16710 tia_gain_db = tiaA_gain_db_rev5;
16711 tia_gainbits = tiaA_gainbits_rev5;
16712 rfseq_init_gain = rfseqA_init_gain_rev5;
16713 init_gaincode = initA_gaincode_rev5;
16714 clip1hi_gaincode = clip1hiA_gaincode_rev5;
16715 clip1md_gaincode = clip1mdA_gaincode_rev5;
16716 clip1lo_gaincode = clip1loA_gaincode_rev5;
16717 crsmin_th = crsminA_th_rev5;
16718 crsminl_th = crsminlA_th_rev5;
16719 crsminu_th = crsminuA_th_rev5;
16720 nbclip_th = nbclipA_th_rev5;
16721 rssi_gain = rssiA_gain_rev5;
16722 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
16723 lna1_gain_db = lna1A_gain_db_rev4;
16724 lna2_gain_db = lna2A_gain_db_rev4;
16725 tia_gain_db = tiaA_gain_db_rev4;
16726 tia_gainbits = tiaA_gainbits_rev4;
16727 if (pi->sh->boardflags & BFL_EXTLNA_5GHz) {
16728
16729 rfseq_init_gain =
16730 rfseqA_init_gain_rev4_elna;
16731 init_gaincode =
16732 initA_gaincode_rev4_elna;
16733 } else {
16734 rfseq_init_gain = rfseqA_init_gain_rev4;
16735 init_gaincode = initA_gaincode_rev4;
16736 }
16737 clip1hi_gaincode = clip1hiA_gaincode_rev4;
16738 clip1md_gaincode = clip1mdA_gaincode_rev4;
16739 clip1lo_gaincode = clip1loA_gaincode_rev4;
16740 crsmin_th = crsminA_th_rev4;
16741 crsminl_th = crsminlA_th_rev4;
16742 crsminu_th = crsminuA_th_rev4;
16743 nbclip_th = nbclipA_th_rev4;
16744 rssi_gain = rssi_gain_default;
16745 } else {
16746 lna1_gain_db = lna1A_gain_db;
16747 lna2_gain_db = lna2A_gain_db;
16748 tia_gain_db = tiaA_gain_db;
16749 tia_gainbits = tiaA_gainbits;
16750 rfseq_init_gain = rfseqA_init_gain;
16751 init_gaincode = initA_gaincode;
16752 clip1hi_gaincode = clip1hiA_gaincode;
16753 clip1md_gaincode = clip1mdA_gaincode;
16754 clip1lo_gaincode = clip1loA_gaincode;
16755 crsmin_th = crsminA_th;
16756 crsminl_th = crsminlA_th;
16757 crsminu_th = crsminuA_th;
16758 nbclip_th = nbclipA_th;
16759 rssi_gain = rssi_gain_default;
16760 }
16761 w1clip_th = w1clipA_th;
16762 }
16763
16764 write_radio_reg(pi,
16765 (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
16766 RADIO_2056_RX0), 0x17);
16767 write_radio_reg(pi,
16768 (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
16769 RADIO_2056_RX1), 0x17);
16770
16771 write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0),
16772 0xf0);
16773 write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1),
16774 0xf0);
16775
16776 write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0),
16777 0x0);
16778 write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1),
16779 0x0);
16780
16781 write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0),
16782 rssi_gain);
16783 write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1),
16784 rssi_gain);
16785
16786 write_radio_reg(pi,
16787 (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
16788 RADIO_2056_RX0), 0x17);
16789 write_radio_reg(pi,
16790 (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
16791 RADIO_2056_RX1), 0x17);
16792
16793 write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0),
16794 0xFF);
16795 write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1),
16796 0xFF);
16797
16798 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8,
16799 8, lna1_gain_db);
16800 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8,
16801 8, lna1_gain_db);
16802
16803 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
16804 8, lna2_gain_db);
16805 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
16806 8, lna2_gain_db);
16807
16808 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20,
16809 8, tia_gain_db);
16810 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20,
16811 8, tia_gain_db);
16812
16813 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20,
16814 8, tia_gainbits);
16815 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20,
16816 8, tia_gainbits);
16817
16818 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40,
16819 8, &lpf_gain_db);
16820 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40,
16821 8, &lpf_gain_db);
16822 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40,
16823 8, &lpf_gainbits);
16824 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40,
16825 8, &lpf_gainbits);
16826
16827 write_phy_reg(pi, 0x20, init_gaincode);
16828 write_phy_reg(pi, 0x2a7, init_gaincode);
16829
16830 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
16831 pi->pubpi.phy_corenum, 0x106, 16,
16832 rfseq_init_gain);
16833
16834 write_phy_reg(pi, 0x22, clip1hi_gaincode);
16835 write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
16836
16837 write_phy_reg(pi, 0x24, clip1md_gaincode);
16838 write_phy_reg(pi, 0x2ab, clip1md_gaincode);
16839
16840 write_phy_reg(pi, 0x37, clip1lo_gaincode);
16841 write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
16842
16843 mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0));
16844 mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
16845 mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
16846
16847 write_phy_reg(pi, 0x2b, nbclip_th);
16848 write_phy_reg(pi, 0x41, nbclip_th);
16849
16850 mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0));
16851 mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0));
16852
16853 write_phy_reg(pi, 0x150, 0x809c);
16854
16855 } else {
16856
16857 mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
16858 mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
16859
16860 write_phy_reg(pi, 0x2b, 0x84);
16861 write_phy_reg(pi, 0x41, 0x84);
16862
16863 if (CHSPEC_IS20(pi->radio_chanspec)) {
16864 write_phy_reg(pi, 0x6b, 0x2b);
16865 write_phy_reg(pi, 0x6c, 0x2b);
16866 write_phy_reg(pi, 0x6d, 0x9);
16867 write_phy_reg(pi, 0x6e, 0x9);
16868 }
16869
16870 w1th = NPHY_RSSICAL_W1_TARGET - 4;
16871 mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0));
16872 mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0));
16873
16874 if (CHSPEC_IS20(pi->radio_chanspec)) {
16875 mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0));
16876 mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0));
16877
16878 mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0));
16879 mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0));
16880 }
16881
16882 write_phy_reg(pi, 0x150, 0x809c);
16883
16884 if (pi->nphy_gain_boost)
16885 if ((CHSPEC_IS2G(pi->radio_chanspec)) &&
16886 (CHSPEC_IS40(pi->radio_chanspec)))
16887 hpf_code = 4;
16888 else
16889 hpf_code = 5;
16890 else if (CHSPEC_IS40(pi->radio_chanspec))
16891 hpf_code = 6;
16892 else
16893 hpf_code = 7;
16894
16895 mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7));
16896 mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7));
16897
16898 for (ctr = 0; ctr < 4; ctr++) {
16899 regval[ctr] = (hpf_code << 8) | 0x7c;
16900 }
16901 wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
16902
16903 wlc_phy_adjust_lnagaintbl_nphy(pi);
16904
16905 if (pi->nphy_elna_gain_config) {
16906 regval[0] = 0;
16907 regval[1] = 1;
16908 regval[2] = 1;
16909 regval[3] = 1;
16910 wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval);
16911 wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval);
16912
16913 for (ctr = 0; ctr < 4; ctr++) {
16914 regval[ctr] = (hpf_code << 8) | 0x74;
16915 }
16916 wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
16917 }
16918
16919 if (NREV_IS(pi->pubpi.phy_rev, 2)) {
16920 for (ctr = 0; ctr < 21; ctr++) {
16921 regval[ctr] = 3 * ctr;
16922 }
16923 wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval);
16924 wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval);
16925
16926 for (ctr = 0; ctr < 21; ctr++) {
16927 regval[ctr] = (u16) ctr;
16928 }
16929 wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval);
16930 wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval);
16931 }
16932
16933 wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU,
16934 rfseq_updategainu_events,
16935 rfseq_updategainu_dlys,
16936 sizeof(rfseq_updategainu_events) /
16937 sizeof(rfseq_updategainu_events[0]));
16938
16939 mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8));
16940
16941 if (CHSPEC_IS2G(pi->radio_chanspec))
16942 mod_phy_reg(pi,
16943 (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES),
16944 0x7f, 0x4);
16945 }
16946}
16947
16948static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi)
16949{
16950 s8 lna1_gain_db[] = { 8, 13, 17, 22 };
16951 s8 lna2_gain_db[] = { -2, 7, 11, 15 };
16952 s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 };
16953 s8 tia_gainbits[] = {
16954 0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
16955
16956 mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
16957 mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
16958
16959 mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
16960
16961 mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0));
16962 mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0));
16963
16964 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8,
16965 lna1_gain_db);
16966 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8,
16967 lna1_gain_db);
16968
16969 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8,
16970 lna2_gain_db);
16971 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8,
16972 lna2_gain_db);
16973
16974 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
16975 tia_gain_db);
16976 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
16977 tia_gain_db);
16978
16979 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
16980 tia_gainbits);
16981 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
16982 tia_gainbits);
16983
16984 write_phy_reg(pi, 0x37, 0x74);
16985 write_phy_reg(pi, 0x2ad, 0x74);
16986 write_phy_reg(pi, 0x38, 0x18);
16987 write_phy_reg(pi, 0x2ae, 0x18);
16988
16989 write_phy_reg(pi, 0x2b, 0xe8);
16990 write_phy_reg(pi, 0x41, 0xe8);
16991
16992 if (CHSPEC_IS20(pi->radio_chanspec)) {
16993
16994 mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0));
16995 mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0));
16996 } else {
16997
16998 mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0));
16999 mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0));
17000 }
17001}
17002
17003static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
17004{
17005 u16 currband;
17006 s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
17007 s8 *lna1_gain_db = NULL;
17008 s8 *lna1_gain_db_2 = NULL;
17009 s8 *lna2_gain_db = NULL;
17010 s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
17011 s8 *tia_gain_db;
17012 s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
17013 s8 *tia_gainbits;
17014 u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
17015 u16 *rfseq_init_gain;
17016 u16 init_gaincode;
17017 u16 clip1hi_gaincode;
17018 u16 clip1md_gaincode = 0;
17019 u16 clip1md_gaincode_B;
17020 u16 clip1lo_gaincode;
17021 u16 clip1lo_gaincode_B;
17022 u8 crsminl_th = 0;
17023 u8 crsminu_th;
17024 u16 nbclip_th = 0;
17025 u8 w1clip_th;
17026 u16 freq;
17027 s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0;
17028 u8 chg_nbclip_th = 0;
17029
17030 mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
17031 mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
17032
17033 currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
17034 if (currband == 0) {
17035
17036 lna1_gain_db = lna1G_gain_db_rev7;
17037
17038 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
17039 lna1_gain_db);
17040 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
17041 lna1_gain_db);
17042
17043 mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0));
17044
17045 if (CHSPEC_IS40(pi->radio_chanspec)) {
17046 mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0));
17047 mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0));
17048 }
17049
17050 mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
17051
17052 if (CHSPEC_IS20(pi->radio_chanspec)) {
17053 mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0));
17054 mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0));
17055 }
17056 } else {
17057
17058 init_gaincode = 0x9e;
17059 clip1hi_gaincode = 0x9e;
17060 clip1md_gaincode_B = 0x24;
17061 clip1lo_gaincode = 0x8a;
17062 clip1lo_gaincode_B = 8;
17063 rfseq_init_gain = rfseqA_init_gain_rev7;
17064
17065 tia_gain_db = tiaA_gain_db_rev7;
17066 tia_gainbits = tiaA_gainbits_rev7;
17067
17068 freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
17069 if (CHSPEC_IS20(pi->radio_chanspec)) {
17070
17071 w1clip_th = 25;
17072 clip1md_gaincode = 0x82;
17073
17074 if ((freq <= 5080) || (freq == 5825)) {
17075
17076 s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
17077 s8 lna1A_gain_db_2_rev7[] = {
17078 11, 17, 22, 25 };
17079 s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
17080
17081 crsminu_th = 0x3e;
17082 lna1_gain_db = lna1A_gain_db_rev7;
17083 lna1_gain_db_2 = lna1A_gain_db_2_rev7;
17084 lna2_gain_db = lna2A_gain_db_rev7;
17085 } else if ((freq >= 5500) && (freq <= 5700)) {
17086
17087 s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
17088 s8 lna1A_gain_db_2_rev7[] = {
17089 12, 18, 22, 26 };
17090 s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
17091
17092 crsminu_th = 0x45;
17093 clip1md_gaincode_B = 0x14;
17094 nbclip_th = 0xff;
17095 chg_nbclip_th = 1;
17096 lna1_gain_db = lna1A_gain_db_rev7;
17097 lna1_gain_db_2 = lna1A_gain_db_2_rev7;
17098 lna2_gain_db = lna2A_gain_db_rev7;
17099 } else {
17100
17101 s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
17102 s8 lna1A_gain_db_2_rev7[] = {
17103 12, 18, 22, 26 };
17104 s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
17105
17106 crsminu_th = 0x41;
17107 lna1_gain_db = lna1A_gain_db_rev7;
17108 lna1_gain_db_2 = lna1A_gain_db_2_rev7;
17109 lna2_gain_db = lna2A_gain_db_rev7;
17110 }
17111
17112 if (freq <= 4920) {
17113 nvar_baseline_offset0 = 5;
17114 nvar_baseline_offset1 = 5;
17115 } else if ((freq > 4920) && (freq <= 5320)) {
17116 nvar_baseline_offset0 = 3;
17117 nvar_baseline_offset1 = 5;
17118 } else if ((freq > 5320) && (freq <= 5700)) {
17119 nvar_baseline_offset0 = 3;
17120 nvar_baseline_offset1 = 2;
17121 } else {
17122 nvar_baseline_offset0 = 4;
17123 nvar_baseline_offset1 = 0;
17124 }
17125 } else {
17126
17127 crsminu_th = 0x3a;
17128 crsminl_th = 0x3a;
17129 w1clip_th = 20;
17130
17131 if ((freq >= 4920) && (freq <= 5320)) {
17132 nvar_baseline_offset0 = 4;
17133 nvar_baseline_offset1 = 5;
17134 } else if ((freq > 5320) && (freq <= 5550)) {
17135 nvar_baseline_offset0 = 4;
17136 nvar_baseline_offset1 = 2;
17137 } else {
17138 nvar_baseline_offset0 = 5;
17139 nvar_baseline_offset1 = 3;
17140 }
17141 }
17142
17143 write_phy_reg(pi, 0x20, init_gaincode);
17144 write_phy_reg(pi, 0x2a7, init_gaincode);
17145
17146 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
17147 pi->pubpi.phy_corenum, 0x106, 16,
17148 rfseq_init_gain);
17149
17150 write_phy_reg(pi, 0x22, clip1hi_gaincode);
17151 write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
17152
17153 write_phy_reg(pi, 0x36, clip1md_gaincode_B);
17154 write_phy_reg(pi, 0x2ac, clip1md_gaincode_B);
17155
17156 write_phy_reg(pi, 0x37, clip1lo_gaincode);
17157 write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
17158 write_phy_reg(pi, 0x38, clip1lo_gaincode_B);
17159 write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B);
17160
17161 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
17162 tia_gain_db);
17163 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
17164 tia_gain_db);
17165
17166 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
17167 tia_gainbits);
17168 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
17169 tia_gainbits);
17170
17171 mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
17172
17173 if (chg_nbclip_th == 1) {
17174 write_phy_reg(pi, 0x2b, nbclip_th);
17175 write_phy_reg(pi, 0x41, nbclip_th);
17176 }
17177
17178 mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0));
17179 mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0));
17180
17181 mod_phy_reg(pi, 0x2e4,
17182 (0x3f << 0), (nvar_baseline_offset0 << 0));
17183
17184 mod_phy_reg(pi, 0x2e4,
17185 (0x3f << 6), (nvar_baseline_offset1 << 6));
17186
17187 if (CHSPEC_IS20(pi->radio_chanspec)) {
17188
17189 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
17190 lna1_gain_db);
17191 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
17192 lna1_gain_db_2);
17193
17194 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
17195 8, lna2_gain_db);
17196 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
17197 8, lna2_gain_db);
17198
17199 write_phy_reg(pi, 0x24, clip1md_gaincode);
17200 write_phy_reg(pi, 0x2ab, clip1md_gaincode);
17201 } else {
17202 mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
17203 }
17204
17205 }
17206
17207}
17208
17209static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi)
17210{
17211 uint core;
17212 int ctr;
17213 s16 gain_delta[2];
17214 u8 curr_channel;
17215 u16 minmax_gain[2];
17216 u16 regval[4];
17217
17218 if (pi->phyhang_avoid)
17219 wlc_phy_stay_in_carriersearch_nphy(pi, true);
17220
17221 if (pi->nphy_gain_boost) {
17222 if ((CHSPEC_IS2G(pi->radio_chanspec))) {
17223
17224 gain_delta[0] = 6;
17225 gain_delta[1] = 6;
17226 } else {
17227
17228 curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
17229 gain_delta[0] =
17230 (s16)
17231 PHY_HW_ROUND(((nphy_lnagain_est0[0] *
17232 curr_channel) +
17233 nphy_lnagain_est0[1]), 13);
17234 gain_delta[1] =
17235 (s16)
17236 PHY_HW_ROUND(((nphy_lnagain_est1[0] *
17237 curr_channel) +
17238 nphy_lnagain_est1[1]), 13);
17239 }
17240 } else {
17241
17242 gain_delta[0] = 0;
17243 gain_delta[1] = 0;
17244 }
17245
17246 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
17247 if (pi->nphy_elna_gain_config) {
17248
17249 regval[0] = nphy_def_lnagains[2] + gain_delta[core];
17250 regval[1] = nphy_def_lnagains[3] + gain_delta[core];
17251 regval[2] = nphy_def_lnagains[3] + gain_delta[core];
17252 regval[3] = nphy_def_lnagains[3] + gain_delta[core];
17253 } else {
17254 for (ctr = 0; ctr < 4; ctr++) {
17255 regval[ctr] =
17256 nphy_def_lnagains[ctr] + gain_delta[core];
17257 }
17258 }
17259 wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval);
17260
17261 minmax_gain[core] =
17262 (u16) (nphy_def_lnagains[2] + gain_delta[core] + 4);
17263 }
17264
17265 mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0));
17266 mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0));
17267
17268 if (pi->phyhang_avoid)
17269 wlc_phy_stay_in_carriersearch_nphy(pi, false);
17270}
17271
17272void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on)
17273{
17274 if (on) {
17275 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
17276 if (!pi->radio_is_on) {
17277 wlc_phy_radio_preinit_205x(pi);
17278 wlc_phy_radio_init_2057(pi);
17279 wlc_phy_radio_postinit_2057(pi);
17280 }
17281
17282 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
17283 pi->radio_chanspec);
17284 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
17285 wlc_phy_radio_preinit_205x(pi);
17286 wlc_phy_radio_init_2056(pi);
17287 wlc_phy_radio_postinit_2056(pi);
17288
17289 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
17290 pi->radio_chanspec);
17291 } else {
17292 wlc_phy_radio_preinit_2055(pi);
17293 wlc_phy_radio_init_2055(pi);
17294 wlc_phy_radio_postinit_2055(pi);
17295 }
17296
17297 pi->radio_is_on = true;
17298
17299 } else {
17300
17301 if (NREV_GE(pi->pubpi.phy_rev, 3)
17302 && NREV_LT(pi->pubpi.phy_rev, 7)) {
17303 and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
17304 mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0);
17305
17306 write_radio_reg(pi,
17307 RADIO_2056_TX_PADA_BOOST_TUNE |
17308 RADIO_2056_TX0, 0);
17309 write_radio_reg(pi,
17310 RADIO_2056_TX_PADG_BOOST_TUNE |
17311 RADIO_2056_TX0, 0);
17312 write_radio_reg(pi,
17313 RADIO_2056_TX_PGAA_BOOST_TUNE |
17314 RADIO_2056_TX0, 0);
17315 write_radio_reg(pi,
17316 RADIO_2056_TX_PGAG_BOOST_TUNE |
17317 RADIO_2056_TX0, 0);
17318 mod_radio_reg(pi,
17319 RADIO_2056_TX_MIXA_BOOST_TUNE |
17320 RADIO_2056_TX0, 0xf0, 0);
17321 write_radio_reg(pi,
17322 RADIO_2056_TX_MIXG_BOOST_TUNE |
17323 RADIO_2056_TX0, 0);
17324
17325 write_radio_reg(pi,
17326 RADIO_2056_TX_PADA_BOOST_TUNE |
17327 RADIO_2056_TX1, 0);
17328 write_radio_reg(pi,
17329 RADIO_2056_TX_PADG_BOOST_TUNE |
17330 RADIO_2056_TX1, 0);
17331 write_radio_reg(pi,
17332 RADIO_2056_TX_PGAA_BOOST_TUNE |
17333 RADIO_2056_TX1, 0);
17334 write_radio_reg(pi,
17335 RADIO_2056_TX_PGAG_BOOST_TUNE |
17336 RADIO_2056_TX1, 0);
17337 mod_radio_reg(pi,
17338 RADIO_2056_TX_MIXA_BOOST_TUNE |
17339 RADIO_2056_TX1, 0xf0, 0);
17340 write_radio_reg(pi,
17341 RADIO_2056_TX_MIXG_BOOST_TUNE |
17342 RADIO_2056_TX1, 0);
17343
17344 pi->radio_is_on = false;
17345 }
17346
17347 if (NREV_GE(pi->pubpi.phy_rev, 8)) {
17348 and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
17349 pi->radio_is_on = false;
17350 }
17351
17352 }
17353}
17354
17355static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi)
17356{
17357
17358 and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE);
17359 or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE);
17360
17361 or_phy_reg(pi, 0x78, RFCC_POR_FORCE);
17362}
17363
17364static void wlc_phy_radio_init_2055(struct brcms_phy *pi)
17365{
17366 wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE);
17367}
17368
17369static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi)
17370{
17371
17372 and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1,
17373 ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK));
17374
17375 if (((pi->sh->sromrev >= 4)
17376 && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS))
17377 || ((pi->sh->sromrev < 4))) {
17378 and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F);
17379 and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F);
17380 }
17381
17382 mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C);
17383 write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C);
17384
17385 and_radio_reg(pi, RADIO_2055_CAL_MISC,
17386 ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N));
17387
17388 or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE);
17389
17390 or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N);
17391
17392 udelay(1000);
17393
17394 or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START);
17395
17396 SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
17397 RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
17398
17399 if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
17400 RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE,
17401 "HW error: radio calibration1\n"))
17402 return;
17403
17404 and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
17405 ~(RADIO_2055_CAL_LPO_ENABLE));
17406
17407 wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
17408
17409 write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9);
17410 write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9);
17411
17412 write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83);
17413 write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83);
17414
17415 mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST,
17416 RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
17417 mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST,
17418 RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
17419 if (pi->nphy_gain_boost) {
17420 and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
17421 ~(RADIO_2055_GAINBST_DISABLE));
17422 and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
17423 ~(RADIO_2055_GAINBST_DISABLE));
17424 } else {
17425 or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
17426 RADIO_2055_GAINBST_DISABLE);
17427 or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
17428 RADIO_2055_GAINBST_DISABLE);
17429 }
17430
17431 udelay(2);
17432}
17433
17434static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi)
17435{
17436
17437 and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
17438 and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE);
17439
17440 or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE);
17441 or_phy_reg(pi, 0x78, RFCC_CHIP0_PU);
17442
17443}
17444
17445static void wlc_phy_radio_init_2056(struct brcms_phy *pi)
17446{
17447 struct radio_regs *regs_SYN_2056_ptr = NULL;
17448 struct radio_regs *regs_TX_2056_ptr = NULL;
17449 struct radio_regs *regs_RX_2056_ptr = NULL;
17450
17451 if (NREV_IS(pi->pubpi.phy_rev, 3)) {
17452 regs_SYN_2056_ptr = regs_SYN_2056;
17453 regs_TX_2056_ptr = regs_TX_2056;
17454 regs_RX_2056_ptr = regs_RX_2056;
17455 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
17456 regs_SYN_2056_ptr = regs_SYN_2056_A1;
17457 regs_TX_2056_ptr = regs_TX_2056_A1;
17458 regs_RX_2056_ptr = regs_RX_2056_A1;
17459 } else {
17460 switch (pi->pubpi.radiorev) {
17461 case 5:
17462 regs_SYN_2056_ptr = regs_SYN_2056_rev5;
17463 regs_TX_2056_ptr = regs_TX_2056_rev5;
17464 regs_RX_2056_ptr = regs_RX_2056_rev5;
17465 break;
17466
17467 case 6:
17468 regs_SYN_2056_ptr = regs_SYN_2056_rev6;
17469 regs_TX_2056_ptr = regs_TX_2056_rev6;
17470 regs_RX_2056_ptr = regs_RX_2056_rev6;
17471 break;
17472
17473 case 7:
17474 case 9:
17475 regs_SYN_2056_ptr = regs_SYN_2056_rev7;
17476 regs_TX_2056_ptr = regs_TX_2056_rev7;
17477 regs_RX_2056_ptr = regs_RX_2056_rev7;
17478 break;
17479
17480 case 8:
17481 regs_SYN_2056_ptr = regs_SYN_2056_rev8;
17482 regs_TX_2056_ptr = regs_TX_2056_rev8;
17483 regs_RX_2056_ptr = regs_RX_2056_rev8;
17484 break;
17485
17486 case 11:
17487 regs_SYN_2056_ptr = regs_SYN_2056_rev11;
17488 regs_TX_2056_ptr = regs_TX_2056_rev11;
17489 regs_RX_2056_ptr = regs_RX_2056_rev11;
17490 break;
17491
17492 default:
17493 break;
17494 }
17495 }
17496
17497 wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN);
17498
17499 wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0);
17500
17501 wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1);
17502
17503 wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0);
17504
17505 wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1);
17506}
17507
17508static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi)
17509{
17510 mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb);
17511
17512 mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2);
17513 mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2);
17514 udelay(1000);
17515 mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0);
17516
17517 if ((pi->sh->boardflags2 & BFL2_LEGACY)
17518 || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN)) {
17519
17520 mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0);
17521 } else {
17522
17523 mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0);
17524 }
17525
17526 mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0);
17527
17528 if (pi->phy_init_por) {
17529 wlc_phy_radio205x_rcal(pi);
17530 }
17531}
17532
17533static void wlc_phy_radio_init_2057(struct brcms_phy *pi)
17534{
17535 struct radio_20xx_regs *regs_2057_ptr = NULL;
17536
17537 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
17538
17539 regs_2057_ptr = regs_2057_rev4;
17540 } else if (NREV_IS(pi->pubpi.phy_rev, 8)
17541 || NREV_IS(pi->pubpi.phy_rev, 9)) {
17542 switch (pi->pubpi.radiorev) {
17543 case 5:
17544
17545 if (pi->pubpi.radiover == 0x0) {
17546
17547 regs_2057_ptr = regs_2057_rev5;
17548
17549 } else if (pi->pubpi.radiover == 0x1) {
17550
17551 regs_2057_ptr = regs_2057_rev5v1;
17552 } else {
17553 break;
17554 }
17555
17556 case 7:
17557
17558 regs_2057_ptr = regs_2057_rev7;
17559 break;
17560
17561 case 8:
17562
17563 regs_2057_ptr = regs_2057_rev8;
17564 break;
17565
17566 default:
17567 break;
17568 }
17569 }
17570
17571 wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
17572}
17573
17574static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi)
17575{
17576
17577 mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1);
17578
17579 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78);
17580 mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80);
17581 mdelay(2);
17582 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0);
17583 mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0);
17584
17585 if (pi->phy_init_por) {
17586 wlc_phy_radio205x_rcal(pi);
17587 wlc_phy_radio2057_rccal(pi);
17588 }
17589
17590 mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0);
17591}
17592
17593static bool
17594wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f,
17595 struct chan_info_nphy_radio2057 **t0,
17596 struct chan_info_nphy_radio205x **t1,
17597 struct chan_info_nphy_radio2057_rev5 **t2,
17598 struct chan_info_nphy_2055 **t3)
17599{
17600 uint i;
17601 struct chan_info_nphy_radio2057 *chan_info_tbl_p_0 = NULL;
17602 struct chan_info_nphy_radio205x *chan_info_tbl_p_1 = NULL;
17603 struct chan_info_nphy_radio2057_rev5 *chan_info_tbl_p_2 = NULL;
17604 u32 tbl_len = 0;
17605
17606 int freq = 0;
17607
17608 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
17609
17610 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
17611
17612 chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4;
17613 tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4);
17614
17615 } else if (NREV_IS(pi->pubpi.phy_rev, 8)
17616 || NREV_IS(pi->pubpi.phy_rev, 9)) {
17617 switch (pi->pubpi.radiorev) {
17618
17619 case 5:
17620
17621 if (pi->pubpi.radiover == 0x0) {
17622
17623 chan_info_tbl_p_2 =
17624 chan_info_nphyrev8_2057_rev5;
17625 tbl_len =
17626 ARRAY_SIZE
17627 (chan_info_nphyrev8_2057_rev5);
17628
17629 } else if (pi->pubpi.radiover == 0x1) {
17630
17631 chan_info_tbl_p_2 =
17632 chan_info_nphyrev9_2057_rev5v1;
17633 tbl_len =
17634 ARRAY_SIZE
17635 (chan_info_nphyrev9_2057_rev5v1);
17636
17637 }
17638 break;
17639
17640 case 7:
17641 chan_info_tbl_p_0 =
17642 chan_info_nphyrev8_2057_rev7;
17643 tbl_len =
17644 ARRAY_SIZE(chan_info_nphyrev8_2057_rev7);
17645 break;
17646
17647 case 8:
17648 chan_info_tbl_p_0 =
17649 chan_info_nphyrev8_2057_rev8;
17650 tbl_len =
17651 ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
17652 break;
17653
17654 default:
17655 if (NORADIO_ENAB(pi->pubpi)) {
17656 goto fail;
17657 }
17658 break;
17659 }
17660 } else if (NREV_IS(pi->pubpi.phy_rev, 16)) {
17661
17662 chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8;
17663 tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
17664 } else {
17665 goto fail;
17666 }
17667
17668 for (i = 0; i < tbl_len; i++) {
17669 if (pi->pubpi.radiorev == 5) {
17670
17671 if (chan_info_tbl_p_2[i].chan == channel)
17672 break;
17673 } else {
17674
17675 if (chan_info_tbl_p_0[i].chan == channel)
17676 break;
17677 }
17678 }
17679
17680 if (i >= tbl_len) {
17681 goto fail;
17682 }
17683 if (pi->pubpi.radiorev == 5) {
17684 *t2 = &chan_info_tbl_p_2[i];
17685 freq = chan_info_tbl_p_2[i].freq;
17686 } else {
17687 *t0 = &chan_info_tbl_p_0[i];
17688 freq = chan_info_tbl_p_0[i].freq;
17689 }
17690
17691 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
17692 if (NREV_IS(pi->pubpi.phy_rev, 3)) {
17693 chan_info_tbl_p_1 = chan_info_nphyrev3_2056;
17694 tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056);
17695 } else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
17696 chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1;
17697 tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1);
17698 } else if (NREV_IS(pi->pubpi.phy_rev, 5)
17699 || NREV_IS(pi->pubpi.phy_rev, 6)) {
17700 switch (pi->pubpi.radiorev) {
17701 case 5:
17702 chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5;
17703 tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5);
17704 break;
17705 case 6:
17706 chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6;
17707 tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6);
17708 break;
17709 case 7:
17710 case 9:
17711 chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7;
17712 tbl_len =
17713 ARRAY_SIZE(chan_info_nphyrev5n6_2056v7);
17714 break;
17715 case 8:
17716 chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8;
17717 tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8);
17718 break;
17719 case 11:
17720 chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11;
17721 tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v11);
17722 break;
17723 default:
17724 if (NORADIO_ENAB(pi->pubpi)) {
17725 goto fail;
17726 }
17727 break;
17728 }
17729 }
17730
17731 for (i = 0; i < tbl_len; i++) {
17732 if (chan_info_tbl_p_1[i].chan == channel)
17733 break;
17734 }
17735
17736 if (i >= tbl_len) {
17737 goto fail;
17738 }
17739 *t1 = &chan_info_tbl_p_1[i];
17740 freq = chan_info_tbl_p_1[i].freq;
17741
17742 } else {
17743 for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++)
17744 if (chan_info_nphy_2055[i].chan == channel)
17745 break;
17746
17747 if (i >= ARRAY_SIZE(chan_info_nphy_2055)) {
17748 goto fail;
17749 }
17750 *t3 = &chan_info_nphy_2055[i];
17751 freq = chan_info_nphy_2055[i].freq;
17752 }
17753
17754 *f = freq;
17755 return true;
17756
17757 fail:
17758 *f = WL_CHAN_FREQ_RANGE_2G;
17759 return false;
17760}
17761
17762u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint channel)
17763{
17764 int freq;
17765 struct chan_info_nphy_radio2057 *t0 = NULL;
17766 struct chan_info_nphy_radio205x *t1 = NULL;
17767 struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
17768 struct chan_info_nphy_2055 *t3 = NULL;
17769
17770 if (NORADIO_ENAB(pi->pubpi))
17771 return WL_CHAN_FREQ_RANGE_2G;
17772
17773 if (channel == 0)
17774 channel = CHSPEC_CHANNEL(pi->radio_chanspec);
17775
17776 wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3);
17777
17778 if (CHSPEC_IS2G(pi->radio_chanspec))
17779 return WL_CHAN_FREQ_RANGE_2G;
17780
17781 if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN)) {
17782 return WL_CHAN_FREQ_RANGE_5GL;
17783 } else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN)) {
17784 return WL_CHAN_FREQ_RANGE_5GM;
17785 } else {
17786 return WL_CHAN_FREQ_RANGE_5GH;
17787 }
17788}
17789
17790static void
17791wlc_phy_chanspec_radio2055_setup(struct brcms_phy *pi,
17792 struct chan_info_nphy_2055 *ci)
17793{
17794
17795 write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref);
17796 write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0);
17797 write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1);
17798 write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail);
17799
17800 BRCMS_PHY_WAR_PR51571(pi);
17801
17802 write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1);
17803 write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2);
17804 write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1);
17805 write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1);
17806
17807 BRCMS_PHY_WAR_PR51571(pi);
17808
17809 write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2);
17810 write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf);
17811 write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1);
17812 write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2);
17813
17814 BRCMS_PHY_WAR_PR51571(pi);
17815
17816 write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE,
17817 ci->RF_core1_lgbuf_a_tune);
17818 write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE,
17819 ci->RF_core1_lgbuf_g_tune);
17820 write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1);
17821 write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN,
17822 ci->RF_core1_tx_pga_pad_tn);
17823
17824 BRCMS_PHY_WAR_PR51571(pi);
17825
17826 write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM,
17827 ci->RF_core1_tx_mx_bgtrim);
17828 write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE,
17829 ci->RF_core2_lgbuf_a_tune);
17830 write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE,
17831 ci->RF_core2_lgbuf_g_tune);
17832 write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1);
17833
17834 BRCMS_PHY_WAR_PR51571(pi);
17835
17836 write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN,
17837 ci->RF_core2_tx_pga_pad_tn);
17838 write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM,
17839 ci->RF_core2_tx_mx_bgtrim);
17840
17841 udelay(50);
17842
17843 write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05);
17844 write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45);
17845
17846 BRCMS_PHY_WAR_PR51571(pi);
17847
17848 write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65);
17849
17850 udelay(300);
17851}
17852
17853static void
17854wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi,
17855 const struct chan_info_nphy_radio205x *ci)
17856{
17857 struct radio_regs *regs_SYN_2056_ptr = NULL;
17858
17859 write_radio_reg(pi,
17860 RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN,
17861 ci->RF_SYN_pll_vcocal1);
17862 write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN,
17863 ci->RF_SYN_pll_vcocal2);
17864 write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN,
17865 ci->RF_SYN_pll_refdiv);
17866 write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN,
17867 ci->RF_SYN_pll_mmd2);
17868 write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN,
17869 ci->RF_SYN_pll_mmd1);
17870 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
17871 ci->RF_SYN_pll_loopfilter1);
17872 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
17873 ci->RF_SYN_pll_loopfilter2);
17874 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN,
17875 ci->RF_SYN_pll_loopfilter3);
17876 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
17877 ci->RF_SYN_pll_loopfilter4);
17878 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN,
17879 ci->RF_SYN_pll_loopfilter5);
17880 write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN,
17881 ci->RF_SYN_reserved_addr27);
17882 write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN,
17883 ci->RF_SYN_reserved_addr28);
17884 write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN,
17885 ci->RF_SYN_reserved_addr29);
17886 write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN,
17887 ci->RF_SYN_logen_VCOBUF1);
17888 write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN,
17889 ci->RF_SYN_logen_MIXER2);
17890 write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN,
17891 ci->RF_SYN_logen_BUF3);
17892 write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN,
17893 ci->RF_SYN_logen_BUF4);
17894
17895 write_radio_reg(pi,
17896 RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0,
17897 ci->RF_RX0_lnaa_tune);
17898 write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0,
17899 ci->RF_RX0_lnag_tune);
17900 write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0,
17901 ci->RF_TX0_intpaa_boost_tune);
17902 write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0,
17903 ci->RF_TX0_intpag_boost_tune);
17904 write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0,
17905 ci->RF_TX0_pada_boost_tune);
17906 write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0,
17907 ci->RF_TX0_padg_boost_tune);
17908 write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0,
17909 ci->RF_TX0_pgaa_boost_tune);
17910 write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0,
17911 ci->RF_TX0_pgag_boost_tune);
17912 write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0,
17913 ci->RF_TX0_mixa_boost_tune);
17914 write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0,
17915 ci->RF_TX0_mixg_boost_tune);
17916
17917 write_radio_reg(pi,
17918 RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1,
17919 ci->RF_RX1_lnaa_tune);
17920 write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1,
17921 ci->RF_RX1_lnag_tune);
17922 write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1,
17923 ci->RF_TX1_intpaa_boost_tune);
17924 write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1,
17925 ci->RF_TX1_intpag_boost_tune);
17926 write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1,
17927 ci->RF_TX1_pada_boost_tune);
17928 write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1,
17929 ci->RF_TX1_padg_boost_tune);
17930 write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1,
17931 ci->RF_TX1_pgaa_boost_tune);
17932 write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1,
17933 ci->RF_TX1_pgag_boost_tune);
17934 write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1,
17935 ci->RF_TX1_mixa_boost_tune);
17936 write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1,
17937 ci->RF_TX1_mixg_boost_tune);
17938
17939 if (NREV_IS(pi->pubpi.phy_rev, 3))
17940 regs_SYN_2056_ptr = regs_SYN_2056;
17941 else if (NREV_IS(pi->pubpi.phy_rev, 4))
17942 regs_SYN_2056_ptr = regs_SYN_2056_A1;
17943 else {
17944 switch (pi->pubpi.radiorev) {
17945 case 5:
17946 regs_SYN_2056_ptr = regs_SYN_2056_rev5;
17947 break;
17948 case 6:
17949 regs_SYN_2056_ptr = regs_SYN_2056_rev6;
17950 break;
17951 case 7:
17952 case 9:
17953 regs_SYN_2056_ptr = regs_SYN_2056_rev7;
17954 break;
17955 case 8:
17956 regs_SYN_2056_ptr = regs_SYN_2056_rev8;
17957 break;
17958 case 11:
17959 regs_SYN_2056_ptr = regs_SYN_2056_rev11;
17960 break;
17961 }
17962 }
17963 if (CHSPEC_IS2G(pi->radio_chanspec)) {
17964 write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
17965 RADIO_2056_SYN,
17966 (u16) regs_SYN_2056_ptr[0x49 - 2].init_g);
17967 } else {
17968 write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
17969 RADIO_2056_SYN,
17970 (u16) regs_SYN_2056_ptr[0x49 - 2].init_a);
17971 }
17972
17973 if (pi->sh->boardflags2 & BFL2_GPLL_WAR) {
17974 if (CHSPEC_IS2G(pi->radio_chanspec)) {
17975 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
17976 RADIO_2056_SYN, 0x1f);
17977 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
17978 RADIO_2056_SYN, 0x1f);
17979
17980 write_radio_reg(pi,
17981 RADIO_2056_SYN_PLL_LOOPFILTER4 |
17982 RADIO_2056_SYN, 0xb);
17983 write_radio_reg(pi,
17984 RADIO_2056_SYN_PLL_CP2 |
17985 RADIO_2056_SYN, 0x14);
17986 }
17987 }
17988
17989 if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) &&
17990 (CHSPEC_IS2G(pi->radio_chanspec))) {
17991 write_radio_reg(pi,
17992 RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
17993 0x1f);
17994 write_radio_reg(pi,
17995 RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
17996 0x1f);
17997 write_radio_reg(pi,
17998 RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
17999 0xb);
18000 write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN,
18001 0x20);
18002 }
18003
18004 if (pi->sh->boardflags2 & BFL2_APLL_WAR) {
18005 if (CHSPEC_IS5G(pi->radio_chanspec)) {
18006 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
18007 RADIO_2056_SYN, 0x1f);
18008 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
18009 RADIO_2056_SYN, 0x1f);
18010 write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 |
18011 RADIO_2056_SYN, 0x5);
18012 write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
18013 RADIO_2056_SYN, 0xc);
18014 }
18015 }
18016
18017 if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) {
18018 u16 pag_boost_tune;
18019 u16 padg_boost_tune;
18020 u16 pgag_boost_tune;
18021 u16 mixg_boost_tune;
18022 u16 bias, cascbias;
18023 uint core;
18024
18025 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
18026
18027 if (NREV_GE(pi->pubpi.phy_rev, 5)) {
18028
18029 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18030 PADG_IDAC, 0xcc);
18031
18032 bias = 0x25;
18033 cascbias = 0x20;
18034
18035 if ((pi->sh->chip ==
18036 BCM43224_CHIP_ID)
18037 || (pi->sh->chip ==
18038 BCM43225_CHIP_ID)) {
18039 if (pi->sh->chippkg ==
18040 BCM43224_FAB_SMIC) {
18041 bias = 0x2a;
18042 cascbias = 0x38;
18043 }
18044 }
18045
18046 pag_boost_tune = 0x4;
18047 pgag_boost_tune = 0x03;
18048 padg_boost_tune = 0x77;
18049 mixg_boost_tune = 0x65;
18050
18051 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18052 INTPAG_IMAIN_STAT, bias);
18053 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18054 INTPAG_IAUX_STAT, bias);
18055 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18056 INTPAG_CASCBIAS, cascbias);
18057
18058 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18059 INTPAG_BOOST_TUNE,
18060 pag_boost_tune);
18061 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18062 PGAG_BOOST_TUNE,
18063 pgag_boost_tune);
18064 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18065 PADG_BOOST_TUNE,
18066 padg_boost_tune);
18067 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18068 MIXG_BOOST_TUNE,
18069 mixg_boost_tune);
18070 } else {
18071
18072 bias = IS40MHZ(pi) ? 0x40 : 0x20;
18073
18074 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18075 INTPAG_IMAIN_STAT, bias);
18076 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18077 INTPAG_IAUX_STAT, bias);
18078 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18079 INTPAG_CASCBIAS, 0x30);
18080 }
18081 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1,
18082 0xee);
18083 }
18084 }
18085
18086 if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6)
18087 && CHSPEC_IS5G(pi->radio_chanspec)) {
18088 u16 paa_boost_tune;
18089 u16 pada_boost_tune;
18090 u16 pgaa_boost_tune;
18091 u16 mixa_boost_tune;
18092 u16 freq, pabias, cascbias;
18093 uint core;
18094
18095 freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
18096
18097 if (freq < 5150) {
18098
18099 paa_boost_tune = 0xa;
18100 pada_boost_tune = 0x77;
18101 pgaa_boost_tune = 0xf;
18102 mixa_boost_tune = 0xf;
18103 } else if (freq < 5340) {
18104
18105 paa_boost_tune = 0x8;
18106 pada_boost_tune = 0x77;
18107 pgaa_boost_tune = 0xfb;
18108 mixa_boost_tune = 0xf;
18109 } else if (freq < 5650) {
18110
18111 paa_boost_tune = 0x0;
18112 pada_boost_tune = 0x77;
18113 pgaa_boost_tune = 0xb;
18114 mixa_boost_tune = 0xf;
18115 } else {
18116
18117 paa_boost_tune = 0x0;
18118 pada_boost_tune = 0x77;
18119 if (freq != 5825) {
18120 pgaa_boost_tune = -(int)(freq - 18) / 36 + 168;
18121 } else {
18122 pgaa_boost_tune = 6;
18123 }
18124 mixa_boost_tune = 0xf;
18125 }
18126
18127 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
18128 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18129 INTPAA_BOOST_TUNE, paa_boost_tune);
18130 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18131 PADA_BOOST_TUNE, pada_boost_tune);
18132 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18133 PGAA_BOOST_TUNE, pgaa_boost_tune);
18134 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18135 MIXA_BOOST_TUNE, mixa_boost_tune);
18136
18137 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18138 TXSPARE1, 0x30);
18139 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18140 PA_SPARE2, 0xee);
18141
18142 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18143 PADA_CASCBIAS, 0x3);
18144
18145 cascbias = 0x30;
18146
18147 if ((pi->sh->chip == BCM43224_CHIP_ID) ||
18148 (pi->sh->chip == BCM43225_CHIP_ID)) {
18149 if (pi->sh->chippkg == BCM43224_FAB_SMIC) {
18150 cascbias = 0x35;
18151 }
18152 }
18153
18154 pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias;
18155
18156 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18157 INTPAA_IAUX_STAT, pabias);
18158 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18159 INTPAA_IMAIN_STAT, pabias);
18160 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
18161 INTPAA_CASCBIAS, cascbias);
18162 }
18163 }
18164
18165 udelay(50);
18166
18167 wlc_phy_radio205x_vcocal_nphy(pi);
18168}
18169
18170void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi)
18171{
18172 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18173 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0);
18174 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0);
18175 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04,
18176 (1 << 2));
18177 mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01);
18178 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18179 write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0);
18180 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
18181 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18);
18182 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
18183 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39);
18184 }
18185
18186 udelay(300);
18187}
18188
18189#define MAX_205x_RCAL_WAITLOOPS 10000
18190
18191static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi)
18192{
18193 u16 rcal_reg = 0;
18194 int i;
18195
18196 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18197
18198 if (pi->pubpi.radiorev == 5) {
18199
18200 and_phy_reg(pi, 0x342, ~(0x1 << 1));
18201
18202 udelay(10);
18203
18204 mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1);
18205 mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
18206 0x1);
18207 }
18208 mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1);
18209
18210 udelay(10);
18211
18212 mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3);
18213
18214 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
18215 rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS);
18216 if (rcal_reg & 0x1) {
18217 break;
18218 }
18219 udelay(100);
18220 }
18221
18222 if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
18223 "HW error: radio calib2"))
18224 return 0;
18225
18226 mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
18227
18228 rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e;
18229
18230 mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0);
18231 if (pi->pubpi.radiorev == 5) {
18232
18233 mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0);
18234 mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
18235 0x0);
18236 }
18237
18238 if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
18239
18240 mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c,
18241 rcal_reg);
18242 mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0,
18243 rcal_reg << 2);
18244 }
18245
18246 } else if (NREV_IS(pi->pubpi.phy_rev, 3)) {
18247 u16 savereg;
18248
18249 savereg =
18250 read_radio_reg(pi,
18251 RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN);
18252 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
18253 savereg | 0x7);
18254 udelay(10);
18255
18256 write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
18257 0x1);
18258 udelay(10);
18259
18260 write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
18261 0x9);
18262
18263 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
18264 rcal_reg = read_radio_reg(pi,
18265 RADIO_2056_SYN_RCAL_CODE_OUT |
18266 RADIO_2056_SYN);
18267 if (rcal_reg & 0x80) {
18268 break;
18269 }
18270 udelay(100);
18271 }
18272
18273 if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
18274 "HW error: radio calib3"))
18275 return 0;
18276
18277 write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
18278 0x1);
18279
18280 rcal_reg =
18281 read_radio_reg(pi,
18282 RADIO_2056_SYN_RCAL_CODE_OUT |
18283 RADIO_2056_SYN);
18284
18285 write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
18286 0x0);
18287
18288 write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
18289 savereg);
18290
18291 return rcal_reg & 0x1f;
18292 }
18293 return rcal_reg & 0x3e;
18294}
18295
18296static void
18297wlc_phy_chanspec_radio2057_setup(struct brcms_phy *pi,
18298 const struct chan_info_nphy_radio2057 *ci,
18299 const struct chan_info_nphy_radio2057_rev5 *ci2)
18300{
18301 int coreNum;
18302 u16 txmix2g_tune_boost_pu = 0;
18303 u16 pad2g_tune_pus = 0;
18304
18305 if (pi->pubpi.radiorev == 5) {
18306
18307 write_radio_reg(pi,
18308 RADIO_2057_VCOCAL_COUNTVAL0,
18309 ci2->RF_vcocal_countval0);
18310 write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
18311 ci2->RF_vcocal_countval1);
18312 write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
18313 ci2->RF_rfpll_refmaster_sparextalsize);
18314 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
18315 ci2->RF_rfpll_loopfilter_r1);
18316 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
18317 ci2->RF_rfpll_loopfilter_c2);
18318 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
18319 ci2->RF_rfpll_loopfilter_c1);
18320 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC,
18321 ci2->RF_cp_kpd_idac);
18322 write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0);
18323 write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1);
18324 write_radio_reg(pi,
18325 RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune);
18326 write_radio_reg(pi,
18327 RADIO_2057_LOGEN_MX2G_TUNE,
18328 ci2->RF_logen_mx2g_tune);
18329 write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
18330 ci2->RF_logen_indbuf2g_tune);
18331
18332 write_radio_reg(pi,
18333 RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
18334 ci2->RF_txmix2g_tune_boost_pu_core0);
18335 write_radio_reg(pi,
18336 RADIO_2057_PAD2G_TUNE_PUS_CORE0,
18337 ci2->RF_pad2g_tune_pus_core0);
18338 write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
18339 ci2->RF_lna2g_tune_core0);
18340
18341 write_radio_reg(pi,
18342 RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
18343 ci2->RF_txmix2g_tune_boost_pu_core1);
18344 write_radio_reg(pi,
18345 RADIO_2057_PAD2G_TUNE_PUS_CORE1,
18346 ci2->RF_pad2g_tune_pus_core1);
18347 write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
18348 ci2->RF_lna2g_tune_core1);
18349
18350 } else {
18351
18352 write_radio_reg(pi,
18353 RADIO_2057_VCOCAL_COUNTVAL0,
18354 ci->RF_vcocal_countval0);
18355 write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
18356 ci->RF_vcocal_countval1);
18357 write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
18358 ci->RF_rfpll_refmaster_sparextalsize);
18359 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
18360 ci->RF_rfpll_loopfilter_r1);
18361 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
18362 ci->RF_rfpll_loopfilter_c2);
18363 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
18364 ci->RF_rfpll_loopfilter_c1);
18365 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac);
18366 write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0);
18367 write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1);
18368 write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune);
18369 write_radio_reg(pi,
18370 RADIO_2057_LOGEN_MX2G_TUNE,
18371 ci->RF_logen_mx2g_tune);
18372 write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE,
18373 ci->RF_logen_mx5g_tune);
18374 write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
18375 ci->RF_logen_indbuf2g_tune);
18376 write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE,
18377 ci->RF_logen_indbuf5g_tune);
18378
18379 write_radio_reg(pi,
18380 RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
18381 ci->RF_txmix2g_tune_boost_pu_core0);
18382 write_radio_reg(pi,
18383 RADIO_2057_PAD2G_TUNE_PUS_CORE0,
18384 ci->RF_pad2g_tune_pus_core0);
18385 write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0,
18386 ci->RF_pga_boost_tune_core0);
18387 write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0,
18388 ci->RF_txmix5g_boost_tune_core0);
18389 write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0,
18390 ci->RF_pad5g_tune_misc_pus_core0);
18391 write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
18392 ci->RF_lna2g_tune_core0);
18393 write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0,
18394 ci->RF_lna5g_tune_core0);
18395
18396 write_radio_reg(pi,
18397 RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
18398 ci->RF_txmix2g_tune_boost_pu_core1);
18399 write_radio_reg(pi,
18400 RADIO_2057_PAD2G_TUNE_PUS_CORE1,
18401 ci->RF_pad2g_tune_pus_core1);
18402 write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1,
18403 ci->RF_pga_boost_tune_core1);
18404 write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1,
18405 ci->RF_txmix5g_boost_tune_core1);
18406 write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1,
18407 ci->RF_pad5g_tune_misc_pus_core1);
18408 write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
18409 ci->RF_lna2g_tune_core1);
18410 write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1,
18411 ci->RF_lna5g_tune_core1);
18412 }
18413
18414 if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
18415
18416 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18417 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
18418 0x3f);
18419 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
18420 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
18421 0x8);
18422 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
18423 0x8);
18424 } else {
18425 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
18426 0x1f);
18427 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
18428 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
18429 0x8);
18430 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
18431 0x8);
18432 }
18433 } else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) ||
18434 (pi->pubpi.radiorev == 8)) {
18435
18436 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18437 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
18438 0x1b);
18439 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30);
18440 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
18441 0xa);
18442 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
18443 0xa);
18444 } else {
18445 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
18446 0x1f);
18447 write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
18448 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
18449 0x8);
18450 write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
18451 0x8);
18452 }
18453
18454 }
18455
18456 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18457 if (PHY_IPA(pi)) {
18458 if (pi->pubpi.radiorev == 3) {
18459 txmix2g_tune_boost_pu = 0x6b;
18460 }
18461
18462 if (pi->pubpi.radiorev == 5)
18463 pad2g_tune_pus = 0x73;
18464
18465 } else {
18466 if (pi->pubpi.radiorev != 5) {
18467 pad2g_tune_pus = 0x3;
18468
18469 txmix2g_tune_boost_pu = 0x61;
18470 }
18471 }
18472
18473 for (coreNum = 0; coreNum <= 1; coreNum++) {
18474
18475 if (txmix2g_tune_boost_pu != 0)
18476 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
18477 TXMIX2G_TUNE_BOOST_PU,
18478 txmix2g_tune_boost_pu);
18479
18480 if (pad2g_tune_pus != 0)
18481 WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
18482 PAD2G_TUNE_PUS,
18483 pad2g_tune_pus);
18484 }
18485 }
18486
18487 udelay(50);
18488
18489 wlc_phy_radio205x_vcocal_nphy(pi);
18490}
18491
18492static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi)
18493{
18494 u16 rccal_valid;
18495 int i;
18496 bool chip43226_6362A0;
18497
18498 chip43226_6362A0 = ((pi->pubpi.radiorev == 3)
18499 || (pi->pubpi.radiorev == 4)
18500 || (pi->pubpi.radiorev == 6));
18501
18502 rccal_valid = 0;
18503 if (chip43226_6362A0) {
18504 write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61);
18505 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0);
18506 } else {
18507 write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61);
18508
18509 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9);
18510 }
18511 write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
18512 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
18513
18514 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
18515 rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
18516 if (rccal_valid & 0x2) {
18517 break;
18518 }
18519 udelay(500);
18520 }
18521
18522 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
18523
18524 rccal_valid = 0;
18525 if (chip43226_6362A0) {
18526 write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69);
18527 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
18528 } else {
18529 write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69);
18530
18531 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5);
18532 }
18533 write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
18534 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
18535
18536 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
18537 rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
18538 if (rccal_valid & 0x2) {
18539 break;
18540 }
18541 udelay(500);
18542 }
18543
18544 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
18545
18546 rccal_valid = 0;
18547 if (chip43226_6362A0) {
18548 write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73);
18549
18550 write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28);
18551 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
18552 } else {
18553 write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73);
18554 write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
18555 write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99);
18556 }
18557 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
18558
18559 for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
18560 rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
18561 if (rccal_valid & 0x2) {
18562 break;
18563 }
18564 udelay(500);
18565 }
18566
18567 if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4"))
18568 return 0;
18569
18570 write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
18571
18572 return rccal_valid;
18573}
18574
18575static void
18576wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr)
18577{
18578 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
18579 if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
18580 CHSPEC_IS40(pi->radio_chanspec)) {
18581 if (!pi->nphy_anarxlpf_adjusted) {
18582 write_radio_reg(pi,
18583 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
18584 RADIO_2056_RX0),
18585 ((pi->nphy_rccal_value +
18586 reduction_factr) | 0x80));
18587
18588 pi->nphy_anarxlpf_adjusted = true;
18589 }
18590 } else {
18591 if (pi->nphy_anarxlpf_adjusted) {
18592 write_radio_reg(pi,
18593 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
18594 RADIO_2056_RX0),
18595 (pi->nphy_rccal_value | 0x80));
18596
18597 pi->nphy_anarxlpf_adjusted = false;
18598 }
18599 }
18600 }
18601}
18602
18603static void
18604wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, int ntones,
18605 int *tone_id_buf, u32 *noise_var_buf)
18606{
18607 int i;
18608 u32 offset;
18609 int tone_id;
18610 int tbllen =
18611 CHSPEC_IS40(pi->
18612 radio_chanspec) ? NPHY_NOISEVAR_TBLLEN40 :
18613 NPHY_NOISEVAR_TBLLEN20;
18614
18615 if (pi->nphy_noisevars_adjusted) {
18616 for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) {
18617 tone_id = pi->nphy_saved_noisevars.tone_id[i];
18618 offset = (tone_id >= 0) ?
18619 ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1);
18620 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
18621 offset, 32,
18622 (void *)&pi->
18623 nphy_saved_noisevars.
18624 min_noise_vars[i]);
18625 }
18626
18627 pi->nphy_saved_noisevars.bufcount = 0;
18628 pi->nphy_noisevars_adjusted = false;
18629 }
18630
18631 if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) {
18632 pi->nphy_saved_noisevars.bufcount = 0;
18633
18634 for (i = 0; i < ntones; i++) {
18635 tone_id = tone_id_buf[i];
18636 offset = (tone_id >= 0) ?
18637 ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1);
18638 pi->nphy_saved_noisevars.tone_id[i] = tone_id;
18639 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
18640 offset, 32,
18641 &pi->nphy_saved_noisevars.
18642 min_noise_vars[i]);
18643 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
18644 offset, 32,
18645 (void *)&noise_var_buf[i]);
18646 pi->nphy_saved_noisevars.bufcount++;
18647 }
18648
18649 pi->nphy_noisevars_adjusted = true;
18650 }
18651}
18652
18653static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr)
18654{
18655 u16 regval;
18656
18657 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18658 if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
18659 CHSPEC_IS40(pi->radio_chanspec)) {
18660 if (!pi->nphy_crsminpwr_adjusted) {
18661 regval = read_phy_reg(pi, 0x27d);
18662 pi->nphy_crsminpwr[0] = regval & 0xff;
18663 regval &= 0xff00;
18664 regval |= (u16) minpwr;
18665 write_phy_reg(pi, 0x27d, regval);
18666
18667 regval = read_phy_reg(pi, 0x280);
18668 pi->nphy_crsminpwr[1] = regval & 0xff;
18669 regval &= 0xff00;
18670 regval |= (u16) minpwr;
18671 write_phy_reg(pi, 0x280, regval);
18672
18673 regval = read_phy_reg(pi, 0x283);
18674 pi->nphy_crsminpwr[2] = regval & 0xff;
18675 regval &= 0xff00;
18676 regval |= (u16) minpwr;
18677 write_phy_reg(pi, 0x283, regval);
18678
18679 pi->nphy_crsminpwr_adjusted = true;
18680 }
18681 } else {
18682 if (pi->nphy_crsminpwr_adjusted) {
18683 regval = read_phy_reg(pi, 0x27d);
18684 regval &= 0xff00;
18685 regval |= pi->nphy_crsminpwr[0];
18686 write_phy_reg(pi, 0x27d, regval);
18687
18688 regval = read_phy_reg(pi, 0x280);
18689 regval &= 0xff00;
18690 regval |= pi->nphy_crsminpwr[1];
18691 write_phy_reg(pi, 0x280, regval);
18692
18693 regval = read_phy_reg(pi, 0x283);
18694 regval &= 0xff00;
18695 regval |= pi->nphy_crsminpwr[2];
18696 write_phy_reg(pi, 0x283, regval);
18697
18698 pi->nphy_crsminpwr_adjusted = false;
18699 }
18700 }
18701 }
18702}
18703
18704static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi)
18705{
18706 u8 tx_lpf_bw = 0;
18707
18708 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
18709 if (CHSPEC_IS40(pi->radio_chanspec)) {
18710 tx_lpf_bw = 3;
18711 } else {
18712 tx_lpf_bw = 1;
18713 }
18714
18715 if (PHY_IPA(pi)) {
18716 if (CHSPEC_IS40(pi->radio_chanspec)) {
18717 tx_lpf_bw = 5;
18718 } else {
18719 tx_lpf_bw = 4;
18720 }
18721 }
18722 write_phy_reg(pi, 0xe8,
18723 (tx_lpf_bw << 0) |
18724 (tx_lpf_bw << 3) |
18725 (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
18726
18727 if (PHY_IPA(pi)) {
18728
18729 if (CHSPEC_IS40(pi->radio_chanspec)) {
18730 tx_lpf_bw = 4;
18731 } else {
18732 tx_lpf_bw = 1;
18733 }
18734
18735 write_phy_reg(pi, 0xe9,
18736 (tx_lpf_bw << 0) |
18737 (tx_lpf_bw << 3) |
18738 (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
18739 }
18740 }
18741}
18742
18743static void wlc_phy_spurwar_nphy(struct brcms_phy *pi)
18744{
18745 u16 cur_channel = 0;
18746 int nphy_adj_tone_id_buf[] = { 57, 58 };
18747 u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff };
18748 bool isAdjustNoiseVar = false;
18749 uint numTonesAdjust = 0;
18750 u32 tempval = 0;
18751
18752 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
18753 if (pi->phyhang_avoid)
18754 wlc_phy_stay_in_carriersearch_nphy(pi, true);
18755
18756 cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
18757
18758 if (pi->nphy_gband_spurwar_en) {
18759
18760 wlc_phy_adjust_rx_analpfbw_nphy(pi,
18761 NPHY_ANARXLPFBW_REDUCTIONFACT);
18762
18763 if (CHSPEC_IS2G(pi->radio_chanspec)) {
18764 if ((cur_channel == 11)
18765 && CHSPEC_IS40(pi->radio_chanspec)) {
18766
18767 wlc_phy_adjust_min_noisevar_nphy(pi, 2,
18768 nphy_adj_tone_id_buf,
18769 nphy_adj_noise_var_buf);
18770 } else {
18771
18772 wlc_phy_adjust_min_noisevar_nphy(pi, 0,
18773 NULL,
18774 NULL);
18775 }
18776 }
18777 wlc_phy_adjust_crsminpwr_nphy(pi,
18778 NPHY_ADJUSTED_MINCRSPOWER);
18779 }
18780
18781 if ((pi->nphy_gband_spurwar2_en)
18782 && CHSPEC_IS2G(pi->radio_chanspec)) {
18783
18784 if (CHSPEC_IS40(pi->radio_chanspec)) {
18785 switch (cur_channel) {
18786 case 3:
18787 nphy_adj_tone_id_buf[0] = 57;
18788 nphy_adj_tone_id_buf[1] = 58;
18789 nphy_adj_noise_var_buf[0] = 0x22f;
18790 nphy_adj_noise_var_buf[1] = 0x25f;
18791 isAdjustNoiseVar = true;
18792 break;
18793 case 4:
18794 nphy_adj_tone_id_buf[0] = 41;
18795 nphy_adj_tone_id_buf[1] = 42;
18796 nphy_adj_noise_var_buf[0] = 0x22f;
18797 nphy_adj_noise_var_buf[1] = 0x25f;
18798 isAdjustNoiseVar = true;
18799 break;
18800 case 5:
18801 nphy_adj_tone_id_buf[0] = 25;
18802 nphy_adj_tone_id_buf[1] = 26;
18803 nphy_adj_noise_var_buf[0] = 0x24f;
18804 nphy_adj_noise_var_buf[1] = 0x25f;
18805 isAdjustNoiseVar = true;
18806 break;
18807 case 6:
18808 nphy_adj_tone_id_buf[0] = 9;
18809 nphy_adj_tone_id_buf[1] = 10;
18810 nphy_adj_noise_var_buf[0] = 0x22f;
18811 nphy_adj_noise_var_buf[1] = 0x24f;
18812 isAdjustNoiseVar = true;
18813 break;
18814 case 7:
18815 nphy_adj_tone_id_buf[0] = 121;
18816 nphy_adj_tone_id_buf[1] = 122;
18817 nphy_adj_noise_var_buf[0] = 0x18f;
18818 nphy_adj_noise_var_buf[1] = 0x24f;
18819 isAdjustNoiseVar = true;
18820 break;
18821 case 8:
18822 nphy_adj_tone_id_buf[0] = 105;
18823 nphy_adj_tone_id_buf[1] = 106;
18824 nphy_adj_noise_var_buf[0] = 0x22f;
18825 nphy_adj_noise_var_buf[1] = 0x25f;
18826 isAdjustNoiseVar = true;
18827 break;
18828 case 9:
18829 nphy_adj_tone_id_buf[0] = 89;
18830 nphy_adj_tone_id_buf[1] = 90;
18831 nphy_adj_noise_var_buf[0] = 0x22f;
18832 nphy_adj_noise_var_buf[1] = 0x24f;
18833 isAdjustNoiseVar = true;
18834 break;
18835 case 10:
18836 nphy_adj_tone_id_buf[0] = 73;
18837 nphy_adj_tone_id_buf[1] = 74;
18838 nphy_adj_noise_var_buf[0] = 0x22f;
18839 nphy_adj_noise_var_buf[1] = 0x24f;
18840 isAdjustNoiseVar = true;
18841 break;
18842 default:
18843 isAdjustNoiseVar = false;
18844 break;
18845 }
18846 }
18847
18848 if (isAdjustNoiseVar) {
18849 numTonesAdjust = sizeof(nphy_adj_tone_id_buf) /
18850 sizeof(nphy_adj_tone_id_buf[0]);
18851
18852 wlc_phy_adjust_min_noisevar_nphy(pi,
18853 numTonesAdjust,
18854 nphy_adj_tone_id_buf,
18855 nphy_adj_noise_var_buf);
18856
18857 tempval = 0;
18858
18859 } else {
18860
18861 wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
18862 NULL);
18863 }
18864 }
18865
18866 if ((pi->nphy_aband_spurwar_en) &&
18867 (CHSPEC_IS5G(pi->radio_chanspec))) {
18868 switch (cur_channel) {
18869 case 54:
18870 nphy_adj_tone_id_buf[0] = 32;
18871 nphy_adj_noise_var_buf[0] = 0x25f;
18872 break;
18873 case 38:
18874 case 102:
18875 case 118:
18876 nphy_adj_tone_id_buf[0] = 0;
18877 nphy_adj_noise_var_buf[0] = 0x0;
18878 break;
18879 case 134:
18880 nphy_adj_tone_id_buf[0] = 32;
18881 nphy_adj_noise_var_buf[0] = 0x21f;
18882 break;
18883 case 151:
18884 nphy_adj_tone_id_buf[0] = 16;
18885 nphy_adj_noise_var_buf[0] = 0x23f;
18886 break;
18887 case 153:
18888 case 161:
18889 nphy_adj_tone_id_buf[0] = 48;
18890 nphy_adj_noise_var_buf[0] = 0x23f;
18891 break;
18892 default:
18893 nphy_adj_tone_id_buf[0] = 0;
18894 nphy_adj_noise_var_buf[0] = 0x0;
18895 break;
18896 }
18897
18898 if (nphy_adj_tone_id_buf[0]
18899 && nphy_adj_noise_var_buf[0]) {
18900 wlc_phy_adjust_min_noisevar_nphy(pi, 1,
18901 nphy_adj_tone_id_buf,
18902 nphy_adj_noise_var_buf);
18903 } else {
18904 wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
18905 NULL);
18906 }
18907 }
18908
18909 if (pi->phyhang_avoid)
18910 wlc_phy_stay_in_carriersearch_nphy(pi, false);
18911 }
18912}
18913
18914static void
18915wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chanspec,
18916 const struct nphy_sfo_cfg *ci)
18917{
18918 u16 val;
18919
18920 val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
18921 if (CHSPEC_IS5G(chanspec) && !val) {
18922
18923 val = R_REG(&pi->regs->psm_phy_hdr_param);
18924 W_REG(&pi->regs->psm_phy_hdr_param,
18925 (val | MAC_PHY_FORCE_CLK));
18926
18927 or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
18928 (BBCFG_RESETCCA | BBCFG_RESETRX));
18929
18930 W_REG(&pi->regs->psm_phy_hdr_param, val);
18931
18932 or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
18933 } else if (!CHSPEC_IS5G(chanspec) && val) {
18934
18935 and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
18936
18937 val = R_REG(&pi->regs->psm_phy_hdr_param);
18938 W_REG(&pi->regs->psm_phy_hdr_param,
18939 (val | MAC_PHY_FORCE_CLK));
18940
18941 and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
18942 (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
18943
18944 W_REG(&pi->regs->psm_phy_hdr_param, val);
18945 }
18946
18947 write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
18948 write_phy_reg(pi, 0x1cf, ci->PHY_BW2);
18949 write_phy_reg(pi, 0x1d0, ci->PHY_BW3);
18950
18951 write_phy_reg(pi, 0x1d1, ci->PHY_BW4);
18952 write_phy_reg(pi, 0x1d2, ci->PHY_BW5);
18953 write_phy_reg(pi, 0x1d3, ci->PHY_BW6);
18954
18955 if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
18956 wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0);
18957
18958 or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800);
18959 } else {
18960 wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en,
18961 NPHY_ClassifierCtrl_ofdm_en);
18962
18963 if (CHSPEC_IS2G(chanspec))
18964 and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840);
18965 }
18966
18967 if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
18968 wlc_phy_txpwr_fixpower_nphy(pi);
18969 }
18970
18971 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
18972
18973 wlc_phy_adjust_lnagaintbl_nphy(pi);
18974 }
18975
18976 wlc_phy_txlpfbw_nphy(pi);
18977
18978 if (NREV_GE(pi->pubpi.phy_rev, 3)
18979 && (pi->phy_spuravoid != SPURAVOID_DISABLE)) {
18980 u8 spuravoid = 0;
18981
18982 val = CHSPEC_CHANNEL(chanspec);
18983 if (!CHSPEC_IS40(pi->radio_chanspec)) {
18984 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18985 if ((val == 13) || (val == 14) || (val == 153)) {
18986 spuravoid = 1;
18987 }
18988 } else {
18989
18990 if (((val >= 5) && (val <= 8)) || (val == 13)
18991 || (val == 14)) {
18992 spuravoid = 1;
18993 }
18994 }
18995 } else {
18996 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
18997 if (val == 54) {
18998 spuravoid = 1;
18999 }
19000 } else {
19001
19002 if (pi->nphy_aband_spurwar_en &&
19003 ((val == 38) || (val == 102)
19004 || (val == 118)))
19005 spuravoid = 1;
19006 }
19007 }
19008
19009 if (pi->phy_spuravoid == SPURAVOID_FORCEON)
19010 spuravoid = 1;
19011
19012 wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
19013 si_pmu_spuravoid(pi->sh->sih, spuravoid);
19014 wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
19015
19016 if ((pi->sh->chip == BCM43224_CHIP_ID) ||
19017 (pi->sh->chip == BCM43225_CHIP_ID)) {
19018
19019 if (spuravoid == 1) {
19020
19021 W_REG(&pi->regs->tsf_clk_frac_l,
19022 0x5341);
19023 W_REG(&pi->regs->tsf_clk_frac_h,
19024 0x8);
19025 } else {
19026
19027 W_REG(&pi->regs->tsf_clk_frac_l,
19028 0x8889);
19029 W_REG(&pi->regs->tsf_clk_frac_h,
19030 0x8);
19031 }
19032 }
19033
19034 wlapi_bmac_core_phypll_reset(pi->sh->physhim);
19035
19036 mod_phy_reg(pi, 0x01, (0x1 << 15),
19037 ((spuravoid > 0) ? (0x1 << 15) : 0));
19038
19039 wlc_phy_resetcca_nphy(pi);
19040
19041 pi->phy_isspuravoid = (spuravoid > 0);
19042 }
19043
19044 if (NREV_LT(pi->pubpi.phy_rev, 7))
19045 write_phy_reg(pi, 0x17e, 0x3830);
19046
19047 wlc_phy_spurwar_nphy(pi);
19048}
19049
19050void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, chanspec_t chanspec)
19051{
19052 int freq;
19053 struct chan_info_nphy_radio2057 *t0 = NULL;
19054 struct chan_info_nphy_radio205x *t1 = NULL;
19055 struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
19056 struct chan_info_nphy_2055 *t3 = NULL;
19057
19058 if (NORADIO_ENAB(pi->pubpi)) {
19059 return;
19060 }
19061
19062 if (!wlc_phy_chan2freq_nphy
19063 (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3))
19064 return;
19065
19066 wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
19067
19068 if (CHSPEC_BW(chanspec) != pi->bw)
19069 wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec));
19070
19071 if (CHSPEC_IS40(chanspec)) {
19072 if (CHSPEC_SB_UPPER(chanspec)) {
19073 or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20);
19074 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19075 or_phy_reg(pi, 0x310, PRIM_SEL_UP20);
19076 }
19077 } else {
19078 and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20);
19079 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19080 and_phy_reg(pi, 0x310,
19081 (~PRIM_SEL_UP20 & 0xffff));
19082 }
19083 }
19084 }
19085
19086 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19087 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19088
19089 if ((pi->pubpi.radiorev <= 4)
19090 || (pi->pubpi.radiorev == 6)) {
19091 mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0,
19092 0x2,
19093 (CHSPEC_IS5G(chanspec) ? (1 << 1)
19094 : 0));
19095 mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1,
19096 0x2,
19097 (CHSPEC_IS5G(chanspec) ? (1 << 1)
19098 : 0));
19099 }
19100
19101 wlc_phy_chanspec_radio2057_setup(pi, t0, t2);
19102 wlc_phy_chanspec_nphy_setup(pi, chanspec,
19103 (pi->pubpi.radiorev == 5) ?
19104 (const struct nphy_sfo_cfg *)&(t2->PHY_BW1a) :
19105 (const struct nphy_sfo_cfg *)&(t0->PHY_BW1a));
19106
19107 } else {
19108
19109 mod_radio_reg(pi,
19110 RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN,
19111 0x4,
19112 (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0));
19113 wlc_phy_chanspec_radio2056_setup(pi, t1);
19114
19115 wlc_phy_chanspec_nphy_setup(pi, chanspec,
19116 (const struct nphy_sfo_cfg *) &(t1->PHY_BW1a));
19117 }
19118
19119 } else {
19120
19121 mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70,
19122 (CHSPEC_IS5G(chanspec) ? (0x02 << 4)
19123 : (0x05 << 4)));
19124
19125 wlc_phy_chanspec_radio2055_setup(pi, t3);
19126 wlc_phy_chanspec_nphy_setup(pi, chanspec,
19127 (const struct nphy_sfo_cfg *)&(t3->
19128 PHY_BW1a));
19129 }
19130
19131}
19132
19133static void wlc_phy_savecal_nphy(struct brcms_phy *pi)
19134{
19135 void *tbl_ptr;
19136 int coreNum;
19137 u16 *txcal_radio_regs = NULL;
19138
19139 if (pi->phyhang_avoid)
19140 wlc_phy_stay_in_carriersearch_nphy(pi, true);
19141
19142 if (CHSPEC_IS2G(pi->radio_chanspec)) {
19143
19144 wlc_phy_rx_iq_coeffs_nphy(pi, 0,
19145 &pi->calibration_cache.
19146 rxcal_coeffs_2G);
19147
19148 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19149 txcal_radio_regs =
19150 pi->calibration_cache.txcal_radio_regs_2G;
19151 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19152
19153 pi->calibration_cache.txcal_radio_regs_2G[0] =
19154 read_radio_reg(pi,
19155 RADIO_2056_TX_LOFT_FINE_I |
19156 RADIO_2056_TX0);
19157 pi->calibration_cache.txcal_radio_regs_2G[1] =
19158 read_radio_reg(pi,
19159 RADIO_2056_TX_LOFT_FINE_Q |
19160 RADIO_2056_TX0);
19161 pi->calibration_cache.txcal_radio_regs_2G[2] =
19162 read_radio_reg(pi,
19163 RADIO_2056_TX_LOFT_FINE_I |
19164 RADIO_2056_TX1);
19165 pi->calibration_cache.txcal_radio_regs_2G[3] =
19166 read_radio_reg(pi,
19167 RADIO_2056_TX_LOFT_FINE_Q |
19168 RADIO_2056_TX1);
19169
19170 pi->calibration_cache.txcal_radio_regs_2G[4] =
19171 read_radio_reg(pi,
19172 RADIO_2056_TX_LOFT_COARSE_I |
19173 RADIO_2056_TX0);
19174 pi->calibration_cache.txcal_radio_regs_2G[5] =
19175 read_radio_reg(pi,
19176 RADIO_2056_TX_LOFT_COARSE_Q |
19177 RADIO_2056_TX0);
19178 pi->calibration_cache.txcal_radio_regs_2G[6] =
19179 read_radio_reg(pi,
19180 RADIO_2056_TX_LOFT_COARSE_I |
19181 RADIO_2056_TX1);
19182 pi->calibration_cache.txcal_radio_regs_2G[7] =
19183 read_radio_reg(pi,
19184 RADIO_2056_TX_LOFT_COARSE_Q |
19185 RADIO_2056_TX1);
19186 } else {
19187 pi->calibration_cache.txcal_radio_regs_2G[0] =
19188 read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
19189 pi->calibration_cache.txcal_radio_regs_2G[1] =
19190 read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
19191 pi->calibration_cache.txcal_radio_regs_2G[2] =
19192 read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
19193 pi->calibration_cache.txcal_radio_regs_2G[3] =
19194 read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
19195 }
19196
19197 pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec;
19198 tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
19199 } else {
19200
19201 wlc_phy_rx_iq_coeffs_nphy(pi, 0,
19202 &pi->calibration_cache.
19203 rxcal_coeffs_5G);
19204
19205 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19206 txcal_radio_regs =
19207 pi->calibration_cache.txcal_radio_regs_5G;
19208 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19209
19210 pi->calibration_cache.txcal_radio_regs_5G[0] =
19211 read_radio_reg(pi,
19212 RADIO_2056_TX_LOFT_FINE_I |
19213 RADIO_2056_TX0);
19214 pi->calibration_cache.txcal_radio_regs_5G[1] =
19215 read_radio_reg(pi,
19216 RADIO_2056_TX_LOFT_FINE_Q |
19217 RADIO_2056_TX0);
19218 pi->calibration_cache.txcal_radio_regs_5G[2] =
19219 read_radio_reg(pi,
19220 RADIO_2056_TX_LOFT_FINE_I |
19221 RADIO_2056_TX1);
19222 pi->calibration_cache.txcal_radio_regs_5G[3] =
19223 read_radio_reg(pi,
19224 RADIO_2056_TX_LOFT_FINE_Q |
19225 RADIO_2056_TX1);
19226
19227 pi->calibration_cache.txcal_radio_regs_5G[4] =
19228 read_radio_reg(pi,
19229 RADIO_2056_TX_LOFT_COARSE_I |
19230 RADIO_2056_TX0);
19231 pi->calibration_cache.txcal_radio_regs_5G[5] =
19232 read_radio_reg(pi,
19233 RADIO_2056_TX_LOFT_COARSE_Q |
19234 RADIO_2056_TX0);
19235 pi->calibration_cache.txcal_radio_regs_5G[6] =
19236 read_radio_reg(pi,
19237 RADIO_2056_TX_LOFT_COARSE_I |
19238 RADIO_2056_TX1);
19239 pi->calibration_cache.txcal_radio_regs_5G[7] =
19240 read_radio_reg(pi,
19241 RADIO_2056_TX_LOFT_COARSE_Q |
19242 RADIO_2056_TX1);
19243 } else {
19244 pi->calibration_cache.txcal_radio_regs_5G[0] =
19245 read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
19246 pi->calibration_cache.txcal_radio_regs_5G[1] =
19247 read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
19248 pi->calibration_cache.txcal_radio_regs_5G[2] =
19249 read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
19250 pi->calibration_cache.txcal_radio_regs_5G[3] =
19251 read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
19252 }
19253
19254 pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec;
19255 tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
19256 }
19257 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19258 for (coreNum = 0; coreNum <= 1; coreNum++) {
19259
19260 txcal_radio_regs[2 * coreNum] =
19261 READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19262 LOFT_FINE_I);
19263 txcal_radio_regs[2 * coreNum + 1] =
19264 READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19265 LOFT_FINE_Q);
19266
19267 txcal_radio_regs[2 * coreNum + 4] =
19268 READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19269 LOFT_COARSE_I);
19270 txcal_radio_regs[2 * coreNum + 5] =
19271 READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19272 LOFT_COARSE_Q);
19273 }
19274 }
19275
19276 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr);
19277
19278 if (pi->phyhang_avoid)
19279 wlc_phy_stay_in_carriersearch_nphy(pi, false);
19280}
19281
19282static void wlc_phy_restorecal_nphy(struct brcms_phy *pi)
19283{
19284 u16 *loft_comp;
19285 u16 txcal_coeffs_bphy[4];
19286 u16 *tbl_ptr;
19287 int coreNum;
19288 u16 *txcal_radio_regs = NULL;
19289
19290 if (CHSPEC_IS2G(pi->radio_chanspec)) {
19291 if (pi->nphy_iqcal_chanspec_2G == 0)
19292 return;
19293
19294 tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
19295 loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5];
19296 } else {
19297 if (pi->nphy_iqcal_chanspec_5G == 0)
19298 return;
19299
19300 tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
19301 loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5];
19302 }
19303
19304 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16,
19305 (void *)tbl_ptr);
19306
19307 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19308 txcal_coeffs_bphy[0] = tbl_ptr[0];
19309 txcal_coeffs_bphy[1] = tbl_ptr[1];
19310 txcal_coeffs_bphy[2] = tbl_ptr[2];
19311 txcal_coeffs_bphy[3] = tbl_ptr[3];
19312 } else {
19313 txcal_coeffs_bphy[0] = 0;
19314 txcal_coeffs_bphy[1] = 0;
19315 txcal_coeffs_bphy[2] = 0;
19316 txcal_coeffs_bphy[3] = 0;
19317 }
19318
19319 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16,
19320 txcal_coeffs_bphy);
19321
19322 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp);
19323
19324 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp);
19325
19326 if (NREV_LT(pi->pubpi.phy_rev, 2))
19327 wlc_phy_tx_iq_war_nphy(pi);
19328
19329 if (CHSPEC_IS2G(pi->radio_chanspec)) {
19330 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19331 txcal_radio_regs =
19332 pi->calibration_cache.txcal_radio_regs_2G;
19333 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19334
19335 write_radio_reg(pi,
19336 RADIO_2056_TX_LOFT_FINE_I |
19337 RADIO_2056_TX0,
19338 pi->calibration_cache.
19339 txcal_radio_regs_2G[0]);
19340 write_radio_reg(pi,
19341 RADIO_2056_TX_LOFT_FINE_Q |
19342 RADIO_2056_TX0,
19343 pi->calibration_cache.
19344 txcal_radio_regs_2G[1]);
19345 write_radio_reg(pi,
19346 RADIO_2056_TX_LOFT_FINE_I |
19347 RADIO_2056_TX1,
19348 pi->calibration_cache.
19349 txcal_radio_regs_2G[2]);
19350 write_radio_reg(pi,
19351 RADIO_2056_TX_LOFT_FINE_Q |
19352 RADIO_2056_TX1,
19353 pi->calibration_cache.
19354 txcal_radio_regs_2G[3]);
19355
19356 write_radio_reg(pi,
19357 RADIO_2056_TX_LOFT_COARSE_I |
19358 RADIO_2056_TX0,
19359 pi->calibration_cache.
19360 txcal_radio_regs_2G[4]);
19361 write_radio_reg(pi,
19362 RADIO_2056_TX_LOFT_COARSE_Q |
19363 RADIO_2056_TX0,
19364 pi->calibration_cache.
19365 txcal_radio_regs_2G[5]);
19366 write_radio_reg(pi,
19367 RADIO_2056_TX_LOFT_COARSE_I |
19368 RADIO_2056_TX1,
19369 pi->calibration_cache.
19370 txcal_radio_regs_2G[6]);
19371 write_radio_reg(pi,
19372 RADIO_2056_TX_LOFT_COARSE_Q |
19373 RADIO_2056_TX1,
19374 pi->calibration_cache.
19375 txcal_radio_regs_2G[7]);
19376 } else {
19377 write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
19378 pi->calibration_cache.
19379 txcal_radio_regs_2G[0]);
19380 write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
19381 pi->calibration_cache.
19382 txcal_radio_regs_2G[1]);
19383 write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
19384 pi->calibration_cache.
19385 txcal_radio_regs_2G[2]);
19386 write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
19387 pi->calibration_cache.
19388 txcal_radio_regs_2G[3]);
19389 }
19390
19391 wlc_phy_rx_iq_coeffs_nphy(pi, 1,
19392 &pi->calibration_cache.
19393 rxcal_coeffs_2G);
19394 } else {
19395 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19396 txcal_radio_regs =
19397 pi->calibration_cache.txcal_radio_regs_5G;
19398 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19399
19400 write_radio_reg(pi,
19401 RADIO_2056_TX_LOFT_FINE_I |
19402 RADIO_2056_TX0,
19403 pi->calibration_cache.
19404 txcal_radio_regs_5G[0]);
19405 write_radio_reg(pi,
19406 RADIO_2056_TX_LOFT_FINE_Q |
19407 RADIO_2056_TX0,
19408 pi->calibration_cache.
19409 txcal_radio_regs_5G[1]);
19410 write_radio_reg(pi,
19411 RADIO_2056_TX_LOFT_FINE_I |
19412 RADIO_2056_TX1,
19413 pi->calibration_cache.
19414 txcal_radio_regs_5G[2]);
19415 write_radio_reg(pi,
19416 RADIO_2056_TX_LOFT_FINE_Q |
19417 RADIO_2056_TX1,
19418 pi->calibration_cache.
19419 txcal_radio_regs_5G[3]);
19420
19421 write_radio_reg(pi,
19422 RADIO_2056_TX_LOFT_COARSE_I |
19423 RADIO_2056_TX0,
19424 pi->calibration_cache.
19425 txcal_radio_regs_5G[4]);
19426 write_radio_reg(pi,
19427 RADIO_2056_TX_LOFT_COARSE_Q |
19428 RADIO_2056_TX0,
19429 pi->calibration_cache.
19430 txcal_radio_regs_5G[5]);
19431 write_radio_reg(pi,
19432 RADIO_2056_TX_LOFT_COARSE_I |
19433 RADIO_2056_TX1,
19434 pi->calibration_cache.
19435 txcal_radio_regs_5G[6]);
19436 write_radio_reg(pi,
19437 RADIO_2056_TX_LOFT_COARSE_Q |
19438 RADIO_2056_TX1,
19439 pi->calibration_cache.
19440 txcal_radio_regs_5G[7]);
19441 } else {
19442 write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
19443 pi->calibration_cache.
19444 txcal_radio_regs_5G[0]);
19445 write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
19446 pi->calibration_cache.
19447 txcal_radio_regs_5G[1]);
19448 write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
19449 pi->calibration_cache.
19450 txcal_radio_regs_5G[2]);
19451 write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
19452 pi->calibration_cache.
19453 txcal_radio_regs_5G[3]);
19454 }
19455
19456 wlc_phy_rx_iq_coeffs_nphy(pi, 1,
19457 &pi->calibration_cache.
19458 rxcal_coeffs_5G);
19459 }
19460
19461 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19462 for (coreNum = 0; coreNum <= 1; coreNum++) {
19463
19464 WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19465 LOFT_FINE_I,
19466 txcal_radio_regs[2 * coreNum]);
19467 WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19468 LOFT_FINE_Q,
19469 txcal_radio_regs[2 * coreNum + 1]);
19470
19471 WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19472 LOFT_COARSE_I,
19473 txcal_radio_regs[2 * coreNum + 4]);
19474 WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
19475 LOFT_COARSE_Q,
19476 txcal_radio_regs[2 * coreNum + 5]);
19477 }
19478 }
19479}
19480
19481void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
19482{
19483 struct brcms_phy *pi = (struct brcms_phy *) ppi;
19484 u16 mask = 0xfc00;
19485 u32 mc = 0;
19486
19487 if (NREV_GE(pi->pubpi.phy_rev, 7))
19488 return;
19489
19490 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
19491 u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
19492
19493 if (lut_init == false)
19494 return;
19495
19496 if (pi->srom_fem2g.antswctrllut == 0) {
19497 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
19498 1, 0x02, 16, &v0);
19499 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
19500 1, 0x03, 16, &v1);
19501 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
19502 1, 0x08, 16, &v2);
19503 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
19504 1, 0x0C, 16, &v3);
19505 }
19506
19507 if (pi->srom_fem5g.antswctrllut == 0) {
19508 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
19509 1, 0x12, 16, &v0);
19510 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
19511 1, 0x13, 16, &v1);
19512 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
19513 1, 0x18, 16, &v2);
19514 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
19515 1, 0x1C, 16, &v3);
19516 }
19517 } else {
19518
19519 write_phy_reg(pi, 0xc8, 0x0);
19520 write_phy_reg(pi, 0xc9, 0x0);
19521
19522 ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
19523
19524 mc = R_REG(&pi->regs->maccontrol);
19525 mc &= ~MCTL_GPOUT_SEL_MASK;
19526 W_REG(&pi->regs->maccontrol, mc);
19527
19528 OR_REG(&pi->regs->psm_gpio_oe, mask);
19529
19530 AND_REG(&pi->regs->psm_gpio_out, ~mask);
19531
19532 if (lut_init) {
19533 write_phy_reg(pi, 0xf8, 0x02d8);
19534 write_phy_reg(pi, 0xf9, 0x0301);
19535 write_phy_reg(pi, 0xfa, 0x02d8);
19536 write_phy_reg(pi, 0xfb, 0x0301);
19537 }
19538 }
19539}
19540
19541u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val)
19542{
19543 u16 curr_ctl, new_ctl;
19544 bool suspended = false;
19545
19546 if (D11REV_IS(pi->sh->corerev, 16)) {
19547 suspended =
19548 (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) ?
19549 false : true;
19550 if (!suspended)
19551 wlapi_suspend_mac_and_wait(pi->sh->physhim);
19552 }
19553
19554 curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0);
19555
19556 new_ctl = (curr_ctl & (~mask)) | (val & mask);
19557
19558 mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl);
19559
19560 if (D11REV_IS(pi->sh->corerev, 16) && !suspended)
19561 wlapi_enable_mac(pi->sh->physhim);
19562
19563 return new_ctl;
19564}
19565
19566static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals)
19567{
19568
19569 if (write == 0) {
19570 vals[0] = read_phy_reg(pi, 0x2c);
19571 vals[1] = read_phy_reg(pi, 0x42);
19572 } else {
19573 write_phy_reg(pi, 0x2c, vals[0]);
19574 write_phy_reg(pi, 0x42, vals[1]);
19575 }
19576}
19577
19578void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd)
19579{
19580 u16 trigger_mask, status_mask;
19581 u16 orig_RfseqCoreActv;
19582
19583 switch (cmd) {
19584 case NPHY_RFSEQ_RX2TX:
19585 trigger_mask = NPHY_RfseqTrigger_rx2tx;
19586 status_mask = NPHY_RfseqStatus_rx2tx;
19587 break;
19588 case NPHY_RFSEQ_TX2RX:
19589 trigger_mask = NPHY_RfseqTrigger_tx2rx;
19590 status_mask = NPHY_RfseqStatus_tx2rx;
19591 break;
19592 case NPHY_RFSEQ_RESET2RX:
19593 trigger_mask = NPHY_RfseqTrigger_reset2rx;
19594 status_mask = NPHY_RfseqStatus_reset2rx;
19595 break;
19596 case NPHY_RFSEQ_UPDATEGAINH:
19597 trigger_mask = NPHY_RfseqTrigger_updategainh;
19598 status_mask = NPHY_RfseqStatus_updategainh;
19599 break;
19600 case NPHY_RFSEQ_UPDATEGAINL:
19601 trigger_mask = NPHY_RfseqTrigger_updategainl;
19602 status_mask = NPHY_RfseqStatus_updategainl;
19603 break;
19604 case NPHY_RFSEQ_UPDATEGAINU:
19605 trigger_mask = NPHY_RfseqTrigger_updategainu;
19606 status_mask = NPHY_RfseqStatus_updategainu;
19607 break;
19608 default:
19609 return;
19610 }
19611
19612 orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
19613 or_phy_reg(pi, 0xa1,
19614 (NPHY_RfseqMode_CoreActv_override |
19615 NPHY_RfseqMode_Trigger_override));
19616 or_phy_reg(pi, 0xa3, trigger_mask);
19617 SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
19618 write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
19619 WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf");
19620}
19621
19622static void
19623wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
19624 u8 len)
19625{
19626 u32 t1_offset, t2_offset;
19627 u8 ctr;
19628 u8 end_event =
19629 NREV_GE(pi->pubpi.phy_rev,
19630 3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
19631 u8 end_dly = 1;
19632
19633 if (pi->phyhang_avoid)
19634 wlc_phy_stay_in_carriersearch_nphy(pi, true);
19635
19636 t1_offset = cmd << 4;
19637 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8,
19638 events);
19639 t2_offset = t1_offset + 0x080;
19640 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8,
19641 dlys);
19642
19643 for (ctr = len; ctr < 16; ctr++) {
19644 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
19645 t1_offset + ctr, 8, &end_event);
19646 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
19647 t2_offset + ctr, 8, &end_dly);
19648 }
19649
19650 if (pi->phyhang_avoid)
19651 wlc_phy_stay_in_carriersearch_nphy(pi, false);
19652}
19653
19654static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset)
19655{
19656 u16 lpf_bw_ctl_val = 0;
19657 u16 rx2tx_lpf_rc_lut_offset = 0;
19658
19659 if (offset == 0) {
19660 if (CHSPEC_IS40(pi->radio_chanspec)) {
19661 rx2tx_lpf_rc_lut_offset = 0x159;
19662 } else {
19663 rx2tx_lpf_rc_lut_offset = 0x154;
19664 }
19665 } else {
19666 rx2tx_lpf_rc_lut_offset = offset;
19667 }
19668 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
19669 (u32) rx2tx_lpf_rc_lut_offset, 16,
19670 &lpf_bw_ctl_val);
19671
19672 lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7;
19673
19674 return lpf_bw_ctl_val;
19675}
19676
19677static void
19678wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value,
19679 u8 core_mask, u8 off, u8 override_id)
19680{
19681 u8 core_num;
19682 u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0;
19683 u8 val_shift = 0;
19684
19685 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
19686 en_mask = field;
19687 for (core_num = 0; core_num < 2; core_num++) {
19688 if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) {
19689
19690 switch (field) {
19691 case (0x1 << 2):
19692 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19693 val_addr = (core_num == 0) ? 0x7a :
19694 0x7d;
19695 val_mask = (0x1 << 1);
19696 val_shift = 1;
19697 break;
19698 case (0x1 << 3):
19699 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19700 val_addr = (core_num == 0) ? 0x7a :
19701 0x7d;
19702 val_mask = (0x1 << 2);
19703 val_shift = 2;
19704 break;
19705 case (0x1 << 4):
19706 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19707 val_addr = (core_num == 0) ? 0x7a :
19708 0x7d;
19709 val_mask = (0x1 << 4);
19710 val_shift = 4;
19711 break;
19712 case (0x1 << 5):
19713 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19714 val_addr = (core_num == 0) ? 0x7a :
19715 0x7d;
19716 val_mask = (0x1 << 5);
19717 val_shift = 5;
19718 break;
19719 case (0x1 << 6):
19720 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19721 val_addr = (core_num == 0) ? 0x7a :
19722 0x7d;
19723 val_mask = (0x1 << 6);
19724 val_shift = 6;
19725 break;
19726 case (0x1 << 7):
19727 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19728 val_addr = (core_num == 0) ? 0x7a :
19729 0x7d;
19730 val_mask = (0x1 << 7);
19731 val_shift = 7;
19732 break;
19733 case (0x1 << 10):
19734 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19735 val_addr = (core_num == 0) ? 0xf8 :
19736 0xfa;
19737 val_mask = (0x7 << 4);
19738 val_shift = 4;
19739 break;
19740 case (0x1 << 11):
19741 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19742 val_addr = (core_num == 0) ? 0x7b :
19743 0x7e;
19744 val_mask = (0xffff << 0);
19745 val_shift = 0;
19746 break;
19747 case (0x1 << 12):
19748 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19749 val_addr = (core_num == 0) ? 0x7c :
19750 0x7f;
19751 val_mask = (0xffff << 0);
19752 val_shift = 0;
19753 break;
19754 case (0x3 << 13):
19755 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19756 val_addr = (core_num == 0) ? 0x348 :
19757 0x349;
19758 val_mask = (0xff << 0);
19759 val_shift = 0;
19760 break;
19761 case (0x1 << 13):
19762 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19763 val_addr = (core_num == 0) ? 0x348 :
19764 0x349;
19765 val_mask = (0xf << 0);
19766 val_shift = 0;
19767 break;
19768 default:
19769 addr = 0xffff;
19770 break;
19771 }
19772 } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID1) {
19773
19774 switch (field) {
19775 case (0x1 << 1):
19776 en_addr = (core_num == 0) ? 0x342 :
19777 0x343;
19778 val_addr = (core_num == 0) ? 0x340 :
19779 0x341;
19780 val_mask = (0x1 << 1);
19781 val_shift = 1;
19782 break;
19783 case (0x1 << 3):
19784 en_addr = (core_num == 0) ? 0x342 :
19785 0x343;
19786 val_addr = (core_num == 0) ? 0x340 :
19787 0x341;
19788 val_mask = (0x1 << 3);
19789 val_shift = 3;
19790 break;
19791 case (0x1 << 5):
19792 en_addr = (core_num == 0) ? 0x342 :
19793 0x343;
19794 val_addr = (core_num == 0) ? 0x340 :
19795 0x341;
19796 val_mask = (0x1 << 5);
19797 val_shift = 5;
19798 break;
19799 case (0x1 << 4):
19800 en_addr = (core_num == 0) ? 0x342 :
19801 0x343;
19802 val_addr = (core_num == 0) ? 0x340 :
19803 0x341;
19804 val_mask = (0x1 << 4);
19805 val_shift = 4;
19806 break;
19807 case (0x1 << 2):
19808
19809 en_addr = (core_num == 0) ? 0x342 :
19810 0x343;
19811 val_addr = (core_num == 0) ? 0x340 :
19812 0x341;
19813 val_mask = (0x1 << 2);
19814 val_shift = 2;
19815 break;
19816 case (0x1 << 7):
19817
19818 en_addr = (core_num == 0) ? 0x342 :
19819 0x343;
19820 val_addr = (core_num == 0) ? 0x340 :
19821 0x341;
19822 val_mask = (0x7 << 8);
19823 val_shift = 8;
19824 break;
19825 case (0x1 << 11):
19826 en_addr = (core_num == 0) ? 0x342 :
19827 0x343;
19828 val_addr = (core_num == 0) ? 0x340 :
19829 0x341;
19830 val_mask = (0x1 << 14);
19831 val_shift = 14;
19832 break;
19833 case (0x1 << 10):
19834 en_addr = (core_num == 0) ? 0x342 :
19835 0x343;
19836 val_addr = (core_num == 0) ? 0x340 :
19837 0x341;
19838 val_mask = (0x1 << 13);
19839 val_shift = 13;
19840 break;
19841 case (0x1 << 9):
19842 en_addr = (core_num == 0) ? 0x342 :
19843 0x343;
19844 val_addr = (core_num == 0) ? 0x340 :
19845 0x341;
19846 val_mask = (0x1 << 12);
19847 val_shift = 12;
19848 break;
19849 case (0x1 << 8):
19850 en_addr = (core_num == 0) ? 0x342 :
19851 0x343;
19852 val_addr = (core_num == 0) ? 0x340 :
19853 0x341;
19854 val_mask = (0x1 << 11);
19855 val_shift = 11;
19856 break;
19857 case (0x1 << 6):
19858 en_addr = (core_num == 0) ? 0x342 :
19859 0x343;
19860 val_addr = (core_num == 0) ? 0x340 :
19861 0x341;
19862 val_mask = (0x1 << 6);
19863 val_shift = 6;
19864 break;
19865 case (0x1 << 0):
19866 en_addr = (core_num == 0) ? 0x342 :
19867 0x343;
19868 val_addr = (core_num == 0) ? 0x340 :
19869 0x341;
19870 val_mask = (0x1 << 0);
19871 val_shift = 0;
19872 break;
19873 default:
19874 addr = 0xffff;
19875 break;
19876 }
19877 } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID2) {
19878
19879 switch (field) {
19880 case (0x1 << 3):
19881 en_addr = (core_num == 0) ? 0x346 :
19882 0x347;
19883 val_addr = (core_num == 0) ? 0x344 :
19884 0x345;
19885 val_mask = (0x1 << 3);
19886 val_shift = 3;
19887 break;
19888 case (0x1 << 1):
19889 en_addr = (core_num == 0) ? 0x346 :
19890 0x347;
19891 val_addr = (core_num == 0) ? 0x344 :
19892 0x345;
19893 val_mask = (0x1 << 1);
19894 val_shift = 1;
19895 break;
19896 case (0x1 << 0):
19897 en_addr = (core_num == 0) ? 0x346 :
19898 0x347;
19899 val_addr = (core_num == 0) ? 0x344 :
19900 0x345;
19901 val_mask = (0x1 << 0);
19902 val_shift = 0;
19903 break;
19904 case (0x1 << 2):
19905 en_addr = (core_num == 0) ? 0x346 :
19906 0x347;
19907 val_addr = (core_num == 0) ? 0x344 :
19908 0x345;
19909 val_mask = (0x1 << 2);
19910 val_shift = 2;
19911 break;
19912 case (0x1 << 4):
19913 en_addr = (core_num == 0) ? 0x346 :
19914 0x347;
19915 val_addr = (core_num == 0) ? 0x344 :
19916 0x345;
19917 val_mask = (0x1 << 4);
19918 val_shift = 4;
19919 break;
19920 default:
19921 addr = 0xffff;
19922 break;
19923 }
19924 }
19925
19926 if (off) {
19927 and_phy_reg(pi, en_addr, ~en_mask);
19928 and_phy_reg(pi, val_addr, ~val_mask);
19929 } else {
19930
19931 if ((core_mask == 0)
19932 || (core_mask & (1 << core_num))) {
19933 or_phy_reg(pi, en_addr, en_mask);
19934
19935 if (addr != 0xffff) {
19936 mod_phy_reg(pi, val_addr,
19937 val_mask,
19938 (value <<
19939 val_shift));
19940 }
19941 }
19942 }
19943 }
19944 }
19945}
19946
19947static void
19948wlc_phy_rfctrl_override_nphy(struct brcms_phy *pi, u16 field, u16 value,
19949 u8 core_mask, u8 off)
19950{
19951 u8 core_num;
19952 u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask =
19953 0, val_mask = 0;
19954 u8 shift = 0, val_shift = 0;
19955
19956 if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
19957
19958 en_mask = field;
19959 for (core_num = 0; core_num < 2; core_num++) {
19960
19961 switch (field) {
19962 case (0x1 << 1):
19963 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19964 val_addr = (core_num == 0) ? 0x7a : 0x7d;
19965 val_mask = (0x1 << 0);
19966 val_shift = 0;
19967 break;
19968 case (0x1 << 2):
19969 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19970 val_addr = (core_num == 0) ? 0x7a : 0x7d;
19971 val_mask = (0x1 << 1);
19972 val_shift = 1;
19973 break;
19974 case (0x1 << 3):
19975 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19976 val_addr = (core_num == 0) ? 0x7a : 0x7d;
19977 val_mask = (0x1 << 2);
19978 val_shift = 2;
19979 break;
19980 case (0x1 << 4):
19981 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19982 val_addr = (core_num == 0) ? 0x7a : 0x7d;
19983 val_mask = (0x1 << 4);
19984 val_shift = 4;
19985 break;
19986 case (0x1 << 5):
19987 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19988 val_addr = (core_num == 0) ? 0x7a : 0x7d;
19989 val_mask = (0x1 << 5);
19990 val_shift = 5;
19991 break;
19992 case (0x1 << 6):
19993 en_addr = (core_num == 0) ? 0xe7 : 0xec;
19994 val_addr = (core_num == 0) ? 0x7a : 0x7d;
19995 val_mask = (0x1 << 6);
19996 val_shift = 6;
19997 break;
19998 case (0x1 << 7):
19999 en_addr = (core_num == 0) ? 0xe7 : 0xec;
20000 val_addr = (core_num == 0) ? 0x7a : 0x7d;
20001 val_mask = (0x1 << 7);
20002 val_shift = 7;
20003 break;
20004 case (0x1 << 8):
20005 en_addr = (core_num == 0) ? 0xe7 : 0xec;
20006 val_addr = (core_num == 0) ? 0x7a : 0x7d;
20007 val_mask = (0x7 << 8);
20008 val_shift = 8;
20009 break;
20010 case (0x1 << 11):
20011 en_addr = (core_num == 0) ? 0xe7 : 0xec;
20012 val_addr = (core_num == 0) ? 0x7a : 0x7d;
20013 val_mask = (0x7 << 13);
20014 val_shift = 13;
20015 break;
20016
20017 case (0x1 << 9):
20018 en_addr = (core_num == 0) ? 0xe7 : 0xec;
20019 val_addr = (core_num == 0) ? 0xf8 : 0xfa;
20020 val_mask = (0x7 << 0);
20021 val_shift = 0;
20022 break;
20023
20024 case (0x1 << 10):
20025 en_addr = (core_num == 0) ? 0xe7 : 0xec;
20026 val_addr = (core_num == 0) ? 0xf8 : 0xfa;
20027 val_mask = (0x7 << 4);
20028 val_shift = 4;
20029 break;
20030
20031 case (0x1 << 12):
20032 en_addr = (core_num == 0) ? 0xe7 : 0xec;
20033 val_addr = (core_num == 0) ? 0x7b : 0x7e;
20034 val_mask = (0xffff << 0);
20035 val_shift = 0;
20036 break;
20037 case (0x1 << 13):
20038 en_addr = (core_num == 0) ? 0xe7 : 0xec;
20039 val_addr = (core_num == 0) ? 0x7c : 0x7f;
20040 val_mask = (0xffff << 0);
20041 val_shift = 0;
20042 break;
20043 case (0x1 << 14):
20044 en_addr = (core_num == 0) ? 0xe7 : 0xec;
20045 val_addr = (core_num == 0) ? 0xf9 : 0xfb;
20046 val_mask = (0x3 << 6);
20047 val_shift = 6;
20048 break;
20049 case (0x1 << 0):
20050 en_addr = (core_num == 0) ? 0xe5 : 0xe6;
20051 val_addr = (core_num == 0) ? 0xf9 : 0xfb;
20052 val_mask = (0x1 << 15);
20053 val_shift = 15;
20054 break;
20055 default:
20056 addr = 0xffff;
20057 break;
20058 }
20059
20060 if (off) {
20061 and_phy_reg(pi, en_addr, ~en_mask);
20062 and_phy_reg(pi, val_addr, ~val_mask);
20063 } else {
20064
20065 if ((core_mask == 0)
20066 || (core_mask & (1 << core_num))) {
20067 or_phy_reg(pi, en_addr, en_mask);
20068
20069 if (addr != 0xffff) {
20070 mod_phy_reg(pi, val_addr,
20071 val_mask,
20072 (value <<
20073 val_shift));
20074 }
20075 }
20076 }
20077 }
20078 } else {
20079
20080 if (off) {
20081 and_phy_reg(pi, 0xec, ~field);
20082 value = 0x0;
20083 } else {
20084 or_phy_reg(pi, 0xec, field);
20085 }
20086
20087 for (core_num = 0; core_num < 2; core_num++) {
20088
20089 switch (field) {
20090 case (0x1 << 1):
20091 case (0x1 << 9):
20092 case (0x1 << 12):
20093 case (0x1 << 13):
20094 case (0x1 << 14):
20095 addr = 0x78;
20096
20097 core_mask = 0x1;
20098 break;
20099 case (0x1 << 2):
20100 case (0x1 << 3):
20101 case (0x1 << 4):
20102 case (0x1 << 5):
20103 case (0x1 << 6):
20104 case (0x1 << 7):
20105 case (0x1 << 8):
20106 addr = (core_num == 0) ? 0x7a : 0x7d;
20107 break;
20108 case (0x1 << 10):
20109 addr = (core_num == 0) ? 0x7b : 0x7e;
20110 break;
20111 case (0x1 << 11):
20112 addr = (core_num == 0) ? 0x7c : 0x7f;
20113 break;
20114 default:
20115 addr = 0xffff;
20116 }
20117
20118 switch (field) {
20119 case (0x1 << 1):
20120 mask = (0x7 << 3);
20121 shift = 3;
20122 break;
20123 case (0x1 << 9):
20124 mask = (0x1 << 2);
20125 shift = 2;
20126 break;
20127 case (0x1 << 12):
20128 mask = (0x1 << 8);
20129 shift = 8;
20130 break;
20131 case (0x1 << 13):
20132 mask = (0x1 << 9);
20133 shift = 9;
20134 break;
20135 case (0x1 << 14):
20136 mask = (0xf << 12);
20137 shift = 12;
20138 break;
20139 case (0x1 << 2):
20140 mask = (0x1 << 0);
20141 shift = 0;
20142 break;
20143 case (0x1 << 3):
20144 mask = (0x1 << 1);
20145 shift = 1;
20146 break;
20147 case (0x1 << 4):
20148 mask = (0x1 << 2);
20149 shift = 2;
20150 break;
20151 case (0x1 << 5):
20152 mask = (0x3 << 4);
20153 shift = 4;
20154 break;
20155 case (0x1 << 6):
20156 mask = (0x3 << 6);
20157 shift = 6;
20158 break;
20159 case (0x1 << 7):
20160 mask = (0x1 << 8);
20161 shift = 8;
20162 break;
20163 case (0x1 << 8):
20164 mask = (0x1 << 9);
20165 shift = 9;
20166 break;
20167 case (0x1 << 10):
20168 mask = 0x1fff;
20169 shift = 0x0;
20170 break;
20171 case (0x1 << 11):
20172 mask = 0x1fff;
20173 shift = 0x0;
20174 break;
20175 default:
20176 mask = 0x0;
20177 shift = 0x0;
20178 break;
20179 }
20180
20181 if ((addr != 0xffff) && (core_mask & (1 << core_num))) {
20182 mod_phy_reg(pi, addr, mask, (value << shift));
20183 }
20184 }
20185
20186 or_phy_reg(pi, 0xec, (0x1 << 0));
20187 or_phy_reg(pi, 0x78, (0x1 << 0));
20188 udelay(1);
20189 and_phy_reg(pi, 0xec, ~(0x1 << 0));
20190 }
20191}
20192
20193static void
20194wlc_phy_rfctrl_override_1tomany_nphy(struct brcms_phy *pi, u16 cmd, u16 value,
20195 u8 core_mask, u8 off)
20196{
20197 u16 rfmxgain = 0, lpfgain = 0;
20198 u16 tgain = 0;
20199
20200 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
20201
20202 switch (cmd) {
20203 case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu:
20204 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
20205 value, core_mask, off,
20206 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20207 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), value,
20208 core_mask, off,
20209 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20210 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), value,
20211 core_mask, off,
20212 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20213 break;
20214 case NPHY_REV7_RfctrlOverride_cmd_rx_pu:
20215 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
20216 value, core_mask, off,
20217 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20218 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
20219 core_mask, off,
20220 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20221 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value,
20222 core_mask, off,
20223 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20224 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
20225 core_mask, off,
20226 NPHY_REV7_RFCTRLOVERRIDE_ID2);
20227 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0,
20228 core_mask, off,
20229 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20230 break;
20231 case NPHY_REV7_RfctrlOverride_cmd_tx_pu:
20232 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
20233 value, core_mask, off,
20234 NPHY_REV7_RFCTRLOVERRIDE_ID0);
20235 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
20236 core_mask, off,
20237 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20238 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value,
20239 core_mask, off,
20240 NPHY_REV7_RFCTRLOVERRIDE_ID2);
20241 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), value,
20242 core_mask, off,
20243 NPHY_REV7_RFCTRLOVERRIDE_ID2);
20244 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1,
20245 core_mask, off,
20246 NPHY_REV7_RFCTRLOVERRIDE_ID1);
20247 break;
20248 case NPHY_REV7_RfctrlOverride_cmd_rxgain:
20249 rfmxgain = value & 0x000ff;
20250 lpfgain = value & 0x0ff00;
20251 lpfgain = lpfgain >> 8;
20252
20253 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
20254 rfmxgain, core_mask,
20255 off,
20256 NPHY_REV7_RFCTRLOVERRIDE_ID0);
20257 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x3 << 13),
20258 lpfgain, core_mask,
20259 off,
20260 NPHY_REV7_RFCTRLOVERRIDE_ID0);
20261 break;
20262 case NPHY_REV7_RfctrlOverride_cmd_txgain:
20263 tgain = value & 0x7fff;
20264 lpfgain = value & 0x8000;
20265 lpfgain = lpfgain >> 14;
20266
20267 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
20268 tgain, core_mask, off,
20269 NPHY_REV7_RFCTRLOVERRIDE_ID0);
20270 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 13),
20271 lpfgain, core_mask,
20272 off,
20273 NPHY_REV7_RFCTRLOVERRIDE_ID0);
20274 break;
20275 }
20276 }
20277}
20278
20279static void
20280wlc_phy_scale_offset_rssi_nphy(struct brcms_phy *pi, u16 scale, s8 offset,
20281 u8 coresel, u8 rail, u8 rssi_type)
20282{
20283 u16 valuetostuff;
20284
20285 offset = (offset > NPHY_RSSICAL_MAXREAD) ?
20286 NPHY_RSSICAL_MAXREAD : offset;
20287 offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ?
20288 -NPHY_RSSICAL_MAXREAD - 1 : offset;
20289
20290 valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f);
20291
20292 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20293 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20294 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) {
20295 write_phy_reg(pi, 0x1a6, valuetostuff);
20296 }
20297 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20298 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20299 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) {
20300 write_phy_reg(pi, 0x1ac, valuetostuff);
20301 }
20302 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20303 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20304 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) {
20305 write_phy_reg(pi, 0x1b2, valuetostuff);
20306 }
20307 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20308 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20309 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) {
20310 write_phy_reg(pi, 0x1b8, valuetostuff);
20311 }
20312
20313 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20314 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20315 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) {
20316 write_phy_reg(pi, 0x1a4, valuetostuff);
20317 }
20318 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20319 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20320 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) {
20321 write_phy_reg(pi, 0x1aa, valuetostuff);
20322 }
20323 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20324 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20325 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) {
20326 write_phy_reg(pi, 0x1b0, valuetostuff);
20327 }
20328 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20329 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20330 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) {
20331 write_phy_reg(pi, 0x1b6, valuetostuff);
20332 }
20333
20334 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20335 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20336 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) {
20337 write_phy_reg(pi, 0x1a5, valuetostuff);
20338 }
20339 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20340 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20341 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) {
20342 write_phy_reg(pi, 0x1ab, valuetostuff);
20343 }
20344 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20345 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20346 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) {
20347 write_phy_reg(pi, 0x1b1, valuetostuff);
20348 }
20349 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20350 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20351 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) {
20352 write_phy_reg(pi, 0x1b7, valuetostuff);
20353 }
20354
20355 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20356 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20357 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
20358 write_phy_reg(pi, 0x1a7, valuetostuff);
20359 }
20360 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20361 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20362 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
20363 write_phy_reg(pi, 0x1ad, valuetostuff);
20364 }
20365 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20366 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20367 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
20368 write_phy_reg(pi, 0x1b3, valuetostuff);
20369 }
20370 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20371 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20372 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
20373 write_phy_reg(pi, 0x1b9, valuetostuff);
20374 }
20375
20376 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20377 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20378 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
20379 write_phy_reg(pi, 0x1a8, valuetostuff);
20380 }
20381 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20382 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20383 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
20384 write_phy_reg(pi, 0x1ae, valuetostuff);
20385 }
20386 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20387 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20388 (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
20389 write_phy_reg(pi, 0x1b4, valuetostuff);
20390 }
20391 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20392 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20393 (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
20394 write_phy_reg(pi, 0x1ba, valuetostuff);
20395 }
20396
20397 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20398 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20399 (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) {
20400 write_phy_reg(pi, 0x1a9, valuetostuff);
20401 }
20402 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20403 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20404 (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) {
20405 write_phy_reg(pi, 0x1b5, valuetostuff);
20406 }
20407
20408 if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
20409 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20410 (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) {
20411 write_phy_reg(pi, 0x1af, valuetostuff);
20412 }
20413 if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
20414 (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
20415 (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) {
20416 write_phy_reg(pi, 0x1bb, valuetostuff);
20417 }
20418}
20419
20420void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type)
20421{
20422 u16 mask, val;
20423 u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val,
20424 startseq;
20425 u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val,
20426 rfctrlovr_trigger_val;
20427 u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask;
20428 u16 rfctrlcmd_val, rfctrlovr_val;
20429 u8 core;
20430
20431 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
20432 if (core_code == RADIO_MIMO_CORESEL_OFF) {
20433 mod_phy_reg(pi, 0x8f, (0x1 << 9), 0);
20434 mod_phy_reg(pi, 0xa5, (0x1 << 9), 0);
20435
20436 mod_phy_reg(pi, 0xa6, (0x3 << 8), 0);
20437 mod_phy_reg(pi, 0xa7, (0x3 << 8), 0);
20438
20439 mod_phy_reg(pi, 0xe5, (0x1 << 5), 0);
20440 mod_phy_reg(pi, 0xe6, (0x1 << 5), 0);
20441
20442 mask = (0x1 << 2) |
20443 (0x1 << 3) | (0x1 << 4) | (0x1 << 5);
20444 mod_phy_reg(pi, 0xf9, mask, 0);
20445 mod_phy_reg(pi, 0xfb, mask, 0);
20446
20447 } else {
20448 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
20449 if (core_code == RADIO_MIMO_CORESEL_CORE1
20450 && core == PHY_CORE_1)
20451 continue;
20452 else if (core_code == RADIO_MIMO_CORESEL_CORE2
20453 && core == PHY_CORE_0)
20454 continue;
20455
20456 mod_phy_reg(pi, (core == PHY_CORE_0) ?
20457 0x8f : 0xa5, (0x1 << 9), 1 << 9);
20458
20459 if (rssi_type == NPHY_RSSI_SEL_W1 ||
20460 rssi_type == NPHY_RSSI_SEL_W2 ||
20461 rssi_type == NPHY_RSSI_SEL_NB) {
20462
20463 mod_phy_reg(pi,
20464 (core ==
20465 PHY_CORE_0) ? 0xa6 : 0xa7,
20466 (0x3 << 8), 0);
20467
20468 mask = (0x1 << 2) |
20469 (0x1 << 3) |
20470 (0x1 << 4) | (0x1 << 5);
20471 mod_phy_reg(pi,
20472 (core ==
20473 PHY_CORE_0) ? 0xf9 : 0xfb,
20474 mask, 0);
20475
20476 if (rssi_type == NPHY_RSSI_SEL_W1) {
20477 if (CHSPEC_IS5G
20478 (pi->radio_chanspec)) {
20479 mask = (0x1 << 2);
20480 val = 1 << 2;
20481 } else {
20482 mask = (0x1 << 3);
20483 val = 1 << 3;
20484 }
20485 } else if (rssi_type ==
20486 NPHY_RSSI_SEL_W2) {
20487 mask = (0x1 << 4);
20488 val = 1 << 4;
20489 } else {
20490 mask = (0x1 << 5);
20491 val = 1 << 5;
20492 }
20493 mod_phy_reg(pi,
20494 (core ==
20495 PHY_CORE_0) ? 0xf9 : 0xfb,
20496 mask, val);
20497
20498 mask = (0x1 << 5);
20499 val = 1 << 5;
20500 mod_phy_reg(pi, (core == PHY_CORE_0) ?
20501 0xe5 : 0xe6, mask, val);
20502 } else {
20503 if (rssi_type == NPHY_RSSI_SEL_TBD) {
20504
20505 mask = (0x3 << 8);
20506 val = 1 << 8;
20507 mod_phy_reg(pi,
20508 (core ==
20509 PHY_CORE_0) ? 0xa6
20510 : 0xa7, mask, val);
20511 mask = (0x3 << 10);
20512 val = 1 << 10;
20513 mod_phy_reg(pi,
20514 (core ==
20515 PHY_CORE_0) ? 0xa6
20516 : 0xa7, mask, val);
20517 } else if (rssi_type ==
20518 NPHY_RSSI_SEL_IQ) {
20519
20520 mask = (0x3 << 8);
20521 val = 2 << 8;
20522 mod_phy_reg(pi,
20523 (core ==
20524 PHY_CORE_0) ? 0xa6
20525 : 0xa7, mask, val);
20526 mask = (0x3 << 10);
20527 val = 2 << 10;
20528 mod_phy_reg(pi,
20529 (core ==
20530 PHY_CORE_0) ? 0xa6
20531 : 0xa7, mask, val);
20532 } else {
20533
20534 mask = (0x3 << 8);
20535 val = 3 << 8;
20536 mod_phy_reg(pi,
20537 (core ==
20538 PHY_CORE_0) ? 0xa6
20539 : 0xa7, mask, val);
20540 mask = (0x3 << 10);
20541 val = 3 << 10;
20542 mod_phy_reg(pi,
20543 (core ==
20544 PHY_CORE_0) ? 0xa6
20545 : 0xa7, mask, val);
20546
20547 if (PHY_IPA(pi)) {
20548 if (NREV_GE
20549 (pi->pubpi.phy_rev,
20550 7)) {
20551
20552 write_radio_reg
20553 (pi,
20554 ((core ==
20555 PHY_CORE_0)
20556 ?
20557 RADIO_2057_TX0_TX_SSI_MUX
20558 :
20559 RADIO_2057_TX1_TX_SSI_MUX),
20560 (CHSPEC_IS5G
20561 (pi->
20562 radio_chanspec)
20563 ? 0xc :
20564 0xe));
20565 } else {
20566 write_radio_reg
20567 (pi,
20568 RADIO_2056_TX_TX_SSI_MUX
20569 |
20570 ((core ==
20571 PHY_CORE_0)
20572 ?
20573 RADIO_2056_TX0
20574 :
20575 RADIO_2056_TX1),
20576 (CHSPEC_IS5G
20577 (pi->
20578 radio_chanspec)
20579 ? 0xc :
20580 0xe));
20581 }
20582 } else {
20583
20584 if (NREV_GE
20585 (pi->pubpi.phy_rev,
20586 7)) {
20587 write_radio_reg
20588 (pi,
20589 ((core ==
20590 PHY_CORE_0)
20591 ?
20592 RADIO_2057_TX0_TX_SSI_MUX
20593 :
20594 RADIO_2057_TX1_TX_SSI_MUX),
20595 0x11);
20596
20597 if (pi->pubpi.
20598 radioid ==
20599 BCM2057_ID)
20600 write_radio_reg
20601 (pi,
20602 RADIO_2057_IQTEST_SEL_PU,
20603 0x1);
20604
20605 } else {
20606 write_radio_reg
20607 (pi,
20608 RADIO_2056_TX_TX_SSI_MUX
20609 |
20610 ((core ==
20611 PHY_CORE_0)
20612 ?
20613 RADIO_2056_TX0
20614 :
20615 RADIO_2056_TX1),
20616 0x11);
20617 }
20618 }
20619
20620 afectrlovr_rssi_val = 1 << 9;
20621 mod_phy_reg(pi,
20622 (core ==
20623 PHY_CORE_0) ? 0x8f
20624 : 0xa5, (0x1 << 9),
20625 afectrlovr_rssi_val);
20626 }
20627 }
20628 }
20629 }
20630 } else {
20631
20632 if ((rssi_type == NPHY_RSSI_SEL_W1) ||
20633 (rssi_type == NPHY_RSSI_SEL_W2) ||
20634 (rssi_type == NPHY_RSSI_SEL_NB)) {
20635
20636 val = 0x0;
20637 } else if (rssi_type == NPHY_RSSI_SEL_TBD) {
20638
20639 val = 0x1;
20640 } else if (rssi_type == NPHY_RSSI_SEL_IQ) {
20641
20642 val = 0x2;
20643 } else {
20644
20645 val = 0x3;
20646 }
20647 mask = ((0x3 << 12) | (0x3 << 14));
20648 val = (val << 12) | (val << 14);
20649 mod_phy_reg(pi, 0xa6, mask, val);
20650 mod_phy_reg(pi, 0xa7, mask, val);
20651
20652 if ((rssi_type == NPHY_RSSI_SEL_W1) ||
20653 (rssi_type == NPHY_RSSI_SEL_W2) ||
20654 (rssi_type == NPHY_RSSI_SEL_NB)) {
20655 if (rssi_type == NPHY_RSSI_SEL_W1) {
20656 val = 0x1;
20657 }
20658 if (rssi_type == NPHY_RSSI_SEL_W2) {
20659 val = 0x2;
20660 }
20661 if (rssi_type == NPHY_RSSI_SEL_NB) {
20662 val = 0x3;
20663 }
20664 mask = (0x3 << 4);
20665 val = (val << 4);
20666 mod_phy_reg(pi, 0x7a, mask, val);
20667 mod_phy_reg(pi, 0x7d, mask, val);
20668 }
20669
20670 if (core_code == RADIO_MIMO_CORESEL_OFF) {
20671 afectrlovr_rssi_val = 0;
20672 rfctrlcmd_rxen_val = 0;
20673 rfctrlcmd_coresel_val = 0;
20674 rfctrlovr_rssi_val = 0;
20675 rfctrlovr_rxen_val = 0;
20676 rfctrlovr_coresel_val = 0;
20677 rfctrlovr_trigger_val = 0;
20678 startseq = 0;
20679 } else {
20680 afectrlovr_rssi_val = 1;
20681 rfctrlcmd_rxen_val = 1;
20682 rfctrlcmd_coresel_val = core_code;
20683 rfctrlovr_rssi_val = 1;
20684 rfctrlovr_rxen_val = 1;
20685 rfctrlovr_coresel_val = 1;
20686 rfctrlovr_trigger_val = 1;
20687 startseq = 1;
20688 }
20689
20690 afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13));
20691 afectrlovr_rssi_val = (afectrlovr_rssi_val <<
20692 12) | (afectrlovr_rssi_val << 13);
20693 mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask,
20694 afectrlovr_rssi_val);
20695
20696 if ((rssi_type == NPHY_RSSI_SEL_W1) ||
20697 (rssi_type == NPHY_RSSI_SEL_W2) ||
20698 (rssi_type == NPHY_RSSI_SEL_NB)) {
20699 rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3));
20700 rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) |
20701 (rfctrlcmd_coresel_val << 3);
20702
20703 rfctrlovr_mask = ((0x1 << 5) |
20704 (0x1 << 12) |
20705 (0x1 << 1) | (0x1 << 0));
20706 rfctrlovr_val = (rfctrlovr_rssi_val <<
20707 5) |
20708 (rfctrlovr_rxen_val << 12) |
20709 (rfctrlovr_coresel_val << 1) |
20710 (rfctrlovr_trigger_val << 0);
20711
20712 mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val);
20713 mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val);
20714
20715 mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0));
20716 udelay(20);
20717
20718 mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
20719 }
20720 }
20721}
20722
20723int
20724wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf,
20725 u8 nsamps)
20726{
20727 s16 rssi0, rssi1;
20728 u16 afectrlCore1_save = 0;
20729 u16 afectrlCore2_save = 0;
20730 u16 afectrlOverride1_save = 0;
20731 u16 afectrlOverride2_save = 0;
20732 u16 rfctrlOverrideAux0_save = 0;
20733 u16 rfctrlOverrideAux1_save = 0;
20734 u16 rfctrlMiscReg1_save = 0;
20735 u16 rfctrlMiscReg2_save = 0;
20736 u16 rfctrlcmd_save = 0;
20737 u16 rfctrloverride_save = 0;
20738 u16 rfctrlrssiothers1_save = 0;
20739 u16 rfctrlrssiothers2_save = 0;
20740 s8 tmp_buf[4];
20741 u8 ctr = 0, samp = 0;
20742 s32 rssi_out_val;
20743 u16 gpiosel_orig;
20744
20745 afectrlCore1_save = read_phy_reg(pi, 0xa6);
20746 afectrlCore2_save = read_phy_reg(pi, 0xa7);
20747 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
20748 rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
20749 rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
20750 afectrlOverride1_save = read_phy_reg(pi, 0x8f);
20751 afectrlOverride2_save = read_phy_reg(pi, 0xa5);
20752 rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
20753 rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
20754 } else {
20755 afectrlOverride1_save = read_phy_reg(pi, 0xa5);
20756 rfctrlcmd_save = read_phy_reg(pi, 0x78);
20757 rfctrloverride_save = read_phy_reg(pi, 0xec);
20758 rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a);
20759 rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d);
20760 }
20761
20762 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
20763
20764 gpiosel_orig = read_phy_reg(pi, 0xca);
20765 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
20766 write_phy_reg(pi, 0xca, 5);
20767 }
20768
20769 for (ctr = 0; ctr < 4; ctr++) {
20770 rssi_buf[ctr] = 0;
20771 }
20772
20773 for (samp = 0; samp < nsamps; samp++) {
20774 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
20775 rssi0 = read_phy_reg(pi, 0x1c9);
20776 rssi1 = read_phy_reg(pi, 0x1ca);
20777 } else {
20778 rssi0 = read_phy_reg(pi, 0x219);
20779 rssi1 = read_phy_reg(pi, 0x21a);
20780 }
20781
20782 ctr = 0;
20783 tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2;
20784 tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2;
20785 tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2;
20786 tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2;
20787
20788 for (ctr = 0; ctr < 4; ctr++) {
20789 rssi_buf[ctr] += tmp_buf[ctr];
20790 }
20791
20792 }
20793
20794 rssi_out_val = rssi_buf[3] & 0xff;
20795 rssi_out_val |= (rssi_buf[2] & 0xff) << 8;
20796 rssi_out_val |= (rssi_buf[1] & 0xff) << 16;
20797 rssi_out_val |= (rssi_buf[0] & 0xff) << 24;
20798
20799 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
20800 write_phy_reg(pi, 0xca, gpiosel_orig);
20801 }
20802
20803 write_phy_reg(pi, 0xa6, afectrlCore1_save);
20804 write_phy_reg(pi, 0xa7, afectrlCore2_save);
20805 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
20806 write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save);
20807 write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save);
20808 write_phy_reg(pi, 0x8f, afectrlOverride1_save);
20809 write_phy_reg(pi, 0xa5, afectrlOverride2_save);
20810 write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save);
20811 write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save);
20812 } else {
20813 write_phy_reg(pi, 0xa5, afectrlOverride1_save);
20814 write_phy_reg(pi, 0x78, rfctrlcmd_save);
20815 write_phy_reg(pi, 0xec, rfctrloverride_save);
20816 write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save);
20817 write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save);
20818 }
20819
20820 return rssi_out_val;
20821}
20822
20823s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi)
20824{
20825 u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save;
20826 u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save;
20827 u16 pwrdet_rxtx_core1_save;
20828 u16 pwrdet_rxtx_core2_save;
20829 u16 afectrlCore1_save;
20830 u16 afectrlCore2_save;
20831 u16 afectrlOverride_save;
20832 u16 afectrlOverride2_save;
20833 u16 pd_pll_ts_save;
20834 u16 gpioSel_save;
20835 s32 radio_temp[4];
20836 s32 radio_temp2[4];
20837 u16 syn_tempprocsense_save;
20838 s16 offset = 0;
20839
20840 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
20841 u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save;
20842 u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save;
20843 u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH;
20844 s32 auxADC_Vl;
20845 u16 RfctrlOverride5_save, RfctrlOverride6_save;
20846 u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save;
20847 u16 RSSIMultCoef0QPowerDet_save;
20848 u16 tempsense_Rcal;
20849
20850 syn_tempprocsense_save =
20851 read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG);
20852
20853 afectrlCore1_save = read_phy_reg(pi, 0xa6);
20854 afectrlCore2_save = read_phy_reg(pi, 0xa7);
20855 afectrlOverride_save = read_phy_reg(pi, 0x8f);
20856 afectrlOverride2_save = read_phy_reg(pi, 0xa5);
20857 RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae);
20858 RfctrlOverride5_save = read_phy_reg(pi, 0x346);
20859 RfctrlOverride6_save = read_phy_reg(pi, 0x347);
20860 RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
20861 RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
20862
20863 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
20864 &auxADC_Vmid_save);
20865 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
20866 &auxADC_Av_save);
20867 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
20868 &auxADC_rssi_ctrlL_save);
20869 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
20870 &auxADC_rssi_ctrlH_save);
20871
20872 write_phy_reg(pi, 0x1ae, 0x0);
20873
20874 auxADC_rssi_ctrlL = 0x0;
20875 auxADC_rssi_ctrlH = 0x20;
20876 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
20877 &auxADC_rssi_ctrlL);
20878 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
20879 &auxADC_rssi_ctrlH);
20880
20881 tempsense_Rcal = syn_tempprocsense_save & 0x1c;
20882
20883 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
20884 tempsense_Rcal | 0x01);
20885
20886 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
20887 1, 0, 0,
20888 NPHY_REV7_RFCTRLOVERRIDE_ID2);
20889 mod_phy_reg(pi, 0xa6, (0x1 << 7), 0);
20890 mod_phy_reg(pi, 0xa7, (0x1 << 7), 0);
20891 mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7));
20892 mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7));
20893
20894 mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
20895 mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
20896 mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
20897 mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
20898 udelay(5);
20899 mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
20900 mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
20901 mod_phy_reg(pi, 0xa6, (0x1 << 3), 0);
20902 mod_phy_reg(pi, 0xa7, (0x1 << 3), 0);
20903 mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3));
20904 mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3));
20905 mod_phy_reg(pi, 0xa6, (0x1 << 6), 0);
20906 mod_phy_reg(pi, 0xa7, (0x1 << 6), 0);
20907 mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6));
20908 mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6));
20909
20910 auxADC_Vmid = 0xA3;
20911 auxADC_Av = 0x0;
20912 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
20913 &auxADC_Vmid);
20914 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
20915 &auxADC_Av);
20916
20917 udelay(3);
20918
20919 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
20920 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
20921 tempsense_Rcal | 0x03);
20922
20923 udelay(5);
20924 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
20925
20926 auxADC_Av = 0x7;
20927 if (radio_temp[1] + radio_temp2[1] < -30) {
20928 auxADC_Vmid = 0x45;
20929 auxADC_Vl = 263;
20930 } else if (radio_temp[1] + radio_temp2[1] < -9) {
20931 auxADC_Vmid = 0x200;
20932 auxADC_Vl = 467;
20933 } else if (radio_temp[1] + radio_temp2[1] < 11) {
20934 auxADC_Vmid = 0x266;
20935 auxADC_Vl = 634;
20936 } else {
20937 auxADC_Vmid = 0x2D5;
20938 auxADC_Vl = 816;
20939 }
20940
20941 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
20942 &auxADC_Vmid);
20943 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
20944 &auxADC_Av);
20945
20946 udelay(3);
20947
20948 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
20949 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
20950 tempsense_Rcal | 0x01);
20951
20952 udelay(5);
20953 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
20954
20955 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
20956 syn_tempprocsense_save);
20957
20958 write_phy_reg(pi, 0xa6, afectrlCore1_save);
20959 write_phy_reg(pi, 0xa7, afectrlCore2_save);
20960 write_phy_reg(pi, 0x8f, afectrlOverride_save);
20961 write_phy_reg(pi, 0xa5, afectrlOverride2_save);
20962 write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save);
20963 write_phy_reg(pi, 0x346, RfctrlOverride5_save);
20964 write_phy_reg(pi, 0x347, RfctrlOverride6_save);
20965 write_phy_reg(pi, 0x344, RfctrlMiscReg5_save);
20966 write_phy_reg(pi, 0x345, RfctrlMiscReg5_save);
20967
20968 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
20969 &auxADC_Vmid_save);
20970 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
20971 &auxADC_Av_save);
20972 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
20973 &auxADC_rssi_ctrlL_save);
20974 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
20975 &auxADC_rssi_ctrlH_save);
20976
20977 radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1])
20978 + 82 * (auxADC_Vl) - 28861 +
20979 128) / 256;
20980
20981 offset = (s16) pi->phy_tempsense_offset;
20982
20983 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
20984 syn_tempprocsense_save =
20985 read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE);
20986
20987 afectrlCore1_save = read_phy_reg(pi, 0xa6);
20988 afectrlCore2_save = read_phy_reg(pi, 0xa7);
20989 afectrlOverride_save = read_phy_reg(pi, 0x8f);
20990 afectrlOverride2_save = read_phy_reg(pi, 0xa5);
20991 gpioSel_save = read_phy_reg(pi, 0xca);
20992
20993 write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
20994
20995 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
20996 if (NREV_LT(pi->pubpi.phy_rev, 7))
20997 write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05);
20998
20999 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
21000 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21001 write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01);
21002 } else {
21003 write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
21004 }
21005
21006 radio_temp[0] =
21007 (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64;
21008
21009 write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE,
21010 syn_tempprocsense_save);
21011
21012 write_phy_reg(pi, 0xca, gpioSel_save);
21013 write_phy_reg(pi, 0xa6, afectrlCore1_save);
21014 write_phy_reg(pi, 0xa7, afectrlCore2_save);
21015 write_phy_reg(pi, 0x8f, afectrlOverride_save);
21016 write_phy_reg(pi, 0xa5, afectrlOverride2_save);
21017
21018 offset = (s16) pi->phy_tempsense_offset;
21019 } else {
21020
21021 pwrdet_rxtx_core1_save =
21022 read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
21023 pwrdet_rxtx_core2_save =
21024 read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
21025 core1_txrf_iqcal1_save =
21026 read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
21027 core1_txrf_iqcal2_save =
21028 read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
21029 core2_txrf_iqcal1_save =
21030 read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
21031 core2_txrf_iqcal2_save =
21032 read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
21033 pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS);
21034
21035 afectrlCore1_save = read_phy_reg(pi, 0xa6);
21036 afectrlCore2_save = read_phy_reg(pi, 0xa7);
21037 afectrlOverride_save = read_phy_reg(pi, 0xa5);
21038 gpioSel_save = read_phy_reg(pi, 0xca);
21039
21040 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01);
21041 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01);
21042 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08);
21043 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08);
21044 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
21045 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
21046 write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00);
21047
21048 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
21049 xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
21050
21051 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
21052 xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
21053
21054 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
21055 xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
21056
21057 radio_temp[0] = (radio_temp[0] + radio_temp2[0]);
21058 radio_temp[1] = (radio_temp[1] + radio_temp2[1]);
21059 radio_temp[2] = (radio_temp[2] + radio_temp2[2]);
21060 radio_temp[3] = (radio_temp[3] + radio_temp2[3]);
21061
21062 radio_temp[0] =
21063 (radio_temp[0] + radio_temp[1] + radio_temp[2] +
21064 radio_temp[3]);
21065
21066 radio_temp[0] =
21067 (radio_temp[0] + (8 * 32)) * (950 - 350) / 63 + (350 * 8);
21068
21069 radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38;
21070
21071 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
21072 pwrdet_rxtx_core1_save);
21073 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
21074 pwrdet_rxtx_core2_save);
21075 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
21076 core1_txrf_iqcal1_save);
21077 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
21078 core2_txrf_iqcal1_save);
21079 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
21080 core1_txrf_iqcal2_save);
21081 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
21082 core2_txrf_iqcal2_save);
21083 write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save);
21084
21085 write_phy_reg(pi, 0xca, gpioSel_save);
21086 write_phy_reg(pi, 0xa6, afectrlCore1_save);
21087 write_phy_reg(pi, 0xa7, afectrlCore2_save);
21088 write_phy_reg(pi, 0xa5, afectrlOverride_save);
21089 }
21090
21091 return (s16) radio_temp[0] + offset;
21092}
21093
21094static void
21095wlc_phy_set_rssi_2055_vcm(struct brcms_phy *pi, u8 rssi_type, u8 *vcm_buf)
21096{
21097 u8 core;
21098
21099 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
21100 if (rssi_type == NPHY_RSSI_SEL_NB) {
21101 if (core == PHY_CORE_0) {
21102 mod_radio_reg(pi,
21103 RADIO_2055_CORE1_B0_NBRSSI_VCM,
21104 RADIO_2055_NBRSSI_VCM_I_MASK,
21105 vcm_buf[2 *
21106 core] <<
21107 RADIO_2055_NBRSSI_VCM_I_SHIFT);
21108 mod_radio_reg(pi,
21109 RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
21110 RADIO_2055_NBRSSI_VCM_Q_MASK,
21111 vcm_buf[2 * core +
21112 1] <<
21113 RADIO_2055_NBRSSI_VCM_Q_SHIFT);
21114 } else {
21115 mod_radio_reg(pi,
21116 RADIO_2055_CORE2_B0_NBRSSI_VCM,
21117 RADIO_2055_NBRSSI_VCM_I_MASK,
21118 vcm_buf[2 *
21119 core] <<
21120 RADIO_2055_NBRSSI_VCM_I_SHIFT);
21121 mod_radio_reg(pi,
21122 RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
21123 RADIO_2055_NBRSSI_VCM_Q_MASK,
21124 vcm_buf[2 * core +
21125 1] <<
21126 RADIO_2055_NBRSSI_VCM_Q_SHIFT);
21127 }
21128 } else {
21129
21130 if (core == PHY_CORE_0) {
21131 mod_radio_reg(pi,
21132 RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
21133 RADIO_2055_WBRSSI_VCM_IQ_MASK,
21134 vcm_buf[2 *
21135 core] <<
21136 RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
21137 } else {
21138 mod_radio_reg(pi,
21139 RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
21140 RADIO_2055_WBRSSI_VCM_IQ_MASK,
21141 vcm_buf[2 *
21142 core] <<
21143 RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
21144 }
21145 }
21146 }
21147}
21148
21149void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi)
21150{
21151 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
21152
21153 wlc_phy_rssi_cal_nphy_rev3(pi);
21154 } else {
21155 wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB);
21156 wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1);
21157 wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2);
21158 }
21159}
21160
21161static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
21162{
21163 s32 target_code;
21164 u16 classif_state;
21165 u16 clip_state[2];
21166 u16 rssi_ctrl_state[2], pd_state[2];
21167 u16 rfctrlintc_state[2], rfpdcorerxtx_state[2];
21168 u16 rfctrlintc_override_val;
21169 u16 clip_off[] = { 0xffff, 0xffff };
21170 u16 rf_pd_val, pd_mask, rssi_ctrl_mask;
21171 u8 vcm, min_vcm, vcm_tmp[4];
21172 u8 vcm_final[4] = { 0, 0, 0, 0 };
21173 u8 result_idx, ctr;
21174 s32 poll_results[4][4] = {
21175 {0, 0, 0, 0},
21176 {0, 0, 0, 0},
21177 {0, 0, 0, 0},
21178 {0, 0, 0, 0}
21179 };
21180 s32 poll_miniq[4][2] = {
21181 {0, 0},
21182 {0, 0},
21183 {0, 0},
21184 {0, 0}
21185 };
21186 s32 min_d, curr_d;
21187 s32 fine_digital_offset[4];
21188 s32 poll_results_min[4] = { 0, 0, 0, 0 };
21189 s32 min_poll;
21190
21191 switch (rssi_type) {
21192 case NPHY_RSSI_SEL_NB:
21193 target_code = NPHY_RSSICAL_NB_TARGET;
21194 break;
21195 case NPHY_RSSI_SEL_W1:
21196 target_code = NPHY_RSSICAL_W1_TARGET;
21197 break;
21198 case NPHY_RSSI_SEL_W2:
21199 target_code = NPHY_RSSICAL_W2_TARGET;
21200 break;
21201 default:
21202 return;
21203 break;
21204 }
21205
21206 classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
21207 wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
21208 wlc_phy_clip_det_nphy(pi, 0, clip_state);
21209 wlc_phy_clip_det_nphy(pi, 1, clip_off);
21210
21211 rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4;
21212 rfctrlintc_override_val =
21213 CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110;
21214
21215 rfctrlintc_state[0] = read_phy_reg(pi, 0x91);
21216 rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX);
21217 write_phy_reg(pi, 0x91, rfctrlintc_override_val);
21218 write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val);
21219
21220 rfctrlintc_state[1] = read_phy_reg(pi, 0x92);
21221 rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX);
21222 write_phy_reg(pi, 0x92, rfctrlintc_override_val);
21223 write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val);
21224
21225 pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD |
21226 RADIO_2055_WBRSSI_G2_PD;
21227 pd_state[0] =
21228 read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask;
21229 pd_state[1] =
21230 read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask;
21231 mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0);
21232 mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0);
21233 rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL |
21234 RADIO_2055_WBRSSI_G2_SEL;
21235 rssi_ctrl_state[0] =
21236 read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask;
21237 rssi_ctrl_state[1] =
21238 read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask;
21239 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
21240
21241 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
21242 NPHY_RAIL_I, rssi_type);
21243 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
21244 NPHY_RAIL_Q, rssi_type);
21245
21246 for (vcm = 0; vcm < 4; vcm++) {
21247
21248 vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm;
21249 if (rssi_type != NPHY_RSSI_SEL_W2) {
21250 wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp);
21251 }
21252
21253 wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0],
21254 NPHY_RSSICAL_NPOLL);
21255
21256 if ((rssi_type == NPHY_RSSI_SEL_W1)
21257 || (rssi_type == NPHY_RSSI_SEL_W2)) {
21258 for (ctr = 0; ctr < 2; ctr++) {
21259 poll_miniq[vcm][ctr] =
21260 min(poll_results[vcm][ctr * 2 + 0],
21261 poll_results[vcm][ctr * 2 + 1]);
21262 }
21263 }
21264 }
21265
21266 for (result_idx = 0; result_idx < 4; result_idx++) {
21267 min_d = NPHY_RSSICAL_MAXD;
21268 min_vcm = 0;
21269 min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1;
21270 for (vcm = 0; vcm < 4; vcm++) {
21271 curr_d = ABS(((rssi_type == NPHY_RSSI_SEL_NB) ?
21272 poll_results[vcm][result_idx] :
21273 poll_miniq[vcm][result_idx / 2]) -
21274 (target_code * NPHY_RSSICAL_NPOLL));
21275 if (curr_d < min_d) {
21276 min_d = curr_d;
21277 min_vcm = vcm;
21278 }
21279 if (poll_results[vcm][result_idx] < min_poll) {
21280 min_poll = poll_results[vcm][result_idx];
21281 }
21282 }
21283 vcm_final[result_idx] = min_vcm;
21284 poll_results_min[result_idx] = min_poll;
21285 }
21286
21287 if (rssi_type != NPHY_RSSI_SEL_W2) {
21288 wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final);
21289 }
21290
21291 for (result_idx = 0; result_idx < 4; result_idx++) {
21292 fine_digital_offset[result_idx] =
21293 (target_code * NPHY_RSSICAL_NPOLL) -
21294 poll_results[vcm_final[result_idx]][result_idx];
21295 if (fine_digital_offset[result_idx] < 0) {
21296 fine_digital_offset[result_idx] =
21297 ABS(fine_digital_offset[result_idx]);
21298 fine_digital_offset[result_idx] +=
21299 (NPHY_RSSICAL_NPOLL / 2);
21300 fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
21301 fine_digital_offset[result_idx] =
21302 -fine_digital_offset[result_idx];
21303 } else {
21304 fine_digital_offset[result_idx] +=
21305 (NPHY_RSSICAL_NPOLL / 2);
21306 fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
21307 }
21308
21309 if (poll_results_min[result_idx] ==
21310 NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) {
21311 fine_digital_offset[result_idx] =
21312 (target_code - NPHY_RSSICAL_MAXREAD - 1);
21313 }
21314
21315 wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
21316 (s8)
21317 fine_digital_offset[result_idx],
21318 (result_idx / 2 ==
21319 0) ? RADIO_MIMO_CORESEL_CORE1 :
21320 RADIO_MIMO_CORESEL_CORE2,
21321 (result_idx % 2 ==
21322 0) ? NPHY_RAIL_I : NPHY_RAIL_Q,
21323 rssi_type);
21324 }
21325
21326 mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]);
21327 mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]);
21328 if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL) {
21329 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
21330 NPHY_RSSI_SEL_NB);
21331 } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) {
21332 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
21333 NPHY_RSSI_SEL_W1);
21334 } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) {
21335 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
21336 NPHY_RSSI_SEL_W2);
21337 } else {
21338 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
21339 NPHY_RSSI_SEL_W2);
21340 }
21341 if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) {
21342 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
21343 NPHY_RSSI_SEL_NB);
21344 } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) {
21345 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
21346 NPHY_RSSI_SEL_W1);
21347 } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) {
21348 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
21349 NPHY_RSSI_SEL_W2);
21350 } else {
21351 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
21352 NPHY_RSSI_SEL_W2);
21353 }
21354
21355 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
21356
21357 write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
21358 write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]);
21359 write_phy_reg(pi, 0x92, rfctrlintc_state[1]);
21360 write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]);
21361
21362 wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
21363 wlc_phy_clip_det_nphy(pi, 1, clip_state);
21364
21365 wlc_phy_resetcca_nphy(pi);
21366}
21367
21368int
21369wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct brcms_d11rxhdr *wlc_rxh)
21370{
21371 struct d11rxhdr *rxh = &wlc_rxh->rxhdr;
21372 s16 rxpwr, rxpwr0, rxpwr1;
21373 s16 phyRx0_l, phyRx2_l;
21374
21375 rxpwr = 0;
21376 rxpwr0 = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK;
21377 rxpwr1 = (le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8;
21378
21379 if (rxpwr0 > 127)
21380 rxpwr0 -= 256;
21381 if (rxpwr1 > 127)
21382 rxpwr1 -= 256;
21383
21384 phyRx0_l = le16_to_cpu(rxh->PhyRxStatus_0) & 0x00ff;
21385 phyRx2_l = le16_to_cpu(rxh->PhyRxStatus_2) & 0x00ff;
21386 if (phyRx2_l > 127)
21387 phyRx2_l -= 256;
21388
21389 if (((rxpwr0 == 16) || (rxpwr0 == 32))) {
21390 rxpwr0 = rxpwr1;
21391 rxpwr1 = phyRx2_l;
21392 }
21393
21394 wlc_rxh->rxpwr[0] = (s8) rxpwr0;
21395 wlc_rxh->rxpwr[1] = (s8) rxpwr1;
21396 wlc_rxh->do_rssi_ma = 0;
21397
21398 if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX)
21399 rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1;
21400 else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN)
21401 rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
21402 else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
21403 rxpwr = (rxpwr0 + rxpwr1) >> 1;
21404
21405 return rxpwr;
21406}
21407
21408static void
21409wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value,
21410 u8 core_code)
21411{
21412 u16 mask;
21413 u16 val;
21414 u8 core;
21415
21416 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
21417 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
21418 if (core_code == RADIO_MIMO_CORESEL_CORE1
21419 && core == PHY_CORE_1)
21420 continue;
21421 else if (core_code == RADIO_MIMO_CORESEL_CORE2
21422 && core == PHY_CORE_0)
21423 continue;
21424
21425 if (NREV_LT(pi->pubpi.phy_rev, 7)) {
21426
21427 mask = (0x1 << 10);
21428 val = 1 << 10;
21429 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
21430 0x92, mask, val);
21431 }
21432
21433 if (field == NPHY_RfctrlIntc_override_OFF) {
21434
21435 write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
21436 0x92, 0);
21437
21438 wlc_phy_force_rfseq_nphy(pi,
21439 NPHY_RFSEQ_RESET2RX);
21440 } else if (field == NPHY_RfctrlIntc_override_TRSW) {
21441
21442 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21443
21444 mask = (0x1 << 6) | (0x1 << 7);
21445
21446 val = value << 6;
21447 mod_phy_reg(pi,
21448 (core ==
21449 PHY_CORE_0) ? 0x91 : 0x92,
21450 mask, val);
21451
21452 or_phy_reg(pi,
21453 (core ==
21454 PHY_CORE_0) ? 0x91 : 0x92,
21455 (0x1 << 10));
21456
21457 and_phy_reg(pi, 0x2ff, (u16)
21458 ~(0x3 << 14));
21459 or_phy_reg(pi, 0x2ff, (0x1 << 13));
21460 or_phy_reg(pi, 0x2ff, (0x1 << 0));
21461 } else {
21462
21463 mask = (0x1 << 6) |
21464 (0x1 << 7) |
21465 (0x1 << 8) | (0x1 << 9);
21466 val = value << 6;
21467 mod_phy_reg(pi,
21468 (core ==
21469 PHY_CORE_0) ? 0x91 : 0x92,
21470 mask, val);
21471
21472 mask = (0x1 << 0);
21473 val = 1 << 0;
21474 mod_phy_reg(pi,
21475 (core ==
21476 PHY_CORE_0) ? 0xe7 : 0xec,
21477 mask, val);
21478
21479 mask = (core == PHY_CORE_0) ? (0x1 << 0)
21480 : (0x1 << 1);
21481 val = 1 << ((core == PHY_CORE_0) ?
21482 0 : 1);
21483 mod_phy_reg(pi, 0x78, mask, val);
21484
21485 SPINWAIT(((read_phy_reg(pi, 0x78) & val)
21486 != 0), 10000);
21487 if (WARN(read_phy_reg(pi, 0x78) & val,
21488 "HW error: override failed"))
21489 return;
21490
21491 mask = (0x1 << 0);
21492 val = 0 << 0;
21493 mod_phy_reg(pi,
21494 (core ==
21495 PHY_CORE_0) ? 0xe7 : 0xec,
21496 mask, val);
21497 }
21498 } else if (field == NPHY_RfctrlIntc_override_PA) {
21499 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21500
21501 mask = (0x1 << 4) | (0x1 << 5);
21502
21503 if (CHSPEC_IS5G(pi->radio_chanspec)) {
21504 val = value << 5;
21505 } else {
21506 val = value << 4;
21507 }
21508
21509 mod_phy_reg(pi,
21510 (core ==
21511 PHY_CORE_0) ? 0x91 : 0x92,
21512 mask, val);
21513
21514 or_phy_reg(pi,
21515 (core ==
21516 PHY_CORE_0) ? 0x91 : 0x92,
21517 (0x1 << 12));
21518 } else {
21519
21520 if (CHSPEC_IS5G(pi->radio_chanspec)) {
21521 mask = (0x1 << 5);
21522 val = value << 5;
21523 } else {
21524 mask = (0x1 << 4);
21525 val = value << 4;
21526 }
21527 mod_phy_reg(pi,
21528 (core ==
21529 PHY_CORE_0) ? 0x91 : 0x92,
21530 mask, val);
21531 }
21532 } else if (field == NPHY_RfctrlIntc_override_EXT_LNA_PU) {
21533 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21534 if (CHSPEC_IS5G(pi->radio_chanspec)) {
21535
21536 mask = (0x1 << 0);
21537 val = value << 0;
21538 mod_phy_reg(pi,
21539 (core ==
21540 PHY_CORE_0) ? 0x91
21541 : 0x92, mask, val);
21542
21543 mask = (0x1 << 2);
21544 mod_phy_reg(pi,
21545 (core ==
21546 PHY_CORE_0) ? 0x91
21547 : 0x92, mask, 0);
21548 } else {
21549
21550 mask = (0x1 << 2);
21551 val = value << 2;
21552 mod_phy_reg(pi,
21553 (core ==
21554 PHY_CORE_0) ? 0x91
21555 : 0x92, mask, val);
21556
21557 mask = (0x1 << 0);
21558 mod_phy_reg(pi,
21559 (core ==
21560 PHY_CORE_0) ? 0x91
21561 : 0x92, mask, 0);
21562 }
21563
21564 mask = (0x1 << 11);
21565 val = 1 << 11;
21566 mod_phy_reg(pi,
21567 (core ==
21568 PHY_CORE_0) ? 0x91 : 0x92,
21569 mask, val);
21570 } else {
21571
21572 if (CHSPEC_IS5G(pi->radio_chanspec)) {
21573 mask = (0x1 << 0);
21574 val = value << 0;
21575 } else {
21576 mask = (0x1 << 2);
21577 val = value << 2;
21578 }
21579 mod_phy_reg(pi,
21580 (core ==
21581 PHY_CORE_0) ? 0x91 : 0x92,
21582 mask, val);
21583 }
21584 } else if (field ==
21585 NPHY_RfctrlIntc_override_EXT_LNA_GAIN) {
21586 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21587 if (CHSPEC_IS5G(pi->radio_chanspec)) {
21588
21589 mask = (0x1 << 1);
21590 val = value << 1;
21591 mod_phy_reg(pi,
21592 (core ==
21593 PHY_CORE_0) ? 0x91
21594 : 0x92, mask, val);
21595
21596 mask = (0x1 << 3);
21597 mod_phy_reg(pi,
21598 (core ==
21599 PHY_CORE_0) ? 0x91
21600 : 0x92, mask, 0);
21601 } else {
21602
21603 mask = (0x1 << 3);
21604 val = value << 3;
21605 mod_phy_reg(pi,
21606 (core ==
21607 PHY_CORE_0) ? 0x91
21608 : 0x92, mask, val);
21609
21610 mask = (0x1 << 1);
21611 mod_phy_reg(pi,
21612 (core ==
21613 PHY_CORE_0) ? 0x91
21614 : 0x92, mask, 0);
21615 }
21616
21617 mask = (0x1 << 11);
21618 val = 1 << 11;
21619 mod_phy_reg(pi,
21620 (core ==
21621 PHY_CORE_0) ? 0x91 : 0x92,
21622 mask, val);
21623 } else {
21624
21625 if (CHSPEC_IS5G(pi->radio_chanspec)) {
21626 mask = (0x1 << 1);
21627 val = value << 1;
21628 } else {
21629 mask = (0x1 << 3);
21630 val = value << 3;
21631 }
21632 mod_phy_reg(pi,
21633 (core ==
21634 PHY_CORE_0) ? 0x91 : 0x92,
21635 mask, val);
21636 }
21637 }
21638 }
21639 } else {
21640 return;
21641 }
21642}
21643
21644static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi)
21645{
21646 u16 classif_state;
21647 u16 clip_state[2];
21648 u16 clip_off[] = { 0xffff, 0xffff };
21649 s32 target_code;
21650 u8 vcm, min_vcm;
21651 u8 vcm_final = 0;
21652 u8 result_idx;
21653 s32 poll_results[8][4] = {
21654 {0, 0, 0, 0},
21655 {0, 0, 0, 0},
21656 {0, 0, 0, 0},
21657 {0, 0, 0, 0},
21658 {0, 0, 0, 0},
21659 {0, 0, 0, 0},
21660 {0, 0, 0, 0},
21661 {0, 0, 0, 0}
21662 };
21663 s32 poll_result_core[4] = { 0, 0, 0, 0 };
21664 s32 min_d = NPHY_RSSICAL_MAXD, curr_d;
21665 s32 fine_digital_offset[4];
21666 s32 poll_results_min[4] = { 0, 0, 0, 0 };
21667 s32 min_poll;
21668 u8 vcm_level_max;
21669 u8 core;
21670 u8 wb_cnt;
21671 u8 rssi_type;
21672 u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save;
21673 u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save;
21674 u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save;
21675 u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save;
21676 u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save;
21677 u16 NPHY_RfctrlCmd_save;
21678 u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save;
21679 u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save;
21680 u8 rxcore_state;
21681 u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save;
21682 u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save;
21683 u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save;
21684 u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save;
21685
21686 NPHY_REV7_RfctrlOverride3_save = NPHY_REV7_RfctrlOverride4_save =
21687 NPHY_REV7_RfctrlOverride5_save = NPHY_REV7_RfctrlOverride6_save =
21688 NPHY_REV7_RfctrlMiscReg3_save = NPHY_REV7_RfctrlMiscReg4_save =
21689 NPHY_REV7_RfctrlMiscReg5_save = NPHY_REV7_RfctrlMiscReg6_save = 0;
21690
21691 classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
21692 wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
21693 wlc_phy_clip_det_nphy(pi, 0, clip_state);
21694 wlc_phy_clip_det_nphy(pi, 1, clip_off);
21695
21696 NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91);
21697 NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92);
21698 NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f);
21699 NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5);
21700 NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6);
21701 NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7);
21702 NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7);
21703 NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec);
21704 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21705 NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342);
21706 NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343);
21707 NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346);
21708 NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347);
21709 }
21710 NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
21711 NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
21712 NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78);
21713 NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
21714 NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
21715 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21716 NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340);
21717 NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341);
21718 NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
21719 NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
21720 }
21721 NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a);
21722 NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d);
21723
21724 wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0,
21725 RADIO_MIMO_CORESEL_ALLRXTX);
21726 wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1,
21727 RADIO_MIMO_CORESEL_ALLRXTX);
21728
21729 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21730 wlc_phy_rfctrl_override_1tomany_nphy(pi,
21731 NPHY_REV7_RfctrlOverride_cmd_rxrf_pu,
21732 0, 0, 0);
21733 } else {
21734 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0);
21735 }
21736
21737 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21738 wlc_phy_rfctrl_override_1tomany_nphy(pi,
21739 NPHY_REV7_RfctrlOverride_cmd_rx_pu,
21740 1, 0, 0);
21741 } else {
21742 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0);
21743 }
21744
21745 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21746 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
21747 1, 0, 0,
21748 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21749 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0,
21750 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21751 } else {
21752 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0);
21753 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0);
21754 }
21755
21756 if (CHSPEC_IS5G(pi->radio_chanspec)) {
21757 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21758 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
21759 0, 0, 0,
21760 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21761 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0,
21762 0,
21763 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21764 } else {
21765 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0);
21766 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0);
21767 }
21768
21769 } else {
21770 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21771 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4),
21772 0, 0, 0,
21773 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21774 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 1, 0,
21775 0,
21776 NPHY_REV7_RFCTRLOVERRIDE_ID0);
21777 } else {
21778 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0);
21779 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0);
21780 }
21781 }
21782
21783 rxcore_state = wlc_phy_rxcore_getstate_nphy(
21784 (struct brcms_phy_pub *) pi);
21785
21786 vcm_level_max = 8;
21787
21788 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
21789
21790 if ((rxcore_state & (1 << core)) == 0)
21791 continue;
21792
21793 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
21794 core ==
21795 PHY_CORE_0 ?
21796 RADIO_MIMO_CORESEL_CORE1 :
21797 RADIO_MIMO_CORESEL_CORE2,
21798 NPHY_RAIL_I, NPHY_RSSI_SEL_NB);
21799 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
21800 core ==
21801 PHY_CORE_0 ?
21802 RADIO_MIMO_CORESEL_CORE1 :
21803 RADIO_MIMO_CORESEL_CORE2,
21804 NPHY_RAIL_Q, NPHY_RSSI_SEL_NB);
21805
21806 for (vcm = 0; vcm < vcm_level_max; vcm++) {
21807 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21808
21809 mod_radio_reg(pi, (core == PHY_CORE_0) ?
21810 RADIO_2057_NB_MASTER_CORE0 :
21811 RADIO_2057_NB_MASTER_CORE1,
21812 RADIO_2057_VCM_MASK, vcm);
21813 } else {
21814
21815 mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
21816 ((core ==
21817 PHY_CORE_0) ? RADIO_2056_RX0 :
21818 RADIO_2056_RX1),
21819 RADIO_2056_VCM_MASK,
21820 vcm << RADIO_2056_RSSI_VCM_SHIFT);
21821 }
21822
21823 wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB,
21824 &poll_results[vcm][0],
21825 NPHY_RSSICAL_NPOLL);
21826 }
21827
21828 for (result_idx = 0; result_idx < 4; result_idx++) {
21829 if ((core == result_idx / 2) && (result_idx % 2 == 0)) {
21830
21831 min_d = NPHY_RSSICAL_MAXD;
21832 min_vcm = 0;
21833 min_poll =
21834 NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL +
21835 1;
21836 for (vcm = 0; vcm < vcm_level_max; vcm++) {
21837 curr_d = poll_results[vcm][result_idx] *
21838 poll_results[vcm][result_idx] +
21839 poll_results[vcm][result_idx + 1] *
21840 poll_results[vcm][result_idx + 1];
21841 if (curr_d < min_d) {
21842 min_d = curr_d;
21843 min_vcm = vcm;
21844 }
21845 if (poll_results[vcm][result_idx] <
21846 min_poll) {
21847 min_poll =
21848 poll_results[vcm]
21849 [result_idx];
21850 }
21851 }
21852 vcm_final = min_vcm;
21853 poll_results_min[result_idx] = min_poll;
21854 }
21855 }
21856
21857 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
21858 mod_radio_reg(pi, (core == PHY_CORE_0) ?
21859 RADIO_2057_NB_MASTER_CORE0 :
21860 RADIO_2057_NB_MASTER_CORE1,
21861 RADIO_2057_VCM_MASK, vcm_final);
21862 } else {
21863 mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
21864 ((core ==
21865 PHY_CORE_0) ? RADIO_2056_RX0 :
21866 RADIO_2056_RX1), RADIO_2056_VCM_MASK,
21867 vcm_final << RADIO_2056_RSSI_VCM_SHIFT);
21868 }
21869
21870 for (result_idx = 0; result_idx < 4; result_idx++) {
21871 if (core == result_idx / 2) {
21872 fine_digital_offset[result_idx] =
21873 (NPHY_RSSICAL_NB_TARGET *
21874 NPHY_RSSICAL_NPOLL) -
21875 poll_results[vcm_final][result_idx];
21876 if (fine_digital_offset[result_idx] < 0) {
21877 fine_digital_offset[result_idx] =
21878 ABS(fine_digital_offset
21879 [result_idx]);
21880 fine_digital_offset[result_idx] +=
21881 (NPHY_RSSICAL_NPOLL / 2);
21882 fine_digital_offset[result_idx] /=
21883 NPHY_RSSICAL_NPOLL;
21884 fine_digital_offset[result_idx] =
21885 -fine_digital_offset[result_idx];
21886 } else {
21887 fine_digital_offset[result_idx] +=
21888 (NPHY_RSSICAL_NPOLL / 2);
21889 fine_digital_offset[result_idx] /=
21890 NPHY_RSSICAL_NPOLL;
21891 }
21892
21893 if (poll_results_min[result_idx] ==
21894 NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) {
21895 fine_digital_offset[result_idx] =
21896 (NPHY_RSSICAL_NB_TARGET -
21897 NPHY_RSSICAL_MAXREAD - 1);
21898 }
21899
21900 wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
21901 (s8)
21902 fine_digital_offset
21903 [result_idx],
21904 (result_idx /
21905 2 ==
21906 0) ?
21907 RADIO_MIMO_CORESEL_CORE1
21908 :
21909 RADIO_MIMO_CORESEL_CORE2,
21910 (result_idx %
21911 2 ==
21912 0) ? NPHY_RAIL_I
21913 : NPHY_RAIL_Q,
21914 NPHY_RSSI_SEL_NB);
21915 }
21916 }
21917
21918 }
21919
21920 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
21921
21922 if ((rxcore_state & (1 << core)) == 0)
21923 continue;
21924
21925 for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) {
21926 if (wb_cnt == 0) {
21927 rssi_type = NPHY_RSSI_SEL_W1;
21928 target_code = NPHY_RSSICAL_W1_TARGET_REV3;
21929 } else {
21930 rssi_type = NPHY_RSSI_SEL_W2;
21931 target_code = NPHY_RSSICAL_W2_TARGET_REV3;
21932 }
21933
21934 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
21935 core ==
21936 PHY_CORE_0 ?
21937 RADIO_MIMO_CORESEL_CORE1
21938 :
21939 RADIO_MIMO_CORESEL_CORE2,
21940 NPHY_RAIL_I, rssi_type);
21941 wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
21942 core ==
21943 PHY_CORE_0 ?
21944 RADIO_MIMO_CORESEL_CORE1
21945 :
21946 RADIO_MIMO_CORESEL_CORE2,
21947 NPHY_RAIL_Q, rssi_type);
21948
21949 wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core,
21950 NPHY_RSSICAL_NPOLL);
21951
21952 for (result_idx = 0; result_idx < 4; result_idx++) {
21953 if (core == result_idx / 2) {
21954 fine_digital_offset[result_idx] =
21955 (target_code * NPHY_RSSICAL_NPOLL) -
21956 poll_result_core[result_idx];
21957 if (fine_digital_offset[result_idx] < 0) {
21958 fine_digital_offset[result_idx]
21959 =
21960 ABS(fine_digital_offset
21961 [result_idx]);
21962 fine_digital_offset[result_idx]
21963 += (NPHY_RSSICAL_NPOLL / 2);
21964 fine_digital_offset[result_idx]
21965 /= NPHY_RSSICAL_NPOLL;
21966 fine_digital_offset[result_idx]
21967 =
21968 -fine_digital_offset
21969 [result_idx];
21970 } else {
21971 fine_digital_offset[result_idx]
21972 += (NPHY_RSSICAL_NPOLL / 2);
21973 fine_digital_offset[result_idx]
21974 /= NPHY_RSSICAL_NPOLL;
21975 }
21976
21977 wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
21978 (s8)
21979 fine_digital_offset
21980 [core *
21981 2],
21982 (core ==
21983 PHY_CORE_0)
21984 ?
21985 RADIO_MIMO_CORESEL_CORE1
21986 :
21987 RADIO_MIMO_CORESEL_CORE2,
21988 (result_idx
21989 % 2 ==
21990 0) ?
21991 NPHY_RAIL_I
21992 :
21993 NPHY_RAIL_Q,
21994 rssi_type);
21995 }
21996 }
21997
21998 }
21999 }
22000
22001 write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save);
22002 write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save);
22003
22004 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
22005
22006 mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0);
22007 mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0);
22008 mod_phy_reg(pi, 0xe7, (0x1 << 0), 0);
22009
22010 mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0);
22011 mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1);
22012 mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
22013
22014 write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save);
22015 write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save);
22016 write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save);
22017 write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save);
22018 write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save);
22019 write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save);
22020 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22021 write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save);
22022 write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save);
22023 write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save);
22024 write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save);
22025 }
22026 write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save);
22027 write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save);
22028 write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save);
22029 write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save);
22030 write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save);
22031 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22032 write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save);
22033 write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save);
22034 write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save);
22035 write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save);
22036 }
22037 write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save);
22038 write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save);
22039
22040 if (CHSPEC_IS2G(pi->radio_chanspec)) {
22041 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22042 pi->rssical_cache.rssical_radio_regs_2G[0] =
22043 read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
22044 pi->rssical_cache.rssical_radio_regs_2G[1] =
22045 read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
22046 } else {
22047 pi->rssical_cache.rssical_radio_regs_2G[0] =
22048 read_radio_reg(pi,
22049 RADIO_2056_RX_RSSI_MISC |
22050 RADIO_2056_RX0);
22051 pi->rssical_cache.rssical_radio_regs_2G[1] =
22052 read_radio_reg(pi,
22053 RADIO_2056_RX_RSSI_MISC |
22054 RADIO_2056_RX1);
22055 }
22056
22057 pi->rssical_cache.rssical_phyregs_2G[0] =
22058 read_phy_reg(pi, 0x1a6);
22059 pi->rssical_cache.rssical_phyregs_2G[1] =
22060 read_phy_reg(pi, 0x1ac);
22061 pi->rssical_cache.rssical_phyregs_2G[2] =
22062 read_phy_reg(pi, 0x1b2);
22063 pi->rssical_cache.rssical_phyregs_2G[3] =
22064 read_phy_reg(pi, 0x1b8);
22065 pi->rssical_cache.rssical_phyregs_2G[4] =
22066 read_phy_reg(pi, 0x1a4);
22067 pi->rssical_cache.rssical_phyregs_2G[5] =
22068 read_phy_reg(pi, 0x1aa);
22069 pi->rssical_cache.rssical_phyregs_2G[6] =
22070 read_phy_reg(pi, 0x1b0);
22071 pi->rssical_cache.rssical_phyregs_2G[7] =
22072 read_phy_reg(pi, 0x1b6);
22073 pi->rssical_cache.rssical_phyregs_2G[8] =
22074 read_phy_reg(pi, 0x1a5);
22075 pi->rssical_cache.rssical_phyregs_2G[9] =
22076 read_phy_reg(pi, 0x1ab);
22077 pi->rssical_cache.rssical_phyregs_2G[10] =
22078 read_phy_reg(pi, 0x1b1);
22079 pi->rssical_cache.rssical_phyregs_2G[11] =
22080 read_phy_reg(pi, 0x1b7);
22081
22082 pi->nphy_rssical_chanspec_2G = pi->radio_chanspec;
22083 } else {
22084 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22085 pi->rssical_cache.rssical_radio_regs_5G[0] =
22086 read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
22087 pi->rssical_cache.rssical_radio_regs_5G[1] =
22088 read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
22089 } else {
22090 pi->rssical_cache.rssical_radio_regs_5G[0] =
22091 read_radio_reg(pi,
22092 RADIO_2056_RX_RSSI_MISC |
22093 RADIO_2056_RX0);
22094 pi->rssical_cache.rssical_radio_regs_5G[1] =
22095 read_radio_reg(pi,
22096 RADIO_2056_RX_RSSI_MISC |
22097 RADIO_2056_RX1);
22098 }
22099
22100 pi->rssical_cache.rssical_phyregs_5G[0] =
22101 read_phy_reg(pi, 0x1a6);
22102 pi->rssical_cache.rssical_phyregs_5G[1] =
22103 read_phy_reg(pi, 0x1ac);
22104 pi->rssical_cache.rssical_phyregs_5G[2] =
22105 read_phy_reg(pi, 0x1b2);
22106 pi->rssical_cache.rssical_phyregs_5G[3] =
22107 read_phy_reg(pi, 0x1b8);
22108 pi->rssical_cache.rssical_phyregs_5G[4] =
22109 read_phy_reg(pi, 0x1a4);
22110 pi->rssical_cache.rssical_phyregs_5G[5] =
22111 read_phy_reg(pi, 0x1aa);
22112 pi->rssical_cache.rssical_phyregs_5G[6] =
22113 read_phy_reg(pi, 0x1b0);
22114 pi->rssical_cache.rssical_phyregs_5G[7] =
22115 read_phy_reg(pi, 0x1b6);
22116 pi->rssical_cache.rssical_phyregs_5G[8] =
22117 read_phy_reg(pi, 0x1a5);
22118 pi->rssical_cache.rssical_phyregs_5G[9] =
22119 read_phy_reg(pi, 0x1ab);
22120 pi->rssical_cache.rssical_phyregs_5G[10] =
22121 read_phy_reg(pi, 0x1b1);
22122 pi->rssical_cache.rssical_phyregs_5G[11] =
22123 read_phy_reg(pi, 0x1b7);
22124
22125 pi->nphy_rssical_chanspec_5G = pi->radio_chanspec;
22126 }
22127
22128 wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
22129 wlc_phy_clip_det_nphy(pi, 1, clip_state);
22130}
22131
22132static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi)
22133{
22134 if (CHSPEC_IS2G(pi->radio_chanspec)) {
22135 if (pi->nphy_rssical_chanspec_2G == 0)
22136 return;
22137
22138 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22139 mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
22140 RADIO_2057_VCM_MASK,
22141 pi->rssical_cache.
22142 rssical_radio_regs_2G[0]);
22143 mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
22144 RADIO_2057_VCM_MASK,
22145 pi->rssical_cache.
22146 rssical_radio_regs_2G[1]);
22147 } else {
22148 mod_radio_reg(pi,
22149 RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
22150 RADIO_2056_VCM_MASK,
22151 pi->rssical_cache.
22152 rssical_radio_regs_2G[0]);
22153 mod_radio_reg(pi,
22154 RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
22155 RADIO_2056_VCM_MASK,
22156 pi->rssical_cache.
22157 rssical_radio_regs_2G[1]);
22158 }
22159
22160 write_phy_reg(pi, 0x1a6,
22161 pi->rssical_cache.rssical_phyregs_2G[0]);
22162 write_phy_reg(pi, 0x1ac,
22163 pi->rssical_cache.rssical_phyregs_2G[1]);
22164 write_phy_reg(pi, 0x1b2,
22165 pi->rssical_cache.rssical_phyregs_2G[2]);
22166 write_phy_reg(pi, 0x1b8,
22167 pi->rssical_cache.rssical_phyregs_2G[3]);
22168 write_phy_reg(pi, 0x1a4,
22169 pi->rssical_cache.rssical_phyregs_2G[4]);
22170 write_phy_reg(pi, 0x1aa,
22171 pi->rssical_cache.rssical_phyregs_2G[5]);
22172 write_phy_reg(pi, 0x1b0,
22173 pi->rssical_cache.rssical_phyregs_2G[6]);
22174 write_phy_reg(pi, 0x1b6,
22175 pi->rssical_cache.rssical_phyregs_2G[7]);
22176 write_phy_reg(pi, 0x1a5,
22177 pi->rssical_cache.rssical_phyregs_2G[8]);
22178 write_phy_reg(pi, 0x1ab,
22179 pi->rssical_cache.rssical_phyregs_2G[9]);
22180 write_phy_reg(pi, 0x1b1,
22181 pi->rssical_cache.rssical_phyregs_2G[10]);
22182 write_phy_reg(pi, 0x1b7,
22183 pi->rssical_cache.rssical_phyregs_2G[11]);
22184
22185 } else {
22186 if (pi->nphy_rssical_chanspec_5G == 0)
22187 return;
22188
22189 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22190 mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
22191 RADIO_2057_VCM_MASK,
22192 pi->rssical_cache.
22193 rssical_radio_regs_5G[0]);
22194 mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
22195 RADIO_2057_VCM_MASK,
22196 pi->rssical_cache.
22197 rssical_radio_regs_5G[1]);
22198 } else {
22199 mod_radio_reg(pi,
22200 RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
22201 RADIO_2056_VCM_MASK,
22202 pi->rssical_cache.
22203 rssical_radio_regs_5G[0]);
22204 mod_radio_reg(pi,
22205 RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
22206 RADIO_2056_VCM_MASK,
22207 pi->rssical_cache.
22208 rssical_radio_regs_5G[1]);
22209 }
22210
22211 write_phy_reg(pi, 0x1a6,
22212 pi->rssical_cache.rssical_phyregs_5G[0]);
22213 write_phy_reg(pi, 0x1ac,
22214 pi->rssical_cache.rssical_phyregs_5G[1]);
22215 write_phy_reg(pi, 0x1b2,
22216 pi->rssical_cache.rssical_phyregs_5G[2]);
22217 write_phy_reg(pi, 0x1b8,
22218 pi->rssical_cache.rssical_phyregs_5G[3]);
22219 write_phy_reg(pi, 0x1a4,
22220 pi->rssical_cache.rssical_phyregs_5G[4]);
22221 write_phy_reg(pi, 0x1aa,
22222 pi->rssical_cache.rssical_phyregs_5G[5]);
22223 write_phy_reg(pi, 0x1b0,
22224 pi->rssical_cache.rssical_phyregs_5G[6]);
22225 write_phy_reg(pi, 0x1b6,
22226 pi->rssical_cache.rssical_phyregs_5G[7]);
22227 write_phy_reg(pi, 0x1a5,
22228 pi->rssical_cache.rssical_phyregs_5G[8]);
22229 write_phy_reg(pi, 0x1ab,
22230 pi->rssical_cache.rssical_phyregs_5G[9]);
22231 write_phy_reg(pi, 0x1b1,
22232 pi->rssical_cache.rssical_phyregs_5G[10]);
22233 write_phy_reg(pi, 0x1b7,
22234 pi->rssical_cache.rssical_phyregs_5G[11]);
22235 }
22236}
22237
22238static u16
22239wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
22240 u8 dac_test_mode)
22241{
22242 u8 phy_bw, is_phybw40;
22243 u16 num_samps, t, spur;
22244 fixed theta = 0, rot = 0;
22245 u32 tbl_len;
22246 cs32 *tone_buf = NULL;
22247
22248 is_phybw40 = CHSPEC_IS40(pi->radio_chanspec);
22249 phy_bw = (is_phybw40 == 1) ? 40 : 20;
22250 tbl_len = (phy_bw << 3);
22251
22252 if (dac_test_mode == 1) {
22253 spur = read_phy_reg(pi, 0x01);
22254 spur = (spur >> 15) & 1;
22255 phy_bw = (spur == 1) ? 82 : 80;
22256 phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw;
22257
22258 tbl_len = (phy_bw << 1);
22259 }
22260
22261 tone_buf = kmalloc(sizeof(cs32) * tbl_len, GFP_ATOMIC);
22262 if (tone_buf == NULL) {
22263 return 0;
22264 }
22265
22266 num_samps = (u16) tbl_len;
22267 rot = FIXED((f_kHz * 36) / phy_bw) / 100;
22268 theta = 0;
22269
22270 for (t = 0; t < num_samps; t++) {
22271
22272 wlc_phy_cordic(theta, &tone_buf[t]);
22273
22274 theta += rot;
22275
22276 tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val);
22277 tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val);
22278 }
22279
22280 wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
22281
22282 kfree(tone_buf);
22283
22284 return num_samps;
22285}
22286
22287int
22288wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
22289 u8 iqmode, u8 dac_test_mode, bool modify_bbmult)
22290{
22291 u16 num_samps;
22292 u16 loops = 0xffff;
22293 u16 wait = 0;
22294
22295 num_samps =
22296 wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode);
22297 if (num_samps == 0) {
22298 return -EBADE;
22299 }
22300
22301 wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
22302 dac_test_mode, modify_bbmult);
22303
22304 return 0;
22305}
22306
22307static void
22308wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, cs32 *tone_buf,
22309 u16 num_samps)
22310{
22311 u16 t;
22312 u32 *data_buf = NULL;
22313
22314 data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC);
22315 if (data_buf == NULL) {
22316 return;
22317 }
22318
22319 if (pi->phyhang_avoid)
22320 wlc_phy_stay_in_carriersearch_nphy(pi, true);
22321
22322 for (t = 0; t < num_samps; t++) {
22323 data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) |
22324 (((unsigned int)tone_buf[t].q) & 0x3ff);
22325 }
22326 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32,
22327 data_buf);
22328
22329 kfree(data_buf);
22330
22331 if (pi->phyhang_avoid)
22332 wlc_phy_stay_in_carriersearch_nphy(pi, false);
22333}
22334
22335static void
22336wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops,
22337 u16 wait, u8 iqmode, u8 dac_test_mode,
22338 bool modify_bbmult)
22339{
22340 u16 bb_mult;
22341 u8 phy_bw, sample_cmd;
22342 u16 orig_RfseqCoreActv;
22343 u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3,
22344 lpf_bw_ctl_miscreg4;
22345
22346 if (pi->phyhang_avoid)
22347 wlc_phy_stay_in_carriersearch_nphy(pi, true);
22348
22349 phy_bw = 20;
22350 if (CHSPEC_IS40(pi->radio_chanspec))
22351 phy_bw = 40;
22352
22353 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22354
22355 lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7);
22356 lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7);
22357 if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) {
22358 lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
22359 (0x7 << 8);
22360 lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
22361 (0x7 << 8);
22362 } else {
22363 wlc_phy_rfctrl_override_nphy_rev7(pi,
22364 (0x1 << 7),
22365 wlc_phy_read_lpf_bw_ctl_nphy
22366 (pi, 0), 0, 0,
22367 NPHY_REV7_RFCTRLOVERRIDE_ID1);
22368
22369 pi->nphy_sample_play_lpf_bw_ctl_ovr = true;
22370
22371 lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
22372 (0x7 << 8);
22373 lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
22374 (0x7 << 8);
22375 }
22376 }
22377
22378 if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) {
22379
22380 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
22381 &bb_mult);
22382 pi->nphy_bb_mult_save =
22383 BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK);
22384 }
22385
22386 if (modify_bbmult) {
22387 bb_mult = (phy_bw == 20) ? 100 : 71;
22388 bb_mult = (bb_mult << 8) + bb_mult;
22389 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
22390 &bb_mult);
22391 }
22392
22393 if (pi->phyhang_avoid)
22394 wlc_phy_stay_in_carriersearch_nphy(pi, false);
22395
22396 write_phy_reg(pi, 0xc6, num_samps - 1);
22397
22398 if (loops != 0xffff) {
22399 write_phy_reg(pi, 0xc4, loops - 1);
22400 } else {
22401 write_phy_reg(pi, 0xc4, loops);
22402 }
22403 write_phy_reg(pi, 0xc5, wait);
22404
22405 orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
22406 or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
22407 if (iqmode) {
22408
22409 and_phy_reg(pi, 0xc2, 0x7FFF);
22410
22411 or_phy_reg(pi, 0xc2, 0x8000);
22412 } else {
22413
22414 sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1;
22415 write_phy_reg(pi, 0xc3, sample_cmd);
22416 }
22417
22418 SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000);
22419
22420 write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
22421}
22422
22423void wlc_phy_stopplayback_nphy(struct brcms_phy *pi)
22424{
22425 u16 playback_status;
22426 u16 bb_mult;
22427
22428 if (pi->phyhang_avoid)
22429 wlc_phy_stay_in_carriersearch_nphy(pi, true);
22430
22431 playback_status = read_phy_reg(pi, 0xc7);
22432 if (playback_status & 0x1) {
22433 or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP);
22434 } else if (playback_status & 0x2) {
22435
22436 and_phy_reg(pi, 0xc2,
22437 (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN);
22438 }
22439
22440 and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2));
22441
22442 if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) {
22443
22444 bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK;
22445 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
22446 &bb_mult);
22447
22448 pi->nphy_bb_mult_save = 0;
22449 }
22450
22451 if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) {
22452 if (pi->nphy_sample_play_lpf_bw_ctl_ovr) {
22453 wlc_phy_rfctrl_override_nphy_rev7(pi,
22454 (0x1 << 7),
22455 0, 0, 1,
22456 NPHY_REV7_RFCTRLOVERRIDE_ID1);
22457 pi->nphy_sample_play_lpf_bw_ctl_ovr = false;
22458 }
22459 }
22460
22461 if (pi->phyhang_avoid)
22462 wlc_phy_stay_in_carriersearch_nphy(pi, false);
22463}
22464
22465struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi)
22466{
22467 u16 base_idx[2], curr_gain[2];
22468 u8 core_no;
22469 struct nphy_txgains target_gain;
22470 u32 *tx_pwrctrl_tbl = NULL;
22471
22472 if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
22473 if (pi->phyhang_avoid)
22474 wlc_phy_stay_in_carriersearch_nphy(pi, true);
22475
22476 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
22477 curr_gain);
22478
22479 if (pi->phyhang_avoid)
22480 wlc_phy_stay_in_carriersearch_nphy(pi, false);
22481
22482 for (core_no = 0; core_no < 2; core_no++) {
22483 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22484 target_gain.ipa[core_no] =
22485 curr_gain[core_no] & 0x0007;
22486 target_gain.pad[core_no] =
22487 ((curr_gain[core_no] & 0x00F8) >> 3);
22488 target_gain.pga[core_no] =
22489 ((curr_gain[core_no] & 0x0F00) >> 8);
22490 target_gain.txgm[core_no] =
22491 ((curr_gain[core_no] & 0x7000) >> 12);
22492 target_gain.txlpf[core_no] =
22493 ((curr_gain[core_no] & 0x8000) >> 15);
22494 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
22495 target_gain.ipa[core_no] =
22496 curr_gain[core_no] & 0x000F;
22497 target_gain.pad[core_no] =
22498 ((curr_gain[core_no] & 0x00F0) >> 4);
22499 target_gain.pga[core_no] =
22500 ((curr_gain[core_no] & 0x0F00) >> 8);
22501 target_gain.txgm[core_no] =
22502 ((curr_gain[core_no] & 0x7000) >> 12);
22503 } else {
22504 target_gain.ipa[core_no] =
22505 curr_gain[core_no] & 0x0003;
22506 target_gain.pad[core_no] =
22507 ((curr_gain[core_no] & 0x000C) >> 2);
22508 target_gain.pga[core_no] =
22509 ((curr_gain[core_no] & 0x0070) >> 4);
22510 target_gain.txgm[core_no] =
22511 ((curr_gain[core_no] & 0x0380) >> 7);
22512 }
22513 }
22514 } else {
22515 uint phyrev = pi->pubpi.phy_rev;
22516
22517 base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f;
22518 base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f;
22519 for (core_no = 0; core_no < 2; core_no++) {
22520 if (NREV_GE(phyrev, 3)) {
22521 if (PHY_IPA(pi)) {
22522 tx_pwrctrl_tbl =
22523 wlc_phy_get_ipa_gaintbl_nphy(pi);
22524 } else {
22525 if (CHSPEC_IS5G(pi->radio_chanspec)) {
22526 if (NREV_IS(phyrev, 3)) {
22527 tx_pwrctrl_tbl =
22528 nphy_tpc_5GHz_txgain_rev3;
22529 } else if (NREV_IS(phyrev, 4)) {
22530 tx_pwrctrl_tbl =
22531 (pi->srom_fem5g.
22532 extpagain ==
22533 3) ?
22534 nphy_tpc_5GHz_txgain_HiPwrEPA
22535 :
22536 nphy_tpc_5GHz_txgain_rev4;
22537 } else {
22538 tx_pwrctrl_tbl =
22539 nphy_tpc_5GHz_txgain_rev5;
22540 }
22541 } else {
22542 if (NREV_GE(phyrev, 7)) {
22543 if (pi->pubpi.
22544 radiorev == 3) {
22545 tx_pwrctrl_tbl =
22546 nphy_tpc_txgain_epa_2057rev3;
22547 } else if (pi->pubpi.
22548 radiorev ==
22549 5) {
22550 tx_pwrctrl_tbl =
22551 nphy_tpc_txgain_epa_2057rev5;
22552 }
22553
22554 } else {
22555 if (NREV_GE(phyrev, 5)
22556 && (pi->srom_fem2g.
22557 extpagain ==
22558 3)) {
22559 tx_pwrctrl_tbl =
22560 nphy_tpc_txgain_HiPwrEPA;
22561 } else {
22562 tx_pwrctrl_tbl =
22563 nphy_tpc_txgain_rev3;
22564 }
22565 }
22566 }
22567 }
22568 if (NREV_GE(phyrev, 7)) {
22569 target_gain.ipa[core_no] =
22570 (tx_pwrctrl_tbl[base_idx[core_no]]
22571 >> 16) & 0x7;
22572 target_gain.pad[core_no] =
22573 (tx_pwrctrl_tbl[base_idx[core_no]]
22574 >> 19) & 0x1f;
22575 target_gain.pga[core_no] =
22576 (tx_pwrctrl_tbl[base_idx[core_no]]
22577 >> 24) & 0xf;
22578 target_gain.txgm[core_no] =
22579 (tx_pwrctrl_tbl[base_idx[core_no]]
22580 >> 28) & 0x7;
22581 target_gain.txlpf[core_no] =
22582 (tx_pwrctrl_tbl[base_idx[core_no]]
22583 >> 31) & 0x1;
22584 } else {
22585 target_gain.ipa[core_no] =
22586 (tx_pwrctrl_tbl[base_idx[core_no]]
22587 >> 16) & 0xf;
22588 target_gain.pad[core_no] =
22589 (tx_pwrctrl_tbl[base_idx[core_no]]
22590 >> 20) & 0xf;
22591 target_gain.pga[core_no] =
22592 (tx_pwrctrl_tbl[base_idx[core_no]]
22593 >> 24) & 0xf;
22594 target_gain.txgm[core_no] =
22595 (tx_pwrctrl_tbl[base_idx[core_no]]
22596 >> 28) & 0x7;
22597 }
22598 } else {
22599 target_gain.ipa[core_no] =
22600 (nphy_tpc_txgain[base_idx[core_no]] >> 16) &
22601 0x3;
22602 target_gain.pad[core_no] =
22603 (nphy_tpc_txgain[base_idx[core_no]] >> 18) &
22604 0x3;
22605 target_gain.pga[core_no] =
22606 (nphy_tpc_txgain[base_idx[core_no]] >> 20) &
22607 0x7;
22608 target_gain.txgm[core_no] =
22609 (nphy_tpc_txgain[base_idx[core_no]] >> 23) &
22610 0x7;
22611 }
22612 }
22613 }
22614
22615 return target_gain;
22616}
22617
22618static void
22619wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no,
22620 struct nphy_txgains target_gain,
22621 struct nphy_iqcal_params *params)
22622{
22623 u8 k;
22624 int idx;
22625 u16 gain_index;
22626 u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
22627
22628 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
22629 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22630 params->txlpf = target_gain.txlpf[core_no];
22631 }
22632 params->txgm = target_gain.txgm[core_no];
22633 params->pga = target_gain.pga[core_no];
22634 params->pad = target_gain.pad[core_no];
22635 params->ipa = target_gain.ipa[core_no];
22636 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22637 params->cal_gain =
22638 ((params->txlpf << 15) | (params->
22639 txgm << 12) | (params->
22640 pga << 8) |
22641 (params->pad << 3) | (params->ipa));
22642 } else {
22643 params->cal_gain =
22644 ((params->txgm << 12) | (params->
22645 pga << 8) | (params->
22646 pad << 4) |
22647 (params->ipa));
22648 }
22649 params->ncorr[0] = 0x79;
22650 params->ncorr[1] = 0x79;
22651 params->ncorr[2] = 0x79;
22652 params->ncorr[3] = 0x79;
22653 params->ncorr[4] = 0x79;
22654 } else {
22655
22656 gain_index = ((target_gain.pad[core_no] << 0) |
22657 (target_gain.pga[core_no] << 4) | (target_gain.
22658 txgm[core_no]
22659 << 8));
22660
22661 idx = -1;
22662 for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) {
22663 if (tbl_iqcal_gainparams_nphy[band_idx][k][0] ==
22664 gain_index) {
22665 idx = k;
22666 break;
22667 }
22668 }
22669
22670 params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
22671 params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
22672 params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
22673 params->cal_gain = ((params->txgm << 7) | (params->pga << 4) |
22674 (params->pad << 2));
22675 params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4];
22676 params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5];
22677 params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6];
22678 params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7];
22679 }
22680}
22681
22682static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi)
22683{
22684 u16 jtag_core, core;
22685
22686 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22687
22688 for (core = 0; core <= 1; core++) {
22689
22690 pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
22691 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
22692 TX_SSI_MASTER);
22693
22694 pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
22695 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
22696 IQCAL_VCM_HG);
22697
22698 pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
22699 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
22700 IQCAL_IDAC);
22701
22702 pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
22703 READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM);
22704
22705 pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0;
22706
22707 pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
22708 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
22709 TX_SSI_MUX);
22710
22711 if (pi->pubpi.radiorev != 5)
22712 pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
22713 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
22714 TSSIA);
22715
22716 pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
22717 READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG);
22718
22719 pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
22720 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
22721 TSSI_MISC1);
22722
22723 if (CHSPEC_IS5G(pi->radio_chanspec)) {
22724 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22725 TX_SSI_MASTER, 0x0a);
22726 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22727 IQCAL_VCM_HG, 0x43);
22728 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22729 IQCAL_IDAC, 0x55);
22730 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22731 TSSI_VCM, 0x00);
22732 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22733 TSSIG, 0x00);
22734 if (pi->use_int_tx_iqlo_cal_nphy) {
22735 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
22736 core, TX_SSI_MUX, 0x4);
22737 if (!
22738 (pi->
22739 internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
22740
22741 WRITE_RADIO_REG3(pi, RADIO_2057,
22742 TX, core,
22743 TSSIA, 0x31);
22744 } else {
22745
22746 WRITE_RADIO_REG3(pi, RADIO_2057,
22747 TX, core,
22748 TSSIA, 0x21);
22749 }
22750 }
22751 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22752 TSSI_MISC1, 0x00);
22753 } else {
22754 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22755 TX_SSI_MASTER, 0x06);
22756 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22757 IQCAL_VCM_HG, 0x43);
22758 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22759 IQCAL_IDAC, 0x55);
22760 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22761 TSSI_VCM, 0x00);
22762
22763 if (pi->pubpi.radiorev != 5)
22764 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
22765 core, TSSIA, 0x00);
22766 if (pi->use_int_tx_iqlo_cal_nphy) {
22767 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
22768 core, TX_SSI_MUX,
22769 0x06);
22770 if (!
22771 (pi->
22772 internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
22773
22774 WRITE_RADIO_REG3(pi, RADIO_2057,
22775 TX, core,
22776 TSSIG, 0x31);
22777 } else {
22778
22779 WRITE_RADIO_REG3(pi, RADIO_2057,
22780 TX, core,
22781 TSSIG, 0x21);
22782 }
22783 }
22784 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
22785 TSSI_MISC1, 0x00);
22786 }
22787 }
22788 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
22789
22790 for (core = 0; core <= 1; core++) {
22791 jtag_core =
22792 (core ==
22793 PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
22794
22795 pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
22796 read_radio_reg(pi,
22797 RADIO_2056_TX_TX_SSI_MASTER |
22798 jtag_core);
22799
22800 pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
22801 read_radio_reg(pi,
22802 RADIO_2056_TX_IQCAL_VCM_HG |
22803 jtag_core);
22804
22805 pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
22806 read_radio_reg(pi,
22807 RADIO_2056_TX_IQCAL_IDAC |
22808 jtag_core);
22809
22810 pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
22811 read_radio_reg(pi,
22812 RADIO_2056_TX_TSSI_VCM | jtag_core);
22813
22814 pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] =
22815 read_radio_reg(pi,
22816 RADIO_2056_TX_TX_AMP_DET |
22817 jtag_core);
22818
22819 pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
22820 read_radio_reg(pi,
22821 RADIO_2056_TX_TX_SSI_MUX |
22822 jtag_core);
22823
22824 pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
22825 read_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core);
22826
22827 pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
22828 read_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core);
22829
22830 pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
22831 read_radio_reg(pi,
22832 RADIO_2056_TX_TSSI_MISC1 |
22833 jtag_core);
22834
22835 pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] =
22836 read_radio_reg(pi,
22837 RADIO_2056_TX_TSSI_MISC2 |
22838 jtag_core);
22839
22840 pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] =
22841 read_radio_reg(pi,
22842 RADIO_2056_TX_TSSI_MISC3 |
22843 jtag_core);
22844
22845 if (CHSPEC_IS5G(pi->radio_chanspec)) {
22846 write_radio_reg(pi,
22847 RADIO_2056_TX_TX_SSI_MASTER |
22848 jtag_core, 0x0a);
22849 write_radio_reg(pi,
22850 RADIO_2056_TX_IQCAL_VCM_HG |
22851 jtag_core, 0x40);
22852 write_radio_reg(pi,
22853 RADIO_2056_TX_IQCAL_IDAC |
22854 jtag_core, 0x55);
22855 write_radio_reg(pi,
22856 RADIO_2056_TX_TSSI_VCM |
22857 jtag_core, 0x00);
22858 write_radio_reg(pi,
22859 RADIO_2056_TX_TX_AMP_DET |
22860 jtag_core, 0x00);
22861
22862 if (PHY_IPA(pi)) {
22863 write_radio_reg(pi,
22864 RADIO_2056_TX_TX_SSI_MUX
22865 | jtag_core, 0x4);
22866 write_radio_reg(pi,
22867 RADIO_2056_TX_TSSIA |
22868 jtag_core, 0x1);
22869 } else {
22870 write_radio_reg(pi,
22871 RADIO_2056_TX_TX_SSI_MUX
22872 | jtag_core, 0x00);
22873 write_radio_reg(pi,
22874 RADIO_2056_TX_TSSIA |
22875 jtag_core, 0x2f);
22876 }
22877 write_radio_reg(pi,
22878 RADIO_2056_TX_TSSIG | jtag_core,
22879 0x00);
22880 write_radio_reg(pi,
22881 RADIO_2056_TX_TSSI_MISC1 |
22882 jtag_core, 0x00);
22883
22884 write_radio_reg(pi,
22885 RADIO_2056_TX_TSSI_MISC2 |
22886 jtag_core, 0x00);
22887 write_radio_reg(pi,
22888 RADIO_2056_TX_TSSI_MISC3 |
22889 jtag_core, 0x00);
22890 } else {
22891 write_radio_reg(pi,
22892 RADIO_2056_TX_TX_SSI_MASTER |
22893 jtag_core, 0x06);
22894 write_radio_reg(pi,
22895 RADIO_2056_TX_IQCAL_VCM_HG |
22896 jtag_core, 0x40);
22897 write_radio_reg(pi,
22898 RADIO_2056_TX_IQCAL_IDAC |
22899 jtag_core, 0x55);
22900 write_radio_reg(pi,
22901 RADIO_2056_TX_TSSI_VCM |
22902 jtag_core, 0x00);
22903 write_radio_reg(pi,
22904 RADIO_2056_TX_TX_AMP_DET |
22905 jtag_core, 0x00);
22906 write_radio_reg(pi,
22907 RADIO_2056_TX_TSSIA | jtag_core,
22908 0x00);
22909
22910 if (PHY_IPA(pi)) {
22911
22912 write_radio_reg(pi,
22913 RADIO_2056_TX_TX_SSI_MUX
22914 | jtag_core, 0x06);
22915 if (NREV_LT(pi->pubpi.phy_rev, 5)) {
22916
22917 write_radio_reg(pi,
22918 RADIO_2056_TX_TSSIG
22919 | jtag_core,
22920 0x11);
22921 } else {
22922
22923 write_radio_reg(pi,
22924 RADIO_2056_TX_TSSIG
22925 | jtag_core,
22926 0x1);
22927 }
22928 } else {
22929 write_radio_reg(pi,
22930 RADIO_2056_TX_TX_SSI_MUX
22931 | jtag_core, 0x00);
22932 write_radio_reg(pi,
22933 RADIO_2056_TX_TSSIG |
22934 jtag_core, 0x20);
22935 }
22936
22937 write_radio_reg(pi,
22938 RADIO_2056_TX_TSSI_MISC1 |
22939 jtag_core, 0x00);
22940 write_radio_reg(pi,
22941 RADIO_2056_TX_TSSI_MISC2 |
22942 jtag_core, 0x00);
22943 write_radio_reg(pi,
22944 RADIO_2056_TX_TSSI_MISC3 |
22945 jtag_core, 0x00);
22946 }
22947 }
22948 } else {
22949
22950 pi->tx_rx_cal_radio_saveregs[0] =
22951 read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
22952 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29);
22953 pi->tx_rx_cal_radio_saveregs[1] =
22954 read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
22955 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54);
22956
22957 pi->tx_rx_cal_radio_saveregs[2] =
22958 read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
22959 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29);
22960 pi->tx_rx_cal_radio_saveregs[3] =
22961 read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
22962 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54);
22963
22964 pi->tx_rx_cal_radio_saveregs[4] =
22965 read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
22966 pi->tx_rx_cal_radio_saveregs[5] =
22967 read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
22968
22969 if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) ==
22970 0) {
22971
22972 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
22973 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
22974 } else {
22975
22976 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20);
22977 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20);
22978 }
22979
22980 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
22981
22982 or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20);
22983 or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20);
22984 } else {
22985
22986 and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf);
22987 and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf);
22988 }
22989 }
22990}
22991
22992static void wlc_phy_txcal_radio_cleanup_nphy(struct brcms_phy *pi)
22993{
22994 u16 jtag_core, core;
22995
22996 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
22997 for (core = 0; core <= 1; core++) {
22998
22999 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23000 TX_SSI_MASTER,
23001 pi->
23002 tx_rx_cal_radio_saveregs[(core * 11) +
23003 0]);
23004
23005 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
23006 pi->
23007 tx_rx_cal_radio_saveregs[(core * 11) +
23008 1]);
23009
23010 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
23011 pi->
23012 tx_rx_cal_radio_saveregs[(core * 11) +
23013 2]);
23014
23015 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
23016 pi->
23017 tx_rx_cal_radio_saveregs[(core * 11) +
23018 3]);
23019
23020 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX,
23021 pi->
23022 tx_rx_cal_radio_saveregs[(core * 11) +
23023 5]);
23024
23025 if (pi->pubpi.radiorev != 5)
23026 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
23027 TSSIA,
23028 pi->
23029 tx_rx_cal_radio_saveregs[(core
23030 *
23031 11) +
23032 6]);
23033
23034 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG,
23035 pi->
23036 tx_rx_cal_radio_saveregs[(core * 11) +
23037 7]);
23038
23039 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
23040 pi->
23041 tx_rx_cal_radio_saveregs[(core * 11) +
23042 8]);
23043 }
23044 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23045 for (core = 0; core <= 1; core++) {
23046 jtag_core =
23047 (core ==
23048 PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
23049
23050 write_radio_reg(pi,
23051 RADIO_2056_TX_TX_SSI_MASTER | jtag_core,
23052 pi->
23053 tx_rx_cal_radio_saveregs[(core * 11) +
23054 0]);
23055
23056 write_radio_reg(pi,
23057 RADIO_2056_TX_IQCAL_VCM_HG | jtag_core,
23058 pi->
23059 tx_rx_cal_radio_saveregs[(core * 11) +
23060 1]);
23061
23062 write_radio_reg(pi,
23063 RADIO_2056_TX_IQCAL_IDAC | jtag_core,
23064 pi->
23065 tx_rx_cal_radio_saveregs[(core * 11) +
23066 2]);
23067
23068 write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core,
23069 pi->
23070 tx_rx_cal_radio_saveregs[(core * 11) +
23071 3]);
23072
23073 write_radio_reg(pi,
23074 RADIO_2056_TX_TX_AMP_DET | jtag_core,
23075 pi->
23076 tx_rx_cal_radio_saveregs[(core * 11) +
23077 4]);
23078
23079 write_radio_reg(pi,
23080 RADIO_2056_TX_TX_SSI_MUX | jtag_core,
23081 pi->
23082 tx_rx_cal_radio_saveregs[(core * 11) +
23083 5]);
23084
23085 write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core,
23086 pi->
23087 tx_rx_cal_radio_saveregs[(core * 11) +
23088 6]);
23089
23090 write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core,
23091 pi->
23092 tx_rx_cal_radio_saveregs[(core * 11) +
23093 7]);
23094
23095 write_radio_reg(pi,
23096 RADIO_2056_TX_TSSI_MISC1 | jtag_core,
23097 pi->
23098 tx_rx_cal_radio_saveregs[(core * 11) +
23099 8]);
23100
23101 write_radio_reg(pi,
23102 RADIO_2056_TX_TSSI_MISC2 | jtag_core,
23103 pi->
23104 tx_rx_cal_radio_saveregs[(core * 11) +
23105 9]);
23106
23107 write_radio_reg(pi,
23108 RADIO_2056_TX_TSSI_MISC3 | jtag_core,
23109 pi->
23110 tx_rx_cal_radio_saveregs[(core * 11) +
23111 10]);
23112 }
23113 } else {
23114
23115 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
23116 pi->tx_rx_cal_radio_saveregs[0]);
23117 write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
23118 pi->tx_rx_cal_radio_saveregs[1]);
23119 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
23120 pi->tx_rx_cal_radio_saveregs[2]);
23121 write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
23122 pi->tx_rx_cal_radio_saveregs[3]);
23123 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
23124 pi->tx_rx_cal_radio_saveregs[4]);
23125 write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
23126 pi->tx_rx_cal_radio_saveregs[5]);
23127 }
23128}
23129
23130static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi)
23131{
23132 u16 val, mask;
23133
23134 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23135 pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
23136 pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
23137
23138 mask = ((0x3 << 8) | (0x3 << 10));
23139 val = (0x2 << 8);
23140 val |= (0x2 << 10);
23141 mod_phy_reg(pi, 0xa6, mask, val);
23142 mod_phy_reg(pi, 0xa7, mask, val);
23143
23144 val = read_phy_reg(pi, 0x8f);
23145 pi->tx_rx_cal_phy_saveregs[2] = val;
23146 val |= ((0x1 << 9) | (0x1 << 10));
23147 write_phy_reg(pi, 0x8f, val);
23148
23149 val = read_phy_reg(pi, 0xa5);
23150 pi->tx_rx_cal_phy_saveregs[3] = val;
23151 val |= ((0x1 << 9) | (0x1 << 10));
23152 write_phy_reg(pi, 0xa5, val);
23153
23154 pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01);
23155 mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
23156
23157 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
23158 &val);
23159 pi->tx_rx_cal_phy_saveregs[5] = val;
23160 val = 0;
23161 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
23162 &val);
23163
23164 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
23165 &val);
23166 pi->tx_rx_cal_phy_saveregs[6] = val;
23167 val = 0;
23168 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
23169 &val);
23170
23171 pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91);
23172 pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92);
23173
23174 if (!(pi->use_int_tx_iqlo_cal_nphy)) {
23175
23176 wlc_phy_rfctrlintc_override_nphy(pi,
23177 NPHY_RfctrlIntc_override_PA,
23178 1,
23179 RADIO_MIMO_CORESEL_CORE1
23180 |
23181 RADIO_MIMO_CORESEL_CORE2);
23182 } else {
23183
23184 wlc_phy_rfctrlintc_override_nphy(pi,
23185 NPHY_RfctrlIntc_override_PA,
23186 0,
23187 RADIO_MIMO_CORESEL_CORE1
23188 |
23189 RADIO_MIMO_CORESEL_CORE2);
23190 }
23191
23192 wlc_phy_rfctrlintc_override_nphy(pi,
23193 NPHY_RfctrlIntc_override_TRSW,
23194 0x2, RADIO_MIMO_CORESEL_CORE1);
23195 wlc_phy_rfctrlintc_override_nphy(pi,
23196 NPHY_RfctrlIntc_override_TRSW,
23197 0x8, RADIO_MIMO_CORESEL_CORE2);
23198
23199 pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
23200 pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
23201 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
23202 0x29b, (0x1 << 0), (0) << 0);
23203
23204 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
23205 0x29b, (0x1 << 0), (0) << 0);
23206
23207 if (NREV_IS(pi->pubpi.phy_rev, 7)
23208 || NREV_GE(pi->pubpi.phy_rev, 8)) {
23209 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
23210 wlc_phy_read_lpf_bw_ctl_nphy
23211 (pi, 0), 0, 0,
23212 NPHY_REV7_RFCTRLOVERRIDE_ID1);
23213 }
23214
23215 if (pi->use_int_tx_iqlo_cal_nphy
23216 && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
23217
23218 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
23219
23220 mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
23221 1 << 4);
23222
23223 if (CHSPEC_IS2G(pi->radio_chanspec)) {
23224 mod_radio_reg(pi,
23225 RADIO_2057_PAD2G_TUNE_PUS_CORE0,
23226 1, 0);
23227 mod_radio_reg(pi,
23228 RADIO_2057_PAD2G_TUNE_PUS_CORE1,
23229 1, 0);
23230 } else {
23231 mod_radio_reg(pi,
23232 RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
23233 1, 0);
23234 mod_radio_reg(pi,
23235 RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
23236 1, 0);
23237 }
23238 } else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
23239 wlc_phy_rfctrl_override_nphy_rev7(pi,
23240 (0x1 << 3), 0,
23241 0x3, 0,
23242 NPHY_REV7_RFCTRLOVERRIDE_ID0);
23243 }
23244 }
23245 } else {
23246 pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
23247 pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
23248
23249 mask = ((0x3 << 12) | (0x3 << 14));
23250 val = (0x2 << 12);
23251 val |= (0x2 << 14);
23252 mod_phy_reg(pi, 0xa6, mask, val);
23253 mod_phy_reg(pi, 0xa7, mask, val);
23254
23255 val = read_phy_reg(pi, 0xa5);
23256 pi->tx_rx_cal_phy_saveregs[2] = val;
23257 val |= ((0x1 << 12) | (0x1 << 13));
23258 write_phy_reg(pi, 0xa5, val);
23259
23260 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
23261 &val);
23262 pi->tx_rx_cal_phy_saveregs[3] = val;
23263 val |= 0x2000;
23264 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
23265 &val);
23266
23267 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
23268 &val);
23269 pi->tx_rx_cal_phy_saveregs[4] = val;
23270 val |= 0x2000;
23271 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
23272 &val);
23273
23274 pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91);
23275 pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92);
23276 val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
23277 write_phy_reg(pi, 0x91, val);
23278 write_phy_reg(pi, 0x92, val);
23279 }
23280}
23281
23282static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi)
23283{
23284 u16 mask;
23285
23286 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23287 write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]);
23288 write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]);
23289 write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]);
23290 write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]);
23291 write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]);
23292
23293 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
23294 &pi->tx_rx_cal_phy_saveregs[5]);
23295 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
23296 &pi->tx_rx_cal_phy_saveregs[6]);
23297
23298 write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]);
23299 write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]);
23300
23301 write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
23302 write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
23303
23304 if (NREV_IS(pi->pubpi.phy_rev, 7)
23305 || NREV_GE(pi->pubpi.phy_rev, 8)) {
23306 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0,
23307 1,
23308 NPHY_REV7_RFCTRLOVERRIDE_ID1);
23309 }
23310
23311 wlc_phy_resetcca_nphy(pi);
23312
23313 if (pi->use_int_tx_iqlo_cal_nphy
23314 && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
23315
23316 if (NREV_IS(pi->pubpi.phy_rev, 7)) {
23317 if (CHSPEC_IS2G(pi->radio_chanspec)) {
23318 mod_radio_reg(pi,
23319 RADIO_2057_PAD2G_TUNE_PUS_CORE0,
23320 1, 1);
23321 mod_radio_reg(pi,
23322 RADIO_2057_PAD2G_TUNE_PUS_CORE1,
23323 1, 1);
23324 } else {
23325 mod_radio_reg(pi,
23326 RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
23327 1, 1);
23328 mod_radio_reg(pi,
23329 RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
23330 1, 1);
23331 }
23332
23333 mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
23334 0);
23335 } else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
23336 wlc_phy_rfctrl_override_nphy_rev7(pi,
23337 (0x1 << 3), 0,
23338 0x3, 1,
23339 NPHY_REV7_RFCTRLOVERRIDE_ID0);
23340 }
23341 }
23342 } else {
23343 mask = ((0x3 << 12) | (0x3 << 14));
23344 mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]);
23345 mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]);
23346 write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]);
23347
23348 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
23349 &pi->tx_rx_cal_phy_saveregs[3]);
23350
23351 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
23352 &pi->tx_rx_cal_phy_saveregs[4]);
23353
23354 write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]);
23355 write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]);
23356 }
23357}
23358
23359#define NPHY_CAL_TSSISAMPS 64
23360#define NPHY_TEST_TONE_FREQ_40MHz 4000
23361#define NPHY_TEST_TONE_FREQ_20MHz 2500
23362
23363void
23364wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps)
23365{
23366 u16 tssi_reg;
23367 s32 temp, pwrindex[2];
23368 s32 idle_tssi[2];
23369 s32 rssi_buf[4];
23370 s32 tssival[2];
23371 u8 tssi_type;
23372
23373 tssi_reg = read_phy_reg(pi, 0x1e9);
23374
23375 temp = (s32) (tssi_reg & 0x3f);
23376 idle_tssi[0] = (temp <= 31) ? temp : (temp - 64);
23377
23378 temp = (s32) ((tssi_reg >> 8) & 0x3f);
23379 idle_tssi[1] = (temp <= 31) ? temp : (temp - 64);
23380
23381 tssi_type =
23382 CHSPEC_IS5G(pi->radio_chanspec) ?
23383 (u8)NPHY_RSSI_SEL_TSSI_5G : (u8)NPHY_RSSI_SEL_TSSI_2G;
23384
23385 wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps);
23386
23387 tssival[0] = rssi_buf[0] / ((s32) num_samps);
23388 tssival[1] = rssi_buf[2] / ((s32) num_samps);
23389
23390 pwrindex[0] = idle_tssi[0] - tssival[0] + 64;
23391 pwrindex[1] = idle_tssi[1] - tssival[1] + 64;
23392
23393 if (pwrindex[0] < 0) {
23394 pwrindex[0] = 0;
23395 } else if (pwrindex[0] > 63) {
23396 pwrindex[0] = 63;
23397 }
23398
23399 if (pwrindex[1] < 0) {
23400 pwrindex[1] = 0;
23401 } else if (pwrindex[1] > 63) {
23402 pwrindex[1] = 63;
23403 }
23404
23405 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1,
23406 (u32) pwrindex[0], 32, &qdBm_pwrbuf[0]);
23407 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1,
23408 (u32) pwrindex[1], 32, &qdBm_pwrbuf[1]);
23409}
23410
23411static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi)
23412{
23413 u16 txcal_gain[2];
23414
23415 pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0];
23416 pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0];
23417 wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
23418 wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
23419
23420 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
23421 txcal_gain);
23422
23423 if (CHSPEC_IS2G(pi->radio_chanspec)) {
23424 txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40;
23425 txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40;
23426 } else {
23427 txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60;
23428 txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60;
23429 }
23430
23431 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
23432 txcal_gain);
23433}
23434
23435static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi)
23436{
23437 bool save_bbmult = false;
23438 u8 txcal_index_2057_rev5n7 = 0;
23439 u8 txcal_index_2057_rev3n4n6 = 10;
23440
23441 if (pi->use_int_tx_iqlo_cal_nphy) {
23442 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
23443 if ((pi->pubpi.radiorev == 3) ||
23444 (pi->pubpi.radiorev == 4) ||
23445 (pi->pubpi.radiorev == 6)) {
23446
23447 pi->nphy_txcal_pwr_idx[0] =
23448 txcal_index_2057_rev3n4n6;
23449 pi->nphy_txcal_pwr_idx[1] =
23450 txcal_index_2057_rev3n4n6;
23451 wlc_phy_txpwr_index_nphy(pi, 3,
23452 txcal_index_2057_rev3n4n6,
23453 false);
23454 } else {
23455
23456 pi->nphy_txcal_pwr_idx[0] =
23457 txcal_index_2057_rev5n7;
23458 pi->nphy_txcal_pwr_idx[1] =
23459 txcal_index_2057_rev5n7;
23460 wlc_phy_txpwr_index_nphy(pi, 3,
23461 txcal_index_2057_rev5n7,
23462 false);
23463 }
23464 save_bbmult = true;
23465
23466 } else if (NREV_LT(pi->pubpi.phy_rev, 5)) {
23467 wlc_phy_cal_txgainctrl_nphy(pi, 11, false);
23468 if (pi->sh->hw_phytxchain != 3) {
23469 pi->nphy_txcal_pwr_idx[1] =
23470 pi->nphy_txcal_pwr_idx[0];
23471 wlc_phy_txpwr_index_nphy(pi, 3,
23472 pi->
23473 nphy_txcal_pwr_idx[0],
23474 true);
23475 save_bbmult = true;
23476 }
23477
23478 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
23479 if (PHY_IPA(pi)) {
23480 if (CHSPEC_IS2G(pi->radio_chanspec)) {
23481 wlc_phy_cal_txgainctrl_nphy(pi, 12,
23482 false);
23483 } else {
23484 pi->nphy_txcal_pwr_idx[0] = 80;
23485 pi->nphy_txcal_pwr_idx[1] = 80;
23486 wlc_phy_txpwr_index_nphy(pi, 3, 80,
23487 false);
23488 save_bbmult = true;
23489 }
23490 } else {
23491
23492 wlc_phy_internal_cal_txgain_nphy(pi);
23493 save_bbmult = true;
23494 }
23495
23496 } else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
23497 if (PHY_IPA(pi)) {
23498 if (CHSPEC_IS2G(pi->radio_chanspec)) {
23499 wlc_phy_cal_txgainctrl_nphy(pi, 12,
23500 false);
23501 } else {
23502 wlc_phy_cal_txgainctrl_nphy(pi, 14,
23503 false);
23504 }
23505 } else {
23506
23507 wlc_phy_internal_cal_txgain_nphy(pi);
23508 save_bbmult = true;
23509 }
23510 }
23511
23512 } else {
23513 wlc_phy_cal_txgainctrl_nphy(pi, 10, false);
23514 }
23515
23516 if (save_bbmult) {
23517 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
23518 &pi->nphy_txcal_bbmult);
23519 }
23520}
23521
23522void
23523wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower,
23524 bool debug)
23525{
23526 int gainctrl_loopidx;
23527 uint core;
23528 u16 m0m1, curr_m0m1;
23529 s32 delta_power;
23530 s32 txpwrindex;
23531 s32 qdBm_power[2];
23532 u16 orig_BBConfig;
23533 u16 phy_saveregs[4];
23534 u32 freq_test;
23535 u16 ampl_test = 250;
23536 uint stepsize;
23537 bool phyhang_avoid_state = false;
23538
23539 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
23540
23541 stepsize = 2;
23542 } else {
23543
23544 stepsize = 1;
23545 }
23546
23547 if (CHSPEC_IS40(pi->radio_chanspec)) {
23548 freq_test = 5000;
23549 } else {
23550 freq_test = 2500;
23551 }
23552
23553 wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
23554 wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
23555
23556 if (pi->phyhang_avoid)
23557 wlc_phy_stay_in_carriersearch_nphy(pi, true);
23558
23559 phyhang_avoid_state = pi->phyhang_avoid;
23560 pi->phyhang_avoid = false;
23561
23562 phy_saveregs[0] = read_phy_reg(pi, 0x91);
23563 phy_saveregs[1] = read_phy_reg(pi, 0x92);
23564 phy_saveregs[2] = read_phy_reg(pi, 0xe7);
23565 phy_saveregs[3] = read_phy_reg(pi, 0xec);
23566 wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1,
23567 RADIO_MIMO_CORESEL_CORE1 |
23568 RADIO_MIMO_CORESEL_CORE2);
23569
23570 if (!debug) {
23571 wlc_phy_rfctrlintc_override_nphy(pi,
23572 NPHY_RfctrlIntc_override_TRSW,
23573 0x2, RADIO_MIMO_CORESEL_CORE1);
23574 wlc_phy_rfctrlintc_override_nphy(pi,
23575 NPHY_RfctrlIntc_override_TRSW,
23576 0x8, RADIO_MIMO_CORESEL_CORE2);
23577 } else {
23578 wlc_phy_rfctrlintc_override_nphy(pi,
23579 NPHY_RfctrlIntc_override_TRSW,
23580 0x1, RADIO_MIMO_CORESEL_CORE1);
23581 wlc_phy_rfctrlintc_override_nphy(pi,
23582 NPHY_RfctrlIntc_override_TRSW,
23583 0x7, RADIO_MIMO_CORESEL_CORE2);
23584 }
23585
23586 orig_BBConfig = read_phy_reg(pi, 0x01);
23587 mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
23588
23589 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
23590
23591 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
23592 txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core];
23593
23594 for (gainctrl_loopidx = 0; gainctrl_loopidx < 2;
23595 gainctrl_loopidx++) {
23596 wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
23597 false);
23598
23599 if (core == PHY_CORE_0) {
23600 curr_m0m1 = m0m1 & 0xff00;
23601 } else {
23602 curr_m0m1 = m0m1 & 0x00ff;
23603 }
23604
23605 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1);
23606 wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1);
23607
23608 udelay(50);
23609
23610 wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
23611 NPHY_CAL_TSSISAMPS);
23612
23613 pi->nphy_bb_mult_save = 0;
23614 wlc_phy_stopplayback_nphy(pi);
23615
23616 delta_power = (dBm_targetpower * 4) - qdBm_power[core];
23617
23618 txpwrindex -= stepsize * delta_power;
23619 if (txpwrindex < 0) {
23620 txpwrindex = 0;
23621 } else if (txpwrindex > 127) {
23622 txpwrindex = 127;
23623 }
23624
23625 if (CHSPEC_IS5G(pi->radio_chanspec)) {
23626 if (NREV_IS(pi->pubpi.phy_rev, 4) &&
23627 (pi->srom_fem5g.extpagain == 3)) {
23628 if (txpwrindex < 30) {
23629 txpwrindex = 30;
23630 }
23631 }
23632 } else {
23633 if (NREV_GE(pi->pubpi.phy_rev, 5) &&
23634 (pi->srom_fem2g.extpagain == 3)) {
23635 if (txpwrindex < 50) {
23636 txpwrindex = 50;
23637 }
23638 }
23639 }
23640
23641 wlc_phy_txpwr_index_nphy(pi, (1 << core),
23642 (u8) txpwrindex, true);
23643 }
23644
23645 pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex;
23646
23647 if (debug) {
23648 u16 radio_gain;
23649 u16 dbg_m0m1;
23650
23651 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
23652
23653 wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
23654 false);
23655
23656 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
23657 wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1);
23658
23659 udelay(100);
23660
23661 wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
23662 NPHY_CAL_TSSISAMPS);
23663
23664 wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16,
23665 &radio_gain);
23666
23667 mdelay(4000);
23668 pi->nphy_bb_mult_save = 0;
23669 wlc_phy_stopplayback_nphy(pi);
23670 }
23671 }
23672
23673 wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true);
23674 wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true);
23675
23676 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult);
23677
23678 write_phy_reg(pi, 0x01, orig_BBConfig);
23679
23680 write_phy_reg(pi, 0x91, phy_saveregs[0]);
23681 write_phy_reg(pi, 0x92, phy_saveregs[1]);
23682 write_phy_reg(pi, 0xe7, phy_saveregs[2]);
23683 write_phy_reg(pi, 0xec, phy_saveregs[3]);
23684
23685 pi->phyhang_avoid = phyhang_avoid_state;
23686
23687 if (pi->phyhang_avoid)
23688 wlc_phy_stay_in_carriersearch_nphy(pi, false);
23689}
23690
23691static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core)
23692{
23693 int index;
23694 u32 bbmult_scale;
23695 u16 bbmult;
23696 u16 tblentry;
23697
23698 struct nphy_txiqcal_ladder ladder_lo[] = {
23699 {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
23700 {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
23701 {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
23702 };
23703
23704 struct nphy_txiqcal_ladder ladder_iq[] = {
23705 {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
23706 {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
23707 {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
23708 };
23709
23710 bbmult = (core == PHY_CORE_0) ?
23711 ((pi->nphy_txcal_bbmult >> 8) & 0xff) : (pi->
23712 nphy_txcal_bbmult & 0xff);
23713
23714 for (index = 0; index < 18; index++) {
23715 bbmult_scale = ladder_lo[index].percent * bbmult;
23716 bbmult_scale /= 100;
23717
23718 tblentry =
23719 ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env;
23720 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16,
23721 &tblentry);
23722
23723 bbmult_scale = ladder_iq[index].percent * bbmult;
23724 bbmult_scale /= 100;
23725
23726 tblentry =
23727 ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env;
23728 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32,
23729 16, &tblentry);
23730 }
23731}
23732
23733void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype)
23734{
23735 struct nphy_txgains target_gain;
23736 u8 tx_pwr_ctrl_state;
23737 bool fullcal = true;
23738 bool restore_tx_gain = false;
23739 bool mphase;
23740
23741 if (NORADIO_ENAB(pi->pubpi)) {
23742 wlc_phy_cal_perical_mphase_reset(pi);
23743 return;
23744 }
23745
23746 if (PHY_MUTED(pi))
23747 return;
23748
23749 if (caltype == PHY_PERICAL_AUTO)
23750 fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
23751 else if (caltype == PHY_PERICAL_PARTIAL)
23752 fullcal = false;
23753
23754 if (pi->cal_type_override != PHY_PERICAL_AUTO) {
23755 fullcal =
23756 (pi->cal_type_override == PHY_PERICAL_FULL) ? true : false;
23757 }
23758
23759 if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) {
23760 if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec)
23761 wlc_phy_cal_perical_mphase_restart(pi);
23762 }
23763
23764 if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) {
23765 wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
23766 }
23767
23768 wlapi_suspend_mac_and_wait(pi->sh->physhim);
23769
23770 wlc_phyreg_enter((struct brcms_phy_pub *) pi);
23771
23772 if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) ||
23773 (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) {
23774 pi->nphy_cal_orig_pwr_idx[0] =
23775 (u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f);
23776 pi->nphy_cal_orig_pwr_idx[1] =
23777 (u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f);
23778
23779 if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) {
23780 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2,
23781 0x110, 16,
23782 pi->nphy_cal_orig_tx_gain);
23783 } else {
23784 pi->nphy_cal_orig_tx_gain[0] = 0;
23785 pi->nphy_cal_orig_tx_gain[1] = 0;
23786 }
23787 }
23788 target_gain = wlc_phy_get_tx_gain_nphy(pi);
23789 tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
23790 wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
23791
23792 if (pi->antsel_type == ANTSEL_2x3)
23793 wlc_phy_antsel_init((struct brcms_phy_pub *) pi, true);
23794
23795 mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE);
23796 if (!mphase) {
23797
23798 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23799 wlc_phy_precal_txgain_nphy(pi);
23800 pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
23801 restore_tx_gain = true;
23802
23803 target_gain = pi->nphy_cal_target_gain;
23804 }
23805 if (0 ==
23806 wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) {
23807 if (PHY_IPA(pi))
23808 wlc_phy_a4(pi, true);
23809
23810 wlc_phyreg_exit((struct brcms_phy_pub *) pi);
23811 wlapi_enable_mac(pi->sh->physhim);
23812 wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION,
23813 10000);
23814 wlapi_suspend_mac_and_wait(pi->sh->physhim);
23815 wlc_phyreg_enter((struct brcms_phy_pub *) pi);
23816
23817 if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain,
23818 (pi->
23819 first_cal_after_assoc
23820 || (pi->
23821 cal_type_override
23822 ==
23823 PHY_PERICAL_FULL))
23824 ? 2 : 0, false)) {
23825 wlc_phy_savecal_nphy(pi);
23826
23827 wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
23828
23829 pi->nphy_perical_last = pi->sh->now;
23830 }
23831 }
23832 if (caltype != PHY_PERICAL_AUTO) {
23833 wlc_phy_rssi_cal_nphy(pi);
23834 }
23835
23836 if (pi->first_cal_after_assoc
23837 || (pi->cal_type_override == PHY_PERICAL_FULL)) {
23838 pi->first_cal_after_assoc = false;
23839 wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
23840 wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
23841 }
23842
23843 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23844 wlc_phy_radio205x_vcocal_nphy(pi);
23845 }
23846 } else {
23847 switch (pi->mphase_cal_phase_id) {
23848 case MPHASE_CAL_STATE_INIT:
23849 pi->nphy_perical_last = pi->sh->now;
23850 pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
23851
23852 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23853 wlc_phy_precal_txgain_nphy(pi);
23854 }
23855 pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
23856 pi->mphase_cal_phase_id++;
23857 break;
23858
23859 case MPHASE_CAL_STATE_TXPHASE0:
23860 case MPHASE_CAL_STATE_TXPHASE1:
23861 case MPHASE_CAL_STATE_TXPHASE2:
23862 case MPHASE_CAL_STATE_TXPHASE3:
23863 case MPHASE_CAL_STATE_TXPHASE4:
23864 case MPHASE_CAL_STATE_TXPHASE5:
23865 if ((pi->radar_percal_mask & 0x10) != 0)
23866 pi->nphy_rxcal_active = true;
23867
23868 if (wlc_phy_cal_txiqlo_nphy
23869 (pi, pi->nphy_cal_target_gain, fullcal,
23870 true) != 0) {
23871
23872 wlc_phy_cal_perical_mphase_reset(pi);
23873 break;
23874 }
23875
23876 if (NREV_LE(pi->pubpi.phy_rev, 2) &&
23877 (pi->mphase_cal_phase_id ==
23878 MPHASE_CAL_STATE_TXPHASE4)) {
23879 pi->mphase_cal_phase_id += 2;
23880 } else {
23881 pi->mphase_cal_phase_id++;
23882 }
23883 break;
23884
23885 case MPHASE_CAL_STATE_PAPDCAL:
23886 if ((pi->radar_percal_mask & 0x2) != 0)
23887 pi->nphy_rxcal_active = true;
23888
23889 if (PHY_IPA(pi)) {
23890 wlc_phy_a4(pi, true);
23891 }
23892 pi->mphase_cal_phase_id++;
23893 break;
23894
23895 case MPHASE_CAL_STATE_RXCAL:
23896 if ((pi->radar_percal_mask & 0x1) != 0)
23897 pi->nphy_rxcal_active = true;
23898 if (wlc_phy_cal_rxiq_nphy(pi, target_gain,
23899 (pi->first_cal_after_assoc ||
23900 (pi->cal_type_override ==
23901 PHY_PERICAL_FULL)) ? 2 : 0,
23902 false) == 0) {
23903 wlc_phy_savecal_nphy(pi);
23904 }
23905
23906 pi->mphase_cal_phase_id++;
23907 break;
23908
23909 case MPHASE_CAL_STATE_RSSICAL:
23910 if ((pi->radar_percal_mask & 0x4) != 0)
23911 pi->nphy_rxcal_active = true;
23912 wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
23913 wlc_phy_rssi_cal_nphy(pi);
23914
23915 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23916 wlc_phy_radio205x_vcocal_nphy(pi);
23917 }
23918 restore_tx_gain = true;
23919
23920 if (pi->first_cal_after_assoc) {
23921 pi->mphase_cal_phase_id++;
23922 } else {
23923 wlc_phy_cal_perical_mphase_reset(pi);
23924 }
23925
23926 break;
23927
23928 case MPHASE_CAL_STATE_IDLETSSI:
23929 if ((pi->radar_percal_mask & 0x8) != 0)
23930 pi->nphy_rxcal_active = true;
23931
23932 if (pi->first_cal_after_assoc) {
23933 pi->first_cal_after_assoc = false;
23934 wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
23935 wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
23936 }
23937
23938 wlc_phy_cal_perical_mphase_reset(pi);
23939 break;
23940
23941 default:
23942 wlc_phy_cal_perical_mphase_reset(pi);
23943 break;
23944 }
23945 }
23946
23947 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
23948 if (restore_tx_gain) {
23949 if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) {
23950
23951 wlc_phy_txpwr_index_nphy(pi, 1,
23952 pi->
23953 nphy_cal_orig_pwr_idx
23954 [0], false);
23955 wlc_phy_txpwr_index_nphy(pi, 2,
23956 pi->
23957 nphy_cal_orig_pwr_idx
23958 [1], false);
23959
23960 pi->nphy_txpwrindex[0].index = -1;
23961 pi->nphy_txpwrindex[1].index = -1;
23962 } else {
23963 wlc_phy_txpwr_index_nphy(pi, (1 << 0),
23964 (s8) (pi->
23965 nphy_txpwrindex
23966 [0].
23967 index_internal),
23968 false);
23969 wlc_phy_txpwr_index_nphy(pi, (1 << 1),
23970 (s8) (pi->
23971 nphy_txpwrindex
23972 [1].
23973 index_internal),
23974 false);
23975 }
23976 }
23977 }
23978
23979 wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
23980 wlc_phyreg_exit((struct brcms_phy_pub *) pi);
23981 wlapi_enable_mac(pi->sh->physhim);
23982}
23983
23984int
23985wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
23986 bool fullcal, bool mphase)
23987{
23988 u16 val;
23989 u16 tbl_buf[11];
23990 u8 cal_cnt;
23991 u16 cal_cmd;
23992 u8 num_cals, max_cal_cmds;
23993 u16 core_no, cal_type;
23994 u16 diq_start = 0;
23995 u8 phy_bw;
23996 u16 max_val;
23997 u16 tone_freq;
23998 u16 gain_save[2];
23999 u16 cal_gain[2];
24000 struct nphy_iqcal_params cal_params[2];
24001 u32 tbl_len;
24002 void *tbl_ptr;
24003 bool ladder_updated[2];
24004 u8 mphase_cal_lastphase = 0;
24005 int bcmerror = 0;
24006 bool phyhang_avoid_state = false;
24007
24008 u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
24009 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
24010 0x1902,
24011 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
24012 0x6407
24013 };
24014
24015 u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
24016 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
24017 0x3200,
24018 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
24019 0x6407
24020 };
24021
24022 u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
24023 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
24024 0x1202,
24025 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
24026 0x4707
24027 };
24028
24029 u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
24030 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
24031 0x2300,
24032 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
24033 0x4707
24034 };
24035
24036 u16 tbl_tx_iqlo_cal_startcoefs[] = {
24037 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
24038 0x0000
24039 };
24040
24041 u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
24042 0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
24043 0x9123, 0x9264, 0x9086, 0x9245, 0x9056
24044 };
24045
24046 u16 tbl_tx_iqlo_cal_cmds_recal[] = {
24047 0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
24048 0x9101, 0x9253, 0x9053, 0x9234, 0x9034
24049 };
24050
24051 u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
24052 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
24053 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
24054 0x0000
24055 };
24056
24057 u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
24058 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
24059 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
24060 };
24061
24062 u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
24063 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
24064 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
24065 };
24066
24067 wlc_phy_stay_in_carriersearch_nphy(pi, true);
24068
24069 if (NREV_GE(pi->pubpi.phy_rev, 4)) {
24070 phyhang_avoid_state = pi->phyhang_avoid;
24071 pi->phyhang_avoid = false;
24072 }
24073
24074 if (CHSPEC_IS40(pi->radio_chanspec)) {
24075 phy_bw = 40;
24076 } else {
24077 phy_bw = 20;
24078 }
24079
24080 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
24081
24082 for (core_no = 0; core_no <= 1; core_no++) {
24083 wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
24084 &cal_params[core_no]);
24085 cal_gain[core_no] = cal_params[core_no].cal_gain;
24086 }
24087
24088 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
24089
24090 wlc_phy_txcal_radio_setup_nphy(pi);
24091
24092 wlc_phy_txcal_physetup_nphy(pi);
24093
24094 ladder_updated[0] = ladder_updated[1] = false;
24095 if (!(NREV_GE(pi->pubpi.phy_rev, 6) ||
24096 (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi)
24097 && (CHSPEC_IS2G(pi->radio_chanspec))))) {
24098
24099 if (phy_bw == 40) {
24100 tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40;
24101 tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40);
24102 } else {
24103 tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20;
24104 tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20);
24105 }
24106 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0,
24107 16, tbl_ptr);
24108
24109 if (phy_bw == 40) {
24110 tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40;
24111 tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40);
24112 } else {
24113 tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20;
24114 tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20);
24115 }
24116 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32,
24117 16, tbl_ptr);
24118 }
24119
24120 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
24121 write_phy_reg(pi, 0xc2, 0x8ad9);
24122 } else {
24123 write_phy_reg(pi, 0xc2, 0x8aa9);
24124 }
24125
24126 max_val = 250;
24127 tone_freq = (phy_bw == 20) ? 2500 : 5000;
24128
24129 if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
24130 wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false);
24131 bcmerror = 0;
24132 } else {
24133 bcmerror =
24134 wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, false);
24135 }
24136
24137 if (bcmerror == 0) {
24138
24139 if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
24140 tbl_ptr = pi->mphase_txcal_bestcoeffs;
24141 tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
24142 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
24143
24144 tbl_len -= 2;
24145 }
24146 } else {
24147 if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) {
24148
24149 tbl_ptr = pi->nphy_txiqlocal_bestc;
24150 tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
24151 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
24152
24153 tbl_len -= 2;
24154 }
24155 } else {
24156
24157 fullcal = true;
24158
24159 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
24160 tbl_ptr =
24161 tbl_tx_iqlo_cal_startcoefs_nphyrev3;
24162 tbl_len =
24163 ARRAY_SIZE
24164 (tbl_tx_iqlo_cal_startcoefs_nphyrev3);
24165 } else {
24166 tbl_ptr = tbl_tx_iqlo_cal_startcoefs;
24167 tbl_len =
24168 ARRAY_SIZE
24169 (tbl_tx_iqlo_cal_startcoefs);
24170 }
24171 }
24172 }
24173 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64,
24174 16, tbl_ptr);
24175
24176 if (fullcal) {
24177 max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
24178 ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) :
24179 ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal);
24180 } else {
24181 max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
24182 ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal_nphyrev3) :
24183 ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal);
24184 }
24185
24186 if (mphase) {
24187 cal_cnt = pi->mphase_txcal_cmdidx;
24188 if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds) {
24189 num_cals = cal_cnt + pi->mphase_txcal_numcmds;
24190 } else {
24191 num_cals = max_cal_cmds;
24192 }
24193 } else {
24194 cal_cnt = 0;
24195 num_cals = max_cal_cmds;
24196 }
24197
24198 for (; cal_cnt < num_cals; cal_cnt++) {
24199
24200 if (fullcal) {
24201 cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
24202 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3
24203 [cal_cnt] :
24204 tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt];
24205 } else {
24206 cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
24207 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[cal_cnt]
24208 : tbl_tx_iqlo_cal_cmds_recal[cal_cnt];
24209 }
24210
24211 core_no = ((cal_cmd & 0x3000) >> 12);
24212 cal_type = ((cal_cmd & 0x0F00) >> 8);
24213
24214 if (NREV_GE(pi->pubpi.phy_rev, 6) ||
24215 (NREV_IS(pi->pubpi.phy_rev, 5) &&
24216 PHY_IPA(pi)
24217 && (CHSPEC_IS2G(pi->radio_chanspec)))) {
24218 if (!ladder_updated[core_no]) {
24219 wlc_phy_update_txcal_ladder_nphy(pi,
24220 core_no);
24221 ladder_updated[core_no] = true;
24222 }
24223 }
24224
24225 val =
24226 (cal_params[core_no].
24227 ncorr[cal_type] << 8) | NPHY_N_GCTL;
24228 write_phy_reg(pi, 0xc1, val);
24229
24230 if ((cal_type == 1) || (cal_type == 3)
24231 || (cal_type == 4)) {
24232
24233 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
24234 1, 69 + core_no, 16,
24235 tbl_buf);
24236
24237 diq_start = tbl_buf[0];
24238
24239 tbl_buf[0] = 0;
24240 wlc_phy_table_write_nphy(pi,
24241 NPHY_TBL_ID_IQLOCAL, 1,
24242 69 + core_no, 16,
24243 tbl_buf);
24244 }
24245
24246 write_phy_reg(pi, 0xc0, cal_cmd);
24247
24248 SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
24249 20000);
24250 if (WARN(read_phy_reg(pi, 0xc0) & 0xc000,
24251 "HW error: txiq calib"))
24252 return -EIO;
24253
24254 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
24255 tbl_len, 96, 16, tbl_buf);
24256 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL,
24257 tbl_len, 64, 16, tbl_buf);
24258
24259 if ((cal_type == 1) || (cal_type == 3)
24260 || (cal_type == 4)) {
24261
24262 tbl_buf[0] = diq_start;
24263
24264 }
24265
24266 }
24267
24268 if (mphase) {
24269 pi->mphase_txcal_cmdidx = num_cals;
24270 if (pi->mphase_txcal_cmdidx >= max_cal_cmds)
24271 pi->mphase_txcal_cmdidx = 0;
24272 }
24273
24274 mphase_cal_lastphase =
24275 (NREV_LE(pi->pubpi.phy_rev, 2)) ?
24276 MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5;
24277
24278 if (!mphase
24279 || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) {
24280
24281 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96,
24282 16, tbl_buf);
24283 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
24284 16, tbl_buf);
24285
24286 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
24287
24288 tbl_buf[0] = 0;
24289 tbl_buf[1] = 0;
24290 tbl_buf[2] = 0;
24291 tbl_buf[3] = 0;
24292
24293 }
24294 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
24295 16, tbl_buf);
24296
24297 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101,
24298 16, tbl_buf);
24299 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
24300 16, tbl_buf);
24301
24302 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
24303 16, tbl_buf);
24304
24305 tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
24306 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
24307
24308 tbl_len -= 2;
24309 }
24310 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
24311 tbl_len, 96, 16,
24312 pi->nphy_txiqlocal_bestc);
24313
24314 pi->nphy_txiqlocal_coeffsvalid = true;
24315 pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
24316 } else {
24317 tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
24318 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
24319
24320 tbl_len -= 2;
24321 }
24322 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
24323 tbl_len, 96, 16,
24324 pi->mphase_txcal_bestcoeffs);
24325 }
24326
24327 wlc_phy_stopplayback_nphy(pi);
24328
24329 write_phy_reg(pi, 0xc2, 0x0000);
24330
24331 }
24332
24333 wlc_phy_txcal_phycleanup_nphy(pi);
24334
24335 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
24336 gain_save);
24337
24338 wlc_phy_txcal_radio_cleanup_nphy(pi);
24339
24340 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
24341 if (!mphase
24342 || (pi->mphase_cal_phase_id == mphase_cal_lastphase))
24343 wlc_phy_tx_iq_war_nphy(pi);
24344 }
24345
24346 if (NREV_GE(pi->pubpi.phy_rev, 4)) {
24347 pi->phyhang_avoid = phyhang_avoid_state;
24348 }
24349
24350 wlc_phy_stay_in_carriersearch_nphy(pi, false);
24351
24352 return bcmerror;
24353}
24354
24355static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi)
24356{
24357 u16 tbl_buf[7];
24358
24359 if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
24360 (pi->nphy_txiqlocal_coeffsvalid)) {
24361 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
24362 ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf);
24363
24364 if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) ||
24365 (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) ||
24366 (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) ||
24367 (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) {
24368
24369 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
24370 16, pi->nphy_txiqlocal_bestc);
24371
24372 tbl_buf[0] = 0;
24373 tbl_buf[1] = 0;
24374 tbl_buf[2] = 0;
24375 tbl_buf[3] = 0;
24376 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
24377 16, tbl_buf);
24378
24379 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
24380 16,
24381 &pi->nphy_txiqlocal_bestc[5]);
24382
24383 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
24384 16,
24385 &pi->nphy_txiqlocal_bestc[5]);
24386 }
24387 }
24388}
24389
24390static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi)
24391{
24392 struct nphy_iq_comp tx_comp;
24393
24394 wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, (void *)&tx_comp);
24395
24396 wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0);
24397 wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0);
24398 wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1);
24399 wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1);
24400}
24401
24402void
24403wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
24404 struct nphy_iq_comp *pcomp)
24405{
24406 if (write) {
24407 write_phy_reg(pi, 0x9a, pcomp->a0);
24408 write_phy_reg(pi, 0x9b, pcomp->b0);
24409 write_phy_reg(pi, 0x9c, pcomp->a1);
24410 write_phy_reg(pi, 0x9d, pcomp->b1);
24411 } else {
24412 pcomp->a0 = read_phy_reg(pi, 0x9a);
24413 pcomp->b0 = read_phy_reg(pi, 0x9b);
24414 pcomp->a1 = read_phy_reg(pi, 0x9c);
24415 pcomp->b1 = read_phy_reg(pi, 0x9d);
24416 }
24417}
24418
24419void
24420wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
24421 u16 num_samps, u8 wait_time, u8 wait_for_crs)
24422{
24423 u8 core;
24424
24425 write_phy_reg(pi, 0x12b, num_samps);
24426 mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0));
24427 mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode,
24428 (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0);
24429
24430 mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart);
24431
24432 SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
24433 10000);
24434 if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart,
24435 "HW error: rxiq est"))
24436 return;
24437
24438 if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
24439 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
24440 est[core].i_pwr =
24441 (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16)
24442 | read_phy_reg(pi, NPHY_IqestipwrAccLo(core));
24443 est[core].q_pwr =
24444 (read_phy_reg(pi, NPHY_IqestqpwrAccHi(core)) << 16)
24445 | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core));
24446 est[core].iq_prod =
24447 (read_phy_reg(pi, NPHY_IqestIqAccHi(core)) << 16) |
24448 read_phy_reg(pi, NPHY_IqestIqAccLo(core));
24449 }
24450 }
24451}
24452
24453#define CAL_RETRY_CNT 2
24454static void wlc_phy_calc_rx_iq_comp_nphy(struct brcms_phy *pi, u8 core_mask)
24455{
24456 u8 curr_core;
24457 struct phy_iq_est est[PHY_CORE_MAX];
24458 struct nphy_iq_comp old_comp, new_comp;
24459 s32 iq = 0;
24460 u32 ii = 0, qq = 0;
24461 s16 iq_nbits, qq_nbits, brsh, arsh;
24462 s32 a, b, temp;
24463 int bcmerror = 0;
24464 uint cal_retry = 0;
24465
24466 if (core_mask == 0x0)
24467 return;
24468
24469 wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp);
24470 new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0;
24471 wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
24472
24473 cal_try:
24474 wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0);
24475
24476 new_comp = old_comp;
24477
24478 for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) {
24479
24480 if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
24481 iq = est[curr_core].iq_prod;
24482 ii = est[curr_core].i_pwr;
24483 qq = est[curr_core].q_pwr;
24484 } else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
24485 iq = est[curr_core].iq_prod;
24486 ii = est[curr_core].i_pwr;
24487 qq = est[curr_core].q_pwr;
24488 } else {
24489 continue;
24490 }
24491
24492 if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
24493 bcmerror = -EBADE;
24494 break;
24495 }
24496
24497 iq_nbits = wlc_phy_nbits(iq);
24498 qq_nbits = wlc_phy_nbits(qq);
24499
24500 arsh = 10 - (30 - iq_nbits);
24501 if (arsh >= 0) {
24502 a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
24503 temp = (s32) (ii >> arsh);
24504 if (temp == 0) {
24505 bcmerror = -EBADE;
24506 break;
24507 }
24508 } else {
24509 a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
24510 temp = (s32) (ii << -arsh);
24511 if (temp == 0) {
24512 bcmerror = -EBADE;
24513 break;
24514 }
24515 }
24516
24517 a /= temp;
24518
24519 brsh = qq_nbits - 31 + 20;
24520 if (brsh >= 0) {
24521 b = (qq << (31 - qq_nbits));
24522 temp = (s32) (ii >> brsh);
24523 if (temp == 0) {
24524 bcmerror = -EBADE;
24525 break;
24526 }
24527 } else {
24528 b = (qq << (31 - qq_nbits));
24529 temp = (s32) (ii << -brsh);
24530 if (temp == 0) {
24531 bcmerror = -EBADE;
24532 break;
24533 }
24534 }
24535 b /= temp;
24536 b -= a * a;
24537 b = (s32) int_sqrt((unsigned long) b);
24538 b -= (1 << 10);
24539
24540 if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
24541 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
24542 new_comp.a0 = (s16) a & 0x3ff;
24543 new_comp.b0 = (s16) b & 0x3ff;
24544 } else {
24545
24546 new_comp.a0 = (s16) b & 0x3ff;
24547 new_comp.b0 = (s16) a & 0x3ff;
24548 }
24549 }
24550 if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
24551 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
24552 new_comp.a1 = (s16) a & 0x3ff;
24553 new_comp.b1 = (s16) b & 0x3ff;
24554 } else {
24555
24556 new_comp.a1 = (s16) b & 0x3ff;
24557 new_comp.b1 = (s16) a & 0x3ff;
24558 }
24559 }
24560 }
24561
24562 if (bcmerror != 0) {
24563 printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__,
24564 cal_retry);
24565
24566 if (cal_retry < CAL_RETRY_CNT) {
24567 cal_retry++;
24568 goto cal_try;
24569 }
24570
24571 new_comp = old_comp;
24572 }
24573
24574 wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
24575}
24576
24577static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core)
24578{
24579 u16 offtune_val;
24580 u16 bias_g = 0;
24581 u16 bias_a = 0;
24582
24583 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
24584 if (rx_core == PHY_CORE_0) {
24585 if (CHSPEC_IS5G(pi->radio_chanspec)) {
24586 pi->tx_rx_cal_radio_saveregs[0] =
24587 read_radio_reg(pi,
24588 RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP);
24589 pi->tx_rx_cal_radio_saveregs[1] =
24590 read_radio_reg(pi,
24591 RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN);
24592
24593 write_radio_reg(pi,
24594 RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
24595 0x3);
24596 write_radio_reg(pi,
24597 RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
24598 0xaf);
24599
24600 } else {
24601 pi->tx_rx_cal_radio_saveregs[0] =
24602 read_radio_reg(pi,
24603 RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP);
24604 pi->tx_rx_cal_radio_saveregs[1] =
24605 read_radio_reg(pi,
24606 RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN);
24607
24608 write_radio_reg(pi,
24609 RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
24610 0x3);
24611 write_radio_reg(pi,
24612 RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
24613 0x7f);
24614 }
24615
24616 } else {
24617 if (CHSPEC_IS5G(pi->radio_chanspec)) {
24618 pi->tx_rx_cal_radio_saveregs[0] =
24619 read_radio_reg(pi,
24620 RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP);
24621 pi->tx_rx_cal_radio_saveregs[1] =
24622 read_radio_reg(pi,
24623 RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN);
24624
24625 write_radio_reg(pi,
24626 RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
24627 0x3);
24628 write_radio_reg(pi,
24629 RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
24630 0xaf);
24631
24632 } else {
24633 pi->tx_rx_cal_radio_saveregs[0] =
24634 read_radio_reg(pi,
24635 RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP);
24636 pi->tx_rx_cal_radio_saveregs[1] =
24637 read_radio_reg(pi,
24638 RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN);
24639
24640 write_radio_reg(pi,
24641 RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
24642 0x3);
24643 write_radio_reg(pi,
24644 RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
24645 0x7f);
24646 }
24647 }
24648
24649 } else {
24650 if (rx_core == PHY_CORE_0) {
24651 pi->tx_rx_cal_radio_saveregs[0] =
24652 read_radio_reg(pi,
24653 RADIO_2056_TX_RXIQCAL_TXMUX |
24654 RADIO_2056_TX1);
24655 pi->tx_rx_cal_radio_saveregs[1] =
24656 read_radio_reg(pi,
24657 RADIO_2056_RX_RXIQCAL_RXMUX |
24658 RADIO_2056_RX0);
24659
24660 if (pi->pubpi.radiorev >= 5) {
24661 pi->tx_rx_cal_radio_saveregs[2] =
24662 read_radio_reg(pi,
24663 RADIO_2056_RX_RXSPARE2 |
24664 RADIO_2056_RX0);
24665 pi->tx_rx_cal_radio_saveregs[3] =
24666 read_radio_reg(pi,
24667 RADIO_2056_TX_TXSPARE2 |
24668 RADIO_2056_TX1);
24669 }
24670
24671 if (CHSPEC_IS5G(pi->radio_chanspec)) {
24672
24673 if (pi->pubpi.radiorev >= 5) {
24674 pi->tx_rx_cal_radio_saveregs[4] =
24675 read_radio_reg(pi,
24676 RADIO_2056_RX_LNAA_MASTER
24677 | RADIO_2056_RX0);
24678
24679 write_radio_reg(pi,
24680 RADIO_2056_RX_LNAA_MASTER
24681 | RADIO_2056_RX0, 0x40);
24682
24683 write_radio_reg(pi,
24684 RADIO_2056_TX_TXSPARE2 |
24685 RADIO_2056_TX1, bias_a);
24686
24687 write_radio_reg(pi,
24688 RADIO_2056_RX_RXSPARE2 |
24689 RADIO_2056_RX0, bias_a);
24690 } else {
24691 pi->tx_rx_cal_radio_saveregs[4] =
24692 read_radio_reg(pi,
24693 RADIO_2056_RX_LNAA_TUNE
24694 | RADIO_2056_RX0);
24695
24696 offtune_val =
24697 (pi->
24698 tx_rx_cal_radio_saveregs[2] & 0xF0)
24699 >> 8;
24700 offtune_val =
24701 (offtune_val <= 0x7) ? 0xF : 0;
24702
24703 mod_radio_reg(pi,
24704 RADIO_2056_RX_LNAA_TUNE |
24705 RADIO_2056_RX0, 0xF0,
24706 (offtune_val << 8));
24707 }
24708
24709 write_radio_reg(pi,
24710 RADIO_2056_TX_RXIQCAL_TXMUX |
24711 RADIO_2056_TX1, 0x9);
24712 write_radio_reg(pi,
24713 RADIO_2056_RX_RXIQCAL_RXMUX |
24714 RADIO_2056_RX0, 0x9);
24715 } else {
24716 if (pi->pubpi.radiorev >= 5) {
24717 pi->tx_rx_cal_radio_saveregs[4] =
24718 read_radio_reg(pi,
24719 RADIO_2056_RX_LNAG_MASTER
24720 | RADIO_2056_RX0);
24721
24722 write_radio_reg(pi,
24723 RADIO_2056_RX_LNAG_MASTER
24724 | RADIO_2056_RX0, 0x40);
24725
24726 write_radio_reg(pi,
24727 RADIO_2056_TX_TXSPARE2 |
24728 RADIO_2056_TX1, bias_g);
24729
24730 write_radio_reg(pi,
24731 RADIO_2056_RX_RXSPARE2 |
24732 RADIO_2056_RX0, bias_g);
24733
24734 } else {
24735 pi->tx_rx_cal_radio_saveregs[4] =
24736 read_radio_reg(pi,
24737 RADIO_2056_RX_LNAG_TUNE
24738 | RADIO_2056_RX0);
24739
24740 offtune_val =
24741 (pi->
24742 tx_rx_cal_radio_saveregs[2] & 0xF0)
24743 >> 8;
24744 offtune_val =
24745 (offtune_val <= 0x7) ? 0xF : 0;
24746
24747 mod_radio_reg(pi,
24748 RADIO_2056_RX_LNAG_TUNE |
24749 RADIO_2056_RX0, 0xF0,
24750 (offtune_val << 8));
24751 }
24752
24753 write_radio_reg(pi,
24754 RADIO_2056_TX_RXIQCAL_TXMUX |
24755 RADIO_2056_TX1, 0x6);
24756 write_radio_reg(pi,
24757 RADIO_2056_RX_RXIQCAL_RXMUX |
24758 RADIO_2056_RX0, 0x6);
24759 }
24760
24761 } else {
24762 pi->tx_rx_cal_radio_saveregs[0] =
24763 read_radio_reg(pi,
24764 RADIO_2056_TX_RXIQCAL_TXMUX |
24765 RADIO_2056_TX0);
24766 pi->tx_rx_cal_radio_saveregs[1] =
24767 read_radio_reg(pi,
24768 RADIO_2056_RX_RXIQCAL_RXMUX |
24769 RADIO_2056_RX1);
24770
24771 if (pi->pubpi.radiorev >= 5) {
24772 pi->tx_rx_cal_radio_saveregs[2] =
24773 read_radio_reg(pi,
24774 RADIO_2056_RX_RXSPARE2 |
24775 RADIO_2056_RX1);
24776 pi->tx_rx_cal_radio_saveregs[3] =
24777 read_radio_reg(pi,
24778 RADIO_2056_TX_TXSPARE2 |
24779 RADIO_2056_TX0);
24780 }
24781
24782 if (CHSPEC_IS5G(pi->radio_chanspec)) {
24783
24784 if (pi->pubpi.radiorev >= 5) {
24785 pi->tx_rx_cal_radio_saveregs[4] =
24786 read_radio_reg(pi,
24787 RADIO_2056_RX_LNAA_MASTER
24788 | RADIO_2056_RX1);
24789
24790 write_radio_reg(pi,
24791 RADIO_2056_RX_LNAA_MASTER
24792 | RADIO_2056_RX1, 0x40);
24793
24794 write_radio_reg(pi,
24795 RADIO_2056_TX_TXSPARE2 |
24796 RADIO_2056_TX0, bias_a);
24797
24798 write_radio_reg(pi,
24799 RADIO_2056_RX_RXSPARE2 |
24800 RADIO_2056_RX1, bias_a);
24801 } else {
24802 pi->tx_rx_cal_radio_saveregs[4] =
24803 read_radio_reg(pi,
24804 RADIO_2056_RX_LNAA_TUNE
24805 | RADIO_2056_RX1);
24806
24807 offtune_val =
24808 (pi->
24809 tx_rx_cal_radio_saveregs[2] & 0xF0)
24810 >> 8;
24811 offtune_val =
24812 (offtune_val <= 0x7) ? 0xF : 0;
24813
24814 mod_radio_reg(pi,
24815 RADIO_2056_RX_LNAA_TUNE |
24816 RADIO_2056_RX1, 0xF0,
24817 (offtune_val << 8));
24818 }
24819
24820 write_radio_reg(pi,
24821 RADIO_2056_TX_RXIQCAL_TXMUX |
24822 RADIO_2056_TX0, 0x9);
24823 write_radio_reg(pi,
24824 RADIO_2056_RX_RXIQCAL_RXMUX |
24825 RADIO_2056_RX1, 0x9);
24826 } else {
24827 if (pi->pubpi.radiorev >= 5) {
24828 pi->tx_rx_cal_radio_saveregs[4] =
24829 read_radio_reg(pi,
24830 RADIO_2056_RX_LNAG_MASTER
24831 | RADIO_2056_RX1);
24832
24833 write_radio_reg(pi,
24834 RADIO_2056_RX_LNAG_MASTER
24835 | RADIO_2056_RX1, 0x40);
24836
24837 write_radio_reg(pi,
24838 RADIO_2056_TX_TXSPARE2 |
24839 RADIO_2056_TX0, bias_g);
24840
24841 write_radio_reg(pi,
24842 RADIO_2056_RX_RXSPARE2 |
24843 RADIO_2056_RX1, bias_g);
24844 } else {
24845 pi->tx_rx_cal_radio_saveregs[4] =
24846 read_radio_reg(pi,
24847 RADIO_2056_RX_LNAG_TUNE
24848 | RADIO_2056_RX1);
24849
24850 offtune_val =
24851 (pi->
24852 tx_rx_cal_radio_saveregs[2] & 0xF0)
24853 >> 8;
24854 offtune_val =
24855 (offtune_val <= 0x7) ? 0xF : 0;
24856
24857 mod_radio_reg(pi,
24858 RADIO_2056_RX_LNAG_TUNE |
24859 RADIO_2056_RX1, 0xF0,
24860 (offtune_val << 8));
24861 }
24862
24863 write_radio_reg(pi,
24864 RADIO_2056_TX_RXIQCAL_TXMUX |
24865 RADIO_2056_TX0, 0x6);
24866 write_radio_reg(pi,
24867 RADIO_2056_RX_RXIQCAL_RXMUX |
24868 RADIO_2056_RX1, 0x6);
24869 }
24870 }
24871 }
24872}
24873
24874static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core)
24875{
24876 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
24877 if (rx_core == PHY_CORE_0) {
24878 if (CHSPEC_IS5G(pi->radio_chanspec)) {
24879 write_radio_reg(pi,
24880 RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
24881 pi->
24882 tx_rx_cal_radio_saveregs[0]);
24883 write_radio_reg(pi,
24884 RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
24885 pi->
24886 tx_rx_cal_radio_saveregs[1]);
24887
24888 } else {
24889 write_radio_reg(pi,
24890 RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
24891 pi->
24892 tx_rx_cal_radio_saveregs[0]);
24893 write_radio_reg(pi,
24894 RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
24895 pi->
24896 tx_rx_cal_radio_saveregs[1]);
24897 }
24898
24899 } else {
24900 if (CHSPEC_IS5G(pi->radio_chanspec)) {
24901 write_radio_reg(pi,
24902 RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
24903 pi->
24904 tx_rx_cal_radio_saveregs[0]);
24905 write_radio_reg(pi,
24906 RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
24907 pi->
24908 tx_rx_cal_radio_saveregs[1]);
24909
24910 } else {
24911 write_radio_reg(pi,
24912 RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
24913 pi->
24914 tx_rx_cal_radio_saveregs[0]);
24915 write_radio_reg(pi,
24916 RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
24917 pi->
24918 tx_rx_cal_radio_saveregs[1]);
24919 }
24920 }
24921
24922 } else {
24923 if (rx_core == PHY_CORE_0) {
24924 write_radio_reg(pi,
24925 RADIO_2056_TX_RXIQCAL_TXMUX |
24926 RADIO_2056_TX1,
24927 pi->tx_rx_cal_radio_saveregs[0]);
24928
24929 write_radio_reg(pi,
24930 RADIO_2056_RX_RXIQCAL_RXMUX |
24931 RADIO_2056_RX0,
24932 pi->tx_rx_cal_radio_saveregs[1]);
24933
24934 if (pi->pubpi.radiorev >= 5) {
24935 write_radio_reg(pi,
24936 RADIO_2056_RX_RXSPARE2 |
24937 RADIO_2056_RX0,
24938 pi->
24939 tx_rx_cal_radio_saveregs[2]);
24940
24941 write_radio_reg(pi,
24942 RADIO_2056_TX_TXSPARE2 |
24943 RADIO_2056_TX1,
24944 pi->
24945 tx_rx_cal_radio_saveregs[3]);
24946 }
24947
24948 if (CHSPEC_IS5G(pi->radio_chanspec)) {
24949 if (pi->pubpi.radiorev >= 5) {
24950 write_radio_reg(pi,
24951 RADIO_2056_RX_LNAA_MASTER
24952 | RADIO_2056_RX0,
24953 pi->
24954 tx_rx_cal_radio_saveregs
24955 [4]);
24956 } else {
24957 write_radio_reg(pi,
24958 RADIO_2056_RX_LNAA_TUNE
24959 | RADIO_2056_RX0,
24960 pi->
24961 tx_rx_cal_radio_saveregs
24962 [4]);
24963 }
24964 } else {
24965 if (pi->pubpi.radiorev >= 5) {
24966 write_radio_reg(pi,
24967 RADIO_2056_RX_LNAG_MASTER
24968 | RADIO_2056_RX0,
24969 pi->
24970 tx_rx_cal_radio_saveregs
24971 [4]);
24972 } else {
24973 write_radio_reg(pi,
24974 RADIO_2056_RX_LNAG_TUNE
24975 | RADIO_2056_RX0,
24976 pi->
24977 tx_rx_cal_radio_saveregs
24978 [4]);
24979 }
24980 }
24981
24982 } else {
24983 write_radio_reg(pi,
24984 RADIO_2056_TX_RXIQCAL_TXMUX |
24985 RADIO_2056_TX0,
24986 pi->tx_rx_cal_radio_saveregs[0]);
24987
24988 write_radio_reg(pi,
24989 RADIO_2056_RX_RXIQCAL_RXMUX |
24990 RADIO_2056_RX1,
24991 pi->tx_rx_cal_radio_saveregs[1]);
24992
24993 if (pi->pubpi.radiorev >= 5) {
24994 write_radio_reg(pi,
24995 RADIO_2056_RX_RXSPARE2 |
24996 RADIO_2056_RX1,
24997 pi->
24998 tx_rx_cal_radio_saveregs[2]);
24999
25000 write_radio_reg(pi,
25001 RADIO_2056_TX_TXSPARE2 |
25002 RADIO_2056_TX0,
25003 pi->
25004 tx_rx_cal_radio_saveregs[3]);
25005 }
25006
25007 if (CHSPEC_IS5G(pi->radio_chanspec)) {
25008 if (pi->pubpi.radiorev >= 5) {
25009 write_radio_reg(pi,
25010 RADIO_2056_RX_LNAA_MASTER
25011 | RADIO_2056_RX1,
25012 pi->
25013 tx_rx_cal_radio_saveregs
25014 [4]);
25015 } else {
25016 write_radio_reg(pi,
25017 RADIO_2056_RX_LNAA_TUNE
25018 | RADIO_2056_RX1,
25019 pi->
25020 tx_rx_cal_radio_saveregs
25021 [4]);
25022 }
25023 } else {
25024 if (pi->pubpi.radiorev >= 5) {
25025 write_radio_reg(pi,
25026 RADIO_2056_RX_LNAG_MASTER
25027 | RADIO_2056_RX1,
25028 pi->
25029 tx_rx_cal_radio_saveregs
25030 [4]);
25031 } else {
25032 write_radio_reg(pi,
25033 RADIO_2056_RX_LNAG_TUNE
25034 | RADIO_2056_RX1,
25035 pi->
25036 tx_rx_cal_radio_saveregs
25037 [4]);
25038 }
25039 }
25040 }
25041 }
25042}
25043
25044static void wlc_phy_rxcal_physetup_nphy(struct brcms_phy *pi, u8 rx_core)
25045{
25046 u8 tx_core;
25047 u16 rx_antval, tx_antval;
25048
25049 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25050
25051 tx_core = rx_core;
25052 } else {
25053 tx_core = (rx_core == PHY_CORE_0) ? 1 : 0;
25054 }
25055
25056 pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2);
25057 pi->tx_rx_cal_phy_saveregs[1] =
25058 read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7);
25059 pi->tx_rx_cal_phy_saveregs[2] =
25060 read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5);
25061 pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91);
25062 pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92);
25063 pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a);
25064 pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d);
25065 pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7);
25066 pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec);
25067 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25068 pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342);
25069 pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343);
25070 pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346);
25071 pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347);
25072 }
25073
25074 pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
25075 pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
25076 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
25077 0x29b, (0x1 << 0), (0) << 0);
25078
25079 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
25080 0x29b, (0x1 << 0), (0) << 0);
25081
25082 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25083
25084 mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
25085
25086 mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12);
25087
25088 } else {
25089
25090 mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
25091 mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
25092 mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4);
25093 mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8);
25094 }
25095
25096 mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0);
25097 mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
25098 (0x1 << 2), (0x1 << 2));
25099 if (NREV_LT(pi->pubpi.phy_rev, 7)) {
25100 mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
25101 (0x1 << 0) | (0x1 << 1), 0);
25102 mod_phy_reg(pi, (rx_core == PHY_CORE_0) ?
25103 0x8f : 0xa5,
25104 (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1));
25105 }
25106
25107 wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0,
25108 RADIO_MIMO_CORESEL_CORE1 |
25109 RADIO_MIMO_CORESEL_CORE2);
25110
25111 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25112 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
25113 0, 0, 0,
25114 NPHY_REV7_RFCTRLOVERRIDE_ID0);
25115 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0,
25116 NPHY_REV7_RFCTRLOVERRIDE_ID1);
25117 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0,
25118 NPHY_REV7_RFCTRLOVERRIDE_ID1);
25119 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0,
25120 NPHY_REV7_RFCTRLOVERRIDE_ID1);
25121 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0,
25122 NPHY_REV7_RFCTRLOVERRIDE_ID2);
25123 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0,
25124 NPHY_REV7_RFCTRLOVERRIDE_ID1);
25125 if (CHSPEC_IS40(pi->radio_chanspec)) {
25126 wlc_phy_rfctrl_override_nphy_rev7(pi,
25127 (0x1 << 7),
25128 2, 0, 0,
25129 NPHY_REV7_RFCTRLOVERRIDE_ID1);
25130 } else {
25131 wlc_phy_rfctrl_override_nphy_rev7(pi,
25132 (0x1 << 7),
25133 0, 0, 0,
25134 NPHY_REV7_RFCTRLOVERRIDE_ID1);
25135 }
25136 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
25137 0, 0, 0,
25138 NPHY_REV7_RFCTRLOVERRIDE_ID1);
25139 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0,
25140 NPHY_REV7_RFCTRLOVERRIDE_ID1);
25141 } else {
25142 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0);
25143 }
25144
25145 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
25146
25147 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25148
25149 wlc_phy_rfctrlintc_override_nphy(pi,
25150 NPHY_RfctrlIntc_override_TRSW,
25151 0x1, rx_core + 1);
25152 } else {
25153
25154 if (rx_core == PHY_CORE_0) {
25155 rx_antval = 0x1;
25156 tx_antval = 0x8;
25157 } else {
25158 rx_antval = 0x4;
25159 tx_antval = 0x2;
25160 }
25161
25162 wlc_phy_rfctrlintc_override_nphy(pi,
25163 NPHY_RfctrlIntc_override_TRSW,
25164 rx_antval, rx_core + 1);
25165 wlc_phy_rfctrlintc_override_nphy(pi,
25166 NPHY_RfctrlIntc_override_TRSW,
25167 tx_antval, tx_core + 1);
25168 }
25169}
25170
25171static void wlc_phy_rxcal_phycleanup_nphy(struct brcms_phy *pi, u8 rx_core)
25172{
25173
25174 write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]);
25175 write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7,
25176 pi->tx_rx_cal_phy_saveregs[1]);
25177 write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
25178 pi->tx_rx_cal_phy_saveregs[2]);
25179 write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]);
25180 write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]);
25181
25182 write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]);
25183 write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]);
25184 write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]);
25185 write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]);
25186 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25187 write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]);
25188 write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]);
25189 write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]);
25190 write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]);
25191 }
25192
25193 write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
25194 write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
25195}
25196
25197static void
25198wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core,
25199 u16 *rxgain, u8 cal_type)
25200{
25201
25202 u16 num_samps;
25203 struct phy_iq_est est[PHY_CORE_MAX];
25204 u8 tx_core;
25205 struct nphy_iq_comp save_comp, zero_comp;
25206 u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, thresh_pwr =
25207 10000;
25208 s16 desired_log2_pwr, actual_log2_pwr, delta_pwr;
25209 bool gainctrl_done = false;
25210 u8 mix_tia_gain = 3;
25211 s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0;
25212 s8 curr_gaintbl_index = 3;
25213 u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT;
25214 struct nphy_ipa_txrxgain *nphy_rxcal_gaintbl;
25215 u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1;
25216 int fine_gain_idx;
25217 s8 txpwrindex;
25218 u16 nphy_rxcal_txgain[2];
25219
25220 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25221
25222 tx_core = rx_core;
25223 } else {
25224 tx_core = 1 - rx_core;
25225 }
25226
25227 num_samps = 1024;
25228 desired_log2_pwr = (cal_type == 0) ? 13 : 13;
25229
25230 wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
25231 zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
25232 wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp);
25233
25234 if (CHSPEC_IS5G(pi->radio_chanspec)) {
25235 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25236 mix_tia_gain = 3;
25237 } else if (NREV_GE(pi->pubpi.phy_rev, 4)) {
25238 mix_tia_gain = 4;
25239 } else {
25240 mix_tia_gain = 6;
25241 }
25242 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25243 nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7;
25244 } else {
25245 nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz;
25246 }
25247 } else {
25248 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25249 nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7;
25250 } else {
25251 nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz;
25252 }
25253 }
25254
25255 do {
25256
25257 hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ?
25258 0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga;
25259 lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1;
25260 lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0;
25261 lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2;
25262 lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1;
25263 txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex;
25264
25265 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25266 wlc_phy_rfctrl_override_1tomany_nphy(pi,
25267 NPHY_REV7_RfctrlOverride_cmd_rxgain,
25268 ((lpf_biq1 << 12) |
25269 (lpf_biq0 << 8) |
25270 (mix_tia_gain <<
25271 4) | (lna2 << 2)
25272 | lna1), 0x3, 0);
25273 } else {
25274 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
25275 ((hpvga << 12) |
25276 (lpf_biq1 << 10) |
25277 (lpf_biq0 << 8) |
25278 (mix_tia_gain << 4) |
25279 (lna2 << 2) | lna1), 0x3,
25280 0);
25281 }
25282
25283 pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex;
25284
25285 if (txpwrindex == -1) {
25286 nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval;
25287 nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval;
25288 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
25289 2, 0x110, 16,
25290 nphy_rxcal_txgain);
25291 } else {
25292 wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex,
25293 false);
25294 }
25295
25296 wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ?
25297 NPHY_RXCAL_TONEFREQ_40MHz :
25298 NPHY_RXCAL_TONEFREQ_20MHz,
25299 NPHY_RXCAL_TONEAMP, 0, cal_type, false);
25300
25301 wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
25302 i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
25303 q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
25304 curr_pwr = i_pwr + q_pwr;
25305
25306 switch (gainctrl_dirn) {
25307 case NPHY_RXCAL_GAIN_INIT:
25308 if (curr_pwr > thresh_pwr) {
25309 gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN;
25310 prev_gaintbl_index = curr_gaintbl_index;
25311 curr_gaintbl_index--;
25312 } else {
25313 gainctrl_dirn = NPHY_RXCAL_GAIN_UP;
25314 prev_gaintbl_index = curr_gaintbl_index;
25315 curr_gaintbl_index++;
25316 }
25317 break;
25318
25319 case NPHY_RXCAL_GAIN_UP:
25320 if (curr_pwr > thresh_pwr) {
25321 gainctrl_done = true;
25322 optim_pwr = prev_pwr;
25323 optim_gaintbl_index = prev_gaintbl_index;
25324 } else {
25325 prev_gaintbl_index = curr_gaintbl_index;
25326 curr_gaintbl_index++;
25327 }
25328 break;
25329
25330 case NPHY_RXCAL_GAIN_DOWN:
25331 if (curr_pwr > thresh_pwr) {
25332 prev_gaintbl_index = curr_gaintbl_index;
25333 curr_gaintbl_index--;
25334 } else {
25335 gainctrl_done = true;
25336 optim_pwr = curr_pwr;
25337 optim_gaintbl_index = curr_gaintbl_index;
25338 }
25339 break;
25340
25341 default:
25342 break;
25343 }
25344
25345 if ((curr_gaintbl_index < 0) ||
25346 (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) {
25347 gainctrl_done = true;
25348 optim_pwr = curr_pwr;
25349 optim_gaintbl_index = prev_gaintbl_index;
25350 } else {
25351 prev_pwr = curr_pwr;
25352 }
25353
25354 wlc_phy_stopplayback_nphy(pi);
25355 } while (!gainctrl_done);
25356
25357 hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga;
25358 lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1;
25359 lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0;
25360 lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2;
25361 lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1;
25362 txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex;
25363
25364 actual_log2_pwr = wlc_phy_nbits(optim_pwr);
25365 delta_pwr = desired_log2_pwr - actual_log2_pwr;
25366
25367 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25368 fine_gain_idx = (int)lpf_biq1 + delta_pwr;
25369
25370 if (fine_gain_idx + (int)lpf_biq0 > 10) {
25371 lpf_biq1 = 10 - lpf_biq0;
25372 } else {
25373 lpf_biq1 = (u16) max(fine_gain_idx, 0);
25374 }
25375 wlc_phy_rfctrl_override_1tomany_nphy(pi,
25376 NPHY_REV7_RfctrlOverride_cmd_rxgain,
25377 ((lpf_biq1 << 12) |
25378 (lpf_biq0 << 8) |
25379 (mix_tia_gain << 4) |
25380 (lna2 << 2) | lna1), 0x3,
25381 0);
25382 } else {
25383 hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0);
25384 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
25385 ((hpvga << 12) | (lpf_biq1 << 10) |
25386 (lpf_biq0 << 8) | (mix_tia_gain <<
25387 4) | (lna2 <<
25388 2) |
25389 lna1), 0x3, 0);
25390
25391 }
25392
25393 if (rxgain != NULL) {
25394 *rxgain++ = lna1;
25395 *rxgain++ = lna2;
25396 *rxgain++ = mix_tia_gain;
25397 *rxgain++ = lpf_biq0;
25398 *rxgain++ = lpf_biq1;
25399 *rxgain = hpvga;
25400 }
25401
25402 wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp);
25403}
25404
25405static void
25406wlc_phy_rxcal_gainctrl_nphy(struct brcms_phy *pi, u8 rx_core, u16 *rxgain,
25407 u8 cal_type)
25408{
25409 wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type);
25410}
25411
25412static u8
25413wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type)
25414{
25415 u32 target_bws[2] = { 9500, 21000 };
25416 u32 ref_tones[2] = { 3000, 6000 };
25417 u32 target_bw, ref_tone;
25418
25419 u32 target_pwr_ratios[2] = { 28606, 18468 };
25420 u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0;
25421
25422 u16 start_rccal_ovr_val = 128;
25423 u16 txlpf_rccal_lpc_ovr_val = 128;
25424 u16 rxlpf_rccal_hpc_ovr_val = 159;
25425
25426 u16 orig_txlpf_rccal_lpc_ovr_val;
25427 u16 orig_rxlpf_rccal_hpc_ovr_val;
25428 u16 radio_addr_offset_rx;
25429 u16 radio_addr_offset_tx;
25430 u16 orig_dcBypass;
25431 u16 orig_RxStrnFilt40Num[6];
25432 u16 orig_RxStrnFilt40Den[4];
25433 u16 orig_rfctrloverride[2];
25434 u16 orig_rfctrlauxreg[2];
25435 u16 orig_rfctrlrssiothers;
25436 u16 tx_lpf_bw = 4;
25437
25438 u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 };
25439 u16 lpf_hpc = 7, hpvga_hpc = 7;
25440
25441 s8 rccal_stepsize;
25442 u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0;
25443 u32 ref_iq_vals = 0, target_iq_vals = 0;
25444 u16 num_samps, log_num_samps = 10;
25445 struct phy_iq_est est[PHY_CORE_MAX];
25446
25447 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25448 return 0;
25449 }
25450
25451 num_samps = (1 << log_num_samps);
25452
25453 if (CHSPEC_IS40(pi->radio_chanspec)) {
25454 target_bw = target_bws[1];
25455 target_pwr_ratio = target_pwr_ratios[1];
25456 ref_tone = ref_tones[1];
25457 rx_lpf_bw = rx_lpf_bws[1];
25458 } else {
25459 target_bw = target_bws[0];
25460 target_pwr_ratio = target_pwr_ratios[0];
25461 ref_tone = ref_tones[0];
25462 rx_lpf_bw = rx_lpf_bws[0];
25463 }
25464
25465 if (core_idx == 0) {
25466 radio_addr_offset_rx = RADIO_2056_RX0;
25467 radio_addr_offset_tx =
25468 (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
25469 } else {
25470 radio_addr_offset_rx = RADIO_2056_RX1;
25471 radio_addr_offset_tx =
25472 (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0;
25473 }
25474
25475 orig_txlpf_rccal_lpc_ovr_val =
25476 read_radio_reg(pi,
25477 (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx));
25478 orig_rxlpf_rccal_hpc_ovr_val =
25479 read_radio_reg(pi,
25480 (RADIO_2056_RX_RXLPF_RCCAL_HPC |
25481 radio_addr_offset_rx));
25482
25483 orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1);
25484
25485 orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267);
25486 orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268);
25487 orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269);
25488 orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a);
25489 orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b);
25490 orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c);
25491 orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d);
25492 orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e);
25493 orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f);
25494 orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270);
25495
25496 orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7);
25497 orig_rfctrloverride[1] = read_phy_reg(pi, 0xec);
25498 orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8);
25499 orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa);
25500 orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d);
25501
25502 write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
25503 txlpf_rccal_lpc_ovr_val);
25504
25505 write_radio_reg(pi,
25506 (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
25507 rxlpf_rccal_hpc_ovr_val);
25508
25509 mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8));
25510
25511 write_phy_reg(pi, 0x267, 0x02d4);
25512 write_phy_reg(pi, 0x268, 0x0000);
25513 write_phy_reg(pi, 0x269, 0x0000);
25514 write_phy_reg(pi, 0x26a, 0x0000);
25515 write_phy_reg(pi, 0x26b, 0x0000);
25516 write_phy_reg(pi, 0x26c, 0x02d4);
25517 write_phy_reg(pi, 0x26d, 0x0000);
25518 write_phy_reg(pi, 0x26e, 0x0000);
25519 write_phy_reg(pi, 0x26f, 0x0000);
25520 write_phy_reg(pi, 0x270, 0x0000);
25521
25522 or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8));
25523 or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15));
25524 or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9));
25525 or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10));
25526
25527 mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8,
25528 (0x7 << 10), (tx_lpf_bw << 10));
25529 mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
25530 (0x7 << 0), (hpvga_hpc << 0));
25531 mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
25532 (0x7 << 4), (lpf_hpc << 4));
25533 mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d,
25534 (0x7 << 8), (rx_lpf_bw << 8));
25535
25536 rccal_stepsize = 16;
25537 rccal_val = start_rccal_ovr_val + rccal_stepsize;
25538
25539 while (rccal_stepsize >= 0) {
25540 write_radio_reg(pi,
25541 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
25542 radio_addr_offset_rx), rccal_val);
25543
25544 if (rccal_stepsize == 16) {
25545
25546 wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP,
25547 0, 1, false);
25548 udelay(2);
25549
25550 wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
25551
25552 if (core_idx == 0) {
25553 ref_iq_vals =
25554 max_t(u32, (est[0].i_pwr +
25555 est[0].q_pwr) >> (log_num_samps + 1),
25556 1);
25557 } else {
25558 ref_iq_vals =
25559 max_t(u32, (est[1].i_pwr +
25560 est[1].q_pwr) >> (log_num_samps + 1),
25561 1);
25562 }
25563
25564 wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP,
25565 0, 1, false);
25566 udelay(2);
25567 }
25568
25569 wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
25570
25571 if (core_idx == 0) {
25572 target_iq_vals =
25573 (est[0].i_pwr + est[0].q_pwr) >> (log_num_samps +
25574 1);
25575 } else {
25576 target_iq_vals =
25577 (est[1].i_pwr + est[1].q_pwr) >> (log_num_samps +
25578 1);
25579 }
25580 pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals);
25581
25582 if (rccal_stepsize == 0) {
25583 rccal_stepsize--;
25584 } else if (rccal_stepsize == 1) {
25585 last_rccal_val = rccal_val;
25586 rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1;
25587 last_pwr_ratio = pwr_ratio;
25588 rccal_stepsize--;
25589 } else {
25590 rccal_stepsize = (rccal_stepsize >> 1);
25591 rccal_val += ((pwr_ratio > target_pwr_ratio) ?
25592 rccal_stepsize : (-rccal_stepsize));
25593 }
25594
25595 if (rccal_stepsize == -1) {
25596 best_rccal_val =
25597 (ABS((int)last_pwr_ratio - (int)target_pwr_ratio) <
25598 ABS((int)pwr_ratio -
25599 (int)target_pwr_ratio)) ? last_rccal_val :
25600 rccal_val;
25601
25602 if (CHSPEC_IS40(pi->radio_chanspec)) {
25603 if ((best_rccal_val > 140)
25604 || (best_rccal_val < 135)) {
25605 best_rccal_val = 138;
25606 }
25607 } else {
25608 if ((best_rccal_val > 142)
25609 || (best_rccal_val < 137)) {
25610 best_rccal_val = 140;
25611 }
25612 }
25613
25614 write_radio_reg(pi,
25615 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
25616 radio_addr_offset_rx), best_rccal_val);
25617 }
25618 }
25619
25620 wlc_phy_stopplayback_nphy(pi);
25621
25622 write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
25623 orig_txlpf_rccal_lpc_ovr_val);
25624 write_radio_reg(pi,
25625 (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
25626 orig_rxlpf_rccal_hpc_ovr_val);
25627
25628 mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8));
25629
25630 write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]);
25631 write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]);
25632 write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]);
25633 write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]);
25634 write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]);
25635 write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]);
25636 write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]);
25637 write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]);
25638 write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]);
25639 write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]);
25640
25641 write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]);
25642 write_phy_reg(pi, 0xec, orig_rfctrloverride[1]);
25643 write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]);
25644 write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]);
25645 write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers);
25646
25647 pi->nphy_anarxlpf_adjusted = false;
25648
25649 return best_rccal_val - 0x80;
25650}
25651
25652#define WAIT_FOR_SCOPE 4000
25653static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi,
25654 struct nphy_txgains target_gain,
25655 u8 cal_type, bool debug)
25656{
25657 u16 orig_BBConfig;
25658 u8 core_no, rx_core;
25659 u8 best_rccal[2];
25660 u16 gain_save[2];
25661 u16 cal_gain[2];
25662 struct nphy_iqcal_params cal_params[2];
25663 u8 rxcore_state;
25664 s8 rxlpf_rccal_hpc, txlpf_rccal_lpc;
25665 s8 txlpf_idac;
25666 bool phyhang_avoid_state = false;
25667 bool skip_rxiqcal = false;
25668
25669 orig_BBConfig = read_phy_reg(pi, 0x01);
25670 mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
25671
25672 wlc_phy_stay_in_carriersearch_nphy(pi, true);
25673
25674 if (NREV_GE(pi->pubpi.phy_rev, 4)) {
25675 phyhang_avoid_state = pi->phyhang_avoid;
25676 pi->phyhang_avoid = false;
25677 }
25678
25679 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
25680
25681 for (core_no = 0; core_no <= 1; core_no++) {
25682 wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
25683 &cal_params[core_no]);
25684 cal_gain[core_no] = cal_params[core_no].cal_gain;
25685 }
25686
25687 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
25688
25689 rxcore_state = wlc_phy_rxcore_getstate_nphy(
25690 (struct brcms_phy_pub *) pi);
25691
25692 for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
25693
25694 skip_rxiqcal =
25695 ((rxcore_state & (1 << rx_core)) == 0) ? true : false;
25696
25697 wlc_phy_rxcal_physetup_nphy(pi, rx_core);
25698
25699 wlc_phy_rxcal_radio_setup_nphy(pi, rx_core);
25700
25701 if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) {
25702
25703 wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0);
25704
25705 wlc_phy_tx_tone_nphy(pi,
25706 (CHSPEC_IS40(pi->radio_chanspec)) ?
25707 NPHY_RXCAL_TONEFREQ_40MHz :
25708 NPHY_RXCAL_TONEFREQ_20MHz,
25709 NPHY_RXCAL_TONEAMP, 0, cal_type,
25710 false);
25711
25712 if (debug)
25713 mdelay(WAIT_FOR_SCOPE);
25714
25715 wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1);
25716 wlc_phy_stopplayback_nphy(pi);
25717 }
25718
25719 if (((cal_type == 1) || (cal_type == 2))
25720 && NREV_LT(pi->pubpi.phy_rev, 7)) {
25721
25722 if (rx_core == PHY_CORE_1) {
25723
25724 if (rxcore_state == 1) {
25725 wlc_phy_rxcore_setstate_nphy(
25726 (struct brcms_phy_pub *) pi, 3);
25727 }
25728
25729 wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL,
25730 1);
25731
25732 best_rccal[rx_core] =
25733 wlc_phy_rc_sweep_nphy(pi, rx_core, 1);
25734 pi->nphy_rccal_value = best_rccal[rx_core];
25735
25736 if (rxcore_state == 1) {
25737 wlc_phy_rxcore_setstate_nphy(
25738 (struct brcms_phy_pub *) pi,
25739 rxcore_state);
25740 }
25741 }
25742 }
25743
25744 wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core);
25745
25746 wlc_phy_rxcal_phycleanup_nphy(pi, rx_core);
25747 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
25748 }
25749
25750 if ((cal_type == 1) || (cal_type == 2)) {
25751
25752 best_rccal[0] = best_rccal[1];
25753 write_radio_reg(pi,
25754 (RADIO_2056_RX_RXLPF_RCCAL_LPC |
25755 RADIO_2056_RX0), (best_rccal[0] | 0x80));
25756
25757 for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
25758 rxlpf_rccal_hpc =
25759 (((int)best_rccal[rx_core] - 12) >> 1) + 10;
25760 txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10;
25761
25762 if (PHY_IPA(pi)) {
25763 txlpf_rccal_lpc += IS40MHZ(pi) ? 24 : 12;
25764 txlpf_idac = IS40MHZ(pi) ? 0x0e : 0x13;
25765 WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core,
25766 TXLPF_IDAC_4, txlpf_idac);
25767 }
25768
25769 rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31), 0);
25770 txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31), 0);
25771
25772 write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC |
25773 ((rx_core ==
25774 PHY_CORE_0) ? RADIO_2056_RX0 :
25775 RADIO_2056_RX1)),
25776 (rxlpf_rccal_hpc | 0x80));
25777
25778 write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL |
25779 ((rx_core ==
25780 PHY_CORE_0) ? RADIO_2056_TX0 :
25781 RADIO_2056_TX1)),
25782 (txlpf_rccal_lpc | 0x80));
25783 }
25784 }
25785
25786 write_phy_reg(pi, 0x01, orig_BBConfig);
25787
25788 wlc_phy_resetcca_nphy(pi);
25789
25790 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
25791 wlc_phy_rfctrl_override_1tomany_nphy(pi,
25792 NPHY_REV7_RfctrlOverride_cmd_rxgain,
25793 0, 0x3, 1);
25794 } else {
25795 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
25796 }
25797 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
25798
25799 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
25800 gain_save);
25801
25802 if (NREV_GE(pi->pubpi.phy_rev, 4)) {
25803 pi->phyhang_avoid = phyhang_avoid_state;
25804 }
25805
25806 wlc_phy_stay_in_carriersearch_nphy(pi, false);
25807
25808 return 0;
25809}
25810
25811static int
25812wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi,
25813 struct nphy_txgains target_gain, bool debug)
25814{
25815 struct phy_iq_est est[PHY_CORE_MAX];
25816 u8 core_num, rx_core, tx_core;
25817 u16 lna_vals[] = { 0x3, 0x3, 0x1 };
25818 u16 hpf1_vals[] = { 0x7, 0x2, 0x0 };
25819 u16 hpf2_vals[] = { 0x2, 0x0, 0x0 };
25820 s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna;
25821 s16 desired_log2_pwr, actual_log2_pwr, hpf_change;
25822 u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride;
25823 u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx;
25824 u16 num_samps;
25825 u32 i_pwr, q_pwr, tot_pwr[3];
25826 u8 gain_pass, use_hpf_num;
25827 u16 mask, val1, val2;
25828 u16 core_no;
25829 u16 gain_save[2];
25830 u16 cal_gain[2];
25831 struct nphy_iqcal_params cal_params[2];
25832 u8 phy_bw;
25833 int bcmerror = 0;
25834 bool first_playtone = true;
25835
25836 wlc_phy_stay_in_carriersearch_nphy(pi, true);
25837
25838 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
25839
25840 wlc_phy_reapply_txcal_coeffs_nphy(pi);
25841 }
25842
25843 wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
25844
25845 for (core_no = 0; core_no <= 1; core_no++) {
25846 wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
25847 &cal_params[core_no]);
25848 cal_gain[core_no] = cal_params[core_no].cal_gain;
25849 }
25850
25851 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
25852
25853 num_samps = 1024;
25854 desired_log2_pwr = 13;
25855
25856 for (core_num = 0; core_num < 2; core_num++) {
25857
25858 rx_core = core_num;
25859 tx_core = 1 - core_num;
25860
25861 orig_RfseqCoreActv = read_phy_reg(pi, 0xa2);
25862 orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
25863 0xa6 : 0xa7);
25864 orig_AfectrlOverride = read_phy_reg(pi, 0xa5);
25865 orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
25866 0x91 : 0x92);
25867 orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ?
25868 0x91 : 0x92);
25869
25870 mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
25871 mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
25872
25873 or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
25874 ((0x1 << 1) | (0x1 << 2)));
25875 or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2)));
25876
25877 if (((pi->nphy_rxcalparams) & 0xff000000)) {
25878
25879 write_phy_reg(pi,
25880 (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
25881 (CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 :
25882 0x110));
25883 } else {
25884
25885 write_phy_reg(pi,
25886 (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
25887 (CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 :
25888 0x120));
25889 }
25890
25891 write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92,
25892 (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 :
25893 0x114));
25894
25895 mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK;
25896 if (rx_core == PHY_CORE_0) {
25897 val1 = RADIO_2055_COUPLE_RX_MASK;
25898 val2 = RADIO_2055_COUPLE_TX_MASK;
25899 } else {
25900 val1 = RADIO_2055_COUPLE_TX_MASK;
25901 val2 = RADIO_2055_COUPLE_RX_MASK;
25902 }
25903
25904 if ((pi->nphy_rxcalparams & 0x10000)) {
25905 mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask,
25906 val1);
25907 mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask,
25908 val2);
25909 }
25910
25911 for (gain_pass = 0; gain_pass < 4; gain_pass++) {
25912
25913 if (debug)
25914 mdelay(WAIT_FOR_SCOPE);
25915
25916 if (gain_pass < 3) {
25917 curr_lna = lna_vals[gain_pass];
25918 curr_hpf1 = hpf1_vals[gain_pass];
25919 curr_hpf2 = hpf2_vals[gain_pass];
25920 } else {
25921
25922 if (tot_pwr[1] > 10000) {
25923 curr_lna = lna_vals[2];
25924 curr_hpf1 = hpf1_vals[2];
25925 curr_hpf2 = hpf2_vals[2];
25926 use_hpf_num = 1;
25927 curr_hpf = curr_hpf1;
25928 actual_log2_pwr =
25929 wlc_phy_nbits(tot_pwr[2]);
25930 } else {
25931 if (tot_pwr[0] > 10000) {
25932 curr_lna = lna_vals[1];
25933 curr_hpf1 = hpf1_vals[1];
25934 curr_hpf2 = hpf2_vals[1];
25935 use_hpf_num = 1;
25936 curr_hpf = curr_hpf1;
25937 actual_log2_pwr =
25938 wlc_phy_nbits(tot_pwr[1]);
25939 } else {
25940 curr_lna = lna_vals[0];
25941 curr_hpf1 = hpf1_vals[0];
25942 curr_hpf2 = hpf2_vals[0];
25943 use_hpf_num = 2;
25944 curr_hpf = curr_hpf2;
25945 actual_log2_pwr =
25946 wlc_phy_nbits(tot_pwr[0]);
25947 }
25948 }
25949
25950 hpf_change = desired_log2_pwr - actual_log2_pwr;
25951 curr_hpf += hpf_change;
25952 curr_hpf = max(min_t(u16, curr_hpf, 10), 0);
25953 if (use_hpf_num == 1) {
25954 curr_hpf1 = curr_hpf;
25955 } else {
25956 curr_hpf2 = curr_hpf;
25957 }
25958 }
25959
25960 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10),
25961 ((curr_hpf2 << 8) |
25962 (curr_hpf1 << 4) |
25963 (curr_lna << 2)), 0x3, 0);
25964 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
25965
25966 wlc_phy_stopplayback_nphy(pi);
25967
25968 if (first_playtone) {
25969 bcmerror = wlc_phy_tx_tone_nphy(pi, 4000,
25970 (u16) (pi->
25971 nphy_rxcalparams
25972 &
25973 0xffff),
25974 0, 0, true);
25975 first_playtone = false;
25976 } else {
25977 phy_bw =
25978 (CHSPEC_IS40(pi->radio_chanspec)) ? 40 : 20;
25979 wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff,
25980 0, 0, 0, true);
25981 }
25982
25983 if (bcmerror == 0) {
25984 if (gain_pass < 3) {
25985
25986 wlc_phy_rx_iq_est_nphy(pi, est,
25987 num_samps, 32,
25988 0);
25989 i_pwr =
25990 (est[rx_core].i_pwr +
25991 num_samps / 2) / num_samps;
25992 q_pwr =
25993 (est[rx_core].q_pwr +
25994 num_samps / 2) / num_samps;
25995 tot_pwr[gain_pass] = i_pwr + q_pwr;
25996 } else {
25997
25998 wlc_phy_calc_rx_iq_comp_nphy(pi,
25999 (1 <<
26000 rx_core));
26001 }
26002
26003 wlc_phy_stopplayback_nphy(pi);
26004 }
26005
26006 if (bcmerror != 0)
26007 break;
26008 }
26009
26010 and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask);
26011 and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask);
26012
26013 write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 :
26014 0x92, orig_RfctrlIntcTx);
26015 write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 :
26016 0x92, orig_RfctrlIntcRx);
26017 write_phy_reg(pi, 0xa5, orig_AfectrlOverride);
26018 write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 :
26019 0xa7, orig_AfectrlCore);
26020 write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
26021
26022 if (bcmerror != 0)
26023 break;
26024 }
26025
26026 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1);
26027 wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
26028
26029 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
26030 gain_save);
26031
26032 wlc_phy_stay_in_carriersearch_nphy(pi, false);
26033
26034 return bcmerror;
26035}
26036
26037int
26038wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
26039 u8 cal_type, bool debug)
26040{
26041 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26042
26043 cal_type = 0;
26044 }
26045 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
26046 return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type,
26047 debug);
26048 } else {
26049 return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug);
26050 }
26051}
26052
26053static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
26054{
26055 int j, type = 2;
26056 u16 addr_offset = 0x2c5;
26057
26058 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
26059 write_phy_reg(pi, addr_offset + j,
26060 NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
26061 }
26062}
26063
26064static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
26065{
26066 int j, type;
26067 u16 addr_offset[] = { 0x186, 0x195,
26068 0x2c5
26069 };
26070
26071 for (type = 0; type < 3; type++) {
26072 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
26073 write_phy_reg(pi, addr_offset[type] + j,
26074 NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
26075 }
26076 }
26077
26078 if (IS40MHZ(pi)) {
26079 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
26080 write_phy_reg(pi, 0x186 + j,
26081 NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
26082 }
26083 } else {
26084 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26085 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
26086 write_phy_reg(pi, 0x186 + j,
26087 NPHY_IPA_REV4_txdigi_filtcoeffs[5]
26088 [j]);
26089 }
26090 }
26091
26092 if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
26093 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
26094 write_phy_reg(pi, 0x2c5 + j,
26095 NPHY_IPA_REV4_txdigi_filtcoeffs[6]
26096 [j]);
26097 }
26098 }
26099 }
26100}
26101
26102static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi)
26103{
26104 int j;
26105
26106 if (IS40MHZ(pi)) {
26107 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
26108 write_phy_reg(pi, 0x195 + j,
26109 NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]);
26110 }
26111 } else {
26112 for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
26113 write_phy_reg(pi, 0x186 + j,
26114 NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
26115 }
26116 }
26117}
26118
26119static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi)
26120{
26121 u16 m0m1;
26122
26123 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
26124
26125 return m0m1;
26126}
26127
26128static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1)
26129{
26130 u16 m0m1 = (u16) ((m0 << 8) | m1);
26131
26132 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1);
26133 wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1);
26134}
26135
26136static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi)
26137{
26138 u32 *tx_pwrctrl_tbl = NULL;
26139
26140 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26141
26142 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26143
26144 if ((pi->pubpi.radiorev == 4)
26145 || (pi->pubpi.radiorev == 6)) {
26146
26147 tx_pwrctrl_tbl =
26148 nphy_tpc_txgain_ipa_2g_2057rev4n6;
26149 } else if (pi->pubpi.radiorev == 3) {
26150
26151 tx_pwrctrl_tbl =
26152 nphy_tpc_txgain_ipa_2g_2057rev3;
26153 } else if (pi->pubpi.radiorev == 5) {
26154
26155 tx_pwrctrl_tbl =
26156 nphy_tpc_txgain_ipa_2g_2057rev5;
26157 } else if ((pi->pubpi.radiorev == 7)
26158 || (pi->pubpi.radiorev == 8)) {
26159
26160 tx_pwrctrl_tbl =
26161 nphy_tpc_txgain_ipa_2g_2057rev7;
26162 }
26163
26164 } else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
26165
26166 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6;
26167 } else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
26168
26169 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
26170 } else {
26171
26172 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa;
26173 }
26174
26175 } else {
26176
26177 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26178 if ((pi->pubpi.radiorev == 3) ||
26179 (pi->pubpi.radiorev == 4) ||
26180 (pi->pubpi.radiorev == 6)) {
26181
26182 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057;
26183 } else if ((pi->pubpi.radiorev == 7)
26184 || (pi->pubpi.radiorev == 8)) {
26185
26186 tx_pwrctrl_tbl =
26187 nphy_tpc_txgain_ipa_5g_2057rev7;
26188 }
26189
26190 } else {
26191 tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g;
26192 }
26193 }
26194
26195 return tx_pwrctrl_tbl;
26196}
26197
26198static void
26199wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi,
26200 struct nphy_papd_restore_state *state, u8 core)
26201{
26202 s32 tone_freq;
26203 u8 off_core;
26204 u16 mixgain = 0;
26205
26206 off_core = core ^ 0x1;
26207 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26208
26209 if (NREV_IS(pi->pubpi.phy_rev, 7)
26210 || NREV_GE(pi->pubpi.phy_rev, 8)) {
26211 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
26212 wlc_phy_read_lpf_bw_ctl_nphy
26213 (pi, 0), 0, 0,
26214 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26215 }
26216
26217 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26218 if (pi->pubpi.radiorev == 5) {
26219 mixgain = (core == 0) ? 0x20 : 0x00;
26220
26221 } else if ((pi->pubpi.radiorev == 7)
26222 || (pi->pubpi.radiorev == 8)) {
26223
26224 mixgain = 0x00;
26225
26226 } else if ((pi->pubpi.radiorev <= 4)
26227 || (pi->pubpi.radiorev == 6)) {
26228
26229 mixgain = 0x00;
26230 }
26231
26232 } else {
26233 if ((pi->pubpi.radiorev == 4) ||
26234 (pi->pubpi.radiorev == 6)) {
26235
26236 mixgain = 0x50;
26237 } else if ((pi->pubpi.radiorev == 3)
26238 || (pi->pubpi.radiorev == 7)
26239 || (pi->pubpi.radiorev == 8)) {
26240
26241 mixgain = 0x0;
26242 }
26243 }
26244
26245 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
26246 mixgain, (1 << core), 0,
26247 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26248
26249 wlc_phy_rfctrl_override_1tomany_nphy(pi,
26250 NPHY_REV7_RfctrlOverride_cmd_tx_pu,
26251 1, (1 << core), 0);
26252 wlc_phy_rfctrl_override_1tomany_nphy(pi,
26253 NPHY_REV7_RfctrlOverride_cmd_tx_pu,
26254 0, (1 << off_core), 0);
26255
26256 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
26257 0, 0x3, 0,
26258 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26259 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1,
26260 (1 << core), 0,
26261 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26262 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0,
26263 (1 << core), 0,
26264 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26265 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1,
26266 (1 << core), 0,
26267 NPHY_REV7_RFCTRLOVERRIDE_ID2);
26268 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0,
26269 (1 << core), 0,
26270 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26271 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1,
26272 (1 << core), 0,
26273 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26274 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0,
26275 (1 << core), 0,
26276 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26277 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1,
26278 (1 << core), 0,
26279 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26280
26281 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
26282 0, (1 << core), 0,
26283 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26284 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0,
26285 (1 << core), 0,
26286 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26287
26288 state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
26289 0xa6 : 0xa7);
26290 state->afeoverride[core] =
26291 read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
26292 state->afectrl[off_core] =
26293 read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6);
26294 state->afeoverride[off_core] =
26295 read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f);
26296
26297 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
26298 (0x1 << 2), 0);
26299 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
26300 0xa5), (0x1 << 2), (0x1 << 2));
26301
26302 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6),
26303 (0x1 << 2), (0x1 << 2));
26304 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 :
26305 0x8f), (0x1 << 2), (0x1 << 2));
26306
26307 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26308 state->pwrup[core] =
26309 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
26310 TXRXCOUPLE_2G_PWRUP);
26311 state->atten[core] =
26312 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
26313 TXRXCOUPLE_2G_ATTEN);
26314 state->pwrup[off_core] =
26315 READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
26316 TXRXCOUPLE_2G_PWRUP);
26317 state->atten[off_core] =
26318 READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
26319 TXRXCOUPLE_2G_ATTEN);
26320
26321 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26322 TXRXCOUPLE_2G_PWRUP, 0xc);
26323
26324 if ((pi->pubpi.radiorev == 3) ||
26325 (pi->pubpi.radiorev == 4) ||
26326 (pi->pubpi.radiorev == 6)) {
26327
26328 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26329 TXRXCOUPLE_2G_ATTEN, 0xf0);
26330
26331 } else if (pi->pubpi.radiorev == 5) {
26332
26333 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26334 TXRXCOUPLE_2G_ATTEN,
26335 (core == 0) ? 0xf7 : 0xf2);
26336
26337 } else if ((pi->pubpi.radiorev == 7)
26338 || (pi->pubpi.radiorev == 8)) {
26339
26340 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26341 TXRXCOUPLE_2G_ATTEN, 0xf0);
26342
26343 }
26344
26345 WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
26346 TXRXCOUPLE_2G_PWRUP, 0x0);
26347 WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
26348 TXRXCOUPLE_2G_ATTEN, 0xff);
26349
26350 } else {
26351 state->pwrup[core] =
26352 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
26353 TXRXCOUPLE_5G_PWRUP);
26354 state->atten[core] =
26355 READ_RADIO_REG3(pi, RADIO_2057, TX, core,
26356 TXRXCOUPLE_5G_ATTEN);
26357 state->pwrup[off_core] =
26358 READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
26359 TXRXCOUPLE_5G_PWRUP);
26360 state->atten[off_core] =
26361 READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
26362 TXRXCOUPLE_5G_ATTEN);
26363
26364 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26365 TXRXCOUPLE_5G_PWRUP, 0xc);
26366
26367 if ((pi->pubpi.radiorev == 7)
26368 || (pi->pubpi.radiorev == 8)) {
26369
26370 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26371 TXRXCOUPLE_5G_ATTEN, 0xf4);
26372
26373 } else {
26374 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26375 TXRXCOUPLE_5G_ATTEN, 0xf0);
26376 }
26377
26378 WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
26379 TXRXCOUPLE_5G_PWRUP, 0x0);
26380 WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
26381 TXRXCOUPLE_5G_ATTEN, 0xff);
26382 }
26383
26384 tone_freq = 4000;
26385
26386 wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
26387
26388 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
26389 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
26390
26391 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26392 0x2a4, (0x1 << 13), (1) << 13);
26393
26394 mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
26395 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0);
26396
26397 mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 :
26398 0x2a4, (0x1 << 13), (0) << 13);
26399
26400 } else {
26401
26402 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0);
26403
26404 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0);
26405
26406 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0);
26407
26408 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0);
26409 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0);
26410
26411 state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
26412 0xa6 : 0xa7);
26413 state->afeoverride[core] =
26414 read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
26415
26416 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
26417 (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0);
26418 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
26419 0xa5),
26420 (0x1 << 0) |
26421 (0x1 << 1) |
26422 (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
26423
26424 state->vga_master[core] =
26425 READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER);
26426 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b);
26427 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26428 state->fbmix[core] =
26429 READ_RADIO_REG2(pi, RADIO_2056, RX, core,
26430 TXFBMIX_G);
26431 state->intpa_master[core] =
26432 READ_RADIO_REG2(pi, RADIO_2056, TX, core,
26433 INTPAG_MASTER);
26434
26435 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G,
26436 0x03);
26437 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
26438 INTPAG_MASTER, 0x04);
26439 } else {
26440 state->fbmix[core] =
26441 READ_RADIO_REG2(pi, RADIO_2056, RX, core,
26442 TXFBMIX_A);
26443 state->intpa_master[core] =
26444 READ_RADIO_REG2(pi, RADIO_2056, TX, core,
26445 INTPAA_MASTER);
26446
26447 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A,
26448 0x03);
26449 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
26450 INTPAA_MASTER, 0x04);
26451
26452 }
26453
26454 tone_freq = 4000;
26455
26456 wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
26457
26458 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
26459 0x29b, (0x1 << 0), (1) << 0);
26460
26461 mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
26462 0x29b, (0x1 << 0), (0) << 0);
26463
26464 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
26465 }
26466}
26467
26468static void
26469wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi,
26470 struct nphy_papd_restore_state *state)
26471{
26472 u8 core;
26473
26474 wlc_phy_stopplayback_nphy(pi);
26475
26476 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26477
26478 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
26479
26480 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26481 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26482 TXRXCOUPLE_2G_PWRUP, 0);
26483 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26484 TXRXCOUPLE_2G_ATTEN,
26485 state->atten[core]);
26486 } else {
26487 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26488 TXRXCOUPLE_5G_PWRUP, 0);
26489 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
26490 TXRXCOUPLE_5G_ATTEN,
26491 state->atten[core]);
26492 }
26493 }
26494
26495 if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) {
26496 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
26497 1, 0x3, 0,
26498 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26499 } else {
26500 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
26501 0, 0x3, 1,
26502 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26503 }
26504 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
26505 0, 0x3, 1,
26506 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26507 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
26508 NPHY_REV7_RFCTRLOVERRIDE_ID2);
26509 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1,
26510 NPHY_REV7_RFCTRLOVERRIDE_ID2);
26511 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1,
26512 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26513 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1,
26514 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26515 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1,
26516 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26517 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1,
26518 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26519 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1,
26520 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26521 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
26522 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26523 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1,
26524 NPHY_REV7_RFCTRLOVERRIDE_ID2);
26525 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1,
26526 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26527 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1,
26528 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26529 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1,
26530 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26531 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1,
26532 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26533 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1,
26534 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26535 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1,
26536 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26537
26538 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
26539
26540 write_phy_reg(pi, (core == PHY_CORE_0) ?
26541 0xa6 : 0xa7, state->afectrl[core]);
26542 write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
26543 0xa5, state->afeoverride[core]);
26544 }
26545
26546 wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
26547 (state->mm & 0xff));
26548
26549 if (NREV_IS(pi->pubpi.phy_rev, 7)
26550 || NREV_GE(pi->pubpi.phy_rev, 8)) {
26551 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0,
26552 1,
26553 NPHY_REV7_RFCTRLOVERRIDE_ID1);
26554 }
26555 } else {
26556
26557 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
26558 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1);
26559 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1);
26560
26561 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1);
26562 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1);
26563
26564 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
26565
26566 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER,
26567 state->vga_master[core]);
26568 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26569 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
26570 TXFBMIX_G, state->fbmix[core]);
26571 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
26572 INTPAG_MASTER,
26573 state->intpa_master[core]);
26574 } else {
26575 WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
26576 TXFBMIX_A, state->fbmix[core]);
26577 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
26578 INTPAA_MASTER,
26579 state->intpa_master[core]);
26580 }
26581
26582 write_phy_reg(pi, (core == PHY_CORE_0) ?
26583 0xa6 : 0xa7, state->afectrl[core]);
26584 write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
26585 0xa5, state->afeoverride[core]);
26586 }
26587
26588 wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
26589 (state->mm & 0xff));
26590
26591 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1);
26592 }
26593}
26594
26595static void
26596wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32 start,
26597 u32 end)
26598{
26599 u32 *buf, *src, *dst, sz;
26600
26601 sz = end - start + 1;
26602
26603 buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC);
26604 if (NULL == buf) {
26605 return;
26606 }
26607
26608 src = buf;
26609 dst = buf + NPHY_PAPD_EPS_TBL_SIZE;
26610
26611 wlc_phy_table_read_nphy(pi,
26612 (core ==
26613 PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 :
26614 NPHY_TBL_ID_EPSILONTBL1),
26615 NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src);
26616
26617 do {
26618 u32 phy_a1, phy_a2;
26619 s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7;
26620
26621 phy_a1 = end - min(end, (winsz >> 1));
26622 phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1, end + (winsz >> 1));
26623 phy_a3 = phy_a2 - phy_a1 + 1;
26624 phy_a6 = 0;
26625 phy_a7 = 0;
26626
26627 do {
26628 wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4,
26629 &phy_a5);
26630 phy_a6 += phy_a4;
26631 phy_a7 += phy_a5;
26632 } while (phy_a2-- != phy_a1);
26633
26634 phy_a6 /= phy_a3;
26635 phy_a7 /= phy_a3;
26636 dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff);
26637 } while (end-- != start);
26638
26639 wlc_phy_table_write_nphy(pi,
26640 (core ==
26641 PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 :
26642 NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst);
26643
26644 kfree(buf);
26645}
26646
26647static void
26648wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *txgains,
26649 enum phy_cal_mode cal_mode, u8 core)
26650{
26651 u16 phy_a1, phy_a2, phy_a3;
26652 u16 phy_a4, phy_a5;
26653 bool phy_a6;
26654 u8 phy_a7, m[2];
26655 u32 phy_a8 = 0;
26656 struct nphy_txgains phy_a9;
26657
26658 if (NREV_LT(pi->pubpi.phy_rev, 3))
26659 return;
26660
26661 phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
26662
26663 phy_a6 = ((cal_mode == CAL_GCTRL)
26664 || (cal_mode == CAL_SOFT)) ? true : false;
26665
26666 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26667
26668 phy_a9 = wlc_phy_get_tx_gain_nphy(pi);
26669
26670 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26671 phy_a5 = ((phy_a9.txlpf[core] << 15) |
26672 (phy_a9.txgm[core] << 12) |
26673 (phy_a9.pga[core] << 8) |
26674 (txgains->gains.pad[core] << 3) |
26675 (phy_a9.ipa[core]));
26676 } else {
26677 phy_a5 = ((phy_a9.txlpf[core] << 15) |
26678 (phy_a9.txgm[core] << 12) |
26679 (txgains->gains.pga[core] << 8) |
26680 (phy_a9.pad[core] << 3) | (phy_a9.ipa[core]));
26681 }
26682
26683 wlc_phy_rfctrl_override_1tomany_nphy(pi,
26684 NPHY_REV7_RfctrlOverride_cmd_txgain,
26685 phy_a5, (1 << core), 0);
26686
26687 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26688 if ((pi->pubpi.radiorev <= 4)
26689 || (pi->pubpi.radiorev == 6)) {
26690
26691 m[core] = IS40MHZ(pi) ? 60 : 79;
26692 } else {
26693
26694 m[core] = IS40MHZ(pi) ? 45 : 64;
26695 }
26696
26697 } else {
26698 m[core] = IS40MHZ(pi) ? 75 : 107;
26699 }
26700
26701 m[phy_a7] = 0;
26702 wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
26703
26704 phy_a2 = 63;
26705
26706 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26707 if ((pi->pubpi.radiorev == 4)
26708 || (pi->pubpi.radiorev == 6)) {
26709 phy_a1 = 30;
26710 phy_a3 = 30;
26711 } else {
26712 phy_a1 = 25;
26713 phy_a3 = 25;
26714 }
26715 } else {
26716 if ((pi->pubpi.radiorev == 5)
26717 || (pi->pubpi.radiorev == 7)
26718 || (pi->pubpi.radiorev == 8)) {
26719 phy_a1 = 25;
26720 phy_a3 = 25;
26721 } else {
26722 phy_a1 = 35;
26723 phy_a3 = 35;
26724 }
26725 }
26726
26727 if (cal_mode == CAL_GCTRL) {
26728 if ((pi->pubpi.radiorev == 5)
26729 && (CHSPEC_IS2G(pi->radio_chanspec))) {
26730 phy_a1 = 55;
26731 } else if (((pi->pubpi.radiorev == 7) &&
26732 (CHSPEC_IS2G(pi->radio_chanspec))) ||
26733 ((pi->pubpi.radiorev == 8) &&
26734 (CHSPEC_IS2G(pi->radio_chanspec)))) {
26735 phy_a1 = 60;
26736 } else {
26737 phy_a1 = 63;
26738 }
26739
26740 } else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) {
26741
26742 phy_a1 = 35;
26743 phy_a3 = 35;
26744 }
26745
26746 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
26747 0x29b, (0x1 << 0), (1) << 0);
26748
26749 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
26750 0x29b, (0x1 << 0), (0) << 0);
26751
26752 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26753 0x2a4, (0x1 << 13), (1) << 13);
26754
26755 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
26756 0x2a4, (0x1 << 13), (0) << 13);
26757
26758 write_phy_reg(pi, 0x2a1, 0x80);
26759 write_phy_reg(pi, 0x2a2, 0x100);
26760
26761 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26762 0x2a4, (0x7 << 4), (11) << 4);
26763
26764 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26765 0x2a4, (0x7 << 8), (11) << 8);
26766
26767 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26768 0x2a4, (0x7 << 0), (0x3) << 0);
26769
26770 write_phy_reg(pi, 0x2e5, 0x20);
26771
26772 mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
26773
26774 mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
26775
26776 mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
26777
26778 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
26779 1, ((core == 0) ? 1 : 2), 0,
26780 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26781 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
26782 0, ((core == 0) ? 2 : 1), 0,
26783 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26784
26785 write_phy_reg(pi, 0x2be, 1);
26786 SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
26787
26788 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
26789 0, 0x3, 0,
26790 NPHY_REV7_RFCTRLOVERRIDE_ID0);
26791
26792 wlc_phy_table_write_nphy(pi,
26793 (core ==
26794 PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
26795 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
26796 32, &phy_a8);
26797
26798 if (cal_mode != CAL_GCTRL) {
26799 if (CHSPEC_IS5G(pi->radio_chanspec)) {
26800 wlc_phy_a1_nphy(pi, core, 5, 0, 35);
26801 }
26802 }
26803
26804 wlc_phy_rfctrl_override_1tomany_nphy(pi,
26805 NPHY_REV7_RfctrlOverride_cmd_txgain,
26806 phy_a5, (1 << core), 1);
26807
26808 } else {
26809
26810 if (txgains) {
26811 if (txgains->useindex) {
26812 phy_a4 = 15 - ((txgains->index) >> 3);
26813 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26814 if (NREV_GE(pi->pubpi.phy_rev, 6))
26815 phy_a5 = 0x00f7 | (phy_a4 << 8);
26816
26817 else
26818 if (NREV_IS(pi->pubpi.phy_rev, 5))
26819 phy_a5 = 0x10f7 | (phy_a4 << 8);
26820 else
26821 phy_a5 = 0x50f7 | (phy_a4 << 8);
26822 } else {
26823 phy_a5 = 0x70f7 | (phy_a4 << 8);
26824 }
26825 wlc_phy_rfctrl_override_nphy(pi,
26826 (0x1 << 13),
26827 phy_a5,
26828 (1 << core), 0);
26829 } else {
26830 wlc_phy_rfctrl_override_nphy(pi,
26831 (0x1 << 13),
26832 0x5bf7,
26833 (1 << core), 0);
26834 }
26835 }
26836
26837 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26838 m[core] = IS40MHZ(pi) ? 45 : 64;
26839 } else {
26840 m[core] = IS40MHZ(pi) ? 75 : 107;
26841 }
26842
26843 m[phy_a7] = 0;
26844 wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
26845
26846 phy_a2 = 63;
26847
26848 if (cal_mode == CAL_FULL) {
26849 phy_a1 = 25;
26850 phy_a3 = 25;
26851 } else if (cal_mode == CAL_SOFT) {
26852 phy_a1 = 25;
26853 phy_a3 = 25;
26854 } else if (cal_mode == CAL_GCTRL) {
26855 phy_a1 = 63;
26856 phy_a3 = 25;
26857 } else {
26858
26859 phy_a1 = 25;
26860 phy_a3 = 25;
26861 }
26862
26863 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
26864 0x29b, (0x1 << 0), (1) << 0);
26865
26866 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
26867 0x29b, (0x1 << 0), (0) << 0);
26868
26869 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
26870 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26871 0x2a4, (0x1 << 13), (1) << 13);
26872
26873 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
26874 0x2a4, (0x1 << 13), (0) << 13);
26875
26876 write_phy_reg(pi, 0x2a1, 0x20);
26877 write_phy_reg(pi, 0x2a2, 0x60);
26878
26879 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26880 0x2a4, (0xf << 4), (9) << 4);
26881
26882 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26883 0x2a4, (0xf << 8), (9) << 8);
26884
26885 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26886 0x2a4, (0xf << 0), (0x2) << 0);
26887
26888 write_phy_reg(pi, 0x2e5, 0x20);
26889 } else {
26890 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26891 0x2a4, (0x1 << 11), (1) << 11);
26892
26893 mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
26894 0x2a4, (0x1 << 11), (0) << 11);
26895
26896 write_phy_reg(pi, 0x2a1, 0x80);
26897 write_phy_reg(pi, 0x2a2, 0x600);
26898
26899 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26900 0x2a4, (0x7 << 4), (0) << 4);
26901
26902 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26903 0x2a4, (0x7 << 8), (0) << 8);
26904
26905 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
26906 0x2a4, (0x7 << 0), (0x3) << 0);
26907
26908 mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8);
26909
26910 }
26911
26912 mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
26913
26914 mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
26915
26916 mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
26917
26918 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0);
26919
26920 write_phy_reg(pi, 0x2be, 1);
26921 SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
26922
26923 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
26924
26925 wlc_phy_table_write_nphy(pi,
26926 (core ==
26927 PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
26928 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
26929 32, &phy_a8);
26930
26931 if (cal_mode != CAL_GCTRL) {
26932 wlc_phy_a1_nphy(pi, core, 5, 0, 40);
26933 }
26934 }
26935}
26936
26937static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core)
26938{
26939 int phy_a1;
26940 int phy_a2;
26941 bool phy_a3;
26942 struct nphy_ipa_txcalgains phy_a4;
26943 bool phy_a5 = false;
26944 bool phy_a6 = true;
26945 s32 phy_a7, phy_a8;
26946 u32 phy_a9;
26947 int phy_a10;
26948 bool phy_a11 = false;
26949 int phy_a12;
26950 u8 phy_a13 = 0;
26951 u8 phy_a14;
26952 u8 *phy_a15 = NULL;
26953
26954 phy_a4.useindex = true;
26955 phy_a12 = start_gain;
26956
26957 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
26958
26959 phy_a2 = 20;
26960 phy_a1 = 1;
26961
26962 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26963 if (pi->pubpi.radiorev == 5) {
26964
26965 phy_a15 = pad_gain_codes_used_2057rev5;
26966 phy_a13 = sizeof(pad_gain_codes_used_2057rev5) /
26967 sizeof(pad_gain_codes_used_2057rev5[0]) - 1;
26968
26969 } else if ((pi->pubpi.radiorev == 7)
26970 || (pi->pubpi.radiorev == 8)) {
26971
26972 phy_a15 = pad_gain_codes_used_2057rev7;
26973 phy_a13 = sizeof(pad_gain_codes_used_2057rev7) /
26974 sizeof(pad_gain_codes_used_2057rev7[0]) - 1;
26975
26976 } else {
26977
26978 phy_a15 = pad_all_gain_codes_2057;
26979 phy_a13 = sizeof(pad_all_gain_codes_2057) /
26980 sizeof(pad_all_gain_codes_2057[0]) - 1;
26981 }
26982
26983 } else {
26984
26985 phy_a15 = pga_all_gain_codes_2057;
26986 phy_a13 = sizeof(pga_all_gain_codes_2057) /
26987 sizeof(pga_all_gain_codes_2057[0]) - 1;
26988 }
26989
26990 phy_a14 = 0;
26991
26992 for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
26993 if (CHSPEC_IS2G(pi->radio_chanspec)) {
26994 phy_a4.gains.pad[core] =
26995 (u16) phy_a15[phy_a12];
26996 } else {
26997 phy_a4.gains.pga[core] =
26998 (u16) phy_a15[phy_a12];
26999 }
27000
27001 wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
27002
27003 wlc_phy_table_read_nphy(pi,
27004 (core ==
27005 PHY_CORE_0 ?
27006 NPHY_TBL_ID_EPSILONTBL0 :
27007 NPHY_TBL_ID_EPSILONTBL1), 1,
27008 63, 32, &phy_a9);
27009
27010 wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
27011
27012 phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
27013 (phy_a8 == 4095) || (phy_a8 == -4096));
27014
27015 if (!phy_a6 && (phy_a3 != phy_a5)) {
27016 if (!phy_a3) {
27017 phy_a12 -= (u8) phy_a1;
27018 }
27019 phy_a11 = true;
27020 break;
27021 }
27022
27023 if (phy_a3)
27024 phy_a12 += (u8) phy_a1;
27025 else
27026 phy_a12 -= (u8) phy_a1;
27027
27028 if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) {
27029 if (phy_a12 < phy_a14) {
27030 phy_a12 = phy_a14;
27031 } else {
27032 phy_a12 = phy_a13;
27033 }
27034 phy_a11 = true;
27035 break;
27036 }
27037
27038 phy_a6 = false;
27039 phy_a5 = phy_a3;
27040 }
27041
27042 } else {
27043 phy_a2 = 10;
27044 phy_a1 = 8;
27045 for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
27046 phy_a4.index = (u8) phy_a12;
27047 wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
27048
27049 wlc_phy_table_read_nphy(pi,
27050 (core ==
27051 PHY_CORE_0 ?
27052 NPHY_TBL_ID_EPSILONTBL0 :
27053 NPHY_TBL_ID_EPSILONTBL1), 1,
27054 63, 32, &phy_a9);
27055
27056 wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
27057
27058 phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
27059 (phy_a8 == 4095) || (phy_a8 == -4096));
27060
27061 if (!phy_a6 && (phy_a3 != phy_a5)) {
27062 if (!phy_a3) {
27063 phy_a12 -= (u8) phy_a1;
27064 }
27065 phy_a11 = true;
27066 break;
27067 }
27068
27069 if (phy_a3)
27070 phy_a12 += (u8) phy_a1;
27071 else
27072 phy_a12 -= (u8) phy_a1;
27073
27074 if ((phy_a12 < 0) || (phy_a12 > 127)) {
27075 if (phy_a12 < 0) {
27076 phy_a12 = 0;
27077 } else {
27078 phy_a12 = 127;
27079 }
27080 phy_a11 = true;
27081 break;
27082 }
27083
27084 phy_a6 = false;
27085 phy_a5 = phy_a3;
27086 }
27087
27088 }
27089
27090 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27091 return (u8) phy_a15[phy_a12];
27092 } else {
27093 return (u8) phy_a12;
27094 }
27095
27096}
27097
27098static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal)
27099{
27100 struct nphy_ipa_txcalgains phy_b1[2];
27101 struct nphy_papd_restore_state phy_b2;
27102 bool phy_b3;
27103 u8 phy_b4;
27104 u8 phy_b5;
27105 s16 phy_b6, phy_b7, phy_b8;
27106 u16 phy_b9;
27107 s16 phy_b10, phy_b11, phy_b12;
27108
27109 phy_b11 = 0;
27110 phy_b12 = 0;
27111 phy_b7 = 0;
27112 phy_b8 = 0;
27113 phy_b6 = 0;
27114
27115 if (pi->nphy_papd_skip == 1)
27116 return;
27117
27118 phy_b3 =
27119 (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
27120 if (!phy_b3) {
27121 wlapi_suspend_mac_and_wait(pi->sh->physhim);
27122 }
27123
27124 wlc_phy_stay_in_carriersearch_nphy(pi, true);
27125
27126 pi->nphy_force_papd_cal = false;
27127
27128 for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++)
27129 pi->nphy_papd_tx_gain_at_last_cal[phy_b5] =
27130 wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5);
27131
27132 pi->nphy_papd_last_cal = pi->sh->now;
27133 pi->nphy_papd_recal_counter++;
27134
27135 if (NORADIO_ENAB(pi->pubpi))
27136 return;
27137
27138 phy_b4 = pi->nphy_txpwrctrl;
27139 wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
27140
27141 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32,
27142 nphy_papd_scaltbl);
27143 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32,
27144 nphy_papd_scaltbl);
27145
27146 phy_b9 = read_phy_reg(pi, 0x01);
27147 mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
27148
27149 for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
27150 s32 i, val = 0;
27151 for (i = 0; i < 64; i++) {
27152 wlc_phy_table_write_nphy(pi,
27153 ((phy_b5 ==
27154 PHY_CORE_0) ?
27155 NPHY_TBL_ID_EPSILONTBL0 :
27156 NPHY_TBL_ID_EPSILONTBL1), 1,
27157 i, 32, &val);
27158 }
27159 }
27160
27161 wlc_phy_ipa_restore_tx_digi_filts_nphy(pi);
27162
27163 phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi);
27164 for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
27165 wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5);
27166
27167 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27168 if (CHSPEC_IS2G(pi->radio_chanspec)) {
27169
27170 if ((pi->pubpi.radiorev == 3)
27171 || (pi->pubpi.radiorev == 4)
27172 || (pi->pubpi.radiorev == 6)) {
27173
27174 pi->nphy_papd_cal_gain_index[phy_b5] =
27175 23;
27176
27177 } else if (pi->pubpi.radiorev == 5) {
27178
27179 pi->nphy_papd_cal_gain_index[phy_b5] =
27180 0;
27181 pi->nphy_papd_cal_gain_index[phy_b5] =
27182 wlc_phy_a3_nphy(pi,
27183 pi->
27184 nphy_papd_cal_gain_index
27185 [phy_b5], phy_b5);
27186
27187 } else if ((pi->pubpi.radiorev == 7)
27188 || (pi->pubpi.radiorev == 8)) {
27189
27190 pi->nphy_papd_cal_gain_index[phy_b5] =
27191 0;
27192 pi->nphy_papd_cal_gain_index[phy_b5] =
27193 wlc_phy_a3_nphy(pi,
27194 pi->
27195 nphy_papd_cal_gain_index
27196 [phy_b5], phy_b5);
27197
27198 }
27199
27200 phy_b1[phy_b5].gains.pad[phy_b5] =
27201 pi->nphy_papd_cal_gain_index[phy_b5];
27202
27203 } else {
27204 pi->nphy_papd_cal_gain_index[phy_b5] = 0;
27205 pi->nphy_papd_cal_gain_index[phy_b5] =
27206 wlc_phy_a3_nphy(pi,
27207 pi->
27208 nphy_papd_cal_gain_index
27209 [phy_b5], phy_b5);
27210 phy_b1[phy_b5].gains.pga[phy_b5] =
27211 pi->nphy_papd_cal_gain_index[phy_b5];
27212 }
27213 } else {
27214 phy_b1[phy_b5].useindex = true;
27215 phy_b1[phy_b5].index = 16;
27216 phy_b1[phy_b5].index =
27217 wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index, phy_b5);
27218
27219 pi->nphy_papd_cal_gain_index[phy_b5] =
27220 15 - ((phy_b1[phy_b5].index) >> 3);
27221 }
27222
27223 switch (pi->nphy_papd_cal_type) {
27224 case 0:
27225 wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5);
27226 break;
27227 case 1:
27228 wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5);
27229 break;
27230 }
27231
27232 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27233 wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
27234 }
27235 }
27236
27237 if (NREV_LT(pi->pubpi.phy_rev, 7)) {
27238 wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
27239 }
27240
27241 for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
27242 int eps_offset = 0;
27243
27244 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27245 if (CHSPEC_IS2G(pi->radio_chanspec)) {
27246 if (pi->pubpi.radiorev == 3) {
27247 eps_offset = -2;
27248 } else if (pi->pubpi.radiorev == 5) {
27249 eps_offset = 3;
27250 } else {
27251 eps_offset = -1;
27252 }
27253 } else {
27254 eps_offset = 2;
27255 }
27256
27257 if (CHSPEC_IS2G(pi->radio_chanspec)) {
27258 phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5];
27259 phy_b10 = 0;
27260 if ((pi->pubpi.radiorev == 3) ||
27261 (pi->pubpi.radiorev == 4) ||
27262 (pi->pubpi.radiorev == 6)) {
27263 phy_b12 =
27264 -
27265 (nphy_papd_padgain_dlt_2g_2057rev3n4
27266 [phy_b8]
27267 + 1) / 2;
27268 phy_b10 = -1;
27269 } else if (pi->pubpi.radiorev == 5) {
27270 phy_b12 =
27271 -(nphy_papd_padgain_dlt_2g_2057rev5
27272 [phy_b8]
27273 + 1) / 2;
27274 } else if ((pi->pubpi.radiorev == 7) ||
27275 (pi->pubpi.radiorev == 8)) {
27276 phy_b12 =
27277 -(nphy_papd_padgain_dlt_2g_2057rev7
27278 [phy_b8]
27279 + 1) / 2;
27280 }
27281 } else {
27282 phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
27283 if ((pi->pubpi.radiorev == 3) ||
27284 (pi->pubpi.radiorev == 4) ||
27285 (pi->pubpi.radiorev == 6)) {
27286 phy_b11 =
27287 -(nphy_papd_pgagain_dlt_5g_2057
27288 [phy_b7]
27289 + 1) / 2;
27290 } else if ((pi->pubpi.radiorev == 7)
27291 || (pi->pubpi.radiorev == 8)) {
27292 phy_b11 =
27293 -(nphy_papd_pgagain_dlt_5g_2057rev7
27294 [phy_b7]
27295 + 1) / 2;
27296 }
27297
27298 phy_b10 = -9;
27299 }
27300
27301 if (CHSPEC_IS2G(pi->radio_chanspec)) {
27302 phy_b6 =
27303 -60 + 27 + eps_offset + phy_b12 + phy_b10;
27304 } else {
27305 phy_b6 =
27306 -60 + 27 + eps_offset + phy_b11 + phy_b10;
27307 }
27308
27309 mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
27310 0x29c, (0x1ff << 7), (phy_b6) << 7);
27311
27312 pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
27313 } else {
27314 if (NREV_LT(pi->pubpi.phy_rev, 5)) {
27315 eps_offset = 4;
27316 } else {
27317 eps_offset = 2;
27318 }
27319
27320 phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3);
27321
27322 if (CHSPEC_IS2G(pi->radio_chanspec)) {
27323 phy_b11 =
27324 -(nphy_papd_pga_gain_delta_ipa_2g[phy_b7] +
27325 1) / 2;
27326 phy_b10 = 0;
27327 } else {
27328 phy_b11 =
27329 -(nphy_papd_pga_gain_delta_ipa_5g[phy_b7] +
27330 1) / 2;
27331 phy_b10 = -9;
27332 }
27333
27334 phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10;
27335
27336 mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
27337 0x29c, (0x1ff << 7), (phy_b6) << 7);
27338
27339 pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
27340 }
27341 }
27342
27343 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
27344 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
27345
27346 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
27347 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
27348
27349 if (NREV_GE(pi->pubpi.phy_rev, 6)) {
27350 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
27351 0x2a4, (0x1 << 13), (0) << 13);
27352
27353 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
27354 0x2a4, (0x1 << 13), (0) << 13);
27355
27356 } else {
27357 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
27358 0x2a4, (0x1 << 11), (0) << 11);
27359
27360 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
27361 0x2a4, (0x1 << 11), (0) << 11);
27362
27363 }
27364 pi->nphy_papdcomp = NPHY_PAPD_COMP_ON;
27365
27366 write_phy_reg(pi, 0x01, phy_b9);
27367
27368 wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
27369
27370 wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4);
27371 if (phy_b4 == PHY_TPC_HW_OFF) {
27372 wlc_phy_txpwr_index_nphy(pi, (1 << 0),
27373 (s8) (pi->nphy_txpwrindex[0].
27374 index_internal), false);
27375 wlc_phy_txpwr_index_nphy(pi, (1 << 1),
27376 (s8) (pi->nphy_txpwrindex[1].
27377 index_internal), false);
27378 }
27379
27380 wlc_phy_stay_in_carriersearch_nphy(pi, false);
27381
27382 if (!phy_b3) {
27383 wlapi_enable_mac(pi->sh->physhim);
27384 }
27385}
27386
27387void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi)
27388{
27389 uint core;
27390 u32 txgain;
27391 u16 rad_gain, dac_gain, bbmult, m1m2;
27392 u8 txpi[2], chan_freq_range;
27393 s32 rfpwr_offset;
27394
27395 if (pi->phyhang_avoid)
27396 wlc_phy_stay_in_carriersearch_nphy(pi, true);
27397
27398 if (pi->sh->sromrev < 4) {
27399 txpi[0] = txpi[1] = 72;
27400 } else {
27401
27402 chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
27403 switch (chan_freq_range) {
27404 case WL_CHAN_FREQ_RANGE_2G:
27405 txpi[0] = pi->nphy_txpid2g[0];
27406 txpi[1] = pi->nphy_txpid2g[1];
27407 break;
27408 case WL_CHAN_FREQ_RANGE_5GL:
27409 txpi[0] = pi->nphy_txpid5gl[0];
27410 txpi[1] = pi->nphy_txpid5gl[1];
27411 break;
27412 case WL_CHAN_FREQ_RANGE_5GM:
27413 txpi[0] = pi->nphy_txpid5g[0];
27414 txpi[1] = pi->nphy_txpid5g[1];
27415 break;
27416 case WL_CHAN_FREQ_RANGE_5GH:
27417 txpi[0] = pi->nphy_txpid5gh[0];
27418 txpi[1] = pi->nphy_txpid5gh[1];
27419 break;
27420 default:
27421 txpi[0] = txpi[1] = 91;
27422 break;
27423 }
27424 }
27425
27426 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
27427 txpi[0] = txpi[1] = 30;
27428 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
27429 txpi[0] = txpi[1] = 40;
27430 }
27431
27432 if (NREV_LT(pi->pubpi.phy_rev, 7)) {
27433
27434 if ((txpi[0] < 40) || (txpi[0] > 100) ||
27435 (txpi[1] < 40) || (txpi[1] > 100))
27436 txpi[0] = txpi[1] = 91;
27437 }
27438
27439 pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0];
27440 pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1];
27441 pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0];
27442 pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1];
27443
27444 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
27445 uint phyrev = pi->pubpi.phy_rev;
27446
27447 if (NREV_GE(phyrev, 3)) {
27448 if (PHY_IPA(pi)) {
27449 u32 *tx_gaintbl =
27450 wlc_phy_get_ipa_gaintbl_nphy(pi);
27451 txgain = tx_gaintbl[txpi[core]];
27452 } else {
27453 if (CHSPEC_IS5G(pi->radio_chanspec)) {
27454 if (NREV_IS(phyrev, 3)) {
27455 txgain =
27456 nphy_tpc_5GHz_txgain_rev3
27457 [txpi[core]];
27458 } else if (NREV_IS(phyrev, 4)) {
27459 txgain =
27460 (pi->srom_fem5g.extpagain ==
27461 3) ?
27462 nphy_tpc_5GHz_txgain_HiPwrEPA
27463 [txpi[core]] :
27464 nphy_tpc_5GHz_txgain_rev4
27465 [txpi[core]];
27466 } else {
27467 txgain =
27468 nphy_tpc_5GHz_txgain_rev5
27469 [txpi[core]];
27470 }
27471 } else {
27472 if (NREV_GE(phyrev, 5) &&
27473 (pi->srom_fem2g.extpagain == 3)) {
27474 txgain =
27475 nphy_tpc_txgain_HiPwrEPA
27476 [txpi[core]];
27477 } else {
27478 txgain =
27479 nphy_tpc_txgain_rev3[txpi
27480 [core]];
27481 }
27482 }
27483 }
27484 } else {
27485 txgain = nphy_tpc_txgain[txpi[core]];
27486 }
27487
27488 if (NREV_GE(phyrev, 3))
27489 rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
27490 else
27491 rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
27492
27493 if (NREV_GE(phyrev, 7))
27494 dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1);
27495 else
27496 dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
27497
27498 bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
27499
27500 if (NREV_GE(phyrev, 3)) {
27501 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
27502 0xa5), (0x1 << 8), (0x1 << 8));
27503 } else {
27504 mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
27505 }
27506 write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain);
27507
27508 wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
27509 &rad_gain);
27510
27511 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
27512 m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
27513 m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
27514 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
27515
27516 if (PHY_IPA(pi)) {
27517 wlc_phy_table_read_nphy(pi,
27518 (core ==
27519 PHY_CORE_0 ?
27520 NPHY_TBL_ID_CORE1TXPWRCTL :
27521 NPHY_TBL_ID_CORE2TXPWRCTL), 1,
27522 576 + txpi[core], 32,
27523 &rfpwr_offset);
27524
27525 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
27526 0x29b, (0x1ff << 4),
27527 ((s16) rfpwr_offset) << 4);
27528
27529 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
27530 0x29b, (0x1 << 2), (1) << 2);
27531
27532 }
27533 }
27534
27535 and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0)));
27536
27537 if (pi->phyhang_avoid)
27538 wlc_phy_stay_in_carriersearch_nphy(pi, false);
27539}
27540
27541static void
27542wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset,
27543 u8 tmp_max_pwr, u8 rate_start,
27544 u8 rate_end)
27545{
27546 u8 rate;
27547 u8 word_num, nibble_num;
27548 u8 tmp_nibble;
27549
27550 for (rate = rate_start; rate <= rate_end; rate++) {
27551 word_num = (rate - rate_start) >> 2;
27552 nibble_num = (rate - rate_start) & 0x3;
27553 tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf;
27554
27555 srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble;
27556 }
27557}
27558
27559static void
27560wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset,
27561 u8 rate_start, u8 rate_end)
27562{
27563 u8 rate;
27564
27565 for (rate = rate_start; rate <= rate_end; rate++) {
27566 srom_max[rate] -= 2 * pwr_offset;
27567 }
27568}
27569
27570void
27571wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
27572 u8 rate_mcs_end, u8 rate_ofdm_start)
27573{
27574 u8 rate1, rate2;
27575
27576 rate2 = rate_ofdm_start;
27577 for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) {
27578 power[rate1] = power[rate2];
27579 rate2 += (rate1 == rate_mcs_start) ? 2 : 1;
27580 }
27581 power[rate_mcs_end] = power[rate_mcs_end - 1];
27582}
27583
27584void
27585wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start,
27586 u8 rate_ofdm_end, u8 rate_mcs_start)
27587{
27588 u8 rate1, rate2;
27589
27590 for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start;
27591 rate1 <= rate_ofdm_end; rate1++, rate2++) {
27592 power[rate1] = power[rate2];
27593 if (rate1 == rate_ofdm_start)
27594 power[++rate1] = power[rate2];
27595 }
27596}
27597
27598void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi)
27599{
27600 uint rate1, rate2, band_num;
27601 u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0;
27602 u8 tmp_max_pwr = 0;
27603 u16 pwr_offsets1[2], *pwr_offsets2 = NULL;
27604 u8 *tx_srom_max_rate = NULL;
27605
27606 for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) {
27607 switch (band_num) {
27608 case 0:
27609
27610 tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g,
27611 pi->nphy_pwrctrl_info[1].max_pwr_2g);
27612
27613 pwr_offsets1[0] = pi->cck2gpo;
27614 wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g,
27615 pwr_offsets1,
27616 tmp_max_pwr,
27617 TXP_FIRST_CCK,
27618 TXP_LAST_CCK);
27619
27620 pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff);
27621 pwr_offsets1[1] =
27622 (u16) (pi->ofdm2gpo >> 16) & 0xffff;
27623
27624 pwr_offsets2 = pi->mcs2gpo;
27625
27626 tmp_cddpo = pi->cdd2gpo;
27627 tmp_stbcpo = pi->stbc2gpo;
27628 tmp_bw40po = pi->bw402gpo;
27629
27630 tx_srom_max_rate = pi->tx_srom_max_rate_2g;
27631 break;
27632 case 1:
27633
27634 tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm,
27635 pi->nphy_pwrctrl_info[1].max_pwr_5gm);
27636
27637 pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff);
27638 pwr_offsets1[1] =
27639 (u16) (pi->ofdm5gpo >> 16) & 0xffff;
27640
27641 pwr_offsets2 = pi->mcs5gpo;
27642
27643 tmp_cddpo = pi->cdd5gpo;
27644 tmp_stbcpo = pi->stbc5gpo;
27645 tmp_bw40po = pi->bw405gpo;
27646
27647 tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid;
27648 break;
27649 case 2:
27650
27651 tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl,
27652 pi->nphy_pwrctrl_info[1].max_pwr_5gl);
27653
27654 pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff);
27655 pwr_offsets1[1] =
27656 (u16) (pi->ofdm5glpo >> 16) & 0xffff;
27657
27658 pwr_offsets2 = pi->mcs5glpo;
27659
27660 tmp_cddpo = pi->cdd5glpo;
27661 tmp_stbcpo = pi->stbc5glpo;
27662 tmp_bw40po = pi->bw405glpo;
27663
27664 tx_srom_max_rate = pi->tx_srom_max_rate_5g_low;
27665 break;
27666 case 3:
27667
27668 tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh,
27669 pi->nphy_pwrctrl_info[1].max_pwr_5gh);
27670
27671 pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff);
27672 pwr_offsets1[1] =
27673 (u16) (pi->ofdm5ghpo >> 16) & 0xffff;
27674
27675 pwr_offsets2 = pi->mcs5ghpo;
27676
27677 tmp_cddpo = pi->cdd5ghpo;
27678 tmp_stbcpo = pi->stbc5ghpo;
27679 tmp_bw40po = pi->bw405ghpo;
27680
27681 tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi;
27682 break;
27683 }
27684
27685 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1,
27686 tmp_max_pwr, TXP_FIRST_OFDM,
27687 TXP_LAST_OFDM);
27688
27689 wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate,
27690 TXP_FIRST_MCS_20_SISO,
27691 TXP_LAST_MCS_20_SISO,
27692 TXP_FIRST_OFDM);
27693
27694 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
27695 tmp_max_pwr,
27696 TXP_FIRST_MCS_20_CDD,
27697 TXP_LAST_MCS_20_CDD);
27698
27699 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
27700
27701 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
27702 TXP_FIRST_MCS_20_CDD,
27703 TXP_LAST_MCS_20_CDD);
27704 }
27705
27706 wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
27707 TXP_FIRST_OFDM_20_CDD,
27708 TXP_LAST_OFDM_20_CDD,
27709 TXP_FIRST_MCS_20_CDD);
27710
27711 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
27712 tmp_max_pwr,
27713 TXP_FIRST_MCS_20_STBC,
27714 TXP_LAST_MCS_20_STBC);
27715
27716 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
27717
27718 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
27719 tmp_stbcpo,
27720 TXP_FIRST_MCS_20_STBC,
27721 TXP_LAST_MCS_20_STBC);
27722 }
27723
27724 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
27725 &pwr_offsets2[2], tmp_max_pwr,
27726 TXP_FIRST_MCS_20_SDM,
27727 TXP_LAST_MCS_20_SDM);
27728
27729 if (NPHY_IS_SROM_REINTERPRET) {
27730
27731 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
27732 &pwr_offsets2[4],
27733 tmp_max_pwr,
27734 TXP_FIRST_MCS_40_SISO,
27735 TXP_LAST_MCS_40_SISO);
27736
27737 wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
27738 TXP_FIRST_OFDM_40_SISO,
27739 TXP_LAST_OFDM_40_SISO,
27740 TXP_FIRST_MCS_40_SISO);
27741
27742 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
27743 &pwr_offsets2[4],
27744 tmp_max_pwr,
27745 TXP_FIRST_MCS_40_CDD,
27746 TXP_LAST_MCS_40_CDD);
27747
27748 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
27749 TXP_FIRST_MCS_40_CDD,
27750 TXP_LAST_MCS_40_CDD);
27751
27752 wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
27753 TXP_FIRST_OFDM_40_CDD,
27754 TXP_LAST_OFDM_40_CDD,
27755 TXP_FIRST_MCS_40_CDD);
27756
27757 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
27758 &pwr_offsets2[4],
27759 tmp_max_pwr,
27760 TXP_FIRST_MCS_40_STBC,
27761 TXP_LAST_MCS_40_STBC);
27762
27763 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
27764 tmp_stbcpo,
27765 TXP_FIRST_MCS_40_STBC,
27766 TXP_LAST_MCS_40_STBC);
27767
27768 wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
27769 &pwr_offsets2[6],
27770 tmp_max_pwr,
27771 TXP_FIRST_MCS_40_SDM,
27772 TXP_LAST_MCS_40_SDM);
27773 } else {
27774
27775 for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 =
27776 TXP_FIRST_OFDM; rate1 <= TXP_LAST_MCS_40_SDM;
27777 rate1++, rate2++)
27778 tx_srom_max_rate[rate1] =
27779 tx_srom_max_rate[rate2];
27780 }
27781
27782 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
27783 wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
27784 tmp_bw40po,
27785 TXP_FIRST_OFDM_40_SISO,
27786 TXP_LAST_MCS_40_SDM);
27787 }
27788
27789 tx_srom_max_rate[TXP_MCS_32] =
27790 tx_srom_max_rate[TXP_FIRST_MCS_40_CDD];
27791 }
27792
27793 return;
27794}
27795
27796static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
27797{
27798 u16 bw40po, cddpo, stbcpo, bwduppo;
27799 uint band_num;
27800
27801 if (pi->sh->sromrev >= 9) {
27802
27803 return;
27804 }
27805
27806 bw40po = (u16) PHY_GETINTVAR(pi, "bw40po");
27807 pi->bw402gpo = bw40po & 0xf;
27808 pi->bw405gpo = (bw40po & 0xf0) >> 4;
27809 pi->bw405glpo = (bw40po & 0xf00) >> 8;
27810 pi->bw405ghpo = (bw40po & 0xf000) >> 12;
27811
27812 cddpo = (u16) PHY_GETINTVAR(pi, "cddpo");
27813 pi->cdd2gpo = cddpo & 0xf;
27814 pi->cdd5gpo = (cddpo & 0xf0) >> 4;
27815 pi->cdd5glpo = (cddpo & 0xf00) >> 8;
27816 pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
27817
27818 stbcpo = (u16) PHY_GETINTVAR(pi, "stbcpo");
27819 pi->stbc2gpo = stbcpo & 0xf;
27820 pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
27821 pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
27822 pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
27823
27824 bwduppo = (u16) PHY_GETINTVAR(pi, "bwduppo");
27825 pi->bwdup2gpo = bwduppo & 0xf;
27826 pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
27827 pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
27828 pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12;
27829
27830 for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) {
27831 switch (band_num) {
27832 case 0:
27833
27834 pi->nphy_txpid2g[PHY_CORE_0] =
27835 (u8) PHY_GETINTVAR(pi, "txpid2ga0");
27836 pi->nphy_txpid2g[PHY_CORE_1] =
27837 (u8) PHY_GETINTVAR(pi, "txpid2ga1");
27838 pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
27839 (s8) PHY_GETINTVAR(pi, "maxp2ga0");
27840 pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
27841 (s8) PHY_GETINTVAR(pi, "maxp2ga1");
27842 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
27843 (s16) PHY_GETINTVAR(pi, "pa2gw0a0");
27844 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
27845 (s16) PHY_GETINTVAR(pi, "pa2gw0a1");
27846 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
27847 (s16) PHY_GETINTVAR(pi, "pa2gw1a0");
27848 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
27849 (s16) PHY_GETINTVAR(pi, "pa2gw1a1");
27850 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
27851 (s16) PHY_GETINTVAR(pi, "pa2gw2a0");
27852 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
27853 (s16) PHY_GETINTVAR(pi, "pa2gw2a1");
27854 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
27855 (s8) PHY_GETINTVAR(pi, "itt2ga0");
27856 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
27857 (s8) PHY_GETINTVAR(pi, "itt2ga1");
27858
27859 pi->cck2gpo = (u16) PHY_GETINTVAR(pi, "cck2gpo");
27860
27861 pi->ofdm2gpo = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
27862
27863 pi->mcs2gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs2gpo0");
27864 pi->mcs2gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs2gpo1");
27865 pi->mcs2gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs2gpo2");
27866 pi->mcs2gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs2gpo3");
27867 pi->mcs2gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs2gpo4");
27868 pi->mcs2gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs2gpo5");
27869 pi->mcs2gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs2gpo6");
27870 pi->mcs2gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs2gpo7");
27871 break;
27872 case 1:
27873
27874 pi->nphy_txpid5g[PHY_CORE_0] =
27875 (u8) PHY_GETINTVAR(pi, "txpid5ga0");
27876 pi->nphy_txpid5g[PHY_CORE_1] =
27877 (u8) PHY_GETINTVAR(pi, "txpid5ga1");
27878 pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
27879 (s8) PHY_GETINTVAR(pi, "maxp5ga0");
27880 pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
27881 (s8) PHY_GETINTVAR(pi, "maxp5ga1");
27882 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
27883 (s16) PHY_GETINTVAR(pi, "pa5gw0a0");
27884 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
27885 (s16) PHY_GETINTVAR(pi, "pa5gw0a1");
27886 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
27887 (s16) PHY_GETINTVAR(pi, "pa5gw1a0");
27888 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
27889 (s16) PHY_GETINTVAR(pi, "pa5gw1a1");
27890 pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
27891 (s16) PHY_GETINTVAR(pi, "pa5gw2a0");
27892 pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
27893 (s16) PHY_GETINTVAR(pi, "pa5gw2a1");
27894 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
27895 (s8) PHY_GETINTVAR(pi, "itt5ga0");
27896 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
27897 (s8) PHY_GETINTVAR(pi, "itt5ga1");
27898
27899 pi->ofdm5gpo = (u32) PHY_GETINTVAR(pi, "ofdm5gpo");
27900
27901 pi->mcs5gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs5gpo0");
27902 pi->mcs5gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs5gpo1");
27903 pi->mcs5gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs5gpo2");
27904 pi->mcs5gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs5gpo3");
27905 pi->mcs5gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs5gpo4");
27906 pi->mcs5gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs5gpo5");
27907 pi->mcs5gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs5gpo6");
27908 pi->mcs5gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs5gpo7");
27909 break;
27910 case 2:
27911
27912 pi->nphy_txpid5gl[0] =
27913 (u8) PHY_GETINTVAR(pi, "txpid5gla0");
27914 pi->nphy_txpid5gl[1] =
27915 (u8) PHY_GETINTVAR(pi, "txpid5gla1");
27916 pi->nphy_pwrctrl_info[0].max_pwr_5gl =
27917 (s8) PHY_GETINTVAR(pi, "maxp5gla0");
27918 pi->nphy_pwrctrl_info[1].max_pwr_5gl =
27919 (s8) PHY_GETINTVAR(pi, "maxp5gla1");
27920 pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
27921 (s16) PHY_GETINTVAR(pi, "pa5glw0a0");
27922 pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
27923 (s16) PHY_GETINTVAR(pi, "pa5glw0a1");
27924 pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
27925 (s16) PHY_GETINTVAR(pi, "pa5glw1a0");
27926 pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
27927 (s16) PHY_GETINTVAR(pi, "pa5glw1a1");
27928 pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
27929 (s16) PHY_GETINTVAR(pi, "pa5glw2a0");
27930 pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
27931 (s16) PHY_GETINTVAR(pi, "pa5glw2a1");
27932 pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
27933 pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
27934
27935 pi->ofdm5glpo = (u32) PHY_GETINTVAR(pi, "ofdm5glpo");
27936
27937 pi->mcs5glpo[0] =
27938 (u16) PHY_GETINTVAR(pi, "mcs5glpo0");
27939 pi->mcs5glpo[1] =
27940 (u16) PHY_GETINTVAR(pi, "mcs5glpo1");
27941 pi->mcs5glpo[2] =
27942 (u16) PHY_GETINTVAR(pi, "mcs5glpo2");
27943 pi->mcs5glpo[3] =
27944 (u16) PHY_GETINTVAR(pi, "mcs5glpo3");
27945 pi->mcs5glpo[4] =
27946 (u16) PHY_GETINTVAR(pi, "mcs5glpo4");
27947 pi->mcs5glpo[5] =
27948 (u16) PHY_GETINTVAR(pi, "mcs5glpo5");
27949 pi->mcs5glpo[6] =
27950 (u16) PHY_GETINTVAR(pi, "mcs5glpo6");
27951 pi->mcs5glpo[7] =
27952 (u16) PHY_GETINTVAR(pi, "mcs5glpo7");
27953 break;
27954 case 3:
27955
27956 pi->nphy_txpid5gh[0] =
27957 (u8) PHY_GETINTVAR(pi, "txpid5gha0");
27958 pi->nphy_txpid5gh[1] =
27959 (u8) PHY_GETINTVAR(pi, "txpid5gha1");
27960 pi->nphy_pwrctrl_info[0].max_pwr_5gh =
27961 (s8) PHY_GETINTVAR(pi, "maxp5gha0");
27962 pi->nphy_pwrctrl_info[1].max_pwr_5gh =
27963 (s8) PHY_GETINTVAR(pi, "maxp5gha1");
27964 pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
27965 (s16) PHY_GETINTVAR(pi, "pa5ghw0a0");
27966 pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
27967 (s16) PHY_GETINTVAR(pi, "pa5ghw0a1");
27968 pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
27969 (s16) PHY_GETINTVAR(pi, "pa5ghw1a0");
27970 pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
27971 (s16) PHY_GETINTVAR(pi, "pa5ghw1a1");
27972 pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
27973 (s16) PHY_GETINTVAR(pi, "pa5ghw2a0");
27974 pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
27975 (s16) PHY_GETINTVAR(pi, "pa5ghw2a1");
27976 pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
27977 pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
27978
27979 pi->ofdm5ghpo = (u32) PHY_GETINTVAR(pi, "ofdm5ghpo");
27980
27981 pi->mcs5ghpo[0] =
27982 (u16) PHY_GETINTVAR(pi, "mcs5ghpo0");
27983 pi->mcs5ghpo[1] =
27984 (u16) PHY_GETINTVAR(pi, "mcs5ghpo1");
27985 pi->mcs5ghpo[2] =
27986 (u16) PHY_GETINTVAR(pi, "mcs5ghpo2");
27987 pi->mcs5ghpo[3] =
27988 (u16) PHY_GETINTVAR(pi, "mcs5ghpo3");
27989 pi->mcs5ghpo[4] =
27990 (u16) PHY_GETINTVAR(pi, "mcs5ghpo4");
27991 pi->mcs5ghpo[5] =
27992 (u16) PHY_GETINTVAR(pi, "mcs5ghpo5");
27993 pi->mcs5ghpo[6] =
27994 (u16) PHY_GETINTVAR(pi, "mcs5ghpo6");
27995 pi->mcs5ghpo[7] =
27996 (u16) PHY_GETINTVAR(pi, "mcs5ghpo7");
27997 break;
27998 }
27999 }
28000
28001 wlc_phy_txpwr_apply_nphy(pi);
28002}
28003
28004static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
28005{
28006
28007 pi->antswitch = (u8) PHY_GETINTVAR(pi, "antswitch");
28008 pi->aa2g = (u8) PHY_GETINTVAR(pi, "aa2g");
28009 pi->aa5g = (u8) PHY_GETINTVAR(pi, "aa5g");
28010
28011 pi->srom_fem2g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos2g");
28012 pi->srom_fem2g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain2g");
28013 pi->srom_fem2g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange2g");
28014 pi->srom_fem2g.triso = (u8) PHY_GETINTVAR(pi, "triso2g");
28015 pi->srom_fem2g.antswctrllut = (u8) PHY_GETINTVAR(pi, "antswctl2g");
28016
28017 pi->srom_fem5g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos5g");
28018 pi->srom_fem5g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain5g");
28019 pi->srom_fem5g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange5g");
28020 pi->srom_fem5g.triso = (u8) PHY_GETINTVAR(pi, "triso5g");
28021 if (PHY_GETVAR(pi, "antswctl5g")) {
28022
28023 pi->srom_fem5g.antswctrllut =
28024 (u8) PHY_GETINTVAR(pi, "antswctl5g");
28025 } else {
28026
28027 pi->srom_fem5g.antswctrllut =
28028 (u8) PHY_GETINTVAR(pi, "antswctl2g");
28029 }
28030
28031 wlc_phy_txpower_ipa_upd(pi);
28032
28033 pi->phy_txcore_disable_temp = (s16) PHY_GETINTVAR(pi, "tempthresh");
28034 if (pi->phy_txcore_disable_temp == 0) {
28035 pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
28036 }
28037
28038 pi->phy_tempsense_offset = (s8) PHY_GETINTVAR(pi, "tempoffset");
28039 if (pi->phy_tempsense_offset != 0) {
28040 if (pi->phy_tempsense_offset >
28041 (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) {
28042 pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET;
28043 } else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT +
28044 NPHY_SROM_MINTEMPOFFSET)) {
28045 pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET;
28046 } else {
28047 pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT;
28048 }
28049 }
28050
28051 pi->phy_txcore_enable_temp =
28052 pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
28053
28054 pi->phycal_tempdelta = (u8) PHY_GETINTVAR(pi, "phycal_tempdelta");
28055 if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) {
28056 pi->phycal_tempdelta = 0;
28057 }
28058
28059 wlc_phy_txpwr_srom_read_ppr_nphy(pi);
28060
28061 return true;
28062}
28063
28064void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi)
28065{
28066 u8 tx_pwr_ctrl_state;
28067 wlc_phy_txpwr_limit_to_tbl_nphy(pi);
28068 wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
28069
28070 tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
28071
28072 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
28073 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
28074 (void)R_REG(&pi->regs->maccontrol);
28075 udelay(1);
28076 }
28077
28078 wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
28079
28080 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
28081 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
28082}
28083
28084static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi)
28085{
28086 u32 idx;
28087 u16 iqloCalbuf[7];
28088 u32 iqcomp, locomp, curr_locomp;
28089 s8 locomp_i, locomp_q;
28090 s8 curr_locomp_i, curr_locomp_q;
28091 u32 tbl_id, tbl_len, tbl_offset;
28092 u32 regval[128];
28093
28094 if (pi->phyhang_avoid)
28095 wlc_phy_stay_in_carriersearch_nphy(pi, true);
28096
28097 wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf);
28098
28099 tbl_len = 128;
28100 tbl_offset = 320;
28101 for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
28102 tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
28103 iqcomp =
28104 (tbl_id ==
28105 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) |
28106 (iqloCalbuf[1] & 0x3ff)
28107 : (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) |
28108 (iqloCalbuf[3] & 0x3ff);
28109
28110 for (idx = 0; idx < tbl_len; idx++) {
28111 regval[idx] = iqcomp;
28112 }
28113 wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
28114 regval);
28115 }
28116
28117 tbl_offset = 448;
28118 for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
28119 tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
28120
28121 locomp =
28122 (u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]);
28123 locomp_i = (s8) ((locomp >> 8) & 0xff);
28124 locomp_q = (s8) ((locomp) & 0xff);
28125 for (idx = 0; idx < tbl_len; idx++) {
28126 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28127 curr_locomp_i = locomp_i;
28128 curr_locomp_q = locomp_q;
28129 } else {
28130 curr_locomp_i = (s8) ((locomp_i *
28131 nphy_tpc_loscale[idx] +
28132 128) >> 8);
28133 curr_locomp_q =
28134 (s8) ((locomp_q * nphy_tpc_loscale[idx] +
28135 128) >> 8);
28136 }
28137 curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8);
28138 curr_locomp |= (u32) (curr_locomp_q & 0xff);
28139 regval[idx] = curr_locomp;
28140 }
28141 wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
28142 regval);
28143 }
28144
28145 if (NREV_LT(pi->pubpi.phy_rev, 2)) {
28146
28147 wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF);
28148 wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF);
28149 }
28150
28151 if (pi->phyhang_avoid)
28152 wlc_phy_stay_in_carriersearch_nphy(pi, false);
28153}
28154
28155static void wlc_phy_ipa_internal_tssi_setup_nphy(struct brcms_phy *pi)
28156{
28157 u8 core;
28158
28159 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
28160 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
28161 if (CHSPEC_IS2G(pi->radio_chanspec)) {
28162 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
28163 TX_SSI_MASTER, 0x5);
28164 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
28165 TX_SSI_MUX, 0xe);
28166
28167 if (pi->pubpi.radiorev != 5)
28168 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
28169 core, TSSIA, 0);
28170
28171 if (!NREV_IS(pi->pubpi.phy_rev, 7)) {
28172
28173 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
28174 core, TSSIG, 0x1);
28175 } else {
28176
28177 WRITE_RADIO_REG3(pi, RADIO_2057, TX,
28178 core, TSSIG, 0x31);
28179 }
28180 } else {
28181 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
28182 TX_SSI_MASTER, 0x9);
28183 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
28184 TX_SSI_MUX, 0xc);
28185 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
28186 TSSIG, 0);
28187
28188 if (pi->pubpi.radiorev != 5) {
28189 if (!NREV_IS(pi->pubpi.phy_rev, 7)) {
28190
28191 WRITE_RADIO_REG3(pi, RADIO_2057,
28192 TX, core,
28193 TSSIA, 0x1);
28194 } else {
28195
28196 WRITE_RADIO_REG3(pi, RADIO_2057,
28197 TX, core,
28198 TSSIA, 0x31);
28199 }
28200 }
28201 }
28202 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
28203 0);
28204 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
28205 0);
28206 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
28207 0x3);
28208 WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
28209 0x0);
28210 }
28211 } else {
28212 WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31,
28213 (CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 :
28214 0x80);
28215 WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0);
28216 WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29);
28217
28218 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
28219 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG,
28220 0x0);
28221 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC,
28222 0x0);
28223 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM,
28224 0x3);
28225 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET,
28226 0x0);
28227 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1,
28228 0x8);
28229 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2,
28230 0x0);
28231 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3,
28232 0x0);
28233
28234 if (CHSPEC_IS2G(pi->radio_chanspec)) {
28235 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
28236 TX_SSI_MASTER, 0x5);
28237
28238 if (pi->pubpi.radiorev != 5)
28239 WRITE_RADIO_REG2(pi, RADIO_2056, TX,
28240 core, TSSIA, 0x0);
28241 if (NREV_GE(pi->pubpi.phy_rev, 5)) {
28242
28243 WRITE_RADIO_REG2(pi, RADIO_2056, TX,
28244 core, TSSIG, 0x31);
28245 } else {
28246 WRITE_RADIO_REG2(pi, RADIO_2056, TX,
28247 core, TSSIG, 0x11);
28248 }
28249 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
28250 TX_SSI_MUX, 0xe);
28251 } else {
28252 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
28253 TX_SSI_MASTER, 0x9);
28254 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
28255 TSSIA, 0x31);
28256 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
28257 TSSIG, 0x0);
28258 WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
28259 TX_SSI_MUX, 0xc);
28260 }
28261 }
28262 }
28263}
28264
28265static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi)
28266{
28267 s32 rssi_buf[4];
28268 s32 int_val;
28269
28270 if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi))
28271
28272 return;
28273
28274 if (PHY_IPA(pi)) {
28275 wlc_phy_ipa_internal_tssi_setup_nphy(pi);
28276 }
28277
28278 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
28279 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
28280 0, 0x3, 0,
28281 NPHY_REV7_RFCTRLOVERRIDE_ID0);
28282 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28283 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0);
28284 }
28285
28286 wlc_phy_stopplayback_nphy(pi);
28287
28288 wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false);
28289
28290 udelay(20);
28291 int_val =
28292 wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf,
28293 1);
28294 wlc_phy_stopplayback_nphy(pi);
28295 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0);
28296
28297 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
28298 wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
28299 0, 0x3, 1,
28300 NPHY_REV7_RFCTRLOVERRIDE_ID0);
28301 } else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28302 wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1);
28303 }
28304
28305 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28306
28307 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
28308 (u8) ((int_val >> 24) & 0xff);
28309 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
28310 (u8) ((int_val >> 24) & 0xff);
28311
28312 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
28313 (u8) ((int_val >> 8) & 0xff);
28314 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
28315 (u8) ((int_val >> 8) & 0xff);
28316 } else {
28317 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
28318 (u8) ((int_val >> 24) & 0xff);
28319
28320 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
28321 (u8) ((int_val >> 8) & 0xff);
28322
28323 pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
28324 (u8) ((int_val >> 16) & 0xff);
28325 pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
28326 (u8) ((int_val) & 0xff);
28327 }
28328
28329}
28330
28331static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
28332{
28333 u32 idx;
28334 s16 a1[2], b0[2], b1[2];
28335 s8 target_pwr_qtrdbm[2];
28336 s32 num, den, pwr_est;
28337 u8 chan_freq_range;
28338 u8 idle_tssi[2];
28339 u32 tbl_id, tbl_len, tbl_offset;
28340 u32 regval[64];
28341 u8 core;
28342
28343 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
28344 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
28345 (void)R_REG(&pi->regs->maccontrol);
28346 udelay(1);
28347 }
28348
28349 if (pi->phyhang_avoid)
28350 wlc_phy_stay_in_carriersearch_nphy(pi, true);
28351
28352 or_phy_reg(pi, 0x122, (0x1 << 0));
28353
28354 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28355 and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15)));
28356 } else {
28357
28358 or_phy_reg(pi, 0x1e7, (0x1 << 15));
28359 }
28360
28361 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
28362 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
28363
28364 if (pi->sh->sromrev < 4) {
28365 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
28366 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
28367 target_pwr_qtrdbm[0] = 13 * 4;
28368 target_pwr_qtrdbm[1] = 13 * 4;
28369 a1[0] = -424;
28370 a1[1] = -424;
28371 b0[0] = 5612;
28372 b0[1] = 5612;
28373 b1[1] = -1393;
28374 b1[0] = -1393;
28375 } else {
28376
28377 chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
28378 switch (chan_freq_range) {
28379 case WL_CHAN_FREQ_RANGE_2G:
28380 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
28381 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
28382 target_pwr_qtrdbm[0] =
28383 pi->nphy_pwrctrl_info[0].max_pwr_2g;
28384 target_pwr_qtrdbm[1] =
28385 pi->nphy_pwrctrl_info[1].max_pwr_2g;
28386 a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
28387 a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
28388 b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
28389 b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0;
28390 b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1;
28391 b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1;
28392 break;
28393 case WL_CHAN_FREQ_RANGE_5GL:
28394 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
28395 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
28396 target_pwr_qtrdbm[0] =
28397 pi->nphy_pwrctrl_info[0].max_pwr_5gl;
28398 target_pwr_qtrdbm[1] =
28399 pi->nphy_pwrctrl_info[1].max_pwr_5gl;
28400 a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
28401 a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
28402 b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
28403 b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0;
28404 b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1;
28405 b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1;
28406 break;
28407 case WL_CHAN_FREQ_RANGE_5GM:
28408 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
28409 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
28410 target_pwr_qtrdbm[0] =
28411 pi->nphy_pwrctrl_info[0].max_pwr_5gm;
28412 target_pwr_qtrdbm[1] =
28413 pi->nphy_pwrctrl_info[1].max_pwr_5gm;
28414 a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
28415 a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
28416 b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
28417 b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0;
28418 b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1;
28419 b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1;
28420 break;
28421 case WL_CHAN_FREQ_RANGE_5GH:
28422 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
28423 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
28424 target_pwr_qtrdbm[0] =
28425 pi->nphy_pwrctrl_info[0].max_pwr_5gh;
28426 target_pwr_qtrdbm[1] =
28427 pi->nphy_pwrctrl_info[1].max_pwr_5gh;
28428 a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
28429 a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
28430 b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
28431 b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0;
28432 b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1;
28433 b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1;
28434 break;
28435 default:
28436 idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
28437 idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
28438 target_pwr_qtrdbm[0] = 13 * 4;
28439 target_pwr_qtrdbm[1] = 13 * 4;
28440 a1[0] = -424;
28441 a1[1] = -424;
28442 b0[0] = 5612;
28443 b0[1] = 5612;
28444 b1[1] = -1393;
28445 b1[0] = -1393;
28446 break;
28447 }
28448 }
28449
28450 target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
28451 target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
28452
28453 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28454 if (pi->srom_fem2g.tssipos) {
28455 or_phy_reg(pi, 0x1e9, (0x1 << 14));
28456 }
28457
28458 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
28459 for (core = 0; core <= 1; core++) {
28460 if (PHY_IPA(pi)) {
28461
28462 if (CHSPEC_IS2G(pi->radio_chanspec)) {
28463 WRITE_RADIO_REG3(pi, RADIO_2057,
28464 TX, core,
28465 TX_SSI_MUX,
28466 0xe);
28467 } else {
28468 WRITE_RADIO_REG3(pi, RADIO_2057,
28469 TX, core,
28470 TX_SSI_MUX,
28471 0xc);
28472 }
28473 } else {
28474 }
28475 }
28476 } else {
28477 if (PHY_IPA(pi)) {
28478
28479 write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
28480 RADIO_2056_TX0,
28481 (CHSPEC_IS5G
28482 (pi->
28483 radio_chanspec)) ? 0xc : 0xe);
28484 write_radio_reg(pi,
28485 RADIO_2056_TX_TX_SSI_MUX |
28486 RADIO_2056_TX1,
28487 (CHSPEC_IS5G
28488 (pi->
28489 radio_chanspec)) ? 0xc : 0xe);
28490 } else {
28491
28492 write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
28493 RADIO_2056_TX0, 0x11);
28494 write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
28495 RADIO_2056_TX1, 0x11);
28496 }
28497 }
28498 }
28499
28500 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
28501 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
28502 (void)R_REG(&pi->regs->maccontrol);
28503 udelay(1);
28504 }
28505
28506 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
28507 mod_phy_reg(pi, 0x1e7, (0x7f << 0),
28508 (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
28509 } else {
28510 mod_phy_reg(pi, 0x1e7, (0x7f << 0),
28511 (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
28512 }
28513
28514 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
28515 mod_phy_reg(pi, 0x222, (0xff << 0),
28516 (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
28517 } else if (NREV_GT(pi->pubpi.phy_rev, 1)) {
28518 mod_phy_reg(pi, 0x222, (0xff << 0),
28519 (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
28520 }
28521
28522 if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
28523 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
28524
28525 write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0));
28526
28527 write_phy_reg(pi, 0x1e9,
28528 (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8));
28529
28530 write_phy_reg(pi, 0x1ea,
28531 (target_pwr_qtrdbm[0] << 0) |
28532 (target_pwr_qtrdbm[1] << 8));
28533
28534 tbl_len = 64;
28535 tbl_offset = 0;
28536 for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
28537 tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
28538
28539 for (idx = 0; idx < tbl_len; idx++) {
28540 num =
28541 8 * (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
28542 den = 32768 + a1[tbl_id - 26] * idx;
28543 pwr_est = max(((4 * num + den / 2) / den), -8);
28544 if (NREV_LT(pi->pubpi.phy_rev, 3)) {
28545 if (idx <=
28546 (uint) (31 - idle_tssi[tbl_id - 26] + 1))
28547 pwr_est =
28548 max(pwr_est,
28549 target_pwr_qtrdbm[tbl_id - 26] +
28550 1);
28551 }
28552 regval[idx] = (u32) pwr_est;
28553 }
28554 wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
28555 regval);
28556 }
28557
28558 wlc_phy_txpwr_limit_to_tbl_nphy(pi);
28559 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8,
28560 pi->adj_pwr_tbl_nphy);
28561 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8,
28562 pi->adj_pwr_tbl_nphy);
28563
28564 if (pi->phyhang_avoid)
28565 wlc_phy_stay_in_carriersearch_nphy(pi, false);
28566}
28567
28568static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi)
28569{
28570 return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) |
28571 (0x1 << 14) | (0x1 << 13));
28572}
28573
28574static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core)
28575{
28576 u16 tmp;
28577 tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee));
28578
28579 tmp = (tmp & (0x7f << 8)) >> 8;
28580 return (u8) tmp;
28581}
28582
28583static void
28584wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1)
28585{
28586 mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0);
28587
28588 if (NREV_GT(pi->pubpi.phy_rev, 1))
28589 mod_phy_reg(pi, 0x222, (0xff << 0), idx1);
28590}
28591
28592u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi)
28593{
28594 u16 tmp;
28595 u16 pwr_idx[2];
28596
28597 if (wlc_phy_txpwr_ison_nphy(pi)) {
28598 pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0);
28599 pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1);
28600
28601 tmp = (pwr_idx[0] << 8) | pwr_idx[1];
28602 } else {
28603 tmp =
28604 ((pi->nphy_txpwrindex[PHY_CORE_0].
28605 index_internal & 0xff) << 8) | (pi->
28606 nphy_txpwrindex
28607 [PHY_CORE_1].
28608 index_internal & 0xff);
28609 }
28610
28611 return tmp;
28612}
28613
28614void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi)
28615{
28616 if (PHY_IPA(pi)
28617 && (pi->nphy_force_papd_cal
28618 || (wlc_phy_txpwr_ison_nphy(pi)
28619 &&
28620 (((u32)
28621 ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) -
28622 pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4)
28623 || ((u32)
28624 ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) -
28625 pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4))))) {
28626 wlc_phy_a4(pi, true);
28627 }
28628}
28629
28630void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type)
28631{
28632 u16 mask = 0, val = 0, ishw = 0;
28633 u8 ctr;
28634 uint core;
28635 u32 tbl_offset;
28636 u32 tbl_len;
28637 u16 regval[84];
28638
28639 if (pi->phyhang_avoid)
28640 wlc_phy_stay_in_carriersearch_nphy(pi, true);
28641
28642 switch (ctrl_type) {
28643 case PHY_TPC_HW_OFF:
28644 case PHY_TPC_HW_ON:
28645 pi->nphy_txpwrctrl = ctrl_type;
28646 break;
28647 default:
28648 break;
28649 }
28650
28651 if (ctrl_type == PHY_TPC_HW_OFF) {
28652 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28653
28654 if (wlc_phy_txpwr_ison_nphy(pi)) {
28655 for (core = 0; core < pi->pubpi.phy_corenum;
28656 core++)
28657 pi->nphy_txpwr_idx[core] =
28658 wlc_phy_txpwr_idx_cur_get_nphy(pi,
28659 (u8)
28660 core);
28661 }
28662
28663 }
28664
28665 tbl_len = 84;
28666 tbl_offset = 64;
28667 for (ctr = 0; ctr < tbl_len; ctr++) {
28668 regval[ctr] = 0;
28669 }
28670 wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16,
28671 regval);
28672 wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16,
28673 regval);
28674
28675 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28676
28677 and_phy_reg(pi, 0x1e7,
28678 (u16) (~((0x1 << 15) |
28679 (0x1 << 14) | (0x1 << 13))));
28680 } else {
28681 and_phy_reg(pi, 0x1e7,
28682 (u16) (~((0x1 << 14) | (0x1 << 13))));
28683 }
28684
28685 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28686 or_phy_reg(pi, 0x8f, (0x1 << 8));
28687 or_phy_reg(pi, 0xa5, (0x1 << 8));
28688 } else {
28689 or_phy_reg(pi, 0xa5, (0x1 << 14));
28690 }
28691
28692 if (NREV_IS(pi->pubpi.phy_rev, 2))
28693 mod_phy_reg(pi, 0xdc, 0x00ff, 0x53);
28694 else if (NREV_LT(pi->pubpi.phy_rev, 2))
28695 mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a);
28696
28697 if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi))
28698 wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
28699 MHF1_IQSWAP_WAR, BRCM_BAND_ALL);
28700
28701 } else {
28702
28703 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64,
28704 8, pi->adj_pwr_tbl_nphy);
28705 wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64,
28706 8, pi->adj_pwr_tbl_nphy);
28707
28708 ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0;
28709 mask = (0x1 << 14) | (0x1 << 13);
28710 val = (ishw << 14) | (ishw << 13);
28711
28712 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28713 mask |= (0x1 << 15);
28714 val |= (ishw << 15);
28715 }
28716
28717 mod_phy_reg(pi, 0x1e7, mask, val);
28718
28719 if (CHSPEC_IS5G(pi->radio_chanspec)) {
28720 if (NREV_GE(pi->pubpi.phy_rev, 7)) {
28721 mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32);
28722 mod_phy_reg(pi, 0x222, (0xff << 0), 0x32);
28723 } else {
28724 mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64);
28725 if (NREV_GT(pi->pubpi.phy_rev, 1))
28726 mod_phy_reg(pi, 0x222,
28727 (0xff << 0), 0x64);
28728 }
28729 }
28730
28731 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28732 if ((pi->nphy_txpwr_idx[0] != 128)
28733 && (pi->nphy_txpwr_idx[1] != 128)) {
28734 wlc_phy_txpwr_idx_cur_set_nphy(pi,
28735 pi->
28736 nphy_txpwr_idx
28737 [0],
28738 pi->
28739 nphy_txpwr_idx
28740 [1]);
28741 }
28742 }
28743
28744 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28745 and_phy_reg(pi, 0x8f, ~(0x1 << 8));
28746 and_phy_reg(pi, 0xa5, ~(0x1 << 8));
28747 } else {
28748 and_phy_reg(pi, 0xa5, ~(0x1 << 14));
28749 }
28750
28751 if (NREV_IS(pi->pubpi.phy_rev, 2))
28752 mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
28753 else if (NREV_LT(pi->pubpi.phy_rev, 2))
28754 mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
28755
28756 if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi))
28757 wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
28758 0x0, BRCM_BAND_ALL);
28759
28760 if (PHY_IPA(pi)) {
28761 mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
28762 0x29b, (0x1 << 2), (0) << 2);
28763
28764 mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
28765 0x29b, (0x1 << 2), (0) << 2);
28766
28767 }
28768
28769 }
28770
28771 if (pi->phyhang_avoid)
28772 wlc_phy_stay_in_carriersearch_nphy(pi, false);
28773}
28774
28775void
28776wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex,
28777 bool restore_cals)
28778{
28779 u8 core, txpwrctl_tbl;
28780 u16 tx_ind0, iq_ind0, lo_ind0;
28781 u16 m1m2;
28782 u32 txgain;
28783 u16 rad_gain, dac_gain;
28784 u8 bbmult;
28785 u32 iqcomp;
28786 u16 iqcomp_a, iqcomp_b;
28787 u32 locomp;
28788 u16 tmpval;
28789 u8 tx_pwr_ctrl_state;
28790 s32 rfpwr_offset;
28791 u16 regval[2];
28792
28793 if (pi->phyhang_avoid)
28794 wlc_phy_stay_in_carriersearch_nphy(pi, true);
28795
28796 tx_ind0 = 192;
28797 iq_ind0 = 320;
28798 lo_ind0 = 448;
28799
28800 for (core = 0; core < pi->pubpi.phy_corenum; core++) {
28801
28802 if ((core_mask & (1 << core)) == 0) {
28803 continue;
28804 }
28805
28806 txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27;
28807
28808 if (txpwrindex < 0) {
28809 if (pi->nphy_txpwrindex[core].index < 0) {
28810
28811 continue;
28812 }
28813
28814 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28815 mod_phy_reg(pi, 0x8f,
28816 (0x1 << 8),
28817 pi->nphy_txpwrindex[core].
28818 AfectrlOverride);
28819 mod_phy_reg(pi, 0xa5, (0x1 << 8),
28820 pi->nphy_txpwrindex[core].
28821 AfectrlOverride);
28822 } else {
28823 mod_phy_reg(pi, 0xa5,
28824 (0x1 << 14),
28825 pi->nphy_txpwrindex[core].
28826 AfectrlOverride);
28827 }
28828
28829 write_phy_reg(pi, (core == PHY_CORE_0) ?
28830 0xaa : 0xab,
28831 pi->nphy_txpwrindex[core].AfeCtrlDacGain);
28832
28833 wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
28834 &pi->nphy_txpwrindex[core].
28835 rad_gain);
28836
28837 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
28838 m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
28839 m1m2 |= ((core == PHY_CORE_0) ?
28840 (pi->nphy_txpwrindex[core].bbmult << 8) :
28841 (pi->nphy_txpwrindex[core].bbmult << 0));
28842 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
28843
28844 if (restore_cals) {
28845
28846 wlc_phy_table_write_nphy(pi, 15, 2,
28847 (80 + 2 * core), 16,
28848 (void *)&pi->
28849 nphy_txpwrindex[core].
28850 iqcomp_a);
28851
28852 wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
28853 16,
28854 &pi->
28855 nphy_txpwrindex[core].
28856 locomp);
28857 wlc_phy_table_write_nphy(pi, 15, 1, (93 + core),
28858 16,
28859 (void *)&pi->
28860 nphy_txpwrindex[core].
28861 locomp);
28862 }
28863
28864 wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
28865
28866 pi->nphy_txpwrindex[core].index_internal =
28867 pi->nphy_txpwrindex[core].index_internal_save;
28868 } else {
28869
28870 if (pi->nphy_txpwrindex[core].index < 0) {
28871
28872 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28873 mod_phy_reg(pi, 0x8f,
28874 (0x1 << 8),
28875 pi->nphy_txpwrindex[core].
28876 AfectrlOverride);
28877 mod_phy_reg(pi, 0xa5, (0x1 << 8),
28878 pi->nphy_txpwrindex[core].
28879 AfectrlOverride);
28880 } else {
28881 pi->nphy_txpwrindex[core].
28882 AfectrlOverride =
28883 read_phy_reg(pi, 0xa5);
28884 }
28885
28886 pi->nphy_txpwrindex[core].AfeCtrlDacGain =
28887 read_phy_reg(pi,
28888 (core ==
28889 PHY_CORE_0) ? 0xaa : 0xab);
28890
28891 wlc_phy_table_read_nphy(pi, 7, 1,
28892 (0x110 + core), 16,
28893 &pi->
28894 nphy_txpwrindex[core].
28895 rad_gain);
28896
28897 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
28898 &tmpval);
28899 tmpval >>= ((core == PHY_CORE_0) ? 8 : 0);
28900 tmpval &= 0xff;
28901 pi->nphy_txpwrindex[core].bbmult =
28902 (u8) tmpval;
28903
28904 wlc_phy_table_read_nphy(pi, 15, 2,
28905 (80 + 2 * core), 16,
28906 (void *)&pi->
28907 nphy_txpwrindex[core].
28908 iqcomp_a);
28909
28910 wlc_phy_table_read_nphy(pi, 15, 1, (85 + core),
28911 16,
28912 (void *)&pi->
28913 nphy_txpwrindex[core].
28914 locomp);
28915
28916 pi->nphy_txpwrindex[core].index_internal_save =
28917 pi->nphy_txpwrindex[core].index_internal;
28918 }
28919
28920 tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
28921 wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
28922
28923 if (NREV_IS(pi->pubpi.phy_rev, 1))
28924 wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
28925
28926 wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
28927 (tx_ind0 + txpwrindex), 32,
28928 &txgain);
28929
28930 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28931 rad_gain =
28932 (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
28933 } else {
28934 rad_gain =
28935 (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
28936 }
28937 dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
28938 bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
28939
28940 if (NREV_GE(pi->pubpi.phy_rev, 3)) {
28941 mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
28942 0xa5), (0x1 << 8), (0x1 << 8));
28943 } else {
28944 mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
28945 }
28946 write_phy_reg(pi, (core == PHY_CORE_0) ?
28947 0xaa : 0xab, dac_gain);
28948
28949 wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
28950 &rad_gain);
28951
28952 wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
28953 m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
28954 m1m2 |=
28955 ((core ==
28956 PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
28957
28958 wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
28959
28960 wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
28961 (iq_ind0 + txpwrindex), 32,
28962 &iqcomp);
28963 iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1);
28964 iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1);
28965
28966 if (restore_cals) {
28967 regval[0] = (u16) iqcomp_a;
28968 regval[1] = (u16) iqcomp_b;
28969 wlc_phy_table_write_nphy(pi, 15, 2,
28970 (80 + 2 * core), 16,
28971 regval);
28972 }
28973
28974 wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
28975 (lo_ind0 + txpwrindex), 32,
28976 &locomp);
28977 if (restore_cals) {
28978 wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
28979 16, &locomp);
28980 }
28981
28982 if (NREV_IS(pi->pubpi.phy_rev, 1))
28983 wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
28984
28985 if (PHY_IPA(pi)) {
28986 wlc_phy_table_read_nphy(pi,
28987 (core ==
28988 PHY_CORE_0 ?
28989 NPHY_TBL_ID_CORE1TXPWRCTL
28990 :
28991 NPHY_TBL_ID_CORE2TXPWRCTL),
28992 1, 576 + txpwrindex, 32,
28993 &rfpwr_offset);
28994
28995 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
28996 0x29b, (0x1ff << 4),
28997 ((s16) rfpwr_offset) << 4);
28998
28999 mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
29000 0x29b, (0x1 << 2), (1) << 2);
29001
29002 }
29003
29004 wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
29005 }
29006
29007 pi->nphy_txpwrindex[core].index = txpwrindex;
29008 }
29009
29010 if (pi->phyhang_avoid)
29011 wlc_phy_stay_in_carriersearch_nphy(pi, false);
29012}
29013
29014void
29015wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, u8 *max_pwr,
29016 u8 txp_rate_idx)
29017{
29018 u8 chan_freq_range;
29019
29020 chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan);
29021 switch (chan_freq_range) {
29022 case WL_CHAN_FREQ_RANGE_2G:
29023 *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
29024 break;
29025 case WL_CHAN_FREQ_RANGE_5GM:
29026 *max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
29027 break;
29028 case WL_CHAN_FREQ_RANGE_5GL:
29029 *max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx];
29030 break;
29031 case WL_CHAN_FREQ_RANGE_5GH:
29032 *max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
29033 break;
29034 default:
29035 *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
29036 break;
29037 }
29038
29039 return;
29040}
29041
29042void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable)
29043{
29044 u16 clip_off[] = { 0xffff, 0xffff };
29045
29046 if (enable) {
29047 if (pi->nphy_deaf_count == 0) {
29048 pi->classifier_state =
29049 wlc_phy_classifier_nphy(pi, 0, 0);
29050 wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
29051 wlc_phy_clip_det_nphy(pi, 0, pi->clip_state);
29052 wlc_phy_clip_det_nphy(pi, 1, clip_off);
29053 }
29054
29055 pi->nphy_deaf_count++;
29056
29057 wlc_phy_resetcca_nphy(pi);
29058
29059 } else {
29060 pi->nphy_deaf_count--;
29061
29062 if (pi->nphy_deaf_count == 0) {
29063 wlc_phy_classifier_nphy(pi, (0x7 << 0),
29064 pi->classifier_state);
29065 wlc_phy_clip_det_nphy(pi, 1, pi->clip_state);
29066 }
29067 }
29068}
29069
29070void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode)
29071{
29072 wlapi_suspend_mac_and_wait(pi->sh->physhim);
29073
29074 if (mode) {
29075 if (pi->nphy_deaf_count == 0)
29076 wlc_phy_stay_in_carriersearch_nphy(pi, true);
29077 } else {
29078 if (pi->nphy_deaf_count > 0)
29079 wlc_phy_stay_in_carriersearch_nphy(pi, false);
29080 }
29081 wlapi_enable_mac(pi->sh->physhim);
29082}
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c
new file mode 100644
index 00000000000..01ff0c8eb4b
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c
@@ -0,0 +1,294 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "phy_qmath.h"
18
19/*
20Description: This function make 16 bit unsigned multiplication. To fit the output into
2116 bits the 32 bit multiplication result is right shifted by 16 bits.
22*/
23u16 qm_mulu16(u16 op1, u16 op2)
24{
25 return (u16) (((u32) op1 * (u32) op2) >> 16);
26}
27
28/*
29Description: This function make 16 bit multiplication and return the result in 16 bits.
30To fit the multiplication result into 16 bits the multiplication result is right shifted by
3115 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed
32due to the multiplication.
33When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff.
34*/
35s16 qm_muls16(s16 op1, s16 op2)
36{
37 s32 result;
38 if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) {
39 result = 0x7fffffff;
40 } else {
41 result = ((s32) (op1) * (s32) (op2));
42 }
43 return (s16) (result >> 15);
44}
45
46/*
47Description: This function add two 32 bit numbers and return the 32bit result.
48If the result overflow 32 bits, the output will be saturated to 32bits.
49*/
50s32 qm_add32(s32 op1, s32 op2)
51{
52 s32 result;
53 result = op1 + op2;
54 if (op1 < 0 && op2 < 0 && result > 0) {
55 result = 0x80000000;
56 } else if (op1 > 0 && op2 > 0 && result < 0) {
57 result = 0x7fffffff;
58 }
59 return result;
60}
61
62/*
63Description: This function add two 16 bit numbers and return the 16bit result.
64If the result overflow 16 bits, the output will be saturated to 16bits.
65*/
66s16 qm_add16(s16 op1, s16 op2)
67{
68 s16 result;
69 s32 temp = (s32) op1 + (s32) op2;
70 if (temp > (s32) 0x7fff) {
71 result = (s16) 0x7fff;
72 } else if (temp < (s32) 0xffff8000) {
73 result = (s16) 0xffff8000;
74 } else {
75 result = (s16) temp;
76 }
77 return result;
78}
79
80/*
81Description: This function make 16 bit subtraction and return the 16bit result.
82If the result overflow 16 bits, the output will be saturated to 16bits.
83*/
84s16 qm_sub16(s16 op1, s16 op2)
85{
86 s16 result;
87 s32 temp = (s32) op1 - (s32) op2;
88 if (temp > (s32) 0x7fff) {
89 result = (s16) 0x7fff;
90 } else if (temp < (s32) 0xffff8000) {
91 result = (s16) 0xffff8000;
92 } else {
93 result = (s16) temp;
94 }
95 return result;
96}
97
98/*
99Description: This function make a 32 bit saturated left shift when the specified shift
100is +ve. This function will make a 32 bit right shift when the specified shift is -ve.
101This function return the result after shifting operation.
102*/
103s32 qm_shl32(s32 op, int shift)
104{
105 int i;
106 s32 result;
107 result = op;
108 if (shift > 31)
109 shift = 31;
110 else if (shift < -31)
111 shift = -31;
112 if (shift >= 0) {
113 for (i = 0; i < shift; i++) {
114 result = qm_add32(result, result);
115 }
116 } else {
117 result = result >> (-shift);
118 }
119 return result;
120}
121
122/*
123Description: This function make a 16 bit saturated left shift when the specified shift
124is +ve. This function will make a 16 bit right shift when the specified shift is -ve.
125This function return the result after shifting operation.
126*/
127s16 qm_shl16(s16 op, int shift)
128{
129 int i;
130 s16 result;
131 result = op;
132 if (shift > 15)
133 shift = 15;
134 else if (shift < -15)
135 shift = -15;
136 if (shift > 0) {
137 for (i = 0; i < shift; i++) {
138 result = qm_add16(result, result);
139 }
140 } else {
141 result = result >> (-shift);
142 }
143 return result;
144}
145
146/*
147Description: This function make a 16 bit right shift when shift is +ve.
148This function make a 16 bit saturated left shift when shift is -ve. This function
149return the result of the shift operation.
150*/
151s16 qm_shr16(s16 op, int shift)
152{
153 return qm_shl16(op, -shift);
154}
155
156/*
157Description: This function return the number of redundant sign bits in a 32 bit number.
158Example: qm_norm32(0x00000080) = 23
159*/
160s16 qm_norm32(s32 op)
161{
162 u16 u16extraSignBits;
163 if (op == 0) {
164 return 31;
165 } else {
166 u16extraSignBits = 0;
167 while ((op >> 31) == (op >> 30)) {
168 u16extraSignBits++;
169 op = op << 1;
170 }
171 }
172 return u16extraSignBits;
173}
174
175/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
176static const s16 log_table[] = {
177 0,
178 1455,
179 2866,
180 4236,
181 5568,
182 6863,
183 8124,
184 9352,
185 10549,
186 11716,
187 12855,
188 13968,
189 15055,
190 16117,
191 17156,
192 18173,
193 19168,
194 20143,
195 21098,
196 22034,
197 22952,
198 23852,
199 24736,
200 25604,
201 26455,
202 27292,
203 28114,
204 28922,
205 29717,
206 30498,
207 31267,
208 32024
209};
210
211#define LOG_TABLE_SIZE 32 /* log_table size */
212#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */
213#define Q_LOG_TABLE 15 /* qformat of log_table */
214#define LOG10_2 19728 /* log10(2) in q.16 */
215
216/*
217Description:
218This routine takes the input number N and its q format qN and compute
219the log10(N). This routine first normalizes the input no N. Then N is in mag*(2^x) format.
220mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed.
221From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
222This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs.
223As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup.
224Next 16 MSBs are used for interpolation.
225Inputs:
226N - number to which log10 has to be found.
227qN - q format of N
228log10N - address where log10(N) will be written.
229qLog10N - address where log10N qformat will be written.
230Note/Problem:
231For accurate results input should be in normalized or near normalized form.
232*/
233void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
234{
235 s16 s16norm, s16tableIndex, s16errorApproximation;
236 u16 u16offset;
237 s32 s32log;
238
239 /* normalize the N. */
240 s16norm = qm_norm32(N);
241 N = N << s16norm;
242
243 /* The qformat of N after normalization.
244 * -30 is added to treat the no as between 1.0 to 2.0
245 * i.e. after adding the -30 to the qformat the decimal point will be
246 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
247 * at the right side of 30th bit.
248 */
249 qN = qN + s16norm - 30;
250
251 /* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */
252 s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
253
254 /* remove the MSB. the MSB is always 1 after normalization. */
255 s16tableIndex =
256 s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
257
258 /* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
259 N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
260
261 /* take the offset as the 16 MSBS after table index.
262 */
263 u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
264
265 /* look the log value in the table. */
266 s32log = log_table[s16tableIndex]; /* q.15 format */
267
268 /* interpolate using the offset. */
269 s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex])); /* q.15 */
270
271 s32log = qm_add16((s16) s32log, s16errorApproximation); /* q.15 format */
272
273 /* adjust for the qformat of the N as
274 * log2(mag * 2^x) = log2(mag) + x
275 */
276 s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */
277
278 /* normalize the result. */
279 s16norm = qm_norm32(s32log);
280
281 /* bring all the important bits into lower 16 bits */
282 s32log = qm_shl32(s32log, s16norm - 16); /* q.15+s16norm-16 format */
283
284 /* compute the log10(N) by multiplying log2(N) with log10(2).
285 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
286 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
287 */
288 *log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
289
290 /* write the q format of the result. */
291 *qLog10N = 15 + s16norm - 16 + 1;
292
293 return;
294}
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h
new file mode 100644
index 00000000000..20e3783f921
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_QMATH_H_
18#define _BRCM_QMATH_H_
19
20#include <types.h>
21
22u16 qm_mulu16(u16 op1, u16 op2);
23
24s16 qm_muls16(s16 op1, s16 op2);
25
26s32 qm_add32(s32 op1, s32 op2);
27
28s16 qm_add16(s16 op1, s16 op2);
29
30s16 qm_sub16(s16 op1, s16 op2);
31
32s32 qm_shl32(s32 op, int shift);
33
34s16 qm_shl16(s16 op, int shift);
35
36s16 qm_shr16(s16 op, int shift);
37
38s16 qm_norm32(s32 op);
39
40void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
41
42#endif /* #ifndef _BRCM_QMATH_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h
new file mode 100644
index 00000000000..c3a675455ff
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h
@@ -0,0 +1,1533 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_PHY_RADIO_H_
18#define _BRCM_PHY_RADIO_H_
19
20#define RADIO_IDCODE 0x01
21
22#define RADIO_DEFAULT_CORE 0
23
24#define RXC0_RSSI_RST 0x80
25#define RXC0_MODE_RSSI 0x40
26#define RXC0_MODE_OFF 0x20
27#define RXC0_MODE_CM 0x10
28#define RXC0_LAN_LOAD 0x08
29#define RXC0_OFF_ADJ_MASK 0x07
30
31#define TXC0_MODE_TXLPF 0x04
32#define TXC0_PA_TSSI_EN 0x02
33#define TXC0_TSSI_EN 0x01
34
35#define TXC1_PA_GAIN_MASK 0x60
36#define TXC1_PA_GAIN_3DB 0x40
37#define TXC1_PA_GAIN_2DB 0x20
38#define TXC1_TX_MIX_GAIN 0x10
39#define TXC1_OFF_I_MASK 0x0c
40#define TXC1_OFF_Q_MASK 0x03
41
42#define RADIO_2055_READ_OFF 0x100
43#define RADIO_2057_READ_OFF 0x200
44
45#define RADIO_2055_GEN_SPARE 0x00
46#define RADIO_2055_SP_PIN_PD 0x02
47#define RADIO_2055_SP_RSSI_CORE1 0x03
48#define RADIO_2055_SP_PD_MISC_CORE1 0x04
49#define RADIO_2055_SP_RSSI_CORE2 0x05
50#define RADIO_2055_SP_PD_MISC_CORE2 0x06
51#define RADIO_2055_SP_RX_GC1_CORE1 0x07
52#define RADIO_2055_SP_RX_GC2_CORE1 0x08
53#define RADIO_2055_SP_RX_GC1_CORE2 0x09
54#define RADIO_2055_SP_RX_GC2_CORE2 0x0a
55#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b
56#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c
57#define RADIO_2055_SP_TX_GC1_CORE1 0x0d
58#define RADIO_2055_SP_TX_GC2_CORE1 0x0e
59#define RADIO_2055_SP_TX_GC1_CORE2 0x0f
60#define RADIO_2055_SP_TX_GC2_CORE2 0x10
61#define RADIO_2055_MASTER_CNTRL1 0x11
62#define RADIO_2055_MASTER_CNTRL2 0x12
63#define RADIO_2055_PD_LGEN 0x13
64#define RADIO_2055_PD_PLL_TS 0x14
65#define RADIO_2055_PD_CORE1_LGBUF 0x15
66#define RADIO_2055_PD_CORE1_TX 0x16
67#define RADIO_2055_PD_CORE1_RXTX 0x17
68#define RADIO_2055_PD_CORE1_RSSI_MISC 0x18
69#define RADIO_2055_PD_CORE2_LGBUF 0x19
70#define RADIO_2055_PD_CORE2_TX 0x1a
71#define RADIO_2055_PD_CORE2_RXTX 0x1b
72#define RADIO_2055_PD_CORE2_RSSI_MISC 0x1c
73#define RADIO_2055_PWRDET_LGEN 0x1d
74#define RADIO_2055_PWRDET_LGBUF_CORE1 0x1e
75#define RADIO_2055_PWRDET_RXTX_CORE1 0x1f
76#define RADIO_2055_PWRDET_LGBUF_CORE2 0x20
77#define RADIO_2055_PWRDET_RXTX_CORE2 0x21
78#define RADIO_2055_RRCCAL_CNTRL_SPARE 0x22
79#define RADIO_2055_RRCCAL_N_OPT_SEL 0x23
80#define RADIO_2055_CAL_MISC 0x24
81#define RADIO_2055_CAL_COUNTER_OUT 0x25
82#define RADIO_2055_CAL_COUNTER_OUT2 0x26
83#define RADIO_2055_CAL_CVAR_CNTRL 0x27
84#define RADIO_2055_CAL_RVAR_CNTRL 0x28
85#define RADIO_2055_CAL_LPO_CNTRL 0x29
86#define RADIO_2055_CAL_TS 0x2a
87#define RADIO_2055_CAL_RCCAL_READ_TS 0x2b
88#define RADIO_2055_CAL_RCAL_READ_TS 0x2c
89#define RADIO_2055_PAD_DRIVER 0x2d
90#define RADIO_2055_XO_CNTRL1 0x2e
91#define RADIO_2055_XO_CNTRL2 0x2f
92#define RADIO_2055_XO_REGULATOR 0x30
93#define RADIO_2055_XO_MISC 0x31
94#define RADIO_2055_PLL_LF_C1 0x32
95#define RADIO_2055_PLL_CAL_VTH 0x33
96#define RADIO_2055_PLL_LF_C2 0x34
97#define RADIO_2055_PLL_REF 0x35
98#define RADIO_2055_PLL_LF_R1 0x36
99#define RADIO_2055_PLL_PFD_CP 0x37
100#define RADIO_2055_PLL_IDAC_CPOPAMP 0x38
101#define RADIO_2055_PLL_CP_REGULATOR 0x39
102#define RADIO_2055_PLL_RCAL 0x3a
103#define RADIO_2055_RF_PLL_MOD0 0x3b
104#define RADIO_2055_RF_PLL_MOD1 0x3c
105#define RADIO_2055_RF_MMD_IDAC1 0x3d
106#define RADIO_2055_RF_MMD_IDAC0 0x3e
107#define RADIO_2055_RF_MMD_SPARE 0x3f
108#define RADIO_2055_VCO_CAL1 0x40
109#define RADIO_2055_VCO_CAL2 0x41
110#define RADIO_2055_VCO_CAL3 0x42
111#define RADIO_2055_VCO_CAL4 0x43
112#define RADIO_2055_VCO_CAL5 0x44
113#define RADIO_2055_VCO_CAL6 0x45
114#define RADIO_2055_VCO_CAL7 0x46
115#define RADIO_2055_VCO_CAL8 0x47
116#define RADIO_2055_VCO_CAL9 0x48
117#define RADIO_2055_VCO_CAL10 0x49
118#define RADIO_2055_VCO_CAL11 0x4a
119#define RADIO_2055_VCO_CAL12 0x4b
120#define RADIO_2055_VCO_CAL13 0x4c
121#define RADIO_2055_VCO_CAL14 0x4d
122#define RADIO_2055_VCO_CAL15 0x4e
123#define RADIO_2055_VCO_CAL16 0x4f
124#define RADIO_2055_VCO_KVCO 0x50
125#define RADIO_2055_VCO_CAP_TAIL 0x51
126#define RADIO_2055_VCO_IDAC_VCO 0x52
127#define RADIO_2055_VCO_REGULATOR 0x53
128#define RADIO_2055_PLL_RF_VTH 0x54
129#define RADIO_2055_LGBUF_CEN_BUF 0x55
130#define RADIO_2055_LGEN_TUNE1 0x56
131#define RADIO_2055_LGEN_TUNE2 0x57
132#define RADIO_2055_LGEN_IDAC1 0x58
133#define RADIO_2055_LGEN_IDAC2 0x59
134#define RADIO_2055_LGEN_BIAS_CNT 0x5a
135#define RADIO_2055_LGEN_BIAS_IDAC 0x5b
136#define RADIO_2055_LGEN_RCAL 0x5c
137#define RADIO_2055_LGEN_DIV 0x5d
138#define RADIO_2055_LGEN_SPARE2 0x5e
139#define RADIO_2055_CORE1_LGBUF_A_TUNE 0x5f
140#define RADIO_2055_CORE1_LGBUF_G_TUNE 0x60
141#define RADIO_2055_CORE1_LGBUF_DIV 0x61
142#define RADIO_2055_CORE1_LGBUF_A_IDAC 0x62
143#define RADIO_2055_CORE1_LGBUF_G_IDAC 0x63
144#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64
145#define RADIO_2055_CORE1_LGBUF_SPARE 0x65
146#define RADIO_2055_CORE1_RXRF_SPC1 0x66
147#define RADIO_2055_CORE1_RXRF_REG1 0x67
148#define RADIO_2055_CORE1_RXRF_REG2 0x68
149#define RADIO_2055_CORE1_RXRF_RCAL 0x69
150#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a
151#define RADIO_2055_CORE1_RXBB_LPF 0x6b
152#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c
153#define RADIO_2055_CORE1_RXBB_VGA1_IDAC 0x6d
154#define RADIO_2055_CORE1_RXBB_VGA2_IDAC 0x6e
155#define RADIO_2055_CORE1_RXBB_VGA3_IDAC 0x6f
156#define RADIO_2055_CORE1_RXBB_BUFO_CTRL 0x70
157#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71
158#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72
159#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73
160#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74
161#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75
162#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76
163#define RADIO_2055_CORE1_RXBB_REGULATOR 0x77
164#define RADIO_2055_CORE1_RXBB_SPARE1 0x78
165#define RADIO_2055_CORE1_RXTXBB_RCAL 0x79
166#define RADIO_2055_CORE1_TXRF_SGM_PGA 0x7a
167#define RADIO_2055_CORE1_TXRF_SGM_PAD 0x7b
168#define RADIO_2055_CORE1_TXRF_CNTR_PGA1 0x7c
169#define RADIO_2055_CORE1_TXRF_CNTR_PAD1 0x7d
170#define RADIO_2055_CORE1_TX_RFPGA_IDAC 0x7e
171#define RADIO_2055_CORE1_TX_PGA_PAD_TN 0x7f
172#define RADIO_2055_CORE1_TX_PAD_IDAC1 0x80
173#define RADIO_2055_CORE1_TX_PAD_IDAC2 0x81
174#define RADIO_2055_CORE1_TX_MX_BGTRIM 0x82
175#define RADIO_2055_CORE1_TXRF_RCAL 0x83
176#define RADIO_2055_CORE1_TXRF_PAD_TSSI1 0x84
177#define RADIO_2055_CORE1_TXRF_PAD_TSSI2 0x85
178#define RADIO_2055_CORE1_TX_RF_SPARE 0x86
179#define RADIO_2055_CORE1_TXRF_IQCAL1 0x87
180#define RADIO_2055_CORE1_TXRF_IQCAL2 0x88
181#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89
182#define RADIO_2055_CORE1_TXBB_LPF1 0x8a
183#define RADIO_2055_CORE1_TX_VOS_CNCL 0x8b
184#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c
185#define RADIO_2055_CORE1_TX_BB_MXGM 0x8d
186#define RADIO_2055_CORE2_LGBUF_A_TUNE 0x8e
187#define RADIO_2055_CORE2_LGBUF_G_TUNE 0x8f
188#define RADIO_2055_CORE2_LGBUF_DIV 0x90
189#define RADIO_2055_CORE2_LGBUF_A_IDAC 0x91
190#define RADIO_2055_CORE2_LGBUF_G_IDAC 0x92
191#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93
192#define RADIO_2055_CORE2_LGBUF_SPARE 0x94
193#define RADIO_2055_CORE2_RXRF_SPC1 0x95
194#define RADIO_2055_CORE2_RXRF_REG1 0x96
195#define RADIO_2055_CORE2_RXRF_REG2 0x97
196#define RADIO_2055_CORE2_RXRF_RCAL 0x98
197#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99
198#define RADIO_2055_CORE2_RXBB_LPF 0x9a
199#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b
200#define RADIO_2055_CORE2_RXBB_VGA1_IDAC 0x9c
201#define RADIO_2055_CORE2_RXBB_VGA2_IDAC 0x9d
202#define RADIO_2055_CORE2_RXBB_VGA3_IDAC 0x9e
203#define RADIO_2055_CORE2_RXBB_BUFO_CTRL 0x9f
204#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0
205#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1
206#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2
207#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3
208#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4
209#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5
210#define RADIO_2055_CORE2_RXBB_REGULATOR 0xa6
211#define RADIO_2055_CORE2_RXBB_SPARE1 0xa7
212#define RADIO_2055_CORE2_RXTXBB_RCAL 0xa8
213#define RADIO_2055_CORE2_TXRF_SGM_PGA 0xa9
214#define RADIO_2055_CORE2_TXRF_SGM_PAD 0xaa
215#define RADIO_2055_CORE2_TXRF_CNTR_PGA1 0xab
216#define RADIO_2055_CORE2_TXRF_CNTR_PAD1 0xac
217#define RADIO_2055_CORE2_TX_RFPGA_IDAC 0xad
218#define RADIO_2055_CORE2_TX_PGA_PAD_TN 0xae
219#define RADIO_2055_CORE2_TX_PAD_IDAC1 0xaf
220#define RADIO_2055_CORE2_TX_PAD_IDAC2 0xb0
221#define RADIO_2055_CORE2_TX_MX_BGTRIM 0xb1
222#define RADIO_2055_CORE2_TXRF_RCAL 0xb2
223#define RADIO_2055_CORE2_TXRF_PAD_TSSI1 0xb3
224#define RADIO_2055_CORE2_TXRF_PAD_TSSI2 0xb4
225#define RADIO_2055_CORE2_TX_RF_SPARE 0xb5
226#define RADIO_2055_CORE2_TXRF_IQCAL1 0xb6
227#define RADIO_2055_CORE2_TXRF_IQCAL2 0xb7
228#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8
229#define RADIO_2055_CORE2_TXBB_LPF1 0xb9
230#define RADIO_2055_CORE2_TX_VOS_CNCL 0xba
231#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb
232#define RADIO_2055_CORE2_TX_BB_MXGM 0xbc
233#define RADIO_2055_PRG_GC_HPVGA23_21 0xbd
234#define RADIO_2055_PRG_GC_HPVGA23_22 0xbe
235#define RADIO_2055_PRG_GC_HPVGA23_23 0xbf
236#define RADIO_2055_PRG_GC_HPVGA23_24 0xc0
237#define RADIO_2055_PRG_GC_HPVGA23_25 0xc1
238#define RADIO_2055_PRG_GC_HPVGA23_26 0xc2
239#define RADIO_2055_PRG_GC_HPVGA23_27 0xc3
240#define RADIO_2055_PRG_GC_HPVGA23_28 0xc4
241#define RADIO_2055_PRG_GC_HPVGA23_29 0xc5
242#define RADIO_2055_PRG_GC_HPVGA23_30 0xc6
243#define RADIO_2055_CORE1_LNA_GAINBST 0xcd
244#define RADIO_2055_CORE1_B0_NBRSSI_VCM 0xd2
245#define RADIO_2055_CORE1_GEN_SPARE2 0xd6
246#define RADIO_2055_CORE2_LNA_GAINBST 0xd9
247#define RADIO_2055_CORE2_B0_NBRSSI_VCM 0xde
248#define RADIO_2055_CORE2_GEN_SPARE2 0xe2
249
250#define RADIO_2055_GAINBST_GAIN_DB 6
251#define RADIO_2055_GAINBST_CODE 0x6
252
253#define RADIO_2055_JTAGCTRL_MASK 0x04
254#define RADIO_2055_JTAGSYNC_MASK 0x08
255#define RADIO_2055_RRCAL_START 0x40
256#define RADIO_2055_RRCAL_RST_N 0x01
257#define RADIO_2055_CAL_LPO_ENABLE 0x80
258#define RADIO_2055_RCAL_DONE 0x80
259#define RADIO_2055_NBRSSI_VCM_I_MASK 0x03
260#define RADIO_2055_NBRSSI_VCM_I_SHIFT 0x00
261#define RADIO_2055_NBRSSI_VCM_Q_MASK 0x03
262#define RADIO_2055_NBRSSI_VCM_Q_SHIFT 0x00
263#define RADIO_2055_WBRSSI_VCM_IQ_MASK 0x0c
264#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT 0x02
265#define RADIO_2055_NBRSSI_PD 0x01
266#define RADIO_2055_WBRSSI_G1_PD 0x04
267#define RADIO_2055_WBRSSI_G2_PD 0x02
268#define RADIO_2055_NBRSSI_SEL 0x01
269#define RADIO_2055_WBRSSI_G1_SEL 0x04
270#define RADIO_2055_WBRSSI_G2_SEL 0x02
271#define RADIO_2055_COUPLE_RX_MASK 0x01
272#define RADIO_2055_COUPLE_TX_MASK 0x02
273#define RADIO_2055_GAINBST_DISABLE 0x02
274#define RADIO_2055_GAINBST_VAL_MASK 0x07
275#define RADIO_2055_RXMX_GC_MASK 0x0c
276
277#define RADIO_MIMO_CORESEL_OFF 0x0
278#define RADIO_MIMO_CORESEL_CORE1 0x1
279#define RADIO_MIMO_CORESEL_CORE2 0x2
280#define RADIO_MIMO_CORESEL_CORE3 0x3
281#define RADIO_MIMO_CORESEL_CORE4 0x4
282#define RADIO_MIMO_CORESEL_ALLRX 0x5
283#define RADIO_MIMO_CORESEL_ALLTX 0x6
284#define RADIO_MIMO_CORESEL_ALLRXTX 0x7
285
286#define RADIO_2064_READ_OFF 0x200
287
288#define RADIO_2064_REG000 0x0
289#define RADIO_2064_REG001 0x1
290#define RADIO_2064_REG002 0x2
291#define RADIO_2064_REG003 0x3
292#define RADIO_2064_REG004 0x4
293#define RADIO_2064_REG005 0x5
294#define RADIO_2064_REG006 0x6
295#define RADIO_2064_REG007 0x7
296#define RADIO_2064_REG008 0x8
297#define RADIO_2064_REG009 0x9
298#define RADIO_2064_REG00A 0xa
299#define RADIO_2064_REG00B 0xb
300#define RADIO_2064_REG00C 0xc
301#define RADIO_2064_REG00D 0xd
302#define RADIO_2064_REG00E 0xe
303#define RADIO_2064_REG00F 0xf
304#define RADIO_2064_REG010 0x10
305#define RADIO_2064_REG011 0x11
306#define RADIO_2064_REG012 0x12
307#define RADIO_2064_REG013 0x13
308#define RADIO_2064_REG014 0x14
309#define RADIO_2064_REG015 0x15
310#define RADIO_2064_REG016 0x16
311#define RADIO_2064_REG017 0x17
312#define RADIO_2064_REG018 0x18
313#define RADIO_2064_REG019 0x19
314#define RADIO_2064_REG01A 0x1a
315#define RADIO_2064_REG01B 0x1b
316#define RADIO_2064_REG01C 0x1c
317#define RADIO_2064_REG01D 0x1d
318#define RADIO_2064_REG01E 0x1e
319#define RADIO_2064_REG01F 0x1f
320#define RADIO_2064_REG020 0x20
321#define RADIO_2064_REG021 0x21
322#define RADIO_2064_REG022 0x22
323#define RADIO_2064_REG023 0x23
324#define RADIO_2064_REG024 0x24
325#define RADIO_2064_REG025 0x25
326#define RADIO_2064_REG026 0x26
327#define RADIO_2064_REG027 0x27
328#define RADIO_2064_REG028 0x28
329#define RADIO_2064_REG029 0x29
330#define RADIO_2064_REG02A 0x2a
331#define RADIO_2064_REG02B 0x2b
332#define RADIO_2064_REG02C 0x2c
333#define RADIO_2064_REG02D 0x2d
334#define RADIO_2064_REG02E 0x2e
335#define RADIO_2064_REG02F 0x2f
336#define RADIO_2064_REG030 0x30
337#define RADIO_2064_REG031 0x31
338#define RADIO_2064_REG032 0x32
339#define RADIO_2064_REG033 0x33
340#define RADIO_2064_REG034 0x34
341#define RADIO_2064_REG035 0x35
342#define RADIO_2064_REG036 0x36
343#define RADIO_2064_REG037 0x37
344#define RADIO_2064_REG038 0x38
345#define RADIO_2064_REG039 0x39
346#define RADIO_2064_REG03A 0x3a
347#define RADIO_2064_REG03B 0x3b
348#define RADIO_2064_REG03C 0x3c
349#define RADIO_2064_REG03D 0x3d
350#define RADIO_2064_REG03E 0x3e
351#define RADIO_2064_REG03F 0x3f
352#define RADIO_2064_REG040 0x40
353#define RADIO_2064_REG041 0x41
354#define RADIO_2064_REG042 0x42
355#define RADIO_2064_REG043 0x43
356#define RADIO_2064_REG044 0x44
357#define RADIO_2064_REG045 0x45
358#define RADIO_2064_REG046 0x46
359#define RADIO_2064_REG047 0x47
360#define RADIO_2064_REG048 0x48
361#define RADIO_2064_REG049 0x49
362#define RADIO_2064_REG04A 0x4a
363#define RADIO_2064_REG04B 0x4b
364#define RADIO_2064_REG04C 0x4c
365#define RADIO_2064_REG04D 0x4d
366#define RADIO_2064_REG04E 0x4e
367#define RADIO_2064_REG04F 0x4f
368#define RADIO_2064_REG050 0x50
369#define RADIO_2064_REG051 0x51
370#define RADIO_2064_REG052 0x52
371#define RADIO_2064_REG053 0x53
372#define RADIO_2064_REG054 0x54
373#define RADIO_2064_REG055 0x55
374#define RADIO_2064_REG056 0x56
375#define RADIO_2064_REG057 0x57
376#define RADIO_2064_REG058 0x58
377#define RADIO_2064_REG059 0x59
378#define RADIO_2064_REG05A 0x5a
379#define RADIO_2064_REG05B 0x5b
380#define RADIO_2064_REG05C 0x5c
381#define RADIO_2064_REG05D 0x5d
382#define RADIO_2064_REG05E 0x5e
383#define RADIO_2064_REG05F 0x5f
384#define RADIO_2064_REG060 0x60
385#define RADIO_2064_REG061 0x61
386#define RADIO_2064_REG062 0x62
387#define RADIO_2064_REG063 0x63
388#define RADIO_2064_REG064 0x64
389#define RADIO_2064_REG065 0x65
390#define RADIO_2064_REG066 0x66
391#define RADIO_2064_REG067 0x67
392#define RADIO_2064_REG068 0x68
393#define RADIO_2064_REG069 0x69
394#define RADIO_2064_REG06A 0x6a
395#define RADIO_2064_REG06B 0x6b
396#define RADIO_2064_REG06C 0x6c
397#define RADIO_2064_REG06D 0x6d
398#define RADIO_2064_REG06E 0x6e
399#define RADIO_2064_REG06F 0x6f
400#define RADIO_2064_REG070 0x70
401#define RADIO_2064_REG071 0x71
402#define RADIO_2064_REG072 0x72
403#define RADIO_2064_REG073 0x73
404#define RADIO_2064_REG074 0x74
405#define RADIO_2064_REG075 0x75
406#define RADIO_2064_REG076 0x76
407#define RADIO_2064_REG077 0x77
408#define RADIO_2064_REG078 0x78
409#define RADIO_2064_REG079 0x79
410#define RADIO_2064_REG07A 0x7a
411#define RADIO_2064_REG07B 0x7b
412#define RADIO_2064_REG07C 0x7c
413#define RADIO_2064_REG07D 0x7d
414#define RADIO_2064_REG07E 0x7e
415#define RADIO_2064_REG07F 0x7f
416#define RADIO_2064_REG080 0x80
417#define RADIO_2064_REG081 0x81
418#define RADIO_2064_REG082 0x82
419#define RADIO_2064_REG083 0x83
420#define RADIO_2064_REG084 0x84
421#define RADIO_2064_REG085 0x85
422#define RADIO_2064_REG086 0x86
423#define RADIO_2064_REG087 0x87
424#define RADIO_2064_REG088 0x88
425#define RADIO_2064_REG089 0x89
426#define RADIO_2064_REG08A 0x8a
427#define RADIO_2064_REG08B 0x8b
428#define RADIO_2064_REG08C 0x8c
429#define RADIO_2064_REG08D 0x8d
430#define RADIO_2064_REG08E 0x8e
431#define RADIO_2064_REG08F 0x8f
432#define RADIO_2064_REG090 0x90
433#define RADIO_2064_REG091 0x91
434#define RADIO_2064_REG092 0x92
435#define RADIO_2064_REG093 0x93
436#define RADIO_2064_REG094 0x94
437#define RADIO_2064_REG095 0x95
438#define RADIO_2064_REG096 0x96
439#define RADIO_2064_REG097 0x97
440#define RADIO_2064_REG098 0x98
441#define RADIO_2064_REG099 0x99
442#define RADIO_2064_REG09A 0x9a
443#define RADIO_2064_REG09B 0x9b
444#define RADIO_2064_REG09C 0x9c
445#define RADIO_2064_REG09D 0x9d
446#define RADIO_2064_REG09E 0x9e
447#define RADIO_2064_REG09F 0x9f
448#define RADIO_2064_REG0A0 0xa0
449#define RADIO_2064_REG0A1 0xa1
450#define RADIO_2064_REG0A2 0xa2
451#define RADIO_2064_REG0A3 0xa3
452#define RADIO_2064_REG0A4 0xa4
453#define RADIO_2064_REG0A5 0xa5
454#define RADIO_2064_REG0A6 0xa6
455#define RADIO_2064_REG0A7 0xa7
456#define RADIO_2064_REG0A8 0xa8
457#define RADIO_2064_REG0A9 0xa9
458#define RADIO_2064_REG0AA 0xaa
459#define RADIO_2064_REG0AB 0xab
460#define RADIO_2064_REG0AC 0xac
461#define RADIO_2064_REG0AD 0xad
462#define RADIO_2064_REG0AE 0xae
463#define RADIO_2064_REG0AF 0xaf
464#define RADIO_2064_REG0B0 0xb0
465#define RADIO_2064_REG0B1 0xb1
466#define RADIO_2064_REG0B2 0xb2
467#define RADIO_2064_REG0B3 0xb3
468#define RADIO_2064_REG0B4 0xb4
469#define RADIO_2064_REG0B5 0xb5
470#define RADIO_2064_REG0B6 0xb6
471#define RADIO_2064_REG0B7 0xb7
472#define RADIO_2064_REG0B8 0xb8
473#define RADIO_2064_REG0B9 0xb9
474#define RADIO_2064_REG0BA 0xba
475#define RADIO_2064_REG0BB 0xbb
476#define RADIO_2064_REG0BC 0xbc
477#define RADIO_2064_REG0BD 0xbd
478#define RADIO_2064_REG0BE 0xbe
479#define RADIO_2064_REG0BF 0xbf
480#define RADIO_2064_REG0C0 0xc0
481#define RADIO_2064_REG0C1 0xc1
482#define RADIO_2064_REG0C2 0xc2
483#define RADIO_2064_REG0C3 0xc3
484#define RADIO_2064_REG0C4 0xc4
485#define RADIO_2064_REG0C5 0xc5
486#define RADIO_2064_REG0C6 0xc6
487#define RADIO_2064_REG0C7 0xc7
488#define RADIO_2064_REG0C8 0xc8
489#define RADIO_2064_REG0C9 0xc9
490#define RADIO_2064_REG0CA 0xca
491#define RADIO_2064_REG0CB 0xcb
492#define RADIO_2064_REG0CC 0xcc
493#define RADIO_2064_REG0CD 0xcd
494#define RADIO_2064_REG0CE 0xce
495#define RADIO_2064_REG0CF 0xcf
496#define RADIO_2064_REG0D0 0xd0
497#define RADIO_2064_REG0D1 0xd1
498#define RADIO_2064_REG0D2 0xd2
499#define RADIO_2064_REG0D3 0xd3
500#define RADIO_2064_REG0D4 0xd4
501#define RADIO_2064_REG0D5 0xd5
502#define RADIO_2064_REG0D6 0xd6
503#define RADIO_2064_REG0D7 0xd7
504#define RADIO_2064_REG0D8 0xd8
505#define RADIO_2064_REG0D9 0xd9
506#define RADIO_2064_REG0DA 0xda
507#define RADIO_2064_REG0DB 0xdb
508#define RADIO_2064_REG0DC 0xdc
509#define RADIO_2064_REG0DD 0xdd
510#define RADIO_2064_REG0DE 0xde
511#define RADIO_2064_REG0DF 0xdf
512#define RADIO_2064_REG0E0 0xe0
513#define RADIO_2064_REG0E1 0xe1
514#define RADIO_2064_REG0E2 0xe2
515#define RADIO_2064_REG0E3 0xe3
516#define RADIO_2064_REG0E4 0xe4
517#define RADIO_2064_REG0E5 0xe5
518#define RADIO_2064_REG0E6 0xe6
519#define RADIO_2064_REG0E7 0xe7
520#define RADIO_2064_REG0E8 0xe8
521#define RADIO_2064_REG0E9 0xe9
522#define RADIO_2064_REG0EA 0xea
523#define RADIO_2064_REG0EB 0xeb
524#define RADIO_2064_REG0EC 0xec
525#define RADIO_2064_REG0ED 0xed
526#define RADIO_2064_REG0EE 0xee
527#define RADIO_2064_REG0EF 0xef
528#define RADIO_2064_REG0F0 0xf0
529#define RADIO_2064_REG0F1 0xf1
530#define RADIO_2064_REG0F2 0xf2
531#define RADIO_2064_REG0F3 0xf3
532#define RADIO_2064_REG0F4 0xf4
533#define RADIO_2064_REG0F5 0xf5
534#define RADIO_2064_REG0F6 0xf6
535#define RADIO_2064_REG0F7 0xf7
536#define RADIO_2064_REG0F8 0xf8
537#define RADIO_2064_REG0F9 0xf9
538#define RADIO_2064_REG0FA 0xfa
539#define RADIO_2064_REG0FB 0xfb
540#define RADIO_2064_REG0FC 0xfc
541#define RADIO_2064_REG0FD 0xfd
542#define RADIO_2064_REG0FE 0xfe
543#define RADIO_2064_REG0FF 0xff
544#define RADIO_2064_REG100 0x100
545#define RADIO_2064_REG101 0x101
546#define RADIO_2064_REG102 0x102
547#define RADIO_2064_REG103 0x103
548#define RADIO_2064_REG104 0x104
549#define RADIO_2064_REG105 0x105
550#define RADIO_2064_REG106 0x106
551#define RADIO_2064_REG107 0x107
552#define RADIO_2064_REG108 0x108
553#define RADIO_2064_REG109 0x109
554#define RADIO_2064_REG10A 0x10a
555#define RADIO_2064_REG10B 0x10b
556#define RADIO_2064_REG10C 0x10c
557#define RADIO_2064_REG10D 0x10d
558#define RADIO_2064_REG10E 0x10e
559#define RADIO_2064_REG10F 0x10f
560#define RADIO_2064_REG110 0x110
561#define RADIO_2064_REG111 0x111
562#define RADIO_2064_REG112 0x112
563#define RADIO_2064_REG113 0x113
564#define RADIO_2064_REG114 0x114
565#define RADIO_2064_REG115 0x115
566#define RADIO_2064_REG116 0x116
567#define RADIO_2064_REG117 0x117
568#define RADIO_2064_REG118 0x118
569#define RADIO_2064_REG119 0x119
570#define RADIO_2064_REG11A 0x11a
571#define RADIO_2064_REG11B 0x11b
572#define RADIO_2064_REG11C 0x11c
573#define RADIO_2064_REG11D 0x11d
574#define RADIO_2064_REG11E 0x11e
575#define RADIO_2064_REG11F 0x11f
576#define RADIO_2064_REG120 0x120
577#define RADIO_2064_REG121 0x121
578#define RADIO_2064_REG122 0x122
579#define RADIO_2064_REG123 0x123
580#define RADIO_2064_REG124 0x124
581#define RADIO_2064_REG125 0x125
582#define RADIO_2064_REG126 0x126
583#define RADIO_2064_REG127 0x127
584#define RADIO_2064_REG128 0x128
585#define RADIO_2064_REG129 0x129
586#define RADIO_2064_REG12A 0x12a
587#define RADIO_2064_REG12B 0x12b
588#define RADIO_2064_REG12C 0x12c
589#define RADIO_2064_REG12D 0x12d
590#define RADIO_2064_REG12E 0x12e
591#define RADIO_2064_REG12F 0x12f
592#define RADIO_2064_REG130 0x130
593
594#define RADIO_2056_SYN (0x0 << 12)
595#define RADIO_2056_TX0 (0x2 << 12)
596#define RADIO_2056_TX1 (0x3 << 12)
597#define RADIO_2056_RX0 (0x6 << 12)
598#define RADIO_2056_RX1 (0x7 << 12)
599#define RADIO_2056_ALLTX (0xe << 12)
600#define RADIO_2056_ALLRX (0xf << 12)
601
602#define RADIO_2056_SYN_RESERVED_ADDR0 0x0
603#define RADIO_2056_SYN_IDCODE 0x1
604#define RADIO_2056_SYN_RESERVED_ADDR2 0x2
605#define RADIO_2056_SYN_RESERVED_ADDR3 0x3
606#define RADIO_2056_SYN_RESERVED_ADDR4 0x4
607#define RADIO_2056_SYN_RESERVED_ADDR5 0x5
608#define RADIO_2056_SYN_RESERVED_ADDR6 0x6
609#define RADIO_2056_SYN_RESERVED_ADDR7 0x7
610#define RADIO_2056_SYN_COM_CTRL 0x8
611#define RADIO_2056_SYN_COM_PU 0x9
612#define RADIO_2056_SYN_COM_OVR 0xa
613#define RADIO_2056_SYN_COM_RESET 0xb
614#define RADIO_2056_SYN_COM_RCAL 0xc
615#define RADIO_2056_SYN_COM_RC_RXLPF 0xd
616#define RADIO_2056_SYN_COM_RC_TXLPF 0xe
617#define RADIO_2056_SYN_COM_RC_RXHPF 0xf
618#define RADIO_2056_SYN_RESERVED_ADDR16 0x10
619#define RADIO_2056_SYN_RESERVED_ADDR17 0x11
620#define RADIO_2056_SYN_RESERVED_ADDR18 0x12
621#define RADIO_2056_SYN_RESERVED_ADDR19 0x13
622#define RADIO_2056_SYN_RESERVED_ADDR20 0x14
623#define RADIO_2056_SYN_RESERVED_ADDR21 0x15
624#define RADIO_2056_SYN_RESERVED_ADDR22 0x16
625#define RADIO_2056_SYN_RESERVED_ADDR23 0x17
626#define RADIO_2056_SYN_RESERVED_ADDR24 0x18
627#define RADIO_2056_SYN_RESERVED_ADDR25 0x19
628#define RADIO_2056_SYN_RESERVED_ADDR26 0x1a
629#define RADIO_2056_SYN_RESERVED_ADDR27 0x1b
630#define RADIO_2056_SYN_RESERVED_ADDR28 0x1c
631#define RADIO_2056_SYN_RESERVED_ADDR29 0x1d
632#define RADIO_2056_SYN_RESERVED_ADDR30 0x1e
633#define RADIO_2056_SYN_RESERVED_ADDR31 0x1f
634#define RADIO_2056_SYN_GPIO_MASTER1 0x20
635#define RADIO_2056_SYN_GPIO_MASTER2 0x21
636#define RADIO_2056_SYN_TOPBIAS_MASTER 0x22
637#define RADIO_2056_SYN_TOPBIAS_RCAL 0x23
638#define RADIO_2056_SYN_AFEREG 0x24
639#define RADIO_2056_SYN_TEMPPROCSENSE 0x25
640#define RADIO_2056_SYN_TEMPPROCSENSEIDAC 0x26
641#define RADIO_2056_SYN_TEMPPROCSENSERCAL 0x27
642#define RADIO_2056_SYN_LPO 0x28
643#define RADIO_2056_SYN_VDDCAL_MASTER 0x29
644#define RADIO_2056_SYN_VDDCAL_IDAC 0x2a
645#define RADIO_2056_SYN_VDDCAL_STATUS 0x2b
646#define RADIO_2056_SYN_RCAL_MASTER 0x2c
647#define RADIO_2056_SYN_RCAL_CODE_OUT 0x2d
648#define RADIO_2056_SYN_RCCAL_CTRL0 0x2e
649#define RADIO_2056_SYN_RCCAL_CTRL1 0x2f
650#define RADIO_2056_SYN_RCCAL_CTRL2 0x30
651#define RADIO_2056_SYN_RCCAL_CTRL3 0x31
652#define RADIO_2056_SYN_RCCAL_CTRL4 0x32
653#define RADIO_2056_SYN_RCCAL_CTRL5 0x33
654#define RADIO_2056_SYN_RCCAL_CTRL6 0x34
655#define RADIO_2056_SYN_RCCAL_CTRL7 0x35
656#define RADIO_2056_SYN_RCCAL_CTRL8 0x36
657#define RADIO_2056_SYN_RCCAL_CTRL9 0x37
658#define RADIO_2056_SYN_RCCAL_CTRL10 0x38
659#define RADIO_2056_SYN_RCCAL_CTRL11 0x39
660#define RADIO_2056_SYN_ZCAL_SPARE1 0x3a
661#define RADIO_2056_SYN_ZCAL_SPARE2 0x3b
662#define RADIO_2056_SYN_PLL_MAST1 0x3c
663#define RADIO_2056_SYN_PLL_MAST2 0x3d
664#define RADIO_2056_SYN_PLL_MAST3 0x3e
665#define RADIO_2056_SYN_PLL_BIAS_RESET 0x3f
666#define RADIO_2056_SYN_PLL_XTAL0 0x40
667#define RADIO_2056_SYN_PLL_XTAL1 0x41
668#define RADIO_2056_SYN_PLL_XTAL3 0x42
669#define RADIO_2056_SYN_PLL_XTAL4 0x43
670#define RADIO_2056_SYN_PLL_XTAL5 0x44
671#define RADIO_2056_SYN_PLL_XTAL6 0x45
672#define RADIO_2056_SYN_PLL_REFDIV 0x46
673#define RADIO_2056_SYN_PLL_PFD 0x47
674#define RADIO_2056_SYN_PLL_CP1 0x48
675#define RADIO_2056_SYN_PLL_CP2 0x49
676#define RADIO_2056_SYN_PLL_CP3 0x4a
677#define RADIO_2056_SYN_PLL_LOOPFILTER1 0x4b
678#define RADIO_2056_SYN_PLL_LOOPFILTER2 0x4c
679#define RADIO_2056_SYN_PLL_LOOPFILTER3 0x4d
680#define RADIO_2056_SYN_PLL_LOOPFILTER4 0x4e
681#define RADIO_2056_SYN_PLL_LOOPFILTER5 0x4f
682#define RADIO_2056_SYN_PLL_MMD1 0x50
683#define RADIO_2056_SYN_PLL_MMD2 0x51
684#define RADIO_2056_SYN_PLL_VCO1 0x52
685#define RADIO_2056_SYN_PLL_VCO2 0x53
686#define RADIO_2056_SYN_PLL_MONITOR1 0x54
687#define RADIO_2056_SYN_PLL_MONITOR2 0x55
688#define RADIO_2056_SYN_PLL_VCOCAL1 0x56
689#define RADIO_2056_SYN_PLL_VCOCAL2 0x57
690#define RADIO_2056_SYN_PLL_VCOCAL4 0x58
691#define RADIO_2056_SYN_PLL_VCOCAL5 0x59
692#define RADIO_2056_SYN_PLL_VCOCAL6 0x5a
693#define RADIO_2056_SYN_PLL_VCOCAL7 0x5b
694#define RADIO_2056_SYN_PLL_VCOCAL8 0x5c
695#define RADIO_2056_SYN_PLL_VCOCAL9 0x5d
696#define RADIO_2056_SYN_PLL_VCOCAL10 0x5e
697#define RADIO_2056_SYN_PLL_VCOCAL11 0x5f
698#define RADIO_2056_SYN_PLL_VCOCAL12 0x60
699#define RADIO_2056_SYN_PLL_VCOCAL13 0x61
700#define RADIO_2056_SYN_PLL_VREG 0x62
701#define RADIO_2056_SYN_PLL_STATUS1 0x63
702#define RADIO_2056_SYN_PLL_STATUS2 0x64
703#define RADIO_2056_SYN_PLL_STATUS3 0x65
704#define RADIO_2056_SYN_LOGEN_PU0 0x66
705#define RADIO_2056_SYN_LOGEN_PU1 0x67
706#define RADIO_2056_SYN_LOGEN_PU2 0x68
707#define RADIO_2056_SYN_LOGEN_PU3 0x69
708#define RADIO_2056_SYN_LOGEN_PU5 0x6a
709#define RADIO_2056_SYN_LOGEN_PU6 0x6b
710#define RADIO_2056_SYN_LOGEN_PU7 0x6c
711#define RADIO_2056_SYN_LOGEN_PU8 0x6d
712#define RADIO_2056_SYN_LOGEN_BIAS_RESET 0x6e
713#define RADIO_2056_SYN_LOGEN_RCCR1 0x6f
714#define RADIO_2056_SYN_LOGEN_VCOBUF1 0x70
715#define RADIO_2056_SYN_LOGEN_MIXER1 0x71
716#define RADIO_2056_SYN_LOGEN_MIXER2 0x72
717#define RADIO_2056_SYN_LOGEN_BUF1 0x73
718#define RADIO_2056_SYN_LOGENBUF2 0x74
719#define RADIO_2056_SYN_LOGEN_BUF3 0x75
720#define RADIO_2056_SYN_LOGEN_BUF4 0x76
721#define RADIO_2056_SYN_LOGEN_DIV1 0x77
722#define RADIO_2056_SYN_LOGEN_DIV2 0x78
723#define RADIO_2056_SYN_LOGEN_DIV3 0x79
724#define RADIO_2056_SYN_LOGEN_ACL1 0x7a
725#define RADIO_2056_SYN_LOGEN_ACL2 0x7b
726#define RADIO_2056_SYN_LOGEN_ACL3 0x7c
727#define RADIO_2056_SYN_LOGEN_ACL4 0x7d
728#define RADIO_2056_SYN_LOGEN_ACL5 0x7e
729#define RADIO_2056_SYN_LOGEN_ACL6 0x7f
730#define RADIO_2056_SYN_LOGEN_ACLOUT 0x80
731#define RADIO_2056_SYN_LOGEN_ACLCAL1 0x81
732#define RADIO_2056_SYN_LOGEN_ACLCAL2 0x82
733#define RADIO_2056_SYN_LOGEN_ACLCAL3 0x83
734#define RADIO_2056_SYN_CALEN 0x84
735#define RADIO_2056_SYN_LOGEN_PEAKDET1 0x85
736#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR 0x86
737#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87
738#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88
739#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89
740#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8a
741#define RADIO_2056_SYN_LOGEN_VCOBUF2 0x8b
742#define RADIO_2056_SYN_LOGEN_MIXER3 0x8c
743#define RADIO_2056_SYN_LOGEN_BUF5 0x8d
744#define RADIO_2056_SYN_LOGEN_BUF6 0x8e
745#define RADIO_2056_SYN_LOGEN_CBUFRX1 0x8f
746#define RADIO_2056_SYN_LOGEN_CBUFRX2 0x90
747#define RADIO_2056_SYN_LOGEN_CBUFRX3 0x91
748#define RADIO_2056_SYN_LOGEN_CBUFRX4 0x92
749#define RADIO_2056_SYN_LOGEN_CBUFTX1 0x93
750#define RADIO_2056_SYN_LOGEN_CBUFTX2 0x94
751#define RADIO_2056_SYN_LOGEN_CBUFTX3 0x95
752#define RADIO_2056_SYN_LOGEN_CBUFTX4 0x96
753#define RADIO_2056_SYN_LOGEN_CMOSRX1 0x97
754#define RADIO_2056_SYN_LOGEN_CMOSRX2 0x98
755#define RADIO_2056_SYN_LOGEN_CMOSRX3 0x99
756#define RADIO_2056_SYN_LOGEN_CMOSRX4 0x9a
757#define RADIO_2056_SYN_LOGEN_CMOSTX1 0x9b
758#define RADIO_2056_SYN_LOGEN_CMOSTX2 0x9c
759#define RADIO_2056_SYN_LOGEN_CMOSTX3 0x9d
760#define RADIO_2056_SYN_LOGEN_CMOSTX4 0x9e
761#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9f
762#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL 0xa0
763#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL 0xa1
764#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL 0xa2
765#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xa3
766#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xa4
767#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xa5
768#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xa6
769#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xa7
770#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xa8
771#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xa9
772#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xaa
773#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xab
774#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xac
775#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xad
776#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xae
777#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xaf
778#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xb0
779#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xb1
780#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xb2
781#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT 0xb3
782#define RADIO_2056_SYN_LOGEN_CORE_CALVALID 0xb4
783#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID 0xb5
784#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID 0xb6
785
786#define RADIO_2056_TX_RESERVED_ADDR0 0x0
787#define RADIO_2056_TX_IDCODE 0x1
788#define RADIO_2056_TX_RESERVED_ADDR2 0x2
789#define RADIO_2056_TX_RESERVED_ADDR3 0x3
790#define RADIO_2056_TX_RESERVED_ADDR4 0x4
791#define RADIO_2056_TX_RESERVED_ADDR5 0x5
792#define RADIO_2056_TX_RESERVED_ADDR6 0x6
793#define RADIO_2056_TX_RESERVED_ADDR7 0x7
794#define RADIO_2056_TX_COM_CTRL 0x8
795#define RADIO_2056_TX_COM_PU 0x9
796#define RADIO_2056_TX_COM_OVR 0xa
797#define RADIO_2056_TX_COM_RESET 0xb
798#define RADIO_2056_TX_COM_RCAL 0xc
799#define RADIO_2056_TX_COM_RC_RXLPF 0xd
800#define RADIO_2056_TX_COM_RC_TXLPF 0xe
801#define RADIO_2056_TX_COM_RC_RXHPF 0xf
802#define RADIO_2056_TX_RESERVED_ADDR16 0x10
803#define RADIO_2056_TX_RESERVED_ADDR17 0x11
804#define RADIO_2056_TX_RESERVED_ADDR18 0x12
805#define RADIO_2056_TX_RESERVED_ADDR19 0x13
806#define RADIO_2056_TX_RESERVED_ADDR20 0x14
807#define RADIO_2056_TX_RESERVED_ADDR21 0x15
808#define RADIO_2056_TX_RESERVED_ADDR22 0x16
809#define RADIO_2056_TX_RESERVED_ADDR23 0x17
810#define RADIO_2056_TX_RESERVED_ADDR24 0x18
811#define RADIO_2056_TX_RESERVED_ADDR25 0x19
812#define RADIO_2056_TX_RESERVED_ADDR26 0x1a
813#define RADIO_2056_TX_RESERVED_ADDR27 0x1b
814#define RADIO_2056_TX_RESERVED_ADDR28 0x1c
815#define RADIO_2056_TX_RESERVED_ADDR29 0x1d
816#define RADIO_2056_TX_RESERVED_ADDR30 0x1e
817#define RADIO_2056_TX_RESERVED_ADDR31 0x1f
818#define RADIO_2056_TX_IQCAL_GAIN_BW 0x20
819#define RADIO_2056_TX_LOFT_FINE_I 0x21
820#define RADIO_2056_TX_LOFT_FINE_Q 0x22
821#define RADIO_2056_TX_LOFT_COARSE_I 0x23
822#define RADIO_2056_TX_LOFT_COARSE_Q 0x24
823#define RADIO_2056_TX_TX_COM_MASTER1 0x25
824#define RADIO_2056_TX_TX_COM_MASTER2 0x26
825#define RADIO_2056_TX_RXIQCAL_TXMUX 0x27
826#define RADIO_2056_TX_TX_SSI_MASTER 0x28
827#define RADIO_2056_TX_IQCAL_VCM_HG 0x29
828#define RADIO_2056_TX_IQCAL_IDAC 0x2a
829#define RADIO_2056_TX_TSSI_VCM 0x2b
830#define RADIO_2056_TX_TX_AMP_DET 0x2c
831#define RADIO_2056_TX_TX_SSI_MUX 0x2d
832#define RADIO_2056_TX_TSSIA 0x2e
833#define RADIO_2056_TX_TSSIG 0x2f
834#define RADIO_2056_TX_TSSI_MISC1 0x30
835#define RADIO_2056_TX_TSSI_MISC2 0x31
836#define RADIO_2056_TX_TSSI_MISC3 0x32
837#define RADIO_2056_TX_PA_SPARE1 0x33
838#define RADIO_2056_TX_PA_SPARE2 0x34
839#define RADIO_2056_TX_INTPAA_MASTER 0x35
840#define RADIO_2056_TX_INTPAA_GAIN 0x36
841#define RADIO_2056_TX_INTPAA_BOOST_TUNE 0x37
842#define RADIO_2056_TX_INTPAA_IAUX_STAT 0x38
843#define RADIO_2056_TX_INTPAA_IAUX_DYN 0x39
844#define RADIO_2056_TX_INTPAA_IMAIN_STAT 0x3a
845#define RADIO_2056_TX_INTPAA_IMAIN_DYN 0x3b
846#define RADIO_2056_TX_INTPAA_CASCBIAS 0x3c
847#define RADIO_2056_TX_INTPAA_PASLOPE 0x3d
848#define RADIO_2056_TX_INTPAA_PA_MISC 0x3e
849#define RADIO_2056_TX_INTPAG_MASTER 0x3f
850#define RADIO_2056_TX_INTPAG_GAIN 0x40
851#define RADIO_2056_TX_INTPAG_BOOST_TUNE 0x41
852#define RADIO_2056_TX_INTPAG_IAUX_STAT 0x42
853#define RADIO_2056_TX_INTPAG_IAUX_DYN 0x43
854#define RADIO_2056_TX_INTPAG_IMAIN_STAT 0x44
855#define RADIO_2056_TX_INTPAG_IMAIN_DYN 0x45
856#define RADIO_2056_TX_INTPAG_CASCBIAS 0x46
857#define RADIO_2056_TX_INTPAG_PASLOPE 0x47
858#define RADIO_2056_TX_INTPAG_PA_MISC 0x48
859#define RADIO_2056_TX_PADA_MASTER 0x49
860#define RADIO_2056_TX_PADA_IDAC 0x4a
861#define RADIO_2056_TX_PADA_CASCBIAS 0x4b
862#define RADIO_2056_TX_PADA_GAIN 0x4c
863#define RADIO_2056_TX_PADA_BOOST_TUNE 0x4d
864#define RADIO_2056_TX_PADA_SLOPE 0x4e
865#define RADIO_2056_TX_PADG_MASTER 0x4f
866#define RADIO_2056_TX_PADG_IDAC 0x50
867#define RADIO_2056_TX_PADG_CASCBIAS 0x51
868#define RADIO_2056_TX_PADG_GAIN 0x52
869#define RADIO_2056_TX_PADG_BOOST_TUNE 0x53
870#define RADIO_2056_TX_PADG_SLOPE 0x54
871#define RADIO_2056_TX_PGAA_MASTER 0x55
872#define RADIO_2056_TX_PGAA_IDAC 0x56
873#define RADIO_2056_TX_PGAA_GAIN 0x57
874#define RADIO_2056_TX_PGAA_BOOST_TUNE 0x58
875#define RADIO_2056_TX_PGAA_SLOPE 0x59
876#define RADIO_2056_TX_PGAA_MISC 0x5a
877#define RADIO_2056_TX_PGAG_MASTER 0x5b
878#define RADIO_2056_TX_PGAG_IDAC 0x5c
879#define RADIO_2056_TX_PGAG_GAIN 0x5d
880#define RADIO_2056_TX_PGAG_BOOST_TUNE 0x5e
881#define RADIO_2056_TX_PGAG_SLOPE 0x5f
882#define RADIO_2056_TX_PGAG_MISC 0x60
883#define RADIO_2056_TX_MIXA_MASTER 0x61
884#define RADIO_2056_TX_MIXA_BOOST_TUNE 0x62
885#define RADIO_2056_TX_MIXG 0x63
886#define RADIO_2056_TX_MIXG_BOOST_TUNE 0x64
887#define RADIO_2056_TX_BB_GM_MASTER 0x65
888#define RADIO_2056_TX_GMBB_GM 0x66
889#define RADIO_2056_TX_GMBB_IDAC 0x67
890#define RADIO_2056_TX_TXLPF_MASTER 0x68
891#define RADIO_2056_TX_TXLPF_RCCAL 0x69
892#define RADIO_2056_TX_TXLPF_RCCAL_OFF0 0x6a
893#define RADIO_2056_TX_TXLPF_RCCAL_OFF1 0x6b
894#define RADIO_2056_TX_TXLPF_RCCAL_OFF2 0x6c
895#define RADIO_2056_TX_TXLPF_RCCAL_OFF3 0x6d
896#define RADIO_2056_TX_TXLPF_RCCAL_OFF4 0x6e
897#define RADIO_2056_TX_TXLPF_RCCAL_OFF5 0x6f
898#define RADIO_2056_TX_TXLPF_RCCAL_OFF6 0x70
899#define RADIO_2056_TX_TXLPF_BW 0x71
900#define RADIO_2056_TX_TXLPF_GAIN 0x72
901#define RADIO_2056_TX_TXLPF_IDAC 0x73
902#define RADIO_2056_TX_TXLPF_IDAC_0 0x74
903#define RADIO_2056_TX_TXLPF_IDAC_1 0x75
904#define RADIO_2056_TX_TXLPF_IDAC_2 0x76
905#define RADIO_2056_TX_TXLPF_IDAC_3 0x77
906#define RADIO_2056_TX_TXLPF_IDAC_4 0x78
907#define RADIO_2056_TX_TXLPF_IDAC_5 0x79
908#define RADIO_2056_TX_TXLPF_IDAC_6 0x7a
909#define RADIO_2056_TX_TXLPF_OPAMP_IDAC 0x7b
910#define RADIO_2056_TX_TXLPF_MISC 0x7c
911#define RADIO_2056_TX_TXSPARE1 0x7d
912#define RADIO_2056_TX_TXSPARE2 0x7e
913#define RADIO_2056_TX_TXSPARE3 0x7f
914#define RADIO_2056_TX_TXSPARE4 0x80
915#define RADIO_2056_TX_TXSPARE5 0x81
916#define RADIO_2056_TX_TXSPARE6 0x82
917#define RADIO_2056_TX_TXSPARE7 0x83
918#define RADIO_2056_TX_TXSPARE8 0x84
919#define RADIO_2056_TX_TXSPARE9 0x85
920#define RADIO_2056_TX_TXSPARE10 0x86
921#define RADIO_2056_TX_TXSPARE11 0x87
922#define RADIO_2056_TX_TXSPARE12 0x88
923#define RADIO_2056_TX_TXSPARE13 0x89
924#define RADIO_2056_TX_TXSPARE14 0x8a
925#define RADIO_2056_TX_TXSPARE15 0x8b
926#define RADIO_2056_TX_TXSPARE16 0x8c
927#define RADIO_2056_TX_STATUS_INTPA_GAIN 0x8d
928#define RADIO_2056_TX_STATUS_PAD_GAIN 0x8e
929#define RADIO_2056_TX_STATUS_PGA_GAIN 0x8f
930#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN 0x90
931#define RADIO_2056_TX_STATUS_TXLPF_BW 0x91
932#define RADIO_2056_TX_STATUS_TXLPF_RC 0x92
933#define RADIO_2056_TX_GMBB_IDAC0 0x93
934#define RADIO_2056_TX_GMBB_IDAC1 0x94
935#define RADIO_2056_TX_GMBB_IDAC2 0x95
936#define RADIO_2056_TX_GMBB_IDAC3 0x96
937#define RADIO_2056_TX_GMBB_IDAC4 0x97
938#define RADIO_2056_TX_GMBB_IDAC5 0x98
939#define RADIO_2056_TX_GMBB_IDAC6 0x99
940#define RADIO_2056_TX_GMBB_IDAC7 0x9a
941
942#define RADIO_2056_RX_RESERVED_ADDR0 0x0
943#define RADIO_2056_RX_IDCODE 0x1
944#define RADIO_2056_RX_RESERVED_ADDR2 0x2
945#define RADIO_2056_RX_RESERVED_ADDR3 0x3
946#define RADIO_2056_RX_RESERVED_ADDR4 0x4
947#define RADIO_2056_RX_RESERVED_ADDR5 0x5
948#define RADIO_2056_RX_RESERVED_ADDR6 0x6
949#define RADIO_2056_RX_RESERVED_ADDR7 0x7
950#define RADIO_2056_RX_COM_CTRL 0x8
951#define RADIO_2056_RX_COM_PU 0x9
952#define RADIO_2056_RX_COM_OVR 0xa
953#define RADIO_2056_RX_COM_RESET 0xb
954#define RADIO_2056_RX_COM_RCAL 0xc
955#define RADIO_2056_RX_COM_RC_RXLPF 0xd
956#define RADIO_2056_RX_COM_RC_TXLPF 0xe
957#define RADIO_2056_RX_COM_RC_RXHPF 0xf
958#define RADIO_2056_RX_RESERVED_ADDR16 0x10
959#define RADIO_2056_RX_RESERVED_ADDR17 0x11
960#define RADIO_2056_RX_RESERVED_ADDR18 0x12
961#define RADIO_2056_RX_RESERVED_ADDR19 0x13
962#define RADIO_2056_RX_RESERVED_ADDR20 0x14
963#define RADIO_2056_RX_RESERVED_ADDR21 0x15
964#define RADIO_2056_RX_RESERVED_ADDR22 0x16
965#define RADIO_2056_RX_RESERVED_ADDR23 0x17
966#define RADIO_2056_RX_RESERVED_ADDR24 0x18
967#define RADIO_2056_RX_RESERVED_ADDR25 0x19
968#define RADIO_2056_RX_RESERVED_ADDR26 0x1a
969#define RADIO_2056_RX_RESERVED_ADDR27 0x1b
970#define RADIO_2056_RX_RESERVED_ADDR28 0x1c
971#define RADIO_2056_RX_RESERVED_ADDR29 0x1d
972#define RADIO_2056_RX_RESERVED_ADDR30 0x1e
973#define RADIO_2056_RX_RESERVED_ADDR31 0x1f
974#define RADIO_2056_RX_RXIQCAL_RXMUX 0x20
975#define RADIO_2056_RX_RSSI_PU 0x21
976#define RADIO_2056_RX_RSSI_SEL 0x22
977#define RADIO_2056_RX_RSSI_GAIN 0x23
978#define RADIO_2056_RX_RSSI_NB_IDAC 0x24
979#define RADIO_2056_RX_RSSI_WB2I_IDAC_1 0x25
980#define RADIO_2056_RX_RSSI_WB2I_IDAC_2 0x26
981#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1 0x27
982#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2 0x28
983#define RADIO_2056_RX_RSSI_POLE 0x29
984#define RADIO_2056_RX_RSSI_WB1_IDAC 0x2a
985#define RADIO_2056_RX_RSSI_MISC 0x2b
986#define RADIO_2056_RX_LNAA_MASTER 0x2c
987#define RADIO_2056_RX_LNAA_TUNE 0x2d
988#define RADIO_2056_RX_LNAA_GAIN 0x2e
989#define RADIO_2056_RX_LNA_A_SLOPE 0x2f
990#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC 0x30
991#define RADIO_2056_RX_LNAA2_IDAC 0x31
992#define RADIO_2056_RX_LNA1A_MISC 0x32
993#define RADIO_2056_RX_LNAG_MASTER 0x33
994#define RADIO_2056_RX_LNAG_TUNE 0x34
995#define RADIO_2056_RX_LNAG_GAIN 0x35
996#define RADIO_2056_RX_LNA_G_SLOPE 0x36
997#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC 0x37
998#define RADIO_2056_RX_LNAG2_IDAC 0x38
999#define RADIO_2056_RX_LNA1G_MISC 0x39
1000#define RADIO_2056_RX_MIXA_MASTER 0x3a
1001#define RADIO_2056_RX_MIXA_VCM 0x3b
1002#define RADIO_2056_RX_MIXA_CTRLPTAT 0x3c
1003#define RADIO_2056_RX_MIXA_LOB_BIAS 0x3d
1004#define RADIO_2056_RX_MIXA_CORE_IDAC 0x3e
1005#define RADIO_2056_RX_MIXA_CMFB_IDAC 0x3f
1006#define RADIO_2056_RX_MIXA_BIAS_AUX 0x40
1007#define RADIO_2056_RX_MIXA_BIAS_MAIN 0x41
1008#define RADIO_2056_RX_MIXA_BIAS_MISC 0x42
1009#define RADIO_2056_RX_MIXA_MAST_BIAS 0x43
1010#define RADIO_2056_RX_MIXG_MASTER 0x44
1011#define RADIO_2056_RX_MIXG_VCM 0x45
1012#define RADIO_2056_RX_MIXG_CTRLPTAT 0x46
1013#define RADIO_2056_RX_MIXG_LOB_BIAS 0x47
1014#define RADIO_2056_RX_MIXG_CORE_IDAC 0x48
1015#define RADIO_2056_RX_MIXG_CMFB_IDAC 0x49
1016#define RADIO_2056_RX_MIXG_BIAS_AUX 0x4a
1017#define RADIO_2056_RX_MIXG_BIAS_MAIN 0x4b
1018#define RADIO_2056_RX_MIXG_BIAS_MISC 0x4c
1019#define RADIO_2056_RX_MIXG_MAST_BIAS 0x4d
1020#define RADIO_2056_RX_TIA_MASTER 0x4e
1021#define RADIO_2056_RX_TIA_IOPAMP 0x4f
1022#define RADIO_2056_RX_TIA_QOPAMP 0x50
1023#define RADIO_2056_RX_TIA_IMISC 0x51
1024#define RADIO_2056_RX_TIA_QMISC 0x52
1025#define RADIO_2056_RX_TIA_GAIN 0x53
1026#define RADIO_2056_RX_TIA_SPARE1 0x54
1027#define RADIO_2056_RX_TIA_SPARE2 0x55
1028#define RADIO_2056_RX_BB_LPF_MASTER 0x56
1029#define RADIO_2056_RX_AACI_MASTER 0x57
1030#define RADIO_2056_RX_RXLPF_IDAC 0x58
1031#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59
1032#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5a
1033#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL 0x5b
1034#define RADIO_2056_RX_RXLPF_OUTVCM 0x5c
1035#define RADIO_2056_RX_RXLPF_INVCM_BODY 0x5d
1036#define RADIO_2056_RX_RXLPF_CC_OP 0x5e
1037#define RADIO_2056_RX_RXLPF_GAIN 0x5f
1038#define RADIO_2056_RX_RXLPF_Q_BW 0x60
1039#define RADIO_2056_RX_RXLPF_HP_CORNER_BW 0x61
1040#define RADIO_2056_RX_RXLPF_RCCAL_HPC 0x62
1041#define RADIO_2056_RX_RXHPF_OFF0 0x63
1042#define RADIO_2056_RX_RXHPF_OFF1 0x64
1043#define RADIO_2056_RX_RXHPF_OFF2 0x65
1044#define RADIO_2056_RX_RXHPF_OFF3 0x66
1045#define RADIO_2056_RX_RXHPF_OFF4 0x67
1046#define RADIO_2056_RX_RXHPF_OFF5 0x68
1047#define RADIO_2056_RX_RXHPF_OFF6 0x69
1048#define RADIO_2056_RX_RXHPF_OFF7 0x6a
1049#define RADIO_2056_RX_RXLPF_RCCAL_LPC 0x6b
1050#define RADIO_2056_RX_RXLPF_OFF_0 0x6c
1051#define RADIO_2056_RX_RXLPF_OFF_1 0x6d
1052#define RADIO_2056_RX_RXLPF_OFF_2 0x6e
1053#define RADIO_2056_RX_RXLPF_OFF_3 0x6f
1054#define RADIO_2056_RX_RXLPF_OFF_4 0x70
1055#define RADIO_2056_RX_UNUSED 0x71
1056#define RADIO_2056_RX_VGA_MASTER 0x72
1057#define RADIO_2056_RX_VGA_BIAS 0x73
1058#define RADIO_2056_RX_VGA_BIAS_DCCANCEL 0x74
1059#define RADIO_2056_RX_VGA_GAIN 0x75
1060#define RADIO_2056_RX_VGA_HP_CORNER_BW 0x76
1061#define RADIO_2056_RX_VGABUF_BIAS 0x77
1062#define RADIO_2056_RX_VGABUF_GAIN_BW 0x78
1063#define RADIO_2056_RX_TXFBMIX_A 0x79
1064#define RADIO_2056_RX_TXFBMIX_G 0x7a
1065#define RADIO_2056_RX_RXSPARE1 0x7b
1066#define RADIO_2056_RX_RXSPARE2 0x7c
1067#define RADIO_2056_RX_RXSPARE3 0x7d
1068#define RADIO_2056_RX_RXSPARE4 0x7e
1069#define RADIO_2056_RX_RXSPARE5 0x7f
1070#define RADIO_2056_RX_RXSPARE6 0x80
1071#define RADIO_2056_RX_RXSPARE7 0x81
1072#define RADIO_2056_RX_RXSPARE8 0x82
1073#define RADIO_2056_RX_RXSPARE9 0x83
1074#define RADIO_2056_RX_RXSPARE10 0x84
1075#define RADIO_2056_RX_RXSPARE11 0x85
1076#define RADIO_2056_RX_RXSPARE12 0x86
1077#define RADIO_2056_RX_RXSPARE13 0x87
1078#define RADIO_2056_RX_RXSPARE14 0x88
1079#define RADIO_2056_RX_RXSPARE15 0x89
1080#define RADIO_2056_RX_RXSPARE16 0x8a
1081#define RADIO_2056_RX_STATUS_LNAA_GAIN 0x8b
1082#define RADIO_2056_RX_STATUS_LNAG_GAIN 0x8c
1083#define RADIO_2056_RX_STATUS_MIXTIA_GAIN 0x8d
1084#define RADIO_2056_RX_STATUS_RXLPF_GAIN 0x8e
1085#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN 0x8f
1086#define RADIO_2056_RX_STATUS_RXLPF_Q 0x90
1087#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW 0x91
1088#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC 0x92
1089#define RADIO_2056_RX_STATUS_RXLPF_RC 0x93
1090#define RADIO_2056_RX_STATUS_HPC_RC 0x94
1091
1092#define RADIO_2056_LNA1_A_PU 0x01
1093#define RADIO_2056_LNA2_A_PU 0x02
1094#define RADIO_2056_LNA1_G_PU 0x01
1095#define RADIO_2056_LNA2_G_PU 0x02
1096#define RADIO_2056_MIXA_PU_I 0x01
1097#define RADIO_2056_MIXA_PU_Q 0x02
1098#define RADIO_2056_MIXA_PU_GM 0x10
1099#define RADIO_2056_MIXG_PU_I 0x01
1100#define RADIO_2056_MIXG_PU_Q 0x02
1101#define RADIO_2056_MIXG_PU_GM 0x10
1102#define RADIO_2056_TIA_PU 0x01
1103#define RADIO_2056_BB_LPF_PU 0x20
1104#define RADIO_2056_W1_PU 0x02
1105#define RADIO_2056_W2_PU 0x04
1106#define RADIO_2056_NB_PU 0x08
1107#define RADIO_2056_RSSI_W1_SEL 0x02
1108#define RADIO_2056_RSSI_W2_SEL 0x04
1109#define RADIO_2056_RSSI_NB_SEL 0x08
1110#define RADIO_2056_VCM_MASK 0x1c
1111#define RADIO_2056_RSSI_VCM_SHIFT 0x02
1112
1113#define RADIO_2057_DACBUF_VINCM_CORE0 0x0
1114#define RADIO_2057_IDCODE 0x1
1115#define RADIO_2057_RCCAL_MASTER 0x2
1116#define RADIO_2057_RCCAL_CAP_SIZE 0x3
1117#define RADIO_2057_RCAL_CONFIG 0x4
1118#define RADIO_2057_GPAIO_CONFIG 0x5
1119#define RADIO_2057_GPAIO_SEL1 0x6
1120#define RADIO_2057_GPAIO_SEL0 0x7
1121#define RADIO_2057_CLPO_CONFIG 0x8
1122#define RADIO_2057_BANDGAP_CONFIG 0x9
1123#define RADIO_2057_BANDGAP_RCAL_TRIM 0xa
1124#define RADIO_2057_AFEREG_CONFIG 0xb
1125#define RADIO_2057_TEMPSENSE_CONFIG 0xc
1126#define RADIO_2057_XTAL_CONFIG1 0xd
1127#define RADIO_2057_XTAL_ICORE_SIZE 0xe
1128#define RADIO_2057_XTAL_BUF_SIZE 0xf
1129#define RADIO_2057_XTAL_PULLCAP_SIZE 0x10
1130#define RADIO_2057_RFPLL_MASTER 0x11
1131#define RADIO_2057_VCOMONITOR_VTH_L 0x12
1132#define RADIO_2057_VCOMONITOR_VTH_H 0x13
1133#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14
1134#define RADIO_2057_VCO_VARCSIZE_IDAC 0x15
1135#define RADIO_2057_VCOCAL_COUNTVAL0 0x16
1136#define RADIO_2057_VCOCAL_COUNTVAL1 0x17
1137#define RADIO_2057_VCOCAL_INTCLK_COUNT 0x18
1138#define RADIO_2057_VCOCAL_MASTER 0x19
1139#define RADIO_2057_VCOCAL_NUMCAPCHANGE 0x1a
1140#define RADIO_2057_VCOCAL_WINSIZE 0x1b
1141#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH 0x1c
1142#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP 0x1d
1143#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP 0x1e
1144#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP 0x1f
1145#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1 0x20
1146#define RADIO_2057_VCO_FORCECAP0 0x21
1147#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22
1148#define RADIO_2057_RFPLL_PFD_RESET_PW 0x23
1149#define RADIO_2057_RFPLL_LOOPFILTER_R2 0x24
1150#define RADIO_2057_RFPLL_LOOPFILTER_R1 0x25
1151#define RADIO_2057_RFPLL_LOOPFILTER_C3 0x26
1152#define RADIO_2057_RFPLL_LOOPFILTER_C2 0x27
1153#define RADIO_2057_RFPLL_LOOPFILTER_C1 0x28
1154#define RADIO_2057_CP_KPD_IDAC 0x29
1155#define RADIO_2057_RFPLL_IDACS 0x2a
1156#define RADIO_2057_RFPLL_MISC_EN 0x2b
1157#define RADIO_2057_RFPLL_MMD0 0x2c
1158#define RADIO_2057_RFPLL_MMD1 0x2d
1159#define RADIO_2057_RFPLL_MISC_CAL_RESETN 0x2e
1160#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES 0x2f
1161#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE 0x30
1162#define RADIO_2057_VCOCAL_READCAP0 0x31
1163#define RADIO_2057_VCOCAL_READCAP1 0x32
1164#define RADIO_2057_VCOCAL_STATUS 0x33
1165#define RADIO_2057_LOGEN_PUS 0x34
1166#define RADIO_2057_LOGEN_PTAT_RESETS 0x35
1167#define RADIO_2057_VCOBUF_IDACS 0x36
1168#define RADIO_2057_VCOBUF_TUNE 0x37
1169#define RADIO_2057_CMOSBUF_TX2GQ_IDACS 0x38
1170#define RADIO_2057_CMOSBUF_TX2GI_IDACS 0x39
1171#define RADIO_2057_CMOSBUF_TX5GQ_IDACS 0x3a
1172#define RADIO_2057_CMOSBUF_TX5GI_IDACS 0x3b
1173#define RADIO_2057_CMOSBUF_RX2GQ_IDACS 0x3c
1174#define RADIO_2057_CMOSBUF_RX2GI_IDACS 0x3d
1175#define RADIO_2057_CMOSBUF_RX5GQ_IDACS 0x3e
1176#define RADIO_2057_CMOSBUF_RX5GI_IDACS 0x3f
1177#define RADIO_2057_LOGEN_MX2G_IDACS 0x40
1178#define RADIO_2057_LOGEN_MX2G_TUNE 0x41
1179#define RADIO_2057_LOGEN_MX5G_IDACS 0x42
1180#define RADIO_2057_LOGEN_MX5G_TUNE 0x43
1181#define RADIO_2057_LOGEN_MX5G_RCCR 0x44
1182#define RADIO_2057_LOGEN_INDBUF2G_IDAC 0x45
1183#define RADIO_2057_LOGEN_INDBUF2G_IBOOST 0x46
1184#define RADIO_2057_LOGEN_INDBUF2G_TUNE 0x47
1185#define RADIO_2057_LOGEN_INDBUF5G_IDAC 0x48
1186#define RADIO_2057_LOGEN_INDBUF5G_IBOOST 0x49
1187#define RADIO_2057_LOGEN_INDBUF5G_TUNE 0x4a
1188#define RADIO_2057_CMOSBUF_TX_RCCR 0x4b
1189#define RADIO_2057_CMOSBUF_RX_RCCR 0x4c
1190#define RADIO_2057_LOGEN_SEL_PKDET 0x4d
1191#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT 0x4e
1192#define RADIO_2057_RXTXBIAS_CONFIG_CORE0 0x4f
1193#define RADIO_2057_TXGM_TXRF_PUS_CORE0 0x50
1194#define RADIO_2057_TXGM_IDAC_BLEED_CORE0 0x51
1195#define RADIO_2057_TXGM_GAIN_CORE0 0x56
1196#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0 0x57
1197#define RADIO_2057_PAD2G_PTATS_CORE0 0x58
1198#define RADIO_2057_PAD2G_IDACS_CORE0 0x59
1199#define RADIO_2057_PAD2G_BOOST_PU_CORE0 0x5a
1200#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0 0x5b
1201#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0 0x5c
1202#define RADIO_2057_TXMIX2G_LODC_CORE0 0x5d
1203#define RADIO_2057_PAD2G_TUNE_PUS_CORE0 0x5e
1204#define RADIO_2057_IPA2G_GAIN_CORE0 0x5f
1205#define RADIO_2057_TSSI2G_SPARE1_CORE0 0x60
1206#define RADIO_2057_TSSI2G_SPARE2_CORE0 0x61
1207#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0 0x62
1208#define RADIO_2057_IPA2G_IMAIN_CORE0 0x63
1209#define RADIO_2057_IPA2G_CASCONV_CORE0 0x64
1210#define RADIO_2057_IPA2G_CASCOFFV_CORE0 0x65
1211#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0 0x66
1212#define RADIO_2057_TX5G_PKDET_CORE0 0x69
1213#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0 0x6a
1214#define RADIO_2057_PAD5G_PTATS1_CORE0 0x6b
1215#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0 0x6c
1216#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0 0x6d
1217#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0 0x6e
1218#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f
1219#define RADIO_2057_PGA_BOOST_TUNE_CORE0 0x70
1220#define RADIO_2057_PGA_GAIN_CORE0 0x71
1221#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72
1222#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0 0x73
1223#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0 0x74
1224#define RADIO_2057_IPA5G_IAUX_CORE0 0x75
1225#define RADIO_2057_IPA5G_GAIN_CORE0 0x76
1226#define RADIO_2057_TSSI5G_SPARE1_CORE0 0x77
1227#define RADIO_2057_TSSI5G_SPARE2_CORE0 0x78
1228#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0 0x79
1229#define RADIO_2057_IPA5G_PTAT_CORE0 0x7a
1230#define RADIO_2057_IPA5G_IMAIN_CORE0 0x7b
1231#define RADIO_2057_IPA5G_CASCONV_CORE0 0x7c
1232#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0 0x7d
1233#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0 0x80
1234#define RADIO_2057_TR2G_CONFIG1_CORE0_NU 0x81
1235#define RADIO_2057_TR2G_CONFIG2_CORE0_NU 0x82
1236#define RADIO_2057_LNA5G_RFEN_CORE0 0x83
1237#define RADIO_2057_TR5G_CONFIG2_CORE0_NU 0x84
1238#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0 0x85
1239#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86
1240#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0 0x87
1241#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0 0x88
1242#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0 0x89
1243#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0 0x8a
1244#define RADIO_2057_LNA2_IAUX_PTAT_CORE0 0x8b
1245#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0 0x8c
1246#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d
1247#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0 0x8e
1248#define RADIO_2057_TIA_CONFIG_CORE0 0x8f
1249#define RADIO_2057_TIA_IQGAIN_CORE0 0x90
1250#define RADIO_2057_TIA_IBIAS2_CORE0 0x91
1251#define RADIO_2057_TIA_IBIAS1_CORE0 0x92
1252#define RADIO_2057_TIA_SPARE_Q_CORE0 0x93
1253#define RADIO_2057_TIA_SPARE_I_CORE0 0x94
1254#define RADIO_2057_RXMIX2G_PUS_CORE0 0x95
1255#define RADIO_2057_RXMIX2G_VCMREFS_CORE0 0x96
1256#define RADIO_2057_RXMIX2G_LODC_QI_CORE0 0x97
1257#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0 0x98
1258#define RADIO_2057_LNA2G_GAIN_CORE0 0x99
1259#define RADIO_2057_LNA2G_TUNE_CORE0 0x9a
1260#define RADIO_2057_RXMIX5G_PUS_CORE0 0x9b
1261#define RADIO_2057_RXMIX5G_VCMREFS_CORE0 0x9c
1262#define RADIO_2057_RXMIX5G_LODC_QI_CORE0 0x9d
1263#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0 0x9e
1264#define RADIO_2057_LNA5G_GAIN_CORE0 0x9f
1265#define RADIO_2057_LNA5G_TUNE_CORE0 0xa0
1266#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0 0xa1
1267#define RADIO_2057_RXBB_BIAS_MASTER_CORE0 0xa2
1268#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0 0xa3
1269#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4
1270#define RADIO_2057_TXBUF_VINCM_CORE0 0xa5
1271#define RADIO_2057_TXBUF_IDACS_CORE0 0xa6
1272#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0 0xa7
1273#define RADIO_2057_RXBB_CC_CORE0 0xa8
1274#define RADIO_2057_RXBB_SPARE3_CORE0 0xa9
1275#define RADIO_2057_RXBB_RCCAL_HPC_CORE0 0xaa
1276#define RADIO_2057_LPF_IDACS_CORE0 0xab
1277#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0 0xac
1278#define RADIO_2057_TXBUF_GAIN_CORE0 0xad
1279#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0 0xae
1280#define RADIO_2057_RXBUF_DEGEN_CORE0 0xaf
1281#define RADIO_2057_RXBB_SPARE2_CORE0 0xb0
1282#define RADIO_2057_RXBB_SPARE1_CORE0 0xb1
1283#define RADIO_2057_RSSI_MASTER_CORE0 0xb2
1284#define RADIO_2057_W2_MASTER_CORE0 0xb3
1285#define RADIO_2057_NB_MASTER_CORE0 0xb4
1286#define RADIO_2057_W2_IDACS0_Q_CORE0 0xb5
1287#define RADIO_2057_W2_IDACS1_Q_CORE0 0xb6
1288#define RADIO_2057_W2_IDACS0_I_CORE0 0xb7
1289#define RADIO_2057_W2_IDACS1_I_CORE0 0xb8
1290#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0 0xb9
1291#define RADIO_2057_NB_IDACS_Q_CORE0 0xba
1292#define RADIO_2057_NB_IDACS_I_CORE0 0xbb
1293#define RADIO_2057_BACKUP4_CORE0 0xc1
1294#define RADIO_2057_BACKUP3_CORE0 0xc2
1295#define RADIO_2057_BACKUP2_CORE0 0xc3
1296#define RADIO_2057_BACKUP1_CORE0 0xc4
1297#define RADIO_2057_SPARE16_CORE0 0xc5
1298#define RADIO_2057_SPARE15_CORE0 0xc6
1299#define RADIO_2057_SPARE14_CORE0 0xc7
1300#define RADIO_2057_SPARE13_CORE0 0xc8
1301#define RADIO_2057_SPARE12_CORE0 0xc9
1302#define RADIO_2057_SPARE11_CORE0 0xca
1303#define RADIO_2057_TX2G_BIAS_RESETS_CORE0 0xcb
1304#define RADIO_2057_TX5G_BIAS_RESETS_CORE0 0xcc
1305#define RADIO_2057_IQTEST_SEL_PU 0xcd
1306#define RADIO_2057_XTAL_CONFIG2 0xce
1307#define RADIO_2057_BUFS_MISC_LPFBW_CORE0 0xcf
1308#define RADIO_2057_TXLPF_RCCAL_CORE0 0xd0
1309#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1
1310#define RADIO_2057_LPF_GAIN_CORE0 0xd2
1311#define RADIO_2057_DACBUF_IDACS_BW_CORE0 0xd3
1312#define RADIO_2057_RXTXBIAS_CONFIG_CORE1 0xd4
1313#define RADIO_2057_TXGM_TXRF_PUS_CORE1 0xd5
1314#define RADIO_2057_TXGM_IDAC_BLEED_CORE1 0xd6
1315#define RADIO_2057_TXGM_GAIN_CORE1 0xdb
1316#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1 0xdc
1317#define RADIO_2057_PAD2G_PTATS_CORE1 0xdd
1318#define RADIO_2057_PAD2G_IDACS_CORE1 0xde
1319#define RADIO_2057_PAD2G_BOOST_PU_CORE1 0xdf
1320#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1 0xe0
1321#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1 0xe1
1322#define RADIO_2057_TXMIX2G_LODC_CORE1 0xe2
1323#define RADIO_2057_PAD2G_TUNE_PUS_CORE1 0xe3
1324#define RADIO_2057_IPA2G_GAIN_CORE1 0xe4
1325#define RADIO_2057_TSSI2G_SPARE1_CORE1 0xe5
1326#define RADIO_2057_TSSI2G_SPARE2_CORE1 0xe6
1327#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1 0xe7
1328#define RADIO_2057_IPA2G_IMAIN_CORE1 0xe8
1329#define RADIO_2057_IPA2G_CASCONV_CORE1 0xe9
1330#define RADIO_2057_IPA2G_CASCOFFV_CORE1 0xea
1331#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1 0xeb
1332#define RADIO_2057_TX5G_PKDET_CORE1 0xee
1333#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1 0xef
1334#define RADIO_2057_PAD5G_PTATS1_CORE1 0xf0
1335#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1 0xf1
1336#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1 0xf2
1337#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1 0xf3
1338#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4
1339#define RADIO_2057_PGA_BOOST_TUNE_CORE1 0xf5
1340#define RADIO_2057_PGA_GAIN_CORE1 0xf6
1341#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7
1342#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1 0xf8
1343#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1 0xf9
1344#define RADIO_2057_IPA5G_IAUX_CORE1 0xfa
1345#define RADIO_2057_IPA5G_GAIN_CORE1 0xfb
1346#define RADIO_2057_TSSI5G_SPARE1_CORE1 0xfc
1347#define RADIO_2057_TSSI5G_SPARE2_CORE1 0xfd
1348#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1 0xfe
1349#define RADIO_2057_IPA5G_PTAT_CORE1 0xff
1350#define RADIO_2057_IPA5G_IMAIN_CORE1 0x100
1351#define RADIO_2057_IPA5G_CASCONV_CORE1 0x101
1352#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1 0x102
1353#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1 0x105
1354#define RADIO_2057_TR2G_CONFIG1_CORE1_NU 0x106
1355#define RADIO_2057_TR2G_CONFIG2_CORE1_NU 0x107
1356#define RADIO_2057_LNA5G_RFEN_CORE1 0x108
1357#define RADIO_2057_TR5G_CONFIG2_CORE1_NU 0x109
1358#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1 0x10a
1359#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
1360#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1 0x10c
1361#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1 0x10d
1362#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1 0x10e
1363#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1 0x10f
1364#define RADIO_2057_LNA2_IAUX_PTAT_CORE1 0x110
1365#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1 0x111
1366#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
1367#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1 0x113
1368#define RADIO_2057_TIA_CONFIG_CORE1 0x114
1369#define RADIO_2057_TIA_IQGAIN_CORE1 0x115
1370#define RADIO_2057_TIA_IBIAS2_CORE1 0x116
1371#define RADIO_2057_TIA_IBIAS1_CORE1 0x117
1372#define RADIO_2057_TIA_SPARE_Q_CORE1 0x118
1373#define RADIO_2057_TIA_SPARE_I_CORE1 0x119
1374#define RADIO_2057_RXMIX2G_PUS_CORE1 0x11a
1375#define RADIO_2057_RXMIX2G_VCMREFS_CORE1 0x11b
1376#define RADIO_2057_RXMIX2G_LODC_QI_CORE1 0x11c
1377#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1 0x11d
1378#define RADIO_2057_LNA2G_GAIN_CORE1 0x11e
1379#define RADIO_2057_LNA2G_TUNE_CORE1 0x11f
1380#define RADIO_2057_RXMIX5G_PUS_CORE1 0x120
1381#define RADIO_2057_RXMIX5G_VCMREFS_CORE1 0x121
1382#define RADIO_2057_RXMIX5G_LODC_QI_CORE1 0x122
1383#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1 0x123
1384#define RADIO_2057_LNA5G_GAIN_CORE1 0x124
1385#define RADIO_2057_LNA5G_TUNE_CORE1 0x125
1386#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1 0x126
1387#define RADIO_2057_RXBB_BIAS_MASTER_CORE1 0x127
1388#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1 0x128
1389#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
1390#define RADIO_2057_TXBUF_VINCM_CORE1 0x12a
1391#define RADIO_2057_TXBUF_IDACS_CORE1 0x12b
1392#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1 0x12c
1393#define RADIO_2057_RXBB_CC_CORE1 0x12d
1394#define RADIO_2057_RXBB_SPARE3_CORE1 0x12e
1395#define RADIO_2057_RXBB_RCCAL_HPC_CORE1 0x12f
1396#define RADIO_2057_LPF_IDACS_CORE1 0x130
1397#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1 0x131
1398#define RADIO_2057_TXBUF_GAIN_CORE1 0x132
1399#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1 0x133
1400#define RADIO_2057_RXBUF_DEGEN_CORE1 0x134
1401#define RADIO_2057_RXBB_SPARE2_CORE1 0x135
1402#define RADIO_2057_RXBB_SPARE1_CORE1 0x136
1403#define RADIO_2057_RSSI_MASTER_CORE1 0x137
1404#define RADIO_2057_W2_MASTER_CORE1 0x138
1405#define RADIO_2057_NB_MASTER_CORE1 0x139
1406#define RADIO_2057_W2_IDACS0_Q_CORE1 0x13a
1407#define RADIO_2057_W2_IDACS1_Q_CORE1 0x13b
1408#define RADIO_2057_W2_IDACS0_I_CORE1 0x13c
1409#define RADIO_2057_W2_IDACS1_I_CORE1 0x13d
1410#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1 0x13e
1411#define RADIO_2057_NB_IDACS_Q_CORE1 0x13f
1412#define RADIO_2057_NB_IDACS_I_CORE1 0x140
1413#define RADIO_2057_BACKUP4_CORE1 0x146
1414#define RADIO_2057_BACKUP3_CORE1 0x147
1415#define RADIO_2057_BACKUP2_CORE1 0x148
1416#define RADIO_2057_BACKUP1_CORE1 0x149
1417#define RADIO_2057_SPARE16_CORE1 0x14a
1418#define RADIO_2057_SPARE15_CORE1 0x14b
1419#define RADIO_2057_SPARE14_CORE1 0x14c
1420#define RADIO_2057_SPARE13_CORE1 0x14d
1421#define RADIO_2057_SPARE12_CORE1 0x14e
1422#define RADIO_2057_SPARE11_CORE1 0x14f
1423#define RADIO_2057_TX2G_BIAS_RESETS_CORE1 0x150
1424#define RADIO_2057_TX5G_BIAS_RESETS_CORE1 0x151
1425#define RADIO_2057_SPARE8_CORE1 0x152
1426#define RADIO_2057_SPARE7_CORE1 0x153
1427#define RADIO_2057_BUFS_MISC_LPFBW_CORE1 0x154
1428#define RADIO_2057_TXLPF_RCCAL_CORE1 0x155
1429#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
1430#define RADIO_2057_LPF_GAIN_CORE1 0x157
1431#define RADIO_2057_DACBUF_IDACS_BW_CORE1 0x158
1432#define RADIO_2057_DACBUF_VINCM_CORE1 0x159
1433#define RADIO_2057_RCCAL_START_R1_Q1_P1 0x15a
1434#define RADIO_2057_RCCAL_X1 0x15b
1435#define RADIO_2057_RCCAL_TRC0 0x15c
1436#define RADIO_2057_RCCAL_TRC1 0x15d
1437#define RADIO_2057_RCCAL_DONE_OSCCAP 0x15e
1438#define RADIO_2057_RCCAL_N0_0 0x15f
1439#define RADIO_2057_RCCAL_N0_1 0x160
1440#define RADIO_2057_RCCAL_N1_0 0x161
1441#define RADIO_2057_RCCAL_N1_1 0x162
1442#define RADIO_2057_RCAL_STATUS 0x163
1443#define RADIO_2057_XTALPUOVR_PINCTRL 0x164
1444#define RADIO_2057_OVR_REG0 0x165
1445#define RADIO_2057_OVR_REG1 0x166
1446#define RADIO_2057_OVR_REG2 0x167
1447#define RADIO_2057_OVR_REG3 0x168
1448#define RADIO_2057_OVR_REG4 0x169
1449#define RADIO_2057_RCCAL_SCAP_VAL 0x16a
1450#define RADIO_2057_RCCAL_BCAP_VAL 0x16b
1451#define RADIO_2057_RCCAL_HPC_VAL 0x16c
1452#define RADIO_2057_RCCAL_OVERRIDES 0x16d
1453#define RADIO_2057_TX0_IQCAL_GAIN_BW 0x170
1454#define RADIO_2057_TX0_LOFT_FINE_I 0x171
1455#define RADIO_2057_TX0_LOFT_FINE_Q 0x172
1456#define RADIO_2057_TX0_LOFT_COARSE_I 0x173
1457#define RADIO_2057_TX0_LOFT_COARSE_Q 0x174
1458#define RADIO_2057_TX0_TX_SSI_MASTER 0x175
1459#define RADIO_2057_TX0_IQCAL_VCM_HG 0x176
1460#define RADIO_2057_TX0_IQCAL_IDAC 0x177
1461#define RADIO_2057_TX0_TSSI_VCM 0x178
1462#define RADIO_2057_TX0_TX_SSI_MUX 0x179
1463#define RADIO_2057_TX0_TSSIA 0x17a
1464#define RADIO_2057_TX0_TSSIG 0x17b
1465#define RADIO_2057_TX0_TSSI_MISC1 0x17c
1466#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN 0x17d
1467#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e
1468#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f
1469#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180
1470#define RADIO_2057_TX1_IQCAL_GAIN_BW 0x190
1471#define RADIO_2057_TX1_LOFT_FINE_I 0x191
1472#define RADIO_2057_TX1_LOFT_FINE_Q 0x192
1473#define RADIO_2057_TX1_LOFT_COARSE_I 0x193
1474#define RADIO_2057_TX1_LOFT_COARSE_Q 0x194
1475#define RADIO_2057_TX1_TX_SSI_MASTER 0x195
1476#define RADIO_2057_TX1_IQCAL_VCM_HG 0x196
1477#define RADIO_2057_TX1_IQCAL_IDAC 0x197
1478#define RADIO_2057_TX1_TSSI_VCM 0x198
1479#define RADIO_2057_TX1_TX_SSI_MUX 0x199
1480#define RADIO_2057_TX1_TSSIA 0x19a
1481#define RADIO_2057_TX1_TSSIG 0x19b
1482#define RADIO_2057_TX1_TSSI_MISC1 0x19c
1483#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN 0x19d
1484#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e
1485#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f
1486#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0
1487#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1
1488#define RADIO_2057_AFE_SET_VCM_I_CORE0 0x1a2
1489#define RADIO_2057_AFE_SET_VCM_Q_CORE0 0x1a3
1490#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0 0x1a4
1491#define RADIO_2057_AFE_STATUS_VCM_I_CORE0 0x1a5
1492#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0 0x1a6
1493#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1 0x1a7
1494#define RADIO_2057_AFE_SET_VCM_I_CORE1 0x1a8
1495#define RADIO_2057_AFE_SET_VCM_Q_CORE1 0x1a9
1496#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1 0x1aa
1497#define RADIO_2057_AFE_STATUS_VCM_I_CORE1 0x1ab
1498#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1 0x1ac
1499
1500#define RADIO_2057v7_DACBUF_VINCM_CORE0 0x1ad
1501#define RADIO_2057v7_RCCAL_MASTER 0x1ae
1502#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU 0x1af
1503#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU 0x1b0
1504#define RADIO_2057v7_LOGEN_PUS1 0x1b1
1505#define RADIO_2057v7_OVR_REG5 0x1b2
1506#define RADIO_2057v7_OVR_REG6 0x1b3
1507#define RADIO_2057v7_OVR_REG7 0x1b4
1508#define RADIO_2057v7_OVR_REG8 0x1b5
1509#define RADIO_2057v7_OVR_REG9 0x1b6
1510#define RADIO_2057v7_OVR_REG10 0x1b7
1511#define RADIO_2057v7_OVR_REG11 0x1b8
1512#define RADIO_2057v7_OVR_REG12 0x1b9
1513#define RADIO_2057v7_OVR_REG13 0x1ba
1514#define RADIO_2057v7_OVR_REG14 0x1bb
1515#define RADIO_2057v7_OVR_REG15 0x1bc
1516#define RADIO_2057v7_OVR_REG16 0x1bd
1517#define RADIO_2057v7_OVR_REG1 0x1be
1518#define RADIO_2057v7_OVR_REG18 0x1bf
1519#define RADIO_2057v7_OVR_REG19 0x1c0
1520#define RADIO_2057v7_OVR_REG20 0x1c1
1521#define RADIO_2057v7_OVR_REG21 0x1c2
1522#define RADIO_2057v7_OVR_REG2 0x1c3
1523#define RADIO_2057v7_OVR_REG23 0x1c4
1524#define RADIO_2057v7_OVR_REG24 0x1c5
1525#define RADIO_2057v7_OVR_REG25 0x1c6
1526#define RADIO_2057v7_OVR_REG26 0x1c7
1527#define RADIO_2057v7_OVR_REG27 0x1c8
1528#define RADIO_2057v7_OVR_REG28 0x1c9
1529#define RADIO_2057v7_IQTEST_SEL_PU2 0x1ca
1530
1531#define RADIO_2057_VCM_MASK 0x7
1532
1533#endif /* _BRCM_PHY_RADIO_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h b/drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h
new file mode 100644
index 00000000000..a97c3a79947
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h
@@ -0,0 +1,167 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#define NPHY_TBL_ID_GAIN1 0
18#define NPHY_TBL_ID_GAIN2 1
19#define NPHY_TBL_ID_GAINBITS1 2
20#define NPHY_TBL_ID_GAINBITS2 3
21#define NPHY_TBL_ID_GAINLIMIT 4
22#define NPHY_TBL_ID_WRSSIGainLimit 5
23#define NPHY_TBL_ID_RFSEQ 7
24#define NPHY_TBL_ID_AFECTRL 8
25#define NPHY_TBL_ID_ANTSWCTRLLUT 9
26#define NPHY_TBL_ID_IQLOCAL 15
27#define NPHY_TBL_ID_NOISEVAR 16
28#define NPHY_TBL_ID_SAMPLEPLAY 17
29#define NPHY_TBL_ID_CORE1TXPWRCTL 26
30#define NPHY_TBL_ID_CORE2TXPWRCTL 27
31#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30
32
33#define NPHY_TBL_ID_EPSILONTBL0 31
34#define NPHY_TBL_ID_SCALARTBL0 32
35#define NPHY_TBL_ID_EPSILONTBL1 33
36#define NPHY_TBL_ID_SCALARTBL1 34
37
38#define NPHY_TO_BPHY_OFF 0xc00
39
40#define NPHY_BandControl_currentBand 0x0001
41#define RFCC_CHIP0_PU 0x0400
42#define RFCC_POR_FORCE 0x0040
43#define RFCC_OE_POR_FORCE 0x0080
44#define NPHY_RfctrlIntc_override_OFF 0
45#define NPHY_RfctrlIntc_override_TRSW 1
46#define NPHY_RfctrlIntc_override_PA 2
47#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3
48#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4
49#define RIFS_ENABLE 0x80
50#define BPHY_BAND_SEL_UP20 0x10
51#define NPHY_MLenable 0x02
52
53#define NPHY_RfseqMode_CoreActv_override 0x0001
54#define NPHY_RfseqMode_Trigger_override 0x0002
55#define NPHY_RfseqCoreActv_TxRxChain0 (0x11)
56#define NPHY_RfseqCoreActv_TxRxChain1 (0x22)
57
58#define NPHY_RfseqTrigger_rx2tx 0x0001
59#define NPHY_RfseqTrigger_tx2rx 0x0002
60#define NPHY_RfseqTrigger_updategainh 0x0004
61#define NPHY_RfseqTrigger_updategainl 0x0008
62#define NPHY_RfseqTrigger_updategainu 0x0010
63#define NPHY_RfseqTrigger_reset2rx 0x0020
64#define NPHY_RfseqStatus_rx2tx 0x0001
65#define NPHY_RfseqStatus_tx2rx 0x0002
66#define NPHY_RfseqStatus_updategainh 0x0004
67#define NPHY_RfseqStatus_updategainl 0x0008
68#define NPHY_RfseqStatus_updategainu 0x0010
69#define NPHY_RfseqStatus_reset2rx 0x0020
70#define NPHY_ClassifierCtrl_cck_en 0x1
71#define NPHY_ClassifierCtrl_ofdm_en 0x2
72#define NPHY_ClassifierCtrl_waited_en 0x4
73#define NPHY_IQFlip_ADC1 0x0001
74#define NPHY_IQFlip_ADC2 0x0010
75#define NPHY_sampleCmd_STOP 0x0002
76
77#define RX_GF_OR_MM 0x0004
78#define RX_GF_MM_AUTO 0x0100
79
80#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000
81
82#define NPHY_IqestCmd_iqstart 0x1
83#define NPHY_IqestCmd_iqMode 0x2
84
85#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40
86#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19
87
88#define PRIM_SEL_UP20 0x8000
89
90#define NPHY_RFSEQ_RX2TX 0x0
91#define NPHY_RFSEQ_TX2RX 0x1
92#define NPHY_RFSEQ_RESET2RX 0x2
93#define NPHY_RFSEQ_UPDATEGAINH 0x3
94#define NPHY_RFSEQ_UPDATEGAINL 0x4
95#define NPHY_RFSEQ_UPDATEGAINU 0x5
96
97#define NPHY_RFSEQ_CMD_NOP 0x0
98#define NPHY_RFSEQ_CMD_RXG_FBW 0x1
99#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2
100#define NPHY_RFSEQ_CMD_EXT_PA 0x3
101#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4
102#define NPHY_RFSEQ_CMD_TX_GAIN 0x5
103#define NPHY_RFSEQ_CMD_RX_GAIN 0x6
104#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7
105#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8
106#define NPHY_RFSEQ_CMD_END 0xf
107
108#define NPHY_REV3_RFSEQ_CMD_NOP 0x0
109#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1
110#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2
111#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3
112#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4
113#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5
114#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6
115#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7
116#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8
117#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9
118#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa
119#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb
120#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc
121#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd
122#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe
123#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf
124#define NPHY_REV3_RFSEQ_CMD_END 0x1f
125
126#define NPHY_RSSI_SEL_W1 0x0
127#define NPHY_RSSI_SEL_W2 0x1
128#define NPHY_RSSI_SEL_NB 0x2
129#define NPHY_RSSI_SEL_IQ 0x3
130#define NPHY_RSSI_SEL_TSSI_2G 0x4
131#define NPHY_RSSI_SEL_TSSI_5G 0x5
132#define NPHY_RSSI_SEL_TBD 0x6
133
134#define NPHY_RAIL_I 0x0
135#define NPHY_RAIL_Q 0x1
136
137#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8
138
139#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
140#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1
141#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2
142#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3
143#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4
144
145#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
146#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00
147#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
148
149#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff
150#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000
151#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
152
153#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
154#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
155#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
156
157#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134)
158
159#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135)
160
161#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136)
162
163#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137)
164
165#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138)
166
167#define NPHY_IqestqpwrAccHi(core) ((core == 0) ? 0x131 : 0x139)
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c
new file mode 100644
index 00000000000..023d05aa97a
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -0,0 +1,3638 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <types.h>
18#include "phytbl_lcn.h"
19
20const u32 dot11lcn_gain_tbl_rev0[] = {
21 0x00000000,
22 0x00000000,
23 0x00000000,
24 0x00000000,
25 0x00000000,
26 0x00000000,
27 0x00000000,
28 0x00000000,
29 0x00000004,
30 0x00000000,
31 0x00000004,
32 0x00000008,
33 0x00000001,
34 0x00000005,
35 0x00000009,
36 0x0000000d,
37 0x0000004d,
38 0x0000008d,
39 0x0000000d,
40 0x0000004d,
41 0x0000008d,
42 0x000000cd,
43 0x0000004f,
44 0x0000008f,
45 0x000000cf,
46 0x000000d3,
47 0x00000113,
48 0x00000513,
49 0x00000913,
50 0x00000953,
51 0x00000d53,
52 0x00001153,
53 0x00001193,
54 0x00005193,
55 0x00009193,
56 0x0000d193,
57 0x00011193,
58 0x00000000,
59 0x00000000,
60 0x00000000,
61 0x00000000,
62 0x00000000,
63 0x00000000,
64 0x00000004,
65 0x00000000,
66 0x00000004,
67 0x00000008,
68 0x00000001,
69 0x00000005,
70 0x00000009,
71 0x0000000d,
72 0x0000004d,
73 0x0000008d,
74 0x0000000d,
75 0x0000004d,
76 0x0000008d,
77 0x000000cd,
78 0x0000004f,
79 0x0000008f,
80 0x000000cf,
81 0x000000d3,
82 0x00000113,
83 0x00000513,
84 0x00000913,
85 0x00000953,
86 0x00000d53,
87 0x00001153,
88 0x00005153,
89 0x00009153,
90 0x0000d153,
91 0x00011153,
92 0x00015153,
93 0x00019153,
94 0x0001d153,
95 0x00000000,
96 0x00000000,
97 0x00000000,
98 0x00000000,
99 0x00000000,
100 0x00000000,
101 0x00000000,
102 0x00000000,
103 0x00000000,
104 0x00000000,
105 0x00000000,
106 0x00000000,
107 0x00000000,
108 0x00000000,
109 0x00000000,
110 0x00000000,
111 0x00000000,
112 0x00000000,
113 0x00000000,
114 0x00000000,
115 0x00000000,
116 0x00000000,
117};
118
119const u32 dot11lcn_gain_tbl_rev1[] = {
120 0x00000000,
121 0x00000000,
122 0x00000000,
123 0x00000000,
124 0x00000000,
125 0x00000000,
126 0x00000000,
127 0x00000000,
128 0x00000008,
129 0x00000004,
130 0x00000008,
131 0x00000001,
132 0x00000005,
133 0x00000009,
134 0x0000000D,
135 0x00000011,
136 0x00000051,
137 0x00000091,
138 0x00000011,
139 0x00000051,
140 0x00000091,
141 0x000000d1,
142 0x00000053,
143 0x00000093,
144 0x000000d3,
145 0x000000d7,
146 0x00000117,
147 0x00000517,
148 0x00000917,
149 0x00000957,
150 0x00000d57,
151 0x00001157,
152 0x00001197,
153 0x00005197,
154 0x00009197,
155 0x0000d197,
156 0x00011197,
157 0x00000000,
158 0x00000000,
159 0x00000000,
160 0x00000000,
161 0x00000000,
162 0x00000000,
163 0x00000008,
164 0x00000004,
165 0x00000008,
166 0x00000001,
167 0x00000005,
168 0x00000009,
169 0x0000000D,
170 0x00000011,
171 0x00000051,
172 0x00000091,
173 0x00000011,
174 0x00000051,
175 0x00000091,
176 0x000000d1,
177 0x00000053,
178 0x00000093,
179 0x000000d3,
180 0x000000d7,
181 0x00000117,
182 0x00000517,
183 0x00000917,
184 0x00000957,
185 0x00000d57,
186 0x00001157,
187 0x00005157,
188 0x00009157,
189 0x0000d157,
190 0x00011157,
191 0x00015157,
192 0x00019157,
193 0x0001d157,
194 0x00000000,
195 0x00000000,
196 0x00000000,
197 0x00000000,
198 0x00000000,
199 0x00000000,
200 0x00000000,
201 0x00000000,
202 0x00000000,
203 0x00000000,
204 0x00000000,
205 0x00000000,
206 0x00000000,
207 0x00000000,
208 0x00000000,
209 0x00000000,
210 0x00000000,
211 0x00000000,
212 0x00000000,
213 0x00000000,
214 0x00000000,
215 0x00000000,
216};
217
218const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = {
219 0x0401,
220 0x0402,
221 0x0403,
222 0x0404,
223 0x0405,
224 0x0406,
225 0x0407,
226 0x0408,
227 0x0409,
228 0x040a,
229 0x058b,
230 0x058c,
231 0x058d,
232 0x058e,
233 0x058f,
234 0x0090,
235 0x0091,
236 0x0092,
237 0x0193,
238 0x0194,
239 0x0195,
240 0x0196,
241 0x0197,
242 0x0198,
243 0x0199,
244 0x019a,
245 0x019b,
246 0x019c,
247 0x019d,
248 0x019e,
249 0x019f,
250 0x01a0,
251 0x01a1,
252 0x01a2,
253 0x01a3,
254 0x01a4,
255 0x01a5,
256 0x0000,
257};
258
259const u32 dot11lcn_gain_idx_tbl_rev0[] = {
260 0x00000000,
261 0x00000000,
262 0x10000000,
263 0x00000000,
264 0x20000000,
265 0x00000000,
266 0x30000000,
267 0x00000000,
268 0x40000000,
269 0x00000000,
270 0x50000000,
271 0x00000000,
272 0x60000000,
273 0x00000000,
274 0x70000000,
275 0x00000000,
276 0x80000000,
277 0x00000000,
278 0x90000000,
279 0x00000008,
280 0xa0000000,
281 0x00000008,
282 0xb0000000,
283 0x00000008,
284 0xc0000000,
285 0x00000008,
286 0xd0000000,
287 0x00000008,
288 0xe0000000,
289 0x00000008,
290 0xf0000000,
291 0x00000008,
292 0x00000000,
293 0x00000009,
294 0x10000000,
295 0x00000009,
296 0x20000000,
297 0x00000019,
298 0x30000000,
299 0x00000019,
300 0x40000000,
301 0x00000019,
302 0x50000000,
303 0x00000019,
304 0x60000000,
305 0x00000019,
306 0x70000000,
307 0x00000019,
308 0x80000000,
309 0x00000019,
310 0x90000000,
311 0x00000019,
312 0xa0000000,
313 0x00000019,
314 0xb0000000,
315 0x00000019,
316 0xc0000000,
317 0x00000019,
318 0xd0000000,
319 0x00000019,
320 0xe0000000,
321 0x00000019,
322 0xf0000000,
323 0x00000019,
324 0x00000000,
325 0x0000001a,
326 0x10000000,
327 0x0000001a,
328 0x20000000,
329 0x0000001a,
330 0x30000000,
331 0x0000001a,
332 0x40000000,
333 0x0000001a,
334 0x50000000,
335 0x00000002,
336 0x60000000,
337 0x00000002,
338 0x70000000,
339 0x00000002,
340 0x80000000,
341 0x00000002,
342 0x90000000,
343 0x00000002,
344 0xa0000000,
345 0x00000002,
346 0xb0000000,
347 0x00000002,
348 0xc0000000,
349 0x0000000a,
350 0xd0000000,
351 0x0000000a,
352 0xe0000000,
353 0x0000000a,
354 0xf0000000,
355 0x0000000a,
356 0x00000000,
357 0x0000000b,
358 0x10000000,
359 0x0000000b,
360 0x20000000,
361 0x0000000b,
362 0x30000000,
363 0x0000000b,
364 0x40000000,
365 0x0000000b,
366 0x50000000,
367 0x0000001b,
368 0x60000000,
369 0x0000001b,
370 0x70000000,
371 0x0000001b,
372 0x80000000,
373 0x0000001b,
374 0x90000000,
375 0x0000001b,
376 0xa0000000,
377 0x0000001b,
378 0xb0000000,
379 0x0000001b,
380 0xc0000000,
381 0x0000001b,
382 0xd0000000,
383 0x0000001b,
384 0xe0000000,
385 0x0000001b,
386 0xf0000000,
387 0x0000001b,
388 0x00000000,
389 0x0000001c,
390 0x10000000,
391 0x0000001c,
392 0x20000000,
393 0x0000001c,
394 0x30000000,
395 0x0000001c,
396 0x40000000,
397 0x0000001c,
398 0x50000000,
399 0x0000001c,
400 0x60000000,
401 0x0000001c,
402 0x70000000,
403 0x0000001c,
404 0x80000000,
405 0x0000001c,
406 0x90000000,
407 0x0000001c,
408};
409
410const u16 dot11lcn_aux_gain_idx_tbl_2G[] = {
411 0x0000,
412 0x0000,
413 0x0000,
414 0x0000,
415 0x0001,
416 0x0080,
417 0x0081,
418 0x0100,
419 0x0101,
420 0x0180,
421 0x0181,
422 0x0182,
423 0x0183,
424 0x0184,
425 0x0185,
426 0x0186,
427 0x0187,
428 0x0188,
429 0x0285,
430 0x0289,
431 0x028a,
432 0x028b,
433 0x028c,
434 0x028d,
435 0x028e,
436 0x028f,
437 0x0290,
438 0x0291,
439 0x0292,
440 0x0293,
441 0x0294,
442 0x0295,
443 0x0296,
444 0x0297,
445 0x0298,
446 0x0299,
447 0x029a,
448 0x0000
449};
450
451const u8 dot11lcn_gain_val_tbl_2G[] = {
452 0xfc,
453 0x02,
454 0x08,
455 0x0e,
456 0x13,
457 0x1b,
458 0xfc,
459 0x02,
460 0x08,
461 0x0e,
462 0x13,
463 0x1b,
464 0xfc,
465 0x00,
466 0x0c,
467 0x03,
468 0xeb,
469 0xfe,
470 0x07,
471 0x0b,
472 0x0f,
473 0xfb,
474 0xfe,
475 0x01,
476 0x05,
477 0x08,
478 0x0b,
479 0x0e,
480 0x11,
481 0x14,
482 0x17,
483 0x00,
484 0x00,
485 0x00,
486 0x00,
487 0x00,
488 0x00,
489 0x00,
490 0x03,
491 0x06,
492 0x09,
493 0x0c,
494 0x0f,
495 0x12,
496 0x00,
497 0x00,
498 0x00,
499 0x00,
500 0x00,
501 0x00,
502 0x00,
503 0x00,
504 0x00,
505 0x00,
506 0x03,
507 0x06,
508 0x09,
509 0x0c,
510 0x0f,
511 0x12,
512 0x15,
513 0x18,
514 0x1b,
515 0x00,
516 0x00,
517 0x00,
518 0x00,
519 0x00
520};
521
522const u32 dot11lcn_gain_idx_tbl_2G[] = {
523 0x00000000,
524 0x00000000,
525 0x00000000,
526 0x00000000,
527 0x00000000,
528 0x00000000,
529 0x00000000,
530 0x00000000,
531 0x10000000,
532 0x00000000,
533 0x00000000,
534 0x00000008,
535 0x10000000,
536 0x00000008,
537 0x00000000,
538 0x00000010,
539 0x10000000,
540 0x00000010,
541 0x00000000,
542 0x00000018,
543 0x10000000,
544 0x00000018,
545 0x20000000,
546 0x00000018,
547 0x30000000,
548 0x00000018,
549 0x40000000,
550 0x00000018,
551 0x50000000,
552 0x00000018,
553 0x60000000,
554 0x00000018,
555 0x70000000,
556 0x00000018,
557 0x80000000,
558 0x00000018,
559 0x50000000,
560 0x00000028,
561 0x90000000,
562 0x00000028,
563 0xa0000000,
564 0x00000028,
565 0xb0000000,
566 0x00000028,
567 0xc0000000,
568 0x00000028,
569 0xd0000000,
570 0x00000028,
571 0xe0000000,
572 0x00000028,
573 0xf0000000,
574 0x00000028,
575 0x00000000,
576 0x00000029,
577 0x10000000,
578 0x00000029,
579 0x20000000,
580 0x00000029,
581 0x30000000,
582 0x00000029,
583 0x40000000,
584 0x00000029,
585 0x50000000,
586 0x00000029,
587 0x60000000,
588 0x00000029,
589 0x70000000,
590 0x00000029,
591 0x80000000,
592 0x00000029,
593 0x90000000,
594 0x00000029,
595 0xa0000000,
596 0x00000029,
597 0x00000000,
598 0x00000000,
599 0x00000000,
600 0x00000000,
601 0x10000000,
602 0x00000000,
603 0x00000000,
604 0x00000008,
605 0x10000000,
606 0x00000008,
607 0x00000000,
608 0x00000010,
609 0x10000000,
610 0x00000010,
611 0x00000000,
612 0x00000018,
613 0x10000000,
614 0x00000018,
615 0x20000000,
616 0x00000018,
617 0x30000000,
618 0x00000018,
619 0x40000000,
620 0x00000018,
621 0x50000000,
622 0x00000018,
623 0x60000000,
624 0x00000018,
625 0x70000000,
626 0x00000018,
627 0x80000000,
628 0x00000018,
629 0x50000000,
630 0x00000028,
631 0x90000000,
632 0x00000028,
633 0xa0000000,
634 0x00000028,
635 0xb0000000,
636 0x00000028,
637 0xc0000000,
638 0x00000028,
639 0xd0000000,
640 0x00000028,
641 0xe0000000,
642 0x00000028,
643 0xf0000000,
644 0x00000028,
645 0x00000000,
646 0x00000029,
647 0x10000000,
648 0x00000029,
649 0x20000000,
650 0x00000029,
651 0x30000000,
652 0x00000029,
653 0x40000000,
654 0x00000029,
655 0x50000000,
656 0x00000029,
657 0x60000000,
658 0x00000029,
659 0x70000000,
660 0x00000029,
661 0x80000000,
662 0x00000029,
663 0x90000000,
664 0x00000029,
665 0xa0000000,
666 0x00000029,
667 0xb0000000,
668 0x00000029,
669 0xc0000000,
670 0x00000029,
671 0x00000000,
672 0x00000000,
673 0x00000000,
674 0x00000000
675};
676
677const u32 dot11lcn_gain_tbl_2G[] = {
678 0x00000000,
679 0x00000004,
680 0x00000008,
681 0x00000001,
682 0x00000005,
683 0x00000009,
684 0x0000000d,
685 0x0000004d,
686 0x0000008d,
687 0x00000049,
688 0x00000089,
689 0x000000c9,
690 0x0000004b,
691 0x0000008b,
692 0x000000cb,
693 0x000000cf,
694 0x0000010f,
695 0x0000050f,
696 0x0000090f,
697 0x0000094f,
698 0x00000d4f,
699 0x0000114f,
700 0x0000118f,
701 0x0000518f,
702 0x0000918f,
703 0x0000d18f,
704 0x0001118f,
705 0x0001518f,
706 0x0001918f,
707 0x00000000,
708 0x00000000,
709 0x00000000,
710 0x00000000,
711 0x00000000,
712 0x00000000,
713 0x00000000,
714 0x00000000,
715 0x00000000,
716 0x00000000,
717 0x00000000,
718 0x00000000,
719 0x00000000,
720 0x00000000,
721 0x00000000,
722 0x00000000,
723 0x00000000,
724 0x00000000,
725 0x00000000,
726 0x00000000,
727 0x00000000,
728 0x00000000,
729 0x00000000,
730 0x00000000,
731 0x00000000,
732 0x00000000,
733 0x00000000,
734 0x00000000,
735 0x00000000,
736 0x00000000,
737 0x00000000,
738 0x00000000,
739 0x00000000,
740 0x00000000,
741 0x00000000,
742 0x00000000,
743 0x00000000,
744 0x00000000,
745 0x00000000,
746 0x00000000,
747 0x00000000,
748 0x00000000,
749 0x00000000,
750 0x00000000,
751 0x00000000,
752 0x00000000,
753 0x00000000,
754 0x00000000,
755 0x00000000,
756 0x00000000,
757 0x00000000,
758 0x00000000,
759 0x00000000,
760 0x00000000,
761 0x00000000,
762 0x00000000,
763 0x00000000,
764 0x00000000,
765 0x00000000,
766 0x00000000,
767 0x00000000,
768 0x00000000,
769 0x00000000,
770 0x00000000,
771 0x00000000,
772 0x00000000,
773 0x00000000
774};
775
776const u32 dot11lcn_gain_tbl_extlna_2G[] = {
777 0x00000000,
778 0x00000004,
779 0x00000008,
780 0x00000001,
781 0x00000005,
782 0x00000009,
783 0x0000000d,
784 0x00000003,
785 0x00000007,
786 0x0000000b,
787 0x0000000f,
788 0x0000004f,
789 0x0000008f,
790 0x000000cf,
791 0x0000010f,
792 0x0000014f,
793 0x0000018f,
794 0x0000058f,
795 0x0000098f,
796 0x00000d8f,
797 0x00008000,
798 0x00008004,
799 0x00008008,
800 0x00008001,
801 0x00008005,
802 0x00008009,
803 0x0000800d,
804 0x00008003,
805 0x00008007,
806 0x0000800b,
807 0x0000800f,
808 0x0000804f,
809 0x0000808f,
810 0x000080cf,
811 0x0000810f,
812 0x0000814f,
813 0x0000818f,
814 0x0000858f,
815 0x0000898f,
816 0x00008d8f,
817 0x00000000,
818 0x00000000,
819 0x00000000,
820 0x00000000,
821 0x00000000,
822 0x00000000,
823 0x00000000,
824 0x00000000,
825 0x00000000,
826 0x00000000,
827 0x00000000,
828 0x00000000,
829 0x00000000,
830 0x00000000,
831 0x00000000,
832 0x00000000,
833 0x00000000,
834 0x00000000,
835 0x00000000,
836 0x00000000,
837 0x00000000,
838 0x00000000,
839 0x00000000,
840 0x00000000,
841 0x00000000,
842 0x00000000,
843 0x00000000,
844 0x00000000,
845 0x00000000,
846 0x00000000,
847 0x00000000,
848 0x00000000,
849 0x00000000,
850 0x00000000,
851 0x00000000,
852 0x00000000,
853 0x00000000,
854 0x00000000,
855 0x00000000,
856 0x00000000,
857 0x00000000,
858 0x00000000,
859 0x00000000,
860 0x00000000,
861 0x00000000,
862 0x00000000,
863 0x00000000,
864 0x00000000,
865 0x00000000,
866 0x00000000,
867 0x00000000,
868 0x00000000,
869 0x00000000,
870 0x00000000,
871 0x00000000,
872 0x00000000
873};
874
875const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = {
876 0x0400,
877 0x0400,
878 0x0400,
879 0x0400,
880 0x0400,
881 0x0400,
882 0x0400,
883 0x0400,
884 0x0400,
885 0x0401,
886 0x0402,
887 0x0403,
888 0x0404,
889 0x0483,
890 0x0484,
891 0x0485,
892 0x0486,
893 0x0583,
894 0x0584,
895 0x0585,
896 0x0587,
897 0x0588,
898 0x0589,
899 0x058a,
900 0x0687,
901 0x0688,
902 0x0689,
903 0x068a,
904 0x068b,
905 0x068c,
906 0x068d,
907 0x068e,
908 0x068f,
909 0x0690,
910 0x0691,
911 0x0692,
912 0x0693,
913 0x0000
914};
915
916const u8 dot11lcn_gain_val_tbl_extlna_2G[] = {
917 0xfc,
918 0x02,
919 0x08,
920 0x0e,
921 0x13,
922 0x1b,
923 0xfc,
924 0x02,
925 0x08,
926 0x0e,
927 0x13,
928 0x1b,
929 0xfc,
930 0x00,
931 0x0f,
932 0x03,
933 0xeb,
934 0xfe,
935 0x07,
936 0x0b,
937 0x0f,
938 0xfb,
939 0xfe,
940 0x01,
941 0x05,
942 0x08,
943 0x0b,
944 0x0e,
945 0x11,
946 0x14,
947 0x17,
948 0x00,
949 0x00,
950 0x00,
951 0x00,
952 0x00,
953 0x00,
954 0x00,
955 0x03,
956 0x06,
957 0x09,
958 0x0c,
959 0x0f,
960 0x12,
961 0x00,
962 0x00,
963 0x00,
964 0x00,
965 0x00,
966 0x00,
967 0x00,
968 0x00,
969 0x00,
970 0x00,
971 0x03,
972 0x06,
973 0x09,
974 0x0c,
975 0x0f,
976 0x12,
977 0x15,
978 0x18,
979 0x1b,
980 0x00,
981 0x00,
982 0x00,
983 0x00,
984 0x00
985};
986
987const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = {
988 0x00000000,
989 0x00000040,
990 0x00000000,
991 0x00000040,
992 0x00000000,
993 0x00000040,
994 0x00000000,
995 0x00000040,
996 0x00000000,
997 0x00000040,
998 0x00000000,
999 0x00000040,
1000 0x00000000,
1001 0x00000040,
1002 0x00000000,
1003 0x00000040,
1004 0x00000000,
1005 0x00000040,
1006 0x10000000,
1007 0x00000040,
1008 0x20000000,
1009 0x00000040,
1010 0x30000000,
1011 0x00000040,
1012 0x40000000,
1013 0x00000040,
1014 0x30000000,
1015 0x00000048,
1016 0x40000000,
1017 0x00000048,
1018 0x50000000,
1019 0x00000048,
1020 0x60000000,
1021 0x00000048,
1022 0x30000000,
1023 0x00000058,
1024 0x40000000,
1025 0x00000058,
1026 0x50000000,
1027 0x00000058,
1028 0x70000000,
1029 0x00000058,
1030 0x80000000,
1031 0x00000058,
1032 0x90000000,
1033 0x00000058,
1034 0xa0000000,
1035 0x00000058,
1036 0x70000000,
1037 0x00000068,
1038 0x80000000,
1039 0x00000068,
1040 0x90000000,
1041 0x00000068,
1042 0xa0000000,
1043 0x00000068,
1044 0xb0000000,
1045 0x00000068,
1046 0xc0000000,
1047 0x00000068,
1048 0xd0000000,
1049 0x00000068,
1050 0xe0000000,
1051 0x00000068,
1052 0xf0000000,
1053 0x00000068,
1054 0x00000000,
1055 0x00000069,
1056 0x10000000,
1057 0x00000069,
1058 0x20000000,
1059 0x00000069,
1060 0x30000000,
1061 0x00000069,
1062 0x40000000,
1063 0x00000041,
1064 0x40000000,
1065 0x00000041,
1066 0x40000000,
1067 0x00000041,
1068 0x40000000,
1069 0x00000041,
1070 0x40000000,
1071 0x00000041,
1072 0x40000000,
1073 0x00000041,
1074 0x40000000,
1075 0x00000041,
1076 0x40000000,
1077 0x00000041,
1078 0x40000000,
1079 0x00000041,
1080 0x50000000,
1081 0x00000041,
1082 0x60000000,
1083 0x00000041,
1084 0x70000000,
1085 0x00000041,
1086 0x80000000,
1087 0x00000041,
1088 0x70000000,
1089 0x00000049,
1090 0x80000000,
1091 0x00000049,
1092 0x90000000,
1093 0x00000049,
1094 0xa0000000,
1095 0x00000049,
1096 0x70000000,
1097 0x00000059,
1098 0x80000000,
1099 0x00000059,
1100 0x90000000,
1101 0x00000059,
1102 0xb0000000,
1103 0x00000059,
1104 0xc0000000,
1105 0x00000059,
1106 0xd0000000,
1107 0x00000059,
1108 0xe0000000,
1109 0x00000059,
1110 0xb0000000,
1111 0x00000069,
1112 0xc0000000,
1113 0x00000069,
1114 0xd0000000,
1115 0x00000069,
1116 0xe0000000,
1117 0x00000069,
1118 0xf0000000,
1119 0x00000069,
1120 0x00000000,
1121 0x0000006a,
1122 0x10000000,
1123 0x0000006a,
1124 0x20000000,
1125 0x0000006a,
1126 0x30000000,
1127 0x0000006a,
1128 0x40000000,
1129 0x0000006a,
1130 0x50000000,
1131 0x0000006a,
1132 0x60000000,
1133 0x0000006a,
1134 0x70000000,
1135 0x0000006a,
1136 0x00000000,
1137 0x00000000,
1138 0x00000000,
1139 0x00000000
1140};
1141
1142const u32 dot11lcn_aux_gain_idx_tbl_5G[] = {
1143 0x0000,
1144 0x0000,
1145 0x0000,
1146 0x0000,
1147 0x0001,
1148 0x0002,
1149 0x0003,
1150 0x0004,
1151 0x0083,
1152 0x0084,
1153 0x0085,
1154 0x0086,
1155 0x0087,
1156 0x0186,
1157 0x0187,
1158 0x0188,
1159 0x0189,
1160 0x018a,
1161 0x018b,
1162 0x018c,
1163 0x018d,
1164 0x018e,
1165 0x018f,
1166 0x0190,
1167 0x0191,
1168 0x0192,
1169 0x0193,
1170 0x0194,
1171 0x0195,
1172 0x0196,
1173 0x0197,
1174 0x0198,
1175 0x0199,
1176 0x019a,
1177 0x019b,
1178 0x019c,
1179 0x019d,
1180 0x0000
1181};
1182
1183const u32 dot11lcn_gain_val_tbl_5G[] = {
1184 0xf7,
1185 0xfd,
1186 0x00,
1187 0x04,
1188 0x04,
1189 0x04,
1190 0xf7,
1191 0xfd,
1192 0x00,
1193 0x04,
1194 0x04,
1195 0x04,
1196 0xf6,
1197 0x00,
1198 0x0c,
1199 0x03,
1200 0xeb,
1201 0xfe,
1202 0x06,
1203 0x0a,
1204 0x10,
1205 0x00,
1206 0x03,
1207 0x06,
1208 0x09,
1209 0x0c,
1210 0x0f,
1211 0x12,
1212 0x15,
1213 0x18,
1214 0x1b,
1215 0x00,
1216 0x00,
1217 0x00,
1218 0x00,
1219 0x00,
1220 0x00,
1221 0x00,
1222 0x03,
1223 0x06,
1224 0x09,
1225 0x0c,
1226 0x0f,
1227 0x12,
1228 0x00,
1229 0x00,
1230 0x00,
1231 0x00,
1232 0x00,
1233 0x00,
1234 0x00,
1235 0x00,
1236 0x00,
1237 0x00,
1238 0x03,
1239 0x06,
1240 0x09,
1241 0x0c,
1242 0x0f,
1243 0x12,
1244 0x15,
1245 0x18,
1246 0x1b,
1247 0x00,
1248 0x00,
1249 0x00,
1250 0x00,
1251 0x00
1252};
1253
1254const u32 dot11lcn_gain_idx_tbl_5G[] = {
1255 0x00000000,
1256 0x00000000,
1257 0x00000000,
1258 0x00000000,
1259 0x00000000,
1260 0x00000000,
1261 0x00000000,
1262 0x00000000,
1263 0x10000000,
1264 0x00000000,
1265 0x20000000,
1266 0x00000000,
1267 0x30000000,
1268 0x00000000,
1269 0x40000000,
1270 0x00000000,
1271 0x30000000,
1272 0x00000008,
1273 0x40000000,
1274 0x00000008,
1275 0x50000000,
1276 0x00000008,
1277 0x60000000,
1278 0x00000008,
1279 0x70000000,
1280 0x00000008,
1281 0x60000000,
1282 0x00000018,
1283 0x70000000,
1284 0x00000018,
1285 0x80000000,
1286 0x00000018,
1287 0x90000000,
1288 0x00000018,
1289 0xa0000000,
1290 0x00000018,
1291 0xb0000000,
1292 0x00000018,
1293 0xc0000000,
1294 0x00000018,
1295 0xd0000000,
1296 0x00000018,
1297 0xe0000000,
1298 0x00000018,
1299 0xf0000000,
1300 0x00000018,
1301 0x00000000,
1302 0x00000019,
1303 0x10000000,
1304 0x00000019,
1305 0x20000000,
1306 0x00000019,
1307 0x30000000,
1308 0x00000019,
1309 0x40000000,
1310 0x00000019,
1311 0x50000000,
1312 0x00000019,
1313 0x60000000,
1314 0x00000019,
1315 0x70000000,
1316 0x00000019,
1317 0x80000000,
1318 0x00000019,
1319 0x90000000,
1320 0x00000019,
1321 0xa0000000,
1322 0x00000019,
1323 0xb0000000,
1324 0x00000019,
1325 0xc0000000,
1326 0x00000019,
1327 0xd0000000,
1328 0x00000019,
1329 0x00000000,
1330 0x00000000,
1331 0x00000000,
1332 0x00000000,
1333 0x00000000,
1334 0x00000000,
1335 0x00000000,
1336 0x00000000,
1337 0x00000000,
1338 0x00000000,
1339 0x00000000,
1340 0x00000000,
1341 0x00000000,
1342 0x00000000,
1343 0x00000000,
1344 0x00000000,
1345 0x00000000,
1346 0x00000000,
1347 0x00000000,
1348 0x00000000,
1349 0x00000000,
1350 0x00000000,
1351 0x00000000,
1352 0x00000000,
1353 0x00000000,
1354 0x00000000,
1355 0x00000000,
1356 0x00000000,
1357 0x00000000,
1358 0x00000000,
1359 0x00000000,
1360 0x00000000,
1361 0x00000000,
1362 0x00000000,
1363 0x00000000,
1364 0x00000000,
1365 0x00000000,
1366 0x00000000,
1367 0x00000000,
1368 0x00000000,
1369 0x00000000,
1370 0x00000000,
1371 0x00000000,
1372 0x00000000,
1373 0x00000000,
1374 0x00000000,
1375 0x00000000,
1376 0x00000000,
1377 0x00000000,
1378 0x00000000,
1379 0x00000000,
1380 0x00000000,
1381 0x00000000,
1382 0x00000000,
1383 0x00000000,
1384 0x00000000,
1385 0x00000000,
1386 0x00000000,
1387 0x00000000,
1388 0x00000000,
1389 0x00000000,
1390 0x00000000,
1391 0x00000000,
1392 0x00000000,
1393 0x00000000,
1394 0x00000000,
1395 0x00000000,
1396 0x00000000,
1397 0x00000000,
1398 0x00000000,
1399 0x00000000,
1400 0x00000000,
1401 0x00000000,
1402 0x00000000,
1403 0x00000000,
1404 0x00000000,
1405 0x00000000,
1406 0x00000000
1407};
1408
1409const u32 dot11lcn_gain_tbl_5G[] = {
1410 0x00000000,
1411 0x00000040,
1412 0x00000080,
1413 0x00000001,
1414 0x00000005,
1415 0x00000009,
1416 0x0000000d,
1417 0x00000011,
1418 0x00000015,
1419 0x00000055,
1420 0x00000095,
1421 0x00000017,
1422 0x0000001b,
1423 0x0000005b,
1424 0x0000009b,
1425 0x000000db,
1426 0x0000011b,
1427 0x0000015b,
1428 0x0000019b,
1429 0x0000059b,
1430 0x0000099b,
1431 0x00000d9b,
1432 0x0000119b,
1433 0x0000519b,
1434 0x0000919b,
1435 0x0000d19b,
1436 0x0001119b,
1437 0x0001519b,
1438 0x0001919b,
1439 0x0001d19b,
1440 0x00000000,
1441 0x00000000,
1442 0x00000000,
1443 0x00000000,
1444 0x00000000,
1445 0x00000000,
1446 0x00000000,
1447 0x00000000,
1448 0x00000000,
1449 0x00000000,
1450 0x00000000,
1451 0x00000000,
1452 0x00000000,
1453 0x00000000,
1454 0x00000000,
1455 0x00000000,
1456 0x00000000,
1457 0x00000000,
1458 0x00000000,
1459 0x00000000,
1460 0x00000000,
1461 0x00000000,
1462 0x00000000,
1463 0x00000000,
1464 0x00000000,
1465 0x00000000,
1466 0x00000000,
1467 0x00000000,
1468 0x00000000,
1469 0x00000000,
1470 0x00000000,
1471 0x00000000,
1472 0x00000000,
1473 0x00000000,
1474 0x00000000,
1475 0x00000000,
1476 0x00000000,
1477 0x00000000,
1478 0x00000000,
1479 0x00000000,
1480 0x00000000,
1481 0x00000000,
1482 0x00000000,
1483 0x00000000,
1484 0x00000000,
1485 0x00000000,
1486 0x00000000,
1487 0x00000000,
1488 0x00000000,
1489 0x00000000,
1490 0x00000000,
1491 0x00000000,
1492 0x00000000,
1493 0x00000000,
1494 0x00000000,
1495 0x00000000,
1496 0x00000000,
1497 0x00000000,
1498 0x00000000,
1499 0x00000000,
1500 0x00000000,
1501 0x00000000,
1502 0x00000000,
1503 0x00000000,
1504 0x00000000,
1505 0x00000000
1506};
1507
1508const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[] = {
1509 {&dot11lcn_gain_tbl_rev0,
1510 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
1511 0, 32}
1512 ,
1513 {&dot11lcn_aux_gain_idx_tbl_rev0,
1514 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
1515 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
1516 ,
1517 {&dot11lcn_gain_idx_tbl_rev0,
1518 sizeof(dot11lcn_gain_idx_tbl_rev0) /
1519 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
1520 ,
1521};
1522
1523const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev1[] = {
1524 {&dot11lcn_gain_tbl_rev1,
1525 sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
1526 0, 32}
1527 ,
1528 {&dot11lcn_aux_gain_idx_tbl_rev0,
1529 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
1530 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
1531 ,
1532 {&dot11lcn_gain_idx_tbl_rev0,
1533 sizeof(dot11lcn_gain_idx_tbl_rev0) /
1534 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
1535 ,
1536};
1537
1538const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
1539 {&dot11lcn_gain_tbl_2G,
1540 sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
1541 32}
1542 ,
1543 {&dot11lcn_aux_gain_idx_tbl_2G,
1544 sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
1545 sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
1546 ,
1547 {&dot11lcn_gain_idx_tbl_2G,
1548 sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
1549 13, 0, 32}
1550 ,
1551 {&dot11lcn_gain_val_tbl_2G,
1552 sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
1553 17, 0, 8}
1554};
1555
1556const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
1557 {&dot11lcn_gain_tbl_5G,
1558 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
1559 32}
1560 ,
1561 {&dot11lcn_aux_gain_idx_tbl_5G,
1562 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
1563 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
1564 ,
1565 {&dot11lcn_gain_idx_tbl_5G,
1566 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
1567 13, 0, 32}
1568 ,
1569 {&dot11lcn_gain_val_tbl_5G,
1570 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
1571 17, 0, 8}
1572};
1573
1574const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
1575 {&dot11lcn_gain_tbl_extlna_2G,
1576 sizeof(dot11lcn_gain_tbl_extlna_2G) /
1577 sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
1578 ,
1579 {&dot11lcn_aux_gain_idx_tbl_extlna_2G,
1580 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
1581 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
1582 ,
1583 {&dot11lcn_gain_idx_tbl_extlna_2G,
1584 sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
1585 sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
1586 ,
1587 {&dot11lcn_gain_val_tbl_extlna_2G,
1588 sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
1589 sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
1590};
1591
1592const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
1593 {&dot11lcn_gain_tbl_5G,
1594 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
1595 32}
1596 ,
1597 {&dot11lcn_aux_gain_idx_tbl_5G,
1598 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
1599 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
1600 ,
1601 {&dot11lcn_gain_idx_tbl_5G,
1602 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
1603 13, 0, 32}
1604 ,
1605 {&dot11lcn_gain_val_tbl_5G,
1606 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
1607 17, 0, 8}
1608};
1609
1610const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
1611 sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
1612 sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
1613
1614const u32 dot11lcnphytbl_rx_gain_info_sz_rev1 =
1615 sizeof(dot11lcnphytbl_rx_gain_info_rev1) /
1616 sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]);
1617
1618const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
1619 sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
1620 sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
1621
1622const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
1623 sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
1624 sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
1625
1626const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
1627 0x014d,
1628 0x014d,
1629 0x014d,
1630 0x014d,
1631 0x014d,
1632 0x014d,
1633 0x014d,
1634 0x014d,
1635 0x014d,
1636 0x014d,
1637 0x014d,
1638 0x014d,
1639 0x014d,
1640 0x014d,
1641 0x014d,
1642 0x014d,
1643 0x014d,
1644 0x014d,
1645 0x014d,
1646 0x014d,
1647 0x014d,
1648 0x014d,
1649 0x014d,
1650 0x014d,
1651 0x014d,
1652 0x014d,
1653 0x014d,
1654 0x014d,
1655 0x014d,
1656 0x014d,
1657 0x014d,
1658 0x014d,
1659 0x014d,
1660 0x014d,
1661 0x014d,
1662 0x014d,
1663 0x014d,
1664 0x014d,
1665 0x014d,
1666 0x014d,
1667 0x014d,
1668 0x014d,
1669 0x014d,
1670 0x014d,
1671 0x014d,
1672 0x014d,
1673 0x014d,
1674 0x014d,
1675 0x014d,
1676 0x014d,
1677 0x014d,
1678 0x014d,
1679 0x014d,
1680 0x014d,
1681 0x014d,
1682 0x014d,
1683 0x014d,
1684 0x014d,
1685 0x014d,
1686 0x014d,
1687 0x014d,
1688 0x014d,
1689 0x014d,
1690 0x014d,
1691};
1692
1693const u16 dot11lcn_noise_scale_tbl_rev0[] = {
1694 0x0000,
1695 0x0000,
1696 0x0000,
1697 0x0000,
1698 0x0000,
1699 0x0000,
1700 0x0000,
1701 0x0000,
1702 0x0000,
1703 0x0000,
1704 0x0000,
1705 0x0000,
1706 0x0000,
1707 0x0000,
1708 0x0000,
1709 0x0000,
1710 0x0000,
1711 0x0000,
1712 0x0000,
1713 0x0000,
1714 0x0000,
1715 0x0000,
1716 0x0000,
1717 0x0000,
1718 0x0000,
1719 0x0000,
1720 0x0000,
1721 0x0000,
1722 0x0000,
1723 0x0000,
1724 0x0000,
1725 0x0000,
1726 0x0000,
1727 0x0000,
1728 0x0000,
1729 0x0000,
1730 0x0000,
1731 0x0000,
1732 0x0000,
1733 0x0000,
1734 0x0000,
1735 0x0000,
1736 0x0000,
1737 0x0000,
1738 0x0000,
1739 0x0000,
1740 0x0000,
1741 0x0000,
1742 0x0000,
1743 0x0000,
1744 0x0000,
1745 0x0000,
1746 0x0000,
1747 0x0000,
1748 0x0000,
1749 0x0000,
1750 0x0000,
1751 0x0000,
1752 0x0000,
1753 0x0000,
1754 0x0000,
1755 0x0000,
1756 0x0000,
1757 0x0000,
1758};
1759
1760const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = {
1761 0x000141f8,
1762 0x000021f8,
1763 0x000021fb,
1764 0x000041fb,
1765 0x0001fe4b,
1766 0x0000217b,
1767 0x00002133,
1768 0x000040eb,
1769 0x0001fea3,
1770 0x0000024b,
1771};
1772
1773const u32 dot11lcn_ps_ctrl_tbl_rev0[] = {
1774 0x00100001,
1775 0x00200010,
1776 0x00300001,
1777 0x00400010,
1778 0x00500022,
1779 0x00600122,
1780 0x00700222,
1781 0x00800322,
1782 0x00900422,
1783 0x00a00522,
1784 0x00b00622,
1785 0x00c00722,
1786 0x00d00822,
1787 0x00f00922,
1788 0x00100a22,
1789 0x00200b22,
1790 0x00300c22,
1791 0x00400d22,
1792 0x00500e22,
1793 0x00600f22,
1794};
1795
1796const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = {
1797 0x0007,
1798 0x0005,
1799 0x0006,
1800 0x0004,
1801 0x0007,
1802 0x0005,
1803 0x0006,
1804 0x0004,
1805 0x0007,
1806 0x0005,
1807 0x0006,
1808 0x0004,
1809 0x0007,
1810 0x0005,
1811 0x0006,
1812 0x0004,
1813 0x000b,
1814 0x000b,
1815 0x000a,
1816 0x000a,
1817 0x000b,
1818 0x000b,
1819 0x000a,
1820 0x000a,
1821 0x000b,
1822 0x000b,
1823 0x000a,
1824 0x000a,
1825 0x000b,
1826 0x000b,
1827 0x000a,
1828 0x000a,
1829 0x0007,
1830 0x0005,
1831 0x0006,
1832 0x0004,
1833 0x0007,
1834 0x0005,
1835 0x0006,
1836 0x0004,
1837 0x0007,
1838 0x0005,
1839 0x0006,
1840 0x0004,
1841 0x0007,
1842 0x0005,
1843 0x0006,
1844 0x0004,
1845 0x000b,
1846 0x000b,
1847 0x000a,
1848 0x000a,
1849 0x000b,
1850 0x000b,
1851 0x000a,
1852 0x000a,
1853 0x000b,
1854 0x000b,
1855 0x000a,
1856 0x000a,
1857 0x000b,
1858 0x000b,
1859 0x000a,
1860 0x000a,
1861
1862};
1863
1864const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = {
1865 0x0007,
1866 0x0005,
1867 0x0002,
1868 0x0000,
1869 0x0007,
1870 0x0005,
1871 0x0002,
1872 0x0000,
1873 0x0007,
1874 0x0005,
1875 0x0002,
1876 0x0000,
1877 0x0007,
1878 0x0005,
1879 0x0002,
1880 0x0000,
1881 0x0007,
1882 0x0007,
1883 0x0002,
1884 0x0002,
1885 0x0007,
1886 0x0007,
1887 0x0002,
1888 0x0002,
1889 0x0007,
1890 0x0007,
1891 0x0002,
1892 0x0002,
1893 0x0007,
1894 0x0007,
1895 0x0002,
1896 0x0002,
1897 0x0007,
1898 0x0005,
1899 0x0002,
1900 0x0000,
1901 0x0007,
1902 0x0005,
1903 0x0002,
1904 0x0000,
1905 0x0007,
1906 0x0005,
1907 0x0002,
1908 0x0000,
1909 0x0007,
1910 0x0005,
1911 0x0002,
1912 0x0000,
1913 0x0007,
1914 0x0007,
1915 0x0002,
1916 0x0002,
1917 0x0007,
1918 0x0007,
1919 0x0002,
1920 0x0002,
1921 0x0007,
1922 0x0007,
1923 0x0002,
1924 0x0002,
1925 0x0007,
1926 0x0007,
1927 0x0002,
1928 0x0002,
1929};
1930
1931const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
1932 0x0002,
1933 0x0008,
1934 0x0004,
1935 0x0001,
1936 0x0002,
1937 0x0008,
1938 0x0004,
1939 0x0001,
1940 0x0002,
1941 0x0008,
1942 0x0004,
1943 0x0001,
1944 0x0002,
1945 0x0008,
1946 0x0004,
1947 0x0001,
1948 0x0002,
1949 0x0008,
1950 0x0004,
1951 0x0001,
1952 0x0002,
1953 0x0008,
1954 0x0004,
1955 0x0001,
1956 0x0002,
1957 0x0008,
1958 0x0004,
1959 0x0001,
1960 0x0002,
1961 0x0008,
1962 0x0004,
1963 0x0001,
1964 0x0002,
1965 0x0008,
1966 0x0004,
1967 0x0001,
1968 0x0002,
1969 0x0008,
1970 0x0004,
1971 0x0001,
1972 0x0002,
1973 0x0008,
1974 0x0004,
1975 0x0001,
1976 0x0002,
1977 0x0008,
1978 0x0004,
1979 0x0001,
1980 0x0002,
1981 0x0008,
1982 0x0004,
1983 0x0001,
1984 0x0002,
1985 0x0008,
1986 0x0004,
1987 0x0001,
1988 0x0002,
1989 0x0008,
1990 0x0004,
1991 0x0001,
1992 0x0002,
1993 0x0008,
1994 0x0004,
1995 0x0001,
1996};
1997
1998const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
1999 0x000a,
2000 0x0009,
2001 0x0006,
2002 0x0005,
2003 0x000a,
2004 0x0009,
2005 0x0006,
2006 0x0005,
2007 0x000a,
2008 0x0009,
2009 0x0006,
2010 0x0005,
2011 0x000a,
2012 0x0009,
2013 0x0006,
2014 0x0005,
2015 0x000a,
2016 0x0009,
2017 0x0006,
2018 0x0005,
2019 0x000a,
2020 0x0009,
2021 0x0006,
2022 0x0005,
2023 0x000a,
2024 0x0009,
2025 0x0006,
2026 0x0005,
2027 0x000a,
2028 0x0009,
2029 0x0006,
2030 0x0005,
2031 0x000a,
2032 0x0009,
2033 0x0006,
2034 0x0005,
2035 0x000a,
2036 0x0009,
2037 0x0006,
2038 0x0005,
2039 0x000a,
2040 0x0009,
2041 0x0006,
2042 0x0005,
2043 0x000a,
2044 0x0009,
2045 0x0006,
2046 0x0005,
2047 0x000a,
2048 0x0009,
2049 0x0006,
2050 0x0005,
2051 0x000a,
2052 0x0009,
2053 0x0006,
2054 0x0005,
2055 0x000a,
2056 0x0009,
2057 0x0006,
2058 0x0005,
2059 0x000a,
2060 0x0009,
2061 0x0006,
2062 0x0005,
2063};
2064
2065const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
2066 0x0004,
2067 0x0004,
2068 0x0002,
2069 0x0002,
2070 0x0004,
2071 0x0004,
2072 0x0002,
2073 0x0002,
2074 0x0004,
2075 0x0004,
2076 0x0002,
2077 0x0002,
2078 0x0004,
2079 0x0004,
2080 0x0002,
2081 0x0002,
2082 0x0004,
2083 0x0004,
2084 0x0002,
2085 0x0002,
2086 0x0004,
2087 0x0004,
2088 0x0002,
2089 0x0002,
2090 0x0004,
2091 0x0004,
2092 0x0002,
2093 0x0002,
2094 0x0004,
2095 0x0004,
2096 0x0002,
2097 0x0002,
2098 0x0004,
2099 0x0004,
2100 0x0002,
2101 0x0002,
2102 0x0004,
2103 0x0004,
2104 0x0002,
2105 0x0002,
2106 0x0004,
2107 0x0004,
2108 0x0002,
2109 0x0002,
2110 0x0004,
2111 0x0004,
2112 0x0002,
2113 0x0002,
2114 0x0004,
2115 0x0004,
2116 0x0002,
2117 0x0002,
2118 0x0004,
2119 0x0004,
2120 0x0002,
2121 0x0002,
2122 0x0004,
2123 0x0004,
2124 0x0002,
2125 0x0002,
2126 0x0004,
2127 0x0004,
2128 0x0002,
2129 0x0002,
2130};
2131
2132const u8 dot11lcn_nf_table_rev0[] = {
2133 0x5f,
2134 0x36,
2135 0x29,
2136 0x1f,
2137 0x5f,
2138 0x36,
2139 0x29,
2140 0x1f,
2141 0x5f,
2142 0x36,
2143 0x29,
2144 0x1f,
2145 0x5f,
2146 0x36,
2147 0x29,
2148 0x1f,
2149};
2150
2151const u8 dot11lcn_gain_val_tbl_rev0[] = {
2152 0x09,
2153 0x0f,
2154 0x14,
2155 0x18,
2156 0xfe,
2157 0x07,
2158 0x0b,
2159 0x0f,
2160 0xfb,
2161 0xfe,
2162 0x01,
2163 0x05,
2164 0x08,
2165 0x0b,
2166 0x0e,
2167 0x11,
2168 0x14,
2169 0x17,
2170 0x00,
2171 0x00,
2172 0x00,
2173 0x00,
2174 0x00,
2175 0x00,
2176 0x00,
2177 0x03,
2178 0x06,
2179 0x09,
2180 0x0c,
2181 0x0f,
2182 0x12,
2183 0x00,
2184 0x00,
2185 0x00,
2186 0x00,
2187 0x00,
2188 0x00,
2189 0x00,
2190 0x00,
2191 0x00,
2192 0x00,
2193 0x03,
2194 0x06,
2195 0x09,
2196 0x0c,
2197 0x0f,
2198 0x12,
2199 0x15,
2200 0x18,
2201 0x1b,
2202 0x00,
2203 0x00,
2204 0x00,
2205 0x00,
2206 0x00,
2207 0x00,
2208 0x03,
2209 0xeb,
2210 0x00,
2211 0x00,
2212};
2213
2214const u8 dot11lcn_spur_tbl_rev0[] = {
2215 0x01,
2216 0x01,
2217 0x01,
2218 0x01,
2219 0x01,
2220 0x01,
2221 0x01,
2222 0x01,
2223 0x01,
2224 0x01,
2225 0x01,
2226 0x01,
2227 0x01,
2228 0x01,
2229 0x01,
2230 0x01,
2231 0x01,
2232 0x01,
2233 0x01,
2234 0x01,
2235 0x01,
2236 0x01,
2237 0x01,
2238 0x01,
2239 0x01,
2240 0x01,
2241 0x01,
2242 0x01,
2243 0x01,
2244 0x01,
2245 0x02,
2246 0x03,
2247 0x01,
2248 0x03,
2249 0x02,
2250 0x01,
2251 0x01,
2252 0x01,
2253 0x01,
2254 0x01,
2255 0x01,
2256 0x01,
2257 0x01,
2258 0x01,
2259 0x01,
2260 0x01,
2261 0x01,
2262 0x01,
2263 0x01,
2264 0x01,
2265 0x01,
2266 0x01,
2267 0x01,
2268 0x01,
2269 0x01,
2270 0x01,
2271 0x01,
2272 0x01,
2273 0x01,
2274 0x01,
2275 0x01,
2276 0x01,
2277 0x01,
2278 0x01,
2279 0x01,
2280 0x01,
2281 0x01,
2282 0x01,
2283 0x01,
2284 0x01,
2285 0x01,
2286 0x01,
2287 0x01,
2288 0x01,
2289 0x01,
2290 0x01,
2291 0x01,
2292 0x01,
2293 0x01,
2294 0x01,
2295 0x01,
2296 0x01,
2297 0x01,
2298 0x01,
2299 0x01,
2300 0x01,
2301 0x01,
2302 0x01,
2303 0x01,
2304 0x01,
2305 0x01,
2306 0x01,
2307 0x01,
2308 0x01,
2309 0x02,
2310 0x03,
2311 0x01,
2312 0x03,
2313 0x02,
2314 0x01,
2315 0x01,
2316 0x01,
2317 0x01,
2318 0x01,
2319 0x01,
2320 0x01,
2321 0x01,
2322 0x01,
2323 0x01,
2324 0x01,
2325 0x01,
2326 0x01,
2327 0x01,
2328 0x01,
2329 0x01,
2330 0x01,
2331 0x01,
2332 0x01,
2333 0x01,
2334 0x01,
2335 0x01,
2336 0x01,
2337 0x01,
2338 0x01,
2339 0x01,
2340 0x01,
2341 0x01,
2342 0x01,
2343};
2344
2345const u16 dot11lcn_unsup_mcs_tbl_rev0[] = {
2346 0x001a,
2347 0x0034,
2348 0x004e,
2349 0x0068,
2350 0x009c,
2351 0x00d0,
2352 0x00ea,
2353 0x0104,
2354 0x0034,
2355 0x0068,
2356 0x009c,
2357 0x00d0,
2358 0x0138,
2359 0x01a0,
2360 0x01d4,
2361 0x0208,
2362 0x004e,
2363 0x009c,
2364 0x00ea,
2365 0x0138,
2366 0x01d4,
2367 0x0270,
2368 0x02be,
2369 0x030c,
2370 0x0068,
2371 0x00d0,
2372 0x0138,
2373 0x01a0,
2374 0x0270,
2375 0x0340,
2376 0x03a8,
2377 0x0410,
2378 0x0018,
2379 0x009c,
2380 0x00d0,
2381 0x0104,
2382 0x00ea,
2383 0x0138,
2384 0x0186,
2385 0x00d0,
2386 0x0104,
2387 0x0104,
2388 0x0138,
2389 0x016c,
2390 0x016c,
2391 0x01a0,
2392 0x0138,
2393 0x0186,
2394 0x0186,
2395 0x01d4,
2396 0x0222,
2397 0x0222,
2398 0x0270,
2399 0x0104,
2400 0x0138,
2401 0x016c,
2402 0x0138,
2403 0x016c,
2404 0x01a0,
2405 0x01d4,
2406 0x01a0,
2407 0x01d4,
2408 0x0208,
2409 0x0208,
2410 0x023c,
2411 0x0186,
2412 0x01d4,
2413 0x0222,
2414 0x01d4,
2415 0x0222,
2416 0x0270,
2417 0x02be,
2418 0x0270,
2419 0x02be,
2420 0x030c,
2421 0x030c,
2422 0x035a,
2423 0x0036,
2424 0x006c,
2425 0x00a2,
2426 0x00d8,
2427 0x0144,
2428 0x01b0,
2429 0x01e6,
2430 0x021c,
2431 0x006c,
2432 0x00d8,
2433 0x0144,
2434 0x01b0,
2435 0x0288,
2436 0x0360,
2437 0x03cc,
2438 0x0438,
2439 0x00a2,
2440 0x0144,
2441 0x01e6,
2442 0x0288,
2443 0x03cc,
2444 0x0510,
2445 0x05b2,
2446 0x0654,
2447 0x00d8,
2448 0x01b0,
2449 0x0288,
2450 0x0360,
2451 0x0510,
2452 0x06c0,
2453 0x0798,
2454 0x0870,
2455 0x0018,
2456 0x0144,
2457 0x01b0,
2458 0x021c,
2459 0x01e6,
2460 0x0288,
2461 0x032a,
2462 0x01b0,
2463 0x021c,
2464 0x021c,
2465 0x0288,
2466 0x02f4,
2467 0x02f4,
2468 0x0360,
2469 0x0288,
2470 0x032a,
2471 0x032a,
2472 0x03cc,
2473 0x046e,
2474 0x046e,
2475 0x0510,
2476 0x021c,
2477 0x0288,
2478 0x02f4,
2479 0x0288,
2480 0x02f4,
2481 0x0360,
2482 0x03cc,
2483 0x0360,
2484 0x03cc,
2485 0x0438,
2486 0x0438,
2487 0x04a4,
2488 0x032a,
2489 0x03cc,
2490 0x046e,
2491 0x03cc,
2492 0x046e,
2493 0x0510,
2494 0x05b2,
2495 0x0510,
2496 0x05b2,
2497 0x0654,
2498 0x0654,
2499 0x06f6,
2500};
2501
2502const u16 dot11lcn_iq_local_tbl_rev0[] = {
2503 0x0200,
2504 0x0300,
2505 0x0400,
2506 0x0600,
2507 0x0800,
2508 0x0b00,
2509 0x1000,
2510 0x1001,
2511 0x1002,
2512 0x1003,
2513 0x1004,
2514 0x1005,
2515 0x1006,
2516 0x1007,
2517 0x1707,
2518 0x2007,
2519 0x2d07,
2520 0x4007,
2521 0x0000,
2522 0x0000,
2523 0x0000,
2524 0x0000,
2525 0x0000,
2526 0x0000,
2527 0x0000,
2528 0x0000,
2529 0x0000,
2530 0x0000,
2531 0x0000,
2532 0x0000,
2533 0x0000,
2534 0x0000,
2535 0x0200,
2536 0x0300,
2537 0x0400,
2538 0x0600,
2539 0x0800,
2540 0x0b00,
2541 0x1000,
2542 0x1001,
2543 0x1002,
2544 0x1003,
2545 0x1004,
2546 0x1005,
2547 0x1006,
2548 0x1007,
2549 0x1707,
2550 0x2007,
2551 0x2d07,
2552 0x4007,
2553 0x0000,
2554 0x0000,
2555 0x0000,
2556 0x0000,
2557 0x0000,
2558 0x0000,
2559 0x0000,
2560 0x0000,
2561 0x0000,
2562 0x0000,
2563 0x0000,
2564 0x0000,
2565 0x0000,
2566 0x0000,
2567 0x0000,
2568 0x0000,
2569 0x0000,
2570 0x0000,
2571 0x0000,
2572 0x0000,
2573 0x0000,
2574 0x0000,
2575 0x0000,
2576 0x0000,
2577 0x0000,
2578 0x0000,
2579 0x0000,
2580 0x0000,
2581 0x0000,
2582 0x0000,
2583 0x0000,
2584 0x0000,
2585 0x0000,
2586 0x0000,
2587 0x0000,
2588 0x0000,
2589 0x0000,
2590 0x4000,
2591 0x0000,
2592 0x0000,
2593 0x0000,
2594 0x0000,
2595 0x0000,
2596 0x0000,
2597 0x0000,
2598 0x0000,
2599 0x0000,
2600 0x0000,
2601 0x0000,
2602 0x0000,
2603 0x0000,
2604 0x0000,
2605 0x0000,
2606 0x0000,
2607 0x0000,
2608 0x0000,
2609 0x0000,
2610 0x0000,
2611};
2612
2613const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
2614 0x00080000,
2615 0x00080000,
2616 0x00080000,
2617 0x00080000,
2618 0x00080000,
2619 0x00080000,
2620 0x00080000,
2621 0x00080000,
2622 0x00080000,
2623 0x00080000,
2624 0x00080000,
2625 0x00080000,
2626 0x00080000,
2627 0x00080000,
2628 0x00080000,
2629 0x00080000,
2630 0x00080000,
2631 0x00080000,
2632 0x00080000,
2633 0x00080000,
2634 0x00080000,
2635 0x00080000,
2636 0x00080000,
2637 0x00080000,
2638 0x00080000,
2639 0x00080000,
2640 0x00080000,
2641 0x00080000,
2642 0x00080000,
2643 0x00080000,
2644 0x00080000,
2645 0x00080000,
2646 0x00080000,
2647 0x00080000,
2648 0x00080000,
2649 0x00080000,
2650 0x00080000,
2651 0x00080000,
2652 0x00080000,
2653 0x00080000,
2654 0x00080000,
2655 0x00080000,
2656 0x00080000,
2657 0x00080000,
2658 0x00080000,
2659 0x00080000,
2660 0x00080000,
2661 0x00080000,
2662 0x00080000,
2663 0x00080000,
2664 0x00080000,
2665 0x00080000,
2666 0x00080000,
2667 0x00080000,
2668 0x00080000,
2669 0x00080000,
2670 0x00080000,
2671 0x00080000,
2672 0x00080000,
2673 0x00080000,
2674 0x00080000,
2675 0x00080000,
2676 0x00080000,
2677 0x00080000,
2678 0x00080000,
2679 0x00080000,
2680 0x00080000,
2681 0x00080000,
2682 0x00080000,
2683 0x00080000,
2684 0x00080000,
2685 0x00080000,
2686 0x00080000,
2687 0x00080000,
2688 0x00080000,
2689 0x00080000,
2690 0x00080000,
2691 0x00080000,
2692 0x00080000,
2693 0x00080000,
2694 0x00080000,
2695 0x00080000,
2696 0x00080000,
2697 0x00080000,
2698 0x00080000,
2699 0x00080000,
2700 0x00080000,
2701 0x00080000,
2702 0x00080000,
2703 0x00080000,
2704 0x00080000,
2705 0x00080000,
2706 0x00080000,
2707 0x00080000,
2708 0x00080000,
2709 0x00080000,
2710 0x00080000,
2711 0x00080000,
2712 0x00080000,
2713 0x00080000,
2714 0x00080000,
2715 0x00080000,
2716 0x00080000,
2717 0x00080000,
2718 0x00080000,
2719 0x00080000,
2720 0x00080000,
2721 0x00080000,
2722 0x00080000,
2723 0x00080000,
2724 0x00080000,
2725 0x00080000,
2726 0x00080000,
2727 0x00080000,
2728 0x00080000,
2729 0x00080000,
2730 0x00080000,
2731 0x00080000,
2732 0x00080000,
2733 0x00080000,
2734 0x00080000,
2735 0x00080000,
2736 0x00080000,
2737 0x00080000,
2738 0x00080000,
2739 0x00080000,
2740 0x00080000,
2741 0x00080000,
2742 0x00080000,
2743 0x00080000,
2744 0x00080000,
2745 0x00080000,
2746 0x00080000,
2747 0x00080000,
2748 0x00080000,
2749 0x00080000,
2750 0x00080000,
2751 0x00080000,
2752 0x00080000,
2753 0x00080000,
2754 0x00080000,
2755 0x00080000,
2756 0x00080000,
2757 0x00080000,
2758 0x00080000,
2759 0x00080000,
2760 0x00080000,
2761 0x00080000,
2762 0x00080000,
2763 0x00080000,
2764 0x00080000,
2765 0x00080000,
2766 0x00080000,
2767 0x00080000,
2768 0x00080000,
2769 0x00080000,
2770 0x00080000,
2771 0x00080000,
2772 0x00080000,
2773 0x00080000,
2774};
2775
2776const struct phytbl_info dot11lcnphytbl_info_rev0[] = {
2777 {&dot11lcn_min_sig_sq_tbl_rev0,
2778 sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
2779 sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
2780 ,
2781 {&dot11lcn_noise_scale_tbl_rev0,
2782 sizeof(dot11lcn_noise_scale_tbl_rev0) /
2783 sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
2784 ,
2785 {&dot11lcn_fltr_ctrl_tbl_rev0,
2786 sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
2787 sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
2788 ,
2789 {&dot11lcn_ps_ctrl_tbl_rev0,
2790 sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
2791 sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
2792 ,
2793 {&dot11lcn_gain_idx_tbl_rev0,
2794 sizeof(dot11lcn_gain_idx_tbl_rev0) /
2795 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
2796 ,
2797 {&dot11lcn_aux_gain_idx_tbl_rev0,
2798 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
2799 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
2800 ,
2801 {&dot11lcn_sw_ctrl_tbl_rev0,
2802 sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
2803 sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
2804 ,
2805 {&dot11lcn_nf_table_rev0,
2806 sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
2807 0, 8}
2808 ,
2809 {&dot11lcn_gain_val_tbl_rev0,
2810 sizeof(dot11lcn_gain_val_tbl_rev0) /
2811 sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
2812 ,
2813 {&dot11lcn_gain_tbl_rev0,
2814 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
2815 0, 32}
2816 ,
2817 {&dot11lcn_spur_tbl_rev0,
2818 sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
2819 0, 8}
2820 ,
2821 {&dot11lcn_unsup_mcs_tbl_rev0,
2822 sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
2823 sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
2824 ,
2825 {&dot11lcn_iq_local_tbl_rev0,
2826 sizeof(dot11lcn_iq_local_tbl_rev0) /
2827 sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
2828 ,
2829 {&dot11lcn_papd_compdelta_tbl_rev0,
2830 sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
2831 sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
2832 ,
2833};
2834
2835const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = {
2836 &dot11lcn_sw_ctrl_tbl_4313_rev0,
2837 sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
2838 sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
2839};
2840
2841const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = {
2842 &dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
2843 sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
2844 sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
2845};
2846
2847const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
2848 &dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
2849 sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
2850 sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
2851};
2852
2853const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
2854 &dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
2855 sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
2856 sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
2857};
2858
2859const u32 dot11lcnphytbl_info_sz_rev0 =
2860 sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
2861
2862const struct lcnphy_tx_gain_tbl_entry
2863dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
2864 {3, 0, 31, 0, 72,}
2865 ,
2866 {3, 0, 31, 0, 70,}
2867 ,
2868 {3, 0, 31, 0, 68,}
2869 ,
2870 {3, 0, 30, 0, 67,}
2871 ,
2872 {3, 0, 29, 0, 68,}
2873 ,
2874 {3, 0, 28, 0, 68,}
2875 ,
2876 {3, 0, 27, 0, 69,}
2877 ,
2878 {3, 0, 26, 0, 70,}
2879 ,
2880 {3, 0, 25, 0, 70,}
2881 ,
2882 {3, 0, 24, 0, 71,}
2883 ,
2884 {3, 0, 23, 0, 72,}
2885 ,
2886 {3, 0, 23, 0, 70,}
2887 ,
2888 {3, 0, 22, 0, 71,}
2889 ,
2890 {3, 0, 21, 0, 72,}
2891 ,
2892 {3, 0, 21, 0, 70,}
2893 ,
2894 {3, 0, 21, 0, 68,}
2895 ,
2896 {3, 0, 21, 0, 66,}
2897 ,
2898 {3, 0, 21, 0, 64,}
2899 ,
2900 {3, 0, 21, 0, 63,}
2901 ,
2902 {3, 0, 20, 0, 64,}
2903 ,
2904 {3, 0, 19, 0, 65,}
2905 ,
2906 {3, 0, 19, 0, 64,}
2907 ,
2908 {3, 0, 18, 0, 65,}
2909 ,
2910 {3, 0, 18, 0, 64,}
2911 ,
2912 {3, 0, 17, 0, 65,}
2913 ,
2914 {3, 0, 17, 0, 64,}
2915 ,
2916 {3, 0, 16, 0, 65,}
2917 ,
2918 {3, 0, 16, 0, 64,}
2919 ,
2920 {3, 0, 16, 0, 62,}
2921 ,
2922 {3, 0, 16, 0, 60,}
2923 ,
2924 {3, 0, 16, 0, 58,}
2925 ,
2926 {3, 0, 15, 0, 61,}
2927 ,
2928 {3, 0, 15, 0, 59,}
2929 ,
2930 {3, 0, 14, 0, 61,}
2931 ,
2932 {3, 0, 14, 0, 60,}
2933 ,
2934 {3, 0, 14, 0, 58,}
2935 ,
2936 {3, 0, 13, 0, 60,}
2937 ,
2938 {3, 0, 13, 0, 59,}
2939 ,
2940 {3, 0, 12, 0, 62,}
2941 ,
2942 {3, 0, 12, 0, 60,}
2943 ,
2944 {3, 0, 12, 0, 58,}
2945 ,
2946 {3, 0, 11, 0, 62,}
2947 ,
2948 {3, 0, 11, 0, 60,}
2949 ,
2950 {3, 0, 11, 0, 59,}
2951 ,
2952 {3, 0, 11, 0, 57,}
2953 ,
2954 {3, 0, 10, 0, 61,}
2955 ,
2956 {3, 0, 10, 0, 59,}
2957 ,
2958 {3, 0, 10, 0, 57,}
2959 ,
2960 {3, 0, 9, 0, 62,}
2961 ,
2962 {3, 0, 9, 0, 60,}
2963 ,
2964 {3, 0, 9, 0, 58,}
2965 ,
2966 {3, 0, 9, 0, 57,}
2967 ,
2968 {3, 0, 8, 0, 62,}
2969 ,
2970 {3, 0, 8, 0, 60,}
2971 ,
2972 {3, 0, 8, 0, 58,}
2973 ,
2974 {3, 0, 8, 0, 57,}
2975 ,
2976 {3, 0, 8, 0, 55,}
2977 ,
2978 {3, 0, 7, 0, 61,}
2979 ,
2980 {3, 0, 7, 0, 60,}
2981 ,
2982 {3, 0, 7, 0, 58,}
2983 ,
2984 {3, 0, 7, 0, 56,}
2985 ,
2986 {3, 0, 7, 0, 55,}
2987 ,
2988 {3, 0, 6, 0, 62,}
2989 ,
2990 {3, 0, 6, 0, 60,}
2991 ,
2992 {3, 0, 6, 0, 58,}
2993 ,
2994 {3, 0, 6, 0, 57,}
2995 ,
2996 {3, 0, 6, 0, 55,}
2997 ,
2998 {3, 0, 6, 0, 54,}
2999 ,
3000 {3, 0, 6, 0, 52,}
3001 ,
3002 {3, 0, 5, 0, 61,}
3003 ,
3004 {3, 0, 5, 0, 59,}
3005 ,
3006 {3, 0, 5, 0, 57,}
3007 ,
3008 {3, 0, 5, 0, 56,}
3009 ,
3010 {3, 0, 5, 0, 54,}
3011 ,
3012 {3, 0, 5, 0, 53,}
3013 ,
3014 {3, 0, 5, 0, 51,}
3015 ,
3016 {3, 0, 4, 0, 62,}
3017 ,
3018 {3, 0, 4, 0, 60,}
3019 ,
3020 {3, 0, 4, 0, 58,}
3021 ,
3022 {3, 0, 4, 0, 57,}
3023 ,
3024 {3, 0, 4, 0, 55,}
3025 ,
3026 {3, 0, 4, 0, 54,}
3027 ,
3028 {3, 0, 4, 0, 52,}
3029 ,
3030 {3, 0, 4, 0, 51,}
3031 ,
3032 {3, 0, 4, 0, 49,}
3033 ,
3034 {3, 0, 4, 0, 48,}
3035 ,
3036 {3, 0, 4, 0, 46,}
3037 ,
3038 {3, 0, 3, 0, 60,}
3039 ,
3040 {3, 0, 3, 0, 58,}
3041 ,
3042 {3, 0, 3, 0, 57,}
3043 ,
3044 {3, 0, 3, 0, 55,}
3045 ,
3046 {3, 0, 3, 0, 54,}
3047 ,
3048 {3, 0, 3, 0, 52,}
3049 ,
3050 {3, 0, 3, 0, 51,}
3051 ,
3052 {3, 0, 3, 0, 49,}
3053 ,
3054 {3, 0, 3, 0, 48,}
3055 ,
3056 {3, 0, 3, 0, 46,}
3057 ,
3058 {3, 0, 3, 0, 45,}
3059 ,
3060 {3, 0, 3, 0, 44,}
3061 ,
3062 {3, 0, 3, 0, 43,}
3063 ,
3064 {3, 0, 3, 0, 41,}
3065 ,
3066 {3, 0, 2, 0, 61,}
3067 ,
3068 {3, 0, 2, 0, 59,}
3069 ,
3070 {3, 0, 2, 0, 57,}
3071 ,
3072 {3, 0, 2, 0, 56,}
3073 ,
3074 {3, 0, 2, 0, 54,}
3075 ,
3076 {3, 0, 2, 0, 53,}
3077 ,
3078 {3, 0, 2, 0, 51,}
3079 ,
3080 {3, 0, 2, 0, 50,}
3081 ,
3082 {3, 0, 2, 0, 48,}
3083 ,
3084 {3, 0, 2, 0, 47,}
3085 ,
3086 {3, 0, 2, 0, 46,}
3087 ,
3088 {3, 0, 2, 0, 44,}
3089 ,
3090 {3, 0, 2, 0, 43,}
3091 ,
3092 {3, 0, 2, 0, 42,}
3093 ,
3094 {3, 0, 2, 0, 41,}
3095 ,
3096 {3, 0, 2, 0, 39,}
3097 ,
3098 {3, 0, 2, 0, 38,}
3099 ,
3100 {3, 0, 2, 0, 37,}
3101 ,
3102 {3, 0, 2, 0, 36,}
3103 ,
3104 {3, 0, 2, 0, 35,}
3105 ,
3106 {3, 0, 2, 0, 34,}
3107 ,
3108 {3, 0, 2, 0, 33,}
3109 ,
3110 {3, 0, 2, 0, 32,}
3111 ,
3112 {3, 0, 1, 0, 63,}
3113 ,
3114 {3, 0, 1, 0, 61,}
3115 ,
3116 {3, 0, 1, 0, 59,}
3117 ,
3118 {3, 0, 1, 0, 57,}
3119 ,
3120};
3121
3122const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
3123 {7, 0, 31, 0, 72,}
3124 ,
3125 {7, 0, 31, 0, 70,}
3126 ,
3127 {7, 0, 31, 0, 68,}
3128 ,
3129 {7, 0, 30, 0, 67,}
3130 ,
3131 {7, 0, 29, 0, 68,}
3132 ,
3133 {7, 0, 28, 0, 68,}
3134 ,
3135 {7, 0, 27, 0, 69,}
3136 ,
3137 {7, 0, 26, 0, 70,}
3138 ,
3139 {7, 0, 25, 0, 70,}
3140 ,
3141 {7, 0, 24, 0, 71,}
3142 ,
3143 {7, 0, 23, 0, 72,}
3144 ,
3145 {7, 0, 23, 0, 70,}
3146 ,
3147 {7, 0, 22, 0, 71,}
3148 ,
3149 {7, 0, 21, 0, 72,}
3150 ,
3151 {7, 0, 21, 0, 70,}
3152 ,
3153 {7, 0, 21, 0, 68,}
3154 ,
3155 {7, 0, 21, 0, 66,}
3156 ,
3157 {7, 0, 21, 0, 64,}
3158 ,
3159 {7, 0, 21, 0, 63,}
3160 ,
3161 {7, 0, 20, 0, 64,}
3162 ,
3163 {7, 0, 19, 0, 65,}
3164 ,
3165 {7, 0, 19, 0, 64,}
3166 ,
3167 {7, 0, 18, 0, 65,}
3168 ,
3169 {7, 0, 18, 0, 64,}
3170 ,
3171 {7, 0, 17, 0, 65,}
3172 ,
3173 {7, 0, 17, 0, 64,}
3174 ,
3175 {7, 0, 16, 0, 65,}
3176 ,
3177 {7, 0, 16, 0, 64,}
3178 ,
3179 {7, 0, 16, 0, 62,}
3180 ,
3181 {7, 0, 16, 0, 60,}
3182 ,
3183 {7, 0, 16, 0, 58,}
3184 ,
3185 {7, 0, 15, 0, 61,}
3186 ,
3187 {7, 0, 15, 0, 59,}
3188 ,
3189 {7, 0, 14, 0, 61,}
3190 ,
3191 {7, 0, 14, 0, 60,}
3192 ,
3193 {7, 0, 14, 0, 58,}
3194 ,
3195 {7, 0, 13, 0, 60,}
3196 ,
3197 {7, 0, 13, 0, 59,}
3198 ,
3199 {7, 0, 12, 0, 62,}
3200 ,
3201 {7, 0, 12, 0, 60,}
3202 ,
3203 {7, 0, 12, 0, 58,}
3204 ,
3205 {7, 0, 11, 0, 62,}
3206 ,
3207 {7, 0, 11, 0, 60,}
3208 ,
3209 {7, 0, 11, 0, 59,}
3210 ,
3211 {7, 0, 11, 0, 57,}
3212 ,
3213 {7, 0, 10, 0, 61,}
3214 ,
3215 {7, 0, 10, 0, 59,}
3216 ,
3217 {7, 0, 10, 0, 57,}
3218 ,
3219 {7, 0, 9, 0, 62,}
3220 ,
3221 {7, 0, 9, 0, 60,}
3222 ,
3223 {7, 0, 9, 0, 58,}
3224 ,
3225 {7, 0, 9, 0, 57,}
3226 ,
3227 {7, 0, 8, 0, 62,}
3228 ,
3229 {7, 0, 8, 0, 60,}
3230 ,
3231 {7, 0, 8, 0, 58,}
3232 ,
3233 {7, 0, 8, 0, 57,}
3234 ,
3235 {7, 0, 8, 0, 55,}
3236 ,
3237 {7, 0, 7, 0, 61,}
3238 ,
3239 {7, 0, 7, 0, 60,}
3240 ,
3241 {7, 0, 7, 0, 58,}
3242 ,
3243 {7, 0, 7, 0, 56,}
3244 ,
3245 {7, 0, 7, 0, 55,}
3246 ,
3247 {7, 0, 6, 0, 62,}
3248 ,
3249 {7, 0, 6, 0, 60,}
3250 ,
3251 {7, 0, 6, 0, 58,}
3252 ,
3253 {7, 0, 6, 0, 57,}
3254 ,
3255 {7, 0, 6, 0, 55,}
3256 ,
3257 {7, 0, 6, 0, 54,}
3258 ,
3259 {7, 0, 6, 0, 52,}
3260 ,
3261 {7, 0, 5, 0, 61,}
3262 ,
3263 {7, 0, 5, 0, 59,}
3264 ,
3265 {7, 0, 5, 0, 57,}
3266 ,
3267 {7, 0, 5, 0, 56,}
3268 ,
3269 {7, 0, 5, 0, 54,}
3270 ,
3271 {7, 0, 5, 0, 53,}
3272 ,
3273 {7, 0, 5, 0, 51,}
3274 ,
3275 {7, 0, 4, 0, 62,}
3276 ,
3277 {7, 0, 4, 0, 60,}
3278 ,
3279 {7, 0, 4, 0, 58,}
3280 ,
3281 {7, 0, 4, 0, 57,}
3282 ,
3283 {7, 0, 4, 0, 55,}
3284 ,
3285 {7, 0, 4, 0, 54,}
3286 ,
3287 {7, 0, 4, 0, 52,}
3288 ,
3289 {7, 0, 4, 0, 51,}
3290 ,
3291 {7, 0, 4, 0, 49,}
3292 ,
3293 {7, 0, 4, 0, 48,}
3294 ,
3295 {7, 0, 4, 0, 46,}
3296 ,
3297 {7, 0, 3, 0, 60,}
3298 ,
3299 {7, 0, 3, 0, 58,}
3300 ,
3301 {7, 0, 3, 0, 57,}
3302 ,
3303 {7, 0, 3, 0, 55,}
3304 ,
3305 {7, 0, 3, 0, 54,}
3306 ,
3307 {7, 0, 3, 0, 52,}
3308 ,
3309 {7, 0, 3, 0, 51,}
3310 ,
3311 {7, 0, 3, 0, 49,}
3312 ,
3313 {7, 0, 3, 0, 48,}
3314 ,
3315 {7, 0, 3, 0, 46,}
3316 ,
3317 {7, 0, 3, 0, 45,}
3318 ,
3319 {7, 0, 3, 0, 44,}
3320 ,
3321 {7, 0, 3, 0, 43,}
3322 ,
3323 {7, 0, 3, 0, 41,}
3324 ,
3325 {7, 0, 2, 0, 61,}
3326 ,
3327 {7, 0, 2, 0, 59,}
3328 ,
3329 {7, 0, 2, 0, 57,}
3330 ,
3331 {7, 0, 2, 0, 56,}
3332 ,
3333 {7, 0, 2, 0, 54,}
3334 ,
3335 {7, 0, 2, 0, 53,}
3336 ,
3337 {7, 0, 2, 0, 51,}
3338 ,
3339 {7, 0, 2, 0, 50,}
3340 ,
3341 {7, 0, 2, 0, 48,}
3342 ,
3343 {7, 0, 2, 0, 47,}
3344 ,
3345 {7, 0, 2, 0, 46,}
3346 ,
3347 {7, 0, 2, 0, 44,}
3348 ,
3349 {7, 0, 2, 0, 43,}
3350 ,
3351 {7, 0, 2, 0, 42,}
3352 ,
3353 {7, 0, 2, 0, 41,}
3354 ,
3355 {7, 0, 2, 0, 39,}
3356 ,
3357 {7, 0, 2, 0, 38,}
3358 ,
3359 {7, 0, 2, 0, 37,}
3360 ,
3361 {7, 0, 2, 0, 36,}
3362 ,
3363 {7, 0, 2, 0, 35,}
3364 ,
3365 {7, 0, 2, 0, 34,}
3366 ,
3367 {7, 0, 2, 0, 33,}
3368 ,
3369 {7, 0, 2, 0, 32,}
3370 ,
3371 {7, 0, 1, 0, 63,}
3372 ,
3373 {7, 0, 1, 0, 61,}
3374 ,
3375 {7, 0, 1, 0, 59,}
3376 ,
3377 {7, 0, 1, 0, 57,}
3378 ,
3379};
3380
3381const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
3382 {255, 255, 0xf0, 0, 152,}
3383 ,
3384 {255, 255, 0xf0, 0, 147,}
3385 ,
3386 {255, 255, 0xf0, 0, 143,}
3387 ,
3388 {255, 255, 0xf0, 0, 139,}
3389 ,
3390 {255, 255, 0xf0, 0, 135,}
3391 ,
3392 {255, 255, 0xf0, 0, 131,}
3393 ,
3394 {255, 255, 0xf0, 0, 128,}
3395 ,
3396 {255, 255, 0xf0, 0, 124,}
3397 ,
3398 {255, 255, 0xf0, 0, 121,}
3399 ,
3400 {255, 255, 0xf0, 0, 117,}
3401 ,
3402 {255, 255, 0xf0, 0, 114,}
3403 ,
3404 {255, 255, 0xf0, 0, 111,}
3405 ,
3406 {255, 255, 0xf0, 0, 107,}
3407 ,
3408 {255, 255, 0xf0, 0, 104,}
3409 ,
3410 {255, 255, 0xf0, 0, 101,}
3411 ,
3412 {255, 255, 0xf0, 0, 99,}
3413 ,
3414 {255, 255, 0xf0, 0, 96,}
3415 ,
3416 {255, 255, 0xf0, 0, 93,}
3417 ,
3418 {255, 255, 0xf0, 0, 90,}
3419 ,
3420 {255, 255, 0xf0, 0, 88,}
3421 ,
3422 {255, 255, 0xf0, 0, 85,}
3423 ,
3424 {255, 255, 0xf0, 0, 83,}
3425 ,
3426 {255, 255, 0xf0, 0, 81,}
3427 ,
3428 {255, 255, 0xf0, 0, 78,}
3429 ,
3430 {255, 255, 0xf0, 0, 76,}
3431 ,
3432 {255, 255, 0xf0, 0, 74,}
3433 ,
3434 {255, 255, 0xf0, 0, 72,}
3435 ,
3436 {255, 255, 0xf0, 0, 70,}
3437 ,
3438 {255, 255, 0xf0, 0, 68,}
3439 ,
3440 {255, 255, 0xf0, 0, 66,}
3441 ,
3442 {255, 255, 0xf0, 0, 64,}
3443 ,
3444 {255, 248, 0xf0, 0, 64,}
3445 ,
3446 {255, 241, 0xf0, 0, 64,}
3447 ,
3448 {255, 251, 0xe0, 0, 64,}
3449 ,
3450 {255, 244, 0xe0, 0, 64,}
3451 ,
3452 {255, 254, 0xd0, 0, 64,}
3453 ,
3454 {255, 246, 0xd0, 0, 64,}
3455 ,
3456 {255, 239, 0xd0, 0, 64,}
3457 ,
3458 {255, 249, 0xc0, 0, 64,}
3459 ,
3460 {255, 242, 0xc0, 0, 64,}
3461 ,
3462 {255, 255, 0xb0, 0, 64,}
3463 ,
3464 {255, 248, 0xb0, 0, 64,}
3465 ,
3466 {255, 241, 0xb0, 0, 64,}
3467 ,
3468 {255, 254, 0xa0, 0, 64,}
3469 ,
3470 {255, 246, 0xa0, 0, 64,}
3471 ,
3472 {255, 239, 0xa0, 0, 64,}
3473 ,
3474 {255, 255, 0x90, 0, 64,}
3475 ,
3476 {255, 248, 0x90, 0, 64,}
3477 ,
3478 {255, 241, 0x90, 0, 64,}
3479 ,
3480 {255, 234, 0x90, 0, 64,}
3481 ,
3482 {255, 255, 0x80, 0, 64,}
3483 ,
3484 {255, 248, 0x80, 0, 64,}
3485 ,
3486 {255, 241, 0x80, 0, 64,}
3487 ,
3488 {255, 234, 0x80, 0, 64,}
3489 ,
3490 {255, 255, 0x70, 0, 64,}
3491 ,
3492 {255, 248, 0x70, 0, 64,}
3493 ,
3494 {255, 241, 0x70, 0, 64,}
3495 ,
3496 {255, 234, 0x70, 0, 64,}
3497 ,
3498 {255, 227, 0x70, 0, 64,}
3499 ,
3500 {255, 221, 0x70, 0, 64,}
3501 ,
3502 {255, 215, 0x70, 0, 64,}
3503 ,
3504 {255, 208, 0x70, 0, 64,}
3505 ,
3506 {255, 203, 0x70, 0, 64,}
3507 ,
3508 {255, 197, 0x70, 0, 64,}
3509 ,
3510 {255, 255, 0x60, 0, 64,}
3511 ,
3512 {255, 248, 0x60, 0, 64,}
3513 ,
3514 {255, 241, 0x60, 0, 64,}
3515 ,
3516 {255, 234, 0x60, 0, 64,}
3517 ,
3518 {255, 227, 0x60, 0, 64,}
3519 ,
3520 {255, 221, 0x60, 0, 64,}
3521 ,
3522 {255, 255, 0x50, 0, 64,}
3523 ,
3524 {255, 248, 0x50, 0, 64,}
3525 ,
3526 {255, 241, 0x50, 0, 64,}
3527 ,
3528 {255, 234, 0x50, 0, 64,}
3529 ,
3530 {255, 227, 0x50, 0, 64,}
3531 ,
3532 {255, 221, 0x50, 0, 64,}
3533 ,
3534 {255, 215, 0x50, 0, 64,}
3535 ,
3536 {255, 208, 0x50, 0, 64,}
3537 ,
3538 {255, 255, 0x40, 0, 64,}
3539 ,
3540 {255, 248, 0x40, 0, 64,}
3541 ,
3542 {255, 241, 0x40, 0, 64,}
3543 ,
3544 {255, 234, 0x40, 0, 64,}
3545 ,
3546 {255, 227, 0x40, 0, 64,}
3547 ,
3548 {255, 221, 0x40, 0, 64,}
3549 ,
3550 {255, 215, 0x40, 0, 64,}
3551 ,
3552 {255, 208, 0x40, 0, 64,}
3553 ,
3554 {255, 203, 0x40, 0, 64,}
3555 ,
3556 {255, 197, 0x40, 0, 64,}
3557 ,
3558 {255, 255, 0x30, 0, 64,}
3559 ,
3560 {255, 248, 0x30, 0, 64,}
3561 ,
3562 {255, 241, 0x30, 0, 64,}
3563 ,
3564 {255, 234, 0x30, 0, 64,}
3565 ,
3566 {255, 227, 0x30, 0, 64,}
3567 ,
3568 {255, 221, 0x30, 0, 64,}
3569 ,
3570 {255, 215, 0x30, 0, 64,}
3571 ,
3572 {255, 208, 0x30, 0, 64,}
3573 ,
3574 {255, 203, 0x30, 0, 64,}
3575 ,
3576 {255, 197, 0x30, 0, 64,}
3577 ,
3578 {255, 191, 0x30, 0, 64,}
3579 ,
3580 {255, 186, 0x30, 0, 64,}
3581 ,
3582 {255, 181, 0x30, 0, 64,}
3583 ,
3584 {255, 175, 0x30, 0, 64,}
3585 ,
3586 {255, 255, 0x20, 0, 64,}
3587 ,
3588 {255, 248, 0x20, 0, 64,}
3589 ,
3590 {255, 241, 0x20, 0, 64,}
3591 ,
3592 {255, 234, 0x20, 0, 64,}
3593 ,
3594 {255, 227, 0x20, 0, 64,}
3595 ,
3596 {255, 221, 0x20, 0, 64,}
3597 ,
3598 {255, 215, 0x20, 0, 64,}
3599 ,
3600 {255, 208, 0x20, 0, 64,}
3601 ,
3602 {255, 203, 0x20, 0, 64,}
3603 ,
3604 {255, 197, 0x20, 0, 64,}
3605 ,
3606 {255, 191, 0x20, 0, 64,}
3607 ,
3608 {255, 186, 0x20, 0, 64,}
3609 ,
3610 {255, 181, 0x20, 0, 64,}
3611 ,
3612 {255, 175, 0x20, 0, 64,}
3613 ,
3614 {255, 170, 0x20, 0, 64,}
3615 ,
3616 {255, 166, 0x20, 0, 64,}
3617 ,
3618 {255, 161, 0x20, 0, 64,}
3619 ,
3620 {255, 156, 0x20, 0, 64,}
3621 ,
3622 {255, 152, 0x20, 0, 64,}
3623 ,
3624 {255, 148, 0x20, 0, 64,}
3625 ,
3626 {255, 143, 0x20, 0, 64,}
3627 ,
3628 {255, 139, 0x20, 0, 64,}
3629 ,
3630 {255, 135, 0x20, 0, 64,}
3631 ,
3632 {255, 132, 0x20, 0, 64,}
3633 ,
3634 {255, 255, 0x10, 0, 64,}
3635 ,
3636 {255, 248, 0x10, 0, 64,}
3637 ,
3638};
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h
new file mode 100644
index 00000000000..5f75e16bf5a
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <types.h>
18#include "phy_int.h"
19
20extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
21extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
22extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
23extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
24extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
25extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
26extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
27
28extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
29extern const u32 dot11lcnphytbl_info_sz_rev0;
30
31extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
32extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
33
34extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
35extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
36
37extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
38
39extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
40
41struct lcnphy_tx_gain_tbl_entry {
42 unsigned char gm;
43 unsigned char pga;
44 unsigned char pad;
45 unsigned char dac;
46 unsigned char bb_mult;
47};
48
49extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
50
51extern const struct
52lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
53
54extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c
new file mode 100644
index 00000000000..7f741f4868a
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c
@@ -0,0 +1,10629 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <types.h>
18#include "phytbl_n.h"
19
20const u32 frame_struct_rev0[] = {
21 0x08004a04,
22 0x00100000,
23 0x01000a05,
24 0x00100020,
25 0x09804506,
26 0x00100030,
27 0x09804507,
28 0x00100030,
29 0x00000000,
30 0x00000000,
31 0x00000000,
32 0x00000000,
33 0x00000000,
34 0x00000000,
35 0x00000000,
36 0x00000000,
37 0x08004a0c,
38 0x00100004,
39 0x01000a0d,
40 0x00100024,
41 0x0980450e,
42 0x00100034,
43 0x0980450f,
44 0x00100034,
45 0x00000000,
46 0x00000000,
47 0x00000000,
48 0x00000000,
49 0x00000000,
50 0x00000000,
51 0x00000000,
52 0x00000000,
53 0x00000a04,
54 0x00100000,
55 0x11008a05,
56 0x00100020,
57 0x1980c506,
58 0x00100030,
59 0x21810506,
60 0x00100030,
61 0x21810506,
62 0x00100030,
63 0x01800504,
64 0x00100030,
65 0x11808505,
66 0x00100030,
67 0x29814507,
68 0x01100030,
69 0x00000a04,
70 0x00100000,
71 0x11008a05,
72 0x00100020,
73 0x21810506,
74 0x00100030,
75 0x21810506,
76 0x00100030,
77 0x29814507,
78 0x01100030,
79 0x00000000,
80 0x00000000,
81 0x00000000,
82 0x00000000,
83 0x00000000,
84 0x00000000,
85 0x00000a0c,
86 0x00100008,
87 0x11008a0d,
88 0x00100028,
89 0x1980c50e,
90 0x00100038,
91 0x2181050e,
92 0x00100038,
93 0x2181050e,
94 0x00100038,
95 0x0180050c,
96 0x00100038,
97 0x1180850d,
98 0x00100038,
99 0x2981450f,
100 0x01100038,
101 0x00000a0c,
102 0x00100008,
103 0x11008a0d,
104 0x00100028,
105 0x2181050e,
106 0x00100038,
107 0x2181050e,
108 0x00100038,
109 0x2981450f,
110 0x01100038,
111 0x00000000,
112 0x00000000,
113 0x00000000,
114 0x00000000,
115 0x00000000,
116 0x00000000,
117 0x08004a04,
118 0x00100000,
119 0x01000a05,
120 0x00100020,
121 0x1980c506,
122 0x00100030,
123 0x1980c506,
124 0x00100030,
125 0x11808504,
126 0x00100030,
127 0x3981ca05,
128 0x00100030,
129 0x29814507,
130 0x01100030,
131 0x00000000,
132 0x00000000,
133 0x10008a04,
134 0x00100000,
135 0x3981ca05,
136 0x00100030,
137 0x1980c506,
138 0x00100030,
139 0x29814507,
140 0x01100030,
141 0x00000000,
142 0x00000000,
143 0x00000000,
144 0x00000000,
145 0x00000000,
146 0x00000000,
147 0x00000000,
148 0x00000000,
149 0x08004a0c,
150 0x00100008,
151 0x01000a0d,
152 0x00100028,
153 0x1980c50e,
154 0x00100038,
155 0x1980c50e,
156 0x00100038,
157 0x1180850c,
158 0x00100038,
159 0x3981ca0d,
160 0x00100038,
161 0x2981450f,
162 0x01100038,
163 0x00000000,
164 0x00000000,
165 0x10008a0c,
166 0x00100008,
167 0x3981ca0d,
168 0x00100038,
169 0x1980c50e,
170 0x00100038,
171 0x2981450f,
172 0x01100038,
173 0x00000000,
174 0x00000000,
175 0x00000000,
176 0x00000000,
177 0x00000000,
178 0x00000000,
179 0x00000000,
180 0x00000000,
181 0x40021404,
182 0x00100000,
183 0x02001405,
184 0x00100040,
185 0x0b004a06,
186 0x01900060,
187 0x13008a06,
188 0x01900060,
189 0x13008a06,
190 0x01900060,
191 0x43020a04,
192 0x00100060,
193 0x1b00ca05,
194 0x00100060,
195 0x23010a07,
196 0x01500060,
197 0x40021404,
198 0x00100000,
199 0x1a00d405,
200 0x00100040,
201 0x13008a06,
202 0x01900060,
203 0x13008a06,
204 0x01900060,
205 0x23010a07,
206 0x01500060,
207 0x00000000,
208 0x00000000,
209 0x00000000,
210 0x00000000,
211 0x00000000,
212 0x00000000,
213 0x4002140c,
214 0x00100010,
215 0x0200140d,
216 0x00100050,
217 0x0b004a0e,
218 0x01900070,
219 0x13008a0e,
220 0x01900070,
221 0x13008a0e,
222 0x01900070,
223 0x43020a0c,
224 0x00100070,
225 0x1b00ca0d,
226 0x00100070,
227 0x23010a0f,
228 0x01500070,
229 0x4002140c,
230 0x00100010,
231 0x1a00d40d,
232 0x00100050,
233 0x13008a0e,
234 0x01900070,
235 0x13008a0e,
236 0x01900070,
237 0x23010a0f,
238 0x01500070,
239 0x00000000,
240 0x00000000,
241 0x00000000,
242 0x00000000,
243 0x00000000,
244 0x00000000,
245 0x50029404,
246 0x00100000,
247 0x32019405,
248 0x00100040,
249 0x0b004a06,
250 0x01900060,
251 0x0b004a06,
252 0x01900060,
253 0x5b02ca04,
254 0x00100060,
255 0x3b01d405,
256 0x00100060,
257 0x23010a07,
258 0x01500060,
259 0x00000000,
260 0x00000000,
261 0x5802d404,
262 0x00100000,
263 0x3b01d405,
264 0x00100060,
265 0x0b004a06,
266 0x01900060,
267 0x23010a07,
268 0x01500060,
269 0x00000000,
270 0x00000000,
271 0x00000000,
272 0x00000000,
273 0x00000000,
274 0x00000000,
275 0x00000000,
276 0x00000000,
277 0x5002940c,
278 0x00100010,
279 0x3201940d,
280 0x00100050,
281 0x0b004a0e,
282 0x01900070,
283 0x0b004a0e,
284 0x01900070,
285 0x5b02ca0c,
286 0x00100070,
287 0x3b01d40d,
288 0x00100070,
289 0x23010a0f,
290 0x01500070,
291 0x00000000,
292 0x00000000,
293 0x5802d40c,
294 0x00100010,
295 0x3b01d40d,
296 0x00100070,
297 0x0b004a0e,
298 0x01900070,
299 0x23010a0f,
300 0x01500070,
301 0x00000000,
302 0x00000000,
303 0x00000000,
304 0x00000000,
305 0x00000000,
306 0x00000000,
307 0x00000000,
308 0x00000000,
309 0x40021404,
310 0x000f4800,
311 0x62031405,
312 0x00100040,
313 0x53028a06,
314 0x01900060,
315 0x53028a07,
316 0x01900060,
317 0x00000000,
318 0x00000000,
319 0x00000000,
320 0x00000000,
321 0x00000000,
322 0x00000000,
323 0x00000000,
324 0x00000000,
325 0x4002140c,
326 0x000f4808,
327 0x6203140d,
328 0x00100048,
329 0x53028a0e,
330 0x01900068,
331 0x53028a0f,
332 0x01900068,
333 0x00000000,
334 0x00000000,
335 0x00000000,
336 0x00000000,
337 0x00000000,
338 0x00000000,
339 0x00000000,
340 0x00000000,
341 0x00000a0c,
342 0x00100004,
343 0x11008a0d,
344 0x00100024,
345 0x1980c50e,
346 0x00100034,
347 0x2181050e,
348 0x00100034,
349 0x2181050e,
350 0x00100034,
351 0x0180050c,
352 0x00100038,
353 0x1180850d,
354 0x00100038,
355 0x1181850d,
356 0x00100038,
357 0x2981450f,
358 0x01100038,
359 0x00000000,
360 0x00000000,
361 0x00000000,
362 0x00000000,
363 0x00000000,
364 0x00000000,
365 0x00000000,
366 0x00000000,
367 0x00000000,
368 0x00000000,
369 0x00000000,
370 0x00000000,
371 0x00000000,
372 0x00000000,
373 0x00000a0c,
374 0x00100008,
375 0x11008a0d,
376 0x00100028,
377 0x2181050e,
378 0x00100038,
379 0x2181050e,
380 0x00100038,
381 0x1181850d,
382 0x00100038,
383 0x2981450f,
384 0x01100038,
385 0x00000000,
386 0x00000000,
387 0x00000000,
388 0x00000000,
389 0x00000000,
390 0x00000000,
391 0x00000000,
392 0x00000000,
393 0x00000000,
394 0x00000000,
395 0x00000000,
396 0x00000000,
397 0x00000000,
398 0x00000000,
399 0x00000000,
400 0x00000000,
401 0x00000000,
402 0x00000000,
403 0x00000000,
404 0x00000000,
405 0x08004a04,
406 0x00100000,
407 0x01000a05,
408 0x00100020,
409 0x0180c506,
410 0x00100030,
411 0x0180c506,
412 0x00100030,
413 0x2180c50c,
414 0x00100030,
415 0x49820a0d,
416 0x0016a130,
417 0x41824a0d,
418 0x0016a130,
419 0x2981450f,
420 0x01100030,
421 0x00000000,
422 0x00000000,
423 0x00000000,
424 0x00000000,
425 0x00000000,
426 0x00000000,
427 0x00000000,
428 0x00000000,
429 0x00000000,
430 0x00000000,
431 0x00000000,
432 0x00000000,
433 0x00000000,
434 0x00000000,
435 0x00000000,
436 0x00000000,
437 0x2000ca0c,
438 0x00100000,
439 0x49820a0d,
440 0x0016a130,
441 0x1980c50e,
442 0x00100030,
443 0x41824a0d,
444 0x0016a130,
445 0x2981450f,
446 0x01100030,
447 0x00000000,
448 0x00000000,
449 0x00000000,
450 0x00000000,
451 0x00000000,
452 0x00000000,
453 0x00000000,
454 0x00000000,
455 0x00000000,
456 0x00000000,
457 0x00000000,
458 0x00000000,
459 0x00000000,
460 0x00000000,
461 0x00000000,
462 0x00000000,
463 0x00000000,
464 0x00000000,
465 0x00000000,
466 0x00000000,
467 0x00000000,
468 0x00000000,
469 0x4002140c,
470 0x00100008,
471 0x0200140d,
472 0x00100048,
473 0x0b004a0e,
474 0x01900068,
475 0x13008a0e,
476 0x01900068,
477 0x13008a0e,
478 0x01900068,
479 0x43020a0c,
480 0x00100070,
481 0x1b00ca0d,
482 0x00100070,
483 0x1b014a0d,
484 0x00100070,
485 0x23010a0f,
486 0x01500070,
487 0x00000000,
488 0x00000000,
489 0x00000000,
490 0x00000000,
491 0x00000000,
492 0x00000000,
493 0x00000000,
494 0x00000000,
495 0x00000000,
496 0x00000000,
497 0x00000000,
498 0x00000000,
499 0x00000000,
500 0x00000000,
501 0x4002140c,
502 0x00100010,
503 0x1a00d40d,
504 0x00100050,
505 0x13008a0e,
506 0x01900070,
507 0x13008a0e,
508 0x01900070,
509 0x1b014a0d,
510 0x00100070,
511 0x23010a0f,
512 0x01500070,
513 0x00000000,
514 0x00000000,
515 0x00000000,
516 0x00000000,
517 0x00000000,
518 0x00000000,
519 0x00000000,
520 0x00000000,
521 0x00000000,
522 0x00000000,
523 0x00000000,
524 0x00000000,
525 0x00000000,
526 0x00000000,
527 0x00000000,
528 0x00000000,
529 0x00000000,
530 0x00000000,
531 0x00000000,
532 0x00000000,
533 0x50029404,
534 0x00100000,
535 0x32019405,
536 0x00100040,
537 0x03004a06,
538 0x01900060,
539 0x03004a06,
540 0x01900060,
541 0x6b030a0c,
542 0x00100060,
543 0x4b02140d,
544 0x0016a160,
545 0x4302540d,
546 0x0016a160,
547 0x23010a0f,
548 0x01500060,
549 0x00000000,
550 0x00000000,
551 0x00000000,
552 0x00000000,
553 0x00000000,
554 0x00000000,
555 0x00000000,
556 0x00000000,
557 0x00000000,
558 0x00000000,
559 0x00000000,
560 0x00000000,
561 0x00000000,
562 0x00000000,
563 0x00000000,
564 0x00000000,
565 0x6b03140c,
566 0x00100060,
567 0x4b02140d,
568 0x0016a160,
569 0x0b004a0e,
570 0x01900060,
571 0x4302540d,
572 0x0016a160,
573 0x23010a0f,
574 0x01500060,
575 0x00000000,
576 0x00000000,
577 0x00000000,
578 0x00000000,
579 0x00000000,
580 0x00000000,
581 0x00000000,
582 0x00000000,
583 0x00000000,
584 0x00000000,
585 0x00000000,
586 0x00000000,
587 0x00000000,
588 0x00000000,
589 0x00000000,
590 0x00000000,
591 0x00000000,
592 0x00000000,
593 0x00000000,
594 0x00000000,
595 0x00000000,
596 0x00000000,
597 0x40021404,
598 0x00100000,
599 0x1a00d405,
600 0x00100040,
601 0x53028a06,
602 0x01900060,
603 0x5b02ca06,
604 0x01900060,
605 0x5b02ca06,
606 0x01900060,
607 0x43020a04,
608 0x00100060,
609 0x1b00ca05,
610 0x00100060,
611 0x53028a07,
612 0x0190c060,
613 0x00000000,
614 0x00000000,
615 0x00000000,
616 0x00000000,
617 0x00000000,
618 0x00000000,
619 0x00000000,
620 0x00000000,
621 0x00000000,
622 0x00000000,
623 0x00000000,
624 0x00000000,
625 0x00000000,
626 0x00000000,
627 0x00000000,
628 0x00000000,
629 0x4002140c,
630 0x00100010,
631 0x1a00d40d,
632 0x00100050,
633 0x53028a0e,
634 0x01900070,
635 0x5b02ca0e,
636 0x01900070,
637 0x5b02ca0e,
638 0x01900070,
639 0x43020a0c,
640 0x00100070,
641 0x1b00ca0d,
642 0x00100070,
643 0x53028a0f,
644 0x0190c070,
645 0x00000000,
646 0x00000000,
647 0x00000000,
648 0x00000000,
649 0x00000000,
650 0x00000000,
651 0x00000000,
652 0x00000000,
653 0x00000000,
654 0x00000000,
655 0x00000000,
656 0x00000000,
657 0x00000000,
658 0x00000000,
659 0x00000000,
660 0x00000000,
661 0x40021404,
662 0x00100000,
663 0x1a00d405,
664 0x00100040,
665 0x5b02ca06,
666 0x01900060,
667 0x5b02ca06,
668 0x01900060,
669 0x53028a07,
670 0x0190c060,
671 0x00000000,
672 0x00000000,
673 0x00000000,
674 0x00000000,
675 0x00000000,
676 0x00000000,
677 0x00000000,
678 0x00000000,
679 0x00000000,
680 0x00000000,
681 0x00000000,
682 0x00000000,
683 0x00000000,
684 0x00000000,
685 0x00000000,
686 0x00000000,
687 0x00000000,
688 0x00000000,
689 0x00000000,
690 0x00000000,
691 0x00000000,
692 0x00000000,
693 0x4002140c,
694 0x00100010,
695 0x1a00d40d,
696 0x00100050,
697 0x5b02ca0e,
698 0x01900070,
699 0x5b02ca0e,
700 0x01900070,
701 0x53028a0f,
702 0x0190c070,
703 0x00000000,
704 0x00000000,
705 0x00000000,
706 0x00000000,
707 0x00000000,
708 0x00000000,
709 0x00000000,
710 0x00000000,
711 0x00000000,
712 0x00000000,
713 0x00000000,
714 0x00000000,
715 0x00000000,
716 0x00000000,
717 0x00000000,
718 0x00000000,
719 0x00000000,
720 0x00000000,
721 0x00000000,
722 0x00000000,
723 0x00000000,
724 0x00000000,
725 0x00000000,
726 0x00000000,
727 0x00000000,
728 0x00000000,
729 0x00000000,
730 0x00000000,
731 0x00000000,
732 0x00000000,
733 0x00000000,
734 0x00000000,
735 0x00000000,
736 0x00000000,
737 0x00000000,
738 0x00000000,
739 0x00000000,
740 0x00000000,
741 0x00000000,
742 0x00000000,
743 0x00000000,
744 0x00000000,
745 0x00000000,
746 0x00000000,
747 0x00000000,
748 0x00000000,
749 0x00000000,
750 0x00000000,
751 0x00000000,
752 0x00000000,
753 0x00000000,
754 0x00000000,
755 0x00000000,
756 0x00000000,
757 0x00000000,
758 0x00000000,
759 0x00000000,
760 0x00000000,
761 0x00000000,
762 0x00000000,
763 0x00000000,
764 0x00000000,
765 0x00000000,
766 0x00000000,
767 0x00000000,
768 0x00000000,
769 0x00000000,
770 0x00000000,
771 0x00000000,
772 0x00000000,
773 0x00000000,
774 0x00000000,
775 0x00000000,
776 0x00000000,
777 0x00000000,
778 0x00000000,
779 0x00000000,
780 0x00000000,
781 0x00000000,
782 0x00000000,
783 0x00000000,
784 0x00000000,
785 0x00000000,
786 0x00000000,
787 0x00000000,
788 0x00000000,
789 0x00000000,
790 0x00000000,
791 0x00000000,
792 0x00000000,
793 0x00000000,
794 0x00000000,
795 0x00000000,
796 0x00000000,
797 0x00000000,
798 0x00000000,
799 0x00000000,
800 0x00000000,
801 0x00000000,
802 0x00000000,
803 0x00000000,
804 0x00000000,
805 0x00000000,
806 0x00000000,
807 0x00000000,
808 0x00000000,
809 0x00000000,
810 0x00000000,
811 0x00000000,
812 0x00000000,
813 0x00000000,
814 0x00000000,
815 0x00000000,
816 0x00000000,
817 0x00000000,
818 0x00000000,
819 0x00000000,
820 0x00000000,
821 0x00000000,
822 0x00000000,
823 0x00000000,
824 0x00000000,
825 0x00000000,
826 0x00000000,
827 0x00000000,
828 0x00000000,
829 0x00000000,
830 0x00000000,
831 0x00000000,
832 0x00000000,
833 0x00000000,
834 0x00000000,
835 0x00000000,
836 0x00000000,
837 0x00000000,
838 0x00000000,
839 0x00000000,
840 0x00000000,
841 0x00000000,
842 0x00000000,
843 0x00000000,
844 0x00000000,
845 0x00000000,
846 0x00000000,
847 0x00000000,
848 0x00000000,
849 0x00000000,
850 0x00000000,
851 0x00000000,
852 0x00000000,
853};
854
855const u8 frame_lut_rev0[] = {
856 0x02,
857 0x04,
858 0x14,
859 0x14,
860 0x03,
861 0x05,
862 0x16,
863 0x16,
864 0x0a,
865 0x0c,
866 0x1c,
867 0x1c,
868 0x0b,
869 0x0d,
870 0x1e,
871 0x1e,
872 0x06,
873 0x08,
874 0x18,
875 0x18,
876 0x07,
877 0x09,
878 0x1a,
879 0x1a,
880 0x0e,
881 0x10,
882 0x20,
883 0x28,
884 0x0f,
885 0x11,
886 0x22,
887 0x2a,
888};
889
890const u32 tmap_tbl_rev0[] = {
891 0x8a88aa80,
892 0x8aaaaa8a,
893 0x8a8a8aa8,
894 0x00000888,
895 0x88000000,
896 0x8a8a88aa,
897 0x8aa88888,
898 0x8888a8a8,
899 0xf1111110,
900 0x11111111,
901 0x11f11111,
902 0x00000111,
903 0x11000000,
904 0x1111f111,
905 0x11111111,
906 0x111111f1,
907 0x8a88aa80,
908 0x8aaaaa8a,
909 0x8a8a8aa8,
910 0x000aa888,
911 0x88880000,
912 0x8a8a88aa,
913 0x8aa88888,
914 0x8888a8a8,
915 0xa1111110,
916 0x11111111,
917 0x11c11111,
918 0x00000111,
919 0x11000000,
920 0x1111a111,
921 0x11111111,
922 0x111111a1,
923 0xa2222220,
924 0x22222222,
925 0x22c22222,
926 0x00000222,
927 0x22000000,
928 0x2222a222,
929 0x22222222,
930 0x222222a2,
931 0xf1111110,
932 0x11111111,
933 0x11f11111,
934 0x00011111,
935 0x11110000,
936 0x1111f111,
937 0x11111111,
938 0x111111f1,
939 0xa8aa88a0,
940 0xa88888a8,
941 0xa8a8a88a,
942 0x00088aaa,
943 0xaaaa0000,
944 0xa8a8aa88,
945 0xa88aaaaa,
946 0xaaaa8a8a,
947 0xaaa8aaa0,
948 0x8aaa8aaa,
949 0xaa8a8a8a,
950 0x000aaa88,
951 0x8aaa0000,
952 0xaaa8a888,
953 0x8aa88a8a,
954 0x8a88a888,
955 0x08080a00,
956 0x0a08080a,
957 0x080a0a08,
958 0x00080808,
959 0x080a0000,
960 0x080a0808,
961 0x080a0808,
962 0x0a0a0a08,
963 0xa0a0a0a0,
964 0x80a0a080,
965 0x8080a0a0,
966 0x00008080,
967 0x80a00000,
968 0x80a080a0,
969 0xa080a0a0,
970 0x8080a0a0,
971 0x00000000,
972 0x00000000,
973 0x00000000,
974 0x00000000,
975 0x00000000,
976 0x00000000,
977 0x00000000,
978 0x00000000,
979 0x00000000,
980 0x00000000,
981 0x00000000,
982 0x00000000,
983 0x00000000,
984 0x00000000,
985 0x00000000,
986 0x00000000,
987 0x00000000,
988 0x00000000,
989 0x00000000,
990 0x00000000,
991 0x00000000,
992 0x00000000,
993 0x00000000,
994 0x00000000,
995 0x00000000,
996 0x00000000,
997 0x00000000,
998 0x00000000,
999 0x00000000,
1000 0x00000000,
1001 0x00000000,
1002 0x00000000,
1003 0x00000000,
1004 0x00000000,
1005 0x00000000,
1006 0x00000000,
1007 0x00000000,
1008 0x00000000,
1009 0x00000000,
1010 0x00000000,
1011 0x00000000,
1012 0x00000000,
1013 0x00000000,
1014 0x00000000,
1015 0x00000000,
1016 0x00000000,
1017 0x00000000,
1018 0x00000000,
1019 0x99999000,
1020 0x9b9b99bb,
1021 0x9bb99999,
1022 0x9999b9b9,
1023 0x9b99bb90,
1024 0x9bbbbb9b,
1025 0x9b9b9bb9,
1026 0x00000999,
1027 0x88000000,
1028 0x8a8a88aa,
1029 0x8aa88888,
1030 0x8888a8a8,
1031 0x8a88aa80,
1032 0x8aaaaa8a,
1033 0x8a8a8aa8,
1034 0x00aaa888,
1035 0x22000000,
1036 0x2222b222,
1037 0x22222222,
1038 0x222222b2,
1039 0xb2222220,
1040 0x22222222,
1041 0x22d22222,
1042 0x00000222,
1043 0x11000000,
1044 0x1111a111,
1045 0x11111111,
1046 0x111111a1,
1047 0xa1111110,
1048 0x11111111,
1049 0x11c11111,
1050 0x00000111,
1051 0x33000000,
1052 0x3333b333,
1053 0x33333333,
1054 0x333333b3,
1055 0xb3333330,
1056 0x33333333,
1057 0x33d33333,
1058 0x00000333,
1059 0x22000000,
1060 0x2222a222,
1061 0x22222222,
1062 0x222222a2,
1063 0xa2222220,
1064 0x22222222,
1065 0x22c22222,
1066 0x00000222,
1067 0x99b99b00,
1068 0x9b9b99bb,
1069 0x9bb99999,
1070 0x9999b9b9,
1071 0x9b99bb99,
1072 0x9bbbbb9b,
1073 0x9b9b9bb9,
1074 0x00000999,
1075 0x88000000,
1076 0x8a8a88aa,
1077 0x8aa88888,
1078 0x8888a8a8,
1079 0x8a88aa88,
1080 0x8aaaaa8a,
1081 0x8a8a8aa8,
1082 0x08aaa888,
1083 0x22222200,
1084 0x2222f222,
1085 0x22222222,
1086 0x222222f2,
1087 0x22222222,
1088 0x22222222,
1089 0x22f22222,
1090 0x00000222,
1091 0x11000000,
1092 0x1111f111,
1093 0x11111111,
1094 0x11111111,
1095 0xf1111111,
1096 0x11111111,
1097 0x11f11111,
1098 0x01111111,
1099 0xbb9bb900,
1100 0xb9b9bb99,
1101 0xb99bbbbb,
1102 0xbbbb9b9b,
1103 0xb9bb99bb,
1104 0xb99999b9,
1105 0xb9b9b99b,
1106 0x00000bbb,
1107 0xaa000000,
1108 0xa8a8aa88,
1109 0xa88aaaaa,
1110 0xaaaa8a8a,
1111 0xa8aa88aa,
1112 0xa88888a8,
1113 0xa8a8a88a,
1114 0x0a888aaa,
1115 0xaa000000,
1116 0xa8a8aa88,
1117 0xa88aaaaa,
1118 0xaaaa8a8a,
1119 0xa8aa88a0,
1120 0xa88888a8,
1121 0xa8a8a88a,
1122 0x00000aaa,
1123 0x88000000,
1124 0x8a8a88aa,
1125 0x8aa88888,
1126 0x8888a8a8,
1127 0x8a88aa80,
1128 0x8aaaaa8a,
1129 0x8a8a8aa8,
1130 0x00000888,
1131 0xbbbbbb00,
1132 0x999bbbbb,
1133 0x9bb99b9b,
1134 0xb9b9b9bb,
1135 0xb9b99bbb,
1136 0xb9b9b9bb,
1137 0xb9bb9b99,
1138 0x00000999,
1139 0x8a000000,
1140 0xaa88a888,
1141 0xa88888aa,
1142 0xa88a8a88,
1143 0xa88aa88a,
1144 0x88a8aaaa,
1145 0xa8aa8aaa,
1146 0x0888a88a,
1147 0x0b0b0b00,
1148 0x090b0b0b,
1149 0x0b090b0b,
1150 0x0909090b,
1151 0x09090b0b,
1152 0x09090b0b,
1153 0x09090b09,
1154 0x00000909,
1155 0x0a000000,
1156 0x0a080808,
1157 0x080a080a,
1158 0x080a0a08,
1159 0x080a080a,
1160 0x0808080a,
1161 0x0a0a0a08,
1162 0x0808080a,
1163 0xb0b0b000,
1164 0x9090b0b0,
1165 0x90b09090,
1166 0xb0b0b090,
1167 0xb0b090b0,
1168 0x90b0b0b0,
1169 0xb0b09090,
1170 0x00000090,
1171 0x80000000,
1172 0xa080a080,
1173 0xa08080a0,
1174 0xa0808080,
1175 0xa080a080,
1176 0x80a0a0a0,
1177 0xa0a080a0,
1178 0x00a0a0a0,
1179 0x22000000,
1180 0x2222f222,
1181 0x22222222,
1182 0x222222f2,
1183 0xf2222220,
1184 0x22222222,
1185 0x22f22222,
1186 0x00000222,
1187 0x11000000,
1188 0x1111f111,
1189 0x11111111,
1190 0x111111f1,
1191 0xf1111110,
1192 0x11111111,
1193 0x11f11111,
1194 0x00000111,
1195 0x33000000,
1196 0x3333f333,
1197 0x33333333,
1198 0x333333f3,
1199 0xf3333330,
1200 0x33333333,
1201 0x33f33333,
1202 0x00000333,
1203 0x22000000,
1204 0x2222f222,
1205 0x22222222,
1206 0x222222f2,
1207 0xf2222220,
1208 0x22222222,
1209 0x22f22222,
1210 0x00000222,
1211 0x99000000,
1212 0x9b9b99bb,
1213 0x9bb99999,
1214 0x9999b9b9,
1215 0x9b99bb90,
1216 0x9bbbbb9b,
1217 0x9b9b9bb9,
1218 0x00000999,
1219 0x88000000,
1220 0x8a8a88aa,
1221 0x8aa88888,
1222 0x8888a8a8,
1223 0x8a88aa80,
1224 0x8aaaaa8a,
1225 0x8a8a8aa8,
1226 0x00000888,
1227 0x88888000,
1228 0x8a8a88aa,
1229 0x8aa88888,
1230 0x8888a8a8,
1231 0x8a88aa80,
1232 0x8aaaaa8a,
1233 0x8a8a8aa8,
1234 0x00000888,
1235 0x88000000,
1236 0x8a8a88aa,
1237 0x8aa88888,
1238 0x8888a8a8,
1239 0x8a88aa80,
1240 0x8aaaaa8a,
1241 0x8a8a8aa8,
1242 0x00aaa888,
1243 0x88a88a00,
1244 0x8a8a88aa,
1245 0x8aa88888,
1246 0x8888a8a8,
1247 0x8a88aa88,
1248 0x8aaaaa8a,
1249 0x8a8a8aa8,
1250 0x00000888,
1251 0x88000000,
1252 0x8a8a88aa,
1253 0x8aa88888,
1254 0x8888a8a8,
1255 0x8a88aa88,
1256 0x8aaaaa8a,
1257 0x8a8a8aa8,
1258 0x08aaa888,
1259 0x11000000,
1260 0x1111a111,
1261 0x11111111,
1262 0x111111a1,
1263 0xa1111110,
1264 0x11111111,
1265 0x11c11111,
1266 0x00000111,
1267 0x11000000,
1268 0x1111a111,
1269 0x11111111,
1270 0x111111a1,
1271 0xa1111110,
1272 0x11111111,
1273 0x11c11111,
1274 0x00000111,
1275 0x88000000,
1276 0x8a8a88aa,
1277 0x8aa88888,
1278 0x8888a8a8,
1279 0x8a88aa80,
1280 0x8aaaaa8a,
1281 0x8a8a8aa8,
1282 0x00000888,
1283 0x88000000,
1284 0x8a8a88aa,
1285 0x8aa88888,
1286 0x8888a8a8,
1287 0x8a88aa80,
1288 0x8aaaaa8a,
1289 0x8a8a8aa8,
1290 0x00000888,
1291 0x00000000,
1292 0x00000000,
1293 0x00000000,
1294 0x00000000,
1295 0x00000000,
1296 0x00000000,
1297 0x00000000,
1298 0x00000000,
1299 0x00000000,
1300 0x00000000,
1301 0x00000000,
1302 0x00000000,
1303 0x00000000,
1304 0x00000000,
1305 0x00000000,
1306 0x00000000,
1307 0x00000000,
1308 0x00000000,
1309 0x00000000,
1310 0x00000000,
1311 0x00000000,
1312 0x00000000,
1313 0x00000000,
1314 0x00000000,
1315 0x00000000,
1316 0x00000000,
1317 0x00000000,
1318 0x00000000,
1319 0x00000000,
1320 0x00000000,
1321 0x00000000,
1322 0x00000000,
1323 0x00000000,
1324 0x00000000,
1325 0x00000000,
1326 0x00000000,
1327 0x00000000,
1328 0x00000000,
1329 0x00000000,
1330 0x00000000,
1331 0x00000000,
1332 0x00000000,
1333 0x00000000,
1334 0x00000000,
1335 0x00000000,
1336 0x00000000,
1337 0x00000000,
1338 0x00000000,
1339};
1340
1341const u32 tdtrn_tbl_rev0[] = {
1342 0x061c061c,
1343 0x0050ee68,
1344 0xf592fe36,
1345 0xfe5212f6,
1346 0x00000c38,
1347 0xfe5212f6,
1348 0xf592fe36,
1349 0x0050ee68,
1350 0x061c061c,
1351 0xee680050,
1352 0xfe36f592,
1353 0x12f6fe52,
1354 0x0c380000,
1355 0x12f6fe52,
1356 0xfe36f592,
1357 0xee680050,
1358 0x061c061c,
1359 0x0050ee68,
1360 0xf592fe36,
1361 0xfe5212f6,
1362 0x00000c38,
1363 0xfe5212f6,
1364 0xf592fe36,
1365 0x0050ee68,
1366 0x061c061c,
1367 0xee680050,
1368 0xfe36f592,
1369 0x12f6fe52,
1370 0x0c380000,
1371 0x12f6fe52,
1372 0xfe36f592,
1373 0xee680050,
1374 0x05e305e3,
1375 0x004def0c,
1376 0xf5f3fe47,
1377 0xfe611246,
1378 0x00000bc7,
1379 0xfe611246,
1380 0xf5f3fe47,
1381 0x004def0c,
1382 0x05e305e3,
1383 0xef0c004d,
1384 0xfe47f5f3,
1385 0x1246fe61,
1386 0x0bc70000,
1387 0x1246fe61,
1388 0xfe47f5f3,
1389 0xef0c004d,
1390 0x05e305e3,
1391 0x004def0c,
1392 0xf5f3fe47,
1393 0xfe611246,
1394 0x00000bc7,
1395 0xfe611246,
1396 0xf5f3fe47,
1397 0x004def0c,
1398 0x05e305e3,
1399 0xef0c004d,
1400 0xfe47f5f3,
1401 0x1246fe61,
1402 0x0bc70000,
1403 0x1246fe61,
1404 0xfe47f5f3,
1405 0xef0c004d,
1406 0xfa58fa58,
1407 0xf895043b,
1408 0xff4c09c0,
1409 0xfbc6ffa8,
1410 0xfb84f384,
1411 0x0798f6f9,
1412 0x05760122,
1413 0x058409f6,
1414 0x0b500000,
1415 0x05b7f542,
1416 0x08860432,
1417 0x06ddfee7,
1418 0xfb84f384,
1419 0xf9d90664,
1420 0xf7e8025c,
1421 0x00fff7bd,
1422 0x05a805a8,
1423 0xf7bd00ff,
1424 0x025cf7e8,
1425 0x0664f9d9,
1426 0xf384fb84,
1427 0xfee706dd,
1428 0x04320886,
1429 0xf54205b7,
1430 0x00000b50,
1431 0x09f60584,
1432 0x01220576,
1433 0xf6f90798,
1434 0xf384fb84,
1435 0xffa8fbc6,
1436 0x09c0ff4c,
1437 0x043bf895,
1438 0x02d402d4,
1439 0x07de0270,
1440 0xfc96079c,
1441 0xf90afe94,
1442 0xfe00ff2c,
1443 0x02d4065d,
1444 0x092a0096,
1445 0x0014fbb8,
1446 0xfd2cfd2c,
1447 0x076afb3c,
1448 0x0096f752,
1449 0xf991fd87,
1450 0xfb2c0200,
1451 0xfeb8f960,
1452 0x08e0fc96,
1453 0x049802a8,
1454 0xfd2cfd2c,
1455 0x02a80498,
1456 0xfc9608e0,
1457 0xf960feb8,
1458 0x0200fb2c,
1459 0xfd87f991,
1460 0xf7520096,
1461 0xfb3c076a,
1462 0xfd2cfd2c,
1463 0xfbb80014,
1464 0x0096092a,
1465 0x065d02d4,
1466 0xff2cfe00,
1467 0xfe94f90a,
1468 0x079cfc96,
1469 0x027007de,
1470 0x02d402d4,
1471 0x027007de,
1472 0x079cfc96,
1473 0xfe94f90a,
1474 0xff2cfe00,
1475 0x065d02d4,
1476 0x0096092a,
1477 0xfbb80014,
1478 0xfd2cfd2c,
1479 0xfb3c076a,
1480 0xf7520096,
1481 0xfd87f991,
1482 0x0200fb2c,
1483 0xf960feb8,
1484 0xfc9608e0,
1485 0x02a80498,
1486 0xfd2cfd2c,
1487 0x049802a8,
1488 0x08e0fc96,
1489 0xfeb8f960,
1490 0xfb2c0200,
1491 0xf991fd87,
1492 0x0096f752,
1493 0x076afb3c,
1494 0xfd2cfd2c,
1495 0x0014fbb8,
1496 0x092a0096,
1497 0x02d4065d,
1498 0xfe00ff2c,
1499 0xf90afe94,
1500 0xfc96079c,
1501 0x07de0270,
1502 0x00000000,
1503 0x00000000,
1504 0x00000000,
1505 0x00000000,
1506 0x00000000,
1507 0x00000000,
1508 0x00000000,
1509 0x00000000,
1510 0x00000000,
1511 0x00000000,
1512 0x00000000,
1513 0x00000000,
1514 0x00000000,
1515 0x00000000,
1516 0x00000000,
1517 0x00000000,
1518 0x00000000,
1519 0x00000000,
1520 0x00000000,
1521 0x00000000,
1522 0x00000000,
1523 0x00000000,
1524 0x00000000,
1525 0x00000000,
1526 0x00000000,
1527 0x00000000,
1528 0x00000000,
1529 0x00000000,
1530 0x00000000,
1531 0x00000000,
1532 0x00000000,
1533 0x00000000,
1534 0x00000000,
1535 0x00000000,
1536 0x00000000,
1537 0x00000000,
1538 0x00000000,
1539 0x00000000,
1540 0x00000000,
1541 0x00000000,
1542 0x00000000,
1543 0x00000000,
1544 0x00000000,
1545 0x00000000,
1546 0x00000000,
1547 0x00000000,
1548 0x00000000,
1549 0x00000000,
1550 0x00000000,
1551 0x00000000,
1552 0x00000000,
1553 0x00000000,
1554 0x00000000,
1555 0x00000000,
1556 0x00000000,
1557 0x00000000,
1558 0x00000000,
1559 0x00000000,
1560 0x00000000,
1561 0x00000000,
1562 0x00000000,
1563 0x00000000,
1564 0x00000000,
1565 0x00000000,
1566 0x00000000,
1567 0x00000000,
1568 0x00000000,
1569 0x00000000,
1570 0x00000000,
1571 0x00000000,
1572 0x00000000,
1573 0x00000000,
1574 0x00000000,
1575 0x00000000,
1576 0x00000000,
1577 0x00000000,
1578 0x00000000,
1579 0x00000000,
1580 0x00000000,
1581 0x00000000,
1582 0x00000000,
1583 0x00000000,
1584 0x00000000,
1585 0x00000000,
1586 0x00000000,
1587 0x00000000,
1588 0x00000000,
1589 0x00000000,
1590 0x00000000,
1591 0x00000000,
1592 0x00000000,
1593 0x00000000,
1594 0x00000000,
1595 0x00000000,
1596 0x00000000,
1597 0x00000000,
1598 0x062a0000,
1599 0xfefa0759,
1600 0x08b80908,
1601 0xf396fc2d,
1602 0xf9d6045c,
1603 0xfc4ef608,
1604 0xf748f596,
1605 0x07b207bf,
1606 0x062a062a,
1607 0xf84ef841,
1608 0xf748f596,
1609 0x03b209f8,
1610 0xf9d6045c,
1611 0x0c6a03d3,
1612 0x08b80908,
1613 0x0106f8a7,
1614 0x062a0000,
1615 0xfefaf8a7,
1616 0x08b8f6f8,
1617 0xf39603d3,
1618 0xf9d6fba4,
1619 0xfc4e09f8,
1620 0xf7480a6a,
1621 0x07b2f841,
1622 0x062af9d6,
1623 0xf84e07bf,
1624 0xf7480a6a,
1625 0x03b2f608,
1626 0xf9d6fba4,
1627 0x0c6afc2d,
1628 0x08b8f6f8,
1629 0x01060759,
1630 0x062a0000,
1631 0xfefa0759,
1632 0x08b80908,
1633 0xf396fc2d,
1634 0xf9d6045c,
1635 0xfc4ef608,
1636 0xf748f596,
1637 0x07b207bf,
1638 0x062a062a,
1639 0xf84ef841,
1640 0xf748f596,
1641 0x03b209f8,
1642 0xf9d6045c,
1643 0x0c6a03d3,
1644 0x08b80908,
1645 0x0106f8a7,
1646 0x062a0000,
1647 0xfefaf8a7,
1648 0x08b8f6f8,
1649 0xf39603d3,
1650 0xf9d6fba4,
1651 0xfc4e09f8,
1652 0xf7480a6a,
1653 0x07b2f841,
1654 0x062af9d6,
1655 0xf84e07bf,
1656 0xf7480a6a,
1657 0x03b2f608,
1658 0xf9d6fba4,
1659 0x0c6afc2d,
1660 0x08b8f6f8,
1661 0x01060759,
1662 0x061c061c,
1663 0xff30009d,
1664 0xffb21141,
1665 0xfd87fb54,
1666 0xf65dfe59,
1667 0x02eef99e,
1668 0x0166f03c,
1669 0xfff809b6,
1670 0x000008a4,
1671 0x000af42b,
1672 0x00eff577,
1673 0xfa840bf2,
1674 0xfc02ff51,
1675 0x08260f67,
1676 0xfff0036f,
1677 0x0842f9c3,
1678 0x00000000,
1679 0x063df7be,
1680 0xfc910010,
1681 0xf099f7da,
1682 0x00af03fe,
1683 0xf40e057c,
1684 0x0a89ff11,
1685 0x0bd5fff6,
1686 0xf75c0000,
1687 0xf64a0008,
1688 0x0fc4fe9a,
1689 0x0662fd12,
1690 0x01a709a3,
1691 0x04ac0279,
1692 0xeebf004e,
1693 0xff6300d0,
1694 0xf9e4f9e4,
1695 0x00d0ff63,
1696 0x004eeebf,
1697 0x027904ac,
1698 0x09a301a7,
1699 0xfd120662,
1700 0xfe9a0fc4,
1701 0x0008f64a,
1702 0x0000f75c,
1703 0xfff60bd5,
1704 0xff110a89,
1705 0x057cf40e,
1706 0x03fe00af,
1707 0xf7daf099,
1708 0x0010fc91,
1709 0xf7be063d,
1710 0x00000000,
1711 0xf9c30842,
1712 0x036ffff0,
1713 0x0f670826,
1714 0xff51fc02,
1715 0x0bf2fa84,
1716 0xf57700ef,
1717 0xf42b000a,
1718 0x08a40000,
1719 0x09b6fff8,
1720 0xf03c0166,
1721 0xf99e02ee,
1722 0xfe59f65d,
1723 0xfb54fd87,
1724 0x1141ffb2,
1725 0x009dff30,
1726 0x05e30000,
1727 0xff060705,
1728 0x085408a0,
1729 0xf425fc59,
1730 0xfa1d042a,
1731 0xfc78f67a,
1732 0xf7acf60e,
1733 0x075a0766,
1734 0x05e305e3,
1735 0xf8a6f89a,
1736 0xf7acf60e,
1737 0x03880986,
1738 0xfa1d042a,
1739 0x0bdb03a7,
1740 0x085408a0,
1741 0x00faf8fb,
1742 0x05e30000,
1743 0xff06f8fb,
1744 0x0854f760,
1745 0xf42503a7,
1746 0xfa1dfbd6,
1747 0xfc780986,
1748 0xf7ac09f2,
1749 0x075af89a,
1750 0x05e3fa1d,
1751 0xf8a60766,
1752 0xf7ac09f2,
1753 0x0388f67a,
1754 0xfa1dfbd6,
1755 0x0bdbfc59,
1756 0x0854f760,
1757 0x00fa0705,
1758 0x05e30000,
1759 0xff060705,
1760 0x085408a0,
1761 0xf425fc59,
1762 0xfa1d042a,
1763 0xfc78f67a,
1764 0xf7acf60e,
1765 0x075a0766,
1766 0x05e305e3,
1767 0xf8a6f89a,
1768 0xf7acf60e,
1769 0x03880986,
1770 0xfa1d042a,
1771 0x0bdb03a7,
1772 0x085408a0,
1773 0x00faf8fb,
1774 0x05e30000,
1775 0xff06f8fb,
1776 0x0854f760,
1777 0xf42503a7,
1778 0xfa1dfbd6,
1779 0xfc780986,
1780 0xf7ac09f2,
1781 0x075af89a,
1782 0x05e3fa1d,
1783 0xf8a60766,
1784 0xf7ac09f2,
1785 0x0388f67a,
1786 0xfa1dfbd6,
1787 0x0bdbfc59,
1788 0x0854f760,
1789 0x00fa0705,
1790 0xfa58fa58,
1791 0xf8f0fe00,
1792 0x0448073d,
1793 0xfdc9fe46,
1794 0xf9910258,
1795 0x089d0407,
1796 0xfd5cf71a,
1797 0x02affde0,
1798 0x083e0496,
1799 0xff5a0740,
1800 0xff7afd97,
1801 0x00fe01f1,
1802 0x0009082e,
1803 0xfa94ff75,
1804 0xfecdf8ea,
1805 0xffb0f693,
1806 0xfd2cfa58,
1807 0x0433ff16,
1808 0xfba405dd,
1809 0xfa610341,
1810 0x06a606cb,
1811 0x0039fd2d,
1812 0x0677fa97,
1813 0x01fa05e0,
1814 0xf896003e,
1815 0x075a068b,
1816 0x012cfc3e,
1817 0xfa23f98d,
1818 0xfc7cfd43,
1819 0xff90fc0d,
1820 0x01c10982,
1821 0x00c601d6,
1822 0xfd2cfd2c,
1823 0x01d600c6,
1824 0x098201c1,
1825 0xfc0dff90,
1826 0xfd43fc7c,
1827 0xf98dfa23,
1828 0xfc3e012c,
1829 0x068b075a,
1830 0x003ef896,
1831 0x05e001fa,
1832 0xfa970677,
1833 0xfd2d0039,
1834 0x06cb06a6,
1835 0x0341fa61,
1836 0x05ddfba4,
1837 0xff160433,
1838 0xfa58fd2c,
1839 0xf693ffb0,
1840 0xf8eafecd,
1841 0xff75fa94,
1842 0x082e0009,
1843 0x01f100fe,
1844 0xfd97ff7a,
1845 0x0740ff5a,
1846 0x0496083e,
1847 0xfde002af,
1848 0xf71afd5c,
1849 0x0407089d,
1850 0x0258f991,
1851 0xfe46fdc9,
1852 0x073d0448,
1853 0xfe00f8f0,
1854 0xfd2cfd2c,
1855 0xfce00500,
1856 0xfc09fddc,
1857 0xfe680157,
1858 0x04c70571,
1859 0xfc3aff21,
1860 0xfcd70228,
1861 0x056d0277,
1862 0x0200fe00,
1863 0x0022f927,
1864 0xfe3c032b,
1865 0xfc44ff3c,
1866 0x03e9fbdb,
1867 0x04570313,
1868 0x04c9ff5c,
1869 0x000d03b8,
1870 0xfa580000,
1871 0xfbe900d2,
1872 0xf9d0fe0b,
1873 0x0125fdf9,
1874 0x042501bf,
1875 0x0328fa2b,
1876 0xffa902f0,
1877 0xfa250157,
1878 0x0200fe00,
1879 0x03740438,
1880 0xff0405fd,
1881 0x030cfe52,
1882 0x0037fb39,
1883 0xff6904c5,
1884 0x04f8fd23,
1885 0xfd31fc1b,
1886 0xfd2cfd2c,
1887 0xfc1bfd31,
1888 0xfd2304f8,
1889 0x04c5ff69,
1890 0xfb390037,
1891 0xfe52030c,
1892 0x05fdff04,
1893 0x04380374,
1894 0xfe000200,
1895 0x0157fa25,
1896 0x02f0ffa9,
1897 0xfa2b0328,
1898 0x01bf0425,
1899 0xfdf90125,
1900 0xfe0bf9d0,
1901 0x00d2fbe9,
1902 0x0000fa58,
1903 0x03b8000d,
1904 0xff5c04c9,
1905 0x03130457,
1906 0xfbdb03e9,
1907 0xff3cfc44,
1908 0x032bfe3c,
1909 0xf9270022,
1910 0xfe000200,
1911 0x0277056d,
1912 0x0228fcd7,
1913 0xff21fc3a,
1914 0x057104c7,
1915 0x0157fe68,
1916 0xfddcfc09,
1917 0x0500fce0,
1918 0xfd2cfd2c,
1919 0x0500fce0,
1920 0xfddcfc09,
1921 0x0157fe68,
1922 0x057104c7,
1923 0xff21fc3a,
1924 0x0228fcd7,
1925 0x0277056d,
1926 0xfe000200,
1927 0xf9270022,
1928 0x032bfe3c,
1929 0xff3cfc44,
1930 0xfbdb03e9,
1931 0x03130457,
1932 0xff5c04c9,
1933 0x03b8000d,
1934 0x0000fa58,
1935 0x00d2fbe9,
1936 0xfe0bf9d0,
1937 0xfdf90125,
1938 0x01bf0425,
1939 0xfa2b0328,
1940 0x02f0ffa9,
1941 0x0157fa25,
1942 0xfe000200,
1943 0x04380374,
1944 0x05fdff04,
1945 0xfe52030c,
1946 0xfb390037,
1947 0x04c5ff69,
1948 0xfd2304f8,
1949 0xfc1bfd31,
1950 0xfd2cfd2c,
1951 0xfd31fc1b,
1952 0x04f8fd23,
1953 0xff6904c5,
1954 0x0037fb39,
1955 0x030cfe52,
1956 0xff0405fd,
1957 0x03740438,
1958 0x0200fe00,
1959 0xfa250157,
1960 0xffa902f0,
1961 0x0328fa2b,
1962 0x042501bf,
1963 0x0125fdf9,
1964 0xf9d0fe0b,
1965 0xfbe900d2,
1966 0xfa580000,
1967 0x000d03b8,
1968 0x04c9ff5c,
1969 0x04570313,
1970 0x03e9fbdb,
1971 0xfc44ff3c,
1972 0xfe3c032b,
1973 0x0022f927,
1974 0x0200fe00,
1975 0x056d0277,
1976 0xfcd70228,
1977 0xfc3aff21,
1978 0x04c70571,
1979 0xfe680157,
1980 0xfc09fddc,
1981 0xfce00500,
1982 0x05a80000,
1983 0xff1006be,
1984 0x0800084a,
1985 0xf49cfc7e,
1986 0xfa580400,
1987 0xfc9cf6da,
1988 0xf800f672,
1989 0x0710071c,
1990 0x05a805a8,
1991 0xf8f0f8e4,
1992 0xf800f672,
1993 0x03640926,
1994 0xfa580400,
1995 0x0b640382,
1996 0x0800084a,
1997 0x00f0f942,
1998 0x05a80000,
1999 0xff10f942,
2000 0x0800f7b6,
2001 0xf49c0382,
2002 0xfa58fc00,
2003 0xfc9c0926,
2004 0xf800098e,
2005 0x0710f8e4,
2006 0x05a8fa58,
2007 0xf8f0071c,
2008 0xf800098e,
2009 0x0364f6da,
2010 0xfa58fc00,
2011 0x0b64fc7e,
2012 0x0800f7b6,
2013 0x00f006be,
2014 0x05a80000,
2015 0xff1006be,
2016 0x0800084a,
2017 0xf49cfc7e,
2018 0xfa580400,
2019 0xfc9cf6da,
2020 0xf800f672,
2021 0x0710071c,
2022 0x05a805a8,
2023 0xf8f0f8e4,
2024 0xf800f672,
2025 0x03640926,
2026 0xfa580400,
2027 0x0b640382,
2028 0x0800084a,
2029 0x00f0f942,
2030 0x05a80000,
2031 0xff10f942,
2032 0x0800f7b6,
2033 0xf49c0382,
2034 0xfa58fc00,
2035 0xfc9c0926,
2036 0xf800098e,
2037 0x0710f8e4,
2038 0x05a8fa58,
2039 0xf8f0071c,
2040 0xf800098e,
2041 0x0364f6da,
2042 0xfa58fc00,
2043 0x0b64fc7e,
2044 0x0800f7b6,
2045 0x00f006be,
2046};
2047
2048const u32 intlv_tbl_rev0[] = {
2049 0x00802070,
2050 0x0671188d,
2051 0x0a60192c,
2052 0x0a300e46,
2053 0x00c1188d,
2054 0x080024d2,
2055 0x00000070,
2056};
2057
2058const u16 pilot_tbl_rev0[] = {
2059 0xff08,
2060 0xff08,
2061 0xff08,
2062 0xff08,
2063 0xff08,
2064 0xff08,
2065 0xff08,
2066 0xff08,
2067 0x80d5,
2068 0x80d5,
2069 0x80d5,
2070 0x80d5,
2071 0x80d5,
2072 0x80d5,
2073 0x80d5,
2074 0x80d5,
2075 0xff0a,
2076 0xff82,
2077 0xffa0,
2078 0xff28,
2079 0xffff,
2080 0xffff,
2081 0xffff,
2082 0xffff,
2083 0xff82,
2084 0xffa0,
2085 0xff28,
2086 0xff0a,
2087 0xffff,
2088 0xffff,
2089 0xffff,
2090 0xffff,
2091 0xf83f,
2092 0xfa1f,
2093 0xfa97,
2094 0xfab5,
2095 0xf2bd,
2096 0xf0bf,
2097 0xffff,
2098 0xffff,
2099 0xf017,
2100 0xf815,
2101 0xf215,
2102 0xf095,
2103 0xf035,
2104 0xf01d,
2105 0xffff,
2106 0xffff,
2107 0xff08,
2108 0xff02,
2109 0xff80,
2110 0xff20,
2111 0xff08,
2112 0xff02,
2113 0xff80,
2114 0xff20,
2115 0xf01f,
2116 0xf817,
2117 0xfa15,
2118 0xf295,
2119 0xf0b5,
2120 0xf03d,
2121 0xffff,
2122 0xffff,
2123 0xf82a,
2124 0xfa0a,
2125 0xfa82,
2126 0xfaa0,
2127 0xf2a8,
2128 0xf0aa,
2129 0xffff,
2130 0xffff,
2131 0xf002,
2132 0xf800,
2133 0xf200,
2134 0xf080,
2135 0xf020,
2136 0xf008,
2137 0xffff,
2138 0xffff,
2139 0xf00a,
2140 0xf802,
2141 0xfa00,
2142 0xf280,
2143 0xf0a0,
2144 0xf028,
2145 0xffff,
2146 0xffff,
2147};
2148
2149const u32 pltlut_tbl_rev0[] = {
2150 0x76540123,
2151 0x62407351,
2152 0x76543201,
2153 0x76540213,
2154 0x76540123,
2155 0x76430521,
2156};
2157
2158const u32 tdi_tbl20_ant0_rev0[] = {
2159 0x00091226,
2160 0x000a1429,
2161 0x000b56ad,
2162 0x000c58b0,
2163 0x000d5ab3,
2164 0x000e9cb6,
2165 0x000f9eba,
2166 0x0000c13d,
2167 0x00020301,
2168 0x00030504,
2169 0x00040708,
2170 0x0005090b,
2171 0x00064b8e,
2172 0x00095291,
2173 0x000a5494,
2174 0x000b9718,
2175 0x000c9927,
2176 0x000d9b2a,
2177 0x000edd2e,
2178 0x000fdf31,
2179 0x000101b4,
2180 0x000243b7,
2181 0x000345bb,
2182 0x000447be,
2183 0x00058982,
2184 0x00068c05,
2185 0x00099309,
2186 0x000a950c,
2187 0x000bd78f,
2188 0x000cd992,
2189 0x000ddb96,
2190 0x000f1d99,
2191 0x00005fa8,
2192 0x0001422c,
2193 0x0002842f,
2194 0x00038632,
2195 0x00048835,
2196 0x0005ca38,
2197 0x0006ccbc,
2198 0x0009d3bf,
2199 0x000b1603,
2200 0x000c1806,
2201 0x000d1a0a,
2202 0x000e1c0d,
2203 0x000f5e10,
2204 0x00008093,
2205 0x00018297,
2206 0x0002c49a,
2207 0x0003c680,
2208 0x0004c880,
2209 0x00060b00,
2210 0x00070d00,
2211 0x00000000,
2212 0x00000000,
2213 0x00000000,
2214};
2215
2216const u32 tdi_tbl20_ant1_rev0[] = {
2217 0x00014b26,
2218 0x00028d29,
2219 0x000393ad,
2220 0x00049630,
2221 0x0005d833,
2222 0x0006da36,
2223 0x00099c3a,
2224 0x000a9e3d,
2225 0x000bc081,
2226 0x000cc284,
2227 0x000dc488,
2228 0x000f068b,
2229 0x0000488e,
2230 0x00018b91,
2231 0x0002d214,
2232 0x0003d418,
2233 0x0004d6a7,
2234 0x000618aa,
2235 0x00071aae,
2236 0x0009dcb1,
2237 0x000b1eb4,
2238 0x000c0137,
2239 0x000d033b,
2240 0x000e053e,
2241 0x000f4702,
2242 0x00008905,
2243 0x00020c09,
2244 0x0003128c,
2245 0x0004148f,
2246 0x00051712,
2247 0x00065916,
2248 0x00091b19,
2249 0x000a1d28,
2250 0x000b5f2c,
2251 0x000c41af,
2252 0x000d43b2,
2253 0x000e85b5,
2254 0x000f87b8,
2255 0x0000c9bc,
2256 0x00024cbf,
2257 0x00035303,
2258 0x00045506,
2259 0x0005978a,
2260 0x0006998d,
2261 0x00095b90,
2262 0x000a5d93,
2263 0x000b9f97,
2264 0x000c821a,
2265 0x000d8400,
2266 0x000ec600,
2267 0x000fc800,
2268 0x00010a00,
2269 0x00000000,
2270 0x00000000,
2271 0x00000000,
2272};
2273
2274const u32 tdi_tbl40_ant0_rev0[] = {
2275 0x0011a346,
2276 0x00136ccf,
2277 0x0014f5d9,
2278 0x001641e2,
2279 0x0017cb6b,
2280 0x00195475,
2281 0x001b2383,
2282 0x001cad0c,
2283 0x001e7616,
2284 0x0000821f,
2285 0x00020ba8,
2286 0x0003d4b2,
2287 0x00056447,
2288 0x00072dd0,
2289 0x0008b6da,
2290 0x000a02e3,
2291 0x000b8c6c,
2292 0x000d15f6,
2293 0x0011e484,
2294 0x0013ae0d,
2295 0x00153717,
2296 0x00168320,
2297 0x00180ca9,
2298 0x00199633,
2299 0x001b6548,
2300 0x001ceed1,
2301 0x001eb7db,
2302 0x0000c3e4,
2303 0x00024d6d,
2304 0x000416f7,
2305 0x0005a585,
2306 0x00076f0f,
2307 0x0008f818,
2308 0x000a4421,
2309 0x000bcdab,
2310 0x000d9734,
2311 0x00122649,
2312 0x0013efd2,
2313 0x001578dc,
2314 0x0016c4e5,
2315 0x00184e6e,
2316 0x001a17f8,
2317 0x001ba686,
2318 0x001d3010,
2319 0x001ef999,
2320 0x00010522,
2321 0x00028eac,
2322 0x00045835,
2323 0x0005e74a,
2324 0x0007b0d3,
2325 0x00093a5d,
2326 0x000a85e6,
2327 0x000c0f6f,
2328 0x000dd8f9,
2329 0x00126787,
2330 0x00143111,
2331 0x0015ba9a,
2332 0x00170623,
2333 0x00188fad,
2334 0x001a5936,
2335 0x001be84b,
2336 0x001db1d4,
2337 0x001f3b5e,
2338 0x000146e7,
2339 0x00031070,
2340 0x000499fa,
2341 0x00062888,
2342 0x0007f212,
2343 0x00097b9b,
2344 0x000ac7a4,
2345 0x000c50ae,
2346 0x000e1a37,
2347 0x0012a94c,
2348 0x001472d5,
2349 0x0015fc5f,
2350 0x00174868,
2351 0x0018d171,
2352 0x001a9afb,
2353 0x001c2989,
2354 0x001df313,
2355 0x001f7c9c,
2356 0x000188a5,
2357 0x000351af,
2358 0x0004db38,
2359 0x0006aa4d,
2360 0x000833d7,
2361 0x0009bd60,
2362 0x000b0969,
2363 0x000c9273,
2364 0x000e5bfc,
2365 0x00132a8a,
2366 0x0014b414,
2367 0x00163d9d,
2368 0x001789a6,
2369 0x001912b0,
2370 0x001adc39,
2371 0x001c6bce,
2372 0x001e34d8,
2373 0x001fbe61,
2374 0x0001ca6a,
2375 0x00039374,
2376 0x00051cfd,
2377 0x0006ec0b,
2378 0x00087515,
2379 0x0009fe9e,
2380 0x000b4aa7,
2381 0x000cd3b1,
2382 0x000e9d3a,
2383 0x00000000,
2384 0x00000000,
2385};
2386
2387const u32 tdi_tbl40_ant1_rev0[] = {
2388 0x001edb36,
2389 0x000129ca,
2390 0x0002b353,
2391 0x00047cdd,
2392 0x0005c8e6,
2393 0x000791ef,
2394 0x00091bf9,
2395 0x000aaa07,
2396 0x000c3391,
2397 0x000dfd1a,
2398 0x00120923,
2399 0x0013d22d,
2400 0x00155c37,
2401 0x0016eacb,
2402 0x00187454,
2403 0x001a3dde,
2404 0x001b89e7,
2405 0x001d12f0,
2406 0x001f1cfa,
2407 0x00016b88,
2408 0x00033492,
2409 0x0004be1b,
2410 0x00060a24,
2411 0x0007d32e,
2412 0x00095d38,
2413 0x000aec4c,
2414 0x000c7555,
2415 0x000e3edf,
2416 0x00124ae8,
2417 0x001413f1,
2418 0x0015a37b,
2419 0x00172c89,
2420 0x0018b593,
2421 0x001a419c,
2422 0x001bcb25,
2423 0x001d942f,
2424 0x001f63b9,
2425 0x0001ad4d,
2426 0x00037657,
2427 0x0004c260,
2428 0x00068be9,
2429 0x000814f3,
2430 0x0009a47c,
2431 0x000b2d8a,
2432 0x000cb694,
2433 0x000e429d,
2434 0x00128c26,
2435 0x001455b0,
2436 0x0015e4ba,
2437 0x00176e4e,
2438 0x0018f758,
2439 0x001a8361,
2440 0x001c0cea,
2441 0x001dd674,
2442 0x001fa57d,
2443 0x0001ee8b,
2444 0x0003b795,
2445 0x0005039e,
2446 0x0006cd27,
2447 0x000856b1,
2448 0x0009e5c6,
2449 0x000b6f4f,
2450 0x000cf859,
2451 0x000e8462,
2452 0x00130deb,
2453 0x00149775,
2454 0x00162603,
2455 0x0017af8c,
2456 0x00193896,
2457 0x001ac49f,
2458 0x001c4e28,
2459 0x001e17b2,
2460 0x0000a6c7,
2461 0x00023050,
2462 0x0003f9da,
2463 0x00054563,
2464 0x00070eec,
2465 0x00089876,
2466 0x000a2704,
2467 0x000bb08d,
2468 0x000d3a17,
2469 0x001185a0,
2470 0x00134f29,
2471 0x0014d8b3,
2472 0x001667c8,
2473 0x0017f151,
2474 0x00197adb,
2475 0x001b0664,
2476 0x001c8fed,
2477 0x001e5977,
2478 0x0000e805,
2479 0x0002718f,
2480 0x00043b18,
2481 0x000586a1,
2482 0x0007502b,
2483 0x0008d9b4,
2484 0x000a68c9,
2485 0x000bf252,
2486 0x000dbbdc,
2487 0x0011c7e5,
2488 0x001390ee,
2489 0x00151a78,
2490 0x0016a906,
2491 0x00183290,
2492 0x0019bc19,
2493 0x001b4822,
2494 0x001cd12c,
2495 0x001e9ab5,
2496 0x00000000,
2497 0x00000000,
2498};
2499
2500const u16 bdi_tbl_rev0[] = {
2501 0x0070,
2502 0x0126,
2503 0x012c,
2504 0x0246,
2505 0x048d,
2506 0x04d2,
2507};
2508
2509const u32 chanest_tbl_rev0[] = {
2510 0x44444444,
2511 0x44444444,
2512 0x44444444,
2513 0x44444444,
2514 0x44444444,
2515 0x44444444,
2516 0x44444444,
2517 0x44444444,
2518 0x10101010,
2519 0x10101010,
2520 0x10101010,
2521 0x10101010,
2522 0x10101010,
2523 0x10101010,
2524 0x10101010,
2525 0x10101010,
2526 0x44444444,
2527 0x44444444,
2528 0x44444444,
2529 0x44444444,
2530 0x44444444,
2531 0x44444444,
2532 0x44444444,
2533 0x44444444,
2534 0x10101010,
2535 0x10101010,
2536 0x10101010,
2537 0x10101010,
2538 0x10101010,
2539 0x10101010,
2540 0x10101010,
2541 0x10101010,
2542 0x44444444,
2543 0x44444444,
2544 0x44444444,
2545 0x44444444,
2546 0x44444444,
2547 0x44444444,
2548 0x44444444,
2549 0x44444444,
2550 0x44444444,
2551 0x44444444,
2552 0x44444444,
2553 0x44444444,
2554 0x44444444,
2555 0x44444444,
2556 0x44444444,
2557 0x44444444,
2558 0x10101010,
2559 0x10101010,
2560 0x10101010,
2561 0x10101010,
2562 0x10101010,
2563 0x10101010,
2564 0x10101010,
2565 0x10101010,
2566 0x10101010,
2567 0x10101010,
2568 0x10101010,
2569 0x10101010,
2570 0x10101010,
2571 0x10101010,
2572 0x10101010,
2573 0x10101010,
2574 0x44444444,
2575 0x44444444,
2576 0x44444444,
2577 0x44444444,
2578 0x44444444,
2579 0x44444444,
2580 0x44444444,
2581 0x44444444,
2582 0x44444444,
2583 0x44444444,
2584 0x44444444,
2585 0x44444444,
2586 0x44444444,
2587 0x44444444,
2588 0x44444444,
2589 0x44444444,
2590 0x10101010,
2591 0x10101010,
2592 0x10101010,
2593 0x10101010,
2594 0x10101010,
2595 0x10101010,
2596 0x10101010,
2597 0x10101010,
2598 0x10101010,
2599 0x10101010,
2600 0x10101010,
2601 0x10101010,
2602 0x10101010,
2603 0x10101010,
2604 0x10101010,
2605 0x10101010,
2606};
2607
2608const u8 mcs_tbl_rev0[] = {
2609 0x00,
2610 0x08,
2611 0x0a,
2612 0x10,
2613 0x12,
2614 0x19,
2615 0x1a,
2616 0x1c,
2617 0x40,
2618 0x48,
2619 0x4a,
2620 0x50,
2621 0x52,
2622 0x59,
2623 0x5a,
2624 0x5c,
2625 0x80,
2626 0x88,
2627 0x8a,
2628 0x90,
2629 0x92,
2630 0x99,
2631 0x9a,
2632 0x9c,
2633 0xc0,
2634 0xc8,
2635 0xca,
2636 0xd0,
2637 0xd2,
2638 0xd9,
2639 0xda,
2640 0xdc,
2641 0x00,
2642 0x00,
2643 0x00,
2644 0x00,
2645 0x00,
2646 0x00,
2647 0x00,
2648 0x00,
2649 0x00,
2650 0x00,
2651 0x00,
2652 0x00,
2653 0x00,
2654 0x00,
2655 0x00,
2656 0x00,
2657 0x00,
2658 0x00,
2659 0x00,
2660 0x00,
2661 0x00,
2662 0x00,
2663 0x00,
2664 0x00,
2665 0x00,
2666 0x00,
2667 0x00,
2668 0x00,
2669 0x00,
2670 0x00,
2671 0x00,
2672 0x00,
2673 0x00,
2674 0x01,
2675 0x02,
2676 0x04,
2677 0x08,
2678 0x09,
2679 0x0a,
2680 0x0c,
2681 0x10,
2682 0x11,
2683 0x12,
2684 0x14,
2685 0x18,
2686 0x19,
2687 0x1a,
2688 0x1c,
2689 0x20,
2690 0x21,
2691 0x22,
2692 0x24,
2693 0x40,
2694 0x41,
2695 0x42,
2696 0x44,
2697 0x48,
2698 0x49,
2699 0x4a,
2700 0x4c,
2701 0x50,
2702 0x51,
2703 0x52,
2704 0x54,
2705 0x58,
2706 0x59,
2707 0x5a,
2708 0x5c,
2709 0x60,
2710 0x61,
2711 0x62,
2712 0x64,
2713 0x00,
2714 0x00,
2715 0x00,
2716 0x00,
2717 0x00,
2718 0x00,
2719 0x00,
2720 0x00,
2721 0x00,
2722 0x00,
2723 0x00,
2724 0x00,
2725 0x00,
2726 0x00,
2727 0x00,
2728 0x00,
2729 0x00,
2730 0x00,
2731 0x00,
2732 0x00,
2733 0x00,
2734 0x00,
2735 0x00,
2736 0x00,
2737};
2738
2739const u32 noise_var_tbl0_rev0[] = {
2740 0x020c020c,
2741 0x0000014d,
2742 0x020c020c,
2743 0x0000014d,
2744 0x020c020c,
2745 0x0000014d,
2746 0x020c020c,
2747 0x0000014d,
2748 0x020c020c,
2749 0x0000014d,
2750 0x020c020c,
2751 0x0000014d,
2752 0x020c020c,
2753 0x0000014d,
2754 0x020c020c,
2755 0x0000014d,
2756 0x020c020c,
2757 0x0000014d,
2758 0x020c020c,
2759 0x0000014d,
2760 0x020c020c,
2761 0x0000014d,
2762 0x020c020c,
2763 0x0000014d,
2764 0x020c020c,
2765 0x0000014d,
2766 0x020c020c,
2767 0x0000014d,
2768 0x020c020c,
2769 0x0000014d,
2770 0x020c020c,
2771 0x0000014d,
2772 0x020c020c,
2773 0x0000014d,
2774 0x020c020c,
2775 0x0000014d,
2776 0x020c020c,
2777 0x0000014d,
2778 0x020c020c,
2779 0x0000014d,
2780 0x020c020c,
2781 0x0000014d,
2782 0x020c020c,
2783 0x0000014d,
2784 0x020c020c,
2785 0x0000014d,
2786 0x020c020c,
2787 0x0000014d,
2788 0x020c020c,
2789 0x0000014d,
2790 0x020c020c,
2791 0x0000014d,
2792 0x020c020c,
2793 0x0000014d,
2794 0x020c020c,
2795 0x0000014d,
2796 0x020c020c,
2797 0x0000014d,
2798 0x020c020c,
2799 0x0000014d,
2800 0x020c020c,
2801 0x0000014d,
2802 0x020c020c,
2803 0x0000014d,
2804 0x020c020c,
2805 0x0000014d,
2806 0x020c020c,
2807 0x0000014d,
2808 0x020c020c,
2809 0x0000014d,
2810 0x020c020c,
2811 0x0000014d,
2812 0x020c020c,
2813 0x0000014d,
2814 0x020c020c,
2815 0x0000014d,
2816 0x020c020c,
2817 0x0000014d,
2818 0x020c020c,
2819 0x0000014d,
2820 0x020c020c,
2821 0x0000014d,
2822 0x020c020c,
2823 0x0000014d,
2824 0x020c020c,
2825 0x0000014d,
2826 0x020c020c,
2827 0x0000014d,
2828 0x020c020c,
2829 0x0000014d,
2830 0x020c020c,
2831 0x0000014d,
2832 0x020c020c,
2833 0x0000014d,
2834 0x020c020c,
2835 0x0000014d,
2836 0x020c020c,
2837 0x0000014d,
2838 0x020c020c,
2839 0x0000014d,
2840 0x020c020c,
2841 0x0000014d,
2842 0x020c020c,
2843 0x0000014d,
2844 0x020c020c,
2845 0x0000014d,
2846 0x020c020c,
2847 0x0000014d,
2848 0x020c020c,
2849 0x0000014d,
2850 0x020c020c,
2851 0x0000014d,
2852 0x020c020c,
2853 0x0000014d,
2854 0x020c020c,
2855 0x0000014d,
2856 0x020c020c,
2857 0x0000014d,
2858 0x020c020c,
2859 0x0000014d,
2860 0x020c020c,
2861 0x0000014d,
2862 0x020c020c,
2863 0x0000014d,
2864 0x020c020c,
2865 0x0000014d,
2866 0x020c020c,
2867 0x0000014d,
2868 0x020c020c,
2869 0x0000014d,
2870 0x020c020c,
2871 0x0000014d,
2872 0x020c020c,
2873 0x0000014d,
2874 0x020c020c,
2875 0x0000014d,
2876 0x020c020c,
2877 0x0000014d,
2878 0x020c020c,
2879 0x0000014d,
2880 0x020c020c,
2881 0x0000014d,
2882 0x020c020c,
2883 0x0000014d,
2884 0x020c020c,
2885 0x0000014d,
2886 0x020c020c,
2887 0x0000014d,
2888 0x020c020c,
2889 0x0000014d,
2890 0x020c020c,
2891 0x0000014d,
2892 0x020c020c,
2893 0x0000014d,
2894 0x020c020c,
2895 0x0000014d,
2896 0x020c020c,
2897 0x0000014d,
2898 0x020c020c,
2899 0x0000014d,
2900 0x020c020c,
2901 0x0000014d,
2902 0x020c020c,
2903 0x0000014d,
2904 0x020c020c,
2905 0x0000014d,
2906 0x020c020c,
2907 0x0000014d,
2908 0x020c020c,
2909 0x0000014d,
2910 0x020c020c,
2911 0x0000014d,
2912 0x020c020c,
2913 0x0000014d,
2914 0x020c020c,
2915 0x0000014d,
2916 0x020c020c,
2917 0x0000014d,
2918 0x020c020c,
2919 0x0000014d,
2920 0x020c020c,
2921 0x0000014d,
2922 0x020c020c,
2923 0x0000014d,
2924 0x020c020c,
2925 0x0000014d,
2926 0x020c020c,
2927 0x0000014d,
2928 0x020c020c,
2929 0x0000014d,
2930 0x020c020c,
2931 0x0000014d,
2932 0x020c020c,
2933 0x0000014d,
2934 0x020c020c,
2935 0x0000014d,
2936 0x020c020c,
2937 0x0000014d,
2938 0x020c020c,
2939 0x0000014d,
2940 0x020c020c,
2941 0x0000014d,
2942 0x020c020c,
2943 0x0000014d,
2944 0x020c020c,
2945 0x0000014d,
2946 0x020c020c,
2947 0x0000014d,
2948 0x020c020c,
2949 0x0000014d,
2950 0x020c020c,
2951 0x0000014d,
2952 0x020c020c,
2953 0x0000014d,
2954 0x020c020c,
2955 0x0000014d,
2956 0x020c020c,
2957 0x0000014d,
2958 0x020c020c,
2959 0x0000014d,
2960 0x020c020c,
2961 0x0000014d,
2962 0x020c020c,
2963 0x0000014d,
2964 0x020c020c,
2965 0x0000014d,
2966 0x020c020c,
2967 0x0000014d,
2968 0x020c020c,
2969 0x0000014d,
2970 0x020c020c,
2971 0x0000014d,
2972 0x020c020c,
2973 0x0000014d,
2974 0x020c020c,
2975 0x0000014d,
2976 0x020c020c,
2977 0x0000014d,
2978 0x020c020c,
2979 0x0000014d,
2980 0x020c020c,
2981 0x0000014d,
2982 0x020c020c,
2983 0x0000014d,
2984 0x020c020c,
2985 0x0000014d,
2986 0x020c020c,
2987 0x0000014d,
2988 0x020c020c,
2989 0x0000014d,
2990 0x020c020c,
2991 0x0000014d,
2992 0x020c020c,
2993 0x0000014d,
2994 0x020c020c,
2995 0x0000014d,
2996};
2997
2998const u32 noise_var_tbl1_rev0[] = {
2999 0x020c020c,
3000 0x0000014d,
3001 0x020c020c,
3002 0x0000014d,
3003 0x020c020c,
3004 0x0000014d,
3005 0x020c020c,
3006 0x0000014d,
3007 0x020c020c,
3008 0x0000014d,
3009 0x020c020c,
3010 0x0000014d,
3011 0x020c020c,
3012 0x0000014d,
3013 0x020c020c,
3014 0x0000014d,
3015 0x020c020c,
3016 0x0000014d,
3017 0x020c020c,
3018 0x0000014d,
3019 0x020c020c,
3020 0x0000014d,
3021 0x020c020c,
3022 0x0000014d,
3023 0x020c020c,
3024 0x0000014d,
3025 0x020c020c,
3026 0x0000014d,
3027 0x020c020c,
3028 0x0000014d,
3029 0x020c020c,
3030 0x0000014d,
3031 0x020c020c,
3032 0x0000014d,
3033 0x020c020c,
3034 0x0000014d,
3035 0x020c020c,
3036 0x0000014d,
3037 0x020c020c,
3038 0x0000014d,
3039 0x020c020c,
3040 0x0000014d,
3041 0x020c020c,
3042 0x0000014d,
3043 0x020c020c,
3044 0x0000014d,
3045 0x020c020c,
3046 0x0000014d,
3047 0x020c020c,
3048 0x0000014d,
3049 0x020c020c,
3050 0x0000014d,
3051 0x020c020c,
3052 0x0000014d,
3053 0x020c020c,
3054 0x0000014d,
3055 0x020c020c,
3056 0x0000014d,
3057 0x020c020c,
3058 0x0000014d,
3059 0x020c020c,
3060 0x0000014d,
3061 0x020c020c,
3062 0x0000014d,
3063 0x020c020c,
3064 0x0000014d,
3065 0x020c020c,
3066 0x0000014d,
3067 0x020c020c,
3068 0x0000014d,
3069 0x020c020c,
3070 0x0000014d,
3071 0x020c020c,
3072 0x0000014d,
3073 0x020c020c,
3074 0x0000014d,
3075 0x020c020c,
3076 0x0000014d,
3077 0x020c020c,
3078 0x0000014d,
3079 0x020c020c,
3080 0x0000014d,
3081 0x020c020c,
3082 0x0000014d,
3083 0x020c020c,
3084 0x0000014d,
3085 0x020c020c,
3086 0x0000014d,
3087 0x020c020c,
3088 0x0000014d,
3089 0x020c020c,
3090 0x0000014d,
3091 0x020c020c,
3092 0x0000014d,
3093 0x020c020c,
3094 0x0000014d,
3095 0x020c020c,
3096 0x0000014d,
3097 0x020c020c,
3098 0x0000014d,
3099 0x020c020c,
3100 0x0000014d,
3101 0x020c020c,
3102 0x0000014d,
3103 0x020c020c,
3104 0x0000014d,
3105 0x020c020c,
3106 0x0000014d,
3107 0x020c020c,
3108 0x0000014d,
3109 0x020c020c,
3110 0x0000014d,
3111 0x020c020c,
3112 0x0000014d,
3113 0x020c020c,
3114 0x0000014d,
3115 0x020c020c,
3116 0x0000014d,
3117 0x020c020c,
3118 0x0000014d,
3119 0x020c020c,
3120 0x0000014d,
3121 0x020c020c,
3122 0x0000014d,
3123 0x020c020c,
3124 0x0000014d,
3125 0x020c020c,
3126 0x0000014d,
3127 0x020c020c,
3128 0x0000014d,
3129 0x020c020c,
3130 0x0000014d,
3131 0x020c020c,
3132 0x0000014d,
3133 0x020c020c,
3134 0x0000014d,
3135 0x020c020c,
3136 0x0000014d,
3137 0x020c020c,
3138 0x0000014d,
3139 0x020c020c,
3140 0x0000014d,
3141 0x020c020c,
3142 0x0000014d,
3143 0x020c020c,
3144 0x0000014d,
3145 0x020c020c,
3146 0x0000014d,
3147 0x020c020c,
3148 0x0000014d,
3149 0x020c020c,
3150 0x0000014d,
3151 0x020c020c,
3152 0x0000014d,
3153 0x020c020c,
3154 0x0000014d,
3155 0x020c020c,
3156 0x0000014d,
3157 0x020c020c,
3158 0x0000014d,
3159 0x020c020c,
3160 0x0000014d,
3161 0x020c020c,
3162 0x0000014d,
3163 0x020c020c,
3164 0x0000014d,
3165 0x020c020c,
3166 0x0000014d,
3167 0x020c020c,
3168 0x0000014d,
3169 0x020c020c,
3170 0x0000014d,
3171 0x020c020c,
3172 0x0000014d,
3173 0x020c020c,
3174 0x0000014d,
3175 0x020c020c,
3176 0x0000014d,
3177 0x020c020c,
3178 0x0000014d,
3179 0x020c020c,
3180 0x0000014d,
3181 0x020c020c,
3182 0x0000014d,
3183 0x020c020c,
3184 0x0000014d,
3185 0x020c020c,
3186 0x0000014d,
3187 0x020c020c,
3188 0x0000014d,
3189 0x020c020c,
3190 0x0000014d,
3191 0x020c020c,
3192 0x0000014d,
3193 0x020c020c,
3194 0x0000014d,
3195 0x020c020c,
3196 0x0000014d,
3197 0x020c020c,
3198 0x0000014d,
3199 0x020c020c,
3200 0x0000014d,
3201 0x020c020c,
3202 0x0000014d,
3203 0x020c020c,
3204 0x0000014d,
3205 0x020c020c,
3206 0x0000014d,
3207 0x020c020c,
3208 0x0000014d,
3209 0x020c020c,
3210 0x0000014d,
3211 0x020c020c,
3212 0x0000014d,
3213 0x020c020c,
3214 0x0000014d,
3215 0x020c020c,
3216 0x0000014d,
3217 0x020c020c,
3218 0x0000014d,
3219 0x020c020c,
3220 0x0000014d,
3221 0x020c020c,
3222 0x0000014d,
3223 0x020c020c,
3224 0x0000014d,
3225 0x020c020c,
3226 0x0000014d,
3227 0x020c020c,
3228 0x0000014d,
3229 0x020c020c,
3230 0x0000014d,
3231 0x020c020c,
3232 0x0000014d,
3233 0x020c020c,
3234 0x0000014d,
3235 0x020c020c,
3236 0x0000014d,
3237 0x020c020c,
3238 0x0000014d,
3239 0x020c020c,
3240 0x0000014d,
3241 0x020c020c,
3242 0x0000014d,
3243 0x020c020c,
3244 0x0000014d,
3245 0x020c020c,
3246 0x0000014d,
3247 0x020c020c,
3248 0x0000014d,
3249 0x020c020c,
3250 0x0000014d,
3251 0x020c020c,
3252 0x0000014d,
3253 0x020c020c,
3254 0x0000014d,
3255};
3256
3257const u8 est_pwr_lut_core0_rev0[] = {
3258 0x50,
3259 0x4f,
3260 0x4e,
3261 0x4d,
3262 0x4c,
3263 0x4b,
3264 0x4a,
3265 0x49,
3266 0x48,
3267 0x47,
3268 0x46,
3269 0x45,
3270 0x44,
3271 0x43,
3272 0x42,
3273 0x41,
3274 0x40,
3275 0x3f,
3276 0x3e,
3277 0x3d,
3278 0x3c,
3279 0x3b,
3280 0x3a,
3281 0x39,
3282 0x38,
3283 0x37,
3284 0x36,
3285 0x35,
3286 0x34,
3287 0x33,
3288 0x32,
3289 0x31,
3290 0x30,
3291 0x2f,
3292 0x2e,
3293 0x2d,
3294 0x2c,
3295 0x2b,
3296 0x2a,
3297 0x29,
3298 0x28,
3299 0x27,
3300 0x26,
3301 0x25,
3302 0x24,
3303 0x23,
3304 0x22,
3305 0x21,
3306 0x20,
3307 0x1f,
3308 0x1e,
3309 0x1d,
3310 0x1c,
3311 0x1b,
3312 0x1a,
3313 0x19,
3314 0x18,
3315 0x17,
3316 0x16,
3317 0x15,
3318 0x14,
3319 0x13,
3320 0x12,
3321 0x11,
3322};
3323
3324const u8 est_pwr_lut_core1_rev0[] = {
3325 0x50,
3326 0x4f,
3327 0x4e,
3328 0x4d,
3329 0x4c,
3330 0x4b,
3331 0x4a,
3332 0x49,
3333 0x48,
3334 0x47,
3335 0x46,
3336 0x45,
3337 0x44,
3338 0x43,
3339 0x42,
3340 0x41,
3341 0x40,
3342 0x3f,
3343 0x3e,
3344 0x3d,
3345 0x3c,
3346 0x3b,
3347 0x3a,
3348 0x39,
3349 0x38,
3350 0x37,
3351 0x36,
3352 0x35,
3353 0x34,
3354 0x33,
3355 0x32,
3356 0x31,
3357 0x30,
3358 0x2f,
3359 0x2e,
3360 0x2d,
3361 0x2c,
3362 0x2b,
3363 0x2a,
3364 0x29,
3365 0x28,
3366 0x27,
3367 0x26,
3368 0x25,
3369 0x24,
3370 0x23,
3371 0x22,
3372 0x21,
3373 0x20,
3374 0x1f,
3375 0x1e,
3376 0x1d,
3377 0x1c,
3378 0x1b,
3379 0x1a,
3380 0x19,
3381 0x18,
3382 0x17,
3383 0x16,
3384 0x15,
3385 0x14,
3386 0x13,
3387 0x12,
3388 0x11,
3389};
3390
3391const u8 adj_pwr_lut_core0_rev0[] = {
3392 0x00,
3393 0x00,
3394 0x00,
3395 0x00,
3396 0x00,
3397 0x00,
3398 0x00,
3399 0x00,
3400 0x00,
3401 0x00,
3402 0x00,
3403 0x00,
3404 0x00,
3405 0x00,
3406 0x00,
3407 0x00,
3408 0x00,
3409 0x00,
3410 0x00,
3411 0x00,
3412 0x00,
3413 0x00,
3414 0x00,
3415 0x00,
3416 0x00,
3417 0x00,
3418 0x00,
3419 0x00,
3420 0x00,
3421 0x00,
3422 0x00,
3423 0x00,
3424 0x00,
3425 0x00,
3426 0x00,
3427 0x00,
3428 0x00,
3429 0x00,
3430 0x00,
3431 0x00,
3432 0x00,
3433 0x00,
3434 0x00,
3435 0x00,
3436 0x00,
3437 0x00,
3438 0x00,
3439 0x00,
3440 0x00,
3441 0x00,
3442 0x00,
3443 0x00,
3444 0x00,
3445 0x00,
3446 0x00,
3447 0x00,
3448 0x00,
3449 0x00,
3450 0x00,
3451 0x00,
3452 0x00,
3453 0x00,
3454 0x00,
3455 0x00,
3456 0x00,
3457 0x00,
3458 0x00,
3459 0x00,
3460 0x00,
3461 0x00,
3462 0x00,
3463 0x00,
3464 0x00,
3465 0x00,
3466 0x00,
3467 0x00,
3468 0x00,
3469 0x00,
3470 0x00,
3471 0x00,
3472 0x00,
3473 0x00,
3474 0x00,
3475 0x00,
3476 0x00,
3477 0x00,
3478 0x00,
3479 0x00,
3480 0x00,
3481 0x00,
3482 0x00,
3483 0x00,
3484 0x00,
3485 0x00,
3486 0x00,
3487 0x00,
3488 0x00,
3489 0x00,
3490 0x00,
3491 0x00,
3492 0x00,
3493 0x00,
3494 0x00,
3495 0x00,
3496 0x00,
3497 0x00,
3498 0x00,
3499 0x00,
3500 0x00,
3501 0x00,
3502 0x00,
3503 0x00,
3504 0x00,
3505 0x00,
3506 0x00,
3507 0x00,
3508 0x00,
3509 0x00,
3510 0x00,
3511 0x00,
3512 0x00,
3513 0x00,
3514 0x00,
3515 0x00,
3516 0x00,
3517 0x00,
3518 0x00,
3519 0x00,
3520};
3521
3522const u8 adj_pwr_lut_core1_rev0[] = {
3523 0x00,
3524 0x00,
3525 0x00,
3526 0x00,
3527 0x00,
3528 0x00,
3529 0x00,
3530 0x00,
3531 0x00,
3532 0x00,
3533 0x00,
3534 0x00,
3535 0x00,
3536 0x00,
3537 0x00,
3538 0x00,
3539 0x00,
3540 0x00,
3541 0x00,
3542 0x00,
3543 0x00,
3544 0x00,
3545 0x00,
3546 0x00,
3547 0x00,
3548 0x00,
3549 0x00,
3550 0x00,
3551 0x00,
3552 0x00,
3553 0x00,
3554 0x00,
3555 0x00,
3556 0x00,
3557 0x00,
3558 0x00,
3559 0x00,
3560 0x00,
3561 0x00,
3562 0x00,
3563 0x00,
3564 0x00,
3565 0x00,
3566 0x00,
3567 0x00,
3568 0x00,
3569 0x00,
3570 0x00,
3571 0x00,
3572 0x00,
3573 0x00,
3574 0x00,
3575 0x00,
3576 0x00,
3577 0x00,
3578 0x00,
3579 0x00,
3580 0x00,
3581 0x00,
3582 0x00,
3583 0x00,
3584 0x00,
3585 0x00,
3586 0x00,
3587 0x00,
3588 0x00,
3589 0x00,
3590 0x00,
3591 0x00,
3592 0x00,
3593 0x00,
3594 0x00,
3595 0x00,
3596 0x00,
3597 0x00,
3598 0x00,
3599 0x00,
3600 0x00,
3601 0x00,
3602 0x00,
3603 0x00,
3604 0x00,
3605 0x00,
3606 0x00,
3607 0x00,
3608 0x00,
3609 0x00,
3610 0x00,
3611 0x00,
3612 0x00,
3613 0x00,
3614 0x00,
3615 0x00,
3616 0x00,
3617 0x00,
3618 0x00,
3619 0x00,
3620 0x00,
3621 0x00,
3622 0x00,
3623 0x00,
3624 0x00,
3625 0x00,
3626 0x00,
3627 0x00,
3628 0x00,
3629 0x00,
3630 0x00,
3631 0x00,
3632 0x00,
3633 0x00,
3634 0x00,
3635 0x00,
3636 0x00,
3637 0x00,
3638 0x00,
3639 0x00,
3640 0x00,
3641 0x00,
3642 0x00,
3643 0x00,
3644 0x00,
3645 0x00,
3646 0x00,
3647 0x00,
3648 0x00,
3649 0x00,
3650 0x00,
3651};
3652
3653const u32 gainctrl_lut_core0_rev0[] = {
3654 0x03cc2b44,
3655 0x03cc2b42,
3656 0x03cc2b40,
3657 0x03cc2b3e,
3658 0x03cc2b3d,
3659 0x03cc2b3b,
3660 0x03c82b44,
3661 0x03c82b42,
3662 0x03c82b40,
3663 0x03c82b3e,
3664 0x03c82b3d,
3665 0x03c82b3b,
3666 0x03c82b39,
3667 0x03c82b38,
3668 0x03c82b36,
3669 0x03c82b34,
3670 0x03c42b44,
3671 0x03c42b42,
3672 0x03c42b40,
3673 0x03c42b3e,
3674 0x03c42b3d,
3675 0x03c42b3b,
3676 0x03c42b39,
3677 0x03c42b38,
3678 0x03c42b36,
3679 0x03c42b34,
3680 0x03c42b33,
3681 0x03c42b32,
3682 0x03c42b30,
3683 0x03c42b2f,
3684 0x03c42b2d,
3685 0x03c02b44,
3686 0x03c02b42,
3687 0x03c02b40,
3688 0x03c02b3e,
3689 0x03c02b3d,
3690 0x03c02b3b,
3691 0x03c02b39,
3692 0x03c02b38,
3693 0x03c02b36,
3694 0x03c02b34,
3695 0x03b02b44,
3696 0x03b02b42,
3697 0x03b02b40,
3698 0x03b02b3e,
3699 0x03b02b3d,
3700 0x03b02b3b,
3701 0x03b02b39,
3702 0x03b02b38,
3703 0x03b02b36,
3704 0x03b02b34,
3705 0x03b02b33,
3706 0x03b02b32,
3707 0x03b02b30,
3708 0x03b02b2f,
3709 0x03b02b2d,
3710 0x03a02b44,
3711 0x03a02b42,
3712 0x03a02b40,
3713 0x03a02b3e,
3714 0x03a02b3d,
3715 0x03a02b3b,
3716 0x03a02b39,
3717 0x03a02b38,
3718 0x03a02b36,
3719 0x03a02b34,
3720 0x03902b44,
3721 0x03902b42,
3722 0x03902b40,
3723 0x03902b3e,
3724 0x03902b3d,
3725 0x03902b3b,
3726 0x03902b39,
3727 0x03902b38,
3728 0x03902b36,
3729 0x03902b34,
3730 0x03902b33,
3731 0x03902b32,
3732 0x03902b30,
3733 0x03802b44,
3734 0x03802b42,
3735 0x03802b40,
3736 0x03802b3e,
3737 0x03802b3d,
3738 0x03802b3b,
3739 0x03802b39,
3740 0x03802b38,
3741 0x03802b36,
3742 0x03802b34,
3743 0x03802b33,
3744 0x03802b32,
3745 0x03802b30,
3746 0x03802b2f,
3747 0x03802b2d,
3748 0x03802b2c,
3749 0x03802b2b,
3750 0x03802b2a,
3751 0x03802b29,
3752 0x03802b27,
3753 0x03802b26,
3754 0x03802b25,
3755 0x03802b24,
3756 0x03802b23,
3757 0x03802b22,
3758 0x03802b21,
3759 0x03802b20,
3760 0x03802b1f,
3761 0x03802b1e,
3762 0x03802b1e,
3763 0x03802b1d,
3764 0x03802b1c,
3765 0x03802b1b,
3766 0x03802b1a,
3767 0x03802b1a,
3768 0x03802b19,
3769 0x03802b18,
3770 0x03802b18,
3771 0x03802b18,
3772 0x03802b18,
3773 0x03802b18,
3774 0x03802b18,
3775 0x03802b18,
3776 0x03802b18,
3777 0x03802b18,
3778 0x03802b18,
3779 0x03802b18,
3780 0x03802b18,
3781 0x00002b00,
3782};
3783
3784const u32 gainctrl_lut_core1_rev0[] = {
3785 0x03cc2b44,
3786 0x03cc2b42,
3787 0x03cc2b40,
3788 0x03cc2b3e,
3789 0x03cc2b3d,
3790 0x03cc2b3b,
3791 0x03c82b44,
3792 0x03c82b42,
3793 0x03c82b40,
3794 0x03c82b3e,
3795 0x03c82b3d,
3796 0x03c82b3b,
3797 0x03c82b39,
3798 0x03c82b38,
3799 0x03c82b36,
3800 0x03c82b34,
3801 0x03c42b44,
3802 0x03c42b42,
3803 0x03c42b40,
3804 0x03c42b3e,
3805 0x03c42b3d,
3806 0x03c42b3b,
3807 0x03c42b39,
3808 0x03c42b38,
3809 0x03c42b36,
3810 0x03c42b34,
3811 0x03c42b33,
3812 0x03c42b32,
3813 0x03c42b30,
3814 0x03c42b2f,
3815 0x03c42b2d,
3816 0x03c02b44,
3817 0x03c02b42,
3818 0x03c02b40,
3819 0x03c02b3e,
3820 0x03c02b3d,
3821 0x03c02b3b,
3822 0x03c02b39,
3823 0x03c02b38,
3824 0x03c02b36,
3825 0x03c02b34,
3826 0x03b02b44,
3827 0x03b02b42,
3828 0x03b02b40,
3829 0x03b02b3e,
3830 0x03b02b3d,
3831 0x03b02b3b,
3832 0x03b02b39,
3833 0x03b02b38,
3834 0x03b02b36,
3835 0x03b02b34,
3836 0x03b02b33,
3837 0x03b02b32,
3838 0x03b02b30,
3839 0x03b02b2f,
3840 0x03b02b2d,
3841 0x03a02b44,
3842 0x03a02b42,
3843 0x03a02b40,
3844 0x03a02b3e,
3845 0x03a02b3d,
3846 0x03a02b3b,
3847 0x03a02b39,
3848 0x03a02b38,
3849 0x03a02b36,
3850 0x03a02b34,
3851 0x03902b44,
3852 0x03902b42,
3853 0x03902b40,
3854 0x03902b3e,
3855 0x03902b3d,
3856 0x03902b3b,
3857 0x03902b39,
3858 0x03902b38,
3859 0x03902b36,
3860 0x03902b34,
3861 0x03902b33,
3862 0x03902b32,
3863 0x03902b30,
3864 0x03802b44,
3865 0x03802b42,
3866 0x03802b40,
3867 0x03802b3e,
3868 0x03802b3d,
3869 0x03802b3b,
3870 0x03802b39,
3871 0x03802b38,
3872 0x03802b36,
3873 0x03802b34,
3874 0x03802b33,
3875 0x03802b32,
3876 0x03802b30,
3877 0x03802b2f,
3878 0x03802b2d,
3879 0x03802b2c,
3880 0x03802b2b,
3881 0x03802b2a,
3882 0x03802b29,
3883 0x03802b27,
3884 0x03802b26,
3885 0x03802b25,
3886 0x03802b24,
3887 0x03802b23,
3888 0x03802b22,
3889 0x03802b21,
3890 0x03802b20,
3891 0x03802b1f,
3892 0x03802b1e,
3893 0x03802b1e,
3894 0x03802b1d,
3895 0x03802b1c,
3896 0x03802b1b,
3897 0x03802b1a,
3898 0x03802b1a,
3899 0x03802b19,
3900 0x03802b18,
3901 0x03802b18,
3902 0x03802b18,
3903 0x03802b18,
3904 0x03802b18,
3905 0x03802b18,
3906 0x03802b18,
3907 0x03802b18,
3908 0x03802b18,
3909 0x03802b18,
3910 0x03802b18,
3911 0x03802b18,
3912 0x00002b00,
3913};
3914
3915const u32 iq_lut_core0_rev0[] = {
3916 0x0000007f,
3917 0x0000007f,
3918 0x0000007f,
3919 0x0000007f,
3920 0x0000007f,
3921 0x0000007f,
3922 0x0000007f,
3923 0x0000007f,
3924 0x0000007f,
3925 0x0000007f,
3926 0x0000007f,
3927 0x0000007f,
3928 0x0000007f,
3929 0x0000007f,
3930 0x0000007f,
3931 0x0000007f,
3932 0x0000007f,
3933 0x0000007f,
3934 0x0000007f,
3935 0x0000007f,
3936 0x0000007f,
3937 0x0000007f,
3938 0x0000007f,
3939 0x0000007f,
3940 0x0000007f,
3941 0x0000007f,
3942 0x0000007f,
3943 0x0000007f,
3944 0x0000007f,
3945 0x0000007f,
3946 0x0000007f,
3947 0x0000007f,
3948 0x0000007f,
3949 0x0000007f,
3950 0x0000007f,
3951 0x0000007f,
3952 0x0000007f,
3953 0x0000007f,
3954 0x0000007f,
3955 0x0000007f,
3956 0x0000007f,
3957 0x0000007f,
3958 0x0000007f,
3959 0x0000007f,
3960 0x0000007f,
3961 0x0000007f,
3962 0x0000007f,
3963 0x0000007f,
3964 0x0000007f,
3965 0x0000007f,
3966 0x0000007f,
3967 0x0000007f,
3968 0x0000007f,
3969 0x0000007f,
3970 0x0000007f,
3971 0x0000007f,
3972 0x0000007f,
3973 0x0000007f,
3974 0x0000007f,
3975 0x0000007f,
3976 0x0000007f,
3977 0x0000007f,
3978 0x0000007f,
3979 0x0000007f,
3980 0x0000007f,
3981 0x0000007f,
3982 0x0000007f,
3983 0x0000007f,
3984 0x0000007f,
3985 0x0000007f,
3986 0x0000007f,
3987 0x0000007f,
3988 0x0000007f,
3989 0x0000007f,
3990 0x0000007f,
3991 0x0000007f,
3992 0x0000007f,
3993 0x0000007f,
3994 0x0000007f,
3995 0x0000007f,
3996 0x0000007f,
3997 0x0000007f,
3998 0x0000007f,
3999 0x0000007f,
4000 0x0000007f,
4001 0x0000007f,
4002 0x0000007f,
4003 0x0000007f,
4004 0x0000007f,
4005 0x0000007f,
4006 0x0000007f,
4007 0x0000007f,
4008 0x0000007f,
4009 0x0000007f,
4010 0x0000007f,
4011 0x0000007f,
4012 0x0000007f,
4013 0x0000007f,
4014 0x0000007f,
4015 0x0000007f,
4016 0x0000007f,
4017 0x0000007f,
4018 0x0000007f,
4019 0x0000007f,
4020 0x0000007f,
4021 0x0000007f,
4022 0x0000007f,
4023 0x0000007f,
4024 0x0000007f,
4025 0x0000007f,
4026 0x0000007f,
4027 0x0000007f,
4028 0x0000007f,
4029 0x0000007f,
4030 0x0000007f,
4031 0x0000007f,
4032 0x0000007f,
4033 0x0000007f,
4034 0x0000007f,
4035 0x0000007f,
4036 0x0000007f,
4037 0x0000007f,
4038 0x0000007f,
4039 0x0000007f,
4040 0x0000007f,
4041 0x0000007f,
4042 0x0000007f,
4043 0x0000007f,
4044};
4045
4046const u32 iq_lut_core1_rev0[] = {
4047 0x0000007f,
4048 0x0000007f,
4049 0x0000007f,
4050 0x0000007f,
4051 0x0000007f,
4052 0x0000007f,
4053 0x0000007f,
4054 0x0000007f,
4055 0x0000007f,
4056 0x0000007f,
4057 0x0000007f,
4058 0x0000007f,
4059 0x0000007f,
4060 0x0000007f,
4061 0x0000007f,
4062 0x0000007f,
4063 0x0000007f,
4064 0x0000007f,
4065 0x0000007f,
4066 0x0000007f,
4067 0x0000007f,
4068 0x0000007f,
4069 0x0000007f,
4070 0x0000007f,
4071 0x0000007f,
4072 0x0000007f,
4073 0x0000007f,
4074 0x0000007f,
4075 0x0000007f,
4076 0x0000007f,
4077 0x0000007f,
4078 0x0000007f,
4079 0x0000007f,
4080 0x0000007f,
4081 0x0000007f,
4082 0x0000007f,
4083 0x0000007f,
4084 0x0000007f,
4085 0x0000007f,
4086 0x0000007f,
4087 0x0000007f,
4088 0x0000007f,
4089 0x0000007f,
4090 0x0000007f,
4091 0x0000007f,
4092 0x0000007f,
4093 0x0000007f,
4094 0x0000007f,
4095 0x0000007f,
4096 0x0000007f,
4097 0x0000007f,
4098 0x0000007f,
4099 0x0000007f,
4100 0x0000007f,
4101 0x0000007f,
4102 0x0000007f,
4103 0x0000007f,
4104 0x0000007f,
4105 0x0000007f,
4106 0x0000007f,
4107 0x0000007f,
4108 0x0000007f,
4109 0x0000007f,
4110 0x0000007f,
4111 0x0000007f,
4112 0x0000007f,
4113 0x0000007f,
4114 0x0000007f,
4115 0x0000007f,
4116 0x0000007f,
4117 0x0000007f,
4118 0x0000007f,
4119 0x0000007f,
4120 0x0000007f,
4121 0x0000007f,
4122 0x0000007f,
4123 0x0000007f,
4124 0x0000007f,
4125 0x0000007f,
4126 0x0000007f,
4127 0x0000007f,
4128 0x0000007f,
4129 0x0000007f,
4130 0x0000007f,
4131 0x0000007f,
4132 0x0000007f,
4133 0x0000007f,
4134 0x0000007f,
4135 0x0000007f,
4136 0x0000007f,
4137 0x0000007f,
4138 0x0000007f,
4139 0x0000007f,
4140 0x0000007f,
4141 0x0000007f,
4142 0x0000007f,
4143 0x0000007f,
4144 0x0000007f,
4145 0x0000007f,
4146 0x0000007f,
4147 0x0000007f,
4148 0x0000007f,
4149 0x0000007f,
4150 0x0000007f,
4151 0x0000007f,
4152 0x0000007f,
4153 0x0000007f,
4154 0x0000007f,
4155 0x0000007f,
4156 0x0000007f,
4157 0x0000007f,
4158 0x0000007f,
4159 0x0000007f,
4160 0x0000007f,
4161 0x0000007f,
4162 0x0000007f,
4163 0x0000007f,
4164 0x0000007f,
4165 0x0000007f,
4166 0x0000007f,
4167 0x0000007f,
4168 0x0000007f,
4169 0x0000007f,
4170 0x0000007f,
4171 0x0000007f,
4172 0x0000007f,
4173 0x0000007f,
4174 0x0000007f,
4175};
4176
4177const u16 loft_lut_core0_rev0[] = {
4178 0x0000,
4179 0x0101,
4180 0x0002,
4181 0x0103,
4182 0x0000,
4183 0x0101,
4184 0x0002,
4185 0x0103,
4186 0x0000,
4187 0x0101,
4188 0x0002,
4189 0x0103,
4190 0x0000,
4191 0x0101,
4192 0x0002,
4193 0x0103,
4194 0x0000,
4195 0x0101,
4196 0x0002,
4197 0x0103,
4198 0x0000,
4199 0x0101,
4200 0x0002,
4201 0x0103,
4202 0x0000,
4203 0x0101,
4204 0x0002,
4205 0x0103,
4206 0x0000,
4207 0x0101,
4208 0x0002,
4209 0x0103,
4210 0x0000,
4211 0x0101,
4212 0x0002,
4213 0x0103,
4214 0x0000,
4215 0x0101,
4216 0x0002,
4217 0x0103,
4218 0x0000,
4219 0x0101,
4220 0x0002,
4221 0x0103,
4222 0x0000,
4223 0x0101,
4224 0x0002,
4225 0x0103,
4226 0x0000,
4227 0x0101,
4228 0x0002,
4229 0x0103,
4230 0x0000,
4231 0x0101,
4232 0x0002,
4233 0x0103,
4234 0x0000,
4235 0x0101,
4236 0x0002,
4237 0x0103,
4238 0x0000,
4239 0x0101,
4240 0x0002,
4241 0x0103,
4242 0x0000,
4243 0x0101,
4244 0x0002,
4245 0x0103,
4246 0x0000,
4247 0x0101,
4248 0x0002,
4249 0x0103,
4250 0x0000,
4251 0x0101,
4252 0x0002,
4253 0x0103,
4254 0x0000,
4255 0x0101,
4256 0x0002,
4257 0x0103,
4258 0x0000,
4259 0x0101,
4260 0x0002,
4261 0x0103,
4262 0x0000,
4263 0x0101,
4264 0x0002,
4265 0x0103,
4266 0x0000,
4267 0x0101,
4268 0x0002,
4269 0x0103,
4270 0x0000,
4271 0x0101,
4272 0x0002,
4273 0x0103,
4274 0x0000,
4275 0x0101,
4276 0x0002,
4277 0x0103,
4278 0x0000,
4279 0x0101,
4280 0x0002,
4281 0x0103,
4282 0x0000,
4283 0x0101,
4284 0x0002,
4285 0x0103,
4286 0x0000,
4287 0x0101,
4288 0x0002,
4289 0x0103,
4290 0x0000,
4291 0x0101,
4292 0x0002,
4293 0x0103,
4294 0x0000,
4295 0x0101,
4296 0x0002,
4297 0x0103,
4298 0x0000,
4299 0x0101,
4300 0x0002,
4301 0x0103,
4302 0x0000,
4303 0x0101,
4304 0x0002,
4305 0x0103,
4306};
4307
4308const u16 loft_lut_core1_rev0[] = {
4309 0x0000,
4310 0x0101,
4311 0x0002,
4312 0x0103,
4313 0x0000,
4314 0x0101,
4315 0x0002,
4316 0x0103,
4317 0x0000,
4318 0x0101,
4319 0x0002,
4320 0x0103,
4321 0x0000,
4322 0x0101,
4323 0x0002,
4324 0x0103,
4325 0x0000,
4326 0x0101,
4327 0x0002,
4328 0x0103,
4329 0x0000,
4330 0x0101,
4331 0x0002,
4332 0x0103,
4333 0x0000,
4334 0x0101,
4335 0x0002,
4336 0x0103,
4337 0x0000,
4338 0x0101,
4339 0x0002,
4340 0x0103,
4341 0x0000,
4342 0x0101,
4343 0x0002,
4344 0x0103,
4345 0x0000,
4346 0x0101,
4347 0x0002,
4348 0x0103,
4349 0x0000,
4350 0x0101,
4351 0x0002,
4352 0x0103,
4353 0x0000,
4354 0x0101,
4355 0x0002,
4356 0x0103,
4357 0x0000,
4358 0x0101,
4359 0x0002,
4360 0x0103,
4361 0x0000,
4362 0x0101,
4363 0x0002,
4364 0x0103,
4365 0x0000,
4366 0x0101,
4367 0x0002,
4368 0x0103,
4369 0x0000,
4370 0x0101,
4371 0x0002,
4372 0x0103,
4373 0x0000,
4374 0x0101,
4375 0x0002,
4376 0x0103,
4377 0x0000,
4378 0x0101,
4379 0x0002,
4380 0x0103,
4381 0x0000,
4382 0x0101,
4383 0x0002,
4384 0x0103,
4385 0x0000,
4386 0x0101,
4387 0x0002,
4388 0x0103,
4389 0x0000,
4390 0x0101,
4391 0x0002,
4392 0x0103,
4393 0x0000,
4394 0x0101,
4395 0x0002,
4396 0x0103,
4397 0x0000,
4398 0x0101,
4399 0x0002,
4400 0x0103,
4401 0x0000,
4402 0x0101,
4403 0x0002,
4404 0x0103,
4405 0x0000,
4406 0x0101,
4407 0x0002,
4408 0x0103,
4409 0x0000,
4410 0x0101,
4411 0x0002,
4412 0x0103,
4413 0x0000,
4414 0x0101,
4415 0x0002,
4416 0x0103,
4417 0x0000,
4418 0x0101,
4419 0x0002,
4420 0x0103,
4421 0x0000,
4422 0x0101,
4423 0x0002,
4424 0x0103,
4425 0x0000,
4426 0x0101,
4427 0x0002,
4428 0x0103,
4429 0x0000,
4430 0x0101,
4431 0x0002,
4432 0x0103,
4433 0x0000,
4434 0x0101,
4435 0x0002,
4436 0x0103,
4437};
4438
4439const struct phytbl_info mimophytbl_info_rev0_volatile[] = {
4440 {&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0,
4441 16}
4442 ,
4443 {&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]),
4444 20, 0, 32}
4445 ,
4446 {&gainctrl_lut_core0_rev0,
4447 sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]),
4448 26, 192, 32}
4449 ,
4450 {&gainctrl_lut_core1_rev0,
4451 sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]),
4452 27, 192, 32}
4453 ,
4454
4455 {&est_pwr_lut_core0_rev0,
4456 sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26,
4457 0, 8}
4458 ,
4459 {&est_pwr_lut_core1_rev0,
4460 sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27,
4461 0, 8}
4462 ,
4463 {&adj_pwr_lut_core0_rev0,
4464 sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26,
4465 64, 8}
4466 ,
4467 {&adj_pwr_lut_core1_rev0,
4468 sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27,
4469 64, 8}
4470 ,
4471 {&iq_lut_core0_rev0,
4472 sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32}
4473 ,
4474 {&iq_lut_core1_rev0,
4475 sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32}
4476 ,
4477 {&loft_lut_core0_rev0,
4478 sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448,
4479 16}
4480 ,
4481 {&loft_lut_core1_rev0,
4482 sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448,
4483 16}
4484 ,
4485};
4486
4487const struct phytbl_info mimophytbl_info_rev0[] = {
4488 {&frame_struct_rev0,
4489 sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32}
4490 ,
4491 {&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]),
4492 24, 0, 8}
4493 ,
4494 {&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12,
4495 0, 32}
4496 ,
4497 {&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]),
4498 14, 0, 32}
4499 ,
4500 {&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]),
4501 13, 0, 32}
4502 ,
4503 {&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]),
4504 11, 0, 16}
4505 ,
4506 {&tdi_tbl20_ant0_rev0,
4507 sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128,
4508 32}
4509 ,
4510 {&tdi_tbl20_ant1_rev0,
4511 sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256,
4512 32}
4513 ,
4514 {&tdi_tbl40_ant0_rev0,
4515 sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640,
4516 32}
4517 ,
4518 {&tdi_tbl40_ant1_rev0,
4519 sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768,
4520 32}
4521 ,
4522 {&chanest_tbl_rev0,
4523 sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32}
4524 ,
4525 {&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, 8}
4526 ,
4527 {&noise_var_tbl0_rev0,
4528 sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0,
4529 32}
4530 ,
4531 {&noise_var_tbl1_rev0,
4532 sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128,
4533 32}
4534 ,
4535};
4536
4537const u32 mimophytbl_info_sz_rev0 =
4538 sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]);
4539const u32 mimophytbl_info_sz_rev0_volatile =
4540 sizeof(mimophytbl_info_rev0_volatile) /
4541 sizeof(mimophytbl_info_rev0_volatile[0]);
4542
4543const u16 ant_swctrl_tbl_rev3[] = {
4544 0x0082,
4545 0x0082,
4546 0x0211,
4547 0x0222,
4548 0x0328,
4549 0x0000,
4550 0x0000,
4551 0x0000,
4552 0x0144,
4553 0x0000,
4554 0x0000,
4555 0x0000,
4556 0x0188,
4557 0x0000,
4558 0x0000,
4559 0x0000,
4560 0x0082,
4561 0x0082,
4562 0x0211,
4563 0x0222,
4564 0x0328,
4565 0x0000,
4566 0x0000,
4567 0x0000,
4568 0x0144,
4569 0x0000,
4570 0x0000,
4571 0x0000,
4572 0x0188,
4573 0x0000,
4574 0x0000,
4575 0x0000,
4576};
4577
4578const u16 ant_swctrl_tbl_rev3_1[] = {
4579 0x0022,
4580 0x0022,
4581 0x0011,
4582 0x0022,
4583 0x0022,
4584 0x0000,
4585 0x0000,
4586 0x0000,
4587 0x0011,
4588 0x0000,
4589 0x0000,
4590 0x0000,
4591 0x0022,
4592 0x0000,
4593 0x0000,
4594 0x0000,
4595 0x0022,
4596 0x0022,
4597 0x0011,
4598 0x0022,
4599 0x0022,
4600 0x0000,
4601 0x0000,
4602 0x0000,
4603 0x0011,
4604 0x0000,
4605 0x0000,
4606 0x0000,
4607 0x0022,
4608 0x0000,
4609 0x0000,
4610 0x0000,
4611};
4612
4613const u16 ant_swctrl_tbl_rev3_2[] = {
4614 0x0088,
4615 0x0088,
4616 0x0044,
4617 0x0088,
4618 0x0088,
4619 0x0000,
4620 0x0000,
4621 0x0000,
4622 0x0044,
4623 0x0000,
4624 0x0000,
4625 0x0000,
4626 0x0088,
4627 0x0000,
4628 0x0000,
4629 0x0000,
4630 0x0088,
4631 0x0088,
4632 0x0044,
4633 0x0088,
4634 0x0088,
4635 0x0000,
4636 0x0000,
4637 0x0000,
4638 0x0044,
4639 0x0000,
4640 0x0000,
4641 0x0000,
4642 0x0088,
4643 0x0000,
4644 0x0000,
4645 0x0000,
4646};
4647
4648const u16 ant_swctrl_tbl_rev3_3[] = {
4649 0x022,
4650 0x022,
4651 0x011,
4652 0x022,
4653 0x000,
4654 0x000,
4655 0x000,
4656 0x000,
4657 0x011,
4658 0x000,
4659 0x000,
4660 0x000,
4661 0x022,
4662 0x000,
4663 0x000,
4664 0x3cc,
4665 0x022,
4666 0x022,
4667 0x011,
4668 0x022,
4669 0x000,
4670 0x000,
4671 0x000,
4672 0x000,
4673 0x011,
4674 0x000,
4675 0x000,
4676 0x000,
4677 0x022,
4678 0x000,
4679 0x000,
4680 0x3cc
4681};
4682
4683const u32 frame_struct_rev3[] = {
4684 0x08004a04,
4685 0x00100000,
4686 0x01000a05,
4687 0x00100020,
4688 0x09804506,
4689 0x00100030,
4690 0x09804507,
4691 0x00100030,
4692 0x00000000,
4693 0x00000000,
4694 0x00000000,
4695 0x00000000,
4696 0x00000000,
4697 0x00000000,
4698 0x00000000,
4699 0x00000000,
4700 0x08004a0c,
4701 0x00100004,
4702 0x01000a0d,
4703 0x00100024,
4704 0x0980450e,
4705 0x00100034,
4706 0x0980450f,
4707 0x00100034,
4708 0x00000000,
4709 0x00000000,
4710 0x00000000,
4711 0x00000000,
4712 0x00000000,
4713 0x00000000,
4714 0x00000000,
4715 0x00000000,
4716 0x00000a04,
4717 0x00100000,
4718 0x11008a05,
4719 0x00100020,
4720 0x1980c506,
4721 0x00100030,
4722 0x21810506,
4723 0x00100030,
4724 0x21810506,
4725 0x00100030,
4726 0x01800504,
4727 0x00100030,
4728 0x11808505,
4729 0x00100030,
4730 0x29814507,
4731 0x01100030,
4732 0x00000a04,
4733 0x00100000,
4734 0x11008a05,
4735 0x00100020,
4736 0x21810506,
4737 0x00100030,
4738 0x21810506,
4739 0x00100030,
4740 0x29814507,
4741 0x01100030,
4742 0x00000000,
4743 0x00000000,
4744 0x00000000,
4745 0x00000000,
4746 0x00000000,
4747 0x00000000,
4748 0x00000a0c,
4749 0x00100008,
4750 0x11008a0d,
4751 0x00100028,
4752 0x1980c50e,
4753 0x00100038,
4754 0x2181050e,
4755 0x00100038,
4756 0x2181050e,
4757 0x00100038,
4758 0x0180050c,
4759 0x00100038,
4760 0x1180850d,
4761 0x00100038,
4762 0x2981450f,
4763 0x01100038,
4764 0x00000a0c,
4765 0x00100008,
4766 0x11008a0d,
4767 0x00100028,
4768 0x2181050e,
4769 0x00100038,
4770 0x2181050e,
4771 0x00100038,
4772 0x2981450f,
4773 0x01100038,
4774 0x00000000,
4775 0x00000000,
4776 0x00000000,
4777 0x00000000,
4778 0x00000000,
4779 0x00000000,
4780 0x08004a04,
4781 0x00100000,
4782 0x01000a05,
4783 0x00100020,
4784 0x1980c506,
4785 0x00100030,
4786 0x1980c506,
4787 0x00100030,
4788 0x11808504,
4789 0x00100030,
4790 0x3981ca05,
4791 0x00100030,
4792 0x29814507,
4793 0x01100030,
4794 0x00000000,
4795 0x00000000,
4796 0x10008a04,
4797 0x00100000,
4798 0x3981ca05,
4799 0x00100030,
4800 0x1980c506,
4801 0x00100030,
4802 0x29814507,
4803 0x01100030,
4804 0x00000000,
4805 0x00000000,
4806 0x00000000,
4807 0x00000000,
4808 0x00000000,
4809 0x00000000,
4810 0x00000000,
4811 0x00000000,
4812 0x08004a0c,
4813 0x00100008,
4814 0x01000a0d,
4815 0x00100028,
4816 0x1980c50e,
4817 0x00100038,
4818 0x1980c50e,
4819 0x00100038,
4820 0x1180850c,
4821 0x00100038,
4822 0x3981ca0d,
4823 0x00100038,
4824 0x2981450f,
4825 0x01100038,
4826 0x00000000,
4827 0x00000000,
4828 0x10008a0c,
4829 0x00100008,
4830 0x3981ca0d,
4831 0x00100038,
4832 0x1980c50e,
4833 0x00100038,
4834 0x2981450f,
4835 0x01100038,
4836 0x00000000,
4837 0x00000000,
4838 0x00000000,
4839 0x00000000,
4840 0x00000000,
4841 0x00000000,
4842 0x00000000,
4843 0x00000000,
4844 0x40021404,
4845 0x00100000,
4846 0x02001405,
4847 0x00100040,
4848 0x0b004a06,
4849 0x01900060,
4850 0x13008a06,
4851 0x01900060,
4852 0x13008a06,
4853 0x01900060,
4854 0x43020a04,
4855 0x00100060,
4856 0x1b00ca05,
4857 0x00100060,
4858 0x23010a07,
4859 0x01500060,
4860 0x40021404,
4861 0x00100000,
4862 0x1a00d405,
4863 0x00100040,
4864 0x13008a06,
4865 0x01900060,
4866 0x13008a06,
4867 0x01900060,
4868 0x23010a07,
4869 0x01500060,
4870 0x00000000,
4871 0x00000000,
4872 0x00000000,
4873 0x00000000,
4874 0x00000000,
4875 0x00000000,
4876 0x4002140c,
4877 0x00100010,
4878 0x0200140d,
4879 0x00100050,
4880 0x0b004a0e,
4881 0x01900070,
4882 0x13008a0e,
4883 0x01900070,
4884 0x13008a0e,
4885 0x01900070,
4886 0x43020a0c,
4887 0x00100070,
4888 0x1b00ca0d,
4889 0x00100070,
4890 0x23010a0f,
4891 0x01500070,
4892 0x4002140c,
4893 0x00100010,
4894 0x1a00d40d,
4895 0x00100050,
4896 0x13008a0e,
4897 0x01900070,
4898 0x13008a0e,
4899 0x01900070,
4900 0x23010a0f,
4901 0x01500070,
4902 0x00000000,
4903 0x00000000,
4904 0x00000000,
4905 0x00000000,
4906 0x00000000,
4907 0x00000000,
4908 0x50029404,
4909 0x00100000,
4910 0x32019405,
4911 0x00100040,
4912 0x0b004a06,
4913 0x01900060,
4914 0x0b004a06,
4915 0x01900060,
4916 0x5b02ca04,
4917 0x00100060,
4918 0x3b01d405,
4919 0x00100060,
4920 0x23010a07,
4921 0x01500060,
4922 0x00000000,
4923 0x00000000,
4924 0x5802d404,
4925 0x00100000,
4926 0x3b01d405,
4927 0x00100060,
4928 0x0b004a06,
4929 0x01900060,
4930 0x23010a07,
4931 0x01500060,
4932 0x00000000,
4933 0x00000000,
4934 0x00000000,
4935 0x00000000,
4936 0x00000000,
4937 0x00000000,
4938 0x00000000,
4939 0x00000000,
4940 0x5002940c,
4941 0x00100010,
4942 0x3201940d,
4943 0x00100050,
4944 0x0b004a0e,
4945 0x01900070,
4946 0x0b004a0e,
4947 0x01900070,
4948 0x5b02ca0c,
4949 0x00100070,
4950 0x3b01d40d,
4951 0x00100070,
4952 0x23010a0f,
4953 0x01500070,
4954 0x00000000,
4955 0x00000000,
4956 0x5802d40c,
4957 0x00100010,
4958 0x3b01d40d,
4959 0x00100070,
4960 0x0b004a0e,
4961 0x01900070,
4962 0x23010a0f,
4963 0x01500070,
4964 0x00000000,
4965 0x00000000,
4966 0x00000000,
4967 0x00000000,
4968 0x00000000,
4969 0x00000000,
4970 0x00000000,
4971 0x00000000,
4972 0x40021404,
4973 0x000f4800,
4974 0x62031405,
4975 0x00100040,
4976 0x53028a06,
4977 0x01900060,
4978 0x53028a07,
4979 0x01900060,
4980 0x00000000,
4981 0x00000000,
4982 0x00000000,
4983 0x00000000,
4984 0x00000000,
4985 0x00000000,
4986 0x00000000,
4987 0x00000000,
4988 0x4002140c,
4989 0x000f4808,
4990 0x6203140d,
4991 0x00100048,
4992 0x53028a0e,
4993 0x01900068,
4994 0x53028a0f,
4995 0x01900068,
4996 0x00000000,
4997 0x00000000,
4998 0x00000000,
4999 0x00000000,
5000 0x00000000,
5001 0x00000000,
5002 0x00000000,
5003 0x00000000,
5004 0x00000a0c,
5005 0x00100004,
5006 0x11008a0d,
5007 0x00100024,
5008 0x1980c50e,
5009 0x00100034,
5010 0x2181050e,
5011 0x00100034,
5012 0x2181050e,
5013 0x00100034,
5014 0x0180050c,
5015 0x00100038,
5016 0x1180850d,
5017 0x00100038,
5018 0x1181850d,
5019 0x00100038,
5020 0x2981450f,
5021 0x01100038,
5022 0x00000000,
5023 0x00000000,
5024 0x00000000,
5025 0x00000000,
5026 0x00000000,
5027 0x00000000,
5028 0x00000000,
5029 0x00000000,
5030 0x00000000,
5031 0x00000000,
5032 0x00000000,
5033 0x00000000,
5034 0x00000000,
5035 0x00000000,
5036 0x00000a0c,
5037 0x00100008,
5038 0x11008a0d,
5039 0x00100028,
5040 0x2181050e,
5041 0x00100038,
5042 0x2181050e,
5043 0x00100038,
5044 0x1181850d,
5045 0x00100038,
5046 0x2981450f,
5047 0x01100038,
5048 0x00000000,
5049 0x00000000,
5050 0x00000000,
5051 0x00000000,
5052 0x00000000,
5053 0x00000000,
5054 0x00000000,
5055 0x00000000,
5056 0x00000000,
5057 0x00000000,
5058 0x00000000,
5059 0x00000000,
5060 0x00000000,
5061 0x00000000,
5062 0x00000000,
5063 0x00000000,
5064 0x00000000,
5065 0x00000000,
5066 0x00000000,
5067 0x00000000,
5068 0x08004a04,
5069 0x00100000,
5070 0x01000a05,
5071 0x00100020,
5072 0x0180c506,
5073 0x00100030,
5074 0x0180c506,
5075 0x00100030,
5076 0x2180c50c,
5077 0x00100030,
5078 0x49820a0d,
5079 0x0016a130,
5080 0x41824a0d,
5081 0x0016a130,
5082 0x2981450f,
5083 0x01100030,
5084 0x00000000,
5085 0x00000000,
5086 0x00000000,
5087 0x00000000,
5088 0x00000000,
5089 0x00000000,
5090 0x00000000,
5091 0x00000000,
5092 0x00000000,
5093 0x00000000,
5094 0x00000000,
5095 0x00000000,
5096 0x00000000,
5097 0x00000000,
5098 0x00000000,
5099 0x00000000,
5100 0x2000ca0c,
5101 0x00100000,
5102 0x49820a0d,
5103 0x0016a130,
5104 0x1980c50e,
5105 0x00100030,
5106 0x41824a0d,
5107 0x0016a130,
5108 0x2981450f,
5109 0x01100030,
5110 0x00000000,
5111 0x00000000,
5112 0x00000000,
5113 0x00000000,
5114 0x00000000,
5115 0x00000000,
5116 0x00000000,
5117 0x00000000,
5118 0x00000000,
5119 0x00000000,
5120 0x00000000,
5121 0x00000000,
5122 0x00000000,
5123 0x00000000,
5124 0x00000000,
5125 0x00000000,
5126 0x00000000,
5127 0x00000000,
5128 0x00000000,
5129 0x00000000,
5130 0x00000000,
5131 0x00000000,
5132 0x4002140c,
5133 0x00100008,
5134 0x0200140d,
5135 0x00100048,
5136 0x0b004a0e,
5137 0x01900068,
5138 0x13008a0e,
5139 0x01900068,
5140 0x13008a0e,
5141 0x01900068,
5142 0x43020a0c,
5143 0x00100070,
5144 0x1b00ca0d,
5145 0x00100070,
5146 0x1b014a0d,
5147 0x00100070,
5148 0x23010a0f,
5149 0x01500070,
5150 0x00000000,
5151 0x00000000,
5152 0x00000000,
5153 0x00000000,
5154 0x00000000,
5155 0x00000000,
5156 0x00000000,
5157 0x00000000,
5158 0x00000000,
5159 0x00000000,
5160 0x00000000,
5161 0x00000000,
5162 0x00000000,
5163 0x00000000,
5164 0x4002140c,
5165 0x00100010,
5166 0x1a00d40d,
5167 0x00100050,
5168 0x13008a0e,
5169 0x01900070,
5170 0x13008a0e,
5171 0x01900070,
5172 0x1b014a0d,
5173 0x00100070,
5174 0x23010a0f,
5175 0x01500070,
5176 0x00000000,
5177 0x00000000,
5178 0x00000000,
5179 0x00000000,
5180 0x00000000,
5181 0x00000000,
5182 0x00000000,
5183 0x00000000,
5184 0x00000000,
5185 0x00000000,
5186 0x00000000,
5187 0x00000000,
5188 0x00000000,
5189 0x00000000,
5190 0x00000000,
5191 0x00000000,
5192 0x00000000,
5193 0x00000000,
5194 0x00000000,
5195 0x00000000,
5196 0x50029404,
5197 0x00100000,
5198 0x32019405,
5199 0x00100040,
5200 0x03004a06,
5201 0x01900060,
5202 0x03004a06,
5203 0x01900060,
5204 0x6b030a0c,
5205 0x00100060,
5206 0x4b02140d,
5207 0x0016a160,
5208 0x4302540d,
5209 0x0016a160,
5210 0x23010a0f,
5211 0x01500060,
5212 0x00000000,
5213 0x00000000,
5214 0x00000000,
5215 0x00000000,
5216 0x00000000,
5217 0x00000000,
5218 0x00000000,
5219 0x00000000,
5220 0x00000000,
5221 0x00000000,
5222 0x00000000,
5223 0x00000000,
5224 0x00000000,
5225 0x00000000,
5226 0x00000000,
5227 0x00000000,
5228 0x6b03140c,
5229 0x00100060,
5230 0x4b02140d,
5231 0x0016a160,
5232 0x0b004a0e,
5233 0x01900060,
5234 0x4302540d,
5235 0x0016a160,
5236 0x23010a0f,
5237 0x01500060,
5238 0x00000000,
5239 0x00000000,
5240 0x00000000,
5241 0x00000000,
5242 0x00000000,
5243 0x00000000,
5244 0x00000000,
5245 0x00000000,
5246 0x00000000,
5247 0x00000000,
5248 0x00000000,
5249 0x00000000,
5250 0x00000000,
5251 0x00000000,
5252 0x00000000,
5253 0x00000000,
5254 0x00000000,
5255 0x00000000,
5256 0x00000000,
5257 0x00000000,
5258 0x00000000,
5259 0x00000000,
5260 0x40021404,
5261 0x00100000,
5262 0x1a00d405,
5263 0x00100040,
5264 0x53028a06,
5265 0x01900060,
5266 0x5b02ca06,
5267 0x01900060,
5268 0x5b02ca06,
5269 0x01900060,
5270 0x43020a04,
5271 0x00100060,
5272 0x1b00ca05,
5273 0x00100060,
5274 0x53028a07,
5275 0x0190c060,
5276 0x00000000,
5277 0x00000000,
5278 0x00000000,
5279 0x00000000,
5280 0x00000000,
5281 0x00000000,
5282 0x00000000,
5283 0x00000000,
5284 0x00000000,
5285 0x00000000,
5286 0x00000000,
5287 0x00000000,
5288 0x00000000,
5289 0x00000000,
5290 0x00000000,
5291 0x00000000,
5292 0x4002140c,
5293 0x00100010,
5294 0x1a00d40d,
5295 0x00100050,
5296 0x53028a0e,
5297 0x01900070,
5298 0x5b02ca0e,
5299 0x01900070,
5300 0x5b02ca0e,
5301 0x01900070,
5302 0x43020a0c,
5303 0x00100070,
5304 0x1b00ca0d,
5305 0x00100070,
5306 0x53028a0f,
5307 0x0190c070,
5308 0x00000000,
5309 0x00000000,
5310 0x00000000,
5311 0x00000000,
5312 0x00000000,
5313 0x00000000,
5314 0x00000000,
5315 0x00000000,
5316 0x00000000,
5317 0x00000000,
5318 0x00000000,
5319 0x00000000,
5320 0x00000000,
5321 0x00000000,
5322 0x00000000,
5323 0x00000000,
5324 0x40021404,
5325 0x00100000,
5326 0x1a00d405,
5327 0x00100040,
5328 0x5b02ca06,
5329 0x01900060,
5330 0x5b02ca06,
5331 0x01900060,
5332 0x53028a07,
5333 0x0190c060,
5334 0x00000000,
5335 0x00000000,
5336 0x00000000,
5337 0x00000000,
5338 0x00000000,
5339 0x00000000,
5340 0x00000000,
5341 0x00000000,
5342 0x00000000,
5343 0x00000000,
5344 0x00000000,
5345 0x00000000,
5346 0x00000000,
5347 0x00000000,
5348 0x00000000,
5349 0x00000000,
5350 0x00000000,
5351 0x00000000,
5352 0x00000000,
5353 0x00000000,
5354 0x00000000,
5355 0x00000000,
5356 0x4002140c,
5357 0x00100010,
5358 0x1a00d40d,
5359 0x00100050,
5360 0x5b02ca0e,
5361 0x01900070,
5362 0x5b02ca0e,
5363 0x01900070,
5364 0x53028a0f,
5365 0x0190c070,
5366 0x00000000,
5367 0x00000000,
5368 0x00000000,
5369 0x00000000,
5370 0x00000000,
5371 0x00000000,
5372 0x00000000,
5373 0x00000000,
5374 0x00000000,
5375 0x00000000,
5376 0x00000000,
5377 0x00000000,
5378 0x00000000,
5379 0x00000000,
5380 0x00000000,
5381 0x00000000,
5382 0x00000000,
5383 0x00000000,
5384 0x00000000,
5385 0x00000000,
5386 0x00000000,
5387 0x00000000,
5388 0x00000000,
5389 0x00000000,
5390 0x00000000,
5391 0x00000000,
5392 0x00000000,
5393 0x00000000,
5394 0x00000000,
5395 0x00000000,
5396 0x00000000,
5397 0x00000000,
5398 0x00000000,
5399 0x00000000,
5400 0x00000000,
5401 0x00000000,
5402 0x00000000,
5403 0x00000000,
5404 0x00000000,
5405 0x00000000,
5406 0x00000000,
5407 0x00000000,
5408 0x00000000,
5409 0x00000000,
5410 0x00000000,
5411 0x00000000,
5412 0x00000000,
5413 0x00000000,
5414 0x00000000,
5415 0x00000000,
5416 0x00000000,
5417 0x00000000,
5418 0x00000000,
5419 0x00000000,
5420 0x00000000,
5421 0x00000000,
5422 0x00000000,
5423 0x00000000,
5424 0x00000000,
5425 0x00000000,
5426 0x00000000,
5427 0x00000000,
5428 0x00000000,
5429 0x00000000,
5430 0x00000000,
5431 0x00000000,
5432 0x00000000,
5433 0x00000000,
5434 0x00000000,
5435 0x00000000,
5436 0x00000000,
5437 0x00000000,
5438 0x00000000,
5439 0x00000000,
5440 0x00000000,
5441 0x00000000,
5442 0x00000000,
5443 0x00000000,
5444 0x00000000,
5445 0x00000000,
5446 0x00000000,
5447 0x00000000,
5448 0x00000000,
5449 0x00000000,
5450 0x00000000,
5451 0x00000000,
5452 0x00000000,
5453 0x00000000,
5454 0x00000000,
5455 0x00000000,
5456 0x00000000,
5457 0x00000000,
5458 0x00000000,
5459 0x00000000,
5460 0x00000000,
5461 0x00000000,
5462 0x00000000,
5463 0x00000000,
5464 0x00000000,
5465 0x00000000,
5466 0x00000000,
5467 0x00000000,
5468 0x00000000,
5469 0x00000000,
5470 0x00000000,
5471 0x00000000,
5472 0x00000000,
5473 0x00000000,
5474 0x00000000,
5475 0x00000000,
5476 0x00000000,
5477 0x00000000,
5478 0x00000000,
5479 0x00000000,
5480 0x00000000,
5481 0x00000000,
5482 0x00000000,
5483 0x00000000,
5484 0x00000000,
5485 0x00000000,
5486 0x00000000,
5487 0x00000000,
5488 0x00000000,
5489 0x00000000,
5490 0x00000000,
5491 0x00000000,
5492 0x00000000,
5493 0x00000000,
5494 0x00000000,
5495 0x00000000,
5496 0x00000000,
5497 0x00000000,
5498 0x00000000,
5499 0x00000000,
5500 0x00000000,
5501 0x00000000,
5502 0x00000000,
5503 0x00000000,
5504 0x00000000,
5505 0x00000000,
5506 0x00000000,
5507 0x00000000,
5508 0x00000000,
5509 0x00000000,
5510 0x00000000,
5511 0x00000000,
5512 0x00000000,
5513 0x00000000,
5514 0x00000000,
5515 0x00000000,
5516};
5517
5518const u16 pilot_tbl_rev3[] = {
5519 0xff08,
5520 0xff08,
5521 0xff08,
5522 0xff08,
5523 0xff08,
5524 0xff08,
5525 0xff08,
5526 0xff08,
5527 0x80d5,
5528 0x80d5,
5529 0x80d5,
5530 0x80d5,
5531 0x80d5,
5532 0x80d5,
5533 0x80d5,
5534 0x80d5,
5535 0xff0a,
5536 0xff82,
5537 0xffa0,
5538 0xff28,
5539 0xffff,
5540 0xffff,
5541 0xffff,
5542 0xffff,
5543 0xff82,
5544 0xffa0,
5545 0xff28,
5546 0xff0a,
5547 0xffff,
5548 0xffff,
5549 0xffff,
5550 0xffff,
5551 0xf83f,
5552 0xfa1f,
5553 0xfa97,
5554 0xfab5,
5555 0xf2bd,
5556 0xf0bf,
5557 0xffff,
5558 0xffff,
5559 0xf017,
5560 0xf815,
5561 0xf215,
5562 0xf095,
5563 0xf035,
5564 0xf01d,
5565 0xffff,
5566 0xffff,
5567 0xff08,
5568 0xff02,
5569 0xff80,
5570 0xff20,
5571 0xff08,
5572 0xff02,
5573 0xff80,
5574 0xff20,
5575 0xf01f,
5576 0xf817,
5577 0xfa15,
5578 0xf295,
5579 0xf0b5,
5580 0xf03d,
5581 0xffff,
5582 0xffff,
5583 0xf82a,
5584 0xfa0a,
5585 0xfa82,
5586 0xfaa0,
5587 0xf2a8,
5588 0xf0aa,
5589 0xffff,
5590 0xffff,
5591 0xf002,
5592 0xf800,
5593 0xf200,
5594 0xf080,
5595 0xf020,
5596 0xf008,
5597 0xffff,
5598 0xffff,
5599 0xf00a,
5600 0xf802,
5601 0xfa00,
5602 0xf280,
5603 0xf0a0,
5604 0xf028,
5605 0xffff,
5606 0xffff,
5607};
5608
5609const u32 tmap_tbl_rev3[] = {
5610 0x8a88aa80,
5611 0x8aaaaa8a,
5612 0x8a8a8aa8,
5613 0x00000888,
5614 0x88000000,
5615 0x8a8a88aa,
5616 0x8aa88888,
5617 0x8888a8a8,
5618 0xf1111110,
5619 0x11111111,
5620 0x11f11111,
5621 0x00000111,
5622 0x11000000,
5623 0x1111f111,
5624 0x11111111,
5625 0x111111f1,
5626 0x8a88aa80,
5627 0x8aaaaa8a,
5628 0x8a8a8aa8,
5629 0x000aa888,
5630 0x88880000,
5631 0x8a8a88aa,
5632 0x8aa88888,
5633 0x8888a8a8,
5634 0xa1111110,
5635 0x11111111,
5636 0x11c11111,
5637 0x00000111,
5638 0x11000000,
5639 0x1111a111,
5640 0x11111111,
5641 0x111111a1,
5642 0xa2222220,
5643 0x22222222,
5644 0x22c22222,
5645 0x00000222,
5646 0x22000000,
5647 0x2222a222,
5648 0x22222222,
5649 0x222222a2,
5650 0xf1111110,
5651 0x11111111,
5652 0x11f11111,
5653 0x00011111,
5654 0x11110000,
5655 0x1111f111,
5656 0x11111111,
5657 0x111111f1,
5658 0xa8aa88a0,
5659 0xa88888a8,
5660 0xa8a8a88a,
5661 0x00088aaa,
5662 0xaaaa0000,
5663 0xa8a8aa88,
5664 0xa88aaaaa,
5665 0xaaaa8a8a,
5666 0xaaa8aaa0,
5667 0x8aaa8aaa,
5668 0xaa8a8a8a,
5669 0x000aaa88,
5670 0x8aaa0000,
5671 0xaaa8a888,
5672 0x8aa88a8a,
5673 0x8a88a888,
5674 0x08080a00,
5675 0x0a08080a,
5676 0x080a0a08,
5677 0x00080808,
5678 0x080a0000,
5679 0x080a0808,
5680 0x080a0808,
5681 0x0a0a0a08,
5682 0xa0a0a0a0,
5683 0x80a0a080,
5684 0x8080a0a0,
5685 0x00008080,
5686 0x80a00000,
5687 0x80a080a0,
5688 0xa080a0a0,
5689 0x8080a0a0,
5690 0x00000000,
5691 0x00000000,
5692 0x00000000,
5693 0x00000000,
5694 0x00000000,
5695 0x00000000,
5696 0x00000000,
5697 0x00000000,
5698 0x00000000,
5699 0x00000000,
5700 0x00000000,
5701 0x00000000,
5702 0x00000000,
5703 0x00000000,
5704 0x00000000,
5705 0x00000000,
5706 0x00000000,
5707 0x00000000,
5708 0x00000000,
5709 0x00000000,
5710 0x00000000,
5711 0x00000000,
5712 0x00000000,
5713 0x00000000,
5714 0x00000000,
5715 0x00000000,
5716 0x00000000,
5717 0x00000000,
5718 0x00000000,
5719 0x00000000,
5720 0x00000000,
5721 0x00000000,
5722 0x00000000,
5723 0x00000000,
5724 0x00000000,
5725 0x00000000,
5726 0x00000000,
5727 0x00000000,
5728 0x00000000,
5729 0x00000000,
5730 0x00000000,
5731 0x00000000,
5732 0x00000000,
5733 0x00000000,
5734 0x00000000,
5735 0x00000000,
5736 0x00000000,
5737 0x00000000,
5738 0x99999000,
5739 0x9b9b99bb,
5740 0x9bb99999,
5741 0x9999b9b9,
5742 0x9b99bb90,
5743 0x9bbbbb9b,
5744 0x9b9b9bb9,
5745 0x00000999,
5746 0x88000000,
5747 0x8a8a88aa,
5748 0x8aa88888,
5749 0x8888a8a8,
5750 0x8a88aa80,
5751 0x8aaaaa8a,
5752 0x8a8a8aa8,
5753 0x00aaa888,
5754 0x22000000,
5755 0x2222b222,
5756 0x22222222,
5757 0x222222b2,
5758 0xb2222220,
5759 0x22222222,
5760 0x22d22222,
5761 0x00000222,
5762 0x11000000,
5763 0x1111a111,
5764 0x11111111,
5765 0x111111a1,
5766 0xa1111110,
5767 0x11111111,
5768 0x11c11111,
5769 0x00000111,
5770 0x33000000,
5771 0x3333b333,
5772 0x33333333,
5773 0x333333b3,
5774 0xb3333330,
5775 0x33333333,
5776 0x33d33333,
5777 0x00000333,
5778 0x22000000,
5779 0x2222a222,
5780 0x22222222,
5781 0x222222a2,
5782 0xa2222220,
5783 0x22222222,
5784 0x22c22222,
5785 0x00000222,
5786 0x99b99b00,
5787 0x9b9b99bb,
5788 0x9bb99999,
5789 0x9999b9b9,
5790 0x9b99bb99,
5791 0x9bbbbb9b,
5792 0x9b9b9bb9,
5793 0x00000999,
5794 0x88000000,
5795 0x8a8a88aa,
5796 0x8aa88888,
5797 0x8888a8a8,
5798 0x8a88aa88,
5799 0x8aaaaa8a,
5800 0x8a8a8aa8,
5801 0x08aaa888,
5802 0x22222200,
5803 0x2222f222,
5804 0x22222222,
5805 0x222222f2,
5806 0x22222222,
5807 0x22222222,
5808 0x22f22222,
5809 0x00000222,
5810 0x11000000,
5811 0x1111f111,
5812 0x11111111,
5813 0x11111111,
5814 0xf1111111,
5815 0x11111111,
5816 0x11f11111,
5817 0x01111111,
5818 0xbb9bb900,
5819 0xb9b9bb99,
5820 0xb99bbbbb,
5821 0xbbbb9b9b,
5822 0xb9bb99bb,
5823 0xb99999b9,
5824 0xb9b9b99b,
5825 0x00000bbb,
5826 0xaa000000,
5827 0xa8a8aa88,
5828 0xa88aaaaa,
5829 0xaaaa8a8a,
5830 0xa8aa88aa,
5831 0xa88888a8,
5832 0xa8a8a88a,
5833 0x0a888aaa,
5834 0xaa000000,
5835 0xa8a8aa88,
5836 0xa88aaaaa,
5837 0xaaaa8a8a,
5838 0xa8aa88a0,
5839 0xa88888a8,
5840 0xa8a8a88a,
5841 0x00000aaa,
5842 0x88000000,
5843 0x8a8a88aa,
5844 0x8aa88888,
5845 0x8888a8a8,
5846 0x8a88aa80,
5847 0x8aaaaa8a,
5848 0x8a8a8aa8,
5849 0x00000888,
5850 0xbbbbbb00,
5851 0x999bbbbb,
5852 0x9bb99b9b,
5853 0xb9b9b9bb,
5854 0xb9b99bbb,
5855 0xb9b9b9bb,
5856 0xb9bb9b99,
5857 0x00000999,
5858 0x8a000000,
5859 0xaa88a888,
5860 0xa88888aa,
5861 0xa88a8a88,
5862 0xa88aa88a,
5863 0x88a8aaaa,
5864 0xa8aa8aaa,
5865 0x0888a88a,
5866 0x0b0b0b00,
5867 0x090b0b0b,
5868 0x0b090b0b,
5869 0x0909090b,
5870 0x09090b0b,
5871 0x09090b0b,
5872 0x09090b09,
5873 0x00000909,
5874 0x0a000000,
5875 0x0a080808,
5876 0x080a080a,
5877 0x080a0a08,
5878 0x080a080a,
5879 0x0808080a,
5880 0x0a0a0a08,
5881 0x0808080a,
5882 0xb0b0b000,
5883 0x9090b0b0,
5884 0x90b09090,
5885 0xb0b0b090,
5886 0xb0b090b0,
5887 0x90b0b0b0,
5888 0xb0b09090,
5889 0x00000090,
5890 0x80000000,
5891 0xa080a080,
5892 0xa08080a0,
5893 0xa0808080,
5894 0xa080a080,
5895 0x80a0a0a0,
5896 0xa0a080a0,
5897 0x00a0a0a0,
5898 0x22000000,
5899 0x2222f222,
5900 0x22222222,
5901 0x222222f2,
5902 0xf2222220,
5903 0x22222222,
5904 0x22f22222,
5905 0x00000222,
5906 0x11000000,
5907 0x1111f111,
5908 0x11111111,
5909 0x111111f1,
5910 0xf1111110,
5911 0x11111111,
5912 0x11f11111,
5913 0x00000111,
5914 0x33000000,
5915 0x3333f333,
5916 0x33333333,
5917 0x333333f3,
5918 0xf3333330,
5919 0x33333333,
5920 0x33f33333,
5921 0x00000333,
5922 0x22000000,
5923 0x2222f222,
5924 0x22222222,
5925 0x222222f2,
5926 0xf2222220,
5927 0x22222222,
5928 0x22f22222,
5929 0x00000222,
5930 0x99000000,
5931 0x9b9b99bb,
5932 0x9bb99999,
5933 0x9999b9b9,
5934 0x9b99bb90,
5935 0x9bbbbb9b,
5936 0x9b9b9bb9,
5937 0x00000999,
5938 0x88000000,
5939 0x8a8a88aa,
5940 0x8aa88888,
5941 0x8888a8a8,
5942 0x8a88aa80,
5943 0x8aaaaa8a,
5944 0x8a8a8aa8,
5945 0x00000888,
5946 0x88888000,
5947 0x8a8a88aa,
5948 0x8aa88888,
5949 0x8888a8a8,
5950 0x8a88aa80,
5951 0x8aaaaa8a,
5952 0x8a8a8aa8,
5953 0x00000888,
5954 0x88000000,
5955 0x8a8a88aa,
5956 0x8aa88888,
5957 0x8888a8a8,
5958 0x8a88aa80,
5959 0x8aaaaa8a,
5960 0x8a8a8aa8,
5961 0x00aaa888,
5962 0x88a88a00,
5963 0x8a8a88aa,
5964 0x8aa88888,
5965 0x8888a8a8,
5966 0x8a88aa88,
5967 0x8aaaaa8a,
5968 0x8a8a8aa8,
5969 0x00000888,
5970 0x88000000,
5971 0x8a8a88aa,
5972 0x8aa88888,
5973 0x8888a8a8,
5974 0x8a88aa88,
5975 0x8aaaaa8a,
5976 0x8a8a8aa8,
5977 0x08aaa888,
5978 0x11000000,
5979 0x1111a111,
5980 0x11111111,
5981 0x111111a1,
5982 0xa1111110,
5983 0x11111111,
5984 0x11c11111,
5985 0x00000111,
5986 0x11000000,
5987 0x1111a111,
5988 0x11111111,
5989 0x111111a1,
5990 0xa1111110,
5991 0x11111111,
5992 0x11c11111,
5993 0x00000111,
5994 0x88000000,
5995 0x8a8a88aa,
5996 0x8aa88888,
5997 0x8888a8a8,
5998 0x8a88aa80,
5999 0x8aaaaa8a,
6000 0x8a8a8aa8,
6001 0x00000888,
6002 0x88000000,
6003 0x8a8a88aa,
6004 0x8aa88888,
6005 0x8888a8a8,
6006 0x8a88aa80,
6007 0x8aaaaa8a,
6008 0x8a8a8aa8,
6009 0x00000888,
6010 0x00000000,
6011 0x00000000,
6012 0x00000000,
6013 0x00000000,
6014 0x00000000,
6015 0x00000000,
6016 0x00000000,
6017 0x00000000,
6018 0x00000000,
6019 0x00000000,
6020 0x00000000,
6021 0x00000000,
6022 0x00000000,
6023 0x00000000,
6024 0x00000000,
6025 0x00000000,
6026 0x00000000,
6027 0x00000000,
6028 0x00000000,
6029 0x00000000,
6030 0x00000000,
6031 0x00000000,
6032 0x00000000,
6033 0x00000000,
6034 0x00000000,
6035 0x00000000,
6036 0x00000000,
6037 0x00000000,
6038 0x00000000,
6039 0x00000000,
6040 0x00000000,
6041 0x00000000,
6042 0x00000000,
6043 0x00000000,
6044 0x00000000,
6045 0x00000000,
6046 0x00000000,
6047 0x00000000,
6048 0x00000000,
6049 0x00000000,
6050 0x00000000,
6051 0x00000000,
6052 0x00000000,
6053 0x00000000,
6054 0x00000000,
6055 0x00000000,
6056 0x00000000,
6057 0x00000000,
6058};
6059
6060const u32 intlv_tbl_rev3[] = {
6061 0x00802070,
6062 0x0671188d,
6063 0x0a60192c,
6064 0x0a300e46,
6065 0x00c1188d,
6066 0x080024d2,
6067 0x00000070,
6068};
6069
6070const u32 tdtrn_tbl_rev3[] = {
6071 0x061c061c,
6072 0x0050ee68,
6073 0xf592fe36,
6074 0xfe5212f6,
6075 0x00000c38,
6076 0xfe5212f6,
6077 0xf592fe36,
6078 0x0050ee68,
6079 0x061c061c,
6080 0xee680050,
6081 0xfe36f592,
6082 0x12f6fe52,
6083 0x0c380000,
6084 0x12f6fe52,
6085 0xfe36f592,
6086 0xee680050,
6087 0x061c061c,
6088 0x0050ee68,
6089 0xf592fe36,
6090 0xfe5212f6,
6091 0x00000c38,
6092 0xfe5212f6,
6093 0xf592fe36,
6094 0x0050ee68,
6095 0x061c061c,
6096 0xee680050,
6097 0xfe36f592,
6098 0x12f6fe52,
6099 0x0c380000,
6100 0x12f6fe52,
6101 0xfe36f592,
6102 0xee680050,
6103 0x05e305e3,
6104 0x004def0c,
6105 0xf5f3fe47,
6106 0xfe611246,
6107 0x00000bc7,
6108 0xfe611246,
6109 0xf5f3fe47,
6110 0x004def0c,
6111 0x05e305e3,
6112 0xef0c004d,
6113 0xfe47f5f3,
6114 0x1246fe61,
6115 0x0bc70000,
6116 0x1246fe61,
6117 0xfe47f5f3,
6118 0xef0c004d,
6119 0x05e305e3,
6120 0x004def0c,
6121 0xf5f3fe47,
6122 0xfe611246,
6123 0x00000bc7,
6124 0xfe611246,
6125 0xf5f3fe47,
6126 0x004def0c,
6127 0x05e305e3,
6128 0xef0c004d,
6129 0xfe47f5f3,
6130 0x1246fe61,
6131 0x0bc70000,
6132 0x1246fe61,
6133 0xfe47f5f3,
6134 0xef0c004d,
6135 0xfa58fa58,
6136 0xf895043b,
6137 0xff4c09c0,
6138 0xfbc6ffa8,
6139 0xfb84f384,
6140 0x0798f6f9,
6141 0x05760122,
6142 0x058409f6,
6143 0x0b500000,
6144 0x05b7f542,
6145 0x08860432,
6146 0x06ddfee7,
6147 0xfb84f384,
6148 0xf9d90664,
6149 0xf7e8025c,
6150 0x00fff7bd,
6151 0x05a805a8,
6152 0xf7bd00ff,
6153 0x025cf7e8,
6154 0x0664f9d9,
6155 0xf384fb84,
6156 0xfee706dd,
6157 0x04320886,
6158 0xf54205b7,
6159 0x00000b50,
6160 0x09f60584,
6161 0x01220576,
6162 0xf6f90798,
6163 0xf384fb84,
6164 0xffa8fbc6,
6165 0x09c0ff4c,
6166 0x043bf895,
6167 0x02d402d4,
6168 0x07de0270,
6169 0xfc96079c,
6170 0xf90afe94,
6171 0xfe00ff2c,
6172 0x02d4065d,
6173 0x092a0096,
6174 0x0014fbb8,
6175 0xfd2cfd2c,
6176 0x076afb3c,
6177 0x0096f752,
6178 0xf991fd87,
6179 0xfb2c0200,
6180 0xfeb8f960,
6181 0x08e0fc96,
6182 0x049802a8,
6183 0xfd2cfd2c,
6184 0x02a80498,
6185 0xfc9608e0,
6186 0xf960feb8,
6187 0x0200fb2c,
6188 0xfd87f991,
6189 0xf7520096,
6190 0xfb3c076a,
6191 0xfd2cfd2c,
6192 0xfbb80014,
6193 0x0096092a,
6194 0x065d02d4,
6195 0xff2cfe00,
6196 0xfe94f90a,
6197 0x079cfc96,
6198 0x027007de,
6199 0x02d402d4,
6200 0x027007de,
6201 0x079cfc96,
6202 0xfe94f90a,
6203 0xff2cfe00,
6204 0x065d02d4,
6205 0x0096092a,
6206 0xfbb80014,
6207 0xfd2cfd2c,
6208 0xfb3c076a,
6209 0xf7520096,
6210 0xfd87f991,
6211 0x0200fb2c,
6212 0xf960feb8,
6213 0xfc9608e0,
6214 0x02a80498,
6215 0xfd2cfd2c,
6216 0x049802a8,
6217 0x08e0fc96,
6218 0xfeb8f960,
6219 0xfb2c0200,
6220 0xf991fd87,
6221 0x0096f752,
6222 0x076afb3c,
6223 0xfd2cfd2c,
6224 0x0014fbb8,
6225 0x092a0096,
6226 0x02d4065d,
6227 0xfe00ff2c,
6228 0xf90afe94,
6229 0xfc96079c,
6230 0x07de0270,
6231 0x00000000,
6232 0x00000000,
6233 0x00000000,
6234 0x00000000,
6235 0x00000000,
6236 0x00000000,
6237 0x00000000,
6238 0x00000000,
6239 0x00000000,
6240 0x00000000,
6241 0x00000000,
6242 0x00000000,
6243 0x00000000,
6244 0x00000000,
6245 0x00000000,
6246 0x00000000,
6247 0x00000000,
6248 0x00000000,
6249 0x00000000,
6250 0x00000000,
6251 0x00000000,
6252 0x00000000,
6253 0x00000000,
6254 0x00000000,
6255 0x00000000,
6256 0x00000000,
6257 0x00000000,
6258 0x00000000,
6259 0x00000000,
6260 0x00000000,
6261 0x00000000,
6262 0x00000000,
6263 0x00000000,
6264 0x00000000,
6265 0x00000000,
6266 0x00000000,
6267 0x00000000,
6268 0x00000000,
6269 0x00000000,
6270 0x00000000,
6271 0x00000000,
6272 0x00000000,
6273 0x00000000,
6274 0x00000000,
6275 0x00000000,
6276 0x00000000,
6277 0x00000000,
6278 0x00000000,
6279 0x00000000,
6280 0x00000000,
6281 0x00000000,
6282 0x00000000,
6283 0x00000000,
6284 0x00000000,
6285 0x00000000,
6286 0x00000000,
6287 0x00000000,
6288 0x00000000,
6289 0x00000000,
6290 0x00000000,
6291 0x00000000,
6292 0x00000000,
6293 0x00000000,
6294 0x00000000,
6295 0x00000000,
6296 0x00000000,
6297 0x00000000,
6298 0x00000000,
6299 0x00000000,
6300 0x00000000,
6301 0x00000000,
6302 0x00000000,
6303 0x00000000,
6304 0x00000000,
6305 0x00000000,
6306 0x00000000,
6307 0x00000000,
6308 0x00000000,
6309 0x00000000,
6310 0x00000000,
6311 0x00000000,
6312 0x00000000,
6313 0x00000000,
6314 0x00000000,
6315 0x00000000,
6316 0x00000000,
6317 0x00000000,
6318 0x00000000,
6319 0x00000000,
6320 0x00000000,
6321 0x00000000,
6322 0x00000000,
6323 0x00000000,
6324 0x00000000,
6325 0x00000000,
6326 0x00000000,
6327 0x062a0000,
6328 0xfefa0759,
6329 0x08b80908,
6330 0xf396fc2d,
6331 0xf9d6045c,
6332 0xfc4ef608,
6333 0xf748f596,
6334 0x07b207bf,
6335 0x062a062a,
6336 0xf84ef841,
6337 0xf748f596,
6338 0x03b209f8,
6339 0xf9d6045c,
6340 0x0c6a03d3,
6341 0x08b80908,
6342 0x0106f8a7,
6343 0x062a0000,
6344 0xfefaf8a7,
6345 0x08b8f6f8,
6346 0xf39603d3,
6347 0xf9d6fba4,
6348 0xfc4e09f8,
6349 0xf7480a6a,
6350 0x07b2f841,
6351 0x062af9d6,
6352 0xf84e07bf,
6353 0xf7480a6a,
6354 0x03b2f608,
6355 0xf9d6fba4,
6356 0x0c6afc2d,
6357 0x08b8f6f8,
6358 0x01060759,
6359 0x062a0000,
6360 0xfefa0759,
6361 0x08b80908,
6362 0xf396fc2d,
6363 0xf9d6045c,
6364 0xfc4ef608,
6365 0xf748f596,
6366 0x07b207bf,
6367 0x062a062a,
6368 0xf84ef841,
6369 0xf748f596,
6370 0x03b209f8,
6371 0xf9d6045c,
6372 0x0c6a03d3,
6373 0x08b80908,
6374 0x0106f8a7,
6375 0x062a0000,
6376 0xfefaf8a7,
6377 0x08b8f6f8,
6378 0xf39603d3,
6379 0xf9d6fba4,
6380 0xfc4e09f8,
6381 0xf7480a6a,
6382 0x07b2f841,
6383 0x062af9d6,
6384 0xf84e07bf,
6385 0xf7480a6a,
6386 0x03b2f608,
6387 0xf9d6fba4,
6388 0x0c6afc2d,
6389 0x08b8f6f8,
6390 0x01060759,
6391 0x061c061c,
6392 0xff30009d,
6393 0xffb21141,
6394 0xfd87fb54,
6395 0xf65dfe59,
6396 0x02eef99e,
6397 0x0166f03c,
6398 0xfff809b6,
6399 0x000008a4,
6400 0x000af42b,
6401 0x00eff577,
6402 0xfa840bf2,
6403 0xfc02ff51,
6404 0x08260f67,
6405 0xfff0036f,
6406 0x0842f9c3,
6407 0x00000000,
6408 0x063df7be,
6409 0xfc910010,
6410 0xf099f7da,
6411 0x00af03fe,
6412 0xf40e057c,
6413 0x0a89ff11,
6414 0x0bd5fff6,
6415 0xf75c0000,
6416 0xf64a0008,
6417 0x0fc4fe9a,
6418 0x0662fd12,
6419 0x01a709a3,
6420 0x04ac0279,
6421 0xeebf004e,
6422 0xff6300d0,
6423 0xf9e4f9e4,
6424 0x00d0ff63,
6425 0x004eeebf,
6426 0x027904ac,
6427 0x09a301a7,
6428 0xfd120662,
6429 0xfe9a0fc4,
6430 0x0008f64a,
6431 0x0000f75c,
6432 0xfff60bd5,
6433 0xff110a89,
6434 0x057cf40e,
6435 0x03fe00af,
6436 0xf7daf099,
6437 0x0010fc91,
6438 0xf7be063d,
6439 0x00000000,
6440 0xf9c30842,
6441 0x036ffff0,
6442 0x0f670826,
6443 0xff51fc02,
6444 0x0bf2fa84,
6445 0xf57700ef,
6446 0xf42b000a,
6447 0x08a40000,
6448 0x09b6fff8,
6449 0xf03c0166,
6450 0xf99e02ee,
6451 0xfe59f65d,
6452 0xfb54fd87,
6453 0x1141ffb2,
6454 0x009dff30,
6455 0x05e30000,
6456 0xff060705,
6457 0x085408a0,
6458 0xf425fc59,
6459 0xfa1d042a,
6460 0xfc78f67a,
6461 0xf7acf60e,
6462 0x075a0766,
6463 0x05e305e3,
6464 0xf8a6f89a,
6465 0xf7acf60e,
6466 0x03880986,
6467 0xfa1d042a,
6468 0x0bdb03a7,
6469 0x085408a0,
6470 0x00faf8fb,
6471 0x05e30000,
6472 0xff06f8fb,
6473 0x0854f760,
6474 0xf42503a7,
6475 0xfa1dfbd6,
6476 0xfc780986,
6477 0xf7ac09f2,
6478 0x075af89a,
6479 0x05e3fa1d,
6480 0xf8a60766,
6481 0xf7ac09f2,
6482 0x0388f67a,
6483 0xfa1dfbd6,
6484 0x0bdbfc59,
6485 0x0854f760,
6486 0x00fa0705,
6487 0x05e30000,
6488 0xff060705,
6489 0x085408a0,
6490 0xf425fc59,
6491 0xfa1d042a,
6492 0xfc78f67a,
6493 0xf7acf60e,
6494 0x075a0766,
6495 0x05e305e3,
6496 0xf8a6f89a,
6497 0xf7acf60e,
6498 0x03880986,
6499 0xfa1d042a,
6500 0x0bdb03a7,
6501 0x085408a0,
6502 0x00faf8fb,
6503 0x05e30000,
6504 0xff06f8fb,
6505 0x0854f760,
6506 0xf42503a7,
6507 0xfa1dfbd6,
6508 0xfc780986,
6509 0xf7ac09f2,
6510 0x075af89a,
6511 0x05e3fa1d,
6512 0xf8a60766,
6513 0xf7ac09f2,
6514 0x0388f67a,
6515 0xfa1dfbd6,
6516 0x0bdbfc59,
6517 0x0854f760,
6518 0x00fa0705,
6519 0xfa58fa58,
6520 0xf8f0fe00,
6521 0x0448073d,
6522 0xfdc9fe46,
6523 0xf9910258,
6524 0x089d0407,
6525 0xfd5cf71a,
6526 0x02affde0,
6527 0x083e0496,
6528 0xff5a0740,
6529 0xff7afd97,
6530 0x00fe01f1,
6531 0x0009082e,
6532 0xfa94ff75,
6533 0xfecdf8ea,
6534 0xffb0f693,
6535 0xfd2cfa58,
6536 0x0433ff16,
6537 0xfba405dd,
6538 0xfa610341,
6539 0x06a606cb,
6540 0x0039fd2d,
6541 0x0677fa97,
6542 0x01fa05e0,
6543 0xf896003e,
6544 0x075a068b,
6545 0x012cfc3e,
6546 0xfa23f98d,
6547 0xfc7cfd43,
6548 0xff90fc0d,
6549 0x01c10982,
6550 0x00c601d6,
6551 0xfd2cfd2c,
6552 0x01d600c6,
6553 0x098201c1,
6554 0xfc0dff90,
6555 0xfd43fc7c,
6556 0xf98dfa23,
6557 0xfc3e012c,
6558 0x068b075a,
6559 0x003ef896,
6560 0x05e001fa,
6561 0xfa970677,
6562 0xfd2d0039,
6563 0x06cb06a6,
6564 0x0341fa61,
6565 0x05ddfba4,
6566 0xff160433,
6567 0xfa58fd2c,
6568 0xf693ffb0,
6569 0xf8eafecd,
6570 0xff75fa94,
6571 0x082e0009,
6572 0x01f100fe,
6573 0xfd97ff7a,
6574 0x0740ff5a,
6575 0x0496083e,
6576 0xfde002af,
6577 0xf71afd5c,
6578 0x0407089d,
6579 0x0258f991,
6580 0xfe46fdc9,
6581 0x073d0448,
6582 0xfe00f8f0,
6583 0xfd2cfd2c,
6584 0xfce00500,
6585 0xfc09fddc,
6586 0xfe680157,
6587 0x04c70571,
6588 0xfc3aff21,
6589 0xfcd70228,
6590 0x056d0277,
6591 0x0200fe00,
6592 0x0022f927,
6593 0xfe3c032b,
6594 0xfc44ff3c,
6595 0x03e9fbdb,
6596 0x04570313,
6597 0x04c9ff5c,
6598 0x000d03b8,
6599 0xfa580000,
6600 0xfbe900d2,
6601 0xf9d0fe0b,
6602 0x0125fdf9,
6603 0x042501bf,
6604 0x0328fa2b,
6605 0xffa902f0,
6606 0xfa250157,
6607 0x0200fe00,
6608 0x03740438,
6609 0xff0405fd,
6610 0x030cfe52,
6611 0x0037fb39,
6612 0xff6904c5,
6613 0x04f8fd23,
6614 0xfd31fc1b,
6615 0xfd2cfd2c,
6616 0xfc1bfd31,
6617 0xfd2304f8,
6618 0x04c5ff69,
6619 0xfb390037,
6620 0xfe52030c,
6621 0x05fdff04,
6622 0x04380374,
6623 0xfe000200,
6624 0x0157fa25,
6625 0x02f0ffa9,
6626 0xfa2b0328,
6627 0x01bf0425,
6628 0xfdf90125,
6629 0xfe0bf9d0,
6630 0x00d2fbe9,
6631 0x0000fa58,
6632 0x03b8000d,
6633 0xff5c04c9,
6634 0x03130457,
6635 0xfbdb03e9,
6636 0xff3cfc44,
6637 0x032bfe3c,
6638 0xf9270022,
6639 0xfe000200,
6640 0x0277056d,
6641 0x0228fcd7,
6642 0xff21fc3a,
6643 0x057104c7,
6644 0x0157fe68,
6645 0xfddcfc09,
6646 0x0500fce0,
6647 0xfd2cfd2c,
6648 0x0500fce0,
6649 0xfddcfc09,
6650 0x0157fe68,
6651 0x057104c7,
6652 0xff21fc3a,
6653 0x0228fcd7,
6654 0x0277056d,
6655 0xfe000200,
6656 0xf9270022,
6657 0x032bfe3c,
6658 0xff3cfc44,
6659 0xfbdb03e9,
6660 0x03130457,
6661 0xff5c04c9,
6662 0x03b8000d,
6663 0x0000fa58,
6664 0x00d2fbe9,
6665 0xfe0bf9d0,
6666 0xfdf90125,
6667 0x01bf0425,
6668 0xfa2b0328,
6669 0x02f0ffa9,
6670 0x0157fa25,
6671 0xfe000200,
6672 0x04380374,
6673 0x05fdff04,
6674 0xfe52030c,
6675 0xfb390037,
6676 0x04c5ff69,
6677 0xfd2304f8,
6678 0xfc1bfd31,
6679 0xfd2cfd2c,
6680 0xfd31fc1b,
6681 0x04f8fd23,
6682 0xff6904c5,
6683 0x0037fb39,
6684 0x030cfe52,
6685 0xff0405fd,
6686 0x03740438,
6687 0x0200fe00,
6688 0xfa250157,
6689 0xffa902f0,
6690 0x0328fa2b,
6691 0x042501bf,
6692 0x0125fdf9,
6693 0xf9d0fe0b,
6694 0xfbe900d2,
6695 0xfa580000,
6696 0x000d03b8,
6697 0x04c9ff5c,
6698 0x04570313,
6699 0x03e9fbdb,
6700 0xfc44ff3c,
6701 0xfe3c032b,
6702 0x0022f927,
6703 0x0200fe00,
6704 0x056d0277,
6705 0xfcd70228,
6706 0xfc3aff21,
6707 0x04c70571,
6708 0xfe680157,
6709 0xfc09fddc,
6710 0xfce00500,
6711 0x05a80000,
6712 0xff1006be,
6713 0x0800084a,
6714 0xf49cfc7e,
6715 0xfa580400,
6716 0xfc9cf6da,
6717 0xf800f672,
6718 0x0710071c,
6719 0x05a805a8,
6720 0xf8f0f8e4,
6721 0xf800f672,
6722 0x03640926,
6723 0xfa580400,
6724 0x0b640382,
6725 0x0800084a,
6726 0x00f0f942,
6727 0x05a80000,
6728 0xff10f942,
6729 0x0800f7b6,
6730 0xf49c0382,
6731 0xfa58fc00,
6732 0xfc9c0926,
6733 0xf800098e,
6734 0x0710f8e4,
6735 0x05a8fa58,
6736 0xf8f0071c,
6737 0xf800098e,
6738 0x0364f6da,
6739 0xfa58fc00,
6740 0x0b64fc7e,
6741 0x0800f7b6,
6742 0x00f006be,
6743 0x05a80000,
6744 0xff1006be,
6745 0x0800084a,
6746 0xf49cfc7e,
6747 0xfa580400,
6748 0xfc9cf6da,
6749 0xf800f672,
6750 0x0710071c,
6751 0x05a805a8,
6752 0xf8f0f8e4,
6753 0xf800f672,
6754 0x03640926,
6755 0xfa580400,
6756 0x0b640382,
6757 0x0800084a,
6758 0x00f0f942,
6759 0x05a80000,
6760 0xff10f942,
6761 0x0800f7b6,
6762 0xf49c0382,
6763 0xfa58fc00,
6764 0xfc9c0926,
6765 0xf800098e,
6766 0x0710f8e4,
6767 0x05a8fa58,
6768 0xf8f0071c,
6769 0xf800098e,
6770 0x0364f6da,
6771 0xfa58fc00,
6772 0x0b64fc7e,
6773 0x0800f7b6,
6774 0x00f006be,
6775};
6776
6777const u32 noise_var_tbl_rev3[] = {
6778 0x02110211,
6779 0x0000014d,
6780 0x02110211,
6781 0x0000014d,
6782 0x02110211,
6783 0x0000014d,
6784 0x02110211,
6785 0x0000014d,
6786 0x02110211,
6787 0x0000014d,
6788 0x02110211,
6789 0x0000014d,
6790 0x02110211,
6791 0x0000014d,
6792 0x02110211,
6793 0x0000014d,
6794 0x02110211,
6795 0x0000014d,
6796 0x02110211,
6797 0x0000014d,
6798 0x02110211,
6799 0x0000014d,
6800 0x02110211,
6801 0x0000014d,
6802 0x02110211,
6803 0x0000014d,
6804 0x02110211,
6805 0x0000014d,
6806 0x02110211,
6807 0x0000014d,
6808 0x02110211,
6809 0x0000014d,
6810 0x02110211,
6811 0x0000014d,
6812 0x02110211,
6813 0x0000014d,
6814 0x02110211,
6815 0x0000014d,
6816 0x02110211,
6817 0x0000014d,
6818 0x02110211,
6819 0x0000014d,
6820 0x02110211,
6821 0x0000014d,
6822 0x02110211,
6823 0x0000014d,
6824 0x02110211,
6825 0x0000014d,
6826 0x02110211,
6827 0x0000014d,
6828 0x02110211,
6829 0x0000014d,
6830 0x02110211,
6831 0x0000014d,
6832 0x02110211,
6833 0x0000014d,
6834 0x02110211,
6835 0x0000014d,
6836 0x02110211,
6837 0x0000014d,
6838 0x02110211,
6839 0x0000014d,
6840 0x02110211,
6841 0x0000014d,
6842 0x02110211,
6843 0x0000014d,
6844 0x02110211,
6845 0x0000014d,
6846 0x02110211,
6847 0x0000014d,
6848 0x02110211,
6849 0x0000014d,
6850 0x02110211,
6851 0x0000014d,
6852 0x02110211,
6853 0x0000014d,
6854 0x02110211,
6855 0x0000014d,
6856 0x02110211,
6857 0x0000014d,
6858 0x02110211,
6859 0x0000014d,
6860 0x02110211,
6861 0x0000014d,
6862 0x02110211,
6863 0x0000014d,
6864 0x02110211,
6865 0x0000014d,
6866 0x02110211,
6867 0x0000014d,
6868 0x02110211,
6869 0x0000014d,
6870 0x02110211,
6871 0x0000014d,
6872 0x02110211,
6873 0x0000014d,
6874 0x02110211,
6875 0x0000014d,
6876 0x02110211,
6877 0x0000014d,
6878 0x02110211,
6879 0x0000014d,
6880 0x02110211,
6881 0x0000014d,
6882 0x02110211,
6883 0x0000014d,
6884 0x02110211,
6885 0x0000014d,
6886 0x02110211,
6887 0x0000014d,
6888 0x02110211,
6889 0x0000014d,
6890 0x02110211,
6891 0x0000014d,
6892 0x02110211,
6893 0x0000014d,
6894 0x02110211,
6895 0x0000014d,
6896 0x02110211,
6897 0x0000014d,
6898 0x02110211,
6899 0x0000014d,
6900 0x02110211,
6901 0x0000014d,
6902 0x02110211,
6903 0x0000014d,
6904 0x02110211,
6905 0x0000014d,
6906 0x02110211,
6907 0x0000014d,
6908 0x02110211,
6909 0x0000014d,
6910 0x02110211,
6911 0x0000014d,
6912 0x02110211,
6913 0x0000014d,
6914 0x02110211,
6915 0x0000014d,
6916 0x02110211,
6917 0x0000014d,
6918 0x02110211,
6919 0x0000014d,
6920 0x02110211,
6921 0x0000014d,
6922 0x02110211,
6923 0x0000014d,
6924 0x02110211,
6925 0x0000014d,
6926 0x02110211,
6927 0x0000014d,
6928 0x02110211,
6929 0x0000014d,
6930 0x02110211,
6931 0x0000014d,
6932 0x02110211,
6933 0x0000014d,
6934 0x02110211,
6935 0x0000014d,
6936 0x02110211,
6937 0x0000014d,
6938 0x02110211,
6939 0x0000014d,
6940 0x02110211,
6941 0x0000014d,
6942 0x02110211,
6943 0x0000014d,
6944 0x02110211,
6945 0x0000014d,
6946 0x02110211,
6947 0x0000014d,
6948 0x02110211,
6949 0x0000014d,
6950 0x02110211,
6951 0x0000014d,
6952 0x02110211,
6953 0x0000014d,
6954 0x02110211,
6955 0x0000014d,
6956 0x02110211,
6957 0x0000014d,
6958 0x02110211,
6959 0x0000014d,
6960 0x02110211,
6961 0x0000014d,
6962 0x02110211,
6963 0x0000014d,
6964 0x02110211,
6965 0x0000014d,
6966 0x02110211,
6967 0x0000014d,
6968 0x02110211,
6969 0x0000014d,
6970 0x02110211,
6971 0x0000014d,
6972 0x02110211,
6973 0x0000014d,
6974 0x02110211,
6975 0x0000014d,
6976 0x02110211,
6977 0x0000014d,
6978 0x02110211,
6979 0x0000014d,
6980 0x02110211,
6981 0x0000014d,
6982 0x02110211,
6983 0x0000014d,
6984 0x02110211,
6985 0x0000014d,
6986 0x02110211,
6987 0x0000014d,
6988 0x02110211,
6989 0x0000014d,
6990 0x02110211,
6991 0x0000014d,
6992 0x02110211,
6993 0x0000014d,
6994 0x02110211,
6995 0x0000014d,
6996 0x02110211,
6997 0x0000014d,
6998 0x02110211,
6999 0x0000014d,
7000 0x02110211,
7001 0x0000014d,
7002 0x02110211,
7003 0x0000014d,
7004 0x02110211,
7005 0x0000014d,
7006 0x02110211,
7007 0x0000014d,
7008 0x02110211,
7009 0x0000014d,
7010 0x02110211,
7011 0x0000014d,
7012 0x02110211,
7013 0x0000014d,
7014 0x02110211,
7015 0x0000014d,
7016 0x02110211,
7017 0x0000014d,
7018 0x02110211,
7019 0x0000014d,
7020 0x02110211,
7021 0x0000014d,
7022 0x02110211,
7023 0x0000014d,
7024 0x02110211,
7025 0x0000014d,
7026 0x02110211,
7027 0x0000014d,
7028 0x02110211,
7029 0x0000014d,
7030 0x02110211,
7031 0x0000014d,
7032 0x02110211,
7033 0x0000014d,
7034};
7035
7036const u16 mcs_tbl_rev3[] = {
7037 0x0000,
7038 0x0008,
7039 0x000a,
7040 0x0010,
7041 0x0012,
7042 0x0019,
7043 0x001a,
7044 0x001c,
7045 0x0080,
7046 0x0088,
7047 0x008a,
7048 0x0090,
7049 0x0092,
7050 0x0099,
7051 0x009a,
7052 0x009c,
7053 0x0100,
7054 0x0108,
7055 0x010a,
7056 0x0110,
7057 0x0112,
7058 0x0119,
7059 0x011a,
7060 0x011c,
7061 0x0180,
7062 0x0188,
7063 0x018a,
7064 0x0190,
7065 0x0192,
7066 0x0199,
7067 0x019a,
7068 0x019c,
7069 0x0000,
7070 0x0098,
7071 0x00a0,
7072 0x00a8,
7073 0x009a,
7074 0x00a2,
7075 0x00aa,
7076 0x0120,
7077 0x0128,
7078 0x0128,
7079 0x0130,
7080 0x0138,
7081 0x0138,
7082 0x0140,
7083 0x0122,
7084 0x012a,
7085 0x012a,
7086 0x0132,
7087 0x013a,
7088 0x013a,
7089 0x0142,
7090 0x01a8,
7091 0x01b0,
7092 0x01b8,
7093 0x01b0,
7094 0x01b8,
7095 0x01c0,
7096 0x01c8,
7097 0x01c0,
7098 0x01c8,
7099 0x01d0,
7100 0x01d0,
7101 0x01d8,
7102 0x01aa,
7103 0x01b2,
7104 0x01ba,
7105 0x01b2,
7106 0x01ba,
7107 0x01c2,
7108 0x01ca,
7109 0x01c2,
7110 0x01ca,
7111 0x01d2,
7112 0x01d2,
7113 0x01da,
7114 0x0001,
7115 0x0002,
7116 0x0004,
7117 0x0009,
7118 0x000c,
7119 0x0011,
7120 0x0014,
7121 0x0018,
7122 0x0020,
7123 0x0021,
7124 0x0022,
7125 0x0024,
7126 0x0081,
7127 0x0082,
7128 0x0084,
7129 0x0089,
7130 0x008c,
7131 0x0091,
7132 0x0094,
7133 0x0098,
7134 0x00a0,
7135 0x00a1,
7136 0x00a2,
7137 0x00a4,
7138 0x0007,
7139 0x0007,
7140 0x0007,
7141 0x0007,
7142 0x0007,
7143 0x0007,
7144 0x0007,
7145 0x0007,
7146 0x0007,
7147 0x0007,
7148 0x0007,
7149 0x0007,
7150 0x0007,
7151 0x0007,
7152 0x0007,
7153 0x0007,
7154 0x0007,
7155 0x0007,
7156 0x0007,
7157 0x0007,
7158 0x0007,
7159 0x0007,
7160 0x0007,
7161 0x0007,
7162 0x0007,
7163 0x0007,
7164 0x0007,
7165};
7166
7167const u32 tdi_tbl20_ant0_rev3[] = {
7168 0x00091226,
7169 0x000a1429,
7170 0x000b56ad,
7171 0x000c58b0,
7172 0x000d5ab3,
7173 0x000e9cb6,
7174 0x000f9eba,
7175 0x0000c13d,
7176 0x00020301,
7177 0x00030504,
7178 0x00040708,
7179 0x0005090b,
7180 0x00064b8e,
7181 0x00095291,
7182 0x000a5494,
7183 0x000b9718,
7184 0x000c9927,
7185 0x000d9b2a,
7186 0x000edd2e,
7187 0x000fdf31,
7188 0x000101b4,
7189 0x000243b7,
7190 0x000345bb,
7191 0x000447be,
7192 0x00058982,
7193 0x00068c05,
7194 0x00099309,
7195 0x000a950c,
7196 0x000bd78f,
7197 0x000cd992,
7198 0x000ddb96,
7199 0x000f1d99,
7200 0x00005fa8,
7201 0x0001422c,
7202 0x0002842f,
7203 0x00038632,
7204 0x00048835,
7205 0x0005ca38,
7206 0x0006ccbc,
7207 0x0009d3bf,
7208 0x000b1603,
7209 0x000c1806,
7210 0x000d1a0a,
7211 0x000e1c0d,
7212 0x000f5e10,
7213 0x00008093,
7214 0x00018297,
7215 0x0002c49a,
7216 0x0003c680,
7217 0x0004c880,
7218 0x00060b00,
7219 0x00070d00,
7220 0x00000000,
7221 0x00000000,
7222 0x00000000,
7223};
7224
7225const u32 tdi_tbl20_ant1_rev3[] = {
7226 0x00014b26,
7227 0x00028d29,
7228 0x000393ad,
7229 0x00049630,
7230 0x0005d833,
7231 0x0006da36,
7232 0x00099c3a,
7233 0x000a9e3d,
7234 0x000bc081,
7235 0x000cc284,
7236 0x000dc488,
7237 0x000f068b,
7238 0x0000488e,
7239 0x00018b91,
7240 0x0002d214,
7241 0x0003d418,
7242 0x0004d6a7,
7243 0x000618aa,
7244 0x00071aae,
7245 0x0009dcb1,
7246 0x000b1eb4,
7247 0x000c0137,
7248 0x000d033b,
7249 0x000e053e,
7250 0x000f4702,
7251 0x00008905,
7252 0x00020c09,
7253 0x0003128c,
7254 0x0004148f,
7255 0x00051712,
7256 0x00065916,
7257 0x00091b19,
7258 0x000a1d28,
7259 0x000b5f2c,
7260 0x000c41af,
7261 0x000d43b2,
7262 0x000e85b5,
7263 0x000f87b8,
7264 0x0000c9bc,
7265 0x00024cbf,
7266 0x00035303,
7267 0x00045506,
7268 0x0005978a,
7269 0x0006998d,
7270 0x00095b90,
7271 0x000a5d93,
7272 0x000b9f97,
7273 0x000c821a,
7274 0x000d8400,
7275 0x000ec600,
7276 0x000fc800,
7277 0x00010a00,
7278 0x00000000,
7279 0x00000000,
7280 0x00000000,
7281};
7282
7283const u32 tdi_tbl40_ant0_rev3[] = {
7284 0x0011a346,
7285 0x00136ccf,
7286 0x0014f5d9,
7287 0x001641e2,
7288 0x0017cb6b,
7289 0x00195475,
7290 0x001b2383,
7291 0x001cad0c,
7292 0x001e7616,
7293 0x0000821f,
7294 0x00020ba8,
7295 0x0003d4b2,
7296 0x00056447,
7297 0x00072dd0,
7298 0x0008b6da,
7299 0x000a02e3,
7300 0x000b8c6c,
7301 0x000d15f6,
7302 0x0011e484,
7303 0x0013ae0d,
7304 0x00153717,
7305 0x00168320,
7306 0x00180ca9,
7307 0x00199633,
7308 0x001b6548,
7309 0x001ceed1,
7310 0x001eb7db,
7311 0x0000c3e4,
7312 0x00024d6d,
7313 0x000416f7,
7314 0x0005a585,
7315 0x00076f0f,
7316 0x0008f818,
7317 0x000a4421,
7318 0x000bcdab,
7319 0x000d9734,
7320 0x00122649,
7321 0x0013efd2,
7322 0x001578dc,
7323 0x0016c4e5,
7324 0x00184e6e,
7325 0x001a17f8,
7326 0x001ba686,
7327 0x001d3010,
7328 0x001ef999,
7329 0x00010522,
7330 0x00028eac,
7331 0x00045835,
7332 0x0005e74a,
7333 0x0007b0d3,
7334 0x00093a5d,
7335 0x000a85e6,
7336 0x000c0f6f,
7337 0x000dd8f9,
7338 0x00126787,
7339 0x00143111,
7340 0x0015ba9a,
7341 0x00170623,
7342 0x00188fad,
7343 0x001a5936,
7344 0x001be84b,
7345 0x001db1d4,
7346 0x001f3b5e,
7347 0x000146e7,
7348 0x00031070,
7349 0x000499fa,
7350 0x00062888,
7351 0x0007f212,
7352 0x00097b9b,
7353 0x000ac7a4,
7354 0x000c50ae,
7355 0x000e1a37,
7356 0x0012a94c,
7357 0x001472d5,
7358 0x0015fc5f,
7359 0x00174868,
7360 0x0018d171,
7361 0x001a9afb,
7362 0x001c2989,
7363 0x001df313,
7364 0x001f7c9c,
7365 0x000188a5,
7366 0x000351af,
7367 0x0004db38,
7368 0x0006aa4d,
7369 0x000833d7,
7370 0x0009bd60,
7371 0x000b0969,
7372 0x000c9273,
7373 0x000e5bfc,
7374 0x00132a8a,
7375 0x0014b414,
7376 0x00163d9d,
7377 0x001789a6,
7378 0x001912b0,
7379 0x001adc39,
7380 0x001c6bce,
7381 0x001e34d8,
7382 0x001fbe61,
7383 0x0001ca6a,
7384 0x00039374,
7385 0x00051cfd,
7386 0x0006ec0b,
7387 0x00087515,
7388 0x0009fe9e,
7389 0x000b4aa7,
7390 0x000cd3b1,
7391 0x000e9d3a,
7392 0x00000000,
7393 0x00000000,
7394};
7395
7396const u32 tdi_tbl40_ant1_rev3[] = {
7397 0x001edb36,
7398 0x000129ca,
7399 0x0002b353,
7400 0x00047cdd,
7401 0x0005c8e6,
7402 0x000791ef,
7403 0x00091bf9,
7404 0x000aaa07,
7405 0x000c3391,
7406 0x000dfd1a,
7407 0x00120923,
7408 0x0013d22d,
7409 0x00155c37,
7410 0x0016eacb,
7411 0x00187454,
7412 0x001a3dde,
7413 0x001b89e7,
7414 0x001d12f0,
7415 0x001f1cfa,
7416 0x00016b88,
7417 0x00033492,
7418 0x0004be1b,
7419 0x00060a24,
7420 0x0007d32e,
7421 0x00095d38,
7422 0x000aec4c,
7423 0x000c7555,
7424 0x000e3edf,
7425 0x00124ae8,
7426 0x001413f1,
7427 0x0015a37b,
7428 0x00172c89,
7429 0x0018b593,
7430 0x001a419c,
7431 0x001bcb25,
7432 0x001d942f,
7433 0x001f63b9,
7434 0x0001ad4d,
7435 0x00037657,
7436 0x0004c260,
7437 0x00068be9,
7438 0x000814f3,
7439 0x0009a47c,
7440 0x000b2d8a,
7441 0x000cb694,
7442 0x000e429d,
7443 0x00128c26,
7444 0x001455b0,
7445 0x0015e4ba,
7446 0x00176e4e,
7447 0x0018f758,
7448 0x001a8361,
7449 0x001c0cea,
7450 0x001dd674,
7451 0x001fa57d,
7452 0x0001ee8b,
7453 0x0003b795,
7454 0x0005039e,
7455 0x0006cd27,
7456 0x000856b1,
7457 0x0009e5c6,
7458 0x000b6f4f,
7459 0x000cf859,
7460 0x000e8462,
7461 0x00130deb,
7462 0x00149775,
7463 0x00162603,
7464 0x0017af8c,
7465 0x00193896,
7466 0x001ac49f,
7467 0x001c4e28,
7468 0x001e17b2,
7469 0x0000a6c7,
7470 0x00023050,
7471 0x0003f9da,
7472 0x00054563,
7473 0x00070eec,
7474 0x00089876,
7475 0x000a2704,
7476 0x000bb08d,
7477 0x000d3a17,
7478 0x001185a0,
7479 0x00134f29,
7480 0x0014d8b3,
7481 0x001667c8,
7482 0x0017f151,
7483 0x00197adb,
7484 0x001b0664,
7485 0x001c8fed,
7486 0x001e5977,
7487 0x0000e805,
7488 0x0002718f,
7489 0x00043b18,
7490 0x000586a1,
7491 0x0007502b,
7492 0x0008d9b4,
7493 0x000a68c9,
7494 0x000bf252,
7495 0x000dbbdc,
7496 0x0011c7e5,
7497 0x001390ee,
7498 0x00151a78,
7499 0x0016a906,
7500 0x00183290,
7501 0x0019bc19,
7502 0x001b4822,
7503 0x001cd12c,
7504 0x001e9ab5,
7505 0x00000000,
7506 0x00000000,
7507};
7508
7509const u32 pltlut_tbl_rev3[] = {
7510 0x76540213,
7511 0x62407351,
7512 0x76543210,
7513 0x76540213,
7514 0x76540213,
7515 0x76430521,
7516};
7517
7518const u32 chanest_tbl_rev3[] = {
7519 0x44444444,
7520 0x44444444,
7521 0x44444444,
7522 0x44444444,
7523 0x44444444,
7524 0x44444444,
7525 0x44444444,
7526 0x44444444,
7527 0x10101010,
7528 0x10101010,
7529 0x10101010,
7530 0x10101010,
7531 0x10101010,
7532 0x10101010,
7533 0x10101010,
7534 0x10101010,
7535 0x44444444,
7536 0x44444444,
7537 0x44444444,
7538 0x44444444,
7539 0x44444444,
7540 0x44444444,
7541 0x44444444,
7542 0x44444444,
7543 0x10101010,
7544 0x10101010,
7545 0x10101010,
7546 0x10101010,
7547 0x10101010,
7548 0x10101010,
7549 0x10101010,
7550 0x10101010,
7551 0x44444444,
7552 0x44444444,
7553 0x44444444,
7554 0x44444444,
7555 0x44444444,
7556 0x44444444,
7557 0x44444444,
7558 0x44444444,
7559 0x44444444,
7560 0x44444444,
7561 0x44444444,
7562 0x44444444,
7563 0x44444444,
7564 0x44444444,
7565 0x44444444,
7566 0x44444444,
7567 0x10101010,
7568 0x10101010,
7569 0x10101010,
7570 0x10101010,
7571 0x10101010,
7572 0x10101010,
7573 0x10101010,
7574 0x10101010,
7575 0x10101010,
7576 0x10101010,
7577 0x10101010,
7578 0x10101010,
7579 0x10101010,
7580 0x10101010,
7581 0x10101010,
7582 0x10101010,
7583 0x44444444,
7584 0x44444444,
7585 0x44444444,
7586 0x44444444,
7587 0x44444444,
7588 0x44444444,
7589 0x44444444,
7590 0x44444444,
7591 0x44444444,
7592 0x44444444,
7593 0x44444444,
7594 0x44444444,
7595 0x44444444,
7596 0x44444444,
7597 0x44444444,
7598 0x44444444,
7599 0x10101010,
7600 0x10101010,
7601 0x10101010,
7602 0x10101010,
7603 0x10101010,
7604 0x10101010,
7605 0x10101010,
7606 0x10101010,
7607 0x10101010,
7608 0x10101010,
7609 0x10101010,
7610 0x10101010,
7611 0x10101010,
7612 0x10101010,
7613 0x10101010,
7614 0x10101010,
7615};
7616
7617const u8 frame_lut_rev3[] = {
7618 0x02,
7619 0x04,
7620 0x14,
7621 0x14,
7622 0x03,
7623 0x05,
7624 0x16,
7625 0x16,
7626 0x0a,
7627 0x0c,
7628 0x1c,
7629 0x1c,
7630 0x0b,
7631 0x0d,
7632 0x1e,
7633 0x1e,
7634 0x06,
7635 0x08,
7636 0x18,
7637 0x18,
7638 0x07,
7639 0x09,
7640 0x1a,
7641 0x1a,
7642 0x0e,
7643 0x10,
7644 0x20,
7645 0x28,
7646 0x0f,
7647 0x11,
7648 0x22,
7649 0x2a,
7650};
7651
7652const u8 est_pwr_lut_core0_rev3[] = {
7653 0x55,
7654 0x54,
7655 0x54,
7656 0x53,
7657 0x52,
7658 0x52,
7659 0x51,
7660 0x51,
7661 0x50,
7662 0x4f,
7663 0x4f,
7664 0x4e,
7665 0x4e,
7666 0x4d,
7667 0x4c,
7668 0x4c,
7669 0x4b,
7670 0x4a,
7671 0x49,
7672 0x49,
7673 0x48,
7674 0x47,
7675 0x46,
7676 0x46,
7677 0x45,
7678 0x44,
7679 0x43,
7680 0x42,
7681 0x41,
7682 0x40,
7683 0x40,
7684 0x3f,
7685 0x3e,
7686 0x3d,
7687 0x3c,
7688 0x3a,
7689 0x39,
7690 0x38,
7691 0x37,
7692 0x36,
7693 0x35,
7694 0x33,
7695 0x32,
7696 0x31,
7697 0x2f,
7698 0x2e,
7699 0x2c,
7700 0x2b,
7701 0x29,
7702 0x27,
7703 0x25,
7704 0x23,
7705 0x21,
7706 0x1f,
7707 0x1d,
7708 0x1a,
7709 0x18,
7710 0x15,
7711 0x12,
7712 0x0e,
7713 0x0b,
7714 0x07,
7715 0x02,
7716 0xfd,
7717};
7718
7719const u8 est_pwr_lut_core1_rev3[] = {
7720 0x55,
7721 0x54,
7722 0x54,
7723 0x53,
7724 0x52,
7725 0x52,
7726 0x51,
7727 0x51,
7728 0x50,
7729 0x4f,
7730 0x4f,
7731 0x4e,
7732 0x4e,
7733 0x4d,
7734 0x4c,
7735 0x4c,
7736 0x4b,
7737 0x4a,
7738 0x49,
7739 0x49,
7740 0x48,
7741 0x47,
7742 0x46,
7743 0x46,
7744 0x45,
7745 0x44,
7746 0x43,
7747 0x42,
7748 0x41,
7749 0x40,
7750 0x40,
7751 0x3f,
7752 0x3e,
7753 0x3d,
7754 0x3c,
7755 0x3a,
7756 0x39,
7757 0x38,
7758 0x37,
7759 0x36,
7760 0x35,
7761 0x33,
7762 0x32,
7763 0x31,
7764 0x2f,
7765 0x2e,
7766 0x2c,
7767 0x2b,
7768 0x29,
7769 0x27,
7770 0x25,
7771 0x23,
7772 0x21,
7773 0x1f,
7774 0x1d,
7775 0x1a,
7776 0x18,
7777 0x15,
7778 0x12,
7779 0x0e,
7780 0x0b,
7781 0x07,
7782 0x02,
7783 0xfd,
7784};
7785
7786const u8 adj_pwr_lut_core0_rev3[] = {
7787 0x00,
7788 0x00,
7789 0x00,
7790 0x00,
7791 0x00,
7792 0x00,
7793 0x00,
7794 0x00,
7795 0x00,
7796 0x00,
7797 0x00,
7798 0x00,
7799 0x00,
7800 0x00,
7801 0x00,
7802 0x00,
7803 0x00,
7804 0x00,
7805 0x00,
7806 0x00,
7807 0x00,
7808 0x00,
7809 0x00,
7810 0x00,
7811 0x00,
7812 0x00,
7813 0x00,
7814 0x00,
7815 0x00,
7816 0x00,
7817 0x00,
7818 0x00,
7819 0x00,
7820 0x00,
7821 0x00,
7822 0x00,
7823 0x00,
7824 0x00,
7825 0x00,
7826 0x00,
7827 0x00,
7828 0x00,
7829 0x00,
7830 0x00,
7831 0x00,
7832 0x00,
7833 0x00,
7834 0x00,
7835 0x00,
7836 0x00,
7837 0x00,
7838 0x00,
7839 0x00,
7840 0x00,
7841 0x00,
7842 0x00,
7843 0x00,
7844 0x00,
7845 0x00,
7846 0x00,
7847 0x00,
7848 0x00,
7849 0x00,
7850 0x00,
7851 0x00,
7852 0x00,
7853 0x00,
7854 0x00,
7855 0x00,
7856 0x00,
7857 0x00,
7858 0x00,
7859 0x00,
7860 0x00,
7861 0x00,
7862 0x00,
7863 0x00,
7864 0x00,
7865 0x00,
7866 0x00,
7867 0x00,
7868 0x00,
7869 0x00,
7870 0x00,
7871 0x00,
7872 0x00,
7873 0x00,
7874 0x00,
7875 0x00,
7876 0x00,
7877 0x00,
7878 0x00,
7879 0x00,
7880 0x00,
7881 0x00,
7882 0x00,
7883 0x00,
7884 0x00,
7885 0x00,
7886 0x00,
7887 0x00,
7888 0x00,
7889 0x00,
7890 0x00,
7891 0x00,
7892 0x00,
7893 0x00,
7894 0x00,
7895 0x00,
7896 0x00,
7897 0x00,
7898 0x00,
7899 0x00,
7900 0x00,
7901 0x00,
7902 0x00,
7903 0x00,
7904 0x00,
7905 0x00,
7906 0x00,
7907 0x00,
7908 0x00,
7909 0x00,
7910 0x00,
7911 0x00,
7912 0x00,
7913 0x00,
7914 0x00,
7915};
7916
7917const u8 adj_pwr_lut_core1_rev3[] = {
7918 0x00,
7919 0x00,
7920 0x00,
7921 0x00,
7922 0x00,
7923 0x00,
7924 0x00,
7925 0x00,
7926 0x00,
7927 0x00,
7928 0x00,
7929 0x00,
7930 0x00,
7931 0x00,
7932 0x00,
7933 0x00,
7934 0x00,
7935 0x00,
7936 0x00,
7937 0x00,
7938 0x00,
7939 0x00,
7940 0x00,
7941 0x00,
7942 0x00,
7943 0x00,
7944 0x00,
7945 0x00,
7946 0x00,
7947 0x00,
7948 0x00,
7949 0x00,
7950 0x00,
7951 0x00,
7952 0x00,
7953 0x00,
7954 0x00,
7955 0x00,
7956 0x00,
7957 0x00,
7958 0x00,
7959 0x00,
7960 0x00,
7961 0x00,
7962 0x00,
7963 0x00,
7964 0x00,
7965 0x00,
7966 0x00,
7967 0x00,
7968 0x00,
7969 0x00,
7970 0x00,
7971 0x00,
7972 0x00,
7973 0x00,
7974 0x00,
7975 0x00,
7976 0x00,
7977 0x00,
7978 0x00,
7979 0x00,
7980 0x00,
7981 0x00,
7982 0x00,
7983 0x00,
7984 0x00,
7985 0x00,
7986 0x00,
7987 0x00,
7988 0x00,
7989 0x00,
7990 0x00,
7991 0x00,
7992 0x00,
7993 0x00,
7994 0x00,
7995 0x00,
7996 0x00,
7997 0x00,
7998 0x00,
7999 0x00,
8000 0x00,
8001 0x00,
8002 0x00,
8003 0x00,
8004 0x00,
8005 0x00,
8006 0x00,
8007 0x00,
8008 0x00,
8009 0x00,
8010 0x00,
8011 0x00,
8012 0x00,
8013 0x00,
8014 0x00,
8015 0x00,
8016 0x00,
8017 0x00,
8018 0x00,
8019 0x00,
8020 0x00,
8021 0x00,
8022 0x00,
8023 0x00,
8024 0x00,
8025 0x00,
8026 0x00,
8027 0x00,
8028 0x00,
8029 0x00,
8030 0x00,
8031 0x00,
8032 0x00,
8033 0x00,
8034 0x00,
8035 0x00,
8036 0x00,
8037 0x00,
8038 0x00,
8039 0x00,
8040 0x00,
8041 0x00,
8042 0x00,
8043 0x00,
8044 0x00,
8045 0x00,
8046};
8047
8048const u32 gainctrl_lut_core0_rev3[] = {
8049 0x5bf70044,
8050 0x5bf70042,
8051 0x5bf70040,
8052 0x5bf7003e,
8053 0x5bf7003c,
8054 0x5bf7003b,
8055 0x5bf70039,
8056 0x5bf70037,
8057 0x5bf70036,
8058 0x5bf70034,
8059 0x5bf70033,
8060 0x5bf70031,
8061 0x5bf70030,
8062 0x5ba70044,
8063 0x5ba70042,
8064 0x5ba70040,
8065 0x5ba7003e,
8066 0x5ba7003c,
8067 0x5ba7003b,
8068 0x5ba70039,
8069 0x5ba70037,
8070 0x5ba70036,
8071 0x5ba70034,
8072 0x5ba70033,
8073 0x5b770044,
8074 0x5b770042,
8075 0x5b770040,
8076 0x5b77003e,
8077 0x5b77003c,
8078 0x5b77003b,
8079 0x5b770039,
8080 0x5b770037,
8081 0x5b770036,
8082 0x5b770034,
8083 0x5b770033,
8084 0x5b770031,
8085 0x5b770030,
8086 0x5b77002f,
8087 0x5b77002d,
8088 0x5b77002c,
8089 0x5b470044,
8090 0x5b470042,
8091 0x5b470040,
8092 0x5b47003e,
8093 0x5b47003c,
8094 0x5b47003b,
8095 0x5b470039,
8096 0x5b470037,
8097 0x5b470036,
8098 0x5b470034,
8099 0x5b470033,
8100 0x5b470031,
8101 0x5b470030,
8102 0x5b47002f,
8103 0x5b47002d,
8104 0x5b47002c,
8105 0x5b47002b,
8106 0x5b47002a,
8107 0x5b270044,
8108 0x5b270042,
8109 0x5b270040,
8110 0x5b27003e,
8111 0x5b27003c,
8112 0x5b27003b,
8113 0x5b270039,
8114 0x5b270037,
8115 0x5b270036,
8116 0x5b270034,
8117 0x5b270033,
8118 0x5b270031,
8119 0x5b270030,
8120 0x5b27002f,
8121 0x5b170044,
8122 0x5b170042,
8123 0x5b170040,
8124 0x5b17003e,
8125 0x5b17003c,
8126 0x5b17003b,
8127 0x5b170039,
8128 0x5b170037,
8129 0x5b170036,
8130 0x5b170034,
8131 0x5b170033,
8132 0x5b170031,
8133 0x5b170030,
8134 0x5b17002f,
8135 0x5b17002d,
8136 0x5b17002c,
8137 0x5b17002b,
8138 0x5b17002a,
8139 0x5b170028,
8140 0x5b170027,
8141 0x5b170026,
8142 0x5b170025,
8143 0x5b170024,
8144 0x5b170023,
8145 0x5b070044,
8146 0x5b070042,
8147 0x5b070040,
8148 0x5b07003e,
8149 0x5b07003c,
8150 0x5b07003b,
8151 0x5b070039,
8152 0x5b070037,
8153 0x5b070036,
8154 0x5b070034,
8155 0x5b070033,
8156 0x5b070031,
8157 0x5b070030,
8158 0x5b07002f,
8159 0x5b07002d,
8160 0x5b07002c,
8161 0x5b07002b,
8162 0x5b07002a,
8163 0x5b070028,
8164 0x5b070027,
8165 0x5b070026,
8166 0x5b070025,
8167 0x5b070024,
8168 0x5b070023,
8169 0x5b070022,
8170 0x5b070021,
8171 0x5b070020,
8172 0x5b07001f,
8173 0x5b07001e,
8174 0x5b07001d,
8175 0x5b07001d,
8176 0x5b07001c,
8177};
8178
8179const u32 gainctrl_lut_core1_rev3[] = {
8180 0x5bf70044,
8181 0x5bf70042,
8182 0x5bf70040,
8183 0x5bf7003e,
8184 0x5bf7003c,
8185 0x5bf7003b,
8186 0x5bf70039,
8187 0x5bf70037,
8188 0x5bf70036,
8189 0x5bf70034,
8190 0x5bf70033,
8191 0x5bf70031,
8192 0x5bf70030,
8193 0x5ba70044,
8194 0x5ba70042,
8195 0x5ba70040,
8196 0x5ba7003e,
8197 0x5ba7003c,
8198 0x5ba7003b,
8199 0x5ba70039,
8200 0x5ba70037,
8201 0x5ba70036,
8202 0x5ba70034,
8203 0x5ba70033,
8204 0x5b770044,
8205 0x5b770042,
8206 0x5b770040,
8207 0x5b77003e,
8208 0x5b77003c,
8209 0x5b77003b,
8210 0x5b770039,
8211 0x5b770037,
8212 0x5b770036,
8213 0x5b770034,
8214 0x5b770033,
8215 0x5b770031,
8216 0x5b770030,
8217 0x5b77002f,
8218 0x5b77002d,
8219 0x5b77002c,
8220 0x5b470044,
8221 0x5b470042,
8222 0x5b470040,
8223 0x5b47003e,
8224 0x5b47003c,
8225 0x5b47003b,
8226 0x5b470039,
8227 0x5b470037,
8228 0x5b470036,
8229 0x5b470034,
8230 0x5b470033,
8231 0x5b470031,
8232 0x5b470030,
8233 0x5b47002f,
8234 0x5b47002d,
8235 0x5b47002c,
8236 0x5b47002b,
8237 0x5b47002a,
8238 0x5b270044,
8239 0x5b270042,
8240 0x5b270040,
8241 0x5b27003e,
8242 0x5b27003c,
8243 0x5b27003b,
8244 0x5b270039,
8245 0x5b270037,
8246 0x5b270036,
8247 0x5b270034,
8248 0x5b270033,
8249 0x5b270031,
8250 0x5b270030,
8251 0x5b27002f,
8252 0x5b170044,
8253 0x5b170042,
8254 0x5b170040,
8255 0x5b17003e,
8256 0x5b17003c,
8257 0x5b17003b,
8258 0x5b170039,
8259 0x5b170037,
8260 0x5b170036,
8261 0x5b170034,
8262 0x5b170033,
8263 0x5b170031,
8264 0x5b170030,
8265 0x5b17002f,
8266 0x5b17002d,
8267 0x5b17002c,
8268 0x5b17002b,
8269 0x5b17002a,
8270 0x5b170028,
8271 0x5b170027,
8272 0x5b170026,
8273 0x5b170025,
8274 0x5b170024,
8275 0x5b170023,
8276 0x5b070044,
8277 0x5b070042,
8278 0x5b070040,
8279 0x5b07003e,
8280 0x5b07003c,
8281 0x5b07003b,
8282 0x5b070039,
8283 0x5b070037,
8284 0x5b070036,
8285 0x5b070034,
8286 0x5b070033,
8287 0x5b070031,
8288 0x5b070030,
8289 0x5b07002f,
8290 0x5b07002d,
8291 0x5b07002c,
8292 0x5b07002b,
8293 0x5b07002a,
8294 0x5b070028,
8295 0x5b070027,
8296 0x5b070026,
8297 0x5b070025,
8298 0x5b070024,
8299 0x5b070023,
8300 0x5b070022,
8301 0x5b070021,
8302 0x5b070020,
8303 0x5b07001f,
8304 0x5b07001e,
8305 0x5b07001d,
8306 0x5b07001d,
8307 0x5b07001c,
8308};
8309
8310const u32 iq_lut_core0_rev3[] = {
8311 0x00000000,
8312 0x00000000,
8313 0x00000000,
8314 0x00000000,
8315 0x00000000,
8316 0x00000000,
8317 0x00000000,
8318 0x00000000,
8319 0x00000000,
8320 0x00000000,
8321 0x00000000,
8322 0x00000000,
8323 0x00000000,
8324 0x00000000,
8325 0x00000000,
8326 0x00000000,
8327 0x00000000,
8328 0x00000000,
8329 0x00000000,
8330 0x00000000,
8331 0x00000000,
8332 0x00000000,
8333 0x00000000,
8334 0x00000000,
8335 0x00000000,
8336 0x00000000,
8337 0x00000000,
8338 0x00000000,
8339 0x00000000,
8340 0x00000000,
8341 0x00000000,
8342 0x00000000,
8343 0x00000000,
8344 0x00000000,
8345 0x00000000,
8346 0x00000000,
8347 0x00000000,
8348 0x00000000,
8349 0x00000000,
8350 0x00000000,
8351 0x00000000,
8352 0x00000000,
8353 0x00000000,
8354 0x00000000,
8355 0x00000000,
8356 0x00000000,
8357 0x00000000,
8358 0x00000000,
8359 0x00000000,
8360 0x00000000,
8361 0x00000000,
8362 0x00000000,
8363 0x00000000,
8364 0x00000000,
8365 0x00000000,
8366 0x00000000,
8367 0x00000000,
8368 0x00000000,
8369 0x00000000,
8370 0x00000000,
8371 0x00000000,
8372 0x00000000,
8373 0x00000000,
8374 0x00000000,
8375 0x00000000,
8376 0x00000000,
8377 0x00000000,
8378 0x00000000,
8379 0x00000000,
8380 0x00000000,
8381 0x00000000,
8382 0x00000000,
8383 0x00000000,
8384 0x00000000,
8385 0x00000000,
8386 0x00000000,
8387 0x00000000,
8388 0x00000000,
8389 0x00000000,
8390 0x00000000,
8391 0x00000000,
8392 0x00000000,
8393 0x00000000,
8394 0x00000000,
8395 0x00000000,
8396 0x00000000,
8397 0x00000000,
8398 0x00000000,
8399 0x00000000,
8400 0x00000000,
8401 0x00000000,
8402 0x00000000,
8403 0x00000000,
8404 0x00000000,
8405 0x00000000,
8406 0x00000000,
8407 0x00000000,
8408 0x00000000,
8409 0x00000000,
8410 0x00000000,
8411 0x00000000,
8412 0x00000000,
8413 0x00000000,
8414 0x00000000,
8415 0x00000000,
8416 0x00000000,
8417 0x00000000,
8418 0x00000000,
8419 0x00000000,
8420 0x00000000,
8421 0x00000000,
8422 0x00000000,
8423 0x00000000,
8424 0x00000000,
8425 0x00000000,
8426 0x00000000,
8427 0x00000000,
8428 0x00000000,
8429 0x00000000,
8430 0x00000000,
8431 0x00000000,
8432 0x00000000,
8433 0x00000000,
8434 0x00000000,
8435 0x00000000,
8436 0x00000000,
8437 0x00000000,
8438 0x00000000,
8439};
8440
8441const u32 iq_lut_core1_rev3[] = {
8442 0x00000000,
8443 0x00000000,
8444 0x00000000,
8445 0x00000000,
8446 0x00000000,
8447 0x00000000,
8448 0x00000000,
8449 0x00000000,
8450 0x00000000,
8451 0x00000000,
8452 0x00000000,
8453 0x00000000,
8454 0x00000000,
8455 0x00000000,
8456 0x00000000,
8457 0x00000000,
8458 0x00000000,
8459 0x00000000,
8460 0x00000000,
8461 0x00000000,
8462 0x00000000,
8463 0x00000000,
8464 0x00000000,
8465 0x00000000,
8466 0x00000000,
8467 0x00000000,
8468 0x00000000,
8469 0x00000000,
8470 0x00000000,
8471 0x00000000,
8472 0x00000000,
8473 0x00000000,
8474 0x00000000,
8475 0x00000000,
8476 0x00000000,
8477 0x00000000,
8478 0x00000000,
8479 0x00000000,
8480 0x00000000,
8481 0x00000000,
8482 0x00000000,
8483 0x00000000,
8484 0x00000000,
8485 0x00000000,
8486 0x00000000,
8487 0x00000000,
8488 0x00000000,
8489 0x00000000,
8490 0x00000000,
8491 0x00000000,
8492 0x00000000,
8493 0x00000000,
8494 0x00000000,
8495 0x00000000,
8496 0x00000000,
8497 0x00000000,
8498 0x00000000,
8499 0x00000000,
8500 0x00000000,
8501 0x00000000,
8502 0x00000000,
8503 0x00000000,
8504 0x00000000,
8505 0x00000000,
8506 0x00000000,
8507 0x00000000,
8508 0x00000000,
8509 0x00000000,
8510 0x00000000,
8511 0x00000000,
8512 0x00000000,
8513 0x00000000,
8514 0x00000000,
8515 0x00000000,
8516 0x00000000,
8517 0x00000000,
8518 0x00000000,
8519 0x00000000,
8520 0x00000000,
8521 0x00000000,
8522 0x00000000,
8523 0x00000000,
8524 0x00000000,
8525 0x00000000,
8526 0x00000000,
8527 0x00000000,
8528 0x00000000,
8529 0x00000000,
8530 0x00000000,
8531 0x00000000,
8532 0x00000000,
8533 0x00000000,
8534 0x00000000,
8535 0x00000000,
8536 0x00000000,
8537 0x00000000,
8538 0x00000000,
8539 0x00000000,
8540 0x00000000,
8541 0x00000000,
8542 0x00000000,
8543 0x00000000,
8544 0x00000000,
8545 0x00000000,
8546 0x00000000,
8547 0x00000000,
8548 0x00000000,
8549 0x00000000,
8550 0x00000000,
8551 0x00000000,
8552 0x00000000,
8553 0x00000000,
8554 0x00000000,
8555 0x00000000,
8556 0x00000000,
8557 0x00000000,
8558 0x00000000,
8559 0x00000000,
8560 0x00000000,
8561 0x00000000,
8562 0x00000000,
8563 0x00000000,
8564 0x00000000,
8565 0x00000000,
8566 0x00000000,
8567 0x00000000,
8568 0x00000000,
8569 0x00000000,
8570};
8571
8572const u16 loft_lut_core0_rev3[] = {
8573 0x0000,
8574 0x0000,
8575 0x0000,
8576 0x0000,
8577 0x0000,
8578 0x0000,
8579 0x0000,
8580 0x0000,
8581 0x0000,
8582 0x0000,
8583 0x0000,
8584 0x0000,
8585 0x0000,
8586 0x0000,
8587 0x0000,
8588 0x0000,
8589 0x0000,
8590 0x0000,
8591 0x0000,
8592 0x0000,
8593 0x0000,
8594 0x0000,
8595 0x0000,
8596 0x0000,
8597 0x0000,
8598 0x0000,
8599 0x0000,
8600 0x0000,
8601 0x0000,
8602 0x0000,
8603 0x0000,
8604 0x0000,
8605 0x0000,
8606 0x0000,
8607 0x0000,
8608 0x0000,
8609 0x0000,
8610 0x0000,
8611 0x0000,
8612 0x0000,
8613 0x0000,
8614 0x0000,
8615 0x0000,
8616 0x0000,
8617 0x0000,
8618 0x0000,
8619 0x0000,
8620 0x0000,
8621 0x0000,
8622 0x0000,
8623 0x0000,
8624 0x0000,
8625 0x0000,
8626 0x0000,
8627 0x0000,
8628 0x0000,
8629 0x0000,
8630 0x0000,
8631 0x0000,
8632 0x0000,
8633 0x0000,
8634 0x0000,
8635 0x0000,
8636 0x0000,
8637 0x0000,
8638 0x0000,
8639 0x0000,
8640 0x0000,
8641 0x0000,
8642 0x0000,
8643 0x0000,
8644 0x0000,
8645 0x0000,
8646 0x0000,
8647 0x0000,
8648 0x0000,
8649 0x0000,
8650 0x0000,
8651 0x0000,
8652 0x0000,
8653 0x0000,
8654 0x0000,
8655 0x0000,
8656 0x0000,
8657 0x0000,
8658 0x0000,
8659 0x0000,
8660 0x0000,
8661 0x0000,
8662 0x0000,
8663 0x0000,
8664 0x0000,
8665 0x0000,
8666 0x0000,
8667 0x0000,
8668 0x0000,
8669 0x0000,
8670 0x0000,
8671 0x0000,
8672 0x0000,
8673 0x0000,
8674 0x0000,
8675 0x0000,
8676 0x0000,
8677 0x0000,
8678 0x0000,
8679 0x0000,
8680 0x0000,
8681 0x0000,
8682 0x0000,
8683 0x0000,
8684 0x0000,
8685 0x0000,
8686 0x0000,
8687 0x0000,
8688 0x0000,
8689 0x0000,
8690 0x0000,
8691 0x0000,
8692 0x0000,
8693 0x0000,
8694 0x0000,
8695 0x0000,
8696 0x0000,
8697 0x0000,
8698 0x0000,
8699 0x0000,
8700 0x0000,
8701};
8702
8703const u16 loft_lut_core1_rev3[] = {
8704 0x0000,
8705 0x0000,
8706 0x0000,
8707 0x0000,
8708 0x0000,
8709 0x0000,
8710 0x0000,
8711 0x0000,
8712 0x0000,
8713 0x0000,
8714 0x0000,
8715 0x0000,
8716 0x0000,
8717 0x0000,
8718 0x0000,
8719 0x0000,
8720 0x0000,
8721 0x0000,
8722 0x0000,
8723 0x0000,
8724 0x0000,
8725 0x0000,
8726 0x0000,
8727 0x0000,
8728 0x0000,
8729 0x0000,
8730 0x0000,
8731 0x0000,
8732 0x0000,
8733 0x0000,
8734 0x0000,
8735 0x0000,
8736 0x0000,
8737 0x0000,
8738 0x0000,
8739 0x0000,
8740 0x0000,
8741 0x0000,
8742 0x0000,
8743 0x0000,
8744 0x0000,
8745 0x0000,
8746 0x0000,
8747 0x0000,
8748 0x0000,
8749 0x0000,
8750 0x0000,
8751 0x0000,
8752 0x0000,
8753 0x0000,
8754 0x0000,
8755 0x0000,
8756 0x0000,
8757 0x0000,
8758 0x0000,
8759 0x0000,
8760 0x0000,
8761 0x0000,
8762 0x0000,
8763 0x0000,
8764 0x0000,
8765 0x0000,
8766 0x0000,
8767 0x0000,
8768 0x0000,
8769 0x0000,
8770 0x0000,
8771 0x0000,
8772 0x0000,
8773 0x0000,
8774 0x0000,
8775 0x0000,
8776 0x0000,
8777 0x0000,
8778 0x0000,
8779 0x0000,
8780 0x0000,
8781 0x0000,
8782 0x0000,
8783 0x0000,
8784 0x0000,
8785 0x0000,
8786 0x0000,
8787 0x0000,
8788 0x0000,
8789 0x0000,
8790 0x0000,
8791 0x0000,
8792 0x0000,
8793 0x0000,
8794 0x0000,
8795 0x0000,
8796 0x0000,
8797 0x0000,
8798 0x0000,
8799 0x0000,
8800 0x0000,
8801 0x0000,
8802 0x0000,
8803 0x0000,
8804 0x0000,
8805 0x0000,
8806 0x0000,
8807 0x0000,
8808 0x0000,
8809 0x0000,
8810 0x0000,
8811 0x0000,
8812 0x0000,
8813 0x0000,
8814 0x0000,
8815 0x0000,
8816 0x0000,
8817 0x0000,
8818 0x0000,
8819 0x0000,
8820 0x0000,
8821 0x0000,
8822 0x0000,
8823 0x0000,
8824 0x0000,
8825 0x0000,
8826 0x0000,
8827 0x0000,
8828 0x0000,
8829 0x0000,
8830 0x0000,
8831 0x0000,
8832};
8833
8834const u16 papd_comp_rfpwr_tbl_core0_rev3[] = {
8835 0x0036,
8836 0x0036,
8837 0x0036,
8838 0x0036,
8839 0x0036,
8840 0x0036,
8841 0x0036,
8842 0x0036,
8843 0x0036,
8844 0x0036,
8845 0x0036,
8846 0x0036,
8847 0x0036,
8848 0x002a,
8849 0x002a,
8850 0x002a,
8851 0x002a,
8852 0x002a,
8853 0x002a,
8854 0x002a,
8855 0x002a,
8856 0x002a,
8857 0x002a,
8858 0x002a,
8859 0x001e,
8860 0x001e,
8861 0x001e,
8862 0x001e,
8863 0x001e,
8864 0x001e,
8865 0x001e,
8866 0x001e,
8867 0x001e,
8868 0x001e,
8869 0x001e,
8870 0x001e,
8871 0x001e,
8872 0x001e,
8873 0x001e,
8874 0x001e,
8875 0x000e,
8876 0x000e,
8877 0x000e,
8878 0x000e,
8879 0x000e,
8880 0x000e,
8881 0x000e,
8882 0x000e,
8883 0x000e,
8884 0x000e,
8885 0x000e,
8886 0x000e,
8887 0x000e,
8888 0x000e,
8889 0x000e,
8890 0x000e,
8891 0x000e,
8892 0x000e,
8893 0x01fc,
8894 0x01fc,
8895 0x01fc,
8896 0x01fc,
8897 0x01fc,
8898 0x01fc,
8899 0x01fc,
8900 0x01fc,
8901 0x01fc,
8902 0x01fc,
8903 0x01fc,
8904 0x01fc,
8905 0x01fc,
8906 0x01fc,
8907 0x01ee,
8908 0x01ee,
8909 0x01ee,
8910 0x01ee,
8911 0x01ee,
8912 0x01ee,
8913 0x01ee,
8914 0x01ee,
8915 0x01ee,
8916 0x01ee,
8917 0x01ee,
8918 0x01ee,
8919 0x01ee,
8920 0x01ee,
8921 0x01ee,
8922 0x01ee,
8923 0x01ee,
8924 0x01ee,
8925 0x01ee,
8926 0x01ee,
8927 0x01ee,
8928 0x01ee,
8929 0x01ee,
8930 0x01ee,
8931 0x01d6,
8932 0x01d6,
8933 0x01d6,
8934 0x01d6,
8935 0x01d6,
8936 0x01d6,
8937 0x01d6,
8938 0x01d6,
8939 0x01d6,
8940 0x01d6,
8941 0x01d6,
8942 0x01d6,
8943 0x01d6,
8944 0x01d6,
8945 0x01d6,
8946 0x01d6,
8947 0x01d6,
8948 0x01d6,
8949 0x01d6,
8950 0x01d6,
8951 0x01d6,
8952 0x01d6,
8953 0x01d6,
8954 0x01d6,
8955 0x01d6,
8956 0x01d6,
8957 0x01d6,
8958 0x01d6,
8959 0x01d6,
8960 0x01d6,
8961 0x01d6,
8962 0x01d6,
8963};
8964
8965const u16 papd_comp_rfpwr_tbl_core1_rev3[] = {
8966 0x0036,
8967 0x0036,
8968 0x0036,
8969 0x0036,
8970 0x0036,
8971 0x0036,
8972 0x0036,
8973 0x0036,
8974 0x0036,
8975 0x0036,
8976 0x0036,
8977 0x0036,
8978 0x0036,
8979 0x002a,
8980 0x002a,
8981 0x002a,
8982 0x002a,
8983 0x002a,
8984 0x002a,
8985 0x002a,
8986 0x002a,
8987 0x002a,
8988 0x002a,
8989 0x002a,
8990 0x001e,
8991 0x001e,
8992 0x001e,
8993 0x001e,
8994 0x001e,
8995 0x001e,
8996 0x001e,
8997 0x001e,
8998 0x001e,
8999 0x001e,
9000 0x001e,
9001 0x001e,
9002 0x001e,
9003 0x001e,
9004 0x001e,
9005 0x001e,
9006 0x000e,
9007 0x000e,
9008 0x000e,
9009 0x000e,
9010 0x000e,
9011 0x000e,
9012 0x000e,
9013 0x000e,
9014 0x000e,
9015 0x000e,
9016 0x000e,
9017 0x000e,
9018 0x000e,
9019 0x000e,
9020 0x000e,
9021 0x000e,
9022 0x000e,
9023 0x000e,
9024 0x01fc,
9025 0x01fc,
9026 0x01fc,
9027 0x01fc,
9028 0x01fc,
9029 0x01fc,
9030 0x01fc,
9031 0x01fc,
9032 0x01fc,
9033 0x01fc,
9034 0x01fc,
9035 0x01fc,
9036 0x01fc,
9037 0x01fc,
9038 0x01ee,
9039 0x01ee,
9040 0x01ee,
9041 0x01ee,
9042 0x01ee,
9043 0x01ee,
9044 0x01ee,
9045 0x01ee,
9046 0x01ee,
9047 0x01ee,
9048 0x01ee,
9049 0x01ee,
9050 0x01ee,
9051 0x01ee,
9052 0x01ee,
9053 0x01ee,
9054 0x01ee,
9055 0x01ee,
9056 0x01ee,
9057 0x01ee,
9058 0x01ee,
9059 0x01ee,
9060 0x01ee,
9061 0x01ee,
9062 0x01d6,
9063 0x01d6,
9064 0x01d6,
9065 0x01d6,
9066 0x01d6,
9067 0x01d6,
9068 0x01d6,
9069 0x01d6,
9070 0x01d6,
9071 0x01d6,
9072 0x01d6,
9073 0x01d6,
9074 0x01d6,
9075 0x01d6,
9076 0x01d6,
9077 0x01d6,
9078 0x01d6,
9079 0x01d6,
9080 0x01d6,
9081 0x01d6,
9082 0x01d6,
9083 0x01d6,
9084 0x01d6,
9085 0x01d6,
9086 0x01d6,
9087 0x01d6,
9088 0x01d6,
9089 0x01d6,
9090 0x01d6,
9091 0x01d6,
9092 0x01d6,
9093 0x01d6,
9094};
9095
9096const u32 papd_comp_epsilon_tbl_core0_rev3[] = {
9097 0x00000000,
9098 0x00001fa0,
9099 0x00019f78,
9100 0x0001df7e,
9101 0x03fa9f86,
9102 0x03fd1f90,
9103 0x03fe5f8a,
9104 0x03fb1f94,
9105 0x03fd9fa0,
9106 0x00009f98,
9107 0x03fd1fac,
9108 0x03ff9fa2,
9109 0x03fe9fae,
9110 0x00001fae,
9111 0x03fddfb4,
9112 0x03ff1fb8,
9113 0x03ff9fbc,
9114 0x03ffdfbe,
9115 0x03fe9fc2,
9116 0x03fedfc6,
9117 0x03fedfc6,
9118 0x03ff9fc8,
9119 0x03ff5fc6,
9120 0x03fedfc2,
9121 0x03ff9fc0,
9122 0x03ff5fac,
9123 0x03ff5fac,
9124 0x03ff9fa2,
9125 0x03ff9fa6,
9126 0x03ff9faa,
9127 0x03ff5fb0,
9128 0x03ff5fb4,
9129 0x03ff1fca,
9130 0x03ff5fce,
9131 0x03fcdfdc,
9132 0x03fb4006,
9133 0x00000030,
9134 0x03ff808a,
9135 0x03ff80da,
9136 0x0000016c,
9137 0x03ff8318,
9138 0x03ff063a,
9139 0x03fd8bd6,
9140 0x00014ffe,
9141 0x00034ffe,
9142 0x00034ffe,
9143 0x0003cffe,
9144 0x00040ffe,
9145 0x00040ffe,
9146 0x0003cffe,
9147 0x0003cffe,
9148 0x00020ffe,
9149 0x03fe0ffe,
9150 0x03fdcffe,
9151 0x03f94ffe,
9152 0x03f54ffe,
9153 0x03f44ffe,
9154 0x03ef8ffe,
9155 0x03ee0ffe,
9156 0x03ebcffe,
9157 0x03e8cffe,
9158 0x03e74ffe,
9159 0x03e4cffe,
9160 0x03e38ffe,
9161};
9162
9163const u32 papd_cal_scalars_tbl_core0_rev3[] = {
9164 0x05af005a,
9165 0x0571005e,
9166 0x05040066,
9167 0x04bd006c,
9168 0x047d0072,
9169 0x04430078,
9170 0x03f70081,
9171 0x03cb0087,
9172 0x03870091,
9173 0x035e0098,
9174 0x032e00a1,
9175 0x030300aa,
9176 0x02d800b4,
9177 0x02ae00bf,
9178 0x028900ca,
9179 0x026400d6,
9180 0x024100e3,
9181 0x022200f0,
9182 0x020200ff,
9183 0x01e5010e,
9184 0x01ca011e,
9185 0x01b0012f,
9186 0x01990140,
9187 0x01830153,
9188 0x016c0168,
9189 0x0158017d,
9190 0x01450193,
9191 0x013301ab,
9192 0x012101c5,
9193 0x011101e0,
9194 0x010201fc,
9195 0x00f4021a,
9196 0x00e6011d,
9197 0x00d9012e,
9198 0x00cd0140,
9199 0x00c20153,
9200 0x00b70167,
9201 0x00ac017c,
9202 0x00a30193,
9203 0x009a01ab,
9204 0x009101c4,
9205 0x008901df,
9206 0x008101fb,
9207 0x007a0219,
9208 0x00730239,
9209 0x006d025b,
9210 0x0067027e,
9211 0x006102a4,
9212 0x005c02cc,
9213 0x005602f6,
9214 0x00520323,
9215 0x004d0353,
9216 0x00490385,
9217 0x004503bb,
9218 0x004103f3,
9219 0x003d042f,
9220 0x003a046f,
9221 0x003704b2,
9222 0x003404f9,
9223 0x00310545,
9224 0x002e0596,
9225 0x002b05f5,
9226 0x00290640,
9227 0x002606a4,
9228};
9229
9230const u32 papd_comp_epsilon_tbl_core1_rev3[] = {
9231 0x00000000,
9232 0x00001fa0,
9233 0x00019f78,
9234 0x0001df7e,
9235 0x03fa9f86,
9236 0x03fd1f90,
9237 0x03fe5f8a,
9238 0x03fb1f94,
9239 0x03fd9fa0,
9240 0x00009f98,
9241 0x03fd1fac,
9242 0x03ff9fa2,
9243 0x03fe9fae,
9244 0x00001fae,
9245 0x03fddfb4,
9246 0x03ff1fb8,
9247 0x03ff9fbc,
9248 0x03ffdfbe,
9249 0x03fe9fc2,
9250 0x03fedfc6,
9251 0x03fedfc6,
9252 0x03ff9fc8,
9253 0x03ff5fc6,
9254 0x03fedfc2,
9255 0x03ff9fc0,
9256 0x03ff5fac,
9257 0x03ff5fac,
9258 0x03ff9fa2,
9259 0x03ff9fa6,
9260 0x03ff9faa,
9261 0x03ff5fb0,
9262 0x03ff5fb4,
9263 0x03ff1fca,
9264 0x03ff5fce,
9265 0x03fcdfdc,
9266 0x03fb4006,
9267 0x00000030,
9268 0x03ff808a,
9269 0x03ff80da,
9270 0x0000016c,
9271 0x03ff8318,
9272 0x03ff063a,
9273 0x03fd8bd6,
9274 0x00014ffe,
9275 0x00034ffe,
9276 0x00034ffe,
9277 0x0003cffe,
9278 0x00040ffe,
9279 0x00040ffe,
9280 0x0003cffe,
9281 0x0003cffe,
9282 0x00020ffe,
9283 0x03fe0ffe,
9284 0x03fdcffe,
9285 0x03f94ffe,
9286 0x03f54ffe,
9287 0x03f44ffe,
9288 0x03ef8ffe,
9289 0x03ee0ffe,
9290 0x03ebcffe,
9291 0x03e8cffe,
9292 0x03e74ffe,
9293 0x03e4cffe,
9294 0x03e38ffe,
9295};
9296
9297const u32 papd_cal_scalars_tbl_core1_rev3[] = {
9298 0x05af005a,
9299 0x0571005e,
9300 0x05040066,
9301 0x04bd006c,
9302 0x047d0072,
9303 0x04430078,
9304 0x03f70081,
9305 0x03cb0087,
9306 0x03870091,
9307 0x035e0098,
9308 0x032e00a1,
9309 0x030300aa,
9310 0x02d800b4,
9311 0x02ae00bf,
9312 0x028900ca,
9313 0x026400d6,
9314 0x024100e3,
9315 0x022200f0,
9316 0x020200ff,
9317 0x01e5010e,
9318 0x01ca011e,
9319 0x01b0012f,
9320 0x01990140,
9321 0x01830153,
9322 0x016c0168,
9323 0x0158017d,
9324 0x01450193,
9325 0x013301ab,
9326 0x012101c5,
9327 0x011101e0,
9328 0x010201fc,
9329 0x00f4021a,
9330 0x00e6011d,
9331 0x00d9012e,
9332 0x00cd0140,
9333 0x00c20153,
9334 0x00b70167,
9335 0x00ac017c,
9336 0x00a30193,
9337 0x009a01ab,
9338 0x009101c4,
9339 0x008901df,
9340 0x008101fb,
9341 0x007a0219,
9342 0x00730239,
9343 0x006d025b,
9344 0x0067027e,
9345 0x006102a4,
9346 0x005c02cc,
9347 0x005602f6,
9348 0x00520323,
9349 0x004d0353,
9350 0x00490385,
9351 0x004503bb,
9352 0x004103f3,
9353 0x003d042f,
9354 0x003a046f,
9355 0x003704b2,
9356 0x003404f9,
9357 0x00310545,
9358 0x002e0596,
9359 0x002b05f5,
9360 0x00290640,
9361 0x002606a4,
9362};
9363
9364const struct phytbl_info mimophytbl_info_rev3_volatile[] = {
9365 {&ant_swctrl_tbl_rev3,
9366 sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16}
9367 ,
9368};
9369
9370const struct phytbl_info mimophytbl_info_rev3_volatile1[] = {
9371 {&ant_swctrl_tbl_rev3_1,
9372 sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0,
9373 16}
9374 ,
9375};
9376
9377const struct phytbl_info mimophytbl_info_rev3_volatile2[] = {
9378 {&ant_swctrl_tbl_rev3_2,
9379 sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0,
9380 16}
9381 ,
9382};
9383
9384const struct phytbl_info mimophytbl_info_rev3_volatile3[] = {
9385 {&ant_swctrl_tbl_rev3_3,
9386 sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0,
9387 16}
9388 ,
9389};
9390
9391const struct phytbl_info mimophytbl_info_rev3[] = {
9392 {&frame_struct_rev3,
9393 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
9394 ,
9395 {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
9396 11, 0, 16}
9397 ,
9398 {&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12,
9399 0, 32}
9400 ,
9401 {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
9402 13, 0, 32}
9403 ,
9404 {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
9405 14, 0, 32}
9406 ,
9407 {&noise_var_tbl_rev3,
9408 sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32}
9409 ,
9410 {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
9411 16}
9412 ,
9413 {&tdi_tbl20_ant0_rev3,
9414 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
9415 32}
9416 ,
9417 {&tdi_tbl20_ant1_rev3,
9418 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
9419 32}
9420 ,
9421 {&tdi_tbl40_ant0_rev3,
9422 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
9423 32}
9424 ,
9425 {&tdi_tbl40_ant1_rev3,
9426 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
9427 32}
9428 ,
9429 {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
9430 20, 0, 32}
9431 ,
9432 {&chanest_tbl_rev3,
9433 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
9434 ,
9435 {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
9436 24, 0, 8}
9437 ,
9438 {&est_pwr_lut_core0_rev3,
9439 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
9440 0, 8}
9441 ,
9442 {&est_pwr_lut_core1_rev3,
9443 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
9444 0, 8}
9445 ,
9446 {&adj_pwr_lut_core0_rev3,
9447 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
9448 64, 8}
9449 ,
9450 {&adj_pwr_lut_core1_rev3,
9451 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
9452 64, 8}
9453 ,
9454 {&gainctrl_lut_core0_rev3,
9455 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
9456 26, 192, 32}
9457 ,
9458 {&gainctrl_lut_core1_rev3,
9459 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
9460 27, 192, 32}
9461 ,
9462 {&iq_lut_core0_rev3,
9463 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
9464 ,
9465 {&iq_lut_core1_rev3,
9466 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
9467 ,
9468 {&loft_lut_core0_rev3,
9469 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
9470 16}
9471 ,
9472 {&loft_lut_core1_rev3,
9473 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
9474 16}
9475};
9476
9477const u32 mimophytbl_info_sz_rev3 =
9478 sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]);
9479const u32 mimophytbl_info_sz_rev3_volatile =
9480 sizeof(mimophytbl_info_rev3_volatile) /
9481 sizeof(mimophytbl_info_rev3_volatile[0]);
9482const u32 mimophytbl_info_sz_rev3_volatile1 =
9483 sizeof(mimophytbl_info_rev3_volatile1) /
9484 sizeof(mimophytbl_info_rev3_volatile1[0]);
9485const u32 mimophytbl_info_sz_rev3_volatile2 =
9486 sizeof(mimophytbl_info_rev3_volatile2) /
9487 sizeof(mimophytbl_info_rev3_volatile2[0]);
9488const u32 mimophytbl_info_sz_rev3_volatile3 =
9489 sizeof(mimophytbl_info_rev3_volatile3) /
9490 sizeof(mimophytbl_info_rev3_volatile3[0]);
9491
9492const u32 tmap_tbl_rev7[] = {
9493 0x8a88aa80,
9494 0x8aaaaa8a,
9495 0x8a8a8aa8,
9496 0x00000888,
9497 0x88000000,
9498 0x8a8a88aa,
9499 0x8aa88888,
9500 0x8888a8a8,
9501 0xf1111110,
9502 0x11111111,
9503 0x11f11111,
9504 0x00000111,
9505 0x11000000,
9506 0x1111f111,
9507 0x11111111,
9508 0x111111f1,
9509 0x8a88aa80,
9510 0x8aaaaa8a,
9511 0x8a8a8aa8,
9512 0x000aa888,
9513 0x88880000,
9514 0x8a8a88aa,
9515 0x8aa88888,
9516 0x8888a8a8,
9517 0xa1111110,
9518 0x11111111,
9519 0x11c11111,
9520 0x00000111,
9521 0x11000000,
9522 0x1111a111,
9523 0x11111111,
9524 0x111111a1,
9525 0xa2222220,
9526 0x22222222,
9527 0x22c22222,
9528 0x00000222,
9529 0x22000000,
9530 0x2222a222,
9531 0x22222222,
9532 0x222222a2,
9533 0xf1111110,
9534 0x11111111,
9535 0x11f11111,
9536 0x00011111,
9537 0x11110000,
9538 0x1111f111,
9539 0x11111111,
9540 0x111111f1,
9541 0xa8aa88a0,
9542 0xa88888a8,
9543 0xa8a8a88a,
9544 0x00088aaa,
9545 0xaaaa0000,
9546 0xa8a8aa88,
9547 0xa88aaaaa,
9548 0xaaaa8a8a,
9549 0xaaa8aaa0,
9550 0x8aaa8aaa,
9551 0xaa8a8a8a,
9552 0x000aaa88,
9553 0x8aaa0000,
9554 0xaaa8a888,
9555 0x8aa88a8a,
9556 0x8a88a888,
9557 0x08080a00,
9558 0x0a08080a,
9559 0x080a0a08,
9560 0x00080808,
9561 0x080a0000,
9562 0x080a0808,
9563 0x080a0808,
9564 0x0a0a0a08,
9565 0xa0a0a0a0,
9566 0x80a0a080,
9567 0x8080a0a0,
9568 0x00008080,
9569 0x80a00000,
9570 0x80a080a0,
9571 0xa080a0a0,
9572 0x8080a0a0,
9573 0x00000000,
9574 0x00000000,
9575 0x00000000,
9576 0x00000000,
9577 0x00000000,
9578 0x00000000,
9579 0x00000000,
9580 0x00000000,
9581 0x00000000,
9582 0x00000000,
9583 0x00000000,
9584 0x00000000,
9585 0x00000000,
9586 0x00000000,
9587 0x00000000,
9588 0x00000000,
9589 0x00000000,
9590 0x00000000,
9591 0x00000000,
9592 0x00000000,
9593 0x00000000,
9594 0x00000000,
9595 0x00000000,
9596 0x00000000,
9597 0x00000000,
9598 0x00000000,
9599 0x00000000,
9600 0x00000000,
9601 0x00000000,
9602 0x00000000,
9603 0x00000000,
9604 0x00000000,
9605 0x00000000,
9606 0x00000000,
9607 0x00000000,
9608 0x00000000,
9609 0x00000000,
9610 0x00000000,
9611 0x00000000,
9612 0x00000000,
9613 0x00000000,
9614 0x00000000,
9615 0x00000000,
9616 0x00000000,
9617 0x00000000,
9618 0x00000000,
9619 0x00000000,
9620 0x00000000,
9621 0x99999000,
9622 0x9b9b99bb,
9623 0x9bb99999,
9624 0x9999b9b9,
9625 0x9b99bb90,
9626 0x9bbbbb9b,
9627 0x9b9b9bb9,
9628 0x00000999,
9629 0x88000000,
9630 0x8a8a88aa,
9631 0x8aa88888,
9632 0x8888a8a8,
9633 0x8a88aa80,
9634 0x8aaaaa8a,
9635 0x8a8a8aa8,
9636 0x00aaa888,
9637 0x22000000,
9638 0x2222b222,
9639 0x22222222,
9640 0x222222b2,
9641 0xb2222220,
9642 0x22222222,
9643 0x22d22222,
9644 0x00000222,
9645 0x11000000,
9646 0x1111a111,
9647 0x11111111,
9648 0x111111a1,
9649 0xa1111110,
9650 0x11111111,
9651 0x11c11111,
9652 0x00000111,
9653 0x33000000,
9654 0x3333b333,
9655 0x33333333,
9656 0x333333b3,
9657 0xb3333330,
9658 0x33333333,
9659 0x33d33333,
9660 0x00000333,
9661 0x22000000,
9662 0x2222a222,
9663 0x22222222,
9664 0x222222a2,
9665 0xa2222220,
9666 0x22222222,
9667 0x22c22222,
9668 0x00000222,
9669 0x99b99b00,
9670 0x9b9b99bb,
9671 0x9bb99999,
9672 0x9999b9b9,
9673 0x9b99bb99,
9674 0x9bbbbb9b,
9675 0x9b9b9bb9,
9676 0x00000999,
9677 0x88000000,
9678 0x8a8a88aa,
9679 0x8aa88888,
9680 0x8888a8a8,
9681 0x8a88aa88,
9682 0x8aaaaa8a,
9683 0x8a8a8aa8,
9684 0x08aaa888,
9685 0x22222200,
9686 0x2222f222,
9687 0x22222222,
9688 0x222222f2,
9689 0x22222222,
9690 0x22222222,
9691 0x22f22222,
9692 0x00000222,
9693 0x11000000,
9694 0x1111f111,
9695 0x11111111,
9696 0x11111111,
9697 0xf1111111,
9698 0x11111111,
9699 0x11f11111,
9700 0x01111111,
9701 0xbb9bb900,
9702 0xb9b9bb99,
9703 0xb99bbbbb,
9704 0xbbbb9b9b,
9705 0xb9bb99bb,
9706 0xb99999b9,
9707 0xb9b9b99b,
9708 0x00000bbb,
9709 0xaa000000,
9710 0xa8a8aa88,
9711 0xa88aaaaa,
9712 0xaaaa8a8a,
9713 0xa8aa88aa,
9714 0xa88888a8,
9715 0xa8a8a88a,
9716 0x0a888aaa,
9717 0xaa000000,
9718 0xa8a8aa88,
9719 0xa88aaaaa,
9720 0xaaaa8a8a,
9721 0xa8aa88a0,
9722 0xa88888a8,
9723 0xa8a8a88a,
9724 0x00000aaa,
9725 0x88000000,
9726 0x8a8a88aa,
9727 0x8aa88888,
9728 0x8888a8a8,
9729 0x8a88aa80,
9730 0x8aaaaa8a,
9731 0x8a8a8aa8,
9732 0x00000888,
9733 0xbbbbbb00,
9734 0x999bbbbb,
9735 0x9bb99b9b,
9736 0xb9b9b9bb,
9737 0xb9b99bbb,
9738 0xb9b9b9bb,
9739 0xb9bb9b99,
9740 0x00000999,
9741 0x8a000000,
9742 0xaa88a888,
9743 0xa88888aa,
9744 0xa88a8a88,
9745 0xa88aa88a,
9746 0x88a8aaaa,
9747 0xa8aa8aaa,
9748 0x0888a88a,
9749 0x0b0b0b00,
9750 0x090b0b0b,
9751 0x0b090b0b,
9752 0x0909090b,
9753 0x09090b0b,
9754 0x09090b0b,
9755 0x09090b09,
9756 0x00000909,
9757 0x0a000000,
9758 0x0a080808,
9759 0x080a080a,
9760 0x080a0a08,
9761 0x080a080a,
9762 0x0808080a,
9763 0x0a0a0a08,
9764 0x0808080a,
9765 0xb0b0b000,
9766 0x9090b0b0,
9767 0x90b09090,
9768 0xb0b0b090,
9769 0xb0b090b0,
9770 0x90b0b0b0,
9771 0xb0b09090,
9772 0x00000090,
9773 0x80000000,
9774 0xa080a080,
9775 0xa08080a0,
9776 0xa0808080,
9777 0xa080a080,
9778 0x80a0a0a0,
9779 0xa0a080a0,
9780 0x00a0a0a0,
9781 0x22000000,
9782 0x2222f222,
9783 0x22222222,
9784 0x222222f2,
9785 0xf2222220,
9786 0x22222222,
9787 0x22f22222,
9788 0x00000222,
9789 0x11000000,
9790 0x1111f111,
9791 0x11111111,
9792 0x111111f1,
9793 0xf1111110,
9794 0x11111111,
9795 0x11f11111,
9796 0x00000111,
9797 0x33000000,
9798 0x3333f333,
9799 0x33333333,
9800 0x333333f3,
9801 0xf3333330,
9802 0x33333333,
9803 0x33f33333,
9804 0x00000333,
9805 0x22000000,
9806 0x2222f222,
9807 0x22222222,
9808 0x222222f2,
9809 0xf2222220,
9810 0x22222222,
9811 0x22f22222,
9812 0x00000222,
9813 0x99000000,
9814 0x9b9b99bb,
9815 0x9bb99999,
9816 0x9999b9b9,
9817 0x9b99bb90,
9818 0x9bbbbb9b,
9819 0x9b9b9bb9,
9820 0x00000999,
9821 0x88000000,
9822 0x8a8a88aa,
9823 0x8aa88888,
9824 0x8888a8a8,
9825 0x8a88aa80,
9826 0x8aaaaa8a,
9827 0x8a8a8aa8,
9828 0x00000888,
9829 0x88888000,
9830 0x8a8a88aa,
9831 0x8aa88888,
9832 0x8888a8a8,
9833 0x8a88aa80,
9834 0x8aaaaa8a,
9835 0x8a8a8aa8,
9836 0x00000888,
9837 0x88000000,
9838 0x8a8a88aa,
9839 0x8aa88888,
9840 0x8888a8a8,
9841 0x8a88aa80,
9842 0x8aaaaa8a,
9843 0x8a8a8aa8,
9844 0x00aaa888,
9845 0x88a88a00,
9846 0x8a8a88aa,
9847 0x8aa88888,
9848 0x8888a8a8,
9849 0x8a88aa88,
9850 0x8aaaaa8a,
9851 0x8a8a8aa8,
9852 0x000aa888,
9853 0x88880000,
9854 0x8a8a88aa,
9855 0x8aa88888,
9856 0x8888a8a8,
9857 0x8a88aa88,
9858 0x8aaaaa8a,
9859 0x8a8a8aa8,
9860 0x08aaa888,
9861 0x11000000,
9862 0x1111a111,
9863 0x11111111,
9864 0x111111a1,
9865 0xa1111110,
9866 0x11111111,
9867 0x11c11111,
9868 0x00000111,
9869 0x11000000,
9870 0x1111a111,
9871 0x11111111,
9872 0x111111a1,
9873 0xa1111110,
9874 0x11111111,
9875 0x11c11111,
9876 0x00000111,
9877 0x88000000,
9878 0x8a8a88aa,
9879 0x8aa88888,
9880 0x8888a8a8,
9881 0x8a88aa80,
9882 0x8aaaaa8a,
9883 0x8a8a8aa8,
9884 0x00000888,
9885 0x88000000,
9886 0x8a8a88aa,
9887 0x8aa88888,
9888 0x8888a8a8,
9889 0x8a88aa80,
9890 0x8aaaaa8a,
9891 0x8a8a8aa8,
9892 0x00000888,
9893 0x00000000,
9894 0x00000000,
9895 0x00000000,
9896 0x00000000,
9897 0x00000000,
9898 0x00000000,
9899 0x00000000,
9900 0x00000000,
9901 0x00000000,
9902 0x00000000,
9903 0x00000000,
9904 0x00000000,
9905 0x00000000,
9906 0x00000000,
9907 0x00000000,
9908 0x00000000,
9909 0x00000000,
9910 0x00000000,
9911 0x00000000,
9912 0x00000000,
9913 0x00000000,
9914 0x00000000,
9915 0x00000000,
9916 0x00000000,
9917 0x00000000,
9918 0x00000000,
9919 0x00000000,
9920 0x00000000,
9921 0x00000000,
9922 0x00000000,
9923 0x00000000,
9924 0x00000000,
9925 0x00000000,
9926 0x00000000,
9927 0x00000000,
9928 0x00000000,
9929 0x00000000,
9930 0x00000000,
9931 0x00000000,
9932 0x00000000,
9933 0x00000000,
9934 0x00000000,
9935 0x00000000,
9936 0x00000000,
9937 0x00000000,
9938 0x00000000,
9939 0x00000000,
9940 0x00000000,
9941};
9942
9943const u32 noise_var_tbl_rev7[] = {
9944 0x020c020c,
9945 0x0000014d,
9946 0x020c020c,
9947 0x0000014d,
9948 0x020c020c,
9949 0x0000014d,
9950 0x020c020c,
9951 0x0000014d,
9952 0x020c020c,
9953 0x0000014d,
9954 0x020c020c,
9955 0x0000014d,
9956 0x020c020c,
9957 0x0000014d,
9958 0x020c020c,
9959 0x0000014d,
9960 0x020c020c,
9961 0x0000014d,
9962 0x020c020c,
9963 0x0000014d,
9964 0x020c020c,
9965 0x0000014d,
9966 0x020c020c,
9967 0x0000014d,
9968 0x020c020c,
9969 0x0000014d,
9970 0x020c020c,
9971 0x0000014d,
9972 0x020c020c,
9973 0x0000014d,
9974 0x020c020c,
9975 0x0000014d,
9976 0x020c020c,
9977 0x0000014d,
9978 0x020c020c,
9979 0x0000014d,
9980 0x020c020c,
9981 0x0000014d,
9982 0x020c020c,
9983 0x0000014d,
9984 0x020c020c,
9985 0x0000014d,
9986 0x020c020c,
9987 0x0000014d,
9988 0x020c020c,
9989 0x0000014d,
9990 0x020c020c,
9991 0x0000014d,
9992 0x020c020c,
9993 0x0000014d,
9994 0x020c020c,
9995 0x0000014d,
9996 0x020c020c,
9997 0x0000014d,
9998 0x020c020c,
9999 0x0000014d,
10000 0x020c020c,
10001 0x0000014d,
10002 0x020c020c,
10003 0x0000014d,
10004 0x020c020c,
10005 0x0000014d,
10006 0x020c020c,
10007 0x0000014d,
10008 0x020c020c,
10009 0x0000014d,
10010 0x020c020c,
10011 0x0000014d,
10012 0x020c020c,
10013 0x0000014d,
10014 0x020c020c,
10015 0x0000014d,
10016 0x020c020c,
10017 0x0000014d,
10018 0x020c020c,
10019 0x0000014d,
10020 0x020c020c,
10021 0x0000014d,
10022 0x020c020c,
10023 0x0000014d,
10024 0x020c020c,
10025 0x0000014d,
10026 0x020c020c,
10027 0x0000014d,
10028 0x020c020c,
10029 0x0000014d,
10030 0x020c020c,
10031 0x0000014d,
10032 0x020c020c,
10033 0x0000014d,
10034 0x020c020c,
10035 0x0000014d,
10036 0x020c020c,
10037 0x0000014d,
10038 0x020c020c,
10039 0x0000014d,
10040 0x020c020c,
10041 0x0000014d,
10042 0x020c020c,
10043 0x0000014d,
10044 0x020c020c,
10045 0x0000014d,
10046 0x020c020c,
10047 0x0000014d,
10048 0x020c020c,
10049 0x0000014d,
10050 0x020c020c,
10051 0x0000014d,
10052 0x020c020c,
10053 0x0000014d,
10054 0x020c020c,
10055 0x0000014d,
10056 0x020c020c,
10057 0x0000014d,
10058 0x020c020c,
10059 0x0000014d,
10060 0x020c020c,
10061 0x0000014d,
10062 0x020c020c,
10063 0x0000014d,
10064 0x020c020c,
10065 0x0000014d,
10066 0x020c020c,
10067 0x0000014d,
10068 0x020c020c,
10069 0x0000014d,
10070 0x020c020c,
10071 0x0000014d,
10072 0x020c020c,
10073 0x0000014d,
10074 0x020c020c,
10075 0x0000014d,
10076 0x020c020c,
10077 0x0000014d,
10078 0x020c020c,
10079 0x0000014d,
10080 0x020c020c,
10081 0x0000014d,
10082 0x020c020c,
10083 0x0000014d,
10084 0x020c020c,
10085 0x0000014d,
10086 0x020c020c,
10087 0x0000014d,
10088 0x020c020c,
10089 0x0000014d,
10090 0x020c020c,
10091 0x0000014d,
10092 0x020c020c,
10093 0x0000014d,
10094 0x020c020c,
10095 0x0000014d,
10096 0x020c020c,
10097 0x0000014d,
10098 0x020c020c,
10099 0x0000014d,
10100 0x020c020c,
10101 0x0000014d,
10102 0x020c020c,
10103 0x0000014d,
10104 0x020c020c,
10105 0x0000014d,
10106 0x020c020c,
10107 0x0000014d,
10108 0x020c020c,
10109 0x0000014d,
10110 0x020c020c,
10111 0x0000014d,
10112 0x020c020c,
10113 0x0000014d,
10114 0x020c020c,
10115 0x0000014d,
10116 0x020c020c,
10117 0x0000014d,
10118 0x020c020c,
10119 0x0000014d,
10120 0x020c020c,
10121 0x0000014d,
10122 0x020c020c,
10123 0x0000014d,
10124 0x020c020c,
10125 0x0000014d,
10126 0x020c020c,
10127 0x0000014d,
10128 0x020c020c,
10129 0x0000014d,
10130 0x020c020c,
10131 0x0000014d,
10132 0x020c020c,
10133 0x0000014d,
10134 0x020c020c,
10135 0x0000014d,
10136 0x020c020c,
10137 0x0000014d,
10138 0x020c020c,
10139 0x0000014d,
10140 0x020c020c,
10141 0x0000014d,
10142 0x020c020c,
10143 0x0000014d,
10144 0x020c020c,
10145 0x0000014d,
10146 0x020c020c,
10147 0x0000014d,
10148 0x020c020c,
10149 0x0000014d,
10150 0x020c020c,
10151 0x0000014d,
10152 0x020c020c,
10153 0x0000014d,
10154 0x020c020c,
10155 0x0000014d,
10156 0x020c020c,
10157 0x0000014d,
10158 0x020c020c,
10159 0x0000014d,
10160 0x020c020c,
10161 0x0000014d,
10162 0x020c020c,
10163 0x0000014d,
10164 0x020c020c,
10165 0x0000014d,
10166 0x020c020c,
10167 0x0000014d,
10168 0x020c020c,
10169 0x0000014d,
10170 0x020c020c,
10171 0x0000014d,
10172 0x020c020c,
10173 0x0000014d,
10174 0x020c020c,
10175 0x0000014d,
10176 0x020c020c,
10177 0x0000014d,
10178 0x020c020c,
10179 0x0000014d,
10180 0x020c020c,
10181 0x0000014d,
10182 0x020c020c,
10183 0x0000014d,
10184 0x020c020c,
10185 0x0000014d,
10186 0x020c020c,
10187 0x0000014d,
10188 0x020c020c,
10189 0x0000014d,
10190 0x020c020c,
10191 0x0000014d,
10192 0x020c020c,
10193 0x0000014d,
10194 0x020c020c,
10195 0x0000014d,
10196 0x020c020c,
10197 0x0000014d,
10198 0x020c020c,
10199 0x0000014d,
10200};
10201
10202const u32 papd_comp_epsilon_tbl_core0_rev7[] = {
10203 0x00000000,
10204 0x00000000,
10205 0x00016023,
10206 0x00006028,
10207 0x00034036,
10208 0x0003402e,
10209 0x0007203c,
10210 0x0006e037,
10211 0x00070030,
10212 0x0009401f,
10213 0x0009a00f,
10214 0x000b600d,
10215 0x000c8007,
10216 0x000ce007,
10217 0x00101fff,
10218 0x00121ff9,
10219 0x0012e004,
10220 0x0014dffc,
10221 0x0016dff6,
10222 0x0018dfe9,
10223 0x001b3fe5,
10224 0x001c5fd0,
10225 0x001ddfc2,
10226 0x001f1fb6,
10227 0x00207fa4,
10228 0x00219f8f,
10229 0x0022ff7d,
10230 0x00247f6c,
10231 0x0024df5b,
10232 0x00267f4b,
10233 0x0027df3b,
10234 0x0029bf3b,
10235 0x002b5f2f,
10236 0x002d3f2e,
10237 0x002f5f2a,
10238 0x002fff15,
10239 0x00315f0b,
10240 0x0032defa,
10241 0x0033beeb,
10242 0x0034fed9,
10243 0x00353ec5,
10244 0x00361eb0,
10245 0x00363e9b,
10246 0x0036be87,
10247 0x0036be70,
10248 0x0038fe67,
10249 0x0044beb2,
10250 0x00513ef3,
10251 0x00595f11,
10252 0x00669f3d,
10253 0x0078dfdf,
10254 0x00a143aa,
10255 0x01642fff,
10256 0x0162afff,
10257 0x01620fff,
10258 0x0160cfff,
10259 0x015f0fff,
10260 0x015dafff,
10261 0x015bcfff,
10262 0x015bcfff,
10263 0x015b4fff,
10264 0x015acfff,
10265 0x01590fff,
10266 0x0156cfff,
10267};
10268
10269const u32 papd_cal_scalars_tbl_core0_rev7[] = {
10270 0x0b5e002d,
10271 0x0ae2002f,
10272 0x0a3b0032,
10273 0x09a70035,
10274 0x09220038,
10275 0x08ab003b,
10276 0x081f003f,
10277 0x07a20043,
10278 0x07340047,
10279 0x06d2004b,
10280 0x067a004f,
10281 0x06170054,
10282 0x05bf0059,
10283 0x0571005e,
10284 0x051e0064,
10285 0x04d3006a,
10286 0x04910070,
10287 0x044c0077,
10288 0x040f007e,
10289 0x03d90085,
10290 0x03a1008d,
10291 0x036f0095,
10292 0x033d009e,
10293 0x030b00a8,
10294 0x02e000b2,
10295 0x02b900bc,
10296 0x029200c7,
10297 0x026d00d3,
10298 0x024900e0,
10299 0x022900ed,
10300 0x020a00fb,
10301 0x01ec010a,
10302 0x01d20119,
10303 0x01b7012a,
10304 0x019e013c,
10305 0x0188014e,
10306 0x01720162,
10307 0x015d0177,
10308 0x0149018e,
10309 0x013701a5,
10310 0x012601be,
10311 0x011501d8,
10312 0x010601f4,
10313 0x00f70212,
10314 0x00e90231,
10315 0x00dc0253,
10316 0x00d00276,
10317 0x00c4029b,
10318 0x00b902c3,
10319 0x00af02ed,
10320 0x00a50319,
10321 0x009c0348,
10322 0x0093037a,
10323 0x008b03af,
10324 0x008303e6,
10325 0x007c0422,
10326 0x00750460,
10327 0x006e04a3,
10328 0x006804e9,
10329 0x00620533,
10330 0x005d0582,
10331 0x005805d6,
10332 0x0053062e,
10333 0x004e068c,
10334};
10335
10336const u32 papd_comp_epsilon_tbl_core1_rev7[] = {
10337 0x00000000,
10338 0x00000000,
10339 0x00016023,
10340 0x00006028,
10341 0x00034036,
10342 0x0003402e,
10343 0x0007203c,
10344 0x0006e037,
10345 0x00070030,
10346 0x0009401f,
10347 0x0009a00f,
10348 0x000b600d,
10349 0x000c8007,
10350 0x000ce007,
10351 0x00101fff,
10352 0x00121ff9,
10353 0x0012e004,
10354 0x0014dffc,
10355 0x0016dff6,
10356 0x0018dfe9,
10357 0x001b3fe5,
10358 0x001c5fd0,
10359 0x001ddfc2,
10360 0x001f1fb6,
10361 0x00207fa4,
10362 0x00219f8f,
10363 0x0022ff7d,
10364 0x00247f6c,
10365 0x0024df5b,
10366 0x00267f4b,
10367 0x0027df3b,
10368 0x0029bf3b,
10369 0x002b5f2f,
10370 0x002d3f2e,
10371 0x002f5f2a,
10372 0x002fff15,
10373 0x00315f0b,
10374 0x0032defa,
10375 0x0033beeb,
10376 0x0034fed9,
10377 0x00353ec5,
10378 0x00361eb0,
10379 0x00363e9b,
10380 0x0036be87,
10381 0x0036be70,
10382 0x0038fe67,
10383 0x0044beb2,
10384 0x00513ef3,
10385 0x00595f11,
10386 0x00669f3d,
10387 0x0078dfdf,
10388 0x00a143aa,
10389 0x01642fff,
10390 0x0162afff,
10391 0x01620fff,
10392 0x0160cfff,
10393 0x015f0fff,
10394 0x015dafff,
10395 0x015bcfff,
10396 0x015bcfff,
10397 0x015b4fff,
10398 0x015acfff,
10399 0x01590fff,
10400 0x0156cfff,
10401};
10402
10403const u32 papd_cal_scalars_tbl_core1_rev7[] = {
10404 0x0b5e002d,
10405 0x0ae2002f,
10406 0x0a3b0032,
10407 0x09a70035,
10408 0x09220038,
10409 0x08ab003b,
10410 0x081f003f,
10411 0x07a20043,
10412 0x07340047,
10413 0x06d2004b,
10414 0x067a004f,
10415 0x06170054,
10416 0x05bf0059,
10417 0x0571005e,
10418 0x051e0064,
10419 0x04d3006a,
10420 0x04910070,
10421 0x044c0077,
10422 0x040f007e,
10423 0x03d90085,
10424 0x03a1008d,
10425 0x036f0095,
10426 0x033d009e,
10427 0x030b00a8,
10428 0x02e000b2,
10429 0x02b900bc,
10430 0x029200c7,
10431 0x026d00d3,
10432 0x024900e0,
10433 0x022900ed,
10434 0x020a00fb,
10435 0x01ec010a,
10436 0x01d20119,
10437 0x01b7012a,
10438 0x019e013c,
10439 0x0188014e,
10440 0x01720162,
10441 0x015d0177,
10442 0x0149018e,
10443 0x013701a5,
10444 0x012601be,
10445 0x011501d8,
10446 0x010601f4,
10447 0x00f70212,
10448 0x00e90231,
10449 0x00dc0253,
10450 0x00d00276,
10451 0x00c4029b,
10452 0x00b902c3,
10453 0x00af02ed,
10454 0x00a50319,
10455 0x009c0348,
10456 0x0093037a,
10457 0x008b03af,
10458 0x008303e6,
10459 0x007c0422,
10460 0x00750460,
10461 0x006e04a3,
10462 0x006804e9,
10463 0x00620533,
10464 0x005d0582,
10465 0x005805d6,
10466 0x0053062e,
10467 0x004e068c,
10468};
10469
10470const struct phytbl_info mimophytbl_info_rev7[] = {
10471 {&frame_struct_rev3,
10472 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
10473 ,
10474 {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
10475 11, 0, 16}
10476 ,
10477 {&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12,
10478 0, 32}
10479 ,
10480 {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
10481 13, 0, 32}
10482 ,
10483 {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
10484 14, 0, 32}
10485 ,
10486 {&noise_var_tbl_rev7,
10487 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
10488 ,
10489 {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
10490 16}
10491 ,
10492 {&tdi_tbl20_ant0_rev3,
10493 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
10494 32}
10495 ,
10496 {&tdi_tbl20_ant1_rev3,
10497 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
10498 32}
10499 ,
10500 {&tdi_tbl40_ant0_rev3,
10501 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
10502 32}
10503 ,
10504 {&tdi_tbl40_ant1_rev3,
10505 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
10506 32}
10507 ,
10508 {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
10509 20, 0, 32}
10510 ,
10511 {&chanest_tbl_rev3,
10512 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
10513 ,
10514 {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
10515 24, 0, 8}
10516 ,
10517 {&est_pwr_lut_core0_rev3,
10518 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
10519 0, 8}
10520 ,
10521 {&est_pwr_lut_core1_rev3,
10522 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
10523 0, 8}
10524 ,
10525 {&adj_pwr_lut_core0_rev3,
10526 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
10527 64, 8}
10528 ,
10529 {&adj_pwr_lut_core1_rev3,
10530 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
10531 64, 8}
10532 ,
10533 {&gainctrl_lut_core0_rev3,
10534 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
10535 26, 192, 32}
10536 ,
10537 {&gainctrl_lut_core1_rev3,
10538 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
10539 27, 192, 32}
10540 ,
10541 {&iq_lut_core0_rev3,
10542 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
10543 ,
10544 {&iq_lut_core1_rev3,
10545 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
10546 ,
10547 {&loft_lut_core0_rev3,
10548 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
10549 16}
10550 ,
10551 {&loft_lut_core1_rev3,
10552 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
10553 16}
10554 ,
10555 {&papd_comp_rfpwr_tbl_core0_rev3,
10556 sizeof(papd_comp_rfpwr_tbl_core0_rev3) /
10557 sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16}
10558 ,
10559 {&papd_comp_rfpwr_tbl_core1_rev3,
10560 sizeof(papd_comp_rfpwr_tbl_core1_rev3) /
10561 sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16}
10562 ,
10563 {&papd_comp_epsilon_tbl_core0_rev7,
10564 sizeof(papd_comp_epsilon_tbl_core0_rev7) /
10565 sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32}
10566 ,
10567 {&papd_cal_scalars_tbl_core0_rev7,
10568 sizeof(papd_cal_scalars_tbl_core0_rev7) /
10569 sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32}
10570 ,
10571 {&papd_comp_epsilon_tbl_core1_rev7,
10572 sizeof(papd_comp_epsilon_tbl_core1_rev7) /
10573 sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32}
10574 ,
10575 {&papd_cal_scalars_tbl_core1_rev7,
10576 sizeof(papd_cal_scalars_tbl_core1_rev7) /
10577 sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32}
10578 ,
10579};
10580
10581const u32 mimophytbl_info_sz_rev7 =
10582 sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]);
10583
10584const struct phytbl_info mimophytbl_info_rev16[] = {
10585 {&noise_var_tbl_rev7,
10586 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
10587 ,
10588 {&est_pwr_lut_core0_rev3,
10589 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
10590 0, 8}
10591 ,
10592 {&est_pwr_lut_core1_rev3,
10593 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
10594 0, 8}
10595 ,
10596 {&adj_pwr_lut_core0_rev3,
10597 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
10598 64, 8}
10599 ,
10600 {&adj_pwr_lut_core1_rev3,
10601 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
10602 64, 8}
10603 ,
10604 {&gainctrl_lut_core0_rev3,
10605 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
10606 26, 192, 32}
10607 ,
10608 {&gainctrl_lut_core1_rev3,
10609 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
10610 27, 192, 32}
10611 ,
10612 {&iq_lut_core0_rev3,
10613 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
10614 ,
10615 {&iq_lut_core1_rev3,
10616 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
10617 ,
10618 {&loft_lut_core0_rev3,
10619 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
10620 16}
10621 ,
10622 {&loft_lut_core1_rev3,
10623 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
10624 16}
10625 ,
10626};
10627
10628const u32 mimophytbl_info_sz_rev16 =
10629 sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]);
diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h
new file mode 100644
index 00000000000..c5266cf2372
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#define ANT_SWCTRL_TBL_REV3_IDX (0)
18
19#include <types.h>
20#include "phy_int.h"
21
22extern const struct phytbl_info mimophytbl_info_rev0[],
23 mimophytbl_info_rev0_volatile[];
24extern const u32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile;
25
26extern const struct phytbl_info mimophytbl_info_rev3[],
27 mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[],
28 mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[];
29extern const u32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile,
30 mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2,
31 mimophytbl_info_sz_rev3_volatile3;
32
33extern const u32 noise_var_tbl_rev3[];
34
35extern const struct phytbl_info mimophytbl_info_rev7[];
36extern const u32 mimophytbl_info_sz_rev7;
37extern const u32 noise_var_tbl_rev7[];
38
39extern const struct phytbl_info mimophytbl_info_rev16[];
40extern const u32 mimophytbl_info_sz_rev16;
diff --git a/drivers/staging/brcm80211/brcmsmac/phy_shim.c b/drivers/staging/brcm80211/brcmsmac/phy_shim.c
new file mode 100644
index 00000000000..82ecdcda271
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy_shim.c
@@ -0,0 +1,218 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer.
19 * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY.
20 * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the
21 * access to wlc_hw pointer.
22 */
23#include <linux/slab.h>
24#include <net/mac80211.h>
25
26#include "bmac.h"
27#include "main.h"
28#include "mac80211_if.h"
29#include "phy_shim.h"
30
31/* PHY SHIM module specific state */
32struct phy_shim_info {
33 struct brcms_hardware *wlc_hw; /* pointer to main wlc_hw structure */
34 void *wlc; /* pointer to main wlc structure */
35 void *wl; /* pointer to os-specific private state */
36};
37
38struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
39 void *wl, void *wlc) {
40 struct phy_shim_info *physhim = NULL;
41
42 physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
43 if (!physhim) {
44 wiphy_err(wlc_hw->wlc->wiphy,
45 "wl%d: wlc_phy_shim_attach: out of mem\n",
46 wlc_hw->unit);
47 return NULL;
48 }
49 physhim->wlc_hw = wlc_hw;
50 physhim->wlc = wlc;
51 physhim->wl = wl;
52
53 return physhim;
54}
55
56void wlc_phy_shim_detach(struct phy_shim_info *physhim)
57{
58 kfree(physhim);
59}
60
61struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
62 void (*fn) (void *arg), void *arg,
63 const char *name)
64{
65 return (struct wlapi_timer *)
66 brcms_init_timer(physhim->wl, fn, arg, name);
67}
68
69void wlapi_free_timer(struct phy_shim_info *physhim, struct wlapi_timer *t)
70{
71 brcms_free_timer(physhim->wl, (struct brcms_timer *)t);
72}
73
74void
75wlapi_add_timer(struct phy_shim_info *physhim, struct wlapi_timer *t, uint ms,
76 int periodic)
77{
78 brcms_add_timer(physhim->wl, (struct brcms_timer *)t, ms, periodic);
79}
80
81bool wlapi_del_timer(struct phy_shim_info *physhim, struct wlapi_timer *t)
82{
83 return brcms_del_timer(physhim->wl, (struct brcms_timer *)t);
84}
85
86void wlapi_intrson(struct phy_shim_info *physhim)
87{
88 brcms_intrson(physhim->wl);
89}
90
91u32 wlapi_intrsoff(struct phy_shim_info *physhim)
92{
93 return brcms_intrsoff(physhim->wl);
94}
95
96void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
97{
98 brcms_intrsrestore(physhim->wl, macintmask);
99}
100
101void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
102{
103 brcms_b_write_shm(physhim->wlc_hw, offset, v);
104}
105
106u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
107{
108 return brcms_b_read_shm(physhim->wlc_hw, offset);
109}
110
111void
112wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
113 u16 val, int bands)
114{
115 brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
116}
117
118void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
119{
120 brcms_b_corereset(physhim->wlc_hw, flags);
121}
122
123void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
124{
125 brcms_c_suspend_mac_and_wait(physhim->wlc);
126}
127
128void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
129{
130 brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
131}
132
133void wlapi_enable_mac(struct phy_shim_info *physhim)
134{
135 brcms_c_enable_mac(physhim->wlc);
136}
137
138void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
139{
140 brcms_b_mctrl(physhim->wlc_hw, mask, val);
141}
142
143void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
144{
145 brcms_b_phy_reset(physhim->wlc_hw);
146}
147
148void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
149{
150 brcms_b_bw_set(physhim->wlc_hw, bw);
151}
152
153u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
154{
155 return brcms_b_get_txant(physhim->wlc_hw);
156}
157
158void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
159{
160 brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
161}
162
163void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
164{
165 brcms_b_macphyclk_set(physhim->wlc_hw, clk);
166}
167
168void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
169{
170 brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
171}
172
173void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
174{
175 brcms_b_core_phypll_reset(physhim->wlc_hw);
176}
177
178void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
179{
180 brcms_c_ucode_wake_override_set(physhim->wlc_hw,
181 BRCMS_WAKE_OVERRIDE_PHYREG);
182}
183
184void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
185{
186 brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
187 BRCMS_WAKE_OVERRIDE_PHYREG);
188}
189
190void
191wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
192 int len, void *buf)
193{
194 brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
195}
196
197u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
198{
199 return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
200}
201
202void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
203{
204}
205
206void
207wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
208 int len, u32 sel)
209{
210 brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
211}
212
213void
214wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
215 int l, u32 sel)
216{
217 brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
218}
diff --git a/drivers/staging/brcm80211/brcmsmac/phy_shim.h b/drivers/staging/brcm80211/brcmsmac/phy_shim.h
new file mode 100644
index 00000000000..2d12bb4400f
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/phy_shim.h
@@ -0,0 +1,164 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * phy_shim.h: stuff defined in phy_shim.c and included only by the phy
19 */
20
21#ifndef _BRCM_PHY_SHIM_H_
22#define _BRCM_PHY_SHIM_H_
23
24#include "types.h"
25
26#define RADAR_TYPE_NONE 0 /* Radar type None */
27#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */
28#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */
29#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */
30#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */
31#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */
32#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */
33#define RADAR_TYPE_BIN5 7 /* long pulse radar type */
34#define RADAR_TYPE_STG2 8 /* staggered-2 radar */
35#define RADAR_TYPE_STG3 9 /* staggered-3 radar */
36#define RADAR_TYPE_FRA 10 /* French radar */
37
38/* French radar pulse widths */
39#define FRA_T1_20MHZ 52770
40#define FRA_T2_20MHZ 61538
41#define FRA_T3_20MHZ 66002
42#define FRA_T1_40MHZ 105541
43#define FRA_T2_40MHZ 123077
44#define FRA_T3_40MHZ 132004
45#define FRA_ERR_20MHZ 60
46#define FRA_ERR_40MHZ 120
47
48#define ANTSEL_NA 0 /* No boardlevel selection available */
49#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */
50#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */
51
52/* Rx Antenna diversity control values */
53#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
54#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
55#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
56#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
57#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
58#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
59
60#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */
61#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */
62#define WL_ANT_IDX_1 0 /* antenna index 1 */
63#define WL_ANT_IDX_2 1 /* antenna index 2 */
64
65/* values for n_preamble_type */
66#define BRCMS_N_PREAMBLE_MIXEDMODE 0
67#define BRCMS_N_PREAMBLE_GF 1
68#define BRCMS_N_PREAMBLE_GF_BRCM 2
69
70#define WL_TX_POWER_RATES_LEGACY 45
71#define WL_TX_POWER_MCS20_FIRST 12
72#define WL_TX_POWER_MCS20_NUM 16
73#define WL_TX_POWER_MCS40_FIRST 28
74#define WL_TX_POWER_MCS40_NUM 17
75
76
77#define WL_TX_POWER_RATES 101
78#define WL_TX_POWER_CCK_FIRST 0
79#define WL_TX_POWER_CCK_NUM 4
80#define WL_TX_POWER_OFDM_FIRST 4 /* Index for first 20MHz OFDM SISO rate */
81#define WL_TX_POWER_OFDM20_CDD_FIRST 12 /* Index for first 20MHz OFDM CDD rate */
82#define WL_TX_POWER_OFDM40_SISO_FIRST 52 /* Index for first 40MHz OFDM SISO rate */
83#define WL_TX_POWER_OFDM40_CDD_FIRST 60 /* Index for first 40MHz OFDM CDD rate */
84#define WL_TX_POWER_OFDM_NUM 8
85#define WL_TX_POWER_MCS20_SISO_FIRST 20 /* Index for first 20MHz MCS SISO rate */
86#define WL_TX_POWER_MCS20_CDD_FIRST 28 /* Index for first 20MHz MCS CDD rate */
87#define WL_TX_POWER_MCS20_STBC_FIRST 36 /* Index for first 20MHz MCS STBC rate */
88#define WL_TX_POWER_MCS20_SDM_FIRST 44 /* Index for first 20MHz MCS SDM rate */
89#define WL_TX_POWER_MCS40_SISO_FIRST 68 /* Index for first 40MHz MCS SISO rate */
90#define WL_TX_POWER_MCS40_CDD_FIRST 76 /* Index for first 40MHz MCS CDD rate */
91#define WL_TX_POWER_MCS40_STBC_FIRST 84 /* Index for first 40MHz MCS STBC rate */
92#define WL_TX_POWER_MCS40_SDM_FIRST 92 /* Index for first 40MHz MCS SDM rate */
93#define WL_TX_POWER_MCS_1_STREAM_NUM 8
94#define WL_TX_POWER_MCS_2_STREAM_NUM 8
95#define WL_TX_POWER_MCS_32 100 /* Index for 40MHz rate MCS 32 */
96#define WL_TX_POWER_MCS_32_NUM 1
97
98/* sslpnphy specifics */
99#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12 /* Index for first 20MHz MCS SISO rate */
100
101/* struct tx_power::flags bits */
102#define WL_TX_POWER_F_ENABLED 1
103#define WL_TX_POWER_F_HW 2
104#define WL_TX_POWER_F_MIMO 4
105#define WL_TX_POWER_F_SISO 8
106
107/* values to force tx/rx chain */
108#define BRCMS_N_TXRX_CHAIN0 0
109#define BRCMS_N_TXRX_CHAIN1 1
110
111extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
112 void *wl, void *wlc);
113extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
114
115/* PHY to WL utility functions */
116extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
117 void (*fn) (void *arg), void *arg,
118 const char *name);
119extern void wlapi_free_timer(struct phy_shim_info *physhim,
120 struct wlapi_timer *t);
121extern void wlapi_add_timer(struct phy_shim_info *physhim,
122 struct wlapi_timer *t, uint ms, int periodic);
123extern bool wlapi_del_timer(struct phy_shim_info *physhim,
124 struct wlapi_timer *t);
125extern void wlapi_intrson(struct phy_shim_info *physhim);
126extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
127extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
128 u32 macintmask);
129
130extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset,
131 u16 v);
132extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
133extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx,
134 u16 mask, u16 val, int bands);
135extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
136extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
137extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
138extern void wlapi_enable_mac(struct phy_shim_info *physhim);
139extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask,
140 u32 val);
141extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
142extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
143extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
144extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
145extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
146extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
147extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *
148 physhim);
149extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *
150 physhim);
151extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
152 int len, void *buf);
153extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim,
154 u8 rate);
155extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
156extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint,
157 void *buf, int, u32 sel);
158extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
159 const void *buf, int, u32);
160
161extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
162 u32 phy_mode);
163extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
164#endif /* _BRCM_PHY_SHIM_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/pmu.c b/drivers/staging/brcm80211/brcmsmac/pmu.c
new file mode 100644
index 00000000000..e8b2b81d2d0
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/pmu.c
@@ -0,0 +1,474 @@
1/*
2 * Copyright (c) 2011 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/delay.h>
18#include <linux/io.h>
19
20#include <brcm_hw_ids.h>
21#include <chipcommon.h>
22#include <brcmu_utils.h>
23#include "pub.h"
24#include "aiutils.h"
25#include "pmu.h"
26
27/*
28 * external LPO crystal frequency
29 */
30#define EXT_ILP_HZ 32768
31
32/*
33 * Duration for ILP clock frequency measurment in milliseconds
34 *
35 * remark: 1000 must be an integer multiple of this duration
36 */
37#define ILP_CALC_DUR 10
38
39/* Fields in pmucontrol */
40#define PCTL_ILP_DIV_MASK 0xffff0000
41#define PCTL_ILP_DIV_SHIFT 16
42#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */
43#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */
44#define PCTL_HT_REQ_EN 0x00000100
45#define PCTL_ALP_REQ_EN 0x00000080
46#define PCTL_XTALFREQ_MASK 0x0000007c
47#define PCTL_XTALFREQ_SHIFT 2
48#define PCTL_ILP_DIV_EN 0x00000002
49#define PCTL_LPO_SEL 0x00000001
50
51/* ILP clock */
52#define ILP_CLOCK 32000
53
54/* ALP clock on pre-PMU chips */
55#define ALP_CLOCK 20000000
56
57/* pmustatus */
58#define PST_EXTLPOAVAIL 0x0100
59#define PST_WDRESET 0x0080
60#define PST_INTPEND 0x0040
61#define PST_SBCLKST 0x0030
62#define PST_SBCLKST_ILP 0x0010
63#define PST_SBCLKST_ALP 0x0020
64#define PST_SBCLKST_HT 0x0030
65#define PST_ALPAVAIL 0x0008
66#define PST_HTAVAIL 0x0004
67#define PST_RESINIT 0x0003
68
69/* PMU resource bit position */
70#define PMURES_BIT(bit) (1 << (bit))
71
72/* PMU corerev and chip specific PLL controls.
73 * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number
74 * to differentiate different PLLs controlled by the same PMU rev.
75 */
76/* pllcontrol registers */
77/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
78#define PMU1_PLL0_PLLCTL0 0
79#define PMU1_PLL0_PLLCTL1 1
80#define PMU1_PLL0_PLLCTL2 2
81#define PMU1_PLL0_PLLCTL3 3
82#define PMU1_PLL0_PLLCTL4 4
83#define PMU1_PLL0_PLLCTL5 5
84
85/* pmu XtalFreqRatio */
86#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF
87#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000
88#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31
89
90/* 4313 resources */
91#define RES4313_BB_PU_RSRC 0
92#define RES4313_ILP_REQ_RSRC 1
93#define RES4313_XTAL_PU_RSRC 2
94#define RES4313_ALP_AVAIL_RSRC 3
95#define RES4313_RADIO_PU_RSRC 4
96#define RES4313_BG_PU_RSRC 5
97#define RES4313_VREG1P4_PU_RSRC 6
98#define RES4313_AFE_PWRSW_RSRC 7
99#define RES4313_RX_PWRSW_RSRC 8
100#define RES4313_TX_PWRSW_RSRC 9
101#define RES4313_BB_PWRSW_RSRC 10
102#define RES4313_SYNTH_PWRSW_RSRC 11
103#define RES4313_MISC_PWRSW_RSRC 12
104#define RES4313_BB_PLL_PWRSW_RSRC 13
105#define RES4313_HT_AVAIL_RSRC 14
106#define RES4313_MACPHY_CLK_AVAIL_RSRC 15
107
108/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
109static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
110{
111 u32 min_mask = 0, max_mask = 0;
112 uint rsrcs;
113
114 /* # resources */
115 rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
116
117 /* determine min/max rsrc masks */
118 switch (sih->chip) {
119 case BCM43224_CHIP_ID:
120 case BCM43225_CHIP_ID:
121 /* ??? */
122 break;
123
124 case BCM4313_CHIP_ID:
125 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
126 PMURES_BIT(RES4313_XTAL_PU_RSRC) |
127 PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
128 PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
129 max_mask = 0xffff;
130 break;
131 default:
132 break;
133 }
134
135 *pmin = min_mask;
136 *pmax = max_mask;
137}
138
139static void
140si_pmu_spuravoid_pllupdate(struct si_pub *sih, chipcregs_t *cc, u8 spuravoid)
141{
142 u32 tmp = 0;
143
144 switch (sih->chip) {
145 case BCM43224_CHIP_ID:
146 case BCM43225_CHIP_ID:
147 if (spuravoid == 1) {
148 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
149 W_REG(&cc->pllcontrol_data, 0x11500010);
150 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
151 W_REG(&cc->pllcontrol_data, 0x000C0C06);
152 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
153 W_REG(&cc->pllcontrol_data, 0x0F600a08);
154 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
155 W_REG(&cc->pllcontrol_data, 0x00000000);
156 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
157 W_REG(&cc->pllcontrol_data, 0x2001E920);
158 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
159 W_REG(&cc->pllcontrol_data, 0x88888815);
160 } else {
161 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
162 W_REG(&cc->pllcontrol_data, 0x11100010);
163 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
164 W_REG(&cc->pllcontrol_data, 0x000c0c06);
165 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
166 W_REG(&cc->pllcontrol_data, 0x03000a08);
167 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
168 W_REG(&cc->pllcontrol_data, 0x00000000);
169 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
170 W_REG(&cc->pllcontrol_data, 0x200005c0);
171 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
172 W_REG(&cc->pllcontrol_data, 0x88888815);
173 }
174 tmp = 1 << 10;
175 break;
176
177 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
178 W_REG(&cc->pllcontrol_data, 0x11100008);
179 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
180 W_REG(&cc->pllcontrol_data, 0x0c000c06);
181 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
182 W_REG(&cc->pllcontrol_data, 0x03000a08);
183 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
184 W_REG(&cc->pllcontrol_data, 0x00000000);
185 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
186 W_REG(&cc->pllcontrol_data, 0x200005c0);
187 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
188 W_REG(&cc->pllcontrol_data, 0x88888855);
189
190 tmp = 1 << 10;
191 break;
192
193 default:
194 /* bail out */
195 return;
196 }
197
198 tmp |= R_REG(&cc->pmucontrol);
199 W_REG(&cc->pmucontrol, tmp);
200}
201
202u32 si_pmu_ilp_clock(struct si_pub *sih)
203{
204 static u32 ilpcycles_per_sec;
205
206 if (!PMUCTL_ENAB(sih))
207 return ILP_CLOCK;
208
209 if (ilpcycles_per_sec == 0) {
210 u32 start, end, delta;
211 u32 origidx = ai_coreidx(sih);
212 chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX);
213 start = R_REG(&cc->pmutimer);
214 mdelay(ILP_CALC_DUR);
215 end = R_REG(&cc->pmutimer);
216 delta = end - start;
217 ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
218 ai_setcoreidx(sih, origidx);
219 }
220
221 return ilpcycles_per_sec;
222}
223
224u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
225{
226 uint delay = PMU_MAX_TRANSITION_DLY;
227
228 switch (sih->chip) {
229 case BCM43224_CHIP_ID:
230 case BCM43225_CHIP_ID:
231 case BCM4313_CHIP_ID:
232 delay = 3700;
233 break;
234 default:
235 break;
236 }
237
238 return (u16) delay;
239}
240
241void si_pmu_sprom_enable(struct si_pub *sih, bool enable)
242{
243 chipcregs_t *cc;
244 uint origidx;
245
246 /* Remember original core before switch to chipc */
247 origidx = ai_coreidx(sih);
248 cc = ai_setcoreidx(sih, SI_CC_IDX);
249
250 /* Return to original core */
251 ai_setcoreidx(sih, origidx);
252}
253
254/* Read/write a chipcontrol reg */
255u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
256{
257 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
258 reg);
259 return ai_corereg(sih, SI_CC_IDX,
260 offsetof(chipcregs_t, chipcontrol_data), mask, val);
261}
262
263/* Read/write a regcontrol reg */
264u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
265{
266 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
267 reg);
268 return ai_corereg(sih, SI_CC_IDX,
269 offsetof(chipcregs_t, regcontrol_data), mask, val);
270}
271
272/* Read/write a pllcontrol reg */
273u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
274{
275 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
276 reg);
277 return ai_corereg(sih, SI_CC_IDX,
278 offsetof(chipcregs_t, pllcontrol_data), mask, val);
279}
280
281/* PMU PLL update */
282void si_pmu_pllupd(struct si_pub *sih)
283{
284 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
285 PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
286}
287
288/* query alp/xtal clock frequency */
289u32 si_pmu_alp_clock(struct si_pub *sih)
290{
291 u32 clock = ALP_CLOCK;
292
293 /* bail out with default */
294 if (!PMUCTL_ENAB(sih))
295 return clock;
296
297 switch (sih->chip) {
298 case BCM43224_CHIP_ID:
299 case BCM43225_CHIP_ID:
300 case BCM4313_CHIP_ID:
301 /* always 20Mhz */
302 clock = 20000 * 1000;
303 break;
304 default:
305 break;
306 }
307
308 return clock;
309}
310
311void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid)
312{
313 chipcregs_t *cc;
314 uint origidx, intr_val;
315
316 /* Remember original core before switch to chipc */
317 cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx,
318 &intr_val);
319
320 /* update the pll changes */
321 si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
322
323 /* Return to original core */
324 ai_restore_core(sih, origidx, intr_val);
325}
326
327/* initialize PMU */
328void si_pmu_init(struct si_pub *sih)
329{
330 chipcregs_t *cc;
331 uint origidx;
332
333 /* Remember original core before switch to chipc */
334 origidx = ai_coreidx(sih);
335 cc = ai_setcoreidx(sih, SI_CC_IDX);
336
337 if (sih->pmurev == 1)
338 AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
339 else if (sih->pmurev >= 2)
340 OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
341
342 /* Return to original core */
343 ai_setcoreidx(sih, origidx);
344}
345
346/* initialize PMU chip controls and other chip level stuff */
347void si_pmu_chip_init(struct si_pub *sih)
348{
349 uint origidx;
350
351 /* Gate off SPROM clock and chip select signals */
352 si_pmu_sprom_enable(sih, false);
353
354 /* Remember original core */
355 origidx = ai_coreidx(sih);
356
357 /* Return to original core */
358 ai_setcoreidx(sih, origidx);
359}
360
361/* initialize PMU switch/regulators */
362void si_pmu_swreg_init(struct si_pub *sih)
363{
364}
365
366/* initialize PLL */
367void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq)
368{
369 chipcregs_t *cc;
370 uint origidx;
371
372 /* Remember original core before switch to chipc */
373 origidx = ai_coreidx(sih);
374 cc = ai_setcoreidx(sih, SI_CC_IDX);
375
376 switch (sih->chip) {
377 case BCM4313_CHIP_ID:
378 case BCM43224_CHIP_ID:
379 case BCM43225_CHIP_ID:
380 /* ??? */
381 break;
382 default:
383 break;
384 }
385
386 /* Return to original core */
387 ai_setcoreidx(sih, origidx);
388}
389
390/* initialize PMU resources */
391void si_pmu_res_init(struct si_pub *sih)
392{
393 chipcregs_t *cc;
394 uint origidx;
395 u32 min_mask = 0, max_mask = 0;
396
397 /* Remember original core before switch to chipc */
398 origidx = ai_coreidx(sih);
399 cc = ai_setcoreidx(sih, SI_CC_IDX);
400
401 /* Determine min/max rsrc masks */
402 si_pmu_res_masks(sih, &min_mask, &max_mask);
403
404 /* It is required to program max_mask first and then min_mask */
405
406 /* Program max resource mask */
407
408 if (max_mask)
409 W_REG(&cc->max_res_mask, max_mask);
410
411 /* Program min resource mask */
412
413 if (min_mask)
414 W_REG(&cc->min_res_mask, min_mask);
415
416 /* Add some delay; allow resources to come up and settle. */
417 mdelay(2);
418
419 /* Return to original core */
420 ai_setcoreidx(sih, origidx);
421}
422
423u32 si_pmu_measure_alpclk(struct si_pub *sih)
424{
425 chipcregs_t *cc;
426 uint origidx;
427 u32 alp_khz;
428
429 if (sih->pmurev < 10)
430 return 0;
431
432 /* Remember original core before switch to chipc */
433 origidx = ai_coreidx(sih);
434 cc = ai_setcoreidx(sih, SI_CC_IDX);
435
436 if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
437 u32 ilp_ctr, alp_hz;
438
439 /*
440 * Enable the reg to measure the freq,
441 * in case it was disabled before
442 */
443 W_REG(&cc->pmu_xtalfreq,
444 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
445
446 /* Delay for well over 4 ILP clocks */
447 udelay(1000);
448
449 /* Read the latched number of ALP ticks per 4 ILP ticks */
450 ilp_ctr =
451 R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
452
453 /*
454 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
455 * bit to save power
456 */
457 W_REG(&cc->pmu_xtalfreq, 0);
458
459 /* Calculate ALP frequency */
460 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
461
462 /*
463 * Round to nearest 100KHz, and at
464 * the same time convert to KHz
465 */
466 alp_khz = (alp_hz + 50000) / 100000 * 100;
467 } else
468 alp_khz = 0;
469
470 /* Return to original core */
471 ai_setcoreidx(sih, origidx);
472
473 return alp_khz;
474}
diff --git a/drivers/staging/brcm80211/brcmsmac/pmu.h b/drivers/staging/brcm80211/brcmsmac/pmu.h
new file mode 100644
index 00000000000..0c7e48c4bcd
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/pmu.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18#ifndef _BRCM_PMU_H_
19#define _BRCM_PMU_H_
20
21#include "types.h"
22/*
23 * LDO selections used in si_pmu_set_ldo_voltage
24 */
25#define SET_LDO_VOLTAGE_LDO1 1
26#define SET_LDO_VOLTAGE_LDO2 2
27#define SET_LDO_VOLTAGE_LDO3 3
28#define SET_LDO_VOLTAGE_PAREF 4
29#define SET_LDO_VOLTAGE_CLDO_PWM 5
30#define SET_LDO_VOLTAGE_CLDO_BURST 6
31#define SET_LDO_VOLTAGE_CBUCK_PWM 7
32#define SET_LDO_VOLTAGE_CBUCK_BURST 8
33#define SET_LDO_VOLTAGE_LNLDO1 9
34#define SET_LDO_VOLTAGE_LNLDO2_SEL 10
35
36extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
37extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable);
38extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
39extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
40extern u32 si_pmu_ilp_clock(struct si_pub *sih);
41extern u32 si_pmu_alp_clock(struct si_pub *sih);
42extern void si_pmu_pllupd(struct si_pub *sih);
43extern void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid);
44extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
45extern void si_pmu_init(struct si_pub *sih);
46extern void si_pmu_chip_init(struct si_pub *sih);
47extern void si_pmu_pll_init(struct si_pub *sih, u32 xtalfreq);
48extern void si_pmu_res_init(struct si_pub *sih);
49extern void si_pmu_swreg_init(struct si_pub *sih);
50extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
51
52#endif /* _BRCM_PMU_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/pub.h b/drivers/staging/brcm80211/brcmsmac/pub.h
new file mode 100644
index 00000000000..01d74609560
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/pub.h
@@ -0,0 +1,665 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_PUB_H_
18#define _BRCM_PUB_H_
19
20#include <brcmu_wifi.h>
21#include "types.h"
22#include "defs.h"
23
24#define BRCMS_NUMRATES 16 /* max # of rates in a rateset */
25#define MAXMULTILIST 32 /* max # multicast addresses */
26#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */
27
28/* phy types */
29#define PHY_TYPE_A 0 /* Phy type A */
30#define PHY_TYPE_G 2 /* Phy type G */
31#define PHY_TYPE_N 4 /* Phy type N */
32#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */
33#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */
34#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */
35#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */
36#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */
37
38/* bw */
39#define BRCMS_10_MHZ 10 /* 10Mhz nphy channel bandwidth */
40#define BRCMS_20_MHZ 20 /* 20Mhz nphy channel bandwidth */
41#define BRCMS_40_MHZ 40 /* 40Mhz nphy channel bandwidth */
42
43#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? BRCMS_40_MHZ : \
44 CHSPEC_IS20(chanspec) ? BRCMS_20_MHZ : \
45 BRCMS_10_MHZ)
46
47#define BRCMS_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */
48#define BRCMS_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */
49#define BRCMS_RSSI_VERY_LOW -80 /* Very low quality cutoffs */
50#define BRCMS_RSSI_LOW -70 /* Low quality cutoffs */
51#define BRCMS_RSSI_GOOD -68 /* Good quality cutoffs */
52#define BRCMS_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */
53#define BRCMS_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */
54
55/* macro to perform PHY -> D11 PHY TYPE, currently 1:1 */
56#define BRCMS_PHYTYPE(_x) (_x)
57
58#define MA_WINDOW_SZ 8 /* moving average window size */
59
60#define BRCMS_SNR_INVALID 0 /* invalid SNR value */
61
62/* a large TX Power as an init value to factor out of min() calculations,
63 * keep low enough to fit in an s8, units are .25 dBm
64 */
65#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
66
67/* rate related definitions */
68#define BRCMS_RATE_FLAG 0x80 /* Flag to indicate it is a basic rate */
69#define BRCMS_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */
70
71/* legacy rx Antenna diversity for SISO rates */
72#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
73#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
74#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
75#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
76#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
77#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
78
79/* legacy rx Antenna diversity for SISO rates */
80#define ANT_TX_FORCE_0 0 /* Tx on antenna 0, "legacy term Main" */
81#define ANT_TX_FORCE_1 1 /* Tx on antenna 1, "legacy term Aux" */
82#define ANT_TX_LAST_RX 3 /* Tx on phy's last good Rx antenna */
83#define ANT_TX_DEF 3 /* driver's default tx antenna setting */
84
85#define TXCORE_POLICY_ALL 0x1 /* use all available core for transmit */
86
87/* Tx Chain values */
88#define TXCHAIN_DEF 0x1 /* def bitmap of txchain */
89#define TXCHAIN_DEF_NPHY 0x3 /* default bitmap of tx chains for nphy */
90#define TXCHAIN_DEF_HTPHY 0x7 /* default bitmap of tx chains for nphy */
91#define RXCHAIN_DEF 0x1 /* def bitmap of rxchain */
92#define RXCHAIN_DEF_NPHY 0x3 /* default bitmap of rx chains for nphy */
93#define RXCHAIN_DEF_HTPHY 0x7 /* default bitmap of rx chains for nphy */
94#define ANTSWITCH_NONE 0 /* no antenna switch */
95#define ANTSWITCH_TYPE_1 1 /* antenna switch on 4321CB2, 2of3 */
96#define ANTSWITCH_TYPE_2 2 /* antenna switch on 4321MPCI, 2of3 */
97#define ANTSWITCH_TYPE_3 3 /* antenna switch on 4322, 2of3 */
98
99#define RXBUFSZ PKTBUFSZ
100#ifndef AIDMAPSZ
101#define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */
102#endif /* AIDMAPSZ */
103
104#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */
105
106#define WL_SPURAVOID_OFF 0
107#define WL_SPURAVOID_ON1 1
108#define WL_SPURAVOID_ON2 2
109
110struct brcms_tunables {
111 int ntxd; /* size of tx descriptor table */
112 int nrxd; /* size of rx descriptor table */
113 int rxbufsz; /* size of rx buffers to post */
114 int nrxbufpost; /* # of rx buffers to post */
115 int maxscb; /* # of SCBs supported */
116 int ampdunummpdu; /* max number of mpdu in an ampdu */
117 int maxpktcb; /* max # of packet callbacks */
118 int maxucodebss; /* max # of BSS handled in ucode bcn/prb */
119 int maxucodebss4; /* max # of BSS handled in sw bcn/prb */
120 int maxbss; /* max # of bss info elements in scan list */
121 int datahiwat; /* data msg txq hiwat mark */
122 int ampdudatahiwat; /* AMPDU msg txq hiwat mark */
123 int rxbnd; /* max # of rx bufs to process before deferring to dpc */
124 int txsbnd; /* max # tx status to process in wlc_txstatus() */
125 int memreserved; /* memory reserved for BMAC's USB dma rx */
126};
127
128struct brcms_rateset {
129 uint count; /* number of rates in rates[] */
130 /* rates in 500kbps units w/hi bit set if basic */
131 u8 rates[BRCMS_NUMRATES];
132 u8 htphy_membership; /* HT PHY Membership */
133 u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */
134};
135
136struct rsn_parms {
137 u8 flags; /* misc booleans (e.g., supported) */
138 u8 multicast; /* multicast cipher */
139 u8 ucount; /* count of unicast ciphers */
140 u8 unicast[4]; /* unicast ciphers */
141 u8 acount; /* count of auth modes */
142 u8 auth[4]; /* Authentication modes */
143 u8 PAD[4]; /* padding for future growth */
144};
145
146/*
147 * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
148 */
149#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1)
150
151#define RSN_FLAGS_SUPPORTED 0x1 /* Flag for rsn_params */
152#define RSN_FLAGS_PREAUTH 0x2 /* Flag for WPA2 rsn_params */
153
154/* All the HT-specific default advertised capabilities (including AMPDU)
155 * should be grouped here at one place
156 */
157#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */
158
159/* defaults for the HT (MIMO) bss */
160#define HT_CAP (IEEE80211_HT_CAP_SM_PS |\
161 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\
162 IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40)
163
164/* wlc internal bss_info */
165struct brcms_bss_info {
166 u8 BSSID[ETH_ALEN]; /* network BSSID */
167 u16 flags; /* flags for internal attributes */
168 u8 SSID_len; /* the length of SSID */
169 u8 SSID[32]; /* SSID string */
170 s16 RSSI; /* receive signal strength (in dBm) */
171 s16 SNR; /* receive signal SNR in dB */
172 u16 beacon_period; /* units are Kusec */
173 u16 atim_window; /* units are Kusec */
174 chanspec_t chanspec; /* Channel num, bw, ctrl_sb and band */
175 s8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */
176 wlc_rateset_t rateset; /* supported rates */
177 u8 dtim_period; /* DTIM period */
178 s8 phy_noise; /* noise right after tx (in dBm) */
179 u16 capability; /* Capability information */
180 u8 wme_qosinfo; /* QoS Info from WME IE; valid if BSS_WME flag set */
181 struct rsn_parms wpa;
182 struct rsn_parms wpa2;
183 u16 qbss_load_aac; /* qbss load available admission capacity */
184 /* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */
185 u8 qbss_load_chan_free; /* indicates how free the channel is */
186 u8 mcipher; /* multicast cipher */
187 u8 wpacfg; /* wpa config index */
188};
189
190/* IOVar flags for common error checks */
191#define IOVF_MFG (1<<3) /* flag for mfgtest iovars */
192#define IOVF_WHL (1<<4) /* value must be whole (0-max) */
193#define IOVF_NTRL (1<<5) /* value must be natural (1-max) */
194
195#define IOVF_SET_UP (1<<6) /* set requires driver be up */
196#define IOVF_SET_DOWN (1<<7) /* set requires driver be down */
197#define IOVF_SET_CLK (1<<8) /* set requires core clock */
198#define IOVF_SET_BAND (1<<9) /* set requires fixed band */
199
200#define IOVF_GET_UP (1<<10) /* get requires driver be up */
201#define IOVF_GET_DOWN (1<<11) /* get requires driver be down */
202#define IOVF_GET_CLK (1<<12) /* get requires core clock */
203#define IOVF_GET_BAND (1<<13) /* get requires fixed band */
204#define IOVF_OPEN_ALLOW (1<<14) /* set allowed iovar for opensrc */
205
206/* watchdog down and dump callback function proto's */
207typedef int (*watchdog_fn_t) (void *handle);
208typedef int (*down_fn_t) (void *handle);
209typedef int (*dump_fn_t) (void *handle, struct brcmu_strbuf *b);
210
211/* IOVar handler
212 *
213 * handle - a pointer value registered with the function
214 * vi - iovar_info that was looked up
215 * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid.
216 * name - the actual iovar name
217 * params/plen - parameters and length for a get, input only.
218 * arg/len - buffer and length for value to be set or retrieved, input or output.
219 * vsize - value size, valid for integer type only.
220 * wlcif - interface context (brcms_c_if pointer)
221 *
222 * All pointers may point into the same buffer.
223 */
224typedef int (*iovar_fn_t) (void *handle, const struct brcmu_iovar *vi,
225 u32 actionid, const char *name, void *params,
226 uint plen, void *arg, int alen, int vsize,
227 struct brcms_c_if *wlcif);
228
229#define MAC80211_PROMISC_BCNS (1 << 0)
230#define MAC80211_SCAN (1 << 1)
231
232/*
233 * Public portion of "common" os-independent state structure.
234 * The wlc handle points at this.
235 */
236struct brcms_pub {
237 void *wlc;
238
239 struct ieee80211_hw *ieee_hw;
240 struct scb *global_scb;
241 struct scb_ampdu *global_ampdu;
242 uint mac80211_state;
243 uint unit; /* device instance number */
244 uint corerev; /* core revision */
245 struct si_pub *sih; /* SI handle (cookie for siutils calls) */
246 char *vars; /* "environment" name=value */
247 bool up; /* interface up and running */
248 bool hw_off; /* HW is off */
249 /* tunables: ntxd, nrxd, maxscb, etc. */
250 struct brcms_tunables *tunables;
251 bool hw_up; /* one time hw up/down(from boot or hibernation) */
252 bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */
253 uint _nbands; /* # bands supported */
254 uint now; /* # elapsed seconds */
255
256 bool promisc; /* promiscuous destination address */
257 bool delayed_down; /* down delayed */
258 bool _ap; /* AP mode enabled */
259 bool _apsta; /* simultaneous AP/STA mode enabled */
260 bool _assoc_recreate; /* association recreation on up transitions */
261 int _wme; /* WME QoS mode */
262 u8 _mbss; /* MBSS mode on */
263 bool allmulti; /* enable all multicasts */
264 bool associated; /* true:part of [I]BSS, false: not */
265 /* (union of stas_associated, aps_associated) */
266 bool phytest_on; /* whether a PHY test is running */
267 bool bf_preempt_4306; /* True to enable 'darwin' mode */
268 bool _ampdu; /* ampdu enabled or not */
269 bool _cac; /* 802.11e CAC enabled */
270 u8 _n_enab; /* bitmap of 11N + HT support */
271 bool _n_reqd; /* N support required for clients */
272
273 s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */
274 bool _priofc; /* Priority-based flowcontrol */
275
276 u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */
277
278 u8 *multicast; /* ptr to list of multicast addresses */
279 uint nmulticast; /* # enabled multicast addresses */
280
281 u32 wlfeatureflag; /* Flags to control sw features from registry */
282 int psq_pkts_total; /* total num of ps pkts */
283
284 u16 txmaxpkts; /* max number of large pkts allowed to be pending */
285
286 /* s/w decryption counters */
287 u32 swdecrypt; /* s/w decrypt attempts */
288
289 int bcmerror; /* last bcm error */
290
291 mbool radio_disabled; /* bit vector for radio disabled reasons */
292 bool radio_active; /* radio on/off state */
293 u16 roam_time_thresh; /* Max. # secs. of not hearing beacons
294 * before roaming.
295 */
296 bool align_wd_tbtt; /* Align watchdog with tbtt indication
297 * handling. This flag is cleared by default
298 * and is set by per port code explicitly and
299 * you need to make sure the OSL_SYSUPTIME()
300 * is implemented properly in osl of that port
301 * when it enables this Power Save feature.
302 */
303
304 u16 boardrev; /* version # of particular board */
305 u8 sromrev; /* version # of the srom */
306 char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */
307 u32 boardflags; /* Board specific flags from srom */
308 u32 boardflags2; /* More board flags if sromrev >= 4 */
309 bool tempsense_disable; /* disable periodic tempsense check */
310 bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
311 bool _ampdumac; /* mac assist ampdu enabled or not */
312
313 struct wl_cnt *_cnt; /* low-level counters in driver */
314};
315
316/* wl_monitor rx status per packet */
317struct wl_rxsts {
318 uint pkterror; /* error flags per pkt */
319 uint phytype; /* 802.11 A/B/G ... */
320 uint channel; /* channel */
321 uint datarate; /* rate in 500kbps */
322 uint antenna; /* antenna pkts received on */
323 uint pktlength; /* pkt length minus bcm phy hdr */
324 u32 mactime; /* time stamp from mac, count per 1us */
325 uint sq; /* signal quality */
326 s32 signal; /* in dbm */
327 s32 noise; /* in dbm */
328 uint preamble; /* Unknown, short, long */
329 uint encoding; /* Unknown, CCK, PBCC, OFDM */
330 uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */
331 struct brcms_if *wlif; /* wl interface */
332};
333
334/* status per error RX pkt */
335#define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */
336#define WL_RXS_RUNT_ERROR 0x00000002 /* Runt packet */
337#define WL_RXS_ALIGN_ERROR 0x00000004 /* Misaligned packet */
338#define WL_RXS_OVERSIZE_ERROR 0x00000008 /* packet bigger than RX_LENGTH (usually 1518) */
339#define WL_RXS_WEP_ICV_ERROR 0x00000010 /* Integrity Check Value error */
340#define WL_RXS_WEP_ENCRYPTED 0x00000020 /* Encrypted with WEP */
341#define WL_RXS_PLCP_SHORT 0x00000040 /* Short PLCP error */
342#define WL_RXS_DECRYPT_ERR 0x00000080 /* Decryption error */
343#define WL_RXS_OTHER_ERR 0x80000000 /* Other errors */
344
345/* phy type */
346#define WL_RXS_PHY_A 0x00000000 /* A phy type */
347#define WL_RXS_PHY_B 0x00000001 /* B phy type */
348#define WL_RXS_PHY_G 0x00000002 /* G phy type */
349#define WL_RXS_PHY_N 0x00000004 /* N phy type */
350
351/* encoding */
352#define WL_RXS_ENCODING_CCK 0x00000000 /* CCK encoding */
353#define WL_RXS_ENCODING_OFDM 0x00000001 /* OFDM encoding */
354
355/* preamble */
356#define WL_RXS_UNUSED_STUB 0x0 /* stub to match with wlc_ethereal.h */
357#define WL_RXS_PREAMBLE_SHORT 0x00000001 /* Short preamble */
358#define WL_RXS_PREAMBLE_LONG 0x00000002 /* Long preamble */
359#define WL_RXS_PREAMBLE_MIMO_MM 0x00000003 /* MIMO mixed mode preamble */
360#define WL_RXS_PREAMBLE_MIMO_GF 0x00000004 /* MIMO green field preamble */
361
362#define WL_RXS_NFRM_AMPDU_FIRST 0x00000001 /* first MPDU in A-MPDU */
363#define WL_RXS_NFRM_AMPDU_SUB 0x00000002 /* subsequent MPDU(s) in A-MPDU */
364#define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */
365#define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */
366
367enum wlc_par_id {
368 IOV_MPC = 1,
369 IOV_RTSTHRESH,
370 IOV_QTXPOWER,
371 IOV_BCN_LI_BCN /* Beacon listen interval in # of beacons */
372};
373
374/***********************************************
375 * Feature-related macros to optimize out code *
376 * *********************************************
377 */
378
379/* AP Support (versus STA) */
380#define AP_ENAB(pub) (0)
381
382/* Macro to check if APSTA mode enabled */
383#define APSTA_ENAB(pub) (0)
384
385/* Some useful combinations */
386#define STA_ONLY(pub) (!AP_ENAB(pub))
387#define AP_ONLY(pub) (AP_ENAB(pub) && !APSTA_ENAB(pub))
388
389#define ENAB_1x1 0x01
390#define ENAB_2x2 0x02
391#define ENAB_3x3 0x04
392#define ENAB_4x4 0x08
393#define SUPPORT_11N (ENAB_1x1|ENAB_2x2)
394#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3)
395/* WL11N Support */
396#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \
397 (defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0)))
398#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N)
399#define N_REQD(pub) ((pub)->_n_reqd)
400#else
401#define N_ENAB(pub) 0
402#define N_REQD(pub) 0
403#endif
404
405#if (defined(HTCONF) && (HTCONF != 0))
406#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT)
407#else
408#define HT_ENAB(pub) 0
409#endif
410
411#define AMPDU_AGG_HOST 1
412#define AMPDU_ENAB(pub) ((pub)->_ampdu)
413
414#define EDCF_ENAB(pub) (WME_ENAB(pub))
415#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub))
416
417#define MONITOR_ENAB(wlc) ((wlc)->monitor)
418
419#define PROMISC_ENAB(wlc) ((wlc)->promisc)
420
421#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */
422
423/* pri is priority encoded in the packet. This maps the Packet priority to
424 * enqueue precedence as defined in wlc_prec_map
425 */
426extern const u8 wlc_prio2prec_map[];
427#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7]
428
429/* This maps priority to one precedence higher - Used by PS-Poll response packets to
430 * simulate enqueue-at-head operation, but still maintain the order on the queue
431 */
432#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\
433 BRCMS_PREC_COUNT - 1)
434
435extern const u8 wme_fifo2ac[];
436#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]]
437
438/* Mask to describe all precedence levels */
439#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT)
440
441/* Define a bitmap of precedences comprised by each AC */
442#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
443 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \
444 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \
445 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
446#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
447 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \
448 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \
449 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
450#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
451 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \
452 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \
453 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
454#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
455 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \
456 NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \
457 NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
458
459/* WME Support */
460#define WME_ENAB(pub) ((pub)->_wme != OFF)
461#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO)
462
463/* invalid core flags, use the saved coreflags */
464#define BRCMS_USE_COREFLAGS 0xffffffff
465
466
467/* network protection config */
468#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */
469#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */
470#define BRCMS_PROT_G_USER 3 /* gmode specified by user */
471#define BRCMS_PROT_OVERLAP 4 /* overlap */
472#define BRCMS_PROT_N_USER 10 /* nmode specified by user */
473#define BRCMS_PROT_N_CFG 11 /* n protection */
474#define BRCMS_PROT_N_CFG_OVR 12 /* n protection override */
475#define BRCMS_PROT_N_NONGF 13 /* non-GF protection */
476#define BRCMS_PROT_N_NONGF_OVR 14 /* non-GF protection override */
477#define BRCMS_PROT_N_PAM_OVR 15 /* n preamble override */
478#define BRCMS_PROT_N_OBSS 16 /* non-HT OBSS present */
479
480/*
481 * 54g modes (basic bits may still be overridden)
482 *
483 * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11
484 * Preamble: Long
485 * Shortslot: Off
486 * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
487 * Extended Rateset: 6, 9, 12, 48
488 * Preamble: Long
489 * Shortslot: Auto
490 * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
491 * Extended Rateset: 6b, 9, 12b, 48
492 * Preamble: Short required
493 * Shortslot: Auto
494 * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
495 * Extended Rateset: 6, 9, 12, 48
496 * Preamble: Long
497 * Shortslot: On
498 * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
499 * Preamble: Short required
500 * Shortslot: On and required
501 * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b
502 * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
503 * Preamble: Long
504 * Shortslot: Auto
505 */
506#define GMODE_LEGACY_B 0
507#define GMODE_AUTO 1
508#define GMODE_ONLY 2
509#define GMODE_B_DEFERRED 3
510#define GMODE_PERFORMANCE 4
511#define GMODE_LRS 5
512#define GMODE_MAX 6
513
514/* values for PLCPHdr_override */
515#define BRCMS_PLCP_AUTO -1
516#define BRCMS_PLCP_SHORT 0
517#define BRCMS_PLCP_LONG 1
518
519/* values for g_protection_override and n_protection_override */
520#define BRCMS_PROTECTION_AUTO -1
521#define BRCMS_PROTECTION_OFF 0
522#define BRCMS_PROTECTION_ON 1
523#define BRCMS_PROTECTION_MMHDR_ONLY 2
524#define BRCMS_PROTECTION_CTS_ONLY 3
525
526/* values for g_protection_control and n_protection_control */
527#define BRCMS_PROTECTION_CTL_OFF 0
528#define BRCMS_PROTECTION_CTL_LOCAL 1
529#define BRCMS_PROTECTION_CTL_OVERLAP 2
530
531/* values for n_protection */
532#define BRCMS_N_PROTECTION_OFF 0
533#define BRCMS_N_PROTECTION_OPTIONAL 1
534#define BRCMS_N_PROTECTION_20IN40 2
535#define BRCMS_N_PROTECTION_MIXEDMODE 3
536
537/* values for band specific 40MHz capabilities */
538#define BRCMS_N_BW_20ALL 0
539#define BRCMS_N_BW_40ALL 1
540#define BRCMS_N_BW_20IN2G_40IN5G 2
541
542/* bitflags for SGI support (sgi_rx iovar) */
543#define BRCMS_N_SGI_20 0x01
544#define BRCMS_N_SGI_40 0x02
545
546/* defines used by the nrate iovar */
547#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */
548#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */
549#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */
550#define NRATE_STF_SHIFT 8 /* stf mode shift */
551#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */
552#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */
553#define NRATE_SGI_MASK 0x00800000 /* sgi mode */
554#define NRATE_SGI_SHIFT 23 /* sgi mode */
555#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */
556#define NRATE_LDPC_SHIFT 22 /* ldpc shift */
557
558#define NRATE_STF_SISO 0 /* stf mode SISO */
559#define NRATE_STF_CDD 1 /* stf mode CDD */
560#define NRATE_STF_STBC 2 /* stf mode STBC */
561#define NRATE_STF_SDM 3 /* stf mode SDM */
562
563#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */
564
565#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */
566
567struct brcms_antselcfg {
568 u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */
569 u8 num_antcfg; /* number of available antenna configurations */
570};
571
572/* common functions for every port */
573extern void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device,
574 uint unit, bool piomode, void *regsva, uint bustype,
575 void *btparam, uint *perr);
576extern uint brcms_c_detach(struct brcms_c_info *wlc);
577extern int brcms_c_up(struct brcms_c_info *wlc);
578extern uint brcms_c_down(struct brcms_c_info *wlc);
579
580extern int brcms_c_set(struct brcms_c_info *wlc, int cmd, int arg);
581extern int brcms_c_get(struct brcms_c_info *wlc, int cmd, int *arg);
582extern bool brcms_c_chipmatch(u16 vendor, u16 device);
583extern void brcms_c_init(struct brcms_c_info *wlc);
584extern void brcms_c_reset(struct brcms_c_info *wlc);
585
586extern void brcms_c_intrson(struct brcms_c_info *wlc);
587extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
588extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
589extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
590extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
591extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
592extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
593 struct sk_buff *sdu,
594 struct ieee80211_hw *hw);
595extern int brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len,
596 struct brcms_c_if *wlcif);
597extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
598
599/* helper functions */
600extern void brcms_c_statsupd(struct brcms_c_info *wlc);
601extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx,
602 int val);
603extern int brcms_c_get_header_len(void);
604extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
605 bool promisc);
606extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc,
607 int match_reg_offset,
608 const u8 *addr);
609extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
610 const struct ieee80211_tx_queue_params *arg,
611 bool suspend);
612extern struct brcms_pub *brcms_c_pub(void *wlc);
613
614/* common functions for every port */
615extern void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val,
616 int bands);
617extern void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
618 wlc_rateset_t *rateset);
619extern void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs);
620
621extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
622 struct ieee80211_sta *sta, u16 tid);
623extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
624 u8 ba_wsize, uint max_rx_ampdu_bytes);
625extern int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
626 int val);
627extern int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
628 int *ret_int_ptr);
629extern char *getvar(char *vars, const char *name);
630extern int getintvar(char *vars, const char *name);
631
632/* wlc_phy.c helper functions */
633extern void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc);
634extern void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val);
635
636extern int brcms_c_module_register(struct brcms_pub *pub,
637 const char *name, void *hdl,
638 watchdog_fn_t watchdog_fn, down_fn_t down_fn);
639extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
640 void *hdl);
641extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc);
642extern void brcms_c_enable_mac(struct brcms_c_info *wlc);
643extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
644extern void brcms_c_scan_start(struct brcms_c_info *wlc);
645extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
646extern int brcms_c_get_curband(struct brcms_c_info *wlc);
647extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
648 bool drop);
649
650/* helper functions */
651extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
652extern bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc);
653
654#define MAXBANDS 2 /* Maximum #of bands */
655/* bandstate array indices */
656#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */
657#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */
658
659#define BAND_2G_NAME "2.4G"
660#define BAND_5G_NAME "5G"
661
662/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */
663#define BRCMS_RPCTX_PARAMS 32
664
665#endif /* _BRCM_PUB_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/rate.c b/drivers/staging/brcm80211/brcmsmac/rate.c
new file mode 100644
index 00000000000..f0e4b99c256
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/rate.c
@@ -0,0 +1,498 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <brcmu_wifi.h>
18#include <brcmu_utils.h>
19
20#include "d11.h"
21#include "pub.h"
22#include "rate.h"
23
24/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */
25const u8 rate_info[BRCM_MAXRATE + 1] = {
26 /* 0 1 2 3 4 5 6 7 8 9 */
27/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
28/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
29/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
30/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
31/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
32/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
37/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
38};
39
40/* rates are in units of Kbps */
41const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = {
42 /* MCS 0: SS 1, MOD: BPSK, CR 1/2 */
43 {6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
44 BRCM_RATE_6M},
45 /* MCS 1: SS 1, MOD: QPSK, CR 1/2 */
46 {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
47 BRCM_RATE_12M},
48 /* MCS 2: SS 1, MOD: QPSK, CR 3/4 */
49 {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
50 BRCM_RATE_18M},
51 /* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */
52 {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
53 BRCM_RATE_24M},
54 /* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */
55 {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
56 BRCM_RATE_36M},
57 /* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */
58 {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
59 BRCM_RATE_48M},
60 /* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */
61 {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
62 BRCM_RATE_54M},
63 /* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */
64 {65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
65 BRCM_RATE_54M},
66 /* MCS 8: SS 2, MOD: BPSK, CR 1/2 */
67 {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
68 BRCM_RATE_6M},
69 /* MCS 9: SS 2, MOD: QPSK, CR 1/2 */
70 {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
71 BRCM_RATE_12M},
72 /* MCS 10: SS 2, MOD: QPSK, CR 3/4 */
73 {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
74 BRCM_RATE_18M},
75 /* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
76 {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
77 BRCM_RATE_24M},
78 /* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
79 {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
80 BRCM_RATE_36M},
81 /* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
82 {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
83 BRCM_RATE_48M},
84 /* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
85 {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
86 BRCM_RATE_54M},
87 /* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
88 {130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
89 BRCM_RATE_54M},
90 /* MCS 16: SS 3, MOD: BPSK, CR 1/2 */
91 {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
92 BRCM_RATE_6M},
93 /* MCS 17: SS 3, MOD: QPSK, CR 1/2 */
94 {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
95 BRCM_RATE_12M},
96 /* MCS 18: SS 3, MOD: QPSK, CR 3/4 */
97 {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
98 BRCM_RATE_18M},
99 /* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
100 {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
101 BRCM_RATE_24M},
102 /* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
103 {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
104 BRCM_RATE_36M},
105 /* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
106 {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
107 BRCM_RATE_48M},
108 /* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
109 {175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
110 BRCM_RATE_54M},
111 /* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
112 {195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
113 BRCM_RATE_54M},
114 /* MCS 24: SS 4, MOD: BPSK, CR 1/2 */
115 {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
116 BRCM_RATE_6M},
117 /* MCS 25: SS 4, MOD: QPSK, CR 1/2 */
118 {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
119 BRCM_RATE_12M},
120 /* MCS 26: SS 4, MOD: QPSK, CR 3/4 */
121 {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
122 BRCM_RATE_18M},
123 /* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
124 {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
125 BRCM_RATE_24M},
126 /* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
127 {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
128 BRCM_RATE_36M},
129 /* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
130 {208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
131 BRCM_RATE_48M},
132 /* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
133 {234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
134 BRCM_RATE_54M},
135 /* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
136 {260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
137 BRCM_RATE_54M},
138 /* MCS 32: SS 1, MOD: BPSK, CR 1/2 */
139 {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M},
140};
141
142/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
143 * Number of spatial streams: always 1
144 * other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard
145 */
146struct legacy_phycfg {
147 u32 rate_ofdm; /* ofdm mac rate */
148 u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */
149};
150
151#define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */
152
153/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
154/* Eventually MIMOPHY would also be converted to this format */
155/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
156static const struct
157legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
158 {BRCM_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */
159 {BRCM_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */
160 {BRCM_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */
161 {BRCM_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */
162 /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */
163 {BRCM_RATE_6M, 0x00},
164 /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */
165 {BRCM_RATE_9M, 0x02},
166 /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */
167 {BRCM_RATE_12M, 0x08},
168 /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */
169 {BRCM_RATE_18M, 0x0A},
170 /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
171 {BRCM_RATE_24M, 0x10},
172 /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
173 {BRCM_RATE_36M, 0x12},
174 /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
175 {BRCM_RATE_48M, 0x19},
176 /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
177 {BRCM_RATE_54M, 0x1A},
178};
179
180/* Hardware rates (also encodes default basic rates) */
181
182const wlc_rateset_t cck_ofdm_mimo_rates = {
183 12,
184 { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
185 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
186 0x6c},
187 0x00,
188 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00}
190};
191
192const wlc_rateset_t ofdm_mimo_rates = {
193 8,
194 { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
195 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
196 0x00,
197 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x00, 0x00, 0x00}
199};
200
201/* Default ratesets that include MCS32 for 40BW channels */
202const wlc_rateset_t cck_ofdm_40bw_mimo_rates = {
203 12,
204 { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
205 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
206 0x6c},
207 0x00,
208 {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00}
210};
211
212const wlc_rateset_t ofdm_40bw_mimo_rates = {
213 8,
214 { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
215 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
216 0x00,
217 {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00}
219};
220
221const wlc_rateset_t cck_ofdm_rates = {
222 12,
223 { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */
224 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
225 0x6c},
226 0x00,
227 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00, 0x00}
229};
230
231const wlc_rateset_t gphy_legacy_rates = {
232 4,
233 { /* 1b, 2b, 5.5b, 11b Mbps */
234 0x82, 0x84, 0x8b, 0x96},
235 0x00,
236 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00}
238};
239
240const wlc_rateset_t ofdm_rates = {
241 8,
242 { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */
243 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
244 0x00,
245 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00}
247};
248
249const wlc_rateset_t cck_rates = {
250 4,
251 { /* 1b, 2b, 5.5, 11 Mbps */
252 0x82, 0x84, 0x0b, 0x16},
253 0x00,
254 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x00, 0x00, 0x00, 0x00}
256};
257
258/* check if rateset is valid.
259 * if check_brate is true, rateset without a basic rate is considered NOT valid.
260 */
261static bool brcms_c_rateset_valid(wlc_rateset_t *rs, bool check_brate)
262{
263 uint idx;
264
265 if (!rs->count)
266 return false;
267
268 if (!check_brate)
269 return true;
270
271 /* error if no basic rates */
272 for (idx = 0; idx < rs->count; idx++) {
273 if (rs->rates[idx] & BRCMS_RATE_FLAG)
274 return true;
275 }
276 return false;
277}
278
279void brcms_c_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams)
280{
281 int i;
282 for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
283 rs->mcs[i] = 0;
284}
285
286/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved,
287 * and check if resulting rateset is valid.
288*/
289bool
290brcms_c_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs,
291 const wlc_rateset_t *hw_rs,
292 bool check_brate, u8 txstreams)
293{
294 u8 rateset[BRCM_MAXRATE + 1];
295 u8 r;
296 uint count;
297 uint i;
298
299 memset(rateset, 0, sizeof(rateset));
300 count = rs->count;
301
302 for (i = 0; i < count; i++) {
303 /* mask off "basic rate" bit, BRCMS_RATE_FLAG */
304 r = (int)rs->rates[i] & BRCMS_RATE_MASK;
305 if ((r > BRCM_MAXRATE) || (rate_info[r] == 0))
306 continue;
307 rateset[r] = rs->rates[i]; /* preserve basic bit! */
308 }
309
310 /* fill out the rates in order, looking at only supported rates */
311 count = 0;
312 for (i = 0; i < hw_rs->count; i++) {
313 r = hw_rs->rates[i] & BRCMS_RATE_MASK;
314 if (rateset[r])
315 rs->rates[count++] = rateset[r];
316 }
317
318 rs->count = count;
319
320 /* only set the mcs rate bit if the equivalent hw mcs bit is set */
321 for (i = 0; i < MCSSET_LEN; i++)
322 rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
323
324 if (brcms_c_rateset_valid(rs, check_brate))
325 return true;
326 else
327 return false;
328}
329
330/* calculate the rate of a rx'd frame and return it as a ratespec */
331ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp)
332{
333 int phy_type;
334 ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
335
336 phy_type =
337 ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
338
339 if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
340 (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
341 switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
342 case PRXS0_CCK:
343 rspec =
344 CCK_PHY2MAC_RATE(
345 ((struct cck_phy_hdr *) plcp)->signal);
346 break;
347 case PRXS0_OFDM:
348 rspec =
349 OFDM_PHY2MAC_RATE(
350 ((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
351 break;
352 case PRXS0_PREN:
353 rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
354 if (plcp[0] & MIMO_PLCP_40MHZ) {
355 /* indicate rspec is for 40 MHz mode */
356 rspec &= ~RSPEC_BW_MASK;
357 rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
358 }
359 break;
360 case PRXS0_STDN:
361 /* fallthru */
362 default:
363 /* not supported, error condition */
364 break;
365 }
366 if (PLCP3_ISSGI(plcp[3]))
367 rspec |= RSPEC_SHORT_GI;
368 } else
369 if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
370 rspec = OFDM_PHY2MAC_RATE(
371 ((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
372 else
373 rspec = CCK_PHY2MAC_RATE(
374 ((struct cck_phy_hdr *) plcp)->signal);
375
376 return rspec;
377}
378
379/* copy rateset src to dst as-is (no masking or sorting) */
380void brcms_c_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst)
381{
382 memcpy(dst, src, sizeof(wlc_rateset_t));
383}
384
385/*
386 * Copy and selectively filter one rateset to another.
387 * 'basic_only' means only copy basic rates.
388 * 'rates' indicates cck (11b) and ofdm rates combinations.
389 * - 0: cck and ofdm
390 * - 1: cck only
391 * - 2: ofdm only
392 * 'xmask' is the copy mask (typically 0x7f or 0xff).
393 */
394void
395brcms_c_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only,
396 u8 rates, uint xmask, bool mcsallow)
397{
398 uint i;
399 uint r;
400 uint count;
401
402 count = 0;
403 for (i = 0; i < src->count; i++) {
404 r = src->rates[i];
405 if (basic_only && !(r & BRCMS_RATE_FLAG))
406 continue;
407 if (rates == BRCMS_RATES_CCK && IS_OFDM((r & BRCMS_RATE_MASK)))
408 continue;
409 if (rates == BRCMS_RATES_OFDM && IS_CCK((r & BRCMS_RATE_MASK)))
410 continue;
411 dst->rates[count++] = r & xmask;
412 }
413 dst->count = count;
414 dst->htphy_membership = src->htphy_membership;
415
416 if (mcsallow && rates != BRCMS_RATES_CCK)
417 memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
418 else
419 brcms_c_rateset_mcs_clear(dst);
420}
421
422/* select rateset for a given phy_type and bandtype and filter it, sort it
423 * and fill rs_tgt with result
424 */
425void
426brcms_c_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw,
427 uint phy_type, int bandtype, bool cck_only, uint rate_mask,
428 bool mcsallow, u8 bw, u8 txstreams)
429{
430 const wlc_rateset_t *rs_dflt;
431 wlc_rateset_t rs_sel;
432 if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
433 (PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
434 (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
435 (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
436 if (BAND_5G(bandtype)) {
437 rs_dflt = (bw == BRCMS_20_MHZ ?
438 &ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
439 } else {
440 rs_dflt = (bw == BRCMS_20_MHZ ?
441 &cck_ofdm_mimo_rates :
442 &cck_ofdm_40bw_mimo_rates);
443 }
444 } else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
445 rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates;
446 } else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
447 rs_dflt = &ofdm_rates;
448 } else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
449 rs_dflt = &cck_ofdm_rates;
450 } else {
451 /* should not happen, error condition */
452 rs_dflt = &cck_rates; /* force cck */
453 }
454
455 /* if hw rateset is not supplied, assign selected rateset to it */
456 if (!rs_hw)
457 rs_hw = rs_dflt;
458
459 brcms_c_rateset_copy(rs_dflt, &rs_sel);
460 brcms_c_rateset_mcs_upd(&rs_sel, txstreams);
461 brcms_c_rateset_filter(&rs_sel, rs_tgt, false,
462 cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM,
463 rate_mask, mcsallow);
464 brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
465 mcsallow ? txstreams : 1);
466}
467
468s16 brcms_c_rate_legacy_phyctl(uint rate)
469{
470 uint i;
471 for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
472 if (rate == legacy_phycfg_table[i].rate_ofdm)
473 return legacy_phycfg_table[i].tx_phy_ctl3;
474
475 return -1;
476}
477
478void brcms_c_rateset_mcs_clear(wlc_rateset_t *rateset)
479{
480 uint i;
481 for (i = 0; i < MCSSET_LEN; i++)
482 rateset->mcs[i] = 0;
483}
484
485void brcms_c_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams)
486{
487 memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
488 brcms_c_rateset_mcs_upd(rateset, txstreams);
489}
490
491/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
492void brcms_c_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw)
493{
494 if (bw == BRCMS_40_MHZ)
495 setbit(rateset->mcs, 32);
496 else
497 clrbit(rateset->mcs, 32);
498}
diff --git a/drivers/staging/brcm80211/brcmsmac/rate.h b/drivers/staging/brcm80211/brcmsmac/rate.h
new file mode 100644
index 00000000000..dbfd3e5816d
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/rate.h
@@ -0,0 +1,173 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_RATE_H_
18#define _BRCM_RATE_H_
19
20#include "types.h"
21
22extern const u8 rate_info[];
23extern const struct brcms_rateset cck_ofdm_mimo_rates;
24extern const struct brcms_rateset ofdm_mimo_rates;
25extern const struct brcms_rateset cck_ofdm_rates;
26extern const struct brcms_rateset ofdm_rates;
27extern const struct brcms_rateset cck_rates;
28extern const struct brcms_rateset gphy_legacy_rates;
29extern const struct brcms_rateset wlc_lrs_rates;
30extern const struct brcms_rateset rate_limit_1_2;
31
32struct brcms_mcs_info {
33 u32 phy_rate_20; /* phy rate in kbps [20Mhz] */
34 u32 phy_rate_40; /* phy rate in kbps [40Mhz] */
35 u32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */
36 u32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */
37 u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */
38 u8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */
39};
40
41#define BRCMS_MAXMCS 32 /* max valid mcs index */
42#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */
43extern const struct brcms_mcs_info mcs_table[];
44
45#define MCS_INVALID 0xFF
46#define MCS_CR_MASK 0x07 /* Code Rate bit mask */
47#define MCS_MOD_MASK 0x38 /* Modulation bit shift */
48#define MCS_MOD_SHIFT 3 /* MOdulation bit shift */
49#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */
50#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */
51#define MCS_CR(_mcs) (mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK)
52#define MCS_MOD(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT)
53#define MCS_TXS(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT)
54#define MCS_RATE(_mcs, _is40, _sgi) (_sgi ? \
55 (_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \
56 (_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20))
57#define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE))
58
59/* Macro to use the rate_info table */
60#define BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
61
62/* convert 500kbps to bps */
63#define BRCMS_RATE_500K_TO_BPS(rate) ((rate) * 500000)
64
65/* rate spec : holds rate and mode specific information required to generate a tx frame. */
66/* Legacy CCK and OFDM information is held in the same manner as was done in the past */
67/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */
68
69/* rate spec bit fields */
70#define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */
71#define RSPEC_MIMORATE 0x08000000 /* mimo MCS is stored in RSPEC_RATE_MASK */
72#define RSPEC_BW_MASK 0x00000700 /* mimo bw mask */
73#define RSPEC_BW_SHIFT 8 /* mimo bw shift */
74#define RSPEC_STF_MASK 0x00003800 /* mimo Space/Time/Frequency mode mask */
75#define RSPEC_STF_SHIFT 11 /* mimo Space/Time/Frequency mode shift */
76#define RSPEC_CT_MASK 0x0000C000 /* mimo coding type mask */
77#define RSPEC_CT_SHIFT 14 /* mimo coding type shift */
78#define RSPEC_STC_MASK 0x00300000 /* mimo num STC streams per PLCP defn. */
79#define RSPEC_STC_SHIFT 20 /* mimo num STC streams per PLCP defn. */
80#define RSPEC_LDPC_CODING 0x00400000 /* mimo bit indicates adv coding in use */
81#define RSPEC_SHORT_GI 0x00800000 /* mimo bit indicates short GI in use */
82#define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */
83#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */
84
85#define BRCMS_HTPHY 127 /* HT PHY Membership */
86
87#define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE))
88#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \
89 MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \
90 (rspec & RSPEC_RATE_MASK))
91/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */
92#define RSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \
93 MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \
94 (rspec & RSPEC_RATE_MASK))
95#define CRSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \
96 MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\
97 (rspec & RSPEC_RATE_MASK))
98
99#define RSPEC2KBPS(rspec) (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500)
100#define RSPEC_PHYTXBYTE2(rspec) ((rspec & 0xff00) >> 8)
101#define RSPEC_GET_BW(rspec) ((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT)
102#define RSPEC_IS40MHZ(rspec) ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \
103 PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \
104 RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP))
105#define RSPEC_ISSGI(rspec) ((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI)
106#define RSPEC_MIMOPLCP3(rspec) ((rspec & 0xf00000) >> 16)
107#define PLCP3_ISSGI(plcp) (plcp & (RSPEC_SHORT_GI >> 16))
108#define RSPEC_STC(rspec) ((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT)
109#define RSPEC_STF(rspec) ((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT)
110#define PLCP3_ISSTBC(plcp) ((plcp & (RSPEC_STC_MASK) >> 16) == 0x10)
111#define PLCP3_STC_MASK 0x30
112#define PLCP3_STC_SHIFT 4
113
114/* Rate info table; takes a legacy rate or ratespec_t */
115#define IS_MCS(r) (r & RSPEC_MIMORATE)
116#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & \
117 BRCMS_RATE_FLAG))
118#define IS_CCK(r) (!IS_MCS(r) && ( \
119 ((r) & BRCMS_RATE_MASK) == BRCM_RATE_1M || \
120 ((r) & BRCMS_RATE_MASK) == BRCM_RATE_2M || \
121 ((r) & BRCMS_RATE_MASK) == BRCM_RATE_5M5 || \
122 ((r) & BRCMS_RATE_MASK) == BRCM_RATE_11M))
123#define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32))
124#define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK)
125#define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\
126 (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT))
127#define LEGACY_RSPEC(rate) (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate))
128
129#define MCS_RSPEC(mcs) (((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \
130 (IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \
131 (PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT)))
132
133/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */
134extern const u8 ofdm_rate_lookup[];
135#define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7])
136#define CCK_PHY2MAC_RATE(signal) (signal/5)
137
138/* Rates specified in brcms_c_rateset_filter() */
139#define BRCMS_RATES_CCK_OFDM 0
140#define BRCMS_RATES_CCK 1
141#define BRCMS_RATES_OFDM 2
142
143/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */
144extern bool
145brcms_c_rate_hwrs_filter_sort_validate(struct brcms_rateset *rs,
146 const struct brcms_rateset *hw_rs,
147 bool check_brate, u8 txstreams);
148/* copy rateset src to dst as-is (no masking or sorting) */
149extern void brcms_c_rateset_copy(const struct brcms_rateset *src,
150 struct brcms_rateset *dst);
151
152/* would be nice to have these documented ... */
153extern ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
154
155extern void brcms_c_rateset_filter(struct brcms_rateset *src,
156 struct brcms_rateset *dst, bool basic_only, u8 rates, uint xmask,
157 bool mcsallow);
158
159extern void
160brcms_c_rateset_default(struct brcms_rateset *rs_tgt,
161 const struct brcms_rateset *rs_hw, uint phy_type,
162 int bandtype, bool cck_only, uint rate_mask,
163 bool mcsallow, u8 bw, u8 txstreams);
164
165extern s16 brcms_c_rate_legacy_phyctl(uint rate);
166
167extern void brcms_c_rateset_mcs_upd(struct brcms_rateset *rs, u8 txstreams);
168extern void brcms_c_rateset_mcs_clear(struct brcms_rateset *rateset);
169extern void brcms_c_rateset_mcs_build(struct brcms_rateset *rateset,
170 u8 txstreams);
171extern void brcms_c_rateset_bw_mcs_filter(struct brcms_rateset *rateset, u8 bw);
172
173#endif /* _BRCM_RATE_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/scb.h b/drivers/staging/brcm80211/brcmsmac/scb.h
new file mode 100644
index 00000000000..d6c8328554d
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/scb.h
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SCB_H_
18#define _BRCM_SCB_H_
19
20#include <linux/if_ether.h>
21#include <brcmu_utils.h>
22#include <defs.h>
23#include "types.h"
24
25#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */
26/* structure to store per-tid state for the ampdu initiator */
27struct scb_ampdu_tid_ini {
28 u8 tx_in_transit; /* number of pending mpdus in transit in driver */
29 u8 tid; /* initiator tid for easy lookup */
30 u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */
31 struct scb *scb; /* backptr for easy lookup */
32 u8 ba_wsize; /* negotiated ba window size (in pdu) */
33};
34
35#define AMPDU_MAX_SCB_TID NUMPRIO
36
37struct scb_ampdu {
38 struct scb *scb; /* back pointer for easy reference */
39 u8 mpdu_density; /* mpdu density */
40 u8 max_pdu; /* max pdus allowed in ampdu */
41 u8 release; /* # of mpdus released at a time */
42 u16 min_len; /* min mpdu len to support the density */
43 u32 max_rx_ampdu_bytes; /* max ampdu rcv length; 8k, 16k, 32k, 64k */
44 struct pktq txq; /* sdu transmit queue pending aggregation */
45
46 /* This could easily be a ini[] pointer and we keep this info in wl itself instead
47 * of having mac80211 hold it for us. Also could be made dynamic per tid instead of
48 * static.
49 */
50 /* initiator info - per tid (NUMPRIO): */
51 struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID];
52};
53
54#define SCB_MAGIC 0xbeefcafe
55
56/* station control block - one per remote MAC address */
57struct scb {
58 u32 magic;
59 u32 flags; /* various bit flags as defined below */
60 u32 flags2; /* various bit flags2 as defined below */
61 u8 state; /* current state bitfield of auth/assoc process */
62 u8 ea[ETH_ALEN]; /* station address */
63 void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */
64 uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */
65
66 u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */
67 u16 seqctl_nonqos; /* seqctl of last received frame (for dups) for
68 * non-QoS data and management
69 */
70 u16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */
71
72 struct scb_ampdu scb_ampdu; /* AMPDU state including per tid info */
73};
74
75/* scb flags */
76#define SCB_WMECAP 0x0040 /* may ONLY be set if WME_ENAB(wlc) */
77#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */
78#define SCB_IS40 0x80000 /* 40MHz capable */
79#define SCB_STBCCAP 0x40000000 /* STBC Capable */
80#define SCB_WME(a) ((a)->flags & SCB_WMECAP)/* implies WME_ENAB */
81#define SCB_SEQNUM(scb, prio) ((scb)->seqnum[(prio)])
82#define SCB_PS(a) NULL
83#define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP)
84#define SCB_AMPDU(a) true
85#endif /* _BRCM_SCB_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/srom.c b/drivers/staging/brcm80211/brcmsmac/srom.c
new file mode 100644
index 00000000000..f39442ed4ce
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/srom.c
@@ -0,0 +1,1237 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/io.h>
20#include <linux/etherdevice.h>
21#include <stdarg.h>
22
23#include <chipcommon.h>
24#include <brcmu_utils.h>
25#include "nicpci.h"
26#include "aiutils.h"
27#include "otp.h"
28#include "srom.h"
29
30#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
31 (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
32 ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
33 ((u8 *)curmap + PCI_BAR0_SPROM_OFFSET))
34
35#if defined(BCMDBG)
36#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
37#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
38#endif
39
40/* Maximum srom: 6 Kilobits == 768 bytes */
41#define SROM_MAX 768
42
43/* PCI fields */
44#define PCI_F0DEVID 48
45
46#define SROM_WORDS 64
47
48#define SROM_SSID 2
49
50#define SROM_WL1LHMAXP 29
51
52#define SROM_WL1LPAB0 30
53#define SROM_WL1LPAB1 31
54#define SROM_WL1LPAB2 32
55
56#define SROM_WL1HPAB0 33
57#define SROM_WL1HPAB1 34
58#define SROM_WL1HPAB2 35
59
60#define SROM_MACHI_IL0 36
61#define SROM_MACMID_IL0 37
62#define SROM_MACLO_IL0 38
63#define SROM_MACHI_ET1 42
64#define SROM_MACMID_ET1 43
65#define SROM_MACLO_ET1 44
66#define SROM3_MACHI 37
67#define SROM3_MACMID 38
68#define SROM3_MACLO 39
69
70#define SROM_BXARSSI2G 40
71#define SROM_BXARSSI5G 41
72
73#define SROM_TRI52G 42
74#define SROM_TRI5GHL 43
75
76#define SROM_RXPO52G 45
77
78#define SROM_AABREV 46
79/* Fields in AABREV */
80#define SROM_BR_MASK 0x00ff
81#define SROM_CC_MASK 0x0f00
82#define SROM_CC_SHIFT 8
83#define SROM_AA0_MASK 0x3000
84#define SROM_AA0_SHIFT 12
85#define SROM_AA1_MASK 0xc000
86#define SROM_AA1_SHIFT 14
87
88#define SROM_WL0PAB0 47
89#define SROM_WL0PAB1 48
90#define SROM_WL0PAB2 49
91
92#define SROM_LEDBH10 50
93#define SROM_LEDBH32 51
94
95#define SROM_WL10MAXP 52
96
97#define SROM_WL1PAB0 53
98#define SROM_WL1PAB1 54
99#define SROM_WL1PAB2 55
100
101#define SROM_ITT 56
102
103#define SROM_BFL 57
104#define SROM_BFL2 28
105#define SROM3_BFL2 61
106
107#define SROM_AG10 58
108
109#define SROM_CCODE 59
110
111#define SROM_OPO 60
112
113#define SROM3_LEDDC 62
114
115#define SROM_CRCREV 63
116
117/* SROM Rev 4: Reallocate the software part of the srom to accommodate
118 * MIMO features. It assumes up to two PCIE functions and 440 bytes
119 * of usable srom i.e. the usable storage in chips with OTP that
120 * implements hardware redundancy.
121 */
122
123#define SROM4_WORDS 220
124
125#define SROM4_SIGN 32
126#define SROM4_SIGNATURE 0x5372
127
128#define SROM4_BREV 33
129
130#define SROM4_BFL0 34
131#define SROM4_BFL1 35
132#define SROM4_BFL2 36
133#define SROM4_BFL3 37
134#define SROM5_BFL0 37
135#define SROM5_BFL1 38
136#define SROM5_BFL2 39
137#define SROM5_BFL3 40
138
139#define SROM4_MACHI 38
140#define SROM4_MACMID 39
141#define SROM4_MACLO 40
142#define SROM5_MACHI 41
143#define SROM5_MACMID 42
144#define SROM5_MACLO 43
145
146#define SROM4_CCODE 41
147#define SROM4_REGREV 42
148#define SROM5_CCODE 34
149#define SROM5_REGREV 35
150
151#define SROM4_LEDBH10 43
152#define SROM4_LEDBH32 44
153#define SROM5_LEDBH10 59
154#define SROM5_LEDBH32 60
155
156#define SROM4_LEDDC 45
157#define SROM5_LEDDC 45
158
159#define SROM4_AA 46
160
161#define SROM4_AG10 47
162#define SROM4_AG32 48
163
164#define SROM4_TXPID2G 49
165#define SROM4_TXPID5G 51
166#define SROM4_TXPID5GL 53
167#define SROM4_TXPID5GH 55
168
169#define SROM4_TXRXC 61
170#define SROM4_TXCHAIN_MASK 0x000f
171#define SROM4_TXCHAIN_SHIFT 0
172#define SROM4_RXCHAIN_MASK 0x00f0
173#define SROM4_RXCHAIN_SHIFT 4
174#define SROM4_SWITCH_MASK 0xff00
175#define SROM4_SWITCH_SHIFT 8
176
177/* Per-path fields */
178#define MAX_PATH_SROM 4
179#define SROM4_PATH0 64
180#define SROM4_PATH1 87
181#define SROM4_PATH2 110
182#define SROM4_PATH3 133
183
184#define SROM4_2G_ITT_MAXP 0
185#define SROM4_2G_PA 1
186#define SROM4_5G_ITT_MAXP 5
187#define SROM4_5GLH_MAXP 6
188#define SROM4_5G_PA 7
189#define SROM4_5GL_PA 11
190#define SROM4_5GH_PA 15
191
192/* All the miriad power offsets */
193#define SROM4_2G_CCKPO 156
194#define SROM4_2G_OFDMPO 157
195#define SROM4_5G_OFDMPO 159
196#define SROM4_5GL_OFDMPO 161
197#define SROM4_5GH_OFDMPO 163
198#define SROM4_2G_MCSPO 165
199#define SROM4_5G_MCSPO 173
200#define SROM4_5GL_MCSPO 181
201#define SROM4_5GH_MCSPO 189
202#define SROM4_CDDPO 197
203#define SROM4_STBCPO 198
204#define SROM4_BW40PO 199
205#define SROM4_BWDUPPO 200
206
207#define SROM4_CRCREV 219
208
209/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
210 * This is acombined srom for both MIMO and SISO boards, usable in
211 * the .130 4Kilobit OTP with hardware redundancy.
212 */
213#define SROM8_BREV 65
214
215#define SROM8_BFL0 66
216#define SROM8_BFL1 67
217#define SROM8_BFL2 68
218#define SROM8_BFL3 69
219
220#define SROM8_MACHI 70
221#define SROM8_MACMID 71
222#define SROM8_MACLO 72
223
224#define SROM8_CCODE 73
225#define SROM8_REGREV 74
226
227#define SROM8_LEDBH10 75
228#define SROM8_LEDBH32 76
229
230#define SROM8_LEDDC 77
231
232#define SROM8_AA 78
233
234#define SROM8_AG10 79
235#define SROM8_AG32 80
236
237#define SROM8_TXRXC 81
238
239#define SROM8_BXARSSI2G 82
240#define SROM8_BXARSSI5G 83
241#define SROM8_TRI52G 84
242#define SROM8_TRI5GHL 85
243#define SROM8_RXPO52G 86
244
245#define SROM8_FEM2G 87
246#define SROM8_FEM5G 88
247#define SROM8_FEM_ANTSWLUT_MASK 0xf800
248#define SROM8_FEM_ANTSWLUT_SHIFT 11
249#define SROM8_FEM_TR_ISO_MASK 0x0700
250#define SROM8_FEM_TR_ISO_SHIFT 8
251#define SROM8_FEM_PDET_RANGE_MASK 0x00f8
252#define SROM8_FEM_PDET_RANGE_SHIFT 3
253#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006
254#define SROM8_FEM_EXTPA_GAIN_SHIFT 1
255#define SROM8_FEM_TSSIPOS_MASK 0x0001
256#define SROM8_FEM_TSSIPOS_SHIFT 0
257
258#define SROM8_THERMAL 89
259
260/* Temp sense related entries */
261#define SROM8_MPWR_RAWTS 90
262#define SROM8_TS_SLP_OPT_CORRX 91
263/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
264#define SROM8_FOC_HWIQ_IQSWP 92
265
266/* Temperature delta for PHY calibration */
267#define SROM8_PHYCAL_TEMPDELTA 93
268
269/* Per-path offsets & fields */
270#define SROM8_PATH0 96
271#define SROM8_PATH1 112
272#define SROM8_PATH2 128
273#define SROM8_PATH3 144
274
275#define SROM8_2G_ITT_MAXP 0
276#define SROM8_2G_PA 1
277#define SROM8_5G_ITT_MAXP 4
278#define SROM8_5GLH_MAXP 5
279#define SROM8_5G_PA 6
280#define SROM8_5GL_PA 9
281#define SROM8_5GH_PA 12
282
283/* All the miriad power offsets */
284#define SROM8_2G_CCKPO 160
285
286#define SROM8_2G_OFDMPO 161
287#define SROM8_5G_OFDMPO 163
288#define SROM8_5GL_OFDMPO 165
289#define SROM8_5GH_OFDMPO 167
290
291#define SROM8_2G_MCSPO 169
292#define SROM8_5G_MCSPO 177
293#define SROM8_5GL_MCSPO 185
294#define SROM8_5GH_MCSPO 193
295
296#define SROM8_CDDPO 201
297#define SROM8_STBCPO 202
298#define SROM8_BW40PO 203
299#define SROM8_BWDUPPO 204
300
301/* SISO PA parameters are in the path0 spaces */
302#define SROM8_SISO 96
303
304/* Legacy names for SISO PA paramters */
305#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP)
306#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA)
307#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1)
308#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2)
309#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP)
310#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP)
311#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA)
312#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1)
313#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2)
314#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA)
315#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1)
316#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2)
317#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA)
318#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1)
319#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2)
320
321/* SROM REV 9 */
322#define SROM9_2GPO_CCKBW20 160
323#define SROM9_2GPO_CCKBW20UL 161
324#define SROM9_2GPO_LOFDMBW20 162
325#define SROM9_2GPO_LOFDMBW20UL 164
326
327#define SROM9_5GLPO_LOFDMBW20 166
328#define SROM9_5GLPO_LOFDMBW20UL 168
329#define SROM9_5GMPO_LOFDMBW20 170
330#define SROM9_5GMPO_LOFDMBW20UL 172
331#define SROM9_5GHPO_LOFDMBW20 174
332#define SROM9_5GHPO_LOFDMBW20UL 176
333
334#define SROM9_2GPO_MCSBW20 178
335#define SROM9_2GPO_MCSBW20UL 180
336#define SROM9_2GPO_MCSBW40 182
337
338#define SROM9_5GLPO_MCSBW20 184
339#define SROM9_5GLPO_MCSBW20UL 186
340#define SROM9_5GLPO_MCSBW40 188
341#define SROM9_5GMPO_MCSBW20 190
342#define SROM9_5GMPO_MCSBW20UL 192
343#define SROM9_5GMPO_MCSBW40 194
344#define SROM9_5GHPO_MCSBW20 196
345#define SROM9_5GHPO_MCSBW20UL 198
346#define SROM9_5GHPO_MCSBW40 200
347
348#define SROM9_PO_MCS32 202
349#define SROM9_PO_LOFDM40DUP 203
350
351/* SROM flags (see sromvar_t) */
352#define SRFL_MORE 1 /* value continues as described by the next entry */
353#define SRFL_NOFFS 2 /* value bits can't be all one's */
354#define SRFL_PRHEX 4 /* value is in hexdecimal format */
355#define SRFL_PRSIGN 8 /* value is in signed decimal format */
356#define SRFL_CCODE 0x10 /* value is in country code format */
357#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */
358#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */
359#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */
360
361/* Max. nvram variable table size */
362#define MAXSZ_NVRAM_VARS 4096
363
364struct brcms_sromvar {
365 const char *name;
366 u32 revmask;
367 u32 flags;
368 u16 off;
369 u16 mask;
370};
371
372struct brcms_varbuf {
373 char *base; /* pointer to buffer base */
374 char *buf; /* pointer to current position */
375 unsigned int size; /* current (residual) size in bytes */
376};
377
378/* Assumptions:
379 * - Ethernet address spans across 3 consective words
380 *
381 * Table rules:
382 * - Add multiple entries next to each other if a value spans across multiple words
383 * (even multiple fields in the same word) with each entry except the last having
384 * it's SRFL_MORE bit set.
385 * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
386 * bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
387 * - The last entry's name field must be NULL to indicate the end of the table. Other
388 * entries must have non-NULL name.
389 */
390static const struct brcms_sromvar pci_sromvars[] = {
391 {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff},
392 {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
393 {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
394 {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
395 {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
396 {"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
397 {"", 0, 0, SROM_BFL2, 0xffff},
398 {"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
399 {"", 0, 0, SROM3_BFL2, 0xffff},
400 {"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
401 {"", 0, 0, SROM4_BFL1, 0xffff},
402 {"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
403 {"", 0, 0, SROM5_BFL1, 0xffff},
404 {"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
405 {"", 0, 0, SROM8_BFL1, 0xffff},
406 {"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
407 {"", 0, 0, SROM4_BFL3, 0xffff},
408 {"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
409 {"", 0, 0, SROM5_BFL3, 0xffff},
410 {"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
411 {"", 0, 0, SROM8_BFL3, 0xffff},
412 {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
413 {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
414 {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
415 {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
416 {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
417 {"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
418 {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
419 {"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
420 {"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff},
421 {"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff},
422 {"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff},
423 {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
424 {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
425 {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
426 {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
427 {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
428 {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
429 {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
430 {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
431 {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
432 {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
433 {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
434 {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
435 {"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
436 {"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
437 {"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
438 {"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
439 {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
440 {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
441 {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
442 {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff},
443 {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
444 {"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
445 {"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
446 {"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
447 {"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
448 {"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
449 {"opo", 0x0000000c, 0, SROM_OPO, 0x00ff},
450 {"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
451 {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
452 {"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff},
453 {"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff},
454 {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
455 {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
456 {"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
457 {"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff},
458 {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
459 {"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff},
460 {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
461 {"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff},
462 {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
463 {"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff},
464 {"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
465 {"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff},
466 {"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
467 {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
468 {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
469 {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
470 {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
471 {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
472 {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
473 {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
474 {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
475 {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
476 {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
477 {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
478 {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
479 {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
480 {"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
481 {"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
482 {"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
483 {"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
484 {"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
485 {"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
486 {"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
487 {"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
488 {"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
489 {"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
490 {"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
491 {"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
492 {"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
493 {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
494 {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
495 {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
496 {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
497 {"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
498 {"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
499 {"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
500 {"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
501 {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
502 {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
503 {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
504 {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
505 {"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
506 {"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
507 {"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
508 {"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
509 {"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff},
510 {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
511 {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
512 {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
513 {"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
514 {"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
515 {"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
516 {"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
517 {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
518 {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
519 {"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
520 {"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
521 {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
522 {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
523 {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
524 {"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
525 {"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
526 {"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
527 {"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK},
528 {"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK},
529 {"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK},
530 {"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
531 {"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK},
532 {"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK},
533 {"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK},
534 {"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK},
535 {"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
536 {"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK},
537 {"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00},
538 {"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
539 {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
540 {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
541 {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff},
542 {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
543 {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
544 {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
545 {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff},
546 {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
547 {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
548 {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
549 {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff},
550 {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
551 {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
552 {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
553 {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff},
554 {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
555
556 {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
557 {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
558 {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
559 {"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
560 {"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
561 {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
562 {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
563 {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
564 {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
565 {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
566 {"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
567 {"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
568 {"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
569 {"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
570 {"rawtempsense", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff},
571 {"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00},
572 {"tempsense_slope", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
573 0x00ff},
574 {"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00},
575 {"tempsense_option", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
576 0x0300},
577 {"freqoffset_corr", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
578 0x000f},
579 {"iqcal_swp_dis", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010},
580 {"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020},
581 {"phycal_tempdelta", 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff},
582
583 {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
584 {"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
585 {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
586 {"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
587 {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
588 {"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
589 {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
590 {"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
591 {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
592 {"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
593 {"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
594 {"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
595 {"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
596 {"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
597 {"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
598 {"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
599 {"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
600 {"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
601 {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
602 {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
603 {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
604 {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
605 {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
606 {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
607 {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
608 {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
609 {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
610 {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
611 {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
612 {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
613 {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
614 {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
615 {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
616 {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
617 {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
618 {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
619 {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
620 {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
621 {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
622 {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
623 {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
624 {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
625 {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
626 {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
627 {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
628 {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
629 {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
630 {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
631 {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
632 {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
633 {"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
634 {"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
635 {"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
636 {"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
637 {"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
638 {"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
639 {"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
640 {"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
641 {"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
642 {"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
643 {"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
644 {"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
645 {"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
646 {"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
647 {"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
648 {"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
649 {"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
650 {"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
651 {"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
652 {"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
653 {"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
654 {"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
655 {"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
656 {"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
657 {"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
658 {"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
659 {"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
660 {"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
661 {"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
662 {"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
663 {"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
664 {"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
665 {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
666 {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
667 {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
668 {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
669 {"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff},
670 {"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff},
671 {"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff},
672 {"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
673
674 /* power per rate from sromrev 9 */
675 {"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
676 {"cckbw20ul2gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
677 {"legofdmbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20,
678 0xffff},
679 {"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
680 {"legofdmbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL,
681 0xffff},
682 {"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
683 {"legofdmbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20,
684 0xffff},
685 {"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
686 {"legofdmbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL,
687 0xffff},
688 {"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
689 {"legofdmbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20,
690 0xffff},
691 {"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
692 {"legofdmbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL,
693 0xffff},
694 {"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
695 {"legofdmbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20,
696 0xffff},
697 {"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
698 {"legofdmbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL,
699 0xffff},
700 {"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
701 {"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff},
702 {"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
703 {"mcsbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff},
704 {"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
705 {"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff},
706 {"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
707 {"mcsbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff},
708 {"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
709 {"mcsbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL,
710 0xffff},
711 {"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
712 {"mcsbw405glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff},
713 {"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
714 {"mcsbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff},
715 {"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
716 {"mcsbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL,
717 0xffff},
718 {"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
719 {"mcsbw405gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff},
720 {"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
721 {"mcsbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff},
722 {"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
723 {"mcsbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL,
724 0xffff},
725 {"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
726 {"mcsbw405ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff},
727 {"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
728 {"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
729 {"legofdm40duppo", 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
730
731 {NULL, 0, 0, 0, 0}
732};
733
734static const struct brcms_sromvar perpath_pci_sromvars[] = {
735 {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
736 {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
737 {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
738 {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
739 {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
740 {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
741 {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
742 {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
743 {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
744 {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
745 {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
746 {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
747 {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
748 {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
749 {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
750 {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff},
751 {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff},
752 {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff},
753 {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
754 {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff},
755 {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff},
756 {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff},
757 {"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
758 {"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
759 {"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
760 {"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
761 {"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
762 {"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
763 {"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
764 {"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
765 {"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
766 {"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
767 {"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
768 {"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
769 {"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
770 {"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff},
771 {"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff},
772 {"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
773 {"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff},
774 {"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff},
775 {NULL, 0, 0, 0, 0}
776};
777
778static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off,
779 struct brcms_varbuf *b);
780static int initvars_srom_pci(struct si_pub *sih, void *curmap, char **vars,
781 uint *count);
782static int sprom_read_pci(struct si_pub *sih, u16 *sprom,
783 uint wordoff, u16 *buf, uint nwords, bool check_crc);
784#if defined(BCMNVRAMR)
785static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz);
786#endif
787
788static int initvars_table(char *start, char *end,
789 char **vars, uint *count);
790
791/* Initialization of varbuf structure */
792static void varbuf_init(struct brcms_varbuf *b, char *buf, uint size)
793{
794 b->size = size;
795 b->base = b->buf = buf;
796}
797
798/* append a null terminated var=value string */
799static int varbuf_append(struct brcms_varbuf *b, const char *fmt, ...)
800{
801 va_list ap;
802 int r;
803 size_t len;
804 char *s;
805
806 if (b->size < 2)
807 return 0;
808
809 va_start(ap, fmt);
810 r = vsnprintf(b->buf, b->size, fmt, ap);
811 va_end(ap);
812
813 /* C99 snprintf behavior returns r >= size on overflow,
814 * others return -1 on overflow.
815 * All return -1 on format error.
816 * We need to leave room for 2 null terminations, one for the current var
817 * string, and one for final null of the var table. So check that the
818 * strlen written, r, leaves room for 2 chars.
819 */
820 if ((r == -1) || (r > (int)(b->size - 2))) {
821 b->size = 0;
822 return 0;
823 }
824
825 /* Remove any earlier occurrence of the same variable */
826 s = strchr(b->buf, '=');
827 if (s != NULL) {
828 len = (size_t) (s - b->buf);
829 for (s = b->base; s < b->buf;) {
830 if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') {
831 len = strlen(s) + 1;
832 memmove(s, (s + len),
833 ((b->buf + r + 1) - (s + len)));
834 b->buf -= len;
835 b->size += (unsigned int)len;
836 break;
837 }
838
839 while (*s++)
840 ;
841 }
842 }
843
844 /* skip over this string's null termination */
845 r++;
846 b->size -= r;
847 b->buf += r;
848
849 return r;
850}
851
852/*
853 * Initialize local vars from the right source for this platform.
854 * Return 0 on success, nonzero on error.
855 */
856int srom_var_init(struct si_pub *sih, uint bustype, void *curmap,
857 char **vars, uint *count)
858{
859 uint len;
860
861 len = 0;
862
863 if (vars == NULL || count == NULL)
864 return 0;
865
866 *vars = NULL;
867 *count = 0;
868
869 if (curmap != NULL && bustype == PCI_BUS)
870 return initvars_srom_pci(sih, curmap, vars, count);
871
872 return -EINVAL;
873}
874
875static inline void ltoh16_buf(u16 *buf, unsigned int size)
876{
877 for (size /= 2; size; size--)
878 *(buf + size) = le16_to_cpu(*(buf + size));
879}
880
881static inline void htol16_buf(u16 *buf, unsigned int size)
882{
883 for (size /= 2; size; size--)
884 *(buf + size) = cpu_to_le16(*(buf + size));
885}
886
887/*
888 * Read in and validate sprom.
889 * Return 0 on success, nonzero on error.
890 */
891static int
892sprom_read_pci(struct si_pub *sih, u16 *sprom, uint wordoff,
893 u16 *buf, uint nwords, bool check_crc)
894{
895 int err = 0;
896 uint i;
897
898 /* read the sprom */
899 for (i = 0; i < nwords; i++)
900 buf[i] = R_REG(&sprom[wordoff + i]);
901
902 if (check_crc) {
903
904 if (buf[0] == 0xffff) {
905 /* The hardware thinks that an srom that starts with 0xffff
906 * is blank, regardless of the rest of the content, so declare
907 * it bad.
908 */
909 return -ENODATA;
910 }
911
912 /* fixup the endianness so crc8 will pass */
913 htol16_buf(buf, nwords * 2);
914 if (brcmu_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) !=
915 CRC8_GOOD_VALUE) {
916 /* DBG only pci always read srom4 first, then srom8/9 */
917 err = -EIO;
918 }
919 /* now correct the endianness of the byte array */
920 ltoh16_buf(buf, nwords * 2);
921 }
922 return err;
923}
924
925#if defined(BCMNVRAMR)
926static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz)
927{
928 u8 *otp;
929 uint sz = OTP_SZ_MAX / 2; /* size in words */
930 int err = 0;
931
932 otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
933 if (otp == NULL) {
934 return -ENOMEM;
935 }
936
937 err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
938
939 memcpy(buf, otp, bufsz);
940
941 kfree(otp);
942
943 /* Check CRC */
944 if (buf[0] == 0xffff) {
945 /* The hardware thinks that an srom that starts with 0xffff
946 * is blank, regardless of the rest of the content, so declare
947 * it bad.
948 */
949 return -ENODATA;
950 }
951
952 /* fixup the endianness so crc8 will pass */
953 htol16_buf(buf, bufsz);
954 if (brcmu_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) !=
955 CRC8_GOOD_VALUE) {
956 err = -EIO;
957 }
958 /* now correct the endianness of the byte array */
959 ltoh16_buf(buf, bufsz);
960
961 return err;
962}
963#endif /* defined(BCMNVRAMR) */
964/*
965* Create variable table from memory.
966* Return 0 on success, nonzero on error.
967*/
968static int initvars_table(char *start, char *end,
969 char **vars, uint *count)
970{
971 int c = (int)(end - start);
972
973 /* do it only when there is more than just the null string */
974 if (c > 1) {
975 char *vp = kmalloc(c, GFP_ATOMIC);
976 if (!vp)
977 return -ENOMEM;
978 memcpy(vp, start, c);
979 *vars = vp;
980 *count = c;
981 } else {
982 *vars = NULL;
983 *count = 0;
984 }
985
986 return 0;
987}
988
989/* Parse SROM and create name=value pairs. 'srom' points to
990 * the SROM word array. 'off' specifies the offset of the
991 * first word 'srom' points to, which should be either 0 or
992 * SROM3_SWRG_OFF (full SROM or software region).
993 */
994
995static uint mask_shift(u16 mask)
996{
997 uint i;
998 for (i = 0; i < (sizeof(mask) << 3); i++) {
999 if (mask & (1 << i))
1000 return i;
1001 }
1002 return 0;
1003}
1004
1005static uint mask_width(u16 mask)
1006{
1007 int i;
1008 for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
1009 if (mask & (1 << i))
1010 return (uint) (i - mask_shift(mask) + 1);
1011 }
1012 return 0;
1013}
1014
1015static void
1016_initvars_srom_pci(u8 sromrev, u16 *srom, uint off, struct brcms_varbuf *b)
1017{
1018 u16 w;
1019 u32 val;
1020 const struct brcms_sromvar *srv;
1021 uint width;
1022 uint flags;
1023 u32 sr = (1 << sromrev);
1024
1025 varbuf_append(b, "sromrev=%d", sromrev);
1026
1027 for (srv = pci_sromvars; srv->name != NULL; srv++) {
1028 const char *name;
1029
1030 if ((srv->revmask & sr) == 0)
1031 continue;
1032
1033 if (srv->off < off)
1034 continue;
1035
1036 flags = srv->flags;
1037 name = srv->name;
1038
1039 /* This entry is for mfgc only. Don't generate param for it, */
1040 if (flags & SRFL_NOVAR)
1041 continue;
1042
1043 if (flags & SRFL_ETHADDR) {
1044 u8 ea[ETH_ALEN];
1045
1046 ea[0] = (srom[srv->off - off] >> 8) & 0xff;
1047 ea[1] = srom[srv->off - off] & 0xff;
1048 ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
1049 ea[3] = srom[srv->off + 1 - off] & 0xff;
1050 ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
1051 ea[5] = srom[srv->off + 2 - off] & 0xff;
1052
1053 varbuf_append(b, "%s=%pM", name, ea);
1054 } else {
1055 w = srom[srv->off - off];
1056 val = (w & srv->mask) >> mask_shift(srv->mask);
1057 width = mask_width(srv->mask);
1058
1059 while (srv->flags & SRFL_MORE) {
1060 srv++;
1061 if (srv->off == 0 || srv->off < off)
1062 continue;
1063
1064 w = srom[srv->off - off];
1065 val +=
1066 ((w & srv->mask) >> mask_shift(srv->
1067 mask)) <<
1068 width;
1069 width += mask_width(srv->mask);
1070 }
1071
1072 if ((flags & SRFL_NOFFS)
1073 && ((int)val == (1 << width) - 1))
1074 continue;
1075
1076 if (flags & SRFL_CCODE) {
1077 if (val == 0)
1078 varbuf_append(b, "ccode=");
1079 else
1080 varbuf_append(b, "ccode=%c%c",
1081 (val >> 8), (val & 0xff));
1082 }
1083 /* LED Powersave duty cycle has to be scaled:
1084 *(oncount >> 24) (offcount >> 8)
1085 */
1086 else if (flags & SRFL_LEDDC) {
1087 u32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */
1088 (((val & 0xff)) << 8); /* offcount */
1089 varbuf_append(b, "leddc=%d", w32);
1090 } else if (flags & SRFL_PRHEX)
1091 varbuf_append(b, "%s=0x%x", name, val);
1092 else if ((flags & SRFL_PRSIGN)
1093 && (val & (1 << (width - 1))))
1094 varbuf_append(b, "%s=%d", name,
1095 (int)(val | (~0 << width)));
1096 else
1097 varbuf_append(b, "%s=%u", name, val);
1098 }
1099 }
1100
1101 if (sromrev >= 4) {
1102 /* Do per-path variables */
1103 uint p, pb, psz;
1104
1105 if (sromrev >= 8) {
1106 pb = SROM8_PATH0;
1107 psz = SROM8_PATH1 - SROM8_PATH0;
1108 } else {
1109 pb = SROM4_PATH0;
1110 psz = SROM4_PATH1 - SROM4_PATH0;
1111 }
1112
1113 for (p = 0; p < MAX_PATH_SROM; p++) {
1114 for (srv = perpath_pci_sromvars; srv->name != NULL;
1115 srv++) {
1116 if ((srv->revmask & sr) == 0)
1117 continue;
1118
1119 if (pb + srv->off < off)
1120 continue;
1121
1122 /* This entry is for mfgc only. Don't generate param for it, */
1123 if (srv->flags & SRFL_NOVAR)
1124 continue;
1125
1126 w = srom[pb + srv->off - off];
1127 val = (w & srv->mask) >> mask_shift(srv->mask);
1128 width = mask_width(srv->mask);
1129
1130 /* Cheating: no per-path var is more than 1 word */
1131
1132 if ((srv->flags & SRFL_NOFFS)
1133 && ((int)val == (1 << width) - 1))
1134 continue;
1135
1136 if (srv->flags & SRFL_PRHEX)
1137 varbuf_append(b, "%s%d=0x%x", srv->name,
1138 p, val);
1139 else
1140 varbuf_append(b, "%s%d=%d", srv->name,
1141 p, val);
1142 }
1143 pb += psz;
1144 }
1145 }
1146}
1147
1148/*
1149 * Initialize nonvolatile variable table from sprom.
1150 * Return 0 on success, nonzero on error.
1151 */
1152static int initvars_srom_pci(struct si_pub *sih, void *curmap, char **vars,
1153 uint *count)
1154{
1155 u16 *srom, *sromwindow;
1156 u8 sromrev = 0;
1157 u32 sr;
1158 struct brcms_varbuf b;
1159 char *vp, *base = NULL;
1160 int err = 0;
1161
1162 /*
1163 * Apply CRC over SROM content regardless SROM is present or not.
1164 */
1165 srom = kmalloc(SROM_MAX, GFP_ATOMIC);
1166 if (!srom)
1167 return -ENOMEM;
1168
1169 sromwindow = (u16 *) SROM_OFFSET(sih);
1170 if (ai_is_sprom_available(sih)) {
1171 err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS,
1172 true);
1173
1174 if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
1175 (((sih->buscoretype == PCIE_CORE_ID)
1176 && (sih->buscorerev >= 6))
1177 || ((sih->buscoretype == PCI_CORE_ID)
1178 && (sih->buscorerev >= 0xe)))) {
1179 /* sromrev >= 4, read more */
1180 err = sprom_read_pci(sih, sromwindow, 0, srom,
1181 SROM4_WORDS, true);
1182 sromrev = srom[SROM4_CRCREV] & 0xff;
1183 } else if (err == 0) {
1184 /* srom is good and is rev < 4 */
1185 /* top word of sprom contains version and crc8 */
1186 sromrev = srom[SROM_CRCREV] & 0xff;
1187 /* bcm4401 sroms misprogrammed */
1188 if (sromrev == 0x10)
1189 sromrev = 1;
1190 }
1191 }
1192#if defined(BCMNVRAMR)
1193 /* Use OTP if SPROM not available */
1194 else {
1195 err = otp_read_pci(sih, srom, SROM_MAX);
1196 if (err == 0)
1197 /* OTP only contain SROM rev8/rev9 for now */
1198 sromrev = srom[SROM4_CRCREV] & 0xff;
1199 }
1200#else
1201 else
1202 err = -ENODEV;
1203#endif
1204
1205 if (!err) {
1206 /* Bitmask for the sromrev */
1207 sr = 1 << sromrev;
1208
1209 /* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */
1210 if ((sr & 0x33e) == 0) {
1211 err = -EINVAL;
1212 goto errout;
1213 }
1214
1215 base = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
1216 if (!base) {
1217 err = -ENOMEM;
1218 goto errout;
1219 }
1220
1221 varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
1222
1223 /* parse SROM into name=value pairs. */
1224 _initvars_srom_pci(sromrev, srom, 0, &b);
1225
1226 /* final nullbyte terminator */
1227 vp = b.buf;
1228 *vp++ = '\0';
1229
1230 err = initvars_table(base, vp, vars, count);
1231 kfree(base);
1232 }
1233
1234errout:
1235 kfree(srom);
1236 return err;
1237}
diff --git a/drivers/staging/brcm80211/brcmsmac/srom.h b/drivers/staging/brcm80211/brcmsmac/srom.h
new file mode 100644
index 00000000000..efc4d1edd86
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/srom.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SROM_H_
18#define _BRCM_SROM_H_
19
20#include "types.h"
21
22/* Prototypes */
23extern int srom_var_init(struct si_pub *sih, uint bus, void *curmap,
24 char **vars, uint *count);
25
26extern int srom_read(struct si_pub *sih, uint bus, void *curmap,
27 uint byteoff, uint nbytes, u16 *buf, bool check_crc);
28
29/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP
30 * and extract from it into name=value pairs
31 */
32extern int srom_parsecis(u8 **pcis, uint ciscnt,
33 char **vars, uint *count);
34#endif /* _BRCM_SROM_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/stf.c b/drivers/staging/brcm80211/brcmsmac/stf.c
new file mode 100644
index 00000000000..a55ff010178
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/stf.c
@@ -0,0 +1,477 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <net/mac80211.h>
18
19#include "types.h"
20#include "d11.h"
21#include "rate.h"
22#include "phy/phy_hal.h"
23#include "channel.h"
24#include "main.h"
25#include "bmac.h"
26#include "stf.h"
27
28#define MIN_SPATIAL_EXPANSION 0
29#define MAX_SPATIAL_EXPANSION 1
30
31#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
32 NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
33
34static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val);
35static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, u8 val);
36static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val);
37static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val);
38
39static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
40static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
41 ratespec_t rspec);
42
43#define NSTS_1 1
44#define NSTS_2 2
45#define NSTS_3 3
46#define NSTS_4 4
47const u8 txcore_default[5] = {
48 (0), /* bitmap of the core enabled */
49 (0x01), /* For Nsts = 1, enable core 1 */
50 (0x03), /* For Nsts = 2, enable core 1 & 2 */
51 (0x07), /* For Nsts = 3, enable core 1, 2 & 3 */
52 (0x0f) /* For Nsts = 4, enable all cores */
53};
54
55static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val)
56{
57 /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
58 if (BRCMS_STF_SS_STBC_RX(wlc)) {
59 if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
60 return;
61 }
62
63 wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_RX_STBC;
64 wlc->ht_cap.cap_info |= (val << IEEE80211_HT_CAP_RX_STBC_SHIFT);
65
66 if (wlc->pub->up) {
67 brcms_c_update_beacon(wlc);
68 brcms_c_update_probe_resp(wlc, true);
69 }
70}
71
72/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */
73void brcms_c_tempsense_upd(struct brcms_c_info *wlc)
74{
75 struct brcms_phy_pub *pi = wlc->band->pi;
76 uint active_chains, txchain;
77
78 /* Check if the chip is too hot. Disable one Tx chain, if it is */
79 /* high 4 bits are for Rx chain, low 4 bits are for Tx chain */
80 active_chains = wlc_phy_stf_chain_active_get(pi);
81 txchain = active_chains & 0xf;
82
83 if (wlc->stf->txchain == wlc->stf->hw_txchain) {
84 if (txchain && (txchain < wlc->stf->hw_txchain)) {
85 /* turn off 1 tx chain */
86 brcms_c_stf_txchain_set(wlc, txchain, true);
87 }
88 } else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
89 if (txchain == wlc->stf->hw_txchain) {
90 /* turn back on txchain */
91 brcms_c_stf_txchain_set(wlc, txchain, true);
92 }
93 }
94}
95
96void
97brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
98 chanspec_t chanspec)
99{
100 struct tx_power power;
101 u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
102
103 /* Clear previous settings */
104 *ss_algo_channel = 0;
105
106 if (!wlc->pub->up) {
107 *ss_algo_channel = (u16) -1;
108 return;
109 }
110
111 wlc_phy_txpower_get_current(wlc->band->pi, &power,
112 CHSPEC_CHANNEL(chanspec));
113
114 siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
115 WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
116 cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
117 WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
118 stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
119 WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
120
121 /* criteria to choose stf mode */
122
123 /* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs
124 * on both chains
125 */
126 if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
127 setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
128 else
129 setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
130
131 /* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check
132 * so cannot be default mode of operation. One of SISO, CDD have to be set
133 */
134 if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
135 setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
136}
137
138static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val)
139{
140 if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) {
141 return false;
142 }
143
144 if ((int_val == ON) && (wlc->stf->txstreams == 1))
145 return false;
146
147 if ((int_val == OFF) || (wlc->stf->txstreams == 1)
148 || !BRCMS_STBC_CAP_PHY(wlc))
149 wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
150 else
151 wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC;
152
153 wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
154 wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
155
156 return true;
157}
158
159bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
160{
161 if ((int_val != HT_CAP_RX_STBC_NO)
162 && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) {
163 return false;
164 }
165
166 if (BRCMS_STF_SS_STBC_RX(wlc)) {
167 if ((int_val != HT_CAP_RX_STBC_NO)
168 && (wlc->stf->rxstreams == 1))
169 return false;
170 }
171
172 brcms_c_stf_stbc_rx_ht_update(wlc, int_val);
173 return true;
174}
175
176static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
177 u8 core_mask)
178{
179 BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
180 wlc->pub->unit, Nsts, core_mask);
181
182 if (BRCMS_BITSCNT(core_mask) > wlc->stf->txstreams) {
183 core_mask = 0;
184 }
185
186 if ((BRCMS_BITSCNT(core_mask) == wlc->stf->txstreams) &&
187 ((core_mask & ~wlc->stf->txchain)
188 || !(core_mask & wlc->stf->txchain))) {
189 core_mask = wlc->stf->txchain;
190 }
191
192 wlc->stf->txcore[Nsts] = core_mask;
193 /* Nsts = 1..4, txcore index = 1..4 */
194 if (Nsts == 1) {
195 /* Needs to update beacon and ucode generated response
196 * frames when 1 stream core map changed
197 */
198 wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
199 brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
200 if (wlc->clk) {
201 brcms_c_suspend_mac_and_wait(wlc);
202 brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
203 brcms_c_enable_mac(wlc);
204 }
205 }
206
207 return 0;
208}
209
210static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
211{
212 int i;
213 u8 core_mask = 0;
214
215 BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
216
217 wlc->stf->spatial_policy = (s8) val;
218 for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
219 core_mask = (val == MAX_SPATIAL_EXPANSION) ?
220 wlc->stf->txchain : txcore_default[i];
221 brcms_c_stf_txcore_set(wlc, (u8) i, core_mask);
222 }
223 return 0;
224}
225
226int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
227{
228 u8 txchain = (u8) int_val;
229 u8 txstreams;
230 uint i;
231
232 if (wlc->stf->txchain == txchain)
233 return 0;
234
235 if ((txchain & ~wlc->stf->hw_txchain)
236 || !(txchain & wlc->stf->hw_txchain))
237 return -EINVAL;
238
239 /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */
240 txstreams = (u8) BRCMS_BITSCNT(txchain);
241 if (txstreams > MAX_STREAMS_SUPPORTED)
242 return -EINVAL;
243
244 if (txstreams == 1) {
245 for (i = 0; i < NBANDS(wlc); i++)
246 if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) !=
247 PHY_TXC1_MODE_SISO)
248 || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) !=
249 PHY_TXC1_MODE_SISO)) {
250 if (!force)
251 return -EBADE;
252
253 /* over-write the override rspec */
254 if (RSPEC_STF(wlc->bandstate[i]->rspec_override)
255 != PHY_TXC1_MODE_SISO) {
256 wlc->bandstate[i]->rspec_override = 0;
257 wiphy_err(wlc->wiphy, "%s(): temp "
258 "sense override non-SISO "
259 "rspec_override\n",
260 __func__);
261 }
262 if (RSPEC_STF
263 (wlc->bandstate[i]->mrspec_override) !=
264 PHY_TXC1_MODE_SISO) {
265 wlc->bandstate[i]->mrspec_override = 0;
266 wiphy_err(wlc->wiphy, "%s(): temp "
267 "sense override non-SISO "
268 "mrspec_override\n",
269 __func__);
270 }
271 }
272 }
273
274 wlc->stf->txchain = txchain;
275 wlc->stf->txstreams = txstreams;
276 brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
277 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
278 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
279 wlc->stf->txant =
280 (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
281 _brcms_c_stf_phy_txant_upd(wlc);
282
283 wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
284 wlc->stf->rxchain);
285
286 for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
287 brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
288
289 return 0;
290}
291
292/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */
293int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
294{
295 int ret_code = 0;
296 u8 prev_stf_ss;
297 u8 upd_stf_ss;
298
299 prev_stf_ss = wlc->stf->ss_opmode;
300
301 /* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */
302 if (BRCMS_STBC_CAP_PHY(wlc) &&
303 wlc->stf->ss_algosel_auto
304 && (wlc->stf->ss_algo_channel != (u16) -1)) {
305 upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1)
306 || isset(&wlc->stf->ss_algo_channel,
307 PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO
308 : PHY_TXC1_MODE_CDD;
309 } else {
310 if (wlc->band != band)
311 return ret_code;
312 upd_stf_ss = (wlc->stf->no_cddstbc
313 || (wlc->stf->txstreams ==
314 1)) ? PHY_TXC1_MODE_SISO : band->
315 band_stf_ss_mode;
316 }
317 if (prev_stf_ss != upd_stf_ss) {
318 wlc->stf->ss_opmode = upd_stf_ss;
319 brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
320 }
321
322 return ret_code;
323}
324
325int brcms_c_stf_attach(struct brcms_c_info *wlc)
326{
327 wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
328 wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
329
330 if (BRCMS_ISNPHY(wlc->band) &&
331 (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
332 wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
333 PHY_TXC1_MODE_CDD;
334 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
335 brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
336
337 brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
338 wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
339 wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
340
341 if (BRCMS_STBC_CAP_PHY(wlc)) {
342 wlc->stf->ss_algosel_auto = true;
343 wlc->stf->ss_algo_channel = (u16) -1; /* Init the default value */
344 }
345 return 0;
346}
347
348void brcms_c_stf_detach(struct brcms_c_info *wlc)
349{
350}
351
352/*
353 * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain
354 * change
355 *
356 * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
357 * achieve various tx/rx antenna selection schemes
358 *
359 * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx)
360 * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and
361 * do tx-antenna selection for SISO transmissions
362 * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and
363 * do tx-antenna selection for SISO transmissions
364 * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active
365*/
366static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
367{
368 s8 txant;
369
370 txant = (s8) wlc->stf->txant;
371 if (BRCMS_PHY_11N_CAP(wlc->band)) {
372 if (txant == ANT_TX_FORCE_0) {
373 wlc->stf->phytxant = PHY_TXC_ANT_0;
374 } else if (txant == ANT_TX_FORCE_1) {
375 wlc->stf->phytxant = PHY_TXC_ANT_1;
376
377 if (BRCMS_ISNPHY(wlc->band) &&
378 NREV_GE(wlc->band->phyrev, 3)
379 && NREV_LT(wlc->band->phyrev, 7)) {
380 wlc->stf->phytxant = PHY_TXC_ANT_2;
381 }
382 } else {
383 if (BRCMS_ISLCNPHY(wlc->band) ||
384 BRCMS_ISSSLPNPHY(wlc->band))
385 wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
386 else {
387 /* catch out of sync wlc->stf->txcore */
388 WARN_ON(wlc->stf->txchain <= 0);
389 wlc->stf->phytxant =
390 wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
391 }
392 }
393 } else {
394 if (txant == ANT_TX_FORCE_0)
395 wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
396 else if (txant == ANT_TX_FORCE_1)
397 wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
398 else
399 wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
400 }
401
402 brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
403}
404
405void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
406{
407 _brcms_c_stf_phy_txant_upd(wlc);
408}
409
410void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
411{
412 /* get available rx/tx chains */
413 wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain");
414 wlc->stf->hw_rxchain = (u8) getintvar(wlc->pub->vars, "rxchain");
415
416 /* these parameter are intended to be used for all PHY types */
417 if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
418 if (BRCMS_ISNPHY(wlc->band)) {
419 wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
420 } else {
421 wlc->stf->hw_txchain = TXCHAIN_DEF;
422 }
423 }
424
425 wlc->stf->txchain = wlc->stf->hw_txchain;
426 wlc->stf->txstreams = (u8) BRCMS_BITSCNT(wlc->stf->hw_txchain);
427
428 if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
429 if (BRCMS_ISNPHY(wlc->band)) {
430 wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
431 } else {
432 wlc->stf->hw_rxchain = RXCHAIN_DEF;
433 }
434 }
435
436 wlc->stf->rxchain = wlc->stf->hw_rxchain;
437 wlc->stf->rxstreams = (u8) BRCMS_BITSCNT(wlc->stf->hw_rxchain);
438
439 /* initialize the txcore table */
440 memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
441
442 /* default spatial_policy */
443 wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
444 brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
445}
446
447static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
448 ratespec_t rspec)
449{
450 u16 phytxant = wlc->stf->phytxant;
451
452 if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) {
453 phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
454 } else if (wlc->stf->txant == ANT_TX_DEF)
455 phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
456 phytxant &= PHY_TXC_ANT_MASK;
457 return phytxant;
458}
459
460u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, ratespec_t rspec)
461{
462 return _brcms_c_stf_phytxchain_sel(wlc, rspec);
463}
464
465u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, ratespec_t rspec)
466{
467 u16 phytxant = wlc->stf->phytxant;
468 u16 mask = PHY_TXC_ANT_MASK;
469
470 /* for non-siso rates or default setting, use the available chains */
471 if (BRCMS_ISNPHY(wlc->band)) {
472 phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec);
473 mask = PHY_TXC_HTANT_MASK;
474 }
475 phytxant |= phytxant & mask;
476 return phytxant;
477}
diff --git a/drivers/staging/brcm80211/brcmsmac/stf.h b/drivers/staging/brcm80211/brcmsmac/stf.h
new file mode 100644
index 00000000000..06c2a399649
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/stf.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_STF_H_
18#define _BRCM_STF_H_
19
20#include "types.h"
21
22extern int brcms_c_stf_attach(struct brcms_c_info *wlc);
23extern void brcms_c_stf_detach(struct brcms_c_info *wlc);
24
25extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
26extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
27 u16 *ss_algo_channel,
28 chanspec_t chanspec);
29extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc,
30 struct brcms_band *band);
31extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
32extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val,
33 bool force);
34extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
35extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
36extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc);
37extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
38 ratespec_t rspec);
39extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc,
40 ratespec_t rspec);
41
42#endif /* _BRCM_STF_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/types.h b/drivers/staging/brcm80211/brcmsmac/types.h
new file mode 100644
index 00000000000..823b5e4672e
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/types.h
@@ -0,0 +1,399 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_TYPES_H_
18#define _BRCM_TYPES_H_
19
20#include <linux/types.h>
21#include <linux/io.h>
22
23/* Bus types */
24#define SI_BUS 0 /* SOC Interconnect */
25#define PCI_BUS 1 /* PCI target */
26#define SDIO_BUS 3 /* SDIO target */
27#define JTAG_BUS 4 /* JTAG */
28#define USB_BUS 5 /* USB (does not support R/W REG) */
29#define SPI_BUS 6 /* gSPI target */
30#define RPC_BUS 7 /* RPC target */
31
32#define WL_CHAN_FREQ_RANGE_2G 0
33#define WL_CHAN_FREQ_RANGE_5GL 1
34#define WL_CHAN_FREQ_RANGE_5GM 2
35#define WL_CHAN_FREQ_RANGE_5GH 3
36
37#define MAX_DMA_SEGS 4
38
39/* boardflags */
40#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */
41#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */
42#define BFL_FEM 0x00000800 /* Board supports the Front End Module */
43#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */
44#define BFL_NOPA 0x00010000 /* Board has no PA */
45#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */
46#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */
47#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */
48#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */
49#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */
50
51/* boardflags2 */
52#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */
53#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */
54#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */
55#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */
56#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */
57#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */
58#define BFL2_LEGACY 0x00000080
59#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */
60#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */
61#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */
62#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */
63#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */
64#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */
65#define BFL2_IPALVLSHIFT_3P3 0x00020000
66#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */
67#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio "ON"
68 * Most drivers will turn it off without this flag
69 * to save power.
70 */
71
72/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
73#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
74#define BOARD_GPIO_12 0x1000 /* gpio 12 */
75#define BOARD_GPIO_13 0x2000 /* gpio 13 */
76
77/* **** Core type/rev defaults **** */
78#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27
79 * also need to update wlc.h MAXCOREREV
80 */
81
82#define NCONF 0x000001ff /* Supported nphy revs:
83 * 0 4321a0
84 * 1 4321a1
85 * 2 4321b0/b1/c0/c1
86 * 3 4322a0
87 * 4 4322a1
88 * 5 4716a0
89 * 6 43222a0, 43224a0
90 * 7 43226a0
91 * 8 5357a0, 43236a0
92 */
93
94#define LCNCONF 0x00000007 /* Supported lcnphy revs:
95 * 0 4313a0, 4336a0, 4330a0
96 * 1
97 * 2 4330a0
98 */
99
100#define SSLPNCONF 0x0000000f /* Supported sslpnphy revs:
101 * 0 4329a0/k0
102 * 1 4329b0/4329C0
103 * 2 4319a0
104 * 3 5356a0
105 */
106
107/********************************************************************
108 * Phy/Core Configuration. Defines macros to to check core phy/rev *
109 * compile-time configuration. Defines default core support. *
110 * ******************************************************************
111 */
112
113/* Basic macros to check a configuration bitmask */
114
115#define CONF_HAS(config, val) ((config) & (1 << (val)))
116#define CONF_MSK(config, mask) ((config) & (mask))
117#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low)))
118#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
119
120#define CONF_IS(config, val) ((config) == (1 << (val)))
121#define CONF_GE(config, val) ((config) & (0-(1 << (val))))
122#define CONF_GT(config, val) ((config) & (0-2*(1 << (val))))
123#define CONF_LT(config, val) ((config) & ((1 << (val))-1))
124#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1))
125
126/* Wrappers for some of the above, specific to config constants */
127
128#define NCONF_HAS(val) CONF_HAS(NCONF, val)
129#define NCONF_MSK(mask) CONF_MSK(NCONF, mask)
130#define NCONF_IS(val) CONF_IS(NCONF, val)
131#define NCONF_GE(val) CONF_GE(NCONF, val)
132#define NCONF_GT(val) CONF_GT(NCONF, val)
133#define NCONF_LT(val) CONF_LT(NCONF, val)
134#define NCONF_LE(val) CONF_LE(NCONF, val)
135
136#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val)
137#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask)
138#define LCNCONF_IS(val) CONF_IS(LCNCONF, val)
139#define LCNCONF_GE(val) CONF_GE(LCNCONF, val)
140#define LCNCONF_GT(val) CONF_GT(LCNCONF, val)
141#define LCNCONF_LT(val) CONF_LT(LCNCONF, val)
142#define LCNCONF_LE(val) CONF_LE(LCNCONF, val)
143
144#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
145#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
146#define D11CONF_IS(val) CONF_IS(D11CONF, val)
147#define D11CONF_GE(val) CONF_GE(D11CONF, val)
148#define D11CONF_GT(val) CONF_GT(D11CONF, val)
149#define D11CONF_LT(val) CONF_LT(D11CONF, val)
150#define D11CONF_LE(val) CONF_LE(D11CONF, val)
151
152#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
153#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val)
154
155#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
156#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
157#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
158#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
159#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
160
161#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
162#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
163#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
164#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
165#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
166
167#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
168#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
169#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
170#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
171#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
172
173#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
174
175/* Finally, early-exit from switch case if anyone wants it... */
176
177#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break
178#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break
179
180/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
181
182#define _PHYCONF_N (1 << PHY_TYPE_N)
183#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
184#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
185
186#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
187
188/* Utility macro to identify 802.11n (HT) capable PHYs */
189#define PHYTYPE_11N_CAP(phytype) \
190 (PHYTYPE_IS(phytype, PHY_TYPE_N) || \
191 PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
192 PHYTYPE_IS(phytype, PHY_TYPE_SSN))
193
194/* Last but not least: shorter wlc-specific var checks */
195#define BRCMS_ISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
196#define BRCMS_ISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
197#define BRCMS_ISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
198
199#define BRCMS_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype)
200
201/**********************************************************************
202 * ------------- End of Core phy/rev configuration. ----------------- *
203 * ********************************************************************
204 */
205
206/*************************************************
207 * Defaults for tunables (e.g. sizing constants)
208 *
209 * For each new tunable, add a member to the end
210 * of struct brcms_tunables in brcms_c_pub.h to enable
211 * runtime checks of tunable values. (Directly
212 * using the macros in code invalidates ROM code)
213 *
214 * ***********************************************
215 */
216#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */
217#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */
218#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */
219#define MAXSCB 32 /* Maximum SCBs in cache for STA */
220#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */
221
222/* Count of packet callback structures. either of following
223 * 1. Set to the number of SCBs since a STA
224 * can queue up a rate callback for each IBSS STA it knows about, and an AP can
225 * queue up an "are you there?" Null Data callback for each associated STA
226 * 2. controlled by tunable config file
227 */
228#define MAXPKTCB MAXSCB /* Max number of packet callbacks */
229
230/* NetBSD also needs to keep track of this */
231
232/* Number of BSS handled in ucode bcn/prb */
233#define BRCMS_MAX_UCODE_BSS (16)
234/* Number of BSS handled in sw bcn/prb */
235#define BRCMS_MAX_UCODE_BSS4 (4)
236/* max # BSS configs */
237#define BRCMS_MAXBSSCFG (1)
238/* max # available networks */
239#define MAXBSS 64
240/* data msg txq hiwat mark */
241#define BRCMS_DATAHIWAT 50
242#define BRCMS_AMPDUDATAHIWAT 255
243
244/* bounded rx loops */
245#define RXBND 8 /* max # frames to process in brcms_c_recv() */
246#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */
247
248#define BAND_5G(bt) ((bt) == BRCM_BAND_5G)
249#define BAND_2G(bt) ((bt) == BRCM_BAND_2G)
250
251#define BCMMSG(dev, fmt, args...) \
252do { \
253 if (brcm_msg_level & LOG_TRACE_VAL) \
254 wiphy_err(dev, "%s: " fmt, __func__, ##args); \
255} while (0)
256
257#define WL_ERROR_ON() (brcm_msg_level & LOG_ERROR_VAL)
258
259/* register access macros */
260#ifndef __BIG_ENDIAN
261#ifndef __mips__
262#define R_REG(r) \
263 ({\
264 sizeof(*(r)) == sizeof(u8) ? \
265 readb((u8 *)(r)) : \
266 sizeof(*(r)) == sizeof(u16) ? readw((u16 *)(r)) : \
267 readl((u32 *)(r)); \
268 })
269#else /* __mips__ */
270#define R_REG(r) \
271 ({ \
272 __typeof(*(r)) __osl_v; \
273 __asm__ __volatile__("sync"); \
274 switch (sizeof(*(r))) { \
275 case sizeof(u8): \
276 __osl_v = readb((u8 *)(r)); \
277 break; \
278 case sizeof(u16): \
279 __osl_v = readw((u16 *)(r)); \
280 break; \
281 case sizeof(u32): \
282 __osl_v = \
283 readl((u32 *)(r)); \
284 break; \
285 } \
286 __asm__ __volatile__("sync"); \
287 __osl_v; \
288 })
289#endif /* __mips__ */
290
291#define W_REG(r, v) do { \
292 switch (sizeof(*(r))) { \
293 case sizeof(u8): \
294 writeb((u8)(v), (u8 *)(r)); break; \
295 case sizeof(u16): \
296 writew((u16)(v), (u16 *)(r)); break; \
297 case sizeof(u32): \
298 writel((u32)(v), (u32 *)(r)); break; \
299 }; \
300 } while (0)
301#else /* __BIG_ENDIAN */
302#define R_REG(r) \
303 ({ \
304 __typeof(*(r)) __osl_v; \
305 switch (sizeof(*(r))) { \
306 case sizeof(u8): \
307 __osl_v = \
308 readb((u8 *)((r)^3)); \
309 break; \
310 case sizeof(u16): \
311 __osl_v = \
312 readw((u16 *)((r)^2)); \
313 break; \
314 case sizeof(u32): \
315 __osl_v = readl((u32 *)(r)); \
316 break; \
317 } \
318 __osl_v; \
319 })
320
321#define W_REG(r, v) do { \
322 switch (sizeof(*(r))) { \
323 case sizeof(u8): \
324 writeb((u8)(v), \
325 (u8 *)((r)^3)); break; \
326 case sizeof(u16): \
327 writew((u16)(v), \
328 (u16 *)((r)^2)); break; \
329 case sizeof(u32): \
330 writel((u32)(v), \
331 (u32 *)(r)); break; \
332 } \
333 } while (0)
334#endif /* __BIG_ENDIAN */
335
336#ifdef __mips__
337/*
338 * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
339 * transactions. As a fix, a read after write is performed on certain places
340 * in the code. Older chips and the newer 5357 family don't require this fix.
341 */
342#define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); })
343#else
344#define W_REG_FLUSH(r, v) W_REG((r), (v))
345#endif /* __mips__ */
346
347#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
348#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
349
350#define SET_REG(r, mask, val) \
351 W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
352
353/* multi-bool data type: set of bools, mbool is true if any is set */
354typedef u32 mbool;
355#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */
356#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */
357#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* true if one bool is set */
358#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
359
360/* forward declarations */
361struct wiphy;
362struct ieee80211_sta;
363struct ieee80211_tx_queue_params;
364struct brcms_info;
365struct brcms_c_info;
366struct brcms_hardware;
367struct brcms_c_if;
368struct brcmu_iovar;
369struct brcmu_strbuf;
370struct brcms_txq_info;
371struct brcms_band;
372struct dma_pub;
373struct si_pub;
374struct tx_status;
375struct d11rxhdr;
376struct brcms_d11rxhdr;
377struct txpwr_limits;
378struct brcms_phy;
379
380typedef volatile struct intctrlregs intctrlregs_t;
381typedef volatile struct pio2regs pio2regs_t;
382typedef volatile struct pio2regp pio2regp_t;
383typedef volatile struct pio4regs pio4regs_t;
384typedef volatile struct pio4regp pio4regp_t;
385typedef volatile struct fifo64 fifo64_t;
386typedef volatile struct d11regs d11regs_t;
387typedef volatile struct dma32diag dma32diag_t;
388typedef volatile struct dma64regs dma64regs_t;
389typedef struct brcms_rateset wlc_rateset_t;
390typedef u32 ratespec_t;
391typedef struct chanvec chanvec_t;
392typedef s32 fixed;
393typedef struct _cs32 cs32;
394typedef volatile union pmqreg pmqreg_t;
395
396/* brcm_msg_level is a bit vector with defs in defs.h */
397extern u32 brcm_msg_level;
398
399#endif /* _BRCM_TYPES_H_ */
diff --git a/drivers/staging/brcm80211/brcmsmac/ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/ucode_loader.c
new file mode 100644
index 00000000000..bf733fb18ce
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/ucode_loader.c
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <defs.h>
18#include "types.h"
19#include <ucode_loader.h>
20
21enum {
22 D11UCODE_NAMETAG_START = 0,
23 D11LCN0BSINITVALS24,
24 D11LCN0INITVALS24,
25 D11LCN1BSINITVALS24,
26 D11LCN1INITVALS24,
27 D11LCN2BSINITVALS24,
28 D11LCN2INITVALS24,
29 D11N0ABSINITVALS16,
30 D11N0BSINITVALS16,
31 D11N0INITVALS16,
32 D11UCODE_OVERSIGHT16_MIMO,
33 D11UCODE_OVERSIGHT16_MIMOSZ,
34 D11UCODE_OVERSIGHT24_LCN,
35 D11UCODE_OVERSIGHT24_LCNSZ,
36 D11UCODE_OVERSIGHT_BOMMAJOR,
37 D11UCODE_OVERSIGHT_BOMMINOR
38};
39
40struct d11init *d11lcn0bsinitvals24;
41struct d11init *d11lcn0initvals24;
42struct d11init *d11lcn1bsinitvals24;
43struct d11init *d11lcn1initvals24;
44struct d11init *d11lcn2bsinitvals24;
45struct d11init *d11lcn2initvals24;
46struct d11init *d11n0absinitvals16;
47struct d11init *d11n0bsinitvals16;
48struct d11init *d11n0initvals16;
49u32 *bcm43xx_16_mimo;
50u32 bcm43xx_16_mimosz;
51u32 *bcm43xx_24_lcn;
52u32 bcm43xx_24_lcnsz;
53u32 *bcm43xx_bommajor;
54u32 *bcm43xx_bomminor;
55
56int brcms_ucode_data_init(struct brcms_info *wl)
57{
58 int rc;
59 rc = brcms_check_firmwares(wl);
60
61 rc = rc < 0 ? rc :
62 brcms_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24,
63 D11LCN0BSINITVALS24);
64 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn0initvals24,
65 D11LCN0INITVALS24);
66 rc = rc < 0 ? rc :
67 brcms_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24,
68 D11LCN1BSINITVALS24);
69 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn1initvals24,
70 D11LCN1INITVALS24);
71 rc = rc < 0 ? rc :
72 brcms_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24,
73 D11LCN2BSINITVALS24);
74 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn2initvals24,
75 D11LCN2INITVALS24);
76 rc = rc < 0 ? rc :
77 brcms_ucode_init_buf(wl, (void **)&d11n0absinitvals16,
78 D11N0ABSINITVALS16);
79 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11n0bsinitvals16,
80 D11N0BSINITVALS16);
81 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11n0initvals16,
82 D11N0INITVALS16);
83 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo,
84 D11UCODE_OVERSIGHT16_MIMO);
85 rc = rc < 0 ? rc : brcms_ucode_init_uint(wl, &bcm43xx_16_mimosz,
86 D11UCODE_OVERSIGHT16_MIMOSZ);
87 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn,
88 D11UCODE_OVERSIGHT24_LCN);
89 rc = rc < 0 ? rc : brcms_ucode_init_uint(wl, &bcm43xx_24_lcnsz,
90 D11UCODE_OVERSIGHT24_LCNSZ);
91 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_bommajor,
92 D11UCODE_OVERSIGHT_BOMMAJOR);
93 rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_bomminor,
94 D11UCODE_OVERSIGHT_BOMMINOR);
95 return rc;
96}
97
98void brcms_ucode_data_free(void)
99{
100 brcms_ucode_free_buf((void *)d11lcn0bsinitvals24);
101 brcms_ucode_free_buf((void *)d11lcn0initvals24);
102 brcms_ucode_free_buf((void *)d11lcn1bsinitvals24);
103 brcms_ucode_free_buf((void *)d11lcn1initvals24);
104 brcms_ucode_free_buf((void *)d11lcn2bsinitvals24);
105 brcms_ucode_free_buf((void *)d11lcn2initvals24);
106 brcms_ucode_free_buf((void *)d11n0absinitvals16);
107 brcms_ucode_free_buf((void *)d11n0bsinitvals16);
108 brcms_ucode_free_buf((void *)d11n0initvals16);
109 brcms_ucode_free_buf((void *)bcm43xx_16_mimo);
110 brcms_ucode_free_buf((void *)bcm43xx_24_lcn);
111 brcms_ucode_free_buf((void *)bcm43xx_bommajor);
112 brcms_ucode_free_buf((void *)bcm43xx_bomminor);
113
114 return;
115}
diff --git a/drivers/staging/brcm80211/brcmsmac/ucode_loader.h b/drivers/staging/brcm80211/brcmsmac/ucode_loader.h
new file mode 100644
index 00000000000..ca53deced7b
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmsmac/ucode_loader.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "types.h" /* forward structure declarations */
18
19#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */
20#define MAX_FW_SIZE 150000
21
22#define UCODE_LOADER_API_VER 0
23
24struct d11init {
25 u16 addr;
26 u16 size;
27 u32 value;
28};
29
30extern struct d11init *d11lcn0bsinitvals24;
31extern struct d11init *d11lcn0initvals24;
32extern struct d11init *d11lcn1bsinitvals24;
33extern struct d11init *d11lcn1initvals24;
34extern struct d11init *d11lcn2bsinitvals24;
35extern struct d11init *d11lcn2initvals24;
36extern struct d11init *d11n0absinitvals16;
37extern struct d11init *d11n0bsinitvals16;
38extern struct d11init *d11n0initvals16;
39extern u32 *bcm43xx_16_mimo;
40extern u32 bcm43xx_16_mimosz;
41extern u32 *bcm43xx_24_lcn;
42extern u32 bcm43xx_24_lcnsz;
43
44extern int brcms_ucode_data_init(struct brcms_info *wl);
45extern void brcms_ucode_data_free(void);
46
47extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf,
48 unsigned int idx);
49extern int brcms_ucode_init_uint(struct brcms_info *wl, unsigned *data,
50 unsigned int idx);
51extern void brcms_ucode_free_buf(void *);
52extern int brcms_check_firmwares(struct brcms_info *wl);
diff --git a/drivers/staging/brcm80211/brcmutil/Makefile b/drivers/staging/brcm80211/brcmutil/Makefile
new file mode 100644
index 00000000000..6403423c021
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmutil/Makefile
@@ -0,0 +1,29 @@
1#
2# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
3#
4# Copyright (c) 2011 Broadcom Corporation
5#
6# Permission to use, copy, modify, and/or distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18ccflags-y := \
19 -Idrivers/staging/brcm80211/brcmutil \
20 -Idrivers/staging/brcm80211/include
21
22BRCMUTIL_OFILES := \
23 utils.o \
24 wifi.o
25
26MODULEPFX := brcmutil
27
28obj-$(CONFIG_BRCMUTIL) += $(MODULEPFX).o
29$(MODULEPFX)-objs = $(BRCMUTIL_OFILES)
diff --git a/drivers/staging/brcm80211/brcmutil/utils.c b/drivers/staging/brcm80211/brcmutil/utils.c
new file mode 100644
index 00000000000..37b6b779779
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmutil/utils.c
@@ -0,0 +1,787 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/netdevice.h>
18#include <brcmu_utils.h>
19
20MODULE_AUTHOR("Broadcom Corporation");
21MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
22MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
23MODULE_LICENSE("Dual BSD/GPL");
24
25struct sk_buff *brcmu_pkt_buf_get_skb(uint len)
26{
27 struct sk_buff *skb;
28
29 skb = dev_alloc_skb(len);
30 if (skb) {
31 skb_put(skb, len);
32 skb->priority = 0;
33 }
34
35 return skb;
36}
37EXPORT_SYMBOL(brcmu_pkt_buf_get_skb);
38
39/* Free the driver packet. Free the tag if present */
40void brcmu_pkt_buf_free_skb(struct sk_buff *skb)
41{
42 struct sk_buff *nskb;
43 int nest = 0;
44
45 /* perversion: we use skb->next to chain multi-skb packets */
46 while (skb) {
47 nskb = skb->next;
48 skb->next = NULL;
49
50 if (skb->destructor)
51 /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
52 * destructor exists
53 */
54 dev_kfree_skb_any(skb);
55 else
56 /* can free immediately (even in_irq()) if destructor
57 * does not exist
58 */
59 dev_kfree_skb(skb);
60
61 nest++;
62 skb = nskb;
63 }
64}
65EXPORT_SYMBOL(brcmu_pkt_buf_free_skb);
66
67
68/* copy a buffer into a pkt buffer chain */
69uint brcmu_pktfrombuf(struct sk_buff *p, uint offset, int len,
70 unsigned char *buf)
71{
72 uint n, ret = 0;
73
74 /* skip 'offset' bytes */
75 for (; p && offset; p = p->next) {
76 if (offset < (uint) (p->len))
77 break;
78 offset -= p->len;
79 }
80
81 if (!p)
82 return 0;
83
84 /* copy the data */
85 for (; p && len; p = p->next) {
86 n = min((uint) (p->len) - offset, (uint) len);
87 memcpy(p->data + offset, buf, n);
88 buf += n;
89 len -= n;
90 ret += n;
91 offset = 0;
92 }
93
94 return ret;
95}
96EXPORT_SYMBOL(brcmu_pktfrombuf);
97
98/* return total length of buffer chain */
99uint brcmu_pkttotlen(struct sk_buff *p)
100{
101 uint total;
102
103 total = 0;
104 for (; p; p = p->next)
105 total += p->len;
106 return total;
107}
108EXPORT_SYMBOL(brcmu_pkttotlen);
109
110/*
111 * osl multiple-precedence packet queue
112 * hi_prec is always >= the number of the highest non-empty precedence
113 */
114struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
115 struct sk_buff *p)
116{
117 struct pktq_prec *q;
118
119 if (pktq_full(pq) || pktq_pfull(pq, prec))
120 return NULL;
121
122 q = &pq->q[prec];
123
124 if (q->head)
125 q->tail->prev = p;
126 else
127 q->head = p;
128
129 q->tail = p;
130 q->len++;
131
132 pq->len++;
133
134 if (pq->hi_prec < prec)
135 pq->hi_prec = (u8) prec;
136
137 return p;
138}
139EXPORT_SYMBOL(brcmu_pktq_penq);
140
141struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
142 struct sk_buff *p)
143{
144 struct pktq_prec *q;
145
146 if (pktq_full(pq) || pktq_pfull(pq, prec))
147 return NULL;
148
149 q = &pq->q[prec];
150
151 if (q->head == NULL)
152 q->tail = p;
153
154 p->prev = q->head;
155 q->head = p;
156 q->len++;
157
158 pq->len++;
159
160 if (pq->hi_prec < prec)
161 pq->hi_prec = (u8) prec;
162
163 return p;
164}
165EXPORT_SYMBOL(brcmu_pktq_penq_head);
166
167struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
168{
169 struct pktq_prec *q;
170 struct sk_buff *p;
171
172 q = &pq->q[prec];
173
174 p = q->head;
175 if (p == NULL)
176 return NULL;
177
178 q->head = p->prev;
179 if (q->head == NULL)
180 q->tail = NULL;
181
182 q->len--;
183
184 pq->len--;
185
186 p->prev = NULL;
187
188 return p;
189}
190EXPORT_SYMBOL(brcmu_pktq_pdeq);
191
192struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
193{
194 struct pktq_prec *q;
195 struct sk_buff *p, *prev;
196
197 q = &pq->q[prec];
198
199 p = q->head;
200 if (p == NULL)
201 return NULL;
202
203 for (prev = NULL; p != q->tail; p = p->prev)
204 prev = p;
205
206 if (prev)
207 prev->prev = NULL;
208 else
209 q->head = NULL;
210
211 q->tail = prev;
212 q->len--;
213
214 pq->len--;
215
216 return p;
217}
218EXPORT_SYMBOL(brcmu_pktq_pdeq_tail);
219
220void
221brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir,
222 ifpkt_cb_t fn, void *arg)
223{
224 struct pktq_prec *q;
225 struct sk_buff *p, *prev = NULL;
226
227 q = &pq->q[prec];
228 p = q->head;
229 while (p) {
230 if (fn == NULL || (*fn) (p, arg)) {
231 bool head = (p == q->head);
232 if (head)
233 q->head = p->prev;
234 else
235 prev->prev = p->prev;
236 p->prev = NULL;
237 brcmu_pkt_buf_free_skb(p);
238 q->len--;
239 pq->len--;
240 p = (head ? q->head : prev->prev);
241 } else {
242 prev = p;
243 p = p->prev;
244 }
245 }
246
247 if (q->head == NULL) {
248 q->tail = NULL;
249 }
250}
251EXPORT_SYMBOL(brcmu_pktq_pflush);
252
253void brcmu_pktq_flush(struct pktq *pq, bool dir,
254 ifpkt_cb_t fn, void *arg)
255{
256 int prec;
257 for (prec = 0; prec < pq->num_prec; prec++)
258 brcmu_pktq_pflush(pq, prec, dir, fn, arg);
259}
260EXPORT_SYMBOL(brcmu_pktq_flush);
261
262void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len)
263{
264 int prec;
265
266 /* pq is variable size; only zero out what's requested */
267 memset(pq, 0,
268 offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
269
270 pq->num_prec = (u16) num_prec;
271
272 pq->max = (u16) max_len;
273
274 for (prec = 0; prec < num_prec; prec++)
275 pq->q[prec].max = pq->max;
276}
277EXPORT_SYMBOL(brcmu_pktq_init);
278
279struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out)
280{
281 int prec;
282
283 if (pq->len == 0)
284 return NULL;
285
286 for (prec = 0; prec < pq->hi_prec; prec++)
287 if (pq->q[prec].head)
288 break;
289
290 if (prec_out)
291 *prec_out = prec;
292
293 return pq->q[prec].tail;
294}
295EXPORT_SYMBOL(brcmu_pktq_peek_tail);
296
297/* Return sum of lengths of a specific set of precedences */
298int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp)
299{
300 int prec, len;
301
302 len = 0;
303
304 for (prec = 0; prec <= pq->hi_prec; prec++)
305 if (prec_bmp & (1 << prec))
306 len += pq->q[prec].len;
307
308 return len;
309}
310EXPORT_SYMBOL(brcmu_pktq_mlen);
311
312/* Priority dequeue from a specific set of precedences */
313struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
314 int *prec_out)
315{
316 struct pktq_prec *q;
317 struct sk_buff *p;
318 int prec;
319
320 if (pq->len == 0)
321 return NULL;
322
323 while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
324 pq->hi_prec--;
325
326 while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
327 if (prec-- == 0)
328 return NULL;
329
330 q = &pq->q[prec];
331
332 p = q->head;
333 if (p == NULL)
334 return NULL;
335
336 q->head = p->prev;
337 if (q->head == NULL)
338 q->tail = NULL;
339
340 q->len--;
341
342 if (prec_out)
343 *prec_out = prec;
344
345 pq->len--;
346
347 p->prev = NULL;
348
349 return p;
350}
351EXPORT_SYMBOL(brcmu_pktq_mdeq);
352
353/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
354int brcmu_ether_atoe(char *p, u8 *ea)
355{
356 int i = 0;
357
358 for (;;) {
359 ea[i++] = (char)simple_strtoul(p, &p, 16);
360 if (!*p++ || i == 6)
361 break;
362 }
363
364 return i == 6;
365}
366EXPORT_SYMBOL(brcmu_ether_atoe);
367
368#if defined(BCMDBG)
369/* pretty hex print a pkt buffer chain */
370void brcmu_prpkt(const char *msg, struct sk_buff *p0)
371{
372 struct sk_buff *p;
373
374 if (msg && (msg[0] != '\0'))
375 printk(KERN_DEBUG "%s:\n", msg);
376
377 for (p = p0; p; p = p->next)
378 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
379}
380EXPORT_SYMBOL(brcmu_prpkt);
381#endif /* defined(BCMDBG) */
382
383/* iovar table lookup */
384const struct brcmu_iovar *brcmu_iovar_lookup(const struct brcmu_iovar *table,
385 const char *name)
386{
387 const struct brcmu_iovar *vi;
388 const char *lookup_name;
389
390 /* skip any ':' delimited option prefixes */
391 lookup_name = strrchr(name, ':');
392 if (lookup_name != NULL)
393 lookup_name++;
394 else
395 lookup_name = name;
396
397 for (vi = table; vi->name; vi++) {
398 if (!strcmp(vi->name, lookup_name))
399 return vi;
400 }
401 /* ran to end of table */
402
403 return NULL; /* var name not found */
404}
405EXPORT_SYMBOL(brcmu_iovar_lookup);
406
407int brcmu_iovar_lencheck(const struct brcmu_iovar *vi, void *arg, int len,
408 bool set)
409{
410 int bcmerror = 0;
411
412 /* length check on io buf */
413 switch (vi->type) {
414 case IOVT_BOOL:
415 case IOVT_INT8:
416 case IOVT_INT16:
417 case IOVT_INT32:
418 case IOVT_UINT8:
419 case IOVT_UINT16:
420 case IOVT_UINT32:
421 /* all integers are s32 sized args at the ioctl interface */
422 if (len < (int)sizeof(int)) {
423 bcmerror = -EOVERFLOW;
424 }
425 break;
426
427 case IOVT_BUFFER:
428 /* buffer must meet minimum length requirement */
429 if (len < vi->minlen) {
430 bcmerror = -EOVERFLOW;
431 }
432 break;
433
434 case IOVT_VOID:
435 if (!set) {
436 /* Cannot return nil... */
437 bcmerror = -ENOTSUPP;
438 } else if (len) {
439 /* Set is an action w/o parameters */
440 bcmerror = -ENOBUFS;
441 }
442 break;
443
444 default:
445 /* unknown type for length check in iovar info */
446 bcmerror = -ENOTSUPP;
447 }
448
449 return bcmerror;
450}
451EXPORT_SYMBOL(brcmu_iovar_lencheck);
452
453/*******************************************************************************
454 * crc8
455 *
456 * Computes a crc8 over the input data using the polynomial:
457 *
458 * x^8 + x^7 +x^6 + x^4 + x^2 + 1
459 *
460 * The caller provides the initial value (either CRC8_INIT_VALUE
461 * or the previous returned value) to allow for processing of
462 * discontiguous blocks of data. When generating the CRC the
463 * caller is responsible for complementing the final return value
464 * and inserting it into the byte stream. When checking, a final
465 * return value of CRC8_GOOD_VALUE indicates a valid CRC.
466 *
467 * Reference: Dallas Semiconductor Application Note 27
468 * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
469 * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
470 * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
471 *
472 * ****************************************************************************
473 */
474
475static const u8 crc8_table[256] = {
476 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
477 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
478 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
479 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
480 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
481 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
482 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
483 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
484 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
485 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
486 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
487 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
488 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
489 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
490 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
491 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
492 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
493 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
494 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
495 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
496 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
497 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
498 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
499 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
500 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
501 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
502 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
503 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
504 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
505 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
506 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
507 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
508};
509
510u8 brcmu_crc8(u8 *pdata, /* pointer to array of data to process */
511 uint nbytes, /* number of input data bytes to process */
512 u8 crc /* either CRC8_INIT_VALUE or previous return value */
513 ) {
514 /* loop over the buffer data */
515 while (nbytes-- > 0)
516 crc = crc8_table[(crc ^ *pdata++) & 0xff];
517
518 return crc;
519}
520EXPORT_SYMBOL(brcmu_crc8);
521
522/*
523 * Traverse a string of 1-byte tag/1-byte length/variable-length value
524 * triples, returning a pointer to the substring whose first element
525 * matches tag
526 */
527struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen, uint key)
528{
529 struct brcmu_tlv *elt;
530 int totlen;
531
532 elt = (struct brcmu_tlv *) buf;
533 totlen = buflen;
534
535 /* find tagged parameter */
536 while (totlen >= 2) {
537 int len = elt->len;
538
539 /* validate remaining totlen */
540 if ((elt->id == key) && (totlen >= (len + 2)))
541 return elt;
542
543 elt = (struct brcmu_tlv *) ((u8 *) elt + (len + 2));
544 totlen -= (len + 2);
545 }
546
547 return NULL;
548}
549EXPORT_SYMBOL(brcmu_parse_tlvs);
550
551
552#if defined(BCMDBG)
553int
554brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags, char *buf,
555 int len)
556{
557 int i;
558 char *p = buf;
559 char hexstr[16];
560 int slen = 0, nlen = 0;
561 u32 bit;
562 const char *name;
563
564 if (len < 2 || !buf)
565 return 0;
566
567 buf[0] = '\0';
568
569 for (i = 0; flags != 0; i++) {
570 bit = bd[i].bit;
571 name = bd[i].name;
572 if (bit == 0 && flags != 0) {
573 /* print any unnamed bits */
574 snprintf(hexstr, 16, "0x%X", flags);
575 name = hexstr;
576 flags = 0; /* exit loop */
577 } else if ((flags & bit) == 0)
578 continue;
579 flags &= ~bit;
580 nlen = strlen(name);
581 slen += nlen;
582 /* count btwn flag space */
583 if (flags != 0)
584 slen += 1;
585 /* need NULL char as well */
586 if (len <= slen)
587 break;
588 /* copy NULL char but don't count it */
589 strncpy(p, name, nlen + 1);
590 p += nlen;
591 /* copy btwn flag space and NULL char */
592 if (flags != 0)
593 p += snprintf(p, 2, " ");
594 len -= slen;
595 }
596
597 /* indicate the str was too short */
598 if (flags != 0) {
599 if (len < 2)
600 p -= 2 - len; /* overwrite last char */
601 p += snprintf(p, 2, ">");
602 }
603
604 return (int)(p - buf);
605}
606EXPORT_SYMBOL(brcmu_format_flags);
607
608/* print bytes formatted as hex to a string. return the resulting string length */
609int brcmu_format_hex(char *str, const void *bytes, int len)
610{
611 int i;
612 char *p = str;
613 const u8 *src = (const u8 *)bytes;
614
615 for (i = 0; i < len; i++) {
616 p += snprintf(p, 3, "%02X", *src);
617 src++;
618 }
619 return (int)(p - str);
620}
621EXPORT_SYMBOL(brcmu_format_hex);
622#endif /* defined(BCMDBG) */
623
624char *brcmu_chipname(uint chipid, char *buf, uint len)
625{
626 const char *fmt;
627
628 fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
629 snprintf(buf, len, fmt, chipid);
630 return buf;
631}
632EXPORT_SYMBOL(brcmu_chipname);
633
634uint brcmu_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
635{
636 uint len;
637
638 len = strlen(name) + 1;
639
640 if ((len + datalen) > buflen)
641 return 0;
642
643 strncpy(buf, name, buflen);
644
645 /* append data onto the end of the name string */
646 memcpy(&buf[len], data, datalen);
647 len += datalen;
648
649 return len;
650}
651EXPORT_SYMBOL(brcmu_mkiovar);
652
653/* Quarter dBm units to mW
654 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
655 * Table is offset so the last entry is largest mW value that fits in
656 * a u16.
657 */
658
659#define QDBM_OFFSET 153 /* Offset for first entry */
660#define QDBM_TABLE_LEN 40 /* Table size */
661
662/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
663 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
664 */
665#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
666
667/* Largest mW value that will round down to the last table entry,
668 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
669 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
670 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
671 */
672#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
673
674static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
675/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
676/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
677/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
678/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
679/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
680/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
681};
682
683u16 brcmu_qdbm_to_mw(u8 qdbm)
684{
685 uint factor = 1;
686 int idx = qdbm - QDBM_OFFSET;
687
688 if (idx >= QDBM_TABLE_LEN) {
689 /* clamp to max u16 mW value */
690 return 0xFFFF;
691 }
692
693 /* scale the qdBm index up to the range of the table 0-40
694 * where an offset of 40 qdBm equals a factor of 10 mW.
695 */
696 while (idx < 0) {
697 idx += 40;
698 factor *= 10;
699 }
700
701 /* return the mW value scaled down to the correct factor of 10,
702 * adding in factor/2 to get proper rounding.
703 */
704 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
705}
706EXPORT_SYMBOL(brcmu_qdbm_to_mw);
707
708u8 brcmu_mw_to_qdbm(u16 mw)
709{
710 u8 qdbm;
711 int offset;
712 uint mw_uint = mw;
713 uint boundary;
714
715 /* handle boundary case */
716 if (mw_uint <= 1)
717 return 0;
718
719 offset = QDBM_OFFSET;
720
721 /* move mw into the range of the table */
722 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
723 mw_uint *= 10;
724 offset -= 40;
725 }
726
727 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
728 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
729 nqdBm_to_mW_map[qdbm]) / 2;
730 if (mw_uint < boundary)
731 break;
732 }
733
734 qdbm += (u8) offset;
735
736 return qdbm;
737}
738EXPORT_SYMBOL(brcmu_mw_to_qdbm);
739
740uint brcmu_bitcount(u8 *bitmap, uint length)
741{
742 uint bitcount = 0, i;
743 u8 tmp;
744 for (i = 0; i < length; i++) {
745 tmp = bitmap[i];
746 while (tmp) {
747 bitcount++;
748 tmp &= (tmp - 1);
749 }
750 }
751 return bitcount;
752}
753EXPORT_SYMBOL(brcmu_bitcount);
754
755/* Initialization of brcmu_strbuf structure */
756void brcmu_binit(struct brcmu_strbuf *b, char *buf, uint size)
757{
758 b->origsize = b->size = size;
759 b->origbuf = b->buf = buf;
760}
761EXPORT_SYMBOL(brcmu_binit);
762
763/* Buffer sprintf wrapper to guard against buffer overflow */
764int brcmu_bprintf(struct brcmu_strbuf *b, const char *fmt, ...)
765{
766 va_list ap;
767 int r;
768
769 va_start(ap, fmt);
770 r = vsnprintf(b->buf, b->size, fmt, ap);
771
772 /* Non Ansi C99 compliant returns -1,
773 * Ansi compliant return r >= b->size,
774 * stdlib returns 0, handle all
775 */
776 if ((r == -1) || (r >= (int)b->size) || (r == 0)) {
777 b->size = 0;
778 } else {
779 b->size -= r;
780 b->buf += r;
781 }
782
783 va_end(ap);
784
785 return r;
786}
787EXPORT_SYMBOL(brcmu_bprintf);
diff --git a/drivers/staging/brcm80211/brcmutil/wifi.c b/drivers/staging/brcm80211/brcmutil/wifi.c
new file mode 100644
index 00000000000..b9ffe8682a2
--- /dev/null
+++ b/drivers/staging/brcm80211/brcmutil/wifi.c
@@ -0,0 +1,131 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <brcmu_wifi.h>
17
18/*
19 * Verify the chanspec is using a legal set of parameters, i.e. that the
20 * chanspec specified a band, bw, ctl_sb and channel and that the
21 * combination could be legal given any set of circumstances.
22 * RETURNS: true is the chanspec is malformed, false if it looks good.
23 */
24bool brcmu_chspec_malformed(chanspec_t chanspec)
25{
26 /* must be 2G or 5G band */
27 if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
28 return true;
29 /* must be 20 or 40 bandwidth */
30 if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
31 return true;
32
33 /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
34 if (CHSPEC_IS20(chanspec)) {
35 if (!CHSPEC_SB_NONE(chanspec))
36 return true;
37 } else {
38 if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec))
39 return true;
40 }
41
42 return false;
43}
44EXPORT_SYMBOL(brcmu_chspec_malformed);
45
46/*
47 * This function returns the channel number that control traffic is being sent on, for legacy
48 * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
49 * sideband depending on the chanspec selected
50 */
51u8 brcmu_chspec_ctlchan(chanspec_t chspec)
52{
53 u8 ctl_chan;
54
55 /* Is there a sideband ? */
56 if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
57 return CHSPEC_CHANNEL(chspec);
58 } else {
59 /* we only support 40MHZ with sidebands */
60 /* chanspec channel holds the centre frequency, use that and the
61 * side band information to reconstruct the control channel number
62 */
63 if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
64 /* control chan is the upper 20 MHZ SB of the 40MHZ channel */
65 ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
66 } else {
67 /* control chan is the lower 20 MHZ SB of the 40MHZ channel */
68 ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
69 }
70 }
71
72 return ctl_chan;
73}
74EXPORT_SYMBOL(brcmu_chspec_ctlchan);
75
76/*
77 * Return the channel number for a given frequency and base frequency.
78 * The returned channel number is relative to the given base frequency.
79 * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
80 * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
81 *
82 * Frequency is specified in MHz.
83 * The base frequency is specified as (start_factor * 500 kHz).
84 * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
85 * 2.4 GHz and 5 GHz bands.
86 *
87 * The returned channel will be in the range [1, 14] in the 2.4 GHz band
88 * and [0, 200] otherwise.
89 * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
90 * frequency is not a 2.4 GHz channel, or if the frequency is not and even
91 * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
92 *
93 * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
94 */
95int brcmu_mhz2channel(uint freq, uint start_factor)
96{
97 int ch = -1;
98 uint base;
99 int offset;
100
101 /* take the default channel start frequency */
102 if (start_factor == 0) {
103 if (freq >= 2400 && freq <= 2500)
104 start_factor = WF_CHAN_FACTOR_2_4_G;
105 else if (freq >= 5000 && freq <= 6000)
106 start_factor = WF_CHAN_FACTOR_5_G;
107 }
108
109 if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
110 return 14;
111
112 base = start_factor / 2;
113
114 /* check that the frequency is in 1GHz range of the base */
115 if ((freq < base) || (freq > base + 1000))
116 return -1;
117
118 offset = freq - base;
119 ch = offset / 5;
120
121 /* check that frequency is a 5MHz multiple from the base */
122 if (offset != (ch * 5))
123 return -1;
124
125 /* restricted channel range check for 2.4G */
126 if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
127 return -1;
128
129 return ch;
130}
131EXPORT_SYMBOL(brcmu_mhz2channel);
diff --git a/drivers/staging/brcm80211/include/brcm_hw_ids.h b/drivers/staging/brcm80211/include/brcm_hw_ids.h
new file mode 100644
index 00000000000..5fb17d53c9b
--- /dev/null
+++ b/drivers/staging/brcm80211/include/brcm_hw_ids.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_HW_IDS_H_
18#define _BRCM_HW_IDS_H_
19
20#define BCM4325_D11DUAL_ID 0x431b
21#define BCM4325_D11G_ID 0x431c
22#define BCM4325_D11A_ID 0x431d
23
24#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */
25#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */
26#define BCM4329_D11NDUAL_ID 0x432e
27
28#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */
29#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */
30#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */
31
32#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
33#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */
34
35#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
36
37#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
38#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
39
40#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
41
42/* Chip IDs */
43#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */
44#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */
45
46#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */
47#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */
48#define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */
49#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */
50#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */
51#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */
52#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */
53#define BCM4325_CHIP_ID 0x4325 /* 4325 chipcommon chipid */
54#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */
55#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */
56#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */
57#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */
58
59#endif /* _BRCM_HW_IDS_H_ */
diff --git a/drivers/staging/brcm80211/include/brcmu_utils.h b/drivers/staging/brcm80211/include/brcmu_utils.h
new file mode 100644
index 00000000000..2d54cc5f4b1
--- /dev/null
+++ b/drivers/staging/brcm80211/include/brcmu_utils.h
@@ -0,0 +1,301 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMU_UTILS_H_
18#define _BRCMU_UTILS_H_
19
20#include <linux/skbuff.h>
21
22/* Buffer structure for collecting string-formatted data
23* using brcmu_bprintf() API.
24* Use brcmu_binit() to initialize before use
25*/
26
27struct brcmu_strbuf {
28 char *buf; /* pointer to current position in origbuf */
29 unsigned int size; /* current (residual) size in bytes */
30 char *origbuf; /* unmodified pointer to orignal buffer */
31 unsigned int origsize; /* unmodified orignal buffer size in bytes */
32};
33
34/*
35 * Spin at most 'us' microseconds while 'exp' is true.
36 * Caller should explicitly test 'exp' when this completes
37 * and take appropriate error action if 'exp' is still true.
38 */
39#define SPINWAIT(exp, us) { \
40 uint countdown = (us) + 9; \
41 while ((exp) && (countdown >= 10)) {\
42 udelay(10); \
43 countdown -= 10; \
44 } \
45}
46
47/* osl multi-precedence packet queue */
48#ifndef PKTQ_LEN_DEFAULT
49#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
50#endif
51#ifndef PKTQ_MAX_PREC
52#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
53#endif
54
55struct pktq_prec {
56 struct sk_buff *head; /* first packet to dequeue */
57 struct sk_buff *tail; /* last packet to dequeue */
58 u16 len; /* number of queued packets */
59 u16 max; /* maximum number of queued packets */
60};
61
62/* multi-priority pkt queue */
63struct pktq {
64 u16 num_prec; /* number of precedences in use */
65 u16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
66 u16 max; /* total max packets */
67 u16 len; /* total number of packets */
68 /*
69 * q array must be last since # of elements can be either
70 * PKTQ_MAX_PREC or 1
71 */
72 struct pktq_prec q[PKTQ_MAX_PREC];
73};
74
75/* fn(pkt, arg). return true if pkt belongs to if */
76typedef bool(*ifpkt_cb_t) (struct sk_buff *, void *);
77
78/* operations on a specific precedence in packet queue */
79
80#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max))
81#define pktq_plen(pq, prec) ((pq)->q[prec].len)
82#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len)
83#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max)
84#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0)
85
86#define pktq_ppeek(pq, prec) ((pq)->q[prec].head)
87#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail)
88
89extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
90 struct sk_buff *p);
91extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
92 struct sk_buff *p);
93extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
94extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
95
96/* packet primitives */
97extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
98extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb);
99
100/* Empty the queue at particular precedence level */
101extern void brcmu_pktq_pflush(struct pktq *pq, int prec,
102 bool dir, ifpkt_cb_t fn, void *arg);
103
104/* operations on a set of precedences in packet queue */
105
106extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp);
107extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
108 int *prec_out);
109
110/* operations on packet queue as a whole */
111
112#define pktq_len(pq) ((int)(pq)->len)
113#define pktq_max(pq) ((int)(pq)->max)
114#define pktq_avail(pq) ((int)((pq)->max - (pq)->len))
115#define pktq_full(pq) ((pq)->len >= (pq)->max)
116#define pktq_empty(pq) ((pq)->len == 0)
117
118/* operations for single precedence queues */
119#define pktenq(pq, p) brcmu_pktq_penq(((struct pktq *)pq), 0, (p))
120#define pktenq_head(pq, p)\
121 brcmu_pktq_penq_head(((struct pktq *)pq), 0, (p))
122#define pktdeq(pq) brcmu_pktq_pdeq(((struct pktq *)pq), 0)
123#define pktdeq_tail(pq) brcmu_pktq_pdeq_tail(((struct pktq *)pq), 0)
124#define pktqinit(pq, len) brcmu_pktq_init(((struct pktq *)pq), 1, len)
125
126extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len);
127/* prec_out may be NULL if caller is not interested in return value */
128extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out);
129extern void brcmu_pktq_flush(struct pktq *pq, bool dir,
130 ifpkt_cb_t fn, void *arg);
131
132/* externs */
133/* packet */
134extern uint brcmu_pktfrombuf(struct sk_buff *p,
135 uint offset, int len, unsigned char *buf);
136extern uint brcmu_pkttotlen(struct sk_buff *p);
137
138/* ethernet address */
139extern int brcmu_ether_atoe(char *p, u8 *ea);
140
141/* ip address */
142struct ipv4_addr;
143
144#ifdef BCMDBG
145extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
146#else
147#define brcmu_prpkt(a, b)
148#endif /* BCMDBG */
149
150/* Support for sharing code across in-driver iovar implementations.
151 * The intent is that a driver use this structure to map iovar names
152 * to its (private) iovar identifiers, and the lookup function to
153 * find the entry. Macros are provided to map ids and get/set actions
154 * into a single number space for a switch statement.
155 */
156
157/* iovar structure */
158struct brcmu_iovar {
159 const char *name; /* name for lookup and display */
160 u16 varid; /* id for switch */
161 u16 flags; /* driver-specific flag bits */
162 u16 type; /* base type of argument */
163 u16 minlen; /* min length for buffer vars */
164};
165
166/* varid definitions are per-driver, may use these get/set bits */
167
168/* IOVar action bits for id mapping */
169#define IOV_GET 0 /* Get an iovar */
170#define IOV_SET 1 /* Set an iovar */
171
172/* Varid to actionid mapping */
173#define IOV_GVAL(id) ((id)*2)
174#define IOV_SVAL(id) (((id)*2)+IOV_SET)
175#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET)
176#define IOV_ID(actionid) (actionid >> 1)
177
178extern const struct
179brcmu_iovar *brcmu_iovar_lookup(const struct brcmu_iovar *table,
180 const char *name);
181extern int brcmu_iovar_lencheck(const struct brcmu_iovar *table, void *arg,
182 int len, bool set);
183
184/* Base type definitions */
185#define IOVT_VOID 0 /* no value (implictly set only) */
186#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */
187#define IOVT_INT8 2 /* integer values are range-checked */
188#define IOVT_UINT8 3 /* unsigned int 8 bits */
189#define IOVT_INT16 4 /* int 16 bits */
190#define IOVT_UINT16 5 /* unsigned int 16 bits */
191#define IOVT_INT32 6 /* int 32 bits */
192#define IOVT_UINT32 7 /* unsigned int 32 bits */
193#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */
194#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER)
195
196/* ** driver/apps-shared section ** */
197
198#define BCME_STRLEN 64 /* Max string length for BCM errors */
199
200#ifndef ABS
201#define ABS(a) (((a) < 0) ? -(a) : (a))
202#endif /* ABS */
203
204#define CEIL(x, y) (((x) + ((y)-1)) / (y))
205#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0)
206
207/* map physical to virtual I/O */
208#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), \
209 (unsigned long)(size))
210
211/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
212#define PKTBUFSZ 2048
213
214#define OSL_SYSUPTIME() ((u32)jiffies * (1000 / HZ))
215
216#ifndef setbit
217#ifndef NBBY /* the BSD family defines NBBY */
218#define NBBY 8 /* 8 bits per byte */
219#endif /* #ifndef NBBY */
220#define setbit(a, i) (((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
221#define clrbit(a, i) (((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
222#define isset(a, i) (((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
223#define isclr(a, i) ((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
224#endif /* setbit */
225
226#define NBITS(type) (sizeof(type) * 8)
227#define NBITVAL(nbits) (1 << (nbits))
228#define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
229#define NBITMASK(nbits) MAXBITVAL(nbits)
230#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
231
232/* basic mux operation - can be optimized on several architectures */
233#define MUX(pred, true, false) ((pred) ? (true) : (false))
234
235/* modulo inc/dec - assumes x E [0, bound - 1] */
236#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
237#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
238
239/* modulo inc/dec, bound = 2^k */
240#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
241#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
242
243/* modulo add/sub - assumes x, y E [0, bound - 1] */
244#define MODADD(x, y, bound) \
245 MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
246#define MODSUB(x, y, bound) \
247 MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
248
249/* module add/sub, bound = 2^k */
250#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
251#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
252
253/* crc defines */
254#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
255#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
256#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
257#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
258
259/* brcmu_format_flags() bit description structure */
260struct brcmu_bit_desc {
261 u32 bit;
262 const char *name;
263};
264
265/* tag_ID/length/value_buffer tuple */
266struct brcmu_tlv {
267 u8 id;
268 u8 len;
269 u8 data[1];
270};
271
272#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */
273
274/* externs */
275/* crc */
276extern u8 brcmu_crc8(u8 *p, uint nbytes, u8 crc);
277
278/* format/print */
279#if defined(BCMDBG)
280extern int brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags,
281 char *buf, int len);
282extern int brcmu_format_hex(char *str, const void *bytes, int len);
283#endif
284
285extern char *brcmu_chipname(uint chipid, char *buf, uint len);
286
287extern struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen,
288 uint key);
289
290/* power conversion */
291extern u16 brcmu_qdbm_to_mw(u8 qdbm);
292extern u8 brcmu_mw_to_qdbm(u16 mw);
293
294extern void brcmu_binit(struct brcmu_strbuf *b, char *buf, uint size);
295extern int brcmu_bprintf(struct brcmu_strbuf *b, const char *fmt, ...);
296
297extern uint brcmu_mkiovar(char *name, char *data, uint datalen,
298 char *buf, uint len);
299extern uint brcmu_bitcount(u8 *bitmap, uint bytelength);
300
301#endif /* _BRCMU_UTILS_H_ */
diff --git a/drivers/staging/brcm80211/include/brcmu_wifi.h b/drivers/staging/brcm80211/include/brcmu_wifi.h
new file mode 100644
index 00000000000..fde592bd917
--- /dev/null
+++ b/drivers/staging/brcm80211/include/brcmu_wifi.h
@@ -0,0 +1,243 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCMU_WIFI_H_
18#define _BRCMU_WIFI_H_
19
20#include <linux/if_ether.h> /* for ETH_ALEN */
21#include <linux/ieee80211.h> /* for WLAN_PMKID_LEN */
22
23/* A chanspec holds the channel number, band, bandwidth and control sideband */
24typedef u16 chanspec_t;
25
26/* channel defines */
27#define CH_UPPER_SB 0x01
28#define CH_LOWER_SB 0x02
29#define CH_EWA_VALID 0x04
30#define CH_20MHZ_APART 4
31#define CH_10MHZ_APART 2
32#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
33#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
34#define BRCM_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */
35#define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216,
36 * this is that + 1 rounded up to a multiple of NBBY (8).
37 * DO NOT MAKE it > 255: channels are u8's all over
38 */
39
40#define WL_CHANSPEC_CHAN_MASK 0x00ff
41#define WL_CHANSPEC_CHAN_SHIFT 0
42
43#define WL_CHANSPEC_CTL_SB_MASK 0x0300
44#define WL_CHANSPEC_CTL_SB_SHIFT 8
45#define WL_CHANSPEC_CTL_SB_LOWER 0x0100
46#define WL_CHANSPEC_CTL_SB_UPPER 0x0200
47#define WL_CHANSPEC_CTL_SB_NONE 0x0300
48
49#define WL_CHANSPEC_BW_MASK 0x0C00
50#define WL_CHANSPEC_BW_SHIFT 10
51#define WL_CHANSPEC_BW_10 0x0400
52#define WL_CHANSPEC_BW_20 0x0800
53#define WL_CHANSPEC_BW_40 0x0C00
54
55#define WL_CHANSPEC_BAND_MASK 0xf000
56#define WL_CHANSPEC_BAND_SHIFT 12
57#define WL_CHANSPEC_BAND_5G 0x1000
58#define WL_CHANSPEC_BAND_2G 0x2000
59#define INVCHANSPEC 255
60
61/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
62#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
63#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
64#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
65
66/* channel defines */
67#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0)
68#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
69 ((channel) + CH_10MHZ_APART) : 0)
70#define CHSPEC_BANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : \
71 BAND_2G_INDEX)
72#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
73 WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
74 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
75#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
76 ((channel) + CH_20MHZ_APART) : 0)
77#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
78 ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
79 ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
80 WL_CHANSPEC_BAND_5G))
81#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
82#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
83
84#ifdef WL11N_20MHZONLY
85
86#define CHSPEC_CTL_SB(chspec) WL_CHANSPEC_CTL_SB_NONE
87#define CHSPEC_BW(chspec) WL_CHANSPEC_BW_20
88#define CHSPEC_IS10(chspec) 0
89#define CHSPEC_IS20(chspec) 1
90#ifndef CHSPEC_IS40
91#define CHSPEC_IS40(chspec) 0
92#endif
93
94#else /* !WL11N_20MHZONLY */
95
96#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
97#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
98#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
99#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
100#ifndef CHSPEC_IS40
101#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
102#endif
103
104#endif /* !WL11N_20MHZONLY */
105
106#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
107#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
108#define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
109#define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
110#define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
111#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \
112 (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
113 (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))))
114#define CHSPEC2BAND(chspec) (CHSPEC_IS5G(chspec) ? BRCM_BAND_5G : BRCM_BAND_2G)
115
116#define CHANSPEC_STR_LEN 8
117
118/* defined rate in 500kbps */
119#define BRCM_MAXRATE 108 /* in 500kbps units */
120#define BRCM_RATE_1M 2 /* in 500kbps units */
121#define BRCM_RATE_2M 4 /* in 500kbps units */
122#define BRCM_RATE_5M5 11 /* in 500kbps units */
123#define BRCM_RATE_11M 22 /* in 500kbps units */
124#define BRCM_RATE_6M 12 /* in 500kbps units */
125#define BRCM_RATE_9M 18 /* in 500kbps units */
126#define BRCM_RATE_12M 24 /* in 500kbps units */
127#define BRCM_RATE_18M 36 /* in 500kbps units */
128#define BRCM_RATE_24M 48 /* in 500kbps units */
129#define BRCM_RATE_36M 72 /* in 500kbps units */
130#define BRCM_RATE_48M 96 /* in 500kbps units */
131#define BRCM_RATE_54M 108 /* in 500kbps units */
132
133#define BRCM_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */
134
135#define MCSSET_LEN 16
136
137#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0)
138
139/*
140 * Verify the chanspec is using a legal set of parameters, i.e. that the
141 * chanspec specified a band, bw, ctl_sb and channel and that the
142 * combination could be legal given any set of circumstances.
143 * RETURNS: true is the chanspec is malformed, false if it looks good.
144 */
145extern bool brcmu_chspec_malformed(chanspec_t chanspec);
146
147/*
148 * This function returns the channel number that control traffic is being sent on, for legacy
149 * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
150 * sideband depending on the chanspec selected
151 */
152extern u8 brcmu_chspec_ctlchan(chanspec_t chspec);
153
154/*
155 * Return the channel number for a given frequency and base frequency.
156 * The returned channel number is relative to the given base frequency.
157 * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
158 * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
159 *
160 * Frequency is specified in MHz.
161 * The base frequency is specified as (start_factor * 500 kHz).
162 * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
163 * 2.4 GHz and 5 GHz bands.
164 *
165 * The returned channel will be in the range [1, 14] in the 2.4 GHz band
166 * and [0, 200] otherwise.
167 * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
168 * frequency is not a 2.4 GHz channel, or if the frequency is not and even
169 * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
170 *
171 * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
172 */
173extern int brcmu_mhz2channel(uint freq, uint start_factor);
174
175/* Enumerate crypto algorithms */
176#define CRYPTO_ALGO_OFF 0
177#define CRYPTO_ALGO_WEP1 1
178#define CRYPTO_ALGO_TKIP 2
179#define CRYPTO_ALGO_WEP128 3
180#define CRYPTO_ALGO_AES_CCM 4
181#define CRYPTO_ALGO_AES_RESERVED1 5
182#define CRYPTO_ALGO_AES_RESERVED2 6
183#define CRYPTO_ALGO_NALG 7
184
185/* wireless security bitvec */
186#define WEP_ENABLED 0x0001
187#define TKIP_ENABLED 0x0002
188#define AES_ENABLED 0x0004
189#define WSEC_SWFLAG 0x0008
190#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */
191
192/* WPA authentication mode bitvec */
193#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
194#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */
195#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */
196#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */
197#define WPA_AUTH_RESERVED1 0x0008
198#define WPA_AUTH_RESERVED2 0x0010
199 /* #define WPA_AUTH_8021X 0x0020 *//* 802.1x, reserved */
200#define WPA2_AUTH_RESERVED1 0x0020
201#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */
202#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */
203#define WPA2_AUTH_RESERVED3 0x0200
204#define WPA2_AUTH_RESERVED4 0x0400
205#define WPA2_AUTH_RESERVED5 0x0800
206
207/* pmkid */
208#define MAXPMKID 16
209
210#define DOT11_DEFAULT_RTS_LEN 2347
211#define DOT11_DEFAULT_FRAG_LEN 2346
212
213#define DOT11_ICV_AES_LEN 8
214#define DOT11_QOS_LEN 2
215#define DOT11_IV_MAX_LEN 8
216#define DOT11_A4_HDR_LEN 30
217
218#define HT_CAP_RX_STBC_NO 0x0
219#define HT_CAP_RX_STBC_ONE_STREAM 0x1
220
221typedef struct _pmkid {
222 u8 BSSID[ETH_ALEN];
223 u8 PMKID[WLAN_PMKID_LEN];
224} pmkid_t;
225
226typedef struct _pmkid_list {
227 u32 npmkid;
228 pmkid_t pmkid[1];
229} pmkid_list_t;
230
231typedef struct _pmkid_cand {
232 u8 BSSID[ETH_ALEN];
233 u8 preauth;
234} pmkid_cand_t;
235
236typedef struct _pmkid_cand_list {
237 u32 npmkid_cand;
238 pmkid_cand_t pmkid_cand[1];
239} pmkid_cand_list_t;
240
241typedef u8 ac_bitmap_t;
242
243#endif /* _BRCMU_WIFI_H_ */
diff --git a/drivers/staging/brcm80211/include/chipcommon.h b/drivers/staging/brcm80211/include/chipcommon.h
new file mode 100644
index 00000000000..296582aced6
--- /dev/null
+++ b/drivers/staging/brcm80211/include/chipcommon.h
@@ -0,0 +1,281 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _SBCHIPC_H
18#define _SBCHIPC_H
19
20#include "defs.h" /* for PAD macro */
21
22typedef volatile struct {
23 u32 chipid; /* 0x0 */
24 u32 capabilities;
25 u32 corecontrol; /* corerev >= 1 */
26 u32 bist;
27
28 /* OTP */
29 u32 otpstatus; /* 0x10, corerev >= 10 */
30 u32 otpcontrol;
31 u32 otpprog;
32 u32 otplayout; /* corerev >= 23 */
33
34 /* Interrupt control */
35 u32 intstatus; /* 0x20 */
36 u32 intmask;
37
38 /* Chip specific regs */
39 u32 chipcontrol; /* 0x28, rev >= 11 */
40 u32 chipstatus; /* 0x2c, rev >= 11 */
41
42 /* Jtag Master */
43 u32 jtagcmd; /* 0x30, rev >= 10 */
44 u32 jtagir;
45 u32 jtagdr;
46 u32 jtagctrl;
47
48 /* serial flash interface registers */
49 u32 flashcontrol; /* 0x40 */
50 u32 flashaddress;
51 u32 flashdata;
52 u32 PAD[1];
53
54 /* Silicon backplane configuration broadcast control */
55 u32 broadcastaddress; /* 0x50 */
56 u32 broadcastdata;
57
58 /* gpio - cleared only by power-on-reset */
59 u32 gpiopullup; /* 0x58, corerev >= 20 */
60 u32 gpiopulldown; /* 0x5c, corerev >= 20 */
61 u32 gpioin; /* 0x60 */
62 u32 gpioout; /* 0x64 */
63 u32 gpioouten; /* 0x68 */
64 u32 gpiocontrol; /* 0x6C */
65 u32 gpiointpolarity; /* 0x70 */
66 u32 gpiointmask; /* 0x74 */
67
68 /* GPIO events corerev >= 11 */
69 u32 gpioevent;
70 u32 gpioeventintmask;
71
72 /* Watchdog timer */
73 u32 watchdog; /* 0x80 */
74
75 /* GPIO events corerev >= 11 */
76 u32 gpioeventintpolarity;
77
78 /* GPIO based LED powersave registers corerev >= 16 */
79 u32 gpiotimerval; /* 0x88 */
80 u32 gpiotimeroutmask;
81
82 /* clock control */
83 u32 clockcontrol_n; /* 0x90 */
84 u32 clockcontrol_sb; /* aka m0 */
85 u32 clockcontrol_pci; /* aka m1 */
86 u32 clockcontrol_m2; /* mii/uart/mipsref */
87 u32 clockcontrol_m3; /* cpu */
88 u32 clkdiv; /* corerev >= 3 */
89 u32 gpiodebugsel; /* corerev >= 28 */
90 u32 capabilities_ext; /* 0xac */
91
92 /* pll delay registers (corerev >= 4) */
93 u32 pll_on_delay; /* 0xb0 */
94 u32 fref_sel_delay;
95 u32 slow_clk_ctl; /* 5 < corerev < 10 */
96 u32 PAD;
97
98 /* Instaclock registers (corerev >= 10) */
99 u32 system_clk_ctl; /* 0xc0 */
100 u32 clkstatestretch;
101 u32 PAD[2];
102
103 /* Indirect backplane access (corerev >= 22) */
104 u32 bp_addrlow; /* 0xd0 */
105 u32 bp_addrhigh;
106 u32 bp_data;
107 u32 PAD;
108 u32 bp_indaccess;
109 u32 PAD[3];
110
111 /* More clock dividers (corerev >= 32) */
112 u32 clkdiv2;
113 u32 PAD[2];
114
115 /* In AI chips, pointer to erom */
116 u32 eromptr; /* 0xfc */
117
118 /* ExtBus control registers (corerev >= 3) */
119 u32 pcmcia_config; /* 0x100 */
120 u32 pcmcia_memwait;
121 u32 pcmcia_attrwait;
122 u32 pcmcia_iowait;
123 u32 ide_config;
124 u32 ide_memwait;
125 u32 ide_attrwait;
126 u32 ide_iowait;
127 u32 prog_config;
128 u32 prog_waitcount;
129 u32 flash_config;
130 u32 flash_waitcount;
131 u32 SECI_config; /* 0x130 SECI configuration */
132 u32 PAD[3];
133
134 /* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
135 u32 eci_output; /* 0x140 */
136 u32 eci_control;
137 u32 eci_inputlo;
138 u32 eci_inputmi;
139 u32 eci_inputhi;
140 u32 eci_inputintpolaritylo;
141 u32 eci_inputintpolaritymi;
142 u32 eci_inputintpolarityhi;
143 u32 eci_intmasklo;
144 u32 eci_intmaskmi;
145 u32 eci_intmaskhi;
146 u32 eci_eventlo;
147 u32 eci_eventmi;
148 u32 eci_eventhi;
149 u32 eci_eventmasklo;
150 u32 eci_eventmaskmi;
151 u32 eci_eventmaskhi;
152 u32 PAD[3];
153
154 /* SROM interface (corerev >= 32) */
155 u32 sromcontrol; /* 0x190 */
156 u32 sromaddress;
157 u32 sromdata;
158 u32 PAD[17];
159
160 /* Clock control and hardware workarounds (corerev >= 20) */
161 u32 clk_ctl_st; /* 0x1e0 */
162 u32 hw_war;
163 u32 PAD[70];
164
165 /* UARTs */
166 u8 uart0data; /* 0x300 */
167 u8 uart0imr;
168 u8 uart0fcr;
169 u8 uart0lcr;
170 u8 uart0mcr;
171 u8 uart0lsr;
172 u8 uart0msr;
173 u8 uart0scratch;
174 u8 PAD[248]; /* corerev >= 1 */
175
176 u8 uart1data; /* 0x400 */
177 u8 uart1imr;
178 u8 uart1fcr;
179 u8 uart1lcr;
180 u8 uart1mcr;
181 u8 uart1lsr;
182 u8 uart1msr;
183 u8 uart1scratch;
184 u32 PAD[126];
185
186 /* PMU registers (corerev >= 20) */
187 u32 pmucontrol; /* 0x600 */
188 u32 pmucapabilities;
189 u32 pmustatus;
190 u32 res_state;
191 u32 res_pending;
192 u32 pmutimer;
193 u32 min_res_mask;
194 u32 max_res_mask;
195 u32 res_table_sel;
196 u32 res_dep_mask;
197 u32 res_updn_timer;
198 u32 res_timer;
199 u32 clkstretch;
200 u32 pmuwatchdog;
201 u32 gpiosel; /* 0x638, rev >= 1 */
202 u32 gpioenable; /* 0x63c, rev >= 1 */
203 u32 res_req_timer_sel;
204 u32 res_req_timer;
205 u32 res_req_mask;
206 u32 PAD;
207 u32 chipcontrol_addr; /* 0x650 */
208 u32 chipcontrol_data; /* 0x654 */
209 u32 regcontrol_addr;
210 u32 regcontrol_data;
211 u32 pllcontrol_addr;
212 u32 pllcontrol_data;
213 u32 pmustrapopt; /* 0x668, corerev >= 28 */
214 u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */
215 u32 PAD[100];
216 u16 sromotp[768];
217} chipcregs_t;
218
219/* chipid */
220#define CID_ID_MASK 0x0000ffff /* Chip Id mask */
221#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */
222#define CID_REV_SHIFT 16 /* Chip Revision shift */
223#define CID_PKG_MASK 0x00f00000 /* Package Option mask */
224#define CID_PKG_SHIFT 20 /* Package Option shift */
225#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */
226#define CID_CC_SHIFT 24
227#define CID_TYPE_MASK 0xf0000000 /* Chip Type */
228#define CID_TYPE_SHIFT 28
229
230/* capabilities */
231#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */
232#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
233#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */
234#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */
235#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */
236#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */
237#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */
238#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */
239#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */
240#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */
241#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */
242#define CC_CAP_PWR_CTL 0x00040000 /* Power control */
243#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
244#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
245#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */
246#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */
247#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */
248#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */
249#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */
250#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */
251#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */
252
253#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */
254#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */
255
256/* pmucapabilities */
257#define PCAP_REV_MASK 0x000000ff
258#define PCAP_RC_MASK 0x00001f00
259#define PCAP_RC_SHIFT 8
260#define PCAP_TC_MASK 0x0001e000
261#define PCAP_TC_SHIFT 13
262#define PCAP_PC_MASK 0x001e0000
263#define PCAP_PC_SHIFT 17
264#define PCAP_VC_MASK 0x01e00000
265#define PCAP_VC_SHIFT 21
266#define PCAP_CC_MASK 0x1e000000
267#define PCAP_CC_SHIFT 25
268#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */
269#define PCAP5_PC_SHIFT 17
270#define PCAP5_VC_MASK 0x07c00000
271#define PCAP5_VC_SHIFT 22
272#define PCAP5_CC_MASK 0xf8000000
273#define PCAP5_CC_SHIFT 27
274
275/*
276* Maximum delay for the PMU state transition in us.
277* This is an upper bound intended for spinwaits etc.
278*/
279#define PMU_MAX_TRANSITION_DLY 15000
280
281#endif /* _SBCHIPC_H */
diff --git a/drivers/staging/brcm80211/include/defs.h b/drivers/staging/brcm80211/include/defs.h
new file mode 100644
index 00000000000..8b3e17dec15
--- /dev/null
+++ b/drivers/staging/brcm80211/include/defs.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_DEFS_H_
18#define _BRCM_DEFS_H_
19
20#include <linux/types.h>
21
22#define SI_BUS 0
23#define PCI_BUS 1
24#define PCMCIA_BUS 2
25#define SDIO_BUS 3
26#define JTAG_BUS 4
27#define USB_BUS 5
28#define SPI_BUS 6
29
30#ifndef OFF
31#define OFF 0
32#endif
33
34#ifndef ON
35#define ON 1 /* ON = 1 */
36#endif
37
38#define AUTO (-1) /* Auto = -1 */
39
40/*
41 * Priority definitions according 802.1D
42 */
43#define PRIO_8021D_NONE 2
44#define PRIO_8021D_BK 1
45#define PRIO_8021D_BE 0
46#define PRIO_8021D_EE 3
47#define PRIO_8021D_CL 4
48#define PRIO_8021D_VI 5
49#define PRIO_8021D_VO 6
50#define PRIO_8021D_NC 7
51
52#define MAXPRIO 7
53#define NUMPRIO (MAXPRIO + 1)
54
55#define WL_NUMRATES 16 /* max # of rates in a rateset */
56
57typedef struct wl_rateset {
58 u32 count; /* # rates in this set */
59 u8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */
60} wl_rateset_t;
61
62#define BRCM_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */
63
64#define BRCM_SET_CHANNEL 30
65#define BRCM_SET_SRL 32
66#define BRCM_SET_LRL 34
67
68#define BRCM_SET_RATESET 72
69#define BRCM_SET_BCNPRD 76
70#define BRCM_GET_CURR_RATESET 114 /* current rateset */
71#define BRCM_GET_PHYLIST 180
72
73/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
74#define WL_RADIO_SW_DISABLE (1<<0)
75#define WL_RADIO_HW_DISABLE (1<<1)
76#define WL_RADIO_MPC_DISABLE (1<<2)
77#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */
78
79/* Override bit for SET_TXPWR. if set, ignore other level limits */
80#define WL_TXPWR_OVERRIDE (1U<<31)
81
82/* band types */
83#define BRCM_BAND_AUTO 0 /* auto-select */
84#define BRCM_BAND_5G 1 /* 5 Ghz */
85#define BRCM_BAND_2G 2 /* 2.4 Ghz */
86#define BRCM_BAND_ALL 3 /* all bands */
87
88/* Values for PM */
89#define PM_OFF 0
90#define PM_MAX 1
91
92/* Message levels */
93#define LOG_ERROR_VAL 0x00000001
94#define LOG_TRACE_VAL 0x00000002
95
96#define PM_OFF 0
97#define PM_MAX 1
98#define PM_FAST 2
99
100/*
101 * Sonics Configuration Space Registers.
102 */
103#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */
104
105/* cpp contortions to concatenate w/arg prescan */
106#ifndef PAD
107#define _PADLINE(line) pad ## line
108#define _XSTR(line) _PADLINE(line)
109#define PAD _XSTR(__LINE__)
110#endif
111
112#endif /* _BRCM_DEFS_H_ */
diff --git a/drivers/staging/brcm80211/include/soc.h b/drivers/staging/brcm80211/include/soc.h
new file mode 100644
index 00000000000..6e5a705c493
--- /dev/null
+++ b/drivers/staging/brcm80211/include/soc.h
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _BRCM_SOC_H
18#define _BRCM_SOC_H
19
20#ifdef SI_ENUM_BASE_VARIABLE
21#define SI_ENUM_BASE (sii->pub.si_enum_base)
22#else
23#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
24#endif /* SI_ENUM_BASE_VARIABLE */
25
26/* core codes */
27#define NODEV_CORE_ID 0x700 /* Invalid coreid */
28#define CC_CORE_ID 0x800 /* chipcommon core */
29#define ILINE20_CORE_ID 0x801 /* iline20 core */
30#define SRAM_CORE_ID 0x802 /* sram core */
31#define SDRAM_CORE_ID 0x803 /* sdram core */
32#define PCI_CORE_ID 0x804 /* pci core */
33#define MIPS_CORE_ID 0x805 /* mips core */
34#define ENET_CORE_ID 0x806 /* enet mac core */
35#define CODEC_CORE_ID 0x807 /* v90 codec core */
36#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
37#define ADSL_CORE_ID 0x809 /* ADSL core */
38#define ILINE100_CORE_ID 0x80a /* iline100 core */
39#define IPSEC_CORE_ID 0x80b /* ipsec core */
40#define UTOPIA_CORE_ID 0x80c /* utopia core */
41#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
42#define SOCRAM_CORE_ID 0x80e /* internal memory core */
43#define MEMC_CORE_ID 0x80f /* memc sdram core */
44#define OFDM_CORE_ID 0x810 /* OFDM phy core */
45#define EXTIF_CORE_ID 0x811 /* external interface core */
46#define D11_CORE_ID 0x812 /* 802.11 MAC core */
47#define APHY_CORE_ID 0x813 /* 802.11a phy core */
48#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
49#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
50#define MIPS33_CORE_ID 0x816 /* mips3302 core */
51#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
52#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
53#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
54#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
55#define SDIOH_CORE_ID 0x81b /* sdio host core */
56#define ROBO_CORE_ID 0x81c /* roboswitch core */
57#define ATA100_CORE_ID 0x81d /* parallel ATA core */
58#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
59#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
60#define PCIE_CORE_ID 0x820 /* pci express core */
61#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
62#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
63#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
64#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
65#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
66#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
67#define PMU_CORE_ID 0x827 /* PMU core */
68#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
69#define SDIOD_CORE_ID 0x829 /* SDIO device core */
70#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
71#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
72#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
73#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
74#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
75#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
76#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
77#define SC_CORE_ID 0x831 /* shared common core */
78#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
79#define SPIH_CORE_ID 0x833 /* SPI host core */
80#define I2S_CORE_ID 0x834 /* I2S core */
81#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
82#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
83#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
84#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all
85 * unused address ranges
86 */
87
88/* Common core control flags */
89#define SICF_BIST_EN 0x8000
90#define SICF_PME_EN 0x4000
91#define SICF_CORE_BITS 0x3ffc
92#define SICF_FGC 0x0002
93#define SICF_CLOCK_EN 0x0001
94
95#endif /* _BRCM_SOC_H */