build/patch/kernel/sun4i-default/0030-ap6210_module.patch

127005 lines
4.3 MiB

diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index a17fd93..6afeab3 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -278,6 +278,7 @@ source "drivers/net/wireless/ath/Kconfig"
source "drivers/net/wireless/b43/Kconfig"
source "drivers/net/wireless/b43legacy/Kconfig"
source "drivers/net/wireless/bcmdhd/Kconfig"
+source "drivers/net/wireless/ap6210/Kconfig"
source "drivers/net/wireless/brcm80211/Kconfig"
source "drivers/net/wireless/bcm4330/Kconfig"
source "drivers/net/wireless/hostap/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 0db00ba..a970c43 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_IWM) += iwmc3200wifi/
obj-$(CONFIG_MWIFIEX) += mwifiex/
obj-$(CONFIG_BCMDHD) += bcmdhd/
+obj-$(CONFIG_AP6210) += ap6210/
obj-$(CONFIG_BRCMFMAC) += brcm80211/
obj-$(CONFIG_BRCMSMAC) += brcm80211/
diff --git a/drivers/net/wireless/ap6210/Kconfig b/drivers/net/wireless/ap6210/Kconfig
new file mode 100644
index 0000000..9756ac7
--- /dev/null
+++ b/drivers/net/wireless/ap6210/Kconfig
@@ -0,0 +1,45 @@
+config AP6210
+ tristate "AMPAK AP6210 wireless/bluetooth module support"
+ depends on MMC
+ default n
+ ---help---
+ This module adds support for the wireless and bluetooth
+ module of the CubieTruck.
+
+config AP6210_FW_PATH
+ depends on AP6210
+ string "Firmware path"
+ default "/system/vendor/modules/fw_bcmxxxx.bin"
+ ---help---
+ Path to the firmware file.
+
+config AP6210_NVRAM_PATH
+ depends on AP6210
+ string "NVRAM path"
+ default "/system/vendor/modules/nvram_apxxxx.txt"
+ ---help---
+ Path to the calibration file.
+
+config AP6210_WEXT
+ bool "Enable WEXT support"
+ depends on AP6210 && CFG80211 = n
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ help
+ Enables WEXT support
+
+choice
+ depends on AP6210
+ prompt "Interrupt type"
+config AP6210_OOB
+ depends on AP6210
+ bool "Out-of-Band Interrupt"
+ ---help---
+ Interrupt through WL_HOST_WAKE.
+config AP6210_SDIO_IRQ
+ depends on AP6210
+ bool "In-Band Interrupt"
+ default y
+ ---help---
+ Interrupt through SDIO DAT[1]
+endchoice
diff --git a/drivers/net/wireless/ap6210/Makefile b/drivers/net/wireless/ap6210/Makefile
new file mode 100644
index 0000000..02c0b0f
--- /dev/null
+++ b/drivers/net/wireless/ap6210/Makefile
@@ -0,0 +1,65 @@
+# ap6210
+DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \
+ -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE \
+ -DDHDTHREAD -DDHD_DEBUG -DSDTEST -DBDC -DTOE \
+ -DDHD_BCMEVENTS -DSHOW_EVENTS -DPROP_TXSTATUS -DBCMDBG \
+ -DMMC_SDIO_ABORT -DBCMSDIO -DBCMLXSDMMC -DBCMPLATFORM_BUS -DWLP2P \
+ -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT \
+ -DKEEP_ALIVE -DPKT_FILTER_SUPPORT \
+ -DEMBEDDED_PLATFORM -DENABLE_INSMOD_NO_FW_LOAD -DPNO_SUPPORT \
+ -DDHD_USE_IDLECOUNT -DSET_RANDOM_MAC_SOFTAP -DVSDB \
+ -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST -DSDIO_CRC_ERROR_FIX \
+ -DESCAN_RESULT_PATCH -DHT40_GO -DPASS_ARP_PACKET -DSUPPORT_PM2_ONLY \
+ -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DAMPDU_HOSTREORDER \
+ -DDISABLE_FW_ROAM_SUSPEND -DDISABLE_BUILTIN_ROAM \
+ -DCUSTOM_SDIO_F2_BLKSIZE=128 -DWL_SDO -DWL_SUPPORT_BACKPORTED_KPATCHES\
+ -Idrivers/net/wireless/ap6210 -Idrivers/net/wireless/ap6210/include
+
+DHDOFILES = aiutils.o bcmsdh_sdmmc_linux.o dhd_linux.o siutils.o bcmutils.o \
+ dhd_linux_sched.o dhd_sdio.o bcmwifi_channels.o bcmevent.o hndpmu.o \
+ bcmsdh.o dhd_cdc.o bcmsdh_linux.o dhd_common.o linux_osl.o \
+ bcmsdh_sdmmc.o dhd_custom_gpio.o sbutils.o wldev_common.o wl_android.o \
+ ap6210_gpio_wifi.o ap6210_gpio_bt.o
+
+obj-$(CONFIG_AP6210) += ap6210.o
+ap6210-objs += $(DHDOFILES)
+
+DHDOFILES += dhd_gpio.o
+DHDCFLAGS += -DCUSTOMER_HW
+#DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI
+
+ifeq ($(CONFIG_AP6210_OOB),y)
+DHDCFLAGS += -DOOB_INTR_ONLY -DHW_OOB -DCUSTOMER_OOB
+else
+DHDCFLAGS += -DSDIO_ISR_THREAD
+endif
+
+ifeq ($(CONFIG_AP6210_AG),y)
+ DHDCFLAGS += -DBAND_AG
+endif
+
+ifneq ($(CONFIG_WIRELESS_EXT),)
+ap6210-objs += wl_iw.o
+DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW
+endif
+ifneq ($(CONFIG_CFG80211),)
+ap6210-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o dhd_cfg80211.o
+DHDCFLAGS += -DWL_CFG80211 -DWL_CFG80211_STA_EVENT -DWL_ENABLE_P2P_IF
+DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-65
+DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15
+DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000
+DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=7
+DHDCFLAGS += -fno-aggressive-loop-optimizations
+endif
+ifneq ($(CONFIG_DHD_USE_SCHED_SCAN),)
+DHDCFLAGS += -DWL_SCHED_SCAN
+endif
+EXTRA_CFLAGS = $(DHDCFLAGS)
+ifeq ($(CONFIG_AP6210),m)
+EXTRA_LDFLAGS += --strip-debug
+endif
+
+# GPIO Power Management Modules
+
+#obj-$(CONFIG_AP6210) += ap6210_gpio_wifi.o
+#obj-$(CONFIG_AP6210) += ap6210_gpio_bt.o
diff --git a/drivers/net/wireless/ap6210/aiutils.c b/drivers/net/wireless/ap6210/aiutils.c
new file mode 100644
index 0000000..bc116d7
--- /dev/null
+++ b/drivers/net/wireless/ap6210/aiutils.c
@@ -0,0 +1,873 @@
+/*
+ * Misc utility routines for accessing chip-specific features
+ * of the SiliconBackplane-based Broadcom chips.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: aiutils.c 347614 2012-07-27 10:24:51Z $
+ */
+#include <bcm_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <ap6210.h>
+#include "siutils_priv.h"
+
+#include <ap6210.h>
+
+#define BCM47162_DMP() (0)
+#define BCM5357_DMP() (0)
+#define remap_coreid(sih, coreid) (coreid)
+#define remap_corerev(sih, corerev) (corerev)
+
+/* EROM parsing */
+
+static uint32
+get_erom_ent(si_t *sih, uint32 **eromptr, uint32 mask, uint32 match)
+{
+ uint32 ent;
+ uint inv = 0, nom = 0;
+
+ while (TRUE) {
+ ent = R_REG(si_osh(sih), *eromptr);
+ (*eromptr)++;
+
+ if (mask == 0)
+ break;
+
+ if ((ent & ER_VALID) == 0) {
+ inv++;
+ continue;
+ }
+
+ if (ent == (ER_END | ER_VALID))
+ break;
+
+ if ((ent & mask) == match)
+ break;
+
+ nom++;
+ }
+
+ AP6210_DEBUG("%s: Returning ent 0x%08x\n", __FUNCTION__, ent);
+ if (inv + nom) {
+ AP6210_DEBUG(" after %d invalid and %d non-matching entries\n", inv, nom);
+ }
+ return ent;
+}
+
+static uint32
+get_asd(si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st, uint32 *addrl, uint32 *addrh,
+ uint32 *sizel, uint32 *sizeh)
+{
+ uint32 asd, sz, szd;
+
+ asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
+ if (((asd & ER_TAG1) != ER_ADD) ||
+ (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
+ ((asd & AD_ST_MASK) != st)) {
+ /* This is not what we want, "push" it back */
+ (*eromptr)--;
+ return 0;
+ }
+ *addrl = asd & AD_ADDR_MASK;
+ if (asd & AD_AG32)
+ *addrh = get_erom_ent(sih, eromptr, 0, 0);
+ else
+ *addrh = 0;
+ *sizeh = 0;
+ sz = asd & AD_SZ_MASK;
+ if (sz == AD_SZ_SZD) {
+ szd = get_erom_ent(sih, eromptr, 0, 0);
+ *sizel = szd & SD_SZ_MASK;
+ if (szd & SD_SG32)
+ *sizeh = get_erom_ent(sih, eromptr, 0, 0);
+ } else
+ *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
+
+ AP6210_DEBUG(" SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
+ sp, ad, st, *sizeh, *sizel, *addrh, *addrl);
+
+ return asd;
+}
+
+static void
+ai_hwfixup(si_info_t *sii)
+{
+}
+
+
+/* parse the enumeration rom to identify all cores */
+void
+ai_scan(si_t *sih, void *regs, uint devid)
+{
+ si_info_t *sii = SI_INFO(sih);
+ chipcregs_t *cc = (chipcregs_t *)regs;
+ uint32 erombase, *eromptr, *eromlim;
+
+ erombase = R_REG(sii->osh, &cc->eromptr);
+
+ switch (BUSTYPE(sih->bustype)) {
+ case SI_BUS:
+ eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE);
+ break;
+
+ case PCI_BUS:
+ /* Set wrappers address */
+ sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE);
+
+ /* Now point the window at the erom */
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase);
+ eromptr = regs;
+ break;
+
+ case SPI_BUS:
+ case SDIO_BUS:
+ eromptr = (uint32 *)(uintptr)erombase;
+ break;
+
+ case PCMCIA_BUS:
+ default:
+ AP6210_ERR("Don't know how to do AXI enumertion on bus %d\n", sih->bustype);
+ ASSERT(0);
+ return;
+ }
+ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32));
+
+ AP6210_DEBUG("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n",
+ regs, erombase, eromptr, eromlim);
+ while (eromptr < eromlim) {
+ uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
+ uint32 mpd, asd, addrl, addrh, sizel, sizeh;
+ uint i, j, idx;
+ bool br;
+
+ br = FALSE;
+
+ /* Grok a component */
+ cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
+ if (cia == (ER_END | ER_VALID)) {
+ AP6210_DEBUG("Found END of erom after %d cores\n", sii->numcores);
+ ai_hwfixup(sii);
+ return;
+ }
+
+ cib = get_erom_ent(sih, &eromptr, 0, 0);
+
+ if ((cib & ER_TAG) != ER_CI) {
+ AP6210_ERR("CIA not followed by CIB\n");
+ goto error;
+ }
+
+ cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
+ mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+ crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+ nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
+ nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
+ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
+ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
+
+#ifdef BCMDBG_SI
+ AP6210_DEBUG("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, eromptr - 1, nmw, nsw, nmp, nsp);
+#else
+ BCM_REFERENCE(crev);
+#endif
+
+ if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
+ continue;
+ if ((nmw + nsw == 0)) {
+ /* A component which is not a core */
+ if (cid == OOB_ROUTER_CORE_ID) {
+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
+ &addrl, &addrh, &sizel, &sizeh);
+ if (asd != 0) {
+ sii->oob_router = addrl;
+ }
+ }
+ if (cid != GMAC_COMMON_4706_CORE_ID)
+ continue;
+ }
+
+ idx = sii->numcores;
+
+ sii->cia[idx] = cia;
+ sii->cib[idx] = cib;
+ sii->coreid[idx] = remap_coreid(sih, cid);
+
+ for (i = 0; i < nmp; i++) {
+ mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
+ if ((mpd & ER_TAG) != ER_MP) {
+ AP6210_ERR("Not enough MP entries for component 0x%x\n", cid);
+ goto error;
+ }
+ AP6210_DEBUG(" Master port %d, mp: %d id: %d\n", i,
+ (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
+ (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT);
+ }
+
+ /* First Slave Address Descriptor should be port 0:
+ * the main register space for the core
+ */
+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh);
+ if (asd == 0) {
+ do {
+ /* Try again to see if it is a bridge */
+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh,
+ &sizel, &sizeh);
+ if (asd != 0)
+ br = TRUE;
+ else {
+ if (br == TRUE) {
+ break;
+ }
+ else if ((addrh != 0) || (sizeh != 0) ||
+ (sizel != SI_CORE_SIZE)) {
+ AP6210_ERR("addrh = 0x%x\t sizeh = 0x%x\t size1 ="
+ "0x%x\n", addrh, sizeh, sizel);
+ AP6210_ERR("First Slave ASD for"
+ "core 0x%04x malformed "
+ "(0x%08x)\n", cid, asd);
+ goto error;
+ }
+ }
+ } while (1);
+ }
+ sii->coresba[idx] = addrl;
+ sii->coresba_size[idx] = sizel;
+ /* Get any more ASDs in port 0 */
+ j = 1;
+ do {
+ asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh,
+ &sizel, &sizeh);
+ if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
+ sii->coresba2[idx] = addrl;
+ sii->coresba2_size[idx] = sizel;
+ }
+ j++;
+ } while (asd != 0);
+
+ /* Go through the ASDs for other slave ports */
+ for (i = 1; i < nsp; i++) {
+ j = 0;
+ do {
+ asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh,
+ &sizel, &sizeh);
+
+ if (asd == 0)
+ break;
+ j++;
+ } while (1);
+ if (j == 0) {
+ AP6210_ERR(" SP %d has no address descriptors\n", i);
+ goto error;
+ }
+ }
+
+ /* Now get master wrappers */
+ for (i = 0; i < nmw; i++) {
+ asd = get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, &addrh,
+ &sizel, &sizeh);
+ if (asd == 0) {
+ AP6210_ERR("Missing descriptor for MW %d\n", i);
+ goto error;
+ }
+ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+ AP6210_ERR("Master wrapper %d is not 4KB\n", i);
+ goto error;
+ }
+ if (i == 0)
+ sii->wrapba[idx] = addrl;
+ }
+
+ /* And finally slave wrappers */
+ for (i = 0; i < nsw; i++) {
+ uint fwp = (nsp == 1) ? 0 : 1;
+ asd = get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, &addrl, &addrh,
+ &sizel, &sizeh);
+ if (asd == 0) {
+ AP6210_ERR("Missing descriptor for SW %d\n", i);
+ goto error;
+ }
+ if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+ AP6210_ERR("Slave wrapper %d is not 4KB\n", i);
+ goto error;
+ }
+ if ((nmw == 0) && (i == 0))
+ sii->wrapba[idx] = addrl;
+ }
+
+
+ /* Don't record bridges */
+ if (br)
+ continue;
+
+ /* Done with core */
+ sii->numcores++;
+ }
+
+ AP6210_ERR("Reached end of erom without finding END");
+
+error:
+ sii->numcores = 0;
+ return;
+}
+
+/* This function changes the logical "focus" to the indicated core.
+ * Return the current core's virtual address.
+ */
+void *
+ai_setcoreidx(si_t *sih, uint coreidx)
+{
+ si_info_t *sii = SI_INFO(sih);
+ uint32 addr, wrap;
+ void *regs;
+
+ if (coreidx >= MIN(sii->numcores, SI_MAXCORES))
+ return (NULL);
+
+ addr = sii->coresba[coreidx];
+ wrap = sii->wrapba[coreidx];
+
+ /*
+ * If the user has provided an interrupt mask enabled function,
+ * then assert interrupts are disabled before switching the core.
+ */
+ ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg));
+
+ switch (BUSTYPE(sih->bustype)) {
+ case SI_BUS:
+ /* map new one */
+ if (!sii->regs[coreidx]) {
+ sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE);
+ ASSERT(GOODREGS(sii->regs[coreidx]));
+ }
+ sii->curmap = regs = sii->regs[coreidx];
+ if (!sii->wrappers[coreidx]) {
+ sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
+ ASSERT(GOODREGS(sii->wrappers[coreidx]));
+ }
+ sii->curwrap = sii->wrappers[coreidx];
+ break;
+
+
+ case SPI_BUS:
+ case SDIO_BUS:
+ sii->curmap = regs = (void *)((uintptr)addr);
+ sii->curwrap = (void *)((uintptr)wrap);
+ break;
+
+ case PCMCIA_BUS:
+ default:
+ ASSERT(0);
+ regs = NULL;
+ break;
+ }
+
+ sii->curmap = regs;
+ sii->curidx = coreidx;
+
+ return regs;
+}
+
+void
+ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size)
+{
+ si_info_t *sii = SI_INFO(sih);
+ chipcregs_t *cc = NULL;
+ uint32 erombase, *eromptr, *eromlim;
+ uint i, j, cidx;
+ uint32 cia, cib, nmp, nsp;
+ uint32 asd, addrl, addrh, sizel, sizeh;
+
+ for (i = 0; i < sii->numcores; i++) {
+ if (sii->coreid[i] == CC_CORE_ID) {
+ cc = (chipcregs_t *)sii->regs[i];
+ break;
+ }
+ }
+ if (cc == NULL)
+ goto error;
+
+ erombase = R_REG(sii->osh, &cc->eromptr);
+ eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE);
+ eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32));
+
+ cidx = sii->curidx;
+ cia = sii->cia[cidx];
+ cib = sii->cib[cidx];
+
+ nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
+ nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
+
+ /* scan for cores */
+ while (eromptr < eromlim) {
+ if ((get_erom_ent(sih, &eromptr, ER_TAG, ER_CI) == cia) &&
+ (get_erom_ent(sih, &eromptr, 0, 0) == cib)) {
+ break;
+ }
+ }
+
+ /* skip master ports */
+ for (i = 0; i < nmp; i++)
+ get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
+
+ /* Skip ASDs in port 0 */
+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh);
+ if (asd == 0) {
+ /* Try again to see if it is a bridge */
+ asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh,
+ &sizel, &sizeh);
+ }
+
+ j = 1;
+ do {
+ asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh,
+ &sizel, &sizeh);
+ j++;
+ } while (asd != 0);
+
+ /* Go through the ASDs for other slave ports */
+ for (i = 1; i < nsp; i++) {
+ j = 0;
+ do {
+ asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh,
+ &sizel, &sizeh);
+ if (asd == 0)
+ break;
+
+ if (!asidx--) {
+ *addr = addrl;
+ *size = sizel;
+ return;
+ }
+ j++;
+ } while (1);
+
+ if (j == 0) {
+ AP6210_ERR(" SP %d has no address descriptors\n", i);
+ break;
+ }
+ }
+
+error:
+ *size = 0;
+ return;
+}
+
+/* Return the number of address spaces in current core */
+int
+ai_numaddrspaces(si_t *sih)
+{
+ return 2;
+}
+
+/* Return the address of the nth address space in the current core */
+uint32
+ai_addrspace(si_t *sih, uint asidx)
+{
+ si_info_t *sii;
+ uint cidx;
+
+ sii = SI_INFO(sih);
+ cidx = sii->curidx;
+
+ if (asidx == 0)
+ return sii->coresba[cidx];
+ else if (asidx == 1)
+ return sii->coresba2[cidx];
+ else {
+ AP6210_ERR("%s: Need to parse the erom again to find addr space %d\n",
+ __FUNCTION__, asidx);
+ return 0;
+ }
+}
+
+/* Return the size of the nth address space in the current core */
+uint32
+ai_addrspacesize(si_t *sih, uint asidx)
+{
+ si_info_t *sii;
+ uint cidx;
+
+ sii = SI_INFO(sih);
+ cidx = sii->curidx;
+
+ if (asidx == 0)
+ return sii->coresba_size[cidx];
+ else if (asidx == 1)
+ return sii->coresba2_size[cidx];
+ else {
+ AP6210_ERR("%s: Need to parse the erom again to find addr space %d\n",
+ __FUNCTION__, asidx);
+ return 0;
+ }
+}
+
+uint
+ai_flag(si_t *sih)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+
+ sii = SI_INFO(sih);
+ if (BCM47162_DMP()) {
+ AP6210_ERR("%s: Attempting to read MIPS DMP registers on 47162a0", __FUNCTION__);
+ return sii->curidx;
+ }
+ if (BCM5357_DMP()) {
+ AP6210_ERR("%s: Attempting to read USB20H DMP registers on 5357b0\n", __FUNCTION__);
+ return sii->curidx;
+ }
+ ai = sii->curwrap;
+
+ return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f);
+}
+
+void
+ai_setint(si_t *sih, int siflag)
+{
+}
+
+uint
+ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
+{
+ si_info_t *sii = SI_INFO(sih);
+ uint32 *map = (uint32 *) sii->curwrap;
+
+ if (mask || val) {
+ uint32 w = R_REG(sii->osh, map+(offset/4));
+ w &= ~mask;
+ w |= val;
+ W_REG(sii->osh, map+(offset/4), val);
+ }
+
+ return (R_REG(sii->osh, map+(offset/4)));
+}
+
+uint
+ai_corevendor(si_t *sih)
+{
+ si_info_t *sii;
+ uint32 cia;
+
+ sii = SI_INFO(sih);
+ cia = sii->cia[sii->curidx];
+ return ((cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT);
+}
+
+uint
+ai_corerev(si_t *sih)
+{
+ si_info_t *sii;
+ uint32 cib;
+
+ sii = SI_INFO(sih);
+ cib = sii->cib[sii->curidx];
+ return remap_corerev(sih, (cib & CIB_REV_MASK) >> CIB_REV_SHIFT);
+}
+
+bool
+ai_iscoreup(si_t *sih)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+
+ sii = SI_INFO(sih);
+ ai = sii->curwrap;
+
+ return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) &&
+ ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0));
+}
+
+/*
+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
+ * switch back to the original core, and return the new value.
+ *
+ * When using the silicon backplane, no fiddling with interrupts or core switches is needed.
+ *
+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers
+ * and (on newer pci cores) chipcommon registers.
+ */
+uint
+ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+ uint origidx = 0;
+ uint32 *r = NULL;
+ uint w;
+ uint intr_val = 0;
+ bool fast = FALSE;
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ ASSERT(GOODIDX(coreidx));
+ ASSERT(regoff < SI_CORE_SIZE);
+ ASSERT((val & ~mask) == 0);
+
+ if (coreidx >= SI_MAXCORES)
+ return 0;
+
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ /* If internal bus, we can always get at everything */
+ fast = TRUE;
+ /* map if does not exist */
+ if (!sii->regs[coreidx]) {
+ sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
+ SI_CORE_SIZE);
+ ASSERT(GOODREGS(sii->regs[coreidx]));
+ }
+ r = (uint32 *)((uchar *)sii->regs[coreidx] + regoff);
+ } else if (BUSTYPE(sih->bustype) == PCI_BUS) {
+ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
+
+ if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+ /* Chipc registers are mapped at 12KB */
+
+ fast = TRUE;
+ r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff);
+ } else if (sii->pub.buscoreidx == coreidx) {
+ /* pci registers are at either in the last 2KB of an 8KB window
+ * or, in pcie and pci rev 13 at 8KB
+ */
+ fast = TRUE;
+ if (SI_FAST(sii))
+ r = (uint32 *)((char *)sii->curmap +
+ PCI_16KB0_PCIREGS_OFFSET + regoff);
+ else
+ r = (uint32 *)((char *)sii->curmap +
+ ((regoff >= SBCONFIGOFF) ?
+ PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
+ regoff);
+ }
+ }
+
+ if (!fast) {
+ INTR_OFF(sii, intr_val);
+
+ /* save current core index */
+ origidx = si_coreidx(&sii->pub);
+
+ /* switch core */
+ r = (uint32*) ((uchar*) ai_setcoreidx(&sii->pub, coreidx) + regoff);
+ }
+ ASSERT(r != NULL);
+
+ /* mask and set */
+ if (mask || val) {
+ w = (R_REG(sii->osh, r) & ~mask) | val;
+ W_REG(sii->osh, r, w);
+ }
+
+ /* readback */
+ w = R_REG(sii->osh, r);
+
+ if (!fast) {
+ /* restore core index */
+ if (origidx != coreidx)
+ ai_setcoreidx(&sii->pub, origidx);
+
+ INTR_RESTORE(sii, intr_val);
+ }
+
+ return (w);
+}
+
+void
+ai_core_disable(si_t *sih, uint32 bits)
+{
+ si_info_t *sii;
+ volatile uint32 dummy;
+ uint32 status;
+ aidmp_t *ai;
+
+ sii = SI_INFO(sih);
+
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ /* if core is already in reset, just return */
+ if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET)
+ return;
+
+ /* ensure there are no pending backplane operations */
+ SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
+
+ /* if pending backplane ops still, try waiting longer */
+ if (status != 0) {
+ /* 300usecs was sufficient to allow backplane ops to clear for big hammer */
+ /* during driver load we may need more time */
+ SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 10000);
+ /* if still pending ops, continue on and try disable anyway */
+ /* this is in big hammer path, so don't call wl_reinit in this case... */
+ }
+
+ W_REG(sii->osh, &ai->ioctrl, bits);
+ dummy = R_REG(sii->osh, &ai->ioctrl);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(10);
+
+ W_REG(sii->osh, &ai->resetctrl, AIRC_RESET);
+ dummy = R_REG(sii->osh, &ai->resetctrl);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(1);
+}
+
+/* reset and re-enable a core
+ * inputs:
+ * bits - core specific bits that are set during and after reset sequence
+ * resetbits - core specific bits that are set only during reset sequence
+ */
+void
+ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+ volatile uint32 dummy;
+
+ sii = SI_INFO(sih);
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ /*
+ * Must do the disable sequence first to work for arbitrary current core state.
+ */
+ ai_core_disable(sih, (bits | resetbits));
+
+ /*
+ * Now do the initialization sequence.
+ */
+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
+ dummy = R_REG(sii->osh, &ai->ioctrl);
+ BCM_REFERENCE(dummy);
+
+ W_REG(sii->osh, &ai->resetctrl, 0);
+ dummy = R_REG(sii->osh, &ai->resetctrl);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(1);
+
+ W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN));
+ dummy = R_REG(sii->osh, &ai->ioctrl);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(1);
+}
+
+void
+ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+
+ if (BCM47162_DMP()) {
+ AP6210_ERR("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+ __FUNCTION__);
+ return;
+ }
+ if (BCM5357_DMP()) {
+ AP6210_ERR("%s: Accessing USB20H DMP register (ioctrl) on 5357\n",
+ __FUNCTION__);
+ return;
+ }
+
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ ASSERT((val & ~mask) == 0);
+
+ if (mask || val) {
+ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val);
+ W_REG(sii->osh, &ai->ioctrl, w);
+ }
+}
+
+uint32
+ai_core_cflags(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+ if (BCM47162_DMP()) {
+ AP6210_ERR("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+ __FUNCTION__);
+ return 0;
+ }
+ if (BCM5357_DMP()) {
+ AP6210_ERR("%s: Accessing USB20H DMP register (ioctrl) on 5357\n",
+ __FUNCTION__);
+ return 0;
+ }
+
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ ASSERT((val & ~mask) == 0);
+
+ if (mask || val) {
+ w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val);
+ W_REG(sii->osh, &ai->ioctrl, w);
+ }
+
+ return R_REG(sii->osh, &ai->ioctrl);
+}
+
+uint32
+ai_core_sflags(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ aidmp_t *ai;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+ if (BCM47162_DMP()) {
+ AP6210_ERR("%s: Accessing MIPS DMP register (iostatus) on 47162a0",
+ __FUNCTION__);
+ return 0;
+ }
+ if (BCM5357_DMP()) {
+ AP6210_ERR("%s: Accessing USB20H DMP register (iostatus) on 5357\n",
+ __FUNCTION__);
+ return 0;
+ }
+
+ ASSERT(GOODREGS(sii->curwrap));
+ ai = sii->curwrap;
+
+ ASSERT((val & ~mask) == 0);
+ ASSERT((mask & ~SISF_CORE_BITS) == 0);
+
+ if (mask || val) {
+ w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val);
+ W_REG(sii->osh, &ai->iostatus, w);
+ }
+
+ return R_REG(sii->osh, &ai->iostatus);
+}
diff --git a/drivers/net/wireless/ap6210/ap6210.h b/drivers/net/wireless/ap6210/ap6210.h
new file mode 100644
index 0000000..90e7d8d
--- /dev/null
+++ b/drivers/net/wireless/ap6210/ap6210.h
@@ -0,0 +1,22 @@
+#ifndef __AP6210_H__
+#define __AP6210_H__
+
+#define AP6210_EMERG(...) pr_emerg("[ap6210] "__VA_ARGS__)
+#define AP6210_ALERT(...) pr_alert("[ap6210] "__VA_ARGS__)
+#define AP6210_CRIT(...) pr_crit("[ap6210] "__VA_ARGS__)
+#define AP6210_ERR(...) pr_err("[ap6210] "__VA_ARGS__)
+#define AP6210_WARN(...) pr_warn("[ap6210] "__VA_ARGS__)
+#define AP6210_NOTICE(...) pr_notice("[ap6210] "__VA_ARGS__)
+#define AP6210_INFO(...) pr_info("[ap6210] "__VA_ARGS__)
+#define AP6210_DEBUG(...) pr_debug("[ap6210] "__VA_ARGS__)
+#define AP6210_DUMP(...) pr_debug(__VA_ARGS__)
+#define AP6210_CONT(...) pr_cont(__VA_ARGS__)
+
+extern int __init sw_rfkill_init(void);
+extern void __exit sw_rfkill_exit(void);
+
+extern int __init ap6210_gpio_wifi_init(void);
+extern void __exit ap6210_gpio_wifi_exit(void);
+
+
+#endif /* __AP6210_H__ */
diff --git a/drivers/net/wireless/ap6210/ap6210_gpio.h b/drivers/net/wireless/ap6210/ap6210_gpio.h
new file mode 100644
index 0000000..96a3166
--- /dev/null
+++ b/drivers/net/wireless/ap6210/ap6210_gpio.h
@@ -0,0 +1,9 @@
+#ifndef __AP6210_GPIO_H__
+#define __AP6210_GPIO_H__
+
+extern int ap6210_gpio_wifi_get_mod_type(void);
+extern int ap6210_gpio_wifi_gpio_ctrl(char* name, int level);
+extern void ap6210_gpio_wifi_power(int on);
+extern char *ap6210_gpio_wifi_get_name(int module_sel);
+
+#endif /* __AP6210_GPIO_H__ */
diff --git a/drivers/net/wireless/ap6210/ap6210_gpio_bt.c b/drivers/net/wireless/ap6210/ap6210_gpio_bt.c
new file mode 100644
index 0000000..4686615
--- /dev/null
+++ b/drivers/net/wireless/ap6210/ap6210_gpio_bt.c
@@ -0,0 +1,164 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/rfkill.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <plat/sys_config.h>
+
+#if (defined CONFIG_MMC)
+#include "ap6210_gpio.h"
+#else
+static __inline int ap6210_gpio_wifi_get_mod_type(void)
+{
+ AP6210_DEBUG("%s : not implemented!\n", __FUNCTION__ );
+ return 0;
+}
+static __inline int ap6210_gpio_wifi_gpio_ctrl(char* name, int level)
+{
+ AP6210_DEBUG("%s : not implemented!\n", __FUNCTION__ );
+ return -1;
+}
+#endif
+
+#include <ap6210.h>
+
+static const char bt_name[] = "bcm40183";
+static struct rfkill *sw_rfkill;
+static int bt_used;
+
+static int rfkill_set_power(void *data, bool blocked)
+{
+ unsigned int mod_sel = ap6210_gpio_wifi_get_mod_type();
+
+ AP6210_DEBUG("rfkill set power %s\n", ( blocked ? "blocked" : "unblocked" ));
+
+ switch (mod_sel)
+ {
+ case 2: /* bcm40183 */
+ if (!blocked) {
+ ap6210_gpio_wifi_gpio_ctrl("bcm40183_bt_regon", 1);
+ ap6210_gpio_wifi_gpio_ctrl("bcm40183_bt_rst", 1);
+ } else {
+ ap6210_gpio_wifi_gpio_ctrl("bcm40183_bt_rst", 0);
+ ap6210_gpio_wifi_gpio_ctrl("bcm40183_bt_regon", 0);
+ }
+ AP6210_ERR("Using %s configuration.\n", ap6210_gpio_wifi_get_name(mod_sel) );
+ break;
+ case 3: /* realtek rtl8723as */
+ if (!blocked) {
+ ap6210_gpio_wifi_gpio_ctrl("rtk_rtl8723as_bt_dis", 1);
+ } else {
+ ap6210_gpio_wifi_gpio_ctrl("rtk_rtl8723as_bt_dis", 0);
+ }
+ AP6210_ERR("Using %s configuration.\n", ap6210_gpio_wifi_get_name(mod_sel) );
+ break;
+ case 7: /* ap6210 */
+ case 8: /* ap6330 */
+ if (!blocked) {
+ ap6210_gpio_wifi_gpio_ctrl("ap6xxx_bt_regon", 1);
+ } else {
+ ap6210_gpio_wifi_gpio_ctrl("ap6xxx_bt_regon", 0);
+ }
+ AP6210_ERR("Using %s configuration.\n", ap6210_gpio_wifi_get_name(mod_sel) );
+ break;
+ case 10: /* realtek rtl8723au */
+ if (!blocked) {
+ ap6210_gpio_wifi_gpio_ctrl("rtl8723au_bt", 1);
+ } else {
+ ap6210_gpio_wifi_gpio_ctrl("rtl8723au_bt", 0);
+ }
+ AP6210_ERR("Using %s configuration.\n", ap6210_gpio_wifi_get_name(mod_sel) );
+ break;
+ default:
+ AP6210_ERR("no bluetooth module matched.\n" );
+ }
+
+ msleep(10);
+ return 0;
+}
+
+static struct rfkill_ops sw_rfkill_ops = {
+ .set_block = rfkill_set_power,
+};
+
+static int sw_rfkill_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ sw_rfkill = rfkill_alloc(bt_name, &pdev->dev,
+ RFKILL_TYPE_BLUETOOTH, &sw_rfkill_ops, NULL);
+ if (unlikely(!sw_rfkill)) {
+ AP6210_DEBUG("Unable to alocate rfkill structure.\n" );
+ return -ENOMEM;
+ }
+
+ ret = rfkill_register(sw_rfkill);
+ if (unlikely(ret)) {
+ AP6210_DEBUG("Unable to register rfkill structure.\n" );
+ rfkill_destroy(sw_rfkill);
+ }
+ AP6210_DEBUG("rfkill structure registered successfully.\n" );
+ return ret;
+}
+
+static int sw_rfkill_remove(struct platform_device *pdev)
+{
+ if (likely(sw_rfkill)) {
+ rfkill_unregister(sw_rfkill);
+ rfkill_destroy(sw_rfkill);
+ AP6210_DEBUG("rfkill structure removed successfully.\n" );
+ }
+
+ return 0;
+}
+
+static struct platform_driver sw_rfkill_driver = {
+ .probe = sw_rfkill_probe,
+ .remove = sw_rfkill_remove,
+ .driver = {
+ .name = "sunxi-rfkill",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_device sw_rfkill_dev = {
+ .name = "sunxi-rfkill",
+};
+
+int __init sw_rfkill_init(void)
+{
+ if (SCRIPT_PARSER_OK != script_parser_fetch("bt_para", "bt_used", &bt_used, 1)) {
+ AP6210_DEBUG("parse bt_used failed in script.fex.\n" );
+ return -1;
+ }
+
+ if (!bt_used) {
+ AP6210_ERR("bluetooth is disable in script.fex.\n" );
+ return 0;
+ }
+
+ platform_device_register(&sw_rfkill_dev);
+ AP6210_ERR("platform device registered successfully.\n" );
+ return platform_driver_register(&sw_rfkill_driver);
+}
+
+void __exit sw_rfkill_exit(void)
+{
+ if (!bt_used) {
+ AP6210_ERR("exit no bt used in configuration\n" );
+ return ;
+ }
+
+ platform_device_unregister(&sw_rfkill_dev);
+ platform_driver_unregister(&sw_rfkill_driver);
+}
+
+/*
+module_init(sw_rfkill_init);
+module_exit(sw_rfkill_exit);
+
+MODULE_DESCRIPTION("sunxi-rfkill driver");
+MODULE_AUTHOR("Aaron.magic<mgaic@reuuimllatech.com>");
+MODULE_LICENSE("GPL");
+*/
+
diff --git a/drivers/net/wireless/ap6210/ap6210_gpio_wifi.c b/drivers/net/wireless/ap6210/ap6210_gpio_wifi.c
new file mode 100644
index 0000000..13e0bdf
--- /dev/null
+++ b/drivers/net/wireless/ap6210/ap6210_gpio_wifi.c
@@ -0,0 +1,433 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <plat/sys_config.h>
+#include <mach/gpio.h>
+#include <mach/clock.h>
+#include <linux/proc_fs.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <ap6210.h>
+
+static char* wifi_para = "wifi_para";
+
+struct ap6210_gpio_wifi_ops {
+ char* mod_name;
+ int wifi_used;
+ int sdio_id;
+ int usb_id;
+ int module_sel;
+ int (*gpio_ctrl)(char* name, int level);
+ void (*standby)(int in);
+ void (*power)(int mode, int *updown);
+
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *proc_root;
+ struct proc_dir_entry *proc_power;
+#endif /* CONFIG_PROC_FS */
+};
+
+static int ap6210_wl_regon = 0;
+static int ap6210_bt_regon = 0;
+
+struct ap6210_gpio_wifi_ops ap6210_wifi_select_pm_ops;
+
+char *ap6210_gpio_wifi_get_name(int module_sel) {
+ char* mod_name[] = { " ",
+ "bcm40181", /* 1 - BCM40181(BCM4330)*/
+ "bcm40183", /* 2 - BCM40183(BCM4330)*/
+ "rtl8723as", /* 3 - RTL8723AS(RF-SM02B) */
+ "rtl8189es", /* 4 - RTL8189ES(SM89E00) */
+ "rtl8192cu", /* 5 - RTL8192CU*/
+ "rtl8188eu", /* 6 - RTL8188EU*/
+ "ap6210", /* 7 - AP6210*/
+ "ap6330", /* 8 - AP6330*/
+ "ap6181", /* 9 - AP6181*/
+ "rtl8723au", /* 10 - RTL8723AU */
+ };
+
+ return(mod_name[module_sel]);
+}
+
+EXPORT_SYMBOL(ap6210_gpio_wifi_get_name);
+
+static int ap6210_gpio_ctrl(char* name, int level)
+{
+ int i = 0;
+ int ret = 0;
+ int gpio = 0;
+ char * gpio_name[2] = {"ap6210_wl_regon", "ap6210_bt_regon"};
+
+ for (i = 0; i < 2; i++) {
+ if (strcmp(name, gpio_name[i]) == 0) {
+ switch (i)
+ {
+ case 0: /*ap6210_wl_regon*/
+ gpio = ap6210_wl_regon;
+ break;
+ case 1: /*ap6210_bt_regon*/
+ gpio = ap6210_bt_regon;
+ break;
+ default:
+ AP6210_ERR("no matched gpio.\n" );
+ }
+ break;
+ }
+ }
+
+ ret = gpio_write_one_pin_value(gpio, level, name);
+
+ return 0;
+}
+
+static int ap6210_gpio_read(char* name)
+{
+ int i = 0;
+ int gpio = 0;
+ int val = 0;
+ char * gpio_name[2] = {"ap6210_wl_regon", "ap6210_bt_regon"};
+
+ for (i = 0; i < 2; i++) {
+ if (strcmp(name, gpio_name[i]) == 0) {
+ switch (i)
+ {
+ case 0: /*ap6210_wl_regon*/
+ gpio = ap6210_wl_regon;
+ break;
+ case 1: /*ap6210_bt_regon*/
+ gpio = ap6210_bt_regon;
+ break;
+ default:
+ AP6210_ERR("no matched gpio.\n" );
+ }
+ break;
+ }
+ }
+
+ val = gpio_read_one_pin_value(gpio, name);
+
+ return val;
+}
+
+
+void ap6210_power(int mode, int *updown)
+{
+ if (mode) {
+ if (*updown) {
+ ap6210_gpio_ctrl("ap6210_wl_regon", 1);
+ mdelay(100);
+ } else {
+ ap6210_gpio_ctrl("ap6210_wl_regon", 0);
+ mdelay(100);
+ }
+ AP6210_DEBUG("sdio wifi power state: %s\n", *updown ? "on" : "off");
+ } else {
+ *updown = ap6210_gpio_read("ap6210_wl_regon");
+ }
+
+ return;
+}
+
+static void ap6210_cfg_gpio_32k_clkout(int gpio_index)
+{
+ int ret;
+ struct clk *clk_32k, *parent;
+
+ parent = clk_get(NULL, CLK_SYS_LOSC);
+ clk_32k = clk_get(NULL, CLK_MOD_OUTA);
+ ret = clk_set_parent(clk_32k, parent);
+
+ if(ret){
+ AP6210_ERR("32k clk_set_parent fail.\n" );
+ return;
+ }
+
+ ret = clk_set_rate(clk_32k, 32768);
+ if(ret){
+ AP6210_ERR("32k clk_set_rate fail.\n" );
+ return;
+ }
+
+ clk_enable(clk_32k);
+}
+void ap6210_gpio_init(void)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+ int ap6210_lpo = 0;
+
+/* CT expected ap6210_lpo as a GPIO */
+ ap6210_lpo = gpio_request_ex(wifi_para, "ap6xxx_lpo");
+ if (!ap6210_lpo) {
+ AP6210_ERR("request lpo gpio failed.\n" );
+ return;
+ }
+
+ if(ap6210_lpo) {
+ AP6210_DEBUG("config 32k clock.\n" );
+ ap6210_cfg_gpio_32k_clkout(ap6210_lpo);
+ }
+
+ ap6210_wl_regon = gpio_request_ex(wifi_para, "ap6xxx_wl_regon");
+ if (!ap6210_wl_regon) {
+ AP6210_ERR("request wl_regon gpio failed.\n" );
+ return;
+ }
+
+ ap6210_bt_regon = gpio_request_ex(wifi_para, "ap6xxx_bt_regon");
+ if (!ap6210_bt_regon) {
+ AP6210_ERR("request ap6210_bt_regon gpio failed.\n" );
+ return;
+ }
+
+ ops->gpio_ctrl = ap6210_gpio_ctrl;
+ ops->power = ap6210_power;
+}
+
+int ap6210_gpio_wifi_get_mod_type(void)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+ if (ops->wifi_used)
+ return ops->module_sel;
+ else {
+ AP6210_ERR("No wifi type selected, please check your config.\n" );
+ return 0;
+ }
+}
+EXPORT_SYMBOL(ap6210_gpio_wifi_get_mod_type);
+
+int ap6210_gpio_wifi_gpio_ctrl(char* name, int level)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+ if (ops->wifi_used && ops->gpio_ctrl)
+ return ops->gpio_ctrl(name, level);
+ else {
+ AP6210_ERR("No wifi type selected, please check your config.\n" );
+ return -1;
+ }
+}
+EXPORT_SYMBOL(ap6210_gpio_wifi_gpio_ctrl);
+
+void ap6210_gpio_wifi_power(int on)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+ int power = on;
+
+ if (ops->wifi_used && ops->power)
+ return ops->power(1, &power);
+ else {
+ AP6210_ERR("No wifi type selected, please check your config.\n" );
+ return;
+ }
+}
+EXPORT_SYMBOL(ap6210_gpio_wifi_power);
+
+#ifdef CONFIG_PROC_FS
+static int ap6210_gpio_wifi_power_stat(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ struct ap6210_gpio_wifi_ops *ops = (struct ap6210_gpio_wifi_ops *)data;
+ char *p = page;
+ int power = 0;
+
+ if (ops->power)
+ ops->power(0, &power);
+
+ p += sprintf(p, "%s : power state %s\n", ops->mod_name, power ? "on" : "off");
+ return p - page;
+}
+
+static int ap6210_gpio_wifi_power_ctrl(struct file *file, const char __user *buffer, unsigned long count, void *data)
+{
+ struct ap6210_gpio_wifi_ops *ops = (struct ap6210_gpio_wifi_ops *)data;
+ int power = simple_strtoul(buffer, NULL, 10);
+
+ power = power ? 1 : 0;
+ if (ops->power)
+ ops->power(1, &power);
+ else
+ AP6210_ERR("No power control for %s\n", ops->mod_name);
+ return sizeof(power);
+}
+
+static inline void awwifi_procfs_attach(void)
+{
+ char proc_rootname[] = "driver/ap6210_gpio_wifi";
+ char proc_powername[] = "power";
+
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+
+ ops->proc_root = proc_mkdir(proc_rootname, NULL);
+ if (IS_ERR(ops->proc_root))
+ {
+ AP6210_ERR("failed to create procfs \"%s\".\n", proc_rootname );
+ }
+
+ ops->proc_power = create_proc_entry(proc_powername, 0644, ops->proc_root);
+ if (IS_ERR(ops->proc_power))
+ {
+ AP6210_ERR("failed to create procfs \"%s\".\n", proc_powername);
+ }
+ ops->proc_power->data = ops;
+ ops->proc_power->read_proc = ap6210_gpio_wifi_power_stat;
+ ops->proc_power->write_proc = ap6210_gpio_wifi_power_ctrl;
+}
+
+static inline void awwifi_procfs_remove(void)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+ char proc_rootname[] = "driver/ap6210_gpio_wifi";
+
+ remove_proc_entry("power", ops->proc_root);
+ remove_proc_entry(proc_rootname, NULL);
+}
+#else
+static inline void awwifi_procfs_attach(void) {}
+static inline void awwifi_procfs_remove(void) {}
+#endif
+
+
+
+static int ap6210_gpio_wifi_get_res(void)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+
+ if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_used", &ops->wifi_used, 1)) {
+ AP6210_ERR("parse wifi_used failed in script.fex.\n" );
+ return -1;
+ }
+ if (!ops->wifi_used) {
+ AP6210_ERR("wifi pm disable in script.fex.\n" );
+ return -1;
+ }
+
+ if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_sdc_id", &ops->sdio_id, 1)) {
+ AP6210_ERR("parse wifi_sdc_id in script.fex failed.\n" );
+ return -1;
+ }
+
+ if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_usbc_id", &ops->usb_id, 1)) {
+ AP6210_ERR("parse wifi_sdc_id in script.fex failed.\n" );
+ return -1;
+ }
+
+ if (SCRIPT_PARSER_OK != script_parser_fetch(wifi_para, "wifi_mod_sel", &ops->module_sel, 1)) {
+ AP6210_ERR("parse wifi_sdc_id in script.fex failed.\n" );
+ return -1;
+ }
+
+ ops->mod_name = ap6210_gpio_wifi_get_name(ops->module_sel);
+
+ AP6210_ERR("select wifi %s\n", ops->mod_name);
+
+ return 0;
+}
+
+static int __devinit ap6210_gpio_wifi_probe(struct platform_device *pdev)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+
+ switch (ops->module_sel) {
+ case 1: /* BCM40181 */
+ case 2: /* BCM40183 */
+ case 3: /* RTL8723AS */
+ case 4: /* RTL8189ES */
+ case 5: /* RTL8192CU */
+ case 6: /* RTL8188EU */
+ AP6210_ERR("Unsupported device.\n");
+ break;
+ case 7: /* AP6210 */
+ case 8: /* AP6330 */
+ case 9: /* AP6181 */
+ AP6210_ERR("Initializing %s.\n", ops->mod_name);
+ ap6210_gpio_init();
+ break;
+ case 10: /* RTL8723AU */
+ AP6210_ERR("Unsupported device.\n");
+ break;
+ default:
+ AP6210_ERR("Unsupported device.\n");
+ }
+
+ awwifi_procfs_attach();
+ AP6210_DEBUG("wifi gpio attached.\n" );
+ return 0;
+}
+
+static int __devexit ap6210_gpio_wifi_remove(struct platform_device *pdev)
+{
+ awwifi_procfs_remove();
+ AP6210_DEBUG("wifi gpio released.\n" );
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ap6210_gpio_wifi_suspend(struct device *dev)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+
+ if (ops->standby)
+ ops->standby(1);
+ return 0;
+}
+
+static int ap6210_gpio_wifi_resume(struct device *dev)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+
+ if (ops->standby)
+ ops->standby(0);
+ return 0;
+}
+
+static struct dev_pm_ops wifi_dev_pm_ops = {
+ .suspend = ap6210_gpio_wifi_suspend,
+ .resume = ap6210_gpio_wifi_resume,
+};
+#endif
+
+static struct platform_device ap6210_gpio_wifi_dev = {
+ .name = "ap6210_gpio_wifi",
+};
+
+static struct platform_driver ap6210_gpio_wifi_driver = {
+ .driver.name = "ap6210_gpio_wifi",
+ .driver.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .driver.pm = &wifi_dev_pm_ops,
+#endif
+ .probe = ap6210_gpio_wifi_probe,
+ .remove = __devexit_p(ap6210_gpio_wifi_remove),
+};
+
+int __init ap6210_gpio_wifi_init(void)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+
+ memset(ops, 0, sizeof(struct ap6210_gpio_wifi_ops));
+ ap6210_gpio_wifi_get_res();
+ if (!ops->wifi_used)
+ return 0;
+
+ platform_device_register(&ap6210_gpio_wifi_dev);
+ return platform_driver_register(&ap6210_gpio_wifi_driver);
+}
+
+void __exit ap6210_gpio_wifi_exit(void)
+{
+ struct ap6210_gpio_wifi_ops *ops = &ap6210_wifi_select_pm_ops;
+ if (!ops->wifi_used)
+ return;
+
+ platform_driver_unregister(&ap6210_gpio_wifi_driver);
+ memset(ops, 0, sizeof(struct ap6210_gpio_wifi_ops));
+}
+
+/*
+module_init(ap6210_gpio_wifi_init);
+module_exit(ap6210_gpio_wifi_exit);
+
+MODULE_LICENSE("GPL");
+*/
\ No newline at end of file
diff --git a/drivers/net/wireless/ap6210/bcmevent.c b/drivers/net/wireless/ap6210/bcmevent.c
new file mode 100644
index 0000000..16e2fca
--- /dev/null
+++ b/drivers/net/wireless/ap6210/bcmevent.c
@@ -0,0 +1,152 @@
+/*
+ * bcmevent read-only data shared by kernel or app layers
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ * $Id: bcmevent.c 370587 2012-11-22 09:32:38Z $
+ */
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <proto/ethernet.h>
+#include <proto/bcmeth.h>
+#include <proto/bcmevent.h>
+#include <ap6210.h>
+
+#if WLC_E_LAST != 107
+#error "You need to add an entry to bcmevent_names[] for the new event"
+#endif
+
+const bcmevent_name_t bcmevent_names[] = {
+ { WLC_E_SET_SSID, "SET_SSID" },
+ { WLC_E_JOIN, "JOIN" },
+ { WLC_E_START, "START" },
+ { WLC_E_AUTH, "AUTH" },
+ { WLC_E_AUTH_IND, "AUTH_IND" },
+ { WLC_E_DEAUTH, "DEAUTH" },
+ { WLC_E_DEAUTH_IND, "DEAUTH_IND" },
+ { WLC_E_ASSOC, "ASSOC" },
+ { WLC_E_ASSOC_IND, "ASSOC_IND" },
+ { WLC_E_REASSOC, "REASSOC" },
+ { WLC_E_REASSOC_IND, "REASSOC_IND" },
+ { WLC_E_DISASSOC, "DISASSOC" },
+ { WLC_E_DISASSOC_IND, "DISASSOC_IND" },
+ { WLC_E_QUIET_START, "START_QUIET" },
+ { WLC_E_QUIET_END, "END_QUIET" },
+ { WLC_E_BEACON_RX, "BEACON_RX" },
+ { WLC_E_LINK, "LINK" },
+ { WLC_E_MIC_ERROR, "MIC_ERROR" },
+ { WLC_E_NDIS_LINK, "NDIS_LINK" },
+ { WLC_E_ROAM, "ROAM" },
+ { WLC_E_TXFAIL, "TXFAIL" },
+ { WLC_E_PMKID_CACHE, "PMKID_CACHE" },
+ { WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF" },
+ { WLC_E_PRUNE, "PRUNE" },
+ { WLC_E_AUTOAUTH, "AUTOAUTH" },
+ { WLC_E_EAPOL_MSG, "EAPOL_MSG" },
+ { WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE" },
+ { WLC_E_ADDTS_IND, "ADDTS_IND" },
+ { WLC_E_DELTS_IND, "DELTS_IND" },
+ { WLC_E_BCNSENT_IND, "BCNSENT_IND" },
+ { WLC_E_BCNRX_MSG, "BCNRX_MSG" },
+ { WLC_E_BCNLOST_MSG, "BCNLOST_IND" },
+ { WLC_E_ROAM_PREP, "ROAM_PREP" },
+ { WLC_E_PFN_NET_FOUND, "PFNFOUND_IND" },
+ { WLC_E_PFN_NET_LOST, "PFNLOST_IND" },
+#if defined(IBSS_PEER_DISCOVERY_EVENT)
+ { WLC_E_IBSS_ASSOC, "IBSS_ASSOC" },
+#endif /* defined(IBSS_PEER_DISCOVERY_EVENT) */
+ { WLC_E_RADIO, "RADIO" },
+ { WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG" },
+ { WLC_E_PROBREQ_MSG, "PROBE_REQ_MSG" },
+ { WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND" },
+ { WLC_E_PSK_SUP, "PSK_SUP" },
+ { WLC_E_COUNTRY_CODE_CHANGED, "CNTRYCODE_IND" },
+ { WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME" },
+ { WLC_E_ICV_ERROR, "ICV_ERROR" },
+ { WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" },
+ { WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" },
+ { WLC_E_TRACE, "TRACE" },
+#ifdef WLBTAMP
+ { WLC_E_BTA_HCI_EVENT, "BTA_HCI_EVENT" },
+#endif
+ { WLC_E_IF, "IF" },
+#ifdef WLP2P
+ { WLC_E_P2P_DISC_LISTEN_COMPLETE, "WLC_E_P2P_DISC_LISTEN_COMPLETE" },
+#endif
+ { WLC_E_RSSI, "RSSI" },
+ { WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE" },
+ { WLC_E_EXTLOG_MSG, "EXTERNAL LOG MESSAGE" },
+#ifdef WIFI_ACT_FRAME
+ { WLC_E_ACTION_FRAME, "ACTION_FRAME" },
+ { WLC_E_ACTION_FRAME_RX, "ACTION_FRAME_RX" },
+ { WLC_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" },
+#endif
+#ifdef BCMWAPI_WAI
+ { WLC_E_WAI_STA_EVENT, "WAI_STA_EVENT" },
+ { WLC_E_WAI_MSG, "WAI_MSG" },
+#endif /* BCMWAPI_WAI */
+#if 0 && (NDISVER >= 0x0620)
+ { WLC_E_PRE_ASSOC_IND, "ASSOC_RECV" },
+ { WLC_E_PRE_REASSOC_IND, "REASSOC_RECV" },
+ { WLC_E_CHANNEL_ADOPTED, "CHANNEL_ADOPTED" },
+ { WLC_E_AP_STARTED, "AP_STARTED" },
+ { WLC_E_DFS_AP_STOP, "DFS_AP_STOP" },
+ { WLC_E_DFS_AP_RESUME, "DFS_AP_RESUME" },
+ { WLC_E_ASSOC_IND_NDIS, "ASSOC_IND_NDIS"},
+ { WLC_E_REASSOC_IND_NDIS, "REASSOC_IND_NDIS"},
+ { WLC_E_ACTION_FRAME_RX_NDIS, "WLC_E_ACTION_FRAME_RX_NDIS" },
+ { WLC_E_AUTH_REQ, "WLC_E_AUTH_REQ" },
+#endif
+ { WLC_E_ESCAN_RESULT, "WLC_E_ESCAN_RESULT" },
+ { WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "WLC_E_AF_OFF_CHAN_COMPLETE" },
+#ifdef WLP2P
+ { WLC_E_PROBRESP_MSG, "PROBE_RESP_MSG" },
+ { WLC_E_P2P_PROBREQ_MSG, "P2P PROBE_REQ_MSG" },
+#endif
+#ifdef PROP_TXSTATUS
+ { WLC_E_FIFO_CREDIT_MAP, "FIFO_CREDIT_MAP" },
+#endif
+ { WLC_E_WAKE_EVENT, "WAKE_EVENT" },
+ { WLC_E_DCS_REQUEST, "DCS_REQUEST" },
+ { WLC_E_RM_COMPLETE, "RM_COMPLETE" },
+#ifdef WLMEDIA_HTSF
+ { WLC_E_HTSFSYNC, "HTSF_SYNC_EVENT" },
+#endif
+ { WLC_E_OVERLAY_REQ, "OVERLAY_REQ_EVENT" },
+ { WLC_E_CSA_COMPLETE_IND, "WLC_E_CSA_COMPLETE_IND"},
+ { WLC_E_EXCESS_PM_WAKE_EVENT, "EXCESS_PM_WAKE_EVENT" },
+ { WLC_E_PFN_SCAN_NONE, "PFN_SCAN_NONE" },
+ { WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" },
+#ifdef SOFTAP
+ { WLC_E_GTK_PLUMBED, "GTK_PLUMBED" },
+#endif
+ { WLC_E_ASSOC_REQ_IE, "ASSOC_REQ_IE" },
+ { WLC_E_ASSOC_RESP_IE, "ASSOC_RESP_IE" },
+ { WLC_E_ACTION_FRAME_RX_NDIS, "WLC_E_ACTION_FRAME_RX_NDIS" },
+#ifdef WLTDLS
+ { WLC_E_TDLS_PEER_EVENT, "TDLS_PEER_EVENT" },
+#endif /* WLTDLS */
+ { WLC_E_SERVICE_FOUND, "SERVICE_FOUND" },
+ { WLC_E_P2PO_ADD_DEVICE, "P2PO_DEV_FOUND" },
+ { WLC_E_P2PO_DEL_DEVICE, "P2PO_DEV_LOST" },
+};
+
+const int bcmevent_names_size = ARRAYSIZE(bcmevent_names);
diff --git a/drivers/net/wireless/ap6210/bcmsdh.c b/drivers/net/wireless/ap6210/bcmsdh.c
new file mode 100644
index 0000000..ca59ff8
--- /dev/null
+++ b/drivers/net/wireless/ap6210/bcmsdh.c
@@ -0,0 +1,778 @@
+/*
+ * BCMSDH interface glue
+ * implement bcmsdh API for SDIOH driver
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdh.c 373330 2012-12-07 04:46:17Z $
+ */
+
+/**
+ * @file bcmsdh.c
+ */
+
+/* ****************** BCMSDH Interface Functions *************************** */
+
+#include <typedefs.h>
+#include <bcmdevs.h>
+#include <bcmendian.h>
+#include <bcmutils.h>
+#include <hndsoc.h>
+#include <siutils.h>
+#include <osl.h>
+
+#include <bcmsdh.h> /* BRCM API for SDIO clients (such as wl, dhd) */
+#include <bcmsdbus.h> /* common SDIO/controller interface */
+#include <sbsdio.h> /* SDIO device core hardware definitions. */
+
+#include <sdio.h> /* SDIO Device and Protocol Specs */
+
+#include <ap6210.h>
+
+#define SDIOH_API_ACCESS_RETRY_LIMIT 2
+const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
+
+/**
+ * BCMSDH API context
+ */
+struct bcmsdh_info
+{
+ bool init_success; /* underlying driver successfully attached */
+ void *sdioh; /* handler for sdioh */
+ uint32 vendevid; /* Target Vendor and Device ID on SD bus */
+ osl_t *osh;
+ bool regfail; /* Save status of last reg_read/reg_write call */
+ uint32 sbwad; /* Save backplane window address */
+};
+/* local copy of bcm sd handler */
+bcmsdh_info_t * l_bcmsdh = NULL;
+
+#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+extern int
+sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
+
+void
+bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
+{
+ sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
+}
+#endif
+
+#if defined(HW_OOB)
+#include <sbchipc.h>
+void
+bcmsdh_config_hw_oob_intr(bcmsdh_info_t *sdh, uint chip)
+{
+ uint32 gpiocontrol, addr;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+ if (CHIPID(chip) == BCM43362_CHIP_ID) {
+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol);
+ gpiocontrol = bcmsdh_reg_read(sdh, addr, 4);
+ gpiocontrol |= 0x2;
+ bcmsdh_reg_write(sdh, addr, 4, gpiocontrol);
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL);
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL);
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL);
+ }
+}
+#endif
+
+/* Attach BCMSDH layer to SDIO Host Controller Driver
+ *
+ * @param osh OSL Handle.
+ * @param cfghdl Configuration Handle.
+ * @param regsva Virtual address of controller registers.
+ * @param irq Interrupt number of SDIO controller.
+ *
+ * @return bcmsdh_info_t Handle to BCMSDH context.
+ */
+bcmsdh_info_t *
+bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq)
+{
+ bcmsdh_info_t *bcmsdh;
+
+ if ((bcmsdh = (bcmsdh_info_t *)MALLOC(osh, sizeof(bcmsdh_info_t))) == NULL) {
+ BCMSDH_ERROR(("bcmsdh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh)));
+ return NULL;
+ }
+ bzero((char *)bcmsdh, sizeof(bcmsdh_info_t));
+
+ /* save the handler locally */
+ l_bcmsdh = bcmsdh;
+
+ if (!(bcmsdh->sdioh = sdioh_attach(osh, cfghdl, irq))) {
+ bcmsdh_detach(osh, bcmsdh);
+ return NULL;
+ }
+
+ bcmsdh->osh = osh;
+ bcmsdh->init_success = TRUE;
+
+ *regsva = (uint32 *)SI_ENUM_BASE;
+
+ /* Report the BAR, to fix if needed */
+ bcmsdh->sbwad = SI_ENUM_BASE;
+ return bcmsdh;
+}
+
+int
+bcmsdh_detach(osl_t *osh, void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ if (bcmsdh != NULL) {
+ if (bcmsdh->sdioh) {
+ sdioh_detach(osh, bcmsdh->sdioh);
+ bcmsdh->sdioh = NULL;
+ }
+ MFREE(osh, bcmsdh, sizeof(bcmsdh_info_t));
+ }
+
+ l_bcmsdh = NULL;
+ return 0;
+}
+
+int
+bcmsdh_iovar_op(void *sdh, const char *name,
+ void *params, int plen, void *arg, int len, bool set)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
+}
+
+bool
+bcmsdh_intr_query(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ bool on;
+
+ ASSERT(bcmsdh);
+ status = sdioh_interrupt_query(bcmsdh->sdioh, &on);
+ if (SDIOH_API_SUCCESS(status))
+ return FALSE;
+ else
+ return on;
+}
+
+int
+bcmsdh_intr_enable(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ ASSERT(bcmsdh);
+
+ status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE);
+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_intr_disable(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ ASSERT(bcmsdh);
+
+ status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE);
+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ ASSERT(bcmsdh);
+
+ status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_intr_dereg(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ ASSERT(bcmsdh);
+
+ status = sdioh_interrupt_deregister(bcmsdh->sdioh);
+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+#if defined(DHD_DEBUG)
+bool
+bcmsdh_intr_pending(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ ASSERT(sdh);
+ return sdioh_interrupt_pending(bcmsdh->sdioh);
+}
+#endif
+
+
+int
+bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+{
+ ASSERT(sdh);
+
+ /* don't support yet */
+ return BCME_UNSUPPORTED;
+}
+
+/**
+ * Read from SDIO Configuration Space
+ * @param sdh SDIO Host context.
+ * @param func_num Function number to read from.
+ * @param addr Address to read from.
+ * @param err Error return.
+ * @return value read from SDIO configuration space.
+ */
+uint8
+bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+ int32 retry = 0;
+#endif
+ uint8 data = 0;
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ ASSERT(bcmsdh->init_success);
+
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+ do {
+ if (retry) /* wait for 1 ms till bus get settled down */
+ OSL_DELAY(1000);
+#endif
+ status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+ } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
+#endif
+ if (err)
+ *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+
+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
+ fnc_num, addr, data));
+
+ return data;
+}
+
+void
+bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+ int32 retry = 0;
+#endif
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ ASSERT(bcmsdh->init_success);
+
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+ do {
+ if (retry) /* wait for 1 ms till bus get settled down */
+ OSL_DELAY(1000);
+#endif
+ status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+ } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
+#endif
+ if (err)
+ *err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
+
+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
+ fnc_num, addr, data));
+}
+
+uint32
+bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ uint32 data = 0;
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ ASSERT(bcmsdh->init_success);
+
+ status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, fnc_num,
+ addr, &data, 4);
+
+ if (err)
+ *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+
+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__,
+ fnc_num, addr, data));
+
+ return data;
+}
+
+void
+bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ ASSERT(bcmsdh->init_success);
+
+ status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, fnc_num,
+ addr, &data, 4);
+
+ if (err)
+ *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+
+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, fnc_num,
+ addr, data));
+}
+
+
+int
+bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+
+ uint8 *tmp_buf, *tmp_ptr;
+ uint8 *ptr;
+ bool ascii = func & ~0xf;
+ func &= 0x7;
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ ASSERT(bcmsdh->init_success);
+ ASSERT(cis);
+ ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
+
+ status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length);
+
+ if (ascii) {
+ /* Move binary bits to tmp and format them into the provided buffer. */
+ if ((tmp_buf = (uint8 *)MALLOC(bcmsdh->osh, length)) == NULL) {
+ BCMSDH_ERROR(("%s: out of memory\n", __FUNCTION__));
+ return BCME_NOMEM;
+ }
+ bcopy(cis, tmp_buf, length);
+ for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) {
+ ptr += snprintf((char*)ptr, (cis + length - ptr - 4),
+ "%.2x ", *tmp_ptr & 0xff);
+ if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
+ ptr += snprintf((char *)ptr, (cis + length - ptr -4), "\n");
+ }
+ MFREE(bcmsdh->osh, tmp_buf, length);
+ }
+
+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+
+int
+bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set)
+{
+ int err = 0;
+ uint bar0 = address & ~SBSDIO_SB_OFT_ADDR_MASK;
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ if (bar0 != bcmsdh->sbwad || force_set) {
+ bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
+ (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
+ if (!err)
+ bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
+ (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
+ if (!err)
+ bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
+ (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err);
+
+ if (!err)
+ bcmsdh->sbwad = bar0;
+ else
+ /* invalidate cached window var */
+ bcmsdh->sbwad = 0;
+
+ }
+
+ return err;
+}
+
+uint32
+bcmsdh_reg_read(void *sdh, uint32 addr, uint size)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ uint32 word = 0;
+
+ BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __FUNCTION__, addr));
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ ASSERT(bcmsdh->init_success);
+
+ if (bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))
+ return 0xFFFFFFFF;
+
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
+ if (size == 4)
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+ status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+ SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
+
+ bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+
+ BCMSDH_INFO(("uint32data = 0x%x\n", word));
+
+ /* if ok, return appropriately masked word */
+ if (SDIOH_API_SUCCESS(status)) {
+ switch (size) {
+ case sizeof(uint8):
+ return (word & 0xff);
+ case sizeof(uint16):
+ return (word & 0xffff);
+ case sizeof(uint32):
+ return word;
+ default:
+ bcmsdh->regfail = TRUE;
+
+ }
+ }
+
+ /* otherwise, bad sdio access or invalid size */
+ BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __FUNCTION__, addr, size));
+ return 0xFFFFFFFF;
+}
+
+uint32
+bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ int err = 0;
+
+ BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
+ __FUNCTION__, addr, size*8, data));
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ ASSERT(bcmsdh->init_success);
+
+ if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)))
+ return err;
+
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
+ if (size == 4)
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+ status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1,
+ addr, &data, size);
+ bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+
+ if (SDIOH_API_SUCCESS(status))
+ return 0;
+
+ BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
+ __FUNCTION__, data, addr, size));
+ return 0xFFFFFFFF;
+}
+
+bool
+bcmsdh_regfail(void *sdh)
+{
+ return ((bcmsdh_info_t *)sdh)->regfail;
+}
+
+int
+bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags,
+ uint8 *buf, uint nbytes, void *pkt,
+ bcmsdh_cmplt_fn_t complete_fn, void *handle)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ uint incr_fix;
+ uint width;
+ int err = 0;
+
+ ASSERT(bcmsdh);
+ ASSERT(bcmsdh->init_success);
+
+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+ __FUNCTION__, fn, addr, nbytes));
+
+ /* Async not implemented yet */
+ ASSERT(!(flags & SDIO_REQ_ASYNC));
+ if (flags & SDIO_REQ_ASYNC)
+ return BCME_UNSUPPORTED;
+
+ if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)))
+ return err;
+
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
+
+ incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
+ width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+ if (width == 4)
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+ status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
+ SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
+
+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+}
+
+int
+bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags,
+ uint8 *buf, uint nbytes, void *pkt,
+ bcmsdh_cmplt_fn_t complete_fn, void *handle)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+ uint incr_fix;
+ uint width;
+ int err = 0;
+
+ ASSERT(bcmsdh);
+ ASSERT(bcmsdh->init_success);
+
+ BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+ __FUNCTION__, fn, addr, nbytes));
+
+ /* Async not implemented yet */
+ ASSERT(!(flags & SDIO_REQ_ASYNC));
+ if (flags & SDIO_REQ_ASYNC)
+ return BCME_UNSUPPORTED;
+
+ if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)))
+ return err;
+
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
+
+ incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
+ width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+ if (width == 4)
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+ status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
+ SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
+
+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ SDIOH_API_RC status;
+
+ ASSERT(bcmsdh);
+ ASSERT(bcmsdh->init_success);
+ ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
+
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+ status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC,
+ (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
+ addr, 4, nbytes, buf, NULL);
+
+ return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_abort(void *sdh, uint fn)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ return sdioh_abort(bcmsdh->sdioh, fn);
+}
+
+int
+bcmsdh_start(void *sdh, int stage)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ return sdioh_start(bcmsdh->sdioh, stage);
+}
+
+int
+bcmsdh_stop(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ return sdioh_stop(bcmsdh->sdioh);
+}
+
+int
+bcmsdh_waitlockfree(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ return sdioh_waitlockfree(bcmsdh->sdioh);
+}
+
+
+int
+bcmsdh_query_device(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0;
+ return (bcmsdh->vendevid);
+}
+
+uint
+bcmsdh_query_iofnum(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ return (sdioh_query_iofnum(bcmsdh->sdioh));
+}
+
+int
+bcmsdh_reset(bcmsdh_info_t *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ return sdioh_sdio_reset(bcmsdh->sdioh);
+}
+
+void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh)
+{
+ ASSERT(sdh);
+ return sdh->sdioh;
+}
+
+/* Function to pass device-status bits to DHD. */
+uint32
+bcmsdh_get_dstatus(void *sdh)
+{
+ return 0;
+}
+uint32
+bcmsdh_cur_sbwad(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
+ return (bcmsdh->sbwad);
+}
+
+void
+bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev)
+{
+ return;
+}
+
+
+int
+bcmsdh_sleep(void *sdh, bool enab)
+{
+#ifdef SDIOH_SLEEP_ENABLED
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+ return sdioh_sleep(sd, enab);
+#else
+ return BCME_UNSUPPORTED;
+#endif
+}
+
+int
+bcmsdh_gpio_init(void *sdh)
+{
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+ return sdioh_gpio_init(sd);
+}
+
+bool
+bcmsdh_gpioin(void *sdh, uint32 gpio)
+{
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+ return sdioh_gpioin(sd, gpio);
+}
+
+int
+bcmsdh_gpioouten(void *sdh, uint32 gpio)
+{
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+ return sdioh_gpioouten(sd, gpio);
+}
+
+int
+bcmsdh_gpioout(void *sdh, uint32 gpio, bool enab)
+{
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+ return sdioh_gpioout(sd, gpio, enab);
+}
+
+#ifdef BCMSDIOH_TXGLOM
+void
+bcmsdh_glom_post(void *sdh, uint8 *frame, uint len)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ sdioh_glom_post(bcmsdh->sdioh, frame, len);
+}
+
+void
+bcmsdh_glom_clear(void *sdh)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ sdioh_glom_clear(bcmsdh->sdioh);
+}
+
+uint
+bcmsdh_set_mode(void *sdh, uint mode)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+ return (sdioh_set_mode(bcmsdh->sdioh, mode));
+}
+
+bool
+bcmsdh_glom_enabled(void)
+{
+ return (sdioh_glom_enabled());
+}
+#endif /* BCMSDIOH_TXGLOM */
diff --git a/drivers/net/wireless/ap6210/bcmsdh_linux.c b/drivers/net/wireless/ap6210/bcmsdh_linux.c
new file mode 100644
index 0000000..71bb3d9
--- /dev/null
+++ b/drivers/net/wireless/ap6210/bcmsdh_linux.c
@@ -0,0 +1,796 @@
+/*
+ * SDIO access interface for drivers - linux specific (pci only)
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdh_linux.c 373359 2012-12-07 06:36:37Z $
+ */
+
+/**
+ * @file bcmsdh_linux.c
+ */
+
+#define __UNDEF_NO_VERSION__
+
+#include <typedefs.h>
+#include <linuxver.h>
+
+#include <linux/pci.h>
+#include <linux/completion.h>
+
+#include <osl.h>
+#include <pcicfg.h>
+#include <bcmdefs.h>
+#include <bcmdevs.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+
+#if defined(OOB_INTR_ONLY)
+#include <linux/irq.h>
+extern void dhdsdio_isr(void * args);
+#include <bcmutils.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <mach/gpio.h>
+#include <plat/sys_config.h>
+#endif
+
+#include <ap6210.h>
+
+/**
+ * SDIO Host Controller info
+ */
+typedef struct bcmsdh_hc bcmsdh_hc_t;
+
+struct bcmsdh_hc {
+ bcmsdh_hc_t *next;
+#ifdef BCMPLATFORM_BUS
+ struct device *dev; /* platform device handle */
+#else
+ struct pci_dev *dev; /* pci device handle */
+#endif /* BCMPLATFORM_BUS */
+ osl_t *osh;
+ void *regs; /* SDIO Host Controller address */
+ bcmsdh_info_t *sdh; /* SDIO Host Controller handle */
+ void *ch;
+ unsigned int oob_irq;
+ unsigned long oob_flags; /* OOB Host specifiction as edge and etc */
+ bool oob_irq_registered;
+ bool oob_irq_enable_flag;
+#if defined(OOB_INTR_ONLY)
+ spinlock_t irq_lock;
+#endif
+};
+static bcmsdh_hc_t *sdhcinfo = NULL;
+
+/* driver info, initialized when bcmsdh_register is called */
+static bcmsdh_driver_t drvinfo = {NULL, NULL};
+
+/**
+ * Checks to see if vendor and device IDs match a supported SDIO Host Controller.
+ */
+bool
+bcmsdh_chipmatch(uint16 vendor, uint16 device)
+{
+ /* Add other vendors and devices as required */
+
+#ifdef BCMSDIOH_STD
+ /* Check for Arasan host controller */
+ if (vendor == VENDOR_SI_IMAGE) {
+ return (TRUE);
+ }
+ /* Check for BRCM 27XX Standard host controller */
+ if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) {
+ return (TRUE);
+ }
+ /* Check for BRCM Standard host controller */
+ if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) {
+ return (TRUE);
+ }
+ /* Check for TI PCIxx21 Standard host controller */
+ if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) {
+ return (TRUE);
+ }
+ if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) {
+ return (TRUE);
+ }
+ /* Ricoh R5C822 Standard SDIO Host */
+ if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) {
+ return (TRUE);
+ }
+ /* JMicron Standard SDIO Host */
+ if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) {
+ return (TRUE);
+ }
+
+#endif /* BCMSDIOH_STD */
+#ifdef BCMSDIOH_SPI
+ /* This is the PciSpiHost. */
+ if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) {
+ AP6210_ERR("Found PCI SPI Host Controller\n");
+ return (TRUE);
+ }
+
+#endif /* BCMSDIOH_SPI */
+
+ return (FALSE);
+}
+
+#if defined(BCMPLATFORM_BUS)
+#if defined(BCMLXSDMMC)
+/* forward declarations */
+int bcmsdh_probe(struct device *dev);
+int bcmsdh_remove(struct device *dev);
+
+EXPORT_SYMBOL(bcmsdh_probe);
+EXPORT_SYMBOL(bcmsdh_remove);
+
+#else
+/* forward declarations */
+static int __devinit bcmsdh_probe(struct device *dev);
+static int __devexit bcmsdh_remove(struct device *dev);
+#endif
+
+#if !defined(BCMLXSDMMC)
+static
+#endif
+int bcmsdh_probe(struct device *dev)
+{
+ osl_t *osh = NULL;
+ bcmsdh_hc_t *sdhc = NULL;
+ ulong regs = 0;
+ bcmsdh_info_t *sdh = NULL;
+#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
+ struct platform_device *pdev;
+ struct resource *r;
+#endif
+ int irq = 0;
+ uint32 vendevid;
+ unsigned long irq_flags = 0;
+
+#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
+ pdev = to_platform_device(dev);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!r || irq == NO_IRQ)
+ return -ENXIO;
+#endif
+
+#if defined(OOB_INTR_ONLY)
+#ifdef HW_OOB
+ irq_flags =
+ IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE;
+#else
+ irq_flags = IRQF_TRIGGER_FALLING;
+#endif /* HW_OOB */
+
+ /* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */
+ irq = dhd_customer_oob_irq_map(&irq_flags);
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
+ /* Do not disable this IRQ during suspend */
+ irq_flags |= IRQF_NO_SUSPEND;
+#endif /* defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) */
+ if (irq < 0) {
+ AP6210_ERR("%s: Host irq is not defined\n", __FUNCTION__);
+ return 1;
+ }
+#endif
+ /* allocate SDIO Host Controller state info */
+ if (!(osh = osl_attach(dev, PCI_BUS, FALSE))) {
+ AP6210_ERR("%s: osl_attach failed\n", __FUNCTION__);
+ goto err;
+ }
+ if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) {
+ AP6210_ERR("%s: out of memory, allocated %d bytes\n",
+ __FUNCTION__,
+ MALLOCED(osh));
+ goto err;
+ }
+ bzero(sdhc, sizeof(bcmsdh_hc_t));
+ sdhc->osh = osh;
+
+ sdhc->dev = (void *)dev;
+
+#if defined(BCMLXSDMMC)
+ if (!(sdh = bcmsdh_attach(osh, (void *)0,
+ (void **)&regs, irq))) {
+ AP6210_ERR("%s: bcmsdh_attach failed\n", __FUNCTION__);
+ goto err;
+ }
+#else
+ if (!(sdh = bcmsdh_attach(osh, (void *)r->start,
+ (void **)&regs, irq))) {
+ AP6210_ERR("%s: bcmsdh_attach failed\n", __FUNCTION__);
+ goto err;
+ }
+#endif
+ sdhc->sdh = sdh;
+ sdhc->oob_irq = irq;
+ sdhc->oob_flags = irq_flags;
+ sdhc->oob_irq_registered = FALSE; /* to make sure.. */
+ sdhc->oob_irq_enable_flag = FALSE;
+#if defined(OOB_INTR_ONLY)
+ spin_lock_init(&sdhc->irq_lock);
+#endif
+
+ /* chain SDIO Host Controller info together */
+ sdhc->next = sdhcinfo;
+ sdhcinfo = sdhc;
+
+ /* Read the vendor/device ID from the CIS */
+ vendevid = bcmsdh_query_device(sdh);
+ /* try to attach to the target device */
+ if (!(sdhc->ch = drvinfo.attach((vendevid >> 16),
+ (vendevid & 0xFFFF), 0, 0, 0, 0,
+ (void *)regs, NULL, sdh))) {
+ AP6210_ERR("%s: device attach failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ return 0;
+
+ /* error handling */
+err:
+ if (sdhc) {
+ if (sdhc->sdh)
+ bcmsdh_detach(sdhc->osh, sdhc->sdh);
+ MFREE(osh, sdhc, sizeof(bcmsdh_hc_t));
+ }
+ if (osh)
+ osl_detach(osh);
+ return -ENODEV;
+}
+
+#if !defined(BCMLXSDMMC)
+static
+#endif
+int bcmsdh_remove(struct device *dev)
+{
+ bcmsdh_hc_t *sdhc, *prev;
+ osl_t *osh;
+
+ sdhc = sdhcinfo;
+ drvinfo.detach(sdhc->ch);
+ bcmsdh_detach(sdhc->osh, sdhc->sdh);
+
+ /* find the SDIO Host Controller state for this pdev and take it out from the list */
+ for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
+ if (sdhc->dev == (void *)dev) {
+ if (prev)
+ prev->next = sdhc->next;
+ else
+ sdhcinfo = NULL;
+ break;
+ }
+ prev = sdhc;
+ }
+ if (!sdhc) {
+ AP6210_ERR("%s: failed\n", __FUNCTION__);
+ return 0;
+ }
+
+ /* release SDIO Host Controller info */
+ osh = sdhc->osh;
+ MFREE(osh, sdhc, sizeof(bcmsdh_hc_t));
+ osl_detach(osh);
+
+#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY)
+ dev_set_drvdata(dev, NULL);
+#endif
+
+ return 0;
+}
+
+#else /* BCMPLATFORM_BUS */
+
+#if !defined(BCMLXSDMMC)
+/* forward declarations for PCI probe and remove functions. */
+static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev);
+
+/**
+ * pci id table
+ */
+static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = {
+ { vendor: PCI_ANY_ID,
+ device: PCI_ANY_ID,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+ class: 0,
+ class_mask: 0,
+ driver_data: 0,
+ },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid);
+
+/**
+ * SDIO Host Controller pci driver info
+ */
+static struct pci_driver bcmsdh_pci_driver = {
+ node: {},
+ name: "bcmsdh",
+ id_table: bcmsdh_pci_devid,
+ probe: bcmsdh_pci_probe,
+ remove: bcmsdh_pci_remove,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+ save_state: NULL,
+#endif
+ suspend: NULL,
+ resume: NULL,
+ };
+
+
+extern uint sd_pci_slot; /* Force detection to a particular PCI */
+ /* slot only . Allows for having multiple */
+ /* WL devices at once in a PC */
+ /* Only one instance of dhd will be */
+ /* usable at a time */
+ /* Upper word is bus number, */
+ /* lower word is slot number */
+ /* Default value of 0xffffffff turns this */
+ /* off */
+module_param(sd_pci_slot, uint, 0);
+
+
+/**
+ * Detect supported SDIO Host Controller and attach if found.
+ *
+ * Determine if the device described by pdev is a supported SDIO Host
+ * Controller. If so, attach to it and attach to the target device.
+ */
+static int __devinit
+bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ osl_t *osh = NULL;
+ bcmsdh_hc_t *sdhc = NULL;
+ ulong regs;
+ bcmsdh_info_t *sdh = NULL;
+ int rc;
+
+ if (sd_pci_slot != 0xFFFFffff) {
+ if (pdev->bus->number != (sd_pci_slot>>16) ||
+ PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) {
+ AP6210_DEBUG("%s: %s: bus %X, slot %X, vend %X, dev %X\n",
+ __FUNCTION__,
+ bcmsdh_chipmatch(pdev->vendor, pdev->device)
+ ?"Found compatible SDIOHC"
+ :"Probing unknown device",
+ pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor,
+ pdev->device);
+ return -ENODEV;
+ }
+ AP6210_DEBUG("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n",
+ __FUNCTION__,
+ bcmsdh_chipmatch(pdev->vendor, pdev->device)
+ ?"Using compatible SDIOHC"
+ :"WARNING, forced use of unkown device",
+ pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device);
+ }
+
+ if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) ||
+ (pdev->device == PCIXX21_FLASHMEDIA0_ID))) {
+ uint32 config_reg;
+
+ AP6210_ERR("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__);
+ if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) {
+ AP6210_ERR("%s: osl_attach failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4);
+
+ /*
+ * Set MMC_SD_DIS bit in FlashMedia Controller.
+ * Disbling the SD/MMC Controller in the FlashMedia Controller
+ * allows the Standard SD Host Controller to take over control
+ * of the SD Slot.
+ */
+ config_reg |= 0x02;
+ OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg);
+ osl_detach(osh);
+ }
+ /* match this pci device with what we support */
+ /* we can't solely rely on this to believe it is our SDIO Host Controller! */
+ if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) {
+ return -ENODEV;
+ }
+
+ /* this is a pci device we might support */
+ AP6210_ERR("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n",
+ __FUNCTION__,
+ pdev->bus->number, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), pdev->irq);
+
+ /* use bcmsdh_query_device() to get the vendor ID of the target device so
+ * it will eventually appear in the Broadcom string on the console
+ */
+
+ /* allocate SDIO Host Controller state info */
+ if (!(osh = osl_attach(pdev, PCI_BUS, FALSE))) {
+ AP6210_ERR("%s: osl_attach failed\n", __FUNCTION__);
+ goto err;
+ }
+ if (!(sdhc = MALLOC(osh, sizeof(bcmsdh_hc_t)))) {
+ AP6210_ERR("%s: out of memory, allocated %d bytes\n",
+ __FUNCTION__,
+ MALLOCED(osh));
+ goto err;
+ }
+ bzero(sdhc, sizeof(bcmsdh_hc_t));
+ sdhc->osh = osh;
+
+ sdhc->dev = pdev;
+
+ /* map to address where host can access */
+ pci_set_master(pdev);
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ AP6210_ERR("%s: Cannot enable PCI device\n", __FUNCTION__);
+ goto err;
+ }
+ if (!(sdh = bcmsdh_attach(osh, (void *)(uintptr)pci_resource_start(pdev, 0),
+ (void **)&regs, pdev->irq))) {
+ AP6210_ERR("%s: bcmsdh_attach failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ sdhc->sdh = sdh;
+
+ /* try to attach to the target device */
+ if (!(sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */
+ bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0,
+ (void *)regs, NULL, sdh))) {
+ AP6210_ERR("%s: device attach failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ /* chain SDIO Host Controller info together */
+ sdhc->next = sdhcinfo;
+ sdhcinfo = sdhc;
+
+ return 0;
+
+ /* error handling */
+err:
+ if (sdhc) {
+ if (sdhc->sdh)
+ bcmsdh_detach(sdhc->osh, sdhc->sdh);
+ MFREE(osh, sdhc, sizeof(bcmsdh_hc_t));
+ }
+ if (osh)
+ osl_detach(osh);
+ return -ENODEV;
+}
+
+
+/**
+ * Detach from target devices and SDIO Host Controller
+ */
+static void __devexit
+bcmsdh_pci_remove(struct pci_dev *pdev)
+{
+ bcmsdh_hc_t *sdhc, *prev;
+ osl_t *osh;
+
+ /* find the SDIO Host Controller state for this pdev and take it out from the list */
+ for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
+ if (sdhc->dev == pdev) {
+ if (prev)
+ prev->next = sdhc->next;
+ else
+ sdhcinfo = NULL;
+ break;
+ }
+ prev = sdhc;
+ }
+ if (!sdhc)
+ return;
+
+ drvinfo.detach(sdhc->ch);
+
+ bcmsdh_detach(sdhc->osh, sdhc->sdh);
+
+ /* release SDIO Host Controller info */
+ osh = sdhc->osh;
+ MFREE(osh, sdhc, sizeof(bcmsdh_hc_t));
+ osl_detach(osh);
+}
+#endif /* BCMLXSDMMC */
+#endif /* BCMPLATFORM_BUS */
+
+extern int sdio_function_init(void);
+
+extern int sdio_func_reg_notify(void* semaphore);
+extern void sdio_func_unreg_notify(void);
+
+#if defined(BCMLXSDMMC)
+int bcmsdh_reg_sdio_notify(void* semaphore)
+{
+ return sdio_func_reg_notify(semaphore);
+}
+
+void bcmsdh_unreg_sdio_notify(void)
+{
+ sdio_func_unreg_notify();
+}
+#endif /* defined(BCMLXSDMMC) */
+
+int
+bcmsdh_register(bcmsdh_driver_t *driver)
+{
+ int error = 0;
+
+ drvinfo = *driver;
+
+#if defined(BCMPLATFORM_BUS)
+ AP6210_ERR("Linux Kernel SDIO/MMC Driver\n");
+ error = sdio_function_init();
+ return error;
+#endif /* defined(BCMPLATFORM_BUS) */
+
+#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+ if (!(error = pci_module_init(&bcmsdh_pci_driver)))
+ return 0;
+#else
+ if (!(error = pci_register_driver(&bcmsdh_pci_driver)))
+ return 0;
+#endif
+
+ AP6210_ERR("%s: pci_module_init failed 0x%x\n", __FUNCTION__, error);
+#endif /* BCMPLATFORM_BUS */
+
+ return error;
+}
+
+extern void sdio_function_cleanup(void);
+
+void
+bcmsdh_unregister(void)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+ if (bcmsdh_pci_driver.node.next)
+#endif
+
+#if defined(BCMLXSDMMC)
+ sdio_function_cleanup();
+#endif /* BCMLXSDMMC */
+
+#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
+ pci_unregister_driver(&bcmsdh_pci_driver);
+#endif /* BCMPLATFORM_BUS */
+}
+
+int bcmsdh_set_drvdata(void * dhdp)
+{
+ AP6210_DEBUG("%s Enter \n", __FUNCTION__);
+
+ dev_set_drvdata(sdhcinfo->dev, dhdp);
+
+ return 0;
+}
+
+#if defined(OOB_INTR_ONLY)
+#define CONFIG_ARCH_SUN6I_AP6210 1
+
+void bcmsdh_oob_intr_set(bool enable)
+{
+ static bool curstate = 1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdhcinfo->irq_lock, flags);
+ if (curstate != enable) {
+ if(enable) {
+ enable_irq(sdhcinfo->oob_irq);
+ }
+ else {
+ disable_irq_nosync(sdhcinfo->oob_irq);
+ }
+ curstate = enable;
+ }
+
+ spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags);
+}
+
+static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
+{
+ dhd_pub_t *dhdp;
+
+ dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev);
+
+ bcmsdh_oob_intr_set(0);
+
+ if (dhdp == NULL) {
+ AP6210_ERR("Out of band GPIO interrupt fired way too early\n");
+ return IRQ_HANDLED;
+ }
+
+ dhdsdio_isr((void *)dhdp->bus);
+
+ return IRQ_HANDLED;
+}
+
+extern int wl_host_wake_irqno;
+irqreturn_t bcmdhd_gpio_irq_handler(int irq, void *dev)
+{
+ wlan_oob_irq(0, NULL);
+ return IRQ_HANDLED;
+}
+
+int bcmsdh_register_oob_intr(void * dhdp)
+{
+ int error = 0;
+ int ret;
+ AP6210_DEBUG("%s Enter \n", __FUNCTION__);
+
+ /* IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */
+ dev_set_drvdata(sdhcinfo->dev, dhdp);
+
+ if (!sdhcinfo->oob_irq_registered) {
+ AP6210_DEBUG("%s IRQ=%d Type=%X \n", __FUNCTION__,
+ (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags);
+
+ ret = request_irq(wl_host_wake_irqno, bcmdhd_gpio_irq_handler, IRQF_DISABLED| IRQF_SHARED| IRQF_TRIGGER_HIGH, "bcmdhd_gpio_irq", (void *)&wl_host_wake_irqno);
+ if (ret) {
+ AP6210_ERR("request irq%d failed\n", wl_host_wake_irqno);
+ return -1;
+ }
+
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_AP6210)
+ if (device_may_wakeup(sdhcinfo->dev)) {
+#endif
+ error = enable_irq_wake(sdhcinfo->oob_irq);
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_AP6210)
+ }
+#endif
+ if (error)
+ AP6210_ERR("%s enable_irq_wake error=%d \n", __FUNCTION__, error);
+ sdhcinfo->oob_irq_registered = TRUE;
+ sdhcinfo->oob_irq_enable_flag = TRUE;
+ }
+
+ return 0;
+}
+
+void bcmsdh_set_irq(int flag)
+{
+ if (sdhcinfo->oob_irq_registered && sdhcinfo->oob_irq_enable_flag != flag) {
+ AP6210_ERR("%s Flag = %d\n", __FUNCTION__, flag);
+ sdhcinfo->oob_irq_enable_flag = flag;
+ if (flag) {
+ enable_irq(sdhcinfo->oob_irq);
+
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_AP6210)
+ if (device_may_wakeup(sdhcinfo->dev))
+#endif
+ enable_irq_wake(sdhcinfo->oob_irq);
+ } else {
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || defined(CONFIG_ARCH_SUN6I_AP6210)
+ if (device_may_wakeup(sdhcinfo->dev))
+#endif
+ disable_irq_wake(sdhcinfo->oob_irq);
+
+
+ disable_irq(sdhcinfo->oob_irq);
+ }
+ }
+}
+
+void bcmsdh_unregister_oob_intr(void)
+{
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (sdhcinfo->oob_irq_registered == TRUE) {
+
+ if(0 != wl_host_wake_irqno) {
+ AP6210_DEBUG("free_irq %d\n", wl_host_wake_irqno);
+ free_irq(wl_host_wake_irqno, &wl_host_wake_irqno);
+ }
+
+ sdhcinfo->oob_irq_registered = FALSE;
+ }
+}
+#endif
+
+#if defined(BCMLXSDMMC)
+void *bcmsdh_get_drvdata(void)
+{
+ if (!sdhcinfo)
+ return NULL;
+ return dev_get_drvdata(sdhcinfo->dev);
+}
+#endif
+
+/* Module parameters specific to each host-controller driver */
+
+extern uint sd_msglevel; /* Debug message level */
+module_param(sd_msglevel, uint, 0);
+
+extern uint sd_power; /* 0 = SD Power OFF, 1 = SD Power ON. */
+module_param(sd_power, uint, 0);
+
+extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */
+module_param(sd_clock, uint, 0);
+
+extern uint sd_divisor; /* Divisor (-1 means external clock) */
+module_param(sd_divisor, uint, 0);
+
+extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */
+module_param(sd_sdmode, uint, 0);
+
+extern uint sd_hiok; /* Ok to use hi-speed mode */
+module_param(sd_hiok, uint, 0);
+
+extern uint sd_f2_blocksize;
+module_param(sd_f2_blocksize, int, 0);
+
+#ifdef BCMSDIOH_STD
+extern int sd_uhsimode;
+module_param(sd_uhsimode, int, 0);
+#endif
+
+#ifdef BCMSDIOH_TXGLOM
+extern uint sd_txglom;
+module_param(sd_txglom, uint, 0);
+#endif
+
+#ifdef BCMSDH_MODULE
+EXPORT_SYMBOL(bcmsdh_attach);
+EXPORT_SYMBOL(bcmsdh_detach);
+EXPORT_SYMBOL(bcmsdh_intr_query);
+EXPORT_SYMBOL(bcmsdh_intr_enable);
+EXPORT_SYMBOL(bcmsdh_intr_disable);
+EXPORT_SYMBOL(bcmsdh_intr_reg);
+EXPORT_SYMBOL(bcmsdh_intr_dereg);
+
+#if defined(DHD_DEBUG)
+EXPORT_SYMBOL(bcmsdh_intr_pending);
+#endif
+
+EXPORT_SYMBOL(bcmsdh_devremove_reg);
+EXPORT_SYMBOL(bcmsdh_cfg_read);
+EXPORT_SYMBOL(bcmsdh_cfg_write);
+EXPORT_SYMBOL(bcmsdh_cis_read);
+EXPORT_SYMBOL(bcmsdh_reg_read);
+EXPORT_SYMBOL(bcmsdh_reg_write);
+EXPORT_SYMBOL(bcmsdh_regfail);
+EXPORT_SYMBOL(bcmsdh_send_buf);
+EXPORT_SYMBOL(bcmsdh_recv_buf);
+
+EXPORT_SYMBOL(bcmsdh_rwdata);
+EXPORT_SYMBOL(bcmsdh_abort);
+EXPORT_SYMBOL(bcmsdh_query_device);
+EXPORT_SYMBOL(bcmsdh_query_iofnum);
+EXPORT_SYMBOL(bcmsdh_iovar_op);
+EXPORT_SYMBOL(bcmsdh_register);
+EXPORT_SYMBOL(bcmsdh_unregister);
+EXPORT_SYMBOL(bcmsdh_chipmatch);
+EXPORT_SYMBOL(bcmsdh_reset);
+EXPORT_SYMBOL(bcmsdh_waitlockfree);
+
+EXPORT_SYMBOL(bcmsdh_get_dstatus);
+EXPORT_SYMBOL(bcmsdh_cfg_read_word);
+EXPORT_SYMBOL(bcmsdh_cfg_write_word);
+EXPORT_SYMBOL(bcmsdh_cur_sbwad);
+EXPORT_SYMBOL(bcmsdh_chipinfo);
+
+#endif /* BCMSDH_MODULE */
diff --git a/drivers/net/wireless/ap6210/bcmsdh_sdmmc.c b/drivers/net/wireless/ap6210/bcmsdh_sdmmc.c
new file mode 100644
index 0000000..5f0d300
--- /dev/null
+++ b/drivers/net/wireless/ap6210/bcmsdh_sdmmc.c
@@ -0,0 +1,1532 @@
+/*
+ * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdh_sdmmc.c 362913 2012-10-15 11:26:11Z $
+ */
+#include <typedefs.h>
+
+#include <bcmdevs.h>
+#include <bcmendian.h>
+#include <bcmutils.h>
+#include <osl.h>
+#include <sdio.h> /* SDIO Device and Protocol Specs */
+#include <sdioh.h> /* Standard SDIO Host Controller Specification */
+#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
+#include <sdiovar.h> /* ioctl/iovars */
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
+#include <linux/suspend.h>
+extern volatile bool dhd_mmc_suspend;
+#endif
+#include "bcmsdh_sdmmc.h"
+
+#include <ap6210.h>
+
+#ifndef BCMSDH_MODULE
+extern int sdio_function_init(void);
+extern void sdio_function_cleanup(void);
+#endif /* BCMSDH_MODULE */
+
+#if !defined(OOB_INTR_ONLY)
+static void IRQHandler(struct sdio_func *func);
+static void IRQHandlerF2(struct sdio_func *func);
+#endif /* !defined(OOB_INTR_ONLY) */
+static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr);
+extern int sdio_reset_comm(struct mmc_card *card);
+extern int sw_mci_check_r1_ready(struct mmc_host* mmc, unsigned ms);
+
+extern PBCMSDH_SDMMC_INSTANCE gInstance;
+
+#define DEFAULT_SDIO_F2_BLKSIZE 512
+#ifndef CUSTOM_SDIO_F2_BLKSIZE
+#define CUSTOM_SDIO_F2_BLKSIZE DEFAULT_SDIO_F2_BLKSIZE
+#endif
+
+uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */
+uint sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE;
+uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */
+
+uint sd_power = 1; /* Default to SD Slot powered ON */
+uint sd_clock = 1; /* Default to SD Clock turned ON */
+uint sd_hiok = FALSE; /* Don't use hi-speed mode by default */
+uint sd_msglevel = 0x01;
+uint sd_use_dma = TRUE;
+DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait);
+DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait);
+DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait);
+DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait);
+
+#define DMA_ALIGN_MASK 0x03
+#define MMC_SDIO_ABORT_RETRY_LIMIT 5
+
+int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data);
+
+static int
+sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd)
+{
+ int err_ret;
+ uint32 fbraddr;
+ uint8 func;
+
+ AP6210_DEBUG("%s\n", __FUNCTION__);;
+
+ /* Get the Card's common CIS address */
+ sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0);
+ sd->func_cis_ptr[0] = sd->com_cis_ptr;
+ AP6210_DEBUG("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr);
+
+ /* Get the Card's function CIS (for each function) */
+ for (fbraddr = SDIOD_FBR_STARTADDR, func = 1;
+ func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
+ sd->func_cis_ptr[func] = sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr);
+ AP6210_DEBUG("%s: Function %d CIS Ptr = 0x%x\n",
+ __FUNCTION__, func, sd->func_cis_ptr[func]);
+ }
+
+ sd->func_cis_ptr[0] = sd->com_cis_ptr;
+ AP6210_DEBUG("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr);
+
+ /* Enable Function 1 */
+ sdio_claim_host(gInstance->func[1]);
+ err_ret = sdio_enable_func(gInstance->func[1]);
+ sdio_release_host(gInstance->func[1]);
+ if (err_ret) {
+ AP6210_ERR("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x", err_ret);
+ }
+
+ return FALSE;
+}
+
+/*
+ * Public entry points & extern's
+ */
+extern sdioh_info_t *
+sdioh_attach(osl_t *osh, void *bar0, uint irq)
+{
+ sdioh_info_t *sd;
+ int err_ret;
+
+ AP6210_DEBUG("%s\n", __FUNCTION__);
+
+ if (gInstance == NULL) {
+ AP6210_ERR("%s: SDIO Device not present\n", __FUNCTION__);
+ return NULL;
+ }
+
+ if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) {
+ AP6210_ERR("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh));
+ return NULL;
+ }
+ bzero((char *)sd, sizeof(sdioh_info_t));
+ sd->osh = osh;
+ if (sdioh_sdmmc_osinit(sd) != 0) {
+ AP6210_ERR("%s:sdioh_sdmmc_osinit() failed\n", __FUNCTION__);
+ MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+ return NULL;
+ }
+
+ sd->num_funcs = 2;
+ sd->sd_blockmode = TRUE;
+ sd->use_client_ints = TRUE;
+ sd->client_block_size[0] = 64;
+ sd->use_rxchain = FALSE;
+
+ gInstance->sd = sd;
+
+ /* Claim host controller */
+ if (gInstance->func[1]) {
+ sdio_claim_host(gInstance->func[1]);
+
+ sd->client_block_size[1] = 64;
+ err_ret = sdio_set_block_size(gInstance->func[1], 64);
+ if (err_ret) {
+ AP6210_ERR("bcmsdh_sdmmc: Failed to set F1 blocksize\n");
+ }
+
+ /* Release host controller F1 */
+ sdio_release_host(gInstance->func[1]);
+ } else {
+ AP6210_ERR("%s:gInstance->func[1] is null\n", __FUNCTION__);
+ MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+ return NULL;
+ }
+
+ if (gInstance->func[2]) {
+ /* Claim host controller F2 */
+ sdio_claim_host(gInstance->func[2]);
+
+ sd->client_block_size[2] = sd_f2_blocksize;
+ err_ret = sdio_set_block_size(gInstance->func[2], sd_f2_blocksize);
+ if (err_ret) {
+ AP6210_ERR("bcmsdh_sdmmc: Failed to set F2 blocksize to %d\n",
+ sd_f2_blocksize);
+ }
+
+ /* Release host controller F2 */
+ sdio_release_host(gInstance->func[2]);
+ } else {
+ AP6210_ERR("%s:gInstance->func[2] is null\n", __FUNCTION__);
+ MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+ return NULL;
+ }
+
+ sdioh_sdmmc_card_enablefuncs(sd);
+
+ AP6210_DEBUG("%s: Done\n", __FUNCTION__);
+ return sd;
+}
+
+
+extern SDIOH_API_RC
+sdioh_detach(osl_t *osh, sdioh_info_t *sd)
+{
+ AP6210_DEBUG("%s\n", __FUNCTION__);
+
+ if (sd) {
+
+ /* Disable Function 2 */
+ sdio_claim_host(gInstance->func[2]);
+ sdio_disable_func(gInstance->func[2]);
+ sdio_release_host(gInstance->func[2]);
+
+ /* Disable Function 1 */
+ if (gInstance->func[1]) {
+ sdio_claim_host(gInstance->func[1]);
+ sdio_disable_func(gInstance->func[1]);
+ sdio_release_host(gInstance->func[1]);
+ }
+
+ gInstance->func[1] = NULL;
+ gInstance->func[2] = NULL;
+
+ /* deregister irq */
+ sdioh_sdmmc_osfree(sd);
+
+ MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+ }
+ return SDIOH_API_RC_SUCCESS;
+}
+
+#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+
+extern SDIOH_API_RC
+sdioh_enable_func_intr(void)
+{
+ uint8 reg;
+ int err;
+
+ if (gInstance->func[0]) {
+ sdio_claim_host(gInstance->func[0]);
+
+ reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err);
+ if (err) {
+ AP6210_ERR("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err);
+ sdio_release_host(gInstance->func[0]);
+ return SDIOH_API_RC_FAIL;
+ }
+
+ /* Enable F1 and F2 interrupts, set master enable */
+ reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | INTR_CTL_MASTER_EN);
+
+ sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err);
+ sdio_release_host(gInstance->func[0]);
+
+ if (err) {
+ AP6210_ERR("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err);
+ return SDIOH_API_RC_FAIL;
+ }
+ }
+
+ return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_disable_func_intr(void)
+{
+ uint8 reg;
+ int err;
+
+ if (gInstance->func[0]) {
+ sdio_claim_host(gInstance->func[0]);
+ reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err);
+ if (err) {
+ AP6210_ERR("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err);
+ sdio_release_host(gInstance->func[0]);
+ return SDIOH_API_RC_FAIL;
+ }
+
+ reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
+ /* Disable master interrupt with the last function interrupt */
+ if (!(reg & 0xFE))
+ reg = 0;
+ sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err);
+
+ sdio_release_host(gInstance->func[0]);
+ if (err) {
+ AP6210_ERR("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err);
+ return SDIOH_API_RC_FAIL;
+ }
+ }
+ return SDIOH_API_RC_SUCCESS;
+}
+#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
+
+/* Configure callback to client when we recieve client interrupt */
+extern SDIOH_API_RC
+sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
+{
+ AP6210_DEBUG("%s: Entering\n", __FUNCTION__);
+ if (fn == NULL) {
+ AP6210_ERR("%s: interrupt handler is NULL, not registering\n", __FUNCTION__);
+ return SDIOH_API_RC_FAIL;
+ }
+#if !defined(OOB_INTR_ONLY)
+ sd->intr_handler = fn;
+ sd->intr_handler_arg = argh;
+ sd->intr_handler_valid = TRUE;
+
+ /* register and unmask irq */
+ if (gInstance->func[2]) {
+ sdio_claim_host(gInstance->func[2]);
+ sdio_claim_irq(gInstance->func[2], IRQHandlerF2);
+ sdio_release_host(gInstance->func[2]);
+ }
+
+ if (gInstance->func[1]) {
+ sdio_claim_host(gInstance->func[1]);
+ sdio_claim_irq(gInstance->func[1], IRQHandler);
+ sdio_release_host(gInstance->func[1]);
+ }
+#elif defined(HW_OOB)
+ sdioh_enable_func_intr();
+#endif /* !defined(OOB_INTR_ONLY) */
+
+ return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_interrupt_deregister(sdioh_info_t *sd)
+{
+ AP6210_DEBUG("%s: Entering\n", __FUNCTION__);
+
+#if !defined(OOB_INTR_ONLY)
+ if (gInstance->func[1]) {
+ /* register and unmask irq */
+ sdio_claim_host(gInstance->func[1]);
+ sdio_release_irq(gInstance->func[1]);
+ sdio_release_host(gInstance->func[1]);
+ }
+
+ if (gInstance->func[2]) {
+ /* Claim host controller F2 */
+ sdio_claim_host(gInstance->func[2]);
+ sdio_release_irq(gInstance->func[2]);
+ /* Release host controller F2 */
+ sdio_release_host(gInstance->func[2]);
+ }
+
+ sd->intr_handler_valid = FALSE;
+ sd->intr_handler = NULL;
+ sd->intr_handler_arg = NULL;
+#elif defined(HW_OOB)
+ sdioh_disable_func_intr();
+#endif /* !defined(OOB_INTR_ONLY) */
+ return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
+{
+ AP6210_DEBUG("%s: Entering\n", __FUNCTION__);
+ *onoff = sd->client_intr_enabled;
+ return SDIOH_API_RC_SUCCESS;
+}
+
+#if defined(DHD_DEBUG)
+extern bool
+sdioh_interrupt_pending(sdioh_info_t *sd)
+{
+ return (0);
+}
+#endif
+
+uint
+sdioh_query_iofnum(sdioh_info_t *sd)
+{
+ return sd->num_funcs;
+}
+
+/* IOVar table */
+enum {
+ IOV_MSGLEVEL = 1,
+ IOV_BLOCKMODE,
+ IOV_BLOCKSIZE,
+ IOV_DMA,
+ IOV_USEINTS,
+ IOV_NUMINTS,
+ IOV_NUMLOCALINTS,
+ IOV_HOSTREG,
+ IOV_DEVREG,
+ IOV_DIVISOR,
+ IOV_SDMODE,
+ IOV_HISPEED,
+ IOV_HCIREGS,
+ IOV_POWER,
+ IOV_CLOCK,
+ IOV_RXCHAIN
+};
+
+const bcm_iovar_t sdioh_iovars[] = {
+ {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 },
+ {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 },
+ {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */
+ {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0 },
+ {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 },
+ {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 },
+ {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 },
+ {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
+ {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
+ {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 },
+ {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 },
+ {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 },
+ {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100},
+ {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0 },
+ {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0 },
+ {NULL, 0, 0, 0, 0 }
+};
+
+int
+sdioh_iovar_op(sdioh_info_t *si, const char *name,
+ void *params, int plen, void *arg, int len, bool set)
+{
+ const bcm_iovar_t *vi = NULL;
+ int bcmerror = 0;
+ int val_size;
+ int32 int_val = 0;
+ bool bool_val;
+ uint32 actionid;
+
+ ASSERT(name);
+ ASSERT(len >= 0);
+
+ /* Get must have return space; Set does not take qualifiers */
+ ASSERT(set || (arg && len));
+ ASSERT(!set || (!params && !plen));
+
+ AP6210_DEBUG("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name);
+
+ if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) {
+ bcmerror = BCME_UNSUPPORTED;
+ goto exit;
+ }
+
+ if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0)
+ goto exit;
+
+ /* Set up params so get and set can share the convenience variables */
+ if (params == NULL) {
+ params = arg;
+ plen = len;
+ }
+
+ if (vi->type == IOVT_VOID)
+ val_size = 0;
+ else if (vi->type == IOVT_BUFFER)
+ val_size = len;
+ else
+ val_size = sizeof(int);
+
+ if (plen >= (int)sizeof(int_val))
+ bcopy(params, &int_val, sizeof(int_val));
+
+ bool_val = (int_val != 0) ? TRUE : FALSE;
+ BCM_REFERENCE(bool_val);
+
+ actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+ switch (actionid) {
+ case IOV_GVAL(IOV_MSGLEVEL):
+ int_val = (int32)sd_msglevel;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_MSGLEVEL):
+ sd_msglevel = int_val;
+ break;
+
+ case IOV_GVAL(IOV_BLOCKMODE):
+ int_val = (int32)si->sd_blockmode;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_BLOCKMODE):
+ si->sd_blockmode = (bool)int_val;
+ /* Haven't figured out how to make non-block mode with DMA */
+ break;
+
+ case IOV_GVAL(IOV_BLOCKSIZE):
+ if ((uint32)int_val > si->num_funcs) {
+ bcmerror = BCME_BADARG;
+ break;
+ }
+ int_val = (int32)si->client_block_size[int_val];
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_BLOCKSIZE):
+ {
+ uint func = ((uint32)int_val >> 16);
+ uint blksize = (uint16)int_val;
+ uint maxsize;
+
+ if (func > si->num_funcs) {
+ bcmerror = BCME_BADARG;
+ break;
+ }
+
+ switch (func) {
+ case 0: maxsize = 32; break;
+ case 1: maxsize = BLOCK_SIZE_4318; break;
+ case 2: maxsize = BLOCK_SIZE_4328; break;
+ default: maxsize = 0;
+ }
+ if (blksize > maxsize) {
+ bcmerror = BCME_BADARG;
+ break;
+ }
+ if (!blksize) {
+ blksize = maxsize;
+ }
+
+ /* Now set it */
+ si->client_block_size[func] = blksize;
+
+ break;
+ }
+
+ case IOV_GVAL(IOV_RXCHAIN):
+ int_val = (int32)si->use_rxchain;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_GVAL(IOV_DMA):
+ int_val = (int32)si->sd_use_dma;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_DMA):
+ si->sd_use_dma = (bool)int_val;
+ break;
+
+ case IOV_GVAL(IOV_USEINTS):
+ int_val = (int32)si->use_client_ints;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_USEINTS):
+ si->use_client_ints = (bool)int_val;
+ if (si->use_client_ints)
+ si->intmask |= CLIENT_INTR;
+ else
+ si->intmask &= ~CLIENT_INTR;
+
+ break;
+
+ case IOV_GVAL(IOV_DIVISOR):
+ int_val = (uint32)sd_divisor;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_DIVISOR):
+ sd_divisor = int_val;
+ break;
+
+ case IOV_GVAL(IOV_POWER):
+ int_val = (uint32)sd_power;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_POWER):
+ sd_power = int_val;
+ break;
+
+ case IOV_GVAL(IOV_CLOCK):
+ int_val = (uint32)sd_clock;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_CLOCK):
+ sd_clock = int_val;
+ break;
+
+ case IOV_GVAL(IOV_SDMODE):
+ int_val = (uint32)sd_sdmode;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_SDMODE):
+ sd_sdmode = int_val;
+ break;
+
+ case IOV_GVAL(IOV_HISPEED):
+ int_val = (uint32)sd_hiok;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_HISPEED):
+ sd_hiok = int_val;
+ break;
+
+ case IOV_GVAL(IOV_NUMINTS):
+ int_val = (int32)si->intrcount;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_GVAL(IOV_NUMLOCALINTS):
+ int_val = (int32)0;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_GVAL(IOV_HOSTREG):
+ {
+ sdreg_t *sd_ptr = (sdreg_t *)params;
+
+ if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
+ AP6210_ERR("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset);
+ bcmerror = BCME_BADARG;
+ break;
+ }
+
+ AP6210_DEBUG("%s: rreg%d at offset %d\n", __FUNCTION__,
+ (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
+ sd_ptr->offset);
+ if (sd_ptr->offset & 1)
+ int_val = 8; /* sdioh_sdmmc_rreg8(si, sd_ptr->offset); */
+ else if (sd_ptr->offset & 2)
+ int_val = 16; /* sdioh_sdmmc_rreg16(si, sd_ptr->offset); */
+ else
+ int_val = 32; /* sdioh_sdmmc_rreg(si, sd_ptr->offset); */
+
+ bcopy(&int_val, arg, sizeof(int_val));
+ break;
+ }
+
+ case IOV_SVAL(IOV_HOSTREG):
+ {
+ sdreg_t *sd_ptr = (sdreg_t *)params;
+
+ if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
+ AP6210_ERR("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset);
+ bcmerror = BCME_BADARG;
+ break;
+ }
+
+ AP6210_DEBUG("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value,
+ (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
+ sd_ptr->offset);
+ break;
+ }
+
+ case IOV_GVAL(IOV_DEVREG):
+ {
+ sdreg_t *sd_ptr = (sdreg_t *)params;
+ uint8 data = 0;
+
+ if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) {
+ bcmerror = BCME_SDIO_ERROR;
+ break;
+ }
+
+ int_val = (int)data;
+ bcopy(&int_val, arg, sizeof(int_val));
+ break;
+ }
+
+ case IOV_SVAL(IOV_DEVREG):
+ {
+ sdreg_t *sd_ptr = (sdreg_t *)params;
+ uint8 data = (uint8)sd_ptr->value;
+
+ if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
+ bcmerror = BCME_SDIO_ERROR;
+ break;
+ }
+ break;
+ }
+
+ default:
+ bcmerror = BCME_UNSUPPORTED;
+ break;
+ }
+exit:
+
+ return bcmerror;
+}
+
+#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+
+SDIOH_API_RC
+sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable)
+{
+ SDIOH_API_RC status;
+ uint8 data;
+
+ if (enable)
+ data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE | SDIO_SEPINT_ACT_HI;
+ else
+ data = SDIO_SEPINT_ACT_HI; /* disable hw oob interrupt */
+
+ status = sdioh_request_byte(sd, SDIOH_WRITE, 0, SDIOD_CCCR_BRCM_SEPINT, &data);
+ return status;
+}
+#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
+
+extern SDIOH_API_RC
+sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
+{
+ SDIOH_API_RC status;
+ /* No lock needed since sdioh_request_byte does locking */
+ status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
+ return status;
+}
+
+extern SDIOH_API_RC
+sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
+{
+ /* No lock needed since sdioh_request_byte does locking */
+ SDIOH_API_RC status;
+ status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
+ return status;
+}
+
+static int
+sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr)
+{
+ /* read 24 bits and return valid 17 bit addr */
+ int i;
+ uint32 scratch, regdata;
+ uint8 *ptr = (uint8 *)&scratch;
+ for (i = 0; i < 3; i++) {
+ if ((sdioh_sdmmc_card_regread (sd, 0, regaddr, 1, &regdata)) != SUCCESS)
+ AP6210_ERR("%s: Can't read!\n", __FUNCTION__);
+
+ *ptr++ = (uint8) regdata;
+ regaddr++;
+ }
+
+ /* Only the lower 17-bits are valid */
+ scratch = ltoh32(scratch);
+ scratch &= 0x0001FFFF;
+ return (scratch);
+}
+
+extern SDIOH_API_RC
+sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length)
+{
+ uint32 count;
+ int offset;
+ uint32 foo;
+ uint8 *cis = cisd;
+
+ AP6210_DEBUG("%s: Func = %d\n", __FUNCTION__, func);
+
+ if (!sd->func_cis_ptr[func]) {
+ bzero(cis, length);
+ AP6210_ERR("%s: no func_cis_ptr[%d]\n", __FUNCTION__, func);
+ return SDIOH_API_RC_FAIL;
+ }
+
+ AP6210_ERR("%s: func_cis_ptr[%d]=0x%04x\n", __FUNCTION__, func, sd->func_cis_ptr[func]);
+
+ for (count = 0; count < length; count++) {
+ offset = sd->func_cis_ptr[func] + count;
+ if (sdioh_sdmmc_card_regread (sd, 0, offset, 1, &foo) < 0) {
+ AP6210_ERR("%s: regread failed: Can't read CIS\n", __FUNCTION__);
+ return SDIOH_API_RC_FAIL;
+ }
+
+ *cis = (uint8)(foo & 0xff);
+ cis++;
+ }
+
+ return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte)
+{
+ int err_ret;
+#if defined(MMC_SDIO_ABORT)
+ int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT;
+#endif
+ int ret = 0;
+
+ AP6210_DEBUG("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr);
+
+ DHD_PM_RESUME_WAIT(sdioh_request_byte_wait);
+ DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+ if(rw) { /* CMD52 Write */
+ if (func == 0) {
+ /* Can only directly write to some F0 registers. Handle F2 enable
+ * as a special case.
+ */
+ if (regaddr == SDIOD_CCCR_IOEN) {
+ if (gInstance->func[2]) {
+ sdio_claim_host(gInstance->func[2]);
+ if (*byte & SDIO_FUNC_ENABLE_2) {
+ /* Enable Function 2 */
+ err_ret = sdio_enable_func(gInstance->func[2]);
+ if (err_ret) {
+ AP6210_ERR("bcmsdh_sdmmc: enable F2 failed:%d",
+ err_ret);
+ }
+ } else {
+ /* Disable Function 2 */
+ err_ret = sdio_disable_func(gInstance->func[2]);
+ if (err_ret) {
+ AP6210_ERR("bcmsdh_sdmmc: Disab F2 failed:%d",
+ err_ret);
+ }
+ }
+ sdio_release_host(gInstance->func[2]);
+ }
+ }
+#if defined(MMC_SDIO_ABORT)
+ /* to allow abort command through F1 */
+ else if (regaddr == SDIOD_CCCR_IOABORT) {
+ /* Because of SDIO3.0 host issue on Manta,
+ * sometimes the abort fails.
+ * Retrying again will fix this issue.
+ */
+ while (sdio_abort_retry--) {
+ if (gInstance->func[func]) {
+ sdio_claim_host(gInstance->func[func]);
+ /*
+ * this sdio_f0_writeb() can be replaced with
+ * another api depending upon MMC driver change.
+ * As of this time, this is temporaray one
+ */
+ sdio_writeb(gInstance->func[func],
+ *byte, regaddr, &err_ret);
+ sdio_release_host(gInstance->func[func]);
+ }
+ if (!err_ret)
+ break;
+ }
+ }
+#endif /* MMC_SDIO_ABORT */
+ else if (regaddr < 0xF0) {
+ AP6210_ERR("bcmsdh_sdmmc: F0 Wr:0x%02x: write disallowed\n", regaddr);
+ } else {
+ /* Claim host controller, perform F0 write, and release */
+ if (gInstance->func[func]) {
+ sdio_claim_host(gInstance->func[func]);
+ sdio_f0_writeb(gInstance->func[func],
+ *byte, regaddr, &err_ret);
+ sdio_release_host(gInstance->func[func]);
+ }
+ }
+ } else {
+ /* Claim host controller, perform Fn write, and release */
+ if (gInstance->func[func]) {
+ sdio_claim_host(gInstance->func[func]);
+ sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret);
+ sdio_release_host(gInstance->func[func]);
+ }
+ }
+ } else { /* CMD52 Read */
+ /* Claim host controller, perform Fn read, and release */
+ if (gInstance->func[func]) {
+ sdio_claim_host(gInstance->func[func]);
+ if (func == 0) {
+ *byte = sdio_f0_readb(gInstance->func[func], regaddr, &err_ret);
+ } else {
+ *byte = sdio_readb(gInstance->func[func], regaddr, &err_ret);
+ }
+ sdio_release_host(gInstance->func[func]);
+ }
+ }
+
+ //AW judge sdio read write timeout, 1s
+ ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000);
+ if (ret != 0)
+ AP6210_DEBUG("%s data timeout.\n", __FUNCTION__);
+
+ if (err_ret) {
+ AP6210_ERR("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
+ rw ? "Write" : "Read", func, regaddr, *byte, err_ret);
+ }
+
+ return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+}
+
+extern SDIOH_API_RC
+sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr,
+ uint32 *word, uint nbytes)
+{
+ int err_ret = SDIOH_API_RC_FAIL;
+#if defined(MMC_SDIO_ABORT)
+ int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT;
+#endif
+ int ret = 0;
+
+ if (func == 0) {
+ AP6210_ERR("%s: Only CMD52 allowed to F0.\n", __FUNCTION__);
+ return SDIOH_API_RC_FAIL;
+ }
+
+ AP6210_DEBUG("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
+ __FUNCTION__, cmd_type, rw, func, addr, nbytes);
+
+ DHD_PM_RESUME_WAIT(sdioh_request_word_wait);
+ DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+ /* Claim host controller */
+ sdio_claim_host(gInstance->func[func]);
+
+ if(rw) { /* CMD53 Write */
+ if (nbytes == 4) {
+ sdio_writel(gInstance->func[func], *word, addr, &err_ret);
+ } else if (nbytes == 2) {
+ sdio_writew(gInstance->func[func], (*word & 0xFFFF), addr, &err_ret);
+ } else {
+ AP6210_ERR("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes);
+ }
+ } else { /* CMD52 Read */
+ if (nbytes == 4) {
+ *word = sdio_readl(gInstance->func[func], addr, &err_ret);
+ } else if (nbytes == 2) {
+ *word = sdio_readw(gInstance->func[func], addr, &err_ret) & 0xFFFF;
+ } else {
+ AP6210_ERR("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes);
+ }
+ }
+
+ //AW judge sdio read write timeout, 1s
+ ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000);
+ if (ret != 0)
+ AP6210_DEBUG("%s data timeout.\n", __FUNCTION__);
+
+ /* Release host controller */
+ sdio_release_host(gInstance->func[func]);
+
+ if (err_ret) {
+#if defined(MMC_SDIO_ABORT)
+ /* Any error on CMD53 transaction should abort that function using function 0. */
+ while (sdio_abort_retry--) {
+ if (gInstance->func[0]) {
+ sdio_claim_host(gInstance->func[0]);
+ /*
+ * this sdio_f0_writeb() can be replaced with another api
+ * depending upon MMC driver change.
+ * As of this time, this is temporaray one
+ */
+ sdio_writeb(gInstance->func[0],
+ func, SDIOD_CCCR_IOABORT, &err_ret);
+ sdio_release_host(gInstance->func[0]);
+ }
+ if (!err_ret)
+ break;
+ }
+ if (err_ret)
+#endif /* MMC_SDIO_ABORT */
+ {
+ AP6210_ERR("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x\n",
+ rw ? "Write" : "Read", err_ret);
+ }
+ }
+
+ return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+}
+
+static SDIOH_API_RC
+sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
+ uint addr, void *pkt)
+{
+ bool fifo = (fix_inc == SDIOH_DATA_FIX);
+ uint32 SGCount = 0;
+ int err_ret = 0;
+ void *pnext, *pprev;
+ uint ttl_len, dma_len, lft_len, xfred_len, pkt_len;
+ uint blk_num;
+ int blk_size;
+ struct mmc_request mmc_req;
+ struct mmc_command mmc_cmd;
+ struct mmc_data mmc_dat;
+ int ret = 0;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ ASSERT(pkt);
+ DHD_PM_RESUME_WAIT(sdioh_request_packet_wait);
+ DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+
+ ttl_len = xfred_len = 0;
+ /* at least 4 bytes alignment of skb buff is guaranteed */
+ for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext))
+ ttl_len += PKTLEN(sd->osh, pnext);
+
+ blk_size = sd->client_block_size[func];
+ if (!sd->use_rxchain || ttl_len <= blk_size) {
+ blk_num = 0;
+ dma_len = 0;
+ } else {
+ blk_num = ttl_len / blk_size;
+ dma_len = blk_num * blk_size;
+ }
+ lft_len = ttl_len - dma_len;
+
+ AP6210_DEBUG("%s: %s %dB to func%d:%08x, %d blks with DMA, %dB leftover\n",
+ __FUNCTION__, write ? "W" : "R",
+ ttl_len, func, addr, blk_num, lft_len);
+
+ if (0 != dma_len) {
+ memset(&mmc_req, 0, sizeof(struct mmc_request));
+ memset(&mmc_cmd, 0, sizeof(struct mmc_command));
+ memset(&mmc_dat, 0, sizeof(struct mmc_data));
+
+ /* Set up DMA descriptors */
+ pprev = pkt;
+ for (pnext = pkt;
+ pnext && dma_len;
+ pnext = PKTNEXT(sd->osh, pnext)) {
+ pkt_len = PKTLEN(sd->osh, pnext);
+
+ if (dma_len > pkt_len)
+ dma_len -= pkt_len;
+ else {
+ pkt_len = xfred_len = dma_len;
+ dma_len = 0;
+ pkt = pnext;
+ }
+
+ sg_set_buf(&sd->sg_list[SGCount++],
+ (uint8*)PKTDATA(sd->osh, pnext),
+ pkt_len);
+
+ if (SGCount >= SDIOH_SDMMC_MAX_SG_ENTRIES) {
+ AP6210_ERR("%s: sg list entries exceed limit\n",
+ __FUNCTION__);
+ return (SDIOH_API_RC_FAIL);
+ }
+ }
+
+ mmc_dat.sg = sd->sg_list;
+ mmc_dat.sg_len = SGCount;
+ mmc_dat.blksz = blk_size;
+ mmc_dat.blocks = blk_num;
+ mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+
+ mmc_cmd.opcode = 53; /* SD_IO_RW_EXTENDED */
+ mmc_cmd.arg = write ? 1<<31 : 0;
+ mmc_cmd.arg |= (func & 0x7) << 28;
+ mmc_cmd.arg |= 1<<27;
+ mmc_cmd.arg |= fifo ? 0 : 1<<26;
+ mmc_cmd.arg |= (addr & 0x1FFFF) << 9;
+ mmc_cmd.arg |= blk_num & 0x1FF;
+ mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+
+ mmc_req.cmd = &mmc_cmd;
+ mmc_req.data = &mmc_dat;
+
+ sdio_claim_host(gInstance->func[func]);
+ mmc_set_data_timeout(&mmc_dat, gInstance->func[func]->card);
+ mmc_wait_for_req(gInstance->func[func]->card->host, &mmc_req);
+ sdio_release_host(gInstance->func[func]);
+
+ err_ret = mmc_cmd.error? mmc_cmd.error : mmc_dat.error;
+ if (0 != err_ret) {
+ AP6210_ERR("%s:CMD53 %s failed with code %d\n",
+ __FUNCTION__,
+ write ? "write" : "read",
+ err_ret);
+ AP6210_ERR("%s:Disabling rxchain and fire it with PIO\n",
+ __FUNCTION__);
+ sd->use_rxchain = FALSE;
+ pkt = pprev;
+ lft_len = ttl_len;
+ } else if (!fifo) {
+ addr = addr + ttl_len - lft_len - dma_len;
+ }
+ }
+
+ /* PIO mode */
+ if (0 != lft_len) {
+ /* Claim host controller */
+ sdio_claim_host(gInstance->func[func]);
+ for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) {
+ uint8 *buf = (uint8*)PKTDATA(sd->osh, pnext) +
+ xfred_len;
+ pkt_len = PKTLEN(sd->osh, pnext);
+ if (0 != xfred_len) {
+ pkt_len -= xfred_len;
+ xfred_len = 0;
+ }
+
+ /* Align Patch
+ * read or small packet(ex:BDC header) skip 32 byte align
+ * otherwise, padding DHD_SDALIGN for performance
+ */
+ if (write == 0 || pkt_len < 32)
+ pkt_len = (pkt_len + 3) & 0xFFFFFFFC;
+ else if (pkt_len % blk_size)
+ pkt_len += blk_size - (pkt_len % blk_size);
+
+#ifdef CONFIG_MMC_MSM7X00A
+ if ((pkt_len % 64) == 32) {
+ AP6210_DEBUG("%s: Rounding up TX packet +=32\n", __FUNCTION__);
+ pkt_len += 32;
+ }
+#endif /* CONFIG_MMC_MSM7X00A */
+
+ if ((write) && (!fifo))
+ err_ret = sdio_memcpy_toio(
+ gInstance->func[func],
+ addr, buf, pkt_len);
+ else if (write)
+ err_ret = sdio_memcpy_toio(
+ gInstance->func[func],
+ addr, buf, pkt_len);
+ else if (fifo)
+ err_ret = sdio_readsb(
+ gInstance->func[func],
+ buf, addr, pkt_len);
+ else
+ err_ret = sdio_memcpy_fromio(
+ gInstance->func[func],
+ buf, addr, pkt_len);
+
+ //AW judge sdio read write timeout, 1s
+ ret = sw_mci_check_r1_ready(gInstance->func[func]->card->host, 1000);
+ if (ret != 0)
+ AP6210_DEBUG("%s data timeout.\n", __FUNCTION__);
+
+ if (err_ret)
+ AP6210_ERR("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=%d\n",
+ __FUNCTION__,
+ (write) ? "TX" : "RX",
+ pnext, SGCount, addr, pkt_len, err_ret);
+ else
+ AP6210_DEBUG("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n",
+ __FUNCTION__,
+ (write) ? "TX" : "RX",
+ pnext, SGCount, addr, pkt_len);
+
+ if (!fifo)
+ addr += pkt_len;
+ SGCount ++;
+ }
+ sdio_release_host(gInstance->func[func]);
+ }
+
+ AP6210_DEBUG("%s: Exit\n", __FUNCTION__);
+ return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+}
+
+
+/*
+ * This function takes a buffer or packet, and fixes everything up so that in the
+ * end, a DMA-able packet is created.
+ *
+ * A buffer does not have an associated packet pointer, and may or may not be aligned.
+ * A packet may consist of a single packet, or a packet chain. If it is a packet chain,
+ * then all the packets in the chain must be properly aligned. If the packet data is not
+ * aligned, then there may only be one packet, and in this case, it is copied to a new
+ * aligned packet.
+ *
+ */
+extern SDIOH_API_RC
+sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func,
+ uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt)
+{
+ SDIOH_API_RC Status;
+ void *mypkt = NULL;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait);
+ DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+ /* Case 1: we don't have a packet. */
+ if (pkt == NULL) {
+ AP6210_DEBUG("%s: Creating new %s Packet, len=%d\n",
+ __FUNCTION__, write ? "TX" : "RX", buflen_u);
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+ if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE)))
+#else
+ if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE)))
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+ {
+ AP6210_ERR("%s: PKTGET failed: len %d\n",
+ __FUNCTION__, buflen_u);
+ return SDIOH_API_RC_FAIL;
+ }
+
+ /* For a write, copy the buffer data into the packet. */
+ if (write) {
+ bcopy(buffer, PKTDATA(sd->osh, mypkt), buflen_u);
+ }
+
+ Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
+
+ /* For a read, copy the packet data back to the buffer. */
+ if (!write) {
+ bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u);
+ }
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+ PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE);
+#else
+ PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE);
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+ } else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) {
+ /* Case 2: We have a packet, but it is unaligned. */
+
+ /* In this case, we cannot have a chain. */
+ ASSERT(PKTNEXT(sd->osh, pkt) == NULL);
+
+ AP6210_DEBUG("%s: Creating aligned %s Packet, len=%d\n",
+ __FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt));
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+ if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE)))
+#else
+ if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE)))
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+ {
+ AP6210_ERR("%s: PKTGET failed: len %d\n",
+ __FUNCTION__, PKTLEN(sd->osh, pkt));
+ return SDIOH_API_RC_FAIL;
+ }
+
+ /* For a write, copy the buffer data into the packet. */
+ if (write) {
+ bcopy(PKTDATA(sd->osh, pkt),
+ PKTDATA(sd->osh, mypkt),
+ PKTLEN(sd->osh, pkt));
+ }
+
+ Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
+
+ /* For a read, copy the packet data back to the buffer. */
+ if (!write) {
+ bcopy(PKTDATA(sd->osh, mypkt),
+ PKTDATA(sd->osh, pkt),
+ PKTLEN(sd->osh, mypkt));
+ }
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+ PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE);
+#else
+ PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE);
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+ } else { /* case 3: We have a packet and it is aligned. */
+ AP6210_DEBUG("%s: Aligned %s Packet, direct DMA\n",
+ __FUNCTION__, write ? "Tx" : "Rx");
+ Status = sdioh_request_packet(sd, fix_inc, write, func, addr, pkt);
+ }
+
+ return (Status);
+}
+
+/* this function performs "abort" for both of host & device */
+extern int
+sdioh_abort(sdioh_info_t *sd, uint func)
+{
+#if defined(MMC_SDIO_ABORT)
+ char t_func = (char) func;
+#endif /* defined(MMC_SDIO_ABORT) */
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+#if defined(MMC_SDIO_ABORT)
+ /* issue abort cmd52 command through F1 */
+ sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, &t_func);
+#endif /* defined(MMC_SDIO_ABORT) */
+
+ AP6210_DEBUG("%s: Exit\n", __FUNCTION__);
+ return SDIOH_API_RC_SUCCESS;
+}
+
+/* Reset and re-initialize the device */
+int sdioh_sdio_reset(sdioh_info_t *si)
+{
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+ AP6210_DEBUG("%s: Exit\n", __FUNCTION__);
+ return SDIOH_API_RC_SUCCESS;
+}
+
+/* Disable device interrupt */
+void
+sdioh_sdmmc_devintr_off(sdioh_info_t *sd)
+{
+ AP6210_DEBUG("%s: %d\n", __FUNCTION__, sd->use_client_ints);
+ sd->intmask &= ~CLIENT_INTR;
+}
+
+/* Enable device interrupt */
+void
+sdioh_sdmmc_devintr_on(sdioh_info_t *sd)
+{
+ AP6210_DEBUG("%s: %d\n", __FUNCTION__, sd->use_client_ints);
+ sd->intmask |= CLIENT_INTR;
+}
+
+/* Read client card reg */
+int
+sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data)
+{
+
+ if ((func == 0) || (regsize == 1)) {
+ uint8 temp = 0;
+
+ sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
+ *data = temp;
+ *data &= 0xff;
+ AP6210_DEBUG("%s: byte read data=0x%02x\n",
+ __FUNCTION__, *data);
+ } else {
+ sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, regsize);
+ if (regsize == 2)
+ *data &= 0xffff;
+
+ AP6210_DEBUG("%s: word read data=0x%08x\n",
+ __FUNCTION__, *data);
+ }
+
+ return SUCCESS;
+}
+
+#if !defined(OOB_INTR_ONLY)
+/* bcmsdh_sdmmc interrupt handler */
+static void IRQHandler(struct sdio_func *func)
+{
+ sdioh_info_t *sd;
+
+ AP6210_DEBUG("bcmsdh_sdmmc: ***IRQHandler\n");
+ sd = gInstance->sd;
+
+ ASSERT(sd != NULL);
+ sdio_release_host(gInstance->func[0]);
+
+ if (sd->use_client_ints) {
+ sd->intrcount++;
+ ASSERT(sd->intr_handler);
+ ASSERT(sd->intr_handler_arg);
+ (sd->intr_handler)(sd->intr_handler_arg);
+ } else {
+ AP6210_ERR("bcmsdh_sdmmc: ***IRQHandler\n");
+
+ AP6210_ERR("%s: Not ready for intr: enabled %d, handler %p\n",
+ __FUNCTION__, sd->client_intr_enabled, sd->intr_handler);
+ }
+
+ sdio_claim_host(gInstance->func[0]);
+}
+
+/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */
+static void IRQHandlerF2(struct sdio_func *func)
+{
+ sdioh_info_t *sd;
+
+ AP6210_DEBUG("bcmsdh_sdmmc: ***IRQHandlerF2\n");
+
+ sd = gInstance->sd;
+
+ ASSERT(sd != NULL);
+ BCM_REFERENCE(sd);
+}
+#endif /* !defined(OOB_INTR_ONLY) */
+
+#ifdef NOTUSED
+/* Write client card reg */
+static int
+sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data)
+{
+
+ if ((func == 0) || (regsize == 1)) {
+ uint8 temp;
+
+ temp = data & 0xff;
+ sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
+ AP6210_DEBUG("%s: byte write data=0x%02x\n",
+ __FUNCTION__, data);
+ } else {
+ if (regsize == 2)
+ data &= 0xffff;
+
+ sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data, regsize);
+
+ AP6210_DEBUG("%s: word write data=0x%08x\n",
+ __FUNCTION__, data);
+ }
+
+ return SUCCESS;
+}
+#endif /* NOTUSED */
+
+int
+sdioh_start(sdioh_info_t *si, int stage)
+{
+ int ret;
+ sdioh_info_t *sd = gInstance->sd;
+
+ if (!sd) return (0);
+
+ /* Need to do this stages as we can't enable the interrupt till
+ downloading of the firmware is complete, other wise polling
+ sdio access will come in way
+ */
+ if (gInstance->func[0]) {
+ if (stage == 0) {
+ /* Since the power to the chip is killed, we will have
+ re enumerate the device again. Set the block size
+ and enable the fucntion 1 for in preparation for
+ downloading the code
+ */
+ /* sdio_reset_comm() - has been fixed in latest kernel/msm.git for Linux
+ 2.6.27. The implementation prior to that is buggy, and needs broadcom's
+ patch for it
+ */
+ if ((ret = sdio_reset_comm(gInstance->func[0]->card))) {
+ AP6210_ERR("%s Failed, error = %d\n", __FUNCTION__, ret);
+ return ret;
+ }
+ else {
+ sd->num_funcs = 2;
+ sd->sd_blockmode = TRUE;
+ sd->use_client_ints = TRUE;
+ sd->client_block_size[0] = 64;
+
+ if (gInstance->func[1]) {
+ /* Claim host controller */
+ sdio_claim_host(gInstance->func[1]);
+
+ sd->client_block_size[1] = 64;
+ if (sdio_set_block_size(gInstance->func[1], 64)) {
+ AP6210_ERR("bcmsdh_sdmmc: Failed to set F1 blocksize\n");
+ }
+
+ /* Release host controller F1 */
+ sdio_release_host(gInstance->func[1]);
+ }
+
+ if (gInstance->func[2]) {
+ /* Claim host controller F2 */
+ sdio_claim_host(gInstance->func[2]);
+
+ sd->client_block_size[2] = sd_f2_blocksize;
+ if (sdio_set_block_size(gInstance->func[2],
+ sd_f2_blocksize)) {
+ AP6210_ERR("bcmsdh_sdmmc: Failed to set F2 "
+ "blocksize to %d\n", sd_f2_blocksize);
+ }
+
+ /* Release host controller F2 */
+ sdio_release_host(gInstance->func[2]);
+ }
+
+ sdioh_sdmmc_card_enablefuncs(sd);
+ }
+ } else {
+#if !defined(OOB_INTR_ONLY)
+ sdio_claim_host(gInstance->func[0]);
+ if (gInstance->func[2])
+ sdio_claim_irq(gInstance->func[2], IRQHandlerF2);
+ if (gInstance->func[1])
+ sdio_claim_irq(gInstance->func[1], IRQHandler);
+ sdio_release_host(gInstance->func[0]);
+#else /* defined(OOB_INTR_ONLY) */
+#if defined(HW_OOB)
+ sdioh_enable_func_intr();
+#endif
+ bcmsdh_oob_intr_set(TRUE);
+#endif /* !defined(OOB_INTR_ONLY) */
+ }
+ }
+ else
+ AP6210_ERR("%s Failed\n", __FUNCTION__);
+
+ return (0);
+}
+
+int
+sdioh_stop(sdioh_info_t *si)
+{
+ /* MSM7201A Android sdio stack has bug with interrupt
+ So internaly within SDIO stack they are polling
+ which cause issue when device is turned off. So
+ unregister interrupt with SDIO stack to stop the
+ polling
+ */
+ if (gInstance->func[0]) {
+#if !defined(OOB_INTR_ONLY)
+ sdio_claim_host(gInstance->func[0]);
+ if (gInstance->func[1])
+ sdio_release_irq(gInstance->func[1]);
+ if (gInstance->func[2])
+ sdio_release_irq(gInstance->func[2]);
+ sdio_release_host(gInstance->func[0]);
+#else /* defined(OOB_INTR_ONLY) */
+#if defined(HW_OOB)
+ sdioh_disable_func_intr();
+#endif
+ bcmsdh_oob_intr_set(FALSE);
+#endif /* !defined(OOB_INTR_ONLY) */
+ }
+ else
+ AP6210_ERR("%s Failed\n", __FUNCTION__);
+ return (0);
+}
+
+int
+sdioh_waitlockfree(sdioh_info_t *sd)
+{
+ return (1);
+}
+
+
+SDIOH_API_RC
+sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio)
+{
+ return SDIOH_API_RC_FAIL;
+}
+
+SDIOH_API_RC
+sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab)
+{
+ return SDIOH_API_RC_FAIL;
+}
+
+bool
+sdioh_gpioin(sdioh_info_t *sd, uint32 gpio)
+{
+ return FALSE;
+}
+
+SDIOH_API_RC
+sdioh_gpio_init(sdioh_info_t *sd)
+{
+ return SDIOH_API_RC_FAIL;
+}
diff --git a/drivers/net/wireless/ap6210/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/ap6210/bcmsdh_sdmmc_linux.c
new file mode 100644
index 0000000..98b5818
--- /dev/null
+++ b/drivers/net/wireless/ap6210/bcmsdh_sdmmc_linux.c
@@ -0,0 +1,427 @@
+/*
+ * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdh_sdmmc_linux.c 363783 2012-10-19 06:27:14Z $
+ */
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <sdio.h> /* SDIO Device and Protocol Specs */
+#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
+#include <sdiovar.h> /* to get msglevel bit values */
+
+#include <linux/sched.h> /* request_irq() */
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+
+#include <ap6210.h>
+
+#if !defined(SDIO_VENDOR_ID_BROADCOM)
+#define SDIO_VENDOR_ID_BROADCOM 0x02d0
+#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */
+
+#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000
+
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)
+#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4325)
+#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4329)
+#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4319)
+#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4319) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4330)
+#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4330) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4334)
+#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4334) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_4324)
+#define SDIO_DEVICE_ID_BROADCOM_4324 0x4324
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4324) */
+#if !defined(SDIO_DEVICE_ID_BROADCOM_43239)
+#define SDIO_DEVICE_ID_BROADCOM_43239 43239
+#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_43239) */
+
+
+#include <bcmsdh_sdmmc.h>
+
+#include <dhd_dbg.h>
+
+#ifdef WL_CFG80211
+extern void wl_cfg80211_set_parent_dev(void *dev);
+#endif
+
+extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
+extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+extern int dhd_os_check_wakelock(void *dhdp);
+extern int dhd_os_check_if_up(void *dhdp);
+extern void *bcmsdh_get_drvdata(void);
+
+int sdio_function_init(void);
+void sdio_function_cleanup(void);
+
+#define DESCRIPTION "bcmsdh_sdmmc Driver"
+#define AUTHOR "Broadcom Corporation"
+
+/* module param defaults */
+static int clockoverride = 0;
+
+module_param(clockoverride, int, 0644);
+MODULE_PARM_DESC(clockoverride, "SDIO card clock override");
+
+PBCMSDH_SDMMC_INSTANCE gInstance;
+
+/* Maximum number of bcmsdh_sdmmc devices supported by driver */
+#define BCMSDH_SDMMC_MAX_DEVICES 1
+
+extern int bcmsdh_probe(struct device *dev);
+extern int bcmsdh_remove(struct device *dev);
+extern volatile bool dhd_mmc_suspend;
+
+static int bcmsdh_sdmmc_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ int ret = 0;
+ static struct sdio_func sdio_func_0;
+
+ if (func) {
+ AP6210_DEBUG("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__);
+ AP6210_DEBUG("sdio_bcmsdh: func->class=%x\n", func->class);
+ AP6210_DEBUG("sdio_vendor: 0x%04x\n", func->vendor);
+ AP6210_DEBUG("sdio_device: 0x%04x\n", func->device);
+ AP6210_DEBUG("Function#: 0x%04x\n", func->num);
+
+ if (func->num == 1) {
+ sdio_func_0.num = 0;
+ sdio_func_0.card = func->card;
+ gInstance->func[0] = &sdio_func_0;
+ if(func->device == 0x4) { /* 4318 */
+ gInstance->func[2] = NULL;
+ AP6210_DEBUG("NIC found, calling bcmsdh_probe...\n");
+ ret = bcmsdh_probe(&func->dev);
+ }
+ }
+
+ gInstance->func[func->num] = func;
+
+ if (func->num == 2) {
+ #ifdef WL_CFG80211
+ wl_cfg80211_set_parent_dev(&func->dev);
+ #endif
+ AP6210_DEBUG("F2 found, calling bcmsdh_probe...\n");
+ ret = bcmsdh_probe(&func->dev);
+ }
+ } else {
+ ret = -ENODEV;
+ }
+
+ return ret;
+}
+
+static void bcmsdh_sdmmc_remove(struct sdio_func *func)
+{
+ if (func) {
+ AP6210_DEBUG("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__);
+ AP6210_DEBUG("sdio_bcmsdh: func->class=%x\n", func->class);
+ AP6210_DEBUG("sdio_vendor: 0x%04x\n", func->vendor);
+ AP6210_DEBUG("sdio_device: 0x%04x\n", func->device);
+ AP6210_DEBUG("Function#: 0x%04x\n", func->num);
+
+ if (gInstance->func[2]) {
+ AP6210_DEBUG("F2 found, calling bcmsdh_remove...\n");
+ bcmsdh_remove(&func->dev);
+ gInstance->func[2] = NULL;
+ }
+ if (func->num == 1) {
+ sdio_claim_host(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+ gInstance->func[1] = NULL;
+ }
+ }
+}
+
+/* devices we support, null terminated */
+static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4324) },
+ { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43239) },
+ { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) },
+ { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
+static int bcmsdh_sdmmc_suspend(struct device *pdev)
+{
+ struct sdio_func *func = dev_to_sdio_func(pdev);
+ mmc_pm_flag_t sdio_flags;
+ int ret;
+
+ if (func->num != 2)
+ return 0;
+
+ AP6210_DEBUG("%s Enter\n", __FUNCTION__);
+
+ if (dhd_os_check_wakelock(bcmsdh_get_drvdata()))
+ return -EBUSY;
+
+ sdio_flags = sdio_get_host_pm_caps(func);
+
+ if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
+ AP6210_ERR("%s: can't keep power while host is suspended\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ /* keep power while host suspended */
+ ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+ if (ret) {
+ AP6210_ERR("%s: error while trying to keep power\n", __FUNCTION__);
+ return ret;
+ }
+
+#if defined(OOB_INTR_ONLY)
+ bcmsdh_oob_intr_set(0);
+#endif /* defined(OOB_INTR_ONLY) */
+ dhd_mmc_suspend = TRUE;
+ smp_mb();
+
+ return 0;
+}
+
+static int bcmsdh_sdmmc_resume(struct device *pdev)
+{
+#if defined(OOB_INTR_ONLY)
+ struct sdio_func *func = dev_to_sdio_func(pdev);
+#endif /* defined(OOB_INTR_ONLY) */
+ AP6210_DEBUG("%s Enter\n", __FUNCTION__);
+
+ dhd_mmc_suspend = FALSE;
+#if defined(OOB_INTR_ONLY)
+ if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata()))
+ bcmsdh_oob_intr_set(1);
+#endif /* (OOB_INTR_ONLY) */
+ smp_mb();
+ return 0;
+}
+
+static const struct dev_pm_ops bcmsdh_sdmmc_pm_ops = {
+ .suspend = bcmsdh_sdmmc_suspend,
+ .resume = bcmsdh_sdmmc_resume,
+};
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
+
+#if defined(BCMLXSDMMC)
+static struct semaphore *notify_semaphore = NULL;
+
+static int dummy_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ if (notify_semaphore)
+ up(notify_semaphore);
+ return 0;
+}
+
+static void dummy_remove(struct sdio_func *func)
+{
+}
+
+static struct sdio_driver dummy_sdmmc_driver = {
+ .probe = dummy_probe,
+ .remove = dummy_remove,
+ .name = "dummy_sdmmc",
+ .id_table = bcmsdh_sdmmc_ids,
+ };
+
+int sdio_func_reg_notify(void* semaphore)
+{
+ notify_semaphore = semaphore;
+ return sdio_register_driver(&dummy_sdmmc_driver);
+}
+
+void sdio_func_unreg_notify(void)
+{
+ sdio_unregister_driver(&dummy_sdmmc_driver);
+}
+
+#endif /* defined(BCMLXSDMMC) */
+
+static struct sdio_driver bcmsdh_sdmmc_driver = {
+ .probe = bcmsdh_sdmmc_probe,
+ .remove = bcmsdh_sdmmc_remove,
+ .name = "bcmsdh_sdmmc",
+ .id_table = bcmsdh_sdmmc_ids,
+#if !defined(CONFIG_ARCH_RHEA) || !defined(CONFIG_ARCH_CAPRI)
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM)
+ .drv = {
+ .pm = &bcmsdh_sdmmc_pm_ops,
+ },
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM) */
+#endif /* !defined(CONFIG_ARCH_RHEA) || !defined(CONFIG_ARCH_CAPRI) */
+ };
+
+struct sdos_info {
+ sdioh_info_t *sd;
+ spinlock_t lock;
+};
+
+
+int
+sdioh_sdmmc_osinit(sdioh_info_t *sd)
+{
+ struct sdos_info *sdos;
+
+ if (!sd)
+ return BCME_BADARG;
+
+ sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info));
+ sd->sdos_info = (void*)sdos;
+ if (sdos == NULL)
+ return BCME_NOMEM;
+
+ sdos->sd = sd;
+ spin_lock_init(&sdos->lock);
+ return BCME_OK;
+}
+
+void
+sdioh_sdmmc_osfree(sdioh_info_t *sd)
+{
+ struct sdos_info *sdos;
+ ASSERT(sd && sd->sdos_info);
+
+ sdos = (struct sdos_info *)sd->sdos_info;
+ MFREE(sd->osh, sdos, sizeof(struct sdos_info));
+}
+
+/* Interrupt enable/disable */
+SDIOH_API_RC
+sdioh_interrupt_set(sdioh_info_t *sd, bool enable)
+{
+ ulong flags;
+ struct sdos_info *sdos;
+
+ if (!sd)
+ return BCME_BADARG;
+
+ AP6210_DEBUG("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling");
+
+ sdos = (struct sdos_info *)sd->sdos_info;
+ ASSERT(sdos);
+
+#if !defined(OOB_INTR_ONLY)
+ if (enable && !(sd->intr_handler && sd->intr_handler_arg)) {
+ AP6210_ERR("%s: no handler registered, will not enable\n", __FUNCTION__);
+ return SDIOH_API_RC_FAIL;
+ }
+#endif /* !defined(OOB_INTR_ONLY) */
+
+ /* Ensure atomicity for enable/disable calls */
+ spin_lock_irqsave(&sdos->lock, flags);
+
+ sd->client_intr_enabled = enable;
+ if (enable) {
+ sdioh_sdmmc_devintr_on(sd);
+ } else {
+ sdioh_sdmmc_devintr_off(sd);
+ }
+
+ spin_unlock_irqrestore(&sdos->lock, flags);
+
+ return SDIOH_API_RC_SUCCESS;
+}
+
+
+#ifdef BCMSDH_MODULE
+static int __init
+bcmsdh_module_init(void)
+{
+ int error = 0;
+ error = sdio_function_init();
+ return error;
+}
+
+static void __exit
+bcmsdh_module_cleanup(void)
+{
+ sdio_function_cleanup();
+}
+
+module_init(bcmsdh_module_init);
+module_exit(bcmsdh_module_cleanup);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DESCRIPTION);
+MODULE_AUTHOR(AUTHOR);
+
+#endif /* BCMSDH_MODULE */
+/*
+ * module init
+*/
+int sdio_function_init(void)
+{
+ int error = 0;
+ AP6210_DEBUG("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__);
+
+ gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL);
+ if (!gInstance)
+ return -ENOMEM;
+
+ error = sdio_register_driver(&bcmsdh_sdmmc_driver);
+ if (error && gInstance) {
+ kfree(gInstance);
+ gInstance = 0;
+ }
+
+ return error;
+}
+
+/*
+ * module cleanup
+*/
+extern int bcmsdh_remove(struct device *dev);
+void sdio_function_cleanup(void)
+{
+ AP6210_DEBUG("%s Enter\n", __FUNCTION__);
+
+
+ sdio_unregister_driver(&bcmsdh_sdmmc_driver);
+
+ if (gInstance)
+ kfree(gInstance);
+}
diff --git a/drivers/net/wireless/ap6210/bcmutils.c b/drivers/net/wireless/ap6210/bcmutils.c
new file mode 100644
index 0000000..631125a
--- /dev/null
+++ b/drivers/net/wireless/ap6210/bcmutils.c
@@ -0,0 +1,2095 @@
+/*
+ * Driver O/S-independent utility routines
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ * $Id: bcmutils.c 312855 2012-02-04 02:01:18Z $
+ */
+
+#include <bcm_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <stdarg.h>
+#ifdef BCMDRIVER
+
+#include <osl.h>
+#include <bcmutils.h>
+
+#else /* !BCMDRIVER */
+
+#include <stdio.h>
+#include <string.h>
+#include <bcmutils.h>
+
+#if defined(BCMEXTSUP)
+#include <bcm_osl.h>
+#endif
+
+
+#endif /* !BCMDRIVER */
+
+#include <bcmendian.h>
+#include <bcmdevs.h>
+#include <proto/ethernet.h>
+#include <proto/vlan.h>
+#include <proto/bcmip.h>
+#include <proto/802.1d.h>
+#include <proto/802.11.h>
+void *_bcmutils_dummy_fn = NULL;
+
+#include <ap6210.h>
+
+
+#ifdef BCMDRIVER
+
+
+
+/* copy a pkt buffer chain into a buffer */
+uint
+pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf)
+{
+ uint n, ret = 0;
+
+ if (len < 0)
+ len = 4096; /* "infinite" */
+
+ /* skip 'offset' bytes */
+ for (; p && offset; p = PKTNEXT(osh, p)) {
+ if (offset < (uint)PKTLEN(osh, p))
+ break;
+ offset -= PKTLEN(osh, p);
+ }
+
+ if (!p)
+ return 0;
+
+ /* copy the data */
+ for (; p && len; p = PKTNEXT(osh, p)) {
+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
+ bcopy(PKTDATA(osh, p) + offset, buf, n);
+ buf += n;
+ len -= n;
+ ret += n;
+ offset = 0;
+ }
+
+ return ret;
+}
+
+/* copy a buffer into a pkt buffer chain */
+uint
+pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf)
+{
+ uint n, ret = 0;
+
+ /* skip 'offset' bytes */
+ for (; p && offset; p = PKTNEXT(osh, p)) {
+ if (offset < (uint)PKTLEN(osh, p))
+ break;
+ offset -= PKTLEN(osh, p);
+ }
+
+ if (!p)
+ return 0;
+
+ /* copy the data */
+ for (; p && len; p = PKTNEXT(osh, p)) {
+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
+ bcopy(buf, PKTDATA(osh, p) + offset, n);
+ buf += n;
+ len -= n;
+ ret += n;
+ offset = 0;
+ }
+
+ return ret;
+}
+
+
+
+/* return total length of buffer chain */
+uint BCMFASTPATH
+pkttotlen(osl_t *osh, void *p)
+{
+ uint total;
+ int len;
+
+ total = 0;
+ for (; p; p = PKTNEXT(osh, p)) {
+ len = PKTLEN(osh, p);
+ total += len;
+ }
+
+ return (total);
+}
+
+/* return the last buffer of chained pkt */
+void *
+pktlast(osl_t *osh, void *p)
+{
+ for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p))
+ ;
+
+ return (p);
+}
+
+/* count segments of a chained packet */
+uint BCMFASTPATH
+pktsegcnt(osl_t *osh, void *p)
+{
+ uint cnt;
+
+ for (cnt = 0; p; p = PKTNEXT(osh, p))
+ cnt++;
+
+ return cnt;
+}
+
+
+/* count segments of a chained packet */
+uint BCMFASTPATH
+pktsegcnt_war(osl_t *osh, void *p)
+{
+ uint cnt;
+ uint8 *pktdata;
+ uint len, remain, align64;
+
+ for (cnt = 0; p; p = PKTNEXT(osh, p)) {
+ cnt++;
+ len = PKTLEN(osh, p);
+ if (len > 128) {
+ pktdata = (uint8 *)PKTDATA(osh, p); /* starting address of data */
+ /* Check for page boundary straddle (2048B) */
+ if (((uintptr)pktdata & ~0x7ff) != ((uintptr)(pktdata+len) & ~0x7ff))
+ cnt++;
+
+ align64 = (uint)((uintptr)pktdata & 0x3f); /* aligned to 64B */
+ align64 = (64 - align64) & 0x3f;
+ len -= align64; /* bytes from aligned 64B to end */
+ /* if aligned to 128B, check for MOD 128 between 1 to 4B */
+ remain = len % 128;
+ if (remain > 0 && remain <= 4)
+ cnt++; /* add extra seg */
+ }
+ }
+
+ return cnt;
+}
+
+uint8 * BCMFASTPATH
+pktoffset(osl_t *osh, void *p, uint offset)
+{
+ uint total = pkttotlen(osh, p);
+ uint pkt_off = 0, len = 0;
+ uint8 *pdata = (uint8 *) PKTDATA(osh, p);
+
+ if (offset > total)
+ return NULL;
+
+ for (; p; p = PKTNEXT(osh, p)) {
+ pdata = (uint8 *) PKTDATA(osh, p);
+ pkt_off = offset - len;
+ len += PKTLEN(osh, p);
+ if (len > offset)
+ break;
+ }
+ return (uint8*) (pdata+pkt_off);
+}
+
+/*
+ * osl multiple-precedence packet queue
+ * hi_prec is always >= the number of the highest non-empty precedence
+ */
+void * BCMFASTPATH
+pktq_penq(struct pktq *pq, int prec, void *p)
+{
+ struct pktq_prec *q;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
+
+ ASSERT(!pktq_full(pq));
+ ASSERT(!pktq_pfull(pq, prec));
+
+ q = &pq->q[prec];
+
+ if (q->head)
+ PKTSETLINK(q->tail, p);
+ else
+ q->head = p;
+
+ q->tail = p;
+ q->len++;
+
+ pq->len++;
+
+ if (pq->hi_prec < prec)
+ pq->hi_prec = (uint8)prec;
+
+ return p;
+}
+
+void * BCMFASTPATH
+pktq_penq_head(struct pktq *pq, int prec, void *p)
+{
+ struct pktq_prec *q;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
+
+ ASSERT(!pktq_full(pq));
+ ASSERT(!pktq_pfull(pq, prec));
+
+ q = &pq->q[prec];
+
+ if (q->head == NULL)
+ q->tail = p;
+
+ PKTSETLINK(p, q->head);
+ q->head = p;
+ q->len++;
+
+ pq->len++;
+
+ if (pq->hi_prec < prec)
+ pq->hi_prec = (uint8)prec;
+
+ return p;
+}
+
+void * BCMFASTPATH
+pktq_pdeq(struct pktq *pq, int prec)
+{
+ struct pktq_prec *q;
+ void *p;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ q = &pq->q[prec];
+
+ if ((p = q->head) == NULL)
+ return NULL;
+
+ if ((q->head = PKTLINK(p)) == NULL)
+ q->tail = NULL;
+
+ q->len--;
+
+ pq->len--;
+
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+void * BCMFASTPATH
+pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p)
+{
+ struct pktq_prec *q;
+ void *p;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ q = &pq->q[prec];
+
+ if (prev_p == NULL)
+ return NULL;
+
+ if ((p = PKTLINK(prev_p)) == NULL)
+ return NULL;
+
+ q->len--;
+
+ pq->len--;
+
+ PKTSETLINK(prev_p, PKTLINK(p));
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+void * BCMFASTPATH
+pktq_pdeq_tail(struct pktq *pq, int prec)
+{
+ struct pktq_prec *q;
+ void *p, *prev;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ q = &pq->q[prec];
+
+ if ((p = q->head) == NULL)
+ return NULL;
+
+ for (prev = NULL; p != q->tail; p = PKTLINK(p))
+ prev = p;
+
+ if (prev)
+ PKTSETLINK(prev, NULL);
+ else
+ q->head = NULL;
+
+ q->tail = prev;
+ q->len--;
+
+ pq->len--;
+
+ return p;
+}
+
+void
+pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg)
+{
+ struct pktq_prec *q;
+ void *p, *prev = NULL;
+
+ q = &pq->q[prec];
+ p = q->head;
+ while (p) {
+ if (fn == NULL || (*fn)(p, arg)) {
+ bool head = (p == q->head);
+ if (head)
+ q->head = PKTLINK(p);
+ else
+ PKTSETLINK(prev, PKTLINK(p));
+ PKTSETLINK(p, NULL);
+ PKTFREE(osh, p, dir);
+ q->len--;
+ pq->len--;
+ p = (head ? q->head : PKTLINK(prev));
+ } else {
+ prev = p;
+ p = PKTLINK(p);
+ }
+ }
+
+ if (q->head == NULL) {
+ ASSERT(q->len == 0);
+ q->tail = NULL;
+ }
+}
+
+bool BCMFASTPATH
+pktq_pdel(struct pktq *pq, void *pktbuf, int prec)
+{
+ struct pktq_prec *q;
+ void *p;
+
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ if (!pktbuf)
+ return FALSE;
+
+ q = &pq->q[prec];
+
+ if (q->head == pktbuf) {
+ if ((q->head = PKTLINK(pktbuf)) == NULL)
+ q->tail = NULL;
+ } else {
+ for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p))
+ ;
+ if (p == NULL)
+ return FALSE;
+
+ PKTSETLINK(p, PKTLINK(pktbuf));
+ if (q->tail == pktbuf)
+ q->tail = p;
+ }
+
+ q->len--;
+ pq->len--;
+ PKTSETLINK(pktbuf, NULL);
+ return TRUE;
+}
+
+void
+pktq_init(struct pktq *pq, int num_prec, int max_len)
+{
+ int prec;
+
+ ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC);
+
+ /* pq is variable size; only zero out what's requested */
+ bzero(pq, OFFSETOF(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
+
+ pq->num_prec = (uint16)num_prec;
+
+ pq->max = (uint16)max_len;
+
+ for (prec = 0; prec < num_prec; prec++)
+ pq->q[prec].max = pq->max;
+}
+
+void
+pktq_set_max_plen(struct pktq *pq, int prec, int max_len)
+{
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ if (prec < pq->num_prec)
+ pq->q[prec].max = (uint16)max_len;
+}
+
+void * BCMFASTPATH
+pktq_deq(struct pktq *pq, int *prec_out)
+{
+ struct pktq_prec *q;
+ void *p;
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
+
+ q = &pq->q[prec];
+
+ if ((p = q->head) == NULL)
+ return NULL;
+
+ if ((q->head = PKTLINK(p)) == NULL)
+ q->tail = NULL;
+
+ q->len--;
+
+ pq->len--;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+void * BCMFASTPATH
+pktq_deq_tail(struct pktq *pq, int *prec_out)
+{
+ struct pktq_prec *q;
+ void *p, *prev;
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ for (prec = 0; prec < pq->hi_prec; prec++)
+ if (pq->q[prec].head)
+ break;
+
+ q = &pq->q[prec];
+
+ if ((p = q->head) == NULL)
+ return NULL;
+
+ for (prev = NULL; p != q->tail; p = PKTLINK(p))
+ prev = p;
+
+ if (prev)
+ PKTSETLINK(prev, NULL);
+ else
+ q->head = NULL;
+
+ q->tail = prev;
+ q->len--;
+
+ pq->len--;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+void *
+pktq_peek(struct pktq *pq, int *prec_out)
+{
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ return (pq->q[prec].head);
+}
+
+void *
+pktq_peek_tail(struct pktq *pq, int *prec_out)
+{
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ for (prec = 0; prec < pq->hi_prec; prec++)
+ if (pq->q[prec].head)
+ break;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ return (pq->q[prec].tail);
+}
+
+void
+pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg)
+{
+ int prec;
+
+ /* Optimize flush, if pktq len = 0, just return.
+ * pktq len of 0 means pktq's prec q's are all empty.
+ */
+ if (pq->len == 0) {
+ return;
+ }
+
+ for (prec = 0; prec < pq->num_prec; prec++)
+ pktq_pflush(osh, pq, prec, dir, fn, arg);
+ if (fn == NULL)
+ ASSERT(pq->len == 0);
+}
+
+/* Return sum of lengths of a specific set of precedences */
+int
+pktq_mlen(struct pktq *pq, uint prec_bmp)
+{
+ int prec, len;
+
+ len = 0;
+
+ for (prec = 0; prec <= pq->hi_prec; prec++)
+ if (prec_bmp & (1 << prec))
+ len += pq->q[prec].len;
+
+ return len;
+}
+
+/* Priority peek from a specific set of precedences */
+void * BCMFASTPATH
+pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out)
+{
+ struct pktq_prec *q;
+ void *p;
+ int prec;
+
+ if (pq->len == 0)
+ {
+ return NULL;
+ }
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
+
+ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
+ if (prec-- == 0)
+ return NULL;
+
+ q = &pq->q[prec];
+
+ if ((p = q->head) == NULL)
+ return NULL;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ return p;
+}
+/* Priority dequeue from a specific set of precedences */
+void * BCMFASTPATH
+pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out)
+{
+ struct pktq_prec *q;
+ void *p;
+ int prec;
+
+ if (pq->len == 0)
+ return NULL;
+
+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+ pq->hi_prec--;
+
+ while ((pq->q[prec].head == NULL) || ((prec_bmp & (1 << prec)) == 0))
+ if (prec-- == 0)
+ return NULL;
+
+ q = &pq->q[prec];
+
+ if ((p = q->head) == NULL)
+ return NULL;
+
+ if ((q->head = PKTLINK(p)) == NULL)
+ q->tail = NULL;
+
+ q->len--;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ pq->len--;
+
+ PKTSETLINK(p, NULL);
+
+ return p;
+}
+
+#endif /* BCMDRIVER */
+
+const unsigned char bcm_ctype[] = {
+
+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */
+ _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C,
+ _BCM_C, /* 8-15 */
+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */
+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */
+ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */
+ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */
+ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */
+ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */
+ _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X,
+ _BCM_U|_BCM_X, _BCM_U, /* 64-71 */
+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */
+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */
+ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */
+ _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X,
+ _BCM_L|_BCM_X, _BCM_L, /* 96-103 */
+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
+ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */
+ _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
+ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U,
+ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L,
+ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
+};
+
+ulong
+bcm_strtoul(const char *cp, char **endp, uint base)
+{
+ ulong result, last_result = 0, value;
+ bool minus;
+
+ minus = FALSE;
+
+ while (bcm_isspace(*cp))
+ cp++;
+
+ if (cp[0] == '+')
+ cp++;
+ else if (cp[0] == '-') {
+ minus = TRUE;
+ cp++;
+ }
+
+ if (base == 0) {
+ if (cp[0] == '0') {
+ if ((cp[1] == 'x') || (cp[1] == 'X')) {
+ base = 16;
+ cp = &cp[2];
+ } else {
+ base = 8;
+ cp = &cp[1];
+ }
+ } else
+ base = 10;
+ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
+ cp = &cp[2];
+ }
+
+ result = 0;
+
+ while (bcm_isxdigit(*cp) &&
+ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) {
+ result = result*base + value;
+ /* Detected overflow */
+ if (result < last_result && !minus)
+ return (ulong)-1;
+ last_result = result;
+ cp++;
+ }
+
+ if (minus)
+ result = (ulong)(-(long)result);
+
+ if (endp)
+ *endp = DISCARD_QUAL(cp, char);
+
+ return (result);
+}
+
+int
+bcm_atoi(const char *s)
+{
+ return (int)bcm_strtoul(s, NULL, 10);
+}
+
+/* return pointer to location of substring 'needle' in 'haystack' */
+char *
+bcmstrstr(const char *haystack, const char *needle)
+{
+ int len, nlen;
+ int i;
+
+ if ((haystack == NULL) || (needle == NULL))
+ return DISCARD_QUAL(haystack, char);
+
+ nlen = strlen(needle);
+ len = strlen(haystack) - nlen + 1;
+
+ for (i = 0; i < len; i++)
+ if (memcmp(needle, &haystack[i], nlen) == 0)
+ return DISCARD_QUAL(&haystack[i], char);
+ return (NULL);
+}
+
+char *
+bcmstrcat(char *dest, const char *src)
+{
+ char *p;
+
+ p = dest + strlen(dest);
+
+ while ((*p++ = *src++) != '\0')
+ ;
+
+ return (dest);
+}
+
+char *
+bcmstrncat(char *dest, const char *src, uint size)
+{
+ char *endp;
+ char *p;
+
+ p = dest + strlen(dest);
+ endp = p + size;
+
+ while (p != endp && (*p++ = *src++) != '\0')
+ ;
+
+ return (dest);
+}
+
+
+/****************************************************************************
+* Function: bcmstrtok
+*
+* Purpose:
+* Tokenizes a string. This function is conceptually similiar to ANSI C strtok(),
+* but allows strToken() to be used by different strings or callers at the same
+* time. Each call modifies '*string' by substituting a NULL character for the
+* first delimiter that is encountered, and updates 'string' to point to the char
+* after the delimiter. Leading delimiters are skipped.
+*
+* Parameters:
+* string (mod) Ptr to string ptr, updated by token.
+* delimiters (in) Set of delimiter characters.
+* tokdelim (out) Character that delimits the returned token. (May
+* be set to NULL if token delimiter is not required).
+*
+* Returns: Pointer to the next token found. NULL when no more tokens are found.
+*****************************************************************************
+*/
+char *
+bcmstrtok(char **string, const char *delimiters, char *tokdelim)
+{
+ unsigned char *str;
+ unsigned long map[8];
+ int count;
+ char *nextoken;
+
+ if (tokdelim != NULL) {
+ /* Prime the token delimiter */
+ *tokdelim = '\0';
+ }
+
+ /* Clear control map */
+ for (count = 0; count < 8; count++) {
+ map[count] = 0;
+ }
+
+ /* Set bits in delimiter table */
+ do {
+ map[*delimiters >> 5] |= (1 << (*delimiters & 31));
+ }
+ while (*delimiters++);
+
+ str = (unsigned char*)*string;
+
+ /* Find beginning of token (skip over leading delimiters). Note that
+ * there is no token iff this loop sets str to point to the terminal
+ * null (*str == '\0')
+ */
+ while (((map[*str >> 5] & (1 << (*str & 31))) && *str) || (*str == ' ')) {
+ str++;
+ }
+
+ nextoken = (char*)str;
+
+ /* Find the end of the token. If it is not the end of the string,
+ * put a null there.
+ */
+ for (; *str; str++) {
+ if (map[*str >> 5] & (1 << (*str & 31))) {
+ if (tokdelim != NULL) {
+ *tokdelim = *str;
+ }
+
+ *str++ = '\0';
+ break;
+ }
+ }
+
+ *string = (char*)str;
+
+ /* Determine if a token has been found. */
+ if (nextoken == (char *) str) {
+ return NULL;
+ }
+ else {
+ return nextoken;
+ }
+}
+
+
+#define xToLower(C) \
+ ((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C)
+
+
+/****************************************************************************
+* Function: bcmstricmp
+*
+* Purpose: Compare to strings case insensitively.
+*
+* Parameters: s1 (in) First string to compare.
+* s2 (in) Second string to compare.
+*
+* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
+* t1 > t2, when ignoring case sensitivity.
+*****************************************************************************
+*/
+int
+bcmstricmp(const char *s1, const char *s2)
+{
+ char dc, sc;
+
+ while (*s2 && *s1) {
+ dc = xToLower(*s1);
+ sc = xToLower(*s2);
+ if (dc < sc) return -1;
+ if (dc > sc) return 1;
+ s1++;
+ s2++;
+ }
+
+ if (*s1 && !*s2) return 1;
+ if (!*s1 && *s2) return -1;
+ return 0;
+}
+
+
+/****************************************************************************
+* Function: bcmstrnicmp
+*
+* Purpose: Compare to strings case insensitively, upto a max of 'cnt'
+* characters.
+*
+* Parameters: s1 (in) First string to compare.
+* s2 (in) Second string to compare.
+* cnt (in) Max characters to compare.
+*
+* Returns: Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
+* t1 > t2, when ignoring case sensitivity.
+*****************************************************************************
+*/
+int
+bcmstrnicmp(const char* s1, const char* s2, int cnt)
+{
+ char dc, sc;
+
+ while (*s2 && *s1 && cnt) {
+ dc = xToLower(*s1);
+ sc = xToLower(*s2);
+ if (dc < sc) return -1;
+ if (dc > sc) return 1;
+ s1++;
+ s2++;
+ cnt--;
+ }
+
+ if (!cnt) return 0;
+ if (*s1 && !*s2) return 1;
+ if (!*s1 && *s2) return -1;
+ return 0;
+}
+
+/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
+int
+bcm_ether_atoe(const char *p, struct ether_addr *ea)
+{
+ int i = 0;
+ char *ep;
+
+ for (;;) {
+ ea->octet[i++] = (char) bcm_strtoul(p, &ep, 16);
+ p = ep;
+ if (!*p++ || i == 6)
+ break;
+ }
+
+ return (i == 6);
+}
+
+
+#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER)
+/* registry routine buffer preparation utility functions:
+ * parameter order is like strncpy, but returns count
+ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2)
+ */
+ulong
+wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen)
+{
+ ulong copyct = 1;
+ ushort i;
+
+ if (abuflen == 0)
+ return 0;
+
+ /* wbuflen is in bytes */
+ wbuflen /= sizeof(ushort);
+
+ for (i = 0; i < wbuflen; ++i) {
+ if (--abuflen == 0)
+ break;
+ *abuf++ = (char) *wbuf++;
+ ++copyct;
+ }
+ *abuf = '\0';
+
+ return copyct;
+}
+#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */
+
+char *
+bcm_ether_ntoa(const struct ether_addr *ea, char *buf)
+{
+ static const char hex[] =
+ {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+ const uint8 *octet = ea->octet;
+ char *p = buf;
+ int i;
+
+ for (i = 0; i < 6; i++, octet++) {
+ *p++ = hex[(*octet >> 4) & 0xf];
+ *p++ = hex[*octet & 0xf];
+ *p++ = ':';
+ }
+
+ *(p-1) = '\0';
+
+ return (buf);
+}
+
+char *
+bcm_ip_ntoa(struct ipv4_addr *ia, char *buf)
+{
+ snprintf(buf, 16, "%d.%d.%d.%d",
+ ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]);
+ return (buf);
+}
+
+#ifdef BCMDRIVER
+
+void
+bcm_mdelay(uint ms)
+{
+ uint i;
+
+ for (i = 0; i < ms; i++) {
+ OSL_DELAY(1000);
+ }
+}
+
+
+
+
+
+#if defined(DHD_DEBUG)
+/* pretty hex print a pkt buffer chain */
+void
+prpkt(const char *msg, osl_t *osh, void *p0)
+{
+ void *p;
+
+ if (msg && (msg[0] != '\0'))
+ AP6210_DEBUG("%s:\n", msg);
+
+ for (p = p0; p; p = PKTNEXT(osh, p))
+ prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p));
+}
+#endif
+
+/* Takes an Ethernet frame and sets out-of-bound PKTPRIO.
+ * Also updates the inplace vlan tag if requested.
+ * For debugging, it returns an indication of what it did.
+ */
+uint BCMFASTPATH
+pktsetprio(void *pkt, bool update_vtag)
+{
+ struct ether_header *eh;
+ struct ethervlan_header *evh;
+ uint8 *pktdata;
+ int priority = 0;
+ int rc = 0;
+
+ pktdata = (uint8 *)PKTDATA(NULL, pkt);
+ ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16)));
+
+ eh = (struct ether_header *) pktdata;
+
+ if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) {
+ uint16 vlan_tag;
+ int vlan_prio, dscp_prio = 0;
+
+ evh = (struct ethervlan_header *)eh;
+
+ vlan_tag = ntoh16(evh->vlan_tag);
+ vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
+
+ if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) {
+ uint8 *ip_body = pktdata + sizeof(struct ethervlan_header);
+ uint8 tos_tc = IP_TOS46(ip_body);
+ dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
+ }
+
+ /* DSCP priority gets precedence over 802.1P (vlan tag) */
+ if (dscp_prio != 0) {
+ priority = dscp_prio;
+ rc |= PKTPRIO_VDSCP;
+ } else {
+ priority = vlan_prio;
+ rc |= PKTPRIO_VLAN;
+ }
+ /*
+ * If the DSCP priority is not the same as the VLAN priority,
+ * then overwrite the priority field in the vlan tag, with the
+ * DSCP priority value. This is required for Linux APs because
+ * the VLAN driver on Linux, overwrites the skb->priority field
+ * with the priority value in the vlan tag
+ */
+ if (update_vtag && (priority != vlan_prio)) {
+ vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT);
+ vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT;
+ evh->vlan_tag = hton16(vlan_tag);
+ rc |= PKTPRIO_UPD;
+ }
+ } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) {
+ uint8 *ip_body = pktdata + sizeof(struct ether_header);
+ uint8 tos_tc = IP_TOS46(ip_body);
+ priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT);
+ rc |= PKTPRIO_DSCP;
+ }
+
+ ASSERT(priority >= 0 && priority <= MAXPRIO);
+ PKTSETPRIO(pkt, priority);
+ return (rc | priority);
+}
+
+
+static char bcm_undeferrstr[32];
+static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
+
+/* Convert the error codes into related error strings */
+const char *
+bcmerrorstr(int bcmerror)
+{
+ /* check if someone added a bcmerror code but forgot to add errorstring */
+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1));
+
+ if (bcmerror > 0 || bcmerror < BCME_LAST) {
+ snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr), "Undefined error %d", bcmerror);
+ return bcm_undeferrstr;
+ }
+
+ ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN);
+
+ return bcmerrorstrtable[-bcmerror];
+}
+
+
+
+/* iovar table lookup */
+const bcm_iovar_t*
+bcm_iovar_lookup(const bcm_iovar_t *table, const char *name)
+{
+ const bcm_iovar_t *vi;
+ const char *lookup_name;
+
+ /* skip any ':' delimited option prefixes */
+ lookup_name = strrchr(name, ':');
+ if (lookup_name != NULL)
+ lookup_name++;
+ else
+ lookup_name = name;
+
+ ASSERT(table != NULL);
+
+ for (vi = table; vi->name; vi++) {
+ if (!strcmp(vi->name, lookup_name))
+ return vi;
+ }
+ /* ran to end of table */
+
+ return NULL; /* var name not found */
+}
+
+int
+bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
+{
+ int bcmerror = 0;
+
+ /* length check on io buf */
+ switch (vi->type) {
+ case IOVT_BOOL:
+ case IOVT_INT8:
+ case IOVT_INT16:
+ case IOVT_INT32:
+ case IOVT_UINT8:
+ case IOVT_UINT16:
+ case IOVT_UINT32:
+ /* all integers are int32 sized args at the ioctl interface */
+ if (len < (int)sizeof(int)) {
+ bcmerror = BCME_BUFTOOSHORT;
+ }
+ break;
+
+ case IOVT_BUFFER:
+ /* buffer must meet minimum length requirement */
+ if (len < vi->minlen) {
+ bcmerror = BCME_BUFTOOSHORT;
+ }
+ break;
+
+ case IOVT_VOID:
+ if (!set) {
+ /* Cannot return nil... */
+ bcmerror = BCME_UNSUPPORTED;
+ } else if (len) {
+ /* Set is an action w/o parameters */
+ bcmerror = BCME_BUFTOOLONG;
+ }
+ break;
+
+ default:
+ /* unknown type for length check in iovar info */
+ ASSERT(0);
+ bcmerror = BCME_UNSUPPORTED;
+ }
+
+ return bcmerror;
+}
+
+#endif /* BCMDRIVER */
+
+
+/*******************************************************************************
+ * crc8
+ *
+ * Computes a crc8 over the input data using the polynomial:
+ *
+ * x^8 + x^7 +x^6 + x^4 + x^2 + 1
+ *
+ * The caller provides the initial value (either CRC8_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data. When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream. When checking, a final
+ * return value of CRC8_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint8 crc8_table[256] = {
+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
+};
+
+#define CRC_INNER_LOOP(n, c, x) \
+ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
+
+uint8
+hndcrc8(
+ uint8 *pdata, /* pointer to array of data to process */
+ uint nbytes, /* number of input data bytes to process */
+ uint8 crc /* either CRC8_INIT_VALUE or previous return value */
+)
+{
+ /* hard code the crc loop instead of using CRC_INNER_LOOP macro
+ * to avoid the undefined and unnecessary (uint8 >> 8) operation.
+ */
+ while (nbytes-- > 0)
+ crc = crc8_table[(crc ^ *pdata++) & 0xff];
+
+ return crc;
+}
+
+/*******************************************************************************
+ * crc16
+ *
+ * Computes a crc16 over the input data using the polynomial:
+ *
+ * x^16 + x^12 +x^5 + 1
+ *
+ * The caller provides the initial value (either CRC16_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data. When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream. When checking, a final
+ * return value of CRC16_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint16 crc16_table[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
+ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
+ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
+ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
+ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
+ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
+ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
+ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
+ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
+ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
+ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
+ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
+ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
+ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
+ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
+ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
+ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
+ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
+ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
+ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
+ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
+ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
+ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
+ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
+ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
+ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
+ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
+ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
+ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
+ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
+ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
+ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
+};
+
+uint16
+hndcrc16(
+ uint8 *pdata, /* pointer to array of data to process */
+ uint nbytes, /* number of input data bytes to process */
+ uint16 crc /* either CRC16_INIT_VALUE or previous return value */
+)
+{
+ while (nbytes-- > 0)
+ CRC_INNER_LOOP(16, crc, *pdata++);
+ return crc;
+}
+
+static const uint32 crc32_table[256] = {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+};
+
+/*
+ * crc input is CRC32_INIT_VALUE for a fresh start, or previous return value if
+ * accumulating over multiple pieces.
+ */
+uint32
+hndcrc32(uint8 *pdata, uint nbytes, uint32 crc)
+{
+ uint8 *pend;
+ pend = pdata + nbytes;
+ while (pdata < pend)
+ CRC_INNER_LOOP(32, crc, *pdata++);
+
+ return crc;
+}
+
+#ifdef notdef
+#define CLEN 1499 /* CRC Length */
+#define CBUFSIZ (CLEN+4)
+#define CNBUFS 5 /* # of bufs */
+
+void
+testcrc32(void)
+{
+ uint j, k, l;
+ uint8 *buf;
+ uint len[CNBUFS];
+ uint32 crcr;
+ uint32 crc32tv[CNBUFS] =
+ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110};
+
+ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL);
+
+ /* step through all possible alignments */
+ for (l = 0; l <= 4; l++) {
+ for (j = 0; j < CNBUFS; j++) {
+ len[j] = CLEN;
+ for (k = 0; k < len[j]; k++)
+ *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff;
+ }
+
+ for (j = 0; j < CNBUFS; j++) {
+ crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE);
+ ASSERT(crcr == crc32tv[j]);
+ }
+ }
+
+ MFREE(buf, CBUFSIZ*CNBUFS);
+ return;
+}
+#endif /* notdef */
+
+/*
+ * Advance from the current 1-byte tag/1-byte length/variable-length value
+ * triple, to the next, returning a pointer to the next.
+ * If the current or next TLV is invalid (does not fit in given buffer length),
+ * NULL is returned.
+ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented
+ * by the TLV parameter's length if it is valid.
+ */
+bcm_tlv_t *
+bcm_next_tlv(bcm_tlv_t *elt, int *buflen)
+{
+ int len;
+
+ /* validate current elt */
+ if (!bcm_valid_tlv(elt, *buflen))
+ return NULL;
+
+ /* advance to next elt */
+ len = elt->len;
+ elt = (bcm_tlv_t*)(elt->data + len);
+ *buflen -= (TLV_HDR_LEN + len);
+
+ /* validate next elt */
+ if (!bcm_valid_tlv(elt, *buflen))
+ return NULL;
+
+ return elt;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag
+ */
+bcm_tlv_t *
+bcm_parse_tlvs(void *buf, int buflen, uint key)
+{
+ bcm_tlv_t *elt;
+ int totlen;
+
+ elt = (bcm_tlv_t*)buf;
+ totlen = buflen;
+
+ /* find tagged parameter */
+ while (totlen >= TLV_HDR_LEN) {
+ int len = elt->len;
+
+ /* validate remaining totlen */
+ if ((elt->id == key) &&
+ (totlen >= (len + TLV_HDR_LEN)))
+ return (elt);
+
+ elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN));
+ totlen -= (len + TLV_HDR_LEN);
+ }
+
+ return NULL;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag. Stop parsing when we see an element whose ID is greater
+ * than the target key.
+ */
+bcm_tlv_t *
+bcm_parse_ordered_tlvs(void *buf, int buflen, uint key)
+{
+ bcm_tlv_t *elt;
+ int totlen;
+
+ elt = (bcm_tlv_t*)buf;
+ totlen = buflen;
+
+ /* find tagged parameter */
+ while (totlen >= TLV_HDR_LEN) {
+ uint id = elt->id;
+ int len = elt->len;
+
+ /* Punt if we start seeing IDs > than target key */
+ if (id > key)
+ return (NULL);
+
+ /* validate remaining totlen */
+ if ((id == key) &&
+ (totlen >= (len + TLV_HDR_LEN)))
+ return (elt);
+
+ elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN));
+ totlen -= (len + TLV_HDR_LEN);
+ }
+ return NULL;
+}
+
+#if defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || defined(WLMSG_ASSOC) || \
+ defined(DHD_DEBUG)
+int
+bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len)
+{
+ int i;
+ char* p = buf;
+ char hexstr[16];
+ int slen = 0, nlen = 0;
+ uint32 bit;
+ const char* name;
+
+ if (len < 2 || !buf)
+ return 0;
+
+ buf[0] = '\0';
+
+ for (i = 0; flags != 0; i++) {
+ bit = bd[i].bit;
+ name = bd[i].name;
+ if (bit == 0 && flags != 0) {
+ /* print any unnamed bits */
+ snprintf(hexstr, 16, "0x%X", flags);
+ name = hexstr;
+ flags = 0; /* exit loop */
+ } else if ((flags & bit) == 0)
+ continue;
+ flags &= ~bit;
+ nlen = strlen(name);
+ slen += nlen;
+ /* count btwn flag space */
+ if (flags != 0)
+ slen += 1;
+ /* need NULL char as well */
+ if (len <= slen)
+ break;
+ /* copy NULL char but don't count it */
+ strncpy(p, name, nlen + 1);
+ p += nlen;
+ /* copy btwn flag space and NULL char */
+ if (flags != 0)
+ p += snprintf(p, 2, " ");
+ }
+
+ /* indicate the str was too short */
+ if (flags != 0) {
+ if (len < 2)
+ p -= 2 - len; /* overwrite last char */
+ p += snprintf(p, 2, ">");
+ }
+
+ return (int)(p - buf);
+}
+
+/* print bytes formatted as hex to a string. return the resulting string length */
+int
+bcm_format_hex(char *str, const void *bytes, int len)
+{
+ int i;
+ char *p = str;
+ const uint8 *src = (const uint8*)bytes;
+
+ for (i = 0; i < len; i++) {
+ p += snprintf(p, 3, "%02X", *src);
+ src++;
+ }
+ return (int)(p - str);
+}
+#endif
+
+/* pretty hex print a contiguous buffer */
+void
+prhex(const char *msg, uchar *buf, uint nbytes)
+{
+ char line[128], *p;
+ int len = sizeof(line);
+ int nchar;
+ uint i;
+
+ if (msg && (msg[0] != '\0'))
+ AP6210_DEBUG("%s:\n", msg);
+
+ p = line;
+ for (i = 0; i < nbytes; i++) {
+ if (i % 16 == 0) {
+ nchar = snprintf(p, len, " %04d: ", i); /* line prefix */
+ p += nchar;
+ len -= nchar;
+ }
+ if (len > 0) {
+ nchar = snprintf(p, len, "%02x ", buf[i]);
+ p += nchar;
+ len -= nchar;
+ }
+
+ if (i % 16 == 15) {
+ AP6210_DEBUG("%s\n", line); /* flush line */
+ p = line;
+ len = sizeof(line);
+ }
+ }
+
+ /* flush last partial line */
+ if (p != line)
+ AP6210_DUMP("%s\n", line);
+}
+
+static const char *crypto_algo_names[] = {
+ "NONE",
+ "WEP1",
+ "TKIP",
+ "WEP128",
+ "AES_CCM",
+ "AES_OCB_MSDU",
+ "AES_OCB_MPDU",
+ "NALG"
+ "UNDEF",
+ "UNDEF",
+ "UNDEF",
+#ifdef BCMWAPI_WPI
+ "WAPI",
+#endif /* BCMWAPI_WPI */
+ "UNDEF"
+};
+
+const char *
+bcm_crypto_algo_name(uint algo)
+{
+ return (algo < ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR";
+}
+
+
+char *
+bcm_chipname(uint chipid, char *buf, uint len)
+{
+ const char *fmt;
+
+ fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
+ snprintf(buf, len, fmt, chipid);
+ return buf;
+}
+
+/* Produce a human-readable string for boardrev */
+char *
+bcm_brev_str(uint32 brev, char *buf)
+{
+ if (brev < 0x100)
+ snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf);
+ else
+ snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff);
+
+ return (buf);
+}
+
+#define BUFSIZE_TODUMP_ATONCE 512 /* Buffer size */
+
+/* dump large strings to console */
+void
+printbig(char *buf)
+{
+ uint len, max_len;
+ char c;
+
+ len = strlen(buf);
+
+ max_len = BUFSIZE_TODUMP_ATONCE;
+
+ while (len > max_len) {
+ c = buf[max_len];
+ buf[max_len] = '\0';
+ AP6210_DUMP("%s", buf);
+ buf[max_len] = c;
+
+ buf += max_len;
+ len -= max_len;
+ }
+ /* print the remaining string */
+ AP6210_DUMP("%s\n", buf);
+ return;
+}
+
+/* routine to dump fields in a fileddesc structure */
+uint
+bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array,
+ char *buf, uint32 bufsize)
+{
+ uint filled_len;
+ int len;
+ struct fielddesc *cur_ptr;
+
+ filled_len = 0;
+ cur_ptr = fielddesc_array;
+
+ while (bufsize > 1) {
+ if (cur_ptr->nameandfmt == NULL)
+ break;
+ len = snprintf(buf, bufsize, cur_ptr->nameandfmt,
+ read_rtn(arg0, arg1, cur_ptr->offset));
+ /* check for snprintf overflow or error */
+ if (len < 0 || (uint32)len >= bufsize)
+ len = bufsize - 1;
+ buf += len;
+ bufsize -= len;
+ filled_len += len;
+ cur_ptr++;
+ }
+ return filled_len;
+}
+
+uint
+bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
+{
+ uint len;
+
+ len = strlen(name) + 1;
+
+ if ((len + datalen) > buflen)
+ return 0;
+
+ strncpy(buf, name, buflen);
+
+ /* append data onto the end of the name string */
+ memcpy(&buf[len], data, datalen);
+ len += datalen;
+
+ return len;
+}
+
+/* Quarter dBm units to mW
+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+ * Table is offset so the last entry is largest mW value that fits in
+ * a uint16.
+ */
+
+#define QDBM_OFFSET 153 /* Offset for first entry */
+#define QDBM_TABLE_LEN 40 /* Table size */
+
+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+ */
+#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
+
+/* Largest mW value that will round down to the last table entry,
+ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+ */
+#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
+
+static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
+};
+
+uint16
+bcm_qdbm_to_mw(uint8 qdbm)
+{
+ uint factor = 1;
+ int idx = qdbm - QDBM_OFFSET;
+
+ if (idx >= QDBM_TABLE_LEN) {
+ /* clamp to max uint16 mW value */
+ return 0xFFFF;
+ }
+
+ /* scale the qdBm index up to the range of the table 0-40
+ * where an offset of 40 qdBm equals a factor of 10 mW.
+ */
+ while (idx < 0) {
+ idx += 40;
+ factor *= 10;
+ }
+
+ /* return the mW value scaled down to the correct factor of 10,
+ * adding in factor/2 to get proper rounding.
+ */
+ return ((nqdBm_to_mW_map[idx] + factor/2) / factor);
+}
+
+uint8
+bcm_mw_to_qdbm(uint16 mw)
+{
+ uint8 qdbm;
+ int offset;
+ uint mw_uint = mw;
+ uint boundary;
+
+ /* handle boundary case */
+ if (mw_uint <= 1)
+ return 0;
+
+ offset = QDBM_OFFSET;
+
+ /* move mw into the range of the table */
+ while (mw_uint < QDBM_TABLE_LOW_BOUND) {
+ mw_uint *= 10;
+ offset -= 40;
+ }
+
+ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) {
+ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] -
+ nqdBm_to_mW_map[qdbm])/2;
+ if (mw_uint < boundary) break;
+ }
+
+ qdbm += (uint8)offset;
+
+ return (qdbm);
+}
+
+
+uint
+bcm_bitcount(uint8 *bitmap, uint length)
+{
+ uint bitcount = 0, i;
+ uint8 tmp;
+ for (i = 0; i < length; i++) {
+ tmp = bitmap[i];
+ while (tmp) {
+ bitcount++;
+ tmp &= (tmp - 1);
+ }
+ }
+ return bitcount;
+}
+
+#ifdef BCMDRIVER
+
+/* Initialization of bcmstrbuf structure */
+void
+bcm_binit(struct bcmstrbuf *b, char *buf, uint size)
+{
+ b->origsize = b->size = size;
+ b->origbuf = b->buf = buf;
+}
+
+/* Buffer sprintf wrapper to guard against buffer overflow */
+int
+bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ va_start(ap, fmt);
+
+ r = vsnprintf(b->buf, b->size, fmt, ap);
+
+ /* Non Ansi C99 compliant returns -1,
+ * Ansi compliant return r >= b->size,
+ * bcmstdlib returns 0, handle all
+ */
+ /* r == 0 is also the case when strlen(fmt) is zero.
+ * typically the case when "" is passed as argument.
+ */
+ if ((r == -1) || (r >= (int)b->size)) {
+ b->size = 0;
+ } else {
+ b->size -= r;
+ b->buf += r;
+ }
+
+ va_end(ap);
+
+ return r;
+}
+
+void
+bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len)
+{
+ int i;
+
+ if (msg != NULL && msg[0] != '\0')
+ bcm_bprintf(b, "%s", msg);
+ for (i = 0; i < len; i ++)
+ bcm_bprintf(b, "%02X", buf[i]);
+ if (newline)
+ bcm_bprintf(b, "\n");
+}
+
+void
+bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount)
+{
+ int i;
+
+ for (i = 0; i < num_bytes; i++) {
+ num[i] += amount;
+ if (num[i] >= amount)
+ break;
+ amount = 1;
+ }
+}
+
+int
+bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes)
+{
+ int i;
+
+ for (i = nbytes - 1; i >= 0; i--) {
+ if (arg1[i] != arg2[i])
+ return (arg1[i] - arg2[i]);
+ }
+ return 0;
+}
+
+void
+bcm_print_bytes(const char *name, const uchar *data, int len)
+{
+ int i;
+ int per_line = 0;
+
+ AP6210_DEBUG("%s: %d \n", name ? name : "", len);
+ for (i = 0; i < len; i++) {
+ AP6210_DUMP("%02x ", *data++);
+ per_line++;
+ if (per_line == 16) {
+ per_line = 0;
+ AP6210_DUMP("\n");
+ }
+ }
+ AP6210_DUMP("\n");
+}
+#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \
+ defined(WLMSG_PRPKT) || defined(WLMSG_WSEC)
+#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1)
+
+int
+bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len)
+{
+ uint i, c;
+ char *p = buf;
+ char *endp = buf + SSID_FMT_BUF_LEN;
+
+ if (ssid_len > DOT11_MAX_SSID_LEN) ssid_len = DOT11_MAX_SSID_LEN;
+
+ for (i = 0; i < ssid_len; i++) {
+ c = (uint)ssid[i];
+ if (c == '\\') {
+ *p++ = '\\';
+ *p++ = '\\';
+ } else if (bcm_isprint((uchar)c)) {
+ *p++ = (char)c;
+ } else {
+ p += snprintf(p, (endp - p), "\\x%02X", c);
+ }
+ }
+ *p = '\0';
+ ASSERT(p < endp);
+
+ return (int)(p - buf);
+}
+#endif
+
+#endif /* BCMDRIVER */
+
+/*
+ * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file and ending in a NUL.
+ * also accepts nvram files which are already in the format of <var1>=<value>\0\<var2>=<value2>\0
+ * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs.
+ * Shortens buffer as needed and pads with NULs. End of buffer is marked by two NULs.
+*/
+
+unsigned int
+process_nvram_vars(char *varbuf, unsigned int len)
+{
+ char *dp;
+ bool findNewline;
+ int column;
+ unsigned int buf_len, n;
+ unsigned int pad = 0;
+
+ dp = varbuf;
+
+ findNewline = FALSE;
+ column = 0;
+
+ for (n = 0; n < len; n++) {
+ if (varbuf[n] == '\r')
+ continue;
+ if (findNewline && varbuf[n] != '\n')
+ continue;
+ findNewline = FALSE;
+ if (varbuf[n] == '#') {
+ findNewline = TRUE;
+ continue;
+ }
+ if (varbuf[n] == '\n') {
+ if (column == 0)
+ continue;
+ *dp++ = 0;
+ column = 0;
+ continue;
+ }
+ *dp++ = varbuf[n];
+ column++;
+ }
+ buf_len = (unsigned int)(dp - varbuf);
+ if (buf_len % 4) {
+ pad = 4 - buf_len % 4;
+ if (pad && (buf_len + pad <= len)) {
+ buf_len += pad;
+ }
+ }
+
+ while (dp < varbuf + n)
+ *dp++ = 0;
+
+ return buf_len;
+}
diff --git a/drivers/net/wireless/ap6210/bcmwifi_channels.c b/drivers/net/wireless/ap6210/bcmwifi_channels.c
new file mode 100644
index 0000000..6b5b0a3
--- /dev/null
+++ b/drivers/net/wireless/ap6210/bcmwifi_channels.c
@@ -0,0 +1,1179 @@
+/*
+ * Misc utility routines used by kernel or app-level.
+ * Contents are wifi-specific, used by any kernel or app-level
+ * software that might want wifi things as it grows.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ * $Id: bcmwifi_channels.c 309193 2012-01-19 00:03:57Z $
+ */
+
+#include <bcm_cfg.h>
+#include <typedefs.h>
+
+#ifdef BCMDRIVER
+#include <osl.h>
+#include <bcmutils.h>
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifndef ASSERT
+#define ASSERT(exp)
+#endif
+#endif /* BCMDRIVER */
+
+#ifdef _bcmwifi_c_
+/* temporary for transitional compatibility */
+#include <bcmwifi.h>
+#else
+#include <bcmwifi_channels.h>
+#endif
+
+#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL))
+#include <bcmstdlib.h> /* For wl/exe/GNUmakefile.brcm_wlu and GNUmakefile.wlm_dll */
+#endif
+
+#ifndef D11AC_IOTYPES
+
+/* Definitions for legacy Chanspec type */
+
+/* Chanspec ASCII representation:
+ * <channel><band><bandwidth><ctl-sideband>
+ * digit [AB] [N] [UL]
+ *
+ * <channel>: channel number of the 10MHz or 20MHz channel,
+ * or control sideband channel of 40MHz channel.
+ * <band>: A for 5GHz, B for 2.4GHz
+ * <bandwidth>: N for 10MHz, nothing for 20MHz or 40MHz
+ * (ctl-sideband spec implies 40MHz)
+ * <ctl-sideband>: U for upper, L for lower
+ *
+ * <band> may be omitted on input, and will be assumed to be
+ * 2.4GHz if channel number <= 14.
+ *
+ * Examples:
+ * 8 -> 2.4GHz channel 8, 20MHz
+ * 8b -> 2.4GHz channel 8, 20MHz
+ * 8l -> 2.4GHz channel 8, 40MHz, lower ctl sideband
+ * 8a -> 5GHz channel 8 (low 5 GHz band), 20MHz
+ * 36 -> 5GHz channel 36, 20MHz
+ * 36l -> 5GHz channel 36, 40MHz, lower ctl sideband
+ * 40u -> 5GHz channel 40, 40MHz, upper ctl sideband
+ * 180n -> channel 180, 10MHz
+ */
+
+
+/* given a chanspec and a string buffer, format the chanspec as a
+ * string, and return the original pointer a.
+ * Min buffer length must be CHANSPEC_STR_LEN.
+ * On error return NULL
+ */
+char *
+wf_chspec_ntoa(chanspec_t chspec, char *buf)
+{
+ const char *band, *bw, *sb;
+ uint channel;
+
+ band = "";
+ bw = "";
+ sb = "";
+ channel = CHSPEC_CHANNEL(chspec);
+ /* check for non-default band spec */
+ if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) ||
+ (CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL))
+ band = (CHSPEC_IS2G(chspec)) ? "b" : "a";
+ if (CHSPEC_IS40(chspec)) {
+ if (CHSPEC_SB_UPPER(chspec)) {
+ sb = "u";
+ channel += CH_10MHZ_APART;
+ } else {
+ sb = "l";
+ channel -= CH_10MHZ_APART;
+ }
+ } else if (CHSPEC_IS10(chspec)) {
+ bw = "n";
+ }
+
+ /* Outputs a max of 6 chars including '\0' */
+ snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb);
+ return (buf);
+}
+
+/* given a chanspec string, convert to a chanspec.
+ * On error return 0
+ */
+chanspec_t
+wf_chspec_aton(const char *a)
+{
+ char *endp = NULL;
+ uint channel, band, bw, ctl_sb;
+ char c;
+
+ channel = strtoul(a, &endp, 10);
+
+ /* check for no digits parsed */
+ if (endp == a)
+ return 0;
+
+ if (channel > MAXCHANNEL)
+ return 0;
+
+ band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
+ bw = WL_CHANSPEC_BW_20;
+ ctl_sb = WL_CHANSPEC_CTL_SB_NONE;
+
+ a = endp;
+
+ c = tolower(a[0]);
+ if (c == '\0')
+ goto done;
+
+ /* parse the optional ['A' | 'B'] band spec */
+ if (c == 'a' || c == 'b') {
+ band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G;
+ a++;
+ c = tolower(a[0]);
+ if (c == '\0')
+ goto done;
+ }
+
+ /* parse bandwidth 'N' (10MHz) or 40MHz ctl sideband ['L' | 'U'] */
+ if (c == 'n') {
+ bw = WL_CHANSPEC_BW_10;
+ } else if (c == 'l') {
+ bw = WL_CHANSPEC_BW_40;
+ ctl_sb = WL_CHANSPEC_CTL_SB_LOWER;
+ /* adjust channel to center of 40MHz band */
+ if (channel <= (MAXCHANNEL - CH_20MHZ_APART))
+ channel += CH_10MHZ_APART;
+ else
+ return 0;
+ } else if (c == 'u') {
+ bw = WL_CHANSPEC_BW_40;
+ ctl_sb = WL_CHANSPEC_CTL_SB_UPPER;
+ /* adjust channel to center of 40MHz band */
+ if (channel > CH_20MHZ_APART)
+ channel -= CH_10MHZ_APART;
+ else
+ return 0;
+ } else {
+ return 0;
+ }
+
+done:
+ return (channel | band | bw | ctl_sb);
+}
+
+/*
+ * Verify the chanspec is using a legal set of parameters, i.e. that the
+ * chanspec specified a band, bw, ctl_sb and channel and that the
+ * combination could be legal given any set of circumstances.
+ * RETURNS: TRUE is the chanspec is malformed, false if it looks good.
+ */
+bool
+wf_chspec_malformed(chanspec_t chanspec)
+{
+ /* must be 2G or 5G band */
+ if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
+ return TRUE;
+ /* must be 20 or 40 bandwidth */
+ if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
+ return TRUE;
+
+ /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
+ if (CHSPEC_IS20(chanspec)) {
+ if (!CHSPEC_SB_NONE(chanspec))
+ return TRUE;
+ } else {
+ if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * This function returns the channel number that control traffic is being sent on, for legacy
+ * channels this is just the channel number, for 40MHZ channels it is the upper or lower 20MHZ
+ * sideband depending on the chanspec selected
+ */
+uint8
+wf_chspec_ctlchan(chanspec_t chspec)
+{
+ uint8 ctl_chan;
+
+ /* Is there a sideband ? */
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
+ return CHSPEC_CHANNEL(chspec);
+ } else {
+ /* we only support 40MHZ with sidebands */
+ ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40);
+ /* chanspec channel holds the centre frequency, use that and the
+ * side band information to reconstruct the control channel number
+ */
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
+ /* control chan is the upper 20 MHZ SB of the 40MHZ channel */
+ ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+ } else {
+ ASSERT(CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_LOWER);
+ /* control chan is the lower 20 MHZ SB of the 40MHZ channel */
+ ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+ }
+ }
+
+ return ctl_chan;
+}
+
+chanspec_t
+wf_chspec_ctlchspec(chanspec_t chspec)
+{
+ chanspec_t ctl_chspec = 0;
+ uint8 channel;
+
+ ASSERT(!wf_chspec_malformed(chspec));
+
+ /* Is there a sideband ? */
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
+ return chspec;
+ } else {
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
+ channel = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+ } else {
+ channel = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+ }
+ ctl_chspec = channel | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
+ ctl_chspec |= CHSPEC_BAND(chspec);
+ }
+ return ctl_chspec;
+}
+
+#else /* D11AC_IOTYPES */
+
+/* Definitions for D11AC capable Chanspec type */
+
+/* Chanspec ASCII representation with 802.11ac capability:
+ * [<band> 'g'] <channel> ['/'<bandwidth> [<ctl-sideband>]['/'<1st80channel>'-'<2nd80channel>]]
+ *
+ * <band>:
+ * (optional) 2, 3, 4, 5 for 2.4GHz, 3GHz, 4GHz, and 5GHz respectively.
+ * Default value is 2g if channel <= 14, otherwise 5g.
+ * <channel>:
+ * channel number of the 5MHz, 10MHz, 20MHz channel,
+ * or primary channel of 40MHz, 80MHz, 160MHz, or 80+80MHz channel.
+ * <bandwidth>:
+ * (optional) 5, 10, 20, 40, 80, 160, or 80+80. Default value is 20.
+ * <primary-sideband>:
+ * (only for 2.4GHz band 40MHz) U for upper sideband primary, L for lower.
+ *
+ * For 2.4GHz band 40MHz channels, the same primary channel may be the
+ * upper sideband for one 40MHz channel, and the lower sideband for an
+ * overlapping 40MHz channel. The U/L disambiguates which 40MHz channel
+ * is being specified.
+ *
+ * For 40MHz in the 5GHz band and all channel bandwidths greater than
+ * 40MHz, the U/L specificaion is not allowed since the channels are
+ * non-overlapping and the primary sub-band is derived from its
+ * position in the wide bandwidth channel.
+ *
+ * <1st80Channel>:
+ * <2nd80Channel>:
+ * Required for 80+80, otherwise not allowed.
+ * Specifies the center channel of the first and second 80MHz band.
+ *
+ * In its simplest form, it is a 20MHz channel number, with the implied band
+ * of 2.4GHz if channel number <= 14, and 5GHz otherwise.
+ *
+ * To allow for backward compatibility with scripts, the old form for
+ * 40MHz channels is also allowed: <channel><ctl-sideband>
+ *
+ * <channel>:
+ * primary channel of 40MHz, channel <= 14 is 2GHz, otherwise 5GHz
+ * <ctl-sideband>:
+ * "U" for upper, "L" for lower (or lower case "u" "l")
+ *
+ * 5 GHz Examples:
+ * Chanspec BW Center Ch Channel Range Primary Ch
+ * 5g8 20MHz 8 - -
+ * 52 20MHz 52 - -
+ * 52/40 40MHz 54 52-56 52
+ * 56/40 40MHz 54 52-56 56
+ * 52/80 80MHz 58 52-64 52
+ * 56/80 80MHz 58 52-64 56
+ * 60/80 80MHz 58 52-64 60
+ * 64/80 80MHz 58 52-64 64
+ * 52/160 160MHz 50 36-64 52
+ * 36/160 160MGz 50 36-64 36
+ * 36/80+80/42-106 80+80MHz 42,106 36-48,100-112 36
+ *
+ * 2 GHz Examples:
+ * Chanspec BW Center Ch Channel Range Primary Ch
+ * 2g8 20MHz 8 - -
+ * 8 20MHz 8 - -
+ * 6 20MHz 6 - -
+ * 6/40l 40MHz 8 6-10 6
+ * 6l 40MHz 8 6-10 6
+ * 6/40u 40MHz 4 2-6 6
+ * 6u 40MHz 4 2-6 6
+ */
+
+/* bandwidth ASCII string */
+static const char *wf_chspec_bw_str[] =
+{
+ "5",
+ "10",
+ "20",
+ "40",
+ "80",
+ "160",
+ "80+80",
+ "na"
+};
+
+static const uint8 wf_chspec_bw_mhz[] =
+{5, 10, 20, 40, 80, 160, 160};
+
+#define WF_NUM_BW \
+ (sizeof(wf_chspec_bw_mhz)/sizeof(uint8))
+
+/* 40MHz channels in 5GHz band */
+static const uint8 wf_5g_40m_chans[] =
+{38, 46, 54, 62, 102, 110, 118, 126, 134, 142, 151, 159};
+#define WF_NUM_5G_40M_CHANS \
+ (sizeof(wf_5g_40m_chans)/sizeof(uint8))
+
+/* 80MHz channels in 5GHz band */
+static const uint8 wf_5g_80m_chans[] =
+{42, 58, 106, 122, 138, 155};
+#define WF_NUM_5G_80M_CHANS \
+ (sizeof(wf_5g_80m_chans)/sizeof(uint8))
+
+/* 160MHz channels in 5GHz band */
+static const uint8 wf_5g_160m_chans[] =
+{50, 114};
+#define WF_NUM_5G_160M_CHANS \
+ (sizeof(wf_5g_160m_chans)/sizeof(uint8))
+
+
+/* convert bandwidth from chanspec to MHz */
+static uint
+bw_chspec_to_mhz(chanspec_t chspec)
+{
+ uint bw;
+
+ bw = (chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT;
+ return (bw >= WF_NUM_BW ? 0 : wf_chspec_bw_mhz[bw]);
+}
+
+/* bw in MHz, return the channel count from the center channel to the
+ * the channel at the edge of the band
+ */
+static uint8
+center_chan_to_edge(uint bw)
+{
+ /* edge channels separated by BW - 10MHz on each side
+ * delta from cf to edge is half of that,
+ * MHz to channel num conversion is 5MHz/channel
+ */
+ return (uint8)(((bw - 20) / 2) / 5);
+}
+
+/* return channel number of the low edge of the band
+ * given the center channel and BW
+ */
+static uint8
+channel_low_edge(uint center_ch, uint bw)
+{
+ return (uint8)(center_ch - center_chan_to_edge(bw));
+}
+
+/* return side band number given center channel and control channel
+ * return -1 on error
+ */
+static int
+channel_to_sb(uint center_ch, uint ctl_ch, uint bw)
+{
+ uint lowest = channel_low_edge(center_ch, bw);
+ uint sb;
+
+ if ((ctl_ch - lowest) % 4) {
+ /* bad ctl channel, not mult 4 */
+ return -1;
+ }
+
+ sb = ((ctl_ch - lowest) / 4);
+
+ /* sb must be a index to a 20MHz channel in range */
+ if (sb >= (bw / 20)) {
+ /* ctl_ch must have been too high for the center_ch */
+ return -1;
+ }
+
+ return sb;
+}
+
+/* return control channel given center channel and side band */
+static uint8
+channel_to_ctl_chan(uint center_ch, uint bw, uint sb)
+{
+ return (uint8)(channel_low_edge(center_ch, bw) + sb * 4);
+}
+
+/* return index of 80MHz channel from channel number
+ * return -1 on error
+ */
+static int
+channel_80mhz_to_id(uint ch)
+{
+ uint i;
+ for (i = 0; i < WF_NUM_5G_80M_CHANS; i ++) {
+ if (ch == wf_5g_80m_chans[i])
+ return i;
+ }
+
+ return -1;
+}
+
+/* given a chanspec and a string buffer, format the chanspec as a
+ * string, and return the original pointer a.
+ * Min buffer length must be CHANSPEC_STR_LEN.
+ * On error return NULL
+ */
+char *
+wf_chspec_ntoa(chanspec_t chspec, char *buf)
+{
+ const char *band;
+ uint ctl_chan;
+
+ if (wf_chspec_malformed(chspec))
+ return NULL;
+
+ band = "";
+
+ /* check for non-default band spec */
+ if ((CHSPEC_IS2G(chspec) && CHSPEC_CHANNEL(chspec) > CH_MAX_2G_CHANNEL) ||
+ (CHSPEC_IS5G(chspec) && CHSPEC_CHANNEL(chspec) <= CH_MAX_2G_CHANNEL))
+ band = (CHSPEC_IS2G(chspec)) ? "2g" : "5g";
+
+ /* ctl channel */
+ ctl_chan = wf_chspec_ctlchan(chspec);
+
+ /* bandwidth and ctl sideband */
+ if (CHSPEC_IS20(chspec)) {
+ snprintf(buf, CHANSPEC_STR_LEN, "%s%d", band, ctl_chan);
+ } else if (!CHSPEC_IS8080(chspec)) {
+ const char *bw;
+ const char *sb = "";
+
+ bw = wf_chspec_bw_str[(chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT];
+
+#ifdef CHANSPEC_NEW_40MHZ_FORMAT
+ /* ctl sideband string if needed for 2g 40MHz */
+ if (CHSPEC_IS40(chspec) && CHSPEC_IS2G(chspec)) {
+ sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l";
+ }
+
+ snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s%s", band, ctl_chan, bw, sb);
+#else
+ /* ctl sideband string instead of BW for 40MHz */
+ if (CHSPEC_IS40(chspec)) {
+ sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l";
+ snprintf(buf, CHANSPEC_STR_LEN, "%s%d%s", band, ctl_chan, sb);
+ } else {
+ snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s", band, ctl_chan, bw);
+ }
+#endif /* CHANSPEC_NEW_40MHZ_FORMAT */
+
+ } else {
+ /* 80+80 */
+ uint chan1 = (chspec & WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT;
+ uint chan2 = (chspec & WL_CHANSPEC_CHAN2_MASK) >> WL_CHANSPEC_CHAN2_SHIFT;
+
+ /* convert to channel number */
+ chan1 = (chan1 < WF_NUM_5G_80M_CHANS) ? wf_5g_80m_chans[chan1] : 0;
+ chan2 = (chan2 < WF_NUM_5G_80M_CHANS) ? wf_5g_80m_chans[chan2] : 0;
+
+ /* Outputs a max of CHANSPEC_STR_LEN chars including '\0' */
+ snprintf(buf, CHANSPEC_STR_LEN, "%d/80+80/%d-%d", ctl_chan, chan1, chan2);
+ }
+
+ return (buf);
+}
+
+static int
+read_uint(const char **p, unsigned int *num)
+{
+ unsigned long val;
+ char *endp = NULL;
+
+ val = strtoul(*p, &endp, 10);
+ /* if endp is the initial pointer value, then a number was not read */
+ if (endp == *p)
+ return 0;
+
+ /* advance the buffer pointer to the end of the integer string */
+ *p = endp;
+ /* return the parsed integer */
+ *num = (unsigned int)val;
+
+ return 1;
+}
+
+/* given a chanspec string, convert to a chanspec.
+ * On error return 0
+ */
+chanspec_t
+wf_chspec_aton(const char *a)
+{
+ chanspec_t chspec;
+ uint chspec_ch, chspec_band, bw, chspec_bw, chspec_sb;
+ uint num, ctl_ch;
+ uint ch1, ch2;
+ char c, sb_ul = '\0';
+ int i;
+
+ bw = 20;
+ chspec_sb = 0;
+ chspec_ch = ch1 = ch2 = 0;
+
+ /* parse channel num or band */
+ if (!read_uint(&a, &num))
+ return 0;
+
+ /* if we are looking at a 'g', then the first number was a band */
+ c = tolower(a[0]);
+ if (c == 'g') {
+ a ++; /* consume the char */
+
+ /* band must be "2" or "5" */
+ if (num == 2)
+ chspec_band = WL_CHANSPEC_BAND_2G;
+ else if (num == 5)
+ chspec_band = WL_CHANSPEC_BAND_5G;
+ else
+ return 0;
+
+ /* read the channel number */
+ if (!read_uint(&a, &ctl_ch))
+ return 0;
+
+ c = tolower(a[0]);
+ }
+ else {
+ /* first number is channel, use default for band */
+ ctl_ch = num;
+ chspec_band = ((ctl_ch <= CH_MAX_2G_CHANNEL) ?
+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
+ }
+
+ if (c == '\0') {
+ /* default BW of 20MHz */
+ chspec_bw = WL_CHANSPEC_BW_20;
+ goto done_read;
+ }
+
+ a ++; /* consume the 'u','l', or '/' */
+
+ /* check 'u'/'l' */
+ if (c == 'u' || c == 'l') {
+ sb_ul = c;
+ chspec_bw = WL_CHANSPEC_BW_40;
+ goto done_read;
+ }
+
+ /* next letter must be '/' */
+ if (c != '/')
+ return 0;
+
+ /* read bandwidth */
+ if (!read_uint(&a, &bw))
+ return 0;
+
+ /* convert to chspec value */
+ if (bw == 20) {
+ chspec_bw = WL_CHANSPEC_BW_20;
+ } else if (bw == 40) {
+ chspec_bw = WL_CHANSPEC_BW_40;
+ } else if (bw == 80) {
+ chspec_bw = WL_CHANSPEC_BW_80;
+ } else if (bw == 160) {
+ chspec_bw = WL_CHANSPEC_BW_160;
+ } else {
+ return 0;
+ }
+
+ /* So far we have <band>g<chan>/<bw>
+ * Can now be followed by u/l if bw = 40,
+ * or '+80' if bw = 80, to make '80+80' bw.
+ */
+
+ c = tolower(a[0]);
+
+ /* if we have a 2g/40 channel, we should have a l/u spec now */
+ if (chspec_band == WL_CHANSPEC_BAND_2G && bw == 40) {
+ if (c == 'u' || c == 'l') {
+ a ++; /* consume the u/l char */
+ sb_ul = c;
+ goto done_read;
+ }
+ }
+
+ /* check for 80+80 */
+ if (c == '+') {
+ /* 80+80 */
+ static const char *plus80 = "80/";
+
+ /* must be looking at '+80/'
+ * check and consume this string.
+ */
+ chspec_bw = WL_CHANSPEC_BW_8080;
+
+ a ++; /* consume the char '+' */
+
+ /* consume the '80/' string */
+ for (i = 0; i < 3; i++) {
+ if (*a++ != *plus80++) {
+ return 0;
+ }
+ }
+
+ /* read primary 80MHz channel */
+ if (!read_uint(&a, &ch1))
+ return 0;
+
+ /* must followed by '-' */
+ if (a[0] != '-')
+ return 0;
+ a ++; /* consume the char */
+
+ /* read secondary 80MHz channel */
+ if (!read_uint(&a, &ch2))
+ return 0;
+ }
+
+done_read:
+ /* skip trailing white space */
+ while (a[0] == ' ') {
+ a ++;
+ }
+
+ /* must be end of string */
+ if (a[0] != '\0')
+ return 0;
+
+ /* Now have all the chanspec string parts read;
+ * chspec_band, ctl_ch, chspec_bw, sb_ul, ch1, ch2.
+ * chspec_band and chspec_bw are chanspec values.
+ * Need to convert ctl_ch, sb_ul, and ch1,ch2 into
+ * a center channel (or two) and sideband.
+ */
+
+ /* if a sb u/l string was given, just use that,
+ * guaranteed to be bw = 40 by sting parse.
+ */
+ if (sb_ul != '\0') {
+ if (sb_ul == 'l') {
+ chspec_ch = UPPER_20_SB(ctl_ch);
+ chspec_sb = WL_CHANSPEC_CTL_SB_LLL;
+ } else if (sb_ul == 'u') {
+ chspec_ch = LOWER_20_SB(ctl_ch);
+ chspec_sb = WL_CHANSPEC_CTL_SB_LLU;
+ }
+ }
+ /* if the bw is 20, center and sideband are trivial */
+ else if (chspec_bw == WL_CHANSPEC_BW_20) {
+ chspec_ch = ctl_ch;
+ chspec_sb = 0;
+ }
+ /* if the bw is 40/80/160, not 80+80, a single method
+ * can be used to to find the center and sideband
+ */
+ else if (chspec_bw != WL_CHANSPEC_BW_8080) {
+ /* figure out ctl sideband based on ctl channel and bandwidth */
+ const uint8 *center_ch = NULL;
+ int num_ch = 0;
+ int sb = -1;
+
+ if (chspec_bw == WL_CHANSPEC_BW_40) {
+ center_ch = wf_5g_40m_chans;
+ num_ch = WF_NUM_5G_40M_CHANS;
+ } else if (chspec_bw == WL_CHANSPEC_BW_80) {
+ center_ch = wf_5g_80m_chans;
+ num_ch = WF_NUM_5G_80M_CHANS;
+ } else if (chspec_bw == WL_CHANSPEC_BW_160) {
+ center_ch = wf_5g_160m_chans;
+ num_ch = WF_NUM_5G_160M_CHANS;
+ } else {
+ return 0;
+ }
+
+ for (i = 0; i < num_ch; i ++) {
+ sb = channel_to_sb(center_ch[i], ctl_ch, bw);
+ if (sb >= 0) {
+ chspec_ch = center_ch[i];
+ chspec_sb = sb << WL_CHANSPEC_CTL_SB_SHIFT;
+ break;
+ }
+ }
+
+ /* check for no matching sb/center */
+ if (sb < 0) {
+ return 0;
+ }
+ }
+ /* Otherwise, bw is 80+80. Figure out channel pair and sb */
+ else {
+ int ch1_id = 0, ch2_id = 0;
+ int sb;
+
+ ch1_id = channel_80mhz_to_id(ch1);
+ ch2_id = channel_80mhz_to_id(ch2);
+
+ /* validate channels */
+ if (ch1 >= ch2 || ch1_id < 0 || ch2_id < 0)
+ return 0;
+
+ /* combined channel in chspec */
+ chspec_ch = (((uint16)ch1_id << WL_CHANSPEC_CHAN1_SHIFT) |
+ ((uint16)ch2_id << WL_CHANSPEC_CHAN2_SHIFT));
+
+ /* figure out ctl sideband */
+
+ /* does the primary channel fit with the 1st 80MHz channel ? */
+ sb = channel_to_sb(ch1, ctl_ch, bw);
+ if (sb < 0) {
+ /* no, so does the primary channel fit with the 2nd 80MHz channel ? */
+ sb = channel_to_sb(ch2, ctl_ch, bw);
+ if (sb < 0) {
+ /* no match for ctl_ch to either 80MHz center channel */
+ return 0;
+ }
+ /* sb index is 0-3 for the low 80MHz channel, and 4-7 for
+ * the high 80MHz channel. Add 4 to to shift to high set.
+ */
+ sb += 4;
+ }
+
+ chspec_sb = sb << WL_CHANSPEC_CTL_SB_SHIFT;
+ }
+
+ chspec = (chspec_ch | chspec_band | chspec_bw | chspec_sb);
+
+ if (wf_chspec_malformed(chspec))
+ return 0;
+
+ return chspec;
+}
+
+/*
+ * Verify the chanspec is using a legal set of parameters, i.e. that the
+ * chanspec specified a band, bw, ctl_sb and channel and that the
+ * combination could be legal given any set of circumstances.
+ * RETURNS: TRUE is the chanspec is malformed, false if it looks good.
+ */
+bool
+wf_chspec_malformed(chanspec_t chanspec)
+{
+ uint chspec_bw = CHSPEC_BW(chanspec);
+ uint chspec_ch = CHSPEC_CHANNEL(chanspec);
+
+ /* must be 2G or 5G band */
+ if (CHSPEC_IS2G(chanspec)) {
+ /* must be valid bandwidth */
+ if (chspec_bw != WL_CHANSPEC_BW_20 &&
+ chspec_bw != WL_CHANSPEC_BW_40) {
+ return TRUE;
+ }
+ } else if (CHSPEC_IS5G(chanspec)) {
+ if (chspec_bw == WL_CHANSPEC_BW_8080) {
+ uint ch1_id, ch2_id;
+
+ /* channel number in 80+80 must be in range */
+ ch1_id = CHSPEC_CHAN1(chanspec);
+ ch2_id = CHSPEC_CHAN2(chanspec);
+ if (ch1_id >= WF_NUM_5G_80M_CHANS || ch2_id >= WF_NUM_5G_80M_CHANS)
+ return TRUE;
+
+ /* ch2 must be above ch1 for the chanspec */
+ if (ch2_id <= ch1_id)
+ return TRUE;
+ } else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 ||
+ chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) {
+
+ if (chspec_ch > MAXCHANNEL) {
+ return TRUE;
+ }
+ } else {
+ /* invalid bandwidth */
+ return TRUE;
+ }
+ } else {
+ /* must be 2G or 5G band */
+ return TRUE;
+ }
+
+ /* side band needs to be consistent with bandwidth */
+ if (chspec_bw == WL_CHANSPEC_BW_20) {
+ if (CHSPEC_CTL_SB(chanspec) != WL_CHANSPEC_CTL_SB_LLL)
+ return TRUE;
+ } else if (chspec_bw == WL_CHANSPEC_BW_40) {
+ if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LLU)
+ return TRUE;
+ } else if (chspec_bw == WL_CHANSPEC_BW_80) {
+ if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LUU)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Verify the chanspec specifies a valid channel according to 802.11.
+ * RETURNS: TRUE if the chanspec is a valid 802.11 channel
+ */
+bool
+wf_chspec_valid(chanspec_t chanspec)
+{
+ uint chspec_bw = CHSPEC_BW(chanspec);
+ uint chspec_ch = CHSPEC_CHANNEL(chanspec);
+
+ if (wf_chspec_malformed(chanspec))
+ return FALSE;
+
+ if (CHSPEC_IS2G(chanspec)) {
+ /* must be valid bandwidth and channel range */
+ if (chspec_bw == WL_CHANSPEC_BW_20) {
+ if (chspec_ch >= 1 && chspec_ch <= 14)
+ return TRUE;
+ } else if (chspec_bw == WL_CHANSPEC_BW_40) {
+ if (chspec_ch >= 3 && chspec_ch <= 11)
+ return TRUE;
+ }
+ } else if (CHSPEC_IS5G(chanspec)) {
+ if (chspec_bw == WL_CHANSPEC_BW_8080) {
+ uint16 ch1, ch2;
+
+ ch1 = wf_5g_80m_chans[CHSPEC_CHAN1(chanspec)];
+ ch2 = wf_5g_80m_chans[CHSPEC_CHAN2(chanspec)];
+
+ /* the two channels must be separated by more than 80MHz by VHT req,
+ * and ch2 above ch1 for the chanspec
+ */
+ if (ch2 > ch1 + CH_80MHZ_APART)
+ return TRUE;
+ } else {
+ const uint8 *center_ch;
+ uint num_ch, i;
+
+ if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40) {
+ center_ch = wf_5g_40m_chans;
+ num_ch = WF_NUM_5G_40M_CHANS;
+ } else if (chspec_bw == WL_CHANSPEC_BW_80) {
+ center_ch = wf_5g_80m_chans;
+ num_ch = WF_NUM_5G_80M_CHANS;
+ } else if (chspec_bw == WL_CHANSPEC_BW_160) {
+ center_ch = wf_5g_160m_chans;
+ num_ch = WF_NUM_5G_160M_CHANS;
+ } else {
+ /* invalid bandwidth */
+ return FALSE;
+ }
+
+ /* check for a valid center channel */
+ if (chspec_bw == WL_CHANSPEC_BW_20) {
+ /* We don't have an array of legal 20MHz 5G channels, but they are
+ * each side of the legal 40MHz channels. Check the chanspec
+ * channel against either side of the 40MHz channels.
+ */
+ for (i = 0; i < num_ch; i ++) {
+ if (chspec_ch == (uint)LOWER_20_SB(center_ch[i]) ||
+ chspec_ch == (uint)UPPER_20_SB(center_ch[i]))
+ break; /* match found */
+ }
+
+ if (i == num_ch) {
+ /* check for legacy JP channels on failure */
+ if (chspec_ch == 34 || chspec_ch == 38 ||
+ chspec_ch == 42 || chspec_ch == 46)
+ i = 0;
+ }
+ } else {
+ /* check the chanspec channel to each legal channel */
+ for (i = 0; i < num_ch; i ++) {
+ if (chspec_ch == center_ch[i])
+ break; /* match found */
+ }
+ }
+
+ if (i < num_ch) {
+ /* match found */
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ * This function returns the channel number that control traffic is being sent on, for 20MHz
+ * channels this is just the channel number, for 40MHZ, 80MHz, 160MHz channels it is the 20MHZ
+ * sideband depending on the chanspec selected
+ */
+uint8
+wf_chspec_ctlchan(chanspec_t chspec)
+{
+ uint center_chan;
+ uint bw_mhz;
+ uint sb;
+
+ ASSERT(!wf_chspec_malformed(chspec));
+
+ /* Is there a sideband ? */
+ if (CHSPEC_IS20(chspec)) {
+ return CHSPEC_CHANNEL(chspec);
+ } else {
+ sb = CHSPEC_CTL_SB(chspec) >> WL_CHANSPEC_CTL_SB_SHIFT;
+
+ if (CHSPEC_IS8080(chspec)) {
+ bw_mhz = 80;
+
+ if (sb < 4) {
+ center_chan = CHSPEC_CHAN1(chspec);
+ }
+ else {
+ center_chan = CHSPEC_CHAN2(chspec);
+ sb -= 4;
+ }
+
+ /* convert from channel index to channel number */
+ center_chan = wf_5g_80m_chans[center_chan];
+ }
+ else {
+ bw_mhz = bw_chspec_to_mhz(chspec);
+ center_chan = CHSPEC_CHANNEL(chspec) >> WL_CHANSPEC_CHAN_SHIFT;
+ }
+
+ return (channel_to_ctl_chan(center_chan, bw_mhz, sb));
+ }
+}
+
+/*
+ * This function returns the chanspec of the control channel of a given chanspec
+ */
+chanspec_t
+wf_chspec_ctlchspec(chanspec_t chspec)
+{
+ chanspec_t ctl_chspec = chspec;
+ uint8 ctl_chan;
+
+ ASSERT(!wf_chspec_malformed(chspec));
+
+ /* Is there a sideband ? */
+ if (!CHSPEC_IS20(chspec)) {
+ ctl_chan = wf_chspec_ctlchan(chspec);
+ ctl_chspec = ctl_chan | WL_CHANSPEC_BW_20;
+ ctl_chspec |= CHSPEC_BAND(chspec);
+ }
+ return ctl_chspec;
+}
+
+/* return chanspec given control channel and bandwidth
+ * return 0 on error
+ */
+uint16
+wf_channel2chspec(uint ctl_ch, uint bw)
+{
+ uint16 chspec;
+ const uint8 *center_ch = NULL;
+ int num_ch = 0;
+ int sb = -1;
+ int i = 0;
+
+ chspec = ((ctl_ch <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
+
+ chspec |= bw;
+
+ if (bw == WL_CHANSPEC_BW_40) {
+ center_ch = wf_5g_40m_chans;
+ num_ch = WF_NUM_5G_40M_CHANS;
+ bw = 40;
+ } else if (bw == WL_CHANSPEC_BW_80) {
+ center_ch = wf_5g_80m_chans;
+ num_ch = WF_NUM_5G_80M_CHANS;
+ bw = 80;
+ } else if (bw == WL_CHANSPEC_BW_160) {
+ center_ch = wf_5g_160m_chans;
+ num_ch = WF_NUM_5G_160M_CHANS;
+ bw = 160;
+ } else if (bw == WL_CHANSPEC_BW_20) {
+ chspec |= ctl_ch;
+ return chspec;
+ } else {
+ return 0;
+ }
+
+ for (i = 0; i < num_ch; i ++) {
+ sb = channel_to_sb(center_ch[i], ctl_ch, bw);
+ if (sb >= 0) {
+ chspec |= center_ch[i];
+ chspec |= (sb << WL_CHANSPEC_CTL_SB_SHIFT);
+ break;
+ }
+ }
+
+ /* check for no matching sb/center */
+ if (sb < 0) {
+ return 0;
+ }
+
+ return chspec;
+}
+#endif /* D11AC_IOTYPES */
+
+/*
+ * This function returns the chanspec for the primary 40MHz of an 80MHz channel.
+ * The control sideband specifies the same 20MHz channel that the 80MHz channel is using
+ * as the primary 20MHz channel.
+ */
+extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec)
+{
+ chanspec_t chspec40 = chspec;
+ uint center_chan;
+ uint sb;
+
+ ASSERT(!wf_chspec_malformed(chspec));
+
+ if (CHSPEC_IS80(chspec)) {
+ center_chan = CHSPEC_CHANNEL(chspec);
+ sb = CHSPEC_CTL_SB(chspec);
+
+ if (sb == WL_CHANSPEC_CTL_SB_UL) {
+ /* Primary 40MHz is on upper side */
+ sb = WL_CHANSPEC_CTL_SB_L;
+ center_chan += CH_20MHZ_APART;
+ } else if (sb == WL_CHANSPEC_CTL_SB_UU) {
+ /* Primary 40MHz is on upper side */
+ sb = WL_CHANSPEC_CTL_SB_U;
+ center_chan += CH_20MHZ_APART;
+ } else {
+ /* Primary 40MHz is on lower side */
+ /* sideband bits are the same for LL/LU and L/U */
+ center_chan -= CH_20MHZ_APART;
+ }
+
+ /* Create primary 40MHz chanspec */
+ chspec40 = (WL_CHANSPEC_BAND_5G | WL_CHANSPEC_BW_40 |
+ sb | center_chan);
+ }
+
+ return chspec40;
+}
+
+/*
+ * Return the channel number for a given frequency and base frequency.
+ * The returned channel number is relative to the given base frequency.
+ * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
+ * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
+ *
+ * Frequency is specified in MHz.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+ * 2.4 GHz and 5 GHz bands.
+ *
+ * The returned channel will be in the range [1, 14] in the 2.4 GHz band
+ * and [0, 200] otherwise.
+ * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+ * frequency is not a 2.4 GHz channel, or if the frequency is not and even
+ * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
+ *
+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+ */
+int
+wf_mhz2channel(uint freq, uint start_factor)
+{
+ int ch = -1;
+ uint base;
+ int offset;
+
+ /* take the default channel start frequency */
+ if (start_factor == 0) {
+ if (freq >= 2400 && freq <= 2500)
+ start_factor = WF_CHAN_FACTOR_2_4_G;
+ else if (freq >= 5000 && freq <= 6000)
+ start_factor = WF_CHAN_FACTOR_5_G;
+ }
+
+ if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
+ return 14;
+
+ base = start_factor / 2;
+
+ /* check that the frequency is in 1GHz range of the base */
+ if ((freq < base) || (freq > base + 1000))
+ return -1;
+
+ offset = freq - base;
+ ch = offset / 5;
+
+ /* check that frequency is a 5MHz multiple from the base */
+ if (offset != (ch * 5))
+ return -1;
+
+ /* restricted channel range check for 2.4G */
+ if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
+ return -1;
+
+ return ch;
+}
+
+/*
+ * Return the center frequency in MHz of the given channel and base frequency.
+ * The channel number is interpreted relative to the given base frequency.
+ *
+ * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_4_G, and WF_CHAN_FACTOR_5_G
+ * are defined for 2.4 GHz, 4 GHz, and 5 GHz bands.
+ * The channel range of [1, 14] is only checked for a start_factor of
+ * WF_CHAN_FACTOR_2_4_G (4814 = 2407 * 2).
+ * Odd start_factors produce channels on .5 MHz boundaries, in which case
+ * the answer is rounded down to an integral MHz.
+ * -1 is returned for an out of range channel.
+ *
+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+ */
+int
+wf_channel2mhz(uint ch, uint start_factor)
+{
+ int freq;
+
+ if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) ||
+ (ch > 200))
+ freq = -1;
+ else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14))
+ freq = 2484;
+ else
+ freq = ch * 5 + start_factor / 2;
+
+ return freq;
+}
diff --git a/drivers/net/wireless/ap6210/dhd.h b/drivers/net/wireless/ap6210/dhd.h
new file mode 100644
index 0000000..006a41c
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd.h
@@ -0,0 +1,888 @@
+/*
+ * Header file describing the internal (inter-module) DHD interfaces.
+ *
+ * Provides type definitions and function prototypes used to link the
+ * DHD OS, bus, and protocol modules.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd.h 373887 2012-12-10 21:58:02Z $
+ */
+
+/****************
+ * Common types *
+ */
+
+#ifndef _dhd_h_
+#define _dhd_h_
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
+#include <linux/wakelock.h>
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
+/* The kernel threading is sdio-specific */
+struct task_struct;
+struct sched_param;
+int setScheduler(struct task_struct *p, int policy, struct sched_param *param);
+
+#define ALL_INTERFACES 0xff
+
+#include <wlioctl.h>
+#include <wlfc_proto.h>
+
+
+/* Forward decls */
+struct dhd_bus;
+struct dhd_prot;
+struct dhd_info;
+
+/* The level of bus communication with the dongle */
+enum dhd_bus_state {
+ DHD_BUS_DOWN, /* Not ready for frame transfers */
+ DHD_BUS_LOAD, /* Download access only (CPU reset) */
+ DHD_BUS_DATA /* Ready for frame transfers */
+};
+
+enum dhd_op_flags {
+/* Firmware requested operation mode */
+ DHD_FLAG_STA_MODE = BIT(0), /* STA only */
+ DHD_FLAG_HOSTAP_MODE = BIT(1), /* SOFTAP only */
+ DHD_FLAG_P2P_MODE = BIT(2), /* P2P Only */
+ /* STA + P2P */
+ DHD_FLAG_CONCURR_SINGLE_CHAN_MODE = (DHD_FLAG_STA_MODE | DHD_FLAG_P2P_MODE),
+ DHD_FLAG_CONCURR_MULTI_CHAN_MODE = BIT(4), /* STA + P2P */
+ /* Current P2P mode for P2P connection */
+ DHD_FLAG_P2P_GC_MODE = BIT(5),
+ DHD_FLAG_P2P_GO_MODE = BIT(6),
+ DHD_FLAG_MBSS_MODE = BIT(7) /* MBSS in future */
+};
+
+#define MANUFACTRING_FW "WLTEST"
+
+/* max sequential rxcntl timeouts to set HANG event */
+#ifndef MAX_CNTL_TIMEOUT
+#define MAX_CNTL_TIMEOUT 2
+#endif
+
+#define DHD_SCAN_ASSOC_ACTIVE_TIME 40 /* ms: Embedded default Active setting from DHD */
+#define DHD_SCAN_UNASSOC_ACTIVE_TIME 80 /* ms: Embedded def. Unassoc Active setting from DHD */
+#define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD */
+
+#ifndef POWERUP_MAX_RETRY
+#define POWERUP_MAX_RETRY 3 /* how many times we retry to power up the chip */
+#endif
+#ifndef POWERUP_WAIT_MS
+#define POWERUP_WAIT_MS 2000 /* ms: time out in waiting wifi to come up */
+#endif
+
+enum dhd_bus_wake_state {
+ WAKE_LOCK_OFF,
+ WAKE_LOCK_PRIV,
+ WAKE_LOCK_DPC,
+ WAKE_LOCK_IOCTL,
+ WAKE_LOCK_DOWNLOAD,
+ WAKE_LOCK_TMOUT,
+ WAKE_LOCK_WATCHDOG,
+ WAKE_LOCK_LINK_DOWN_TMOUT,
+ WAKE_LOCK_PNO_FIND_TMOUT,
+ WAKE_LOCK_SOFTAP_SET,
+ WAKE_LOCK_SOFTAP_STOP,
+ WAKE_LOCK_SOFTAP_START,
+ WAKE_LOCK_SOFTAP_THREAD,
+ WAKE_LOCK_MAX
+};
+
+enum dhd_prealloc_index {
+ DHD_PREALLOC_PROT = 0,
+ DHD_PREALLOC_RXBUF,
+ DHD_PREALLOC_DATABUF,
+#if defined(STATIC_WL_PRIV_STRUCT)
+ DHD_PREALLOC_OSL_BUF,
+ DHD_PREALLOC_WIPHY_ESCAN0 = 5,
+#else
+ DHD_PREALLOC_OSL_BUF
+#endif /* STATIC_WL_PRIV_STRUCT */
+};
+
+typedef enum {
+ DHD_IF_NONE = 0,
+ DHD_IF_ADD,
+ DHD_IF_DEL,
+ DHD_IF_CHANGE,
+ DHD_IF_DELETING
+} dhd_if_state_t;
+
+
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
+
+uint8* dhd_os_prealloc(void *osh, int section, uint size);
+void dhd_os_prefree(void *osh, void *addr, uint size);
+#define DHD_OS_PREALLOC(osh, section, size) dhd_os_prealloc(osh, section, size)
+#define DHD_OS_PREFREE(osh, addr, size) dhd_os_prefree(osh, addr, size)
+
+#else
+
+#define DHD_OS_PREALLOC(osh, section, size) MALLOC(osh, size)
+#define DHD_OS_PREFREE(osh, addr, size) MFREE(osh, addr, size)
+
+#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */
+
+/* Packet alignment for most efficient SDIO (can change based on platform) */
+#ifndef DHD_SDALIGN
+#define DHD_SDALIGN 32
+#endif
+
+/* host reordering packts logic */
+/* followed the structure to hold the reorder buffers (void **p) */
+typedef struct reorder_info {
+ void **p;
+ uint8 flow_id;
+ uint8 cur_idx;
+ uint8 exp_idx;
+ uint8 max_idx;
+ uint8 pend_pkts;
+} reorder_info_t;
+
+/* Common structure for module and instance linkage */
+typedef struct dhd_pub {
+ /* Linkage ponters */
+ osl_t *osh; /* OSL handle */
+ struct dhd_bus *bus; /* Bus module handle */
+ struct dhd_prot *prot; /* Protocol module handle */
+ struct dhd_info *info; /* Info module handle */
+
+ /* Internal dhd items */
+ bool up; /* Driver up/down (to OS) */
+ bool txoff; /* Transmit flow-controlled */
+ bool dongle_reset; /* TRUE = DEVRESET put dongle into reset */
+ enum dhd_bus_state busstate;
+ uint hdrlen; /* Total DHD header length (proto + bus) */
+ uint maxctl; /* Max size rxctl request from proto to bus */
+ uint rxsz; /* Rx buffer size bus module should use */
+ uint8 wme_dp; /* wme discard priority */
+
+ /* Dongle media info */
+ bool iswl; /* Dongle-resident driver is wl */
+ ulong drv_version; /* Version of dongle-resident driver */
+ struct ether_addr mac; /* MAC address obtained from dongle */
+ dngl_stats_t dstats; /* Stats for dongle-based data */
+
+ /* Additional stats for the bus level */
+ ulong tx_packets; /* Data packets sent to dongle */
+ ulong tx_multicast; /* Multicast data packets sent to dongle */
+ ulong tx_errors; /* Errors in sending data to dongle */
+ ulong tx_ctlpkts; /* Control packets sent to dongle */
+ ulong tx_ctlerrs; /* Errors sending control frames to dongle */
+ ulong rx_packets; /* Packets sent up the network interface */
+ ulong rx_multicast; /* Multicast packets sent up the network interface */
+ ulong rx_errors; /* Errors processing rx data packets */
+ ulong rx_ctlpkts; /* Control frames processed from dongle */
+ ulong rx_ctlerrs; /* Errors in processing rx control frames */
+ ulong rx_dropped; /* Packets dropped locally (no memory) */
+ ulong rx_flushed; /* Packets flushed due to unscheduled sendup thread */
+ ulong wd_dpc_sched; /* Number of times dhd dpc scheduled by watchdog timer */
+
+ ulong rx_readahead_cnt; /* Number of packets where header read-ahead was used. */
+ ulong tx_realloc; /* Number of tx packets we had to realloc for headroom */
+ ulong fc_packets; /* Number of flow control pkts recvd */
+
+ /* Last error return */
+ int bcmerror;
+ uint tickcnt;
+
+ /* Last error from dongle */
+ int dongle_error;
+
+ uint8 country_code[WLC_CNTRY_BUF_SZ];
+
+ /* Suspend disable flag and "in suspend" flag */
+ int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */
+ int in_suspend; /* flag set to 1 when early suspend called */
+#ifdef PNO_SUPPORT
+ int pno_enable; /* pno status : "1" is pno enable */
+ int pno_suspend; /* pno suspend status : "1" is pno suspended */
+#endif /* PNO_SUPPORT */
+ /* DTIM skip value, default 0(or 1) means wake each DTIM
+ * 3 means skip 2 DTIMs and wake up 3rd DTIM(9th beacon when AP DTIM is 3)
+ */
+ int suspend_bcn_li_dtim; /* bcn_li_dtim value in suspend mode */
+#ifdef PKT_FILTER_SUPPORT
+ int early_suspended; /* Early suspend status */
+ int dhcp_in_progress; /* DHCP period */
+#endif
+
+ /* Pkt filter defination */
+ char * pktfilter[100];
+ int pktfilter_count;
+
+ wl_country_t dhd_cspec; /* Current Locale info */
+ char eventmask[WL_EVENTING_MASK_LEN];
+ int op_mode; /* STA, HostAPD, WFD, SoftAP */
+
+/* Set this to 1 to use a seperate interface (p2p0) for p2p operations.
+ * For ICS MR1 releases it should be disable to be compatable with ICS MR1 Framework
+ * see target dhd-cdc-sdmmc-panda-cfg80211-icsmr1-gpl-debug in Makefile
+ */
+/* #define WL_ENABLE_P2P_IF 1 */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ struct mutex wl_start_stop_lock; /* lock/unlock for Android start/stop */
+ struct mutex wl_softap_lock; /* lock/unlock for any SoftAP/STA settings */
+#endif
+
+#ifdef WLBTAMP
+ uint16 maxdatablks;
+#endif /* WLBTAMP */
+#ifdef PROP_TXSTATUS
+ int wlfc_enabled;
+ void* wlfc_state;
+#endif
+ bool dongle_isolation;
+ bool dongle_trap_occured; /* flag for sending HANG event to upper layer */
+ int hang_was_sent;
+ int rxcnt_timeout; /* counter rxcnt timeout to send HANG */
+ int txcnt_timeout; /* counter txcnt timeout to send HANG */
+#ifdef WLMEDIA_HTSF
+ uint8 htsfdlystat_sz; /* Size of delay stats, max 255B */
+#endif
+ struct reorder_info *reorder_bufs[WLHOST_REORDERDATA_MAXFLOWS];
+#if defined(ARP_OFFLOAD_SUPPORT)
+ uint32 arp_version;
+#endif
+} dhd_pub_t;
+
+
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
+
+ #define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
+ #define _DHD_PM_RESUME_WAIT(a, b) do {\
+ int retry = 0; \
+ SMP_RD_BARRIER_DEPENDS(); \
+ while (dhd_mmc_suspend && retry++ != b) { \
+ SMP_RD_BARRIER_DEPENDS(); \
+ wait_event_interruptible_timeout(a, !dhd_mmc_suspend, 1); \
+ } \
+ } while (0)
+ #define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 200)
+ #define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0)
+ #define DHD_PM_RESUME_RETURN_ERROR(a) do { if (dhd_mmc_suspend) return a; } while (0)
+ #define DHD_PM_RESUME_RETURN do { if (dhd_mmc_suspend) return; } while (0)
+
+ #define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
+ #define SPINWAIT_SLEEP(a, exp, us) do { \
+ uint countdown = (us) + 9999; \
+ while ((exp) && (countdown >= 10000)) { \
+ wait_event_interruptible_timeout(a, FALSE, 1); \
+ countdown -= 10000; \
+ } \
+ } while (0)
+
+ #else
+
+ #define DHD_PM_RESUME_WAIT_INIT(a)
+ #define DHD_PM_RESUME_WAIT(a)
+ #define DHD_PM_RESUME_WAIT_FOREVER(a)
+ #define DHD_PM_RESUME_RETURN_ERROR(a)
+ #define DHD_PM_RESUME_RETURN
+
+ #define DHD_SPINWAIT_SLEEP_INIT(a)
+ #define SPINWAIT_SLEEP(a, exp, us) do { \
+ uint countdown = (us) + 9; \
+ while ((exp) && (countdown >= 10)) { \
+ OSL_DELAY(10); \
+ countdown -= 10; \
+ } \
+ } while (0)
+
+ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
+#ifndef DHDTHREAD
+#undef SPINWAIT_SLEEP
+#define SPINWAIT_SLEEP(a, exp, us) SPINWAIT(exp, us)
+#endif /* DHDTHREAD */
+#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */
+
+unsigned long dhd_os_spin_lock(dhd_pub_t *pub);
+void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags);
+
+/* Wakelock Functions */
+extern int dhd_os_wake_lock(dhd_pub_t *pub);
+extern int dhd_os_wake_unlock(dhd_pub_t *pub);
+extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub);
+extern int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val);
+extern int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val);
+extern int dhd_os_wd_wake_lock(dhd_pub_t *pub);
+extern int dhd_os_wd_wake_unlock(dhd_pub_t *pub);
+
+inline static void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t * dhdp)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ mutex_init(&dhdp->wl_softap_lock);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+}
+
+inline static void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t * dhdp)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ mutex_lock(&dhdp->wl_softap_lock);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+}
+
+inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ mutex_unlock(&dhdp->wl_softap_lock);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+}
+
+#define DHD_OS_WAKE_LOCK(pub) dhd_os_wake_lock(pub)
+#define DHD_OS_WAKE_UNLOCK(pub) dhd_os_wake_unlock(pub)
+#define DHD_OS_WD_WAKE_LOCK(pub) dhd_os_wd_wake_lock(pub)
+#define DHD_OS_WD_WAKE_UNLOCK(pub) dhd_os_wd_wake_unlock(pub)
+#define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub)
+#define DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(pub, val) \
+ dhd_os_wake_lock_rx_timeout_enable(pub, val)
+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val) \
+ dhd_os_wake_lock_ctrl_timeout_enable(pub, val)
+#define DHD_PACKET_TIMEOUT_MS 1000
+#define DHD_EVENT_TIMEOUT_MS 1500
+
+/* interface operations (register, remove) should be atomic, use this lock to prevent race
+ * condition among wifi on/off and interface operation functions
+ */
+void dhd_net_if_lock(struct net_device *dev);
+void dhd_net_if_unlock(struct net_device *dev);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+extern struct mutex _dhd_sdio_mutex_lock_;
+#endif
+
+typedef struct dhd_if_event {
+ uint8 ifidx;
+ uint8 action;
+ uint8 flags;
+ uint8 bssidx;
+ uint8 is_AP;
+} dhd_if_event_t;
+
+typedef enum dhd_attach_states
+{
+ DHD_ATTACH_STATE_INIT = 0x0,
+ DHD_ATTACH_STATE_NET_ALLOC = 0x1,
+ DHD_ATTACH_STATE_DHD_ALLOC = 0x2,
+ DHD_ATTACH_STATE_ADD_IF = 0x4,
+ DHD_ATTACH_STATE_PROT_ATTACH = 0x8,
+ DHD_ATTACH_STATE_WL_ATTACH = 0x10,
+ DHD_ATTACH_STATE_THREADS_CREATED = 0x20,
+ DHD_ATTACH_STATE_WAKELOCKS_INIT = 0x40,
+ DHD_ATTACH_STATE_CFG80211 = 0x80,
+ DHD_ATTACH_STATE_EARLYSUSPEND_DONE = 0x100,
+ DHD_ATTACH_STATE_DONE = 0x200
+} dhd_attach_states_t;
+
+/* Value -1 means we are unsuccessful in creating the kthread. */
+#define DHD_PID_KT_INVALID -1
+/* Value -2 means we are unsuccessful in both creating the kthread and tasklet */
+#define DHD_PID_KT_TL_INVALID -2
+
+/*
+ * Exported from dhd OS modules (dhd_linux/dhd_ndis)
+ */
+
+/* To allow osl_attach/detach calls from os-independent modules */
+osl_t *dhd_osl_attach(void *pdev, uint bustype);
+void dhd_osl_detach(osl_t *osh);
+
+/* Indication from bus module regarding presence/insertion of dongle.
+ * Return dhd_pub_t pointer, used as handle to OS module in later calls.
+ * Returned structure should have bus and prot pointers filled in.
+ * bus_hdrlen specifies required headroom for bus module header.
+ */
+extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen);
+#if defined(WLP2P) && defined(WL_CFG80211)
+/* To allow attach/detach calls corresponding to p2p0 interface */
+extern int dhd_attach_p2p(dhd_pub_t *);
+extern int dhd_detach_p2p(dhd_pub_t *);
+#endif /* WLP2P && WL_CFG80211 */
+extern int dhd_net_attach(dhd_pub_t *dhdp, int idx);
+
+/* Indication from bus module regarding removal/absence of dongle */
+extern void dhd_detach(dhd_pub_t *dhdp);
+extern void dhd_free(dhd_pub_t *dhdp);
+
+/* Indication from bus module to change flow-control state */
+extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on);
+
+extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec);
+
+/* Receive frame for delivery to OS. Callee disposes of rxp. */
+extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt, uint8 chan);
+
+/* Return pointer to interface name */
+extern char *dhd_ifname(dhd_pub_t *dhdp, int idx);
+
+/* Request scheduling of the bus dpc */
+extern void dhd_sched_dpc(dhd_pub_t *dhdp);
+
+/* Notify tx completion */
+extern void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success);
+
+/* OS independent layer functions */
+extern int dhd_os_proto_block(dhd_pub_t * pub);
+extern int dhd_os_proto_unblock(dhd_pub_t * pub);
+extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition, bool * pending);
+extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub);
+extern unsigned int dhd_os_get_ioctl_resp_timeout(void);
+extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec);
+extern void * dhd_os_open_image(char * filename);
+extern int dhd_os_get_image_block(char * buf, int len, void * image);
+extern void dhd_os_close_image(void * image);
+extern void dhd_os_wd_timer(void *bus, uint wdtick);
+extern void dhd_os_sdlock(dhd_pub_t * pub);
+extern void dhd_os_sdunlock(dhd_pub_t * pub);
+extern void dhd_os_sdlock_txq(dhd_pub_t * pub);
+extern void dhd_os_sdunlock_txq(dhd_pub_t * pub);
+extern void dhd_os_sdlock_rxq(dhd_pub_t * pub);
+extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub);
+extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub);
+extern void dhd_customer_gpio_wlan_ctrl(int onoff);
+extern int dhd_custom_get_mac_address(unsigned char *buf);
+extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub);
+extern void dhd_os_sdlock_eventq(dhd_pub_t * pub);
+extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub);
+extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret);
+extern int dhd_os_send_hang_message(dhd_pub_t *dhdp);
+extern void dhd_set_version_info(dhd_pub_t *pub, char *fw);
+
+#ifdef PNO_SUPPORT
+extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
+extern int dhd_pno_clean(dhd_pub_t *dhd);
+extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid,
+ ushort scan_fr, int pno_repeat, int pno_freq_expo_max);
+extern int dhd_pno_get_status(dhd_pub_t *dhd);
+extern int dhd_dev_pno_reset(struct net_device *dev);
+extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local,
+ int nssid, ushort scan_fr, int pno_repeat, int pno_freq_expo_max);
+extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
+extern int dhd_dev_get_pno_status(struct net_device *dev);
+#endif /* PNO_SUPPORT */
+
+#ifdef PKT_FILTER_SUPPORT
+#define DHD_UNICAST_FILTER_NUM 0
+#define DHD_BROADCAST_FILTER_NUM 1
+#define DHD_MULTICAST4_FILTER_NUM 2
+#define DHD_MULTICAST6_FILTER_NUM 3
+#define DHD_MDNS_FILTER_NUM 4
+extern int dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val);
+extern void dhd_enable_packet_filter(int value, dhd_pub_t *dhd);
+extern int net_os_enable_packet_filter(struct net_device *dev, int val);
+extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num);
+#endif /* PKT_FILTER_SUPPORT */
+
+extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd);
+extern bool dhd_support_sta_mode(dhd_pub_t *dhd);
+
+#ifdef DHD_DEBUG
+extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size);
+#endif /* DHD_DEBUG */
+#if defined(OOB_INTR_ONLY)
+extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr);
+#endif
+extern void dhd_os_sdtxlock(dhd_pub_t * pub);
+extern void dhd_os_sdtxunlock(dhd_pub_t * pub);
+
+typedef struct {
+ uint32 limit; /* Expiration time (usec) */
+ uint32 increment; /* Current expiration increment (usec) */
+ uint32 elapsed; /* Current elapsed time (usec) */
+ uint32 tick; /* O/S tick time (usec) */
+} dhd_timeout_t;
+
+extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec);
+extern int dhd_timeout_expired(dhd_timeout_t *tmo);
+
+extern int dhd_ifname2idx(struct dhd_info *dhd, char *name);
+extern int dhd_net2idx(struct dhd_info *dhd, struct net_device *net);
+extern struct net_device * dhd_idx2net(void *pub, int ifidx);
+extern int net_os_send_hang_message(struct net_device *dev);
+extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata,
+ wl_event_msg_t *, void **data_ptr);
+extern void wl_event_to_host_order(wl_event_msg_t * evt);
+
+extern int dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len);
+extern int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set,
+ int ifindex);
+
+extern void dhd_common_init(osl_t *osh);
+
+extern int dhd_do_driver_init(struct net_device *net);
+extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle,
+ char *name, uint8 *mac_addr, uint32 flags, uint8 bssidx);
+extern void dhd_del_if(struct dhd_info *dhd, int ifidx);
+
+extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char * name);
+extern void dhd_vif_del(struct dhd_info *dhd, int ifidx);
+
+extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx);
+extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, uchar *cp, int len);
+
+
+/* Send packet to dongle via data channel */
+extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pkt);
+
+/* send up locally generated event */
+extern void dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data);
+/* Send event to host */
+extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data);
+extern int dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag);
+extern uint dhd_bus_status(dhd_pub_t *dhdp);
+extern int dhd_bus_start(dhd_pub_t *dhdp);
+extern int dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size);
+extern void dhd_print_buf(void *pbuf, int len, int bytes_per_line);
+extern bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval);
+extern uint dhd_bus_chip_id(dhd_pub_t *dhdp);
+extern uint dhd_bus_chiprev_id(dhd_pub_t *dhdp);
+extern uint dhd_bus_chippkg_id(dhd_pub_t *dhdp);
+
+#if defined(KEEP_ALIVE)
+extern int dhd_keep_alive_onoff(dhd_pub_t *dhd);
+#endif /* KEEP_ALIVE */
+
+extern bool dhd_is_concurrent_mode(dhd_pub_t *dhd);
+
+typedef enum cust_gpio_modes {
+ WLAN_RESET_ON,
+ WLAN_RESET_OFF,
+ WLAN_POWER_ON,
+ WLAN_POWER_OFF
+} cust_gpio_modes_t;
+
+extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag);
+extern int wl_iw_send_priv_event(struct net_device *dev, char *flag);
+/*
+ * Insmod parameters for debug/test
+ */
+
+/* Watchdog timer interval */
+extern uint dhd_watchdog_ms;
+
+#if defined(DHD_DEBUG)
+/* Console output poll interval */
+extern uint dhd_console_ms;
+#endif /* defined(DHD_DEBUG) */
+//extern uint android_msg_level;
+#ifdef CONFIG_WIRELESS_EXT
+extern uint iw_msg_level;
+#endif
+#ifdef WL_CFG80211
+extern uint wl_dbg_level;
+#endif
+extern uint dhd_slpauto;
+
+/* Use interrupts */
+extern uint dhd_intr;
+
+/* Use polling */
+extern uint dhd_poll;
+
+/* ARP offload agent mode */
+extern uint dhd_arp_mode;
+
+/* ARP offload enable */
+extern uint dhd_arp_enable;
+
+/* Pkt filte enable control */
+extern uint dhd_pkt_filter_enable;
+
+/* Pkt filter init setup */
+extern uint dhd_pkt_filter_init;
+
+/* Pkt filter mode control */
+extern uint dhd_master_mode;
+
+/* Roaming mode control */
+extern uint dhd_roam_disable;
+
+/* Roaming mode control */
+extern uint dhd_radio_up;
+
+/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */
+extern int dhd_idletime;
+#ifdef DHD_USE_IDLECOUNT
+#define DHD_IDLETIME_TICKS 5
+#else
+#define DHD_IDLETIME_TICKS 1
+#endif /* DHD_USE_IDLECOUNT */
+
+/* SDIO Drive Strength */
+extern uint dhd_sdiod_drive_strength;
+
+/* Override to force tx queueing all the time */
+extern uint dhd_force_tx_queueing;
+/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */
+#define DEFAULT_KEEP_ALIVE_VALUE 55000 /* msec */
+#ifndef CUSTOM_KEEP_ALIVE_SETTING
+#define CUSTOM_KEEP_ALIVE_SETTING DEFAULT_KEEP_ALIVE_VALUE
+#endif /* DEFAULT_KEEP_ALIVE_VALUE */
+
+#define NULL_PKT_STR "null_pkt"
+
+/* hooks for custom glom setting option via Makefile */
+#define DEFAULT_GLOM_VALUE -1
+#ifndef CUSTOM_GLOM_SETTING
+#define CUSTOM_GLOM_SETTING DEFAULT_GLOM_VALUE
+#endif
+
+/* hooks for custom Roaming Trigger setting via Makefile */
+#define DEFAULT_ROAM_TRIGGER_VALUE -75 /* dBm default roam trigger all band */
+#define DEFAULT_ROAM_TRIGGER_SETTING -1
+#ifndef CUSTOM_ROAM_TRIGGER_SETTING
+#define CUSTOM_ROAM_TRIGGER_SETTING DEFAULT_ROAM_TRIGGER_VALUE
+#endif
+
+/* hooks for custom Roaming Romaing setting via Makefile */
+#define DEFAULT_ROAM_DELTA_VALUE 10 /* dBm default roam delta all band */
+#define DEFAULT_ROAM_DELTA_SETTING -1
+#ifndef CUSTOM_ROAM_DELTA_SETTING
+#define CUSTOM_ROAM_DELTA_SETTING DEFAULT_ROAM_DELTA_VALUE
+#endif
+
+/* hooks for custom PNO Event wake lock to guarantee enough time
+ for the Platform to detect Event before system suspended
+*/
+#define DEFAULT_PNO_EVENT_LOCK_xTIME 2 /* multiplay of DHD_PACKET_TIMEOUT_MS */
+#ifndef CUSTOM_PNO_EVENT_LOCK_xTIME
+#define CUSTOM_PNO_EVENT_LOCK_xTIME DEFAULT_PNO_EVENT_LOCK_xTIME
+#endif
+
+/* hooks for custom dhd_dpc_prio setting option via Makefile */
+#define DEFAULT_DHP_DPC_PRIO 1
+#ifndef CUSTOM_DPC_PRIO_SETTING
+#define CUSTOM_DPC_PRIO_SETTING DEFAULT_DHP_DPC_PRIO
+#endif
+
+#define DEFAULT_SUSPEND_BCN_LI_DTIM 3
+#ifndef CUSTOM_SUSPEND_BCN_LI_DTIM
+#define CUSTOM_SUSPEND_BCN_LI_DTIM DEFAULT_SUSPEND_BCN_LI_DTIM
+#endif
+
+#ifdef SDTEST
+/* Echo packet generator (SDIO), pkts/s */
+extern uint dhd_pktgen;
+
+/* Echo packet len (0 => sawtooth, max 1800) */
+extern uint dhd_pktgen_len;
+#define MAX_PKTGEN_LEN 1800
+#endif
+
+
+/* optionally set by a module_param_string() */
+#define MOD_PARAM_PATHLEN 2048
+extern char fw_path[MOD_PARAM_PATHLEN];
+extern char nv_path[MOD_PARAM_PATHLEN];
+
+#define MOD_PARAM_INFOLEN 512
+
+#ifdef SOFTAP
+extern char fw_path2[MOD_PARAM_PATHLEN];
+#endif
+
+#define FW_PATH_AUTO_SELECT 1
+extern char firmware_path[MOD_PARAM_PATHLEN];
+extern void dhd_bus_select_firmware_name_by_chip(struct dhd_bus *bus, char *dst, char *src);
+#define COPY_FW_PATH_BY_CHIP(bus, dst, src) dhd_bus_select_firmware_name_by_chip(bus, dst, src);
+
+/* Flag to indicate if we should download firmware on driver load */
+extern uint dhd_download_fw_on_driverload;
+
+
+/* For supporting multiple interfaces */
+#define DHD_MAX_IFS 16
+#define DHD_DEL_IF -0xe
+#define DHD_BAD_IF -0xf
+#define WL_AUTO_ROAM_TRIGGER -75
+
+#ifdef PROP_TXSTATUS
+/* Please be mindful that total pkttag space is 32 octets only */
+typedef struct dhd_pkttag {
+ /*
+ b[11 ] - 1 = this packet was sent in response to one time packet request,
+ do not increment credit on status for this one. [WLFC_CTL_TYPE_MAC_REQUEST_PACKET].
+ b[10 ] - 1 = signal-only-packet to firmware [i.e. nothing to piggyback on]
+ b[9 ] - 1 = packet is host->firmware (transmit direction)
+ - 0 = packet received from firmware (firmware->host)
+ b[8 ] - 1 = packet was sent due to credit_request (pspoll),
+ packet does not count against FIFO credit.
+ - 0 = normal transaction, packet counts against FIFO credit
+ b[7 ] - 1 = AP, 0 = STA
+ b[6:4] - AC FIFO number
+ b[3:0] - interface index
+ */
+ uint16 if_flags;
+ /* destination MAC address for this packet so that not every
+ module needs to open the packet to find this
+ */
+ uint8 dstn_ether[ETHER_ADDR_LEN];
+ /*
+ This 32-bit goes from host to device for every packet.
+ */
+ uint32 htod_tag;
+ /* bus specific stuff */
+ union {
+ struct {
+ void* stuff;
+ uint32 thing1;
+ uint32 thing2;
+ } sd;
+ struct {
+ void* bus;
+ void* urb;
+ } usb;
+ } bus_specific;
+} dhd_pkttag_t;
+
+#define DHD_PKTTAG_SET_H2DTAG(tag, h2dvalue) ((dhd_pkttag_t*)(tag))->htod_tag = (h2dvalue)
+#define DHD_PKTTAG_H2DTAG(tag) (((dhd_pkttag_t*)(tag))->htod_tag)
+
+#define DHD_PKTTAG_IFMASK 0xf
+#define DHD_PKTTAG_IFTYPE_MASK 0x1
+#define DHD_PKTTAG_IFTYPE_SHIFT 7
+#define DHD_PKTTAG_FIFO_MASK 0x7
+#define DHD_PKTTAG_FIFO_SHIFT 4
+
+#define DHD_PKTTAG_SIGNALONLY_MASK 0x1
+#define DHD_PKTTAG_SIGNALONLY_SHIFT 10
+
+#define DHD_PKTTAG_ONETIMEPKTRQST_MASK 0x1
+#define DHD_PKTTAG_ONETIMEPKTRQST_SHIFT 11
+
+#define DHD_PKTTAG_PKTDIR_MASK 0x1
+#define DHD_PKTTAG_PKTDIR_SHIFT 9
+
+#define DHD_PKTTAG_CREDITCHECK_MASK 0x1
+#define DHD_PKTTAG_CREDITCHECK_SHIFT 8
+
+#define DHD_PKTTAG_INVALID_FIFOID 0x7
+
+#define DHD_PKTTAG_SETFIFO(tag, fifo) ((dhd_pkttag_t*)(tag))->if_flags = \
+ (((dhd_pkttag_t*)(tag))->if_flags & ~(DHD_PKTTAG_FIFO_MASK << DHD_PKTTAG_FIFO_SHIFT)) | \
+ (((fifo) & DHD_PKTTAG_FIFO_MASK) << DHD_PKTTAG_FIFO_SHIFT)
+#define DHD_PKTTAG_FIFO(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
+ DHD_PKTTAG_FIFO_SHIFT) & DHD_PKTTAG_FIFO_MASK)
+
+#define DHD_PKTTAG_SETIF(tag, if) ((dhd_pkttag_t*)(tag))->if_flags = \
+ (((dhd_pkttag_t*)(tag))->if_flags & ~DHD_PKTTAG_IFMASK) | ((if) & DHD_PKTTAG_IFMASK)
+#define DHD_PKTTAG_IF(tag) (((dhd_pkttag_t*)(tag))->if_flags & DHD_PKTTAG_IFMASK)
+
+#define DHD_PKTTAG_SETIFTYPE(tag, isAP) ((dhd_pkttag_t*)(tag))->if_flags = \
+ (((dhd_pkttag_t*)(tag))->if_flags & \
+ ~(DHD_PKTTAG_IFTYPE_MASK << DHD_PKTTAG_IFTYPE_SHIFT)) | \
+ (((isAP) & DHD_PKTTAG_IFTYPE_MASK) << DHD_PKTTAG_IFTYPE_SHIFT)
+#define DHD_PKTTAG_IFTYPE(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
+ DHD_PKTTAG_IFTYPE_SHIFT) & DHD_PKTTAG_IFTYPE_MASK)
+
+#define DHD_PKTTAG_SETCREDITCHECK(tag, check) ((dhd_pkttag_t*)(tag))->if_flags = \
+ (((dhd_pkttag_t*)(tag))->if_flags & \
+ ~(DHD_PKTTAG_CREDITCHECK_MASK << DHD_PKTTAG_CREDITCHECK_SHIFT)) | \
+ (((check) & DHD_PKTTAG_CREDITCHECK_MASK) << DHD_PKTTAG_CREDITCHECK_SHIFT)
+#define DHD_PKTTAG_CREDITCHECK(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
+ DHD_PKTTAG_CREDITCHECK_SHIFT) & DHD_PKTTAG_CREDITCHECK_MASK)
+
+#define DHD_PKTTAG_SETPKTDIR(tag, dir) ((dhd_pkttag_t*)(tag))->if_flags = \
+ (((dhd_pkttag_t*)(tag))->if_flags & \
+ ~(DHD_PKTTAG_PKTDIR_MASK << DHD_PKTTAG_PKTDIR_SHIFT)) | \
+ (((dir) & DHD_PKTTAG_PKTDIR_MASK) << DHD_PKTTAG_PKTDIR_SHIFT)
+#define DHD_PKTTAG_PKTDIR(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
+ DHD_PKTTAG_PKTDIR_SHIFT) & DHD_PKTTAG_PKTDIR_MASK)
+
+#define DHD_PKTTAG_SETSIGNALONLY(tag, signalonly) ((dhd_pkttag_t*)(tag))->if_flags = \
+ (((dhd_pkttag_t*)(tag))->if_flags & \
+ ~(DHD_PKTTAG_SIGNALONLY_MASK << DHD_PKTTAG_SIGNALONLY_SHIFT)) | \
+ (((signalonly) & DHD_PKTTAG_SIGNALONLY_MASK) << DHD_PKTTAG_SIGNALONLY_SHIFT)
+#define DHD_PKTTAG_SIGNALONLY(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
+ DHD_PKTTAG_SIGNALONLY_SHIFT) & DHD_PKTTAG_SIGNALONLY_MASK)
+
+#define DHD_PKTTAG_SETONETIMEPKTRQST(tag) ((dhd_pkttag_t*)(tag))->if_flags = \
+ (((dhd_pkttag_t*)(tag))->if_flags & \
+ ~(DHD_PKTTAG_ONETIMEPKTRQST_MASK << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)) | \
+ (1 << DHD_PKTTAG_ONETIMEPKTRQST_SHIFT)
+#define DHD_PKTTAG_ONETIMEPKTRQST(tag) ((((dhd_pkttag_t*)(tag))->if_flags >> \
+ DHD_PKTTAG_ONETIMEPKTRQST_SHIFT) & DHD_PKTTAG_ONETIMEPKTRQST_MASK)
+
+#define DHD_PKTTAG_SETDSTN(tag, dstn_MAC_ea) memcpy(((dhd_pkttag_t*)((tag)))->dstn_ether, \
+ (dstn_MAC_ea), ETHER_ADDR_LEN)
+#define DHD_PKTTAG_DSTN(tag) ((dhd_pkttag_t*)(tag))->dstn_ether
+
+typedef int (*f_commitpkt_t)(void* ctx, void* p, bool wlfc_locked);
+
+#ifdef PROP_TXSTATUS_DEBUG
+#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do { (entry)->closed_ct++; } while (0)
+#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do { (entry)->opened_ct++; } while (0)
+#else
+#define DHD_WLFC_CTRINC_MAC_CLOSE(entry) do {} while (0)
+#define DHD_WLFC_CTRINC_MAC_OPEN(entry) do {} while (0)
+#endif
+
+#endif /* PROP_TXSTATUS */
+
+extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar);
+extern void dhd_wait_event_wakeup(dhd_pub_t*dhd);
+
+#define IFLOCK_INIT(lock) *lock = 0
+#define IFLOCK(lock) while (InterlockedCompareExchange((lock), 1, 0)) \
+ NdisStallExecution(1);
+#define IFUNLOCK(lock) InterlockedExchange((lock), 0)
+#define IFLOCK_FREE(lock)
+
+#ifdef PNO_SUPPORT
+extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
+extern int dhd_pnoenable(dhd_pub_t *dhd, int pfn_enabled);
+extern int dhd_pno_clean(dhd_pub_t *dhd);
+extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid,
+ ushort scan_fr, int pno_repeat, int pno_freq_expo_max);
+extern int dhd_pno_get_status(dhd_pub_t *dhd);
+extern int dhd_pno_set_add(dhd_pub_t *dhd, wl_pfn_t *netinfo, int nssid, ushort scan_fr,
+ ushort slowscan_fr, uint8 pno_repeat, uint8 pno_freq_expo_max, int16 flags);
+extern int dhd_pno_cfg(dhd_pub_t *dhd, wl_pfn_cfg_t *pcfg);
+extern int dhd_pno_suspend(dhd_pub_t *dhd, int pfn_suspend);
+#endif /* PNO_SUPPORT */
+#ifdef ARP_OFFLOAD_SUPPORT
+#define MAX_IPV4_ENTRIES 8
+void dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode);
+void dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable);
+
+/* dhd_commn arp offload wrapers */
+void dhd_aoe_hostip_clr(dhd_pub_t *dhd, int idx);
+void dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx);
+int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx);
+void dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx);
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#endif /* _dhd_h_ */
diff --git a/drivers/net/wireless/ap6210/dhd_bta.c b/drivers/net/wireless/ap6210/dhd_bta.c
new file mode 100644
index 0000000..3752bbd
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_bta.c
@@ -0,0 +1,338 @@
+/*
+ * BT-AMP support routines
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_bta.c 303834 2011-12-20 06:17:39Z $
+ */
+#ifndef WLBTAMP
+#error "WLBTAMP is not defined"
+#endif /* WLBTAMP */
+
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmcdc.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <proto/802.11.h>
+#include <proto/802.11_bta.h>
+#include <proto/bt_amp_hci.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <dhdioctl.h>
+#include <dhd_dbg.h>
+
+#include <dhd_bta.h>
+
+
+#ifdef SEND_HCI_CMD_VIA_IOCTL
+#define BTA_HCI_CMD_MAX_LEN HCI_CMD_PREAMBLE_SIZE + HCI_CMD_DATA_SIZE
+
+/* Send HCI cmd via wl iovar HCI_cmd to the dongle. */
+int
+dhd_bta_docmd(dhd_pub_t *pub, void *cmd_buf, uint cmd_len)
+{
+ amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)cmd_buf;
+ uint8 buf[BTA_HCI_CMD_MAX_LEN + 16];
+ uint len = sizeof(buf);
+ wl_ioctl_t ioc;
+
+ if (cmd_len < HCI_CMD_PREAMBLE_SIZE)
+ return BCME_BADLEN;
+
+ if ((uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE > cmd_len)
+ return BCME_BADLEN;
+
+ len = bcm_mkiovar("HCI_cmd",
+ (char *)cmd, (uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE, (char *)buf, len);
+
+
+ memset(&ioc, 0, sizeof(ioc));
+
+ ioc.cmd = WLC_SET_VAR;
+ ioc.buf = buf;
+ ioc.len = len;
+ ioc.set = TRUE;
+
+ return dhd_wl_ioctl(pub, &ioc, ioc.buf, ioc.len);
+}
+#else /* !SEND_HCI_CMD_VIA_IOCTL */
+
+static void
+dhd_bta_flush_hcidata(dhd_pub_t *pub, uint16 llh)
+{
+ int prec;
+ struct pktq *q;
+ uint count = 0;
+
+ q = dhd_bus_txq(pub->bus);
+ if (q == NULL)
+ return;
+
+ DHD_BTA(("dhd: flushing HCI ACL data for logical link %u...\n", llh));
+
+ dhd_os_sdlock_txq(pub);
+
+ /* Walk through the txq and toss all HCI ACL data packets */
+ PKTQ_PREC_ITER(q, prec) {
+ void *head_pkt = NULL;
+
+ while (pktq_ppeek(q, prec) != head_pkt) {
+ void *pkt = pktq_pdeq(q, prec);
+ int ifidx;
+
+ PKTPULL(pub->osh, pkt, dhd_bus_hdrlen(pub->bus));
+ dhd_prot_hdrpull(pub, &ifidx, pkt, NULL, NULL);
+
+ if (PKTLEN(pub->osh, pkt) >= RFC1042_HDR_LEN) {
+ struct ether_header *eh =
+ (struct ether_header *)PKTDATA(pub->osh, pkt);
+
+ if (ntoh16(eh->ether_type) < ETHER_TYPE_MIN) {
+ struct dot11_llc_snap_header *lsh =
+ (struct dot11_llc_snap_header *)&eh[1];
+
+ if (bcmp(lsh, BT_SIG_SNAP_MPROT,
+ DOT11_LLC_SNAP_HDR_LEN - 2) == 0 &&
+ ntoh16(lsh->type) == BTA_PROT_L2CAP) {
+ amp_hci_ACL_data_t *ACL_data =
+ (amp_hci_ACL_data_t *)&lsh[1];
+ uint16 handle = ltoh16(ACL_data->handle);
+
+ if (HCI_ACL_DATA_HANDLE(handle) == llh) {
+ PKTFREE(pub->osh, pkt, TRUE);
+ count ++;
+ continue;
+ }
+ }
+ }
+ }
+
+ dhd_prot_hdrpush(pub, ifidx, pkt);
+ PKTPUSH(pub->osh, pkt, dhd_bus_hdrlen(pub->bus));
+
+ if (head_pkt == NULL)
+ head_pkt = pkt;
+ pktq_penq(q, prec, pkt);
+ }
+ }
+
+ dhd_os_sdunlock_txq(pub);
+
+ DHD_BTA(("dhd: flushed %u packet(s) for logical link %u...\n", count, llh));
+}
+
+/* Handle HCI cmd locally.
+ * Return 0: continue to send the cmd across SDIO
+ * < 0: stop, fail
+ * > 0: stop, succuess
+ */
+static int
+_dhd_bta_docmd(dhd_pub_t *pub, amp_hci_cmd_t *cmd)
+{
+ int status = 0;
+
+ switch (ltoh16_ua((uint8 *)&cmd->opcode)) {
+ case HCI_Enhanced_Flush: {
+ eflush_cmd_parms_t *cmdparms = (eflush_cmd_parms_t *)cmd->parms;
+ dhd_bta_flush_hcidata(pub, ltoh16_ua(cmdparms->llh));
+ break;
+ }
+ default:
+ break;
+ }
+
+ return status;
+}
+
+/* Send HCI cmd encapsulated in BT-SIG frame via data channel to the dongle. */
+int
+dhd_bta_docmd(dhd_pub_t *pub, void *cmd_buf, uint cmd_len)
+{
+ amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)cmd_buf;
+ struct ether_header *eh;
+ struct dot11_llc_snap_header *lsh;
+ osl_t *osh = pub->osh;
+ uint len;
+ void *p;
+ int status;
+
+ if (cmd_len < HCI_CMD_PREAMBLE_SIZE) {
+ AP6210_ERR("dhd_bta_docmd: short command, cmd_len %u\n", cmd_len);
+ return BCME_BADLEN;
+ }
+
+ if ((len = (uint)cmd->plen + HCI_CMD_PREAMBLE_SIZE) > cmd_len) {
+ AP6210_ERR("dhd_bta_docmd: malformed command, len %u cmd_len %u\n",
+ len, cmd_len);
+ /* return BCME_BADLEN; */
+ }
+
+ p = PKTGET(osh, pub->hdrlen + RFC1042_HDR_LEN + len, TRUE);
+ if (p == NULL) {
+ AP6210_ERR("dhd_bta_docmd: out of memory\n");
+ return BCME_NOMEM;
+ }
+
+
+ /* intercept and handle the HCI cmd locally */
+ if ((status = _dhd_bta_docmd(pub, cmd)) > 0)
+ return 0;
+ else if (status < 0)
+ return status;
+
+ /* copy in HCI cmd */
+ PKTPULL(osh, p, pub->hdrlen + RFC1042_HDR_LEN);
+ bcopy(cmd, PKTDATA(osh, p), len);
+
+ /* copy in partial Ethernet header with BT-SIG LLC/SNAP header */
+ PKTPUSH(osh, p, RFC1042_HDR_LEN);
+ eh = (struct ether_header *)PKTDATA(osh, p);
+ bzero(eh->ether_dhost, ETHER_ADDR_LEN);
+ ETHER_SET_LOCALADDR(eh->ether_dhost);
+ bcopy(&pub->mac, eh->ether_shost, ETHER_ADDR_LEN);
+ eh->ether_type = hton16(len + DOT11_LLC_SNAP_HDR_LEN);
+ lsh = (struct dot11_llc_snap_header *)&eh[1];
+ bcopy(BT_SIG_SNAP_MPROT, lsh, DOT11_LLC_SNAP_HDR_LEN - 2);
+ lsh->type = 0;
+
+ return dhd_sendpkt(pub, 0, p);
+}
+#endif /* !SEND_HCI_CMD_VIA_IOCTL */
+
+/* Send HCI ACL data to dongle via data channel */
+int
+dhd_bta_tx_hcidata(dhd_pub_t *pub, void *data_buf, uint data_len)
+{
+ amp_hci_ACL_data_t *data = (amp_hci_ACL_data_t *)data_buf;
+ struct ether_header *eh;
+ struct dot11_llc_snap_header *lsh;
+ osl_t *osh = pub->osh;
+ uint len;
+ void *p;
+
+ if (data_len < HCI_ACL_DATA_PREAMBLE_SIZE) {
+ AP6210_ERR("dhd_bta_tx_hcidata: short data_buf, data_len %u\n", data_len);
+ return BCME_BADLEN;
+ }
+
+ if ((len = (uint)ltoh16(data->dlen) + HCI_ACL_DATA_PREAMBLE_SIZE) > data_len) {
+ AP6210_ERR("dhd_bta_tx_hcidata: malformed hci data, len %u data_len %u\n",
+ len, data_len);
+ /* return BCME_BADLEN; */
+ }
+
+ p = PKTGET(osh, pub->hdrlen + RFC1042_HDR_LEN + len, TRUE);
+ if (p == NULL) {
+ AP6210_ERR("dhd_bta_tx_hcidata: out of memory\n");
+ return BCME_NOMEM;
+ }
+
+
+ /* copy in HCI ACL data header and HCI ACL data */
+ PKTPULL(osh, p, pub->hdrlen + RFC1042_HDR_LEN);
+ bcopy(data, PKTDATA(osh, p), len);
+
+ /* copy in partial Ethernet header with BT-SIG LLC/SNAP header */
+ PKTPUSH(osh, p, RFC1042_HDR_LEN);
+ eh = (struct ether_header *)PKTDATA(osh, p);
+ bzero(eh->ether_dhost, ETHER_ADDR_LEN);
+ bcopy(&pub->mac, eh->ether_shost, ETHER_ADDR_LEN);
+ eh->ether_type = hton16(len + DOT11_LLC_SNAP_HDR_LEN);
+ lsh = (struct dot11_llc_snap_header *)&eh[1];
+ bcopy(BT_SIG_SNAP_MPROT, lsh, DOT11_LLC_SNAP_HDR_LEN - 2);
+ lsh->type = HTON16(BTA_PROT_L2CAP);
+
+ return dhd_sendpkt(pub, 0, p);
+}
+
+/* txcomplete callback */
+void
+dhd_bta_tx_hcidata_complete(dhd_pub_t *dhdp, void *txp, bool success)
+{
+ uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, txp);
+ amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)(pktdata + RFC1042_HDR_LEN);
+ uint16 handle = ltoh16(ACL_data->handle);
+ uint16 llh = HCI_ACL_DATA_HANDLE(handle);
+
+ wl_event_msg_t event;
+ uint8 data[HCI_EVT_PREAMBLE_SIZE + sizeof(num_completed_data_blocks_evt_parms_t)];
+ amp_hci_event_t *evt;
+ num_completed_data_blocks_evt_parms_t *parms;
+
+ uint16 len = HCI_EVT_PREAMBLE_SIZE + sizeof(num_completed_data_blocks_evt_parms_t);
+
+ /* update the event struct */
+ memset(&event, 0, sizeof(event));
+ event.version = hton16(BCM_EVENT_MSG_VERSION);
+ event.event_type = hton32(WLC_E_BTA_HCI_EVENT);
+ event.status = 0;
+ event.reason = 0;
+ event.auth_type = 0;
+ event.datalen = hton32(len);
+ event.flags = 0;
+
+ /* generate Number of Completed Blocks event */
+ evt = (amp_hci_event_t *)data;
+ evt->ecode = HCI_Number_of_Completed_Data_Blocks;
+ evt->plen = sizeof(num_completed_data_blocks_evt_parms_t);
+
+ parms = (num_completed_data_blocks_evt_parms_t *)evt->parms;
+ htol16_ua_store(dhdp->maxdatablks, (uint8 *)&parms->num_blocks);
+ parms->num_handles = 1;
+ htol16_ua_store(llh, (uint8 *)&parms->completed[0].handle);
+ parms->completed[0].pkts = 1;
+ parms->completed[0].blocks = 1;
+
+ dhd_sendup_event_common(dhdp, &event, data);
+}
+
+/* event callback */
+void
+dhd_bta_doevt(dhd_pub_t *dhdp, void *data_buf, uint data_len)
+{
+ amp_hci_event_t *evt = (amp_hci_event_t *)data_buf;
+
+ switch (evt->ecode) {
+ case HCI_Command_Complete: {
+ cmd_complete_parms_t *parms = (cmd_complete_parms_t *)evt->parms;
+ switch (ltoh16_ua((uint8 *)&parms->opcode)) {
+ case HCI_Read_Data_Block_Size: {
+ read_data_block_size_evt_parms_t *parms2 =
+ (read_data_block_size_evt_parms_t *)parms->parms;
+ dhdp->maxdatablks = ltoh16_ua((uint8 *)&parms2->data_block_num);
+ break;
+ }
+ }
+ break;
+ }
+
+ case HCI_Flush_Occurred: {
+ flush_occurred_evt_parms_t *evt_parms = (flush_occurred_evt_parms_t *)evt->parms;
+ dhd_bta_flush_hcidata(dhdp, ltoh16_ua((uint8 *)&evt_parms->handle));
+ break;
+ }
+ default:
+ break;
+ }
+}
diff --git a/drivers/net/wireless/ap6210/dhd_bta.h b/drivers/net/wireless/ap6210/dhd_bta.h
new file mode 100644
index 0000000..0337f15
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_bta.h
@@ -0,0 +1,39 @@
+/*
+ * BT-AMP support routines
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_bta.h 291086 2011-10-21 01:17:24Z $
+ */
+#ifndef __dhd_bta_h__
+#define __dhd_bta_h__
+
+struct dhd_pub;
+
+extern int dhd_bta_docmd(struct dhd_pub *pub, void *cmd_buf, uint cmd_len);
+
+extern void dhd_bta_doevt(struct dhd_pub *pub, void *data_buf, uint data_len);
+
+extern int dhd_bta_tx_hcidata(struct dhd_pub *pub, void *data_buf, uint data_len);
+extern void dhd_bta_tx_hcidata_complete(struct dhd_pub *dhdp, void *txp, bool success);
+
+
+#endif /* __dhd_bta_h__ */
diff --git a/drivers/net/wireless/ap6210/dhd_bus.h b/drivers/net/wireless/ap6210/dhd_bus.h
new file mode 100644
index 0000000..131907d
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_bus.h
@@ -0,0 +1,111 @@
+/*
+ * Header file describing the internal (inter-module) DHD interfaces.
+ *
+ * Provides type definitions and function prototypes used to link the
+ * DHD OS, bus, and protocol modules.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_bus.h 347614 2012-07-27 10:24:51Z $
+ */
+
+#ifndef _dhd_bus_h_
+#define _dhd_bus_h_
+
+/*
+ * Exported from dhd bus module (dhd_usb, dhd_sdio)
+ */
+
+/* Indicate (dis)interest in finding dongles. */
+extern int dhd_bus_register(void);
+extern void dhd_bus_unregister(void);
+
+/* Download firmware image and nvram image */
+extern bool dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
+ char *fw_path, char *nv_path);
+
+/* Stop bus module: clear pending frames, disable data flow */
+extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex);
+
+/* Initialize bus module: prepare for communication w/dongle */
+extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex);
+
+/* Get the Bus Idle Time */
+extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int *idletime);
+
+/* Set the Bus Idle Time */
+extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time);
+
+/* Send a data frame to the dongle. Callee disposes of txp. */
+extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp, bool wlfc_locked);
+
+/* Send/receive a control message to/from the dongle.
+ * Expects caller to enforce a single outstanding transaction.
+ */
+extern int dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen);
+extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen);
+
+/* Watchdog timer function */
+extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
+extern void dhd_disable_intr(dhd_pub_t *dhd);
+
+#if defined(DHD_DEBUG)
+/* Device console input function */
+extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen);
+#endif /* defined(DHD_DEBUG) */
+
+/* Deferred processing for the bus, return TRUE requests reschedule */
+extern bool dhd_bus_dpc(struct dhd_bus *bus);
+extern void dhd_bus_isr(bool * InterruptRecognized, bool * QueueMiniportHandleInterrupt, void *arg);
+
+
+/* Check for and handle local prot-specific iovar commands */
+extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
+ void *params, int plen, void *arg, int len, bool set);
+
+/* Add bus dump output to a buffer */
+extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+
+/* Clear any bus counters */
+extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
+
+/* return the dongle chipid */
+extern uint dhd_bus_chip(struct dhd_bus *bus);
+
+/* Set user-specified nvram parameters. */
+extern void dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params);
+
+extern void *dhd_bus_pub(struct dhd_bus *bus);
+extern void *dhd_bus_txq(struct dhd_bus *bus);
+extern uint dhd_bus_hdrlen(struct dhd_bus *bus);
+
+
+#define DHD_SET_BUS_STATE_DOWN(_bus) do { \
+ (_bus)->dhd->busstate = DHD_BUS_DOWN; \
+} while (0)
+
+/* Register a dummy SDIO client driver in order to be notified of new SDIO device */
+extern int dhd_bus_reg_sdio_notify(void* semaphore);
+extern void dhd_bus_unreg_sdio_notify(void);
+
+extern void dhd_txglom_enable(dhd_pub_t *dhdp, bool enable);
+
+#endif /* _dhd_bus_h_ */
diff --git a/drivers/net/wireless/ap6210/dhd_cdc.c b/drivers/net/wireless/ap6210/dhd_cdc.c
new file mode 100644
index 0000000..3a7f55b
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_cdc.c
@@ -0,0 +1,3191 @@
+/*
+ * DHD Protocol Module for CDC and BDC.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_cdc.c 368762 2012-11-14 21:59:17Z $
+ *
+ * BDC is like CDC, except it includes a header for data packets to convey
+ * packet priority over the bus, and flags (e.g. to indicate checksum status
+ * for dongle offload.)
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+
+#include <bcmutils.h>
+#include <bcmcdc.h>
+#include <bcmendian.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_proto.h>
+#include <dhd_bus.h>
+#include <dhd_dbg.h>
+
+
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+#include <ap6210.h>
+
+#define RETRIES 2 /* # of retries to retrieve matching ioctl response */
+#define BUS_HEADER_LEN (24+DHD_SDALIGN) /* Must be at least SDPCM_RESERVE
+ * defined in dhd_sdio.c (amount of header tha might be added)
+ * plus any space that might be needed for alignment padding.
+ */
+#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for
+ * round off at the end of buffer
+ */
+
+#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */
+
+#ifdef PROP_TXSTATUS
+typedef struct dhd_wlfc_commit_info {
+ uint8 needs_hdr;
+ uint8 ac_fifo_credit_spent;
+ ewlfc_packet_state_t pkt_type;
+ wlfc_mac_descriptor_t* mac_entry;
+ void* p;
+} dhd_wlfc_commit_info_t;
+#endif /* PROP_TXSTATUS */
+
+
+typedef struct dhd_prot {
+ uint16 reqid;
+ uint8 pending;
+ uint32 lastcmd;
+ uint8 bus_header[BUS_HEADER_LEN];
+ cdc_ioctl_t msg;
+ unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN];
+} dhd_prot_t;
+
+
+static int
+dhdcdc_msg(dhd_pub_t *dhd)
+{
+ int err = 0;
+ dhd_prot_t *prot = dhd->prot;
+ int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t);
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ DHD_OS_WAKE_LOCK(dhd);
+
+ /* NOTE : cdc->msg.len holds the desired length of the buffer to be
+ * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
+ * is actually sent to the dongle
+ */
+ if (len > CDC_MAX_MSG_SIZE)
+ len = CDC_MAX_MSG_SIZE;
+
+ /* Send request */
+ err = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len);
+
+ DHD_OS_WAKE_UNLOCK(dhd);
+ return err;
+}
+
+static int
+dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len)
+{
+ int ret;
+ int cdc_len = len + sizeof(cdc_ioctl_t);
+ dhd_prot_t *prot = dhd->prot;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ do {
+ ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, cdc_len);
+ if (ret < 0)
+ break;
+ } while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id);
+
+ return ret;
+}
+
+static int
+dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
+{
+ dhd_prot_t *prot = dhd->prot;
+ cdc_ioctl_t *msg = &prot->msg;
+ void *info;
+ int ret = 0, retries = 0;
+ uint32 id, flags = 0;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+ AP6210_DEBUG("%s: cmd %d len %d\n", __FUNCTION__, cmd, len);
+
+
+ /* Respond "bcmerror" and "bcmerrorstr" with local cache */
+ if (cmd == WLC_GET_VAR && buf)
+ {
+ if (!strcmp((char *)buf, "bcmerrorstr"))
+ {
+ strncpy((char *)buf, bcmerrorstr(dhd->dongle_error), BCME_STRLEN);
+ goto done;
+ }
+ else if (!strcmp((char *)buf, "bcmerror"))
+ {
+ *(int *)buf = dhd->dongle_error;
+ goto done;
+ }
+ }
+
+ memset(msg, 0, sizeof(cdc_ioctl_t));
+
+ msg->cmd = htol32(cmd);
+ msg->len = htol32(len);
+ msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
+ CDC_SET_IF_IDX(msg, ifidx);
+ /* add additional action bits */
+ action &= WL_IOCTL_ACTION_MASK;
+ msg->flags |= (action << CDCF_IOC_ACTION_SHIFT);
+ msg->flags = htol32(msg->flags);
+
+ if (buf)
+ memcpy(prot->buf, buf, len);
+
+ if ((ret = dhdcdc_msg(dhd)) < 0) {
+ if (!dhd->hang_was_sent)
+ AP6210_ERR("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret);
+ goto done;
+ }
+
+retry:
+ /* wait for interrupt and get first fragment */
+ if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0)
+ goto done;
+
+ flags = ltoh32(msg->flags);
+ id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
+
+ if ((id < prot->reqid) && (++retries < RETRIES))
+ goto retry;
+ if (id != prot->reqid) {
+ AP6210_ERR("%s: %s: unexpected request id %d (expected %d)\n",
+ dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /* Check info buffer */
+ info = (void*)&msg[1];
+
+ /* Copy info buffer */
+ if (buf)
+ {
+ if (ret < (int)len)
+ len = ret;
+ memcpy(buf, info, len);
+ }
+
+ /* Check the ERROR flag */
+ if (flags & CDCF_IOC_ERROR)
+ {
+ ret = ltoh32(msg->status);
+ /* Cache error from dongle */
+ dhd->dongle_error = ret;
+ }
+
+done:
+ return ret;
+}
+
+static int
+dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
+{
+ dhd_prot_t *prot = dhd->prot;
+ cdc_ioctl_t *msg = &prot->msg;
+ int ret = 0;
+ uint32 flags, id;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+ AP6210_DEBUG("%s: cmd %d len %d\n", __FUNCTION__, cmd, len);
+
+ if (dhd->busstate == DHD_BUS_DOWN) {
+ AP6210_ERR("%s : bus is down. we have nothing to do\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ /* don't talk to the dongle if fw is about to be reloaded */
+ if (dhd->hang_was_sent) {
+ AP6210_ERR("%s: HANG was sent up earlier. Not talking to the chip\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+
+ memset(msg, 0, sizeof(cdc_ioctl_t));
+
+ msg->cmd = htol32(cmd);
+ msg->len = htol32(len);
+ msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
+ CDC_SET_IF_IDX(msg, ifidx);
+ /* add additional action bits */
+ action &= WL_IOCTL_ACTION_MASK;
+ msg->flags |= (action << CDCF_IOC_ACTION_SHIFT) | CDCF_IOC_SET;
+ msg->flags = htol32(msg->flags);
+
+ if (buf)
+ memcpy(prot->buf, buf, len);
+
+ if ((ret = dhdcdc_msg(dhd)) < 0) {
+ AP6210_ERR("%s: dhdcdc_msg failed w/status %d\n", __FUNCTION__, ret);
+ goto done;
+ }
+
+ if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0)
+ goto done;
+
+ flags = ltoh32(msg->flags);
+ id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
+
+ if (id != prot->reqid) {
+ AP6210_ERR("%s: %s: unexpected request id %d (expected %d)\n",
+ dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /* Check the ERROR flag */
+ if (flags & CDCF_IOC_ERROR)
+ {
+ ret = ltoh32(msg->status);
+ /* Cache error from dongle */
+ dhd->dongle_error = ret;
+ }
+
+done:
+ return ret;
+}
+
+
+int
+dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
+{
+ dhd_prot_t *prot = dhd->prot;
+ int ret = -1;
+ uint8 action;
+#if defined(NDIS630)
+ bool acquired = FALSE;
+#endif
+
+ if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) {
+ AP6210_ERR("%s : bus is down. we have nothing to do\n", __FUNCTION__);
+ goto done;
+ }
+#if defined(NDIS630)
+ if (dhd_os_proto_block(dhd))
+ {
+ acquired = TRUE;
+ }
+ else
+ {
+ /* attempt to acquire protocol mutex timed out. */
+ ret = -1;
+ return ret;
+ }
+#endif /* NDIS630 */
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ ASSERT(len <= WLC_IOCTL_MAXLEN);
+
+ if (len > WLC_IOCTL_MAXLEN)
+ goto done;
+
+ if (prot->pending == TRUE) {
+ AP6210_ERR("CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
+ ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
+ (unsigned long)prot->lastcmd);
+ if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) {
+ AP6210_DEBUG("iovar cmd=%s\n", (char*)buf);
+ }
+ goto done;
+ }
+
+ prot->pending = TRUE;
+ prot->lastcmd = ioc->cmd;
+ action = ioc->set;
+ if (action & WL_IOCTL_ACTION_SET)
+ ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len, action);
+ else {
+ ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len, action);
+ if (ret > 0)
+ ioc->used = ret - sizeof(cdc_ioctl_t);
+ }
+
+ /* Too many programs assume ioctl() returns 0 on success */
+ if (ret >= 0)
+ ret = 0;
+ else {
+ cdc_ioctl_t *msg = &prot->msg;
+ ioc->needed = ltoh32(msg->len); /* len == needed when set/query fails from dongle */
+ }
+
+ /* Intercept the wme_dp ioctl here */
+ if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) {
+ int slen, val = 0;
+
+ slen = strlen("wme_dp") + 1;
+ if (len >= (int)(slen + sizeof(int)))
+ bcopy(((char *)buf + slen), &val, sizeof(int));
+ dhd->wme_dp = (uint8) ltoh32(val);
+ }
+
+ prot->pending = FALSE;
+
+done:
+#if defined(NDIS630)
+ if (acquired)
+ dhd_os_proto_unblock(dhd);
+#endif
+ return ret;
+}
+
+int
+dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
+ void *params, int plen, void *arg, int len, bool set)
+{
+ return BCME_UNSUPPORTED;
+}
+
+#ifdef PROP_TXSTATUS
+void
+dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+ int i;
+ uint8* ea;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhdp->wlfc_state;
+ wlfc_hanger_t* h;
+ wlfc_mac_descriptor_t* mac_table;
+ wlfc_mac_descriptor_t* interfaces;
+ char* iftypes[] = {"STA", "AP", "WDS", "p2pGO", "p2pCL"};
+
+ if (wlfc == NULL) {
+ bcm_bprintf(strbuf, "wlfc not initialized yet\n");
+ return;
+ }
+ h = (wlfc_hanger_t*)wlfc->hanger;
+ if (h == NULL) {
+ bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n");
+ }
+
+ mac_table = wlfc->destination_entries.nodes;
+ interfaces = wlfc->destination_entries.interfaces;
+ bcm_bprintf(strbuf, "---- wlfc stats ----\n");
+ if (h) {
+ bcm_bprintf(strbuf, "wlfc hanger (pushed,popped,f_push,"
+ "f_pop,f_slot, pending) = (%d,%d,%d,%d,%d,%d)\n",
+ h->pushed,
+ h->popped,
+ h->failed_to_push,
+ h->failed_to_pop,
+ h->failed_slotfind,
+ (h->pushed - h->popped));
+ }
+
+ bcm_bprintf(strbuf, "wlfc fail(tlv,credit_rqst,mac_update,psmode_update), "
+ "(dq_full,sendq_full, rollback_fail) = (%d,%d,%d,%d), (%d,%d,%d)\n",
+ wlfc->stats.tlv_parse_failed,
+ wlfc->stats.credit_request_failed,
+ wlfc->stats.mac_update_failed,
+ wlfc->stats.psmode_update_failed,
+ wlfc->stats.delayq_full_error,
+ wlfc->stats.sendq_full_error,
+ wlfc->stats.rollback_failed);
+
+ bcm_bprintf(strbuf, "SENDQ (len,credit,sent) "
+ "(AC0[%d,%d,%d],AC1[%d,%d,%d],AC2[%d,%d,%d],AC3[%d,%d,%d],BC_MC[%d,%d,%d])\n",
+ wlfc->SENDQ.q[0].len, wlfc->FIFO_credit[0], wlfc->stats.sendq_pkts[0],
+ wlfc->SENDQ.q[1].len, wlfc->FIFO_credit[1], wlfc->stats.sendq_pkts[1],
+ wlfc->SENDQ.q[2].len, wlfc->FIFO_credit[2], wlfc->stats.sendq_pkts[2],
+ wlfc->SENDQ.q[3].len, wlfc->FIFO_credit[3], wlfc->stats.sendq_pkts[3],
+ wlfc->SENDQ.q[4].len, wlfc->FIFO_credit[4], wlfc->stats.sendq_pkts[4]);
+
+#ifdef PROP_TXSTATUS_DEBUG
+ bcm_bprintf(strbuf, "SENDQ dropped: AC[0-3]:(%d,%d,%d,%d), (bcmc,atim):(%d,%d)\n",
+ wlfc->stats.dropped_qfull[0], wlfc->stats.dropped_qfull[1],
+ wlfc->stats.dropped_qfull[2], wlfc->stats.dropped_qfull[3],
+ wlfc->stats.dropped_qfull[4], wlfc->stats.dropped_qfull[5]);
+#endif
+
+ bcm_bprintf(strbuf, "\n");
+ for (i = 0; i < WLFC_MAX_IFNUM; i++) {
+ if (interfaces[i].occupied) {
+ char* iftype_desc;
+
+ if (interfaces[i].iftype > WLC_E_IF_ROLE_P2P_CLIENT)
+ iftype_desc = "<Unknown";
+ else
+ iftype_desc = iftypes[interfaces[i].iftype];
+
+ ea = interfaces[i].ea;
+ bcm_bprintf(strbuf, "INTERFACE[%d].ea = "
+ "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d, type: %s"
+ "netif_flow_control:%s\n", i,
+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
+ interfaces[i].interface_id,
+ iftype_desc, ((wlfc->hostif_flow_state[i] == OFF)
+ ? " OFF":" ON"));
+
+ bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ(len,state,credit)"
+ "= (%d,%s,%d)\n",
+ i,
+ interfaces[i].psq.len,
+ ((interfaces[i].state ==
+ WLFC_STATE_OPEN) ? " OPEN":"CLOSE"),
+ interfaces[i].requested_credit);
+
+ bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ"
+ "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = "
+ "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n",
+ i,
+ interfaces[i].psq.q[0].len,
+ interfaces[i].psq.q[1].len,
+ interfaces[i].psq.q[2].len,
+ interfaces[i].psq.q[3].len,
+ interfaces[i].psq.q[4].len,
+ interfaces[i].psq.q[5].len,
+ interfaces[i].psq.q[6].len,
+ interfaces[i].psq.q[7].len);
+ }
+ }
+
+ bcm_bprintf(strbuf, "\n");
+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
+ if (mac_table[i].occupied) {
+ ea = mac_table[i].ea;
+ bcm_bprintf(strbuf, "MAC_table[%d].ea = "
+ "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i,
+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
+ mac_table[i].interface_id);
+
+ bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ(len,state,credit)"
+ "= (%d,%s,%d)\n",
+ i,
+ mac_table[i].psq.len,
+ ((mac_table[i].state ==
+ WLFC_STATE_OPEN) ? " OPEN":"CLOSE"),
+ mac_table[i].requested_credit);
+#ifdef PROP_TXSTATUS_DEBUG
+ bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n",
+ i, mac_table[i].opened_ct, mac_table[i].closed_ct);
+#endif
+ bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ"
+ "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = "
+ "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n",
+ i,
+ mac_table[i].psq.q[0].len,
+ mac_table[i].psq.q[1].len,
+ mac_table[i].psq.q[2].len,
+ mac_table[i].psq.q[3].len,
+ mac_table[i].psq.q[4].len,
+ mac_table[i].psq.q[5].len,
+ mac_table[i].psq.q[6].len,
+ mac_table[i].psq.q[7].len);
+ }
+ }
+
+#ifdef PROP_TXSTATUS_DEBUG
+ {
+ int avg;
+ int moving_avg = 0;
+ int moving_samples;
+
+ if (wlfc->stats.latency_sample_count) {
+ moving_samples = sizeof(wlfc->stats.deltas)/sizeof(uint32);
+
+ for (i = 0; i < moving_samples; i++)
+ moving_avg += wlfc->stats.deltas[i];
+ moving_avg /= moving_samples;
+
+ avg = (100 * wlfc->stats.total_status_latency) /
+ wlfc->stats.latency_sample_count;
+ bcm_bprintf(strbuf, "txstatus latency (average, last, moving[%d]) = "
+ "(%d.%d, %03d, %03d)\n",
+ moving_samples, avg/100, (avg - (avg/100)*100),
+ wlfc->stats.latency_most_recent,
+ moving_avg);
+ }
+ }
+
+ bcm_bprintf(strbuf, "wlfc- fifo[0-5] credit stats: sent = (%d,%d,%d,%d,%d,%d), "
+ "back = (%d,%d,%d,%d,%d,%d)\n",
+ wlfc->stats.fifo_credits_sent[0],
+ wlfc->stats.fifo_credits_sent[1],
+ wlfc->stats.fifo_credits_sent[2],
+ wlfc->stats.fifo_credits_sent[3],
+ wlfc->stats.fifo_credits_sent[4],
+ wlfc->stats.fifo_credits_sent[5],
+
+ wlfc->stats.fifo_credits_back[0],
+ wlfc->stats.fifo_credits_back[1],
+ wlfc->stats.fifo_credits_back[2],
+ wlfc->stats.fifo_credits_back[3],
+ wlfc->stats.fifo_credits_back[4],
+ wlfc->stats.fifo_credits_back[5]);
+ {
+ uint32 fifo_cr_sent = 0;
+ uint32 fifo_cr_acked = 0;
+ uint32 request_cr_sent = 0;
+ uint32 request_cr_ack = 0;
+ uint32 bc_mc_cr_ack = 0;
+
+ for (i = 0; i < sizeof(wlfc->stats.fifo_credits_sent)/sizeof(uint32); i++) {
+ fifo_cr_sent += wlfc->stats.fifo_credits_sent[i];
+ }
+
+ for (i = 0; i < sizeof(wlfc->stats.fifo_credits_back)/sizeof(uint32); i++) {
+ fifo_cr_acked += wlfc->stats.fifo_credits_back[i];
+ }
+
+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
+ if (wlfc->destination_entries.nodes[i].occupied) {
+ request_cr_sent +=
+ wlfc->destination_entries.nodes[i].dstncredit_sent_packets;
+ }
+ }
+ for (i = 0; i < WLFC_MAX_IFNUM; i++) {
+ if (wlfc->destination_entries.interfaces[i].occupied) {
+ request_cr_sent +=
+ wlfc->destination_entries.interfaces[i].dstncredit_sent_packets;
+ }
+ }
+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
+ if (wlfc->destination_entries.nodes[i].occupied) {
+ request_cr_ack +=
+ wlfc->destination_entries.nodes[i].dstncredit_acks;
+ }
+ }
+ for (i = 0; i < WLFC_MAX_IFNUM; i++) {
+ if (wlfc->destination_entries.interfaces[i].occupied) {
+ request_cr_ack +=
+ wlfc->destination_entries.interfaces[i].dstncredit_acks;
+ }
+ }
+ bcm_bprintf(strbuf, "wlfc- (sent, status) => pq(%d,%d), vq(%d,%d),"
+ "other:%d, bc_mc:%d, signal-only, (sent,freed): (%d,%d)",
+ fifo_cr_sent, fifo_cr_acked,
+ request_cr_sent, request_cr_ack,
+ wlfc->destination_entries.other.dstncredit_acks,
+ bc_mc_cr_ack,
+ wlfc->stats.signal_only_pkts_sent, wlfc->stats.signal_only_pkts_freed);
+ }
+#endif /* PROP_TXSTATUS_DEBUG */
+ bcm_bprintf(strbuf, "\n");
+ bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull),(dropped,hdr_only,wlc_tossed)"
+ "(freed,free_err,rollback)) = "
+ "((%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n",
+ wlfc->stats.pktin,
+ wlfc->stats.pkt2bus,
+ wlfc->stats.txstatus_in,
+ wlfc->stats.dhd_hdrpulls,
+
+ wlfc->stats.pktdropped,
+ wlfc->stats.wlfc_header_only_pkt,
+ wlfc->stats.wlc_tossed_pkts,
+
+ wlfc->stats.pkt_freed,
+ wlfc->stats.pkt_free_err, wlfc->stats.rollback);
+
+ bcm_bprintf(strbuf, "wlfc- suppress((d11,wlc,err),enq(d11,wl,hq,mac?),retx(d11,wlc,hq)) = "
+ "((%d,%d,%d),(%d,%d,%d,%d),(%d,%d,%d))\n",
+
+ wlfc->stats.d11_suppress,
+ wlfc->stats.wl_suppress,
+ wlfc->stats.bad_suppress,
+
+ wlfc->stats.psq_d11sup_enq,
+ wlfc->stats.psq_wlsup_enq,
+ wlfc->stats.psq_hostq_enq,
+ wlfc->stats.mac_handle_notfound,
+
+ wlfc->stats.psq_d11sup_retx,
+ wlfc->stats.psq_wlsup_retx,
+ wlfc->stats.psq_hostq_retx);
+ return;
+}
+
+/* Create a place to store all packet pointers submitted to the firmware until
+ a status comes back, suppress or otherwise.
+
+ hang-er: noun, a contrivance on which things are hung, as a hook.
+*/
+static void*
+dhd_wlfc_hanger_create(osl_t *osh, int max_items)
+{
+ int i;
+ wlfc_hanger_t* hanger;
+
+ /* allow only up to a specific size for now */
+ ASSERT(max_items == WLFC_HANGER_MAXITEMS);
+
+ if ((hanger = (wlfc_hanger_t*)MALLOC(osh, WLFC_HANGER_SIZE(max_items))) == NULL)
+ return NULL;
+
+ memset(hanger, 0, WLFC_HANGER_SIZE(max_items));
+ hanger->max_items = max_items;
+
+ for (i = 0; i < hanger->max_items; i++) {
+ hanger->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ }
+ return hanger;
+}
+
+static int
+dhd_wlfc_hanger_delete(osl_t *osh, void* hanger)
+{
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ if (h) {
+ MFREE(osh, h, WLFC_HANGER_SIZE(h->max_items));
+ return BCME_OK;
+ }
+ return BCME_BADARG;
+}
+
+static uint16
+dhd_wlfc_hanger_get_free_slot(void* hanger)
+{
+ uint32 i;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ if (h) {
+ for (i = (h->slot_pos + 1); i != h->slot_pos;) {
+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_FREE) {
+ h->slot_pos = i;
+ return (uint16)i;
+ }
+ (i == h->max_items)? i = 0 : i++;
+ }
+ h->failed_slotfind++;
+ }
+ return WLFC_HANGER_MAXITEMS;
+}
+
+static int
+dhd_wlfc_hanger_get_genbit(void* hanger, void* pkt, uint32 slot_id, int* gen)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ *gen = 0xff;
+
+ /* this packet was not pushed at the time it went to the firmware */
+ if (slot_id == WLFC_HANGER_MAXITEMS)
+ return BCME_NOTFOUND;
+
+ if (h) {
+ if ((h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) ||
+ (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED)) {
+ *gen = h->items[slot_id].gen;
+ }
+ else {
+ rc = BCME_NOTFOUND;
+ }
+ }
+ else
+ rc = BCME_BADARG;
+ return rc;
+}
+
+static int
+dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ if (h && (slot_id < WLFC_HANGER_MAXITEMS)) {
+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_FREE) {
+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE;
+ h->items[slot_id].pkt = pkt;
+ h->items[slot_id].identifier = slot_id;
+ h->pushed++;
+ }
+ else {
+ h->failed_to_push++;
+ rc = BCME_NOTFOUND;
+ }
+ }
+ else
+ rc = BCME_BADARG;
+ return rc;
+}
+
+static int
+dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_from_hanger)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ /* this packet was not pushed at the time it went to the firmware */
+ if (slot_id == WLFC_HANGER_MAXITEMS)
+ return BCME_NOTFOUND;
+
+ if (h) {
+ if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) {
+ *pktout = h->items[slot_id].pkt;
+ if (remove_from_hanger) {
+ h->items[slot_id].state =
+ WLFC_HANGER_ITEM_STATE_FREE;
+ h->items[slot_id].pkt = NULL;
+ h->items[slot_id].identifier = 0;
+ h->items[slot_id].gen = 0xff;
+ h->popped++;
+ }
+ }
+ else {
+ h->failed_to_pop++;
+ rc = BCME_NOTFOUND;
+ }
+ }
+ else
+ rc = BCME_BADARG;
+ return rc;
+}
+
+static int
+dhd_wlfc_hanger_mark_suppressed(void* hanger, uint32 slot_id, uint8 gen)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ /* this packet was not pushed at the time it went to the firmware */
+ if (slot_id == WLFC_HANGER_MAXITEMS)
+ return BCME_NOTFOUND;
+ if (h) {
+ h->items[slot_id].gen = gen;
+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED;
+ }
+ else
+ rc = BCME_BADARG;
+ }
+ else
+ rc = BCME_BADARG;
+
+ return rc;
+}
+
+static int
+_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void* p, bool tim_signal,
+ uint8 tim_bmp, uint8 mac_handle, uint32 htodtag)
+{
+ uint32 wl_pktinfo = 0;
+ uint8* wlh;
+ uint8 dataOffset;
+ uint8 fillers;
+ uint8 tim_signal_len = 0;
+
+ struct bdc_header *h;
+
+ if (tim_signal) {
+ tim_signal_len = 1 + 1 + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP;
+ }
+
+ /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
+ dataOffset = WLFC_CTL_VALUE_LEN_PKTTAG + 2 + tim_signal_len;
+ fillers = ROUNDUP(dataOffset, 4) - dataOffset;
+ dataOffset += fillers;
+
+ PKTPUSH(ctx->osh, p, dataOffset);
+ wlh = (uint8*) PKTDATA(ctx->osh, p);
+
+ wl_pktinfo = htol32(htodtag);
+
+ wlh[0] = WLFC_CTL_TYPE_PKTTAG;
+ wlh[1] = WLFC_CTL_VALUE_LEN_PKTTAG;
+ memcpy(&wlh[2], &wl_pktinfo, sizeof(uint32));
+
+ if (tim_signal_len) {
+ wlh[dataOffset - fillers - tim_signal_len ] =
+ WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP;
+ wlh[dataOffset - fillers - tim_signal_len + 1] =
+ WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP;
+ wlh[dataOffset - fillers - tim_signal_len + 2] = mac_handle;
+ wlh[dataOffset - fillers - tim_signal_len + 3] = tim_bmp;
+ }
+ if (fillers)
+ memset(&wlh[dataOffset - fillers], WLFC_CTL_TYPE_FILLER, fillers);
+
+ PKTPUSH(ctx->osh, p, BDC_HEADER_LEN);
+ h = (struct bdc_header *)PKTDATA(ctx->osh, p);
+ h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
+ if (PKTSUMNEEDED(p))
+ h->flags |= BDC_FLAG_SUM_NEEDED;
+
+
+ h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK);
+ h->flags2 = 0;
+ h->dataOffset = dataOffset >> 2;
+ BDC_SET_IF_IDX(h, DHD_PKTTAG_IF(PKTTAG(p)));
+ return BCME_OK;
+}
+
+static int
+_dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf)
+{
+ struct bdc_header *h;
+
+ if (PKTLEN(ctx->osh, pktbuf) < BDC_HEADER_LEN) {
+ AP6210_DEBUG("%s: rx data too short (%d < %d)\n", __FUNCTION__,
+ PKTLEN(ctx->osh, pktbuf), BDC_HEADER_LEN);
+ return BCME_ERROR;
+ }
+ h = (struct bdc_header *)PKTDATA(ctx->osh, pktbuf);
+
+ /* pull BDC header */
+ PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN);
+
+ if (PKTLEN(ctx->osh, pktbuf) < (h->dataOffset << 2)) {
+ AP6210_DEBUG("%s: rx data too short (%d < %d)\n", __FUNCTION__,
+ PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2));
+ return BCME_ERROR;
+ }
+ /* pull wl-header */
+ PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2));
+ return BCME_OK;
+}
+
+static wlfc_mac_descriptor_t*
+_dhd_wlfc_find_table_entry(athost_wl_status_info_t* ctx, void* p)
+{
+ int i;
+ wlfc_mac_descriptor_t* table = ctx->destination_entries.nodes;
+ uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p));
+ uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p));
+
+ if (((ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_STA) ||
+ ETHER_ISMULTI(dstn) ||
+ (ctx->destination_entries.interfaces[ifid].iftype == WLC_E_IF_ROLE_P2P_CLIENT)) &&
+ (ctx->destination_entries.interfaces[ifid].occupied)) {
+ return &ctx->destination_entries.interfaces[ifid];
+ }
+
+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
+ if (table[i].occupied) {
+ if (table[i].interface_id == ifid) {
+ if (!memcmp(table[i].ea, dstn, ETHER_ADDR_LEN))
+ return &table[i];
+ }
+ }
+ }
+ return &ctx->destination_entries.other;
+}
+
+static int
+_dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx,
+ void* p, ewlfc_packet_state_t pkt_type, uint32 hslot)
+{
+ /*
+ put the packet back to the head of queue
+
+ - a packet from send-q will need to go back to send-q and not delay-q
+ since that will change the order of packets.
+ - suppressed packet goes back to suppress sub-queue
+ - pull out the header, if new or delayed packet
+
+ Note: hslot is used only when header removal is done.
+ */
+ wlfc_mac_descriptor_t* entry;
+ void* pktout;
+ int rc = BCME_OK;
+ int prec;
+
+ entry = _dhd_wlfc_find_table_entry(ctx, p);
+ prec = DHD_PKTTAG_FIFO(PKTTAG(p));
+ if (entry != NULL) {
+ if (pkt_type == eWLFC_PKTTYPE_SUPPRESSED) {
+ /* wl-header is saved for suppressed packets */
+ if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, ((prec << 1) + 1), p) == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ rc = BCME_ERROR;
+ }
+ }
+ else {
+ /* remove header first */
+ rc = _dhd_wlfc_pullheader(ctx, p);
+ if (rc != BCME_OK) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ /* free the hanger slot */
+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1);
+ PKTFREE(ctx->osh, p, TRUE);
+ rc = BCME_ERROR;
+ return rc;
+ }
+
+ if (pkt_type == eWLFC_PKTTYPE_DELAYED) {
+ /* delay-q packets are going to delay-q */
+ if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, (prec << 1), p) == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ rc = BCME_ERROR;
+ }
+ }
+ else {
+ /* these are going to SENDQ */
+ if (WLFC_PKTQ_PENQ_HEAD(&ctx->SENDQ, prec, p) == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ rc = BCME_ERROR;
+ }
+ }
+ /* free the hanger slot */
+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1);
+
+ /* decrement sequence count */
+ WLFC_DECR_SEQCOUNT(entry, prec);
+ }
+ /*
+ if this packet did not count against FIFO credit, it must have
+ taken a requested_credit from the firmware (for pspoll etc.)
+ */
+ if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) {
+ entry->requested_credit++;
+ }
+ }
+ else {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ rc = BCME_ERROR;
+ }
+ if (rc != BCME_OK)
+ ctx->stats.rollback_failed++;
+ else
+ ctx->stats.rollback++;
+
+ return rc;
+}
+
+static void
+_dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint8 if_id)
+{
+ if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) {
+ /* start traffic */
+ ctx->hostif_flow_state[if_id] = OFF;
+ /*
+ AP6210_DEBUG("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n",
+ pq->len, if_id, __FUNCTION__);
+ */
+ AP6210_DEBUG("F");
+ dhd_txflowcontrol(ctx->dhdp, if_id, OFF);
+ ctx->toggle_host_if = 0;
+ }
+ if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) {
+ /* stop traffic */
+ ctx->hostif_flow_state[if_id] = ON;
+ /*
+ AP6210_DEBUG("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n",
+ pq->len, if_id, __FUNCTION__);
+ */
+ AP6210_DEBUG("N");
+ dhd_txflowcontrol(ctx->dhdp, if_id, ON);
+ ctx->host_ifidx = if_id;
+ ctx->toggle_host_if = 1;
+ }
+ return;
+}
+
+static int
+_dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
+ uint8 ta_bmp)
+{
+ int rc = BCME_OK;
+ void* p = NULL;
+ int dummylen = ((dhd_pub_t *)ctx->dhdp)->hdrlen+ 12;
+
+ /* allocate a dummy packet */
+ p = PKTGET(ctx->osh, dummylen, TRUE);
+ if (p) {
+ PKTPULL(ctx->osh, p, dummylen);
+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), 0);
+ _dhd_wlfc_pushheader(ctx, p, TRUE, ta_bmp, entry->mac_handle, 0);
+ DHD_PKTTAG_SETSIGNALONLY(PKTTAG(p), 1);
+#ifdef PROP_TXSTATUS_DEBUG
+ ctx->stats.signal_only_pkts_sent++;
+#endif
+ rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p, FALSE);
+ if (rc != BCME_OK) {
+ PKTFREE(ctx->osh, p, TRUE);
+ }
+ }
+ else {
+ AP6210_ERR("%s: couldn't allocate new %d-byte packet\n",
+ __FUNCTION__, dummylen);
+ rc = BCME_NOMEM;
+ }
+ return rc;
+}
+
+/* Return TRUE if traffic availability changed */
+static bool
+_dhd_wlfc_traffic_pending_check(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
+ int prec)
+{
+ bool rc = FALSE;
+
+ if (entry->state == WLFC_STATE_CLOSE) {
+ if ((pktq_plen(&entry->psq, (prec << 1)) == 0) &&
+ (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) {
+
+ if (entry->traffic_pending_bmp & NBITVAL(prec)) {
+ rc = TRUE;
+ entry->traffic_pending_bmp =
+ entry->traffic_pending_bmp & ~ NBITVAL(prec);
+ }
+ }
+ else {
+ if (!(entry->traffic_pending_bmp & NBITVAL(prec))) {
+ rc = TRUE;
+ entry->traffic_pending_bmp =
+ entry->traffic_pending_bmp | NBITVAL(prec);
+ }
+ }
+ }
+ if (rc) {
+ /* request a TIM update to firmware at the next piggyback opportunity */
+ if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp) {
+ entry->send_tim_signal = 1;
+ _dhd_wlfc_send_signalonly_packet(ctx, entry, entry->traffic_pending_bmp);
+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
+ entry->send_tim_signal = 0;
+ }
+ else {
+ rc = FALSE;
+ }
+ }
+ return rc;
+}
+
+static int
+_dhd_wlfc_enque_suppressed(athost_wl_status_info_t* ctx, int prec, void* p)
+{
+ wlfc_mac_descriptor_t* entry;
+
+ entry = _dhd_wlfc_find_table_entry(ctx, p);
+ if (entry == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_NOTFOUND;
+ }
+ /*
+ - suppressed packets go to sub_queue[2*prec + 1] AND
+ - delayed packets go to sub_queue[2*prec + 0] to ensure
+ order of delivery.
+ */
+ if (WLFC_PKTQ_PENQ(&entry->psq, ((prec << 1) + 1), p) == NULL) {
+ ctx->stats.delayq_full_error++;
+ /* AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); */
+ AP6210_DEBUG("s");
+ return BCME_ERROR;
+ }
+ /* A packet has been pushed, update traffic availability bitmap, if applicable */
+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec);
+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p)));
+ return BCME_OK;
+}
+
+static int
+_dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx,
+ wlfc_mac_descriptor_t* entry, void* p, int header_needed, uint32* slot)
+{
+ int rc = BCME_OK;
+ int hslot = WLFC_HANGER_MAXITEMS;
+ bool send_tim_update = FALSE;
+ uint32 htod = 0;
+ uint8 free_ctr;
+
+ *slot = hslot;
+
+ if (entry == NULL) {
+ entry = _dhd_wlfc_find_table_entry(ctx, p);
+ }
+
+ if (entry == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_ERROR;
+ }
+ if (entry->send_tim_signal) {
+ send_tim_update = TRUE;
+ entry->send_tim_signal = 0;
+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
+ }
+ if (header_needed) {
+ hslot = dhd_wlfc_hanger_get_free_slot(ctx->hanger);
+ free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p)));
+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod);
+ WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation);
+ entry->transit_count++;
+ }
+ else {
+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ }
+ WLFC_PKTID_HSLOT_SET(htod, hslot);
+ WLFC_PKTID_FREERUNCTR_SET(htod, free_ctr);
+ DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1);
+ WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST);
+ WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p)));
+
+ if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) {
+ /*
+ Indicate that this packet is being sent in response to an
+ explicit request from the firmware side.
+ */
+ WLFC_PKTFLAG_SET_PKTREQUESTED(htod);
+ }
+ else {
+ WLFC_PKTFLAG_CLR_PKTREQUESTED(htod);
+ }
+ if (header_needed) {
+ rc = _dhd_wlfc_pushheader(ctx, p, send_tim_update,
+ entry->traffic_lastreported_bmp, entry->mac_handle, htod);
+ if (rc == BCME_OK) {
+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod);
+ /*
+ a new header was created for this packet.
+ push to hanger slot and scrub q. Since bus
+ send succeeded, increment seq number as well.
+ */
+ rc = dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot);
+ if (rc == BCME_OK) {
+ /* increment free running sequence count */
+ WLFC_INCR_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p)));
+#ifdef PROP_TXSTATUS_DEBUG
+ ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].push_time =
+ OSL_SYSUPTIME();
+#endif
+ }
+ else {
+ AP6210_DEBUG("%s() hanger_pushpkt() failed, rc: %d\n",
+ __FUNCTION__, rc);
+ }
+ }
+ }
+ else {
+ int gen;
+
+ /* remove old header */
+ rc = _dhd_wlfc_pullheader(ctx, p);
+ if (rc == BCME_OK) {
+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen);
+
+ WLFC_PKTFLAG_SET_GENERATION(htod, gen);
+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ /* push new header */
+ _dhd_wlfc_pushheader(ctx, p, send_tim_update,
+ entry->traffic_lastreported_bmp, entry->mac_handle, htod);
+ }
+ }
+ *slot = hslot;
+ return rc;
+}
+
+static int
+_dhd_wlfc_is_destination_closed(athost_wl_status_info_t* ctx,
+ wlfc_mac_descriptor_t* entry, int prec)
+{
+ if (ctx->destination_entries.interfaces[entry->interface_id].iftype ==
+ WLC_E_IF_ROLE_P2P_GO) {
+ /* - destination interface is of type p2p GO.
+ For a p2pGO interface, if the destination is OPEN but the interface is
+ CLOSEd, do not send traffic. But if the dstn is CLOSEd while there is
+ destination-specific-credit left send packets. This is because the
+ firmware storing the destination-specific-requested packet in queue.
+ */
+ if ((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) &&
+ (entry->requested_packet == 0))
+ return 1;
+ }
+ /* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */
+ if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) &&
+ (entry->requested_packet == 0)) ||
+ (!(entry->ac_bitmap & (1 << prec))))
+ return 1;
+
+ return 0;
+}
+
+static void*
+_dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx,
+ int prec, uint8* ac_credit_spent, uint8* needs_hdr, wlfc_mac_descriptor_t** entry_out)
+{
+ wlfc_mac_descriptor_t* entry;
+ wlfc_mac_descriptor_t* table;
+ uint8 token_pos;
+ int total_entries;
+ void* p = NULL;
+ int pout;
+ int i;
+
+ *entry_out = NULL;
+ token_pos = ctx->token_pos[prec];
+ /* most cases a packet will count against FIFO credit */
+ *ac_credit_spent = 1;
+ *needs_hdr = 1;
+
+ /* search all entries, include nodes as well as interfaces */
+ table = (wlfc_mac_descriptor_t*)&ctx->destination_entries;
+ total_entries = sizeof(ctx->destination_entries)/sizeof(wlfc_mac_descriptor_t);
+
+ for (i = 0; i < total_entries; i++) {
+ entry = &table[(token_pos + i) % total_entries];
+ if (entry->occupied) {
+ if (!_dhd_wlfc_is_destination_closed(ctx, entry, prec)) {
+ p = pktq_mdeq(&entry->psq,
+ /* higher precedence will be picked up first,
+ * i.e. suppressed packets before delayed ones
+ */
+ NBITVAL((prec << 1) + 1), &pout);
+ *needs_hdr = 0;
+
+ if (p == NULL) {
+ if (entry->suppressed == TRUE) {
+ if ((entry->suppr_transit_count <=
+ entry->suppress_count)) {
+ entry->suppressed = FALSE;
+ } else {
+ return NULL;
+ }
+ }
+ /* De-Q from delay Q */
+ p = pktq_mdeq(&entry->psq,
+ NBITVAL((prec << 1)),
+ &pout);
+ *needs_hdr = 1;
+ }
+
+ if (p != NULL) {
+ /* did the packet come from suppress sub-queue? */
+ if (entry->requested_credit > 0) {
+ entry->requested_credit--;
+#ifdef PROP_TXSTATUS_DEBUG
+ entry->dstncredit_sent_packets++;
+#endif
+ /*
+ if the packet was pulled out while destination is in
+ closed state but had a non-zero packets requested,
+ then this should not count against the FIFO credit.
+ That is due to the fact that the firmware will
+ most likely hold onto this packet until a suitable
+ time later to push it to the appropriate AC FIFO.
+ */
+ if (entry->state == WLFC_STATE_CLOSE)
+ *ac_credit_spent = 0;
+ }
+ else if (entry->requested_packet > 0) {
+ entry->requested_packet--;
+ DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p));
+ if (entry->state == WLFC_STATE_CLOSE)
+ *ac_credit_spent = 0;
+ }
+ /* move token to ensure fair round-robin */
+ ctx->token_pos[prec] =
+ (token_pos + i + 1) % total_entries;
+ *entry_out = entry;
+ _dhd_wlfc_flow_control_check(ctx, &entry->psq,
+ DHD_PKTTAG_IF(PKTTAG(p)));
+ /*
+ A packet has been picked up, update traffic
+ availability bitmap, if applicable
+ */
+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec);
+ return p;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+static void*
+_dhd_wlfc_deque_sendq(athost_wl_status_info_t* ctx, int prec)
+{
+ wlfc_mac_descriptor_t* entry;
+ void* p;
+
+
+ p = pktq_pdeq(&ctx->SENDQ, prec);
+ if (p != NULL) {
+ if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(p))))
+ /* bc/mc packets do not have a delay queue */
+ return p;
+
+ entry = _dhd_wlfc_find_table_entry(ctx, p);
+
+ if (entry == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return p;
+ }
+
+ while ((p != NULL)) {
+ /*
+ - suppressed packets go to sub_queue[2*prec + 1] AND
+ - delayed packets go to sub_queue[2*prec + 0] to ensure
+ order of delivery.
+ */
+ if (WLFC_PKTQ_PENQ(&entry->psq, (prec << 1), p) == NULL) {
+ AP6210_DEBUG("D");
+ /* dhd_txcomplete(ctx->dhdp, p, FALSE); */
+ PKTFREE(ctx->osh, p, TRUE);
+ ctx->stats.delayq_full_error++;
+ }
+ /*
+ A packet has been pushed, update traffic availability bitmap,
+ if applicable
+ */
+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec);
+
+ p = pktq_pdeq(&ctx->SENDQ, prec);
+ if (p == NULL)
+ break;
+
+ entry = _dhd_wlfc_find_table_entry(ctx, p);
+
+ if ((entry == NULL) || (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(p))))) {
+ return p;
+ }
+ }
+ }
+ return p;
+}
+
+static int
+_dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea)
+{
+ int rc = BCME_OK;
+
+ if (action == eWLFC_MAC_ENTRY_ACTION_ADD) {
+ entry->occupied = 1;
+ entry->state = WLFC_STATE_OPEN;
+ entry->requested_credit = 0;
+ entry->interface_id = ifid;
+ entry->iftype = iftype;
+ entry->ac_bitmap = 0xff; /* update this when handling APSD */
+ /* for an interface entry we may not care about the MAC address */
+ if (ea != NULL)
+ memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN);
+ pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN);
+ }
+ else if (action == eWLFC_MAC_ENTRY_ACTION_UPDATE) {
+ entry->occupied = 1;
+ entry->state = WLFC_STATE_OPEN;
+ entry->requested_credit = 0;
+ entry->interface_id = ifid;
+ entry->iftype = iftype;
+ entry->ac_bitmap = 0xff; /* update this when handling APSD */
+ /* for an interface entry we may not care about the MAC address */
+ if (ea != NULL)
+ memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN);
+ }
+ else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) {
+ entry->occupied = 0;
+ entry->state = WLFC_STATE_CLOSE;
+ entry->requested_credit = 0;
+ /* enable after packets are queued-deqeued properly.
+ pktq_flush(dhd->osh, &entry->psq, FALSE, NULL, 0);
+ */
+ }
+ return rc;
+}
+
+int
+_dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, uint8 available_credit_map, int borrower_ac)
+{
+ int lender_ac;
+ int rc = BCME_ERROR;
+
+ if (ctx == NULL || available_credit_map == 0) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_BADARG;
+ }
+
+ /* Borrow from lowest priority available AC (including BC/MC credits) */
+ for (lender_ac = 0; lender_ac <= AC_COUNT; lender_ac++) {
+ if ((available_credit_map && (1 << lender_ac)) &&
+ (ctx->FIFO_credit[lender_ac] > 0)) {
+ ctx->credits_borrowed[borrower_ac][lender_ac]++;
+ ctx->FIFO_credit[lender_ac]--;
+ rc = BCME_OK;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+int
+dhd_wlfc_interface_entry_update(void* state,
+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea)
+{
+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+ wlfc_mac_descriptor_t* entry;
+
+ if (ifid >= WLFC_MAX_IFNUM)
+ return BCME_BADARG;
+
+ entry = &ctx->destination_entries.interfaces[ifid];
+ return _dhd_wlfc_mac_entry_update(ctx, entry, action, ifid, iftype, ea);
+}
+
+int
+dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits)
+{
+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+
+ /* update the AC FIFO credit map */
+ ctx->FIFO_credit[0] = credits[0];
+ ctx->FIFO_credit[1] = credits[1];
+ ctx->FIFO_credit[2] = credits[2];
+ ctx->FIFO_credit[3] = credits[3];
+ /* credit for bc/mc packets */
+ ctx->FIFO_credit[4] = credits[4];
+ /* credit for ATIM FIFO is not used yet. */
+ ctx->FIFO_credit[5] = 0;
+ return BCME_OK;
+}
+
+int
+dhd_wlfc_enque_sendq(void* state, int prec, void* p)
+{
+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+
+ if ((state == NULL) ||
+ /* prec = AC_COUNT is used for bc/mc queue */
+ (prec > AC_COUNT) ||
+ (p == NULL)) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_BADARG;
+ }
+ if (FALSE == dhd_prec_enq(ctx->dhdp, &ctx->SENDQ, p, prec)) {
+ ctx->stats.sendq_full_error++;
+ /*
+ AP6210_DEBUG("Error: %s():%d, qlen:%d\n",
+ __FUNCTION__, __LINE__, ctx->SENDQ.len);
+ */
+ WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, prec);
+ AP6210_DEBUG("Q");
+ PKTFREE(ctx->osh, p, TRUE);
+ return BCME_ERROR;
+ }
+ ctx->stats.pktin++;
+ /* _dhd_wlfc_flow_control_check(ctx, &ctx->SENDQ, DHD_PKTTAG_IF(PKTTAG(p))); */
+ return BCME_OK;
+}
+
+int
+_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac,
+ dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx)
+{
+ uint32 hslot;
+ int rc;
+
+ /*
+ if ac_fifo_credit_spent = 0
+
+ This packet will not count against the FIFO credit.
+ To ensure the txstatus corresponding to this packet
+ does not provide an implied credit (default behavior)
+ mark the packet accordingly.
+
+ if ac_fifo_credit_spent = 1
+
+ This is a normal packet and it counts against the FIFO
+ credit count.
+ */
+ DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent);
+ rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, commit_info->p,
+ commit_info->needs_hdr, &hslot);
+
+ if (rc == BCME_OK)
+ rc = fcommit(commit_ctx, commit_info->p, TRUE);
+ else
+ ctx->stats.generic_error++;
+
+ if (rc == BCME_OK) {
+ ctx->stats.pkt2bus++;
+ if (commit_info->ac_fifo_credit_spent) {
+ ctx->stats.sendq_pkts[ac]++;
+ WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac);
+ }
+ } else if (rc == BCME_NORESOURCE)
+ rc = BCME_ERROR;
+ else {
+ /*
+ bus commit has failed, rollback.
+ - remove wl-header for a delayed packet
+ - save wl-header header for suppressed packets
+ */
+ rc = _dhd_wlfc_rollback_packet_toq(ctx, commit_info->p,
+ (commit_info->pkt_type), hslot);
+ if (rc != BCME_OK)
+ ctx->stats.rollback_failed++;
+
+ rc = BCME_ERROR;
+ }
+
+ return rc;
+}
+
+int
+dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx)
+{
+ int ac;
+ int credit;
+ int rc;
+ dhd_wlfc_commit_info_t commit_info;
+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+ int credit_count = 0;
+ int bus_retry_count = 0;
+ uint8 ac_available = 0; /* Bitmask for 4 ACs + BC/MC */
+
+ if ((state == NULL) ||
+ (fcommit == NULL)) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_BADARG;
+ }
+
+ memset(&commit_info, 0, sizeof(commit_info));
+
+ /*
+ Commit packets for regular AC traffic. Higher priority first.
+ First, use up FIFO credits available to each AC. Based on distribution
+ and credits left, borrow from other ACs as applicable
+
+ -NOTE:
+ If the bus between the host and firmware is overwhelmed by the
+ traffic from host, it is possible that higher priority traffic
+ starves the lower priority queue. If that occurs often, we may
+ have to employ weighted round-robin or ucode scheme to avoid
+ low priority packet starvation.
+ */
+
+ for (ac = AC_COUNT; ac >= 0; ac--) {
+
+ int initial_credit_count = ctx->FIFO_credit[ac];
+
+ /* packets from SENDQ are fresh and they'd need header and have no MAC entry */
+ commit_info.needs_hdr = 1;
+ commit_info.mac_entry = NULL;
+ commit_info.pkt_type = eWLFC_PKTTYPE_NEW;
+
+ do {
+ commit_info.p = _dhd_wlfc_deque_sendq(ctx, ac);
+ if (commit_info.p == NULL)
+ break;
+ else if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(commit_info.p)))) {
+ ASSERT(ac == AC_COUNT);
+
+ if (ctx->FIFO_credit[ac]) {
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+
+ /* Bus commits may fail (e.g. flow control); abort after retries */
+ if (rc == BCME_OK) {
+ if (commit_info.ac_fifo_credit_spent) {
+ (void) _dhd_wlfc_borrow_credit(ctx,
+ ac_available, ac);
+ credit_count--;
+ }
+ } else {
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ AP6210_ERR(" %s: bus error\n",
+ __FUNCTION__);
+ return rc;
+ }
+ }
+ }
+ }
+
+ } while (commit_info.p);
+
+ for (credit = 0; credit < ctx->FIFO_credit[ac];) {
+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
+ &(commit_info.ac_fifo_credit_spent),
+ &(commit_info.needs_hdr),
+ &(commit_info.mac_entry));
+
+ if (commit_info.p == NULL)
+ break;
+
+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
+ eWLFC_PKTTYPE_SUPPRESSED;
+
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+
+ /* Bus commits may fail (e.g. flow control); abort after retries */
+ if (rc == BCME_OK) {
+ if (commit_info.ac_fifo_credit_spent) {
+ credit++;
+ }
+ }
+ else {
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ AP6210_ERR("dhd_wlfc_commit_packets(): bus error\n");
+ ctx->FIFO_credit[ac] -= credit;
+ return rc;
+ }
+ }
+ }
+
+ ctx->FIFO_credit[ac] -= credit;
+
+
+ /* If no credits were used, the queue is idle and can be re-used
+ Note that resv credits cannot be borrowed
+ */
+ if (initial_credit_count == ctx->FIFO_credit[ac]) {
+ ac_available |= (1 << ac);
+ credit_count += ctx->FIFO_credit[ac];
+ }
+ }
+
+ /* We borrow only for AC_BE and only if no other traffic seen for DEFER_PERIOD
+
+ Note that (ac_available & WLFC_AC_BE_TRAFFIC_ONLY) is done to:
+ a) ignore BC/MC for deferring borrow
+ b) ignore AC_BE being available along with other ACs
+ (this should happen only for pure BC/MC traffic)
+
+ i.e. AC_VI, AC_VO, AC_BK all MUST be available (i.e. no traffic) and
+ we do not care if AC_BE and BC/MC are available or not
+ */
+ if ((ac_available & WLFC_AC_BE_TRAFFIC_ONLY) == WLFC_AC_BE_TRAFFIC_ONLY) {
+
+ if (ctx->allow_credit_borrow) {
+ ac = 1; /* Set ac to AC_BE and borrow credits */
+ }
+ else {
+ int delta;
+ int curr_t = OSL_SYSUPTIME();
+
+ if (curr_t > ctx->borrow_defer_timestamp)
+ delta = curr_t - ctx->borrow_defer_timestamp;
+ else
+ delta = 0xffffffff + curr_t - ctx->borrow_defer_timestamp;
+
+ if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) {
+ /* Reset borrow but defer to next iteration (defensive borrowing) */
+ ctx->allow_credit_borrow = TRUE;
+ ctx->borrow_defer_timestamp = 0;
+ }
+ return BCME_OK;
+ }
+ }
+ else {
+ /* If we have multiple AC traffic, turn off borrowing, mark time and bail out */
+ ctx->allow_credit_borrow = FALSE;
+ ctx->borrow_defer_timestamp = OSL_SYSUPTIME();
+ return BCME_OK;
+ }
+
+ /* At this point, borrow all credits only for "ac" (which should be set above to AC_BE)
+ Generically use "ac" only in case we extend to all ACs in future
+ */
+ for (; (credit_count > 0);) {
+
+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
+ &(commit_info.ac_fifo_credit_spent),
+ &(commit_info.needs_hdr),
+ &(commit_info.mac_entry));
+ if (commit_info.p == NULL)
+ break;
+
+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
+ eWLFC_PKTTYPE_SUPPRESSED;
+
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+
+ /* Bus commits may fail (e.g. flow control); abort after retries */
+ if (rc == BCME_OK) {
+ if (commit_info.ac_fifo_credit_spent) {
+ (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac);
+ credit_count--;
+ }
+ }
+ else {
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ AP6210_ERR("dhd_wlfc_commit_packets(): bus error\n");
+ return rc;
+ }
+ }
+ }
+
+ return BCME_OK;
+}
+
+static uint8
+dhd_wlfc_find_mac_desc_id_from_mac(dhd_pub_t *dhdp, uint8* ea)
+{
+ wlfc_mac_descriptor_t* table =
+ ((athost_wl_status_info_t*)dhdp->wlfc_state)->destination_entries.nodes;
+ uint8 table_index;
+
+ if (ea != NULL) {
+ for (table_index = 0; table_index < WLFC_MAC_DESC_TABLE_SIZE; table_index++) {
+ if ((memcmp(ea, &table[table_index].ea[0], ETHER_ADDR_LEN) == 0) &&
+ table[table_index].occupied)
+ return table_index;
+ }
+ }
+ return WLFC_MAC_DESC_ID_INVALID;
+}
+
+void
+dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success, bool wake_locked)
+{
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ void* p;
+ int fifo_id;
+
+ if (!wake_locked)
+ dhd_os_wlfc_block(dhd);
+
+ if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) {
+#ifdef PROP_TXSTATUS_DEBUG
+ wlfc->stats.signal_only_pkts_freed++;
+#endif
+ if (success)
+ /* is this a signal-only packet? */
+ PKTFREE(wlfc->osh, txp, TRUE);
+ if (!wake_locked)
+ dhd_os_wlfc_unblock(dhd);
+ return;
+ }
+ if (!success) {
+ AP6210_DEBUG("At: %s():%d, bus_complete() failure for %p, htod_tag:0x%08x\n",
+ __FUNCTION__, __LINE__, txp, DHD_PKTTAG_H2DTAG(PKTTAG(txp)));
+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG
+ (PKTTAG(txp))), &p, 1);
+
+ /* indicate failure and free the packet */
+ dhd_txcomplete(dhd, txp, FALSE);
+
+ /* return the credit, if necessary */
+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(txp))) {
+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */
+
+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(txp));
+
+ /* Return credits to highest priority lender first */
+ for (lender = AC_COUNT; lender >= 0; lender--) {
+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) {
+ wlfc->FIFO_credit[lender]++;
+ wlfc->credits_borrowed[fifo_id][lender]--;
+ credit_returned = 1;
+ break;
+ }
+ }
+
+ if (!credit_returned) {
+ wlfc->FIFO_credit[fifo_id]++;
+ }
+ }
+
+ PKTFREE(wlfc->osh, txp, TRUE);
+ }
+ if (!wake_locked)
+ dhd_os_wlfc_unblock(dhd);
+ return;
+}
+
+static int
+dhd_wlfc_compressed_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info, uint8 len)
+{
+ uint8 status_flag;
+ uint32 status;
+ int ret;
+ int remove_from_hanger = 1;
+ void* pktbuf;
+ uint8 fifo_id;
+ uint8 count = 0;
+ uint32 status_g;
+ uint32 hslot, hcnt;
+ wlfc_mac_descriptor_t* entry = NULL;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+
+ memcpy(&status, pkt_info, sizeof(uint32));
+ status_flag = WL_TXSTATUS_GET_FLAGS(status);
+ status_g = status & 0xff000000;
+ hslot = (status & 0x00ffff00) >> 8;
+ hcnt = status & 0xff;
+ len = pkt_info[4];
+
+ wlfc->stats.txstatus_in++;
+
+ if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) {
+ wlfc->stats.pkt_freed++;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) {
+ wlfc->stats.d11_suppress++;
+ remove_from_hanger = 0;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) {
+ wlfc->stats.wl_suppress++;
+ remove_from_hanger = 0;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) {
+ wlfc->stats.wlc_tossed_pkts++;
+ }
+ while (count < len) {
+ status = (status_g << 24) | (hslot << 8) | (hcnt);
+ count++;
+ hslot++;
+ hcnt++;
+
+ ret = dhd_wlfc_hanger_poppkt(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger);
+ if (ret != BCME_OK) {
+ /* do something */
+ continue;
+ }
+
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+
+ if (!remove_from_hanger) {
+ /* this packet was suppressed */
+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) {
+ entry->suppressed = TRUE;
+ entry->suppress_count = pktq_mlen(&entry->psq,
+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1));
+ entry->suppr_transit_count = entry->transit_count;
+ }
+ entry->generation = WLFC_PKTID_GEN(status);
+ }
+
+#ifdef PROP_TXSTATUS_DEBUG
+ {
+ uint32 new_t = OSL_SYSUPTIME();
+ uint32 old_t;
+ uint32 delta;
+ old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[
+ WLFC_PKTID_HSLOT_GET(status)].push_time;
+
+
+ wlfc->stats.latency_sample_count++;
+ if (new_t > old_t)
+ delta = new_t - old_t;
+ else
+ delta = 0xffffffff + new_t - old_t;
+ wlfc->stats.total_status_latency += delta;
+ wlfc->stats.latency_most_recent = delta;
+
+ wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta;
+ if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32))
+ wlfc->stats.idx_delta = 0;
+ }
+#endif /* PROP_TXSTATUS_DEBUG */
+
+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf));
+
+ /* pick up the implicit credit from this packet */
+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) {
+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) {
+
+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */
+
+ /* Return credits to highest priority lender first */
+ for (lender = AC_COUNT; lender >= 0; lender--) {
+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) {
+ wlfc->FIFO_credit[lender]++;
+ wlfc->credits_borrowed[fifo_id][lender]--;
+ credit_returned = 1;
+ break;
+ }
+ }
+
+ if (!credit_returned) {
+ wlfc->FIFO_credit[fifo_id]++;
+ }
+ }
+ }
+ else {
+ /*
+ if this packet did not count against FIFO credit, it must have
+ taken a requested_credit from the destination entry (for pspoll etc.)
+ */
+ if (!entry) {
+
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+ }
+ if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf)))
+ entry->requested_credit++;
+#ifdef PROP_TXSTATUS_DEBUG
+ entry->dstncredit_acks++;
+#endif
+ }
+ if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) ||
+ (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) {
+
+ ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf);
+ if (ret != BCME_OK) {
+ /* delay q is full, drop this packet */
+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status),
+ &pktbuf, 1);
+
+ /* indicate failure and free the packet */
+ dhd_txcomplete(dhd, pktbuf, FALSE);
+ entry->transit_count--;
+ /* packet is transmitted Successfully by dongle
+ * after first suppress.
+ */
+ if (entry->suppressed) {
+ entry->suppr_transit_count--;
+ }
+ PKTFREE(wlfc->osh, pktbuf, TRUE);
+ } else {
+ /* Mark suppressed to avoid a double free during wlfc cleanup */
+
+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status));
+ entry->suppress_count++;
+ }
+ }
+ else {
+ dhd_txcomplete(dhd, pktbuf, TRUE);
+ entry->transit_count--;
+
+ /* This packet is transmitted Successfully by dongle
+ * even after first suppress.
+ */
+ if (entry->suppressed) {
+ entry->suppr_transit_count--;
+ }
+ /* free the packet */
+ PKTFREE(wlfc->osh, pktbuf, TRUE);
+ }
+ }
+ return BCME_OK;
+}
+
+/* Handle discard or suppress indication */
+static int
+dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info)
+{
+ uint8 status_flag;
+ uint32 status;
+ int ret;
+ int remove_from_hanger = 1;
+ void* pktbuf;
+ uint8 fifo_id;
+ wlfc_mac_descriptor_t* entry = NULL;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+
+ memcpy(&status, pkt_info, sizeof(uint32));
+ status_flag = WL_TXSTATUS_GET_FLAGS(status);
+ wlfc->stats.txstatus_in++;
+
+ if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) {
+ wlfc->stats.pkt_freed++;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) {
+ wlfc->stats.d11_suppress++;
+ remove_from_hanger = 0;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) {
+ wlfc->stats.wl_suppress++;
+ remove_from_hanger = 0;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) {
+ wlfc->stats.wlc_tossed_pkts++;
+ }
+
+ ret = dhd_wlfc_hanger_poppkt(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger);
+ if (ret != BCME_OK) {
+ /* do something */
+ return ret;
+ }
+
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+
+ if (!remove_from_hanger) {
+ /* this packet was suppressed */
+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) {
+ entry->suppressed = TRUE;
+ entry->suppress_count = pktq_mlen(&entry->psq,
+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1));
+ entry->suppr_transit_count = entry->transit_count;
+ }
+ entry->generation = WLFC_PKTID_GEN(status);
+ }
+
+#ifdef PROP_TXSTATUS_DEBUG
+ {
+ uint32 new_t = OSL_SYSUPTIME();
+ uint32 old_t;
+ uint32 delta;
+ old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[
+ WLFC_PKTID_HSLOT_GET(status)].push_time;
+
+
+ wlfc->stats.latency_sample_count++;
+ if (new_t > old_t)
+ delta = new_t - old_t;
+ else
+ delta = 0xffffffff + new_t - old_t;
+ wlfc->stats.total_status_latency += delta;
+ wlfc->stats.latency_most_recent = delta;
+
+ wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta;
+ if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32))
+ wlfc->stats.idx_delta = 0;
+ }
+#endif /* PROP_TXSTATUS_DEBUG */
+
+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf));
+
+ /* pick up the implicit credit from this packet */
+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) {
+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) {
+
+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */
+
+ /* Return credits to highest priority lender first */
+ for (lender = AC_COUNT; lender >= 0; lender--) {
+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) {
+ wlfc->FIFO_credit[lender]++;
+ wlfc->credits_borrowed[fifo_id][lender]--;
+ credit_returned = 1;
+ break;
+ }
+ }
+
+ if (!credit_returned) {
+ wlfc->FIFO_credit[fifo_id]++;
+ }
+ }
+ }
+ else {
+ /*
+ if this packet did not count against FIFO credit, it must have
+ taken a requested_credit from the destination entry (for pspoll etc.)
+ */
+ if (!entry) {
+
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+ }
+ if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf)))
+ entry->requested_credit++;
+#ifdef PROP_TXSTATUS_DEBUG
+ entry->dstncredit_acks++;
+#endif
+ }
+ if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) ||
+ (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) {
+
+ ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf);
+ if (ret != BCME_OK) {
+ /* delay q is full, drop this packet */
+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status),
+ &pktbuf, 1);
+
+ /* indicate failure and free the packet */
+ dhd_txcomplete(dhd, pktbuf, FALSE);
+ entry->transit_count--;
+ /* This packet is transmitted Successfully by
+ * dongle even after first suppress.
+ */
+ if (entry->suppressed) {
+ entry->suppr_transit_count--;
+ }
+ PKTFREE(wlfc->osh, pktbuf, TRUE);
+ } else {
+ /* Mark suppressed to avoid a double free during wlfc cleanup */
+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status));
+ entry->suppress_count++;
+ }
+ }
+ else {
+ dhd_txcomplete(dhd, pktbuf, TRUE);
+ entry->transit_count--;
+
+ /* This packet is transmitted Successfully by dongle even after first suppress. */
+ if (entry->suppressed) {
+ entry->suppr_transit_count--;
+ }
+ /* free the packet */
+ PKTFREE(wlfc->osh, pktbuf, TRUE);
+ }
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits)
+{
+ int i;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) {
+#ifdef PROP_TXSTATUS_DEBUG
+ wlfc->stats.fifo_credits_back[i] += credits[i];
+#endif
+ /* update FIFO credits */
+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT)
+ {
+ int lender; /* Note that borrower is i */
+
+ /* Return credits to highest priority lender first */
+ for (lender = AC_COUNT; (lender >= 0) && (credits[i] > 0); lender--) {
+ if (wlfc->credits_borrowed[i][lender] > 0) {
+ if (credits[i] >= wlfc->credits_borrowed[i][lender]) {
+ credits[i] -= wlfc->credits_borrowed[i][lender];
+ wlfc->FIFO_credit[lender] +=
+ wlfc->credits_borrowed[i][lender];
+ wlfc->credits_borrowed[i][lender] = 0;
+ }
+ else {
+ wlfc->credits_borrowed[i][lender] -= credits[i];
+ wlfc->FIFO_credit[lender] += credits[i];
+ credits[i] = 0;
+ }
+ }
+ }
+
+ /* If we have more credits left over, these must belong to the AC */
+ if (credits[i] > 0) {
+ wlfc->FIFO_credit[i] += credits[i];
+ }
+ }
+ }
+
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value)
+{
+ uint32 timestamp;
+
+ (void)dhd;
+
+ bcopy(&value[2], &timestamp, sizeof(uint32));
+ AP6210_DEBUG("RXPKT: SEQ: %d, timestamp %d\n", value[1], timestamp);
+ return BCME_OK;
+}
+
+
+static int
+dhd_wlfc_rssi_indicate(dhd_pub_t *dhd, uint8* rssi)
+{
+ (void)dhd;
+ (void)rssi;
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type)
+{
+ int rc;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ uint8 existing_index;
+ uint8 table_index;
+ uint8 ifid;
+ uint8* ea;
+
+ AP6210_DEBUG("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n",
+ __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7],
+ ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"),
+ WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0]);
+
+ table = wlfc->destination_entries.nodes;
+ table_index = WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]);
+ ifid = value[1];
+ ea = &value[2];
+
+ if (type == WLFC_CTL_TYPE_MACDESC_ADD) {
+ existing_index = dhd_wlfc_find_mac_desc_id_from_mac(dhd, &value[2]);
+ if (existing_index == WLFC_MAC_DESC_ID_INVALID) {
+ /* this MAC entry does not exist, create one */
+ if (!table[table_index].occupied) {
+ table[table_index].mac_handle = value[0];
+ rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index],
+ eWLFC_MAC_ENTRY_ACTION_ADD, ifid,
+ wlfc->destination_entries.interfaces[ifid].iftype,
+ ea);
+ }
+ else {
+ /* the space should have been empty, but it's not */
+ wlfc->stats.mac_update_failed++;
+ }
+ }
+ else {
+ /*
+ there is an existing entry, move it to new index
+ if necessary.
+ */
+ if (existing_index != table_index) {
+ /* if we already have an entry, free the old one */
+ table[existing_index].occupied = 0;
+ table[existing_index].state = WLFC_STATE_CLOSE;
+ table[existing_index].requested_credit = 0;
+ table[existing_index].interface_id = 0;
+ /* enable after packets are queued-deqeued properly.
+ pktq_flush(dhd->osh, &table[existing_index].psq, FALSE, NULL, 0);
+ */
+ }
+ }
+ }
+ if (type == WLFC_CTL_TYPE_MACDESC_DEL) {
+ if (table[table_index].occupied) {
+ rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index],
+ eWLFC_MAC_ENTRY_ACTION_DEL, ifid,
+ wlfc->destination_entries.interfaces[ifid].iftype,
+ ea);
+ }
+ else {
+ /* the space should have been occupied, but it's not */
+ wlfc->stats.mac_update_failed++;
+ }
+ }
+ BCM_REFERENCE(rc);
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_psmode_update(dhd_pub_t *dhd, uint8* value, uint8 type)
+{
+ /* Handle PS on/off indication */
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ wlfc_mac_descriptor_t* desc;
+ uint8 mac_handle = value[0];
+ int i;
+
+ table = wlfc->destination_entries.nodes;
+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
+ if (desc->occupied) {
+ /* a fresh PS mode should wipe old ps credits? */
+ desc->requested_credit = 0;
+ if (type == WLFC_CTL_TYPE_MAC_OPEN) {
+ desc->state = WLFC_STATE_OPEN;
+ DHD_WLFC_CTRINC_MAC_OPEN(desc);
+ }
+ else {
+ desc->state = WLFC_STATE_CLOSE;
+ DHD_WLFC_CTRINC_MAC_CLOSE(desc);
+ /*
+ Indicate to firmware if there is any traffic pending.
+ */
+ for (i = AC_BE; i < AC_COUNT; i++) {
+ _dhd_wlfc_traffic_pending_check(wlfc, desc, i);
+ }
+ }
+ }
+ else {
+ wlfc->stats.psmode_update_failed++;
+ }
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type)
+{
+ /* Handle PS on/off indication */
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ uint8 if_id = value[0];
+
+ if (if_id < WLFC_MAX_IFNUM) {
+ table = wlfc->destination_entries.interfaces;
+ if (table[if_id].occupied) {
+ if (type == WLFC_CTL_TYPE_INTERFACE_OPEN) {
+ table[if_id].state = WLFC_STATE_OPEN;
+ /* AP6210_DEBUG("INTERFACE[%d] OPEN\n", if_id); */
+ }
+ else {
+ table[if_id].state = WLFC_STATE_CLOSE;
+ /* AP6210_DEBUG("INTERFACE[%d] CLOSE\n", if_id); */
+ }
+ return BCME_OK;
+ }
+ }
+ wlfc->stats.interface_update_failed++;
+
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_credit_request(dhd_pub_t *dhd, uint8* value)
+{
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ wlfc_mac_descriptor_t* desc;
+ uint8 mac_handle;
+ uint8 credit;
+
+ table = wlfc->destination_entries.nodes;
+ mac_handle = value[1];
+ credit = value[0];
+
+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
+ if (desc->occupied) {
+ desc->requested_credit = credit;
+
+ desc->ac_bitmap = value[2];
+ }
+ else {
+ wlfc->stats.credit_request_failed++;
+ }
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value)
+{
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ wlfc_mac_descriptor_t* desc;
+ uint8 mac_handle;
+ uint8 packet_count;
+
+ table = wlfc->destination_entries.nodes;
+ mac_handle = value[1];
+ packet_count = value[0];
+
+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
+ if (desc->occupied) {
+ desc->requested_packet = packet_count;
+
+ desc->ac_bitmap = value[2];
+ }
+ else {
+ wlfc->stats.packet_request_failed++;
+ }
+ return BCME_OK;
+}
+
+static void
+dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len)
+{
+ if (info_len) {
+ if (info_buf) {
+ bcopy(val, info_buf, len);
+ *info_len = len;
+ }
+ else
+ *info_len = 0;
+ }
+}
+
+static int
+dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len, uchar *reorder_info_buf,
+ uint *reorder_info_len)
+{
+ uint8 type, len;
+ uint8* value;
+ uint8* tmpbuf;
+ uint16 remainder = tlv_hdr_len;
+ uint16 processed = 0;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ tmpbuf = (uint8*)PKTDATA(dhd->osh, pktbuf);
+ if (remainder) {
+ while ((processed < (WLFC_MAX_PENDING_DATALEN * 2)) && (remainder > 0)) {
+ type = tmpbuf[processed];
+ if (type == WLFC_CTL_TYPE_FILLER) {
+ remainder -= 1;
+ processed += 1;
+ continue;
+ }
+
+ len = tmpbuf[processed + 1];
+ value = &tmpbuf[processed + 2];
+
+ if (remainder < (2 + len))
+ break;
+
+ remainder -= 2 + len;
+ processed += 2 + len;
+ if (type == WLFC_CTL_TYPE_TXSTATUS)
+ dhd_wlfc_txstatus_update(dhd, value);
+ if (type == WLFC_CTL_TYPE_COMP_TXSTATUS)
+ dhd_wlfc_compressed_txstatus_update(dhd, value, len);
+
+ else if (type == WLFC_CTL_TYPE_HOST_REORDER_RXPKTS)
+ dhd_wlfc_reorderinfo_indicate(value, len, reorder_info_buf,
+ reorder_info_len);
+ else if (type == WLFC_CTL_TYPE_FIFO_CREDITBACK)
+ dhd_wlfc_fifocreditback_indicate(dhd, value);
+
+ else if (type == WLFC_CTL_TYPE_RSSI)
+ dhd_wlfc_rssi_indicate(dhd, value);
+
+ else if (type == WLFC_CTL_TYPE_MAC_REQUEST_CREDIT)
+ dhd_wlfc_credit_request(dhd, value);
+
+ else if (type == WLFC_CTL_TYPE_MAC_REQUEST_PACKET)
+ dhd_wlfc_packet_request(dhd, value);
+
+ else if ((type == WLFC_CTL_TYPE_MAC_OPEN) ||
+ (type == WLFC_CTL_TYPE_MAC_CLOSE))
+ dhd_wlfc_psmode_update(dhd, value, type);
+
+ else if ((type == WLFC_CTL_TYPE_MACDESC_ADD) ||
+ (type == WLFC_CTL_TYPE_MACDESC_DEL))
+ dhd_wlfc_mac_table_update(dhd, value, type);
+
+ else if (type == WLFC_CTL_TYPE_TRANS_ID)
+ dhd_wlfc_dbg_senum_check(dhd, value);
+
+ else if ((type == WLFC_CTL_TYPE_INTERFACE_OPEN) ||
+ (type == WLFC_CTL_TYPE_INTERFACE_CLOSE)) {
+ dhd_wlfc_interface_update(dhd, value, type);
+ }
+ }
+ if (remainder != 0) {
+ /* trouble..., something is not right */
+ wlfc->stats.tlv_parse_failed++;
+ }
+ }
+ return BCME_OK;
+}
+
+int
+dhd_wlfc_init(dhd_pub_t *dhd)
+{
+ char iovbuf[12]; /* Room for "tlv" + '\0' + parameter */
+ /* enable all signals & indicate host proptxstatus logic is active */
+ uint32 tlv = dhd->wlfc_enabled?
+ WLFC_FLAGS_RSSI_SIGNALS |
+ WLFC_FLAGS_XONXOFF_SIGNALS |
+ WLFC_FLAGS_CREDIT_STATUS_SIGNALS |
+ WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE |
+ WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0;
+ /* WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; */
+
+
+ /*
+ try to enable/disable signaling by sending "tlv" iovar. if that fails,
+ fallback to no flow control? Print a message for now.
+ */
+
+ /* enable proptxtstatus signaling by default */
+ bcm_mkiovar("tlv", (char *)&tlv, 4, iovbuf, sizeof(iovbuf));
+ if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) {
+ AP6210_ERR("dhd_wlfc_init(): failed to enable/disable bdcv2 tlv signaling\n");
+ }
+ else {
+ /*
+ Leaving the message for now, it should be removed after a while; once
+ the tlv situation is stable.
+ */
+ AP6210_DEBUG("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n",
+ dhd->wlfc_enabled?"enabled":"disabled", tlv);
+ }
+ return BCME_OK;
+}
+
+int
+dhd_wlfc_enable(dhd_pub_t *dhd)
+{
+ int i;
+ athost_wl_status_info_t* wlfc;
+
+ AP6210_DEBUG("Enter %s\n", __FUNCTION__);
+
+ if (!dhd->wlfc_enabled || dhd->wlfc_state)
+ return BCME_OK;
+
+ /* allocate space to track txstatus propagated from firmware */
+ dhd->wlfc_state = MALLOC(dhd->osh, sizeof(athost_wl_status_info_t));
+ if (dhd->wlfc_state == NULL)
+ return BCME_NOMEM;
+
+ /* initialize state space */
+ wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
+ memset(wlfc, 0, sizeof(athost_wl_status_info_t));
+
+ /* remember osh & dhdp */
+ wlfc->osh = dhd->osh;
+ wlfc->dhdp = dhd;
+
+ wlfc->hanger =
+ dhd_wlfc_hanger_create(dhd->osh, WLFC_HANGER_MAXITEMS);
+ if (wlfc->hanger == NULL) {
+ MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t));
+ dhd->wlfc_state = NULL;
+ return BCME_NOMEM;
+ }
+
+ /* initialize all interfaces to accept traffic */
+ for (i = 0; i < WLFC_MAX_IFNUM; i++) {
+ wlfc->hostif_flow_state[i] = OFF;
+ }
+
+ /*
+ create the SENDQ containing
+ sub-queues for all AC precedences + 1 for bc/mc traffic
+ */
+ pktq_init(&wlfc->SENDQ, (AC_COUNT + 1), WLFC_SENDQ_LEN);
+
+ wlfc->destination_entries.other.state = WLFC_STATE_OPEN;
+ /* bc/mc FIFO is always open [credit aside], i.e. b[5] */
+ wlfc->destination_entries.other.ac_bitmap = 0x1f;
+ wlfc->destination_entries.other.interface_id = 0;
+
+ wlfc->proptxstatus_mode = WLFC_FCMODE_EXPLICIT_CREDIT;
+
+ wlfc->allow_credit_borrow = TRUE;
+ wlfc->borrow_defer_timestamp = 0;
+
+ return BCME_OK;
+}
+
+/* release all packet resources */
+void
+dhd_wlfc_cleanup(dhd_pub_t *dhd)
+{
+ int i;
+ int total_entries;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ wlfc_hanger_t* h;
+ int prec;
+ void *pkt = NULL;
+ struct pktq *txq = NULL;
+
+ AP6210_DEBUG("Enter %s\n", __FUNCTION__);
+ if (dhd->wlfc_state == NULL)
+ return;
+ /* flush bus->txq */
+ txq = dhd_bus_txq(dhd->bus);
+
+ /* any in the hanger? */
+ h = (wlfc_hanger_t*)wlfc->hanger;
+ total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t);
+ /* search all entries, include nodes as well as interfaces */
+ table = (wlfc_mac_descriptor_t*)&wlfc->destination_entries;
+
+ for (i = 0; i < total_entries; i++) {
+ if (table[i].occupied) {
+ if (table[i].psq.len) {
+ AP6210_DEBUG("%s(): DELAYQ[%d].len = %d\n",
+ __FUNCTION__, i, table[i].psq.len);
+ /* release packets held in DELAYQ */
+ pktq_flush(wlfc->osh, &table[i].psq, TRUE, NULL, 0);
+ }
+ table[i].occupied = 0;
+ }
+ }
+ /* release packets held in SENDQ */
+ if (wlfc->SENDQ.len)
+ pktq_flush(wlfc->osh, &wlfc->SENDQ, TRUE, NULL, 0);
+ for (prec = 0; prec < txq->num_prec; prec++) {
+ pkt = pktq_pdeq(txq, prec);
+ while (pkt) {
+ for (i = 0; i < h->max_items; i++) {
+ if (pkt == h->items[i].pkt) {
+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ PKTFREE(wlfc->osh, h->items[i].pkt, TRUE);
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ h->items[i].pkt = NULL;
+ h->items[i].identifier = 0;
+ } else if (h->items[i].state ==
+ WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) {
+ /* These are already freed from the psq */
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ }
+ break;
+ }
+ }
+ pkt = pktq_pdeq(txq, prec);
+ }
+ }
+ /* flush remained pkt in hanger queue, not in bus->txq */
+ for (i = 0; i < h->max_items; i++) {
+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ PKTFREE(wlfc->osh, h->items[i].pkt, TRUE);
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ } else if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) {
+ /* These are freed from the psq so no need to free again */
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ }
+ }
+
+ return;
+}
+
+void
+dhd_wlfc_deinit(dhd_pub_t *dhd)
+{
+ /* cleanup all psq related resources */
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+
+ AP6210_DEBUG("Enter %s\n", __FUNCTION__);
+
+ dhd_os_wlfc_block(dhd);
+ if (dhd->wlfc_state == NULL) {
+ dhd_os_wlfc_unblock(dhd);
+ return;
+ }
+
+#ifdef PROP_TXSTATUS_DEBUG
+ {
+ int i;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger;
+ for (i = 0; i < h->max_items; i++) {
+ if (h->items[i].state != WLFC_HANGER_ITEM_STATE_FREE) {
+ AP6210_DEBUG("%s() pkt[%d] = 0x%p, FIFO_credit_used:%d\n",
+ __FUNCTION__, i, h->items[i].pkt,
+ DHD_PKTTAG_CREDITCHECK(PKTTAG(h->items[i].pkt)));
+ }
+ }
+ }
+#endif
+ /* delete hanger */
+ dhd_wlfc_hanger_delete(dhd->osh, wlfc->hanger);
+
+ /* free top structure */
+ MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t));
+ dhd->wlfc_state = NULL;
+ dhd_os_wlfc_unblock(dhd);
+
+ return;
+}
+#endif /* PROP_TXSTATUS */
+
+void
+dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+ bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid);
+#ifdef PROP_TXSTATUS
+ dhd_os_wlfc_block(dhdp);
+ if (dhdp->wlfc_state)
+ dhd_wlfc_dump(dhdp, strbuf);
+ dhd_os_wlfc_unblock(dhdp);
+#endif
+}
+
+void
+dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf)
+{
+#ifdef BDC
+ struct bdc_header *h;
+#endif /* BDC */
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+#ifdef BDC
+ /* Push BDC header used to convey priority for buses that don't */
+
+ PKTPUSH(dhd->osh, pktbuf, BDC_HEADER_LEN);
+
+ h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf);
+
+ h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
+ if (PKTSUMNEEDED(pktbuf))
+ h->flags |= BDC_FLAG_SUM_NEEDED;
+
+
+ h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK);
+ h->flags2 = 0;
+ h->dataOffset = 0;
+#endif /* BDC */
+ BDC_SET_IF_IDX(h, ifidx);
+}
+
+int
+dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf, uchar *reorder_buf_info,
+ uint *reorder_info_len)
+{
+#ifdef BDC
+ struct bdc_header *h;
+#endif
+ uint8 data_offset = 0;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+#ifdef BDC
+ if (reorder_info_len)
+ *reorder_info_len = 0;
+ /* Pop BDC header used to convey priority for buses that don't */
+
+ if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) {
+ AP6210_ERR("%s: rx data too short (%d < %d)\n", __FUNCTION__,
+ PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN);
+ return BCME_ERROR;
+ }
+
+ h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf);
+
+#if defined(NDIS630)
+ h->dataOffset = 0;
+#endif
+
+ if (!ifidx) {
+ /* for tx packet, skip the analysis */
+ data_offset = h->dataOffset;
+ PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN);
+ goto exit;
+ }
+
+ if ((*ifidx = BDC_GET_IF_IDX(h)) >= DHD_MAX_IFS) {
+ AP6210_ERR("%s: rx data ifnum out of range (%d)\n",
+ __FUNCTION__, *ifidx);
+ return BCME_ERROR;
+ }
+
+ if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) {
+ AP6210_ERR("%s: non-BDC packet received, flags = 0x%x\n",
+ dhd_ifname(dhd, *ifidx), h->flags);
+ if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) == BDC_PROTO_VER_1)
+ h->dataOffset = 0;
+ else
+ return BCME_ERROR;
+ }
+
+ if (h->flags & BDC_FLAG_SUM_GOOD) {
+ AP6210_DEBUG("%s: BDC packet received with good rx-csum, flags 0x%x\n",
+ dhd_ifname(dhd, *ifidx), h->flags);
+ PKTSETSUMGOOD(pktbuf, TRUE);
+ }
+
+ PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK));
+ data_offset = h->dataOffset;
+ PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN);
+#endif /* BDC */
+
+#if !defined(NDIS630)
+ if (PKTLEN(dhd->osh, pktbuf) < (uint32) (data_offset << 2)) {
+ AP6210_ERR("%s: rx data too short (%d < %d)\n", __FUNCTION__,
+ PKTLEN(dhd->osh, pktbuf), (data_offset * 4));
+ return BCME_ERROR;
+ }
+#endif
+#ifdef PROP_TXSTATUS
+ if (dhd->wlfc_state &&
+ ((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode
+ != WLFC_FCMODE_NONE &&
+ (!DHD_PKTTAG_PKTDIR(PKTTAG(pktbuf)))) {
+ /*
+ - parse txstatus only for packets that came from the firmware
+ */
+ dhd_os_wlfc_block(dhd);
+ dhd_wlfc_parse_header_info(dhd, pktbuf, (data_offset << 2),
+ reorder_buf_info, reorder_info_len);
+ ((athost_wl_status_info_t*)dhd->wlfc_state)->stats.dhd_hdrpulls++;
+ dhd_os_wlfc_unblock(dhd);
+ }
+#endif /* PROP_TXSTATUS */
+
+exit:
+#if !defined(NDIS630)
+ PKTPULL(dhd->osh, pktbuf, (data_offset << 2));
+#endif
+ return 0;
+}
+
+#if defined(PROP_TXSTATUS)
+void
+dhd_wlfc_trigger_pktcommit(dhd_pub_t *dhd)
+{
+ if (dhd->wlfc_state &&
+ (((athost_wl_status_info_t*)dhd->wlfc_state)->proptxstatus_mode
+ != WLFC_FCMODE_NONE)) {
+ dhd_os_wlfc_block(dhd);
+ dhd_wlfc_commit_packets(dhd->wlfc_state, (f_commitpkt_t)dhd_bus_txdata,
+ (void *)dhd->bus);
+ dhd_os_wlfc_unblock(dhd);
+ }
+}
+#endif
+
+int
+dhd_prot_attach(dhd_pub_t *dhd)
+{
+ dhd_prot_t *cdc;
+
+ if (!(cdc = (dhd_prot_t *)DHD_OS_PREALLOC(dhd->osh, DHD_PREALLOC_PROT,
+ sizeof(dhd_prot_t)))) {
+ AP6210_ERR("%s: kmalloc failed\n", __FUNCTION__);
+ goto fail;
+ }
+ memset(cdc, 0, sizeof(dhd_prot_t));
+
+ /* ensure that the msg buf directly follows the cdc msg struct */
+ if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) {
+ AP6210_ERR("dhd_prot_t is not correctly defined\n");
+ goto fail;
+ }
+
+ dhd->prot = cdc;
+#ifdef BDC
+ dhd->hdrlen += BDC_HEADER_LEN;
+#endif
+ dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN;
+ return 0;
+
+fail:
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+ if (cdc != NULL)
+ MFREE(dhd->osh, cdc, sizeof(dhd_prot_t));
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+ return BCME_NOMEM;
+}
+
+/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
+void
+dhd_prot_detach(dhd_pub_t *dhd)
+{
+#ifdef PROP_TXSTATUS
+ dhd_wlfc_deinit(dhd);
+#endif
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+ MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t));
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+ dhd->prot = NULL;
+}
+
+void
+dhd_prot_dstats(dhd_pub_t *dhd)
+{
+ /* No stats from dongle added yet, copy bus stats */
+ dhd->dstats.tx_packets = dhd->tx_packets;
+ dhd->dstats.tx_errors = dhd->tx_errors;
+ dhd->dstats.rx_packets = dhd->rx_packets;
+ dhd->dstats.rx_errors = dhd->rx_errors;
+ dhd->dstats.rx_dropped = dhd->rx_dropped;
+ dhd->dstats.multicast = dhd->rx_multicast;
+ return;
+}
+
+int
+dhd_prot_init(dhd_pub_t *dhd)
+{
+ int ret = 0;
+ wlc_rev_info_t revinfo;
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+
+ /* Get the device rev info */
+ memset(&revinfo, 0, sizeof(revinfo));
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE, 0);
+ if (ret < 0)
+ goto done;
+
+
+#if defined(WL_CFG80211)
+ if (dhd_download_fw_on_driverload)
+#endif /* defined(WL_CFG80211) */
+ ret = dhd_preinit_ioctls(dhd);
+
+#ifdef PROP_TXSTATUS
+ ret = dhd_wlfc_init(dhd);
+#endif
+
+ /* Always assumes wl for now */
+ dhd->iswl = TRUE;
+
+done:
+ return ret;
+}
+
+void
+dhd_prot_stop(dhd_pub_t *dhd)
+{
+ /* Nothing to do for CDC */
+}
+
+
+static void
+dhd_get_hostreorder_pkts(void *osh, struct reorder_info *ptr, void **pkt,
+ uint32 *pkt_count, void **pplast, uint8 start, uint8 end)
+{
+ uint i;
+ void *plast = NULL, *p;
+ uint32 pkt_cnt = 0;
+
+ if (ptr->pend_pkts == 0) {
+ AP6210_DEBUG("%s: no packets in reorder queue \n", __FUNCTION__);
+ *pplast = NULL;
+ *pkt_count = 0;
+ *pkt = NULL;
+ return;
+ }
+ if (start == end)
+ i = ptr->max_idx + 1;
+ else {
+ if (start > end)
+ i = ((ptr->max_idx + 1) - start) + end;
+ else
+ i = end - start;
+ }
+ while (i) {
+ p = (void *)(ptr->p[start]);
+ ptr->p[start] = NULL;
+
+ if (p != NULL) {
+ if (plast == NULL)
+ *pkt = p;
+ else
+ PKTSETNEXT(osh, plast, p);
+
+ plast = p;
+ pkt_cnt++;
+ }
+ i--;
+ if (start++ == ptr->max_idx)
+ start = 0;
+ }
+ *pplast = plast;
+ *pkt_count = (uint32)pkt_cnt;
+}
+
+int
+dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, uint reorder_info_len,
+ void **pkt, uint32 *pkt_count)
+{
+ uint8 flow_id, max_idx, cur_idx, exp_idx;
+ struct reorder_info *ptr;
+ uint8 flags;
+ void *cur_pkt, *plast = NULL;
+ uint32 cnt = 0;
+
+ if (pkt == NULL) {
+ if (pkt_count != NULL)
+ *pkt_count = 0;
+ return 0;
+ }
+
+ flow_id = reorder_info_buf[WLHOST_REORDERDATA_FLOWID_OFFSET];
+ flags = reorder_info_buf[WLHOST_REORDERDATA_FLAGS_OFFSET];
+
+ AP6210_DEBUG("flow_id %d, flags 0x%02x, idx(%d, %d, %d)\n", flow_id, flags,
+ reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET],
+ reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET],
+ reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET]);
+
+ /* validate flags and flow id */
+ if (flags == 0xFF) {
+ AP6210_ERR("%s: invalid flags...so ignore this packet\n", __FUNCTION__);
+ *pkt_count = 1;
+ return 0;
+ }
+
+ cur_pkt = *pkt;
+ *pkt = NULL;
+
+ ptr = dhd->reorder_bufs[flow_id];
+ if (flags & WLHOST_REORDERDATA_DEL_FLOW) {
+ uint32 buf_size = sizeof(struct reorder_info);
+
+ AP6210_DEBUG("%s: Flags indicating to delete a flow id %d\n",
+ __FUNCTION__, flow_id);
+
+ if (ptr == NULL) {
+ AP6210_ERR("%s: received flags to cleanup, but no flow (%d) yet\n",
+ __FUNCTION__, flow_id);
+ *pkt_count = 1;
+ *pkt = cur_pkt;
+ return 0;
+ }
+
+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
+ ptr->exp_idx, ptr->exp_idx);
+ /* set it to the last packet */
+ if (plast) {
+ PKTSETNEXT(dhd->osh, plast, cur_pkt);
+ cnt++;
+ }
+ else {
+ if (cnt != 0) {
+ AP6210_ERR("%s: del flow: something fishy, pending packets %d\n",
+ __FUNCTION__, cnt);
+ }
+ *pkt = cur_pkt;
+ cnt = 1;
+ }
+ buf_size += ((ptr->max_idx + 1) * sizeof(void *));
+ MFREE(dhd->osh, ptr, buf_size);
+ dhd->reorder_bufs[flow_id] = NULL;
+ *pkt_count = cnt;
+ return 0;
+ }
+ /* all the other cases depend on the existance of the reorder struct for that flow id */
+ if (ptr == NULL) {
+ uint32 buf_size_alloc = sizeof(reorder_info_t);
+ max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET];
+
+ buf_size_alloc += ((max_idx + 1) * sizeof(void*));
+ /* allocate space to hold the buffers, index etc */
+
+ AP6210_DEBUG("%s: alloc buffer of size %d size, reorder info id %d, maxidx %d\n",
+ __FUNCTION__, buf_size_alloc, flow_id, max_idx);
+ ptr = (struct reorder_info *)MALLOC(dhd->osh, buf_size_alloc);
+ if (ptr == NULL) {
+ AP6210_ERR("%s: Malloc failed to alloc buffer\n", __FUNCTION__);
+ *pkt_count = 1;
+ return 0;
+ }
+ bzero(ptr, buf_size_alloc);
+ dhd->reorder_bufs[flow_id] = ptr;
+ ptr->p = (void *)(ptr+1);
+ ptr->max_idx = max_idx;
+ }
+ if (flags & WLHOST_REORDERDATA_NEW_HOLE) {
+ AP6210_DEBUG("%s: new hole, so cleanup pending buffers\n", __FUNCTION__);
+ if (ptr->pend_pkts) {
+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
+ ptr->exp_idx, ptr->exp_idx);
+ ptr->pend_pkts = 0;
+ }
+ ptr->cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET];
+ ptr->exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
+ ptr->max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET];
+ ptr->p[ptr->cur_idx] = cur_pkt;
+ ptr->pend_pkts++;
+ *pkt_count = cnt;
+ }
+ else if (flags & WLHOST_REORDERDATA_CURIDX_VALID) {
+ cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET];
+ exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
+
+
+ if ((exp_idx == ptr->exp_idx) && (cur_idx != ptr->exp_idx)) {
+ /* still in the current hole */
+ /* enqueue the current on the buffer chain */
+ if (ptr->p[cur_idx] != NULL) {
+ AP6210_DEBUG("%s: HOLE: ERROR buffer pending..free it\n",
+ __FUNCTION__);
+ PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE);
+ ptr->p[cur_idx] = NULL;
+ }
+ ptr->p[cur_idx] = cur_pkt;
+ ptr->pend_pkts++;
+ ptr->cur_idx = cur_idx;
+ AP6210_DEBUG("%s: fill up a hole..pending packets is %d\n",
+ __FUNCTION__, ptr->pend_pkts);
+ *pkt_count = 0;
+ *pkt = NULL;
+ }
+ else if (ptr->exp_idx == cur_idx) {
+ /* got the right one ..flush from cur to exp and update exp */
+ AP6210_DEBUG("%s: got the right one now, cur_idx is %d\n",
+ __FUNCTION__, cur_idx);
+ if (ptr->p[cur_idx] != NULL) {
+ AP6210_DEBUG("%s: Error buffer pending..free it\n",
+ __FUNCTION__);
+ PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE);
+ ptr->p[cur_idx] = NULL;
+ }
+ ptr->p[cur_idx] = cur_pkt;
+ ptr->pend_pkts++;
+
+ ptr->cur_idx = cur_idx;
+ ptr->exp_idx = exp_idx;
+
+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
+ cur_idx, exp_idx);
+ ptr->pend_pkts -= (uint8)cnt;
+ *pkt_count = cnt;
+ AP6210_DEBUG("%s: freeing up buffers %d, still pending %d\n",
+ __FUNCTION__, cnt, ptr->pend_pkts);
+ }
+ else {
+ uint8 end_idx;
+ bool flush_current = FALSE;
+ /* both cur and exp are moved now .. */
+ AP6210_DEBUG("%s:, flow %d, both moved, cur %d(%d), exp %d(%d)\n",
+ __FUNCTION__, flow_id, ptr->cur_idx, cur_idx,
+ ptr->exp_idx, exp_idx);
+ if (flags & WLHOST_REORDERDATA_FLUSH_ALL)
+ end_idx = ptr->exp_idx;
+ else
+ end_idx = exp_idx;
+
+ /* flush pkts first */
+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
+ ptr->exp_idx, end_idx);
+
+ if (cur_idx == ptr->max_idx) {
+ if (exp_idx == 0)
+ flush_current = TRUE;
+ } else {
+ if (exp_idx == cur_idx + 1)
+ flush_current = TRUE;
+ }
+ if (flush_current) {
+ if (plast)
+ PKTSETNEXT(dhd->osh, plast, cur_pkt);
+ else
+ *pkt = cur_pkt;
+ cnt++;
+ }
+ else {
+ ptr->p[cur_idx] = cur_pkt;
+ ptr->pend_pkts++;
+ }
+ ptr->exp_idx = exp_idx;
+ ptr->cur_idx = cur_idx;
+ *pkt_count = cnt;
+ }
+ }
+ else {
+ uint8 end_idx;
+ /* no real packet but update to exp_seq...that means explicit window move */
+ exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
+
+ AP6210_DEBUG("%s: move the window, cur_idx is %d, exp is %d, new exp is %d\n",
+ __FUNCTION__, ptr->cur_idx, ptr->exp_idx, exp_idx);
+ if (flags & WLHOST_REORDERDATA_FLUSH_ALL)
+ end_idx = ptr->exp_idx;
+ else
+ end_idx = exp_idx;
+
+ dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, ptr->exp_idx, end_idx);
+ ptr->pend_pkts -= (uint8)cnt;
+ if (plast)
+ PKTSETNEXT(dhd->osh, plast, cur_pkt);
+ else
+ *pkt = cur_pkt;
+ cnt++;
+ *pkt_count = cnt;
+ /* set the new expected idx */
+ ptr->exp_idx = exp_idx;
+ }
+ return 0;
+}
diff --git a/drivers/net/wireless/ap6210/dhd_cfg80211.c b/drivers/net/wireless/ap6210/dhd_cfg80211.c
new file mode 100644
index 0000000..8cb440e
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_cfg80211.c
@@ -0,0 +1,680 @@
+/*
+ * Linux cfg80211 driver - Dongle Host Driver (DHD) related
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $
+ */
+
+#include <net/rtnetlink.h>
+
+#include <bcmutils.h>
+#include <wldev_common.h>
+#include <wl_cfg80211.h>
+#include <dhd_cfg80211.h>
+
+#ifdef PKT_FILTER_SUPPORT
+#include <dngl_stats.h>
+#include <dhd.h>
+#endif
+
+extern struct wl_priv *wlcfg_drv_priv;
+
+#ifdef PKT_FILTER_SUPPORT
+extern uint dhd_pkt_filter_enable;
+extern uint dhd_master_mode;
+extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode);
+#endif
+
+static int dhd_dongle_up = FALSE;
+
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhdioctl.h>
+#include <wlioctl.h>
+#include <dhd_cfg80211.h>
+
+#include <ap6210.h>
+
+static s32 wl_dongle_up(struct net_device *ndev, u32 up);
+
+/**
+ * Function implementations
+ */
+
+s32 dhd_cfg80211_init(struct wl_priv *wl)
+{
+ dhd_dongle_up = FALSE;
+ return 0;
+}
+
+s32 dhd_cfg80211_deinit(struct wl_priv *wl)
+{
+ dhd_dongle_up = FALSE;
+ return 0;
+}
+
+s32 dhd_cfg80211_down(struct wl_priv *wl)
+{
+ dhd_dongle_up = FALSE;
+ return 0;
+}
+
+s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val)
+{
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ dhd->op_mode |= val;
+ AP6210_ERR("Set : op_mode=0x%04x\n", dhd->op_mode);
+#ifdef ARP_OFFLOAD_SUPPORT
+ if (dhd->arp_version == 1) {
+ /* IF P2P is enabled, disable arpoe */
+ dhd_arp_offload_set(dhd, 0);
+ dhd_arp_offload_enable(dhd, false);
+ }
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+ return 0;
+}
+
+s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl)
+{
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ dhd->op_mode &= ~(DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE);
+ AP6210_ERR("Clean : op_mode=0x%04x\n", dhd->op_mode);
+
+#ifdef ARP_OFFLOAD_SUPPORT
+ if (dhd->arp_version == 1) {
+ /* IF P2P is disabled, enable arpoe back for STA mode. */
+ dhd_arp_offload_set(dhd, dhd_arp_mode);
+ dhd_arp_offload_enable(dhd, true);
+ }
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+ return 0;
+}
+
+static s32 wl_dongle_up(struct net_device *ndev, u32 up)
+{
+ s32 err = 0;
+
+ err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), true);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_UP error (%d)\n", err);
+ }
+ return err;
+}
+s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock)
+{
+#ifndef DHD_SDALIGN
+#define DHD_SDALIGN 32
+#endif
+ struct net_device *ndev;
+ s32 err = 0;
+
+ AP6210_DEBUG("In\n");
+ if (dhd_dongle_up) {
+ AP6210_ERR("Dongle is already up\n");
+ return err;
+ }
+
+ ndev = wl_to_prmry_ndev(wl);
+
+ if (need_lock)
+ rtnl_lock();
+
+ err = wl_dongle_up(ndev, 0);
+ if (unlikely(err)) {
+ AP6210_ERR("wl_dongle_up failed\n");
+ goto default_conf_out;
+ }
+ dhd_dongle_up = true;
+
+default_conf_out:
+ if (need_lock)
+ rtnl_unlock();
+ return err;
+
+}
+
+
+/* TODO: clean up the BT-Coex code, it still have some legacy ioctl/iovar functions */
+#define COEX_DHCP
+
+#if defined(COEX_DHCP)
+
+/* use New SCO/eSCO smart YG suppression */
+#define BT_DHCP_eSCO_FIX
+/* this flag boost wifi pkt priority to max, caution: -not fair to sco */
+#define BT_DHCP_USE_FLAGS
+/* T1 start SCO/ESCo priority suppression */
+#define BT_DHCP_OPPR_WIN_TIME 2500
+/* T2 turn off SCO/SCO supperesion is (timeout) */
+#define BT_DHCP_FLAG_FORCE_TIME 5500
+
+enum wl_cfg80211_btcoex_status {
+ BT_DHCP_IDLE,
+ BT_DHCP_START,
+ BT_DHCP_OPPR_WIN,
+ BT_DHCP_FLAG_FORCE_TIMEOUT
+};
+
+/*
+ * get named driver variable to uint register value and return error indication
+ * calling example: dev_wlc_intvar_get_reg(dev, "btc_params",66, &reg_value)
+ */
+static int
+dev_wlc_intvar_get_reg(struct net_device *dev, char *name,
+ uint reg, int *retval)
+{
+ union {
+ char buf[WLC_IOCTL_SMLEN];
+ int val;
+ } var;
+ int error;
+
+ bcm_mkiovar(name, (char *)(&reg), sizeof(reg),
+ (char *)(&var), sizeof(var.buf));
+ error = wldev_ioctl(dev, WLC_GET_VAR, (char *)(&var), sizeof(var.buf), false);
+
+ *retval = dtoh32(var.val);
+ return (error);
+}
+
+static int
+dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+ char ioctlbuf_local[1024];
+#else
+ static char ioctlbuf_local[1024];
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */
+
+ bcm_mkiovar(name, buf, len, ioctlbuf_local, sizeof(ioctlbuf_local));
+
+ return (wldev_ioctl(dev, WLC_SET_VAR, ioctlbuf_local, sizeof(ioctlbuf_local), true));
+}
+/*
+get named driver variable to uint register value and return error indication
+calling example: dev_wlc_intvar_set_reg(dev, "btc_params",66, value)
+*/
+static int
+dev_wlc_intvar_set_reg(struct net_device *dev, char *name, char *addr, char * val)
+{
+ char reg_addr[8];
+
+ memset(reg_addr, 0, sizeof(reg_addr));
+ memcpy((char *)&reg_addr[0], (char *)addr, 4);
+ memcpy((char *)&reg_addr[4], (char *)val, 4);
+
+ return (dev_wlc_bufvar_set(dev, name, (char *)&reg_addr[0], sizeof(reg_addr)));
+}
+
+static bool btcoex_is_sco_active(struct net_device *dev)
+{
+ int ioc_res = 0;
+ bool res = FALSE;
+ int sco_id_cnt = 0;
+ int param27;
+ int i;
+
+ for (i = 0; i < 12; i++) {
+
+ ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, &param27);
+
+ AP6210_DEBUG("%s, sample[%d], btc params: 27:%x\n",
+ __FUNCTION__, i, param27);
+
+ if (ioc_res < 0) {
+ AP6210_ERR("%s ioc read btc params error\n", __FUNCTION__);
+ break;
+ }
+
+ if ((param27 & 0x6) == 2) { /* count both sco & esco */
+ sco_id_cnt++;
+ }
+
+ if (sco_id_cnt > 2) {
+ AP6210_DEBUG("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n",
+ __FUNCTION__, sco_id_cnt, i);
+ res = TRUE;
+ break;
+ }
+
+ msleep(5);
+ }
+
+ return res;
+}
+
+#if defined(BT_DHCP_eSCO_FIX)
+/* Enhanced BT COEX settings for eSCO compatibility during DHCP window */
+static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
+{
+ static bool saved_status = FALSE;
+
+ char buf_reg50va_dhcp_on[8] =
+ { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 };
+ char buf_reg51va_dhcp_on[8] =
+ { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+ char buf_reg64va_dhcp_on[8] =
+ { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+ char buf_reg65va_dhcp_on[8] =
+ { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+ char buf_reg71va_dhcp_on[8] =
+ { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+ uint32 regaddr;
+ static uint32 saved_reg50;
+ static uint32 saved_reg51;
+ static uint32 saved_reg64;
+ static uint32 saved_reg65;
+ static uint32 saved_reg71;
+
+ if (trump_sco) {
+ /* this should reduce eSCO agressive retransmit
+ * w/o breaking it
+ */
+
+ /* 1st save current */
+ AP6210_DEBUG("Do new SCO/eSCO coex algo {save &"
+ "override}\n");
+ if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50, &saved_reg50)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 51, &saved_reg51)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 64, &saved_reg64)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 65, &saved_reg65)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 71, &saved_reg71))) {
+ saved_status = TRUE;
+ AP6210_DEBUG("%s saved bt_params[50,51,64,65,71]:"
+ "0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ __FUNCTION__, saved_reg50, saved_reg51,
+ saved_reg64, saved_reg65, saved_reg71);
+ } else {
+ AP6210_ERR(":%s: save btc_params failed\n",
+ __FUNCTION__);
+ saved_status = FALSE;
+ return -1;
+ }
+
+ AP6210_DEBUG("override with [50,51,64,65,71]:"
+ "0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ *(u32 *)(buf_reg50va_dhcp_on+4),
+ *(u32 *)(buf_reg51va_dhcp_on+4),
+ *(u32 *)(buf_reg64va_dhcp_on+4),
+ *(u32 *)(buf_reg65va_dhcp_on+4),
+ *(u32 *)(buf_reg71va_dhcp_on+4));
+
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg50va_dhcp_on[0], 8);
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg51va_dhcp_on[0], 8);
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg64va_dhcp_on[0], 8);
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg65va_dhcp_on[0], 8);
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg71va_dhcp_on[0], 8);
+
+ saved_status = TRUE;
+ } else if (saved_status) {
+ /* restore previously saved bt params */
+ AP6210_DEBUG("Do new SCO/eSCO coex algo {save &"
+ "override}\n");
+
+ regaddr = 50;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)&regaddr, (char *)&saved_reg50);
+ regaddr = 51;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)&regaddr, (char *)&saved_reg51);
+ regaddr = 64;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)&regaddr, (char *)&saved_reg64);
+ regaddr = 65;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)&regaddr, (char *)&saved_reg65);
+ regaddr = 71;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)&regaddr, (char *)&saved_reg71);
+
+ AP6210_DEBUG("restore bt_params[50,51,64,65,71]:"
+ "0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ saved_reg50, saved_reg51, saved_reg64,
+ saved_reg65, saved_reg71);
+
+ saved_status = FALSE;
+ } else {
+ AP6210_ERR(":%s att to restore not saved BTCOEX params\n",
+ __FUNCTION__);
+ return -1;
+ }
+ return 0;
+}
+#endif /* BT_DHCP_eSCO_FIX */
+
+static void
+wl_cfg80211_bt_setflag(struct net_device *dev, bool set)
+{
+#if defined(BT_DHCP_USE_FLAGS)
+ char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 };
+ char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
+#endif
+
+
+#if defined(BT_DHCP_eSCO_FIX)
+ /* set = 1, save & turn on 0 - off & restore prev settings */
+ set_btc_esco_params(dev, set);
+#endif
+
+#if defined(BT_DHCP_USE_FLAGS)
+ AP6210_DEBUG("WI-FI priority boost via bt flags, set:%d\n", set);
+ if (set == TRUE)
+ /* Forcing bt_flag7 */
+ dev_wlc_bufvar_set(dev, "btc_flags",
+ (char *)&buf_flag7_dhcp_on[0],
+ sizeof(buf_flag7_dhcp_on));
+ else
+ /* Restoring default bt flag7 */
+ dev_wlc_bufvar_set(dev, "btc_flags",
+ (char *)&buf_flag7_default[0],
+ sizeof(buf_flag7_default));
+#endif
+}
+
+static void wl_cfg80211_bt_timerfunc(ulong data)
+{
+ struct btcoex_info *bt_local = (struct btcoex_info *)data;
+ AP6210_DEBUG("%s\n", __FUNCTION__);
+ bt_local->timer_on = 0;
+ schedule_work(&bt_local->work);
+}
+
+static void wl_cfg80211_bt_handler(struct work_struct *work)
+{
+ struct btcoex_info *btcx_inf;
+
+ btcx_inf = container_of(work, struct btcoex_info, work);
+
+ if (btcx_inf->timer_on) {
+ btcx_inf->timer_on = 0;
+ del_timer_sync(&btcx_inf->timer);
+ }
+
+ switch (btcx_inf->bt_state) {
+ case BT_DHCP_START:
+ /* DHCP started
+ * provide OPPORTUNITY window to get DHCP address
+ */
+ AP6210_DEBUG("%s bt_dhcp stm: started \n",
+ __FUNCTION__);
+ btcx_inf->bt_state = BT_DHCP_OPPR_WIN;
+ mod_timer(&btcx_inf->timer,
+ jiffies + msecs_to_jiffies(BT_DHCP_OPPR_WIN_TIME));
+ btcx_inf->timer_on = 1;
+ break;
+
+ case BT_DHCP_OPPR_WIN:
+ if (btcx_inf->dhcp_done) {
+ AP6210_DEBUG("%s DHCP Done before T1 expiration\n",
+ __FUNCTION__);
+ goto btc_coex_idle;
+ }
+
+ /* DHCP is not over yet, start lowering BT priority
+ * enforce btc_params + flags if necessary
+ */
+ AP6210_DEBUG("%s DHCP T1:%d expired\n", __FUNCTION__,
+ BT_DHCP_OPPR_WIN_TIME);
+ if (btcx_inf->dev)
+ wl_cfg80211_bt_setflag(btcx_inf->dev, TRUE);
+ btcx_inf->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT;
+ mod_timer(&btcx_inf->timer,
+ jiffies + msecs_to_jiffies(BT_DHCP_FLAG_FORCE_TIME));
+ btcx_inf->timer_on = 1;
+ break;
+
+ case BT_DHCP_FLAG_FORCE_TIMEOUT:
+ if (btcx_inf->dhcp_done) {
+ AP6210_DEBUG("%s DHCP Done before T2 expiration\n",
+ __FUNCTION__);
+ } else {
+ /* Noo dhcp during T1+T2, restore BT priority */
+ AP6210_DEBUG("%s DHCP wait interval T2:%d"
+ "msec expired\n", __FUNCTION__,
+ BT_DHCP_FLAG_FORCE_TIME);
+ }
+
+ /* Restoring default bt priority */
+ if (btcx_inf->dev)
+ wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE);
+btc_coex_idle:
+ btcx_inf->bt_state = BT_DHCP_IDLE;
+ btcx_inf->timer_on = 0;
+ break;
+
+ default:
+ AP6210_ERR("%s error g_status=%d !!!\n", __FUNCTION__,
+ btcx_inf->bt_state);
+ if (btcx_inf->dev)
+ wl_cfg80211_bt_setflag(btcx_inf->dev, FALSE);
+ btcx_inf->bt_state = BT_DHCP_IDLE;
+ btcx_inf->timer_on = 0;
+ break;
+ }
+
+ net_os_wake_unlock(btcx_inf->dev);
+}
+
+int wl_cfg80211_btcoex_init(struct wl_priv *wl)
+{
+ struct btcoex_info *btco_inf = NULL;
+
+ btco_inf = kmalloc(sizeof(struct btcoex_info), GFP_KERNEL);
+ if (!btco_inf)
+ return -ENOMEM;
+
+ btco_inf->bt_state = BT_DHCP_IDLE;
+ btco_inf->ts_dhcp_start = 0;
+ btco_inf->ts_dhcp_ok = 0;
+ /* Set up timer for BT */
+ btco_inf->timer_ms = 10;
+ init_timer(&btco_inf->timer);
+ btco_inf->timer.data = (ulong)btco_inf;
+ btco_inf->timer.function = wl_cfg80211_bt_timerfunc;
+
+ btco_inf->dev = wl->wdev->netdev;
+
+ INIT_WORK(&btco_inf->work, wl_cfg80211_bt_handler);
+
+ wl->btcoex_info = btco_inf;
+ return 0;
+}
+
+void wl_cfg80211_btcoex_deinit(struct wl_priv *wl)
+{
+ if (!wl->btcoex_info)
+ return;
+
+ if (wl->btcoex_info->timer_on) {
+ wl->btcoex_info->timer_on = 0;
+ del_timer_sync(&wl->btcoex_info->timer);
+ }
+
+ cancel_work_sync(&wl->btcoex_info->work);
+
+ kfree(wl->btcoex_info);
+ wl->btcoex_info = NULL;
+}
+#endif
+
+int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
+{
+
+ struct wl_priv *wl = wlcfg_drv_priv;
+ char powermode_val = 0;
+ char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 };
+ char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 };
+ char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 };
+
+ uint32 regaddr;
+ static uint32 saved_reg66;
+ static uint32 saved_reg41;
+ static uint32 saved_reg68;
+ static bool saved_status = FALSE;
+
+#ifdef COEX_DHCP
+ char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
+ struct btcoex_info *btco_inf = wl->btcoex_info;
+#endif /* COEX_DHCP */
+
+#ifdef PKT_FILTER_SUPPORT
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+#endif
+
+ /* Figure out powermode 1 or o command */
+ strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1);
+
+ if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
+ AP6210_DEBUG("%s: DHCP session starts\n", __FUNCTION__);
+
+#if defined(DHCP_SCAN_SUPPRESS)
+ /* Suppress scan during the DHCP */
+ wl_cfg80211_scan_suppress(dev, 1);
+#endif /* OEM_ANDROID */
+
+#ifdef PKT_FILTER_SUPPORT
+ dhd->dhcp_in_progress = 1;
+
+ if (dhd->early_suspended) {
+ AP6210_DEBUG("DHCP in progressing , disable packet filter!!!\n");
+ dhd_enable_packet_filter(0, dhd);
+ }
+#endif
+
+ /* Retrieve and saved orig regs value */
+ if ((saved_status == FALSE) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) &&
+ (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) {
+ saved_status = TRUE;
+ AP6210_DEBUG("Saved 0x%x 0x%x 0x%x\n",
+ saved_reg66, saved_reg41, saved_reg68);
+
+ /* Disable PM mode during dhpc session */
+
+ /* Disable PM mode during dhpc session */
+#ifdef COEX_DHCP
+ /* Start BT timer only for SCO connection */
+ if (btcoex_is_sco_active(dev)) {
+ /* btc_params 66 */
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg66va_dhcp_on[0],
+ sizeof(buf_reg66va_dhcp_on));
+ /* btc_params 41 0x33 */
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg41va_dhcp_on[0],
+ sizeof(buf_reg41va_dhcp_on));
+ /* btc_params 68 0x190 */
+ dev_wlc_bufvar_set(dev, "btc_params",
+ (char *)&buf_reg68va_dhcp_on[0],
+ sizeof(buf_reg68va_dhcp_on));
+ saved_status = TRUE;
+
+ btco_inf->bt_state = BT_DHCP_START;
+ btco_inf->timer_on = 1;
+ mod_timer(&btco_inf->timer, btco_inf->timer.expires);
+ AP6210_DEBUG("%s enable BT DHCP Timer\n",
+ __FUNCTION__);
+ }
+#endif /* COEX_DHCP */
+ }
+ else if (saved_status == TRUE) {
+ AP6210_ERR("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__);
+ }
+ }
+ else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) {
+
+
+#ifdef PKT_FILTER_SUPPORT
+ dhd->dhcp_in_progress = 0;
+ AP6210_DEBUG("%s: DHCP is complete \n", __FUNCTION__);
+
+#if defined(DHCP_SCAN_SUPPRESS)
+ /* Since DHCP is complete, enable the scan back */
+ wl_cfg80211_scan_suppress(dev, 0);
+#endif /* OEM_ANDROID */
+
+ /* Enable packet filtering */
+ if (dhd->early_suspended) {
+ AP6210_DEBUG("DHCP is complete , enable packet filter!!!\n");
+ dhd_enable_packet_filter(1, dhd);
+ }
+#endif /* PKT_FILTER_SUPPORT */
+
+ /* Restoring PM mode */
+
+#ifdef COEX_DHCP
+ /* Stop any bt timer because DHCP session is done */
+ AP6210_DEBUG("%s disable BT DHCP Timer\n", __FUNCTION__);
+ if (btco_inf->timer_on) {
+ btco_inf->timer_on = 0;
+ del_timer_sync(&btco_inf->timer);
+
+ if (btco_inf->bt_state != BT_DHCP_IDLE) {
+ /* need to restore original btc flags & extra btc params */
+ AP6210_DEBUG("%s bt->bt_state:%d\n",
+ __FUNCTION__, btco_inf->bt_state);
+ /* wake up btcoex thread to restore btlags+params */
+ schedule_work(&btco_inf->work);
+ }
+ }
+
+ /* Restoring btc_flag paramter anyway */
+ if (saved_status == TRUE)
+ dev_wlc_bufvar_set(dev, "btc_flags",
+ (char *)&buf_flag7_default[0], sizeof(buf_flag7_default));
+#endif /* COEX_DHCP */
+
+ /* Restore original values */
+ if (saved_status == TRUE) {
+ regaddr = 66;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)&regaddr, (char *)&saved_reg66);
+ regaddr = 41;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)&regaddr, (char *)&saved_reg41);
+ regaddr = 68;
+ dev_wlc_intvar_set_reg(dev, "btc_params",
+ (char *)&regaddr, (char *)&saved_reg68);
+
+ AP6210_DEBUG("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n",
+ saved_reg66, saved_reg41, saved_reg68);
+ }
+ saved_status = FALSE;
+
+ }
+ else {
+ AP6210_ERR("%s Unkwown yet power setting, ignored\n",
+ __FUNCTION__);
+ }
+
+ snprintf(command, 3, "OK");
+
+ return (strlen("OK"));
+}
diff --git a/drivers/net/wireless/ap6210/dhd_cfg80211.h b/drivers/net/wireless/ap6210/dhd_cfg80211.h
new file mode 100644
index 0000000..922d6ed
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_cfg80211.h
@@ -0,0 +1,44 @@
+/*
+ * Linux cfg80211 driver - Dongle Host Driver (DHD) related
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $
+ */
+
+
+#ifndef __DHD_CFG80211__
+#define __DHD_CFG80211__
+
+#include <wl_cfg80211.h>
+#include <wl_cfgp2p.h>
+
+s32 dhd_cfg80211_init(struct wl_priv *wl);
+s32 dhd_cfg80211_deinit(struct wl_priv *wl);
+s32 dhd_cfg80211_down(struct wl_priv *wl);
+s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val);
+s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl);
+s32 dhd_config_dongle(struct wl_priv *wl, bool need_lock);
+
+int wl_cfg80211_btcoex_init(struct wl_priv *wl);
+void wl_cfg80211_btcoex_deinit(struct wl_priv *wl);
+
+#endif /* __DHD_CFG80211__ */
diff --git a/drivers/net/wireless/ap6210/dhd_common.c b/drivers/net/wireless/ap6210/dhd_common.c
new file mode 100644
index 0000000..96c021f
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_common.c
@@ -0,0 +1,2255 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), common DHD core.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_common.c 373873 2012-12-10 20:45:58Z $
+ */
+#include <typedefs.h>
+#include <osl.h>
+
+#include <epivers.h>
+#include <bcmutils.h>
+
+#include <bcmendian.h>
+#include <dngl_stats.h>
+#include <wlioctl.h>
+#include <dhd.h>
+
+#include <proto/bcmevent.h>
+
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <dhd_dbg.h>
+#include <msgtrace.h>
+
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#endif
+#ifdef WLBTAMP
+#include <proto/bt_amp_hci.h>
+#include <dhd_bta.h>
+#endif
+#ifdef SET_RANDOM_MAC_SOFTAP
+#include <linux/random.h>
+#include <linux/jiffies.h>
+#endif
+
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+#include <ap6210_gpio.h>
+#include <ap6210.h>
+
+#ifdef WLMEDIA_HTSF
+extern void htsf_update(struct dhd_info *dhd, void *data);
+#endif
+int dhd_msg_level = DHD_ERROR_VAL;
+
+
+#include <wl_iw.h>
+
+char fw_path[MOD_PARAM_PATHLEN];
+char nv_path[MOD_PARAM_PATHLEN];
+
+#ifdef SOFTAP
+char fw_path2[MOD_PARAM_PATHLEN];
+extern bool softap_enabled;
+#endif
+
+/* Last connection success/failure status */
+uint32 dhd_conn_event;
+uint32 dhd_conn_status;
+uint32 dhd_conn_reason;
+
+extern int dhd_iscan_request(void * dhdp, uint16 action);
+extern void dhd_ind_scan_confirm(void *h, bool status);
+extern int dhd_iscan_in_progress(void *h);
+void dhd_iscan_lock(void);
+void dhd_iscan_unlock(void);
+extern int dhd_change_mtu(dhd_pub_t *dhd, int new_mtu, int ifidx);
+#if !defined(AP) && defined(WLP2P)
+extern int dhd_get_concurrent_capabilites(dhd_pub_t *dhd);
+#endif
+bool ap_cfg_running = FALSE;
+bool ap_fw_loaded = FALSE;
+
+
+#ifdef DHD_DEBUG
+const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on "
+ __DATE__ " at " __TIME__;
+#else
+const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR;
+#endif
+
+void dhd_set_timer(void *bus, uint wdtick);
+
+/* IOVar table */
+enum {
+ IOV_VERSION = 1,
+ IOV_WLMSGLEVEL,
+ IOV_MSGLEVEL,
+ IOV_BCMERRORSTR,
+ IOV_BCMERROR,
+ IOV_WDTICK,
+ IOV_DUMP,
+ IOV_CLEARCOUNTS,
+ IOV_LOGDUMP,
+ IOV_LOGCAL,
+ IOV_LOGSTAMP,
+ IOV_GPIOOB,
+ IOV_IOCTLTIMEOUT,
+#ifdef WLBTAMP
+ IOV_HCI_CMD, /* HCI command */
+ IOV_HCI_ACL_DATA, /* HCI data packet */
+#endif
+#if defined(DHD_DEBUG)
+ IOV_CONS,
+ IOV_DCONSOLE_POLL,
+#endif /* defined(DHD_DEBUG) */
+#ifdef PROP_TXSTATUS
+ IOV_PROPTXSTATUS_ENABLE,
+ IOV_PROPTXSTATUS_MODE,
+#endif
+ IOV_BUS_TYPE,
+#ifdef WLMEDIA_HTSF
+ IOV_WLPKTDLYSTAT_SZ,
+#endif
+ IOV_CHANGEMTU,
+ IOV_HOSTREORDER_FLOWS,
+ IOV_LAST
+};
+
+const bcm_iovar_t dhd_iovars[] = {
+ {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version) },
+ {"wlmsglevel", IOV_WLMSGLEVEL, 0, IOVT_UINT32, 0 },
+#ifdef DHD_DEBUG
+ {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 },
+#endif /* DHD_DEBUG */
+ {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN },
+ {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0 },
+ {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0 },
+ {"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN },
+#ifdef DHD_DEBUG
+ {"cons", IOV_CONS, 0, IOVT_BUFFER, 0 },
+ {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0 },
+#endif
+ {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0 },
+ {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0 },
+ {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0 },
+#ifdef WLBTAMP
+ {"HCI_cmd", IOV_HCI_CMD, 0, IOVT_BUFFER, 0},
+ {"HCI_ACL_data", IOV_HCI_ACL_DATA, 0, IOVT_BUFFER, 0},
+#endif
+#ifdef PROP_TXSTATUS
+ {"proptx", IOV_PROPTXSTATUS_ENABLE, 0, IOVT_UINT32, 0 },
+ /*
+ set the proptxtstatus operation mode:
+ 0 - Do not do any proptxtstatus flow control
+ 1 - Use implied credit from a packet status
+ 2 - Use explicit credit
+ */
+ {"ptxmode", IOV_PROPTXSTATUS_MODE, 0, IOVT_UINT32, 0 },
+#endif
+ {"bustype", IOV_BUS_TYPE, 0, IOVT_UINT32, 0},
+#ifdef WLMEDIA_HTSF
+ {"pktdlystatsz", IOV_WLPKTDLYSTAT_SZ, 0, IOVT_UINT8, 0 },
+#endif
+ {"changemtu", IOV_CHANGEMTU, 0, IOVT_UINT32, 0 },
+ {"host_reorder_flows", IOV_HOSTREORDER_FLOWS, 0, IOVT_BUFFER,
+ (WLHOST_REORDERDATA_MAXFLOWS + 1) },
+ {NULL, 0, 0, 0, 0 }
+};
+
+void
+dhd_common_init(osl_t *osh)
+{
+ int select_type = 0;
+ //aw checkout which wifi had select
+ select_type = ap6210_gpio_wifi_get_mod_type();
+
+#ifdef CONFIG_AP6210_FW_PATH
+ //select bcm40181/ap6181/ap6210
+ if (select_type == 1 || select_type == 7 || select_type == 9) {
+ bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40181a2.bin", MOD_PARAM_PATHLEN-1);
+ }
+ //select bcm40183
+ if (select_type == 2) {
+ bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40183b2.bin", MOD_PARAM_PATHLEN-1);
+ }
+ //select ap6330
+ if (select_type == 8) {
+ bcm_strncpy_s(fw_path, sizeof(fw_path), "/lib/firmware/ap6210/fw_bcm40183b2_ag.bin", MOD_PARAM_PATHLEN-1);
+ }
+
+#else /* CONFIG_AP6210_FW_PATH */
+ fw_path[0] = '\0';
+#endif /* CONFIG_AP6210_FW_PATH */
+#ifdef CONFIG_AP6210_NVRAM_PATH
+ //select bcm40181
+ if (select_type == 1) {
+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_bcm40181.txt", MOD_PARAM_PATHLEN-1);
+ }
+ //select bcm40183
+ if (select_type == 2) {
+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_bcm40183.txt", MOD_PARAM_PATHLEN-1);
+ }
+ //select ap6210
+ if (select_type == 7) {
+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6210.txt", MOD_PARAM_PATHLEN-1);
+ }
+
+ //select ap6330
+ if (select_type == 8) {
+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6330.txt", MOD_PARAM_PATHLEN-1);
+ }
+ //select ap6181
+ if (select_type == 9) {
+ bcm_strncpy_s(nv_path, sizeof(nv_path), "/lib/firmware/ap6210/nvram_ap6181.txt", MOD_PARAM_PATHLEN-1);
+ }
+#else /* CONFIG_AP6210_NVRAM_PATH */
+ nv_path[0] = '\0';
+#endif /* CONFIG_AP6210_NVRAM_PATH */
+#ifdef SOFTAP
+ fw_path2[0] = '\0';
+#endif
+}
+
+static int
+dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen)
+{
+ char eabuf[ETHER_ADDR_STR_LEN];
+
+ struct bcmstrbuf b;
+ struct bcmstrbuf *strbuf = &b;
+
+ bcm_binit(strbuf, buf, buflen);
+
+ /* Base DHD info */
+ bcm_bprintf(strbuf, "%s\n", dhd_version);
+ bcm_bprintf(strbuf, "\n");
+ bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n",
+ dhdp->up, dhdp->txoff, dhdp->busstate);
+ bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n",
+ dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz);
+ bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %s\n",
+ dhdp->iswl, dhdp->drv_version, bcm_ether_ntoa(&dhdp->mac, eabuf));
+ bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror, dhdp->tickcnt);
+
+ bcm_bprintf(strbuf, "dongle stats:\n");
+ bcm_bprintf(strbuf, "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n",
+ dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes,
+ dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped);
+ bcm_bprintf(strbuf, "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n",
+ dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes,
+ dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped);
+ bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast);
+
+ bcm_bprintf(strbuf, "bus stats:\n");
+ bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n",
+ dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors);
+ bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n",
+ dhdp->tx_ctlpkts, dhdp->tx_ctlerrs);
+ bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld \n",
+ dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors);
+ bcm_bprintf(strbuf, "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld\n",
+ dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped);
+ bcm_bprintf(strbuf, "rx_readahead_cnt %ld tx_realloc %ld\n",
+ dhdp->rx_readahead_cnt, dhdp->tx_realloc);
+ bcm_bprintf(strbuf, "\n");
+
+ /* Add any prot info */
+ dhd_prot_dump(dhdp, strbuf);
+ bcm_bprintf(strbuf, "\n");
+
+ /* Add any bus info */
+ dhd_bus_dump(dhdp, strbuf);
+
+ return (!strbuf->size ? BCME_BUFTOOSHORT : 0);
+}
+
+int
+dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, int ifindex)
+{
+ wl_ioctl_t ioc;
+
+ ioc.cmd = cmd;
+ ioc.buf = arg;
+ ioc.len = len;
+ ioc.set = set;
+
+ return dhd_wl_ioctl(dhd_pub, ifindex, &ioc, arg, len);
+}
+
+
+int
+dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len)
+{
+ int ret;
+
+ dhd_os_proto_block(dhd_pub);
+
+ ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len);
+ if ((ret) && (dhd_pub->up))
+ /* Send hang event only if dhd_open() was success */
+ dhd_os_check_hang(dhd_pub, ifindex, ret);
+
+ dhd_os_proto_unblock(dhd_pub);
+
+ return ret;
+}
+
+static int
+dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const char *name,
+ void *params, int plen, void *arg, int len, int val_size)
+{
+ int bcmerror = 0;
+ int32 int_val = 0;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+ AP6210_DEBUG("%s: actionid = %d; name %s\n", __FUNCTION__, actionid, name);
+
+ if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0)
+ goto exit;
+
+ if (plen >= (int)sizeof(int_val))
+ bcopy(params, &int_val, sizeof(int_val));
+
+ switch (actionid) {
+ case IOV_GVAL(IOV_VERSION):
+ /* Need to have checked buffer length */
+ bcm_strncpy_s((char*)arg, len, dhd_version, len);
+ break;
+
+ case IOV_GVAL(IOV_WLMSGLEVEL):
+ //AP6210_DEBUG("android_msg_level=0x%x\n", android_msg_level);
+#if defined(CONFIG_WIRELESS_EXT)
+ int_val = (int32)iw_msg_level;
+ bcopy(&int_val, arg, val_size);
+ AP6210_DEBUG("iw_msg_level=0x%x\n", iw_msg_level);
+#endif
+#ifdef WL_CFG80211
+ int_val = (int32)wl_dbg_level;
+ bcopy(&int_val, arg, val_size);
+ AP6210_DEBUG("cfg_msg_level=0x%x\n", wl_dbg_level);
+#endif
+ break;
+
+ case IOV_SVAL(IOV_WLMSGLEVEL):
+#if defined(CONFIG_WIRELESS_EXT)
+ if (int_val & DHD_IW_VAL) {
+ iw_msg_level = (uint)(int_val & 0xFFFF);
+ AP6210_DEBUG("iw_msg_level=0x%x\n", iw_msg_level);
+ } else
+#endif
+#ifdef WL_CFG80211
+ if (int_val & DHD_CFG_VAL) {
+ wl_cfg80211_enable_trace((u32)(int_val & 0xFFFF));
+ } else
+#endif
+ {
+ //android_msg_level = (uint)int_val;
+ //AP6210_DEBUG("android_msg_level=0x%x\n", android_msg_level);
+ }
+ break;
+
+ case IOV_GVAL(IOV_MSGLEVEL):
+ int_val = (int32)dhd_msg_level;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_MSGLEVEL):
+ dhd_msg_level = int_val;
+ break;
+
+ case IOV_GVAL(IOV_BCMERRORSTR):
+ bcm_strncpy_s((char *)arg, len, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN);
+ ((char *)arg)[BCME_STRLEN - 1] = 0x00;
+ break;
+
+ case IOV_GVAL(IOV_BCMERROR):
+ int_val = (int32)dhd_pub->bcmerror;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_GVAL(IOV_WDTICK):
+ int_val = (int32)dhd_watchdog_ms;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_WDTICK):
+ if (!dhd_pub->up) {
+ bcmerror = BCME_NOTUP;
+ break;
+ }
+ dhd_os_wd_timer(dhd_pub, (uint)int_val);
+ break;
+
+ case IOV_GVAL(IOV_DUMP):
+ bcmerror = dhd_dump(dhd_pub, arg, len);
+ break;
+
+#ifdef DHD_DEBUG
+ case IOV_GVAL(IOV_DCONSOLE_POLL):
+ int_val = (int32)dhd_console_ms;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_DCONSOLE_POLL):
+ dhd_console_ms = (uint)int_val;
+ break;
+
+ case IOV_SVAL(IOV_CONS):
+ if (len > 0)
+ bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1);
+ break;
+#endif /* DHD_DEBUG */
+
+ case IOV_SVAL(IOV_CLEARCOUNTS):
+ dhd_pub->tx_packets = dhd_pub->rx_packets = 0;
+ dhd_pub->tx_errors = dhd_pub->rx_errors = 0;
+ dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0;
+ dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0;
+ dhd_pub->rx_dropped = 0;
+ dhd_pub->rx_readahead_cnt = 0;
+ dhd_pub->tx_realloc = 0;
+ dhd_pub->wd_dpc_sched = 0;
+ memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats));
+ dhd_bus_clearcounts(dhd_pub);
+#ifdef PROP_TXSTATUS
+ /* clear proptxstatus related counters */
+ if (dhd_pub->wlfc_state) {
+ athost_wl_status_info_t *wlfc =
+ (athost_wl_status_info_t*)dhd_pub->wlfc_state;
+ wlfc_hanger_t* hanger;
+
+ memset(&wlfc->stats, 0, sizeof(athost_wl_stat_counters_t));
+
+ hanger = (wlfc_hanger_t*)wlfc->hanger;
+ hanger->pushed = 0;
+ hanger->popped = 0;
+ hanger->failed_slotfind = 0;
+ hanger->failed_to_pop = 0;
+ hanger->failed_to_push = 0;
+ }
+#endif /* PROP_TXSTATUS */
+ break;
+
+
+ case IOV_GVAL(IOV_IOCTLTIMEOUT): {
+ int_val = (int32)dhd_os_get_ioctl_resp_timeout();
+ bcopy(&int_val, arg, sizeof(int_val));
+ break;
+ }
+
+ case IOV_SVAL(IOV_IOCTLTIMEOUT): {
+ if (int_val <= 0)
+ bcmerror = BCME_BADARG;
+ else
+ dhd_os_set_ioctl_resp_timeout((unsigned int)int_val);
+ break;
+ }
+
+#ifdef WLBTAMP
+ case IOV_SVAL(IOV_HCI_CMD): {
+ amp_hci_cmd_t *cmd = (amp_hci_cmd_t *)arg;
+
+ /* sanity check: command preamble present */
+ if (len < HCI_CMD_PREAMBLE_SIZE)
+ return BCME_BUFTOOSHORT;
+
+ /* sanity check: command parameters are present */
+ if (len < (int)(HCI_CMD_PREAMBLE_SIZE + cmd->plen))
+ return BCME_BUFTOOSHORT;
+
+ dhd_bta_docmd(dhd_pub, cmd, len);
+ break;
+ }
+
+ case IOV_SVAL(IOV_HCI_ACL_DATA): {
+ amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)arg;
+
+ /* sanity check: HCI header present */
+ if (len < HCI_ACL_DATA_PREAMBLE_SIZE)
+ return BCME_BUFTOOSHORT;
+
+ /* sanity check: ACL data is present */
+ if (len < (int)(HCI_ACL_DATA_PREAMBLE_SIZE + ACL_data->dlen))
+ return BCME_BUFTOOSHORT;
+
+ dhd_bta_tx_hcidata(dhd_pub, ACL_data, len);
+ break;
+ }
+#endif /* WLBTAMP */
+
+#ifdef PROP_TXSTATUS
+ case IOV_GVAL(IOV_PROPTXSTATUS_ENABLE):
+ int_val = dhd_pub->wlfc_enabled? 1 : 0;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_PROPTXSTATUS_ENABLE):
+ dhd_pub->wlfc_enabled = int_val? 1 : 0;
+ break;
+
+ case IOV_GVAL(IOV_PROPTXSTATUS_MODE): {
+ athost_wl_status_info_t *wlfc =
+ (athost_wl_status_info_t*)dhd_pub->wlfc_state;
+ int_val = dhd_pub->wlfc_state ? (int32)wlfc->proptxstatus_mode : 0;
+ bcopy(&int_val, arg, val_size);
+ break;
+ }
+
+ case IOV_SVAL(IOV_PROPTXSTATUS_MODE):
+ if (dhd_pub->wlfc_state) {
+ athost_wl_status_info_t *wlfc =
+ (athost_wl_status_info_t*)dhd_pub->wlfc_state;
+ wlfc->proptxstatus_mode = int_val & 0xff;
+ }
+ break;
+#endif /* PROP_TXSTATUS */
+
+ case IOV_GVAL(IOV_BUS_TYPE):
+ /* The dhd application queries the driver to check if its usb or sdio. */
+#ifdef AP6210USB
+ int_val = BUS_TYPE_USB;
+#endif
+ int_val = BUS_TYPE_SDIO;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+
+#ifdef WLMEDIA_HTSF
+ case IOV_GVAL(IOV_WLPKTDLYSTAT_SZ):
+ int_val = dhd_pub->htsfdlystat_sz;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_WLPKTDLYSTAT_SZ):
+ dhd_pub->htsfdlystat_sz = int_val & 0xff;
+ AP6210_DEBUG("Setting tsfdlystat_sz:%d\n", dhd_pub->htsfdlystat_sz);
+ break;
+#endif
+ case IOV_SVAL(IOV_CHANGEMTU):
+ int_val &= 0xffff;
+ bcmerror = dhd_change_mtu(dhd_pub, int_val, 0);
+ break;
+
+ case IOV_GVAL(IOV_HOSTREORDER_FLOWS):
+ {
+ uint i = 0;
+ uint8 *ptr = (uint8 *)arg;
+ uint8 count = 0;
+
+ ptr++;
+ for (i = 0; i < WLHOST_REORDERDATA_MAXFLOWS; i++) {
+ if (dhd_pub->reorder_bufs[i] != NULL) {
+ *ptr = dhd_pub->reorder_bufs[i]->flow_id;
+ ptr++;
+ count++;
+ }
+ }
+ ptr = (uint8 *)arg;
+ *ptr = count;
+ break;
+ }
+
+ default:
+ bcmerror = BCME_UNSUPPORTED;
+ break;
+ }
+
+exit:
+ AP6210_DEBUG("%s: actionid %d, bcmerror %d\n", __FUNCTION__, actionid, bcmerror);
+ return bcmerror;
+}
+
+/* Store the status of a connection attempt for later retrieval by an iovar */
+void
+dhd_store_conn_status(uint32 event, uint32 status, uint32 reason)
+{
+ /* Do not overwrite a WLC_E_PRUNE with a WLC_E_SET_SSID
+ * because an encryption/rsn mismatch results in both events, and
+ * the important information is in the WLC_E_PRUNE.
+ */
+ if (!(event == WLC_E_SET_SSID && status == WLC_E_STATUS_FAIL &&
+ dhd_conn_event == WLC_E_PRUNE)) {
+ dhd_conn_event = event;
+ dhd_conn_status = status;
+ dhd_conn_reason = reason;
+ }
+}
+
+bool
+dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec)
+{
+ void *p;
+ int eprec = -1; /* precedence to evict from */
+ bool discard_oldest;
+
+ /* Fast case, precedence queue is not full and we are also not
+ * exceeding total queue length
+ */
+ if (!pktq_pfull(q, prec) && !pktq_full(q)) {
+ pktq_penq(q, prec, pkt);
+ return TRUE;
+ }
+
+ /* Determine precedence from which to evict packet, if any */
+ if (pktq_pfull(q, prec))
+ eprec = prec;
+ else if (pktq_full(q)) {
+ pktq_peek_tail(q, &eprec);
+ if (eprec > prec || eprec < 0)
+ return FALSE;
+ }
+
+ /* Evict if needed */
+ if (eprec >= 0) {
+ /* Detect queueing to unconfigured precedence */
+ ASSERT(!pktq_pempty(q, eprec));
+ discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec);
+ if (eprec == prec && !discard_oldest)
+ return FALSE; /* refuse newer (incoming) packet */
+ /* Evict packet according to discard policy */
+ p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, eprec);
+ ASSERT(p);
+
+ PKTFREE(dhdp->osh, p, TRUE);
+ }
+
+ /* Enqueue */
+ pktq_penq(q, prec, pkt);
+
+ return TRUE;
+}
+
+static int
+dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name,
+ void *params, int plen, void *arg, int len, bool set)
+{
+ int bcmerror = 0;
+ int val_size;
+ const bcm_iovar_t *vi = NULL;
+ uint32 actionid;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ ASSERT(name);
+ ASSERT(len >= 0);
+
+ /* Get MUST have return space */
+ ASSERT(set || (arg && len));
+
+ /* Set does NOT take qualifiers */
+ ASSERT(!set || (!params && !plen));
+
+ if ((vi = bcm_iovar_lookup(dhd_iovars, name)) == NULL) {
+ bcmerror = BCME_UNSUPPORTED;
+ goto exit;
+ }
+
+ AP6210_DEBUG("%s: %s %s, len %d plen %d\n", __FUNCTION__,
+ name, (set ? "set" : "get"), len, plen);
+
+ /* set up 'params' pointer in case this is a set command so that
+ * the convenience int and bool code can be common to set and get
+ */
+ if (params == NULL) {
+ params = arg;
+ plen = len;
+ }
+
+ if (vi->type == IOVT_VOID)
+ val_size = 0;
+ else if (vi->type == IOVT_BUFFER)
+ val_size = len;
+ else
+ /* all other types are integer sized */
+ val_size = sizeof(int);
+
+ actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+
+ bcmerror = dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len, val_size);
+
+exit:
+ return bcmerror;
+}
+
+int
+dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen)
+{
+ int bcmerror = 0;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (!buf) {
+ return BCME_BADARG;
+ }
+
+ switch (ioc->cmd) {
+ case DHD_GET_MAGIC:
+ if (buflen < sizeof(int))
+ bcmerror = BCME_BUFTOOSHORT;
+ else
+ *(int*)buf = DHD_IOCTL_MAGIC;
+ break;
+
+ case DHD_GET_VERSION:
+ if (buflen < sizeof(int))
+ bcmerror = -BCME_BUFTOOSHORT;
+ else
+ *(int*)buf = DHD_IOCTL_VERSION;
+ break;
+
+ case DHD_GET_VAR:
+ case DHD_SET_VAR: {
+ char *arg;
+ uint arglen;
+
+ /* scan past the name to any arguments */
+ for (arg = buf, arglen = buflen; *arg && arglen; arg++, arglen--)
+ ;
+
+ if (*arg) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ /* account for the NUL terminator */
+ arg++, arglen--;
+
+ /* call with the appropriate arguments */
+ if (ioc->cmd == DHD_GET_VAR)
+ bcmerror = dhd_iovar_op(dhd_pub, buf, arg, arglen,
+ buf, buflen, IOV_GET);
+ else
+ bcmerror = dhd_iovar_op(dhd_pub, buf, NULL, 0, arg, arglen, IOV_SET);
+ if (bcmerror != BCME_UNSUPPORTED)
+ break;
+
+ /* not in generic table, try protocol module */
+ if (ioc->cmd == DHD_GET_VAR)
+ bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg,
+ arglen, buf, buflen, IOV_GET);
+ else
+ bcmerror = dhd_prot_iovar_op(dhd_pub, buf,
+ NULL, 0, arg, arglen, IOV_SET);
+ if (bcmerror != BCME_UNSUPPORTED)
+ break;
+
+ /* if still not found, try bus module */
+ if (ioc->cmd == DHD_GET_VAR) {
+ bcmerror = dhd_bus_iovar_op(dhd_pub, buf,
+ arg, arglen, buf, buflen, IOV_GET);
+ } else {
+ bcmerror = dhd_bus_iovar_op(dhd_pub, buf,
+ NULL, 0, arg, arglen, IOV_SET);
+ }
+
+ break;
+ }
+
+ default:
+ bcmerror = BCME_UNSUPPORTED;
+ }
+
+ return bcmerror;
+}
+
+#ifdef SHOW_EVENTS
+static void
+wl_show_host_event(wl_event_msg_t *event, void *event_data)
+{
+ uint i, status, reason;
+ bool group = FALSE, flush_txq = FALSE, link = FALSE;
+ const char *auth_str;
+ const char *event_name;
+ uchar *buf;
+ char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
+ uint event_type, flags, auth_type, datalen;
+
+ event_type = ntoh32(event->event_type);
+ flags = ntoh16(event->flags);
+ status = ntoh32(event->status);
+ reason = ntoh32(event->reason);
+ BCM_REFERENCE(reason);
+ auth_type = ntoh32(event->auth_type);
+ datalen = ntoh32(event->datalen);
+
+ /* debug dump of event messages */
+ snprintf(eabuf, sizeof(eabuf), "%02x:%02x:%02x:%02x:%02x:%02x",
+ (uchar)event->addr.octet[0]&0xff,
+ (uchar)event->addr.octet[1]&0xff,
+ (uchar)event->addr.octet[2]&0xff,
+ (uchar)event->addr.octet[3]&0xff,
+ (uchar)event->addr.octet[4]&0xff,
+ (uchar)event->addr.octet[5]&0xff);
+
+ event_name = "UNKNOWN";
+ for (i = 0; i < (uint)bcmevent_names_size; i++)
+ if (bcmevent_names[i].event == event_type)
+ event_name = bcmevent_names[i].name;
+
+ if (flags & WLC_EVENT_MSG_LINK)
+ link = TRUE;
+ if (flags & WLC_EVENT_MSG_GROUP)
+ group = TRUE;
+ if (flags & WLC_EVENT_MSG_FLUSHTXQ)
+ flush_txq = TRUE;
+
+ switch (event_type) {
+ case WLC_E_START:
+ case WLC_E_DEAUTH:
+ case WLC_E_DISASSOC:
+ AP6210_DEBUG("MACEVENT: %s, MAC %s\n", event_name, eabuf);
+ break;
+
+ case WLC_E_ASSOC_IND:
+ case WLC_E_REASSOC_IND:
+
+ AP6210_DEBUG("MACEVENT: %s, MAC %s\n", event_name, eabuf);
+ break;
+
+ case WLC_E_ASSOC:
+ case WLC_E_REASSOC:
+ if (status == WLC_E_STATUS_SUCCESS) {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, SUCCESS\n", event_name, eabuf);
+ } else if (status == WLC_E_STATUS_TIMEOUT) {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, TIMEOUT\n", event_name, eabuf);
+ } else if (status == WLC_E_STATUS_FAIL) {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
+ event_name, eabuf, (int)reason);
+ } else {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, unexpected status %d\n",
+ event_name, eabuf, (int)status);
+ }
+ break;
+
+ case WLC_E_DEAUTH_IND:
+ case WLC_E_DISASSOC_IND:
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason);
+ break;
+
+ case WLC_E_AUTH:
+ case WLC_E_AUTH_IND:
+ if (auth_type == DOT11_OPEN_SYSTEM)
+ auth_str = "Open System";
+ else if (auth_type == DOT11_SHARED_KEY)
+ auth_str = "Shared Key";
+ else {
+ snprintf(err_msg, sizeof(err_msg), "AUTH unknown: %d", (int)auth_type);
+ auth_str = err_msg;
+ }
+ if (event_type == WLC_E_AUTH_IND) {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, %s\n", event_name, eabuf, auth_str);
+ } else if (status == WLC_E_STATUS_SUCCESS) {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, %s, SUCCESS\n",
+ event_name, eabuf, auth_str);
+ } else if (status == WLC_E_STATUS_TIMEOUT) {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
+ event_name, eabuf, auth_str);
+ } else if (status == WLC_E_STATUS_FAIL) {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n",
+ event_name, eabuf, auth_str, (int)reason);
+ }
+ BCM_REFERENCE(auth_str);
+
+ break;
+
+ case WLC_E_JOIN:
+ case WLC_E_ROAM:
+ case WLC_E_SET_SSID:
+ if (status == WLC_E_STATUS_SUCCESS) {
+ AP6210_DEBUG("MACEVENT: %s, MAC %s\n", event_name, eabuf);
+ } else if (status == WLC_E_STATUS_FAIL) {
+ AP6210_DEBUG("MACEVENT: %s, failed\n", event_name);
+ } else if (status == WLC_E_STATUS_NO_NETWORKS) {
+ AP6210_DEBUG("MACEVENT: %s, no networks found\n", event_name);
+ } else {
+ AP6210_DEBUG("MACEVENT: %s, unexpected status %d\n",
+ event_name, (int)status);
+ }
+ break;
+
+ case WLC_E_BEACON_RX:
+ if (status == WLC_E_STATUS_SUCCESS) {
+ AP6210_DEBUG("MACEVENT: %s, SUCCESS\n", event_name);
+ } else if (status == WLC_E_STATUS_FAIL) {
+ AP6210_DEBUG("MACEVENT: %s, FAIL\n", event_name);
+ } else {
+ AP6210_DEBUG("MACEVENT: %s, status %d\n", event_name, status);
+ }
+ break;
+
+ case WLC_E_LINK:
+ AP6210_DEBUG("MACEVENT: %s %s\n", event_name, link?"UP":"DOWN");
+ BCM_REFERENCE(link);
+ break;
+
+ case WLC_E_MIC_ERROR:
+ AP6210_DEBUG("MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
+ event_name, eabuf, group, flush_txq);
+ BCM_REFERENCE(group);
+ BCM_REFERENCE(flush_txq);
+ break;
+
+ case WLC_E_ICV_ERROR:
+ case WLC_E_UNICAST_DECODE_ERROR:
+ case WLC_E_MULTICAST_DECODE_ERROR:
+ AP6210_DEBUG("MACEVENT: %s, MAC %s\n",
+ event_name, eabuf);
+ break;
+
+ case WLC_E_TXFAIL:
+ AP6210_DEBUG("MACEVENT: %s, RA %s\n", event_name, eabuf);
+ break;
+
+ case WLC_E_SCAN_COMPLETE:
+ case WLC_E_ASSOC_REQ_IE:
+ case WLC_E_ASSOC_RESP_IE:
+ case WLC_E_PMKID_CACHE:
+ AP6210_DEBUG("MACEVENT: %s\n", event_name);
+ break;
+
+ case WLC_E_PFN_NET_FOUND:
+ case WLC_E_PFN_NET_LOST:
+ case WLC_E_PFN_SCAN_COMPLETE:
+ case WLC_E_PFN_SCAN_NONE:
+ case WLC_E_PFN_SCAN_ALLGONE:
+ AP6210_DEBUG("PNOEVENT: %s\n", event_name);
+ break;
+
+ case WLC_E_PSK_SUP:
+ case WLC_E_PRUNE:
+ AP6210_DEBUG("MACEVENT: %s, status %d, reason %d\n",
+ event_name, (int)status, (int)reason);
+ break;
+
+#ifdef WIFI_ACT_FRAME
+ case WLC_E_ACTION_FRAME:
+ AP6210_DEBUG("MACEVENT: %s Bssid %s\n", event_name, eabuf);
+ break;
+#endif /* WIFI_ACT_FRAME */
+
+ case WLC_E_TRACE: {
+ static uint32 seqnum_prev = 0;
+ msgtrace_hdr_t hdr;
+ uint32 nblost;
+ char *s, *p;
+
+ buf = (uchar *) event_data;
+ memcpy(&hdr, buf, MSGTRACE_HDRLEN);
+
+ if (hdr.version != MSGTRACE_VERSION) {
+ AP6210_DEBUG("MACEVENT: %s [unsupported version --> "
+ "dhd version:%d dongle version:%d]\n",
+ event_name, MSGTRACE_VERSION, hdr.version);
+ /* Reset datalen to avoid display below */
+ datalen = 0;
+ break;
+ }
+
+ /* There are 2 bytes available at the end of data */
+ buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0';
+
+ if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) {
+ AP6210_DEBUG("WLC_E_TRACE: [Discarded traces in dongle -->"
+ "discarded_bytes %d discarded_printf %d]\n",
+ ntoh32(hdr.discarded_bytes), ntoh32(hdr.discarded_printf));
+ }
+
+ nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1;
+ if (nblost > 0) {
+ AP6210_DEBUG("WLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n",
+ ntoh32(hdr.seqnum), nblost);
+ }
+ seqnum_prev = ntoh32(hdr.seqnum);
+
+ /* Display the trace buffer. Advance from \n to \n to avoid display big
+ * printf (issue with Linux printk )
+ */
+ p = (char *)&buf[MSGTRACE_HDRLEN];
+ while ((s = strstr(p, "\n")) != NULL) {
+ *s = '\0';
+ AP6210_DEBUG("%s\n", p);
+ p = s+1;
+ }
+ AP6210_DEBUG("%s\n", p);
+
+ /* Reset datalen to avoid display below */
+ datalen = 0;
+ break;
+ }
+
+
+ case WLC_E_RSSI:
+ AP6210_DEBUG("MACEVENT: %s %d\n", event_name, ntoh32(*((int *)event_data)));
+ break;
+
+ case WLC_E_SERVICE_FOUND:
+ case WLC_E_P2PO_ADD_DEVICE:
+ case WLC_E_P2PO_DEL_DEVICE:
+ AP6210_DEBUG("MACEVENT: %s, MAC: %s\n", event_name, eabuf);
+ break;
+
+ default:
+ AP6210_DEBUG("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n",
+ event_name, event_type, eabuf, (int)status, (int)reason,
+ (int)auth_type);
+ break;
+ }
+
+ /* show any appended data */
+ if (datalen) {
+ buf = (uchar *) event_data;
+ AP6210_DEBUG(" data (%d) : ", datalen);
+ for (i = 0; i < datalen; i++)
+ AP6210_DUMP(" 0x%02x ", *buf++);
+ AP6210_DUMP("\n");
+ }
+}
+#endif /* SHOW_EVENTS */
+
+int
+wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata,
+ wl_event_msg_t *event, void **data_ptr)
+{
+ /* check whether packet is a BRCM event pkt */
+ bcm_event_t *pvt_data = (bcm_event_t *)pktdata;
+ uint8 *event_data;
+ uint32 type, status, datalen;
+ uint16 flags;
+ int evlen;
+
+ if (bcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) {
+ AP6210_ERR("%s: mismatched OUI, bailing\n", __FUNCTION__);
+ return (BCME_ERROR);
+ }
+
+ /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
+ if (ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) {
+ AP6210_ERR("%s: mismatched subtype, bailing\n", __FUNCTION__);
+ return (BCME_ERROR);
+ }
+
+ *data_ptr = &pvt_data[1];
+ event_data = *data_ptr;
+
+ /* memcpy since BRCM event pkt may be unaligned. */
+ memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t));
+
+ type = ntoh32_ua((void *)&event->event_type);
+ flags = ntoh16_ua((void *)&event->flags);
+ status = ntoh32_ua((void *)&event->status);
+ datalen = ntoh32_ua((void *)&event->datalen);
+ evlen = datalen + sizeof(bcm_event_t);
+
+ switch (type) {
+#ifdef PROP_TXSTATUS
+ case WLC_E_FIFO_CREDIT_MAP:
+ dhd_wlfc_event(dhd_pub->info);
+ dhd_wlfc_FIFOcreditmap_event(dhd_pub->info, event_data);
+ AP6210_DEBUG("WLC_E_FIFO_CREDIT_MAP:(AC0,AC1,AC2,AC3),(BC_MC),(OTHER): "
+ "(%d,%d,%d,%d),(%d),(%d)\n", event_data[0], event_data[1],
+ event_data[2],
+ event_data[3], event_data[4], event_data[5]);
+ break;
+#endif
+
+ case WLC_E_IF:
+ {
+ dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data;
+#ifdef PROP_TXSTATUS
+ {
+ uint8* ea = pvt_data->eth.ether_dhost;
+ AP6210_DEBUG("WLC_E_IF: idx:%d, action:%s, iftype:%s, "
+ "[%02x:%02x:%02x:%02x:%02x:%02x]\n",
+ ifevent->ifidx,
+ ((ifevent->action == WLC_E_IF_ADD) ? "ADD":"DEL"),
+ ((ifevent->is_AP == 0) ? "STA":"AP "),
+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]);
+ (void)ea;
+ if (ifevent->action == WLC_E_IF_CHANGE)
+ dhd_wlfc_interface_event(dhd_pub->info,
+ eWLFC_MAC_ENTRY_ACTION_UPDATE,
+ ifevent->ifidx, ifevent->is_AP, ea);
+ else
+ dhd_wlfc_interface_event(dhd_pub->info,
+ ((ifevent->action == WLC_E_IF_ADD) ?
+ eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL),
+ ifevent->ifidx, ifevent->is_AP, ea);
+
+
+ /* dhd already has created an interface by default, for 0 */
+ if (ifevent->ifidx == 0)
+ break;
+ }
+#endif /* PROP_TXSTATUS */
+
+#ifdef WL_CFG80211
+ if (wl_cfg80211_is_progress_ifchange()) {
+ AP6210_ERR("%s: ifidx %d for %s action %d\n",
+ __FUNCTION__, ifevent->ifidx,
+ event->ifname, ifevent->action);
+ if (ifevent->action == WLC_E_IF_ADD ||
+ ifevent->action == WLC_E_IF_CHANGE)
+ wl_cfg80211_notify_ifchange();
+ return (BCME_OK);
+ }
+#endif /* WL_CFG80211 */
+ if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) {
+ if (ifevent->action == WLC_E_IF_ADD) {
+ if (dhd_add_if(dhd_pub->info, ifevent->ifidx,
+ NULL, event->ifname,
+ event->addr.octet,
+ ifevent->flags, ifevent->bssidx)) {
+ AP6210_ERR("%s: dhd_add_if failed!!"
+ " ifidx: %d for %s\n",
+ __FUNCTION__,
+ ifevent->ifidx,
+ event->ifname);
+ return (BCME_ERROR);
+ }
+ }
+ else if (ifevent->action == WLC_E_IF_DEL)
+ dhd_del_if(dhd_pub->info, ifevent->ifidx);
+ } else {
+#ifndef PROP_TXSTATUS
+ AP6210_ERR("%s: Invalid ifidx %d for %s\n",
+ __FUNCTION__, ifevent->ifidx, event->ifname);
+#endif /* !PROP_TXSTATUS */
+ }
+ }
+ /* send up the if event: btamp user needs it */
+ *ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname);
+ /* push up to external supp/auth */
+ dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx);
+ break;
+
+
+#ifdef WLMEDIA_HTSF
+ case WLC_E_HTSFSYNC:
+ htsf_update(dhd_pub->info, event_data);
+ break;
+#endif /* WLMEDIA_HTSF */
+#if defined(NDIS630)
+ case WLC_E_NDIS_LINK:
+ break;
+#else /* defined(NDIS630) && defined(BCMDONGLEHOST) */
+ case WLC_E_NDIS_LINK: {
+ uint32 temp = hton32(WLC_E_LINK);
+
+ memcpy((void *)(&pvt_data->event.event_type), &temp,
+ sizeof(pvt_data->event.event_type));
+ }
+#endif
+ /* These are what external supplicant/authenticator wants */
+ /* fall through */
+ case WLC_E_LINK:
+ case WLC_E_DEAUTH:
+ case WLC_E_DEAUTH_IND:
+ case WLC_E_DISASSOC:
+ case WLC_E_DISASSOC_IND:
+ AP6210_DEBUG("%s: Link event %d, flags %x, status %x\n",
+ __FUNCTION__, type, flags, status);
+ /* fall through */
+ default:
+ *ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname);
+ /* push up to external supp/auth */
+ dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx);
+ AP6210_DEBUG("%s: MAC event %d, flags %x, status %x\n",
+ __FUNCTION__, type, flags, status);
+ BCM_REFERENCE(flags);
+ BCM_REFERENCE(status);
+
+ /* put it back to WLC_E_NDIS_LINK */
+ if (type == WLC_E_NDIS_LINK) {
+ uint32 temp;
+
+ temp = ntoh32_ua((void *)&event->event_type);
+ AP6210_DEBUG("Converted to WLC_E_LINK type %d\n", temp);
+
+ temp = ntoh32(WLC_E_NDIS_LINK);
+ memcpy((void *)(&pvt_data->event.event_type), &temp,
+ sizeof(pvt_data->event.event_type));
+ }
+ break;
+ }
+
+#ifdef SHOW_EVENTS
+ wl_show_host_event(event, (void *)event_data);
+#endif /* SHOW_EVENTS */
+
+ return (BCME_OK);
+}
+
+void
+wl_event_to_host_order(wl_event_msg_t * evt)
+{
+ /* Event struct members passed from dongle to host are stored in network
+ * byte order. Convert all members to host-order.
+ */
+ evt->event_type = ntoh32(evt->event_type);
+ evt->flags = ntoh16(evt->flags);
+ evt->status = ntoh32(evt->status);
+ evt->reason = ntoh32(evt->reason);
+ evt->auth_type = ntoh32(evt->auth_type);
+ evt->datalen = ntoh32(evt->datalen);
+ evt->version = ntoh16(evt->version);
+}
+
+void
+dhd_print_buf(void *pbuf, int len, int bytes_per_line)
+{
+#ifdef DHD_DEBUG
+ int i, j = 0;
+ unsigned char *buf = pbuf;
+
+ if (bytes_per_line == 0) {
+ bytes_per_line = len;
+ }
+
+ for (i = 0; i < len; i++) {
+ AP6210_DUMP("%2.2x", *buf++);
+ j++;
+ if (j == bytes_per_line) {
+ AP6210_DUMP("\n");
+ j = 0;
+ } else {
+ AP6210_DUMP(":");
+ }
+ }
+ AP6210_DUMP("\n");
+#endif /* DHD_DEBUG */
+}
+
+#ifndef strtoul
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+#endif
+
+#ifdef PKT_FILTER_SUPPORT
+/* Convert user's input in hex pattern to byte-size mask */
+static int
+wl_pattern_atoh(char *src, char *dst)
+{
+ int i;
+ if (strncmp(src, "0x", 2) != 0 &&
+ strncmp(src, "0X", 2) != 0) {
+ AP6210_ERR("Mask invalid format. Needs to start with 0x\n");
+ return -1;
+ }
+ src = src + 2; /* Skip past 0x */
+ if (strlen(src) % 2 != 0) {
+ AP6210_ERR("Mask invalid format. Needs to be of even length\n");
+ return -1;
+ }
+ for (i = 0; *src != '\0'; i++) {
+ char num[3];
+ bcm_strncpy_s(num, sizeof(num), src, 2);
+ num[2] = '\0';
+ dst[i] = (uint8)strtoul(num, NULL, 16);
+ src += 2;
+ }
+ return i;
+}
+
+void
+dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode)
+{
+ char *argv[8];
+ int i = 0;
+ const char *str;
+ int buf_len;
+ int str_len;
+ char *arg_save = 0, *arg_org = 0;
+ int rc;
+ char buf[128];
+ wl_pkt_filter_enable_t enable_parm;
+ wl_pkt_filter_enable_t * pkt_filterp;
+
+ if (!arg)
+ return;
+
+ if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
+ AP6210_ERR("%s: kmalloc failed\n", __FUNCTION__);
+ goto fail;
+ }
+ arg_org = arg_save;
+ memcpy(arg_save, arg, strlen(arg) + 1);
+
+ argv[i] = bcmstrtok(&arg_save, " ", 0);
+
+ i = 0;
+ if (argv[i] == NULL) {
+ AP6210_ERR("No args provided\n");
+ goto fail;
+ }
+
+ str = "pkt_filter_enable";
+ str_len = strlen(str);
+ bcm_strncpy_s(buf, sizeof(buf), str, str_len);
+ buf[str_len] = '\0';
+ buf_len = str_len + 1;
+
+ pkt_filterp = (wl_pkt_filter_enable_t *)(buf + str_len + 1);
+
+ /* Parse packet filter id. */
+ enable_parm.id = htod32(strtoul(argv[i], NULL, 0));
+
+ /* Parse enable/disable value. */
+ enable_parm.enable = htod32(enable);
+
+ buf_len += sizeof(enable_parm);
+ memcpy((char *)pkt_filterp,
+ &enable_parm,
+ sizeof(enable_parm));
+
+ /* Enable/disable the specified filter. */
+ rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
+ rc = rc >= 0 ? 0 : rc;
+ if (rc)
+ AP6210_DEBUG("%s: failed to add pktfilter %s, retcode = %d\n",
+ __FUNCTION__, arg, rc);
+ else
+ AP6210_DEBUG("%s: successfully added pktfilter %s\n",
+ __FUNCTION__, arg);
+
+ /* Contorl the master mode */
+ bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, sizeof(buf));
+ rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
+ rc = rc >= 0 ? 0 : rc;
+ if (rc)
+ AP6210_DEBUG("%s: failed to add pktfilter %s, retcode = %d\n",
+ __FUNCTION__, arg, rc);
+
+fail:
+ if (arg_org)
+ MFREE(dhd->osh, arg_org, strlen(arg) + 1);
+}
+
+void
+dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
+{
+ const char *str;
+ wl_pkt_filter_t pkt_filter;
+ wl_pkt_filter_t *pkt_filterp;
+ int buf_len;
+ int str_len;
+ int rc;
+ uint32 mask_size;
+ uint32 pattern_size;
+ char *argv[8], * buf = 0;
+ int i = 0;
+ char *arg_save = 0, *arg_org = 0;
+#define BUF_SIZE 2048
+
+ if (!arg)
+ return;
+
+ if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
+ AP6210_ERR("%s: kmalloc failed\n", __FUNCTION__);
+ goto fail;
+ }
+
+ arg_org = arg_save;
+
+ if (!(buf = MALLOC(dhd->osh, BUF_SIZE))) {
+ AP6210_ERR("%s: kmalloc failed\n", __FUNCTION__);
+ goto fail;
+ }
+
+ memcpy(arg_save, arg, strlen(arg) + 1);
+
+ if (strlen(arg) > BUF_SIZE) {
+ AP6210_ERR("Not enough buffer %d < %d\n", (int)strlen(arg), (int)sizeof(buf));
+ goto fail;
+ }
+
+ argv[i] = bcmstrtok(&arg_save, " ", 0);
+ while (argv[i++])
+ argv[i] = bcmstrtok(&arg_save, " ", 0);
+
+ i = 0;
+ if (argv[i] == NULL) {
+ AP6210_ERR("No args provided\n");
+ goto fail;
+ }
+
+ str = "pkt_filter_add";
+ str_len = strlen(str);
+ bcm_strncpy_s(buf, BUF_SIZE, str, str_len);
+ buf[ str_len ] = '\0';
+ buf_len = str_len + 1;
+
+ pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1);
+
+ /* Parse packet filter id. */
+ pkt_filter.id = htod32(strtoul(argv[i], NULL, 0));
+
+ if (argv[++i] == NULL) {
+ AP6210_ERR("Polarity not provided\n");
+ goto fail;
+ }
+
+ /* Parse filter polarity. */
+ pkt_filter.negate_match = htod32(strtoul(argv[i], NULL, 0));
+
+ if (argv[++i] == NULL) {
+ AP6210_ERR("Filter type not provided\n");
+ goto fail;
+ }
+
+ /* Parse filter type. */
+ pkt_filter.type = htod32(strtoul(argv[i], NULL, 0));
+
+ if (argv[++i] == NULL) {
+ AP6210_ERR("Offset not provided\n");
+ goto fail;
+ }
+
+ /* Parse pattern filter offset. */
+ pkt_filter.u.pattern.offset = htod32(strtoul(argv[i], NULL, 0));
+
+ if (argv[++i] == NULL) {
+ AP6210_ERR("Bitmask not provided\n");
+ goto fail;
+ }
+
+ /* Parse pattern filter mask. */
+ mask_size =
+ htod32(wl_pattern_atoh(argv[i], (char *) pkt_filterp->u.pattern.mask_and_pattern));
+
+ if (argv[++i] == NULL) {
+ AP6210_ERR("Pattern not provided\n");
+ goto fail;
+ }
+
+ /* Parse pattern filter pattern. */
+ pattern_size =
+ htod32(wl_pattern_atoh(argv[i],
+ (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
+
+ if (mask_size != pattern_size) {
+ AP6210_ERR("Mask and pattern not the same size\n");
+ goto fail;
+ }
+
+ pkt_filter.u.pattern.size_bytes = mask_size;
+ buf_len += WL_PKT_FILTER_FIXED_LEN;
+ buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
+
+ /* Keep-alive attributes are set in local variable (keep_alive_pkt), and
+ ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
+ ** guarantee that the buffer is properly aligned.
+ */
+ memcpy((char *)pkt_filterp,
+ &pkt_filter,
+ WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
+
+ rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
+ rc = rc >= 0 ? 0 : rc;
+
+ if (rc)
+ AP6210_DEBUG("%s: failed to add pktfilter %s, retcode = %d\n",
+ __FUNCTION__, arg, rc);
+ else
+ AP6210_DEBUG("%s: successfully added pktfilter %s\n",
+ __FUNCTION__, arg);
+
+fail:
+ if (arg_org)
+ MFREE(dhd->osh, arg_org, strlen(arg) + 1);
+
+ if (buf)
+ MFREE(dhd->osh, buf, BUF_SIZE);
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+/* ========================== */
+/* ==== ARP OFFLOAD SUPPORT = */
+/* ========================== */
+#ifdef ARP_OFFLOAD_SUPPORT
+void
+dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode)
+{
+ char iovbuf[32];
+ int retcode;
+
+ bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ retcode = retcode >= 0 ? 0 : retcode;
+ if (retcode)
+ AP6210_DEBUG("%s: failed to set ARP offload mode to 0x%x, retcode = %d\n",
+ __FUNCTION__, arp_mode, retcode);
+ else
+ AP6210_DEBUG("%s: successfully set ARP offload mode to 0x%x\n",
+ __FUNCTION__, arp_mode);
+}
+
+void
+dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable)
+{
+ char iovbuf[32];
+ int retcode;
+
+ bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf));
+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ retcode = retcode >= 0 ? 0 : retcode;
+ if (retcode)
+ AP6210_DEBUG("%s: failed to enabe ARP offload to %d, retcode = %d\n",
+ __FUNCTION__, arp_enable, retcode);
+ else
+ AP6210_DEBUG("%s: successfully enabed ARP offload to %d\n",
+ __FUNCTION__, arp_enable);
+ if (arp_enable) {
+ uint32 version;
+ bcm_mkiovar("arp_version", 0, 0, iovbuf, sizeof(iovbuf));
+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0);
+ if (retcode) {
+ AP6210_DEBUG("%s: fail to get version (maybe version 1:retcode = %d\n",
+ __FUNCTION__, retcode);
+ dhd->arp_version = 1;
+ }
+ else {
+ memcpy(&version, iovbuf, sizeof(version));
+ AP6210_DEBUG("%s: ARP Version= %x\n", __FUNCTION__, version);
+ dhd->arp_version = version;
+ }
+ }
+}
+
+void
+dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx)
+{
+ int ret = 0;
+ int iov_len = 0;
+ char iovbuf[128];
+
+ if (dhd == NULL) return;
+ if (dhd->arp_version == 1)
+ idx = 0;
+
+ iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx) < 0))
+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret);
+}
+
+void
+dhd_aoe_hostip_clr(dhd_pub_t *dhd, int idx)
+{
+ int ret = 0;
+ int iov_len = 0;
+ char iovbuf[128];
+
+ if (dhd == NULL) return;
+ if (dhd->arp_version == 1)
+ idx = 0;
+
+ iov_len = bcm_mkiovar("arp_hostip_clear", 0, 0, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx)) < 0)
+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret);
+}
+
+void
+dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx)
+{
+ int iov_len = 0;
+ char iovbuf[32];
+ int retcode;
+
+
+ if (dhd == NULL) return;
+ if (dhd->arp_version == 1)
+ idx = 0;
+ iov_len = bcm_mkiovar("arp_hostip", (char *)&ipaddr,
+ sizeof(ipaddr), iovbuf, sizeof(iovbuf));
+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx);
+
+ if (retcode)
+ AP6210_DEBUG("%s: ARP ip addr add failed, retcode = %d\n",
+ __FUNCTION__, retcode);
+ else
+ AP6210_DEBUG("%s: sARP H ipaddr entry added \n",
+ __FUNCTION__);
+}
+
+int
+dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx)
+{
+ int retcode, i;
+ int iov_len;
+ uint32 *ptr32 = buf;
+ bool clr_bottom = FALSE;
+
+ if (!buf)
+ return -1;
+ if (dhd == NULL) return -1;
+ if (dhd->arp_version == 1)
+ idx = 0;
+
+ iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen);
+ BCM_REFERENCE(iov_len);
+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, FALSE, idx);
+
+ if (retcode) {
+ AP6210_DEBUG("%s: ioctl WLC_GET_VAR error %d\n",
+ __FUNCTION__, retcode);
+
+ return -1;
+ }
+
+ /* clean up the buf, ascii reminder */
+ for (i = 0; i < MAX_IPV4_ENTRIES; i++) {
+ if (!clr_bottom) {
+ if (*ptr32 == 0)
+ clr_bottom = TRUE;
+ } else {
+ *ptr32 = 0;
+ }
+ ptr32++;
+ }
+
+ return 0;
+}
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+/* send up locally generated event */
+void
+dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data)
+{
+ switch (ntoh32(event->event_type)) {
+#ifdef WLBTAMP
+ case WLC_E_BTA_HCI_EVENT:
+ break;
+#endif /* WLBTAMP */
+ default:
+ break;
+ }
+
+ /* Call per-port handler. */
+ dhd_sendup_event(dhdp, event, data);
+}
+
+
+/*
+ * returns = TRUE if associated, FALSE if not associated
+ */
+bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval)
+{
+ char bssid[6], zbuf[6];
+ int ret = -1;
+
+ bzero(bssid, 6);
+ bzero(zbuf, 6);
+
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, (char *)&bssid, ETHER_ADDR_LEN, FALSE, 0);
+ AP6210_DEBUG(" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret);
+
+ if (ret == BCME_NOTASSOCIATED) {
+ AP6210_DEBUG("%s: not associated! res:%d\n", __FUNCTION__, ret);
+ }
+
+ if (retval)
+ *retval = ret;
+
+ if (ret < 0)
+ return FALSE;
+
+ if ((memcmp(bssid, zbuf, ETHER_ADDR_LEN) != 0)) {
+ /* STA is assocoated BSSID is non zero */
+
+ if (bss_buf) {
+ /* return bss if caller provided buf */
+ memcpy(bss_buf, bssid, ETHER_ADDR_LEN);
+ }
+ return TRUE;
+ } else {
+ AP6210_DEBUG("%s: WLC_GET_BSSID ioctl returned zero bssid\n", __FUNCTION__);
+ return FALSE;
+ }
+}
+
+
+/* Function to estimate possible DTIM_SKIP value */
+int
+dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd)
+{
+ int bcn_li_dtim;
+ int ret = -1;
+ int dtim_assoc = 0;
+
+ bcn_li_dtim = dhd->suspend_bcn_li_dtim;
+
+ /* Check if associated */
+ if (dhd_is_associated(dhd, NULL, NULL) == FALSE) {
+ AP6210_DEBUG("%s NOT assoc ret %d\n", __FUNCTION__, ret);
+ goto exit;
+ }
+
+ /* if assoc grab ap's dtim value */
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_DTIMPRD,
+ &dtim_assoc, sizeof(dtim_assoc), FALSE, 0)) < 0) {
+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret);
+ goto exit;
+ }
+
+ AP6210_ERR("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n",
+ __FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL);
+
+ /* if not assocated just eixt */
+ if (dtim_assoc == 0) {
+ goto exit;
+ }
+
+ /* check if sta listen interval fits into AP dtim */
+ if (dtim_assoc > LISTEN_INTERVAL) {
+ /* AP DTIM to big for our Listen Interval : no dtim skiping */
+ bcn_li_dtim = 1;
+ AP6210_ERR("%s DTIM=%d > Listen=%d : too big ...\n",
+ __FUNCTION__, dtim_assoc, LISTEN_INTERVAL);
+ goto exit;
+ }
+
+ if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) {
+ /* Round up dtim_skip to fit into STAs Listen Interval */
+ bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc);
+ AP6210_DEBUG("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim);
+ }
+
+exit:
+ return bcn_li_dtim;
+}
+
+/* Check if the mode supports STA MODE */
+bool dhd_support_sta_mode(dhd_pub_t *dhd)
+{
+
+#ifdef WL_CFG80211
+ if (!(dhd->op_mode & DHD_FLAG_STA_MODE))
+ return FALSE;
+ else
+#endif /* WL_CFG80211 */
+ return TRUE;
+}
+
+#if defined(PNO_SUPPORT)
+int
+dhd_pno_clean(dhd_pub_t *dhd)
+{
+ char iovbuf[128];
+ int pfn_enabled = 0;
+ int iov_len = 0;
+ int ret;
+
+ /* Disable pfn */
+ iov_len = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) >= 0) {
+ /* clear pfn */
+ iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf));
+ if (iov_len) {
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
+ iov_len, TRUE, 0)) < 0) {
+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret);
+ }
+ }
+ else {
+ ret = -1;
+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, iov_len);
+ }
+ }
+ else
+ AP6210_ERR("%s failed code %d\n", __FUNCTION__, ret);
+
+ return ret;
+}
+
+int
+dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
+{
+ char iovbuf[128];
+ int ret = -1;
+
+ if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) {
+ AP6210_ERR("%s error exit\n", __FUNCTION__);
+ return ret;
+ }
+
+#ifndef WL_SCHED_SCAN
+ if (!dhd_support_sta_mode(dhd))
+ return (ret);
+
+ memset(iovbuf, 0, sizeof(iovbuf));
+
+ if ((pfn_enabled) && (dhd_is_associated(dhd, NULL, NULL) == TRUE)) {
+ AP6210_ERR("%s pno is NOT enable : called in assoc mode , ignore\n", __FUNCTION__);
+ return ret;
+ }
+#endif /* !WL_SCHED_SCAN */
+
+ /* Enable/disable PNO */
+ if ((ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf))) > 0) {
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
+ iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+ AP6210_ERR("%s failed for error=%d\n", __FUNCTION__, ret);
+ return ret;
+ }
+ else {
+ dhd->pno_enable = pfn_enabled;
+ AP6210_DEBUG("%s set pno as %s\n",
+ __FUNCTION__, dhd->pno_enable ? "Enable" : "Disable");
+ }
+ }
+ else AP6210_ERR("%s failed err=%d\n", __FUNCTION__, ret);
+
+ return ret;
+}
+
+/* Function to execute combined scan */
+int
+dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr,
+ int pno_repeat, int pno_freq_expo_max)
+{
+ int err = -1;
+ char iovbuf[128];
+ int k, i;
+ wl_pfn_param_t pfn_param;
+ wl_pfn_t pfn_element;
+ uint len = 0;
+
+ AP6210_DEBUG("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, scan_fr);
+
+ if ((!dhd) || (!ssids_local)) {
+ AP6210_ERR("%s error exit(%s %s)\n", __FUNCTION__,
+ (!dhd)?"dhd is null":"", (!ssids_local)?"ssid is null":"");
+ err = -1;
+ return err;
+ }
+#ifndef WL_SCHED_SCAN
+ if (!dhd_support_sta_mode(dhd))
+ return err;
+#endif /* !WL_SCHED_SCAN */
+
+ /* Check for broadcast ssid */
+ for (k = 0; k < nssid; k++) {
+ if (!ssids_local[k].SSID_len) {
+ AP6210_ERR("%d: Broadcast SSID is ilegal for PNO setting\n", k);
+ return err;
+ }
+ }
+/* #define PNO_DUMP 1 */
+#ifdef PNO_DUMP
+ {
+ int j;
+ for (j = 0; j < nssid; j++) {
+ AP6210_ERR("%d: scan for %s size =%d\n", j,
+ ssids_local[j].SSID, ssids_local[j].SSID_len);
+ }
+ }
+#endif /* PNO_DUMP */
+
+ /* clean up everything */
+ if ((err = dhd_pno_clean(dhd)) < 0) {
+ AP6210_ERR("%s failed error=%d\n", __FUNCTION__, err);
+ return err;
+ }
+ memset(iovbuf, 0, sizeof(iovbuf));
+ memset(&pfn_param, 0, sizeof(pfn_param));
+ memset(&pfn_element, 0, sizeof(pfn_element));
+
+ /* set pfn parameters */
+ pfn_param.version = htod32(PFN_VERSION);
+ pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT));
+
+ /* check and set extra pno params */
+ if ((pno_repeat != 0) || (pno_freq_expo_max != 0)) {
+ pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT);
+ pfn_param.repeat = (uchar) (pno_repeat);
+ pfn_param.exp = (uchar) (pno_freq_expo_max);
+ }
+ /* set up pno scan fr */
+ if (scan_fr != 0)
+ pfn_param.scan_freq = htod32(scan_fr);
+
+ if (pfn_param.scan_freq > PNO_SCAN_MAX_FW_SEC) {
+ AP6210_ERR("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW_SEC);
+ return err;
+ }
+ if (pfn_param.scan_freq < PNO_SCAN_MIN_FW_SEC) {
+ AP6210_ERR("%s pno freq less %d sec\n", __FUNCTION__, PNO_SCAN_MIN_FW_SEC);
+ return err;
+ }
+
+ len = bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf));
+ if ((err = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) {
+ AP6210_ERR("%s pfn_set failed for error=%d\n",
+ __FUNCTION__, err);
+ return err;
+ }
+
+ /* set all pfn ssid */
+ for (i = 0; i < nssid; i++) {
+
+ pfn_element.infra = htod32(DOT11_BSSTYPE_INFRASTRUCTURE);
+ pfn_element.auth = (DOT11_OPEN_SYSTEM);
+ pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY);
+ pfn_element.wsec = htod32(0);
+ pfn_element.infra = htod32(1);
+ pfn_element.flags = htod32(ENABLE << WL_PFN_HIDDEN_BIT);
+ memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len);
+ pfn_element.ssid.SSID_len = ssids_local[i].SSID_len;
+
+ if ((len =
+ bcm_mkiovar("pfn_add", (char *)&pfn_element,
+ sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) {
+ if ((err =
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0)) < 0) {
+ AP6210_ERR("%s failed for i=%d error=%d\n",
+ __FUNCTION__, i, err);
+ return err;
+ }
+ else
+ AP6210_DEBUG("%s set OK with PNO time=%d repeat=%d max_adjust=%d\n",
+ __FUNCTION__, pfn_param.scan_freq,
+ pfn_param.repeat, pfn_param.exp);
+ }
+ else AP6210_ERR("%s failed err=%d\n", __FUNCTION__, err);
+ }
+
+ /* Enable PNO */
+ /* dhd_pno_enable(dhd, 1); */
+ return err;
+}
+
+int
+dhd_pno_get_status(dhd_pub_t *dhd)
+{
+ int ret = -1;
+
+ if (!dhd)
+ return ret;
+ else
+ return (dhd->pno_enable);
+}
+
+#endif /* OEM_ANDROID && PNO_SUPPORT */
+
+#if defined(KEEP_ALIVE)
+int dhd_keep_alive_onoff(dhd_pub_t *dhd)
+{
+ char buf[256];
+ const char *str;
+ wl_mkeep_alive_pkt_t mkeep_alive_pkt;
+ wl_mkeep_alive_pkt_t *mkeep_alive_pktp;
+ int buf_len;
+ int str_len;
+ int res = -1;
+
+ if (!dhd_support_sta_mode(dhd))
+ return res;
+
+ AP6210_DEBUG("%s execution\n", __FUNCTION__);
+
+ str = "mkeep_alive";
+ str_len = strlen(str);
+ strncpy(buf, str, str_len);
+ buf[ str_len ] = '\0';
+ mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) (buf + str_len + 1);
+ mkeep_alive_pkt.period_msec = CUSTOM_KEEP_ALIVE_SETTING;
+ buf_len = str_len + 1;
+ mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION);
+ mkeep_alive_pkt.length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
+ /* Setup keep alive zero for null packet generation */
+ mkeep_alive_pkt.keep_alive_id = 0;
+ mkeep_alive_pkt.len_bytes = 0;
+ buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
+ bzero(mkeep_alive_pkt.data, sizeof(mkeep_alive_pkt.data));
+ /* Keep-alive attributes are set in local variable (mkeep_alive_pkt), and
+ * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no
+ * guarantee that the buffer is properly aligned.
+ */
+ memcpy((char *)mkeep_alive_pktp, &mkeep_alive_pkt, WL_MKEEP_ALIVE_FIXED_LEN);
+
+ res = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
+
+ return res;
+}
+#endif /* defined(KEEP_ALIVE) */
+/* Android ComboSCAN support */
+
+/*
+ * data parsing from ComboScan tlv list
+*/
+int
+wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token,
+ int input_size, int *bytes_left)
+{
+ char* str;
+ uint16 short_temp;
+ uint32 int_temp;
+
+ if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) {
+ AP6210_ERR("%s error paramters\n", __FUNCTION__);
+ return -1;
+ }
+ str = *list_str;
+
+ /* Clean all dest bytes */
+ memset(dst, 0, dst_size);
+ while (*bytes_left > 0) {
+
+ if (str[0] != token) {
+ AP6210_DEBUG("%s NOT Type=%d get=%d left_parse=%d \n",
+ __FUNCTION__, token, str[0], *bytes_left);
+ return -1;
+ }
+
+ *bytes_left -= 1;
+ str += 1;
+
+ if (input_size == 1) {
+ memcpy(dst, str, input_size);
+ }
+ else if (input_size == 2) {
+ memcpy(dst, (char *)htod16(memcpy(&short_temp, str, input_size)),
+ input_size);
+ }
+ else if (input_size == 4) {
+ memcpy(dst, (char *)htod32(memcpy(&int_temp, str, input_size)),
+ input_size);
+ }
+
+ *bytes_left -= input_size;
+ str += input_size;
+ *list_str = str;
+ return 1;
+ }
+ return 1;
+}
+
+/*
+ * channel list parsing from cscan tlv list
+*/
+int
+wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list,
+ int channel_num, int *bytes_left)
+{
+ char* str;
+ int idx = 0;
+
+ if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) {
+ AP6210_ERR("%s error paramters\n", __FUNCTION__);
+ return -1;
+ }
+ str = *list_str;
+
+ while (*bytes_left > 0) {
+
+ if (str[0] != CSCAN_TLV_TYPE_CHANNEL_IE) {
+ *list_str = str;
+ AP6210_DEBUG("End channel=%d left_parse=%d %d\n", idx, *bytes_left, str[0]);
+ return idx;
+ }
+ /* Get proper CSCAN_TLV_TYPE_CHANNEL_IE */
+ *bytes_left -= 1;
+ str += 1;
+
+ if (str[0] == 0) {
+ /* All channels */
+ channel_list[idx] = 0x0;
+ }
+ else {
+ channel_list[idx] = (uint16)str[0];
+ AP6210_DEBUG("%s channel=%d \n", __FUNCTION__, channel_list[idx]);
+ }
+ *bytes_left -= 1;
+ str += 1;
+
+ if (idx++ > 255) {
+ AP6210_ERR("%s Too many channels \n", __FUNCTION__);
+ return -1;
+ }
+ }
+
+ *list_str = str;
+ return idx;
+}
+
+/*
+ * SSIDs list parsing from cscan tlv list
+ */
+int
+wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left)
+{
+ char* str;
+ int idx = 0;
+
+ if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
+ AP6210_ERR("%s error paramters\n", __FUNCTION__);
+ return -1;
+ }
+ str = *list_str;
+ while (*bytes_left > 0) {
+
+ if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
+ *list_str = str;
+ AP6210_DEBUG("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]);
+ return idx;
+ }
+
+ /* Get proper CSCAN_TLV_TYPE_SSID_IE */
+ *bytes_left -= 1;
+ str += 1;
+
+ if (str[0] == 0) {
+ /* Broadcast SSID */
+ ssid[idx].SSID_len = 0;
+ memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN);
+ *bytes_left -= 1;
+ str += 1;
+
+ AP6210_DEBUG("BROADCAST SCAN left=%d\n", *bytes_left);
+ }
+ else if (str[0] <= DOT11_MAX_SSID_LEN) {
+ /* Get proper SSID size */
+ ssid[idx].SSID_len = str[0];
+ *bytes_left -= 1;
+ str += 1;
+
+ /* Get SSID */
+ if (ssid[idx].SSID_len > *bytes_left) {
+ AP6210_ERR("%s out of memory range len=%d but left=%d\n",
+ __FUNCTION__, ssid[idx].SSID_len, *bytes_left);
+ return -1;
+ }
+
+ memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len);
+
+ *bytes_left -= ssid[idx].SSID_len;
+ str += ssid[idx].SSID_len;
+
+ AP6210_DEBUG("%s :size=%d left=%d\n",
+ (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left);
+ }
+ else {
+ AP6210_ERR("### SSID size more that %d\n", str[0]);
+ return -1;
+ }
+
+ if (idx++ > max) {
+ AP6210_ERR("%s number of SSIDs more that %d\n", __FUNCTION__, idx);
+ return -1;
+ }
+ }
+
+ *list_str = str;
+ return idx;
+}
+
+/* Parse a comma-separated list from list_str into ssid array, starting
+ * at index idx. Max specifies size of the ssid array. Parses ssids
+ * and returns updated idx; if idx >= max not all fit, the excess have
+ * not been copied. Returns -1 on empty string, or on ssid too long.
+ */
+int
+wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max)
+{
+ char* str, *ptr;
+
+ if ((list_str == NULL) || (*list_str == NULL))
+ return -1;
+
+ for (str = *list_str; str != NULL; str = ptr) {
+
+ /* check for next TAG */
+ if (!strncmp(str, GET_CHANNEL, strlen(GET_CHANNEL))) {
+ *list_str = str + strlen(GET_CHANNEL);
+ return idx;
+ }
+
+ if ((ptr = strchr(str, ',')) != NULL) {
+ *ptr++ = '\0';
+ }
+
+ if (strlen(str) > DOT11_MAX_SSID_LEN) {
+ AP6210_ERR("ssid <%s> exceeds %d\n", str, DOT11_MAX_SSID_LEN);
+ return -1;
+ }
+
+ if (strlen(str) == 0)
+ ssid[idx].SSID_len = 0;
+
+ if (idx < max) {
+ bzero(ssid[idx].SSID, sizeof(ssid[idx].SSID));
+ strncpy((char*)ssid[idx].SSID, str, sizeof(ssid[idx].SSID) - 1);
+ ssid[idx].SSID_len = strlen(str);
+ }
+ idx++;
+ }
+ return idx;
+}
+
+/*
+ * Parse channel list from iwpriv CSCAN
+ */
+int
+wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num)
+{
+ int num;
+ int val;
+ char* str;
+ char* endptr = NULL;
+
+ if ((list_str == NULL)||(*list_str == NULL))
+ return -1;
+
+ str = *list_str;
+ num = 0;
+ while (strncmp(str, GET_NPROBE, strlen(GET_NPROBE))) {
+ val = (int)strtoul(str, &endptr, 0);
+ if (endptr == str) {
+ AP6210_ERR("could not parse channel number starting at"
+ " substring \"%s\" in list:\n%s\n",
+ str, *list_str);
+ return -1;
+ }
+ str = endptr + strspn(endptr, " ,");
+
+ if (num == channel_num) {
+ AP6210_ERR("too many channels (more than %d) in channel list:\n%s\n",
+ channel_num, *list_str);
+ return -1;
+ }
+
+ channel_list[num++] = (uint16)val;
+ }
+ *list_str = str;
+ return num;
+}
diff --git a/drivers/net/wireless/ap6210/dhd_custom_gpio.c b/drivers/net/wireless/ap6210/dhd_custom_gpio.c
new file mode 100644
index 0000000..afdb9b3
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_custom_gpio.c
@@ -0,0 +1,313 @@
+/*
+* Customer code to add GPIO control during WLAN start/stop
+* Copyright (C) 1999-2012, Broadcom Corporation
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2 (the "GPL"),
+* available at http://www.broadcom.com/licenses/GPLv2.php, with the
+* following added to such license:
+*
+* As a special exception, the copyright holders of this software give you
+* permission to link this software with independent modules, and to copy and
+* distribute the resulting executable under terms of your choice, provided that
+* you also meet, for each linked independent module, the terms and conditions of
+* the license of that module. An independent module is a module which is not
+* derived from this software. The special exception does not apply to any
+* modifications of the software.
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a license
+* other than the GPL, without Broadcom's express prior written consent.
+*
+* $Id: dhd_custom_gpio.c 353167 2012-08-24 22:11:30Z $
+*/
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#include <bcmutils.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+
+#include <wlioctl.h>
+#include <wl_iw.h>
+
+#include <plat/sys_config.h>
+#include <plat/gpio.h>
+
+#include <ap6210_gpio.h>
+#include <ap6210.h>
+
+extern void sunximmc_rescan_card(unsigned id, unsigned insert);
+
+#ifdef CUSTOMER_HW
+#include <mach/gpio.h>
+#if defined(CUSTOMER_OOB)
+extern int bcm_wlan_get_oob_irq(void);
+#endif
+extern void bcm_wlan_power_off(int);
+extern void bcm_wlan_power_on(int);
+#endif /* CUSTOMER_HW */
+#if defined(CUSTOMER_HW2)
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+int wifi_set_power(int on, unsigned long msec);
+int wifi_get_irq_number(unsigned long *irq_flags_ptr);
+int wifi_get_mac_addr(unsigned char *buf);
+void *wifi_get_country_code(char *ccode);
+#else
+int wifi_set_power(int on, unsigned long msec) { return -1; }
+int wifi_get_irq_number(unsigned long *irq_flags_ptr) { return -1; }
+int wifi_get_mac_addr(unsigned char *buf) { return -1; }
+void *wifi_get_country_code(char *ccode) { return NULL; }
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
+#endif
+
+#if defined(OOB_INTR_ONLY)
+
+#if defined(BCMLXSDMMC)
+extern int sdioh_mmc_irq(int irq);
+#endif /* (BCMLXSDMMC) */
+
+#ifdef CUSTOMER_HW3
+#include <mach/gpio.h>
+#endif
+
+/* Customer specific Host GPIO defintion */
+static int dhd_oob_gpio_num = 2;
+
+module_param(dhd_oob_gpio_num, int, 0644);
+MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number");
+
+/* This function will return:
+ * 1) return : Host gpio interrupt number per customer platform
+ * 2) irq_flags_ptr : Type of Host interrupt as Level or Edge
+ *
+ * NOTE :
+ * Customer should check his platform definitions
+ * and his Host Interrupt spec
+ * to figure out the proper setting for his platform.
+ * Broadcom provides just reference settings as example.
+ *
+ */
+int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
+{
+ int host_oob_irq = -1;
+
+#if defined(CUSTOMER_HW2)
+ host_oob_irq = wifi_get_irq_number(irq_flags_ptr);
+
+#elif defined(CUSTOMER_OOB)
+ host_oob_irq = bcm_wlan_get_oob_irq();
+ AP6210_DEBUG("irq=%d, flags=0x%08lx\n", host_oob_irq, *irq_flags_ptr);
+#else
+#if defined(CUSTOM_OOB_GPIO_NUM)
+ if (dhd_oob_gpio_num < 0) {
+ dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
+ }
+#endif /* CUSTOMER_OOB_GPIO_NUM */
+
+ if (dhd_oob_gpio_num < 0) {
+ AP6210_ERR("%s: ERROR customer specific Host GPIO is NOT defined \n",
+ __FUNCTION__);
+ return (dhd_oob_gpio_num);
+ }
+
+ AP6210_ERR("%s: customer specific Host GPIO number is (%d)\n",
+ __FUNCTION__, dhd_oob_gpio_num);
+
+#if defined CUSTOMER_HW
+ AP6210_ERR("%s: should not be here!\n", __FUNCTION__);
+#elif defined CUSTOMER_HW3
+ gpio_request(dhd_oob_gpio_num, "oob irq");
+ host_oob_irq = gpio_to_irq(dhd_oob_gpio_num);
+ gpio_direction_input(dhd_oob_gpio_num);
+#endif /* CUSTOMER_HW */
+#endif
+
+ return (host_oob_irq);
+}
+#endif
+
+/* Customer function to control hw specific wlan gpios */
+void
+dhd_customer_gpio_wlan_ctrl(int onoff)
+{
+ static int sdc_id = 3;
+
+ switch (onoff) {
+ case WLAN_RESET_OFF:
+ AP6210_DEBUG("%s: call customer specific GPIO to insert WLAN RESET\n",
+ __FUNCTION__);
+#ifdef CUSTOMER_HW
+ ap6210_gpio_wifi_power(0);
+#endif /* CUSTOMER_HW */
+#if defined(CUSTOMER_HW2)
+ wifi_set_power(0, 0);
+#endif
+ mdelay(100);
+ AP6210_ERR("WLAN placed in RESET\n");
+ break;
+
+ case WLAN_RESET_ON:
+ AP6210_DEBUG("%s: callc customer specific GPIO to remove WLAN RESET\n",
+ __FUNCTION__);
+#ifdef CUSTOMER_HW
+ ap6210_gpio_wifi_power(1);
+#endif /* CUSTOMER_HW */
+#if defined(CUSTOMER_HW2)
+ wifi_set_power(1, 0);
+#endif
+ mdelay(100);
+ AP6210_ERR("WLAN going back to live\n");
+ break;
+
+ case WLAN_POWER_OFF:
+ AP6210_DEBUG("%s: call customer specific GPIO to turn off WL_REG_ON\n",
+ __FUNCTION__);
+#ifdef CUSTOMER_HW
+ ap6210_gpio_wifi_power(0);
+ sunximmc_rescan_card(sdc_id, 0);
+#endif /* CUSTOMER_HW */
+ AP6210_ERR("WLAN placed in POWER OFF\n");
+ break;
+
+ case WLAN_POWER_ON:
+ AP6210_DEBUG("%s: call customer specific GPIO to turn on WL_REG_ON\n",
+ __FUNCTION__);
+#ifdef CUSTOMER_HW
+ ap6210_gpio_wifi_power(1);
+ sunximmc_rescan_card(sdc_id, 1);
+ /* Lets customer power to get stable */
+#endif /* CUSTOMER_HW */
+ mdelay(100);
+ AP6210_ERR("WLAN placed in POWER ON\n");
+ break;
+ }
+}
+
+#ifdef GET_CUSTOM_MAC_ENABLE
+/* Function to get custom MAC address */
+int
+dhd_custom_get_mac_address(unsigned char *buf)
+{
+ int ret = 0;
+
+ AP6210_DEBUG("%s Enter\n", __FUNCTION__);
+ if (!buf)
+ return -EINVAL;
+
+ /* Customer access to MAC address stored outside of DHD driver */
+#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
+ ret = wifi_get_mac_addr(buf);
+#endif
+
+#ifdef EXAMPLE_GET_MAC
+ /* EXAMPLE code */
+ {
+ struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}};
+ bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
+ }
+#endif /* EXAMPLE_GET_MAC */
+
+ return ret;
+}
+#endif /* GET_CUSTOM_MAC_ENABLE */
+
+/* Customized Locale table : OPTIONAL feature */
+const struct cntry_locales_custom translate_custom_table[] = {
+/* Table should be filled out based on custom platform regulatory requirement */
+#ifdef EXAMPLE_TABLE
+ {"", "XY", 4}, /* Universal if Country code is unknown or empty */
+ {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */
+ {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */
+ {"EU", "EU", 5}, /* European union countries to : EU regrev 05 */
+ {"AT", "EU", 5},
+ {"BE", "EU", 5},
+ {"BG", "EU", 5},
+ {"CY", "EU", 5},
+ {"CZ", "EU", 5},
+ {"DK", "EU", 5},
+ {"EE", "EU", 5},
+ {"FI", "EU", 5},
+ {"FR", "EU", 5},
+ {"DE", "EU", 5},
+ {"GR", "EU", 5},
+ {"HU", "EU", 5},
+ {"IE", "EU", 5},
+ {"IT", "EU", 5},
+ {"LV", "EU", 5},
+ {"LI", "EU", 5},
+ {"LT", "EU", 5},
+ {"LU", "EU", 5},
+ {"MT", "EU", 5},
+ {"NL", "EU", 5},
+ {"PL", "EU", 5},
+ {"PT", "EU", 5},
+ {"RO", "EU", 5},
+ {"SK", "EU", 5},
+ {"SI", "EU", 5},
+ {"ES", "EU", 5},
+ {"SE", "EU", 5},
+ {"GB", "EU", 5},
+ {"KR", "XY", 3},
+ {"AU", "XY", 3},
+ {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */
+ {"TW", "XY", 3},
+ {"AR", "XY", 3},
+ {"MX", "XY", 3},
+ {"IL", "IL", 0},
+ {"CH", "CH", 0},
+ {"TR", "TR", 0},
+ {"NO", "NO", 0},
+#endif /* EXMAPLE_TABLE */
+};
+
+
+/* Customized Locale convertor
+* input : ISO 3166-1 country abbreviation
+* output: customized cspec
+*/
+void get_customized_country_code(char *country_iso_code, wl_country_t *cspec)
+{
+#if defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
+
+ struct cntry_locales_custom *cloc_ptr;
+
+ if (!cspec)
+ return;
+
+ cloc_ptr = wifi_get_country_code(country_iso_code);
+ if (cloc_ptr) {
+ strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ);
+ cspec->rev = cloc_ptr->custom_locale_rev;
+ }
+ return;
+#else
+ int size, i;
+
+ size = ARRAYSIZE(translate_custom_table);
+
+ if (cspec == 0)
+ return;
+
+ if (size == 0)
+ return;
+
+ for (i = 0; i < size; i++) {
+ if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) {
+ memcpy(cspec->ccode,
+ translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ);
+ cspec->rev = translate_custom_table[i].custom_locale_rev;
+ return;
+ }
+ }
+#ifdef EXAMPLE_TABLE
+ /* if no country code matched return first universal code from translate_custom_table */
+ memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ);
+ cspec->rev = translate_custom_table[0].custom_locale_rev;
+#endif /* EXMAPLE_TABLE */
+ return;
+#endif /* defined(CUSTOMER_HW2) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) */
+}
diff --git a/drivers/net/wireless/ap6210/dhd_dbg.h b/drivers/net/wireless/ap6210/dhd_dbg.h
new file mode 100644
index 0000000..67cd2e5
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_dbg.h
@@ -0,0 +1,79 @@
+/*
+ * Debug/trace/assert driver definitions for Dongle Host Driver.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_dbg.h 353490 2012-08-27 21:10:02Z $
+ */
+
+#ifndef _dhd_dbg_
+#define _dhd_dbg_
+
+#define USE_NET_RATELIMIT net_ratelimit()
+
+#if defined(DHD_DEBUG)
+
+#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL)
+#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL)
+#define DHD_INFO_ON() (dhd_msg_level & DHD_INFO_VAL)
+#define DHD_DATA_ON() (dhd_msg_level & DHD_DATA_VAL)
+#define DHD_CTL_ON() (dhd_msg_level & DHD_CTL_VAL)
+#define DHD_TIMER_ON() (dhd_msg_level & DHD_TIMER_VAL)
+#define DHD_HDRS_ON() (dhd_msg_level & DHD_HDRS_VAL)
+#define DHD_BYTES_ON() (dhd_msg_level & DHD_BYTES_VAL)
+#define DHD_INTR_ON() (dhd_msg_level & DHD_INTR_VAL)
+#define DHD_GLOM_ON() (dhd_msg_level & DHD_GLOM_VAL)
+#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL)
+#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL)
+#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL)
+#define DHD_ARPOE_ON() (dhd_msg_level & DHD_ARPOE_VAL)
+#define DHD_REORDER_ON() (dhd_msg_level & DHD_REORDER_VAL)
+
+#else /* defined(BCMDBG) || defined(DHD_DEBUG) */
+
+#define DHD_ERROR_ON() 0
+#define DHD_TRACE_ON() 0
+#define DHD_INFO_ON() 0
+#define DHD_DATA_ON() 0
+#define DHD_CTL_ON() 0
+#define DHD_TIMER_ON() 0
+#define DHD_HDRS_ON() 0
+#define DHD_BYTES_ON() 0
+#define DHD_INTR_ON() 0
+#define DHD_GLOM_ON() 0
+#define DHD_EVENT_ON() 0
+#define DHD_BTA_ON() 0
+#define DHD_ISCAN_ON() 0
+#define DHD_ARPOE_ON() 0
+#define DHD_REORDER_ON() 0
+#endif
+
+#define DHD_LOG(args)
+
+#define DHD_BLOG(cp, size)
+
+#define DHD_NONE(args)
+extern int dhd_msg_level;
+
+/* Defines msg bits */
+#include <dhdioctl.h>
+
+#endif /* _dhd_dbg_ */
diff --git a/drivers/net/wireless/ap6210/dhd_gpio.c b/drivers/net/wireless/ap6210/dhd_gpio.c
new file mode 100644
index 0000000..dae0dd3
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_gpio.c
@@ -0,0 +1,47 @@
+/*
+* Customer code to add GPIO control during WLAN start/stop
+* Copyright (C) 1999-2011, Broadcom Corporation
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2 (the "GPL"),
+* available at http://www.broadcom.com/licenses/GPLv2.php, with the
+* following added to such license:
+*
+* As a special exception, the copyright holders of this software give you
+* permission to link this software with independent modules, and to copy and
+* distribute the resulting executable under terms of your choice, provided that
+* you also meet, for each linked independent module, the terms and conditions of
+* the license of that module. An independent module is a module which is not
+* derived from this software. The special exception does not apply to any
+* modifications of the software.
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a license
+* other than the GPL, without Broadcom's express prior written consent.
+*
+* $Id: dhd_custom_gpio.c,v 1.2.42.1 2010-10-19 00:41:09 Exp $
+*/
+
+#include <osl.h>
+
+#include <mach/gpio.h>
+#include <plat/sys_config.h>
+
+#ifdef CUSTOMER_HW
+
+extern int __gpio_to_irq(unsigned gpio);
+extern int gpio_direction_input(unsigned gpio);
+extern int gpio_request(unsigned gpio, const char *label);
+extern void gpio_free(unsigned gpio);
+
+#ifdef CUSTOMER_OOB
+extern int wl_host_wake_irqno;
+int bcm_wlan_get_oob_irq(void)
+{
+ return wl_host_wake_irqno;
+}
+#endif
+
+
+#endif /* CUSTOMER_HW */
diff --git a/drivers/net/wireless/ap6210/dhd_ip.c b/drivers/net/wireless/ap6210/dhd_ip.c
new file mode 100644
index 0000000..05abc93
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_ip.c
@@ -0,0 +1,111 @@
+/*
+ * IP Packet Parser Module.
+ *
+ * Copyright (C) 1999-2013, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id$
+ */
+#include <typedefs.h>
+#include <osl.h>
+
+#include <proto/ethernet.h>
+#include <proto/vlan.h>
+#include <proto/802.3.h>
+#include <proto/bcmip.h>
+#include <bcmendian.h>
+
+#include <dhd_dbg.h>
+
+#include <dhd_ip.h>
+
+/* special values */
+/* 802.3 llc/snap header */
+static const uint8 llc_snap_hdr[SNAP_HDR_LEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+
+pkt_frag_t pkt_frag_info(osl_t *osh, void *p)
+{
+ uint8 *frame;
+ int length;
+ uint8 *pt; /* Pointer to type field */
+ uint16 ethertype;
+ struct ipv4_hdr *iph; /* IP frame pointer */
+ int ipl; /* IP frame length */
+ uint16 iph_frag;
+
+ ASSERT(osh && p);
+
+ frame = PKTDATA(osh, p);
+ length = PKTLEN(osh, p);
+
+ /* Process Ethernet II or SNAP-encapsulated 802.3 frames */
+ if (length < ETHER_HDR_LEN) {
+ AP6210_DEBUG("%s: short eth frame (%d)\n", __FUNCTION__, length);
+ return DHD_PKT_FRAG_NONE;
+ } else if (ntoh16(*(uint16 *)(frame + ETHER_TYPE_OFFSET)) >= ETHER_TYPE_MIN) {
+ /* Frame is Ethernet II */
+ pt = frame + ETHER_TYPE_OFFSET;
+ } else if (length >= ETHER_HDR_LEN + SNAP_HDR_LEN + ETHER_TYPE_LEN &&
+ !bcmp(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN)) {
+ pt = frame + ETHER_HDR_LEN + SNAP_HDR_LEN;
+ } else {
+ AP6210_DEBUG("%s: non-SNAP 802.3 frame\n", __FUNCTION__);
+ return DHD_PKT_FRAG_NONE;
+ }
+
+ ethertype = ntoh16(*(uint16 *)pt);
+
+ /* Skip VLAN tag, if any */
+ if (ethertype == ETHER_TYPE_8021Q) {
+ pt += VLAN_TAG_LEN;
+
+ if (pt + ETHER_TYPE_LEN > frame + length) {
+ AP6210_DEBUG("%s: short VLAN frame (%d)\n", __FUNCTION__, length);
+ return DHD_PKT_FRAG_NONE;
+ }
+
+ ethertype = ntoh16(*(uint16 *)pt);
+ }
+
+ if (ethertype != ETHER_TYPE_IP) {
+ AP6210_DEBUG("%s: non-IP frame (ethertype 0x%x, length %d)\n",
+ __FUNCTION__, ethertype, length);
+ return DHD_PKT_FRAG_NONE;
+ }
+
+ iph = (struct ipv4_hdr *)(pt + ETHER_TYPE_LEN);
+ ipl = length - (pt + ETHER_TYPE_LEN - frame);
+
+ /* We support IPv4 only */
+ if ((ipl < IPV4_OPTIONS_OFFSET) || (IP_VER(iph) != IP_VER_4)) {
+ AP6210_DEBUG("%s: short frame (%d) or non-IPv4\n", __FUNCTION__, ipl);
+ return DHD_PKT_FRAG_NONE;
+ }
+
+ iph_frag = ntoh16(iph->frag);
+
+ if (iph_frag & IPV4_FRAG_DONT) {
+ return DHD_PKT_FRAG_NONE;
+ } else if ((iph_frag & IPV4_FRAG_MORE) == 0) {
+ return DHD_PKT_FRAG_LAST;
+ } else {
+ return (iph_frag & IPV4_FRAG_OFFSET_MASK)? DHD_PKT_FRAG_CONT : DHD_PKT_FRAG_FIRST;
+ }
+}
diff --git a/drivers/net/wireless/ap6210/dhd_ip.h b/drivers/net/wireless/ap6210/dhd_ip.h
new file mode 100644
index 0000000..ceb3877
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_ip.h
@@ -0,0 +1,42 @@
+/*
+ * Header file describing the common ip parser function.
+ *
+ * Provides type definitions and function prototypes used to parse ip packet.
+ *
+ * Copyright (C) 1999-2013, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id$
+ */
+
+#ifndef _dhd_ip_h_
+#define _dhd_ip_h_
+
+typedef enum pkt_frag
+{
+ DHD_PKT_FRAG_NONE = 0,
+ DHD_PKT_FRAG_FIRST,
+ DHD_PKT_FRAG_CONT,
+ DHD_PKT_FRAG_LAST
+} pkt_frag_t;
+
+extern pkt_frag_t pkt_frag_info(osl_t *osh, void *p);
+
+#endif /* _dhd_ip_h_ */
diff --git a/drivers/net/wireless/ap6210/dhd_linux.c b/drivers/net/wireless/ap6210/dhd_linux.c
new file mode 100644
index 0000000..82a0a58
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_linux.c
@@ -0,0 +1,6151 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface
+ * Basically selected code segments from usb-cdc.c and usb-rndis.c
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_linux.c 374275 2012-12-12 11:44:18Z $
+ */
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/etherdevice.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <epivers.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+
+#include <proto/ethernet.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <dhd_dbg.h>
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#endif
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#endif
+
+#ifdef WLBTAMP
+#include <proto/802.11_bta.h>
+#include <proto/bt_amp_hci.h>
+#include <dhd_bta.h>
+#endif
+
+#include <ap6210_gpio.h>
+#include <ap6210.h>
+
+#ifdef WLMEDIA_HTSF
+#include <linux/time.h>
+#include <htsf.h>
+
+#define HTSF_MINLEN 200 /* min. packet length to timestamp */
+#define HTSF_BUS_DELAY 150 /* assume a fix propagation in us */
+#define TSMAX 1000 /* max no. of timing record kept */
+#define NUMBIN 34
+static uint32 tsidx = 0;
+static uint32 htsf_seqnum = 0;
+uint32 tsfsync;
+struct timeval tsync;
+static uint32 tsport = 5010;
+
+typedef struct histo_ {
+ uint32 bin[NUMBIN];
+} histo_t;
+
+#if !ISPOWEROF2(DHD_SDALIGN)
+#error DHD_SDALIGN is not a power of 2!
+#endif
+
+static histo_t vi_d1, vi_d2, vi_d3, vi_d4;
+#endif /* WLMEDIA_HTSF */
+
+#if defined(PKT_FILTER_SUPPORT)
+#endif /* PKT_FILTER_SUPPORT */
+
+#if defined(SOFTAP)
+extern bool ap_cfg_running;
+extern bool ap_fw_loaded;
+#endif
+
+/* enable HOSTIP cache update from the host side when an eth0:N is up */
+#define AOE_IP_ALIAS_SUPPORT 1
+
+#ifdef BCM_FD_AGGR
+#include <bcm_rpc.h>
+#include <bcm_rpc_tp.h>
+#endif
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+#include <wl_android.h>
+
+#ifdef ARP_OFFLOAD_SUPPORT
+void aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add, int idx);
+static int dhd_device_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr);
+
+static struct notifier_block dhd_notifier = {
+ .notifier_call = dhd_device_event
+};
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
+#include <linux/suspend.h>
+volatile bool dhd_mmc_suspend = FALSE;
+DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
+
+#if defined(OOB_INTR_ONLY)
+extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1)
+static void dhd_hang_process(struct work_struct *work);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+MODULE_LICENSE("GPL v2");
+#endif /* LinuxVer */
+
+#include <dhd_bus.h>
+
+#ifdef BCM_FD_AGGR
+#define DBUS_RX_BUFFER_SIZE_DHD(net) (BCM_RPC_TP_DNGL_AGG_MAX_BYTE)
+#else
+#ifndef PROP_TXSTATUS
+#define DBUS_RX_BUFFER_SIZE_DHD(net) (net->mtu + net->hard_header_len + dhd->pub.hdrlen)
+#else
+#define DBUS_RX_BUFFER_SIZE_DHD(net) (net->mtu + net->hard_header_len + dhd->pub.hdrlen + 128)
+#endif
+#endif /* BCM_FD_AGGR */
+
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15)
+const char *
+print_tainted()
+{
+ return "";
+}
+#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15) */
+
+/* Linux wireless extension support */
+#if defined(CONFIG_WIRELESS_EXT)
+#include <wl_iw.h>
+extern wl_iw_extra_params_t g_wl_iw_params;
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
+
+extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd);
+
+#ifdef PKT_FILTER_SUPPORT
+extern void dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg);
+extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode);
+#endif
+
+#ifdef READ_MACADDR
+extern int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac);
+#endif
+#ifdef RDWR_MACADDR
+extern int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp, struct ether_addr *mac);
+extern int dhd_write_rdwr_macaddr(struct ether_addr *mac);
+#endif
+#ifdef WRITE_MACADDR
+extern int dhd_write_macaddr(struct ether_addr *mac);
+#endif
+#ifdef GET_MAC_FROM_OTP
+extern int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac);
+#endif
+#ifdef MIMO_ANT_SETTING
+extern int dhd_sel_ant_from_file(dhd_pub_t *dhd);
+#endif
+
+#ifdef GLOBALCONFIG_WLAN_COUNTRY_CODE
+int dhd_customer_set_country(dhd_pub_t *dhd);
+#endif
+
+/* Interface control information */
+typedef struct dhd_if {
+ struct dhd_info *info; /* back pointer to dhd_info */
+ /* OS/stack specifics */
+ struct net_device *net;
+ struct net_device_stats stats;
+ int idx; /* iface idx in dongle */
+ dhd_if_state_t state; /* interface state */
+ uint subunit; /* subunit */
+ uint8 mac_addr[ETHER_ADDR_LEN]; /* assigned MAC address */
+ bool attached; /* Delayed attachment when unset */
+ bool txflowcontrol; /* Per interface flow control indicator */
+ char name[IFNAMSIZ+1]; /* linux interface name */
+ uint8 bssidx; /* bsscfg index for the interface */
+ bool set_multicast;
+ bool event2cfg80211; /* To determine if pass event to cfg80211 */
+} dhd_if_t;
+
+#ifdef WLMEDIA_HTSF
+typedef struct {
+ uint32 low;
+ uint32 high;
+} tsf_t;
+
+typedef struct {
+ uint32 last_cycle;
+ uint32 last_sec;
+ uint32 last_tsf;
+ uint32 coef; /* scaling factor */
+ uint32 coefdec1; /* first decimal */
+ uint32 coefdec2; /* second decimal */
+} htsf_t;
+
+typedef struct {
+ uint32 t1;
+ uint32 t2;
+ uint32 t3;
+ uint32 t4;
+} tstamp_t;
+
+static tstamp_t ts[TSMAX];
+static tstamp_t maxdelayts;
+static uint32 maxdelay = 0, tspktcnt = 0, maxdelaypktno = 0;
+
+#endif /* WLMEDIA_HTSF */
+
+/* Local private structure (extension of pub) */
+typedef struct dhd_info {
+#if defined(CONFIG_WIRELESS_EXT)
+ wl_iw_t iw; /* wireless extensions state (must be first) */
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+ dhd_pub_t pub;
+
+ /* For supporting multiple interfaces */
+ dhd_if_t *iflist[DHD_MAX_IFS];
+
+ struct semaphore proto_sem;
+#ifdef PROP_TXSTATUS
+ spinlock_t wlfc_spinlock;
+#endif /* PROP_TXSTATUS */
+#ifdef WLMEDIA_HTSF
+ htsf_t htsf;
+#endif
+ wait_queue_head_t ioctl_resp_wait;
+ struct timer_list timer;
+ bool wd_timer_valid;
+ struct tasklet_struct tasklet;
+ spinlock_t sdlock;
+ spinlock_t txqlock;
+ spinlock_t dhd_lock;
+#ifdef DHDTHREAD
+ /* Thread based operation */
+ bool threads_only;
+ struct semaphore sdsem;
+
+ tsk_ctl_t thr_dpc_ctl;
+ tsk_ctl_t thr_wdt_ctl;
+#endif /* DHDTHREAD */
+ bool dhd_tasklet_create;
+ tsk_ctl_t thr_sysioc_ctl;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ struct work_struct work_hang;
+#endif
+
+ /* Wakelocks */
+#if defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ struct wake_lock *wl_wifi; /* Wifi wakelock */
+ struct wake_lock *wl_rxwake; /* Wifi rx wakelock */
+ struct wake_lock *wl_ctrlwake; /* Wifi ctrl wakelock */
+ struct wake_lock *wl_wdwake; /* Wifi wd wakelock */
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ /* net_device interface lock, prevent race conditions among net_dev interface
+ * calls and wifi_on or wifi_off
+ */
+ struct mutex dhd_net_if_mutex;
+ struct mutex dhd_suspend_mutex;
+#endif
+ spinlock_t wakelock_spinlock;
+ int wakelock_counter;
+ int wakelock_wd_counter;
+ int wakelock_rx_timeout_enable;
+ int wakelock_ctrl_timeout_enable;
+
+ /* Thread to issue ioctl for multicast */
+ unsigned char set_macaddress;
+ struct ether_addr macvalue;
+ wait_queue_head_t ctrl_wait;
+ atomic_t pend_8021x_cnt;
+ dhd_attach_states_t dhd_state;
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+ struct early_suspend early_suspend;
+#endif /* CONFIG_HAS_EARLYSUSPEND && defined(DHD_USE_EARLYSUSPEND) */
+
+#ifdef ARP_OFFLOAD_SUPPORT
+ u32 pend_ipaddr;
+#endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef BCM_FD_AGGR
+ void *rpc_th;
+ void *rpc_osh;
+ struct timer_list rpcth_timer;
+ bool rpcth_timer_active;
+ bool fdaggr;
+#endif
+} dhd_info_t;
+
+/* Flag to indicate if we should download firmware on driver load */
+uint dhd_download_fw_on_driverload = TRUE;
+
+/* Definitions to provide path to the firmware and nvram
+ * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt"
+ */
+char firmware_path[MOD_PARAM_PATHLEN];
+char nvram_path[MOD_PARAM_PATHLEN];
+
+/* information string to keep firmware, chio, cheip version info visiable from log */
+char info_string[MOD_PARAM_INFOLEN];
+module_param_string(info_string, info_string, MOD_PARAM_INFOLEN, 0444);
+
+int op_mode = 0;
+int disable_proptx = 0;
+module_param(op_mode, int, 0644);
+extern int wl_control_wl_start(struct net_device *dev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+struct semaphore dhd_registration_sem;
+struct semaphore dhd_chipup_sem;
+int dhd_registration_check = FALSE;
+
+#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+
+/* Spawn a thread for system ioctls (set mac, set mcast) */
+uint dhd_sysioc = TRUE;
+module_param(dhd_sysioc, uint, 0);
+
+/* Error bits */
+module_param(dhd_msg_level, int, 0);
+#if defined(CONFIG_WIRELESS_EXT)
+module_param(iw_msg_level, int, 0);
+#endif
+#ifdef WL_CFG80211
+module_param(wl_dbg_level, int, 0);
+#endif
+//module_param(android_msg_level, int, 0);
+
+/* Disable Prop tx */
+module_param(disable_proptx, int, 0644);
+
+/* load firmware and/or nvram values from the filesystem */
+module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0660);
+module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0);
+
+/* Watchdog interval */
+uint dhd_watchdog_ms = 10;
+module_param(dhd_watchdog_ms, uint, 0);
+
+#if defined(DHD_DEBUG)
+/* Console poll interval */
+uint dhd_console_ms = 0;
+module_param(dhd_console_ms, uint, 0644);
+#endif /* defined(DHD_DEBUG) */
+
+uint dhd_slpauto = TRUE;
+module_param(dhd_slpauto, uint, 0);
+
+/* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */
+uint dhd_arp_mode = ARP_OL_AGENT | ARP_OL_PEER_AUTO_REPLY;
+module_param(dhd_arp_mode, uint, 0);
+
+/* ARP offload enable */
+uint dhd_arp_enable = TRUE;
+module_param(dhd_arp_enable, uint, 0);
+
+#ifdef PKT_FILTER_SUPPORT
+/* Global Pkt filter enable control */
+uint dhd_pkt_filter_enable = TRUE;
+module_param(dhd_pkt_filter_enable, uint, 0);
+#endif
+
+/* Pkt filter init setup */
+uint dhd_pkt_filter_init = 0;
+module_param(dhd_pkt_filter_init, uint, 0);
+
+/* Pkt filter mode control */
+#ifdef GAN_LITE_NAT_KEEPALIVE_FILTER
+uint dhd_master_mode = FALSE;
+#else
+uint dhd_master_mode = TRUE;
+#endif /* GAL_LITE_NAT_KEEPALIVE_FILTER */
+module_param(dhd_master_mode, uint, 0);
+
+#ifdef DHDTHREAD
+int dhd_watchdog_prio = 0;
+module_param(dhd_watchdog_prio, int, 0);
+
+/* DPC thread priority */
+int dhd_dpc_prio = CUSTOM_DPC_PRIO_SETTING;
+module_param(dhd_dpc_prio, int, 0);
+
+/* DPC thread priority, -1 to use tasklet */
+extern int dhd_dongle_memsize;
+module_param(dhd_dongle_memsize, int, 0);
+#endif /* DHDTHREAD */
+/* Control fw roaming */
+uint dhd_roam_disable = 0;
+
+/* Control radio state */
+uint dhd_radio_up = 1;
+
+/* Network inteface name */
+char iface_name[IFNAMSIZ] = {'\0'};
+module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
+
+/* The following are specific to the SDIO dongle */
+
+/* IOCTL response timeout */
+int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT;
+
+/* Idle timeout for backplane clock */
+int dhd_idletime = DHD_IDLETIME_TICKS;
+module_param(dhd_idletime, int, 0);
+
+/* Use polling */
+uint dhd_poll = FALSE;
+module_param(dhd_poll, uint, 0);
+
+/* Use interrupts */
+uint dhd_intr = TRUE;
+module_param(dhd_intr, uint, 0);
+
+/* SDIO Drive Strength (in milliamps) */
+uint dhd_sdiod_drive_strength = 6;
+module_param(dhd_sdiod_drive_strength, uint, 0);
+
+/* Tx/Rx bounds */
+extern uint dhd_txbound;
+extern uint dhd_rxbound;
+module_param(dhd_txbound, uint, 0);
+module_param(dhd_rxbound, uint, 0);
+
+/* Deferred transmits */
+extern uint dhd_deferred_tx;
+module_param(dhd_deferred_tx, uint, 0);
+
+#ifdef BCMDBGFS
+extern void dhd_dbg_init(dhd_pub_t *dhdp);
+extern void dhd_dbg_remove(void);
+#endif /* BCMDBGFS */
+
+/*
+ * the the 2 vars init at init time
+ *benn@cubietech.com
+ */
+#define WL_HOST_WAKE_DEF_GPIO 2
+int wl_host_wake_irqno = -1;
+int wl_host_wake = -1;
+
+
+#ifdef SDTEST
+/* Echo packet generator (pkts/s) */
+uint dhd_pktgen = 0;
+module_param(dhd_pktgen, uint, 0);
+
+/* Echo packet len (0 => sawtooth, max 2040) */
+uint dhd_pktgen_len = 0;
+module_param(dhd_pktgen_len, uint, 0);
+#endif /* SDTEST */
+
+/* Version string to report */
+#ifdef DHD_DEBUG
+#ifndef SRCBASE
+#define SRCBASE "drivers/net/wireless/ap6210"
+#endif
+#define DHD_COMPILED "\nCompiled in " SRCBASE
+#else
+#define DHD_COMPILED
+#endif /* DHD_DEBUG */
+
+static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR ".";
+#ifdef DHD_DEBUG
+static char dhd_version_info[] = "Compiled in " SRCBASE " on " __DATE__ " at " __TIME__ ".";
+#endif
+
+static void dhd_net_if_lock_local(dhd_info_t *dhd);
+static void dhd_net_if_unlock_local(dhd_info_t *dhd);
+static void dhd_suspend_lock(dhd_pub_t *dhdp);
+static void dhd_suspend_unlock(dhd_pub_t *dhdp);
+
+#ifdef WLMEDIA_HTSF
+void htsf_update(dhd_info_t *dhd, void *data);
+tsf_t prev_tsf, cur_tsf;
+
+uint32 dhd_get_htsf(dhd_info_t *dhd, int ifidx);
+static int dhd_ioctl_htsf_get(dhd_info_t *dhd, int ifidx);
+static void dhd_dump_latency(void);
+static void dhd_htsf_addtxts(dhd_pub_t *dhdp, void *pktbuf);
+static void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf);
+static void dhd_dump_htsfhisto(histo_t *his, char *s);
+#endif /* WLMEDIA_HTSF */
+
+/* Monitor interface */
+int dhd_monitor_init(void *dhd_pub);
+int dhd_monitor_uninit(void);
+
+
+#if defined(CONFIG_WIRELESS_EXT)
+struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev);
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+static void dhd_dpc(ulong data);
+/* forward decl */
+extern int dhd_wait_pend8021x(struct net_device *dev);
+
+#ifdef TOE
+#ifndef BDC
+#error TOE requires BDC
+#endif /* !BDC */
+static int dhd_toe_get(dhd_info_t *dhd, int idx, uint32 *toe_ol);
+static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol);
+#endif /* TOE */
+
+static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
+ wl_event_msg_t *event_ptr, void **data_ptr);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
+static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored)
+{
+ int ret = NOTIFY_DONE;
+
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) || (LINUX_VERSION_CODE <= \
+ KERNEL_VERSION(2, 6, 39))
+ switch (action) {
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ dhd_mmc_suspend = TRUE;
+ ret = NOTIFY_OK;
+ break;
+ case PM_POST_HIBERNATION:
+ case PM_POST_SUSPEND:
+ dhd_mmc_suspend = FALSE;
+ ret = NOTIFY_OK;
+ break;
+ }
+ smp_mb();
+#endif
+ return ret;
+}
+
+static struct notifier_block dhd_sleep_pm_notifier = {
+ .notifier_call = dhd_sleep_pm_callback,
+ .priority = 10
+};
+extern int register_pm_notifier(struct notifier_block *nb);
+extern int unregister_pm_notifier(struct notifier_block *nb);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
+
+void dhd_set_packet_filter(dhd_pub_t *dhd)
+{
+#ifdef PKT_FILTER_SUPPORT
+ int i;
+
+ AP6210_DEBUG("%s: enter\n", __FUNCTION__);
+ if (dhd_pkt_filter_enable) {
+ for (i = 0; i < dhd->pktfilter_count; i++) {
+ dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]);
+ }
+ }
+#endif /* PKT_FILTER_SUPPORT */
+}
+
+void dhd_enable_packet_filter(int value, dhd_pub_t *dhd)
+{
+#ifdef PKT_FILTER_SUPPORT
+ int i;
+
+ AP6210_DEBUG("%s: enter, value = %d\n", __FUNCTION__, value);
+ /* 1 - Enable packet filter, only allow unicast packet to send up */
+ /* 0 - Disable packet filter */
+ if (dhd_pkt_filter_enable && (!value ||
+ (dhd_support_sta_mode(dhd) && !dhd->dhcp_in_progress))) {
+ for (i = 0; i < dhd->pktfilter_count; i++) {
+#ifdef PASS_ARP_PACKET
+ if (value && (i == dhd->pktfilter_count -1) &&
+ !(dhd->op_mode & (DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE))) {
+ AP6210_DEBUG("Do not turn on ARP white list pkt filter:"
+ "val %d, cnt %d, op_mode 0x%x\n",
+ value, i, dhd->op_mode);
+ continue;
+ }
+#endif
+ dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
+ value, dhd_master_mode);
+ }
+ }
+#endif /* PKT_FILTER_SUPPORT */
+}
+
+static int dhd_set_suspend(int value, dhd_pub_t *dhd)
+{
+#if !defined(SUPPORT_PM2_ONLY)
+ int power_mode = PM_MAX;
+#endif
+ /* wl_pkt_filter_enable_t enable_parm; */
+ char iovbuf[32];
+ int bcn_li_dtim = 0; /* Default bcn_li_dtim in resume mode is 0 */
+#ifndef DISABLE_FW_ROAM_SUSPEND
+ uint roamvar = 1;
+#endif
+#ifdef ENABLE_BCN_LI_BCN_WAKEUP
+ int bcn_li_bcn;
+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */
+#ifdef PASS_ALL_MCAST_PKTS
+ struct dhd_info *dhdinfo = dhd->info;
+ uint32 allmulti;
+ uint i;
+#endif /* PASS_ALL_MCAST_PKTS */
+
+ AP6210_DEBUG("%s: enter, value = %d in_suspend=%d\n",
+ __FUNCTION__, value, dhd->in_suspend);
+
+ dhd_suspend_lock(dhd);
+ if (dhd && dhd->up) {
+ if (value && dhd->in_suspend) {
+#ifdef PKT_FILTER_SUPPORT
+ dhd->early_suspended = 1;
+#endif
+ /* Kernel suspended */
+ AP6210_ERR("%s: force extra Suspend setting\n", __FUNCTION__);
+
+#if !defined(SUPPORT_PM2_ONLY)
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
+ sizeof(power_mode), TRUE, 0);
+#endif
+ /* Enable packet filter, only allow unicast packet to send up */
+ dhd_enable_packet_filter(1, dhd);
+#ifdef PASS_ALL_MCAST_PKTS
+ allmulti = 0;
+ bcm_mkiovar("allmulti", (char *)&allmulti,
+ 4, iovbuf, sizeof(iovbuf));
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net)
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
+ sizeof(iovbuf), TRUE, i);
+ }
+#endif /* PASS_ALL_MCAST_PKTS */
+
+ /* If DTIM skip is set up as default, force it to wake
+ * each third DTIM for better power savings. Note that
+ * one side effect is a chance to miss BC/MC packet.
+ */
+ bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd);
+ bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
+ 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+
+#ifndef DISABLE_FW_ROAM_SUSPEND
+ /* Disable firmware roaming during suspend */
+ bcm_mkiovar("roam_off", (char *)&roamvar, 4,
+ iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif
+#ifdef ENABLE_BCN_LI_BCN_WAKEUP
+ bcn_li_bcn = 0;
+ bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn,
+ 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */
+
+ } else {
+#ifdef PKT_FILTER_SUPPORT
+ dhd->early_suspended = 0;
+#endif
+ /* Kernel resumed */
+ AP6210_ERR("%s: Remove extra suspend setting\n", __FUNCTION__);
+
+#if !defined(SUPPORT_PM2_ONLY)
+ power_mode = PM_FAST;
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
+ sizeof(power_mode), TRUE, 0);
+#endif
+ /* disable pkt filter */
+ dhd_enable_packet_filter(0, dhd);
+#ifdef PASS_ALL_MCAST_PKTS
+ allmulti = 1;
+ bcm_mkiovar("allmulti", (char *)&allmulti,
+ 4, iovbuf, sizeof(iovbuf));
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net)
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
+ sizeof(iovbuf), TRUE, i);
+ }
+#endif /* PASS_ALL_MCAST_PKTS */
+
+ /* restore pre-suspend setting for dtim_skip */
+ bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
+ 4, iovbuf, sizeof(iovbuf));
+
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#ifndef DISABLE_FW_ROAM_SUSPEND
+ roamvar = dhd_roam_disable;
+ bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf,
+ sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif
+#ifdef ENABLE_BCN_LI_BCN_WAKEUP
+ bcn_li_bcn = 1;
+ bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn,
+ 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */
+
+ }
+ }
+
+ dhd_suspend_unlock(dhd);
+ return 0;
+}
+
+static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force)
+{
+ dhd_pub_t *dhdp = &dhd->pub;
+ int ret = 0;
+
+ DHD_OS_WAKE_LOCK(dhdp);
+ /* Set flag when early suspend was called */
+ dhdp->in_suspend = val;
+ if ((force || !dhdp->suspend_disable_flag) &&
+ dhd_support_sta_mode(dhdp))
+ {
+ ret = dhd_set_suspend(val, dhdp);
+ }
+
+ DHD_OS_WAKE_UNLOCK(dhdp);
+ return ret;
+}
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+static void dhd_early_suspend(struct early_suspend *h)
+{
+ struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
+ AP6210_DEBUG("%s: enter\n", __FUNCTION__);
+
+ if (dhd)
+ dhd_suspend_resume_helper(dhd, 1, 0);
+}
+
+static void dhd_late_resume(struct early_suspend *h)
+{
+ struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
+ AP6210_DEBUG("%s: enter\n", __FUNCTION__);
+
+ if (dhd)
+ dhd_suspend_resume_helper(dhd, 0, 0);
+}
+#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */
+
+/*
+ * Generalized timeout mechanism. Uses spin sleep with exponential back-off until
+ * the sleep time reaches one jiffy, then switches over to task delay. Usage:
+ *
+ * dhd_timeout_start(&tmo, usec);
+ * while (!dhd_timeout_expired(&tmo))
+ * if (poll_something())
+ * break;
+ * if (dhd_timeout_expired(&tmo))
+ * fatal();
+ */
+
+void
+dhd_timeout_start(dhd_timeout_t *tmo, uint usec)
+{
+ tmo->limit = usec;
+ tmo->increment = 0;
+ tmo->elapsed = 0;
+ tmo->tick = jiffies_to_usecs(1);
+}
+
+int
+dhd_timeout_expired(dhd_timeout_t *tmo)
+{
+ /* Does nothing the first call */
+ if (tmo->increment == 0) {
+ tmo->increment = 1;
+ return 0;
+ }
+
+ if (tmo->elapsed >= tmo->limit)
+ return 1;
+
+ /* Add the delay that's about to take place */
+ tmo->elapsed += tmo->increment;
+
+ if (tmo->increment < tmo->tick) {
+ OSL_DELAY(tmo->increment);
+ tmo->increment *= 2;
+ if (tmo->increment > tmo->tick)
+ tmo->increment = tmo->tick;
+ } else {
+ wait_queue_head_t delay_wait;
+ DECLARE_WAITQUEUE(wait, current);
+ init_waitqueue_head(&delay_wait);
+ add_wait_queue(&delay_wait, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ remove_wait_queue(&delay_wait, &wait);
+ set_current_state(TASK_RUNNING);
+ }
+
+ return 0;
+}
+
+int
+dhd_net2idx(dhd_info_t *dhd, struct net_device *net)
+{
+ int i = 0;
+
+ ASSERT(dhd);
+ while (i < DHD_MAX_IFS) {
+ if (dhd->iflist[i] && (dhd->iflist[i]->net == net))
+ return i;
+ i++;
+ }
+
+ return DHD_BAD_IF;
+}
+
+struct net_device * dhd_idx2net(void *pub, int ifidx)
+{
+ struct dhd_pub *dhd_pub = (struct dhd_pub *)pub;
+ struct dhd_info *dhd_info;
+
+ if (!dhd_pub || ifidx < 0 || ifidx >= DHD_MAX_IFS)
+ return NULL;
+ dhd_info = dhd_pub->info;
+ if (dhd_info && dhd_info->iflist[ifidx])
+ return dhd_info->iflist[ifidx]->net;
+ return NULL;
+}
+
+int
+dhd_ifname2idx(dhd_info_t *dhd, char *name)
+{
+ int i = DHD_MAX_IFS;
+
+ ASSERT(dhd);
+
+ if (name == NULL || *name == '\0')
+ return 0;
+
+ while (--i > 0)
+ if (dhd->iflist[i] && !strncmp(dhd->iflist[i]->name, name, IFNAMSIZ))
+ break;
+
+ AP6210_DEBUG("%s: return idx %d for \"%s\"\n", __FUNCTION__, i, name);
+
+ return i; /* default - the primary interface */
+}
+
+char *
+dhd_ifname(dhd_pub_t *dhdp, int ifidx)
+{
+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+
+ ASSERT(dhd);
+
+ if (ifidx < 0 || ifidx >= DHD_MAX_IFS) {
+ AP6210_ERR("%s: ifidx %d out of range\n", __FUNCTION__, ifidx);
+ return "<if_bad>";
+ }
+
+ if (dhd->iflist[ifidx] == NULL) {
+ AP6210_ERR("%s: null i/f %d\n", __FUNCTION__, ifidx);
+ return "<if_null>";
+ }
+
+ if (dhd->iflist[ifidx]->net)
+ return dhd->iflist[ifidx]->net->name;
+
+ return "<if_none>";
+}
+
+uint8 *
+dhd_bssidx2bssid(dhd_pub_t *dhdp, int idx)
+{
+ int i;
+ dhd_info_t *dhd = (dhd_info_t *)dhdp;
+
+ ASSERT(dhd);
+ for (i = 0; i < DHD_MAX_IFS; i++)
+ if (dhd->iflist[i] && dhd->iflist[i]->bssidx == idx)
+ return dhd->iflist[i]->mac_addr;
+
+ return NULL;
+}
+
+
+static void
+_dhd_set_multicast_list(dhd_info_t *dhd, int ifidx)
+{
+ struct net_device *dev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+ struct netdev_hw_addr *ha;
+#else
+ struct dev_mc_list *mclist;
+#endif
+ uint32 allmulti, cnt;
+
+ wl_ioctl_t ioc;
+ char *buf, *bufp;
+ uint buflen;
+ int ret;
+
+ ASSERT(dhd && dhd->iflist[ifidx]);
+ dev = dhd->iflist[ifidx]->net;
+ if (!dev)
+ return;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ netif_addr_lock_bh(dev);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+ cnt = netdev_mc_count(dev);
+#else
+ cnt = dev->mc_count;
+#endif /* LINUX_VERSION_CODE */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ netif_addr_unlock_bh(dev);
+#endif
+
+ /* Determine initial value of allmulti flag */
+ allmulti = (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE;
+#ifdef PASS_ALL_MCAST_PKTS
+#ifdef PKT_FILTER_SUPPORT
+ if (!dhd->pub.early_suspended)
+#endif /* PKT_FILTER_SUPPORT */
+ allmulti = TRUE;
+#endif /* PASS_ALL_MCAST_PKTS */
+
+ /* Send down the multicast list first. */
+
+
+ buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETHER_ADDR_LEN);
+ if (!(bufp = buf = MALLOC(dhd->pub.osh, buflen))) {
+ AP6210_ERR("%s: out of memory for mcast_list, cnt %d\n",
+ dhd_ifname(&dhd->pub, ifidx), cnt);
+ return;
+ }
+
+ strncpy(bufp, "mcast_list", buflen - 1);
+ bufp[buflen - 1] = '\0';
+ bufp += strlen("mcast_list") + 1;
+
+ cnt = htol32(cnt);
+ memcpy(bufp, &cnt, sizeof(cnt));
+ bufp += sizeof(cnt);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ netif_addr_lock_bh(dev);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+ netdev_for_each_mc_addr(ha, dev) {
+ if (!cnt)
+ break;
+ memcpy(bufp, ha->addr, ETHER_ADDR_LEN);
+ bufp += ETHER_ADDR_LEN;
+ cnt--;
+ }
+#else
+ for (mclist = dev->mc_list; (mclist && (cnt > 0));
+ cnt--, mclist = mclist->next) {
+ memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN);
+ bufp += ETHER_ADDR_LEN;
+ }
+#endif /* LINUX_VERSION_CODE */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ netif_addr_unlock_bh(dev);
+#endif
+
+ memset(&ioc, 0, sizeof(ioc));
+ ioc.cmd = WLC_SET_VAR;
+ ioc.buf = buf;
+ ioc.len = buflen;
+ ioc.set = TRUE;
+
+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+ if (ret < 0) {
+ AP6210_ERR("%s: set mcast_list failed, cnt %d\n",
+ dhd_ifname(&dhd->pub, ifidx), cnt);
+ allmulti = cnt ? TRUE : allmulti;
+ }
+
+ MFREE(dhd->pub.osh, buf, buflen);
+
+ /* Now send the allmulti setting. This is based on the setting in the
+ * net_device flags, but might be modified above to be turned on if we
+ * were trying to set some addresses and dongle rejected it...
+ */
+
+ buflen = sizeof("allmulti") + sizeof(allmulti);
+ if (!(buf = MALLOC(dhd->pub.osh, buflen))) {
+ AP6210_ERR("%s: out of memory for allmulti\n", dhd_ifname(&dhd->pub, ifidx));
+ return;
+ }
+ allmulti = htol32(allmulti);
+
+ if (!bcm_mkiovar("allmulti", (void*)&allmulti, sizeof(allmulti), buf, buflen)) {
+ AP6210_ERR("%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
+ dhd_ifname(&dhd->pub, ifidx), (int)sizeof(allmulti), buflen);
+ MFREE(dhd->pub.osh, buf, buflen);
+ return;
+ }
+
+
+ memset(&ioc, 0, sizeof(ioc));
+ ioc.cmd = WLC_SET_VAR;
+ ioc.buf = buf;
+ ioc.len = buflen;
+ ioc.set = TRUE;
+
+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+ if (ret < 0) {
+ AP6210_ERR("%s: set allmulti %d failed\n",
+ dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti));
+ }
+
+ MFREE(dhd->pub.osh, buf, buflen);
+
+ /* Finally, pick up the PROMISC flag as well, like the NIC driver does */
+
+ allmulti = (dev->flags & IFF_PROMISC) ? TRUE : FALSE;
+ allmulti = htol32(allmulti);
+
+ memset(&ioc, 0, sizeof(ioc));
+ ioc.cmd = WLC_SET_PROMISC;
+ ioc.buf = &allmulti;
+ ioc.len = sizeof(allmulti);
+ ioc.set = TRUE;
+
+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+ if (ret < 0) {
+ AP6210_ERR("%s: set promisc %d failed\n",
+ dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti));
+ }
+}
+
+int
+_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr)
+{
+ char buf[32];
+ wl_ioctl_t ioc;
+ int ret;
+
+ if (!bcm_mkiovar("cur_etheraddr", (char*)addr, ETHER_ADDR_LEN, buf, 32)) {
+ AP6210_ERR("%s: mkiovar failed for cur_etheraddr\n", dhd_ifname(&dhd->pub, ifidx));
+ return -1;
+ }
+ memset(&ioc, 0, sizeof(ioc));
+ ioc.cmd = WLC_SET_VAR;
+ ioc.buf = buf;
+ ioc.len = 32;
+ ioc.set = TRUE;
+
+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+ if (ret < 0) {
+ AP6210_ERR("%s: set cur_etheraddr failed\n", dhd_ifname(&dhd->pub, ifidx));
+ } else {
+ memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN);
+ memcpy(dhd->pub.mac.octet, addr, ETHER_ADDR_LEN);
+ }
+
+ return ret;
+}
+
+#ifdef SOFTAP
+extern struct net_device *ap_net_dev;
+extern tsk_ctl_t ap_eth_ctl; /* ap netdev heper thread ctl */
+#endif
+
+static void
+dhd_op_if(dhd_if_t *ifp)
+{
+ dhd_info_t *dhd;
+ int ret = 0, err = 0;
+#ifdef SOFTAP
+ unsigned long flags;
+#endif
+
+ if (!ifp || !ifp->info || !ifp->idx)
+ return;
+ ASSERT(ifp && ifp->info && ifp->idx); /* Virtual interfaces only */
+ dhd = ifp->info;
+
+ AP6210_DEBUG("%s: idx %d, state %d\n", __FUNCTION__, ifp->idx, ifp->state);
+
+#ifdef WL_CFG80211
+ if (wl_cfg80211_is_progress_ifchange())
+ return;
+
+#endif
+ switch (ifp->state) {
+ case DHD_IF_ADD:
+ /*
+ * Delete the existing interface before overwriting it
+ * in case we missed the WLC_E_IF_DEL event.
+ */
+ if (ifp->net != NULL) {
+ AP6210_ERR("%s: ERROR: netdev:%s already exists, try free & unregister \n",
+ __FUNCTION__, ifp->net->name);
+ netif_stop_queue(ifp->net);
+ unregister_netdev(ifp->net);
+ free_netdev(ifp->net);
+ }
+ /* Allocate etherdev, including space for private structure */
+ if (!(ifp->net = alloc_etherdev(sizeof(dhd)))) {
+ AP6210_ERR("%s: OOM - alloc_etherdev\n", __FUNCTION__);
+ ret = -ENOMEM;
+ }
+ if (ret == 0) {
+ strncpy(ifp->net->name, ifp->name, IFNAMSIZ);
+ ifp->net->name[IFNAMSIZ - 1] = '\0';
+ memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
+#ifdef WL_CFG80211
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+ if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, ifp->bssidx,
+ (void*)dhd_net_attach)) {
+ ifp->state = DHD_IF_NONE;
+ ifp->event2cfg80211 = TRUE;
+ return;
+ }
+#endif
+ if ((err = dhd_net_attach(&dhd->pub, ifp->idx)) != 0) {
+ AP6210_ERR("%s: dhd_net_attach failed, err %d\n",
+ __FUNCTION__, err);
+ ret = -EOPNOTSUPP;
+ } else {
+#if defined(SOFTAP)
+ if (ap_fw_loaded && !(dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) {
+ /* semaphore that the soft AP CODE waits on */
+ flags = dhd_os_spin_lock(&dhd->pub);
+
+ /* save ptr to wl0.1 netdev for use in wl_iw.c */
+ ap_net_dev = ifp->net;
+ /* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */
+ up(&ap_eth_ctl.sema);
+ dhd_os_spin_unlock(&dhd->pub, flags);
+ }
+#endif
+ AP6210_DEBUG(" ==== pid:%x, net_device for if:%s created ===\n\n",
+ current->pid, ifp->net->name);
+ ifp->state = DHD_IF_NONE;
+ }
+ }
+ break;
+ case DHD_IF_DEL:
+ /* Make sure that we don't enter again here if .. */
+ /* dhd_op_if is called again from some other context */
+ ifp->state = DHD_IF_DELETING;
+ if (ifp->net != NULL) {
+ AP6210_DEBUG("%s: got 'DHD_IF_DEL' state\n", __FUNCTION__);
+ netif_stop_queue(ifp->net);
+#ifdef WL_CFG80211
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
+ wl_cfg80211_ifdel_ops(ifp->net);
+ }
+#endif
+ unregister_netdev(ifp->net);
+ ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */
+#ifdef WL_CFG80211
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
+ wl_cfg80211_notify_ifdel();
+ }
+#endif
+ }
+ break;
+ case DHD_IF_DELETING:
+ break;
+ default:
+ AP6210_ERR("%s: bad op %d\n", __FUNCTION__, ifp->state);
+ ASSERT(!ifp->state);
+ break;
+ }
+
+ if (ret < 0) {
+ ifp->set_multicast = FALSE;
+ if (ifp->net) {
+ free_netdev(ifp->net);
+ ifp->net = NULL;
+ }
+ dhd->iflist[ifp->idx] = NULL;
+#ifdef SOFTAP
+ flags = dhd_os_spin_lock(&dhd->pub);
+ if (ifp->net == ap_net_dev)
+ ap_net_dev = NULL; /* NULL SOFTAP global wl0.1 as well */
+ dhd_os_spin_unlock(&dhd->pub, flags);
+#endif /* SOFTAP */
+ MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
+ }
+}
+
+static int
+_dhd_sysioc_thread(void *data)
+{
+ tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+ dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
+
+
+ int i;
+#ifdef SOFTAP
+ bool in_ap = FALSE;
+ unsigned long flags;
+#endif
+#ifndef USE_KTHREAD_API
+ DAEMONIZE("dhd_sysioc");
+
+ complete(&tsk->completed);
+#endif
+
+ while (down_interruptible(&tsk->sema) == 0) {
+
+ SMP_RD_BARRIER_DEPENDS();
+ if (tsk->terminated) {
+ break;
+ }
+
+ dhd_net_if_lock_local(dhd);
+ DHD_OS_WAKE_LOCK(&dhd->pub);
+
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ if (dhd->iflist[i]) {
+ AP6210_DEBUG("%s: interface %d\n", __FUNCTION__, i);
+#ifdef SOFTAP
+ flags = dhd_os_spin_lock(&dhd->pub);
+ in_ap = (ap_net_dev != NULL);
+ dhd_os_spin_unlock(&dhd->pub, flags);
+#endif /* SOFTAP */
+ if (dhd->iflist[i] && dhd->iflist[i]->state)
+ dhd_op_if(dhd->iflist[i]);
+
+ if (dhd->iflist[i] == NULL) {
+ AP6210_DEBUG("%s: interface %d just been removed,!\n", __FUNCTION__, i);
+ continue;
+ }
+#ifdef SOFTAP
+ if (in_ap && dhd->set_macaddress == i+1) {
+ AP6210_DEBUG("attempt to set MAC for %s in AP Mode,"
+ "blocked. \n", dhd->iflist[i]->net->name);
+ dhd->set_macaddress = 0;
+ continue;
+ }
+
+ if (in_ap && dhd->iflist[i]->set_multicast) {
+ AP6210_DEBUG("attempt to set MULTICAST list for %s"
+ "in AP Mode, blocked. \n", dhd->iflist[i]->net->name);
+ dhd->iflist[i]->set_multicast = FALSE;
+ continue;
+ }
+#endif /* SOFTAP */
+ if (dhd->pub.up == 0)
+ continue;
+ if (dhd->iflist[i]->set_multicast) {
+ dhd->iflist[i]->set_multicast = FALSE;
+ _dhd_set_multicast_list(dhd, i);
+ }
+ if (dhd->set_macaddress == i+1) {
+ dhd->set_macaddress = 0;
+ if (_dhd_set_mac_address(dhd, i, &dhd->macvalue) == 0) {
+ AP6210_DEBUG(
+ "dhd_sysioc_thread: MACID is overwritten\n");
+ } else {
+ AP6210_ERR(
+ "dhd_sysioc_thread: _dhd_set_mac_address() failed\n");
+ }
+ }
+ }
+ }
+
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ dhd_net_if_unlock_local(dhd);
+ }
+ AP6210_DEBUG("%s: stopped\n", __FUNCTION__);
+ complete_and_exit(&tsk->completed, 0);
+}
+
+static int
+dhd_set_mac_address(struct net_device *dev, void *addr)
+{
+ int ret = 0;
+
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ struct sockaddr *sa = (struct sockaddr *)addr;
+ int ifidx;
+
+ ifidx = dhd_net2idx(dhd, dev);
+ if (ifidx == DHD_BAD_IF)
+ return -1;
+
+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0);
+ memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN);
+ dhd->set_macaddress = ifidx+1;
+ up(&dhd->thr_sysioc_ctl.sema);
+
+ return ret;
+}
+
+static void
+dhd_set_multicast_list(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ifidx;
+
+ ifidx = dhd_net2idx(dhd, dev);
+ if (ifidx == DHD_BAD_IF)
+ return;
+
+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0);
+ dhd->iflist[ifidx]->set_multicast = TRUE;
+ up(&dhd->thr_sysioc_ctl.sema);
+}
+
+#ifdef PROP_TXSTATUS
+int
+dhd_os_wlfc_block(dhd_pub_t *pub)
+{
+ dhd_info_t *di = (dhd_info_t *)(pub->info);
+ ASSERT(di != NULL);
+ spin_lock_bh(&di->wlfc_spinlock);
+ return 1;
+}
+
+int
+dhd_os_wlfc_unblock(dhd_pub_t *pub)
+{
+ dhd_info_t *di = (dhd_info_t *)(pub->info);
+
+ ASSERT(di != NULL);
+ spin_unlock_bh(&di->wlfc_spinlock);
+ return 1;
+}
+
+const uint8 wme_fifo2ac[] = { 0, 1, 2, 3, 1, 1 };
+uint8 prio2fifo[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
+#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]]
+
+#endif /* PROP_TXSTATUS */
+int
+dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
+{
+ int ret;
+ dhd_info_t *dhd = (dhd_info_t *)(dhdp->info);
+ struct ether_header *eh = NULL;
+
+ /* Reject if down */
+ if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) {
+ /* free the packet here since the caller won't */
+ PKTFREE(dhdp->osh, pktbuf, TRUE);
+ return -ENODEV;
+ }
+
+ /* Update multicast statistic */
+ if (PKTLEN(dhdp->osh, pktbuf) >= ETHER_HDR_LEN) {
+ uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf);
+ eh = (struct ether_header *)pktdata;
+
+ if (ETHER_ISMULTI(eh->ether_dhost))
+ dhdp->tx_multicast++;
+ if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X)
+ atomic_inc(&dhd->pend_8021x_cnt);
+ } else {
+ PKTFREE(dhd->pub.osh, pktbuf, TRUE);
+ return BCME_ERROR;
+ }
+
+ /* Look into the packet and update the packet priority */
+#ifndef PKTPRIO_OVERRIDE
+ if (PKTPRIO(pktbuf) == 0)
+#endif
+ pktsetprio(pktbuf, FALSE);
+
+#ifdef PROP_TXSTATUS
+ if (dhdp->wlfc_state) {
+ /* store the interface ID */
+ DHD_PKTTAG_SETIF(PKTTAG(pktbuf), ifidx);
+
+ /* store destination MAC in the tag as well */
+ DHD_PKTTAG_SETDSTN(PKTTAG(pktbuf), eh->ether_dhost);
+
+ /* decide which FIFO this packet belongs to */
+ if (ETHER_ISMULTI(eh->ether_dhost))
+ /* one additional queue index (highest AC + 1) is used for bc/mc queue */
+ DHD_PKTTAG_SETFIFO(PKTTAG(pktbuf), AC_COUNT);
+ else
+ DHD_PKTTAG_SETFIFO(PKTTAG(pktbuf), WME_PRIO2AC(PKTPRIO(pktbuf)));
+ } else
+#endif /* PROP_TXSTATUS */
+ /* If the protocol uses a data header, apply it */
+ dhd_prot_hdrpush(dhdp, ifidx, pktbuf);
+
+ /* Use bus module to send data frame */
+#ifdef WLMEDIA_HTSF
+ dhd_htsf_addtxts(dhdp, pktbuf);
+#endif
+#ifdef PROP_TXSTATUS
+ dhd_os_wlfc_block(dhdp);
+ if (dhdp->wlfc_state && ((athost_wl_status_info_t*)dhdp->wlfc_state)->proptxstatus_mode
+ != WLFC_FCMODE_NONE) {
+ ret = dhd_wlfc_enque_sendq(dhdp->wlfc_state, DHD_PKTTAG_FIFO(PKTTAG(pktbuf)),
+ pktbuf);
+ dhd_wlfc_commit_packets(dhdp->wlfc_state, (f_commitpkt_t)dhd_bus_txdata,
+ dhdp->bus);
+ if (((athost_wl_status_info_t*)dhdp->wlfc_state)->toggle_host_if) {
+ ((athost_wl_status_info_t*)dhdp->wlfc_state)->toggle_host_if = 0;
+ }
+ dhd_os_wlfc_unblock(dhdp);
+ }
+ else {
+ dhd_os_wlfc_unblock(dhdp);
+ /* non-proptxstatus way */
+ ret = dhd_bus_txdata(dhdp->bus, pktbuf, FALSE);
+ }
+#else
+ ret = dhd_bus_txdata(dhdp->bus, pktbuf, FALSE);
+#endif /* PROP_TXSTATUS */
+
+ return ret;
+}
+
+int
+dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
+{
+ int ret;
+ void *pktbuf;
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
+ int ifidx;
+#ifdef WLMEDIA_HTSF
+ uint8 htsfdlystat_sz = dhd->pub.htsfdlystat_sz;
+#else
+ uint8 htsfdlystat_sz = 0;
+#endif
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ DHD_OS_WAKE_LOCK(&dhd->pub);
+
+ /* Reject if down */
+ if (dhd->pub.busstate == DHD_BUS_DOWN || dhd->pub.hang_was_sent) {
+ AP6210_ERR("%s: xmit rejected pub.up=%d busstate=%d \n",
+ __FUNCTION__, dhd->pub.up, dhd->pub.busstate);
+ netif_stop_queue(net);
+ /* Send Event when bus down detected during data session */
+ if (dhd->pub.up) {
+ AP6210_ERR("%s: Event HANG sent up\n", __FUNCTION__);
+ net_os_send_hang_message(net);
+ }
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
+ return -ENODEV;
+#else
+ return NETDEV_TX_BUSY;
+#endif
+ }
+
+ ifidx = dhd_net2idx(dhd, net);
+ if (ifidx == DHD_BAD_IF) {
+ AP6210_ERR("%s: bad ifidx %d\n", __FUNCTION__, ifidx);
+ netif_stop_queue(net);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
+ return -ENODEV;
+#else
+ return NETDEV_TX_BUSY;
+#endif
+ }
+
+ /* Make sure there's enough room for any header */
+
+ if (skb_headroom(skb) < dhd->pub.hdrlen + htsfdlystat_sz) {
+ struct sk_buff *skb2;
+
+ AP6210_DEBUG("%s: insufficient headroom\n",
+ dhd_ifname(&dhd->pub, ifidx));
+ dhd->pub.tx_realloc++;
+
+ skb2 = skb_realloc_headroom(skb, dhd->pub.hdrlen + htsfdlystat_sz);
+
+ dev_kfree_skb(skb);
+ if ((skb = skb2) == NULL) {
+ AP6210_ERR("%s: skb_realloc_headroom failed\n",
+ dhd_ifname(&dhd->pub, ifidx));
+ ret = -ENOMEM;
+ goto done;
+ }
+ }
+
+ /* Convert to packet */
+ if (!(pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb))) {
+ AP6210_ERR("%s: PKTFRMNATIVE failed\n",
+ dhd_ifname(&dhd->pub, ifidx));
+ dev_kfree_skb_any(skb);
+ ret = -ENOMEM;
+ goto done;
+ }
+#ifdef WLMEDIA_HTSF
+ if (htsfdlystat_sz && PKTLEN(dhd->pub.osh, pktbuf) >= ETHER_ADDR_LEN) {
+ uint8 *pktdata = (uint8 *)PKTDATA(dhd->pub.osh, pktbuf);
+ struct ether_header *eh = (struct ether_header *)pktdata;
+
+ if (!ETHER_ISMULTI(eh->ether_dhost) &&
+ (ntoh16(eh->ether_type) == ETHER_TYPE_IP)) {
+ eh->ether_type = hton16(ETHER_TYPE_BRCM_PKTDLYSTATS);
+ }
+ }
+#endif
+
+ ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf);
+
+
+done:
+ if (ret)
+ dhd->pub.dstats.tx_dropped++;
+ else
+ dhd->pub.tx_packets++;
+
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+ /* Return ok: we always eat the packet */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
+ return 0;
+#else
+ return NETDEV_TX_OK;
+#endif
+}
+
+void
+dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state)
+{
+ struct net_device *net;
+ dhd_info_t *dhd = dhdp->info;
+ int i;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ ASSERT(dhd);
+
+ if (ifidx == ALL_INTERFACES) {
+ /* Flow control on all active interfaces */
+ dhdp->txoff = state;
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ if (dhd->iflist[i]) {
+ net = dhd->iflist[i]->net;
+ if (state == ON)
+ netif_stop_queue(net);
+ else
+ netif_wake_queue(net);
+ }
+ }
+ }
+ else {
+ if (dhd->iflist[ifidx]) {
+ net = dhd->iflist[ifidx]->net;
+ if (state == ON)
+ netif_stop_queue(net);
+ else
+ netif_wake_queue(net);
+ }
+ }
+}
+
+#ifdef DHD_RX_DUMP
+typedef struct {
+ uint16 type;
+ const char *str;
+} PKTTYPE_INFO;
+
+static const PKTTYPE_INFO packet_type_info[] =
+{
+ { ETHER_TYPE_IP, "IP" },
+ { ETHER_TYPE_ARP, "ARP" },
+ { ETHER_TYPE_BRCM, "BRCM" },
+ { ETHER_TYPE_802_1X, "802.1X" },
+ { ETHER_TYPE_WAI, "WAPI" },
+ { 0, ""}
+};
+
+static const char *_get_packet_type_str(uint16 type)
+{
+ int i;
+ int n = sizeof(packet_type_info)/sizeof(packet_type_info[1]) - 1;
+
+ for (i = 0; i < n; i++) {
+ if (packet_type_info[i].type == type)
+ return packet_type_info[i].str;
+ }
+
+ return packet_type_info[n].str;
+}
+#endif /* DHD_RX_DUMP */
+
+void
+dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
+{
+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+ struct sk_buff *skb;
+ uchar *eth;
+ uint len;
+ void *data, *pnext = NULL;
+ int i;
+ dhd_if_t *ifp;
+ wl_event_msg_t event;
+ int tout_rx = 0;
+ int tout_ctrl = 0;
+
+#ifdef DHD_RX_DUMP
+#ifdef DHD_RX_FULL_DUMP
+ int k;
+#endif /* DHD_RX_FULL_DUMP */
+ char *dump_data;
+ uint16 protocol;
+#endif /* DHD_RX_DUMP */
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) {
+#ifdef WLBTAMP
+ struct ether_header *eh;
+ struct dot11_llc_snap_header *lsh;
+#endif
+
+ ifp = dhd->iflist[ifidx];
+ if (ifp == NULL) {
+ AP6210_ERR("%s: ifp is NULL. drop packet\n",
+ __FUNCTION__);
+ PKTFREE(dhdp->osh, pktbuf, TRUE);
+ continue;
+ }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+ /* Dropping packets before registering net device to avoid kernel panic */
+#ifndef PROP_TXSTATUS_VSDB
+ if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED) {
+#else
+ if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED || !dhd->pub.up) {
+#endif /* PROP_TXSTATUS_VSDB */
+ AP6210_ERR("%s: net device is NOT registered yet. drop packet\n",
+ __FUNCTION__);
+ PKTFREE(dhdp->osh, pktbuf, TRUE);
+ continue;
+ }
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */
+
+ pnext = PKTNEXT(dhdp->osh, pktbuf);
+ PKTSETNEXT(wl->sh.osh, pktbuf, NULL);
+
+#ifdef WLBTAMP
+ eh = (struct ether_header *)PKTDATA(wl->sh.osh, pktbuf);
+ lsh = (struct dot11_llc_snap_header *)&eh[1];
+
+ if ((ntoh16(eh->ether_type) < ETHER_TYPE_MIN) &&
+ (PKTLEN(wl->sh.osh, pktbuf) >= RFC1042_HDR_LEN) &&
+ bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 &&
+ lsh->type == HTON16(BTA_PROT_L2CAP)) {
+ amp_hci_ACL_data_t *ACL_data = (amp_hci_ACL_data_t *)
+ ((uint8 *)eh + RFC1042_HDR_LEN);
+ ACL_data = NULL;
+ }
+#endif /* WLBTAMP */
+
+#ifdef PROP_TXSTATUS
+ if (dhdp->wlfc_state && PKTLEN(wl->sh.osh, pktbuf) == 0) {
+ /* WLFC may send header only packet when
+ there is an urgent message but no packet to
+ piggy-back on
+ */
+ ((athost_wl_status_info_t*)dhdp->wlfc_state)->stats.wlfc_header_only_pkt++;
+ PKTFREE(dhdp->osh, pktbuf, TRUE);
+ continue;
+ }
+#endif
+
+ skb = PKTTONATIVE(dhdp->osh, pktbuf);
+
+ /* Get the protocol, maintain skb around eth_type_trans()
+ * The main reason for this hack is for the limitation of
+ * Linux 2.4 where 'eth_type_trans' uses the 'net->hard_header_len'
+ * to perform skb_pull inside vs ETH_HLEN. Since to avoid
+ * coping of the packet coming from the network stack to add
+ * BDC, Hardware header etc, during network interface registration
+ * we set the 'net->hard_header_len' to ETH_HLEN + extra space required
+ * for BDC, Hardware header etc. and not just the ETH_HLEN
+ */
+ eth = skb->data;
+ len = skb->len;
+
+#ifdef DHD_RX_DUMP
+ dump_data = skb->data;
+ protocol = (dump_data[12] << 8) | dump_data[13];
+ AP6210_ERR("RX DUMP - %s\n", _get_packet_type_str(protocol));
+
+#ifdef DHD_RX_FULL_DUMP
+ if (protocol != ETHER_TYPE_BRCM) {
+ for (k = 0; k < skb->len; k++) {
+ AP6210_ERR("%02X ", dump_data[k]));
+ if ((k & 15) == 15)
+ AP6210_ERR("\n");
+ }
+ AP6210_ERR("\n");
+ }
+#endif /* DHD_RX_FULL_DUMP */
+
+ if (protocol != ETHER_TYPE_BRCM) {
+ if (dump_data[0] == 0xFF) {
+ AP6210_ERR("%s: BROADCAST\n", __FUNCTION__);
+
+ if ((dump_data[12] == 8) &&
+ (dump_data[13] == 6)) {
+ AP6210_ERR("%s: ARP %d\n",
+ __FUNCTION__, dump_data[0x15]);
+ }
+ } else if (dump_data[0] & 1) {
+ AP6210_ERR("%s: MULTICAST: " MACDBG "\n",
+ __FUNCTION__, MAC2STRDBG(dump_data));
+ }
+
+ if (protocol == ETHER_TYPE_802_1X) {
+ AP6210_ERR("ETHER_TYPE_802_1X: "
+ "ver %d, type %d, replay %d\n",
+ dump_data[14], dump_data[15],
+ dump_data[30]);
+ }
+ }
+
+#endif /* DHD_RX_DUMP */
+
+ ifp = dhd->iflist[ifidx];
+ if (ifp == NULL)
+ ifp = dhd->iflist[0];
+
+ ASSERT(ifp);
+ skb->dev = ifp->net;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ if (skb->pkt_type == PACKET_MULTICAST) {
+ dhd->pub.rx_multicast++;
+ }
+
+ skb->data = eth;
+ skb->len = len;
+
+#ifdef WLMEDIA_HTSF
+ dhd_htsf_addrxts(dhdp, pktbuf);
+#endif
+ /* Strip header, count, deliver upward */
+ skb_pull(skb, ETH_HLEN);
+
+ /* Process special event packets and then discard them */
+ if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) {
+ dhd_wl_host_event(dhd, &ifidx,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+ skb->mac_header,
+#else
+ skb->mac.raw,
+#endif
+ &event,
+ &data);
+
+ wl_event_to_host_order(&event);
+ if (!tout_ctrl)
+ tout_ctrl = DHD_PACKET_TIMEOUT_MS;
+#ifdef WLBTAMP
+ if (event.event_type == WLC_E_BTA_HCI_EVENT) {
+ dhd_bta_doevt(dhdp, data, event.datalen);
+ }
+#endif /* WLBTAMP */
+
+#if defined(PNO_SUPPORT)
+ if (event.event_type == WLC_E_PFN_NET_FOUND) {
+ /* enforce custom wake lock to garantee that Kernel not suspended */
+ tout_ctrl = CUSTOM_PNO_EVENT_LOCK_xTIME * DHD_PACKET_TIMEOUT_MS;
+ }
+#endif /* PNO_SUPPORT */
+
+#ifdef DHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT
+ PKTFREE(dhdp->osh, pktbuf, TRUE);
+ continue;
+#endif
+ } else {
+ tout_rx = DHD_PACKET_TIMEOUT_MS;
+ }
+
+ ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
+ if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state)
+ ifp = dhd->iflist[ifidx];
+
+ if (ifp->net)
+ ifp->net->last_rx = jiffies;
+
+ dhdp->dstats.rx_bytes += skb->len;
+ dhdp->rx_packets++; /* Local count */
+
+ if (in_interrupt()) {
+ netif_rx(skb);
+ } else {
+ /* If the receive is not processed inside an ISR,
+ * the softirqd must be woken explicitly to service
+ * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled
+ * by netif_rx_ni(), but in earlier kernels, we need
+ * to do it manually.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+ netif_rx_ni(skb);
+#else
+ ulong flags;
+ netif_rx(skb);
+ local_irq_save(flags);
+ RAISE_RX_SOFTIRQ();
+ local_irq_restore(flags);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */
+ }
+ }
+
+ DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(dhdp, tout_rx);
+ DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhdp, tout_ctrl);
+}
+
+void
+dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx)
+{
+ /* Linux version has nothing to do */
+ return;
+}
+
+void
+dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(dhdp->info);
+ struct ether_header *eh;
+ uint16 type;
+#ifdef WLBTAMP
+ uint len;
+#endif
+
+ dhd_prot_hdrpull(dhdp, NULL, txp, NULL, NULL);
+
+ eh = (struct ether_header *)PKTDATA(dhdp->osh, txp);
+ type = ntoh16(eh->ether_type);
+
+ if (type == ETHER_TYPE_802_1X)
+ atomic_dec(&dhd->pend_8021x_cnt);
+
+#ifdef WLBTAMP
+ /* Crack open the packet and check to see if it is BT HCI ACL data packet.
+ * If yes generate packet completion event.
+ */
+ len = PKTLEN(dhdp->osh, txp);
+
+ /* Generate ACL data tx completion event locally to avoid SDIO bus transaction */
+ if ((type < ETHER_TYPE_MIN) && (len >= RFC1042_HDR_LEN)) {
+ struct dot11_llc_snap_header *lsh = (struct dot11_llc_snap_header *)&eh[1];
+
+ if (bcmp(lsh, BT_SIG_SNAP_MPROT, DOT11_LLC_SNAP_HDR_LEN - 2) == 0 &&
+ ntoh16(lsh->type) == BTA_PROT_L2CAP) {
+
+ dhd_bta_tx_hcidata_complete(dhdp, txp, success);
+ }
+ }
+#endif /* WLBTAMP */
+}
+
+static struct net_device_stats *
+dhd_get_stats(struct net_device *net)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
+ dhd_if_t *ifp;
+ int ifidx;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ ifidx = dhd_net2idx(dhd, net);
+ if (ifidx == DHD_BAD_IF) {
+ AP6210_ERR("%s: BAD_IF\n", __FUNCTION__);
+ return NULL;
+ }
+
+ ifp = dhd->iflist[ifidx];
+ ASSERT(dhd && ifp);
+
+ if (dhd->pub.up) {
+ /* Use the protocol to get dongle stats */
+ dhd_prot_dstats(&dhd->pub);
+ }
+
+ /* Copy dongle stats to net device stats */
+ ifp->stats.rx_packets = dhd->pub.dstats.rx_packets;
+ ifp->stats.tx_packets = dhd->pub.dstats.tx_packets;
+ ifp->stats.rx_bytes = dhd->pub.dstats.rx_bytes;
+ ifp->stats.tx_bytes = dhd->pub.dstats.tx_bytes;
+ ifp->stats.rx_errors = dhd->pub.dstats.rx_errors;
+ ifp->stats.tx_errors = dhd->pub.dstats.tx_errors;
+ ifp->stats.rx_dropped = dhd->pub.dstats.rx_dropped;
+ ifp->stats.tx_dropped = dhd->pub.dstats.tx_dropped;
+ ifp->stats.multicast = dhd->pub.dstats.multicast;
+
+ return &ifp->stats;
+}
+
+#ifdef DHDTHREAD
+static int
+dhd_watchdog_thread(void *data)
+{
+ tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+ dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
+ /* This thread doesn't need any user-level access,
+ * so get rid of all our resources
+ */
+ if (dhd_watchdog_prio > 0) {
+ struct sched_param param;
+ param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO)?
+ dhd_watchdog_prio:(MAX_RT_PRIO-1);
+ setScheduler(current, SCHED_FIFO, &param);
+ }
+#ifndef USE_KTHREAD_API
+ DAEMONIZE("dhd_watchdog");
+
+ /* Run until signal received */
+ complete(&tsk->completed);
+#endif
+
+ while (1)
+ if (down_interruptible (&tsk->sema) == 0) {
+ unsigned long flags;
+ unsigned long jiffies_at_start = jiffies;
+ unsigned long time_lapse;
+
+ SMP_RD_BARRIER_DEPENDS();
+ if (tsk->terminated) {
+ break;
+ }
+
+ dhd_os_sdlock(&dhd->pub);
+ if (dhd->pub.dongle_reset == FALSE) {
+ AP6210_DEBUG("%s:\n", __FUNCTION__);
+
+ /* Call the bus module watchdog */
+ dhd_bus_watchdog(&dhd->pub);
+
+ flags = dhd_os_spin_lock(&dhd->pub);
+ /* Count the tick for reference */
+ dhd->pub.tickcnt++;
+ time_lapse = jiffies - jiffies_at_start;
+
+ /* Reschedule the watchdog */
+ if (dhd->wd_timer_valid)
+ mod_timer(&dhd->timer,
+ jiffies +
+ msecs_to_jiffies(dhd_watchdog_ms) -
+ min(msecs_to_jiffies(dhd_watchdog_ms), time_lapse));
+ dhd_os_spin_unlock(&dhd->pub, flags);
+ }
+ dhd_os_sdunlock(&dhd->pub);
+ } else {
+ break;
+ }
+
+ complete_and_exit(&tsk->completed, 0);
+}
+#endif /* DHDTHREAD */
+
+static void dhd_watchdog(ulong data)
+{
+ dhd_info_t *dhd = (dhd_info_t *)data;
+ unsigned long flags;
+
+ if (dhd->pub.dongle_reset) {
+ return;
+ }
+
+#ifdef DHDTHREAD
+ if (dhd->thr_wdt_ctl.thr_pid >= 0) {
+ up(&dhd->thr_wdt_ctl.sema);
+ return;
+ }
+#endif /* DHDTHREAD */
+
+ dhd_os_sdlock(&dhd->pub);
+ /* Call the bus module watchdog */
+ dhd_bus_watchdog(&dhd->pub);
+
+ flags = dhd_os_spin_lock(&dhd->pub);
+ /* Count the tick for reference */
+ dhd->pub.tickcnt++;
+
+ /* Reschedule the watchdog */
+ if (dhd->wd_timer_valid)
+ mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms));
+ dhd_os_spin_unlock(&dhd->pub, flags);
+ dhd_os_sdunlock(&dhd->pub);
+}
+
+#ifdef DHDTHREAD
+static int
+dhd_dpc_thread(void *data)
+{
+ tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+ dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
+
+ /* This thread doesn't need any user-level access,
+ * so get rid of all our resources
+ */
+ if (dhd_dpc_prio > 0)
+ {
+ struct sched_param param;
+ param.sched_priority = (dhd_dpc_prio < MAX_RT_PRIO)?dhd_dpc_prio:(MAX_RT_PRIO-1);
+ setScheduler(current, SCHED_FIFO, &param);
+ }
+#ifndef USE_KTHREAD_API
+ DAEMONIZE("dhd_dpc");
+ /* DHD_OS_WAKE_LOCK is called in dhd_sched_dpc[dhd_linux.c] down below */
+
+ /* signal: thread has started */
+ complete(&tsk->completed);
+#endif
+
+ /* Run until signal received */
+ while (1) {
+ if (down_interruptible(&tsk->sema) == 0) {
+
+ SMP_RD_BARRIER_DEPENDS();
+ if (tsk->terminated) {
+ break;
+ }
+
+ /* Call bus dpc unless it indicated down (then clean stop) */
+ if (dhd->pub.busstate != DHD_BUS_DOWN) {
+ if (dhd_bus_dpc(dhd->pub.bus)) {
+ up(&tsk->sema);
+ }
+ else {
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ }
+ } else {
+ if (dhd->pub.up)
+ dhd_bus_stop(dhd->pub.bus, TRUE);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ }
+ }
+ else
+ break;
+ }
+
+ complete_and_exit(&tsk->completed, 0);
+}
+#endif /* DHDTHREAD */
+
+static void
+dhd_dpc(ulong data)
+{
+ dhd_info_t *dhd;
+
+ dhd = (dhd_info_t *)data;
+
+ /* this (tasklet) can be scheduled in dhd_sched_dpc[dhd_linux.c]
+ * down below , wake lock is set,
+ * the tasklet is initialized in dhd_attach()
+ */
+ /* Call bus dpc unless it indicated down (then clean stop) */
+ if (dhd->pub.busstate != DHD_BUS_DOWN) {
+ if (dhd_bus_dpc(dhd->pub.bus))
+ tasklet_schedule(&dhd->tasklet);
+ else
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ } else {
+ dhd_bus_stop(dhd->pub.bus, TRUE);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ }
+}
+
+void
+dhd_sched_dpc(dhd_pub_t *dhdp)
+{
+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+
+ DHD_OS_WAKE_LOCK(dhdp);
+#ifdef DHDTHREAD
+ if (dhd->thr_dpc_ctl.thr_pid >= 0) {
+ up(&dhd->thr_dpc_ctl.sema);
+ return;
+ }
+#endif /* DHDTHREAD */
+
+ if (dhd->dhd_tasklet_create)
+ tasklet_schedule(&dhd->tasklet);
+}
+
+#ifdef TOE
+/* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */
+static int
+dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol)
+{
+ wl_ioctl_t ioc;
+ char buf[32];
+ int ret;
+
+ memset(&ioc, 0, sizeof(ioc));
+
+ ioc.cmd = WLC_GET_VAR;
+ ioc.buf = buf;
+ ioc.len = (uint)sizeof(buf);
+ ioc.set = FALSE;
+
+ strncpy(buf, "toe_ol", sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+ if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) {
+ /* Check for older dongle image that doesn't support toe_ol */
+ if (ret == -EIO) {
+ AP6210_ERR("%s: toe not supported by device\n",
+ dhd_ifname(&dhd->pub, ifidx));
+ return -EOPNOTSUPP;
+ }
+
+ AP6210_DEBUG("%s: could not get toe_ol: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret);
+ return ret;
+ }
+
+ memcpy(toe_ol, buf, sizeof(uint32));
+ return 0;
+}
+
+/* Set current toe component enables in toe_ol iovar, and set toe global enable iovar */
+static int
+dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol)
+{
+ wl_ioctl_t ioc;
+ char buf[32];
+ int toe, ret;
+
+ memset(&ioc, 0, sizeof(ioc));
+
+ ioc.cmd = WLC_SET_VAR;
+ ioc.buf = buf;
+ ioc.len = (uint)sizeof(buf);
+ ioc.set = TRUE;
+
+ /* Set toe_ol as requested */
+
+ strncpy(buf, "toe_ol", sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+ memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(uint32));
+
+ if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) {
+ AP6210_ERR("%s: could not set toe_ol: ret=%d\n",
+ dhd_ifname(&dhd->pub, ifidx), ret);
+ return ret;
+ }
+
+ /* Enable toe globally only if any components are enabled. */
+
+ toe = (toe_ol != 0);
+
+ strcpy(buf, "toe");
+ memcpy(&buf[sizeof("toe")], &toe, sizeof(uint32));
+
+ if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) {
+ AP6210_ERR("%s: could not set toe: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret);
+ return ret;
+ }
+
+ return 0;
+}
+#endif /* TOE */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+static void
+dhd_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
+
+ snprintf(info->driver, sizeof(info->driver), "wl");
+ snprintf(info->version, sizeof(info->version), "%lu", dhd->pub.drv_version);
+}
+
+struct ethtool_ops dhd_ethtool_ops = {
+ .get_drvinfo = dhd_ethtool_get_drvinfo
+};
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */
+
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2)
+static int
+dhd_ethtool(dhd_info_t *dhd, void *uaddr)
+{
+ struct ethtool_drvinfo info;
+ char drvname[sizeof(info.driver)];
+ uint32 cmd;
+#ifdef TOE
+ struct ethtool_value edata;
+ uint32 toe_cmpnt, csum_dir;
+ int ret;
+#endif
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ /* all ethtool calls start with a cmd word */
+ if (copy_from_user(&cmd, uaddr, sizeof (uint32)))
+ return -EFAULT;
+
+ switch (cmd) {
+ case ETHTOOL_GDRVINFO:
+ /* Copy out any request driver name */
+ if (copy_from_user(&info, uaddr, sizeof(info)))
+ return -EFAULT;
+ strncpy(drvname, info.driver, sizeof(info.driver));
+ drvname[sizeof(info.driver)-1] = '\0';
+
+ /* clear struct for return */
+ memset(&info, 0, sizeof(info));
+ info.cmd = cmd;
+
+ /* if dhd requested, identify ourselves */
+ if (strcmp(drvname, "?dhd") == 0) {
+ snprintf(info.driver, sizeof(info.driver), "dhd");
+ strncpy(info.version, EPI_VERSION_STR, sizeof(info.version) - 1);
+ info.version[sizeof(info.version) - 1] = '\0';
+ }
+
+ /* otherwise, require dongle to be up */
+ else if (!dhd->pub.up) {
+ AP6210_ERR("%s: dongle is not up\n", __FUNCTION__);
+ return -ENODEV;
+ }
+
+ /* finally, report dongle driver type */
+ else if (dhd->pub.iswl)
+ snprintf(info.driver, sizeof(info.driver), "wl");
+ else
+ snprintf(info.driver, sizeof(info.driver), "xx");
+
+ snprintf(info.version, sizeof(info.version), "%lu", dhd->pub.drv_version);
+ if (copy_to_user(uaddr, &info, sizeof(info)))
+ return -EFAULT;
+ AP6210_DEBUG("%s: given %*s, returning %s\n", __FUNCTION__,
+ (int)sizeof(drvname), drvname, info.driver);
+ break;
+
+#ifdef TOE
+ /* Get toe offload components from dongle */
+ case ETHTOOL_GRXCSUM:
+ case ETHTOOL_GTXCSUM:
+ if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0)
+ return ret;
+
+ csum_dir = (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+
+ edata.cmd = cmd;
+ edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
+
+ if (copy_to_user(uaddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ break;
+
+ /* Set toe offload components in dongle */
+ case ETHTOOL_SRXCSUM:
+ case ETHTOOL_STXCSUM:
+ if (copy_from_user(&edata, uaddr, sizeof(edata)))
+ return -EFAULT;
+
+ /* Read the current settings, update and write back */
+ if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0)
+ return ret;
+
+ csum_dir = (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+
+ if (edata.data != 0)
+ toe_cmpnt |= csum_dir;
+ else
+ toe_cmpnt &= ~csum_dir;
+
+ if ((ret = dhd_toe_set(dhd, 0, toe_cmpnt)) < 0)
+ return ret;
+
+ /* If setting TX checksum mode, tell Linux the new mode */
+ if (cmd == ETHTOOL_STXCSUM) {
+ if (edata.data)
+ dhd->iflist[0]->net->features |= NETIF_F_IP_CSUM;
+ else
+ dhd->iflist[0]->net->features &= ~NETIF_F_IP_CSUM;
+ }
+
+ break;
+#endif /* TOE */
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */
+
+static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error)
+{
+ dhd_info_t * dhd;
+
+ if (!dhdp)
+ return FALSE;
+
+ dhd = (dhd_info_t *)dhdp->info;
+ if (dhd->thr_sysioc_ctl.thr_pid < 0) {
+ AP6210_ERR("%s : skipped due to negative pid - unloading?\n", __FUNCTION__);
+ return FALSE;
+ }
+
+ if ((error == -ETIMEDOUT) || (error == -EREMOTEIO) ||
+ ((dhdp->busstate == DHD_BUS_DOWN) && (!dhdp->dongle_reset))) {
+ AP6210_ERR("%s: Event HANG send up due to re=%d te=%d e=%d s=%d\n", __FUNCTION__,
+ dhdp->rxcnt_timeout, dhdp->txcnt_timeout, error, dhdp->busstate);
+ net_os_send_hang_message(net);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int
+dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
+ dhd_ioctl_t ioc;
+ int bcmerror = 0;
+ int buflen = 0;
+ void *buf = NULL;
+ uint driver = 0;
+ int ifidx;
+ int ret;
+
+ DHD_OS_WAKE_LOCK(&dhd->pub);
+
+ /* send to dongle only if we are not waiting for reload already */
+ if (dhd->pub.hang_was_sent) {
+ AP6210_ERR("%s: HANG was sent up earlier\n", __FUNCTION__);
+ DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ return OSL_ERROR(BCME_DONGLE_DOWN);
+ }
+
+ ifidx = dhd_net2idx(dhd, net);
+ AP6210_DEBUG("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd);
+
+ if (ifidx == DHD_BAD_IF) {
+ AP6210_ERR("%s: BAD IF\n", __FUNCTION__);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ return -1;
+ }
+
+#if defined(CONFIG_WIRELESS_EXT)
+ /* linux wireless extensions */
+ if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
+ /* may recurse, do NOT lock */
+ ret = wl_iw_ioctl(net, ifr, cmd);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ return ret;
+ }
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2)
+ if (cmd == SIOCETHTOOL) {
+ ret = dhd_ethtool(dhd, (void*)ifr->ifr_data);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ return ret;
+ }
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */
+
+ if (cmd == SIOCDEVPRIVATE+1) {
+ ret = wl_android_priv_cmd(net, ifr, cmd);
+ dhd_check_hang(net, &dhd->pub, ret);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ return ret;
+ }
+
+ if (cmd != SIOCDEVPRIVATE) {
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ return -EOPNOTSUPP;
+ }
+
+ memset(&ioc, 0, sizeof(ioc));
+
+ /* Copy the ioc control structure part of ioctl request */
+ if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) {
+ bcmerror = BCME_BADADDR;
+ goto done;
+ }
+
+ /* Copy out any buffer passed */
+ if (ioc.buf) {
+ if (ioc.len == 0) {
+ AP6210_DEBUG("%s: ioc.len=0, returns BCME_BADARG \n", __FUNCTION__);
+ bcmerror = BCME_BADARG;
+ goto done;
+ }
+ buflen = MIN(ioc.len, DHD_IOCTL_MAXLEN);
+ /* optimization for direct ioctl calls from kernel */
+ /*
+ if (segment_eq(get_fs(), KERNEL_DS)) {
+ buf = ioc.buf;
+ } else {
+ */
+ {
+ if (!(buf = (char*)MALLOC(dhd->pub.osh, buflen))) {
+ bcmerror = BCME_NOMEM;
+ goto done;
+ }
+ if (copy_from_user(buf, ioc.buf, buflen)) {
+ bcmerror = BCME_BADADDR;
+ goto done;
+ }
+ }
+ }
+
+ /* To differentiate between wl and dhd read 4 more byes */
+ if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t),
+ sizeof(uint)) != 0)) {
+ bcmerror = BCME_BADADDR;
+ goto done;
+ }
+
+ if (!capable(CAP_NET_ADMIN)) {
+ bcmerror = BCME_EPERM;
+ goto done;
+ }
+
+ /* check for local dhd ioctl and handle it */
+ if (driver == DHD_IOCTL_MAGIC) {
+ bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen);
+ if (bcmerror)
+ dhd->pub.bcmerror = bcmerror;
+ goto done;
+ }
+
+ /* send to dongle (must be up, and wl). */
+ if (dhd->pub.busstate != DHD_BUS_DATA) {
+ bcmerror = BCME_DONGLE_DOWN;
+ goto done;
+ }
+
+ if (!dhd->pub.iswl) {
+ bcmerror = BCME_DONGLE_DOWN;
+ goto done;
+ }
+
+ /*
+ * Flush the TX queue if required for proper message serialization:
+ * Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to
+ * prevent M4 encryption and
+ * intercept WLC_DISASSOC IOCTL - serialize WPS-DONE and WLC_DISASSOC IOCTL to
+ * prevent disassoc frame being sent before WPS-DONE frame.
+ */
+ if (ioc.cmd == WLC_SET_KEY ||
+ (ioc.cmd == WLC_SET_VAR && ioc.buf != NULL &&
+ strncmp("wsec_key", ioc.buf, 9) == 0) ||
+ (ioc.cmd == WLC_SET_VAR && ioc.buf != NULL &&
+ strncmp("bsscfg:wsec_key", ioc.buf, 15) == 0) ||
+ ioc.cmd == WLC_DISASSOC)
+ dhd_wait_pend8021x(net);
+
+#ifdef WLMEDIA_HTSF
+ if (ioc.buf) {
+ /* short cut wl ioctl calls here */
+ if (strcmp("htsf", ioc.buf) == 0) {
+ dhd_ioctl_htsf_get(dhd, 0);
+ return BCME_OK;
+ }
+
+ if (strcmp("htsflate", ioc.buf) == 0) {
+ if (ioc.set) {
+ memset(ts, 0, sizeof(tstamp_t)*TSMAX);
+ memset(&maxdelayts, 0, sizeof(tstamp_t));
+ maxdelay = 0;
+ tspktcnt = 0;
+ maxdelaypktno = 0;
+ memset(&vi_d1.bin, 0, sizeof(uint32)*NUMBIN);
+ memset(&vi_d2.bin, 0, sizeof(uint32)*NUMBIN);
+ memset(&vi_d3.bin, 0, sizeof(uint32)*NUMBIN);
+ memset(&vi_d4.bin, 0, sizeof(uint32)*NUMBIN);
+ } else {
+ dhd_dump_latency();
+ }
+ return BCME_OK;
+ }
+ if (strcmp("htsfclear", ioc.buf) == 0) {
+ memset(&vi_d1.bin, 0, sizeof(uint32)*NUMBIN);
+ memset(&vi_d2.bin, 0, sizeof(uint32)*NUMBIN);
+ memset(&vi_d3.bin, 0, sizeof(uint32)*NUMBIN);
+ memset(&vi_d4.bin, 0, sizeof(uint32)*NUMBIN);
+ htsf_seqnum = 0;
+ return BCME_OK;
+ }
+ if (strcmp("htsfhis", ioc.buf) == 0) {
+ dhd_dump_htsfhisto(&vi_d1, "H to D");
+ dhd_dump_htsfhisto(&vi_d2, "D to D");
+ dhd_dump_htsfhisto(&vi_d3, "D to H");
+ dhd_dump_htsfhisto(&vi_d4, "H to H");
+ return BCME_OK;
+ }
+ if (strcmp("tsport", ioc.buf) == 0) {
+ if (ioc.set) {
+ memcpy(&tsport, ioc.buf + 7, 4);
+ } else {
+ AP6210_ERR("current timestamp port: %d \n", tsport);
+ }
+ return BCME_OK;
+ }
+ }
+#endif /* WLMEDIA_HTSF */
+
+ if ((ioc.cmd == WLC_SET_VAR || ioc.cmd == WLC_GET_VAR) &&
+ ioc.buf != NULL && strncmp("rpc_", ioc.buf, 4) == 0) {
+#ifdef BCM_FD_AGGR
+ bcmerror = dhd_fdaggr_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen);
+#else
+ bcmerror = BCME_UNSUPPORTED;
+#endif
+ goto done;
+ }
+ bcmerror = dhd_wl_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen);
+
+done:
+ dhd_check_hang(net, &dhd->pub, bcmerror);
+
+ if (!bcmerror && buf && ioc.buf) {
+ if (copy_to_user(ioc.buf, buf, buflen))
+ bcmerror = -EFAULT;
+ }
+
+ if (buf)
+ MFREE(dhd->pub.osh, buf, buflen);
+
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+ return OSL_ERROR(bcmerror);
+}
+
+#ifdef WL_CFG80211
+static int
+dhd_cleanup_virt_ifaces(dhd_info_t *dhd)
+{
+ int i = 1; /* Leave ifidx 0 [Primary Interface] */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ int rollback_lock = FALSE;
+#endif
+
+ AP6210_DEBUG("%s: Enter \n", __func__);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ /* release lock for unregister_netdev */
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = TRUE;
+ }
+#endif
+
+ for (i = 1; i < DHD_MAX_IFS; i++) {
+ dhd_net_if_lock_local(dhd);
+ if (dhd->iflist[i]) {
+ AP6210_DEBUG("Deleting IF: %d \n", i);
+ if ((dhd->iflist[i]->state != DHD_IF_DEL) &&
+ (dhd->iflist[i]->state != DHD_IF_DELETING)) {
+ dhd->iflist[i]->state = DHD_IF_DEL;
+ dhd->iflist[i]->idx = i;
+ dhd_op_if(dhd->iflist[i]);
+ }
+ }
+ dhd_net_if_unlock_local(dhd);
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ if (rollback_lock)
+ rtnl_lock();
+#endif
+
+ return 0;
+}
+#endif /* WL_CFG80211 */
+
+
+static int
+dhd_stop(struct net_device *net)
+{
+ int ifidx = 0;
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
+ DHD_OS_WAKE_LOCK(&dhd->pub);
+ AP6210_DEBUG("%s: Enter %p\n", __FUNCTION__, net);
+ if (dhd->pub.up == 0) {
+ goto exit;
+ }
+ ifidx = dhd_net2idx(dhd, net);
+ BCM_REFERENCE(ifidx);
+
+ /* Set state and stop OS transmissions */
+ netif_stop_queue(net);
+ dhd->pub.up = 0;
+
+#ifdef WL_CFG80211
+ if (ifidx == 0) {
+ wl_cfg80211_down(NULL);
+
+ /*
+ * For CFG80211: Clean up all the left over virtual interfaces
+ * when the primary Interface is brought down. [ifconfig wlan0 down]
+ */
+ if ((dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) &&
+ (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) {
+ dhd_cleanup_virt_ifaces(dhd);
+ }
+ }
+#endif
+
+#ifdef PROP_TXSTATUS
+ dhd_os_wlfc_block(&dhd->pub);
+ dhd_wlfc_cleanup(&dhd->pub);
+ dhd_os_wlfc_unblock(&dhd->pub);
+#endif
+ /* Stop the protocol module */
+ dhd_prot_stop(&dhd->pub);
+
+ OLD_MOD_DEC_USE_COUNT;
+exit:
+#if defined(WL_CFG80211)
+ if (ifidx == 0) {
+ if (!dhd_download_fw_on_driverload)
+ wl_android_wifi_off(net);
+ }
+#endif
+ dhd->pub.rxcnt_timeout = 0;
+ dhd->pub.txcnt_timeout = 0;
+
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ return 0;
+}
+
+static int
+dhd_open(struct net_device *net)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
+#ifdef TOE
+ uint32 toe_ol;
+#endif
+ int ifidx;
+ int32 ret = 0;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) {
+ AP6210_ERR("%s : dhd_open: call dev open before insmod complete!\n", __FUNCTION__);
+ }
+ mutex_lock(&_dhd_sdio_mutex_lock_);
+#endif
+
+ AP6210_DEBUG("%s, firmware path %s\n", __func__, firmware_path);
+
+ DHD_OS_WAKE_LOCK(&dhd->pub);
+ /* Update FW path if it was changed */
+ if (strlen(firmware_path) != 0) {
+ if (firmware_path[strlen(firmware_path)-1] == '\n')
+ firmware_path[strlen(firmware_path)-1] = '\0';
+ COPY_FW_PATH_BY_CHIP( dhd->pub.bus, fw_path, firmware_path);
+ }
+
+
+ dhd->pub.dongle_trap_occured = 0;
+ dhd->pub.hang_was_sent = 0;
+#if !defined(WL_CFG80211)
+ /*
+ * Force start if ifconfig_up gets called before START command
+ * We keep WEXT's wl_control_wl_start to provide backward compatibility
+ * This should be removed in the future
+ */
+ ret = wl_control_wl_start(net);
+ if (ret != 0) {
+ AP6210_ERR("%s: failed with code %d\n", __FUNCTION__, ret);
+ ret = -1;
+ goto exit;
+ }
+#endif
+
+ ifidx = dhd_net2idx(dhd, net);
+ AP6210_DEBUG("%s: ifidx %d\n", __FUNCTION__, ifidx);
+
+ if (ifidx < 0) {
+ AP6210_ERR("%s: Error: called with invalid IF\n", __FUNCTION__);
+ ret = -1;
+ goto exit;
+ }
+
+ if (!dhd->iflist[ifidx] || dhd->iflist[ifidx]->state == DHD_IF_DEL) {
+ AP6210_ERR("%s: Error: called when IF already deleted\n", __FUNCTION__);
+ ret = -1;
+ goto exit;
+ }
+
+ if (ifidx == 0) {
+ atomic_set(&dhd->pend_8021x_cnt, 0);
+#if defined(WL_CFG80211)
+ AP6210_ERR("%s\n", dhd_version);
+#if defined(DHD_DEBUG)
+ AP6210_ERR("%s\n", dhd_version_info);
+#endif
+
+ if (!dhd_download_fw_on_driverload) {
+ ret = wl_android_wifi_on(net);
+ if (ret != 0) {
+ AP6210_ERR("%s: failed with code %d\n", __FUNCTION__, ret);
+ ret = -1;
+ goto exit;
+ }
+ } else {
+ }
+#endif
+
+ if (dhd->pub.busstate != DHD_BUS_DATA) {
+
+ /* try to bring up bus */
+ if ((ret = dhd_bus_start(&dhd->pub)) != 0) {
+ AP6210_ERR("%s: failed with code %d\n", __FUNCTION__, ret);
+ ret = -1;
+ goto exit;
+ }
+
+ }
+
+ /* dhd_prot_init has been called in dhd_bus_start or wl_android_wifi_on */
+ memcpy(net->dev_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN);
+
+#ifdef TOE
+ /* Get current TOE mode from dongle */
+ if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0)
+ dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM;
+ else
+ dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM;
+#endif /* TOE */
+
+#if defined(WL_CFG80211)
+ if (unlikely(wl_cfg80211_up(NULL))) {
+ AP6210_ERR("%s: failed to bring up cfg80211\n", __FUNCTION__);
+ ret = -1;
+ goto exit;
+ }
+#endif /* WL_CFG80211 */
+ }
+
+ /* Allow transmit calls */
+ netif_start_queue(net);
+ dhd->pub.up = 1;
+
+#ifdef BCMDBGFS
+ dhd_dbg_init(&dhd->pub);
+#endif
+
+ OLD_MOD_INC_USE_COUNT;
+exit:
+ if (ret)
+ dhd_stop(net);
+
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ mutex_unlock(&_dhd_sdio_mutex_lock_);
+#endif
+ return ret;
+}
+
+int dhd_do_driver_init(struct net_device *net)
+{
+ dhd_info_t *dhd = NULL;
+
+ if (!net) {
+ AP6210_ERR("Primary Interface not initialized \n");
+ return -EINVAL;
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+#ifdef MULTIPLE_SUPPLICANT
+ if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) {
+ AP6210_ERR("%s : dhdsdio_probe is already running!\n", __FUNCTION__);
+ return 0;
+ }
+#endif /* MULTIPLE_SUPPLICANT */
+#endif
+
+ dhd = *(dhd_info_t **)netdev_priv(net);
+
+ /* If driver is already initialized, do nothing
+ */
+ if (dhd->pub.busstate == DHD_BUS_DATA) {
+ AP6210_DEBUG("Driver already Inititalized. Nothing to do");
+ return 0;
+ }
+
+ if (dhd_open(net) < 0) {
+ AP6210_ERR("Driver Init Failed \n");
+ return -1;
+ }
+
+ return 0;
+}
+
+osl_t *
+dhd_osl_attach(void *pdev, uint bustype)
+{
+ return osl_attach(pdev, bustype, TRUE);
+}
+
+void
+dhd_osl_detach(osl_t *osh)
+{
+ if (MALLOCED(osh)) {
+ AP6210_ERR("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh));
+ }
+ osl_detach(osh);
+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ dhd_registration_check = FALSE;
+ up(&dhd_registration_sem);
+#if defined(BCMLXSDMMC)
+ up(&dhd_chipup_sem);
+#endif
+#endif
+}
+
+int
+dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name,
+ uint8 *mac_addr, uint32 flags, uint8 bssidx)
+{
+ dhd_if_t *ifp;
+
+ AP6210_DEBUG("%s: idx %d, handle->%p\n", __FUNCTION__, ifidx, handle);
+
+ ASSERT(dhd && (ifidx < DHD_MAX_IFS));
+
+ ifp = dhd->iflist[ifidx];
+ if (ifp != NULL) {
+ if (ifp->net != NULL) {
+ netif_stop_queue(ifp->net);
+ unregister_netdev(ifp->net);
+ free_netdev(ifp->net);
+ }
+ } else
+ if ((ifp = MALLOC(dhd->pub.osh, sizeof(dhd_if_t))) == NULL) {
+ AP6210_ERR("%s: OOM - dhd_if_t\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ memset(ifp, 0, sizeof(dhd_if_t));
+ ifp->event2cfg80211 = FALSE;
+ ifp->info = dhd;
+ dhd->iflist[ifidx] = ifp;
+ strncpy(ifp->name, name, IFNAMSIZ);
+ ifp->name[IFNAMSIZ] = '\0';
+ if (mac_addr != NULL)
+ memcpy(&ifp->mac_addr, mac_addr, ETHER_ADDR_LEN);
+
+ if (handle == NULL) {
+ ifp->state = DHD_IF_ADD;
+ ifp->idx = ifidx;
+ ifp->bssidx = bssidx;
+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0);
+ up(&dhd->thr_sysioc_ctl.sema);
+ } else
+ ifp->net = (struct net_device *)handle;
+
+ if (ifidx == 0) {
+ ifp->event2cfg80211 = TRUE;
+ }
+
+ return 0;
+}
+
+void
+dhd_del_if(dhd_info_t *dhd, int ifidx)
+{
+ dhd_if_t *ifp;
+
+ AP6210_DEBUG("%s: idx %d\n", __FUNCTION__, ifidx);
+
+ ASSERT(dhd && ifidx && (ifidx < DHD_MAX_IFS));
+ ifp = dhd->iflist[ifidx];
+ if (!ifp) {
+ AP6210_ERR("%s: Null interface\n", __FUNCTION__);
+ return;
+ }
+
+ ifp->state = DHD_IF_DEL;
+ ifp->idx = ifidx;
+ ASSERT(dhd->thr_sysioc_ctl.thr_pid >= 0);
+ up(&dhd->thr_sysioc_ctl.sema);
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
+static struct net_device_ops dhd_ops_pri = {
+ .ndo_open = dhd_open,
+ .ndo_stop = dhd_stop,
+ .ndo_get_stats = dhd_get_stats,
+ .ndo_do_ioctl = dhd_ioctl_entry,
+ .ndo_start_xmit = dhd_start_xmit,
+ .ndo_set_mac_address = dhd_set_mac_address,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
+ .ndo_set_rx_mode = dhd_set_multicast_list,
+#else
+ .ndo_set_multicast_list = dhd_set_multicast_list,
+#endif
+};
+
+static struct net_device_ops dhd_ops_virt = {
+ .ndo_get_stats = dhd_get_stats,
+ .ndo_do_ioctl = dhd_ioctl_entry,
+ .ndo_start_xmit = dhd_start_xmit,
+ .ndo_set_mac_address = dhd_set_mac_address,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
+ .ndo_set_rx_mode = dhd_set_multicast_list,
+#else
+ .ndo_set_multicast_list = dhd_set_multicast_list,
+#endif
+};
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) */
+
+dhd_pub_t *
+dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
+{
+ dhd_info_t *dhd = NULL;
+ struct net_device *net = NULL;
+
+ dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT;
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ AP6210_DEBUG("%s, firmware path %s\n", __func__, firmware_path);
+
+ /* updates firmware nvram path if it was provided as module parameters */
+ if ((firmware_path != NULL) && (firmware_path[0] != '\0'))
+ COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path);
+ if (strlen(nvram_path) != 0) {
+ strncpy(nv_path, nvram_path, sizeof(nv_path) -1);
+ nv_path[sizeof(nv_path) -1] = '\0';
+ }
+
+ /* Allocate etherdev, including space for private structure */
+ if (!(net = alloc_etherdev(sizeof(dhd)))) {
+ AP6210_ERR("%s: OOM - alloc_etherdev\n", __FUNCTION__);
+ goto fail;
+ }
+ dhd_state |= DHD_ATTACH_STATE_NET_ALLOC;
+
+ /* Allocate primary dhd_info */
+ if (!(dhd = MALLOC(osh, sizeof(dhd_info_t)))) {
+ AP6210_ERR("%s: OOM - alloc dhd_info\n", __FUNCTION__);
+ goto fail;
+ }
+ memset(dhd, 0, sizeof(dhd_info_t));
+
+#ifdef DHDTHREAD
+ dhd->thr_dpc_ctl.thr_pid = DHD_PID_KT_TL_INVALID;
+ dhd->thr_wdt_ctl.thr_pid = DHD_PID_KT_INVALID;
+#endif /* DHDTHREAD */
+ dhd->dhd_tasklet_create = FALSE;
+ dhd->thr_sysioc_ctl.thr_pid = DHD_PID_KT_INVALID;
+ dhd_state |= DHD_ATTACH_STATE_DHD_ALLOC;
+
+ /*
+ * Save the dhd_info into the priv
+ */
+ memcpy((void *)netdev_priv(net), &dhd, sizeof(dhd));
+ dhd->pub.osh = osh;
+
+ /* Link to info module */
+ dhd->pub.info = dhd;
+ /* Link to bus module */
+ dhd->pub.bus = bus;
+ dhd->pub.hdrlen = bus_hdrlen;
+
+ /* Set network interface name if it was provided as module parameter */
+ if (iface_name[0]) {
+ int len;
+ char ch;
+ strncpy(net->name, iface_name, IFNAMSIZ);
+ net->name[IFNAMSIZ - 1] = 0;
+ len = strlen(net->name);
+ ch = net->name[len - 1];
+ if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2))
+ strcat(net->name, "%d");
+ }
+
+ if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) == DHD_BAD_IF)
+ goto fail;
+ dhd_state |= DHD_ATTACH_STATE_ADD_IF;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+ net->open = NULL;
+#else
+ net->netdev_ops = NULL;
+#endif
+
+ sema_init(&dhd->proto_sem, 1);
+
+#ifdef PROP_TXSTATUS
+ spin_lock_init(&dhd->wlfc_spinlock);
+#ifdef PROP_TXSTATUS_VSDB
+ dhd->pub.wlfc_enabled = FALSE;
+#else
+ dhd->pub.wlfc_enabled = TRUE;
+#endif /* PROP_TXSTATUS_VSDB */
+#endif /* PROP_TXSTATUS */
+
+ /* Initialize other structure content */
+ init_waitqueue_head(&dhd->ioctl_resp_wait);
+ init_waitqueue_head(&dhd->ctrl_wait);
+
+ /* Initialize the spinlocks */
+ spin_lock_init(&dhd->sdlock);
+ spin_lock_init(&dhd->txqlock);
+ spin_lock_init(&dhd->dhd_lock);
+
+ /* Initialize Wakelock stuff */
+ spin_lock_init(&dhd->wakelock_spinlock);
+ dhd->wakelock_counter = 0;
+ dhd->wakelock_wd_counter = 0;
+ dhd->wakelock_rx_timeout_enable = 0;
+ dhd->wakelock_ctrl_timeout_enable = 0;
+#ifdef CONFIG_HAS_WAKELOCK
+ dhd->wl_wifi = MALLOC(osh, sizeof(struct wake_lock));
+ dhd->wl_rxwake = MALLOC(osh, sizeof(struct wake_lock));
+ dhd->wl_ctrlwake = MALLOC(osh, sizeof(struct wake_lock));
+ dhd->wl_wdwake = MALLOC(osh, sizeof(struct wake_lock));
+ if (!dhd->wl_wifi || !dhd->wl_rxwake || !dhd->wl_ctrlwake || !dhd->wl_wdwake) {
+ AP6210_ERR("%s: mem alloc for wake lock failed\n", __FUNCTION__);
+ goto fail;
+ }
+ wake_lock_init(dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
+ wake_lock_init(dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake");
+ wake_lock_init(dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake");
+ wake_lock_init(dhd->wl_wdwake, WAKE_LOCK_SUSPEND, "wlan_wd_wake");
+#endif /* CONFIG_HAS_WAKELOCK */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ mutex_init(&dhd->dhd_net_if_mutex);
+ mutex_init(&dhd->dhd_suspend_mutex);
+#endif
+ dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT;
+
+ /* Attach and link in the protocol */
+ if (dhd_prot_attach(&dhd->pub) != 0) {
+ AP6210_ERR("dhd_prot_attach failed\n");
+ goto fail;
+ }
+ dhd_state |= DHD_ATTACH_STATE_PROT_ATTACH;
+
+#ifdef WL_CFG80211
+ /* Attach and link in the cfg80211 */
+ if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) {
+ AP6210_ERR("wl_cfg80211_attach failed\n");
+ goto fail;
+ }
+
+ dhd_monitor_init(&dhd->pub);
+ dhd_state |= DHD_ATTACH_STATE_CFG80211;
+#endif
+#if defined(CONFIG_WIRELESS_EXT)
+ /* Attach and link in the iw */
+ if (!(dhd_state & DHD_ATTACH_STATE_CFG80211)) {
+ if (wl_iw_attach(net, (void *)&dhd->pub) != 0) {
+ AP6210_ERR("wl_iw_attach failed\n");
+ goto fail;
+ }
+ dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
+ }
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+
+ /* Set up the watchdog timer */
+ init_timer(&dhd->timer);
+ dhd->timer.data = (ulong)dhd;
+ dhd->timer.function = dhd_watchdog;
+
+#ifdef DHDTHREAD
+ /* Initialize thread based operation and lock */
+ sema_init(&dhd->sdsem, 1);
+ if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0)) {
+ dhd->threads_only = TRUE;
+ }
+ else {
+ dhd->threads_only = FALSE;
+ }
+
+ if (dhd_watchdog_prio >= 0) {
+ /* Initialize watchdog thread */
+#ifdef USE_KTHREAD_API
+ PROC_START2(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0, "dhd_watchdog_thread");
+#else
+ PROC_START(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0);
+#endif
+ } else {
+ dhd->thr_wdt_ctl.thr_pid = -1;
+ }
+
+ /* Set up the bottom half handler */
+ if (dhd_dpc_prio >= 0) {
+ /* Initialize DPC thread */
+#ifdef USE_KTHREAD_API
+ PROC_START2(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0, "dhd_dpc");
+#else
+ PROC_START(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0);
+#endif
+ } else {
+ /* use tasklet for dpc */
+ tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd);
+ dhd->thr_dpc_ctl.thr_pid = -1;
+ }
+#else
+ /* Set up the bottom half handler */
+ tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd);
+ dhd->dhd_tasklet_create = TRUE;
+#endif /* DHDTHREAD */
+
+ if (dhd_sysioc) {
+#ifdef USE_KTHREAD_API
+ PROC_START2(_dhd_sysioc_thread, dhd, &dhd->thr_sysioc_ctl, 0, "dhd_sysioc");
+#else
+ PROC_START(_dhd_sysioc_thread, dhd, &dhd->thr_sysioc_ctl, 0);
+#endif
+ } else {
+ dhd->thr_sysioc_ctl.thr_pid = -1;
+ }
+ dhd_state |= DHD_ATTACH_STATE_THREADS_CREATED;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1)
+ INIT_WORK(&dhd->work_hang, dhd_hang_process);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+ /*
+ * Save the dhd_info into the priv
+ */
+ memcpy(netdev_priv(net), &dhd, sizeof(dhd));
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
+ register_pm_notifier(&dhd_sleep_pm_notifier);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+ dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20;
+ dhd->early_suspend.suspend = dhd_early_suspend;
+ dhd->early_suspend.resume = dhd_late_resume;
+ register_early_suspend(&dhd->early_suspend);
+ dhd_state |= DHD_ATTACH_STATE_EARLYSUSPEND_DONE;
+#endif
+
+#ifdef ARP_OFFLOAD_SUPPORT
+ dhd->pend_ipaddr = 0;
+ register_inetaddr_notifier(&dhd_notifier);
+#endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef IPV6
+ register_inet6addr_notifier(&dhd_notifier_ipv6);
+#endif
+
+#ifdef DHDTCPACK_SUPPRESS
+ dhd->pub.tcp_ack_info_cnt = 0;
+ bzero(dhd->pub.tcp_ack_info_tbl, sizeof(struct tcp_ack_info)*MAXTCPSTREAMS);
+#endif /* DHDTCPACK_SUPPRESS */
+
+ dhd_state |= DHD_ATTACH_STATE_DONE;
+ dhd->dhd_state = dhd_state;
+ return &dhd->pub;
+
+fail:
+ if (dhd_state < DHD_ATTACH_STATE_DHD_ALLOC) {
+ if (net) free_netdev(net);
+ } else {
+ AP6210_DEBUG("%s: Calling dhd_detach dhd_state 0x%x &dhd->pub %p\n",
+ __FUNCTION__, dhd_state, &dhd->pub);
+ dhd->dhd_state = dhd_state;
+ dhd_detach(&dhd->pub);
+ dhd_free(&dhd->pub);
+ }
+
+ return NULL;
+}
+
+int
+dhd_bus_start(dhd_pub_t *dhdp)
+{
+ int ret = -1;
+ dhd_info_t *dhd = (dhd_info_t*)dhdp->info;
+ unsigned long flags;
+
+ ASSERT(dhd);
+
+ AP6210_DEBUG("Enter %s:\n", __FUNCTION__);
+
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ dhd_os_sdlock(dhdp);
+#endif /* DHDTHREAD */
+
+
+ /* try to download image and nvram to the dongle */
+ if ((dhd->pub.busstate == DHD_BUS_DOWN) &&
+ (fw_path != NULL) && (fw_path[0] != '\0') &&
+ (nv_path != NULL) && (nv_path[0] != '\0')) {
+ /* wake lock moved to dhdsdio_download_firmware */
+ if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh,
+ fw_path, nv_path))) {
+ AP6210_ERR("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n",
+ __FUNCTION__, fw_path, nv_path);
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
+ return -1;
+ }
+ }
+ if (dhd->pub.busstate != DHD_BUS_LOAD) {
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
+ return -ENETDOWN;
+ }
+
+ /* Start the watchdog timer */
+ dhd->pub.tickcnt = 0;
+ dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
+
+ /* Bring up the bus */
+ if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) {
+
+ AP6210_ERR("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret);
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
+ return ret;
+ }
+ bcmsdh_set_drvdata(dhdp);
+#if defined(OOB_INTR_ONLY)
+ /* Host registration for OOB interrupt */
+ if (bcmsdh_register_oob_intr(dhdp)) {
+ /* deactivate timer and wait for the handler to finish */
+
+ flags = dhd_os_spin_lock(&dhd->pub);
+ dhd->wd_timer_valid = FALSE;
+ dhd_os_spin_unlock(&dhd->pub, flags);
+ del_timer_sync(&dhd->timer);
+ AP6210_ERR("%s Host failed to register for OOB\n", __FUNCTION__);
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
+ DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+ return -ENODEV;
+ }
+
+ /* Enable oob at firmware */
+ dhd_enable_oob_intr(dhd->pub.bus, TRUE);
+#endif
+
+ /* If bus is not ready, can't come up */
+ if (dhd->pub.busstate != DHD_BUS_DATA) {
+ flags = dhd_os_spin_lock(&dhd->pub);
+ dhd->wd_timer_valid = FALSE;
+ dhd_os_spin_unlock(&dhd->pub, flags);
+ del_timer_sync(&dhd->timer);
+ AP6210_ERR("%s failed bus is not ready\n", __FUNCTION__);
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
+ DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+ return -ENODEV;
+ }
+
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
+
+#ifdef BCMSDIOH_TXGLOM
+ if ((dhd->pub.busstate == DHD_BUS_DATA) && bcmsdh_glom_enabled()) {
+ dhd_txglom_enable(dhdp, TRUE);
+ }
+#endif
+
+#ifdef READ_MACADDR
+ dhd_read_macaddr(dhd);
+#endif
+
+ /* Bus is ready, do any protocol initialization */
+ if ((ret = dhd_prot_init(&dhd->pub)) < 0)
+ return ret;
+
+#ifdef WRITE_MACADDR
+ dhd_write_macaddr(dhd->pub.mac.octet);
+#endif
+
+#ifdef ARP_OFFLOAD_SUPPORT
+ if (dhd->pend_ipaddr) {
+#ifdef AOE_IP_ALIAS_SUPPORT
+ aoe_update_host_ipv4_table(&dhd->pub, dhd->pend_ipaddr, TRUE, 0);
+#endif /* AOE_IP_ALIAS_SUPPORT */
+ dhd->pend_ipaddr = 0;
+ }
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+ return 0;
+}
+
+bool dhd_is_concurrent_mode(dhd_pub_t *dhd)
+{
+ if (!dhd)
+ return FALSE;
+
+ if (dhd->op_mode & DHD_FLAG_CONCURR_MULTI_CHAN_MODE)
+ return TRUE;
+ else if ((dhd->op_mode & DHD_FLAG_CONCURR_SINGLE_CHAN_MODE) ==
+ DHD_FLAG_CONCURR_SINGLE_CHAN_MODE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+#if !defined(AP) && defined(WLP2P)
+/* From Android JerryBean release, the concurrent mode is enabled by default and the firmware
+ * name would be fw_bcmdhd.bin. So we need to determine whether P2P is enabled in the STA
+ * firmware and accordingly enable concurrent mode (Apply P2P settings). SoftAP firmware
+ * would still be named as fw_bcmdhd_apsta.
+ */
+uint32
+dhd_get_concurrent_capabilites(dhd_pub_t *dhd)
+{
+ int32 ret = 0;
+ char buf[WLC_IOCTL_SMLEN];
+ bool mchan_supported = FALSE;
+ /* if dhd->op_mode is already set for HOSTAP,
+ * that means we only will use the mode as it is
+ */
+ if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE)
+ return 0;
+ memset(buf, 0, sizeof(buf));
+ bcm_mkiovar("cap", 0, 0, buf, sizeof(buf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf),
+ FALSE, 0)) < 0) {
+ AP6210_ERR("%s: Get Capability failed (error=%d)\n",
+ __FUNCTION__, ret);
+ return 0;
+ }
+ if (strstr(buf, "vsdb")) {
+ mchan_supported = TRUE;
+ }
+ if (strstr(buf, "p2p") == NULL) {
+ AP6210_DEBUG("Chip does not support p2p\n");
+ return 0;
+ }
+ else {
+ /* Chip supports p2p but ensure that p2p is really implemented in firmware or not */
+ memset(buf, 0, sizeof(buf));
+ bcm_mkiovar("p2p", 0, 0, buf, sizeof(buf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf),
+ FALSE, 0)) < 0) {
+ AP6210_ERR("%s: Get P2P failed (error=%d)\n", __FUNCTION__, ret);
+ return 0;
+ }
+ else {
+ if (buf[0] == 1) {
+ /* By default, chip supports single chan concurrency,
+ * now lets check for mchan
+ */
+ ret = DHD_FLAG_CONCURR_SINGLE_CHAN_MODE;
+ if (mchan_supported)
+ ret |= DHD_FLAG_CONCURR_MULTI_CHAN_MODE;
+#if defined(WL_ENABLE_P2P_IF)
+ /* For customer_hw4, although ICS,
+ * we still support concurrent mode
+ */
+ return ret;
+#else
+ return 0;
+#endif
+ }
+ }
+ }
+ return 0;
+}
+#endif
+int
+dhd_preinit_ioctls(dhd_pub_t *dhd)
+{
+ int ret = 0;
+ char eventmask[WL_EVENTING_MASK_LEN];
+ char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */
+
+#if !defined(WL_CFG80211)
+ uint up = 0;
+#endif /* !defined(WL_CFG80211) */
+ uint power_mode = PM_FAST;
+ uint32 dongle_align = DHD_SDALIGN;
+ uint32 glom = CUSTOM_GLOM_SETTING;
+#if defined(VSDB) || defined(ROAM_ENABLE)
+ uint bcn_timeout = 8;
+#else
+ uint bcn_timeout = 4;
+#endif
+#ifdef ENABLE_BCN_LI_BCN_WAKEUP
+ uint32 bcn_li_bcn = 1;
+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */
+ uint retry_max = 3;
+#if defined(ARP_OFFLOAD_SUPPORT)
+ int arpoe = 1;
+#endif
+ int scan_assoc_time = DHD_SCAN_ASSOC_ACTIVE_TIME;
+ int scan_unassoc_time = DHD_SCAN_UNASSOC_ACTIVE_TIME;
+ int scan_passive_time = DHD_SCAN_PASSIVE_TIME;
+ char buf[WLC_IOCTL_SMLEN];
+ char *ptr;
+ uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
+#ifdef ROAM_ENABLE
+ uint roamvar = 0;
+ int roam_trigger[2] = {CUSTOM_ROAM_TRIGGER_SETTING, WLC_BAND_ALL};
+ int roam_scan_period[2] = {10, WLC_BAND_ALL};
+ int roam_delta[2] = {CUSTOM_ROAM_DELTA_SETTING, WLC_BAND_ALL};
+#ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC
+ int roam_fullscan_period = 60;
+#else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
+ int roam_fullscan_period = 120;
+#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
+#else
+#ifdef DISABLE_BUILTIN_ROAM
+ uint roamvar = 1;
+#endif /* DISABLE_BUILTIN_ROAM */
+#endif /* ROAM_ENABLE */
+
+#if defined(SOFTAP)
+ uint dtim = 1;
+#endif
+#if (defined(AP) && !defined(WLP2P)) || (!defined(AP) && defined(WL_CFG80211))
+ uint32 mpc = 0; /* Turn MPC off for AP/APSTA mode */
+ struct ether_addr p2p_ea;
+#endif
+ uint32 mimo_bw_cap = 1; /* Turn HT40 on in 2.4 GHz */
+
+#if defined(AP) || defined(WLP2P)
+ uint32 apsta = 1; /* Enable APSTA mode */
+#endif /* defined(AP) || defined(WLP2P) */
+#ifdef GET_CUSTOM_MAC_ENABLE
+ struct ether_addr ea_addr;
+#endif /* GET_CUSTOM_MAC_ENABLE */
+#ifdef DISABLE_11N
+ uint32 nmode = 0;
+#else
+#ifdef AMPDU_HOSTREORDER
+ uint32 hostreorder = 1;
+#endif
+#endif /* DISABLE_11N */
+ dhd->suspend_bcn_li_dtim = CUSTOM_SUSPEND_BCN_LI_DTIM;
+#ifdef PROP_TXSTATUS
+#ifdef PROP_TXSTATUS_VSDB
+ dhd->wlfc_enabled = FALSE;
+ /* enable WLFC only if the firmware is VSDB */
+#else
+ dhd->wlfc_enabled = TRUE;
+#endif /* PROP_TXSTATUS_VSDB */
+#endif /* PROP_TXSTATUS */
+ AP6210_DEBUG("Enter %s\n", __FUNCTION__);
+ dhd->op_mode = 0;
+#ifdef GET_CUSTOM_MAC_ENABLE
+ ret = dhd_custom_get_mac_address(ea_addr.octet);
+ if (!ret) {
+ memset(buf, 0, sizeof(buf));
+ bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf));
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
+ if (ret < 0) {
+ AP6210_ERR("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret);
+ return BCME_NOTUP;
+ }
+ memcpy(dhd->mac.octet, ea_addr.octet, ETHER_ADDR_LEN);
+ } else {
+#endif /* GET_CUSTOM_MAC_ENABLE */
+ /* Get the default device MAC address directly from firmware */
+ memset(buf, 0, sizeof(buf));
+ bcm_mkiovar("cur_etheraddr", 0, 0, buf, sizeof(buf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf),
+ FALSE, 0)) < 0) {
+ AP6210_ERR("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret);
+ return BCME_NOTUP;
+ }
+ /* Update public MAC address after reading from Firmware */
+ memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
+
+#ifdef GET_CUSTOM_MAC_ENABLE
+ }
+#endif /* GET_CUSTOM_MAC_ENABLE */
+
+ AP6210_DEBUG("Firmware = %s\n", fw_path);
+
+ if ((!op_mode && strstr(fw_path, "_apsta") != NULL) ||
+ (op_mode == DHD_FLAG_HOSTAP_MODE)) {
+#ifdef SET_RANDOM_MAC_SOFTAP
+ uint rand_mac;
+#endif
+ dhd->op_mode = DHD_FLAG_HOSTAP_MODE;
+#if defined(ARP_OFFLOAD_SUPPORT)
+ arpoe = 0;
+#endif
+#ifdef PKT_FILTER_SUPPORT
+ dhd_pkt_filter_enable = FALSE;
+#endif
+#ifdef SET_RANDOM_MAC_SOFTAP
+ srandom32((uint)jiffies);
+ rand_mac = random32();
+ iovbuf[0] = 0x02; /* locally administered bit */
+ iovbuf[1] = 0x1A;
+ iovbuf[2] = 0x11;
+ iovbuf[3] = (unsigned char)(rand_mac & 0x0F) | 0xF0;
+ iovbuf[4] = (unsigned char)(rand_mac >> 8);
+ iovbuf[5] = (unsigned char)(rand_mac >> 16);
+
+ bcm_mkiovar("cur_etheraddr", (void *)iovbuf, ETHER_ADDR_LEN, buf, sizeof(buf));
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
+ if (ret < 0) {
+ AP6210_ERR("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret);
+ } else
+ memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN);
+#endif /* SET_RANDOM_MAC_SOFTAP */
+#if !defined(AP) && defined(WL_CFG80211)
+ /* Turn off MPC in AP mode */
+ bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
+ sizeof(iovbuf), TRUE, 0)) < 0) {
+ AP6210_ERR("%s mpc for HostAPD failed %d\n", __FUNCTION__, ret);
+ }
+#endif
+
+ }
+ else {
+ uint32 concurrent_mode = 0;
+ if ((!op_mode && strstr(fw_path, "_p2p") != NULL) ||
+ (op_mode == DHD_FLAG_P2P_MODE)) {
+#if defined(ARP_OFFLOAD_SUPPORT)
+ arpoe = 0;
+#endif
+#ifdef PKT_FILTER_SUPPORT
+ dhd_pkt_filter_enable = FALSE;
+#endif
+ dhd->op_mode = DHD_FLAG_P2P_MODE;
+ }
+ else
+ dhd->op_mode = DHD_FLAG_STA_MODE;
+#if !defined(AP) && defined(WLP2P)
+ if ((concurrent_mode = dhd_get_concurrent_capabilites(dhd))) {
+#if defined(ARP_OFFLOAD_SUPPORT)
+ arpoe = 1;
+#endif
+ dhd->op_mode |= concurrent_mode;
+ }
+
+ /* Check if we are enabling p2p */
+ if (dhd->op_mode & DHD_FLAG_P2P_MODE) {
+ bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
+ iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+ AP6210_ERR("%s APSTA for P2P failed ret= %d\n", __FUNCTION__, ret);
+ }
+
+ memcpy(&p2p_ea, &dhd->mac, ETHER_ADDR_LEN);
+ ETHER_SET_LOCALADDR(&p2p_ea);
+ bcm_mkiovar("p2p_da_override", (char *)&p2p_ea,
+ ETHER_ADDR_LEN, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
+ iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+ AP6210_ERR("%s p2p_da_override ret= %d\n", __FUNCTION__, ret);
+ } else {
+ AP6210_DEBUG("dhd_preinit_ioctls: p2p_da_override succeeded\n");
+ }
+ }
+#else
+ (void)concurrent_mode;
+#endif
+ }
+
+ AP6210_ERR("Firmware up: op_mode=0x%04x, "
+ "Broadcom Dongle Host Driver mac="MACDBG"\n",
+ dhd->op_mode,
+ MAC2STRDBG(dhd->mac.octet));
+ /* Set Country code */
+ if (dhd->dhd_cspec.ccode[0] != 0) {
+ bcm_mkiovar("country", (char *)&dhd->dhd_cspec,
+ sizeof(wl_country_t), iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+ AP6210_ERR("%s: country code setting failed\n", __FUNCTION__);
+ }
+
+ /* Set Listen Interval */
+ bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+ AP6210_ERR("%s assoc_listen failed %d\n", __FUNCTION__, ret);
+
+#if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
+ /* Disable built-in roaming to allowed ext supplicant to take care of roaming */
+ bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */
+#ifdef ROAM_ENABLE
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, roam_trigger,
+ sizeof(roam_trigger), TRUE, 0)) < 0)
+ AP6210_ERR("%s: roam trigger set failed %d\n", __FUNCTION__, ret);
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_SCAN_PERIOD, roam_scan_period,
+ sizeof(roam_scan_period), TRUE, 0)) < 0)
+ AP6210_ERR("%s: roam scan period set failed %d\n", __FUNCTION__, ret);
+ if ((dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, roam_delta,
+ sizeof(roam_delta), TRUE, 0)) < 0)
+ AP6210_ERR("%s: roam delta set failed %d\n", __FUNCTION__, ret);
+ bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, 4, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+ AP6210_ERR("%s: roam fullscan period set failed %d\n", __FUNCTION__, ret);
+#endif /* ROAM_ENABLE */
+
+ /* Set PowerSave mode */
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
+
+ /* Match Host and Dongle rx alignment */
+ bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+
+ if (glom != DEFAULT_GLOM_VALUE) {
+ AP6210_DEBUG("%s set glom=0x%X\n", __FUNCTION__, glom);
+ bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ }
+
+ /* Setup timeout if Beacons are lost and roam is off to report link down */
+ bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ /* Setup assoc_retry_max count to reconnect target AP in dongle */
+ bcm_mkiovar("assoc_retry_max", (char *)&retry_max, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#if defined(AP) && !defined(WLP2P)
+ /* Turn off MPC in AP mode */
+ bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif /* defined(AP) && !defined(WLP2P) */
+
+ if (dhd_bus_chip_id(dhd) == BCM43341_CHIP_ID || dhd_bus_chip_id(dhd) == BCM4324_CHIP_ID) {
+ /* Turn on HT40 in 2.4 GHz */
+ bcm_mkiovar("mimo_bw_cap", (char *)&mimo_bw_cap, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ }
+
+#if defined(SOFTAP)
+ if (ap_fw_loaded == TRUE) {
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim), TRUE, 0);
+ }
+#endif
+
+#if defined(KEEP_ALIVE)
+ {
+ /* Set Keep Alive : be sure to use FW with -keepalive */
+ int res;
+
+#if defined(SOFTAP)
+ if (ap_fw_loaded == FALSE)
+#endif
+ if (!(dhd->op_mode & DHD_FLAG_HOSTAP_MODE)) {
+ if ((res = dhd_keep_alive_onoff(dhd)) < 0)
+ AP6210_ERR("%s set keeplive failed %d\n",
+ __FUNCTION__, res);
+ }
+ }
+#endif /* defined(KEEP_ALIVE) */
+
+ /* Read event_msgs mask */
+ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {
+ AP6210_ERR("%s read Event mask failed %d\n", __FUNCTION__, ret);
+ goto done;
+ }
+ bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN);
+
+ /* Setup event_msgs */
+ setbit(eventmask, WLC_E_SET_SSID);
+ setbit(eventmask, WLC_E_PRUNE);
+ setbit(eventmask, WLC_E_AUTH);
+ setbit(eventmask, WLC_E_ASSOC);
+ setbit(eventmask, WLC_E_REASSOC);
+ setbit(eventmask, WLC_E_REASSOC_IND);
+ setbit(eventmask, WLC_E_DEAUTH);
+ setbit(eventmask, WLC_E_DEAUTH_IND);
+ setbit(eventmask, WLC_E_DISASSOC_IND);
+ setbit(eventmask, WLC_E_DISASSOC);
+ setbit(eventmask, WLC_E_JOIN);
+ setbit(eventmask, WLC_E_ASSOC_IND);
+ setbit(eventmask, WLC_E_PSK_SUP);
+ setbit(eventmask, WLC_E_LINK);
+ setbit(eventmask, WLC_E_NDIS_LINK);
+ setbit(eventmask, WLC_E_MIC_ERROR);
+ setbit(eventmask, WLC_E_ASSOC_REQ_IE);
+ setbit(eventmask, WLC_E_ASSOC_RESP_IE);
+#ifndef WL_CFG80211
+ setbit(eventmask, WLC_E_PMKID_CACHE);
+ setbit(eventmask, WLC_E_TXFAIL);
+#endif
+ setbit(eventmask, WLC_E_JOIN_START);
+ setbit(eventmask, WLC_E_SCAN_COMPLETE);
+#ifdef WLMEDIA_HTSF
+ setbit(eventmask, WLC_E_HTSFSYNC);
+#endif /* WLMEDIA_HTSF */
+#ifdef PNO_SUPPORT
+ setbit(eventmask, WLC_E_PFN_NET_FOUND);
+#endif /* PNO_SUPPORT */
+ /* enable dongle roaming event */
+ setbit(eventmask, WLC_E_ROAM);
+#ifdef WL_CFG80211
+ setbit(eventmask, WLC_E_ESCAN_RESULT);
+ if (dhd->op_mode & DHD_FLAG_P2P_MODE) {
+ setbit(eventmask, WLC_E_ACTION_FRAME_RX);
+ setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE);
+ }
+#endif /* WL_CFG80211 */
+
+ /* Write updated Event mask */
+ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+ AP6210_ERR("%s Set Event mask failed %d\n", __FUNCTION__, ret);
+ goto done;
+ }
+
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time,
+ sizeof(scan_assoc_time), TRUE, 0);
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time,
+ sizeof(scan_unassoc_time), TRUE, 0);
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_PASSIVE_TIME, (char *)&scan_passive_time,
+ sizeof(scan_passive_time), TRUE, 0);
+
+#ifdef ARP_OFFLOAD_SUPPORT
+ /* Set and enable ARP offload feature for STA only */
+#if defined(SOFTAP)
+ if (arpoe && !ap_fw_loaded) {
+#else
+ if (arpoe) {
+#endif
+ dhd_arp_offload_enable(dhd, TRUE);
+ dhd_arp_offload_set(dhd, dhd_arp_mode);
+ } else {
+ dhd_arp_offload_enable(dhd, FALSE);
+ dhd_arp_offload_set(dhd, 0);
+ }
+ dhd_arp_enable = arpoe;
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#ifdef PKT_FILTER_SUPPORT
+ /* Setup default defintions for pktfilter , enable in suspend */
+ dhd->pktfilter_count = 5;
+ /* Setup filter to allow only unicast */
+ dhd->pktfilter[0] = "100 0 0 0 0x01 0x00";
+ dhd->pktfilter[1] = NULL;
+ dhd->pktfilter[2] = NULL;
+ dhd->pktfilter[3] = NULL;
+ /* Add filter to pass multicastDNS packet and NOT filter out as Broadcast */
+ dhd->pktfilter[4] = "104 0 0 0 0xFFFFFFFFFFFF 0x01005E0000FB";
+ dhd_set_packet_filter(dhd);
+
+#if defined(SOFTAP)
+ if (ap_fw_loaded) {
+ dhd_enable_packet_filter(0, dhd);
+ }
+#endif /* defined(SOFTAP) */
+
+#endif /* PKT_FILTER_SUPPORT */
+#ifdef DISABLE_11N
+ bcm_mkiovar("nmode", (char *)&nmode, 4, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+ AP6210_ERR("%s wl nmode 0 failed %d\n", __FUNCTION__, ret);
+#else
+#ifdef AMPDU_HOSTREORDER
+ bcm_mkiovar("ampdu_hostreorder", (char *)&hostreorder, 4, buf, sizeof(buf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
+#endif /* AMPDU_HOSTREORDER */
+#endif /* DISABLE_11N */
+
+#if !defined(WL_CFG80211)
+ /* Force STA UP */
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&up, sizeof(up), TRUE, 0)) < 0) {
+ AP6210_ERR("%s Setting WL UP failed %d\n", __FUNCTION__, ret);
+ goto done;
+ }
+#endif
+
+#ifdef ENABLE_BCN_LI_BCN_WAKEUP
+ bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */
+
+ /* query for 'ver' to get version info from firmware */
+ memset(buf, 0, sizeof(buf));
+ ptr = buf;
+ bcm_mkiovar("ver", (char *)&buf, 4, buf, sizeof(buf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0)
+ AP6210_ERR("%s failed %d\n", __FUNCTION__, ret);
+ else {
+ bcmstrtok(&ptr, "\n", 0);
+ /* Print fw version info */
+ AP6210_ERR("Firmware version = %s\n", buf);
+
+ dhd_set_version_info(dhd, buf);
+
+ DHD_BLOG(buf, strlen(buf) + 1);
+ DHD_BLOG(dhd_version, strlen(dhd_version) + 1);
+ DHD_BLOG(dhd_version_info, strlen(dhd_version_info) +1);
+
+ /* Check and adjust IOCTL response timeout for Manufactring firmware */
+ if (strstr(buf, MANUFACTRING_FW) != NULL) {
+ dhd_os_set_ioctl_resp_timeout(20000);
+ AP6210_ERR("%s : adjust IOCTL response time for Manufactring Firmware\n",
+ __FUNCTION__);
+ }
+ }
+
+done:
+ return ret;
+}
+
+
+int
+dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set)
+{
+ char buf[strlen(name) + 1 + cmd_len];
+ int len = sizeof(buf);
+ wl_ioctl_t ioc;
+ int ret;
+
+ len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len);
+
+ memset(&ioc, 0, sizeof(ioc));
+
+ ioc.cmd = set? WLC_SET_VAR : WLC_GET_VAR;
+ ioc.buf = buf;
+ ioc.len = len;
+ ioc.set = TRUE;
+
+ ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+ if (!set && ret >= 0)
+ memcpy(cmd_buf, buf, cmd_len);
+
+ return ret;
+}
+
+int dhd_change_mtu(dhd_pub_t *dhdp, int new_mtu, int ifidx)
+{
+ struct dhd_info *dhd = dhdp->info;
+ struct net_device *dev = NULL;
+
+ ASSERT(dhd && dhd->iflist[ifidx]);
+ dev = dhd->iflist[ifidx]->net;
+ ASSERT(dev);
+
+ if (netif_running(dev)) {
+ AP6210_ERR("%s: Must be down to change its MTU", dev->name);
+ return BCME_NOTDOWN;
+ }
+
+#define DHD_MIN_MTU 1500
+#define DHD_MAX_MTU 1752
+
+ if ((new_mtu < DHD_MIN_MTU) || (new_mtu > DHD_MAX_MTU)) {
+ AP6210_ERR("%s: MTU size %d is invalid.\n", __FUNCTION__, new_mtu);
+ return BCME_BADARG;
+ }
+
+ dev->mtu = new_mtu;
+ return 0;
+}
+
+#ifdef ARP_OFFLOAD_SUPPORT
+/* add or remove AOE host ip(s) (up to 8 IPs on the interface) */
+void
+aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add, int idx)
+{
+ u32 ipv4_buf[MAX_IPV4_ENTRIES]; /* temp save for AOE host_ip table */
+ int i;
+ int ret;
+
+ bzero(ipv4_buf, sizeof(ipv4_buf));
+
+ /* display what we've got */
+ ret = dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf), idx);
+ AP6210_DEBUG("%s: hostip table read from Dongle:\n", __FUNCTION__);
+#ifdef AOE_DBG
+ dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */
+#endif
+ /* now we saved hoste_ip table, clr it in the dongle AOE */
+ dhd_aoe_hostip_clr(dhd_pub, idx);
+
+ if (ret) {
+ AP6210_ERR("%s failed\n", __FUNCTION__);
+ return;
+ }
+
+ for (i = 0; i < MAX_IPV4_ENTRIES; i++) {
+ if (add && (ipv4_buf[i] == 0)) {
+ ipv4_buf[i] = ipa;
+ add = FALSE; /* added ipa to local table */
+ AP6210_DEBUG("%s: Saved new IP in temp arp_hostip[%d]\n",
+ __FUNCTION__, i);
+ } else if (ipv4_buf[i] == ipa) {
+ ipv4_buf[i] = 0;
+ AP6210_DEBUG("%s: removed IP:%x from temp table %d\n",
+ __FUNCTION__, ipa, i);
+ }
+
+ if (ipv4_buf[i] != 0) {
+ /* add back host_ip entries from our local cache */
+ dhd_arp_offload_add_ip(dhd_pub, ipv4_buf[i], idx);
+ AP6210_DEBUG("%s: added IP:%x to dongle arp_hostip[%d]\n\n",
+ __FUNCTION__, ipv4_buf[i], i);
+ }
+ }
+#ifdef AOE_DBG
+ /* see the resulting hostip table */
+ dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf), idx);
+ AP6210_DEBUG("%s: read back arp_hostip table:\n", __FUNCTION__);
+ dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */
+#endif
+}
+
+/*
+ * Notification mechanism from kernel to our driver. This function is called by the Linux kernel
+ * whenever there is an event related to an IP address.
+ * ptr : kernel provided pointer to IP address that has changed
+ */
+static int dhd_device_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+
+ dhd_info_t *dhd;
+ dhd_pub_t *dhd_pub;
+ int idx;
+
+ if (!dhd_arp_enable)
+ return NOTIFY_DONE;
+ if (!ifa || !(ifa->ifa_dev->dev))
+ return NOTIFY_DONE;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
+ /* Filter notifications meant for non Broadcom devices */
+ if ((ifa->ifa_dev->dev->netdev_ops != &dhd_ops_pri) &&
+ (ifa->ifa_dev->dev->netdev_ops != &dhd_ops_virt)) {
+#ifdef WLP2P
+ if (!wl_cfgp2p_is_ifops(ifa->ifa_dev->dev->netdev_ops))
+#endif
+ return NOTIFY_DONE;
+ }
+#endif /* LINUX_VERSION_CODE */
+
+ dhd = *(dhd_info_t **)netdev_priv(ifa->ifa_dev->dev);
+ if (!dhd)
+ return NOTIFY_DONE;
+
+ dhd_pub = &dhd->pub;
+
+ if (dhd_pub->arp_version == 1) {
+ idx = 0;
+ }
+ else {
+ for (idx = 0; idx < DHD_MAX_IFS; idx++) {
+ if (dhd->iflist[idx] && dhd->iflist[idx]->net == ifa->ifa_dev->dev)
+ break;
+ }
+ if (idx < DHD_MAX_IFS)
+ AP6210_DEBUG("ifidx : %p %s %d\n", dhd->iflist[idx]->net,
+ dhd->iflist[idx]->name, dhd->iflist[idx]->idx);
+ else {
+ AP6210_ERR("Cannot find ifidx for(%s) set to 0\n", ifa->ifa_label);
+ idx = 0;
+ }
+ }
+
+ switch (event) {
+ case NETDEV_UP:
+ AP6210_DEBUG("%s: [%s] Up IP: 0x%x\n",
+ __FUNCTION__, ifa->ifa_label, ifa->ifa_address);
+
+ if (dhd->pub.busstate != DHD_BUS_DATA) {
+ AP6210_ERR("%s: bus not ready, exit\n", __FUNCTION__);
+ if (dhd->pend_ipaddr) {
+ AP6210_ERR("%s: overwrite pending ipaddr: 0x%x\n",
+ __FUNCTION__, dhd->pend_ipaddr);
+ }
+ dhd->pend_ipaddr = ifa->ifa_address;
+ break;
+ }
+
+#ifdef AOE_IP_ALIAS_SUPPORT
+ AP6210_DEBUG("%s:add aliased IP to AOE hostip cache\n",
+ __FUNCTION__);
+ aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE, idx);
+#endif
+ break;
+
+ case NETDEV_DOWN:
+ AP6210_DEBUG("%s: [%s] Down IP: 0x%x\n",
+ __FUNCTION__, ifa->ifa_label, ifa->ifa_address);
+ dhd->pend_ipaddr = 0;
+#ifdef AOE_IP_ALIAS_SUPPORT
+ AP6210_DEBUG("%s:interface is down, AOE clr all for this if\n",
+ __FUNCTION__);
+ aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE, idx);
+#else
+ dhd_aoe_hostip_clr(&dhd->pub, idx);
+ dhd_aoe_arp_clr(&dhd->pub, idx);
+#endif /* AOE_IP_ALIAS_SUPPORT */
+ break;
+
+ default:
+ AP6210_DEBUG("%s: do noting for [%s] Event: %lu\n",
+ __func__, ifa->ifa_label, event);
+ break;
+ }
+ return NOTIFY_DONE;
+}
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+int
+dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
+{
+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+ struct net_device *net = NULL;
+ int err = 0;
+ uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33 };
+
+ AP6210_DEBUG("%s: ifidx %d\n", __FUNCTION__, ifidx);
+
+ ASSERT(dhd && dhd->iflist[ifidx]);
+
+ net = dhd->iflist[ifidx]->net;
+ ASSERT(net);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+ ASSERT(!net->open);
+ net->get_stats = dhd_get_stats;
+ net->do_ioctl = dhd_ioctl_entry;
+ net->hard_start_xmit = dhd_start_xmit;
+ net->set_mac_address = dhd_set_mac_address;
+ net->set_multicast_list = dhd_set_multicast_list;
+ net->open = net->stop = NULL;
+#else
+ ASSERT(!net->netdev_ops);
+ net->netdev_ops = &dhd_ops_virt;
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */
+
+ /* Ok, link into the network layer... */
+ if (ifidx == 0) {
+ /*
+ * device functions for the primary interface only
+ */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+ net->open = dhd_open;
+ net->stop = dhd_stop;
+#else
+ net->netdev_ops = &dhd_ops_pri;
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */
+ if (!ETHER_ISNULLADDR(dhd->pub.mac.octet))
+ memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN);
+ } else {
+ /*
+ * We have to use the primary MAC for virtual interfaces
+ */
+ memcpy(temp_addr, dhd->iflist[ifidx]->mac_addr, ETHER_ADDR_LEN);
+ /*
+ * Android sets the locally administered bit to indicate that this is a
+ * portable hotspot. This will not work in simultaneous AP/STA mode,
+ * nor with P2P. Need to set the Donlge's MAC address, and then use that.
+ */
+ if (!memcmp(temp_addr, dhd->iflist[0]->mac_addr,
+ ETHER_ADDR_LEN)) {
+ AP6210_ERR("%s interface [%s]: set locally administered bit in MAC\n",
+ __func__, net->name);
+ temp_addr[0] |= 0x02;
+ }
+ }
+
+ net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+ net->ethtool_ops = &dhd_ethtool_ops;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */
+
+#if defined(CONFIG_WIRELESS_EXT)
+#if WIRELESS_EXT < 19
+ net->get_wireless_stats = dhd_get_wireless_stats;
+#endif /* WIRELESS_EXT < 19 */
+#if WIRELESS_EXT > 12
+ net->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def;
+#endif /* WIRELESS_EXT > 12 */
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+ dhd->pub.rxsz = DBUS_RX_BUFFER_SIZE_DHD(net);
+
+ memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN);
+
+ if ((err = register_netdev(net)) != 0) {
+ AP6210_ERR("couldn't register the net device, err %d\n", err);
+ goto fail;
+ }
+ AP6210_ERR("Broadcom Dongle Host Driver: register interface [%s] MAC: "MACDBG"\n",
+ net->name,
+ MAC2STRDBG(net->dev_addr));
+
+#if defined(SOFTAP) && defined(CONFIG_WIRELESS_EXT) && !defined(WL_CFG80211)
+ wl_iw_iscan_set_scan_broadcast_prep(net, 1);
+#endif
+
+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ if (ifidx == 0) {
+ dhd_registration_check = TRUE;
+ up(&dhd_registration_sem);
+ }
+#endif
+ return 0;
+
+fail:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+ net->open = NULL;
+#else
+ net->netdev_ops = NULL;
+#endif
+ return err;
+}
+
+void
+dhd_bus_detach(dhd_pub_t *dhdp)
+{
+ dhd_info_t *dhd;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (dhdp) {
+ dhd = (dhd_info_t *)dhdp->info;
+ if (dhd) {
+
+ /*
+ * In case of Android cfg80211 driver, the bus is down in dhd_stop,
+ * calling stop again will cuase SD read/write errors.
+ */
+ if (dhd->pub.busstate != DHD_BUS_DOWN) {
+ /* Stop the protocol module */
+ dhd_prot_stop(&dhd->pub);
+
+ /* Stop the bus module */
+ dhd_bus_stop(dhd->pub.bus, TRUE);
+ }
+
+#if defined(OOB_INTR_ONLY)
+ bcmsdh_unregister_oob_intr();
+#endif
+ }
+ }
+}
+
+
+void dhd_detach(dhd_pub_t *dhdp)
+{
+ dhd_info_t *dhd;
+ unsigned long flags;
+ int timer_valid = FALSE;
+
+ if (!dhdp)
+ return;
+
+ dhd = (dhd_info_t *)dhdp->info;
+ if (!dhd)
+ return;
+
+ AP6210_DEBUG("%s: Enter state 0x%x\n", __FUNCTION__, dhd->dhd_state);
+#ifdef ARP_OFFLOAD_SUPPORT
+ unregister_inetaddr_notifier(&dhd_notifier);
+#endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef IPV6
+ unregister_inet6addr_notifier(&dhd_notifier_ipv6);
+#endif
+
+ dhd->pub.up = 0;
+ if (!(dhd->dhd_state & DHD_ATTACH_STATE_DONE)) {
+ /* Give sufficient time for threads to start running in case
+ * dhd_attach() has failed
+ */
+ osl_delay(1000*100);
+ }
+
+ if (dhd->dhd_state & DHD_ATTACH_STATE_PROT_ATTACH) {
+ dhd_bus_detach(dhdp);
+
+ if (dhdp->prot)
+ dhd_prot_detach(dhdp);
+ }
+
+#ifdef ARP_OFFLOAD_SUPPORT
+ unregister_inetaddr_notifier(&dhd_notifier);
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+ if (dhd->dhd_state & DHD_ATTACH_STATE_EARLYSUSPEND_DONE) {
+ if (dhd->early_suspend.suspend)
+ unregister_early_suspend(&dhd->early_suspend);
+ }
+#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ cancel_work_sync(&dhd->work_hang);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+
+#if defined(CONFIG_WIRELESS_EXT)
+ if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) {
+ /* Detatch and unlink in the iw */
+ wl_iw_detach();
+ }
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+ if (dhd->thr_sysioc_ctl.thr_pid >= 0) {
+ PROC_STOP(&dhd->thr_sysioc_ctl);
+ }
+
+ /* delete all interfaces, start with virtual */
+ if (dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) {
+ int i = 1;
+ dhd_if_t *ifp;
+
+ /* Cleanup virtual interfaces */
+ for (i = 1; i < DHD_MAX_IFS; i++) {
+ dhd_net_if_lock_local(dhd);
+ if (dhd->iflist[i]) {
+ dhd->iflist[i]->state = DHD_IF_DEL;
+ dhd->iflist[i]->idx = i;
+ dhd_op_if(dhd->iflist[i]);
+ }
+
+ dhd_net_if_unlock_local(dhd);
+ }
+ /* delete primary interface 0 */
+ ifp = dhd->iflist[0];
+ ASSERT(ifp);
+ ASSERT(ifp->net);
+ if (ifp && ifp->net) {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+ if (ifp->net->open)
+#else
+ if (ifp->net->netdev_ops == &dhd_ops_pri)
+#endif
+ {
+ unregister_netdev(ifp->net);
+ free_netdev(ifp->net);
+ ifp->net = NULL;
+ MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
+ dhd->iflist[0] = NULL;
+ }
+ }
+ }
+
+ /* Clear the watchdog timer */
+ flags = dhd_os_spin_lock(&dhd->pub);
+ timer_valid = dhd->wd_timer_valid;
+ dhd->wd_timer_valid = FALSE;
+ dhd_os_spin_unlock(&dhd->pub, flags);
+ if (timer_valid)
+ del_timer_sync(&dhd->timer);
+
+ if (dhd->dhd_state & DHD_ATTACH_STATE_THREADS_CREATED) {
+#ifdef DHDTHREAD
+ if (dhd->thr_wdt_ctl.thr_pid >= 0) {
+ PROC_STOP(&dhd->thr_wdt_ctl);
+ }
+
+ if (dhd->thr_dpc_ctl.thr_pid >= 0) {
+ PROC_STOP(&dhd->thr_dpc_ctl);
+ }
+ else
+#endif /* DHDTHREAD */
+ tasklet_kill(&dhd->tasklet);
+ }
+
+#ifdef WL_CFG80211
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
+ wl_cfg80211_detach(NULL);
+ dhd_monitor_uninit();
+ }
+#endif
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
+ unregister_pm_notifier(&dhd_sleep_pm_notifier);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
+ /* && defined(CONFIG_PM_SLEEP) */
+
+ if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) {
+#ifdef CONFIG_HAS_WAKELOCK
+ dhd->wakelock_counter = 0;
+ dhd->wakelock_wd_counter = 0;
+ dhd->wakelock_rx_timeout_enable = 0;
+ dhd->wakelock_ctrl_timeout_enable = 0;
+ if (dhd->wl_wifi) {
+ wake_lock_destroy(dhd->wl_wifi);
+ MFREE(dhd->pub.osh, dhd->wl_wifi, sizeof(struct wake_lock));
+ dhd->wl_wifi = NULL;
+ }
+ if (dhd->wl_rxwake) {
+ wake_lock_destroy(dhd->wl_rxwake);
+ MFREE(dhd->pub.osh, dhd->wl_rxwake, sizeof(struct wake_lock));
+ dhd->wl_rxwake = NULL;
+ }
+ if (dhd->wl_ctrlwake) {
+ wake_lock_destroy(dhd->wl_ctrlwake);
+ MFREE(dhd->pub.osh, dhd->wl_ctrlwake, sizeof(struct wake_lock));
+ dhd->wl_ctrlwake = NULL;
+ }
+ if (dhd->wl_wdwake) {
+ wake_lock_destroy(dhd->wl_wdwake);
+ MFREE(dhd->pub.osh, dhd->wl_wdwake, sizeof(struct wake_lock));
+ dhd->wl_wdwake = NULL;
+ }
+#endif /* CONFIG_HAS_WAKELOCK */
+ }
+}
+
+
+void
+dhd_free(dhd_pub_t *dhdp)
+{
+ dhd_info_t *dhd;
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (dhdp) {
+ int i;
+ for (i = 0; i < ARRAYSIZE(dhdp->reorder_bufs); i++) {
+ if (dhdp->reorder_bufs[i]) {
+ reorder_info_t *ptr;
+ uint32 buf_size = sizeof(struct reorder_info);
+
+ ptr = dhdp->reorder_bufs[i];
+
+ buf_size += ((ptr->max_idx + 1) * sizeof(void*));
+ AP6210_DEBUG("free flow id buf %d, maxidx is %d, buf_size %d\n",
+ i, ptr->max_idx, buf_size);
+
+ MFREE(dhdp->osh, dhdp->reorder_bufs[i], buf_size);
+ dhdp->reorder_bufs[i] = NULL;
+ }
+ }
+ dhd = (dhd_info_t *)dhdp->info;
+ if (dhd)
+ MFREE(dhd->pub.osh, dhd, sizeof(*dhd));
+ }
+}
+
+static void __exit
+dhd_module_cleanup(void)
+{
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ dhd_bus_unregister();
+
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+ wl_android_wifictrl_func_del();
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
+ wl_android_exit();
+
+ /* Call customer gpio to turn off power with WL_REG_ON signal */
+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+
+ if (wl_host_wake > 0)
+ gpio_free(wl_host_wake);
+ wl_host_wake = -1;
+
+ sw_rfkill_exit();
+ ap6210_gpio_wifi_exit();
+}
+
+
+static int __init
+dhd_module_init(void)
+{
+ int error = 0;
+
+#if 1 && defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ int retry = POWERUP_MAX_RETRY;
+ int chip_up = 0;
+#endif
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ ap6210_gpio_wifi_init();
+ sw_rfkill_init();
+
+ if (gpio_request(WL_HOST_WAKE_DEF_GPIO, "wl_host_wake")) {
+ AP6210_ERR("[%s] get wl_host_wake gpio failed\n", __FUNCTION__);
+ wl_host_wake = -1;
+ return -1;
+ }
+ wl_host_wake = WL_HOST_WAKE_DEF_GPIO;
+ gpio_direction_input(wl_host_wake);
+ wl_host_wake_irqno = gpio_to_irq(wl_host_wake);
+ AP6210_DEBUG("got gpio%d, mapped to irqno%d\n", wl_host_wake, wl_host_wake_irqno);
+
+ wl_android_init();
+
+#if defined(DHDTHREAD)
+ /* Sanity check on the module parameters */
+ do {
+ /* Both watchdog and DPC as tasklets are ok */
+ if ((dhd_watchdog_prio < 0) && (dhd_dpc_prio < 0))
+ break;
+
+ /* If both watchdog and DPC are threads, TX must be deferred */
+ if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0) && dhd_deferred_tx)
+ break;
+
+ AP6210_ERR("Invalid module parameters.\n");
+ return -EINVAL;
+ } while (0);
+#endif
+
+#if 1 && defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ do {
+ sema_init(&dhd_chipup_sem, 0);
+ dhd_bus_reg_sdio_notify(&dhd_chipup_sem);
+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+ if (wl_android_wifictrl_func_add() < 0) {
+ dhd_bus_unreg_sdio_notify();
+ goto fail_1;
+ }
+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
+ if (down_timeout(&dhd_chipup_sem,
+ msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) {
+ dhd_bus_unreg_sdio_notify();
+ chip_up = 1;
+ break;
+ }
+ AP6210_ERR("failed to power up wifi chip, retry again (%d left) **\n\n",
+ retry+1);
+ dhd_bus_unreg_sdio_notify();
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+ wl_android_wifictrl_func_del();
+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+ } while (retry-- > 0);
+
+ if (!chip_up) {
+ AP6210_ERR("failed to power up wifi chip, max retry reached, exits **\n\n");
+ return -ENODEV;
+ }
+#else
+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+ if (wl_android_wifictrl_func_add() < 0)
+ goto fail_1;
+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
+
+#endif
+
+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ sema_init(&dhd_registration_sem, 0);
+#endif
+
+
+ error = dhd_bus_register();
+
+ if (!error)
+ AP6210_DEBUG("%s\n", dhd_version);
+ else {
+ AP6210_ERR("%s: sdio_register_driver failed\n", __FUNCTION__);
+ goto fail_1;
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ /*
+ * Wait till MMC sdio_register_driver callback called and made driver attach.
+ * It's needed to make sync up exit from dhd insmod and
+ * Kernel MMC sdio device callback registration
+ */
+ if ((down_timeout(&dhd_registration_sem,
+ msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)) != 0) ||
+ (dhd_registration_check != TRUE)) {
+ error = -ENODEV;
+ AP6210_ERR("%s: sdio_register_driver timeout or error \n", __FUNCTION__);
+ goto fail_2;
+ }
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+#if defined(WL_CFG80211)
+ wl_android_post_init();
+#endif /* defined(WL_CFG80211) */
+
+ return error;
+
+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+fail_2:
+ dhd_bus_unregister();
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+
+fail_1:
+
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+ wl_android_wifictrl_func_del();
+#endif
+
+ /* Call customer gpio to turn off power with WL_REG_ON signal */
+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+
+ return error;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+late_initcall(dhd_module_init);
+#else
+module_init(dhd_module_init);
+#endif
+
+module_exit(dhd_module_cleanup);
+
+/*
+ * OS specific functions required to implement DHD driver in OS independent way
+ */
+int
+dhd_os_proto_block(dhd_pub_t *pub)
+{
+ dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+
+ if (dhd) {
+ down(&dhd->proto_sem);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+dhd_os_proto_unblock(dhd_pub_t *pub)
+{
+ dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+
+ if (dhd) {
+ up(&dhd->proto_sem);
+ return 1;
+ }
+
+ return 0;
+}
+
+unsigned int
+dhd_os_get_ioctl_resp_timeout(void)
+{
+ return ((unsigned int)dhd_ioctl_timeout_msec);
+}
+
+void
+dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec)
+{
+ dhd_ioctl_timeout_msec = (int)timeout_msec;
+}
+
+int
+dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending)
+{
+ dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+ int timeout;
+
+ /* Convert timeout in millsecond to jiffies */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ timeout = msecs_to_jiffies(dhd_ioctl_timeout_msec);
+#else
+ timeout = dhd_ioctl_timeout_msec * HZ / 1000;
+#endif
+
+ timeout = wait_event_timeout(dhd->ioctl_resp_wait, (*condition), timeout);
+ return timeout;
+}
+
+int
+dhd_os_ioctl_resp_wake(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+ if (waitqueue_active(&dhd->ioctl_resp_wait)) {
+ wake_up(&dhd->ioctl_resp_wait);
+ }
+
+ return 0;
+}
+
+void
+dhd_os_wd_timer(void *bus, uint wdtick)
+{
+ dhd_pub_t *pub = bus;
+ dhd_info_t *dhd = (dhd_info_t *)pub->info;
+ unsigned long flags;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (!dhd)
+ return;
+ if (wdtick)
+ DHD_OS_WD_WAKE_LOCK(pub);
+
+ flags = dhd_os_spin_lock(pub);
+
+ /* don't start the wd until fw is loaded */
+ if (pub->busstate == DHD_BUS_DOWN) {
+ dhd_os_spin_unlock(pub, flags);
+ DHD_OS_WD_WAKE_UNLOCK(pub);
+ return;
+ }
+
+ /* totally stop the timer */
+ if (!wdtick && dhd->wd_timer_valid == TRUE) {
+ dhd->wd_timer_valid = FALSE;
+ dhd_os_spin_unlock(pub, flags);
+#ifdef DHDTHREAD
+ del_timer_sync(&dhd->timer);
+#else
+ del_timer(&dhd->timer);
+#endif /* DHDTHREAD */
+ /* Unlock when timer deleted */
+ DHD_OS_WD_WAKE_UNLOCK(pub);
+ return;
+ }
+
+ if (wdtick) {
+ dhd_watchdog_ms = (uint)wdtick;
+ /* Re arm the timer, at last watchdog period */
+ mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms));
+ dhd->wd_timer_valid = TRUE;
+ }
+ dhd_os_spin_unlock(pub, flags);
+}
+
+void *
+dhd_os_open_image(char *filename)
+{
+ struct file *fp;
+
+ fp = filp_open(filename, O_RDONLY, 0);
+ /*
+ * 2.6.11 (FC4) supports filp_open() but later revs don't?
+ * Alternative:
+ * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
+ * ???
+ */
+ if (IS_ERR(fp))
+ fp = NULL;
+
+ return fp;
+}
+
+int
+dhd_os_get_image_block(char *buf, int len, void *image)
+{
+ struct file *fp = (struct file *)image;
+ int rdlen;
+
+ if (!image)
+ return 0;
+
+ rdlen = kernel_read(fp, fp->f_pos, buf, len);
+ if (rdlen > 0)
+ fp->f_pos += rdlen;
+
+ return rdlen;
+}
+
+void
+dhd_os_close_image(void *image)
+{
+ if (image)
+ filp_close((struct file *)image, NULL);
+}
+
+
+void
+dhd_os_sdlock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd;
+
+ dhd = (dhd_info_t *)(pub->info);
+
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ down(&dhd->sdsem);
+ else
+#endif /* DHDTHREAD */
+ spin_lock_bh(&dhd->sdlock);
+}
+
+void
+dhd_os_sdunlock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd;
+
+ dhd = (dhd_info_t *)(pub->info);
+
+#ifdef DHDTHREAD
+ if (dhd->threads_only)
+ up(&dhd->sdsem);
+ else
+#endif /* DHDTHREAD */
+ spin_unlock_bh(&dhd->sdlock);
+}
+
+void
+dhd_os_sdlock_txq(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd;
+
+ dhd = (dhd_info_t *)(pub->info);
+ spin_lock_bh(&dhd->txqlock);
+}
+
+void
+dhd_os_sdunlock_txq(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd;
+
+ dhd = (dhd_info_t *)(pub->info);
+ spin_unlock_bh(&dhd->txqlock);
+}
+
+void
+dhd_os_sdlock_rxq(dhd_pub_t *pub)
+{
+}
+
+void
+dhd_os_sdunlock_rxq(dhd_pub_t *pub)
+{
+}
+
+void
+dhd_os_sdtxlock(dhd_pub_t *pub)
+{
+ dhd_os_sdlock(pub);
+}
+
+void
+dhd_os_sdtxunlock(dhd_pub_t *pub)
+{
+ dhd_os_sdunlock(pub);
+}
+
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
+uint8* dhd_os_prealloc(void *osh, int section, uint size)
+{
+ return (uint8*)wl_android_prealloc(section, size);
+}
+
+void dhd_os_prefree(void *osh, void *addr, uint size)
+{
+}
+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
+
+#if defined(CONFIG_WIRELESS_EXT)
+struct iw_statistics *
+dhd_get_wireless_stats(struct net_device *dev)
+{
+ int res = 0;
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ if (!dhd->pub.up) {
+ return NULL;
+ }
+
+ res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats);
+
+ if (res == 0)
+ return &dhd->iw.wstats;
+ else
+ return NULL;
+}
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+static int
+dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
+ wl_event_msg_t *event, void **data)
+{
+ int bcmerror = 0;
+ ASSERT(dhd != NULL);
+
+ bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, event, data);
+ if (bcmerror != BCME_OK)
+ return (bcmerror);
+
+#if defined(CONFIG_WIRELESS_EXT)
+ if (event->bsscfgidx == 0) {
+ /*
+ * Wireless ext is on primary interface only
+ */
+
+ ASSERT(dhd->iflist[*ifidx] != NULL);
+ ASSERT(dhd->iflist[*ifidx]->net != NULL);
+
+ if (dhd->iflist[*ifidx]->net) {
+ wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
+ }
+ }
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+#ifdef WL_CFG80211
+ if ((ntoh32(event->event_type) == WLC_E_IF) &&
+ (((dhd_if_event_t *)*data)->action == WLC_E_IF_ADD))
+ /* If ADD_IF has been called directly by wl utility then we
+ * should not report this. In case if ADD_IF was called from
+ * CFG stack, then too this event need not be reported back
+ */
+ return (BCME_OK);
+ if ((wl_cfg80211_is_progress_ifchange() ||
+ wl_cfg80211_is_progress_ifadd()) && (*ifidx != 0)) {
+ /*
+ * If IF_ADD/CHANGE operation is going on,
+ * discard any event received on the virtual I/F
+ */
+ return (BCME_OK);
+ }
+
+ ASSERT(dhd->iflist[*ifidx] != NULL);
+ ASSERT(dhd->iflist[*ifidx]->net != NULL);
+ if (dhd->iflist[*ifidx]->event2cfg80211 && dhd->iflist[*ifidx]->net) {
+ wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, *data);
+ }
+#endif /* defined(WL_CFG80211) */
+
+ return (bcmerror);
+}
+
+/* send up locally generated event */
+void
+dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data)
+{
+ switch (ntoh32(event->event_type)) {
+#ifdef WLBTAMP
+ /* Send up locally generated AMP HCI Events */
+ case WLC_E_BTA_HCI_EVENT: {
+ struct sk_buff *p, *skb;
+ bcm_event_t *msg;
+ wl_event_msg_t *p_bcm_event;
+ char *ptr;
+ uint32 len;
+ uint32 pktlen;
+ dhd_if_t *ifp;
+ dhd_info_t *dhd;
+ uchar *eth;
+ int ifidx;
+
+ len = ntoh32(event->datalen);
+ pktlen = sizeof(bcm_event_t) + len + 2;
+ dhd = dhdp->info;
+ ifidx = dhd_ifname2idx(dhd, event->ifname);
+
+ if ((p = PKTGET(dhdp->osh, pktlen, FALSE))) {
+ ASSERT(ISALIGNED((uintptr)PKTDATA(dhdp->osh, p), sizeof(uint32)));
+
+ msg = (bcm_event_t *) PKTDATA(dhdp->osh, p);
+
+ bcopy(&dhdp->mac, &msg->eth.ether_dhost, ETHER_ADDR_LEN);
+ bcopy(&dhdp->mac, &msg->eth.ether_shost, ETHER_ADDR_LEN);
+ ETHER_TOGGLE_LOCALADDR(&msg->eth.ether_shost);
+
+ msg->eth.ether_type = hton16(ETHER_TYPE_BRCM);
+
+ /* BCM Vendor specific header... */
+ msg->bcm_hdr.subtype = hton16(BCMILCP_SUBTYPE_VENDOR_LONG);
+ msg->bcm_hdr.version = BCMILCP_BCM_SUBTYPEHDR_VERSION;
+ bcopy(BRCM_OUI, &msg->bcm_hdr.oui[0], DOT11_OUI_LEN);
+
+ /* vendor spec header length + pvt data length (private indication
+ * hdr + actual message itself)
+ */
+ msg->bcm_hdr.length = hton16(BCMILCP_BCM_SUBTYPEHDR_MINLENGTH +
+ BCM_MSG_LEN + sizeof(wl_event_msg_t) + (uint16)len);
+ msg->bcm_hdr.usr_subtype = hton16(BCMILCP_BCM_SUBTYPE_EVENT);
+
+ PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2));
+
+ /* copy wl_event_msg_t into sk_buf */
+
+ /* pointer to wl_event_msg_t in sk_buf */
+ p_bcm_event = &msg->event;
+ bcopy(event, p_bcm_event, sizeof(wl_event_msg_t));
+
+ /* copy hci event into sk_buf */
+ bcopy(data, (p_bcm_event + 1), len);
+
+ msg->bcm_hdr.length = hton16(sizeof(wl_event_msg_t) +
+ ntoh16(msg->bcm_hdr.length));
+ PKTSETLEN(dhdp->osh, p, (sizeof(bcm_event_t) + len + 2));
+
+ ptr = (char *)(msg + 1);
+ /* Last 2 bytes of the message are 0x00 0x00 to signal that there
+ * are no ethertypes which are following this
+ */
+ ptr[len+0] = 0x00;
+ ptr[len+1] = 0x00;
+
+ skb = PKTTONATIVE(dhdp->osh, p);
+ eth = skb->data;
+ len = skb->len;
+
+ ifp = dhd->iflist[ifidx];
+ if (ifp == NULL)
+ ifp = dhd->iflist[0];
+
+ ASSERT(ifp);
+ skb->dev = ifp->net;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ skb->data = eth;
+ skb->len = len;
+
+ /* Strip header, count, deliver upward */
+ skb_pull(skb, ETH_HLEN);
+
+ /* Send the packet */
+ if (in_interrupt()) {
+ netif_rx(skb);
+ } else {
+ netif_rx_ni(skb);
+ }
+ }
+ else {
+ /* Could not allocate a sk_buf */
+ AP6210_ERR("%s: unable to alloc sk_buf", __FUNCTION__);
+ }
+ break;
+ } /* case WLC_E_BTA_HCI_EVENT */
+#endif /* WLBTAMP */
+
+ default:
+ break;
+ }
+}
+
+void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar)
+{
+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ struct dhd_info *dhdinfo = dhd->info;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ int timeout = msecs_to_jiffies(IOCTL_RESP_TIMEOUT);
+#else
+ int timeout = (IOCTL_RESP_TIMEOUT / 1000) * HZ;
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+
+ dhd_os_sdunlock(dhd);
+ wait_event_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), timeout);
+ dhd_os_sdlock(dhd);
+#endif
+ return;
+}
+
+void dhd_wait_event_wakeup(dhd_pub_t *dhd)
+{
+#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ struct dhd_info *dhdinfo = dhd->info;
+ if (waitqueue_active(&dhdinfo->ctrl_wait))
+ wake_up(&dhdinfo->ctrl_wait);
+#endif
+ return;
+}
+
+int
+dhd_dev_reset(struct net_device *dev, uint8 flag)
+{
+ int ret;
+
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ if (flag == TRUE) {
+ /* Issue wl down command before resetting the chip */
+ if (dhd_wl_ioctl_cmd(&dhd->pub, WLC_DOWN, NULL, 0, TRUE, 0) < 0) {
+ AP6210_DEBUG("%s: wl down failed\n", __FUNCTION__);
+ }
+ }
+
+ ret = dhd_bus_devreset(&dhd->pub, flag);
+ if (ret) {
+ AP6210_ERR("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+int net_os_set_suspend_disable(struct net_device *dev, int val)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd) {
+ ret = dhd->pub.suspend_disable_flag;
+ dhd->pub.suspend_disable_flag = val;
+ }
+ return ret;
+}
+
+int net_os_set_suspend(struct net_device *dev, int val, int force)
+{
+ int ret = 0;
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ if (dhd) {
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+ ret = dhd_set_suspend(val, &dhd->pub);
+#else
+ ret = dhd_suspend_resume_helper(dhd, val, force);
+#endif
+#ifdef WL_CFG80211
+ wl_cfg80211_update_power_mode(dev);
+#endif
+ }
+ return ret;
+}
+
+int net_os_set_suspend_bcn_li_dtim(struct net_device *dev, int val)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ if (dhd)
+ dhd->pub.suspend_bcn_li_dtim = val;
+
+ return 0;
+}
+
+#ifdef PKT_FILTER_SUPPORT
+int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num)
+{
+#ifndef GAN_LITE_NAT_KEEPALIVE_FILTER
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ char *filterp = NULL;
+ int ret = 0;
+
+ if (!dhd || (num == DHD_UNICAST_FILTER_NUM) ||
+ (num == DHD_MDNS_FILTER_NUM))
+ return ret;
+ if (num >= dhd->pub.pktfilter_count)
+ return -EINVAL;
+ if (add_remove) {
+ switch (num) {
+ case DHD_BROADCAST_FILTER_NUM:
+ filterp = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
+ break;
+ case DHD_MULTICAST4_FILTER_NUM:
+ filterp = "102 0 0 0 0xFFFFFF 0x01005E";
+ break;
+ case DHD_MULTICAST6_FILTER_NUM:
+ filterp = "103 0 0 0 0xFFFF 0x3333";
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ dhd->pub.pktfilter[num] = filterp;
+ dhd_pktfilter_offload_set(&dhd->pub, dhd->pub.pktfilter[num]);
+ return ret;
+#else
+ return 0;
+#endif /* GAN_LITE_NAT_KEEPALIVE_FILTER */
+}
+
+int dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val)
+{
+ int ret = 0;
+
+ /* Packet filtering is set only if we still in early-suspend and
+ * we need either to turn it ON or turn it OFF
+ * We can always turn it OFF in case of early-suspend, but we turn it
+ * back ON only if suspend_disable_flag was not set
+ */
+ if (dhdp && dhdp->up) {
+ if (dhdp->in_suspend) {
+ if (!val || (val && !dhdp->suspend_disable_flag))
+ dhd_enable_packet_filter(val, dhdp);
+ }
+ }
+ return ret;
+}
+
+/* function to enable/disable packet for Network device */
+int net_os_enable_packet_filter(struct net_device *dev, int val)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ return dhd_os_enable_packet_filter(&dhd->pub, val);
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+int
+dhd_dev_init_ioctl(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ return dhd_preinit_ioctls(&dhd->pub);
+}
+
+#ifdef PNO_SUPPORT
+/* Linux wrapper to call common dhd_pno_clean */
+int
+dhd_dev_pno_reset(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ return (dhd_pno_clean(&dhd->pub));
+}
+
+
+/* Linux wrapper to call common dhd_pno_enable */
+int
+dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ return (dhd_pno_enable(&dhd->pub, pfn_enabled));
+}
+
+
+/* Linux wrapper to call common dhd_pno_set */
+int
+dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid,
+ ushort scan_fr, int pno_repeat, int pno_freq_expo_max)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ return (dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr, pno_repeat, pno_freq_expo_max));
+}
+
+/* Linux wrapper to get pno status */
+int
+dhd_dev_get_pno_status(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ return (dhd_pno_get_status(&dhd->pub));
+}
+
+#endif /* PNO_SUPPORT */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (1)
+static void dhd_hang_process(struct work_struct *work)
+{
+ dhd_info_t *dhd;
+ struct net_device *dev;
+
+ dhd = (dhd_info_t *)container_of(work, dhd_info_t, work_hang);
+ dev = dhd->iflist[0]->net;
+
+ if (dev) {
+ rtnl_lock();
+ dev_close(dev);
+ rtnl_unlock();
+#if defined(WL_WIRELESS_EXT)
+ wl_iw_send_priv_event(dev, "HANG");
+#endif
+#if defined(WL_CFG80211)
+ wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
+#endif
+ }
+}
+
+int dhd_os_send_hang_message(dhd_pub_t *dhdp)
+{
+ int ret = 0;
+ if (dhdp) {
+ if (!dhdp->hang_was_sent) {
+ dhdp->hang_was_sent = 1;
+ schedule_work(&dhdp->info->work_hang);
+ }
+ }
+ return ret;
+}
+
+int net_os_send_hang_message(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ ret = dhd_os_send_hang_message(&dhd->pub);
+#else
+ ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
+#endif
+ return ret;
+}
+#endif /* (OEM_ANDROID) */
+
+void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ if (dhd && dhd->pub.up) {
+ memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t));
+#ifdef WL_CFG80211
+ wl_update_wiphybands(NULL, true);
+#endif
+ }
+}
+
+void dhd_bus_band_set(struct net_device *dev, uint band)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ if (dhd && dhd->pub.up) {
+#ifdef WL_CFG80211
+ wl_update_wiphybands(NULL, true);
+#endif
+ }
+}
+
+void dhd_net_if_lock(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ dhd_net_if_lock_local(dhd);
+}
+
+void dhd_net_if_unlock(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ dhd_net_if_unlock_local(dhd);
+}
+
+static void dhd_net_if_lock_local(dhd_info_t *dhd)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ if (dhd)
+ mutex_lock(&dhd->dhd_net_if_mutex);
+#endif
+}
+
+static void dhd_net_if_unlock_local(dhd_info_t *dhd)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ if (dhd)
+ mutex_unlock(&dhd->dhd_net_if_mutex);
+#endif
+}
+
+static void dhd_suspend_lock(dhd_pub_t *pub)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ if (dhd)
+ mutex_lock(&dhd->dhd_suspend_mutex);
+#endif
+}
+
+static void dhd_suspend_unlock(dhd_pub_t *pub)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ if (dhd)
+ mutex_unlock(&dhd->dhd_suspend_mutex);
+#endif
+}
+
+unsigned long dhd_os_spin_lock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags = 0;
+
+ if (dhd)
+ spin_lock_irqsave(&dhd->dhd_lock, flags);
+
+ return flags;
+}
+
+void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+ if (dhd)
+ spin_unlock_irqrestore(&dhd->dhd_lock, flags);
+}
+
+static int
+dhd_get_pend_8021x_cnt(dhd_info_t *dhd)
+{
+ return (atomic_read(&dhd->pend_8021x_cnt));
+}
+
+#define MAX_WAIT_FOR_8021X_TX 25
+
+int
+dhd_wait_pend8021x(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int timeout = msecs_to_jiffies(10);
+ int ntimes = MAX_WAIT_FOR_8021X_TX;
+ int pend = dhd_get_pend_8021x_cnt(dhd);
+
+ while (ntimes && pend) {
+ if (pend) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(timeout);
+ set_current_state(TASK_RUNNING);
+ ntimes--;
+ }
+ pend = dhd_get_pend_8021x_cnt(dhd);
+ }
+ if (ntimes == 0)
+ AP6210_ERR("%s: TIMEOUT\n", __FUNCTION__);
+ return pend;
+}
+
+#ifdef DHD_DEBUG
+int
+write_to_file(dhd_pub_t *dhd, uint8 *buf, int size)
+{
+ int ret = 0;
+ struct file *fp;
+ mm_segment_t old_fs;
+ loff_t pos = 0;
+
+ /* change to KERNEL_DS address limit */
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ /* open file to write */
+ fp = filp_open("/tmp/mem_dump", O_WRONLY|O_CREAT, 0640);
+ if (!fp) {
+ AP6210_ERR("%s: open file error\n", __FUNCTION__);
+ ret = -1;
+ goto exit;
+ }
+
+ /* Write buf to file */
+ fp->f_op->write(fp, buf, size, &pos);
+
+exit:
+ /* free buf before return */
+ MFREE(dhd->osh, buf, size);
+ /* close file before return */
+ if (fp)
+ filp_close(fp, current->files);
+ /* restore previous address limit */
+ set_fs(old_fs);
+
+ return ret;
+}
+#endif /* DHD_DEBUG */
+
+int dhd_os_wake_lock_timeout(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+ ret = dhd->wakelock_rx_timeout_enable > dhd->wakelock_ctrl_timeout_enable ?
+ dhd->wakelock_rx_timeout_enable : dhd->wakelock_ctrl_timeout_enable;
+#ifdef CONFIG_HAS_WAKELOCK
+ if (dhd->wakelock_rx_timeout_enable)
+ wake_lock_timeout(dhd->wl_rxwake,
+ msecs_to_jiffies(dhd->wakelock_rx_timeout_enable));
+ if (dhd->wakelock_ctrl_timeout_enable)
+ wake_lock_timeout(dhd->wl_ctrlwake,
+ msecs_to_jiffies(dhd->wakelock_ctrl_timeout_enable));
+#endif
+ dhd->wakelock_rx_timeout_enable = 0;
+ dhd->wakelock_ctrl_timeout_enable = 0;
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return ret;
+}
+
+int net_os_wake_lock_timeout(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_lock_timeout(&dhd->pub);
+ return ret;
+}
+
+int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+ if (val > dhd->wakelock_rx_timeout_enable)
+ dhd->wakelock_rx_timeout_enable = val;
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return 0;
+}
+
+int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+ if (val > dhd->wakelock_ctrl_timeout_enable)
+ dhd->wakelock_ctrl_timeout_enable = val;
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return 0;
+}
+
+int net_os_wake_lock_rx_timeout_enable(struct net_device *dev, int val)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_lock_rx_timeout_enable(&dhd->pub, val);
+ return ret;
+}
+
+int net_os_wake_lock_ctrl_timeout_enable(struct net_device *dev, int val)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_lock_ctrl_timeout_enable(&dhd->pub, val);
+ return ret;
+}
+
+int dhd_os_wake_lock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+#ifdef CONFIG_HAS_WAKELOCK
+ if (!dhd->wakelock_counter)
+ wake_lock(dhd->wl_wifi);
+#endif
+ dhd->wakelock_counter++;
+ ret = dhd->wakelock_counter;
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return ret;
+}
+
+int net_os_wake_lock(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_lock(&dhd->pub);
+ return ret;
+}
+
+int dhd_os_wake_unlock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ dhd_os_wake_lock_timeout(pub);
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+ if (dhd->wakelock_counter) {
+ dhd->wakelock_counter--;
+#ifdef CONFIG_HAS_WAKELOCK
+ if (!dhd->wakelock_counter)
+ wake_unlock(dhd->wl_wifi);
+#endif
+ ret = dhd->wakelock_counter;
+ }
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return ret;
+}
+
+int dhd_os_check_wakelock(void *dhdp)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+ dhd_pub_t *pub = (dhd_pub_t *)dhdp;
+ dhd_info_t *dhd;
+
+ if (!pub)
+ return 0;
+ dhd = (dhd_info_t *)(pub->info);
+
+ /* Indicate to the SD Host to avoid going to suspend if internal locks are up */
+ if (dhd && (wake_lock_active(dhd->wl_wifi) ||
+ (wake_lock_active(dhd->wl_wdwake))))
+ return 1;
+#endif
+ return 0;
+}
+
+int net_os_wake_unlock(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_unlock(&dhd->pub);
+ return ret;
+}
+
+int dhd_os_wd_wake_lock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+#ifdef CONFIG_HAS_WAKELOCK
+ /* if wakelock_wd_counter was never used : lock it at once */
+ if (!dhd->wakelock_wd_counter) {
+ if (dhd->wl_wdwake)
+ wake_lock(dhd->wl_wdwake);
+ else {
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ return 0;
+ }
+ }
+#endif
+ dhd->wakelock_wd_counter++;
+ ret = dhd->wakelock_wd_counter;
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return ret;
+}
+
+int dhd_os_wd_wake_unlock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+ if (dhd->wakelock_wd_counter) {
+ dhd->wakelock_wd_counter = 0;
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_unlock(dhd->wl_wdwake);
+#endif
+ }
+ spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+ }
+ return ret;
+}
+
+int dhd_os_check_if_up(void *dhdp)
+{
+ dhd_pub_t *pub = (dhd_pub_t *)dhdp;
+
+ if (!pub)
+ return 0;
+ return pub->up;
+}
+
+/* function to collect firmware, chip id and chip version info */
+void dhd_set_version_info(dhd_pub_t *dhdp, char *fw)
+{
+ int i;
+
+ i = snprintf(info_string, sizeof(info_string), "Driver: %s\n Firmware: %s ", EPI_VERSION_STR, fw);
+
+ if (!dhdp)
+ return;
+
+ i = snprintf(&info_string[i], sizeof(info_string) - i,
+ "\n Chip: %x Rev %x Pkg %x", dhd_bus_chip_id(dhdp),
+ dhd_bus_chiprev_id(dhdp), dhd_bus_chippkg_id(dhdp));
+ AP6210_ERR("Chip: %x Rev %x Pkg %x", dhd_bus_chip_id(dhdp), dhd_bus_chiprev_id(dhdp), dhd_bus_chippkg_id(dhdp));
+}
+
+int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd)
+{
+ int ifidx;
+ int ret = 0;
+ dhd_info_t *dhd = NULL;
+
+ if (!net || !netdev_priv(net)) {
+ AP6210_ERR("%s invalid parameter\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ dhd = *(dhd_info_t **)netdev_priv(net);
+ ifidx = dhd_net2idx(dhd, net);
+ if (ifidx == DHD_BAD_IF) {
+ AP6210_ERR("%s bad ifidx\n", __FUNCTION__);
+ return -ENODEV;
+ }
+
+ DHD_OS_WAKE_LOCK(&dhd->pub);
+ ret = dhd_wl_ioctl(&dhd->pub, ifidx, ioc, ioc->buf, ioc->len);
+ dhd_check_hang(net, &dhd->pub, ret);
+ DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+ return ret;
+}
+
+bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret)
+{
+ struct net_device *net;
+
+ net = dhd_idx2net(dhdp, ifidx);
+ return dhd_check_hang(net, dhdp, ret);
+}
+
+
+#ifdef PROP_TXSTATUS
+extern int dhd_wlfc_interface_entry_update(void* state, ewlfc_mac_entry_action_t action, uint8 ifid,
+ uint8 iftype, uint8* ea);
+extern int dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits);
+
+int dhd_wlfc_interface_event(struct dhd_info *dhd,
+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea)
+{
+ int status;
+
+ dhd_os_wlfc_block(&dhd->pub);
+ if (dhd->pub.wlfc_state == NULL) {
+ dhd_os_wlfc_unblock(&dhd->pub);
+ return BCME_OK;
+ }
+
+ status = dhd_wlfc_interface_entry_update(dhd->pub.wlfc_state, action, ifid, iftype, ea);
+ dhd_os_wlfc_unblock(&dhd->pub);
+ return status;
+}
+
+int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data)
+{
+ int status;
+
+ dhd_os_wlfc_block(&dhd->pub);
+ if (dhd->pub.wlfc_state == NULL) {
+ dhd_os_wlfc_unblock(&dhd->pub);
+ return BCME_OK;
+ }
+
+ status = dhd_wlfc_FIFOcreditmap_update(dhd->pub.wlfc_state, event_data);
+ dhd_os_wlfc_unblock(&dhd->pub);
+ return status;
+}
+
+int dhd_wlfc_event(struct dhd_info *dhd)
+{
+ int status;
+
+ dhd_os_wlfc_block(&dhd->pub);
+ status = dhd_wlfc_enable(&dhd->pub);
+ dhd_os_wlfc_unblock(&dhd->pub);
+ return status;
+}
+#endif /* PROP_TXSTATUS */
+
+#ifdef BCMDBGFS
+
+#include <linux/debugfs.h>
+
+extern uint32 dhd_readregl(void *bp, uint32 addr);
+extern uint32 dhd_writeregl(void *bp, uint32 addr, uint32 data);
+
+typedef struct dhd_dbgfs {
+ struct dentry *debugfs_dir;
+ struct dentry *debugfs_mem;
+ dhd_pub_t *dhdp;
+ uint32 size;
+} dhd_dbgfs_t;
+
+dhd_dbgfs_t g_dbgfs;
+
+static int
+dhd_dbg_state_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t
+dhd_dbg_state_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ ssize_t rval;
+ uint32 tmp;
+ loff_t pos = *ppos;
+ size_t ret;
+
+ if (pos < 0)
+ return -EINVAL;
+ if (pos >= g_dbgfs.size || !count)
+ return 0;
+ if (count > g_dbgfs.size - pos)
+ count = g_dbgfs.size - pos;
+
+ /* Basically enforce aligned 4 byte reads. It's up to the user to work out the details */
+ tmp = dhd_readregl(g_dbgfs.dhdp->bus, file->f_pos & (~3));
+
+ ret = copy_to_user(ubuf, &tmp, 4);
+ if (ret == count)
+ return -EFAULT;
+
+ count -= ret;
+ *ppos = pos + count;
+ rval = count;
+
+ return rval;
+}
+
+
+static ssize_t
+dhd_debugfs_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
+{
+ loff_t pos = *ppos;
+ size_t ret;
+ uint32 buf;
+
+ if (pos < 0)
+ return -EINVAL;
+ if (pos >= g_dbgfs.size || !count)
+ return 0;
+ if (count > g_dbgfs.size - pos)
+ count = g_dbgfs.size - pos;
+
+ ret = copy_from_user(&buf, ubuf, sizeof(uint32));
+ if (ret == count)
+ return -EFAULT;
+
+ /* Basically enforce aligned 4 byte writes. It's up to the user to work out the details */
+ dhd_writeregl(g_dbgfs.dhdp->bus, file->f_pos & (~3), buf);
+
+ return count;
+}
+
+
+loff_t
+dhd_debugfs_lseek(struct file *file, loff_t off, int whence)
+{
+ loff_t pos = -1;
+
+ switch (whence) {
+ case 0:
+ pos = off;
+ break;
+ case 1:
+ pos = file->f_pos + off;
+ break;
+ case 2:
+ pos = g_dbgfs.size - off;
+ }
+ return (pos < 0 || pos > g_dbgfs.size) ? -EINVAL : (file->f_pos = pos);
+}
+
+static const struct file_operations dhd_dbg_state_ops = {
+ .read = dhd_dbg_state_read,
+ .write = dhd_debugfs_write,
+ .open = dhd_dbg_state_open,
+ .llseek = dhd_debugfs_lseek
+};
+
+static void dhd_dbg_create(void)
+{
+ if (g_dbgfs.debugfs_dir) {
+ g_dbgfs.debugfs_mem = debugfs_create_file("mem", 0644, g_dbgfs.debugfs_dir,
+ NULL, &dhd_dbg_state_ops);
+ }
+}
+
+void dhd_dbg_init(dhd_pub_t *dhdp)
+{
+ int err;
+
+ g_dbgfs.dhdp = dhdp;
+ g_dbgfs.size = 0x20000000; /* Allow access to various cores regs */
+
+ g_dbgfs.debugfs_dir = debugfs_create_dir("dhd", 0);
+ if (IS_ERR(g_dbgfs.debugfs_dir)) {
+ err = PTR_ERR(g_dbgfs.debugfs_dir);
+ g_dbgfs.debugfs_dir = NULL;
+ return;
+ }
+
+ dhd_dbg_create();
+
+ return;
+}
+
+void dhd_dbg_remove(void)
+{
+ debugfs_remove(g_dbgfs.debugfs_mem);
+ debugfs_remove(g_dbgfs.debugfs_dir);
+
+ bzero((unsigned char *) &g_dbgfs, sizeof(g_dbgfs));
+
+}
+#endif /* ifdef BCMDBGFS */
+
+#ifdef WLMEDIA_HTSF
+
+static
+void dhd_htsf_addtxts(dhd_pub_t *dhdp, void *pktbuf)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(dhdp->info);
+ struct sk_buff *skb;
+ uint32 htsf = 0;
+ uint16 dport = 0, oldmagic = 0xACAC;
+ char *p1;
+ htsfts_t ts;
+
+ /* timestamp packet */
+
+ p1 = (char*) PKTDATA(dhdp->osh, pktbuf);
+
+ if (PKTLEN(dhdp->osh, pktbuf) > HTSF_MINLEN) {
+/* memcpy(&proto, p1+26, 4); */
+ memcpy(&dport, p1+40, 2);
+/* proto = ((ntoh32(proto))>> 16) & 0xFF; */
+ dport = ntoh16(dport);
+ }
+
+ /* timestamp only if icmp or udb iperf with port 5555 */
+/* if (proto == 17 && dport == tsport) { */
+ if (dport >= tsport && dport <= tsport + 20) {
+
+ skb = (struct sk_buff *) pktbuf;
+
+ htsf = dhd_get_htsf(dhd, 0);
+ memset(skb->data + 44, 0, 2); /* clear checksum */
+ memcpy(skb->data+82, &oldmagic, 2);
+ memcpy(skb->data+84, &htsf, 4);
+
+ memset(&ts, 0, sizeof(htsfts_t));
+ ts.magic = HTSFMAGIC;
+ ts.prio = PKTPRIO(pktbuf);
+ ts.seqnum = htsf_seqnum++;
+ ts.c10 = get_cycles();
+ ts.t10 = htsf;
+ ts.endmagic = HTSFENDMAGIC;
+
+ memcpy(skb->data + HTSF_HOSTOFFSET, &ts, sizeof(ts));
+ }
+}
+
+static void dhd_dump_htsfhisto(histo_t *his, char *s)
+{
+ int pktcnt = 0, curval = 0, i;
+ for (i = 0; i < (NUMBIN-2); i++) {
+ curval += 500;
+ AP6210_DUMP("%d ", his->bin[i]);
+ pktcnt += his->bin[i];
+ }
+ AP6210_DUMP(" max: %d TotPkt: %d neg: %d [%s]\n", his->bin[NUMBIN-2], pktcnt,
+ his->bin[NUMBIN-1], s);
+}
+
+static
+void sorttobin(int value, histo_t *histo)
+{
+ int i, binval = 0;
+
+ if (value < 0) {
+ histo->bin[NUMBIN-1]++;
+ return;
+ }
+ if (value > histo->bin[NUMBIN-2]) /* store the max value */
+ histo->bin[NUMBIN-2] = value;
+
+ for (i = 0; i < (NUMBIN-2); i++) {
+ binval += 500; /* 500m s bins */
+ if (value <= binval) {
+ histo->bin[i]++;
+ return;
+ }
+ }
+ histo->bin[NUMBIN-3]++;
+}
+
+static
+void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf)
+{
+ dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+ struct sk_buff *skb;
+ char *p1;
+ uint16 old_magic;
+ int d1, d2, d3, end2end;
+ htsfts_t *htsf_ts;
+ uint32 htsf;
+
+ skb = PKTTONATIVE(dhdp->osh, pktbuf);
+ p1 = (char*)PKTDATA(dhdp->osh, pktbuf);
+
+ if (PKTLEN(osh, pktbuf) > HTSF_MINLEN) {
+ memcpy(&old_magic, p1+78, 2);
+ htsf_ts = (htsfts_t*) (p1 + HTSF_HOSTOFFSET - 4);
+ }
+ else
+ return;
+
+ if (htsf_ts->magic == HTSFMAGIC) {
+ htsf_ts->tE0 = dhd_get_htsf(dhd, 0);
+ htsf_ts->cE0 = get_cycles();
+ }
+
+ if (old_magic == 0xACAC) {
+
+ tspktcnt++;
+ htsf = dhd_get_htsf(dhd, 0);
+ memcpy(skb->data+92, &htsf, sizeof(uint32));
+
+ memcpy(&ts[tsidx].t1, skb->data+80, 16);
+
+ d1 = ts[tsidx].t2 - ts[tsidx].t1;
+ d2 = ts[tsidx].t3 - ts[tsidx].t2;
+ d3 = ts[tsidx].t4 - ts[tsidx].t3;
+ end2end = ts[tsidx].t4 - ts[tsidx].t1;
+
+ sorttobin(d1, &vi_d1);
+ sorttobin(d2, &vi_d2);
+ sorttobin(d3, &vi_d3);
+ sorttobin(end2end, &vi_d4);
+
+ if (end2end > 0 && end2end > maxdelay) {
+ maxdelay = end2end;
+ maxdelaypktno = tspktcnt;
+ memcpy(&maxdelayts, &ts[tsidx], 16);
+ }
+ if (++tsidx >= TSMAX)
+ tsidx = 0;
+ }
+}
+
+uint32 dhd_get_htsf(dhd_info_t *dhd, int ifidx)
+{
+ uint32 htsf = 0, cur_cycle, delta, delta_us;
+ uint32 factor, baseval, baseval2;
+ cycles_t t;
+
+ t = get_cycles();
+ cur_cycle = t;
+
+ if (cur_cycle > dhd->htsf.last_cycle)
+ delta = cur_cycle - dhd->htsf.last_cycle;
+ else {
+ delta = cur_cycle + (0xFFFFFFFF - dhd->htsf.last_cycle);
+ }
+
+ delta = delta >> 4;
+
+ if (dhd->htsf.coef) {
+ /* times ten to get the first digit */
+ factor = (dhd->htsf.coef*10 + dhd->htsf.coefdec1);
+ baseval = (delta*10)/factor;
+ baseval2 = (delta*10)/(factor+1);
+ delta_us = (baseval - (((baseval - baseval2) * dhd->htsf.coefdec2)) / 10);
+ htsf = (delta_us << 4) + dhd->htsf.last_tsf + HTSF_BUS_DELAY;
+ }
+ else {
+ AP6210_ERR("-------dhd->htsf.coef = 0 -------\n");
+ }
+
+ return htsf;
+}
+
+static void dhd_dump_latency(void)
+{
+ int i, max = 0;
+ int d1, d2, d3, d4, d5;
+
+ AP6210_DEBUG("T1 T2 T3 T4 d1 d2 t4-t1 i \n");
+ for (i = 0; i < TSMAX; i++) {
+ d1 = ts[i].t2 - ts[i].t1;
+ d2 = ts[i].t3 - ts[i].t2;
+ d3 = ts[i].t4 - ts[i].t3;
+ d4 = ts[i].t4 - ts[i].t1;
+ d5 = ts[max].t4-ts[max].t1;
+ if (d4 > d5 && d4 > 0) {
+ max = i;
+ }
+ AP6210_DUMP("%08X %08X %08X %08X \t%d %d %d %d i=%d\n",
+ ts[i].t1, ts[i].t2, ts[i].t3, ts[i].t4,
+ d1, d2, d3, d4, i);
+ }
+
+ AP6210_DEBUG("current idx = %d \n", tsidx);
+
+ AP6210_DEBUG("Highest latency %d pkt no.%d total=%d\n", maxdelay, maxdelaypktno, tspktcnt);
+ AP6210_DEBUG("%08X %08X %08X %08X \t%d %d %d %d\n",
+ maxdelayts.t1, maxdelayts.t2, maxdelayts.t3, maxdelayts.t4,
+ maxdelayts.t2 - maxdelayts.t1,
+ maxdelayts.t3 - maxdelayts.t2,
+ maxdelayts.t4 - maxdelayts.t3,
+ maxdelayts.t4 - maxdelayts.t1);
+}
+
+
+static int
+dhd_ioctl_htsf_get(dhd_info_t *dhd, int ifidx)
+{
+ wl_ioctl_t ioc;
+ char buf[32];
+ int ret;
+ uint32 s1, s2;
+
+ struct tsf {
+ uint32 low;
+ uint32 high;
+ } tsf_buf;
+
+ memset(&ioc, 0, sizeof(ioc));
+ memset(&tsf_buf, 0, sizeof(tsf_buf));
+
+ ioc.cmd = WLC_GET_VAR;
+ ioc.buf = buf;
+ ioc.len = (uint)sizeof(buf);
+ ioc.set = FALSE;
+
+ strncpy(buf, "tsf", sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+ s1 = dhd_get_htsf(dhd, 0);
+ if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) {
+ if (ret == -EIO) {
+ AP6210_ERR("%s: tsf is not supported by device\n",
+ dhd_ifname(&dhd->pub, ifidx));
+ return -EOPNOTSUPP;
+ }
+ return ret;
+ }
+ s2 = dhd_get_htsf(dhd, 0);
+
+ memcpy(&tsf_buf, buf, sizeof(tsf_buf));
+ AP6210_DEBUG("TSF_h=%04X lo=%08X Calc:htsf=%08X, coef=%d.%d%d delta=%d ",
+ tsf_buf.high, tsf_buf.low, s2, dhd->htsf.coef, dhd->htsf.coefdec1,
+ dhd->htsf.coefdec2, s2-tsf_buf.low);
+ AP6210_DEBUG("lasttsf=%08X lastcycle=%08X\n", dhd->htsf.last_tsf, dhd->htsf.last_cycle);
+ return 0;
+}
+
+void htsf_update(dhd_info_t *dhd, void *data)
+{
+ static ulong cur_cycle = 0, prev_cycle = 0;
+ uint32 htsf, tsf_delta = 0;
+ uint32 hfactor = 0, cyc_delta, dec1 = 0, dec2, dec3, tmp;
+ ulong b, a;
+ cycles_t t;
+
+ /* cycles_t in inlcude/mips/timex.h */
+
+ t = get_cycles();
+
+ prev_cycle = cur_cycle;
+ cur_cycle = t;
+
+ if (cur_cycle > prev_cycle)
+ cyc_delta = cur_cycle - prev_cycle;
+ else {
+ b = cur_cycle;
+ a = prev_cycle;
+ cyc_delta = cur_cycle + (0xFFFFFFFF - prev_cycle);
+ }
+
+ if (data == NULL)
+ AP6210_DEBUG(" tsf update ata point er is null \n");
+
+ memcpy(&prev_tsf, &cur_tsf, sizeof(tsf_t));
+ memcpy(&cur_tsf, data, sizeof(tsf_t));
+
+ if (cur_tsf.low == 0) {
+ AP6210_DEBUG(" ---- 0 TSF, do not update, return\n");
+ return;
+ }
+
+ if (cur_tsf.low > prev_tsf.low)
+ tsf_delta = (cur_tsf.low - prev_tsf.low);
+ else {
+ AP6210_DEBUG(" ---- tsf low is smaller cur_tsf= %08X, prev_tsf=%08X, \n",
+ cur_tsf.low, prev_tsf.low);
+ if (cur_tsf.high > prev_tsf.high) {
+ tsf_delta = cur_tsf.low + (0xFFFFFFFF - prev_tsf.low);
+ AP6210_DEBUG(" ---- Wrap around tsf coutner adjusted TSF=%08X\n", tsf_delta);
+ }
+ else
+ return; /* do not update */
+ }
+
+ if (tsf_delta) {
+ hfactor = cyc_delta / tsf_delta;
+ tmp = (cyc_delta - (hfactor * tsf_delta))*10;
+ dec1 = tmp/tsf_delta;
+ dec2 = ((tmp - dec1*tsf_delta)*10) / tsf_delta;
+ tmp = (tmp - (dec1*tsf_delta))*10;
+ dec3 = ((tmp - dec2*tsf_delta)*10) / tsf_delta;
+
+ if (dec3 > 4) {
+ if (dec2 == 9) {
+ dec2 = 0;
+ if (dec1 == 9) {
+ dec1 = 0;
+ hfactor++;
+ }
+ else {
+ dec1++;
+ }
+ }
+ else
+ dec2++;
+ }
+ }
+
+ if (hfactor) {
+ htsf = ((cyc_delta * 10) / (hfactor*10+dec1)) + prev_tsf.low;
+ dhd->htsf.coef = hfactor;
+ dhd->htsf.last_cycle = cur_cycle;
+ dhd->htsf.last_tsf = cur_tsf.low;
+ dhd->htsf.coefdec1 = dec1;
+ dhd->htsf.coefdec2 = dec2;
+ }
+ else {
+ htsf = prev_tsf.low;
+ }
+}
+
+#endif /* WLMEDIA_HTSF */
diff --git a/drivers/net/wireless/ap6210/dhd_linux_sched.c b/drivers/net/wireless/ap6210/dhd_linux_sched.c
new file mode 100644
index 0000000..290caf7
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_linux_sched.c
@@ -0,0 +1,39 @@
+/*
+ * Expose some of the kernel scheduler routines
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_linux_sched.c 291086 2011-10-21 01:17:24Z $
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <typedefs.h>
+#include <linuxver.h>
+
+int setScheduler(struct task_struct *p, int policy, struct sched_param *param)
+{
+ int rc = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ rc = sched_setscheduler(p, policy, param);
+#endif /* LinuxVer */
+ return rc;
+}
diff --git a/drivers/net/wireless/ap6210/dhd_pno.c b/drivers/net/wireless/ap6210/dhd_pno.c
new file mode 100644
index 0000000..317a063
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_pno.c
@@ -0,0 +1,1838 @@
+/*
+ * Broadcom Dongle Host Driver (DHD)
+ * Prefered Network Offload and Wi-Fi Location Service(WLS) code.
+ *
+ * Copyright (C) 1999-2013, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_pno.c 420056 2013-08-24 00:53:12Z $
+ */
+#include <typedefs.h>
+#include <osl.h>
+
+#include <epivers.h>
+#include <bcmutils.h>
+
+#include <bcmendian.h>
+#include <linuxver.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/sort.h>
+#include <dngl_stats.h>
+#include <wlioctl.h>
+
+#include <proto/bcmevent.h>
+#include <dhd.h>
+#include <dhd_pno.h>
+#include <dhd_dbg.h>
+
+#ifdef __BIG_ENDIAN
+#include <bcmendian.h>
+#define htod32(i) (bcmswap32(i))
+#define htod16(i) (bcmswap16(i))
+#define dtoh32(i) (bcmswap32(i))
+#define dtoh16(i) (bcmswap16(i))
+#define htodchanspec(i) htod16(i)
+#define dtohchanspec(i) dtoh16(i)
+#else
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+#endif /* IL_BIGENDINA */
+
+#define NULL_CHECK(p, s, err) \
+ do { \
+ if (!(p)) { \
+ printf("NULL POINTER (%s) : %s\n", __FUNCTION__, (s)); \
+ err = BCME_ERROR; \
+ return err; \
+ } \
+ } while (0)
+#define PNO_GET_PNOSTATE(dhd) ((dhd_pno_status_info_t *)dhd->pno_state)
+#define PNO_BESTNET_LEN 1024
+#define PNO_ON 1
+#define PNO_OFF 0
+#define CHANNEL_2G_MAX 14
+#define MAX_NODE_CNT 5
+#define WLS_SUPPORTED(pno_state) (pno_state->wls_supported == TRUE)
+#define TIME_DIFF(timestamp1, timestamp2) (abs((uint32)(timestamp1/1000) \
+ - (uint32)(timestamp2/1000)))
+
+#define ENTRY_OVERHEAD strlen("bssid=\nssid=\nfreq=\nlevel=\nage=\ndist=\ndistSd=\n====")
+#define TIME_MIN_DIFF 5
+static inline bool
+is_dfs(uint16 channel)
+{
+ if (channel >= 52 && channel <= 64) /* class 2 */
+ return TRUE;
+ else if (channel >= 100 && channel <= 140) /* class 4 */
+ return TRUE;
+ else
+ return FALSE;
+}
+static int
+_dhd_pno_clean(dhd_pub_t *dhd)
+{
+ int pfn = 0;
+ int err;
+ dhd_pno_status_info_t *_pno_state;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ /* Disable PNO */
+ err = dhd_iovar(dhd, 0, "pfn", (char *)&pfn, sizeof(pfn), 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to execute pfn(error : %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ _pno_state->pno_status = DHD_PNO_DISABLED;
+ err = dhd_iovar(dhd, 0, "pfnclear", NULL, 0, 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to execute pfnclear(error : %d)\n",
+ __FUNCTION__, err);
+ }
+exit:
+ return err;
+}
+
+static int
+_dhd_pno_suspend(dhd_pub_t *dhd)
+{
+ int err;
+ int suspend = 1;
+ dhd_pno_status_info_t *_pno_state;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ err = dhd_iovar(dhd, 0, "pfn_suspend", (char *)&suspend, sizeof(suspend), 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to suspend pfn(error :%d)\n", __FUNCTION__, err);
+ goto exit;
+
+ }
+ _pno_state->pno_status = DHD_PNO_SUSPEND;
+exit:
+ return err;
+}
+static int
+_dhd_pno_enable(dhd_pub_t *dhd, int enable)
+{
+ int err = BCME_OK;
+ dhd_pno_status_info_t *_pno_state;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+
+ if (enable & 0xfffe) {
+ AP6210_ERR("%s invalid value\n", __FUNCTION__);
+ err = BCME_BADARG;
+ goto exit;
+ }
+ if (!dhd_support_sta_mode(dhd)) {
+ AP6210_ERR("PNO is not allowed for non-STA mode");
+ err = BCME_BADOPTION;
+ goto exit;
+ }
+ if (enable) {
+ if ((_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) &&
+ dhd_is_associated(dhd, NULL, NULL)) {
+ AP6210_ERR("%s Legacy PNO mode cannot be enabled "
+ "in assoc mode , ignore it\n", __FUNCTION__);
+ err = BCME_BADOPTION;
+ goto exit;
+ }
+ }
+ /* Enable/Disable PNO */
+ err = dhd_iovar(dhd, 0, "pfn", (char *)&enable, sizeof(enable), 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to execute pfn_set\n", __FUNCTION__);
+ goto exit;
+ }
+ _pno_state->pno_status = (enable)?
+ DHD_PNO_ENABLED : DHD_PNO_DISABLED;
+ if (!enable)
+ _pno_state->pno_mode = DHD_PNO_NONE_MODE;
+
+ AP6210_DEBUG("%s set pno as %s\n",
+ __FUNCTION__, enable ? "Enable" : "Disable");
+exit:
+ return err;
+}
+
+static int
+_dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t mode)
+{
+ int err = BCME_OK;
+ wl_pfn_param_t pfn_param;
+ dhd_pno_params_t *_params;
+ dhd_pno_status_info_t *_pno_state;
+ bool combined_scan = FALSE;
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+
+ memset(&pfn_param, 0, sizeof(pfn_param));
+
+ /* set pfn parameters */
+ pfn_param.version = htod32(PFN_VERSION);
+ pfn_param.flags = ((PFN_LIST_ORDER << SORT_CRITERIA_BIT) |
+ (ENABLE << IMMEDIATE_SCAN_BIT) | (ENABLE << REPORT_SEPERATELY_BIT));
+ if (mode == DHD_PNO_LEGACY_MODE) {
+ /* check and set extra pno params */
+ if ((pno_params->params_legacy.pno_repeat != 0) ||
+ (pno_params->params_legacy.pno_freq_expo_max != 0)) {
+ pfn_param.flags |= htod16(ENABLE << ENABLE_ADAPTSCAN_BIT);
+ pfn_param.repeat = (uchar) (pno_params->params_legacy.pno_repeat);
+ pfn_param.exp = (uchar) (pno_params->params_legacy.pno_freq_expo_max);
+ }
+ /* set up pno scan fr */
+ if (pno_params->params_legacy.scan_fr != 0)
+ pfn_param.scan_freq = htod32(pno_params->params_legacy.scan_fr);
+ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) {
+ AP6210_DEBUG("will enable combined scan with BATCHIG SCAN MODE\n");
+ mode |= DHD_PNO_BATCH_MODE;
+ combined_scan = TRUE;
+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) {
+ AP6210_DEBUG("will enable combined scan with HOTLIST SCAN MODE\n");
+ mode |= DHD_PNO_HOTLIST_MODE;
+ combined_scan = TRUE;
+ }
+ }
+ if (mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) {
+ /* Scan frequency of 30 sec */
+ pfn_param.scan_freq = htod32(30);
+ /* slow adapt scan is off by default */
+ pfn_param.slow_freq = htod32(0);
+ /* RSSI margin of 30 dBm */
+ pfn_param.rssi_margin = htod16(30);
+ /* Network timeout 60 sec */
+ pfn_param.lost_network_timeout = htod32(60);
+ /* best n = 2 by default */
+ pfn_param.bestn = DEFAULT_BESTN;
+ /* mscan m=0 by default, so not record best networks by default */
+ pfn_param.mscan = DEFAULT_MSCAN;
+ /* default repeat = 10 */
+ pfn_param.repeat = DEFAULT_REPEAT;
+ /* by default, maximum scan interval = 2^2
+ * scan_freq when adaptive scan is turned on
+ */
+ pfn_param.exp = DEFAULT_EXP;
+ if (mode == DHD_PNO_BATCH_MODE) {
+ /* In case of BATCH SCAN */
+ if (pno_params->params_batch.bestn)
+ pfn_param.bestn = pno_params->params_batch.bestn;
+ if (pno_params->params_batch.scan_fr)
+ pfn_param.scan_freq = htod32(pno_params->params_batch.scan_fr);
+ if (pno_params->params_batch.mscan)
+ pfn_param.mscan = pno_params->params_batch.mscan;
+ /* enable broadcast scan */
+ pfn_param.flags |= (ENABLE << ENABLE_BD_SCAN_BIT);
+ } else if (mode == DHD_PNO_HOTLIST_MODE) {
+ /* In case of HOTLIST SCAN */
+ if (pno_params->params_hotlist.scan_fr)
+ pfn_param.scan_freq = htod32(pno_params->params_hotlist.scan_fr);
+ pfn_param.bestn = 0;
+ pfn_param.repeat = 0;
+ /* enable broadcast scan */
+ pfn_param.flags |= (ENABLE << ENABLE_BD_SCAN_BIT);
+ }
+ if (combined_scan) {
+ /* Disable Adaptive Scan */
+ pfn_param.flags &= ~(htod16(ENABLE << ENABLE_ADAPTSCAN_BIT));
+ pfn_param.flags |= (ENABLE << ENABLE_BD_SCAN_BIT);
+ pfn_param.repeat = 0;
+ pfn_param.exp = 0;
+ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) {
+ /* In case of Legacy PNO + BATCH SCAN */
+ _params = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]);
+ if (_params->params_batch.bestn)
+ pfn_param.bestn = _params->params_batch.bestn;
+ if (_params->params_batch.scan_fr)
+ pfn_param.scan_freq = htod32(_params->params_batch.scan_fr);
+ if (_params->params_batch.mscan)
+ pfn_param.mscan = _params->params_batch.mscan;
+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) {
+ /* In case of Legacy PNO + HOTLIST SCAN */
+ _params = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]);
+ if (_params->params_hotlist.scan_fr)
+ pfn_param.scan_freq = htod32(_params->params_hotlist.scan_fr);
+ pfn_param.bestn = 0;
+ pfn_param.repeat = 0;
+ }
+ }
+ }
+ if (pfn_param.scan_freq < htod32(PNO_SCAN_MIN_FW_SEC) ||
+ pfn_param.scan_freq > htod32(PNO_SCAN_MAX_FW_SEC)) {
+ AP6210_ERR("%s pno freq(%d sec) is not valid \n",
+ __FUNCTION__, PNO_SCAN_MIN_FW_SEC);
+ err = BCME_BADARG;
+ goto exit;
+ }
+ if (mode == DHD_PNO_BATCH_MODE) {
+ int _tmp = pfn_param.bestn;
+ /* set bestn to calculate the max mscan which firmware supports */
+ err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to set pfnmscan\n", __FUNCTION__);
+ goto exit;
+ }
+ /* get max mscan which the firmware supports */
+ err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 0);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to get pfnmscan\n", __FUNCTION__);
+ goto exit;
+ }
+ AP6210_DEBUG(" returned mscan : %d, set bestn : %d\n", _tmp, pfn_param.bestn);
+ pfn_param.mscan = MIN(pfn_param.mscan, _tmp);
+ }
+ err = dhd_iovar(dhd, 0, "pfn_set", (char *)&pfn_param, sizeof(pfn_param), 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to execute pfn_set\n", __FUNCTION__);
+ goto exit;
+ }
+ /* need to return mscan if this is for batch scan instead of err */
+ err = (mode == DHD_PNO_BATCH_MODE)? pfn_param.mscan : err;
+exit:
+ return err;
+}
+static int
+_dhd_pno_add_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssids_list, int nssid)
+{
+ int err = BCME_OK;
+ int i = 0;
+ wl_pfn_t pfn_element;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ if (nssid) {
+ NULL_CHECK(ssids_list, "ssid list is NULL", err);
+ }
+ memset(&pfn_element, 0, sizeof(pfn_element));
+ {
+ int j;
+ for (j = 0; j < nssid; j++) {
+ AP6210_DEBUG("%d: scan for %s size = %d\n", j,
+ ssids_list[j].SSID, ssids_list[j].SSID_len);
+ }
+ }
+ /* Check for broadcast ssid */
+ for (i = 0; i < nssid; i++) {
+ if (!ssids_list[i].SSID_len) {
+ AP6210_ERR("%d: Broadcast SSID is ilegal for PNO setting\n", i);
+ err = BCME_ERROR;
+ goto exit;
+ }
+ }
+ /* set all pfn ssid */
+ for (i = 0; i < nssid; i++) {
+ pfn_element.infra = htod32(DOT11_BSSTYPE_INFRASTRUCTURE);
+ pfn_element.auth = (DOT11_OPEN_SYSTEM);
+ pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY);
+ pfn_element.wsec = htod32(0);
+ pfn_element.infra = htod32(1);
+ pfn_element.flags = htod32(ENABLE << WL_PFN_HIDDEN_BIT);
+ memcpy((char *)pfn_element.ssid.SSID, ssids_list[i].SSID,
+ ssids_list[i].SSID_len);
+ pfn_element.ssid.SSID_len = ssids_list[i].SSID_len;
+ err = dhd_iovar(dhd, 0, "pfn_add", (char *)&pfn_element,
+ sizeof(pfn_element), 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to execute pfn_add\n", __FUNCTION__);
+ goto exit;
+ }
+ }
+exit:
+ return err;
+}
+/* qsort compare function */
+static int
+_dhd_pno_cmpfunc(const void *a, const void *b)
+{
+ return (*(uint16*)a - *(uint16*)b);
+}
+static int
+_dhd_pno_chan_merge(uint16 *d_chan_list, int *nchan,
+ uint16 *chan_list1, int nchan1, uint16 *chan_list2, int nchan2)
+{
+ int err = BCME_OK;
+ int i = 0, j = 0, k = 0;
+ uint16 tmp;
+ NULL_CHECK(d_chan_list, "d_chan_list is NULL", err);
+ NULL_CHECK(nchan, "nchan is NULL", err);
+ NULL_CHECK(chan_list1, "chan_list1 is NULL", err);
+ NULL_CHECK(chan_list2, "chan_list2 is NULL", err);
+ /* chan_list1 and chan_list2 should be sorted at first */
+ while (i < nchan1 && j < nchan2) {
+ tmp = chan_list1[i] < chan_list2[j]?
+ chan_list1[i++] : chan_list2[j++];
+ for (; i < nchan1 && chan_list1[i] == tmp; i++);
+ for (; j < nchan2 && chan_list2[j] == tmp; j++);
+ d_chan_list[k++] = tmp;
+ }
+
+ while (i < nchan1) {
+ tmp = chan_list1[i++];
+ for (; i < nchan1 && chan_list1[i] == tmp; i++);
+ d_chan_list[k++] = tmp;
+ }
+
+ while (j < nchan2) {
+ tmp = chan_list2[j++];
+ for (; j < nchan2 && chan_list2[j] == tmp; j++);
+ d_chan_list[k++] = tmp;
+
+ }
+ *nchan = k;
+ return err;
+}
+static int
+_dhd_pno_get_channels(dhd_pub_t *dhd, uint16 *d_chan_list,
+ int *nchan, uint8 band, bool skip_dfs)
+{
+ int err = BCME_OK;
+ int i, j;
+ uint32 chan_buf[WL_NUMCHANNELS + 1];
+ wl_uint32_list_t *list;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ if (*nchan) {
+ NULL_CHECK(d_chan_list, "d_chan_list is NULL", err);
+ }
+ list = (wl_uint32_list_t *) (void *)chan_buf;
+ list->count = htod32(WL_NUMCHANNELS);
+ err = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, chan_buf, sizeof(chan_buf), FALSE, 0);
+ if (err < 0) {
+ AP6210_ERR("failed to get channel list (err: %d)\n", err);
+ goto exit;
+ }
+ for (i = 0, j = 0; i < dtoh32(list->count) && i < *nchan; i++) {
+ if (band == WLC_BAND_2G) {
+ if (dtoh32(list->element[i]) > CHANNEL_2G_MAX)
+ continue;
+ } else if (band == WLC_BAND_5G) {
+ if (dtoh32(list->element[i]) <= CHANNEL_2G_MAX)
+ continue;
+ if (skip_dfs && is_dfs(dtoh32(list->element[i])))
+ continue;
+
+ } else { /* All channels */
+ if (skip_dfs && is_dfs(dtoh32(list->element[i])))
+ continue;
+ }
+ d_chan_list[j++] = dtoh32(list->element[i]);
+ }
+ *nchan = j;
+exit:
+ return err;
+}
+static int
+_dhd_pno_convert_format(dhd_pub_t *dhd, struct dhd_pno_batch_params *params_batch,
+ char *buf, int nbufsize)
+{
+ int err = BCME_OK;
+ int bytes_written = 0, nreadsize = 0;
+ int t_delta = 0;
+ int nleftsize = nbufsize;
+ uint8 cnt = 0;
+ char *bp = buf;
+ char eabuf[ETHER_ADDR_STR_LEN];
+#ifdef PNO_DEBUG
+ char *_base_bp;
+ char msg[150];
+#endif
+ dhd_pno_bestnet_entry_t *iter, *next;
+ dhd_pno_scan_results_t *siter, *snext;
+ dhd_pno_best_header_t *phead, *pprev;
+ NULL_CHECK(params_batch, "params_batch is NULL", err);
+ if (nbufsize > 0)
+ NULL_CHECK(buf, "buf is NULL", err);
+ /* initialize the buffer */
+ memset(buf, 0, nbufsize);
+ AP6210_DEBUG("%s enter \n", __FUNCTION__);
+ /* # of scans */
+ if (!params_batch->get_batch.batch_started) {
+ bp += nreadsize = sprintf(bp, "scancount=%d\n",
+ params_batch->get_batch.expired_tot_scan_cnt);
+ nleftsize -= nreadsize;
+ params_batch->get_batch.batch_started = TRUE;
+ }
+ AP6210_DEBUG("%s scancount %d\n", __FUNCTION__, params_batch->get_batch.expired_tot_scan_cnt);
+ /* preestimate scan count until which scan result this report is going to end */
+ list_for_each_entry_safe(siter, snext,
+ &params_batch->get_batch.expired_scan_results_list, list) {
+ phead = siter->bestnetheader;
+ while (phead != NULL) {
+ /* if left_size is less than bestheader total size , stop this */
+ if (nleftsize <=
+ (phead->tot_size + phead->tot_cnt * ENTRY_OVERHEAD))
+ goto exit;
+ /* increase scan count */
+ cnt++;
+ /* # best of each scan */
+ AP6210_DEBUG("<loop : %d, apcount %d>\n", cnt - 1, phead->tot_cnt);
+ /* attribute of the scan */
+ if (phead->reason & PNO_STATUS_ABORT_MASK) {
+ bp += nreadsize = sprintf(bp, "trunc\n");
+ nleftsize -= nreadsize;
+ }
+ list_for_each_entry_safe(iter, next,
+ &phead->entry_list, list) {
+ t_delta = jiffies_to_msecs(jiffies - iter->recorded_time);
+#ifdef PNO_DEBUG
+ _base_bp = bp;
+ memset(msg, 0, sizeof(msg));
+#endif
+ /* BSSID info */
+ bp += nreadsize = sprintf(bp, "bssid=%s\n",
+ bcm_ether_ntoa((const struct ether_addr *)&iter->BSSID, eabuf));
+ nleftsize -= nreadsize;
+ /* SSID */
+ bp += nreadsize = sprintf(bp, "ssid=%s\n", iter->SSID);
+ nleftsize -= nreadsize;
+ /* channel */
+ bp += nreadsize = sprintf(bp, "freq=%d\n",
+ wf_channel2mhz(iter->channel,
+ iter->channel <= CH_MAX_2G_CHANNEL?
+ WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G));
+ nleftsize -= nreadsize;
+ /* RSSI */
+ bp += nreadsize = sprintf(bp, "level=%d\n", iter->RSSI);
+ nleftsize -= nreadsize;
+ /* add the time consumed in Driver to the timestamp of firmware */
+ iter->timestamp += t_delta;
+ bp += nreadsize = sprintf(bp, "age=%d\n", iter->timestamp);
+ nleftsize -= nreadsize;
+ /* RTT0 */
+ bp += nreadsize = sprintf(bp, "dist=%d\n",
+ (iter->rtt0 == 0)? -1 : iter->rtt0);
+ nleftsize -= nreadsize;
+ /* RTT1 */
+ bp += nreadsize = sprintf(bp, "distSd=%d\n",
+ (iter->rtt0 == 0)? -1 : iter->rtt1);
+ nleftsize -= nreadsize;
+ bp += nreadsize = sprintf(bp, "%s", AP_END_MARKER);
+ nleftsize -= nreadsize;
+ list_del(&iter->list);
+ MFREE(dhd->osh, iter, BESTNET_ENTRY_SIZE);
+#ifdef PNO_DEBUG
+ memcpy(msg, _base_bp, bp - _base_bp);
+ AP6210_DEBUG("Entry : \n%s", msg);
+#endif
+ }
+ bp += nreadsize = sprintf(bp, "%s", SCAN_END_MARKER);
+ AP6210_DEBUG("%s", SCAN_END_MARKER);
+ nleftsize -= nreadsize;
+ pprev = phead;
+ /* reset the header */
+ siter->bestnetheader = phead = phead->next;
+ MFREE(dhd->osh, pprev, BEST_HEADER_SIZE);
+
+ siter->cnt_header--;
+ }
+ if (phead == NULL) {
+ /* we store all entry in this scan , so it is ok to delete */
+ list_del(&siter->list);
+ MFREE(dhd->osh, siter, SCAN_RESULTS_SIZE);
+ }
+ }
+exit:
+ if (cnt < params_batch->get_batch.expired_tot_scan_cnt) {
+ AP6210_ERR("Buffer size is small to save all batch entry,"
+ " cnt : %d (remained_scan_cnt): %d\n",
+ cnt, params_batch->get_batch.expired_tot_scan_cnt - cnt);
+ }
+ params_batch->get_batch.expired_tot_scan_cnt -= cnt;
+ /* set FALSE only if the link list is empty after returning the data */
+ if (list_empty(&params_batch->get_batch.expired_scan_results_list)) {
+ params_batch->get_batch.batch_started = FALSE;
+ bp += sprintf(bp, "%s", RESULTS_END_MARKER);
+ AP6210_DEBUG("%s", RESULTS_END_MARKER);
+ AP6210_DEBUG("%s : Getting the batching data is complete\n", __FUNCTION__);
+ }
+ /* return used memory in buffer */
+ bytes_written = (int32)(bp - buf);
+ return bytes_written;
+}
+static int
+_dhd_pno_clear_all_batch_results(dhd_pub_t *dhd, struct list_head *head, bool only_last)
+{
+ int err = BCME_OK;
+ int removed_scan_cnt = 0;
+ dhd_pno_scan_results_t *siter, *snext;
+ dhd_pno_best_header_t *phead, *pprev;
+ dhd_pno_bestnet_entry_t *iter, *next;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(head, "head is NULL", err);
+ NULL_CHECK(head->next, "head->next is NULL", err);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ list_for_each_entry_safe(siter, snext,
+ head, list) {
+ if (only_last) {
+ /* in case that we need to delete only last one */
+ if (!list_is_last(&siter->list, head)) {
+ /* skip if the one is not last */
+ continue;
+ }
+ }
+ /* delete all data belong if the one is last */
+ phead = siter->bestnetheader;
+ while (phead != NULL) {
+ removed_scan_cnt++;
+ list_for_each_entry_safe(iter, next,
+ &phead->entry_list, list) {
+ list_del(&iter->list);
+ MFREE(dhd->osh, iter, BESTNET_ENTRY_SIZE);
+ }
+ pprev = phead;
+ phead = phead->next;
+ MFREE(dhd->osh, pprev, BEST_HEADER_SIZE);
+ }
+ if (phead == NULL) {
+ /* it is ok to delete top node */
+ list_del(&siter->list);
+ MFREE(dhd->osh, siter, SCAN_RESULTS_SIZE);
+ }
+ }
+ return removed_scan_cnt;
+}
+
+static int
+_dhd_pno_cfg(dhd_pub_t *dhd, uint16 *channel_list, int nchan)
+{
+ int err = BCME_OK;
+ int i = 0;
+ wl_pfn_cfg_t pfncfg_param;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ if (nchan) {
+ NULL_CHECK(channel_list, "nchan is NULL", err);
+ }
+ AP6210_DEBUG("%s enter : nchan : %d\n", __FUNCTION__, nchan);
+ memset(&pfncfg_param, 0, sizeof(wl_pfn_cfg_t));
+ /* Setup default values */
+ pfncfg_param.reporttype = htod32(WL_PFN_REPORT_ALLNET);
+ pfncfg_param.channel_num = htod32(0);
+
+ for (i = 0; i < nchan && nchan < WL_NUMCHANNELS; i++)
+ pfncfg_param.channel_list[i] = channel_list[i];
+
+ pfncfg_param.channel_num = htod32(nchan);
+ err = dhd_iovar(dhd, 0, "pfn_cfg", (char *)&pfncfg_param, sizeof(pfncfg_param), 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to execute pfn_cfg\n", __FUNCTION__);
+ goto exit;
+ }
+exit:
+ return err;
+}
+static int
+_dhd_pno_reinitialize_prof(dhd_pub_t *dhd, dhd_pno_params_t *params, dhd_pno_mode_t mode)
+{
+ int err = BCME_OK;
+ dhd_pno_status_info_t *_pno_state;
+ NULL_CHECK(dhd, "dhd is NULL\n", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL\n", err);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ mutex_lock(&_pno_state->pno_mutex);
+ switch (mode) {
+ case DHD_PNO_LEGACY_MODE: {
+ struct dhd_pno_ssid *iter, *next;
+ if (params->params_legacy.nssid > 0) {
+ list_for_each_entry_safe(iter, next,
+ &params->params_legacy.ssid_list, list) {
+ list_del(&iter->list);
+ kfree(iter);
+ }
+ }
+ params->params_legacy.scan_fr = 0;
+ params->params_legacy.pno_freq_expo_max = 0;
+ params->params_legacy.pno_repeat = 0;
+ params->params_legacy.nchan = 0;
+ memset(params->params_legacy.chan_list, 0,
+ sizeof(params->params_legacy.chan_list));
+ break;
+ }
+ case DHD_PNO_BATCH_MODE: {
+ params->params_batch.scan_fr = 0;
+ params->params_batch.mscan = 0;
+ params->params_batch.nchan = 0;
+ params->params_batch.rtt = 0;
+ params->params_batch.bestn = 0;
+ params->params_batch.nchan = 0;
+ params->params_batch.band = WLC_BAND_AUTO;
+ memset(params->params_batch.chan_list, 0,
+ sizeof(params->params_batch.chan_list));
+ params->params_batch.get_batch.batch_started = FALSE;
+ params->params_batch.get_batch.buf = NULL;
+ params->params_batch.get_batch.bufsize = 0;
+ params->params_batch.get_batch.reason = 0;
+ _dhd_pno_clear_all_batch_results(dhd,
+ &params->params_batch.get_batch.scan_results_list, FALSE);
+ _dhd_pno_clear_all_batch_results(dhd,
+ &params->params_batch.get_batch.expired_scan_results_list, FALSE);
+ params->params_batch.get_batch.tot_scan_cnt = 0;
+ params->params_batch.get_batch.expired_tot_scan_cnt = 0;
+ params->params_batch.get_batch.top_node_cnt = 0;
+ INIT_LIST_HEAD(&params->params_batch.get_batch.scan_results_list);
+ INIT_LIST_HEAD(&params->params_batch.get_batch.expired_scan_results_list);
+ break;
+ }
+ case DHD_PNO_HOTLIST_MODE: {
+ struct dhd_pno_bssid *iter, *next;
+ if (params->params_hotlist.nbssid > 0) {
+ list_for_each_entry_safe(iter, next,
+ &params->params_hotlist.bssid_list, list) {
+ list_del(&iter->list);
+ kfree(iter);
+ }
+ }
+ params->params_hotlist.scan_fr = 0;
+ params->params_hotlist.nbssid = 0;
+ params->params_hotlist.nchan = 0;
+ params->params_batch.band = WLC_BAND_AUTO;
+ memset(params->params_hotlist.chan_list, 0,
+ sizeof(params->params_hotlist.chan_list));
+ break;
+ }
+ default:
+ AP6210_ERR("%s : unknown mode : %d\n", __FUNCTION__, mode);
+ break;
+ }
+ mutex_unlock(&_pno_state->pno_mutex);
+ return err;
+}
+static int
+_dhd_pno_add_bssid(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, int nbssid)
+{
+ int err = BCME_OK;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ if (nbssid) {
+ NULL_CHECK(p_pfn_bssid, "bssid list is NULL", err);
+ }
+ err = dhd_iovar(dhd, 0, "pfn_add_bssid", (char *)&p_pfn_bssid,
+ sizeof(wl_pfn_bssid_t) * nbssid, 1);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to execute pfn_cfg\n", __FUNCTION__);
+ goto exit;
+ }
+exit:
+ return err;
+}
+int
+dhd_pno_stop_for_ssid(dhd_pub_t *dhd)
+{
+ int err = BCME_OK;
+ uint32 mode = 0;
+ dhd_pno_status_info_t *_pno_state;
+ dhd_pno_params_t *_params;
+ wl_pfn_bssid_t *p_pfn_bssid;
+ NULL_CHECK(dhd, "dev is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ if (!(_pno_state->pno_mode & DHD_PNO_LEGACY_MODE)) {
+ AP6210_ERR("%s : LEGACY PNO MODE is not enabled\n", __FUNCTION__);
+ goto exit;
+ }
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE;
+ /* restart Batch mode if the batch mode is on */
+ if (_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) {
+ /* retrieve the batching data from firmware into host */
+ dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE);
+ /* save current pno_mode before calling dhd_pno_clean */
+ mode = _pno_state->pno_mode;
+ _dhd_pno_clean(dhd);
+ /* restore previous pno_mode */
+ _pno_state->pno_mode = mode;
+ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) {
+ _params = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]);
+ /* restart BATCH SCAN */
+ err = dhd_pno_set_for_batch(dhd, &_params->params_batch);
+ if (err < 0) {
+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE;
+ AP6210_ERR("%s : failed to restart batch scan(err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) {
+ /* restart HOTLIST SCAN */
+ struct dhd_pno_bssid *iter, *next;
+ _params = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]);
+ p_pfn_bssid = kzalloc(sizeof(wl_pfn_bssid_t) *
+ _params->params_hotlist.nbssid, GFP_KERNEL);
+ if (p_pfn_bssid == NULL) {
+ AP6210_ERR("%s : failed to allocate wl_pfn_bssid_t array"
+ " (count: %d)",
+ __FUNCTION__, _params->params_hotlist.nbssid);
+ err = BCME_ERROR;
+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE;
+ goto exit;
+ }
+ /* convert dhd_pno_bssid to wl_pfn_bssid */
+ list_for_each_entry_safe(iter, next,
+ &_params->params_hotlist.bssid_list, list) {
+ memcpy(&p_pfn_bssid->macaddr,
+ &iter->macaddr, ETHER_ADDR_LEN);
+ p_pfn_bssid->flags = iter->flags;
+ p_pfn_bssid++;
+ }
+ err = dhd_pno_set_for_hotlist(dhd, p_pfn_bssid, &_params->params_hotlist);
+ if (err < 0) {
+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE;
+ AP6210_ERR("%s : failed to restart hotlist scan(err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+ } else {
+ err = _dhd_pno_clean(dhd);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to call _dhd_pno_clean (err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+exit:
+ return err;
+}
+
+int
+dhd_pno_enable(dhd_pub_t *dhd, int enable)
+{
+ int err = BCME_OK;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ return (_dhd_pno_enable(dhd, enable));
+}
+
+int
+dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid,
+ uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan)
+{
+ struct dhd_pno_ssid *_pno_ssid;
+ dhd_pno_params_t *_params;
+ dhd_pno_params_t *_params2;
+ dhd_pno_status_info_t *_pno_state;
+ uint16 _chan_list[WL_NUMCHANNELS];
+ int32 tot_nchan = 0;
+ int err = BCME_OK;
+ int i;
+ int mode = 0;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+
+ if (!dhd_support_sta_mode(dhd)) {
+ err = BCME_BADOPTION;
+ goto exit;
+ }
+ AP6210_DEBUG("%s enter : scan_fr :%d, pno_repeat :%d,"
+ "pno_freq_expo_max: %d, nchan :%d\n", __FUNCTION__,
+ scan_fr, pno_repeat, pno_freq_expo_max, nchan);
+
+ _params = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]);
+ if (!(_pno_state->pno_mode & DHD_PNO_LEGACY_MODE)) {
+ _pno_state->pno_mode |= DHD_PNO_LEGACY_MODE;
+ err = _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_LEGACY_MODE);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to reinitialize profile (err %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+ memset(_chan_list, 0, sizeof(_chan_list));
+ tot_nchan = nchan;
+ if (tot_nchan > 0 && channel_list) {
+ for (i = 0; i < nchan; i++)
+ _params->params_legacy.chan_list[i] = _chan_list[i] = channel_list[i];
+ }
+ if (_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_HOTLIST_MODE)) {
+ AP6210_DEBUG("BATCH SCAN is on progress in firmware\n");
+ /* retrieve the batching data from firmware into host */
+ dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE);
+ /* store current pno_mode before disabling pno */
+ mode = _pno_state->pno_mode;
+ err = _dhd_pno_enable(dhd, PNO_OFF);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to disable PNO\n", __FUNCTION__);
+ goto exit;
+ }
+ /* restore the previous mode */
+ _pno_state->pno_mode = mode;
+ /* use superset of channel list between two mode */
+ if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) {
+ _params2 = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]);
+ if (_params2->params_batch.nchan > 0 && nchan > 0) {
+ err = _dhd_pno_chan_merge(_chan_list, &tot_nchan,
+ &_params2->params_batch.chan_list[0],
+ _params2->params_batch.nchan,
+ &channel_list[0], nchan);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to merge channel list"
+ " between legacy and batch\n",
+ __FUNCTION__);
+ goto exit;
+ }
+ } else {
+ AP6210_DEBUG("superset channel will use"
+ " all channels in firmware\n");
+ }
+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) {
+ _params2 = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]);
+ if (_params2->params_hotlist.nchan > 0 && nchan > 0) {
+ err = _dhd_pno_chan_merge(_chan_list, &tot_nchan,
+ &_params2->params_hotlist.chan_list[0],
+ _params2->params_hotlist.nchan,
+ &channel_list[0], nchan);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to merge channel list"
+ " between legacy and hotlist\n",
+ __FUNCTION__);
+ goto exit;
+ }
+ }
+ }
+ }
+ _params->params_legacy.scan_fr = scan_fr;
+ _params->params_legacy.pno_repeat = pno_repeat;
+ _params->params_legacy.pno_freq_expo_max = pno_freq_expo_max;
+ _params->params_legacy.nchan = nchan;
+ _params->params_legacy.nssid = nssid;
+ INIT_LIST_HEAD(&_params->params_legacy.ssid_list);
+ if ((err = _dhd_pno_set(dhd, _params, DHD_PNO_LEGACY_MODE)) < 0) {
+ AP6210_ERR("failed to set call pno_set (err %d) in firmware\n", err);
+ goto exit;
+ }
+ if ((err = _dhd_pno_add_ssid(dhd, ssid_list, nssid)) < 0) {
+ AP6210_ERR("failed to add ssid list (err %d) in firmware\n", err);
+ goto exit;
+ }
+ for (i = 0; i < nssid; i++) {
+ _pno_ssid = kzalloc(sizeof(struct dhd_pno_ssid), GFP_KERNEL);
+ if (_pno_ssid == NULL) {
+ AP6210_ERR("%s : failed to allocate struct dhd_pno_ssid\n",
+ __FUNCTION__);
+ goto exit;
+ }
+ _pno_ssid->SSID_len = ssid_list[i].SSID_len;
+ memcpy(_pno_ssid->SSID, ssid_list[i].SSID, _pno_ssid->SSID_len);
+ list_add_tail(&_pno_ssid->list, &_params->params_legacy.ssid_list);
+
+ }
+ if (tot_nchan > 0) {
+ if ((err = _dhd_pno_cfg(dhd, _chan_list, tot_nchan)) < 0) {
+ AP6210_ERR("%s : failed to set call pno_cfg (err %d) in firmware\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+ if (_pno_state->pno_status == DHD_PNO_DISABLED) {
+ if ((err = _dhd_pno_enable(dhd, PNO_ON)) < 0)
+ AP6210_ERR("%s : failed to enable PNO\n", __FUNCTION__);
+ }
+exit:
+ /* clear mode in case of error */
+ if (err < 0)
+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE;
+ return err;
+}
+int
+dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params)
+{
+ int err = BCME_OK;
+ uint16 _chan_list[WL_NUMCHANNELS];
+ int rem_nchan = 0, tot_nchan = 0;
+ int mode = 0, mscan = 0;
+ int i = 0;
+ dhd_pno_params_t *_params;
+ dhd_pno_params_t *_params2;
+ dhd_pno_status_info_t *_pno_state;
+ wlc_ssid_t *p_ssid_list = NULL;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ NULL_CHECK(batch_params, "batch_params is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ if (!dhd_support_sta_mode(dhd)) {
+ err = BCME_BADOPTION;
+ goto exit;
+ }
+ if (!WLS_SUPPORTED(_pno_state)) {
+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__);
+ err = BCME_UNSUPPORTED;
+ goto exit;
+ }
+ _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS];
+ if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) {
+ _pno_state->pno_mode |= DHD_PNO_BATCH_MODE;
+ err = _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_BATCH_MODE);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to call _dhd_pno_reinitialize_prof\n",
+ __FUNCTION__);
+ goto exit;
+ }
+ }
+ _params->params_batch.scan_fr = batch_params->scan_fr;
+ _params->params_batch.bestn = batch_params->bestn;
+ _params->params_batch.mscan = (batch_params->mscan)?
+ batch_params->mscan : DEFAULT_BATCH_MSCAN;
+ _params->params_batch.nchan = batch_params->nchan;
+ memcpy(_params->params_batch.chan_list, batch_params->chan_list,
+ sizeof(_params->params_batch.chan_list));
+
+ memset(_chan_list, 0, sizeof(_chan_list));
+
+ rem_nchan = ARRAYSIZE(batch_params->chan_list) - batch_params->nchan;
+ if (batch_params->band == WLC_BAND_2G || batch_params->band == WLC_BAND_5G) {
+ /* get a valid channel list based on band B or A */
+ err = _dhd_pno_get_channels(dhd,
+ &_params->params_batch.chan_list[batch_params->nchan],
+ &rem_nchan, batch_params->band, FALSE);
+ if (err < 0) {
+ AP6210_ERR("%s: failed to get valid channel list(band : %d)\n",
+ __FUNCTION__, batch_params->band);
+ goto exit;
+ }
+ /* now we need to update nchan because rem_chan has valid channel count */
+ _params->params_batch.nchan += rem_nchan;
+ /* need to sort channel list */
+ sort(_params->params_batch.chan_list, _params->params_batch.nchan,
+ sizeof(_params->params_batch.chan_list[0]), _dhd_pno_cmpfunc, NULL);
+ }
+#ifdef PNO_DEBUG
+{
+ AP6210_DEBUG("Channel list : ");
+ for (i = 0; i < _params->params_batch.nchan; i++) {
+ AP6210_DEBUG("%d ", _params->params_batch.chan_list[i]);
+ }
+ AP6210_DEBUG("\n");
+}
+#endif
+ if (_params->params_batch.nchan) {
+ /* copy the channel list into local array */
+ memcpy(_chan_list, _params->params_batch.chan_list, sizeof(_chan_list));
+ tot_nchan = _params->params_batch.nchan;
+ }
+ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) {
+ struct dhd_pno_ssid *iter, *next;
+ AP6210_DEBUG("PNO SSID is on progress in firmware\n");
+ /* store current pno_mode before disabling pno */
+ mode = _pno_state->pno_mode;
+ err = _dhd_pno_enable(dhd, PNO_OFF);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to disable PNO\n", __FUNCTION__);
+ goto exit;
+ }
+ /* restore the previous mode */
+ _pno_state->pno_mode = mode;
+ /* Use the superset for channelist between two mode */
+ _params2 = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]);
+ if (_params2->params_legacy.nchan > 0 && _params->params_batch.nchan > 0) {
+ err = _dhd_pno_chan_merge(_chan_list, &tot_nchan,
+ &_params2->params_legacy.chan_list[0],
+ _params2->params_legacy.nchan,
+ &_params->params_batch.chan_list[0], _params->params_batch.nchan);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to merge channel list"
+ " between legacy and batch\n",
+ __FUNCTION__);
+ goto exit;
+ }
+ } else {
+ AP6210_DEBUG("superset channel will use all channels in firmware\n");
+ }
+ p_ssid_list = kzalloc(sizeof(wlc_ssid_t) *
+ _params2->params_legacy.nssid, GFP_KERNEL);
+ if (p_ssid_list == NULL) {
+ AP6210_ERR("%s : failed to allocate wlc_ssid_t array (count: %d)",
+ __FUNCTION__, _params2->params_legacy.nssid);
+ err = BCME_ERROR;
+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE;
+ goto exit;
+ }
+ i = 0;
+ /* convert dhd_pno_ssid to dhd_pno_ssid */
+ list_for_each_entry_safe(iter, next, &_params2->params_legacy.ssid_list, list) {
+ p_ssid_list[i].SSID_len = iter->SSID_len;
+ memcpy(p_ssid_list->SSID, iter->SSID, p_ssid_list[i].SSID_len);
+ i++;
+ }
+ if ((err = _dhd_pno_add_ssid(dhd, p_ssid_list,
+ _params2->params_legacy.nssid)) < 0) {
+ AP6210_ERR("failed to add ssid list (err %d) in firmware\n", err);
+ goto exit;
+ }
+ }
+ if ((err = _dhd_pno_set(dhd, _params, DHD_PNO_BATCH_MODE)) < 0) {
+ AP6210_ERR("%s : failed to set call pno_set (err %d) in firmware\n",
+ __FUNCTION__, err);
+ goto exit;
+ } else {
+ /* we need to return mscan */
+ mscan = err;
+ }
+ if (tot_nchan > 0) {
+ if ((err = _dhd_pno_cfg(dhd, _chan_list, tot_nchan)) < 0) {
+ AP6210_ERR("%s : failed to set call pno_cfg (err %d) in firmware\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+ if (_pno_state->pno_status == DHD_PNO_DISABLED) {
+ if ((err = _dhd_pno_enable(dhd, PNO_ON)) < 0)
+ AP6210_ERR("%s : failed to enable PNO\n", __FUNCTION__);
+ }
+exit:
+ /* clear mode in case of error */
+ if (err < 0)
+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE;
+ else {
+ /* return #max scan firmware can do */
+ err = mscan;
+ }
+ if (p_ssid_list)
+ kfree(p_ssid_list);
+ return err;
+}
+
+static int
+_dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason)
+{
+ int err = BCME_OK;
+ int i, j;
+ uint32 timestamp = 0;
+ dhd_pno_params_t *_params = NULL;
+ dhd_pno_status_info_t *_pno_state = NULL;
+ wl_pfn_lscanresults_t *plbestnet = NULL;
+ wl_pfn_lnet_info_t *plnetinfo;
+ dhd_pno_bestnet_entry_t *pbestnet_entry;
+ dhd_pno_best_header_t *pbestnetheader = NULL;
+ dhd_pno_scan_results_t *pscan_results = NULL, *siter, *snext;
+ bool allocate_header = FALSE;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ if (!dhd_support_sta_mode(dhd)) {
+ err = BCME_BADOPTION;
+ goto exit;
+ }
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+
+ if (!WLS_SUPPORTED(_pno_state)) {
+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__);
+ err = BCME_UNSUPPORTED;
+ goto exit;
+ }
+ if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) {
+ AP6210_ERR("%s: Batching SCAN mode is not enabled\n", __FUNCTION__);
+ goto exit;
+ }
+ mutex_lock(&_pno_state->pno_mutex);
+ _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS];
+ if (buf && bufsize) {
+ if (!list_empty(&_params->params_batch.get_batch.expired_scan_results_list)) {
+ /* need to check whether we have cashed data or not */
+ AP6210_DEBUG("%s: have cashed batching data in Driver\n",
+ __FUNCTION__);
+ /* convert to results format */
+ goto convert_format;
+ } else {
+ /* this is a first try to get batching results */
+ if (!list_empty(&_params->params_batch.get_batch.scan_results_list)) {
+ /* move the scan_results_list to expired_scan_results_lists */
+ list_for_each_entry_safe(siter, snext,
+ &_params->params_batch.get_batch.scan_results_list, list) {
+ list_move_tail(&siter->list,
+ &_params->params_batch.get_batch.expired_scan_results_list);
+ }
+ _params->params_batch.get_batch.top_node_cnt = 0;
+ _params->params_batch.get_batch.expired_tot_scan_cnt =
+ _params->params_batch.get_batch.tot_scan_cnt;
+ _params->params_batch.get_batch.tot_scan_cnt = 0;
+ goto convert_format;
+ }
+ }
+ }
+ /* create dhd_pno_scan_results_t whenever we got event WLC_E_PFN_BEST_BATCHING */
+ pscan_results = (dhd_pno_scan_results_t *)MALLOC(dhd->osh, SCAN_RESULTS_SIZE);
+ if (pscan_results == NULL) {
+ err = BCME_NOMEM;
+ AP6210_ERR("failed to allocate dhd_pno_scan_results_t\n");
+ goto exit;
+ }
+ pscan_results->bestnetheader = NULL;
+ pscan_results->cnt_header = 0;
+ /* add the element into list unless total node cnt is less than MAX_NODE_ CNT */
+ if (_params->params_batch.get_batch.top_node_cnt < MAX_NODE_CNT) {
+ list_add(&pscan_results->list, &_params->params_batch.get_batch.scan_results_list);
+ _params->params_batch.get_batch.top_node_cnt++;
+ } else {
+ int _removed_scan_cnt;
+ /* remove oldest one and add new one */
+ AP6210_DEBUG("%s : Remove oldest node and add new one\n", __FUNCTION__);
+ _removed_scan_cnt = _dhd_pno_clear_all_batch_results(dhd,
+ &_params->params_batch.get_batch.scan_results_list, TRUE);
+ _params->params_batch.get_batch.tot_scan_cnt -= _removed_scan_cnt;
+ list_add(&pscan_results->list, &_params->params_batch.get_batch.scan_results_list);
+
+ }
+ plbestnet = (wl_pfn_lscanresults_t *)MALLOC(dhd->osh, PNO_BESTNET_LEN);
+ NULL_CHECK(plbestnet, "failed to allocate buffer for bestnet", err);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ memset(plbestnet, 0, PNO_BESTNET_LEN);
+ while (plbestnet->status != PFN_COMPLETE) {
+ memset(plbestnet, 0, PNO_BESTNET_LEN);
+ err = dhd_iovar(dhd, 0, "pfnlbest", (char *)plbestnet, PNO_BESTNET_LEN, 0);
+ if (err < 0) {
+ if (err == BCME_EPERM) {
+ AP6210_ERR("we cannot get the batching data "
+ "during scanning in firmware, try again\n,");
+ msleep(500);
+ continue;
+ } else {
+ AP6210_ERR("%s : failed to execute pfnlbest (err :%d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+ AP6210_DEBUG("ver %d, status : %d, count %d\n", plbestnet->version,
+ plbestnet->status, plbestnet->count);
+ if (plbestnet->version != PFN_SCANRESULT_VERSION) {
+ err = BCME_VERSION;
+ AP6210_ERR("bestnet version(%d) is mismatch with Driver version(%d)\n",
+ plbestnet->version, PFN_SCANRESULT_VERSION);
+ goto exit;
+ }
+ plnetinfo = plbestnet->netinfo;
+ for (i = 0; i < plbestnet->count; i++) {
+ pbestnet_entry = (dhd_pno_bestnet_entry_t *)
+ MALLOC(dhd->osh, BESTNET_ENTRY_SIZE);
+ if (pbestnet_entry == NULL) {
+ err = BCME_NOMEM;
+ AP6210_ERR("failed to allocate dhd_pno_bestnet_entry\n");
+ goto exit;
+ }
+ pbestnet_entry->recorded_time = jiffies; /* record the current time */
+ /* create header for the first entry */
+ allocate_header = (i == 0)? TRUE : FALSE;
+ /* check whether the new generation is started or not */
+ if (timestamp && (TIME_DIFF(timestamp, plnetinfo->timestamp)
+ > TIME_MIN_DIFF))
+ allocate_header = TRUE;
+ timestamp = plnetinfo->timestamp;
+ if (allocate_header) {
+ pbestnetheader = (dhd_pno_best_header_t *)
+ MALLOC(dhd->osh, BEST_HEADER_SIZE);
+ if (pbestnetheader == NULL) {
+ err = BCME_NOMEM;
+ if (pbestnet_entry)
+ MFREE(dhd->osh, pbestnet_entry,
+ BESTNET_ENTRY_SIZE);
+ AP6210_ERR("failed to allocate dhd_pno_bestnet_entry\n");
+ goto exit;
+ }
+ /* increase total cnt of bestnet header */
+ pscan_results->cnt_header++;
+ /* need to record the reason to call dhd_pno_get_for_bach */
+ if (reason)
+ pbestnetheader->reason = (ENABLE << reason);
+ memset(pbestnetheader, 0, BEST_HEADER_SIZE);
+ /* initialize the head of linked list */
+ INIT_LIST_HEAD(&(pbestnetheader->entry_list));
+ /* link the pbestnet heaer into existed list */
+ if (pscan_results->bestnetheader == NULL)
+ /* In case of header */
+ pscan_results->bestnetheader = pbestnetheader;
+ else {
+ dhd_pno_best_header_t *head = pscan_results->bestnetheader;
+ pscan_results->bestnetheader = pbestnetheader;
+ pbestnetheader->next = head;
+ }
+ }
+ /* fills the best network info */
+ pbestnet_entry->channel = plnetinfo->pfnsubnet.channel;
+ pbestnet_entry->RSSI = plnetinfo->RSSI;
+ if (plnetinfo->flags & PFN_PARTIAL_SCAN_MASK) {
+ /* if RSSI is positive value, we assume that
+ * this scan is aborted by other scan
+ */
+ AP6210_DEBUG("This scan is aborted\n");
+ pbestnetheader->reason = (ENABLE << PNO_STATUS_ABORT);
+ }
+ pbestnet_entry->rtt0 = plnetinfo->rtt0;
+ pbestnet_entry->rtt1 = plnetinfo->rtt1;
+ pbestnet_entry->timestamp = plnetinfo->timestamp;
+ pbestnet_entry->SSID_len = plnetinfo->pfnsubnet.SSID_len;
+ memcpy(pbestnet_entry->SSID, plnetinfo->pfnsubnet.SSID,
+ pbestnet_entry->SSID_len);
+ memcpy(&pbestnet_entry->BSSID, &plnetinfo->pfnsubnet.BSSID, ETHER_ADDR_LEN);
+ /* add the element into list */
+ list_add_tail(&pbestnet_entry->list, &pbestnetheader->entry_list);
+ /* increase best entry count */
+ pbestnetheader->tot_cnt++;
+ pbestnetheader->tot_size += BESTNET_ENTRY_SIZE;
+ AP6210_DEBUG("Header %d\n", pscan_results->cnt_header - 1);
+ AP6210_DEBUG("\tSSID : ");
+ for (j = 0; j < plnetinfo->pfnsubnet.SSID_len; j++)
+ AP6210_DEBUG("%c", plnetinfo->pfnsubnet.SSID[j]);
+ AP6210_DEBUG("\n");
+ AP6210_DEBUG("\tBSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ plnetinfo->pfnsubnet.BSSID.octet[0],
+ plnetinfo->pfnsubnet.BSSID.octet[1],
+ plnetinfo->pfnsubnet.BSSID.octet[2],
+ plnetinfo->pfnsubnet.BSSID.octet[3],
+ plnetinfo->pfnsubnet.BSSID.octet[4],
+ plnetinfo->pfnsubnet.BSSID.octet[5]);
+ AP6210_DEBUG("\tchannel: %d, RSSI: %d, timestamp: %d ms\n",
+ plnetinfo->pfnsubnet.channel,
+ plnetinfo->RSSI, plnetinfo->timestamp);
+ AP6210_DEBUG("\tRTT0 : %d, RTT1: %d\n", plnetinfo->rtt0, plnetinfo->rtt1);
+ plnetinfo++;
+ }
+ }
+ /* increase total scan count using current scan count */
+ _params->params_batch.get_batch.tot_scan_cnt += pscan_results->cnt_header;
+
+ if (buf && bufsize) {
+ /* This is a first try to get batching results */
+ if (!list_empty(&_params->params_batch.get_batch.scan_results_list)) {
+ /* move the scan_results_list to expired_scan_results_lists */
+ list_for_each_entry_safe(siter, snext,
+ &_params->params_batch.get_batch.scan_results_list, list) {
+ list_move_tail(&siter->list,
+ &_params->params_batch.get_batch.expired_scan_results_list);
+ }
+ /* reset gloval values after moving to expired list */
+ _params->params_batch.get_batch.top_node_cnt = 0;
+ _params->params_batch.get_batch.expired_tot_scan_cnt =
+ _params->params_batch.get_batch.tot_scan_cnt;
+ _params->params_batch.get_batch.tot_scan_cnt = 0;
+ }
+convert_format:
+ err = _dhd_pno_convert_format(dhd, &_params->params_batch, buf, bufsize);
+ if (err < 0) {
+ AP6210_ERR("failed to convert the data into upper layer format\n");
+ goto exit;
+ }
+ }
+exit:
+ if (plbestnet)
+ MFREE(dhd->osh, plbestnet, PNO_BESTNET_LEN);
+ _params->params_batch.get_batch.buf = NULL;
+ _params->params_batch.get_batch.bufsize = 0;
+ mutex_unlock(&_pno_state->pno_mutex);
+ complete(&_pno_state->get_batch_done);
+ return err;
+}
+static void
+_dhd_pno_get_batch_handler(struct work_struct *work)
+{
+ dhd_pno_status_info_t *_pno_state;
+ dhd_pub_t *dhd;
+ struct dhd_pno_batch_params *params_batch;
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ _pno_state = container_of(work, struct dhd_pno_status_info, work);
+ dhd = _pno_state->dhd;
+ if (dhd == NULL) {
+ AP6210_ERR("%s : dhd is NULL\n", __FUNCTION__);
+ return;
+ }
+ params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch;
+ _dhd_pno_get_for_batch(dhd, params_batch->get_batch.buf,
+ params_batch->get_batch.bufsize, params_batch->get_batch.reason);
+
+}
+
+int
+dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason)
+{
+ int err = BCME_OK;
+ dhd_pno_status_info_t *_pno_state;
+ struct dhd_pno_batch_params *params_batch;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ if (!dhd_support_sta_mode(dhd)) {
+ err = BCME_BADOPTION;
+ goto exit;
+ }
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+
+ if (!WLS_SUPPORTED(_pno_state)) {
+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__);
+ err = BCME_UNSUPPORTED;
+ goto exit;
+ }
+ params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch;
+ if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) {
+ AP6210_ERR("%s: Batching SCAN mode is not enabled\n", __FUNCTION__);
+ goto exit;
+ }
+ params_batch->get_batch.buf = buf;
+ params_batch->get_batch.bufsize = bufsize;
+ params_batch->get_batch.reason = reason;
+ schedule_work(&_pno_state->work);
+ wait_for_completion(&_pno_state->get_batch_done);
+exit:
+ return err;
+}
+
+int
+dhd_pno_stop_for_batch(dhd_pub_t *dhd)
+{
+ int err = BCME_OK;
+ int mode = 0;
+ int i = 0;
+ dhd_pno_status_info_t *_pno_state;
+ dhd_pno_params_t *_params;
+ wl_pfn_bssid_t *p_pfn_bssid;
+ wlc_ssid_t *p_ssid_list = NULL;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ if (!dhd_support_sta_mode(dhd)) {
+ err = BCME_BADOPTION;
+ goto exit;
+ }
+ if (!WLS_SUPPORTED(_pno_state)) {
+ AP6210_ERR("%s : wifi location service is not supported\n",
+ __FUNCTION__);
+ err = BCME_UNSUPPORTED;
+ goto exit;
+ }
+ if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) {
+ AP6210_ERR("%s : PNO BATCH MODE is not enabled\n", __FUNCTION__);
+ goto exit;
+ }
+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE;
+ if (_pno_state->pno_mode & (DHD_PNO_LEGACY_MODE | DHD_PNO_HOTLIST_MODE)) {
+ mode = _pno_state->pno_mode;
+ _dhd_pno_clean(dhd);
+ _pno_state->pno_mode = mode;
+ /* restart Legacy PNO if the Legacy PNO is on */
+ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) {
+ struct dhd_pno_legacy_params *_params_legacy;
+ struct dhd_pno_ssid *iter, *next;
+ _params_legacy =
+ &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS].params_legacy);
+ p_ssid_list = kzalloc(sizeof(wlc_ssid_t) *
+ _params_legacy->nssid, GFP_KERNEL);
+ if (p_ssid_list == NULL) {
+ AP6210_ERR("%s : failed to allocate wlc_ssid_t array (count: %d)",
+ __FUNCTION__, _params_legacy->nssid);
+ err = BCME_ERROR;
+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE;
+ goto exit;
+ }
+ i = 0;
+ /* convert dhd_pno_ssid to dhd_pno_ssid */
+ list_for_each_entry_safe(iter, next, &_params_legacy->ssid_list, list) {
+ p_ssid_list[i].SSID_len = iter->SSID_len;
+ memcpy(p_ssid_list[i].SSID, iter->SSID, p_ssid_list[i].SSID_len);
+ i++;
+ }
+ err = dhd_pno_set_for_ssid(dhd, p_ssid_list, _params_legacy->nssid,
+ _params_legacy->scan_fr, _params_legacy->pno_repeat,
+ _params_legacy->pno_freq_expo_max, _params_legacy->chan_list,
+ _params_legacy->nchan);
+ if (err < 0) {
+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE;
+ AP6210_ERR("%s : failed to restart legacy PNO scan(err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ } else if (_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE) {
+ struct dhd_pno_bssid *iter, *next;
+ _params = &(_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS]);
+ p_pfn_bssid = kzalloc(sizeof(wl_pfn_bssid_t) *
+ _params->params_hotlist.nbssid, GFP_KERNEL);
+ if (p_pfn_bssid == NULL) {
+ AP6210_ERR("%s : failed to allocate wl_pfn_bssid_t array"
+ " (count: %d)",
+ __FUNCTION__, _params->params_hotlist.nbssid);
+ err = BCME_ERROR;
+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE;
+ goto exit;
+ }
+ i = 0;
+ /* convert dhd_pno_bssid to wl_pfn_bssid */
+ list_for_each_entry_safe(iter, next,
+ &_params->params_hotlist.bssid_list, list) {
+ memcpy(&p_pfn_bssid[i].macaddr, &iter->macaddr, ETHER_ADDR_LEN);
+ p_pfn_bssid[i].flags = iter->flags;
+ i++;
+ }
+ err = dhd_pno_set_for_hotlist(dhd, p_pfn_bssid, &_params->params_hotlist);
+ if (err < 0) {
+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE;
+ AP6210_ERR("%s : failed to restart hotlist scan(err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+ } else {
+ err = _dhd_pno_clean(dhd);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to call _dhd_pno_clean (err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+exit:
+ _params = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS];
+ _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_BATCH_MODE);
+ if (p_ssid_list)
+ kfree(p_ssid_list);
+ return err;
+}
+
+int
+dhd_pno_set_for_hotlist(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid,
+ struct dhd_pno_hotlist_params *hotlist_params)
+{
+ int err = BCME_OK;
+ int i;
+ uint16 _chan_list[WL_NUMCHANNELS];
+ int rem_nchan = 0;
+ int tot_nchan = 0;
+ int mode = 0;
+ dhd_pno_params_t *_params;
+ dhd_pno_params_t *_params2;
+ struct dhd_pno_bssid *_pno_bssid;
+ dhd_pno_status_info_t *_pno_state;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ NULL_CHECK(hotlist_params, "hotlist_params is NULL", err);
+ NULL_CHECK(p_pfn_bssid, "p_pfn_bssid is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+
+ if (!dhd_support_sta_mode(dhd)) {
+ err = BCME_BADOPTION;
+ goto exit;
+ }
+ if (!WLS_SUPPORTED(_pno_state)) {
+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__);
+ err = BCME_UNSUPPORTED;
+ goto exit;
+ }
+ _params = &_pno_state->pno_params_arr[INDEX_OF_HOTLIST_PARAMS];
+ if (!(_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE)) {
+ _pno_state->pno_mode |= DHD_PNO_HOTLIST_MODE;
+ err = _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_HOTLIST_MODE);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to call _dhd_pno_reinitialize_prof\n",
+ __FUNCTION__);
+ goto exit;
+ }
+ }
+ _params->params_batch.nchan = hotlist_params->nchan;
+ _params->params_batch.scan_fr = hotlist_params->scan_fr;
+ if (hotlist_params->nchan)
+ memcpy(_params->params_hotlist.chan_list, hotlist_params->chan_list,
+ sizeof(_params->params_hotlist.chan_list));
+ memset(_chan_list, 0, sizeof(_chan_list));
+
+ rem_nchan = ARRAYSIZE(hotlist_params->chan_list) - hotlist_params->nchan;
+ if (hotlist_params->band == WLC_BAND_2G || hotlist_params->band == WLC_BAND_5G) {
+ /* get a valid channel list based on band B or A */
+ err = _dhd_pno_get_channels(dhd,
+ &_params->params_hotlist.chan_list[hotlist_params->nchan],
+ &rem_nchan, hotlist_params->band, FALSE);
+ if (err < 0) {
+ AP6210_ERR("%s: failed to get valid channel list(band : %d)\n",
+ __FUNCTION__, hotlist_params->band);
+ goto exit;
+ }
+ /* now we need to update nchan because rem_chan has valid channel count */
+ _params->params_hotlist.nchan += rem_nchan;
+ /* need to sort channel list */
+ sort(_params->params_hotlist.chan_list, _params->params_hotlist.nchan,
+ sizeof(_params->params_hotlist.chan_list[0]), _dhd_pno_cmpfunc, NULL);
+ }
+#ifdef PNO_DEBUG
+{
+ int i;
+ AP6210_DEBUG("Channel list : ");
+ for (i = 0; i < _params->params_batch.nchan; i++) {
+ AP6210_DEBUG("%d ", _params->params_batch.chan_list[i]);
+ }
+ AP6210_DEBUG("\n");
+}
+#endif
+ if (_params->params_hotlist.nchan) {
+ /* copy the channel list into local array */
+ memcpy(_chan_list, _params->params_hotlist.chan_list,
+ sizeof(_chan_list));
+ tot_nchan = _params->params_hotlist.nchan;
+ }
+ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) {
+ AP6210_DEBUG("PNO SSID is on progress in firmware\n");
+ /* store current pno_mode before disabling pno */
+ mode = _pno_state->pno_mode;
+ err = _dhd_pno_enable(dhd, PNO_OFF);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to disable PNO\n", __FUNCTION__);
+ goto exit;
+ }
+ /* restore the previous mode */
+ _pno_state->pno_mode = mode;
+ /* Use the superset for channelist between two mode */
+ _params2 = &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS]);
+ if (_params2->params_legacy.nchan > 0 &&
+ _params->params_hotlist.nchan > 0) {
+ err = _dhd_pno_chan_merge(_chan_list, &tot_nchan,
+ &_params2->params_legacy.chan_list[0],
+ _params2->params_legacy.nchan,
+ &_params->params_hotlist.chan_list[0],
+ _params->params_hotlist.nchan);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to merge channel list"
+ "between legacy and hotlist\n",
+ __FUNCTION__);
+ goto exit;
+ }
+ }
+
+ }
+
+ INIT_LIST_HEAD(&(_params->params_hotlist.bssid_list));
+
+ err = _dhd_pno_add_bssid(dhd, p_pfn_bssid, hotlist_params->nbssid);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to call _dhd_pno_add_bssid(err :%d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ if ((err = _dhd_pno_set(dhd, _params, DHD_PNO_HOTLIST_MODE)) < 0) {
+ AP6210_ERR("%s : failed to set call pno_set (err %d) in firmware\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ if (tot_nchan > 0) {
+ if ((err = _dhd_pno_cfg(dhd, _chan_list, tot_nchan)) < 0) {
+ AP6210_ERR("%s : failed to set call pno_cfg (err %d) in firmware\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+ for (i = 0; i < hotlist_params->nbssid; i++) {
+ _pno_bssid = kzalloc(sizeof(struct dhd_pno_bssid), GFP_KERNEL);
+ NULL_CHECK(_pno_bssid, "_pfn_bssid is NULL", err);
+ memcpy(&_pno_bssid->macaddr, &p_pfn_bssid[i].macaddr, ETHER_ADDR_LEN);
+ _pno_bssid->flags = p_pfn_bssid[i].flags;
+ list_add_tail(&_pno_bssid->list, &_params->params_hotlist.bssid_list);
+ }
+ _params->params_hotlist.nbssid = hotlist_params->nbssid;
+ if (_pno_state->pno_status == DHD_PNO_DISABLED) {
+ if ((err = _dhd_pno_enable(dhd, PNO_ON)) < 0)
+ AP6210_ERR("%s : failed to enable PNO\n", __FUNCTION__);
+ }
+exit:
+ /* clear mode in case of error */
+ if (err < 0)
+ _pno_state->pno_mode &= ~DHD_PNO_HOTLIST_MODE;
+ return err;
+}
+
+int
+dhd_pno_stop_for_hotlist(dhd_pub_t *dhd)
+{
+ int err = BCME_OK;
+ uint32 mode = 0;
+ dhd_pno_status_info_t *_pno_state;
+ dhd_pno_params_t *_params;
+ wlc_ssid_t *p_ssid_list;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+
+ if (!WLS_SUPPORTED(_pno_state)) {
+ AP6210_ERR("%s : wifi location service is not supported\n",
+ __FUNCTION__);
+ err = BCME_UNSUPPORTED;
+ goto exit;
+ }
+
+ if (!(_pno_state->pno_mode & DHD_PNO_HOTLIST_MODE)) {
+ AP6210_ERR("%s : Hotlist MODE is not enabled\n",
+ __FUNCTION__);
+ goto exit;
+ }
+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE;
+
+ if (_pno_state->pno_mode & (DHD_PNO_LEGACY_MODE | DHD_PNO_BATCH_MODE)) {
+ /* retrieve the batching data from firmware into host */
+ dhd_pno_get_for_batch(dhd, NULL, 0, PNO_STATUS_DISABLE);
+ /* save current pno_mode before calling dhd_pno_clean */
+ mode = _pno_state->pno_mode;
+ err = _dhd_pno_clean(dhd);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to call _dhd_pno_clean (err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ /* restore previos pno mode */
+ _pno_state->pno_mode = mode;
+ if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) {
+ /* restart Legacy PNO Scan */
+ struct dhd_pno_legacy_params *_params_legacy;
+ struct dhd_pno_ssid *iter, *next;
+ _params_legacy =
+ &(_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS].params_legacy);
+ p_ssid_list =
+ kzalloc(sizeof(wlc_ssid_t) * _params_legacy->nssid, GFP_KERNEL);
+ if (p_ssid_list == NULL) {
+ AP6210_ERR("%s : failed to allocate wlc_ssid_t array (count: %d)",
+ __FUNCTION__, _params_legacy->nssid);
+ err = BCME_ERROR;
+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE;
+ goto exit;
+ }
+ /* convert dhd_pno_ssid to dhd_pno_ssid */
+ list_for_each_entry_safe(iter, next, &_params_legacy->ssid_list, list) {
+ p_ssid_list->SSID_len = iter->SSID_len;
+ memcpy(p_ssid_list->SSID, iter->SSID, p_ssid_list->SSID_len);
+ p_ssid_list++;
+ }
+ err = dhd_pno_set_for_ssid(dhd, p_ssid_list, _params_legacy->nssid,
+ _params_legacy->scan_fr, _params_legacy->pno_repeat,
+ _params_legacy->pno_freq_expo_max, _params_legacy->chan_list,
+ _params_legacy->nchan);
+ if (err < 0) {
+ _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE;
+ AP6210_ERR("%s : failed to restart legacy PNO scan(err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ } else if (_pno_state->pno_mode & DHD_PNO_BATCH_MODE) {
+ /* restart Batching Scan */
+ _params = &(_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS]);
+ /* restart BATCH SCAN */
+ err = dhd_pno_set_for_batch(dhd, &_params->params_batch);
+ if (err < 0) {
+ _pno_state->pno_mode &= ~DHD_PNO_BATCH_MODE;
+ AP6210_ERR("%s : failed to restart batch scan(err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+ } else {
+ err = _dhd_pno_clean(dhd);
+ if (err < 0) {
+ AP6210_ERR("%s : failed to call _dhd_pno_clean (err: %d)\n",
+ __FUNCTION__, err);
+ goto exit;
+ }
+ }
+exit:
+ return err;
+}
+
+int
+dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
+{
+ int err = BCME_OK;
+ uint status, event_type, flags, datalen;
+ dhd_pno_status_info_t *_pno_state;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ NULL_CHECK(dhd->pno_state, "pno_state is NULL", err);
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ if (!WLS_SUPPORTED(_pno_state)) {
+ AP6210_ERR("%s : wifi location service is not supported\n", __FUNCTION__);
+ err = BCME_UNSUPPORTED;
+ goto exit;
+ }
+ event_type = ntoh32(event->event_type);
+ flags = ntoh16(event->flags);
+ status = ntoh32(event->status);
+ datalen = ntoh32(event->datalen);
+ AP6210_DEBUG("%s enter : event_type :%d\n", __FUNCTION__, event_type);
+ switch (event_type) {
+ case WLC_E_PFN_BSSID_NET_FOUND:
+ case WLC_E_PFN_BSSID_NET_LOST:
+ /* XXX : how can we inform this to framework ? */
+ /* TODO : need to implement event logic using generic netlink */
+ break;
+ case WLC_E_PFN_BEST_BATCHING:
+ {
+ struct dhd_pno_batch_params *params_batch;
+ params_batch = &_pno_state->pno_params_arr[INDEX_OF_BATCH_PARAMS].params_batch;
+ AP6210_DEBUG("%s : WLC_E_PFN_BEST_BATCHING\n", __FUNCTION__);
+ params_batch->get_batch.buf = NULL;
+ params_batch->get_batch.bufsize = 0;
+ params_batch->get_batch.reason = PNO_STATUS_EVENT;
+ schedule_work(&_pno_state->work);
+ break;
+ }
+ default:
+ AP6210_ERR("unknown event : %d\n", event_type);
+ }
+exit:
+ return err;
+}
+
+int dhd_pno_init(dhd_pub_t *dhd)
+{
+ int err = BCME_OK;
+ dhd_pno_status_info_t *_pno_state;
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ UNUSED_PARAMETER(_dhd_pno_suspend);
+ if (dhd->pno_state)
+ goto exit;
+ dhd->pno_state = MALLOC(dhd->osh, sizeof(dhd_pno_status_info_t));
+ memset(dhd->pno_state, 0, sizeof(dhd_pno_status_info_t));
+ NULL_CHECK(dhd, "failed to create dhd_pno_state", err);
+ /* need to check whether current firmware support batching and hotlist scan */
+ _pno_state = PNO_GET_PNOSTATE(dhd);
+ _pno_state->wls_supported = TRUE;
+ _pno_state->dhd = dhd;
+ mutex_init(&_pno_state->pno_mutex);
+ INIT_WORK(&_pno_state->work, _dhd_pno_get_batch_handler);
+ init_completion(&_pno_state->get_batch_done);
+ err = dhd_iovar(dhd, 0, "pfnlbest", NULL, 0, 0);
+ if (err == BCME_UNSUPPORTED) {
+ _pno_state->wls_supported = FALSE;
+ AP6210_DEBUG("Current firmware doesn't support"
+ " Android Location Service\n");
+ }
+exit:
+ return err;
+}
+int dhd_pno_deinit(dhd_pub_t *dhd)
+{
+ int err = BCME_OK;
+ dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd);
+ NULL_CHECK(dhd, "dhd is NULL", err);
+ AP6210_DEBUG("%s enter\n", __FUNCTION__);
+ cancel_work_sync(&_pno_state->work);
+ if (dhd->pno_state)
+ MFREE(dhd->osh, dhd->pno_state, sizeof(dhd_pno_status_info_t));
+ dhd->pno_state = NULL;
+ return err;
+}
diff --git a/drivers/net/wireless/ap6210/dhd_pno.h b/drivers/net/wireless/ap6210/dhd_pno.h
new file mode 100644
index 0000000..1e02db1
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_pno.h
@@ -0,0 +1,249 @@
+/*
+ * Header file of Broadcom Dongle Host Driver (DHD)
+ * Prefered Network Offload code and Wi-Fi Location Service(WLS) code.
+ * Copyright (C) 1999-2013, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_pno.h 419969 2013-08-23 18:54:36Z $
+ */
+
+#ifndef __DHD_PNO_H__
+#define __DHD_PNO_H__
+
+#define PNO_TLV_PREFIX 'S'
+#define PNO_TLV_VERSION '1'
+#define PNO_TLV_SUBTYPE_LEGACY_PNO '2'
+#define PNO_TLV_RESERVED '0'
+
+#define PNO_BATCHING_SET "SET"
+#define PNO_BATCHING_GET "GET"
+#define PNO_BATCHING_STOP "STOP"
+
+#define PNO_PARAMS_DELIMETER " "
+#define PNO_PARAM_CHANNEL_DELIMETER ","
+#define PNO_PARAM_VALUE_DELLIMETER '='
+#define PNO_PARAM_SCANFREQ "SCANFREQ"
+#define PNO_PARAM_BESTN "BESTN"
+#define PNO_PARAM_MSCAN "MSCAN"
+#define PNO_PARAM_CHANNEL "CHANNEL"
+#define PNO_PARAM_RTT "RTT"
+
+#define PNO_TLV_TYPE_SSID_IE 'S'
+#define PNO_TLV_TYPE_TIME 'T'
+#define PNO_TLV_FREQ_REPEAT 'R'
+#define PNO_TLV_FREQ_EXPO_MAX 'M'
+
+#define MAXNUM_SSID_PER_ADD 16
+#define MAXNUM_PNO_PARAMS 2
+#define PNO_TLV_COMMON_LENGTH 1
+#define DEFAULT_BATCH_MSCAN 16
+
+#define RESULTS_END_MARKER "----\n"
+#define SCAN_END_MARKER "####\n"
+#define AP_END_MARKER "====\n"
+
+enum scan_status {
+ /* SCAN ABORT by other scan */
+ PNO_STATUS_ABORT,
+ /* RTT is presence or not */
+ PNO_STATUS_RTT_PRESENCE,
+ /* Disable PNO by Driver */
+ PNO_STATUS_DISABLE,
+ /* NORMAL BATCHING GET */
+ PNO_STATUS_NORMAL,
+ /* WLC_E_PFN_BEST_BATCHING */
+ PNO_STATUS_EVENT,
+ PNO_STATUS_MAX
+};
+#define PNO_STATUS_ABORT_MASK 0x0001
+#define PNO_STATUS_RTT_MASK 0x0002
+#define PNO_STATUS_DISABLE_MASK 0x0004
+#define PNO_STATUS_OOM_MASK 0x0010
+
+enum index_mode {
+ INDEX_OF_LEGACY_PARAMS,
+ INDEX_OF_BATCH_PARAMS,
+ INDEX_OF_HOTLIST_PARAMS,
+ INDEX_MODE_MAX
+};
+enum dhd_pno_status {
+ DHD_PNO_DISABLED,
+ DHD_PNO_ENABLED,
+ DHD_PNO_SUSPEND
+};
+typedef struct cmd_tlv {
+ char prefix;
+ char version;
+ char subtype;
+ char reserved;
+} cmd_tlv_t;
+typedef enum dhd_pno_mode {
+ /* Wi-Fi Legacy PNO Mode */
+ DHD_PNO_NONE_MODE = 0,
+ DHD_PNO_LEGACY_MODE = (1 << (0)),
+ /* Wi-Fi Android BATCH SCAN Mode */
+ DHD_PNO_BATCH_MODE = (1 << (1)),
+ /* Wi-Fi Android Hotlist SCAN Mode */
+ DHD_PNO_HOTLIST_MODE = (1 << (2))
+} dhd_pno_mode_t;
+struct dhd_pno_ssid {
+ uint32 SSID_len;
+ uchar SSID[DOT11_MAX_SSID_LEN];
+ struct list_head list;
+};
+struct dhd_pno_bssid {
+ struct ether_addr macaddr;
+ /* Bit4: suppress_lost, Bit3: suppress_found */
+ uint16 flags;
+ struct list_head list;
+};
+typedef struct dhd_pno_bestnet_entry {
+ struct ether_addr BSSID;
+ uint8 SSID_len;
+ uint8 SSID[DOT11_MAX_SSID_LEN];
+ int8 RSSI;
+ uint8 channel;
+ uint32 timestamp;
+ uint16 rtt0; /* distance_cm based on RTT */
+ uint16 rtt1; /* distance_cm based on sample standard deviation */
+ unsigned long recorded_time;
+ struct list_head list;
+} dhd_pno_bestnet_entry_t;
+#define BESTNET_ENTRY_SIZE (sizeof(dhd_pno_bestnet_entry_t))
+
+typedef struct dhd_pno_bestnet_header {
+ struct dhd_pno_bestnet_header *next;
+ uint8 reason;
+ uint32 tot_cnt;
+ uint32 tot_size;
+ struct list_head entry_list;
+} dhd_pno_best_header_t;
+#define BEST_HEADER_SIZE (sizeof(dhd_pno_best_header_t))
+
+typedef struct dhd_pno_scan_results {
+ dhd_pno_best_header_t *bestnetheader;
+ uint8 cnt_header;
+ struct list_head list;
+} dhd_pno_scan_results_t;
+#define SCAN_RESULTS_SIZE (sizeof(dhd_pno_scan_results_t))
+
+struct dhd_pno_get_batch_info {
+ /* info related to get batch */
+ char *buf;
+ bool batch_started;
+ uint32 tot_scan_cnt;
+ uint32 expired_tot_scan_cnt;
+ uint32 top_node_cnt;
+ uint32 bufsize;
+ int reason;
+ struct list_head scan_results_list;
+ struct list_head expired_scan_results_list;
+};
+struct dhd_pno_legacy_params {
+ uint16 scan_fr;
+ uint16 chan_list[WL_NUMCHANNELS];
+ uint16 nchan;
+ int pno_repeat;
+ int pno_freq_expo_max;
+ int nssid;
+ struct list_head ssid_list;
+};
+struct dhd_pno_batch_params {
+ int32 scan_fr;
+ uint8 bestn;
+ uint8 mscan;
+ uint8 band;
+ uint16 chan_list[WL_NUMCHANNELS];
+ uint16 nchan;
+ uint16 rtt;
+ struct dhd_pno_get_batch_info get_batch;
+};
+struct dhd_pno_hotlist_params {
+ uint8 band;
+ int32 scan_fr;
+ uint16 chan_list[WL_NUMCHANNELS];
+ uint16 nchan;
+ uint16 nbssid;
+ struct list_head bssid_list;
+};
+typedef union dhd_pno_params {
+ struct dhd_pno_legacy_params params_legacy;
+ struct dhd_pno_batch_params params_batch;
+ struct dhd_pno_hotlist_params params_hotlist;
+} dhd_pno_params_t;
+typedef struct dhd_pno_status_info {
+ dhd_pub_t *dhd;
+ struct work_struct work;
+ struct mutex pno_mutex;
+ struct completion get_batch_done;
+ bool wls_supported; /* wifi location service supported or not */
+ enum dhd_pno_status pno_status;
+ enum dhd_pno_mode pno_mode;
+ dhd_pno_params_t pno_params_arr[INDEX_MODE_MAX];
+ struct list_head head_list;
+} dhd_pno_status_info_t;
+
+/* wrapper functions */
+extern int
+dhd_dev_pno_enable(struct net_device *dev, int enable);
+
+extern int
+dhd_dev_pno_stop_for_ssid(struct net_device *dev);
+
+extern int
+dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_t* ssids_local, int nssid,
+ uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan);
+
+extern int
+dhd_dev_pno_set_for_batch(struct net_device *dev,
+ struct dhd_pno_batch_params *batch_params);
+
+extern int
+dhd_dev_pno_get_for_batch(struct net_device *dev, char *buf, int bufsize);
+
+extern int
+dhd_dev_pno_stop_for_batch(struct net_device *dev);
+
+extern int
+dhd_dev_pno_set_for_hotlist(struct net_device *dev, wl_pfn_bssid_t *p_pfn_bssid,
+ struct dhd_pno_hotlist_params *hotlist_params);
+
+/* dhd pno fuctions */
+extern int dhd_pno_stop_for_ssid(dhd_pub_t *dhd);
+extern int dhd_pno_enable(dhd_pub_t *dhd, int enable);
+extern int dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_t* ssid_list, int nssid,
+ uint16 scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan);
+
+extern int dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params);
+
+extern int dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason);
+
+
+extern int dhd_pno_stop_for_batch(dhd_pub_t *dhd);
+
+extern int dhd_pno_set_for_hotlist(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid,
+ struct dhd_pno_hotlist_params *hotlist_params);
+
+extern int dhd_pno_stop_for_hotlist(dhd_pub_t *dhd);
+
+extern int dhd_pno_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data);
+extern int dhd_pno_init(dhd_pub_t *dhd);
+extern int dhd_pno_deinit(dhd_pub_t *dhd);
+#endif /* __DHD_PNO_H__ */
diff --git a/drivers/net/wireless/ap6210/dhd_proto.h b/drivers/net/wireless/ap6210/dhd_proto.h
new file mode 100644
index 0000000..09d5468
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_proto.h
@@ -0,0 +1,113 @@
+/*
+ * Header file describing the internal (inter-module) DHD interfaces.
+ *
+ * Provides type definitions and function prototypes used to link the
+ * DHD OS, bus, and protocol modules.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_proto.h 343390 2012-07-06 22:34:19Z $
+ */
+
+#ifndef _dhd_proto_h_
+#define _dhd_proto_h_
+
+#include <dhdioctl.h>
+#include <wlioctl.h>
+
+#ifndef IOCTL_RESP_TIMEOUT
+#define IOCTL_RESP_TIMEOUT 2000 /* In milli second default value for Production FW */
+#endif /* IOCTL_RESP_TIMEOUT */
+
+/*
+ * Exported from the dhd protocol module (dhd_cdc, dhd_rndis)
+ */
+
+/* Linkage, sets prot link and updates hdrlen in pub */
+extern int dhd_prot_attach(dhd_pub_t *dhdp);
+
+/* Unlink, frees allocated protocol memory (including dhd_prot) */
+extern void dhd_prot_detach(dhd_pub_t *dhdp);
+
+/* Initialize protocol: sync w/dongle state.
+ * Sets dongle media info (iswl, drv_version, mac address).
+ */
+extern int dhd_prot_init(dhd_pub_t *dhdp);
+
+/* Stop protocol: sync w/dongle state. */
+extern void dhd_prot_stop(dhd_pub_t *dhdp);
+#ifdef PROP_TXSTATUS
+extern int dhd_wlfc_init(dhd_pub_t *dhd);
+extern void dhd_wlfc_deinit(dhd_pub_t *dhd);
+#endif /* PROP_TXSTATUS */
+
+/* Add any protocol-specific data header.
+ * Caller must reserve prot_hdrlen prepend space.
+ */
+extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, void *txp);
+
+/* Remove any protocol-specific data header. */
+extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp, uchar *buf, uint *len);
+
+/* Use protocol to issue ioctl to dongle */
+extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len);
+
+/* Handles a protocol control response asynchronously */
+extern int dhd_prot_ctl_complete(dhd_pub_t *dhd);
+
+/* Check for and handle local prot-specific iovar commands */
+extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
+ void *params, int plen, void *arg, int len, bool set);
+
+/* Add prot dump output to a buffer */
+extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+
+/* Update local copy of dongle statistics */
+extern void dhd_prot_dstats(dhd_pub_t *dhdp);
+
+extern int dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen);
+
+extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
+
+#ifdef PROP_TXSTATUS
+extern int dhd_wlfc_enque_sendq(void* state, int prec, void* p);
+extern int dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx);
+extern void dhd_wlfc_cleanup(dhd_pub_t *dhd);
+#endif /* PROP_TXSTATUS */
+
+extern int dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf,
+ uint reorder_info_len, void **pkt, uint32 *free_buf_count);
+
+
+/********************************
+ * For version-string expansion *
+ */
+#if defined(BDC)
+#define DHD_PROTOCOL "bdc"
+#elif defined(CDC)
+#define DHD_PROTOCOL "cdc"
+#elif defined(RNDIS)
+#define DHD_PROTOCOL "rndis"
+#else
+#define DHD_PROTOCOL "unknown"
+#endif /* proto */
+
+#endif /* _dhd_proto_h_ */
diff --git a/drivers/net/wireless/ap6210/dhd_sdio.c b/drivers/net/wireless/ap6210/dhd_sdio.c
new file mode 100644
index 0000000..786f287
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_sdio.c
@@ -0,0 +1,7856 @@
+/*
+ * DHD Bus Module for SDIO
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_sdio.c 373330 2012-12-07 04:46:17Z $
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmsdh.h>
+
+#ifdef BCMEMBEDIMAGE
+#include BCMEMBEDIMAGE
+#endif /* BCMEMBEDIMAGE */
+
+#include <bcmdefs.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+
+#include <siutils.h>
+#include <hndpmu.h>
+#include <hndsoc.h>
+#include <bcmsdpcm.h>
+#if defined(DHD_DEBUG)
+#include <hndrte_armtrap.h>
+#include <hndrte_cons.h>
+#endif /* defined(DHD_DEBUG) */
+#include <sbchipc.h>
+#include <sbhnddma.h>
+
+#include <sdio.h>
+#include <sbsdio.h>
+#include <sbsdpcmdev.h>
+#include <bcmsdpcm.h>
+#include <bcmsdbus.h>
+
+#include <proto/ethernet.h>
+#include <proto/802.1d.h>
+#include <proto/802.11.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <dhd_dbg.h>
+#include <dhdioctl.h>
+#include <sdiovar.h>
+
+#include <ap6210.h>
+
+#ifndef DHDSDIO_MEM_DUMP_FNAME
+#define DHDSDIO_MEM_DUMP_FNAME "mem_dump"
+#endif
+
+#define QLEN 256 /* bulk rx and tx queue lengths */
+#define FCHI (QLEN - 10)
+#define FCLOW (FCHI / 2)
+#define PRIOMASK 7
+
+#define TXRETRIES 2 /* # of retries for tx frames */
+
+#define DHD_RXBOUND 50 /* Default for max rx frames in one scheduling */
+
+#define DHD_TXBOUND 20 /* Default for max tx frames in one scheduling */
+
+#define DHD_TXMINMAX 1 /* Max tx frames if rx still pending */
+
+#define MEMBLOCK 2048 /* Block size used for downloading of dongle image */
+#define MAX_NVRAMBUF_SIZE 4096 /* max nvram buf size */
+#define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold biggest possible glom */
+
+#ifndef DHD_FIRSTREAD
+#define DHD_FIRSTREAD 32
+#endif
+#if !ISPOWEROF2(DHD_FIRSTREAD)
+#error DHD_FIRSTREAD is not a power of 2!
+#endif
+
+#ifdef BCMSDIOH_TXGLOM
+/* Total length of TX frame header for dongle protocol */
+#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN + SDPCM_SWHEADER_LEN)
+/* Total length of RX frame for dongle protocol */
+#else
+/* Total length of TX frame header for dongle protocol */
+#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
+#endif
+
+#define SDPCM_HDRLEN_RX (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
+
+#ifdef SDTEST
+#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN)
+#else
+#define SDPCM_RESERVE (SDPCM_HDRLEN + DHD_SDALIGN)
+#endif
+
+/* Space for header read, limit for data packets */
+#ifndef MAX_HDR_READ
+#define MAX_HDR_READ 32
+#endif
+#if !ISPOWEROF2(MAX_HDR_READ)
+#error MAX_HDR_READ is not a power of 2!
+#endif
+
+#define MAX_RX_DATASZ 2048
+
+/* Maximum milliseconds to wait for F2 to come up */
+#define DHD_WAIT_F2RDY 3000
+
+/* Bump up limit on waiting for HT to account for first startup;
+ * if the image is doing a CRC calculation before programming the PMU
+ * for HT availability, it could take a couple hundred ms more, so
+ * max out at a 1 second (1000000us).
+ */
+#if (PMU_MAX_TRANSITION_DLY <= 1000000)
+#undef PMU_MAX_TRANSITION_DLY
+#define PMU_MAX_TRANSITION_DLY 1000000
+#endif
+
+/* Value for ChipClockCSR during initial setup */
+#define DHD_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ)
+#define DHD_INIT_CLKCTL2 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP)
+
+/* Flags for SDH calls */
+#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
+
+/* Packet free applicable unconditionally for sdio and sdspi. Conditional if
+ * bufpool was present for gspi bus.
+ */
+#define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \
+ PKTFREE(bus->dhd->osh, pkt, FALSE);
+DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep);
+#if defined(OOB_INTR_ONLY)
+extern void bcmsdh_set_irq(int flag);
+#endif
+#ifdef PROP_TXSTATUS
+extern void dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success, bool wlfc_locked);
+extern void dhd_wlfc_trigger_pktcommit(dhd_pub_t *dhd);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+DEFINE_MUTEX(_dhd_sdio_mutex_lock_);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
+
+#ifdef DHD_DEBUG
+/* Device console log buffer state */
+#define CONSOLE_LINE_MAX 192
+#define CONSOLE_BUFFER_MAX 2024
+typedef struct dhd_console {
+ uint count; /* Poll interval msec counter */
+ uint log_addr; /* Log struct address (fixed) */
+ hndrte_log_t log; /* Log struct (host copy) */
+ uint bufsize; /* Size of log buffer */
+ uint8 *buf; /* Log buffer (host copy) */
+ uint last; /* Last buffer read index */
+} dhd_console_t;
+#endif /* DHD_DEBUG */
+
+#define REMAP_ENAB(bus) ((bus)->remap)
+#define REMAP_ISADDR(bus, a) (((a) >= ((bus)->orig_ramsize)) && ((a) < ((bus)->ramsize)))
+#define KSO_ENAB(bus) ((bus)->kso)
+#define SR_ENAB(bus) ((bus)->_srenab)
+#define SLPAUTO_ENAB(bus) ((SR_ENAB(bus)) && ((bus)->_slpauto))
+#define MIN_RSRC_ADDR (SI_ENUM_BASE + 0x618)
+#define MIN_RSRC_SR 0x3
+#define CORE_CAPEXT_ADDR (SI_ENUM_BASE + 0x64c)
+#define CORE_CAPEXT_SR_SUPPORTED_MASK (1 << 1)
+#define RCTL_MACPHY_DISABLE_MASK (1 << 26)
+#define RCTL_LOGIC_DISABLE_MASK (1 << 27)
+
+#define OOB_WAKEUP_ENAB(bus) ((bus)->_oobwakeup)
+#define GPIO_DEV_SRSTATE 16 /* Host gpio17 mapped to device gpio0 SR state */
+#define GPIO_DEV_SRSTATE_TIMEOUT 320000 /* 320ms */
+#define GPIO_DEV_WAKEUP 17 /* Host gpio17 mapped to device gpio1 wakeup */
+#define CC_CHIPCTRL2_GPIO1_WAKEUP (1 << 0)
+
+#define CC_PMUCC3 (0x3)
+/* Private data for SDIO bus interaction */
+typedef struct dhd_bus {
+ dhd_pub_t *dhd;
+
+ bcmsdh_info_t *sdh; /* Handle for BCMSDH calls */
+ si_t *sih; /* Handle for SI calls */
+ char *vars; /* Variables (from CIS and/or other) */
+ uint varsz; /* Size of variables buffer */
+ uint32 sbaddr; /* Current SB window pointer (-1, invalid) */
+
+ sdpcmd_regs_t *regs; /* Registers for SDIO core */
+ uint sdpcmrev; /* SDIO core revision */
+ uint armrev; /* CPU core revision */
+ uint ramrev; /* SOCRAM core revision */
+ uint32 ramsize; /* Size of RAM in SOCRAM (bytes) */
+ uint32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */
+ uint32 srmemsize; /* Size of SRMEM */
+
+ uint32 bus; /* gSPI or SDIO bus */
+ uint32 hostintmask; /* Copy of Host Interrupt Mask */
+ uint32 intstatus; /* Intstatus bits (events) pending */
+ bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */
+ bool fcstate; /* State of dongle flow-control */
+
+ uint16 cl_devid; /* cached devid for dhdsdio_probe_attach() */
+ char *fw_path; /* module_param: path to firmware image */
+ char *nv_path; /* module_param: path to nvram vars file */
+ const char *nvram_params; /* user specified nvram params. */
+
+ uint blocksize; /* Block size of SDIO transfers */
+ uint roundup; /* Max roundup limit */
+
+ struct pktq txq; /* Queue length used for flow-control */
+ uint8 flowcontrol; /* per prio flow control bitmask */
+ uint8 tx_seq; /* Transmit sequence number (next) */
+ uint8 tx_max; /* Maximum transmit sequence allowed */
+
+ uint8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN];
+ uint8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
+ uint16 nextlen; /* Next Read Len from last header */
+ uint8 rx_seq; /* Receive sequence number (expected) */
+ bool rxskip; /* Skip receive (awaiting NAK ACK) */
+
+ void *glomd; /* Packet containing glomming descriptor */
+ void *glom; /* Packet chain for glommed superframe */
+ uint glomerr; /* Glom packet read errors */
+
+ uint8 *rxbuf; /* Buffer for receiving control packets */
+ uint rxblen; /* Allocated length of rxbuf */
+ uint8 *rxctl; /* Aligned pointer into rxbuf */
+ uint8 *databuf; /* Buffer for receiving big glom packet */
+ uint8 *dataptr; /* Aligned pointer into databuf */
+ uint rxlen; /* Length of valid data in buffer */
+
+ uint8 sdpcm_ver; /* Bus protocol reported by dongle */
+
+ bool intr; /* Use interrupts */
+ bool poll; /* Use polling */
+ bool ipend; /* Device interrupt is pending */
+ bool intdis; /* Interrupts disabled by isr */
+ uint intrcount; /* Count of device interrupt callbacks */
+ uint lastintrs; /* Count as of last watchdog timer */
+ uint spurious; /* Count of spurious interrupts */
+ uint pollrate; /* Ticks between device polls */
+ uint polltick; /* Tick counter */
+ uint pollcnt; /* Count of active polls */
+
+#ifdef DHD_DEBUG
+ dhd_console_t console; /* Console output polling support */
+ uint console_addr; /* Console address from shared struct */
+#endif /* DHD_DEBUG */
+
+ uint regfails; /* Count of R_REG/W_REG failures */
+
+ uint clkstate; /* State of sd and backplane clock(s) */
+ bool activity; /* Activity flag for clock down */
+ int32 idletime; /* Control for activity timeout */
+ int32 idlecount; /* Activity timeout counter */
+ int32 idleclock; /* How to set bus driver when idle */
+ int32 sd_divisor; /* Speed control to bus driver */
+ int32 sd_mode; /* Mode control to bus driver */
+ int32 sd_rxchain; /* If bcmsdh api accepts PKT chains */
+ bool use_rxchain; /* If dhd should use PKT chains */
+ bool sleeping; /* Is SDIO bus sleeping? */
+ uint rxflow_mode; /* Rx flow control mode */
+ bool rxflow; /* Is rx flow control on */
+ uint prev_rxlim_hit; /* Is prev rx limit exceeded (per dpc schedule) */
+ bool alp_only; /* Don't use HT clock (ALP only) */
+ /* Field to decide if rx of control frames happen in rxbuf or lb-pool */
+ bool usebufpool;
+
+#ifdef SDTEST
+ /* external loopback */
+ bool ext_loop;
+ uint8 loopid;
+
+ /* pktgen configuration */
+ uint pktgen_freq; /* Ticks between bursts */
+ uint pktgen_count; /* Packets to send each burst */
+ uint pktgen_print; /* Bursts between count displays */
+ uint pktgen_total; /* Stop after this many */
+ uint pktgen_minlen; /* Minimum packet data len */
+ uint pktgen_maxlen; /* Maximum packet data len */
+ uint pktgen_mode; /* Configured mode: tx, rx, or echo */
+ uint pktgen_stop; /* Number of tx failures causing stop */
+
+ /* active pktgen fields */
+ uint pktgen_tick; /* Tick counter for bursts */
+ uint pktgen_ptick; /* Burst counter for printing */
+ uint pktgen_sent; /* Number of test packets generated */
+ uint pktgen_rcvd; /* Number of test packets received */
+ uint pktgen_prev_time; /* Time at which previous stats where printed */
+ uint pktgen_prev_sent; /* Number of test packets generated when
+ * previous stats were printed
+ */
+ uint pktgen_prev_rcvd; /* Number of test packets received when
+ * previous stats were printed
+ */
+ uint pktgen_fail; /* Number of failed send attempts */
+ uint16 pktgen_len; /* Length of next packet to send */
+#define PKTGEN_RCV_IDLE (0)
+#define PKTGEN_RCV_ONGOING (1)
+ uint16 pktgen_rcv_state; /* receive state */
+ uint pktgen_rcvd_rcvsession; /* test pkts rcvd per rcv session. */
+#endif /* SDTEST */
+
+ /* Some additional counters */
+ uint tx_sderrs; /* Count of tx attempts with sd errors */
+ uint fcqueued; /* Tx packets that got queued */
+ uint rxrtx; /* Count of rtx requests (NAK to dongle) */
+ uint rx_toolong; /* Receive frames too long to receive */
+ uint rxc_errors; /* SDIO errors when reading control frames */
+ uint rx_hdrfail; /* SDIO errors on header reads */
+ uint rx_badhdr; /* Bad received headers (roosync?) */
+ uint rx_badseq; /* Mismatched rx sequence number */
+ uint fc_rcvd; /* Number of flow-control events received */
+ uint fc_xoff; /* Number which turned on flow-control */
+ uint fc_xon; /* Number which turned off flow-control */
+ uint rxglomfail; /* Failed deglom attempts */
+ uint rxglomframes; /* Number of glom frames (superframes) */
+ uint rxglompkts; /* Number of packets from glom frames */
+ uint f2rxhdrs; /* Number of header reads */
+ uint f2rxdata; /* Number of frame data reads */
+ uint f2txdata; /* Number of f2 frame writes */
+ uint f1regdata; /* Number of f1 register accesses */
+
+ uint8 *ctrl_frame_buf;
+ uint32 ctrl_frame_len;
+ bool ctrl_frame_stat;
+ uint32 rxint_mode; /* rx interrupt mode */
+ bool remap; /* Contiguous 1MB RAM: 512K socram + 512K devram
+ * Available with socram rev 16
+ * Remap region not DMA-able
+ */
+ bool kso;
+ bool _slpauto;
+ bool _oobwakeup;
+ bool _srenab;
+ bool readframes;
+ bool reqbussleep;
+ uint32 resetinstr;
+ uint32 dongle_ram_base;
+#ifdef BCMSDIOH_TXGLOM
+ void *glom_pkt_arr[SDPCM_MAXGLOM_SIZE]; /* Array of pkts for glomming */
+ uint16 glom_cnt; /* Number of pkts in the glom array */
+ uint16 glom_total_len; /* Total length of pkts in glom array */
+ bool glom_enable; /* Flag to indicate whether tx glom is enabled/disabled */
+ uint8 glom_mode; /* Glom mode - 0-copy mode, 1 - Multi-descriptor mode */
+ uint32 glomsize; /* Glom size limitation */
+#endif
+} dhd_bus_t;
+
+/* clkstate */
+#define CLK_NONE 0
+#define CLK_SDONLY 1
+#define CLK_PENDING 2 /* Not used yet */
+#define CLK_AVAIL 3
+
+#define DHD_NOPMU(dhd) (FALSE)
+
+#ifdef DHD_DEBUG
+static int qcount[NUMPRIO];
+static int tx_packets[NUMPRIO];
+#endif /* DHD_DEBUG */
+
+/* Deferred transmit */
+const uint dhd_deferred_tx = 1;
+
+extern uint dhd_watchdog_ms;
+extern void dhd_os_wd_timer(void *bus, uint wdtick);
+
+/* Tx/Rx bounds */
+uint dhd_txbound;
+uint dhd_rxbound;
+uint dhd_txminmax = DHD_TXMINMAX;
+
+/* override the RAM size if possible */
+#define DONGLE_MIN_MEMSIZE (128 *1024)
+int dhd_dongle_memsize;
+
+static bool dhd_doflow;
+static bool dhd_alignctl;
+
+static bool sd1idle;
+
+static bool retrydata;
+#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata)
+
+#if defined(SDIO_CRC_ERROR_FIX)
+static uint watermark = 48;
+static uint mesbusyctrl = 80;
+#else
+static const uint watermark = 8;
+static const uint mesbusyctrl = 0;
+#endif
+static const uint firstread = DHD_FIRSTREAD;
+
+#define HDATLEN (firstread - (SDPCM_HDRLEN))
+
+/* Retry count for register access failures */
+static const uint retry_limit = 2;
+
+/* Force even SD lengths (some host controllers mess up on odd bytes) */
+static bool forcealign;
+
+#define FW_TYPE_STA 0
+#define FW_TYPE_APSTA 1
+#define FW_TYPE_P2P 2
+#define FW_TYPE_MFG 3
+#define FW_TYPE_G 0
+#define FW_TYPE_AG 1
+
+const static char *bcm40183b2_fw_name[] = {
+ "fw_bcm40183b2.bin",
+ "fw_bcm40183b2_apsta.bin",
+ "fw_bcm40183b2_p2p.bin",
+ "fw_bcm40183b2_mfg.bin"
+};
+
+const static char *bcm40183b2ag_fw_name[] = {
+ "fw_bcm40183b2_ag.bin",
+ "fw_bcm40183b2_ag_apsta.bin",
+ "fw_bcm40183b2_ag_p2p.bin",
+ "fw_bcm40183b2_ag_mfg.bin"
+};
+
+const static char *bcm40181a0_fw_name[] = {
+ "fw_bcm40181a0.bin",
+ "fw_bcm40181a0_apsta.bin",
+ "fw_bcm40181a0_p2p.bin",
+ "fw_bcm40181a0_mfg.bin"
+};
+
+const static char *bcm40181a2_fw_name[] = {
+ "fw_bcm40181a2.bin",
+ "fw_bcm40181a2_apsta.bin",
+ "fw_bcm40181a2_p2p.bin",
+ "fw_bcm40181a2_mfg.bin"
+};
+
+const static char *bcm43341b0ag_fw_name[] = {
+ "fw_bcm43341b0_ag.bin",
+ "fw_bcm43341b0_ag_apsta.bin",
+ "fw_bcm43341b0_ag_p2p.bin",
+ "fw_bcm43341b0_ag_mfg.bin"
+};
+
+const static char *bcm43241b4ag_fw_name[] = {
+ "fw_bcm43241b4_ag.bin",
+ "fw_bcm43241b4_ag_apsta.bin",
+ "fw_bcm43241b4_ag_p2p.bin",
+ "fw_bcm43241b4_ag_mfg.bin"
+};
+
+#define BCM4330B2_CHIP_REV 4
+#define BCM43362A0_CHIP_REV 0
+#define BCM43362A2_CHIP_REV 1
+#define BCM43341B0_CHIP_REV 2
+#define BCM43241B4_CHIP_REV 5
+
+#define ALIGNMENT 4
+
+#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable);
+#endif
+
+#if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD)
+#error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD
+#endif /* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */
+#define PKTALIGN(osh, p, len, align) \
+ do { \
+ uint datalign; \
+ datalign = (uintptr)PKTDATA((osh), (p)); \
+ datalign = ROUNDUP(datalign, (align)) - datalign; \
+ ASSERT(datalign < (align)); \
+ ASSERT(PKTLEN((osh), (p)) >= ((len) + datalign)); \
+ if (datalign) \
+ PKTPULL((osh), (p), datalign); \
+ PKTSETLEN((osh), (p), (len)); \
+ } while (0)
+
+/* Limit on rounding up frames */
+static const uint max_roundup = 512;
+
+/* Try doing readahead */
+static bool dhd_readahead;
+
+
+/* To check if there's window offered */
+#define DATAOK(bus) \
+ (((uint8)(bus->tx_max - bus->tx_seq) > 1) && \
+ (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
+
+/* To check if there's window offered for ctrl frame */
+#define TXCTLOK(bus) \
+ (((uint8)(bus->tx_max - bus->tx_seq) != 0) && \
+ (((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
+
+/* Number of pkts available in dongle for data RX */
+#define DATABUFCNT(bus) \
+ ((uint8)(bus->tx_max - bus->tx_seq) - 1)
+
+/* Macros to get register read/write status */
+/* NOTE: these assume a local dhdsdio_bus_t *bus! */
+#define R_SDREG(regvar, regaddr, retryvar) \
+do { \
+ retryvar = 0; \
+ do { \
+ regvar = R_REG(bus->dhd->osh, regaddr); \
+ } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \
+ if (retryvar) { \
+ bus->regfails += (retryvar-1); \
+ if (retryvar > retry_limit) { \
+ AP6210_ERR("%s: FAILED" #regvar "READ, LINE %d\n", \
+ __FUNCTION__, __LINE__); \
+ regvar = 0; \
+ } \
+ } \
+} while (0)
+
+#define W_SDREG(regval, regaddr, retryvar) \
+do { \
+ retryvar = 0; \
+ do { \
+ W_REG(bus->dhd->osh, regaddr, regval); \
+ } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \
+ if (retryvar) { \
+ bus->regfails += (retryvar-1); \
+ if (retryvar > retry_limit) \
+ AP6210_ERR("%s: FAILED REGISTER WRITE, LINE %d\n", \
+ __FUNCTION__, __LINE__); \
+ } \
+} while (0)
+
+#define BUS_WAKE(bus) \
+ do { \
+ bus->idlecount = 0; \
+ if ((bus)->sleeping) \
+ dhdsdio_bussleep((bus), FALSE); \
+ } while (0);
+
+/*
+ * pktavail interrupts from dongle to host can be managed in 3 different ways
+ * whenever there is a packet available in dongle to transmit to host.
+ *
+ * Mode 0: Dongle writes the software host mailbox and host is interrupted.
+ * Mode 1: (sdiod core rev >= 4)
+ * Device sets a new bit in the intstatus whenever there is a packet
+ * available in fifo. Host can't clear this specific status bit until all the
+ * packets are read from the FIFO. No need to ack dongle intstatus.
+ * Mode 2: (sdiod core rev >= 4)
+ * Device sets a bit in the intstatus, and host acks this by writing
+ * one to this bit. Dongle won't generate anymore packet interrupts
+ * until host reads all the packets from the dongle and reads a zero to
+ * figure that there are no more packets. No need to disable host ints.
+ * Need to ack the intstatus.
+ */
+
+#define SDIO_DEVICE_HMB_RXINT 0 /* default old way */
+#define SDIO_DEVICE_RXDATAINT_MODE_0 1 /* from sdiod rev 4 */
+#define SDIO_DEVICE_RXDATAINT_MODE_1 2 /* from sdiod rev 4 */
+
+
+#define FRAME_AVAIL_MASK(bus) \
+ ((bus->rxint_mode == SDIO_DEVICE_HMB_RXINT) ? I_HMB_FRAME_IND : I_XMTDATA_AVAIL)
+
+#define DHD_BUS SDIO_BUS
+
+#define PKT_AVAILABLE(bus, intstatus) ((intstatus) & (FRAME_AVAIL_MASK(bus)))
+
+#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
+
+#define GSPI_PR55150_BAILOUT
+
+#ifdef SDTEST
+static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq);
+static void dhdsdio_sdtest_set(dhd_bus_t *bus, uint count);
+#endif
+
+#ifdef DHD_DEBUG
+static int dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size);
+static int dhd_serialconsole(dhd_bus_t *bus, bool get, bool enable, int *bcmerror);
+#endif /* DHD_DEBUG */
+
+static int dhdsdio_devcap_set(dhd_bus_t *bus, uint8 cap);
+static int dhdsdio_download_state(dhd_bus_t *bus, bool enter);
+
+static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh);
+static void dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh);
+static void dhdsdio_disconnect(void *ptr);
+static bool dhdsdio_chipmatch(uint16 chipid);
+static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh,
+ void * regsva, uint16 devid);
+static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh);
+static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh);
+static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation,
+ bool reset_flag);
+
+static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size);
+static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags,
+ uint8 *buf, uint nbytes,
+ void *pkt, bcmsdh_cmplt_fn_t complete, void *handle);
+static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags,
+ uint8 *buf, uint nbytes,
+ void *pkt, bcmsdh_cmplt_fn_t complete, void *handle);
+#ifdef BCMSDIOH_TXGLOM
+static void dhd_bcmsdh_glom_post(dhd_bus_t *bus, uint8 *frame, uint len);
+static void dhd_bcmsdh_glom_clear(dhd_bus_t *bus);
+#endif
+
+static bool dhdsdio_download_firmware(dhd_bus_t *bus, osl_t *osh, void *sdh);
+static int _dhdsdio_download_firmware(dhd_bus_t *bus);
+
+static int dhdsdio_download_code_file(dhd_bus_t *bus, char *image_path);
+static int dhdsdio_download_nvram(dhd_bus_t *bus);
+#ifdef BCMEMBEDIMAGE
+static int dhdsdio_download_code_array(dhd_bus_t *bus);
+#endif
+static int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep);
+static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok);
+static uint8 dhdsdio_sleepcsr_get(dhd_bus_t *bus);
+
+#ifdef WLMEDIA_HTSF
+#include <htsf.h>
+extern uint32 dhd_get_htsf(void *dhd, int ifidx);
+#endif /* WLMEDIA_HTSF */
+
+static void
+dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size)
+{
+ int32 min_size = DONGLE_MIN_MEMSIZE;
+ /* Restrict the memsize to user specified limit */
+ AP6210_DEBUG("user: Restrict the dongle ram size to %d, min accepted %d\n",
+ dhd_dongle_memsize, min_size);
+ if ((dhd_dongle_memsize > min_size) &&
+ (dhd_dongle_memsize < (int32)bus->orig_ramsize))
+ bus->ramsize = dhd_dongle_memsize;
+}
+
+static int
+dhdsdio_set_siaddr_window(dhd_bus_t *bus, uint32 address)
+{
+ int err = 0;
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
+ (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
+ if (!err)
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
+ (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
+ if (!err)
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
+ (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err);
+ return err;
+}
+
+
+#ifdef USE_OOB_GPIO1
+static int
+dhdsdio_oobwakeup_init(dhd_bus_t *bus)
+{
+ uint32 val, addr, data;
+
+ bcmsdh_gpioouten(bus->sdh, GPIO_DEV_WAKEUP);
+
+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr);
+ data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data);
+
+ /* Set device for gpio1 wakeup */
+ bcmsdh_reg_write(bus->sdh, addr, 4, 2);
+ val = bcmsdh_reg_read(bus->sdh, data, 4);
+ val |= CC_CHIPCTRL2_GPIO1_WAKEUP;
+ bcmsdh_reg_write(bus->sdh, data, 4, val);
+
+ bus->_oobwakeup = TRUE;
+
+ return 0;
+}
+#endif /* USE_OOB_GPIO1 */
+
+/*
+ * Query if FW is in SR mode
+ */
+static bool
+dhdsdio_sr_cap(dhd_bus_t *bus)
+{
+ bool cap = FALSE;
+ uint32 min = 0, core_capext, addr, data;
+ if (bus->sih->chip == BCM4324_CHIP_ID) {
+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr);
+ data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data);
+ bcmsdh_reg_write(bus->sdh, addr, 4, 3);
+ core_capext = bcmsdh_reg_read(bus->sdh, data, 4);
+ } else if (bus->sih->chip == BCM4330_CHIP_ID || bus->sih->chip == BCM43362_CHIP_ID) {
+ core_capext = FALSE;
+ } else if (bus->sih->chip == BCM4335_CHIP_ID) {
+ core_capext = TRUE;
+ } else {
+ core_capext = bcmsdh_reg_read(bus->sdh, CORE_CAPEXT_ADDR, 4);
+ core_capext = (core_capext & CORE_CAPEXT_SR_SUPPORTED_MASK);
+ }
+ if (!(core_capext))
+ return FALSE;
+
+ if (bus->sih->chip == BCM4324_CHIP_ID) {
+ /* FIX: Should change to query SR control register instead */
+ min = bcmsdh_reg_read(bus->sdh, MIN_RSRC_ADDR, 4);
+ if (min == MIN_RSRC_SR)
+ cap = TRUE;
+ } else if (bus->sih->chip == BCM4335_CHIP_ID) {
+ uint32 enabval = 0;
+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr);
+ data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data);
+ bcmsdh_reg_write(bus->sdh, addr, 4, CC_PMUCC3);
+ enabval = bcmsdh_reg_read(bus->sdh, data, 4);
+
+ if (enabval)
+ cap = TRUE;
+ } else {
+ data = bcmsdh_reg_read(bus->sdh,
+ SI_ENUM_BASE + OFFSETOF(chipcregs_t, retention_ctl), 4);
+ if ((data & (RCTL_MACPHY_DISABLE_MASK | RCTL_LOGIC_DISABLE_MASK)) == 0)
+ cap = TRUE;
+ }
+
+ return cap;
+}
+
+static int
+dhdsdio_srwar_init(dhd_bus_t *bus)
+{
+
+ bcmsdh_gpio_init(bus->sdh);
+
+#ifdef USE_OOB_GPIO1
+ dhdsdio_oobwakeup_init(bus);
+#endif
+
+
+ return 0;
+}
+
+static int
+dhdsdio_sr_init(dhd_bus_t *bus)
+{
+ uint8 val;
+ int err = 0;
+
+ if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev == 2))
+ dhdsdio_srwar_init(bus);
+
+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL, NULL);
+ val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL,
+ 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT, &err);
+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_WAKEUPCTRL, NULL);
+
+ /* Add CMD14 Support */
+ dhdsdio_devcap_set(bus,
+ (SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT));
+
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_FORCE_HT, &err);
+
+ bus->_slpauto = dhd_slpauto ? TRUE : FALSE;
+
+ bus->_srenab = TRUE;
+
+ return 0;
+}
+
+/*
+ * FIX: Be sure KSO bit is enabled
+ * Currently, it's defaulting to 0 which should be 1.
+ */
+static int
+dhdsdio_clk_kso_init(dhd_bus_t *bus)
+{
+ uint8 val;
+ int err = 0;
+
+ /* set flag */
+ bus->kso = TRUE;
+
+ /*
+ * Enable KeepSdioOn (KSO) bit for normal operation
+ * Default is 0 (4334A0) so set it. Fixed in B0.
+ */
+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, NULL);
+ if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) {
+ val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, val, &err);
+ if (err)
+ AP6210_ERR("%s: SBSDIO_FUNC1_SLEEPCSR err: 0x%x\n", __FUNCTION__, err);
+ }
+
+ return 0;
+}
+
+#define KSO_DBG(x)
+#define MAX_KSO_ATTEMPTS 64
+static int
+dhdsdio_clk_kso_enab(dhd_bus_t *bus, bool on)
+{
+ uint8 wr_val = 0, rd_val, cmp_val, bmask;
+ int err = 0;
+ int try_cnt = 0;
+
+ KSO_DBG(("%s> op:%s\n", __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR")));
+
+ wr_val |= (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
+
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
+
+ if (on) {
+ cmp_val = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK | SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK;
+ bmask = cmp_val;
+
+ msleep(3);
+
+ } else {
+ /* Put device to sleep, turn off KSO */
+ cmp_val = 0;
+ bmask = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK;
+ }
+
+ do {
+ rd_val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, &err);
+ if (((rd_val & bmask) == cmp_val) && !err)
+ break;
+
+ KSO_DBG(("%s> KSO wr/rd retry:%d, ERR:%x \n", __FUNCTION__, try_cnt, err));
+ OSL_DELAY(50);
+
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
+
+ } while (try_cnt++ < MAX_KSO_ATTEMPTS);
+
+
+ if (try_cnt > 1) {
+ KSO_DBG(("%s> op:%s, try_cnt:%d, rd_val:%x, ERR:%x \n",
+ __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR"), try_cnt, rd_val, err));
+ }
+
+ if (try_cnt > MAX_KSO_ATTEMPTS) {
+ AP6210_ERR("%s> op:%s, ERROR: try_cnt:%d, rd_val:%x, ERR:%x \n",
+ __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR"), try_cnt, rd_val, err);
+ }
+ return err;
+}
+
+static int
+dhdsdio_clk_kso_iovar(dhd_bus_t *bus, bool on)
+{
+ int err = 0;
+
+ if (on == FALSE) {
+
+ BUS_WAKE(bus);
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+
+ AP6210_DEBUG("%s: KSO disable clk: 0x%x\n", __FUNCTION__,
+ bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, &err));
+ dhdsdio_clk_kso_enab(bus, FALSE);
+ } else {
+ AP6210_DEBUG("%s: KSO enable\n", __FUNCTION__);
+
+ /* Make sure we have SD bus access */
+ if (bus->clkstate == CLK_NONE) {
+ AP6210_DEBUG("%s: Request SD clk\n", __FUNCTION__);
+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
+ }
+
+ /* Double-write to be safe in case transition of AOS */
+ dhdsdio_clk_kso_enab(bus, TRUE);
+ dhdsdio_clk_kso_enab(bus, TRUE);
+ OSL_DELAY(4000);
+
+ /* Wait for device ready during transition to wake-up */
+ SPINWAIT(((dhdsdio_sleepcsr_get(bus)) !=
+ (SBSDIO_FUNC1_SLEEPCSR_KSO_MASK |
+ SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)),
+ (10000));
+
+ AP6210_DEBUG("%s: sleepcsr: 0x%x\n", __FUNCTION__,
+ dhdsdio_sleepcsr_get(bus));
+ }
+
+ bus->kso = on;
+ BCM_REFERENCE(err);
+
+ return 0;
+}
+
+static uint8
+dhdsdio_sleepcsr_get(dhd_bus_t *bus)
+{
+ int err = 0;
+ uint8 val = 0;
+
+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SLEEPCSR, &err);
+ if (err)
+ AP6210_DEBUG("Failed to read SLEEPCSR: %d\n", err);
+
+ return val;
+}
+
+uint8
+dhdsdio_devcap_get(dhd_bus_t *bus)
+{
+ return bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, NULL);
+}
+
+static int
+dhdsdio_devcap_set(dhd_bus_t *bus, uint8 cap)
+{
+ int err = 0;
+
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, cap, &err);
+ if (err)
+ AP6210_ERR("%s: devcap set err: 0x%x\n", __FUNCTION__, err);
+
+ return 0;
+}
+
+static int
+dhdsdio_clk_devsleep_iovar(dhd_bus_t *bus, bool on)
+{
+ int err = 0, retry;
+ uint8 val;
+
+ retry = 0;
+ if (on == TRUE) {
+ /* Enter Sleep */
+
+ /* Be sure we request clk before going to sleep
+ * so we can wake-up with clk request already set
+ * else device can go back to sleep immediately
+ */
+ if (!SLPAUTO_ENAB(bus))
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+ else {
+ val = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
+ if ((val & SBSDIO_CSR_MASK) == 0) {
+ AP6210_DEBUG("%s: No clock before enter sleep:0x%x\n",
+ __FUNCTION__, val);
+
+ /* Reset clock request */
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+ SBSDIO_ALP_AVAIL_REQ, &err);
+ AP6210_DEBUG("%s: clock before sleep:0x%x\n", __FUNCTION__,
+ bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, &err));
+ }
+ }
+
+ AP6210_DEBUG("%s: clk before sleep: 0x%x\n", __FUNCTION__,
+ bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, &err));
+#ifdef USE_CMD14
+ err = bcmsdh_sleep(bus->sdh, TRUE);
+#else
+ err = dhdsdio_clk_kso_enab(bus, FALSE);
+ if (OOB_WAKEUP_ENAB(bus))
+ err = bcmsdh_gpioout(bus->sdh, GPIO_DEV_WAKEUP, FALSE); /* GPIO_1 is off */
+#endif
+ } else {
+ /* Exit Sleep */
+ /* Make sure we have SD bus access */
+ if (bus->clkstate == CLK_NONE) {
+ AP6210_DEBUG("%s: Request SD clk\n", __FUNCTION__);
+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
+ }
+
+ if ((bus->sih->chip == BCM4334_CHIP_ID) && (bus->sih->chiprev == 2)) {
+ SPINWAIT((bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) != TRUE),
+ GPIO_DEV_SRSTATE_TIMEOUT);
+
+ if (bcmsdh_gpioin(bus->sdh, GPIO_DEV_SRSTATE) == FALSE) {
+ AP6210_ERR("ERROR: GPIO_DEV_SRSTATE still low!\n");
+ }
+ }
+#ifdef USE_CMD14
+ err = bcmsdh_sleep(bus->sdh, FALSE);
+ if (SLPAUTO_ENAB(bus) && (err != 0)) {
+ OSL_DELAY(10000);
+ AP6210_DEBUG("%s: Resync device sleep\n", __FUNCTION__);
+
+ /* Toggle sleep to resync with host and device */
+ err = bcmsdh_sleep(bus->sdh, TRUE);
+ OSL_DELAY(10000);
+ err = bcmsdh_sleep(bus->sdh, FALSE);
+
+ if (err) {
+ OSL_DELAY(10000);
+ AP6210_ERR("%s: CMD14 exit failed again!\n", __FUNCTION__);
+
+ /* Toggle sleep to resync with host and device */
+ err = bcmsdh_sleep(bus->sdh, TRUE);
+ OSL_DELAY(10000);
+ err = bcmsdh_sleep(bus->sdh, FALSE);
+ if (err) {
+ AP6210_ERR("%s: CMD14 exit failed twice!\n", __FUNCTION__);
+ AP6210_ERR("%s: FATAL: Device non-response!\n",
+ __FUNCTION__);
+ err = 0;
+ }
+ }
+ }
+#else
+ if (OOB_WAKEUP_ENAB(bus))
+ err = bcmsdh_gpioout(bus->sdh, GPIO_DEV_WAKEUP, TRUE); /* GPIO_1 is on */
+
+ do {
+ err = dhdsdio_clk_kso_enab(bus, TRUE);
+ if (err)
+ OSL_DELAY(10000);
+ } while ((err != 0) && (++retry < 3));
+
+ if (err != 0) {
+ AP6210_ERR("ERROR: kso set failed retry: %d\n", retry);
+ err = 0; /* continue anyway */
+ }
+#endif /* !USE_CMD14 */
+
+ if (err == 0) {
+ uint8 csr;
+
+ /* Wait for device ready during transition to wake-up */
+ SPINWAIT((((csr = dhdsdio_sleepcsr_get(bus)) &
+ SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK) !=
+ (SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)), (20000));
+
+ AP6210_DEBUG("%s: ExitSleep sleepcsr: 0x%x\n", __FUNCTION__, csr);
+
+ if (!(csr & SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)) {
+ AP6210_ERR("%s:ERROR: ExitSleep device NOT Ready! 0x%x\n",
+ __FUNCTION__, csr);
+ err = BCME_NODEVICE;
+ }
+
+ SPINWAIT((((csr = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, &err)) & SBSDIO_HT_AVAIL) !=
+ (SBSDIO_HT_AVAIL)), (10000));
+
+ }
+ }
+
+ /* Update if successful */
+ if (err == 0)
+ bus->kso = on ? FALSE : TRUE;
+ else {
+ AP6210_ERR("%s: Sleep request failed: on:%d err:%d\n", __FUNCTION__, on, err);
+ if (!on && retry > 2)
+ bus->kso = TRUE;
+ }
+
+ return err;
+}
+
+/* Turn backplane clock on or off */
+static int
+dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok)
+{
+#define HT_AVAIL_ERROR_MAX 10
+ static int ht_avail_error = 0;
+ int err;
+ uint8 clkctl, clkreq, devctl;
+ bcmsdh_info_t *sdh;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+#if defined(OOB_INTR_ONLY)
+ pendok = FALSE;
+#endif
+ clkctl = 0;
+ sdh = bus->sdh;
+
+
+ if (!KSO_ENAB(bus))
+ return BCME_OK;
+
+ if (SLPAUTO_ENAB(bus)) {
+ bus->clkstate = (on ? CLK_AVAIL : CLK_SDONLY);
+ return BCME_OK;
+ }
+
+ if (on) {
+ /* Request HT Avail */
+ clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
+
+
+
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
+ if (err) {
+ ht_avail_error++;
+ if (ht_avail_error < HT_AVAIL_ERROR_MAX) {
+ AP6210_ERR("%s: HT Avail request error: %d\n", __FUNCTION__, err);
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+ else if (ht_avail_error == HT_AVAIL_ERROR_MAX) {
+ dhd_os_send_hang_message(bus->dhd);
+ }
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) */
+ return BCME_ERROR;
+ } else {
+ ht_avail_error = 0;
+ }
+
+ if (pendok &&
+ ((bus->sih->buscoretype == PCMCIA_CORE_ID) && (bus->sih->buscorerev == 9))) {
+ uint32 dummy, retries;
+ R_SDREG(dummy, &bus->regs->clockctlstatus, retries);
+ BCM_REFERENCE(dummy);
+ }
+
+ /* Check current status */
+ clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
+ if (err) {
+ AP6210_ERR("%s: HT Avail read error: %d\n", __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+
+ /* Go to pending and await interrupt if appropriate */
+ if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
+ /* Allow only clock-available interrupt */
+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+ if (err) {
+ AP6210_ERR("%s: Devctl access error setting CA: %d\n",
+ __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+
+ devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err);
+ AP6210_DEBUG("CLKCTL: set PENDING\n");
+ bus->clkstate = CLK_PENDING;
+ return BCME_OK;
+ } else if (bus->clkstate == CLK_PENDING) {
+ /* Cancel CA-only interrupt filter */
+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+ devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err);
+ }
+
+ /* Otherwise, wait here (polling) for HT Avail */
+ if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
+ SPINWAIT_SLEEP(sdioh_spinwait_sleep,
+ ((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, &err)),
+ !SBSDIO_CLKAV(clkctl, bus->alp_only)), PMU_MAX_TRANSITION_DLY);
+ }
+ if (err) {
+ AP6210_ERR("%s: HT Avail request error: %d\n", __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+ if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
+ AP6210_ERR("%s: HT Avail timeout (%d): clkctl 0x%02x\n",
+ __FUNCTION__, PMU_MAX_TRANSITION_DLY, clkctl);
+ return BCME_ERROR;
+ }
+
+ /* Mark clock available */
+ bus->clkstate = CLK_AVAIL;
+ AP6210_DEBUG("CLKCTL: turned ON\n");
+
+#if defined(DHD_DEBUG)
+ if (bus->alp_only == TRUE) {
+#if !defined(BCMLXSDMMC)
+ if (!SBSDIO_ALPONLY(clkctl)) {
+ AP6210_ERR("%s: HT Clock, when ALP Only\n", __FUNCTION__);
+ }
+#endif /* !defined(BCMLXSDMMC) */
+ } else {
+ if (SBSDIO_ALPONLY(clkctl)) {
+ AP6210_ERR("%s: HT Clock should be on.\n", __FUNCTION__);
+ }
+ }
+#endif /* defined (DHD_DEBUG) */
+
+ bus->activity = TRUE;
+#ifdef DHD_USE_IDLECOUNT
+ bus->idlecount = 0;
+#endif /* DHD_USE_IDLECOUNT */
+ } else {
+ clkreq = 0;
+ if (bus->clkstate == CLK_PENDING) {
+ /* Cancel CA-only interrupt filter */
+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+ devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err);
+ }
+
+ bus->clkstate = CLK_SDONLY;
+ if (!SR_ENAB(bus)) {
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
+ AP6210_DEBUG("CLKCTL: turned OFF\n");
+ if (err) {
+ AP6210_ERR("%s: Failed access turning clock off: %d\n",
+ __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+ }
+ }
+ return BCME_OK;
+}
+
+/* Change idle/active SD state */
+static int
+dhdsdio_sdclk(dhd_bus_t *bus, bool on)
+{
+ int err;
+ int32 iovalue;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (on) {
+ if (bus->idleclock == DHD_IDLE_STOP) {
+ /* Turn on clock and restore mode */
+ iovalue = 1;
+ err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0,
+ &iovalue, sizeof(iovalue), TRUE);
+ if (err) {
+ AP6210_ERR("%s: error enabling sd_clock: %d\n",
+ __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+
+ iovalue = bus->sd_mode;
+ err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
+ &iovalue, sizeof(iovalue), TRUE);
+ if (err) {
+ AP6210_ERR("%s: error changing sd_mode: %d\n",
+ __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+ } else if (bus->idleclock != DHD_IDLE_ACTIVE) {
+ /* Restore clock speed */
+ iovalue = bus->sd_divisor;
+ err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+ &iovalue, sizeof(iovalue), TRUE);
+ if (err) {
+ AP6210_ERR("%s: error restoring sd_divisor: %d\n",
+ __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+ }
+ bus->clkstate = CLK_SDONLY;
+ } else {
+ /* Stop or slow the SD clock itself */
+ if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) {
+ AP6210_DEBUG("%s: can't idle clock, divisor %d mode %d\n",
+ __FUNCTION__, bus->sd_divisor, bus->sd_mode);
+ return BCME_ERROR;
+ }
+ if (bus->idleclock == DHD_IDLE_STOP) {
+ if (sd1idle) {
+ /* Change to SD1 mode and turn off clock */
+ iovalue = 1;
+ err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
+ &iovalue, sizeof(iovalue), TRUE);
+ if (err) {
+ AP6210_ERR("%s: error changing sd_clock: %d\n",
+ __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+ }
+
+ iovalue = 0;
+ err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0,
+ &iovalue, sizeof(iovalue), TRUE);
+ if (err) {
+ AP6210_ERR("%s: error disabling sd_clock: %d\n",
+ __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+ } else if (bus->idleclock != DHD_IDLE_ACTIVE) {
+ /* Set divisor to idle value */
+ iovalue = bus->idleclock;
+ err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+ &iovalue, sizeof(iovalue), TRUE);
+ if (err) {
+ AP6210_ERR("%s: error changing sd_divisor: %d\n",
+ __FUNCTION__, err);
+ return BCME_ERROR;
+ }
+ }
+ bus->clkstate = CLK_NONE;
+ }
+
+ return BCME_OK;
+}
+
+/* Transition SD and backplane clock readiness */
+static int
+dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
+{
+ int ret = BCME_OK;
+#ifdef DHD_DEBUG
+ uint oldstate = bus->clkstate;
+#endif /* DHD_DEBUG */
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ /* Early exit if we're already there */
+ if (bus->clkstate == target) {
+ if (target == CLK_AVAIL) {
+ dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+ bus->activity = TRUE;
+#ifdef DHD_USE_IDLECOUNT
+ bus->idlecount = 0;
+#endif /* DHD_USE_IDLECOUNT */
+ }
+ return ret;
+ }
+
+ switch (target) {
+ case CLK_AVAIL:
+ /* Make sure SD clock is available */
+ if (bus->clkstate == CLK_NONE)
+ dhdsdio_sdclk(bus, TRUE);
+ /* Now request HT Avail on the backplane */
+ ret = dhdsdio_htclk(bus, TRUE, pendok);
+ if (ret == BCME_OK) {
+ dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+ bus->activity = TRUE;
+#ifdef DHD_USE_IDLECOUNT
+ bus->idlecount = 0;
+#endif /* DHD_USE_IDLECOUNT */
+ }
+ break;
+
+ case CLK_SDONLY:
+ /* Remove HT request, or bring up SD clock */
+ if (bus->clkstate == CLK_NONE)
+ ret = dhdsdio_sdclk(bus, TRUE);
+ else if (bus->clkstate == CLK_AVAIL)
+ ret = dhdsdio_htclk(bus, FALSE, FALSE);
+ else
+ AP6210_DEBUG("dhdsdio_clkctl: request for %d -> %d\n",
+ bus->clkstate, target);
+ if (ret == BCME_OK) {
+ dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+ }
+ break;
+
+ case CLK_NONE:
+ /* Make sure to remove HT request */
+ if (bus->clkstate == CLK_AVAIL)
+ ret = dhdsdio_htclk(bus, FALSE, FALSE);
+ /* Now remove the SD clock */
+ ret = dhdsdio_sdclk(bus, FALSE);
+#ifdef DHD_DEBUG
+ if (dhd_console_ms == 0)
+#endif /* DHD_DEBUG */
+ if (bus->poll == 0)
+ dhd_os_wd_timer(bus->dhd, 0);
+ break;
+ }
+#ifdef DHD_DEBUG
+ AP6210_DEBUG("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate);
+#endif /* DHD_DEBUG */
+
+ return ret;
+}
+
+static int
+dhdsdio_bussleep(dhd_bus_t *bus, bool sleep)
+{
+ int err = 0;
+ bcmsdh_info_t *sdh = bus->sdh;
+ sdpcmd_regs_t *regs = bus->regs;
+ uint retries = 0;
+
+ AP6210_DEBUG("dhdsdio_bussleep: request %s (currently %s)\n",
+ (sleep ? "SLEEP" : "WAKE"),
+ (bus->sleeping ? "SLEEP" : "WAKE"));
+
+ /* Done if we're already in the requested state */
+ if (sleep == bus->sleeping)
+ return BCME_OK;
+
+ /* Going to sleep: set the alarm and turn off the lights... */
+ if (sleep) {
+ /* Don't sleep if something is pending */
+ if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
+ return BCME_BUSY;
+
+
+ if (!SLPAUTO_ENAB(bus)) {
+ /* Disable SDIO interrupts (no longer interested) */
+ bcmsdh_intr_disable(bus->sdh);
+
+ /* Make sure the controller has the bus up */
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+
+ /* Tell device to start using OOB wakeup */
+ W_SDREG(SMB_USE_OOB, &regs->tosbmailbox, retries);
+ if (retries > retry_limit)
+ AP6210_ERR("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
+
+ /* Turn off our contribution to the HT clock request */
+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
+
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+ SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
+
+ /* Isolate the bus */
+ if (bus->sih->chip != BCM4329_CHIP_ID &&
+ bus->sih->chip != BCM4319_CHIP_ID) {
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+ SBSDIO_DEVCTL_PADS_ISO, NULL);
+ }
+ } else {
+ /* Leave interrupts enabled since device can exit sleep and
+ * interrupt host
+ */
+ err = dhdsdio_clk_devsleep_iovar(bus, TRUE /* sleep */);
+ }
+
+ /* Change state */
+ bus->sleeping = TRUE;
+
+ } else {
+ /* Waking up: bus power up is ok, set local state */
+
+ if (!SLPAUTO_ENAB(bus)) {
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, &err);
+
+ /* Force pad isolation off if possible (in case power never toggled) */
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL);
+
+
+ /* Make sure the controller has the bus up */
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+
+ /* Send misc interrupt to indicate OOB not needed */
+ W_SDREG(0, &regs->tosbmailboxdata, retries);
+ if (retries <= retry_limit)
+ W_SDREG(SMB_DEV_INT, &regs->tosbmailbox, retries);
+
+ if (retries > retry_limit)
+ AP6210_ERR("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
+
+ /* Make sure we have SD bus access */
+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
+
+ /* Enable interrupts again */
+ if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) {
+ bus->intdis = FALSE;
+ bcmsdh_intr_enable(bus->sdh);
+ }
+ } else {
+ err = dhdsdio_clk_devsleep_iovar(bus, FALSE /* wake */);
+ }
+
+ if (err == 0) {
+ /* Change state */
+ bus->sleeping = FALSE;
+ }
+ }
+
+ return err;
+}
+
+#if defined(OOB_INTR_ONLY)
+void
+dhd_enable_oob_intr(struct dhd_bus *bus, bool enable)
+{
+#if defined(HW_OOB)
+ bcmsdh_enable_hw_oob_intr(bus->sdh, enable);
+#else
+ sdpcmd_regs_t *regs = bus->regs;
+ uint retries = 0;
+
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+ if (enable == TRUE) {
+
+ /* Tell device to start using OOB wakeup */
+ W_SDREG(SMB_USE_OOB, &regs->tosbmailbox, retries);
+ if (retries > retry_limit)
+ AP6210_ERR("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
+
+ } else {
+ /* Send misc interrupt to indicate OOB not needed */
+ W_SDREG(0, &regs->tosbmailboxdata, retries);
+ if (retries <= retry_limit)
+ W_SDREG(SMB_DEV_INT, &regs->tosbmailbox, retries);
+ }
+
+ /* Turn off our contribution to the HT clock request */
+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
+#endif /* !defined(HW_OOB) */
+}
+#endif
+
+/* Writes a HW/SW header into the packet and sends it. */
+/* Assumes: (a) header space already there, (b) caller holds lock */
+static int
+dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt, bool queue_only)
+{
+ int ret;
+ osl_t *osh;
+ uint8 *frame;
+ uint16 len, pad1 = 0;
+ uint32 swheader;
+ uint retries = 0;
+ bcmsdh_info_t *sdh;
+ void *new;
+ int i;
+ int pkt_cnt;
+#ifdef BCMSDIOH_TXGLOM
+ uint8 *frame_tmp;
+#endif
+#ifdef WLMEDIA_HTSF
+ char *p;
+ htsfts_t *htsf_ts;
+#endif
+
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ sdh = bus->sdh;
+ osh = bus->dhd->osh;
+
+ if (bus->dhd->dongle_reset) {
+ ret = BCME_NOTREADY;
+ goto done;
+ }
+
+ frame = (uint8*)PKTDATA(osh, pkt);
+
+#ifdef WLMEDIA_HTSF
+ if (PKTLEN(osh, pkt) >= 100) {
+ p = PKTDATA(osh, pkt);
+ htsf_ts = (htsfts_t*) (p + HTSF_HOSTOFFSET + 12);
+ if (htsf_ts->magic == HTSFMAGIC) {
+ htsf_ts->c20 = get_cycles();
+ htsf_ts->t20 = dhd_get_htsf(bus->dhd->info, 0);
+ }
+ }
+#endif /* WLMEDIA_HTSF */
+
+ /* Add alignment padding, allocate new packet if needed */
+ if (!((uintptr)frame & 1) && (pad1 = ((uintptr)frame % DHD_SDALIGN))) {
+ if (PKTHEADROOM(osh, pkt) < pad1) {
+ AP6210_ERR("%s: insufficient headroom %d for %d pad1\n",
+ __FUNCTION__, (int)PKTHEADROOM(osh, pkt), pad1);
+ bus->dhd->tx_realloc++;
+ new = PKTGET(osh, (PKTLEN(osh, pkt) + DHD_SDALIGN), TRUE);
+ if (!new) {
+ AP6210_ERR("%s: couldn't allocate new %d-byte packet\n",
+ __FUNCTION__, PKTLEN(osh, pkt) + DHD_SDALIGN);
+ ret = BCME_NOMEM;
+ goto done;
+ }
+
+ PKTALIGN(osh, new, PKTLEN(osh, pkt), DHD_SDALIGN);
+ bcopy(PKTDATA(osh, pkt), PKTDATA(osh, new), PKTLEN(osh, pkt));
+ if (free_pkt)
+ PKTFREE(osh, pkt, TRUE);
+ /* free the pkt if canned one is not used */
+ free_pkt = TRUE;
+ pkt = new;
+ frame = (uint8*)PKTDATA(osh, pkt);
+ ASSERT(((uintptr)frame % DHD_SDALIGN) == 0);
+ pad1 = 0;
+ } else {
+ PKTPUSH(osh, pkt, pad1);
+ frame = (uint8*)PKTDATA(osh, pkt);
+
+ ASSERT((pad1 + SDPCM_HDRLEN) <= (int) PKTLEN(osh, pkt));
+ bzero(frame, pad1 + SDPCM_HDRLEN);
+ }
+ }
+ ASSERT(pad1 < DHD_SDALIGN);
+
+ /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
+ len = (uint16)PKTLEN(osh, pkt);
+ *(uint16*)frame = htol16(len);
+ *(((uint16*)frame) + 1) = htol16(~len);
+
+#ifdef BCMSDIOH_TXGLOM
+ if (bus->glom_enable) {
+ uint32 hwheader1 = 0, hwheader2 = 0, act_len = len;
+
+ /* Software tag: channel, sequence number, data offset */
+ swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) |
+ ((bus->tx_seq + bus->glom_cnt) % SDPCM_SEQUENCE_WRAP) |
+ (((pad1 + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
+ htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN);
+ htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN + sizeof(swheader));
+
+ if (queue_only) {
+ if (forcealign && (len & (ALIGNMENT - 1)))
+ len = ROUNDUP(len, ALIGNMENT);
+ /* Hardware extention tag */
+ /* 2byte frame length, 1byte-, 1byte frame flag,
+ * 2byte-hdrlength, 2byte padlenght
+ */
+ hwheader1 = (act_len - SDPCM_FRAMETAG_LEN) | (0 << 24);
+ hwheader2 = (len - act_len) << 16;
+ htol32_ua_store(hwheader1, frame + SDPCM_FRAMETAG_LEN);
+ htol32_ua_store(hwheader2, frame + SDPCM_FRAMETAG_LEN + 4);
+ /* Post the frame pointer to sdio glom array */
+ dhd_bcmsdh_glom_post(bus, frame, len);
+ /* Save the pkt pointer in bus glom array */
+ bus->glom_pkt_arr[bus->glom_cnt] = pkt;
+ bus->glom_total_len += len;
+ bus->glom_cnt++;
+ return BCME_OK;
+ } else {
+ /* Raise len to next SDIO block to eliminate tail command */
+ if (bus->roundup && bus->blocksize &&
+ ((bus->glom_total_len + len) > bus->blocksize)) {
+ uint16 pad2 = bus->blocksize -
+ ((bus->glom_total_len + len) % bus->blocksize);
+ if ((pad2 <= bus->roundup) && (pad2 < bus->blocksize)) {
+ len += pad2;
+ } else {
+ }
+ } else if ((bus->glom_total_len + len) % DHD_SDALIGN) {
+ len += DHD_SDALIGN
+ - ((bus->glom_total_len + len) % DHD_SDALIGN);
+ }
+ if (forcealign && (len & (ALIGNMENT - 1))) {
+ len = ROUNDUP(len, ALIGNMENT);
+ }
+
+ /* Hardware extention tag */
+ /* 2byte frame length, 1byte-, 1byte frame flag,
+ * 2byte-hdrlength, 2byte padlenght
+ */
+ hwheader1 = (act_len - SDPCM_FRAMETAG_LEN) | (1 << 24);
+ hwheader2 = (len - act_len) << 16;
+ htol32_ua_store(hwheader1, frame + SDPCM_FRAMETAG_LEN);
+ htol32_ua_store(hwheader2, frame + SDPCM_FRAMETAG_LEN + 4);
+
+ /* Post the frame pointer to sdio glom array */
+ dhd_bcmsdh_glom_post(bus, frame, len);
+ /* Save the pkt pointer in bus glom array */
+ bus->glom_pkt_arr[bus->glom_cnt] = pkt;
+ bus->glom_cnt++;
+ bus->glom_total_len += len;
+
+ /* Update the total length on the first pkt */
+ frame_tmp = (uint8*)PKTDATA(osh, bus->glom_pkt_arr[0]);
+ *(uint16*)frame_tmp = htol16(bus->glom_total_len);
+ *(((uint16*)frame_tmp) + 1) = htol16(~bus->glom_total_len);
+ }
+ } else
+#endif /* BCMSDIOH_TXGLOM */
+ {
+ /* Software tag: channel, sequence number, data offset */
+ swheader = ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
+ (((pad1 + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
+ htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN);
+ htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
+
+#ifdef DHD_DEBUG
+ if (PKTPRIO(pkt) < ARRAYSIZE(tx_packets)) {
+ tx_packets[PKTPRIO(pkt)]++;
+ }
+ if (DHD_BYTES_ON() &&
+ (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
+ (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
+ prhex("Tx Frame", frame, len);
+ } else if (DHD_HDRS_ON()) {
+ prhex("TxHdr", frame, MIN(len, 16));
+ }
+#endif
+
+ /* Raise len to next SDIO block to eliminate tail command */
+ if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
+ uint16 pad2 = bus->blocksize - (len % bus->blocksize);
+ if ((pad2 <= bus->roundup) && (pad2 < bus->blocksize))
+#ifdef NOTUSED
+ if (pad2 <= PKTTAILROOM(osh, pkt))
+#endif /* NOTUSED */
+ len += pad2;
+ } else if (len % DHD_SDALIGN) {
+ len += DHD_SDALIGN - (len % DHD_SDALIGN);
+ }
+
+ /* Some controllers have trouble with odd bytes -- round to even */
+ if (forcealign && (len & (ALIGNMENT - 1))) {
+#ifdef NOTUSED
+ if (PKTTAILROOM(osh, pkt))
+#endif
+ len = ROUNDUP(len, ALIGNMENT);
+#ifdef NOTUSED
+ else
+ AP6210_DEBUG("%s: sending unrounded %d-byte packet\n", __FUNCTION__, len);
+#endif
+ }
+ }
+
+ do {
+ ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
+ frame, len, pkt, NULL, NULL);
+ bus->f2txdata++;
+ ASSERT(ret != BCME_PENDING);
+
+ if (ret == BCME_NODEVICE) {
+ AP6210_ERR("%s: Device asleep already\n", __FUNCTION__);
+ } else if (ret < 0) {
+ /* On failure, abort the command and terminate the frame */
+ AP6210_ERR("%s: sdio error %d, abort command and terminate frame.\n",
+ __FUNCTION__, ret);
+ bus->tx_sderrs++;
+
+ bcmsdh_abort(sdh, SDIO_FUNC_2);
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL,
+ SFC_WF_TERM, NULL);
+ bus->f1regdata++;
+
+ for (i = 0; i < 3; i++) {
+ uint8 hi, lo;
+ hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_WFRAMEBCHI, NULL);
+ lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_WFRAMEBCLO, NULL);
+ bus->f1regdata += 2;
+ if ((hi == 0) && (lo == 0))
+ break;
+ }
+ }
+ if (ret == 0) {
+#ifdef BCMSDIOH_TXGLOM
+ if (bus->glom_enable) {
+ bus->tx_seq = (bus->tx_seq + bus->glom_cnt) % SDPCM_SEQUENCE_WRAP;
+ } else
+#endif
+ {
+ bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+ }
+ }
+ } while ((ret < 0) && retrydata && retries++ < TXRETRIES);
+
+done:
+
+#ifdef BCMSDIOH_TXGLOM
+ if (bus->glom_enable) {
+ dhd_bcmsdh_glom_clear(bus);
+ pkt_cnt = bus->glom_cnt;
+ } else
+#endif
+ {
+ pkt_cnt = 1;
+ }
+ /* restore pkt buffer pointer before calling tx complete routine */
+ while (pkt_cnt) {
+#ifdef BCMSDIOH_TXGLOM
+ uint32 doff;
+ if (bus->glom_enable) {
+ pkt = bus->glom_pkt_arr[bus->glom_cnt - pkt_cnt];
+ frame = (uint8*)PKTDATA(osh, pkt);
+ doff = ltoh32_ua(frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN);
+ doff = (doff & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT;
+ PKTPULL(osh, pkt, doff);
+ } else
+#endif
+ {
+ PKTPULL(osh, pkt, SDPCM_HDRLEN + pad1);
+ }
+#ifdef PROP_TXSTATUS
+ if (bus->dhd->wlfc_state) {
+ dhd_os_sdunlock(bus->dhd);
+ dhd_wlfc_txcomplete(bus->dhd, pkt, ret == 0, FALSE);
+ dhd_os_sdlock(bus->dhd);
+ } else {
+#endif /* PROP_TXSTATUS */
+#ifdef SDTEST
+ if (chan != SDPCM_TEST_CHANNEL) {
+ dhd_txcomplete(bus->dhd, pkt, ret != 0);
+ }
+#else /* SDTEST */
+ dhd_txcomplete(bus->dhd, pkt, ret != 0);
+#endif /* SDTEST */
+ if (free_pkt)
+ PKTFREE(osh, pkt, TRUE);
+
+#ifdef PROP_TXSTATUS
+ }
+#endif
+ pkt_cnt--;
+ }
+
+#ifdef BCMSDIOH_TXGLOM
+ /* Reset the glom array */
+ if (bus->glom_enable) {
+ bus->glom_cnt = 0;
+ bus->glom_total_len = 0;
+ }
+#endif
+ return ret;
+}
+
+int
+dhd_bus_txdata(struct dhd_bus *bus, void *pkt, bool wlfc_locked)
+{
+ int ret = BCME_ERROR;
+ osl_t *osh;
+ uint datalen, prec;
+#ifdef DHD_TX_DUMP
+ uint8 *dump_data;
+ uint16 protocol;
+#ifdef DHD_TX_FULL_DUMP
+ int i;
+#endif /* DHD_TX_FULL_DUMP */
+#endif /* DHD_TX_DUMP */
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ osh = bus->dhd->osh;
+ datalen = PKTLEN(osh, pkt);
+
+#ifdef SDTEST
+ /* Push the test header if doing loopback */
+ if (bus->ext_loop) {
+ uint8* data;
+ PKTPUSH(osh, pkt, SDPCM_TEST_HDRLEN);
+ data = PKTDATA(osh, pkt);
+ *data++ = SDPCM_TEST_ECHOREQ;
+ *data++ = (uint8)bus->loopid++;
+ *data++ = (datalen >> 0);
+ *data++ = (datalen >> 8);
+ datalen += SDPCM_TEST_HDRLEN;
+ }
+#endif /* SDTEST */
+
+#ifdef DHD_TX_DUMP
+ dump_data = PKTDATA(osh, pkt);
+ dump_data += 4; /* skip 4 bytes header */
+ protocol = (dump_data[12] << 8) | dump_data[13];
+#ifdef DHD_TX_FULL_DUMP
+ AP6210_DEBUG("TX DUMP\n");
+
+ for (i = 0; i < (datalen - 4); i++) {
+ DHD_CONT("%02X ", dump_data[i]);
+ if ((i & 15) == 15)
+ DHD_CONT("\n");
+ }
+ AP6210_DEBUG("\n");
+
+#endif /* DHD_TX_FULL_DUMP */
+ if (protocol == ETHER_TYPE_802_1X) {
+ AP6210_DEBUG("ETHER_TYPE_802_1X: ver %d, type %d, replay %d\n",
+ dump_data[14], dump_data[15], dump_data[30]);
+ }
+#endif /* DHD_TX_DUMP */
+
+ /* Add space for the header */
+ PKTPUSH(osh, pkt, SDPCM_HDRLEN);
+ ASSERT(ISALIGNED((uintptr)PKTDATA(osh, pkt), 2));
+
+ prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK));
+#ifndef DHDTHREAD
+ /* Lock: we're about to use shared data/code (and SDIO) */
+ dhd_os_sdlock(bus->dhd);
+#endif /* DHDTHREAD */
+
+ /* Check for existing queue, current flow-control, pending event, or pending clock */
+ if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq) || bus->dpc_sched ||
+ (!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) ||
+ (bus->clkstate != CLK_AVAIL)) {
+ AP6210_DEBUG("%s: deferring pktq len %d\n", __FUNCTION__,
+ pktq_len(&bus->txq));
+ bus->fcqueued++;
+
+ /* Priority based enq */
+ dhd_os_sdlock_txq(bus->dhd);
+ if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == FALSE) {
+ PKTPULL(osh, pkt, SDPCM_HDRLEN);
+#ifndef DHDTHREAD
+ /* Need to also release txqlock before releasing sdlock.
+ * This thread still has txqlock and releases sdlock.
+ * Deadlock happens when dpc() grabs sdlock first then
+ * attempts to grab txqlock.
+ */
+ dhd_os_sdunlock_txq(bus->dhd);
+ dhd_os_sdunlock(bus->dhd);
+#endif
+#ifdef PROP_TXSTATUS
+ if (bus->dhd->wlfc_state)
+ dhd_wlfc_txcomplete(bus->dhd, pkt, FALSE, wlfc_locked);
+ else
+#endif
+ dhd_txcomplete(bus->dhd, pkt, FALSE);
+#ifndef DHDTHREAD
+ dhd_os_sdlock(bus->dhd);
+ dhd_os_sdlock_txq(bus->dhd);
+#endif
+#ifdef PROP_TXSTATUS
+ /* let the caller decide whether to free the packet */
+ if (!bus->dhd->wlfc_state)
+#endif
+ PKTFREE(osh, pkt, TRUE);
+ ret = BCME_NORESOURCE;
+ }
+ else
+ ret = BCME_OK;
+ dhd_os_sdunlock_txq(bus->dhd);
+
+ if ((pktq_len(&bus->txq) >= FCHI) && dhd_doflow)
+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON);
+
+#ifdef DHD_DEBUG
+ if (pktq_plen(&bus->txq, prec) > qcount[prec])
+ qcount[prec] = pktq_plen(&bus->txq, prec);
+#endif
+ /* Schedule DPC if needed to send queued packet(s) */
+ if (dhd_deferred_tx && !bus->dpc_sched) {
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd);
+ }
+ } else {
+#ifdef DHDTHREAD
+ /* Lock: we're about to use shared data/code (and SDIO) */
+ dhd_os_sdlock(bus->dhd);
+#endif /* DHDTHREAD */
+
+ /* Otherwise, send it now */
+ BUS_WAKE(bus);
+ /* Make sure back plane ht clk is on, no pending allowed */
+ dhdsdio_clkctl(bus, CLK_AVAIL, TRUE);
+#ifndef SDTEST
+ ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE, FALSE);
+#else
+ ret = dhdsdio_txpkt(bus, pkt,
+ (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), TRUE, FALSE);
+#endif
+ if (ret)
+ bus->dhd->tx_errors++;
+ else
+ bus->dhd->dstats.tx_bytes += datalen;
+
+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+ bus->activity = FALSE;
+ dhdsdio_clkctl(bus, CLK_NONE, TRUE);
+ }
+
+#ifdef DHDTHREAD
+ dhd_os_sdunlock(bus->dhd);
+#endif /* DHDTHREAD */
+ }
+
+#ifndef DHDTHREAD
+ dhd_os_sdunlock(bus->dhd);
+#endif /* DHDTHREAD */
+
+ return ret;
+}
+
+static uint
+dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
+{
+ void *pkt;
+ uint32 intstatus = 0;
+ uint retries = 0;
+ int ret = 0, prec_out;
+ uint cnt = 0;
+ uint datalen;
+ uint8 tx_prec_map;
+#ifdef BCMSDIOH_TXGLOM
+ uint i;
+ uint8 glom_cnt;
+#endif
+
+ dhd_pub_t *dhd = bus->dhd;
+ sdpcmd_regs_t *regs = bus->regs;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (!KSO_ENAB(bus)) {
+ AP6210_DEBUG("%s: Device asleep\n", __FUNCTION__);
+ return BCME_NODEVICE;
+ }
+
+ tx_prec_map = ~bus->flowcontrol;
+
+ /* Send frames until the limit or some other event */
+ for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) {
+#ifdef BCMSDIOH_TXGLOM
+ if (bus->glom_enable) {
+ glom_cnt = MIN(DATABUFCNT(bus), bus->glomsize);
+ glom_cnt = MIN(glom_cnt, pktq_mlen(&bus->txq, tx_prec_map));
+ glom_cnt = MIN(glom_cnt, maxframes-cnt);
+
+ /* Limiting the size to 2pkts in case of copy */
+ if (bus->glom_mode == SDPCM_TXGLOM_CPY)
+ glom_cnt = MIN(glom_cnt, 5);
+
+ if (glom_cnt == 0)
+ break;
+ datalen = 0;
+ for (i = 0; i < glom_cnt; i++) {
+ dhd_os_sdlock_txq(bus->dhd);
+ if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) {
+ /* This case should not happen */
+ AP6210_DEBUG("No pkts in the queue for glomming\n");
+ dhd_os_sdunlock_txq(bus->dhd);
+ break;
+ }
+ dhd_os_sdunlock_txq(bus->dhd);
+
+ datalen += (PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN);
+#ifndef SDTEST
+ ret = dhdsdio_txpkt(bus,
+ pkt,
+ SDPCM_DATA_CHANNEL,
+ TRUE,
+ (i == (glom_cnt-1))? FALSE: TRUE);
+#else
+ ret = dhdsdio_txpkt(bus,
+ pkt,
+ (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL),
+ TRUE,
+ (i == (glom_cnt-1))? FALSE: TRUE);
+#endif
+ }
+ cnt += i-1;
+ } else
+#endif /* BCMSDIOH_TXGLOM */
+ {
+ dhd_os_sdlock_txq(bus->dhd);
+ if ((pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out)) == NULL) {
+ dhd_os_sdunlock_txq(bus->dhd);
+ break;
+ }
+ dhd_os_sdunlock_txq(bus->dhd);
+ datalen = PKTLEN(bus->dhd->osh, pkt) - SDPCM_HDRLEN;
+
+#ifndef SDTEST
+ ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, TRUE, FALSE);
+#else
+ ret = dhdsdio_txpkt(bus,
+ pkt,
+ (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL),
+ TRUE,
+ FALSE);
+#endif
+ }
+
+ if (ret)
+ bus->dhd->tx_errors++;
+ else
+ bus->dhd->dstats.tx_bytes += datalen;
+
+ /* In poll mode, need to check for other events */
+ if (!bus->intr && cnt)
+ {
+ /* Check device status, signal pending interrupt */
+ R_SDREG(intstatus, &regs->intstatus, retries);
+ bus->f2txdata++;
+ if (bcmsdh_regfail(bus->sdh))
+ break;
+ if (intstatus & bus->hostintmask)
+ bus->ipend = TRUE;
+ }
+ }
+
+ /* Deflow-control stack if needed */
+ if (dhd_doflow && dhd->up && (dhd->busstate == DHD_BUS_DATA) &&
+ dhd->txoff && (pktq_len(&bus->txq) < FCLOW))
+ dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
+
+ return cnt;
+}
+
+int
+dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
+{
+ uint8 *frame;
+ uint16 len;
+ uint32 swheader;
+ uint retries = 0;
+ bcmsdh_info_t *sdh = bus->sdh;
+ uint8 doff = 0;
+ int ret = -1;
+ int i;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (bus->dhd->dongle_reset)
+ return -EIO;
+
+ /* Back the pointer to make a room for bus header */
+ frame = msg - SDPCM_HDRLEN;
+ len = (msglen += SDPCM_HDRLEN);
+
+ /* Add alignment padding (optional for ctl frames) */
+ if (dhd_alignctl) {
+ if ((doff = ((uintptr)frame % DHD_SDALIGN))) {
+ frame -= doff;
+ len += doff;
+ msglen += doff;
+ bzero(frame, doff + SDPCM_HDRLEN);
+ }
+ ASSERT(doff < DHD_SDALIGN);
+ }
+ doff += SDPCM_HDRLEN;
+
+ /* Round send length to next SDIO block */
+ if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
+ uint16 pad = bus->blocksize - (len % bus->blocksize);
+ if ((pad <= bus->roundup) && (pad < bus->blocksize))
+ len += pad;
+ } else if (len % DHD_SDALIGN) {
+ len += DHD_SDALIGN - (len % DHD_SDALIGN);
+ }
+
+ /* Satisfy length-alignment requirements */
+ if (forcealign && (len & (ALIGNMENT - 1)))
+ len = ROUNDUP(len, ALIGNMENT);
+
+ ASSERT(ISALIGNED((uintptr)frame, 2));
+
+
+ /* Need to lock here to protect txseq and SDIO tx calls */
+ dhd_os_sdlock(bus->dhd);
+
+ BUS_WAKE(bus);
+
+ /* Make sure backplane clock is on */
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+
+ /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
+ *(uint16*)frame = htol16((uint16)msglen);
+ *(((uint16*)frame) + 1) = htol16(~msglen);
+
+#ifdef BCMSDIOH_TXGLOM
+ if (bus->glom_enable) {
+ uint32 hwheader1, hwheader2;
+ /* Software tag: channel, sequence number, data offset */
+ swheader = ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK)
+ | bus->tx_seq
+ | ((doff << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
+ htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN + SDPCM_HWEXT_LEN);
+ htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN
+ + SDPCM_HWEXT_LEN + sizeof(swheader));
+
+ hwheader1 = (msglen - SDPCM_FRAMETAG_LEN) | (1 << 24);
+ hwheader2 = (len - (msglen)) << 16;
+ htol32_ua_store(hwheader1, frame + SDPCM_FRAMETAG_LEN);
+ htol32_ua_store(hwheader2, frame + SDPCM_FRAMETAG_LEN + 4);
+
+ *(uint16*)frame = htol16(len);
+ *(((uint16*)frame) + 1) = htol16(~(len));
+ } else
+#endif /* BCMSDIOH_TXGLOM */
+ {
+ /* Software tag: channel, sequence number, data offset */
+ swheader = ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK)
+ | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
+ htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN);
+ htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
+ }
+ if (!TXCTLOK(bus)) {
+ AP6210_DEBUG("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n",
+ __FUNCTION__, bus->tx_max, bus->tx_seq);
+ bus->ctrl_frame_stat = TRUE;
+ /* Send from dpc */
+ bus->ctrl_frame_buf = frame;
+ bus->ctrl_frame_len = len;
+
+ if (!bus->dpc_sched) {
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd);
+ }
+ if (bus->ctrl_frame_stat) {
+ dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
+ }
+
+ if (bus->ctrl_frame_stat == FALSE) {
+ AP6210_DEBUG("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__);
+ ret = 0;
+ } else {
+ bus->dhd->txcnt_timeout++;
+ if (!bus->dhd->hang_was_sent) {
+ AP6210_DEBUG("%s: ctrl_frame_stat == TRUE txcnt_timeout=%d\n",
+ __FUNCTION__, bus->dhd->txcnt_timeout);
+ }
+ ret = -1;
+ bus->ctrl_frame_stat = FALSE;
+ goto done;
+ }
+ }
+
+ bus->dhd->txcnt_timeout = 0;
+
+ if (ret == -1) {
+#ifdef DHD_DEBUG
+ if (DHD_BYTES_ON() && DHD_CTL_ON()) {
+ prhex("Tx Frame", frame, len);
+ } else if (DHD_HDRS_ON()) {
+ prhex("TxHdr", frame, MIN(len, 16));
+ }
+#endif
+
+ do {
+ ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
+ frame, len, NULL, NULL, NULL);
+ ASSERT(ret != BCME_PENDING);
+
+ if (ret == BCME_NODEVICE) {
+ AP6210_DEBUG("%s: Device asleep already\n", __FUNCTION__);
+ } else if (ret < 0) {
+ /* On failure, abort the command and terminate the frame */
+ AP6210_DEBUG("%s: sdio error %d, abort command and terminate frame.\n",
+ __FUNCTION__, ret);
+ bus->tx_sderrs++;
+
+ bcmsdh_abort(sdh, SDIO_FUNC_2);
+
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL,
+ SFC_WF_TERM, NULL);
+ bus->f1regdata++;
+
+ for (i = 0; i < 3; i++) {
+ uint8 hi, lo;
+ hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_WFRAMEBCHI, NULL);
+ lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_WFRAMEBCLO, NULL);
+ bus->f1regdata += 2;
+ if ((hi == 0) && (lo == 0))
+ break;
+ }
+ }
+ if (ret == 0) {
+ bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+ }
+ } while ((ret < 0) && retries++ < TXRETRIES);
+ }
+
+done:
+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+ bus->activity = FALSE;
+ dhdsdio_clkctl(bus, CLK_NONE, TRUE);
+ }
+
+ dhd_os_sdunlock(bus->dhd);
+
+ if (ret)
+ bus->dhd->tx_ctlerrs++;
+ else
+ bus->dhd->tx_ctlpkts++;
+
+ if (bus->dhd->txcnt_timeout >= MAX_CNTL_TIMEOUT)
+ return -ETIMEDOUT;
+
+ return ret ? -EIO : 0;
+}
+
+int
+dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
+{
+ int timeleft;
+ uint rxlen = 0;
+ bool pending;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (bus->dhd->dongle_reset)
+ return -EIO;
+
+ /* Wait until control frame is available */
+ timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending);
+
+ dhd_os_sdlock(bus->dhd);
+ rxlen = bus->rxlen;
+ bcopy(bus->rxctl, msg, MIN(msglen, rxlen));
+ bus->rxlen = 0;
+ dhd_os_sdunlock(bus->dhd);
+
+ if (rxlen) {
+ AP6210_DEBUG("%s: resumed on rxctl frame, got %d expected %d\n",
+ __FUNCTION__, rxlen, msglen);
+ } else if (timeleft == 0) {
+#ifdef DHD_DEBUG
+ uint32 status, retry = 0;
+ R_SDREG(status, &bus->regs->intstatus, retry);
+ AP6210_DEBUG("%s: resumed on timeout, INT status=0x%08X\n",
+ __FUNCTION__, status);
+#else
+ AP6210_DEBUG("%s: resumed on timeout\n", __FUNCTION__);
+#endif /* DHD_DEBUG */
+#ifdef DHD_DEBUG
+ dhd_os_sdlock(bus->dhd);
+ dhdsdio_checkdied(bus, NULL, 0);
+ dhd_os_sdunlock(bus->dhd);
+#endif /* DHD_DEBUG */
+ } else if (pending == TRUE) {
+ /* signal pending */
+ AP6210_DEBUG("%s: signal pending\n", __FUNCTION__);
+ return -EINTR;
+ } else {
+ AP6210_DEBUG("%s: resumed for unknown reason?\n", __FUNCTION__);
+#ifdef DHD_DEBUG
+ dhd_os_sdlock(bus->dhd);
+ dhdsdio_checkdied(bus, NULL, 0);
+ dhd_os_sdunlock(bus->dhd);
+#endif /* DHD_DEBUG */
+ }
+ if (timeleft == 0) {
+ bus->dhd->rxcnt_timeout++;
+ AP6210_DEBUG("%s: rxcnt_timeout=%d\n", __FUNCTION__, bus->dhd->rxcnt_timeout);
+ }
+ else
+ bus->dhd->rxcnt_timeout = 0;
+
+ if (rxlen)
+ bus->dhd->rx_ctlpkts++;
+ else
+ bus->dhd->rx_ctlerrs++;
+
+ if (bus->dhd->rxcnt_timeout >= MAX_CNTL_TIMEOUT)
+ return -ETIMEDOUT;
+
+ if (bus->dhd->dongle_trap_occured)
+ return -EREMOTEIO;
+
+ return rxlen ? (int)rxlen : -EIO;
+}
+
+/* IOVar table */
+enum {
+ IOV_INTR = 1,
+ IOV_POLLRATE,
+ IOV_SDREG,
+ IOV_SBREG,
+ IOV_SDCIS,
+ IOV_MEMBYTES,
+ IOV_MEMSIZE,
+#ifdef DHD_DEBUG
+ IOV_CHECKDIED,
+ IOV_SERIALCONS,
+#endif /* DHD_DEBUG */
+ IOV_SET_DOWNLOAD_STATE,
+ IOV_SOCRAM_STATE,
+ IOV_FORCEEVEN,
+ IOV_SDIOD_DRIVE,
+ IOV_READAHEAD,
+ IOV_SDRXCHAIN,
+ IOV_ALIGNCTL,
+ IOV_SDALIGN,
+ IOV_DEVRESET,
+ IOV_CPU,
+#if defined(SDIO_CRC_ERROR_FIX)
+ IOV_WATERMARK,
+ IOV_MESBUSYCTRL,
+#endif /* SDIO_CRC_ERROR_FIX */
+#ifdef SDTEST
+ IOV_PKTGEN,
+ IOV_EXTLOOP,
+#endif /* SDTEST */
+ IOV_SPROM,
+ IOV_TXBOUND,
+ IOV_RXBOUND,
+ IOV_TXMINMAX,
+ IOV_IDLETIME,
+ IOV_IDLECLOCK,
+ IOV_SD1IDLE,
+ IOV_SLEEP,
+ IOV_DONGLEISOLATION,
+ IOV_KSO,
+ IOV_DEVSLEEP,
+ IOV_DEVCAP,
+ IOV_VARS,
+#ifdef SOFTAP
+ IOV_FWPATH,
+#endif
+ IOV_TXGLOMSIZE,
+ IOV_TXGLOMMODE
+};
+
+const bcm_iovar_t dhdsdio_iovars[] = {
+ {"intr", IOV_INTR, 0, IOVT_BOOL, 0 },
+ {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0 },
+ {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0 },
+ {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0 },
+ {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0 },
+ {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0 },
+ {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int) },
+ {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0 },
+ {"dwnldstate", IOV_SET_DOWNLOAD_STATE, 0, IOVT_BOOL, 0 },
+ {"socram_state", IOV_SOCRAM_STATE, 0, IOVT_BOOL, 0 },
+ {"vars", IOV_VARS, 0, IOVT_BUFFER, 0 },
+ {"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0 },
+ {"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0 },
+ {"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0 },
+ {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0 },
+ {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0 },
+ {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0 },
+#ifdef DHD_DEBUG
+ {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
+ {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
+ {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN },
+ {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0 },
+ {"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0 },
+ {"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0 },
+ {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0 },
+ {"cpu", IOV_CPU, 0, IOVT_BOOL, 0 },
+#ifdef DHD_DEBUG
+ {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0 },
+ {"serial", IOV_SERIALCONS, 0, IOVT_UINT32, 0 },
+#endif /* DHD_DEBUG */
+#endif /* DHD_DEBUG */
+#ifdef SDTEST
+ {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0 },
+ {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t) },
+#endif /* SDTEST */
+#if defined(SDIO_CRC_ERROR_FIX)
+ {"watermark", IOV_WATERMARK, 0, IOVT_UINT32, 0 },
+ {"mesbusyctrl", IOV_MESBUSYCTRL, 0, IOVT_UINT32, 0 },
+#endif /* SDIO_CRC_ERROR_FIX */
+ {"devcap", IOV_DEVCAP, 0, IOVT_UINT32, 0 },
+ {"dngl_isolation", IOV_DONGLEISOLATION, 0, IOVT_UINT32, 0 },
+ {"kso", IOV_KSO, 0, IOVT_UINT32, 0 },
+ {"devsleep", IOV_DEVSLEEP, 0, IOVT_UINT32, 0 },
+#ifdef SOFTAP
+ {"fwpath", IOV_FWPATH, 0, IOVT_BUFFER, 0 },
+#endif
+ {"txglomsize", IOV_TXGLOMSIZE, 0, IOVT_UINT32, 0 },
+ {"txglommode", IOV_TXGLOMMODE, 0, IOVT_UINT32, 0 },
+ {NULL, 0, 0, 0, 0 }
+};
+
+static void
+dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div)
+{
+ uint q1, q2;
+
+ if (!div) {
+ bcm_bprintf(strbuf, "%s N/A", desc);
+ } else {
+ q1 = num / div;
+ q2 = (100 * (num - (q1 * div))) / div;
+ bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2);
+ }
+}
+
+void
+dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+ dhd_bus_t *bus = dhdp->bus;
+
+ bcm_bprintf(strbuf, "Bus SDIO structure:\n");
+ bcm_bprintf(strbuf, "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n",
+ bus->hostintmask, bus->intstatus, bus->sdpcm_ver);
+ bcm_bprintf(strbuf, "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n",
+ bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max, bus->rxskip,
+ bus->rxlen, bus->rx_seq);
+ bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n",
+ bus->intr, bus->intrcount, bus->lastintrs, bus->spurious);
+ bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n",
+ bus->pollrate, bus->pollcnt, bus->regfails);
+
+ bcm_bprintf(strbuf, "\nAdditional counters:\n");
+ bcm_bprintf(strbuf, "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n",
+ bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong,
+ bus->rxc_errors);
+ bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n",
+ bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq);
+ bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n",
+ bus->fc_rcvd, bus->fc_xoff, bus->fc_xon);
+ bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n",
+ bus->rxglomfail, bus->rxglomframes, bus->rxglompkts);
+ bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n",
+ (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, bus->f2rxdata,
+ bus->f2txdata, bus->f1regdata);
+ {
+ dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets,
+ (bus->f2rxhdrs + bus->f2rxdata));
+ dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets, bus->f1regdata);
+ dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets,
+ (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata));
+ dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets, bus->intrcount);
+ bcm_bprintf(strbuf, "\n");
+
+ dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts),
+ bus->dhd->rx_packets);
+ dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts, bus->rxglomframes);
+ bcm_bprintf(strbuf, "\n");
+
+ dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets, bus->f2txdata);
+ dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets, bus->f1regdata);
+ dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets,
+ (bus->f2txdata + bus->f1regdata));
+ dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets, bus->intrcount);
+ bcm_bprintf(strbuf, "\n");
+
+ dhd_dump_pct(strbuf, "Total: pkts/f2rw",
+ (bus->dhd->tx_packets + bus->dhd->rx_packets),
+ (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata));
+ dhd_dump_pct(strbuf, ", pkts/f1sd",
+ (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->f1regdata);
+ dhd_dump_pct(strbuf, ", pkts/sd",
+ (bus->dhd->tx_packets + bus->dhd->rx_packets),
+ (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata));
+ dhd_dump_pct(strbuf, ", pkts/int",
+ (bus->dhd->tx_packets + bus->dhd->rx_packets), bus->intrcount);
+ bcm_bprintf(strbuf, "\n\n");
+ }
+
+#ifdef SDTEST
+ if (bus->pktgen_count) {
+ bcm_bprintf(strbuf, "pktgen config and count:\n");
+ bcm_bprintf(strbuf, "freq %d count %d print %d total %d min %d len %d\n",
+ bus->pktgen_freq, bus->pktgen_count, bus->pktgen_print,
+ bus->pktgen_total, bus->pktgen_minlen, bus->pktgen_maxlen);
+ bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n",
+ bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail);
+ }
+#endif /* SDTEST */
+#ifdef DHD_DEBUG
+ bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n",
+ bus->dpc_sched, (bcmsdh_intr_pending(bus->sdh) ? " " : " not "));
+ bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, bus->roundup);
+#endif /* DHD_DEBUG */
+ bcm_bprintf(strbuf, "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n",
+ bus->clkstate, bus->activity, bus->idletime, bus->idlecount, bus->sleeping);
+}
+
+void
+dhd_bus_clearcounts(dhd_pub_t *dhdp)
+{
+ dhd_bus_t *bus = (dhd_bus_t *)dhdp->bus;
+
+ bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0;
+ bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0;
+ bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0;
+ bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0;
+ bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0;
+ bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0;
+}
+
+#ifdef SDTEST
+static int
+dhdsdio_pktgen_get(dhd_bus_t *bus, uint8 *arg)
+{
+ dhd_pktgen_t pktgen;
+
+ pktgen.version = DHD_PKTGEN_VERSION;
+ pktgen.freq = bus->pktgen_freq;
+ pktgen.count = bus->pktgen_count;
+ pktgen.print = bus->pktgen_print;
+ pktgen.total = bus->pktgen_total;
+ pktgen.minlen = bus->pktgen_minlen;
+ pktgen.maxlen = bus->pktgen_maxlen;
+ pktgen.numsent = bus->pktgen_sent;
+ pktgen.numrcvd = bus->pktgen_rcvd;
+ pktgen.numfail = bus->pktgen_fail;
+ pktgen.mode = bus->pktgen_mode;
+ pktgen.stop = bus->pktgen_stop;
+
+ bcopy(&pktgen, arg, sizeof(pktgen));
+
+ return 0;
+}
+
+static int
+dhdsdio_pktgen_set(dhd_bus_t *bus, uint8 *arg)
+{
+ dhd_pktgen_t pktgen;
+ uint oldcnt, oldmode;
+
+ bcopy(arg, &pktgen, sizeof(pktgen));
+ if (pktgen.version != DHD_PKTGEN_VERSION)
+ return BCME_BADARG;
+
+ oldcnt = bus->pktgen_count;
+ oldmode = bus->pktgen_mode;
+
+ bus->pktgen_freq = pktgen.freq;
+ bus->pktgen_count = pktgen.count;
+ bus->pktgen_print = pktgen.print;
+ bus->pktgen_total = pktgen.total;
+ bus->pktgen_minlen = pktgen.minlen;
+ bus->pktgen_maxlen = pktgen.maxlen;
+ bus->pktgen_mode = pktgen.mode;
+ bus->pktgen_stop = pktgen.stop;
+
+ bus->pktgen_tick = bus->pktgen_ptick = 0;
+ bus->pktgen_prev_time = jiffies;
+ bus->pktgen_len = MAX(bus->pktgen_len, bus->pktgen_minlen);
+ bus->pktgen_len = MIN(bus->pktgen_len, bus->pktgen_maxlen);
+
+ /* Clear counts for a new pktgen (mode change, or was stopped) */
+ if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode)) {
+ bus->pktgen_sent = bus->pktgen_prev_sent = bus->pktgen_rcvd = 0;
+ bus->pktgen_prev_rcvd = bus->pktgen_fail = 0;
+ }
+
+ return 0;
+}
+#endif /* SDTEST */
+
+static void
+dhdsdio_devram_remap(dhd_bus_t *bus, bool val)
+{
+ uint8 enable, protect, remap;
+
+ si_socdevram(bus->sih, FALSE, &enable, &protect, &remap);
+ remap = val ? TRUE : FALSE;
+ si_socdevram(bus->sih, TRUE, &enable, &protect, &remap);
+}
+
+static int
+dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint size)
+{
+ int bcmerror = 0;
+ uint32 sdaddr;
+ uint dsize;
+
+ /* In remap mode, adjust address beyond socram and redirect
+ * to devram at SOCDEVRAM_BP_ADDR since remap address > orig_ramsize
+ * is not backplane accessible
+ */
+ if (REMAP_ENAB(bus) && REMAP_ISADDR(bus, address)) {
+ address -= bus->orig_ramsize;
+ address += SOCDEVRAM_BP_ADDR;
+ }
+
+ /* Determine initial transfer parameters */
+ sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
+ if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
+ dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
+ else
+ dsize = size;
+
+ /* Set the backplane window to include the start address */
+ if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) {
+ AP6210_ERR("%s: window change failed\n", __FUNCTION__);
+ goto xfer_done;
+ }
+
+ /* Do the transfer(s) */
+ while (size) {
+ AP6210_DEBUG("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n",
+ __FUNCTION__, (write ? "write" : "read"), dsize, sdaddr,
+ (address & SBSDIO_SBWINDOW_MASK));
+ if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize))) {
+ AP6210_ERR("%s: membytes transfer failed\n", __FUNCTION__);
+ break;
+ }
+
+ /* Adjust for next transfer (if any) */
+ if ((size -= dsize)) {
+ data += dsize;
+ address += dsize;
+ if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) {
+ AP6210_ERR("%s: window change failed\n", __FUNCTION__);
+ break;
+ }
+ sdaddr = 0;
+ dsize = MIN(SBSDIO_SB_OFT_ADDR_LIMIT, size);
+ }
+
+ }
+
+xfer_done:
+ /* Return the window to backplane enumeration space for core access */
+ if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) {
+ AP6210_ERR("%s: FAILED to set window back to 0x%x\n", __FUNCTION__,
+ bcmsdh_cur_sbwad(bus->sdh));
+ }
+
+ return bcmerror;
+}
+
+#ifdef DHD_DEBUG
+static int
+dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh)
+{
+ uint32 addr;
+ int rv, i;
+ uint32 shaddr = 0;
+
+ shaddr = bus->dongle_ram_base + bus->ramsize - 4;
+ i = 0;
+ do {
+ /* Read last word in memory to determine address of sdpcm_shared structure */
+ if ((rv = dhdsdio_membytes(bus, FALSE, shaddr, (uint8 *)&addr, 4)) < 0)
+ return rv;
+
+ addr = ltoh32(addr);
+
+ AP6210_DEBUG("sdpcm_shared address 0x%08X\n", addr);
+
+ /*
+ * Check if addr is valid.
+ * NVRAM length at the end of memory should have been overwritten.
+ */
+ if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) {
+ if ((bus->srmemsize > 0) && (i++ == 0)) {
+ shaddr -= bus->srmemsize;
+ } else {
+ AP6210_ERR("%s: address (0x%08x) of sdpcm_shared invalid\n",
+ __FUNCTION__, addr);
+ return BCME_ERROR;
+ }
+ } else
+ break;
+ } while (i < 2);
+
+ /* Read hndrte_shared structure */
+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)sh, sizeof(sdpcm_shared_t))) < 0)
+ return rv;
+
+ /* Endianness */
+ sh->flags = ltoh32(sh->flags);
+ sh->trap_addr = ltoh32(sh->trap_addr);
+ sh->assert_exp_addr = ltoh32(sh->assert_exp_addr);
+ sh->assert_file_addr = ltoh32(sh->assert_file_addr);
+ sh->assert_line = ltoh32(sh->assert_line);
+ sh->console_addr = ltoh32(sh->console_addr);
+ sh->msgtrace_addr = ltoh32(sh->msgtrace_addr);
+
+ if ((sh->flags & SDPCM_SHARED_VERSION_MASK) == 3 && SDPCM_SHARED_VERSION == 1)
+ return BCME_OK;
+
+ if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
+ AP6210_ERR("%s: sdpcm_shared version %d in dhd "
+ "is different than sdpcm_shared version %d in dongle\n",
+ __FUNCTION__, SDPCM_SHARED_VERSION,
+ sh->flags & SDPCM_SHARED_VERSION_MASK);
+ return BCME_ERROR;
+ }
+
+ return BCME_OK;
+}
+
+#define CONSOLE_LINE_MAX 192
+
+static int
+dhdsdio_readconsole(dhd_bus_t *bus)
+{
+ dhd_console_t *c = &bus->console;
+ uint8 line[CONSOLE_LINE_MAX], ch;
+ uint32 n, idx, addr;
+ int rv;
+
+ /* Don't do anything until FWREADY updates console address */
+ if (bus->console_addr == 0)
+ return 0;
+
+ if (!KSO_ENAB(bus))
+ return 0;
+
+ /* Read console log struct */
+ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, log);
+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&c->log, sizeof(c->log))) < 0)
+ return rv;
+
+ /* Allocate console buffer (one time only) */
+ if (c->buf == NULL) {
+ c->bufsize = ltoh32(c->log.buf_size);
+ if ((c->buf = MALLOC(bus->dhd->osh, c->bufsize)) == NULL)
+ return BCME_NOMEM;
+ }
+
+ idx = ltoh32(c->log.idx);
+
+ /* Protect against corrupt value */
+ if (idx > c->bufsize)
+ return BCME_ERROR;
+
+ /* Skip reading the console buffer if the index pointer has not moved */
+ if (idx == c->last)
+ return BCME_OK;
+
+ /* Read the console buffer */
+ addr = ltoh32(c->log.buf);
+ if ((rv = dhdsdio_membytes(bus, FALSE, addr, c->buf, c->bufsize)) < 0)
+ return rv;
+
+ while (c->last != idx) {
+ for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
+ if (c->last == idx) {
+ /* This would output a partial line. Instead, back up
+ * the buffer pointer and output this line next time around.
+ */
+ if (c->last >= n)
+ c->last -= n;
+ else
+ c->last = c->bufsize - n;
+ goto break2;
+ }
+ ch = c->buf[c->last];
+ c->last = (c->last + 1) % c->bufsize;
+ if (ch == '\n')
+ break;
+ line[n] = ch;
+ }
+
+ if (n > 0) {
+ if (line[n - 1] == '\r')
+ n--;
+ line[n] = 0;
+ AP6210_DEBUG("CONSOLE: %s\n", line);
+ }
+ }
+break2:
+
+ return BCME_OK;
+}
+
+static int
+dhdsdio_checkdied(dhd_bus_t *bus, char *data, uint size)
+{
+ int bcmerror = 0;
+ uint msize = 512;
+ char *mbuffer = NULL;
+ char *console_buffer = NULL;
+ uint maxstrlen = 256;
+ char *str = NULL;
+ trap_t tr;
+ sdpcm_shared_t sdpcm_shared;
+ struct bcmstrbuf strbuf;
+ uint32 console_ptr, console_size, console_index;
+ uint8 line[CONSOLE_LINE_MAX], ch;
+ uint32 n, i, addr;
+ int rv;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (data == NULL) {
+ /*
+ * Called after a rx ctrl timeout. "data" is NULL.
+ * allocate memory to trace the trap or assert.
+ */
+ size = msize;
+ mbuffer = data = MALLOC(bus->dhd->osh, msize);
+ if (mbuffer == NULL) {
+ AP6210_ERR("%s: MALLOC(%d) failed \n", __FUNCTION__, msize);
+ bcmerror = BCME_NOMEM;
+ goto done;
+ }
+ }
+
+ if ((str = MALLOC(bus->dhd->osh, maxstrlen)) == NULL) {
+ AP6210_ERR("%s: MALLOC(%d) failed \n", __FUNCTION__, maxstrlen);
+ bcmerror = BCME_NOMEM;
+ goto done;
+ }
+
+ if ((bcmerror = dhdsdio_readshared(bus, &sdpcm_shared)) < 0)
+ goto done;
+
+ bcm_binit(&strbuf, data, size);
+
+ bcm_bprintf(&strbuf, "msgtrace address : 0x%08X\nconsole address : 0x%08X\n",
+ sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr);
+
+ if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
+ /* NOTE: Misspelled assert is intentional - DO NOT FIX.
+ * (Avoids conflict with real asserts for programmatic parsing of output.)
+ */
+ bcm_bprintf(&strbuf, "Assrt not built in dongle\n");
+ }
+
+ if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT|SDPCM_SHARED_TRAP)) == 0) {
+ /* NOTE: Misspelled assert is intentional - DO NOT FIX.
+ * (Avoids conflict with real asserts for programmatic parsing of output.)
+ */
+ bcm_bprintf(&strbuf, "No trap%s in dongle",
+ (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT)
+ ?"/assrt" :"");
+ } else {
+ if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) {
+ /* Download assert */
+ bcm_bprintf(&strbuf, "Dongle assert");
+ if (sdpcm_shared.assert_exp_addr != 0) {
+ str[0] = '\0';
+ if ((bcmerror = dhdsdio_membytes(bus, FALSE,
+ sdpcm_shared.assert_exp_addr,
+ (uint8 *)str, maxstrlen)) < 0)
+ goto done;
+
+ str[maxstrlen - 1] = '\0';
+ bcm_bprintf(&strbuf, " expr \"%s\"", str);
+ }
+
+ if (sdpcm_shared.assert_file_addr != 0) {
+ str[0] = '\0';
+ if ((bcmerror = dhdsdio_membytes(bus, FALSE,
+ sdpcm_shared.assert_file_addr,
+ (uint8 *)str, maxstrlen)) < 0)
+ goto done;
+
+ str[maxstrlen - 1] = '\0';
+ bcm_bprintf(&strbuf, " file \"%s\"", str);
+ }
+
+ bcm_bprintf(&strbuf, " line %d ", sdpcm_shared.assert_line);
+ }
+
+ if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
+ bus->dhd->dongle_trap_occured = TRUE;
+ if ((bcmerror = dhdsdio_membytes(bus, FALSE,
+ sdpcm_shared.trap_addr,
+ (uint8*)&tr, sizeof(trap_t))) < 0)
+ goto done;
+
+ bcm_bprintf(&strbuf,
+ "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x,"
+ "lp 0x%x, rpc 0x%x Trap offset 0x%x, "
+ "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\n",
+ ltoh32(tr.type), ltoh32(tr.epc), ltoh32(tr.cpsr), ltoh32(tr.spsr),
+ ltoh32(tr.r13), ltoh32(tr.r14), ltoh32(tr.pc),
+ ltoh32(sdpcm_shared.trap_addr),
+ ltoh32(tr.r0), ltoh32(tr.r1), ltoh32(tr.r2), ltoh32(tr.r3),
+ ltoh32(tr.r4), ltoh32(tr.r5), ltoh32(tr.r6), ltoh32(tr.r7));
+
+ addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log);
+ if ((rv = dhdsdio_membytes(bus, FALSE, addr,
+ (uint8 *)&console_ptr, sizeof(console_ptr))) < 0)
+ goto printbuf;
+
+ addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log.buf_size);
+ if ((rv = dhdsdio_membytes(bus, FALSE, addr,
+ (uint8 *)&console_size, sizeof(console_size))) < 0)
+ goto printbuf;
+
+ addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log.idx);
+ if ((rv = dhdsdio_membytes(bus, FALSE, addr,
+ (uint8 *)&console_index, sizeof(console_index))) < 0)
+ goto printbuf;
+
+ console_ptr = ltoh32(console_ptr);
+ console_size = ltoh32(console_size);
+ console_index = ltoh32(console_index);
+
+ if (console_size > CONSOLE_BUFFER_MAX ||
+ !(console_buffer = MALLOC(bus->dhd->osh, console_size)))
+ goto printbuf;
+
+ if ((rv = dhdsdio_membytes(bus, FALSE, console_ptr,
+ (uint8 *)console_buffer, console_size)) < 0)
+ goto printbuf;
+
+ for (i = 0, n = 0; i < console_size; i += n + 1) {
+ for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
+ ch = console_buffer[(console_index + i + n) % console_size];
+ if (ch == '\n')
+ break;
+ line[n] = ch;
+ }
+
+
+ if (n > 0) {
+ if (line[n - 1] == '\r')
+ n--;
+ line[n] = 0;
+ /* Don't use DHD_ERROR macro since we print
+ * a lot of information quickly. The macro
+ * will truncate a lot of the printfs
+ */
+
+ if (dhd_msg_level & DHD_ERROR_VAL)
+ AP6210_DEBUG("CONSOLE: %s\n", line);
+ }
+ }
+ }
+ }
+
+printbuf:
+ if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) {
+ AP6210_DEBUG("%s: %s\n", __FUNCTION__, strbuf.origbuf);
+ }
+
+
+done:
+ if (mbuffer)
+ MFREE(bus->dhd->osh, mbuffer, msize);
+ if (str)
+ MFREE(bus->dhd->osh, str, maxstrlen);
+ if (console_buffer)
+ MFREE(bus->dhd->osh, console_buffer, console_size);
+
+ return bcmerror;
+}
+#endif /* #ifdef DHD_DEBUG */
+
+
+int
+dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len)
+{
+ int bcmerror = BCME_OK;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ /* Basic sanity checks */
+ if (bus->dhd->up) {
+ bcmerror = BCME_NOTDOWN;
+ goto err;
+ }
+ if (!len) {
+ bcmerror = BCME_BUFTOOSHORT;
+ goto err;
+ }
+
+ /* Free the old ones and replace with passed variables */
+ if (bus->vars)
+ MFREE(bus->dhd->osh, bus->vars, bus->varsz);
+
+ bus->vars = MALLOC(bus->dhd->osh, len);
+ bus->varsz = bus->vars ? len : 0;
+ if (bus->vars == NULL) {
+ bcmerror = BCME_NOMEM;
+ goto err;
+ }
+
+ /* Copy the passed variables, which should include the terminating double-null */
+ bcopy(arg, bus->vars, bus->varsz);
+err:
+ return bcmerror;
+}
+
+#ifdef DHD_DEBUG
+
+#define CC_PLL_CHIPCTRL_SERIAL_ENAB (1 << 24)
+#define CC_CHIPCTRL_JTAG_SEL (1 << 3)
+#define CC_CHIPCTRL_GPIO_SEL (0x3)
+#define CC_PLL_CHIPCTRL_SERIAL_ENAB_4334 (1 << 28)
+
+static int
+dhd_serialconsole(dhd_bus_t *bus, bool set, bool enable, int *bcmerror)
+{
+ int int_val;
+ uint32 addr, data, uart_enab = 0;
+ uint32 jtag_sel = CC_CHIPCTRL_JTAG_SEL;
+ uint32 gpio_sel = CC_CHIPCTRL_GPIO_SEL;
+
+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_addr);
+ data = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol_data);
+ *bcmerror = 0;
+
+ bcmsdh_reg_write(bus->sdh, addr, 4, 1);
+ if (bcmsdh_regfail(bus->sdh)) {
+ *bcmerror = BCME_SDIO_ERROR;
+ return -1;
+ }
+ int_val = bcmsdh_reg_read(bus->sdh, data, 4);
+ if (bcmsdh_regfail(bus->sdh)) {
+ *bcmerror = BCME_SDIO_ERROR;
+ return -1;
+ }
+ if (bus->sih->chip == BCM4330_CHIP_ID) {
+ uart_enab = CC_PLL_CHIPCTRL_SERIAL_ENAB;
+ }
+ else if (bus->sih->chip == BCM4334_CHIP_ID ||
+ bus->sih->chip == BCM43341_CHIP_ID) {
+ if (enable) {
+ /* Moved to PMU chipcontrol 1 from 4330 */
+ int_val &= ~gpio_sel;
+ int_val |= jtag_sel;
+ } else {
+ int_val |= gpio_sel;
+ int_val &= ~jtag_sel;
+ }
+ uart_enab = CC_PLL_CHIPCTRL_SERIAL_ENAB_4334;
+ }
+
+ if (!set)
+ return (int_val & uart_enab);
+ if (enable)
+ int_val |= uart_enab;
+ else
+ int_val &= ~uart_enab;
+ bcmsdh_reg_write(bus->sdh, data, 4, int_val);
+ if (bcmsdh_regfail(bus->sdh)) {
+ *bcmerror = BCME_SDIO_ERROR;
+ return -1;
+ }
+ if (bus->sih->chip == BCM4330_CHIP_ID) {
+ uint32 chipcontrol;
+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, chipcontrol);
+ chipcontrol = bcmsdh_reg_read(bus->sdh, addr, 4);
+ chipcontrol &= ~jtag_sel;
+ if (enable) {
+ chipcontrol |= jtag_sel;
+ chipcontrol &= ~gpio_sel;
+ }
+ bcmsdh_reg_write(bus->sdh, addr, 4, chipcontrol);
+ }
+
+ return (int_val & uart_enab);
+}
+#endif
+
+static int
+dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name,
+ void *params, int plen, void *arg, int len, int val_size)
+{
+ int bcmerror = 0;
+ int32 int_val = 0;
+ bool bool_val = 0;
+
+ AP6210_DEBUG("%s: Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n",
+ __FUNCTION__, actionid, name, params, plen, arg, len, val_size);
+
+ if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0)
+ goto exit;
+
+ if (plen >= (int)sizeof(int_val))
+ bcopy(params, &int_val, sizeof(int_val));
+
+ bool_val = (int_val != 0) ? TRUE : FALSE;
+
+
+ /* Some ioctls use the bus */
+ dhd_os_sdlock(bus->dhd);
+
+ /* Check if dongle is in reset. If so, only allow DEVRESET iovars */
+ if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) ||
+ actionid == IOV_GVAL(IOV_DEVRESET))) {
+ bcmerror = BCME_NOTREADY;
+ goto exit;
+ }
+
+ /*
+ * Special handling for keepSdioOn: New SDIO Wake-up Mechanism
+ */
+ if ((vi->varid == IOV_KSO) && (IOV_ISSET(actionid))) {
+ dhdsdio_clk_kso_iovar(bus, bool_val);
+ goto exit;
+ } else if ((vi->varid == IOV_DEVSLEEP) && (IOV_ISSET(actionid))) {
+ {
+ dhdsdio_clk_devsleep_iovar(bus, bool_val);
+ if (!SLPAUTO_ENAB(bus) && (bool_val == FALSE) && (bus->ipend)) {
+ AP6210_DEBUG("INT pending in devsleep 1, dpc_sched: %d\n",
+ bus->dpc_sched);
+ if (!bus->dpc_sched) {
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd);
+ }
+ }
+ }
+ goto exit;
+ }
+
+ /* Handle sleep stuff before any clock mucking */
+ if (vi->varid == IOV_SLEEP) {
+ if (IOV_ISSET(actionid)) {
+ bcmerror = dhdsdio_bussleep(bus, bool_val);
+ } else {
+ int_val = (int32)bus->sleeping;
+ bcopy(&int_val, arg, val_size);
+ }
+ goto exit;
+ }
+
+ /* Request clock to allow SDIO accesses */
+ if (!bus->dhd->dongle_reset) {
+ BUS_WAKE(bus);
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+ }
+
+ switch (actionid) {
+ case IOV_GVAL(IOV_INTR):
+ int_val = (int32)bus->intr;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_INTR):
+ bus->intr = bool_val;
+ bus->intdis = FALSE;
+ if (bus->dhd->up) {
+ if (bus->intr) {
+ AP6210_DEBUG("%s: enable SDIO device interrupts\n", __FUNCTION__);
+ bcmsdh_intr_enable(bus->sdh);
+ } else {
+ AP6210_DEBUG("%s: disable SDIO interrupts\n", __FUNCTION__);
+ bcmsdh_intr_disable(bus->sdh);
+ }
+ }
+ break;
+
+ case IOV_GVAL(IOV_POLLRATE):
+ int_val = (int32)bus->pollrate;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_POLLRATE):
+ bus->pollrate = (uint)int_val;
+ bus->poll = (bus->pollrate != 0);
+ break;
+
+ case IOV_GVAL(IOV_IDLETIME):
+ int_val = bus->idletime;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_IDLETIME):
+ if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE)) {
+ bcmerror = BCME_BADARG;
+ } else {
+ bus->idletime = int_val;
+ }
+ break;
+
+ case IOV_GVAL(IOV_IDLECLOCK):
+ int_val = (int32)bus->idleclock;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_IDLECLOCK):
+ bus->idleclock = int_val;
+ break;
+
+ case IOV_GVAL(IOV_SD1IDLE):
+ int_val = (int32)sd1idle;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_SD1IDLE):
+ sd1idle = bool_val;
+ break;
+
+
+ case IOV_SVAL(IOV_MEMBYTES):
+ case IOV_GVAL(IOV_MEMBYTES):
+ {
+ uint32 address;
+ uint size, dsize;
+ uint8 *data;
+
+ bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
+
+ ASSERT(plen >= 2*sizeof(int));
+
+ address = (uint32)int_val;
+ bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val));
+ size = (uint)int_val;
+
+ /* Do some validation */
+ dsize = set ? plen - (2 * sizeof(int)) : len;
+ if (dsize < size) {
+ AP6210_ERR("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n",
+ __FUNCTION__, (set ? "set" : "get"), address, size, dsize);
+ bcmerror = BCME_BADARG;
+ break;
+ }
+
+ AP6210_DEBUG("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__,
+ (set ? "write" : "read"), size, address);
+
+ /* If we know about SOCRAM, check for a fit */
+ if ((bus->orig_ramsize) &&
+ ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize)))
+ {
+ uint8 enable, protect, remap;
+ si_socdevram(bus->sih, FALSE, &enable, &protect, &remap);
+ if (!enable || protect) {
+ AP6210_ERR("%s: ramsize 0x%08x doesn't have %d bytes at 0x%08x\n",
+ __FUNCTION__, bus->orig_ramsize, size, address);
+ AP6210_DEBUG("%s: socram enable %d, protect %d\n",
+ __FUNCTION__, enable, protect);
+ bcmerror = BCME_BADARG;
+ break;
+ }
+
+ if (!REMAP_ENAB(bus) && (address >= SOCDEVRAM_ARM_ADDR)) {
+ uint32 devramsize = si_socdevram_size(bus->sih);
+ if ((address < SOCDEVRAM_ARM_ADDR) ||
+ (address + size > (SOCDEVRAM_ARM_ADDR + devramsize))) {
+ AP6210_ERR("%s: bad address 0x%08x, size 0x%08x\n",
+ __FUNCTION__, address, size);
+ AP6210_DEBUG("%s: socram range 0x%08x,size 0x%08x\n",
+ __FUNCTION__, SOCDEVRAM_ARM_ADDR, devramsize);
+ bcmerror = BCME_BADARG;
+ break;
+ }
+ /* move it such that address is real now */
+ address -= SOCDEVRAM_ARM_ADDR;
+ address += SOCDEVRAM_BP_ADDR;
+ AP6210_DEBUG("%s: Request to %s %d bytes @ Mapped address 0x%08x\n",
+ __FUNCTION__, (set ? "write" : "read"), size, address);
+ } else if (REMAP_ENAB(bus) && REMAP_ISADDR(bus, address) && remap) {
+ /* Can not access remap region while devram remap bit is set
+ * ROM content would be returned in this case
+ */
+ AP6210_ERR("%s: Need to disable remap for address 0x%08x\n",
+ __FUNCTION__, address);
+ bcmerror = BCME_ERROR;
+ break;
+ }
+ }
+
+ /* Generate the actual data pointer */
+ data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg;
+
+ /* Call to do the transfer */
+ bcmerror = dhdsdio_membytes(bus, set, address, data, size);
+
+ break;
+ }
+
+ case IOV_GVAL(IOV_MEMSIZE):
+ int_val = (int32)bus->ramsize;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_GVAL(IOV_SDIOD_DRIVE):
+ int_val = (int32)dhd_sdiod_drive_strength;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_SDIOD_DRIVE):
+ dhd_sdiod_drive_strength = int_val;
+ si_sdiod_drive_strength_init(bus->sih, bus->dhd->osh, dhd_sdiod_drive_strength);
+ break;
+
+ case IOV_SVAL(IOV_SET_DOWNLOAD_STATE):
+ bcmerror = dhdsdio_download_state(bus, bool_val);
+ break;
+
+ case IOV_SVAL(IOV_SOCRAM_STATE):
+ bcmerror = dhdsdio_download_state(bus, bool_val);
+ break;
+
+ case IOV_SVAL(IOV_VARS):
+ bcmerror = dhdsdio_downloadvars(bus, arg, len);
+ break;
+
+ case IOV_GVAL(IOV_READAHEAD):
+ int_val = (int32)dhd_readahead;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_READAHEAD):
+ if (bool_val && !dhd_readahead)
+ bus->nextlen = 0;
+ dhd_readahead = bool_val;
+ break;
+
+ case IOV_GVAL(IOV_SDRXCHAIN):
+ int_val = (int32)bus->use_rxchain;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_SDRXCHAIN):
+ if (bool_val && !bus->sd_rxchain)
+ bcmerror = BCME_UNSUPPORTED;
+ else
+ bus->use_rxchain = bool_val;
+ break;
+ case IOV_GVAL(IOV_ALIGNCTL):
+ int_val = (int32)dhd_alignctl;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_ALIGNCTL):
+ dhd_alignctl = bool_val;
+ break;
+
+ case IOV_GVAL(IOV_SDALIGN):
+ int_val = DHD_SDALIGN;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+#ifdef DHD_DEBUG
+ case IOV_GVAL(IOV_VARS):
+ if (bus->varsz < (uint)len)
+ bcopy(bus->vars, arg, bus->varsz);
+ else
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+#endif /* DHD_DEBUG */
+
+#ifdef DHD_DEBUG
+ case IOV_GVAL(IOV_SDREG):
+ {
+ sdreg_t *sd_ptr;
+ uint32 addr, size;
+
+ sd_ptr = (sdreg_t *)params;
+
+ addr = (uintptr)bus->regs + sd_ptr->offset;
+ size = sd_ptr->func;
+ int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size);
+ if (bcmsdh_regfail(bus->sdh))
+ bcmerror = BCME_SDIO_ERROR;
+ bcopy(&int_val, arg, sizeof(int32));
+ break;
+ }
+
+ case IOV_SVAL(IOV_SDREG):
+ {
+ sdreg_t *sd_ptr;
+ uint32 addr, size;
+
+ sd_ptr = (sdreg_t *)params;
+
+ addr = (uintptr)bus->regs + sd_ptr->offset;
+ size = sd_ptr->func;
+ bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value);
+ if (bcmsdh_regfail(bus->sdh))
+ bcmerror = BCME_SDIO_ERROR;
+ break;
+ }
+
+ /* Same as above, but offset is not backplane (not SDIO core) */
+ case IOV_GVAL(IOV_SBREG):
+ {
+ sdreg_t sdreg;
+ uint32 addr, size;
+
+ bcopy(params, &sdreg, sizeof(sdreg));
+
+ addr = SI_ENUM_BASE + sdreg.offset;
+ size = sdreg.func;
+ int_val = (int32)bcmsdh_reg_read(bus->sdh, addr, size);
+ if (bcmsdh_regfail(bus->sdh))
+ bcmerror = BCME_SDIO_ERROR;
+ bcopy(&int_val, arg, sizeof(int32));
+ break;
+ }
+
+ case IOV_SVAL(IOV_SBREG):
+ {
+ sdreg_t sdreg;
+ uint32 addr, size;
+
+ bcopy(params, &sdreg, sizeof(sdreg));
+
+ addr = SI_ENUM_BASE + sdreg.offset;
+ size = sdreg.func;
+ bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value);
+ if (bcmsdh_regfail(bus->sdh))
+ bcmerror = BCME_SDIO_ERROR;
+ break;
+ }
+
+ case IOV_GVAL(IOV_SDCIS):
+ {
+ *(char *)arg = 0;
+
+ bcmstrcat(arg, "\nFunc 0\n");
+ bcmsdh_cis_read(bus->sdh, 0x10, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT);
+ bcmstrcat(arg, "\nFunc 1\n");
+ bcmsdh_cis_read(bus->sdh, 0x11, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT);
+ bcmstrcat(arg, "\nFunc 2\n");
+ bcmsdh_cis_read(bus->sdh, 0x12, (uint8 *)arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT);
+ break;
+ }
+
+ case IOV_GVAL(IOV_FORCEEVEN):
+ int_val = (int32)forcealign;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_FORCEEVEN):
+ forcealign = bool_val;
+ break;
+
+ case IOV_GVAL(IOV_TXBOUND):
+ int_val = (int32)dhd_txbound;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_TXBOUND):
+ dhd_txbound = (uint)int_val;
+ break;
+
+ case IOV_GVAL(IOV_RXBOUND):
+ int_val = (int32)dhd_rxbound;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_RXBOUND):
+ dhd_rxbound = (uint)int_val;
+ break;
+
+ case IOV_GVAL(IOV_TXMINMAX):
+ int_val = (int32)dhd_txminmax;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_TXMINMAX):
+ dhd_txminmax = (uint)int_val;
+ break;
+
+ case IOV_GVAL(IOV_SERIALCONS):
+ int_val = dhd_serialconsole(bus, FALSE, 0, &bcmerror);
+ if (bcmerror != 0)
+ break;
+
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_SERIALCONS):
+ dhd_serialconsole(bus, TRUE, bool_val, &bcmerror);
+ break;
+
+
+
+#endif /* DHD_DEBUG */
+
+
+#ifdef SDTEST
+ case IOV_GVAL(IOV_EXTLOOP):
+ int_val = (int32)bus->ext_loop;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_EXTLOOP):
+ bus->ext_loop = bool_val;
+ break;
+
+ case IOV_GVAL(IOV_PKTGEN):
+ bcmerror = dhdsdio_pktgen_get(bus, arg);
+ break;
+
+ case IOV_SVAL(IOV_PKTGEN):
+ bcmerror = dhdsdio_pktgen_set(bus, arg);
+ break;
+#endif /* SDTEST */
+
+#if defined(SDIO_CRC_ERROR_FIX)
+ case IOV_GVAL(IOV_WATERMARK):
+ int_val = (int32)watermark;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_WATERMARK):
+ watermark = (uint)int_val;
+ watermark = (watermark > SBSDIO_WATERMARK_MASK) ? SBSDIO_WATERMARK_MASK : watermark;
+ AP6210_DEBUG("Setting watermark as 0x%x.\n", watermark);
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, NULL);
+ break;
+
+ case IOV_GVAL(IOV_MESBUSYCTRL):
+ int_val = (int32)mesbusyctrl;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_MESBUSYCTRL):
+ mesbusyctrl = (uint)int_val;
+ mesbusyctrl = (mesbusyctrl > SBSDIO_MESBUSYCTRL_MASK)
+ ? SBSDIO_MESBUSYCTRL_MASK : mesbusyctrl;
+ AP6210_DEBUG("Setting mesbusyctrl as 0x%x.\n", mesbusyctrl);
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL,
+ ((uint8)mesbusyctrl | 0x80), NULL);
+ break;
+#endif /* SDIO_CRC_ERROR_FIX */
+
+ case IOV_GVAL(IOV_DONGLEISOLATION):
+ int_val = bus->dhd->dongle_isolation;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_DONGLEISOLATION):
+ bus->dhd->dongle_isolation = bool_val;
+ break;
+
+ case IOV_SVAL(IOV_DEVRESET):
+ AP6210_DEBUG("%s: Called set IOV_DEVRESET=%d dongle_reset=%d busstate=%d\n",
+ __FUNCTION__, bool_val, bus->dhd->dongle_reset,
+ bus->dhd->busstate);
+
+ ASSERT(bus->dhd->osh);
+ /* ASSERT(bus->cl_devid); */
+
+ dhd_bus_devreset(bus->dhd, (uint8)bool_val);
+
+ break;
+#ifdef SOFTAP
+ case IOV_GVAL(IOV_FWPATH):
+ {
+ uint32 fw_path_len;
+
+ fw_path_len = strlen(bus->fw_path);
+ AP6210_DEBUG("[softap] get fwpath, l=%d\n", len);
+
+ if (fw_path_len > len-1) {
+ bcmerror = BCME_BUFTOOSHORT;
+ break;
+ }
+
+ if (fw_path_len) {
+ bcopy(bus->fw_path, arg, fw_path_len);
+ ((uchar*)arg)[fw_path_len] = 0;
+ }
+ break;
+ }
+
+ case IOV_SVAL(IOV_FWPATH):
+ AP6210_DEBUG("[softap] set fwpath, idx=%d\n", int_val);
+
+ switch (int_val) {
+ case 1:
+ bus->fw_path = fw_path; /* ordinary one */
+ break;
+ case 2:
+ bus->fw_path = fw_path2;
+ break;
+ default:
+ bcmerror = BCME_BADARG;
+ break;
+ }
+
+ AP6210_DEBUG("[softap] new fw path: %s\n", (bus->fw_path[0] ? bus->fw_path : "NULL"));
+ break;
+
+#endif /* SOFTAP */
+ case IOV_GVAL(IOV_DEVRESET):
+ AP6210_DEBUG("%s: Called get IOV_DEVRESET\n", __FUNCTION__);
+
+ /* Get its status */
+ int_val = (bool) bus->dhd->dongle_reset;
+ bcopy(&int_val, arg, val_size);
+
+ break;
+
+ case IOV_GVAL(IOV_KSO):
+ int_val = dhdsdio_sleepcsr_get(bus);
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_GVAL(IOV_DEVCAP):
+ int_val = dhdsdio_devcap_get(bus);
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_DEVCAP):
+ dhdsdio_devcap_set(bus, (uint8) int_val);
+ break;
+
+#ifdef BCMSDIOH_TXGLOM
+ case IOV_GVAL(IOV_TXGLOMSIZE):
+ int_val = (int32)bus->glomsize;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_TXGLOMSIZE):
+ if (int_val > SDPCM_MAXGLOM_SIZE) {
+ bcmerror = BCME_ERROR;
+ } else {
+ bus->glomsize = (uint)int_val;
+ }
+ break;
+ case IOV_GVAL(IOV_TXGLOMMODE):
+ int_val = (int32)bus->glom_mode;
+ bcopy(&int_val, arg, val_size);
+ break;
+
+ case IOV_SVAL(IOV_TXGLOMMODE):
+ if ((int_val != SDPCM_TXGLOM_CPY) && (int_val != SDPCM_TXGLOM_MDESC)) {
+ bcmerror = BCME_RANGE;
+ } else {
+ if ((bus->glom_mode = bcmsdh_set_mode(bus->sdh, (uint)int_val)) != int_val)
+ bcmerror = BCME_ERROR;
+ }
+ break;
+#endif /* BCMSDIOH_TXGLOM */
+ default:
+ bcmerror = BCME_UNSUPPORTED;
+ break;
+ }
+
+exit:
+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+ bus->activity = FALSE;
+ dhdsdio_clkctl(bus, CLK_NONE, TRUE);
+ }
+
+ dhd_os_sdunlock(bus->dhd);
+
+ return bcmerror;
+}
+
+static int
+dhdsdio_write_vars(dhd_bus_t *bus)
+{
+ int bcmerror = 0;
+ uint32 varsize, phys_size;
+ uint32 varaddr;
+ uint8 *vbuffer;
+ uint32 varsizew;
+#ifdef DHD_DEBUG
+ uint8 *nvram_ularray;
+#endif /* DHD_DEBUG */
+
+ /* Even if there are no vars are to be written, we still need to set the ramsize. */
+ varsize = bus->varsz ? ROUNDUP(bus->varsz, 4) : 0;
+ varaddr = (bus->ramsize - 4) - varsize;
+
+ varaddr += bus->dongle_ram_base;
+
+ if (bus->vars) {
+ if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev == 7)) {
+ if (((varaddr & 0x3C) == 0x3C) && (varsize > 4)) {
+ AP6210_DEBUG("PR85623WAR in place\n");
+ varsize += 4;
+ varaddr -= 4;
+ }
+ }
+
+ vbuffer = (uint8 *)MALLOC(bus->dhd->osh, varsize);
+ if (!vbuffer)
+ return BCME_NOMEM;
+
+ bzero(vbuffer, varsize);
+ bcopy(bus->vars, vbuffer, bus->varsz);
+
+ /* Write the vars list */
+ bcmerror = dhdsdio_membytes(bus, TRUE, varaddr, vbuffer, varsize);
+#ifdef DHD_DEBUG
+ /* Verify NVRAM bytes */
+ AP6210_DEBUG("Compare NVRAM dl & ul; varsize=%d\n", varsize);
+ nvram_ularray = (uint8*)MALLOC(bus->dhd->osh, varsize);
+ if (!nvram_ularray)
+ return BCME_NOMEM;
+
+ /* Upload image to verify downloaded contents. */
+ memset(nvram_ularray, 0xaa, varsize);
+
+ /* Read the vars list to temp buffer for comparison */
+ bcmerror = dhdsdio_membytes(bus, FALSE, varaddr, nvram_ularray, varsize);
+ if (bcmerror) {
+ AP6210_ERR("%s: error %d on reading %d nvram bytes at 0x%08x\n",
+ __FUNCTION__, bcmerror, varsize, varaddr);
+ }
+ /* Compare the org NVRAM with the one read from RAM */
+ if (memcmp(vbuffer, nvram_ularray, varsize)) {
+ AP6210_ERR("%s: Downloaded NVRAM image is corrupted.\n", __FUNCTION__);
+ } else
+ AP6210_DEBUG("%s: Download, Upload and compare of NVRAM succeeded.\n",
+ __FUNCTION__);
+
+ MFREE(bus->dhd->osh, nvram_ularray, varsize);
+#endif /* DHD_DEBUG */
+
+ MFREE(bus->dhd->osh, vbuffer, varsize);
+ }
+
+ phys_size = REMAP_ENAB(bus) ? bus->ramsize : bus->orig_ramsize;
+
+ phys_size += bus->dongle_ram_base;
+
+ /* adjust to the user specified RAM */
+ AP6210_DEBUG("Physical memory size: %d, usable memory size: %d\n",
+ phys_size, bus->ramsize);
+ AP6210_DEBUG("Vars are at %d, orig varsize is %d\n",
+ varaddr, varsize);
+ varsize = ((phys_size - 4) - varaddr);
+
+ /*
+ * Determine the length token:
+ * Varsize, converted to words, in lower 16-bits, checksum in upper 16-bits.
+ */
+ if (bcmerror) {
+ varsizew = 0;
+ } else {
+ varsizew = varsize / 4;
+ varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
+ varsizew = htol32(varsizew);
+ }
+
+ AP6210_DEBUG("New varsize is %d, length token=0x%08x\n", varsize, varsizew);
+
+ /* Write the length token to the last word */
+ bcmerror = dhdsdio_membytes(bus, TRUE, (phys_size - 4),
+ (uint8*)&varsizew, 4);
+
+ return bcmerror;
+}
+
+static int
+dhdsdio_download_state(dhd_bus_t *bus, bool enter)
+{
+ uint retries;
+ int bcmerror = 0;
+ int foundcr4 = 0;
+
+ /* To enter download state, disable ARM and reset SOCRAM.
+ * To exit download state, simply reset ARM (default is RAM boot).
+ */
+ if (enter) {
+ bus->alp_only = TRUE;
+
+ if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) &&
+ !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) {
+ if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) {
+ foundcr4 = 1;
+ } else {
+ AP6210_ERR("%s: Failed to find ARM core!\n", __FUNCTION__);
+ bcmerror = BCME_ERROR;
+ goto fail;
+ }
+ }
+
+ if (!foundcr4) {
+ si_core_disable(bus->sih, 0);
+ if (bcmsdh_regfail(bus->sdh)) {
+ bcmerror = BCME_SDIO_ERROR;
+ goto fail;
+ }
+
+ if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
+ AP6210_ERR("%s: Failed to find SOCRAM core!\n", __FUNCTION__);
+ bcmerror = BCME_ERROR;
+ goto fail;
+ }
+
+ si_core_reset(bus->sih, 0, 0);
+ if (bcmsdh_regfail(bus->sdh)) {
+ AP6210_ERR("%s: Failure trying reset SOCRAM core?\n", __FUNCTION__);
+ bcmerror = BCME_SDIO_ERROR;
+ goto fail;
+ }
+
+ /* Disable remap for download */
+ if (REMAP_ENAB(bus) && si_socdevram_remap_isenb(bus->sih))
+ dhdsdio_devram_remap(bus, FALSE);
+
+ /* Clear the top bit of memory */
+ if (bus->ramsize) {
+ uint32 zeros = 0;
+ if (dhdsdio_membytes(bus, TRUE, bus->ramsize - 4, (uint8*)&zeros, 4) < 0) {
+ bcmerror = BCME_SDIO_ERROR;
+ goto fail;
+ }
+ }
+ } else {
+ /* For CR4,
+ * Halt ARM
+ * Remove ARM reset
+ * Read RAM base address [0x18_0000]
+ * [next] Download firmware
+ * [done at else] Populate the reset vector
+ * [done at else] Remove ARM halt
+ */
+ /* Halt ARM & remove reset */
+ si_core_reset(bus->sih, SICF_CPUHALT, SICF_CPUHALT);
+ }
+ } else {
+ if (!si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) {
+ if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
+ AP6210_ERR("%s: Failed to find SOCRAM core!\n", __FUNCTION__);
+ bcmerror = BCME_ERROR;
+ goto fail;
+ }
+
+ if (!si_iscoreup(bus->sih)) {
+ AP6210_ERR("%s: SOCRAM core is down after reset?\n", __FUNCTION__);
+ bcmerror = BCME_ERROR;
+ goto fail;
+ }
+
+ if ((bcmerror = dhdsdio_write_vars(bus))) {
+ AP6210_ERR("%s: could not write vars to RAM\n", __FUNCTION__);
+ goto fail;
+ }
+
+ /* Enable remap before ARM reset but after vars.
+ * No backplane access in remap mode
+ */
+ if (REMAP_ENAB(bus) && !si_socdevram_remap_isenb(bus->sih))
+ dhdsdio_devram_remap(bus, TRUE);
+
+ if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) &&
+ !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) {
+ AP6210_ERR("%s: Can't change back to SDIO core?\n", __FUNCTION__);
+ bcmerror = BCME_ERROR;
+ goto fail;
+ }
+ W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries);
+
+
+ if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) &&
+ !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) {
+ AP6210_ERR("%s: Failed to find ARM core!\n", __FUNCTION__);
+ bcmerror = BCME_ERROR;
+ goto fail;
+ }
+ } else {
+ /* cr4 has no socram, but tcm's */
+ /* write vars */
+ if ((bcmerror = dhdsdio_write_vars(bus))) {
+ AP6210_ERR("%s: could not write vars to RAM\n", __FUNCTION__);
+ goto fail;
+ }
+
+ if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) &&
+ !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) {
+ AP6210_ERR("%s: Can't change back to SDIO core?\n", __FUNCTION__);
+ bcmerror = BCME_ERROR;
+ goto fail;
+ }
+ W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries);
+
+ /* switch back to arm core again */
+ if (!(si_setcore(bus->sih, ARMCR4_CORE_ID, 0))) {
+ AP6210_ERR("%s: Failed to find ARM CR4 core!\n", __FUNCTION__);
+ bcmerror = BCME_ERROR;
+ goto fail;
+ }
+ /* write address 0 with reset instruction */
+ bcmerror = dhdsdio_membytes(bus, TRUE, 0,
+ (uint8 *)&bus->resetinstr, sizeof(bus->resetinstr));
+
+ /* now remove reset and halt and continue to run CR4 */
+ }
+
+ si_core_reset(bus->sih, 0, 0);
+ if (bcmsdh_regfail(bus->sdh)) {
+ AP6210_ERR("%s: Failure trying to reset ARM core?\n", __FUNCTION__);
+ bcmerror = BCME_SDIO_ERROR;
+ goto fail;
+ }
+
+ /* Allow HT Clock now that the ARM is running. */
+ bus->alp_only = FALSE;
+
+ bus->dhd->busstate = DHD_BUS_LOAD;
+ }
+
+fail:
+ /* Always return to SDIOD core */
+ if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0))
+ si_setcore(bus->sih, SDIOD_CORE_ID, 0);
+
+ return bcmerror;
+}
+
+int
+dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
+ void *params, int plen, void *arg, int len, bool set)
+{
+ dhd_bus_t *bus = dhdp->bus;
+ const bcm_iovar_t *vi = NULL;
+ int bcmerror = 0;
+ int val_size;
+ uint32 actionid;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ ASSERT(name);
+ ASSERT(len >= 0);
+
+ /* Get MUST have return space */
+ ASSERT(set || (arg && len));
+
+ /* Set does NOT take qualifiers */
+ ASSERT(!set || (!params && !plen));
+
+ /* Look up var locally; if not found pass to host driver */
+ if ((vi = bcm_iovar_lookup(dhdsdio_iovars, name)) == NULL) {
+ dhd_os_sdlock(bus->dhd);
+
+ BUS_WAKE(bus);
+
+ /* Turn on clock in case SD command needs backplane */
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+
+ bcmerror = bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len, set);
+
+ /* Check for bus configuration changes of interest */
+
+ /* If it was divisor change, read the new one */
+ if (set && strcmp(name, "sd_divisor") == 0) {
+ if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+ &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) {
+ bus->sd_divisor = -1;
+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, name);
+ } else {
+ AP6210_DEBUG("%s: noted %s update, value now %d\n",
+ __FUNCTION__, name, bus->sd_divisor);
+ }
+ }
+ /* If it was a mode change, read the new one */
+ if (set && strcmp(name, "sd_mode") == 0) {
+ if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
+ &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) {
+ bus->sd_mode = -1;
+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, name);
+ } else {
+ AP6210_DEBUG("%s: noted %s update, value now %d\n",
+ __FUNCTION__, name, bus->sd_mode);
+ }
+ }
+ /* Similar check for blocksize change */
+ if (set && strcmp(name, "sd_blocksize") == 0) {
+ int32 fnum = 2;
+ if (bcmsdh_iovar_op(bus->sdh, "sd_blocksize", &fnum, sizeof(int32),
+ &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) {
+ bus->blocksize = 0;
+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize");
+ } else {
+ AP6210_DEBUG("%s: noted %s update, value now %d\n",
+ __FUNCTION__, "sd_blocksize", bus->blocksize);
+ }
+ }
+ bus->roundup = MIN(max_roundup, bus->blocksize);
+
+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+ bus->activity = FALSE;
+ dhdsdio_clkctl(bus, CLK_NONE, TRUE);
+ }
+
+ dhd_os_sdunlock(bus->dhd);
+ goto exit;
+ }
+
+ AP6210_DEBUG("%s: %s %s, len %d plen %d\n", __FUNCTION__,
+ name, (set ? "set" : "get"), len, plen);
+
+ /* set up 'params' pointer in case this is a set command so that
+ * the convenience int and bool code can be common to set and get
+ */
+ if (params == NULL) {
+ params = arg;
+ plen = len;
+ }
+
+ if (vi->type == IOVT_VOID)
+ val_size = 0;
+ else if (vi->type == IOVT_BUFFER)
+ val_size = len;
+ else
+ /* all other types are integer sized */
+ val_size = sizeof(int);
+
+ actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+ bcmerror = dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len, val_size);
+
+exit:
+ return bcmerror;
+}
+
+void
+dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
+{
+ osl_t *osh;
+ uint32 local_hostintmask;
+ uint8 saveclk, dat;
+ uint retries;
+ int err;
+ if (!bus->dhd)
+ return;
+
+ osh = bus->dhd->osh;
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ bcmsdh_waitlockfree(NULL);
+
+ if (enforce_mutex)
+ dhd_os_sdlock(bus->dhd);
+
+ if ((bus->dhd->busstate == DHD_BUS_DOWN) || bus->dhd->hang_was_sent) {
+ /* if Firmware already hangs disbale any interrupt */
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ bus->hostintmask = 0;
+ bcmsdh_intr_disable(bus->sdh);
+ } else {
+ BUS_WAKE(bus);
+
+ if (KSO_ENAB(bus)) {
+ /* Mask the interrupt */
+ dat = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_INTEN, NULL);
+ dat &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_INTEN, dat, NULL);
+ }
+
+ /* Change our idea of bus state */
+ bus->dhd->busstate = DHD_BUS_DOWN;
+
+ if (KSO_ENAB(bus)) {
+
+ /* Enable clock for device interrupts */
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+
+ /* Disable and clear interrupts at the chip level also */
+ W_SDREG(0, &bus->regs->hostintmask, retries);
+ local_hostintmask = bus->hostintmask;
+ bus->hostintmask = 0;
+
+ /* Force clocks on backplane to be sure F2 interrupt propagates */
+ saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
+ if (!err) {
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+ (saveclk | SBSDIO_FORCE_HT), &err);
+ }
+ if (err) {
+ AP6210_ERR("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err);
+ }
+
+ /* Turn off the bus (F2), free any pending packets */
+ AP6210_DEBUG("%s: disable SDIO interrupts\n", __FUNCTION__);
+ bcmsdh_intr_disable(bus->sdh);
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL);
+
+ /* Clear any pending interrupts now that F2 is disabled */
+ W_SDREG(local_hostintmask, &bus->regs->intstatus, retries);
+ }
+
+ /* Turn off the backplane clock (only) */
+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
+ }
+
+ /* Clear the data packet queues */
+ pktq_flush(osh, &bus->txq, TRUE, NULL, 0);
+
+ /* Clear any held glomming stuff */
+ if (bus->glomd)
+ PKTFREE(osh, bus->glomd, FALSE);
+
+ if (bus->glom)
+ PKTFREE(osh, bus->glom, FALSE);
+
+ bus->glom = bus->glomd = NULL;
+
+ /* Clear rx control and wake any waiters */
+ bus->rxlen = 0;
+ dhd_os_ioctl_resp_wake(bus->dhd);
+
+ /* Reset some F2 state stuff */
+ bus->rxskip = FALSE;
+ bus->tx_seq = bus->rx_seq = 0;
+
+ if (enforce_mutex)
+ dhd_os_sdunlock(bus->dhd);
+}
+
+#ifdef BCMSDIOH_TXGLOM
+void
+dhd_txglom_enable(dhd_pub_t *dhdp, bool enable)
+{
+ dhd_bus_t *bus = dhdp->bus;
+
+ char buf[256];
+ uint32 rxglom;
+ int32 ret;
+
+ if (enable) {
+ rxglom = 1;
+ memset(buf, 0, sizeof(buf));
+ bcm_mkiovar("bus:rxglom",
+ (void *)&rxglom,
+ 4, buf, sizeof(buf));
+ ret = dhd_wl_ioctl_cmd(dhdp,
+ WLC_SET_VAR, buf,
+ sizeof(buf), TRUE, 0);
+ if (!(ret < 0)) {
+ bus->glom_enable = TRUE;
+ }
+ } else {
+ bus->glom_enable = FALSE;
+ }
+}
+#endif /* BCMSDIOH_TXGLOM */
+
+int
+dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
+{
+ dhd_bus_t *bus = dhdp->bus;
+ dhd_timeout_t tmo;
+ uint retries = 0;
+ uint8 ready, enable;
+ int err, ret = 0;
+ uint8 saveclk;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ ASSERT(bus->dhd);
+ if (!bus->dhd)
+ return 0;
+
+ if (enforce_mutex)
+ dhd_os_sdlock(bus->dhd);
+
+ /* Make sure backplane clock is on, needed to generate F2 interrupt */
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+ if (bus->clkstate != CLK_AVAIL) {
+ AP6210_ERR("%s: clock state is wrong. state = %d\n", __FUNCTION__, bus->clkstate);
+ ret = -1;
+ goto exit;
+ }
+
+
+ /* Force clocks on backplane to be sure F2 interrupt propagates */
+ saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
+ if (!err) {
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+ (saveclk | SBSDIO_FORCE_HT), &err);
+ }
+ if (err) {
+ AP6210_ERR("%s: Failed to force clock for F2: err %d\n", __FUNCTION__, err);
+ ret = -1;
+ goto exit;
+ }
+
+ /* Enable function 2 (frame transfers) */
+ W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT),
+ &bus->regs->tosbmailboxdata, retries);
+ enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
+
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL);
+
+ /* Give the dongle some time to do its thing and set IOR2 */
+ dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000);
+
+ ready = 0;
+ while (ready != enable && !dhd_timeout_expired(&tmo))
+ ready = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY, NULL);
+
+ AP6210_DEBUG("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n",
+ __FUNCTION__, enable, ready, tmo.elapsed);
+
+
+ /* If F2 successfully enabled, set core and enable interrupts */
+ if (ready == enable) {
+ /* Make sure we're talking to the core. */
+ if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0)))
+ bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0);
+ ASSERT(bus->regs != NULL);
+
+ /* Set up the interrupt mask and enable interrupts */
+ bus->hostintmask = HOSTINTMASK;
+ /* corerev 4 could use the newer interrupt logic to detect the frames */
+ if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev == 4) &&
+ (bus->rxint_mode != SDIO_DEVICE_HMB_RXINT)) {
+ bus->hostintmask &= ~I_HMB_FRAME_IND;
+ bus->hostintmask |= I_XMTDATA_AVAIL;
+ }
+ W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries);
+#ifdef SDIO_CRC_ERROR_FIX
+ if (bus->blocksize < 512) {
+ mesbusyctrl = watermark = bus->blocksize / 4;
+ }
+#endif /* SDIO_CRC_ERROR_FIX */
+
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, &err);
+#ifdef SDIO_CRC_ERROR_FIX
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL,
+ (uint8)mesbusyctrl|0x80, &err);
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+ SBSDIO_DEVCTL_EN_F2_BLK_WATERMARK, NULL);
+#endif /* SDIO_CRC_ERROR_FIX */
+
+ /* Set bus state according to enable result */
+ dhdp->busstate = DHD_BUS_DATA;
+
+ /* bcmsdh_intr_unmask(bus->sdh); */
+
+ bus->intdis = FALSE;
+ if (bus->intr) {
+ AP6210_DEBUG("%s: enable SDIO device interrupts\n", __FUNCTION__);
+ bcmsdh_intr_enable(bus->sdh);
+ } else {
+ AP6210_DEBUG("%s: disable SDIO interrupts\n", __FUNCTION__);
+ bcmsdh_intr_disable(bus->sdh);
+ }
+
+ }
+
+
+ else {
+ /* Disable F2 again */
+ enable = SDIO_FUNC_ENABLE_1;
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL);
+ }
+
+ if (dhdsdio_sr_cap(bus))
+ dhdsdio_sr_init(bus);
+ else
+ bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
+
+ /* If we didn't come up, turn off backplane clock */
+ if (dhdp->busstate != DHD_BUS_DATA)
+ dhdsdio_clkctl(bus, CLK_NONE, FALSE);
+
+exit:
+ if (enforce_mutex)
+ dhd_os_sdunlock(bus->dhd);
+
+ return ret;
+}
+
+static void
+dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx)
+{
+ bcmsdh_info_t *sdh = bus->sdh;
+ sdpcmd_regs_t *regs = bus->regs;
+ uint retries = 0;
+ uint16 lastrbc;
+ uint8 hi, lo;
+ int err;
+
+ AP6210_ERR("%s: %sterminate frame%s\n", __FUNCTION__,
+ (abort ? "abort command, " : ""), (rtx ? ", send NAK" : ""));
+
+ if (!KSO_ENAB(bus)) {
+ AP6210_ERR("%s: Device asleep\n", __FUNCTION__);
+ return;
+ }
+
+ if (abort) {
+ bcmsdh_abort(sdh, SDIO_FUNC_2);
+ }
+
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err);
+ bus->f1regdata++;
+
+ /* Wait until the packet has been flushed (device/FIFO stable) */
+ for (lastrbc = retries = 0xffff; retries > 0; retries--) {
+ hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI, NULL);
+ lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, NULL);
+ bus->f1regdata += 2;
+
+ if ((hi == 0) && (lo == 0))
+ break;
+
+ if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
+ AP6210_DEBUG("%s: count growing: last 0x%04x now 0x%04x\n",
+ __FUNCTION__, lastrbc, ((hi << 8) + lo));
+ }
+ lastrbc = (hi << 8) + lo;
+ }
+
+ if (!retries) {
+ AP6210_ERR("%s: count never zeroed: last 0x%04x\n", __FUNCTION__, lastrbc);
+ } else {
+ AP6210_DEBUG("%s: flush took %d iterations\n", __FUNCTION__, (0xffff - retries));
+ }
+
+ if (rtx) {
+ bus->rxrtx++;
+ W_SDREG(SMB_NAK, &regs->tosbmailbox, retries);
+ bus->f1regdata++;
+ if (retries <= retry_limit) {
+ bus->rxskip = TRUE;
+ }
+ }
+
+ /* Clear partial in any case */
+ bus->nextlen = 0;
+
+ /* If we can't reach the device, signal failure */
+ if (err || bcmsdh_regfail(sdh))
+ bus->dhd->busstate = DHD_BUS_DOWN;
+}
+
+static void
+dhdsdio_read_control(dhd_bus_t *bus, uint8 *hdr, uint len, uint doff)
+{
+ bcmsdh_info_t *sdh = bus->sdh;
+ uint rdlen, pad;
+
+ int sdret;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ /* Control data already received in aligned rxctl */
+ if ((bus->bus == SPI_BUS) && (!bus->usebufpool))
+ goto gotpkt;
+
+ ASSERT(bus->rxbuf);
+ /* Set rxctl for frame (w/optional alignment) */
+ bus->rxctl = bus->rxbuf;
+ if (dhd_alignctl) {
+ bus->rxctl += firstread;
+ if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN)))
+ bus->rxctl += (DHD_SDALIGN - pad);
+ bus->rxctl -= firstread;
+ }
+ ASSERT(bus->rxctl >= bus->rxbuf);
+
+ /* Copy the already-read portion over */
+ bcopy(hdr, bus->rxctl, firstread);
+ if (len <= firstread)
+ goto gotpkt;
+
+ /* Copy the full data pkt in gSPI case and process ioctl. */
+ if (bus->bus == SPI_BUS) {
+ bcopy(hdr, bus->rxctl, len);
+ goto gotpkt;
+ }
+
+ /* Raise rdlen to next SDIO block to avoid tail command */
+ rdlen = len - firstread;
+ if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
+ pad = bus->blocksize - (rdlen % bus->blocksize);
+ if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
+ ((len + pad) < bus->dhd->maxctl))
+ rdlen += pad;
+ } else if (rdlen % DHD_SDALIGN) {
+ rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+ }
+
+ /* Satisfy length-alignment requirements */
+ if (forcealign && (rdlen & (ALIGNMENT - 1)))
+ rdlen = ROUNDUP(rdlen, ALIGNMENT);
+
+ /* Drop if the read is too big or it exceeds our maximum */
+ if ((rdlen + firstread) > bus->dhd->maxctl) {
+ AP6210_ERR("%s: %d-byte control read exceeds %d-byte buffer\n",
+ __FUNCTION__, rdlen, bus->dhd->maxctl);
+ bus->dhd->rx_errors++;
+ dhdsdio_rxfail(bus, FALSE, FALSE);
+ goto done;
+ }
+
+ if ((len - doff) > bus->dhd->maxctl) {
+ AP6210_ERR("%s: %d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
+ __FUNCTION__, len, (len - doff), bus->dhd->maxctl);
+ bus->dhd->rx_errors++; bus->rx_toolong++;
+ dhdsdio_rxfail(bus, FALSE, FALSE);
+ goto done;
+ }
+
+
+ /* Read remainder of frame body into the rxctl buffer */
+ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
+ (bus->rxctl + firstread), rdlen, NULL, NULL, NULL);
+ bus->f2rxdata++;
+ ASSERT(sdret != BCME_PENDING);
+
+ /* Control frame failures need retransmission */
+ if (sdret < 0) {
+ AP6210_ERR("%s: read %d control bytes failed: %d\n", __FUNCTION__, rdlen, sdret);
+ bus->rxc_errors++; /* dhd.rx_ctlerrs is higher level */
+ dhdsdio_rxfail(bus, TRUE, TRUE);
+ goto done;
+ }
+
+gotpkt:
+
+#ifdef DHD_DEBUG
+ if (DHD_BYTES_ON() && DHD_CTL_ON()) {
+ prhex("RxCtrl", bus->rxctl, len);
+ }
+#endif
+
+ /* Point to valid data and indicate its length */
+ bus->rxctl += doff;
+ bus->rxlen = len - doff;
+
+done:
+ /* Awake any waiters */
+ dhd_os_ioctl_resp_wake(bus->dhd);
+}
+
+static uint8
+dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
+{
+ uint16 dlen, totlen;
+ uint8 *dptr, num = 0;
+
+ uint16 sublen, check;
+ void *pfirst, *plast, *pnext;
+ void * list_tail[DHD_MAX_IFS] = { NULL };
+ void * list_head[DHD_MAX_IFS] = { NULL };
+ uint8 idx;
+ osl_t *osh = bus->dhd->osh;
+
+ int errcode;
+ uint8 chan, seq, doff, sfdoff;
+ uint8 txmax;
+ uchar reorder_info_buf[WLHOST_REORDERDATA_TOTLEN];
+ uint reorder_info_len;
+
+ int ifidx = 0;
+ bool usechain = bus->use_rxchain;
+
+ /* If packets, issue read(s) and send up packet chain */
+ /* Return sequence numbers consumed? */
+
+ AP6210_DEBUG("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd, bus->glom);
+
+ /* If there's a descriptor, generate the packet chain */
+ if (bus->glomd) {
+ dhd_os_sdlock_rxq(bus->dhd);
+
+ pfirst = plast = pnext = NULL;
+ dlen = (uint16)PKTLEN(osh, bus->glomd);
+ dptr = PKTDATA(osh, bus->glomd);
+ if (!dlen || (dlen & 1)) {
+ AP6210_ERR("%s: bad glomd len (%d), ignore descriptor\n",
+ __FUNCTION__, dlen);
+ dlen = 0;
+ }
+
+ for (totlen = num = 0; dlen; num++) {
+ /* Get (and move past) next length */
+ sublen = ltoh16_ua(dptr);
+ dlen -= sizeof(uint16);
+ dptr += sizeof(uint16);
+ if ((sublen < SDPCM_HDRLEN_RX) ||
+ ((num == 0) && (sublen < (2 * SDPCM_HDRLEN_RX)))) {
+ AP6210_ERR("%s: descriptor len %d bad: %d\n",
+ __FUNCTION__, num, sublen);
+ pnext = NULL;
+ break;
+ }
+ if (sublen % DHD_SDALIGN) {
+ AP6210_ERR("%s: sublen %d not a multiple of %d\n",
+ __FUNCTION__, sublen, DHD_SDALIGN);
+ usechain = FALSE;
+ }
+ totlen += sublen;
+
+ /* For last frame, adjust read len so total is a block multiple */
+ if (!dlen) {
+ sublen += (ROUNDUP(totlen, bus->blocksize) - totlen);
+ totlen = ROUNDUP(totlen, bus->blocksize);
+ }
+
+ /* Allocate/chain packet for next subframe */
+ if ((pnext = PKTGET(osh, sublen + DHD_SDALIGN, FALSE)) == NULL) {
+ AP6210_ERR("%s: PKTGET failed, num %d len %d\n",
+ __FUNCTION__, num, sublen);
+ break;
+ }
+ ASSERT(!PKTLINK(pnext));
+ if (!pfirst) {
+ ASSERT(!plast);
+ pfirst = plast = pnext;
+ } else {
+ ASSERT(plast);
+ PKTSETNEXT(osh, plast, pnext);
+ plast = pnext;
+ }
+
+ /* Adhere to start alignment requirements */
+ PKTALIGN(osh, pnext, sublen, DHD_SDALIGN);
+ }
+
+ /* If all allocations succeeded, save packet chain in bus structure */
+ if (pnext) {
+ AP6210_DEBUG("%s: allocated %d-byte packet chain for %d subframes\n",
+ __FUNCTION__, totlen, num);
+ if (DHD_GLOM_ON() && bus->nextlen) {
+ if (totlen != bus->nextlen) {
+ AP6210_DEBUG("%s: glomdesc mismatch: nextlen %d glomdesc %d "
+ "rxseq %d\n", __FUNCTION__, bus->nextlen,
+ totlen, rxseq);
+ }
+ }
+ bus->glom = pfirst;
+ pfirst = pnext = NULL;
+ } else {
+ if (pfirst)
+ PKTFREE(osh, pfirst, FALSE);
+ bus->glom = NULL;
+ num = 0;
+ }
+
+ /* Done with descriptor packet */
+ PKTFREE(osh, bus->glomd, FALSE);
+ bus->glomd = NULL;
+ bus->nextlen = 0;
+
+ dhd_os_sdunlock_rxq(bus->dhd);
+ }
+
+ /* Ok -- either we just generated a packet chain, or had one from before */
+ if (bus->glom) {
+ if (DHD_GLOM_ON()) {
+ AP6210_DEBUG("%s: attempt superframe read, packet chain:\n", __FUNCTION__);
+ for (pnext = bus->glom; pnext; pnext = PKTNEXT(osh, pnext)) {
+ AP6210_DEBUG(" %p: %p len 0x%04x (%d)\n",
+ pnext, (uint8*)PKTDATA(osh, pnext),
+ PKTLEN(osh, pnext), PKTLEN(osh, pnext));
+ }
+ }
+
+ pfirst = bus->glom;
+ dlen = (uint16)pkttotlen(osh, pfirst);
+
+ /* Do an SDIO read for the superframe. Configurable iovar to
+ * read directly into the chained packet, or allocate a large
+ * packet and and copy into the chain.
+ */
+ if (usechain) {
+ errcode = dhd_bcmsdh_recv_buf(bus,
+ bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2,
+ F2SYNC, (uint8*)PKTDATA(osh, pfirst),
+ dlen, pfirst, NULL, NULL);
+ } else if (bus->dataptr) {
+ errcode = dhd_bcmsdh_recv_buf(bus,
+ bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2,
+ F2SYNC, bus->dataptr,
+ dlen, NULL, NULL, NULL);
+ sublen = (uint16)pktfrombuf(osh, pfirst, 0, dlen, bus->dataptr);
+ if (sublen != dlen) {
+ AP6210_ERR("%s: FAILED TO COPY, dlen %d sublen %d\n",
+ __FUNCTION__, dlen, sublen);
+ errcode = -1;
+ }
+ pnext = NULL;
+ } else {
+ AP6210_ERR("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n", dlen);
+ errcode = -1;
+ }
+ bus->f2rxdata++;
+ ASSERT(errcode != BCME_PENDING);
+
+ /* On failure, kill the superframe, allow a couple retries */
+ if (errcode < 0) {
+ AP6210_ERR("%s: glom read of %d bytes failed: %d\n",
+ __FUNCTION__, dlen, errcode);
+ bus->dhd->rx_errors++;
+
+ if (bus->glomerr++ < 3) {
+ dhdsdio_rxfail(bus, TRUE, TRUE);
+ } else {
+ bus->glomerr = 0;
+ dhdsdio_rxfail(bus, TRUE, FALSE);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE(osh, bus->glom, FALSE);
+ dhd_os_sdunlock_rxq(bus->dhd);
+ bus->rxglomfail++;
+ bus->glom = NULL;
+ }
+ return 0;
+ }
+
+#ifdef DHD_DEBUG
+ if (DHD_GLOM_ON()) {
+ prhex("SUPERFRAME", PKTDATA(osh, pfirst),
+ MIN(PKTLEN(osh, pfirst), 48));
+ }
+#endif
+
+
+ /* Validate the superframe header */
+ dptr = (uint8 *)PKTDATA(osh, pfirst);
+ sublen = ltoh16_ua(dptr);
+ check = ltoh16_ua(dptr + sizeof(uint16));
+
+ chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+ seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
+ bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
+ if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+ AP6210_DEBUG("%s: got frame w/nextlen too large (%d) seq %d\n",
+ __FUNCTION__, bus->nextlen, seq);
+ bus->nextlen = 0;
+ }
+ doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+ txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+
+ errcode = 0;
+ if ((uint16)~(sublen^check)) {
+ AP6210_ERR("%s (superframe): HW hdr error: len/check 0x%04x/0x%04x\n",
+ __FUNCTION__, sublen, check);
+ errcode = -1;
+ } else if (ROUNDUP(sublen, bus->blocksize) != dlen) {
+ AP6210_ERR("%s (superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n",
+ __FUNCTION__, sublen, ROUNDUP(sublen, bus->blocksize), dlen);
+ errcode = -1;
+ } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != SDPCM_GLOM_CHANNEL) {
+ AP6210_ERR("%s (superframe): bad channel %d\n", __FUNCTION__,
+ SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]));
+ errcode = -1;
+ } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
+ AP6210_ERR("%s (superframe): got second descriptor?\n", __FUNCTION__);
+ errcode = -1;
+ } else if ((doff < SDPCM_HDRLEN_RX) ||
+ (doff > (PKTLEN(osh, pfirst) - SDPCM_HDRLEN_RX))) {
+ AP6210_ERR("%s (superframe): Bad data offset %d: HW %d pkt %d min %d\n",
+ __FUNCTION__, doff, sublen, PKTLEN(osh, pfirst),
+ SDPCM_HDRLEN_RX);
+ errcode = -1;
+ }
+
+ /* Check sequence number of superframe SW header */
+ if (rxseq != seq) {
+ AP6210_DEBUG("%s: (superframe) rx_seq %d, expected %d\n",
+ __FUNCTION__, seq, rxseq);
+ bus->rx_badseq++;
+ rxseq = seq;
+ }
+
+ /* Check window for sanity */
+ if ((uint8)(txmax - bus->tx_seq) > 0x40) {
+ AP6210_ERR("%s: got unlikely tx max %d with tx_seq %d\n",
+ __FUNCTION__, txmax, bus->tx_seq);
+ txmax = bus->tx_max;
+ }
+ bus->tx_max = txmax;
+
+ /* Remove superframe header, remember offset */
+ PKTPULL(osh, pfirst, doff);
+ sfdoff = doff;
+
+ /* Validate all the subframe headers */
+ for (num = 0, pnext = pfirst; pnext && !errcode;
+ num++, pnext = PKTNEXT(osh, pnext)) {
+ dptr = (uint8 *)PKTDATA(osh, pnext);
+ dlen = (uint16)PKTLEN(osh, pnext);
+ sublen = ltoh16_ua(dptr);
+ check = ltoh16_ua(dptr + sizeof(uint16));
+ chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+ doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+#ifdef DHD_DEBUG
+ if (DHD_GLOM_ON()) {
+ prhex("subframe", dptr, 32);
+ }
+#endif
+
+ if ((uint16)~(sublen^check)) {
+ AP6210_ERR("%s (subframe %d): HW hdr error: "
+ "len/check 0x%04x/0x%04x\n",
+ __FUNCTION__, num, sublen, check);
+ errcode = -1;
+ } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN_RX)) {
+ AP6210_ERR("%s (subframe %d): length mismatch: "
+ "len 0x%04x, expect 0x%04x\n",
+ __FUNCTION__, num, sublen, dlen);
+ errcode = -1;
+ } else if ((chan != SDPCM_DATA_CHANNEL) &&
+ (chan != SDPCM_EVENT_CHANNEL)) {
+ AP6210_ERR("%s (subframe %d): bad channel %d\n",
+ __FUNCTION__, num, chan);
+ errcode = -1;
+ } else if ((doff < SDPCM_HDRLEN_RX) || (doff > sublen)) {
+ AP6210_ERR("%s (subframe %d): Bad data offset %d: HW %d min %d\n",
+ __FUNCTION__, num, doff, sublen, SDPCM_HDRLEN_RX);
+ errcode = -1;
+ }
+ }
+
+ if (errcode) {
+ /* Terminate frame on error, request a couple retries */
+ if (bus->glomerr++ < 3) {
+ /* Restore superframe header space */
+ PKTPUSH(osh, pfirst, sfdoff);
+ dhdsdio_rxfail(bus, TRUE, TRUE);
+ } else {
+ bus->glomerr = 0;
+ dhdsdio_rxfail(bus, TRUE, FALSE);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE(osh, bus->glom, FALSE);
+ dhd_os_sdunlock_rxq(bus->dhd);
+ bus->rxglomfail++;
+ bus->glom = NULL;
+ }
+ bus->nextlen = 0;
+ return 0;
+ }
+
+ /* Basic SD framing looks ok - process each packet (header) */
+ bus->glom = NULL;
+ plast = NULL;
+
+ dhd_os_sdlock_rxq(bus->dhd);
+ for (num = 0; pfirst; rxseq++, pfirst = pnext) {
+ pnext = PKTNEXT(osh, pfirst);
+ PKTSETNEXT(osh, pfirst, NULL);
+
+ dptr = (uint8 *)PKTDATA(osh, pfirst);
+ sublen = ltoh16_ua(dptr);
+ chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+ seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
+ doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+
+ AP6210_DEBUG("%s: Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n",
+ __FUNCTION__, num, pfirst, PKTDATA(osh, pfirst),
+ PKTLEN(osh, pfirst), sublen, chan, seq);
+
+ ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL));
+
+ if (rxseq != seq) {
+ AP6210_DEBUG("%s: rx_seq %d, expected %d\n",
+ __FUNCTION__, seq, rxseq);
+ bus->rx_badseq++;
+ rxseq = seq;
+ }
+
+#ifdef DHD_DEBUG
+ if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+ prhex("Rx Subframe Data", dptr, dlen);
+ }
+#endif
+
+ PKTSETLEN(osh, pfirst, sublen);
+ PKTPULL(osh, pfirst, doff);
+
+ reorder_info_len = sizeof(reorder_info_buf);
+
+ if (PKTLEN(osh, pfirst) == 0) {
+ PKTFREE(bus->dhd->osh, pfirst, FALSE);
+ continue;
+ } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst, reorder_info_buf,
+ &reorder_info_len) != 0) {
+ AP6210_ERR("%s: rx protocol error\n", __FUNCTION__);
+ bus->dhd->rx_errors++;
+ PKTFREE(osh, pfirst, FALSE);
+ continue;
+ }
+ if (reorder_info_len) {
+ uint32 free_buf_count;
+ void *ppfirst;
+
+ ppfirst = pfirst;
+ /* Reordering info from the firmware */
+ dhd_process_pkt_reorder_info(bus->dhd, reorder_info_buf,
+ reorder_info_len, &ppfirst, &free_buf_count);
+
+ if (free_buf_count == 0) {
+ continue;
+ }
+ else {
+ void *temp;
+
+ /* go to the end of the chain and attach the pnext there */
+ temp = ppfirst;
+ while (PKTNEXT(osh, temp) != NULL) {
+ temp = PKTNEXT(osh, temp);
+ }
+ pfirst = temp;
+ if (list_tail[ifidx] == NULL) {
+ list_head[ifidx] = ppfirst;
+ list_tail[ifidx] = pfirst;
+ }
+ else {
+ PKTSETNEXT(osh, list_tail[ifidx], ppfirst);
+ list_tail[ifidx] = pfirst;
+ }
+ }
+
+ num += (uint8)free_buf_count;
+ }
+ else {
+ /* this packet will go up, link back into chain and count it */
+
+ if (list_tail[ifidx] == NULL) {
+ list_head[ifidx] = list_tail[ifidx] = pfirst;
+ }
+ else {
+ PKTSETNEXT(osh, list_tail[ifidx], pfirst);
+ list_tail[ifidx] = pfirst;
+ }
+ num++;
+ }
+#ifdef DHD_DEBUG
+ if (DHD_GLOM_ON()) {
+ AP6210_DEBUG("%s subframe %d to stack, %p(%p/%d) nxt/lnk %p/%p\n",
+ __FUNCTION__, num, pfirst,
+ PKTDATA(osh, pfirst), PKTLEN(osh, pfirst),
+ PKTNEXT(osh, pfirst), PKTLINK(pfirst));
+ prhex("", (uint8 *)PKTDATA(osh, pfirst),
+ MIN(PKTLEN(osh, pfirst), 32));
+ }
+#endif /* DHD_DEBUG */
+ }
+ dhd_os_sdunlock_rxq(bus->dhd);
+
+ for (idx = 0; idx < DHD_MAX_IFS; idx++) {
+ if (list_head[idx]) {
+ void *temp;
+ uint8 cnt = 0;
+ temp = list_head[idx];
+ do {
+ temp = PKTNEXT(osh, temp);
+ cnt++;
+ } while (temp);
+ if (cnt) {
+ dhd_os_sdunlock(bus->dhd);
+ dhd_rx_frame(bus->dhd, idx, list_head[idx], cnt, 0);
+ dhd_os_sdlock(bus->dhd);
+ }
+ }
+ }
+ bus->rxglomframes++;
+ bus->rxglompkts += num;
+ }
+ return num;
+}
+
+
+/* Return TRUE if there may be more frames to read */
+static uint
+dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
+{
+ osl_t *osh = bus->dhd->osh;
+ bcmsdh_info_t *sdh = bus->sdh;
+
+ uint16 len, check; /* Extracted hardware header fields */
+ uint8 chan, seq, doff; /* Extracted software header fields */
+ uint8 fcbits; /* Extracted fcbits from software header */
+ uint8 delta;
+
+ void *pkt; /* Packet for event or data frames */
+ uint16 pad; /* Number of pad bytes to read */
+ uint16 rdlen; /* Total number of bytes to read */
+ uint8 rxseq; /* Next sequence number to expect */
+ uint rxleft = 0; /* Remaining number of frames allowed */
+ int sdret; /* Return code from bcmsdh calls */
+ uint8 txmax; /* Maximum tx sequence offered */
+ bool len_consistent; /* Result of comparing readahead len and len from hw-hdr */
+ uint8 *rxbuf;
+ int ifidx = 0;
+ uint rxcount = 0; /* Total frames read */
+ uchar reorder_info_buf[WLHOST_REORDERDATA_TOTLEN];
+ uint reorder_info_len;
+ uint pkt_count;
+
+#if defined(DHD_DEBUG) || defined(SDTEST)
+ bool sdtest = FALSE; /* To limit message spew from test mode */
+#endif
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ bus->readframes = TRUE;
+
+ if (!KSO_ENAB(bus)) {
+ AP6210_DEBUG("%s: KSO off\n", __FUNCTION__);
+ bus->readframes = FALSE;
+ return 0;
+ }
+
+ ASSERT(maxframes);
+
+#ifdef SDTEST
+ /* Allow pktgen to override maxframes */
+ if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) {
+ maxframes = bus->pktgen_count;
+ sdtest = TRUE;
+ }
+#endif
+
+ /* Not finished unless we encounter no more frames indication */
+ *finished = FALSE;
+
+
+ for (rxseq = bus->rx_seq, rxleft = maxframes;
+ !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN;
+ rxseq++, rxleft--) {
+
+#ifdef DHDTHREAD
+ /* terence: fix got unlikely tx max for 43362a0*/
+ if (bus->sih->chip!=BCM43362_CHIP_ID && bus->sih->chiprev!=BCM43362A0_CHIP_REV) {
+ /* tx more to improve rx performance */
+ if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
+ pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) {
+ dhdsdio_sendfromq(bus, dhd_txbound);
+ }
+ }
+#endif /* DHDTHREAD */
+
+ /* Handle glomming separately */
+ if (bus->glom || bus->glomd) {
+ uint8 cnt;
+ AP6210_DEBUG("%s: calling rxglom: glomd %p, glom %p\n",
+ __FUNCTION__, bus->glomd, bus->glom);
+ cnt = dhdsdio_rxglom(bus, rxseq);
+ AP6210_DEBUG("%s: rxglom returned %d\n", __FUNCTION__, cnt);
+ rxseq += cnt - 1;
+ rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
+ continue;
+ }
+
+ /* Try doing single read if we can */
+ if (dhd_readahead && bus->nextlen) {
+ uint16 nextlen = bus->nextlen;
+ bus->nextlen = 0;
+
+ if (bus->bus == SPI_BUS) {
+ rdlen = len = nextlen;
+ }
+ else {
+ rdlen = len = nextlen << 4;
+
+ /* Pad read to blocksize for efficiency */
+ if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
+ pad = bus->blocksize - (rdlen % bus->blocksize);
+ if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
+ ((rdlen + pad + firstread) < MAX_RX_DATASZ))
+ rdlen += pad;
+ } else if (rdlen % DHD_SDALIGN) {
+ rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+ }
+ }
+
+ /* We use bus->rxctl buffer in WinXP for initial control pkt receives.
+ * Later we use buffer-poll for data as well as control packets.
+ * This is required because dhd receives full frame in gSPI unlike SDIO.
+ * After the frame is received we have to distinguish whether it is data
+ * or non-data frame.
+ */
+ /* Allocate a packet buffer */
+ dhd_os_sdlock_rxq(bus->dhd);
+ if (!(pkt = PKTGET(osh, rdlen + DHD_SDALIGN, FALSE))) {
+ if (bus->bus == SPI_BUS) {
+ bus->usebufpool = FALSE;
+ bus->rxctl = bus->rxbuf;
+ if (dhd_alignctl) {
+ bus->rxctl += firstread;
+ if ((pad = ((uintptr)bus->rxctl % DHD_SDALIGN)))
+ bus->rxctl += (DHD_SDALIGN - pad);
+ bus->rxctl -= firstread;
+ }
+ ASSERT(bus->rxctl >= bus->rxbuf);
+ rxbuf = bus->rxctl;
+ /* Read the entire frame */
+ sdret = dhd_bcmsdh_recv_buf(bus,
+ bcmsdh_cur_sbwad(sdh),
+ SDIO_FUNC_2,
+ F2SYNC, rxbuf, rdlen,
+ NULL, NULL, NULL);
+ bus->f2rxdata++;
+ ASSERT(sdret != BCME_PENDING);
+
+
+ /* Control frame failures need retransmission */
+ if (sdret < 0) {
+ AP6210_ERR("%s: read %d control bytes failed: %d\n",
+ __FUNCTION__, rdlen, sdret);
+ /* dhd.rx_ctlerrs is higher level */
+ bus->rxc_errors++;
+ dhd_os_sdunlock_rxq(bus->dhd);
+ dhdsdio_rxfail(bus, TRUE,
+ (bus->bus == SPI_BUS) ? FALSE : TRUE);
+ continue;
+ }
+ } else {
+ /* Give up on data, request rtx of events */
+ AP6210_ERR("%s (nextlen): PKTGET failed: len %d rdlen %d "
+ "expected rxseq %d\n",
+ __FUNCTION__, len, rdlen, rxseq);
+ /* Just go try again w/normal header read */
+ dhd_os_sdunlock_rxq(bus->dhd);
+ continue;
+ }
+ } else {
+ if (bus->bus == SPI_BUS)
+ bus->usebufpool = TRUE;
+
+ ASSERT(!PKTLINK(pkt));
+ PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN);
+ rxbuf = (uint8 *)PKTDATA(osh, pkt);
+ /* Read the entire frame */
+ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh),
+ SDIO_FUNC_2,
+ F2SYNC, rxbuf, rdlen,
+ pkt, NULL, NULL);
+ bus->f2rxdata++;
+ ASSERT(sdret != BCME_PENDING);
+
+ if (sdret < 0) {
+ AP6210_ERR("%s (nextlen): read %d bytes failed: %d\n",
+ __FUNCTION__, rdlen, sdret);
+ PKTFREE(bus->dhd->osh, pkt, FALSE);
+ bus->dhd->rx_errors++;
+ dhd_os_sdunlock_rxq(bus->dhd);
+ /* Force retry w/normal header read. Don't attempt NAK for
+ * gSPI
+ */
+ dhdsdio_rxfail(bus, TRUE,
+ (bus->bus == SPI_BUS) ? FALSE : TRUE);
+ continue;
+ }
+ }
+ dhd_os_sdunlock_rxq(bus->dhd);
+
+ /* Now check the header */
+ bcopy(rxbuf, bus->rxhdr, SDPCM_HDRLEN_RX);
+
+ /* Extract hardware header fields */
+ len = ltoh16_ua(bus->rxhdr);
+ check = ltoh16_ua(bus->rxhdr + sizeof(uint16));
+
+ /* All zeros means readahead info was bad */
+ if (!(len|check)) {
+ AP6210_DEBUG("%s (nextlen): read zeros in HW header???\n",
+ __FUNCTION__);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE2();
+ dhd_os_sdunlock_rxq(bus->dhd);
+ GSPI_PR55150_BAILOUT;
+ continue;
+ }
+
+ /* Validate check bytes */
+ if ((uint16)~(len^check)) {
+ AP6210_ERR("%s (nextlen): HW hdr error: nextlen/len/check"
+ " 0x%04x/0x%04x/0x%04x\n", __FUNCTION__, nextlen,
+ len, check);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE2();
+ dhd_os_sdunlock_rxq(bus->dhd);
+ bus->rx_badhdr++;
+ dhdsdio_rxfail(bus, FALSE, FALSE);
+ GSPI_PR55150_BAILOUT;
+ continue;
+ }
+
+ /* Validate frame length */
+ if (len < SDPCM_HDRLEN_RX) {
+ AP6210_ERR("%s (nextlen): HW hdr length invalid: %d\n",
+ __FUNCTION__, len);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE2();
+ dhd_os_sdunlock_rxq(bus->dhd);
+ GSPI_PR55150_BAILOUT;
+ continue;
+ }
+
+ /* Check for consistency with readahead info */
+ len_consistent = (nextlen != (ROUNDUP(len, 16) >> 4));
+ if (len_consistent) {
+ /* Mismatch, force retry w/normal header (may be >4K) */
+ AP6210_ERR("%s (nextlen): mismatch, nextlen %d len %d rnd %d; "
+ "expected rxseq %d\n",
+ __FUNCTION__, nextlen, len, ROUNDUP(len, 16), rxseq);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE2();
+ dhd_os_sdunlock_rxq(bus->dhd);
+ dhdsdio_rxfail(bus, TRUE, (bus->bus == SPI_BUS) ? FALSE : TRUE);
+ GSPI_PR55150_BAILOUT;
+ continue;
+ }
+
+
+ /* Extract software header fields */
+ chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+ seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+ doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+ txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+
+ bus->nextlen =
+ bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
+ if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+ AP6210_DEBUG("%s (nextlen): got frame w/nextlen too large"
+ " (%d), seq %d\n", __FUNCTION__, bus->nextlen,
+ seq);
+ bus->nextlen = 0;
+ }
+
+ bus->dhd->rx_readahead_cnt ++;
+ /* Handle Flow Control */
+ fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+
+ delta = 0;
+ if (~bus->flowcontrol & fcbits) {
+ bus->fc_xoff++;
+ delta = 1;
+ }
+ if (bus->flowcontrol & ~fcbits) {
+ bus->fc_xon++;
+ delta = 1;
+ }
+
+ if (delta) {
+ bus->fc_rcvd++;
+ bus->flowcontrol = fcbits;
+ }
+
+ /* Check and update sequence number */
+ if (rxseq != seq) {
+ AP6210_DEBUG("%s (nextlen): rx_seq %d, expected %d\n",
+ __FUNCTION__, seq, rxseq);
+ bus->rx_badseq++;
+ rxseq = seq;
+ }
+
+ /* Check window for sanity */
+ if ((uint8)(txmax - bus->tx_seq) > 0x40) {
+ AP6210_ERR("%s: got unlikely tx max %d with tx_seq %d\n",
+ __FUNCTION__, txmax, bus->tx_seq);
+ txmax = bus->tx_max;
+ }
+ bus->tx_max = txmax;
+
+#ifdef DHD_DEBUG
+ if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+ prhex("Rx Data", rxbuf, len);
+ } else if (DHD_HDRS_ON()) {
+ prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN_RX);
+ }
+#endif
+
+ if (chan == SDPCM_CONTROL_CHANNEL) {
+ if (bus->bus == SPI_BUS) {
+ dhdsdio_read_control(bus, rxbuf, len, doff);
+ if (bus->usebufpool) {
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE(bus->dhd->osh, pkt, FALSE);
+ dhd_os_sdunlock_rxq(bus->dhd);
+ }
+ continue;
+ } else {
+ AP6210_ERR("%s (nextlen): readahead on control"
+ " packet %d?\n", __FUNCTION__, seq);
+ /* Force retry w/normal header read */
+ bus->nextlen = 0;
+ dhdsdio_rxfail(bus, FALSE, TRUE);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE2();
+ dhd_os_sdunlock_rxq(bus->dhd);
+ continue;
+ }
+ }
+
+ if ((bus->bus == SPI_BUS) && !bus->usebufpool) {
+ AP6210_ERR("Received %d bytes on %d channel. Running out of "
+ "rx pktbuf's or not yet malloced.\n", len, chan);
+ continue;
+ }
+
+ /* Validate data offset */
+ if ((doff < SDPCM_HDRLEN_RX) || (doff > len)) {
+ AP6210_ERR("%s (nextlen): bad data offset %d: HW len %d min %d\n",
+ __FUNCTION__, doff, len, SDPCM_HDRLEN_RX);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE2();
+ dhd_os_sdunlock_rxq(bus->dhd);
+ ASSERT(0);
+ dhdsdio_rxfail(bus, FALSE, FALSE);
+ continue;
+ }
+
+ /* All done with this one -- now deliver the packet */
+ goto deliver;
+ }
+ /* gSPI frames should not be handled in fractions */
+ if (bus->bus == SPI_BUS) {
+ break;
+ }
+
+ /* Read frame header (hardware and software) */
+ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
+ bus->rxhdr, firstread, NULL, NULL, NULL);
+ bus->f2rxhdrs++;
+ ASSERT(sdret != BCME_PENDING);
+
+ if (sdret < 0) {
+ AP6210_ERR("%s: RXHEADER FAILED: %d\n", __FUNCTION__, sdret);
+ bus->rx_hdrfail++;
+ dhdsdio_rxfail(bus, TRUE, TRUE);
+ continue;
+ }
+
+#ifdef DHD_DEBUG
+ if (DHD_BYTES_ON() || DHD_HDRS_ON()) {
+ prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN_RX);
+ }
+#endif
+
+ /* Extract hardware header fields */
+ len = ltoh16_ua(bus->rxhdr);
+ check = ltoh16_ua(bus->rxhdr + sizeof(uint16));
+
+ /* All zeros means no more frames */
+ if (!(len|check)) {
+ *finished = TRUE;
+ break;
+ }
+
+ /* Validate check bytes */
+ if ((uint16)~(len^check)) {
+ AP6210_ERR("%s: HW hdr error: len/check 0x%04x/0x%04x\n",
+ __FUNCTION__, len, check);
+ bus->rx_badhdr++;
+ dhdsdio_rxfail(bus, FALSE, FALSE);
+ continue;
+ }
+
+ /* Validate frame length */
+ if (len < SDPCM_HDRLEN_RX) {
+ AP6210_ERR("%s: HW hdr length invalid: %d\n", __FUNCTION__, len);
+ continue;
+ }
+
+ /* Extract software header fields */
+ chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+ seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+ doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+ txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+
+ /* Validate data offset */
+ if ((doff < SDPCM_HDRLEN_RX) || (doff > len)) {
+ AP6210_ERR("%s: Bad data offset %d: HW len %d, min %d seq %d\n",
+ __FUNCTION__, doff, len, SDPCM_HDRLEN_RX, seq);
+ bus->rx_badhdr++;
+ ASSERT(0);
+ dhdsdio_rxfail(bus, FALSE, FALSE);
+ continue;
+ }
+
+ /* Save the readahead length if there is one */
+ bus->nextlen = bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
+ if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+ AP6210_DEBUG("%s (nextlen): got frame w/nextlen too large (%d), seq %d\n",
+ __FUNCTION__, bus->nextlen, seq);
+ bus->nextlen = 0;
+ }
+
+ /* Handle Flow Control */
+ fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+
+ delta = 0;
+ if (~bus->flowcontrol & fcbits) {
+ bus->fc_xoff++;
+ delta = 1;
+ }
+ if (bus->flowcontrol & ~fcbits) {
+ bus->fc_xon++;
+ delta = 1;
+ }
+
+ if (delta) {
+ bus->fc_rcvd++;
+ bus->flowcontrol = fcbits;
+ }
+
+ /* Check and update sequence number */
+ if (rxseq != seq) {
+ AP6210_DEBUG("%s: rx_seq %d, expected %d\n", __FUNCTION__, seq, rxseq);
+ bus->rx_badseq++;
+ rxseq = seq;
+ }
+
+ /* Check window for sanity */
+ if ((uint8)(txmax - bus->tx_seq) > 0x40) {
+ AP6210_ERR("%s: got unlikely tx max %d with tx_seq %d\n",
+ __FUNCTION__, txmax, bus->tx_seq);
+ txmax = bus->tx_max;
+ }
+ bus->tx_max = txmax;
+
+ /* Call a separate function for control frames */
+ if (chan == SDPCM_CONTROL_CHANNEL) {
+ dhdsdio_read_control(bus, bus->rxhdr, len, doff);
+ continue;
+ }
+
+ ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL) ||
+ (chan == SDPCM_TEST_CHANNEL) || (chan == SDPCM_GLOM_CHANNEL));
+
+ /* Length to read */
+ rdlen = (len > firstread) ? (len - firstread) : 0;
+
+ /* May pad read to blocksize for efficiency */
+ if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
+ pad = bus->blocksize - (rdlen % bus->blocksize);
+ if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
+ ((rdlen + pad + firstread) < MAX_RX_DATASZ))
+ rdlen += pad;
+ } else if (rdlen % DHD_SDALIGN) {
+ rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+ }
+
+ /* Satisfy length-alignment requirements */
+ if (forcealign && (rdlen & (ALIGNMENT - 1)))
+ rdlen = ROUNDUP(rdlen, ALIGNMENT);
+
+ if ((rdlen + firstread) > MAX_RX_DATASZ) {
+ /* Too long -- skip this frame */
+ AP6210_ERR("%s: too long: len %d rdlen %d\n", __FUNCTION__, len, rdlen);
+ bus->dhd->rx_errors++; bus->rx_toolong++;
+ dhdsdio_rxfail(bus, FALSE, FALSE);
+ continue;
+ }
+
+ dhd_os_sdlock_rxq(bus->dhd);
+ if (!(pkt = PKTGET(osh, (rdlen + firstread + DHD_SDALIGN), FALSE))) {
+ /* Give up on data, request rtx of events */
+ AP6210_ERR("%s: PKTGET failed: rdlen %d chan %d\n",
+ __FUNCTION__, rdlen, chan);
+ bus->dhd->rx_dropped++;
+ dhd_os_sdunlock_rxq(bus->dhd);
+ dhdsdio_rxfail(bus, FALSE, RETRYCHAN(chan));
+ continue;
+ }
+ dhd_os_sdunlock_rxq(bus->dhd);
+
+ ASSERT(!PKTLINK(pkt));
+
+ /* Leave room for what we already read, and align remainder */
+ ASSERT(firstread < (PKTLEN(osh, pkt)));
+ PKTPULL(osh, pkt, firstread);
+ PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN);
+
+ /* Read the remaining frame data */
+ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
+ ((uint8 *)PKTDATA(osh, pkt)), rdlen, pkt, NULL, NULL);
+ bus->f2rxdata++;
+ ASSERT(sdret != BCME_PENDING);
+
+ if (sdret < 0) {
+ AP6210_ERR("%s: read %d %s bytes failed: %d\n", __FUNCTION__, rdlen,
+ ((chan == SDPCM_EVENT_CHANNEL) ? "event" :
+ ((chan == SDPCM_DATA_CHANNEL) ? "data" : "test")), sdret);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE(bus->dhd->osh, pkt, FALSE);
+ dhd_os_sdunlock_rxq(bus->dhd);
+ bus->dhd->rx_errors++;
+ dhdsdio_rxfail(bus, TRUE, RETRYCHAN(chan));
+ continue;
+ }
+
+ /* Copy the already-read portion */
+ PKTPUSH(osh, pkt, firstread);
+ bcopy(bus->rxhdr, PKTDATA(osh, pkt), firstread);
+
+#ifdef DHD_DEBUG
+ if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+ prhex("Rx Data", PKTDATA(osh, pkt), len);
+ }
+#endif
+
+deliver:
+ /* Save superframe descriptor and allocate packet frame */
+ if (chan == SDPCM_GLOM_CHANNEL) {
+ if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
+ AP6210_DEBUG("%s: got glom descriptor, %d bytes:\n",
+ __FUNCTION__, len);
+#ifdef DHD_DEBUG
+ if (DHD_GLOM_ON()) {
+ prhex("Glom Data", PKTDATA(osh, pkt), len);
+ }
+#endif
+ PKTSETLEN(osh, pkt, len);
+ ASSERT(doff == SDPCM_HDRLEN_RX);
+ PKTPULL(osh, pkt, SDPCM_HDRLEN_RX);
+ bus->glomd = pkt;
+ } else {
+ AP6210_ERR("%s: glom superframe w/o descriptor!\n", __FUNCTION__);
+ dhdsdio_rxfail(bus, FALSE, FALSE);
+ }
+ continue;
+ }
+
+ /* Fill in packet len and prio, deliver upward */
+ PKTSETLEN(osh, pkt, len);
+ PKTPULL(osh, pkt, doff);
+
+#ifdef SDTEST
+ /* Test channel packets are processed separately */
+ if (chan == SDPCM_TEST_CHANNEL) {
+ dhdsdio_testrcv(bus, pkt, seq);
+ continue;
+ }
+#endif /* SDTEST */
+
+ if (PKTLEN(osh, pkt) == 0) {
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE(bus->dhd->osh, pkt, FALSE);
+ dhd_os_sdunlock_rxq(bus->dhd);
+ continue;
+ } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt, reorder_info_buf,
+ &reorder_info_len) != 0) {
+ AP6210_ERR("%s: rx protocol error\n", __FUNCTION__);
+ dhd_os_sdlock_rxq(bus->dhd);
+ PKTFREE(bus->dhd->osh, pkt, FALSE);
+ dhd_os_sdunlock_rxq(bus->dhd);
+ bus->dhd->rx_errors++;
+ continue;
+ }
+ if (reorder_info_len) {
+ /* Reordering info from the firmware */
+ dhd_process_pkt_reorder_info(bus->dhd, reorder_info_buf, reorder_info_len,
+ &pkt, &pkt_count);
+ if (pkt_count == 0)
+ continue;
+ }
+ else
+ pkt_count = 1;
+
+
+ /* Unlock during rx call */
+ dhd_os_sdunlock(bus->dhd);
+ dhd_rx_frame(bus->dhd, ifidx, pkt, pkt_count, chan);
+ dhd_os_sdlock(bus->dhd);
+ }
+ rxcount = maxframes - rxleft;
+#ifdef DHD_DEBUG
+ /* Message if we hit the limit */
+ if (!rxleft && !sdtest)
+ AP6210_DEBUG("%s: hit rx limit of %d frames\n", __FUNCTION__, maxframes);
+ else
+#endif /* DHD_DEBUG */
+ AP6210_DEBUG("%s: processed %d frames\n", __FUNCTION__, rxcount);
+ /* Back off rxseq if awaiting rtx, update rx_seq */
+ if (bus->rxskip)
+ rxseq--;
+ bus->rx_seq = rxseq;
+
+ if (bus->reqbussleep)
+ {
+ dhdsdio_bussleep(bus, TRUE);
+ bus->reqbussleep = FALSE;
+ }
+ bus->readframes = FALSE;
+
+ return rxcount;
+}
+
+static uint32
+dhdsdio_hostmail(dhd_bus_t *bus)
+{
+ sdpcmd_regs_t *regs = bus->regs;
+ uint32 intstatus = 0;
+ uint32 hmb_data;
+ uint8 fcbits;
+ uint retries = 0;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ /* Read mailbox data and ack that we did so */
+ R_SDREG(hmb_data, &regs->tohostmailboxdata, retries);
+ if (retries <= retry_limit)
+ W_SDREG(SMB_INT_ACK, &regs->tosbmailbox, retries);
+ bus->f1regdata += 2;
+
+ /* Dongle recomposed rx frames, accept them again */
+ if (hmb_data & HMB_DATA_NAKHANDLED) {
+ AP6210_DEBUG("Dongle reports NAK handled, expect rtx of %d\n", bus->rx_seq);
+ if (!bus->rxskip) {
+ AP6210_ERR("%s: unexpected NAKHANDLED!\n", __FUNCTION__);
+ }
+ bus->rxskip = FALSE;
+ intstatus |= FRAME_AVAIL_MASK(bus);
+ }
+
+ /*
+ * DEVREADY does not occur with gSPI.
+ */
+ if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
+ bus->sdpcm_ver = (hmb_data & HMB_DATA_VERSION_MASK) >> HMB_DATA_VERSION_SHIFT;
+ if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
+ AP6210_ERR("Version mismatch, dongle reports %d, expecting %d\n",
+ bus->sdpcm_ver, SDPCM_PROT_VERSION);
+ else
+ AP6210_ERR("Dongle ready, protocol version %d\n", bus->sdpcm_ver);
+ /* make sure for the SDIO_DEVICE_RXDATAINT_MODE_1 corecontrol is proper */
+ if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev >= 4) &&
+ (bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_1)) {
+ uint32 val;
+
+ val = R_REG(bus->dhd->osh, &bus->regs->corecontrol);
+ val &= ~CC_XMTDATAAVAIL_MODE;
+ val |= CC_XMTDATAAVAIL_CTRL;
+ W_REG(bus->dhd->osh, &bus->regs->corecontrol, val);
+
+ val = R_REG(bus->dhd->osh, &bus->regs->corecontrol);
+ }
+
+#ifdef DHD_DEBUG
+ /* Retrieve console state address now that firmware should have updated it */
+ {
+ sdpcm_shared_t shared;
+ if (dhdsdio_readshared(bus, &shared) == 0)
+ bus->console_addr = shared.console_addr;
+ }
+#endif /* DHD_DEBUG */
+ }
+
+ /*
+ * Flow Control has been moved into the RX headers and this out of band
+ * method isn't used any more. Leave this here for possibly remaining backward
+ * compatible with older dongles
+ */
+ if (hmb_data & HMB_DATA_FC) {
+ fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT;
+
+ if (fcbits & ~bus->flowcontrol)
+ bus->fc_xoff++;
+ if (bus->flowcontrol & ~fcbits)
+ bus->fc_xon++;
+
+ bus->fc_rcvd++;
+ bus->flowcontrol = fcbits;
+ }
+
+#ifdef DHD_DEBUG
+ /* At least print a message if FW halted */
+ if (hmb_data & HMB_DATA_FWHALT) {
+ AP6210_ERR("INTERNAL ERROR: FIRMWARE HALTED : set BUS DOWN\n");
+ dhdsdio_checkdied(bus, NULL, 0);
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ }
+#endif /* DHD_DEBUG */
+
+ /* Shouldn't be any others */
+ if (hmb_data & ~(HMB_DATA_DEVREADY |
+ HMB_DATA_FWHALT |
+ HMB_DATA_NAKHANDLED |
+ HMB_DATA_FC |
+ HMB_DATA_FWREADY |
+ HMB_DATA_FCDATA_MASK |
+ HMB_DATA_VERSION_MASK)) {
+ AP6210_ERR("Unknown mailbox data content: 0x%02x\n", hmb_data);
+ }
+
+ return intstatus;
+}
+
+static bool
+dhdsdio_dpc(dhd_bus_t *bus)
+{
+ bcmsdh_info_t *sdh = bus->sdh;
+ sdpcmd_regs_t *regs = bus->regs;
+ uint32 intstatus, newstatus = 0;
+ uint retries = 0;
+ uint rxlimit = dhd_rxbound; /* Rx frames to read before resched */
+ uint txlimit = dhd_txbound; /* Tx frames to send before resched */
+ uint framecnt = 0; /* Temporary counter of tx/rx frames */
+ bool rxdone = TRUE; /* Flag for no more read data */
+ bool resched = FALSE; /* Flag indicating resched wanted */
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (bus->dhd->busstate == DHD_BUS_DOWN) {
+ AP6210_ERR("%s: Bus down, ret\n", __FUNCTION__);
+ bus->intstatus = 0;
+ return 0;
+ }
+
+ /* Start with leftover status bits */
+ intstatus = bus->intstatus;
+
+ dhd_os_sdlock(bus->dhd);
+
+ if (!SLPAUTO_ENAB(bus) && !KSO_ENAB(bus)) {
+ AP6210_ERR("%s: Device asleep\n", __FUNCTION__);
+ goto exit;
+ }
+
+ /* If waiting for HTAVAIL, check status */
+ if (!SLPAUTO_ENAB(bus) && (bus->clkstate == CLK_PENDING)) {
+ int err;
+ uint8 clkctl, devctl = 0;
+
+#ifdef DHD_DEBUG
+ /* Check for inconsistent device control */
+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+ if (err) {
+ AP6210_ERR("%s: error reading DEVCTL: %d\n", __FUNCTION__, err);
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ } else {
+ ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY);
+ }
+#endif /* DHD_DEBUG */
+
+ /* Read CSR, if clock on switch to AVAIL, else ignore */
+ clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
+ if (err) {
+ AP6210_ERR("%s: error reading CSR: %d\n", __FUNCTION__, err);
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ }
+
+ AP6210_DEBUG("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl, clkctl);
+
+ if (SBSDIO_HTAV(clkctl)) {
+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+ if (err) {
+ AP6210_ERR("%s: error reading DEVCTL: %d\n",
+ __FUNCTION__, err);
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ }
+ devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err);
+ if (err) {
+ AP6210_ERR("%s: error writing DEVCTL: %d\n",
+ __FUNCTION__, err);
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ }
+ bus->clkstate = CLK_AVAIL;
+ } else {
+ goto clkwait;
+ }
+ }
+
+ BUS_WAKE(bus);
+
+ /* Make sure backplane clock is on */
+ dhdsdio_clkctl(bus, CLK_AVAIL, TRUE);
+ if (bus->clkstate != CLK_AVAIL)
+ goto clkwait;
+
+ /* Pending interrupt indicates new device status */
+ if (bus->ipend) {
+ bus->ipend = FALSE;
+ R_SDREG(newstatus, &regs->intstatus, retries);
+ bus->f1regdata++;
+ if (bcmsdh_regfail(bus->sdh))
+ newstatus = 0;
+ newstatus &= bus->hostintmask;
+ bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
+ if (newstatus) {
+ bus->f1regdata++;
+ if ((bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_0) &&
+ (newstatus == I_XMTDATA_AVAIL)) {
+ }
+ else
+ W_SDREG(newstatus, &regs->intstatus, retries);
+ }
+ }
+
+ /* Merge new bits with previous */
+ intstatus |= newstatus;
+ bus->intstatus = 0;
+
+ /* Handle flow-control change: read new state in case our ack
+ * crossed another change interrupt. If change still set, assume
+ * FC ON for safety, let next loop through do the debounce.
+ */
+ if (intstatus & I_HMB_FC_CHANGE) {
+ intstatus &= ~I_HMB_FC_CHANGE;
+ W_SDREG(I_HMB_FC_CHANGE, &regs->intstatus, retries);
+ R_SDREG(newstatus, &regs->intstatus, retries);
+ bus->f1regdata += 2;
+ bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
+ intstatus |= (newstatus & bus->hostintmask);
+ }
+
+ /* Just being here means nothing more to do for chipactive */
+ if (intstatus & I_CHIPACTIVE) {
+ /* ASSERT(bus->clkstate == CLK_AVAIL); */
+ intstatus &= ~I_CHIPACTIVE;
+ }
+
+ /* Handle host mailbox indication */
+ if (intstatus & I_HMB_HOST_INT) {
+ intstatus &= ~I_HMB_HOST_INT;
+ intstatus |= dhdsdio_hostmail(bus);
+ }
+
+ /* Generally don't ask for these, can get CRC errors... */
+ if (intstatus & I_WR_OOSYNC) {
+ AP6210_DEBUG("Dongle reports WR_OOSYNC\n");
+ intstatus &= ~I_WR_OOSYNC;
+ }
+
+ if (intstatus & I_RD_OOSYNC) {
+ AP6210_DEBUG("Dongle reports RD_OOSYNC\n");
+ intstatus &= ~I_RD_OOSYNC;
+ }
+
+ if (intstatus & I_SBINT) {
+ AP6210_DEBUG("Dongle reports SBINT\n");
+ intstatus &= ~I_SBINT;
+ }
+
+ /* Would be active due to wake-wlan in gSPI */
+ if (intstatus & I_CHIPACTIVE) {
+ AP6210_DEBUG("Dongle reports CHIPACTIVE\n");
+ intstatus &= ~I_CHIPACTIVE;
+ }
+
+ /* Ignore frame indications if rxskip is set */
+ if (bus->rxskip) {
+ intstatus &= ~FRAME_AVAIL_MASK(bus);
+ }
+
+ /* On frame indication, read available frames */
+ if (PKT_AVAILABLE(bus, intstatus)) {
+ framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone);
+ if (rxdone || bus->rxskip)
+ intstatus &= ~FRAME_AVAIL_MASK(bus);
+ rxlimit -= MIN(framecnt, rxlimit);
+ }
+
+ /* Keep still-pending events for next scheduling */
+ bus->intstatus = intstatus;
+
+clkwait:
+ /* Re-enable interrupts to detect new device events (mailbox, rx frame)
+ * or clock availability. (Allows tx loop to check ipend if desired.)
+ * (Unless register access seems hosed, as we may not be able to ACK...)
+ */
+ if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
+ AP6210_DEBUG("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
+ __FUNCTION__, rxdone, framecnt);
+ bus->intdis = FALSE;
+#if defined(OOB_INTR_ONLY)
+ bcmsdh_oob_intr_set(1);
+#endif /* defined(OOB_INTR_ONLY) */
+ bcmsdh_intr_enable(sdh);
+ }
+
+#if defined(OOB_INTR_ONLY) && !defined(HW_OOB)
+ /* In case of SW-OOB(using edge trigger),
+ * Check interrupt status in the dongle again after enable irq on the host.
+ * and rechedule dpc if interrupt is pended in the dongle.
+ * There is a chance to miss OOB interrupt while irq is disabled on the host.
+ * No need to do this with HW-OOB(level trigger)
+ */
+ R_SDREG(newstatus, &regs->intstatus, retries);
+ if (bcmsdh_regfail(bus->sdh))
+ newstatus = 0;
+ if (newstatus & bus->hostintmask) {
+ bus->ipend = TRUE;
+ resched = TRUE;
+ }
+#endif /* defined(OOB_INTR_ONLY) && !defined(HW_OOB) */
+#ifdef PROP_TXSTATUS
+ dhd_wlfc_trigger_pktcommit(bus->dhd);
+#endif
+ if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) {
+ int ret, i;
+
+ uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN;
+
+ if (*frame_seq != bus->tx_seq) {
+ AP6210_DEBUG("%s IOCTL frame seq lag detected!"
+ " frm_seq:%d != bus->tx_seq:%d, corrected\n",
+ __FUNCTION__, *frame_seq, bus->tx_seq);
+ *frame_seq = bus->tx_seq;
+ }
+
+ ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
+ (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len,
+ NULL, NULL, NULL);
+ ASSERT(ret != BCME_PENDING);
+ if (ret == BCME_NODEVICE) {
+ AP6210_ERR("%s: Device asleep already\n", __FUNCTION__);
+ } else if (ret < 0) {
+ /* On failure, abort the command and terminate the frame */
+ AP6210_DEBUG("%s: sdio error %d, abort command and terminate frame.\n",
+ __FUNCTION__, ret);
+ bus->tx_sderrs++;
+
+ bcmsdh_abort(sdh, SDIO_FUNC_2);
+
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL,
+ SFC_WF_TERM, NULL);
+ bus->f1regdata++;
+
+ for (i = 0; i < 3; i++) {
+ uint8 hi, lo;
+ hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_WFRAMEBCHI, NULL);
+ lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_WFRAMEBCLO, NULL);
+ bus->f1regdata += 2;
+ if ((hi == 0) && (lo == 0))
+ break;
+ }
+ }
+ if (ret == 0) {
+ bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+ }
+
+ bus->ctrl_frame_stat = FALSE;
+ dhd_wait_event_wakeup(bus->dhd);
+ }
+ /* Send queued frames (limit 1 if rx may still be pending) */
+ else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
+ pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) {
+ framecnt = rxdone ? txlimit : MIN(txlimit, dhd_txminmax);
+ framecnt = dhdsdio_sendfromq(bus, framecnt);
+ txlimit -= framecnt;
+ }
+ /* Resched the DPC if ctrl cmd is pending on bus credit */
+ if (bus->ctrl_frame_stat)
+ resched = TRUE;
+
+ /* Resched if events or tx frames are pending, else await next interrupt */
+ /* On failed register access, all bets are off: no resched or interrupts */
+ if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) {
+ if ((bus->sih && bus->sih->buscorerev >= 12) && !(dhdsdio_sleepcsr_get(bus) &
+ SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) {
+ /* Bus failed because of KSO */
+ AP6210_ERR("%s: Bus failed due to KSO\n", __FUNCTION__);
+ bus->kso = FALSE;
+ } else {
+ AP6210_ERR("%s: failed backplane access over SDIO, halting operation\n",
+ __FUNCTION__);
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ bus->intstatus = 0;
+ }
+ } else if (bus->clkstate == CLK_PENDING) {
+ /* Awaiting I_CHIPACTIVE; don't resched */
+ } else if (bus->intstatus || bus->ipend ||
+ (!bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) && DATAOK(bus)) ||
+ PKT_AVAILABLE(bus, bus->intstatus)) { /* Read multiple frames */
+ resched = TRUE;
+ }
+
+ bus->dpc_sched = resched;
+
+ /* If we're done for now, turn off clock request. */
+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && (bus->clkstate != CLK_PENDING)) {
+ bus->activity = FALSE;
+ dhdsdio_clkctl(bus, CLK_NONE, FALSE);
+ }
+
+exit:
+ dhd_os_sdunlock(bus->dhd);
+ return resched;
+}
+
+bool
+dhd_bus_dpc(struct dhd_bus *bus)
+{
+ bool resched;
+
+ /* Call the DPC directly. */
+ AP6210_DEBUG("Calling dhdsdio_dpc() from %s\n", __FUNCTION__);
+ resched = dhdsdio_dpc(bus);
+
+ return resched;
+}
+
+void
+dhdsdio_isr(void *arg)
+{
+ dhd_bus_t *bus = (dhd_bus_t*)arg;
+ bcmsdh_info_t *sdh;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (!bus) {
+ AP6210_ERR("%s : bus is null pointer , exit \n", __FUNCTION__);
+ return;
+ }
+ sdh = bus->sdh;
+
+ if (bus->dhd->busstate == DHD_BUS_DOWN) {
+ AP6210_ERR("%s : bus is down. we have nothing to do\n", __FUNCTION__);
+ return;
+ }
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ /* Count the interrupt call */
+ bus->intrcount++;
+ bus->ipend = TRUE;
+
+ /* Shouldn't get this interrupt if we're sleeping? */
+ if (!SLPAUTO_ENAB(bus)) {
+ if (bus->sleeping) {
+ AP6210_ERR("INTERRUPT WHILE SLEEPING??\n");
+ return;
+ } else if (!KSO_ENAB(bus)) {
+ AP6210_ERR("ISR in devsleep 1\n");
+ }
+ }
+
+ /* Disable additional interrupts (is this needed now)? */
+ if (bus->intr) {
+ AP6210_DEBUG("%s: disable SDIO interrupts\n", __FUNCTION__);
+ } else {
+ AP6210_ERR("dhdsdio_isr() w/o interrupt configured!\n");
+ }
+
+ bcmsdh_intr_disable(sdh);
+ bus->intdis = TRUE;
+
+#if defined(SDIO_ISR_THREAD)
+ AP6210_DEBUG("Calling dhdsdio_dpc() from %s\n", __FUNCTION__);
+ DHD_OS_WAKE_LOCK(bus->dhd);
+ while (dhdsdio_dpc(bus));
+ DHD_OS_WAKE_UNLOCK(bus->dhd);
+#else
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd);
+#endif
+
+}
+
+#ifdef SDTEST
+static void
+dhdsdio_pktgen_init(dhd_bus_t *bus)
+{
+ /* Default to specified length, or full range */
+ if (dhd_pktgen_len) {
+ bus->pktgen_maxlen = MIN(dhd_pktgen_len, MAX_PKTGEN_LEN);
+ bus->pktgen_minlen = bus->pktgen_maxlen;
+ } else {
+ bus->pktgen_maxlen = MAX_PKTGEN_LEN;
+ bus->pktgen_minlen = 0;
+ }
+ bus->pktgen_len = (uint16)bus->pktgen_minlen;
+
+ /* Default to per-watchdog burst with 10s print time */
+ bus->pktgen_freq = 1;
+ bus->pktgen_print = dhd_watchdog_ms ? (10000/dhd_watchdog_ms):0;
+ bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000;
+
+ /* Default to echo mode */
+ bus->pktgen_mode = DHD_PKTGEN_ECHO;
+ bus->pktgen_stop = 1;
+}
+
+static void
+dhdsdio_pktgen(dhd_bus_t *bus)
+{
+ void *pkt;
+ uint8 *data;
+ uint pktcount;
+ uint fillbyte;
+ osl_t *osh = bus->dhd->osh;
+ uint16 len;
+ ulong time_lapse;
+ uint sent_pkts;
+ uint rcvd_pkts;
+
+ /* Display current count if appropriate */
+ if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) {
+ bus->pktgen_ptick = 0;
+ AP6210_DEBUG("%s: send attempts %d, rcvd %d, errors %d\n",
+ __FUNCTION__, bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail);
+
+ /* Print throughput stats only for constant length packet runs */
+ if (bus->pktgen_minlen == bus->pktgen_maxlen) {
+ time_lapse = jiffies - bus->pktgen_prev_time;
+ bus->pktgen_prev_time = jiffies;
+ sent_pkts = bus->pktgen_sent - bus->pktgen_prev_sent;
+ bus->pktgen_prev_sent = bus->pktgen_sent;
+ rcvd_pkts = bus->pktgen_rcvd - bus->pktgen_prev_rcvd;
+ bus->pktgen_prev_rcvd = bus->pktgen_rcvd;
+
+ AP6210_DEBUG("%s: Tx Throughput %d kbps, Rx Throughput %d kbps\n",
+ __FUNCTION__,
+ (sent_pkts * bus->pktgen_len / jiffies_to_msecs(time_lapse)) * 8,
+ (rcvd_pkts * bus->pktgen_len / jiffies_to_msecs(time_lapse)) * 8);
+ }
+ }
+
+ /* For recv mode, just make sure dongle has started sending */
+ if (bus->pktgen_mode == DHD_PKTGEN_RECV) {
+ if (bus->pktgen_rcv_state == PKTGEN_RCV_IDLE) {
+ bus->pktgen_rcv_state = PKTGEN_RCV_ONGOING;
+ dhdsdio_sdtest_set(bus, bus->pktgen_total);
+ }
+ return;
+ }
+
+ /* Otherwise, generate or request the specified number of packets */
+ for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) {
+ /* Stop if total has been reached */
+ if (bus->pktgen_total && (bus->pktgen_sent >= bus->pktgen_total)) {
+ bus->pktgen_count = 0;
+ break;
+ }
+
+ /* Allocate an appropriate-sized packet */
+ if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) {
+ len = SDPCM_TEST_PKT_CNT_FLD_LEN;
+ } else {
+ len = bus->pktgen_len;
+ }
+ if (!(pkt = PKTGET(osh, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN),
+ TRUE))) {;
+ AP6210_ERR("%s: PKTGET failed!\n", __FUNCTION__);
+ break;
+ }
+ PKTALIGN(osh, pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN);
+ data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN;
+
+ /* Write test header cmd and extra based on mode */
+ switch (bus->pktgen_mode) {
+ case DHD_PKTGEN_ECHO:
+ *data++ = SDPCM_TEST_ECHOREQ;
+ *data++ = (uint8)bus->pktgen_sent;
+ break;
+
+ case DHD_PKTGEN_SEND:
+ *data++ = SDPCM_TEST_DISCARD;
+ *data++ = (uint8)bus->pktgen_sent;
+ break;
+
+ case DHD_PKTGEN_RXBURST:
+ *data++ = SDPCM_TEST_BURST;
+ *data++ = (uint8)bus->pktgen_count; /* Just for backward compatability */
+ break;
+
+ default:
+ AP6210_ERR("Unrecognized pktgen mode %d\n", bus->pktgen_mode);
+ PKTFREE(osh, pkt, TRUE);
+ bus->pktgen_count = 0;
+ return;
+ }
+
+ /* Write test header length field */
+ *data++ = (bus->pktgen_len >> 0);
+ *data++ = (bus->pktgen_len >> 8);
+
+ /* Write frame count in a 4 byte field adjucent to SDPCM test header for
+ * burst mode
+ */
+ if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) {
+ *data++ = (uint8)(bus->pktgen_count >> 0);
+ *data++ = (uint8)(bus->pktgen_count >> 8);
+ *data++ = (uint8)(bus->pktgen_count >> 16);
+ *data++ = (uint8)(bus->pktgen_count >> 24);
+ } else {
+
+ /* Then fill in the remainder -- N/A for burst */
+ for (fillbyte = 0; fillbyte < len; fillbyte++)
+ *data++ = SDPCM_TEST_FILL(fillbyte, (uint8)bus->pktgen_sent);
+ }
+
+#ifdef DHD_DEBUG
+ if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+ data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN;
+ prhex("dhdsdio_pktgen: Tx Data", data, PKTLEN(osh, pkt) - SDPCM_HDRLEN);
+ }
+#endif
+
+ /* Send it */
+ if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE, FALSE)) {
+ bus->pktgen_fail++;
+ if (bus->pktgen_stop && bus->pktgen_stop == bus->pktgen_fail)
+ bus->pktgen_count = 0;
+ }
+ bus->pktgen_sent++;
+
+ /* Bump length if not fixed, wrap at max */
+ if (++bus->pktgen_len > bus->pktgen_maxlen)
+ bus->pktgen_len = (uint16)bus->pktgen_minlen;
+
+ /* Special case for burst mode: just send one request! */
+ if (bus->pktgen_mode == DHD_PKTGEN_RXBURST)
+ break;
+ }
+}
+
+static void
+dhdsdio_sdtest_set(dhd_bus_t *bus, uint count)
+{
+ void *pkt;
+ uint8 *data;
+ osl_t *osh = bus->dhd->osh;
+
+ /* Allocate the packet */
+ if (!(pkt = PKTGET(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN +
+ SDPCM_TEST_PKT_CNT_FLD_LEN + DHD_SDALIGN, TRUE))) {
+ AP6210_ERR("%s: PKTGET failed!\n", __FUNCTION__);
+ return;
+ }
+ PKTALIGN(osh, pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN +
+ SDPCM_TEST_PKT_CNT_FLD_LEN), DHD_SDALIGN);
+ data = (uint8*)PKTDATA(osh, pkt) + SDPCM_HDRLEN;
+
+ /* Fill in the test header */
+ *data++ = SDPCM_TEST_SEND;
+ *data++ = (count > 0)?TRUE:FALSE;
+ *data++ = (bus->pktgen_maxlen >> 0);
+ *data++ = (bus->pktgen_maxlen >> 8);
+ *data++ = (uint8)(count >> 0);
+ *data++ = (uint8)(count >> 8);
+ *data++ = (uint8)(count >> 16);
+ *data++ = (uint8)(count >> 24);
+
+ /* Send it */
+ if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE, FALSE))
+ bus->pktgen_fail++;
+}
+
+
+static void
+dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq)
+{
+ osl_t *osh = bus->dhd->osh;
+ uint8 *data;
+ uint pktlen;
+
+ uint8 cmd;
+ uint8 extra;
+ uint16 len;
+ uint16 offset;
+
+ /* Check for min length */
+ if ((pktlen = PKTLEN(osh, pkt)) < SDPCM_TEST_HDRLEN) {
+ AP6210_ERR("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen);
+ PKTFREE(osh, pkt, FALSE);
+ return;
+ }
+
+ /* Extract header fields */
+ data = PKTDATA(osh, pkt);
+ cmd = *data++;
+ extra = *data++;
+ len = *data++; len += *data++ << 8;
+ AP6210_DEBUG("%s:cmd:%d, xtra:%d,len:%d\n", __FUNCTION__, cmd, extra, len);
+ /* Check length for relevant commands */
+ if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ || cmd == SDPCM_TEST_ECHORSP) {
+ if (pktlen != len + SDPCM_TEST_HDRLEN) {
+ AP6210_ERR("dhdsdio_testrcv: frame length mismatch, pktlen %d seq %d"
+ " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len);
+ PKTFREE(osh, pkt, FALSE);
+ return;
+ }
+ }
+
+ /* Process as per command */
+ switch (cmd) {
+ case SDPCM_TEST_ECHOREQ:
+ /* Rx->Tx turnaround ok (even on NDIS w/current implementation) */
+ *(uint8 *)(PKTDATA(osh, pkt)) = SDPCM_TEST_ECHORSP;
+ if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, TRUE, FALSE) == 0) {
+ bus->pktgen_sent++;
+ } else {
+ bus->pktgen_fail++;
+ PKTFREE(osh, pkt, FALSE);
+ }
+ bus->pktgen_rcvd++;
+ break;
+
+ case SDPCM_TEST_ECHORSP:
+ if (bus->ext_loop) {
+ PKTFREE(osh, pkt, FALSE);
+ bus->pktgen_rcvd++;
+ break;
+ }
+
+ for (offset = 0; offset < len; offset++, data++) {
+ if (*data != SDPCM_TEST_FILL(offset, extra)) {
+ AP6210_ERR("dhdsdio_testrcv: echo data mismatch: "
+ "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n",
+ offset, len, SDPCM_TEST_FILL(offset, extra), *data);
+ break;
+ }
+ }
+ PKTFREE(osh, pkt, FALSE);
+ bus->pktgen_rcvd++;
+ break;
+
+ case SDPCM_TEST_DISCARD:
+ {
+ int i = 0;
+ uint8 *prn = data;
+ uint8 testval = extra;
+ for (i = 0; i < len; i++) {
+ if (*prn != testval) {
+ AP6210_ERR("DIErr@Pkt#:%d,Ix:%d, expected:0x%x, got:0x%x\n",
+ i, bus->pktgen_rcvd_rcvsession, testval, *prn);
+ prn++; testval++;
+ }
+ }
+ }
+ PKTFREE(osh, pkt, FALSE);
+ bus->pktgen_rcvd++;
+ break;
+
+ case SDPCM_TEST_BURST:
+ case SDPCM_TEST_SEND:
+ default:
+ AP6210_DEBUG("dhdsdio_testrcv: unsupported or unknown command, pktlen %d seq %d"
+ " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len);
+ PKTFREE(osh, pkt, FALSE);
+ break;
+ }
+
+ /* For recv mode, stop at limit (and tell dongle to stop sending) */
+ if (bus->pktgen_mode == DHD_PKTGEN_RECV) {
+ if (bus->pktgen_rcv_state != PKTGEN_RCV_IDLE) {
+ bus->pktgen_rcvd_rcvsession++;
+
+ if (bus->pktgen_total &&
+ (bus->pktgen_rcvd_rcvsession >= bus->pktgen_total)) {
+ bus->pktgen_count = 0;
+ AP6210_ERR("Pktgen:rcv test complete!\n");
+ bus->pktgen_rcv_state = PKTGEN_RCV_IDLE;
+ dhdsdio_sdtest_set(bus, FALSE);
+ bus->pktgen_rcvd_rcvsession = 0;
+ }
+ }
+ }
+}
+#endif /* SDTEST */
+
+extern void
+dhd_disable_intr(dhd_pub_t *dhdp)
+{
+ dhd_bus_t *bus;
+ bus = dhdp->bus;
+ bcmsdh_intr_disable(bus->sdh);
+}
+
+extern bool
+dhd_bus_watchdog(dhd_pub_t *dhdp)
+{
+ dhd_bus_t *bus;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ bus = dhdp->bus;
+
+ if (bus->dhd->dongle_reset)
+ return FALSE;
+
+ /* Ignore the timer if simulating bus down */
+ if (!SLPAUTO_ENAB(bus) && bus->sleeping)
+ return FALSE;
+
+ if (dhdp->busstate == DHD_BUS_DOWN)
+ return FALSE;
+
+ /* Poll period: check device if appropriate. */
+ if (!SLPAUTO_ENAB(bus) && (bus->poll && (++bus->polltick >= bus->pollrate))) {
+ uint32 intstatus = 0;
+
+ /* Reset poll tick */
+ bus->polltick = 0;
+
+ /* Check device if no interrupts */
+ if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
+
+ if (!bus->dpc_sched) {
+ uint8 devpend;
+ devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0,
+ SDIOD_CCCR_INTPEND, NULL);
+ intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2);
+ }
+
+ /* If there is something, make like the ISR and schedule the DPC */
+ if (intstatus) {
+ bus->pollcnt++;
+ bus->ipend = TRUE;
+ if (bus->intr) {
+ bcmsdh_intr_disable(bus->sdh);
+ }
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd);
+
+ }
+ }
+
+ /* Update interrupt tracking */
+ bus->lastintrs = bus->intrcount;
+ }
+
+#ifdef DHD_DEBUG
+ /* Poll for console output periodically */
+ if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) {
+ bus->console.count += dhd_watchdog_ms;
+ if (bus->console.count >= dhd_console_ms) {
+ bus->console.count -= dhd_console_ms;
+ /* Make sure backplane clock is on */
+ if (SLPAUTO_ENAB(bus))
+ dhdsdio_bussleep(bus, FALSE);
+ else
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+ if (dhdsdio_readconsole(bus) < 0)
+ dhd_console_ms = 0; /* On error, stop trying */
+ }
+ }
+#endif /* DHD_DEBUG */
+
+#ifdef SDTEST
+ /* Generate packets if configured */
+ if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) {
+ /* Make sure backplane clock is on */
+ if (SLPAUTO_ENAB(bus))
+ dhdsdio_bussleep(bus, FALSE);
+ else
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+ bus->pktgen_tick = 0;
+ dhdsdio_pktgen(bus);
+ }
+#endif
+
+ /* On idle timeout clear activity flag and/or turn off clock */
+#ifdef DHD_USE_IDLECOUNT
+ if (bus->activity)
+ bus->activity = FALSE;
+ else {
+ bus->idlecount++;
+
+ if (bus->idlecount >= bus->idletime) {
+ AP6210_DEBUG("%s: DHD Idle state!!\n", __FUNCTION__);
+
+ if (SLPAUTO_ENAB(bus)) {
+ if (dhdsdio_bussleep(bus, TRUE) != BCME_BUSY)
+ dhd_os_wd_timer(bus->dhd, 0);
+ } else
+ dhdsdio_clkctl(bus, CLK_NONE, FALSE);
+
+ bus->idlecount = 0;
+ }
+ }
+#else
+ if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
+ if (++bus->idlecount > bus->idletime) {
+ bus->idlecount = 0;
+ if (bus->activity) {
+ bus->activity = FALSE;
+ if (SLPAUTO_ENAB(bus)) {
+ if (!bus->readframes)
+ dhdsdio_bussleep(bus, TRUE);
+ else
+ bus->reqbussleep = TRUE;
+ }
+ else
+ dhdsdio_clkctl(bus, CLK_NONE, FALSE);
+ }
+ }
+ }
+#endif /* DHD_USE_IDLECOUNT */
+
+ return bus->ipend;
+}
+
+#ifdef DHD_DEBUG
+extern int
+dhd_bus_console_in(dhd_pub_t *dhdp, uchar *msg, uint msglen)
+{
+ dhd_bus_t *bus = dhdp->bus;
+ uint32 addr, val;
+ int rv;
+ void *pkt;
+
+ /* Address could be zero if CONSOLE := 0 in dongle Makefile */
+ if (bus->console_addr == 0)
+ return BCME_UNSUPPORTED;
+
+ /* Exclusive bus access */
+ dhd_os_sdlock(bus->dhd);
+
+ /* Don't allow input if dongle is in reset */
+ if (bus->dhd->dongle_reset) {
+ dhd_os_sdunlock(bus->dhd);
+ return BCME_NOTREADY;
+ }
+
+ /* Request clock to allow SDIO accesses */
+ BUS_WAKE(bus);
+ /* No pend allowed since txpkt is called later, ht clk has to be on */
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+
+ /* Zero cbuf_index */
+ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf_idx);
+ val = htol32(0);
+ if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0)
+ goto done;
+
+ /* Write message into cbuf */
+ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, cbuf);
+ if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)msg, msglen)) < 0)
+ goto done;
+
+ /* Write length into vcons_in */
+ addr = bus->console_addr + OFFSETOF(hndrte_cons_t, vcons_in);
+ val = htol32(msglen);
+ if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0)
+ goto done;
+
+ /* Bump dongle by sending an empty packet on the event channel.
+ * sdpcm_sendup (RX) checks for virtual console input.
+ */
+ if ((pkt = PKTGET(bus->dhd->osh, 4 + SDPCM_RESERVE, TRUE)) != NULL)
+ dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, TRUE, FALSE);
+
+done:
+ if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+ bus->activity = FALSE;
+ dhdsdio_clkctl(bus, CLK_NONE, TRUE);
+ }
+
+ dhd_os_sdunlock(bus->dhd);
+
+ return rv;
+}
+#endif /* DHD_DEBUG */
+
+#ifdef DHD_DEBUG
+static void
+dhd_dump_cis(uint fn, uint8 *cis)
+{
+ uint byte, tag, tdata;
+ AP6210_DEBUG("Function %d CIS:\n", fn);
+
+ for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) {
+ if ((byte % 16) == 0)
+ AP6210_DUMP(" ");
+ AP6210_DUMP("%02x ", cis[byte]);
+ if ((byte % 16) == 15)
+ AP6210_DUMP("\n");
+ if (!tdata--) {
+ tag = cis[byte];
+ if (tag == 0xff)
+ break;
+ else if (!tag)
+ tdata = 0;
+ else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT)
+ tdata = cis[byte + 1] + 1;
+ else
+ AP6210_DUMP("]");
+ }
+ }
+ if ((byte % 16) != 15)
+ AP6210_DUMP("\n");
+}
+#endif /* DHD_DEBUG */
+
+static bool
+dhdsdio_chipmatch(uint16 chipid)
+{
+ if (chipid == BCM4325_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4329_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4315_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4319_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4336_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4330_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM43237_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM43362_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4314_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4334_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM43341_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM43239_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4324_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4335_CHIP_ID)
+ return TRUE;
+ return FALSE;
+}
+
+static void *
+dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
+ uint16 func, uint bustype, void *regsva, osl_t * osh, void *sdh)
+{
+ int ret;
+ dhd_bus_t *bus;
+#ifdef GET_CUSTOM_MAC_ENABLE
+ struct ether_addr ea_addr;
+#endif /* GET_CUSTOM_MAC_ENABLE */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+
+ if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) {
+ AP6210_DEBUG("%s : no mutex held. set lock\n", __FUNCTION__);
+ }
+ else {
+ AP6210_DEBUG("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__);
+ }
+ mutex_lock(&_dhd_sdio_mutex_lock_);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
+
+ /* Init global variables at run-time, not as part of the declaration.
+ * This is required to support init/de-init of the driver. Initialization
+ * of globals as part of the declaration results in non-deterministic
+ * behavior since the value of the globals may be different on the
+ * first time that the driver is initialized vs subsequent initializations.
+ */
+ dhd_txbound = DHD_TXBOUND;
+ dhd_rxbound = DHD_RXBOUND;
+ dhd_alignctl = TRUE;
+ sd1idle = TRUE;
+ dhd_readahead = TRUE;
+ retrydata = FALSE;
+ dhd_doflow = FALSE;
+ dhd_dongle_memsize = 0;
+ dhd_txminmax = DHD_TXMINMAX;
+
+ forcealign = TRUE;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+ AP6210_DEBUG("%s: venid 0x%04x devid 0x%04x\n", __FUNCTION__, venid, devid);
+
+ /* We make assumptions about address window mappings */
+ ASSERT((uintptr)regsva == SI_ENUM_BASE);
+
+ /* BCMSDH passes venid and devid based on CIS parsing -- but low-power start
+ * means early parse could fail, so here we should get either an ID
+ * we recognize OR (-1) indicating we must request power first.
+ */
+ /* Check the Vendor ID */
+ switch (venid) {
+ case 0x0000:
+ case VENDOR_BROADCOM:
+ break;
+ default:
+ AP6210_ERR("%s: unknown vendor: 0x%04x\n",
+ __FUNCTION__, venid);
+ goto forcereturn;
+ }
+
+ /* Check the Device ID and make sure it's one that we support */
+ switch (devid) {
+ case BCM4325_D11DUAL_ID: /* 4325 802.11a/g id */
+ case BCM4325_D11G_ID: /* 4325 802.11g 2.4Ghz band id */
+ case BCM4325_D11A_ID: /* 4325 802.11a 5Ghz band id */
+ AP6210_DEBUG("%s: found 4325 Dongle\n", __FUNCTION__);
+ break;
+ case BCM4329_D11N_ID: /* 4329 802.11n dualband device */
+ case BCM4329_D11N2G_ID: /* 4329 802.11n 2.4G device */
+ case BCM4329_D11N5G_ID: /* 4329 802.11n 5G device */
+ case 0x4329:
+ AP6210_DEBUG("%s: found 4329 Dongle\n", __FUNCTION__);
+ break;
+ case BCM4315_D11DUAL_ID: /* 4315 802.11a/g id */
+ case BCM4315_D11G_ID: /* 4315 802.11g id */
+ case BCM4315_D11A_ID: /* 4315 802.11a id */
+ AP6210_DEBUG("%s: found 4315 Dongle\n", __FUNCTION__);
+ break;
+ case BCM4319_D11N_ID: /* 4319 802.11n id */
+ case BCM4319_D11N2G_ID: /* 4319 802.11n2g id */
+ case BCM4319_D11N5G_ID: /* 4319 802.11n5g id */
+ AP6210_DEBUG("%s: found 4319 Dongle\n", __FUNCTION__);
+ break;
+ case 0:
+ AP6210_DEBUG("%s: allow device id 0, will check chip internals\n",
+ __FUNCTION__);
+ break;
+
+ default:
+ AP6210_ERR("%s: skipping 0x%04x/0x%04x, not a dongle\n",
+ __FUNCTION__, venid, devid);
+ goto forcereturn;
+ }
+
+ if (osh == NULL) {
+ /* Ask the OS interface part for an OSL handle */
+ if (!(osh = dhd_osl_attach(sdh, DHD_BUS))) {
+ AP6210_ERR("%s: osl_attach failed!\n", __FUNCTION__);
+ goto forcereturn;
+ }
+ }
+
+ /* Allocate private bus interface state */
+ if (!(bus = MALLOC(osh, sizeof(dhd_bus_t)))) {
+ AP6210_ERR("%s: MALLOC of dhd_bus_t failed\n", __FUNCTION__);
+ goto fail;
+ }
+ bzero(bus, sizeof(dhd_bus_t));
+ bus->sdh = sdh;
+ bus->cl_devid = (uint16)devid;
+ bus->bus = DHD_BUS;
+ bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
+ bus->usebufpool = FALSE; /* Use bufpool if allocated, else use locally malloced rxbuf */
+
+ /* attach the common module */
+ dhd_common_init(osh);
+
+ /* attempt to attach to the dongle */
+ if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) {
+ AP6210_ERR("%s: dhdsdio_probe_attach failed\n", __FUNCTION__);
+ goto fail;
+ }
+
+ /* Attach to the dhd/OS/network interface */
+ if (!(bus->dhd = dhd_attach(osh, bus, SDPCM_RESERVE))) {
+ AP6210_ERR("%s: dhd_attach failed\n", __FUNCTION__);
+ goto fail;
+ }
+
+ /* Allocate buffers */
+ if (!(dhdsdio_probe_malloc(bus, osh, sdh))) {
+ AP6210_ERR("%s: dhdsdio_probe_malloc failed\n", __FUNCTION__);
+ goto fail;
+ }
+
+ if (!(dhdsdio_probe_init(bus, osh, sdh))) {
+ AP6210_ERR("%s: dhdsdio_probe_init failed\n", __FUNCTION__);
+ goto fail;
+ }
+
+ if (bus->intr) {
+ /* Register interrupt callback, but mask it (not operational yet). */
+ AP6210_DEBUG("%s: disable SDIO interrupts (not interested yet)\n", __FUNCTION__);
+ bcmsdh_intr_disable(sdh);
+ if ((ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus)) != 0) {
+ AP6210_ERR("%s: FAILED: bcmsdh_intr_reg returned %d\n",
+ __FUNCTION__, ret);
+ goto fail;
+ }
+ AP6210_DEBUG("%s: registered SDIO interrupt function ok\n", __FUNCTION__);
+ } else {
+ AP6210_DEBUG("%s: SDIO interrupt function is NOT registered due to polling mode\n",
+ __FUNCTION__);
+ }
+
+ AP6210_DEBUG("%s: completed!!\n", __FUNCTION__);
+
+#ifdef GET_CUSTOM_MAC_ENABLE
+ /* Read MAC address from external customer place */
+ memset(&ea_addr, 0, sizeof(ea_addr));
+ ret = dhd_custom_get_mac_address(ea_addr.octet);
+ if (!ret) {
+ memcpy(bus->dhd->mac.octet, (void *)&ea_addr, ETHER_ADDR_LEN);
+ }
+#endif /* GET_CUSTOM_MAC_ENABLE */
+
+ /* if firmware path present try to download and bring up bus */
+ if (dhd_download_fw_on_driverload) {
+ if ((ret = dhd_bus_start(bus->dhd)) != 0) {
+ AP6210_ERR("%s: dhd_bus_start failed\n", __FUNCTION__);
+ goto fail;
+ }
+ }
+ /* Ok, have the per-port tell the stack we're open for business */
+ if (dhd_net_attach(bus->dhd, 0) != 0) {
+ AP6210_ERR("%s: Net attach failed!!\n", __FUNCTION__);
+ goto fail;
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+ mutex_unlock(&_dhd_sdio_mutex_lock_);
+ AP6210_DEBUG("%s : the lock is released.\n", __FUNCTION__);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+
+ return bus;
+
+fail:
+ dhdsdio_release(bus, osh);
+
+forcereturn:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+ mutex_unlock(&_dhd_sdio_mutex_lock_);
+ AP6210_DEBUG("%s : the lock is released.\n", __FUNCTION__);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+
+ return NULL;
+}
+
+static bool
+dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva,
+ uint16 devid)
+{
+ int err = 0;
+ uint8 clkctl = 0;
+
+ bus->alp_only = TRUE;
+ bus->sih = NULL;
+
+ /* Return the window to backplane enumeration space for core access */
+ if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE)) {
+ AP6210_ERR("%s: FAILED to return to SI_ENUM_BASE\n", __FUNCTION__);
+ }
+
+#ifdef DHD_DEBUG
+ AP6210_DEBUG("F1 signature read @0x18000000=0x%4x\n",
+ bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4));
+
+#endif /* DHD_DEBUG */
+
+
+ /* Force PLL off until si_attach() programs PLL control regs */
+
+
+
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, DHD_INIT_CLKCTL1, &err);
+ if (!err)
+ clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
+
+ if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) {
+ AP6210_ERR("dhdsdio_probe: ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
+ err, DHD_INIT_CLKCTL1, clkctl);
+ goto fail;
+ }
+
+#ifdef DHD_DEBUG
+ if (DHD_INFO_ON()) {
+ uint fn, numfn;
+ uint8 *cis[SDIOD_MAX_IOFUNCS];
+ int err = 0;
+
+ numfn = bcmsdh_query_iofnum(sdh);
+ ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
+
+ /* Make sure ALP is available before trying to read CIS */
+ SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
+ !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY);
+
+ /* Now request ALP be put on the bus */
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+ DHD_INIT_CLKCTL2, &err);
+ OSL_DELAY(65);
+
+ for (fn = 0; fn <= numfn; fn++) {
+ if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) {
+ AP6210_DEBUG("dhdsdio_probe: fn %d cis malloc failed\n", fn);
+ break;
+ }
+ bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+
+ if ((err = bcmsdh_cis_read(sdh, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT))) {
+ AP6210_DEBUG("dhdsdio_probe: fn %d cis read err %d\n", fn, err);
+ MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+ break;
+ }
+ dhd_dump_cis(fn, cis[fn]);
+ }
+
+ while (fn-- > 0) {
+ ASSERT(cis[fn]);
+ MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+ }
+
+ if (err) {
+ AP6210_ERR("dhdsdio_probe: failure reading or parsing CIS\n");
+ goto fail;
+ }
+ }
+#endif /* DHD_DEBUG */
+
+ /* si_attach() will provide an SI handle and scan the backplane */
+ if (!(bus->sih = si_attach((uint)devid, osh, regsva, DHD_BUS, sdh,
+ &bus->vars, &bus->varsz))) {
+ AP6210_ERR("%s: si_attach failed!\n", __FUNCTION__);
+ goto fail;
+ }
+
+ bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev);
+
+ if (!dhdsdio_chipmatch((uint16)bus->sih->chip)) {
+ AP6210_ERR("%s: unsupported chip: 0x%04x\n",
+ __FUNCTION__, bus->sih->chip);
+ goto fail;
+ }
+
+ if (bus->sih->buscorerev >= 12)
+ dhdsdio_clk_kso_init(bus);
+ else
+ bus->kso = TRUE;
+
+ if (CST4330_CHIPMODE_SDIOD(bus->sih->chipst)) {
+ }
+
+ si_sdiod_drive_strength_init(bus->sih, osh, dhd_sdiod_drive_strength);
+
+
+ /* Get info on the ARM and SOCRAM cores... */
+ if (!DHD_NOPMU(bus)) {
+ if ((si_setcore(bus->sih, ARM7S_CORE_ID, 0)) ||
+ (si_setcore(bus->sih, ARMCM3_CORE_ID, 0)) ||
+ (si_setcore(bus->sih, ARMCR4_CORE_ID, 0))) {
+ bus->armrev = si_corerev(bus->sih);
+ } else {
+ AP6210_ERR("%s: failed to find ARM core!\n", __FUNCTION__);
+ goto fail;
+ }
+
+ if (!si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) {
+ if (!(bus->orig_ramsize = si_socram_size(bus->sih))) {
+ AP6210_ERR("%s: failed to find SOCRAM memory!\n", __FUNCTION__);
+ goto fail;
+ }
+ } else {
+ /* cr4 has a different way to find the RAM size from TCM's */
+ if (!(bus->orig_ramsize = si_tcm_size(bus->sih))) {
+ AP6210_ERR("%s: failed to find CR4-TCM memory!\n", __FUNCTION__);
+ goto fail;
+ }
+ /* also populate base address */
+ bus->dongle_ram_base = CR4_RAM_BASE;
+ }
+ bus->ramsize = bus->orig_ramsize;
+ if (dhd_dongle_memsize)
+ dhd_dongle_setmemsize(bus, dhd_dongle_memsize);
+
+ AP6210_DEBUG("DHD: dongle ram size is set to %d(orig %d)\n",
+ bus->ramsize, bus->orig_ramsize);
+
+ bus->srmemsize = si_socram_srmem_size(bus->sih);
+ }
+
+ /* ...but normally deal with the SDPCMDEV core */
+ if (!(bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0)) &&
+ !(bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0))) {
+ AP6210_ERR("%s: failed to find SDIODEV core!\n", __FUNCTION__);
+ goto fail;
+ }
+ bus->sdpcmrev = si_corerev(bus->sih);
+
+ /* Set core control so an SDIO reset does a backplane reset */
+ OR_REG(osh, &bus->regs->corecontrol, CC_BPRESEN);
+ bus->rxint_mode = SDIO_DEVICE_HMB_RXINT;
+
+ if ((bus->sih->buscoretype == SDIOD_CORE_ID) && (bus->sdpcmrev >= 4) &&
+ (bus->rxint_mode == SDIO_DEVICE_RXDATAINT_MODE_1))
+ {
+ uint32 val;
+
+ val = R_REG(osh, &bus->regs->corecontrol);
+ val &= ~CC_XMTDATAAVAIL_MODE;
+ val |= CC_XMTDATAAVAIL_CTRL;
+ W_REG(osh, &bus->regs->corecontrol, val);
+ }
+
+
+ pktq_init(&bus->txq, (PRIOMASK + 1), QLEN);
+
+ /* Locate an appropriately-aligned portion of hdrbuf */
+ bus->rxhdr = (uint8 *)ROUNDUP((uintptr)&bus->hdrbuf[0], DHD_SDALIGN);
+
+ /* Set the poll and/or interrupt flags */
+ bus->intr = (bool)dhd_intr;
+ if ((bus->poll = (bool)dhd_poll))
+ bus->pollrate = 1;
+
+#ifdef BCMSDIOH_TXGLOM
+ /* Setting default Glom mode */
+ bus->glom_mode = SDPCM_TXGLOM_CPY;
+ /* Setting default Glom size */
+ bus->glomsize = SDPCM_DEFGLOM_SIZE;
+#endif
+
+ return TRUE;
+
+fail:
+ if (bus->sih != NULL) {
+ si_detach(bus->sih);
+ bus->sih = NULL;
+ }
+ return FALSE;
+}
+
+static bool
+dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh)
+{
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (bus->dhd->maxctl) {
+ bus->rxblen = ROUNDUP((bus->dhd->maxctl + SDPCM_HDRLEN), ALIGNMENT) + DHD_SDALIGN;
+ if (!(bus->rxbuf = DHD_OS_PREALLOC(osh, DHD_PREALLOC_RXBUF, bus->rxblen))) {
+ AP6210_ERR("%s: MALLOC of %d-byte rxbuf failed\n",
+ __FUNCTION__, bus->rxblen);
+ goto fail;
+ }
+ }
+ /* Allocate buffer to receive glomed packet */
+ if (!(bus->databuf = DHD_OS_PREALLOC(osh, DHD_PREALLOC_DATABUF, MAX_DATA_BUF))) {
+ AP6210_ERR("%s: MALLOC of %d-byte databuf failed\n",
+ __FUNCTION__, MAX_DATA_BUF);
+ /* release rxbuf which was already located as above */
+ if (!bus->rxblen)
+ DHD_OS_PREFREE(osh, bus->rxbuf, bus->rxblen);
+ goto fail;
+ }
+
+ /* Align the buffer */
+ if ((uintptr)bus->databuf % DHD_SDALIGN)
+ bus->dataptr = bus->databuf + (DHD_SDALIGN - ((uintptr)bus->databuf % DHD_SDALIGN));
+ else
+ bus->dataptr = bus->databuf;
+
+ return TRUE;
+
+fail:
+ return FALSE;
+}
+
+static bool
+dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh)
+{
+ int32 fnum;
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+#ifdef SDTEST
+ dhdsdio_pktgen_init(bus);
+#endif /* SDTEST */
+
+ /* Disable F2 to clear any intermediate frame state on the dongle */
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, NULL);
+
+ bus->dhd->busstate = DHD_BUS_DOWN;
+ bus->sleeping = FALSE;
+ bus->rxflow = FALSE;
+ bus->prev_rxlim_hit = 0;
+
+ /* Done with backplane-dependent accesses, can drop clock... */
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
+
+ /* ...and initialize clock/power states */
+ bus->clkstate = CLK_SDONLY;
+ bus->idletime = (int32)dhd_idletime;
+ bus->idleclock = DHD_IDLE_ACTIVE;
+
+ /* Query the SD clock speed */
+ if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0,
+ &bus->sd_divisor, sizeof(int32), FALSE) != BCME_OK) {
+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, "sd_divisor");
+ bus->sd_divisor = -1;
+ } else {
+ AP6210_DEBUG("%s: Initial value for %s is %d\n",
+ __FUNCTION__, "sd_divisor", bus->sd_divisor);
+ }
+
+ /* Query the SD bus mode */
+ if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0,
+ &bus->sd_mode, sizeof(int32), FALSE) != BCME_OK) {
+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, "sd_mode");
+ bus->sd_mode = -1;
+ } else {
+ AP6210_DEBUG("%s: Initial value for %s is %d\n",
+ __FUNCTION__, "sd_mode", bus->sd_mode);
+ }
+
+ /* Query the F2 block size, set roundup accordingly */
+ fnum = 2;
+ if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(int32),
+ &bus->blocksize, sizeof(int32), FALSE) != BCME_OK) {
+ bus->blocksize = 0;
+ AP6210_ERR("%s: fail on %s get\n", __FUNCTION__, "sd_blocksize");
+ } else {
+ AP6210_DEBUG("%s: Initial value for %s is %d\n",
+ __FUNCTION__, "sd_blocksize", bus->blocksize);
+ }
+ bus->roundup = MIN(max_roundup, bus->blocksize);
+
+ /* Query if bus module supports packet chaining, default to use if supported */
+ if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0,
+ &bus->sd_rxchain, sizeof(int32), FALSE) != BCME_OK) {
+ bus->sd_rxchain = FALSE;
+ } else {
+ AP6210_DEBUG("%s: bus module (through bcmsdh API) %s chaining\n",
+ __FUNCTION__, (bus->sd_rxchain ? "supports" : "does not support"));
+ }
+ bus->use_rxchain = (bool)bus->sd_rxchain;
+
+ return TRUE;
+}
+
+void
+dhd_bus_select_firmware_name_by_chip(struct dhd_bus *bus, char *dst, char *src)
+{
+ int fw_type, ag_type;
+ static uint chip, chiprev, first=1;
+ int i;
+
+ if (first) {
+ chip = bus->sih->chip;
+ chiprev = bus->sih->chiprev;
+ first = 0;
+ }
+ if (src[0] == '\0') {
+#ifdef CONFIG_AP6210_FW_PATH
+ bcm_strncpy_s(src, sizeof(fw_path), CONFIG_AP6210_FW_PATH, MOD_PARAM_PATHLEN-1);
+ if (src[0] == '\0')
+#endif
+ {
+ AP6210_DEBUG("src firmware path is null\n");
+ return;
+ }
+ }
+
+ strcpy(dst, src);
+#ifndef FW_PATH_AUTO_SELECT
+ return;
+#endif
+
+ /* find out the last '/' */
+ i = strlen(dst);
+ while (i>0){
+ if (dst[i] == '/') break;
+ i--;
+ }
+#ifdef BAND_AG
+ ag_type = FW_TYPE_AG;
+#else
+ ag_type = strstr(&dst[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G;
+#endif
+ fw_type = (strstr(&dst[i], "_mfg") ?
+ FW_TYPE_MFG : (strstr(&dst[i], "_apsta") ?
+ FW_TYPE_APSTA : (strstr(&dst[i], "_p2p") ?
+ FW_TYPE_P2P : FW_TYPE_STA)));
+
+
+ switch (chip) {
+ case BCM4330_CHIP_ID:
+ if (ag_type == FW_TYPE_G) {
+ if (chiprev == BCM4330B2_CHIP_REV)
+ strcpy(&dst[i+1], bcm40183b2_fw_name[fw_type]);
+ break;
+ } else {
+ if (chiprev == BCM4330B2_CHIP_REV)
+ strcpy(&dst[i+1], bcm40183b2ag_fw_name[fw_type]);
+ break;
+ }
+ case BCM43362_CHIP_ID:
+ if (chiprev == BCM43362A0_CHIP_REV)
+ strcpy(&dst[i+1], bcm40181a0_fw_name[fw_type]);
+ else
+ strcpy(&dst[i+1], bcm40181a2_fw_name[fw_type]);
+ break;
+ case BCM43341_CHIP_ID:
+ if (chiprev == BCM43341B0_CHIP_REV)
+ strcpy(&dst[i+1], bcm43341b0ag_fw_name[fw_type]);
+ break;
+ case BCM4324_CHIP_ID:
+ if (chiprev == BCM43241B4_CHIP_REV)
+ strcpy(&dst[i+1], bcm43241b4ag_fw_name[fw_type]);
+ break;
+ }
+
+ AP6210_DEBUG("%s: firmware_path=%s\n", __FUNCTION__, dst);
+}
+
+bool
+dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
+ char *pfw_path, char *pnv_path)
+{
+ bool ret;
+ bus->fw_path = pfw_path;
+ bus->nv_path = pnv_path;
+
+ ret = dhdsdio_download_firmware(bus, osh, bus->sdh);
+
+
+ return ret;
+}
+
+static bool
+dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh)
+{
+ bool ret;
+
+ DHD_OS_WAKE_LOCK(bus->dhd);
+
+ /* Download the firmware */
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+
+ AP6210_ERR("Final fw_path=%s\n", bus->fw_path);
+ AP6210_ERR("Final nv_path=%s\n", bus->nv_path);
+ ret = _dhdsdio_download_firmware(bus) == 0;
+
+ dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
+
+ DHD_OS_WAKE_UNLOCK(bus->dhd);
+ return ret;
+}
+
+/* Detach and free everything */
+static void
+dhdsdio_release(dhd_bus_t *bus, osl_t *osh)
+{
+ bool dongle_isolation = FALSE;
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (bus) {
+ ASSERT(osh);
+
+ if (bus->dhd) {
+ dongle_isolation = bus->dhd->dongle_isolation;
+ dhd_detach(bus->dhd);
+ }
+
+ /* De-register interrupt handler */
+ bcmsdh_intr_disable(bus->sdh);
+ bcmsdh_intr_dereg(bus->sdh);
+
+ if (bus->dhd) {
+ dhdsdio_release_dongle(bus, osh, dongle_isolation, TRUE);
+ dhd_free(bus->dhd);
+ bus->dhd = NULL;
+ }
+
+ dhdsdio_release_malloc(bus, osh);
+
+#ifdef DHD_DEBUG
+ if (bus->console.buf != NULL)
+ MFREE(osh, bus->console.buf, bus->console.bufsize);
+#endif
+
+ MFREE(osh, bus, sizeof(dhd_bus_t));
+ }
+
+ if (osh)
+ dhd_osl_detach(osh);
+
+ AP6210_DEBUG("%s: Disconnected\n", __FUNCTION__);
+}
+
+static void
+dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh)
+{
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (bus->dhd && bus->dhd->dongle_reset)
+ return;
+
+ if (bus->rxbuf) {
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+ MFREE(osh, bus->rxbuf, bus->rxblen);
+#endif
+ bus->rxctl = bus->rxbuf = NULL;
+ bus->rxlen = 0;
+ }
+
+ if (bus->databuf) {
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+ MFREE(osh, bus->databuf, MAX_DATA_BUF);
+#endif
+ bus->databuf = NULL;
+ }
+
+ if (bus->vars && bus->varsz) {
+ MFREE(osh, bus->vars, bus->varsz);
+ bus->vars = NULL;
+ }
+
+}
+
+
+static void
+dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation, bool reset_flag)
+{
+ AP6210_DEBUG("%s: Enter bus->dhd %p bus->dhd->dongle_reset %d \n", __FUNCTION__,
+ bus->dhd, bus->dhd->dongle_reset);
+
+ if ((bus->dhd && bus->dhd->dongle_reset) && reset_flag)
+ return;
+
+ if (bus->sih) {
+#if !defined(BCMLXSDMMC)
+ if (bus->dhd) {
+ dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+ }
+ if (KSO_ENAB(bus) && (dongle_isolation == FALSE))
+ si_watchdog(bus->sih, 4);
+#endif /* !defined(BCMLXSDMMC) */
+ if (bus->dhd) {
+ dhdsdio_clkctl(bus, CLK_NONE, FALSE);
+ }
+ si_detach(bus->sih);
+ bus->sih = NULL;
+ if (bus->vars && bus->varsz)
+ MFREE(osh, bus->vars, bus->varsz);
+ bus->vars = NULL;
+ }
+
+ AP6210_DEBUG("%s: Disconnected\n", __FUNCTION__);
+}
+
+static void
+dhdsdio_disconnect(void *ptr)
+{
+ dhd_bus_t *bus = (dhd_bus_t *)ptr;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+
+ if (mutex_is_locked(&_dhd_sdio_mutex_lock_) == 0) {
+ AP6210_DEBUG("%s : no mutex held. set lock\n", __FUNCTION__);
+ }
+ else {
+ AP6210_DEBUG("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__);
+ }
+ mutex_lock(&_dhd_sdio_mutex_lock_);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
+
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ if (bus) {
+ ASSERT(bus->dhd);
+ dhdsdio_release(bus, bus->dhd->osh);
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+ mutex_unlock(&_dhd_sdio_mutex_lock_);
+ AP6210_ERR("%s : the lock is released.\n", __FUNCTION__);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
+
+ AP6210_DEBUG("%s: Disconnected\n", __FUNCTION__);
+}
+
+
+/* Register/Unregister functions are called by the main DHD entry
+ * point (e.g. module insertion) to link with the bus driver, in
+ * order to look for or await the device.
+ */
+
+static bcmsdh_driver_t dhd_sdio = {
+ dhdsdio_probe,
+ dhdsdio_disconnect
+};
+
+int
+dhd_bus_register(void)
+{
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ return bcmsdh_register(&dhd_sdio);
+}
+
+void
+dhd_bus_unregister(void)
+{
+ AP6210_DEBUG("%s: Enter\n", __FUNCTION__);
+
+ bcmsdh_unregister();
+}
+
+#if defined(BCMLXSDMMC)
+/* Register a dummy SDIO client driver in order to be notified of new SDIO device */
+int dhd_bus_reg_sdio_notify(void* semaphore)
+{
+ return bcmsdh_reg_sdio_notify(semaphore);
+}
+
+void dhd_bus_unreg_sdio_notify(void)
+{
+ bcmsdh_unreg_sdio_notify();
+}
+#endif /* defined(BCMLXSDMMC) */
+
+#ifdef BCMEMBEDIMAGE
+static int
+dhdsdio_download_code_array(struct dhd_bus *bus)
+{
+ int bcmerror = -1;
+ int offset = 0;
+ unsigned char *ularray = NULL;
+
+ AP6210_ERR("%s: download embedded firmware...\n", __FUNCTION__);
+
+ /* Download image */
+ while ((offset + MEMBLOCK) < sizeof(dlarray)) {
+ bcmerror = dhdsdio_membytes(bus, TRUE, offset,
+ (uint8 *) (dlarray + offset), MEMBLOCK);
+ if (bcmerror) {
+ AP6210_ERR("%s: error %d on writing %d membytes at 0x%08x\n",
+ __FUNCTION__, bcmerror, MEMBLOCK, offset);
+ goto err;
+ }
+
+ offset += MEMBLOCK;
+ }
+
+ if (offset < sizeof(dlarray)) {
+ bcmerror = dhdsdio_membytes(bus, TRUE, offset,
+ (uint8 *) (dlarray + offset), sizeof(dlarray) - offset);
+ if (bcmerror) {
+ AP6210_ERR("%s: error %d on writing %d membytes at 0x%08x\n",
+ __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset);
+ goto err;
+ }
+ }
+
+#ifdef DHD_DEBUG
+ /* Upload and compare the downloaded code */
+ {
+ ularray = MALLOC(bus->dhd->osh, bus->ramsize);
+ /* Upload image to verify downloaded contents. */
+ offset = 0;
+ memset(ularray, 0xaa, bus->ramsize);
+ while ((offset + MEMBLOCK) < sizeof(dlarray)) {
+ bcmerror = dhdsdio_membytes(bus, FALSE, offset, ularray + offset, MEMBLOCK);
+ if (bcmerror) {
+ AP6210_ERR("%s: error %d on reading %d membytes at 0x%08x\n",
+ __FUNCTION__, bcmerror, MEMBLOCK, offset);
+ goto err;
+ }
+
+ offset += MEMBLOCK;
+ }
+
+ if (offset < sizeof(dlarray)) {
+ bcmerror = dhdsdio_membytes(bus, FALSE, offset,
+ ularray + offset, sizeof(dlarray) - offset);
+ if (bcmerror) {
+ AP6210_ERR("%s: error %d on reading %d membytes at 0x%08x\n",
+ __FUNCTION__, bcmerror, sizeof(dlarray) - offset, offset);
+ goto err;
+ }
+ }
+
+ if (memcmp(dlarray, ularray, sizeof(dlarray))) {
+ AP6210_ERR("%s: Downloaded image is corrupted (%s, %s, %s).\n",
+ __FUNCTION__, dlimagename, dlimagever, dlimagedate);
+ goto err;
+ } else
+ AP6210_ERR("%s: Download, Upload and compare succeeded (%s, %s, %s).\n",
+ __FUNCTION__, dlimagename, dlimagever, dlimagedate);
+
+ }
+#endif /* DHD_DEBUG */
+
+err:
+ if (ularray)
+ MFREE(bus->dhd->osh, ularray, bus->ramsize);
+ return bcmerror;
+}
+#endif /* BCMEMBEDIMAGE */
+
+static int
+dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path)
+{
+ int bcmerror = -1;
+ int offset = 0;
+ int len;
+ void *image = NULL;
+ uint8 *memblock = NULL, *memptr;
+ uint8 *memptr_tmp = NULL; // terence: check downloaded firmware is correct
+
+ AP6210_ERR("download firmware %s\n", pfw_path);
+
+ image = dhd_os_open_image(pfw_path);
+ if (image == NULL)
+ goto err;
+
+ memptr = memblock = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN);
+ if (memblock == NULL) {
+ AP6210_ERR("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK);
+ goto err;
+ }
+ if (dhd_msg_level & DHD_TRACE_VAL) {
+ memptr_tmp = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN);
+ if (memptr_tmp == NULL) {
+ AP6210_ERR("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK);
+ goto err;
+ }
+ }
+ if ((uint32)(uintptr)memblock % DHD_SDALIGN)
+ memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN));
+
+ /* Download image */
+ while ((len = dhd_os_get_image_block((char*)memptr, MEMBLOCK, image))) {
+ if (len < 0) {
+ AP6210_ERR("%s: dhd_os_get_image_block failed (%d)\n", __FUNCTION__, len);
+ bcmerror = BCME_ERROR;
+ goto err;
+ }
+ bcmerror = dhdsdio_membytes(bus, TRUE, offset, memptr, len);
+ if (bcmerror) {
+ AP6210_ERR("%s: error %d on writing %d membytes at 0x%08x\n",
+ __FUNCTION__, bcmerror, MEMBLOCK, offset);
+ goto err;
+ }
+
+ if (dhd_msg_level & DHD_TRACE_VAL) {
+ bcmerror = dhdsdio_membytes(bus, FALSE, offset, memptr_tmp, len);
+ if (bcmerror) {
+ AP6210_ERR("%s: error %d on reading %d membytes at 0x%08x\n",
+ __FUNCTION__, bcmerror, MEMBLOCK, offset);
+ goto err;
+ }
+ if (memcmp(memptr_tmp, memptr, len)) {
+ AP6210_ERR("%s: Downloaded image is corrupted.\n", __FUNCTION__);
+ goto err;
+ } else
+ AP6210_ERR("%s: Download, Upload and compare succeeded.\n", __FUNCTION__);
+ }
+ offset += MEMBLOCK;
+ }
+
+err:
+ if (memblock)
+ MFREE(bus->dhd->osh, memblock, MEMBLOCK + DHD_SDALIGN);
+ if (dhd_msg_level & DHD_TRACE_VAL) {
+ if (memptr_tmp)
+ MFREE(bus->dhd->osh, memptr_tmp, MEMBLOCK + DHD_SDALIGN);
+ }
+
+ if (image)
+ dhd_os_close_image(image);
+
+ return bcmerror;
+}
+
+/*
+ EXAMPLE: nvram_array
+ nvram_arry format:
+ name=value
+ Use carriage return at the end of each assignment, and an empty string with
+ carriage return at the end of array.
+
+ For example:
+ unsigned char nvram_array[] = {"name1=value1\n", "name2=value2\n", "\n"};
+ Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx.
+
+ Search "EXAMPLE: nvram_array" to see how the array is activated.
+*/
+
+void
+dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params)
+{
+ bus->nvram_params = nvram_params;
+}
+
+static int
+dhdsdio_download_nvram(struct dhd_bus *bus)
+{
+ int bcmerror = -1;
+ uint len;
+ void * image = NULL;
+ char * memblock = NULL;
+ char *bufp;
+ char *pnv_path;
+ bool nvram_file_exists;
+
+ pnv_path = bus->nv_path;
+
+ nvram_file_exists = ((pnv_path != NULL) && (pnv_path[0] != '\0'));
+ if (!nvram_file_exists && (bus->nvram_params == NULL))
+ return (0);
+
+ if (nvram_file_exists) {
+ image = dhd_os_open_image(pnv_path);
+ if (image == NULL)
+ goto err;
+ }
+
+ memblock = MALLOC(bus->dhd->osh, MAX_NVRAMBUF_SIZE);
+ if (memblock == NULL) {
+ AP6210_ERR("%s: Failed to allocate memory %d bytes\n",
+ __FUNCTION__, MAX_NVRAMBUF_SIZE);
+ goto err;
+ }
+
+ /* Download variables */
+ if (nvram_file_exists) {
+ len = dhd_os_get_image_block(memblock, MAX_NVRAMBUF_SIZE, image);
+ }
+ else {
+ len = strlen(bus->nvram_params);
+ ASSERT(len <= MAX_NVRAMBUF_SIZE);
+ memcpy(memblock, bus->nvram_params, len);
+ }
+ if (len > 0 && len < MAX_NVRAMBUF_SIZE) {
+ bufp = (char *)memblock;
+ bufp[len] = 0;
+ len = process_nvram_vars(bufp, len);
+ if (len % 4) {
+ len += 4 - (len % 4);
+ }
+ bufp += len;
+ *bufp++ = 0;
+ if (len)
+ bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1);
+ if (bcmerror) {
+ AP6210_ERR("%s: error downloading vars: %d\n",
+ __FUNCTION__, bcmerror);
+ }
+ }
+ else {
+ AP6210_ERR("%s: error reading nvram file: %d\n",
+ __FUNCTION__, len);
+ bcmerror = BCME_SDIO_ERROR;
+ }
+
+err:
+ if (memblock)
+ MFREE(bus->dhd->osh, memblock, MAX_NVRAMBUF_SIZE);
+
+ if (image)
+ dhd_os_close_image(image);
+
+ return bcmerror;
+}
+
+static int
+_dhdsdio_download_firmware(struct dhd_bus *bus)
+{
+ int bcmerror = -1;
+
+ bool embed = FALSE; /* download embedded firmware */
+ bool dlok = FALSE; /* download firmware succeeded */
+
+ /* Out immediately if no image to download */
+ if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) {
+#ifdef BCMEMBEDIMAGE
+ embed = TRUE;
+#else
+ return 0;
+#endif
+ }
+
+ /* Keep arm in reset */
+ if (dhdsdio_download_state(bus, TRUE)) {
+ AP6210_ERR("%s: error placing ARM core in reset\n", __FUNCTION__);
+ goto err;
+ }
+
+ /* External image takes precedence if specified */
+ if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) {
+ if (dhdsdio_download_code_file(bus, bus->fw_path)) {
+ AP6210_ERR("%s: dongle image file download failed\n", __FUNCTION__);
+#ifdef BCMEMBEDIMAGE
+ embed = TRUE;
+#else
+ goto err;
+#endif
+ }
+ else {
+ embed = FALSE;
+ dlok = TRUE;
+ }
+ }
+#ifdef BCMEMBEDIMAGE
+ if (embed) {
+ if (dhdsdio_download_code_array(bus)) {
+ AP6210_ERR("%s: dongle image array download failed\n", __FUNCTION__);
+ goto err;
+ }
+ else {
+ dlok = TRUE;
+ }
+ }
+#else
+ BCM_REFERENCE(embed);
+#endif
+ if (!dlok) {
+ AP6210_ERR("%s: dongle image download failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ /* EXAMPLE: nvram_array */
+ /* If a valid nvram_arry is specified as above, it can be passed down to dongle */
+ /* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */
+
+ /* External nvram takes precedence if specified */
+ if (dhdsdio_download_nvram(bus)) {
+ AP6210_ERR("%s: dongle nvram file download failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ /* Take arm out of reset */
+ if (dhdsdio_download_state(bus, FALSE)) {
+ AP6210_ERR("%s: error getting out of ARM core reset\n", __FUNCTION__);
+ goto err;
+ }
+
+ bcmerror = 0;
+
+err:
+ return bcmerror;
+}
+
+static int
+dhd_bcmsdh_recv_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes,
+ void *pkt, bcmsdh_cmplt_fn_t complete, void *handle)
+{
+ int status;
+
+ if (!KSO_ENAB(bus)) {
+ AP6210_ERR("%s: Device asleep\n", __FUNCTION__);
+ return BCME_NODEVICE;
+ }
+
+ status = bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle);
+
+ return status;
+}
+
+static int
+dhd_bcmsdh_send_buf(dhd_bus_t *bus, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes,
+ void *pkt, bcmsdh_cmplt_fn_t complete, void *handle)
+{
+ if (!KSO_ENAB(bus)) {
+ AP6210_ERR("%s: Device asleep\n", __FUNCTION__);
+ return BCME_NODEVICE;
+ }
+
+ return (bcmsdh_send_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, handle));
+}
+
+#ifdef BCMSDIOH_TXGLOM
+static void
+dhd_bcmsdh_glom_post(dhd_bus_t *bus, uint8 *frame, uint len)
+{
+ bcmsdh_glom_post(bus->sdh, frame, len);
+}
+
+static void
+dhd_bcmsdh_glom_clear(dhd_bus_t *bus)
+{
+ bcmsdh_glom_clear(bus->sdh);
+}
+#endif
+
+uint
+dhd_bus_chip(struct dhd_bus *bus)
+{
+ ASSERT(bus->sih != NULL);
+ return bus->sih->chip;
+}
+
+void *
+dhd_bus_pub(struct dhd_bus *bus)
+{
+ return bus->dhd;
+}
+
+void *
+dhd_bus_txq(struct dhd_bus *bus)
+{
+ return &bus->txq;
+}
+
+uint
+dhd_bus_hdrlen(struct dhd_bus *bus)
+{
+ return SDPCM_HDRLEN;
+}
+
+int
+dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
+{
+ int bcmerror = 0;
+ dhd_bus_t *bus;
+
+ bus = dhdp->bus;
+
+ if (flag == TRUE) {
+ if (!bus->dhd->dongle_reset) {
+ dhd_os_sdlock(dhdp);
+ dhd_os_wd_timer(dhdp, 0);
+#if !defined(IGNORE_ETH0_DOWN)
+ /* Force flow control as protection when stop come before ifconfig_down */
+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON);
+#endif /* !defined(IGNORE_ETH0_DOWN) */
+ /* Expect app to have torn down any connection before calling */
+ /* Stop the bus, disable F2 */
+ dhd_bus_stop(bus, FALSE);
+
+#if defined(OOB_INTR_ONLY)
+ /* Clean up any pending IRQ */
+ bcmsdh_set_irq(FALSE);
+#endif
+
+ /* Clean tx/rx buffer pointers, detach from the dongle */
+ dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE, TRUE);
+
+ bus->dhd->dongle_reset = TRUE;
+ bus->dhd->up = FALSE;
+#ifdef BCMSDIOH_TXGLOM
+ dhd_txglom_enable(dhdp, FALSE);
+#endif
+ dhd_os_sdunlock(dhdp);
+
+ AP6210_ERR("%s: WLAN OFF DONE\n", __FUNCTION__);
+ /* App can now remove power from device */
+ } else
+ bcmerror = BCME_SDIO_ERROR;
+ } else {
+ /* App must have restored power to device before calling */
+
+ AP6210_ERR("%s: WLAN ON\n", __FUNCTION__);
+
+ if (bus->dhd->dongle_reset) {
+ /* Turn on WLAN */
+#ifdef DHDTHREAD
+ dhd_os_sdlock(dhdp);
+#endif /* DHDTHREAD */
+ /* Reset SD client */
+ bcmsdh_reset(bus->sdh);
+
+ /* Attempt to re-attach & download */
+ if (dhdsdio_probe_attach(bus, bus->dhd->osh, bus->sdh,
+ (uint32 *)SI_ENUM_BASE,
+ bus->cl_devid)) {
+ /* Attempt to download binary to the dongle */
+ COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path); // terence
+ if (dhdsdio_probe_init(bus, bus->dhd->osh, bus->sdh) &&
+ dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) {
+
+ /* Re-init bus, enable F2 transfer */
+ bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE);
+ if (bcmerror == BCME_OK) {
+#if defined(OOB_INTR_ONLY)
+ bcmsdh_set_irq(TRUE);
+ dhd_enable_oob_intr(bus, TRUE);
+#endif
+
+ bus->dhd->dongle_reset = FALSE;
+ bus->dhd->up = TRUE;
+
+#if !defined(IGNORE_ETH0_DOWN)
+ /* Restore flow control */
+ dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF);
+#endif
+ dhd_os_wd_timer(dhdp, dhd_watchdog_ms);
+#ifdef BCMSDIOH_TXGLOM
+ if ((dhdp->busstate == DHD_BUS_DATA) &&
+ bcmsdh_glom_enabled()) {
+ dhd_txglom_enable(dhdp, TRUE);
+ }
+#endif /* BCMSDIOH_TXGLOM */
+ AP6210_ERR("%s: WLAN ON DONE\n", __FUNCTION__);
+ } else {
+ dhd_bus_stop(bus, FALSE);
+ dhdsdio_release_dongle(bus, bus->dhd->osh,
+ TRUE, FALSE);
+ }
+ } else
+ bcmerror = BCME_SDIO_ERROR;
+ } else
+ bcmerror = BCME_SDIO_ERROR;
+
+#ifdef DHDTHREAD
+ dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
+ } else {
+ bcmerror = BCME_SDIO_ERROR;
+ AP6210_DEBUG("%s called when dongle is not in reset\n",
+ __FUNCTION__);
+ AP6210_DEBUG("Will call dhd_bus_start instead\n");
+ sdioh_start(NULL, 1);
+#if defined(HW_OOB)
+ bcmsdh_config_hw_oob_intr(bus->sdh, bus->sih->chip); // terence 20120615: fix for OOB initial issue
+#endif
+ COPY_FW_PATH_BY_CHIP(bus, fw_path, firmware_path);
+ if ((bcmerror = dhd_bus_start(dhdp)) != 0)
+ AP6210_ERR("%s: dhd_bus_start fail with %d\n",
+ __FUNCTION__, bcmerror);
+ }
+ }
+ return bcmerror;
+}
+
+/* Get Chip ID version */
+uint dhd_bus_chip_id(dhd_pub_t *dhdp)
+{
+ dhd_bus_t *bus = dhdp->bus;
+
+ return bus->sih->chip;
+}
+
+/* Get Chip Rev ID version */
+uint dhd_bus_chiprev_id(dhd_pub_t *dhdp)
+{
+ dhd_bus_t *bus = dhdp->bus;
+
+ return bus->sih->chiprev;
+}
+
+/* Get Chip Pkg ID version */
+uint dhd_bus_chippkg_id(dhd_pub_t *dhdp)
+{
+ dhd_bus_t *bus = dhdp->bus;
+
+ return bus->sih->chippkg;
+}
+
+int
+dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size)
+{
+ dhd_bus_t *bus;
+
+ bus = dhdp->bus;
+ return dhdsdio_membytes(bus, set, address, data, size);
+}
diff --git a/drivers/net/wireless/ap6210/dhd_wlfc.c b/drivers/net/wireless/ap6210/dhd_wlfc.c
new file mode 100644
index 0000000..93b4ca3
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_wlfc.c
@@ -0,0 +1,2441 @@
+/*
+ * DHD PROP_TXSTATUS Module.
+ *
+ * Copyright (C) 1999-2013, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_wlfc.c 412994 2013-07-17 12:38:03Z $
+ *
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+
+#include <bcmutils.h>
+#include <bcmendian.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+
+#include <dhd_bus.h>
+#include <dhd_dbg.h>
+
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+
+
+
+#define BUS_RETRIES 1 /* # of retries before aborting a bus tx operation */
+
+#ifdef PROP_TXSTATUS
+typedef struct dhd_wlfc_commit_info {
+ uint8 needs_hdr;
+ uint8 ac_fifo_credit_spent;
+ ewlfc_packet_state_t pkt_type;
+ wlfc_mac_descriptor_t* mac_entry;
+ void* p;
+} dhd_wlfc_commit_info_t;
+#endif /* PROP_TXSTATUS */
+
+
+#ifdef PROP_TXSTATUS
+
+#define DHD_WLFC_QMON_COMPLETE(entry)
+
+void
+dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+ int i;
+ uint8* ea;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhdp->wlfc_state;
+ wlfc_hanger_t* h;
+ wlfc_mac_descriptor_t* mac_table;
+ wlfc_mac_descriptor_t* interfaces;
+ char* iftypes[] = {"STA", "AP", "WDS", "p2pGO", "p2pCL"};
+
+ if (wlfc == NULL) {
+ bcm_bprintf(strbuf, "wlfc not initialized yet\n");
+ return;
+ }
+ h = (wlfc_hanger_t*)wlfc->hanger;
+ if (h == NULL) {
+ bcm_bprintf(strbuf, "wlfc-hanger not initialized yet\n");
+ }
+
+ mac_table = wlfc->destination_entries.nodes;
+ interfaces = wlfc->destination_entries.interfaces;
+ bcm_bprintf(strbuf, "---- wlfc stats ----\n");
+ if (h) {
+ bcm_bprintf(strbuf, "wlfc hanger (pushed,popped,f_push,"
+ "f_pop,f_slot, pending) = (%d,%d,%d,%d,%d,%d)\n",
+ h->pushed,
+ h->popped,
+ h->failed_to_push,
+ h->failed_to_pop,
+ h->failed_slotfind,
+ (h->pushed - h->popped));
+ }
+
+ bcm_bprintf(strbuf, "wlfc fail(tlv,credit_rqst,mac_update,psmode_update), "
+ "(dq_full,rollback_fail) = (%d,%d,%d,%d), (%d,%d)\n",
+ wlfc->stats.tlv_parse_failed,
+ wlfc->stats.credit_request_failed,
+ wlfc->stats.mac_update_failed,
+ wlfc->stats.psmode_update_failed,
+ wlfc->stats.delayq_full_error,
+ wlfc->stats.rollback_failed);
+
+ bcm_bprintf(strbuf, "PKTS (credit,sent) "
+ "(AC0[%d,%d],AC1[%d,%d],AC2[%d,%d],AC3[%d,%d],BC_MC[%d,%d])\n",
+ wlfc->FIFO_credit[0], wlfc->stats.send_pkts[0],
+ wlfc->FIFO_credit[1], wlfc->stats.send_pkts[1],
+ wlfc->FIFO_credit[2], wlfc->stats.send_pkts[2],
+ wlfc->FIFO_credit[3], wlfc->stats.send_pkts[3],
+ wlfc->FIFO_credit[4], wlfc->stats.send_pkts[4]);
+
+ bcm_bprintf(strbuf, "\n");
+ for (i = 0; i < WLFC_MAX_IFNUM; i++) {
+ if (interfaces[i].occupied) {
+ char* iftype_desc;
+
+ if (interfaces[i].iftype > WLC_E_IF_ROLE_P2P_CLIENT)
+ iftype_desc = "<Unknown";
+ else
+ iftype_desc = iftypes[interfaces[i].iftype];
+
+ ea = interfaces[i].ea;
+ bcm_bprintf(strbuf, "INTERFACE[%d].ea = "
+ "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d, type: %s"
+ "netif_flow_control:%s\n", i,
+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
+ interfaces[i].interface_id,
+ iftype_desc, ((wlfc->hostif_flow_state[i] == OFF)
+ ? " OFF":" ON"));
+
+ bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ(len,state,credit)"
+ "= (%d,%s,%d)\n",
+ i,
+ interfaces[i].psq.len,
+ ((interfaces[i].state ==
+ WLFC_STATE_OPEN) ? " OPEN":"CLOSE"),
+ interfaces[i].requested_credit);
+
+ bcm_bprintf(strbuf, "INTERFACE[%d].DELAYQ"
+ "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = "
+ "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n",
+ i,
+ interfaces[i].psq.q[0].len,
+ interfaces[i].psq.q[1].len,
+ interfaces[i].psq.q[2].len,
+ interfaces[i].psq.q[3].len,
+ interfaces[i].psq.q[4].len,
+ interfaces[i].psq.q[5].len,
+ interfaces[i].psq.q[6].len,
+ interfaces[i].psq.q[7].len);
+ }
+ }
+
+ bcm_bprintf(strbuf, "\n");
+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
+ if (mac_table[i].occupied) {
+ ea = mac_table[i].ea;
+ bcm_bprintf(strbuf, "MAC_table[%d].ea = "
+ "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i,
+ ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
+ mac_table[i].interface_id);
+
+ bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ(len,state,credit)"
+ "= (%d,%s,%d)\n",
+ i,
+ mac_table[i].psq.len,
+ ((mac_table[i].state ==
+ WLFC_STATE_OPEN) ? " OPEN":"CLOSE"),
+ mac_table[i].requested_credit);
+#ifdef PROP_TXSTATUS_DEBUG
+ bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n",
+ i, mac_table[i].opened_ct, mac_table[i].closed_ct);
+#endif
+ bcm_bprintf(strbuf, "MAC_table[%d].DELAYQ"
+ "(sup,ac0),(sup,ac1),(sup,ac2),(sup,ac3) = "
+ "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n",
+ i,
+ mac_table[i].psq.q[0].len,
+ mac_table[i].psq.q[1].len,
+ mac_table[i].psq.q[2].len,
+ mac_table[i].psq.q[3].len,
+ mac_table[i].psq.q[4].len,
+ mac_table[i].psq.q[5].len,
+ mac_table[i].psq.q[6].len,
+ mac_table[i].psq.q[7].len);
+ }
+ }
+
+#ifdef PROP_TXSTATUS_DEBUG
+ {
+ int avg;
+ int moving_avg = 0;
+ int moving_samples;
+
+ if (wlfc->stats.latency_sample_count) {
+ moving_samples = sizeof(wlfc->stats.deltas)/sizeof(uint32);
+
+ for (i = 0; i < moving_samples; i++)
+ moving_avg += wlfc->stats.deltas[i];
+ moving_avg /= moving_samples;
+
+ avg = (100 * wlfc->stats.total_status_latency) /
+ wlfc->stats.latency_sample_count;
+ bcm_bprintf(strbuf, "txstatus latency (average, last, moving[%d]) = "
+ "(%d.%d, %03d, %03d)\n",
+ moving_samples, avg/100, (avg - (avg/100)*100),
+ wlfc->stats.latency_most_recent,
+ moving_avg);
+ }
+ }
+
+ bcm_bprintf(strbuf, "wlfc- fifo[0-5] credit stats: sent = (%d,%d,%d,%d,%d,%d), "
+ "back = (%d,%d,%d,%d,%d,%d)\n",
+ wlfc->stats.fifo_credits_sent[0],
+ wlfc->stats.fifo_credits_sent[1],
+ wlfc->stats.fifo_credits_sent[2],
+ wlfc->stats.fifo_credits_sent[3],
+ wlfc->stats.fifo_credits_sent[4],
+ wlfc->stats.fifo_credits_sent[5],
+
+ wlfc->stats.fifo_credits_back[0],
+ wlfc->stats.fifo_credits_back[1],
+ wlfc->stats.fifo_credits_back[2],
+ wlfc->stats.fifo_credits_back[3],
+ wlfc->stats.fifo_credits_back[4],
+ wlfc->stats.fifo_credits_back[5]);
+ {
+ uint32 fifo_cr_sent = 0;
+ uint32 fifo_cr_acked = 0;
+ uint32 request_cr_sent = 0;
+ uint32 request_cr_ack = 0;
+ uint32 bc_mc_cr_ack = 0;
+
+ for (i = 0; i < sizeof(wlfc->stats.fifo_credits_sent)/sizeof(uint32); i++) {
+ fifo_cr_sent += wlfc->stats.fifo_credits_sent[i];
+ }
+
+ for (i = 0; i < sizeof(wlfc->stats.fifo_credits_back)/sizeof(uint32); i++) {
+ fifo_cr_acked += wlfc->stats.fifo_credits_back[i];
+ }
+
+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
+ if (wlfc->destination_entries.nodes[i].occupied) {
+ request_cr_sent +=
+ wlfc->destination_entries.nodes[i].dstncredit_sent_packets;
+ }
+ }
+ for (i = 0; i < WLFC_MAX_IFNUM; i++) {
+ if (wlfc->destination_entries.interfaces[i].occupied) {
+ request_cr_sent +=
+ wlfc->destination_entries.interfaces[i].dstncredit_sent_packets;
+ }
+ }
+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
+ if (wlfc->destination_entries.nodes[i].occupied) {
+ request_cr_ack +=
+ wlfc->destination_entries.nodes[i].dstncredit_acks;
+ }
+ }
+ for (i = 0; i < WLFC_MAX_IFNUM; i++) {
+ if (wlfc->destination_entries.interfaces[i].occupied) {
+ request_cr_ack +=
+ wlfc->destination_entries.interfaces[i].dstncredit_acks;
+ }
+ }
+ bcm_bprintf(strbuf, "wlfc- (sent, status) => pq(%d,%d), vq(%d,%d),"
+ "other:%d, bc_mc:%d, signal-only, (sent,freed): (%d,%d)",
+ fifo_cr_sent, fifo_cr_acked,
+ request_cr_sent, request_cr_ack,
+ wlfc->destination_entries.other.dstncredit_acks,
+ bc_mc_cr_ack,
+ wlfc->stats.signal_only_pkts_sent, wlfc->stats.signal_only_pkts_freed);
+ }
+#endif /* PROP_TXSTATUS_DEBUG */
+ bcm_bprintf(strbuf, "\n");
+ bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull),(dropped,hdr_only,wlc_tossed)"
+ "(freed,free_err,rollback)) = "
+ "((%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n",
+ wlfc->stats.pktin,
+ wlfc->stats.pkt2bus,
+ wlfc->stats.txstatus_in,
+ wlfc->stats.dhd_hdrpulls,
+
+ wlfc->stats.pktdropped,
+ wlfc->stats.wlfc_header_only_pkt,
+ wlfc->stats.wlc_tossed_pkts,
+
+ wlfc->stats.pkt_freed,
+ wlfc->stats.pkt_free_err, wlfc->stats.rollback);
+
+ bcm_bprintf(strbuf, "wlfc- suppress((d11,wlc,err),enq(d11,wl,hq,mac?),retx(d11,wlc,hq)) = "
+ "((%d,%d,%d),(%d,%d,%d,%d),(%d,%d,%d))\n",
+
+ wlfc->stats.d11_suppress,
+ wlfc->stats.wl_suppress,
+ wlfc->stats.bad_suppress,
+
+ wlfc->stats.psq_d11sup_enq,
+ wlfc->stats.psq_wlsup_enq,
+ wlfc->stats.psq_hostq_enq,
+ wlfc->stats.mac_handle_notfound,
+
+ wlfc->stats.psq_d11sup_retx,
+ wlfc->stats.psq_wlsup_retx,
+ wlfc->stats.psq_hostq_retx);
+ bcm_bprintf(strbuf, "wlfc- generic error: %d", wlfc->stats.generic_error);
+
+ return;
+}
+
+/* Create a place to store all packet pointers submitted to the firmware until
+ a status comes back, suppress or otherwise.
+
+ hang-er: noun, a contrivance on which things are hung, as a hook.
+*/
+static void*
+dhd_wlfc_hanger_create(osl_t *osh, int max_items)
+{
+ int i;
+ wlfc_hanger_t* hanger;
+
+ /* allow only up to a specific size for now */
+ ASSERT(max_items == WLFC_HANGER_MAXITEMS);
+
+ if ((hanger = (wlfc_hanger_t*)MALLOC(osh, WLFC_HANGER_SIZE(max_items))) == NULL)
+ return NULL;
+
+ memset(hanger, 0, WLFC_HANGER_SIZE(max_items));
+ hanger->max_items = max_items;
+
+ for (i = 0; i < hanger->max_items; i++) {
+ hanger->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ }
+ return hanger;
+}
+
+static int
+dhd_wlfc_hanger_delete(osl_t *osh, void* hanger)
+{
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ if (h) {
+ MFREE(osh, h, WLFC_HANGER_SIZE(h->max_items));
+ return BCME_OK;
+ }
+ return BCME_BADARG;
+}
+
+static uint16
+dhd_wlfc_hanger_get_free_slot(void* hanger)
+{
+ uint32 i;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ if (h) {
+ i = h->slot_pos + 1;
+ if (i == h->max_items) {
+ i = 0;
+ }
+ while (i != h->slot_pos) {
+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_FREE) {
+ h->slot_pos = i;
+ return (uint16)i;
+ }
+ i++;
+ if (i == h->max_items)
+ i = 0;
+ }
+ h->failed_slotfind++;
+ }
+ return WLFC_HANGER_MAXITEMS;
+}
+
+static int
+dhd_wlfc_hanger_get_genbit(void* hanger, void* pkt, uint32 slot_id, int* gen)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ *gen = 0xff;
+
+ /* this packet was not pushed at the time it went to the firmware */
+ if (slot_id == WLFC_HANGER_MAXITEMS)
+ return BCME_NOTFOUND;
+
+ if (h) {
+ if ((h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) ||
+ (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED)) {
+ *gen = h->items[slot_id].gen;
+ }
+ else {
+ rc = BCME_NOTFOUND;
+ }
+ }
+ else
+ rc = BCME_BADARG;
+ return rc;
+}
+
+static int
+dhd_wlfc_hanger_pushpkt(void* hanger, void* pkt, uint32 slot_id)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ if (h && (slot_id < WLFC_HANGER_MAXITEMS)) {
+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_FREE) {
+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE;
+ h->items[slot_id].pkt = pkt;
+ h->items[slot_id].identifier = slot_id;
+ h->pushed++;
+ }
+ else {
+ h->failed_to_push++;
+ rc = BCME_NOTFOUND;
+ }
+ }
+ else
+ rc = BCME_BADARG;
+ return rc;
+}
+
+static int
+dhd_wlfc_hanger_poppkt(void* hanger, uint32 slot_id, void** pktout, int remove_from_hanger)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ /* this packet was not pushed at the time it went to the firmware */
+ if (slot_id == WLFC_HANGER_MAXITEMS)
+ return BCME_NOTFOUND;
+
+ if (h) {
+ if (h->items[slot_id].state != WLFC_HANGER_ITEM_STATE_FREE) {
+ *pktout = h->items[slot_id].pkt;
+ if (remove_from_hanger) {
+ h->items[slot_id].state =
+ WLFC_HANGER_ITEM_STATE_FREE;
+ h->items[slot_id].pkt = NULL;
+ h->items[slot_id].identifier = 0;
+ h->items[slot_id].gen = 0xff;
+ h->popped++;
+ }
+ }
+ else {
+ h->failed_to_pop++;
+ rc = BCME_NOTFOUND;
+ }
+ }
+ else
+ rc = BCME_BADARG;
+ return rc;
+}
+
+static int
+dhd_wlfc_hanger_mark_suppressed(void* hanger, uint32 slot_id, uint8 gen)
+{
+ int rc = BCME_OK;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
+
+ /* this packet was not pushed at the time it went to the firmware */
+ if (slot_id == WLFC_HANGER_MAXITEMS)
+ return BCME_NOTFOUND;
+ if (h) {
+ h->items[slot_id].gen = gen;
+ if (h->items[slot_id].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ h->items[slot_id].state = WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED;
+ }
+ else
+ rc = BCME_BADARG;
+ }
+ else
+ rc = BCME_BADARG;
+
+ return rc;
+}
+
+static int
+_dhd_wlfc_pushheader(athost_wl_status_info_t* ctx, void* p, bool tim_signal,
+ uint8 tim_bmp, uint8 mac_handle, uint32 htodtag)
+{
+ uint32 wl_pktinfo = 0;
+ uint8* wlh;
+ uint8 dataOffset;
+ uint8 fillers;
+ uint8 tim_signal_len = 0;
+
+ struct bdc_header *h;
+
+ if (tim_signal) {
+ tim_signal_len = 1 + 1 + WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP;
+ }
+
+ /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
+ dataOffset = WLFC_CTL_VALUE_LEN_PKTTAG + 2 + tim_signal_len;
+ fillers = ROUNDUP(dataOffset, 4) - dataOffset;
+ dataOffset += fillers;
+
+ PKTPUSH(ctx->osh, p, dataOffset);
+ wlh = (uint8*) PKTDATA(ctx->osh, p);
+
+ wl_pktinfo = htol32(htodtag);
+
+ wlh[0] = WLFC_CTL_TYPE_PKTTAG;
+ wlh[1] = WLFC_CTL_VALUE_LEN_PKTTAG;
+ memcpy(&wlh[2], &wl_pktinfo, sizeof(uint32));
+
+ if (tim_signal_len) {
+ wlh[dataOffset - fillers - tim_signal_len ] =
+ WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP;
+ wlh[dataOffset - fillers - tim_signal_len + 1] =
+ WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP;
+ wlh[dataOffset - fillers - tim_signal_len + 2] = mac_handle;
+ wlh[dataOffset - fillers - tim_signal_len + 3] = tim_bmp;
+ }
+ if (fillers)
+ memset(&wlh[dataOffset - fillers], WLFC_CTL_TYPE_FILLER, fillers);
+
+ PKTPUSH(ctx->osh, p, BDC_HEADER_LEN);
+ h = (struct bdc_header *)PKTDATA(ctx->osh, p);
+ h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
+ if (PKTSUMNEEDED(p))
+ h->flags |= BDC_FLAG_SUM_NEEDED;
+
+
+ h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK);
+ h->flags2 = 0;
+ h->dataOffset = dataOffset >> 2;
+ BDC_SET_IF_IDX(h, DHD_PKTTAG_IF(PKTTAG(p)));
+ return BCME_OK;
+}
+
+static int
+_dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf)
+{
+ struct bdc_header *h;
+
+ if (PKTLEN(ctx->osh, pktbuf) < BDC_HEADER_LEN) {
+ AP6210_DEBUG("%s: rx data too short (%d < %d)\n", __FUNCTION__,
+ PKTLEN(ctx->osh, pktbuf), BDC_HEADER_LEN);
+ return BCME_ERROR;
+ }
+ h = (struct bdc_header *)PKTDATA(ctx->osh, pktbuf);
+
+ /* pull BDC header */
+ PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN);
+
+ if (PKTLEN(ctx->osh, pktbuf) < (h->dataOffset << 2)) {
+ AP6210_DEBUG("%s: rx data too short (%d < %d)\n", __FUNCTION__,
+ PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2));
+ return BCME_ERROR;
+ }
+
+ /* pull wl-header */
+ PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2));
+ return BCME_OK;
+}
+
+static wlfc_mac_descriptor_t*
+_dhd_wlfc_find_table_entry(athost_wl_status_info_t* ctx, void* p)
+{
+ int i;
+ wlfc_mac_descriptor_t* table = ctx->destination_entries.nodes;
+ uint8 ifid = DHD_PKTTAG_IF(PKTTAG(p));
+ uint8* dstn = DHD_PKTTAG_DSTN(PKTTAG(p));
+ wlfc_mac_descriptor_t* entry = NULL;
+ int iftype = ctx->destination_entries.interfaces[ifid].iftype;
+
+ /* Multicast destination and P2P clients get the interface entry.
+ * STA gets the interface entry if there is no exact match. For
+ * example, TDLS destinations have their own entry.
+ */
+ if ((iftype == WLC_E_IF_ROLE_STA || ETHER_ISMULTI(dstn) ||
+ iftype == WLC_E_IF_ROLE_P2P_CLIENT) &&
+ (ctx->destination_entries.interfaces[ifid].occupied)) {
+ entry = &ctx->destination_entries.interfaces[ifid];
+ }
+
+ if (entry != NULL && ETHER_ISMULTI(dstn))
+ return entry;
+
+ for (i = 0; i < WLFC_MAC_DESC_TABLE_SIZE; i++) {
+ if (table[i].occupied) {
+ if (table[i].interface_id == ifid) {
+ if (!memcmp(table[i].ea, dstn, ETHER_ADDR_LEN)) {
+ entry = &table[i];
+ break;
+ }
+ }
+ }
+ }
+
+ return entry != NULL ? entry : &ctx->destination_entries.other;
+}
+
+static int
+_dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx,
+ void* p, ewlfc_packet_state_t pkt_type, uint32 hslot)
+{
+ /*
+ put the packet back to the head of queue
+
+ - suppressed packet goes back to suppress sub-queue
+ - pull out the header, if new or delayed packet
+
+ Note: hslot is used only when header removal is done.
+ */
+ wlfc_mac_descriptor_t* entry;
+ void* pktout;
+ int rc = BCME_OK;
+ int prec;
+
+ entry = _dhd_wlfc_find_table_entry(ctx, p);
+ prec = DHD_PKTTAG_FIFO(PKTTAG(p));
+ if (entry != NULL) {
+ if (pkt_type == eWLFC_PKTTYPE_SUPPRESSED) {
+ /* wl-header is saved for suppressed packets */
+ if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, ((prec << 1) + 1), p) == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ rc = BCME_ERROR;
+ }
+ }
+ else {
+ /* remove header first */
+ rc = _dhd_wlfc_pullheader(ctx, p);
+ if (rc != BCME_OK) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ /* free the hanger slot */
+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1);
+ PKTFREE(ctx->osh, p, TRUE);
+ ctx->stats.rollback_failed++;
+ return BCME_ERROR;
+ }
+
+ if (pkt_type == eWLFC_PKTTYPE_DELAYED) {
+ /* delay-q packets are going to delay-q */
+ if (WLFC_PKTQ_PENQ_HEAD(&entry->psq, (prec << 1), p) == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ rc = BCME_ERROR;
+ }
+ }
+
+ /* free the hanger slot */
+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1);
+
+ /* decrement sequence count */
+ WLFC_DECR_SEQCOUNT(entry, prec);
+ }
+ /*
+ if this packet did not count against FIFO credit, it must have
+ taken a requested_credit from the firmware (for pspoll etc.)
+ */
+ if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) {
+ entry->requested_credit++;
+ }
+ }
+ else {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ rc = BCME_ERROR;
+ }
+ if (rc != BCME_OK)
+ ctx->stats.rollback_failed++;
+ else
+ ctx->stats.rollback++;
+
+ return rc;
+}
+
+static void
+_dhd_wlfc_flow_control_check(athost_wl_status_info_t* ctx, struct pktq* pq, uint8 if_id)
+{
+ dhd_pub_t *dhdp;
+
+ ASSERT(ctx);
+
+ dhdp = (dhd_pub_t *)ctx->dhdp;
+
+ if (dhdp && dhdp->skip_fc && dhdp->skip_fc())
+ return;
+
+ if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) {
+ /* start traffic */
+ ctx->hostif_flow_state[if_id] = OFF;
+ /*
+ AP6210_DEBUG("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n",
+ pq->len, if_id, __FUNCTION__);
+ */
+ AP6210_DEBUG("F");
+
+ dhd_txflowcontrol(ctx->dhdp, if_id, OFF);
+
+ ctx->toggle_host_if = 0;
+ }
+ if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) {
+ /* stop traffic */
+ ctx->hostif_flow_state[if_id] = ON;
+ /*
+ AP6210_DEBUG("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n",
+ pq->len, if_id, __FUNCTION__);
+ */
+ AP6210_DEBUG("N");
+
+ dhd_txflowcontrol(ctx->dhdp, if_id, ON);
+
+ ctx->host_ifidx = if_id;
+ ctx->toggle_host_if = 1;
+ }
+
+ return;
+}
+
+static int
+_dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
+ uint8 ta_bmp)
+{
+ int rc = BCME_OK;
+ void* p = NULL;
+ int dummylen = ((dhd_pub_t *)ctx->dhdp)->hdrlen+ 12;
+
+ /* allocate a dummy packet */
+ p = PKTGET(ctx->osh, dummylen, TRUE);
+ if (p) {
+ PKTPULL(ctx->osh, p, dummylen);
+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), 0);
+ _dhd_wlfc_pushheader(ctx, p, TRUE, ta_bmp, entry->mac_handle, 0);
+ DHD_PKTTAG_SETSIGNALONLY(PKTTAG(p), 1);
+#ifdef PROP_TXSTATUS_DEBUG
+ ctx->stats.signal_only_pkts_sent++;
+#endif
+ rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p);
+ if (rc != BCME_OK) {
+ PKTFREE(ctx->osh, p, TRUE);
+ }
+ }
+ else {
+ AP6210_ERR("%s: couldn't allocate new %d-byte packet\n",
+ __FUNCTION__, dummylen);
+ rc = BCME_NOMEM;
+ }
+ return rc;
+}
+
+/* Return TRUE if traffic availability changed */
+static bool
+_dhd_wlfc_traffic_pending_check(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
+ int prec)
+{
+ bool rc = FALSE;
+
+ if (entry->state == WLFC_STATE_CLOSE) {
+ if ((pktq_plen(&entry->psq, (prec << 1)) == 0) &&
+ (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) {
+
+ if (entry->traffic_pending_bmp & NBITVAL(prec)) {
+ rc = TRUE;
+ entry->traffic_pending_bmp =
+ entry->traffic_pending_bmp & ~ NBITVAL(prec);
+ }
+ }
+ else {
+ if (!(entry->traffic_pending_bmp & NBITVAL(prec))) {
+ rc = TRUE;
+ entry->traffic_pending_bmp =
+ entry->traffic_pending_bmp | NBITVAL(prec);
+ }
+ }
+ }
+ if (rc) {
+ /* request a TIM update to firmware at the next piggyback opportunity */
+ if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp) {
+ entry->send_tim_signal = 1;
+ _dhd_wlfc_send_signalonly_packet(ctx, entry, entry->traffic_pending_bmp);
+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
+ entry->send_tim_signal = 0;
+ }
+ else {
+ rc = FALSE;
+ }
+ }
+ return rc;
+}
+
+static int
+_dhd_wlfc_enque_suppressed(athost_wl_status_info_t* ctx, int prec, void* p)
+{
+ wlfc_mac_descriptor_t* entry;
+
+ entry = _dhd_wlfc_find_table_entry(ctx, p);
+ if (entry == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_NOTFOUND;
+ }
+ /*
+ - suppressed packets go to sub_queue[2*prec + 1] AND
+ - delayed packets go to sub_queue[2*prec + 0] to ensure
+ order of delivery.
+ */
+ if (WLFC_PKTQ_PENQ(&entry->psq, ((prec << 1) + 1), p) == NULL) {
+ ctx->stats.delayq_full_error++;
+ /* AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__); */
+ AP6210_DEBUG("s");
+ return BCME_ERROR;
+ }
+ /* A packet has been pushed, update traffic availability bitmap, if applicable */
+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec);
+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, DHD_PKTTAG_IF(PKTTAG(p)));
+ return BCME_OK;
+}
+
+static int
+_dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx,
+ wlfc_mac_descriptor_t* entry, void* p, int header_needed, uint32* slot)
+{
+ int rc = BCME_OK;
+ int hslot = WLFC_HANGER_MAXITEMS;
+ bool send_tim_update = FALSE;
+ uint32 htod = 0;
+ uint8 free_ctr;
+
+ *slot = hslot;
+
+ if (entry == NULL) {
+ entry = _dhd_wlfc_find_table_entry(ctx, p);
+ }
+
+ if (entry == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_ERROR;
+ }
+ if (entry->send_tim_signal) {
+ send_tim_update = TRUE;
+ entry->send_tim_signal = 0;
+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
+ }
+ if (header_needed) {
+ hslot = dhd_wlfc_hanger_get_free_slot(ctx->hanger);
+ free_ctr = WLFC_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p)));
+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod);
+ WLFC_PKTFLAG_SET_GENERATION(htod, entry->generation);
+ entry->transit_count++;
+ }
+ else {
+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ }
+ WLFC_PKTID_HSLOT_SET(htod, hslot);
+ WLFC_PKTID_FREERUNCTR_SET(htod, free_ctr);
+ DHD_PKTTAG_SETPKTDIR(PKTTAG(p), 1);
+ WL_TXSTATUS_SET_FLAGS(htod, WLFC_PKTFLAG_PKTFROMHOST);
+ WL_TXSTATUS_SET_FIFO(htod, DHD_PKTTAG_FIFO(PKTTAG(p)));
+
+
+ if (!DHD_PKTTAG_CREDITCHECK(PKTTAG(p))) {
+ /*
+ Indicate that this packet is being sent in response to an
+ explicit request from the firmware side.
+ */
+ WLFC_PKTFLAG_SET_PKTREQUESTED(htod);
+ }
+ else {
+ WLFC_PKTFLAG_CLR_PKTREQUESTED(htod);
+ }
+ if (header_needed) {
+ rc = _dhd_wlfc_pushheader(ctx, p, send_tim_update,
+ entry->traffic_lastreported_bmp, entry->mac_handle, htod);
+ if (rc == BCME_OK) {
+ DHD_PKTTAG_SET_H2DTAG(PKTTAG(p), htod);
+ /*
+ a new header was created for this packet.
+ push to hanger slot and scrub q. Since bus
+ send succeeded, increment seq number as well.
+ */
+ rc = dhd_wlfc_hanger_pushpkt(ctx->hanger, p, hslot);
+ if (rc == BCME_OK) {
+ /* increment free running sequence count */
+ WLFC_INCR_SEQCOUNT(entry, DHD_PKTTAG_FIFO(PKTTAG(p)));
+#ifdef PROP_TXSTATUS_DEBUG
+ ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].push_time =
+ OSL_SYSUPTIME();
+#endif
+ }
+ else {
+ AP6210_DEBUG("%s() hanger_pushpkt() failed, rc: %d\n",
+ __FUNCTION__, rc);
+ }
+ }
+ }
+ else {
+ int gen;
+
+ /* remove old header */
+ rc = _dhd_wlfc_pullheader(ctx, p);
+ if (rc == BCME_OK) {
+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen);
+
+ WLFC_PKTFLAG_SET_GENERATION(htod, gen);
+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ /* push new header */
+ _dhd_wlfc_pushheader(ctx, p, send_tim_update,
+ entry->traffic_lastreported_bmp, entry->mac_handle, htod);
+ }
+ }
+ *slot = hslot;
+ return rc;
+}
+
+static int
+_dhd_wlfc_is_destination_closed(athost_wl_status_info_t* ctx,
+ wlfc_mac_descriptor_t* entry, int prec)
+{
+ if (ctx->destination_entries.interfaces[entry->interface_id].iftype ==
+ WLC_E_IF_ROLE_P2P_GO) {
+ /* - destination interface is of type p2p GO.
+ For a p2pGO interface, if the destination is OPEN but the interface is
+ CLOSEd, do not send traffic. But if the dstn is CLOSEd while there is
+ destination-specific-credit left send packets. This is because the
+ firmware storing the destination-specific-requested packet in queue.
+ */
+ if ((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) &&
+ (entry->requested_packet == 0))
+ return 1;
+ }
+ /* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */
+ if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) &&
+ (entry->requested_packet == 0)) ||
+ (!(entry->ac_bitmap & (1 << prec))))
+ return 1;
+
+ return 0;
+}
+
+static void*
+_dhd_wlfc_deque_delayedq(athost_wl_status_info_t* ctx,
+ int prec, uint8* ac_credit_spent, uint8* needs_hdr, wlfc_mac_descriptor_t** entry_out)
+{
+ wlfc_mac_descriptor_t* entry;
+ wlfc_mac_descriptor_t* table;
+ uint8 token_pos;
+ int total_entries;
+ void* p = NULL;
+ int pout;
+ int i;
+
+ *entry_out = NULL;
+ token_pos = ctx->token_pos[prec];
+ /* most cases a packet will count against FIFO credit */
+ *ac_credit_spent = 1;
+ *needs_hdr = 1;
+
+ /* search all entries, include nodes as well as interfaces */
+ table = (wlfc_mac_descriptor_t*)&ctx->destination_entries;
+ total_entries = sizeof(ctx->destination_entries)/sizeof(wlfc_mac_descriptor_t);
+
+ for (i = 0; i < total_entries; i++) {
+ entry = &table[(token_pos + i) % total_entries];
+ if (entry->occupied && !entry->deleting) {
+ if (!_dhd_wlfc_is_destination_closed(ctx, entry, prec)) {
+ p = pktq_mdeq(&entry->psq,
+ /* higher precedence will be picked up first,
+ * i.e. suppressed packets before delayed ones
+ */
+ NBITVAL((prec << 1) + 1), &pout);
+ *needs_hdr = 0;
+
+ if (p == NULL) {
+ if (entry->suppressed == TRUE) {
+ if ((entry->suppr_transit_count <=
+ entry->suppress_count)) {
+ entry->suppressed = FALSE;
+ } else {
+ return NULL;
+ }
+ }
+ /* De-Q from delay Q */
+ p = pktq_mdeq(&entry->psq,
+ NBITVAL((prec << 1)),
+ &pout);
+ *needs_hdr = 1;
+ }
+
+ if (p != NULL) {
+ /* did the packet come from suppress sub-queue? */
+ if (entry->requested_credit > 0) {
+ entry->requested_credit--;
+#ifdef PROP_TXSTATUS_DEBUG
+ entry->dstncredit_sent_packets++;
+#endif
+ /*
+ if the packet was pulled out while destination is in
+ closed state but had a non-zero packets requested,
+ then this should not count against the FIFO credit.
+ That is due to the fact that the firmware will
+ most likely hold onto this packet until a suitable
+ time later to push it to the appropriate AC FIFO.
+ */
+ if (entry->state == WLFC_STATE_CLOSE)
+ *ac_credit_spent = 0;
+ }
+ else if (entry->requested_packet > 0) {
+ entry->requested_packet--;
+ DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p));
+ if (entry->state == WLFC_STATE_CLOSE)
+ *ac_credit_spent = 0;
+ }
+ /* move token to ensure fair round-robin */
+ ctx->token_pos[prec] =
+ (token_pos + i + 1) % total_entries;
+ *entry_out = entry;
+ _dhd_wlfc_flow_control_check(ctx, &entry->psq,
+ DHD_PKTTAG_IF(PKTTAG(p)));
+ /*
+ A packet has been picked up, update traffic
+ availability bitmap, if applicable
+ */
+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec);
+ return p;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+void *
+_dhd_wlfc_pktq_peek_tail(struct pktq *pq, int *prec_out)
+{
+ int prec;
+
+ ASSERT(pq);
+
+ if (pq->len == 0)
+ return NULL;
+
+ for (prec = 0; prec < pq->hi_prec; prec++)
+ /* only pick packets from dealyed-q */
+ if (((prec & 1) == 0) && pq->q[prec].head)
+ break;
+
+ if (prec_out)
+ *prec_out = prec;
+
+ return (pq->q[prec].tail);
+}
+
+bool
+_dhd_wlfc_prec_enq_with_drop(dhd_pub_t *dhdp, struct pktq *pq, void *pkt, int prec)
+{
+ void *p = NULL;
+ int eprec = -1; /* precedence to evict from */
+
+ ASSERT(dhdp && pq && pkt);
+ ASSERT(prec >= 0 && prec < pq->num_prec);
+
+ /* Fast case, precedence queue is not full and we are also not
+ * exceeding total queue length
+ */
+ if (!pktq_pfull(pq, prec) && !pktq_full(pq)) {
+ pktq_penq(pq, prec, pkt);
+ return TRUE;
+ }
+
+ /* Determine precedence from which to evict packet, if any */
+ if (pktq_pfull(pq, prec))
+ eprec = prec;
+ else if (pktq_full(pq)) {
+ p = _dhd_wlfc_pktq_peek_tail(pq, &eprec);
+ if (!p) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return FALSE;
+ }
+ if ((eprec > prec) || (eprec < 0)) {
+ if (!pktq_pempty(pq, prec)) {
+ eprec = prec;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+
+ /* Evict if needed */
+ if (eprec >= 0) {
+ /* Detect queueing to unconfigured precedence */
+ ASSERT(!pktq_pempty(pq, eprec));
+ /* Evict all fragmented frames */
+ dhd_prec_drop_pkts(dhdp->osh, pq, eprec);
+ }
+
+ /* Enqueue */
+ p = pktq_penq(pq, prec, pkt);
+ if (!p) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int
+_dhd_wlfc_enque_delayq(athost_wl_status_info_t* ctx, void* pktbuf, int prec)
+{
+ wlfc_mac_descriptor_t* entry;
+
+ if (pktbuf != NULL) {
+ entry = _dhd_wlfc_find_table_entry(ctx, pktbuf);
+
+ if (entry == NULL) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_ERROR;
+ }
+
+ /*
+ - suppressed packets go to sub_queue[2*prec + 1] AND
+ - delayed packets go to sub_queue[2*prec + 0] to ensure
+ order of delivery.
+ */
+ if (_dhd_wlfc_prec_enq_with_drop(ctx->dhdp, &entry->psq, pktbuf, (prec << 1))
+ == FALSE) {
+ AP6210_DEBUG("D");
+ /* dhd_txcomplete(ctx->dhdp, pktbuf, FALSE); */
+ PKTFREE(ctx->osh, pktbuf, TRUE);
+ ctx->stats.delayq_full_error++;
+ return BCME_ERROR;
+ }
+
+ /*
+ A packet has been pushed, update traffic availability bitmap,
+ if applicable
+ */
+ _dhd_wlfc_traffic_pending_check(ctx, entry, prec);
+
+ }
+ return BCME_OK;
+}
+
+bool ifpkt_fn(void* p, int ifid)
+{
+ return (ifid == DHD_PKTTAG_IF(PKTTAG(p)));
+}
+
+static int
+_dhd_wlfc_mac_entry_update(athost_wl_status_info_t* ctx, wlfc_mac_descriptor_t* entry,
+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea)
+{
+ int rc = BCME_OK;
+
+ if (action == eWLFC_MAC_ENTRY_ACTION_ADD) {
+ entry->occupied = 1;
+ entry->state = WLFC_STATE_OPEN;
+ entry->requested_credit = 0;
+ entry->interface_id = ifid;
+ entry->iftype = iftype;
+ entry->ac_bitmap = 0xff; /* update this when handling APSD */
+ /* for an interface entry we may not care about the MAC address */
+ if (ea != NULL)
+ memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN);
+ pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN);
+ }
+ else if (action == eWLFC_MAC_ENTRY_ACTION_UPDATE) {
+ entry->occupied = 1;
+ entry->state = WLFC_STATE_OPEN;
+ entry->requested_credit = 0;
+ entry->interface_id = ifid;
+ entry->iftype = iftype;
+ entry->ac_bitmap = 0xff; /* update this when handling APSD */
+ /* for an interface entry we may not care about the MAC address */
+ if (ea != NULL)
+ memcpy(&entry->ea[0], ea, ETHER_ADDR_LEN);
+ }
+ else if (action == eWLFC_MAC_ENTRY_ACTION_DEL) {
+ /* When the entry is deleted, the packets that are queued in the entry must be
+ cleanup. The cleanup action should be before the occupied is set as 0. The
+ flag deleting is set to avoid de-queue action when these queues are being
+ cleanup
+ */
+ entry->deleting = 1;
+ dhd_wlfc_cleanup(ctx->dhdp, ifpkt_fn, ifid);
+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, ifid);
+ entry->deleting = 0;
+
+ entry->occupied = 0;
+ entry->suppressed = 0;
+ entry->state = WLFC_STATE_CLOSE;
+ entry->requested_credit = 0;
+ entry->transit_count = 0;
+ entry->suppr_transit_count = 0;
+ entry->suppress_count = 0;
+ memset(&entry->ea[0], 0, ETHER_ADDR_LEN);
+
+ /* enable after packets are queued-deqeued properly.
+ pktq_flush(dhd->osh, &entry->psq, FALSE, NULL, 0);
+ */
+ }
+ return rc;
+}
+
+int
+_dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, uint8 available_credit_map, int borrower_ac)
+{
+ int lender_ac;
+ int rc = BCME_ERROR;
+
+ if (ctx == NULL || available_credit_map == 0) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_BADARG;
+ }
+
+ /* Borrow from lowest priority available AC (including BC/MC credits) */
+ for (lender_ac = 0; lender_ac <= AC_COUNT; lender_ac++) {
+ if ((available_credit_map && (1 << lender_ac)) &&
+ (ctx->FIFO_credit[lender_ac] > 0)) {
+ ctx->credits_borrowed[borrower_ac][lender_ac]++;
+ ctx->FIFO_credit[lender_ac]--;
+ rc = BCME_OK;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+int
+dhd_wlfc_interface_entry_update(void* state,
+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea)
+{
+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+ wlfc_mac_descriptor_t* entry;
+ int ret;
+
+ if (ifid >= WLFC_MAX_IFNUM)
+ return BCME_BADARG;
+
+ entry = &ctx->destination_entries.interfaces[ifid];
+ ret = _dhd_wlfc_mac_entry_update(ctx, entry, action, ifid, iftype, ea);
+ return ret;
+}
+
+int
+dhd_wlfc_FIFOcreditmap_update(void* state, uint8* credits)
+{
+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+
+ /* update the AC FIFO credit map */
+ ctx->FIFO_credit[0] = credits[0];
+ ctx->FIFO_credit[1] = credits[1];
+ ctx->FIFO_credit[2] = credits[2];
+ ctx->FIFO_credit[3] = credits[3];
+ /* credit for bc/mc packets */
+ ctx->FIFO_credit[4] = credits[4];
+ /* credit for ATIM FIFO is not used yet. */
+ ctx->FIFO_credit[5] = 0;
+ return BCME_OK;
+}
+
+int
+_dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac,
+ dhd_wlfc_commit_info_t *commit_info, f_commitpkt_t fcommit, void* commit_ctx)
+{
+ uint32 hslot;
+ int rc;
+
+ /*
+ if ac_fifo_credit_spent = 0
+
+ This packet will not count against the FIFO credit.
+ To ensure the txstatus corresponding to this packet
+ does not provide an implied credit (default behavior)
+ mark the packet accordingly.
+
+ if ac_fifo_credit_spent = 1
+
+ This is a normal packet and it counts against the FIFO
+ credit count.
+ */
+ DHD_PKTTAG_SETCREDITCHECK(PKTTAG(commit_info->p), commit_info->ac_fifo_credit_spent);
+ rc = _dhd_wlfc_pretx_pktprocess(ctx, commit_info->mac_entry, commit_info->p,
+ commit_info->needs_hdr, &hslot);
+
+ if (rc == BCME_OK)
+ rc = fcommit(commit_ctx, commit_info->p);
+ else
+ ctx->stats.generic_error++;
+
+ if (rc == BCME_OK) {
+ ctx->stats.pkt2bus++;
+ if (commit_info->ac_fifo_credit_spent) {
+ ctx->stats.send_pkts[ac]++;
+ WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac);
+ }
+ } else if (rc == BCME_NORESOURCE)
+ rc = BCME_ERROR;
+ else {
+ /*
+ bus commit has failed, rollback.
+ - remove wl-header for a delayed packet
+ - save wl-header header for suppressed packets
+ */
+ rc = _dhd_wlfc_rollback_packet_toq(ctx, commit_info->p,
+ (commit_info->pkt_type), hslot);
+
+ rc = BCME_ERROR;
+ }
+
+ return rc;
+}
+
+int
+dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx, void *pktbuf)
+{
+ int ac;
+ int credit;
+ int rc;
+ dhd_wlfc_commit_info_t commit_info;
+ athost_wl_status_info_t* ctx = (athost_wl_status_info_t*)state;
+ int credit_count = 0;
+ int bus_retry_count = 0;
+ uint8 ac_available = 0; /* Bitmask for 4 ACs + BC/MC */
+
+ if ((state == NULL) ||
+ (fcommit == NULL)) {
+ AP6210_DEBUG("Error: %s():%d\n", __FUNCTION__, __LINE__);
+ return BCME_BADARG;
+ }
+
+ memset(&commit_info, 0, sizeof(commit_info));
+
+ /*
+ Commit packets for regular AC traffic. Higher priority first.
+ First, use up FIFO credits available to each AC. Based on distribution
+ and credits left, borrow from other ACs as applicable
+
+ -NOTE:
+ If the bus between the host and firmware is overwhelmed by the
+ traffic from host, it is possible that higher priority traffic
+ starves the lower priority queue. If that occurs often, we may
+ have to employ weighted round-robin or ucode scheme to avoid
+ low priority packet starvation.
+ */
+
+ if (pktbuf) {
+ ac = DHD_PKTTAG_FIFO(PKTTAG(pktbuf));
+ if (ETHER_ISMULTI(DHD_PKTTAG_DSTN(PKTTAG(pktbuf)))) {
+ ASSERT(ac == AC_COUNT);
+ commit_info.needs_hdr = 1;
+ commit_info.mac_entry = NULL;
+ commit_info.pkt_type = eWLFC_PKTTYPE_NEW;
+ commit_info.p = pktbuf;
+ if (ctx->FIFO_credit[ac]) {
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+
+ /* Bus commits may fail (e.g. flow control); abort after retries */
+ if (rc == BCME_OK) {
+ if (commit_info.ac_fifo_credit_spent) {
+ (void) _dhd_wlfc_borrow_credit(ctx,
+ ac_available, ac);
+ credit_count--;
+ }
+ } else {
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ AP6210_ERR(" %s: bus error %d\n",
+ __FUNCTION__, rc);
+ return rc;
+ }
+ }
+ }
+ }
+ else {
+ /* en-queue the packets to respective queue. */
+ rc = _dhd_wlfc_enque_delayq(ctx, pktbuf, ac);
+ }
+ }
+
+ for (ac = AC_COUNT; ac >= 0; ac--) {
+
+ bool bQueueIdle = TRUE;
+
+ /* packets from delayQ with less priority are fresh and they'd need header and
+ * have no MAC entry
+ */
+ commit_info.needs_hdr = 1;
+ commit_info.mac_entry = NULL;
+ commit_info.pkt_type = eWLFC_PKTTYPE_NEW;
+
+ for (credit = 0; credit < ctx->FIFO_credit[ac];) {
+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
+ &(commit_info.ac_fifo_credit_spent),
+ &(commit_info.needs_hdr),
+ &(commit_info.mac_entry));
+
+ if (commit_info.p == NULL)
+ break;
+
+ bQueueIdle = FALSE;
+
+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
+ eWLFC_PKTTYPE_SUPPRESSED;
+
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+
+ /* Bus commits may fail (e.g. flow control); abort after retries */
+ if (rc == BCME_OK) {
+ if (commit_info.ac_fifo_credit_spent) {
+ credit++;
+ }
+ }
+ else {
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ AP6210_ERR("%s: bus error %d\n", __FUNCTION__, rc);
+ ctx->FIFO_credit[ac] -= credit;
+ return rc;
+ }
+ }
+ }
+
+ ctx->FIFO_credit[ac] -= credit;
+
+
+ /* If no pkts can be dequed, the credit can be borrowed */
+ if (bQueueIdle) {
+ ac_available |= (1 << ac);
+ credit_count += ctx->FIFO_credit[ac];
+ }
+ }
+
+ /* We borrow only for AC_BE and only if no other traffic seen for DEFER_PERIOD
+
+ Note that (ac_available & WLFC_AC_BE_TRAFFIC_ONLY) is done to:
+ a) ignore BC/MC for deferring borrow
+ b) ignore AC_BE being available along with other ACs
+ (this should happen only for pure BC/MC traffic)
+
+ i.e. AC_VI, AC_VO, AC_BK all MUST be available (i.e. no traffic) and
+ we do not care if AC_BE and BC/MC are available or not
+ */
+ if ((ac_available & WLFC_AC_BE_TRAFFIC_ONLY) == WLFC_AC_BE_TRAFFIC_ONLY) {
+
+ if (ctx->allow_credit_borrow) {
+ ac = 1; /* Set ac to AC_BE and borrow credits */
+ }
+ else {
+ int delta;
+ int curr_t = OSL_SYSUPTIME();
+
+ if (curr_t > ctx->borrow_defer_timestamp)
+ delta = curr_t - ctx->borrow_defer_timestamp;
+ else
+ delta = 0xffffffff + curr_t - ctx->borrow_defer_timestamp;
+
+ if (delta >= WLFC_BORROW_DEFER_PERIOD_MS) {
+ /* Reset borrow but defer to next iteration (defensive borrowing) */
+ ctx->allow_credit_borrow = TRUE;
+ ctx->borrow_defer_timestamp = 0;
+ }
+ return BCME_OK;
+ }
+ }
+ else {
+ /* If we have multiple AC traffic, turn off borrowing, mark time and bail out */
+ ctx->allow_credit_borrow = FALSE;
+ ctx->borrow_defer_timestamp = OSL_SYSUPTIME();
+ return BCME_OK;
+ }
+
+ /* At this point, borrow all credits only for "ac" (which should be set above to AC_BE)
+ Generically use "ac" only in case we extend to all ACs in future
+ */
+ for (; (credit_count > 0);) {
+
+ commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
+ &(commit_info.ac_fifo_credit_spent),
+ &(commit_info.needs_hdr),
+ &(commit_info.mac_entry));
+ if (commit_info.p == NULL)
+ break;
+
+ commit_info.pkt_type = (commit_info.needs_hdr) ? eWLFC_PKTTYPE_DELAYED :
+ eWLFC_PKTTYPE_SUPPRESSED;
+
+ rc = _dhd_wlfc_handle_packet_commit(ctx, ac, &commit_info,
+ fcommit, commit_ctx);
+
+ /* Bus commits may fail (e.g. flow control); abort after retries */
+ if (rc == BCME_OK) {
+ if (commit_info.ac_fifo_credit_spent) {
+ (void) _dhd_wlfc_borrow_credit(ctx, ac_available, ac);
+ credit_count--;
+ }
+ }
+ else {
+ bus_retry_count++;
+ if (bus_retry_count >= BUS_RETRIES) {
+ AP6210_ERR("%s: bus error %d\n", __FUNCTION__, rc);
+ return rc;
+ }
+ }
+ }
+ return BCME_OK;
+}
+
+static uint8
+dhd_wlfc_find_mac_desc_id_from_mac(dhd_pub_t *dhdp, uint8* ea)
+{
+ wlfc_mac_descriptor_t* table =
+ ((athost_wl_status_info_t*)dhdp->wlfc_state)->destination_entries.nodes;
+ uint8 table_index;
+
+ if (ea != NULL) {
+ for (table_index = 0; table_index < WLFC_MAC_DESC_TABLE_SIZE; table_index++) {
+ if ((memcmp(ea, &table[table_index].ea[0], ETHER_ADDR_LEN) == 0) &&
+ table[table_index].occupied)
+ return table_index;
+ }
+ }
+ return WLFC_MAC_DESC_ID_INVALID;
+}
+
+void
+dhd_wlfc_txcomplete(dhd_pub_t *dhd, void *txp, bool success)
+{
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ void* p;
+ int fifo_id;
+
+ if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) {
+#ifdef PROP_TXSTATUS_DEBUG
+ wlfc->stats.signal_only_pkts_freed++;
+#endif
+ /* is this a signal-only packet? */
+ if (success)
+ PKTFREE(wlfc->osh, txp, TRUE);
+ return;
+ }
+ if (!success) {
+ AP6210_DEBUG("At: %s():%d, bus_complete() failure for %p, htod_tag:0x%08x\n",
+ __FUNCTION__, __LINE__, txp, DHD_PKTTAG_H2DTAG(PKTTAG(txp)));
+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG
+ (PKTTAG(txp))), &p, 1);
+
+ /* indicate failure and free the packet */
+ dhd_txcomplete(dhd, txp, FALSE);
+
+ /* return the credit, if necessary */
+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(txp))) {
+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */
+
+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(txp));
+
+ /* Return credits to highest priority lender first */
+ for (lender = AC_COUNT; lender >= 0; lender--) {
+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) {
+ wlfc->FIFO_credit[lender]++;
+ wlfc->credits_borrowed[fifo_id][lender]--;
+ credit_returned = 1;
+ break;
+ }
+ }
+
+ if (!credit_returned) {
+ wlfc->FIFO_credit[fifo_id]++;
+ }
+ }
+
+ PKTFREE(wlfc->osh, txp, TRUE);
+ }
+ return;
+}
+
+static int
+dhd_wlfc_compressed_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info, uint8 len)
+{
+ uint8 status_flag;
+ uint32 status;
+ int ret;
+ int remove_from_hanger = 1;
+ void* pktbuf;
+ uint8 fifo_id;
+ uint8 count = 0;
+ uint32 status_g;
+ uint32 hslot, hcnt;
+ wlfc_mac_descriptor_t* entry = NULL;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+
+ memcpy(&status, pkt_info, sizeof(uint32));
+ status_flag = WL_TXSTATUS_GET_FLAGS(status);
+ status_g = status & 0xff000000;
+ hslot = (status & 0x00ffff00) >> 8;
+ hcnt = status & 0xff;
+ len = pkt_info[4];
+
+ wlfc->stats.txstatus_in++;
+
+ if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) {
+ wlfc->stats.pkt_freed++;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) {
+ wlfc->stats.d11_suppress++;
+ remove_from_hanger = 0;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) {
+ wlfc->stats.wl_suppress++;
+ remove_from_hanger = 0;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) {
+ wlfc->stats.wlc_tossed_pkts++;
+ }
+ while (count < len) {
+ status = (status_g << 24) | (hslot << 8) | (hcnt);
+ count++;
+ hslot++;
+ hcnt++;
+
+ ret = dhd_wlfc_hanger_poppkt(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger);
+ if (ret != BCME_OK) {
+ /* do something */
+ continue;
+ }
+
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+
+ if (!remove_from_hanger) {
+ /* this packet was suppressed */
+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) {
+ entry->suppressed = TRUE;
+ entry->suppress_count = pktq_mlen(&entry->psq,
+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1));
+ entry->suppr_transit_count = entry->transit_count;
+ }
+ entry->generation = WLFC_PKTID_GEN(status);
+ }
+
+#ifdef PROP_TXSTATUS_DEBUG
+ {
+ uint32 new_t = OSL_SYSUPTIME();
+ uint32 old_t;
+ uint32 delta;
+ old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[
+ WLFC_PKTID_HSLOT_GET(status)].push_time;
+
+
+ wlfc->stats.latency_sample_count++;
+ if (new_t > old_t)
+ delta = new_t - old_t;
+ else
+ delta = 0xffffffff + new_t - old_t;
+ wlfc->stats.total_status_latency += delta;
+ wlfc->stats.latency_most_recent = delta;
+
+ wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta;
+ if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32))
+ wlfc->stats.idx_delta = 0;
+ }
+#endif /* PROP_TXSTATUS_DEBUG */
+
+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf));
+
+ /* pick up the implicit credit from this packet */
+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) {
+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) {
+
+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */
+
+ /* Return credits to highest priority lender first */
+ for (lender = AC_COUNT; lender >= 0; lender--) {
+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) {
+ wlfc->FIFO_credit[lender]++;
+ wlfc->credits_borrowed[fifo_id][lender]--;
+ credit_returned = 1;
+ break;
+ }
+ }
+
+ if (!credit_returned) {
+ wlfc->FIFO_credit[fifo_id]++;
+ }
+ }
+ }
+ else {
+ /*
+ if this packet did not count against FIFO credit, it must have
+ taken a requested_credit from the destination entry (for pspoll etc.)
+ */
+ if (!entry) {
+
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+ }
+ if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf)))
+ entry->requested_credit++;
+#ifdef PROP_TXSTATUS_DEBUG
+ entry->dstncredit_acks++;
+#endif
+ }
+ if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) ||
+ (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) {
+
+ ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf);
+ if (ret != BCME_OK) {
+ /* delay q is full, drop this packet */
+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status),
+ &pktbuf, 1);
+
+ /* indicate failure and free the packet */
+ dhd_txcomplete(dhd, pktbuf, FALSE);
+ entry->transit_count--;
+ DHD_WLFC_QMON_COMPLETE(entry);
+ /* packet is transmitted Successfully by dongle
+ * after first suppress.
+ */
+ if (entry->suppressed) {
+ entry->suppr_transit_count--;
+ }
+ PKTFREE(wlfc->osh, pktbuf, TRUE);
+ } else {
+ /* Mark suppressed to avoid a double free during wlfc cleanup */
+
+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status));
+ entry->suppress_count++;
+ }
+ }
+ else {
+ dhd_txcomplete(dhd, pktbuf, TRUE);
+ entry->transit_count--;
+ DHD_WLFC_QMON_COMPLETE(entry);
+
+ /* This packet is transmitted Successfully by dongle
+ * even after first suppress.
+ */
+ if (entry->suppressed) {
+ entry->suppr_transit_count--;
+ }
+ /* free the packet */
+ PKTFREE(wlfc->osh, pktbuf, TRUE);
+ }
+ }
+ return BCME_OK;
+}
+
+/* Handle discard or suppress indication */
+static int
+dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info)
+{
+ uint8 status_flag;
+ uint32 status;
+ int ret;
+ int remove_from_hanger = 1;
+ void* pktbuf;
+ uint8 fifo_id;
+ wlfc_mac_descriptor_t* entry = NULL;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+
+ memcpy(&status, pkt_info, sizeof(uint32));
+ status_flag = WL_TXSTATUS_GET_FLAGS(status);
+ wlfc->stats.txstatus_in++;
+
+ if (status_flag == WLFC_CTL_PKTFLAG_DISCARD) {
+ wlfc->stats.pkt_freed++;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) {
+ wlfc->stats.d11_suppress++;
+ remove_from_hanger = 0;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS) {
+ wlfc->stats.wl_suppress++;
+ remove_from_hanger = 0;
+ }
+
+ else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) {
+ wlfc->stats.wlc_tossed_pkts++;
+ }
+
+ ret = dhd_wlfc_hanger_poppkt(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), &pktbuf, remove_from_hanger);
+ if (ret != BCME_OK) {
+ /* do something */
+ return ret;
+ }
+
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+
+ if (!remove_from_hanger) {
+ /* this packet was suppressed */
+ if (!entry->suppressed || entry->generation != WLFC_PKTID_GEN(status)) {
+ entry->suppressed = TRUE;
+ entry->suppress_count = pktq_mlen(&entry->psq,
+ NBITVAL((WL_TXSTATUS_GET_FIFO(status) << 1) + 1));
+ entry->suppr_transit_count = entry->transit_count;
+ }
+ entry->generation = WLFC_PKTID_GEN(status);
+ }
+
+#ifdef PROP_TXSTATUS_DEBUG
+ {
+ uint32 new_t = OSL_SYSUPTIME();
+ uint32 old_t;
+ uint32 delta;
+ old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[
+ WLFC_PKTID_HSLOT_GET(status)].push_time;
+
+
+ wlfc->stats.latency_sample_count++;
+ if (new_t > old_t)
+ delta = new_t - old_t;
+ else
+ delta = 0xffffffff + new_t - old_t;
+ wlfc->stats.total_status_latency += delta;
+ wlfc->stats.latency_most_recent = delta;
+
+ wlfc->stats.deltas[wlfc->stats.idx_delta++] = delta;
+ if (wlfc->stats.idx_delta == sizeof(wlfc->stats.deltas)/sizeof(uint32))
+ wlfc->stats.idx_delta = 0;
+ }
+#endif /* PROP_TXSTATUS_DEBUG */
+
+ fifo_id = DHD_PKTTAG_FIFO(PKTTAG(pktbuf));
+
+ /* pick up the implicit credit from this packet */
+ if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) {
+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) {
+
+ int lender, credit_returned = 0; /* Note that borrower is fifo_id */
+
+ /* Return credits to highest priority lender first */
+ for (lender = AC_COUNT; lender >= 0; lender--) {
+ if (wlfc->credits_borrowed[fifo_id][lender] > 0) {
+ wlfc->FIFO_credit[lender]++;
+ wlfc->credits_borrowed[fifo_id][lender]--;
+ credit_returned = 1;
+ break;
+ }
+ }
+
+ if (!credit_returned) {
+ wlfc->FIFO_credit[fifo_id]++;
+ }
+ }
+ }
+ else {
+ /*
+ if this packet did not count against FIFO credit, it must have
+ taken a requested_credit from the destination entry (for pspoll etc.)
+ */
+ if (!entry) {
+
+ entry = _dhd_wlfc_find_table_entry(wlfc, pktbuf);
+ }
+ if (!DHD_PKTTAG_ONETIMEPKTRQST(PKTTAG(pktbuf)))
+ entry->requested_credit++;
+#ifdef PROP_TXSTATUS_DEBUG
+ entry->dstncredit_acks++;
+#endif
+ }
+ if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) ||
+ (status_flag == WLFC_CTL_PKTFLAG_WLSUPPRESS)) {
+
+ ret = _dhd_wlfc_enque_suppressed(wlfc, fifo_id, pktbuf);
+ if (ret != BCME_OK) {
+ /* delay q is full, drop this packet */
+ dhd_wlfc_hanger_poppkt(wlfc->hanger, WLFC_PKTID_HSLOT_GET(status),
+ &pktbuf, 1);
+
+ /* indicate failure and free the packet */
+ dhd_txcomplete(dhd, pktbuf, FALSE);
+ entry->transit_count--;
+ DHD_WLFC_QMON_COMPLETE(entry);
+ /* This packet is transmitted Successfully by
+ * dongle even after first suppress.
+ */
+ if (entry->suppressed) {
+ entry->suppr_transit_count--;
+ }
+ PKTFREE(wlfc->osh, pktbuf, TRUE);
+ } else {
+ /* Mark suppressed to avoid a double free during wlfc cleanup */
+
+ dhd_wlfc_hanger_mark_suppressed(wlfc->hanger,
+ WLFC_PKTID_HSLOT_GET(status), WLFC_PKTID_GEN(status));
+ entry->suppress_count++;
+ }
+ }
+ else {
+ dhd_txcomplete(dhd, pktbuf, TRUE);
+ entry->transit_count--;
+ DHD_WLFC_QMON_COMPLETE(entry);
+
+ /* This packet is transmitted Successfully by dongle even after first suppress. */
+ if (entry->suppressed) {
+ entry->suppr_transit_count--;
+ }
+ /* free the packet */
+ PKTFREE(wlfc->osh, pktbuf, TRUE);
+ }
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_fifocreditback_indicate(dhd_pub_t *dhd, uint8* credits)
+{
+ int i;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) {
+#ifdef PROP_TXSTATUS_DEBUG
+ wlfc->stats.fifo_credits_back[i] += credits[i];
+#endif
+ /* update FIFO credits */
+ if (wlfc->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT)
+ {
+ int lender; /* Note that borrower is i */
+
+ /* Return credits to highest priority lender first */
+ for (lender = AC_COUNT; (lender >= 0) && (credits[i] > 0); lender--) {
+ if (wlfc->credits_borrowed[i][lender] > 0) {
+ if (credits[i] >= wlfc->credits_borrowed[i][lender]) {
+ credits[i] -= wlfc->credits_borrowed[i][lender];
+ wlfc->FIFO_credit[lender] +=
+ wlfc->credits_borrowed[i][lender];
+ wlfc->credits_borrowed[i][lender] = 0;
+ }
+ else {
+ wlfc->credits_borrowed[i][lender] -= credits[i];
+ wlfc->FIFO_credit[lender] += credits[i];
+ credits[i] = 0;
+ }
+ }
+ }
+
+ /* If we have more credits left over, these must belong to the AC */
+ if (credits[i] > 0) {
+ wlfc->FIFO_credit[i] += credits[i];
+ }
+ }
+ }
+
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value)
+{
+ uint32 timestamp;
+
+ (void)dhd;
+
+ bcopy(&value[2], &timestamp, sizeof(uint32));
+ AP6210_DEBUG("RXPKT: SEQ: %d, timestamp %d\n", value[1], timestamp);
+ return BCME_OK;
+}
+
+
+static int
+dhd_wlfc_rssi_indicate(dhd_pub_t *dhd, uint8* rssi)
+{
+ (void)dhd;
+ (void)rssi;
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type)
+{
+ int rc;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ uint8 existing_index;
+ uint8 table_index;
+ uint8 ifid;
+ uint8* ea;
+
+ AP6210_DEBUG("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n",
+ __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7],
+ ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"),
+ WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0]);
+
+ table = wlfc->destination_entries.nodes;
+ table_index = WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]);
+ ifid = value[1];
+ ea = &value[2];
+
+ if (type == WLFC_CTL_TYPE_MACDESC_ADD) {
+ existing_index = dhd_wlfc_find_mac_desc_id_from_mac(dhd, &value[2]);
+ if (existing_index == WLFC_MAC_DESC_ID_INVALID) {
+ /* this MAC entry does not exist, create one */
+ if (!table[table_index].occupied) {
+ table[table_index].mac_handle = value[0];
+ rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index],
+ eWLFC_MAC_ENTRY_ACTION_ADD, ifid,
+ wlfc->destination_entries.interfaces[ifid].iftype,
+ ea);
+ }
+ else {
+ /* the space should have been empty, but it's not */
+ wlfc->stats.mac_update_failed++;
+ }
+ }
+ else {
+ /*
+ there is an existing entry, move it to new index
+ if necessary.
+ */
+ if (existing_index != table_index) {
+ /* if we already have an entry, free the old one */
+ table[existing_index].occupied = 0;
+ table[existing_index].state = WLFC_STATE_CLOSE;
+ table[existing_index].requested_credit = 0;
+ table[existing_index].interface_id = 0;
+ /* enable after packets are queued-deqeued properly.
+ pktq_flush(dhd->osh, &table[existing_index].psq, FALSE, NULL, 0);
+ */
+ }
+ }
+ }
+ if (type == WLFC_CTL_TYPE_MACDESC_DEL) {
+ if (table[table_index].occupied) {
+ rc = _dhd_wlfc_mac_entry_update(wlfc, &table[table_index],
+ eWLFC_MAC_ENTRY_ACTION_DEL, ifid,
+ wlfc->destination_entries.interfaces[ifid].iftype,
+ ea);
+ }
+ else {
+ /* the space should have been occupied, but it's not */
+ wlfc->stats.mac_update_failed++;
+ }
+ }
+ BCM_REFERENCE(rc);
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_psmode_update(dhd_pub_t *dhd, uint8* value, uint8 type)
+{
+ /* Handle PS on/off indication */
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ wlfc_mac_descriptor_t* desc;
+ uint8 mac_handle = value[0];
+ int i;
+
+ table = wlfc->destination_entries.nodes;
+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
+ if (desc->occupied) {
+ /* a fresh PS mode should wipe old ps credits? */
+ desc->requested_credit = 0;
+ if (type == WLFC_CTL_TYPE_MAC_OPEN) {
+ desc->state = WLFC_STATE_OPEN;
+ DHD_WLFC_CTRINC_MAC_OPEN(desc);
+ }
+ else {
+ desc->state = WLFC_STATE_CLOSE;
+ DHD_WLFC_CTRINC_MAC_CLOSE(desc);
+ /*
+ Indicate to firmware if there is any traffic pending.
+ */
+ for (i = AC_BE; i < AC_COUNT; i++) {
+ _dhd_wlfc_traffic_pending_check(wlfc, desc, i);
+ }
+ }
+ }
+ else {
+ wlfc->stats.psmode_update_failed++;
+ }
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_interface_update(dhd_pub_t *dhd, uint8* value, uint8 type)
+{
+ /* Handle PS on/off indication */
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ uint8 if_id = value[0];
+
+ if (if_id < WLFC_MAX_IFNUM) {
+ table = wlfc->destination_entries.interfaces;
+ if (table[if_id].occupied) {
+ if (type == WLFC_CTL_TYPE_INTERFACE_OPEN) {
+ table[if_id].state = WLFC_STATE_OPEN;
+ /* AP6210_DEBUG("INTERFACE[%d] OPEN\n", if_id); */
+ }
+ else {
+ table[if_id].state = WLFC_STATE_CLOSE;
+ /* AP6210_DEBUG("INTERFACE[%d] CLOSE\n", if_id); */
+ }
+ return BCME_OK;
+ }
+ }
+ wlfc->stats.interface_update_failed++;
+
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_credit_request(dhd_pub_t *dhd, uint8* value)
+{
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ wlfc_mac_descriptor_t* desc;
+ uint8 mac_handle;
+ uint8 credit;
+
+ table = wlfc->destination_entries.nodes;
+ mac_handle = value[1];
+ credit = value[0];
+
+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
+ if (desc->occupied) {
+ desc->requested_credit = credit;
+
+ desc->ac_bitmap = value[2];
+ }
+ else {
+ wlfc->stats.credit_request_failed++;
+ }
+ return BCME_OK;
+}
+
+static int
+dhd_wlfc_packet_request(dhd_pub_t *dhd, uint8* value)
+{
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ wlfc_mac_descriptor_t* desc;
+ uint8 mac_handle;
+ uint8 packet_count;
+
+ table = wlfc->destination_entries.nodes;
+ mac_handle = value[1];
+ packet_count = value[0];
+
+ desc = &table[WLFC_MAC_DESC_GET_LOOKUP_INDEX(mac_handle)];
+ if (desc->occupied) {
+ desc->requested_packet = packet_count;
+
+ desc->ac_bitmap = value[2];
+ }
+ else {
+ wlfc->stats.packet_request_failed++;
+ }
+ return BCME_OK;
+}
+
+static void
+dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len)
+{
+ if (info_len) {
+ if (info_buf) {
+ bcopy(val, info_buf, len);
+ *info_len = len;
+ }
+ else
+ *info_len = 0;
+ }
+}
+
+int
+dhd_wlfc_parse_header_info(dhd_pub_t *dhd, void* pktbuf, int tlv_hdr_len, uchar *reorder_info_buf,
+ uint *reorder_info_len)
+{
+ uint8 type, len;
+ uint8* value;
+ uint8* tmpbuf;
+ uint16 remainder = tlv_hdr_len;
+ uint16 processed = 0;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ tmpbuf = (uint8*)PKTDATA(dhd->osh, pktbuf);
+ if (remainder) {
+ while ((processed < (WLFC_MAX_PENDING_DATALEN * 2)) && (remainder > 0)) {
+ type = tmpbuf[processed];
+ if (type == WLFC_CTL_TYPE_FILLER) {
+ remainder -= 1;
+ processed += 1;
+ continue;
+ }
+
+ len = tmpbuf[processed + 1];
+ value = &tmpbuf[processed + 2];
+
+ if (remainder < (2 + len))
+ break;
+
+ remainder -= 2 + len;
+ processed += 2 + len;
+ if (type == WLFC_CTL_TYPE_TXSTATUS)
+ dhd_wlfc_txstatus_update(dhd, value);
+ if (type == WLFC_CTL_TYPE_COMP_TXSTATUS)
+ dhd_wlfc_compressed_txstatus_update(dhd, value, len);
+
+ else if (type == WLFC_CTL_TYPE_HOST_REORDER_RXPKTS)
+ dhd_wlfc_reorderinfo_indicate(value, len, reorder_info_buf,
+ reorder_info_len);
+ else if (type == WLFC_CTL_TYPE_FIFO_CREDITBACK)
+ dhd_wlfc_fifocreditback_indicate(dhd, value);
+
+ else if (type == WLFC_CTL_TYPE_RSSI)
+ dhd_wlfc_rssi_indicate(dhd, value);
+
+ else if (type == WLFC_CTL_TYPE_MAC_REQUEST_CREDIT)
+ dhd_wlfc_credit_request(dhd, value);
+
+ else if (type == WLFC_CTL_TYPE_MAC_REQUEST_PACKET)
+ dhd_wlfc_packet_request(dhd, value);
+
+ else if ((type == WLFC_CTL_TYPE_MAC_OPEN) ||
+ (type == WLFC_CTL_TYPE_MAC_CLOSE))
+ dhd_wlfc_psmode_update(dhd, value, type);
+
+ else if ((type == WLFC_CTL_TYPE_MACDESC_ADD) ||
+ (type == WLFC_CTL_TYPE_MACDESC_DEL))
+ dhd_wlfc_mac_table_update(dhd, value, type);
+
+ else if (type == WLFC_CTL_TYPE_TRANS_ID)
+ dhd_wlfc_dbg_senum_check(dhd, value);
+
+ else if ((type == WLFC_CTL_TYPE_INTERFACE_OPEN) ||
+ (type == WLFC_CTL_TYPE_INTERFACE_CLOSE)) {
+ dhd_wlfc_interface_update(dhd, value, type);
+ }
+ }
+ if (remainder != 0) {
+ /* trouble..., something is not right */
+ wlfc->stats.tlv_parse_failed++;
+ }
+ }
+ return BCME_OK;
+}
+
+int
+dhd_wlfc_init(dhd_pub_t *dhd)
+{
+ char iovbuf[12]; /* Room for "tlv" + '\0' + parameter */
+ /* enable all signals & indicate host proptxstatus logic is active */
+ uint32 tlv = dhd->wlfc_enabled?
+ WLFC_FLAGS_RSSI_SIGNALS |
+ WLFC_FLAGS_XONXOFF_SIGNALS |
+ WLFC_FLAGS_CREDIT_STATUS_SIGNALS |
+ WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE |
+ WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0;
+ /* WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | WLFC_FLAGS_HOST_RXRERODER_ACTIVE : 0; */
+
+
+ /*
+ try to enable/disable signaling by sending "tlv" iovar. if that fails,
+ fallback to no flow control? Print a message for now.
+ */
+
+ /* enable proptxtstatus signaling by default */
+ bcm_mkiovar("tlv", (char *)&tlv, 4, iovbuf, sizeof(iovbuf));
+ if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) {
+ AP6210_ERR("dhd_wlfc_init(): failed to enable/disable bdcv2 tlv signaling\n");
+ }
+ else {
+ /*
+ Leaving the message for now, it should be removed after a while; once
+ the tlv situation is stable.
+ */
+ AP6210_ERR("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n",
+ dhd->wlfc_enabled?"enabled":"disabled", tlv);
+ }
+ return BCME_OK;
+}
+
+int
+dhd_wlfc_enable(dhd_pub_t *dhd)
+{
+ int i;
+ athost_wl_status_info_t* wlfc;
+
+ if (!dhd->wlfc_enabled || dhd->wlfc_state)
+ return BCME_OK;
+
+ /* allocate space to track txstatus propagated from firmware */
+ dhd->wlfc_state = MALLOC(dhd->osh, sizeof(athost_wl_status_info_t));
+ if (dhd->wlfc_state == NULL)
+ return BCME_NOMEM;
+
+ /* initialize state space */
+ wlfc = (athost_wl_status_info_t*)dhd->wlfc_state;
+ memset(wlfc, 0, sizeof(athost_wl_status_info_t));
+
+ /* remember osh & dhdp */
+ wlfc->osh = dhd->osh;
+ wlfc->dhdp = dhd;
+
+ wlfc->hanger =
+ dhd_wlfc_hanger_create(dhd->osh, WLFC_HANGER_MAXITEMS);
+ if (wlfc->hanger == NULL) {
+ MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t));
+ dhd->wlfc_state = NULL;
+ AP6210_ERR("Failed to malloc dhd->wlfc_state\n");
+ return BCME_NOMEM;
+ }
+
+ /* initialize all interfaces to accept traffic */
+ for (i = 0; i < WLFC_MAX_IFNUM; i++) {
+ wlfc->hostif_flow_state[i] = OFF;
+ }
+
+ wlfc->destination_entries.other.state = WLFC_STATE_OPEN;
+ /* bc/mc FIFO is always open [credit aside], i.e. b[5] */
+ wlfc->destination_entries.other.ac_bitmap = 0x1f;
+ wlfc->destination_entries.other.interface_id = 0;
+
+ wlfc->proptxstatus_mode = WLFC_FCMODE_EXPLICIT_CREDIT;
+
+ wlfc->allow_credit_borrow = TRUE;
+ wlfc->borrow_defer_timestamp = 0;
+
+ return BCME_OK;
+}
+
+/* release all packet resources */
+void
+dhd_wlfc_cleanup(dhd_pub_t *dhd, ifpkt_cb_t fn, int arg)
+{
+ int i;
+ int total_entries;
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+ wlfc_mac_descriptor_t* table;
+ wlfc_hanger_t* h;
+ int prec;
+ void *pkt = NULL;
+ struct pktq *txq = NULL;
+ if (dhd->wlfc_state == NULL)
+ return;
+ /* flush bus->txq */
+ txq = dhd_bus_txq(dhd->bus);
+ /* any in the hanger? */
+ h = (wlfc_hanger_t*)wlfc->hanger;
+ total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t);
+ /* search all entries, include nodes as well as interfaces */
+ table = (wlfc_mac_descriptor_t*)&wlfc->destination_entries;
+
+ for (i = 0; i < total_entries; i++) {
+ if (table[i].occupied && (fn == NULL || (arg == table[i].interface_id))) {
+ if (table[i].psq.len) {
+ AP6210_DEBUG("%s(): DELAYQ[%d].len = %d\n",
+ __FUNCTION__, i, table[i].psq.len);
+ /* release packets held in DELAYQ */
+ pktq_flush(wlfc->osh, &table[i].psq, TRUE, fn, arg);
+ }
+ if (fn == NULL)
+ table[i].occupied = 0;
+ }
+ }
+ for (prec = 0; prec < txq->num_prec; prec++) {
+ pkt = pktq_pdeq_with_fn(txq, prec, fn, arg);
+ while (pkt) {
+ for (i = 0; i < h->max_items; i++) {
+ if (pkt == h->items[i].pkt) {
+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ PKTFREE(wlfc->osh, h->items[i].pkt, TRUE);
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ } else if (h->items[i].state ==
+ WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) {
+ /* These are already freed from the psq */
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ }
+ break;
+ }
+ }
+ pkt = pktq_pdeq(txq, prec);
+ }
+ }
+ /* flush remained pkt in hanger queue, not in bus->txq */
+ for (i = 0; i < h->max_items; i++) {
+ if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE) {
+ if (fn == NULL || (*fn)(h->items[i].pkt, arg)) {
+ PKTFREE(wlfc->osh, h->items[i].pkt, TRUE);
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ }
+ } else if (h->items[i].state == WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED) {
+ if (fn == NULL || (*fn)(h->items[i].pkt, arg)) {
+ /* These are freed from the psq so no need to free again */
+ h->items[i].state = WLFC_HANGER_ITEM_STATE_FREE;
+ }
+ }
+ }
+ return;
+}
+
+void
+dhd_wlfc_deinit(dhd_pub_t *dhd)
+{
+ /* cleanup all psq related resources */
+ athost_wl_status_info_t* wlfc = (athost_wl_status_info_t*)
+ dhd->wlfc_state;
+
+ dhd_os_wlfc_block(dhd);
+ if (dhd->wlfc_state == NULL) {
+ dhd_os_wlfc_unblock(dhd);
+ return;
+ }
+
+#ifdef PROP_TXSTATUS_DEBUG
+ {
+ int i;
+ wlfc_hanger_t* h = (wlfc_hanger_t*)wlfc->hanger;
+ for (i = 0; i < h->max_items; i++) {
+ if (h->items[i].state != WLFC_HANGER_ITEM_STATE_FREE) {
+ AP6210_DEBUG("%s() pkt[%d] = 0x%p, FIFO_credit_used:%d\n",
+ __FUNCTION__, i, h->items[i].pkt,
+ DHD_PKTTAG_CREDITCHECK(PKTTAG(h->items[i].pkt)));
+ }
+ }
+ }
+#endif
+ /* delete hanger */
+ dhd_wlfc_hanger_delete(dhd->osh, wlfc->hanger);
+
+ /* free top structure */
+ MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t));
+ dhd->wlfc_state = NULL;
+ dhd_os_wlfc_unblock(dhd);
+
+ return;
+}
+#endif /* PROP_TXSTATUS */
diff --git a/drivers/net/wireless/ap6210/dhd_wlfc.h b/drivers/net/wireless/ap6210/dhd_wlfc.h
new file mode 100644
index 0000000..42b350c
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dhd_wlfc.h
@@ -0,0 +1,288 @@
+/*
+* Copyright (C) 1999-2012, Broadcom Corporation
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2 (the "GPL"),
+* available at http://www.broadcom.com/licenses/GPLv2.php, with the
+* following added to such license:
+*
+* As a special exception, the copyright holders of this software give you
+* permission to link this software with independent modules, and to copy and
+* distribute the resulting executable under terms of your choice, provided that
+* you also meet, for each linked independent module, the terms and conditions of
+* the license of that module. An independent module is a module which is not
+* derived from this software. The special exception does not apply to any
+* modifications of the software.
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a license
+* other than the GPL, without Broadcom's express prior written consent.
+* $Id: dhd_wlfc.h 361006 2012-10-05 07:45:51Z $
+*
+*/
+#ifndef __wlfc_host_driver_definitions_h__
+#define __wlfc_host_driver_definitions_h__
+
+/* 16 bits will provide an absolute max of 65536 slots */
+#define WLFC_HANGER_MAXITEMS 1024
+
+#define WLFC_HANGER_ITEM_STATE_FREE 1
+#define WLFC_HANGER_ITEM_STATE_INUSE 2
+#define WLFC_HANGER_ITEM_STATE_INUSE_SUPPRESSED 3
+#define WLFC_PKTID_HSLOT_MASK 0xffff /* allow 16 bits only */
+#define WLFC_PKTID_HSLOT_SHIFT 8
+
+/* x -> TXSTATUS TAG to/from firmware */
+#define WLFC_PKTID_HSLOT_GET(x) \
+ (((x) >> WLFC_PKTID_HSLOT_SHIFT) & WLFC_PKTID_HSLOT_MASK)
+#define WLFC_PKTID_HSLOT_SET(var, slot) \
+ ((var) = ((var) & ~(WLFC_PKTID_HSLOT_MASK << WLFC_PKTID_HSLOT_SHIFT)) | \
+ (((slot) & WLFC_PKTID_HSLOT_MASK) << WLFC_PKTID_HSLOT_SHIFT))
+
+#define WLFC_PKTID_FREERUNCTR_MASK 0xff
+
+#define WLFC_PKTID_FREERUNCTR_GET(x) ((x) & WLFC_PKTID_FREERUNCTR_MASK)
+#define WLFC_PKTID_FREERUNCTR_SET(var, ctr) \
+ ((var) = (((var) & ~WLFC_PKTID_FREERUNCTR_MASK) | \
+ (((ctr) & WLFC_PKTID_FREERUNCTR_MASK))))
+
+#define WLFC_PKTQ_PENQ(pq, prec, p) ((pktq_full((pq)) || pktq_pfull((pq), (prec)))? \
+ NULL : pktq_penq((pq), (prec), (p)))
+#define WLFC_PKTQ_PENQ_HEAD(pq, prec, p) ((pktq_full((pq)) || pktq_pfull((pq), (prec))) ? \
+ NULL : pktq_penq_head((pq), (prec), (p)))
+
+typedef enum ewlfc_packet_state {
+ eWLFC_PKTTYPE_NEW,
+ eWLFC_PKTTYPE_DELAYED,
+ eWLFC_PKTTYPE_SUPPRESSED,
+ eWLFC_PKTTYPE_MAX
+} ewlfc_packet_state_t;
+
+typedef enum ewlfc_mac_entry_action {
+ eWLFC_MAC_ENTRY_ACTION_ADD,
+ eWLFC_MAC_ENTRY_ACTION_DEL,
+ eWLFC_MAC_ENTRY_ACTION_UPDATE,
+ eWLFC_MAC_ENTRY_ACTION_MAX
+} ewlfc_mac_entry_action_t;
+
+typedef struct wlfc_hanger_item {
+ uint8 state;
+ uint8 gen;
+ uint8 pad[2];
+ uint32 identifier;
+ void* pkt;
+#ifdef PROP_TXSTATUS_DEBUG
+ uint32 push_time;
+#endif
+} wlfc_hanger_item_t;
+
+typedef struct wlfc_hanger {
+ int max_items;
+ uint32 pushed;
+ uint32 popped;
+ uint32 failed_to_push;
+ uint32 failed_to_pop;
+ uint32 failed_slotfind;
+ wlfc_hanger_item_t items[1];
+ uint32 slot_pos;
+} wlfc_hanger_t;
+
+#define WLFC_HANGER_SIZE(n) ((sizeof(wlfc_hanger_t) - \
+ sizeof(wlfc_hanger_item_t)) + ((n)*sizeof(wlfc_hanger_item_t)))
+
+#define WLFC_STATE_OPEN 1
+#define WLFC_STATE_CLOSE 2
+
+#define WLFC_PSQ_PREC_COUNT ((AC_COUNT + 1) * 2) /* 2 for each AC traffic and bc/mc */
+
+#define WLFC_PSQ_LEN 2048
+
+#define WLFC_SENDQ_LEN 256
+
+
+#define WLFC_FLOWCONTROL_HIWATER (2048 - 256)
+#define WLFC_FLOWCONTROL_LOWATER 256
+
+
+typedef struct wlfc_mac_descriptor {
+ uint8 occupied;
+ uint8 interface_id;
+ uint8 iftype;
+ uint8 state;
+ uint8 ac_bitmap; /* for APSD */
+ uint8 requested_credit;
+ uint8 requested_packet;
+ uint8 ea[ETHER_ADDR_LEN];
+ /*
+ maintain (MAC,AC) based seq count for
+ packets going to the device. As well as bc/mc.
+ */
+ uint8 seq[AC_COUNT + 1];
+ uint8 generation;
+ struct pktq psq;
+ /* The AC pending bitmap that was reported to the fw at last change */
+ uint8 traffic_lastreported_bmp;
+ /* The new AC pending bitmap */
+ uint8 traffic_pending_bmp;
+ /* 1= send on next opportunity */
+ uint8 send_tim_signal;
+ uint8 mac_handle;
+ uint transit_count;
+ uint suppr_transit_count;
+ uint suppress_count;
+ uint8 suppressed;
+
+#ifdef PROP_TXSTATUS_DEBUG
+ uint32 dstncredit_sent_packets;
+ uint32 dstncredit_acks;
+ uint32 opened_ct;
+ uint32 closed_ct;
+#endif
+} wlfc_mac_descriptor_t;
+
+#define WLFC_DECR_SEQCOUNT(entry, prec) do { if (entry->seq[(prec)] == 0) {\
+ entry->seq[prec] = 0xff; } else entry->seq[prec]--;} while (0)
+
+#define WLFC_INCR_SEQCOUNT(entry, prec) entry->seq[(prec)]++
+#define WLFC_SEQCOUNT(entry, prec) entry->seq[(prec)]
+
+typedef struct athost_wl_stat_counters {
+ uint32 pktin;
+ uint32 pkt2bus;
+ uint32 pktdropped;
+ uint32 tlv_parse_failed;
+ uint32 rollback;
+ uint32 rollback_failed;
+ uint32 sendq_full_error;
+ uint32 delayq_full_error;
+ uint32 credit_request_failed;
+ uint32 packet_request_failed;
+ uint32 mac_update_failed;
+ uint32 psmode_update_failed;
+ uint32 interface_update_failed;
+ uint32 wlfc_header_only_pkt;
+ uint32 txstatus_in;
+ uint32 d11_suppress;
+ uint32 wl_suppress;
+ uint32 bad_suppress;
+ uint32 pkt_freed;
+ uint32 pkt_free_err;
+ uint32 psq_wlsup_retx;
+ uint32 psq_wlsup_enq;
+ uint32 psq_d11sup_retx;
+ uint32 psq_d11sup_enq;
+ uint32 psq_hostq_retx;
+ uint32 psq_hostq_enq;
+ uint32 mac_handle_notfound;
+ uint32 wlc_tossed_pkts;
+ uint32 dhd_hdrpulls;
+ uint32 generic_error;
+ /* an extra one for bc/mc traffic */
+ uint32 sendq_pkts[AC_COUNT + 1];
+#ifdef PROP_TXSTATUS_DEBUG
+ /* all pkt2bus -> txstatus latency accumulated */
+ uint32 latency_sample_count;
+ uint32 total_status_latency;
+ uint32 latency_most_recent;
+ int idx_delta;
+ uint32 deltas[10];
+ uint32 fifo_credits_sent[6];
+ uint32 fifo_credits_back[6];
+ uint32 dropped_qfull[6];
+ uint32 signal_only_pkts_sent;
+ uint32 signal_only_pkts_freed;
+#endif
+} athost_wl_stat_counters_t;
+
+#ifdef PROP_TXSTATUS_DEBUG
+#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do { \
+ (ctx)->stats.fifo_credits_sent[(ac)]++;} while (0)
+#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do { \
+ (ctx)->stats.fifo_credits_back[(ac)]++;} while (0)
+#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do { \
+ (ctx)->stats.dropped_qfull[(ac)]++;} while (0)
+#else
+#define WLFC_HOST_FIFO_CREDIT_INC_SENTCTRS(ctx, ac) do {} while (0)
+#define WLFC_HOST_FIFO_CREDIT_INC_BACKCTRS(ctx, ac) do {} while (0)
+#define WLFC_HOST_FIFO_DROPPEDCTR_INC(ctx, ac) do {} while (0)
+#endif
+
+#define WLFC_FCMODE_NONE 0
+#define WLFC_FCMODE_IMPLIED_CREDIT 1
+#define WLFC_FCMODE_EXPLICIT_CREDIT 2
+
+/* How long to defer borrowing in milliseconds */
+#define WLFC_BORROW_DEFER_PERIOD_MS 100
+
+/* Mask to represent available ACs (note: BC/MC is ignored */
+#define WLFC_AC_MASK 0xF
+
+/* Mask to check for only on-going AC_BE traffic */
+#define WLFC_AC_BE_TRAFFIC_ONLY 0xD
+
+typedef struct athost_wl_status_info {
+ uint8 last_seqid_to_wlc;
+
+ /* OSL handle */
+ osl_t* osh;
+ /* dhd pub */
+ void* dhdp;
+
+ /* stats */
+ athost_wl_stat_counters_t stats;
+
+ /* the additional ones are for bc/mc and ATIM FIFO */
+ int FIFO_credit[AC_COUNT + 2];
+
+ /* Credit borrow counts for each FIFO from each of the other FIFOs */
+ int credits_borrowed[AC_COUNT + 2][AC_COUNT + 2];
+
+ struct pktq SENDQ;
+
+ /* packet hanger and MAC->handle lookup table */
+ void* hanger;
+ struct {
+ /* table for individual nodes */
+ wlfc_mac_descriptor_t nodes[WLFC_MAC_DESC_TABLE_SIZE];
+ /* table for interfaces */
+ wlfc_mac_descriptor_t interfaces[WLFC_MAX_IFNUM];
+ /* OS may send packets to unknown (unassociated) destinations */
+ /* A place holder for bc/mc and packets to unknown destinations */
+ wlfc_mac_descriptor_t other;
+ } destination_entries;
+ /* token position for different priority packets */
+ uint8 token_pos[AC_COUNT+1];
+ /* ON/OFF state for flow control to the host network interface */
+ uint8 hostif_flow_state[WLFC_MAX_IFNUM];
+ uint8 host_ifidx;
+ /* to flow control an OS interface */
+ uint8 toggle_host_if;
+
+ /*
+ Mode in which the dhd flow control shall operate. Must be set before
+ traffic starts to the device.
+ 0 - Do not do any proptxtstatus flow control
+ 1 - Use implied credit from a packet status
+ 2 - Use explicit credit
+ */
+ uint8 proptxstatus_mode;
+
+ /* To borrow credits */
+ uint8 allow_credit_borrow;
+
+ /* Timestamp to compute how long to defer borrowing for */
+ uint32 borrow_defer_timestamp;
+
+ bool wlfc_locked;
+} athost_wl_status_info_t;
+
+int dhd_wlfc_enable(dhd_pub_t *dhd);
+int dhd_wlfc_interface_event(struct dhd_info *,
+ ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea);
+int dhd_wlfc_FIFOcreditmap_event(struct dhd_info *dhd, uint8* event_data);
+int dhd_wlfc_event(struct dhd_info *dhd);
+int dhd_os_wlfc_block(dhd_pub_t *pub);
+int dhd_os_wlfc_unblock(dhd_pub_t *pub);
+
+#endif /* __wlfc_host_driver_definitions_h__ */
diff --git a/drivers/net/wireless/ap6210/dngl_stats.h b/drivers/net/wireless/ap6210/dngl_stats.h
new file mode 100644
index 0000000..5e5a2e2
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dngl_stats.h
@@ -0,0 +1,43 @@
+/*
+ * Common stats definitions for clients of dongle
+ * ports
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dngl_stats.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _dngl_stats_h_
+#define _dngl_stats_h_
+
+typedef struct {
+ unsigned long rx_packets; /* total packets received */
+ unsigned long tx_packets; /* total packets transmitted */
+ unsigned long rx_bytes; /* total bytes received */
+ unsigned long tx_bytes; /* total bytes transmitted */
+ unsigned long rx_errors; /* bad packets received */
+ unsigned long tx_errors; /* packet transmit problems */
+ unsigned long rx_dropped; /* packets dropped by dongle */
+ unsigned long tx_dropped; /* packets dropped by dongle */
+ unsigned long multicast; /* multicast packets received */
+} dngl_stats_t;
+
+#endif /* _dngl_stats_h_ */
diff --git a/drivers/net/wireless/ap6210/dngl_wlhdr.h b/drivers/net/wireless/ap6210/dngl_wlhdr.h
new file mode 100644
index 0000000..0e37df6
--- /dev/null
+++ b/drivers/net/wireless/ap6210/dngl_wlhdr.h
@@ -0,0 +1,40 @@
+/*
+ * Dongle WL Header definitions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dngl_wlhdr.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _dngl_wlhdr_h_
+#define _dngl_wlhdr_h_
+
+typedef struct wl_header {
+ uint8 type; /* Header type */
+ uint8 version; /* Header version */
+ int8 rssi; /* RSSI */
+ uint8 pad; /* Unused */
+} wl_header_t;
+
+#define WL_HEADER_LEN sizeof(wl_header_t)
+#define WL_HEADER_TYPE 0
+#define WL_HEADER_VER 1
+#endif /* _dngl_wlhdr_h_ */
diff --git a/drivers/net/wireless/ap6210/hndpmu.c b/drivers/net/wireless/ap6210/hndpmu.c
new file mode 100644
index 0000000..e639015
--- /dev/null
+++ b/drivers/net/wireless/ap6210/hndpmu.c
@@ -0,0 +1,208 @@
+/*
+ * Misc utility routines for accessing PMU corerev specific features
+ * of the SiliconBackplane-based Broadcom chips.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: hndpmu.c 354194 2012-08-30 08:39:03Z $
+ */
+
+#include <bcm_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <hndpmu.h>
+
+#define PMU_ERROR(args)
+
+#define PMU_MSG(args)
+
+/* To check in verbose debugging messages not intended
+ * to be on except on private builds.
+ */
+#define PMU_NONE(args)
+
+
+/* SDIO Pad drive strength to select value mappings.
+ * The last strength value in each table must be 0 (the tri-state value).
+ */
+typedef struct {
+ uint8 strength; /* Pad Drive Strength in mA */
+ uint8 sel; /* Chip-specific select value */
+} sdiod_drive_str_t;
+
+/* SDIO Drive Strength to sel value table for PMU Rev 1 */
+static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = {
+ {4, 0x2},
+ {2, 0x3},
+ {1, 0x0},
+ {0, 0x0} };
+
+/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
+static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = {
+ {12, 0x7},
+ {10, 0x6},
+ {8, 0x5},
+ {6, 0x4},
+ {4, 0x2},
+ {2, 0x1},
+ {0, 0x0} };
+
+/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
+static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = {
+ {32, 0x7},
+ {26, 0x6},
+ {22, 0x5},
+ {16, 0x4},
+ {12, 0x3},
+ {8, 0x2},
+ {4, 0x1},
+ {0, 0x0} };
+
+/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8v) */
+static const sdiod_drive_str_t sdiod_drive_strength_tab4_1v8[] = {
+ {32, 0x6},
+ {26, 0x7},
+ {22, 0x4},
+ {16, 0x5},
+ {12, 0x2},
+ {8, 0x3},
+ {4, 0x0},
+ {0, 0x1} };
+
+/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.2v) */
+
+/* SDIO Drive Strength to sel value table for PMU Rev 11 (2.5v) */
+
+/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
+static const sdiod_drive_str_t sdiod_drive_strength_tab5_1v8[] = {
+ {6, 0x7},
+ {5, 0x6},
+ {4, 0x5},
+ {3, 0x4},
+ {2, 0x2},
+ {1, 0x1},
+ {0, 0x0} };
+
+/* SDIO Drive Strength to sel value table for PMU Rev 13 (3.3v) */
+
+/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
+static const sdiod_drive_str_t sdiod_drive_strength_tab6_1v8[] = {
+ {3, 0x3},
+ {2, 0x2},
+ {1, 0x1},
+ {0, 0x0} };
+
+#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
+
+void
+si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength)
+{
+ chipcregs_t *cc;
+ uint origidx, intr_val = 0;
+ sdiod_drive_str_t *str_tab = NULL;
+ uint32 str_mask = 0;
+ uint32 str_shift = 0;
+
+ if (!(sih->cccaps & CC_CAP_PMU)) {
+ return;
+ }
+
+ /* Remember original core before switch to chipc */
+ cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
+
+ switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) {
+ case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1;
+ str_mask = 0x30000000;
+ str_shift = 28;
+ break;
+ case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
+ case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
+ case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID, 4):
+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2;
+ str_mask = 0x00003800;
+ str_shift = 11;
+ break;
+ case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
+ case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 11):
+ if (sih->pmurev == 8) {
+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab3;
+ }
+ else if (sih->pmurev == 11) {
+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8;
+ }
+ str_mask = 0x00003800;
+ str_shift = 11;
+ break;
+ case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8;
+ str_mask = 0x00003800;
+ str_shift = 11;
+ break;
+ case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab5_1v8;
+ str_mask = 0x00003800;
+ str_shift = 11;
+ break;
+ case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
+ str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab6_1v8;
+ str_mask = 0x00001800;
+ str_shift = 11;
+ break;
+ default:
+ PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
+ bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev));
+
+ break;
+ }
+
+ if (str_tab != NULL && cc != NULL) {
+ uint32 cc_data_temp;
+ int i;
+
+ /* Pick the lowest available drive strength equal or greater than the
+ * requested strength. Drive strength of 0 requests tri-state.
+ */
+ for (i = 0; drivestrength < str_tab[i].strength; i++)
+ ;
+
+ if (i > 0 && drivestrength > str_tab[i].strength)
+ i--;
+
+ W_REG(osh, &cc->chipcontrol_addr, 1);
+ cc_data_temp = R_REG(osh, &cc->chipcontrol_data);
+ cc_data_temp &= ~str_mask;
+ cc_data_temp |= str_tab[i].sel << str_shift;
+ W_REG(osh, &cc->chipcontrol_data, cc_data_temp);
+
+ PMU_MSG(("SDIO: %dmA drive strength requested; set to %dmA\n",
+ drivestrength, str_tab[i].strength));
+ }
+
+ /* Return to original core */
+ si_restore_core(sih, origidx, intr_val);
+}
diff --git a/drivers/net/wireless/ap6210/include/Makefile b/drivers/net/wireless/ap6210/include/Makefile
new file mode 100644
index 0000000..8483b54
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/Makefile
@@ -0,0 +1,54 @@
+#!/bin/bash
+#
+# This script serves following purpose:
+#
+# 1. It generates native version information by querying
+# automerger maintained database to see where src/include
+# came from
+# 2. For select components, as listed in compvers.sh
+# it generates component version files
+#
+# Copyright 2005, Broadcom, Inc.
+#
+# $Id: Makefile 241686 2011-02-19 00:22:45Z prakashd $
+#
+
+SRCBASE := ..
+
+TARGETS := epivers.h
+
+ifdef VERBOSE
+export VERBOSE
+endif
+
+all release: epivers compvers
+
+# Generate epivers.h for native branch version
+epivers:
+ bash epivers.sh
+
+# Generate epivers.h for native branch version
+compvers:
+ @if [ -s "compvers.sh" ]; then \
+ echo "Generating component versions, if any"; \
+ bash compvers.sh; \
+ else \
+ echo "Skipping component version generation"; \
+ fi
+
+# Generate epivers.h for native branch version
+clean_compvers:
+ @if [ -s "compvers.sh" ]; then \
+ echo "bash compvers.sh clean"; \
+ bash compvers.sh clean; \
+ else \
+ echo "Skipping component version clean"; \
+ fi
+
+clean:
+ rm -f $(TARGETS) *.prev
+
+clean_all: clean clean_compvers
+
+.PHONY: all release clean epivers compvers clean_compvers
+
diff --git a/drivers/net/wireless/ap6210/include/aidmp.h b/drivers/net/wireless/ap6210/include/aidmp.h
new file mode 100644
index 0000000..d557079
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/aidmp.h
@@ -0,0 +1,375 @@
+/*
+ * Broadcom AMBA Interconnect definitions.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: aidmp.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _AIDMP_H
+#define _AIDMP_H
+
+/* Manufacturer Ids */
+#define MFGID_ARM 0x43b
+#define MFGID_BRCM 0x4bf
+#define MFGID_MIPS 0x4a7
+
+/* Component Classes */
+#define CC_SIM 0
+#define CC_EROM 1
+#define CC_CORESIGHT 9
+#define CC_VERIF 0xb
+#define CC_OPTIMO 0xd
+#define CC_GEN 0xe
+#define CC_PRIMECELL 0xf
+
+/* Enumeration ROM registers */
+#define ER_EROMENTRY 0x000
+#define ER_REMAPCONTROL 0xe00
+#define ER_REMAPSELECT 0xe04
+#define ER_MASTERSELECT 0xe10
+#define ER_ITCR 0xf00
+#define ER_ITIP 0xf04
+
+/* Erom entries */
+#define ER_TAG 0xe
+#define ER_TAG1 0x6
+#define ER_VALID 1
+#define ER_CI 0
+#define ER_MP 2
+#define ER_ADD 4
+#define ER_END 0xe
+#define ER_BAD 0xffffffff
+
+/* EROM CompIdentA */
+#define CIA_MFG_MASK 0xfff00000
+#define CIA_MFG_SHIFT 20
+#define CIA_CID_MASK 0x000fff00
+#define CIA_CID_SHIFT 8
+#define CIA_CCL_MASK 0x000000f0
+#define CIA_CCL_SHIFT 4
+
+/* EROM CompIdentB */
+#define CIB_REV_MASK 0xff000000
+#define CIB_REV_SHIFT 24
+#define CIB_NSW_MASK 0x00f80000
+#define CIB_NSW_SHIFT 19
+#define CIB_NMW_MASK 0x0007c000
+#define CIB_NMW_SHIFT 14
+#define CIB_NSP_MASK 0x00003e00
+#define CIB_NSP_SHIFT 9
+#define CIB_NMP_MASK 0x000001f0
+#define CIB_NMP_SHIFT 4
+
+/* EROM MasterPortDesc */
+#define MPD_MUI_MASK 0x0000ff00
+#define MPD_MUI_SHIFT 8
+#define MPD_MP_MASK 0x000000f0
+#define MPD_MP_SHIFT 4
+
+/* EROM AddrDesc */
+#define AD_ADDR_MASK 0xfffff000
+#define AD_SP_MASK 0x00000f00
+#define AD_SP_SHIFT 8
+#define AD_ST_MASK 0x000000c0
+#define AD_ST_SHIFT 6
+#define AD_ST_SLAVE 0x00000000
+#define AD_ST_BRIDGE 0x00000040
+#define AD_ST_SWRAP 0x00000080
+#define AD_ST_MWRAP 0x000000c0
+#define AD_SZ_MASK 0x00000030
+#define AD_SZ_SHIFT 4
+#define AD_SZ_4K 0x00000000
+#define AD_SZ_8K 0x00000010
+#define AD_SZ_16K 0x00000020
+#define AD_SZ_SZD 0x00000030
+#define AD_AG32 0x00000008
+#define AD_ADDR_ALIGN 0x00000fff
+#define AD_SZ_BASE 0x00001000 /* 4KB */
+
+/* EROM SizeDesc */
+#define SD_SZ_MASK 0xfffff000
+#define SD_SG32 0x00000008
+#define SD_SZ_ALIGN 0x00000fff
+
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+typedef volatile struct _aidmp {
+ uint32 oobselina30; /* 0x000 */
+ uint32 oobselina74; /* 0x004 */
+ uint32 PAD[6];
+ uint32 oobselinb30; /* 0x020 */
+ uint32 oobselinb74; /* 0x024 */
+ uint32 PAD[6];
+ uint32 oobselinc30; /* 0x040 */
+ uint32 oobselinc74; /* 0x044 */
+ uint32 PAD[6];
+ uint32 oobselind30; /* 0x060 */
+ uint32 oobselind74; /* 0x064 */
+ uint32 PAD[38];
+ uint32 oobselouta30; /* 0x100 */
+ uint32 oobselouta74; /* 0x104 */
+ uint32 PAD[6];
+ uint32 oobseloutb30; /* 0x120 */
+ uint32 oobseloutb74; /* 0x124 */
+ uint32 PAD[6];
+ uint32 oobseloutc30; /* 0x140 */
+ uint32 oobseloutc74; /* 0x144 */
+ uint32 PAD[6];
+ uint32 oobseloutd30; /* 0x160 */
+ uint32 oobseloutd74; /* 0x164 */
+ uint32 PAD[38];
+ uint32 oobsynca; /* 0x200 */
+ uint32 oobseloutaen; /* 0x204 */
+ uint32 PAD[6];
+ uint32 oobsyncb; /* 0x220 */
+ uint32 oobseloutben; /* 0x224 */
+ uint32 PAD[6];
+ uint32 oobsyncc; /* 0x240 */
+ uint32 oobseloutcen; /* 0x244 */
+ uint32 PAD[6];
+ uint32 oobsyncd; /* 0x260 */
+ uint32 oobseloutden; /* 0x264 */
+ uint32 PAD[38];
+ uint32 oobaextwidth; /* 0x300 */
+ uint32 oobainwidth; /* 0x304 */
+ uint32 oobaoutwidth; /* 0x308 */
+ uint32 PAD[5];
+ uint32 oobbextwidth; /* 0x320 */
+ uint32 oobbinwidth; /* 0x324 */
+ uint32 oobboutwidth; /* 0x328 */
+ uint32 PAD[5];
+ uint32 oobcextwidth; /* 0x340 */
+ uint32 oobcinwidth; /* 0x344 */
+ uint32 oobcoutwidth; /* 0x348 */
+ uint32 PAD[5];
+ uint32 oobdextwidth; /* 0x360 */
+ uint32 oobdinwidth; /* 0x364 */
+ uint32 oobdoutwidth; /* 0x368 */
+ uint32 PAD[37];
+ uint32 ioctrlset; /* 0x400 */
+ uint32 ioctrlclear; /* 0x404 */
+ uint32 ioctrl; /* 0x408 */
+ uint32 PAD[61];
+ uint32 iostatus; /* 0x500 */
+ uint32 PAD[127];
+ uint32 ioctrlwidth; /* 0x700 */
+ uint32 iostatuswidth; /* 0x704 */
+ uint32 PAD[62];
+ uint32 resetctrl; /* 0x800 */
+ uint32 resetstatus; /* 0x804 */
+ uint32 resetreadid; /* 0x808 */
+ uint32 resetwriteid; /* 0x80c */
+ uint32 PAD[60];
+ uint32 errlogctrl; /* 0x900 */
+ uint32 errlogdone; /* 0x904 */
+ uint32 errlogstatus; /* 0x908 */
+ uint32 errlogaddrlo; /* 0x90c */
+ uint32 errlogaddrhi; /* 0x910 */
+ uint32 errlogid; /* 0x914 */
+ uint32 errloguser; /* 0x918 */
+ uint32 errlogflags; /* 0x91c */
+ uint32 PAD[56];
+ uint32 intstatus; /* 0xa00 */
+ uint32 PAD[255];
+ uint32 config; /* 0xe00 */
+ uint32 PAD[63];
+ uint32 itcr; /* 0xf00 */
+ uint32 PAD[3];
+ uint32 itipooba; /* 0xf10 */
+ uint32 itipoobb; /* 0xf14 */
+ uint32 itipoobc; /* 0xf18 */
+ uint32 itipoobd; /* 0xf1c */
+ uint32 PAD[4];
+ uint32 itipoobaout; /* 0xf30 */
+ uint32 itipoobbout; /* 0xf34 */
+ uint32 itipoobcout; /* 0xf38 */
+ uint32 itipoobdout; /* 0xf3c */
+ uint32 PAD[4];
+ uint32 itopooba; /* 0xf50 */
+ uint32 itopoobb; /* 0xf54 */
+ uint32 itopoobc; /* 0xf58 */
+ uint32 itopoobd; /* 0xf5c */
+ uint32 PAD[4];
+ uint32 itopoobain; /* 0xf70 */
+ uint32 itopoobbin; /* 0xf74 */
+ uint32 itopoobcin; /* 0xf78 */
+ uint32 itopoobdin; /* 0xf7c */
+ uint32 PAD[4];
+ uint32 itopreset; /* 0xf90 */
+ uint32 PAD[15];
+ uint32 peripherialid4; /* 0xfd0 */
+ uint32 peripherialid5; /* 0xfd4 */
+ uint32 peripherialid6; /* 0xfd8 */
+ uint32 peripherialid7; /* 0xfdc */
+ uint32 peripherialid0; /* 0xfe0 */
+ uint32 peripherialid1; /* 0xfe4 */
+ uint32 peripherialid2; /* 0xfe8 */
+ uint32 peripherialid3; /* 0xfec */
+ uint32 componentid0; /* 0xff0 */
+ uint32 componentid1; /* 0xff4 */
+ uint32 componentid2; /* 0xff8 */
+ uint32 componentid3; /* 0xffc */
+} aidmp_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* Out-of-band Router registers */
+#define OOB_BUSCONFIG 0x020
+#define OOB_STATUSA 0x100
+#define OOB_STATUSB 0x104
+#define OOB_STATUSC 0x108
+#define OOB_STATUSD 0x10c
+#define OOB_ENABLEA0 0x200
+#define OOB_ENABLEA1 0x204
+#define OOB_ENABLEA2 0x208
+#define OOB_ENABLEA3 0x20c
+#define OOB_ENABLEB0 0x280
+#define OOB_ENABLEB1 0x284
+#define OOB_ENABLEB2 0x288
+#define OOB_ENABLEB3 0x28c
+#define OOB_ENABLEC0 0x300
+#define OOB_ENABLEC1 0x304
+#define OOB_ENABLEC2 0x308
+#define OOB_ENABLEC3 0x30c
+#define OOB_ENABLED0 0x380
+#define OOB_ENABLED1 0x384
+#define OOB_ENABLED2 0x388
+#define OOB_ENABLED3 0x38c
+#define OOB_ITCR 0xf00
+#define OOB_ITIPOOBA 0xf10
+#define OOB_ITIPOOBB 0xf14
+#define OOB_ITIPOOBC 0xf18
+#define OOB_ITIPOOBD 0xf1c
+#define OOB_ITOPOOBA 0xf30
+#define OOB_ITOPOOBB 0xf34
+#define OOB_ITOPOOBC 0xf38
+#define OOB_ITOPOOBD 0xf3c
+
+/* DMP wrapper registers */
+#define AI_OOBSELINA30 0x000
+#define AI_OOBSELINA74 0x004
+#define AI_OOBSELINB30 0x020
+#define AI_OOBSELINB74 0x024
+#define AI_OOBSELINC30 0x040
+#define AI_OOBSELINC74 0x044
+#define AI_OOBSELIND30 0x060
+#define AI_OOBSELIND74 0x064
+#define AI_OOBSELOUTA30 0x100
+#define AI_OOBSELOUTA74 0x104
+#define AI_OOBSELOUTB30 0x120
+#define AI_OOBSELOUTB74 0x124
+#define AI_OOBSELOUTC30 0x140
+#define AI_OOBSELOUTC74 0x144
+#define AI_OOBSELOUTD30 0x160
+#define AI_OOBSELOUTD74 0x164
+#define AI_OOBSYNCA 0x200
+#define AI_OOBSELOUTAEN 0x204
+#define AI_OOBSYNCB 0x220
+#define AI_OOBSELOUTBEN 0x224
+#define AI_OOBSYNCC 0x240
+#define AI_OOBSELOUTCEN 0x244
+#define AI_OOBSYNCD 0x260
+#define AI_OOBSELOUTDEN 0x264
+#define AI_OOBAEXTWIDTH 0x300
+#define AI_OOBAINWIDTH 0x304
+#define AI_OOBAOUTWIDTH 0x308
+#define AI_OOBBEXTWIDTH 0x320
+#define AI_OOBBINWIDTH 0x324
+#define AI_OOBBOUTWIDTH 0x328
+#define AI_OOBCEXTWIDTH 0x340
+#define AI_OOBCINWIDTH 0x344
+#define AI_OOBCOUTWIDTH 0x348
+#define AI_OOBDEXTWIDTH 0x360
+#define AI_OOBDINWIDTH 0x364
+#define AI_OOBDOUTWIDTH 0x368
+
+
+#define AI_IOCTRLSET 0x400
+#define AI_IOCTRLCLEAR 0x404
+#define AI_IOCTRL 0x408
+#define AI_IOSTATUS 0x500
+#define AI_RESETCTRL 0x800
+#define AI_RESETSTATUS 0x804
+
+#define AI_IOCTRLWIDTH 0x700
+#define AI_IOSTATUSWIDTH 0x704
+
+#define AI_RESETREADID 0x808
+#define AI_RESETWRITEID 0x80c
+#define AI_ERRLOGCTRL 0xa00
+#define AI_ERRLOGDONE 0xa04
+#define AI_ERRLOGSTATUS 0xa08
+#define AI_ERRLOGADDRLO 0xa0c
+#define AI_ERRLOGADDRHI 0xa10
+#define AI_ERRLOGID 0xa14
+#define AI_ERRLOGUSER 0xa18
+#define AI_ERRLOGFLAGS 0xa1c
+#define AI_INTSTATUS 0xa00
+#define AI_CONFIG 0xe00
+#define AI_ITCR 0xf00
+#define AI_ITIPOOBA 0xf10
+#define AI_ITIPOOBB 0xf14
+#define AI_ITIPOOBC 0xf18
+#define AI_ITIPOOBD 0xf1c
+#define AI_ITIPOOBAOUT 0xf30
+#define AI_ITIPOOBBOUT 0xf34
+#define AI_ITIPOOBCOUT 0xf38
+#define AI_ITIPOOBDOUT 0xf3c
+#define AI_ITOPOOBA 0xf50
+#define AI_ITOPOOBB 0xf54
+#define AI_ITOPOOBC 0xf58
+#define AI_ITOPOOBD 0xf5c
+#define AI_ITOPOOBAIN 0xf70
+#define AI_ITOPOOBBIN 0xf74
+#define AI_ITOPOOBCIN 0xf78
+#define AI_ITOPOOBDIN 0xf7c
+#define AI_ITOPRESET 0xf90
+#define AI_PERIPHERIALID4 0xfd0
+#define AI_PERIPHERIALID5 0xfd4
+#define AI_PERIPHERIALID6 0xfd8
+#define AI_PERIPHERIALID7 0xfdc
+#define AI_PERIPHERIALID0 0xfe0
+#define AI_PERIPHERIALID1 0xfe4
+#define AI_PERIPHERIALID2 0xfe8
+#define AI_PERIPHERIALID3 0xfec
+#define AI_COMPONENTID0 0xff0
+#define AI_COMPONENTID1 0xff4
+#define AI_COMPONENTID2 0xff8
+#define AI_COMPONENTID3 0xffc
+
+/* resetctrl */
+#define AIRC_RESET 1
+
+/* config */
+#define AICFG_OOB 0x00000020
+#define AICFG_IOS 0x00000010
+#define AICFG_IOC 0x00000008
+#define AICFG_TO 0x00000004
+#define AICFG_ERRL 0x00000002
+#define AICFG_RST 0x00000001
+
+/* bit defines for AI_OOBSELOUTB74 reg */
+#define OOB_SEL_OUTEN_B_5 15
+#define OOB_SEL_OUTEN_B_6 23
+
+#endif /* _AIDMP_H */
diff --git a/drivers/net/wireless/ap6210/include/bcm_cfg.h b/drivers/net/wireless/ap6210/include/bcm_cfg.h
new file mode 100644
index 0000000..ecff4f4
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcm_cfg.h
@@ -0,0 +1,29 @@
+/*
+ * BCM common config options
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcm_cfg.h 294399 2011-11-07 03:31:22Z $
+ */
+
+#ifndef _bcm_cfg_h_
+#define _bcm_cfg_h_
+#endif /* _bcm_cfg_h_ */
diff --git a/drivers/net/wireless/ap6210/include/bcm_mpool_pub.h b/drivers/net/wireless/ap6210/include/bcm_mpool_pub.h
new file mode 100644
index 0000000..8fe3de7
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcm_mpool_pub.h
@@ -0,0 +1,361 @@
+/*
+ * Memory pools library, Public interface
+ *
+ * API Overview
+ *
+ * This package provides a memory allocation subsystem based on pools of
+ * homogenous objects.
+ *
+ * Instrumentation is available for reporting memory utilization both
+ * on a per-data-structure basis and system wide.
+ *
+ * There are two main types defined in this API.
+ *
+ * pool manager: A singleton object that acts as a factory for
+ * pool allocators. It also is used for global
+ * instrumentation, such as reporting all blocks
+ * in use across all data structures. The pool manager
+ * creates and provides individual memory pools
+ * upon request to application code.
+ *
+ * memory pool: An object for allocating homogenous memory blocks.
+ *
+ * Global identifiers in this module use the following prefixes:
+ * bcm_mpm_* Memory pool manager
+ * bcm_mp_* Memory pool
+ *
+ * There are two main types of memory pools:
+ *
+ * prealloc: The contiguous memory block of objects can either be supplied
+ * by the client or malloc'ed by the memory manager. The objects are
+ * allocated out of a block of memory and freed back to the block.
+ *
+ * heap: The memory pool allocator uses the heap (malloc/free) for memory.
+ * In this case, the pool allocator is just providing statistics
+ * and instrumentation on top of the heap, without modifying the heap
+ * allocation implementation.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id$
+ */
+
+#ifndef _BCM_MPOOL_PUB_H
+#define _BCM_MPOOL_PUB_H 1
+
+#include <typedefs.h> /* needed for uint16 */
+
+
+/*
+**************************************************************************
+*
+* Type definitions, handles
+*
+**************************************************************************
+*/
+
+/* Forward declaration of OSL handle. */
+struct osl_info;
+
+/* Forward declaration of string buffer. */
+struct bcmstrbuf;
+
+/*
+ * Opaque type definition for the pool manager handle. This object is used for global
+ * memory pool operations such as obtaining a new pool, deleting a pool, iterating and
+ * instrumentation/debugging.
+ */
+struct bcm_mpm_mgr;
+typedef struct bcm_mpm_mgr *bcm_mpm_mgr_h;
+
+/*
+ * Opaque type definition for an instance of a pool. This handle is used for allocating
+ * and freeing memory through the pool, as well as management/instrumentation on this
+ * specific pool.
+ */
+struct bcm_mp_pool;
+typedef struct bcm_mp_pool *bcm_mp_pool_h;
+
+
+/*
+ * To make instrumentation more readable, every memory
+ * pool must have a readable name. Pool names are up to
+ * 8 bytes including '\0' termination. (7 printable characters.)
+ */
+#define BCM_MP_NAMELEN 8
+
+
+/*
+ * Type definition for pool statistics.
+ */
+typedef struct bcm_mp_stats {
+ char name[BCM_MP_NAMELEN]; /* Name of this pool. */
+ unsigned int objsz; /* Object size allocated in this pool */
+ uint16 nobj; /* Total number of objects in this pool */
+ uint16 num_alloc; /* Number of objects currently allocated */
+ uint16 high_water; /* Max number of allocated objects. */
+ uint16 failed_alloc; /* Failed allocations. */
+} bcm_mp_stats_t;
+
+
+/*
+**************************************************************************
+*
+* API Routines on the pool manager.
+*
+**************************************************************************
+*/
+
+/*
+ * bcm_mpm_init() - initialize the whole memory pool system.
+ *
+ * Parameters:
+ * osh: INPUT Operating system handle. Needed for heap memory allocation.
+ * max_pools: INPUT Maximum number of mempools supported.
+ * mgr: OUTPUT The handle is written with the new pools manager object/handle.
+ *
+ * Returns:
+ * BCME_OK Object initialized successfully. May be used.
+ * BCME_NOMEM Initialization failed due to no memory. Object must not be used.
+ */
+int bcm_mpm_init(struct osl_info *osh, int max_pools, bcm_mpm_mgr_h *mgrp);
+
+
+/*
+ * bcm_mpm_deinit() - de-initialize the whole memory pool system.
+ *
+ * Parameters:
+ * mgr: INPUT Pointer to pool manager handle.
+ *
+ * Returns:
+ * BCME_OK Memory pool manager successfully de-initialized.
+ * other Indicated error occured during de-initialization.
+ */
+int bcm_mpm_deinit(bcm_mpm_mgr_h *mgrp);
+
+/*
+ * bcm_mpm_create_prealloc_pool() - Create a new pool for fixed size objects. The
+ * pool uses a contiguous block of pre-alloced
+ * memory. The memory block may either be provided
+ * by the client or dynamically allocated by the
+ * pool manager.
+ *
+ * Parameters:
+ * mgr: INPUT The handle to the pool manager
+ * obj_sz: INPUT Size of objects that will be allocated by the new pool
+ * Must be >= sizeof(void *).
+ * nobj: INPUT Maximum number of concurrently existing objects to support
+ * memstart INPUT Pointer to the memory to use, or NULL to malloc()
+ * memsize INPUT Number of bytes referenced from memstart (for error checking).
+ * Must be 0 if 'memstart' is NULL.
+ * poolname INPUT For instrumentation, the name of the pool
+ * newp: OUTPUT The handle for the new pool, if creation is successful
+ *
+ * Returns:
+ * BCME_OK Pool created ok.
+ * other Pool not created due to indicated error. newpoolp set to NULL.
+ *
+ *
+ */
+int bcm_mpm_create_prealloc_pool(bcm_mpm_mgr_h mgr,
+ unsigned int obj_sz,
+ int nobj,
+ void *memstart,
+ unsigned int memsize,
+ char poolname[BCM_MP_NAMELEN],
+ bcm_mp_pool_h *newp);
+
+
+/*
+ * bcm_mpm_delete_prealloc_pool() - Delete a memory pool. This should only be called after
+ * all memory objects have been freed back to the pool.
+ *
+ * Parameters:
+ * mgr: INPUT The handle to the pools manager
+ * pool: INPUT The handle of the pool to delete
+ *
+ * Returns:
+ * BCME_OK Pool deleted ok.
+ * other Pool not deleted due to indicated error.
+ *
+ */
+int bcm_mpm_delete_prealloc_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp);
+
+/*
+ * bcm_mpm_create_heap_pool() - Create a new pool for fixed size objects. The memory
+ * pool allocator uses the heap (malloc/free) for memory.
+ * In this case, the pool allocator is just providing
+ * statistics and instrumentation on top of the heap,
+ * without modifying the heap allocation implementation.
+ *
+ * Parameters:
+ * mgr: INPUT The handle to the pool manager
+ * obj_sz: INPUT Size of objects that will be allocated by the new pool
+ * poolname INPUT For instrumentation, the name of the pool
+ * newp: OUTPUT The handle for the new pool, if creation is successful
+ *
+ * Returns:
+ * BCME_OK Pool created ok.
+ * other Pool not created due to indicated error. newpoolp set to NULL.
+ *
+ *
+ */
+int bcm_mpm_create_heap_pool(bcm_mpm_mgr_h mgr, unsigned int obj_sz,
+ char poolname[BCM_MP_NAMELEN],
+ bcm_mp_pool_h *newp);
+
+
+/*
+ * bcm_mpm_delete_heap_pool() - Delete a memory pool. This should only be called after
+ * all memory objects have been freed back to the pool.
+ *
+ * Parameters:
+ * mgr: INPUT The handle to the pools manager
+ * pool: INPUT The handle of the pool to delete
+ *
+ * Returns:
+ * BCME_OK Pool deleted ok.
+ * other Pool not deleted due to indicated error.
+ *
+ */
+int bcm_mpm_delete_heap_pool(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp);
+
+
+/*
+ * bcm_mpm_stats() - Return stats for all pools
+ *
+ * Parameters:
+ * mgr: INPUT The handle to the pools manager
+ * stats: OUTPUT Array of pool statistics.
+ * nentries: MOD Max elements in 'stats' array on INPUT. Actual number
+ * of array elements copied to 'stats' on OUTPUT.
+ *
+ * Returns:
+ * BCME_OK Ok
+ * other Error getting stats.
+ *
+ */
+int bcm_mpm_stats(bcm_mpm_mgr_h mgr, bcm_mp_stats_t *stats, int *nentries);
+
+
+/*
+ * bcm_mpm_dump() - Display statistics on all pools
+ *
+ * Parameters:
+ * mgr: INPUT The handle to the pools manager
+ * b: OUTPUT Output buffer.
+ *
+ * Returns:
+ * BCME_OK Ok
+ * other Error during dump.
+ *
+ */
+int bcm_mpm_dump(bcm_mpm_mgr_h mgr, struct bcmstrbuf *b);
+
+
+/*
+ * bcm_mpm_get_obj_size() - The size of memory objects may need to be padded to
+ * compensate for alignment requirements of the objects.
+ * This function provides the padded object size. If clients
+ * pre-allocate a memory slab for a memory pool, the
+ * padded object size should be used by the client to allocate
+ * the memory slab (in order to provide sufficent space for
+ * the maximum number of objects).
+ *
+ * Parameters:
+ * mgr: INPUT The handle to the pools manager.
+ * obj_sz: INPUT Input object size.
+ * padded_obj_sz: OUTPUT Padded object size.
+ *
+ * Returns:
+ * BCME_OK Ok
+ * BCME_BADARG Bad arguments.
+ *
+ */
+int bcm_mpm_get_obj_size(bcm_mpm_mgr_h mgr, unsigned int obj_sz, unsigned int *padded_obj_sz);
+
+
+/*
+***************************************************************************
+*
+* API Routines on a specific pool.
+*
+***************************************************************************
+*/
+
+
+/*
+ * bcm_mp_alloc() - Allocate a memory pool object.
+ *
+ * Parameters:
+ * pool: INPUT The handle to the pool.
+ *
+ * Returns:
+ * A pointer to the new object. NULL on error.
+ *
+ */
+void* bcm_mp_alloc(bcm_mp_pool_h pool);
+
+/*
+ * bcm_mp_free() - Free a memory pool object.
+ *
+ * Parameters:
+ * pool: INPUT The handle to the pool.
+ * objp: INPUT A pointer to the object to free.
+ *
+ * Returns:
+ * BCME_OK Ok
+ * other Error during free.
+ *
+ */
+int bcm_mp_free(bcm_mp_pool_h pool, void *objp);
+
+/*
+ * bcm_mp_stats() - Return stats for this pool
+ *
+ * Parameters:
+ * pool: INPUT The handle to the pool
+ * stats: OUTPUT Pool statistics
+ *
+ * Returns:
+ * BCME_OK Ok
+ * other Error getting statistics.
+ *
+ */
+int bcm_mp_stats(bcm_mp_pool_h pool, bcm_mp_stats_t *stats);
+
+
+/*
+ * bcm_mp_dump() - Dump a pool
+ *
+ * Parameters:
+ * pool: INPUT The handle to the pool
+ * b OUTPUT Output buffer
+ *
+ * Returns:
+ * BCME_OK Ok
+ * other Error during dump.
+ *
+ */
+int bcm_mp_dump(bcm_mp_pool_h pool, struct bcmstrbuf *b);
+
+
+#endif /* _BCM_MPOOL_PUB_H */
diff --git a/drivers/net/wireless/ap6210/include/bcmcdc.h b/drivers/net/wireless/ap6210/include/bcmcdc.h
new file mode 100644
index 0000000..a1d1271
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmcdc.h
@@ -0,0 +1,132 @@
+/*
+ * CDC network driver ioctl/indication encoding
+ * Broadcom 802.11abg Networking Device Driver
+ *
+ * Definitions subject to change without notice.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmcdc.h 318308 2012-03-02 02:23:42Z $
+ */
+#ifndef _bcmcdc_h_
+#define _bcmcdc_h_
+#include <proto/ethernet.h>
+
+typedef struct cdc_ioctl {
+ uint32 cmd; /* ioctl command value */
+ uint32 len; /* lower 16: output buflen; upper 16: input buflen (excludes header) */
+ uint32 flags; /* flag defns given below */
+ uint32 status; /* status code returned from the device */
+} cdc_ioctl_t;
+
+/* Max valid buffer size that can be sent to the dongle */
+#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN
+
+/* len field is divided into input and output buffer lengths */
+#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected response length, */
+ /* excluding IOCTL header */
+#define CDCL_IOC_OUTLEN_SHIFT 0
+#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, excluding IOCTL header */
+#define CDCL_IOC_INLEN_SHIFT 16
+
+/* CDC flag definitions */
+#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */
+#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */
+#define CDCF_IOC_OVL_IDX_MASK 0x3c /* overlay region index mask */
+#define CDCF_IOC_OVL_RSV 0x40 /* 1=reserve this overlay region */
+#define CDCF_IOC_OVL 0x80 /* 1=this ioctl corresponds to an overlay */
+#define CDCF_IOC_ACTION_MASK 0xfe /* SET/GET, OVL_IDX, OVL_RSV, OVL mask */
+#define CDCF_IOC_ACTION_SHIFT 1 /* SET/GET, OVL_IDX, OVL_RSV, OVL shift */
+#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */
+#define CDCF_IOC_IF_SHIFT 12
+#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl req/resp pairing */
+#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */
+
+#define CDC_IOC_IF_IDX(flags) (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)
+#define CDC_IOC_ID(flags) (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
+
+#define CDC_GET_IF_IDX(hdr) \
+ ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT))
+#define CDC_SET_IF_IDX(hdr, idx) \
+ ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | ((idx) << CDCF_IOC_IF_SHIFT)))
+
+/*
+ * BDC header
+ *
+ * The BDC header is used on data packets to convey priority across USB.
+ */
+
+struct bdc_header {
+ uint8 flags; /* Flags */
+ uint8 priority; /* 802.1d Priority 0:2 bits, 4:7 USB flow control info */
+ uint8 flags2;
+ uint8 dataOffset; /* Offset from end of BDC header to packet data, in
+ * 4-byte words. Leaves room for optional headers.
+ */
+};
+
+#define BDC_HEADER_LEN 4
+
+/* flags field bitmap */
+#define BDC_FLAG_80211_PKT 0x01 /* Packet is in 802.11 format (dongle -> host) */
+#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good RX checksums */
+#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums: host->device */
+#define BDC_FLAG_EVENT_MSG 0x08 /* Payload contains an event msg: device->host */
+#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
+#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
+
+/* priority field bitmap */
+#define BDC_PRIORITY_MASK 0x07
+#define BDC_PRIORITY_FC_MASK 0xf0 /* flow control info mask */
+#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */
+
+/* flags2 field bitmap */
+#define BDC_FLAG2_IF_MASK 0x0f /* interface index (host <-> dongle) */
+#define BDC_FLAG2_IF_SHIFT 0
+#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */
+ /* FLOW CONTROL info only */
+
+/* version numbers */
+#define BDC_PROTO_VER_1 1 /* Old Protocol version */
+#define BDC_PROTO_VER 2 /* Protocol version */
+
+/* flags2.if field access macros */
+#define BDC_GET_IF_IDX(hdr) \
+ ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
+#define BDC_SET_IF_IDX(hdr, idx) \
+ ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | ((idx) << BDC_FLAG2_IF_SHIFT)))
+
+#define BDC_FLAG2_PAD_MASK 0xf0
+#define BDC_FLAG_PAD_MASK 0x03
+#define BDC_FLAG2_PAD_SHIFT 2
+#define BDC_FLAG_PAD_SHIFT 0
+#define BDC_FLAG2_PAD_IDX 0x3c
+#define BDC_FLAG_PAD_IDX 0x03
+#define BDC_GET_PAD_LEN(hdr) \
+ ((int)(((((hdr)->flags2) & BDC_FLAG2_PAD_MASK) >> BDC_FLAG2_PAD_SHIFT) | \
+ ((((hdr)->flags) & BDC_FLAG_PAD_MASK) >> BDC_FLAG_PAD_SHIFT)))
+#define BDC_SET_PAD_LEN(hdr, idx) \
+ ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_PAD_MASK) | \
+ (((idx) & BDC_FLAG2_PAD_IDX) << BDC_FLAG2_PAD_SHIFT))); \
+ ((hdr)->flags = (((hdr)->flags & ~BDC_FLAG_PAD_MASK) | \
+ (((idx) & BDC_FLAG_PAD_IDX) << BDC_FLAG_PAD_SHIFT)))
+
+#endif /* _bcmcdc_h_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmdefs.h b/drivers/net/wireless/ap6210/include/bcmdefs.h
new file mode 100644
index 0000000..00906e3
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmdefs.h
@@ -0,0 +1,270 @@
+/*
+ * Misc system wide definitions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmdefs.h 316830 2012-02-23 20:29:22Z $
+ */
+
+#ifndef _bcmdefs_h_
+#define _bcmdefs_h_
+
+/*
+ * One doesn't need to include this file explicitly, gets included automatically if
+ * typedefs.h is included.
+ */
+
+/* Use BCM_REFERENCE to suppress warnings about intentionally-unused function
+ * arguments or local variables.
+ */
+#define BCM_REFERENCE(data) ((void)(data))
+
+/* Compile-time assert can be used in place of ASSERT if the expression evaluates
+ * to a constant at compile time.
+ */
+#define STATIC_ASSERT(expr) { \
+ /* Make sure the expression is constant. */ \
+ typedef enum { _STATIC_ASSERT_NOT_CONSTANT = (expr) } _static_assert_e; \
+ /* Make sure the expression is true. */ \
+ typedef char STATIC_ASSERT_FAIL[(expr) ? 1 : -1]; \
+}
+
+/* Reclaiming text and data :
+ * The following macros specify special linker sections that can be reclaimed
+ * after a system is considered 'up'.
+ * BCMATTACHFN is also used for detach functions (it's not worth having a BCMDETACHFN,
+ * as in most cases, the attach function calls the detach function to clean up on error).
+ */
+
+#define bcmreclaimed 0
+#define _data _data
+#define _fn _fn
+#define BCMPREATTACHDATA(_data) _data
+#define BCMPREATTACHFN(_fn) _fn
+#define _data _data
+#define _fn _fn
+#define _fn _fn
+#define BCMNMIATTACHFN(_fn) _fn
+#define BCMNMIATTACHDATA(_data) _data
+#define CONST const
+#ifndef BCMFASTPATH
+#define BCMFASTPATH
+#define BCMFASTPATH_HOST
+#endif /* BCMFASTPATH */
+
+
+/* Put some library data/code into ROM to reduce RAM requirements */
+#define _data _data
+#define BCMROMDAT_NAME(_data) _data
+#define _fn _fn
+#define _fn _fn
+#define STATIC static
+#define BCMROMDAT_ARYSIZ(data) ARRAYSIZE(data)
+#define BCMROMDAT_SIZEOF(data) sizeof(data)
+#define BCMROMDAT_APATCH(data)
+#define BCMROMDAT_SPATCH(data)
+
+/* Bus types */
+#define SI_BUS 0 /* SOC Interconnect */
+#define PCI_BUS 1 /* PCI target */
+#define PCMCIA_BUS 2 /* PCMCIA target */
+#define SDIO_BUS 3 /* SDIO target */
+#define JTAG_BUS 4 /* JTAG */
+#define USB_BUS 5 /* USB (does not support R/W REG) */
+#define SPI_BUS 6 /* gSPI target */
+#define RPC_BUS 7 /* RPC target */
+
+/* Allows size optimization for single-bus image */
+#ifdef BCMBUSTYPE
+#define BUSTYPE(bus) (BCMBUSTYPE)
+#else
+#define BUSTYPE(bus) (bus)
+#endif
+
+/* Allows size optimization for single-backplane image */
+#ifdef BCMCHIPTYPE
+#define CHIPTYPE(bus) (BCMCHIPTYPE)
+#else
+#define CHIPTYPE(bus) (bus)
+#endif
+
+
+/* Allows size optimization for SPROM support */
+#if defined(BCMSPROMBUS)
+#define SPROMBUS (BCMSPROMBUS)
+#elif defined(SI_PCMCIA_SROM)
+#define SPROMBUS (PCMCIA_BUS)
+#else
+#define SPROMBUS (PCI_BUS)
+#endif
+
+/* Allows size optimization for single-chip image */
+#ifdef BCMCHIPID
+#define CHIPID(chip) (BCMCHIPID)
+#else
+#define CHIPID(chip) (chip)
+#endif
+
+#ifdef BCMCHIPREV
+#define CHIPREV(rev) (BCMCHIPREV)
+#else
+#define CHIPREV(rev) (rev)
+#endif
+
+/* Defines for DMA Address Width - Shared between OSL and HNDDMA */
+#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */
+#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */
+#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */
+
+#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */
+#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */
+#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */
+#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */
+
+#ifdef BCMDMA64OSL
+typedef struct {
+ uint32 loaddr;
+ uint32 hiaddr;
+} dma64addr_t;
+
+typedef dma64addr_t dmaaddr_t;
+#define PHYSADDRHI(_pa) ((_pa).hiaddr)
+#define PHYSADDRHISET(_pa, _val) \
+ do { \
+ (_pa).hiaddr = (_val); \
+ } while (0)
+#define PHYSADDRLO(_pa) ((_pa).loaddr)
+#define PHYSADDRLOSET(_pa, _val) \
+ do { \
+ (_pa).loaddr = (_val); \
+ } while (0)
+
+#else
+typedef unsigned long dmaaddr_t;
+#define PHYSADDRHI(_pa) (0)
+#define PHYSADDRHISET(_pa, _val)
+#define PHYSADDRLO(_pa) ((_pa))
+#define PHYSADDRLOSET(_pa, _val) \
+ do { \
+ (_pa) = (_val); \
+ } while (0)
+#endif /* BCMDMA64OSL */
+
+/* One physical DMA segment */
+typedef struct {
+ dmaaddr_t addr;
+ uint32 length;
+} hnddma_seg_t;
+
+#define MAX_DMA_SEGS 4
+
+
+typedef struct {
+ void *oshdmah; /* Opaque handle for OSL to store its information */
+ uint origsize; /* Size of the virtual packet */
+ uint nsegs;
+ hnddma_seg_t segs[MAX_DMA_SEGS];
+} hnddma_seg_map_t;
+
+
+/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF).
+ * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL.
+ * There is a compile time check in wlc.c which ensure that this value is at least as big
+ * as TXOFF. This value is used in dma_rxfill (hnddma.c).
+ */
+
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY)
+/* add 40 bytes to allow for extra RPC header and info */
+#define BCMEXTRAHDROOM 220
+#else /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */
+#define BCMEXTRAHDROOM 172
+#endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY */
+
+/* Packet alignment for most efficient SDIO (can change based on platform) */
+#ifndef SDALIGN
+#define SDALIGN 32
+#endif
+
+/* Headroom required for dongle-to-host communication. Packets allocated
+ * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should
+ * leave this much room in front for low-level message headers which may
+ * be needed to get across the dongle bus to the host. (These messages
+ * don't go over the network, so room for the full WL header above would
+ * be a waste.).
+*/
+#define BCMDONGLEHDRSZ 12
+#define BCMDONGLEPADSZ 16
+
+#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ)
+
+
+#if defined(NO_BCMDBG_ASSERT)
+# undef BCMDBG_ASSERT
+# undef BCMASSERT_LOG
+#endif
+
+#if defined(BCMASSERT_LOG)
+#define BCMASSERT_SUPPORT
+#endif
+
+/* Macros for doing definition and get/set of bitfields
+ * Usage example, e.g. a three-bit field (bits 4-6):
+ * #define <NAME>_M BITFIELD_MASK(3)
+ * #define <NAME>_S 4
+ * ...
+ * regval = R_REG(osh, &regs->regfoo);
+ * field = GFIELD(regval, <NAME>);
+ * regval = SFIELD(regval, <NAME>, 1);
+ * W_REG(osh, &regs->regfoo, regval);
+ */
+#define BITFIELD_MASK(width) \
+ (((unsigned)1 << (width)) - 1)
+#define GFIELD(val, field) \
+ (((val) >> field ## _S) & field ## _M)
+#define SFIELD(val, field, bits) \
+ (((val) & (~(field ## _M << field ## _S))) | \
+ ((unsigned)(bits) << field ## _S))
+
+/* define BCMSMALL to remove misc features for memory-constrained environments */
+#ifdef BCMSMALL
+#undef BCMSPACE
+#define bcmspace FALSE /* if (bcmspace) code is discarded */
+#else
+#define BCMSPACE
+#define bcmspace TRUE /* if (bcmspace) code is retained */
+#endif
+
+/* Max. nvram variable table size */
+#define MAXSZ_NVRAM_VARS 4096
+
+
+/* Max size for reclaimable NVRAM array */
+#ifdef DL_NVRAM
+#define NVRAM_ARRAY_MAXSIZE DL_NVRAM
+#else
+#define NVRAM_ARRAY_MAXSIZE MAXSZ_NVRAM_VARS
+#endif /* DL_NVRAM */
+
+#ifdef BCMUSBDEV_ENABLED
+extern uint32 gFWID;
+#endif
+
+#endif /* _bcmdefs_h_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmdevs.h b/drivers/net/wireless/ap6210/include/bcmdevs.h
new file mode 100644
index 0000000..c3dd89f
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmdevs.h
@@ -0,0 +1,503 @@
+/*
+ * Broadcom device-specific manifest constants.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmdevs.h 329854 2012-04-27 01:42:28Z $
+ */
+
+#ifndef _BCMDEVS_H
+#define _BCMDEVS_H
+
+/* PCI vendor IDs */
+#define VENDOR_EPIGRAM 0xfeda
+#define VENDOR_BROADCOM 0x14e4
+#define VENDOR_3COM 0x10b7
+#define VENDOR_NETGEAR 0x1385
+#define VENDOR_DIAMOND 0x1092
+#define VENDOR_INTEL 0x8086
+#define VENDOR_DELL 0x1028
+#define VENDOR_HP 0x103c
+#define VENDOR_HP_COMPAQ 0x0e11
+#define VENDOR_APPLE 0x106b
+#define VENDOR_SI_IMAGE 0x1095 /* Silicon Image, used by Arasan SDIO Host */
+#define VENDOR_BUFFALO 0x1154 /* Buffalo vendor id */
+#define VENDOR_TI 0x104c /* Texas Instruments */
+#define VENDOR_RICOH 0x1180 /* Ricoh */
+#define VENDOR_JMICRON 0x197b
+
+
+/* PCMCIA vendor IDs */
+#define VENDOR_BROADCOM_PCMCIA 0x02d0
+
+/* SDIO vendor IDs */
+#define VENDOR_BROADCOM_SDIO 0x00BF
+
+/* DONGLE VID/PIDs */
+#define BCM_DNGL_VID 0x0a5c
+#define BCM_DNGL_BL_PID_4328 0xbd12
+#define BCM_DNGL_BL_PID_4322 0xbd13
+#define BCM_DNGL_BL_PID_4319 0xbd16
+#define BCM_DNGL_BL_PID_43236 0xbd17
+#define BCM_DNGL_BL_PID_4332 0xbd18
+#define BCM_DNGL_BL_PID_4330 0xbd19
+#define BCM_DNGL_BL_PID_4334 0xbd1a
+#define BCM_DNGL_BL_PID_43239 0xbd1b
+#define BCM_DNGL_BL_PID_4324 0xbd1c
+#define BCM_DNGL_BL_PID_4360 0xbd1d
+
+#define BCM_DNGL_BDC_PID 0x0bdc
+#define BCM_DNGL_JTAG_PID 0x4a44
+
+/* HW USB BLOCK [CPULESS USB] PIDs */
+#define BCM_HWUSB_PID_43239 43239
+
+/* PCI Device IDs */
+#define BCM4210_DEVICE_ID 0x1072 /* never used */
+#define BCM4230_DEVICE_ID 0x1086 /* never used */
+#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
+#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
+#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
+#define BCM4211_DEVICE_ID 0x4211
+#define BCM4231_DEVICE_ID 0x4231
+#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
+#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */
+#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */
+#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */
+#define BCM4328_D11DUAL_ID 0x4314 /* 4328/4312 802.11a/g id */
+#define BCM4328_D11G_ID 0x4315 /* 4328/4312 802.11g id */
+#define BCM4328_D11A_ID 0x4316 /* 4328/4312 802.11a id */
+#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */
+#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */
+#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */
+#define BCM4325_D11DUAL_ID 0x431b /* 4325 802.11a/g id */
+#define BCM4325_D11G_ID 0x431c /* 4325 802.11g id */
+#define BCM4325_D11A_ID 0x431d /* 4325 802.11a id */
+#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
+#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
+#define BCM4306_UART_ID 0x4322 /* 4306 uart */
+#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
+#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
+#define BCM4306_D11G_ID2 0x4325 /* BCM4306_D11G_ID; INF w/loose binding war */
+#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */
+#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Ghz band id */
+#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */
+#define BCM4322_D11N_ID 0x432b /* 4322 802.11n dualband device */
+#define BCM4322_D11N2G_ID 0x432c /* 4322 802.11n 2.4GHz device */
+#define BCM4322_D11N5G_ID 0x432d /* 4322 802.11n 5GHz device */
+#define BCM4329_D11N_ID 0x432e /* 4329 802.11n dualband device */
+#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */
+#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */
+#define BCM4315_D11DUAL_ID 0x4334 /* 4315 802.11a/g id */
+#define BCM4315_D11G_ID 0x4335 /* 4315 802.11g id */
+#define BCM4315_D11A_ID 0x4336 /* 4315 802.11a id */
+#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */
+#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */
+#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */
+#define BCM43231_D11N2G_ID 0x4340 /* 43231 802.11n 2.4GHz device */
+#define BCM43221_D11N2G_ID 0x4341 /* 43221 802.11n 2.4GHz device */
+#define BCM43222_D11N_ID 0x4350 /* 43222 802.11n dualband device */
+#define BCM43222_D11N2G_ID 0x4351 /* 43222 802.11n 2.4GHz device */
+#define BCM43222_D11N5G_ID 0x4352 /* 43222 802.11n 5GHz device */
+#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
+#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db device */
+#define BCM43226_D11N_ID 0x4354 /* 43226 802.11n dualband device */
+#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
+#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
+#define BCM43236_D11N5G_ID 0x4348 /* 43236 802.11n 5GHz device */
+#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
+#define BCM43421_D11N_ID 0xA99D /* 43421 802.11n dualband device */
+#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
+#define BCM4330_D11N_ID 0x4360 /* 4330 802.11n dualband device */
+#define BCM4330_D11N2G_ID 0x4361 /* 4330 802.11n 2.4G device */
+#define BCM4330_D11N5G_ID 0x4362 /* 4330 802.11n 5G device */
+#define BCM4336_D11N_ID 0x4343 /* 4336 802.11n 2.4GHz device */
+#define BCM6362_D11N_ID 0x435f /* 6362 802.11n dualband device */
+#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */
+#define BCM4331_D11N2G_ID 0x4332 /* 4331 802.11n 2.4Ghz band id */
+#define BCM4331_D11N5G_ID 0x4333 /* 4331 802.11n 5Ghz band id */
+#define BCM43237_D11N_ID 0x4355 /* 43237 802.11n dualband device */
+#define BCM43237_D11N5G_ID 0x4356 /* 43237 802.11n 5GHz device */
+#define BCM43227_D11N2G_ID 0x4358 /* 43228 802.11n 2.4GHz device */
+#define BCM43228_D11N_ID 0x4359 /* 43228 802.11n DualBand device */
+#define BCM43228_D11N5G_ID 0x435a /* 43228 802.11n 5GHz device */
+#define BCM43362_D11N_ID 0x4363 /* 43362 802.11n 2.4GHz device */
+#define BCM43239_D11N_ID 0x4370 /* 43239 802.11n dualband device */
+#define BCM4324_D11N_ID 0x4374 /* 4324 802.11n dualband device */
+#define BCM43217_D11N2G_ID 0x43a9 /* 43217 802.11n 2.4GHz device */
+#define BCM43131_D11N2G_ID 0x43aa /* 43131 802.11n 2.4GHz device */
+#define BCM4314_D11N2G_ID 0x4364 /* 4314 802.11n 2.4G device */
+#define BCM43142_D11N2G_ID 0x4365 /* 43142 802.11n 2.4G device */
+#define BCM4334_D11N_ID 0x4380 /* 4334 802.11n dualband device */
+#define BCM4334_D11N2G_ID 0x4381 /* 4334 802.11n 2.4G device */
+#define BCM4334_D11N5G_ID 0x4382 /* 4334 802.11n 5G device */
+#define BCM43341_D11N_ID 0x4386 /* 43341 802.11n dualband device */
+#define BCM43341_D11N2G_ID 0x4387 /* 43341 802.11n 2.4G device */
+#define BCM43341_D11N5G_ID 0x4388 /* 43341 802.11n 5G device */
+#define BCM4360_D11AC_ID 0x43a0
+#define BCM4360_D11AC2G_ID 0x43a1
+#define BCM4360_D11AC5G_ID 0x43a2
+
+/* PCI Subsystem ID */
+#define BCM943228HMB_SSID_VEN1 0x0607
+#define BCM94313HMGBL_SSID_VEN1 0x0608
+#define BCM94313HMG_SSID_VEN1 0x0609
+
+
+#define BCM4335_D11AC_ID 0x43ae
+#define BCM4335_D11AC2G_ID 0x43af
+#define BCM4335_D11AC5G_ID 0x43b0
+#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */
+#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */
+#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */
+
+#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
+#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
+#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */
+#define BCM_JTAGM_ID 0x43f1 /* BCM jtagm device id */
+#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */
+#define BCM_SDIOH_ID 0x43f3 /* BCM sdio host id */
+#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */
+#define SPIH_FPGA_ID 0x43f5 /* PCI SPI Host Controller FPGA */
+#define BCM_SPIH_ID 0x43f6 /* Synopsis SPI Host Controller */
+#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */
+#define BCM_JTAGM2_ID 0x43f9 /* BCM alternate jtagm device id */
+#define SDHCI_FPGA_ID 0x43fa /* Standard SDIO Host Controller FPGA */
+#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
+#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
+#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
+#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
+#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
+#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
+#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
+#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
+#define BCM47XX_AUDIO_ID 0x4711 /* 47xx audio codec */
+#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
+#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
+#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */
+#define BCM47XX_GMAC_ID 0x4715 /* 47xx Unimac based GbE */
+#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */
+#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */
+#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */
+#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */
+#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */
+#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */
+#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */
+#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */
+#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */
+#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
+#define BCM4716_DEVICE_ID 0x4722 /* 4716 base devid */
+#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */
+#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */
+#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
+#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
+#define JINVANI_SDIOH_ID 0x4743 /* Jinvani SDIO Gold Host */
+#define BCM27XX_SDIOH_ID 0x2702 /* BCM27xx Standard SDIO Host */
+#define PCIXX21_FLASHMEDIA_ID 0x803b /* TI PCI xx21 Standard Host Controller */
+#define PCIXX21_SDIOH_ID 0x803c /* TI PCI xx21 Standard Host Controller */
+#define R5C822_SDIOH_ID 0x0822 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host */
+#define JMICRON_SDIOH_ID 0x2381 /* JMicron Standard SDIO Host Controller */
+
+/* Chip IDs */
+#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */
+#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */
+#define BCM43111_CHIP_ID 43111 /* 43111 chipcommon chipid (OTP chipid) */
+#define BCM43112_CHIP_ID 43112 /* 43112 chipcommon chipid (OTP chipid) */
+#define BCM4312_CHIP_ID 0x4312 /* 4312 chipcommon chipid */
+#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */
+#define BCM43131_CHIP_ID 43131 /* 43131 chip id (OTP chipid) */
+#define BCM4315_CHIP_ID 0x4315 /* 4315 chip id */
+#define BCM4318_CHIP_ID 0x4318 /* 4318 chipcommon chipid */
+#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */
+#define BCM4320_CHIP_ID 0x4320 /* 4320 chipcommon chipid */
+#define BCM4321_CHIP_ID 0x4321 /* 4321 chipcommon chipid */
+#define BCM43217_CHIP_ID 43217 /* 43217 chip id (OTP chipid) */
+#define BCM4322_CHIP_ID 0x4322 /* 4322 chipcommon chipid */
+#define BCM43221_CHIP_ID 43221 /* 43221 chipcommon chipid (OTP chipid) */
+#define BCM43222_CHIP_ID 43222 /* 43222 chipcommon chipid */
+#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */
+#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */
+#define BCM43227_CHIP_ID 43227 /* 43227 chipcommon chipid */
+#define BCM43228_CHIP_ID 43228 /* 43228 chipcommon chipid */
+#define BCM43226_CHIP_ID 43226 /* 43226 chipcommon chipid */
+#define BCM43231_CHIP_ID 43231 /* 43231 chipcommon chipid (OTP chipid) */
+#define BCM43234_CHIP_ID 43234 /* 43234 chipcommon chipid */
+#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */
+#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */
+#define BCM43237_CHIP_ID 43237 /* 43237 chipcommon chipid */
+#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */
+#define BCM43239_CHIP_ID 43239 /* 43239 chipcommon chipid */
+#define BCM43420_CHIP_ID 43420 /* 43222 chipcommon chipid (OTP, RBBU) */
+#define BCM43421_CHIP_ID 43421 /* 43224 chipcommon chipid (OTP, RBBU) */
+#define BCM43428_CHIP_ID 43428 /* 43228 chipcommon chipid (OTP, RBBU) */
+#define BCM43431_CHIP_ID 43431 /* 4331 chipcommon chipid (OTP, RBBU) */
+#define BCM43460_CHIP_ID 43460 /* 4360 chipcommon chipid (OTP, RBBU) */
+#define BCM4325_CHIP_ID 0x4325 /* 4325 chip id */
+#define BCM4328_CHIP_ID 0x4328 /* 4328 chip id */
+#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */
+#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */
+#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */
+#define BCM43362_CHIP_ID 43362 /* 43362 chipcommon chipid */
+#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */
+#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */
+#define BCM4314_CHIP_ID 0x4314 /* 4314 chipcommon chipid */
+#define BCM43142_CHIP_ID 43142 /* 43142 chipcommon chipid */
+#define BCM4324_CHIP_ID 0x4324 /* 4324 chipcommon chipid */
+#define BCM43242_CHIP_ID 43242 /* 43242 chipcommon chipid */
+#define BCM4334_CHIP_ID 0x4334 /* 4334 chipcommon chipid */
+#define BCM4360_CHIP_ID 0x4360 /* 4360 chipcommon chipid */
+#define BCM4352_CHIP_ID 0x4352 /* 4352 chipcommon chipid */
+#define BCM43526_CHIP_ID 0xAA06
+#define BCM43341_CHIP_ID 43341 /* 43341 chipcommon chipid */
+#define BCM43342_CHIP_ID 43342 /* 43342 chipcommon chipid */
+
+#define BCM4335_CHIP_ID 0x4335
+
+#define BCM4342_CHIP_ID 4342 /* 4342 chipcommon chipid (OTP, RBBU) */
+#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */
+#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */
+#define BCM4706_CHIP_ID 0x5300 /* 4706 chipcommon chipid */
+#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid */
+#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */
+#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */
+#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */
+#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */
+#define BCM4749_CHIP_ID 0x4749 /* 5357 chipcommon chipid (OTP, RBBU) */
+#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */
+#define BCM5350_CHIP_ID 0x5350 /* 5350 chipcommon chipid */
+#define BCM5352_CHIP_ID 0x5352 /* 5352 chipcommon chipid */
+#define BCM5354_CHIP_ID 0x5354 /* 5354 chipcommon chipid */
+#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */
+#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */
+#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */
+#define BCM53572_CHIP_ID 53572 /* 53572 chipcommon chipid */
+
+/* Package IDs */
+#define BCM4303_PKG_ID 2 /* 4303 package id */
+#define BCM4309_PKG_ID 1 /* 4309 package id */
+#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
+#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
+#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
+#define BCM4328USBD11G_PKG_ID 2 /* 4328 802.11g USB package id */
+#define BCM4328USBDUAL_PKG_ID 3 /* 4328 802.11a/g USB package id */
+#define BCM4328SDIOD11G_PKG_ID 4 /* 4328 802.11g SDIO package id */
+#define BCM4328SDIODUAL_PKG_ID 5 /* 4328 802.11a/g SDIO package id */
+#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */
+#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */
+#define BCM5354E_PKG_ID 1 /* 5354E package id */
+#define BCM4716_PKG_ID 8 /* 4716 package id */
+#define BCM4717_PKG_ID 9 /* 4717 package id */
+#define BCM4718_PKG_ID 10 /* 4718 package id */
+#define BCM5356_PKG_NONMODE 1 /* 5356 package without nmode suppport */
+#define BCM5358U_PKG_ID 8 /* 5358U package id */
+#define BCM5358_PKG_ID 9 /* 5358 package id */
+#define BCM47186_PKG_ID 10 /* 47186 package id */
+#define BCM5357_PKG_ID 11 /* 5357 package id */
+#define BCM5356U_PKG_ID 12 /* 5356U package id */
+#define BCM53572_PKG_ID 8 /* 53572 package id */
+#define BCM5357C0_PKG_ID 8 /* 5357c0 package id (the same as 53572) */
+#define BCM47188_PKG_ID 9 /* 47188 package id */
+#define BCM5358C0_PKG_ID 0xa /* 5358c0 package id */
+#define BCM5356C0_PKG_ID 0xb /* 5356c0 package id */
+#define BCM4331TT_PKG_ID 8 /* 4331 12x12 package id */
+#define BCM4331TN_PKG_ID 9 /* 4331 12x9 package id */
+#define BCM4331TNA0_PKG_ID 0xb /* 4331 12x9 package id */
+#define BCM4706L_PKG_ID 1 /* 4706L package id */
+
+#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */
+#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
+#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
+#define BCM43224_FAB_CSM 0x8 /* the chip is manufactured by CSM */
+#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */
+#define BCM4336_WLBGA_PKG_ID 0x8
+#define BCM4330_WLBGA_PKG_ID 0x0
+#define BCM4314PCIE_ARM_PKG_ID (8 | 0) /* 4314 QFN PCI package id, bit 3 tie high */
+#define BCM4314SDIO_PKG_ID (8 | 1) /* 4314 QFN SDIO package id */
+#define BCM4314PCIE_PKG_ID (8 | 2) /* 4314 QFN PCI (ARM-less) package id */
+#define BCM4314SDIO_ARM_PKG_ID (8 | 3) /* 4314 QFN SDIO (ARM-less) package id */
+#define BCM4314SDIO_FPBGA_PKG_ID (8 | 4) /* 4314 FpBGA SDIO package id */
+#define BCM4314DEV_PKG_ID (8 | 6) /* 4314 Developement package id */
+
+#define PCIXX21_FLASHMEDIA0_ID 0x8033 /* TI PCI xx21 Standard Host Controller */
+#define PCIXX21_SDIOH0_ID 0x8034 /* TI PCI xx21 Standard Host Controller */
+
+/* boardflags */
+#define BFL_BTC2WIRE 0x00000001 /* old 2wire Bluetooth coexistence, OBSOLETE */
+#define BFL_BTCOEX 0x00000001 /* Board supports BTCOEX */
+#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */
+#define BFL_AIRLINEMODE 0x00000004 /* Board implements gpio 13 radio disable indication, UNUSED */
+#define BFL_ADCDIV 0x00000008 /* Board has the rssi ADC divider */
+#define BFL_RFPLL 0x00000008 /* ACPHY: Changing RFPLL BW to be 150 MHz */
+#define BFL_ENETROBO 0x00000010 /* Board has robo switch or core */
+#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */
+#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */
+#define BFL_ENETADM 0x00000080 /* Board has ADMtek switch */
+#define BFL_ENETVLAN 0x00000100 /* Board has VLAN capability */
+#define BFL_UNUSED 0x00000200
+#define BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
+#define BFL_FEM 0x00000800 /* Board supports the Front End Module */
+#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */
+#define BFL_HGPA 0x00002000 /* Board has a high gain PA */
+#define BFL_BTC2WIRE_ALTGPIO 0x00004000 /* Board's BTC 2wire is in the alternate gpios */
+#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */
+#define BFL_NOPA 0x00010000 /* Board has no PA */
+#define BFL_RSSIINV 0x00020000 /* Board's RSSI uses positive slope(not TSSI) */
+#define BFL_PAREF 0x00040000 /* Board uses the PARef LDO */
+#define BFL_3TSWITCH 0x00080000 /* Board uses a triple throw switch shared with BT */
+#define BFL_PHASESHIFT 0x00100000 /* Board can support phase shifter */
+#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */
+#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */
+#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */
+#define BFL_CCKFAVOREVM 0x01000000 /* Favor CCK EVM over spectral mask */
+#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */
+#define BFL_LNLDO2_2P5 0x04000000 /* Select 2.5V as LNLDO2 output voltage */
+#define BFL_FASTPWR 0x08000000
+#define BFL_UCPWRCTL_MININDX 0x08000000 /* Enforce min power index to avoid FEM damage */
+#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */
+#define BFL_TRSW_1by2 0x20000000 /* Board has 2 TRSW's in 1by2 designs */
+#define BFL_LO_TRSW_R_5GHz 0x40000000 /* In 5G do not throw TRSW to T for clipLO gain */
+#define BFL_ELNA_GAINDEF 0x80000000 /* Backoff InitGain based on elna_2g/5g field
+ * when this flag is set
+ */
+#define BFL_EXTLNA_TX 0x20000000 /* Temp boardflag to indicate to */
+
+/* boardflags2 */
+#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */
+#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */
+#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */
+#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */
+#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */
+#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */
+#define BFL2_CAESERS_BRD 0x00000040 /* Board is Caesers brd (unused by sw) */
+#define BFL2_BTC3WIRE 0x00000080 /* Board support legacy 3 wire or 4 wire */
+#define BFL2_BTCLEGACY 0x00000080 /* Board support legacy 3/4 wire, to replace
+ * BFL2_BTC3WIRE
+ */
+#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */
+#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */
+#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */
+#define BFL2_TRISTATE_LED 0x00000800 /* Tri-state the LED */
+#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */
+#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */
+#define BFL2_BPHY_ALL_TXCORES 0x00004000 /* Transmit bphy frames using all tx cores */
+#define BFL2_FCC_BANDEDGE_WAR 0x00008000 /* Activates WAR to improve FCC bandedge performance */
+#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */
+#define BFL2_IPALVLSHIFT_3P3 0x00020000
+#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */
+#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio on */
+ /* Most drivers will turn it off without this flag */
+ /* to save power. */
+
+#define BFL2_ANAPACTRL_2G 0x00100000 /* 2G ext PAs are controlled by analog PA ctrl lines */
+#define BFL2_ANAPACTRL_5G 0x00200000 /* 5G ext PAs are controlled by analog PA ctrl lines */
+#define BFL2_ELNACTRL_TRSW_2G 0x00400000 /* AZW4329: 2G gmode_elna_gain controls TR Switch */
+#define BFL2_BT_SHARE_ANT0 0x00800000 /* share core0 antenna with BT */
+#define BFL2_TEMPSENSE_HIGHER 0x01000000 /* The tempsense threshold can sustain higher value
+ * than programmed. The exact delta is decided by
+ * driver per chip/boardtype. This can be used
+ * when tempsense qualification happens after shipment
+ */
+#define BFL2_BTC3WIREONLY 0x02000000 /* standard 3 wire btc only. 4 wire not supported */
+#define BFL2_PWR_NOMINAL 0x04000000 /* 0: power reduction on, 1: no power reduction */
+#define BFL2_EXTLNA_PWRSAVE 0x08000000 /* boardflag to enable ucode to apply power save */
+ /* ucode control of eLNA during Tx */
+#define BFL2_4313_RADIOREG 0x10000000
+ /* board rework */
+#define BFL2_SDR_EN 0x20000000 /* SDR enabled or disabled */
+
+/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
+#define BOARD_GPIO_BTC3W_IN 0x850 /* bit 4 is RF_ACTIVE, bit 6 is STATUS, bit 11 is PRI */
+#define BOARD_GPIO_BTC3W_OUT 0x020 /* bit 5 is TX_CONF */
+#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistence Input */
+#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistence Out */
+#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistence Input */
+#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistence Out */
+#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
+#define BOARD_GPIO_12 0x1000 /* gpio 12 */
+#define BOARD_GPIO_13 0x2000 /* gpio 13 */
+#define BOARD_GPIO_BTC4_IN 0x0800 /* gpio 11, coex4, in */
+#define BOARD_GPIO_BTC4_BT 0x2000 /* gpio 12, coex4, bt active */
+#define BOARD_GPIO_BTC4_STAT 0x4000 /* gpio 14, coex4, status */
+#define BOARD_GPIO_BTC4_WLAN 0x8000 /* gpio 15, coex4, wlan active */
+#define BOARD_GPIO_1_WLAN_PWR 0x02 /* throttle WLAN power on X21 board */
+#define BOARD_GPIO_3_WLAN_PWR 0x08 /* throttle WLAN power on X28 board */
+#define BOARD_GPIO_4_WLAN_PWR 0x10 /* throttle WLAN power on X19 board */
+
+#define GPIO_BTC4W_OUT_4312 0x010 /* bit 4 is BT_IODISABLE */
+#define GPIO_BTC4W_OUT_43224 0x020 /* bit 5 is BT_IODISABLE */
+#define GPIO_BTC4W_OUT_43224_SHARED 0x0e0 /* bit 5 is BT_IODISABLE */
+#define GPIO_BTC4W_OUT_43225 0x0e0 /* bit 5 BT_IODISABLE, bit 6 SW_BT, bit 7 SW_WL */
+#define GPIO_BTC4W_OUT_43421 0x020 /* bit 5 is BT_IODISABLE */
+#define GPIO_BTC4W_OUT_4313 0x060 /* bit 5 SW_BT, bit 6 SW_WL */
+#define GPIO_BTC4W_OUT_4331_SHARED 0x010 /* GPIO 4 */
+
+#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
+#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
+#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */
+#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */
+
+/* power control defines */
+#define PLL_DELAY 150 /* us pll on delay */
+#define FREF_DELAY 200 /* us fref change delay */
+#define MIN_SLOW_CLK 32 /* us Slow clock period */
+#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
+
+
+/* 43341 Boards */
+#define BCM943341WLABGS_SSID 0x062d
+
+/* # of GPIO pins */
+#define GPIO_NUMPINS 32
+
+/* These values are used by dhd host driver. */
+#define RDL_RAM_BASE_4319 0x60000000
+#define RDL_RAM_BASE_4329 0x60000000
+#define RDL_RAM_SIZE_4319 0x48000
+#define RDL_RAM_SIZE_4329 0x48000
+#define RDL_RAM_SIZE_43236 0x70000
+#define RDL_RAM_BASE_43236 0x60000000
+#define RDL_RAM_SIZE_4328 0x60000
+#define RDL_RAM_BASE_4328 0x80000000
+#define RDL_RAM_SIZE_4322 0x60000
+#define RDL_RAM_BASE_4322 0x60000000
+
+/* generic defs for nvram "muxenab" bits */
+#define MUXENAB_UART 0x00000001
+#define MUXENAB_GPIO 0x00000002
+#define MUXENAB_ERCX 0x00000004 /* External Radio BT coex */
+#define MUXENAB_JTAG 0x00000008
+#define MUXENAB_HOST_WAKE 0x00000010 /* configure GPIO for SDIO host_wake */
+#define MUXENAB_I2S_EN 0x00000020
+#define MUXENAB_I2S_MASTER 0x00000040
+#define MUXENAB_I2S_FULL 0x00000080
+#define MUXENAB_SFLASH 0x00000100
+#define MUXENAB_RFSWCTRL0 0x00000200
+#define MUXENAB_RFSWCTRL1 0x00000400
+#define MUXENAB_RFSWCTRL2 0x00000800
+#define MUXENAB_SECI 0x00001000
+#define MUXENAB_BT_LEGACY 0x00002000
+#define MUXENAB_HOST_WAKE1 0x00004000 /* configure alternative GPIO for SDIO host_wake */
+
+/* Boot flags */
+#define FLASH_KERNEL_NFLASH 0x00000001
+#define FLASH_BOOT_NFLASH 0x00000002
+
+#endif /* _BCMDEVS_H */
diff --git a/drivers/net/wireless/ap6210/include/bcmendian.h b/drivers/net/wireless/ap6210/include/bcmendian.h
new file mode 100644
index 0000000..0cf9145
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmendian.h
@@ -0,0 +1,299 @@
+/*
+ * Byte order utilities
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmendian.h 241182 2011-02-17 21:50:03Z $
+ *
+ * This file by default provides proper behavior on little-endian architectures.
+ * On big-endian architectures, IL_BIGENDIAN should be defined.
+ */
+
+#ifndef _BCMENDIAN_H_
+#define _BCMENDIAN_H_
+
+#include <typedefs.h>
+
+/* Reverse the bytes in a 16-bit value */
+#define BCMSWAP16(val) \
+ ((uint16)((((uint16)(val) & (uint16)0x00ffU) << 8) | \
+ (((uint16)(val) & (uint16)0xff00U) >> 8)))
+
+/* Reverse the bytes in a 32-bit value */
+#define BCMSWAP32(val) \
+ ((uint32)((((uint32)(val) & (uint32)0x000000ffU) << 24) | \
+ (((uint32)(val) & (uint32)0x0000ff00U) << 8) | \
+ (((uint32)(val) & (uint32)0x00ff0000U) >> 8) | \
+ (((uint32)(val) & (uint32)0xff000000U) >> 24)))
+
+/* Reverse the two 16-bit halves of a 32-bit value */
+#define BCMSWAP32BY16(val) \
+ ((uint32)((((uint32)(val) & (uint32)0x0000ffffU) << 16) | \
+ (((uint32)(val) & (uint32)0xffff0000U) >> 16)))
+
+/* Byte swapping macros
+ * Host <=> Network (Big Endian) for 16- and 32-bit values
+ * Host <=> Little-Endian for 16- and 32-bit values
+ */
+#ifndef hton16
+#define HTON16(i) BCMSWAP16(i)
+#define hton16(i) bcmswap16(i)
+#define HTON32(i) BCMSWAP32(i)
+#define hton32(i) bcmswap32(i)
+#define NTOH16(i) BCMSWAP16(i)
+#define ntoh16(i) bcmswap16(i)
+#define NTOH32(i) BCMSWAP32(i)
+#define ntoh32(i) bcmswap32(i)
+#define LTOH16(i) (i)
+#define ltoh16(i) (i)
+#define LTOH32(i) (i)
+#define ltoh32(i) (i)
+#define HTOL16(i) (i)
+#define htol16(i) (i)
+#define HTOL32(i) (i)
+#define htol32(i) (i)
+#endif /* hton16 */
+
+#define ltoh16_buf(buf, i)
+#define htol16_buf(buf, i)
+
+/* Unaligned loads and stores in host byte order */
+#define load32_ua(a) ltoh32_ua(a)
+#define store32_ua(a, v) htol32_ua_store(v, a)
+#define load16_ua(a) ltoh16_ua(a)
+#define store16_ua(a, v) htol16_ua_store(v, a)
+
+#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8))
+#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24))
+#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1])
+#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3])
+
+#define ltoh_ua(ptr) \
+ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
+ sizeof(*(ptr)) == sizeof(uint16) ? _LTOH16_UA((const uint8 *)(ptr)) : \
+ sizeof(*(ptr)) == sizeof(uint32) ? _LTOH32_UA((const uint8 *)(ptr)) : \
+ *(uint8 *)0)
+
+#define ntoh_ua(ptr) \
+ (sizeof(*(ptr)) == sizeof(uint8) ? *(const uint8 *)(ptr) : \
+ sizeof(*(ptr)) == sizeof(uint16) ? _NTOH16_UA((const uint8 *)(ptr)) : \
+ sizeof(*(ptr)) == sizeof(uint32) ? _NTOH32_UA((const uint8 *)(ptr)) : \
+ *(uint8 *)0)
+
+#ifdef __GNUC__
+
+/* GNU macro versions avoid referencing the argument multiple times, while also
+ * avoiding the -fno-inline used in ROM builds.
+ */
+
+#define bcmswap16(val) ({ \
+ uint16 _val = (val); \
+ BCMSWAP16(_val); \
+})
+
+#define bcmswap32(val) ({ \
+ uint32 _val = (val); \
+ BCMSWAP32(_val); \
+})
+
+#define bcmswap32by16(val) ({ \
+ uint32 _val = (val); \
+ BCMSWAP32BY16(_val); \
+})
+
+#define bcmswap16_buf(buf, len) ({ \
+ uint16 *_buf = (uint16 *)(buf); \
+ uint _wds = (len) / 2; \
+ while (_wds--) { \
+ *_buf = bcmswap16(*_buf); \
+ _buf++; \
+ } \
+})
+
+#define htol16_ua_store(val, bytes) ({ \
+ uint16 _val = (val); \
+ uint8 *_bytes = (uint8 *)(bytes); \
+ _bytes[0] = _val & 0xff; \
+ _bytes[1] = _val >> 8; \
+})
+
+#define htol32_ua_store(val, bytes) ({ \
+ uint32 _val = (val); \
+ uint8 *_bytes = (uint8 *)(bytes); \
+ _bytes[0] = _val & 0xff; \
+ _bytes[1] = (_val >> 8) & 0xff; \
+ _bytes[2] = (_val >> 16) & 0xff; \
+ _bytes[3] = _val >> 24; \
+})
+
+#define hton16_ua_store(val, bytes) ({ \
+ uint16 _val = (val); \
+ uint8 *_bytes = (uint8 *)(bytes); \
+ _bytes[0] = _val >> 8; \
+ _bytes[1] = _val & 0xff; \
+})
+
+#define hton32_ua_store(val, bytes) ({ \
+ uint32 _val = (val); \
+ uint8 *_bytes = (uint8 *)(bytes); \
+ _bytes[0] = _val >> 24; \
+ _bytes[1] = (_val >> 16) & 0xff; \
+ _bytes[2] = (_val >> 8) & 0xff; \
+ _bytes[3] = _val & 0xff; \
+})
+
+#define ltoh16_ua(bytes) ({ \
+ const uint8 *_bytes = (const uint8 *)(bytes); \
+ _LTOH16_UA(_bytes); \
+})
+
+#define ltoh32_ua(bytes) ({ \
+ const uint8 *_bytes = (const uint8 *)(bytes); \
+ _LTOH32_UA(_bytes); \
+})
+
+#define ntoh16_ua(bytes) ({ \
+ const uint8 *_bytes = (const uint8 *)(bytes); \
+ _NTOH16_UA(_bytes); \
+})
+
+#define ntoh32_ua(bytes) ({ \
+ const uint8 *_bytes = (const uint8 *)(bytes); \
+ _NTOH32_UA(_bytes); \
+})
+
+#else /* !__GNUC__ */
+
+/* Inline versions avoid referencing the argument multiple times */
+static INLINE uint16
+bcmswap16(uint16 val)
+{
+ return BCMSWAP16(val);
+}
+
+static INLINE uint32
+bcmswap32(uint32 val)
+{
+ return BCMSWAP32(val);
+}
+
+static INLINE uint32
+bcmswap32by16(uint32 val)
+{
+ return BCMSWAP32BY16(val);
+}
+
+/* Reverse pairs of bytes in a buffer (not for high-performance use) */
+/* buf - start of buffer of shorts to swap */
+/* len - byte length of buffer */
+static INLINE void
+bcmswap16_buf(uint16 *buf, uint len)
+{
+ len = len / 2;
+
+ while (len--) {
+ *buf = bcmswap16(*buf);
+ buf++;
+ }
+}
+
+/*
+ * Store 16-bit value to unaligned little-endian byte array.
+ */
+static INLINE void
+htol16_ua_store(uint16 val, uint8 *bytes)
+{
+ bytes[0] = val & 0xff;
+ bytes[1] = val >> 8;
+}
+
+/*
+ * Store 32-bit value to unaligned little-endian byte array.
+ */
+static INLINE void
+htol32_ua_store(uint32 val, uint8 *bytes)
+{
+ bytes[0] = val & 0xff;
+ bytes[1] = (val >> 8) & 0xff;
+ bytes[2] = (val >> 16) & 0xff;
+ bytes[3] = val >> 24;
+}
+
+/*
+ * Store 16-bit value to unaligned network-(big-)endian byte array.
+ */
+static INLINE void
+hton16_ua_store(uint16 val, uint8 *bytes)
+{
+ bytes[0] = val >> 8;
+ bytes[1] = val & 0xff;
+}
+
+/*
+ * Store 32-bit value to unaligned network-(big-)endian byte array.
+ */
+static INLINE void
+hton32_ua_store(uint32 val, uint8 *bytes)
+{
+ bytes[0] = val >> 24;
+ bytes[1] = (val >> 16) & 0xff;
+ bytes[2] = (val >> 8) & 0xff;
+ bytes[3] = val & 0xff;
+}
+
+/*
+ * Load 16-bit value from unaligned little-endian byte array.
+ */
+static INLINE uint16
+ltoh16_ua(const void *bytes)
+{
+ return _LTOH16_UA((const uint8 *)bytes);
+}
+
+/*
+ * Load 32-bit value from unaligned little-endian byte array.
+ */
+static INLINE uint32
+ltoh32_ua(const void *bytes)
+{
+ return _LTOH32_UA((const uint8 *)bytes);
+}
+
+/*
+ * Load 16-bit value from unaligned big-(network-)endian byte array.
+ */
+static INLINE uint16
+ntoh16_ua(const void *bytes)
+{
+ return _NTOH16_UA((const uint8 *)bytes);
+}
+
+/*
+ * Load 32-bit value from unaligned big-(network-)endian byte array.
+ */
+static INLINE uint32
+ntoh32_ua(const void *bytes)
+{
+ return _NTOH32_UA((const uint8 *)bytes);
+}
+
+#endif /* !__GNUC__ */
+#endif /* !_BCMENDIAN_H_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmpcispi.h b/drivers/net/wireless/ap6210/include/bcmpcispi.h
new file mode 100644
index 0000000..44b263c
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmpcispi.h
@@ -0,0 +1,181 @@
+/*
+ * Broadcom PCI-SPI Host Controller Register Definitions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmpcispi.h 241182 2011-02-17 21:50:03Z $
+ */
+#ifndef _BCM_PCI_SPI_H
+#define _BCM_PCI_SPI_H
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif /* PAD */
+
+
+typedef volatile struct {
+ uint32 spih_ctrl; /* 0x00 SPI Control Register */
+ uint32 spih_stat; /* 0x04 SPI Status Register */
+ uint32 spih_data; /* 0x08 SPI Data Register, 32-bits wide */
+ uint32 spih_ext; /* 0x0C SPI Extension Register */
+ uint32 PAD[4]; /* 0x10-0x1F PADDING */
+
+ uint32 spih_gpio_ctrl; /* 0x20 SPI GPIO Control Register */
+ uint32 spih_gpio_data; /* 0x24 SPI GPIO Data Register */
+ uint32 PAD[6]; /* 0x28-0x3F PADDING */
+
+ uint32 spih_int_edge; /* 0x40 SPI Interrupt Edge Register (0=Level, 1=Edge) */
+ uint32 spih_int_pol; /* 0x44 SPI Interrupt Polarity Register (0=Active Low, */
+ /* 1=Active High) */
+ uint32 spih_int_mask; /* 0x48 SPI Interrupt Mask */
+ uint32 spih_int_status; /* 0x4C SPI Interrupt Status */
+ uint32 PAD[4]; /* 0x50-0x5F PADDING */
+
+ uint32 spih_hex_disp; /* 0x60 SPI 4-digit hex display value */
+ uint32 spih_current_ma; /* 0x64 SPI SD card current consumption in mA */
+ uint32 PAD[1]; /* 0x68 PADDING */
+ uint32 spih_disp_sel; /* 0x6c SPI 4-digit hex display mode select (1=current) */
+ uint32 PAD[4]; /* 0x70-0x7F PADDING */
+ uint32 PAD[8]; /* 0x80-0x9F PADDING */
+ uint32 PAD[8]; /* 0xA0-0xBF PADDING */
+ uint32 spih_pll_ctrl; /* 0xC0 PLL Control Register */
+ uint32 spih_pll_status; /* 0xC4 PLL Status Register */
+ uint32 spih_xtal_freq; /* 0xC8 External Clock Frequency in units of 10000Hz */
+ uint32 spih_clk_count; /* 0xCC External Clock Count Register */
+
+} spih_regs_t;
+
+typedef volatile struct {
+ uint32 cfg_space[0x40]; /* 0x000-0x0FF PCI Configuration Space (Read Only) */
+ uint32 P_IMG_CTRL0; /* 0x100 PCI Image0 Control Register */
+
+ uint32 P_BA0; /* 0x104 32 R/W PCI Image0 Base Address register */
+ uint32 P_AM0; /* 0x108 32 R/W PCI Image0 Address Mask register */
+ uint32 P_TA0; /* 0x10C 32 R/W PCI Image0 Translation Address register */
+ uint32 P_IMG_CTRL1; /* 0x110 32 R/W PCI Image1 Control register */
+ uint32 P_BA1; /* 0x114 32 R/W PCI Image1 Base Address register */
+ uint32 P_AM1; /* 0x118 32 R/W PCI Image1 Address Mask register */
+ uint32 P_TA1; /* 0x11C 32 R/W PCI Image1 Translation Address register */
+ uint32 P_IMG_CTRL2; /* 0x120 32 R/W PCI Image2 Control register */
+ uint32 P_BA2; /* 0x124 32 R/W PCI Image2 Base Address register */
+ uint32 P_AM2; /* 0x128 32 R/W PCI Image2 Address Mask register */
+ uint32 P_TA2; /* 0x12C 32 R/W PCI Image2 Translation Address register */
+ uint32 P_IMG_CTRL3; /* 0x130 32 R/W PCI Image3 Control register */
+ uint32 P_BA3; /* 0x134 32 R/W PCI Image3 Base Address register */
+ uint32 P_AM3; /* 0x138 32 R/W PCI Image3 Address Mask register */
+ uint32 P_TA3; /* 0x13C 32 R/W PCI Image3 Translation Address register */
+ uint32 P_IMG_CTRL4; /* 0x140 32 R/W PCI Image4 Control register */
+ uint32 P_BA4; /* 0x144 32 R/W PCI Image4 Base Address register */
+ uint32 P_AM4; /* 0x148 32 R/W PCI Image4 Address Mask register */
+ uint32 P_TA4; /* 0x14C 32 R/W PCI Image4 Translation Address register */
+ uint32 P_IMG_CTRL5; /* 0x150 32 R/W PCI Image5 Control register */
+ uint32 P_BA5; /* 0x154 32 R/W PCI Image5 Base Address register */
+ uint32 P_AM5; /* 0x158 32 R/W PCI Image5 Address Mask register */
+ uint32 P_TA5; /* 0x15C 32 R/W PCI Image5 Translation Address register */
+ uint32 P_ERR_CS; /* 0x160 32 R/W PCI Error Control and Status register */
+ uint32 P_ERR_ADDR; /* 0x164 32 R PCI Erroneous Address register */
+ uint32 P_ERR_DATA; /* 0x168 32 R PCI Erroneous Data register */
+
+ uint32 PAD[5]; /* 0x16C-0x17F PADDING */
+
+ uint32 WB_CONF_SPC_BAR; /* 0x180 32 R WISHBONE Configuration Space Base Address */
+ uint32 W_IMG_CTRL1; /* 0x184 32 R/W WISHBONE Image1 Control register */
+ uint32 W_BA1; /* 0x188 32 R/W WISHBONE Image1 Base Address register */
+ uint32 W_AM1; /* 0x18C 32 R/W WISHBONE Image1 Address Mask register */
+ uint32 W_TA1; /* 0x190 32 R/W WISHBONE Image1 Translation Address reg */
+ uint32 W_IMG_CTRL2; /* 0x194 32 R/W WISHBONE Image2 Control register */
+ uint32 W_BA2; /* 0x198 32 R/W WISHBONE Image2 Base Address register */
+ uint32 W_AM2; /* 0x19C 32 R/W WISHBONE Image2 Address Mask register */
+ uint32 W_TA2; /* 0x1A0 32 R/W WISHBONE Image2 Translation Address reg */
+ uint32 W_IMG_CTRL3; /* 0x1A4 32 R/W WISHBONE Image3 Control register */
+ uint32 W_BA3; /* 0x1A8 32 R/W WISHBONE Image3 Base Address register */
+ uint32 W_AM3; /* 0x1AC 32 R/W WISHBONE Image3 Address Mask register */
+ uint32 W_TA3; /* 0x1B0 32 R/W WISHBONE Image3 Translation Address reg */
+ uint32 W_IMG_CTRL4; /* 0x1B4 32 R/W WISHBONE Image4 Control register */
+ uint32 W_BA4; /* 0x1B8 32 R/W WISHBONE Image4 Base Address register */
+ uint32 W_AM4; /* 0x1BC 32 R/W WISHBONE Image4 Address Mask register */
+ uint32 W_TA4; /* 0x1C0 32 R/W WISHBONE Image4 Translation Address reg */
+ uint32 W_IMG_CTRL5; /* 0x1C4 32 R/W WISHBONE Image5 Control register */
+ uint32 W_BA5; /* 0x1C8 32 R/W WISHBONE Image5 Base Address register */
+ uint32 W_AM5; /* 0x1CC 32 R/W WISHBONE Image5 Address Mask register */
+ uint32 W_TA5; /* 0x1D0 32 R/W WISHBONE Image5 Translation Address reg */
+ uint32 W_ERR_CS; /* 0x1D4 32 R/W WISHBONE Error Control and Status reg */
+ uint32 W_ERR_ADDR; /* 0x1D8 32 R WISHBONE Erroneous Address register */
+ uint32 W_ERR_DATA; /* 0x1DC 32 R WISHBONE Erroneous Data register */
+ uint32 CNF_ADDR; /* 0x1E0 32 R/W Configuration Cycle register */
+ uint32 CNF_DATA; /* 0x1E4 32 R/W Configuration Cycle Generation Data reg */
+
+ uint32 INT_ACK; /* 0x1E8 32 R Interrupt Acknowledge register */
+ uint32 ICR; /* 0x1EC 32 R/W Interrupt Control register */
+ uint32 ISR; /* 0x1F0 32 R/W Interrupt Status register */
+} spih_pciregs_t;
+
+/*
+ * PCI Core interrupt enable and status bit definitions.
+ */
+
+/* PCI Core ICR Register bit definitions */
+#define PCI_INT_PROP_EN (1 << 0) /* Interrupt Propagation Enable */
+#define PCI_WB_ERR_INT_EN (1 << 1) /* Wishbone Error Interrupt Enable */
+#define PCI_PCI_ERR_INT_EN (1 << 2) /* PCI Error Interrupt Enable */
+#define PCI_PAR_ERR_INT_EN (1 << 3) /* Parity Error Interrupt Enable */
+#define PCI_SYS_ERR_INT_EN (1 << 4) /* System Error Interrupt Enable */
+#define PCI_SOFTWARE_RESET (1U << 31) /* Software reset of the PCI Core. */
+
+
+/* PCI Core ISR Register bit definitions */
+#define PCI_INT_PROP_ST (1 << 0) /* Interrupt Propagation Status */
+#define PCI_WB_ERR_INT_ST (1 << 1) /* Wishbone Error Interrupt Status */
+#define PCI_PCI_ERR_INT_ST (1 << 2) /* PCI Error Interrupt Status */
+#define PCI_PAR_ERR_INT_ST (1 << 3) /* Parity Error Interrupt Status */
+#define PCI_SYS_ERR_INT_ST (1 << 4) /* System Error Interrupt Status */
+
+
+/* Registers on the Wishbone bus */
+#define SPIH_CTLR_INTR (1 << 0) /* SPI Host Controller Core Interrupt */
+#define SPIH_DEV_INTR (1 << 1) /* SPI Device Interrupt */
+#define SPIH_WFIFO_INTR (1 << 2) /* SPI Tx FIFO Empty Intr (FPGA Rev >= 8) */
+
+/* GPIO Bit definitions */
+#define SPIH_CS (1 << 0) /* SPI Chip Select (active low) */
+#define SPIH_SLOT_POWER (1 << 1) /* SD Card Slot Power Enable */
+#define SPIH_CARD_DETECT (1 << 2) /* SD Card Detect */
+
+/* SPI Status Register Bit definitions */
+#define SPIH_STATE_MASK 0x30 /* SPI Transfer State Machine state mask */
+#define SPIH_STATE_SHIFT 4 /* SPI Transfer State Machine state shift */
+#define SPIH_WFFULL (1 << 3) /* SPI Write FIFO Full */
+#define SPIH_WFEMPTY (1 << 2) /* SPI Write FIFO Empty */
+#define SPIH_RFFULL (1 << 1) /* SPI Read FIFO Full */
+#define SPIH_RFEMPTY (1 << 0) /* SPI Read FIFO Empty */
+
+#define SPIH_EXT_CLK (1U << 31) /* Use External Clock as PLL Clock source. */
+
+#define SPIH_PLL_NO_CLK (1 << 1) /* Set to 1 if the PLL's input clock is lost. */
+#define SPIH_PLL_LOCKED (1 << 3) /* Set to 1 when the PLL is locked. */
+
+/* Spin bit loop bound check */
+#define SPI_SPIN_BOUND 0xf4240 /* 1 million */
+
+#endif /* _BCM_PCI_SPI_H */
diff --git a/drivers/net/wireless/ap6210/include/bcmperf.h b/drivers/net/wireless/ap6210/include/bcmperf.h
new file mode 100644
index 0000000..7438307
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmperf.h
@@ -0,0 +1,36 @@
+/*
+ * Performance counters software interface.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmperf.h 241182 2011-02-17 21:50:03Z $
+ */
+/* essai */
+#ifndef _BCMPERF_H_
+#define _BCMPERF_H_
+/* get cache hits and misses */
+#define BCMPERF_ENABLE_INSTRCOUNT()
+#define BCMPERF_ENABLE_ICACHE_MISS()
+#define BCMPERF_ENABLE_ICACHE_HIT()
+#define BCMPERF_GETICACHE_MISS(x) ((x) = 0)
+#define BCMPERF_GETICACHE_HIT(x) ((x) = 0)
+#define BCMPERF_GETINSTRCOUNT(x) ((x) = 0)
+#endif /* _BCMPERF_H_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmsdbus.h b/drivers/net/wireless/ap6210/include/bcmsdbus.h
new file mode 100644
index 0000000..2fa706d
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmsdbus.h
@@ -0,0 +1,152 @@
+/*
+ * Definitions for API from sdio common code (bcmsdh) to individual
+ * host controller drivers.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdbus.h 347614 2012-07-27 10:24:51Z $
+ */
+
+#ifndef _sdio_api_h_
+#define _sdio_api_h_
+
+
+#define SDIOH_API_RC_SUCCESS (0x00)
+#define SDIOH_API_RC_FAIL (0x01)
+#define SDIOH_API_SUCCESS(status) (status == 0)
+
+#define SDIOH_READ 0 /* Read request */
+#define SDIOH_WRITE 1 /* Write request */
+
+#define SDIOH_DATA_FIX 0 /* Fixed addressing */
+#define SDIOH_DATA_INC 1 /* Incremental addressing */
+
+#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */
+#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */
+#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */
+
+#define SDIOH_DATA_PIO 0 /* PIO mode */
+#define SDIOH_DATA_DMA 1 /* DMA mode */
+
+#ifdef BCMSDIOH_TXGLOM
+/* Max number of glommed pkts */
+#define SDPCM_MAXGLOM_SIZE 10
+#define SDPCM_DEFGLOM_SIZE 3
+
+#define SDPCM_TXGLOM_CPY 0 /* SDIO 2.0 should use copy mode */
+#define SDPCM_TXGLOM_MDESC 1 /* SDIO 3.0 should use multi-desc mode */
+#endif
+
+
+typedef int SDIOH_API_RC;
+
+/* SDio Host structure */
+typedef struct sdioh_info sdioh_info_t;
+
+/* callback function, taking one arg */
+typedef void (*sdioh_cb_fn_t)(void *);
+
+/* attach, return handler on success, NULL if failed.
+ * The handler shall be provided by all subsequent calls. No local cache
+ * cfghdl points to the starting address of pci device mapped memory
+ */
+extern sdioh_info_t * sdioh_attach(osl_t *osh, void *cfghdl, uint irq);
+extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *si);
+extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, sdioh_cb_fn_t fn, void *argh);
+extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si);
+
+/* query whether SD interrupt is enabled or not */
+extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff);
+
+/* enable or disable SD interrupt */
+extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable);
+
+#if defined(DHD_DEBUG)
+extern bool sdioh_interrupt_pending(sdioh_info_t *si);
+#endif
+
+/* read or write one byte using cmd52 */
+extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc, uint addr, uint8 *byte);
+
+/* read or write 2/4 bytes using cmd53 */
+extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type, uint rw, uint fnc,
+ uint addr, uint32 *word, uint nbyte);
+
+/* read or write any buffer using cmd53 */
+extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, uint fix_inc,
+ uint rw, uint fnc_num, uint32 addr, uint regwidth, uint32 buflen, uint8 *buffer,
+ void *pkt);
+
+#ifdef BCMSDIOH_TXGLOM
+extern void sdioh_glom_post(sdioh_info_t *sd, uint8 *frame, uint len);
+extern void sdioh_glom_clear(sdioh_info_t *sd);
+extern uint sdioh_set_mode(sdioh_info_t *sd, uint mode);
+extern bool sdioh_glom_enabled(void);
+#else
+#define sdioh_glom_post(a, b, c)
+#define sdioh_glom_clear(a)
+#define sdioh_set_mode(a) (0)
+#define sdioh_glom_enabled() (FALSE)
+#endif
+
+/* get cis data */
+extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, uint8 *cis, uint32 length);
+
+extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data);
+extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, uint32 addr, uint8 *data);
+
+/* query number of io functions */
+extern uint sdioh_query_iofnum(sdioh_info_t *si);
+
+/* handle iovars */
+extern int sdioh_iovar_op(sdioh_info_t *si, const char *name,
+ void *params, int plen, void *arg, int len, bool set);
+
+/* Issue abort to the specified function and clear controller as needed */
+extern int sdioh_abort(sdioh_info_t *si, uint fnc);
+
+/* Start and Stop SDIO without re-enumerating the SD card. */
+extern int sdioh_start(sdioh_info_t *si, int stage);
+extern int sdioh_stop(sdioh_info_t *si);
+
+/* Wait system lock free */
+extern int sdioh_waitlockfree(sdioh_info_t *si);
+
+/* Reset and re-initialize the device */
+extern int sdioh_sdio_reset(sdioh_info_t *si);
+
+/* Helper function */
+void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
+
+
+
+#if defined(BCMSDIOH_STD)
+ #define SDIOH_SLEEP_ENABLED
+#endif
+extern SDIOH_API_RC sdioh_sleep(sdioh_info_t *si, bool enab);
+
+/* GPIO support */
+extern SDIOH_API_RC sdioh_gpio_init(sdioh_info_t *sd);
+extern bool sdioh_gpioin(sdioh_info_t *sd, uint32 gpio);
+extern SDIOH_API_RC sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio);
+extern SDIOH_API_RC sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab);
+
+#endif /* _sdio_api_h_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmsdh.h b/drivers/net/wireless/ap6210/include/bcmsdh.h
new file mode 100644
index 0000000..8e5a563
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmsdh.h
@@ -0,0 +1,247 @@
+/*
+ * SDIO host client driver interface of Broadcom HNBU
+ * export functions to client drivers
+ * abstract OS and BUS specific details of SDIO
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdh.h 347614 2012-07-27 10:24:51Z $
+ */
+
+/**
+ * @file bcmsdh.h
+ */
+
+#ifndef _bcmsdh_h_
+#define _bcmsdh_h_
+
+#define BCMSDH_ERROR_VAL 0x0001 /* Error */
+#define BCMSDH_INFO_VAL 0x0002 /* Info */
+extern const uint bcmsdh_msglevel;
+
+#define BCMSDH_ERROR(x)
+#define BCMSDH_INFO(x)
+
+#if (defined(BCMSDIOH_STD) || defined(BCMSDIOH_BCM) || defined(BCMSDIOH_SPI))
+#define BCMSDH_ADAPTER
+#endif /* BCMSDIO && (BCMSDIOH_STD || BCMSDIOH_BCM || BCMSDIOH_SPI) */
+
+/* forward declarations */
+typedef struct bcmsdh_info bcmsdh_info_t;
+typedef void (*bcmsdh_cb_fn_t)(void *);
+
+/* Attach and build an interface to the underlying SD host driver.
+ * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh.
+ * - Returns the bcmsdh handle and virtual address base for register access.
+ * The returned handle should be used in all subsequent calls, but the bcmsh
+ * implementation may maintain a single "default" handle (e.g. the first or
+ * most recent one) to enable single-instance implementations to pass NULL.
+ */
+
+#if 0 && (NDISVER >= 0x0630) && 1
+extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl,
+ void **regsva, uint irq, shared_info_t *sh);
+#else
+extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq);
+#endif
+
+/* Detach - freeup resources allocated in attach */
+extern int bcmsdh_detach(osl_t *osh, void *sdh);
+
+/* Query if SD device interrupts are enabled */
+extern bool bcmsdh_intr_query(void *sdh);
+
+/* Enable/disable SD interrupt */
+extern int bcmsdh_intr_enable(void *sdh);
+extern int bcmsdh_intr_disable(void *sdh);
+
+/* Register/deregister device interrupt handler. */
+extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
+extern int bcmsdh_intr_dereg(void *sdh);
+/* Enable/disable SD card interrupt forward */
+extern void bcmsdh_intr_forward(void *sdh, bool pass);
+
+#if defined(DHD_DEBUG)
+/* Query pending interrupt status from the host controller */
+extern bool bcmsdh_intr_pending(void *sdh);
+#endif
+
+/* Register a callback to be called if and when bcmsdh detects
+ * device removal. No-op in the case of non-removable/hardwired devices.
+ */
+extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
+
+/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
+ * fn: function number
+ * addr: unmodified SDIO-space address
+ * data: data byte to write
+ * err: pointer to error code (or NULL)
+ */
+extern uint8 bcmsdh_cfg_read(void *sdh, uint func, uint32 addr, int *err);
+extern void bcmsdh_cfg_write(void *sdh, uint func, uint32 addr, uint8 data, int *err);
+
+/* Read/Write 4bytes from/to cfg space */
+extern uint32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err);
+extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err);
+
+/* Read CIS content for specified function.
+ * fn: function whose CIS is being requested (0 is common CIS)
+ * cis: pointer to memory location to place results
+ * length: number of bytes to read
+ * Internally, this routine uses the values from the cis base regs (0x9-0xB)
+ * to form an SDIO-space address to read the data from.
+ */
+extern int bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length);
+
+/* Synchronous access to device (client) core registers via CMD53 to F1.
+ * addr: backplane address (i.e. >= regsva from attach)
+ * size: register width in bytes (2 or 4)
+ * data: data for register write
+ */
+extern uint32 bcmsdh_reg_read(void *sdh, uint32 addr, uint size);
+extern uint32 bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data);
+
+/* set sb address window */
+extern int bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set);
+
+/* Indicate if last reg read/write failed */
+extern bool bcmsdh_regfail(void *sdh);
+
+/* Buffer transfer to/from device (client) core via cmd53.
+ * fn: function number
+ * addr: backplane address (i.e. >= regsva from attach)
+ * flags: backplane width, address increment, sync/async
+ * buf: pointer to memory data buffer
+ * nbytes: number of bytes to transfer to/from buf
+ * pkt: pointer to packet associated with buf (if any)
+ * complete: callback function for command completion (async only)
+ * handle: handle for completion callback (first arg in callback)
+ * Returns 0 or error code.
+ * NOTE: Async operation is not currently supported.
+ */
+typedef void (*bcmsdh_cmplt_fn_t)(void *handle, int status, bool sync_waiting);
+extern int bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags,
+ uint8 *buf, uint nbytes, void *pkt,
+ bcmsdh_cmplt_fn_t complete_fn, void *handle);
+extern int bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags,
+ uint8 *buf, uint nbytes, void *pkt,
+ bcmsdh_cmplt_fn_t complete_fn, void *handle);
+
+extern void bcmsdh_glom_post(void *sdh, uint8 *frame, uint len);
+extern void bcmsdh_glom_clear(void *sdh);
+extern uint bcmsdh_set_mode(void *sdh, uint mode);
+extern bool bcmsdh_glom_enabled(void);
+/* Flags bits */
+#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */
+#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */
+#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */
+#define SDIO_BYTE_MODE 0x8 /* Byte mode request(non-block mode) */
+
+/* Pending (non-error) return code */
+#define BCME_PENDING 1
+
+/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
+ * rw: read or write (0/1)
+ * addr: direct SDIO address
+ * buf: pointer to memory data buffer
+ * nbytes: number of bytes to transfer to/from buf
+ * Returns 0 or error code.
+ */
+extern int bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes);
+
+/* Issue an abort to the specified function */
+extern int bcmsdh_abort(void *sdh, uint fn);
+
+/* Start SDIO Host Controller communication */
+extern int bcmsdh_start(void *sdh, int stage);
+
+/* Stop SDIO Host Controller communication */
+extern int bcmsdh_stop(void *sdh);
+
+/* Wait system lock free */
+extern int bcmsdh_waitlockfree(void *sdh);
+
+/* Returns the "Device ID" of target device on the SDIO bus. */
+extern int bcmsdh_query_device(void *sdh);
+
+/* Returns the number of IO functions reported by the device */
+extern uint bcmsdh_query_iofnum(void *sdh);
+
+/* Miscellaneous knob tweaker. */
+extern int bcmsdh_iovar_op(void *sdh, const char *name,
+ void *params, int plen, void *arg, int len, bool set);
+
+/* Reset and reinitialize the device */
+extern int bcmsdh_reset(bcmsdh_info_t *sdh);
+
+/* helper functions */
+
+extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
+
+/* callback functions */
+typedef struct {
+ /* attach to device */
+ void *(*attach)(uint16 vend_id, uint16 dev_id, uint16 bus, uint16 slot,
+ uint16 func, uint bustype, void * regsva, osl_t * osh,
+ void * param);
+ /* detach from device */
+ void (*detach)(void *ch);
+} bcmsdh_driver_t;
+
+/* platform specific/high level functions */
+extern int bcmsdh_register(bcmsdh_driver_t *driver);
+extern void bcmsdh_unregister(void);
+extern bool bcmsdh_chipmatch(uint16 vendor, uint16 device);
+extern void bcmsdh_device_remove(void * sdh);
+
+extern int bcmsdh_reg_sdio_notify(void* semaphore);
+extern void bcmsdh_unreg_sdio_notify(void);
+
+extern int bcmsdh_set_drvdata(void * dhdp);
+
+#if defined(OOB_INTR_ONLY)
+extern int bcmsdh_register_oob_intr(void * dhdp);
+extern void bcmsdh_unregister_oob_intr(void);
+extern void bcmsdh_oob_intr_set(bool enable);
+#endif
+#if defined(HW_OOB)
+void bcmsdh_config_hw_oob_intr(bcmsdh_info_t *sdh, uint chip);
+#endif
+
+/* Function to pass device-status bits to DHD. */
+extern uint32 bcmsdh_get_dstatus(void *sdh);
+
+/* Function to return current window addr */
+extern uint32 bcmsdh_cur_sbwad(void *sdh);
+
+/* Function to pass chipid and rev to lower layers for controlling pr's */
+extern void bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev);
+
+
+extern int bcmsdh_sleep(void *sdh, bool enab);
+
+/* GPIO support */
+extern int bcmsdh_gpio_init(void *sd);
+extern bool bcmsdh_gpioin(void *sd, uint32 gpio);
+extern int bcmsdh_gpioouten(void *sd, uint32 gpio);
+extern int bcmsdh_gpioout(void *sd, uint32 gpio, bool enab);
+
+#endif /* _bcmsdh_h_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmsdh_sdmmc.h b/drivers/net/wireless/ap6210/include/bcmsdh_sdmmc.h
new file mode 100644
index 0000000..a169588
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmsdh_sdmmc.h
@@ -0,0 +1,109 @@
+/*
+ * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdh_sdmmc.h 366812 2012-11-05 13:49:32Z $
+ */
+
+#ifndef __BCMSDH_SDMMC_H__
+#define __BCMSDH_SDMMC_H__
+
+#define sd_sync_dma(sd, read, nbytes)
+#define sd_init_dma(sd)
+#define sd_ack_intr(sd)
+#define sd_wakeup(sd);
+
+/* Allocate/init/free per-OS private data */
+extern int sdioh_sdmmc_osinit(sdioh_info_t *sd);
+extern void sdioh_sdmmc_osfree(sdioh_info_t *sd);
+
+#define BLOCK_SIZE_4318 64
+#define BLOCK_SIZE_4328 512
+
+/* internal return code */
+#define SUCCESS 0
+#define ERROR 1
+
+/* private bus modes */
+#define SDIOH_MODE_SD4 2
+#define CLIENT_INTR 0x100 /* Get rid of this! */
+
+struct sdioh_info {
+ osl_t *osh; /* osh handler */
+ bool client_intr_enabled; /* interrupt connnected flag */
+ bool intr_handler_valid; /* client driver interrupt handler valid */
+ sdioh_cb_fn_t intr_handler; /* registered interrupt handler */
+ void *intr_handler_arg; /* argument to call interrupt handler */
+ uint16 intmask; /* Current active interrupts */
+ void *sdos_info; /* Pointer to per-OS private data */
+
+ uint irq; /* Client irq */
+ int intrcount; /* Client interrupts */
+
+ bool sd_use_dma; /* DMA on CMD53 */
+ bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */
+ /* Must be on for sd_multiblock to be effective */
+ bool use_client_ints; /* If this is false, make sure to restore */
+ int sd_mode; /* SD1/SD4/SPI */
+ int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
+ uint8 num_funcs; /* Supported funcs on client */
+ uint32 com_cis_ptr;
+ uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
+
+#define SDIOH_SDMMC_MAX_SG_ENTRIES 32
+ struct scatterlist sg_list[SDIOH_SDMMC_MAX_SG_ENTRIES];
+ bool use_rxchain;
+};
+
+/************************************************************
+ * Internal interfaces: per-port references into bcmsdh_sdmmc.c
+ */
+
+/* Global message bits */
+extern uint sd_msglevel;
+
+/* OS-independent interrupt handler */
+extern bool check_client_intr(sdioh_info_t *sd);
+
+/* Core interrupt enable/disable of device interrupts */
+extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
+
+
+/**************************************************************
+ * Internal interfaces: bcmsdh_sdmmc.c references to per-port code
+ */
+
+/* Register mapping routines */
+extern uint32 *sdioh_sdmmc_reg_map(osl_t *osh, int32 addr, int size);
+extern void sdioh_sdmmc_reg_unmap(osl_t *osh, int32 addr, int size);
+
+/* Interrupt (de)registration routines */
+extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq);
+extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd);
+
+typedef struct _BCMSDH_SDMMC_INSTANCE {
+ sdioh_info_t *sd;
+ struct sdio_func *func[SDIOD_MAX_IOFUNCS];
+} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE;
+
+#endif /* __BCMSDH_SDMMC_H__ */
diff --git a/drivers/net/wireless/ap6210/include/bcmsdpcm.h b/drivers/net/wireless/ap6210/include/bcmsdpcm.h
new file mode 100644
index 0000000..fb2ec3a
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmsdpcm.h
@@ -0,0 +1,281 @@
+/*
+ * Broadcom SDIO/PCMCIA
+ * Software-specific definitions shared between device and host side
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdpcm.h 362722 2012-10-12 23:55:55Z $
+ */
+
+#ifndef _bcmsdpcm_h_
+#define _bcmsdpcm_h_
+
+/*
+ * Software allocation of To SB Mailbox resources
+ */
+
+/* intstatus bits */
+#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */
+#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */
+#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */
+#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */
+
+#define I_TOSBMAIL (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT)
+
+/* tosbmailbox bits corresponding to intstatus bits */
+#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */
+#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */
+#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */
+#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */
+#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */
+
+/* tosbmailboxdata */
+#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */
+#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */
+
+/*
+ * Software allocation of To Host Mailbox resources
+ */
+
+/* intstatus bits */
+#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */
+#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */
+#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */
+#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */
+
+#define I_TOHOSTMAIL (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT)
+
+/* tohostmailbox bits corresponding to intstatus bits */
+#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */
+#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */
+#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */
+#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */
+#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */
+
+/* tohostmailboxdata */
+#define HMB_DATA_NAKHANDLED 0x01 /* we're ready to retransmit NAK'd frame to host */
+#define HMB_DATA_DEVREADY 0x02 /* we're ready to to talk to host after enable */
+#define HMB_DATA_FC 0x04 /* per prio flowcontrol update flag to host */
+#define HMB_DATA_FWREADY 0x08 /* firmware is ready for protocol activity */
+#define HMB_DATA_FWHALT 0x10 /* firmware has halted operation */
+
+#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */
+#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */
+
+#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */
+#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */
+
+/*
+ * Software-defined protocol header
+ */
+
+/* Current protocol version */
+#define SDPCM_PROT_VERSION 4
+
+/* SW frame header */
+#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */
+#define SDPCM_PACKET_SEQUENCE(p) (((uint8 *)p)[0] & 0xff) /* p starts w/SW Header */
+
+#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */
+#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */
+#define SDPCM_PACKET_CHANNEL(p) (((uint8 *)p)[1] & 0x0f) /* p starts w/SW Header */
+
+#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */
+#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */
+#define SDPCM_PACKET_FLAGS(p) ((((uint8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */
+
+/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */
+#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */
+#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */
+#define SDPCM_NEXTLEN_VALUE(p) ((((uint8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */
+#define SDPCM_NEXTLEN_OFFSET 2
+
+/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
+#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */
+#define SDPCM_DOFFSET_VALUE(p) (((uint8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
+#define SDPCM_DOFFSET_MASK 0xff000000
+#define SDPCM_DOFFSET_SHIFT 24
+
+#define SDPCM_FCMASK_OFFSET 4 /* Flow control */
+#define SDPCM_FCMASK_VALUE(p) (((uint8 *)p)[SDPCM_FCMASK_OFFSET ] & 0xff)
+#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */
+#define SDPCM_WINDOW_VALUE(p) (((uint8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
+#define SDPCM_VERSION_OFFSET 6 /* Version # */
+#define SDPCM_VERSION_VALUE(p) (((uint8 *)p)[SDPCM_VERSION_OFFSET] & 0xff)
+#define SDPCM_UNUSED_OFFSET 7 /* Spare */
+#define SDPCM_UNUSED_VALUE(p) (((uint8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff)
+
+#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */
+
+/* logical channel numbers */
+#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */
+#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */
+#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */
+#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */
+#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */
+#define SDPCM_MAX_CHANNEL 15
+
+#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */
+
+#define SDPCM_FLAG_RESVD0 0x01
+#define SDPCM_FLAG_RESVD1 0x02
+#define SDPCM_FLAG_GSPI_TXENAB 0x04
+#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */
+
+/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */
+#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT)
+
+#define SDPCM_GLOMDESC(p) (((uint8 *)p)[1] & 0x80)
+
+/* For TEST_CHANNEL packets, define another 4-byte header */
+#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2);
+ * Semantics of Ext byte depend on command.
+ * Len is current or requested frame length, not
+ * including test header; sent little-endian.
+ */
+#define SDPCM_TEST_PKT_CNT_FLD_LEN 4 /* Packet count filed legth */
+#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */
+#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */
+#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */
+#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count
+ * (Backward compatabilty) Set frame count in a
+ * 4 byte filed adjacent to the HDR
+ */
+#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off
+ * Set frame count in a 4 byte filed adjacent to
+ * the HDR
+ */
+
+/* Handy macro for filling in datagen packets with a pattern */
+#define SDPCM_TEST_FILL(byteno, id) ((uint8)(id + byteno))
+
+/*
+ * Software counters (first part matches hardware counters)
+ */
+
+typedef volatile struct {
+ uint32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */
+ uint32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */
+ uint32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */
+ uint32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */
+ uint32 abort; /* AbortCount, SDIO: aborts */
+ uint32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */
+ uint32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */
+ uint32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */
+ uint32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */
+ uint32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */
+ uint32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */
+ uint32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */
+ uint32 rxdescuflo; /* receive descriptor underflows */
+ uint32 rxfifooflo; /* receive fifo overflows */
+ uint32 txfifouflo; /* transmit fifo underflows */
+ uint32 runt; /* runt (too short) frames recv'd from bus */
+ uint32 badlen; /* frame's rxh len does not match its hw tag len */
+ uint32 badcksum; /* frame's hw tag chksum doesn't agree with len value */
+ uint32 seqbreak; /* break in sequence # space from one rx frame to the next */
+ uint32 rxfcrc; /* frame rx header indicates crc error */
+ uint32 rxfwoos; /* frame rx header indicates write out of sync */
+ uint32 rxfwft; /* frame rx header indicates write frame termination */
+ uint32 rxfabort; /* frame rx header indicates frame aborted */
+ uint32 woosint; /* write out of sync interrupt */
+ uint32 roosint; /* read out of sync interrupt */
+ uint32 rftermint; /* read frame terminate interrupt */
+ uint32 wftermint; /* write frame terminate interrupt */
+} sdpcmd_cnt_t;
+
+/*
+ * Register Access Macros
+ */
+
+#define SDIODREV_IS(var, val) ((var) == (val))
+#define SDIODREV_GE(var, val) ((var) >= (val))
+#define SDIODREV_GT(var, val) ((var) > (val))
+#define SDIODREV_LT(var, val) ((var) < (val))
+#define SDIODREV_LE(var, val) ((var) <= (val))
+
+#define SDIODDMAREG32(h, dir, chnl) \
+ ((dir) == DMA_TX ? \
+ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].xmt) : \
+ (void *)(uintptr)&((h)->regs->dma.sdiod32.dma32regs[chnl].rcv))
+
+#define SDIODDMAREG64(h, dir, chnl) \
+ ((dir) == DMA_TX ? \
+ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].xmt) : \
+ (void *)(uintptr)&((h)->regs->dma.sdiod64.dma64regs[chnl].rcv))
+
+#define SDIODDMAREG(h, dir, chnl) \
+ (SDIODREV_LT((h)->corerev, 1) ? \
+ SDIODDMAREG32((h), (dir), (chnl)) : \
+ SDIODDMAREG64((h), (dir), (chnl)))
+
+#define PCMDDMAREG(h, dir, chnl) \
+ ((dir) == DMA_TX ? \
+ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.xmt) : \
+ (void *)(uintptr)&((h)->regs->dma.pcm32.dmaregs.rcv))
+
+#define SDPCMDMAREG(h, dir, chnl, coreid) \
+ ((coreid) == SDIOD_CORE_ID ? \
+ SDIODDMAREG(h, dir, chnl) : \
+ PCMDDMAREG(h, dir, chnl))
+
+#define SDIODFIFOREG(h, corerev) \
+ (SDIODREV_LT((corerev), 1) ? \
+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod32.dmafifo)) : \
+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.sdiod64.dmafifo)))
+
+#define PCMDFIFOREG(h) \
+ ((dma32diag_t *)(uintptr)&((h)->regs->dma.pcm32.dmafifo))
+
+#define SDPCMFIFOREG(h, coreid, corerev) \
+ ((coreid) == SDIOD_CORE_ID ? \
+ SDIODFIFOREG(h, corerev) : \
+ PCMDFIFOREG(h))
+
+/*
+ * Shared structure between dongle and the host.
+ * The structure contains pointers to trap or assert information.
+ */
+#define SDPCM_SHARED_VERSION 0x0001
+#define SDPCM_SHARED_VERSION_MASK 0x00FF
+#define SDPCM_SHARED_ASSERT_BUILT 0x0100
+#define SDPCM_SHARED_ASSERT 0x0200
+#define SDPCM_SHARED_TRAP 0x0400
+#define SDPCM_SHARED_IN_BRPT 0x0800
+#define SDPCM_SHARED_SET_BRPT 0x1000
+#define SDPCM_SHARED_PENDING_BRPT 0x2000
+
+typedef struct {
+ uint32 flags;
+ uint32 trap_addr;
+ uint32 assert_exp_addr;
+ uint32 assert_file_addr;
+ uint32 assert_line;
+ uint32 console_addr; /* Address of hndrte_cons_t */
+ uint32 msgtrace_addr;
+ uint32 brpt_addr;
+} sdpcm_shared_t;
+
+extern sdpcm_shared_t sdpcm_shared;
+
+/* Function can be used to notify host of FW halt */
+extern void sdpcmd_fwhalt(void);
+
+#endif /* _bcmsdpcm_h_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmsdspi.h b/drivers/net/wireless/ap6210/include/bcmsdspi.h
new file mode 100644
index 0000000..9a7496b
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmsdspi.h
@@ -0,0 +1,119 @@
+/*
+ * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdspi.h 294363 2011-11-06 23:02:20Z $
+ */
+#ifndef _BCM_SD_SPI_H
+#define _BCM_SD_SPI_H
+
+#define BLOCK_SIZE_4318 64
+#define BLOCK_SIZE_4328 512
+
+/* internal return code */
+#define SUCCESS 0
+#undef ERROR
+#define ERROR 1
+
+/* private bus modes */
+#define SDIOH_MODE_SPI 0
+
+#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */
+#define USE_MULTIBLOCK 0x4
+
+struct sdioh_info {
+ uint cfg_bar; /* pci cfg address for bar */
+ uint32 caps; /* cached value of capabilities reg */
+ uint bar0; /* BAR0 for PCI Device */
+ osl_t *osh; /* osh handler */
+ void *controller; /* Pointer to SPI Controller's private data struct */
+
+ uint lockcount; /* nest count of sdspi_lock() calls */
+ bool client_intr_enabled; /* interrupt connnected flag */
+ bool intr_handler_valid; /* client driver interrupt handler valid */
+ sdioh_cb_fn_t intr_handler; /* registered interrupt handler */
+ void *intr_handler_arg; /* argument to call interrupt handler */
+ bool initialized; /* card initialized */
+ uint32 target_dev; /* Target device ID */
+ uint32 intmask; /* Current active interrupts */
+ void *sdos_info; /* Pointer to per-OS private data */
+
+ uint32 controller_type; /* Host controller type */
+ uint8 version; /* Host Controller Spec Compliance Version */
+ uint irq; /* Client irq */
+ uint32 intrcount; /* Client interrupts */
+ uint32 local_intrcount; /* Controller interrupts */
+ bool host_init_done; /* Controller initted */
+ bool card_init_done; /* Client SDIO interface initted */
+ bool polled_mode; /* polling for command completion */
+
+ bool sd_use_dma; /* DMA on CMD53 */
+ bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */
+ /* Must be on for sd_multiblock to be effective */
+ bool use_client_ints; /* If this is false, make sure to restore */
+ bool got_hcint; /* Host Controller interrupt. */
+ /* polling hack in wl_linux.c:wl_timer() */
+ int adapter_slot; /* Maybe dealing with multiple slots/controllers */
+ int sd_mode; /* SD1/SD4/SPI */
+ int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
+ uint32 data_xfer_count; /* Current register transfer size */
+ uint32 cmd53_wr_data; /* Used to pass CMD53 write data */
+ uint32 card_response; /* Used to pass back response status byte */
+ uint32 card_rsp_data; /* Used to pass back response data word */
+ uint16 card_rca; /* Current Address */
+ uint8 num_funcs; /* Supported funcs on client */
+ uint32 com_cis_ptr;
+ uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
+ void *dma_buf;
+ ulong dma_phys;
+ int r_cnt; /* rx count */
+ int t_cnt; /* tx_count */
+};
+
+/************************************************************
+ * Internal interfaces: per-port references into bcmsdspi.c
+ */
+
+/* Global message bits */
+extern uint sd_msglevel;
+
+/**************************************************************
+ * Internal interfaces: bcmsdspi.c references to per-port code
+ */
+
+/* Register mapping routines */
+extern uint32 *spi_reg_map(osl_t *osh, uintptr addr, int size);
+extern void spi_reg_unmap(osl_t *osh, uintptr addr, int size);
+
+/* Interrupt (de)registration routines */
+extern int spi_register_irq(sdioh_info_t *sd, uint irq);
+extern void spi_free_irq(uint irq, sdioh_info_t *sd);
+
+/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */
+extern void spi_lock(sdioh_info_t *sd);
+extern void spi_unlock(sdioh_info_t *sd);
+
+/* Allocate/init/free per-OS private data */
+extern int spi_osinit(sdioh_info_t *sd);
+extern void spi_osfree(sdioh_info_t *sd);
+
+#endif /* _BCM_SD_SPI_H */
diff --git a/drivers/net/wireless/ap6210/include/bcmsdstd.h b/drivers/net/wireless/ap6210/include/bcmsdstd.h
new file mode 100644
index 0000000..1c854b2
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmsdstd.h
@@ -0,0 +1,248 @@
+0/*
+ * 'Standard' SDIO HOST CONTROLLER driver
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmsdstd.h 347614 2012-07-27 10:24:51Z $
+ */
+#ifndef _BCM_SD_STD_H
+#define _BCM_SD_STD_H
+
+#define sd_sync_dma(sd, read, nbytes)
+#define sd_init_dma(sd)
+#define sd_ack_intr(sd)
+#define sd_wakeup(sd);
+/* Allocate/init/free per-OS private data */
+extern int sdstd_osinit(sdioh_info_t *sd);
+extern void sdstd_osfree(sdioh_info_t *sd);
+
+#define BLOCK_SIZE_4318 64
+#define BLOCK_SIZE_4328 512
+
+/* internal return code */
+#define SUCCESS 0
+#define ERROR 1
+
+/* private bus modes */
+#define SDIOH_MODE_SPI 0
+#define SDIOH_MODE_SD1 1
+#define SDIOH_MODE_SD4 2
+
+#define MAX_SLOTS 6 /* For PCI: Only 6 BAR entries => 6 slots */
+#define SDIOH_REG_WINSZ 0x100 /* Number of registers in Standard Host Controller */
+
+#define SDIOH_TYPE_ARASAN_HDK 1
+#define SDIOH_TYPE_BCM27XX 2
+#define SDIOH_TYPE_TI_PCIXX21 4 /* TI PCIxx21 Standard Host Controller */
+#define SDIOH_TYPE_RICOH_R5C822 5 /* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter */
+#define SDIOH_TYPE_JMICRON 6 /* JMicron Standard SDIO Host Controller */
+
+/* For linux, allow yielding for dongle */
+#define BCMSDYIELD
+
+/* Expected card status value for CMD7 */
+#define SDIOH_CMD7_EXP_STATUS 0x00001E00
+
+#define RETRIES_LARGE 100000
+#define sdstd_os_yield(sd) do {} while (0)
+#define RETRIES_SMALL 100
+
+
+#define USE_BLOCKMODE 0x2 /* Block mode can be single block or multi */
+#define USE_MULTIBLOCK 0x4
+
+#define USE_FIFO 0x8 /* Fifo vs non-fifo */
+
+#define CLIENT_INTR 0x100 /* Get rid of this! */
+
+#define HC_INTR_RETUNING 0x1000
+
+
+#ifdef BCMSDIOH_TXGLOM
+/* Setting the MAX limit to 10 */
+#define SDIOH_MAXGLOM_SIZE 10
+
+typedef struct glom_buf {
+ uint32 count; /* Total number of pkts queued */
+ void *dma_buf_arr[SDIOH_MAXGLOM_SIZE]; /* Frame address */
+ ulong dma_phys_arr[SDIOH_MAXGLOM_SIZE]; /* DMA_MAPed address of frames */
+ uint16 nbytes[SDIOH_MAXGLOM_SIZE]; /* Size of each frame */
+} glom_buf_t;
+#endif
+
+struct sdioh_info {
+ uint cfg_bar; /* pci cfg address for bar */
+ uint32 caps; /* cached value of capabilities reg */
+ uint32 curr_caps; /* max current capabilities reg */
+
+ osl_t *osh; /* osh handler */
+ volatile char *mem_space; /* pci device memory va */
+ uint lockcount; /* nest count of sdstd_lock() calls */
+ bool client_intr_enabled; /* interrupt connnected flag */
+ bool intr_handler_valid; /* client driver interrupt handler valid */
+ sdioh_cb_fn_t intr_handler; /* registered interrupt handler */
+ void *intr_handler_arg; /* argument to call interrupt handler */
+ bool initialized; /* card initialized */
+ uint target_dev; /* Target device ID */
+ uint16 intmask; /* Current active interrupts */
+ void *sdos_info; /* Pointer to per-OS private data */
+
+ uint32 controller_type; /* Host controller type */
+ uint8 version; /* Host Controller Spec Compliance Version */
+ uint irq; /* Client irq */
+ int intrcount; /* Client interrupts */
+ int local_intrcount; /* Controller interrupts */
+ bool host_init_done; /* Controller initted */
+ bool card_init_done; /* Client SDIO interface initted */
+ bool polled_mode; /* polling for command completion */
+
+ bool sd_blockmode; /* sd_blockmode == FALSE => 64 Byte Cmd 53s. */
+ /* Must be on for sd_multiblock to be effective */
+ bool use_client_ints; /* If this is false, make sure to restore */
+ /* polling hack in wl_linux.c:wl_timer() */
+ int adapter_slot; /* Maybe dealing with multiple slots/controllers */
+ int sd_mode; /* SD1/SD4/SPI */
+ int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */
+ uint32 data_xfer_count; /* Current transfer */
+ uint16 card_rca; /* Current Address */
+ int8 sd_dma_mode; /* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */
+ uint8 num_funcs; /* Supported funcs on client */
+ uint32 com_cis_ptr;
+ uint32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
+ void *dma_buf; /* DMA Buffer virtual address */
+ ulong dma_phys; /* DMA Buffer physical address */
+ void *adma2_dscr_buf; /* ADMA2 Descriptor Buffer virtual address */
+ ulong adma2_dscr_phys; /* ADMA2 Descriptor Buffer physical address */
+
+ /* adjustments needed to make the dma align properly */
+ void *dma_start_buf;
+ ulong dma_start_phys;
+ uint alloced_dma_size;
+ void *adma2_dscr_start_buf;
+ ulong adma2_dscr_start_phys;
+ uint alloced_adma2_dscr_size;
+
+ int r_cnt; /* rx count */
+ int t_cnt; /* tx_count */
+ bool got_hcint; /* local interrupt flag */
+ uint16 last_intrstatus; /* to cache intrstatus */
+ int host_UHSISupported; /* whether UHSI is supported for HC. */
+ int card_UHSI_voltage_Supported; /* whether UHSI is supported for
+ * Card in terms of Voltage [1.8 or 3.3].
+ */
+ int global_UHSI_Supp; /* type of UHSI support in both host and card.
+ * HOST_SDR_UNSUPP: capabilities not supported/matched
+ * HOST_SDR_12_25: SDR12 and SDR25 supported
+ * HOST_SDR_50_104_DDR: one of SDR50/SDR104 or DDR50 supptd
+ */
+ volatile int sd3_dat_state; /* data transfer state used for retuning check */
+ volatile int sd3_tun_state; /* tuning state used for retuning check */
+ bool sd3_tuning_reqd; /* tuning requirement parameter */
+ uint32 caps3; /* cached value of 32 MSbits capabilities reg (SDIO 3.0) */
+#ifdef BCMSDIOH_TXGLOM
+ glom_buf_t glom_info; /* pkt information used for glomming */
+ uint txglom_mode; /* Txglom mode: 0 - copy, 1 - multi-descriptor */
+#endif
+};
+
+#define DMA_MODE_NONE 0
+#define DMA_MODE_SDMA 1
+#define DMA_MODE_ADMA1 2
+#define DMA_MODE_ADMA2 3
+#define DMA_MODE_ADMA2_64 4
+#define DMA_MODE_AUTO -1
+
+#define USE_DMA(sd) ((bool)((sd->sd_dma_mode > 0) ? TRUE : FALSE))
+
+/* States for Tuning and corr data */
+#define TUNING_IDLE 0
+#define TUNING_START 1
+#define TUNING_START_AFTER_DAT 2
+#define TUNING_ONGOING 3
+
+#define DATA_TRANSFER_IDLE 0
+#define DATA_TRANSFER_ONGOING 1
+
+#define CHECK_TUNING_PRE_DATA 1
+#define CHECK_TUNING_POST_DATA 2
+
+/************************************************************
+ * Internal interfaces: per-port references into bcmsdstd.c
+ */
+
+/* Global message bits */
+extern uint sd_msglevel;
+
+/* OS-independent interrupt handler */
+extern bool check_client_intr(sdioh_info_t *sd);
+
+/* Core interrupt enable/disable of device interrupts */
+extern void sdstd_devintr_on(sdioh_info_t *sd);
+extern void sdstd_devintr_off(sdioh_info_t *sd);
+
+/* Enable/disable interrupts for local controller events */
+extern void sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err);
+extern void sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err);
+
+/* Wait for specified interrupt and error bits to be set */
+extern void sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err);
+
+
+/**************************************************************
+ * Internal interfaces: bcmsdstd.c references to per-port code
+ */
+
+/* Register mapping routines */
+extern uint32 *sdstd_reg_map(osl_t *osh, int32 addr, int size);
+extern void sdstd_reg_unmap(osl_t *osh, int32 addr, int size);
+
+/* Interrupt (de)registration routines */
+extern int sdstd_register_irq(sdioh_info_t *sd, uint irq);
+extern void sdstd_free_irq(uint irq, sdioh_info_t *sd);
+
+/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */
+extern void sdstd_lock(sdioh_info_t *sd);
+extern void sdstd_unlock(sdioh_info_t *sd);
+extern void sdstd_waitlockfree(sdioh_info_t *sd);
+
+/* OS-specific wait-for-interrupt-or-status */
+extern int sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield, uint16 *bits);
+
+/* used by bcmsdstd_linux [implemented in sdstd] */
+extern void sdstd_3_enable_retuning_int(sdioh_info_t *sd);
+extern void sdstd_3_disable_retuning_int(sdioh_info_t *sd);
+extern bool sdstd_3_is_retuning_int_set(sdioh_info_t *sd);
+extern void sdstd_3_check_and_do_tuning(sdioh_info_t *sd, int tuning_param);
+extern bool sdstd_3_check_and_set_retuning(sdioh_info_t *sd);
+extern int sdstd_3_get_tune_state(sdioh_info_t *sd);
+extern int sdstd_3_get_data_state(sdioh_info_t *sd);
+extern void sdstd_3_set_tune_state(sdioh_info_t *sd, int state);
+extern void sdstd_3_set_data_state(sdioh_info_t *sd, int state);
+extern uint8 sdstd_3_get_tuning_exp(sdioh_info_t *sd);
+extern uint32 sdstd_3_get_uhsi_clkmode(sdioh_info_t *sd);
+extern int sdstd_3_clk_tuning(sdioh_info_t *sd, uint32 sd3ClkMode);
+
+/* used by sdstd [implemented in bcmsdstd_linux/ndis] */
+extern void sdstd_3_start_tuning(sdioh_info_t *sd);
+extern void sdstd_3_osinit_tuning(sdioh_info_t *sd);
+extern void sdstd_3_osclean_tuning(sdioh_info_t *sd);
+
+#endif /* _BCM_SD_STD_H */
diff --git a/drivers/net/wireless/ap6210/include/bcmspi.h b/drivers/net/wireless/ap6210/include/bcmspi.h
new file mode 100644
index 0000000..e226cb1
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmspi.h
@@ -0,0 +1,40 @@
+/*
+ * Broadcom SPI Low-Level Hardware Driver API
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmspi.h 241182 2011-02-17 21:50:03Z $
+ */
+#ifndef _BCM_SPI_H
+#define _BCM_SPI_H
+
+extern void spi_devintr_off(sdioh_info_t *sd);
+extern void spi_devintr_on(sdioh_info_t *sd);
+extern bool spi_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor);
+extern bool spi_controller_highspeed_mode(sdioh_info_t *sd, bool hsmode);
+extern bool spi_check_client_intr(sdioh_info_t *sd, int *is_dev_intr);
+extern bool spi_hw_attach(sdioh_info_t *sd);
+extern bool spi_hw_detach(sdioh_info_t *sd);
+extern void spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen);
+extern void spi_spinbits(sdioh_info_t *sd);
+extern void spi_waitbits(sdioh_info_t *sd, bool yield);
+
+#endif /* _BCM_SPI_H */
diff --git a/drivers/net/wireless/ap6210/include/bcmutils.h b/drivers/net/wireless/ap6210/include/bcmutils.h
new file mode 100644
index 0000000..71af3dc
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmutils.h
@@ -0,0 +1,808 @@
+/*
+ * Misc useful os-independent macros and functions.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmutils.h 354837 2012-09-04 06:58:44Z $
+ */
+
+#ifndef _bcmutils_h_
+#define _bcmutils_h_
+
+#define bcm_strcpy_s(dst, noOfElements, src) strcpy((dst), (src))
+#define bcm_strncpy_s(dst, noOfElements, src, count) strncpy((dst), (src), (count))
+#define bcm_strcat_s(dst, noOfElements, src) strcat((dst), (src))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef PKTQ_LOG
+#include <wlioctl.h>
+#endif
+
+/* ctype replacement */
+#define _BCM_U 0x01 /* upper */
+#define _BCM_L 0x02 /* lower */
+#define _BCM_D 0x04 /* digit */
+#define _BCM_C 0x08 /* cntrl */
+#define _BCM_P 0x10 /* punct */
+#define _BCM_S 0x20 /* white space (space/lf/tab) */
+#define _BCM_X 0x40 /* hex digit */
+#define _BCM_SP 0x80 /* hard space (0x20) */
+
+extern const unsigned char bcm_ctype[];
+#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
+
+#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
+#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
+#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
+#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
+#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
+#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
+#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
+#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
+#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
+#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
+#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
+#define bcm_tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
+#define bcm_toupper(c) (bcm_islower((c)) ? ((c) + 'A' - 'a') : (c))
+
+/* Buffer structure for collecting string-formatted data
+* using bcm_bprintf() API.
+* Use bcm_binit() to initialize before use
+*/
+
+struct bcmstrbuf {
+ char *buf; /* pointer to current position in origbuf */
+ unsigned int size; /* current (residual) size in bytes */
+ char *origbuf; /* unmodified pointer to orignal buffer */
+ unsigned int origsize; /* unmodified orignal buffer size in bytes */
+};
+
+/* ** driver-only section ** */
+#ifdef BCMDRIVER
+#include <osl.h>
+
+#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */
+
+/*
+ * Spin at most 'us' microseconds while 'exp' is true.
+ * Caller should explicitly test 'exp' when this completes
+ * and take appropriate error action if 'exp' is still true.
+ */
+#define SPINWAIT(exp, us) { \
+ uint countdown = (us) + 9; \
+ while ((exp) && (countdown >= 10)) {\
+ OSL_DELAY(10); \
+ countdown -= 10; \
+ } \
+}
+
+/* osl multi-precedence packet queue */
+#ifndef PKTQ_LEN_DEFAULT
+#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */
+#endif
+#ifndef PKTQ_MAX_PREC
+#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */
+#endif
+
+typedef struct pktq_prec {
+ void *head; /* first packet to dequeue */
+ void *tail; /* last packet to dequeue */
+ uint16 len; /* number of queued packets */
+ uint16 max; /* maximum number of queued packets */
+} pktq_prec_t;
+
+#ifdef PKTQ_LOG
+typedef struct {
+ uint32 requested; /* packets requested to be stored */
+ uint32 stored; /* packets stored */
+ uint32 saved; /* packets saved,
+ because a lowest priority queue has given away one packet
+ */
+ uint32 selfsaved; /* packets saved,
+ because an older packet from the same queue has been dropped
+ */
+ uint32 full_dropped; /* packets dropped,
+ because pktq is full with higher precedence packets
+ */
+ uint32 dropped; /* packets dropped because pktq per that precedence is full */
+ uint32 sacrificed; /* packets dropped,
+ in order to save one from a queue of a highest priority
+ */
+ uint32 busy; /* packets droped because of hardware/transmission error */
+ uint32 retry; /* packets re-sent because they were not received */
+ uint32 ps_retry; /* packets retried again prior to moving power save mode */
+ uint32 retry_drop; /* packets finally dropped after retry limit */
+ uint32 max_avail; /* the high-water mark of the queue capacity for packets -
+ goes to zero as queue fills
+ */
+ uint32 max_used; /* the high-water mark of the queue utilisation for packets -
+ increases with use ('inverse' of max_avail)
+ */
+ uint32 queue_capacity; /* the maximum capacity of the queue */
+} pktq_counters_t;
+#endif /* PKTQ_LOG */
+
+
+#define PKTQ_COMMON \
+ uint16 num_prec; /* number of precedences in use */ \
+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ \
+ uint16 max; /* total max packets */ \
+ uint16 len; /* total number of packets */
+
+/* multi-priority pkt queue */
+struct pktq {
+ PKTQ_COMMON
+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
+ struct pktq_prec q[PKTQ_MAX_PREC];
+#ifdef PKTQ_LOG
+ pktq_counters_t _prec_cnt[PKTQ_MAX_PREC]; /* Counters per queue */
+#endif
+};
+
+/* simple, non-priority pkt queue */
+struct spktq {
+ PKTQ_COMMON
+ /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
+ struct pktq_prec q[1];
+};
+
+#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
+
+/* fn(pkt, arg). return true if pkt belongs to if */
+typedef bool (*ifpkt_cb_t)(void*, int);
+
+#ifdef BCMPKTPOOL
+#define POOL_ENAB(pool) ((pool) && (pool)->inited)
+#define SHARED_POOL (pktpool_shared)
+#else /* BCMPKTPOOL */
+#define POOL_ENAB(bus) 0
+#define SHARED_POOL ((struct pktpool *)NULL)
+#endif /* BCMPKTPOOL */
+
+#ifndef PKTPOOL_LEN_MAX
+#define PKTPOOL_LEN_MAX 40
+#endif /* PKTPOOL_LEN_MAX */
+#define PKTPOOL_CB_MAX 3
+
+struct pktpool;
+typedef void (*pktpool_cb_t)(struct pktpool *pool, void *arg);
+typedef struct {
+ pktpool_cb_t cb;
+ void *arg;
+} pktpool_cbinfo_t;
+
+#ifdef BCMDBG_POOL
+/* pkt pool debug states */
+#define POOL_IDLE 0
+#define POOL_RXFILL 1
+#define POOL_RXDH 2
+#define POOL_RXD11 3
+#define POOL_TXDH 4
+#define POOL_TXD11 5
+#define POOL_AMPDU 6
+#define POOL_TXENQ 7
+
+typedef struct {
+ void *p;
+ uint32 cycles;
+ uint32 dur;
+} pktpool_dbg_t;
+
+typedef struct {
+ uint8 txdh; /* tx to host */
+ uint8 txd11; /* tx to d11 */
+ uint8 enq; /* waiting in q */
+ uint8 rxdh; /* rx from host */
+ uint8 rxd11; /* rx from d11 */
+ uint8 rxfill; /* dma_rxfill */
+ uint8 idle; /* avail in pool */
+} pktpool_stats_t;
+#endif /* BCMDBG_POOL */
+
+typedef struct pktpool {
+ bool inited;
+ uint16 r;
+ uint16 w;
+ uint16 len;
+ uint16 maxlen;
+ uint16 plen;
+ bool istx;
+ bool empty;
+ uint8 cbtoggle;
+ uint8 cbcnt;
+ uint8 ecbcnt;
+ bool emptycb_disable;
+ pktpool_cbinfo_t *availcb_excl;
+ pktpool_cbinfo_t cbs[PKTPOOL_CB_MAX];
+ pktpool_cbinfo_t ecbs[PKTPOOL_CB_MAX];
+ void *q[PKTPOOL_LEN_MAX + 1];
+
+#ifdef BCMDBG_POOL
+ uint8 dbg_cbcnt;
+ pktpool_cbinfo_t dbg_cbs[PKTPOOL_CB_MAX];
+ uint16 dbg_qlen;
+ pktpool_dbg_t dbg_q[PKTPOOL_LEN_MAX + 1];
+#endif
+} pktpool_t;
+
+extern pktpool_t *pktpool_shared;
+
+extern int pktpool_init(osl_t *osh, pktpool_t *pktp, int *pktplen, int plen, bool istx);
+extern int pktpool_deinit(osl_t *osh, pktpool_t *pktp);
+extern int pktpool_fill(osl_t *osh, pktpool_t *pktp, bool minimal);
+extern void* pktpool_get(pktpool_t *pktp);
+extern void pktpool_free(pktpool_t *pktp, void *p);
+extern int pktpool_add(pktpool_t *pktp, void *p);
+extern uint16 pktpool_avail(pktpool_t *pktp);
+extern int pktpool_avail_notify_normal(osl_t *osh, pktpool_t *pktp);
+extern int pktpool_avail_notify_exclusive(osl_t *osh, pktpool_t *pktp, pktpool_cb_t cb);
+extern int pktpool_avail_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
+extern int pktpool_empty_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
+extern int pktpool_setmaxlen(pktpool_t *pktp, uint16 maxlen);
+extern int pktpool_setmaxlen_strict(osl_t *osh, pktpool_t *pktp, uint16 maxlen);
+extern void pktpool_emptycb_disable(pktpool_t *pktp, bool disable);
+extern bool pktpool_emptycb_disabled(pktpool_t *pktp);
+
+#define POOLPTR(pp) ((pktpool_t *)(pp))
+#define pktpool_len(pp) (POOLPTR(pp)->len - 1)
+#define pktpool_plen(pp) (POOLPTR(pp)->plen)
+#define pktpool_maxlen(pp) (POOLPTR(pp)->maxlen)
+
+#ifdef BCMDBG_POOL
+extern int pktpool_dbg_register(pktpool_t *pktp, pktpool_cb_t cb, void *arg);
+extern int pktpool_start_trigger(pktpool_t *pktp, void *p);
+extern int pktpool_dbg_dump(pktpool_t *pktp);
+extern int pktpool_dbg_notify(pktpool_t *pktp);
+extern int pktpool_stats_dump(pktpool_t *pktp, pktpool_stats_t *stats);
+#endif /* BCMDBG_POOL */
+
+/* forward definition of ether_addr structure used by some function prototypes */
+
+struct ether_addr;
+
+extern int ether_isbcast(const void *ea);
+extern int ether_isnulladdr(const void *ea);
+
+/* operations on a specific precedence in packet queue */
+
+#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max))
+#define pktq_pmax(pq, prec) ((pq)->q[prec].max)
+#define pktq_plen(pq, prec) ((pq)->q[prec].len)
+#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len)
+#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max)
+#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0)
+
+#define pktq_ppeek(pq, prec) ((pq)->q[prec].head)
+#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail)
+
+extern void *pktq_penq(struct pktq *pq, int prec, void *p);
+extern void *pktq_penq_head(struct pktq *pq, int prec, void *p);
+extern void *pktq_pdeq(struct pktq *pq, int prec);
+extern void *pktq_pdeq_prev(struct pktq *pq, int prec, void *prev_p);
+extern void *pktq_pdeq_tail(struct pktq *pq, int prec);
+/* Empty the queue at particular precedence level */
+extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir,
+ ifpkt_cb_t fn, int arg);
+/* Remove a specified packet from its queue */
+extern bool pktq_pdel(struct pktq *pq, void *p, int prec);
+
+/* operations on a set of precedences in packet queue */
+
+extern int pktq_mlen(struct pktq *pq, uint prec_bmp);
+extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out);
+extern void *pktq_mpeek(struct pktq *pq, uint prec_bmp, int *prec_out);
+
+/* operations on packet queue as a whole */
+
+#define pktq_len(pq) ((int)(pq)->len)
+#define pktq_max(pq) ((int)(pq)->max)
+#define pktq_avail(pq) ((int)((pq)->max - (pq)->len))
+#define pktq_full(pq) ((pq)->len >= (pq)->max)
+#define pktq_empty(pq) ((pq)->len == 0)
+
+/* operations for single precedence queues */
+#define pktenq(pq, p) pktq_penq(((struct pktq *)(void *)pq), 0, (p))
+#define pktenq_head(pq, p) pktq_penq_head(((struct pktq *)(void *)pq), 0, (p))
+#define pktdeq(pq) pktq_pdeq(((struct pktq *)(void *)pq), 0)
+#define pktdeq_tail(pq) pktq_pdeq_tail(((struct pktq *)(void *)pq), 0)
+#define pktqinit(pq, len) pktq_init(((struct pktq *)(void *)pq), 1, len)
+
+extern void pktq_init(struct pktq *pq, int num_prec, int max_len);
+extern void pktq_set_max_plen(struct pktq *pq, int prec, int max_len);
+
+/* prec_out may be NULL if caller is not interested in return value */
+extern void *pktq_deq(struct pktq *pq, int *prec_out);
+extern void *pktq_deq_tail(struct pktq *pq, int *prec_out);
+extern void *pktq_peek(struct pktq *pq, int *prec_out);
+extern void *pktq_peek_tail(struct pktq *pq, int *prec_out);
+extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg);
+
+/* externs */
+/* packet */
+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
+extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, uchar *buf);
+extern uint pkttotlen(osl_t *osh, void *p);
+extern void *pktlast(osl_t *osh, void *p);
+extern uint pktsegcnt(osl_t *osh, void *p);
+extern uint pktsegcnt_war(osl_t *osh, void *p);
+extern uint8 *pktoffset(osl_t *osh, void *p, uint offset);
+
+/* Get priority from a packet and pass it back in scb (or equiv) */
+#define PKTPRIO_VDSCP 0x100 /* DSCP prio found after VLAN tag */
+#define PKTPRIO_VLAN 0x200 /* VLAN prio found */
+#define PKTPRIO_UPD 0x400 /* DSCP used to update VLAN prio */
+#define PKTPRIO_DSCP 0x800 /* DSCP prio found */
+
+extern uint pktsetprio(void *pkt, bool update_vtag);
+
+/* string */
+extern int bcm_atoi(const char *s);
+extern ulong bcm_strtoul(const char *cp, char **endp, uint base);
+extern char *bcmstrstr(const char *haystack, const char *needle);
+extern char *bcmstrcat(char *dest, const char *src);
+extern char *bcmstrncat(char *dest, const char *src, uint size);
+extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen);
+char* bcmstrtok(char **string, const char *delimiters, char *tokdelim);
+int bcmstricmp(const char *s1, const char *s2);
+int bcmstrnicmp(const char* s1, const char* s2, int cnt);
+
+
+/* ethernet address */
+extern char *bcm_ether_ntoa(const struct ether_addr *ea, char *buf);
+extern int bcm_ether_atoe(const char *p, struct ether_addr *ea);
+
+/* ip address */
+struct ipv4_addr;
+extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf);
+
+/* delay */
+extern void bcm_mdelay(uint ms);
+/* variable access */
+#define NVRAM_RECLAIM_CHECK(name)
+
+extern char *getvar(char *vars, const char *name);
+extern int getintvar(char *vars, const char *name);
+extern int getintvararray(char *vars, const char *name, int index);
+extern int getintvararraysize(char *vars, const char *name);
+extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
+#define bcm_perf_enable()
+#define bcmstats(fmt)
+#define bcmlog(fmt, a1, a2)
+#define bcmdumplog(buf, size) *buf = '\0'
+#define bcmdumplogent(buf, idx) -1
+
+#define bcmtslog(tstamp, fmt, a1, a2)
+#define bcmprinttslogs()
+#define bcmprinttstamp(us)
+#define bcmdumptslog(buf, size)
+
+extern char *bcm_nvram_vars(uint *length);
+extern int bcm_nvram_cache(void *sih);
+
+/* Support for sharing code across in-driver iovar implementations.
+ * The intent is that a driver use this structure to map iovar names
+ * to its (private) iovar identifiers, and the lookup function to
+ * find the entry. Macros are provided to map ids and get/set actions
+ * into a single number space for a switch statement.
+ */
+
+/* iovar structure */
+typedef struct bcm_iovar {
+ const char *name; /* name for lookup and display */
+ uint16 varid; /* id for switch */
+ uint16 flags; /* driver-specific flag bits */
+ uint16 type; /* base type of argument */
+ uint16 minlen; /* min length for buffer vars */
+} bcm_iovar_t;
+
+/* varid definitions are per-driver, may use these get/set bits */
+
+/* IOVar action bits for id mapping */
+#define IOV_GET 0 /* Get an iovar */
+#define IOV_SET 1 /* Set an iovar */
+
+/* Varid to actionid mapping */
+#define IOV_GVAL(id) ((id) * 2)
+#define IOV_SVAL(id) ((id) * 2 + IOV_SET)
+#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET)
+#define IOV_ID(actionid) (actionid >> 1)
+
+/* flags are per-driver based on driver attributes */
+
+extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name);
+extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set);
+#if defined(WLTINYDUMP) || defined(WLMSG_INFORM) || defined(WLMSG_ASSOC) || \
+ defined(WLMSG_PRPKT) || defined(WLMSG_WSEC)
+extern int bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len);
+#endif
+#endif /* BCMDRIVER */
+
+/* Base type definitions */
+#define IOVT_VOID 0 /* no value (implictly set only) */
+#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */
+#define IOVT_INT8 2 /* integer values are range-checked */
+#define IOVT_UINT8 3 /* unsigned int 8 bits */
+#define IOVT_INT16 4 /* int 16 bits */
+#define IOVT_UINT16 5 /* unsigned int 16 bits */
+#define IOVT_INT32 6 /* int 32 bits */
+#define IOVT_UINT32 7 /* unsigned int 32 bits */
+#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */
+#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER)
+
+/* Initializer for IOV type strings */
+#define BCM_IOV_TYPE_INIT { \
+ "void", \
+ "bool", \
+ "int8", \
+ "uint8", \
+ "int16", \
+ "uint16", \
+ "int32", \
+ "uint32", \
+ "buffer", \
+ "" }
+
+#define BCM_IOVT_IS_INT(type) (\
+ (type == IOVT_BOOL) || \
+ (type == IOVT_INT8) || \
+ (type == IOVT_UINT8) || \
+ (type == IOVT_INT16) || \
+ (type == IOVT_UINT16) || \
+ (type == IOVT_INT32) || \
+ (type == IOVT_UINT32))
+
+/* ** driver/apps-shared section ** */
+
+#define BCME_STRLEN 64 /* Max string length for BCM errors */
+#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST))
+
+
+/*
+ * error codes could be added but the defined ones shouldn't be changed/deleted
+ * these error codes are exposed to the user code
+ * when ever a new error code is added to this list
+ * please update errorstring table with the related error string and
+ * update osl files with os specific errorcode map
+*/
+
+#define BCME_OK 0 /* Success */
+#define BCME_ERROR -1 /* Error generic */
+#define BCME_BADARG -2 /* Bad Argument */
+#define BCME_BADOPTION -3 /* Bad option */
+#define BCME_NOTUP -4 /* Not up */
+#define BCME_NOTDOWN -5 /* Not down */
+#define BCME_NOTAP -6 /* Not AP */
+#define BCME_NOTSTA -7 /* Not STA */
+#define BCME_BADKEYIDX -8 /* BAD Key Index */
+#define BCME_RADIOOFF -9 /* Radio Off */
+#define BCME_NOTBANDLOCKED -10 /* Not band locked */
+#define BCME_NOCLK -11 /* No Clock */
+#define BCME_BADRATESET -12 /* BAD Rate valueset */
+#define BCME_BADBAND -13 /* BAD Band */
+#define BCME_BUFTOOSHORT -14 /* Buffer too short */
+#define BCME_BUFTOOLONG -15 /* Buffer too long */
+#define BCME_BUSY -16 /* Busy */
+#define BCME_NOTASSOCIATED -17 /* Not Associated */
+#define BCME_BADSSIDLEN -18 /* Bad SSID len */
+#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */
+#define BCME_BADCHAN -20 /* Bad Channel */
+#define BCME_BADADDR -21 /* Bad Address */
+#define BCME_NORESOURCE -22 /* Not Enough Resources */
+#define BCME_UNSUPPORTED -23 /* Unsupported */
+#define BCME_BADLEN -24 /* Bad length */
+#define BCME_NOTREADY -25 /* Not Ready */
+#define BCME_EPERM -26 /* Not Permitted */
+#define BCME_NOMEM -27 /* No Memory */
+#define BCME_ASSOCIATED -28 /* Associated */
+#define BCME_RANGE -29 /* Not In Range */
+#define BCME_NOTFOUND -30 /* Not Found */
+#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */
+#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */
+#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */
+#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */
+#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */
+#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */
+#define BCME_VERSION -37 /* Incorrect version */
+#define BCME_TXFAIL -38 /* TX failure */
+#define BCME_RXFAIL -39 /* RX failure */
+#define BCME_NODEVICE -40 /* Device not present */
+#define BCME_NMODE_DISABLED -41 /* NMODE disabled */
+#define BCME_NONRESIDENT -42 /* access to nonresident overlay */
+#define BCME_LAST BCME_NONRESIDENT
+
+/* These are collection of BCME Error strings */
+#define BCMERRSTRINGTABLE { \
+ "OK", \
+ "Undefined error", \
+ "Bad Argument", \
+ "Bad Option", \
+ "Not up", \
+ "Not down", \
+ "Not AP", \
+ "Not STA", \
+ "Bad Key Index", \
+ "Radio Off", \
+ "Not band locked", \
+ "No clock", \
+ "Bad Rate valueset", \
+ "Bad Band", \
+ "Buffer too short", \
+ "Buffer too long", \
+ "Busy", \
+ "Not Associated", \
+ "Bad SSID len", \
+ "Out of Range Channel", \
+ "Bad Channel", \
+ "Bad Address", \
+ "Not Enough Resources", \
+ "Unsupported", \
+ "Bad length", \
+ "Not Ready", \
+ "Not Permitted", \
+ "No Memory", \
+ "Associated", \
+ "Not In Range", \
+ "Not Found", \
+ "WME Not Enabled", \
+ "TSPEC Not Found", \
+ "ACM Not Supported", \
+ "Not WME Association", \
+ "SDIO Bus Error", \
+ "Dongle Not Accessible", \
+ "Incorrect version", \
+ "TX Failure", \
+ "RX Failure", \
+ "Device Not Present", \
+ "NMODE Disabled", \
+ "Nonresident overlay access", \
+}
+
+#ifndef ABS
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+#endif /* ABS */
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif /* MIN */
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif /* MAX */
+
+#define CEIL(x, y) (((x) + ((y) - 1)) / (y))
+#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
+#define ISALIGNED(a, x) (((uintptr)(a) & ((x) - 1)) == 0)
+#define ALIGN_ADDR(addr, boundary) (void *)(((uintptr)(addr) + (boundary) - 1) \
+ & ~((boundary) - 1))
+#define ALIGN_SIZE(size, boundary) (((size) + (boundary) - 1) \
+ & ~((boundary) - 1))
+#define ISPOWEROF2(x) ((((x) - 1) & (x)) == 0)
+#define VALID_MASK(mask) !((mask) & ((mask) + 1))
+
+#ifndef OFFSETOF
+#ifdef __ARMCC_VERSION
+/*
+ * The ARM RVCT compiler complains when using OFFSETOF where a constant
+ * expression is expected, such as an initializer for a static object.
+ * offsetof from the runtime library doesn't have that problem.
+ */
+#include <stddef.h>
+#define OFFSETOF(type, member) offsetof(type, member)
+#else
+#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
+#endif /* __ARMCC_VERSION */
+#endif /* OFFSETOF */
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
+#endif
+
+/* Reference a function; used to prevent a static function from being optimized out */
+extern void *_bcmutils_dummy_fn;
+#define REFERENCE_FUNCTION(f) (_bcmutils_dummy_fn = (void *)(f))
+
+/* bit map related macros */
+#ifndef setbit
+#ifndef NBBY /* the BSD family defines NBBY */
+#define NBBY 8 /* 8 bits per byte */
+#endif /* #ifndef NBBY */
+#define setbit(a, i) (((uint8 *)a)[(i) / NBBY] |= 1 << ((i) % NBBY))
+#define clrbit(a, i) (((uint8 *)a)[(i) / NBBY] &= ~(1 << ((i) % NBBY)))
+#define isset(a, i) (((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY)))
+#define isclr(a, i) ((((const uint8 *)a)[(i) / NBBY] & (1 << ((i) % NBBY))) == 0)
+#endif /* setbit */
+
+#define NBITS(type) (sizeof(type) * 8)
+#define NBITVAL(nbits) (1 << (nbits))
+#define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
+#define NBITMASK(nbits) MAXBITVAL(nbits)
+#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
+
+/* basic mux operation - can be optimized on several architectures */
+#define MUX(pred, true, false) ((pred) ? (true) : (false))
+
+/* modulo inc/dec - assumes x E [0, bound - 1] */
+#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
+#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
+
+/* modulo inc/dec, bound = 2^k */
+#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
+#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
+
+/* modulo add/sub - assumes x, y E [0, bound - 1] */
+#define MODADD(x, y, bound) \
+ MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
+#define MODSUB(x, y, bound) \
+ MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
+
+/* module add/sub, bound = 2^k */
+#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
+#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
+
+/* crc defines */
+#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
+#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
+#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
+#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
+
+/* use for direct output of MAC address in printf etc */
+#define MACF "%02x:%02x:%02x:%02x:%02x:%02x"
+#define ETHERP_TO_MACF(ea) ((struct ether_addr *) (ea))->octet[0], \
+ ((struct ether_addr *) (ea))->octet[1], \
+ ((struct ether_addr *) (ea))->octet[2], \
+ ((struct ether_addr *) (ea))->octet[3], \
+ ((struct ether_addr *) (ea))->octet[4], \
+ ((struct ether_addr *) (ea))->octet[5]
+
+#define ETHER_TO_MACF(ea) (ea).octet[0], \
+ (ea).octet[1], \
+ (ea).octet[2], \
+ (ea).octet[3], \
+ (ea).octet[4], \
+ (ea).octet[5]
+#if !defined(SIMPLE_MAC_PRINT)
+#define MACDBG "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC2STRDBG(ea) (ea)[0], (ea)[1], (ea)[2], (ea)[3], (ea)[4], (ea)[5]
+#else
+#define MACDBG "%02x:%02x:%02x"
+#define MAC2STRDBG(ea) (ea)[0], (ea)[4], (ea)[5]
+#endif /* SIMPLE_MAC_PRINT */
+
+/* bcm_format_flags() bit description structure */
+typedef struct bcm_bit_desc {
+ uint32 bit;
+ const char* name;
+} bcm_bit_desc_t;
+
+/* tag_ID/length/value_buffer tuple */
+typedef struct bcm_tlv {
+ uint8 id;
+ uint8 len;
+ uint8 data[1];
+} bcm_tlv_t;
+
+/* Check that bcm_tlv_t fits into the given buflen */
+#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
+
+/* buffer length for ethernet address from bcm_ether_ntoa() */
+#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */
+
+/* crypto utility function */
+/* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */
+static INLINE void
+xor_128bit_block(const uint8 *src1, const uint8 *src2, uint8 *dst)
+{
+ if (
+#ifdef __i386__
+ 1 ||
+#endif
+ (((uintptr)src1 | (uintptr)src2 | (uintptr)dst) & 3) == 0) {
+ /* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */
+ /* x86 supports unaligned. This version runs 6x-9x faster on x86. */
+ ((uint32 *)dst)[0] = ((const uint32 *)src1)[0] ^ ((const uint32 *)src2)[0];
+ ((uint32 *)dst)[1] = ((const uint32 *)src1)[1] ^ ((const uint32 *)src2)[1];
+ ((uint32 *)dst)[2] = ((const uint32 *)src1)[2] ^ ((const uint32 *)src2)[2];
+ ((uint32 *)dst)[3] = ((const uint32 *)src1)[3] ^ ((const uint32 *)src2)[3];
+ } else {
+ /* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */
+ int k;
+ for (k = 0; k < 16; k++)
+ dst[k] = src1[k] ^ src2[k];
+ }
+}
+
+/* externs */
+/* crc */
+extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc);
+extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc);
+extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc);
+
+/* format/print */
+#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \
+ defined(WLMSG_ASSOC)
+extern int bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, int len);
+#endif
+
+#if defined(DHD_DEBUG) || defined(WLMSG_PRHDRS) || defined(WLMSG_PRPKT) || \
+ defined(WLMSG_ASSOC) || defined(WLMEDIA_PEAKRATE)
+extern int bcm_format_hex(char *str, const void *bytes, int len);
+#endif
+
+extern const char *bcm_crypto_algo_name(uint algo);
+extern char *bcm_chipname(uint chipid, char *buf, uint len);
+extern char *bcm_brev_str(uint32 brev, char *buf);
+extern void printbig(char *buf);
+extern void prhex(const char *msg, uchar *buf, uint len);
+
+/* IE parsing */
+extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
+extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
+extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key);
+
+/* bcmerror */
+extern const char *bcmerrorstr(int bcmerror);
+extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
+
+/* multi-bool data type: set of bools, mbool is true if any is set */
+typedef uint32 mbool;
+#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */
+#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */
+#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* TRUE if one bool is set */
+#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
+
+/* generic datastruct to help dump routines */
+struct fielddesc {
+ const char *nameandfmt;
+ uint32 offset;
+ uint32 len;
+};
+
+extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
+extern void bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, uint8 *buf, int len);
+
+extern void bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount);
+extern int bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes);
+extern void bcm_print_bytes(const char *name, const uchar *cdata, int len);
+
+typedef uint32 (*bcmutl_rdreg_rtn)(void *arg0, uint arg1, uint32 offset);
+extern uint bcmdumpfields(bcmutl_rdreg_rtn func_ptr, void *arg0, uint arg1, struct fielddesc *str,
+ char *buf, uint32 bufsize);
+extern uint bcm_bitcount(uint8 *bitmap, uint bytelength);
+
+extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
+
+/* power conversion */
+extern uint16 bcm_qdbm_to_mw(uint8 qdbm);
+extern uint8 bcm_mw_to_qdbm(uint16 mw);
+extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
+
+unsigned int process_nvram_vars(char *varbuf, unsigned int len);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _bcmutils_h_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmwifi_channels.h b/drivers/net/wireless/ap6210/include/bcmwifi_channels.h
new file mode 100644
index 0000000..bc57aca
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmwifi_channels.h
@@ -0,0 +1,490 @@
+/*
+ * Misc utility routines for WL and Apps
+ * This header file housing the define and function prototype use by
+ * both the wl driver, tools & Apps.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmwifi_channels.h 309193 2012-01-19 00:03:57Z $
+ */
+
+#ifndef _bcmwifi_channels_h_
+#define _bcmwifi_channels_h_
+
+
+/* A chanspec holds the channel number, band, bandwidth and control sideband */
+typedef uint16 chanspec_t;
+
+/* channel defines */
+#define CH_UPPER_SB 0x01
+#define CH_LOWER_SB 0x02
+#define CH_EWA_VALID 0x04
+#define CH_80MHZ_APART 16
+#define CH_40MHZ_APART 8
+#define CH_20MHZ_APART 4
+#define CH_10MHZ_APART 2
+#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
+#define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
+#define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216,
+ * this is that + 1 rounded up to a multiple of NBBY (8).
+ * DO NOT MAKE it > 255: channels are uint8's all over
+ */
+#define CHSPEC_CTLOVLP(sp1, sp2, sep) ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (sep)
+
+/* All builds use the new 11ac ratespec/chanspec */
+#undef D11AC_IOTYPES
+#define D11AC_IOTYPES
+
+#ifndef D11AC_IOTYPES
+
+#define WL_CHANSPEC_CHAN_MASK 0x00ff
+#define WL_CHANSPEC_CHAN_SHIFT 0
+
+#define WL_CHANSPEC_CTL_SB_MASK 0x0300
+#define WL_CHANSPEC_CTL_SB_SHIFT 8
+#define WL_CHANSPEC_CTL_SB_LOWER 0x0100
+#define WL_CHANSPEC_CTL_SB_UPPER 0x0200
+#define WL_CHANSPEC_CTL_SB_NONE 0x0300
+
+#define WL_CHANSPEC_BW_MASK 0x0C00
+#define WL_CHANSPEC_BW_SHIFT 10
+#define WL_CHANSPEC_BW_10 0x0400
+#define WL_CHANSPEC_BW_20 0x0800
+#define WL_CHANSPEC_BW_40 0x0C00
+
+#define WL_CHANSPEC_BAND_MASK 0xf000
+#define WL_CHANSPEC_BAND_SHIFT 12
+#ifdef WL_CHANSPEC_BAND_5G
+#undef WL_CHANSPEC_BAND_5G
+#endif
+#ifdef WL_CHANSPEC_BAND_2G
+#undef WL_CHANSPEC_BAND_2G
+#endif
+#define WL_CHANSPEC_BAND_5G 0x1000
+#define WL_CHANSPEC_BAND_2G 0x2000
+#define INVCHANSPEC 255
+
+/* channel defines */
+#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0)
+#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
+ ((channel) + CH_10MHZ_APART) : 0)
+#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
+#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
+ WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
+#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
+ ((channel) + CH_20MHZ_APART) : 0)
+#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
+ WL_CHANSPEC_BAND_5G))
+#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK))
+#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
+
+/* chanspec stores radio channel & flags to indicate control channel location, i.e. upper/lower */
+#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
+#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
+
+#ifdef WL11N_20MHZONLY
+
+#define CHSPEC_IS10(chspec) 0
+#define CHSPEC_IS20(chspec) 1
+#ifndef CHSPEC_IS40
+#define CHSPEC_IS40(chspec) 0
+#endif
+
+#else /* !WL11N_20MHZONLY */
+
+#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
+#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
+#ifndef CHSPEC_IS40
+#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
+#endif
+
+#endif /* !WL11N_20MHZONLY */
+
+#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
+#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
+#define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
+#define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
+#define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
+#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \
+ (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
+ (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))))
+#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
+
+#define CHANSPEC_STR_LEN 8
+
+#else /* D11AC_IOTYPES */
+
+#define WL_CHANSPEC_CHAN_MASK 0x00ff
+#define WL_CHANSPEC_CHAN_SHIFT 0
+#define WL_CHANSPEC_CHAN1_MASK 0x000f
+#define WL_CHANSPEC_CHAN1_SHIFT 0
+#define WL_CHANSPEC_CHAN2_MASK 0x00f0
+#define WL_CHANSPEC_CHAN2_SHIFT 4
+
+#define WL_CHANSPEC_CTL_SB_MASK 0x0700
+#define WL_CHANSPEC_CTL_SB_SHIFT 8
+#define WL_CHANSPEC_CTL_SB_LLL 0x0000
+#define WL_CHANSPEC_CTL_SB_LLU 0x0100
+#define WL_CHANSPEC_CTL_SB_LUL 0x0200
+#define WL_CHANSPEC_CTL_SB_LUU 0x0300
+#define WL_CHANSPEC_CTL_SB_ULL 0x0400
+#define WL_CHANSPEC_CTL_SB_ULU 0x0500
+#define WL_CHANSPEC_CTL_SB_UUL 0x0600
+#define WL_CHANSPEC_CTL_SB_UUU 0x0700
+#define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL
+#define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU
+#define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL
+#define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU
+#define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL
+#define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU
+#define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL
+#define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU
+
+#define WL_CHANSPEC_BW_MASK 0x3800
+#define WL_CHANSPEC_BW_SHIFT 11
+#define WL_CHANSPEC_BW_5 0x0000
+#define WL_CHANSPEC_BW_10 0x0800
+#define WL_CHANSPEC_BW_20 0x1000
+#define WL_CHANSPEC_BW_40 0x1800
+#define WL_CHANSPEC_BW_80 0x2000
+#define WL_CHANSPEC_BW_160 0x2800
+#define WL_CHANSPEC_BW_8080 0x3000
+
+#define WL_CHANSPEC_BAND_MASK 0xc000
+#define WL_CHANSPEC_BAND_SHIFT 14
+#define WL_CHANSPEC_BAND_2G 0x0000
+#define WL_CHANSPEC_BAND_3G 0x4000
+#define WL_CHANSPEC_BAND_4G 0x8000
+#define WL_CHANSPEC_BAND_5G 0xc000
+#define INVCHANSPEC 255
+
+/* channel defines */
+#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? \
+ ((channel) - CH_10MHZ_APART) : 0)
+#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
+ ((channel) + CH_10MHZ_APART) : 0)
+#define LOWER_40_SB(channel) ((channel) - CH_20MHZ_APART)
+#define UPPER_40_SB(channel) ((channel) + CH_20MHZ_APART)
+#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
+#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
+ (((channel) <= CH_MAX_2G_CHANNEL) ? \
+ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
+#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
+ ((channel) + CH_20MHZ_APART) : 0)
+#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
+ ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
+ ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
+ WL_CHANSPEC_BAND_5G))
+#define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
+ ((channel) | (ctlsb) | \
+ WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G)
+#define CH160MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
+ ((channel) | (ctlsb) | \
+ WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G)
+
+/* simple MACROs to get different fields of chanspec */
+#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK))
+#define CHSPEC_CHAN1(chspec) ((chspec) & WL_CHANSPEC_CHAN1_MASK)
+#define CHSPEC_CHAN2(chspec) ((chspec) & WL_CHANSPEC_CHAN2_MASK)
+#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
+#define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
+#define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK)
+
+#ifdef WL11N_20MHZONLY
+
+#define CHSPEC_IS10(chspec) 0
+#define CHSPEC_IS20(chspec) 1
+#ifndef CHSPEC_IS40
+#define CHSPEC_IS40(chspec) 0
+#endif
+#ifndef CHSPEC_IS80
+#define CHSPEC_IS80(chspec) 0
+#endif
+#ifndef CHSPEC_IS160
+#define CHSPEC_IS160(chspec) 0
+#endif
+#ifndef CHSPEC_IS8080
+#define CHSPEC_IS8080(chspec) 0
+#endif
+
+#else /* !WL11N_20MHZONLY */
+
+#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
+#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
+#ifndef CHSPEC_IS40
+#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
+#endif
+#ifndef CHSPEC_IS80
+#define CHSPEC_IS80(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80)
+#endif
+#ifndef CHSPEC_IS160
+#define CHSPEC_IS160(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160)
+#endif
+#ifndef CHSPEC_IS8080
+#define CHSPEC_IS8080(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080)
+#endif
+
+#endif /* !WL11N_20MHZONLY */
+
+#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
+#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
+#define CHSPEC_SB_UPPER(chspec) \
+ ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \
+ (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
+#define CHSPEC_SB_LOWER(chspec) \
+ ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \
+ (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
+#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
+
+/**
+ * Number of chars needed for wf_chspec_ntoa() destination character buffer.
+ */
+#define CHANSPEC_STR_LEN 20
+
+
+/* Legacy Chanspec defines
+ * These are the defines for the previous format of the chanspec_t
+ */
+#define WL_LCHANSPEC_CHAN_MASK 0x00ff
+#define WL_LCHANSPEC_CHAN_SHIFT 0
+
+#define WL_LCHANSPEC_CTL_SB_MASK 0x0300
+#define WL_LCHANSPEC_CTL_SB_SHIFT 8
+#define WL_LCHANSPEC_CTL_SB_LOWER 0x0100
+#define WL_LCHANSPEC_CTL_SB_UPPER 0x0200
+#define WL_LCHANSPEC_CTL_SB_NONE 0x0300
+
+#define WL_LCHANSPEC_BW_MASK 0x0C00
+#define WL_LCHANSPEC_BW_SHIFT 10
+#define WL_LCHANSPEC_BW_10 0x0400
+#define WL_LCHANSPEC_BW_20 0x0800
+#define WL_LCHANSPEC_BW_40 0x0C00
+
+#define WL_LCHANSPEC_BAND_MASK 0xf000
+#define WL_LCHANSPEC_BAND_SHIFT 12
+#define WL_LCHANSPEC_BAND_5G 0x1000
+#define WL_LCHANSPEC_BAND_2G 0x2000
+
+#define LCHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK))
+#define LCHSPEC_BAND(chspec) ((chspec) & WL_LCHANSPEC_BAND_MASK)
+#define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK)
+#define LCHSPEC_BW(chspec) ((chspec) & WL_LCHANSPEC_BW_MASK)
+#define LCHSPEC_IS10(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10)
+#define LCHSPEC_IS20(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20)
+#define LCHSPEC_IS40(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40)
+#define LCHSPEC_IS5G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G)
+#define LCHSPEC_IS2G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G)
+
+#define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band)))
+
+#endif /* D11AC_IOTYPES */
+
+/*
+ * WF_CHAN_FACTOR_* constants are used to calculate channel frequency
+ * given a channel number.
+ * chan_freq = chan_factor * 500Mhz + chan_number * 5
+ */
+
+/**
+ * Channel Factor for the starting frequence of 2.4 GHz channels.
+ * The value corresponds to 2407 MHz.
+ */
+#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
+
+/**
+ * Channel Factor for the starting frequence of 5 GHz channels.
+ * The value corresponds to 5000 MHz.
+ */
+#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
+
+/**
+ * Channel Factor for the starting frequence of 4.9 GHz channels.
+ * The value corresponds to 4000 MHz.
+ */
+#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
+
+/* defined rate in 500kbps */
+#define WLC_MAXRATE 108 /* in 500kbps units */
+#define WLC_RATE_1M 2 /* in 500kbps units */
+#define WLC_RATE_2M 4 /* in 500kbps units */
+#define WLC_RATE_5M5 11 /* in 500kbps units */
+#define WLC_RATE_11M 22 /* in 500kbps units */
+#define WLC_RATE_6M 12 /* in 500kbps units */
+#define WLC_RATE_9M 18 /* in 500kbps units */
+#define WLC_RATE_12M 24 /* in 500kbps units */
+#define WLC_RATE_18M 36 /* in 500kbps units */
+#define WLC_RATE_24M 48 /* in 500kbps units */
+#define WLC_RATE_36M 72 /* in 500kbps units */
+#define WLC_RATE_48M 96 /* in 500kbps units */
+#define WLC_RATE_54M 108 /* in 500kbps units */
+
+#define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */
+
+/**
+ * Convert chanspec to ascii string
+ *
+ * @param chspec chanspec format
+ * @param buf ascii string of chanspec
+ *
+ * @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes
+ *
+ * @see CHANSPEC_STR_LEN
+ */
+extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf);
+
+/**
+ * Convert ascii string to chanspec
+ *
+ * @param a pointer to input string
+ *
+ * @return >= 0 if successful or 0 otherwise
+ */
+extern chanspec_t wf_chspec_aton(const char *a);
+
+/**
+ * Verify the chanspec fields are valid.
+ *
+ * Verify the chanspec is using a legal set field values, i.e. that the chanspec
+ * specified a band, bw, ctl_sb and channel and that the combination could be
+ * legal given some set of circumstances.
+ *
+ * @param chanspec input chanspec to verify
+ *
+ * @return TRUE if the chanspec is malformed, FALSE if it looks good.
+ */
+extern bool wf_chspec_malformed(chanspec_t chanspec);
+
+/**
+ * Verify the chanspec specifies a valid channel according to 802.11.
+ *
+ * @param chanspec input chanspec to verify
+ *
+ * @return TRUE if the chanspec is a valid 802.11 channel
+ */
+extern bool wf_chspec_valid(chanspec_t chanspec);
+
+/**
+ * Return the primary (control) channel.
+ *
+ * This function returns the channel number of the primary 20MHz channel. For
+ * 20MHz channels this is just the channel number. For 40MHz or wider channels
+ * it is the primary 20MHz channel specified by the chanspec.
+ *
+ * @param chspec input chanspec
+ *
+ * @return Returns the channel number of the primary 20MHz channel
+ */
+extern uint8 wf_chspec_ctlchan(chanspec_t chspec);
+
+/**
+ * Return the primary (control) chanspec.
+ *
+ * This function returns the chanspec of the primary 20MHz channel. For 20MHz
+ * channels this is just the chanspec. For 40MHz or wider channels it is the
+ * chanspec of the primary 20MHZ channel specified by the chanspec.
+ *
+ * @param chspec input chanspec
+ *
+ * @return Returns the chanspec of the primary 20MHz channel
+ */
+extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec);
+
+/**
+ * Return a channel number corresponding to a frequency.
+ *
+ * This function returns the chanspec for the primary 40MHz of an 80MHz channel.
+ * The control sideband specifies the same 20MHz channel that the 80MHz channel is using
+ * as the primary 20MHz channel.
+ */
+extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec);
+
+/*
+ * Return the channel number for a given frequency and base frequency.
+ * The returned channel number is relative to the given base frequency.
+ * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
+ * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
+ *
+ * Frequency is specified in MHz.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+ * 2.4 GHz and 5 GHz bands.
+ *
+ * The returned channel will be in the range [1, 14] in the 2.4 GHz band
+ * and [0, 200] otherwise.
+ * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+ * frequency is not a 2.4 GHz channel, or if the frequency is not and even
+ * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
+ *
+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+ *
+ * @param freq frequency in MHz
+ * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz
+ *
+ * @return Returns a channel number
+ *
+ * @see WF_CHAN_FACTOR_2_4_G
+ * @see WF_CHAN_FACTOR_5_G
+ */
+extern int wf_mhz2channel(uint freq, uint start_factor);
+
+/**
+ * Return the center frequency in MHz of the given channel and base frequency.
+ *
+ * Return the center frequency in MHz of the given channel and base frequency.
+ * The channel number is interpreted relative to the given base frequency.
+ *
+ * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+ * 2.4 GHz and 5 GHz bands.
+ * The channel range of [1, 14] is only checked for a start_factor of
+ * WF_CHAN_FACTOR_2_4_G (4814).
+ * Odd start_factors produce channels on .5 MHz boundaries, in which case
+ * the answer is rounded down to an integral MHz.
+ * -1 is returned for an out of range channel.
+ *
+ * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+ *
+ * @param channel input channel number
+ * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz
+ *
+ * @return Returns a frequency in MHz
+ *
+ * @see WF_CHAN_FACTOR_2_4_G
+ * @see WF_CHAN_FACTOR_5_G
+ */
+extern int wf_channel2mhz(uint channel, uint start_factor);
+
+/**
+ * Convert ctl chan and bw to chanspec
+ *
+ * @param ctl_ch channel
+ * @param bw bandwidth
+ *
+ * @return > 0 if successful or 0 otherwise
+ *
+ */
+extern uint16 wf_channel2chspec(uint ctl_ch, uint bw);
+
+#endif /* _bcmwifi_channels_h_ */
diff --git a/drivers/net/wireless/ap6210/include/bcmwifi_rates.h b/drivers/net/wireless/ap6210/include/bcmwifi_rates.h
new file mode 100644
index 0000000..ddc6ab5
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/bcmwifi_rates.h
@@ -0,0 +1,318 @@
+/*
+ * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmwifi_rates.h 252708 2011-04-12 06:45:56Z $
+ */
+
+#ifndef _bcmwifi_rates_h_
+#define _bcmwifi_rates_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define WL_RATESET_SZ_DSSS 4
+#define WL_RATESET_SZ_OFDM 8
+#define WL_RATESET_SZ_HT_MCS 8
+#define WL_RATESET_SZ_VHT_MCS 10
+
+#define WL_TX_CHAINS_MAX 3
+
+#define WL_RATE_DISABLED (-128) /* Power value corresponding to unsupported rate */
+
+/* Transmit channel bandwidths */
+typedef enum wl_tx_bw {
+ WL_TX_BW_20,
+ WL_TX_BW_40,
+ WL_TX_BW_80,
+ WL_TX_BW_20IN40,
+ WL_TX_BW_20IN80,
+ WL_TX_BW_40IN80,
+ WL_TX_BW_ALL
+} wl_tx_bw_t;
+
+
+/*
+ * Transmit modes.
+ * Not all modes are listed here, only those required for disambiguation. e.g. SPEXP is not listed
+ */
+typedef enum wl_tx_mode {
+ WL_TX_MODE_NONE,
+ WL_TX_MODE_STBC,
+ WL_TX_MODE_CDD,
+ WL_TX_MODE_SDM
+} wl_tx_mode_t;
+
+
+/* Number of transmit chains */
+typedef enum wl_tx_chains {
+ WL_TX_CHAINS_1 = 1,
+ WL_TX_CHAINS_2,
+ WL_TX_CHAINS_3
+} wl_tx_chains_t;
+
+
+/* Number of transmit streams */
+typedef enum wl_tx_nss {
+ WL_TX_NSS_1 = 1,
+ WL_TX_NSS_2,
+ WL_TX_NSS_3
+} wl_tx_nss_t;
+
+
+typedef enum clm_rates {
+ /************
+ * 1 chain *
+ ************
+ */
+
+ /* 1 Stream */
+ WL_RATE_1X1_DSSS_1 = 0,
+ WL_RATE_1X1_DSSS_2 = 1,
+ WL_RATE_1X1_DSSS_5_5 = 2,
+ WL_RATE_1X1_DSSS_11 = 3,
+
+ WL_RATE_1X1_OFDM_6 = 4,
+ WL_RATE_1X1_OFDM_9 = 5,
+ WL_RATE_1X1_OFDM_12 = 6,
+ WL_RATE_1X1_OFDM_18 = 7,
+ WL_RATE_1X1_OFDM_24 = 8,
+ WL_RATE_1X1_OFDM_36 = 9,
+ WL_RATE_1X1_OFDM_48 = 10,
+ WL_RATE_1X1_OFDM_54 = 11,
+
+ WL_RATE_1X1_MCS0 = 12,
+ WL_RATE_1X1_MCS1 = 13,
+ WL_RATE_1X1_MCS2 = 14,
+ WL_RATE_1X1_MCS3 = 15,
+ WL_RATE_1X1_MCS4 = 16,
+ WL_RATE_1X1_MCS5 = 17,
+ WL_RATE_1X1_MCS6 = 18,
+ WL_RATE_1X1_MCS7 = 19,
+
+ WL_RATE_1X1_VHT0SS1 = 12,
+ WL_RATE_1X1_VHT1SS1 = 13,
+ WL_RATE_1X1_VHT2SS1 = 14,
+ WL_RATE_1X1_VHT3SS1 = 15,
+ WL_RATE_1X1_VHT4SS1 = 16,
+ WL_RATE_1X1_VHT5SS1 = 17,
+ WL_RATE_1X1_VHT6SS1 = 18,
+ WL_RATE_1X1_VHT7SS1 = 19,
+ WL_RATE_1X1_VHT8SS1 = 20,
+ WL_RATE_1X1_VHT9SS1 = 21,
+
+
+ /************
+ * 2 chains *
+ ************
+ */
+
+ /* 1 Stream expanded + 1 */
+ WL_RATE_1X2_DSSS_1 = 22,
+ WL_RATE_1X2_DSSS_2 = 23,
+ WL_RATE_1X2_DSSS_5_5 = 24,
+ WL_RATE_1X2_DSSS_11 = 25,
+
+ WL_RATE_1X2_CDD_OFDM_6 = 26,
+ WL_RATE_1X2_CDD_OFDM_9 = 27,
+ WL_RATE_1X2_CDD_OFDM_12 = 28,
+ WL_RATE_1X2_CDD_OFDM_18 = 29,
+ WL_RATE_1X2_CDD_OFDM_24 = 30,
+ WL_RATE_1X2_CDD_OFDM_36 = 31,
+ WL_RATE_1X2_CDD_OFDM_48 = 32,
+ WL_RATE_1X2_CDD_OFDM_54 = 33,
+
+ WL_RATE_1X2_CDD_MCS0 = 34,
+ WL_RATE_1X2_CDD_MCS1 = 35,
+ WL_RATE_1X2_CDD_MCS2 = 36,
+ WL_RATE_1X2_CDD_MCS3 = 37,
+ WL_RATE_1X2_CDD_MCS4 = 38,
+ WL_RATE_1X2_CDD_MCS5 = 39,
+ WL_RATE_1X2_CDD_MCS6 = 40,
+ WL_RATE_1X2_CDD_MCS7 = 41,
+
+ WL_RATE_1X2_VHT0SS1 = 34,
+ WL_RATE_1X2_VHT1SS1 = 35,
+ WL_RATE_1X2_VHT2SS1 = 36,
+ WL_RATE_1X2_VHT3SS1 = 37,
+ WL_RATE_1X2_VHT4SS1 = 38,
+ WL_RATE_1X2_VHT5SS1 = 39,
+ WL_RATE_1X2_VHT6SS1 = 40,
+ WL_RATE_1X2_VHT7SS1 = 41,
+ WL_RATE_1X2_VHT8SS1 = 42,
+ WL_RATE_1X2_VHT9SS1 = 43,
+
+ /* 2 Streams */
+ WL_RATE_2X2_STBC_MCS0 = 44,
+ WL_RATE_2X2_STBC_MCS1 = 45,
+ WL_RATE_2X2_STBC_MCS2 = 46,
+ WL_RATE_2X2_STBC_MCS3 = 47,
+ WL_RATE_2X2_STBC_MCS4 = 48,
+ WL_RATE_2X2_STBC_MCS5 = 49,
+ WL_RATE_2X2_STBC_MCS6 = 50,
+ WL_RATE_2X2_STBC_MCS7 = 51,
+
+ WL_RATE_2X2_STBC_VHT0SS1 = 44,
+ WL_RATE_2X2_STBC_VHT1SS1 = 45,
+ WL_RATE_2X2_STBC_VHT2SS1 = 46,
+ WL_RATE_2X2_STBC_VHT3SS1 = 47,
+ WL_RATE_2X2_STBC_VHT4SS1 = 48,
+ WL_RATE_2X2_STBC_VHT5SS1 = 49,
+ WL_RATE_2X2_STBC_VHT6SS1 = 50,
+ WL_RATE_2X2_STBC_VHT7SS1 = 51,
+ WL_RATE_2X2_STBC_VHT8SS1 = 52,
+ WL_RATE_2X2_STBC_VHT9SS1 = 53,
+
+ WL_RATE_2X2_SDM_MCS8 = 54,
+ WL_RATE_2X2_SDM_MCS9 = 55,
+ WL_RATE_2X2_SDM_MCS10 = 56,
+ WL_RATE_2X2_SDM_MCS11 = 57,
+ WL_RATE_2X2_SDM_MCS12 = 58,
+ WL_RATE_2X2_SDM_MCS13 = 59,
+ WL_RATE_2X2_SDM_MCS14 = 60,
+ WL_RATE_2X2_SDM_MCS15 = 61,
+
+ WL_RATE_2X2_VHT0SS2 = 54,
+ WL_RATE_2X2_VHT1SS2 = 55,
+ WL_RATE_2X2_VHT2SS2 = 56,
+ WL_RATE_2X2_VHT3SS2 = 57,
+ WL_RATE_2X2_VHT4SS2 = 58,
+ WL_RATE_2X2_VHT5SS2 = 59,
+ WL_RATE_2X2_VHT6SS2 = 60,
+ WL_RATE_2X2_VHT7SS2 = 61,
+ WL_RATE_2X2_VHT8SS2 = 62,
+ WL_RATE_2X2_VHT9SS2 = 63,
+
+
+ /************
+ * 3 chains *
+ ************
+ */
+
+ /* 1 Stream expanded + 2 */
+ WL_RATE_1X3_DSSS_1 = 64,
+ WL_RATE_1X3_DSSS_2 = 65,
+ WL_RATE_1X3_DSSS_5_5 = 66,
+ WL_RATE_1X3_DSSS_11 = 67,
+
+ WL_RATE_1X3_CDD_OFDM_6 = 68,
+ WL_RATE_1X3_CDD_OFDM_9 = 69,
+ WL_RATE_1X3_CDD_OFDM_12 = 70,
+ WL_RATE_1X3_CDD_OFDM_18 = 71,
+ WL_RATE_1X3_CDD_OFDM_24 = 72,
+ WL_RATE_1X3_CDD_OFDM_36 = 73,
+ WL_RATE_1X3_CDD_OFDM_48 = 74,
+ WL_RATE_1X3_CDD_OFDM_54 = 75,
+
+ WL_RATE_1X3_CDD_MCS0 = 76,
+ WL_RATE_1X3_CDD_MCS1 = 77,
+ WL_RATE_1X3_CDD_MCS2 = 78,
+ WL_RATE_1X3_CDD_MCS3 = 79,
+ WL_RATE_1X3_CDD_MCS4 = 80,
+ WL_RATE_1X3_CDD_MCS5 = 81,
+ WL_RATE_1X3_CDD_MCS6 = 82,
+ WL_RATE_1X3_CDD_MCS7 = 83,
+
+ WL_RATE_1X3_VHT0SS1 = 76,
+ WL_RATE_1X3_VHT1SS1 = 77,
+ WL_RATE_1X3_VHT2SS1 = 78,
+ WL_RATE_1X3_VHT3SS1 = 79,
+ WL_RATE_1X3_VHT4SS1 = 80,
+ WL_RATE_1X3_VHT5SS1 = 81,
+ WL_RATE_1X3_VHT6SS1 = 82,
+ WL_RATE_1X3_VHT7SS1 = 83,
+ WL_RATE_1X3_VHT8SS1 = 84,
+ WL_RATE_1X3_VHT9SS1 = 85,
+
+ /* 2 Streams expanded + 1 */
+ WL_RATE_2X3_STBC_MCS0 = 86,
+ WL_RATE_2X3_STBC_MCS1 = 87,
+ WL_RATE_2X3_STBC_MCS2 = 88,
+ WL_RATE_2X3_STBC_MCS3 = 89,
+ WL_RATE_2X3_STBC_MCS4 = 90,
+ WL_RATE_2X3_STBC_MCS5 = 91,
+ WL_RATE_2X3_STBC_MCS6 = 92,
+ WL_RATE_2X3_STBC_MCS7 = 93,
+
+ WL_RATE_2X3_STBC_VHT0SS1 = 86,
+ WL_RATE_2X3_STBC_VHT1SS1 = 87,
+ WL_RATE_2X3_STBC_VHT2SS1 = 88,
+ WL_RATE_2X3_STBC_VHT3SS1 = 89,
+ WL_RATE_2X3_STBC_VHT4SS1 = 90,
+ WL_RATE_2X3_STBC_VHT5SS1 = 91,
+ WL_RATE_2X3_STBC_VHT6SS1 = 92,
+ WL_RATE_2X3_STBC_VHT7SS1 = 93,
+ WL_RATE_2X3_STBC_VHT8SS1 = 94,
+ WL_RATE_2X3_STBC_VHT9SS1 = 95,
+
+ WL_RATE_2X3_SDM_MCS8 = 96,
+ WL_RATE_2X3_SDM_MCS9 = 97,
+ WL_RATE_2X3_SDM_MCS10 = 98,
+ WL_RATE_2X3_SDM_MCS11 = 99,
+ WL_RATE_2X3_SDM_MCS12 = 100,
+ WL_RATE_2X3_SDM_MCS13 = 101,
+ WL_RATE_2X3_SDM_MCS14 = 102,
+ WL_RATE_2X3_SDM_MCS15 = 103,
+
+ WL_RATE_2X3_VHT0SS2 = 96,
+ WL_RATE_2X3_VHT1SS2 = 97,
+ WL_RATE_2X3_VHT2SS2 = 98,
+ WL_RATE_2X3_VHT3SS2 = 99,
+ WL_RATE_2X3_VHT4SS2 = 100,
+ WL_RATE_2X3_VHT5SS2 = 101,
+ WL_RATE_2X3_VHT6SS2 = 102,
+ WL_RATE_2X3_VHT7SS2 = 103,
+ WL_RATE_2X3_VHT8SS2 = 104,
+ WL_RATE_2X3_VHT9SS2 = 105,
+
+ /* 3 Streams */
+ WL_RATE_3X3_SDM_MCS16 = 106,
+ WL_RATE_3X3_SDM_MCS17 = 107,
+ WL_RATE_3X3_SDM_MCS18 = 108,
+ WL_RATE_3X3_SDM_MCS19 = 109,
+ WL_RATE_3X3_SDM_MCS20 = 110,
+ WL_RATE_3X3_SDM_MCS21 = 111,
+ WL_RATE_3X3_SDM_MCS22 = 112,
+ WL_RATE_3X3_SDM_MCS23 = 113,
+
+ WL_RATE_3X3_VHT0SS3 = 106,
+ WL_RATE_3X3_VHT1SS3 = 107,
+ WL_RATE_3X3_VHT2SS3 = 108,
+ WL_RATE_3X3_VHT3SS3 = 109,
+ WL_RATE_3X3_VHT4SS3 = 110,
+ WL_RATE_3X3_VHT5SS3 = 111,
+ WL_RATE_3X3_VHT6SS3 = 112,
+ WL_RATE_3X3_VHT7SS3 = 113,
+ WL_RATE_3X3_VHT8SS3 = 114,
+ WL_RATE_3X3_VHT9SS3 = 115,
+
+ /* Number of rate codes */
+ WL_NUMRATES = 116
+} clm_rates_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _bcmwifi_rates_h_ */
diff --git a/drivers/net/wireless/ap6210/include/dhdioctl.h b/drivers/net/wireless/ap6210/include/dhdioctl.h
new file mode 100644
index 0000000..6909dc2
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/dhdioctl.h
@@ -0,0 +1,136 @@
+/*
+ * Definitions for ioctls to access DHD iovars.
+ * Based on wlioctl.h (for Broadcom 802.11abg driver).
+ * (Moves towards generic ioctls for BCM drivers/iovars.)
+ *
+ * Definitions subject to change without notice.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhdioctl.h 354894 2012-09-04 12:34:07Z $
+ */
+
+#ifndef _dhdioctl_h_
+#define _dhdioctl_h_
+
+#include <typedefs.h>
+
+
+/* require default structure packing */
+#define BWL_DEFAULT_PACKING
+#include <packed_section_start.h>
+
+
+/* Linux network driver ioctl encoding */
+typedef struct dhd_ioctl {
+ uint cmd; /* common ioctl definition */
+ void *buf; /* pointer to user buffer */
+ uint len; /* length of user buffer */
+ bool set; /* get or set request (optional) */
+ uint used; /* bytes read or written (optional) */
+ uint needed; /* bytes needed (optional) */
+ uint driver; /* to identify target driver */
+} dhd_ioctl_t;
+
+/* Underlying BUS definition */
+enum {
+ BUS_TYPE_USB = 0, /* for USB dongles */
+ BUS_TYPE_SDIO /* for SDIO dongles */
+};
+
+/* per-driver magic numbers */
+#define DHD_IOCTL_MAGIC 0x00444944
+
+/* bump this number if you change the ioctl interface */
+#define DHD_IOCTL_VERSION 1
+
+#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */
+#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */
+
+/* common ioctl definitions */
+#define DHD_GET_MAGIC 0
+#define DHD_GET_VERSION 1
+#define DHD_GET_VAR 2
+#define DHD_SET_VAR 3
+
+/* message levels */
+#define DHD_ERROR_VAL 0x0001
+#define DHD_TRACE_VAL 0x0002
+#define DHD_INFO_VAL 0x0004
+#define DHD_DATA_VAL 0x0008
+#define DHD_CTL_VAL 0x0010
+#define DHD_TIMER_VAL 0x0020
+#define DHD_HDRS_VAL 0x0040
+#define DHD_BYTES_VAL 0x0080
+#define DHD_INTR_VAL 0x0100
+#define DHD_LOG_VAL 0x0200
+#define DHD_GLOM_VAL 0x0400
+#define DHD_EVENT_VAL 0x0800
+#define DHD_BTA_VAL 0x1000
+#if 0 && (NDISVER >= 0x0630) && 1
+#define DHD_SCAN_VAL 0x2000
+#else
+#define DHD_ISCAN_VAL 0x2000
+#endif
+#define DHD_ARPOE_VAL 0x4000
+#define DHD_REORDER_VAL 0x8000
+#define DHD_IW_VAL 0x10000
+#define DHD_CFG_VAL 0x20000
+
+#ifdef SDTEST
+/* For pktgen iovar */
+typedef struct dhd_pktgen {
+ uint version; /* To allow structure change tracking */
+ uint freq; /* Max ticks between tx/rx attempts */
+ uint count; /* Test packets to send/rcv each attempt */
+ uint print; /* Print counts every <print> attempts */
+ uint total; /* Total packets (or bursts) */
+ uint minlen; /* Minimum length of packets to send */
+ uint maxlen; /* Maximum length of packets to send */
+ uint numsent; /* Count of test packets sent */
+ uint numrcvd; /* Count of test packets received */
+ uint numfail; /* Count of test send failures */
+ uint mode; /* Test mode (type of test packets) */
+ uint stop; /* Stop after this many tx failures */
+} dhd_pktgen_t;
+
+/* Version in case structure changes */
+#define DHD_PKTGEN_VERSION 2
+
+/* Type of test packets to use */
+#define DHD_PKTGEN_ECHO 1 /* Send echo requests */
+#define DHD_PKTGEN_SEND 2 /* Send discard packets */
+#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */
+#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous tx dongle */
+#endif /* SDTEST */
+
+/* Enter idle immediately (no timeout) */
+#define DHD_IDLE_IMMEDIATE (-1)
+
+/* Values for idleclock iovar: other values are the sd_divisor to use when idle */
+#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change when idle */
+#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped (and use SD1 mode) */
+
+
+/* require default structure packing */
+#include <packed_section_end.h>
+
+#endif /* _dhdioctl_h_ */
diff --git a/drivers/net/wireless/ap6210/include/epivers.h b/drivers/net/wireless/ap6210/include/epivers.h
new file mode 100644
index 0000000..cff9ebd
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/epivers.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 csm Exp $
+ *
+*/
+
+#ifndef _epivers_h_
+#define _epivers_h_
+
+#define EPI_MAJOR_VERSION 1
+
+#define EPI_MINOR_VERSION 28
+
+#define EPI_RC_NUMBER 23
+
+#define EPI_INCREMENTAL_NUMBER 0
+
+#define EPI_BUILD_NUMBER 0
+
+#define EPI_VERSION 1, 28, 23, 0
+
+#define EPI_VERSION_NUM 0x011c1700
+
+#define EPI_VERSION_DEV 1.28.23
+
+/* Driver Version String, ASCII, 32 chars max */
+#ifdef BCMINTERNAL
+#define EPI_VERSION_STR "1.28.23.3 (r BCMINT)"
+#else
+#ifdef WLTEST
+#define EPI_VERSION_STR "1.28.23.3 (r WLTEST)"
+#else
+#define EPI_VERSION_STR "1.28.23.3 (r)"
+#endif
+#endif /* BCMINTERNAL */
+
+#endif /* _epivers_h_ */
diff --git a/drivers/net/wireless/ap6210/include/hndpmu.h b/drivers/net/wireless/ap6210/include/hndpmu.h
new file mode 100644
index 0000000..c41def6
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/hndpmu.h
@@ -0,0 +1,36 @@
+/*
+ * HND SiliconBackplane PMU support.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: hndpmu.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _hndpmu_h_
+#define _hndpmu_h_
+
+
+extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on);
+extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength);
+
+extern void si_pmu_minresmask_htavail_set(si_t *sih, osl_t *osh, bool set_clear);
+
+#endif /* _hndpmu_h_ */
diff --git a/drivers/net/wireless/ap6210/include/hndrte_armtrap.h b/drivers/net/wireless/ap6210/include/hndrte_armtrap.h
new file mode 100644
index 0000000..90d9799
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/hndrte_armtrap.h
@@ -0,0 +1,88 @@
+/*
+ * HNDRTE arm trap handling.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: hndrte_armtrap.h 261365 2011-05-24 20:42:23Z $
+ */
+
+#ifndef _hndrte_armtrap_h
+#define _hndrte_armtrap_h
+
+
+/* ARM trap handling */
+
+/* Trap types defined by ARM (see arminc.h) */
+
+/* Trap locations in lo memory */
+#define TRAP_STRIDE 4
+#define FIRST_TRAP TR_RST
+#define LAST_TRAP (TR_FIQ * TRAP_STRIDE)
+
+#if defined(__ARM_ARCH_4T__)
+#define MAX_TRAP_TYPE (TR_FIQ + 1)
+#elif defined(__ARM_ARCH_7M__)
+#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS)
+#endif /* __ARM_ARCH_7M__ */
+
+/* The trap structure is defined here as offsets for assembly */
+#define TR_TYPE 0x00
+#define TR_EPC 0x04
+#define TR_CPSR 0x08
+#define TR_SPSR 0x0c
+#define TR_REGS 0x10
+#define TR_REG(n) (TR_REGS + (n) * 4)
+#define TR_SP TR_REG(13)
+#define TR_LR TR_REG(14)
+#define TR_PC TR_REG(15)
+
+#define TRAP_T_SIZE 80
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+#include <typedefs.h>
+
+typedef struct _trap_struct {
+ uint32 type;
+ uint32 epc;
+ uint32 cpsr;
+ uint32 spsr;
+ uint32 r0; /* a1 */
+ uint32 r1; /* a2 */
+ uint32 r2; /* a3 */
+ uint32 r3; /* a4 */
+ uint32 r4; /* v1 */
+ uint32 r5; /* v2 */
+ uint32 r6; /* v3 */
+ uint32 r7; /* v4 */
+ uint32 r8; /* v5 */
+ uint32 r9; /* sb/v6 */
+ uint32 r10; /* sl/v7 */
+ uint32 r11; /* fp/v8 */
+ uint32 r12; /* ip */
+ uint32 r13; /* sp */
+ uint32 r14; /* lr */
+ uint32 pc; /* r15 */
+} trap_t;
+
+#endif /* !_LANGUAGE_ASSEMBLY */
+
+#endif /* _hndrte_armtrap_h */
diff --git a/drivers/net/wireless/ap6210/include/hndrte_cons.h b/drivers/net/wireless/ap6210/include/hndrte_cons.h
new file mode 100644
index 0000000..57abbbd
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/hndrte_cons.h
@@ -0,0 +1,67 @@
+/*
+ * Console support for hndrte.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: hndrte_cons.h 300516 2011-12-04 17:39:44Z $
+ */
+#ifndef _HNDRTE_CONS_H
+#define _HNDRTE_CONS_H
+
+#include <typedefs.h>
+
+#define CBUF_LEN (128)
+
+#define LOG_BUF_LEN 1024
+
+typedef struct {
+ uint32 buf; /* Can't be pointer on (64-bit) hosts */
+ uint buf_size;
+ uint idx;
+ char *_buf_compat; /* redundant pointer for backward compat. */
+} hndrte_log_t;
+
+typedef struct {
+ /* Virtual UART
+ * When there is no UART (e.g. Quickturn), the host should write a complete
+ * input line directly into cbuf and then write the length into vcons_in.
+ * This may also be used when there is a real UART (at risk of conflicting with
+ * the real UART). vcons_out is currently unused.
+ */
+ volatile uint vcons_in;
+ volatile uint vcons_out;
+
+ /* Output (logging) buffer
+ * Console output is written to a ring buffer log_buf at index log_idx.
+ * The host may read the output when it sees log_idx advance.
+ * Output will be lost if the output wraps around faster than the host polls.
+ */
+ hndrte_log_t log;
+
+ /* Console input line buffer
+ * Characters are read one at a time into cbuf until <CR> is received, then
+ * the buffer is processed as a command line. Also used for virtual UART.
+ */
+ uint cbuf_idx;
+ char cbuf[CBUF_LEN];
+} hndrte_cons_t;
+
+#endif /* _HNDRTE_CONS_H */
diff --git a/drivers/net/wireless/ap6210/include/hndsoc.h b/drivers/net/wireless/ap6210/include/hndsoc.h
new file mode 100644
index 0000000..66640c3
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/hndsoc.h
@@ -0,0 +1,235 @@
+/*
+ * Broadcom HND chip & on-chip-interconnect-related definitions.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: hndsoc.h 309193 2012-01-19 00:03:57Z $
+ */
+
+#ifndef _HNDSOC_H
+#define _HNDSOC_H
+
+/* Include the soci specific files */
+#include <sbconfig.h>
+#include <aidmp.h>
+
+/*
+ * SOC Interconnect Address Map.
+ * All regions may not exist on all chips.
+ */
+#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */
+#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */
+#define SI_PCI_MEM_SZ (64 * 1024 * 1024)
+#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */
+#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
+#define SI_SDRAM_R2 0x80000000 /* Region 2 for sdram (512 MB) */
+
+#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
+
+#define SI_WRAP_BASE 0x18100000 /* Wrapper space base */
+#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */
+#define SI_MAXCORES 16 /* Max cores (this is arbitrary, for software
+ * convenience and could be changed if we
+ * make any larger chips
+ */
+
+#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */
+#define SI_FASTRAM_SWAPPED 0x19800000
+
+#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */
+#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */
+#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */
+#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */
+#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */
+#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */
+#define SI_ARMCR4_ROM 0x000f0000 /* ARM Cortex-R4 ROM */
+#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */
+#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */
+#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */
+#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */
+
+#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */
+#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */
+#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */
+#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2
+ * (2 ZettaBytes), low 32 bits
+ */
+#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2
+ * (2 ZettaBytes), high 32 bits
+ */
+
+/* core codes */
+#define NODEV_CORE_ID 0x700 /* Invalid coreid */
+#define CC_CORE_ID 0x800 /* chipcommon core */
+#define ILINE20_CORE_ID 0x801 /* iline20 core */
+#define SRAM_CORE_ID 0x802 /* sram core */
+#define SDRAM_CORE_ID 0x803 /* sdram core */
+#define PCI_CORE_ID 0x804 /* pci core */
+#define MIPS_CORE_ID 0x805 /* mips core */
+#define ENET_CORE_ID 0x806 /* enet mac core */
+#define CODEC_CORE_ID 0x807 /* v90 codec core */
+#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */
+#define ADSL_CORE_ID 0x809 /* ADSL core */
+#define ILINE100_CORE_ID 0x80a /* iline100 core */
+#define IPSEC_CORE_ID 0x80b /* ipsec core */
+#define UTOPIA_CORE_ID 0x80c /* utopia core */
+#define PCMCIA_CORE_ID 0x80d /* pcmcia core */
+#define SOCRAM_CORE_ID 0x80e /* internal memory core */
+#define MEMC_CORE_ID 0x80f /* memc sdram core */
+#define OFDM_CORE_ID 0x810 /* OFDM phy core */
+#define EXTIF_CORE_ID 0x811 /* external interface core */
+#define D11_CORE_ID 0x812 /* 802.11 MAC core */
+#define APHY_CORE_ID 0x813 /* 802.11a phy core */
+#define BPHY_CORE_ID 0x814 /* 802.11b phy core */
+#define GPHY_CORE_ID 0x815 /* 802.11g phy core */
+#define MIPS33_CORE_ID 0x816 /* mips3302 core */
+#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */
+#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */
+#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */
+#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */
+#define SDIOH_CORE_ID 0x81b /* sdio host core */
+#define ROBO_CORE_ID 0x81c /* roboswitch core */
+#define ATA100_CORE_ID 0x81d /* parallel ATA core */
+#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */
+#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */
+#define PCIE_CORE_ID 0x820 /* pci express core */
+#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */
+#define SRAMC_CORE_ID 0x822 /* SRAM controller core */
+#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */
+#define ARM11_CORE_ID 0x824 /* ARM 1176 core */
+#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */
+#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */
+#define PMU_CORE_ID 0x827 /* PMU core */
+#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */
+#define SDIOD_CORE_ID 0x829 /* SDIO device core */
+#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */
+#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */
+#define MIPS74K_CORE_ID 0x82c /* mips 74k core */
+#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */
+#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */
+#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */
+#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */
+#define SC_CORE_ID 0x831 /* shared common core */
+#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */
+#define SPIH_CORE_ID 0x833 /* SPI host core */
+#define I2S_CORE_ID 0x834 /* I2S core */
+#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */
+#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */
+
+#define ACPHY_CORE_ID 0x83b /* Dot11 ACPHY */
+#define PCIE2_CORE_ID 0x83c /* pci express Gen2 core */
+#define USB30D_CORE_ID 0x83d /* usb 3.0 device core */
+#define ARMCR4_CORE_ID 0x83e /* ARM CR4 CPU */
+#define APB_BRIDGE_CORE_ID 0x135 /* APB bridge core ID */
+#define AXI_CORE_ID 0x301 /* AXI/GPV core ID */
+#define EROM_CORE_ID 0x366 /* EROM core ID */
+#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */
+#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all
+ * unused address ranges
+ */
+
+#define CC_4706_CORE_ID 0x500 /* chipcommon core */
+#define SOCRAM_4706_CORE_ID 0x50e /* internal memory core */
+#define GMAC_COMMON_4706_CORE_ID 0x5dc /* Gigabit MAC core */
+#define GMAC_4706_CORE_ID 0x52d /* Gigabit MAC core */
+#define AMEMC_CORE_ID 0x52e /* DDR1/2 memory controller core */
+#define ALTA_CORE_ID 0x534 /* I2S core */
+#define DDR23_PHY_CORE_ID 0x5dd
+
+#define SI_PCI1_MEM 0x40000000 /* Host Mode sb2pcitranslation0 (64 MB) */
+#define SI_PCI1_CFG 0x44000000 /* Host Mode sb2pcitranslation1 (64 MB) */
+#define SI_PCIE1_DMA_H32 0xc0000000 /* PCIE Client Mode sb2pcitranslation2
+ * (2 ZettaBytes), high 32 bits
+ */
+#define CC_4706B0_CORE_REV 0x8000001f /* chipcommon core */
+#define SOCRAM_4706B0_CORE_REV 0x80000005 /* internal memory core */
+#define GMAC_4706B0_CORE_REV 0x80000000 /* Gigabit MAC core */
+
+/* There are TWO constants on all HND chips: SI_ENUM_BASE above,
+ * and chipcommon being the first core:
+ */
+#define SI_CC_IDX 0
+
+/* SOC Interconnect types (aka chip types) */
+#define SOCI_SB 0
+#define SOCI_AI 1
+#define SOCI_UBUS 2
+
+/* Common core control flags */
+#define SICF_BIST_EN 0x8000
+#define SICF_PME_EN 0x4000
+#define SICF_CORE_BITS 0x3ffc
+#define SICF_FGC 0x0002
+#define SICF_CLOCK_EN 0x0001
+
+/* Common core status flags */
+#define SISF_BIST_DONE 0x8000
+#define SISF_BIST_ERROR 0x4000
+#define SISF_GATED_CLK 0x2000
+#define SISF_DMA64 0x1000
+#define SISF_CORE_BITS 0x0fff
+
+/* A register that is common to all cores to
+ * communicate w/PMU regarding clock control.
+ */
+#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */
+
+/* clk_ctl_st register */
+#define CCS_FORCEALP 0x00000001 /* force ALP request */
+#define CCS_FORCEHT 0x00000002 /* force HT request */
+#define CCS_FORCEILP 0x00000004 /* force ILP request */
+#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
+#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
+#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
+#define CCS_HQCLKREQ 0x00000040 /* HQ Clock Required */
+#define CCS_USBCLKREQ 0x00000100 /* USB Clock Req */
+#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */
+#define CCS_ERSRC_REQ_SHIFT 8
+#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
+#define CCS_HTAVAIL 0x00020000 /* HT is available */
+#define CCS_BP_ON_APL 0x00040000 /* RO: Backplane is running on ALP clock */
+#define CCS_BP_ON_HT 0x00080000 /* RO: Backplane is running on HT clock */
+#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */
+#define CCS_ERSRC_STS_SHIFT 24
+
+#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */
+#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */
+
+/* Not really related to SOC Interconnect, but a couple of software
+ * conventions for the use the flash space:
+ */
+
+/* Minumum amount of flash we support */
+#define FLASH_MIN 0x00020000 /* Minimum flash size */
+
+/* A boot/binary may have an embedded block that describes its size */
+#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */
+#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */
+#define BISZ_MAGIC_IDX 0 /* Word 0: magic */
+#define BISZ_TXTST_IDX 1 /* 1: text start */
+#define BISZ_TXTEND_IDX 2 /* 2: text end */
+#define BISZ_DATAST_IDX 3 /* 3: data start */
+#define BISZ_DATAEND_IDX 4 /* 4: data end */
+#define BISZ_BSSST_IDX 5 /* 5: bss start */
+#define BISZ_BSSEND_IDX 6 /* 6: bss end */
+#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */
+
+#endif /* _HNDSOC_H */
diff --git a/drivers/net/wireless/ap6210/include/linux_osl.h b/drivers/net/wireless/ap6210/include/linux_osl.h
new file mode 100644
index 0000000..ca28f6b
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/linux_osl.h
@@ -0,0 +1,430 @@
+/*
+ * Linux OS Independent Layer
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: linux_osl.h 354452 2012-08-31 04:59:17Z $
+ */
+
+#ifndef _linux_osl_h_
+#define _linux_osl_h_
+
+#include <typedefs.h>
+
+/* Linux Kernel: File Operations: start */
+extern void * osl_os_open_image(char * filename);
+extern int osl_os_get_image_block(char * buf, int len, void * image);
+extern void osl_os_close_image(void * image);
+extern int osl_os_image_size(void *image);
+/* Linux Kernel: File Operations: end */
+
+#ifdef BCMDRIVER
+
+/* OSL initialization */
+extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
+extern void osl_detach(osl_t *osh);
+
+/* Global ASSERT type */
+extern uint32 g_assert_type;
+
+/* ASSERT */
+#if defined(BCMASSERT_LOG)
+ #define ASSERT(exp) \
+ do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0)
+extern void osl_assert(const char *exp, const char *file, int line);
+#else
+ #ifdef __GNUC__
+ #define GCC_VERSION \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+ #if GCC_VERSION > 30100
+ #define ASSERT(exp) do {} while (0)
+ #else
+ /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */
+ #define ASSERT(exp)
+ #endif /* GCC_VERSION > 30100 */
+ #endif /* __GNUC__ */
+#endif
+
+/* microsecond delay */
+#define OSL_DELAY(usec) osl_delay(usec)
+extern void osl_delay(uint usec);
+
+#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
+ osl_pcmcia_read_attr((osh), (offset), (buf), (size))
+#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
+ osl_pcmcia_write_attr((osh), (offset), (buf), (size))
+extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size);
+extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size);
+
+/* PCI configuration space access macros */
+#define OSL_PCI_READ_CONFIG(osh, offset, size) \
+ osl_pci_read_config((osh), (offset), (size))
+#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
+ osl_pci_write_config((osh), (offset), (size), (val))
+extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size);
+extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val);
+
+/* PCI device bus # and slot # */
+#define OSL_PCI_BUS(osh) osl_pci_bus(osh)
+#define OSL_PCI_SLOT(osh) osl_pci_slot(osh)
+extern uint osl_pci_bus(osl_t *osh);
+extern uint osl_pci_slot(osl_t *osh);
+extern struct pci_dev *osl_pci_device(osl_t *osh);
+
+/* Pkttag flag should be part of public information */
+typedef struct {
+ bool pkttag;
+ uint pktalloced; /* Number of allocated packet buffers */
+ bool mmbus; /* Bus supports memory-mapped register accesses */
+ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */
+ void *tx_ctx; /* Context to the callback function */
+ void *unused[3];
+} osl_pubinfo_t;
+
+#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \
+ do { \
+ ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \
+ ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \
+ } while (0)
+
+
+/* host/bus architecture-specific byte swap */
+#define BUS_SWAP32(v) (v)
+
+ #define MALLOC(osh, size) osl_malloc((osh), (size))
+ #define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size))
+ #define MALLOCED(osh) osl_malloced((osh))
+ extern void *osl_malloc(osl_t *osh, uint size);
+ extern void osl_mfree(osl_t *osh, void *addr, uint size);
+ extern uint osl_malloced(osl_t *osh);
+
+#define NATIVE_MALLOC(osh, size) kmalloc(size, GFP_ATOMIC)
+#define NATIVE_MFREE(osh, addr, size) kfree(addr)
+
+#define MALLOC_FAILED(osh) osl_malloc_failed((osh))
+extern uint osl_malloc_failed(osl_t *osh);
+
+/* allocate/free shared (dma-able) consistent memory */
+#define DMA_CONSISTENT_ALIGN osl_dma_consistent_align()
+#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \
+ osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap))
+#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
+ osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
+extern uint osl_dma_consistent_align(void);
+extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, uint *tot, ulong *pap);
+extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
+
+/* map/unmap direction */
+#define DMA_TX 1 /* TX direction for DMA */
+#define DMA_RX 2 /* RX direction for DMA */
+
+/* map/unmap shared (dma-able) memory */
+#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \
+ osl_dma_unmap((osh), (pa), (size), (direction))
+extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction);
+extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction);
+
+/* API for DMA addressing capability */
+#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
+
+/* register access macros */
+ #include <bcmsdh.h>
+ #define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(NULL, (uintptr)(r), sizeof(*(r)), (v)))
+ #define OSL_READ_REG(osh, r) (bcmsdh_reg_read(NULL, (uintptr)(r), sizeof(*(r))))
+
+ #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \
+ mmap_op else bus_op
+ #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \
+ mmap_op : bus_op
+
+#define OSL_ERROR(bcmerror) osl_error(bcmerror)
+extern int osl_error(int bcmerror);
+
+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
+#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */
+
+/*
+ * BINOSL selects the slightly slower function-call-based binary compatible osl.
+ * Macros expand to calls to functions defined in linux_osl.c .
+ */
+#include <linuxver.h> /* use current 2.4.x calling conventions */
+#include <linux/kernel.h> /* for vsn/printf's */
+#include <linux/string.h> /* for mem*, str* */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 29)
+#define OSL_SYSUPTIME() ((uint32)jiffies_to_msecs(jiffies))
+#else
+#define OSL_SYSUPTIME() ((uint32)jiffies * (1000 / HZ))
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 29) */
+#define printf(fmt, args...) pr_info(fmt , ## args)
+#include <linux/kernel.h> /* for vsn/printf's */
+#include <linux/string.h> /* for mem*, str* */
+/* bcopy's: Linux kernel doesn't provide these (anymore) */
+#define bcopy(src, dst, len) memcpy((dst), (src), (len))
+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
+#define bzero(b, len) memset((b), '\0', (len))
+
+/* register access macros */
+
+#define R_REG(osh, r) (\
+ SELECT_BUS_READ(osh, \
+ ({ \
+ __typeof(*(r)) __osl_v; \
+ BCM_REFERENCE(osh); \
+ switch (sizeof(*(r))) { \
+ case sizeof(uint8): __osl_v = \
+ readb((volatile uint8*)(r)); break; \
+ case sizeof(uint16): __osl_v = \
+ readw((volatile uint16*)(r)); break; \
+ case sizeof(uint32): __osl_v = \
+ readl((volatile uint32*)(r)); break; \
+ } \
+ __osl_v; \
+ }), \
+ OSL_READ_REG(osh, r)) \
+)
+
+#define W_REG(osh, r, v) do { \
+ BCM_REFERENCE(osh); \
+ SELECT_BUS_WRITE(osh, \
+ switch (sizeof(*(r))) { \
+ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \
+ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \
+ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \
+ }, \
+ (OSL_WRITE_REG(osh, r, v))); \
+ } while (0)
+
+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
+
+/* bcopy, bcmp, and bzero functions */
+#define bcopy(src, dst, len) memcpy((dst), (src), (len))
+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
+#define bzero(b, len) memset((b), '\0', (len))
+
+/* uncached/cached virtual address */
+#define OSL_UNCACHED(va) ((void *)va)
+#define OSL_CACHED(va) ((void *)va)
+
+#define OSL_PREF_RANGE_LD(va, sz)
+#define OSL_PREF_RANGE_ST(va, sz)
+
+/* get processor cycle count */
+#if defined(__i386__)
+#define OSL_GETCYCLES(x) rdtscl((x))
+#else
+#define OSL_GETCYCLES(x) ((x) = 0)
+#endif
+
+/* dereference an address that may cause a bus exception */
+#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; })
+
+/* map/unmap physical to virtual I/O */
+#if !defined(CONFIG_MMC_MSM7X00A)
+#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
+#else
+#define REG_MAP(pa, size) (void *)(0)
+#endif /* !defined(CONFIG_MMC_MSM7X00A */
+#define REG_UNMAP(va) iounmap((va))
+
+/* shared (dma-able) memory access macros */
+#define R_SM(r) *(r)
+#define W_SM(r, v) (*(r) = (v))
+#define BZERO_SM(r, len) memset((r), '\0', (len))
+
+/* Because the non BINOSL implemenation of the PKT OSL routines are macros (for
+ * performance reasons), we need the Linux headers.
+ */
+#include <linuxver.h> /* use current 2.4.x calling conventions */
+
+/* packet primitives */
+#define PKTGET(osh, len, send) osl_pktget((osh), (len))
+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb))
+#define PKTLIST_DUMP(osh, buf)
+#define PKTDBG_TRACE(osh, pkt, bit)
+#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len))
+#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send))
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data)
+#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len)
+#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head))
+#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
+#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next)
+#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
+#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len))
+#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes))
+#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes))
+#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb))
+#define PKTALLOCED(osh) ((osl_pubinfo_t *)(osh))->pktalloced
+#define PKTSETPOOL(osh, skb, x, y) do {} while (0)
+#define PKTPOOL(osh, skb) FALSE
+#define PKTSHRINK(osh, m) (m)
+
+#ifdef CTFPOOL
+#define CTFPOOL_REFILL_THRESH 3
+typedef struct ctfpool {
+ void *head;
+ spinlock_t lock;
+ uint max_obj;
+ uint curr_obj;
+ uint obj_size;
+ uint refills;
+ uint fast_allocs;
+ uint fast_frees;
+ uint slow_allocs;
+} ctfpool_t;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+#define FASTBUF (1 << 16)
+#define CTFBUF (1 << 17)
+#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= FASTBUF)
+#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~FASTBUF))
+#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) |= CTFBUF)
+#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) &= (~CTFBUF))
+#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & FASTBUF)
+#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->mac_len) & CTFBUF)
+#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->mac_len)
+#else
+#define FASTBUF (1 << 0)
+#define CTFBUF (1 << 1)
+#define PKTSETFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= FASTBUF)
+#define PKTCLRFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~FASTBUF))
+#define PKTSETCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) |= CTFBUF)
+#define PKTCLRCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) &= (~CTFBUF))
+#define PKTISFAST(osh, skb) ((((struct sk_buff*)(skb))->__unused) & FASTBUF)
+#define PKTISCTF(osh, skb) ((((struct sk_buff*)(skb))->__unused) & CTFBUF)
+#define PKTFAST(osh, skb) (((struct sk_buff*)(skb))->__unused)
+#endif /* 2.6.22 */
+
+#define CTFPOOLPTR(osh, skb) (((struct sk_buff*)(skb))->sk)
+#define CTFPOOLHEAD(osh, skb) (((ctfpool_t *)((struct sk_buff*)(skb))->sk)->head)
+
+extern void *osl_ctfpool_add(osl_t *osh);
+extern void osl_ctfpool_replenish(osl_t *osh, uint thresh);
+extern int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size);
+extern void osl_ctfpool_cleanup(osl_t *osh);
+extern void osl_ctfpool_stats(osl_t *osh, void *b);
+#endif /* CTFPOOL */
+
+
+#ifdef HNDCTF
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+#define SKIPCT (1 << 18)
+#define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len |= SKIPCT)
+#define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len &= (~SKIPCT))
+#define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->mac_len & SKIPCT)
+#else /* 2.6.22 */
+#define SKIPCT (1 << 2)
+#define PKTSETSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused |= SKIPCT)
+#define PKTCLRSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused &= (~SKIPCT))
+#define PKTSKIPCT(osh, skb) (((struct sk_buff*)(skb))->__unused & SKIPCT)
+#endif /* 2.6.22 */
+#else /* HNDCTF */
+#define PKTSETSKIPCT(osh, skb)
+#define PKTCLRSKIPCT(osh, skb)
+#define PKTSKIPCT(osh, skb)
+#endif /* HNDCTF */
+
+extern void osl_pktfree(osl_t *osh, void *skb, bool send);
+extern void *osl_pktget_static(osl_t *osh, uint len);
+extern void osl_pktfree_static(osl_t *osh, void *skb, bool send);
+
+extern void *osl_pkt_frmnative(osl_t *osh, void *skb);
+extern void *osl_pktget(osl_t *osh, uint len);
+extern void *osl_pktdup(osl_t *osh, void *skb);
+extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt);
+#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_t *)osh), (struct sk_buff*)(skb))
+#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((osl_t *)(osh), (pkt))
+
+#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev)
+#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
+#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority)
+#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x))
+#define PKTSUMNEEDED(skb) (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW)
+#define PKTSETSUMGOOD(skb, x) (((struct sk_buff*)(skb))->ip_summed = \
+ ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
+/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */
+#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned)
+
+#define DMA_MAP(osh, va, size, direction, p, dmah) \
+ osl_dma_map((osh), (va), (size), (direction))
+
+#ifdef PKTC
+/* Use 8 bytes of skb tstamp field to store below info */
+struct chain_node {
+ struct sk_buff *link;
+ unsigned int flags:3, pkts:9, bytes:20;
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+#define CHAIN_NODE(skb) ((struct chain_node*)&(((struct sk_buff*)skb)->tstamp))
+#else
+#define CHAIN_NODE(skb) ((struct chain_node*)&(((struct sk_buff*)skb)->stamp))
+#endif
+
+#define PKTCCNT(skb) (CHAIN_NODE(skb)->pkts)
+#define PKTCLEN(skb) (CHAIN_NODE(skb)->bytes)
+#define PKTCFLAGS(skb) (CHAIN_NODE(skb)->flags)
+#define PKTCSETCNT(skb, c) (CHAIN_NODE(skb)->pkts = (c) & ((1 << 9) - 1))
+#define PKTCSETLEN(skb, l) (CHAIN_NODE(skb)->bytes = (l) & ((1 << 20) - 1))
+#define PKTCSETFLAG(skb, fb) (CHAIN_NODE(skb)->flags |= (fb))
+#define PKTCCLRFLAG(skb, fb) (CHAIN_NODE(skb)->flags &= ~(fb))
+#define PKTCLINK(skb) (CHAIN_NODE(skb)->link)
+#define PKTSETCLINK(skb, x) (CHAIN_NODE(skb)->link = (struct sk_buff*)(x))
+#define PKTISCHAINED(skb) (PKTCLINK(skb) != NULL)
+#define FOREACH_CHAINED_PKT(skb, nskb) \
+ for (; (skb) != NULL; (skb) = (nskb)) \
+ if ((nskb) = PKTCLINK(skb), PKTSETCLINK((skb), NULL), 1)
+#define PKTCFREE(osh, skb, send) \
+do { \
+ void *nskb; \
+ ASSERT((skb) != NULL); \
+ FOREACH_CHAINED_PKT((skb), nskb) { \
+ PKTFREE((osh), (skb), (send)); \
+ } \
+} while (0)
+#endif /* PKTC */
+
+#else /* ! BCMDRIVER */
+
+
+/* ASSERT */
+ #define ASSERT(exp) do {} while (0)
+
+/* MALLOC and MFREE */
+#define MALLOC(o, l) malloc(l)
+#define MFREE(o, p, l) free(p)
+#include <stdlib.h>
+
+/* str* and mem* functions */
+#include <string.h>
+
+/* *printf functions */
+#include <stdio.h>
+
+/* bcopy, bcmp, and bzero */
+extern void bcopy(const void *src, void *dst, size_t len);
+extern int bcmp(const void *b1, const void *b2, size_t len);
+extern void bzero(void *b, size_t len);
+#endif /* ! BCMDRIVER */
+
+#endif /* _linux_osl_h_ */
diff --git a/drivers/net/wireless/ap6210/include/linuxver.h b/drivers/net/wireless/ap6210/include/linuxver.h
new file mode 100644
index 0000000..e01b8f0
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/linuxver.h
@@ -0,0 +1,652 @@
+/*
+ * Linux-specific abstractions to gain some independence from linux kernel versions.
+ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: linuxver.h 366812 2012-11-05 13:49:32Z $
+ */
+
+#ifndef _linuxver_h_
+#define _linuxver_h_
+
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+#include <linux/config.h>
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
+#include <generated/autoconf.h>
+#else
+#include <linux/autoconf.h>
+#endif
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */
+#include <linux/module.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0))
+/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */
+#ifdef __UNDEF_NO_VERSION__
+#undef __NO_VERSION__
+#else
+#define __NO_VERSION__
+#endif
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
+#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i")
+#define module_param_string(_name_, _string_, _size_, _perm_) \
+ MODULE_PARM(_string_, "c" __MODULE_STRING(_size_))
+#endif
+
+/* linux/malloc.h is deprecated, use linux/slab.h instead. */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9))
+#include <linux/malloc.h>
+#else
+#include <linux/slab.h>
+#endif
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
+#undef IP_TOS
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) */
+#include <asm/io.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41))
+#include <linux/workqueue.h>
+#else
+#include <linux/tqueue.h>
+#ifndef work_struct
+#define work_struct tq_struct
+#endif
+#ifndef INIT_WORK
+#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data))
+#endif
+#ifndef schedule_work
+#define schedule_work(_work) schedule_task((_work))
+#endif
+#ifndef flush_scheduled_work
+#define flush_scheduled_work() flush_scheduled_tasks()
+#endif
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define DAEMONIZE(a) daemonize(a); \
+ allow_signal(SIGKILL); \
+ allow_signal(SIGTERM);
+#else /* Linux 2.4 (w/o preemption patch) */
+#define RAISE_RX_SOFTIRQ() \
+ cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ)
+#define DAEMONIZE(a) daemonize(); \
+ do { if (a) \
+ strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a)))); \
+ } while (0);
+#endif /* LINUX_VERSION_CODE */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func)
+#else
+#define MY_INIT_WORK(_work, _func) INIT_WORK(_work, _func, _work)
+#if !(LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18) && defined(RHEL_MAJOR) && \
+ (RHEL_MAJOR == 5))
+/* Exclude RHEL 5 */
+typedef void (*work_func_t)(void *work);
+#endif
+#endif /* >= 2.6.20 */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+/* Some distributions have their own 2.6.x compatibility layers */
+#ifndef IRQ_NONE
+typedef void irqreturn_t;
+#define IRQ_NONE
+#define IRQ_HANDLED
+#define IRQ_RETVAL(x)
+#endif
+#else
+typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
+#define IRQF_SHARED SA_SHIRQ
+#endif /* < 2.6.18 */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
+#ifdef CONFIG_NET_RADIO
+#define CONFIG_WIRELESS_EXT
+#endif
+#endif /* < 2.6.17 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67)
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 67) */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+#include <linux/sched.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+#include <net/lib80211.h>
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+#include <linux/ieee80211.h>
+#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+#include <net/ieee80211.h>
+#endif
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) */
+
+
+
+#ifndef __exit
+#define __exit
+#endif
+#ifndef __devexit
+#define __devexit
+#endif
+#ifndef __devinit
+#define __devinit __init
+#endif
+#ifndef __devinitdata
+#define __devinitdata
+#endif
+#ifndef __devexit_p
+#define __devexit_p(x) x
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+
+#define pci_get_drvdata(dev) (dev)->sysdata
+#define pci_set_drvdata(dev, value) (dev)->sysdata = (value)
+
+/*
+ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration
+ */
+
+struct pci_device_id {
+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
+ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
+ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
+ unsigned long driver_data; /* Data private to the driver */
+};
+
+struct pci_driver {
+ struct list_head node;
+ char *name;
+ const struct pci_device_id *id_table; /* NULL if wants all devices */
+ int (*probe)(struct pci_dev *dev,
+ const struct pci_device_id *id); /* New device inserted */
+ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug
+ * capable driver)
+ */
+ void (*suspend)(struct pci_dev *dev); /* Device suspended */
+ void (*resume)(struct pci_dev *dev); /* Device woken up */
+};
+
+#define MODULE_DEVICE_TABLE(type, name)
+#define PCI_ANY_ID (~0)
+
+/* compatpci.c */
+#define pci_module_init pci_register_driver
+extern int pci_register_driver(struct pci_driver *drv);
+extern void pci_unregister_driver(struct pci_driver *drv);
+
+#endif /* PCI registration */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
+#define pci_module_init pci_register_driver
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18))
+#ifdef MODULE
+#define module_init(x) int init_module(void) { return x(); }
+#define module_exit(x) void cleanup_module(void) { x(); }
+#else
+#define module_init(x) __initcall(x);
+#define module_exit(x) __exitcall(x);
+#endif
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
+#define WL_USE_NETDEV_OPS
+#else
+#undef WL_USE_NETDEV_OPS
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) && defined(CONFIG_RFKILL)
+#define WL_CONFIG_RFKILL
+#else
+#undef WL_CONFIG_RFKILL
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48))
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13))
+#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)])
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44))
+#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23))
+#define pci_enable_device(dev) do { } while (0)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14))
+#define net_device device
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42))
+
+/*
+ * DMA mapping
+ *
+ * See linux/Documentation/DMA-mapping.txt
+ */
+
+#ifndef PCI_DMA_TODEVICE
+#define PCI_DMA_TODEVICE 1
+#define PCI_DMA_FROMDEVICE 2
+#endif
+
+typedef u32 dma_addr_t;
+
+/* Pure 2^n version of get_order */
+static inline int get_order(unsigned long size)
+{
+ int order;
+
+ size = (size-1) >> (PAGE_SHIFT-1);
+ order = -1;
+ do {
+ size >>= 1;
+ order++;
+ } while (size);
+ return order;
+}
+
+static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle)
+{
+ void *ret;
+ int gfp = GFP_ATOMIC | GFP_DMA;
+
+ ret = (void *)__get_free_pages(gfp, get_order(size));
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_bus(ret);
+ }
+ return ret;
+}
+static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ free_pages((unsigned long)vaddr, get_order(size));
+}
+#define pci_map_single(cookie, address, size, dir) virt_to_bus(address)
+#define pci_unmap_single(cookie, address, size, dir)
+
+#endif /* DMA mapping */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43))
+
+#define dev_kfree_skb_any(a) dev_kfree_skb(a)
+#define netif_down(dev) do { (dev)->start = 0; } while (0)
+
+/* pcmcia-cs provides its own netdevice compatibility layer */
+#ifndef _COMPAT_NETDEVICE_H
+
+/*
+ * SoftNet
+ *
+ * For pre-softnet kernels we need to tell the upper layer not to
+ * re-enter start_xmit() while we are in there. However softnet
+ * guarantees not to enter while we are in there so there is no need
+ * to do the netif_stop_queue() dance unless the transmit queue really
+ * gets stuck. This should also improve performance according to tests
+ * done by Aman Singla.
+ */
+
+#define dev_kfree_skb_irq(a) dev_kfree_skb(a)
+#define netif_wake_queue(dev) \
+ do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0)
+#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy)
+
+static inline void netif_start_queue(struct net_device *dev)
+{
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+}
+
+#define netif_queue_stopped(dev) (dev)->tbusy
+#define netif_running(dev) (dev)->start
+
+#endif /* _COMPAT_NETDEVICE_H */
+
+#define netif_device_attach(dev) netif_start_queue(dev)
+#define netif_device_detach(dev) netif_stop_queue(dev)
+
+/* 2.4.x renamed bottom halves to tasklets */
+#define tasklet_struct tq_struct
+static inline void tasklet_schedule(struct tasklet_struct *tasklet)
+{
+ queue_task(tasklet, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+}
+
+static inline void tasklet_init(struct tasklet_struct *tasklet,
+ void (*func)(unsigned long),
+ unsigned long data)
+{
+ tasklet->next = NULL;
+ tasklet->sync = 0;
+ tasklet->routine = (void (*)(void *))func;
+ tasklet->data = (void *)data;
+}
+#define tasklet_kill(tasklet) { do {} while (0); }
+
+/* 2.4.x introduced del_timer_sync() */
+#define del_timer_sync(timer) del_timer(timer)
+
+#else
+
+#define netif_down(dev)
+
+#endif /* SoftNet */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3))
+
+/*
+ * Emit code to initialise a tq_struct's routine and data pointers
+ */
+#define PREPARE_TQUEUE(_tq, _routine, _data) \
+ do { \
+ (_tq)->routine = _routine; \
+ (_tq)->data = _data; \
+ } while (0)
+
+/*
+ * Emit code to initialise all of a tq_struct
+ */
+#define INIT_TQUEUE(_tq, _routine, _data) \
+ do { \
+ INIT_LIST_HEAD(&(_tq)->list); \
+ (_tq)->sync = 0; \
+ PREPARE_TQUEUE((_tq), (_routine), (_data)); \
+ } while (0)
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) */
+
+/* Power management related macro & routines */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 9)
+#define PCI_SAVE_STATE(a, b) pci_save_state(a)
+#define PCI_RESTORE_STATE(a, b) pci_restore_state(a)
+#else
+#define PCI_SAVE_STATE(a, b) pci_save_state(a, b)
+#define PCI_RESTORE_STATE(a, b) pci_restore_state(a, b)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6))
+static inline int
+pci_save_state(struct pci_dev *dev, u32 *buffer)
+{
+ int i;
+ if (buffer) {
+ for (i = 0; i < 16; i++)
+ pci_read_config_dword(dev, i * 4, &buffer[i]);
+ }
+ return 0;
+}
+
+static inline int
+pci_restore_state(struct pci_dev *dev, u32 *buffer)
+{
+ int i;
+
+ if (buffer) {
+ for (i = 0; i < 16; i++)
+ pci_write_config_dword(dev, i * 4, buffer[i]);
+ }
+ /*
+ * otherwise, write the context information we know from bootup.
+ * This works around a problem where warm-booting from Windows
+ * combined with a D3(hot)->D0 transition causes PCI config
+ * header data to be forgotten.
+ */
+ else {
+ for (i = 0; i < 6; i ++)
+ pci_write_config_dword(dev,
+ PCI_BASE_ADDRESS_0 + (i * 4),
+ pci_resource_start(dev, i));
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
+ return 0;
+}
+#endif /* PCI power management */
+
+/* Old cp0 access macros deprecated in 2.4.19 */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19))
+#define read_c0_count() read_32bit_cp0_register(CP0_COUNT)
+#endif
+
+/* Module refcount handled internally in 2.6.x */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
+#ifndef SET_MODULE_OWNER
+#define SET_MODULE_OWNER(dev) do {} while (0)
+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
+#else
+#define OLD_MOD_INC_USE_COUNT do {} while (0)
+#define OLD_MOD_DEC_USE_COUNT do {} while (0)
+#endif
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */
+#ifndef SET_MODULE_OWNER
+#define SET_MODULE_OWNER(dev) do {} while (0)
+#endif
+#ifndef MOD_INC_USE_COUNT
+#define MOD_INC_USE_COUNT do {} while (0)
+#endif
+#ifndef MOD_DEC_USE_COUNT
+#define MOD_DEC_USE_COUNT do {} while (0)
+#endif
+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */
+
+#ifndef SET_NETDEV_DEV
+#define SET_NETDEV_DEV(net, pdev) do {} while (0)
+#endif
+
+#ifndef HAVE_FREE_NETDEV
+#define free_netdev(dev) kfree(dev)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+/* struct packet_type redefined in 2.6.x */
+#define af_packet_priv data
+#endif
+
+/* suspend args */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+#define DRV_SUSPEND_STATE_TYPE pm_message_t
+#else
+#define DRV_SUSPEND_STATE_TYPE uint32
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+#define CHECKSUM_HW CHECKSUM_PARTIAL
+#endif
+
+typedef struct {
+ void *parent; /* some external entity that the thread supposed to work for */
+ struct task_struct *p_task;
+ long thr_pid;
+ int prio; /* priority */
+ struct semaphore sema;
+ int terminated;
+ struct completion completed;
+} tsk_ctl_t;
+
+
+/* requires tsk_ctl_t tsk argument, the caller's priv data is passed in owner ptr */
+/* note this macro assumes there may be only one context waiting on thread's completion */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define SMP_RD_BARRIER_DEPENDS(x) smp_read_barrier_depends(x)
+#else
+#define SMP_RD_BARRIER_DEPENDS(x) smp_rmb(x)
+#endif
+
+
+#define PROC_START(thread_func, owner, tsk_ctl, flags) \
+{ \
+ sema_init(&((tsk_ctl)->sema), 0); \
+ init_completion(&((tsk_ctl)->completed)); \
+ (tsk_ctl)->parent = owner; \
+ (tsk_ctl)->terminated = FALSE; \
+ (tsk_ctl)->thr_pid = kernel_thread(thread_func, tsk_ctl, flags); \
+ if ((tsk_ctl)->thr_pid > 0) \
+ wait_for_completion(&((tsk_ctl)->completed)); \
+}
+
+#ifdef USE_KTHREAD_API
+#define PROC_START2(thread_func, owner, tsk_ctl, flags, name) \
+{ \
+ sema_init(&((tsk_ctl)->sema), 0); \
+ init_completion(&((tsk_ctl)->completed)); \
+ (tsk_ctl)->parent = owner; \
+ (tsk_ctl)->terminated = FALSE; \
+ (tsk_ctl)->p_task = kthread_run(thread_func, tsk_ctl, (char*)name); \
+ (tsk_ctl)->thr_pid = (tsk_ctl)->p_task->pid; \
+}
+#endif
+
+#define PROC_STOP(tsk_ctl) \
+{ \
+ (tsk_ctl)->terminated = TRUE; \
+ smp_wmb(); \
+ up(&((tsk_ctl)->sema)); \
+ wait_for_completion(&((tsk_ctl)->completed)); \
+ (tsk_ctl)->thr_pid = -1; \
+}
+
+/* ----------------------- */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
+#define KILL_PROC(nr, sig) \
+{ \
+struct task_struct *tsk; \
+struct pid *pid; \
+pid = find_get_pid((pid_t)nr); \
+tsk = pid_task(pid, PIDTYPE_PID); \
+if (tsk) send_sig(sig, tsk, 1); \
+}
+#else
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \
+ KERNEL_VERSION(2, 6, 30))
+#define KILL_PROC(pid, sig) \
+{ \
+ struct task_struct *tsk; \
+ tsk = find_task_by_vpid(pid); \
+ if (tsk) send_sig(sig, tsk, 1); \
+}
+#else
+#define KILL_PROC(pid, sig) \
+{ \
+ kill_proc(pid, sig, 1); \
+}
+#endif
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#include <linux/time.h>
+#include <linux/wait.h>
+#else
+#include <linux/sched.h>
+
+#define __wait_event_interruptible_timeout(wq, condition, ret) \
+do { \
+ wait_queue_t __wait; \
+ init_waitqueue_entry(&__wait, current); \
+ \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ set_current_state(TASK_INTERRUPTIBLE); \
+ if (condition) \
+ break; \
+ if (!signal_pending(current)) { \
+ ret = schedule_timeout(ret); \
+ if (!ret) \
+ break; \
+ continue; \
+ } \
+ ret = -ERESTARTSYS; \
+ break; \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#define wait_event_interruptible_timeout(wq, condition, timeout) \
+({ \
+ long __ret = timeout; \
+ if (!(condition)) \
+ __wait_event_interruptible_timeout(wq, condition, __ret); \
+ __ret; \
+})
+
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) */
+
+/*
+For < 2.6.24, wl creates its own netdev but doesn't
+align the priv area like the genuine alloc_netdev().
+Since netdev_priv() always gives us the aligned address, it will
+not match our unaligned address for < 2.6.24
+*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
+#define DEV_PRIV(dev) (dev->priv)
+#else
+#define DEV_PRIV(dev) netdev_priv(dev)
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+#define WL_ISR(i, d, p) wl_isr((i), (d))
+#else
+#define WL_ISR(i, d, p) wl_isr((i), (d), (p))
+#endif /* < 2.6.20 */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+#define netdev_priv(dev) dev->priv
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */
+
+#endif /* _linuxver_h_ */
diff --git a/drivers/net/wireless/ap6210/include/miniopt.h b/drivers/net/wireless/ap6210/include/miniopt.h
new file mode 100644
index 0000000..c1eca68
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/miniopt.h
@@ -0,0 +1,77 @@
+/*
+ * Command line options parser.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ * $Id: miniopt.h 241182 2011-02-17 21:50:03Z $
+ */
+
+
+#ifndef MINI_OPT_H
+#define MINI_OPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---- Include Files ---------------------------------------------------- */
+/* ---- Constants and Types ---------------------------------------------- */
+
+#define MINIOPT_MAXKEY 128 /* Max options */
+typedef struct miniopt {
+
+ /* These are persistent after miniopt_init() */
+ const char* name; /* name for prompt in error strings */
+ const char* flags; /* option chars that take no args */
+ bool longflags; /* long options may be flags */
+ bool opt_end; /* at end of options (passed a "--") */
+
+ /* These are per-call to miniopt() */
+
+ int consumed; /* number of argv entries cosumed in
+ * the most recent call to miniopt()
+ */
+ bool positional;
+ bool good_int; /* 'val' member is the result of a sucessful
+ * strtol conversion of the option value
+ */
+ char opt;
+ char key[MINIOPT_MAXKEY];
+ char* valstr; /* positional param, or value for the option,
+ * or null if the option had
+ * no accompanying value
+ */
+ uint uval; /* strtol translation of valstr */
+ int val; /* strtol translation of valstr */
+} miniopt_t;
+
+void miniopt_init(miniopt_t *t, const char* name, const char* flags, bool longflags);
+int miniopt(miniopt_t *t, char **argv);
+
+
+/* ---- Variable Externs ------------------------------------------------- */
+/* ---- Function Prototypes ---------------------------------------------- */
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* MINI_OPT_H */
diff --git a/drivers/net/wireless/ap6210/include/msgtrace.h b/drivers/net/wireless/ap6210/include/msgtrace.h
new file mode 100644
index 0000000..7c5fd81
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/msgtrace.h
@@ -0,0 +1,74 @@
+/*
+ * Trace messages sent over HBUS
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: msgtrace.h 281527 2011-09-02 17:12:53Z $
+ */
+
+#ifndef _MSGTRACE_H
+#define _MSGTRACE_H
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+#define MSGTRACE_VERSION 1
+
+/* Message trace header */
+typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr {
+ uint8 version;
+ uint8 spare;
+ uint16 len; /* Len of the trace */
+ uint32 seqnum; /* Sequence number of message. Useful if the messsage has been lost
+ * because of DMA error or a bus reset (ex: SDIO Func2)
+ */
+ uint32 discarded_bytes; /* Number of discarded bytes because of trace overflow */
+ uint32 discarded_printf; /* Number of discarded printf because of trace overflow */
+} BWL_POST_PACKED_STRUCT msgtrace_hdr_t;
+
+#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t)
+
+/* The hbus driver generates traces when sending a trace message. This causes endless traces.
+ * This flag must be set to TRUE in any hbus traces. The flag is reset in the function msgtrace_put.
+ * This prevents endless traces but generates hasardous lost of traces only in bus device code.
+ * It is recommendat to set this flag in macro SD_TRACE but not in SD_ERROR for avoiding missing
+ * hbus error traces. hbus error trace should not generates endless traces.
+ */
+extern bool msgtrace_hbus_trace;
+
+typedef void (*msgtrace_func_send_t)(void *hdl1, void *hdl2, uint8 *hdr,
+ uint16 hdrlen, uint8 *buf, uint16 buflen);
+extern void msgtrace_start(void);
+extern void msgtrace_stop(void);
+extern void msgtrace_sent(void);
+extern void msgtrace_put(char *buf, int count);
+extern void msgtrace_init(void *hdl1, void *hdl2, msgtrace_func_send_t func_send);
+extern bool msgtrace_event_enabled(void);
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _MSGTRACE_H */
diff --git a/drivers/net/wireless/ap6210/include/osl.h b/drivers/net/wireless/ap6210/include/osl.h
new file mode 100644
index 0000000..0a11d23
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/osl.h
@@ -0,0 +1,90 @@
+/*
+ * OS Abstraction Layer
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: osl.h 320905 2012-03-13 15:33:25Z $
+ */
+
+#ifndef _osl_h_
+#define _osl_h_
+
+/* osl handle type forward declaration */
+typedef struct osl_info osl_t;
+typedef struct osl_dmainfo osldma_t;
+
+#define OSL_PKTTAG_SZ 32 /* Size of PktTag */
+
+/* Drivers use PKTFREESETCB to register a callback function when a packet is freed by OSL */
+typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status);
+
+/* Drivers use REGOPSSET() to register register read/write funcitons */
+typedef unsigned int (*osl_rreg_fn_t)(void *ctx, volatile void *reg, unsigned int size);
+typedef void (*osl_wreg_fn_t)(void *ctx, volatile void *reg, unsigned int val, unsigned int size);
+
+
+#include <linux_osl.h>
+
+#ifndef PKTDBG_TRACE
+#define PKTDBG_TRACE(osh, pkt, bit)
+#endif
+
+#define PKTCTFMAP(osh, p)
+
+/* --------------------------------------------------------------------------
+** Register manipulation macros.
+*/
+
+#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val)))
+
+#ifndef AND_REG
+#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
+#endif /* !AND_REG */
+
+#ifndef OR_REG
+#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
+#endif /* !OR_REG */
+
+#if !defined(OSL_SYSUPTIME)
+#define OSL_SYSUPTIME() (0)
+#define OSL_SYSUPTIME_SUPPORT FALSE
+#else
+#define OSL_SYSUPTIME_SUPPORT TRUE
+#endif /* OSL_SYSUPTIME */
+
+#if !defined(PKTC)
+#define PKTCCNT(skb) (0)
+#define PKTCLEN(skb) (0)
+#define PKTCFLAGS(skb) (0)
+#define PKTCSETCNT(skb, c)
+#define PKTCSETLEN(skb, l)
+#define PKTCSETFLAG(skb, fb)
+#define PKTCCLRFLAG(skb, fb)
+#define PKTCLINK(skb) PKTLINK(skb)
+#define PKTSETCLINK(skb, x) PKTSETLINK((skb), (x))
+#define PKTISCHAINED(skb) FALSE
+#define FOREACH_CHAINED_PKT(skb, nskb) \
+ for ((nskb) = NULL; (skb) != NULL; (skb) = (nskb))
+#define PKTCFREE PKTFREE
+#endif
+
+
+#endif /* _osl_h_ */
diff --git a/drivers/net/wireless/ap6210/include/packed_section_end.h b/drivers/net/wireless/ap6210/include/packed_section_end.h
new file mode 100644
index 0000000..0779b04
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/packed_section_end.h
@@ -0,0 +1,59 @@
+/*
+ * Declare directives for structure packing. No padding will be provided
+ * between the members of packed structures, and therefore, there is no
+ * guarantee that structure members will be aligned.
+ *
+ * Declaring packed structures is compiler specific. In order to handle all
+ * cases, packed structures should be delared as:
+ *
+ * #include <packed_section_start.h>
+ *
+ * typedef BWL_PRE_PACKED_STRUCT struct foobar_t {
+ * some_struct_members;
+ * } BWL_POST_PACKED_STRUCT foobar_t;
+ *
+ * #include <packed_section_end.h>
+ *
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ * $Id: packed_section_end.h 241182 2011-02-17 21:50:03Z $
+ */
+
+
+/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h
+ * and undefined in packed_section_end.h. If it is NOT defined at this
+ * point, then there is a missing include of packed_section_start.h.
+ */
+#ifdef BWL_PACKED_SECTION
+ #undef BWL_PACKED_SECTION
+#else
+ #error "BWL_PACKED_SECTION is NOT defined!"
+#endif
+
+
+
+
+/* Compiler-specific directives for structure packing are declared in
+ * packed_section_start.h. This marks the end of the structure packing section,
+ * so, undef them here.
+ */
+#undef BWL_PRE_PACKED_STRUCT
+#undef BWL_POST_PACKED_STRUCT
diff --git a/drivers/net/wireless/ap6210/include/packed_section_start.h b/drivers/net/wireless/ap6210/include/packed_section_start.h
new file mode 100644
index 0000000..ee93a4b
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/packed_section_start.h
@@ -0,0 +1,63 @@
+/*
+ * Declare directives for structure packing. No padding will be provided
+ * between the members of packed structures, and therefore, there is no
+ * guarantee that structure members will be aligned.
+ *
+ * Declaring packed structures is compiler specific. In order to handle all
+ * cases, packed structures should be delared as:
+ *
+ * #include <packed_section_start.h>
+ *
+ * typedef BWL_PRE_PACKED_STRUCT struct foobar_t {
+ * some_struct_members;
+ * } BWL_POST_PACKED_STRUCT foobar_t;
+ *
+ * #include <packed_section_end.h>
+ *
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ * $Id: packed_section_start.h 286783 2011-09-29 06:18:57Z $
+ */
+
+
+/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h
+ * and undefined in packed_section_end.h. If it is already defined at this
+ * point, then there is a missing include of packed_section_end.h.
+ */
+#ifdef BWL_PACKED_SECTION
+ #error "BWL_PACKED_SECTION is already defined!"
+#else
+ #define BWL_PACKED_SECTION
+#endif
+
+
+
+
+/* Declare compiler-specific directives for structure packing. */
+#if defined(__GNUC__) || defined(__lint)
+ #define BWL_PRE_PACKED_STRUCT
+ #define BWL_POST_PACKED_STRUCT __attribute__ ((packed))
+#elif defined(__CC_ARM)
+ #define BWL_PRE_PACKED_STRUCT __packed
+ #define BWL_POST_PACKED_STRUCT
+#else
+ #error "Unknown compiler!"
+#endif
diff --git a/drivers/net/wireless/ap6210/include/pcicfg.h b/drivers/net/wireless/ap6210/include/pcicfg.h
new file mode 100644
index 0000000..0278bb2
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/pcicfg.h
@@ -0,0 +1,100 @@
+/*
+ * pcicfg.h: PCI configuration constants and structures.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: pcicfg.h 309193 2012-01-19 00:03:57Z $
+ */
+
+#ifndef _h_pcicfg_
+#define _h_pcicfg_
+
+/* A structure for the config registers is nice, but in most
+ * systems the config space is not memory mapped, so we need
+ * field offsetts. :-(
+ */
+#define PCI_CFG_VID 0
+#define PCI_CFG_DID 2
+#define PCI_CFG_CMD 4
+#define PCI_CFG_STAT 6
+#define PCI_CFG_REV 8
+#define PCI_CFG_PROGIF 9
+#define PCI_CFG_SUBCL 0xa
+#define PCI_CFG_BASECL 0xb
+#define PCI_CFG_CLSZ 0xc
+#define PCI_CFG_LATTIM 0xd
+#define PCI_CFG_HDR 0xe
+#define PCI_CFG_BIST 0xf
+#define PCI_CFG_BAR0 0x10
+#define PCI_CFG_BAR1 0x14
+#define PCI_CFG_BAR2 0x18
+#define PCI_CFG_BAR3 0x1c
+#define PCI_CFG_BAR4 0x20
+#define PCI_CFG_BAR5 0x24
+#define PCI_CFG_CIS 0x28
+#define PCI_CFG_SVID 0x2c
+#define PCI_CFG_SSID 0x2e
+#define PCI_CFG_ROMBAR 0x30
+#define PCI_CFG_CAPPTR 0x34
+#define PCI_CFG_INT 0x3c
+#define PCI_CFG_PIN 0x3d
+#define PCI_CFG_MINGNT 0x3e
+#define PCI_CFG_MAXLAT 0x3f
+#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */
+#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */
+#define PCI_SPROM_CONTROL 0x88 /* sprom property control */
+#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */
+#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */
+#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */
+#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */
+#define PCI_BACKPLANE_ADDR 0xa0 /* address an arbitrary location on the system backplane */
+#define PCI_BACKPLANE_DATA 0xa4 /* data at the location specified by above address */
+#define PCI_CLK_CTL_ST 0xa8 /* pci config space clock control/status (>=rev14) */
+#define PCI_BAR0_WIN2 0xac /* backplane addres space accessed by second 4KB of BAR0 */
+#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */
+#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */
+#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */
+
+#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */
+#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */
+#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */
+#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the
+ * 8KB window, so their address is the "regular"
+ * address plus 4K
+ */
+/*
+ * PCIE GEN2 changed some of the above locations for
+ * Bar0WrapperBase, SecondaryBAR0Window and SecondaryBAR0WrapperBase
+ * BAR0 maps 32K of register space
+*/
+#define PCIE2_BAR0_WIN2 0x70 /* backplane addres space accessed by second 4KB of BAR0 */
+#define PCIE2_BAR0_CORE2_WIN 0x74 /* backplane addres space accessed by second 4KB of BAR0 */
+#define PCIE2_BAR0_CORE2_WIN2 0x78 /* backplane addres space accessed by second 4KB of BAR0 */
+
+#define PCI_BAR0_WINSZ (16 * 1024) /* bar0 window size Match with corerev 13 */
+/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
+#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */
+#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */
+#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */
+
+
+#define PCI_CONFIG_SPACE_SIZE 256
+#endif /* _h_pcicfg_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/802.11.h b/drivers/net/wireless/ap6210/include/proto/802.11.h
new file mode 100644
index 0000000..15cd56c
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/802.11.h
@@ -0,0 +1,2355 @@
+/*
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * Fundamental types and constants relating to 802.11
+ *
+ * $Id: 802.11.h 346820 2012-07-24 13:53:12Z $
+ */
+
+#ifndef _802_11_H_
+#define _802_11_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+#ifndef _NET_ETHERNET_H_
+#include <proto/ethernet.h>
+#endif
+
+#include <proto/wpa.h>
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+
+#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */
+
+/* Generic 802.11 frame constants */
+#define DOT11_A3_HDR_LEN 24 /* d11 header length with A3 */
+#define DOT11_A4_HDR_LEN 30 /* d11 header length with A4 */
+#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN /* MAC header length */
+#define DOT11_FCS_LEN 4 /* d11 FCS length */
+#define DOT11_ICV_LEN 4 /* d11 ICV length */
+#define DOT11_ICV_AES_LEN 8 /* d11 ICV/AES length */
+#define DOT11_QOS_LEN 2 /* d11 QoS length */
+#define DOT11_HTC_LEN 4 /* d11 HT Control field length */
+
+#define DOT11_KEY_INDEX_SHIFT 6 /* d11 key index shift */
+#define DOT11_IV_LEN 4 /* d11 IV length */
+#define DOT11_IV_TKIP_LEN 8 /* d11 IV TKIP length */
+#define DOT11_IV_AES_OCB_LEN 4 /* d11 IV/AES/OCB length */
+#define DOT11_IV_AES_CCM_LEN 8 /* d11 IV/AES/CCM length */
+#define DOT11_IV_MAX_LEN 8 /* maximum iv len for any encryption */
+
+/* Includes MIC */
+#define DOT11_MAX_MPDU_BODY_LEN 2304 /* max MPDU body length */
+/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */
+#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \
+ DOT11_QOS_LEN + \
+ DOT11_IV_AES_CCM_LEN + \
+ DOT11_MAX_MPDU_BODY_LEN + \
+ DOT11_ICV_LEN + \
+ DOT11_FCS_LEN) /* d11 max MPDU length */
+
+#define DOT11_MAX_SSID_LEN 32 /* d11 max ssid length */
+
+/* dot11RTSThreshold */
+#define DOT11_DEFAULT_RTS_LEN 2347 /* d11 default RTS length */
+#define DOT11_MAX_RTS_LEN 2347 /* d11 max RTS length */
+
+/* dot11FragmentationThreshold */
+#define DOT11_MIN_FRAG_LEN 256 /* d11 min fragmentation length */
+#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength
+ * of the attached PHY
+ */
+#define DOT11_DEFAULT_FRAG_LEN 2346 /* d11 default fragmentation length */
+
+/* dot11BeaconPeriod */
+#define DOT11_MIN_BEACON_PERIOD 1 /* d11 min beacon period */
+#define DOT11_MAX_BEACON_PERIOD 0xFFFF /* d11 max beacon period */
+
+/* dot11DTIMPeriod */
+#define DOT11_MIN_DTIM_PERIOD 1 /* d11 min DTIM period */
+#define DOT11_MAX_DTIM_PERIOD 0xFF /* d11 max DTIM period */
+
+/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */
+#define DOT11_LLC_SNAP_HDR_LEN 8 /* d11 LLC/SNAP header length */
+#define DOT11_OUI_LEN 3 /* d11 OUI length */
+BWL_PRE_PACKED_STRUCT struct dot11_llc_snap_header {
+ uint8 dsap; /* always 0xAA */
+ uint8 ssap; /* always 0xAA */
+ uint8 ctl; /* always 0x03 */
+ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00
+ * Bridge-Tunnel: 0x00 0x00 0xF8
+ */
+ uint16 type; /* ethertype */
+} BWL_POST_PACKED_STRUCT;
+
+/* RFC1042 header used by 802.11 per 802.1H */
+#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) /* RCF1042 header length */
+
+/* Generic 802.11 MAC header */
+/*
+ * N.B.: This struct reflects the full 4 address 802.11 MAC header.
+ * The fields are defined such that the shorter 1, 2, and 3
+ * address headers just use the first k fields.
+ */
+BWL_PRE_PACKED_STRUCT struct dot11_header {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr a1; /* address 1 */
+ struct ether_addr a2; /* address 2 */
+ struct ether_addr a3; /* address 3 */
+ uint16 seq; /* sequence control */
+ struct ether_addr a4; /* address 4 */
+} BWL_POST_PACKED_STRUCT;
+
+/* Control frames */
+
+BWL_PRE_PACKED_STRUCT struct dot11_rts_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+ struct ether_addr ta; /* transmitter address */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_RTS_LEN 16 /* d11 RTS frame length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_cts_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_CTS_LEN 10 /* d11 CTS frame length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_ack_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ACK_LEN 10 /* d11 ACK frame length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_ps_poll_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* AID */
+ struct ether_addr bssid; /* receiver address, STA in AP */
+ struct ether_addr ta; /* transmitter address */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_PS_POLL_LEN 16 /* d11 PS poll frame length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_cf_end_frame {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+ struct ether_addr bssid; /* transmitter address, STA in AP */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_CS_END_LEN 16 /* d11 CF-END frame length */
+
+/* RWL wifi protocol: The Vendor Specific Action frame is defined for vendor-specific signaling
+* category+OUI+vendor specific content ( this can be variable)
+*/
+BWL_PRE_PACKED_STRUCT struct dot11_action_wifi_vendor_specific {
+ uint8 category;
+ uint8 OUI[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 data[1040];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_action_wifi_vendor_specific dot11_action_wifi_vendor_specific_t;
+
+/* generic vender specific action frame with variable length */
+BWL_PRE_PACKED_STRUCT struct dot11_action_vs_frmhdr {
+ uint8 category;
+ uint8 OUI[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_action_vs_frmhdr dot11_action_vs_frmhdr_t;
+#define DOT11_ACTION_VS_HDR_LEN 6
+
+#define BCM_ACTION_OUI_BYTE0 0x00
+#define BCM_ACTION_OUI_BYTE1 0x90
+#define BCM_ACTION_OUI_BYTE2 0x4c
+
+/* BA/BAR Control parameters */
+#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 /* normal ack */
+#define DOT11_BA_CTL_POLICY_NOACK 0x0001 /* no ack */
+#define DOT11_BA_CTL_POLICY_MASK 0x0001 /* ack policy mask */
+
+#define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */
+#define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */
+
+#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */
+#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */
+
+#define DOT11_BA_CTL_TID_MASK 0xF000 /* tid mask */
+#define DOT11_BA_CTL_TID_SHIFT 12 /* tid shift */
+
+/* control frame header (BA/BAR) */
+BWL_PRE_PACKED_STRUCT struct dot11_ctl_header {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr ra; /* receiver address */
+ struct ether_addr ta; /* transmitter address */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_CTL_HDR_LEN 16 /* control frame hdr len */
+
+/* BAR frame payload */
+BWL_PRE_PACKED_STRUCT struct dot11_bar {
+ uint16 bar_control; /* BAR Control */
+ uint16 seqnum; /* Starting Sequence control */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_BAR_LEN 4 /* BAR frame payload length */
+
+#define DOT11_BA_BITMAP_LEN 128 /* bitmap length */
+#define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */
+/* BA frame payload */
+BWL_PRE_PACKED_STRUCT struct dot11_ba {
+ uint16 ba_control; /* BA Control */
+ uint16 seqnum; /* Starting Sequence control */
+ uint8 bitmap[DOT11_BA_BITMAP_LEN]; /* Block Ack Bitmap */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_BA_LEN 4 /* BA frame payload len (wo bitmap) */
+
+/* Management frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_management_header {
+ uint16 fc; /* frame control */
+ uint16 durid; /* duration/ID */
+ struct ether_addr da; /* receiver address */
+ struct ether_addr sa; /* transmitter address */
+ struct ether_addr bssid; /* BSS ID */
+ uint16 seq; /* sequence control */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_MGMT_HDR_LEN 24 /* d11 management header length */
+
+/* Management frame payloads */
+
+BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb {
+ uint32 timestamp[2];
+ uint16 beacon_interval;
+ uint16 capability;
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_BCN_PRB_LEN 12 /* 802.11 beacon/probe frame fixed length */
+#define DOT11_BCN_PRB_FIXED_LEN 12 /* 802.11 beacon/probe frame fixed length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_auth {
+ uint16 alg; /* algorithm */
+ uint16 seq; /* sequence control */
+ uint16 status; /* status code */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge IE */
+
+BWL_PRE_PACKED_STRUCT struct dot11_assoc_req {
+ uint16 capability; /* capability information */
+ uint16 listen; /* listen interval */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */
+
+BWL_PRE_PACKED_STRUCT struct dot11_reassoc_req {
+ uint16 capability; /* capability information */
+ uint16 listen; /* listen interval */
+ struct ether_addr ap; /* Current AP address */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */
+
+BWL_PRE_PACKED_STRUCT struct dot11_assoc_resp {
+ uint16 capability; /* capability information */
+ uint16 status; /* status code */
+ uint16 aid; /* association ID */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ASSOC_RESP_FIXED_LEN 6 /* length of assoc resp frame without info elts */
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_measure {
+ uint8 category;
+ uint8 action;
+ uint8 token;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ACTION_MEASURE_LEN 3 /* d11 action measurement header length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_ht_ch_width {
+ uint8 category;
+ uint8 action;
+ uint8 ch_width;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_ht_mimops {
+ uint8 category;
+ uint8 action;
+ uint8 control;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_sa_query {
+ uint8 category;
+ uint8 action;
+ uint16 id;
+} BWL_POST_PACKED_STRUCT;
+
+#define SM_PWRSAVE_ENABLE 1
+#define SM_PWRSAVE_MODE 2
+
+/* ************* 802.11h related definitions. ************* */
+BWL_PRE_PACKED_STRUCT struct dot11_power_cnst {
+ uint8 id;
+ uint8 len;
+ uint8 power;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_power_cnst dot11_power_cnst_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_power_cap {
+ uint8 min;
+ uint8 max;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_power_cap dot11_power_cap_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_tpc_rep {
+ uint8 id;
+ uint8 len;
+ uint8 tx_pwr;
+ uint8 margin;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_tpc_rep dot11_tpc_rep_t;
+#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */
+
+BWL_PRE_PACKED_STRUCT struct dot11_supp_channels {
+ uint8 id;
+ uint8 len;
+ uint8 first_channel;
+ uint8 num_channels;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_supp_channels dot11_supp_channels_t;
+
+/* Extension Channel Offset IE: 802.11n-D1.0 spec. added sideband
+ * offset for 40MHz operation. The possible 3 values are:
+ * 1 = above control channel
+ * 3 = below control channel
+ * 0 = no extension channel
+ */
+BWL_PRE_PACKED_STRUCT struct dot11_extch {
+ uint8 id; /* IE ID, 62, DOT11_MNG_EXT_CHANNEL_OFFSET */
+ uint8 len; /* IE length */
+ uint8 extch;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_extch dot11_extch_ie_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_brcm_extch {
+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */
+ uint8 len; /* IE length */
+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */
+ uint8 type; /* type inidicates what follows */
+ uint8 extch;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_brcm_extch dot11_brcm_extch_ie_t;
+
+#define BRCM_EXTCH_IE_LEN 5
+#define BRCM_EXTCH_IE_TYPE 53 /* 802.11n ID not yet assigned */
+#define DOT11_EXTCH_IE_LEN 1
+#define DOT11_EXT_CH_MASK 0x03 /* extension channel mask */
+#define DOT11_EXT_CH_UPPER 0x01 /* ext. ch. on upper sb */
+#define DOT11_EXT_CH_LOWER 0x03 /* ext. ch. on lower sb */
+#define DOT11_EXT_CH_NONE 0x00 /* no extension ch. */
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr {
+ uint8 category;
+ uint8 action;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_ACTION_FRMHDR_LEN 2
+
+/* CSA IE data structure */
+BWL_PRE_PACKED_STRUCT struct dot11_channel_switch {
+ uint8 id; /* id DOT11_MNG_CHANNEL_SWITCH_ID */
+ uint8 len; /* length of IE */
+ uint8 mode; /* mode 0 or 1 */
+ uint8 channel; /* channel switch to */
+ uint8 count; /* number of beacons before switching */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_channel_switch dot11_chan_switch_ie_t;
+
+#define DOT11_SWITCH_IE_LEN 3 /* length of IE data, not including 2 byte header */
+/* CSA mode - 802.11h-2003 $7.3.2.20 */
+#define DOT11_CSA_MODE_ADVISORY 0 /* no DOT11_CSA_MODE_NO_TX restriction imposed */
+#define DOT11_CSA_MODE_NO_TX 1 /* no transmission upon receiving CSA frame. */
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_switch_channel {
+ uint8 category;
+ uint8 action;
+ dot11_chan_switch_ie_t chan_switch_ie; /* for switch IE */
+ dot11_brcm_extch_ie_t extch_ie; /* extension channel offset */
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_csa_body {
+ uint8 mode; /* mode 0 or 1 */
+ uint8 reg; /* regulatory class */
+ uint8 channel; /* channel switch to */
+ uint8 count; /* number of beacons before switching */
+} BWL_POST_PACKED_STRUCT;
+
+/* 11n Extended Channel Switch IE data structure */
+BWL_PRE_PACKED_STRUCT struct dot11_ext_csa {
+ uint8 id; /* id DOT11_MNG_EXT_CHANNEL_SWITCH_ID */
+ uint8 len; /* length of IE */
+ struct dot11_csa_body b; /* body of the ie */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ext_csa dot11_ext_csa_ie_t;
+#define DOT11_EXT_CSA_IE_LEN 4 /* length of extended channel switch IE body */
+
+BWL_PRE_PACKED_STRUCT struct dot11_action_ext_csa {
+ uint8 category;
+ uint8 action;
+ dot11_ext_csa_ie_t chan_switch_ie; /* for switch IE */
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11y_action_ext_csa {
+ uint8 category;
+ uint8 action;
+ struct dot11_csa_body b; /* body of the ie */
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct dot11_obss_coex {
+ uint8 id;
+ uint8 len;
+ uint8 info;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_obss_coex dot11_obss_coex_t;
+#define DOT11_OBSS_COEXINFO_LEN 1 /* length of OBSS Coexistence INFO IE */
+
+#define DOT11_OBSS_COEX_INFO_REQ 0x01
+#define DOT11_OBSS_COEX_40MHZ_INTOLERANT 0x02
+#define DOT11_OBSS_COEX_20MHZ_WIDTH_REQ 0x04
+
+BWL_PRE_PACKED_STRUCT struct dot11_obss_chanlist {
+ uint8 id;
+ uint8 len;
+ uint8 regclass;
+ uint8 chanlist[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_obss_chanlist dot11_obss_chanlist_t;
+#define DOT11_OBSS_CHANLIST_FIXED_LEN 1 /* fixed length of regclass */
+
+BWL_PRE_PACKED_STRUCT struct dot11_extcap_ie {
+ uint8 id;
+ uint8 len;
+ uint8 cap[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_extcap_ie dot11_extcap_ie_t;
+
+#define DOT11_EXTCAP_LEN_MAX 7
+#define DOT11_EXTCAP_LEN_COEX 1
+#define DOT11_EXTCAP_LEN_BT 3
+#define DOT11_EXTCAP_LEN_IW 4
+#define DOT11_EXTCAP_LEN_SI 6
+
+#define DOT11_EXTCAP_LEN_TDLS 5
+BWL_PRE_PACKED_STRUCT struct dot11_extcap {
+ uint8 extcap[DOT11_EXTCAP_LEN_TDLS];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_extcap dot11_extcap_t;
+
+/* TDLS Capabilities */
+#define TDLS_CAP_TDLS 37 /* TDLS support */
+#define TDLS_CAP_PU_BUFFER_STA 28 /* TDLS Peer U-APSD buffer STA support */
+#define TDLS_CAP_PEER_PSM 20 /* TDLS Peer PSM support */
+#define TDLS_CAP_CH_SW 30 /* TDLS Channel switch */
+#define TDLS_CAP_PROH 38 /* TDLS prohibited */
+#define TDLS_CAP_CH_SW_PROH 39 /* TDLS Channel switch prohibited */
+
+#define TDLS_CAP_MAX_BIT 39 /* TDLS max bit defined in ext cap */
+
+/* 802.11h/802.11k Measurement Request/Report IEs */
+/* Measurement Type field */
+#define DOT11_MEASURE_TYPE_BASIC 0 /* d11 measurement basic type */
+#define DOT11_MEASURE_TYPE_CCA 1 /* d11 measurement CCA type */
+#define DOT11_MEASURE_TYPE_RPI 2 /* d11 measurement RPI type */
+#define DOT11_MEASURE_TYPE_CHLOAD 3 /* d11 measurement Channel Load type */
+#define DOT11_MEASURE_TYPE_NOISE 4 /* d11 measurement Noise Histogram type */
+#define DOT11_MEASURE_TYPE_BEACON 5 /* d11 measurement Beacon type */
+#define DOT11_MEASURE_TYPE_FRAME 6 /* d11 measurement Frame type */
+#define DOT11_MEASURE_TYPE_STATS 7 /* d11 measurement STA Statistics type */
+#define DOT11_MEASURE_TYPE_LCI 8 /* d11 measurement LCI type */
+#define DOT11_MEASURE_TYPE_TXSTREAM 9 /* d11 measurement TX Stream type */
+#define DOT11_MEASURE_TYPE_PAUSE 255 /* d11 measurement pause type */
+
+/* Measurement Request Modes */
+#define DOT11_MEASURE_MODE_PARALLEL (1<<0) /* d11 measurement parallel */
+#define DOT11_MEASURE_MODE_ENABLE (1<<1) /* d11 measurement enable */
+#define DOT11_MEASURE_MODE_REQUEST (1<<2) /* d11 measurement request */
+#define DOT11_MEASURE_MODE_REPORT (1<<3) /* d11 measurement report */
+#define DOT11_MEASURE_MODE_DUR (1<<4) /* d11 measurement dur mandatory */
+/* Measurement Report Modes */
+#define DOT11_MEASURE_MODE_LATE (1<<0) /* d11 measurement late */
+#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) /* d11 measurement incapable */
+#define DOT11_MEASURE_MODE_REFUSED (1<<2) /* d11 measurement refuse */
+/* Basic Measurement Map bits */
+#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) /* d11 measurement basic map BSS */
+#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) /* d11 measurement map OFDM */
+#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) /* d11 measurement map unknown */
+#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) /* d11 measurement map radar */
+#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) /* d11 measurement map unmeasuremnt */
+
+BWL_PRE_PACKED_STRUCT struct dot11_meas_req {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_meas_req dot11_meas_req_t;
+#define DOT11_MNG_IE_MREQ_LEN 14 /* d11 measurement request IE length */
+/* length of Measure Request IE data not including variable len */
+#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 /* d11 measurement request IE fixed length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_meas_rep {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ BWL_PRE_PACKED_STRUCT union
+ {
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+ uint8 map;
+ } BWL_POST_PACKED_STRUCT basic;
+ uint8 data[1];
+ } BWL_POST_PACKED_STRUCT rep;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_meas_rep dot11_meas_rep_t;
+
+/* length of Measure Report IE data not including variable len */
+#define DOT11_MNG_IE_MREP_FIXED_LEN 3 /* d11 measurement response IE fixed length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_meas_rep_basic {
+ uint8 channel;
+ uint8 start_time[8];
+ uint16 duration;
+ uint8 map;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t;
+#define DOT11_MEASURE_BASIC_REP_LEN 12 /* d11 measurement basic report length */
+
+BWL_PRE_PACKED_STRUCT struct dot11_quiet {
+ uint8 id;
+ uint8 len;
+ uint8 count; /* TBTTs until beacon interval in quiet starts */
+ uint8 period; /* Beacon intervals between periodic quiet periods ? */
+ uint16 duration; /* Length of quiet period, in TU's */
+ uint16 offset; /* TU's offset from TBTT in Count field */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_quiet dot11_quiet_t;
+
+BWL_PRE_PACKED_STRUCT struct chan_map_tuple {
+ uint8 channel;
+ uint8 map;
+} BWL_POST_PACKED_STRUCT;
+typedef struct chan_map_tuple chan_map_tuple_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_ibss_dfs {
+ uint8 id;
+ uint8 len;
+ uint8 eaddr[ETHER_ADDR_LEN];
+ uint8 interval;
+ chan_map_tuple_t map[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ibss_dfs dot11_ibss_dfs_t;
+
+/* WME Elements */
+#define WME_OUI "\x00\x50\xf2" /* WME OUI */
+#define WME_OUI_LEN 3
+#define WME_OUI_TYPE 2 /* WME type */
+#define WME_TYPE 2 /* WME type, deprecated */
+#define WME_SUBTYPE_IE 0 /* Information Element */
+#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */
+#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */
+#define WME_VER 1 /* WME version */
+
+/* WME Access Category Indices (ACIs) */
+#define AC_BE 0 /* Best Effort */
+#define AC_BK 1 /* Background */
+#define AC_VI 2 /* Video */
+#define AC_VO 3 /* Voice */
+#define AC_COUNT 4 /* number of ACs */
+
+typedef uint8 ac_bitmap_t; /* AC bitmap of (1 << AC_xx) */
+
+#define AC_BITMAP_NONE 0x0 /* No ACs */
+#define AC_BITMAP_ALL 0xf /* All ACs */
+#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0)
+#define AC_BITMAP_SET(ab, ac) (((ab) |= (1 << (ac))))
+#define AC_BITMAP_RESET(ab, ac) (((ab) &= ~(1 << (ac))))
+
+/* WME Information Element (IE) */
+BWL_PRE_PACKED_STRUCT struct wme_ie {
+ uint8 oui[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ uint8 qosinfo;
+} BWL_POST_PACKED_STRUCT;
+typedef struct wme_ie wme_ie_t;
+#define WME_IE_LEN 7 /* WME IE length */
+
+BWL_PRE_PACKED_STRUCT struct edcf_acparam {
+ uint8 ACI;
+ uint8 ECW;
+ uint16 TXOP; /* stored in network order (ls octet first) */
+} BWL_POST_PACKED_STRUCT;
+typedef struct edcf_acparam edcf_acparam_t;
+
+/* WME Parameter Element (PE) */
+BWL_PRE_PACKED_STRUCT struct wme_param_ie {
+ uint8 oui[3];
+ uint8 type;
+ uint8 subtype;
+ uint8 version;
+ uint8 qosinfo;
+ uint8 rsvd;
+ edcf_acparam_t acparam[AC_COUNT];
+} BWL_POST_PACKED_STRUCT;
+typedef struct wme_param_ie wme_param_ie_t;
+#define WME_PARAM_IE_LEN 24 /* WME Parameter IE length */
+
+/* QoS Info field for IE as sent from AP */
+#define WME_QI_AP_APSD_MASK 0x80 /* U-APSD Supported mask */
+#define WME_QI_AP_APSD_SHIFT 7 /* U-APSD Supported shift */
+#define WME_QI_AP_COUNT_MASK 0x0f /* Parameter set count mask */
+#define WME_QI_AP_COUNT_SHIFT 0 /* Parameter set count shift */
+
+/* QoS Info field for IE as sent from STA */
+#define WME_QI_STA_MAXSPLEN_MASK 0x60 /* Max Service Period Length mask */
+#define WME_QI_STA_MAXSPLEN_SHIFT 5 /* Max Service Period Length shift */
+#define WME_QI_STA_APSD_ALL_MASK 0xf /* APSD all AC bits mask */
+#define WME_QI_STA_APSD_ALL_SHIFT 0 /* APSD all AC bits shift */
+#define WME_QI_STA_APSD_BE_MASK 0x8 /* APSD AC_BE mask */
+#define WME_QI_STA_APSD_BE_SHIFT 3 /* APSD AC_BE shift */
+#define WME_QI_STA_APSD_BK_MASK 0x4 /* APSD AC_BK mask */
+#define WME_QI_STA_APSD_BK_SHIFT 2 /* APSD AC_BK shift */
+#define WME_QI_STA_APSD_VI_MASK 0x2 /* APSD AC_VI mask */
+#define WME_QI_STA_APSD_VI_SHIFT 1 /* APSD AC_VI shift */
+#define WME_QI_STA_APSD_VO_MASK 0x1 /* APSD AC_VO mask */
+#define WME_QI_STA_APSD_VO_SHIFT 0 /* APSD AC_VO shift */
+
+/* ACI */
+#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */
+#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */
+#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */
+#define EDCF_ACM_MASK 0x10 /* ACM mask */
+#define EDCF_ACI_MASK 0x60 /* ACI mask */
+#define EDCF_ACI_SHIFT 5 /* ACI shift */
+#define EDCF_AIFSN_SHIFT 12 /* 4 MSB(0xFFF) in ifs_ctl for AC idx */
+
+/* ECW */
+#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */
+#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */
+#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1)
+#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */
+#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */
+#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */
+
+/* TXOP */
+#define EDCF_TXOP_MIN 0 /* TXOP minimum value */
+#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */
+#define EDCF_TXOP2USEC(txop) ((txop) << 5)
+
+/* Default BE ACI value for non-WME connection STA */
+#define NON_EDCF_AC_BE_ACI_STA 0x02
+
+/* Default EDCF parameters that AP advertises for STA to use; WMM draft Table 12 */
+#define EDCF_AC_BE_ACI_STA 0x03 /* STA ACI value for best effort AC */
+#define EDCF_AC_BE_ECW_STA 0xA4 /* STA ECW value for best effort AC */
+#define EDCF_AC_BE_TXOP_STA 0x0000 /* STA TXOP value for best effort AC */
+#define EDCF_AC_BK_ACI_STA 0x27 /* STA ACI value for background AC */
+#define EDCF_AC_BK_ECW_STA 0xA4 /* STA ECW value for background AC */
+#define EDCF_AC_BK_TXOP_STA 0x0000 /* STA TXOP value for background AC */
+#define EDCF_AC_VI_ACI_STA 0x42 /* STA ACI value for video AC */
+#define EDCF_AC_VI_ECW_STA 0x43 /* STA ECW value for video AC */
+#define EDCF_AC_VI_TXOP_STA 0x005e /* STA TXOP value for video AC */
+#define EDCF_AC_VO_ACI_STA 0x62 /* STA ACI value for audio AC */
+#define EDCF_AC_VO_ECW_STA 0x32 /* STA ECW value for audio AC */
+#define EDCF_AC_VO_TXOP_STA 0x002f /* STA TXOP value for audio AC */
+
+/* Default EDCF parameters that AP uses; WMM draft Table 14 */
+#define EDCF_AC_BE_ACI_AP 0x03 /* AP ACI value for best effort AC */
+#define EDCF_AC_BE_ECW_AP 0x64 /* AP ECW value for best effort AC */
+#define EDCF_AC_BE_TXOP_AP 0x0000 /* AP TXOP value for best effort AC */
+#define EDCF_AC_BK_ACI_AP 0x27 /* AP ACI value for background AC */
+#define EDCF_AC_BK_ECW_AP 0xA4 /* AP ECW value for background AC */
+#define EDCF_AC_BK_TXOP_AP 0x0000 /* AP TXOP value for background AC */
+#define EDCF_AC_VI_ACI_AP 0x41 /* AP ACI value for video AC */
+#define EDCF_AC_VI_ECW_AP 0x43 /* AP ECW value for video AC */
+#define EDCF_AC_VI_TXOP_AP 0x005e /* AP TXOP value for video AC */
+#define EDCF_AC_VO_ACI_AP 0x61 /* AP ACI value for audio AC */
+#define EDCF_AC_VO_ECW_AP 0x32 /* AP ECW value for audio AC */
+#define EDCF_AC_VO_TXOP_AP 0x002f /* AP TXOP value for audio AC */
+
+/* EDCA Parameter IE */
+BWL_PRE_PACKED_STRUCT struct edca_param_ie {
+ uint8 qosinfo;
+ uint8 rsvd;
+ edcf_acparam_t acparam[AC_COUNT];
+} BWL_POST_PACKED_STRUCT;
+typedef struct edca_param_ie edca_param_ie_t;
+#define EDCA_PARAM_IE_LEN 18 /* EDCA Parameter IE length */
+
+/* QoS Capability IE */
+BWL_PRE_PACKED_STRUCT struct qos_cap_ie {
+ uint8 qosinfo;
+} BWL_POST_PACKED_STRUCT;
+typedef struct qos_cap_ie qos_cap_ie_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_qbss_load_ie {
+ uint8 id; /* 11, DOT11_MNG_QBSS_LOAD_ID */
+ uint8 length;
+ uint16 station_count; /* total number of STAs associated */
+ uint8 channel_utilization; /* % of time, normalized to 255, QAP sensed medium busy */
+ uint16 aac; /* available admission capacity */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t;
+#define BSS_LOAD_IE_SIZE 7 /* BSS load IE size */
+
+/* nom_msdu_size */
+#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */
+#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */
+
+/* surplus_bandwidth */
+/* Represented as 3 bits of integer, binary point, 13 bits fraction */
+#define INTEGER_SHIFT 13 /* integer shift */
+#define FRACTION_MASK 0x1FFF /* fraction mask */
+
+/* Management Notification Frame */
+BWL_PRE_PACKED_STRUCT struct dot11_management_notification {
+ uint8 category; /* DOT11_ACTION_NOTIFICATION */
+ uint8 action;
+ uint8 token;
+ uint8 status;
+ uint8 data[1]; /* Elements */
+} BWL_POST_PACKED_STRUCT;
+#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */
+
+/* Timeout Interval IE */
+BWL_PRE_PACKED_STRUCT struct ti_ie {
+ uint8 ti_type;
+ uint32 ti_val;
+} BWL_POST_PACKED_STRUCT;
+typedef struct ti_ie ti_ie_t;
+#define TI_TYPE_REASSOC_DEADLINE 1
+#define TI_TYPE_KEY_LIFETIME 2
+
+/* WME Action Codes */
+#define WME_ADDTS_REQUEST 0 /* WME ADDTS request */
+#define WME_ADDTS_RESPONSE 1 /* WME ADDTS response */
+#define WME_DELTS_REQUEST 2 /* WME DELTS request */
+
+/* WME Setup Response Status Codes */
+#define WME_ADMISSION_ACCEPTED 0 /* WME admission accepted */
+#define WME_INVALID_PARAMETERS 1 /* WME invalide parameters */
+#define WME_ADMISSION_REFUSED 3 /* WME admission refused */
+
+/* Macro to take a pointer to a beacon or probe response
+ * body and return the char* pointer to the SSID info element
+ */
+#define BCN_PRB_SSID(body) ((char*)(body) + DOT11_BCN_PRB_LEN)
+
+/* Authentication frame payload constants */
+#define DOT11_OPEN_SYSTEM 0 /* d11 open authentication */
+#define DOT11_SHARED_KEY 1 /* d11 shared authentication */
+#define DOT11_FAST_BSS 2 /* d11 fast bss authentication */
+#define DOT11_CHALLENGE_LEN 128 /* d11 challenge text length */
+
+/* Frame control macros */
+#define FC_PVER_MASK 0x3 /* PVER mask */
+#define FC_PVER_SHIFT 0 /* PVER shift */
+#define FC_TYPE_MASK 0xC /* type mask */
+#define FC_TYPE_SHIFT 2 /* type shift */
+#define FC_SUBTYPE_MASK 0xF0 /* subtype mask */
+#define FC_SUBTYPE_SHIFT 4 /* subtype shift */
+#define FC_TODS 0x100 /* to DS */
+#define FC_TODS_SHIFT 8 /* to DS shift */
+#define FC_FROMDS 0x200 /* from DS */
+#define FC_FROMDS_SHIFT 9 /* from DS shift */
+#define FC_MOREFRAG 0x400 /* more frag. */
+#define FC_MOREFRAG_SHIFT 10 /* more frag. shift */
+#define FC_RETRY 0x800 /* retry */
+#define FC_RETRY_SHIFT 11 /* retry shift */
+#define FC_PM 0x1000 /* PM */
+#define FC_PM_SHIFT 12 /* PM shift */
+#define FC_MOREDATA 0x2000 /* more data */
+#define FC_MOREDATA_SHIFT 13 /* more data shift */
+#define FC_WEP 0x4000 /* WEP */
+#define FC_WEP_SHIFT 14 /* WEP shift */
+#define FC_ORDER 0x8000 /* order */
+#define FC_ORDER_SHIFT 15 /* order shift */
+
+/* sequence control macros */
+#define SEQNUM_SHIFT 4 /* seq. number shift */
+#define SEQNUM_MAX 0x1000 /* max seqnum + 1 */
+#define FRAGNUM_MASK 0xF /* frag. number mask */
+
+/* Frame Control type/subtype defs */
+
+/* FC Types */
+#define FC_TYPE_MNG 0 /* management type */
+#define FC_TYPE_CTL 1 /* control type */
+#define FC_TYPE_DATA 2 /* data type */
+
+/* Management Subtypes */
+#define FC_SUBTYPE_ASSOC_REQ 0 /* assoc. request */
+#define FC_SUBTYPE_ASSOC_RESP 1 /* assoc. response */
+#define FC_SUBTYPE_REASSOC_REQ 2 /* reassoc. request */
+#define FC_SUBTYPE_REASSOC_RESP 3 /* reassoc. response */
+#define FC_SUBTYPE_PROBE_REQ 4 /* probe request */
+#define FC_SUBTYPE_PROBE_RESP 5 /* probe response */
+#define FC_SUBTYPE_BEACON 8 /* beacon */
+#define FC_SUBTYPE_ATIM 9 /* ATIM */
+#define FC_SUBTYPE_DISASSOC 10 /* disassoc. */
+#define FC_SUBTYPE_AUTH 11 /* authentication */
+#define FC_SUBTYPE_DEAUTH 12 /* de-authentication */
+#define FC_SUBTYPE_ACTION 13 /* action */
+#define FC_SUBTYPE_ACTION_NOACK 14 /* action no-ack */
+
+/* Control Subtypes */
+#define FC_SUBTYPE_CTL_WRAPPER 7 /* Control Wrapper */
+#define FC_SUBTYPE_BLOCKACK_REQ 8 /* Block Ack Req */
+#define FC_SUBTYPE_BLOCKACK 9 /* Block Ack */
+#define FC_SUBTYPE_PS_POLL 10 /* PS poll */
+#define FC_SUBTYPE_RTS 11 /* RTS */
+#define FC_SUBTYPE_CTS 12 /* CTS */
+#define FC_SUBTYPE_ACK 13 /* ACK */
+#define FC_SUBTYPE_CF_END 14 /* CF-END */
+#define FC_SUBTYPE_CF_END_ACK 15 /* CF-END ACK */
+
+/* Data Subtypes */
+#define FC_SUBTYPE_DATA 0 /* Data */
+#define FC_SUBTYPE_DATA_CF_ACK 1 /* Data + CF-ACK */
+#define FC_SUBTYPE_DATA_CF_POLL 2 /* Data + CF-Poll */
+#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 /* Data + CF-Ack + CF-Poll */
+#define FC_SUBTYPE_NULL 4 /* Null */
+#define FC_SUBTYPE_CF_ACK 5 /* CF-Ack */
+#define FC_SUBTYPE_CF_POLL 6 /* CF-Poll */
+#define FC_SUBTYPE_CF_ACK_POLL 7 /* CF-Ack + CF-Poll */
+#define FC_SUBTYPE_QOS_DATA 8 /* QoS Data */
+#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 /* QoS Data + CF-Ack */
+#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 /* QoS Data + CF-Poll */
+#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 /* QoS Data + CF-Ack + CF-Poll */
+#define FC_SUBTYPE_QOS_NULL 12 /* QoS Null */
+#define FC_SUBTYPE_QOS_CF_POLL 14 /* QoS CF-Poll */
+#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 /* QoS CF-Ack + CF-Poll */
+
+/* Data Subtype Groups */
+#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0)
+#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0)
+#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0)
+#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0)
+
+/* Type/Subtype Combos */
+#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) /* FC kind mask */
+
+#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) /* FC kind */
+
+#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) /* Subtype from FC */
+#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) /* Type from FC */
+
+#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) /* assoc. request */
+#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) /* assoc. response */
+#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) /* reassoc. request */
+#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) /* reassoc. response */
+#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) /* probe request */
+#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) /* probe response */
+#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) /* beacon */
+#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) /* disassoc */
+#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) /* authentication */
+#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) /* deauthentication */
+#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) /* action */
+#define FC_ACTION_NOACK FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION_NOACK) /* action no-ack */
+
+#define FC_CTL_WRAPPER FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTL_WRAPPER) /* Control Wrapper */
+#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) /* Block Ack Req */
+#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) /* Block Ack */
+#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) /* PS poll */
+#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) /* RTS */
+#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) /* CTS */
+#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) /* ACK */
+#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) /* CF-END */
+#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) /* CF-END ACK */
+
+#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) /* data */
+#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) /* null data */
+#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) /* data CF ACK */
+#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) /* QoS data */
+#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) /* QoS null */
+
+/* QoS Control Field */
+
+/* 802.1D Priority */
+#define QOS_PRIO_SHIFT 0 /* QoS priority shift */
+#define QOS_PRIO_MASK 0x0007 /* QoS priority mask */
+#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) /* QoS priority */
+
+/* Traffic Identifier */
+#define QOS_TID_SHIFT 0 /* QoS TID shift */
+#define QOS_TID_MASK 0x000f /* QoS TID mask */
+#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) /* QoS TID */
+
+/* End of Service Period (U-APSD) */
+#define QOS_EOSP_SHIFT 4 /* QoS End of Service Period shift */
+#define QOS_EOSP_MASK 0x0010 /* QoS End of Service Period mask */
+#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) /* Qos EOSP */
+
+/* Ack Policy */
+#define QOS_ACK_NORMAL_ACK 0 /* Normal Ack */
+#define QOS_ACK_NO_ACK 1 /* No Ack (eg mcast) */
+#define QOS_ACK_NO_EXP_ACK 2 /* No Explicit Ack */
+#define QOS_ACK_BLOCK_ACK 3 /* Block Ack */
+#define QOS_ACK_SHIFT 5 /* QoS ACK shift */
+#define QOS_ACK_MASK 0x0060 /* QoS ACK mask */
+#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) /* QoS ACK */
+
+/* A-MSDU flag */
+#define QOS_AMSDU_SHIFT 7 /* AMSDU shift */
+#define QOS_AMSDU_MASK 0x0080 /* AMSDU mask */
+
+/* Management Frames */
+
+/* Management Frame Constants */
+
+/* Fixed fields */
+#define DOT11_MNG_AUTH_ALGO_LEN 2 /* d11 management auth. algo. length */
+#define DOT11_MNG_AUTH_SEQ_LEN 2 /* d11 management auth. seq. length */
+#define DOT11_MNG_BEACON_INT_LEN 2 /* d11 management beacon interval length */
+#define DOT11_MNG_CAP_LEN 2 /* d11 management cap. length */
+#define DOT11_MNG_AP_ADDR_LEN 6 /* d11 management AP address length */
+#define DOT11_MNG_LISTEN_INT_LEN 2 /* d11 management listen interval length */
+#define DOT11_MNG_REASON_LEN 2 /* d11 management reason length */
+#define DOT11_MNG_AID_LEN 2 /* d11 management AID length */
+#define DOT11_MNG_STATUS_LEN 2 /* d11 management status length */
+#define DOT11_MNG_TIMESTAMP_LEN 8 /* d11 management timestamp length */
+
+/* DUR/ID field in assoc resp is 0xc000 | AID */
+#define DOT11_AID_MASK 0x3fff /* d11 AID mask */
+
+/* Reason Codes */
+#define DOT11_RC_RESERVED 0 /* d11 RC reserved */
+#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */
+#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */
+#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station
+ * is leaving (or has left) IBSS or ESS
+ */
+#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */
+#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle
+ * all currently associated stations
+ */
+#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from
+ * nonauthenticated station
+ */
+#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from
+ * nonassociated station
+ */
+#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is
+ * leaving (or has left) BSS
+ */
+#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is not
+ * authenticated with responding station
+ */
+#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */
+#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */
+/* 12 is unused */
+
+/* 32-39 are QSTA specific reasons added in 11e */
+#define DOT11_RC_UNSPECIFIED_QOS 32 /* unspecified QoS-related reason */
+#define DOT11_RC_INSUFFCIENT_BW 33 /* QAP lacks sufficient bandwidth */
+#define DOT11_RC_EXCESSIVE_FRAMES 34 /* excessive number of frames need ack */
+#define DOT11_RC_TX_OUTSIDE_TXOP 35 /* transmitting outside the limits of txop */
+#define DOT11_RC_LEAVING_QBSS 36 /* QSTA is leaving the QBSS (or restting) */
+#define DOT11_RC_BAD_MECHANISM 37 /* does not want to use the mechanism */
+#define DOT11_RC_SETUP_NEEDED 38 /* mechanism needs a setup */
+#define DOT11_RC_TIMEOUT 39 /* timeout */
+
+#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */
+
+#define DOT11_RC_TDLS_PEER_UNREACH 25
+#define DOT11_RC_TDLS_DOWN_UNSPECIFIED 26
+
+/* Status Codes */
+#define DOT11_SC_SUCCESS 0 /* Successful */
+#define DOT11_SC_FAILURE 1 /* Unspecified failure */
+#define DOT11_SC_TDLS_WAKEUP_SCH_ALT 2 /* TDLS wakeup schedule rejected but alternative */
+ /* schedule provided */
+#define DOT11_SC_TDLS_WAKEUP_SCH_REJ 3 /* TDLS wakeup schedule rejected */
+#define DOT11_SC_TDLS_SEC_DISABLED 5 /* TDLS Security disabled */
+#define DOT11_SC_LIFETIME_REJ 6 /* Unacceptable lifetime */
+#define DOT11_SC_NOT_SAME_BSS 7 /* Not in same BSS */
+#define DOT11_SC_CAP_MISMATCH 10 /* Cannot support all requested
+ * capabilities in the Capability
+ * Information field
+ */
+#define DOT11_SC_REASSOC_FAIL 11 /* Reassociation denied due to inability
+ * to confirm that association exists
+ */
+#define DOT11_SC_ASSOC_FAIL 12 /* Association denied due to reason
+ * outside the scope of this standard
+ */
+#define DOT11_SC_AUTH_MISMATCH 13 /* Responding station does not support
+ * the specified authentication
+ * algorithm
+ */
+#define DOT11_SC_AUTH_SEQ 14 /* Received an Authentication frame
+ * with authentication transaction
+ * sequence number out of expected
+ * sequence
+ */
+#define DOT11_SC_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of
+ * challenge failure
+ */
+#define DOT11_SC_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout
+ * waiting for next frame in sequence
+ */
+#define DOT11_SC_ASSOC_BUSY_FAIL 17 /* Association denied because AP is
+ * unable to handle additional
+ * associated stations
+ */
+#define DOT11_SC_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting
+ * station not supporting all of the
+ * data rates in the BSSBasicRateSet
+ * parameter
+ */
+#define DOT11_SC_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting
+ * station not supporting the Short
+ * Preamble option
+ */
+#define DOT11_SC_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting
+ * station not supporting the PBCC
+ * Modulation option
+ */
+#define DOT11_SC_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting
+ * station not supporting the Channel
+ * Agility option
+ */
+#define DOT11_SC_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum
+ * Management capability is required.
+ */
+#define DOT11_SC_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info
+ * in the Power Cap element is
+ * unacceptable.
+ */
+#define DOT11_SC_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info
+ * in the Supported Channel element is
+ * unacceptable
+ */
+#define DOT11_SC_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting
+ * station not supporting the Short Slot
+ * Time option
+ */
+#define DOT11_SC_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting
+ * station not supporting the ER-PBCC
+ * Modulation option
+ */
+#define DOT11_SC_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting
+ * station not supporting the DSS-OFDM
+ * option
+ */
+#define DOT11_SC_ASSOC_R0KH_UNREACHABLE 28 /* Association denied due to AP
+ * being unable to reach the R0 Key Holder
+ */
+#define DOT11_SC_ASSOC_TRY_LATER 30 /* Association denied temporarily, try again later
+ */
+#define DOT11_SC_ASSOC_MFP_VIOLATION 31 /* Association denied due to Robust Management
+ * frame policy violation
+ */
+
+#define DOT11_SC_DECLINED 37 /* request declined */
+#define DOT11_SC_INVALID_PARAMS 38 /* One or more params have invalid values */
+#define DOT11_SC_INVALID_PAIRWISE_CIPHER 42 /* invalid pairwise cipher */
+#define DOT11_SC_INVALID_AKMP 43 /* Association denied due to invalid AKMP */
+#define DOT11_SC_INVALID_RSNIE_CAP 45 /* invalid RSN IE capabilities */
+#define DOT11_SC_DLS_NOT_ALLOWED 48 /* DLS is not allowed in the BSS by policy */
+#define DOT11_SC_INVALID_PMKID 53 /* Association denied due to invalid PMKID */
+#define DOT11_SC_INVALID_MDID 54 /* Association denied due to invalid MDID */
+#define DOT11_SC_INVALID_FTIE 55 /* Association denied due to invalid FTIE */
+
+#define DOT11_SC_UNEXP_MSG 70 /* Unexpected message */
+#define DOT11_SC_INVALID_SNONCE 71 /* Invalid SNonce */
+#define DOT11_SC_INVALID_RSNIE 72 /* Invalid contents of RSNIE */
+
+/* Info Elts, length of INFORMATION portion of Info Elts */
+#define DOT11_MNG_DS_PARAM_LEN 1 /* d11 management DS parameter length */
+#define DOT11_MNG_IBSS_PARAM_LEN 2 /* d11 management IBSS parameter length */
+
+/* TIM Info element has 3 bytes fixed info in INFORMATION field,
+ * followed by 1 to 251 bytes of Partial Virtual Bitmap
+ */
+#define DOT11_MNG_TIM_FIXED_LEN 3 /* d11 management TIM fixed length */
+#define DOT11_MNG_TIM_DTIM_COUNT 0 /* d11 management DTIM count */
+#define DOT11_MNG_TIM_DTIM_PERIOD 1 /* d11 management DTIM period */
+#define DOT11_MNG_TIM_BITMAP_CTL 2 /* d11 management TIM BITMAP control */
+#define DOT11_MNG_TIM_PVB 3 /* d11 management TIM PVB */
+
+/* TLV defines */
+#define TLV_TAG_OFF 0 /* tag offset */
+#define TLV_LEN_OFF 1 /* length offset */
+#define TLV_HDR_LEN 2 /* header length */
+#define TLV_BODY_OFF 2 /* body offset */
+
+/* Management Frame Information Element IDs */
+#define DOT11_MNG_SSID_ID 0 /* d11 management SSID id */
+#define DOT11_MNG_RATES_ID 1 /* d11 management rates id */
+#define DOT11_MNG_FH_PARMS_ID 2 /* d11 management FH parameter id */
+#define DOT11_MNG_DS_PARMS_ID 3 /* d11 management DS parameter id */
+#define DOT11_MNG_CF_PARMS_ID 4 /* d11 management CF parameter id */
+#define DOT11_MNG_TIM_ID 5 /* d11 management TIM id */
+#define DOT11_MNG_IBSS_PARMS_ID 6 /* d11 management IBSS parameter id */
+#define DOT11_MNG_COUNTRY_ID 7 /* d11 management country id */
+#define DOT11_MNG_HOPPING_PARMS_ID 8 /* d11 management hopping parameter id */
+#define DOT11_MNG_HOPPING_TABLE_ID 9 /* d11 management hopping table id */
+#define DOT11_MNG_REQUEST_ID 10 /* d11 management request id */
+#define DOT11_MNG_QBSS_LOAD_ID 11 /* d11 management QBSS Load id */
+#define DOT11_MNG_EDCA_PARAM_ID 12 /* 11E EDCA Parameter id */
+#define DOT11_MNG_CHALLENGE_ID 16 /* d11 management chanllenge id */
+#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */
+#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */
+#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */
+#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */
+#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */
+#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement */
+#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */
+#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */
+#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */
+#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */
+#define DOT11_MNG_ERP_ID 42 /* d11 management ERP id */
+#define DOT11_MNG_TS_DELAY_ID 43 /* d11 management TS Delay id */
+#define DOT11_MNG_HT_CAP 45 /* d11 mgmt HT cap id */
+#define DOT11_MNG_QOS_CAP_ID 46 /* 11E QoS Capability id */
+#define DOT11_MNG_NONERP_ID 47 /* d11 management NON-ERP id */
+#define DOT11_MNG_RSN_ID 48 /* d11 management RSN id */
+#define DOT11_MNG_EXT_RATES_ID 50 /* d11 management ext. rates id */
+#define DOT11_MNG_AP_CHREP_ID 51 /* 11k AP Channel report id */
+#define DOT11_MNG_NBR_REP_ID 52 /* 11k Neighbor report id */
+#define DOT11_MNG_MDIE_ID 54 /* 11r Mobility domain id */
+#define DOT11_MNG_FTIE_ID 55 /* 11r Fast Bss Transition id */
+#define DOT11_MNG_FT_TI_ID 56 /* 11r Timeout Interval id */
+#define DOT11_MNG_REGCLASS_ID 59 /* d11 management regulatory class id */
+#define DOT11_MNG_EXT_CSA_ID 60 /* d11 Extended CSA */
+#define DOT11_MNG_HT_ADD 61 /* d11 mgmt additional HT info */
+#define DOT11_MNG_EXT_CHANNEL_OFFSET 62 /* d11 mgmt ext channel offset */
+#ifdef BCMWAPI_WAI
+#define DOT11_MNG_WAPI_ID 68 /* d11 management WAPI id */
+#endif
+#define DOT11_MNG_WAPI_ID 68 /* d11 management WAPI id */
+#define DOT11_MNG_TIME_ADVERTISE_ID 69 /* 11p time advertisement */
+#define DOT11_MNG_RRM_CAP_ID 70 /* 11k radio measurement capability */
+#define DOT11_MNG_HT_BSS_COEXINFO_ID 72 /* d11 mgmt OBSS Coexistence INFO */
+#define DOT11_MNG_HT_BSS_CHANNEL_REPORT_ID 73 /* d11 mgmt OBSS Intolerant Channel list */
+#define DOT11_MNG_HT_OBSS_ID 74 /* d11 mgmt OBSS HT info */
+#define DOT11_MNG_CHANNEL_USAGE 97 /* 11v channel usage */
+#define DOT11_MNG_TIME_ZONE_ID 98 /* 11v time zone */
+#define DOT11_MNG_LINK_IDENTIFIER_ID 101 /* 11z TDLS Link Identifier IE */
+#define DOT11_MNG_WAKEUP_SCHEDULE_ID 102 /* 11z TDLS Wakeup Schedule IE */
+#define DOT11_MNG_CHANNEL_SWITCH_TIMING_ID 104 /* 11z TDLS Channel Switch Timing IE */
+#define DOT11_MNG_PTI_CONTROL_ID 105 /* 11z TDLS PTI Control IE */
+#define DOT11_MNG_PU_BUFFER_STATUS_ID 106 /* 11z TDLS PU Buffer Status IE */
+#define DOT11_MNG_INTERWORKING_ID 107 /* 11u interworking */
+#define DOT11_MNG_ADVERTISEMENT_ID 108 /* 11u advertisement protocol */
+#define DOT11_MNG_EXP_BW_REQ_ID 109 /* 11u expedited bandwith request */
+#define DOT11_MNG_QOS_MAP_ID 110 /* 11u QoS map set */
+#define DOT11_MNG_ROAM_CONSORT_ID 111 /* 11u roaming consortium */
+#define DOT11_MNG_EMERGCY_ALERT_ID 112 /* 11u emergency alert identifier */
+#define DOT11_MNG_EXT_CAP_ID 127 /* d11 mgmt ext capability */
+#define DOT11_MNG_VHT_CAP_ID 191 /* d11 mgmt VHT cap id */
+#define DOT11_MNG_VHT_OPERATION_ID 192 /* d11 mgmt VHT op id */
+
+#define DOT11_MNG_WPA_ID 221 /* d11 management WPA id */
+#define DOT11_MNG_PROPR_ID 221 /* d11 management proprietary id */
+/* should start using this one instead of above two */
+#define DOT11_MNG_VS_ID 221 /* d11 management Vendor Specific IE */
+
+/* Rate element Basic flag and rate mask */
+#define DOT11_RATE_BASIC 0x80 /* flag for a Basic Rate */
+#define DOT11_RATE_MASK 0x7F /* mask for numeric part of rate */
+
+/* ERP info element bit values */
+#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */
+#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present
+ *in the BSS
+ */
+#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for
+ *ERP-OFDM frames
+ */
+#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed,
+ * 1 == not allowed
+ */
+/* TS Delay element offset & size */
+#define DOT11_MGN_TS_DELAY_LEN 4 /* length of TS DELAY IE */
+#define TS_DELAY_FIELD_SIZE 4 /* TS DELAY field size */
+
+/* Capability Information Field */
+#define DOT11_CAP_ESS 0x0001 /* d11 cap. ESS */
+#define DOT11_CAP_IBSS 0x0002 /* d11 cap. IBSS */
+#define DOT11_CAP_POLLABLE 0x0004 /* d11 cap. pollable */
+#define DOT11_CAP_POLL_RQ 0x0008 /* d11 cap. poll request */
+#define DOT11_CAP_PRIVACY 0x0010 /* d11 cap. privacy */
+#define DOT11_CAP_SHORT 0x0020 /* d11 cap. short */
+#define DOT11_CAP_PBCC 0x0040 /* d11 cap. PBCC */
+#define DOT11_CAP_AGILITY 0x0080 /* d11 cap. agility */
+#define DOT11_CAP_SPECTRUM 0x0100 /* d11 cap. spectrum */
+#define DOT11_CAP_SHORTSLOT 0x0400 /* d11 cap. shortslot */
+#define DOT11_CAP_RRM 0x1000 /* d11 cap. 11k radio measurement */
+#define DOT11_CAP_CCK_OFDM 0x2000 /* d11 cap. CCK/OFDM */
+
+/* Extended capabilities IE bitfields */
+/* 20/40 BSS Coexistence Management support bit position */
+#define DOT11_EXT_CAP_OBSS_COEX_MGMT 0
+/* scheduled PSMP support bit position */
+#define DOT11_EXT_CAP_SPSMP 6
+/* BSS Transition Management support bit position */
+#define DOT11_EXT_CAP_BSS_TRANSITION_MGMT 19
+/* Interworking support bit position */
+#define DOT11_EXT_CAP_IW 31
+/* service Interval granularity bit position and mask */
+#define DOT11_EXT_CAP_SI 41
+#define DOT11_EXT_CAP_SI_MASK 0x0E
+
+/*
+ * Action Frame Constants
+ */
+#define DOT11_ACTION_HDR_LEN 2 /* action frame category + action field */
+#define DOT11_ACTION_CAT_OFF 0 /* category offset */
+#define DOT11_ACTION_ACT_OFF 1 /* action offset */
+
+/* Action Category field (sec 7.3.1.11) */
+#define DOT11_ACTION_CAT_ERR_MASK 0x80 /* category error mask */
+#define DOT11_ACTION_CAT_MASK 0x7F /* category mask */
+#define DOT11_ACTION_CAT_SPECT_MNG 0 /* category spectrum management */
+#define DOT11_ACTION_CAT_QOS 1 /* category QoS */
+#define DOT11_ACTION_CAT_DLS 2 /* category DLS */
+#define DOT11_ACTION_CAT_BLOCKACK 3 /* category block ack */
+#define DOT11_ACTION_CAT_PUBLIC 4 /* category public */
+#define DOT11_ACTION_CAT_RRM 5 /* category radio measurements */
+#define DOT11_ACTION_CAT_FBT 6 /* category fast bss transition */
+#define DOT11_ACTION_CAT_HT 7 /* category for HT */
+#define DOT11_ACTION_CAT_SA_QUERY 8 /* security association query */
+#define DOT11_ACTION_CAT_PDPA 9 /* protected dual of public action */
+#define DOT11_ACTION_CAT_BSSMGMT 10 /* category for BSS transition management */
+#define DOT11_ACTION_NOTIFICATION 17
+#define DOT11_ACTION_CAT_VSP 126 /* protected vendor specific */
+#define DOT11_ACTION_CAT_VS 127 /* category Vendor Specific */
+
+/* Spectrum Management Action IDs (sec 7.4.1) */
+#define DOT11_SM_ACTION_M_REQ 0 /* d11 action measurement request */
+#define DOT11_SM_ACTION_M_REP 1 /* d11 action measurement response */
+#define DOT11_SM_ACTION_TPC_REQ 2 /* d11 action TPC request */
+#define DOT11_SM_ACTION_TPC_REP 3 /* d11 action TPC response */
+#define DOT11_SM_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */
+#define DOT11_SM_ACTION_EXT_CSA 5 /* d11 extened CSA for 11n */
+
+/* HT action ids */
+#define DOT11_ACTION_ID_HT_CH_WIDTH 0 /* notify channel width action id */
+#define DOT11_ACTION_ID_HT_MIMO_PS 1 /* mimo ps action id */
+
+/* Public action ids */
+#define DOT11_PUB_ACTION_BSS_COEX_MNG 0 /* 20/40 Coexistence Management action id */
+#define DOT11_PUB_ACTION_CHANNEL_SWITCH 4 /* d11 action channel switch */
+
+/* Block Ack action types */
+#define DOT11_BA_ACTION_ADDBA_REQ 0 /* ADDBA Req action frame type */
+#define DOT11_BA_ACTION_ADDBA_RESP 1 /* ADDBA Resp action frame type */
+#define DOT11_BA_ACTION_DELBA 2 /* DELBA action frame type */
+
+/* ADDBA action parameters */
+#define DOT11_ADDBA_PARAM_AMSDU_SUP 0x0001 /* AMSDU supported under BA */
+#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 /* policy mask(ack vs delayed) */
+#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 /* policy shift */
+#define DOT11_ADDBA_PARAM_TID_MASK 0x003c /* tid mask */
+#define DOT11_ADDBA_PARAM_TID_SHIFT 2 /* tid shift */
+#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 /* buffer size mask */
+#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 /* buffer size shift */
+
+#define DOT11_ADDBA_POLICY_DELAYED 0 /* delayed BA policy */
+#define DOT11_ADDBA_POLICY_IMMEDIATE 1 /* immediate BA policy */
+
+/* Fast Transition action types */
+#define DOT11_FT_ACTION_FT_RESERVED 0
+#define DOT11_FT_ACTION_FT_REQ 1 /* FBT request - for over-the-DS FBT */
+#define DOT11_FT_ACTION_FT_RES 2 /* FBT response - for over-the-DS FBT */
+#define DOT11_FT_ACTION_FT_CON 3 /* FBT confirm - for OTDS with RRP */
+#define DOT11_FT_ACTION_FT_ACK 4 /* FBT ack */
+
+/* DLS action types */
+#define DOT11_DLS_ACTION_REQ 0 /* DLS Request */
+#define DOT11_DLS_ACTION_RESP 1 /* DLS Response */
+#define DOT11_DLS_ACTION_TD 2 /* DLS Teardown */
+
+/* Wireless Network Management (WNM) action types */
+#define DOT11_WNM_ACTION_EVENT_REQ 0
+#define DOT11_WNM_ACTION_EVENT_REP 1
+#define DOT11_WNM_ACTION_DIAG_REQ 2
+#define DOT11_WNM_ACTION_DIAG_REP 3
+#define DOT11_WNM_ACTION_LOC_CFG_REQ 4
+#define DOT11_WNM_ACTION_LOC_RFG_RESP 5
+#define DOT11_WNM_ACTION_BSS_TRANS_QURY 6
+#define DOT11_WNM_ACTION_BSS_TRANS_REQ 7
+#define DOT11_WNM_ACTION_BSS_TRANS_RESP 8
+#define DOT11_WNM_ACTION_FMS_REQ 9
+#define DOT11_WNM_ACTION_FMS_RESP 10
+#define DOT11_WNM_ACTION_COL_INTRFRNCE_REQ 11
+#define DOT11_WNM_ACTION_COL_INTRFRNCE_REP 12
+#define DOT11_WNM_ACTION_TFS_REQ 13
+#define DOT11_WNM_ACTION_TFS_RESP 14
+#define DOT11_WNM_ACTION_TFS_NOTIFY 15
+#define DOT11_WNM_ACTION_WNM_SLEEP_REQ 16
+#define DOT11_WNM_ACTION_WNM_SLEEP_RESP 17
+#define DOT11_WNM_ACTION_TIM_BCAST_REQ 18
+#define DOT11_WNM_ACTION_TIM_BCAST_RESP 19
+#define DOT11_WNM_ACTION_QOS_TRFC_CAP_UPD 20
+#define DOT11_WNM_ACTION_CHAN_USAGE_REQ 21
+#define DOT11_WNM_ACTION_CHAN_USAGE_RESP 22
+#define DOT11_WNM_ACTION_DMS_REQ 23
+#define DOT11_WNM_ACTION_DMS_RESP 24
+#define DOT11_WNM_ACTION_TMNG_MEASUR_REQ 25
+#define DOT11_WNM_ACTION_NOTFCTN_REQ 26
+#define DOT11_WNM_ACTION_NOTFCTN_RES 27
+
+#define DOT11_MNG_COUNTRY_ID_LEN 3
+
+/* DLS Request frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_dls_req {
+ uint8 category; /* category of action frame (2) */
+ uint8 action; /* DLS action: req (0) */
+ struct ether_addr da; /* destination address */
+ struct ether_addr sa; /* source address */
+ uint16 cap; /* capability */
+ uint16 timeout; /* timeout value */
+ uint8 data[1]; /* IE:support rate, extend support rate, HT cap */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_dls_req dot11_dls_req_t;
+#define DOT11_DLS_REQ_LEN 18 /* Fixed length */
+
+/* DLS response frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_dls_resp {
+ uint8 category; /* category of action frame (2) */
+ uint8 action; /* DLS action: req (0) */
+ uint16 status; /* status code field */
+ struct ether_addr da; /* destination address */
+ struct ether_addr sa; /* source address */
+ uint8 data[1]; /* optional: capability, rate ... */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_dls_resp dot11_dls_resp_t;
+#define DOT11_DLS_RESP_LEN 16 /* Fixed length */
+
+
+/* BSS Management Transition Query frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_query {
+ uint8 category; /* category of action frame (10) */
+ uint8 action; /* WNM action: trans_query (6) */
+ uint8 token; /* dialog token */
+ uint8 reason; /* transition query reason */
+ uint8 data[1]; /* Elements */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_bss_trans_query dot11_bss_trans_query_t;
+#define DOT11_BSS_TRANS_QUERY_LEN 4 /* Fixed length */
+
+/* BSS Management Transition Request frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_req {
+ uint8 category; /* category of action frame (10) */
+ uint8 action; /* WNM action: trans_req (7) */
+ uint8 token; /* dialog token */
+ uint8 reqmode; /* transition request mode */
+ uint16 disassoc_tmr; /* disassociation timer */
+ uint8 validity_intrvl; /* validity interval */
+ uint8 data[1]; /* optional: BSS term duration, ... */
+ /* ...session info URL, list */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_bss_trans_req dot11_bss_trans_req_t;
+#define DOT11_BSS_TRANS_REQ_LEN 7 /* Fixed length */
+
+#define DOT11_BSS_TERM_DUR_LEN 12 /* Fixed length if present */
+
+
+/* BSS Mgmt Transition Request Mode Field - 802.11v */
+#define DOT11_BSS_TRNS_REQMODE_PREF_LIST_INCL 0x01
+#define DOT11_BSS_TRNS_REQMODE_ABRIDGED 0x02
+#define DOT11_BSS_TRNS_REQMODE_DISASSOC_IMMINENT 0x04
+#define DOT11_BSS_TRNS_REQMODE_BSS_TERM_INCL 0x08
+#define DOT11_BSS_TRNS_REQMODE_ESS_DISASSOC_IMNT 0x10
+
+
+/* BSS Management transition response frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_bss_trans_res {
+ uint8 category; /* category of action frame (10) */
+ uint8 action; /* WNM action: trans_res (8) */
+ uint8 token; /* dialog token */
+ uint8 status; /* transition status */
+ uint8 term_delay; /* validity interval */
+ uint8 data[1]; /* optional: BSS term duration, ... */
+ /* ...session info URL, list */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_bss_trans_res dot11_bss_trans_res_t;
+#define DOT11_BSS_TRANS_RES_LEN 5 /* Fixed length */
+
+/* BSS Mgmt Transition Response Status Field */
+#define DOT11_BSS_TRNS_RES_STATUS_ACCEPT 0
+#define DOT11_BSS_TRNS_RES_STATUS_REJECT 1
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_BCN 2
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_INSUFF_CAP 3
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_UNDESIRED 4
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_TERM_DELAY_REQ 5
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_BSS_LIST_PROVIDED 6
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_NO_SUITABLE_BSS 7
+#define DOT11_BSS_TRNS_RES_STATUS_REJ_LEAVING_ESS 8
+
+
+/* Neighbor Report BSSID Information Field */
+#define DOT11_NBR_RPRT_BSSID_INFO_REACHABILTY 0x0003
+#define DOT11_NBR_RPRT_BSSID_INFO_SEC 0x0004
+#define DOT11_NBR_RPRT_BSSID_INFO_KEY_SCOPE 0x0008
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP 0x03f0
+
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_SPEC_MGMT 0x0010
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_QOS 0x0020
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_APSD 0x0040
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_RDIO_MSMT 0x0080
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_DEL_BA 0x0100
+#define DOT11_NBR_RPRT_BSSID_INFO_CAP_IMM_BA 0x0200
+
+/* Neighbor Report Subelements */
+#define DOT11_NBR_RPRT_SUBELEM_BSS_CANDDT_PREF_ID 3
+
+
+BWL_PRE_PACKED_STRUCT struct dot11_addba_req {
+ uint8 category; /* category of action frame (3) */
+ uint8 action; /* action: addba req */
+ uint8 token; /* identifier */
+ uint16 addba_param_set; /* parameter set */
+ uint16 timeout; /* timeout in seconds */
+ uint16 start_seqnum; /* starting sequence number */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_addba_req dot11_addba_req_t;
+#define DOT11_ADDBA_REQ_LEN 9 /* length of addba req frame */
+
+BWL_PRE_PACKED_STRUCT struct dot11_addba_resp {
+ uint8 category; /* category of action frame (3) */
+ uint8 action; /* action: addba resp */
+ uint8 token; /* identifier */
+ uint16 status; /* status of add request */
+ uint16 addba_param_set; /* negotiated parameter set */
+ uint16 timeout; /* negotiated timeout in seconds */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_addba_resp dot11_addba_resp_t;
+#define DOT11_ADDBA_RESP_LEN 9 /* length of addba resp frame */
+
+/* DELBA action parameters */
+#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 /* initiator mask */
+#define DOT11_DELBA_PARAM_INIT_SHIFT 11 /* initiator shift */
+#define DOT11_DELBA_PARAM_TID_MASK 0xf000 /* tid mask */
+#define DOT11_DELBA_PARAM_TID_SHIFT 12 /* tid shift */
+
+BWL_PRE_PACKED_STRUCT struct dot11_delba {
+ uint8 category; /* category of action frame (3) */
+ uint8 action; /* action: addba req */
+ uint16 delba_param_set; /* paarmeter set */
+ uint16 reason; /* reason for dellba */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_delba dot11_delba_t;
+#define DOT11_DELBA_LEN 6 /* length of delba frame */
+
+/* SA Query action field value */
+#define SA_QUERY_REQUEST 0
+#define SA_QUERY_RESPONSE 1
+
+/* ************* 802.11r related definitions. ************* */
+
+/* Over-the-DS Fast Transition Request frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_ft_req {
+ uint8 category; /* category of action frame (6) */
+ uint8 action; /* action: ft req */
+ uint8 sta_addr[ETHER_ADDR_LEN];
+ uint8 tgt_ap_addr[ETHER_ADDR_LEN];
+ uint8 data[1]; /* Elements */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ft_req dot11_ft_req_t;
+#define DOT11_FT_REQ_FIXED_LEN 14
+
+/* Over-the-DS Fast Transition Response frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_ft_res {
+ uint8 category; /* category of action frame (6) */
+ uint8 action; /* action: ft resp */
+ uint8 sta_addr[ETHER_ADDR_LEN];
+ uint8 tgt_ap_addr[ETHER_ADDR_LEN];
+ uint16 status; /* status code */
+ uint8 data[1]; /* Elements */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ft_res dot11_ft_res_t;
+#define DOT11_FT_RES_FIXED_LEN 16
+
+
+/* ************* 802.11k related definitions. ************* */
+
+/* Radio measurements enabled capability ie */
+
+#define DOT11_RRM_CAP_LEN 5 /* length of rrm cap bitmap */
+BWL_PRE_PACKED_STRUCT struct dot11_rrm_cap_ie {
+ uint8 cap[DOT11_RRM_CAP_LEN];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rrm_cap_ie dot11_rrm_cap_ie_t;
+
+/* Bitmap definitions for cap ie */
+#define DOT11_RRM_CAP_LINK 0
+#define DOT11_RRM_CAP_NEIGHBOR_REPORT 1
+#define DOT11_RRM_CAP_PARALLEL 2
+#define DOT11_RRM_CAP_REPEATED 3
+#define DOT11_RRM_CAP_BCN_PASSIVE 4
+#define DOT11_RRM_CAP_BCN_ACTIVE 5
+#define DOT11_RRM_CAP_BCN_TABLE 6
+#define DOT11_RRM_CAP_BCN_REP_COND 7
+#define DOT11_RRM_CAP_AP_CHANREP 16
+
+
+/* Operating Class (formerly "Regulatory Class") definitions */
+#define DOT11_OP_CLASS_NONE 255
+
+
+/* Radio Measurements action ids */
+#define DOT11_RM_ACTION_RM_REQ 0 /* Radio measurement request */
+#define DOT11_RM_ACTION_RM_REP 1 /* Radio measurement report */
+#define DOT11_RM_ACTION_LM_REQ 2 /* Link measurement request */
+#define DOT11_RM_ACTION_LM_REP 3 /* Link measurement report */
+#define DOT11_RM_ACTION_NR_REQ 4 /* Neighbor report request */
+#define DOT11_RM_ACTION_NR_REP 5 /* Neighbor report response */
+
+/* Generic radio measurement action frame header */
+BWL_PRE_PACKED_STRUCT struct dot11_rm_action {
+ uint8 category; /* category of action frame (5) */
+ uint8 action; /* radio measurement action */
+ uint8 token; /* dialog token */
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rm_action dot11_rm_action_t;
+#define DOT11_RM_ACTION_LEN 3
+
+BWL_PRE_PACKED_STRUCT struct dot11_rmreq {
+ uint8 category; /* category of action frame (5) */
+ uint8 action; /* radio measurement action */
+ uint8 token; /* dialog token */
+ uint16 reps; /* no. of repetitions */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rmreq dot11_rmreq_t;
+#define DOT11_RMREQ_LEN 5
+
+BWL_PRE_PACKED_STRUCT struct dot11_rm_ie {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rm_ie dot11_rm_ie_t;
+#define DOT11_RM_IE_LEN 5
+
+/* Definitions for "mode" bits in rm req */
+#define DOT11_RMREQ_MODE_PARALLEL 1
+#define DOT11_RMREQ_MODE_ENABLE 2
+#define DOT11_RMREQ_MODE_REQUEST 4
+#define DOT11_RMREQ_MODE_REPORT 8
+#define DOT11_RMREQ_MODE_DURMAND 0x10 /* Duration Mandatory */
+
+/* Definitions for "mode" bits in rm rep */
+#define DOT11_RMREP_MODE_LATE 1
+#define DOT11_RMREP_MODE_INCAPABLE 2
+#define DOT11_RMREP_MODE_REFUSED 4
+
+BWL_PRE_PACKED_STRUCT struct dot11_rmreq_bcn {
+ uint8 id;
+ uint8 len;
+ uint8 token;
+ uint8 mode;
+ uint8 type;
+ uint8 reg;
+ uint8 channel;
+ uint16 interval;
+ uint16 duration;
+ uint8 bcn_mode;
+ struct ether_addr bssid;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rmreq_bcn dot11_rmreq_bcn_t;
+#define DOT11_RMREQ_BCN_LEN 18
+
+BWL_PRE_PACKED_STRUCT struct dot11_rmrep_bcn {
+ uint8 reg;
+ uint8 channel;
+ uint32 starttime[2];
+ uint16 duration;
+ uint8 frame_info;
+ uint8 rcpi;
+ uint8 rsni;
+ struct ether_addr bssid;
+ uint8 antenna_id;
+ uint32 parent_tsf;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rmrep_bcn dot11_rmrep_bcn_t;
+#define DOT11_RMREP_BCN_LEN 26
+
+/* Beacon request measurement mode */
+#define DOT11_RMREQ_BCN_PASSIVE 0
+#define DOT11_RMREQ_BCN_ACTIVE 1
+#define DOT11_RMREQ_BCN_TABLE 2
+
+/* Sub-element IDs for Beacon Request */
+#define DOT11_RMREQ_BCN_SSID_ID 0
+#define DOT11_RMREQ_BCN_REPINFO_ID 1
+#define DOT11_RMREQ_BCN_REPDET_ID 2
+#define DOT11_RMREQ_BCN_REQUEST_ID 10
+#define DOT11_RMREQ_BCN_APCHREP_ID 51
+
+/* Reporting Detail element definition */
+#define DOT11_RMREQ_BCN_REPDET_FIXED 0 /* Fixed length fields only */
+#define DOT11_RMREQ_BCN_REPDET_REQUEST 1 /* + requested information elems */
+#define DOT11_RMREQ_BCN_REPDET_ALL 2 /* All fields */
+
+/* Sub-element IDs for Beacon Report */
+#define DOT11_RMREP_BCN_FRM_BODY 1
+
+/* Neighbor measurement report */
+BWL_PRE_PACKED_STRUCT struct dot11_rmrep_nbr {
+ struct ether_addr bssid;
+ uint32 bssid_info;
+ uint8 reg;
+ uint8 channel;
+ uint8 phytype;
+ uchar sub_elements[1]; /* Variable size data */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_rmrep_nbr dot11_rmrep_nbr_t;
+#define DOT11_RMREP_NBR_LEN 13
+
+/* MLME Enumerations */
+#define DOT11_BSSTYPE_INFRASTRUCTURE 0 /* d11 infrastructure */
+#define DOT11_BSSTYPE_INDEPENDENT 1 /* d11 independent */
+#define DOT11_BSSTYPE_ANY 2 /* d11 any BSS type */
+#define DOT11_SCANTYPE_ACTIVE 0 /* d11 scan active */
+#define DOT11_SCANTYPE_PASSIVE 1 /* d11 scan passive */
+
+/* Link Measurement */
+BWL_PRE_PACKED_STRUCT struct dot11_lmreq {
+ uint8 category; /* category of action frame (5) */
+ uint8 action; /* radio measurement action */
+ uint8 token; /* dialog token */
+ uint8 txpwr; /* Transmit Power Used */
+ uint8 maxtxpwr; /* Max Transmit Power */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_lmreq dot11_lmreq_t;
+#define DOT11_LMREQ_LEN 5
+
+BWL_PRE_PACKED_STRUCT struct dot11_lmrep {
+ uint8 category; /* category of action frame (5) */
+ uint8 action; /* radio measurement action */
+ uint8 token; /* dialog token */
+ dot11_tpc_rep_t tpc; /* TPC element */
+ uint8 rxant; /* Receive Antenna ID */
+ uint8 txant; /* Transmit Antenna ID */
+ uint8 rcpi; /* RCPI */
+ uint8 rsni; /* RSNI */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_lmrep dot11_lmrep_t;
+#define DOT11_LMREP_LEN 11
+
+/* 802.11 BRCM "Compromise" Pre N constants */
+#define PREN_PREAMBLE 24 /* green field preamble time */
+#define PREN_MM_EXT 12 /* extra mixed mode preamble time */
+#define PREN_PREAMBLE_EXT 4 /* extra preamble (multiply by unique_streams-1) */
+
+/* 802.11N PHY constants */
+#define RIFS_11N_TIME 2 /* NPHY RIFS time */
+
+/* 802.11 HT PLCP format 802.11n-2009, sec 20.3.9.4.3
+ * HT-SIG is composed of two 24 bit parts, HT-SIG1 and HT-SIG2
+ */
+/* HT-SIG1 */
+#define HT_SIG1_MCS_MASK 0x00007F
+#define HT_SIG1_CBW 0x000080
+#define HT_SIG1_HT_LENGTH 0xFFFF00
+
+/* HT-SIG2 */
+#define HT_SIG2_SMOOTHING 0x000001
+#define HT_SIG2_NOT_SOUNDING 0x000002
+#define HT_SIG2_RESERVED 0x000004
+#define HT_SIG2_AGGREGATION 0x000008
+#define HT_SIG2_STBC_MASK 0x000030
+#define HT_SIG2_STBC_SHIFT 4
+#define HT_SIG2_FEC_CODING 0x000040
+#define HT_SIG2_SHORT_GI 0x000080
+#define HT_SIG2_ESS_MASK 0x000300
+#define HT_SIG2_ESS_SHIFT 8
+#define HT_SIG2_CRC 0x03FC00
+#define HT_SIG2_TAIL 0x1C0000
+
+/* 802.11 A PHY constants */
+#define APHY_SLOT_TIME 9 /* APHY slot time */
+#define APHY_SIFS_TIME 16 /* APHY SIFS time */
+#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) /* APHY DIFS time */
+#define APHY_PREAMBLE_TIME 16 /* APHY preamble time */
+#define APHY_SIGNAL_TIME 4 /* APHY signal time */
+#define APHY_SYMBOL_TIME 4 /* APHY symbol time */
+#define APHY_SERVICE_NBITS 16 /* APHY service nbits */
+#define APHY_TAIL_NBITS 6 /* APHY tail nbits */
+#define APHY_CWMIN 15 /* APHY cwmin */
+
+/* 802.11 B PHY constants */
+#define BPHY_SLOT_TIME 20 /* BPHY slot time */
+#define BPHY_SIFS_TIME 10 /* BPHY SIFS time */
+#define BPHY_DIFS_TIME 50 /* BPHY DIFS time */
+#define BPHY_PLCP_TIME 192 /* BPHY PLCP time */
+#define BPHY_PLCP_SHORT_TIME 96 /* BPHY PLCP short time */
+#define BPHY_CWMIN 31 /* BPHY cwmin */
+
+/* 802.11 G constants */
+#define DOT11_OFDM_SIGNAL_EXTENSION 6 /* d11 OFDM signal extension */
+
+#define PHY_CWMAX 1023 /* PHY cwmax */
+
+#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */
+
+/* 802.11 AC (VHT) constants */
+
+typedef int vht_group_id_t;
+
+/* for VHT-A1 */
+/* SIG-A1 reserved bits */
+#define VHT_SIGA1_CONST_MASK 0x800004
+
+#define VHT_SIGA1_20MHZ_VAL 0x000000
+#define VHT_SIGA1_40MHZ_VAL 0x000001
+#define VHT_SIGA1_80MHZ_VAL 0x000002
+#define VHT_SIGA1_160MHZ_VAL 0x000003
+
+#define VHT_SIGA1_STBC 0x000008
+
+#define VHT_SIGA1_GID_MAX_GID 0x3f
+#define VHT_SIGA1_GID_SHIFT 4
+#define VHT_SIGA1_GID_TO_AP 0x00
+#define VHT_SIGA1_GID_NOT_TO_AP 0x3f
+
+#define VHT_SIGA1_NSTS_SHIFT 10
+#define VHT_SIGA1_NSTS_SHIFT_MASK_USER0 0x001C00
+
+#define VHT_SIGA1_PARTIAL_AID_SHIFT 13
+
+/* for VHT-A2 */
+#define VHT_SIGA2_GI_NONE 0x000000
+#define VHT_SIGA2_GI_SHORT 0x000001
+#define VHT_SIGA2_GI_W_MOD10 0x000002
+#define VHT_SIGA2_CODING_LDPC 0x000004
+#define VHT_SIGA2_BEAMFORM_ENABLE 0x000100
+#define VHT_SIGA2_MCS_SHIFT 4
+
+#define VHT_SIGA2_B9_RESERVED 0x000200
+#define VHT_SIGA2_TAIL_MASK 0xfc0000
+#define VHT_SIGA2_TAIL_VALUE 0x000000
+
+#define VHT_SIGA2_SVC_BITS 16
+#define VHT_SIGA2_TAIL_BITS 6
+
+
+/* dot11Counters Table - 802.11 spec., Annex D */
+typedef struct d11cnt {
+ uint32 txfrag; /* dot11TransmittedFragmentCount */
+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */
+ uint32 txfail; /* dot11FailedCount */
+ uint32 txretry; /* dot11RetryCount */
+ uint32 txretrie; /* dot11MultipleRetryCount */
+ uint32 rxdup; /* dot11FrameduplicateCount */
+ uint32 txrts; /* dot11RTSSuccessCount */
+ uint32 txnocts; /* dot11RTSFailureCount */
+ uint32 txnoack; /* dot11ACKFailureCount */
+ uint32 rxfrag; /* dot11ReceivedFragmentCount */
+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */
+ uint32 rxcrc; /* dot11FCSErrorCount */
+ uint32 txfrmsnt; /* dot11TransmittedFrameCount */
+ uint32 rxundec; /* dot11WEPUndecryptableCount */
+} d11cnt_t;
+
+/* OUI for BRCM proprietary IE */
+#define BRCM_PROP_OUI "\x00\x90\x4C" /* Broadcom proprietary OUI */
+
+
+/* BRCM OUI: Used in the proprietary(221) IE in all broadcom devices */
+#define BRCM_OUI "\x00\x10\x18" /* Broadcom OUI */
+
+/* BRCM info element */
+BWL_PRE_PACKED_STRUCT struct brcm_ie {
+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */
+ uint8 len; /* IE length */
+ uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */
+ uint8 ver; /* type/ver of this IE */
+ uint8 assoc; /* # of assoc STAs */
+ uint8 flags; /* misc flags */
+ uint8 flags1; /* misc flags */
+ uint16 amsdu_mtu_pref; /* preferred A-MSDU MTU */
+} BWL_POST_PACKED_STRUCT;
+typedef struct brcm_ie brcm_ie_t;
+#define BRCM_IE_LEN 11 /* BRCM IE length */
+#define BRCM_IE_VER 2 /* BRCM IE version */
+#define BRCM_IE_LEGACY_AES_VER 1 /* BRCM IE legacy AES version */
+
+/* brcm_ie flags */
+#define BRF_LZWDS 0x4 /* lazy wds enabled */
+#define BRF_BLOCKACK 0x8 /* BlockACK capable */
+
+/* brcm_ie flags1 */
+#define BRF1_AMSDU 0x1 /* A-MSDU capable */
+#define BRF1_WMEPS 0x4 /* AP is capable of handling WME + PS w/o APSD */
+#define BRF1_PSOFIX 0x8 /* AP has fixed PS mode out-of-order packets */
+#define BRF1_RX_LARGE_AGG 0x10 /* device can rx large aggregates */
+#define BRF1_RFAWARE_DCS 0x20 /* RFAWARE dynamic channel selection (DCS) */
+#define BRF1_SOFTAP 0x40 /* Configure as Broadcom SOFTAP */
+
+/* Vendor IE structure */
+BWL_PRE_PACKED_STRUCT struct vndr_ie {
+ uchar id;
+ uchar len;
+ uchar oui [3];
+ uchar data [1]; /* Variable size data */
+} BWL_POST_PACKED_STRUCT;
+typedef struct vndr_ie vndr_ie_t;
+
+#define VNDR_IE_HDR_LEN 2 /* id + len field */
+#define VNDR_IE_MIN_LEN 3 /* size of the oui field */
+#define VNDR_IE_FIXED_LEN (VNDR_IE_HDR_LEN + VNDR_IE_MIN_LEN)
+#define VNDR_IE_MAX_LEN 256 /* verdor IE max length */
+
+/* ************* HT definitions. ************* */
+#define MCSSET_LEN 16 /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */
+#define MAX_MCS_NUM (128) /* max mcs number = 128 */
+
+BWL_PRE_PACKED_STRUCT struct ht_cap_ie {
+ uint16 cap;
+ uint8 params;
+ uint8 supp_mcs[MCSSET_LEN];
+ uint16 ext_htcap;
+ uint32 txbf_cap;
+ uint8 as_cap;
+} BWL_POST_PACKED_STRUCT;
+typedef struct ht_cap_ie ht_cap_ie_t;
+
+/* CAP IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */
+/* the capability IE is primarily used to convey this nodes abilities */
+BWL_PRE_PACKED_STRUCT struct ht_prop_cap_ie {
+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */
+ uint8 len; /* IE length */
+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */
+ uint8 type; /* type inidicates what follows */
+ ht_cap_ie_t cap_ie;
+} BWL_POST_PACKED_STRUCT;
+typedef struct ht_prop_cap_ie ht_prop_cap_ie_t;
+
+#define HT_PROP_IE_OVERHEAD 4 /* overhead bytes for prop oui ie */
+#define HT_CAP_IE_LEN 26 /* HT capability len (based on .11n d2.0) */
+#define HT_CAP_IE_TYPE 51
+
+#define HT_CAP_LDPC_CODING 0x0001 /* Support for rx of LDPC coded pkts */
+#define HT_CAP_40MHZ 0x0002 /* FALSE:20Mhz, TRUE:20/40MHZ supported */
+#define HT_CAP_MIMO_PS_MASK 0x000C /* Mimo PS mask */
+#define HT_CAP_MIMO_PS_SHIFT 0x0002 /* Mimo PS shift */
+#define HT_CAP_MIMO_PS_OFF 0x0003 /* Mimo PS, no restriction */
+#define HT_CAP_MIMO_PS_RTS 0x0001 /* Mimo PS, send RTS/CTS around MIMO frames */
+#define HT_CAP_MIMO_PS_ON 0x0000 /* Mimo PS, MIMO disallowed */
+#define HT_CAP_GF 0x0010 /* Greenfield preamble support */
+#define HT_CAP_SHORT_GI_20 0x0020 /* 20MHZ short guard interval support */
+#define HT_CAP_SHORT_GI_40 0x0040 /* 40Mhz short guard interval support */
+#define HT_CAP_TX_STBC 0x0080 /* Tx STBC support */
+#define HT_CAP_RX_STBC_MASK 0x0300 /* Rx STBC mask */
+#define HT_CAP_RX_STBC_SHIFT 8 /* Rx STBC shift */
+#define HT_CAP_DELAYED_BA 0x0400 /* delayed BA support */
+#define HT_CAP_MAX_AMSDU 0x0800 /* Max AMSDU size in bytes , 0=3839, 1=7935 */
+
+#define HT_CAP_DSSS_CCK 0x1000 /* DSSS/CCK supported by the BSS */
+#define HT_CAP_PSMP 0x2000 /* Power Save Multi Poll support */
+#define HT_CAP_40MHZ_INTOLERANT 0x4000 /* 40MHz Intolerant */
+#define HT_CAP_LSIG_TXOP 0x8000 /* L-SIG TXOP protection support */
+
+#define HT_CAP_RX_STBC_NO 0x0 /* no rx STBC support */
+#define HT_CAP_RX_STBC_ONE_STREAM 0x1 /* rx STBC support of 1 spatial stream */
+#define HT_CAP_RX_STBC_TWO_STREAM 0x2 /* rx STBC support of 1-2 spatial streams */
+#define HT_CAP_RX_STBC_THREE_STREAM 0x3 /* rx STBC support of 1-3 spatial streams */
+
+#define VHT_MAX_MPDU 11454 /* max mpdu size for now (bytes) */
+#define VHT_MPDU_MSDU_DELTA 56 /* Difference in spec - vht mpdu, amsdu len */
+/* Max AMSDU len - per spec */
+#define VHT_MAX_AMSDU (VHT_MAX_MPDU - VHT_MPDU_MSDU_DELTA)
+
+#define HT_MAX_AMSDU 7935 /* max amsdu size (bytes) per the HT spec */
+#define HT_MIN_AMSDU 3835 /* min amsdu size (bytes) per the HT spec */
+
+#define HT_PARAMS_RX_FACTOR_MASK 0x03 /* ampdu rcv factor mask */
+#define HT_PARAMS_DENSITY_MASK 0x1C /* ampdu density mask */
+#define HT_PARAMS_DENSITY_SHIFT 2 /* ampdu density shift */
+
+/* HT/AMPDU specific define */
+#define AMPDU_MAX_MPDU_DENSITY 7 /* max mpdu density; in 1/4 usec units */
+#define AMPDU_DENSITY_NONE 0 /* No density requirement */
+#define AMPDU_DENSITY_1over4_US 1 /* 1/4 us density */
+#define AMPDU_DENSITY_1over2_US 2 /* 1/2 us density */
+#define AMPDU_DENSITY_1_US 3 /* 1 us density */
+#define AMPDU_DENSITY_2_US 4 /* 2 us density */
+#define AMPDU_DENSITY_4_US 5 /* 4 us density */
+#define AMPDU_DENSITY_8_US 6 /* 8 us density */
+#define AMPDU_DENSITY_16_US 7 /* 16 us density */
+#define AMPDU_RX_FACTOR_8K 0 /* max rcv ampdu len (8kb) */
+#define AMPDU_RX_FACTOR_16K 1 /* max rcv ampdu len (16kb) */
+#define AMPDU_RX_FACTOR_32K 2 /* max rcv ampdu len (32kb) */
+#define AMPDU_RX_FACTOR_64K 3 /* max rcv ampdu len (64kb) */
+#define AMPDU_RX_FACTOR_BASE 8*1024 /* ampdu factor base for rx len */
+
+#define AMPDU_DELIMITER_LEN 4 /* length of ampdu delimiter */
+#define AMPDU_DELIMITER_LEN_MAX 63 /* max length of ampdu delimiter(enforced in HW) */
+
+#define HT_CAP_EXT_PCO 0x0001
+#define HT_CAP_EXT_PCO_TTIME_MASK 0x0006
+#define HT_CAP_EXT_PCO_TTIME_SHIFT 1
+#define HT_CAP_EXT_MCS_FEEDBACK_MASK 0x0300
+#define HT_CAP_EXT_MCS_FEEDBACK_SHIFT 8
+#define HT_CAP_EXT_HTC 0x0400
+#define HT_CAP_EXT_RD_RESP 0x0800
+
+BWL_PRE_PACKED_STRUCT struct ht_add_ie {
+ uint8 ctl_ch; /* control channel number */
+ uint8 byte1; /* ext ch,rec. ch. width, RIFS support */
+ uint16 opmode; /* operation mode */
+ uint16 misc_bits; /* misc bits */
+ uint8 basic_mcs[MCSSET_LEN]; /* required MCS set */
+} BWL_POST_PACKED_STRUCT;
+typedef struct ht_add_ie ht_add_ie_t;
+
+/* ADD IE: HT 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */
+/* the additional IE is primarily used to convey the current BSS configuration */
+BWL_PRE_PACKED_STRUCT struct ht_prop_add_ie {
+ uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */
+ uint8 len; /* IE length */
+ uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */
+ uint8 type; /* indicates what follows */
+ ht_add_ie_t add_ie;
+} BWL_POST_PACKED_STRUCT;
+typedef struct ht_prop_add_ie ht_prop_add_ie_t;
+
+#define HT_ADD_IE_LEN 22
+#define HT_ADD_IE_TYPE 52
+
+/* byte1 defn's */
+#define HT_BW_ANY 0x04 /* set, STA can use 20 or 40MHz */
+#define HT_RIFS_PERMITTED 0x08 /* RIFS allowed */
+
+/* opmode defn's */
+#define HT_OPMODE_MASK 0x0003 /* protection mode mask */
+#define HT_OPMODE_SHIFT 0 /* protection mode shift */
+#define HT_OPMODE_PURE 0x0000 /* protection mode PURE */
+#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */
+#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */
+#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */
+#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */
+#define DOT11N_TXBURST 0x0008 /* Tx burst limit */
+#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */
+
+/* misc_bites defn's */
+#define HT_BASIC_STBC_MCS 0x007f /* basic STBC MCS */
+#define HT_DUAL_STBC_PROT 0x0080 /* Dual STBC Protection */
+#define HT_SECOND_BCN 0x0100 /* Secondary beacon support */
+#define HT_LSIG_TXOP 0x0200 /* L-SIG TXOP Protection full support */
+#define HT_PCO_ACTIVE 0x0400 /* PCO active */
+#define HT_PCO_PHASE 0x0800 /* PCO phase */
+#define HT_DUALCTS_PROTECTION 0x0080 /* DUAL CTS protection needed */
+
+/* Tx Burst Limits */
+#define DOT11N_2G_TXBURST_LIMIT 6160 /* 2G band Tx burst limit per 802.11n Draft 1.10 (usec) */
+#define DOT11N_5G_TXBURST_LIMIT 3080 /* 5G band Tx burst limit per 802.11n Draft 1.10 (usec) */
+
+/* Macros for opmode */
+#define GET_HT_OPMODE(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \
+ >> HT_OPMODE_SHIFT)
+#define HT_MIXEDMODE_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \
+ == HT_OPMODE_MIXED) /* mixed mode present */
+#define HT_HT20_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \
+ == HT_OPMODE_HT20IN40) /* 20MHz HT present */
+#define HT_OPTIONAL_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_MASK) \
+ == HT_OPMODE_OPTIONAL) /* Optional protection present */
+#define HT_USE_PROTECTION(add_ie) (HT_HT20_PRESENT((add_ie)) || \
+ HT_MIXEDMODE_PRESENT((add_ie))) /* use protection */
+#define HT_NONGF_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & HT_OPMODE_NONGF) \
+ == HT_OPMODE_NONGF) /* non-GF present */
+#define DOT11N_TXBURST_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_TXBURST) \
+ == DOT11N_TXBURST) /* Tx Burst present */
+#define DOT11N_OBSS_NONHT_PRESENT(add_ie) ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \
+ == DOT11N_OBSS_NONHT) /* OBSS Non-HT present */
+
+BWL_PRE_PACKED_STRUCT struct obss_params {
+ uint16 passive_dwell;
+ uint16 active_dwell;
+ uint16 bss_widthscan_interval;
+ uint16 passive_total;
+ uint16 active_total;
+ uint16 chanwidth_transition_dly;
+ uint16 activity_threshold;
+} BWL_POST_PACKED_STRUCT;
+typedef struct obss_params obss_params_t;
+
+BWL_PRE_PACKED_STRUCT struct dot11_obss_ie {
+ uint8 id;
+ uint8 len;
+ obss_params_t obss_params;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_obss_ie dot11_obss_ie_t;
+#define DOT11_OBSS_SCAN_IE_LEN sizeof(obss_params_t) /* HT OBSS len (based on 802.11n d3.0) */
+
+/* HT control field */
+#define HT_CTRL_LA_TRQ 0x00000002 /* sounding request */
+#define HT_CTRL_LA_MAI 0x0000003C /* MCS request or antenna selection indication */
+#define HT_CTRL_LA_MAI_SHIFT 2
+#define HT_CTRL_LA_MAI_MRQ 0x00000004 /* MCS request */
+#define HT_CTRL_LA_MAI_MSI 0x00000038 /* MCS request sequence identifier */
+#define HT_CTRL_LA_MFSI 0x000001C0 /* MFB sequence identifier */
+#define HT_CTRL_LA_MFSI_SHIFT 6
+#define HT_CTRL_LA_MFB_ASELC 0x0000FE00 /* MCS feedback, antenna selection command/data */
+#define HT_CTRL_LA_MFB_ASELC_SH 9
+#define HT_CTRL_LA_ASELC_CMD 0x00000C00 /* ASEL command */
+#define HT_CTRL_LA_ASELC_DATA 0x0000F000 /* ASEL data */
+#define HT_CTRL_CAL_POS 0x00030000 /* Calibration position */
+#define HT_CTRL_CAL_SEQ 0x000C0000 /* Calibration sequence */
+#define HT_CTRL_CSI_STEERING 0x00C00000 /* CSI/Steering */
+#define HT_CTRL_CSI_STEER_SHIFT 22
+#define HT_CTRL_CSI_STEER_NFB 0 /* no fedback required */
+#define HT_CTRL_CSI_STEER_CSI 1 /* CSI, H matrix */
+#define HT_CTRL_CSI_STEER_NCOM 2 /* non-compressed beamforming */
+#define HT_CTRL_CSI_STEER_COM 3 /* compressed beamforming */
+#define HT_CTRL_NDP_ANNOUNCE 0x01000000 /* NDP announcement */
+#define HT_CTRL_AC_CONSTRAINT 0x40000000 /* AC Constraint */
+#define HT_CTRL_RDG_MOREPPDU 0x80000000 /* RDG/More PPDU */
+
+#define HT_OPMODE_OPTIONAL 0x0001 /* protection mode optional */
+#define HT_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */
+#define HT_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */
+#define HT_OPMODE_NONGF 0x0004 /* protection mode non-GF */
+#define DOT11N_TXBURST 0x0008 /* Tx burst limit */
+#define DOT11N_OBSS_NONHT 0x0010 /* OBSS Non-HT STA present */
+
+/* ************* VHT definitions. ************* */
+
+BWL_PRE_PACKED_STRUCT struct vht_cap_ie {
+ uint32 vht_cap_info;
+ /* supported MCS set - 64 bit field */
+ uint16 rx_mcs_map;
+ uint16 rx_max_rate;
+ uint16 tx_mcs_map;
+ uint16 tx_max_rate;
+} BWL_POST_PACKED_STRUCT;
+typedef struct vht_cap_ie vht_cap_ie_t;
+/* 4B cap_info + 8B supp_mcs */
+#define VHT_CAP_IE_LEN 12
+/* 32bit - cap info */
+#define VHT_CAP_INFO_MAX_MPDU_LEN_MASK 0x00000003
+#define VHT_CAP_INFO_SUPP_CHAN_WIDTH_MASK 0x0000000c
+#define VHT_CAP_INFO_LDPC 0x00000010
+#define VHT_CAP_INFO_SGI_80MHZ 0x00000020
+
+#define VHT_CAP_INFO_SGI_160MHZ 0x00000040
+#define VHT_CAP_INFO_TX_STBC 0x00000080
+
+#define VHT_CAP_INFO_RX_STBC_MASK 0x00000700
+#define VHT_CAP_INFO_RX_STBC_SHIFT 8
+#define VHT_CAP_INFO_SU_BEAMFMR 0x00000800
+#define VHT_CAP_INFO_SU_BEAMFMEE 0x00001000
+#define VHT_CAP_INFO_NUM_BMFMR_ANT_MASK 0x0000e000
+#define VHT_CAP_INFO_NUM_BMFMR_ANT_SHIFT 13
+
+#define VHT_CAP_INFO_NUM_SOUNDING_DIM_MASK 0x00070000
+#define VHT_CAP_INFO_NUM_SOUNDING_DIM_SHIFT 16
+#define VHT_CAP_INFO_MU_BEAMFMR 0x00080000
+#define VHT_CAP_INFO_MU_BEAMFMEE 0x00100000
+#define VHT_CAP_INFO_TXOPPS 0x00200000
+#define VHT_CAP_INFO_HTCVHT 0x00400000
+#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_MASK 0x03800000
+#define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_SHIFT 23
+
+#define VHT_CAP_INFO_LINK_ADAPT_CAP_MASK 0x0c000000
+#define VHT_CAP_INFO_LINK_ADAPT_CAP_SHIFT 26
+
+/* 64-bit Supp MCS. */
+#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_MASK 0x1fff
+#define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_SHIFT 0
+
+#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_MASK 0x1fff
+#define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_SHIFT 0
+
+#define VHT_CAP_MCS_MAP_0_7 0
+#define VHT_CAP_MCS_MAP_0_8 1
+#define VHT_CAP_MCS_MAP_0_9 2
+#define VHT_CAP_MCS_MAP_NONE 3
+
+#define VHT_CAP_MCS_MAP_NSS_MAX 8
+
+/* VHT Capabilities Supported Channel Width */
+typedef enum vht_cap_chan_width {
+ VHT_CAP_CHAN_WIDTH_20_40 = 0x00,
+ VHT_CAP_CHAN_WIDTH_80 = 0x04,
+ VHT_CAP_CHAN_WIDTH_160 = 0x08
+} vht_cap_chan_width_t;
+
+/* VHT Capabilities Supported max MPDU LEN */
+typedef enum vht_cap_max_mpdu_len {
+ VHT_CAP_MPDU_MAX_4K = 0x00,
+ VHT_CAP_MPDU_MAX_8K = 0x01,
+ VHT_CAP_MPDU_MAX_11K = 0x02
+} vht_cap_max_mpdu_len_t;
+
+/* VHT Operation Element */
+BWL_PRE_PACKED_STRUCT struct vht_op_ie {
+ uint8 chan_width;
+ uint8 chan1;
+ uint8 chan2;
+ uint16 supp_mcs; /* same def as above in vht cap */
+} BWL_POST_PACKED_STRUCT;
+typedef struct vht_op_ie vht_op_ie_t;
+/* 3B VHT Op info + 2B Basic MCS */
+#define VHT_OP_IE_LEN 5
+
+typedef enum vht_op_chan_width {
+ VHT_OP_CHAN_WIDTH_20_40 = 0,
+ VHT_OP_CHAN_WIDTH_80 = 1,
+ VHT_OP_CHAN_WIDTH_160 = 2,
+ VHT_OP_CHAN_WIDTH_80_80 = 3
+} vht_op_chan_width_t;
+
+/* Def for rx & tx basic mcs maps - ea ss num has 2 bits of info */
+#define VHT_MCS_MAP_GET_SS_IDX(nss) (((nss)-1)*2)
+#define VHT_MCS_MAP_GET_MCS_PER_SS(nss, mcsMap) \
+ (((mcsMap) >> VHT_MCS_MAP_GET_SS_IDX(nss)) & 0x3)
+#define VHT_MCS_MAP_SET_MCS_PER_SS(nss, numMcs, mcsMap) \
+ ((mcsMap) |= (((numMcs) & 0x3) << VHT_MCS_MAP_GET_SS_IDX(nss)))
+
+/* ************* WPA definitions. ************* */
+#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
+#define WPA_OUI_LEN 3 /* WPA OUI length */
+#define WPA_OUI_TYPE 1
+#define WPA_VERSION 1 /* WPA version */
+#define WPA2_OUI "\x00\x0F\xAC" /* WPA2 OUI */
+#define WPA2_OUI_LEN 3 /* WPA2 OUI length */
+#define WPA2_VERSION 1 /* WPA2 version */
+#define WPA2_VERSION_LEN 2 /* WAP2 version length */
+
+/* ************* WPS definitions. ************* */
+#define WPS_OUI "\x00\x50\xF2" /* WPS OUI */
+#define WPS_OUI_LEN 3 /* WPS OUI length */
+#define WPS_OUI_TYPE 4
+
+/* ************* WFA definitions. ************* */
+
+#ifdef P2P_IE_OVRD
+#define WFA_OUI MAC_OUI
+#else
+#define WFA_OUI "\x50\x6F\x9A" /* WFA OUI */
+#endif /* P2P_IE_OVRD */
+#define WFA_OUI_LEN 3 /* WFA OUI length */
+#ifdef P2P_IE_OVRD
+#define WFA_OUI_TYPE_P2P MAC_OUI_TYPE_P2P
+#else
+#define WFA_OUI_TYPE_P2P 9
+#endif
+
+#define WFA_OUI_TYPE_TPC 8
+#ifdef WLTDLS
+#define WFA_OUI_TYPE_WFD 10
+#endif /* WTDLS */
+
+/* RSN authenticated key managment suite */
+#define RSN_AKM_NONE 0 /* None (IBSS) */
+#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
+#define RSN_AKM_PSK 2 /* Pre-shared Key */
+#define RSN_AKM_FBT_1X 3 /* Fast Bss transition using 802.1X */
+#define RSN_AKM_FBT_PSK 4 /* Fast Bss transition using Pre-shared Key */
+#define RSN_AKM_MFP_1X 5 /* SHA256 key derivation, using 802.1X */
+#define RSN_AKM_MFP_PSK 6 /* SHA256 key derivation, using Pre-shared Key */
+#define RSN_AKM_TPK 7 /* TPK(TDLS Peer Key) handshake */
+
+/* Key related defines */
+#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */
+#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */
+#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */
+#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */
+#define DOT11_WPA_KEY_RSC_LEN 8 /* WPA RSC key len */
+
+#define WEP1_KEY_SIZE 5 /* max size of any WEP key */
+#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */
+#define WEP128_KEY_SIZE 13 /* max size of any WEP key */
+#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */
+#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */
+#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */
+#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */
+#define TKIP_KEY_SIZE 32 /* size of any TKIP key */
+#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */
+#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */
+#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX /* offset to Supplicant MIC RX key */
+#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX /* offset to Supplicant MIC TX key */
+#define AES_KEY_SIZE 16 /* size of AES key */
+#define AES_MIC_SIZE 8 /* size of AES MIC */
+#define BIP_KEY_SIZE 16 /* size of BIP key */
+
+/* WCN */
+#define WCN_OUI "\x00\x50\xf2" /* WCN OUI */
+#define WCN_TYPE 4 /* WCN type */
+#ifdef BCMWAPI_WPI
+#define SMS4_KEY_LEN 16
+#define SMS4_WPI_CBC_MAC_LEN 16
+#endif
+
+
+/* 802.11r protocol definitions */
+
+/* Mobility Domain IE */
+BWL_PRE_PACKED_STRUCT struct dot11_mdid_ie {
+ uint8 id;
+ uint8 len;
+ uint16 mdid; /* Mobility Domain Id */
+ uint8 cap;
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_mdid_ie dot11_mdid_ie_t;
+
+#define FBT_MDID_CAP_OVERDS 0x01 /* Fast Bss transition over the DS support */
+#define FBT_MDID_CAP_RRP 0x02 /* Resource request protocol support */
+
+/* Fast Bss Transition IE */
+BWL_PRE_PACKED_STRUCT struct dot11_ft_ie {
+ uint8 id;
+ uint8 len;
+ uint16 mic_control; /* Mic Control */
+ uint8 mic[16];
+ uint8 anonce[32];
+ uint8 snonce[32];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_ft_ie dot11_ft_ie_t;
+
+#define TIE_TYPE_RESERVED 0
+#define TIE_TYPE_REASSOC_DEADLINE 1
+#define TIE_TYPE_KEY_LIEFTIME 2
+#define TIE_TYPE_ASSOC_COMEBACK 3
+BWL_PRE_PACKED_STRUCT struct dot11_timeout_ie {
+ uint8 id;
+ uint8 len;
+ uint8 type; /* timeout interval type */
+ uint32 value; /* timeout interval value */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_timeout_ie dot11_timeout_ie_t;
+
+
+/* GTK ie */
+BWL_PRE_PACKED_STRUCT struct dot11_gtk_ie {
+ uint8 id;
+ uint8 len;
+ uint16 key_info;
+ uint8 key_len;
+ uint8 rsc[8];
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_gtk_ie dot11_gtk_ie_t;
+
+#define BSSID_INVALID "\x00\x00\x00\x00\x00\x00"
+#define BSSID_BROADCAST "\xFF\xFF\xFF\xFF\xFF\xFF"
+
+
+/* ************* WMM Parameter definitions. ************* */
+#define WMM_OUI "\x00\x50\xF2" /* WNN OUI */
+#define WMM_OUI_LEN 3 /* WMM OUI length */
+#define WMM_OUI_TYPE 2 /* WMM OUT type */
+#define WMM_VERSION 1
+#define WMM_VERSION_LEN 1
+
+/* WMM OUI subtype */
+#define WMM_OUI_SUBTYPE_PARAMETER 1
+#define WMM_PARAMETER_IE_LEN 24
+
+/* Link Identifier Element */
+BWL_PRE_PACKED_STRUCT struct link_id_ie {
+ uint8 id;
+ uint8 len;
+ struct ether_addr bssid;
+ struct ether_addr tdls_init_mac;
+ struct ether_addr tdls_resp_mac;
+} BWL_POST_PACKED_STRUCT;
+typedef struct link_id_ie link_id_ie_t;
+#define TDLS_LINK_ID_IE_LEN 18
+
+/* Link Wakeup Schedule Element */
+BWL_PRE_PACKED_STRUCT struct wakeup_sch_ie {
+ uint8 id;
+ uint8 len;
+ uint32 offset; /* in ms between TSF0 and start of 1st Awake Window */
+ uint32 interval; /* in ms bwtween the start of 2 Awake Windows */
+ uint32 awake_win_slots; /* in backof slots, duration of Awake Window */
+ uint32 max_wake_win; /* in ms, max duration of Awake Window */
+ uint16 idle_cnt; /* number of consecutive Awake Windows */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wakeup_sch_ie wakeup_sch_ie_t;
+#define TDLS_WAKEUP_SCH_IE_LEN 18
+
+/* Channel Switch Timing Element */
+BWL_PRE_PACKED_STRUCT struct channel_switch_timing_ie {
+ uint8 id;
+ uint8 len;
+ uint16 switch_time; /* in ms, time to switch channels */
+ uint16 switch_timeout; /* in ms */
+} BWL_POST_PACKED_STRUCT;
+typedef struct channel_switch_timing_ie channel_switch_timing_ie_t;
+#define TDLS_CHANNEL_SWITCH_TIMING_IE_LEN 4
+
+/* PTI Control Element */
+BWL_PRE_PACKED_STRUCT struct pti_control_ie {
+ uint8 id;
+ uint8 len;
+ uint8 tid;
+ uint16 seq_control;
+} BWL_POST_PACKED_STRUCT;
+typedef struct pti_control_ie pti_control_ie_t;
+#define TDLS_PTI_CONTROL_IE_LEN 3
+
+/* PU Buffer Status Element */
+BWL_PRE_PACKED_STRUCT struct pu_buffer_status_ie {
+ uint8 id;
+ uint8 len;
+ uint8 status;
+} BWL_POST_PACKED_STRUCT;
+typedef struct pu_buffer_status_ie pu_buffer_status_ie_t;
+#define TDLS_PU_BUFFER_STATUS_IE_LEN 1
+#define TDLS_PU_BUFFER_STATUS_AC_BK 1
+#define TDLS_PU_BUFFER_STATUS_AC_BE 2
+#define TDLS_PU_BUFFER_STATUS_AC_VI 4
+#define TDLS_PU_BUFFER_STATUS_AC_VO 8
+
+#ifdef BCMWAPI_WAI
+#define WAPI_IE_MIN_LEN 20 /* WAPI IE min length */
+#define WAPI_VERSION 1 /* WAPI version */
+#define WAPI_VERSION_LEN 2 /* WAPI version length */
+#define WAPI_OUI "\x00\x14\x72" /* WAPI OUI */
+#define WAPI_OUI_LEN DOT11_OUI_LEN /* WAPI OUI length */
+#endif /* BCMWAPI_WAI */
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _802_11_H_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/802.11_bta.h b/drivers/net/wireless/ap6210/include/proto/802.11_bta.h
new file mode 100644
index 0000000..3ee5a74
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/802.11_bta.h
@@ -0,0 +1,45 @@
+/*
+ * BT-AMP (BlueTooth Alternate Mac and Phy) 802.11 PAL (Protocol Adaptation Layer)
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: 802.11_bta.h 294267 2011-11-04 23:41:52Z $
+*/
+
+#ifndef _802_11_BTA_H_
+#define _802_11_BTA_H_
+
+#define BT_SIG_SNAP_MPROT "\xAA\xAA\x03\x00\x19\x58"
+
+/* BT-AMP 802.11 PAL Protocols */
+#define BTA_PROT_L2CAP 1
+#define BTA_PROT_ACTIVITY_REPORT 2
+#define BTA_PROT_SECURITY 3
+#define BTA_PROT_LINK_SUPERVISION_REQUEST 4
+#define BTA_PROT_LINK_SUPERVISION_REPLY 5
+
+/* BT-AMP 802.11 PAL AMP_ASSOC Type IDs */
+#define BTA_TYPE_ID_MAC_ADDRESS 1
+#define BTA_TYPE_ID_PREFERRED_CHANNELS 2
+#define BTA_TYPE_ID_CONNECTED_CHANNELS 3
+#define BTA_TYPE_ID_CAPABILITIES 4
+#define BTA_TYPE_ID_VERSION 5
+#endif /* _802_11_bta_h_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/802.11e.h b/drivers/net/wireless/ap6210/include/proto/802.11e.h
new file mode 100644
index 0000000..f391e68
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/802.11e.h
@@ -0,0 +1,131 @@
+/*
+ * 802.11e protocol header file
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: 802.11e.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _802_11e_H_
+#define _802_11e_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+
+/* WME Traffic Specification (TSPEC) element */
+#define WME_TSPEC_HDR_LEN 2 /* WME TSPEC header length */
+#define WME_TSPEC_BODY_OFF 2 /* WME TSPEC body offset */
+
+#define WME_CATEGORY_CODE_OFFSET 0 /* WME Category code offset */
+#define WME_ACTION_CODE_OFFSET 1 /* WME Action code offset */
+#define WME_TOKEN_CODE_OFFSET 2 /* WME Token code offset */
+#define WME_STATUS_CODE_OFFSET 3 /* WME Status code offset */
+
+BWL_PRE_PACKED_STRUCT struct tsinfo {
+ uint8 octets[3];
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct tsinfo tsinfo_t;
+
+/* 802.11e TSPEC IE */
+typedef BWL_PRE_PACKED_STRUCT struct tspec {
+ uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */
+ uint8 type; /* WME_TYPE */
+ uint8 subtype; /* WME_SUBTYPE_TSPEC */
+ uint8 version; /* WME_VERSION */
+ tsinfo_t tsinfo; /* TS Info bit field */
+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */
+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */
+ uint32 min_srv_interval; /* Minimum Service Interval (us) */
+ uint32 max_srv_interval; /* Maximum Service Interval (us) */
+ uint32 inactivity_interval; /* Inactivity Interval (us) */
+ uint32 suspension_interval; /* Suspension Interval (us) */
+ uint32 srv_start_time; /* Service Start Time (us) */
+ uint32 min_data_rate; /* Minimum Data Rate (bps) */
+ uint32 mean_data_rate; /* Mean Data Rate (bps) */
+ uint32 peak_data_rate; /* Peak Data Rate (bps) */
+ uint32 max_burst_size; /* Maximum Burst Size (bytes) */
+ uint32 delay_bound; /* Delay Bound (us) */
+ uint32 min_phy_rate; /* Minimum PHY Rate (bps) */
+ uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0-8.0) */
+ uint16 medium_time; /* Medium Time (32 us/s periods) */
+} BWL_POST_PACKED_STRUCT tspec_t;
+
+#define WME_TSPEC_LEN (sizeof(tspec_t)) /* not including 2-bytes of header */
+
+/* ts_info */
+/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */
+#define TS_INFO_TID_SHIFT 1 /* TS info. TID shift */
+#define TS_INFO_TID_MASK (0xf << TS_INFO_TID_SHIFT) /* TS info. TID mask */
+#define TS_INFO_CONTENTION_SHIFT 7 /* TS info. contention shift */
+#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) /* TS info. contention mask */
+#define TS_INFO_DIRECTION_SHIFT 5 /* TS info. direction shift */
+#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) /* TS info. direction mask */
+#define TS_INFO_PSB_SHIFT 2 /* TS info. PSB bit Shift */
+#define TS_INFO_PSB_MASK (1 << TS_INFO_PSB_SHIFT) /* TS info. PSB mask */
+#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) /* TS info. uplink */
+#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) /* TS info. downlink */
+#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) /* TS info. bidirectional */
+#define TS_INFO_USER_PRIO_SHIFT 3 /* TS info. user priority shift */
+/* TS info. user priority mask */
+#define TS_INFO_USER_PRIO_MASK (0x7 << TS_INFO_USER_PRIO_SHIFT)
+
+/* Macro to get/set bit(s) field in TSINFO */
+#define WLC_CAC_GET_TID(pt) ((((pt).octets[0]) & TS_INFO_TID_MASK) >> TS_INFO_TID_SHIFT)
+#define WLC_CAC_GET_DIR(pt) ((((pt).octets[0]) & \
+ TS_INFO_DIRECTION_MASK) >> TS_INFO_DIRECTION_SHIFT)
+#define WLC_CAC_GET_PSB(pt) ((((pt).octets[1]) & TS_INFO_PSB_MASK) >> TS_INFO_PSB_SHIFT)
+#define WLC_CAC_GET_USER_PRIO(pt) ((((pt).octets[1]) & \
+ TS_INFO_USER_PRIO_MASK) >> TS_INFO_USER_PRIO_SHIFT)
+
+#define WLC_CAC_SET_TID(pt, id) ((((pt).octets[0]) & (~TS_INFO_TID_MASK)) | \
+ ((id) << TS_INFO_TID_SHIFT))
+#define WLC_CAC_SET_USER_PRIO(pt, prio) ((((pt).octets[0]) & (~TS_INFO_USER_PRIO_MASK)) | \
+ ((prio) << TS_INFO_USER_PRIO_SHIFT))
+
+/* 802.11e QBSS Load IE */
+#define QBSS_LOAD_IE_LEN 5 /* QBSS Load IE length */
+#define QBSS_LOAD_AAC_OFF 3 /* AAC offset in IE */
+
+#define CAC_ADDTS_RESP_TIMEOUT 300 /* default ADDTS response timeout in ms */
+
+/* 802.11e ADDTS status code */
+#define DOT11E_STATUS_ADMISSION_ACCEPTED 0 /* TSPEC Admission accepted status */
+#define DOT11E_STATUS_ADDTS_INVALID_PARAM 1 /* TSPEC invalid parameter status */
+#define DOT11E_STATUS_ADDTS_REFUSED_NSBW 3 /* ADDTS refused (non-sufficient BW) */
+#define DOT11E_STATUS_ADDTS_REFUSED_AWHILE 47 /* ADDTS refused but could retry later */
+
+/* 802.11e DELTS status code */
+#define DOT11E_STATUS_QSTA_LEAVE_QBSS 36 /* STA leave QBSS */
+#define DOT11E_STATUS_END_TS 37 /* END TS */
+#define DOT11E_STATUS_UNKNOWN_TS 38 /* UNKNOWN TS */
+#define DOT11E_STATUS_QSTA_REQ_TIMEOUT 39 /* STA ADDTS request timeout */
+
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _802_11e_CAC_H_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/802.1d.h b/drivers/net/wireless/ap6210/include/proto/802.1d.h
new file mode 100644
index 0000000..f11cc6c
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/802.1d.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * Fundamental types and constants relating to 802.1D
+ *
+ * $Id: 802.1d.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _802_1_D_
+#define _802_1_D_
+
+/* 802.1D priority defines */
+#define PRIO_8021D_NONE 2 /* None = - */
+#define PRIO_8021D_BK 1 /* BK - Background */
+#define PRIO_8021D_BE 0 /* BE - Best-effort */
+#define PRIO_8021D_EE 3 /* EE - Excellent-effort */
+#define PRIO_8021D_CL 4 /* CL - Controlled Load */
+#define PRIO_8021D_VI 5 /* Vi - Video */
+#define PRIO_8021D_VO 6 /* Vo - Voice */
+#define PRIO_8021D_NC 7 /* NC - Network Control */
+#define MAXPRIO 7 /* 0-7 */
+#define NUMPRIO (MAXPRIO + 1)
+
+#define ALLPRIO -1 /* All prioirty */
+
+/* Converts prio to precedence since the numerical value of
+ * PRIO_8021D_BE and PRIO_8021D_NONE are swapped.
+ */
+#define PRIO2PREC(prio) \
+ (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? ((prio^2)) : (prio))
+
+#endif /* _802_1_D__ */
diff --git a/drivers/net/wireless/ap6210/include/proto/bcmeth.h b/drivers/net/wireless/ap6210/include/proto/bcmeth.h
new file mode 100644
index 0000000..91ae75c
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/bcmeth.h
@@ -0,0 +1,112 @@
+/*
+ * Broadcom Ethernettype protocol definitions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bcmeth.h 294352 2011-11-06 19:23:00Z $
+ */
+
+/*
+ * Broadcom Ethernet protocol defines
+ */
+
+#ifndef _BCMETH_H_
+#define _BCMETH_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+/* ETHER_TYPE_BRCM is defined in ethernet.h */
+
+/*
+ * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field
+ * in one of two formats: (only subtypes 32768-65535 are in use now)
+ *
+ * subtypes 0-32767:
+ * 8 bit subtype (0-127)
+ * 8 bit length in bytes (0-255)
+ *
+ * subtypes 32768-65535:
+ * 16 bit big-endian subtype
+ * 16 bit big-endian length in bytes (0-65535)
+ *
+ * length is the number of additional bytes beyond the 4 or 6 byte header
+ *
+ * Reserved values:
+ * 0 reserved
+ * 5-15 reserved for iLine protocol assignments
+ * 17-126 reserved, assignable
+ * 127 reserved
+ * 32768 reserved
+ * 32769-65534 reserved, assignable
+ * 65535 reserved
+ */
+
+/*
+ * While adding the subtypes and their specific processing code make sure
+ * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition
+ */
+
+#define BCMILCP_SUBTYPE_RATE 1
+#define BCMILCP_SUBTYPE_LINK 2
+#define BCMILCP_SUBTYPE_CSA 3
+#define BCMILCP_SUBTYPE_LARQ 4
+#define BCMILCP_SUBTYPE_VENDOR 5
+#define BCMILCP_SUBTYPE_FLH 17
+
+#define BCMILCP_SUBTYPE_VENDOR_LONG 32769
+#define BCMILCP_SUBTYPE_CERT 32770
+#define BCMILCP_SUBTYPE_SES 32771
+
+
+#define BCMILCP_BCM_SUBTYPE_RESERVED 0
+#define BCMILCP_BCM_SUBTYPE_EVENT 1
+#define BCMILCP_BCM_SUBTYPE_SES 2
+/*
+ * The EAPOL type is not used anymore. Instead EAPOL messages are now embedded
+ * within BCMILCP_BCM_SUBTYPE_EVENT type messages
+ */
+/* #define BCMILCP_BCM_SUBTYPE_EAPOL 3 */
+#define BCMILCP_BCM_SUBTYPE_DPT 4
+
+#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8
+#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0
+
+/* These fields are stored in network order */
+typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr
+{
+ uint16 subtype; /* Vendor specific..32769 */
+ uint16 length;
+ uint8 version; /* Version is 0 */
+ uint8 oui[3]; /* Broadcom OUI */
+ /* user specific Data */
+ uint16 usr_subtype;
+} BWL_POST_PACKED_STRUCT bcmeth_hdr_t;
+
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _BCMETH_H_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/bcmevent.h b/drivers/net/wireless/ap6210/include/proto/bcmevent.h
new file mode 100644
index 0000000..c439707
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/bcmevent.h
@@ -0,0 +1,368 @@
+/*
+ * Broadcom Event protocol definitions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * Dependencies: proto/bcmeth.h
+ *
+ * $Id: bcmevent.h 374275 2012-12-12 11:44:18Z $
+ *
+ */
+
+/*
+ * Broadcom Ethernet Events protocol defines
+ *
+ */
+
+#ifndef _BCMEVENT_H_
+#define _BCMEVENT_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+#define BCM_EVENT_MSG_VERSION 2 /* wl_event_msg_t struct version */
+#define BCM_MSG_IFNAME_MAX 16 /* max length of interface name */
+
+/* flags */
+#define WLC_EVENT_MSG_LINK 0x01 /* link is up */
+#define WLC_EVENT_MSG_FLUSHTXQ 0x02 /* flush tx queue on MIC error */
+#define WLC_EVENT_MSG_GROUP 0x04 /* group MIC error */
+#define WLC_EVENT_MSG_UNKBSS 0x08 /* unknown source bsscfg */
+#define WLC_EVENT_MSG_UNKIF 0x10 /* unknown source OS i/f */
+
+/* these fields are stored in network order */
+
+/* version 1 */
+typedef BWL_PRE_PACKED_STRUCT struct
+{
+ uint16 version;
+ uint16 flags; /* see flags below */
+ uint32 event_type; /* Message (see below) */
+ uint32 status; /* Status code (see below) */
+ uint32 reason; /* Reason code (if applicable) */
+ uint32 auth_type; /* WLC_E_AUTH */
+ uint32 datalen; /* data buf */
+ struct ether_addr addr; /* Station address (if applicable) */
+ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */
+} BWL_POST_PACKED_STRUCT wl_event_msg_v1_t;
+
+/* the current version */
+typedef BWL_PRE_PACKED_STRUCT struct
+{
+ uint16 version;
+ uint16 flags; /* see flags below */
+ uint32 event_type; /* Message (see below) */
+ uint32 status; /* Status code (see below) */
+ uint32 reason; /* Reason code (if applicable) */
+ uint32 auth_type; /* WLC_E_AUTH */
+ uint32 datalen; /* data buf */
+ struct ether_addr addr; /* Station address (if applicable) */
+ char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */
+ uint8 ifidx; /* destination OS i/f index */
+ uint8 bsscfgidx; /* source bsscfg index */
+} BWL_POST_PACKED_STRUCT wl_event_msg_t;
+
+/* used by driver msgs */
+typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
+ struct ether_header eth;
+ bcmeth_hdr_t bcm_hdr;
+ wl_event_msg_t event;
+ /* data portion follows */
+} BWL_POST_PACKED_STRUCT bcm_event_t;
+
+#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header))
+
+/* Event messages */
+#define WLC_E_SET_SSID 0 /* indicates status of set SSID */
+#define WLC_E_JOIN 1 /* differentiates join IBSS from found (WLC_E_START) IBSS */
+#define WLC_E_START 2 /* STA founded an IBSS or AP started a BSS */
+#define WLC_E_AUTH 3 /* 802.11 AUTH request */
+#define WLC_E_AUTH_IND 4 /* 802.11 AUTH indication */
+#define WLC_E_DEAUTH 5 /* 802.11 DEAUTH request */
+#define WLC_E_DEAUTH_IND 6 /* 802.11 DEAUTH indication */
+#define WLC_E_ASSOC 7 /* 802.11 ASSOC request */
+#define WLC_E_ASSOC_IND 8 /* 802.11 ASSOC indication */
+#define WLC_E_REASSOC 9 /* 802.11 REASSOC request */
+#define WLC_E_REASSOC_IND 10 /* 802.11 REASSOC indication */
+#define WLC_E_DISASSOC 11 /* 802.11 DISASSOC request */
+#define WLC_E_DISASSOC_IND 12 /* 802.11 DISASSOC indication */
+#define WLC_E_QUIET_START 13 /* 802.11h Quiet period started */
+#define WLC_E_QUIET_END 14 /* 802.11h Quiet period ended */
+#define WLC_E_BEACON_RX 15 /* BEACONS received/lost indication */
+#define WLC_E_LINK 16 /* generic link indication */
+#define WLC_E_MIC_ERROR 17 /* TKIP MIC error occurred */
+#define WLC_E_NDIS_LINK 18 /* NDIS style link indication */
+#define WLC_E_ROAM 19 /* roam attempt occurred: indicate status & reason */
+#define WLC_E_TXFAIL 20 /* change in dot11FailedCount (txfail) */
+#define WLC_E_PMKID_CACHE 21 /* WPA2 pmkid cache indication */
+#define WLC_E_RETROGRADE_TSF 22 /* current AP's TSF value went backward */
+#define WLC_E_PRUNE 23 /* AP was pruned from join list for reason */
+#define WLC_E_AUTOAUTH 24 /* report AutoAuth table entry match for join attempt */
+#define WLC_E_EAPOL_MSG 25 /* Event encapsulating an EAPOL message */
+#define WLC_E_SCAN_COMPLETE 26 /* Scan results are ready or scan was aborted */
+#define WLC_E_ADDTS_IND 27 /* indicate to host addts fail/success */
+#define WLC_E_DELTS_IND 28 /* indicate to host delts fail/success */
+#define WLC_E_BCNSENT_IND 29 /* indicate to host of beacon transmit */
+#define WLC_E_BCNRX_MSG 30 /* Send the received beacon up to the host */
+#define WLC_E_BCNLOST_MSG 31 /* indicate to host loss of beacon */
+#define WLC_E_ROAM_PREP 32 /* before attempting to roam */
+#define WLC_E_PFN_NET_FOUND 33 /* PFN network found event */
+#define WLC_E_PFN_NET_LOST 34 /* PFN network lost event */
+#define WLC_E_RESET_COMPLETE 35
+#define WLC_E_JOIN_START 36
+#define WLC_E_ROAM_START 37
+#define WLC_E_ASSOC_START 38
+#define WLC_E_IBSS_ASSOC 39
+#define WLC_E_RADIO 40
+#define WLC_E_PSM_WATCHDOG 41 /* PSM microcode watchdog fired */
+#define WLC_E_PROBREQ_MSG 44 /* probe request received */
+#define WLC_E_SCAN_CONFIRM_IND 45
+#define WLC_E_PSK_SUP 46 /* WPA Handshake fail */
+#define WLC_E_COUNTRY_CODE_CHANGED 47
+#define WLC_E_EXCEEDED_MEDIUM_TIME 48 /* WMMAC excedded medium time */
+#define WLC_E_ICV_ERROR 49 /* WEP ICV error occurred */
+#define WLC_E_UNICAST_DECODE_ERROR 50 /* Unsupported unicast encrypted frame */
+#define WLC_E_MULTICAST_DECODE_ERROR 51 /* Unsupported multicast encrypted frame */
+#define WLC_E_TRACE 52
+#ifdef WLBTAMP
+#define WLC_E_BTA_HCI_EVENT 53 /* BT-AMP HCI event */
+#endif
+#define WLC_E_IF 54 /* I/F change (for dongle host notification) */
+#define WLC_E_P2P_DISC_LISTEN_COMPLETE 55 /* listen state expires */
+#define WLC_E_RSSI 56 /* indicate RSSI change based on configured levels */
+#define WLC_E_PFN_SCAN_COMPLETE 57 /* PFN completed scan of network list */
+#define WLC_E_EXTLOG_MSG 58
+#define WLC_E_ACTION_FRAME 59 /* Action frame Rx */
+#define WLC_E_ACTION_FRAME_COMPLETE 60 /* Action frame Tx complete */
+#define WLC_E_PRE_ASSOC_IND 61 /* assoc request received */
+#define WLC_E_PRE_REASSOC_IND 62 /* re-assoc request received */
+#define WLC_E_CHANNEL_ADOPTED 63
+#define WLC_E_AP_STARTED 64 /* AP started */
+#define WLC_E_DFS_AP_STOP 65 /* AP stopped due to DFS */
+#define WLC_E_DFS_AP_RESUME 66 /* AP resumed due to DFS */
+#define WLC_E_WAI_STA_EVENT 67 /* WAI stations event */
+#define WLC_E_WAI_MSG 68 /* event encapsulating an WAI message */
+#define WLC_E_ESCAN_RESULT 69 /* escan result event */
+#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 /* action frame off channel complete */
+#define WLC_E_PROBRESP_MSG 71 /* probe response received */
+#define WLC_E_P2P_PROBREQ_MSG 72 /* P2P Probe request received */
+#define WLC_E_DCS_REQUEST 73
+
+#define WLC_E_FIFO_CREDIT_MAP 74 /* credits for D11 FIFOs. [AC0,AC1,AC2,AC3,BC_MC,ATIM] */
+
+#define WLC_E_ACTION_FRAME_RX 75 /* Received action frame event WITH
+ * wl_event_rx_frame_data_t header
+ */
+#define WLC_E_WAKE_EVENT 76 /* Wake Event timer fired, used for wake WLAN test mode */
+#define WLC_E_RM_COMPLETE 77 /* Radio measurement complete */
+#define WLC_E_HTSFSYNC 78 /* Synchronize TSF with the host */
+#define WLC_E_OVERLAY_REQ 79 /* request an overlay IOCTL/iovar from the host */
+#define WLC_E_CSA_COMPLETE_IND 80 /* 802.11 CHANNEL SWITCH ACTION completed */
+#define WLC_E_EXCESS_PM_WAKE_EVENT 81 /* excess PM Wake Event to inform host */
+#define WLC_E_PFN_SCAN_NONE 82 /* no PFN networks around */
+#define WLC_E_PFN_SCAN_ALLGONE 83 /* last found PFN network gets lost */
+#define WLC_E_GTK_PLUMBED 84
+#define WLC_E_ASSOC_IND_NDIS 85 /* 802.11 ASSOC indication for NDIS only */
+#define WLC_E_REASSOC_IND_NDIS 86 /* 802.11 REASSOC indication for NDIS only */
+#define WLC_E_ASSOC_REQ_IE 87
+#define WLC_E_ASSOC_RESP_IE 88
+#define WLC_E_ASSOC_RECREATED 89 /* association recreated on resume */
+#define WLC_E_ACTION_FRAME_RX_NDIS 90 /* rx action frame event for NDIS only */
+#define WLC_E_AUTH_REQ 91 /* authentication request received */
+#define WLC_E_TDLS_PEER_EVENT 92 /* discovered peer, connected or disconnected peer */
+#define WLC_E_SPEEDY_RECREATE_FAIL 93 /* fast assoc recreation failed */
+#define WLC_E_SERVICE_FOUND 102 /* desired service found */
+#define WLC_E_GAS_FRAGMENT_RX 103 /* GAS fragment received */
+#define WLC_E_GAS_COMPLETE 104 /* GAS sessions all complete */
+#define WLC_E_P2PO_ADD_DEVICE 105 /* New device found by p2p offload */
+#define WLC_E_P2PO_DEL_DEVICE 106 /* device has been removed by p2p offload */
+#define WLC_E_LAST 107 /* highest val + 1 for range checking */
+
+
+/* Table of event name strings for UIs and debugging dumps */
+typedef struct {
+ uint event;
+ const char *name;
+} bcmevent_name_t;
+
+extern const bcmevent_name_t bcmevent_names[];
+extern const int bcmevent_names_size;
+
+/* Event status codes */
+#define WLC_E_STATUS_SUCCESS 0 /* operation was successful */
+#define WLC_E_STATUS_FAIL 1 /* operation failed */
+#define WLC_E_STATUS_TIMEOUT 2 /* operation timed out */
+#define WLC_E_STATUS_NO_NETWORKS 3 /* failed due to no matching network found */
+#define WLC_E_STATUS_ABORT 4 /* operation was aborted */
+#define WLC_E_STATUS_NO_ACK 5 /* protocol failure: packet not ack'd */
+#define WLC_E_STATUS_UNSOLICITED 6 /* AUTH or ASSOC packet was unsolicited */
+#define WLC_E_STATUS_ATTEMPT 7 /* attempt to assoc to an auto auth configuration */
+#define WLC_E_STATUS_PARTIAL 8 /* scan results are incomplete */
+#define WLC_E_STATUS_NEWSCAN 9 /* scan aborted by another scan */
+#define WLC_E_STATUS_NEWASSOC 10 /* scan aborted due to assoc in progress */
+#define WLC_E_STATUS_11HQUIET 11 /* 802.11h quiet period started */
+#define WLC_E_STATUS_SUPPRESS 12 /* user disabled scanning (WLC_SET_SCANSUPPRESS) */
+#define WLC_E_STATUS_NOCHANS 13 /* no allowable channels to scan */
+#define WLC_E_STATUS_CS_ABORT 15 /* abort channel select */
+#define WLC_E_STATUS_ERROR 16 /* request failed due to error */
+
+/* roam reason codes */
+#define WLC_E_REASON_INITIAL_ASSOC 0 /* initial assoc */
+#define WLC_E_REASON_LOW_RSSI 1 /* roamed due to low RSSI */
+#define WLC_E_REASON_DEAUTH 2 /* roamed due to DEAUTH indication */
+#define WLC_E_REASON_DISASSOC 3 /* roamed due to DISASSOC indication */
+#define WLC_E_REASON_BCNS_LOST 4 /* roamed due to lost beacons */
+#define WLC_E_REASON_MINTXRATE 9 /* roamed because at mintxrate for too long */
+#define WLC_E_REASON_TXFAIL 10 /* We can hear AP, but AP can't hear us */
+
+/* Roam codes used primarily by CCX */
+#define WLC_E_REASON_FAST_ROAM_FAILED 5 /* roamed due to fast roam failure */
+#define WLC_E_REASON_DIRECTED_ROAM 6 /* roamed due to request by AP */
+#define WLC_E_REASON_TSPEC_REJECTED 7 /* roamed due to TSPEC rejection */
+#define WLC_E_REASON_BETTER_AP 8 /* roamed due to finding better AP */
+
+
+#define WLC_E_REASON_REQUESTED_ROAM 11 /* roamed due to BSS Mgmt Transition request by AP */
+
+/* prune reason codes */
+#define WLC_E_PRUNE_ENCR_MISMATCH 1 /* encryption mismatch */
+#define WLC_E_PRUNE_BCAST_BSSID 2 /* AP uses a broadcast BSSID */
+#define WLC_E_PRUNE_MAC_DENY 3 /* STA's MAC addr is in AP's MAC deny list */
+#define WLC_E_PRUNE_MAC_NA 4 /* STA's MAC addr is not in AP's MAC allow list */
+#define WLC_E_PRUNE_REG_PASSV 5 /* AP not allowed due to regulatory restriction */
+#define WLC_E_PRUNE_SPCT_MGMT 6 /* AP does not support STA locale spectrum mgmt */
+#define WLC_E_PRUNE_RADAR 7 /* AP is on a radar channel of STA locale */
+#define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */
+#define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */
+#define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */
+#define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */
+#define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */
+#define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */
+#define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */
+#define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */
+
+/* WPA failure reason codes carried in the WLC_E_PSK_SUP event */
+#define WLC_E_SUP_OTHER 0 /* Other reason */
+#define WLC_E_SUP_DECRYPT_KEY_DATA 1 /* Decryption of key data failed */
+#define WLC_E_SUP_BAD_UCAST_WEP128 2 /* Illegal use of ucast WEP128 */
+#define WLC_E_SUP_BAD_UCAST_WEP40 3 /* Illegal use of ucast WEP40 */
+#define WLC_E_SUP_UNSUP_KEY_LEN 4 /* Unsupported key length */
+#define WLC_E_SUP_PW_KEY_CIPHER 5 /* Unicast cipher mismatch in pairwise key */
+#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 /* WPA IE contains > 1 RSN IE in key msg 3 */
+#define WLC_E_SUP_MSG3_IE_MISMATCH 7 /* WPA IE mismatch in key message 3 */
+#define WLC_E_SUP_NO_INSTALL_FLAG 8 /* INSTALL flag unset in 4-way msg */
+#define WLC_E_SUP_MSG3_NO_GTK 9 /* encapsulated GTK missing from msg 3 */
+#define WLC_E_SUP_GRP_KEY_CIPHER 10 /* Multicast cipher mismatch in group key */
+#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 /* encapsulated GTK missing from group msg 1 */
+#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 /* GTK decrypt failure */
+#define WLC_E_SUP_SEND_FAIL 13 /* message send failure */
+#define WLC_E_SUP_DEAUTH 14 /* received FC_DEAUTH */
+#define WLC_E_SUP_WPA_PSK_TMO 15 /* WPA PSK 4-way handshake timeout */
+
+/* Event data for events that include frames received over the air */
+/* WLC_E_PROBRESP_MSG
+ * WLC_E_P2P_PROBREQ_MSG
+ * WLC_E_ACTION_FRAME_RX
+ */
+typedef BWL_PRE_PACKED_STRUCT struct wl_event_rx_frame_data {
+ uint16 version;
+ uint16 channel; /* Matches chanspec_t format from bcmwifi_channels.h */
+ int32 rssi;
+ uint32 mactime;
+ uint32 rate;
+} BWL_POST_PACKED_STRUCT wl_event_rx_frame_data_t;
+
+#define BCM_RX_FRAME_DATA_VERSION 1
+
+/* WLC_E_IF event data */
+typedef struct wl_event_data_if {
+ uint8 ifidx; /* RTE virtual device index (for dongle) */
+ uint8 opcode; /* see I/F opcode */
+ uint8 reserved;
+ uint8 bssidx; /* bsscfg index */
+ uint8 role; /* see I/F role */
+} wl_event_data_if_t;
+
+/* opcode in WLC_E_IF event */
+#define WLC_E_IF_ADD 1 /* bsscfg add */
+#define WLC_E_IF_DEL 2 /* bsscfg delete */
+#define WLC_E_IF_CHANGE 3 /* bsscfg role change */
+
+/* I/F role code in WLC_E_IF event */
+#define WLC_E_IF_ROLE_STA 0 /* Infra STA */
+#define WLC_E_IF_ROLE_AP 1 /* Access Point */
+#define WLC_E_IF_ROLE_WDS 2 /* WDS link */
+#define WLC_E_IF_ROLE_P2P_GO 3 /* P2P Group Owner */
+#define WLC_E_IF_ROLE_P2P_CLIENT 4 /* P2P Client */
+#ifdef WLBTAMP
+#define WLC_E_IF_ROLE_BTA_CREATOR 5 /* BT-AMP Creator */
+#define WLC_E_IF_ROLE_BTA_ACCEPTOR 6 /* BT-AMP Acceptor */
+#endif
+
+/* Reason codes for LINK */
+#define WLC_E_LINK_BCN_LOSS 1 /* Link down because of beacon loss */
+#define WLC_E_LINK_DISASSOC 2 /* Link down because of disassoc */
+#define WLC_E_LINK_ASSOC_REC 3 /* Link down because assoc recreate failed */
+#define WLC_E_LINK_BSSCFG_DIS 4 /* Link down due to bsscfg down */
+
+/* reason codes for WLC_E_OVERLAY_REQ event */
+#define WLC_E_OVL_DOWNLOAD 0 /* overlay download request */
+#define WLC_E_OVL_UPDATE_IND 1 /* device indication of host overlay update */
+
+/* reason codes for WLC_E_TDLS_PEER_EVENT event */
+#define WLC_E_TDLS_PEER_DISCOVERED 0 /* peer is ready to establish TDLS */
+#define WLC_E_TDLS_PEER_CONNECTED 1
+#define WLC_E_TDLS_PEER_DISCONNECTED 2
+
+/* GAS event data */
+typedef BWL_PRE_PACKED_STRUCT struct wl_event_gas {
+ uint16 channel; /* channel of GAS protocol */
+ uint8 dialog_token; /* GAS dialog token */
+ uint8 fragment_id; /* fragment id */
+ uint16 status_code; /* status code on GAS completion */
+ uint16 data_len; /* length of data to follow */
+ uint8 data[1]; /* variable length specified by data_len */
+} BWL_POST_PACKED_STRUCT wl_event_gas_t;
+
+/* service discovery TLV */
+typedef BWL_PRE_PACKED_STRUCT struct wl_sd_tlv {
+ uint16 length; /* length of response_data */
+ uint8 protocol; /* service protocol type */
+ uint8 transaction_id; /* service transaction id */
+ uint8 status_code; /* status code */
+ uint8 data[1]; /* response data */
+} BWL_POST_PACKED_STRUCT wl_sd_tlv_t;
+
+/* service discovery event data */
+typedef BWL_PRE_PACKED_STRUCT struct wl_event_sd {
+ uint16 channel; /* channel */
+ uint8 count; /* number of tlvs */
+ wl_sd_tlv_t tlv[1]; /* service discovery TLV */
+} BWL_POST_PACKED_STRUCT wl_event_sd_t;
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _BCMEVENT_H_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/bcmip.h b/drivers/net/wireless/ap6210/include/proto/bcmip.h
new file mode 100644
index 0000000..52cd71d
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/bcmip.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * Fundamental constants relating to IP Protocol
+ *
+ * $Id: bcmip.h 290206 2011-10-17 19:13:51Z $
+ */
+
+#ifndef _bcmip_h_
+#define _bcmip_h_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+
+/* IPV4 and IPV6 common */
+#define IP_VER_OFFSET 0x0 /* offset to version field */
+#define IP_VER_MASK 0xf0 /* version mask */
+#define IP_VER_SHIFT 4 /* version shift */
+#define IP_VER_4 4 /* version number for IPV4 */
+#define IP_VER_6 6 /* version number for IPV6 */
+
+#define IP_VER(ip_body) \
+ ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT)
+
+#define IP_PROT_ICMP 0x1 /* ICMP protocol */
+#define IP_PROT_IGMP 0x2 /* IGMP protocol */
+#define IP_PROT_TCP 0x6 /* TCP protocol */
+#define IP_PROT_UDP 0x11 /* UDP protocol type */
+#define IP_PROT_ICMP6 0x3a /* ICMPv6 protocol type */
+
+/* IPV4 field offsets */
+#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */
+#define IPV4_TOS_OFFSET 1 /* type of service offset */
+#define IPV4_PKTLEN_OFFSET 2 /* packet length offset */
+#define IPV4_PKTFLAG_OFFSET 6 /* more-frag,dont-frag flag offset */
+#define IPV4_PROT_OFFSET 9 /* protocol type offset */
+#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */
+#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */
+#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */
+#define IPV4_OPTIONS_OFFSET 20 /* IP options offset */
+
+/* IPV4 field decodes */
+#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */
+#define IPV4_VER_SHIFT 4 /* IPV4 version shift */
+
+#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */
+#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK))
+
+#define IPV4_ADDR_LEN 4 /* IPV4 address length */
+
+#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \
+ ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0)
+
+#define IPV4_ADDR_BCAST(a) ((((uint8 *)(a))[0] & ((uint8 *)(a))[1] & \
+ ((uint8 *)(a))[2] & ((uint8 *)(a))[3]) == 0xff)
+
+#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */
+#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */
+
+#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET])
+
+#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */
+#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */
+
+#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */
+#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */
+#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */
+
+#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET])
+
+#define IPV4_FRAG_RESV 0x8000 /* Reserved */
+#define IPV4_FRAG_DONT 0x4000 /* Don't fragment */
+#define IPV4_FRAG_MORE 0x2000 /* More fragments */
+#define IPV4_FRAG_OFFSET_MASK 0x1fff /* Fragment offset */
+
+#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */
+
+/* IPV4 packet formats */
+BWL_PRE_PACKED_STRUCT struct ipv4_addr {
+ uint8 addr[IPV4_ADDR_LEN];
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct ipv4_hdr {
+ uint8 version_ihl; /* Version and Internet Header Length */
+ uint8 tos; /* Type Of Service */
+ uint16 tot_len; /* Number of bytes in packet (max 65535) */
+ uint16 id;
+ uint16 frag; /* 3 flag bits and fragment offset */
+ uint8 ttl; /* Time To Live */
+ uint8 prot; /* Protocol */
+ uint16 hdr_chksum; /* IP header checksum */
+ uint8 src_ip[IPV4_ADDR_LEN]; /* Source IP Address */
+ uint8 dst_ip[IPV4_ADDR_LEN]; /* Destination IP Address */
+} BWL_POST_PACKED_STRUCT;
+
+/* IPV6 field offsets */
+#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */
+#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */
+#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */
+#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */
+#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */
+
+/* IPV6 field decodes */
+#define IPV6_TRAFFIC_CLASS(ipv6_body) \
+ (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \
+ ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4))
+
+#define IPV6_FLOW_LABEL(ipv6_body) \
+ (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \
+ (((uint8 *)(ipv6_body))[2] << 8) | \
+ (((uint8 *)(ipv6_body))[3]))
+
+#define IPV6_PAYLOAD_LEN(ipv6_body) \
+ ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \
+ ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1])
+
+#define IPV6_NEXT_HDR(ipv6_body) \
+ (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET])
+
+#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body)
+
+#define IPV6_ADDR_LEN 16 /* IPV6 address length */
+
+/* IPV4 TOS or IPV6 Traffic Classifier or 0 */
+#define IP_TOS46(ip_body) \
+ (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \
+ IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0)
+
+/* IPV6 extension headers (options) */
+#define IPV6_EXTHDR_HOP 0
+#define IPV6_EXTHDR_ROUTING 43
+#define IPV6_EXTHDR_FRAGMENT 44
+#define IPV6_EXTHDR_AUTH 51
+#define IPV6_EXTHDR_NONE 59
+#define IPV6_EXTHDR_DEST 60
+
+#define IPV6_EXTHDR(prot) (((prot) == IPV6_EXTHDR_HOP) || \
+ ((prot) == IPV6_EXTHDR_ROUTING) || \
+ ((prot) == IPV6_EXTHDR_FRAGMENT) || \
+ ((prot) == IPV6_EXTHDR_AUTH) || \
+ ((prot) == IPV6_EXTHDR_NONE) || \
+ ((prot) == IPV6_EXTHDR_DEST))
+
+#define IPV6_MIN_HLEN 40
+
+#define IPV6_EXTHDR_LEN(eh) ((((struct ipv6_exthdr *)(eh))->hdrlen + 1) << 3)
+
+BWL_PRE_PACKED_STRUCT struct ipv6_exthdr {
+ uint8 nexthdr;
+ uint8 hdrlen;
+} BWL_POST_PACKED_STRUCT;
+
+BWL_PRE_PACKED_STRUCT struct ipv6_exthdr_frag {
+ uint8 nexthdr;
+ uint8 rsvd;
+ uint16 frag_off;
+ uint32 ident;
+} BWL_POST_PACKED_STRUCT;
+
+static INLINE int32
+ipv6_exthdr_len(uint8 *h, uint8 *proto)
+{
+ uint16 len = 0, hlen;
+ struct ipv6_exthdr *eh = (struct ipv6_exthdr *)h;
+
+ while (IPV6_EXTHDR(eh->nexthdr)) {
+ if (eh->nexthdr == IPV6_EXTHDR_NONE)
+ return -1;
+ else if (eh->nexthdr == IPV6_EXTHDR_FRAGMENT)
+ hlen = 8;
+ else if (eh->nexthdr == IPV6_EXTHDR_AUTH)
+ hlen = (eh->hdrlen + 2) << 2;
+ else
+ hlen = IPV6_EXTHDR_LEN(eh);
+
+ len += hlen;
+ eh = (struct ipv6_exthdr *)(h + len);
+ }
+
+ *proto = eh->nexthdr;
+ return len;
+}
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _bcmip_h_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/bt_amp_hci.h b/drivers/net/wireless/ap6210/include/proto/bt_amp_hci.h
new file mode 100644
index 0000000..8617985
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/bt_amp_hci.h
@@ -0,0 +1,441 @@
+/*
+ * BT-AMP (BlueTooth Alternate Mac and Phy) HCI (Host/Controller Interface)
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: bt_amp_hci.h 294267 2011-11-04 23:41:52Z $
+*/
+
+#ifndef _bt_amp_hci_h
+#define _bt_amp_hci_h
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+
+/* AMP HCI CMD packet format */
+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_cmd {
+ uint16 opcode;
+ uint8 plen;
+ uint8 parms[1];
+} BWL_POST_PACKED_STRUCT amp_hci_cmd_t;
+
+#define HCI_CMD_PREAMBLE_SIZE OFFSETOF(amp_hci_cmd_t, parms)
+#define HCI_CMD_DATA_SIZE 255
+
+/* AMP HCI CMD opcode layout */
+#define HCI_CMD_OPCODE(ogf, ocf) ((((ogf) & 0x3F) << 10) | ((ocf) & 0x03FF))
+#define HCI_CMD_OGF(opcode) ((uint8)(((opcode) >> 10) & 0x3F))
+#define HCI_CMD_OCF(opcode) ((opcode) & 0x03FF)
+
+/* AMP HCI command opcodes */
+#define HCI_Read_Failed_Contact_Counter HCI_CMD_OPCODE(0x05, 0x0001)
+#define HCI_Reset_Failed_Contact_Counter HCI_CMD_OPCODE(0x05, 0x0002)
+#define HCI_Read_Link_Quality HCI_CMD_OPCODE(0x05, 0x0003)
+#define HCI_Read_Local_AMP_Info HCI_CMD_OPCODE(0x05, 0x0009)
+#define HCI_Read_Local_AMP_ASSOC HCI_CMD_OPCODE(0x05, 0x000A)
+#define HCI_Write_Remote_AMP_ASSOC HCI_CMD_OPCODE(0x05, 0x000B)
+#define HCI_Create_Physical_Link HCI_CMD_OPCODE(0x01, 0x0035)
+#define HCI_Accept_Physical_Link_Request HCI_CMD_OPCODE(0x01, 0x0036)
+#define HCI_Disconnect_Physical_Link HCI_CMD_OPCODE(0x01, 0x0037)
+#define HCI_Create_Logical_Link HCI_CMD_OPCODE(0x01, 0x0038)
+#define HCI_Accept_Logical_Link HCI_CMD_OPCODE(0x01, 0x0039)
+#define HCI_Disconnect_Logical_Link HCI_CMD_OPCODE(0x01, 0x003A)
+#define HCI_Logical_Link_Cancel HCI_CMD_OPCODE(0x01, 0x003B)
+#define HCI_Flow_Spec_Modify HCI_CMD_OPCODE(0x01, 0x003C)
+#define HCI_Write_Flow_Control_Mode HCI_CMD_OPCODE(0x01, 0x0067)
+#define HCI_Read_Best_Effort_Flush_Timeout HCI_CMD_OPCODE(0x01, 0x0069)
+#define HCI_Write_Best_Effort_Flush_Timeout HCI_CMD_OPCODE(0x01, 0x006A)
+#define HCI_Short_Range_Mode HCI_CMD_OPCODE(0x01, 0x006B)
+#define HCI_Reset HCI_CMD_OPCODE(0x03, 0x0003)
+#define HCI_Read_Connection_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0015)
+#define HCI_Write_Connection_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0016)
+#define HCI_Read_Link_Supervision_Timeout HCI_CMD_OPCODE(0x03, 0x0036)
+#define HCI_Write_Link_Supervision_Timeout HCI_CMD_OPCODE(0x03, 0x0037)
+#define HCI_Enhanced_Flush HCI_CMD_OPCODE(0x03, 0x005F)
+#define HCI_Read_Logical_Link_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0061)
+#define HCI_Write_Logical_Link_Accept_Timeout HCI_CMD_OPCODE(0x03, 0x0062)
+#define HCI_Set_Event_Mask_Page_2 HCI_CMD_OPCODE(0x03, 0x0063)
+#define HCI_Read_Location_Data_Command HCI_CMD_OPCODE(0x03, 0x0064)
+#define HCI_Write_Location_Data_Command HCI_CMD_OPCODE(0x03, 0x0065)
+#define HCI_Read_Local_Version_Info HCI_CMD_OPCODE(0x04, 0x0001)
+#define HCI_Read_Local_Supported_Commands HCI_CMD_OPCODE(0x04, 0x0002)
+#define HCI_Read_Buffer_Size HCI_CMD_OPCODE(0x04, 0x0005)
+#define HCI_Read_Data_Block_Size HCI_CMD_OPCODE(0x04, 0x000A)
+
+/* AMP HCI command parameters */
+typedef BWL_PRE_PACKED_STRUCT struct read_local_cmd_parms {
+ uint8 plh;
+ uint8 offset[2]; /* length so far */
+ uint8 max_remote[2];
+} BWL_POST_PACKED_STRUCT read_local_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct write_remote_cmd_parms {
+ uint8 plh;
+ uint8 offset[2];
+ uint8 len[2];
+ uint8 frag[1];
+} BWL_POST_PACKED_STRUCT write_remote_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct phy_link_cmd_parms {
+ uint8 plh;
+ uint8 key_length;
+ uint8 key_type;
+ uint8 key[1];
+} BWL_POST_PACKED_STRUCT phy_link_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct dis_phy_link_cmd_parms {
+ uint8 plh;
+ uint8 reason;
+} BWL_POST_PACKED_STRUCT dis_phy_link_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct log_link_cmd_parms {
+ uint8 plh;
+ uint8 txflow[16];
+ uint8 rxflow[16];
+} BWL_POST_PACKED_STRUCT log_link_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct ext_flow_spec {
+ uint8 id;
+ uint8 service_type;
+ uint8 max_sdu[2];
+ uint8 sdu_ia_time[4];
+ uint8 access_latency[4];
+ uint8 flush_timeout[4];
+} BWL_POST_PACKED_STRUCT ext_flow_spec_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct log_link_cancel_cmd_parms {
+ uint8 plh;
+ uint8 tx_fs_ID;
+} BWL_POST_PACKED_STRUCT log_link_cancel_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct flow_spec_mod_cmd_parms {
+ uint8 llh[2];
+ uint8 txflow[16];
+ uint8 rxflow[16];
+} BWL_POST_PACKED_STRUCT flow_spec_mod_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct plh_pad {
+ uint8 plh;
+ uint8 pad;
+} BWL_POST_PACKED_STRUCT plh_pad_t;
+
+typedef BWL_PRE_PACKED_STRUCT union hci_handle {
+ uint16 bredr;
+ plh_pad_t amp;
+} BWL_POST_PACKED_STRUCT hci_handle_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct ls_to_cmd_parms {
+ hci_handle_t handle;
+ uint8 timeout[2];
+} BWL_POST_PACKED_STRUCT ls_to_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct befto_cmd_parms {
+ uint8 llh[2];
+ uint8 befto[4];
+} BWL_POST_PACKED_STRUCT befto_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct srm_cmd_parms {
+ uint8 plh;
+ uint8 srm;
+} BWL_POST_PACKED_STRUCT srm_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct ld_cmd_parms {
+ uint8 ld_aware;
+ uint8 ld[2];
+ uint8 ld_opts;
+ uint8 l_opts;
+} BWL_POST_PACKED_STRUCT ld_cmd_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct eflush_cmd_parms {
+ uint8 llh[2];
+ uint8 packet_type;
+} BWL_POST_PACKED_STRUCT eflush_cmd_parms_t;
+
+/* Generic AMP extended flow spec service types */
+#define EFS_SVCTYPE_NO_TRAFFIC 0
+#define EFS_SVCTYPE_BEST_EFFORT 1
+#define EFS_SVCTYPE_GUARANTEED 2
+
+/* AMP HCI event packet format */
+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_event {
+ uint8 ecode;
+ uint8 plen;
+ uint8 parms[1];
+} BWL_POST_PACKED_STRUCT amp_hci_event_t;
+
+#define HCI_EVT_PREAMBLE_SIZE OFFSETOF(amp_hci_event_t, parms)
+
+/* AMP HCI event codes */
+#define HCI_Command_Complete 0x0E
+#define HCI_Command_Status 0x0F
+#define HCI_Flush_Occurred 0x11
+#define HCI_Enhanced_Flush_Complete 0x39
+#define HCI_Physical_Link_Complete 0x40
+#define HCI_Channel_Select 0x41
+#define HCI_Disconnect_Physical_Link_Complete 0x42
+#define HCI_Logical_Link_Complete 0x45
+#define HCI_Disconnect_Logical_Link_Complete 0x46
+#define HCI_Flow_Spec_Modify_Complete 0x47
+#define HCI_Number_of_Completed_Data_Blocks 0x48
+#define HCI_Short_Range_Mode_Change_Complete 0x4C
+#define HCI_Status_Change_Event 0x4D
+#define HCI_Vendor_Specific 0xFF
+
+/* AMP HCI event mask bit positions */
+#define HCI_Physical_Link_Complete_Event_Mask 0x0001
+#define HCI_Channel_Select_Event_Mask 0x0002
+#define HCI_Disconnect_Physical_Link_Complete_Event_Mask 0x0004
+#define HCI_Logical_Link_Complete_Event_Mask 0x0020
+#define HCI_Disconnect_Logical_Link_Complete_Event_Mask 0x0040
+#define HCI_Flow_Spec_Modify_Complete_Event_Mask 0x0080
+#define HCI_Number_of_Completed_Data_Blocks_Event_Mask 0x0100
+#define HCI_Short_Range_Mode_Change_Complete_Event_Mask 0x1000
+#define HCI_Status_Change_Event_Mask 0x2000
+#define HCI_All_Event_Mask 0x31e7
+/* AMP HCI event parameters */
+typedef BWL_PRE_PACKED_STRUCT struct cmd_status_parms {
+ uint8 status;
+ uint8 cmdpkts;
+ uint16 opcode;
+} BWL_POST_PACKED_STRUCT cmd_status_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct cmd_complete_parms {
+ uint8 cmdpkts;
+ uint16 opcode;
+ uint8 parms[1];
+} BWL_POST_PACKED_STRUCT cmd_complete_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct flush_occurred_evt_parms {
+ uint16 handle;
+} BWL_POST_PACKED_STRUCT flush_occurred_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct write_remote_evt_parms {
+ uint8 status;
+ uint8 plh;
+} BWL_POST_PACKED_STRUCT write_remote_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct read_local_evt_parms {
+ uint8 status;
+ uint8 plh;
+ uint16 len;
+ uint8 frag[1];
+} BWL_POST_PACKED_STRUCT read_local_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct read_local_info_evt_parms {
+ uint8 status;
+ uint8 AMP_status;
+ uint32 bandwidth;
+ uint32 gbandwidth;
+ uint32 latency;
+ uint32 PDU_size;
+ uint8 ctrl_type;
+ uint16 PAL_cap;
+ uint16 AMP_ASSOC_len;
+ uint32 max_flush_timeout;
+ uint32 be_flush_timeout;
+} BWL_POST_PACKED_STRUCT read_local_info_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct log_link_evt_parms {
+ uint8 status;
+ uint16 llh;
+ uint8 plh;
+ uint8 tx_fs_ID;
+} BWL_POST_PACKED_STRUCT log_link_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct disc_log_link_evt_parms {
+ uint8 status;
+ uint16 llh;
+ uint8 reason;
+} BWL_POST_PACKED_STRUCT disc_log_link_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct log_link_cancel_evt_parms {
+ uint8 status;
+ uint8 plh;
+ uint8 tx_fs_ID;
+} BWL_POST_PACKED_STRUCT log_link_cancel_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct flow_spec_mod_evt_parms {
+ uint8 status;
+ uint16 llh;
+} BWL_POST_PACKED_STRUCT flow_spec_mod_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct phy_link_evt_parms {
+ uint8 status;
+ uint8 plh;
+} BWL_POST_PACKED_STRUCT phy_link_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct dis_phy_link_evt_parms {
+ uint8 status;
+ uint8 plh;
+ uint8 reason;
+} BWL_POST_PACKED_STRUCT dis_phy_link_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct read_ls_to_evt_parms {
+ uint8 status;
+ hci_handle_t handle;
+ uint16 timeout;
+} BWL_POST_PACKED_STRUCT read_ls_to_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct read_lla_ca_to_evt_parms {
+ uint8 status;
+ uint16 timeout;
+} BWL_POST_PACKED_STRUCT read_lla_ca_to_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct read_data_block_size_evt_parms {
+ uint8 status;
+ uint16 ACL_pkt_len;
+ uint16 data_block_len;
+ uint16 data_block_num;
+} BWL_POST_PACKED_STRUCT read_data_block_size_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct data_blocks {
+ uint16 handle;
+ uint16 pkts;
+ uint16 blocks;
+} BWL_POST_PACKED_STRUCT data_blocks_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct num_completed_data_blocks_evt_parms {
+ uint16 num_blocks;
+ uint8 num_handles;
+ data_blocks_t completed[1];
+} BWL_POST_PACKED_STRUCT num_completed_data_blocks_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct befto_evt_parms {
+ uint8 status;
+ uint32 befto;
+} BWL_POST_PACKED_STRUCT befto_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct srm_evt_parms {
+ uint8 status;
+ uint8 plh;
+ uint8 srm;
+} BWL_POST_PACKED_STRUCT srm_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct contact_counter_evt_parms {
+ uint8 status;
+ uint8 llh[2];
+ uint16 counter;
+} BWL_POST_PACKED_STRUCT contact_counter_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct contact_counter_reset_evt_parms {
+ uint8 status;
+ uint8 llh[2];
+} BWL_POST_PACKED_STRUCT contact_counter_reset_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct read_linkq_evt_parms {
+ uint8 status;
+ hci_handle_t handle;
+ uint8 link_quality;
+} BWL_POST_PACKED_STRUCT read_linkq_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct ld_evt_parms {
+ uint8 status;
+ uint8 ld_aware;
+ uint8 ld[2];
+ uint8 ld_opts;
+ uint8 l_opts;
+} BWL_POST_PACKED_STRUCT ld_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct eflush_complete_evt_parms {
+ uint16 handle;
+} BWL_POST_PACKED_STRUCT eflush_complete_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct vendor_specific_evt_parms {
+ uint8 len;
+ uint8 parms[1];
+} BWL_POST_PACKED_STRUCT vendor_specific_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct local_version_info_evt_parms {
+ uint8 status;
+ uint8 hci_version;
+ uint16 hci_revision;
+ uint8 pal_version;
+ uint16 mfg_name;
+ uint16 pal_subversion;
+} BWL_POST_PACKED_STRUCT local_version_info_evt_parms_t;
+
+#define MAX_SUPPORTED_CMD_BYTE 64
+typedef BWL_PRE_PACKED_STRUCT struct local_supported_cmd_evt_parms {
+ uint8 status;
+ uint8 cmd[MAX_SUPPORTED_CMD_BYTE];
+} BWL_POST_PACKED_STRUCT local_supported_cmd_evt_parms_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct status_change_evt_parms {
+ uint8 status;
+ uint8 amp_status;
+} BWL_POST_PACKED_STRUCT status_change_evt_parms_t;
+
+/* AMP HCI error codes */
+#define HCI_SUCCESS 0x00
+#define HCI_ERR_ILLEGAL_COMMAND 0x01
+#define HCI_ERR_NO_CONNECTION 0x02
+#define HCI_ERR_MEMORY_FULL 0x07
+#define HCI_ERR_CONNECTION_TIMEOUT 0x08
+#define HCI_ERR_MAX_NUM_OF_CONNECTIONS 0x09
+#define HCI_ERR_CONNECTION_EXISTS 0x0B
+#define HCI_ERR_CONNECTION_DISALLOWED 0x0C
+#define HCI_ERR_CONNECTION_ACCEPT_TIMEOUT 0x10
+#define HCI_ERR_UNSUPPORTED_VALUE 0x11
+#define HCI_ERR_ILLEGAL_PARAMETER_FMT 0x12
+#define HCI_ERR_CONN_TERM_BY_LOCAL_HOST 0x16
+#define HCI_ERR_UNSPECIFIED 0x1F
+#define HCI_ERR_UNIT_KEY_USED 0x26
+#define HCI_ERR_QOS_REJECTED 0x2D
+#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30
+#define HCI_ERR_NO_SUITABLE_CHANNEL 0x39
+#define HCI_ERR_CHANNEL_MOVE 0xFF
+
+/* AMP HCI ACL Data packet format */
+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_ACL_data {
+ uint16 handle; /* 12-bit connection handle + 2-bit PB and 2-bit BC flags */
+ uint16 dlen; /* data total length */
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT amp_hci_ACL_data_t;
+
+#define HCI_ACL_DATA_PREAMBLE_SIZE OFFSETOF(amp_hci_ACL_data_t, data)
+
+#define HCI_ACL_DATA_BC_FLAGS (0x0 << 14)
+#define HCI_ACL_DATA_PB_FLAGS (0x3 << 12)
+
+#define HCI_ACL_DATA_HANDLE(handle) ((handle) & 0x0fff)
+#define HCI_ACL_DATA_FLAGS(handle) ((handle) >> 12)
+
+/* AMP Activity Report packet formats */
+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_activity_report {
+ uint8 ScheduleKnown;
+ uint8 NumReports;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT amp_hci_activity_report_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct amp_hci_activity_report_triple {
+ uint32 StartTime;
+ uint32 Duration;
+ uint32 Periodicity;
+} BWL_POST_PACKED_STRUCT amp_hci_activity_report_triple_t;
+
+#define HCI_AR_SCHEDULE_KNOWN 0x01
+
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _bt_amp_hci_h_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/eapol.h b/drivers/net/wireless/ap6210/include/proto/eapol.h
new file mode 100644
index 0000000..8936d16
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/eapol.h
@@ -0,0 +1,193 @@
+/*
+ * 802.1x EAPOL definitions
+ *
+ * See
+ * IEEE Std 802.1X-2001
+ * IEEE 802.1X RADIUS Usage Guidelines
+ *
+ * Copyright (C) 2002 Broadcom Corporation
+ *
+ * $Id: eapol.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _eapol_h_
+#define _eapol_h_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+#include <bcmcrypto/aeskeywrap.h>
+
+/* EAPOL for 802.3/Ethernet */
+typedef BWL_PRE_PACKED_STRUCT struct {
+ struct ether_header eth; /* 802.3/Ethernet header */
+ unsigned char version; /* EAPOL protocol version */
+ unsigned char type; /* EAPOL type */
+ unsigned short length; /* Length of body */
+ unsigned char body[1]; /* Body (optional) */
+} BWL_POST_PACKED_STRUCT eapol_header_t;
+
+#define EAPOL_HEADER_LEN 18
+
+typedef struct {
+ unsigned char version; /* EAPOL protocol version */
+ unsigned char type; /* EAPOL type */
+ unsigned short length; /* Length of body */
+} eapol_hdr_t;
+
+#define EAPOL_HDR_LEN 4
+
+/* EAPOL version */
+#define WPA2_EAPOL_VERSION 2
+#define WPA_EAPOL_VERSION 1
+#define LEAP_EAPOL_VERSION 1
+#define SES_EAPOL_VERSION 1
+
+/* EAPOL types */
+#define EAP_PACKET 0
+#define EAPOL_START 1
+#define EAPOL_LOGOFF 2
+#define EAPOL_KEY 3
+#define EAPOL_ASF 4
+
+/* EAPOL-Key types */
+#define EAPOL_RC4_KEY 1
+#define EAPOL_WPA2_KEY 2 /* 802.11i/WPA2 */
+#define EAPOL_WPA_KEY 254 /* WPA */
+
+/* RC4 EAPOL-Key header field sizes */
+#define EAPOL_KEY_REPLAY_LEN 8
+#define EAPOL_KEY_IV_LEN 16
+#define EAPOL_KEY_SIG_LEN 16
+
+/* RC4 EAPOL-Key */
+typedef BWL_PRE_PACKED_STRUCT struct {
+ unsigned char type; /* Key Descriptor Type */
+ unsigned short length; /* Key Length (unaligned) */
+ unsigned char replay[EAPOL_KEY_REPLAY_LEN]; /* Replay Counter */
+ unsigned char iv[EAPOL_KEY_IV_LEN]; /* Key IV */
+ unsigned char index; /* Key Flags & Index */
+ unsigned char signature[EAPOL_KEY_SIG_LEN]; /* Key Signature */
+ unsigned char key[1]; /* Key (optional) */
+} BWL_POST_PACKED_STRUCT eapol_key_header_t;
+
+#define EAPOL_KEY_HEADER_LEN 44
+
+/* RC4 EAPOL-Key flags */
+#define EAPOL_KEY_FLAGS_MASK 0x80
+#define EAPOL_KEY_BROADCAST 0
+#define EAPOL_KEY_UNICAST 0x80
+
+/* RC4 EAPOL-Key index */
+#define EAPOL_KEY_INDEX_MASK 0x7f
+
+/* WPA/802.11i/WPA2 EAPOL-Key header field sizes */
+#define EAPOL_WPA_KEY_REPLAY_LEN 8
+#define EAPOL_WPA_KEY_NONCE_LEN 32
+#define EAPOL_WPA_KEY_IV_LEN 16
+#define EAPOL_WPA_KEY_RSC_LEN 8
+#define EAPOL_WPA_KEY_ID_LEN 8
+#define EAPOL_WPA_KEY_MIC_LEN 16
+#define EAPOL_WPA_KEY_DATA_LEN (EAPOL_WPA_MAX_KEY_SIZE + AKW_BLOCK_LEN)
+#define EAPOL_WPA_MAX_KEY_SIZE 32
+
+/* WPA EAPOL-Key */
+typedef BWL_PRE_PACKED_STRUCT struct {
+ unsigned char type; /* Key Descriptor Type */
+ unsigned short key_info; /* Key Information (unaligned) */
+ unsigned short key_len; /* Key Length (unaligned) */
+ unsigned char replay[EAPOL_WPA_KEY_REPLAY_LEN]; /* Replay Counter */
+ unsigned char nonce[EAPOL_WPA_KEY_NONCE_LEN]; /* Nonce */
+ unsigned char iv[EAPOL_WPA_KEY_IV_LEN]; /* Key IV */
+ unsigned char rsc[EAPOL_WPA_KEY_RSC_LEN]; /* Key RSC */
+ unsigned char id[EAPOL_WPA_KEY_ID_LEN]; /* WPA:Key ID, 802.11i/WPA2: Reserved */
+ unsigned char mic[EAPOL_WPA_KEY_MIC_LEN]; /* Key MIC */
+ unsigned short data_len; /* Key Data Length */
+ unsigned char data[EAPOL_WPA_KEY_DATA_LEN]; /* Key data */
+} BWL_POST_PACKED_STRUCT eapol_wpa_key_header_t;
+
+#define EAPOL_WPA_KEY_LEN 95
+
+/* WPA/802.11i/WPA2 KEY KEY_INFO bits */
+#define WPA_KEY_DESC_V1 0x01
+#define WPA_KEY_DESC_V2 0x02
+#define WPA_KEY_DESC_V3 0x03
+#define WPA_KEY_PAIRWISE 0x08
+#define WPA_KEY_INSTALL 0x40
+#define WPA_KEY_ACK 0x80
+#define WPA_KEY_MIC 0x100
+#define WPA_KEY_SECURE 0x200
+#define WPA_KEY_ERROR 0x400
+#define WPA_KEY_REQ 0x800
+
+#define WPA_KEY_DESC_V2_OR_V3 WPA_KEY_DESC_V2
+
+/* WPA-only KEY KEY_INFO bits */
+#define WPA_KEY_INDEX_0 0x00
+#define WPA_KEY_INDEX_1 0x10
+#define WPA_KEY_INDEX_2 0x20
+#define WPA_KEY_INDEX_3 0x30
+#define WPA_KEY_INDEX_MASK 0x30
+#define WPA_KEY_INDEX_SHIFT 0x04
+
+/* 802.11i/WPA2-only KEY KEY_INFO bits */
+#define WPA_KEY_ENCRYPTED_DATA 0x1000
+
+/* Key Data encapsulation */
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint8 type;
+ uint8 length;
+ uint8 oui[3];
+ uint8 subtype;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT eapol_wpa2_encap_data_t;
+
+#define EAPOL_WPA2_ENCAP_DATA_HDR_LEN 6
+
+#define WPA2_KEY_DATA_SUBTYPE_GTK 1
+#define WPA2_KEY_DATA_SUBTYPE_STAKEY 2
+#define WPA2_KEY_DATA_SUBTYPE_MAC 3
+#define WPA2_KEY_DATA_SUBTYPE_PMKID 4
+#define WPA2_KEY_DATA_SUBTYPE_IGTK 9
+
+/* GTK encapsulation */
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint8 flags;
+ uint8 reserved;
+ uint8 gtk[EAPOL_WPA_MAX_KEY_SIZE];
+} BWL_POST_PACKED_STRUCT eapol_wpa2_key_gtk_encap_t;
+
+#define EAPOL_WPA2_KEY_GTK_ENCAP_HDR_LEN 2
+
+#define WPA2_GTK_INDEX_MASK 0x03
+#define WPA2_GTK_INDEX_SHIFT 0x00
+
+#define WPA2_GTK_TRANSMIT 0x04
+
+/* IGTK encapsulation */
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint16 key_id;
+ uint8 ipn[6];
+ uint8 key[EAPOL_WPA_MAX_KEY_SIZE];
+} BWL_POST_PACKED_STRUCT eapol_wpa2_key_igtk_encap_t;
+
+#define EAPOL_WPA2_KEY_IGTK_ENCAP_HDR_LEN 8
+
+/* STAKey encapsulation */
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint8 reserved[2];
+ uint8 mac[ETHER_ADDR_LEN];
+ uint8 stakey[EAPOL_WPA_MAX_KEY_SIZE];
+} BWL_POST_PACKED_STRUCT eapol_wpa2_key_stakey_encap_t;
+
+#define WPA2_KEY_DATA_PAD 0xdd
+
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _eapol_h_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/ethernet.h b/drivers/net/wireless/ap6210/include/proto/ethernet.h
new file mode 100644
index 0000000..a6ce6e1
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/ethernet.h
@@ -0,0 +1,190 @@
+/*
+ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: ethernet.h 309193 2012-01-19 00:03:57Z $
+ */
+
+#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */
+#define _NET_ETHERNET_H_
+
+#ifndef _TYPEDEFS_H_
+#include "typedefs.h"
+#endif
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+
+/*
+ * The number of bytes in an ethernet (MAC) address.
+ */
+#define ETHER_ADDR_LEN 6
+
+/*
+ * The number of bytes in the type field.
+ */
+#define ETHER_TYPE_LEN 2
+
+/*
+ * The number of bytes in the trailing CRC field.
+ */
+#define ETHER_CRC_LEN 4
+
+/*
+ * The length of the combined header.
+ */
+#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
+
+/*
+ * The minimum packet length.
+ */
+#define ETHER_MIN_LEN 64
+
+/*
+ * The minimum packet user data length.
+ */
+#define ETHER_MIN_DATA 46
+
+/*
+ * The maximum packet length.
+ */
+#define ETHER_MAX_LEN 1518
+
+/*
+ * The maximum packet user data length.
+ */
+#define ETHER_MAX_DATA 1500
+
+/* ether types */
+#define ETHER_TYPE_MIN 0x0600 /* Anything less than MIN is a length */
+#define ETHER_TYPE_IP 0x0800 /* IP */
+#define ETHER_TYPE_ARP 0x0806 /* ARP */
+#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */
+#define ETHER_TYPE_IPV6 0x86dd /* IPv6 */
+#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */
+#define ETHER_TYPE_802_1X 0x888e /* 802.1x */
+#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */
+#define ETHER_TYPE_WAI 0x88b4 /* WAI */
+#define ETHER_TYPE_89_0D 0x890d /* 89-0d frame for TDLS */
+
+#define ETHER_TYPE_IPV6 0x86dd /* IPV6 */
+
+/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */
+#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */
+
+/* ether header */
+#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) /* dest address offset */
+#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) /* src address offset */
+#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) /* ether type offset */
+
+/*
+ * A macro to validate a length with
+ */
+#define ETHER_IS_VALID_LEN(foo) \
+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+#define ETHER_FILL_MCAST_ADDR_FROM_IP(ea, mgrp_ip) { \
+ ((uint8 *)ea)[0] = 0x01; \
+ ((uint8 *)ea)[1] = 0x00; \
+ ((uint8 *)ea)[2] = 0x5e; \
+ ((uint8 *)ea)[3] = ((mgrp_ip) >> 16) & 0x7f; \
+ ((uint8 *)ea)[4] = ((mgrp_ip) >> 8) & 0xff; \
+ ((uint8 *)ea)[5] = ((mgrp_ip) >> 0) & 0xff; \
+}
+
+#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+BWL_PRE_PACKED_STRUCT struct ether_header {
+ uint8 ether_dhost[ETHER_ADDR_LEN];
+ uint8 ether_shost[ETHER_ADDR_LEN];
+ uint16 ether_type;
+} BWL_POST_PACKED_STRUCT;
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+BWL_PRE_PACKED_STRUCT struct ether_addr {
+ uint8 octet[ETHER_ADDR_LEN];
+} BWL_POST_PACKED_STRUCT;
+#endif /* !__INCif_etherh Quick and ugly hack for VxWorks */
+
+/*
+ * Takes a pointer, set, test, clear, toggle locally admininistered
+ * address bit in the 48-bit Ethernet address.
+ */
+#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2))
+#define ETHER_IS_LOCALADDR(ea) (((uint8 *)(ea))[0] & 2)
+#define ETHER_CLR_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & 0xfd))
+#define ETHER_TOGGLE_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] ^ 2))
+
+/* Takes a pointer, marks unicast address bit in the MAC address */
+#define ETHER_SET_UNICAST(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] & ~1))
+
+/*
+ * Takes a pointer, returns true if a 48-bit multicast address
+ * (including broadcast, since it is all ones)
+ */
+#define ETHER_ISMULTI(ea) (((const uint8 *)(ea))[0] & 1)
+
+
+/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */
+#define ether_cmp(a, b) (!(((short*)(a))[0] == ((short*)(b))[0]) | \
+ !(((short*)(a))[1] == ((short*)(b))[1]) | \
+ !(((short*)(a))[2] == ((short*)(b))[2]))
+
+/* copy an ethernet address - assumes the pointers can be referenced as shorts */
+#define ether_copy(s, d) { \
+ ((short*)(d))[0] = ((const short*)(s))[0]; \
+ ((short*)(d))[1] = ((const short*)(s))[1]; \
+ ((short*)(d))[2] = ((const short*)(s))[2]; }
+
+
+static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}};
+static const struct ether_addr ether_null = {{0, 0, 0, 0, 0, 0}};
+
+#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \
+ ((uint8 *)(ea))[1] & \
+ ((uint8 *)(ea))[2] & \
+ ((uint8 *)(ea))[3] & \
+ ((uint8 *)(ea))[4] & \
+ ((uint8 *)(ea))[5]) == 0xff)
+#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \
+ ((uint8 *)(ea))[1] | \
+ ((uint8 *)(ea))[2] | \
+ ((uint8 *)(ea))[3] | \
+ ((uint8 *)(ea))[4] | \
+ ((uint8 *)(ea))[5]) == 0)
+
+#define ETHER_MOVE_HDR(d, s) \
+do { \
+ struct ether_header t; \
+ t = *(struct ether_header *)(s); \
+ *(struct ether_header *)(d) = t; \
+} while (0)
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _NET_ETHERNET_H_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/p2p.h b/drivers/net/wireless/ap6210/include/proto/p2p.h
new file mode 100644
index 0000000..6716e2a
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/p2p.h
@@ -0,0 +1,579 @@
+/*
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * Fundamental types and constants relating to WFA P2P (aka WiFi Direct)
+ *
+ * $Id: p2p.h 356417 2012-09-12 16:41:24Z $
+ */
+
+#ifndef _P2P_H_
+#define _P2P_H_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+#include <wlioctl.h>
+#include <proto/802.11.h>
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+
+/* WiFi P2P OUI values */
+#define P2P_OUI WFA_OUI /* WiFi P2P OUI */
+#define P2P_VER WFA_OUI_TYPE_P2P /* P2P version: 9=WiFi P2P v1.0 */
+
+#define P2P_IE_ID 0xdd /* P2P IE element ID */
+
+/* WiFi P2P IE */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_ie {
+ uint8 id; /* IE ID: 0xDD */
+ uint8 len; /* IE length */
+ uint8 OUI[3]; /* WiFi P2P specific OUI: P2P_OUI */
+ uint8 oui_type; /* Identifies P2P version: P2P_VER */
+ uint8 subelts[1]; /* variable length subelements */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_ie wifi_p2p_ie_t;
+
+#define P2P_IE_FIXED_LEN 6
+
+#define P2P_ATTR_ID_OFF 0
+#define P2P_ATTR_LEN_OFF 1
+#define P2P_ATTR_DATA_OFF 3
+
+#define P2P_ATTR_ID_LEN 1 /* ID filed length */
+#define P2P_ATTR_LEN_LEN 2 /* length field length */
+#define P2P_ATTR_HDR_LEN 3 /* ID + 2-byte length field spec 1.02 */
+
+/* P2P IE Subelement IDs from WiFi P2P Technical Spec 1.00 */
+#define P2P_SEID_STATUS 0 /* Status */
+#define P2P_SEID_MINOR_RC 1 /* Minor Reason Code */
+#define P2P_SEID_P2P_INFO 2 /* P2P Capability (capabilities info) */
+#define P2P_SEID_DEV_ID 3 /* P2P Device ID */
+#define P2P_SEID_INTENT 4 /* Group Owner Intent */
+#define P2P_SEID_CFG_TIMEOUT 5 /* Configuration Timeout */
+#define P2P_SEID_CHANNEL 6 /* Channel */
+#define P2P_SEID_GRP_BSSID 7 /* P2P Group BSSID */
+#define P2P_SEID_XT_TIMING 8 /* Extended Listen Timing */
+#define P2P_SEID_INTINTADDR 9 /* Intended P2P Interface Address */
+#define P2P_SEID_P2P_MGBTY 10 /* P2P Manageability */
+#define P2P_SEID_CHAN_LIST 11 /* Channel List */
+#define P2P_SEID_ABSENCE 12 /* Notice of Absence */
+#define P2P_SEID_DEV_INFO 13 /* Device Info */
+#define P2P_SEID_GROUP_INFO 14 /* Group Info */
+#define P2P_SEID_GROUP_ID 15 /* Group ID */
+#define P2P_SEID_P2P_IF 16 /* P2P Interface */
+#define P2P_SEID_OP_CHANNEL 17 /* Operating Channel */
+#define P2P_SEID_INVITE_FLAGS 18 /* Invitation Flags */
+#define P2P_SEID_VNDR 221 /* Vendor-specific subelement */
+
+#define P2P_SE_VS_ID_SERVICES 0x1b /* BRCM proprietary subel: L2 Services */
+
+
+/* WiFi P2P IE subelement: P2P Capability (capabilities info) */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_info_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_P2P_INFO */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 dev; /* Device Capability Bitmap */
+ uint8 group; /* Group Capability Bitmap */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_info_se_s wifi_p2p_info_se_t;
+
+/* P2P Capability subelement's Device Capability Bitmap bit values */
+#define P2P_CAPSE_DEV_SERVICE_DIS 0x1 /* Service Discovery */
+#define P2P_CAPSE_DEV_CLIENT_DIS 0x2 /* Client Discoverability */
+#define P2P_CAPSE_DEV_CONCURRENT 0x4 /* Concurrent Operation */
+#define P2P_CAPSE_DEV_INFRA_MAN 0x8 /* P2P Infrastructure Managed */
+#define P2P_CAPSE_DEV_LIMIT 0x10 /* P2P Device Limit */
+#define P2P_CAPSE_INVITE_PROC 0x20 /* P2P Invitation Procedure */
+
+/* P2P Capability subelement's Group Capability Bitmap bit values */
+#define P2P_CAPSE_GRP_OWNER 0x1 /* P2P Group Owner */
+#define P2P_CAPSE_PERSIST_GRP 0x2 /* Persistent P2P Group */
+#define P2P_CAPSE_GRP_LIMIT 0x4 /* P2P Group Limit */
+#define P2P_CAPSE_GRP_INTRA_BSS 0x8 /* Intra-BSS Distribution */
+#define P2P_CAPSE_GRP_X_CONNECT 0x10 /* Cross Connection */
+#define P2P_CAPSE_GRP_PERSISTENT 0x20 /* Persistent Reconnect */
+#define P2P_CAPSE_GRP_FORMATION 0x40 /* Group Formation */
+
+
+/* WiFi P2P IE subelement: Group Owner Intent */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_intent_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_INTENT */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 intent; /* Intent Value 0...15 (0=legacy 15=master only) */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_intent_se_s wifi_p2p_intent_se_t;
+
+/* WiFi P2P IE subelement: Configuration Timeout */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_cfg_tmo_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_CFG_TIMEOUT */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 go_tmo; /* GO config timeout in units of 10 ms */
+ uint8 client_tmo; /* Client config timeout in units of 10 ms */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_cfg_tmo_se_s wifi_p2p_cfg_tmo_se_t;
+
+/* WiFi P2P IE subelement: Listen Channel */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_listen_channel_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_CHANNEL */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 country[3]; /* Country String */
+ uint8 op_class; /* Operating Class */
+ uint8 channel; /* Channel */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_listen_channel_se_s wifi_p2p_listen_channel_se_t;
+
+/* WiFi P2P IE subelement: P2P Group BSSID */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_grp_bssid_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_GRP_BSSID */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 mac[6]; /* P2P group bssid */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_grp_bssid_se_s wifi_p2p_grp_bssid_se_t;
+
+/* WiFi P2P IE subelement: P2P Group ID */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_grp_id_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_GROUP_ID */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 mac[6]; /* P2P device address */
+ uint8 ssid[1]; /* ssid. device id. variable length */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_grp_id_se_s wifi_p2p_grp_id_se_t;
+
+/* WiFi P2P IE subelement: P2P Interface */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_intf_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_P2P_IF */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 mac[6]; /* P2P device address */
+ uint8 ifaddrs; /* P2P Interface Address count */
+ uint8 ifaddr[1][6]; /* P2P Interface Address list */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_intf_se_s wifi_p2p_intf_se_t;
+
+/* WiFi P2P IE subelement: Status */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_status_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_STATUS */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 status; /* Status Code: P2P_STATSE_* */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_status_se_s wifi_p2p_status_se_t;
+
+/* Status subelement Status Code definitions */
+#define P2P_STATSE_SUCCESS 0
+ /* Success */
+#define P2P_STATSE_FAIL_INFO_CURR_UNAVAIL 1
+ /* Failed, information currently unavailable */
+#define P2P_STATSE_PASSED_UP P2P_STATSE_FAIL_INFO_CURR_UNAVAIL
+ /* Old name for above in P2P spec 1.08 and older */
+#define P2P_STATSE_FAIL_INCOMPAT_PARAMS 2
+ /* Failed, incompatible parameters */
+#define P2P_STATSE_FAIL_LIMIT_REACHED 3
+ /* Failed, limit reached */
+#define P2P_STATSE_FAIL_INVALID_PARAMS 4
+ /* Failed, invalid parameters */
+#define P2P_STATSE_FAIL_UNABLE_TO_ACCOM 5
+ /* Failed, unable to accomodate request */
+#define P2P_STATSE_FAIL_PROTO_ERROR 6
+ /* Failed, previous protocol error or disruptive behaviour */
+#define P2P_STATSE_FAIL_NO_COMMON_CHAN 7
+ /* Failed, no common channels */
+#define P2P_STATSE_FAIL_UNKNOWN_GROUP 8
+ /* Failed, unknown P2P Group */
+#define P2P_STATSE_FAIL_INTENT 9
+ /* Failed, both peers indicated Intent 15 in GO Negotiation */
+#define P2P_STATSE_FAIL_INCOMPAT_PROVIS 10
+ /* Failed, incompatible provisioning method */
+#define P2P_STATSE_FAIL_USER_REJECT 11
+ /* Failed, rejected by user */
+
+/* WiFi P2P IE attribute: Extended Listen Timing */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_ext_se_s {
+ uint8 eltId; /* ID: P2P_SEID_EXT_TIMING */
+ uint8 len[2]; /* length not including eltId, len fields */
+ uint8 avail[2]; /* availibility period */
+ uint8 interval[2]; /* availibility interval */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_ext_se_s wifi_p2p_ext_se_t;
+
+#define P2P_EXT_MIN 10 /* minimum 10ms */
+
+/* WiFi P2P IE subelement: Intended P2P Interface Address */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_intintad_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_INTINTADDR */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 mac[6]; /* intended P2P interface MAC address */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_intintad_se_s wifi_p2p_intintad_se_t;
+
+/* WiFi P2P IE subelement: Channel */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_channel_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_STATUS */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 band; /* Regulatory Class (band) */
+ uint8 channel; /* Channel */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_channel_se_s wifi_p2p_channel_se_t;
+
+
+/* Channel Entry structure within the Channel List SE */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_chanlist_entry_s {
+ uint8 band; /* Regulatory Class (band) */
+ uint8 num_channels; /* # of channels in the channel list */
+ uint8 channels[WL_NUMCHANNELS]; /* Channel List */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_chanlist_entry_s wifi_p2p_chanlist_entry_t;
+#define WIFI_P2P_CHANLIST_SE_MAX_ENTRIES 2
+
+/* WiFi P2P IE subelement: Channel List */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_chanlist_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_CHAN_LIST */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 country[3]; /* Country String */
+ uint8 num_entries; /* # of channel entries */
+ wifi_p2p_chanlist_entry_t entries[WIFI_P2P_CHANLIST_SE_MAX_ENTRIES];
+ /* Channel Entry List */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_chanlist_se_s wifi_p2p_chanlist_se_t;
+
+/* WiFi Primary Device Type structure */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_pri_devtype_s {
+ uint16 cat_id; /* Category ID */
+ uint8 OUI[3]; /* WFA OUI: 0x0050F2 */
+ uint8 oui_type; /* WPS_OUI_TYPE */
+ uint16 sub_cat_id; /* Sub Category ID */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_pri_devtype_s wifi_p2p_pri_devtype_t;
+
+/* WiFi P2P IE's Device Info subelement */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_devinfo_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_DEVINFO */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 mac[6]; /* P2P Device MAC address */
+ uint16 wps_cfg_meths; /* Config Methods: reg_prototlv.h WPS_CONFMET_* */
+ uint8 pri_devtype[8]; /* Primary Device Type */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_devinfo_se_s wifi_p2p_devinfo_se_t;
+
+#define P2P_DEV_TYPE_LEN 8
+
+/* WiFi P2P IE's Group Info subelement Client Info Descriptor */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_cid_fixed_s {
+ uint8 len;
+ uint8 devaddr[ETHER_ADDR_LEN]; /* P2P Device Address */
+ uint8 ifaddr[ETHER_ADDR_LEN]; /* P2P Interface Address */
+ uint8 devcap; /* Device Capability */
+ uint8 cfg_meths[2]; /* Config Methods: reg_prototlv.h WPS_CONFMET_* */
+ uint8 pridt[P2P_DEV_TYPE_LEN]; /* Primary Device Type */
+ uint8 secdts; /* Number of Secondary Device Types */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_cid_fixed_s wifi_p2p_cid_fixed_t;
+
+/* WiFi P2P IE's Device ID subelement */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_devid_se_s {
+ uint8 eltId;
+ uint8 len[2];
+ struct ether_addr addr; /* P2P Device MAC address */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_devid_se_s wifi_p2p_devid_se_t;
+
+/* WiFi P2P IE subelement: P2P Manageability */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_mgbt_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_P2P_MGBTY */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 mg_bitmap; /* manageability bitmap */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_mgbt_se_s wifi_p2p_mgbt_se_t;
+/* mg_bitmap field bit values */
+#define P2P_MGBTSE_P2PDEVMGMT_FLAG 0x1 /* AP supports Managed P2P Device */
+
+/* WiFi P2P IE subelement: Group Info */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_grpinfo_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_GROUP_INFO */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_grpinfo_se_s wifi_p2p_grpinfo_se_t;
+
+/* WiFi IE subelement: Operating Channel */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_op_channel_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_OP_CHANNEL */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 country[3]; /* Country String */
+ uint8 op_class; /* Operating Class */
+ uint8 channel; /* Channel */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_op_channel_se_s wifi_p2p_op_channel_se_t;
+
+/* WiFi IE subelement: INVITATION FLAGS */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_invite_flags_se_s {
+ uint8 eltId; /* SE ID: P2P_SEID_INVITE_FLAGS */
+ uint8 len[2]; /* SE length not including eltId, len fields */
+ uint8 flags; /* Flags */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_invite_flags_se_s wifi_p2p_invite_flags_se_t;
+
+/* WiFi P2P Action Frame */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_action_frame {
+ uint8 category; /* P2P_AF_CATEGORY */
+ uint8 OUI[3]; /* OUI - P2P_OUI */
+ uint8 type; /* OUI Type - P2P_VER */
+ uint8 subtype; /* OUI Subtype - P2P_AF_* */
+ uint8 dialog_token; /* nonzero, identifies req/resp tranaction */
+ uint8 elts[1]; /* Variable length information elements. Max size =
+ * ACTION_FRAME_SIZE - sizeof(this structure) - 1
+ */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_action_frame wifi_p2p_action_frame_t;
+#define P2P_AF_CATEGORY 0x7f
+
+#define P2P_AF_FIXED_LEN 7
+
+/* WiFi P2P Action Frame OUI Subtypes */
+#define P2P_AF_NOTICE_OF_ABSENCE 0 /* Notice of Absence */
+#define P2P_AF_PRESENCE_REQ 1 /* P2P Presence Request */
+#define P2P_AF_PRESENCE_RSP 2 /* P2P Presence Response */
+#define P2P_AF_GO_DISC_REQ 3 /* GO Discoverability Request */
+
+
+/* WiFi P2P Public Action Frame */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_pub_act_frame {
+ uint8 category; /* P2P_PUB_AF_CATEGORY */
+ uint8 action; /* P2P_PUB_AF_ACTION */
+ uint8 oui[3]; /* P2P_OUI */
+ uint8 oui_type; /* OUI type - P2P_VER */
+ uint8 subtype; /* OUI subtype - P2P_TYPE_* */
+ uint8 dialog_token; /* nonzero, identifies req/rsp transaction */
+ uint8 elts[1]; /* Variable length information elements. Max size =
+ * ACTION_FRAME_SIZE - sizeof(this structure) - 1
+ */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_pub_act_frame wifi_p2p_pub_act_frame_t;
+#define P2P_PUB_AF_FIXED_LEN 8
+#define P2P_PUB_AF_CATEGORY 0x04
+#define P2P_PUB_AF_ACTION 0x09
+
+/* WiFi P2P Public Action Frame OUI Subtypes */
+#define P2P_PAF_GON_REQ 0 /* Group Owner Negotiation Req */
+#define P2P_PAF_GON_RSP 1 /* Group Owner Negotiation Rsp */
+#define P2P_PAF_GON_CONF 2 /* Group Owner Negotiation Confirm */
+#define P2P_PAF_INVITE_REQ 3 /* P2P Invitation Request */
+#define P2P_PAF_INVITE_RSP 4 /* P2P Invitation Response */
+#define P2P_PAF_DEVDIS_REQ 5 /* Device Discoverability Request */
+#define P2P_PAF_DEVDIS_RSP 6 /* Device Discoverability Response */
+#define P2P_PAF_PROVDIS_REQ 7 /* Provision Discovery Request */
+#define P2P_PAF_PROVDIS_RSP 8 /* Provision Discovery Response */
+#define P2P_PAF_SUBTYPE_INVALID 255 /* Invalid Subtype */
+
+/* TODO: Stop using these obsolete aliases for P2P_PAF_GON_* */
+#define P2P_TYPE_MNREQ P2P_PAF_GON_REQ
+#define P2P_TYPE_MNRSP P2P_PAF_GON_RSP
+#define P2P_TYPE_MNCONF P2P_PAF_GON_CONF
+
+/* WiFi P2P IE subelement: Notice of Absence */
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_desc {
+ uint8 cnt_type; /* Count/Type */
+ uint32 duration; /* Duration */
+ uint32 interval; /* Interval */
+ uint32 start; /* Start Time */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_noa_desc wifi_p2p_noa_desc_t;
+
+BWL_PRE_PACKED_STRUCT struct wifi_p2p_noa_se {
+ uint8 eltId; /* Subelement ID */
+ uint8 len[2]; /* Length */
+ uint8 index; /* Index */
+ uint8 ops_ctw_parms; /* CTWindow and OppPS Parameters */
+ wifi_p2p_noa_desc_t desc[1]; /* Notice of Absence Descriptor(s) */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2p_noa_se wifi_p2p_noa_se_t;
+
+#define P2P_NOA_SE_FIXED_LEN 5
+
+/* cnt_type field values */
+#define P2P_NOA_DESC_CNT_RESERVED 0 /* reserved and should not be used */
+#define P2P_NOA_DESC_CNT_REPEAT 255 /* continuous schedule */
+#define P2P_NOA_DESC_TYPE_PREFERRED 1 /* preferred values */
+#define P2P_NOA_DESC_TYPE_ACCEPTABLE 2 /* acceptable limits */
+
+/* ctw_ops_parms field values */
+#define P2P_NOA_CTW_MASK 0x7f
+#define P2P_NOA_OPS_MASK 0x80
+#define P2P_NOA_OPS_SHIFT 7
+
+#define P2P_CTW_MIN 10 /* minimum 10TU */
+
+/*
+ * P2P Service Discovery related
+ */
+#define P2PSD_ACTION_CATEGORY 0x04
+ /* Public action frame */
+#define P2PSD_ACTION_ID_GAS_IREQ 0x0a
+ /* Action value for GAS Initial Request AF */
+#define P2PSD_ACTION_ID_GAS_IRESP 0x0b
+ /* Action value for GAS Initial Response AF */
+#define P2PSD_ACTION_ID_GAS_CREQ 0x0c
+ /* Action value for GAS Comback Request AF */
+#define P2PSD_ACTION_ID_GAS_CRESP 0x0d
+ /* Action value for GAS Comback Response AF */
+#define P2PSD_AD_EID 0x6c
+ /* Advertisement Protocol IE ID */
+#define P2PSD_ADP_TUPLE_QLMT_PAMEBI 0x00
+ /* Query Response Length Limit 7 bits plus PAME-BI 1 bit */
+#define P2PSD_ADP_PROTO_ID 0x00
+ /* Advertisement Protocol ID. Always 0 for P2P SD */
+#define P2PSD_GAS_OUI P2P_OUI
+ /* WFA OUI */
+#define P2PSD_GAS_OUI_SUBTYPE P2P_VER
+ /* OUI Subtype for GAS IE */
+#define P2PSD_GAS_NQP_INFOID 0xDDDD
+ /* NQP Query Info ID: 56797 */
+#define P2PSD_GAS_COMEBACKDEALY 0x00
+ /* Not used in the Native GAS protocol */
+
+/* Service Protocol Type */
+typedef enum p2psd_svc_protype {
+ SVC_RPOTYPE_ALL = 0,
+ SVC_RPOTYPE_BONJOUR = 1,
+ SVC_RPOTYPE_UPNP = 2,
+ SVC_RPOTYPE_WSD = 3,
+ SVC_RPOTYPE_VENDOR = 255
+} p2psd_svc_protype_t;
+
+/* Service Discovery response status code */
+typedef enum {
+ P2PSD_RESP_STATUS_SUCCESS = 0,
+ P2PSD_RESP_STATUS_PROTYPE_NA = 1,
+ P2PSD_RESP_STATUS_DATA_NA = 2,
+ P2PSD_RESP_STATUS_BAD_REQUEST = 3
+} p2psd_resp_status_t;
+
+/* Advertisement Protocol IE tuple field */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_adp_tpl {
+ uint8 llm_pamebi; /* Query Response Length Limit bit 0-6, set to 0 plus
+ * Pre-Associated Message Exchange BSSID Independent bit 7, set to 0
+ */
+ uint8 adp_id; /* Advertisement Protocol ID: 0 for NQP Native Query Protocol */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_adp_tpl wifi_p2psd_adp_tpl_t;
+
+/* Advertisement Protocol IE */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_adp_ie {
+ uint8 id; /* IE ID: 0x6c - 108 */
+ uint8 len; /* IE length */
+ wifi_p2psd_adp_tpl_t adp_tpl; /* Advertisement Protocol Tuple field. Only one
+ * tuple is defined for P2P Service Discovery
+ */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_adp_ie wifi_p2psd_adp_ie_t;
+
+/* NQP Vendor-specific Content */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_nqp_query_vsc {
+ uint8 oui_subtype; /* OUI Subtype: 0x09 */
+ uint16 svc_updi; /* Service Update Indicator */
+ uint8 svc_tlvs[1]; /* wifi_p2psd_qreq_tlv_t type for service request,
+ * wifi_p2psd_qresp_tlv_t type for service response
+ */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_nqp_query_vsc wifi_p2psd_nqp_query_vsc_t;
+
+/* Service Request TLV */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qreq_tlv {
+ uint16 len; /* Length: 5 plus size of Query Data */
+ uint8 svc_prot; /* Service Protocol Type */
+ uint8 svc_tscid; /* Service Transaction ID */
+ uint8 query_data[1]; /* Query Data, passed in from above Layer 2 */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_qreq_tlv wifi_p2psd_qreq_tlv_t;
+
+/* Query Request Frame, defined in generic format, instead of NQP specific */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qreq_frame {
+ uint16 info_id; /* Info ID: 0xDDDD */
+ uint16 len; /* Length of service request TLV, 5 plus the size of request data */
+ uint8 oui[3]; /* WFA OUI: 0x0050F2 */
+ uint8 qreq_vsc[1]; /* Vendor-specific Content: wifi_p2psd_nqp_query_vsc_t type for NQP */
+
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_qreq_frame wifi_p2psd_qreq_frame_t;
+
+/* GAS Initial Request AF body, "elts" in wifi_p2p_pub_act_frame */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_ireq_frame {
+ wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */
+ uint16 qreq_len; /* Query Request Length */
+ uint8 qreq_frm[1]; /* Query Request Frame wifi_p2psd_qreq_frame_t */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_gas_ireq_frame wifi_p2psd_gas_ireq_frame_t;
+
+/* Service Response TLV */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qresp_tlv {
+ uint16 len; /* Length: 5 plus size of Query Data */
+ uint8 svc_prot; /* Service Protocol Type */
+ uint8 svc_tscid; /* Service Transaction ID */
+ uint8 status; /* Value defined in Table 57 of P2P spec. */
+ uint8 query_data[1]; /* Response Data, passed in from above Layer 2 */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_qresp_tlv wifi_p2psd_qresp_tlv_t;
+
+/* Query Response Frame, defined in generic format, instead of NQP specific */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_qresp_frame {
+ uint16 info_id; /* Info ID: 0xDDDD */
+ uint16 len; /* Lenth of service response TLV, 6 plus the size of resp data */
+ uint8 oui[3]; /* WFA OUI: 0x0050F2 */
+ uint8 qresp_vsc[1]; /* Vendor-specific Content: wifi_p2psd_qresp_tlv_t type for NQP */
+
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_qresp_frame wifi_p2psd_qresp_frame_t;
+
+/* GAS Initial Response AF body, "elts" in wifi_p2p_pub_act_frame */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_iresp_frame {
+ uint16 status; /* Value defined in Table 7-23 of IEEE P802.11u */
+ uint16 cb_delay; /* GAS Comeback Delay */
+ wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */
+ uint16 qresp_len; /* Query Response Length */
+ uint8 qresp_frm[1]; /* Query Response Frame wifi_p2psd_qresp_frame_t */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_gas_iresp_frame wifi_p2psd_gas_iresp_frame_t;
+
+/* GAS Comeback Response AF body, "elts" in wifi_p2p_pub_act_frame */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_cresp_frame {
+ uint16 status; /* Value defined in Table 7-23 of IEEE P802.11u */
+ uint8 fragment_id; /* Fragmentation ID */
+ uint16 cb_delay; /* GAS Comeback Delay */
+ wifi_p2psd_adp_ie_t adp_ie; /* Advertisement Protocol IE */
+ uint16 qresp_len; /* Query Response Length */
+ uint8 qresp_frm[1]; /* Query Response Frame wifi_p2psd_qresp_frame_t */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_gas_cresp_frame wifi_p2psd_gas_cresp_frame_t;
+
+/* Wi-Fi GAS Public Action Frame */
+BWL_PRE_PACKED_STRUCT struct wifi_p2psd_gas_pub_act_frame {
+ uint8 category; /* 0x04 Public Action Frame */
+ uint8 action; /* 0x6c Advertisement Protocol */
+ uint8 dialog_token; /* nonzero, identifies req/rsp transaction */
+ uint8 query_data[1]; /* Query Data. wifi_p2psd_gas_ireq_frame_t
+ * or wifi_p2psd_gas_iresp_frame_t format
+ */
+} BWL_POST_PACKED_STRUCT;
+typedef struct wifi_p2psd_gas_pub_act_frame wifi_p2psd_gas_pub_act_frame_t;
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _P2P_H_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/sdspi.h b/drivers/net/wireless/ap6210/include/proto/sdspi.h
new file mode 100644
index 0000000..a4900ed
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/sdspi.h
@@ -0,0 +1,75 @@
+/*
+ * SD-SPI Protocol Standard
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sdspi.h 241182 2011-02-17 21:50:03Z $
+ */
+#ifndef _SD_SPI_H
+#define _SD_SPI_H
+
+#define SPI_START_M BITFIELD_MASK(1) /* Bit [31] - Start Bit */
+#define SPI_START_S 31
+#define SPI_DIR_M BITFIELD_MASK(1) /* Bit [30] - Direction */
+#define SPI_DIR_S 30
+#define SPI_CMD_INDEX_M BITFIELD_MASK(6) /* Bits [29:24] - Command number */
+#define SPI_CMD_INDEX_S 24
+#define SPI_RW_M BITFIELD_MASK(1) /* Bit [23] - Read=0, Write=1 */
+#define SPI_RW_S 23
+#define SPI_FUNC_M BITFIELD_MASK(3) /* Bits [22:20] - Function Number */
+#define SPI_FUNC_S 20
+#define SPI_RAW_M BITFIELD_MASK(1) /* Bit [19] - Read After Wr */
+#define SPI_RAW_S 19
+#define SPI_STUFF_M BITFIELD_MASK(1) /* Bit [18] - Stuff bit */
+#define SPI_STUFF_S 18
+#define SPI_BLKMODE_M BITFIELD_MASK(1) /* Bit [19] - Blockmode 1=blk */
+#define SPI_BLKMODE_S 19
+#define SPI_OPCODE_M BITFIELD_MASK(1) /* Bit [18] - OP Code */
+#define SPI_OPCODE_S 18
+#define SPI_ADDR_M BITFIELD_MASK(17) /* Bits [17:1] - Address */
+#define SPI_ADDR_S 1
+#define SPI_STUFF0_M BITFIELD_MASK(1) /* Bit [0] - Stuff bit */
+#define SPI_STUFF0_S 0
+
+#define SPI_RSP_START_M BITFIELD_MASK(1) /* Bit [7] - Start Bit (always 0) */
+#define SPI_RSP_START_S 7
+#define SPI_RSP_PARAM_ERR_M BITFIELD_MASK(1) /* Bit [6] - Parameter Error */
+#define SPI_RSP_PARAM_ERR_S 6
+#define SPI_RSP_RFU5_M BITFIELD_MASK(1) /* Bit [5] - RFU (Always 0) */
+#define SPI_RSP_RFU5_S 5
+#define SPI_RSP_FUNC_ERR_M BITFIELD_MASK(1) /* Bit [4] - Function number error */
+#define SPI_RSP_FUNC_ERR_S 4
+#define SPI_RSP_CRC_ERR_M BITFIELD_MASK(1) /* Bit [3] - COM CRC Error */
+#define SPI_RSP_CRC_ERR_S 3
+#define SPI_RSP_ILL_CMD_M BITFIELD_MASK(1) /* Bit [2] - Illegal Command error */
+#define SPI_RSP_ILL_CMD_S 2
+#define SPI_RSP_RFU1_M BITFIELD_MASK(1) /* Bit [1] - RFU (Always 0) */
+#define SPI_RSP_RFU1_S 1
+#define SPI_RSP_IDLE_M BITFIELD_MASK(1) /* Bit [0] - In idle state */
+#define SPI_RSP_IDLE_S 0
+
+/* SD-SPI Protocol Definitions */
+#define SDSPI_COMMAND_LEN 6 /* Number of bytes in an SD command */
+#define SDSPI_START_BLOCK 0xFE /* SD Start Block Token */
+#define SDSPI_IDLE_PAD 0xFF /* SD-SPI idle value for MOSI */
+#define SDSPI_START_BIT_MASK 0x80
+
+#endif /* _SD_SPI_H */
diff --git a/drivers/net/wireless/ap6210/include/proto/vlan.h b/drivers/net/wireless/ap6210/include/proto/vlan.h
new file mode 100644
index 0000000..88502bf
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/vlan.h
@@ -0,0 +1,69 @@
+/*
+ * 802.1Q VLAN protocol definitions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: vlan.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _vlan_h_
+#define _vlan_h_
+
+#ifndef _TYPEDEFS_H_
+#include <typedefs.h>
+#endif
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */
+#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */
+#define VLAN_PRI_SHIFT 13 /* user priority */
+
+#define VLAN_PRI_MASK 7 /* 3 bits of priority */
+
+#define VLAN_TAG_LEN 4
+#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) /* offset in Ethernet II packet only */
+
+#define VLAN_TPID 0x8100 /* VLAN ethertype/Tag Protocol ID */
+
+struct ethervlan_header {
+ uint8 ether_dhost[ETHER_ADDR_LEN];
+ uint8 ether_shost[ETHER_ADDR_LEN];
+ uint16 vlan_type; /* 0x8100 */
+ uint16 vlan_tag; /* priority, cfi and vid */
+ uint16 ether_type;
+};
+
+#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN)
+
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#define ETHERVLAN_MOVE_HDR(d, s) \
+do { \
+ struct ethervlan_header t; \
+ t = *(struct ethervlan_header *)(s); \
+ *(struct ethervlan_header *)(d) = t; \
+} while (0)
+
+#endif /* _vlan_h_ */
diff --git a/drivers/net/wireless/ap6210/include/proto/wpa.h b/drivers/net/wireless/ap6210/include/proto/wpa.h
new file mode 100644
index 0000000..23ab8d6
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/proto/wpa.h
@@ -0,0 +1,206 @@
+/*
+ * Fundamental types and constants relating to WPA
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wpa.h 261155 2011-05-23 23:51:32Z $
+ */
+
+#ifndef _proto_wpa_h_
+#define _proto_wpa_h_
+
+#include <typedefs.h>
+#include <proto/ethernet.h>
+
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+/* Reason Codes */
+
+/* 13 through 23 taken from IEEE Std 802.11i-2004 */
+#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */
+#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */
+#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */
+#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */
+#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from
+ * (re-)assoc. request/probe response
+ */
+#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */
+#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */
+#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */
+#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */
+#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */
+#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */
+
+#define WPA2_PMKID_LEN 16
+
+/* WPA IE fixed portion */
+typedef BWL_PRE_PACKED_STRUCT struct
+{
+ uint8 tag; /* TAG */
+ uint8 length; /* TAG length */
+ uint8 oui[3]; /* IE OUI */
+ uint8 oui_type; /* OUI type */
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 low;
+ uint8 high;
+ } BWL_POST_PACKED_STRUCT version; /* IE version */
+} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t;
+#define WPA_IE_OUITYPE_LEN 4
+#define WPA_IE_FIXED_LEN 8
+#define WPA_IE_TAG_FIXED_LEN 6
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint8 tag; /* TAG */
+ uint8 length; /* TAG length */
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 low;
+ uint8 high;
+ } BWL_POST_PACKED_STRUCT version; /* IE version */
+} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t;
+#define WPA_RSN_IE_FIXED_LEN 4
+#define WPA_RSN_IE_TAG_FIXED_LEN 2
+typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN];
+
+/* WPA suite/multicast suite */
+typedef BWL_PRE_PACKED_STRUCT struct
+{
+ uint8 oui[3];
+ uint8 type;
+} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t;
+#define WPA_SUITE_LEN 4
+
+/* WPA unicast suite list/key management suite list */
+typedef BWL_PRE_PACKED_STRUCT struct
+{
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 low;
+ uint8 high;
+ } BWL_POST_PACKED_STRUCT count;
+ wpa_suite_t list[1];
+} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t;
+#define WPA_IE_SUITE_COUNT_LEN 2
+typedef BWL_PRE_PACKED_STRUCT struct
+{
+ BWL_PRE_PACKED_STRUCT struct {
+ uint8 low;
+ uint8 high;
+ } BWL_POST_PACKED_STRUCT count;
+ wpa_pmkid_t list[1];
+} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t;
+
+/* WPA cipher suites */
+#define WPA_CIPHER_NONE 0 /* None */
+#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
+#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
+#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */
+#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
+#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
+#define WPA_CIPHER_BIP 6 /* WEP (104-bit) */
+#define WPA_CIPHER_TPK 7 /* Group addressed traffic not allowed */
+#ifdef BCMWAPI_WPI
+#define WAPI_CIPHER_NONE WPA_CIPHER_NONE
+#define WAPI_CIPHER_SMS4 11
+
+#define WAPI_CSE_WPI_SMS4 1
+#endif /* BCMWAPI_WPI */
+
+
+#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \
+ (cipher) == WPA_CIPHER_WEP_40 || \
+ (cipher) == WPA_CIPHER_WEP_104 || \
+ (cipher) == WPA_CIPHER_TKIP || \
+ (cipher) == WPA_CIPHER_AES_OCB || \
+ (cipher) == WPA_CIPHER_AES_CCM || \
+ (cipher) == WPA_CIPHER_TPK)
+
+#ifdef BCMWAPI_WAI
+#define IS_WAPI_CIPHER(cipher) ((cipher) == WAPI_CIPHER_NONE || \
+ (cipher) == WAPI_CSE_WPI_SMS4)
+
+/* convert WAPI_CSE_WPI_XXX to WAPI_CIPHER_XXX */
+#define WAPI_CSE_WPI_2_CIPHER(cse) ((cse) == WAPI_CSE_WPI_SMS4 ? \
+ WAPI_CIPHER_SMS4 : WAPI_CIPHER_NONE)
+
+#define WAPI_CIPHER_2_CSE_WPI(cipher) ((cipher) == WAPI_CIPHER_SMS4 ? \
+ WAPI_CSE_WPI_SMS4 : WAPI_CIPHER_NONE)
+#endif /* BCMWAPI_WAI */
+
+
+/* WPA TKIP countermeasures parameters */
+#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */
+#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */
+
+/* RSN IE defines */
+#define RSN_CAP_LEN 2 /* Length of RSN capabilities field (2 octets) */
+
+/* RSN Capabilities defined in 802.11i */
+#define RSN_CAP_PREAUTH 0x0001
+#define RSN_CAP_NOPAIRWISE 0x0002
+#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
+#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2
+#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030
+#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4
+#define RSN_CAP_1_REPLAY_CNTR 0
+#define RSN_CAP_2_REPLAY_CNTRS 1
+#define RSN_CAP_4_REPLAY_CNTRS 2
+#define RSN_CAP_16_REPLAY_CNTRS 3
+#ifdef MFP
+#define RSN_CAP_MFPR 0x0040
+#define RSN_CAP_MFPC 0x0080
+#endif
+
+/* WPA capabilities defined in 802.11i */
+#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS
+#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS
+#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT
+#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK
+
+/* WPA capabilities defined in 802.11zD9.0 */
+#define WPA_CAP_PEER_KEY_ENABLE (0x1 << 1) /* bit 9 */
+
+/* WPA Specific defines */
+#define WPA_CAP_LEN RSN_CAP_LEN /* Length of RSN capabilities in RSN IE (2 octets) */
+#define WPA_PMKID_CNT_LEN 2 /* Length of RSN PMKID count (2 octests) */
+
+#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH
+
+#ifdef BCMWAPI_WAI
+#define WAPI_CAP_PREAUTH RSN_CAP_PREAUTH
+
+/* Other WAI definition */
+#define WAPI_WAI_REQUEST 0x00F1
+#define WAPI_UNICAST_REKEY 0x00F2
+#define WAPI_STA_AGING 0x00F3
+#define WAPI_MUTIL_REKEY 0x00F4
+#define WAPI_STA_STATS 0x00F5
+
+#define WAPI_USK_REKEY_COUNT 0x4000000 /* 0xA00000 */
+#define WAPI_MSK_REKEY_COUNT 0x4000000 /* 0xA00000 */
+#endif /* BCMWAPI_WAI */
+#define WPA2_PMKID_COUNT_LEN 2
+
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _proto_wpa_h_ */
diff --git a/drivers/net/wireless/ap6210/include/sbchipc.h b/drivers/net/wireless/ap6210/include/sbchipc.h
new file mode 100644
index 0000000..c694291
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sbchipc.h
@@ -0,0 +1,2405 @@
+/*
+ * SiliconBackplane Chipcommon core hardware definitions.
+ *
+ * The chipcommon core provides chip identification, SB control,
+ * JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer,
+ * GPIO interface, extbus, and support for serial and parallel flashes.
+ *
+ * $Id: sbchipc.h 347614 2012-07-27 10:24:51Z $
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ */
+
+#ifndef _SBCHIPC_H
+#define _SBCHIPC_H
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif /* PAD */
+
+typedef struct eci_prerev35 {
+ uint32 eci_output;
+ uint32 eci_control;
+ uint32 eci_inputlo;
+ uint32 eci_inputmi;
+ uint32 eci_inputhi;
+ uint32 eci_inputintpolaritylo;
+ uint32 eci_inputintpolaritymi;
+ uint32 eci_inputintpolarityhi;
+ uint32 eci_intmasklo;
+ uint32 eci_intmaskmi;
+ uint32 eci_intmaskhi;
+ uint32 eci_eventlo;
+ uint32 eci_eventmi;
+ uint32 eci_eventhi;
+ uint32 eci_eventmasklo;
+ uint32 eci_eventmaskmi;
+ uint32 eci_eventmaskhi;
+ uint32 PAD[3];
+} eci_prerev35_t;
+
+typedef struct eci_rev35 {
+ uint32 eci_outputlo;
+ uint32 eci_outputhi;
+ uint32 eci_controllo;
+ uint32 eci_controlhi;
+ uint32 eci_inputlo;
+ uint32 eci_inputhi;
+ uint32 eci_inputintpolaritylo;
+ uint32 eci_inputintpolarityhi;
+ uint32 eci_intmasklo;
+ uint32 eci_intmaskhi;
+ uint32 eci_eventlo;
+ uint32 eci_eventhi;
+ uint32 eci_eventmasklo;
+ uint32 eci_eventmaskhi;
+ uint32 eci_auxtx;
+ uint32 eci_auxrx;
+ uint32 eci_datatag;
+ uint32 eci_uartescvalue;
+ uint32 eci_autobaudctr;
+ uint32 eci_uartfifolevel;
+} eci_rev35_t;
+
+typedef struct flash_config {
+ uint32 PAD[19];
+ /* Flash struct configuration registers (0x18c) for BCM4706 (corerev = 31) */
+ uint32 flashstrconfig;
+} flash_config_t;
+
+typedef volatile struct {
+ uint32 chipid; /* 0x0 */
+ uint32 capabilities;
+ uint32 corecontrol; /* corerev >= 1 */
+ uint32 bist;
+
+ /* OTP */
+ uint32 otpstatus; /* 0x10, corerev >= 10 */
+ uint32 otpcontrol;
+ uint32 otpprog;
+ uint32 otplayout; /* corerev >= 23 */
+
+ /* Interrupt control */
+ uint32 intstatus; /* 0x20 */
+ uint32 intmask;
+
+ /* Chip specific regs */
+ uint32 chipcontrol; /* 0x28, rev >= 11 */
+ uint32 chipstatus; /* 0x2c, rev >= 11 */
+
+ /* Jtag Master */
+ uint32 jtagcmd; /* 0x30, rev >= 10 */
+ uint32 jtagir;
+ uint32 jtagdr;
+ uint32 jtagctrl;
+
+ /* serial flash interface registers */
+ uint32 flashcontrol; /* 0x40 */
+ uint32 flashaddress;
+ uint32 flashdata;
+ uint32 otplayoutextension; /* rev >= 35 */
+
+ /* Silicon backplane configuration broadcast control */
+ uint32 broadcastaddress; /* 0x50 */
+ uint32 broadcastdata;
+
+ /* gpio - cleared only by power-on-reset */
+ uint32 gpiopullup; /* 0x58, corerev >= 20 */
+ uint32 gpiopulldown; /* 0x5c, corerev >= 20 */
+ uint32 gpioin; /* 0x60 */
+ uint32 gpioout; /* 0x64 */
+ uint32 gpioouten; /* 0x68 */
+ uint32 gpiocontrol; /* 0x6C */
+ uint32 gpiointpolarity; /* 0x70 */
+ uint32 gpiointmask; /* 0x74 */
+
+ /* GPIO events corerev >= 11 */
+ uint32 gpioevent;
+ uint32 gpioeventintmask;
+
+ /* Watchdog timer */
+ uint32 watchdog; /* 0x80 */
+
+ /* GPIO events corerev >= 11 */
+ uint32 gpioeventintpolarity;
+
+ /* GPIO based LED powersave registers corerev >= 16 */
+ uint32 gpiotimerval; /* 0x88 */
+ uint32 gpiotimeroutmask;
+
+ /* clock control */
+ uint32 clockcontrol_n; /* 0x90 */
+ uint32 clockcontrol_sb; /* aka m0 */
+ uint32 clockcontrol_pci; /* aka m1 */
+ uint32 clockcontrol_m2; /* mii/uart/mipsref */
+ uint32 clockcontrol_m3; /* cpu */
+ uint32 clkdiv; /* corerev >= 3 */
+ uint32 gpiodebugsel; /* corerev >= 28 */
+ uint32 capabilities_ext; /* 0xac */
+
+ /* pll delay registers (corerev >= 4) */
+ uint32 pll_on_delay; /* 0xb0 */
+ uint32 fref_sel_delay;
+ uint32 slow_clk_ctl; /* 5 < corerev < 10 */
+ uint32 PAD;
+
+ /* Instaclock registers (corerev >= 10) */
+ uint32 system_clk_ctl; /* 0xc0 */
+ uint32 clkstatestretch;
+ uint32 PAD[2];
+
+ /* Indirect backplane access (corerev >= 22) */
+ uint32 bp_addrlow; /* 0xd0 */
+ uint32 bp_addrhigh;
+ uint32 bp_data;
+ uint32 PAD;
+ uint32 bp_indaccess;
+ /* SPI registers, corerev >= 37 */
+ uint32 gsioctrl;
+ uint32 gsioaddress;
+ uint32 gsiodata;
+
+ /* More clock dividers (corerev >= 32) */
+ uint32 clkdiv2;
+ /* FAB ID (corerev >= 40) */
+ uint32 otpcontrol1;
+ uint32 fabid; /* 0xf8 */
+
+ /* In AI chips, pointer to erom */
+ uint32 eromptr; /* 0xfc */
+
+ /* ExtBus control registers (corerev >= 3) */
+ uint32 pcmcia_config; /* 0x100 */
+ uint32 pcmcia_memwait;
+ uint32 pcmcia_attrwait;
+ uint32 pcmcia_iowait;
+ uint32 ide_config;
+ uint32 ide_memwait;
+ uint32 ide_attrwait;
+ uint32 ide_iowait;
+ uint32 prog_config;
+ uint32 prog_waitcount;
+ uint32 flash_config;
+ uint32 flash_waitcount;
+ uint32 SECI_config; /* 0x130 SECI configuration */
+ uint32 SECI_status;
+ uint32 SECI_statusmask;
+ uint32 SECI_rxnibchanged;
+
+ uint32 PAD[20];
+
+ /* SROM interface (corerev >= 32) */
+ uint32 sromcontrol; /* 0x190 */
+ uint32 sromaddress;
+ uint32 sromdata;
+ uint32 PAD[1]; /* 0x19C */
+ /* NAND flash registers for BCM4706 (corerev = 31) */
+ uint32 nflashctrl; /* 0x1a0 */
+ uint32 nflashconf;
+ uint32 nflashcoladdr;
+ uint32 nflashrowaddr;
+ uint32 nflashdata;
+ uint32 nflashwaitcnt0; /* 0x1b4 */
+ uint32 PAD[2];
+
+ uint32 seci_uart_data; /* 0x1C0 */
+ uint32 seci_uart_bauddiv;
+ uint32 seci_uart_fcr;
+ uint32 seci_uart_lcr;
+ uint32 seci_uart_mcr;
+ uint32 seci_uart_lsr;
+ uint32 seci_uart_msr;
+ uint32 seci_uart_baudadj;
+ /* Clock control and hardware workarounds (corerev >= 20) */
+ uint32 clk_ctl_st; /* 0x1e0 */
+ uint32 hw_war;
+ uint32 PAD[70];
+
+ /* UARTs */
+ uint8 uart0data; /* 0x300 */
+ uint8 uart0imr;
+ uint8 uart0fcr;
+ uint8 uart0lcr;
+ uint8 uart0mcr;
+ uint8 uart0lsr;
+ uint8 uart0msr;
+ uint8 uart0scratch;
+ uint8 PAD[248]; /* corerev >= 1 */
+
+ uint8 uart1data; /* 0x400 */
+ uint8 uart1imr;
+ uint8 uart1fcr;
+ uint8 uart1lcr;
+ uint8 uart1mcr;
+ uint8 uart1lsr;
+ uint8 uart1msr;
+ uint8 uart1scratch;
+ uint32 PAD[126];
+
+ /* PMU registers (corerev >= 20) */
+ /* Note: all timers driven by ILP clock are updated asynchronously to HT/ALP.
+ * The CPU must read them twice, compare, and retry if different.
+ */
+ uint32 pmucontrol; /* 0x600 */
+ uint32 pmucapabilities;
+ uint32 pmustatus;
+ uint32 res_state;
+ uint32 res_pending;
+ uint32 pmutimer;
+ uint32 min_res_mask;
+ uint32 max_res_mask;
+ uint32 res_table_sel;
+ uint32 res_dep_mask;
+ uint32 res_updn_timer;
+ uint32 res_timer;
+ uint32 clkstretch;
+ uint32 pmuwatchdog;
+ uint32 gpiosel; /* 0x638, rev >= 1 */
+ uint32 gpioenable; /* 0x63c, rev >= 1 */
+ uint32 res_req_timer_sel;
+ uint32 res_req_timer;
+ uint32 res_req_mask;
+ uint32 PAD;
+ uint32 chipcontrol_addr; /* 0x650 */
+ uint32 chipcontrol_data; /* 0x654 */
+ uint32 regcontrol_addr;
+ uint32 regcontrol_data;
+ uint32 pllcontrol_addr;
+ uint32 pllcontrol_data;
+ uint32 pmustrapopt; /* 0x668, corerev >= 28 */
+ uint32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */
+ uint32 retention_ctl; /* 0x670 */
+ uint32 PAD[3];
+ uint32 retention_grpidx; /* 0x680 */
+ uint32 retention_grpctl; /* 0x684 */
+ uint32 PAD[94];
+ uint16 sromotp[512]; /* 0x800 */
+#ifdef NFLASH_SUPPORT
+ /* Nand flash MLC controller registers (corerev >= 38) */
+ uint32 nand_revision; /* 0xC00 */
+ uint32 nand_cmd_start;
+ uint32 nand_cmd_addr_x;
+ uint32 nand_cmd_addr;
+ uint32 nand_cmd_end_addr;
+ uint32 nand_cs_nand_select;
+ uint32 nand_cs_nand_xor;
+ uint32 PAD;
+ uint32 nand_spare_rd0;
+ uint32 nand_spare_rd4;
+ uint32 nand_spare_rd8;
+ uint32 nand_spare_rd12;
+ uint32 nand_spare_wr0;
+ uint32 nand_spare_wr4;
+ uint32 nand_spare_wr8;
+ uint32 nand_spare_wr12;
+ uint32 nand_acc_control;
+ uint32 PAD;
+ uint32 nand_config;
+ uint32 PAD;
+ uint32 nand_timing_1;
+ uint32 nand_timing_2;
+ uint32 nand_semaphore;
+ uint32 PAD;
+ uint32 nand_devid;
+ uint32 nand_devid_x;
+ uint32 nand_block_lock_status;
+ uint32 nand_intfc_status;
+ uint32 nand_ecc_corr_addr_x;
+ uint32 nand_ecc_corr_addr;
+ uint32 nand_ecc_unc_addr_x;
+ uint32 nand_ecc_unc_addr;
+ uint32 nand_read_error_count;
+ uint32 nand_corr_stat_threshold;
+ uint32 PAD[2];
+ uint32 nand_read_addr_x;
+ uint32 nand_read_addr;
+ uint32 nand_page_program_addr_x;
+ uint32 nand_page_program_addr;
+ uint32 nand_copy_back_addr_x;
+ uint32 nand_copy_back_addr;
+ uint32 nand_block_erase_addr_x;
+ uint32 nand_block_erase_addr;
+ uint32 nand_inv_read_addr_x;
+ uint32 nand_inv_read_addr;
+ uint32 PAD[2];
+ uint32 nand_blk_wr_protect;
+ uint32 PAD[3];
+ uint32 nand_acc_control_cs1;
+ uint32 nand_config_cs1;
+ uint32 nand_timing_1_cs1;
+ uint32 nand_timing_2_cs1;
+ uint32 PAD[20];
+ uint32 nand_spare_rd16;
+ uint32 nand_spare_rd20;
+ uint32 nand_spare_rd24;
+ uint32 nand_spare_rd28;
+ uint32 nand_cache_addr;
+ uint32 nand_cache_data;
+ uint32 nand_ctrl_config;
+ uint32 nand_ctrl_status;
+#endif /* NFLASH_SUPPORT */
+ uint32 gci_corecaps0; /* GCI starting at 0xC00 */
+ uint32 gci_corecaps1;
+ uint32 gci_corecaps2;
+ uint32 gci_corectrl;
+ uint32 gci_corestat; /* 0xC10 */
+ uint32 PAD[11];
+ uint32 gci_indirect_addr; /* 0xC40 */
+ uint32 PAD[111];
+ uint32 gci_chipctrl; /* 0xE00 */
+} chipcregs_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+
+#define CC_CHIPID 0
+#define CC_CAPABILITIES 4
+#define CC_CHIPST 0x2c
+#define CC_EROMPTR 0xfc
+
+#define CC_OTPST 0x10
+#define CC_JTAGCMD 0x30
+#define CC_JTAGIR 0x34
+#define CC_JTAGDR 0x38
+#define CC_JTAGCTRL 0x3c
+#define CC_GPIOPU 0x58
+#define CC_GPIOPD 0x5c
+#define CC_GPIOIN 0x60
+#define CC_GPIOOUT 0x64
+#define CC_GPIOOUTEN 0x68
+#define CC_GPIOCTRL 0x6c
+#define CC_GPIOPOL 0x70
+#define CC_GPIOINTM 0x74
+#define CC_WATCHDOG 0x80
+#define CC_CLKC_N 0x90
+#define CC_CLKC_M0 0x94
+#define CC_CLKC_M1 0x98
+#define CC_CLKC_M2 0x9c
+#define CC_CLKC_M3 0xa0
+#define CC_CLKDIV 0xa4
+#define CC_SYS_CLK_CTL 0xc0
+#define CC_CLK_CTL_ST SI_CLK_CTL_ST
+#define PMU_CTL 0x600
+#define PMU_CAP 0x604
+#define PMU_ST 0x608
+#define PMU_RES_STATE 0x60c
+#define PMU_TIMER 0x614
+#define PMU_MIN_RES_MASK 0x618
+#define PMU_MAX_RES_MASK 0x61c
+#define CC_CHIPCTL_ADDR 0x650
+#define CC_CHIPCTL_DATA 0x654
+#define PMU_REG_CONTROL_ADDR 0x658
+#define PMU_REG_CONTROL_DATA 0x65C
+#define PMU_PLL_CONTROL_ADDR 0x660
+#define PMU_PLL_CONTROL_DATA 0x664
+#define CC_SROM_OTP 0x800 /* SROM/OTP address space */
+#define CC_GCI_INDIRECT_ADDR_REG 0xC40
+#define CC_GCI_CHIP_CTRL_REG 0xE00
+#define CC_GCI_CC_OFFSET_2 2
+#define CC_GCI_CC_OFFSET_5 5
+
+#ifdef NFLASH_SUPPORT
+/* NAND flash support */
+#define CC_NAND_REVISION 0xC00
+#define CC_NAND_CMD_START 0xC04
+#define CC_NAND_CMD_ADDR 0xC0C
+#define CC_NAND_SPARE_RD_0 0xC20
+#define CC_NAND_SPARE_RD_4 0xC24
+#define CC_NAND_SPARE_RD_8 0xC28
+#define CC_NAND_SPARE_RD_C 0xC2C
+#define CC_NAND_CONFIG 0xC48
+#define CC_NAND_DEVID 0xC60
+#define CC_NAND_DEVID_EXT 0xC64
+#define CC_NAND_INTFC_STATUS 0xC6C
+#endif /* NFLASH_SUPPORT */
+
+/* chipid */
+#define CID_ID_MASK 0x0000ffff /* Chip Id mask */
+#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */
+#define CID_REV_SHIFT 16 /* Chip Revision shift */
+#define CID_PKG_MASK 0x00f00000 /* Package Option mask */
+#define CID_PKG_SHIFT 20 /* Package Option shift */
+#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */
+#define CID_CC_SHIFT 24
+#define CID_TYPE_MASK 0xf0000000 /* Chip Type */
+#define CID_TYPE_SHIFT 28
+
+/* capabilities */
+#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */
+#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
+#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */
+#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */
+#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */
+#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */
+#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */
+#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */
+#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */
+#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */
+#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */
+#define CC_CAP_PWR_CTL 0x00040000 /* Power control */
+#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
+#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
+#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */
+#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */
+#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */
+#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */
+#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */
+#define CC_CAP_ECI 0x20000000 /* ECI Present, rev >= 21 */
+#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */
+#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */
+
+#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */
+#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */
+
+/* capabilities extension */
+#define CC_CAP_EXT_SECI_PRESENT 0x00000001 /* SECI present */
+
+/* PLL type */
+#define PLL_NONE 0x00000000
+#define PLL_TYPE1 0x00010000 /* 48MHz base, 3 dividers */
+#define PLL_TYPE2 0x00020000 /* 48MHz, 4 dividers */
+#define PLL_TYPE3 0x00030000 /* 25MHz, 2 dividers */
+#define PLL_TYPE4 0x00008000 /* 48MHz, 4 dividers */
+#define PLL_TYPE5 0x00018000 /* 25MHz, 4 dividers */
+#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */
+#define PLL_TYPE7 0x00038000 /* 25MHz, 4 dividers */
+
+/* ILP clock */
+#define ILP_CLOCK 32000
+
+/* ALP clock on pre-PMU chips */
+#define ALP_CLOCK 20000000
+
+/* HT clock */
+#define HT_CLOCK 80000000
+
+/* corecontrol */
+#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */
+#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
+#define CC_ASYNCGPIO 0x00000004 /* 1=generate GPIO interrupt without backplane clock */
+#define CC_UARTCLKEN 0x00000008 /* enable UART Clock (corerev > = 21 */
+
+/* 4321 chipcontrol */
+#define CHIPCTRL_4321A0_DEFAULT 0x3a4
+#define CHIPCTRL_4321A1_DEFAULT 0x0a4
+#define CHIPCTRL_4321_PLL_DOWN 0x800000 /* serdes PLL down override */
+
+/* Fields in the otpstatus register in rev >= 21 */
+#define OTPS_OL_MASK 0x000000ff
+#define OTPS_OL_MFG 0x00000001 /* manuf row is locked */
+#define OTPS_OL_OR1 0x00000002 /* otp redundancy row 1 is locked */
+#define OTPS_OL_OR2 0x00000004 /* otp redundancy row 2 is locked */
+#define OTPS_OL_GU 0x00000008 /* general use region is locked */
+#define OTPS_GUP_MASK 0x00000f00
+#define OTPS_GUP_SHIFT 8
+#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */
+#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */
+#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */
+#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */
+#define OTPS_READY 0x00001000
+#define OTPS_RV(x) (1 << (16 + (x))) /* redundancy entry valid */
+#define OTPS_RV_MASK 0x0fff0000
+#define OTPS_PROGOK 0x40000000
+
+/* Fields in the otpcontrol register in rev >= 21 */
+#define OTPC_PROGSEL 0x00000001
+#define OTPC_PCOUNT_MASK 0x0000000e
+#define OTPC_PCOUNT_SHIFT 1
+#define OTPC_VSEL_MASK 0x000000f0
+#define OTPC_VSEL_SHIFT 4
+#define OTPC_TMM_MASK 0x00000700
+#define OTPC_TMM_SHIFT 8
+#define OTPC_ODM 0x00000800
+#define OTPC_PROGEN 0x80000000
+
+/* Fields in the 40nm otpcontrol register in rev >= 40 */
+#define OTPC_40NM_PROGSEL_SHIFT 0
+#define OTPC_40NM_PCOUNT_SHIFT 1
+#define OTPC_40NM_PCOUNT_WR 0xA
+#define OTPC_40NM_PCOUNT_V1X 0xB
+#define OTPC_40NM_REGCSEL_SHIFT 5
+#define OTPC_40NM_REGCSEL_DEF 0x4
+#define OTPC_40NM_PROGIN_SHIFT 8
+#define OTPC_40NM_R2X_SHIFT 10
+#define OTPC_40NM_ODM_SHIFT 11
+#define OTPC_40NM_DF_SHIFT 15
+#define OTPC_40NM_VSEL_SHIFT 16
+#define OTPC_40NM_VSEL_WR 0xA
+#define OTPC_40NM_VSEL_V1X 0xA
+#define OTPC_40NM_VSEL_R1X 0x5
+#define OTPC_40NM_COFAIL_SHIFT 30
+
+#define OTPC1_CPCSEL_SHIFT 0
+#define OTPC1_CPCSEL_DEF 6
+#define OTPC1_TM_SHIFT 8
+#define OTPC1_TM_WR 0x84
+#define OTPC1_TM_V1X 0x84
+#define OTPC1_TM_R1X 0x4
+
+/* Fields in otpprog in rev >= 21 and HND OTP */
+#define OTPP_COL_MASK 0x000000ff
+#define OTPP_COL_SHIFT 0
+#define OTPP_ROW_MASK 0x0000ff00
+#define OTPP_ROW_SHIFT 8
+#define OTPP_OC_MASK 0x0f000000
+#define OTPP_OC_SHIFT 24
+#define OTPP_READERR 0x10000000
+#define OTPP_VALUE_MASK 0x20000000
+#define OTPP_VALUE_SHIFT 29
+#define OTPP_START_BUSY 0x80000000
+#define OTPP_READ 0x40000000 /* HND OTP */
+
+/* Fields in otplayout register */
+#define OTPL_HWRGN_OFF_MASK 0x00000FFF
+#define OTPL_HWRGN_OFF_SHIFT 0
+#define OTPL_WRAP_REVID_MASK 0x00F80000
+#define OTPL_WRAP_REVID_SHIFT 19
+#define OTPL_WRAP_TYPE_MASK 0x00070000
+#define OTPL_WRAP_TYPE_SHIFT 16
+#define OTPL_WRAP_TYPE_65NM 0
+#define OTPL_WRAP_TYPE_40NM 1
+
+/* otplayout reg corerev >= 36 */
+#define OTP_CISFORMAT_NEW 0x80000000
+
+/* Opcodes for OTPP_OC field */
+#define OTPPOC_READ 0
+#define OTPPOC_BIT_PROG 1
+#define OTPPOC_VERIFY 3
+#define OTPPOC_INIT 4
+#define OTPPOC_SET 5
+#define OTPPOC_RESET 6
+#define OTPPOC_OCST 7
+#define OTPPOC_ROW_LOCK 8
+#define OTPPOC_PRESCN_TEST 9
+
+/* Opcodes for OTPP_OC field (40NM) */
+#define OTPPOC_READ_40NM 0
+#define OTPPOC_PROG_ENABLE_40NM 1
+#define OTPPOC_PROG_DISABLE_40NM 2
+#define OTPPOC_VERIFY_40NM 3
+#define OTPPOC_WORD_VERIFY_1_40NM 4
+#define OTPPOC_ROW_LOCK_40NM 5
+#define OTPPOC_STBY_40NM 6
+#define OTPPOC_WAKEUP_40NM 7
+#define OTPPOC_WORD_VERIFY_0_40NM 8
+#define OTPPOC_PRESCN_TEST_40NM 9
+#define OTPPOC_BIT_PROG_40NM 10
+#define OTPPOC_WORDPROG_40NM 11
+#define OTPPOC_BURNIN_40NM 12
+#define OTPPOC_AUTORELOAD_40NM 13
+#define OTPPOC_OVST_READ_40NM 14
+#define OTPPOC_OVST_PROG_40NM 15
+
+/* Fields in otplayoutextension */
+#define OTPLAYOUTEXT_FUSE_MASK 0x3FF
+
+
+/* Jtagm characteristics that appeared at a given corerev */
+#define JTAGM_CREV_OLD 10 /* Old command set, 16bit max IR */
+#define JTAGM_CREV_IRP 22 /* Able to do pause-ir */
+#define JTAGM_CREV_RTI 28 /* Able to do return-to-idle */
+
+/* jtagcmd */
+#define JCMD_START 0x80000000
+#define JCMD_BUSY 0x80000000
+#define JCMD_STATE_MASK 0x60000000
+#define JCMD_STATE_TLR 0x00000000 /* Test-logic-reset */
+#define JCMD_STATE_PIR 0x20000000 /* Pause IR */
+#define JCMD_STATE_PDR 0x40000000 /* Pause DR */
+#define JCMD_STATE_RTI 0x60000000 /* Run-test-idle */
+#define JCMD0_ACC_MASK 0x0000f000
+#define JCMD0_ACC_IRDR 0x00000000
+#define JCMD0_ACC_DR 0x00001000
+#define JCMD0_ACC_IR 0x00002000
+#define JCMD0_ACC_RESET 0x00003000
+#define JCMD0_ACC_IRPDR 0x00004000
+#define JCMD0_ACC_PDR 0x00005000
+#define JCMD0_IRW_MASK 0x00000f00
+#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */
+#define JCMD_ACC_IRDR 0x00000000
+#define JCMD_ACC_DR 0x00010000
+#define JCMD_ACC_IR 0x00020000
+#define JCMD_ACC_RESET 0x00030000
+#define JCMD_ACC_IRPDR 0x00040000
+#define JCMD_ACC_PDR 0x00050000
+#define JCMD_ACC_PIR 0x00060000
+#define JCMD_ACC_IRDR_I 0x00070000 /* rev 28: return to run-test-idle */
+#define JCMD_ACC_DR_I 0x00080000 /* rev 28: return to run-test-idle */
+#define JCMD_IRW_MASK 0x00001f00
+#define JCMD_IRW_SHIFT 8
+#define JCMD_DRW_MASK 0x0000003f
+
+/* jtagctrl */
+#define JCTRL_FORCE_CLK 4 /* Force clock */
+#define JCTRL_EXT_EN 2 /* Enable external targets */
+#define JCTRL_EN 1 /* Enable Jtag master */
+
+/* Fields in clkdiv */
+#define CLKD_SFLASH 0x0f000000
+#define CLKD_SFLASH_SHIFT 24
+#define CLKD_OTP 0x000f0000
+#define CLKD_OTP_SHIFT 16
+#define CLKD_JTAG 0x00000f00
+#define CLKD_JTAG_SHIFT 8
+#define CLKD_UART 0x000000ff
+
+#define CLKD2_SROM 0x00000003
+
+/* intstatus/intmask */
+#define CI_GPIO 0x00000001 /* gpio intr */
+#define CI_EI 0x00000002 /* extif intr (corerev >= 3) */
+#define CI_TEMP 0x00000004 /* temp. ctrl intr (corerev >= 15) */
+#define CI_SIRQ 0x00000008 /* serial IRQ intr (corerev >= 15) */
+#define CI_ECI 0x00000010 /* eci intr (corerev >= 21) */
+#define CI_PMU 0x00000020 /* pmu intr (corerev >= 21) */
+#define CI_UART 0x00000040 /* uart intr (corerev >= 21) */
+#define CI_WDRESET 0x80000000 /* watchdog reset occurred */
+
+/* slow_clk_ctl */
+#define SCC_SS_MASK 0x00000007 /* slow clock source mask */
+#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */
+#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */
+#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */
+#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
+#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled,
+ * 0: LPO is enabled
+ */
+#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock,
+ * 0: power logic control
+ */
+#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors
+ * PLL clock disable requests from core
+ */
+#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't
+ * disable crystal when appropriate
+ */
+#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
+#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
+#define SCC_CD_SHIFT 16
+
+/* system_clk_ctl */
+#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */
+#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */
+#define SYCC_FP 0x00000004 /* ForcePLLOn */
+#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */
+#define SYCC_HR 0x00000010 /* Force HT */
+#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */
+#define SYCC_CD_SHIFT 16
+
+/* Indirect backplane access */
+#define BPIA_BYTEEN 0x0000000f
+#define BPIA_SZ1 0x00000001
+#define BPIA_SZ2 0x00000003
+#define BPIA_SZ4 0x00000007
+#define BPIA_SZ8 0x0000000f
+#define BPIA_WRITE 0x00000100
+#define BPIA_START 0x00000200
+#define BPIA_BUSY 0x00000200
+#define BPIA_ERROR 0x00000400
+
+/* pcmcia/prog/flash_config */
+#define CF_EN 0x00000001 /* enable */
+#define CF_EM_MASK 0x0000000e /* mode */
+#define CF_EM_SHIFT 1
+#define CF_EM_FLASH 0 /* flash/asynchronous mode */
+#define CF_EM_SYNC 2 /* synchronous mode */
+#define CF_EM_PCMCIA 4 /* pcmcia mode */
+#define CF_DS 0x00000010 /* destsize: 0=8bit, 1=16bit */
+#define CF_BS 0x00000020 /* byteswap */
+#define CF_CD_MASK 0x000000c0 /* clock divider */
+#define CF_CD_SHIFT 6
+#define CF_CD_DIV2 0x00000000 /* backplane/2 */
+#define CF_CD_DIV3 0x00000040 /* backplane/3 */
+#define CF_CD_DIV4 0x00000080 /* backplane/4 */
+#define CF_CE 0x00000100 /* clock enable */
+#define CF_SB 0x00000200 /* size/bytestrobe (synch only) */
+
+/* pcmcia_memwait */
+#define PM_W0_MASK 0x0000003f /* waitcount0 */
+#define PM_W1_MASK 0x00001f00 /* waitcount1 */
+#define PM_W1_SHIFT 8
+#define PM_W2_MASK 0x001f0000 /* waitcount2 */
+#define PM_W2_SHIFT 16
+#define PM_W3_MASK 0x1f000000 /* waitcount3 */
+#define PM_W3_SHIFT 24
+
+/* pcmcia_attrwait */
+#define PA_W0_MASK 0x0000003f /* waitcount0 */
+#define PA_W1_MASK 0x00001f00 /* waitcount1 */
+#define PA_W1_SHIFT 8
+#define PA_W2_MASK 0x001f0000 /* waitcount2 */
+#define PA_W2_SHIFT 16
+#define PA_W3_MASK 0x1f000000 /* waitcount3 */
+#define PA_W3_SHIFT 24
+
+/* pcmcia_iowait */
+#define PI_W0_MASK 0x0000003f /* waitcount0 */
+#define PI_W1_MASK 0x00001f00 /* waitcount1 */
+#define PI_W1_SHIFT 8
+#define PI_W2_MASK 0x001f0000 /* waitcount2 */
+#define PI_W2_SHIFT 16
+#define PI_W3_MASK 0x1f000000 /* waitcount3 */
+#define PI_W3_SHIFT 24
+
+/* prog_waitcount */
+#define PW_W0_MASK 0x0000001f /* waitcount0 */
+#define PW_W1_MASK 0x00001f00 /* waitcount1 */
+#define PW_W1_SHIFT 8
+#define PW_W2_MASK 0x001f0000 /* waitcount2 */
+#define PW_W2_SHIFT 16
+#define PW_W3_MASK 0x1f000000 /* waitcount3 */
+#define PW_W3_SHIFT 24
+
+#define PW_W0 0x0000000c
+#define PW_W1 0x00000a00
+#define PW_W2 0x00020000
+#define PW_W3 0x01000000
+
+/* flash_waitcount */
+#define FW_W0_MASK 0x0000003f /* waitcount0 */
+#define FW_W1_MASK 0x00001f00 /* waitcount1 */
+#define FW_W1_SHIFT 8
+#define FW_W2_MASK 0x001f0000 /* waitcount2 */
+#define FW_W2_SHIFT 16
+#define FW_W3_MASK 0x1f000000 /* waitcount3 */
+#define FW_W3_SHIFT 24
+
+/* When Srom support present, fields in sromcontrol */
+#define SRC_START 0x80000000
+#define SRC_BUSY 0x80000000
+#define SRC_OPCODE 0x60000000
+#define SRC_OP_READ 0x00000000
+#define SRC_OP_WRITE 0x20000000
+#define SRC_OP_WRDIS 0x40000000
+#define SRC_OP_WREN 0x60000000
+#define SRC_OTPSEL 0x00000010
+#define SRC_LOCK 0x00000008
+#define SRC_SIZE_MASK 0x00000006
+#define SRC_SIZE_1K 0x00000000
+#define SRC_SIZE_4K 0x00000002
+#define SRC_SIZE_16K 0x00000004
+#define SRC_SIZE_SHIFT 1
+#define SRC_PRESENT 0x00000001
+
+/* Fields in pmucontrol */
+#define PCTL_ILP_DIV_MASK 0xffff0000
+#define PCTL_ILP_DIV_SHIFT 16
+#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */
+#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */
+#define PCTL_HT_REQ_EN 0x00000100
+#define PCTL_ALP_REQ_EN 0x00000080
+#define PCTL_XTALFREQ_MASK 0x0000007c
+#define PCTL_XTALFREQ_SHIFT 2
+#define PCTL_ILP_DIV_EN 0x00000002
+#define PCTL_LPO_SEL 0x00000001
+
+/* Fields in clkstretch */
+#define CSTRETCH_HT 0xffff0000
+#define CSTRETCH_ALP 0x0000ffff
+
+/* gpiotimerval */
+#define GPIO_ONTIME_SHIFT 16
+
+/* clockcontrol_n */
+#define CN_N1_MASK 0x3f /* n1 control */
+#define CN_N2_MASK 0x3f00 /* n2 control */
+#define CN_N2_SHIFT 8
+#define CN_PLLC_MASK 0xf0000 /* pll control */
+#define CN_PLLC_SHIFT 16
+
+/* clockcontrol_sb/pci/uart */
+#define CC_M1_MASK 0x3f /* m1 control */
+#define CC_M2_MASK 0x3f00 /* m2 control */
+#define CC_M2_SHIFT 8
+#define CC_M3_MASK 0x3f0000 /* m3 control */
+#define CC_M3_SHIFT 16
+#define CC_MC_MASK 0x1f000000 /* mux control */
+#define CC_MC_SHIFT 24
+
+/* N3M Clock control magic field values */
+#define CC_F6_2 0x02 /* A factor of 2 in */
+#define CC_F6_3 0x03 /* 6-bit fields like */
+#define CC_F6_4 0x05 /* N1, M1 or M3 */
+#define CC_F6_5 0x09
+#define CC_F6_6 0x11
+#define CC_F6_7 0x21
+
+#define CC_F5_BIAS 5 /* 5-bit fields get this added */
+
+#define CC_MC_BYPASS 0x08
+#define CC_MC_M1 0x04
+#define CC_MC_M1M2 0x02
+#define CC_MC_M1M2M3 0x01
+#define CC_MC_M1M3 0x11
+
+/* Type 2 Clock control magic field values */
+#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */
+#define CC_T2M2_BIAS 3 /* m2 bias */
+
+#define CC_T2MC_M1BYP 1
+#define CC_T2MC_M2BYP 2
+#define CC_T2MC_M3BYP 4
+
+/* Type 6 Clock control magic field values */
+#define CC_T6_MMASK 1 /* bits of interest in m */
+#define CC_T6_M0 120000000 /* sb clock for m = 0 */
+#define CC_T6_M1 100000000 /* sb clock for m = 1 */
+#define SB2MIPS_T6(sb) (2 * (sb))
+
+/* Common clock base */
+#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */
+#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLLs */
+
+/* Clock control values for 200MHz in 5350 */
+#define CLKC_5350_N 0x0311
+#define CLKC_5350_M 0x04020009
+
+/* Flash types in the chipcommon capabilities register */
+#define FLASH_NONE 0x000 /* No flash */
+#define SFLASH_ST 0x100 /* ST serial flash */
+#define SFLASH_AT 0x200 /* Atmel serial flash */
+#define NFLASH 0x300
+#define PFLASH 0x700 /* Parallel flash */
+
+/* Bits in the ExtBus config registers */
+#define CC_CFG_EN 0x0001 /* Enable */
+#define CC_CFG_EM_MASK 0x000e /* Extif Mode */
+#define CC_CFG_EM_ASYNC 0x0000 /* Async/Parallel flash */
+#define CC_CFG_EM_SYNC 0x0002 /* Synchronous */
+#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */
+#define CC_CFG_EM_IDE 0x0006 /* IDE */
+#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
+#define CC_CFG_CD_MASK 0x00e0 /* Sync: Clock divisor, rev >= 20 */
+#define CC_CFG_CE 0x0100 /* Sync: Clock enable, rev >= 20 */
+#define CC_CFG_SB 0x0200 /* Sync: Size/Bytestrobe, rev >= 20 */
+#define CC_CFG_IS 0x0400 /* Extif Sync Clk Select, rev >= 20 */
+
+/* ExtBus address space */
+#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */
+#define CC_EB_PCMCIA_MEM 0x1a000000 /* PCMCIA 0 memory base address */
+#define CC_EB_PCMCIA_IO 0x1a200000 /* PCMCIA 0 I/O base address */
+#define CC_EB_PCMCIA_CFG 0x1a400000 /* PCMCIA 0 config base address */
+#define CC_EB_IDE 0x1a800000 /* IDE memory base */
+#define CC_EB_PCMCIA1_MEM 0x1a800000 /* PCMCIA 1 memory base address */
+#define CC_EB_PCMCIA1_IO 0x1aa00000 /* PCMCIA 1 I/O base address */
+#define CC_EB_PCMCIA1_CFG 0x1ac00000 /* PCMCIA 1 config base address */
+#define CC_EB_PROGIF 0x1b000000 /* ProgIF Async/Sync base address */
+
+
+/* Start/busy bit in flashcontrol */
+#define SFLASH_OPCODE 0x000000ff
+#define SFLASH_ACTION 0x00000700
+#define SFLASH_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */
+#define SFLASH_START 0x80000000
+#define SFLASH_BUSY SFLASH_START
+
+/* flashcontrol action codes */
+#define SFLASH_ACT_OPONLY 0x0000 /* Issue opcode only */
+#define SFLASH_ACT_OP1D 0x0100 /* opcode + 1 data byte */
+#define SFLASH_ACT_OP3A 0x0200 /* opcode + 3 addr bytes */
+#define SFLASH_ACT_OP3A1D 0x0300 /* opcode + 3 addr & 1 data bytes */
+#define SFLASH_ACT_OP3A4D 0x0400 /* opcode + 3 addr & 4 data bytes */
+#define SFLASH_ACT_OP3A4X4D 0x0500 /* opcode + 3 addr, 4 don't care & 4 data bytes */
+#define SFLASH_ACT_OP3A1X4D 0x0700 /* opcode + 3 addr, 1 don't care & 4 data bytes */
+
+/* flashcontrol action+opcodes for ST flashes */
+#define SFLASH_ST_WREN 0x0006 /* Write Enable */
+#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */
+#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */
+#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */
+#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */
+#define SFLASH_ST_PP 0x0302 /* Page Program */
+#define SFLASH_ST_SE 0x02d8 /* Sector Erase */
+#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */
+#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */
+#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */
+#define SFLASH_ST_CSA 0x1000 /* Keep chip select asserted */
+#define SFLASH_ST_SSE 0x0220 /* Sub-sector Erase */
+
+#define SFLASH_MXIC_RDID 0x0390 /* Read Manufacture ID */
+#define SFLASH_MXIC_MFID 0xc2 /* MXIC Manufacture ID */
+
+/* Status register bits for ST flashes */
+#define SFLASH_ST_WIP 0x01 /* Write In Progress */
+#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */
+#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */
+#define SFLASH_ST_BP_SHIFT 2
+#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */
+
+/* flashcontrol action+opcodes for Atmel flashes */
+#define SFLASH_AT_READ 0x07e8
+#define SFLASH_AT_PAGE_READ 0x07d2
+#define SFLASH_AT_BUF1_READ
+#define SFLASH_AT_BUF2_READ
+#define SFLASH_AT_STATUS 0x01d7
+#define SFLASH_AT_BUF1_WRITE 0x0384
+#define SFLASH_AT_BUF2_WRITE 0x0387
+#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283
+#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286
+#define SFLASH_AT_BUF1_PROGRAM 0x0288
+#define SFLASH_AT_BUF2_PROGRAM 0x0289
+#define SFLASH_AT_PAGE_ERASE 0x0281
+#define SFLASH_AT_BLOCK_ERASE 0x0250
+#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382
+#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385
+#define SFLASH_AT_BUF1_LOAD 0x0253
+#define SFLASH_AT_BUF2_LOAD 0x0255
+#define SFLASH_AT_BUF1_COMPARE 0x0260
+#define SFLASH_AT_BUF2_COMPARE 0x0261
+#define SFLASH_AT_BUF1_REPROGRAM 0x0258
+#define SFLASH_AT_BUF2_REPROGRAM 0x0259
+
+/* Status register bits for Atmel flashes */
+#define SFLASH_AT_READY 0x80
+#define SFLASH_AT_MISMATCH 0x40
+#define SFLASH_AT_ID_MASK 0x38
+#define SFLASH_AT_ID_SHIFT 3
+
+/* SPI register bits, corerev >= 37 */
+#define GSIO_START 0x80000000
+#define GSIO_BUSY GSIO_START
+
+/*
+ * These are the UART port assignments, expressed as offsets from the base
+ * register. These assignments should hold for any serial port based on
+ * a 8250, 16450, or 16550(A).
+ */
+
+#define UART_RX 0 /* In: Receive buffer (DLAB=0) */
+#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
+#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
+#define UART_IER 1 /* In/Out: Interrupt Enable Register (DLAB=0) */
+#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
+#define UART_IIR 2 /* In: Interrupt Identity Register */
+#define UART_FCR 2 /* Out: FIFO Control Register */
+#define UART_LCR 3 /* Out: Line Control Register */
+#define UART_MCR 4 /* Out: Modem Control Register */
+#define UART_LSR 5 /* In: Line Status Register */
+#define UART_MSR 6 /* In: Modem Status Register */
+#define UART_SCR 7 /* I/O: Scratch Register */
+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
+#define UART_LCR_WLEN8 0x03 /* Word length: 8 bits */
+#define UART_MCR_OUT2 0x08 /* MCR GPIO out 2 */
+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
+#define UART_LSR_RX_FIFO 0x80 /* Receive FIFO error */
+#define UART_LSR_TDHR 0x40 /* Data-hold-register empty */
+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
+#define UART_LSR_BREAK 0x10 /* Break interrupt */
+#define UART_LSR_FRAMING 0x08 /* Framing error */
+#define UART_LSR_PARITY 0x04 /* Parity error */
+#define UART_LSR_OVERRUN 0x02 /* Overrun error */
+#define UART_LSR_RXRDY 0x01 /* Receiver ready */
+#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */
+
+/* Interrupt Identity Register (IIR) bits */
+#define UART_IIR_FIFO_MASK 0xc0 /* IIR FIFO disable/enabled mask */
+#define UART_IIR_INT_MASK 0xf /* IIR interrupt ID source */
+#define UART_IIR_MDM_CHG 0x0 /* Modem status changed */
+#define UART_IIR_NOINT 0x1 /* No interrupt pending */
+#define UART_IIR_THRE 0x2 /* THR empty */
+#define UART_IIR_RCVD_DATA 0x4 /* Received data available */
+#define UART_IIR_RCVR_STATUS 0x6 /* Receiver status */
+#define UART_IIR_CHAR_TIME 0xc /* Character time */
+
+/* Interrupt Enable Register (IER) bits */
+#define UART_IER_EDSSI 8 /* enable modem status interrupt */
+#define UART_IER_ELSI 4 /* enable receiver line status interrupt */
+#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */
+#define UART_IER_ERBFI 1 /* enable data available interrupt */
+
+/* pmustatus */
+#define PST_EXTLPOAVAIL 0x0100
+#define PST_WDRESET 0x0080
+#define PST_INTPEND 0x0040
+#define PST_SBCLKST 0x0030
+#define PST_SBCLKST_ILP 0x0010
+#define PST_SBCLKST_ALP 0x0020
+#define PST_SBCLKST_HT 0x0030
+#define PST_ALPAVAIL 0x0008
+#define PST_HTAVAIL 0x0004
+#define PST_RESINIT 0x0003
+
+/* pmucapabilities */
+#define PCAP_REV_MASK 0x000000ff
+#define PCAP_RC_MASK 0x00001f00
+#define PCAP_RC_SHIFT 8
+#define PCAP_TC_MASK 0x0001e000
+#define PCAP_TC_SHIFT 13
+#define PCAP_PC_MASK 0x001e0000
+#define PCAP_PC_SHIFT 17
+#define PCAP_VC_MASK 0x01e00000
+#define PCAP_VC_SHIFT 21
+#define PCAP_CC_MASK 0x1e000000
+#define PCAP_CC_SHIFT 25
+#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */
+#define PCAP5_PC_SHIFT 17
+#define PCAP5_VC_MASK 0x07c00000
+#define PCAP5_VC_SHIFT 22
+#define PCAP5_CC_MASK 0xf8000000
+#define PCAP5_CC_SHIFT 27
+
+/* PMU Resource Request Timer registers */
+/* This is based on PmuRev0 */
+#define PRRT_TIME_MASK 0x03ff
+#define PRRT_INTEN 0x0400
+#define PRRT_REQ_ACTIVE 0x0800
+#define PRRT_ALP_REQ 0x1000
+#define PRRT_HT_REQ 0x2000
+#define PRRT_HQ_REQ 0x4000
+
+/* PMU resource bit position */
+#define PMURES_BIT(bit) (1 << (bit))
+
+/* PMU resource number limit */
+#define PMURES_MAX_RESNUM 30
+
+/* PMU chip control0 register */
+#define PMU_CHIPCTL0 0
+
+/* clock req types */
+#define PMU_CC1_CLKREQ_TYPE_SHIFT 19
+#define PMU_CC1_CLKREQ_TYPE_MASK (1 << PMU_CC1_CLKREQ_TYPE_SHIFT)
+
+#define CLKREQ_TYPE_CONFIG_OPENDRAIN 0
+#define CLKREQ_TYPE_CONFIG_PUSHPULL 1
+
+/* PMU chip control1 register */
+#define PMU_CHIPCTL1 1
+#define PMU_CC1_RXC_DLL_BYPASS 0x00010000
+
+#define PMU_CC1_IF_TYPE_MASK 0x00000030
+#define PMU_CC1_IF_TYPE_RMII 0x00000000
+#define PMU_CC1_IF_TYPE_MII 0x00000010
+#define PMU_CC1_IF_TYPE_RGMII 0x00000020
+
+#define PMU_CC1_SW_TYPE_MASK 0x000000c0
+#define PMU_CC1_SW_TYPE_EPHY 0x00000000
+#define PMU_CC1_SW_TYPE_EPHYMII 0x00000040
+#define PMU_CC1_SW_TYPE_EPHYRMII 0x00000080
+#define PMU_CC1_SW_TYPE_RGMII 0x000000c0
+
+/* PMU chip control2 register */
+#define PMU_CHIPCTL2 2
+
+/* PMU chip control3 register */
+#define PMU_CHIPCTL3 3
+
+#define PMU_CC3_ENABLE_SDIO_WAKEUP_SHIFT 19
+#define PMU_CC3_ENABLE_RF_SHIFT 22
+#define PMU_CC3_RF_DISABLE_IVALUE_SHIFT 23
+
+
+/* PMU corerev and chip specific PLL controls.
+ * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number
+ * to differentiate different PLLs controlled by the same PMU rev.
+ */
+/* pllcontrol registers */
+/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */
+#define PMU0_PLL0_PLLCTL0 0
+#define PMU0_PLL0_PC0_PDIV_MASK 1
+#define PMU0_PLL0_PC0_PDIV_FREQ 25000
+#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038
+#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3
+#define PMU0_PLL0_PC0_DIV_ARM_BASE 8
+
+/* PC0_DIV_ARM for PLLOUT_ARM */
+#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0
+#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1
+#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2
+#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 /* Default */
+#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4
+#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5
+#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6
+#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7
+
+/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */
+#define PMU0_PLL0_PLLCTL1 1
+#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000
+#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28
+#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00
+#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8
+#define PMU0_PLL0_PC1_STOP_MOD 0x00000040
+
+/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */
+#define PMU0_PLL0_PLLCTL2 2
+#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf
+#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4
+
+/* pllcontrol registers */
+/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
+#define PMU1_PLL0_PLLCTL0 0
+#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000
+#define PMU1_PLL0_PC0_P1DIV_SHIFT 20
+#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000
+#define PMU1_PLL0_PC0_P2DIV_SHIFT 24
+
+/* m<x>div */
+#define PMU1_PLL0_PLLCTL1 1
+#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff
+#define PMU1_PLL0_PC1_M1DIV_SHIFT 0
+#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00
+#define PMU1_PLL0_PC1_M2DIV_SHIFT 8
+#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000
+#define PMU1_PLL0_PC1_M3DIV_SHIFT 16
+#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000
+#define PMU1_PLL0_PC1_M4DIV_SHIFT 24
+#define PMU1_PLL0_PC1_M4DIV_BY_9 9
+#define PMU1_PLL0_PC1_M4DIV_BY_18 0x12
+#define PMU1_PLL0_PC1_M4DIV_BY_36 0x24
+
+#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8
+#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
+#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
+
+/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+#define PMU1_PLL0_PLLCTL2 2
+#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff
+#define PMU1_PLL0_PC2_M5DIV_SHIFT 0
+#define PMU1_PLL0_PC2_M5DIV_BY_12 0xc
+#define PMU1_PLL0_PC2_M5DIV_BY_18 0x12
+#define PMU1_PLL0_PC2_M5DIV_BY_36 0x24
+#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00
+#define PMU1_PLL0_PC2_M6DIV_SHIFT 8
+#define PMU1_PLL0_PC2_M6DIV_BY_18 0x12
+#define PMU1_PLL0_PC2_M6DIV_BY_36 0x24
+#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000
+#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17
+#define PMU1_PLL0_PC2_NDIV_MODE_MASH 1
+#define PMU1_PLL0_PC2_NDIV_MODE_MFB 2 /* recommended for 4319 */
+#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000
+#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20
+
+/* ndiv_frac */
+#define PMU1_PLL0_PLLCTL3 3
+#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff
+#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0
+
+/* pll_ctrl */
+#define PMU1_PLL0_PLLCTL4 4
+
+/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+#define PMU1_PLL0_PLLCTL5 5
+#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00
+#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8
+
+/* PMU rev 2 control words */
+#define PMU2_PHY_PLL_PLLCTL 4
+#define PMU2_SI_PLL_PLLCTL 10
+
+/* PMU rev 2 */
+/* pllcontrol registers */
+/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
+#define PMU2_PLL_PLLCTL0 0
+#define PMU2_PLL_PC0_P1DIV_MASK 0x00f00000
+#define PMU2_PLL_PC0_P1DIV_SHIFT 20
+#define PMU2_PLL_PC0_P2DIV_MASK 0x0f000000
+#define PMU2_PLL_PC0_P2DIV_SHIFT 24
+
+/* m<x>div */
+#define PMU2_PLL_PLLCTL1 1
+#define PMU2_PLL_PC1_M1DIV_MASK 0x000000ff
+#define PMU2_PLL_PC1_M1DIV_SHIFT 0
+#define PMU2_PLL_PC1_M2DIV_MASK 0x0000ff00
+#define PMU2_PLL_PC1_M2DIV_SHIFT 8
+#define PMU2_PLL_PC1_M3DIV_MASK 0x00ff0000
+#define PMU2_PLL_PC1_M3DIV_SHIFT 16
+#define PMU2_PLL_PC1_M4DIV_MASK 0xff000000
+#define PMU2_PLL_PC1_M4DIV_SHIFT 24
+
+/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+#define PMU2_PLL_PLLCTL2 2
+#define PMU2_PLL_PC2_M5DIV_MASK 0x000000ff
+#define PMU2_PLL_PC2_M5DIV_SHIFT 0
+#define PMU2_PLL_PC2_M6DIV_MASK 0x0000ff00
+#define PMU2_PLL_PC2_M6DIV_SHIFT 8
+#define PMU2_PLL_PC2_NDIV_MODE_MASK 0x000e0000
+#define PMU2_PLL_PC2_NDIV_MODE_SHIFT 17
+#define PMU2_PLL_PC2_NDIV_INT_MASK 0x1ff00000
+#define PMU2_PLL_PC2_NDIV_INT_SHIFT 20
+
+/* ndiv_frac */
+#define PMU2_PLL_PLLCTL3 3
+#define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff
+#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0
+
+/* pll_ctrl */
+#define PMU2_PLL_PLLCTL4 4
+
+/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+#define PMU2_PLL_PLLCTL5 5
+#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK 0x00000f00
+#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8
+#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK 0x0000f000
+#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12
+#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK 0x000f0000
+#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16
+#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK 0x00f00000
+#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20
+#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK 0x0f000000
+#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24
+#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK 0xf0000000
+#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28
+
+/* PMU rev 5 (& 6) */
+#define PMU5_PLL_P1P2_OFF 0
+#define PMU5_PLL_P1_MASK 0x0f000000
+#define PMU5_PLL_P1_SHIFT 24
+#define PMU5_PLL_P2_MASK 0x00f00000
+#define PMU5_PLL_P2_SHIFT 20
+#define PMU5_PLL_M14_OFF 1
+#define PMU5_PLL_MDIV_MASK 0x000000ff
+#define PMU5_PLL_MDIV_WIDTH 8
+#define PMU5_PLL_NM5_OFF 2
+#define PMU5_PLL_NDIV_MASK 0xfff00000
+#define PMU5_PLL_NDIV_SHIFT 20
+#define PMU5_PLL_NDIV_MODE_MASK 0x000e0000
+#define PMU5_PLL_NDIV_MODE_SHIFT 17
+#define PMU5_PLL_FMAB_OFF 3
+#define PMU5_PLL_MRAT_MASK 0xf0000000
+#define PMU5_PLL_MRAT_SHIFT 28
+#define PMU5_PLL_ABRAT_MASK 0x08000000
+#define PMU5_PLL_ABRAT_SHIFT 27
+#define PMU5_PLL_FDIV_MASK 0x07ffffff
+#define PMU5_PLL_PLLCTL_OFF 4
+#define PMU5_PLL_PCHI_OFF 5
+#define PMU5_PLL_PCHI_MASK 0x0000003f
+
+/* pmu XtalFreqRatio */
+#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF
+#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000
+#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31
+
+/* Divider allocation in 4716/47162/5356/5357 */
+#define PMU5_MAINPLL_CPU 1
+#define PMU5_MAINPLL_MEM 2
+#define PMU5_MAINPLL_SI 3
+
+/* 4706 PMU */
+#define PMU4706_MAINPLL_PLL0 0
+#define PMU6_4706_PROCPLL_OFF 4 /* The CPU PLL */
+#define PMU6_4706_PROC_P2DIV_MASK 0x000f0000
+#define PMU6_4706_PROC_P2DIV_SHIFT 16
+#define PMU6_4706_PROC_P1DIV_MASK 0x0000f000
+#define PMU6_4706_PROC_P1DIV_SHIFT 12
+#define PMU6_4706_PROC_NDIV_INT_MASK 0x00000ff8
+#define PMU6_4706_PROC_NDIV_INT_SHIFT 3
+#define PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007
+#define PMU6_4706_PROC_NDIV_MODE_SHIFT 0
+
+#define PMU7_PLL_PLLCTL7 7
+#define PMU7_PLL_CTL7_M4DIV_MASK 0xff000000
+#define PMU7_PLL_CTL7_M4DIV_SHIFT 24
+#define PMU7_PLL_CTL7_M4DIV_BY_6 6
+#define PMU7_PLL_CTL7_M4DIV_BY_12 0xc
+#define PMU7_PLL_CTL7_M4DIV_BY_24 0x18
+#define PMU7_PLL_PLLCTL8 8
+#define PMU7_PLL_CTL8_M5DIV_MASK 0x000000ff
+#define PMU7_PLL_CTL8_M5DIV_SHIFT 0
+#define PMU7_PLL_CTL8_M5DIV_BY_8 8
+#define PMU7_PLL_CTL8_M5DIV_BY_12 0xc
+#define PMU7_PLL_CTL8_M5DIV_BY_24 0x18
+#define PMU7_PLL_CTL8_M6DIV_MASK 0x0000ff00
+#define PMU7_PLL_CTL8_M6DIV_SHIFT 8
+#define PMU7_PLL_CTL8_M6DIV_BY_12 0xc
+#define PMU7_PLL_CTL8_M6DIV_BY_24 0x18
+#define PMU7_PLL_PLLCTL11 11
+#define PMU7_PLL_PLLCTL11_MASK 0xffffff00
+#define PMU7_PLL_PLLCTL11_VAL 0x22222200
+
+/* PMU rev 15 */
+#define PMU15_PLL_PLLCTL0 0
+#define PMU15_PLL_PC0_CLKSEL_MASK 0x00000003
+#define PMU15_PLL_PC0_CLKSEL_SHIFT 0
+#define PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC
+#define PMU15_PLL_PC0_FREQTGT_SHIFT 2
+#define PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000
+#define PMU15_PLL_PC0_PRESCALE_SHIFT 22
+#define PMU15_PLL_PC0_KPCTRL_MASK 0x07000000
+#define PMU15_PLL_PC0_KPCTRL_SHIFT 24
+#define PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000
+#define PMU15_PLL_PC0_FCNTCTRL_SHIFT 27
+#define PMU15_PLL_PC0_FDCMODE_MASK 0x40000000
+#define PMU15_PLL_PC0_FDCMODE_SHIFT 30
+#define PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000
+#define PMU15_PLL_PC0_CTRLBIAS_SHIFT 31
+
+#define PMU15_PLL_PLLCTL1 1
+#define PMU15_PLL_PC1_BIAS_CTLM_MASK 0x00000060
+#define PMU15_PLL_PC1_BIAS_CTLM_SHIFT 5
+#define PMU15_PLL_PC1_BIAS_CTLM_RST_MASK 0x00000040
+#define PMU15_PLL_PC1_BIAS_CTLM_RST_SHIFT 6
+#define PMU15_PLL_PC1_BIAS_SS_DIVR_MASK 0x0001FF80
+#define PMU15_PLL_PC1_BIAS_SS_DIVR_SHIFT 7
+#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_MASK 0x03FE0000
+#define PMU15_PLL_PC1_BIAS_SS_RSTVAL_SHIFT 17
+#define PMU15_PLL_PC1_BIAS_INTG_BW_MASK 0x0C000000
+#define PMU15_PLL_PC1_BIAS_INTG_BW_SHIFT 26
+#define PMU15_PLL_PC1_BIAS_INTG_BYP_MASK 0x10000000
+#define PMU15_PLL_PC1_BIAS_INTG_BYP_SHIFT 28
+#define PMU15_PLL_PC1_OPENLP_EN_MASK 0x40000000
+#define PMU15_PLL_PC1_OPENLP_EN_SHIFT 30
+
+#define PMU15_PLL_PLLCTL2 2
+#define PMU15_PLL_PC2_CTEN_MASK 0x00000001
+#define PMU15_PLL_PC2_CTEN_SHIFT 0
+
+#define PMU15_PLL_PLLCTL3 3
+#define PMU15_PLL_PC3_DITHER_EN_MASK 0x00000001
+#define PMU15_PLL_PC3_DITHER_EN_SHIFT 0
+#define PMU15_PLL_PC3_DCOCTLSP_MASK 0xFE000000
+#define PMU15_PLL_PC3_DCOCTLSP_SHIFT 25
+#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_MASK 0x01
+#define PMU15_PLL_PC3_DCOCTLSP_DIV2EN_SHIFT 0
+#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_MASK 0x02
+#define PMU15_PLL_PC3_DCOCTLSP_CH0EN_SHIFT 1
+#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_MASK 0x04
+#define PMU15_PLL_PC3_DCOCTLSP_CH1EN_SHIFT 2
+#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_MASK 0x18
+#define PMU15_PLL_PC3_DCOCTLSP_CH0SEL_SHIFT 3
+#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_MASK 0x60
+#define PMU15_PLL_PC3_DCOCTLSP_CH1SEL_SHIFT 5
+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV1 0
+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV2 1
+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV3 2
+#define PMU15_PLL_PC3_DCOCTLSP_CHSEL_OUTP_DIV5 3
+
+#define PMU15_PLL_PLLCTL4 4
+#define PMU15_PLL_PC4_FLLCLK1_DIV_MASK 0x00000007
+#define PMU15_PLL_PC4_FLLCLK1_DIV_SHIFT 0
+#define PMU15_PLL_PC4_FLLCLK2_DIV_MASK 0x00000038
+#define PMU15_PLL_PC4_FLLCLK2_DIV_SHIFT 3
+#define PMU15_PLL_PC4_FLLCLK3_DIV_MASK 0x000001C0
+#define PMU15_PLL_PC4_FLLCLK3_DIV_SHIFT 6
+#define PMU15_PLL_PC4_DBGMODE_MASK 0x00000E00
+#define PMU15_PLL_PC4_DBGMODE_SHIFT 9
+#define PMU15_PLL_PC4_FLL480_CTLSP_LK_MASK 0x00001000
+#define PMU15_PLL_PC4_FLL480_CTLSP_LK_SHIFT 12
+#define PMU15_PLL_PC4_FLL480_CTLSP_MASK 0x000FE000
+#define PMU15_PLL_PC4_FLL480_CTLSP_SHIFT 13
+#define PMU15_PLL_PC4_DINPOL_MASK 0x00100000
+#define PMU15_PLL_PC4_DINPOL_SHIFT 20
+#define PMU15_PLL_PC4_CLKOUT_PD_MASK 0x00200000
+#define PMU15_PLL_PC4_CLKOUT_PD_SHIFT 21
+#define PMU15_PLL_PC4_CLKDIV2_PD_MASK 0x00400000
+#define PMU15_PLL_PC4_CLKDIV2_PD_SHIFT 22
+#define PMU15_PLL_PC4_CLKDIV4_PD_MASK 0x00800000
+#define PMU15_PLL_PC4_CLKDIV4_PD_SHIFT 23
+#define PMU15_PLL_PC4_CLKDIV8_PD_MASK 0x01000000
+#define PMU15_PLL_PC4_CLKDIV8_PD_SHIFT 24
+#define PMU15_PLL_PC4_CLKDIV16_PD_MASK 0x02000000
+#define PMU15_PLL_PC4_CLKDIV16_PD_SHIFT 25
+#define PMU15_PLL_PC4_TEST_EN_MASK 0x04000000
+#define PMU15_PLL_PC4_TEST_EN_SHIFT 26
+
+#define PMU15_PLL_PLLCTL5 5
+#define PMU15_PLL_PC5_FREQTGT_MASK 0x000FFFFF
+#define PMU15_PLL_PC5_FREQTGT_SHIFT 0
+#define PMU15_PLL_PC5_DCOCTLSP_MASK 0x07F00000
+#define PMU15_PLL_PC5_DCOCTLSP_SHIFT 20
+#define PMU15_PLL_PC5_PRESCALE_MASK 0x18000000
+#define PMU15_PLL_PC5_PRESCALE_SHIFT 27
+
+#define PMU15_PLL_PLLCTL6 6
+#define PMU15_PLL_PC6_FREQTGT_MASK 0x000FFFFF
+#define PMU15_PLL_PC6_FREQTGT_SHIFT 0
+#define PMU15_PLL_PC6_DCOCTLSP_MASK 0x07F00000
+#define PMU15_PLL_PC6_DCOCTLSP_SHIFT 20
+#define PMU15_PLL_PC6_PRESCALE_MASK 0x18000000
+#define PMU15_PLL_PC6_PRESCALE_SHIFT 27
+
+#define PMU15_FREQTGT_480_DEFAULT 0x19AB1
+#define PMU15_FREQTGT_492_DEFAULT 0x1A4F5
+#define PMU15_ARM_96MHZ 96000000 /* 96 Mhz */
+#define PMU15_ARM_98MHZ 98400000 /* 98.4 Mhz */
+#define PMU15_ARM_97MHZ 97000000 /* 97 Mhz */
+
+
+#define PMU17_PLLCTL2_NDIVTYPE_MASK 0x00000070
+#define PMU17_PLLCTL2_NDIVTYPE_SHIFT 4
+
+#define PMU17_PLLCTL2_NDIV_MODE_INT 0
+#define PMU17_PLLCTL2_NDIV_MODE_INT1B8 1
+#define PMU17_PLLCTL2_NDIV_MODE_MASH111 2
+#define PMU17_PLLCTL2_NDIV_MODE_MASH111B8 3
+
+#define PMU17_PLLCTL0_BBPLL_PWRDWN 0
+#define PMU17_PLLCTL0_BBPLL_DRST 3
+#define PMU17_PLLCTL0_BBPLL_DISBL_CLK 8
+
+/* PLL usage in 4716/47162 */
+#define PMU4716_MAINPLL_PLL0 12
+
+/* PLL usage in 5356/5357 */
+#define PMU5356_MAINPLL_PLL0 0
+#define PMU5357_MAINPLL_PLL0 0
+
+/* 4716/47162 resources */
+#define RES4716_PROC_PLL_ON 0x00000040
+#define RES4716_PROC_HT_AVAIL 0x00000080
+
+/* 4716/4717/4718 Chip specific ChipControl register bits */
+#define CCTRL_471X_I2S_PINS_ENABLE 0x0080 /* I2S pins off by default, shared w/ pflash */
+
+/* 5357 Chip specific ChipControl register bits */
+/* 2nd - 32-bit reg */
+#define CCTRL_5357_I2S_PINS_ENABLE 0x00040000 /* I2S pins enable */
+#define CCTRL_5357_I2CSPI_PINS_ENABLE 0x00080000 /* I2C/SPI pins enable */
+
+/* 5354 resources */
+#define RES5354_EXT_SWITCHER_PWM 0 /* 0x00001 */
+#define RES5354_BB_SWITCHER_PWM 1 /* 0x00002 */
+#define RES5354_BB_SWITCHER_BURST 2 /* 0x00004 */
+#define RES5354_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */
+#define RES5354_ILP_REQUEST 4 /* 0x00010 */
+#define RES5354_RADIO_SWITCHER_PWM 5 /* 0x00020 */
+#define RES5354_RADIO_SWITCHER_BURST 6 /* 0x00040 */
+#define RES5354_ROM_SWITCH 7 /* 0x00080 */
+#define RES5354_PA_REF_LDO 8 /* 0x00100 */
+#define RES5354_RADIO_LDO 9 /* 0x00200 */
+#define RES5354_AFE_LDO 10 /* 0x00400 */
+#define RES5354_PLL_LDO 11 /* 0x00800 */
+#define RES5354_BG_FILTBYP 12 /* 0x01000 */
+#define RES5354_TX_FILTBYP 13 /* 0x02000 */
+#define RES5354_RX_FILTBYP 14 /* 0x04000 */
+#define RES5354_XTAL_PU 15 /* 0x08000 */
+#define RES5354_XTAL_EN 16 /* 0x10000 */
+#define RES5354_BB_PLL_FILTBYP 17 /* 0x20000 */
+#define RES5354_RF_PLL_FILTBYP 18 /* 0x40000 */
+#define RES5354_BB_PLL_PU 19 /* 0x80000 */
+
+/* 5357 Chip specific ChipControl register bits */
+#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */
+#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */
+#define CCTRL5357_NFLASH (1<<16) /* Nandflash in ChipControl 1, bit 16 */
+
+/* 43217 Chip specific ChipControl register bits */
+#define CCTRL43217_EXTPA_C0 (1<<13) /* core0 extPA in ChipControl 1, bit 13 */
+#define CCTRL43217_EXTPA_C1 (1<<8) /* core1 extPA in ChipControl 1, bit 8 */
+
+/* 4328 resources */
+#define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */
+#define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */
+#define RES4328_BB_SWITCHER_BURST 2 /* 0x00004 */
+#define RES4328_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */
+#define RES4328_ILP_REQUEST 4 /* 0x00010 */
+#define RES4328_RADIO_SWITCHER_PWM 5 /* 0x00020 */
+#define RES4328_RADIO_SWITCHER_BURST 6 /* 0x00040 */
+#define RES4328_ROM_SWITCH 7 /* 0x00080 */
+#define RES4328_PA_REF_LDO 8 /* 0x00100 */
+#define RES4328_RADIO_LDO 9 /* 0x00200 */
+#define RES4328_AFE_LDO 10 /* 0x00400 */
+#define RES4328_PLL_LDO 11 /* 0x00800 */
+#define RES4328_BG_FILTBYP 12 /* 0x01000 */
+#define RES4328_TX_FILTBYP 13 /* 0x02000 */
+#define RES4328_RX_FILTBYP 14 /* 0x04000 */
+#define RES4328_XTAL_PU 15 /* 0x08000 */
+#define RES4328_XTAL_EN 16 /* 0x10000 */
+#define RES4328_BB_PLL_FILTBYP 17 /* 0x20000 */
+#define RES4328_RF_PLL_FILTBYP 18 /* 0x40000 */
+#define RES4328_BB_PLL_PU 19 /* 0x80000 */
+
+/* 4325 A0/A1 resources */
+#define RES4325_BUCK_BOOST_BURST 0 /* 0x00000001 */
+#define RES4325_CBUCK_BURST 1 /* 0x00000002 */
+#define RES4325_CBUCK_PWM 2 /* 0x00000004 */
+#define RES4325_CLDO_CBUCK_BURST 3 /* 0x00000008 */
+#define RES4325_CLDO_CBUCK_PWM 4 /* 0x00000010 */
+#define RES4325_BUCK_BOOST_PWM 5 /* 0x00000020 */
+#define RES4325_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4325_ABUCK_BURST 7 /* 0x00000080 */
+#define RES4325_ABUCK_PWM 8 /* 0x00000100 */
+#define RES4325_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4325_OTP_PU 10 /* 0x00000400 */
+#define RES4325_LNLDO3_PU 11 /* 0x00000800 */
+#define RES4325_LNLDO4_PU 12 /* 0x00001000 */
+#define RES4325_XTAL_PU 13 /* 0x00002000 */
+#define RES4325_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4325_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4325_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4325_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4325_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4325_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4325_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4325_HT_AVAIL 21 /* 0x00200000 */
+
+/* 4325 B0/C0 resources */
+#define RES4325B0_CBUCK_LPOM 1 /* 0x00000002 */
+#define RES4325B0_CBUCK_BURST 2 /* 0x00000004 */
+#define RES4325B0_CBUCK_PWM 3 /* 0x00000008 */
+#define RES4325B0_CLDO_PU 4 /* 0x00000010 */
+
+/* 4325 C1 resources */
+#define RES4325C1_LNLDO2_PU 12 /* 0x00001000 */
+
+/* 4325 chip-specific ChipStatus register bits */
+#define CST4325_SPROM_OTP_SEL_MASK 0x00000003
+#define CST4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
+#define CST4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
+#define CST4325_OTP_SEL 2 /* OTP is powered up, no SPROM */
+#define CST4325_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */
+#define CST4325_SDIO_USB_MODE_MASK 0x00000004
+#define CST4325_SDIO_USB_MODE_SHIFT 2
+#define CST4325_RCAL_VALID_MASK 0x00000008
+#define CST4325_RCAL_VALID_SHIFT 3
+#define CST4325_RCAL_VALUE_MASK 0x000001f0
+#define CST4325_RCAL_VALUE_SHIFT 4
+#define CST4325_PMUTOP_2B_MASK 0x00000200 /* 1 for 2b, 0 for to 2a */
+#define CST4325_PMUTOP_2B_SHIFT 9
+
+#define RES4329_RESERVED0 0 /* 0x00000001 */
+#define RES4329_CBUCK_LPOM 1 /* 0x00000002 */
+#define RES4329_CBUCK_BURST 2 /* 0x00000004 */
+#define RES4329_CBUCK_PWM 3 /* 0x00000008 */
+#define RES4329_CLDO_PU 4 /* 0x00000010 */
+#define RES4329_PALDO_PU 5 /* 0x00000020 */
+#define RES4329_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4329_RESERVED7 7 /* 0x00000080 */
+#define RES4329_RESERVED8 8 /* 0x00000100 */
+#define RES4329_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4329_OTP_PU 10 /* 0x00000400 */
+#define RES4329_RESERVED11 11 /* 0x00000800 */
+#define RES4329_LNLDO2_PU 12 /* 0x00001000 */
+#define RES4329_XTAL_PU 13 /* 0x00002000 */
+#define RES4329_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4329_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4329_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4329_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4329_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4329_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4329_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4329_HT_AVAIL 21 /* 0x00200000 */
+
+#define CST4329_SPROM_OTP_SEL_MASK 0x00000003
+#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
+#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
+#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */
+#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */
+#define CST4329_SPI_SDIO_MODE_MASK 0x00000004
+#define CST4329_SPI_SDIO_MODE_SHIFT 2
+
+/* 4312 chip-specific ChipStatus register bits */
+#define CST4312_SPROM_OTP_SEL_MASK 0x00000003
+#define CST4312_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
+#define CST4312_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
+#define CST4312_OTP_SEL 2 /* OTP is powered up, no SPROM */
+#define CST4312_OTP_BAD 3 /* OTP is broken, SPROM is present */
+
+/* 4312 resources (all PMU chips with little memory constraint) */
+#define RES4312_SWITCHER_BURST 0 /* 0x00000001 */
+#define RES4312_SWITCHER_PWM 1 /* 0x00000002 */
+#define RES4312_PA_REF_LDO 2 /* 0x00000004 */
+#define RES4312_CORE_LDO_BURST 3 /* 0x00000008 */
+#define RES4312_CORE_LDO_PWM 4 /* 0x00000010 */
+#define RES4312_RADIO_LDO 5 /* 0x00000020 */
+#define RES4312_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4312_BG_FILTBYP 7 /* 0x00000080 */
+#define RES4312_TX_FILTBYP 8 /* 0x00000100 */
+#define RES4312_RX_FILTBYP 9 /* 0x00000200 */
+#define RES4312_XTAL_PU 10 /* 0x00000400 */
+#define RES4312_ALP_AVAIL 11 /* 0x00000800 */
+#define RES4312_BB_PLL_FILTBYP 12 /* 0x00001000 */
+#define RES4312_RF_PLL_FILTBYP 13 /* 0x00002000 */
+#define RES4312_HT_AVAIL 14 /* 0x00004000 */
+
+/* 4322 resources */
+#define RES4322_RF_LDO 0
+#define RES4322_ILP_REQUEST 1
+#define RES4322_XTAL_PU 2
+#define RES4322_ALP_AVAIL 3
+#define RES4322_SI_PLL_ON 4
+#define RES4322_HT_SI_AVAIL 5
+#define RES4322_PHY_PLL_ON 6
+#define RES4322_HT_PHY_AVAIL 7
+#define RES4322_OTP_PU 8
+
+/* 4322 chip-specific ChipStatus register bits */
+#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020
+#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0
+#define CST4322_SPROM_OTP_SEL_SHIFT 6
+#define CST4322_NO_SPROM_OTP 0 /* no OTP, no SPROM */
+#define CST4322_SPROM_PRESENT 1 /* SPROM is present */
+#define CST4322_OTP_PRESENT 2 /* OTP is present */
+#define CST4322_PCI_OR_USB 0x00000100
+#define CST4322_BOOT_MASK 0x00000600
+#define CST4322_BOOT_SHIFT 9
+#define CST4322_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */
+#define CST4322_BOOT_FROM_ROM 1 /* boot from ROM */
+#define CST4322_BOOT_FROM_FLASH 2 /* boot from FLASH */
+#define CST4322_BOOT_FROM_INVALID 3
+#define CST4322_ILP_DIV_EN 0x00000800
+#define CST4322_FLASH_TYPE_MASK 0x00001000
+#define CST4322_FLASH_TYPE_SHIFT 12
+#define CST4322_FLASH_TYPE_SHIFT_ST 0 /* ST serial FLASH */
+#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 /* ATMEL flash */
+#define CST4322_ARM_TAP_SEL 0x00002000
+#define CST4322_RES_INIT_MODE_MASK 0x0000c000
+#define CST4322_RES_INIT_MODE_SHIFT 14
+#define CST4322_RES_INIT_MODE_ILPAVAIL 0 /* resinitmode: ILP available */
+#define CST4322_RES_INIT_MODE_ILPREQ 1 /* resinitmode: ILP request */
+#define CST4322_RES_INIT_MODE_ALPAVAIL 2 /* resinitmode: ALP available */
+#define CST4322_RES_INIT_MODE_HTAVAIL 3 /* resinitmode: HT available */
+#define CST4322_PCIPLLCLK_GATING 0x00010000
+#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000
+#define CST4322_PCI_CARDBUS_MODE 0x00040000
+
+/* 43224 chip-specific ChipControl register bits */
+#define CCTRL43224_GPIO_TOGGLE 0x8000 /* gpio[3:0] pins as btcoex or s/w gpio */
+#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */
+#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */
+
+/* 43236 resources */
+#define RES43236_REGULATOR 0
+#define RES43236_ILP_REQUEST 1
+#define RES43236_XTAL_PU 2
+#define RES43236_ALP_AVAIL 3
+#define RES43236_SI_PLL_ON 4
+#define RES43236_HT_SI_AVAIL 5
+
+/* 43236 chip-specific ChipControl register bits */
+#define CCTRL43236_BT_COEXIST (1<<0) /* 0 disable */
+#define CCTRL43236_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */
+#define CCTRL43236_EXT_LNA (1<<2) /* 0 disable */
+#define CCTRL43236_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */
+#define CCTRL43236_GSIO (1<<4) /* 0 disable */
+
+/* 43236 Chip specific ChipStatus register bits */
+#define CST43236_SFLASH_MASK 0x00000040
+#define CST43236_OTP_SEL_MASK 0x00000080
+#define CST43236_OTP_SEL_SHIFT 7
+#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */
+#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */
+#define CST43236_BOOT_MASK 0x00001800
+#define CST43236_BOOT_SHIFT 11
+#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */
+#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */
+#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */
+#define CST43236_BOOT_FROM_INVALID 3
+
+/* 43237 resources */
+#define RES43237_REGULATOR 0
+#define RES43237_ILP_REQUEST 1
+#define RES43237_XTAL_PU 2
+#define RES43237_ALP_AVAIL 3
+#define RES43237_SI_PLL_ON 4
+#define RES43237_HT_SI_AVAIL 5
+
+/* 43237 chip-specific ChipControl register bits */
+#define CCTRL43237_BT_COEXIST (1<<0) /* 0 disable */
+#define CCTRL43237_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */
+#define CCTRL43237_EXT_LNA (1<<2) /* 0 disable */
+#define CCTRL43237_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */
+#define CCTRL43237_GSIO (1<<4) /* 0 disable */
+
+/* 43237 Chip specific ChipStatus register bits */
+#define CST43237_SFLASH_MASK 0x00000040
+#define CST43237_OTP_SEL_MASK 0x00000080
+#define CST43237_OTP_SEL_SHIFT 7
+#define CST43237_HSIC_MASK 0x00000100 /* USB/HSIC */
+#define CST43237_BP_CLK 0x00000200 /* 120/96Mbps */
+#define CST43237_BOOT_MASK 0x00001800
+#define CST43237_BOOT_SHIFT 11
+#define CST43237_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */
+#define CST43237_BOOT_FROM_ROM 1 /* boot from ROM */
+#define CST43237_BOOT_FROM_FLASH 2 /* boot from FLASH */
+#define CST43237_BOOT_FROM_INVALID 3
+
+/* 43239 resources */
+#define RES43239_OTP_PU 9
+#define RES43239_MACPHY_CLKAVAIL 23
+#define RES43239_HT_AVAIL 24
+
+/* 43239 Chip specific ChipStatus register bits */
+#define CST43239_SPROM_MASK 0x00000002
+#define CST43239_SFLASH_MASK 0x00000004
+#define CST43239_RES_INIT_MODE_SHIFT 7
+#define CST43239_RES_INIT_MODE_MASK 0x000001f0
+#define CST43239_CHIPMODE_SDIOD(cs) ((cs) & (1 << 15)) /* SDIO || gSPI */
+#define CST43239_CHIPMODE_USB20D(cs) (~(cs) & (1 << 15)) /* USB || USBDA */
+#define CST43239_CHIPMODE_SDIO(cs) (((cs) & (1 << 0)) == 0) /* SDIO */
+#define CST43239_CHIPMODE_GSPI(cs) (((cs) & (1 << 0)) == (1 << 0)) /* gSPI */
+
+/* 4324 resources */
+#define RES4324_OTP_PU 10
+#define RES4324_HT_AVAIL 29
+#define RES4324_MACPHY_CLKAVAIL 30
+
+/* 4324 Chip specific ChipStatus register bits */
+#define CST4324_SPROM_MASK 0x00000080
+#define CST4324_SFLASH_MASK 0x00400000
+#define CST4324_RES_INIT_MODE_SHIFT 10
+#define CST4324_RES_INIT_MODE_MASK 0x00000c00
+#define CST4324_CHIPMODE_MASK 0x7
+#define CST4324_CHIPMODE_SDIOD(cs) ((~(cs)) & (1 << 2)) /* SDIO || gSPI */
+#define CST4324_CHIPMODE_USB20D(cs) (((cs) & CST4324_CHIPMODE_MASK) == 0x6) /* USB || USBDA */
+
+/* 4331 resources */
+#define RES4331_REGULATOR 0
+#define RES4331_ILP_REQUEST 1
+#define RES4331_XTAL_PU 2
+#define RES4331_ALP_AVAIL 3
+#define RES4331_SI_PLL_ON 4
+#define RES4331_HT_SI_AVAIL 5
+
+/* 4331 chip-specific ChipControl register bits */
+#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */
+#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */
+#define CCTRL4331_EXT_LNA_G (1<<2) /* 0 disable */
+#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */
+#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */
+#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */
+#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */
+#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */
+#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */
+#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */
+#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */
+#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */
+#define CCTRL4331_EXTPA_EN2 (1<<12) /* 0 ext pa disable, 1 ext pa enabled */
+#define CCTRL4331_EXT_LNA_A (1<<13) /* 0 disable */
+#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */
+#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */
+#define CCTRL4331_EXTPA_ANA_EN (1<<24) /* 0 ext pa disable, 1 ext pa enabled */
+
+/* 4331 Chip specific ChipStatus register bits */
+#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */
+#define CST4331_SPROM_OTP_SEL_MASK 0x00000006
+#define CST4331_SPROM_OTP_SEL_SHIFT 1
+#define CST4331_SPROM_PRESENT 0x00000002
+#define CST4331_OTP_PRESENT 0x00000004
+#define CST4331_LDO_RF 0x00000008
+#define CST4331_LDO_PAR 0x00000010
+
+/* 4315 resource */
+#define RES4315_CBUCK_LPOM 1 /* 0x00000002 */
+#define RES4315_CBUCK_BURST 2 /* 0x00000004 */
+#define RES4315_CBUCK_PWM 3 /* 0x00000008 */
+#define RES4315_CLDO_PU 4 /* 0x00000010 */
+#define RES4315_PALDO_PU 5 /* 0x00000020 */
+#define RES4315_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4315_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4315_OTP_PU 10 /* 0x00000400 */
+#define RES4315_LNLDO2_PU 12 /* 0x00001000 */
+#define RES4315_XTAL_PU 13 /* 0x00002000 */
+#define RES4315_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4315_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4315_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4315_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4315_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4315_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4315_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4315_HT_AVAIL 21 /* 0x00200000 */
+
+/* 4315 chip-specific ChipStatus register bits */
+#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 /* gpio [7:6], SDIO CIS selection */
+#define CST4315_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */
+#define CST4315_SPROM_SEL 0x00000001 /* use SPROM, OTP is powered up */
+#define CST4315_OTP_SEL 0x00000002 /* use OTP, OTP is powered up */
+#define CST4315_OTP_PWRDN 0x00000003 /* use SPROM, OTP is powered down */
+#define CST4315_SDIO_MODE 0x00000004 /* gpio [8], sdio/usb mode */
+#define CST4315_RCAL_VALID 0x00000008
+#define CST4315_RCAL_VALUE_MASK 0x000001f0
+#define CST4315_RCAL_VALUE_SHIFT 4
+#define CST4315_PALDO_EXTPNP 0x00000200 /* PALDO is configured with external PNP */
+#define CST4315_CBUCK_MODE_MASK 0x00000c00
+#define CST4315_CBUCK_MODE_BURST 0x00000400
+#define CST4315_CBUCK_MODE_LPBURST 0x00000c00
+
+/* 4319 resources */
+#define RES4319_CBUCK_LPOM 1 /* 0x00000002 */
+#define RES4319_CBUCK_BURST 2 /* 0x00000004 */
+#define RES4319_CBUCK_PWM 3 /* 0x00000008 */
+#define RES4319_CLDO_PU 4 /* 0x00000010 */
+#define RES4319_PALDO_PU 5 /* 0x00000020 */
+#define RES4319_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4319_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4319_OTP_PU 10 /* 0x00000400 */
+#define RES4319_LNLDO2_PU 12 /* 0x00001000 */
+#define RES4319_XTAL_PU 13 /* 0x00002000 */
+#define RES4319_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4319_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4319_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4319_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4319_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4319_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4319_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4319_HT_AVAIL 21 /* 0x00200000 */
+
+/* 4319 chip-specific ChipStatus register bits */
+#define CST4319_SPI_CPULESSUSB 0x00000001
+#define CST4319_SPI_CLK_POL 0x00000002
+#define CST4319_SPI_CLK_PH 0x00000008
+#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */
+#define CST4319_SPROM_OTP_SEL_SHIFT 6
+#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */
+#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */
+#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */
+#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */
+#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */
+#define CST4319_REMAP_SEL_MASK 0x00000600
+#define CST4319_ILPDIV_EN 0x00000800
+#define CST4319_XTAL_PD_POL 0x00001000
+#define CST4319_LPO_SEL 0x00002000
+#define CST4319_RES_INIT_MODE 0x0000c000
+#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */
+#define CST4319_CBUCK_MODE_MASK 0x00060000
+#define CST4319_CBUCK_MODE_BURST 0x00020000
+#define CST4319_CBUCK_MODE_LPBURST 0x00060000
+#define CST4319_RCAL_VALID 0x01000000
+#define CST4319_RCAL_VALUE_MASK 0x3e000000
+#define CST4319_RCAL_VALUE_SHIFT 25
+
+#define PMU1_PLL0_CHIPCTL0 0
+#define PMU1_PLL0_CHIPCTL1 1
+#define PMU1_PLL0_CHIPCTL2 2
+#define CCTL_4319USB_XTAL_SEL_MASK 0x00180000
+#define CCTL_4319USB_XTAL_SEL_SHIFT 19
+#define CCTL_4319USB_48MHZ_PLL_SEL 1
+#define CCTL_4319USB_24MHZ_PLL_SEL 2
+
+/* PMU resources for 4336 */
+#define RES4336_CBUCK_LPOM 0
+#define RES4336_CBUCK_BURST 1
+#define RES4336_CBUCK_LP_PWM 2
+#define RES4336_CBUCK_PWM 3
+#define RES4336_CLDO_PU 4
+#define RES4336_DIS_INT_RESET_PD 5
+#define RES4336_ILP_REQUEST 6
+#define RES4336_LNLDO_PU 7
+#define RES4336_LDO3P3_PU 8
+#define RES4336_OTP_PU 9
+#define RES4336_XTAL_PU 10
+#define RES4336_ALP_AVAIL 11
+#define RES4336_RADIO_PU 12
+#define RES4336_BG_PU 13
+#define RES4336_VREG1p4_PU_PU 14
+#define RES4336_AFE_PWRSW_PU 15
+#define RES4336_RX_PWRSW_PU 16
+#define RES4336_TX_PWRSW_PU 17
+#define RES4336_BB_PWRSW_PU 18
+#define RES4336_SYNTH_PWRSW_PU 19
+#define RES4336_MISC_PWRSW_PU 20
+#define RES4336_LOGEN_PWRSW_PU 21
+#define RES4336_BBPLL_PWRSW_PU 22
+#define RES4336_MACPHY_CLKAVAIL 23
+#define RES4336_HT_AVAIL 24
+#define RES4336_RSVD 25
+
+/* 4336 chip-specific ChipStatus register bits */
+#define CST4336_SPI_MODE_MASK 0x00000001
+#define CST4336_SPROM_PRESENT 0x00000002
+#define CST4336_OTP_PRESENT 0x00000004
+#define CST4336_ARMREMAP_0 0x00000008
+#define CST4336_ILPDIV_EN_MASK 0x00000010
+#define CST4336_ILPDIV_EN_SHIFT 4
+#define CST4336_XTAL_PD_POL_MASK 0x00000020
+#define CST4336_XTAL_PD_POL_SHIFT 5
+#define CST4336_LPO_SEL_MASK 0x00000040
+#define CST4336_LPO_SEL_SHIFT 6
+#define CST4336_RES_INIT_MODE_MASK 0x00000180
+#define CST4336_RES_INIT_MODE_SHIFT 7
+#define CST4336_CBUCK_MODE_MASK 0x00000600
+#define CST4336_CBUCK_MODE_SHIFT 9
+
+/* 4336 Chip specific PMU ChipControl register bits */
+#define PCTL_4336_SERIAL_ENAB (1 << 24)
+
+/* 4330 resources */
+#define RES4330_CBUCK_LPOM 0
+#define RES4330_CBUCK_BURST 1
+#define RES4330_CBUCK_LP_PWM 2
+#define RES4330_CBUCK_PWM 3
+#define RES4330_CLDO_PU 4
+#define RES4330_DIS_INT_RESET_PD 5
+#define RES4330_ILP_REQUEST 6
+#define RES4330_LNLDO_PU 7
+#define RES4330_LDO3P3_PU 8
+#define RES4330_OTP_PU 9
+#define RES4330_XTAL_PU 10
+#define RES4330_ALP_AVAIL 11
+#define RES4330_RADIO_PU 12
+#define RES4330_BG_PU 13
+#define RES4330_VREG1p4_PU_PU 14
+#define RES4330_AFE_PWRSW_PU 15
+#define RES4330_RX_PWRSW_PU 16
+#define RES4330_TX_PWRSW_PU 17
+#define RES4330_BB_PWRSW_PU 18
+#define RES4330_SYNTH_PWRSW_PU 19
+#define RES4330_MISC_PWRSW_PU 20
+#define RES4330_LOGEN_PWRSW_PU 21
+#define RES4330_BBPLL_PWRSW_PU 22
+#define RES4330_MACPHY_CLKAVAIL 23
+#define RES4330_HT_AVAIL 24
+#define RES4330_5gRX_PWRSW_PU 25
+#define RES4330_5gTX_PWRSW_PU 26
+#define RES4330_5g_LOGEN_PWRSW_PU 27
+
+/* 4330 chip-specific ChipStatus register bits */
+#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */
+#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */
+#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */
+#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */
+#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */
+#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */
+#define CST4330_OTP_PRESENT 0x00000010
+#define CST4330_LPO_AUTODET_EN 0x00000020
+#define CST4330_ARMREMAP_0 0x00000040
+#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */
+#define CST4330_ILPDIV_EN 0x00000100
+#define CST4330_LPO_SEL 0x00000200
+#define CST4330_RES_INIT_MODE_SHIFT 10
+#define CST4330_RES_INIT_MODE_MASK 0x00000c00
+#define CST4330_CBUCK_MODE_SHIFT 12
+#define CST4330_CBUCK_MODE_MASK 0x00003000
+#define CST4330_CBUCK_POWER_OK 0x00004000
+#define CST4330_BB_PLL_LOCKED 0x00008000
+#define SOCDEVRAM_BP_ADDR 0x1E000000
+#define SOCDEVRAM_ARM_ADDR 0x00800000
+
+/* 4330 Chip specific PMU ChipControl register bits */
+#define PCTL_4330_SERIAL_ENAB (1 << 24)
+
+/* 4330 Chip specific ChipControl register bits */
+#define CCTRL_4330_GPIO_SEL 0x00000001 /* 1=select GPIOs to be muxed out */
+#define CCTRL_4330_ERCX_SEL 0x00000002 /* 1=select ERCX BT coex to be muxed out */
+#define CCTRL_4330_SDIO_HOST_WAKE 0x00000004 /* SDIO: 1=configure GPIO0 for host wake */
+#define CCTRL_4330_JTAG_DISABLE 0x00000008 /* 1=disable JTAG interface on mux'd pins */
+
+#define PMU_VREG0_ADDR 0
+#define PMU_VREG0_DISABLE_PULLD_BT_SHIFT 2
+#define PMU_VREG0_DISABLE_PULLD_WL_SHIFT 3
+
+/* 4334 resources */
+#define RES4334_LPLDO_PU 0
+#define RES4334_RESET_PULLDN_DIS 1
+#define RES4334_PMU_BG_PU 2
+#define RES4334_HSIC_LDO_PU 3
+#define RES4334_CBUCK_LPOM_PU 4
+#define RES4334_CBUCK_PFM_PU 5
+#define RES4334_CLDO_PU 6
+#define RES4334_LPLDO2_LVM 7
+#define RES4334_LNLDO_PU 8
+#define RES4334_LDO3P3_PU 9
+#define RES4334_OTP_PU 10
+#define RES4334_XTAL_PU 11
+#define RES4334_WL_PWRSW_PU 12
+#define RES4334_LQ_AVAIL 13
+#define RES4334_LOGIC_RET 14
+#define RES4334_MEM_SLEEP 15
+#define RES4334_MACPHY_RET 16
+#define RES4334_WL_CORE_READY 17
+#define RES4334_ILP_REQ 18
+#define RES4334_ALP_AVAIL 19
+#define RES4334_MISC_PWRSW_PU 20
+#define RES4334_SYNTH_PWRSW_PU 21
+#define RES4334_RX_PWRSW_PU 22
+#define RES4334_RADIO_PU 23
+#define RES4334_WL_PMU_PU 24
+#define RES4334_VCO_LDO_PU 25
+#define RES4334_AFE_LDO_PU 26
+#define RES4334_RX_LDO_PU 27
+#define RES4334_TX_LDO_PU 28
+#define RES4334_HT_AVAIL 29
+#define RES4334_MACPHY_CLK_AVAIL 30
+
+/* 4334 chip-specific ChipStatus register bits */
+#define CST4334_CHIPMODE_MASK 7
+#define CST4334_SDIO_MODE 0x00000000
+#define CST4334_SPI_MODE 0x00000004
+#define CST4334_HSIC_MODE 0x00000006
+#define CST4334_BLUSB_MODE 0x00000007
+#define CST4334_CHIPMODE_HSIC(cs) (((cs) & CST4334_CHIPMODE_MASK) == CST4334_HSIC_MODE)
+#define CST4334_OTP_PRESENT 0x00000010
+#define CST4334_LPO_AUTODET_EN 0x00000020
+#define CST4334_ARMREMAP_0 0x00000040
+#define CST4334_SPROM_PRESENT 0x00000080
+#define CST4334_ILPDIV_EN_MASK 0x00000100
+#define CST4334_ILPDIV_EN_SHIFT 8
+#define CST4334_LPO_SEL_MASK 0x00000200
+#define CST4334_LPO_SEL_SHIFT 9
+#define CST4334_RES_INIT_MODE_MASK 0x00000C00
+#define CST4334_RES_INIT_MODE_SHIFT 10
+
+/* 4334 Chip specific PMU ChipControl register bits */
+#define PCTL_4334_GPIO3_ENAB (1 << 3)
+
+/* 4334 Chip control */
+#define CCTRL4334_HSIC_LDO_PU (1 << 23)
+
+/* 4324 Chip specific ChipControl1 register bits */
+#define CCTRL1_4324_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */
+#define CCTRL1_4324_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */
+
+
+/* 4313 resources */
+#define RES4313_BB_PU_RSRC 0
+#define RES4313_ILP_REQ_RSRC 1
+#define RES4313_XTAL_PU_RSRC 2
+#define RES4313_ALP_AVAIL_RSRC 3
+#define RES4313_RADIO_PU_RSRC 4
+#define RES4313_BG_PU_RSRC 5
+#define RES4313_VREG1P4_PU_RSRC 6
+#define RES4313_AFE_PWRSW_RSRC 7
+#define RES4313_RX_PWRSW_RSRC 8
+#define RES4313_TX_PWRSW_RSRC 9
+#define RES4313_BB_PWRSW_RSRC 10
+#define RES4313_SYNTH_PWRSW_RSRC 11
+#define RES4313_MISC_PWRSW_RSRC 12
+#define RES4313_BB_PLL_PWRSW_RSRC 13
+#define RES4313_HT_AVAIL_RSRC 14
+#define RES4313_MACPHY_CLK_AVAIL_RSRC 15
+
+/* 4313 chip-specific ChipStatus register bits */
+#define CST4313_SPROM_PRESENT 1
+#define CST4313_OTP_PRESENT 2
+#define CST4313_SPROM_OTP_SEL_MASK 0x00000002
+#define CST4313_SPROM_OTP_SEL_SHIFT 0
+
+/* 4313 Chip specific ChipControl register bits */
+#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */
+
+/* PMU respources for 4314 */
+#define RES4314_LPLDO_PU 0
+#define RES4314_PMU_SLEEP_DIS 1
+#define RES4314_PMU_BG_PU 2
+#define RES4314_CBUCK_LPOM_PU 3
+#define RES4314_CBUCK_PFM_PU 4
+#define RES4314_CLDO_PU 5
+#define RES4314_LPLDO2_LVM 6
+#define RES4314_WL_PMU_PU 7
+#define RES4314_LNLDO_PU 8
+#define RES4314_LDO3P3_PU 9
+#define RES4314_OTP_PU 10
+#define RES4314_XTAL_PU 11
+#define RES4314_WL_PWRSW_PU 12
+#define RES4314_LQ_AVAIL 13
+#define RES4314_LOGIC_RET 14
+#define RES4314_MEM_SLEEP 15
+#define RES4314_MACPHY_RET 16
+#define RES4314_WL_CORE_READY 17
+#define RES4314_ILP_REQ 18
+#define RES4314_ALP_AVAIL 19
+#define RES4314_MISC_PWRSW_PU 20
+#define RES4314_SYNTH_PWRSW_PU 21
+#define RES4314_RX_PWRSW_PU 22
+#define RES4314_RADIO_PU 23
+#define RES4314_VCO_LDO_PU 24
+#define RES4314_AFE_LDO_PU 25
+#define RES4314_RX_LDO_PU 26
+#define RES4314_TX_LDO_PU 27
+#define RES4314_HT_AVAIL 28
+#define RES4314_MACPHY_CLK_AVAIL 29
+
+/* 4314 chip-specific ChipStatus register bits */
+#define CST4314_OTP_ENABLED 0x00200000
+
+/* 43228 resources */
+#define RES43228_NOT_USED 0
+#define RES43228_ILP_REQUEST 1
+#define RES43228_XTAL_PU 2
+#define RES43228_ALP_AVAIL 3
+#define RES43228_PLL_EN 4
+#define RES43228_HT_PHY_AVAIL 5
+
+/* 43228 chipstatus reg bits */
+#define CST43228_ILP_DIV_EN 0x1
+#define CST43228_OTP_PRESENT 0x2
+#define CST43228_SERDES_REFCLK_PADSEL 0x4
+#define CST43228_SDIO_MODE 0x8
+#define CST43228_SDIO_OTP_PRESENT 0x10
+#define CST43228_SDIO_RESET 0x20
+
+/* 4706 chipstatus reg bits */
+#define CST4706_PKG_OPTION (1<<0) /* 0: full-featured package 1: low-cost package */
+#define CST4706_SFLASH_PRESENT (1<<1) /* 0: parallel, 1: serial flash is present */
+#define CST4706_SFLASH_TYPE (1<<2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */
+#define CST4706_MIPS_BENDIAN (1<<3) /* 0: little, 1: big endian */
+#define CST4706_PCIE1_DISABLE (1<<5) /* PCIE1 enable strap pin */
+
+/* 4706 flashstrconfig reg bits */
+#define FLSTRCF4706_MASK 0x000000ff
+#define FLSTRCF4706_SF1 0x00000001 /* 2nd serial flash present */
+#define FLSTRCF4706_PF1 0x00000002 /* 2nd parallel flash present */
+#define FLSTRCF4706_SF1_TYPE 0x00000004 /* 2nd serial flash type : 0 : ST, 1 : Atmel */
+#define FLSTRCF4706_NF1 0x00000008 /* 2nd NAND flash present */
+#define FLSTRCF4706_1ST_MADDR_SEG_MASK 0x000000f0 /* Valid value mask */
+#define FLSTRCF4706_1ST_MADDR_SEG_4MB 0x00000010 /* 4MB */
+#define FLSTRCF4706_1ST_MADDR_SEG_8MB 0x00000020 /* 8MB */
+#define FLSTRCF4706_1ST_MADDR_SEG_16MB 0x00000030 /* 16MB */
+#define FLSTRCF4706_1ST_MADDR_SEG_32MB 0x00000040 /* 32MB */
+#define FLSTRCF4706_1ST_MADDR_SEG_64MB 0x00000050 /* 64MB */
+#define FLSTRCF4706_1ST_MADDR_SEG_128MB 0x00000060 /* 128MB */
+#define FLSTRCF4706_1ST_MADDR_SEG_256MB 0x00000070 /* 256MB */
+
+/* 4360 Chip specific ChipControl register bits */
+#define CCTRL4360_SECI_MODE (1 << 2)
+#define CCTRL4360_BTSWCTRL_MODE (1 << 3)
+#define CCTRL4360_EXTRA_FEMCTRL_MODE (1 << 8)
+#define CCTRL4360_BT_LGCY_MODE (1 << 9)
+#define CCTRL4360_CORE2FEMCTRL4_ON (1 << 21)
+
+/* 4360 PMU resources and chip status bits */
+#define RES4360_REGULATOR 0
+#define RES4360_ILP_AVAIL 1
+#define RES4360_ILP_REQ 2
+#define RES4360_XTAL_LDO_PU 3
+#define RES4360_XTAL_PU 4
+#define RES4360_ALP_AVAIL 5
+#define RES4360_BBPLLPWRSW_PU 6
+#define RES4360_HT_AVAIL 7
+#define RES4360_OTP_PU 8
+
+#define CST4360_XTAL_40MZ 0x00000001
+#define CST4360_SFLASH 0x00000002
+#define CST4360_SPROM_PRESENT 0x00000004
+#define CST4360_SFLASH_TYPE 0x00000004
+#define CST4360_OTP_ENABLED 0x00000008
+#define CST4360_REMAP_ROM 0x00000010
+#define CST4360_RSRC_INIT_MODE_MASK 0x00000060
+#define CST4360_RSRC_INIT_MODE_SHIFT 5
+#define CST4360_ILP_DIVEN 0x00000080
+#define CST4360_MODE_USB 0x00000100
+#define CST4360_SPROM_SIZE_MASK 0x00000600
+#define CST4360_SPROM_SIZE_SHIFT 9
+#define CST4360_BBPLL_LOCK 0x00000800
+#define CST4360_AVBBPLL_LOCK 0x00001000
+#define CST4360_USBBBPLL_LOCK 0x00002000
+
+#define CCTRL_4360_UART_SEL 0x2
+
+/* 4335 resources */
+#define RES4335_LPLDO_PO 0
+#define RES4335_PMU_BG_PU 1
+#define RES4335_PMU_SLEEP 2
+#define RES4335_RSVD_3 3
+#define RES4335_CBUCK_LPOM_PU 4
+#define RES4335_CBUCK_PFM_PU 5
+#define RES4335_RSVD_6 6
+#define RES4335_RSVD_7 7
+#define RES4335_LNLDO_PU 8
+#define RES4335_XTALLDO_PU 9
+#define RES4335_LDO3P3_PU 10
+#define RES4335_OTP_PU 11
+#define RES4335_XTAL_PU 12
+#define RES4335_SR_CLK_START 13
+#define RES4335_LQ_AVAIL 14
+#define RES4335_LQ_START 15
+#define RES4335_RSVD_16 16
+#define RES4335_WL_CORE_RDY 17
+#define RES4335_ILP_REQ 18
+#define RES4335_ALP_AVAIL 19
+#define RES4335_MINI_PMU 20
+#define RES4335_RADIO_PU 21
+#define RES4335_SR_CLK_STABLE 22
+#define RES4335_SR_SAVE_RESTORE 23
+#define RES4335_SR_PHY_PWRSW 24
+#define RES4335_SR_VDDM_PWRSW 25
+#define RES4335_SR_SUBCORE_PWRSW 26
+#define RES4335_SR_SLEEP 27
+#define RES4335_HT_START 28
+#define RES4335_HT_AVAIL 29
+#define RES4335_MACPHY_CLKAVAIL 30
+
+/* 4335 Chip specific ChipStatus register bits */
+#define CST4335_SPROM_MASK 0x00000020
+#define CST4335_SFLASH_MASK 0x00000040
+#define CST4335_RES_INIT_MODE_SHIFT 7
+#define CST4335_RES_INIT_MODE_MASK 0x00000180
+#define CST4335_CHIPMODE_MASK 0xF
+#define CST4335_CHIPMODE_SDIOD(cs) (((cs) & (1 << 0)) != 0) /* SDIO */
+#define CST4335_CHIPMODE_GSPI(cs) (((cs) & (1 << 1)) != 0) /* gSPI */
+#define CST4335_CHIPMODE_USB20D(cs) (((cs) & (1 << 2)) != 0) /* USB || USBDA */
+#define CST4335_CHIPMODE_PCIE(cs) (((cs) & (1 << 3)) != 0) /* PCIE */
+
+/* 4335 Chip specific ChipControl1 register bits */
+#define CCTRL1_4335_GPIO_SEL (1 << 0) /* 1=select GPIOs to be muxed out */
+#define CCTRL1_4335_SDIO_HOST_WAKE (1 << 2) /* SDIO: 1=configure GPIO0 for host wake */
+
+
+#define CR4_RAM_BASE (0x180000)
+
+/* 4335 resources--END */
+
+/* GCI chipcontrol register indices */
+#define CC_GCI_CHIPCTRL_00 (0)
+#define CC_GCI_CHIPCTRL_01 (1)
+#define CC_GCI_CHIPCTRL_02 (2)
+#define CC_GCI_CHIPCTRL_03 (3)
+#define CC_GCI_CHIPCTRL_04 (4)
+#define CC_GCI_CHIPCTRL_05 (5)
+#define CC_GCI_CHIPCTRL_06 (6)
+#define CC_GCI_CHIPCTRL_07 (7)
+#define CC_GCI_CHIPCTRL_08 (8)
+
+#define CC_GCI_NUMCHIPCTRLREGS(cap1) ((cap1 & 0xF00) >> 8)
+
+/* 4335 pins
+* note: only the values set as default/used are added here.
+*/
+#define CC4335_PIN_GPIO_00 (0)
+#define CC4335_PIN_GPIO_01 (1)
+#define CC4335_PIN_GPIO_02 (2)
+#define CC4335_PIN_GPIO_03 (3)
+#define CC4335_PIN_GPIO_04 (4)
+#define CC4335_PIN_GPIO_05 (5)
+#define CC4335_PIN_GPIO_06 (6)
+#define CC4335_PIN_GPIO_07 (7)
+#define CC4335_PIN_GPIO_08 (8)
+#define CC4335_PIN_GPIO_09 (9)
+#define CC4335_PIN_GPIO_10 (10)
+#define CC4335_PIN_GPIO_11 (11)
+#define CC4335_PIN_GPIO_12 (12)
+#define CC4335_PIN_GPIO_13 (13)
+#define CC4335_PIN_GPIO_14 (14)
+#define CC4335_PIN_GPIO_15 (15)
+#define CC4335_PIN_SDIO_CLK (16)
+#define CC4335_PIN_SDIO_CMD (17)
+#define CC4335_PIN_SDIO_DATA0 (18)
+#define CC4335_PIN_SDIO_DATA1 (19)
+#define CC4335_PIN_SDIO_DATA2 (20)
+#define CC4335_PIN_SDIO_DATA3 (21)
+#define CC4335_PIN_RF_SW_CTRL_0 (22)
+#define CC4335_PIN_RF_SW_CTRL_1 (23)
+#define CC4335_PIN_RF_SW_CTRL_2 (24)
+#define CC4335_PIN_RF_SW_CTRL_3 (25)
+#define CC4335_PIN_RF_SW_CTRL_4 (26)
+#define CC4335_PIN_RF_SW_CTRL_5 (27)
+#define CC4335_PIN_RF_SW_CTRL_6 (28)
+#define CC4335_PIN_RF_SW_CTRL_7 (29)
+#define CC4335_PIN_RF_SW_CTRL_8 (30)
+#define CC4335_PIN_RF_SW_CTRL_9 (31)
+
+/* 4335 GCI function sel values
+*/
+#define CC4335_FNSEL_HWDEF (0)
+#define CC4335_FNSEL_SAMEASPIN (1)
+#define CC4335_FNSEL_GPIO0 (2)
+#define CC4335_FNSEL_GPIO1 (3)
+#define CC4335_FNSEL_GCI0 (4)
+#define CC4335_FNSEL_GCI1 (5)
+#define CC4335_FNSEL_UART (6)
+#define CC4335_FNSEL_SFLASH (7)
+#define CC4335_FNSEL_SPROM (8)
+#define CC4335_FNSEL_MISC0 (9)
+#define CC4335_FNSEL_MISC1 (10)
+#define CC4335_FNSEL_MISC2 (11)
+#define CC4335_FNSEL_IND (12)
+#define CC4335_FNSEL_PDN (13)
+#define CC4335_FNSEL_PUP (14)
+#define CC4335_FNSEL_TRI (15)
+
+/* find the 4 bit mask given the bit position */
+#define GCIMASK(pos) (((uint32)0xF) << pos)
+
+/* get the value which can be used to directly OR with chipcontrol reg */
+#define GCIPOSVAL(val, pos) ((((uint32)val) << pos) & GCIMASK(pos))
+
+/* 4335 MUX options. each nibble belongs to a setting. Non-zero value specifies a logic
+* for now only UART for bootloader.
+*/
+#define MUXENAB4335_UART_MASK (0x0000000f)
+
+
+/* defines to detect active host interface in use */
+#define CHIP_HOSTIF_USB(sih) (si_chip_hostif(sih) & CST4360_MODE_USB)
+
+/*
+* Maximum delay for the PMU state transition in us.
+* This is an upper bound intended for spinwaits etc.
+*/
+#define PMU_MAX_TRANSITION_DLY 15000
+
+/* PMU resource up transition time in ILP cycles */
+#define PMURES_UP_TRANSITION 2
+
+
+/* SECI configuration */
+#define SECI_MODE_UART 0x0
+#define SECI_MODE_SECI 0x1
+#define SECI_MODE_LEGACY_3WIRE_BT 0x2
+#define SECI_MODE_LEGACY_3WIRE_WLAN 0x3
+#define SECI_MODE_HALF_SECI 0x4
+
+#define SECI_RESET (1 << 0)
+#define SECI_RESET_BAR_UART (1 << 1)
+#define SECI_ENAB_SECI_ECI (1 << 2)
+#define SECI_ENAB_SECIOUT_DIS (1 << 3)
+#define SECI_MODE_MASK 0x7
+#define SECI_MODE_SHIFT 4 /* (bits 5, 6, 7) */
+#define SECI_UPD_SECI (1 << 7)
+
+#define SECI_SIGNOFF_0 0xDB
+#define SECI_SIGNOFF_1 0
+
+/* seci clk_ctl_st bits */
+#define CLKCTL_STS_SECI_CLK_REQ (1 << 8)
+#define CLKCTL_STS_SECI_CLK_AVAIL (1 << 24)
+
+#define SECI_UART_MSR_CTS_STATE (1 << 0)
+#define SECI_UART_MSR_RTS_STATE (1 << 1)
+#define SECI_UART_SECI_IN_STATE (1 << 2)
+#define SECI_UART_SECI_IN2_STATE (1 << 3)
+
+/* SECI UART LCR/MCR register bits */
+#define SECI_UART_LCR_STOP_BITS (1 << 0) /* 0 - 1bit, 1 - 2bits */
+#define SECI_UART_LCR_PARITY_EN (1 << 1)
+#define SECI_UART_LCR_PARITY (1 << 2) /* 0 - odd, 1 - even */
+#define SECI_UART_LCR_RX_EN (1 << 3)
+#define SECI_UART_LCR_LBRK_CTRL (1 << 4) /* 1 => SECI_OUT held low */
+#define SECI_UART_LCR_TXO_EN (1 << 5)
+#define SECI_UART_LCR_RTSO_EN (1 << 6)
+#define SECI_UART_LCR_SLIPMODE_EN (1 << 7)
+#define SECI_UART_LCR_RXCRC_CHK (1 << 8)
+#define SECI_UART_LCR_TXCRC_INV (1 << 9)
+#define SECI_UART_LCR_TXCRC_LSBF (1 << 10)
+#define SECI_UART_LCR_TXCRC_EN (1 << 11)
+
+#define SECI_UART_MCR_TX_EN (1 << 0)
+#define SECI_UART_MCR_PRTS (1 << 1)
+#define SECI_UART_MCR_SWFLCTRL_EN (1 << 2)
+#define SECI_UART_MCR_HIGHRATE_EN (1 << 3)
+#define SECI_UART_MCR_LOOPBK_EN (1 << 4)
+#define SECI_UART_MCR_AUTO_RTS (1 << 5)
+#define SECI_UART_MCR_AUTO_TX_DIS (1 << 6)
+#define SECI_UART_MCR_BAUD_ADJ_EN (1 << 7)
+#define SECI_UART_MCR_XONOFF_RPT (1 << 9)
+
+/* WLAN channel numbers - used from wifi.h */
+
+/* WLAN BW */
+#define ECI_BW_20 0x0
+#define ECI_BW_25 0x1
+#define ECI_BW_30 0x2
+#define ECI_BW_35 0x3
+#define ECI_BW_40 0x4
+#define ECI_BW_45 0x5
+#define ECI_BW_50 0x6
+#define ECI_BW_ALL 0x7
+
+/* WLAN - number of antenna */
+#define WLAN_NUM_ANT1 TXANT_0
+#define WLAN_NUM_ANT2 TXANT_1
+
+#endif /* _SBCHIPC_H */
diff --git a/drivers/net/wireless/ap6210/include/sbconfig.h b/drivers/net/wireless/ap6210/include/sbconfig.h
new file mode 100644
index 0000000..73ddadd
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sbconfig.h
@@ -0,0 +1,282 @@
+/*
+ * Broadcom SiliconBackplane hardware register definitions.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sbconfig.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _SBCONFIG_H
+#define _SBCONFIG_H
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif
+
+/* enumeration in SB is based on the premise that cores are contiguos in the
+ * enumeration space.
+ */
+#define SB_BUS_SIZE 0x10000 /* Each bus gets 64Kbytes for cores */
+#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE)
+#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) /* Max cores per bus */
+
+/*
+ * Sonics Configuration Space Registers.
+ */
+#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */
+#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */
+
+#define SBIPSFLAG 0x08
+#define SBTPSFLAG 0x18
+#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */
+#define SBTMERRLOG 0x50 /* sonics >= 2.3 */
+#define SBADMATCH3 0x60
+#define SBADMATCH2 0x68
+#define SBADMATCH1 0x70
+#define SBIMSTATE 0x90
+#define SBINTVEC 0x94
+#define SBTMSTATELOW 0x98
+#define SBTMSTATEHIGH 0x9c
+#define SBBWA0 0xa0
+#define SBIMCONFIGLOW 0xa8
+#define SBIMCONFIGHIGH 0xac
+#define SBADMATCH0 0xb0
+#define SBTMCONFIGLOW 0xb8
+#define SBTMCONFIGHIGH 0xbc
+#define SBBCONFIG 0xc0
+#define SBBSTATE 0xc8
+#define SBACTCNFG 0xd8
+#define SBFLAGST 0xe8
+#define SBIDLOW 0xf8
+#define SBIDHIGH 0xfc
+
+/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have
+ * a few registers *below* that line. I think it would be very confusing to try
+ * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here,
+ */
+
+#define SBIMERRLOGA 0xea8
+#define SBIMERRLOG 0xeb0
+#define SBTMPORTCONNID0 0xed8
+#define SBTMPORTLOCK0 0xef8
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+typedef volatile struct _sbconfig {
+ uint32 PAD[2];
+ uint32 sbipsflag; /* initiator port ocp slave flag */
+ uint32 PAD[3];
+ uint32 sbtpsflag; /* target port ocp slave flag */
+ uint32 PAD[11];
+ uint32 sbtmerrloga; /* (sonics >= 2.3) */
+ uint32 PAD;
+ uint32 sbtmerrlog; /* (sonics >= 2.3) */
+ uint32 PAD[3];
+ uint32 sbadmatch3; /* address match3 */
+ uint32 PAD;
+ uint32 sbadmatch2; /* address match2 */
+ uint32 PAD;
+ uint32 sbadmatch1; /* address match1 */
+ uint32 PAD[7];
+ uint32 sbimstate; /* initiator agent state */
+ uint32 sbintvec; /* interrupt mask */
+ uint32 sbtmstatelow; /* target state */
+ uint32 sbtmstatehigh; /* target state */
+ uint32 sbbwa0; /* bandwidth allocation table0 */
+ uint32 PAD;
+ uint32 sbimconfiglow; /* initiator configuration */
+ uint32 sbimconfighigh; /* initiator configuration */
+ uint32 sbadmatch0; /* address match0 */
+ uint32 PAD;
+ uint32 sbtmconfiglow; /* target configuration */
+ uint32 sbtmconfighigh; /* target configuration */
+ uint32 sbbconfig; /* broadcast configuration */
+ uint32 PAD;
+ uint32 sbbstate; /* broadcast state */
+ uint32 PAD[3];
+ uint32 sbactcnfg; /* activate configuration */
+ uint32 PAD[3];
+ uint32 sbflagst; /* current sbflags */
+ uint32 PAD[3];
+ uint32 sbidlow; /* identification */
+ uint32 sbidhigh; /* identification */
+} sbconfig_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* sbipsflag */
+#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */
+#define SBIPS_INT1_SHIFT 0
+#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */
+#define SBIPS_INT2_SHIFT 8
+#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */
+#define SBIPS_INT3_SHIFT 16
+#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */
+#define SBIPS_INT4_SHIFT 24
+
+/* sbtpsflag */
+#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */
+#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */
+
+/* sbtmerrlog */
+#define SBTMEL_CM 0x00000007 /* command */
+#define SBTMEL_CI 0x0000ff00 /* connection id */
+#define SBTMEL_EC 0x0f000000 /* error code */
+#define SBTMEL_ME 0x80000000 /* multiple error */
+
+/* sbimstate */
+#define SBIM_PC 0xf /* pipecount */
+#define SBIM_AP_MASK 0x30 /* arbitration policy */
+#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */
+#define SBIM_AP_TS 0x10 /* use timesliaces only */
+#define SBIM_AP_TK 0x20 /* use token only */
+#define SBIM_AP_RSV 0x30 /* reserved */
+#define SBIM_IBE 0x20000 /* inbanderror */
+#define SBIM_TO 0x40000 /* timeout */
+#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */
+#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */
+
+/* sbtmstatelow */
+#define SBTML_RESET 0x0001 /* reset */
+#define SBTML_REJ_MASK 0x0006 /* reject field */
+#define SBTML_REJ 0x0002 /* reject */
+#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */
+
+#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */
+
+/* sbtmstatehigh */
+#define SBTMH_SERR 0x0001 /* serror */
+#define SBTMH_INT 0x0002 /* interrupt */
+#define SBTMH_BUSY 0x0004 /* busy */
+#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */
+
+#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */
+
+/* sbbwa0 */
+#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */
+#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */
+#define SBBWA_TAB1_SHIFT 16
+
+/* sbimconfiglow */
+#define SBIMCL_STO_MASK 0x7 /* service timeout */
+#define SBIMCL_RTO_MASK 0x70 /* request timeout */
+#define SBIMCL_RTO_SHIFT 4
+#define SBIMCL_CID_MASK 0xff0000 /* connection id */
+#define SBIMCL_CID_SHIFT 16
+
+/* sbimconfighigh */
+#define SBIMCH_IEM_MASK 0xc /* inband error mode */
+#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */
+#define SBIMCH_TEM_SHIFT 4
+#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */
+#define SBIMCH_BEM_SHIFT 6
+
+/* sbadmatch0 */
+#define SBAM_TYPE_MASK 0x3 /* address type */
+#define SBAM_AD64 0x4 /* reserved */
+#define SBAM_ADINT0_MASK 0xf8 /* type0 size */
+#define SBAM_ADINT0_SHIFT 3
+#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */
+#define SBAM_ADINT1_SHIFT 3
+#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */
+#define SBAM_ADINT2_SHIFT 3
+#define SBAM_ADEN 0x400 /* enable */
+#define SBAM_ADNEG 0x800 /* negative decode */
+#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */
+#define SBAM_BASE0_SHIFT 8
+#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */
+#define SBAM_BASE1_SHIFT 12
+#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */
+#define SBAM_BASE2_SHIFT 16
+
+/* sbtmconfiglow */
+#define SBTMCL_CD_MASK 0xff /* clock divide */
+#define SBTMCL_CO_MASK 0xf800 /* clock offset */
+#define SBTMCL_CO_SHIFT 11
+#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */
+#define SBTMCL_IF_SHIFT 18
+#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */
+#define SBTMCL_IM_SHIFT 24
+
+/* sbtmconfighigh */
+#define SBTMCH_BM_MASK 0x3 /* busy mode */
+#define SBTMCH_RM_MASK 0x3 /* retry mode */
+#define SBTMCH_RM_SHIFT 2
+#define SBTMCH_SM_MASK 0x30 /* stop mode */
+#define SBTMCH_SM_SHIFT 4
+#define SBTMCH_EM_MASK 0x300 /* sb error mode */
+#define SBTMCH_EM_SHIFT 8
+#define SBTMCH_IM_MASK 0xc00 /* int mode */
+#define SBTMCH_IM_SHIFT 10
+
+/* sbbconfig */
+#define SBBC_LAT_MASK 0x3 /* sb latency */
+#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */
+#define SBBC_MAX0_SHIFT 16
+#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */
+#define SBBC_MAX1_SHIFT 20
+
+/* sbbstate */
+#define SBBS_SRD 0x1 /* st reg disable */
+#define SBBS_HRD 0x2 /* hold reg disable */
+
+/* sbidlow */
+#define SBIDL_CS_MASK 0x3 /* config space */
+#define SBIDL_AR_MASK 0x38 /* # address ranges supported */
+#define SBIDL_AR_SHIFT 3
+#define SBIDL_SYNCH 0x40 /* sync */
+#define SBIDL_INIT 0x80 /* initiator */
+#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */
+#define SBIDL_MINLAT_SHIFT 8
+#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */
+#define SBIDL_MAXLAT_SHIFT 12
+#define SBIDL_FIRST 0x10000 /* this initiator is first */
+#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */
+#define SBIDL_CW_SHIFT 18
+#define SBIDL_TP_MASK 0xf00000 /* target ports */
+#define SBIDL_TP_SHIFT 20
+#define SBIDL_IP_MASK 0xf000000 /* initiator ports */
+#define SBIDL_IP_SHIFT 24
+#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */
+#define SBIDL_RV_SHIFT 28
+#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */
+#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */
+
+/* sbidhigh */
+#define SBIDH_RC_MASK 0x000f /* revision code */
+#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */
+#define SBIDH_RCE_SHIFT 8
+#define SBCOREREV(sbidh) \
+ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK))
+#define SBIDH_CC_MASK 0x8ff0 /* core code */
+#define SBIDH_CC_SHIFT 4
+#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
+#define SBIDH_VC_SHIFT 16
+
+#define SB_COMMIT 0xfd8 /* update buffered registers value */
+
+/* vendor codes */
+#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */
+
+#endif /* _SBCONFIG_H */
diff --git a/drivers/net/wireless/ap6210/include/sbhnddma.h b/drivers/net/wireless/ap6210/include/sbhnddma.h
new file mode 100644
index 0000000..40ebd8a
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sbhnddma.h
@@ -0,0 +1,384 @@
+/*
+ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface
+ * This supports the following chips: BCM42xx, 44xx, 47xx .
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sbhnddma.h 309193 2012-01-19 00:03:57Z $
+ */
+
+#ifndef _sbhnddma_h_
+#define _sbhnddma_h_
+
+/* DMA structure:
+ * support two DMA engines: 32 bits address or 64 bit addressing
+ * basic DMA register set is per channel(transmit or receive)
+ * a pair of channels is defined for convenience
+ */
+
+
+/* 32 bits addressing */
+
+/* dma registers per channel(xmt or rcv) */
+typedef volatile struct {
+ uint32 control; /* enable, et al */
+ uint32 addr; /* descriptor ring base address (4K aligned) */
+ uint32 ptr; /* last descriptor posted to chip */
+ uint32 status; /* current active descriptor, et al */
+} dma32regs_t;
+
+typedef volatile struct {
+ dma32regs_t xmt; /* dma tx channel */
+ dma32regs_t rcv; /* dma rx channel */
+} dma32regp_t;
+
+typedef volatile struct { /* diag access */
+ uint32 fifoaddr; /* diag address */
+ uint32 fifodatalow; /* low 32bits of data */
+ uint32 fifodatahigh; /* high 32bits of data */
+ uint32 pad; /* reserved */
+} dma32diag_t;
+
+/*
+ * DMA Descriptor
+ * Descriptors are only read by the hardware, never written back.
+ */
+typedef volatile struct {
+ uint32 ctrl; /* misc control bits & bufcount */
+ uint32 addr; /* data buffer address */
+} dma32dd_t;
+
+/*
+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
+ */
+#define D32RINGALIGN_BITS 12
+#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS)
+#define D32RINGALIGN (1 << D32RINGALIGN_BITS)
+
+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t))
+
+/* transmit channel control */
+#define XC_XE ((uint32)1 << 0) /* transmit enable */
+#define XC_SE ((uint32)1 << 1) /* transmit suspend request */
+#define XC_LE ((uint32)1 << 2) /* loopback enable */
+#define XC_FL ((uint32)1 << 4) /* flush request */
+#define XC_MR_MASK 0x000000C0 /* Multiple outstanding reads */
+#define XC_MR_SHIFT 6
+#define XC_PD ((uint32)1 << 11) /* parity check disable */
+#define XC_AE ((uint32)3 << 16) /* address extension bits */
+#define XC_AE_SHIFT 16
+#define XC_BL_MASK 0x001C0000 /* BurstLen bits */
+#define XC_BL_SHIFT 18
+#define XC_PC_MASK 0x00E00000 /* Prefetch control */
+#define XC_PC_SHIFT 21
+#define XC_PT_MASK 0x03000000 /* Prefetch threshold */
+#define XC_PT_SHIFT 24
+
+/* Multiple outstanding reads */
+#define DMA_MR_1 0
+#define DMA_MR_2 1
+/* 2, 3: reserved */
+
+/* DMA Burst Length in bytes */
+#define DMA_BL_16 0
+#define DMA_BL_32 1
+#define DMA_BL_64 2
+#define DMA_BL_128 3
+#define DMA_BL_256 4
+#define DMA_BL_512 5
+#define DMA_BL_1024 6
+
+/* Prefetch control */
+#define DMA_PC_0 0
+#define DMA_PC_4 1
+#define DMA_PC_8 2
+#define DMA_PC_16 3
+/* others: reserved */
+
+/* Prefetch threshold */
+#define DMA_PT_1 0
+#define DMA_PT_2 1
+#define DMA_PT_4 2
+#define DMA_PT_8 3
+
+/* transmit descriptor table pointer */
+#define XP_LD_MASK 0xfff /* last valid descriptor */
+
+/* transmit channel status */
+#define XS_CD_MASK 0x0fff /* current descriptor pointer */
+#define XS_XS_MASK 0xf000 /* transmit state */
+#define XS_XS_SHIFT 12
+#define XS_XS_DISABLED 0x0000 /* disabled */
+#define XS_XS_ACTIVE 0x1000 /* active */
+#define XS_XS_IDLE 0x2000 /* idle wait */
+#define XS_XS_STOPPED 0x3000 /* stopped */
+#define XS_XS_SUSP 0x4000 /* suspend pending */
+#define XS_XE_MASK 0xf0000 /* transmit errors */
+#define XS_XE_SHIFT 16
+#define XS_XE_NOERR 0x00000 /* no error */
+#define XS_XE_DPE 0x10000 /* descriptor protocol error */
+#define XS_XE_DFU 0x20000 /* data fifo underrun */
+#define XS_XE_BEBR 0x30000 /* bus error on buffer read */
+#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */
+#define XS_AD_MASK 0xfff00000 /* active descriptor */
+#define XS_AD_SHIFT 20
+
+/* receive channel control */
+#define RC_RE ((uint32)1 << 0) /* receive enable */
+#define RC_RO_MASK 0xfe /* receive frame offset */
+#define RC_RO_SHIFT 1
+#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */
+#define RC_SH ((uint32)1 << 9) /* separate rx header descriptor enable */
+#define RC_OC ((uint32)1 << 10) /* overflow continue */
+#define RC_PD ((uint32)1 << 11) /* parity check disable */
+#define RC_AE ((uint32)3 << 16) /* address extension bits */
+#define RC_AE_SHIFT 16
+#define RC_BL_MASK 0x001C0000 /* BurstLen bits */
+#define RC_BL_SHIFT 18
+#define RC_PC_MASK 0x00E00000 /* Prefetch control */
+#define RC_PC_SHIFT 21
+#define RC_PT_MASK 0x03000000 /* Prefetch threshold */
+#define RC_PT_SHIFT 24
+
+/* receive descriptor table pointer */
+#define RP_LD_MASK 0xfff /* last valid descriptor */
+
+/* receive channel status */
+#define RS_CD_MASK 0x0fff /* current descriptor pointer */
+#define RS_RS_MASK 0xf000 /* receive state */
+#define RS_RS_SHIFT 12
+#define RS_RS_DISABLED 0x0000 /* disabled */
+#define RS_RS_ACTIVE 0x1000 /* active */
+#define RS_RS_IDLE 0x2000 /* idle wait */
+#define RS_RS_STOPPED 0x3000 /* reserved */
+#define RS_RE_MASK 0xf0000 /* receive errors */
+#define RS_RE_SHIFT 16
+#define RS_RE_NOERR 0x00000 /* no error */
+#define RS_RE_DPE 0x10000 /* descriptor protocol error */
+#define RS_RE_DFO 0x20000 /* data fifo overflow */
+#define RS_RE_BEBW 0x30000 /* bus error on buffer write */
+#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */
+#define RS_AD_MASK 0xfff00000 /* active descriptor */
+#define RS_AD_SHIFT 20
+
+/* fifoaddr */
+#define FA_OFF_MASK 0xffff /* offset */
+#define FA_SEL_MASK 0xf0000 /* select */
+#define FA_SEL_SHIFT 16
+#define FA_SEL_XDD 0x00000 /* transmit dma data */
+#define FA_SEL_XDP 0x10000 /* transmit dma pointers */
+#define FA_SEL_RDD 0x40000 /* receive dma data */
+#define FA_SEL_RDP 0x50000 /* receive dma pointers */
+#define FA_SEL_XFD 0x80000 /* transmit fifo data */
+#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */
+#define FA_SEL_RFD 0xc0000 /* receive fifo data */
+#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */
+#define FA_SEL_RSD 0xe0000 /* receive frame status data */
+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */
+
+/* descriptor control flags */
+#define CTRL_BC_MASK 0x00001fff /* buffer byte count, real data len must <= 4KB */
+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */
+#define CTRL_AE_SHIFT 16
+#define CTRL_PARITY ((uint32)3 << 18) /* parity bit */
+#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */
+#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */
+#define CTRL_EOF ((uint32)1 << 30) /* end of frame */
+#define CTRL_SOF ((uint32)1 << 31) /* start of frame */
+
+/* control flags in the range [27:20] are core-specific and not defined here */
+#define CTRL_CORE_MASK 0x0ff00000
+
+/* 64 bits addressing */
+
+/* dma registers per channel(xmt or rcv) */
+typedef volatile struct {
+ uint32 control; /* enable, et al */
+ uint32 ptr; /* last descriptor posted to chip */
+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
+ uint32 status0; /* current descriptor, xmt state */
+ uint32 status1; /* active descriptor, xmt error */
+} dma64regs_t;
+
+typedef volatile struct {
+ dma64regs_t tx; /* dma64 tx channel */
+ dma64regs_t rx; /* dma64 rx channel */
+} dma64regp_t;
+
+typedef volatile struct { /* diag access */
+ uint32 fifoaddr; /* diag address */
+ uint32 fifodatalow; /* low 32bits of data */
+ uint32 fifodatahigh; /* high 32bits of data */
+ uint32 pad; /* reserved */
+} dma64diag_t;
+
+/*
+ * DMA Descriptor
+ * Descriptors are only read by the hardware, never written back.
+ */
+typedef volatile struct {
+ uint32 ctrl1; /* misc control bits */
+ uint32 ctrl2; /* buffer count and address extension */
+ uint32 addrlow; /* memory address of the date buffer, bits 31:0 */
+ uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */
+} dma64dd_t;
+
+/*
+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss.
+ */
+#define D64RINGALIGN_BITS 13
+#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS)
+#define D64RINGALIGN (1 << D64RINGALIGN_BITS)
+
+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t))
+
+/* transmit channel control */
+#define D64_XC_XE 0x00000001 /* transmit enable */
+#define D64_XC_SE 0x00000002 /* transmit suspend request */
+#define D64_XC_LE 0x00000004 /* loopback enable */
+#define D64_XC_FL 0x00000010 /* flush request */
+#define D64_XC_MR_MASK 0x000000C0 /* Multiple outstanding reads */
+#define D64_XC_MR_SHIFT 6
+#define D64_XC_PD 0x00000800 /* parity check disable */
+#define D64_XC_AE 0x00030000 /* address extension bits */
+#define D64_XC_AE_SHIFT 16
+#define D64_XC_BL_MASK 0x001C0000 /* BurstLen bits */
+#define D64_XC_BL_SHIFT 18
+#define D64_XC_PC_MASK 0x00E00000 /* Prefetch control */
+#define D64_XC_PC_SHIFT 21
+#define D64_XC_PT_MASK 0x03000000 /* Prefetch threshold */
+#define D64_XC_PT_SHIFT 24
+
+/* transmit descriptor table pointer */
+#define D64_XP_LD_MASK 0x00001fff /* last valid descriptor */
+
+/* transmit channel status */
+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
+#define D64_XS0_XS_SHIFT 28
+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
+
+#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */
+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
+#define D64_XS1_XE_SHIFT 28
+#define D64_XS1_XE_NOERR 0x00000000 /* no error */
+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
+#define D64_XS1_XE_COREE 0x50000000 /* core error */
+
+/* receive channel control */
+#define D64_RC_RE 0x00000001 /* receive enable */
+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */
+#define D64_RC_RO_SHIFT 1
+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */
+#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */
+#define D64_RC_OC 0x00000400 /* overflow continue */
+#define D64_RC_PD 0x00000800 /* parity check disable */
+#define D64_RC_AE 0x00030000 /* address extension bits */
+#define D64_RC_AE_SHIFT 16
+#define D64_RC_BL_MASK 0x001C0000 /* BurstLen bits */
+#define D64_RC_BL_SHIFT 18
+#define D64_RC_PC_MASK 0x00E00000 /* Prefetch control */
+#define D64_RC_PC_SHIFT 21
+#define D64_RC_PT_MASK 0x03000000 /* Prefetch threshold */
+#define D64_RC_PT_SHIFT 24
+
+/* flags for dma controller */
+#define DMA_CTRL_PEN (1 << 0) /* partity enable */
+#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */
+#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */
+#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */
+#define DMA_CTRL_USB_BOUNDRY4KB_WAR (1 << 4)
+#define DMA_CTRL_DMA_AVOIDANCE_WAR (1 << 5) /* DMA avoidance WAR for 4331 */
+
+/* receive descriptor table pointer */
+#define D64_RP_LD_MASK 0x00001fff /* last valid descriptor */
+
+/* receive channel status */
+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
+#define D64_RS0_RS_SHIFT 28
+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
+
+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
+#define D64_RS1_RE_SHIFT 28
+#define D64_RS1_RE_NOERR 0x00000000 /* no error */
+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
+#define D64_RS1_RE_COREE 0x50000000 /* core error */
+
+/* fifoaddr */
+#define D64_FA_OFF_MASK 0xffff /* offset */
+#define D64_FA_SEL_MASK 0xf0000 /* select */
+#define D64_FA_SEL_SHIFT 16
+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
+
+/* descriptor control flags 1 */
+#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */
+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */
+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */
+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */
+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */
+
+/* descriptor control flags 2 */
+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */
+#define D64_CTRL2_AE 0x00030000 /* address extension bits */
+#define D64_CTRL2_AE_SHIFT 16
+#define D64_CTRL2_PARITY 0x00040000 /* parity bit */
+
+/* control flags in the range [27:20] are core-specific and not defined here */
+#define D64_CTRL_CORE_MASK 0x0ff00000
+
+#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */
+#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */
+#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1, d11corerev >= 22 */
+#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */
+
+/* receive frame status */
+typedef volatile struct {
+ uint16 len;
+ uint16 flags;
+} dma_rxh_t;
+
+#endif /* _sbhnddma_h_ */
diff --git a/drivers/net/wireless/ap6210/include/sbpcmcia.h b/drivers/net/wireless/ap6210/include/sbpcmcia.h
new file mode 100644
index 0000000..c4e9d46
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sbpcmcia.h
@@ -0,0 +1,113 @@
+/*
+ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sbpcmcia.h 326494 2012-04-09 13:29:57Z $
+ */
+
+#ifndef _SBPCMCIA_H
+#define _SBPCMCIA_H
+
+/* All the addresses that are offsets in attribute space are divided
+ * by two to account for the fact that odd bytes are invalid in
+ * attribute space and our read/write routines make the space appear
+ * as if they didn't exist. Still we want to show the original numbers
+ * as documented in the hnd_pcmcia core manual.
+ */
+
+/* PCMCIA Function Configuration Registers */
+#define PCMCIA_FCR (0x700 / 2)
+
+#define FCR0_OFF 0
+#define FCR1_OFF (0x40 / 2)
+#define FCR2_OFF (0x80 / 2)
+#define FCR3_OFF (0xc0 / 2)
+
+#define PCMCIA_FCR0 (0x700 / 2)
+#define PCMCIA_FCR1 (0x740 / 2)
+#define PCMCIA_FCR2 (0x780 / 2)
+#define PCMCIA_FCR3 (0x7c0 / 2)
+
+/* Standard PCMCIA FCR registers */
+
+#define PCMCIA_COR 0
+
+#define COR_RST 0x80
+#define COR_LEV 0x40
+#define COR_IRQEN 0x04
+#define COR_BLREN 0x01
+#define COR_FUNEN 0x01
+
+
+#define PCICIA_FCSR (2 / 2)
+#define PCICIA_PRR (4 / 2)
+#define PCICIA_SCR (6 / 2)
+#define PCICIA_ESR (8 / 2)
+
+
+#define PCM_MEMOFF 0x0000
+#define F0_MEMOFF 0x1000
+#define F1_MEMOFF 0x2000
+#define F2_MEMOFF 0x3000
+#define F3_MEMOFF 0x4000
+
+/* Memory base in the function fcr's */
+#define MEM_ADDR0 (0x728 / 2)
+#define MEM_ADDR1 (0x72a / 2)
+#define MEM_ADDR2 (0x72c / 2)
+
+/* PCMCIA base plus Srom access in fcr0: */
+#define PCMCIA_ADDR0 (0x072e / 2)
+#define PCMCIA_ADDR1 (0x0730 / 2)
+#define PCMCIA_ADDR2 (0x0732 / 2)
+
+#define MEM_SEG (0x0734 / 2)
+#define SROM_CS (0x0736 / 2)
+#define SROM_DATAL (0x0738 / 2)
+#define SROM_DATAH (0x073a / 2)
+#define SROM_ADDRL (0x073c / 2)
+#define SROM_ADDRH (0x073e / 2)
+#define SROM_INFO2 (0x0772 / 2) /* Corerev >= 2 && <= 5 */
+#define SROM_INFO (0x07be / 2) /* Corerev >= 6 */
+
+/* Values for srom_cs: */
+#define SROM_IDLE 0
+#define SROM_WRITE 1
+#define SROM_READ 2
+#define SROM_WEN 4
+#define SROM_WDS 7
+#define SROM_DONE 8
+
+/* Fields in srom_info: */
+#define SRI_SZ_MASK 0x03
+#define SRI_BLANK 0x04
+#define SRI_OTP 0x80
+
+
+/* sbtmstatelow */
+#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */
+#define SBTML_INT_EN 0x20000 /* enable sb interrupt */
+
+/* sbtmstatehigh */
+#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */
+
+#endif /* _SBPCMCIA_H */
diff --git a/drivers/net/wireless/ap6210/include/sbsdio.h b/drivers/net/wireless/ap6210/include/sbsdio.h
new file mode 100644
index 0000000..8d0139d
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sbsdio.h
@@ -0,0 +1,188 @@
+/*
+ * SDIO device core hardware definitions.
+ * sdio is a portion of the pcmcia core in core rev 3 - rev 8
+ *
+ * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sbsdio.h 361940 2012-10-10 08:32:12Z $
+ */
+
+#ifndef _SBSDIO_H
+#define _SBSDIO_H
+
+#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */
+
+/* function 1 miscellaneous registers */
+#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */
+#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */
+#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */
+#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */
+#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */
+#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */
+#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */
+#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */
+#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */
+#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */
+
+/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */
+#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */
+#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */
+#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */
+#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */
+#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */
+#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */
+#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */
+#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */
+#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */
+#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */
+#define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D /* MesBusyCtl at 0x1001D (rev 11) */
+
+#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */
+#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */
+
+/* Sdio Core Rev 12 */
+#define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E
+#define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1
+#define SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT 0
+#define SBSDIO_FUNC1_WCTRL_HTWAIT_MASK 0x2
+#define SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT 1
+#define SBSDIO_FUNC1_SLEEPCSR 0x1001F
+#define SBSDIO_FUNC1_SLEEPCSR_KSO_MASK 0x1
+#define SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT 0
+#define SBSDIO_FUNC1_SLEEPCSR_KSO_EN 1
+#define SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK 0x2
+#define SBSDIO_FUNC1_SLEEPCSR_DEVON_SHIFT 1
+
+/* SBSDIO_SPROM_CS */
+#define SBSDIO_SPROM_IDLE 0
+#define SBSDIO_SPROM_WRITE 1
+#define SBSDIO_SPROM_READ 2
+#define SBSDIO_SPROM_WEN 4
+#define SBSDIO_SPROM_WDS 7
+#define SBSDIO_SPROM_DONE 8
+
+/* SBSDIO_SPROM_INFO */
+#define SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */
+#define SROM_BLANK 0x04 /* depreciated in corerev 6 */
+#define SROM_OTP 0x80 /* OTP present */
+
+/* SBSDIO_CHIP_CTRL */
+#define SBSDIO_CHIP_CTRL_XTAL 0x01 /* or'd with onchip xtal_pu,
+ * 1: power on oscillator
+ * (for 4318 only)
+ */
+/* SBSDIO_WATERMARK */
+#define SBSDIO_WATERMARK_MASK 0x7f /* number of words - 1 for sd device
+ * to wait before sending data to host
+ */
+
+/* SBSDIO_MESBUSYCTRL */
+/* When RX FIFO has less entries than this & MBE is set
+ * => busy signal is asserted between data blocks.
+*/
+#define SBSDIO_MESBUSYCTRL_MASK 0x7f
+
+/* SBSDIO_DEVICE_CTL */
+#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when
+ * receiving CMD53
+ */
+#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is
+ * synchronous to the sdio clock
+ */
+#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host
+ * except the chipActive (rev 8)
+ */
+#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put
+ * external pads in tri-state; requires
+ * sdio bus power cycle to clear (rev 9)
+ */
+#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */
+#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */
+#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */
+#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */
+#define SBSDIO_DEVCTL_EN_F2_BLK_WATERMARK 0x10 /* Enable function 2 tx for each block */
+
+
+/* SBSDIO_FUNC1_CHIPCLKCSR */
+#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */
+#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */
+#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */
+#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */
+#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */
+#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */
+#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */
+#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */
+/* In rev8, actual avail bits followed original docs */
+#define SBSDIO_Rev8_HT_AVAIL 0x40
+#define SBSDIO_Rev8_ALP_AVAIL 0x80
+#define SBSDIO_CSR_MASK 0x1F
+
+#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
+#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
+#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
+#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
+#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \
+ (alponly ? 1 : SBSDIO_HTAV(regval)))
+
+/* SBSDIO_FUNC1_SDIOPULLUP */
+#define SBSDIO_PULLUP_D0 0x01 /* Enable D0/MISO pullup */
+#define SBSDIO_PULLUP_D1 0x02 /* Enable D1/INT# pullup */
+#define SBSDIO_PULLUP_D2 0x04 /* Enable D2 pullup */
+#define SBSDIO_PULLUP_CMD 0x08 /* Enable CMD/MOSI pullup */
+#define SBSDIO_PULLUP_ALL 0x0f /* All valid bits */
+
+/* function 1 OCP space */
+#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */
+#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
+#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */
+
+/* some duplication with sbsdpcmdev.h here */
+/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
+#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */
+#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */
+#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */
+#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */
+
+/* direct(mapped) cis space */
+#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */
+#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */
+#define SBSDIO_OTP_CIS_SIZE_LIMIT 0x078 /* maximum bytes OTP CIS */
+
+#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */
+
+#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple,
+ * link bytes
+ */
+
+/* indirect cis access (in sprom) */
+#define SBSDIO_SPROM_CIS_OFFSET 0x8 /* 8 control bytes first, CIS starts from
+ * 8th byte
+ */
+
+#define SBSDIO_BYTEMODE_DATALEN_MAX 64 /* sdio byte mode: maximum length of one
+ * data comamnd
+ */
+
+#define SBSDIO_CORE_ADDR_MASK 0x1FFFF /* sdio core function one address mask */
+
+#endif /* _SBSDIO_H */
diff --git a/drivers/net/wireless/ap6210/include/sbsdpcmdev.h b/drivers/net/wireless/ap6210/include/sbsdpcmdev.h
new file mode 100644
index 0000000..10c7401
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sbsdpcmdev.h
@@ -0,0 +1,295 @@
+/*
+ * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific
+ * device core support
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sbsdpcmdev.h 347614 2012-07-27 10:24:51Z $
+ */
+
+#ifndef _sbsdpcmdev_h_
+#define _sbsdpcmdev_h_
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif /* PAD */
+
+
+typedef volatile struct {
+ dma64regs_t xmt; /* dma tx */
+ uint32 PAD[2];
+ dma64regs_t rcv; /* dma rx */
+ uint32 PAD[2];
+} dma64p_t;
+
+/* dma64 sdiod corerev >= 1 */
+typedef volatile struct {
+ dma64p_t dma64regs[2];
+ dma64diag_t dmafifo; /* DMA Diagnostic Regs, 0x280-0x28c */
+ uint32 PAD[92];
+} sdiodma64_t;
+
+/* dma32 sdiod corerev == 0 */
+typedef volatile struct {
+ dma32regp_t dma32regs[2]; /* dma tx & rx, 0x200-0x23c */
+ dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x240-0x24c */
+ uint32 PAD[108];
+} sdiodma32_t;
+
+/* dma32 regs for pcmcia core */
+typedef volatile struct {
+ dma32regp_t dmaregs; /* DMA Regs, 0x200-0x21c, rev8 */
+ dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x220-0x22c */
+ uint32 PAD[116];
+} pcmdma32_t;
+
+/* core registers */
+typedef volatile struct {
+ uint32 corecontrol; /* CoreControl, 0x000, rev8 */
+ uint32 corestatus; /* CoreStatus, 0x004, rev8 */
+ uint32 PAD[1];
+ uint32 biststatus; /* BistStatus, 0x00c, rev8 */
+
+ /* PCMCIA access */
+ uint16 pcmciamesportaladdr; /* PcmciaMesPortalAddr, 0x010, rev8 */
+ uint16 PAD[1];
+ uint16 pcmciamesportalmask; /* PcmciaMesPortalMask, 0x014, rev8 */
+ uint16 PAD[1];
+ uint16 pcmciawrframebc; /* PcmciaWrFrameBC, 0x018, rev8 */
+ uint16 PAD[1];
+ uint16 pcmciaunderflowtimer; /* PcmciaUnderflowTimer, 0x01c, rev8 */
+ uint16 PAD[1];
+
+ /* interrupt */
+ uint32 intstatus; /* IntStatus, 0x020, rev8 */
+ uint32 hostintmask; /* IntHostMask, 0x024, rev8 */
+ uint32 intmask; /* IntSbMask, 0x028, rev8 */
+ uint32 sbintstatus; /* SBIntStatus, 0x02c, rev8 */
+ uint32 sbintmask; /* SBIntMask, 0x030, rev8 */
+ uint32 funcintmask; /* SDIO Function Interrupt Mask, SDIO rev4 */
+ uint32 PAD[2];
+ uint32 tosbmailbox; /* ToSBMailbox, 0x040, rev8 */
+ uint32 tohostmailbox; /* ToHostMailbox, 0x044, rev8 */
+ uint32 tosbmailboxdata; /* ToSbMailboxData, 0x048, rev8 */
+ uint32 tohostmailboxdata; /* ToHostMailboxData, 0x04c, rev8 */
+
+ /* synchronized access to registers in SDIO clock domain */
+ uint32 sdioaccess; /* SdioAccess, 0x050, rev8 */
+ uint32 PAD[3];
+
+ /* PCMCIA frame control */
+ uint8 pcmciaframectrl; /* pcmciaFrameCtrl, 0x060, rev8 */
+ uint8 PAD[3];
+ uint8 pcmciawatermark; /* pcmciaWaterMark, 0x064, rev8 */
+ uint8 PAD[155];
+
+ /* interrupt batching control */
+ uint32 intrcvlazy; /* IntRcvLazy, 0x100, rev8 */
+ uint32 PAD[3];
+
+ /* counters */
+ uint32 cmd52rd; /* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */
+ uint32 cmd52wr; /* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */
+ uint32 cmd53rd; /* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */
+ uint32 cmd53wr; /* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */
+ uint32 abort; /* AbortCount, 0x120, rev8, SDIO: aborts */
+ uint32 datacrcerror; /* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */
+ uint32 rdoutofsync; /* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */
+ uint32 wroutofsync; /* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */
+ uint32 writebusy; /* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */
+ uint32 readwait; /* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */
+ uint32 readterm; /* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */
+ uint32 writeterm; /* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */
+ uint32 PAD[40];
+ uint32 clockctlstatus; /* ClockCtlStatus, 0x1e0, rev8 */
+ uint32 PAD[7];
+
+ /* DMA engines */
+ volatile union {
+ pcmdma32_t pcm32;
+ sdiodma32_t sdiod32;
+ sdiodma64_t sdiod64;
+ } dma;
+
+ /* SDIO/PCMCIA CIS region */
+ char cis[512]; /* 512 byte CIS, 0x400-0x5ff, rev6 */
+
+ /* PCMCIA function control registers */
+ char pcmciafcr[256]; /* PCMCIA FCR, 0x600-6ff, rev6 */
+ uint16 PAD[55];
+
+ /* PCMCIA backplane access */
+ uint16 backplanecsr; /* BackplaneCSR, 0x76E, rev6 */
+ uint16 backplaneaddr0; /* BackplaneAddr0, 0x770, rev6 */
+ uint16 backplaneaddr1; /* BackplaneAddr1, 0x772, rev6 */
+ uint16 backplaneaddr2; /* BackplaneAddr2, 0x774, rev6 */
+ uint16 backplaneaddr3; /* BackplaneAddr3, 0x776, rev6 */
+ uint16 backplanedata0; /* BackplaneData0, 0x778, rev6 */
+ uint16 backplanedata1; /* BackplaneData1, 0x77a, rev6 */
+ uint16 backplanedata2; /* BackplaneData2, 0x77c, rev6 */
+ uint16 backplanedata3; /* BackplaneData3, 0x77e, rev6 */
+ uint16 PAD[31];
+
+ /* sprom "size" & "blank" info */
+ uint16 spromstatus; /* SPROMStatus, 0x7BE, rev2 */
+ uint32 PAD[464];
+
+ /* Sonics SiliconBackplane registers */
+ sbconfig_t sbconfig; /* SbConfig Regs, 0xf00-0xfff, rev8 */
+} sdpcmd_regs_t;
+
+/* corecontrol */
+#define CC_CISRDY (1 << 0) /* CIS Ready */
+#define CC_BPRESEN (1 << 1) /* CCCR RES signal causes backplane reset */
+#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */
+#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation bit (rev 11) */
+#define CC_XMTDATAAVAIL_MODE (1 << 4) /* data avail generates an interrupt */
+#define CC_XMTDATAAVAIL_CTRL (1 << 5) /* data avail interrupt ctrl */
+
+/* corestatus */
+#define CS_PCMCIAMODE (1 << 0) /* Device Mode; 0=SDIO, 1=PCMCIA */
+#define CS_SMARTDEV (1 << 1) /* 1=smartDev enabled */
+#define CS_F2ENABLED (1 << 2) /* 1=host has enabled the device */
+
+#define PCMCIA_MES_PA_MASK 0x7fff /* PCMCIA Message Portal Address Mask */
+#define PCMCIA_MES_PM_MASK 0x7fff /* PCMCIA Message Portal Mask Mask */
+#define PCMCIA_WFBC_MASK 0xffff /* PCMCIA Write Frame Byte Count Mask */
+#define PCMCIA_UT_MASK 0x07ff /* PCMCIA Underflow Timer Mask */
+
+/* intstatus */
+#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
+#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
+#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */
+#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */
+#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */
+#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */
+#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */
+#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */
+#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */
+#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */
+#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */
+#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */
+#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */
+#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */
+#define I_PC (1 << 10) /* descriptor error */
+#define I_PD (1 << 11) /* data error */
+#define I_DE (1 << 12) /* Descriptor protocol Error */
+#define I_RU (1 << 13) /* Receive descriptor Underflow */
+#define I_RO (1 << 14) /* Receive fifo Overflow */
+#define I_XU (1 << 15) /* Transmit fifo Underflow */
+#define I_RI (1 << 16) /* Receive Interrupt */
+#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */
+#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */
+#define I_XI (1 << 24) /* Transmit Interrupt */
+#define I_RF_TERM (1 << 25) /* Read Frame Terminate */
+#define I_WF_TERM (1 << 26) /* Write Frame Terminate */
+#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */
+#define I_SBINT (1 << 28) /* sbintstatus Interrupt */
+#define I_CHIPACTIVE (1 << 29) /* chip transitioned from doze to active state */
+#define I_SRESET (1 << 30) /* CCCR RES interrupt */
+#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */
+#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) /* DMA Errors */
+#define I_DMA (I_RI | I_XI | I_ERRORS)
+
+/* sbintstatus */
+#define I_SB_SERR (1 << 8) /* Backplane SError (write) */
+#define I_SB_RESPERR (1 << 9) /* Backplane Response Error (read) */
+#define I_SB_SPROMERR (1 << 10) /* Error accessing the sprom */
+
+/* sdioaccess */
+#define SDA_DATA_MASK 0x000000ff /* Read/Write Data Mask */
+#define SDA_ADDR_MASK 0x000fff00 /* Read/Write Address Mask */
+#define SDA_ADDR_SHIFT 8 /* Read/Write Address Shift */
+#define SDA_WRITE 0x01000000 /* Write bit */
+#define SDA_READ 0x00000000 /* Write bit cleared for Read */
+#define SDA_BUSY 0x80000000 /* Busy bit */
+
+/* sdioaccess-accessible register address spaces */
+#define SDA_CCCR_SPACE 0x000 /* sdioAccess CCCR register space */
+#define SDA_F1_FBR_SPACE 0x100 /* sdioAccess F1 FBR register space */
+#define SDA_F2_FBR_SPACE 0x200 /* sdioAccess F2 FBR register space */
+#define SDA_F1_REG_SPACE 0x300 /* sdioAccess F1 core-specific register space */
+
+/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */
+#define SDA_CHIPCONTROLDATA 0x006 /* ChipControlData */
+#define SDA_CHIPCONTROLENAB 0x007 /* ChipControlEnable */
+#define SDA_F2WATERMARK 0x008 /* Function 2 Watermark */
+#define SDA_DEVICECONTROL 0x009 /* DeviceControl */
+#define SDA_SBADDRLOW 0x00a /* SbAddrLow */
+#define SDA_SBADDRMID 0x00b /* SbAddrMid */
+#define SDA_SBADDRHIGH 0x00c /* SbAddrHigh */
+#define SDA_FRAMECTRL 0x00d /* FrameCtrl */
+#define SDA_CHIPCLOCKCSR 0x00e /* ChipClockCSR */
+#define SDA_SDIOPULLUP 0x00f /* SdioPullUp */
+#define SDA_SDIOWRFRAMEBCLOW 0x019 /* SdioWrFrameBCLow */
+#define SDA_SDIOWRFRAMEBCHIGH 0x01a /* SdioWrFrameBCHigh */
+#define SDA_SDIORDFRAMEBCLOW 0x01b /* SdioRdFrameBCLow */
+#define SDA_SDIORDFRAMEBCHIGH 0x01c /* SdioRdFrameBCHigh */
+
+/* SDA_F2WATERMARK */
+#define SDA_F2WATERMARK_MASK 0x7f /* F2Watermark Mask */
+
+/* SDA_SBADDRLOW */
+#define SDA_SBADDRLOW_MASK 0x80 /* SbAddrLow Mask */
+
+/* SDA_SBADDRMID */
+#define SDA_SBADDRMID_MASK 0xff /* SbAddrMid Mask */
+
+/* SDA_SBADDRHIGH */
+#define SDA_SBADDRHIGH_MASK 0xff /* SbAddrHigh Mask */
+
+/* SDA_FRAMECTRL */
+#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */
+#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */
+#define SFC_CRC4WOOS (1 << 2) /* HW reports CRC error for write out of sync */
+#define SFC_ABORTALL (1 << 3) /* Abort cancels all in-progress frames */
+
+/* pcmciaframectrl */
+#define PFC_RF_TERM (1 << 0) /* Read Frame Terminate */
+#define PFC_WF_TERM (1 << 1) /* Write Frame Terminate */
+
+/* intrcvlazy */
+#define IRL_TO_MASK 0x00ffffff /* timeout */
+#define IRL_FC_MASK 0xff000000 /* frame count */
+#define IRL_FC_SHIFT 24 /* frame count */
+
+/* rx header */
+typedef volatile struct {
+ uint16 len;
+ uint16 flags;
+} sdpcmd_rxh_t;
+
+/* rx header flags */
+#define RXF_CRC 0x0001 /* CRC error detected */
+#define RXF_WOOS 0x0002 /* write frame out of sync */
+#define RXF_WF_TERM 0x0004 /* write frame terminated */
+#define RXF_ABORT 0x0008 /* write frame aborted */
+#define RXF_DISCARD (RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT) /* bad frame */
+
+/* HW frame tag */
+#define SDPCM_FRAMETAG_LEN 4 /* HW frametag: 2 bytes len, 2 bytes check val */
+
+#define SDPCM_HWEXT_LEN 8
+
+#endif /* _sbsdpcmdev_h_ */
diff --git a/drivers/net/wireless/ap6210/include/sbsocram.h b/drivers/net/wireless/ap6210/include/sbsocram.h
new file mode 100644
index 0000000..6455f2b
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sbsocram.h
@@ -0,0 +1,199 @@
+/*
+ * BCM47XX Sonics SiliconBackplane embedded ram core
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sbsocram.h 271781 2011-07-13 20:00:06Z $
+ */
+
+#ifndef _SBSOCRAM_H
+#define _SBSOCRAM_H
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif /* PAD */
+
+/* Memcsocram core registers */
+typedef volatile struct sbsocramregs {
+ uint32 coreinfo;
+ uint32 bwalloc;
+ uint32 extracoreinfo;
+ uint32 biststat;
+ uint32 bankidx;
+ uint32 standbyctrl;
+
+ uint32 errlogstatus; /* rev 6 */
+ uint32 errlogaddr; /* rev 6 */
+ /* used for patching rev 3 & 5 */
+ uint32 cambankidx;
+ uint32 cambankstandbyctrl;
+ uint32 cambankpatchctrl;
+ uint32 cambankpatchtblbaseaddr;
+ uint32 cambankcmdreg;
+ uint32 cambankdatareg;
+ uint32 cambankmaskreg;
+ uint32 PAD[1];
+ uint32 bankinfo; /* corev 8 */
+ uint32 PAD[15];
+ uint32 extmemconfig;
+ uint32 extmemparitycsr;
+ uint32 extmemparityerrdata;
+ uint32 extmemparityerrcnt;
+ uint32 extmemwrctrlandsize;
+ uint32 PAD[84];
+ uint32 workaround;
+ uint32 pwrctl; /* corerev >= 2 */
+ uint32 PAD[133];
+ uint32 sr_control; /* corerev >= 15 */
+ uint32 sr_status; /* corerev >= 15 */
+ uint32 sr_address; /* corerev >= 15 */
+ uint32 sr_data; /* corerev >= 15 */
+} sbsocramregs_t;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* Register offsets */
+#define SR_COREINFO 0x00
+#define SR_BWALLOC 0x04
+#define SR_BISTSTAT 0x0c
+#define SR_BANKINDEX 0x10
+#define SR_BANKSTBYCTL 0x14
+#define SR_PWRCTL 0x1e8
+
+/* Coreinfo register */
+#define SRCI_PT_MASK 0x00070000 /* corerev >= 6; port type[18:16] */
+#define SRCI_PT_SHIFT 16
+/* port types : SRCI_PT_<processorPT>_<backplanePT> */
+#define SRCI_PT_OCP_OCP 0
+#define SRCI_PT_AXI_OCP 1
+#define SRCI_PT_ARM7AHB_OCP 2
+#define SRCI_PT_CM3AHB_OCP 3
+#define SRCI_PT_AXI_AXI 4
+#define SRCI_PT_AHB_AXI 5
+/* corerev >= 3 */
+#define SRCI_LSS_MASK 0x00f00000
+#define SRCI_LSS_SHIFT 20
+#define SRCI_LRS_MASK 0x0f000000
+#define SRCI_LRS_SHIFT 24
+
+/* In corerev 0, the memory size is 2 to the power of the
+ * base plus 16 plus to the contents of the memsize field plus 1.
+ */
+#define SRCI_MS0_MASK 0xf
+#define SR_MS0_BASE 16
+
+/*
+ * In corerev 1 the bank size is 2 ^ the bank size field plus 14,
+ * the memory size is number of banks times bank size.
+ * The same applies to rom size.
+ */
+#define SRCI_ROMNB_MASK 0xf000
+#define SRCI_ROMNB_SHIFT 12
+#define SRCI_ROMBSZ_MASK 0xf00
+#define SRCI_ROMBSZ_SHIFT 8
+#define SRCI_SRNB_MASK 0xf0
+#define SRCI_SRNB_SHIFT 4
+#define SRCI_SRBSZ_MASK 0xf
+#define SRCI_SRBSZ_SHIFT 0
+
+#define SR_BSZ_BASE 14
+
+/* Standby control register */
+#define SRSC_SBYOVR_MASK 0x80000000
+#define SRSC_SBYOVR_SHIFT 31
+#define SRSC_SBYOVRVAL_MASK 0x60000000
+#define SRSC_SBYOVRVAL_SHIFT 29
+#define SRSC_SBYEN_MASK 0x01000000 /* rev >= 3 */
+#define SRSC_SBYEN_SHIFT 24
+
+/* Power control register */
+#define SRPC_PMU_STBYDIS_MASK 0x00000010 /* rev >= 3 */
+#define SRPC_PMU_STBYDIS_SHIFT 4
+#define SRPC_STBYOVRVAL_MASK 0x00000008
+#define SRPC_STBYOVRVAL_SHIFT 3
+#define SRPC_STBYOVR_MASK 0x00000007
+#define SRPC_STBYOVR_SHIFT 0
+
+/* Extra core capability register */
+#define SRECC_NUM_BANKS_MASK 0x000000F0
+#define SRECC_NUM_BANKS_SHIFT 4
+#define SRECC_BANKSIZE_MASK 0x0000000F
+#define SRECC_BANKSIZE_SHIFT 0
+
+#define SRECC_BANKSIZE(value) (1 << (value))
+
+/* CAM bank patch control */
+#define SRCBPC_PATCHENABLE 0x80000000
+
+#define SRP_ADDRESS 0x0001FFFC
+#define SRP_VALID 0x8000
+
+/* CAM bank command reg */
+#define SRCMD_WRITE 0x00020000
+#define SRCMD_READ 0x00010000
+#define SRCMD_DONE 0x80000000
+
+#define SRCMD_DONE_DLY 1000
+
+/* bankidx and bankinfo reg defines corerev >= 8 */
+#define SOCRAM_BANKINFO_SZMASK 0x7f
+#define SOCRAM_BANKIDX_ROM_MASK 0x100
+
+#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8
+/* socram bankinfo memtype */
+#define SOCRAM_MEMTYPE_RAM 0
+#define SOCRAM_MEMTYPE_R0M 1
+#define SOCRAM_MEMTYPE_DEVRAM 2
+
+#define SOCRAM_BANKINFO_REG 0x40
+#define SOCRAM_BANKIDX_REG 0x10
+#define SOCRAM_BANKINFO_STDBY_MASK 0x400
+#define SOCRAM_BANKINFO_STDBY_TIMER 0x800
+
+/* bankinfo rev >= 10 */
+#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13
+#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000
+#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14
+#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000
+#define SOCRAM_BANKINFO_SLPSUPP_SHIFT 15
+#define SOCRAM_BANKINFO_SLPSUPP_MASK 0x8000
+#define SOCRAM_BANKINFO_RETNTRAM_SHIFT 16
+#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000
+#define SOCRAM_BANKINFO_PDASZ_SHIFT 17
+#define SOCRAM_BANKINFO_PDASZ_MASK 0x003E0000
+#define SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT 24
+#define SOCRAM_BANKINFO_DEVRAMREMAP_MASK 0x01000000
+
+/* extracoreinfo register */
+#define SOCRAM_DEVRAMBANK_MASK 0xF000
+#define SOCRAM_DEVRAMBANK_SHIFT 12
+
+/* bank info to calculate bank size */
+#define SOCRAM_BANKINFO_SZBASE 8192
+#define SOCRAM_BANKSIZE_SHIFT 13 /* SOCRAM_BANKINFO_SZBASE */
+
+
+#endif /* _SBSOCRAM_H */
diff --git a/drivers/net/wireless/ap6210/include/sdio.h b/drivers/net/wireless/ap6210/include/sdio.h
new file mode 100644
index 0000000..b8eee1f
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sdio.h
@@ -0,0 +1,617 @@
+/*
+ * SDIO spec header file
+ * Protocol and standard (common) device definitions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sdio.h 308973 2012-01-18 04:19:34Z $
+ */
+
+#ifndef _SDIO_H
+#define _SDIO_H
+
+
+/* CCCR structure for function 0 */
+typedef volatile struct {
+ uint8 cccr_sdio_rev; /* RO, cccr and sdio revision */
+ uint8 sd_rev; /* RO, sd spec revision */
+ uint8 io_en; /* I/O enable */
+ uint8 io_rdy; /* I/O ready reg */
+ uint8 intr_ctl; /* Master and per function interrupt enable control */
+ uint8 intr_status; /* RO, interrupt pending status */
+ uint8 io_abort; /* read/write abort or reset all functions */
+ uint8 bus_inter; /* bus interface control */
+ uint8 capability; /* RO, card capability */
+
+ uint8 cis_base_low; /* 0x9 RO, common CIS base address, LSB */
+ uint8 cis_base_mid;
+ uint8 cis_base_high; /* 0xB RO, common CIS base address, MSB */
+
+ /* suspend/resume registers */
+ uint8 bus_suspend; /* 0xC */
+ uint8 func_select; /* 0xD */
+ uint8 exec_flag; /* 0xE */
+ uint8 ready_flag; /* 0xF */
+
+ uint8 fn0_blk_size[2]; /* 0x10(LSB), 0x11(MSB) */
+
+ uint8 power_control; /* 0x12 (SDIO version 1.10) */
+
+ uint8 speed_control; /* 0x13 */
+} sdio_regs_t;
+
+/* SDIO Device CCCR offsets */
+#define SDIOD_CCCR_REV 0x00
+#define SDIOD_CCCR_SDREV 0x01
+#define SDIOD_CCCR_IOEN 0x02
+#define SDIOD_CCCR_IORDY 0x03
+#define SDIOD_CCCR_INTEN 0x04
+#define SDIOD_CCCR_INTPEND 0x05
+#define SDIOD_CCCR_IOABORT 0x06
+#define SDIOD_CCCR_BICTRL 0x07
+#define SDIOD_CCCR_CAPABLITIES 0x08
+#define SDIOD_CCCR_CISPTR_0 0x09
+#define SDIOD_CCCR_CISPTR_1 0x0A
+#define SDIOD_CCCR_CISPTR_2 0x0B
+#define SDIOD_CCCR_BUSSUSP 0x0C
+#define SDIOD_CCCR_FUNCSEL 0x0D
+#define SDIOD_CCCR_EXECFLAGS 0x0E
+#define SDIOD_CCCR_RDYFLAGS 0x0F
+#define SDIOD_CCCR_BLKSIZE_0 0x10
+#define SDIOD_CCCR_BLKSIZE_1 0x11
+#define SDIOD_CCCR_POWER_CONTROL 0x12
+#define SDIOD_CCCR_SPEED_CONTROL 0x13
+#define SDIOD_CCCR_UHSI_SUPPORT 0x14
+#define SDIOD_CCCR_DRIVER_STRENGTH 0x15
+#define SDIOD_CCCR_INTR_EXTN 0x16
+
+/* Broadcom extensions (corerev >= 1) */
+#define SDIOD_CCCR_BRCM_CARDCAP 0xf0
+#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02
+#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04
+#define SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08
+#define SDIOD_CCCR_BRCM_CARDCTL 0xf1
+#define SDIOD_CCCR_BRCM_SEPINT 0xf2
+
+/* cccr_sdio_rev */
+#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */
+#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */
+
+/* sd_rev */
+#define SD_REV_PHY_MASK 0x0f /* SD format version number */
+
+/* io_en */
+#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */
+#define SDIO_FUNC_ENABLE_2 0x04 /* function 2 I/O enable */
+
+/* io_rdys */
+#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */
+#define SDIO_FUNC_READY_2 0x04 /* function 2 I/O ready */
+
+/* intr_ctl */
+#define INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */
+#define INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */
+#define INTR_CTL_FUNC2_EN 0x4 /* interrupt enable for function 2 */
+
+/* intr_status */
+#define INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */
+#define INTR_STATUS_FUNC2 0x4 /* interrupt pending for function 2 */
+
+/* io_abort */
+#define IO_ABORT_RESET_ALL 0x08 /* I/O card reset */
+#define IO_ABORT_FUNC_MASK 0x07 /* abort selction: function x */
+
+/* bus_inter */
+#define BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */
+#define BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */
+#define BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */
+#define BUS_SD_DATA_WIDTH_MASK 0x03 /* bus width mask */
+#define BUS_SD_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */
+#define BUS_SD_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */
+
+/* capability */
+#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */
+#define SDIO_CAP_LSC 0x40 /* low speed card */
+#define SDIO_CAP_E4MI 0x20 /* enable interrupt between block of data in 4-bit mode */
+#define SDIO_CAP_S4MI 0x10 /* support interrupt between block of data in 4-bit mode */
+#define SDIO_CAP_SBS 0x08 /* support suspend/resume */
+#define SDIO_CAP_SRW 0x04 /* support read wait */
+#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */
+#define SDIO_CAP_SDC 0x01 /* Support Direct commands during multi-byte transfer */
+
+/* power_control */
+#define SDIO_POWER_SMPC 0x01 /* supports master power control (RO) */
+#define SDIO_POWER_EMPC 0x02 /* enable master power control (allow > 200mA) (RW) */
+
+/* speed_control (control device entry into high-speed clocking mode) */
+#define SDIO_SPEED_SHS 0x01 /* supports high-speed [clocking] mode (RO) */
+#define SDIO_SPEED_EHS 0x02 /* enable high-speed [clocking] mode (RW) */
+
+/* for setting bus speed in card: 0x13h */
+#define SDIO_BUS_SPEED_UHSISEL_M BITFIELD_MASK(3)
+#define SDIO_BUS_SPEED_UHSISEL_S 1
+
+/* for getting bus speed cap in card: 0x14h */
+#define SDIO_BUS_SPEED_UHSICAP_M BITFIELD_MASK(3)
+#define SDIO_BUS_SPEED_UHSICAP_S 0
+
+/* for getting driver type CAP in card: 0x15h */
+#define SDIO_BUS_DRVR_TYPE_CAP_M BITFIELD_MASK(3)
+#define SDIO_BUS_DRVR_TYPE_CAP_S 0
+
+/* for setting driver type selection in card: 0x15h */
+#define SDIO_BUS_DRVR_TYPE_SEL_M BITFIELD_MASK(2)
+#define SDIO_BUS_DRVR_TYPE_SEL_S 4
+
+/* for getting async int support in card: 0x16h */
+#define SDIO_BUS_ASYNCINT_CAP_M BITFIELD_MASK(1)
+#define SDIO_BUS_ASYNCINT_CAP_S 0
+
+/* for setting async int selection in card: 0x16h */
+#define SDIO_BUS_ASYNCINT_SEL_M BITFIELD_MASK(1)
+#define SDIO_BUS_ASYNCINT_SEL_S 1
+
+/* brcm sepint */
+#define SDIO_SEPINT_MASK 0x01 /* route sdpcmdev intr onto separate pad (chip-specific) */
+#define SDIO_SEPINT_OE 0x02 /* 1 asserts output enable for above pad */
+#define SDIO_SEPINT_ACT_HI 0x04 /* use active high interrupt level instead of active low */
+
+/* FBR structure for function 1-7, FBR addresses and register offsets */
+typedef volatile struct {
+ uint8 devctr; /* device interface, CSA control */
+ uint8 ext_dev; /* extended standard I/O device type code */
+ uint8 pwr_sel; /* power selection support */
+ uint8 PAD[6]; /* reserved */
+
+ uint8 cis_low; /* CIS LSB */
+ uint8 cis_mid;
+ uint8 cis_high; /* CIS MSB */
+ uint8 csa_low; /* code storage area, LSB */
+ uint8 csa_mid;
+ uint8 csa_high; /* code storage area, MSB */
+ uint8 csa_dat_win; /* data access window to function */
+
+ uint8 fnx_blk_size[2]; /* block size, little endian */
+} sdio_fbr_t;
+
+/* Maximum number of I/O funcs */
+#define SDIOD_MAX_FUNCS 8
+#define SDIOD_MAX_IOFUNCS 7
+
+/* SDIO Device FBR Start Address */
+#define SDIOD_FBR_STARTADDR 0x100
+
+/* SDIO Device FBR Size */
+#define SDIOD_FBR_SIZE 0x100
+
+/* Macro to calculate FBR register base */
+#define SDIOD_FBR_BASE(n) ((n) * 0x100)
+
+/* Function register offsets */
+#define SDIOD_FBR_DEVCTR 0x00 /* basic info for function */
+#define SDIOD_FBR_EXT_DEV 0x01 /* extended I/O device code */
+#define SDIOD_FBR_PWR_SEL 0x02 /* power selection bits */
+
+/* SDIO Function CIS ptr offset */
+#define SDIOD_FBR_CISPTR_0 0x09
+#define SDIOD_FBR_CISPTR_1 0x0A
+#define SDIOD_FBR_CISPTR_2 0x0B
+
+/* Code Storage Area pointer */
+#define SDIOD_FBR_CSA_ADDR_0 0x0C
+#define SDIOD_FBR_CSA_ADDR_1 0x0D
+#define SDIOD_FBR_CSA_ADDR_2 0x0E
+#define SDIOD_FBR_CSA_DATA 0x0F
+
+/* SDIO Function I/O Block Size */
+#define SDIOD_FBR_BLKSIZE_0 0x10
+#define SDIOD_FBR_BLKSIZE_1 0x11
+
+/* devctr */
+#define SDIOD_FBR_DEVCTR_DIC 0x0f /* device interface code */
+#define SDIOD_FBR_DECVTR_CSA 0x40 /* CSA support flag */
+#define SDIOD_FBR_DEVCTR_CSA_EN 0x80 /* CSA enabled */
+/* interface codes */
+#define SDIOD_DIC_NONE 0 /* SDIO standard interface is not supported */
+#define SDIOD_DIC_UART 1
+#define SDIOD_DIC_BLUETOOTH_A 2
+#define SDIOD_DIC_BLUETOOTH_B 3
+#define SDIOD_DIC_GPS 4
+#define SDIOD_DIC_CAMERA 5
+#define SDIOD_DIC_PHS 6
+#define SDIOD_DIC_WLAN 7
+#define SDIOD_DIC_EXT 0xf /* extended device interface, read ext_dev register */
+
+/* pwr_sel */
+#define SDIOD_PWR_SEL_SPS 0x01 /* supports power selection */
+#define SDIOD_PWR_SEL_EPS 0x02 /* enable power selection (low-current mode) */
+
+/* misc defines */
+#define SDIO_FUNC_0 0
+#define SDIO_FUNC_1 1
+#define SDIO_FUNC_2 2
+#define SDIO_FUNC_3 3
+#define SDIO_FUNC_4 4
+#define SDIO_FUNC_5 5
+#define SDIO_FUNC_6 6
+#define SDIO_FUNC_7 7
+
+#define SD_CARD_TYPE_UNKNOWN 0 /* bad type or unrecognized */
+#define SD_CARD_TYPE_IO 1 /* IO only card */
+#define SD_CARD_TYPE_MEMORY 2 /* memory only card */
+#define SD_CARD_TYPE_COMBO 3 /* IO and memory combo card */
+
+#define SDIO_MAX_BLOCK_SIZE 2048 /* maximum block size for block mode operation */
+#define SDIO_MIN_BLOCK_SIZE 1 /* minimum block size for block mode operation */
+
+/* Card registers: status bit position */
+#define CARDREG_STATUS_BIT_OUTOFRANGE 31
+#define CARDREG_STATUS_BIT_COMCRCERROR 23
+#define CARDREG_STATUS_BIT_ILLEGALCOMMAND 22
+#define CARDREG_STATUS_BIT_ERROR 19
+#define CARDREG_STATUS_BIT_IOCURRENTSTATE3 12
+#define CARDREG_STATUS_BIT_IOCURRENTSTATE2 11
+#define CARDREG_STATUS_BIT_IOCURRENTSTATE1 10
+#define CARDREG_STATUS_BIT_IOCURRENTSTATE0 9
+#define CARDREG_STATUS_BIT_FUN_NUM_ERROR 4
+
+
+
+#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */
+#define SD_CMD_SEND_OPCOND 1
+#define SD_CMD_MMC_SET_RCA 3
+#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */
+#define SD_CMD_SELECT_DESELECT_CARD 7
+#define SD_CMD_SEND_CSD 9
+#define SD_CMD_SEND_CID 10
+#define SD_CMD_STOP_TRANSMISSION 12
+#define SD_CMD_SEND_STATUS 13
+#define SD_CMD_GO_INACTIVE_STATE 15
+#define SD_CMD_SET_BLOCKLEN 16
+#define SD_CMD_READ_SINGLE_BLOCK 17
+#define SD_CMD_READ_MULTIPLE_BLOCK 18
+#define SD_CMD_WRITE_BLOCK 24
+#define SD_CMD_WRITE_MULTIPLE_BLOCK 25
+#define SD_CMD_PROGRAM_CSD 27
+#define SD_CMD_SET_WRITE_PROT 28
+#define SD_CMD_CLR_WRITE_PROT 29
+#define SD_CMD_SEND_WRITE_PROT 30
+#define SD_CMD_ERASE_WR_BLK_START 32
+#define SD_CMD_ERASE_WR_BLK_END 33
+#define SD_CMD_ERASE 38
+#define SD_CMD_LOCK_UNLOCK 42
+#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */
+#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */
+#define SD_CMD_APP_CMD 55
+#define SD_CMD_GEN_CMD 56
+#define SD_CMD_READ_OCR 58
+#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */
+#define SD_ACMD_SD_STATUS 13
+#define SD_ACMD_SEND_NUM_WR_BLOCKS 22
+#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23
+#define SD_ACMD_SD_SEND_OP_COND 41
+#define SD_ACMD_SET_CLR_CARD_DETECT 42
+#define SD_ACMD_SEND_SCR 51
+
+/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */
+#define SD_IO_OP_READ 0 /* Read_Write: Read */
+#define SD_IO_OP_WRITE 1 /* Read_Write: Write */
+#define SD_IO_RW_NORMAL 0 /* no RAW */
+#define SD_IO_RW_RAW 1 /* RAW */
+#define SD_IO_BYTE_MODE 0 /* Byte Mode */
+#define SD_IO_BLOCK_MODE 1 /* BlockMode */
+#define SD_IO_FIXED_ADDRESS 0 /* fix Address */
+#define SD_IO_INCREMENT_ADDRESS 1 /* IncrementAddress */
+
+/* build SD_CMD_IO_RW_DIRECT Argument */
+#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \
+ ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \
+ (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF))
+
+/* build SD_CMD_IO_RW_EXTENDED Argument */
+#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \
+ ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \
+ (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF))
+
+/* SDIO response parameters */
+#define SD_RSP_NO_NONE 0
+#define SD_RSP_NO_1 1
+#define SD_RSP_NO_2 2
+#define SD_RSP_NO_3 3
+#define SD_RSP_NO_4 4
+#define SD_RSP_NO_5 5
+#define SD_RSP_NO_6 6
+
+ /* Modified R6 response (to CMD3) */
+#define SD_RSP_MR6_COM_CRC_ERROR 0x8000
+#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000
+#define SD_RSP_MR6_ERROR 0x2000
+
+ /* Modified R1 in R4 Response (to CMD5) */
+#define SD_RSP_MR1_SBIT 0x80
+#define SD_RSP_MR1_PARAMETER_ERROR 0x40
+#define SD_RSP_MR1_RFU5 0x20
+#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10
+#define SD_RSP_MR1_COM_CRC_ERROR 0x08
+#define SD_RSP_MR1_ILLEGAL_COMMAND 0x04
+#define SD_RSP_MR1_RFU1 0x02
+#define SD_RSP_MR1_IDLE_STATE 0x01
+
+ /* R5 response (to CMD52 and CMD53) */
+#define SD_RSP_R5_COM_CRC_ERROR 0x80
+#define SD_RSP_R5_ILLEGAL_COMMAND 0x40
+#define SD_RSP_R5_IO_CURRENTSTATE1 0x20
+#define SD_RSP_R5_IO_CURRENTSTATE0 0x10
+#define SD_RSP_R5_ERROR 0x08
+#define SD_RSP_R5_RFU 0x04
+#define SD_RSP_R5_FUNC_NUM_ERROR 0x02
+#define SD_RSP_R5_OUT_OF_RANGE 0x01
+
+#define SD_RSP_R5_ERRBITS 0xCB
+
+
+/* ------------------------------------------------
+ * SDIO Commands and responses
+ *
+ * I/O only commands are:
+ * CMD0, CMD3, CMD5, CMD7, CMD14, CMD15, CMD52, CMD53
+ * ------------------------------------------------
+ */
+
+/* SDIO Commands */
+#define SDIOH_CMD_0 0
+#define SDIOH_CMD_3 3
+#define SDIOH_CMD_5 5
+#define SDIOH_CMD_7 7
+#define SDIOH_CMD_11 11
+#define SDIOH_CMD_14 14
+#define SDIOH_CMD_15 15
+#define SDIOH_CMD_19 19
+#define SDIOH_CMD_52 52
+#define SDIOH_CMD_53 53
+#define SDIOH_CMD_59 59
+
+/* SDIO Command Responses */
+#define SDIOH_RSP_NONE 0
+#define SDIOH_RSP_R1 1
+#define SDIOH_RSP_R2 2
+#define SDIOH_RSP_R3 3
+#define SDIOH_RSP_R4 4
+#define SDIOH_RSP_R5 5
+#define SDIOH_RSP_R6 6
+
+/*
+ * SDIO Response Error flags
+ */
+#define SDIOH_RSP5_ERROR_FLAGS 0xCB
+
+/* ------------------------------------------------
+ * SDIO Command structures. I/O only commands are:
+ *
+ * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53
+ * ------------------------------------------------
+ */
+
+#define CMD5_OCR_M BITFIELD_MASK(24)
+#define CMD5_OCR_S 0
+
+#define CMD5_S18R_M BITFIELD_MASK(1)
+#define CMD5_S18R_S 24
+
+#define CMD7_RCA_M BITFIELD_MASK(16)
+#define CMD7_RCA_S 16
+
+#define CMD14_RCA_M BITFIELD_MASK(16)
+#define CMD14_RCA_S 16
+#define CMD14_SLEEP_M BITFIELD_MASK(1)
+#define CMD14_SLEEP_S 15
+
+#define CMD_15_RCA_M BITFIELD_MASK(16)
+#define CMD_15_RCA_S 16
+
+#define CMD52_DATA_M BITFIELD_MASK(8) /* Bits [7:0] - Write Data/Stuff bits of CMD52
+ */
+#define CMD52_DATA_S 0
+#define CMD52_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */
+#define CMD52_REG_ADDR_S 9
+#define CMD52_RAW_M BITFIELD_MASK(1) /* Bit 27 - Read after Write flag */
+#define CMD52_RAW_S 27
+#define CMD52_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */
+#define CMD52_FUNCTION_S 28
+#define CMD52_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */
+#define CMD52_RW_FLAG_S 31
+
+
+#define CMD53_BYTE_BLK_CNT_M BITFIELD_MASK(9) /* Bits [8:0] - Byte/Block Count of CMD53 */
+#define CMD53_BYTE_BLK_CNT_S 0
+#define CMD53_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */
+#define CMD53_REG_ADDR_S 9
+#define CMD53_OP_CODE_M BITFIELD_MASK(1) /* Bit 26 - R/W Operation Code */
+#define CMD53_OP_CODE_S 26
+#define CMD53_BLK_MODE_M BITFIELD_MASK(1) /* Bit 27 - Block Mode */
+#define CMD53_BLK_MODE_S 27
+#define CMD53_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */
+#define CMD53_FUNCTION_S 28
+#define CMD53_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */
+#define CMD53_RW_FLAG_S 31
+
+/* ------------------------------------------------------
+ * SDIO Command Response structures for SD1 and SD4 modes
+ * -----------------------------------------------------
+ */
+#define RSP4_IO_OCR_M BITFIELD_MASK(24) /* Bits [23:0] - Card's OCR Bits [23:0] */
+#define RSP4_IO_OCR_S 0
+
+#define RSP4_S18A_M BITFIELD_MASK(1) /* Bits [23:0] - Card's OCR Bits [23:0] */
+#define RSP4_S18A_S 24
+
+#define RSP4_STUFF_M BITFIELD_MASK(3) /* Bits [26:24] - Stuff bits */
+#define RSP4_STUFF_S 24
+#define RSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 27 - Memory present */
+#define RSP4_MEM_PRESENT_S 27
+#define RSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [30:28] - Number of I/O funcs */
+#define RSP4_NUM_FUNCS_S 28
+#define RSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 31 - SDIO card ready */
+#define RSP4_CARD_READY_S 31
+
+#define RSP6_STATUS_M BITFIELD_MASK(16) /* Bits [15:0] - Card status bits [19,22,23,12:0]
+ */
+#define RSP6_STATUS_S 0
+#define RSP6_IO_RCA_M BITFIELD_MASK(16) /* Bits [31:16] - RCA bits[31-16] */
+#define RSP6_IO_RCA_S 16
+
+#define RSP1_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error */
+#define RSP1_AKE_SEQ_ERROR_S 3
+#define RSP1_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */
+#define RSP1_APP_CMD_S 5
+#define RSP1_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data (buff empty) */
+#define RSP1_READY_FOR_DATA_S 8
+#define RSP1_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - State of card
+ * when Cmd was received
+ */
+#define RSP1_CURR_STATE_S 9
+#define RSP1_EARSE_RESET_M BITFIELD_MASK(1) /* Bit 13 - Erase seq cleared */
+#define RSP1_EARSE_RESET_S 13
+#define RSP1_CARD_ECC_DISABLE_M BITFIELD_MASK(1) /* Bit 14 - Card ECC disabled */
+#define RSP1_CARD_ECC_DISABLE_S 14
+#define RSP1_WP_ERASE_SKIP_M BITFIELD_MASK(1) /* Bit 15 - Partial blocks erased due to W/P */
+#define RSP1_WP_ERASE_SKIP_S 15
+#define RSP1_CID_CSD_OVERW_M BITFIELD_MASK(1) /* Bit 16 - Illegal write to CID or R/O bits
+ * of CSD
+ */
+#define RSP1_CID_CSD_OVERW_S 16
+#define RSP1_ERROR_M BITFIELD_MASK(1) /* Bit 19 - General/Unknown error */
+#define RSP1_ERROR_S 19
+#define RSP1_CC_ERROR_M BITFIELD_MASK(1) /* Bit 20 - Internal Card Control error */
+#define RSP1_CC_ERROR_S 20
+#define RSP1_CARD_ECC_FAILED_M BITFIELD_MASK(1) /* Bit 21 - Card internal ECC failed
+ * to correct data
+ */
+#define RSP1_CARD_ECC_FAILED_S 21
+#define RSP1_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 22 - Cmd not legal for the card state */
+#define RSP1_ILLEGAL_CMD_S 22
+#define RSP1_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 23 - CRC check of previous command failed
+ */
+#define RSP1_COM_CRC_ERROR_S 23
+#define RSP1_LOCK_UNLOCK_FAIL_M BITFIELD_MASK(1) /* Bit 24 - Card lock-unlock Cmd Seq error */
+#define RSP1_LOCK_UNLOCK_FAIL_S 24
+#define RSP1_CARD_LOCKED_M BITFIELD_MASK(1) /* Bit 25 - Card locked by the host */
+#define RSP1_CARD_LOCKED_S 25
+#define RSP1_WP_VIOLATION_M BITFIELD_MASK(1) /* Bit 26 - Attempt to program
+ * write-protected blocks
+ */
+#define RSP1_WP_VIOLATION_S 26
+#define RSP1_ERASE_PARAM_M BITFIELD_MASK(1) /* Bit 27 - Invalid erase blocks */
+#define RSP1_ERASE_PARAM_S 27
+#define RSP1_ERASE_SEQ_ERR_M BITFIELD_MASK(1) /* Bit 28 - Erase Cmd seq error */
+#define RSP1_ERASE_SEQ_ERR_S 28
+#define RSP1_BLK_LEN_ERR_M BITFIELD_MASK(1) /* Bit 29 - Block length error */
+#define RSP1_BLK_LEN_ERR_S 29
+#define RSP1_ADDR_ERR_M BITFIELD_MASK(1) /* Bit 30 - Misaligned address */
+#define RSP1_ADDR_ERR_S 30
+#define RSP1_OUT_OF_RANGE_M BITFIELD_MASK(1) /* Bit 31 - Cmd arg was out of range */
+#define RSP1_OUT_OF_RANGE_S 31
+
+
+#define RSP5_DATA_M BITFIELD_MASK(8) /* Bits [0:7] - data */
+#define RSP5_DATA_S 0
+#define RSP5_FLAGS_M BITFIELD_MASK(8) /* Bit [15:8] - Rsp flags */
+#define RSP5_FLAGS_S 8
+#define RSP5_STUFF_M BITFIELD_MASK(16) /* Bits [31:16] - Stuff bits */
+#define RSP5_STUFF_S 16
+
+/* ----------------------------------------------
+ * SDIO Command Response structures for SPI mode
+ * ----------------------------------------------
+ */
+#define SPIRSP4_IO_OCR_M BITFIELD_MASK(16) /* Bits [15:0] - Card's OCR Bits [23:8] */
+#define SPIRSP4_IO_OCR_S 0
+#define SPIRSP4_STUFF_M BITFIELD_MASK(3) /* Bits [18:16] - Stuff bits */
+#define SPIRSP4_STUFF_S 16
+#define SPIRSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 19 - Memory present */
+#define SPIRSP4_MEM_PRESENT_S 19
+#define SPIRSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [22:20] - Number of I/O funcs */
+#define SPIRSP4_NUM_FUNCS_S 20
+#define SPIRSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 23 - SDIO card ready */
+#define SPIRSP4_CARD_READY_S 23
+#define SPIRSP4_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - idle state */
+#define SPIRSP4_IDLE_STATE_S 24
+#define SPIRSP4_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */
+#define SPIRSP4_ILLEGAL_CMD_S 26
+#define SPIRSP4_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */
+#define SPIRSP4_COM_CRC_ERROR_S 27
+#define SPIRSP4_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error
+ */
+#define SPIRSP4_FUNC_NUM_ERROR_S 28
+#define SPIRSP4_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */
+#define SPIRSP4_PARAM_ERROR_S 30
+#define SPIRSP4_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */
+#define SPIRSP4_START_BIT_S 31
+
+#define SPIRSP5_DATA_M BITFIELD_MASK(8) /* Bits [23:16] - R/W Data */
+#define SPIRSP5_DATA_S 16
+#define SPIRSP5_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - Idle state */
+#define SPIRSP5_IDLE_STATE_S 24
+#define SPIRSP5_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */
+#define SPIRSP5_ILLEGAL_CMD_S 26
+#define SPIRSP5_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */
+#define SPIRSP5_COM_CRC_ERROR_S 27
+#define SPIRSP5_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error
+ */
+#define SPIRSP5_FUNC_NUM_ERROR_S 28
+#define SPIRSP5_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */
+#define SPIRSP5_PARAM_ERROR_S 30
+#define SPIRSP5_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */
+#define SPIRSP5_START_BIT_S 31
+
+/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */
+#define RSP6STAT_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error
+ */
+#define RSP6STAT_AKE_SEQ_ERROR_S 3
+#define RSP6STAT_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */
+#define RSP6STAT_APP_CMD_S 5
+#define RSP6STAT_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data
+ * (buff empty)
+ */
+#define RSP6STAT_READY_FOR_DATA_S 8
+#define RSP6STAT_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - Card state at
+ * Cmd reception
+ */
+#define RSP6STAT_CURR_STATE_S 9
+#define RSP6STAT_ERROR_M BITFIELD_MASK(1) /* Bit 13 - General/Unknown error Bit 19
+ */
+#define RSP6STAT_ERROR_S 13
+#define RSP6STAT_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 14 - Illegal cmd for
+ * card state Bit 22
+ */
+#define RSP6STAT_ILLEGAL_CMD_S 14
+#define RSP6STAT_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 15 - CRC previous command
+ * failed Bit 23
+ */
+#define RSP6STAT_COM_CRC_ERROR_S 15
+
+#define SDIOH_XFER_TYPE_READ SD_IO_OP_READ
+#define SDIOH_XFER_TYPE_WRITE SD_IO_OP_WRITE
+
+/* command issue options */
+#define CMD_OPTION_DEFAULT 0
+#define CMD_OPTION_TUNING 1
+#endif /* _SDIO_H */
diff --git a/drivers/net/wireless/ap6210/include/sdioh.h b/drivers/net/wireless/ap6210/include/sdioh.h
new file mode 100644
index 0000000..5517a71
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sdioh.h
@@ -0,0 +1,445 @@
+/*
+ * SDIO Host Controller Spec header file
+ * Register map and definitions for the Standard Host Controller
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sdioh.h 347633 2012-07-27 11:02:02Z $
+ */
+
+#ifndef _SDIOH_H
+#define _SDIOH_H
+
+#define SD_SysAddr 0x000
+#define SD_BlockSize 0x004
+#define SD_BlockCount 0x006
+#define SD_Arg0 0x008
+#define SD_Arg1 0x00A
+#define SD_TransferMode 0x00C
+#define SD_Command 0x00E
+#define SD_Response0 0x010
+#define SD_Response1 0x012
+#define SD_Response2 0x014
+#define SD_Response3 0x016
+#define SD_Response4 0x018
+#define SD_Response5 0x01A
+#define SD_Response6 0x01C
+#define SD_Response7 0x01E
+#define SD_BufferDataPort0 0x020
+#define SD_BufferDataPort1 0x022
+#define SD_PresentState 0x024
+#define SD_HostCntrl 0x028
+#define SD_PwrCntrl 0x029
+#define SD_BlockGapCntrl 0x02A
+#define SD_WakeupCntrl 0x02B
+#define SD_ClockCntrl 0x02C
+#define SD_TimeoutCntrl 0x02E
+#define SD_SoftwareReset 0x02F
+#define SD_IntrStatus 0x030
+#define SD_ErrorIntrStatus 0x032
+#define SD_IntrStatusEnable 0x034
+#define SD_ErrorIntrStatusEnable 0x036
+#define SD_IntrSignalEnable 0x038
+#define SD_ErrorIntrSignalEnable 0x03A
+#define SD_CMD12ErrorStatus 0x03C
+#define SD_Capabilities 0x040
+#define SD_Capabilities3 0x044
+#define SD_MaxCurCap 0x048
+#define SD_MaxCurCap_Reserved 0x04C
+#define SD_ADMA_ErrStatus 0x054
+#define SD_ADMA_SysAddr 0x58
+#define SD_SlotInterruptStatus 0x0FC
+#define SD_HostControllerVersion 0x0FE
+#define SD_GPIO_Reg 0x100
+#define SD_GPIO_OE 0x104
+#define SD_GPIO_Enable 0x108
+
+/* SD specific registers in PCI config space */
+#define SD_SlotInfo 0x40
+
+/* HC 3.0 specific registers and offsets */
+#define SD3_HostCntrl2 0x03E
+/* preset regsstart and count */
+#define SD3_PresetValStart 0x060
+#define SD3_PresetValCount 8
+/* preset-indiv regs */
+#define SD3_PresetVal_init 0x060
+#define SD3_PresetVal_default 0x062
+#define SD3_PresetVal_HS 0x064
+#define SD3_PresetVal_SDR12 0x066
+#define SD3_PresetVal_SDR25 0x068
+#define SD3_PresetVal_SDR50 0x06a
+#define SD3_PresetVal_SDR104 0x06c
+#define SD3_PresetVal_DDR50 0x06e
+/* SDIO3.0 Revx specific Registers */
+#define SD3_Tuning_Info_Register 0x0EC
+#define SD3_WL_BT_reset_register 0x0F0
+
+
+/* preset value indices */
+#define SD3_PRESETVAL_INITIAL_IX 0
+#define SD3_PRESETVAL_DESPEED_IX 1
+#define SD3_PRESETVAL_HISPEED_IX 2
+#define SD3_PRESETVAL_SDR12_IX 3
+#define SD3_PRESETVAL_SDR25_IX 4
+#define SD3_PRESETVAL_SDR50_IX 5
+#define SD3_PRESETVAL_SDR104_IX 6
+#define SD3_PRESETVAL_DDR50_IX 7
+
+/* SD_Capabilities reg (0x040) */
+#define CAP_TO_CLKFREQ_M BITFIELD_MASK(6)
+#define CAP_TO_CLKFREQ_S 0
+#define CAP_TO_CLKUNIT_M BITFIELD_MASK(1)
+#define CAP_TO_CLKUNIT_S 7
+/* Note: for sdio-2.0 case, this mask has to be 6 bits, but msb 2
+ bits are reserved. going ahead with 8 bits, as it is req for 3.0
+*/
+#define CAP_BASECLK_M BITFIELD_MASK(8)
+#define CAP_BASECLK_S 8
+#define CAP_MAXBLOCK_M BITFIELD_MASK(2)
+#define CAP_MAXBLOCK_S 16
+#define CAP_ADMA2_M BITFIELD_MASK(1)
+#define CAP_ADMA2_S 19
+#define CAP_ADMA1_M BITFIELD_MASK(1)
+#define CAP_ADMA1_S 20
+#define CAP_HIGHSPEED_M BITFIELD_MASK(1)
+#define CAP_HIGHSPEED_S 21
+#define CAP_DMA_M BITFIELD_MASK(1)
+#define CAP_DMA_S 22
+#define CAP_SUSPEND_M BITFIELD_MASK(1)
+#define CAP_SUSPEND_S 23
+#define CAP_VOLT_3_3_M BITFIELD_MASK(1)
+#define CAP_VOLT_3_3_S 24
+#define CAP_VOLT_3_0_M BITFIELD_MASK(1)
+#define CAP_VOLT_3_0_S 25
+#define CAP_VOLT_1_8_M BITFIELD_MASK(1)
+#define CAP_VOLT_1_8_S 26
+#define CAP_64BIT_HOST_M BITFIELD_MASK(1)
+#define CAP_64BIT_HOST_S 28
+
+#define SDIO_OCR_READ_FAIL (2)
+
+
+#define CAP_ASYNCINT_SUP_M BITFIELD_MASK(1)
+#define CAP_ASYNCINT_SUP_S 29
+
+#define CAP_SLOTTYPE_M BITFIELD_MASK(2)
+#define CAP_SLOTTYPE_S 30
+
+#define CAP3_MSBits_OFFSET (32)
+/* note: following are caps MSB32 bits.
+ So the bits start from 0, instead of 32. that is why
+ CAP3_MSBits_OFFSET is subtracted.
+*/
+#define CAP3_SDR50_SUP_M BITFIELD_MASK(1)
+#define CAP3_SDR50_SUP_S (32 - CAP3_MSBits_OFFSET)
+
+#define CAP3_SDR104_SUP_M BITFIELD_MASK(1)
+#define CAP3_SDR104_SUP_S (33 - CAP3_MSBits_OFFSET)
+
+#define CAP3_DDR50_SUP_M BITFIELD_MASK(1)
+#define CAP3_DDR50_SUP_S (34 - CAP3_MSBits_OFFSET)
+
+/* for knowing the clk caps in a single read */
+#define CAP3_30CLKCAP_M BITFIELD_MASK(3)
+#define CAP3_30CLKCAP_S (32 - CAP3_MSBits_OFFSET)
+
+#define CAP3_DRIVTYPE_A_M BITFIELD_MASK(1)
+#define CAP3_DRIVTYPE_A_S (36 - CAP3_MSBits_OFFSET)
+
+#define CAP3_DRIVTYPE_C_M BITFIELD_MASK(1)
+#define CAP3_DRIVTYPE_C_S (37 - CAP3_MSBits_OFFSET)
+
+#define CAP3_DRIVTYPE_D_M BITFIELD_MASK(1)
+#define CAP3_DRIVTYPE_D_S (38 - CAP3_MSBits_OFFSET)
+
+#define CAP3_RETUNING_TC_M BITFIELD_MASK(4)
+#define CAP3_RETUNING_TC_S (40 - CAP3_MSBits_OFFSET)
+
+#define CAP3_TUNING_SDR50_M BITFIELD_MASK(1)
+#define CAP3_TUNING_SDR50_S (45 - CAP3_MSBits_OFFSET)
+
+#define CAP3_RETUNING_MODES_M BITFIELD_MASK(2)
+#define CAP3_RETUNING_MODES_S (46 - CAP3_MSBits_OFFSET)
+
+#define CAP3_CLK_MULT_M BITFIELD_MASK(8)
+#define CAP3_CLK_MULT_S (48 - CAP3_MSBits_OFFSET)
+
+#define PRESET_DRIVR_SELECT_M BITFIELD_MASK(2)
+#define PRESET_DRIVR_SELECT_S 14
+
+#define PRESET_CLK_DIV_M BITFIELD_MASK(10)
+#define PRESET_CLK_DIV_S 0
+
+/* SD_MaxCurCap reg (0x048) */
+#define CAP_CURR_3_3_M BITFIELD_MASK(8)
+#define CAP_CURR_3_3_S 0
+#define CAP_CURR_3_0_M BITFIELD_MASK(8)
+#define CAP_CURR_3_0_S 8
+#define CAP_CURR_1_8_M BITFIELD_MASK(8)
+#define CAP_CURR_1_8_S 16
+
+/* SD_SysAddr: Offset 0x0000, Size 4 bytes */
+
+/* SD_BlockSize: Offset 0x004, Size 2 bytes */
+#define BLKSZ_BLKSZ_M BITFIELD_MASK(12)
+#define BLKSZ_BLKSZ_S 0
+#define BLKSZ_BNDRY_M BITFIELD_MASK(3)
+#define BLKSZ_BNDRY_S 12
+
+/* SD_BlockCount: Offset 0x006, size 2 bytes */
+
+/* SD_Arg0: Offset 0x008, size = 4 bytes */
+/* SD_TransferMode Offset 0x00C, size = 2 bytes */
+#define XFER_DMA_ENABLE_M BITFIELD_MASK(1)
+#define XFER_DMA_ENABLE_S 0
+#define XFER_BLK_COUNT_EN_M BITFIELD_MASK(1)
+#define XFER_BLK_COUNT_EN_S 1
+#define XFER_CMD_12_EN_M BITFIELD_MASK(1)
+#define XFER_CMD_12_EN_S 2
+#define XFER_DATA_DIRECTION_M BITFIELD_MASK(1)
+#define XFER_DATA_DIRECTION_S 4
+#define XFER_MULTI_BLOCK_M BITFIELD_MASK(1)
+#define XFER_MULTI_BLOCK_S 5
+
+/* SD_Command: Offset 0x00E, size = 2 bytes */
+/* resp_type field */
+#define RESP_TYPE_NONE 0
+#define RESP_TYPE_136 1
+#define RESP_TYPE_48 2
+#define RESP_TYPE_48_BUSY 3
+/* type field */
+#define CMD_TYPE_NORMAL 0
+#define CMD_TYPE_SUSPEND 1
+#define CMD_TYPE_RESUME 2
+#define CMD_TYPE_ABORT 3
+
+#define CMD_RESP_TYPE_M BITFIELD_MASK(2) /* Bits [0-1] - Response type */
+#define CMD_RESP_TYPE_S 0
+#define CMD_CRC_EN_M BITFIELD_MASK(1) /* Bit 3 - CRC enable */
+#define CMD_CRC_EN_S 3
+#define CMD_INDEX_EN_M BITFIELD_MASK(1) /* Bit 4 - Enable index checking */
+#define CMD_INDEX_EN_S 4
+#define CMD_DATA_EN_M BITFIELD_MASK(1) /* Bit 5 - Using DAT line */
+#define CMD_DATA_EN_S 5
+#define CMD_TYPE_M BITFIELD_MASK(2) /* Bit [6-7] - Normal, abort, resume, etc
+ */
+#define CMD_TYPE_S 6
+#define CMD_INDEX_M BITFIELD_MASK(6) /* Bits [8-13] - Command number */
+#define CMD_INDEX_S 8
+
+/* SD_BufferDataPort0 : Offset 0x020, size = 2 or 4 bytes */
+/* SD_BufferDataPort1 : Offset 0x022, size = 2 bytes */
+/* SD_PresentState : Offset 0x024, size = 4 bytes */
+#define PRES_CMD_INHIBIT_M BITFIELD_MASK(1) /* Bit 0 May use CMD */
+#define PRES_CMD_INHIBIT_S 0
+#define PRES_DAT_INHIBIT_M BITFIELD_MASK(1) /* Bit 1 May use DAT */
+#define PRES_DAT_INHIBIT_S 1
+#define PRES_DAT_BUSY_M BITFIELD_MASK(1) /* Bit 2 DAT is busy */
+#define PRES_DAT_BUSY_S 2
+#define PRES_PRESENT_RSVD_M BITFIELD_MASK(5) /* Bit [3-7] rsvd */
+#define PRES_PRESENT_RSVD_S 3
+#define PRES_WRITE_ACTIVE_M BITFIELD_MASK(1) /* Bit 8 Write is active */
+#define PRES_WRITE_ACTIVE_S 8
+#define PRES_READ_ACTIVE_M BITFIELD_MASK(1) /* Bit 9 Read is active */
+#define PRES_READ_ACTIVE_S 9
+#define PRES_WRITE_DATA_RDY_M BITFIELD_MASK(1) /* Bit 10 Write buf is avail */
+#define PRES_WRITE_DATA_RDY_S 10
+#define PRES_READ_DATA_RDY_M BITFIELD_MASK(1) /* Bit 11 Read buf data avail */
+#define PRES_READ_DATA_RDY_S 11
+#define PRES_CARD_PRESENT_M BITFIELD_MASK(1) /* Bit 16 Card present - debounced */
+#define PRES_CARD_PRESENT_S 16
+#define PRES_CARD_STABLE_M BITFIELD_MASK(1) /* Bit 17 Debugging */
+#define PRES_CARD_STABLE_S 17
+#define PRES_CARD_PRESENT_RAW_M BITFIELD_MASK(1) /* Bit 18 Not debounced */
+#define PRES_CARD_PRESENT_RAW_S 18
+#define PRES_WRITE_ENABLED_M BITFIELD_MASK(1) /* Bit 19 Write protected? */
+#define PRES_WRITE_ENABLED_S 19
+#define PRES_DAT_SIGNAL_M BITFIELD_MASK(4) /* Bit [20-23] Debugging */
+#define PRES_DAT_SIGNAL_S 20
+#define PRES_CMD_SIGNAL_M BITFIELD_MASK(1) /* Bit 24 Debugging */
+#define PRES_CMD_SIGNAL_S 24
+
+/* SD_HostCntrl: Offset 0x028, size = 1 bytes */
+#define HOST_LED_M BITFIELD_MASK(1) /* Bit 0 LED On/Off */
+#define HOST_LED_S 0
+#define HOST_DATA_WIDTH_M BITFIELD_MASK(1) /* Bit 1 4 bit enable */
+#define HOST_DATA_WIDTH_S 1
+#define HOST_HI_SPEED_EN_M BITFIELD_MASK(1) /* Bit 2 High speed vs low speed */
+#define HOST_DMA_SEL_S 3
+#define HOST_DMA_SEL_M BITFIELD_MASK(2) /* Bit 4:3 DMA Select */
+#define HOST_HI_SPEED_EN_S 2
+
+/* Host Control2: */
+#define HOSTCtrl2_PRESVAL_EN_M BITFIELD_MASK(1) /* 1 bit */
+#define HOSTCtrl2_PRESVAL_EN_S 15 /* bit# */
+
+#define HOSTCtrl2_ASYINT_EN_M BITFIELD_MASK(1) /* 1 bit */
+#define HOSTCtrl2_ASYINT_EN_S 14 /* bit# */
+
+#define HOSTCtrl2_SAMPCLK_SEL_M BITFIELD_MASK(1) /* 1 bit */
+#define HOSTCtrl2_SAMPCLK_SEL_S 7 /* bit# */
+
+#define HOSTCtrl2_EXEC_TUNING_M BITFIELD_MASK(1) /* 1 bit */
+#define HOSTCtrl2_EXEC_TUNING_S 6 /* bit# */
+
+#define HOSTCtrl2_DRIVSTRENGTH_SEL_M BITFIELD_MASK(2) /* 2 bit */
+#define HOSTCtrl2_DRIVSTRENGTH_SEL_S 4 /* bit# */
+
+#define HOSTCtrl2_1_8SIG_EN_M BITFIELD_MASK(1) /* 1 bit */
+#define HOSTCtrl2_1_8SIG_EN_S 3 /* bit# */
+
+#define HOSTCtrl2_UHSMODE_SEL_M BITFIELD_MASK(3) /* 3 bit */
+#define HOSTCtrl2_UHSMODE_SEL_S 0 /* bit# */
+
+#define HOST_CONTR_VER_2 (1)
+#define HOST_CONTR_VER_3 (2)
+
+/* misc defines */
+#define SD1_MODE 0x1 /* SD Host Cntrlr Spec */
+#define SD4_MODE 0x2 /* SD Host Cntrlr Spec */
+
+/* SD_PwrCntrl: Offset 0x029, size = 1 bytes */
+#define PWR_BUS_EN_M BITFIELD_MASK(1) /* Bit 0 Power the bus */
+#define PWR_BUS_EN_S 0
+#define PWR_VOLTS_M BITFIELD_MASK(3) /* Bit [1-3] Voltage Select */
+#define PWR_VOLTS_S 1
+
+/* SD_SoftwareReset: Offset 0x02F, size = 1 byte */
+#define SW_RESET_ALL_M BITFIELD_MASK(1) /* Bit 0 Reset All */
+#define SW_RESET_ALL_S 0
+#define SW_RESET_CMD_M BITFIELD_MASK(1) /* Bit 1 CMD Line Reset */
+#define SW_RESET_CMD_S 1
+#define SW_RESET_DAT_M BITFIELD_MASK(1) /* Bit 2 DAT Line Reset */
+#define SW_RESET_DAT_S 2
+
+/* SD_IntrStatus: Offset 0x030, size = 2 bytes */
+/* Defs also serve SD_IntrStatusEnable and SD_IntrSignalEnable */
+#define INTSTAT_CMD_COMPLETE_M BITFIELD_MASK(1) /* Bit 0 */
+#define INTSTAT_CMD_COMPLETE_S 0
+#define INTSTAT_XFER_COMPLETE_M BITFIELD_MASK(1)
+#define INTSTAT_XFER_COMPLETE_S 1
+#define INTSTAT_BLOCK_GAP_EVENT_M BITFIELD_MASK(1)
+#define INTSTAT_BLOCK_GAP_EVENT_S 2
+#define INTSTAT_DMA_INT_M BITFIELD_MASK(1)
+#define INTSTAT_DMA_INT_S 3
+#define INTSTAT_BUF_WRITE_READY_M BITFIELD_MASK(1)
+#define INTSTAT_BUF_WRITE_READY_S 4
+#define INTSTAT_BUF_READ_READY_M BITFIELD_MASK(1)
+#define INTSTAT_BUF_READ_READY_S 5
+#define INTSTAT_CARD_INSERTION_M BITFIELD_MASK(1)
+#define INTSTAT_CARD_INSERTION_S 6
+#define INTSTAT_CARD_REMOVAL_M BITFIELD_MASK(1)
+#define INTSTAT_CARD_REMOVAL_S 7
+#define INTSTAT_CARD_INT_M BITFIELD_MASK(1)
+#define INTSTAT_CARD_INT_S 8
+#define INTSTAT_RETUNING_INT_M BITFIELD_MASK(1) /* Bit 12 */
+#define INTSTAT_RETUNING_INT_S 12
+#define INTSTAT_ERROR_INT_M BITFIELD_MASK(1) /* Bit 15 */
+#define INTSTAT_ERROR_INT_S 15
+
+/* SD_ErrorIntrStatus: Offset 0x032, size = 2 bytes */
+/* Defs also serve SD_ErrorIntrStatusEnable and SD_ErrorIntrSignalEnable */
+#define ERRINT_CMD_TIMEOUT_M BITFIELD_MASK(1)
+#define ERRINT_CMD_TIMEOUT_S 0
+#define ERRINT_CMD_CRC_M BITFIELD_MASK(1)
+#define ERRINT_CMD_CRC_S 1
+#define ERRINT_CMD_ENDBIT_M BITFIELD_MASK(1)
+#define ERRINT_CMD_ENDBIT_S 2
+#define ERRINT_CMD_INDEX_M BITFIELD_MASK(1)
+#define ERRINT_CMD_INDEX_S 3
+#define ERRINT_DATA_TIMEOUT_M BITFIELD_MASK(1)
+#define ERRINT_DATA_TIMEOUT_S 4
+#define ERRINT_DATA_CRC_M BITFIELD_MASK(1)
+#define ERRINT_DATA_CRC_S 5
+#define ERRINT_DATA_ENDBIT_M BITFIELD_MASK(1)
+#define ERRINT_DATA_ENDBIT_S 6
+#define ERRINT_CURRENT_LIMIT_M BITFIELD_MASK(1)
+#define ERRINT_CURRENT_LIMIT_S 7
+#define ERRINT_AUTO_CMD12_M BITFIELD_MASK(1)
+#define ERRINT_AUTO_CMD12_S 8
+#define ERRINT_VENDOR_M BITFIELD_MASK(4)
+#define ERRINT_VENDOR_S 12
+#define ERRINT_ADMA_M BITFIELD_MASK(1)
+#define ERRINT_ADMA_S 9
+
+/* Also provide definitions in "normal" form to allow combined masks */
+#define ERRINT_CMD_TIMEOUT_BIT 0x0001
+#define ERRINT_CMD_CRC_BIT 0x0002
+#define ERRINT_CMD_ENDBIT_BIT 0x0004
+#define ERRINT_CMD_INDEX_BIT 0x0008
+#define ERRINT_DATA_TIMEOUT_BIT 0x0010
+#define ERRINT_DATA_CRC_BIT 0x0020
+#define ERRINT_DATA_ENDBIT_BIT 0x0040
+#define ERRINT_CURRENT_LIMIT_BIT 0x0080
+#define ERRINT_AUTO_CMD12_BIT 0x0100
+#define ERRINT_ADMA_BIT 0x0200
+
+/* Masks to select CMD vs. DATA errors */
+#define ERRINT_CMD_ERRS (ERRINT_CMD_TIMEOUT_BIT | ERRINT_CMD_CRC_BIT |\
+ ERRINT_CMD_ENDBIT_BIT | ERRINT_CMD_INDEX_BIT)
+#define ERRINT_DATA_ERRS (ERRINT_DATA_TIMEOUT_BIT | ERRINT_DATA_CRC_BIT |\
+ ERRINT_DATA_ENDBIT_BIT | ERRINT_ADMA_BIT)
+#define ERRINT_TRANSFER_ERRS (ERRINT_CMD_ERRS | ERRINT_DATA_ERRS)
+
+/* SD_WakeupCntr_BlockGapCntrl : Offset 0x02A , size = bytes */
+/* SD_ClockCntrl : Offset 0x02C , size = bytes */
+/* SD_SoftwareReset_TimeoutCntrl : Offset 0x02E , size = bytes */
+/* SD_IntrStatus : Offset 0x030 , size = bytes */
+/* SD_ErrorIntrStatus : Offset 0x032 , size = bytes */
+/* SD_IntrStatusEnable : Offset 0x034 , size = bytes */
+/* SD_ErrorIntrStatusEnable : Offset 0x036 , size = bytes */
+/* SD_IntrSignalEnable : Offset 0x038 , size = bytes */
+/* SD_ErrorIntrSignalEnable : Offset 0x03A , size = bytes */
+/* SD_CMD12ErrorStatus : Offset 0x03C , size = bytes */
+/* SD_Capabilities : Offset 0x040 , size = bytes */
+/* SD_MaxCurCap : Offset 0x048 , size = bytes */
+/* SD_MaxCurCap_Reserved: Offset 0x04C , size = bytes */
+/* SD_SlotInterruptStatus: Offset 0x0FC , size = bytes */
+/* SD_HostControllerVersion : Offset 0x0FE , size = bytes */
+
+/* SDIO Host Control Register DMA Mode Definitions */
+#define SDIOH_SDMA_MODE 0
+#define SDIOH_ADMA1_MODE 1
+#define SDIOH_ADMA2_MODE 2
+#define SDIOH_ADMA2_64_MODE 3
+
+#define ADMA2_ATTRIBUTE_VALID (1 << 0) /* ADMA Descriptor line valid */
+#define ADMA2_ATTRIBUTE_END (1 << 1) /* End of Descriptor */
+#define ADMA2_ATTRIBUTE_INT (1 << 2) /* Interrupt when line is done */
+#define ADMA2_ATTRIBUTE_ACT_NOP (0 << 4) /* Skip current line, go to next. */
+#define ADMA2_ATTRIBUTE_ACT_RSV (1 << 4) /* Same as NOP */
+#define ADMA1_ATTRIBUTE_ACT_SET (1 << 4) /* ADMA1 Only - set transfer length */
+#define ADMA2_ATTRIBUTE_ACT_TRAN (2 << 4) /* Transfer Data of one descriptor line. */
+#define ADMA2_ATTRIBUTE_ACT_LINK (3 << 4) /* Link Descriptor */
+
+/* ADMA2 Descriptor Table Entry for 32-bit Address */
+typedef struct adma2_dscr_32b {
+ uint32 len_attr;
+ uint32 phys_addr;
+} adma2_dscr_32b_t;
+
+/* ADMA1 Descriptor Table Entry */
+typedef struct adma1_dscr {
+ uint32 phys_addr_attr;
+} adma1_dscr_t;
+
+#endif /* _SDIOH_H */
diff --git a/drivers/net/wireless/ap6210/include/sdiovar.h b/drivers/net/wireless/ap6210/include/sdiovar.h
new file mode 100644
index 0000000..83f82de
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/sdiovar.h
@@ -0,0 +1,58 @@
+/*
+ * Structure used by apps whose drivers access SDIO drivers.
+ * Pulled out separately so dhdu and wlu can both use it.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sdiovar.h 241182 2011-02-17 21:50:03Z $
+ */
+
+#ifndef _sdiovar_h_
+#define _sdiovar_h_
+
+#include <typedefs.h>
+
+/* require default structure packing */
+#define BWL_DEFAULT_PACKING
+#include <packed_section_start.h>
+
+typedef struct sdreg {
+ int func;
+ int offset;
+ int value;
+} sdreg_t;
+
+/* Common msglevel constants */
+#define SDH_ERROR_VAL 0x0001 /* Error */
+#define SDH_TRACE_VAL 0x0002 /* Trace */
+#define SDH_INFO_VAL 0x0004 /* Info */
+#define SDH_DEBUG_VAL 0x0008 /* Debug */
+#define SDH_DATA_VAL 0x0010 /* Data */
+#define SDH_CTRL_VAL 0x0020 /* Control Regs */
+#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */
+#define SDH_DMA_VAL 0x0080 /* DMA */
+
+#define NUM_PREV_TRANSACTIONS 16
+
+
+#include <packed_section_end.h>
+
+#endif /* _sdiovar_h_ */
diff --git a/drivers/net/wireless/ap6210/include/siutils.h b/drivers/net/wireless/ap6210/include/siutils.h
new file mode 100644
index 0000000..acc72ee
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/siutils.h
@@ -0,0 +1,347 @@
+/*
+ * Misc utility routines for accessing the SOC Interconnects
+ * of Broadcom HNBU chips.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: siutils.h 347614 2012-07-27 10:24:51Z $
+ */
+
+#ifndef _siutils_h_
+#define _siutils_h_
+
+/*
+ * Data structure to export all chip specific common variables
+ * public (read-only) portion of siutils handle returned by si_attach()/si_kattach()
+ */
+struct si_pub {
+ uint socitype; /* SOCI_SB, SOCI_AI */
+
+ uint bustype; /* SI_BUS, PCI_BUS */
+ uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
+ uint buscorerev; /* buscore rev */
+ uint buscoreidx; /* buscore index */
+ int ccrev; /* chip common core rev */
+ uint32 cccaps; /* chip common capabilities */
+ uint32 cccaps_ext; /* chip common capabilities extension */
+ int pmurev; /* pmu core rev */
+ uint32 pmucaps; /* pmu capabilities */
+ uint boardtype; /* board type */
+ uint boardrev; /* board rev */
+ uint boardvendor; /* board vendor */
+ uint boardflags; /* board flags */
+ uint boardflags2; /* board flags2 */
+ uint chip; /* chip number */
+ uint chiprev; /* chip revision */
+ uint chippkg; /* chip package option */
+ uint32 chipst; /* chip status */
+ bool issim; /* chip is in simulation or emulation */
+ uint socirev; /* SOC interconnect rev */
+ bool pci_pr32414;
+
+};
+
+/* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver
+ * for monolithic driver, it is readonly to prevent accident change
+ */
+typedef const struct si_pub si_t;
+
+
+/*
+ * Many of the routines below take an 'sih' handle as their first arg.
+ * Allocate this by calling si_attach(). Free it by calling si_detach().
+ * At any one time, the sih is logically focused on one particular si core
+ * (the "current core").
+ * Use si_setcore() or si_setcoreidx() to change the association to another core.
+ */
+#define SI_OSH NULL /* Use for si_kattach when no osh is available */
+
+#define BADIDX (SI_MAXCORES + 1)
+
+/* clkctl xtal what flags */
+#define XTAL 0x1 /* primary crystal oscillator (2050) */
+#define PLL 0x2 /* main chip pll */
+
+/* clkctl clk mode */
+#define CLK_FAST 0 /* force fast (pll) clock */
+#define CLK_DYNAMIC 2 /* enable dynamic clock control */
+
+/* GPIO usage priorities */
+#define GPIO_DRV_PRIORITY 0 /* Driver */
+#define GPIO_APP_PRIORITY 1 /* Application */
+#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */
+
+/* GPIO pull up/down */
+#define GPIO_PULLUP 0
+#define GPIO_PULLDN 1
+
+/* GPIO event regtype */
+#define GPIO_REGEVT 0 /* GPIO register event */
+#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
+#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
+
+/* device path */
+#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
+
+/* SI routine enumeration: to be used by update function with multiple hooks */
+#define SI_DOATTACH 1
+#define SI_PCIDOWN 2
+#define SI_PCIUP 3
+
+#define ISSIM_ENAB(sih) 0
+
+/* PMU clock/power control */
+#if defined(BCMPMUCTL)
+#define PMUCTL_ENAB(sih) (BCMPMUCTL)
+#else
+#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU)
+#endif
+
+/* chipcommon clock/power control (exclusive with PMU's) */
+#if defined(BCMPMUCTL) && BCMPMUCTL
+#define CCCTL_ENAB(sih) (0)
+#define CCPLL_ENAB(sih) (0)
+#else
+#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL)
+#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK)
+#endif
+
+typedef void (*gpio_handler_t)(uint32 stat, void *arg);
+/* External BT Coex enable mask */
+#define CC_BTCOEX_EN_MASK 0x01
+/* External PA enable mask */
+#define GPIO_CTRL_EPA_EN_MASK 0x40
+/* WL/BT control enable mask */
+#define GPIO_CTRL_5_6_EN_MASK 0x60
+#define GPIO_CTRL_7_6_EN_MASK 0xC0
+#define GPIO_OUT_7_EN_MASK 0x80
+
+
+/* CR4 specific defines used by the host driver */
+#define SI_CR4_CAP (0x04)
+#define SI_CR4_BANKIDX (0x40)
+#define SI_CR4_BANKINFO (0x44)
+
+#define ARMCR4_TCBBNB_MASK 0xf0
+#define ARMCR4_TCBBNB_SHIFT 4
+#define ARMCR4_TCBANB_MASK 0xf
+#define ARMCR4_TCBANB_SHIFT 0
+
+#define SICF_CPUHALT (0x0020)
+#define ARMCR4_BSZ_MASK 0x3f
+#define ARMCR4_BSZ_MULT 8192
+
+
+/* === exported functions === */
+extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype,
+ void *sdh, char **vars, uint *varsz);
+extern si_t *si_kattach(osl_t *osh);
+extern void si_detach(si_t *sih);
+extern bool si_pci_war16165(si_t *sih);
+
+extern uint si_corelist(si_t *sih, uint coreid[]);
+extern uint si_coreid(si_t *sih);
+extern uint si_flag(si_t *sih);
+extern uint si_intflag(si_t *sih);
+extern uint si_coreidx(si_t *sih);
+extern uint si_coreunit(si_t *sih);
+extern uint si_corevendor(si_t *sih);
+extern uint si_corerev(si_t *sih);
+extern void *si_osh(si_t *sih);
+extern void si_setosh(si_t *sih, osl_t *osh);
+extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val);
+extern void *si_coreregs(si_t *sih);
+extern uint si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val);
+extern uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val);
+extern void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val);
+extern uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val);
+extern bool si_iscoreup(si_t *sih);
+extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit);
+extern void *si_setcoreidx(si_t *sih, uint coreidx);
+extern void *si_setcore(si_t *sih, uint coreid, uint coreunit);
+extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val);
+extern void si_restore_core(si_t *sih, uint coreid, uint intr_val);
+extern int si_numaddrspaces(si_t *sih);
+extern uint32 si_addrspace(si_t *sih, uint asidx);
+extern uint32 si_addrspacesize(si_t *sih, uint asidx);
+extern void si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size);
+extern int si_corebist(si_t *sih);
+extern void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits);
+extern void si_core_disable(si_t *sih, uint32 bits);
+extern uint32 si_clock_rate(uint32 pll_type, uint32 n, uint32 m);
+extern bool si_read_pmu_autopll(si_t *sih);
+extern uint32 si_clock(si_t *sih);
+extern uint32 si_alp_clock(si_t *sih);
+extern uint32 si_ilp_clock(si_t *sih);
+extern void si_pci_setup(si_t *sih, uint coremask);
+extern void si_pcmcia_init(si_t *sih);
+extern void si_setint(si_t *sih, int siflag);
+extern bool si_backplane64(si_t *sih);
+extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
+ void *intrsenabled_fn, void *intr_arg);
+extern void si_deregister_intr_callback(si_t *sih);
+extern void si_clkctl_init(si_t *sih);
+extern uint16 si_clkctl_fast_pwrup_delay(si_t *sih);
+extern bool si_clkctl_cc(si_t *sih, uint mode);
+extern int si_clkctl_xtal(si_t *sih, uint what, bool on);
+extern uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 val);
+extern void si_btcgpiowar(si_t *sih);
+extern bool si_deviceremoved(si_t *sih);
+extern uint32 si_socram_size(si_t *sih);
+extern uint32 si_socdevram_size(si_t *sih);
+extern uint32 si_socram_srmem_size(si_t *sih);
+extern void si_socdevram(si_t *sih, bool set, uint8 *ennable, uint8 *protect, uint8 *remap);
+extern bool si_socdevram_pkg(si_t *sih);
+extern bool si_socdevram_remap_isenb(si_t *sih);
+extern uint32 si_socdevram_remap_size(si_t *sih);
+
+extern void si_watchdog(si_t *sih, uint ticks);
+extern void si_watchdog_ms(si_t *sih, uint32 ms);
+extern uint32 si_watchdog_msticks(void);
+extern void *si_gpiosetcore(si_t *sih);
+extern uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority);
+extern uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority);
+extern uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority);
+extern uint32 si_gpioin(si_t *sih);
+extern uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority);
+extern uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority);
+extern uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val);
+extern uint32 si_gpioreserve(si_t *sih, uint32 gpio_num, uint8 priority);
+extern uint32 si_gpiorelease(si_t *sih, uint32 gpio_num, uint8 priority);
+extern uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val);
+extern uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val);
+extern uint32 si_gpio_int_enable(si_t *sih, bool enable);
+
+/* GPIO event handlers */
+extern void *si_gpio_handler_register(si_t *sih, uint32 e, bool lev, gpio_handler_t cb, void *arg);
+extern void si_gpio_handler_unregister(si_t *sih, void* gpioh);
+extern void si_gpio_handler_process(si_t *sih);
+
+/* Wake-on-wireless-LAN (WOWL) */
+extern bool si_pci_pmecap(si_t *sih);
+struct osl_info;
+extern bool si_pci_fastpmecap(struct osl_info *osh);
+extern bool si_pci_pmestat(si_t *sih);
+extern void si_pci_pmeclr(si_t *sih);
+extern void si_pci_pmeen(si_t *sih);
+extern void si_pci_pmestatclr(si_t *sih);
+extern uint si_pcie_readreg(void *sih, uint addrtype, uint offset);
+
+extern void si_sdio_init(si_t *sih);
+
+extern uint16 si_d11_devid(si_t *sih);
+extern int si_corepciid(si_t *sih, uint func, uint16 *pcivendor, uint16 *pcidevice,
+ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, uint8 *pciheader);
+
+#define si_eci(sih) 0
+static INLINE void * si_eci_init(si_t *sih) {return NULL;}
+#define si_eci_notify_bt(sih, type, val) (0)
+#define si_seci(sih) 0
+#define si_seci_upd(sih, a) do {} while (0)
+static INLINE void * si_seci_init(si_t *sih, uint8 use_seci) {return NULL;}
+#define si_seci_down(sih) do {} while (0)
+
+/* OTP status */
+extern bool si_is_otp_disabled(si_t *sih);
+extern bool si_is_otp_powered(si_t *sih);
+extern void si_otp_power(si_t *sih, bool on);
+
+/* SPROM availability */
+extern bool si_is_sprom_available(si_t *sih);
+extern bool si_is_sprom_enabled(si_t *sih);
+extern void si_sprom_enable(si_t *sih, bool enable);
+
+/* OTP/SROM CIS stuff */
+extern int si_cis_source(si_t *sih);
+#define CIS_DEFAULT 0
+#define CIS_SROM 1
+#define CIS_OTP 2
+
+/* Fab-id information */
+#define DEFAULT_FAB 0x0 /* Original/first fab used for this chip */
+#define CSM_FAB7 0x1 /* CSM Fab7 chip */
+#define TSMC_FAB12 0x2 /* TSMC Fab12/Fab14 chip */
+#define SMIC_FAB4 0x3 /* SMIC Fab4 chip */
+extern int si_otp_fabid(si_t *sih, uint16 *fabid, bool rw);
+extern uint16 si_fabid(si_t *sih);
+
+/*
+ * Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
+ * The returned path is NULL terminated and has trailing '/'.
+ * Return 0 on success, nonzero otherwise.
+ */
+extern int si_devpath(si_t *sih, char *path, int size);
+/* Read variable with prepending the devpath to the name */
+extern char *si_getdevpathvar(si_t *sih, const char *name);
+extern int si_getdevpathintvar(si_t *sih, const char *name);
+extern char *si_coded_devpathvar(si_t *sih, char *varname, int var_len, const char *name);
+
+
+extern uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val);
+extern uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val);
+extern void si_war42780_clkreq(si_t *sih, bool clkreq);
+extern void si_pci_down(si_t *sih);
+extern void si_pci_up(si_t *sih);
+extern void si_pci_sleep(si_t *sih);
+extern void si_pcie_war_ovr_update(si_t *sih, uint8 aspm);
+extern void si_pcie_power_save_enable(si_t *sih, bool enable);
+extern void si_pcie_extendL1timer(si_t *sih, bool extend);
+extern int si_pci_fixcfg(si_t *sih);
+extern void si_chippkg_set(si_t *sih, uint);
+
+extern void si_chipcontrl_btshd0_4331(si_t *sih, bool on);
+extern void si_chipcontrl_restore(si_t *sih, uint32 val);
+extern uint32 si_chipcontrl_read(si_t *sih);
+extern void si_chipcontrl_epa4331(si_t *sih, bool on);
+extern void si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl);
+extern void si_chipcontrl_srom4360(si_t *sih, bool on);
+/* Enable BT-COEX & Ex-PA for 4313 */
+extern void si_epa_4313war(si_t *sih);
+extern void si_btc_enable_chipcontrol(si_t *sih);
+/* BT/WL selection for 4313 bt combo >= P250 boards */
+extern void si_btcombo_p250_4313_war(si_t *sih);
+extern void si_btcombo_43228_war(si_t *sih);
+extern void si_clk_pmu_htavail_set(si_t *sih, bool set_clear);
+extern uint si_pll_reset(si_t *sih);
+/* === debug routines === */
+
+extern bool si_taclear(si_t *sih, bool details);
+
+
+
+extern uint32 si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val, uint type);
+extern uint32 si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset, uint32 mask, uint32 val);
+extern void si_pcie_set_request_size(si_t *sih, uint16 size);
+extern uint16 si_pcie_get_request_size(si_t *sih);
+extern uint16 si_pcie_get_ssid(si_t *sih);
+extern uint32 si_pcie_get_bar0(si_t *sih);
+extern int si_pcie_configspace_cache(si_t *sih);
+extern int si_pcie_configspace_restore(si_t *sih);
+extern int si_pcie_configspace_get(si_t *sih, uint8 *buf, uint size);
+
+char *si_getnvramflvar(si_t *sih, const char *name);
+
+
+extern uint32 si_tcm_size(si_t *sih);
+
+extern int si_set_sromctl(si_t *sih, uint32 value);
+extern uint32 si_get_sromctl(si_t *sih);
+#endif /* _siutils_h_ */
diff --git a/drivers/net/wireless/ap6210/include/trxhdr.h b/drivers/net/wireless/ap6210/include/trxhdr.h
new file mode 100644
index 0000000..bf92a56
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/trxhdr.h
@@ -0,0 +1,53 @@
+/*
+ * TRX image file header format.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: trxhdr.h 260898 2011-05-20 23:11:12Z $
+ */
+
+#ifndef _TRX_HDR_H
+#define _TRX_HDR_H
+
+#include <typedefs.h>
+
+#define TRX_MAGIC 0x30524448 /* "HDR0" */
+#define TRX_VERSION 1 /* Version 1 */
+#define TRX_MAX_LEN 0x3B0000 /* Max length */
+#define TRX_NO_HEADER 1 /* Do not write TRX header */
+#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
+#define TRX_EMBED_UCODE 0x8 /* Trx contains embedded ucode image */
+#define TRX_ROMSIM_IMAGE 0x10 /* Trx contains ROM simulation image */
+#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed rtecdc.bin image */
+#define TRX_MAX_OFFSET 3 /* Max number of individual files */
+
+struct trx_header {
+ uint32 magic; /* "HDR0" */
+ uint32 len; /* Length of file including header */
+ uint32 crc32; /* 32-bit CRC from flag_version to end of file */
+ uint32 flag_version; /* 0:15 flags, 16:31 version */
+ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
+};
+
+/* Compatibility */
+typedef struct trx_header TRXHDR, *PTRXHDR;
+
+#endif /* _TRX_HDR_H */
diff --git a/drivers/net/wireless/ap6210/include/typedefs.h b/drivers/net/wireless/ap6210/include/typedefs.h
new file mode 100644
index 0000000..fe1d162
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/typedefs.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ * $Id: typedefs.h 286783 2011-09-29 06:18:57Z $
+ */
+
+#ifndef _TYPEDEFS_H_
+#define _TYPEDEFS_H_
+
+#ifdef SITE_TYPEDEFS
+
+/*
+ * Define SITE_TYPEDEFS in the compile to include a site-specific
+ * typedef file "site_typedefs.h".
+ *
+ * If SITE_TYPEDEFS is not defined, then the code section below makes
+ * inferences about the compile environment based on defined symbols and
+ * possibly compiler pragmas.
+ *
+ * Following these two sections is the Default Typedefs section.
+ * This section is only processed if USE_TYPEDEF_DEFAULTS is
+ * defined. This section has a default set of typedefs and a few
+ * preprocessor symbols (TRUE, FALSE, NULL, ...).
+ */
+
+#include "site_typedefs.h"
+
+#else
+
+/*
+ * Infer the compile environment based on preprocessor symbols and pragmas.
+ * Override type definitions as needed, and include configuration-dependent
+ * header files to define types.
+ */
+
+#ifdef __cplusplus
+
+#define TYPEDEF_BOOL
+#ifndef FALSE
+#define FALSE false
+#endif
+#ifndef TRUE
+#define TRUE true
+#endif
+
+#else /* ! __cplusplus */
+
+
+#endif /* ! __cplusplus */
+
+#if defined(__x86_64__)
+#define TYPEDEF_UINTPTR
+typedef unsigned long long int uintptr;
+#endif
+
+
+
+
+
+#if defined(_NEED_SIZE_T_)
+typedef long unsigned int size_t;
+#endif
+
+
+
+
+#if defined(__sparc__)
+#define TYPEDEF_ULONG
+#endif
+
+
+/*
+ * If this is either a Linux hybrid build or the per-port code of a hybrid build
+ * then use the Linux header files to get some of the typedefs. Otherwise, define
+ * them entirely in this file. We can't always define the types because we get
+ * a duplicate typedef error; there is no way to "undefine" a typedef.
+ * We know when it's per-port code because each file defines LINUX_PORT at the top.
+ */
+#if !defined(LINUX_HYBRID) || defined(LINUX_PORT)
+#define TYPEDEF_UINT
+#ifndef TARGETENV_android
+#define TYPEDEF_USHORT
+#define TYPEDEF_ULONG
+#endif /* TARGETENV_android */
+#ifdef __KERNEL__
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
+#define TYPEDEF_BOOL
+#endif /* >= 2.6.19 */
+/* special detection for 2.6.18-128.7.1.0.1.el5 */
+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18))
+#include <linux/compiler.h>
+#ifdef noinline_for_stack
+#define TYPEDEF_BOOL
+#endif
+#endif /* == 2.6.18 */
+#endif /* __KERNEL__ */
+#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */
+
+
+
+
+/* Do not support the (u)int64 types with strict ansi for GNU C */
+#if defined(__GNUC__) && defined(__STRICT_ANSI__)
+#define TYPEDEF_INT64
+#define TYPEDEF_UINT64
+#endif
+
+/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode
+ * for signed or unsigned
+ */
+#if defined(__ICL)
+
+#define TYPEDEF_INT64
+
+#if defined(__STDC__)
+#define TYPEDEF_UINT64
+#endif
+
+#endif /* __ICL */
+
+#if !defined(__DJGPP__)
+
+/* pick up ushort & uint from standard types.h */
+#if defined(__KERNEL__)
+
+/* See note above */
+#if !defined(LINUX_HYBRID) || defined(LINUX_PORT)
+#include <linux/types.h> /* sys/types.h and linux/types.h are oil and water */
+#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */
+
+#else
+
+
+#include <sys/types.h>
+
+#endif /* linux && __KERNEL__ */
+
+#endif
+
+
+
+/* use the default typedefs in the next section of this file */
+#define USE_TYPEDEF_DEFAULTS
+
+#endif /* SITE_TYPEDEFS */
+
+
+/*
+ * Default Typedefs
+ */
+
+#ifdef USE_TYPEDEF_DEFAULTS
+#undef USE_TYPEDEF_DEFAULTS
+
+#ifndef TYPEDEF_BOOL
+typedef /* @abstract@ */ unsigned char bool;
+#endif
+
+/* define uchar, ushort, uint, ulong */
+
+#ifndef TYPEDEF_UCHAR
+typedef unsigned char uchar;
+#endif
+
+#ifndef TYPEDEF_USHORT
+typedef unsigned short ushort;
+#endif
+
+#ifndef TYPEDEF_UINT
+typedef unsigned int uint;
+#endif
+
+#ifndef TYPEDEF_ULONG
+typedef unsigned long ulong;
+#endif
+
+/* define [u]int8/16/32/64, uintptr */
+
+#ifndef TYPEDEF_UINT8
+typedef unsigned char uint8;
+#endif
+
+#ifndef TYPEDEF_UINT16
+typedef unsigned short uint16;
+#endif
+
+#ifndef TYPEDEF_UINT32
+typedef unsigned int uint32;
+#endif
+
+#ifndef TYPEDEF_UINT64
+typedef unsigned long long uint64;
+#endif
+
+#ifndef TYPEDEF_UINTPTR
+typedef unsigned int uintptr;
+#endif
+
+#ifndef TYPEDEF_INT8
+typedef signed char int8;
+#endif
+
+#ifndef TYPEDEF_INT16
+typedef signed short int16;
+#endif
+
+#ifndef TYPEDEF_INT32
+typedef signed int int32;
+#endif
+
+#ifndef TYPEDEF_INT64
+typedef signed long long int64;
+#endif
+
+/* define float32/64, float_t */
+
+#ifndef TYPEDEF_FLOAT32
+typedef float float32;
+#endif
+
+#ifndef TYPEDEF_FLOAT64
+typedef double float64;
+#endif
+
+/*
+ * abstracted floating point type allows for compile time selection of
+ * single or double precision arithmetic. Compiling with -DFLOAT32
+ * selects single precision; the default is double precision.
+ */
+
+#ifndef TYPEDEF_FLOAT_T
+
+#if defined(FLOAT32)
+typedef float32 float_t;
+#else /* default to double precision floating point */
+typedef float64 float_t;
+#endif
+
+#endif /* TYPEDEF_FLOAT_T */
+
+/* define macro values */
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1 /* TRUE */
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef OFF
+#define OFF 0
+#endif
+
+#ifndef ON
+#define ON 1 /* ON = 1 */
+#endif
+
+#define AUTO (-1) /* Auto = -1 */
+
+/* define PTRSZ, INLINE */
+
+#ifndef PTRSZ
+#define PTRSZ sizeof(char*)
+#endif
+
+
+/* Detect compiler type. */
+#if defined(__GNUC__) || defined(__lint)
+ #define BWL_COMPILER_GNU
+#elif defined(__CC_ARM) && __CC_ARM
+ #define BWL_COMPILER_ARMCC
+#else
+ #error "Unknown compiler!"
+#endif
+
+
+#ifndef INLINE
+ #if defined(BWL_COMPILER_MICROSOFT)
+ #define INLINE __inline
+ #elif defined(BWL_COMPILER_GNU)
+ #define INLINE __inline__
+ #elif defined(BWL_COMPILER_ARMCC)
+ #define INLINE __inline
+ #else
+ #define INLINE
+ #endif
+#endif /* INLINE */
+
+#undef TYPEDEF_BOOL
+#undef TYPEDEF_UCHAR
+#undef TYPEDEF_USHORT
+#undef TYPEDEF_UINT
+#undef TYPEDEF_ULONG
+#undef TYPEDEF_UINT8
+#undef TYPEDEF_UINT16
+#undef TYPEDEF_UINT32
+#undef TYPEDEF_UINT64
+#undef TYPEDEF_UINTPTR
+#undef TYPEDEF_INT8
+#undef TYPEDEF_INT16
+#undef TYPEDEF_INT32
+#undef TYPEDEF_INT64
+#undef TYPEDEF_FLOAT32
+#undef TYPEDEF_FLOAT64
+#undef TYPEDEF_FLOAT_T
+
+#endif /* USE_TYPEDEF_DEFAULTS */
+
+/* Suppress unused parameter warning */
+#define UNUSED_PARAMETER(x) (void)(x)
+
+/* Avoid warning for discarded const or volatile qualifier in special cases (-Wcast-qual) */
+#define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr))
+
+/*
+ * Including the bcmdefs.h here, to make sure everyone including typedefs.h
+ * gets this automatically
+*/
+#include <bcmdefs.h>
+#endif /* _TYPEDEFS_H_ */
diff --git a/drivers/net/wireless/ap6210/include/wlfc_proto.h b/drivers/net/wireless/ap6210/include/wlfc_proto.h
new file mode 100644
index 0000000..98d2fa9
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/wlfc_proto.h
@@ -0,0 +1,217 @@
+/*
+* Copyright (C) 1999-2012, Broadcom Corporation
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2 (the "GPL"),
+* available at http://www.broadcom.com/licenses/GPLv2.php, with the
+* following added to such license:
+*
+* As a special exception, the copyright holders of this software give you
+* permission to link this software with independent modules, and to copy and
+* distribute the resulting executable under terms of your choice, provided that
+* you also meet, for each linked independent module, the terms and conditions of
+* the license of that module. An independent module is a module which is not
+* derived from this software. The special exception does not apply to any
+* modifications of the software.
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a license
+* other than the GPL, without Broadcom's express prior written consent.
+* $Id: wlfc_proto.h 361006 2012-10-05 07:45:51Z $
+*
+*/
+#ifndef __wlfc_proto_definitions_h__
+#define __wlfc_proto_definitions_h__
+
+ /* Use TLV to convey WLFC information.
+ ---------------------------------------------------------------------------
+ | Type | Len | value | Description
+ ---------------------------------------------------------------------------
+ | 1 | 1 | (handle) | MAC OPEN
+ ---------------------------------------------------------------------------
+ | 2 | 1 | (handle) | MAC CLOSE
+ ---------------------------------------------------------------------------
+ | 3 | 2 | (count, handle, prec_bmp)| Set the credit depth for a MAC dstn
+ ---------------------------------------------------------------------------
+ | 4 | 4 | see pkttag comments | TXSTATUS
+ ---------------------------------------------------------------------------
+ | 5 | 4 | see pkttag comments | PKKTTAG [host->firmware]
+ ---------------------------------------------------------------------------
+ | 6 | 8 | (handle, ifid, MAC) | MAC ADD
+ ---------------------------------------------------------------------------
+ | 7 | 8 | (handle, ifid, MAC) | MAC DEL
+ ---------------------------------------------------------------------------
+ | 8 | 1 | (rssi) | RSSI - RSSI value for the packet.
+ ---------------------------------------------------------------------------
+ | 9 | 1 | (interface ID) | Interface OPEN
+ ---------------------------------------------------------------------------
+ | 10 | 1 | (interface ID) | Interface CLOSE
+ ---------------------------------------------------------------------------
+ | 11 | 8 | fifo credit returns map | FIFO credits back to the host
+ | | | |
+ | | | | --------------------------------------
+ | | | | | ac0 | ac1 | ac2 | ac3 | bcmc | atim |
+ | | | | --------------------------------------
+ | | | |
+ ---------------------------------------------------------------------------
+ | 12 | 2 | MAC handle, | Host provides a bitmap of pending
+ | | | AC[0-3] traffic bitmap | unicast traffic for MAC-handle dstn.
+ | | | | [host->firmware]
+ ---------------------------------------------------------------------------
+ | 13 | 3 | (count, handle, prec_bmp)| One time request for packet to a specific
+ | | | | MAC destination.
+ ---------------------------------------------------------------------------
+ | 15 | 1 | interface ID | NIC period start
+ ---------------------------------------------------------------------------
+ | 16 | 1 | interface ID | NIC period end
+ ---------------------------------------------------------------------------
+ | 17 | 3 | (ifid, txs) | Action frame tx status
+ ---------------------------------------------------------------------------
+ | 255 | N/A | N/A | FILLER - This is a special type
+ | | | | that has no length or value.
+ | | | | Typically used for padding.
+ ---------------------------------------------------------------------------
+ */
+
+#define WLFC_CTL_TYPE_MAC_OPEN 1
+#define WLFC_CTL_TYPE_MAC_CLOSE 2
+#define WLFC_CTL_TYPE_MAC_REQUEST_CREDIT 3
+#define WLFC_CTL_TYPE_TXSTATUS 4
+#define WLFC_CTL_TYPE_PKTTAG 5
+
+#define WLFC_CTL_TYPE_MACDESC_ADD 6
+#define WLFC_CTL_TYPE_MACDESC_DEL 7
+#define WLFC_CTL_TYPE_RSSI 8
+
+#define WLFC_CTL_TYPE_INTERFACE_OPEN 9
+#define WLFC_CTL_TYPE_INTERFACE_CLOSE 10
+
+#define WLFC_CTL_TYPE_FIFO_CREDITBACK 11
+
+#define WLFC_CTL_TYPE_PENDING_TRAFFIC_BMP 12
+#define WLFC_CTL_TYPE_MAC_REQUEST_PACKET 13
+#define WLFC_CTL_TYPE_HOST_REORDER_RXPKTS 14
+
+#define WLFC_CTL_TYPE_NIC_PRD_START 15
+#define WLFC_CTL_TYPE_NIC_PRD_END 16
+#define WLFC_CTL_TYPE_AF_TXS 17
+#define WLFC_CTL_TYPE_TRANS_ID 18
+#define WLFC_CTL_TYPE_COMP_TXSTATUS 19
+
+#define WLFC_CTL_TYPE_FILLER 255
+
+#define WLFC_CTL_VALUE_LEN_MACDESC 8 /* handle, interface, MAC */
+
+#define WLFC_CTL_VALUE_LEN_MAC 1 /* MAC-handle */
+#define WLFC_CTL_VALUE_LEN_RSSI 1
+
+#define WLFC_CTL_VALUE_LEN_INTERFACE 1
+#define WLFC_CTL_VALUE_LEN_PENDING_TRAFFIC_BMP 2
+
+#define WLFC_CTL_VALUE_LEN_TXSTATUS 4
+#define WLFC_CTL_VALUE_LEN_PKTTAG 4
+
+/* enough space to host all 4 ACs, bc/mc and atim fifo credit */
+#define WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK 6
+
+#define WLFC_CTL_VALUE_LEN_REQUEST_CREDIT 3 /* credit, MAC-handle, prec_bitmap */
+#define WLFC_CTL_VALUE_LEN_REQUEST_PACKET 3 /* credit, MAC-handle, prec_bitmap */
+
+#define WLFC_CTL_VALUE_LEN_NIC_PRD_START 1
+#define WLFC_CTL_VALUE_LEN_NIC_PRD_END 1
+#define WLFC_CTL_VALUE_LEN_AF_TXS 3
+
+
+#define WLFC_PKTID_GEN_MASK 0x80000000
+#define WLFC_PKTID_GEN_SHIFT 31
+
+#define WLFC_PKTID_GEN(x) (((x) & WLFC_PKTID_GEN_MASK) >> WLFC_PKTID_GEN_SHIFT)
+#define WLFC_PKTID_SETGEN(x, gen) (x) = ((x) & ~WLFC_PKTID_GEN_MASK) | \
+ (((gen) << WLFC_PKTID_GEN_SHIFT) & WLFC_PKTID_GEN_MASK)
+
+#define WLFC_PKTFLAG_PKTFROMHOST 0x01
+#define WLFC_PKTFLAG_PKT_REQUESTED 0x02
+
+#define WL_TXSTATUS_FLAGS_MASK 0xf /* allow 4 bits only */
+#define WL_TXSTATUS_FLAGS_SHIFT 27
+
+#define WL_TXSTATUS_SET_FLAGS(x, flags) ((x) = \
+ ((x) & ~(WL_TXSTATUS_FLAGS_MASK << WL_TXSTATUS_FLAGS_SHIFT)) | \
+ (((flags) & WL_TXSTATUS_FLAGS_MASK) << WL_TXSTATUS_FLAGS_SHIFT))
+#define WL_TXSTATUS_GET_FLAGS(x) (((x) >> WL_TXSTATUS_FLAGS_SHIFT) & \
+ WL_TXSTATUS_FLAGS_MASK)
+
+#define WL_TXSTATUS_FIFO_MASK 0x7 /* allow 3 bits for FIFO ID */
+#define WL_TXSTATUS_FIFO_SHIFT 24
+
+#define WL_TXSTATUS_SET_FIFO(x, flags) ((x) = \
+ ((x) & ~(WL_TXSTATUS_FIFO_MASK << WL_TXSTATUS_FIFO_SHIFT)) | \
+ (((flags) & WL_TXSTATUS_FIFO_MASK) << WL_TXSTATUS_FIFO_SHIFT))
+#define WL_TXSTATUS_GET_FIFO(x) (((x) >> WL_TXSTATUS_FIFO_SHIFT) & WL_TXSTATUS_FIFO_MASK)
+
+#define WL_TXSTATUS_PKTID_MASK 0xffffff /* allow 24 bits */
+#define WL_TXSTATUS_SET_PKTID(x, num) ((x) = \
+ ((x) & ~WL_TXSTATUS_PKTID_MASK) | (num))
+#define WL_TXSTATUS_GET_PKTID(x) ((x) & WL_TXSTATUS_PKTID_MASK)
+
+/* 32 STA should be enough??, 6 bits; Must be power of 2 */
+#define WLFC_MAC_DESC_TABLE_SIZE 32
+#define WLFC_MAX_IFNUM 16
+#define WLFC_MAC_DESC_ID_INVALID 0xff
+
+/* b[7:5] -reuse guard, b[4:0] -value */
+#define WLFC_MAC_DESC_GET_LOOKUP_INDEX(x) ((x) & 0x1f)
+
+#define WLFC_PKTFLAG_SET_PKTREQUESTED(x) (x) |= \
+ (WLFC_PKTFLAG_PKT_REQUESTED << WL_TXSTATUS_FLAGS_SHIFT)
+
+#define WLFC_PKTFLAG_CLR_PKTREQUESTED(x) (x) &= \
+ ~(WLFC_PKTFLAG_PKT_REQUESTED << WL_TXSTATUS_FLAGS_SHIFT)
+
+#define WL_TXSTATUS_GENERATION_MASK 1
+#define WL_TXSTATUS_GENERATION_SHIFT 31
+
+#define WLFC_PKTFLAG_SET_GENERATION(x, gen) ((x) = \
+ ((x) & ~(WL_TXSTATUS_GENERATION_MASK << WL_TXSTATUS_GENERATION_SHIFT)) | \
+ (((gen) & WL_TXSTATUS_GENERATION_MASK) << WL_TXSTATUS_GENERATION_SHIFT))
+
+#define WLFC_PKTFLAG_GENERATION(x) (((x) >> WL_TXSTATUS_GENERATION_SHIFT) & \
+ WL_TXSTATUS_GENERATION_MASK)
+
+#define WLFC_MAX_PENDING_DATALEN 120
+
+/* host is free to discard the packet */
+#define WLFC_CTL_PKTFLAG_DISCARD 0
+/* D11 suppressed a packet */
+#define WLFC_CTL_PKTFLAG_D11SUPPRESS 1
+/* WL firmware suppressed a packet because MAC is
+ already in PSMode (short time window)
+*/
+#define WLFC_CTL_PKTFLAG_WLSUPPRESS 2
+/* Firmware tossed this packet */
+#define WLFC_CTL_PKTFLAG_TOSSED_BYWLC 3
+
+#define WLFC_D11_STATUS_INTERPRET(txs) \
+ (((txs)->status.suppr_ind != 0) ? WLFC_CTL_PKTFLAG_D11SUPPRESS : WLFC_CTL_PKTFLAG_DISCARD)
+
+/* AMPDU host reorder packet flags */
+#define WLHOST_REORDERDATA_MAXFLOWS 256
+#define WLHOST_REORDERDATA_LEN 10
+#define WLHOST_REORDERDATA_TOTLEN (WLHOST_REORDERDATA_LEN + 1 + 1) /* +tag +len */
+
+#define WLHOST_REORDERDATA_FLOWID_OFFSET 0
+#define WLHOST_REORDERDATA_MAXIDX_OFFSET 2
+#define WLHOST_REORDERDATA_FLAGS_OFFSET 4
+#define WLHOST_REORDERDATA_CURIDX_OFFSET 6
+#define WLHOST_REORDERDATA_EXPIDX_OFFSET 8
+
+#define WLHOST_REORDERDATA_DEL_FLOW 0x01
+#define WLHOST_REORDERDATA_FLUSH_ALL 0x02
+#define WLHOST_REORDERDATA_CURIDX_VALID 0x04
+#define WLHOST_REORDERDATA_EXPIDX_VALID 0x08
+#define WLHOST_REORDERDATA_NEW_HOLE 0x10
+/* transaction id data len byte 0: rsvd, byte 1: seqnumber, byte 2-5 will be used for timestampe */
+#define WLFC_CTL_TRANS_ID_LEN 6
+
+#endif /* __wlfc_proto_definitions_h__ */
diff --git a/drivers/net/wireless/ap6210/include/wlioctl.h b/drivers/net/wireless/ap6210/include/wlioctl.h
new file mode 100644
index 0000000..a3e7003
--- /dev/null
+++ b/drivers/net/wireless/ap6210/include/wlioctl.h
@@ -0,0 +1,5079 @@
+/*
+ * Custom OID/ioctl definitions for
+ * Broadcom 802.11abg Networking Device Driver
+ *
+ * Definitions subject to change without notice.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wlioctl.h 366141 2012-11-01 01:55:06Z $
+ */
+
+#ifndef _wlioctl_h_
+#define _wlioctl_h_
+
+#include <typedefs.h>
+#include <proto/ethernet.h>
+#include <proto/bcmeth.h>
+#include <proto/bcmevent.h>
+#include <proto/802.11.h>
+#include <bcmwifi_channels.h>
+#include <bcmwifi_rates.h>
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+#include <bcm_mpool_pub.h>
+#include <bcmcdc.h>
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* LINUX_POSTMOGRIFY_REMOVAL: undefined during compile phase, so its
+ * a no-op for most cases. For hybrid and other open source releases,
+ * its defined during a second pass and mogrified out for distribution.
+ */
+
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+
+#ifndef INTF_NAME_SIZ
+#define INTF_NAME_SIZ 16
+#endif
+
+/* Used to send ioctls over the transport pipe */
+typedef struct remote_ioctl {
+ cdc_ioctl_t msg;
+ uint data_len;
+ char intf_name[INTF_NAME_SIZ];
+} rem_ioctl_t;
+#define REMOTE_SIZE sizeof(rem_ioctl_t)
+
+#define ACTION_FRAME_SIZE 1800
+
+typedef struct wl_action_frame {
+ struct ether_addr da;
+ uint16 len;
+ uint32 packetId;
+ uint8 data[ACTION_FRAME_SIZE];
+} wl_action_frame_t;
+
+#define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame)
+
+typedef struct ssid_info
+{
+ uint8 ssid_len; /* the length of SSID */
+ uint8 ssid[32]; /* SSID string */
+} ssid_info_t;
+
+typedef struct wl_af_params {
+ uint32 channel;
+ int32 dwell_time;
+ struct ether_addr BSSID;
+ wl_action_frame_t action_frame;
+} wl_af_params_t;
+
+#define WL_WIFI_AF_PARAMS_SIZE sizeof(struct wl_af_params)
+
+#define MFP_TEST_FLAG_NORMAL 0
+#define MFP_TEST_FLAG_ANY_KEY 1
+typedef struct wl_sa_query {
+ uint32 flag;
+ uint8 action;
+ uint16 id;
+ struct ether_addr da;
+} wl_sa_query_t;
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* require default structure packing */
+#define BWL_DEFAULT_PACKING
+#include <packed_section_start.h>
+
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+/* Legacy structure to help keep backward compatible wl tool and tray app */
+
+#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */
+
+typedef struct wl_bss_info_107 {
+ uint32 version; /* version field */
+ uint32 length; /* byte length of data in this record,
+ * starting at version and including IEs
+ */
+ struct ether_addr BSSID;
+ uint16 beacon_period; /* units are Kusec */
+ uint16 capability; /* Capability information */
+ uint8 SSID_len;
+ uint8 SSID[32];
+ struct {
+ uint count; /* # rates in this set */
+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
+ } rateset; /* supported rates */
+ uint8 channel; /* Channel no. */
+ uint16 atim_window; /* units are Kusec */
+ uint8 dtim_period; /* DTIM period */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ int8 phy_noise; /* noise (in dBm) */
+ uint32 ie_length; /* byte length of Information Elements */
+ /* variable length Information Elements */
+} wl_bss_info_107_t;
+
+/*
+ * Per-BSS information structure.
+ */
+
+#define LEGACY2_WL_BSS_INFO_VERSION 108 /* old version of wl_bss_info struct */
+
+/* BSS info structure
+ * Applications MUST CHECK ie_offset field and length field to access IEs and
+ * next bss_info structure in a vector (in wl_scan_results_t)
+ */
+typedef struct wl_bss_info_108 {
+ uint32 version; /* version field */
+ uint32 length; /* byte length of data in this record,
+ * starting at version and including IEs
+ */
+ struct ether_addr BSSID;
+ uint16 beacon_period; /* units are Kusec */
+ uint16 capability; /* Capability information */
+ uint8 SSID_len;
+ uint8 SSID[32];
+ struct {
+ uint count; /* # rates in this set */
+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
+ } rateset; /* supported rates */
+ chanspec_t chanspec; /* chanspec for bss */
+ uint16 atim_window; /* units are Kusec */
+ uint8 dtim_period; /* DTIM period */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ int8 phy_noise; /* noise (in dBm) */
+
+ uint8 n_cap; /* BSS is 802.11N Capable */
+ uint32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */
+ uint8 ctl_ch; /* 802.11N BSS control channel number */
+ uint32 reserved32[1]; /* Reserved for expansion of BSS properties */
+ uint8 flags; /* flags */
+ uint8 reserved[3]; /* Reserved for expansion of BSS properties */
+ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
+
+ uint16 ie_offset; /* offset at which IEs start, from beginning */
+ uint32 ie_length; /* byte length of Information Elements */
+ /* Add new fields here */
+ /* variable length Information Elements */
+} wl_bss_info_108_t;
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+#define WL_BSS_INFO_VERSION 109 /* current version of wl_bss_info struct */
+
+/* BSS info structure
+ * Applications MUST CHECK ie_offset field and length field to access IEs and
+ * next bss_info structure in a vector (in wl_scan_results_t)
+ */
+typedef struct wl_bss_info {
+ uint32 version; /* version field */
+ uint32 length; /* byte length of data in this record,
+ * starting at version and including IEs
+ */
+ struct ether_addr BSSID;
+ uint16 beacon_period; /* units are Kusec */
+ uint16 capability; /* Capability information */
+ uint8 SSID_len;
+ uint8 SSID[32];
+ struct {
+ uint count; /* # rates in this set */
+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
+ } rateset; /* supported rates */
+ chanspec_t chanspec; /* chanspec for bss */
+ uint16 atim_window; /* units are Kusec */
+ uint8 dtim_period; /* DTIM period */
+ int16 RSSI; /* receive signal strength (in dBm) */
+ int8 phy_noise; /* noise (in dBm) */
+
+ uint8 n_cap; /* BSS is 802.11N Capable */
+ uint32 nbss_cap; /* 802.11N+AC BSS Capabilities */
+ uint8 ctl_ch; /* 802.11N BSS control channel number */
+ uint8 padding1[3]; /* explicit struct alignment padding */
+ uint16 vht_rxmcsmap; /* VHT rx mcs map */
+ uint16 vht_txmcsmap; /* VHT tx mcs map */
+ uint8 flags; /* flags */
+ uint8 vht_cap; /* BSS is vht capable */
+ uint8 reserved[2]; /* Reserved for expansion of BSS properties */
+ uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
+
+ uint16 ie_offset; /* offset at which IEs start, from beginning */
+ uint32 ie_length; /* byte length of Information Elements */
+ int16 SNR; /* average SNR of during frame reception */
+ /* Add new fields here */
+ /* variable length Information Elements */
+} wl_bss_info_t;
+
+/* bss_info_cap_t flags */
+#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */
+#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */
+#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info was received on channel (vs offchannel) */
+
+/* bssinfo flag for nbss_cap */
+#define VHT_BI_SGI_80MHZ 0x00000100
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+
+typedef struct wl_bsscfg {
+ uint32 wsec;
+ uint32 WPA_auth;
+ uint32 wsec_index;
+ uint32 associated;
+ uint32 BSS;
+ uint32 phytest_on;
+ struct ether_addr prev_BSSID;
+ struct ether_addr BSSID;
+ uint32 targetbss_wpa2_flags;
+ uint32 assoc_type;
+ uint32 assoc_state;
+} wl_bsscfg_t;
+
+typedef struct wl_bss_config {
+ uint32 atim_window;
+ uint32 beacon_period;
+ uint32 chanspec;
+} wl_bss_config_t;
+
+#define DLOAD_HANDLER_VER 1 /* Downloader version */
+#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */
+#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */
+
+#define DL_CRC_NOT_INUSE 0x0001
+
+/* generic download types & flags */
+enum {
+ DL_TYPE_UCODE = 1,
+ DL_TYPE_CLM = 2
+};
+
+/* ucode type values */
+enum {
+ UCODE_FW,
+ INIT_VALS,
+ BS_INIT_VALS
+};
+
+struct wl_dload_data {
+ uint16 flag;
+ uint16 dload_type;
+ uint32 len;
+ uint32 crc;
+ uint8 data[1];
+};
+typedef struct wl_dload_data wl_dload_data_t;
+
+struct wl_ucode_info {
+ uint32 ucode_type;
+ uint32 num_chunks;
+ uint32 chunk_len;
+ uint32 chunk_num;
+ uint8 data_chunk[1];
+};
+typedef struct wl_ucode_info wl_ucode_info_t;
+
+struct wl_clm_dload_info {
+ uint32 ds_id;
+ uint32 clm_total_len;
+ uint32 num_chunks;
+ uint32 chunk_len;
+ uint32 chunk_offset;
+ uint8 data_chunk[1];
+};
+typedef struct wl_clm_dload_info wl_clm_dload_info_t;
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+typedef struct wlc_ssid {
+ uint32 SSID_len;
+ uchar SSID[32];
+} wlc_ssid_t;
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+
+#define MAX_PREFERRED_AP_NUM 5
+typedef struct wlc_fastssidinfo {
+ uint32 SSID_channel[MAX_PREFERRED_AP_NUM];
+ wlc_ssid_t SSID_info[MAX_PREFERRED_AP_NUM];
+} wlc_fastssidinfo_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct wnm_url {
+ uint8 len;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT wnm_url_t;
+
+typedef struct chan_scandata {
+ uint8 txpower;
+ uint8 pad;
+ chanspec_t channel; /* Channel num, bw, ctrl_sb and band */
+ uint32 channel_mintime;
+ uint32 channel_maxtime;
+} chan_scandata_t;
+
+typedef enum wl_scan_type {
+ EXTDSCAN_FOREGROUND_SCAN,
+ EXTDSCAN_BACKGROUND_SCAN,
+ EXTDSCAN_FORCEDBACKGROUND_SCAN
+} wl_scan_type_t;
+
+#define WLC_EXTDSCAN_MAX_SSID 5
+
+typedef struct wl_extdscan_params {
+ int8 nprobes; /* 0, passive, otherwise active */
+ int8 split_scan; /* split scan */
+ int8 band; /* band */
+ int8 pad;
+ wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID]; /* ssid list */
+ uint32 tx_rate; /* in 500ksec units */
+ wl_scan_type_t scan_type; /* enum */
+ int32 channel_num;
+ chan_scandata_t channel_list[1]; /* list of chandata structs */
+} wl_extdscan_params_t;
+
+#define WL_EXTDSCAN_PARAMS_FIXED_SIZE (sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t))
+
+#define WL_BSSTYPE_INFRA 1
+#define WL_BSSTYPE_INDEP 0
+#define WL_BSSTYPE_ANY 2
+
+/* Bitmask for scan_type */
+#define WL_SCANFLAGS_PASSIVE 0x01 /* force passive scan */
+#define WL_SCANFLAGS_RESERVED 0x02 /* Reserved */
+#define WL_SCANFLAGS_PROHIBITED 0x04 /* allow scanning prohibited channels */
+
+#define WL_SCAN_PARAMS_SSID_MAX 10
+
+typedef struct wl_scan_params {
+ wlc_ssid_t ssid; /* default: {0, ""} */
+ struct ether_addr bssid; /* default: bcast */
+ int8 bss_type; /* default: any,
+ * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
+ */
+ uint8 scan_type; /* flags, 0 use default */
+ int32 nprobes; /* -1 use default, number of probes per channel */
+ int32 active_time; /* -1 use default, dwell time per channel for
+ * active scanning
+ */
+ int32 passive_time; /* -1 use default, dwell time per channel
+ * for passive scanning
+ */
+ int32 home_time; /* -1 use default, dwell time for the home channel
+ * between channel scans
+ */
+ int32 channel_num; /* count of channels and ssids that follow
+ *
+ * low half is count of channels in channel_list, 0
+ * means default (use all available channels)
+ *
+ * high half is entries in wlc_ssid_t array that
+ * follows channel_list, aligned for int32 (4 bytes)
+ * meaning an odd channel count implies a 2-byte pad
+ * between end of channel_list and first ssid
+ *
+ * if ssid count is zero, single ssid in the fixed
+ * parameter portion is assumed, otherwise ssid in
+ * the fixed portion is ignored
+ */
+ uint16 channel_list[1]; /* list of chanspecs */
+} wl_scan_params_t;
+
+/* size of wl_scan_params not including variable length array */
+#define WL_SCAN_PARAMS_FIXED_SIZE 64
+
+/* masks for channel and ssid count */
+#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff
+#define WL_SCAN_PARAMS_NSSID_SHIFT 16
+
+#define WL_SCAN_ACTION_START 1
+#define WL_SCAN_ACTION_CONTINUE 2
+#define WL_SCAN_ACTION_ABORT 3
+
+#define ISCAN_REQ_VERSION 1
+
+/* incremental scan struct */
+typedef struct wl_iscan_params {
+ uint32 version;
+ uint16 action;
+ uint16 scan_duration;
+ wl_scan_params_t params;
+} wl_iscan_params_t;
+
+/* 3 fields + size of wl_scan_params, not including variable length array */
+#define WL_ISCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_iscan_params_t, params) + sizeof(wlc_ssid_t))
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+typedef struct wl_scan_results {
+ uint32 buflen;
+ uint32 version;
+ uint32 count;
+ wl_bss_info_t bss_info[1];
+} wl_scan_results_t;
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+/* size of wl_scan_results not including variable length array */
+#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t))
+
+/* wl_iscan_results status values */
+#define WL_SCAN_RESULTS_SUCCESS 0
+#define WL_SCAN_RESULTS_PARTIAL 1
+#define WL_SCAN_RESULTS_PENDING 2
+#define WL_SCAN_RESULTS_ABORTED 3
+#define WL_SCAN_RESULTS_NO_MEM 4
+
+/* Used in EXT_STA */
+#define DNGL_RXCTXT_SIZE 45
+
+
+#define ESCAN_REQ_VERSION 1
+
+typedef struct wl_escan_params {
+ uint32 version;
+ uint16 action;
+ uint16 sync_id;
+ wl_scan_params_t params;
+} wl_escan_params_t;
+
+#define WL_ESCAN_PARAMS_FIXED_SIZE (OFFSETOF(wl_escan_params_t, params) + sizeof(wlc_ssid_t))
+
+typedef struct wl_escan_result {
+ uint32 buflen;
+ uint32 version;
+ uint16 sync_id;
+ uint16 bss_count;
+ wl_bss_info_t bss_info[1];
+} wl_escan_result_t;
+
+#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t))
+
+/* incremental scan results struct */
+typedef struct wl_iscan_results {
+ uint32 status;
+ wl_scan_results_t results;
+} wl_iscan_results_t;
+
+/* size of wl_iscan_results not including variable length array */
+#define WL_ISCAN_RESULTS_FIXED_SIZE \
+ (WL_SCAN_RESULTS_FIXED_SIZE + OFFSETOF(wl_iscan_results_t, results))
+
+typedef struct wl_probe_params {
+ wlc_ssid_t ssid;
+ struct ether_addr bssid;
+ struct ether_addr mac;
+} wl_probe_params_t;
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+#define WL_MAXRATES_IN_SET 16 /* max # of rates in a rateset */
+typedef struct wl_rateset {
+ uint32 count; /* # rates in this set */
+ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */
+} wl_rateset_t;
+
+typedef struct wl_rateset_args {
+ uint32 count; /* # rates in this set */
+ uint8 rates[WL_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */
+ uint8 mcs[MCSSET_LEN]; /* supported mcs index bit map */
+} wl_rateset_args_t;
+
+/* uint32 list */
+typedef struct wl_uint32_list {
+ /* in - # of elements, out - # of entries */
+ uint32 count;
+ /* variable length uint32 list */
+ uint32 element[1];
+} wl_uint32_list_t;
+
+/* used for association with a specific BSSID and chanspec list */
+typedef struct wl_assoc_params {
+ struct ether_addr bssid; /* 00:00:00:00:00:00: broadcast scan */
+ uint16 bssid_cnt; /* 0: use chanspec_num, and the single bssid,
+ * otherwise count of chanspecs in chanspec_list
+ * AND paired bssids following chanspec_list
+ */
+ int32 chanspec_num; /* 0: all available channels,
+ * otherwise count of chanspecs in chanspec_list
+ */
+ chanspec_t chanspec_list[1]; /* list of chanspecs */
+} wl_assoc_params_t;
+#define WL_ASSOC_PARAMS_FIXED_SIZE OFFSETOF(wl_assoc_params_t, chanspec_list)
+
+/* used for reassociation/roam to a specific BSSID and channel */
+typedef wl_assoc_params_t wl_reassoc_params_t;
+#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE
+
+/* used for association to a specific BSSID and channel */
+typedef wl_assoc_params_t wl_join_assoc_params_t;
+#define WL_JOIN_ASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE
+
+/* used for join with or without a specific bssid and channel list */
+typedef struct wl_join_params {
+ wlc_ssid_t ssid;
+ wl_assoc_params_t params; /* optional field, but it must include the fixed portion
+ * of the wl_assoc_params_t struct when it does present.
+ */
+} wl_join_params_t;
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+#define WL_JOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_join_params_t, params) + \
+ WL_ASSOC_PARAMS_FIXED_SIZE)
+/* scan params for extended join */
+typedef struct wl_join_scan_params {
+ uint8 scan_type; /* 0 use default, active or passive scan */
+ int32 nprobes; /* -1 use default, number of probes per channel */
+ int32 active_time; /* -1 use default, dwell time per channel for
+ * active scanning
+ */
+ int32 passive_time; /* -1 use default, dwell time per channel
+ * for passive scanning
+ */
+ int32 home_time; /* -1 use default, dwell time for the home channel
+ * between channel scans
+ */
+} wl_join_scan_params_t;
+
+/* extended join params */
+typedef struct wl_extjoin_params {
+ wlc_ssid_t ssid; /* {0, ""}: wildcard scan */
+ wl_join_scan_params_t scan;
+ wl_join_assoc_params_t assoc; /* optional field, but it must include the fixed portion
+ * of the wl_join_assoc_params_t struct when it does
+ * present.
+ */
+} wl_extjoin_params_t;
+#define WL_EXTJOIN_PARAMS_FIXED_SIZE (OFFSETOF(wl_extjoin_params_t, assoc) + \
+ WL_JOIN_ASSOC_PARAMS_FIXED_SIZE)
+
+/* All builds use the new 11ac ratespec/chanspec */
+#undef D11AC_IOTYPES
+#define D11AC_IOTYPES
+
+#ifndef D11AC_IOTYPES
+
+/* defines used by the nrate iovar */
+#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */
+#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */
+#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */
+#define NRATE_STF_SHIFT 8 /* stf mode shift */
+#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */
+#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */
+#define NRATE_SGI_MASK 0x00800000 /* sgi mode */
+#define NRATE_SGI_SHIFT 23 /* sgi mode */
+#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */
+#define NRATE_LDPC_SHIFT 22 /* ldpc shift */
+
+#define NRATE_STF_SISO 0 /* stf mode SISO */
+#define NRATE_STF_CDD 1 /* stf mode CDD */
+#define NRATE_STF_STBC 2 /* stf mode STBC */
+#define NRATE_STF_SDM 3 /* stf mode SDM */
+
+#else /* D11AC_IOTYPES */
+
+/* WL_RSPEC defines for rate information */
+#define WL_RSPEC_RATE_MASK 0x000000FF /* rate or HT MCS value */
+#define WL_RSPEC_VHT_MCS_MASK 0x0000000F /* VHT MCS value */
+#define WL_RSPEC_VHT_NSS_MASK 0x000000F0 /* VHT Nss value */
+#define WL_RSPEC_VHT_NSS_SHIFT 4 /* VHT Nss value shift */
+#define WL_RSPEC_TXEXP_MASK 0x00000300
+#define WL_RSPEC_TXEXP_SHIFT 8
+#define WL_RSPEC_BW_MASK 0x00070000 /* bandwidth mask */
+#define WL_RSPEC_BW_SHIFT 16 /* bandwidth shift */
+#define WL_RSPEC_STBC 0x00100000 /* STBC encoding, Nsts = 2 x Nss */
+#define WL_RSPEC_LDPC 0x00400000 /* bit indicates adv coding in use */
+#define WL_RSPEC_SGI 0x00800000 /* Short GI mode */
+#define WL_RSPEC_ENCODING_MASK 0x03000000 /* Encoding of Rate/MCS field */
+#define WL_RSPEC_OVERRIDE_RATE 0x40000000 /* bit indicate to override mcs only */
+#define WL_RSPEC_OVERRIDE_MODE 0x80000000 /* bit indicates override both rate & mode */
+
+/* WL_RSPEC_ENCODING field defs */
+#define WL_RSPEC_ENCODE_RATE 0x00000000 /* Legacy rate is stored in RSPEC_RATE_MASK */
+#define WL_RSPEC_ENCODE_HT 0x01000000 /* HT MCS is stored in RSPEC_RATE_MASK */
+#define WL_RSPEC_ENCODE_VHT 0x02000000 /* VHT MCS and Nss is stored in RSPEC_RATE_MASK */
+
+/* WL_RSPEC_BW field defs */
+#define WL_RSPEC_BW_UNSPECIFIED 0
+#define WL_RSPEC_BW_20MHZ 0x00010000
+#define WL_RSPEC_BW_40MHZ 0x00020000
+#define WL_RSPEC_BW_80MHZ 0x00030000
+#define WL_RSPEC_BW_160MHZ 0x00040000
+
+/* Legacy defines for the nrate iovar */
+#define OLD_NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */
+#define OLD_NRATE_RATE_MASK 0x0000007f /* rate/mcs value */
+#define OLD_NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */
+#define OLD_NRATE_STF_SHIFT 8 /* stf mode shift */
+#define OLD_NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */
+#define OLD_NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */
+#define OLD_NRATE_SGI 0x00800000 /* sgi mode */
+#define OLD_NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */
+
+#define OLD_NRATE_STF_SISO 0 /* stf mode SISO */
+#define OLD_NRATE_STF_CDD 1 /* stf mode CDD */
+#define OLD_NRATE_STF_STBC 2 /* stf mode STBC */
+#define OLD_NRATE_STF_SDM 3 /* stf mode SDM */
+
+#endif /* D11AC_IOTYPES */
+
+#define ANTENNA_NUM_1 1 /* total number of antennas to be used */
+#define ANTENNA_NUM_2 2
+#define ANTENNA_NUM_3 3
+#define ANTENNA_NUM_4 4
+
+#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
+#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
+#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */
+#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */
+#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */
+#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */
+#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */
+
+#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */
+
+typedef struct {
+ uint8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */
+ uint8 num_antcfg; /* number of available antenna configurations */
+} wlc_antselcfg_t;
+
+#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */
+
+#define MAX_CCA_CHANNELS 38 /* Max number of 20 Mhz wide channels */
+#define MAX_CCA_SECS 60 /* CCA keeps this many seconds history */
+
+#define IBSS_MED 15 /* Mediom in-bss congestion percentage */
+#define IBSS_HI 25 /* Hi in-bss congestion percentage */
+#define OBSS_MED 12
+#define OBSS_HI 25
+#define INTERFER_MED 5
+#define INTERFER_HI 10
+
+#define CCA_FLAG_2G_ONLY 0x01 /* Return a channel from 2.4 Ghz band */
+#define CCA_FLAG_5G_ONLY 0x02 /* Return a channel from 2.4 Ghz band */
+#define CCA_FLAG_IGNORE_DURATION 0x04 /* Ignore dwell time for each channel */
+#define CCA_FLAGS_PREFER_1_6_11 0x10
+#define CCA_FLAG_IGNORE_INTERFER 0x20 /* do not exlude channel based on interfer level */
+
+#define CCA_ERRNO_BAND 1 /* After filtering for band pref, no choices left */
+#define CCA_ERRNO_DURATION 2 /* After filtering for duration, no choices left */
+#define CCA_ERRNO_PREF_CHAN 3 /* After filtering for chan pref, no choices left */
+#define CCA_ERRNO_INTERFER 4 /* After filtering for interference, no choices left */
+#define CCA_ERRNO_TOO_FEW 5 /* Only 1 channel was input */
+
+typedef struct {
+ uint32 duration; /* millisecs spent sampling this channel */
+ uint32 congest_ibss; /* millisecs in our bss (presumably this traffic will */
+ /* move if cur bss moves channels) */
+ uint32 congest_obss; /* traffic not in our bss */
+ uint32 interference; /* millisecs detecting a non 802.11 interferer. */
+ uint32 timestamp; /* second timestamp */
+} cca_congest_t;
+
+typedef struct {
+ chanspec_t chanspec; /* Which channel? */
+ uint8 num_secs; /* How many secs worth of data */
+ cca_congest_t secs[1]; /* Data */
+} cca_congest_channel_req_t;
+
+/* interference source detection and identification mode */
+#define ITFR_MODE_DISABLE 0 /* disable feature */
+#define ITFR_MODE_MANUAL_ENABLE 1 /* enable manual detection */
+#define ITFR_MODE_AUTO_ENABLE 2 /* enable auto detection */
+
+/* interference sources */
+enum interference_source {
+ ITFR_NONE = 0, /* interference */
+ ITFR_PHONE, /* wireless phone */
+ ITFR_VIDEO_CAMERA, /* wireless video camera */
+ ITFR_MICROWAVE_OVEN, /* microwave oven */
+ ITFR_BABY_MONITOR, /* wireless baby monitor */
+ ITFR_BLUETOOTH, /* bluetooth */
+ ITFR_VIDEO_CAMERA_OR_BABY_MONITOR, /* wireless camera or baby monitor */
+ ITFR_BLUETOOTH_OR_BABY_MONITOR, /* bluetooth or baby monitor */
+ ITFR_VIDEO_CAMERA_OR_PHONE, /* video camera or phone */
+ ITFR_UNIDENTIFIED /* interference from unidentified source */
+};
+
+/* structure for interference source report */
+typedef struct {
+ uint32 flags; /* flags. bit definitions below */
+ uint32 source; /* last detected interference source */
+ uint32 timestamp; /* second timestamp on interferenced flag change */
+} interference_source_rep_t;
+
+/* bit definitions for flags in interference source report */
+#define ITFR_INTERFERENCED 1 /* interference detected */
+#define ITFR_HOME_CHANNEL 2 /* home channel has interference */
+#define ITFR_NOISY_ENVIRONMENT 4 /* noisy environemnt so feature stopped */
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+
+typedef struct wl_country {
+ char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in
+ * the Country IE
+ */
+ int32 rev; /* revision specifier for ccode
+ * on set, -1 indicates unspecified.
+ * on get, rev >= 0
+ */
+ char ccode[WLC_CNTRY_BUF_SZ]; /* nul-terminated built-in country code.
+ * variable length, but fixed size in
+ * struct allows simple allocation for
+ * expected country strings <= 3 chars.
+ */
+} wl_country_t;
+
+typedef struct wl_channels_in_country {
+ uint32 buflen;
+ uint32 band;
+ char country_abbrev[WLC_CNTRY_BUF_SZ];
+ uint32 count;
+ uint32 channel[1];
+} wl_channels_in_country_t;
+
+typedef struct wl_country_list {
+ uint32 buflen;
+ uint32 band_set;
+ uint32 band;
+ uint32 count;
+ char country_abbrev[1];
+} wl_country_list_t;
+
+#define WL_NUM_RPI_BINS 8
+#define WL_RM_TYPE_BASIC 1
+#define WL_RM_TYPE_CCA 2
+#define WL_RM_TYPE_RPI 3
+
+#define WL_RM_FLAG_PARALLEL (1<<0)
+
+#define WL_RM_FLAG_LATE (1<<1)
+#define WL_RM_FLAG_INCAPABLE (1<<2)
+#define WL_RM_FLAG_REFUSED (1<<3)
+
+typedef struct wl_rm_req_elt {
+ int8 type;
+ int8 flags;
+ chanspec_t chanspec;
+ uint32 token; /* token for this measurement */
+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */
+ uint32 tsf_l; /* TSF low 32-bits */
+ uint32 dur; /* TUs */
+} wl_rm_req_elt_t;
+
+typedef struct wl_rm_req {
+ uint32 token; /* overall measurement set token */
+ uint32 count; /* number of measurement requests */
+ void *cb; /* completion callback function: may be NULL */
+ void *cb_arg; /* arg to completion callback function */
+ wl_rm_req_elt_t req[1]; /* variable length block of requests */
+} wl_rm_req_t;
+#define WL_RM_REQ_FIXED_LEN OFFSETOF(wl_rm_req_t, req)
+
+typedef struct wl_rm_rep_elt {
+ int8 type;
+ int8 flags;
+ chanspec_t chanspec;
+ uint32 token; /* token for this measurement */
+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */
+ uint32 tsf_l; /* TSF low 32-bits */
+ uint32 dur; /* TUs */
+ uint32 len; /* byte length of data block */
+ uint8 data[1]; /* variable length data block */
+} wl_rm_rep_elt_t;
+#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */
+
+#define WL_RPI_REP_BIN_NUM 8
+typedef struct wl_rm_rpi_rep {
+ uint8 rpi[WL_RPI_REP_BIN_NUM];
+ int8 rpi_max[WL_RPI_REP_BIN_NUM];
+} wl_rm_rpi_rep_t;
+
+typedef struct wl_rm_rep {
+ uint32 token; /* overall measurement set token */
+ uint32 len; /* length of measurement report block */
+ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */
+} wl_rm_rep_t;
+#define WL_RM_REP_FIXED_LEN 8
+
+
+typedef enum sup_auth_status {
+ /* Basic supplicant authentication states */
+ WLC_SUP_DISCONNECTED = 0,
+ WLC_SUP_CONNECTING,
+ WLC_SUP_IDREQUIRED,
+ WLC_SUP_AUTHENTICATING,
+ WLC_SUP_AUTHENTICATED,
+ WLC_SUP_KEYXCHANGE,
+ WLC_SUP_KEYED,
+ WLC_SUP_TIMEOUT,
+ WLC_SUP_LAST_BASIC_STATE,
+
+ /* Extended supplicant authentication states */
+ /* Waiting to receive handshake msg M1 */
+ WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED,
+ /* Preparing to send handshake msg M2 */
+ WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE,
+ /* Waiting to receive handshake msg M3 */
+ WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE,
+ WLC_SUP_KEYXCHANGE_PREP_M4, /* Preparing to send handshake msg M4 */
+ WLC_SUP_KEYXCHANGE_WAIT_G1, /* Waiting to receive handshake msg G1 */
+ WLC_SUP_KEYXCHANGE_PREP_G2 /* Preparing to send handshake msg G2 */
+} sup_auth_status_t;
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* Enumerate crypto algorithms */
+#define CRYPTO_ALGO_OFF 0
+#define CRYPTO_ALGO_WEP1 1
+#define CRYPTO_ALGO_TKIP 2
+#define CRYPTO_ALGO_WEP128 3
+#define CRYPTO_ALGO_AES_CCM 4
+#define CRYPTO_ALGO_AES_OCB_MSDU 5
+#define CRYPTO_ALGO_AES_OCB_MPDU 6
+#if !defined(BCMEXTCCX)
+#define CRYPTO_ALGO_NALG 7
+#else
+#define CRYPTO_ALGO_CKIP 7
+#define CRYPTO_ALGO_CKIP_MMH 8
+#define CRYPTO_ALGO_WEP_MMH 9
+#define CRYPTO_ALGO_NALG 10
+#endif
+#ifdef BCMWAPI_WPI
+#define CRYPTO_ALGO_SMS4 11
+#endif /* BCMWAPI_WPI */
+#define CRYPTO_ALGO_PMK 12 /* for 802.1x supp to set PMK before 4-way */
+
+#define WSEC_GEN_MIC_ERROR 0x0001
+#define WSEC_GEN_REPLAY 0x0002
+#define WSEC_GEN_ICV_ERROR 0x0004
+#define WSEC_GEN_MFP_ACT_ERROR 0x0008
+#define WSEC_GEN_MFP_DISASSOC_ERROR 0x0010
+#define WSEC_GEN_MFP_DEAUTH_ERROR 0x0020
+
+#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */
+#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */
+#if defined(BCMEXTCCX)
+#define WL_CKIP_KP (1 << 4) /* CMIC */
+#define WL_CKIP_MMH (1 << 5) /* CKIP */
+#else
+#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */
+#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */
+#endif
+#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */
+
+typedef struct wl_wsec_key {
+ uint32 index; /* key index */
+ uint32 len; /* key length */
+ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */
+ uint32 pad_1[18];
+ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+ uint32 flags; /* misc flags */
+ uint32 pad_2[2];
+ int pad_3;
+ int iv_initialized; /* has IV been initialized already? */
+ int pad_4;
+ /* Rx IV */
+ struct {
+ uint32 hi; /* upper 32 bits of IV */
+ uint16 lo; /* lower 16 bits of IV */
+ } rxiv;
+ uint32 pad_5[2];
+ struct ether_addr ea; /* per station */
+} wl_wsec_key_t;
+
+#define WSEC_MIN_PSK_LEN 8
+#define WSEC_MAX_PSK_LEN 64
+
+/* Flag for key material needing passhash'ing */
+#define WSEC_PASSPHRASE (1<<0)
+
+/* receptacle for WLC_SET_WSEC_PMK parameter */
+typedef struct {
+ ushort key_len; /* octets in key material */
+ ushort flags; /* key handling qualification */
+ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */
+} wsec_pmk_t;
+
+/* wireless security bitvec */
+#define WEP_ENABLED 0x0001
+#define TKIP_ENABLED 0x0002
+#define AES_ENABLED 0x0004
+#define WSEC_SWFLAG 0x0008
+#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */
+
+/* wsec macros for operating on the above definitions */
+#define WSEC_WEP_ENABLED(wsec) ((wsec) & WEP_ENABLED)
+#define WSEC_TKIP_ENABLED(wsec) ((wsec) & TKIP_ENABLED)
+#define WSEC_AES_ENABLED(wsec) ((wsec) & AES_ENABLED)
+
+#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
+#define WSEC_SES_OW_ENABLED(wsec) ((wsec) & SES_OW_ENABLED)
+#ifdef BCMWAPI_WPI
+#define SMS4_ENABLED 0x0100
+#endif /* BCMWAPI_WPI */
+
+#ifdef MFP
+#define MFP_CAPABLE 0x0200
+#define MFP_REQUIRED 0x0400
+#define MFP_SHA256 0x0800 /* a special configuration for STA for WIFI test tool */
+#endif /* MFP */
+
+/* WPA authentication mode bitvec */
+#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
+#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */
+#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */
+#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */
+#if defined(BCMEXTCCX)
+#define WPA_AUTH_CCKM 0x0008 /* CCKM */
+#define WPA2_AUTH_CCKM 0x0010 /* CCKM2 */
+#endif
+/* #define WPA_AUTH_8021X 0x0020 */ /* 802.1x, reserved */
+#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */
+#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */
+#define BRCM_AUTH_PSK 0x0100 /* BRCM specific PSK */
+#define BRCM_AUTH_DPT 0x0200 /* DPT PSK without group keys */
+#ifdef BCMWAPI_WAI
+#define WPA_AUTH_WAPI 0x0400
+#define WAPI_AUTH_NONE WPA_AUTH_NONE /* none (IBSS) */
+#define WAPI_AUTH_UNSPECIFIED 0x0400 /* over AS */
+#define WAPI_AUTH_PSK 0x0800 /* Pre-shared key */
+#endif /* BCMWAPI_WAI */
+#define WPA2_AUTH_MFP 0x1000 /* MFP (11w) in contrast to CCX */
+#define WPA2_AUTH_TPK 0x2000 /* TDLS Peer Key */
+#define WPA2_AUTH_FT 0x4000 /* Fast Transition. */
+#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */
+
+/* pmkid */
+#define MAXPMKID 16
+
+typedef struct _pmkid {
+ struct ether_addr BSSID;
+ uint8 PMKID[WPA2_PMKID_LEN];
+} pmkid_t;
+
+typedef struct _pmkid_list {
+ uint32 npmkid;
+ pmkid_t pmkid[1];
+} pmkid_list_t;
+
+typedef struct _pmkid_cand {
+ struct ether_addr BSSID;
+ uint8 preauth;
+} pmkid_cand_t;
+
+typedef struct _pmkid_cand_list {
+ uint32 npmkid_cand;
+ pmkid_cand_t pmkid_cand[1];
+} pmkid_cand_list_t;
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+typedef struct wl_assoc_info {
+ uint32 req_len;
+ uint32 resp_len;
+ uint32 flags;
+ struct dot11_assoc_req req;
+ struct ether_addr reassoc_bssid; /* used in reassoc's */
+ struct dot11_assoc_resp resp;
+} wl_assoc_info_t;
+
+/* flags */
+#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */
+
+typedef struct wl_led_info {
+ uint32 index; /* led index */
+ uint32 behavior;
+ uint8 activehi;
+} wl_led_info_t;
+
+
+/* srom read/write struct passed through ioctl */
+typedef struct {
+ uint byteoff; /* byte offset */
+ uint nbytes; /* number of bytes */
+ uint16 buf[1];
+} srom_rw_t;
+
+/* similar cis (srom or otp) struct [iovar: may not be aligned] */
+typedef struct {
+ uint32 source; /* cis source */
+ uint32 byteoff; /* byte offset */
+ uint32 nbytes; /* number of bytes */
+ /* data follows here */
+} cis_rw_t;
+
+#define WLC_CIS_DEFAULT 0 /* built-in default */
+#define WLC_CIS_SROM 1 /* source is sprom */
+#define WLC_CIS_OTP 2 /* source is otp */
+
+/* R_REG and W_REG struct passed through ioctl */
+typedef struct {
+ uint32 byteoff; /* byte offset of the field in d11regs_t */
+ uint32 val; /* read/write value of the field */
+ uint32 size; /* sizeof the field */
+ uint band; /* band (optional) */
+} rw_reg_t;
+
+/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */
+/* PCL - Power Control Loop */
+/* current gain setting is replaced by user input */
+#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */
+#define WL_ATTEN_PCL_ON 1 /* turn on PCL */
+/* current gain setting is maintained */
+#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */
+
+typedef struct {
+ uint16 auto_ctrl; /* WL_ATTEN_XX */
+ uint16 bb; /* Baseband attenuation */
+ uint16 radio; /* Radio attenuation */
+ uint16 txctl1; /* Radio TX_CTL1 value */
+} atten_t;
+
+/* Per-AC retry parameters */
+struct wme_tx_params_s {
+ uint8 short_retry;
+ uint8 short_fallback;
+ uint8 long_retry;
+ uint8 long_fallback;
+ uint16 max_rate; /* In units of 512 Kbps */
+};
+
+typedef struct wme_tx_params_s wme_tx_params_t;
+
+#define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT)
+
+/* defines used by poweridx iovar - it controls power in a-band */
+/* current gain setting is maintained */
+#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */
+#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */
+#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */
+#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */
+/* value >= 0 causes
+ * - input to be set to that value
+ * - PCL to be off
+ */
+
+/* Used to get specific link/ac parameters */
+typedef struct {
+ int ac;
+ uint8 val;
+ struct ether_addr ea;
+} link_val_t;
+
+#define BCM_MAC_STATUS_INDICATION (0x40010200L)
+
+typedef struct {
+ uint16 ver; /* version of this struct */
+ uint16 len; /* length in bytes of this structure */
+ uint16 cap; /* sta's advertised capabilities */
+ uint32 flags; /* flags defined below */
+ uint32 idle; /* time since data pkt rx'd from sta */
+ struct ether_addr ea; /* Station address */
+ wl_rateset_t rateset; /* rateset in use */
+ uint32 in; /* seconds elapsed since associated */
+ uint32 listen_interval_inms; /* Min Listen interval in ms for this STA */
+ uint32 tx_pkts; /* # of packets transmitted */
+ uint32 tx_failures; /* # of packets failed */
+ uint32 rx_ucast_pkts; /* # of unicast packets received */
+ uint32 rx_mcast_pkts; /* # of multicast packets received */
+ uint32 tx_rate; /* Rate of last successful tx frame */
+ uint32 rx_rate; /* Rate of last successful rx frame */
+ uint32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
+ uint32 rx_decrypt_failures; /* # of packet decrypted unsuccessfully */
+} sta_info_t;
+
+#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts)
+
+#define WL_STA_VER 3
+
+/* Flags for sta_info_t indicating properties of STA */
+#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */
+#define WL_STA_WME 0x2 /* WMM association */
+#define WL_STA_UNUSED 0x4
+#define WL_STA_AUTHE 0x8 /* Authenticated */
+#define WL_STA_ASSOC 0x10 /* Associated */
+#define WL_STA_AUTHO 0x20 /* Authorized */
+#define WL_STA_WDS 0x40 /* Wireless Distribution System */
+#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */
+#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */
+#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */
+#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */
+#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */
+#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */
+#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */
+#define WL_STA_SCBSTATS 0x4000 /* Per STA debug stats */
+
+#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */
+
+/* Values for TX Filter override mode */
+#define WLC_TXFILTER_OVERRIDE_DISABLED 0
+#define WLC_TXFILTER_OVERRIDE_ENABLED 1
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* Used to get specific STA parameters */
+typedef struct {
+ uint32 val;
+ struct ether_addr ea;
+} scb_val_t;
+
+/* Used by iovar versions of some ioctls, i.e. WLC_SCB_AUTHORIZE et al */
+typedef struct {
+ uint32 code;
+ scb_val_t ioctl_args;
+} authops_t;
+
+/* channel encoding */
+typedef struct channel_info {
+ int hw_channel;
+ int target_channel;
+ int scan_channel;
+} channel_info_t;
+
+/* For ioctls that take a list of MAC addresses */
+struct maclist {
+ uint count; /* number of MAC addresses */
+ struct ether_addr ea[1]; /* variable length array of MAC addresses */
+};
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+/* get pkt count struct passed through ioctl */
+typedef struct get_pktcnt {
+ uint rx_good_pkt;
+ uint rx_bad_pkt;
+ uint tx_good_pkt;
+ uint tx_bad_pkt;
+ uint rx_ocast_good_pkt; /* unicast packets destined for others */
+} get_pktcnt_t;
+
+/* NINTENDO2 */
+#define LQ_IDX_MIN 0
+#define LQ_IDX_MAX 1
+#define LQ_IDX_AVG 2
+#define LQ_IDX_SUM 2
+#define LQ_IDX_LAST 3
+#define LQ_STOP_MONITOR 0
+#define LQ_START_MONITOR 1
+
+/* Get averages RSSI, Rx PHY rate and SNR values */
+typedef struct {
+ int rssi[LQ_IDX_LAST]; /* Array to keep min, max, avg rssi */
+ int snr[LQ_IDX_LAST]; /* Array to keep min, max, avg snr */
+ int isvalid; /* Flag indicating whether above data is valid */
+} wl_lq_t; /* Link Quality */
+
+typedef enum wl_wakeup_reason_type {
+ LCD_ON = 1,
+ LCD_OFF,
+ DRC1_WAKE,
+ DRC2_WAKE,
+ REASON_LAST
+} wl_wr_type_t;
+
+typedef struct {
+/* Unique filter id */
+ uint32 id;
+
+/* stores the reason for the last wake up */
+ uint8 reason;
+} wl_wr_t;
+
+/* Get MAC specific rate histogram command */
+typedef struct {
+ struct ether_addr ea; /* MAC Address */
+ uint8 ac_cat; /* Access Category */
+ uint8 num_pkts; /* Number of packet entries to be averaged */
+} wl_mac_ratehisto_cmd_t; /* MAC Specific Rate Histogram command */
+
+/* Get MAC rate histogram response */
+typedef struct {
+ uint32 rate[WLC_MAXRATE + 1]; /* Rates */
+ uint32 mcs[WL_RATESET_SZ_HT_MCS * WL_TX_CHAINS_MAX]; /* MCS counts */
+ uint32 vht[WL_RATESET_SZ_VHT_MCS][WL_TX_CHAINS_MAX]; /* VHT counts */
+ uint32 tsf_timer[2][2]; /* Start and End time for 8bytes value */
+} wl_mac_ratehisto_res_t; /* MAC Specific Rate Histogram Response */
+
+/* Values for TX Filter override mode */
+#define WLC_TXFILTER_OVERRIDE_DISABLED 0
+#define WLC_TXFILTER_OVERRIDE_ENABLED 1
+
+#define WL_IOCTL_ACTION_GET 0x0
+#define WL_IOCTL_ACTION_SET 0x1
+#define WL_IOCTL_ACTION_OVL_IDX_MASK 0x1e
+#define WL_IOCTL_ACTION_OVL_RSV 0x20
+#define WL_IOCTL_ACTION_OVL 0x40
+#define WL_IOCTL_ACTION_MASK 0x7e
+#define WL_IOCTL_ACTION_OVL_SHIFT 1
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* Linux network driver ioctl encoding */
+typedef struct wl_ioctl {
+ uint cmd; /* common ioctl definition */
+ void *buf; /* pointer to user buffer */
+ uint len; /* length of user buffer */
+ uint8 set; /* 1=set IOCTL; 0=query IOCTL */
+ uint used; /* bytes read or written (optional) */
+ uint needed; /* bytes needed (optional) */
+} wl_ioctl_t;
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+
+/* reference to wl_ioctl_t struct used by usermode driver */
+#define ioctl_subtype set /* subtype param */
+#define ioctl_pid used /* pid param */
+#define ioctl_status needed /* status param */
+
+/*
+ * Structure for passing hardware and software
+ * revision info up from the driver.
+ */
+typedef struct wlc_rev_info {
+ uint vendorid; /* PCI vendor id */
+ uint deviceid; /* device id of chip */
+ uint radiorev; /* radio revision */
+ uint chiprev; /* chip revision */
+ uint corerev; /* core revision */
+ uint boardid; /* board identifier (usu. PCI sub-device id) */
+ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */
+ uint boardrev; /* board revision */
+ uint driverrev; /* driver version */
+ uint ucoderev; /* microcode version */
+ uint bus; /* bus type */
+ uint chipnum; /* chip number */
+ uint phytype; /* phy type */
+ uint phyrev; /* phy revision */
+ uint anarev; /* anacore rev */
+ uint chippkg; /* chip package info */
+} wlc_rev_info_t;
+
+#define WL_REV_INFO_LEGACY_LENGTH 48
+
+#define WL_BRAND_MAX 10
+typedef struct wl_instance_info {
+ uint instance;
+ char brand[WL_BRAND_MAX];
+} wl_instance_info_t;
+
+/* structure to change size of tx fifo */
+typedef struct wl_txfifo_sz {
+ uint16 magic;
+ uint16 fifo;
+ uint16 size;
+} wl_txfifo_sz_t;
+/* magic pattern used for mismatch driver and wl */
+#define WL_TXFIFO_SZ_MAGIC 0xa5a5
+
+/* Transfer info about an IOVar from the driver */
+/* Max supported IOV name size in bytes, + 1 for nul termination */
+#define WLC_IOV_NAME_LEN 30
+typedef struct wlc_iov_trx_s {
+ uint8 module;
+ uint8 type;
+ char name[WLC_IOV_NAME_LEN];
+} wlc_iov_trx_t;
+
+/* check this magic number */
+#define WLC_IOCTL_MAGIC 0x14e46c77
+
+/* bump this number if you change the ioctl interface */
+#ifdef D11AC_IOTYPES
+#define WLC_IOCTL_VERSION 2
+#define WLC_IOCTL_VERSION_LEGACY_IOTYPES 1
+#else
+#define WLC_IOCTL_VERSION 1
+#endif /* D11AC_IOTYPES */
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */
+#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */
+#define WLC_IOCTL_MEDLEN 1536 /* "med" length ioctl buffer required */
+#if defined(LCNCONF) || defined(LCN40CONF)
+#define WLC_SAMPLECOLLECT_MAXLEN 8192 /* Max Sample Collect buffer */
+#else
+#define WLC_SAMPLECOLLECT_MAXLEN 10240 /* Max Sample Collect buffer for two cores */
+#endif
+
+/* common ioctl definitions */
+#define WLC_GET_MAGIC 0
+#define WLC_GET_VERSION 1
+#define WLC_UP 2
+#define WLC_DOWN 3
+#define WLC_GET_LOOP 4
+#define WLC_SET_LOOP 5
+#define WLC_DUMP 6
+#define WLC_GET_MSGLEVEL 7
+#define WLC_SET_MSGLEVEL 8
+#define WLC_GET_PROMISC 9
+#define WLC_SET_PROMISC 10
+/* #define WLC_OVERLAY_IOCTL 11 */ /* not supported */
+#define WLC_GET_RATE 12
+#define WLC_GET_MAX_RATE 13
+#define WLC_GET_INSTANCE 14
+/* #define WLC_GET_FRAG 15 */ /* no longer supported */
+/* #define WLC_SET_FRAG 16 */ /* no longer supported */
+/* #define WLC_GET_RTS 17 */ /* no longer supported */
+/* #define WLC_SET_RTS 18 */ /* no longer supported */
+#define WLC_GET_INFRA 19
+#define WLC_SET_INFRA 20
+#define WLC_GET_AUTH 21
+#define WLC_SET_AUTH 22
+#define WLC_GET_BSSID 23
+#define WLC_SET_BSSID 24
+#define WLC_GET_SSID 25
+#define WLC_SET_SSID 26
+#define WLC_RESTART 27
+#define WLC_TERMINATED 28
+/* #define WLC_DUMP_SCB 28 */ /* no longer supported */
+#define WLC_GET_CHANNEL 29
+#define WLC_SET_CHANNEL 30
+#define WLC_GET_SRL 31
+#define WLC_SET_SRL 32
+#define WLC_GET_LRL 33
+#define WLC_SET_LRL 34
+#define WLC_GET_PLCPHDR 35
+#define WLC_SET_PLCPHDR 36
+#define WLC_GET_RADIO 37
+#define WLC_SET_RADIO 38
+#define WLC_GET_PHYTYPE 39
+#define WLC_DUMP_RATE 40
+#define WLC_SET_RATE_PARAMS 41
+#define WLC_GET_FIXRATE 42
+#define WLC_SET_FIXRATE 43
+/* #define WLC_GET_WEP 42 */ /* no longer supported */
+/* #define WLC_SET_WEP 43 */ /* no longer supported */
+#define WLC_GET_KEY 44
+#define WLC_SET_KEY 45
+#define WLC_GET_REGULATORY 46
+#define WLC_SET_REGULATORY 47
+#define WLC_GET_PASSIVE_SCAN 48
+#define WLC_SET_PASSIVE_SCAN 49
+#define WLC_SCAN 50
+#define WLC_SCAN_RESULTS 51
+#define WLC_DISASSOC 52
+#define WLC_REASSOC 53
+#define WLC_GET_ROAM_TRIGGER 54
+#define WLC_SET_ROAM_TRIGGER 55
+#define WLC_GET_ROAM_DELTA 56
+#define WLC_SET_ROAM_DELTA 57
+#define WLC_GET_ROAM_SCAN_PERIOD 58
+#define WLC_SET_ROAM_SCAN_PERIOD 59
+#define WLC_EVM 60 /* diag */
+#define WLC_GET_TXANT 61
+#define WLC_SET_TXANT 62
+#define WLC_GET_ANTDIV 63
+#define WLC_SET_ANTDIV 64
+/* #define WLC_GET_TXPWR 65 */ /* no longer supported */
+/* #define WLC_SET_TXPWR 66 */ /* no longer supported */
+#define WLC_GET_CLOSED 67
+#define WLC_SET_CLOSED 68
+#define WLC_GET_MACLIST 69
+#define WLC_SET_MACLIST 70
+#define WLC_GET_RATESET 71
+#define WLC_SET_RATESET 72
+/* #define WLC_GET_LOCALE 73 */ /* no longer supported */
+#define WLC_LONGTRAIN 74
+#define WLC_GET_BCNPRD 75
+#define WLC_SET_BCNPRD 76
+#define WLC_GET_DTIMPRD 77
+#define WLC_SET_DTIMPRD 78
+#define WLC_GET_SROM 79
+#define WLC_SET_SROM 80
+#define WLC_GET_WEP_RESTRICT 81
+#define WLC_SET_WEP_RESTRICT 82
+#define WLC_GET_COUNTRY 83
+#define WLC_SET_COUNTRY 84
+#define WLC_GET_PM 85
+#define WLC_SET_PM 86
+#define WLC_GET_WAKE 87
+#define WLC_SET_WAKE 88
+/* #define WLC_GET_D11CNTS 89 */ /* -> "counters" iovar */
+#define WLC_GET_FORCELINK 90 /* ndis only */
+#define WLC_SET_FORCELINK 91 /* ndis only */
+#define WLC_FREQ_ACCURACY 92 /* diag */
+#define WLC_CARRIER_SUPPRESS 93 /* diag */
+#define WLC_GET_PHYREG 94
+#define WLC_SET_PHYREG 95
+#define WLC_GET_RADIOREG 96
+#define WLC_SET_RADIOREG 97
+#define WLC_GET_REVINFO 98
+#define WLC_GET_UCANTDIV 99
+#define WLC_SET_UCANTDIV 100
+#define WLC_R_REG 101
+#define WLC_W_REG 102
+/* #define WLC_DIAG_LOOPBACK 103 old tray diag */
+/* #define WLC_RESET_D11CNTS 104 */ /* -> "reset_d11cnts" iovar */
+#define WLC_GET_MACMODE 105
+#define WLC_SET_MACMODE 106
+#define WLC_GET_MONITOR 107
+#define WLC_SET_MONITOR 108
+#define WLC_GET_GMODE 109
+#define WLC_SET_GMODE 110
+#define WLC_GET_LEGACY_ERP 111
+#define WLC_SET_LEGACY_ERP 112
+#define WLC_GET_RX_ANT 113
+#define WLC_GET_CURR_RATESET 114 /* current rateset */
+#define WLC_GET_SCANSUPPRESS 115
+#define WLC_SET_SCANSUPPRESS 116
+#define WLC_GET_AP 117
+#define WLC_SET_AP 118
+#define WLC_GET_EAP_RESTRICT 119
+#define WLC_SET_EAP_RESTRICT 120
+#define WLC_SCB_AUTHORIZE 121
+#define WLC_SCB_DEAUTHORIZE 122
+#define WLC_GET_WDSLIST 123
+#define WLC_SET_WDSLIST 124
+#define WLC_GET_ATIM 125
+#define WLC_SET_ATIM 126
+#define WLC_GET_RSSI 127
+#define WLC_GET_PHYANTDIV 128
+#define WLC_SET_PHYANTDIV 129
+#define WLC_AP_RX_ONLY 130
+#define WLC_GET_TX_PATH_PWR 131
+#define WLC_SET_TX_PATH_PWR 132
+#define WLC_GET_WSEC 133
+#define WLC_SET_WSEC 134
+#define WLC_GET_PHY_NOISE 135
+#define WLC_GET_BSS_INFO 136
+#define WLC_GET_PKTCNTS 137
+#define WLC_GET_LAZYWDS 138
+#define WLC_SET_LAZYWDS 139
+#define WLC_GET_BANDLIST 140
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+#define WLC_GET_BAND 141
+#define WLC_SET_BAND 142
+#define WLC_SCB_DEAUTHENTICATE 143
+#define WLC_GET_SHORTSLOT 144
+#define WLC_GET_SHORTSLOT_OVERRIDE 145
+#define WLC_SET_SHORTSLOT_OVERRIDE 146
+#define WLC_GET_SHORTSLOT_RESTRICT 147
+#define WLC_SET_SHORTSLOT_RESTRICT 148
+#define WLC_GET_GMODE_PROTECTION 149
+#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150
+#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151
+#define WLC_UPGRADE 152
+/* #define WLC_GET_MRATE 153 */ /* no longer supported */
+/* #define WLC_SET_MRATE 154 */ /* no longer supported */
+#define WLC_GET_IGNORE_BCNS 155
+#define WLC_SET_IGNORE_BCNS 156
+#define WLC_GET_SCB_TIMEOUT 157
+#define WLC_SET_SCB_TIMEOUT 158
+#define WLC_GET_ASSOCLIST 159
+#define WLC_GET_CLK 160
+#define WLC_SET_CLK 161
+#define WLC_GET_UP 162
+#define WLC_OUT 163
+#define WLC_GET_WPA_AUTH 164
+#define WLC_SET_WPA_AUTH 165
+#define WLC_GET_UCFLAGS 166
+#define WLC_SET_UCFLAGS 167
+#define WLC_GET_PWRIDX 168
+#define WLC_SET_PWRIDX 169
+#define WLC_GET_TSSI 170
+#define WLC_GET_SUP_RATESET_OVERRIDE 171
+#define WLC_SET_SUP_RATESET_OVERRIDE 172
+/* #define WLC_SET_FAST_TIMER 173 */ /* no longer supported */
+/* #define WLC_GET_FAST_TIMER 174 */ /* no longer supported */
+/* #define WLC_SET_SLOW_TIMER 175 */ /* no longer supported */
+/* #define WLC_GET_SLOW_TIMER 176 */ /* no longer supported */
+/* #define WLC_DUMP_PHYREGS 177 */ /* no longer supported */
+#define WLC_GET_PROTECTION_CONTROL 178
+#define WLC_SET_PROTECTION_CONTROL 179
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+#define WLC_GET_PHYLIST 180
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+#define WLC_ENCRYPT_STRENGTH 181 /* ndis only */
+#define WLC_DECRYPT_STATUS 182 /* ndis only */
+#define WLC_GET_KEY_SEQ 183
+#define WLC_GET_SCAN_CHANNEL_TIME 184
+#define WLC_SET_SCAN_CHANNEL_TIME 185
+#define WLC_GET_SCAN_UNASSOC_TIME 186
+#define WLC_SET_SCAN_UNASSOC_TIME 187
+#define WLC_GET_SCAN_HOME_TIME 188
+#define WLC_SET_SCAN_HOME_TIME 189
+#define WLC_GET_SCAN_NPROBES 190
+#define WLC_SET_SCAN_NPROBES 191
+#define WLC_GET_PRB_RESP_TIMEOUT 192
+#define WLC_SET_PRB_RESP_TIMEOUT 193
+#define WLC_GET_ATTEN 194
+#define WLC_SET_ATTEN 195
+#define WLC_GET_SHMEM 196 /* diag */
+#define WLC_SET_SHMEM 197 /* diag */
+/* #define WLC_GET_GMODE_PROTECTION_CTS 198 */ /* no longer supported */
+/* #define WLC_SET_GMODE_PROTECTION_CTS 199 */ /* no longer supported */
+#define WLC_SET_WSEC_TEST 200
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+#define WLC_TKIP_COUNTERMEASURES 202
+#define WLC_GET_PIOMODE 203
+#define WLC_SET_PIOMODE 204
+#define WLC_SET_ASSOC_PREFER 205
+#define WLC_GET_ASSOC_PREFER 206
+#define WLC_SET_ROAM_PREFER 207
+#define WLC_GET_ROAM_PREFER 208
+#define WLC_SET_LED 209
+#define WLC_GET_LED 210
+#define WLC_GET_INTERFERENCE_MODE 211
+#define WLC_SET_INTERFERENCE_MODE 212
+#define WLC_GET_CHANNEL_QA 213
+#define WLC_START_CHANNEL_QA 214
+#define WLC_GET_CHANNEL_SEL 215
+#define WLC_START_CHANNEL_SEL 216
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+#define WLC_GET_VALID_CHANNELS 217
+#define WLC_GET_FAKEFRAG 218
+#define WLC_SET_FAKEFRAG 219
+#define WLC_GET_PWROUT_PERCENTAGE 220
+#define WLC_SET_PWROUT_PERCENTAGE 221
+#define WLC_SET_BAD_FRAME_PREEMPT 222
+#define WLC_GET_BAD_FRAME_PREEMPT 223
+#define WLC_SET_LEAP_LIST 224
+#define WLC_GET_LEAP_LIST 225
+#define WLC_GET_CWMIN 226
+#define WLC_SET_CWMIN 227
+#define WLC_GET_CWMAX 228
+#define WLC_SET_CWMAX 229
+#define WLC_GET_WET 230
+#define WLC_SET_WET 231
+#define WLC_GET_PUB 232
+/* #define WLC_SET_GLACIAL_TIMER 233 */ /* no longer supported */
+/* #define WLC_GET_GLACIAL_TIMER 234 */ /* no longer supported */
+#define WLC_GET_KEY_PRIMARY 235
+#define WLC_SET_KEY_PRIMARY 236
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+
+/* #define WLC_DUMP_RADIOREGS 237 */ /* no longer supported */
+#define WLC_GET_ACI_ARGS 238
+#define WLC_SET_ACI_ARGS 239
+#define WLC_UNSET_CALLBACK 240
+#define WLC_SET_CALLBACK 241
+#define WLC_GET_RADAR 242
+#define WLC_SET_RADAR 243
+#define WLC_SET_SPECT_MANAGMENT 244
+#define WLC_GET_SPECT_MANAGMENT 245
+#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */
+#define WLC_WDS_GET_WPA_SUP 247
+#define WLC_SET_CS_SCAN_TIMER 248
+#define WLC_GET_CS_SCAN_TIMER 249
+#define WLC_MEASURE_REQUEST 250
+#define WLC_INIT 251
+#define WLC_SEND_QUIET 252
+#define WLC_KEEPALIVE 253
+#define WLC_SEND_PWR_CONSTRAINT 254
+#define WLC_UPGRADE_STATUS 255
+#define WLC_CURRENT_PWR 256
+#define WLC_GET_SCAN_PASSIVE_TIME 257
+#define WLC_SET_SCAN_PASSIVE_TIME 258
+#define WLC_LEGACY_LINK_BEHAVIOR 259
+#define WLC_GET_CHANNELS_IN_COUNTRY 260
+#define WLC_GET_COUNTRY_LIST 261
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+#define WLC_GET_VAR 262 /* get value of named variable */
+#define WLC_SET_VAR 263 /* set named variable to value */
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+#define WLC_NVRAM_GET 264 /* deprecated */
+#define WLC_NVRAM_SET 265
+#define WLC_NVRAM_DUMP 266
+#define WLC_REBOOT 267
+#define WLC_SET_WSEC_PMK 268
+#define WLC_GET_AUTH_MODE 269
+#define WLC_SET_AUTH_MODE 270
+#define WLC_GET_WAKEENTRY 271
+#define WLC_SET_WAKEENTRY 272
+#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */
+#define WLC_NVOTPW 274
+#define WLC_OTPW 275
+#define WLC_IOV_BLOCK_GET 276
+#define WLC_IOV_MODULES_GET 277
+#define WLC_SOFT_RESET 278
+#define WLC_GET_ALLOW_MODE 279
+#define WLC_SET_ALLOW_MODE 280
+#define WLC_GET_DESIRED_BSSID 281
+#define WLC_SET_DESIRED_BSSID 282
+#define WLC_DISASSOC_MYAP 283
+#define WLC_GET_NBANDS 284 /* for Dongle EXT_STA support */
+#define WLC_GET_BANDSTATES 285 /* for Dongle EXT_STA support */
+#define WLC_GET_WLC_BSS_INFO 286 /* for Dongle EXT_STA support */
+#define WLC_GET_ASSOC_INFO 287 /* for Dongle EXT_STA support */
+#define WLC_GET_OID_PHY 288 /* for Dongle EXT_STA support */
+#define WLC_SET_OID_PHY 289 /* for Dongle EXT_STA support */
+#define WLC_SET_ASSOC_TIME 290 /* for Dongle EXT_STA support */
+#define WLC_GET_DESIRED_SSID 291 /* for Dongle EXT_STA support */
+#define WLC_GET_CHANSPEC 292 /* for Dongle EXT_STA support */
+#define WLC_GET_ASSOC_STATE 293 /* for Dongle EXT_STA support */
+#define WLC_SET_PHY_STATE 294 /* for Dongle EXT_STA support */
+#define WLC_GET_SCAN_PENDING 295 /* for Dongle EXT_STA support */
+#define WLC_GET_SCANREQ_PENDING 296 /* for Dongle EXT_STA support */
+#define WLC_GET_PREV_ROAM_REASON 297 /* for Dongle EXT_STA support */
+#define WLC_SET_PREV_ROAM_REASON 298 /* for Dongle EXT_STA support */
+#define WLC_GET_BANDSTATES_PI 299 /* for Dongle EXT_STA support */
+#define WLC_GET_PHY_STATE 300 /* for Dongle EXT_STA support */
+#define WLC_GET_BSS_WPA_RSN 301 /* for Dongle EXT_STA support */
+#define WLC_GET_BSS_WPA2_RSN 302 /* for Dongle EXT_STA support */
+#define WLC_GET_BSS_BCN_TS 303 /* for Dongle EXT_STA support */
+#define WLC_GET_INT_DISASSOC 304 /* for Dongle EXT_STA support */
+#define WLC_SET_NUM_PEERS 305 /* for Dongle EXT_STA support */
+#define WLC_GET_NUM_BSS 306 /* for Dongle EXT_STA support */
+#define WLC_PHY_SAMPLE_COLLECT 307 /* phy sample collect mode */
+/* #define WLC_UM_PRIV 308 */ /* Deprecated: usermode driver */
+#define WLC_GET_CMD 309
+/* #define WLC_LAST 310 */ /* Never used - can be reused */
+#define WLC_SET_INTERFERENCE_OVERRIDE_MODE 311 /* set inter mode override */
+#define WLC_GET_INTERFERENCE_OVERRIDE_MODE 312 /* get inter mode override */
+/* #define WLC_GET_WAI_RESTRICT 313 */ /* for WAPI, deprecated use iovar instead */
+/* #define WLC_SET_WAI_RESTRICT 314 */ /* for WAPI, deprecated use iovar instead */
+/* #define WLC_SET_WAI_REKEY 315 */ /* for WAPI, deprecated use iovar instead */
+#define WLC_SET_NAT_CONFIG 316 /* for configuring NAT filter driver */
+#define WLC_GET_NAT_STATE 317
+#define WLC_LAST 318
+
+#ifndef EPICTRL_COOKIE
+#define EPICTRL_COOKIE 0xABADCEDE
+#endif
+
+/* vx wlc ioctl's offset */
+#define CMN_IOCTL_OFF 0x180
+
+/*
+ * custom OID support
+ *
+ * 0xFF - implementation specific OID
+ * 0xE4 - first byte of Broadcom PCI vendor ID
+ * 0x14 - second byte of Broadcom PCI vendor ID
+ * 0xXX - the custom OID number
+ */
+
+/* begin 0x1f values beyond the start of the ET driver range. */
+#define WL_OID_BASE 0xFFE41420
+
+/* NDIS overrides */
+#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE)
+#define OID_WL_GET_FORCELINK (WL_OID_BASE + WLC_GET_FORCELINK)
+#define OID_WL_SET_FORCELINK (WL_OID_BASE + WLC_SET_FORCELINK)
+#define OID_WL_ENCRYPT_STRENGTH (WL_OID_BASE + WLC_ENCRYPT_STRENGTH)
+#define OID_WL_DECRYPT_STATUS (WL_OID_BASE + WLC_DECRYPT_STATUS)
+#define OID_LEGACY_LINK_BEHAVIOR (WL_OID_BASE + WLC_LEGACY_LINK_BEHAVIOR)
+#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM)
+
+/* EXT_STA Dongle suuport */
+#define OID_STA_CHANSPEC (WL_OID_BASE + WLC_GET_CHANSPEC)
+#define OID_STA_NBANDS (WL_OID_BASE + WLC_GET_NBANDS)
+#define OID_STA_GET_PHY (WL_OID_BASE + WLC_GET_OID_PHY)
+#define OID_STA_SET_PHY (WL_OID_BASE + WLC_SET_OID_PHY)
+#define OID_STA_ASSOC_TIME (WL_OID_BASE + WLC_SET_ASSOC_TIME)
+#define OID_STA_DESIRED_SSID (WL_OID_BASE + WLC_GET_DESIRED_SSID)
+#define OID_STA_SET_PHY_STATE (WL_OID_BASE + WLC_SET_PHY_STATE)
+#define OID_STA_SCAN_PENDING (WL_OID_BASE + WLC_GET_SCAN_PENDING)
+#define OID_STA_SCANREQ_PENDING (WL_OID_BASE + WLC_GET_SCANREQ_PENDING)
+#define OID_STA_GET_ROAM_REASON (WL_OID_BASE + WLC_GET_PREV_ROAM_REASON)
+#define OID_STA_SET_ROAM_REASON (WL_OID_BASE + WLC_SET_PREV_ROAM_REASON)
+#define OID_STA_GET_PHY_STATE (WL_OID_BASE + WLC_GET_PHY_STATE)
+#define OID_STA_INT_DISASSOC (WL_OID_BASE + WLC_GET_INT_DISASSOC)
+#define OID_STA_SET_NUM_PEERS (WL_OID_BASE + WLC_SET_NUM_PEERS)
+#define OID_STA_GET_NUM_BSS (WL_OID_BASE + WLC_GET_NUM_BSS)
+
+/* NAT filter driver support */
+#define OID_NAT_SET_CONFIG (WL_OID_BASE + WLC_SET_NAT_CONFIG)
+#define OID_NAT_GET_STATE (WL_OID_BASE + WLC_GET_NAT_STATE)
+
+#define WL_DECRYPT_STATUS_SUCCESS 1
+#define WL_DECRYPT_STATUS_FAILURE 2
+#define WL_DECRYPT_STATUS_UNKNOWN 3
+
+/* allows user-mode app to poll the status of USB image upgrade */
+#define WLC_UPGRADE_SUCCESS 0
+#define WLC_UPGRADE_PENDING 1
+
+#ifdef CONFIG_USBRNDIS_RETAIL
+/* struct passed in for WLC_NDCONFIG_ITEM */
+typedef struct {
+ char *name;
+ void *param;
+} ndconfig_item_t;
+#endif
+
+
+/* WLC_GET_AUTH, WLC_SET_AUTH values */
+#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */
+#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
+#ifdef BCM4330_CHIP
+#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */
+#else
+/* BCM4334(Phoenex branch) value changed to 3 */
+#define WL_AUTH_OPEN_SHARED 3 /* try open, then shared if open failed w/rc 13 */
+#endif
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
+#define WL_RADIO_SW_DISABLE (1<<0)
+#define WL_RADIO_HW_DISABLE (1<<1)
+#define WL_RADIO_MPC_DISABLE (1<<2)
+#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */
+
+#define WL_SPURAVOID_OFF 0
+#define WL_SPURAVOID_ON1 1
+#define WL_SPURAVOID_ON2 2
+
+/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */
+#define WL_TXPWR_OVERRIDE (1U<<31)
+#define WL_TXPWR_NEG (1U<<30)
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+#define WL_PHY_PAVARS_LEN 32 /* Phy type, Band range, chain, a1[0], b0[0], b1[0] ... */
+
+#define WL_PHY_PAVAR_VER 1 /* pavars version */
+
+typedef struct wl_po {
+ uint16 phy_type; /* Phy type */
+ uint16 band;
+ uint16 cckpo;
+ uint32 ofdmpo;
+ uint16 mcspo[8];
+} wl_po_t;
+
+/* a large TX Power as an init value to factor out of MIN() calculations,
+ * keep low enough to fit in an int8, units are .25 dBm
+ */
+#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
+
+/* "diag" iovar argument and error code */
+#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */
+#define WL_DIAG_LOOPBACK 2 /* d11 loopback data test */
+#define WL_DIAG_MEMORY 3 /* d11 memory test */
+#define WL_DIAG_LED 4 /* LED test */
+#define WL_DIAG_REG 5 /* d11/phy register test */
+#define WL_DIAG_SROM 6 /* srom read/crc test */
+#define WL_DIAG_DMA 7 /* DMA test */
+#define WL_DIAG_LOOPBACK_EXT 8 /* enhenced d11 loopback data test */
+
+#define WL_DIAGERR_SUCCESS 0
+#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */
+#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */
+#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */
+#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */
+#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */
+#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */
+#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */
+#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */
+#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */
+#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */
+
+#define WL_DIAGERR_MEMORY_TIMEOUT 11 /* d11 memory test didn't finish in time */
+#define WL_DIAGERR_MEMORY_BADPATTERN 12 /* d11 memory test result in bad pattern */
+
+/* band types */
+#define WLC_BAND_AUTO 0 /* auto-select */
+#define WLC_BAND_5G 1 /* 5 Ghz */
+#define WLC_BAND_2G 2 /* 2.4 Ghz */
+#define WLC_BAND_ALL 3 /* all bands */
+
+/* band range returned by band_range iovar */
+#define WL_CHAN_FREQ_RANGE_2G 0
+#define WL_CHAN_FREQ_RANGE_5GL 1
+#define WL_CHAN_FREQ_RANGE_5GM 2
+#define WL_CHAN_FREQ_RANGE_5GH 3
+
+#define WL_CHAN_FREQ_RANGE_5G_BAND0 1
+#define WL_CHAN_FREQ_RANGE_5G_BAND1 2
+#define WL_CHAN_FREQ_RANGE_5G_BAND2 3
+#define WL_CHAN_FREQ_RANGE_5G_BAND3 4
+
+#define WL_CHAN_FREQ_RANGE_5G_4BAND 5
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* phy types (returned by WLC_GET_PHYTPE) */
+#define WLC_PHY_TYPE_A 0
+#define WLC_PHY_TYPE_B 1
+#define WLC_PHY_TYPE_G 2
+#define WLC_PHY_TYPE_N 4
+#define WLC_PHY_TYPE_LP 5
+#define WLC_PHY_TYPE_SSN 6
+#define WLC_PHY_TYPE_HT 7
+#define WLC_PHY_TYPE_LCN 8
+#define WLC_PHY_TYPE_LCN40 10
+#define WLC_PHY_TYPE_AC 11
+#define WLC_PHY_TYPE_NULL 0xf
+
+/* Values for PM */
+#define PM_OFF 0
+#define PM_MAX 1
+#define PM_FAST 2
+#define PM_FORCE_OFF 3 /* use this bit to force PM off even bt is active */
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+/* MAC list modes */
+#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */
+#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */
+#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */
+
+/*
+ * 54g modes (basic bits may still be overridden)
+ *
+ * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11
+ * Preamble: Long
+ * Shortslot: Off
+ * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
+ * Extended Rateset: 6, 9, 12, 48
+ * Preamble: Long
+ * Shortslot: Auto
+ * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
+ * Extended Rateset: 6b, 9, 12b, 48
+ * Preamble: Short required
+ * Shortslot: Auto
+ * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
+ * Extended Rateset: 6, 9, 12, 48
+ * Preamble: Long
+ * Shortslot: On
+ * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
+ * Preamble: Short required
+ * Shortslot: On and required
+ * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b
+ * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
+ * Preamble: Long
+ * Shortslot: Auto
+ */
+#define GMODE_LEGACY_B 0
+#define GMODE_AUTO 1
+#define GMODE_ONLY 2
+#define GMODE_B_DEFERRED 3
+#define GMODE_PERFORMANCE 4
+#define GMODE_LRS 5
+#define GMODE_MAX 6
+
+/* values for PLCPHdr_override */
+#define WLC_PLCP_AUTO -1
+#define WLC_PLCP_SHORT 0
+#define WLC_PLCP_LONG 1
+
+/* values for g_protection_override and n_protection_override */
+#define WLC_PROTECTION_AUTO -1
+#define WLC_PROTECTION_OFF 0
+#define WLC_PROTECTION_ON 1
+#define WLC_PROTECTION_MMHDR_ONLY 2
+#define WLC_PROTECTION_CTS_ONLY 3
+
+/* values for g_protection_control and n_protection_control */
+#define WLC_PROTECTION_CTL_OFF 0
+#define WLC_PROTECTION_CTL_LOCAL 1
+#define WLC_PROTECTION_CTL_OVERLAP 2
+
+/* values for n_protection */
+#define WLC_N_PROTECTION_OFF 0
+#define WLC_N_PROTECTION_OPTIONAL 1
+#define WLC_N_PROTECTION_20IN40 2
+#define WLC_N_PROTECTION_MIXEDMODE 3
+
+/* values for n_preamble_type */
+#define WLC_N_PREAMBLE_MIXEDMODE 0
+#define WLC_N_PREAMBLE_GF 1
+#define WLC_N_PREAMBLE_GF_BRCM 2
+
+/* values for band specific 40MHz capabilities (deprecated) */
+#define WLC_N_BW_20ALL 0
+#define WLC_N_BW_40ALL 1
+#define WLC_N_BW_20IN2G_40IN5G 2
+
+#define WLC_BW_20MHZ_BIT (1<<0)
+#define WLC_BW_40MHZ_BIT (1<<1)
+#define WLC_BW_80MHZ_BIT (1<<2)
+
+/* Bandwidth capabilities */
+#define WLC_BW_CAP_20MHZ (WLC_BW_20MHZ_BIT)
+#define WLC_BW_CAP_40MHZ (WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT)
+#define WLC_BW_CAP_80MHZ (WLC_BW_80MHZ_BIT|WLC_BW_40MHZ_BIT|WLC_BW_20MHZ_BIT)
+#define WLC_BW_CAP_UNRESTRICTED 0xFF
+
+#define WL_BW_CAP_20MHZ(bw_cap) (((bw_cap) & WLC_BW_20MHZ_BIT) ? TRUE : FALSE)
+#define WL_BW_CAP_40MHZ(bw_cap) (((bw_cap) & WLC_BW_40MHZ_BIT) ? TRUE : FALSE)
+#define WL_BW_CAP_80MHZ(bw_cap) (((bw_cap) & WLC_BW_80MHZ_BIT) ? TRUE : FALSE)
+
+/* values to force tx/rx chain */
+#define WLC_N_TXRX_CHAIN0 0
+#define WLC_N_TXRX_CHAIN1 1
+
+/* bitflags for SGI support (sgi_rx iovar) */
+#define WLC_N_SGI_20 0x01
+#define WLC_N_SGI_40 0x02
+#define WLC_VHT_SGI_80 0x04
+
+/* when sgi_tx==WLC_SGI_ALL, bypass rate selection, enable sgi for all mcs */
+#define WLC_SGI_ALL 0x02
+
+#define LISTEN_INTERVAL 10
+/* interference mitigation options */
+#define INTERFERE_OVRRIDE_OFF -1 /* interference override off */
+#define INTERFERE_NONE 0 /* off */
+#define NON_WLAN 1 /* foreign/non 802.11 interference, no auto detect */
+#define WLAN_MANUAL 2 /* ACI: no auto detection */
+#define WLAN_AUTO 3 /* ACI: auto detect */
+#define WLAN_AUTO_W_NOISE 4 /* ACI: auto - detect and non 802.11 interference */
+#define AUTO_ACTIVE (1 << 7) /* Auto is currently active */
+
+/* AP environment */
+#define AP_ENV_DETECT_NOT_USED 0 /* We aren't using AP environment detection */
+#define AP_ENV_DENSE 1 /* "Corporate" or other AP dense environment */
+#define AP_ENV_SPARSE 2 /* "Home" or other sparse environment */
+#define AP_ENV_INDETERMINATE 3 /* AP environment hasn't been identified */
+
+typedef struct wl_aci_args {
+ int enter_aci_thresh; /* Trigger level to start detecting ACI */
+ int exit_aci_thresh; /* Trigger level to exit ACI mode */
+ int usec_spin; /* microsecs to delay between rssi samples */
+ int glitch_delay; /* interval between ACI scans when glitch count is consistently high */
+ uint16 nphy_adcpwr_enter_thresh; /* ADC power to enter ACI mitigation mode */
+ uint16 nphy_adcpwr_exit_thresh; /* ADC power to exit ACI mitigation mode */
+ uint16 nphy_repeat_ctr; /* Number of tries per channel to compute power */
+ uint16 nphy_num_samples; /* Number of samples to compute power on one channel */
+ uint16 nphy_undetect_window_sz; /* num of undetects to exit ACI Mitigation mode */
+ uint16 nphy_b_energy_lo_aci; /* low ACI power energy threshold for bphy */
+ uint16 nphy_b_energy_md_aci; /* mid ACI power energy threshold for bphy */
+ uint16 nphy_b_energy_hi_aci; /* high ACI power energy threshold for bphy */
+ uint16 nphy_noise_noassoc_glitch_th_up; /* wl interference 4 */
+ uint16 nphy_noise_noassoc_glitch_th_dn;
+ uint16 nphy_noise_assoc_glitch_th_up;
+ uint16 nphy_noise_assoc_glitch_th_dn;
+ uint16 nphy_noise_assoc_aci_glitch_th_up;
+ uint16 nphy_noise_assoc_aci_glitch_th_dn;
+ uint16 nphy_noise_assoc_enter_th;
+ uint16 nphy_noise_noassoc_enter_th;
+ uint16 nphy_noise_assoc_rx_glitch_badplcp_enter_th;
+ uint16 nphy_noise_noassoc_crsidx_incr;
+ uint16 nphy_noise_assoc_crsidx_incr;
+ uint16 nphy_noise_crsidx_decr;
+} wl_aci_args_t;
+
+#define TRIGGER_NOW 0
+#define TRIGGER_CRS 0x01
+#define TRIGGER_CRSDEASSERT 0x02
+#define TRIGGER_GOODFCS 0x04
+#define TRIGGER_BADFCS 0x08
+#define TRIGGER_BADPLCP 0x10
+#define TRIGGER_CRSGLITCH 0x20
+#define WL_ACI_ARGS_LEGACY_LENGTH 16 /* bytes of pre NPHY aci args */
+#define WL_SAMPLECOLLECT_T_VERSION 2 /* version of wl_samplecollect_args_t struct */
+typedef struct wl_samplecollect_args {
+ /* version 0 fields */
+ uint8 coll_us;
+ int cores;
+ /* add'l version 1 fields */
+ uint16 version; /* see definition of WL_SAMPLECOLLECT_T_VERSION */
+ uint16 length; /* length of entire structure */
+ int8 trigger;
+ uint16 timeout;
+ uint16 mode;
+ uint32 pre_dur;
+ uint32 post_dur;
+ uint8 gpio_sel;
+ bool downsamp;
+ bool be_deaf;
+ bool agc; /* loop from init gain and going down */
+ bool filter; /* override high pass corners to lowest */
+ /* add'l version 2 fields */
+ uint8 trigger_state;
+ uint8 module_sel1;
+ uint8 module_sel2;
+ uint16 nsamps;
+} wl_samplecollect_args_t;
+
+#define WL_SAMPLEDATA_HEADER_TYPE 1
+#define WL_SAMPLEDATA_HEADER_SIZE 80 /* sample collect header size (bytes) */
+#define WL_SAMPLEDATA_TYPE 2
+#define WL_SAMPLEDATA_SEQ 0xff /* sequence # */
+#define WL_SAMPLEDATA_MORE_DATA 0x100 /* more data mask */
+#define WL_SAMPLEDATA_T_VERSION 1 /* version of wl_samplecollect_args_t struct */
+/* version for unpacked sample data, int16 {(I,Q),Core(0..N)} */
+#define WL_SAMPLEDATA_T_VERSION_SPEC_AN 2
+
+typedef struct wl_sampledata {
+ uint16 version; /* structure version */
+ uint16 size; /* size of structure */
+ uint16 tag; /* Header/Data */
+ uint16 length; /* data length */
+ uint32 flag; /* bit def */
+} wl_sampledata_t;
+
+/* wl_radar_args_t */
+typedef struct {
+ int npulses; /* required number of pulses at n * t_int */
+ int ncontig; /* required number of pulses at t_int */
+ int min_pw; /* minimum pulse width (20 MHz clocks) */
+ int max_pw; /* maximum pulse width (20 MHz clocks) */
+ uint16 thresh0; /* Radar detection, thresh 0 */
+ uint16 thresh1; /* Radar detection, thresh 1 */
+ uint16 blank; /* Radar detection, blank control */
+ uint16 fmdemodcfg; /* Radar detection, fmdemod config */
+ int npulses_lp; /* Radar detection, minimum long pulses */
+ int min_pw_lp; /* Minimum pulsewidth for long pulses */
+ int max_pw_lp; /* Maximum pulsewidth for long pulses */
+ int min_fm_lp; /* Minimum fm for long pulses */
+ int max_span_lp; /* Maximum deltat for long pulses */
+ int min_deltat; /* Minimum spacing between pulses */
+ int max_deltat; /* Maximum spacing between pulses */
+ uint16 autocorr; /* Radar detection, autocorr on or off */
+ uint16 st_level_time; /* Radar detection, start_timing level */
+ uint16 t2_min; /* minimum clocks needed to remain in state 2 */
+ uint32 version; /* version */
+ uint32 fra_pulse_err; /* sample error margin for detecting French radar pulsed */
+ int npulses_fra; /* Radar detection, minimum French pulses set */
+ int npulses_stg2; /* Radar detection, minimum staggered-2 pulses set */
+ int npulses_stg3; /* Radar detection, minimum staggered-3 pulses set */
+ uint16 percal_mask; /* defines which period cal is masked from radar detection */
+ int quant; /* quantization resolution to pulse positions */
+ uint32 min_burst_intv_lp; /* minimum burst to burst interval for bin3 radar */
+ uint32 max_burst_intv_lp; /* maximum burst to burst interval for bin3 radar */
+ int nskip_rst_lp; /* number of skipped pulses before resetting lp buffer */
+ int max_pw_tol; /* maximum tollerance allowed in detected pulse width for radar detection */
+ uint16 feature_mask; /* 16-bit mask to specify enabled features */
+} wl_radar_args_t;
+
+#define WL_RADAR_ARGS_VERSION 2
+
+typedef struct {
+ uint32 version; /* version */
+ uint16 thresh0_20_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 20MHz */
+ uint16 thresh1_20_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 20MHz */
+ uint16 thresh0_40_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 40MHz */
+ uint16 thresh1_40_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 40MHz */
+ uint16 thresh0_80_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 80MHz */
+ uint16 thresh1_80_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 80MHz */
+ uint16 thresh0_160_lo; /* Radar detection, thresh 0 (range 5250-5350MHz) for BW 160MHz */
+ uint16 thresh1_160_lo; /* Radar detection, thresh 1 (range 5250-5350MHz) for BW 160MHz */
+ uint16 thresh0_20_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 20MHz */
+ uint16 thresh1_20_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 20MHz */
+ uint16 thresh0_40_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 40MHz */
+ uint16 thresh1_40_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 40MHz */
+ uint16 thresh0_80_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 80MHz */
+ uint16 thresh1_80_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 80MHz */
+ uint16 thresh0_160_hi; /* Radar detection, thresh 0 (range 5470-5725MHz) for BW 160MHz */
+ uint16 thresh1_160_hi; /* Radar detection, thresh 1 (range 5470-5725MHz) for BW 160MHz */
+} wl_radar_thr_t;
+
+#define WL_RADAR_THR_VERSION 2
+#define WL_THRESHOLD_LO_BAND 70 /* range from 5250MHz - 5350MHz */
+
+/* radar iovar SET defines */
+#define WL_RADAR_DETECTOR_OFF 0 /* radar detector off */
+#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */
+#define WL_RADAR_SIMULATED 2 /* force radar detector to declare
+ * detection once
+ */
+#define WL_RSSI_ANT_VERSION 1 /* current version of wl_rssi_ant_t */
+#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */
+#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */
+#define WL_ANT_IDX_1 0 /* antenna index 1 */
+#define WL_ANT_IDX_2 1 /* antenna index 2 */
+
+#ifndef WL_RSSI_ANT_MAX
+#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */
+#elif WL_RSSI_ANT_MAX != 4
+#error "WL_RSSI_ANT_MAX does not match"
+#endif
+
+/* RSSI per antenna */
+typedef struct {
+ uint32 version; /* version field */
+ uint32 count; /* number of valid antenna rssi */
+ int8 rssi_ant[WL_RSSI_ANT_MAX]; /* rssi per antenna */
+} wl_rssi_ant_t;
+
+/* dfs_status iovar-related defines */
+
+/* cac - channel availability check,
+ * ism - in-service monitoring
+ * csa - channel switching announcement
+ */
+
+/* cac state values */
+#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */
+#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */
+#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */
+#define WL_DFS_CACSTATE_CSA 3 /* csa */
+#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */
+#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */
+#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */
+#define WL_DFS_CACSTATES 7 /* this many states exist */
+
+/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */
+typedef struct {
+ uint state; /* noted by WL_DFS_CACSTATE_XX. */
+ uint duration; /* time spent in ms in state. */
+ /* as dfs enters ISM state, it removes the operational channel from quiet channel
+ * list and notes the channel in channel_cleared. set to 0 if no channel is cleared
+ */
+ chanspec_t chanspec_cleared;
+ /* chanspec cleared used to be a uint, add another to uint16 to maintain size */
+ uint16 pad;
+} wl_dfs_status_t;
+
+#define NUM_PWRCTRL_RATES 12
+
+typedef struct {
+ uint8 txpwr_band_max[NUM_PWRCTRL_RATES]; /* User set target */
+ uint8 txpwr_limit[NUM_PWRCTRL_RATES]; /* reg and local power limit */
+ uint8 txpwr_local_max; /* local max according to the AP */
+ uint8 txpwr_local_constraint; /* local constraint according to the AP */
+ uint8 txpwr_chan_reg_max; /* Regulatory max for this channel */
+ uint8 txpwr_target[2][NUM_PWRCTRL_RATES]; /* Latest target for 2.4 and 5 Ghz */
+ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
+ uint8 txpwr_opo[NUM_PWRCTRL_RATES]; /* On G phy, OFDM power offset */
+ uint8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; /* Max CCK power for this band (SROM) */
+ uint8 txpwr_bphy_ofdm_max; /* Max OFDM power for this band (SROM) */
+ uint8 txpwr_aphy_max[NUM_PWRCTRL_RATES]; /* Max power for A band (SROM) */
+ int8 txpwr_antgain[2]; /* Ant gain for each band - from SROM */
+ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
+} tx_power_legacy_t;
+
+#define WL_TX_POWER_RATES_LEGACY 45
+#define WL_TX_POWER_MCS20_FIRST 12
+#define WL_TX_POWER_MCS20_NUM 16
+#define WL_TX_POWER_MCS40_FIRST 28
+#define WL_TX_POWER_MCS40_NUM 17
+
+typedef struct {
+ uint32 flags;
+ chanspec_t chanspec; /* txpwr report for this channel */
+ chanspec_t local_chanspec; /* channel on which we are associated */
+ uint8 local_max; /* local max according to the AP */
+ uint8 local_constraint; /* local constraint according to the AP */
+ int8 antgain[2]; /* Ant gain for each band - from SROM */
+ uint8 rf_cores; /* count of RF Cores being reported */
+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF
+ * chain without adjustment
+ */
+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */
+ uint8 user_limit[WL_TX_POWER_RATES_LEGACY]; /* User limit */
+ uint8 reg_limit[WL_TX_POWER_RATES_LEGACY]; /* Regulatory power limit */
+ uint8 board_limit[WL_TX_POWER_RATES_LEGACY]; /* Max power board can support (SROM) */
+ uint8 target[WL_TX_POWER_RATES_LEGACY]; /* Latest target power */
+} tx_power_legacy2_t;
+
+/* TX Power index defines */
+#define WL_NUM_RATES_CCK 4 /* 1, 2, 5.5, 11 Mbps */
+#define WL_NUM_RATES_OFDM 8 /* 6, 9, 12, 18, 24, 36, 48, 54 Mbps SISO/CDD */
+#define WL_NUM_RATES_MCS_1STREAM 8 /* MCS 0-7 1-stream rates - SISO/CDD/STBC/MCS */
+#define WL_NUM_RATES_EXTRA_VHT 2 /* Additional VHT 11AC rates */
+#define WL_NUM_RATES_VHT 10
+#define WL_NUM_RATES_MCS32 1
+
+#define WLC_NUM_RATES_CCK WL_NUM_RATES_CCK
+#define WLC_NUM_RATES_OFDM WL_NUM_RATES_OFDM
+#define WLC_NUM_RATES_MCS_1_STREAM WL_NUM_RATES_MCS_1STREAM
+#define WLC_NUM_RATES_MCS_2_STREAM WL_NUM_RATES_MCS_1STREAM
+#define WLC_NUM_RATES_MCS32 WL_NUM_RATES_MCS32
+#define WL_TX_POWER_CCK_NUM WL_NUM_RATES_CCK
+#define WL_TX_POWER_OFDM_NUM WL_NUM_RATES_OFDM
+#define WL_TX_POWER_MCS_1_STREAM_NUM WL_NUM_RATES_MCS_1STREAM
+#define WL_TX_POWER_MCS_2_STREAM_NUM WL_NUM_RATES_MCS_1STREAM
+#define WL_TX_POWER_MCS_32_NUM WL_NUM_RATES_MCS32
+
+#define WL_NUM_2x2_ELEMENTS 4
+#define WL_NUM_3x3_ELEMENTS 6
+
+typedef struct txppr {
+ /* start of 20MHz tx power limits */
+ uint8 b20_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */
+ uint8 b20_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */
+
+ uint8 b20_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b20_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */
+ uint8 b20_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b20_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */
+
+ uint8 b20_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b20_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */
+ uint8 b20_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b20_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */
+ uint8 b20_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */
+
+ uint8 b20_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */
+ uint8 b20_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */
+ uint8 b20_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */
+ uint8 b20_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */
+ uint8 b20_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */
+ uint8 b20_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */
+ uint8 b20_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */
+ uint8 b20_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */
+
+ /* start of 40MHz tx power limits */
+ uint8 b40_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */
+ uint8 b40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */
+
+ uint8 b40_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */
+ uint8 b40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */
+
+ uint8 b40_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */
+ uint8 b40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */
+ uint8 b40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */
+
+ uint8 b40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */
+ uint8 b40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */
+ uint8 b40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */
+ uint8 b40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */
+ uint8 b40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */
+ uint8 b40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */
+ uint8 b40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */
+ uint8 b40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */
+
+ /* start of 20in40MHz tx power limits */
+ uint8 b20in40_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20in40_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */
+ uint8 b20in40_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */
+
+ uint8 b20in40_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20in40_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b20in40_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */
+ uint8 b20in40_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b20in40_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */
+
+ uint8 b20in40_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20in40_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* 20 in 40 MHz Legacy OFDM CDD */
+ uint8 b20in40_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */
+ uint8 b20in40_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b20in40_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */
+ uint8 b20in40_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */
+
+ uint8 b20in40_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */
+ uint8 b20in40_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */
+ uint8 b20in40_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */
+ uint8 b20in40_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */
+ uint8 b20in40_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */
+ uint8 b20in40_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */
+ uint8 b20in40_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */
+ uint8 b20in40_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */
+
+ /* start of 80MHz tx power limits */
+ uint8 b80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */
+ uint8 b80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */
+
+ uint8 b80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */
+ uint8 b80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */
+
+ uint8 b80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */
+ uint8 b80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */
+ uint8 b80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */
+
+ uint8 b80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */
+ uint8 b80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */
+ uint8 b80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */
+ uint8 b80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */
+ uint8 b80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */
+ uint8 b80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */
+ uint8 b80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */
+ uint8 b80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */
+
+ /* start of 20in80MHz tx power limits */
+ uint8 b20in80_1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */
+ uint8 b20in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */
+
+ uint8 b20in80_1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b20in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */
+ uint8 b20in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b20in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */
+
+ uint8 b20in80_1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b20in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b20in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */
+ uint8 b20in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b20in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */
+ uint8 b20in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */
+
+ uint8 b20in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */
+ uint8 b20in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */
+ uint8 b20in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */
+ uint8 b20in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */
+ uint8 b20in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */
+ uint8 b20in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */
+ uint8 b20in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */
+ uint8 b20in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */
+
+ /* start of 40in80MHz tx power limits */
+ uint8 b40in80_dummy1x1dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b40in80_1x1ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM transmission */
+ uint8 b40in80_1x1mcs0[WL_NUM_RATES_MCS_1STREAM]; /* SISO MCS 0-7 */
+
+ uint8 b40in80_dummy1x2dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b40in80_1x2cdd_ofdm[WL_NUM_RATES_OFDM]; /* Legacy OFDM CDD transmission */
+ uint8 b40in80_1x2cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* CDD MCS 0-7 */
+ uint8 b40in80_2x2stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b40in80_2x2sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* MCS 8-15 */
+
+ uint8 b40in80_dummy1x3dsss[WL_NUM_RATES_CCK]; /* Legacy CCK/DSSS */
+ uint8 b40in80_1x3cdd_ofdm[WL_NUM_RATES_OFDM]; /* MHz Legacy OFDM CDD */
+ uint8 b40in80_1x3cdd_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* 1 Nsts to 3 Tx Chain */
+ uint8 b40in80_2x3stbc_mcs0[WL_NUM_RATES_MCS_1STREAM]; /* STBC MCS 0-7 */
+ uint8 b40in80_2x3sdm_mcs8[WL_NUM_RATES_MCS_1STREAM]; /* 2 Nsts to 3 Tx Chain */
+ uint8 b40in80_3x3sdm_mcs16[WL_NUM_RATES_MCS_1STREAM]; /* 3 Nsts to 3 Tx Chain */
+
+ uint8 b40in80_1x1vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1 */
+ uint8 b40in80_1x2cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD1 */
+ uint8 b40in80_2x2stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC */
+ uint8 b40in80_2x2sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2 */
+ uint8 b40in80_1x3cdd_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_CDD2 */
+ uint8 b40in80_2x3stbc_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS1_STBC_SPEXP1 */
+ uint8 b40in80_2x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS2_SPEXP1 */
+ uint8 b40in80_3x3sdm_vht[WL_NUM_RATES_EXTRA_VHT]; /* VHT8_9SS3 */
+
+ uint8 mcs32; /* C_CHECK - THIS NEEDS TO BE REMOVED THROUGHOUT THE CODE */
+} txppr_t;
+
+/* 20MHz */
+#define WL_TX_POWER_CCK_FIRST OFFSETOF(txppr_t, b20_1x1dsss)
+#define WL_TX_POWER_OFDM20_FIRST OFFSETOF(txppr_t, b20_1x1ofdm)
+#define WL_TX_POWER_MCS20_SISO_FIRST OFFSETOF(txppr_t, b20_1x1mcs0)
+#define WL_TX_POWER_20_S1x1_FIRST OFFSETOF(txppr_t, b20_1x1mcs0)
+
+#define WL_TX_POWER_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2dsss)
+#define WL_TX_POWER_OFDM20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_ofdm)
+#define WL_TX_POWER_MCS20_CDD_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0)
+#define WL_TX_POWER_20_S1x2_FIRST OFFSETOF(txppr_t, b20_1x2cdd_mcs0)
+#define WL_TX_POWER_MCS20_STBC_FIRST OFFSETOF(txppr_t, b20_2x2stbc_mcs0)
+#define WL_TX_POWER_MCS20_SDM_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8)
+#define WL_TX_POWER_20_S2x2_FIRST OFFSETOF(txppr_t, b20_2x2sdm_mcs8)
+
+#define WL_TX_POWER_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3dsss)
+#define WL_TX_POWER_OFDM20_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_ofdm)
+#define WL_TX_POWER_20_S1x3_FIRST OFFSETOF(txppr_t, b20_1x3cdd_mcs0)
+#define WL_TX_POWER_20_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3stbc_mcs0)
+#define WL_TX_POWER_20_S2x3_FIRST OFFSETOF(txppr_t, b20_2x3sdm_mcs8)
+#define WL_TX_POWER_20_S3x3_FIRST OFFSETOF(txppr_t, b20_3x3sdm_mcs16)
+
+#define WL_TX_POWER_20_S1X1_VHT OFFSETOF(txppr_t, b20_1x1vht)
+#define WL_TX_POWER_20_S1X2_CDD_VHT OFFSETOF(txppr_t, b20_1x2cdd_vht)
+#define WL_TX_POWER_20_S2X2_STBC_VHT OFFSETOF(txppr_t, b20_2x2stbc_vht)
+#define WL_TX_POWER_20_S2X2_VHT OFFSETOF(txppr_t, b20_2x2sdm_vht)
+#define WL_TX_POWER_20_S1X3_CDD_VHT OFFSETOF(txppr_t, b20_1x3cdd_vht)
+#define WL_TX_POWER_20_S2X3_STBC_VHT OFFSETOF(txppr_t, b20_2x3stbc_vht)
+#define WL_TX_POWER_20_S2X3_VHT OFFSETOF(txppr_t, b20_2x3sdm_vht)
+#define WL_TX_POWER_20_S3X3_VHT OFFSETOF(txppr_t, b20_3x3sdm_vht)
+
+/* 40MHz */
+#define WL_TX_POWER_40_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40_dummy1x1dsss)
+#define WL_TX_POWER_OFDM40_FIRST OFFSETOF(txppr_t, b40_1x1ofdm)
+#define WL_TX_POWER_MCS40_SISO_FIRST OFFSETOF(txppr_t, b40_1x1mcs0)
+#define WL_TX_POWER_40_S1x1_FIRST OFFSETOF(txppr_t, b40_1x1mcs0)
+
+#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40_dummy1x2dsss)
+#define WL_TX_POWER_OFDM40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_ofdm)
+#define WL_TX_POWER_MCS40_CDD_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0)
+#define WL_TX_POWER_40_S1x2_FIRST OFFSETOF(txppr_t, b40_1x2cdd_mcs0)
+#define WL_TX_POWER_MCS40_STBC_FIRST OFFSETOF(txppr_t, b40_2x2stbc_mcs0)
+#define WL_TX_POWER_MCS40_SDM_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8)
+#define WL_TX_POWER_40_S2x2_FIRST OFFSETOF(txppr_t, b40_2x2sdm_mcs8)
+
+#define WL_TX_POWER_40_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_dummy1x3dsss)
+#define WL_TX_POWER_OFDM40_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_ofdm)
+#define WL_TX_POWER_40_S1x3_FIRST OFFSETOF(txppr_t, b40_1x3cdd_mcs0)
+#define WL_TX_POWER_40_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3stbc_mcs0)
+#define WL_TX_POWER_40_S2x3_FIRST OFFSETOF(txppr_t, b40_2x3sdm_mcs8)
+#define WL_TX_POWER_40_S3x3_FIRST OFFSETOF(txppr_t, b40_3x3sdm_mcs16)
+
+#define WL_TX_POWER_40_S1X1_VHT OFFSETOF(txppr_t, b40_1x1vht)
+#define WL_TX_POWER_40_S1X2_CDD_VHT OFFSETOF(txppr_t, b40_1x2cdd_vht)
+#define WL_TX_POWER_40_S2X2_STBC_VHT OFFSETOF(txppr_t, b40_2x2stbc_vht)
+#define WL_TX_POWER_40_S2X2_VHT OFFSETOF(txppr_t, b40_2x2sdm_vht)
+#define WL_TX_POWER_40_S1X3_CDD_VHT OFFSETOF(txppr_t, b40_1x3cdd_vht)
+#define WL_TX_POWER_40_S2X3_STBC_VHT OFFSETOF(txppr_t, b40_2x3stbc_vht)
+#define WL_TX_POWER_40_S2X3_VHT OFFSETOF(txppr_t, b40_2x3sdm_vht)
+#define WL_TX_POWER_40_S3X3_VHT OFFSETOF(txppr_t, b40_3x3sdm_vht)
+
+/* 20 in 40MHz */
+#define WL_TX_POWER_20UL_CCK_FIRST OFFSETOF(txppr_t, b20in40_1x1dsss)
+#define WL_TX_POWER_20UL_OFDM_FIRST OFFSETOF(txppr_t, b20in40_1x1ofdm)
+#define WL_TX_POWER_20UL_S1x1_FIRST OFFSETOF(txppr_t, b20in40_1x1mcs0)
+
+#define WL_TX_POWER_CCK_20U_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2dsss)
+#define WL_TX_POWER_20UL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_ofdm)
+#define WL_TX_POWER_20UL_S1x2_FIRST OFFSETOF(txppr_t, b20in40_1x2cdd_mcs0)
+#define WL_TX_POWER_20UL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2stbc_mcs0)
+#define WL_TX_POWER_20UL_S2x2_FIRST OFFSETOF(txppr_t, b20in40_2x2sdm_mcs8)
+
+#define WL_TX_POWER_CCK_20U_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3dsss)
+#define WL_TX_POWER_20UL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_ofdm)
+#define WL_TX_POWER_20UL_S1x3_FIRST OFFSETOF(txppr_t, b20in40_1x3cdd_mcs0)
+#define WL_TX_POWER_20UL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3stbc_mcs0)
+#define WL_TX_POWER_20UL_S2x3_FIRST OFFSETOF(txppr_t, b20in40_2x3sdm_mcs8)
+#define WL_TX_POWER_20UL_S3x3_FIRST OFFSETOF(txppr_t, b20in40_3x3sdm_mcs16)
+
+#define WL_TX_POWER_20UL_S1X1_VHT OFFSETOF(txppr_t, b20in40_1x1vht)
+#define WL_TX_POWER_20UL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in40_1x2cdd_vht)
+#define WL_TX_POWER_20UL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in40_2x2stbc_vht)
+#define WL_TX_POWER_20UL_S2X2_VHT OFFSETOF(txppr_t, b20in40_2x2sdm_vht)
+#define WL_TX_POWER_20UL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in40_1x3cdd_vht)
+#define WL_TX_POWER_20UL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in40_2x3stbc_vht)
+#define WL_TX_POWER_20UL_S2X3_VHT OFFSETOF(txppr_t, b20in40_2x3sdm_vht)
+#define WL_TX_POWER_20UL_S3X3_VHT OFFSETOF(txppr_t, b20in40_3x3sdm_vht)
+
+/* 80MHz */
+#define WL_TX_POWER_80_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b80_dummy1x1dsss)
+#define WL_TX_POWER_OFDM80_FIRST OFFSETOF(txppr_t, b80_1x1ofdm)
+#define WL_TX_POWER_MCS80_SISO_FIRST OFFSETOF(txppr_t, b80_1x1mcs0)
+#define WL_TX_POWER_80_S1x1_FIRST OFFSETOF(txppr_t, b80_1x1mcs0)
+
+#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x2_FIRST OFFSETOF(txppr_t, b80_dummy1x2dsss)
+#define WL_TX_POWER_OFDM80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_ofdm)
+#define WL_TX_POWER_MCS80_CDD_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0)
+#define WL_TX_POWER_80_S1x2_FIRST OFFSETOF(txppr_t, b80_1x2cdd_mcs0)
+#define WL_TX_POWER_MCS80_STBC_FIRST OFFSETOF(txppr_t, b80_2x2stbc_mcs0)
+#define WL_TX_POWER_MCS80_SDM_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8)
+#define WL_TX_POWER_80_S2x2_FIRST OFFSETOF(txppr_t, b80_2x2sdm_mcs8)
+
+#define WL_TX_POWER_80_DUMMY_CCK_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_dummy1x3dsss)
+#define WL_TX_POWER_OFDM80_CDD_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_ofdm)
+#define WL_TX_POWER_80_S1x3_FIRST OFFSETOF(txppr_t, b80_1x3cdd_mcs0)
+#define WL_TX_POWER_80_STBC_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3stbc_mcs0)
+#define WL_TX_POWER_80_S2x3_FIRST OFFSETOF(txppr_t, b80_2x3sdm_mcs8)
+#define WL_TX_POWER_80_S3x3_FIRST OFFSETOF(txppr_t, b80_3x3sdm_mcs16)
+
+#define WL_TX_POWER_80_S1X1_VHT OFFSETOF(txppr_t, b80_1x1vht)
+#define WL_TX_POWER_80_S1X2_CDD_VHT OFFSETOF(txppr_t, b80_1x2cdd_vht)
+#define WL_TX_POWER_80_S2X2_STBC_VHT OFFSETOF(txppr_t, b80_2x2stbc_vht)
+#define WL_TX_POWER_80_S2X2_VHT OFFSETOF(txppr_t, b80_2x2sdm_vht)
+#define WL_TX_POWER_80_S1X3_CDD_VHT OFFSETOF(txppr_t, b80_1x3cdd_vht)
+#define WL_TX_POWER_80_S2X3_STBC_VHT OFFSETOF(txppr_t, b80_2x3stbc_vht)
+#define WL_TX_POWER_80_S2X3_VHT OFFSETOF(txppr_t, b80_2x3sdm_vht)
+#define WL_TX_POWER_80_S3X3_VHT OFFSETOF(txppr_t, b80_3x3sdm_vht)
+
+/* 20 in 80MHz */
+#define WL_TX_POWER_20UUL_CCK_FIRST OFFSETOF(txppr_t, b20in80_1x1dsss)
+#define WL_TX_POWER_20UUL_OFDM_FIRST OFFSETOF(txppr_t, b20in80_1x1ofdm)
+#define WL_TX_POWER_20UUL_S1x1_FIRST OFFSETOF(txppr_t, b20in80_1x1mcs0)
+
+#define WL_TX_POWER_CCK_20UU_CDD_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2dsss)
+#define WL_TX_POWER_20UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_ofdm)
+#define WL_TX_POWER_20UUL_S1x2_FIRST OFFSETOF(txppr_t, b20in80_1x2cdd_mcs0)
+#define WL_TX_POWER_20UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2stbc_mcs0)
+#define WL_TX_POWER_20UUL_S2x2_FIRST OFFSETOF(txppr_t, b20in80_2x2sdm_mcs8)
+
+#define WL_TX_POWER_CCK_20UU_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3dsss)
+#define WL_TX_POWER_20UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_ofdm)
+#define WL_TX_POWER_20UUL_S1x3_FIRST OFFSETOF(txppr_t, b20in80_1x3cdd_mcs0)
+#define WL_TX_POWER_20UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3stbc_mcs0)
+#define WL_TX_POWER_20UUL_S2x3_FIRST OFFSETOF(txppr_t, b20in80_2x3sdm_mcs8)
+#define WL_TX_POWER_20UUL_S3x3_FIRST OFFSETOF(txppr_t, b20in80_3x3sdm_mcs16)
+
+#define WL_TX_POWER_20UUL_S1X1_VHT OFFSETOF(txppr_t, b20in80_1x1vht)
+#define WL_TX_POWER_20UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b20in80_1x2cdd_vht)
+#define WL_TX_POWER_20UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b20in80_2x2stbc_vht)
+#define WL_TX_POWER_20UUL_S2X2_VHT OFFSETOF(txppr_t, b20in80_2x2sdm_vht)
+#define WL_TX_POWER_20UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b20in80_1x3cdd_vht)
+#define WL_TX_POWER_20UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b20in80_2x3stbc_vht)
+#define WL_TX_POWER_20UUL_S2X3_VHT OFFSETOF(txppr_t, b20in80_2x3sdm_vht)
+#define WL_TX_POWER_20UUL_S3X3_VHT OFFSETOF(txppr_t, b20in80_3x3sdm_vht)
+
+/* 40 in 80MHz */
+#define WL_TX_POWER_40UUL_DUMMY_CCK_FIRST OFFSETOF(txppr_t, b40in80_dummy1x1dsss)
+#define WL_TX_POWER_40UUL_OFDM_FIRST OFFSETOF(txppr_t, b40in80_1x1ofdm)
+#define WL_TX_POWER_40UUL_S1x1_FIRST OFFSETOF(txppr_t, b40in80_1x1mcs0)
+
+#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x2_FIRST OFFSETOF(txppr_t, b40in80_dummy1x2dsss)
+#define WL_TX_POWER_40UUL_OFDM_CDD_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_ofdm)
+#define WL_TX_POWER_40UUL_S1x2_FIRST OFFSETOF(txppr_t, b40in80_1x2cdd_mcs0)
+#define WL_TX_POWER_40UUL_STBC_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2stbc_mcs0)
+#define WL_TX_POWER_40UUL_S2x2_FIRST OFFSETOF(txppr_t, b40in80_2x2sdm_mcs8)
+
+#define WL_TX_POWER_CCK_40UU_DUMMY_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_dummy1x3dsss)
+#define WL_TX_POWER_40UUL_OFDM_CDD_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_ofdm)
+#define WL_TX_POWER_40UUL_S1x3_FIRST OFFSETOF(txppr_t, b40in80_1x3cdd_mcs0)
+#define WL_TX_POWER_40UUL_STBC_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3stbc_mcs0)
+#define WL_TX_POWER_40UUL_S2x3_FIRST OFFSETOF(txppr_t, b40in80_2x3sdm_mcs8)
+#define WL_TX_POWER_40UUL_S3x3_FIRST OFFSETOF(txppr_t, b40in80_3x3sdm_mcs16)
+
+#define WL_TX_POWER_40UUL_S1X1_VHT OFFSETOF(txppr_t, b40in80_1x1vht)
+#define WL_TX_POWER_40UUL_S1X2_CDD_VHT OFFSETOF(txppr_t, b40in80_1x2cdd_vht)
+#define WL_TX_POWER_40UUL_S2X2_STBC_VHT OFFSETOF(txppr_t, b40in80_2x2stbc_vht)
+#define WL_TX_POWER_40UUL_S2X2_VHT OFFSETOF(txppr_t, b40in80_2x2sdm_vht)
+#define WL_TX_POWER_40UUL_S1X3_CDD_VHT OFFSETOF(txppr_t, b40in80_1x3cdd_vht)
+#define WL_TX_POWER_40UUL_S2X3_STBC_VHT OFFSETOF(txppr_t, b40in80_2x3stbc_vht)
+#define WL_TX_POWER_40UUL_S2X3_VHT OFFSETOF(txppr_t, b40in80_2x3sdm_vht)
+#define WL_TX_POWER_40UUL_S3X3_VHT OFFSETOF(txppr_t, b40in80_3x3sdm_vht)
+
+#define WL_TX_POWER_MCS_32 OFFSETOF(txppr_t, mcs32) /* C_CHECK remove later */
+
+#define WL_TX_POWER_RATES sizeof(struct txppr)
+
+/* sslpnphy specifics */
+#define WL_TX_POWER_MCS20_SISO_FIRST_SSN WL_TX_POWER_MCS20_SISO_FIRST
+#define WL_TX_POWER_MCS40_SISO_FIRST_SSN WL_TX_POWER_MCS40_SISO_FIRST
+
+/* tx_power_t.flags bits */
+#define WL_TX_POWER_F_ENABLED 1
+#define WL_TX_POWER_F_HW 2
+#define WL_TX_POWER_F_MIMO 4
+#define WL_TX_POWER_F_SISO 8
+#define WL_TX_POWER_F_HT 0x10
+
+typedef struct {
+ uint16 ver; /* version of this struct */
+ uint16 len; /* length in bytes of this structure */
+ uint32 flags;
+ chanspec_t chanspec; /* txpwr report for this channel */
+ chanspec_t local_chanspec; /* channel on which we are associated */
+ uint8 ppr[WL_TX_POWER_RATES]; /* Latest target power */
+} wl_txppr_t;
+
+#define WL_TXPPR_VERSION 0
+#define WL_TXPPR_LENGTH (sizeof(wl_txppr_t))
+#define TX_POWER_T_VERSION 43
+
+/* Defines used with channel_bandwidth for curpower */
+#define WL_BW_20MHZ 0
+#define WL_BW_40MHZ 1
+#define WL_BW_80MHZ 2
+
+/* tx_power_t.flags bits */
+#ifdef PPR_API
+#define WL_TX_POWER2_F_ENABLED 1
+#define WL_TX_POWER2_F_HW 2
+#define WL_TX_POWER2_F_MIMO 4
+#define WL_TX_POWER2_F_SISO 8
+#define WL_TX_POWER2_F_HT 0x10
+#else
+#define WL_TX_POWER_F_ENABLED 1
+#define WL_TX_POWER_F_HW 2
+#define WL_TX_POWER_F_MIMO 4
+#define WL_TX_POWER_F_SISO 8
+#define WL_TX_POWER_F_HT 0x10
+#endif
+typedef struct {
+ uint32 flags;
+ chanspec_t chanspec; /* txpwr report for this channel */
+ chanspec_t local_chanspec; /* channel on which we are associated */
+ uint8 local_max; /* local max according to the AP */
+ uint8 local_constraint; /* local constraint according to the AP */
+ int8 antgain[2]; /* Ant gain for each band - from SROM */
+ uint8 rf_cores; /* count of RF Cores being reported */
+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
+ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain
+ * without adjustment
+ */
+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */
+ uint8 tx_power_max[4]; /* Maximum target power among all rates */
+ uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */
+ uint8 user_limit[WL_TX_POWER_RATES]; /* User limit */
+ int8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */
+ int8 target[WL_TX_POWER_RATES]; /* Latest target power */
+ int8 clm_limits[WL_NUMRATES]; /* regulatory limits - 20, 40 or 80MHz */
+ int8 clm_limits_subchan1[WL_NUMRATES]; /* regulatory limits - 20in40 or 40in80 */
+ int8 clm_limits_subchan2[WL_NUMRATES]; /* regulatory limits - 20in80MHz */
+ int8 sar; /* SAR limit for display by wl executable */
+ int8 channel_bandwidth; /* 20, 40 or 80 MHz bandwidth? */
+ uint8 version; /* Version of the data format wlu <--> driver */
+ uint8 display_core; /* Displayed curpower core */
+#ifdef PPR_API
+} tx_power_new_t;
+#else
+} tx_power_t;
+#endif
+
+typedef struct tx_inst_power {
+ uint8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
+ uint8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
+} tx_inst_power_t;
+
+
+typedef struct {
+ uint32 flags;
+ chanspec_t chanspec; /* txpwr report for this channel */
+ chanspec_t local_chanspec; /* channel on which we are associated */
+ uint8 local_max; /* local max according to the AP */
+ uint8 local_constraint; /* local constraint according to the AP */
+ int8 antgain[2]; /* Ant gain for each band - from SROM */
+ uint8 rf_cores; /* count of RF Cores being reported */
+ uint8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
+ uint8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain
+ * without adjustment
+ */
+ uint8 est_Pout_cck; /* Latest CCK tx power out estimate */
+ uint8 tx_power_max[4]; /* Maximum target power among all rates */
+ uint tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */
+ txppr_t user_limit; /* User limit */
+ txppr_t reg_limit; /* Regulatory power limit */
+ txppr_t board_limit; /* Max power board can support (SROM) */
+ txppr_t target; /* Latest target power */
+} wl_txpwr_t;
+
+#define WL_NUM_TXCHAIN_MAX 4
+typedef struct wl_txchain_pwr_offsets {
+ int8 offset[WL_NUM_TXCHAIN_MAX]; /* quarter dBm signed offset for each chain */
+} wl_txchain_pwr_offsets_t;
+
+/* 802.11h measurement types */
+#define WLC_MEASURE_TPC 1
+#define WLC_MEASURE_CHANNEL_BASIC 2
+#define WLC_MEASURE_CHANNEL_CCA 3
+#define WLC_MEASURE_CHANNEL_RPI 4
+
+/* regulatory enforcement levels */
+#define SPECT_MNGMT_OFF 0 /* both 11h and 11d disabled */
+#define SPECT_MNGMT_LOOSE_11H 1 /* allow non-11h APs in scan lists */
+#define SPECT_MNGMT_STRICT_11H 2 /* prune out non-11h APs from scan list */
+#define SPECT_MNGMT_STRICT_11D 3 /* switch to 802.11D mode */
+/* SPECT_MNGMT_LOOSE_11H_D - same as SPECT_MNGMT_LOOSE with the exception that Country IE
+ * adoption is done regardless of capability spectrum_management
+ */
+#define SPECT_MNGMT_LOOSE_11H_D 4 /* operation defined above */
+
+#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */
+#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */
+#define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */
+#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */
+#define WL_CHAN_INACTIVE (1 << 4) /* temporarily inactive due to radar */
+#define WL_CHAN_PASSIVE (1 << 5) /* channel is in passive mode */
+#define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */
+
+/* BTC mode used by "btc_mode" iovar */
+#define WL_BTC_DISABLE 0 /* disable BT coexistence */
+#define WL_BTC_FULLTDM 1 /* full TDM COEX */
+#define WL_BTC_ENABLE 1 /* full TDM COEX to maintain backward compatiblity */
+#define WL_BTC_PREMPT 2 /* full TDM COEX with preemption */
+#define WL_BTC_LITE 3 /* light weight coex for large isolation platform */
+#define WL_BTC_PARALLEL 4 /* BT and WLAN run in parallel with separate antenna */
+#define WL_BTC_HYBRID 5 /* hybrid coex, only ack is allowed to transmit in BT slot */
+#define WL_BTC_DEFAULT 8 /* set the default mode for the device */
+#define WL_INF_BTC_DISABLE 0
+#define WL_INF_BTC_ENABLE 1
+#define WL_INF_BTC_AUTO 3
+
+/* BTC wire used by "btc_wire" iovar */
+#define WL_BTC_DEFWIRE 0 /* use default wire setting */
+#define WL_BTC_2WIRE 2 /* use 2-wire BTC */
+#define WL_BTC_3WIRE 3 /* use 3-wire BTC */
+#define WL_BTC_4WIRE 4 /* use 4-wire BTC */
+
+/* BTC flags: BTC configuration that can be set by host */
+#define WL_BTC_FLAG_PREMPT (1 << 0)
+#define WL_BTC_FLAG_BT_DEF (1 << 1)
+#define WL_BTC_FLAG_ACTIVE_PROT (1 << 2)
+#define WL_BTC_FLAG_SIM_RSP (1 << 3)
+#define WL_BTC_FLAG_PS_PROTECT (1 << 4)
+#define WL_BTC_FLAG_SIM_TX_LP (1 << 5)
+#define WL_BTC_FLAG_ECI (1 << 6)
+#define WL_BTC_FLAG_LIGHT (1 << 7)
+#define WL_BTC_FLAG_PARALLEL (1 << 8)
+
+/* Message levels */
+#define WL_ERROR_VAL 0x00000001
+#define WL_TRACE_VAL 0x00000002
+#define WL_PRHDRS_VAL 0x00000004
+#define WL_PRPKT_VAL 0x00000008
+#define WL_INFORM_VAL 0x00000010
+#define WL_TMP_VAL 0x00000020
+#define WL_OID_VAL 0x00000040
+#define WL_RATE_VAL 0x00000080
+#define WL_ASSOC_VAL 0x00000100
+#define WL_PRUSR_VAL 0x00000200
+#define WL_PS_VAL 0x00000400
+#define WL_TXPWR_VAL 0x00000800 /* retired in TOT on 6/10/2009 */
+#define WL_PORT_VAL 0x00001000
+#define WL_DUAL_VAL 0x00002000
+#define WL_WSEC_VAL 0x00004000
+#define WL_WSEC_DUMP_VAL 0x00008000
+#define WL_LOG_VAL 0x00010000
+#define WL_NRSSI_VAL 0x00020000 /* retired in TOT on 6/10/2009 */
+#define WL_LOFT_VAL 0x00040000 /* retired in TOT on 6/10/2009 */
+#define WL_REGULATORY_VAL 0x00080000
+#define WL_PHYCAL_VAL 0x00100000 /* retired in TOT on 6/10/2009 */
+#define WL_RADAR_VAL 0x00200000 /* retired in TOT on 6/10/2009 */
+#define WL_MPC_VAL 0x00400000
+#define WL_APSTA_VAL 0x00800000
+#define WL_DFS_VAL 0x01000000
+#define WL_BA_VAL 0x02000000 /* retired in TOT on 6/14/2010 */
+#define WL_ACI_VAL 0x04000000
+#define WL_MBSS_VAL 0x04000000
+#define WL_CAC_VAL 0x08000000
+#define WL_AMSDU_VAL 0x10000000
+#define WL_AMPDU_VAL 0x20000000
+#define WL_FFPLD_VAL 0x40000000
+
+/* wl_msg_level is full. For new bits take the next one and AND with
+ * wl_msg_level2 in wl_dbg.h
+ */
+#define WL_DPT_VAL 0x00000001
+#define WL_SCAN_VAL 0x00000002
+#define WL_WOWL_VAL 0x00000004
+#define WL_COEX_VAL 0x00000008
+#define WL_RTDC_VAL 0x00000010
+#define WL_PROTO_VAL 0x00000020
+#define WL_BTA_VAL 0x00000040
+#define WL_CHANINT_VAL 0x00000080
+#define WL_THERMAL_VAL 0x00000100 /* retired in TOT on 6/10/2009 */
+#define WL_P2P_VAL 0x00000200
+#define WL_ITFR_VAL 0x00000400
+#define WL_MCHAN_VAL 0x00000800
+#define WL_TDLS_VAL 0x00001000
+#define WL_MCNX_VAL 0x00002000
+#define WL_PROT_VAL 0x00004000
+#define WL_PSTA_VAL 0x00008000
+#define WL_TBTT_VAL 0x00010000
+#define WL_NIC_VAL 0x00020000
+#define WL_PWRSEL_VAL 0x00040000
+/* use top-bit for WL_TIME_STAMP_VAL because this is a modifier
+ * rather than a message-type of its own
+ */
+#define WL_TIMESTAMP_VAL 0x80000000
+
+/* max # of leds supported by GPIO (gpio pin# == led index#) */
+#define WL_LED_NUMGPIO 32 /* gpio 0-31 */
+
+/* led per-pin behaviors */
+#define WL_LED_OFF 0 /* always off */
+#define WL_LED_ON 1 /* always on */
+#define WL_LED_ACTIVITY 2 /* activity */
+#define WL_LED_RADIO 3 /* radio enabled */
+#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */
+#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */
+#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */
+#define WL_LED_WI1 7
+#define WL_LED_WI2 8
+#define WL_LED_WI3 9
+#define WL_LED_ASSOC 10 /* associated state indicator */
+#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */
+#define WL_LED_ASSOCACT 12 /* on when associated; blink fast for activity */
+#define WL_LED_WI4 13
+#define WL_LED_WI5 14
+#define WL_LED_BLINKSLOW 15 /* blink slow */
+#define WL_LED_BLINKMED 16 /* blink med */
+#define WL_LED_BLINKFAST 17 /* blink fast */
+#define WL_LED_BLINKCUSTOM 18 /* blink custom */
+#define WL_LED_BLINKPERIODIC 19 /* blink periodic (custom 1000ms / off 400ms) */
+#define WL_LED_ASSOC_WITH_SEC 20 /* when connected with security */
+ /* keep on for 300 sec */
+#define WL_LED_START_OFF 21 /* off upon boot, could be turned on later */
+#define WL_LED_NUMBEHAVIOR 22
+
+/* led behavior numeric value format */
+#define WL_LED_BEH_MASK 0x7f /* behavior mask */
+#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */
+
+/* maximum channels returned by the get valid channels iovar */
+#define WL_NUMCHANNELS 64
+
+/* max number of chanspecs (used by the iovar to calc. buf space) */
+#define WL_NUMCHANSPECS 110
+
+/* WDS link local endpoint WPA role */
+#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */
+#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */
+#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */
+
+/* number of bytes needed to define a 128-bit mask for MAC event reporting */
+#define WL_EVENTING_MASK_LEN 16
+
+/*
+ * Join preference iovar value is an array of tuples. Each tuple has a one-byte type,
+ * a one-byte length, and a variable length value. RSSI type tuple must be present
+ * in the array.
+ *
+ * Types are defined in "join preference types" section.
+ *
+ * Length is the value size in octets. It is reserved for WL_JOIN_PREF_WPA type tuple
+ * and must be set to zero.
+ *
+ * Values are defined below.
+ *
+ * 1. RSSI - 2 octets
+ * offset 0: reserved
+ * offset 1: reserved
+ *
+ * 2. WPA - 2 + 12 * n octets (n is # tuples defined below)
+ * offset 0: reserved
+ * offset 1: # of tuples
+ * offset 2: tuple 1
+ * offset 14: tuple 2
+ * ...
+ * offset 2 + 12 * (n - 1) octets: tuple n
+ *
+ * struct wpa_cfg_tuple {
+ * uint8 akm[DOT11_OUI_LEN+1]; akm suite
+ * uint8 ucipher[DOT11_OUI_LEN+1]; unicast cipher suite
+ * uint8 mcipher[DOT11_OUI_LEN+1]; multicast cipher suite
+ * };
+ *
+ * multicast cipher suite can be specified as a specific cipher suite or WL_WPA_ACP_MCS_ANY.
+ *
+ * 3. BAND - 2 octets
+ * offset 0: reserved
+ * offset 1: see "band preference" and "band types"
+ *
+ * 4. BAND RSSI - 2 octets
+ * offset 0: band types
+ * offset 1: +ve RSSI boost balue in dB
+ */
+
+/* join preference types */
+#define WL_JOIN_PREF_RSSI 1 /* by RSSI */
+#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers */
+#define WL_JOIN_PREF_BAND 3 /* by 802.11 band */
+#define WL_JOIN_PREF_RSSI_DELTA 4 /* by 802.11 band only if RSSI delta condition matches */
+#define WL_JOIN_PREF_TRANS_PREF 5 /* defined by requesting AP */
+
+/* band preference */
+#define WLJP_BAND_ASSOC_PREF 255 /* use what WLC_SET_ASSOC_PREFER ioctl specifies */
+
+/* any multicast cipher suite */
+#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00"
+
+struct tsinfo_arg {
+ uint8 octets[3];
+};
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+#define NFIFO 6 /* # tx/rx fifopairs */
+
+#define WL_CNT_T_VERSION 8 /* current version of wl_cnt_t struct */
+
+typedef struct {
+ uint16 version; /* see definition of WL_CNT_T_VERSION */
+ uint16 length; /* length of entire structure */
+
+ /* transmit stat counters */
+ uint32 txframe; /* tx data frames */
+ uint32 txbyte; /* tx data bytes */
+ uint32 txretrans; /* tx mac retransmits */
+ uint32 txerror; /* tx data errors (derived: sum of others) */
+ uint32 txctl; /* tx management frames */
+ uint32 txprshort; /* tx short preamble frames */
+ uint32 txserr; /* tx status errors */
+ uint32 txnobuf; /* tx out of buffers errors */
+ uint32 txnoassoc; /* tx discard because we're not associated */
+ uint32 txrunt; /* tx runt frames */
+ uint32 txchit; /* tx header cache hit (fastpath) */
+ uint32 txcmiss; /* tx header cache miss (slowpath) */
+
+ /* transmit chip error counters */
+ uint32 txuflo; /* tx fifo underflows */
+ uint32 txphyerr; /* tx phy errors (indicated in tx status) */
+ uint32 txphycrs;
+
+ /* receive stat counters */
+ uint32 rxframe; /* rx data frames */
+ uint32 rxbyte; /* rx data bytes */
+ uint32 rxerror; /* rx data errors (derived: sum of others) */
+ uint32 rxctl; /* rx management frames */
+ uint32 rxnobuf; /* rx out of buffers errors */
+ uint32 rxnondata; /* rx non data frames in the data channel errors */
+ uint32 rxbadds; /* rx bad DS errors */
+ uint32 rxbadcm; /* rx bad control or management frames */
+ uint32 rxfragerr; /* rx fragmentation errors */
+ uint32 rxrunt; /* rx runt frames */
+ uint32 rxgiant; /* rx giant frames */
+ uint32 rxnoscb; /* rx no scb error */
+ uint32 rxbadproto; /* rx invalid frames */
+ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */
+ uint32 rxbadda; /* rx frames tossed for invalid da */
+ uint32 rxfilter; /* rx frames filtered out */
+
+ /* receive chip error counters */
+ uint32 rxoflo; /* rx fifo overflow errors */
+ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */
+
+ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */
+ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */
+ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */
+
+ /* misc counters */
+ uint32 dmade; /* tx/rx dma descriptor errors */
+ uint32 dmada; /* tx/rx dma data errors */
+ uint32 dmape; /* tx/rx dma descriptor protocol errors */
+ uint32 reset; /* reset count */
+ uint32 tbtt; /* cnts the TBTT int's */
+ uint32 txdmawar;
+ uint32 pkt_callback_reg_fail; /* callbacks register failure */
+
+ /* MAC counters: 32-bit version of d11.h's macstat_t */
+ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS,
+ * Control Management (includes retransmissions)
+ */
+ uint32 txrtsfrm; /* number of RTS sent out by the MAC */
+ uint32 txctsfrm; /* number of CTS sent out by the MAC */
+ uint32 txackfrm; /* number of ACK frames sent out */
+ uint32 txdnlfrm; /* Not used */
+ uint32 txbcnfrm; /* beacons transmitted */
+ uint32 txfunfl[8]; /* per-fifo tx underflows */
+ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS
+ * or BCN)
+ */
+ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for
+ * driver enqueued frames
+ */
+ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */
+ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */
+ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not
+ * data/control/management
+ */
+ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */
+ uint32 rxbadplcp; /* parity check of the PLCP header failed */
+ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */
+ uint32 rxstrt; /* Number of received frames with a good PLCP
+ * (i.e. passing parity check)
+ */
+ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */
+ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */
+ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */
+ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */
+ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */
+ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */
+ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */
+ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */
+ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */
+ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */
+ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */
+ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */
+ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */
+ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC
+ * (unlikely to see these)
+ */
+ uint32 rxbeaconmbss; /* beacons received from member of BSS */
+ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from
+ * other BSS (WDS FRAME)
+ */
+ uint32 rxbeaconobss; /* beacons received from other BSS */
+ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames
+ * expecting a response
+ */
+ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */
+ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */
+ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */
+ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */
+ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */
+ uint32 pmqovfl; /* Number of PMQ overflows */
+ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into
+ * the PRQ fifo
+ */
+ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */
+ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did
+ * not get ACK
+ */
+ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */
+ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ
+ * fifo because a probe response could not be sent out within
+ * the time limit defined in M_PRS_MAXTIME
+ */
+ uint32 rxnack; /* obsolete */
+ uint32 frmscons; /* obsolete */
+ uint32 txnack; /* obsolete */
+ uint32 txglitch_nack; /* obsolete */
+ uint32 txburst; /* obsolete */
+
+ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */
+ uint32 txfrag; /* dot11TransmittedFragmentCount */
+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */
+ uint32 txfail; /* dot11FailedCount */
+ uint32 txretry; /* dot11RetryCount */
+ uint32 txretrie; /* dot11MultipleRetryCount */
+ uint32 rxdup; /* dot11FrameduplicateCount */
+ uint32 txrts; /* dot11RTSSuccessCount */
+ uint32 txnocts; /* dot11RTSFailureCount */
+ uint32 txnoack; /* dot11ACKFailureCount */
+ uint32 rxfrag; /* dot11ReceivedFragmentCount */
+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */
+ uint32 rxcrc; /* dot11FCSErrorCount */
+ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */
+ uint32 rxundec; /* dot11WEPUndecryptableCount */
+
+ /* WPA2 counters (see rxundec for DecryptFailureCount) */
+ uint32 tkipmicfaill; /* TKIPLocalMICFailures */
+ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */
+ uint32 tkipreplay; /* TKIPReplays */
+ uint32 ccmpfmterr; /* CCMPFormatErrors */
+ uint32 ccmpreplay; /* CCMPReplays */
+ uint32 ccmpundec; /* CCMPDecryptErrors */
+ uint32 fourwayfail; /* FourWayHandshakeFailures */
+ uint32 wepundec; /* dot11WEPUndecryptableCount */
+ uint32 wepicverr; /* dot11WEPICVErrorCount */
+ uint32 decsuccess; /* DecryptSuccessCount */
+ uint32 tkipicverr; /* TKIPICVErrorCount */
+ uint32 wepexcluded; /* dot11WEPExcludedCount */
+
+ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */
+ uint32 psmwds; /* Count PSM watchdogs */
+ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */
+
+ /* MBSS counters, AP only */
+ uint32 prq_entries_handled; /* PRQ entries read in */
+ uint32 prq_undirected_entries; /* which were bcast bss & ssid */
+ uint32 prq_bad_entries; /* which could not be translated to info */
+ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */
+ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */
+ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */
+ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */
+
+ /* per-rate receive stat counters */
+ uint32 rx1mbps; /* packets rx at 1Mbps */
+ uint32 rx2mbps; /* packets rx at 2Mbps */
+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */
+ uint32 rx6mbps; /* packets rx at 6Mbps */
+ uint32 rx9mbps; /* packets rx at 9Mbps */
+ uint32 rx11mbps; /* packets rx at 11Mbps */
+ uint32 rx12mbps; /* packets rx at 12Mbps */
+ uint32 rx18mbps; /* packets rx at 18Mbps */
+ uint32 rx24mbps; /* packets rx at 24Mbps */
+ uint32 rx36mbps; /* packets rx at 36Mbps */
+ uint32 rx48mbps; /* packets rx at 48Mbps */
+ uint32 rx54mbps; /* packets rx at 54Mbps */
+ uint32 rx108mbps; /* packets rx at 108mbps */
+ uint32 rx162mbps; /* packets rx at 162mbps */
+ uint32 rx216mbps; /* packets rx at 216 mbps */
+ uint32 rx270mbps; /* packets rx at 270 mbps */
+ uint32 rx324mbps; /* packets rx at 324 mbps */
+ uint32 rx378mbps; /* packets rx at 378 mbps */
+ uint32 rx432mbps; /* packets rx at 432 mbps */
+ uint32 rx486mbps; /* packets rx at 486 mbps */
+ uint32 rx540mbps; /* packets rx at 540 mbps */
+
+ /* pkteng rx frame stats */
+ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */
+ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */
+
+ uint32 rfdisable; /* count of radio disables */
+ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */
+
+ uint32 txexptime; /* Tx frames suppressed due to timer expiration */
+
+ uint32 txmpdu_sgi; /* count for sgi transmit */
+ uint32 rxmpdu_sgi; /* count for sgi received */
+ uint32 txmpdu_stbc; /* count for stbc transmit */
+ uint32 rxmpdu_stbc; /* count for stbc received */
+
+ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */
+
+ /* WPA2 counters (see rxundec for DecryptFailureCount) */
+ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */
+ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */
+ uint32 tkipreplay_mcst; /* TKIPReplays */
+ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */
+ uint32 ccmpreplay_mcst; /* CCMPReplays */
+ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */
+ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */
+ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */
+ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */
+ uint32 decsuccess_mcst; /* DecryptSuccessCount */
+ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */
+ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */
+
+ uint32 dma_hang; /* count for dma hang */
+ uint32 reinit; /* count for reinit */
+
+ uint32 pstatxucast; /* count of ucast frames xmitted on all psta assoc */
+ uint32 pstatxnoassoc; /* count of txnoassoc frames xmitted on all psta assoc */
+ uint32 pstarxucast; /* count of ucast frames received on all psta assoc */
+ uint32 pstarxbcmc; /* count of bcmc frames received on all psta */
+ uint32 pstatxbcmc; /* count of bcmc frames transmitted on all psta */
+
+ uint32 cso_passthrough; /* hw cso required but passthrough */
+} wl_cnt_t;
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+typedef struct {
+ uint16 version; /* see definition of WL_CNT_T_VERSION */
+ uint16 length; /* length of entire structure */
+
+ /* transmit stat counters */
+ uint32 txframe; /* tx data frames */
+ uint32 txbyte; /* tx data bytes */
+ uint32 txretrans; /* tx mac retransmits */
+ uint32 txerror; /* tx data errors (derived: sum of others) */
+ uint32 txctl; /* tx management frames */
+ uint32 txprshort; /* tx short preamble frames */
+ uint32 txserr; /* tx status errors */
+ uint32 txnobuf; /* tx out of buffers errors */
+ uint32 txnoassoc; /* tx discard because we're not associated */
+ uint32 txrunt; /* tx runt frames */
+ uint32 txchit; /* tx header cache hit (fastpath) */
+ uint32 txcmiss; /* tx header cache miss (slowpath) */
+
+ /* transmit chip error counters */
+ uint32 txuflo; /* tx fifo underflows */
+ uint32 txphyerr; /* tx phy errors (indicated in tx status) */
+ uint32 txphycrs;
+
+ /* receive stat counters */
+ uint32 rxframe; /* rx data frames */
+ uint32 rxbyte; /* rx data bytes */
+ uint32 rxerror; /* rx data errors (derived: sum of others) */
+ uint32 rxctl; /* rx management frames */
+ uint32 rxnobuf; /* rx out of buffers errors */
+ uint32 rxnondata; /* rx non data frames in the data channel errors */
+ uint32 rxbadds; /* rx bad DS errors */
+ uint32 rxbadcm; /* rx bad control or management frames */
+ uint32 rxfragerr; /* rx fragmentation errors */
+ uint32 rxrunt; /* rx runt frames */
+ uint32 rxgiant; /* rx giant frames */
+ uint32 rxnoscb; /* rx no scb error */
+ uint32 rxbadproto; /* rx invalid frames */
+ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */
+ uint32 rxbadda; /* rx frames tossed for invalid da */
+ uint32 rxfilter; /* rx frames filtered out */
+
+ /* receive chip error counters */
+ uint32 rxoflo; /* rx fifo overflow errors */
+ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */
+
+ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */
+ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */
+ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */
+
+ /* misc counters */
+ uint32 dmade; /* tx/rx dma descriptor errors */
+ uint32 dmada; /* tx/rx dma data errors */
+ uint32 dmape; /* tx/rx dma descriptor protocol errors */
+ uint32 reset; /* reset count */
+ uint32 tbtt; /* cnts the TBTT int's */
+ uint32 txdmawar;
+ uint32 pkt_callback_reg_fail; /* callbacks register failure */
+
+ /* MAC counters: 32-bit version of d11.h's macstat_t */
+ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS,
+ * Control Management (includes retransmissions)
+ */
+ uint32 txrtsfrm; /* number of RTS sent out by the MAC */
+ uint32 txctsfrm; /* number of CTS sent out by the MAC */
+ uint32 txackfrm; /* number of ACK frames sent out */
+ uint32 txdnlfrm; /* Not used */
+ uint32 txbcnfrm; /* beacons transmitted */
+ uint32 txfunfl[8]; /* per-fifo tx underflows */
+ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS
+ * or BCN)
+ */
+ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for
+ * driver enqueued frames
+ */
+ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */
+ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */
+ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not
+ * data/control/management
+ */
+ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */
+ uint32 rxbadplcp; /* parity check of the PLCP header failed */
+ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */
+ uint32 rxstrt; /* Number of received frames with a good PLCP
+ * (i.e. passing parity check)
+ */
+ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */
+ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */
+ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */
+ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */
+ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */
+ uint32 rxackucast; /* number of ucast ACKS received (good FCS) */
+ uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */
+ uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */
+ uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */
+ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */
+ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */
+ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */
+ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */
+ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC
+ * (unlikely to see these)
+ */
+ uint32 rxbeaconmbss; /* beacons received from member of BSS */
+ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from
+ * other BSS (WDS FRAME)
+ */
+ uint32 rxbeaconobss; /* beacons received from other BSS */
+ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames
+ * expecting a response
+ */
+ uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */
+ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */
+ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */
+ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */
+ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */
+ uint32 pmqovfl; /* Number of PMQ overflows */
+ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into
+ * the PRQ fifo
+ */
+ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */
+ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did
+ * not get ACK
+ */
+ uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */
+ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ
+ * fifo because a probe response could not be sent out within
+ * the time limit defined in M_PRS_MAXTIME
+ */
+ uint32 rxnack;
+ uint32 frmscons;
+ uint32 txnack;
+ uint32 txglitch_nack; /* obsolete */
+ uint32 txburst; /* obsolete */
+
+ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */
+ uint32 txfrag; /* dot11TransmittedFragmentCount */
+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */
+ uint32 txfail; /* dot11FailedCount */
+ uint32 txretry; /* dot11RetryCount */
+ uint32 txretrie; /* dot11MultipleRetryCount */
+ uint32 rxdup; /* dot11FrameduplicateCount */
+ uint32 txrts; /* dot11RTSSuccessCount */
+ uint32 txnocts; /* dot11RTSFailureCount */
+ uint32 txnoack; /* dot11ACKFailureCount */
+ uint32 rxfrag; /* dot11ReceivedFragmentCount */
+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */
+ uint32 rxcrc; /* dot11FCSErrorCount */
+ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */
+ uint32 rxundec; /* dot11WEPUndecryptableCount */
+
+ /* WPA2 counters (see rxundec for DecryptFailureCount) */
+ uint32 tkipmicfaill; /* TKIPLocalMICFailures */
+ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */
+ uint32 tkipreplay; /* TKIPReplays */
+ uint32 ccmpfmterr; /* CCMPFormatErrors */
+ uint32 ccmpreplay; /* CCMPReplays */
+ uint32 ccmpundec; /* CCMPDecryptErrors */
+ uint32 fourwayfail; /* FourWayHandshakeFailures */
+ uint32 wepundec; /* dot11WEPUndecryptableCount */
+ uint32 wepicverr; /* dot11WEPICVErrorCount */
+ uint32 decsuccess; /* DecryptSuccessCount */
+ uint32 tkipicverr; /* TKIPICVErrorCount */
+ uint32 wepexcluded; /* dot11WEPExcludedCount */
+
+ uint32 rxundec_mcst; /* dot11WEPUndecryptableCount */
+
+ /* WPA2 counters (see rxundec for DecryptFailureCount) */
+ uint32 tkipmicfaill_mcst; /* TKIPLocalMICFailures */
+ uint32 tkipcntrmsr_mcst; /* TKIPCounterMeasuresInvoked */
+ uint32 tkipreplay_mcst; /* TKIPReplays */
+ uint32 ccmpfmterr_mcst; /* CCMPFormatErrors */
+ uint32 ccmpreplay_mcst; /* CCMPReplays */
+ uint32 ccmpundec_mcst; /* CCMPDecryptErrors */
+ uint32 fourwayfail_mcst; /* FourWayHandshakeFailures */
+ uint32 wepundec_mcst; /* dot11WEPUndecryptableCount */
+ uint32 wepicverr_mcst; /* dot11WEPICVErrorCount */
+ uint32 decsuccess_mcst; /* DecryptSuccessCount */
+ uint32 tkipicverr_mcst; /* TKIPICVErrorCount */
+ uint32 wepexcluded_mcst; /* dot11WEPExcludedCount */
+
+ uint32 txchanrej; /* Tx frames suppressed due to channel rejection */
+ uint32 txexptime; /* Tx frames suppressed due to timer expiration */
+ uint32 psmwds; /* Count PSM watchdogs */
+ uint32 phywatchdog; /* Count Phy watchdogs (triggered by ucode) */
+
+ /* MBSS counters, AP only */
+ uint32 prq_entries_handled; /* PRQ entries read in */
+ uint32 prq_undirected_entries; /* which were bcast bss & ssid */
+ uint32 prq_bad_entries; /* which could not be translated to info */
+ uint32 atim_suppress_count; /* TX suppressions on ATIM fifo */
+ uint32 bcn_template_not_ready; /* Template marked in use on send bcn ... */
+ uint32 bcn_template_not_ready_done; /* ...but "DMA done" interrupt rcvd */
+ uint32 late_tbtt_dpc; /* TBTT DPC did not happen in time */
+
+ /* per-rate receive stat counters */
+ uint32 rx1mbps; /* packets rx at 1Mbps */
+ uint32 rx2mbps; /* packets rx at 2Mbps */
+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */
+ uint32 rx6mbps; /* packets rx at 6Mbps */
+ uint32 rx9mbps; /* packets rx at 9Mbps */
+ uint32 rx11mbps; /* packets rx at 11Mbps */
+ uint32 rx12mbps; /* packets rx at 12Mbps */
+ uint32 rx18mbps; /* packets rx at 18Mbps */
+ uint32 rx24mbps; /* packets rx at 24Mbps */
+ uint32 rx36mbps; /* packets rx at 36Mbps */
+ uint32 rx48mbps; /* packets rx at 48Mbps */
+ uint32 rx54mbps; /* packets rx at 54Mbps */
+ uint32 rx108mbps; /* packets rx at 108mbps */
+ uint32 rx162mbps; /* packets rx at 162mbps */
+ uint32 rx216mbps; /* packets rx at 216 mbps */
+ uint32 rx270mbps; /* packets rx at 270 mbps */
+ uint32 rx324mbps; /* packets rx at 324 mbps */
+ uint32 rx378mbps; /* packets rx at 378 mbps */
+ uint32 rx432mbps; /* packets rx at 432 mbps */
+ uint32 rx486mbps; /* packets rx at 486 mbps */
+ uint32 rx540mbps; /* packets rx at 540 mbps */
+
+ /* pkteng rx frame stats */
+ uint32 pktengrxducast; /* unicast frames rxed by the pkteng code */
+ uint32 pktengrxdmcast; /* multicast frames rxed by the pkteng code */
+
+ uint32 rfdisable; /* count of radio disables */
+ uint32 bphy_rxcrsglitch; /* PHY count of bphy glitches */
+
+ uint32 txmpdu_sgi; /* count for sgi transmit */
+ uint32 rxmpdu_sgi; /* count for sgi received */
+ uint32 txmpdu_stbc; /* count for stbc transmit */
+ uint32 rxmpdu_stbc; /* count for stbc received */
+} wl_cnt_ver_six_t;
+
+#define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */
+
+typedef struct {
+ uint16 version; /* see definition of WL_DELTA_STATS_T_VERSION */
+ uint16 length; /* length of entire structure */
+
+ /* transmit stat counters */
+ uint32 txframe; /* tx data frames */
+ uint32 txbyte; /* tx data bytes */
+ uint32 txretrans; /* tx mac retransmits */
+ uint32 txfail; /* tx failures */
+
+ /* receive stat counters */
+ uint32 rxframe; /* rx data frames */
+ uint32 rxbyte; /* rx data bytes */
+
+ /* per-rate receive stat counters */
+ uint32 rx1mbps; /* packets rx at 1Mbps */
+ uint32 rx2mbps; /* packets rx at 2Mbps */
+ uint32 rx5mbps5; /* packets rx at 5.5Mbps */
+ uint32 rx6mbps; /* packets rx at 6Mbps */
+ uint32 rx9mbps; /* packets rx at 9Mbps */
+ uint32 rx11mbps; /* packets rx at 11Mbps */
+ uint32 rx12mbps; /* packets rx at 12Mbps */
+ uint32 rx18mbps; /* packets rx at 18Mbps */
+ uint32 rx24mbps; /* packets rx at 24Mbps */
+ uint32 rx36mbps; /* packets rx at 36Mbps */
+ uint32 rx48mbps; /* packets rx at 48Mbps */
+ uint32 rx54mbps; /* packets rx at 54Mbps */
+ uint32 rx108mbps; /* packets rx at 108mbps */
+ uint32 rx162mbps; /* packets rx at 162mbps */
+ uint32 rx216mbps; /* packets rx at 216 mbps */
+ uint32 rx270mbps; /* packets rx at 270 mbps */
+ uint32 rx324mbps; /* packets rx at 324 mbps */
+ uint32 rx378mbps; /* packets rx at 378 mbps */
+ uint32 rx432mbps; /* packets rx at 432 mbps */
+ uint32 rx486mbps; /* packets rx at 486 mbps */
+ uint32 rx540mbps; /* packets rx at 540 mbps */
+} wl_delta_stats_t;
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */
+
+typedef struct {
+ uint32 packets;
+ uint32 bytes;
+} wl_traffic_stats_t;
+
+typedef struct {
+ uint16 version; /* see definition of WL_WME_CNT_VERSION */
+ uint16 length; /* length of entire structure */
+
+ wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */
+ wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */
+ wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */
+ wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */
+
+ wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */
+
+ wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */
+
+} wl_wme_cnt_t;
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+struct wl_msglevel2 {
+ uint32 low;
+ uint32 high;
+};
+
+typedef struct wl_mkeep_alive_pkt {
+ uint16 version; /* Version for mkeep_alive */
+ uint16 length; /* length of fixed parameters in the structure */
+ uint32 period_msec;
+ uint16 len_bytes;
+ uint8 keep_alive_id; /* 0 - 3 for N = 4 */
+ uint8 data[1];
+} wl_mkeep_alive_pkt_t;
+
+#define WL_MKEEP_ALIVE_VERSION 1
+#define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data)
+#define WL_MKEEP_ALIVE_PRECISION 500
+
+#ifdef WLBA
+
+#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */
+
+/* block ack related stats */
+typedef struct wlc_ba_cnt {
+ uint16 version; /* WLC_BA_CNT_VERSION */
+ uint16 length; /* length of entire structure */
+
+ /* transmit stat counters */
+ uint32 txpdu; /* pdus sent */
+ uint32 txsdu; /* sdus sent */
+ uint32 txfc; /* tx side flow controlled packets */
+ uint32 txfci; /* tx side flow control initiated */
+ uint32 txretrans; /* retransmitted pdus */
+ uint32 txbatimer; /* ba resend due to timer */
+ uint32 txdrop; /* dropped packets */
+ uint32 txaddbareq; /* addba req sent */
+ uint32 txaddbaresp; /* addba resp sent */
+ uint32 txdelba; /* delba sent */
+ uint32 txba; /* ba sent */
+ uint32 txbar; /* bar sent */
+ uint32 txpad[4]; /* future */
+
+ /* receive side counters */
+ uint32 rxpdu; /* pdus recd */
+ uint32 rxqed; /* pdus buffered before sending up */
+ uint32 rxdup; /* duplicate pdus */
+ uint32 rxnobuf; /* pdus discarded due to no buf */
+ uint32 rxaddbareq; /* addba req recd */
+ uint32 rxaddbaresp; /* addba resp recd */
+ uint32 rxdelba; /* delba recd */
+ uint32 rxba; /* ba recd */
+ uint32 rxbar; /* bar recd */
+ uint32 rxinvba; /* invalid ba recd */
+ uint32 rxbaholes; /* ba recd with holes */
+ uint32 rxunexp; /* unexpected packets */
+ uint32 rxpad[4]; /* future */
+} wlc_ba_cnt_t;
+#endif /* WLBA */
+
+/* structure for per-tid ampdu control */
+struct ampdu_tid_control {
+ uint8 tid; /* tid */
+ uint8 enable; /* enable/disable */
+};
+
+/* structure for identifying ea/tid for sending addba/delba */
+struct ampdu_ea_tid {
+ struct ether_addr ea; /* Station address */
+ uint8 tid; /* tid */
+};
+/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */
+struct ampdu_retry_tid {
+ uint8 tid; /* tid */
+ uint8 retry; /* retry value */
+};
+
+/* Different discovery modes for dpt */
+#define DPT_DISCOVERY_MANUAL 0x01 /* manual discovery mode */
+#define DPT_DISCOVERY_AUTO 0x02 /* auto discovery mode */
+#define DPT_DISCOVERY_SCAN 0x04 /* scan-based discovery mode */
+
+/* different path selection values */
+#define DPT_PATHSEL_AUTO 0 /* auto mode for path selection */
+#define DPT_PATHSEL_DIRECT 1 /* always use direct DPT path */
+#define DPT_PATHSEL_APPATH 2 /* always use AP path */
+
+/* different ops for deny list */
+#define DPT_DENY_LIST_ADD 1 /* add to dpt deny list */
+#define DPT_DENY_LIST_REMOVE 2 /* remove from dpt deny list */
+
+/* different ops for manual end point */
+#define DPT_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */
+#define DPT_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */
+#define DPT_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */
+
+/* structure for dpt iovars */
+typedef struct dpt_iovar {
+ struct ether_addr ea; /* Station address */
+ uint8 mode; /* mode: depends on iovar */
+ uint32 pad; /* future */
+} dpt_iovar_t;
+
+/* flags to indicate DPT status */
+#define DPT_STATUS_ACTIVE 0x01 /* link active (though may be suspended) */
+#define DPT_STATUS_AES 0x02 /* link secured through AES encryption */
+#define DPT_STATUS_FAILED 0x04 /* DPT link failed */
+
+#define DPT_FNAME_LEN 48 /* Max length of friendly name */
+
+typedef struct dpt_status {
+ uint8 status; /* flags to indicate status */
+ uint8 fnlen; /* length of friendly name */
+ uchar name[DPT_FNAME_LEN]; /* friendly name */
+ uint32 rssi; /* RSSI of the link */
+ sta_info_t sta; /* sta info */
+} dpt_status_t;
+
+/* structure for dpt list */
+typedef struct dpt_list {
+ uint32 num; /* number of entries in struct */
+ dpt_status_t status[1]; /* per station info */
+} dpt_list_t;
+
+/* structure for dpt friendly name */
+typedef struct dpt_fname {
+ uint8 len; /* length of friendly name */
+ uchar name[DPT_FNAME_LEN]; /* friendly name */
+} dpt_fname_t;
+
+#define BDD_FNAME_LEN 32 /* Max length of friendly name */
+typedef struct bdd_fname {
+ uint8 len; /* length of friendly name */
+ uchar name[BDD_FNAME_LEN]; /* friendly name */
+} bdd_fname_t;
+
+/* structure for addts arguments */
+/* For ioctls that take a list of TSPEC */
+struct tslist {
+ int count; /* number of tspecs */
+ struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */
+};
+
+#ifdef WLTDLS
+/* different ops for manual end point */
+#define TDLS_MANUAL_EP_CREATE 1 /* create manual dpt endpoint */
+#define TDLS_MANUAL_EP_MODIFY 2 /* modify manual dpt endpoint */
+#define TDLS_MANUAL_EP_DELETE 3 /* delete manual dpt endpoint */
+#define TDLS_MANUAL_EP_PM 4 /* put dpt endpoint in PM mode */
+#define TDLS_MANUAL_EP_WAKE 5 /* wake up dpt endpoint from PM */
+#define TDLS_MANUAL_EP_DISCOVERY 6 /* discover if endpoint is TDLS capable */
+#define TDLS_MANUAL_EP_CHSW 7 /* channel switch */
+
+/* structure for tdls iovars */
+typedef struct tdls_iovar {
+ struct ether_addr ea; /* Station address */
+ uint8 mode; /* mode: depends on iovar */
+ chanspec_t chanspec;
+ uint32 pad; /* future */
+} tdls_iovar_t;
+
+/* modes */
+#define TDLS_WFD_IE_TX 0
+#define TDLS_WFD_IE_RX 1
+#define TDLS_WFD_IE_SIZE 255
+/* structure for tdls wfd ie */
+typedef struct tdls_wfd_ie_iovar {
+ struct ether_addr ea; /* Station address */
+ uint8 mode;
+ uint8 length;
+ uint8 data[TDLS_WFD_IE_SIZE];
+} tdls_wfd_ie_iovar_t;
+#endif /* WLTDLS */
+
+/* structure for addts/delts arguments */
+typedef struct tspec_arg {
+ uint16 version; /* see definition of TSPEC_ARG_VERSION */
+ uint16 length; /* length of entire structure */
+ uint flag; /* bit field */
+ /* TSPEC Arguments */
+ struct tsinfo_arg tsinfo; /* TS Info bit field */
+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */
+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */
+ uint min_srv_interval; /* Minimum Service Interval (us) */
+ uint max_srv_interval; /* Maximum Service Interval (us) */
+ uint inactivity_interval; /* Inactivity Interval (us) */
+ uint suspension_interval; /* Suspension Interval (us) */
+ uint srv_start_time; /* Service Start Time (us) */
+ uint min_data_rate; /* Minimum Data Rate (bps) */
+ uint mean_data_rate; /* Mean Data Rate (bps) */
+ uint peak_data_rate; /* Peak Data Rate (bps) */
+ uint max_burst_size; /* Maximum Burst Size (bytes) */
+ uint delay_bound; /* Delay Bound (us) */
+ uint min_phy_rate; /* Minimum PHY Rate (bps) */
+ uint16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0 to 8.0) */
+ uint16 medium_time; /* Medium Time (32 us/s periods) */
+ uint8 dialog_token; /* dialog token */
+} tspec_arg_t;
+
+/* tspec arg for desired station */
+typedef struct tspec_per_sta_arg {
+ struct ether_addr ea;
+ struct tspec_arg ts;
+} tspec_per_sta_arg_t;
+
+/* structure for max bandwidth for each access category */
+typedef struct wme_max_bandwidth {
+ uint32 ac[AC_COUNT]; /* max bandwidth for each access category */
+} wme_max_bandwidth_t;
+
+#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t))
+
+/* current version of wl_tspec_arg_t struct */
+#define TSPEC_ARG_VERSION 2 /* current version of wl_tspec_arg_t struct */
+#define TSPEC_ARG_LENGTH 55 /* argument length from tsinfo to medium_time */
+#define TSPEC_DEFAULT_DIALOG_TOKEN 42 /* default dialog token */
+#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 /* default surplus bw */
+
+
+#define WL_WOWL_KEEPALIVE_MAX_PACKET_SIZE 80
+#define WLC_WOWL_MAX_KEEPALIVE 2
+
+/* define for flag */
+#define TSPEC_PENDING 0 /* TSPEC pending */
+#define TSPEC_ACCEPTED 1 /* TSPEC accepted */
+#define TSPEC_REJECTED 2 /* TSPEC rejected */
+#define TSPEC_UNKNOWN 3 /* TSPEC unknown */
+#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */
+
+
+/* Software feature flag defines used by wlfeatureflag */
+#ifdef WLAFTERBURNER
+#define WL_SWFL_ABBFL 0x0001 /* Allow Afterburner on systems w/o hardware BFL */
+#define WL_SWFL_ABENCORE 0x0002 /* Allow AB on non-4318E chips */
+#endif /* WLAFTERBURNER */
+#define WL_SWFL_NOHWRADIO 0x0004
+#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */
+#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */
+
+#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */
+
+/* Packet lifetime configuration per ac */
+typedef struct wl_lifetime {
+ uint32 ac; /* access class */
+ uint32 lifetime; /* Packet lifetime value in ms */
+} wl_lifetime_t;
+
+/* Channel Switch Announcement param */
+typedef struct wl_chan_switch {
+ uint8 mode; /* value 0 or 1 */
+ uint8 count; /* count # of beacons before switching */
+ chanspec_t chspec; /* chanspec */
+ uint8 reg; /* regulatory class */
+} wl_chan_switch_t;
+
+/* Roaming trigger definitions for WLC_SET_ROAM_TRIGGER.
+ *
+ * (-100 < value < 0) value is used directly as a roaming trigger in dBm
+ * (0 <= value) value specifies a logical roaming trigger level from
+ * the list below
+ *
+ * WLC_GET_ROAM_TRIGGER always returns roaming trigger value in dBm, never
+ * the logical roam trigger value.
+ */
+#define WLC_ROAM_TRIGGER_DEFAULT 0 /* default roaming trigger */
+#define WLC_ROAM_TRIGGER_BANDWIDTH 1 /* optimize for bandwidth roaming trigger */
+#define WLC_ROAM_TRIGGER_DISTANCE 2 /* optimize for distance roaming trigger */
+#define WLC_ROAM_TRIGGER_AUTO 3 /* auto-detect environment */
+#define WLC_ROAM_TRIGGER_MAX_VALUE 3 /* max. valid value */
+
+#define WLC_ROAM_NEVER_ROAM_TRIGGER (-100) /* Avoid Roaming by setting a large value */
+
+/* Preferred Network Offload (PNO, formerly PFN) defines */
+#define WPA_AUTH_PFN_ANY 0xffffffff /* for PFN, match only ssid */
+
+enum {
+ PFN_LIST_ORDER,
+ PFN_RSSI
+};
+
+enum {
+ DISABLE,
+ ENABLE
+};
+
+enum {
+ OFF_ADAPT,
+ SMART_ADAPT,
+ STRICT_ADAPT,
+ SLOW_ADAPT
+};
+
+#define SORT_CRITERIA_BIT 0
+#define AUTO_NET_SWITCH_BIT 1
+#define ENABLE_BKGRD_SCAN_BIT 2
+#define IMMEDIATE_SCAN_BIT 3
+#define AUTO_CONNECT_BIT 4
+#define ENABLE_BD_SCAN_BIT 5
+#define ENABLE_ADAPTSCAN_BIT 6
+#define IMMEDIATE_EVENT_BIT 8
+#define SUPPRESS_SSID_BIT 9
+#define ENABLE_NET_OFFLOAD_BIT 10
+
+#define SORT_CRITERIA_MASK 0x0001
+#define AUTO_NET_SWITCH_MASK 0x0002
+#define ENABLE_BKGRD_SCAN_MASK 0x0004
+#define IMMEDIATE_SCAN_MASK 0x0008
+#define AUTO_CONNECT_MASK 0x0010
+
+#define ENABLE_BD_SCAN_MASK 0x0020
+#define ENABLE_ADAPTSCAN_MASK 0x00c0
+#define IMMEDIATE_EVENT_MASK 0x0100
+#define SUPPRESS_SSID_MASK 0x0200
+#define ENABLE_NET_OFFLOAD_MASK 0x0400
+
+#define PFN_VERSION 2
+#define PFN_SCANRESULT_VERSION 1
+#define MAX_PFN_LIST_COUNT 16
+
+#define PFN_COMPLETE 1
+#define PFN_INCOMPLETE 0
+
+#define DEFAULT_BESTN 2
+#define DEFAULT_MSCAN 0
+#define DEFAULT_REPEAT 10
+#define DEFAULT_EXP 2
+
+/* PFN network info structure */
+typedef struct wl_pfn_subnet_info {
+ struct ether_addr BSSID;
+ uint8 channel; /* channel number only */
+ uint8 SSID_len;
+ uint8 SSID[32];
+} wl_pfn_subnet_info_t;
+
+typedef struct wl_pfn_net_info {
+ wl_pfn_subnet_info_t pfnsubnet;
+ int16 RSSI; /* receive signal strength (in dBm) */
+ uint16 timestamp; /* age in seconds */
+} wl_pfn_net_info_t;
+
+typedef struct wl_pfn_scanresults {
+ uint32 version;
+ uint32 status;
+ uint32 count;
+ wl_pfn_net_info_t netinfo[1];
+} wl_pfn_scanresults_t;
+
+/* PFN data structure */
+typedef struct wl_pfn_param {
+ int32 version; /* PNO parameters version */
+ int32 scan_freq; /* Scan frequency */
+ int32 lost_network_timeout; /* Timeout in sec. to declare
+ * discovered network as lost
+ */
+ int16 flags; /* Bit field to control features
+ * of PFN such as sort criteria auto
+ * enable switch and background scan
+ */
+ int16 rssi_margin; /* Margin to avoid jitter for choosing a
+ * PFN based on RSSI sort criteria
+ */
+ uint8 bestn; /* number of best networks in each scan */
+ uint8 mscan; /* number of scans recorded */
+ uint8 repeat; /* Minimum number of scan intervals
+ *before scan frequency changes in adaptive scan
+ */
+ uint8 exp; /* Exponent of 2 for maximum scan interval */
+ int32 slow_freq; /* slow scan period */
+} wl_pfn_param_t;
+
+typedef struct wl_pfn_bssid {
+ struct ether_addr macaddr;
+ /* Bit4: suppress_lost, Bit3: suppress_found */
+ uint16 flags;
+} wl_pfn_bssid_t;
+#define WL_PFN_SUPPRESSFOUND_MASK 0x08
+#define WL_PFN_SUPPRESSLOST_MASK 0x10
+
+typedef struct wl_pfn_cfg {
+ uint32 reporttype;
+ int32 channel_num;
+ uint16 channel_list[WL_NUMCHANNELS];
+} wl_pfn_cfg_t;
+#define WL_PFN_REPORT_ALLNET 0
+#define WL_PFN_REPORT_SSIDNET 1
+#define WL_PFN_REPORT_BSSIDNET 2
+
+typedef struct wl_pfn {
+ wlc_ssid_t ssid; /* ssid name and its length */
+ int32 flags; /* bit2: hidden */
+ int32 infra; /* BSS Vs IBSS */
+ int32 auth; /* Open Vs Closed */
+ int32 wpa_auth; /* WPA type */
+ int32 wsec; /* wsec value */
+} wl_pfn_t;
+#define WL_PFN_HIDDEN_BIT 2
+#define PNO_SCAN_MAX_FW 508*1000 /* max time scan time in msec */
+#define PNO_SCAN_MAX_FW_SEC PNO_SCAN_MAX_FW/1000 /* max time scan time in SEC */
+#define PNO_SCAN_MIN_FW_SEC 10 /* min time scan time in SEC */
+#define WL_PFN_HIDDEN_MASK 0x4
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* TCP Checksum Offload defines */
+#define TOE_TX_CSUM_OL 0x00000001
+#define TOE_RX_CSUM_OL 0x00000002
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+/* TCP Checksum Offload error injection for testing */
+#define TOE_ERRTEST_TX_CSUM 0x00000001
+#define TOE_ERRTEST_RX_CSUM 0x00000002
+#define TOE_ERRTEST_RX_CSUM2 0x00000004
+
+struct toe_ol_stats_t {
+ /* Num of tx packets that don't need to be checksummed */
+ uint32 tx_summed;
+
+ /* Num of tx packets where checksum is filled by offload engine */
+ uint32 tx_iph_fill;
+ uint32 tx_tcp_fill;
+ uint32 tx_udp_fill;
+ uint32 tx_icmp_fill;
+
+ /* Num of rx packets where toe finds out if checksum is good or bad */
+ uint32 rx_iph_good;
+ uint32 rx_iph_bad;
+ uint32 rx_tcp_good;
+ uint32 rx_tcp_bad;
+ uint32 rx_udp_good;
+ uint32 rx_udp_bad;
+ uint32 rx_icmp_good;
+ uint32 rx_icmp_bad;
+
+ /* Num of tx packets in which csum error is injected */
+ uint32 tx_tcp_errinj;
+ uint32 tx_udp_errinj;
+ uint32 tx_icmp_errinj;
+
+ /* Num of rx packets in which csum error is injected */
+ uint32 rx_tcp_errinj;
+ uint32 rx_udp_errinj;
+ uint32 rx_icmp_errinj;
+};
+
+/* ARP Offload feature flags for arp_ol iovar */
+#define ARP_OL_AGENT 0x00000001
+#define ARP_OL_SNOOP 0x00000002
+#define ARP_OL_HOST_AUTO_REPLY 0x00000004
+#define ARP_OL_PEER_AUTO_REPLY 0x00000008
+
+/* ARP Offload error injection */
+#define ARP_ERRTEST_REPLY_PEER 0x1
+#define ARP_ERRTEST_REPLY_HOST 0x2
+
+#define ARP_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */
+#define ND_MULTIHOMING_MAX 8 /* Maximum local host IP addresses */
+
+/* Arp offload statistic counts */
+struct arp_ol_stats_t {
+ uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */
+ uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */
+
+ uint32 arp_table_entries; /* ARP table entries */
+ uint32 arp_table_overflow; /* ARP table additions skipped due to overflow */
+
+ uint32 host_request; /* ARP requests from host */
+ uint32 host_reply; /* ARP replies from host */
+ uint32 host_service; /* ARP requests from host serviced by ARP Agent */
+
+ uint32 peer_request; /* ARP requests received from network */
+ uint32 peer_request_drop; /* ARP requests from network that were dropped */
+ uint32 peer_reply; /* ARP replies received from network */
+ uint32 peer_reply_drop; /* ARP replies from network that were dropped */
+ uint32 peer_service; /* ARP request from host serviced by ARP Agent */
+};
+
+/* NS offload statistic counts */
+struct nd_ol_stats_t {
+ uint32 host_ip_entries; /* Host IP table addresses (more than one if multihomed) */
+ uint32 host_ip_overflow; /* Host IP table additions skipped due to overflow */
+ uint32 peer_request; /* NS requests received from network */
+ uint32 peer_request_drop; /* NS requests from network that were dropped */
+ uint32 peer_reply_drop; /* NA replies from network that were dropped */
+ uint32 peer_service; /* NS request from host serviced by firmware */
+};
+
+/*
+ * Keep-alive packet offloading.
+ */
+
+/* NAT keep-alive packets format: specifies the re-transmission period, the packet
+ * length, and packet contents.
+ */
+typedef struct wl_keep_alive_pkt {
+ uint32 period_msec; /* Retransmission period (0 to disable packet re-transmits) */
+ uint16 len_bytes; /* Size of packet to transmit (0 to disable packet re-transmits) */
+ uint8 data[1]; /* Variable length packet to transmit. Contents should include
+ * entire ethernet packet (enet header, IP header, UDP header,
+ * and UDP payload) in network byte order.
+ */
+} wl_keep_alive_pkt_t;
+
+#define WL_KEEP_ALIVE_FIXED_LEN OFFSETOF(wl_keep_alive_pkt_t, data)
+
+/*
+ * Dongle pattern matching filter.
+ */
+
+/* Packet filter types. Currently, only pattern matching is supported. */
+typedef enum wl_pkt_filter_type {
+ WL_PKT_FILTER_TYPE_PATTERN_MATCH /* Pattern matching filter */
+} wl_pkt_filter_type_t;
+
+#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t
+
+/* Pattern matching filter. Specifies an offset within received packets to
+ * start matching, the pattern to match, the size of the pattern, and a bitmask
+ * that indicates which bits within the pattern should be matched.
+ */
+typedef struct wl_pkt_filter_pattern {
+ uint32 offset; /* Offset within received packet to start pattern matching.
+ * Offset '0' is the first byte of the ethernet header.
+ */
+ uint32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */
+ uint8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts
+ * at offset 0. Pattern immediately follows mask.
+ */
+} wl_pkt_filter_pattern_t;
+
+/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
+typedef struct wl_pkt_filter {
+ uint32 id; /* Unique filter id, specified by app. */
+ uint32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
+ uint32 negate_match; /* Negate the result of filter matches */
+ union { /* Filter definitions */
+ wl_pkt_filter_pattern_t pattern; /* Pattern matching filter */
+ } u;
+} wl_pkt_filter_t;
+
+#define WL_PKT_FILTER_FIXED_LEN OFFSETOF(wl_pkt_filter_t, u)
+#define WL_PKT_FILTER_PATTERN_FIXED_LEN OFFSETOF(wl_pkt_filter_pattern_t, mask_and_pattern)
+
+/* IOVAR "pkt_filter_enable" parameter. */
+typedef struct wl_pkt_filter_enable {
+ uint32 id; /* Unique filter id */
+ uint32 enable; /* Enable/disable bool */
+} wl_pkt_filter_enable_t;
+
+/* IOVAR "pkt_filter_list" parameter. Used to retrieve a list of installed filters. */
+typedef struct wl_pkt_filter_list {
+ uint32 num; /* Number of installed packet filters */
+ wl_pkt_filter_t filter[1]; /* Variable array of packet filters. */
+} wl_pkt_filter_list_t;
+
+#define WL_PKT_FILTER_LIST_FIXED_LEN OFFSETOF(wl_pkt_filter_list_t, filter)
+
+/* IOVAR "pkt_filter_stats" parameter. Used to retrieve debug statistics. */
+typedef struct wl_pkt_filter_stats {
+ uint32 num_pkts_matched; /* # filter matches for specified filter id */
+ uint32 num_pkts_forwarded; /* # packets fwded from dongle to host for all filters */
+ uint32 num_pkts_discarded; /* # packets discarded by dongle for all filters */
+} wl_pkt_filter_stats_t;
+
+/* Sequential Commands ioctl */
+typedef struct wl_seq_cmd_ioctl {
+ uint32 cmd; /* common ioctl definition */
+ uint32 len; /* length of user buffer */
+} wl_seq_cmd_ioctl_t;
+
+#define WL_SEQ_CMD_ALIGN_BYTES 4
+
+/* These are the set of get IOCTLs that should be allowed when using
+ * IOCTL sequence commands. These are issued implicitly by wl.exe each time
+ * it is invoked. We never want to buffer these, or else wl.exe will stop working.
+ */
+#define WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd) \
+ (((cmd) == WLC_GET_MAGIC) || \
+ ((cmd) == WLC_GET_VERSION) || \
+ ((cmd) == WLC_GET_AP) || \
+ ((cmd) == WLC_GET_INSTANCE))
+
+/*
+ * Packet engine interface
+ */
+
+#define WL_PKTENG_PER_TX_START 0x01
+#define WL_PKTENG_PER_TX_STOP 0x02
+#define WL_PKTENG_PER_RX_START 0x04
+#define WL_PKTENG_PER_RX_WITH_ACK_START 0x05
+#define WL_PKTENG_PER_TX_WITH_ACK_START 0x06
+#define WL_PKTENG_PER_RX_STOP 0x08
+#define WL_PKTENG_PER_MASK 0xff
+
+#define WL_PKTENG_SYNCHRONOUS 0x100 /* synchronous flag */
+
+typedef struct wl_pkteng {
+ uint32 flags;
+ uint32 delay; /* Inter-packet delay */
+ uint32 nframes; /* Number of frames */
+ uint32 length; /* Packet length */
+ uint8 seqno; /* Enable/disable sequence no. */
+ struct ether_addr dest; /* Destination address */
+ struct ether_addr src; /* Source address */
+} wl_pkteng_t;
+
+#define NUM_80211b_RATES 4
+#define NUM_80211ag_RATES 8
+#define NUM_80211n_RATES 32
+#define NUM_80211_RATES (NUM_80211b_RATES+NUM_80211ag_RATES+NUM_80211n_RATES)
+typedef struct wl_pkteng_stats {
+ uint32 lostfrmcnt; /* RX PER test: no of frames lost (skip seqno) */
+ int32 rssi; /* RSSI */
+ int32 snr; /* signal to noise ratio */
+ uint16 rxpktcnt[NUM_80211_RATES+1];
+} wl_pkteng_stats_t;
+
+
+#define WL_WOWL_MAGIC (1 << 0) /* Wakeup on Magic packet */
+#define WL_WOWL_NET (1 << 1) /* Wakeup on Netpattern */
+#define WL_WOWL_DIS (1 << 2) /* Wakeup on loss-of-link due to Disassoc/Deauth */
+#define WL_WOWL_RETR (1 << 3) /* Wakeup on retrograde TSF */
+#define WL_WOWL_BCN (1 << 4) /* Wakeup on loss of beacon */
+#define WL_WOWL_TST (1 << 5) /* Wakeup after test */
+#define WL_WOWL_M1 (1 << 6) /* Wakeup after PTK refresh */
+#define WL_WOWL_EAPID (1 << 7) /* Wakeup after receipt of EAP-Identity Req */
+#define WL_WOWL_PME_GPIO (1 << 8) /* Wakeind via PME(0) or GPIO(1) */
+#define WL_WOWL_NEEDTKIP1 (1 << 9) /* need tkip phase 1 key to be updated by the driver */
+#define WL_WOWL_GTK_FAILURE (1 << 10) /* enable wakeup if GTK fails */
+#define WL_WOWL_EXTMAGPAT (1 << 11) /* support extended magic packets */
+#define WL_WOWL_ARPOFFLOAD (1 << 12) /* support ARP/NS/keepalive offloading */
+#define WL_WOWL_WPA2 (1 << 13) /* read protocol version for EAPOL frames */
+#define WL_WOWL_KEYROT (1 << 14) /* If the bit is set, use key rotaton */
+#define WL_WOWL_BCAST (1 << 15) /* If the bit is set, frm received was bcast frame */
+
+#define MAGIC_PKT_MINLEN 102 /* Magic pkt min length is 6 * 0xFF + 16 * ETHER_ADDR_LEN */
+
+#define WOWL_PATTEN_TYPE_ARP (1 << 0) /* ARP offload Pattern */
+#define WOWL_PATTEN_TYPE_NA (1 << 1) /* NA offload Pattern */
+
+typedef struct {
+ uint32 masksize; /* Size of the mask in #of bytes */
+ uint32 offset; /* Offset to start looking for the packet in # of bytes */
+ uint32 patternoffset; /* Offset of start of pattern in the structure */
+ uint32 patternsize; /* Size of the pattern itself in #of bytes */
+ uint32 id; /* id */
+ uint32 reasonsize; /* Size of the wakeup reason code */
+ uint32 flags; /* Flags to tell the pattern type and other properties */
+ /* Mask follows the structure above */
+ /* Pattern follows the mask is at 'patternoffset' from the start */
+} wl_wowl_pattern_t;
+
+typedef struct {
+ uint count;
+ wl_wowl_pattern_t pattern[1];
+} wl_wowl_pattern_list_t;
+
+typedef struct {
+ uint8 pci_wakeind; /* Whether PCI PMECSR PMEStatus bit was set */
+ uint16 ucode_wakeind; /* What wakeup-event indication was set by ucode */
+} wl_wowl_wakeind_t;
+
+
+/* per AC rate control related data structure */
+typedef struct wl_txrate_class {
+ uint8 init_rate;
+ uint8 min_rate;
+ uint8 max_rate;
+} wl_txrate_class_t;
+
+
+
+/* Overlap BSS Scan parameters default, minimum, maximum */
+#define WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT 20 /* unit TU */
+#define WLC_OBSS_SCAN_PASSIVE_DWELL_MIN 5 /* unit TU */
+#define WLC_OBSS_SCAN_PASSIVE_DWELL_MAX 1000 /* unit TU */
+#define WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT 10 /* unit TU */
+#define WLC_OBSS_SCAN_ACTIVE_DWELL_MIN 10 /* unit TU */
+#define WLC_OBSS_SCAN_ACTIVE_DWELL_MAX 1000 /* unit TU */
+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT 300 /* unit Sec */
+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN 10 /* unit Sec */
+#define WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX 900 /* unit Sec */
+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT 5
+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN 5
+#define WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX 100
+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT 200 /* unit TU */
+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN 200 /* unit TU */
+#define WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */
+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT 20 /* unit TU */
+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN 20 /* unit TU */
+#define WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX 10000 /* unit TU */
+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT 25 /* unit percent */
+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN 0 /* unit percent */
+#define WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX 100 /* unit percent */
+
+/* structure for Overlap BSS scan arguments */
+typedef struct wl_obss_scan_arg {
+ int16 passive_dwell;
+ int16 active_dwell;
+ int16 bss_widthscan_interval;
+ int16 passive_total;
+ int16 active_total;
+ int16 chanwidth_transition_delay;
+ int16 activity_threshold;
+} wl_obss_scan_arg_t;
+
+#define WL_OBSS_SCAN_PARAM_LEN sizeof(wl_obss_scan_arg_t)
+#define WL_MIN_NUM_OBSS_SCAN_ARG 7 /* minimum number of arguments required for OBSS Scan */
+
+#define WL_COEX_INFO_MASK 0x07
+#define WL_COEX_INFO_REQ 0x01
+#define WL_COEX_40MHZ_INTOLERANT 0x02
+#define WL_COEX_WIDTH20 0x04
+
+#define WLC_RSSI_INVALID 0 /* invalid RSSI value */
+
+#define MAX_RSSI_LEVELS 8
+
+/* RSSI event notification configuration. */
+typedef struct wl_rssi_event {
+ uint32 rate_limit_msec; /* # of events posted to application will be limited to
+ * one per specified period (0 to disable rate limit).
+ */
+ uint8 num_rssi_levels; /* Number of entries in rssi_levels[] below */
+ int8 rssi_levels[MAX_RSSI_LEVELS]; /* Variable number of RSSI levels. An event
+ * will be posted each time the RSSI of received
+ * beacons/packets crosses a level.
+ */
+} wl_rssi_event_t;
+
+typedef struct wl_action_obss_coex_req {
+ uint8 info;
+ uint8 num;
+ uint8 ch_list[1];
+} wl_action_obss_coex_req_t;
+
+
+/* IOVar parameter block for small MAC address array with type indicator */
+#define WL_IOV_MAC_PARAM_LEN 4
+
+#define WL_IOV_PKTQ_LOG_PRECS 16
+
+typedef struct {
+ uint32 num_addrs;
+ char addr_type[WL_IOV_MAC_PARAM_LEN];
+ struct ether_addr ea[WL_IOV_MAC_PARAM_LEN];
+} wl_iov_mac_params_t;
+
+
+/* Parameter block for PKTQ_LOG statistics */
+typedef struct {
+ uint32 requested; /* packets requested to be stored */
+ uint32 stored; /* packets stored */
+ uint32 saved; /* packets saved,
+ because a lowest priority queue has given away one packet
+ */
+ uint32 selfsaved; /* packets saved,
+ because an older packet from the same queue has been dropped
+ */
+ uint32 full_dropped; /* packets dropped,
+ because pktq is full with higher precedence packets
+ */
+ uint32 dropped; /* packets dropped because pktq per that precedence is full */
+ uint32 sacrificed; /* packets dropped,
+ in order to save one from a queue of a highest priority
+ */
+ uint32 busy; /* packets droped because of hardware/transmission error */
+ uint32 retry; /* packets re-sent because they were not received */
+ uint32 ps_retry; /* packets retried again prior to moving power save mode */
+ uint32 retry_drop; /* packets finally dropped after retry limit */
+ uint32 max_avail; /* the high-water mark of the queue capacity for packets -
+ goes to zero as queue fills
+ */
+ uint32 max_used; /* the high-water mark of the queue utilisation for packets -
+ increases with use ('inverse' of max_avail)
+ */
+ uint32 queue_capacity; /* the maximum capacity of the queue */
+} pktq_log_counters_v01_t;
+
+#define sacrified sacrificed
+
+typedef struct {
+ uint8 num_prec[WL_IOV_MAC_PARAM_LEN];
+ pktq_log_counters_v01_t counters[WL_IOV_MAC_PARAM_LEN][WL_IOV_PKTQ_LOG_PRECS];
+ char headings[1];
+} pktq_log_format_v01_t;
+
+
+typedef struct {
+ uint32 version;
+ wl_iov_mac_params_t params;
+ union {
+ pktq_log_format_v01_t v01;
+ } pktq_log;
+} wl_iov_pktq_log_t;
+
+
+/* **** EXTLOG **** */
+#define EXTLOG_CUR_VER 0x0100
+
+#define MAX_ARGSTR_LEN 18 /* At least big enough for storing ETHER_ADDR_STR_LEN */
+
+/* log modules (bitmap) */
+#define LOG_MODULE_COMMON 0x0001
+#define LOG_MODULE_ASSOC 0x0002
+#define LOG_MODULE_EVENT 0x0004
+#define LOG_MODULE_MAX 3 /* Update when adding module */
+
+/* log levels */
+#define WL_LOG_LEVEL_DISABLE 0
+#define WL_LOG_LEVEL_ERR 1
+#define WL_LOG_LEVEL_WARN 2
+#define WL_LOG_LEVEL_INFO 3
+#define WL_LOG_LEVEL_MAX WL_LOG_LEVEL_INFO /* Update when adding level */
+
+/* flag */
+#define LOG_FLAG_EVENT 1
+
+/* log arg_type */
+#define LOG_ARGTYPE_NULL 0
+#define LOG_ARGTYPE_STR 1 /* %s */
+#define LOG_ARGTYPE_INT 2 /* %d */
+#define LOG_ARGTYPE_INT_STR 3 /* %d...%s */
+#define LOG_ARGTYPE_STR_INT 4 /* %s...%d */
+
+typedef struct wlc_extlog_cfg {
+ int max_number;
+ uint16 module; /* bitmap */
+ uint8 level;
+ uint8 flag;
+ uint16 version;
+} wlc_extlog_cfg_t;
+
+typedef struct log_record {
+ uint32 time;
+ uint16 module;
+ uint16 id;
+ uint8 level;
+ uint8 sub_unit;
+ uint8 seq_num;
+ int32 arg;
+ char str[MAX_ARGSTR_LEN];
+} log_record_t;
+
+typedef struct wlc_extlog_req {
+ uint32 from_last;
+ uint32 num;
+} wlc_extlog_req_t;
+
+typedef struct wlc_extlog_results {
+ uint16 version;
+ uint16 record_len;
+ uint32 num;
+ log_record_t logs[1];
+} wlc_extlog_results_t;
+
+typedef struct log_idstr {
+ uint16 id;
+ uint16 flag;
+ uint8 arg_type;
+ const char *fmt_str;
+} log_idstr_t;
+
+#define FMTSTRF_USER 1
+
+/* flat ID definitions
+ * New definitions HAVE TO BE ADDED at the end of the table. Otherwise, it will
+ * affect backward compatibility with pre-existing apps
+ */
+typedef enum {
+ FMTSTR_DRIVER_UP_ID = 0,
+ FMTSTR_DRIVER_DOWN_ID = 1,
+ FMTSTR_SUSPEND_MAC_FAIL_ID = 2,
+ FMTSTR_NO_PROGRESS_ID = 3,
+ FMTSTR_RFDISABLE_ID = 4,
+ FMTSTR_REG_PRINT_ID = 5,
+ FMTSTR_EXPTIME_ID = 6,
+ FMTSTR_JOIN_START_ID = 7,
+ FMTSTR_JOIN_COMPLETE_ID = 8,
+ FMTSTR_NO_NETWORKS_ID = 9,
+ FMTSTR_SECURITY_MISMATCH_ID = 10,
+ FMTSTR_RATE_MISMATCH_ID = 11,
+ FMTSTR_AP_PRUNED_ID = 12,
+ FMTSTR_KEY_INSERTED_ID = 13,
+ FMTSTR_DEAUTH_ID = 14,
+ FMTSTR_DISASSOC_ID = 15,
+ FMTSTR_LINK_UP_ID = 16,
+ FMTSTR_LINK_DOWN_ID = 17,
+ FMTSTR_RADIO_HW_OFF_ID = 18,
+ FMTSTR_RADIO_HW_ON_ID = 19,
+ FMTSTR_EVENT_DESC_ID = 20,
+ FMTSTR_PNP_SET_POWER_ID = 21,
+ FMTSTR_RADIO_SW_OFF_ID = 22,
+ FMTSTR_RADIO_SW_ON_ID = 23,
+ FMTSTR_PWD_MISMATCH_ID = 24,
+ FMTSTR_FATAL_ERROR_ID = 25,
+ FMTSTR_AUTH_FAIL_ID = 26,
+ FMTSTR_ASSOC_FAIL_ID = 27,
+ FMTSTR_IBSS_FAIL_ID = 28,
+ FMTSTR_EXTAP_FAIL_ID = 29,
+ FMTSTR_MAX_ID
+} log_fmtstr_id_t;
+
+#ifdef DONGLEOVERLAYS
+typedef struct {
+ uint32 flags_idx; /* lower 8 bits: overlay index; upper 24 bits: flags */
+ uint32 offset; /* offset into overlay region to write code */
+ uint32 len; /* overlay code len */
+ /* overlay code follows this struct */
+} wl_ioctl_overlay_t;
+
+#define OVERLAY_IDX_MASK 0x000000ff
+#define OVERLAY_IDX_SHIFT 0
+#define OVERLAY_FLAGS_MASK 0xffffff00
+#define OVERLAY_FLAGS_SHIFT 8
+/* overlay written to device memory immediately after loading the base image */
+#define OVERLAY_FLAG_POSTLOAD 0x100
+/* defer overlay download until the device responds w/WLC_E_OVL_DOWNLOAD event */
+#define OVERLAY_FLAG_DEFER_DL 0x200
+/* overlay downloaded prior to the host going to sleep */
+#define OVERLAY_FLAG_PRESLEEP 0x400
+
+#define OVERLAY_DOWNLOAD_CHUNKSIZE 1024
+#endif /* DONGLEOVERLAYS */
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* no default structure packing */
+#include <packed_section_end.h>
+
+/* require strict packing */
+#include <packed_section_start.h>
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+
+/* Structures and constants used for "vndr_ie" IOVar interface */
+#define VNDR_IE_CMD_LEN 4 /* length of the set command string:
+ * "add", "del" (+ NUL)
+ */
+
+/* 802.11 Mgmt Packet flags */
+#define VNDR_IE_BEACON_FLAG 0x1
+#define VNDR_IE_PRBRSP_FLAG 0x2
+#define VNDR_IE_ASSOCRSP_FLAG 0x4
+#define VNDR_IE_AUTHRSP_FLAG 0x8
+#define VNDR_IE_PRBREQ_FLAG 0x10
+#define VNDR_IE_ASSOCREQ_FLAG 0x20
+#define VNDR_IE_IWAPID_FLAG 0x40 /* vendor IE in IW advertisement protocol ID field */
+#define VNDR_IE_CUSTOM_FLAG 0x100 /* allow custom IE id */
+
+#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32))
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */
+ vndr_ie_t vndr_ie_data; /* vendor IE data */
+} BWL_POST_PACKED_STRUCT vndr_ie_info_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ int iecount; /* number of entries in the vndr_ie_list[] array */
+ vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */
+} BWL_POST_PACKED_STRUCT vndr_ie_buf_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NUL */
+ vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */
+} BWL_POST_PACKED_STRUCT vndr_ie_setbuf_t;
+
+/* tag_ID/length/value_buffer tuple */
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint8 id;
+ uint8 len;
+ uint8 data[1];
+} BWL_POST_PACKED_STRUCT tlv_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */
+ tlv_t ie_data; /* IE data */
+} BWL_POST_PACKED_STRUCT ie_info_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ int iecount; /* number of entries in the ie_list[] array */
+ ie_info_t ie_list[1]; /* variable size list of ie_info_t structs */
+} BWL_POST_PACKED_STRUCT ie_buf_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ char cmd[VNDR_IE_CMD_LEN]; /* ie IOVar set command : "add" + NUL */
+ ie_buf_t ie_buffer; /* buffer containing IE list information */
+} BWL_POST_PACKED_STRUCT ie_setbuf_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct {
+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */
+ uint8 id; /* IE type */
+} BWL_POST_PACKED_STRUCT ie_getbuf_t;
+
+/* structures used to define format of wps ie data from probe requests */
+/* passed up to applications via iovar "prbreq_wpsie" */
+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_hdr {
+ struct ether_addr staAddr;
+ uint16 ieLen;
+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_hdr_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_data {
+ sta_prbreq_wps_ie_hdr_t hdr;
+ uint8 ieData[1];
+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_data_t;
+
+typedef BWL_PRE_PACKED_STRUCT struct sta_prbreq_wps_ie_list {
+ uint32 totLen;
+ uint8 ieDataList[1];
+} BWL_POST_PACKED_STRUCT sta_prbreq_wps_ie_list_t;
+
+
+#ifdef WLMEDIA_TXFAILEVENT
+typedef BWL_PRE_PACKED_STRUCT struct {
+ char dest[ETHER_ADDR_LEN]; /* destination MAC */
+ uint8 prio; /* Packet Priority */
+ uint8 flags; /* Flags */
+ uint32 tsf_l; /* TSF timer low */
+ uint32 tsf_h; /* TSF timer high */
+ uint16 rates; /* Main Rates */
+ uint16 txstatus; /* TX Status */
+} BWL_POST_PACKED_STRUCT txfailinfo_t;
+#endif /* WLMEDIA_TXFAILEVENT */
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+
+/* no strict structure packing */
+#include <packed_section_end.h>
+
+#ifdef BCMWAPI_WAI
+#define IV_LEN 16 /* XXX, same as SMS4_WPI_PN_LEN */
+struct wapi_sta_msg_t
+{
+ uint16 msg_type;
+ uint16 datalen;
+ uint8 vap_mac[6];
+ uint8 reserve_data1[2];
+ uint8 sta_mac[6];
+ uint8 reserve_data2[2];
+ uint8 gsn[IV_LEN];
+ uint8 wie[256];
+};
+#endif /* BCMWAPI_WAI */
+
+#ifndef LINUX_POSTMOGRIFY_REMOVAL
+/* Global ASSERT Logging */
+#define ASSERTLOG_CUR_VER 0x0100
+#define MAX_ASSRTSTR_LEN 64
+
+typedef struct assert_record {
+ uint32 time;
+ uint8 seq_num;
+ char str[MAX_ASSRTSTR_LEN];
+} assert_record_t;
+
+typedef struct assertlog_results {
+ uint16 version;
+ uint16 record_len;
+ uint32 num;
+ assert_record_t logs[1];
+} assertlog_results_t;
+
+#define LOGRRC_FIX_LEN 8
+#define IOBUF_ALLOWED_NUM_OF_LOGREC(type, len) ((len - LOGRRC_FIX_LEN)/sizeof(type))
+
+
+/* channel interference measurement (chanim) related defines */
+
+/* chanim mode */
+#define CHANIM_DISABLE 0 /* disabled */
+#define CHANIM_DETECT 1 /* detection only */
+#define CHANIM_EXT 2 /* external state machine */
+#define CHANIM_ACT 3 /* full internal state machine, detect + act */
+#define CHANIM_MODE_MAX 4
+
+/* define for apcs reason code */
+#define APCS_INIT 0
+#define APCS_IOCTL 1
+#define APCS_CHANIM 2
+#define APCS_CSTIMER 3
+#define APCS_BTA 4
+
+/* number of ACS record entries */
+#define CHANIM_ACS_RECORD 10
+
+/* CHANIM */
+#define CCASTATS_TXDUR 0
+#define CCASTATS_INBSS 1
+#define CCASTATS_OBSS 2
+#define CCASTATS_NOCTG 3
+#define CCASTATS_NOPKT 4
+#define CCASTATS_DOZE 5
+#define CCASTATS_TXOP 6
+#define CCASTATS_GDTXDUR 7
+#define CCASTATS_BDTXDUR 8
+#define CCASTATS_MAX 9
+
+/* chanim acs record */
+typedef struct {
+ bool valid;
+ uint8 trigger;
+ chanspec_t selected_chspc;
+ int8 bgnoise;
+ uint32 glitch_cnt;
+ uint8 ccastats;
+ uint timestamp;
+} chanim_acs_record_t;
+
+typedef struct {
+ chanim_acs_record_t acs_record[CHANIM_ACS_RECORD];
+ uint8 count;
+ uint timestamp;
+} wl_acs_record_t;
+
+typedef struct chanim_stats {
+ uint32 glitchcnt; /* normalized as per second count */
+ uint32 badplcp; /* normalized as per second count */
+ uint8 ccastats[CCASTATS_MAX]; /* normalized as 0-255 */
+ int8 bgnoise; /* background noise level (in dBm) */
+ chanspec_t chanspec;
+ uint32 timestamp;
+} chanim_stats_t;
+
+#define WL_CHANIM_STATS_VERSION 1
+#define WL_CHANIM_COUNT_ALL 0xff
+#define WL_CHANIM_COUNT_ONE 0x1
+
+typedef struct {
+ uint32 buflen;
+ uint32 version;
+ uint32 count;
+ chanim_stats_t stats[1];
+} wl_chanim_stats_t;
+
+#define WL_CHANIM_STATS_FIXED_LEN OFFSETOF(wl_chanim_stats_t, stats)
+
+/* Noise measurement metrics. */
+#define NOISE_MEASURE_KNOISE 0x1
+
+/* scb probe parameter */
+typedef struct {
+ uint32 scb_timeout;
+ uint32 scb_activity_time;
+ uint32 scb_max_probe;
+} wl_scb_probe_t;
+
+/* ap tpc modes */
+#define AP_TPC_OFF 0
+#define AP_TPC_BSS_PWR 1 /* BSS power control */
+#define AP_TPC_AP_PWR 2 /* AP power control */
+#define AP_TPC_AP_BSS_PWR 3 /* Both AP and BSS power control */
+#define AP_TPC_MAX_LINK_MARGIN 127
+
+/* ap tpc modes */
+#define AP_TPC_OFF 0
+#define AP_TPC_BSS_PWR 1 /* BSS power control */
+#define AP_TPC_AP_PWR 2 /* AP power control */
+#define AP_TPC_AP_BSS_PWR 3 /* Both AP and BSS power control */
+#define AP_TPC_MAX_LINK_MARGIN 127
+
+/* structure/defines for selective mgmt frame (smf) stats support */
+
+#define SMFS_VERSION 1
+/* selected mgmt frame (smf) stats element */
+typedef struct wl_smfs_elem {
+ uint32 count;
+ uint16 code; /* SC or RC code */
+} wl_smfs_elem_t;
+
+typedef struct wl_smf_stats {
+ uint32 version;
+ uint16 length; /* reserved for future usage */
+ uint8 type;
+ uint8 codetype;
+ uint32 ignored_cnt;
+ uint32 malformed_cnt;
+ uint32 count_total; /* count included the interested group */
+ wl_smfs_elem_t elem[1];
+} wl_smf_stats_t;
+
+#define WL_SMFSTATS_FIXED_LEN OFFSETOF(wl_smf_stats_t, elem);
+
+enum {
+ SMFS_CODETYPE_SC,
+ SMFS_CODETYPE_RC
+};
+
+/* reuse two number in the sc/rc space */
+#define SMFS_CODE_MALFORMED 0xFFFE
+#define SMFS_CODE_IGNORED 0xFFFD
+
+typedef enum smfs_type {
+ SMFS_TYPE_AUTH,
+ SMFS_TYPE_ASSOC,
+ SMFS_TYPE_REASSOC,
+ SMFS_TYPE_DISASSOC_TX,
+ SMFS_TYPE_DISASSOC_RX,
+ SMFS_TYPE_DEAUTH_TX,
+ SMFS_TYPE_DEAUTH_RX,
+ SMFS_TYPE_MAX
+} smfs_type_t;
+
+#ifdef PHYMON
+
+#define PHYMON_VERSION 1
+
+typedef struct wl_phycal_core_state {
+ /* Tx IQ/LO calibration coeffs */
+ int16 tx_iqlocal_a;
+ int16 tx_iqlocal_b;
+ int8 tx_iqlocal_ci;
+ int8 tx_iqlocal_cq;
+ int8 tx_iqlocal_di;
+ int8 tx_iqlocal_dq;
+ int8 tx_iqlocal_ei;
+ int8 tx_iqlocal_eq;
+ int8 tx_iqlocal_fi;
+ int8 tx_iqlocal_fq;
+
+ /* Rx IQ calibration coeffs */
+ int16 rx_iqcal_a;
+ int16 rx_iqcal_b;
+
+ uint8 tx_iqlocal_pwridx; /* Tx Power Index for Tx IQ/LO calibration */
+ uint32 papd_epsilon_table[64]; /* PAPD epsilon table */
+ int16 papd_epsilon_offset; /* PAPD epsilon offset */
+ uint8 curr_tx_pwrindex; /* Tx power index */
+ int8 idle_tssi; /* Idle TSSI */
+ int8 est_tx_pwr; /* Estimated Tx Power (dB) */
+ int8 est_rx_pwr; /* Estimated Rx Power (dB) from RSSI */
+ uint16 rx_gaininfo; /* Rx gain applied on last Rx pkt */
+ uint16 init_gaincode; /* initgain required for ACI */
+ int8 estirr_tx;
+ int8 estirr_rx;
+
+} wl_phycal_core_state_t;
+
+typedef struct wl_phycal_state {
+ int version;
+ int8 num_phy_cores; /* number of cores */
+ int8 curr_temperature; /* on-chip temperature sensor reading */
+ chanspec_t chspec; /* channspec for this state */
+ bool aci_state; /* ACI state: ON/OFF */
+ uint16 crsminpower; /* crsminpower required for ACI */
+ uint16 crsminpowerl; /* crsminpowerl required for ACI */
+ uint16 crsminpoweru; /* crsminpoweru required for ACI */
+ wl_phycal_core_state_t phycal_core[1];
+} wl_phycal_state_t;
+
+#define WL_PHYCAL_STAT_FIXED_LEN OFFSETOF(wl_phycal_state_t, phycal_core)
+#endif /* PHYMON */
+
+/* discovery state */
+typedef struct wl_p2p_disc_st {
+ uint8 state; /* see state */
+ chanspec_t chspec; /* valid in listen state */
+ uint16 dwell; /* valid in listen state, in ms */
+} wl_p2p_disc_st_t;
+
+/* state */
+#define WL_P2P_DISC_ST_SCAN 0
+#define WL_P2P_DISC_ST_LISTEN 1
+#define WL_P2P_DISC_ST_SEARCH 2
+
+/* scan request */
+typedef struct wl_p2p_scan {
+ uint8 type; /* 'S' for WLC_SCAN, 'E' for "escan" */
+ uint8 reserved[3];
+ /* scan or escan parms... */
+} wl_p2p_scan_t;
+
+/* i/f request */
+typedef struct wl_p2p_if {
+ struct ether_addr addr;
+ uint8 type; /* see i/f type */
+ chanspec_t chspec; /* for p2p_ifadd GO */
+} wl_p2p_if_t;
+
+/* i/f type */
+#define WL_P2P_IF_CLIENT 0
+#define WL_P2P_IF_GO 1
+#define WL_P2P_IF_DYNBCN_GO 2
+#define WL_P2P_IF_DEV 3
+
+/* i/f query */
+typedef struct wl_p2p_ifq {
+ uint bsscfgidx;
+ char ifname[BCM_MSG_IFNAME_MAX];
+} wl_p2p_ifq_t;
+
+/* OppPS & CTWindow */
+typedef struct wl_p2p_ops {
+ uint8 ops; /* 0: disable 1: enable */
+ uint8 ctw; /* >= 10 */
+} wl_p2p_ops_t;
+
+/* absence and presence request */
+typedef struct wl_p2p_sched_desc {
+ uint32 start;
+ uint32 interval;
+ uint32 duration;
+ uint32 count; /* see count */
+} wl_p2p_sched_desc_t;
+
+/* count */
+#define WL_P2P_SCHED_RSVD 0
+#define WL_P2P_SCHED_REPEAT 255 /* anything > 255 will be treated as 255 */
+
+typedef struct wl_p2p_sched {
+ uint8 type; /* see schedule type */
+ uint8 action; /* see schedule action */
+ uint8 option; /* see schedule option */
+ wl_p2p_sched_desc_t desc[1];
+} wl_p2p_sched_t;
+#define WL_P2P_SCHED_FIXED_LEN 3
+
+/* schedule type */
+#define WL_P2P_SCHED_TYPE_ABS 0 /* Scheduled Absence */
+#define WL_P2P_SCHED_TYPE_REQ_ABS 1 /* Requested Absence */
+
+/* schedule action during absence periods (for WL_P2P_SCHED_ABS type) */
+#define WL_P2P_SCHED_ACTION_NONE 0 /* no action */
+#define WL_P2P_SCHED_ACTION_DOZE 1 /* doze */
+/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */
+#define WL_P2P_SCHED_ACTION_GOOFF 2 /* turn off GO beacon/prbrsp functions */
+/* schedule option - WL_P2P_SCHED_TYPE_XXX */
+#define WL_P2P_SCHED_ACTION_RESET 255 /* reset */
+
+/* schedule option - WL_P2P_SCHED_TYPE_ABS */
+#define WL_P2P_SCHED_OPTION_NORMAL 0 /* normal start/interval/duration/count */
+#define WL_P2P_SCHED_OPTION_BCNPCT 1 /* percentage of beacon interval */
+/* schedule option - WL_P2P_SCHED_TYPE_REQ_ABS */
+#define WL_P2P_SCHED_OPTION_TSFOFS 2 /* normal start/internal/duration/count with
+ * start being an offset of the 'current' TSF
+ */
+
+/* feature flags */
+#define WL_P2P_FEAT_GO_CSA (1 << 0) /* GO moves with the STA using CSA method */
+#define WL_P2P_FEAT_GO_NOLEGACY (1 << 1) /* GO does not probe respond to non-p2p probe
+ * requests
+ */
+#define WL_P2P_FEAT_RESTRICT_DEV_RESP (1 << 2) /* Restrict p2p dev interface from responding */
+
+#ifdef WLNIC
+/* nic_cnx iovar */
+typedef struct wl_nic_cnx {
+ uint8 opcode;
+ struct ether_addr addr;
+ /* the following are valid for WL_NIC_CNX_CONN */
+ uint8 SSID_len;
+ uint8 SSID[32];
+ struct ether_addr abssid;
+ uint8 join_period;
+} wl_nic_cnx_t;
+
+/* opcode */
+#define WL_NIC_CNX_ADD 0 /* add NIC connection */
+#define WL_NIC_CNX_DEL 1 /* delete NIC connection */
+#define WL_NIC_CNX_IDX 2 /* query NIC connection index */
+#define WL_NIC_CNX_CONN 3 /* join/create network */
+#define WL_NIC_CNX_DIS 4 /* disconnect from network */
+
+/* nic_cfg iovar */
+typedef struct wl_nic_cfg {
+ uint8 version;
+ uint8 beacon_mode;
+ uint16 beacon_interval;
+ uint8 diluted_beacon_period;
+ uint8 repeat_EQC;
+ uint8 scan_length;
+ uint8 scan_interval;
+ uint8 scan_probability;
+ uint8 awake_window_length;
+ int8 TSF_correction;
+ uint8 ASID;
+ uint8 channel_usage_mode;
+} wl_nic_cfg_t;
+
+/* version */
+#define WL_NIC_CFG_VER 1
+
+/* beacon_mode */
+#define WL_NIC_BCN_NORM 0
+#define WL_NIC_BCN_DILUTED 1
+
+/* channel_usage_mode */
+#define WL_NIC_CHAN_STATIC 0
+#define WL_NIC_CHAN_CYCLE 1
+
+/* nic_cfg iovar */
+typedef struct wl_nic_frm {
+ uint8 type;
+ struct ether_addr da;
+ uint8 body[1];
+} wl_nic_frm_t;
+
+/* type */
+#define WL_NIC_FRM_MYNET 1
+#define WL_NIC_FRM_ACTION 2
+
+/* i/f query */
+typedef struct wl_nic_ifq {
+ uint bsscfgidx;
+ char ifname[BCM_MSG_IFNAME_MAX];
+} wl_nic_ifq_t;
+
+/* data mode */
+/* nic_dm iovar */
+typedef struct wl_nic_dm {
+ uint8 enab;
+ chanspec_t chspec;
+} wl_nic_dm_t;
+#endif /* WLNIC */
+
+/* RFAWARE def */
+#define BCM_ACTION_RFAWARE 0x77
+#define BCM_ACTION_RFAWARE_DCS 0x01
+
+/* DCS reason code define */
+#define BCM_DCS_IOVAR 0x1
+#define BCM_DCS_UNKNOWN 0xFF
+
+typedef struct wl_bcmdcs_data {
+ uint reason;
+ chanspec_t chspec;
+} wl_bcmdcs_data_t;
+
+/* n-mode support capability */
+/* 2x2 includes both 1x1 & 2x2 devices
+ * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
+ * control it independently
+ */
+#define WL_11N_2x2 1
+#define WL_11N_3x3 3
+#define WL_11N_4x4 4
+
+/* define 11n feature disable flags */
+#define WLFEATURE_DISABLE_11N 0x00000001
+#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002
+#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004
+#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008
+#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010
+#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020
+#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040
+#define WLFEATURE_DISABLE_11N_GF 0x00000080
+
+/* Proxy STA modes */
+#define PSTA_MODE_DISABLED 0
+#define PSTA_MODE_PROXY 1
+#define PSTA_MODE_REPEATER 2
+
+
+/* NAT configuration */
+typedef struct {
+ uint32 ipaddr; /* interface ip address */
+ uint32 ipaddr_mask; /* interface ip address mask */
+ uint32 ipaddr_gateway; /* gateway ip address */
+ uint8 mac_gateway[6]; /* gateway mac address */
+ uint32 ipaddr_dns; /* DNS server ip address, valid only for public if */
+ uint8 mac_dns[6]; /* DNS server mac address, valid only for public if */
+ uint8 GUID[38]; /* interface GUID */
+} nat_if_info_t;
+
+typedef struct {
+ uint op; /* operation code */
+ bool pub_if; /* set for public if, clear for private if */
+ nat_if_info_t if_info; /* interface info */
+} nat_cfg_t;
+
+/* op code in nat_cfg */
+#define NAT_OP_ENABLE 1 /* enable NAT on given interface */
+#define NAT_OP_DISABLE 2 /* disable NAT on given interface */
+#define NAT_OP_DISABLE_ALL 3 /* disable NAT on all interfaces */
+
+/* NAT state */
+#define NAT_STATE_ENABLED 1 /* NAT is enabled */
+#define NAT_STATE_DISABLED 2 /* NAT is disabled */
+
+typedef struct {
+ int state; /* NAT state returned */
+} nat_state_t;
+
+#ifdef PROP_TXSTATUS
+/* Bit definitions for tlv iovar */
+/*
+ * enable RSSI signals:
+ * WLFC_CTL_TYPE_RSSI
+ */
+#define WLFC_FLAGS_RSSI_SIGNALS 0x0001
+
+/* enable (if/mac_open, if/mac_close,, mac_add, mac_del) signals:
+ *
+ * WLFC_CTL_TYPE_MAC_OPEN
+ * WLFC_CTL_TYPE_MAC_CLOSE
+ *
+ * WLFC_CTL_TYPE_INTERFACE_OPEN
+ * WLFC_CTL_TYPE_INTERFACE_CLOSE
+ *
+ * WLFC_CTL_TYPE_MACDESC_ADD
+ * WLFC_CTL_TYPE_MACDESC_DEL
+ *
+ */
+#define WLFC_FLAGS_XONXOFF_SIGNALS 0x0002
+
+/* enable (status, fifo_credit, mac_credit) signals
+ * WLFC_CTL_TYPE_MAC_REQUEST_CREDIT
+ * WLFC_CTL_TYPE_TXSTATUS
+ * WLFC_CTL_TYPE_FIFO_CREDITBACK
+ */
+#define WLFC_FLAGS_CREDIT_STATUS_SIGNALS 0x0004
+
+#define WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE 0x0008
+#define WLFC_FLAGS_PSQ_GENERATIONFSM_ENABLE 0x0010
+#define WLFC_FLAGS_PSQ_ZERO_BUFFER_ENABLE 0x0020
+#define WLFC_FLAGS_HOST_RXRERODER_ACTIVE 0x0040
+#endif /* PROP_TXSTATUS */
+
+#define BTA_STATE_LOG_SZ 64
+
+/* BTAMP Statemachine states */
+enum {
+ HCIReset = 1,
+ HCIReadLocalAMPInfo,
+ HCIReadLocalAMPASSOC,
+ HCIWriteRemoteAMPASSOC,
+ HCICreatePhysicalLink,
+ HCIAcceptPhysicalLinkRequest,
+ HCIDisconnectPhysicalLink,
+ HCICreateLogicalLink,
+ HCIAcceptLogicalLink,
+ HCIDisconnectLogicalLink,
+ HCILogicalLinkCancel,
+ HCIAmpStateChange,
+ HCIWriteLogicalLinkAcceptTimeout
+};
+
+typedef struct flush_txfifo {
+ uint32 txfifobmp;
+ uint32 hwtxfifoflush;
+ struct ether_addr ea;
+} flush_txfifo_t;
+
+#define CHANNEL_5G_LOW_START 36 /* 5G low (36..48) CDD enable/disable bit mask */
+#define CHANNEL_5G_MID_START 52 /* 5G mid (52..64) CDD enable/disable bit mask */
+#define CHANNEL_5G_HIGH_START 100 /* 5G high (100..140) CDD enable/disable bit mask */
+#define CHANNEL_5G_UPPER_START 149 /* 5G upper (149..161) CDD enable/disable bit mask */
+
+enum {
+ SPATIAL_MODE_2G_IDX = 0,
+ SPATIAL_MODE_5G_LOW_IDX,
+ SPATIAL_MODE_5G_MID_IDX,
+ SPATIAL_MODE_5G_HIGH_IDX,
+ SPATIAL_MODE_5G_UPPER_IDX,
+ SPATIAL_MODE_MAX_IDX
+};
+
+/* IOVAR "mempool" parameter. Used to retrieve a list of memory pool statistics. */
+typedef struct wl_mempool_stats {
+ int num; /* Number of memory pools */
+ bcm_mp_stats_t s[1]; /* Variable array of memory pool stats. */
+} wl_mempool_stats_t;
+
+
+/* D0 Coalescing */
+#define IPV4_ARP_FILTER 0x0001
+#define IPV4_NETBT_FILTER 0x0002
+#define IPV4_LLMNR_FILTER 0x0004
+#define IPV4_SSDP_FILTER 0x0008
+#define IPV4_WSD_FILTER 0x0010
+#define IPV6_NETBT_FILTER 0x0200
+#define IPV6_LLMNR_FILTER 0x0400
+#define IPV6_SSDP_FILTER 0x0800
+#define IPV6_WSD_FILTER 0x1000
+
+/* Network Offload Engine */
+#define NWOE_OL_ENABLE 0x00000001
+
+typedef struct {
+ uint32 ipaddr;
+ uint32 ipaddr_netmask;
+ uint32 ipaddr_gateway;
+} nwoe_ifconfig_t;
+
+/*
+ * Traffic management structures/defines.
+ */
+
+/* Traffic management bandwidth parameters */
+#define TRF_MGMT_MAX_PRIORITIES 3
+
+#define TRF_MGMT_FLAG_ADD_DSCP 0x0001 /* Add DSCP to IP TOS field */
+#define TRF_MGMT_FLAG_DISABLE_SHAPING 0x0002 /* Only support traffic clasification */
+#define TRF_MGMT_FLAG_DISABLE_PRIORITY_TAGGING 0x0004 /* Don't override packet's priority */
+
+/* Traffic management priority classes */
+typedef enum trf_mgmt_priority_class {
+ trf_mgmt_priority_low = 0, /* Maps to 802.1p BO */
+ trf_mgmt_priority_medium = 1, /* Maps to 802.1p BE */
+ trf_mgmt_priority_high = 2, /* Maps to 802.1p VI */
+ trf_mgmt_priority_invalid = (trf_mgmt_priority_high + 1)
+} trf_mgmt_priority_class_t;
+
+/* Traffic management configuration parameters */
+typedef struct trf_mgmt_config {
+ uint32 trf_mgmt_enabled; /* 0 - disabled, 1 - enabled */
+ uint32 flags; /* See TRF_MGMT_FLAG_xxx defines */
+ uint32 host_ip_addr; /* My IP address to determine subnet */
+ uint32 host_subnet_mask; /* My subnet mask */
+ uint32 downlink_bandwidth; /* In units of kbps */
+ uint32 uplink_bandwidth; /* In units of kbps */
+ uint32 min_tx_bandwidth[TRF_MGMT_MAX_PRIORITIES]; /* Minimum guaranteed tx bandwidth */
+ uint32 min_rx_bandwidth[TRF_MGMT_MAX_PRIORITIES]; /* Minimum guaranteed rx bandwidth */
+} trf_mgmt_config_t;
+
+/* Traffic management filter */
+typedef struct trf_mgmt_filter {
+ struct ether_addr dst_ether_addr; /* His L2 address */
+ uint32 dst_ip_addr; /* His IP address */
+ uint16 dst_port; /* His L4 port */
+ uint16 src_port; /* My L4 port */
+ uint16 prot; /* L4 protocol (only TCP or UDP) */
+ uint16 flags; /* TBD. For now, this must be zero. */
+ trf_mgmt_priority_class_t priority; /* Priority for filtered packets */
+} trf_mgmt_filter_t;
+
+/* Traffic management filter list (variable length) */
+typedef struct trf_mgmt_filter_list {
+ uint32 num_filters;
+ trf_mgmt_filter_t filter[1];
+} trf_mgmt_filter_list_t;
+
+/* Traffic management global info used for all queues */
+typedef struct trf_mgmt_global_info {
+ uint32 maximum_bytes_per_second;
+ uint32 maximum_bytes_per_sampling_period;
+ uint32 total_bytes_consumed_per_second;
+ uint32 total_bytes_consumed_per_sampling_period;
+ uint32 total_unused_bytes_per_sampling_period;
+} trf_mgmt_global_info_t;
+
+/* Traffic management shaping info per priority queue */
+typedef struct trf_mgmt_shaping_info {
+ uint32 gauranteed_bandwidth_percentage;
+ uint32 guaranteed_bytes_per_second;
+ uint32 guaranteed_bytes_per_sampling_period;
+ uint32 num_bytes_produced_per_second;
+ uint32 num_bytes_consumed_per_second;
+ uint32 num_queued_packets; /* Number of packets in queue */
+ uint32 num_queued_bytes; /* Number of bytes in queue */
+} trf_mgmt_shaping_info_t;
+
+/* Traffic management shaping info array */
+typedef struct trf_mgmt_shaping_info_array {
+ trf_mgmt_global_info_t tx_global_shaping_info;
+ trf_mgmt_shaping_info_t tx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES];
+ trf_mgmt_global_info_t rx_global_shaping_info;
+ trf_mgmt_shaping_info_t rx_queue_shaping_info[TRF_MGMT_MAX_PRIORITIES];
+} trf_mgmt_shaping_info_array_t;
+
+
+/* Traffic management statistical counters */
+typedef struct trf_mgmt_stats {
+ uint32 num_processed_packets; /* Number of packets processed */
+ uint32 num_processed_bytes; /* Number of bytes processed */
+ uint32 num_discarded_packets; /* Number of packets discarded from queue */
+} trf_mgmt_stats_t;
+
+/* Traffic management statisics array */
+typedef struct trf_mgmt_stats_array {
+ trf_mgmt_stats_t tx_queue_stats[TRF_MGMT_MAX_PRIORITIES];
+ trf_mgmt_stats_t rx_queue_stats[TRF_MGMT_MAX_PRIORITIES];
+} trf_mgmt_stats_array_t;
+
+typedef struct powersel_params {
+ /* LPC Params exposed via IOVAR */
+ int32 tp_ratio_thresh; /* Throughput ratio threshold */
+ uint8 rate_stab_thresh; /* Thresh for rate stability based on nupd */
+ uint8 pwr_stab_thresh; /* Number of successes before power step down */
+ uint8 pwr_sel_exp_time; /* Time lapse for expiry of database */
+} powersel_params_t;
+
+#endif /* LINUX_POSTMOGRIFY_REMOVAL */
+#endif /* _wlioctl_h_ */
diff --git a/drivers/net/wireless/ap6210/linux_osl.c b/drivers/net/wireless/ap6210/linux_osl.c
new file mode 100644
index 0000000..d74eee3
--- /dev/null
+++ b/drivers/net/wireless/ap6210/linux_osl.c
@@ -0,0 +1,1138 @@
+/*
+ * Linux OS Independent Layer
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: linux_osl.c 373382 2012-12-07 07:59:52Z $
+ */
+
+#define LINUX_PORT
+
+#include <typedefs.h>
+#include <bcmendian.h>
+#include <linuxver.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <linux/delay.h>
+#include <pcicfg.h>
+
+
+#include <linux/fs.h>
+
+#define PCI_CFG_RETRY 10
+
+#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognize osh */
+#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */
+
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+#define DHD_SKB_HDRSIZE 336
+#define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)
+
+#define STATIC_BUF_MAX_NUM 16
+#define STATIC_BUF_SIZE (PAGE_SIZE*2)
+#define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
+
+typedef struct bcm_static_buf {
+ struct semaphore static_sem;
+ unsigned char *buf_ptr;
+ unsigned char buf_use[STATIC_BUF_MAX_NUM];
+} bcm_static_buf_t;
+
+static bcm_static_buf_t *bcm_static_buf = 0;
+
+#define STATIC_PKT_MAX_NUM 8
+#if defined(ENHANCED_STATIC_BUF)
+#define STATIC_PKT_4PAGE_NUM 1
+#define DHD_SKB_MAX_BUFSIZE DHD_SKB_4PAGE_BUFSIZE
+#else
+#define STATIC_PKT_4PAGE_NUM 0
+#define DHD_SKB_MAX_BUFSIZE DHD_SKB_2PAGE_BUFSIZE
+#endif /* ENHANCED_STATIC_BUF */
+
+typedef struct bcm_static_pkt {
+ struct sk_buff *skb_4k[STATIC_PKT_MAX_NUM];
+ struct sk_buff *skb_8k[STATIC_PKT_MAX_NUM];
+#ifdef ENHANCED_STATIC_BUF
+ struct sk_buff *skb_16k;
+#endif
+ struct semaphore osl_pkt_sem;
+ unsigned char pkt_use[STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM];
+} bcm_static_pkt_t;
+
+static bcm_static_pkt_t *bcm_static_skb = 0;
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+
+typedef struct bcm_mem_link {
+ struct bcm_mem_link *prev;
+ struct bcm_mem_link *next;
+ uint size;
+ int line;
+ void *osh;
+ char file[BCM_MEM_FILENAME_LEN];
+} bcm_mem_link_t;
+
+struct osl_info {
+ osl_pubinfo_t pub;
+#ifdef CTFPOOL
+ ctfpool_t *ctfpool;
+#endif /* CTFPOOL */
+ uint magic;
+ void *pdev;
+ atomic_t malloced;
+ uint failed;
+ uint bustype;
+ bcm_mem_link_t *dbgmem_list;
+ spinlock_t dbgmem_lock;
+ spinlock_t pktalloc_lock;
+};
+
+/* PCMCIA attribute space access macros */
+
+/* Global ASSERT type flag */
+uint32 g_assert_type = FALSE;
+
+static int16 linuxbcmerrormap[] =
+{ 0, /* 0 */
+ -EINVAL, /* BCME_ERROR */
+ -EINVAL, /* BCME_BADARG */
+ -EINVAL, /* BCME_BADOPTION */
+ -EINVAL, /* BCME_NOTUP */
+ -EINVAL, /* BCME_NOTDOWN */
+ -EINVAL, /* BCME_NOTAP */
+ -EINVAL, /* BCME_NOTSTA */
+ -EINVAL, /* BCME_BADKEYIDX */
+ -EINVAL, /* BCME_RADIOOFF */
+ -EINVAL, /* BCME_NOTBANDLOCKED */
+ -EINVAL, /* BCME_NOCLK */
+ -EINVAL, /* BCME_BADRATESET */
+ -EINVAL, /* BCME_BADBAND */
+ -E2BIG, /* BCME_BUFTOOSHORT */
+ -E2BIG, /* BCME_BUFTOOLONG */
+ -EBUSY, /* BCME_BUSY */
+ -EINVAL, /* BCME_NOTASSOCIATED */
+ -EINVAL, /* BCME_BADSSIDLEN */
+ -EINVAL, /* BCME_OUTOFRANGECHAN */
+ -EINVAL, /* BCME_BADCHAN */
+ -EFAULT, /* BCME_BADADDR */
+ -ENOMEM, /* BCME_NORESOURCE */
+ -EOPNOTSUPP, /* BCME_UNSUPPORTED */
+ -EMSGSIZE, /* BCME_BADLENGTH */
+ -EINVAL, /* BCME_NOTREADY */
+ -EPERM, /* BCME_EPERM */
+ -ENOMEM, /* BCME_NOMEM */
+ -EINVAL, /* BCME_ASSOCIATED */
+ -ERANGE, /* BCME_RANGE */
+ -EINVAL, /* BCME_NOTFOUND */
+ -EINVAL, /* BCME_WME_NOT_ENABLED */
+ -EINVAL, /* BCME_TSPEC_NOTFOUND */
+ -EINVAL, /* BCME_ACM_NOTSUPPORTED */
+ -EINVAL, /* BCME_NOT_WME_ASSOCIATION */
+ -EIO, /* BCME_SDIO_ERROR */
+ -ENODEV, /* BCME_DONGLE_DOWN */
+ -EINVAL, /* BCME_VERSION */
+ -EIO, /* BCME_TXFAIL */
+ -EIO, /* BCME_RXFAIL */
+ -ENODEV, /* BCME_NODEVICE */
+ -EINVAL, /* BCME_NMODE_DISABLED */
+ -ENODATA, /* BCME_NONRESIDENT */
+
+/* When an new error code is added to bcmutils.h, add os
+ * specific error translation here as well
+ */
+/* check if BCME_LAST changed since the last time this function was updated */
+#if BCME_LAST != -42
+#error "You need to add a OS error translation in the linuxbcmerrormap \
+ for new error code defined in bcmutils.h"
+#endif
+};
+
+/* translate bcmerrors into linux errors */
+int
+osl_error(int bcmerror)
+{
+ if (bcmerror > 0)
+ bcmerror = 0;
+ else if (bcmerror < BCME_LAST)
+ bcmerror = BCME_ERROR;
+
+ /* Array bounds covered by ASSERT in osl_attach */
+ return linuxbcmerrormap[-bcmerror];
+}
+
+extern uint8* dhd_os_prealloc(void *osh, int section, int size);
+
+osl_t *
+osl_attach(void *pdev, uint bustype, bool pkttag)
+{
+ osl_t *osh;
+
+ if (!(osh = kmalloc(sizeof(osl_t), GFP_ATOMIC)))
+ return osh;
+
+ ASSERT(osh);
+
+ bzero(osh, sizeof(osl_t));
+
+ /* Check that error map has the right number of entries in it */
+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1));
+
+ osh->magic = OS_HANDLE_MAGIC;
+ atomic_set(&osh->malloced, 0);
+ osh->failed = 0;
+ osh->dbgmem_list = NULL;
+ spin_lock_init(&(osh->dbgmem_lock));
+ osh->pdev = pdev;
+ osh->pub.pkttag = pkttag;
+ osh->bustype = bustype;
+
+ switch (bustype) {
+ case PCI_BUS:
+ case SI_BUS:
+ case PCMCIA_BUS:
+ osh->pub.mmbus = TRUE;
+ break;
+ case JTAG_BUS:
+ case SDIO_BUS:
+ case USB_BUS:
+ case SPI_BUS:
+ case RPC_BUS:
+ osh->pub.mmbus = FALSE;
+ break;
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
+ if (!bcm_static_buf) {
+ if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+
+ STATIC_BUF_TOTAL_LEN))) {
+ AP6210_DEBUG("can not alloc static buf!\n");
+ }
+ else
+ AP6210_DEBUG("alloc static buf at %x!\n", (unsigned int)bcm_static_buf);
+
+
+ sema_init(&bcm_static_buf->static_sem, 1);
+
+ bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE;
+ }
+
+ if (!bcm_static_skb) {
+ int i;
+ void *skb_buff_ptr = 0;
+ bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048);
+ skb_buff_ptr = dhd_os_prealloc(osh, 4, 0);
+
+ bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)*
+ (STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM));
+ for (i = 0; i < (STATIC_PKT_MAX_NUM * 2 + STATIC_PKT_4PAGE_NUM); i++)
+ bcm_static_skb->pkt_use[i] = 0;
+
+ sema_init(&bcm_static_skb->osl_pkt_sem, 1);
+ }
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+
+ spin_lock_init(&(osh->pktalloc_lock));
+
+ return osh;
+}
+
+void
+osl_detach(osl_t *osh)
+{
+ if (osh == NULL)
+ return;
+
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+ if (bcm_static_buf) {
+ bcm_static_buf = 0;
+ }
+ if (bcm_static_skb) {
+ bcm_static_skb = 0;
+ }
+#endif
+
+ ASSERT(osh->magic == OS_HANDLE_MAGIC);
+ kfree(osh);
+}
+
+static struct sk_buff *osl_alloc_skb(unsigned int len)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+ return __dev_alloc_skb(len, GFP_ATOMIC);
+#else
+ return dev_alloc_skb(len);
+#endif
+}
+
+#ifdef CTFPOOL
+
+#ifdef CTFPOOL_SPINLOCK
+#define CTFPOOL_LOCK(ctfpool, flags) spin_lock_irqsave(&(ctfpool)->lock, flags)
+#define CTFPOOL_UNLOCK(ctfpool, flags) spin_unlock_irqrestore(&(ctfpool)->lock, flags)
+#else
+#define CTFPOOL_LOCK(ctfpool, flags) spin_lock_bh(&(ctfpool)->lock)
+#define CTFPOOL_UNLOCK(ctfpool, flags) spin_unlock_bh(&(ctfpool)->lock)
+#endif /* CTFPOOL_SPINLOCK */
+/*
+ * Allocate and add an object to packet pool.
+ */
+void *
+osl_ctfpool_add(osl_t *osh)
+{
+ struct sk_buff *skb;
+#ifdef CTFPOOL_SPINLOCK
+ unsigned long flags;
+#endif /* CTFPOOL_SPINLOCK */
+
+ if ((osh == NULL) || (osh->ctfpool == NULL))
+ return NULL;
+
+ CTFPOOL_LOCK(osh->ctfpool, flags);
+ ASSERT(osh->ctfpool->curr_obj <= osh->ctfpool->max_obj);
+
+ /* No need to allocate more objects */
+ if (osh->ctfpool->curr_obj == osh->ctfpool->max_obj) {
+ CTFPOOL_UNLOCK(osh->ctfpool, flags);
+ return NULL;
+ }
+
+ /* Allocate a new skb and add it to the ctfpool */
+ skb = osl_alloc_skb(osh->ctfpool->obj_size);
+ if (skb == NULL) {
+ AP6210_DEBUG("%s: skb alloc of len %d failed\n", __FUNCTION__,
+ osh->ctfpool->obj_size);
+ CTFPOOL_UNLOCK(osh->ctfpool, flags);
+ return NULL;
+ }
+
+ /* Add to ctfpool */
+ skb->next = (struct sk_buff *)osh->ctfpool->head;
+ osh->ctfpool->head = skb;
+ osh->ctfpool->fast_frees++;
+ osh->ctfpool->curr_obj++;
+
+ /* Hijack a skb member to store ptr to ctfpool */
+ CTFPOOLPTR(osh, skb) = (void *)osh->ctfpool;
+
+ /* Use bit flag to indicate skb from fast ctfpool */
+ PKTFAST(osh, skb) = FASTBUF;
+
+ CTFPOOL_UNLOCK(osh->ctfpool, flags);
+
+ return skb;
+}
+
+/*
+ * Add new objects to the pool.
+ */
+void
+osl_ctfpool_replenish(osl_t *osh, uint thresh)
+{
+ if ((osh == NULL) || (osh->ctfpool == NULL))
+ return;
+
+ /* Do nothing if no refills are required */
+ while ((osh->ctfpool->refills > 0) && (thresh--)) {
+ osl_ctfpool_add(osh);
+ osh->ctfpool->refills--;
+ }
+}
+
+/*
+ * Initialize the packet pool with specified number of objects.
+ */
+int32
+osl_ctfpool_init(osl_t *osh, uint numobj, uint size)
+{
+ osh->ctfpool = kmalloc(sizeof(ctfpool_t), GFP_ATOMIC);
+ ASSERT(osh->ctfpool);
+ bzero(osh->ctfpool, sizeof(ctfpool_t));
+
+ osh->ctfpool->max_obj = numobj;
+ osh->ctfpool->obj_size = size;
+
+ spin_lock_init(&osh->ctfpool->lock);
+
+ while (numobj--) {
+ if (!osl_ctfpool_add(osh))
+ return -1;
+ osh->ctfpool->fast_frees--;
+ }
+
+ return 0;
+}
+
+/*
+ * Cleanup the packet pool objects.
+ */
+void
+osl_ctfpool_cleanup(osl_t *osh)
+{
+ struct sk_buff *skb, *nskb;
+#ifdef CTFPOOL_SPINLOCK
+ unsigned long flags;
+#endif /* CTFPOOL_SPINLOCK */
+
+ if ((osh == NULL) || (osh->ctfpool == NULL))
+ return;
+
+ CTFPOOL_LOCK(osh->ctfpool, flags);
+
+ skb = osh->ctfpool->head;
+
+ while (skb != NULL) {
+ nskb = skb->next;
+ dev_kfree_skb(skb);
+ skb = nskb;
+ osh->ctfpool->curr_obj--;
+ }
+
+ ASSERT(osh->ctfpool->curr_obj == 0);
+ osh->ctfpool->head = NULL;
+ CTFPOOL_UNLOCK(osh->ctfpool, flags);
+
+ kfree(osh->ctfpool);
+ osh->ctfpool = NULL;
+}
+
+void
+osl_ctfpool_stats(osl_t *osh, void *b)
+{
+ struct bcmstrbuf *bb;
+
+ if ((osh == NULL) || (osh->ctfpool == NULL))
+ return;
+
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+ if (bcm_static_buf) {
+ bcm_static_buf = 0;
+ }
+ if (bcm_static_skb) {
+ bcm_static_skb = 0;
+ }
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+
+ bb = b;
+
+ ASSERT((osh != NULL) && (bb != NULL));
+
+ bcm_bprintf(bb, "max_obj %d obj_size %d curr_obj %d refills %d\n",
+ osh->ctfpool->max_obj, osh->ctfpool->obj_size,
+ osh->ctfpool->curr_obj, osh->ctfpool->refills);
+ bcm_bprintf(bb, "fast_allocs %d fast_frees %d slow_allocs %d\n",
+ osh->ctfpool->fast_allocs, osh->ctfpool->fast_frees,
+ osh->ctfpool->slow_allocs);
+}
+
+static inline struct sk_buff *
+osl_pktfastget(osl_t *osh, uint len)
+{
+ struct sk_buff *skb;
+#ifdef CTFPOOL_SPINLOCK
+ unsigned long flags;
+#endif /* CTFPOOL_SPINLOCK */
+
+ /* Try to do fast allocate. Return null if ctfpool is not in use
+ * or if there are no items in the ctfpool.
+ */
+ if (osh->ctfpool == NULL)
+ return NULL;
+
+ CTFPOOL_LOCK(osh->ctfpool, flags);
+ if (osh->ctfpool->head == NULL) {
+ ASSERT(osh->ctfpool->curr_obj == 0);
+ osh->ctfpool->slow_allocs++;
+ CTFPOOL_UNLOCK(osh->ctfpool, flags);
+ return NULL;
+ }
+
+ ASSERT(len <= osh->ctfpool->obj_size);
+
+ /* Get an object from ctfpool */
+ skb = (struct sk_buff *)osh->ctfpool->head;
+ osh->ctfpool->head = (void *)skb->next;
+
+ osh->ctfpool->fast_allocs++;
+ osh->ctfpool->curr_obj--;
+ ASSERT(CTFPOOLHEAD(osh, skb) == (struct sock *)osh->ctfpool->head);
+ CTFPOOL_UNLOCK(osh->ctfpool, flags);
+
+ /* Init skb struct */
+ skb->next = skb->prev = NULL;
+ skb->data = skb->head + 16;
+ skb->tail = skb->head + 16;
+
+ skb->len = 0;
+ skb->cloned = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
+ skb->list = NULL;
+#endif
+ atomic_set(&skb->users, 1);
+
+ return skb;
+}
+#endif /* CTFPOOL */
+/* Convert a driver packet to native(OS) packet
+ * In the process, packettag is zeroed out before sending up
+ * IP code depends on skb->cb to be setup correctly with various options
+ * In our case, that means it should be 0
+ */
+struct sk_buff * BCMFASTPATH
+osl_pkt_tonative(osl_t *osh, void *pkt)
+{
+#ifndef WL_UMK
+ struct sk_buff *nskb;
+ unsigned long flags;
+#endif
+
+ if (osh->pub.pkttag)
+ bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ);
+
+#ifndef WL_UMK
+ /* Decrement the packet counter */
+ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
+ spin_lock_irqsave(&osh->pktalloc_lock, flags);
+ osh->pub.pktalloced--;
+ spin_unlock_irqrestore(&osh->pktalloc_lock, flags);
+ }
+#endif /* WL_UMK */
+ return (struct sk_buff *)pkt;
+}
+
+/* Convert a native(OS) packet to driver packet.
+ * In the process, native packet is destroyed, there is no copying
+ * Also, a packettag is zeroed out
+ */
+void * BCMFASTPATH
+osl_pkt_frmnative(osl_t *osh, void *pkt)
+{
+#ifndef WL_UMK
+ struct sk_buff *nskb;
+ unsigned long flags;
+#endif
+
+ if (osh->pub.pkttag)
+ bzero((void*)((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ);
+
+#ifndef WL_UMK
+ /* Increment the packet counter */
+ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
+ spin_lock_irqsave(&osh->pktalloc_lock, flags);
+ osh->pub.pktalloced++;
+ spin_unlock_irqrestore(&osh->pktalloc_lock, flags);
+ }
+#endif /* WL_UMK */
+ return (void *)pkt;
+}
+
+/* Return a new packet. zero out pkttag */
+void * BCMFASTPATH
+osl_pktget(osl_t *osh, uint len)
+{
+ struct sk_buff *skb;
+ unsigned long flags;
+
+#ifdef CTFPOOL
+ /* Allocate from local pool */
+ skb = osl_pktfastget(osh, len);
+ if ((skb != NULL) || ((skb = osl_alloc_skb(len)) != NULL)) {
+#else /* CTFPOOL */
+ if ((skb = osl_alloc_skb(len))) {
+#endif /* CTFPOOL */
+ skb_put(skb, len);
+ skb->priority = 0;
+
+
+ spin_lock_irqsave(&osh->pktalloc_lock, flags);
+ osh->pub.pktalloced++;
+ spin_unlock_irqrestore(&osh->pktalloc_lock, flags);
+ }
+
+ return ((void*) skb);
+}
+
+#ifdef CTFPOOL
+static inline void
+osl_pktfastfree(osl_t *osh, struct sk_buff *skb)
+{
+ ctfpool_t *ctfpool;
+#ifdef CTFPOOL_SPINLOCK
+ unsigned long flags;
+#endif /* CTFPOOL_SPINLOCK */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+ skb->tstamp.tv.sec = 0;
+#else
+ skb->stamp.tv_sec = 0;
+#endif
+
+ /* We only need to init the fields that we change */
+ skb->dev = NULL;
+ skb->dst = NULL;
+ memset(skb->cb, 0, sizeof(skb->cb));
+ skb->ip_summed = 0;
+ skb->destructor = NULL;
+
+ ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb);
+ ASSERT(ctfpool != NULL);
+
+ /* Add object to the ctfpool */
+ CTFPOOL_LOCK(ctfpool, flags);
+ skb->next = (struct sk_buff *)ctfpool->head;
+ ctfpool->head = (void *)skb;
+
+ ctfpool->fast_frees++;
+ ctfpool->curr_obj++;
+
+ ASSERT(ctfpool->curr_obj <= ctfpool->max_obj);
+ CTFPOOL_UNLOCK(ctfpool, flags);
+}
+#endif /* CTFPOOL */
+
+/* Free the driver packet. Free the tag if present */
+void BCMFASTPATH
+osl_pktfree(osl_t *osh, void *p, bool send)
+{
+ struct sk_buff *skb, *nskb;
+ unsigned long flags;
+
+ skb = (struct sk_buff*) p;
+
+ if (send && osh->pub.tx_fn)
+ osh->pub.tx_fn(osh->pub.tx_ctx, p, 0);
+
+ PKTDBG_TRACE(osh, (void *) skb, PKTLIST_PKTFREE);
+
+ /* perversion: we use skb->next to chain multi-skb packets */
+ while (skb) {
+ nskb = skb->next;
+ skb->next = NULL;
+
+
+
+#ifdef CTFPOOL
+ if ((PKTISFAST(osh, skb)) && (atomic_read(&skb->users) == 1))
+ osl_pktfastfree(osh, skb);
+ else {
+#else /* CTFPOOL */
+ {
+#endif /* CTFPOOL */
+
+ if (skb->destructor)
+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
+ * destructor exists
+ */
+ dev_kfree_skb_any(skb);
+ else
+ /* can free immediately (even in_irq()) if destructor
+ * does not exist
+ */
+ dev_kfree_skb(skb);
+ }
+ spin_lock_irqsave(&osh->pktalloc_lock, flags);
+ osh->pub.pktalloced--;
+ spin_unlock_irqrestore(&osh->pktalloc_lock, flags);
+ skb = nskb;
+ }
+}
+
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+void*
+osl_pktget_static(osl_t *osh, uint len)
+{
+ int i = 0;
+ struct sk_buff *skb;
+
+
+ if (len > DHD_SKB_MAX_BUFSIZE) {
+ AP6210_DEBUG("osl_pktget_static: Do we really need this big skb??"
+ " len=%d\n", len);
+ return osl_pktget(osh, len);
+ }
+
+ down(&bcm_static_skb->osl_pkt_sem);
+
+ if (len <= DHD_SKB_1PAGE_BUFSIZE) {
+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
+ if (bcm_static_skb->pkt_use[i] == 0)
+ break;
+ }
+
+ if (i != STATIC_PKT_MAX_NUM) {
+ bcm_static_skb->pkt_use[i] = 1;
+
+ skb = bcm_static_skb->skb_4k[i];
+ skb->tail = skb->data + len;
+ skb->len = len;
+
+ up(&bcm_static_skb->osl_pkt_sem);
+ return skb;
+ }
+ }
+
+ if (len <= DHD_SKB_2PAGE_BUFSIZE) {
+
+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
+ if (bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM]
+ == 0)
+ break;
+ }
+
+ if (i != STATIC_PKT_MAX_NUM) {
+ bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 1;
+ skb = bcm_static_skb->skb_8k[i];
+ skb->tail = skb->data + len;
+ skb->len = len;
+
+ up(&bcm_static_skb->osl_pkt_sem);
+ return skb;
+ }
+ }
+
+#if defined(ENHANCED_STATIC_BUF)
+ if (bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM * 2] == 0) {
+ bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM * 2] = 1;
+
+ skb = bcm_static_skb->skb_16k;
+ skb->tail = skb->data + len;
+ skb->len = len;
+
+ up(&bcm_static_skb->osl_pkt_sem);
+ return skb;
+ }
+#endif
+
+ up(&bcm_static_skb->osl_pkt_sem);
+ AP6210_DEBUG("osl_pktget_static: all static pkt in use!\n");
+ return osl_pktget(osh, len);
+}
+
+void
+osl_pktfree_static(osl_t *osh, void *p, bool send)
+{
+ int i;
+ if (!bcm_static_skb) {
+ osl_pktfree(osh, p, send);
+ return;
+ }
+
+ down(&bcm_static_skb->osl_pkt_sem);
+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
+ if (p == bcm_static_skb->skb_4k[i]) {
+ bcm_static_skb->pkt_use[i] = 0;
+ up(&bcm_static_skb->osl_pkt_sem);
+ return;
+ }
+ }
+
+ for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
+ if (p == bcm_static_skb->skb_8k[i]) {
+ bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0;
+ up(&bcm_static_skb->osl_pkt_sem);
+ return;
+ }
+ }
+#ifdef ENHANCED_STATIC_BUF
+ if (p == bcm_static_skb->skb_16k) {
+ bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM*2] = 0;
+ up(&bcm_static_skb->osl_pkt_sem);
+ return;
+ }
+#endif
+ up(&bcm_static_skb->osl_pkt_sem);
+
+ osl_pktfree(osh, p, send);
+ return;
+}
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+
+uint32
+osl_pci_read_config(osl_t *osh, uint offset, uint size)
+{
+ uint val = 0;
+ uint retry = PCI_CFG_RETRY;
+
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ /* only 4byte access supported */
+ ASSERT(size == 4);
+
+ do {
+ pci_read_config_dword(osh->pdev, offset, &val);
+ if (val != 0xffffffff)
+ break;
+ } while (retry--);
+
+
+ return (val);
+}
+
+void
+osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
+{
+ uint retry = PCI_CFG_RETRY;
+
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ /* only 4byte access supported */
+ ASSERT(size == 4);
+
+ do {
+ pci_write_config_dword(osh->pdev, offset, val);
+ if (offset != PCI_BAR0_WIN)
+ break;
+ if (osl_pci_read_config(osh, offset, size) == val)
+ break;
+ } while (retry--);
+
+}
+
+/* return bus # for the pci device pointed by osh->pdev */
+uint
+osl_pci_bus(osl_t *osh)
+{
+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+ return ((struct pci_dev *)osh->pdev)->bus->number;
+}
+
+/* return slot # for the pci device pointed by osh->pdev */
+uint
+osl_pci_slot(osl_t *osh)
+{
+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
+}
+
+/* return the pci device pointed by osh->pdev */
+struct pci_dev *
+osl_pci_device(osl_t *osh)
+{
+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev);
+
+ return osh->pdev;
+}
+
+static void
+osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write)
+{
+}
+
+void
+osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size)
+{
+ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE);
+}
+
+void
+osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size)
+{
+ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE);
+}
+
+void *
+osl_malloc(osl_t *osh, uint size)
+{
+ void *addr;
+
+ /* only ASSERT if osh is defined */
+ if (osh)
+ ASSERT(osh->magic == OS_HANDLE_MAGIC);
+
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+ if (bcm_static_buf)
+ {
+ int i = 0;
+ if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE))
+ {
+ down(&bcm_static_buf->static_sem);
+
+ for (i = 0; i < STATIC_BUF_MAX_NUM; i++)
+ {
+ if (bcm_static_buf->buf_use[i] == 0)
+ break;
+ }
+
+ if (i == STATIC_BUF_MAX_NUM)
+ {
+ up(&bcm_static_buf->static_sem);
+ AP6210_DEBUG("all static buff in use!\n");
+ goto original;
+ }
+
+ bcm_static_buf->buf_use[i] = 1;
+ up(&bcm_static_buf->static_sem);
+
+ bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size);
+ if (osh)
+ atomic_add(size, &osh->malloced);
+
+ return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i));
+ }
+ }
+original:
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+
+ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) {
+ if (osh)
+ osh->failed++;
+ return (NULL);
+ }
+ if (osh)
+ atomic_add(size, &osh->malloced);
+
+ return (addr);
+}
+
+void
+osl_mfree(osl_t *osh, void *addr, uint size)
+{
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+ if (bcm_static_buf)
+ {
+ if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr
+ <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN)))
+ {
+ int buf_idx = 0;
+
+ buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE;
+
+ down(&bcm_static_buf->static_sem);
+ bcm_static_buf->buf_use[buf_idx] = 0;
+ up(&bcm_static_buf->static_sem);
+
+ if (osh) {
+ ASSERT(osh->magic == OS_HANDLE_MAGIC);
+ atomic_sub(size, &osh->malloced);
+ }
+ return;
+ }
+ }
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+ if (osh) {
+ ASSERT(osh->magic == OS_HANDLE_MAGIC);
+ atomic_sub(size, &osh->malloced);
+ }
+ kfree(addr);
+}
+
+uint
+osl_malloced(osl_t *osh)
+{
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ return (atomic_read(&osh->malloced));
+}
+
+uint
+osl_malloc_failed(osl_t *osh)
+{
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ return (osh->failed);
+}
+
+
+uint
+osl_dma_consistent_align(void)
+{
+ return (PAGE_SIZE);
+}
+
+void*
+osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, uint *alloced, ulong *pap)
+{
+ uint16 align = (1 << align_bits);
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align))
+ size += align;
+ *alloced = size;
+
+ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap));
+}
+
+void
+osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
+{
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+
+ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
+}
+
+uint BCMFASTPATH
+osl_dma_map(osl_t *osh, void *va, uint size, int direction)
+{
+ int dir;
+
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
+ return (pci_map_single(osh->pdev, va, size, dir));
+}
+
+void BCMFASTPATH
+osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction)
+{
+ int dir;
+
+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
+ pci_unmap_single(osh->pdev, (uint32)pa, size, dir);
+}
+
+#if defined(BCMASSERT_LOG)
+void
+osl_assert(const char *exp, const char *file, int line)
+{
+ char tempbuf[256];
+ const char *basename;
+
+ basename = strrchr(file, '/');
+ /* skip the '/' */
+ if (basename)
+ basename++;
+
+ if (!basename)
+ basename = file;
+
+ snprintf(tempbuf, 64, "\"%s\": file \"%s\", line %d\n",
+ exp, basename, line);
+
+ AP6210_DEBUG("%s", tempbuf);
+
+
+}
+#endif
+
+void
+osl_delay(uint usec)
+{
+ uint d;
+
+ while (usec > 0) {
+ d = MIN(usec, 1000);
+ udelay(d);
+ usec -= d;
+ }
+}
+
+
+/* Clone a packet.
+ * The pkttag contents are NOT cloned.
+ */
+void *
+osl_pktdup(osl_t *osh, void *skb)
+{
+ void * p;
+ unsigned long irqflags;
+
+ /* clear the CTFBUF flag if set and map the rest of the buffer
+ * before cloning.
+ */
+ PKTCTFMAP(osh, skb);
+
+ if ((p = skb_clone((struct sk_buff *)skb, GFP_ATOMIC)) == NULL)
+ return NULL;
+
+#ifdef CTFPOOL
+ if (PKTISFAST(osh, skb)) {
+ ctfpool_t *ctfpool;
+
+ /* if the buffer allocated from ctfpool is cloned then
+ * we can't be sure when it will be freed. since there
+ * is a chance that we will be losing a buffer
+ * from our pool, we increment the refill count for the
+ * object to be alloced later.
+ */
+ ctfpool = (ctfpool_t *)CTFPOOLPTR(osh, skb);
+ ASSERT(ctfpool != NULL);
+ PKTCLRFAST(osh, p);
+ PKTCLRFAST(osh, skb);
+ ctfpool->refills++;
+ }
+#endif /* CTFPOOL */
+
+ /* skb_clone copies skb->cb.. we don't want that */
+ if (osh->pub.pkttag)
+ bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ);
+
+ /* Increment the packet counter */
+ spin_lock_irqsave(&osh->pktalloc_lock, irqflags);
+ osh->pub.pktalloced++;
+ spin_unlock_irqrestore(&osh->pktalloc_lock, irqflags);
+ return (p);
+}
+
+
+/*
+ * OSLREGOPS specifies the use of osl_XXX routines to be used for register access
+ */
+
+/*
+ * BINOSL selects the slightly slower function-call-based binary compatible osl.
+ */
+
+/* Linux Kernel: File Operations: start */
+void *
+osl_os_open_image(char *filename)
+{
+ struct file *fp;
+
+ fp = filp_open(filename, O_RDONLY, 0);
+ /*
+ * 2.6.11 (FC4) supports filp_open() but later revs don't?
+ * Alternative:
+ * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
+ * ???
+ */
+ if (IS_ERR(fp))
+ fp = NULL;
+
+ return fp;
+}
+
+int
+osl_os_get_image_block(char *buf, int len, void *image)
+{
+ struct file *fp = (struct file *)image;
+ int rdlen;
+
+ if (!image)
+ return 0;
+
+ rdlen = kernel_read(fp, fp->f_pos, buf, len);
+ if (rdlen > 0)
+ fp->f_pos += rdlen;
+
+ return rdlen;
+}
+
+void
+osl_os_close_image(void *image)
+{
+ if (image)
+ filp_close((struct file *)image, NULL);
+}
+/* Linux Kernel: File Operations: end */
diff --git a/drivers/net/wireless/ap6210/sbutils.c b/drivers/net/wireless/ap6210/sbutils.c
new file mode 100644
index 0000000..89f9eb3
--- /dev/null
+++ b/drivers/net/wireless/ap6210/sbutils.c
@@ -0,0 +1,1003 @@
+/*
+ * Misc utility routines for accessing chip-specific features
+ * of the SiliconBackplane-based Broadcom chips.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: sbutils.c 310902 2012-01-26 19:45:33Z $
+ */
+
+#include <bcm_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <sbpcmcia.h>
+
+#include "siutils_priv.h"
+
+#include <ap6210.h>
+
+
+/* local prototypes */
+static uint _sb_coreidx(si_info_t *sii, uint32 sba);
+static uint _sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba,
+ uint ncores);
+static uint32 _sb_coresba(si_info_t *sii);
+static void *_sb_setcoreidx(si_info_t *sii, uint coreidx);
+
+#define SET_SBREG(sii, r, mask, val) \
+ W_SBREG((sii), (r), ((R_SBREG((sii), (r)) & ~(mask)) | (val)))
+#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF)
+
+/* sonicsrev */
+#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT)
+#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT)
+
+#define R_SBREG(sii, sbr) sb_read_sbreg((sii), (sbr))
+#define W_SBREG(sii, sbr, v) sb_write_sbreg((sii), (sbr), (v))
+#define AND_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) & (v)))
+#define OR_SBREG(sii, sbr, v) W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) | (v)))
+
+static uint32
+sb_read_sbreg(si_info_t *sii, volatile uint32 *sbr)
+{
+ uint8 tmp;
+ uint32 val, intr_val = 0;
+
+
+ /*
+ * compact flash only has 11 bits address, while we needs 12 bits address.
+ * MEM_SEG will be OR'd with other 11 bits address in hardware,
+ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
+ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
+ */
+ if (PCMCIA(sii)) {
+ INTR_OFF(sii, intr_val);
+ tmp = 1;
+ OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1);
+ sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */
+ }
+
+ val = R_REG(sii->osh, sbr);
+
+ if (PCMCIA(sii)) {
+ tmp = 0;
+ OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1);
+ INTR_RESTORE(sii, intr_val);
+ }
+
+ return (val);
+}
+
+static void
+sb_write_sbreg(si_info_t *sii, volatile uint32 *sbr, uint32 v)
+{
+ uint8 tmp;
+ volatile uint32 dummy;
+ uint32 intr_val = 0;
+
+
+ /*
+ * compact flash only has 11 bits address, while we needs 12 bits address.
+ * MEM_SEG will be OR'd with other 11 bits address in hardware,
+ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
+ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
+ */
+ if (PCMCIA(sii)) {
+ INTR_OFF(sii, intr_val);
+ tmp = 1;
+ OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1);
+ sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */
+ }
+
+ if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) {
+ dummy = R_REG(sii->osh, sbr);
+ BCM_REFERENCE(dummy);
+ W_REG(sii->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff));
+ dummy = R_REG(sii->osh, sbr);
+ BCM_REFERENCE(dummy);
+ W_REG(sii->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff));
+ } else
+ W_REG(sii->osh, sbr, v);
+
+ if (PCMCIA(sii)) {
+ tmp = 0;
+ OSL_PCMCIA_WRITE_ATTR(sii->osh, MEM_SEG, &tmp, 1);
+ INTR_RESTORE(sii, intr_val);
+ }
+}
+
+uint
+sb_coreid(si_t *sih)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT);
+}
+
+uint
+sb_intflag(si_t *sih)
+{
+ si_info_t *sii;
+ void *corereg;
+ sbconfig_t *sb;
+ uint origidx, intflag, intr_val = 0;
+
+ sii = SI_INFO(sih);
+
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+ corereg = si_setcore(sih, CC_CORE_ID, 0);
+ ASSERT(corereg != NULL);
+ sb = REGS2SB(corereg);
+ intflag = R_SBREG(sii, &sb->sbflagst);
+ sb_setcoreidx(sih, origidx);
+ INTR_RESTORE(sii, intr_val);
+
+ return intflag;
+}
+
+uint
+sb_flag(si_t *sih)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ return R_SBREG(sii, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
+}
+
+void
+sb_setint(si_t *sih, int siflag)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+ uint32 vec;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ if (siflag == -1)
+ vec = 0;
+ else
+ vec = 1 << siflag;
+ W_SBREG(sii, &sb->sbintvec, vec);
+}
+
+/* return core index of the core with address 'sba' */
+static uint
+_sb_coreidx(si_info_t *sii, uint32 sba)
+{
+ uint i;
+
+ for (i = 0; i < sii->numcores; i ++)
+ if (sba == sii->coresba[i])
+ return i;
+ return BADIDX;
+}
+
+/* return core address of the current core */
+static uint32
+_sb_coresba(si_info_t *sii)
+{
+ uint32 sbaddr;
+
+
+ switch (BUSTYPE(sii->pub.bustype)) {
+ case SI_BUS: {
+ sbconfig_t *sb = REGS2SB(sii->curmap);
+ sbaddr = sb_base(R_SBREG(sii, &sb->sbadmatch0));
+ break;
+ }
+
+ case PCI_BUS:
+ sbaddr = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
+ break;
+
+ case PCMCIA_BUS: {
+ uint8 tmp = 0;
+ OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1);
+ sbaddr = (uint32)tmp << 12;
+ OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1);
+ sbaddr |= (uint32)tmp << 16;
+ OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1);
+ sbaddr |= (uint32)tmp << 24;
+ break;
+ }
+
+ case SPI_BUS:
+ case SDIO_BUS:
+ sbaddr = (uint32)(uintptr)sii->curmap;
+ break;
+
+
+ default:
+ sbaddr = BADCOREADDR;
+ break;
+ }
+
+ return sbaddr;
+}
+
+uint
+sb_corevendor(si_t *sih)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ return ((R_SBREG(sii, &sb->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT);
+}
+
+uint
+sb_corerev(si_t *sih)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+ uint sbidh;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+ sbidh = R_SBREG(sii, &sb->sbidhigh);
+
+ return (SBCOREREV(sbidh));
+}
+
+/* set core-specific control flags */
+void
+sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ ASSERT((val & ~mask) == 0);
+
+ /* mask and set */
+ w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) |
+ (val << SBTML_SICF_SHIFT);
+ W_SBREG(sii, &sb->sbtmstatelow, w);
+}
+
+/* set/clear core-specific control flags */
+uint32
+sb_core_cflags(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ ASSERT((val & ~mask) == 0);
+
+ /* mask and set */
+ if (mask || val) {
+ w = (R_SBREG(sii, &sb->sbtmstatelow) & ~(mask << SBTML_SICF_SHIFT)) |
+ (val << SBTML_SICF_SHIFT);
+ W_SBREG(sii, &sb->sbtmstatelow, w);
+ }
+
+ /* return the new value
+ * for write operation, the following readback ensures the completion of write opration.
+ */
+ return (R_SBREG(sii, &sb->sbtmstatelow) >> SBTML_SICF_SHIFT);
+}
+
+/* set/clear core-specific status flags */
+uint32
+sb_core_sflags(si_t *sih, uint32 mask, uint32 val)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+ uint32 w;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ ASSERT((val & ~mask) == 0);
+ ASSERT((mask & ~SISF_CORE_BITS) == 0);
+
+ /* mask and set */
+ if (mask || val) {
+ w = (R_SBREG(sii, &sb->sbtmstatehigh) & ~(mask << SBTMH_SISF_SHIFT)) |
+ (val << SBTMH_SISF_SHIFT);
+ W_SBREG(sii, &sb->sbtmstatehigh, w);
+ }
+
+ /* return the new value */
+ return (R_SBREG(sii, &sb->sbtmstatehigh) >> SBTMH_SISF_SHIFT);
+}
+
+bool
+sb_iscoreup(si_t *sih)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ return ((R_SBREG(sii, &sb->sbtmstatelow) &
+ (SBTML_RESET | SBTML_REJ_MASK | (SICF_CLOCK_EN << SBTML_SICF_SHIFT))) ==
+ (SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+}
+
+/*
+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
+ * switch back to the original core, and return the new value.
+ *
+ * When using the silicon backplane, no fidleing with interrupts or core switches are needed.
+ *
+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers
+ * and (on newer pci cores) chipcommon registers.
+ */
+uint
+sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+ uint origidx = 0;
+ uint32 *r = NULL;
+ uint w;
+ uint intr_val = 0;
+ bool fast = FALSE;
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ ASSERT(GOODIDX(coreidx));
+ ASSERT(regoff < SI_CORE_SIZE);
+ ASSERT((val & ~mask) == 0);
+
+ if (coreidx >= SI_MAXCORES)
+ return 0;
+
+ if (BUSTYPE(sii->pub.bustype) == SI_BUS) {
+ /* If internal bus, we can always get at everything */
+ fast = TRUE;
+ /* map if does not exist */
+ if (!sii->regs[coreidx]) {
+ sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
+ SI_CORE_SIZE);
+ ASSERT(GOODREGS(sii->regs[coreidx]));
+ }
+ r = (uint32 *)((uchar *)sii->regs[coreidx] + regoff);
+ } else if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
+
+ if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+ /* Chipc registers are mapped at 12KB */
+
+ fast = TRUE;
+ r = (uint32 *)((char *)sii->curmap + PCI_16KB0_CCREGS_OFFSET + regoff);
+ } else if (sii->pub.buscoreidx == coreidx) {
+ /* pci registers are at either in the last 2KB of an 8KB window
+ * or, in pcie and pci rev 13 at 8KB
+ */
+ fast = TRUE;
+ if (SI_FAST(sii))
+ r = (uint32 *)((char *)sii->curmap +
+ PCI_16KB0_PCIREGS_OFFSET + regoff);
+ else
+ r = (uint32 *)((char *)sii->curmap +
+ ((regoff >= SBCONFIGOFF) ?
+ PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
+ regoff);
+ }
+ }
+
+ if (!fast) {
+ INTR_OFF(sii, intr_val);
+
+ /* save current core index */
+ origidx = si_coreidx(&sii->pub);
+
+ /* switch core */
+ r = (uint32*) ((uchar*)sb_setcoreidx(&sii->pub, coreidx) + regoff);
+ }
+ ASSERT(r != NULL);
+
+ /* mask and set */
+ if (mask || val) {
+ if (regoff >= SBCONFIGOFF) {
+ w = (R_SBREG(sii, r) & ~mask) | val;
+ W_SBREG(sii, r, w);
+ } else {
+ w = (R_REG(sii->osh, r) & ~mask) | val;
+ W_REG(sii->osh, r, w);
+ }
+ }
+
+ /* readback */
+ if (regoff >= SBCONFIGOFF)
+ w = R_SBREG(sii, r);
+ else {
+ if ((CHIPID(sii->pub.chip) == BCM5354_CHIP_ID) &&
+ (coreidx == SI_CC_IDX) &&
+ (regoff == OFFSETOF(chipcregs_t, watchdog))) {
+ w = val;
+ } else
+ w = R_REG(sii->osh, r);
+ }
+
+ if (!fast) {
+ /* restore core index */
+ if (origidx != coreidx)
+ sb_setcoreidx(&sii->pub, origidx);
+
+ INTR_RESTORE(sii, intr_val);
+ }
+
+ return (w);
+}
+
+/* Scan the enumeration space to find all cores starting from the given
+ * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba'
+ * is the default core address at chip POR time and 'regs' is the virtual
+ * address that the default core is mapped at. 'ncores' is the number of
+ * cores expected on bus 'sbba'. It returns the total number of cores
+ * starting from bus 'sbba', inclusive.
+ */
+#define SB_MAXBUSES 2
+static uint
+_sb_scan(si_info_t *sii, uint32 sba, void *regs, uint bus, uint32 sbba, uint numcores)
+{
+ uint next;
+ uint ncc = 0;
+ uint i;
+
+ if (bus >= SB_MAXBUSES) {
+ AP6210_ERR("_sb_scan: bus 0x%08x at level %d is too deep to scan\n", sbba, bus);
+ return 0;
+ }
+ AP6210_DEBUG("_sb_scan: scan bus 0x%08x assume %u cores\n", sbba, numcores);
+
+ /* Scan all cores on the bus starting from core 0.
+ * Core addresses must be contiguous on each bus.
+ */
+ for (i = 0, next = sii->numcores; i < numcores && next < SB_BUS_MAXCORES; i++, next++) {
+ sii->coresba[next] = sbba + (i * SI_CORE_SIZE);
+
+ /* keep and reuse the initial register mapping */
+ if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && (sii->coresba[next] == sba)) {
+ AP6210_DEBUG("_sb_scan: reuse mapped regs %p for core %u\n", regs, next);
+ sii->regs[next] = regs;
+ }
+
+ /* change core to 'next' and read its coreid */
+ sii->curmap = _sb_setcoreidx(sii, next);
+ sii->curidx = next;
+
+ sii->coreid[next] = sb_coreid(&sii->pub);
+
+ /* core specific processing... */
+ /* chipc provides # cores */
+ if (sii->coreid[next] == CC_CORE_ID) {
+ chipcregs_t *cc = (chipcregs_t *)sii->curmap;
+ uint32 ccrev = sb_corerev(&sii->pub);
+
+ /* determine numcores - this is the total # cores in the chip */
+ if (((ccrev == 4) || (ccrev >= 6)))
+ numcores = (R_REG(sii->osh, &cc->chipid) & CID_CC_MASK) >>
+ CID_CC_SHIFT;
+ else {
+ /* Older chips */
+ uint chip = CHIPID(sii->pub.chip);
+
+ if (chip == BCM4306_CHIP_ID) /* < 4306c0 */
+ numcores = 6;
+ else if (chip == BCM4704_CHIP_ID)
+ numcores = 9;
+ else if (chip == BCM5365_CHIP_ID)
+ numcores = 7;
+ else {
+ AP6210_ERR("sb_chip2numcores: unsupported chip 0x%x\n",
+ chip);
+ ASSERT(0);
+ numcores = 1;
+ }
+ }
+ AP6210_DEBUG("_sb_scan: there are %u cores in the chip %s\n", numcores,
+ sii->pub.issim ? "QT" : "");
+ }
+ /* scan bridged SB(s) and add results to the end of the list */
+ else if (sii->coreid[next] == OCP_CORE_ID) {
+ sbconfig_t *sb = REGS2SB(sii->curmap);
+ uint32 nsbba = R_SBREG(sii, &sb->sbadmatch1);
+ uint nsbcc;
+
+ sii->numcores = next + 1;
+
+ if ((nsbba & 0xfff00000) != SI_ENUM_BASE)
+ continue;
+ nsbba &= 0xfffff000;
+ if (_sb_coreidx(sii, nsbba) != BADIDX)
+ continue;
+
+ nsbcc = (R_SBREG(sii, &sb->sbtmstatehigh) & 0x000f0000) >> 16;
+ nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc);
+ if (sbba == SI_ENUM_BASE)
+ numcores -= nsbcc;
+ ncc += nsbcc;
+ }
+ }
+
+ AP6210_DEBUG("_sb_scan: found %u cores on bus 0x%08x\n", i, sbba);
+
+ sii->numcores = i + ncc;
+ return sii->numcores;
+}
+
+/* scan the sb enumerated space to identify all cores */
+void
+sb_scan(si_t *sih, void *regs, uint devid)
+{
+ si_info_t *sii;
+ uint32 origsba;
+ sbconfig_t *sb;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ sii->pub.socirev = (R_SBREG(sii, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT;
+
+ /* Save the current core info and validate it later till we know
+ * for sure what is good and what is bad.
+ */
+ origsba = _sb_coresba(sii);
+
+ /* scan all SB(s) starting from SI_ENUM_BASE */
+ sii->numcores = _sb_scan(sii, origsba, regs, 0, SI_ENUM_BASE, 1);
+}
+
+/*
+ * This function changes logical "focus" to the indicated core;
+ * must be called with interrupts off.
+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core
+ */
+void *
+sb_setcoreidx(si_t *sih, uint coreidx)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (coreidx >= sii->numcores)
+ return (NULL);
+
+ /*
+ * If the user has provided an interrupt mask enabled function,
+ * then assert interrupts are disabled before switching the core.
+ */
+ ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn)((sii)->intr_arg));
+
+ sii->curmap = _sb_setcoreidx(sii, coreidx);
+ sii->curidx = coreidx;
+
+ return (sii->curmap);
+}
+
+/* This function changes the logical "focus" to the indicated core.
+ * Return the current core's virtual address.
+ */
+static void *
+_sb_setcoreidx(si_info_t *sii, uint coreidx)
+{
+ uint32 sbaddr = sii->coresba[coreidx];
+ void *regs;
+
+ switch (BUSTYPE(sii->pub.bustype)) {
+ case SI_BUS:
+ /* map new one */
+ if (!sii->regs[coreidx]) {
+ sii->regs[coreidx] = REG_MAP(sbaddr, SI_CORE_SIZE);
+ ASSERT(GOODREGS(sii->regs[coreidx]));
+ }
+ regs = sii->regs[coreidx];
+ break;
+
+ case PCI_BUS:
+ /* point bar0 window */
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, sbaddr);
+ regs = sii->curmap;
+ break;
+
+ case PCMCIA_BUS: {
+ uint8 tmp = (sbaddr >> 12) & 0x0f;
+ OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR0, &tmp, 1);
+ tmp = (sbaddr >> 16) & 0xff;
+ OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR1, &tmp, 1);
+ tmp = (sbaddr >> 24) & 0xff;
+ OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_ADDR2, &tmp, 1);
+ regs = sii->curmap;
+ break;
+ }
+ case SPI_BUS:
+ case SDIO_BUS:
+ /* map new one */
+ if (!sii->regs[coreidx]) {
+ sii->regs[coreidx] = (void *)(uintptr)sbaddr;
+ ASSERT(GOODREGS(sii->regs[coreidx]));
+ }
+ regs = sii->regs[coreidx];
+ break;
+
+
+ default:
+ ASSERT(0);
+ regs = NULL;
+ break;
+ }
+
+ return regs;
+}
+
+/* Return the address of sbadmatch0/1/2/3 register */
+static volatile uint32 *
+sb_admatch(si_info_t *sii, uint asidx)
+{
+ sbconfig_t *sb;
+ volatile uint32 *addrm;
+
+ sb = REGS2SB(sii->curmap);
+
+ switch (asidx) {
+ case 0:
+ addrm = &sb->sbadmatch0;
+ break;
+
+ case 1:
+ addrm = &sb->sbadmatch1;
+ break;
+
+ case 2:
+ addrm = &sb->sbadmatch2;
+ break;
+
+ case 3:
+ addrm = &sb->sbadmatch3;
+ break;
+
+ default:
+ AP6210_ERR("%s: Address space index (%d) out of range\n", __FUNCTION__, asidx);
+ return 0;
+ }
+
+ return (addrm);
+}
+
+/* Return the number of address spaces in current core */
+int
+sb_numaddrspaces(si_t *sih)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+
+ sii = SI_INFO(sih);
+ sb = REGS2SB(sii->curmap);
+
+ /* + 1 because of enumeration space */
+ return ((R_SBREG(sii, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT) + 1;
+}
+
+/* Return the address of the nth address space in the current core */
+uint32
+sb_addrspace(si_t *sih, uint asidx)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ return (sb_base(R_SBREG(sii, sb_admatch(sii, asidx))));
+}
+
+/* Return the size of the nth address space in the current core */
+uint32
+sb_addrspacesize(si_t *sih, uint asidx)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ return (sb_size(R_SBREG(sii, sb_admatch(sii, asidx))));
+}
+
+
+/* do buffered registers update */
+void
+sb_commit(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+
+ sii = SI_INFO(sih);
+
+ origidx = sii->curidx;
+ ASSERT(GOODIDX(origidx));
+
+ INTR_OFF(sii, intr_val);
+
+ /* switch over to chipcommon core if there is one, else use pci */
+ if (sii->pub.ccrev != NOREV) {
+ chipcregs_t *ccregs = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+ ASSERT(ccregs != NULL);
+
+ /* do the buffer registers update */
+ W_REG(sii->osh, &ccregs->broadcastaddress, SB_COMMIT);
+ W_REG(sii->osh, &ccregs->broadcastdata, 0x0);
+ } else
+ ASSERT(0);
+
+ /* restore core index */
+ sb_setcoreidx(sih, origidx);
+ INTR_RESTORE(sii, intr_val);
+}
+
+void
+sb_core_disable(si_t *sih, uint32 bits)
+{
+ si_info_t *sii;
+ volatile uint32 dummy;
+ sbconfig_t *sb;
+
+ sii = SI_INFO(sih);
+
+ ASSERT(GOODREGS(sii->curmap));
+ sb = REGS2SB(sii->curmap);
+
+ /* if core is already in reset, just return */
+ if (R_SBREG(sii, &sb->sbtmstatelow) & SBTML_RESET)
+ return;
+
+ /* if clocks are not enabled, put into reset and return */
+ if ((R_SBREG(sii, &sb->sbtmstatelow) & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) == 0)
+ goto disable;
+
+ /* set target reject and spin until busy is clear (preserve core-specific bits) */
+ OR_SBREG(sii, &sb->sbtmstatelow, SBTML_REJ);
+ dummy = R_SBREG(sii, &sb->sbtmstatelow);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(1);
+ SPINWAIT((R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000);
+ if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY)
+ AP6210_ERR("%s: target state still busy\n", __FUNCTION__);
+
+ if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) {
+ OR_SBREG(sii, &sb->sbimstate, SBIM_RJ);
+ dummy = R_SBREG(sii, &sb->sbimstate);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(1);
+ SPINWAIT((R_SBREG(sii, &sb->sbimstate) & SBIM_BY), 100000);
+ }
+
+ /* set reset and reject while enabling the clocks */
+ W_SBREG(sii, &sb->sbtmstatelow,
+ (((bits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
+ SBTML_REJ | SBTML_RESET));
+ dummy = R_SBREG(sii, &sb->sbtmstatelow);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(10);
+
+ /* don't forget to clear the initiator reject bit */
+ if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT)
+ AND_SBREG(sii, &sb->sbimstate, ~SBIM_RJ);
+
+disable:
+ /* leave reset and reject asserted */
+ W_SBREG(sii, &sb->sbtmstatelow, ((bits << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET));
+ OSL_DELAY(1);
+}
+
+/* reset and re-enable a core
+ * inputs:
+ * bits - core specific bits that are set during and after reset sequence
+ * resetbits - core specific bits that are set only during reset sequence
+ */
+void
+sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
+{
+ si_info_t *sii;
+ sbconfig_t *sb;
+ volatile uint32 dummy;
+
+ sii = SI_INFO(sih);
+ ASSERT(GOODREGS(sii->curmap));
+ sb = REGS2SB(sii->curmap);
+
+ /*
+ * Must do the disable sequence first to work for arbitrary current core state.
+ */
+ sb_core_disable(sih, (bits | resetbits));
+
+ /*
+ * Now do the initialization sequence.
+ */
+
+ /* set reset while enabling the clock and forcing them on throughout the core */
+ W_SBREG(sii, &sb->sbtmstatelow,
+ (((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
+ SBTML_RESET));
+ dummy = R_SBREG(sii, &sb->sbtmstatelow);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(1);
+
+ if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_SERR) {
+ W_SBREG(sii, &sb->sbtmstatehigh, 0);
+ }
+ if ((dummy = R_SBREG(sii, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) {
+ AND_SBREG(sii, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
+ }
+
+ /* clear reset and allow it to propagate throughout the core */
+ W_SBREG(sii, &sb->sbtmstatelow,
+ ((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT));
+ dummy = R_SBREG(sii, &sb->sbtmstatelow);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(1);
+
+ /* leave clock enabled */
+ W_SBREG(sii, &sb->sbtmstatelow, ((bits | SICF_CLOCK_EN) << SBTML_SICF_SHIFT));
+ dummy = R_SBREG(sii, &sb->sbtmstatelow);
+ BCM_REFERENCE(dummy);
+ OSL_DELAY(1);
+}
+
+/*
+ * Set the initiator timeout for the "master core".
+ * The master core is defined to be the core in control
+ * of the chip and so it issues accesses to non-memory
+ * locations (Because of dma *any* core can access memeory).
+ *
+ * The routine uses the bus to decide who is the master:
+ * SI_BUS => mips
+ * JTAG_BUS => chipc
+ * PCI_BUS => pci or pcie
+ * PCMCIA_BUS => pcmcia
+ * SDIO_BUS => pcmcia
+ *
+ * This routine exists so callers can disable initiator
+ * timeouts so accesses to very slow devices like otp
+ * won't cause an abort. The routine allows arbitrary
+ * settings of the service and request timeouts, though.
+ *
+ * Returns the timeout state before changing it or -1
+ * on error.
+ */
+
+#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK)
+
+uint32
+sb_set_initiator_to(si_t *sih, uint32 to, uint idx)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ uint32 tmp, ret = 0xffffffff;
+ sbconfig_t *sb;
+
+ sii = SI_INFO(sih);
+
+ if ((to & ~TO_MASK) != 0)
+ return ret;
+
+ /* Figure out the master core */
+ if (idx == BADIDX) {
+ switch (BUSTYPE(sii->pub.bustype)) {
+ case PCI_BUS:
+ idx = sii->pub.buscoreidx;
+ break;
+ case JTAG_BUS:
+ idx = SI_CC_IDX;
+ break;
+ case PCMCIA_BUS:
+ case SDIO_BUS:
+ idx = si_findcoreidx(sih, PCMCIA_CORE_ID, 0);
+ break;
+ case SI_BUS:
+ idx = si_findcoreidx(sih, MIPS33_CORE_ID, 0);
+ break;
+ default:
+ ASSERT(0);
+ }
+ if (idx == BADIDX)
+ return ret;
+ }
+
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ sb = REGS2SB(sb_setcoreidx(sih, idx));
+
+ tmp = R_SBREG(sii, &sb->sbimconfiglow);
+ ret = tmp & TO_MASK;
+ W_SBREG(sii, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to);
+
+ sb_commit(sih);
+ sb_setcoreidx(sih, origidx);
+ INTR_RESTORE(sii, intr_val);
+ return ret;
+}
+
+uint32
+sb_base(uint32 admatch)
+{
+ uint32 base;
+ uint type;
+
+ type = admatch & SBAM_TYPE_MASK;
+ ASSERT(type < 3);
+
+ base = 0;
+
+ if (type == 0) {
+ base = admatch & SBAM_BASE0_MASK;
+ } else if (type == 1) {
+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
+ base = admatch & SBAM_BASE1_MASK;
+ } else if (type == 2) {
+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
+ base = admatch & SBAM_BASE2_MASK;
+ }
+
+ return (base);
+}
+
+uint32
+sb_size(uint32 admatch)
+{
+ uint32 size;
+ uint type;
+
+ type = admatch & SBAM_TYPE_MASK;
+ ASSERT(type < 3);
+
+ size = 0;
+
+ if (type == 0) {
+ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1);
+ } else if (type == 1) {
+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
+ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1);
+ } else if (type == 2) {
+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
+ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1);
+ }
+
+ return (size);
+}
diff --git a/drivers/net/wireless/ap6210/siutils.c b/drivers/net/wireless/ap6210/siutils.c
new file mode 100644
index 0000000..f917c41
--- /dev/null
+++ b/drivers/net/wireless/ap6210/siutils.c
@@ -0,0 +1,2472 @@
+/*
+ * Misc utility routines for accessing chip-specific features
+ * of the SiliconBackplane-based Broadcom chips.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: siutils.c 347632 2012-07-27 11:00:35Z $
+ */
+
+#include <bcm_cfg.h>
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <sbpcmcia.h>
+#include <sbsocram.h>
+#include <bcmsdh.h>
+#include <sdio.h>
+#include <sbsdio.h>
+#include <sbhnddma.h>
+#include <sbsdpcmdev.h>
+#include <bcmsdpcm.h>
+#include <hndpmu.h>
+
+#include "siutils_priv.h"
+
+#include <ap6210.h>
+
+/* local prototypes */
+static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
+ uint bustype, void *sdh, char **vars, uint *varsz);
+static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh);
+static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
+ uint *origidx, void *regs);
+
+
+
+/* global variable to indicate reservation/release of gpio's */
+static uint32 si_gpioreservation = 0;
+
+/* global flag to prevent shared resources from being initialized multiple times in si_attach() */
+
+int do_4360_pcie2_war = 0;
+
+/*
+ * Allocate a si handle.
+ * devid - pci device id (used to determine chip#)
+ * osh - opaque OS handle
+ * regs - virtual address of initial core registers
+ * bustype - pci/pcmcia/sb/sdio/etc
+ * vars - pointer to a pointer area for "environment" variables
+ * varsz - pointer to int to return the size of the vars
+ */
+si_t *
+si_attach(uint devid, osl_t *osh, void *regs,
+ uint bustype, void *sdh, char **vars, uint *varsz)
+{
+ si_info_t *sii;
+
+ /* alloc si_info_t */
+ if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) {
+ AP6210_ERR("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh));
+ return (NULL);
+ }
+
+ if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) {
+ MFREE(osh, sii, sizeof(si_info_t));
+ return (NULL);
+ }
+ sii->vars = vars ? *vars : NULL;
+ sii->varsz = varsz ? *varsz : 0;
+
+ return (si_t *)sii;
+}
+
+/* global kernel resource */
+static si_info_t ksii;
+
+static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */
+
+/* generic kernel variant of si_attach() */
+si_t *
+si_kattach(osl_t *osh)
+{
+ static bool ksii_attached = FALSE;
+
+ if (!ksii_attached) {
+ void *regs = NULL;
+ regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
+
+ if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs,
+ SI_BUS, NULL,
+ osh != SI_OSH ? &ksii.vars : NULL,
+ osh != SI_OSH ? &ksii.varsz : NULL) == NULL) {
+ AP6210_ERR("si_kattach: si_doattach failed\n");
+ REG_UNMAP(regs);
+ return NULL;
+ }
+ REG_UNMAP(regs);
+
+ /* save ticks normalized to ms for si_watchdog_ms() */
+ if (PMUCTL_ENAB(&ksii.pub)) {
+ /* based on 32KHz ILP clock */
+ wd_msticks = 32;
+ } else {
+ wd_msticks = ALP_CLOCK / 1000;
+ }
+
+ ksii_attached = TRUE;
+ AP6210_DEBUG("si_kattach done. ccrev = %d, wd_msticks = %d\n",
+ ksii.pub.ccrev, wd_msticks);
+ }
+
+ return &ksii.pub;
+}
+
+
+static bool
+si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh)
+{
+ /* need to set memseg flag for CF card first before any sb registers access */
+ if (BUSTYPE(bustype) == PCMCIA_BUS)
+ sii->memseg = TRUE;
+
+
+ if (BUSTYPE(bustype) == SDIO_BUS) {
+ int err;
+ uint8 clkset;
+
+ /* Try forcing SDIO core to do ALPAvail request only */
+ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
+ if (!err) {
+ uint8 clkval;
+
+ /* If register supported, wait for ALPAvail and then force ALP */
+ clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL);
+ if ((clkval & ~SBSDIO_AVBITS) == clkset) {
+ SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+ SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)),
+ PMU_MAX_TRANSITION_DLY);
+ if (!SBSDIO_ALPAV(clkval)) {
+ AP6210_ERR("timeout on ALPAV wait, clkval 0x%02x\n",
+ clkval);
+ return FALSE;
+ }
+ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+ clkset, &err);
+ OSL_DELAY(65);
+ }
+ }
+
+ /* Also, disable the extra SDIO pull-ups */
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
+ }
+
+
+ return TRUE;
+}
+
+static bool
+si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
+ uint *origidx, void *regs)
+{
+ bool pci, pcie, pcie_gen2 = FALSE;
+ uint i;
+ uint pciidx, pcieidx, pcirev, pcierev;
+
+ cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
+ ASSERT((uintptr)cc);
+
+ /* get chipcommon rev */
+ sii->pub.ccrev = (int)si_corerev(&sii->pub);
+
+ /* get chipcommon chipstatus */
+ if (sii->pub.ccrev >= 11)
+ sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
+
+ /* get chipcommon capabilites */
+ sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
+ /* get chipcommon extended capabilities */
+
+ if (sii->pub.ccrev >= 35)
+ sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
+
+ /* get pmu rev and caps */
+ if (sii->pub.cccaps & CC_CAP_PMU) {
+ sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
+ sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+ }
+
+ AP6210_DEBUG("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
+ sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
+ sii->pub.pmucaps);
+
+ /* figure out bus/orignal core idx */
+ sii->pub.buscoretype = NODEV_CORE_ID;
+ sii->pub.buscorerev = (uint)NOREV;
+ sii->pub.buscoreidx = BADIDX;
+
+ pci = pcie = FALSE;
+ pcirev = pcierev = (uint)NOREV;
+ pciidx = pcieidx = BADIDX;
+
+ for (i = 0; i < sii->numcores; i++) {
+ uint cid, crev;
+
+ si_setcoreidx(&sii->pub, i);
+ cid = si_coreid(&sii->pub);
+ crev = si_corerev(&sii->pub);
+
+ /* Display cores found */
+ AP6210_DEBUG("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
+ i, cid, crev, sii->coresba[i], sii->regs[i]);
+
+ if (BUSTYPE(bustype) == PCI_BUS) {
+ if (cid == PCI_CORE_ID) {
+ pciidx = i;
+ pcirev = crev;
+ pci = TRUE;
+ } else if ((cid == PCIE_CORE_ID) || (cid == PCIE2_CORE_ID)) {
+ pcieidx = i;
+ pcierev = crev;
+ pcie = TRUE;
+ if (cid == PCIE2_CORE_ID)
+ pcie_gen2 = TRUE;
+ }
+ } else if ((BUSTYPE(bustype) == PCMCIA_BUS) &&
+ (cid == PCMCIA_CORE_ID)) {
+ sii->pub.buscorerev = crev;
+ sii->pub.buscoretype = cid;
+ sii->pub.buscoreidx = i;
+ }
+ else if (((BUSTYPE(bustype) == SDIO_BUS) ||
+ (BUSTYPE(bustype) == SPI_BUS)) &&
+ ((cid == PCMCIA_CORE_ID) ||
+ (cid == SDIOD_CORE_ID))) {
+ sii->pub.buscorerev = crev;
+ sii->pub.buscoretype = cid;
+ sii->pub.buscoreidx = i;
+ }
+
+ /* find the core idx before entering this func. */
+ if ((savewin && (savewin == sii->coresba[i])) ||
+ (regs == sii->regs[i]))
+ *origidx = i;
+ }
+
+ if (pci) {
+ sii->pub.buscoretype = PCI_CORE_ID;
+ sii->pub.buscorerev = pcirev;
+ sii->pub.buscoreidx = pciidx;
+ } else if (pcie) {
+ if (pcie_gen2)
+ sii->pub.buscoretype = PCIE2_CORE_ID;
+ else
+ sii->pub.buscoretype = PCIE_CORE_ID;
+ sii->pub.buscorerev = pcierev;
+ sii->pub.buscoreidx = pcieidx;
+ }
+
+ AP6210_DEBUG("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype,
+ sii->pub.buscorerev);
+
+ if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) &&
+ (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (CHIPREV(sii->pub.chiprev) <= 3))
+ OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL);
+
+
+ /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was
+ * already running.
+ */
+ if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) {
+ if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
+ si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
+ si_core_disable(&sii->pub, 0);
+ }
+
+ /* return to the original core */
+ si_setcoreidx(&sii->pub, *origidx);
+
+ return TRUE;
+}
+
+
+
+
+static si_info_t *
+si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
+ uint bustype, void *sdh, char **vars, uint *varsz)
+{
+ struct si_pub *sih = &sii->pub;
+ uint32 w, savewin;
+ chipcregs_t *cc;
+ char *pvars = NULL;
+ uint origidx;
+
+ ASSERT(GOODREGS(regs));
+
+ bzero((uchar*)sii, sizeof(si_info_t));
+
+ savewin = 0;
+
+ sih->buscoreidx = BADIDX;
+
+ sii->curmap = regs;
+ sii->sdh = sdh;
+ sii->osh = osh;
+
+
+
+ /* find Chipcommon address */
+ if (bustype == PCI_BUS) {
+ savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
+ if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
+ savewin = SI_ENUM_BASE;
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
+ if (!regs)
+ return NULL;
+ cc = (chipcregs_t *)regs;
+ } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
+ cc = (chipcregs_t *)sii->curmap;
+ } else {
+ cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
+ }
+
+ sih->bustype = bustype;
+ if (bustype != BUSTYPE(bustype)) {
+ AP6210_ERR("si_doattach: bus type %d does not match configured bus type %d\n",
+ bustype, BUSTYPE(bustype));
+ return NULL;
+ }
+
+ /* bus/core/clk setup for register access */
+ if (!si_buscore_prep(sii, bustype, devid, sdh)) {
+ AP6210_ERR("si_doattach: si_core_clk_prep failed %d\n", bustype);
+ return NULL;
+ }
+
+ /* ChipID recognition.
+ * We assume we can read chipid at offset 0 from the regs arg.
+ * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
+ * some way of recognizing them needs to be added here.
+ */
+ if (!cc) {
+ AP6210_ERR("%s: chipcommon register space is null \n", __FUNCTION__);
+ return NULL;
+ }
+ w = R_REG(osh, &cc->chipid);
+ sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
+ /* Might as wll fill in chip id rev & pkg */
+ sih->chip = w & CID_ID_MASK;
+ sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
+ sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
+
+#if defined(HW_OOB)
+ bcmsdh_config_hw_oob_intr(sdh, sih->chip);
+#endif
+
+ if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) &&
+ (sih->chippkg != BCM4329_289PIN_PKG_ID)) {
+ sih->chippkg = BCM4329_182PIN_PKG_ID;
+ }
+ sih->issim = IS_SIM(sih->chippkg);
+
+ /* scan for cores */
+ if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
+ AP6210_DEBUG("Found chip type SB (0x%08x)\n", w);
+ sb_scan(&sii->pub, regs, devid);
+ } else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) {
+ AP6210_DEBUG("Found chip type AI (0x%08x)\n", w);
+ /* pass chipc address instead of original core base */
+ ai_scan(&sii->pub, (void *)(uintptr)cc, devid);
+ } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) {
+ AP6210_DEBUG("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip);
+ /* pass chipc address instead of original core base */
+ ub_scan(&sii->pub, (void *)(uintptr)cc, devid);
+ } else {
+ AP6210_ERR("Found chip of unknown type (0x%08x)\n", w);
+ return NULL;
+ }
+ /* no cores found, bail out */
+ if (sii->numcores == 0) {
+ AP6210_ERR("si_doattach: could not find any cores\n");
+ return NULL;
+ }
+ /* bus/core/clk setup */
+ origidx = SI_CC_IDX;
+ if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
+ AP6210_ERR("si_doattach: si_buscore_setup failed\n");
+ goto exit;
+ }
+
+ if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK)
+ >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT |
+ CST4322_SPROM_PRESENT))) {
+ AP6210_ERR("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__);
+ return NULL;
+ }
+
+ /* assume current core is CC */
+ if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID ||
+ CHIPID(sih->chip) == BCM43235_CHIP_ID ||
+ CHIPID(sih->chip) == BCM43234_CHIP_ID ||
+ CHIPID(sih->chip) == BCM43238_CHIP_ID) &&
+ (CHIPREV(sii->pub.chiprev) <= 2))) {
+
+ if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
+ uint clkdiv;
+ clkdiv = R_REG(osh, &cc->clkdiv);
+ /* otp_clk_div is even number, 120/14 < 9mhz */
+ clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
+ W_REG(osh, &cc->clkdiv, clkdiv);
+ AP6210_ERR("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv);
+ }
+ OSL_DELAY(10);
+ }
+
+ if (bustype == PCI_BUS) {
+
+ }
+
+ pvars = NULL;
+ BCM_REFERENCE(pvars);
+
+
+
+ if (sii->pub.ccrev >= 20) {
+ uint32 gpiopullup = 0, gpiopulldown = 0;
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+ ASSERT(cc != NULL);
+
+ /* 4314/43142 has pin muxing, don't clear gpio bits */
+ if ((CHIPID(sih->chip) == BCM4314_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM43142_CHIP_ID)) {
+ gpiopullup |= 0x402e0;
+ gpiopulldown |= 0x20500;
+ }
+
+ W_REG(osh, &cc->gpiopullup, gpiopullup);
+ W_REG(osh, &cc->gpiopulldown, gpiopulldown);
+ si_setcoreidx(sih, origidx);
+ }
+
+
+ /* clear any previous epidiag-induced target abort */
+ ASSERT(!si_taclear(sih, FALSE));
+
+ return (sii);
+
+exit:
+
+ return NULL;
+}
+
+/* may be called with core in reset */
+void
+si_detach(si_t *sih)
+{
+ si_info_t *sii;
+ uint idx;
+
+
+ sii = SI_INFO(sih);
+
+ if (sii == NULL)
+ return;
+
+ if (BUSTYPE(sih->bustype) == SI_BUS)
+ for (idx = 0; idx < SI_MAXCORES; idx++)
+ if (sii->regs[idx]) {
+ REG_UNMAP(sii->regs[idx]);
+ sii->regs[idx] = NULL;
+ }
+
+
+
+#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
+ if (sii != &ksii)
+#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
+ MFREE(sii->osh, sii, sizeof(si_info_t));
+}
+
+void *
+si_osh(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ return sii->osh;
+}
+
+void
+si_setosh(si_t *sih, osl_t *osh)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ if (sii->osh != NULL) {
+ AP6210_ERR("osh is already set....\n");
+ ASSERT(!sii->osh);
+ }
+ sii->osh = osh;
+}
+
+/* register driver interrupt disabling and restoring callback functions */
+void
+si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
+ void *intrsenabled_fn, void *intr_arg)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ sii->intr_arg = intr_arg;
+ sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn;
+ sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn;
+ sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn;
+ /* save current core id. when this function called, the current core
+ * must be the core which provides driver functions(il, et, wl, etc.)
+ */
+ sii->dev_coreid = sii->coreid[sii->curidx];
+}
+
+void
+si_deregister_intr_callback(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ sii->intrsoff_fn = NULL;
+}
+
+uint
+si_intflag(si_t *sih)
+{
+ si_info_t *sii = SI_INFO(sih);
+
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_intflag(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return R_REG(sii->osh, ((uint32 *)(uintptr)
+ (sii->oob_router + OOB_STATUSA)));
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+uint
+si_flag(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_flag(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_flag(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_flag(sih);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+void
+si_setint(si_t *sih, int siflag)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ sb_setint(sih, siflag);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_setint(sih, siflag);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ ub_setint(sih, siflag);
+ else
+ ASSERT(0);
+}
+
+uint
+si_coreid(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ return sii->coreid[sii->curidx];
+}
+
+uint
+si_coreidx(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ return sii->curidx;
+}
+
+/* return the core-type instantiation # of the current core */
+uint
+si_coreunit(si_t *sih)
+{
+ si_info_t *sii;
+ uint idx;
+ uint coreid;
+ uint coreunit;
+ uint i;
+
+ sii = SI_INFO(sih);
+ coreunit = 0;
+
+ idx = sii->curidx;
+
+ ASSERT(GOODREGS(sii->curmap));
+ coreid = si_coreid(sih);
+
+ /* count the cores of our type */
+ for (i = 0; i < idx; i++)
+ if (sii->coreid[i] == coreid)
+ coreunit++;
+
+ return (coreunit);
+}
+
+uint
+si_corevendor(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_corevendor(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_corevendor(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_corevendor(sih);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+bool
+si_backplane64(si_t *sih)
+{
+ return ((sih->cccaps & CC_CAP_BKPLN64) != 0);
+}
+
+uint
+si_corerev(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_corerev(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_corerev(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_corerev(sih);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+/* return index of coreid or BADIDX if not found */
+uint
+si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
+{
+ si_info_t *sii;
+ uint found;
+ uint i;
+
+ sii = SI_INFO(sih);
+
+ found = 0;
+
+ for (i = 0; i < sii->numcores; i++)
+ if (sii->coreid[i] == coreid) {
+ if (found == coreunit)
+ return (i);
+ found++;
+ }
+
+ return (BADIDX);
+}
+
+/* return list of found cores */
+uint
+si_corelist(si_t *sih, uint coreid[])
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ bcopy((uchar*)sii->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint)));
+ return (sii->numcores);
+}
+
+/* return current register mapping */
+void *
+si_coreregs(si_t *sih)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ ASSERT(GOODREGS(sii->curmap));
+
+ return (sii->curmap);
+}
+
+/*
+ * This function changes logical "focus" to the indicated core;
+ * must be called with interrupts off.
+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core
+ */
+void *
+si_setcore(si_t *sih, uint coreid, uint coreunit)
+{
+ uint idx;
+
+ idx = si_findcoreidx(sih, coreid, coreunit);
+ if (!GOODIDX(idx))
+ return (NULL);
+
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_setcoreidx(sih, idx);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_setcoreidx(sih, idx);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_setcoreidx(sih, idx);
+ else {
+ ASSERT(0);
+ return NULL;
+ }
+}
+
+void *
+si_setcoreidx(si_t *sih, uint coreidx)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_setcoreidx(sih, coreidx);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_setcoreidx(sih, coreidx);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_setcoreidx(sih, coreidx);
+ else {
+ ASSERT(0);
+ return NULL;
+ }
+}
+
+/* Turn off interrupt as required by sb_setcore, before switch core */
+void *
+si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
+{
+ void *cc;
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ if (SI_FAST(sii)) {
+ /* Overloading the origidx variable to remember the coreid,
+ * this works because the core ids cannot be confused with
+ * core indices.
+ */
+ *origidx = coreid;
+ if (coreid == CC_CORE_ID)
+ return (void *)CCREGS_FAST(sii);
+ else if (coreid == sih->buscoretype)
+ return (void *)PCIEREGS(sii);
+ }
+ INTR_OFF(sii, *intr_val);
+ *origidx = sii->curidx;
+ cc = si_setcore(sih, coreid, 0);
+ ASSERT(cc != NULL);
+
+ return cc;
+}
+
+/* restore coreidx and restore interrupt */
+void
+si_restore_core(si_t *sih, uint coreid, uint intr_val)
+{
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+ if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
+ return;
+
+ si_setcoreidx(sih, coreid);
+ INTR_RESTORE(sii, intr_val);
+}
+
+int
+si_numaddrspaces(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_numaddrspaces(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_numaddrspaces(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_numaddrspaces(sih);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+uint32
+si_addrspace(si_t *sih, uint asidx)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_addrspace(sih, asidx);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_addrspace(sih, asidx);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_addrspace(sih, asidx);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+uint32
+si_addrspacesize(si_t *sih, uint asidx)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_addrspacesize(sih, asidx);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_addrspacesize(sih, asidx);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_addrspacesize(sih, asidx);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+void
+si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size)
+{
+ /* Only supported for SOCI_AI */
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_coreaddrspaceX(sih, asidx, addr, size);
+ else
+ *size = 0;
+}
+
+uint32
+si_core_cflags(si_t *sih, uint32 mask, uint32 val)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_core_cflags(sih, mask, val);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_core_cflags(sih, mask, val);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_core_cflags(sih, mask, val);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+void
+si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ sb_core_cflags_wo(sih, mask, val);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_core_cflags_wo(sih, mask, val);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ ub_core_cflags_wo(sih, mask, val);
+ else
+ ASSERT(0);
+}
+
+uint32
+si_core_sflags(si_t *sih, uint32 mask, uint32 val)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_core_sflags(sih, mask, val);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_core_sflags(sih, mask, val);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_core_sflags(sih, mask, val);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+bool
+si_iscoreup(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_iscoreup(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_iscoreup(sih);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_iscoreup(sih);
+ else {
+ ASSERT(0);
+ return FALSE;
+ }
+}
+
+uint
+si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
+{
+ /* only for AI back plane chips */
+ if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return (ai_wrap_reg(sih, offset, mask, val));
+ return 0;
+}
+
+uint
+si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return sb_corereg(sih, coreidx, regoff, mask, val);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ return ai_corereg(sih, coreidx, regoff, mask, val);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ return ub_corereg(sih, coreidx, regoff, mask, val);
+ else {
+ ASSERT(0);
+ return 0;
+ }
+}
+
+void
+si_core_disable(si_t *sih, uint32 bits)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ sb_core_disable(sih, bits);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_core_disable(sih, bits);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ ub_core_disable(sih, bits);
+}
+
+void
+si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ sb_core_reset(sih, bits, resetbits);
+ else if (CHIPTYPE(sih->socitype) == SOCI_AI)
+ ai_core_reset(sih, bits, resetbits);
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ ub_core_reset(sih, bits, resetbits);
+}
+
+/* Run bist on current core. Caller needs to take care of core-specific bist hazards */
+int
+si_corebist(si_t *sih)
+{
+ uint32 cflags;
+ int result = 0;
+
+ /* Read core control flags */
+ cflags = si_core_cflags(sih, 0, 0);
+
+ /* Set bist & fgc */
+ si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
+
+ /* Wait for bist done */
+ SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
+
+ if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
+ result = BCME_ERROR;
+
+ /* Reset core control flags */
+ si_core_cflags(sih, 0xffff, cflags);
+
+ return result;
+}
+
+static uint32
+factor6(uint32 x)
+{
+ switch (x) {
+ case CC_F6_2: return 2;
+ case CC_F6_3: return 3;
+ case CC_F6_4: return 4;
+ case CC_F6_5: return 5;
+ case CC_F6_6: return 6;
+ case CC_F6_7: return 7;
+ default: return 0;
+ }
+}
+
+/* calculate the speed the SI would run at given a set of clockcontrol values */
+uint32
+si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
+{
+ uint32 n1, n2, clock, m1, m2, m3, mc;
+
+ n1 = n & CN_N1_MASK;
+ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
+
+ if (pll_type == PLL_TYPE6) {
+ if (m & CC_T6_MMASK)
+ return CC_T6_M1;
+ else
+ return CC_T6_M0;
+ } else if ((pll_type == PLL_TYPE1) ||
+ (pll_type == PLL_TYPE3) ||
+ (pll_type == PLL_TYPE4) ||
+ (pll_type == PLL_TYPE7)) {
+ n1 = factor6(n1);
+ n2 += CC_F5_BIAS;
+ } else if (pll_type == PLL_TYPE2) {
+ n1 += CC_T2_BIAS;
+ n2 += CC_T2_BIAS;
+ ASSERT((n1 >= 2) && (n1 <= 7));
+ ASSERT((n2 >= 5) && (n2 <= 23));
+ } else if (pll_type == PLL_TYPE5) {
+ return (100000000);
+ } else
+ ASSERT(0);
+ /* PLL types 3 and 7 use BASE2 (25Mhz) */
+ if ((pll_type == PLL_TYPE3) ||
+ (pll_type == PLL_TYPE7)) {
+ clock = CC_CLOCK_BASE2 * n1 * n2;
+ } else
+ clock = CC_CLOCK_BASE1 * n1 * n2;
+
+ if (clock == 0)
+ return 0;
+
+ m1 = m & CC_M1_MASK;
+ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
+ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
+ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
+
+ if ((pll_type == PLL_TYPE1) ||
+ (pll_type == PLL_TYPE3) ||
+ (pll_type == PLL_TYPE4) ||
+ (pll_type == PLL_TYPE7)) {
+ m1 = factor6(m1);
+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
+ m2 += CC_F5_BIAS;
+ else
+ m2 = factor6(m2);
+ m3 = factor6(m3);
+
+ switch (mc) {
+ case CC_MC_BYPASS: return (clock);
+ case CC_MC_M1: return (clock / m1);
+ case CC_MC_M1M2: return (clock / (m1 * m2));
+ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3));
+ case CC_MC_M1M3: return (clock / (m1 * m3));
+ default: return (0);
+ }
+ } else {
+ ASSERT(pll_type == PLL_TYPE2);
+
+ m1 += CC_T2_BIAS;
+ m2 += CC_T2M2_BIAS;
+ m3 += CC_T2_BIAS;
+ ASSERT((m1 >= 2) && (m1 <= 7));
+ ASSERT((m2 >= 3) && (m2 <= 10));
+ ASSERT((m3 >= 2) && (m3 <= 7));
+
+ if ((mc & CC_T2MC_M1BYP) == 0)
+ clock /= m1;
+ if ((mc & CC_T2MC_M2BYP) == 0)
+ clock /= m2;
+ if ((mc & CC_T2MC_M3BYP) == 0)
+ clock /= m3;
+
+ return (clock);
+ }
+}
+
+
+/* set chip watchdog reset timer to fire in 'ticks' */
+void
+si_watchdog(si_t *sih, uint ticks)
+{
+ uint nb, maxt;
+
+ if (PMUCTL_ENAB(sih)) {
+
+ if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) &&
+ (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) {
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2);
+ si_setcore(sih, USB20D_CORE_ID, 0);
+ si_core_disable(sih, 1);
+ si_setcore(sih, CC_CORE_ID, 0);
+ }
+
+ nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
+ /* The mips compiler uses the sllv instruction,
+ * so we specially handle the 32-bit case.
+ */
+ if (nb == 32)
+ maxt = 0xffffffff;
+ else
+ maxt = ((1 << nb) - 1);
+
+ if (ticks == 1)
+ ticks = 2;
+ else if (ticks > maxt)
+ ticks = maxt;
+
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog), ~0, ticks);
+ } else {
+ maxt = (1 << 28) - 1;
+ if (ticks > maxt)
+ ticks = maxt;
+
+ si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
+ }
+}
+
+/* trigger watchdog reset after ms milliseconds */
+void
+si_watchdog_ms(si_t *sih, uint32 ms)
+{
+ si_watchdog(sih, wd_msticks * ms);
+}
+
+uint32 si_watchdog_msticks(void)
+{
+ return wd_msticks;
+}
+
+bool
+si_taclear(si_t *sih, bool details)
+{
+ return FALSE;
+}
+
+
+
+/* return the slow clock source - LPO, XTAL, or PCI */
+static uint
+si_slowclk_src(si_info_t *sii)
+{
+ chipcregs_t *cc;
+
+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
+
+ if (sii->pub.ccrev < 6) {
+ if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
+ (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) &
+ PCI_CFG_GPIO_SCS))
+ return (SCC_SS_PCI);
+ else
+ return (SCC_SS_XTAL);
+ } else if (sii->pub.ccrev < 10) {
+ cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx);
+ return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
+ } else /* Insta-clock */
+ return (SCC_SS_XTAL);
+}
+
+/* return the ILP (slowclock) min or max frequency */
+static uint
+si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
+{
+ uint32 slowclk;
+ uint div;
+
+ ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
+
+ /* shouldn't be here unless we've established the chip has dynamic clk control */
+ ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
+
+ slowclk = si_slowclk_src(sii);
+ if (sii->pub.ccrev < 6) {
+ if (slowclk == SCC_SS_PCI)
+ return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64));
+ else
+ return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32));
+ } else if (sii->pub.ccrev < 10) {
+ div = 4 *
+ (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
+ if (slowclk == SCC_SS_LPO)
+ return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
+ else if (slowclk == SCC_SS_XTAL)
+ return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div));
+ else if (slowclk == SCC_SS_PCI)
+ return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div));
+ else
+ ASSERT(0);
+ } else {
+ /* Chipc rev 10 is InstaClock */
+ div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
+ div = 4 * (div + 1);
+ return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
+ }
+ return (0);
+}
+
+static void
+si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
+{
+ chipcregs_t *cc = (chipcregs_t *)chipcregs;
+ uint slowmaxfreq, pll_delay, slowclk;
+ uint pll_on_delay, fref_sel_delay;
+
+ pll_delay = PLL_DELAY;
+
+ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
+ * since the xtal will also be powered down by dynamic clk control logic.
+ */
+
+ slowclk = si_slowclk_src(sii);
+ if (slowclk != SCC_SS_XTAL)
+ pll_delay += XTAL_ON_DELAY;
+
+ /* Starting with 4318 it is ILP that is used for the delays */
+ slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc);
+
+ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
+ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
+
+ W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
+ W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
+}
+
+/* initialize power control delay registers */
+void
+si_clkctl_init(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx = 0;
+ chipcregs_t *cc;
+ bool fast;
+
+ if (!CCCTL_ENAB(sih))
+ return;
+
+ sii = SI_INFO(sih);
+ fast = SI_FAST(sii);
+ if (!fast) {
+ origidx = sii->curidx;
+ if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL)
+ return;
+ } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL)
+ return;
+ ASSERT(cc != NULL);
+
+ /* set all Instaclk chip ILP to 1 MHz */
+ if (sih->ccrev >= 10)
+ SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
+ (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
+
+ si_clkctl_setdelay(sii, (void *)(uintptr)cc);
+
+ if (!fast)
+ si_setcoreidx(sih, origidx);
+}
+
+
+/* change logical "focus" to the gpio core for optimized access */
+void *
+si_gpiosetcore(si_t *sih)
+{
+ return (si_setcoreidx(sih, SI_CC_IDX));
+}
+
+/*
+ * mask & set gpiocontrol bits.
+ * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin.
+ * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated
+ * to some chip-specific purpose.
+ */
+uint32
+si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+
+ regoff = 0;
+
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpiocontrol);
+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
+}
+
+/* mask&set gpio output enable bits */
+uint32
+si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+
+ regoff = 0;
+
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpioouten);
+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
+}
+
+/* mask&set gpio output bits */
+uint32
+si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+
+ regoff = 0;
+
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpioout);
+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
+}
+
+/* reserve one gpio */
+uint32
+si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority)
+{
+ /* only cores on SI_BUS share GPIO's and only applcation users need to
+ * reserve/release GPIO
+ */
+ if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
+ ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
+ return 0xffffffff;
+ }
+ /* make sure only one bit is set */
+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
+ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
+ return 0xffffffff;
+ }
+
+ /* already reserved */
+ if (si_gpioreservation & gpio_bitmask)
+ return 0xffffffff;
+ /* set reservation */
+ si_gpioreservation |= gpio_bitmask;
+
+ return si_gpioreservation;
+}
+
+/* release one gpio */
+/*
+ * releasing the gpio doesn't change the current value on the GPIO last write value
+ * persists till some one overwrites it
+ */
+
+uint32
+si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority)
+{
+ /* only cores on SI_BUS share GPIO's and only applcation users need to
+ * reserve/release GPIO
+ */
+ if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
+ ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
+ return 0xffffffff;
+ }
+ /* make sure only one bit is set */
+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
+ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
+ return 0xffffffff;
+ }
+
+ /* already released */
+ if (!(si_gpioreservation & gpio_bitmask))
+ return 0xffffffff;
+
+ /* clear reservation */
+ si_gpioreservation &= ~gpio_bitmask;
+
+ return si_gpioreservation;
+}
+
+/* return the current gpioin register value */
+uint32
+si_gpioin(si_t *sih)
+{
+ uint regoff;
+
+ regoff = OFFSETOF(chipcregs_t, gpioin);
+ return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0));
+}
+
+/* mask&set gpio interrupt polarity bits */
+uint32
+si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+
+ /* gpios could be shared on router platforms */
+ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
+}
+
+/* mask&set gpio interrupt mask bits */
+uint32
+si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+
+ /* gpios could be shared on router platforms */
+ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+
+ regoff = OFFSETOF(chipcregs_t, gpiointmask);
+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
+}
+
+/* assign the gpio to an led */
+uint32
+si_gpioled(si_t *sih, uint32 mask, uint32 val)
+{
+ if (sih->ccrev < 16)
+ return 0xffffffff;
+
+ /* gpio led powersave reg */
+ return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
+}
+
+/* mask&set gpio timer val */
+uint32
+si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
+{
+ if (sih->ccrev < 16)
+ return 0xffffffff;
+
+ return (si_corereg(sih, SI_CC_IDX,
+ OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
+}
+
+uint32
+si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
+{
+ uint offs;
+
+ if (sih->ccrev < 20)
+ return 0xffffffff;
+
+ offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup));
+ return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
+}
+
+uint32
+si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
+{
+ uint offs;
+
+ if (sih->ccrev < 11)
+ return 0xffffffff;
+
+ if (regtype == GPIO_REGEVT)
+ offs = OFFSETOF(chipcregs_t, gpioevent);
+ else if (regtype == GPIO_REGEVT_INTMSK)
+ offs = OFFSETOF(chipcregs_t, gpioeventintmask);
+ else if (regtype == GPIO_REGEVT_INTPOL)
+ offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
+ else
+ return 0xffffffff;
+
+ return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
+}
+
+void *
+si_gpio_handler_register(si_t *sih, uint32 event,
+ bool level, gpio_handler_t cb, void *arg)
+{
+ si_info_t *sii;
+ gpioh_item_t *gi;
+
+ ASSERT(event);
+ ASSERT(cb != NULL);
+
+ sii = SI_INFO(sih);
+ if (sih->ccrev < 11)
+ return NULL;
+
+ if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL)
+ return NULL;
+
+ bzero(gi, sizeof(gpioh_item_t));
+ gi->event = event;
+ gi->handler = cb;
+ gi->arg = arg;
+ gi->level = level;
+
+ gi->next = sii->gpioh_head;
+ sii->gpioh_head = gi;
+
+ return (void *)(gi);
+}
+
+void
+si_gpio_handler_unregister(si_t *sih, void *gpioh)
+{
+ si_info_t *sii;
+ gpioh_item_t *p, *n;
+
+ sii = SI_INFO(sih);
+ if (sih->ccrev < 11)
+ return;
+
+ ASSERT(sii->gpioh_head != NULL);
+ if ((void*)sii->gpioh_head == gpioh) {
+ sii->gpioh_head = sii->gpioh_head->next;
+ MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
+ return;
+ } else {
+ p = sii->gpioh_head;
+ n = p->next;
+ while (n) {
+ if ((void*)n == gpioh) {
+ p->next = n->next;
+ MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
+ return;
+ }
+ p = n;
+ n = n->next;
+ }
+ }
+
+ ASSERT(0); /* Not found in list */
+}
+
+void
+si_gpio_handler_process(si_t *sih)
+{
+ si_info_t *sii;
+ gpioh_item_t *h;
+ uint32 level = si_gpioin(sih);
+ uint32 levelp = si_gpiointpolarity(sih, 0, 0, 0);
+ uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0);
+ uint32 edgep = si_gpioevent(sih, GPIO_REGEVT_INTPOL, 0, 0);
+
+ sii = SI_INFO(sih);
+ for (h = sii->gpioh_head; h != NULL; h = h->next) {
+ if (h->handler) {
+ uint32 status = (h->level ? level : edge) & h->event;
+ uint32 polarity = (h->level ? levelp : edgep) & h->event;
+
+ /* polarity bitval is opposite of status bitval */
+ if (status ^ polarity)
+ h->handler(status, h->arg);
+ }
+ }
+
+ si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */
+}
+
+uint32
+si_gpio_int_enable(si_t *sih, bool enable)
+{
+ uint offs;
+
+ if (sih->ccrev < 11)
+ return 0xffffffff;
+
+ offs = OFFSETOF(chipcregs_t, intmask);
+ return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
+}
+
+
+/* Return the size of the specified SOCRAM bank */
+static uint
+socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type)
+{
+ uint banksize, bankinfo;
+ uint bankidx = idx | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
+
+ ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
+
+ W_REG(sii->osh, &regs->bankidx, bankidx);
+ bankinfo = R_REG(sii->osh, &regs->bankinfo);
+ banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
+ return banksize;
+}
+
+void
+si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ sbsocramregs_t *regs;
+ bool wasup;
+ uint corerev;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ if (!set)
+ *enable = *protect = *remap = 0;
+
+ /* Switch to SOCRAM core */
+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
+ goto done;
+
+ /* Get info for determining size */
+ if (!(wasup = si_iscoreup(sih)))
+ si_core_reset(sih, 0, 0);
+
+ corerev = si_corerev(sih);
+ if (corerev >= 10) {
+ uint32 extcinfo;
+ uint8 nb;
+ uint8 i;
+ uint32 bankidx, bankinfo;
+
+ extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
+ nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
+ for (i = 0; i < nb; i++) {
+ bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
+ W_REG(sii->osh, &regs->bankidx, bankidx);
+ bankinfo = R_REG(sii->osh, &regs->bankinfo);
+ if (set) {
+ bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
+ bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
+ bankinfo &= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK;
+ if (*enable) {
+ bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
+ if (*protect)
+ bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
+ if ((corerev >= 16) && *remap)
+ bankinfo |=
+ (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT);
+ }
+ W_REG(sii->osh, &regs->bankinfo, bankinfo);
+ }
+ else if (i == 0) {
+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
+ *enable = 1;
+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK)
+ *protect = 1;
+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK)
+ *remap = 1;
+ }
+ }
+ }
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+done:
+ INTR_RESTORE(sii, intr_val);
+}
+
+bool
+si_socdevram_remap_isenb(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ sbsocramregs_t *regs;
+ bool wasup, remap = FALSE;
+ uint corerev;
+ uint32 extcinfo;
+ uint8 nb;
+ uint8 i;
+ uint32 bankidx, bankinfo;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ /* Switch to SOCRAM core */
+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
+ goto done;
+
+ /* Get info for determining size */
+ if (!(wasup = si_iscoreup(sih)))
+ si_core_reset(sih, 0, 0);
+
+ corerev = si_corerev(sih);
+ if (corerev >= 16) {
+ extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
+ nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
+ for (i = 0; i < nb; i++) {
+ bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
+ W_REG(sii->osh, &regs->bankidx, bankidx);
+ bankinfo = R_REG(sii->osh, &regs->bankinfo);
+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) {
+ remap = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+done:
+ INTR_RESTORE(sii, intr_val);
+ return remap;
+}
+
+bool
+si_socdevram_pkg(si_t *sih)
+{
+ if (si_socdevram_size(sih) > 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+uint32
+si_socdevram_size(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ uint32 memsize = 0;
+ sbsocramregs_t *regs;
+ bool wasup;
+ uint corerev;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ /* Switch to SOCRAM core */
+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
+ goto done;
+
+ /* Get info for determining size */
+ if (!(wasup = si_iscoreup(sih)))
+ si_core_reset(sih, 0, 0);
+
+ corerev = si_corerev(sih);
+ if (corerev >= 10) {
+ uint32 extcinfo;
+ uint8 nb;
+ uint8 i;
+
+ extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
+ nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
+ for (i = 0; i < nb; i++)
+ memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+done:
+ INTR_RESTORE(sii, intr_val);
+
+ return memsize;
+}
+
+uint32
+si_socdevram_remap_size(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ uint32 memsize = 0, banksz;
+ sbsocramregs_t *regs;
+ bool wasup;
+ uint corerev;
+ uint32 extcinfo;
+ uint8 nb;
+ uint8 i;
+ uint32 bankidx, bankinfo;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ /* Switch to SOCRAM core */
+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
+ goto done;
+
+ /* Get info for determining size */
+ if (!(wasup = si_iscoreup(sih)))
+ si_core_reset(sih, 0, 0);
+
+ corerev = si_corerev(sih);
+ if (corerev >= 16) {
+ extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
+ nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
+
+ /*
+ * FIX: A0 Issue: Max addressable is 512KB, instead 640KB
+ * Only four banks are accessible to ARM
+ */
+ if ((corerev == 16) && (nb == 5))
+ nb = 4;
+
+ for (i = 0; i < nb; i++) {
+ bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
+ W_REG(sii->osh, &regs->bankidx, bankidx);
+ bankinfo = R_REG(sii->osh, &regs->bankinfo);
+ if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) {
+ banksz = socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
+ memsize += banksz;
+ } else {
+ /* Account only consecutive banks for now */
+ break;
+ }
+ }
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+done:
+ INTR_RESTORE(sii, intr_val);
+
+ return memsize;
+}
+
+/* Return the RAM size of the SOCRAM core */
+uint32
+si_socram_size(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+
+ sbsocramregs_t *regs;
+ bool wasup;
+ uint corerev;
+ uint32 coreinfo;
+ uint memsize = 0;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ /* Switch to SOCRAM core */
+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
+ goto done;
+
+ /* Get info for determining size */
+ if (!(wasup = si_iscoreup(sih)))
+ si_core_reset(sih, 0, 0);
+ corerev = si_corerev(sih);
+ coreinfo = R_REG(sii->osh, &regs->coreinfo);
+
+ /* Calculate size from coreinfo based on rev */
+ if (corerev == 0)
+ memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
+ else if (corerev < 3) {
+ memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
+ memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ } else if ((corerev <= 7) || (corerev == 12)) {
+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
+ uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
+ if (lss != 0)
+ nb --;
+ memsize = nb * (1 << (bsz + SR_BSZ_BASE));
+ if (lss != 0)
+ memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
+ } else {
+ uint8 i;
+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ for (i = 0; i < nb; i++)
+ memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+done:
+ INTR_RESTORE(sii, intr_val);
+
+ return memsize;
+}
+
+
+/* Return the TCM-RAM size of the ARMCR4 core. */
+uint32
+si_tcm_size(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ uint8 *regs;
+ bool wasup;
+ uint32 corecap;
+ uint memsize = 0;
+ uint32 nab = 0;
+ uint32 nbb = 0;
+ uint32 totb = 0;
+ uint32 bxinfo = 0;
+ uint32 idx = 0;
+ uint32 *arm_cap_reg;
+ uint32 *arm_bidx;
+ uint32 *arm_binfo;
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ /* Switch to CR4 core */
+ if (!(regs = si_setcore(sih, ARMCR4_CORE_ID, 0)))
+ goto done;
+
+ /* Get info for determining size. If in reset, come out of reset,
+ * but remain in halt
+ */
+ if (!(wasup = si_iscoreup(sih)))
+ si_core_reset(sih, SICF_CPUHALT, SICF_CPUHALT);
+
+ arm_cap_reg = (uint32 *)(regs + SI_CR4_CAP);
+ corecap = R_REG(sii->osh, arm_cap_reg);
+
+ nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
+ nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
+ totb = nab + nbb;
+
+ arm_bidx = (uint32 *)(regs + SI_CR4_BANKIDX);
+ arm_binfo = (uint32 *)(regs + SI_CR4_BANKINFO);
+ for (idx = 0; idx < totb; idx++) {
+ W_REG(sii->osh, arm_bidx, idx);
+
+ bxinfo = R_REG(sii->osh, arm_binfo);
+ memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+done:
+ INTR_RESTORE(sii, intr_val);
+
+ return memsize;
+}
+
+uint32
+si_socram_srmem_size(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+
+ sbsocramregs_t *regs;
+ bool wasup;
+ uint corerev;
+ uint32 coreinfo;
+ uint memsize = 0;
+
+ if ((CHIPID(sih->chip) == BCM4334_CHIP_ID) && (CHIPREV(sih->chiprev) < 2)) {
+ return (32 * 1024);
+ }
+
+ sii = SI_INFO(sih);
+
+ /* Block ints and save current core */
+ INTR_OFF(sii, intr_val);
+ origidx = si_coreidx(sih);
+
+ /* Switch to SOCRAM core */
+ if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
+ goto done;
+
+ /* Get info for determining size */
+ if (!(wasup = si_iscoreup(sih)))
+ si_core_reset(sih, 0, 0);
+ corerev = si_corerev(sih);
+ coreinfo = R_REG(sii->osh, &regs->coreinfo);
+
+ /* Calculate size from coreinfo based on rev */
+ if (corerev >= 16) {
+ uint8 i;
+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ for (i = 0; i < nb; i++) {
+ W_REG(sii->osh, &regs->bankidx, i);
+ if (R_REG(sii->osh, &regs->bankinfo) & SOCRAM_BANKINFO_RETNTRAM_MASK)
+ memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
+ }
+ }
+
+ /* Return to previous state and core */
+ if (!wasup)
+ si_core_disable(sih, 0);
+ si_setcoreidx(sih, origidx);
+
+done:
+ INTR_RESTORE(sii, intr_val);
+
+ return memsize;
+}
+
+
+void
+si_btcgpiowar(si_t *sih)
+{
+ si_info_t *sii;
+ uint origidx;
+ uint intr_val = 0;
+ chipcregs_t *cc;
+
+ sii = SI_INFO(sih);
+
+ /* Make sure that there is ChipCommon core present &&
+ * UART_TX is strapped to 1
+ */
+ if (!(sih->cccaps & CC_CAP_UARTGPIO))
+ return;
+
+ /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
+ INTR_OFF(sii, intr_val);
+
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+ ASSERT(cc != NULL);
+
+ W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04);
+
+ /* restore the original index */
+ si_setcoreidx(sih, origidx);
+
+ INTR_RESTORE(sii, intr_val);
+}
+
+void
+si_chipcontrl_btshd0_4331(si_t *sih, bool on)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 val;
+ uint intr_val = 0;
+
+ sii = SI_INFO(sih);
+
+ INTR_OFF(sii, intr_val);
+
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+
+ val = R_REG(sii->osh, &cc->chipcontrol);
+
+ /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */
+ if (on) {
+ /* Enable bt_shd0 on gpio4: */
+ val |= (CCTRL4331_BT_SHD0_ON_GPIO4);
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ } else {
+ val &= ~(CCTRL4331_BT_SHD0_ON_GPIO4);
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ }
+
+ /* restore the original index */
+ si_setcoreidx(sih, origidx);
+
+ INTR_RESTORE(sii, intr_val);
+}
+
+void
+si_chipcontrl_restore(si_t *sih, uint32 val)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ si_setcoreidx(sih, origidx);
+}
+
+uint32
+si_chipcontrl_read(si_t *sih)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 val;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+ val = R_REG(sii->osh, &cc->chipcontrol);
+ si_setcoreidx(sih, origidx);
+ return val;
+}
+
+void
+si_chipcontrl_epa4331(si_t *sih, bool on)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 val;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+
+ val = R_REG(sii->osh, &cc->chipcontrol);
+
+ if (on) {
+ if (sih->chippkg == 9 || sih->chippkg == 0xb) {
+ val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
+ /* Ext PA Controls for 4331 12x9 Package */
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ } else {
+ /* Ext PA Controls for 4331 12x12 Package */
+ if (sih->chiprev > 0) {
+ W_REG(sii->osh, &cc->chipcontrol, val |
+ (CCTRL4331_EXTPA_EN) | (CCTRL4331_EXTPA_EN2));
+ } else {
+ W_REG(sii->osh, &cc->chipcontrol, val | (CCTRL4331_EXTPA_EN));
+ }
+ }
+ } else {
+ val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_EN2 | CCTRL4331_EXTPA_ON_GPIO2_5);
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ }
+
+ si_setcoreidx(sih, origidx);
+}
+
+/* switch muxed pins, on: SROM, off: FEMCTRL */
+void
+si_chipcontrl_srom4360(si_t *sih, bool on)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 val;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+
+ val = R_REG(sii->osh, &cc->chipcontrol);
+
+ if (on) {
+ val &= ~(CCTRL4360_SECI_MODE |
+ CCTRL4360_BTSWCTRL_MODE |
+ CCTRL4360_EXTRA_FEMCTRL_MODE |
+ CCTRL4360_BT_LGCY_MODE |
+ CCTRL4360_CORE2FEMCTRL4_ON);
+
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ } else {
+ }
+
+ si_setcoreidx(sih, origidx);
+}
+
+void
+si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 val;
+ bool sel_chip;
+
+ sel_chip = (CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM43431_CHIP_ID);
+ sel_chip &= ((sih->chippkg == 9 || sih->chippkg == 0xb));
+
+ if (!sel_chip)
+ return;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+
+ val = R_REG(sii->osh, &cc->chipcontrol);
+
+ if (enter_wowl) {
+ val |= CCTRL4331_EXTPA_EN;
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ } else {
+ val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
+ W_REG(sii->osh, &cc->chipcontrol, val);
+ }
+ si_setcoreidx(sih, origidx);
+}
+
+uint
+si_pll_reset(si_t *sih)
+{
+ uint err = 0;
+
+ return (err);
+}
+
+/* Enable BT-COEX & Ex-PA for 4313 */
+void
+si_epa_4313war(si_t *sih)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+
+ /* EPA Fix */
+ W_REG(sii->osh, &cc->gpiocontrol,
+ R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
+
+ si_setcoreidx(sih, origidx);
+}
+
+void
+si_clk_pmu_htavail_set(si_t *sih, bool set_clear)
+{
+}
+
+/* WL/BT control for 4313 btcombo boards >= P250 */
+void
+si_btcombo_p250_4313_war(si_t *sih)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+ W_REG(sii->osh, &cc->gpiocontrol,
+ R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_5_6_EN_MASK);
+
+ W_REG(sii->osh, &cc->gpioouten,
+ R_REG(sii->osh, &cc->gpioouten) | GPIO_CTRL_5_6_EN_MASK);
+
+ si_setcoreidx(sih, origidx);
+}
+void
+si_btc_enable_chipcontrol(si_t *sih)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+
+ /* BT fix */
+ W_REG(sii->osh, &cc->chipcontrol,
+ R_REG(sii->osh, &cc->chipcontrol) | CC_BTCOEX_EN_MASK);
+
+ si_setcoreidx(sih, origidx);
+}
+void
+si_btcombo_43228_war(si_t *sih)
+{
+ si_info_t *sii;
+ chipcregs_t *cc;
+ uint origidx;
+
+ sii = SI_INFO(sih);
+ origidx = si_coreidx(sih);
+
+ cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
+
+ W_REG(sii->osh, &cc->gpioouten, GPIO_CTRL_7_6_EN_MASK);
+ W_REG(sii->osh, &cc->gpioout, GPIO_OUT_7_EN_MASK);
+
+ si_setcoreidx(sih, origidx);
+}
+
+/* check if the device is removed */
+bool
+si_deviceremoved(si_t *sih)
+{
+ uint32 w;
+ si_info_t *sii;
+
+ sii = SI_INFO(sih);
+
+ switch (BUSTYPE(sih->bustype)) {
+ case PCI_BUS:
+ ASSERT(sii->osh != NULL);
+ w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32));
+ if ((w & 0xFFFF) != VENDOR_BROADCOM)
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+bool
+si_is_sprom_available(si_t *sih)
+{
+ if (sih->ccrev >= 31) {
+ si_info_t *sii;
+ uint origidx;
+ chipcregs_t *cc;
+ uint32 sromctrl;
+
+ if ((sih->cccaps & CC_CAP_SROM) == 0)
+ return FALSE;
+
+ sii = SI_INFO(sih);
+ origidx = sii->curidx;
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ sromctrl = R_REG(sii->osh, &cc->sromcontrol);
+ si_setcoreidx(sih, origidx);
+ return (sromctrl & SRC_PRESENT);
+ }
+
+ switch (CHIPID(sih->chip)) {
+ case BCM4312_CHIP_ID:
+ return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL);
+ case BCM4325_CHIP_ID:
+ return (sih->chipst & CST4325_SPROM_SEL) != 0;
+ case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID:
+ case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID:
+ case BCM4342_CHIP_ID: {
+ uint32 spromotp;
+ spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >>
+ CST4322_SPROM_OTP_SEL_SHIFT;
+ return (spromotp & CST4322_SPROM_PRESENT) != 0;
+ }
+ case BCM4329_CHIP_ID:
+ return (sih->chipst & CST4329_SPROM_SEL) != 0;
+ case BCM4315_CHIP_ID:
+ return (sih->chipst & CST4315_SPROM_SEL) != 0;
+ case BCM4319_CHIP_ID:
+ return (sih->chipst & CST4319_SPROM_SEL) != 0;
+ case BCM4336_CHIP_ID:
+ case BCM43362_CHIP_ID:
+ return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
+ case BCM4330_CHIP_ID:
+ return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
+ case BCM4313_CHIP_ID:
+ return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
+ case BCM4331_CHIP_ID:
+ case BCM43431_CHIP_ID:
+ return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
+ case BCM43239_CHIP_ID:
+ return ((sih->chipst & CST43239_SPROM_MASK) &&
+ !(sih->chipst & CST43239_SFLASH_MASK));
+ case BCM4324_CHIP_ID:
+ return ((sih->chipst & CST4324_SPROM_MASK) &&
+ !(sih->chipst & CST4324_SFLASH_MASK));
+ case BCM4335_CHIP_ID:
+ return ((sih->chipst & CST4335_SPROM_MASK) &&
+ !(sih->chipst & CST4335_SFLASH_MASK));
+ case BCM43131_CHIP_ID:
+ case BCM43217_CHIP_ID:
+ case BCM43227_CHIP_ID:
+ case BCM43228_CHIP_ID:
+ case BCM43428_CHIP_ID:
+ return (sih->chipst & CST43228_OTP_PRESENT) != CST43228_OTP_PRESENT;
+ default:
+ return TRUE;
+ }
+}
+
+
+uint32 si_get_sromctl(si_t *sih)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 sromctl;
+ osl_t *osh;
+
+ osh = si_osh(sih);
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT((uintptr)cc);
+
+ sromctl = R_REG(osh, &cc->sromcontrol);
+
+ /* return to the original core */
+ si_setcoreidx(sih, origidx);
+ return sromctl;
+}
+
+int si_set_sromctl(si_t *sih, uint32 value)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ osl_t *osh;
+
+ osh = si_osh(sih);
+ origidx = si_coreidx(sih);
+ cc = si_setcoreidx(sih, SI_CC_IDX);
+ ASSERT((uintptr)cc);
+
+ /* get chipcommon rev */
+ if (si_corerev(sih) < 32)
+ return BCME_UNSUPPORTED;
+
+ W_REG(osh, &cc->sromcontrol, value);
+
+ /* return to the original core */
+ si_setcoreidx(sih, origidx);
+ return BCME_OK;
+
+}
diff --git a/drivers/net/wireless/ap6210/siutils_priv.h b/drivers/net/wireless/ap6210/siutils_priv.h
new file mode 100644
index 0000000..34fc3fa
--- /dev/null
+++ b/drivers/net/wireless/ap6210/siutils_priv.h
@@ -0,0 +1,236 @@
+/*
+ * Include file private to the SOC Interconnect support files.
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: siutils_priv.h 309193 2012-01-19 00:03:57Z $
+ */
+
+#ifndef _siutils_priv_h_
+#define _siutils_priv_h_
+
+#define IS_SIM(chippkg) ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
+
+typedef uint32 (*si_intrsoff_t)(void *intr_arg);
+typedef void (*si_intrsrestore_t)(void *intr_arg, uint32 arg);
+typedef bool (*si_intrsenabled_t)(void *intr_arg);
+
+typedef struct gpioh_item {
+ void *arg;
+ bool level;
+ gpio_handler_t handler;
+ uint32 event;
+ struct gpioh_item *next;
+} gpioh_item_t;
+
+/* misc si info needed by some of the routines */
+typedef struct si_info {
+ struct si_pub pub; /* back plane public state (must be first field) */
+
+ void *osh; /* osl os handle */
+ void *sdh; /* bcmsdh handle */
+
+ uint dev_coreid; /* the core provides driver functions */
+ void *intr_arg; /* interrupt callback function arg */
+ si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */
+ si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
+ si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
+
+ void *pch; /* PCI/E core handle */
+
+ gpioh_item_t *gpioh_head; /* GPIO event handlers list */
+
+ bool memseg; /* flag to toggle MEM_SEG register */
+
+ char *vars;
+ uint varsz;
+
+ void *curmap; /* current regs va */
+ void *regs[SI_MAXCORES]; /* other regs va */
+
+ uint curidx; /* current core index */
+ uint numcores; /* # discovered cores */
+ uint coreid[SI_MAXCORES]; /* id of each core */
+ uint32 coresba[SI_MAXCORES]; /* backplane address of each core */
+ void *regs2[SI_MAXCORES]; /* va of each core second register set (usbh20) */
+ uint32 coresba2[SI_MAXCORES]; /* address of each core second register set (usbh20) */
+ uint32 coresba_size[SI_MAXCORES]; /* backplane address space size */
+ uint32 coresba2_size[SI_MAXCORES]; /* second address space size */
+
+ void *curwrap; /* current wrapper va */
+ void *wrappers[SI_MAXCORES]; /* other cores wrapper va */
+ uint32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */
+
+ uint32 cia[SI_MAXCORES]; /* erom cia entry for each core */
+ uint32 cib[SI_MAXCORES]; /* erom cia entry for each core */
+ uint32 oob_router; /* oob router registers for axi */
+} si_info_t;
+
+#define SI_INFO(sih) (si_info_t *)(uintptr)sih
+
+#define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
+ ISALIGNED((x), SI_CORE_SIZE))
+#define GOODREGS(regs) ((regs) != NULL && ISALIGNED((uintptr)(regs), SI_CORE_SIZE))
+#define BADCOREADDR 0
+#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES)
+#define NOREV -1 /* Invalid rev */
+
+#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \
+ ((si)->pub.buscoretype == PCI_CORE_ID))
+
+#define PCIE_GEN1(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \
+ ((si)->pub.buscoretype == PCIE_CORE_ID))
+
+#define PCIE_GEN2(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \
+ ((si)->pub.buscoretype == PCIE2_CORE_ID))
+
+#define PCIE(si) (PCIE_GEN1(si) || PCIE_GEN2(si))
+
+#define PCMCIA(si) ((BUSTYPE((si)->pub.bustype) == PCMCIA_BUS) && ((si)->memseg == TRUE))
+
+/* Newer chips can access PCI/PCIE and CC core without requiring to change
+ * PCI BAR0 WIN
+ */
+#define SI_FAST(si) (PCIE(si) || (PCI(si) && ((si)->pub.buscorerev >= 13)))
+
+#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET))
+#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
+
+/*
+ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/
+ * after core switching to avoid invalid register accesss inside ISR.
+ */
+#define INTR_OFF(si, intr_val) \
+ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \
+ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); }
+#define INTR_RESTORE(si, intr_val) \
+ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \
+ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); }
+
+/* dynamic clock control defines */
+#define LPOMINFREQ 25000 /* low power oscillator min */
+#define LPOMAXFREQ 43000 /* low power oscillator max */
+#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
+#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
+#define PCIMINFREQ 25000000 /* 25 MHz */
+#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
+
+#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
+#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
+
+#define PCI_FORCEHT(si) \
+ (((PCIE_GEN1(si)) && (si->pub.chip == BCM4311_CHIP_ID) && ((si->pub.chiprev <= 1))) || \
+ ((PCI(si) || PCIE_GEN1(si)) && (si->pub.chip == BCM4321_CHIP_ID)) || \
+ (PCIE_GEN1(si) && (si->pub.chip == BCM4716_CHIP_ID)) || \
+ (PCIE_GEN1(si) && (si->pub.chip == BCM4748_CHIP_ID)))
+
+/* GPIO Based LED powersave defines */
+#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
+#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
+
+#ifndef DEFAULT_GPIOTIMERVAL
+#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
+#endif
+
+/* Silicon Backplane externs */
+extern void sb_scan(si_t *sih, void *regs, uint devid);
+extern uint sb_coreid(si_t *sih);
+extern uint sb_intflag(si_t *sih);
+extern uint sb_flag(si_t *sih);
+extern void sb_setint(si_t *sih, int siflag);
+extern uint sb_corevendor(si_t *sih);
+extern uint sb_corerev(si_t *sih);
+extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val);
+extern bool sb_iscoreup(si_t *sih);
+extern void *sb_setcoreidx(si_t *sih, uint coreidx);
+extern uint32 sb_core_cflags(si_t *sih, uint32 mask, uint32 val);
+extern void sb_core_cflags_wo(si_t *sih, uint32 mask, uint32 val);
+extern uint32 sb_core_sflags(si_t *sih, uint32 mask, uint32 val);
+extern void sb_commit(si_t *sih);
+extern uint32 sb_base(uint32 admatch);
+extern uint32 sb_size(uint32 admatch);
+extern void sb_core_reset(si_t *sih, uint32 bits, uint32 resetbits);
+extern void sb_core_disable(si_t *sih, uint32 bits);
+extern uint32 sb_addrspace(si_t *sih, uint asidx);
+extern uint32 sb_addrspacesize(si_t *sih, uint asidx);
+extern int sb_numaddrspaces(si_t *sih);
+
+extern uint32 sb_set_initiator_to(si_t *sih, uint32 to, uint idx);
+
+extern bool sb_taclear(si_t *sih, bool details);
+
+
+/* Wake-on-wireless-LAN (WOWL) */
+extern bool sb_pci_pmecap(si_t *sih);
+struct osl_info;
+extern bool sb_pci_fastpmecap(struct osl_info *osh);
+extern bool sb_pci_pmeclr(si_t *sih);
+extern void sb_pci_pmeen(si_t *sih);
+extern uint sb_pcie_readreg(void *sih, uint addrtype, uint offset);
+
+/* AMBA Interconnect exported externs */
+extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype,
+ void *sdh, char **vars, uint *varsz);
+extern si_t *ai_kattach(osl_t *osh);
+extern void ai_scan(si_t *sih, void *regs, uint devid);
+
+extern uint ai_flag(si_t *sih);
+extern void ai_setint(si_t *sih, int siflag);
+extern uint ai_coreidx(si_t *sih);
+extern uint ai_corevendor(si_t *sih);
+extern uint ai_corerev(si_t *sih);
+extern bool ai_iscoreup(si_t *sih);
+extern void *ai_setcoreidx(si_t *sih, uint coreidx);
+extern uint32 ai_core_cflags(si_t *sih, uint32 mask, uint32 val);
+extern void ai_core_cflags_wo(si_t *sih, uint32 mask, uint32 val);
+extern uint32 ai_core_sflags(si_t *sih, uint32 mask, uint32 val);
+extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val);
+extern void ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits);
+extern void ai_core_disable(si_t *sih, uint32 bits);
+extern int ai_numaddrspaces(si_t *sih);
+extern uint32 ai_addrspace(si_t *sih, uint asidx);
+extern uint32 ai_addrspacesize(si_t *sih, uint asidx);
+extern void ai_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size);
+extern uint ai_wrap_reg(si_t *sih, uint32 offset, uint32 mask, uint32 val);
+
+
+
+#define ub_scan(a, b, c) do {} while (0)
+#define ub_flag(a) (0)
+#define ub_setint(a, b) do {} while (0)
+#define ub_coreidx(a) (0)
+#define ub_corevendor(a) (0)
+#define ub_corerev(a) (0)
+#define ub_iscoreup(a) (0)
+#define ub_setcoreidx(a, b) (0)
+#define ub_core_cflags(a, b, c) (0)
+#define ub_core_cflags_wo(a, b, c) do {} while (0)
+#define ub_core_sflags(a, b, c) (0)
+#define ub_corereg(a, b, c, d, e) (0)
+#define ub_core_reset(a, b, c) do {} while (0)
+#define ub_core_disable(a, b) do {} while (0)
+#define ub_numaddrspaces(a) (0)
+#define ub_addrspace(a, b) (0)
+#define ub_addrspacesize(a, b) (0)
+#define ub_view(a, b) do {} while (0)
+#define ub_dumpregs(a, b) do {} while (0)
+
+#endif /* _siutils_priv_h_ */
diff --git a/drivers/net/wireless/ap6210/uamp_api.h b/drivers/net/wireless/ap6210/uamp_api.h
new file mode 100644
index 0000000..673dce0
--- /dev/null
+++ b/drivers/net/wireless/ap6210/uamp_api.h
@@ -0,0 +1,176 @@
+/*
+ * Name: uamp_api.h
+ *
+ * Description: Universal AMP API
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: uamp_api.h 294267 2011-11-04 23:41:52Z $
+ *
+ */
+#ifndef UAMP_API_H
+#define UAMP_API_H
+
+
+#include "typedefs.h"
+
+
+/*****************************************************************************
+** Constant and Type Definitions
+******************************************************************************
+*/
+
+#define BT_API
+
+/* Types. */
+typedef bool BOOLEAN;
+typedef uint8 UINT8;
+typedef uint16 UINT16;
+
+
+/* UAMP identifiers */
+#define UAMP_ID_1 1
+#define UAMP_ID_2 2
+typedef UINT8 tUAMP_ID;
+
+/* UAMP event ids (used by UAMP_CBACK) */
+#define UAMP_EVT_RX_READY 0 /* Data from AMP controller is ready to be read */
+#define UAMP_EVT_CTLR_REMOVED 1 /* Controller removed */
+#define UAMP_EVT_CTLR_READY 2 /* Controller added/ready */
+typedef UINT8 tUAMP_EVT;
+
+
+/* UAMP Channels */
+#define UAMP_CH_HCI_CMD 0 /* HCI Command channel */
+#define UAMP_CH_HCI_EVT 1 /* HCI Event channel */
+#define UAMP_CH_HCI_DATA 2 /* HCI ACL Data channel */
+typedef UINT8 tUAMP_CH;
+
+/* tUAMP_EVT_DATA: union for event-specific data, used by UAMP_CBACK */
+typedef union {
+ tUAMP_CH channel; /* UAMP_EVT_RX_READY: channel for which rx occured */
+} tUAMP_EVT_DATA;
+
+
+/*****************************************************************************
+**
+** Function: UAMP_CBACK
+**
+** Description: Callback for events. Register callback using UAMP_Init.
+**
+** Parameters amp_id: AMP device identifier that generated the event
+** amp_evt: event id
+** p_amp_evt_data: pointer to event-specific data
+**
+******************************************************************************
+*/
+typedef void (*tUAMP_CBACK)(tUAMP_ID amp_id, tUAMP_EVT amp_evt, tUAMP_EVT_DATA *p_amp_evt_data);
+
+/*****************************************************************************
+** external function declarations
+******************************************************************************
+*/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*****************************************************************************
+**
+** Function: UAMP_Init
+**
+** Description: Initialize UAMP driver
+**
+** Parameters p_cback: Callback function for UAMP event notification
+**
+******************************************************************************
+*/
+BT_API BOOLEAN UAMP_Init(tUAMP_CBACK p_cback);
+
+
+/*****************************************************************************
+**
+** Function: UAMP_Open
+**
+** Description: Open connection to local AMP device.
+**
+** Parameters app_id: Application specific AMP identifer. This value
+** will be included in AMP messages sent to the
+** BTU task, to identify source of the message
+**
+******************************************************************************
+*/
+BT_API BOOLEAN UAMP_Open(tUAMP_ID amp_id);
+
+/*****************************************************************************
+**
+** Function: UAMP_Close
+**
+** Description: Close connection to local AMP device.
+**
+** Parameters app_id: Application specific AMP identifer.
+**
+******************************************************************************
+*/
+BT_API void UAMP_Close(tUAMP_ID amp_id);
+
+
+/*****************************************************************************
+**
+** Function: UAMP_Write
+**
+** Description: Send buffer to AMP device. Frees GKI buffer when done.
+**
+**
+** Parameters: app_id: AMP identifer.
+** p_buf: pointer to buffer to write
+** num_bytes: number of bytes to write
+** channel: UAMP_CH_HCI_ACL, or UAMP_CH_HCI_CMD
+**
+** Returns: number of bytes written
+**
+******************************************************************************
+*/
+BT_API UINT16 UAMP_Write(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 num_bytes, tUAMP_CH channel);
+
+/*****************************************************************************
+**
+** Function: UAMP_Read
+**
+** Description: Read incoming data from AMP. Call after receiving a
+** UAMP_EVT_RX_READY callback event.
+**
+** Parameters: app_id: AMP identifer.
+** p_buf: pointer to buffer for holding incoming AMP data
+** buf_size: size of p_buf
+** channel: UAMP_CH_HCI_ACL, or UAMP_CH_HCI_EVT
+**
+** Returns: number of bytes read
+**
+******************************************************************************
+*/
+BT_API UINT16 UAMP_Read(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 buf_size, tUAMP_CH channel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UAMP_API_H */
diff --git a/drivers/net/wireless/ap6210/wl_android.c b/drivers/net/wireless/ap6210/wl_android.c
new file mode 100644
index 0000000..7e8b724
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_android.c
@@ -0,0 +1,1448 @@
+/*
+ * Linux cfg80211 driver - Android related functions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_android.c 372668 2012-12-04 14:07:12Z $
+ */
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+#include <wl_android.h>
+#include <wldev_common.h>
+#include <wlioctl.h>
+#include <bcmutils.h>
+#include <linux_osl.h>
+#include <dhd_dbg.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <bcmsdbus.h>
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#endif
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+#include <linux/platform_device.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
+#include <linux/wlan_plat.h>
+#else
+#include <linux/wifi_tiwlan.h>
+#endif
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
+
+#include <ap6210.h>
+
+#ifndef WL_CFG80211
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+#endif
+
+/*
+ * Android private command strings, PLEASE define new private commands here
+ * so they can be updated easily in the future (if needed)
+ */
+
+#define CMD_START "START"
+#define CMD_STOP "STOP"
+#define CMD_SCAN_ACTIVE "SCAN-ACTIVE"
+#define CMD_SCAN_PASSIVE "SCAN-PASSIVE"
+#define CMD_RSSI "RSSI"
+#define CMD_LINKSPEED "LINKSPEED"
+#define CMD_RXFILTER_START "RXFILTER-START"
+#define CMD_RXFILTER_STOP "RXFILTER-STOP"
+#define CMD_RXFILTER_ADD "RXFILTER-ADD"
+#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE"
+#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START"
+#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP"
+#define CMD_BTCOEXMODE "BTCOEXMODE"
+#define CMD_SETSUSPENDOPT "SETSUSPENDOPT"
+#define CMD_SETSUSPENDMODE "SETSUSPENDMODE"
+#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR"
+#define CMD_SETFWPATH "SETFWPATH"
+#define CMD_SETBAND "SETBAND"
+#define CMD_GETBAND "GETBAND"
+#define CMD_COUNTRY "COUNTRY"
+#define CMD_P2P_SET_NOA "P2P_SET_NOA"
+#if !defined WL_ENABLE_P2P_IF
+#define CMD_P2P_GET_NOA "P2P_GET_NOA"
+#endif
+#define CMD_P2P_SD_OFFLOAD "P2P_SD_"
+#define CMD_P2P_SET_PS "P2P_SET_PS"
+#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE"
+#define CMD_SETROAMMODE "SETROAMMODE"
+
+
+/* CCX Private Commands */
+
+#ifdef PNO_SUPPORT
+#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR"
+#define CMD_PNOSETUP_SET "PNOSETUP "
+#define CMD_PNOENABLE_SET "PNOFORCE"
+#define CMD_PNODEBUG_SET "PNODEBUG"
+
+#define PNO_TLV_PREFIX 'S'
+#define PNO_TLV_VERSION '1'
+#define PNO_TLV_SUBVERSION '2'
+#define PNO_TLV_RESERVED '0'
+#define PNO_TLV_TYPE_SSID_IE 'S'
+#define PNO_TLV_TYPE_TIME 'T'
+#define PNO_TLV_FREQ_REPEAT 'R'
+#define PNO_TLV_FREQ_EXPO_MAX 'M'
+
+typedef struct cmd_tlv {
+ char prefix;
+ char version;
+ char subver;
+ char reserved;
+} cmd_tlv_t;
+#endif /* PNO_SUPPORT */
+
+#define CMD_OKC_SET_PMK "SET_PMK"
+#define CMD_OKC_ENABLE "OKC_ENABLE"
+
+
+typedef struct android_wifi_priv_cmd {
+ char *buf;
+ int used_len;
+ int total_len;
+} android_wifi_priv_cmd;
+
+/**
+ * Extern function declarations (TODO: move them to dhd_linux.h)
+ */
+void dhd_customer_gpio_wlan_ctrl(int onoff);
+int dhd_dev_reset(struct net_device *dev, uint8 flag);
+int dhd_dev_init_ioctl(struct net_device *dev);
+#ifdef WL_CFG80211
+int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr);
+int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command);
+#else
+int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
+{ return 0; }
+int wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len)
+{ return 0; }
+int wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len)
+{ return 0; }
+int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len)
+{ return 0; }
+#endif /* WL_CFG80211 */
+
+extern int dhd_os_check_wakelock(void *dhdp);
+extern int dhd_os_check_if_up(void *dhdp);
+extern void *bcmsdh_get_drvdata(void);
+#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB)
+extern int dhd_wlfc_init(dhd_pub_t *dhd);
+extern void dhd_wlfc_deinit(dhd_pub_t *dhd);
+#endif
+
+extern bool ap_fw_loaded;
+extern char iface_name[IFNAMSIZ];
+
+#define WIFI_TURNOFF_DELAY 0
+/**
+ * Local (static) functions and variables
+ */
+
+/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first
+ * time (only) in dhd_open, subsequential wifi on will be handled by
+ * wl_android_wifi_on
+ */
+static int g_wifi_on = TRUE;
+
+/**
+ * Local (static) function definitions
+ */
+static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len)
+{
+ int link_speed;
+ int bytes_written;
+ int error;
+
+ error = wldev_get_link_speed(net, &link_speed);
+ if (error)
+ return -1;
+
+ /* Convert Kbps to Android Mbps */
+ link_speed = link_speed / 1000;
+ bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed);
+ AP6210_DEBUG("%s: command result is %s\n", __FUNCTION__, command);
+ return bytes_written;
+}
+
+static int wl_android_get_rssi(struct net_device *net, char *command, int total_len)
+{
+ wlc_ssid_t ssid = {0};
+ int rssi;
+ int bytes_written = 0;
+ int error;
+
+ error = wldev_get_rssi(net, &rssi);
+ if (error)
+ return -1;
+#if defined(RSSIOFFSET)
+ rssi = wl_update_rssi_offset(rssi);
+#endif
+
+ error = wldev_get_ssid(net, &ssid);
+ if (error)
+ return -1;
+ if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) {
+ AP6210_ERR("%s: wldev_get_ssid failed\n", __FUNCTION__);
+ } else {
+ memcpy(command, ssid.SSID, ssid.SSID_len);
+ bytes_written = ssid.SSID_len;
+ }
+ bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi);
+ AP6210_DEBUG("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written);
+ return bytes_written;
+}
+
+static int wl_android_set_suspendopt(struct net_device *dev, char *command, int total_len)
+{
+ int suspend_flag;
+ int ret_now;
+ int ret = 0;
+
+ suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0';
+
+ if (suspend_flag != 0)
+ suspend_flag = 1;
+ ret_now = net_os_set_suspend_disable(dev, suspend_flag);
+
+ if (ret_now != suspend_flag) {
+ if (!(ret = net_os_set_suspend(dev, ret_now, 1)))
+ AP6210_DEBUG("%s: Suspend Flag %d -> %d\n",
+ __FUNCTION__, ret_now, suspend_flag);
+ else
+ AP6210_ERR("%s: failed %d\n", __FUNCTION__, ret);
+ }
+ return ret;
+}
+
+static int wl_android_set_suspendmode(struct net_device *dev, char *command, int total_len)
+{
+ int ret = 0;
+
+#if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(DHD_USE_EARLYSUSPEND)
+ int suspend_flag;
+
+ suspend_flag = *(command + strlen(CMD_SETSUSPENDMODE) + 1) - '0';
+
+ if (suspend_flag != 0)
+ suspend_flag = 1;
+
+ if (!(ret = net_os_set_suspend(dev, suspend_flag, 0)))
+ AP6210_DEBUG("%s: Suspend Mode %d\n",__FUNCTION__,suspend_flag);
+ else
+ AP6210_ERR("%s: failed %d\n",__FUNCTION__,ret);
+#endif
+ return ret;
+}
+
+static int wl_android_get_band(struct net_device *dev, char *command, int total_len)
+{
+ uint band;
+ int bytes_written;
+ int error;
+
+ error = wldev_get_band(dev, &band);
+ if (error)
+ return -1;
+ bytes_written = snprintf(command, total_len, "Band %d", band);
+ return bytes_written;
+}
+
+#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN)
+static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len)
+{
+ wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
+ int res = -1;
+ int nssid = 0;
+ cmd_tlv_t *cmd_tlv_temp;
+ char *str_ptr;
+ int tlv_size_left;
+ int pno_time = 0;
+ int pno_repeat = 0;
+ int pno_freq_expo_max = 0;
+
+#ifdef PNO_SET_DEBUG
+ int i;
+ char pno_in_example[] = {
+ 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
+ 'S', '1', '2', '0',
+ 'S',
+ 0x05,
+ 'd', 'l', 'i', 'n', 'k',
+ 'S',
+ 0x04,
+ 'G', 'O', 'O', 'G',
+ 'T',
+ '0', 'B',
+ 'R',
+ '2',
+ 'M',
+ '2',
+ 0x00
+ };
+#endif /* PNO_SET_DEBUG */
+
+ AP6210_DEBUG("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len);
+
+ if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) {
+ AP6210_ERR("%s argument=%d less min size\n", __FUNCTION__, total_len);
+ goto exit_proc;
+ }
+
+
+#ifdef PNO_SET_DEBUG
+ memcpy(command, pno_in_example, sizeof(pno_in_example));
+ for (i = 0; i < sizeof(pno_in_example); i++)
+ AP6210_DUMP("%02X ", command[i]);
+ AP6210_DUMP("\n");
+ total_len = sizeof(pno_in_example);
+#endif
+
+ str_ptr = command + strlen(CMD_PNOSETUP_SET);
+ tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET);
+
+ cmd_tlv_temp = (cmd_tlv_t *)str_ptr;
+ memset(ssids_local, 0, sizeof(ssids_local));
+
+ if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) &&
+ (cmd_tlv_temp->version == PNO_TLV_VERSION) &&
+ (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) {
+
+ str_ptr += sizeof(cmd_tlv_t);
+ tlv_size_left -= sizeof(cmd_tlv_t);
+
+ if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local,
+ MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) {
+ AP6210_ERR("SSID is not presented or corrupted ret=%d\n", nssid);
+ goto exit_proc;
+ } else {
+ if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) {
+ AP6210_ERR("%s scan duration corrupted field size %d\n",
+ __FUNCTION__, tlv_size_left);
+ goto exit_proc;
+ }
+ str_ptr++;
+ pno_time = simple_strtoul(str_ptr, &str_ptr, 16);
+ AP6210_DEBUG("%s: pno_time=%d\n", __FUNCTION__, pno_time);
+
+ if (str_ptr[0] != 0) {
+ if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) {
+ AP6210_ERR("%s pno repeat : corrupted field\n",
+ __FUNCTION__);
+ goto exit_proc;
+ }
+ str_ptr++;
+ pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16);
+ AP6210_DEBUG("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat);
+ if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) {
+ AP6210_ERR("%s FREQ_EXPO_MAX corrupted field size\n",
+ __FUNCTION__);
+ goto exit_proc;
+ }
+ str_ptr++;
+ pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16);
+ AP6210_DEBUG("%s: pno_freq_expo_max=%d\n",
+ __FUNCTION__, pno_freq_expo_max);
+ }
+ }
+ } else {
+ AP6210_ERR("%s get wrong TLV command\n", __FUNCTION__);
+ goto exit_proc;
+ }
+
+ res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max);
+
+exit_proc:
+ return res;
+}
+#endif /* PNO_SUPPORT && !WL_SCHED_SCAN */
+
+static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len)
+{
+ int ret;
+ int bytes_written = 0;
+
+ ret = wl_cfg80211_get_p2p_dev_addr(ndev, (struct ether_addr*)command);
+ if (ret)
+ return 0;
+ bytes_written = sizeof(struct ether_addr);
+ return bytes_written;
+}
+
+/**
+ * Global function definitions (declared in wl_android.h)
+ */
+
+int wl_android_wifi_on(struct net_device *dev)
+{
+ int ret = 0;
+ int retry = POWERUP_MAX_RETRY;
+
+ AP6210_DEBUG("%s in\n", __FUNCTION__);
+ if (!dev) {
+ AP6210_ERR("%s: dev is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ dhd_net_if_lock(dev);
+ if (!g_wifi_on) {
+ do {
+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
+ ret = sdioh_start(NULL, 0);
+ if (ret == 0)
+ break;
+ AP6210_ERR("failed to power up wifi chip, retry again (%d left) **\n\n",
+ retry+1);
+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
+ } while (retry-- >= 0);
+ if (ret != 0) {
+ AP6210_ERR("failed to power up wifi chip, max retry reached **\n\n");
+ goto exit;
+ }
+ ret = dhd_dev_reset(dev, FALSE);
+ if (ret)
+ goto err;
+ sdioh_start(NULL, 1);
+ if (!ret) {
+ if (dhd_dev_init_ioctl(dev) < 0) {
+ ret = -EFAULT;
+ goto err;
+ }
+ }
+#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB)
+ dhd_wlfc_init(bcmsdh_get_drvdata());
+#endif
+ g_wifi_on = TRUE;
+ }
+
+exit:
+ dhd_net_if_unlock(dev);
+ AP6210_DEBUG("%s: Success\n", __FUNCTION__);
+ return ret;
+err:
+ dhd_dev_reset(dev, TRUE);
+ sdioh_stop(NULL);
+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
+ dhd_net_if_unlock(dev);
+ AP6210_DEBUG("%s: Failed\n", __FUNCTION__);
+
+ return ret;
+}
+
+int wl_android_wifi_off(struct net_device *dev)
+{
+ int ret = 0;
+
+ AP6210_DEBUG("%s in\n", __FUNCTION__);
+ if (!dev) {
+ AP6210_DEBUG("%s: dev is null\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ dhd_net_if_lock(dev);
+ if (g_wifi_on) {
+#if defined(PROP_TXSTATUS) && !defined(PROP_TXSTATUS_VSDB)
+ dhd_wlfc_deinit(bcmsdh_get_drvdata());
+#endif
+ ret = dhd_dev_reset(dev, TRUE);
+ sdioh_stop(NULL);
+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
+ g_wifi_on = FALSE;
+ }
+ dhd_net_if_unlock(dev);
+
+ return ret;
+}
+
+static int wl_android_set_fwpath(struct net_device *net, char *command, int total_len)
+{
+ if ((strlen(command) - strlen(CMD_SETFWPATH)) > MOD_PARAM_PATHLEN)
+ return -1;
+ bcm_strncpy_s(fw_path, sizeof(fw_path),
+ command + strlen(CMD_SETFWPATH) + 1, MOD_PARAM_PATHLEN - 1);
+ if (strstr(fw_path, "apsta") != NULL) {
+ AP6210_DEBUG("GOT APSTA FIRMWARE\n");
+ ap_fw_loaded = TRUE;
+ } else {
+ AP6210_DEBUG("GOT STA FIRMWARE\n");
+ ap_fw_loaded = FALSE;
+ }
+ return 0;
+}
+
+static int
+wl_android_set_pmk(struct net_device *dev, char *command, int total_len)
+{
+ uchar pmk[33];
+ int error = 0;
+ char smbuf[WLC_IOCTL_SMLEN];
+#ifdef OKC_DEBUG
+ int i = 0;
+#endif
+
+ bzero(pmk, sizeof(pmk));
+ memcpy((char *)pmk, command + strlen("SET_PMK "), 32);
+ error = wldev_iovar_setbuf(dev, "okc_info_pmk", pmk, 32, smbuf, sizeof(smbuf), NULL);
+ if (error) {
+ AP6210_ERR("Failed to set PMK for OKC, error = %d\n", error);
+ }
+#ifdef OKC_DEBUG
+ AP6210_ERR("PMK is ");
+ for (i = 0; i < 32; i++)
+ AP6210_ERR("%02X ", pmk[i]);
+
+ AP6210_ERR("\n");
+#endif
+ return error;
+}
+
+static int
+wl_android_okc_enable(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ char okc_enable = 0;
+
+ okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0';
+ error = wldev_iovar_setint(dev, "okc_enable", okc_enable);
+ if (error) {
+ AP6210_ERR("Failed to %s OKC, error = %d\n",
+ okc_enable ? "enable" : "disable", error);
+ }
+
+ return error;
+}
+
+int wl_android_set_roam_mode(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ int mode = 0;
+
+ if (sscanf(command, "%*s %d", &mode) != 1) {
+ AP6210_ERR("%s: Failed to get Parameter\n", __FUNCTION__);
+ return -1;
+ }
+
+ error = wldev_iovar_setint(dev, "roam_off", mode);
+ if (error) {
+ AP6210_ERR("%s: Failed to set roaming Mode %d, error = %d\n",
+ __FUNCTION__, mode, error);
+ return -1;
+ }
+ else
+ AP6210_ERR("%s: succeeded to set roaming Mode %d, error = %d\n",
+ __FUNCTION__, mode, error);
+ return 0;
+}
+
+int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
+{
+#define PRIVATE_COMMAND_MAX_LEN 8192
+ int ret = 0;
+ char *command = NULL;
+ int bytes_written = 0;
+ android_wifi_priv_cmd priv_cmd;
+
+ net_os_wake_lock(net);
+
+ if (!ifr->ifr_data) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) {
+ ret = -EFAULT;
+ goto exit;
+ }
+ if (priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN)
+ {
+ AP6210_ERR("%s: too long priavte command\n", __FUNCTION__);
+ ret = -EINVAL;
+ }
+ command = kmalloc(priv_cmd.total_len, GFP_KERNEL);
+ if (!command)
+ {
+ AP6210_ERR("%s: failed to allocate memory\n", __FUNCTION__);
+ ret = -ENOMEM;
+ goto exit;
+ }
+ if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) {
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ AP6210_DEBUG("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name);
+
+ if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) {
+ AP6210_DEBUG("%s, Received regular START command\n", __FUNCTION__);
+ bytes_written = wl_android_wifi_on(net);
+ }
+ else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) {
+ bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len);
+ }
+
+ if (!g_wifi_on) {
+ AP6210_ERR("%s: Ignore private cmd \"%s\" - iface %s is down\n",
+ __FUNCTION__, command, ifr->ifr_name);
+ ret = 0;
+ goto exit;
+ }
+
+ if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) {
+ bytes_written = wl_android_wifi_off(net);
+ }
+ else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) {
+ /* TBD: SCAN-ACTIVE */
+ }
+ else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) {
+ /* TBD: SCAN-PASSIVE */
+ }
+ else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
+ bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) {
+ bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len);
+ }
+#ifdef PKT_FILTER_SUPPORT
+ else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) {
+ bytes_written = net_os_enable_packet_filter(net, 1);
+ }
+ else if (strnicmp(command, CMD_RXFILTER_STOP, strlen(CMD_RXFILTER_STOP)) == 0) {
+ bytes_written = net_os_enable_packet_filter(net, 0);
+ }
+ else if (strnicmp(command, CMD_RXFILTER_ADD, strlen(CMD_RXFILTER_ADD)) == 0) {
+ int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0';
+ bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num);
+ }
+ else if (strnicmp(command, CMD_RXFILTER_REMOVE, strlen(CMD_RXFILTER_REMOVE)) == 0) {
+ int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0';
+ bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num);
+ }
+#endif /* PKT_FILTER_SUPPORT */
+ else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) {
+ /* TBD: BTCOEXSCAN-START */
+ }
+ else if (strnicmp(command, CMD_BTCOEXSCAN_STOP, strlen(CMD_BTCOEXSCAN_STOP)) == 0) {
+ /* TBD: BTCOEXSCAN-STOP */
+ }
+ else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) {
+#ifdef WL_CFG80211
+ bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command);
+#else
+#ifdef PKT_FILTER_SUPPORT
+ uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0';
+
+ if (mode == 1)
+ net_os_enable_packet_filter(net, 0); /* DHCP starts */
+ else
+ net_os_enable_packet_filter(net, 1); /* DHCP ends */
+#endif /* PKT_FILTER_SUPPORT */
+#endif /* WL_CFG80211 */
+ }
+ else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) {
+ bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) {
+ bytes_written = wl_android_set_suspendmode(net, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) {
+ uint band = *(command + strlen(CMD_SETBAND) + 1) - '0';
+#ifdef WL_HOST_BAND_MGMT
+ if (wl_cfg80211_set_band(net, band) < 0) {
+ bytes_written = -1;
+ goto exit;
+ }
+ if (band == WLC_BAND_AUTO)
+ bytes_written = wldev_set_band(net, band);
+#else
+ bytes_written = wldev_set_band(net, band);
+#endif /* WL_HOST_BAND_MGMT */
+ }
+ else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) {
+ bytes_written = wl_android_get_band(net, command, priv_cmd.total_len);
+ }
+#ifdef WL_CFG80211
+ /* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */
+ else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
+ char *country_code = command + strlen(CMD_COUNTRY) + 1;
+ bytes_written = wldev_set_country(net, country_code);
+ }
+#endif /* WL_CFG80211 */
+#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN)
+ else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) {
+ bytes_written = dhd_dev_pno_reset(net);
+ }
+ else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) {
+ bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) {
+ uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0';
+ bytes_written = dhd_dev_pno_enable(net, pfn_enabled);
+ }
+#endif /* PNO_SUPPORT && !WL_SCHED_SCAN */
+ else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) {
+ bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_P2P_SET_NOA, strlen(CMD_P2P_SET_NOA)) == 0) {
+ int skip = strlen(CMD_P2P_SET_NOA) + 1;
+ bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip,
+ priv_cmd.total_len - skip);
+ }
+#if !defined WL_ENABLE_P2P_IF
+ else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) {
+ bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len);
+ }
+#endif /* WL_ENABLE_P2P_IF */
+ else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) {
+ int skip = strlen(CMD_P2P_SET_PS) + 1;
+ bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip,
+ priv_cmd.total_len - skip);
+ }
+#ifdef WL_CFG80211
+ else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE,
+ strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) {
+ int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3;
+ bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip,
+ priv_cmd.total_len - skip, *(command + skip - 2) - '0');
+ }
+#endif /* WL_CFG80211 */
+ else if (strnicmp(command, CMD_OKC_SET_PMK, strlen(CMD_OKC_SET_PMK)) == 0)
+ bytes_written = wl_android_set_pmk(net, command, priv_cmd.total_len);
+ else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0)
+ bytes_written = wl_android_okc_enable(net, command, priv_cmd.total_len);
+ else if (strnicmp(command, CMD_SETROAMMODE, strlen(CMD_SETROAMMODE)) == 0)
+ bytes_written = wl_android_set_roam_mode(net, command, priv_cmd.total_len);
+ else {
+ AP6210_ERR("Unknown PRIVATE command %s - ignored\n", command);
+ snprintf(command, 3, "OK");
+ bytes_written = strlen("OK");
+ }
+
+ if (bytes_written >= 0) {
+ if ((bytes_written == 0) && (priv_cmd.total_len > 0))
+ command[0] = '\0';
+ if (bytes_written >= priv_cmd.total_len) {
+ AP6210_ERR("%s: bytes_written = %d\n", __FUNCTION__, bytes_written);
+ bytes_written = priv_cmd.total_len;
+ } else {
+ bytes_written++;
+ }
+ priv_cmd.used_len = bytes_written;
+ if (copy_to_user(priv_cmd.buf, command, bytes_written)) {
+ AP6210_ERR("%s: failed to copy data to user buffer\n", __FUNCTION__);
+ ret = -EFAULT;
+ }
+ }
+ else {
+ ret = bytes_written;
+ }
+
+exit:
+ net_os_wake_unlock(net);
+ if (command) {
+ kfree(command);
+ }
+
+ return ret;
+}
+
+int wl_android_init(void)
+{
+ int ret = 0;
+
+ dhd_msg_level |= DHD_ERROR_VAL;
+#ifdef ENABLE_INSMOD_NO_FW_LOAD
+ dhd_download_fw_on_driverload = FALSE;
+#endif /* ENABLE_INSMOD_NO_FW_LOAD */
+ if (!iface_name[0]) {
+ memset(iface_name, 0, IFNAMSIZ);
+ bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ);
+ }
+ return ret;
+}
+
+int wl_android_exit(void)
+{
+ int ret = 0;
+
+ return ret;
+}
+
+void wl_android_post_init(void)
+{
+ if (!dhd_download_fw_on_driverload) {
+ /* Call customer gpio to turn off power with WL_REG_ON signal */
+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
+ g_wifi_on = 0;
+ }
+}
+
+#if defined(RSSIAVG)
+void
+wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, *cur, **rssi_head;
+ int i=0;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+
+ for (;node;) {
+ AP6210_DEBUG("%s: Free %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->BSSID);
+ cur = node;
+ node = cur->next;
+ kfree(cur);
+ i++;
+ }
+ *rssi_head = NULL;
+}
+
+void
+wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, *prev, **rssi_head;
+ int i = -1, tmp = 0;
+#if defined(BSSCACHE)
+ int max = BSSCACHE_LEN;
+#else
+ int max = RSSICACHE_LEN;
+#endif
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (node->dirty >= max || node->dirty >= RSSICACHE_LEN) {
+ if (node == *rssi_head) {
+ tmp = 1;
+ *rssi_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ AP6210_DEBUG("%s: Del %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->BSSID);
+ kfree(node);
+ if (tmp == 1) {
+ node = *rssi_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, **rssi_head;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ /* reset dirty */
+ node = *rssi_head;
+ for (;node;) {
+ node->dirty += 1;
+ node = node->next;
+ }
+}
+
+void
+wl_update_connected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, struct net_device *net)
+{
+ wl_rssi_cache_t *node, *prev, **rssi_head;
+ int j, k=0;
+ int rssi, error;
+ struct ether_addr bssid;
+
+ error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false);
+ if (error)
+ return;
+ error = wldev_get_rssi(net, &rssi);
+ if (error)
+ return;
+
+ /* update RSSI */
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+ for (;node;) {
+ if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) {
+ AP6210_DEBUG("%s: Update %d with BSSID %pM, RSSI=%d\n",
+ __FUNCTION__, k, &bssid, rssi);
+ for(j=0; j<RSSIAVG_LEN-1; j++)
+ node->RSSI[j] = node->RSSI[j+1];
+ node->RSSI[j] = rssi;
+ node->dirty = 0;
+ break;
+ }
+ prev = node;
+ node = node->next;
+ k++;
+ }
+}
+
+void
+wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list)
+{
+ wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;
+ wl_bss_info_t *bi = NULL;
+ int i, j, k;
+
+ if (!ss_list->count)
+ return;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ /* update RSSI */
+ for (i = 0; i < ss_list->count; i++) {
+ node = *rssi_head;
+ prev = NULL;
+ k = 0;
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;
+ for (;node;) {
+ if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {
+ AP6210_DEBUG("%s: Update %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID);
+ for(j=0; j<RSSIAVG_LEN-1; j++)
+ node->RSSI[j] = node->RSSI[j+1];
+ node->RSSI[j] = dtoh16(bi->RSSI);
+ node->dirty = 0;
+ break;
+ }
+ prev = node;
+ node = node->next;
+ k++;
+ }
+
+ if (node)
+ continue;
+
+ leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
+ if (!leaf) {
+ AP6210_ERR("%s: Memory alloc failure %d\n",
+ __FUNCTION__, sizeof(wl_rssi_cache_t));
+ return;
+ }
+ AP6210_DEBUG("%s: Add %d with cached BSSID %pM, RSSI=%d, SSID \"%s\" in the leaf\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID);
+
+ leaf->next = NULL;
+ leaf->dirty = 0;
+ memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN);
+ for (j=0; j<RSSIAVG_LEN; j++)
+ leaf->RSSI[j] = dtoh16(bi->RSSI);
+
+ if (!prev)
+ *rssi_head = leaf;
+ else
+ prev->next = leaf;
+ }
+}
+
+int16
+wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr)
+{
+ wl_rssi_cache_t *node, **rssi_head;
+ int j, rssi_sum, rssi=-200;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ /* reset dirty */
+ node = *rssi_head;
+ for (;node;) {
+ if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) {
+ rssi_sum = 0;
+ rssi = 0;
+ for (j=0; j<RSSIAVG_LEN; j++)
+ rssi_sum += node->RSSI[RSSIAVG_LEN-j-1];
+ rssi = rssi_sum / j;
+ break;
+ }
+ node = node->next;
+ }
+ if (rssi >= -2)
+ rssi = -2;
+ if (rssi == -200) {
+ AP6210_ERR("%s: BSSID %pM does not in RSSI cache\n",
+ __FUNCTION__, addr);
+ }
+ return (int16)rssi;
+}
+#endif
+
+#if defined(RSSIOFFSET)
+int
+wl_update_rssi_offset(int rssi)
+{
+ uint chip, chiprev;
+
+ chip = dhd_bus_chip_id(bcmsdh_get_drvdata());
+ chiprev = dhd_bus_chiprev_id(bcmsdh_get_drvdata());
+ if (chip == BCM4330_CHIP_ID && chiprev == BCM4330B2_CHIP_REV) {
+#if defined(RSSIOFFSET_NEW)
+ int j;
+ for (j=0; j<RSSI_OFFSET; j++) {
+ if (rssi - (RSSI_MIN+RSSI_INT*(j+1)) < 0)
+ break;
+ }
+ rssi += j;
+#else
+ rssi += RSSI_OFFSET;
+#endif
+ }
+ if (rssi >= -2)
+ rssi = -2;
+ return rssi;
+}
+#endif
+
+#if defined(BSSCACHE)
+#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32
+
+void
+wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, *cur, **bss_head;
+ int i=0;
+
+ AP6210_DEBUG("%s called\n", __FUNCTION__);
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+ node = *bss_head;
+
+ for (;node;) {
+ AP6210_DEBUG("%s: Free %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->results.bss_info->BSSID);
+ cur = node;
+ node = cur->next;
+ kfree(cur);
+ i++;
+ }
+ *bss_head = NULL;
+}
+
+void
+wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, *prev, **bss_head;
+ int i = -1, tmp = 0;
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+ node = *bss_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (node->dirty >= BSSCACHE_LEN) {
+ if (node == *bss_head) {
+ tmp = 1;
+ *bss_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ AP6210_DEBUG("%s: Del %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n",
+ __FUNCTION__, i, &node->results.bss_info->BSSID,
+ dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID);
+ kfree(node);
+ if (tmp == 1) {
+ node = *bss_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, **bss_head;
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+
+ /* reset dirty */
+ node = *bss_head;
+ for (;node;) {
+ node->dirty += 1;
+ node = node->next;
+ }
+}
+
+void
+wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, wl_scan_results_t *ss_list)
+{
+ wl_bss_cache_t *node, *prev, *leaf, *tmp, **bss_head;
+ wl_bss_info_t *bi = NULL;
+ int i, k=0;
+
+ if (!ss_list->count)
+ return;
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+
+ for (i=0; i < ss_list->count; i++) {
+ node = *bss_head;
+ prev = NULL;
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;
+
+ for (;node;) {
+ if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {
+ tmp = node;
+ leaf = kmalloc(dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL);
+ if (!leaf) {
+ AP6210_ERR("%s: Memory alloc failure %d and keep old BSS info\n",
+ __FUNCTION__, dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN);
+ break;
+ }
+
+ memcpy(leaf->results.bss_info, bi, dtoh32(bi->length));
+ leaf->next = node->next;
+ leaf->dirty = 0;
+ leaf->results.count = 1;
+ leaf->results.version = ss_list->version;
+ AP6210_DEBUG("%s: Update %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID);
+ if (!prev)
+ *bss_head = leaf;
+ else
+ prev->next = leaf;
+ node = leaf;
+ prev = node;
+
+ kfree(tmp);
+ k++;
+ break;
+ }
+ prev = node;
+ node = node->next;
+ }
+
+ if (node)
+ continue;
+
+ leaf = kmalloc(dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL);
+ if (!leaf) {
+ AP6210_ERR("%s: Memory alloc failure %d\n", __FUNCTION__,
+ dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN);
+ return;
+ }
+ AP6210_DEBUG("%s: Add %d with cached BSSID %pM, RSSI=%d, SSID \"%s\" in the leaf\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID);
+
+ memcpy(leaf->results.bss_info, bi, dtoh32(bi->length));
+ leaf->next = NULL;
+ leaf->dirty = 0;
+ leaf->results.count = 1;
+ leaf->results.version = ss_list->version;
+ k++;
+
+ if (!prev)
+ *bss_head = leaf;
+ else
+ prev->next = leaf;
+ }
+}
+
+void
+wl_run_bss_cache_timer(wl_bss_cache_ctrl_t *bss_cache_ctrl, int kick_off)
+{
+ struct timer_list **timer;
+
+ timer = &bss_cache_ctrl->m_timer;
+
+ if (*timer) {
+ if (kick_off) {
+ (*timer)->expires = jiffies + BSSCACHE_TIME * HZ / 1000;
+ add_timer(*timer);
+ AP6210_DEBUG("%s: timer starts\n", __FUNCTION__);
+ } else {
+ del_timer_sync(*timer);
+ AP6210_DEBUG("%s: timer stops\n", __FUNCTION__);
+ }
+ }
+}
+
+void
+wl_set_bss_cache_timer_flag(ulong data)
+{
+ wl_bss_cache_ctrl_t *bss_cache_ctrl = (wl_bss_cache_ctrl_t *)data;
+
+ bss_cache_ctrl->m_timer_expired = 1;
+ AP6210_DEBUG("%s called\n", __FUNCTION__);
+}
+
+void
+wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ AP6210_DEBUG("%s:\n", __FUNCTION__);
+ wl_free_bss_cache(bss_cache_ctrl);
+ wl_run_bss_cache_timer(bss_cache_ctrl, 0);
+ if (bss_cache_ctrl->m_timer) {
+ kfree(bss_cache_ctrl->m_timer);
+ }
+}
+
+void
+wl_init_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ AP6210_DEBUG("%s:\n", __FUNCTION__);
+ bss_cache_ctrl->m_timer_expired = 0;
+
+ bss_cache_ctrl->m_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
+ if (!bss_cache_ctrl->m_timer) {
+ AP6210_ERR("%s: Memory alloc failure\n", __FUNCTION__ );
+ return;
+ }
+ init_timer(bss_cache_ctrl->m_timer);
+ bss_cache_ctrl->m_timer->function = (void *)wl_set_bss_cache_timer_flag;
+ bss_cache_ctrl->m_timer->data = (ulong)bss_cache_ctrl;
+}
+#endif
+
+/**
+ * Functions for Android WiFi card detection
+ */
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+
+static int g_wifidev_registered = 0;
+static struct semaphore wifi_control_sem;
+static struct wifi_platform_data *wifi_control_data = NULL;
+static struct resource *wifi_irqres = NULL;
+
+static int wifi_add_dev(void);
+static void wifi_del_dev(void);
+
+int wl_android_wifictrl_func_add(void)
+{
+ int ret = 0;
+ sema_init(&wifi_control_sem, 0);
+
+ ret = wifi_add_dev();
+ if (ret) {
+ AP6210_ERR("%s: platform_driver_register failed\n", __FUNCTION__);
+ return ret;
+ }
+ g_wifidev_registered = 1;
+
+ /* Waiting callback after platform_driver_register is done or exit with error */
+ if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {
+ ret = -EINVAL;
+ AP6210_ERR("%s: platform_driver_register timeout\n", __FUNCTION__);
+ }
+
+ return ret;
+}
+
+void wl_android_wifictrl_func_del(void)
+{
+ if (g_wifidev_registered)
+ {
+ wifi_del_dev();
+ g_wifidev_registered = 0;
+ }
+}
+
+void* wl_android_prealloc(int section, unsigned long size)
+{
+ void *alloc_ptr = NULL;
+ if (wifi_control_data && wifi_control_data->mem_prealloc) {
+ alloc_ptr = wifi_control_data->mem_prealloc(section, size);
+ if (alloc_ptr) {
+ AP6210_DEBUG("success alloc section %d\n", section);
+ if (size != 0L)
+ bzero(alloc_ptr, size);
+ return alloc_ptr;
+ }
+ }
+
+ AP6210_ERR("can't alloc section %d\n", section);
+ return NULL;
+}
+
+int wifi_get_irq_number(unsigned long *irq_flags_ptr)
+{
+ if (wifi_irqres) {
+ *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK;
+ return (int)wifi_irqres->start;
+ }
+#ifdef CUSTOM_OOB_GPIO_NUM
+ return CUSTOM_OOB_GPIO_NUM;
+#else
+ return -1;
+#endif
+}
+
+int wifi_set_power(int on, unsigned long msec)
+{
+ AP6210_ERR("%s = %d\n", __FUNCTION__, on);
+ if (wifi_control_data && wifi_control_data->set_power) {
+ wifi_control_data->set_power(on);
+ }
+ if (msec)
+ msleep(msec);
+ return 0;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
+int wifi_get_mac_addr(unsigned char *buf)
+{
+ AP6210_ERR("%s\n", __FUNCTION__);
+ if (!buf)
+ return -EINVAL;
+ if (wifi_control_data && wifi_control_data->get_mac_addr) {
+ return wifi_control_data->get_mac_addr(buf);
+ }
+ return -EOPNOTSUPP;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
+void *wifi_get_country_code(char *ccode)
+{
+ AP6210_DEBUG("%s\n", __FUNCTION__);
+ if (!ccode)
+ return NULL;
+ if (wifi_control_data && wifi_control_data->get_country_code) {
+ return wifi_control_data->get_country_code(ccode);
+ }
+ return NULL;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */
+
+static int wifi_set_carddetect(int on)
+{
+ AP6210_ERR("%s = %d\n", __FUNCTION__, on);
+ if (wifi_control_data && wifi_control_data->set_carddetect) {
+ wifi_control_data->set_carddetect(on);
+ }
+ return 0;
+}
+
+static int wifi_probe(struct platform_device *pdev)
+{
+ struct wifi_platform_data *wifi_ctrl =
+ (struct wifi_platform_data *)(pdev->dev.platform_data);
+
+ wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
+ if (wifi_irqres == NULL)
+ wifi_irqres = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ, "bcm4329_wlan_irq");
+ wifi_control_data = wifi_ctrl;
+ wifi_set_power(1, 0); /* Power On */
+ wifi_set_carddetect(1); /* CardDetect (0->1) */
+
+ up(&wifi_control_sem);
+ return 0;
+}
+
+static int wifi_remove(struct platform_device *pdev)
+{
+ struct wifi_platform_data *wifi_ctrl =
+ (struct wifi_platform_data *)(pdev->dev.platform_data);
+
+ AP6210_ERR("## %s\n", __FUNCTION__);
+ wifi_control_data = wifi_ctrl;
+
+ wifi_set_power(0, WIFI_TURNOFF_DELAY); /* Power Off */
+ wifi_set_carddetect(0); /* CardDetect (1->0) */
+
+ up(&wifi_control_sem);
+ return 0;
+}
+
+static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ AP6210_DEBUG("##> %s\n", __FUNCTION__);
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
+ if (dhd_os_check_wakelock(bcmsdh_get_drvdata()))
+ return -EBUSY;
+#endif /* defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI) */
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1
+ bcmsdh_oob_intr_set(0);
+#endif /* (OOB_INTR_ONLY) */
+ return 0;
+}
+
+static int wifi_resume(struct platform_device *pdev)
+{
+ AP6210_DEBUG("##> %s\n", __FUNCTION__);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1
+ if (dhd_os_check_if_up(bcmsdh_get_drvdata()))
+ bcmsdh_oob_intr_set(1);
+#endif /* (OOB_INTR_ONLY) */
+ return 0;
+}
+
+static struct platform_driver wifi_device = {
+ .probe = wifi_probe,
+ .remove = wifi_remove,
+ .suspend = wifi_suspend,
+ .resume = wifi_resume,
+ .driver = {
+ .name = "bcmdhd_wlan",
+ }
+};
+
+static struct platform_driver wifi_device_legacy = {
+ .probe = wifi_probe,
+ .remove = wifi_remove,
+ .suspend = wifi_suspend,
+ .resume = wifi_resume,
+ .driver = {
+ .name = "bcm4329_wlan",
+ }
+};
+
+static int wifi_add_dev(void)
+{
+ int ret = 0;
+ AP6210_DEBUG("## Calling platform_driver_register\n");
+ ret = platform_driver_register(&wifi_device);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&wifi_device_legacy);
+ return ret;
+}
+
+static void wifi_del_dev(void)
+{
+ AP6210_DEBUG("## Unregister platform_driver_register\n");
+ platform_driver_unregister(&wifi_device);
+ platform_driver_unregister(&wifi_device_legacy);
+}
+#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
diff --git a/drivers/net/wireless/ap6210/wl_android.h b/drivers/net/wireless/ap6210/wl_android.h
new file mode 100644
index 0000000..d933e06
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_android.h
@@ -0,0 +1,124 @@
+/*
+ * Linux cfg80211 driver - Android related functions
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_android.h 367273 2012-11-07 09:58:55Z $
+ */
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <wldev_common.h>
+
+/* If any feature uses the Generic Netlink Interface, put it here to enable WL_GENL
+ * automatically
+ */
+
+/**
+ * Android platform dependent functions, feel free to add Android specific functions here
+ * (save the macros in dhd). Please do NOT declare functions that are NOT exposed to dhd
+ * or cfg, define them as static in wl_android.c
+ */
+
+/**
+ * wl_android_init will be called from module init function (dhd_module_init now), similarly
+ * wl_android_exit will be called from module exit function (dhd_module_cleanup now)
+ */
+int wl_android_init(void);
+int wl_android_exit(void);
+void wl_android_post_init(void);
+int wl_android_wifi_on(struct net_device *dev);
+int wl_android_wifi_off(struct net_device *dev);
+int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
+
+#define BSSCACHE
+#define RSSIAVG
+#define RSSIOFFSET
+//#define RSSIOFFSET_NEW
+
+#if defined(RSSIAVG)
+#define RSSIAVG_LEN 8
+#define RSSICACHE_LEN 8
+
+typedef struct wl_rssi_cache {
+ struct wl_rssi_cache *next;
+ int dirty;
+ struct ether_addr BSSID;
+ int16 RSSI[RSSIAVG_LEN];
+} wl_rssi_cache_t;
+
+typedef struct wl_rssi_cache_ctrl {
+ wl_rssi_cache_t *m_cache_head;
+} wl_rssi_cache_ctrl_t;
+
+void wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl);
+void wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl);
+void wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl);
+void wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list);
+void wl_update_connected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, struct net_device *net);
+int16 wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr);
+#endif
+
+#if defined(RSSIOFFSET)
+#define RSSI_OFFSET 5
+#define RSSI_MAX -80
+#define RSSI_MIN -94
+#define RSSI_INT ((RSSI_MAX-RSSI_MIN)/RSSI_OFFSET)
+#define BCM4330_CHIP_ID 0x4330
+#define BCM4330B2_CHIP_REV 4
+int wl_update_rssi_offset(int rssi);
+#endif
+
+#if defined(BSSCACHE)
+#define BSSCACHE_LEN 8
+#define BSSCACHE_TIME 15000
+
+typedef struct wl_bss_cache {
+ struct wl_bss_cache *next;
+ int dirty;
+ wl_scan_results_t results;
+} wl_bss_cache_t;
+
+typedef struct wl_bss_cache_ctrl {
+ wl_bss_cache_t *m_cache_head;
+ struct timer_list *m_timer;
+ int m_timer_expired;
+} wl_bss_cache_ctrl_t;
+
+void wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl);
+void wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl);
+void wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl);
+void wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, wl_scan_results_t *ss_list);
+void wl_run_bss_cache_timer(wl_bss_cache_ctrl_t *bss_cache_ctrl, int kick_off);
+void wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl);
+void wl_init_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl);
+#endif
+
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+int wl_android_wifictrl_func_add(void);
+void wl_android_wifictrl_func_del(void);
+void* wl_android_prealloc(int section, unsigned long size);
+
+int wifi_get_irq_number(unsigned long *irq_flags_ptr);
+int wifi_set_power(int on, unsigned long msec);
+int wifi_get_mac_addr(unsigned char *buf);
+void *wifi_get_country_code(char *ccode);
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
diff --git a/drivers/net/wireless/ap6210/wl_cfg80211.c b/drivers/net/wireless/ap6210/wl_cfg80211.c
new file mode 100644
index 0000000..1ebce14
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_cfg80211.c
@@ -0,0 +1,10129 @@
+/*
+ * Linux cfg80211 driver
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_cfg80211.c 374275 2012-12-12 11:44:18Z $
+ */
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#include <linux/kernel.h>
+
+#include <bcmutils.h>
+#include <bcmwifi_channels.h>
+#include <bcmendian.h>
+#include <proto/ethernet.h>
+#include <proto/802.11.h>
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhdioctl.h>
+#include <wlioctl.h>
+#include <dhd_cfg80211.h>
+
+#include <proto/ethernet.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/netdevice.h>
+#include <linux/sched.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <linux/wait.h>
+#include <net/cfg80211.h>
+#include <net/rtnetlink.h>
+#include <wlioctl.h>
+#include <wldev_common.h>
+#include <wl_cfg80211.h>
+#include <wl_cfgp2p.h>
+#include <wl_android.h>
+
+#include <ap6210.h>
+
+#ifdef PROP_TXSTATUS
+#include <dhd_wlfc.h>
+#endif
+#ifdef BCMWAPI_WPI
+/* these items should evetually go into wireless.h of the linux system headfile dir */
+#ifndef IW_ENCODE_ALG_SM4
+#define IW_ENCODE_ALG_SM4 0x20
+#endif
+
+#ifndef IW_AUTH_WAPI_ENABLED
+#define IW_AUTH_WAPI_ENABLED 0x20
+#endif
+
+#ifndef IW_AUTH_WAPI_VERSION_1
+#define IW_AUTH_WAPI_VERSION_1 0x00000008
+#endif
+
+#ifndef IW_AUTH_CIPHER_SMS4
+#define IW_AUTH_CIPHER_SMS4 0x00000020
+#endif
+
+#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK
+#define IW_AUTH_KEY_MGMT_WAPI_PSK 4
+#endif
+
+#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT
+#define IW_AUTH_KEY_MGMT_WAPI_CERT 8
+#endif
+#endif /* BCMWAPI_WPI */
+
+#ifdef BCMWAPI_WPI
+#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED))
+#else /* BCMWAPI_WPI */
+#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
+#endif /* BCMWAPI_WPI */
+#ifdef WL11U
+#ifndef WL_ENABLE_P2P_IF
+#error "You should enable WL_ENABLE_P2P_IF and Only supported in JB"
+#endif
+#endif /* WL11U */
+
+#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
+
+static struct device *cfg80211_parent_dev = NULL;
+struct wl_priv *wlcfg_drv_priv = NULL;
+u32 wl_dbg_level = WL_DBG_ERR;
+
+#define MAX_WAIT_TIME 1500
+
+#ifdef VSDB
+/* sleep time to keep STA's connecting or connection for continuous af tx or finding a peer */
+#define DEFAULT_SLEEP_TIME_VSDB 200
+#define OFF_CHAN_TIME_THRESHOLD_MS 200
+
+/* if sta is connected or connecting, sleep for a while before retry af tx or finding a peer */
+#define WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl) \
+ do { \
+ if (wl_get_drv_status(wl, CONNECTED, wl_to_prmry_ndev(wl)) || \
+ wl_get_drv_status(wl, CONNECTING, wl_to_prmry_ndev(wl))) { \
+ msleep(DEFAULT_SLEEP_TIME_VSDB); \
+ } \
+ } while (0)
+#else /* VSDB */
+/* if not VSDB, do nothing */
+#define WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl)
+#endif /* VSDB */
+
+#ifdef WL_CFG80211_SYNC_GON
+#define WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl) \
+ (wl_get_drv_status_all(wl, SENDING_ACT_FRM) || \
+ wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN))
+#else
+#define WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl) wl_get_drv_status_all(wl, SENDING_ACT_FRM)
+#endif /* WL_CFG80211_SYNC_GON */
+
+#define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL
+
+
+#define DNGL_FUNC(func, parameters) func parameters;
+#define COEX_DHCP
+
+#define WLAN_EID_SSID 0
+#define CH_MIN_5G_CHANNEL 34
+#define CH_MIN_2G_CHANNEL 1
+
+/* This is to override regulatory domains defined in cfg80211 module (reg.c)
+ * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
+ * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165).
+ * With respect to these flags, wpa_supplicant doesn't start p2p operations on 5GHz channels.
+ * All the chnages in world regulatory domain are to be done here.
+ */
+static const struct ieee80211_regdomain brcm_regdom = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ /* IEEE 802.11b/g, channels 1..11 */
+ REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
+ /* If any */
+ /* IEEE 802.11 channel 14 - Only JP enables
+ * this and for 802.11b only
+ */
+ REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
+ /* IEEE 802.11a, channel 36..64 */
+ REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
+ /* IEEE 802.11a, channel 100..165 */
+ REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
+};
+
+
+/* Data Element Definitions */
+#define WPS_ID_CONFIG_METHODS 0x1008
+#define WPS_ID_REQ_TYPE 0x103A
+#define WPS_ID_DEVICE_NAME 0x1011
+#define WPS_ID_VERSION 0x104A
+#define WPS_ID_DEVICE_PWD_ID 0x1012
+#define WPS_ID_REQ_DEV_TYPE 0x106A
+#define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053
+#define WPS_ID_PRIM_DEV_TYPE 0x1054
+
+/* Device Password ID */
+#define DEV_PW_DEFAULT 0x0000
+#define DEV_PW_USER_SPECIFIED 0x0001,
+#define DEV_PW_MACHINE_SPECIFIED 0x0002
+#define DEV_PW_REKEY 0x0003
+#define DEV_PW_PUSHBUTTON 0x0004
+#define DEV_PW_REGISTRAR_SPECIFIED 0x0005
+
+/* Config Methods */
+#define WPS_CONFIG_USBA 0x0001
+#define WPS_CONFIG_ETHERNET 0x0002
+#define WPS_CONFIG_LABEL 0x0004
+#define WPS_CONFIG_DISPLAY 0x0008
+#define WPS_CONFIG_EXT_NFC_TOKEN 0x0010
+#define WPS_CONFIG_INT_NFC_TOKEN 0x0020
+#define WPS_CONFIG_NFC_INTERFACE 0x0040
+#define WPS_CONFIG_PUSHBUTTON 0x0080
+#define WPS_CONFIG_KEYPAD 0x0100
+#define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
+#define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
+#define WPS_CONFIG_VIRT_DISPLAY 0x2008
+#define WPS_CONFIG_PHY_DISPLAY 0x4008
+
+#define PM_BLOCK 1
+#define PM_ENABLE 0
+/*
+ * cfg80211_ops api/callback list
+ */
+static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
+ const struct ether_addr *sa, const struct ether_addr *bssid,
+ u8 **pheader, u32 *body_len, u8 *pbody);
+static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request,
+ struct cfg80211_ssid *this_ssid);
+static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request);
+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
+static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *params);
+static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
+ struct net_device *dev);
+static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
+ struct net_device *dev, u8 *mac,
+ struct station_info *sinfo);
+static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+ struct net_device *dev, bool enabled,
+ s32 timeout);
+static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_connect_params *sme);
+static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+ u16 reason_code);
+static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
+ enum nl80211_tx_power_setting type,
+ s32 dbm);
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
+static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
+ struct net_device *dev,
+ u8 key_idx, bool unicast, bool multicast);
+static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, bool pairwise, const u8 *mac_addr,
+ struct key_params *params);
+static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, bool pairwise, const u8 *mac_addr);
+static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, bool pairwise, const u8 *mac_addr,
+ void *cookie, void (*callback) (void *cookie,
+ struct key_params *params));
+static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
+ struct net_device *dev, u8 key_idx);
+static s32 wl_cfg80211_resume(struct wiphy *wiphy);
+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \
+ 2, 0))
+static s32 wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+ struct net_device *dev, u64 cookie);
+static s32 wl_cfg80211_del_station(struct wiphy *wiphy,
+ struct net_device *ndev, u8* mac_addr);
+#endif
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
+static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
+#else
+static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
+#endif
+static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_pmksa *pmksa);
+static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_pmksa *pmksa);
+static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
+ struct net_device *dev);
+static s32 wl_notify_escan_complete(struct wl_priv *wl,
+ struct net_device *ndev, bool aborted, bool fw_abort);
+/*
+ * event & event Q handlers for cfg80211 interfaces
+ */
+static s32 wl_create_event_handler(struct wl_priv *wl);
+static void wl_destroy_event_handler(struct wl_priv *wl);
+static s32 wl_event_handler(void *data);
+static void wl_init_eq(struct wl_priv *wl);
+static void wl_flush_eq(struct wl_priv *wl);
+static unsigned long wl_lock_eq(struct wl_priv *wl);
+static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags);
+static void wl_init_eq_lock(struct wl_priv *wl);
+static void wl_init_event_handler(struct wl_priv *wl);
+static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
+static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
+ const wl_event_msg_t *msg, void *data);
+static void wl_put_event(struct wl_event_q *e);
+static void wl_wakeup_event(struct wl_priv *wl);
+static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+static s32 wl_notify_connect_status(struct wl_priv *wl,
+ struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+static s32 wl_notify_roaming_status(struct wl_priv *wl,
+ struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data, bool completed);
+static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+#ifdef WL_SCHED_SCAN
+static s32
+wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+#endif /* WL_SCHED_SCAN */
+#ifdef PNO_SUPPORT
+static s32 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+#endif /* PNO_SUPPORT */
+static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_info,
+ enum wl_status state, bool set);
+/*
+ * register/deregister parent device
+ */
+static void wl_cfg80211_clear_parent_dev(void);
+
+/*
+ * ioctl utilites
+ */
+
+/*
+ * cfg80211 set_wiphy_params utilities
+ */
+static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
+static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
+static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
+
+/*
+ * wl profile utilities
+ */
+static s32 wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data, s32 item);
+static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item);
+static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev);
+
+/*
+ * cfg80211 connect utilites
+ */
+static s32 wl_set_wpa_version(struct net_device *dev,
+ struct cfg80211_connect_params *sme);
+static s32 wl_set_auth_type(struct net_device *dev,
+ struct cfg80211_connect_params *sme);
+static s32 wl_set_set_cipher(struct net_device *dev,
+ struct cfg80211_connect_params *sme);
+static s32 wl_set_key_mgmt(struct net_device *dev,
+ struct cfg80211_connect_params *sme);
+static s32 wl_set_set_sharedkey(struct net_device *dev,
+ struct cfg80211_connect_params *sme);
+#ifdef BCMWAPI_WPI
+static s32 wl_set_set_wapi_ie(struct net_device *dev,
+ struct cfg80211_connect_params *sme);
+#endif
+static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev);
+static void wl_ch_to_chanspec(int ch,
+ struct wl_join_params *join_params, size_t *join_params_size);
+
+/*
+ * information element utilities
+ */
+static void wl_rst_ie(struct wl_priv *wl);
+static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
+static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
+static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
+static u32 wl_get_ielen(struct wl_priv *wl);
+
+#ifdef WL11U
+bcm_tlv_t *
+wl_cfg80211_find_interworking_ie(u8 *parse, u32 len);
+static s32
+wl_cfg80211_add_iw_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag,
+ uint8 ie_id, uint8 *data, uint8 data_len);
+#endif /* WL11U */
+
+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev);
+static void wl_free_wdev(struct wl_priv *wl);
+static int
+wl_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+
+static s32 wl_inform_bss(struct wl_priv *wl);
+static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done);
+static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is_roam_done);
+static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy);
+s32 wl_cfg80211_channel_to_freq(u32 channel);
+
+#if defined(DHCP_SCAN_SUPPRESS)
+static void wl_cfg80211_work_handler(struct work_struct *work);
+static void wl_cfg80211_scan_supp_timerfunc(ulong data);
+#endif /* DHCP_SCAN_SUPPRESS */
+
+static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, const u8 *mac_addr,
+ struct key_params *params);
+/*
+ * key indianess swap utilities
+ */
+static void swap_key_from_BE(struct wl_wsec_key *key);
+static void swap_key_to_BE(struct wl_wsec_key *key);
+
+/*
+ * wl_priv memory init/deinit utilities
+ */
+static s32 wl_init_priv_mem(struct wl_priv *wl);
+static void wl_deinit_priv_mem(struct wl_priv *wl);
+
+static void wl_delay(u32 ms);
+
+/*
+ * ibss mode utilities
+ */
+static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
+static __used bool wl_is_ibssstarter(struct wl_priv *wl);
+
+/*
+ * link up/down , default configuration utilities
+ */
+static s32 __wl_cfg80211_up(struct wl_priv *wl);
+static s32 __wl_cfg80211_down(struct wl_priv *wl);
+static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
+static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
+static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
+static void wl_link_up(struct wl_priv *wl);
+static void wl_link_down(struct wl_priv *wl);
+static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
+static void wl_init_conf(struct wl_conf *conf);
+
+/*
+ * iscan handler
+ */
+static void wl_iscan_timer(unsigned long data);
+static void wl_term_iscan(struct wl_priv *wl);
+static s32 wl_init_scan(struct wl_priv *wl);
+static s32 wl_iscan_thread(void *data);
+static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
+ u16 action);
+static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request);
+static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
+static s32 wl_invoke_iscan(struct wl_priv *wl);
+static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
+ struct wl_scan_results **bss_list);
+static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
+static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan);
+static s32 wl_iscan_done(struct wl_priv *wl);
+static s32 wl_iscan_pending(struct wl_priv *wl);
+static s32 wl_iscan_inprogress(struct wl_priv *wl);
+static s32 wl_iscan_aborted(struct wl_priv *wl);
+
+/*
+ * find most significant bit set
+ */
+static __used u32 wl_find_msb(u16 bit16);
+
+/*
+ * rfkill support
+ */
+static int wl_setup_rfkill(struct wl_priv *wl, bool setup);
+static int wl_rfkill_set(void *data, bool blocked);
+
+static wl_scan_params_t *wl_cfg80211_scan_alloc_params(int channel,
+ int nprobes, int *out_params_size);
+static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac);
+
+/*
+ * Some external functions, TODO: move them to dhd_linux.h
+ */
+int dhd_add_monitor(char *name, struct net_device **new_ndev);
+int dhd_del_monitor(struct net_device *ndev);
+int dhd_monitor_init(void *dhd_pub);
+int dhd_monitor_uninit(void);
+int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
+
+
+
+#define CHECK_SYS_UP(wlpriv) \
+do { \
+ struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \
+ if (unlikely(!wl_get_drv_status(wlpriv, READY, ndev))) { \
+ AP6210_DEBUG("device is not ready\n"); \
+ return -EIO; \
+ } \
+} while (0)
+
+
+#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
+ (akm) == RSN_AKM_UNSPECIFIED || \
+ (akm) == RSN_AKM_PSK)
+
+
+extern int dhd_wait_pend8021x(struct net_device *dev);
+#ifdef PROP_TXSTATUS_VSDB
+extern int disable_proptx;
+extern int dhd_wlfc_init(dhd_pub_t *dhd);
+extern void dhd_wlfc_deinit(dhd_pub_t *dhd);
+#endif /* PROP_TXSTATUS_VSDB */
+
+#if (WL_DBG_LEVEL > 0)
+#define WL_DBG_ESTR_MAX 50
+static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
+ "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
+ "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
+ "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
+ "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
+ "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
+ "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
+ "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
+ "PFN_NET_LOST",
+ "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
+ "IBSS_ASSOC",
+ "RADIO", "PSM_WATCHDOG", "WLC_E_CCX_ASSOC_START", "WLC_E_CCX_ASSOC_ABORT",
+ "PROBREQ_MSG",
+ "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
+ "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
+ "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
+ "WLC_E_BTA_HCI_EVENT", "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE",
+ "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG",
+ "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND",
+ "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED",
+ "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT",
+ "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE",
+ "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP",
+ "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE"
+};
+#endif /* WL_DBG_LEVEL */
+
+#define CHAN2G(_channel, _freq, _flags) { \
+ .band = IEEE80211_BAND_2GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_channel), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+#define CHAN5G(_channel, _flags) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .center_freq = 5000 + (5 * (_channel)), \
+ .hw_value = (_channel), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
+#define RATETAB_ENT(_rateid, _flags) \
+ { \
+ .bitrate = RATE_TO_BASE100KBPS(_rateid), \
+ .hw_value = (_rateid), \
+ .flags = (_flags), \
+ }
+
+static struct ieee80211_rate __wl_rates[] = {
+ RATETAB_ENT(WLC_RATE_1M, 0),
+ RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATETAB_ENT(WLC_RATE_6M, 0),
+ RATETAB_ENT(WLC_RATE_9M, 0),
+ RATETAB_ENT(WLC_RATE_12M, 0),
+ RATETAB_ENT(WLC_RATE_18M, 0),
+ RATETAB_ENT(WLC_RATE_24M, 0),
+ RATETAB_ENT(WLC_RATE_36M, 0),
+ RATETAB_ENT(WLC_RATE_48M, 0),
+ RATETAB_ENT(WLC_RATE_54M, 0)
+};
+
+#define wl_a_rates (__wl_rates + 4)
+#define wl_a_rates_size 8
+#define wl_g_rates (__wl_rates + 0)
+#define wl_g_rates_size 12
+
+static struct ieee80211_channel __wl_2ghz_channels[] = {
+ CHAN2G(1, 2412, 0),
+ CHAN2G(2, 2417, 0),
+ CHAN2G(3, 2422, 0),
+ CHAN2G(4, 2427, 0),
+ CHAN2G(5, 2432, 0),
+ CHAN2G(6, 2437, 0),
+ CHAN2G(7, 2442, 0),
+ CHAN2G(8, 2447, 0),
+ CHAN2G(9, 2452, 0),
+ CHAN2G(10, 2457, 0),
+ CHAN2G(11, 2462, 0),
+ CHAN2G(12, 2467, 0),
+ CHAN2G(13, 2472, 0),
+ CHAN2G(14, 2484, 0)
+};
+
+static struct ieee80211_channel __wl_5ghz_a_channels[] = {
+ CHAN5G(34, 0), CHAN5G(36, 0),
+ CHAN5G(38, 0), CHAN5G(40, 0),
+ CHAN5G(42, 0), CHAN5G(44, 0),
+ CHAN5G(46, 0), CHAN5G(48, 0),
+ CHAN5G(52, 0), CHAN5G(56, 0),
+ CHAN5G(60, 0), CHAN5G(64, 0),
+ CHAN5G(100, 0), CHAN5G(104, 0),
+ CHAN5G(108, 0), CHAN5G(112, 0),
+ CHAN5G(116, 0), CHAN5G(120, 0),
+ CHAN5G(124, 0), CHAN5G(128, 0),
+ CHAN5G(132, 0), CHAN5G(136, 0),
+ CHAN5G(140, 0), CHAN5G(149, 0),
+ CHAN5G(153, 0), CHAN5G(157, 0),
+ CHAN5G(161, 0), CHAN5G(165, 0)
+};
+
+static struct ieee80211_supported_band __wl_band_2ghz = {
+ .band = IEEE80211_BAND_2GHZ,
+ .channels = __wl_2ghz_channels,
+ .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
+ .bitrates = wl_g_rates,
+ .n_bitrates = wl_g_rates_size
+};
+
+static struct ieee80211_supported_band __wl_band_5ghz_a = {
+ .band = IEEE80211_BAND_5GHZ,
+ .channels = __wl_5ghz_a_channels,
+ .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
+ .bitrates = wl_a_rates,
+ .n_bitrates = wl_a_rates_size
+};
+
+static const u32 __wl_cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+ WLAN_CIPHER_SUITE_AES_CMAC,
+#ifdef BCMWAPI_WPI
+ WLAN_CIPHER_SUITE_SMS4
+#endif
+};
+
+
+/* IOCtl version read from targeted driver */
+static int ioctl_version;
+
+/* Return a new chanspec given a legacy chanspec
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_chspec_from_legacy(chanspec_t legacy_chspec)
+{
+ chanspec_t chspec;
+
+ /* get the channel number */
+ chspec = LCHSPEC_CHANNEL(legacy_chspec);
+
+ /* convert the band */
+ if (LCHSPEC_IS2G(legacy_chspec)) {
+ chspec |= WL_CHANSPEC_BAND_2G;
+ } else {
+ chspec |= WL_CHANSPEC_BAND_5G;
+ }
+
+ /* convert the bw and sideband */
+ if (LCHSPEC_IS20(legacy_chspec)) {
+ chspec |= WL_CHANSPEC_BW_20;
+ } else {
+ chspec |= WL_CHANSPEC_BW_40;
+ if (LCHSPEC_CTL_SB(legacy_chspec) == WL_LCHANSPEC_CTL_SB_LOWER) {
+ chspec |= WL_CHANSPEC_CTL_SB_L;
+ } else {
+ chspec |= WL_CHANSPEC_CTL_SB_U;
+ }
+ }
+
+ if (wf_chspec_malformed(chspec)) {
+ AP6210_ERR("wl_chspec_from_legacy: output chanspec (0x%04X) malformed\n",
+ chspec);
+ return INVCHANSPEC;
+ }
+
+ return chspec;
+}
+
+/* Return a legacy chanspec given a new chanspec
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_chspec_to_legacy(chanspec_t chspec)
+{
+ chanspec_t lchspec;
+
+ if (wf_chspec_malformed(chspec)) {
+ AP6210_ERR("wl_chspec_to_legacy: input chanspec (0x%04X) malformed\n",
+ chspec);
+ return INVCHANSPEC;
+ }
+
+ /* get the channel number */
+ lchspec = CHSPEC_CHANNEL(chspec);
+
+ /* convert the band */
+ if (CHSPEC_IS2G(chspec)) {
+ lchspec |= WL_LCHANSPEC_BAND_2G;
+ } else {
+ lchspec |= WL_LCHANSPEC_BAND_5G;
+ }
+
+ /* convert the bw and sideband */
+ if (CHSPEC_IS20(chspec)) {
+ lchspec |= WL_LCHANSPEC_BW_20;
+ lchspec |= WL_LCHANSPEC_CTL_SB_NONE;
+ } else if (CHSPEC_IS40(chspec)) {
+ lchspec |= WL_LCHANSPEC_BW_40;
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_L) {
+ lchspec |= WL_LCHANSPEC_CTL_SB_LOWER;
+ } else {
+ lchspec |= WL_LCHANSPEC_CTL_SB_UPPER;
+ }
+ } else {
+ /* cannot express the bandwidth */
+ char chanbuf[CHANSPEC_STR_LEN];
+ AP6210_ERR(
+ "wl_chspec_to_legacy: unable to convert chanspec %s (0x%04X) "
+ "to pre-11ac format\n",
+ wf_chspec_ntoa(chspec, chanbuf), chspec);
+ return INVCHANSPEC;
+ }
+
+ return lchspec;
+}
+
+/* given a chanspec value, do the endian and chanspec version conversion to
+ * a chanspec_t value
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_chspec_host_to_driver(chanspec_t chanspec)
+{
+ if (ioctl_version == 1) {
+ chanspec = wl_chspec_to_legacy(chanspec);
+ if (chanspec == INVCHANSPEC) {
+ return chanspec;
+ }
+ }
+ chanspec = htodchanspec(chanspec);
+
+ return chanspec;
+}
+
+/* given a channel value, do the endian and chanspec version conversion to
+ * a chanspec_t value
+ * Returns INVCHANSPEC on error
+ */
+chanspec_t
+wl_ch_host_to_driver(u16 channel)
+{
+
+ chanspec_t chanspec;
+
+ chanspec = channel & WL_CHANSPEC_CHAN_MASK;
+
+ if (channel <= CH_MAX_2G_CHANNEL)
+ chanspec |= WL_CHANSPEC_BAND_2G;
+ else
+ chanspec |= WL_CHANSPEC_BAND_5G;
+
+ chanspec |= WL_CHANSPEC_BW_20;
+ chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+
+ return wl_chspec_host_to_driver(chanspec);
+}
+
+/* given a chanspec value from the driver, do the endian and chanspec version conversion to
+ * a chanspec_t value
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_chspec_driver_to_host(chanspec_t chanspec)
+{
+ chanspec = dtohchanspec(chanspec);
+ if (ioctl_version == 1) {
+ chanspec = wl_chspec_from_legacy(chanspec);
+ }
+
+ return chanspec;
+}
+
+/* There isn't a lot of sense in it, but you can transmit anything you like */
+static const struct ieee80211_txrx_stypes
+wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
+ [NL80211_IFTYPE_ADHOC] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
+ },
+ [NL80211_IFTYPE_STATION] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ },
+ [NL80211_IFTYPE_AP] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4)
+ },
+ [NL80211_IFTYPE_AP_VLAN] = {
+ /* copy AP */
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4)
+ },
+ [NL80211_IFTYPE_P2P_CLIENT] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ },
+ [NL80211_IFTYPE_P2P_GO] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4)
+ }
+};
+
+static void swap_key_from_BE(struct wl_wsec_key *key)
+{
+ key->index = htod32(key->index);
+ key->len = htod32(key->len);
+ key->algo = htod32(key->algo);
+ key->flags = htod32(key->flags);
+ key->rxiv.hi = htod32(key->rxiv.hi);
+ key->rxiv.lo = htod16(key->rxiv.lo);
+ key->iv_initialized = htod32(key->iv_initialized);
+}
+
+static void swap_key_to_BE(struct wl_wsec_key *key)
+{
+ key->index = dtoh32(key->index);
+ key->len = dtoh32(key->len);
+ key->algo = dtoh32(key->algo);
+ key->flags = dtoh32(key->flags);
+ key->rxiv.hi = dtoh32(key->rxiv.hi);
+ key->rxiv.lo = dtoh16(key->rxiv.lo);
+ key->iv_initialized = dtoh32(key->iv_initialized);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
+/* For debug: Dump the contents of the encoded wps ie buffe */
+static void
+wl_validate_wps_ie(char *wps_ie, s32 wps_ie_len, bool *pbc)
+{
+ #define WPS_IE_FIXED_LEN 6
+ u16 len;
+ u8 *subel = NULL;
+ u16 subelt_id;
+ u16 subelt_len;
+ u16 val;
+ u8 *valptr = (uint8*) &val;
+ if (wps_ie == NULL || wps_ie_len < WPS_IE_FIXED_LEN) {
+ AP6210_ERR("invalid argument : NULL\n"));
+ return;
+ }
+ len = (u16)wps_ie[TLV_LEN_OFF];
+
+ if (len > wps_ie_len) {
+ AP6210_ERR("invalid length len %d, wps ie len %d\n", len, wps_ie_len);
+ return;
+ }
+ AP6210_DEBUG("wps_ie len=%d\n", len);
+ len -= 4; /* for the WPS IE's OUI, oui_type fields */
+ subel = wps_ie + WPS_IE_FIXED_LEN;
+ while (len >= 4) { /* must have attr id, attr len fields */
+ valptr[0] = *subel++;
+ valptr[1] = *subel++;
+ subelt_id = HTON16(val);
+
+ valptr[0] = *subel++;
+ valptr[1] = *subel++;
+ subelt_len = HTON16(val);
+
+ len -= 4; /* for the attr id, attr len fields */
+ len -= subelt_len; /* for the remaining fields in this attribute */
+ AP6210_DEBUG(" subel=%p, subelt_id=0x%x subelt_len=%u\n",
+ subel, subelt_id, subelt_len);
+
+ if (subelt_id == WPS_ID_VERSION) {
+ AP6210_DEBUG(" attr WPS_ID_VERSION: %u\n", *subel);
+ } else if (subelt_id == WPS_ID_REQ_TYPE) {
+ AP6210_DEBUG(" attr WPS_ID_REQ_TYPE: %u\n", *subel);
+ } else if (subelt_id == WPS_ID_CONFIG_METHODS) {
+ valptr[0] = *subel;
+ valptr[1] = *(subel + 1);
+ AP6210_DEBUG(" attr WPS_ID_CONFIG_METHODS: %x\n", HTON16(val));
+ } else if (subelt_id == WPS_ID_DEVICE_NAME) {
+ char devname[100];
+ memcpy(devname, subel, subelt_len);
+ devname[subelt_len] = '\0';
+ AP6210_DEBUG(" attr WPS_ID_DEVICE_NAME: %s (len %u)\n",
+ devname, subelt_len);
+ } else if (subelt_id == WPS_ID_DEVICE_PWD_ID) {
+ valptr[0] = *subel;
+ valptr[1] = *(subel + 1);
+ AP6210_DEBUG(" attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val));
+ *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false;
+ } else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) {
+ valptr[0] = *subel;
+ valptr[1] = *(subel + 1);
+ AP6210_DEBUG(" attr WPS_ID_PRIM_DEV_TYPE: cat=%u \n", HTON16(val));
+ valptr[0] = *(subel + 6);
+ valptr[1] = *(subel + 7);
+ AP6210_DEBUG(" attr WPS_ID_PRIM_DEV_TYPE: subcat=%u\n", HTON16(val));
+ } else if (subelt_id == WPS_ID_REQ_DEV_TYPE) {
+ valptr[0] = *subel;
+ valptr[1] = *(subel + 1);
+ AP6210_DEBUG(" attr WPS_ID_REQ_DEV_TYPE: cat=%u\n", HTON16(val));
+ valptr[0] = *(subel + 6);
+ valptr[1] = *(subel + 7);
+ AP6210_DEBUG(" attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val));
+ } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) {
+ valptr[0] = *subel;
+ valptr[1] = *(subel + 1);
+ AP6210_DEBUG(" attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS"
+ ": cat=%u\n", HTON16(val));
+ } else {
+ AP6210_DEBUG(" unknown attr 0x%x\n", subelt_id);
+ }
+
+ subel += subelt_len;
+ }
+}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) */
+
+static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy)
+{
+ chanspec_t chspec;
+ int err = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *dev = wl_to_prmry_ndev(wl);
+ struct ether_addr bssid;
+ struct wl_bss_info *bss = NULL;
+
+ if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
+ /* STA interface is not associated. So start the new interface on a temp
+ * channel . Later proper channel will be applied by the above framework
+ * via set_channel (cfg80211 API).
+ */
+ AP6210_DEBUG("Not associated. Return a temp channel. \n");
+ return wl_ch_host_to_driver(WL_P2P_TEMP_CHAN);
+ }
+
+
+ *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
+ if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf,
+ WL_EXTRA_BUF_MAX, false))) {
+ AP6210_ERR("Failed to get associated bss info, use temp channel \n");
+ chspec = wl_ch_host_to_driver(WL_P2P_TEMP_CHAN);
+ }
+ else {
+ bss = (struct wl_bss_info *) (wl->extra_buf + 4);
+ chspec = bss->chanspec;
+ AP6210_DEBUG("Valid BSS Found. chanspec:%d \n", chspec);
+ }
+ return chspec;
+}
+
+static struct net_device* wl_cfg80211_add_monitor_if(char *name)
+{
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
+ AP6210_DEBUG("wl_cfg80211_add_monitor_if: No more support monitor interface\n");
+ return ERR_PTR(-EOPNOTSUPP);
+#else
+ struct net_device* ndev = NULL;
+
+ dhd_add_monitor(name, &ndev);
+ AP6210_DEBUG("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev);
+ return ndev;
+#endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */
+}
+
+static struct net_device *
+wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+{
+ s32 err;
+ s32 timeout = -1;
+ s32 wlif_type = -1;
+ s32 mode = 0;
+ s32 val = 0;
+ s32 dhd_mode = 0;
+ chanspec_t chspec;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *_ndev;
+ struct ether_addr primary_mac;
+ int (*net_attach)(void *dhdp, int ifidx);
+ bool rollback_lock = false;
+#ifdef PROP_TXSTATUS_VSDB
+ s32 up = 1;
+ dhd_pub_t *dhd;
+#endif /* PROP_TXSTATUS_VSDB */
+
+ if (!wl)
+ return ERR_PTR(-EINVAL);
+
+#ifdef PROP_TXSTATUS_VSDB
+ dhd = (dhd_pub_t *)(wl->pub);
+#endif /* PROP_TXSTATUS_VSDB */
+
+
+ /* Use primary I/F for sending cmds down to firmware */
+ _ndev = wl_to_prmry_ndev(wl);
+
+ AP6210_DEBUG("if name: %s, type: %d\n", name, type);
+ switch (type) {
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_WDS:
+ case NL80211_IFTYPE_MESH_POINT:
+ AP6210_ERR("Unsupported interface type\n");
+ mode = WL_MODE_IBSS;
+ return NULL;
+ case NL80211_IFTYPE_MONITOR:
+ return wl_cfg80211_add_monitor_if(name);
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_STATION:
+ wlif_type = WL_P2P_IF_CLIENT;
+ mode = WL_MODE_BSS;
+ break;
+ case NL80211_IFTYPE_P2P_GO:
+ case NL80211_IFTYPE_AP:
+ wlif_type = WL_P2P_IF_GO;
+ mode = WL_MODE_AP;
+ break;
+ default:
+ AP6210_ERR("Unsupported interface type\n");
+ return NULL;
+ break;
+ }
+
+ if (!name) {
+ AP6210_ERR("name is NULL\n");
+ return NULL;
+ }
+ if (wl->p2p_supported && (wlif_type != -1)) {
+ if (wl_get_p2p_status(wl, IF_DELETING)) {
+ /* wait till IF_DEL is complete
+ * release the lock for the unregister to proceed
+ */
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
+ AP6210_DEBUG("%s: Released the lock and wait till IF_DEL is complete\n",
+ __func__);
+ timeout = wait_event_interruptible_timeout(wl->netif_change_event,
+ (wl_get_p2p_status(wl, IF_DELETING) == false),
+ msecs_to_jiffies(MAX_WAIT_TIME));
+
+ /* put back the rtnl_lock again */
+ if (rollback_lock) {
+ rtnl_lock();
+ rollback_lock = false;
+ }
+ if (timeout > 0) {
+ AP6210_ERR("IF DEL is Success\n");
+
+ } else {
+ AP6210_ERR("timeount < 0, return -EAGAIN\n");
+ return ERR_PTR(-EAGAIN);
+ }
+ /* It should be now be safe to put this check here since we are sure
+ * by now netdev_notifier (unregister) would have been called
+ */
+ if (wl->iface_cnt == IFACE_MAX_CNT)
+ return ERR_PTR(-ENOMEM);
+ }
+
+#ifdef PROP_TXSTATUS_VSDB
+ if (!dhd)
+ return ERR_PTR(-ENODEV);
+#endif /* PROP_TXSTATUS_VSDB */
+ if (!wl->p2p)
+ return ERR_PTR(-ENODEV);
+
+ if (wl->p2p && !wl->p2p->on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
+ p2p_on(wl) = true;
+ wl_cfgp2p_set_firm_p2p(wl);
+ wl_cfgp2p_init_discovery(wl);
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac,
+ &wl->p2p->dev_addr, &wl->p2p->int_addr);
+ }
+
+ memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
+ strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
+
+ wl_notify_escan_complete(wl, _ndev, true, true);
+#ifdef PROP_TXSTATUS_VSDB
+ if (!wl->wlfc_on && !disable_proptx) {
+ dhd->wlfc_enabled = true;
+ dhd_wlfc_init(dhd);
+ err = wldev_ioctl(_ndev, WLC_UP, &up, sizeof(s32), true);
+ if (err < 0)
+ AP6210_ERR("WLC_UP return err:%d\n", err);
+ wl->wlfc_on = true;
+ }
+#endif /* PROP_TXSTATUS_VSDB */
+
+ /* In concurrency case, STA may be already associated in a particular channel.
+ * so retrieve the current channel of primary interface and then start the virtual
+ * interface on that.
+ */
+ chspec = wl_cfg80211_get_shared_freq(wiphy);
+
+ /* For P2P mode, use P2P-specific driver features to create the
+ * bss: "wl p2p_ifadd"
+ */
+ wl_set_p2p_status(wl, IF_ADD);
+ if (wlif_type == WL_P2P_IF_GO)
+ wldev_iovar_setint(_ndev, "mpc", 0);
+ err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
+
+ if (unlikely(err)) {
+ AP6210_ERR(" virtual iface add failed (%d) \n", err);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ timeout = wait_event_interruptible_timeout(wl->netif_change_event,
+ (wl_get_p2p_status(wl, IF_ADD) == false),
+ msecs_to_jiffies(MAX_WAIT_TIME));
+ if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
+
+ struct wireless_dev *vwdev;
+ vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
+ if (unlikely(!vwdev)) {
+ AP6210_ERR("Could not allocate wireless device\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ vwdev->wiphy = wl->wdev->wiphy;
+ AP6210_DEBUG(" virtual interface(%s) is created memalloc done \n",
+ wl->p2p->vir_ifname);
+ vwdev->iftype = type;
+ _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
+ _ndev->ieee80211_ptr = vwdev;
+ SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
+ vwdev->netdev = _ndev;
+ wl_set_drv_status(wl, READY, _ndev);
+ wl->p2p->vif_created = true;
+ wl_set_mode_by_netdev(wl, _ndev, mode);
+ net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
+ if (net_attach && !net_attach(wl->pub, _ndev->ifindex)) {
+ wl_alloc_netinfo(wl, _ndev, vwdev, mode, PM_ENABLE);
+ val = 1;
+ /* Disable firmware roaming for P2P interface */
+ wldev_iovar_setint(_ndev, "roam_off", val);
+ AP6210_ERR(" virtual interface(%s) is "
+ "created net attach done\n", wl->p2p->vir_ifname);
+ if (mode == WL_MODE_AP)
+ wl_set_drv_status(wl, CONNECTED, _ndev);
+ if (type == NL80211_IFTYPE_P2P_CLIENT)
+ dhd_mode = DHD_FLAG_P2P_GC_MODE;
+ else if (type == NL80211_IFTYPE_P2P_GO)
+ dhd_mode = DHD_FLAG_P2P_GO_MODE;
+ DNGL_FUNC(dhd_cfg80211_set_p2p_info, (wl, dhd_mode));
+ } else {
+ /* put back the rtnl_lock again */
+ if (rollback_lock)
+ rtnl_lock();
+ goto fail;
+ }
+ /* put back the rtnl_lock again */
+ if (rollback_lock)
+ rtnl_lock();
+ return _ndev;
+
+ } else {
+ wl_clr_p2p_status(wl, IF_ADD);
+ AP6210_ERR(" virtual interface(%s) is not created \n", wl->p2p->vir_ifname);
+ memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
+ wl->p2p->vif_created = false;
+#ifdef PROP_TXSTATUS_VSDB
+ if (dhd->wlfc_enabled && wl->wlfc_on) {
+ dhd->wlfc_enabled = false;
+ dhd_wlfc_deinit(dhd);
+ wl->wlfc_on = false;
+ }
+#endif /* PROP_TXSTATUS_VSDB */
+ }
+ }
+fail:
+ if (wlif_type == WL_P2P_IF_GO)
+ wldev_iovar_setint(_ndev, "mpc", 1);
+ return ERR_PTR(-ENODEV);
+}
+
+static s32
+wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct ether_addr p2p_mac;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ s32 timeout = -1;
+ s32 ret = 0;
+ AP6210_DEBUG("Enter\n");
+
+ if (wl->p2p_net == dev) {
+ /* Since there is no ifidx corresponding to p2p0, cmds to
+ * firmware should be routed through primary I/F
+ */
+ dev = wl_to_prmry_ndev(wl);
+ }
+
+ if (wl->p2p_supported) {
+ memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
+
+ /* Clear GO_NEG_PHASE bit to take care of GO-NEG-FAIL cases
+ */
+ AP6210_DEBUG("P2P: GO_NEG_PHASE status cleared ");
+ wl_clr_p2p_status(wl, GO_NEG_PHASE);
+ if (wl->p2p->vif_created) {
+ if (wl_get_drv_status(wl, SCANNING, dev)) {
+ wl_notify_escan_complete(wl, dev, true, true);
+ }
+ wldev_iovar_setint(dev, "mpc", 1);
+
+ /* for GC */
+ if (wl_get_drv_status(wl, DISCONNECTING, dev) &&
+ (wl_get_mode_by_netdev(wl, dev) != WL_MODE_AP)) {
+ AP6210_ERR("Wait for Link Down event for GC !\n");
+ wait_for_completion_timeout
+ (&wl->iface_disable, msecs_to_jiffies(500));
+ }
+ wl_set_p2p_status(wl, IF_DELETING);
+ DNGL_FUNC(dhd_cfg80211_clean_p2p_info, (wl));
+
+ /* for GO */
+ if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
+ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, false);
+ /* disable interface before bsscfg free */
+ ret = wl_cfgp2p_ifdisable(wl, &p2p_mac);
+ /* if fw doesn't support "ifdis",
+ do not wait for link down of ap mode
+ */
+ if (ret == 0) {
+ AP6210_ERR("Wait for Link Down event for GO !!!\n");
+ wait_for_completion_timeout(&wl->iface_disable,
+ msecs_to_jiffies(500));
+ } else {
+ msleep(300);
+ }
+ }
+ wl_cfgp2p_clear_management_ie(wl, wl_cfgp2p_find_idx(wl, dev));
+ /* delete interface after link down */
+ ret = wl_cfgp2p_ifdel(wl, &p2p_mac);
+ /* Firmware could not delete the interface so we will not get WLC_E_IF
+ * event for cleaning the dhd virtual nw interace
+ * So lets do it here. Failures from fw will ensure the application to do
+ * ifconfig <inter> down and up sequnce, which will reload the fw
+ * however we should cleanup the linux network virtual interfaces
+ */
+ /* Request framework to RESET and clean up */
+ if (ret) {
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ AP6210_ERR("Firmware returned an error (%d) from p2p_ifdel"
+ "HANG Notification sent to %s\n", ret, ndev->name);
+ net_os_send_hang_message(ndev);
+ }
+ /* Wait for IF_DEL operation to be finished in firmware */
+ timeout = wait_event_interruptible_timeout(wl->netif_change_event,
+ (wl->p2p->vif_created == false),
+ msecs_to_jiffies(MAX_WAIT_TIME));
+ if (timeout > 0 && (wl->p2p->vif_created == false)) {
+ AP6210_DEBUG("IFDEL operation done\n");
+ } else {
+ AP6210_ERR("IFDEL didn't complete properly\n");
+ }
+ ret = dhd_del_monitor(dev);
+ }
+ }
+ return ret;
+}
+
+static s32
+wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+{
+ s32 ap = 0;
+ s32 infra = 0;
+ s32 wlif_type;
+ s32 mode = 0;
+ chanspec_t chspec;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ AP6210_DEBUG("Enter type %d\n", type);
+ switch (type) {
+ case NL80211_IFTYPE_MONITOR:
+ case NL80211_IFTYPE_WDS:
+ case NL80211_IFTYPE_MESH_POINT:
+ ap = 1;
+ AP6210_ERR("type (%d) : currently we do not support this type\n",
+ type);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ mode = WL_MODE_IBSS;
+ break;
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ mode = WL_MODE_BSS;
+ infra = 1;
+ break;
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_P2P_GO:
+ mode = WL_MODE_AP;
+ ap = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (!dhd)
+ return -EINVAL;
+ if (ap) {
+ wl_set_mode_by_netdev(wl, ndev, mode);
+ if (wl->p2p_supported && wl->p2p->vif_created) {
+ AP6210_DEBUG("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
+ p2p_on(wl));
+ wldev_iovar_setint(ndev, "mpc", 0);
+ wl_notify_escan_complete(wl, ndev, true, true);
+
+ /* In concurrency case, STA may be already associated in a particular
+ * channel. so retrieve the current channel of primary interface and
+ * then start the virtual interface on that.
+ */
+ chspec = wl_cfg80211_get_shared_freq(wiphy);
+
+ wlif_type = WL_P2P_IF_GO;
+ AP6210_ERR("%s : ap (%d), infra (%d), iftype: (%d)\n",
+ ndev->name, ap, infra, type);
+ wl_set_p2p_status(wl, IF_CHANGING);
+ wl_clr_p2p_status(wl, IF_CHANGED);
+ wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
+ wait_event_interruptible_timeout(wl->netif_change_event,
+ (wl_get_p2p_status(wl, IF_CHANGED) == true),
+ msecs_to_jiffies(MAX_WAIT_TIME));
+ wl_set_mode_by_netdev(wl, ndev, mode);
+ dhd->op_mode &= ~DHD_FLAG_P2P_GC_MODE;
+ dhd->op_mode |= DHD_FLAG_P2P_GO_MODE;
+ wl_clr_p2p_status(wl, IF_CHANGING);
+ wl_clr_p2p_status(wl, IF_CHANGED);
+ if (mode == WL_MODE_AP)
+ wl_set_drv_status(wl, CONNECTED, ndev);
+ } else if (ndev == wl_to_prmry_ndev(wl) &&
+ !wl_get_drv_status(wl, AP_CREATED, ndev)) {
+ wl_set_drv_status(wl, AP_CREATING, ndev);
+ if (!wl->ap_info &&
+ !(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) {
+ AP6210_ERR("struct ap_saved_ie allocation failed\n");
+ return -ENOMEM;
+ }
+ } else {
+ AP6210_ERR("Cannot change the interface for GO or SOFTAP\n");
+ return -EINVAL;
+ }
+ } else {
+ AP6210_DEBUG("Change_virtual_iface for transition from GO/AP to client/STA");
+ }
+
+ ndev->ieee80211_ptr->iftype = type;
+ return 0;
+}
+
+s32
+wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
+ void* _net_attach)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ s32 ret = BCME_OK;
+ AP6210_DEBUG("Enter");
+ if (!ndev) {
+ AP6210_ERR("net is NULL\n");
+ return 0;
+ }
+ if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) {
+ AP6210_DEBUG("IF_ADD event called from dongle, old interface name: %s,"
+ "new name: %s\n", ndev->name, wl->p2p->vir_ifname);
+ /* Assign the net device to CONNECT BSSCFG */
+ strncpy(ndev->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = ndev;
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = bssidx;
+ wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach;
+ ndev->ifindex = idx;
+ wl_clr_p2p_status(wl, IF_ADD);
+
+ wake_up_interruptible(&wl->netif_change_event);
+ } else {
+ ret = BCME_NOTREADY;
+ }
+ return ret;
+}
+
+s32
+wl_cfg80211_notify_ifdel(void)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+ AP6210_DEBUG("Enter \n");
+ wl_clr_p2p_status(wl, IF_DELETING);
+ wake_up_interruptible(&wl->netif_change_event);
+ return 0;
+}
+
+s32
+wl_cfg80211_ifdel_ops(struct net_device *ndev)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ bool rollback_lock = false;
+ s32 index = 0;
+#ifdef PROP_TXSTATUS_VSDB
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+#endif /* PROP_TXSTATUS_VSDB */
+ if (!ndev || (strlen(ndev->name) == 0)) {
+ AP6210_ERR("net is NULL\n");
+ return 0;
+ }
+
+ if (p2p_is_on(wl) && wl->p2p->vif_created &&
+ wl_get_p2p_status(wl, IF_DELETING)) {
+ if (wl->scan_request &&
+ (wl->escan_info.ndev == ndev)) {
+ /* Abort any pending scan requests */
+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+ if (!rtnl_is_locked()) {
+ rtnl_lock();
+ rollback_lock = true;
+ }
+ AP6210_DEBUG("ESCAN COMPLETED\n");
+ wl_notify_escan_complete(wl, ndev, true, false);
+ if (rollback_lock)
+ rtnl_unlock();
+ }
+ AP6210_ERR("IF_DEL event called from dongle, net %x, vif name: %s\n",
+ (unsigned int)ndev, wl->p2p->vir_ifname);
+
+ memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
+ index = wl_cfgp2p_find_idx(wl, ndev);
+ wl_to_p2p_bss_ndev(wl, index) = NULL;
+ wl_to_p2p_bss_bssidx(wl, index) = WL_INVALID;
+ wl->p2p->vif_created = false;
+
+ AP6210_DEBUG("index : %d\n", index);
+#ifdef PROP_TXSTATUS_VSDB
+ if (dhd->wlfc_enabled && wl->wlfc_on) {
+ dhd->wlfc_enabled = false;
+ dhd_wlfc_deinit(dhd);
+ wl->wlfc_on = false;
+ }
+#endif /* PROP_TXSTATUS_VSDB */
+ wl_clr_drv_status(wl, CONNECTED, ndev);
+ }
+ /* Wake up any waiting thread */
+ wake_up_interruptible(&wl->netif_change_event);
+
+ return 0;
+}
+
+s32
+wl_cfg80211_is_progress_ifadd(void)
+{
+ s32 is_progress = 0;
+ struct wl_priv *wl = wlcfg_drv_priv;
+ if (wl_get_p2p_status(wl, IF_ADD))
+ is_progress = 1;
+ return is_progress;
+}
+
+s32
+wl_cfg80211_is_progress_ifchange(void)
+{
+ s32 is_progress = 0;
+ struct wl_priv *wl = wlcfg_drv_priv;
+ if (wl_get_p2p_status(wl, IF_CHANGING))
+ is_progress = 1;
+ return is_progress;
+}
+
+
+s32
+wl_cfg80211_notify_ifchange(void)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ if (wl_get_p2p_status(wl, IF_CHANGING)) {
+ wl_set_p2p_status(wl, IF_CHANGED);
+ wake_up_interruptible(&wl->netif_change_event);
+ }
+ return 0;
+}
+
+/* Find listen channel */
+static s32 wl_find_listen_channel(struct wl_priv *wl,
+ u8 *ie, u32 ie_len)
+{
+ wifi_p2p_ie_t *p2p_ie;
+ u8 *end, *pos;
+ s32 listen_channel;
+
+ p2p_ie = wl_cfgp2p_find_p2pie(ie, ie_len);
+
+ if (p2p_ie == NULL)
+ return 0;
+
+ pos = p2p_ie->subelts;
+ end = p2p_ie->subelts + (p2p_ie->len - 4);
+
+ AP6210_DEBUG(" found p2p ie ! lenth %d \n",
+ p2p_ie->len);
+
+ while (pos < end) {
+ uint16 attr_len;
+ if (pos + 2 >= end) {
+ AP6210_DEBUG(" -- Invalid P2P attribute");
+ return 0;
+ }
+ attr_len = ((uint16) (((pos + 1)[1] << 8) | (pos + 1)[0]));
+
+ if (pos + 3 + attr_len > end) {
+ AP6210_DEBUG("P2P: Attribute underflow "
+ "(len=%u left=%d)",
+ attr_len, (int) (end - pos - 3));
+ return 0;
+ }
+
+ /* if Listen Channel att id is 6 and the vailue is valid,
+ * return the listen channel
+ */
+ if (pos[0] == 6) {
+ /* listen channel subel length format
+ * 1(id) + 2(len) + 3(country) + 1(op. class) + 1(chan num)
+ */
+ listen_channel = pos[1 + 2 + 3 + 1];
+
+ if (listen_channel == SOCIAL_CHAN_1 ||
+ listen_channel == SOCIAL_CHAN_2 ||
+ listen_channel == SOCIAL_CHAN_3) {
+ AP6210_DEBUG(" Found my Listen Channel %d \n", listen_channel);
+ return listen_channel;
+ }
+ }
+ pos += 3 + attr_len;
+ }
+ return 0;
+}
+
+static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request)
+{
+ u32 n_ssids;
+ u32 n_channels;
+ u16 channel;
+ chanspec_t chanspec;
+ s32 i = 0, j = 0, offset;
+ char *ptr;
+ wlc_ssid_t ssid;
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+ memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
+ params->bss_type = DOT11_BSSTYPE_ANY;
+ params->scan_type = 0;
+ params->nprobes = -1;
+ params->active_time = -1;
+ params->passive_time = -1;
+ params->home_time = -1;
+ params->channel_num = 0;
+ memset(&params->ssid, 0, sizeof(wlc_ssid_t));
+
+ AP6210_DEBUG("Preparing Scan request\n");
+ AP6210_DEBUG("nprobes=%d\n", params->nprobes);
+ AP6210_DEBUG("active_time=%d\n", params->active_time);
+ AP6210_DEBUG("passive_time=%d\n", params->passive_time);
+ AP6210_DEBUG("home_time=%d\n", params->home_time);
+ AP6210_DEBUG("scan_type=%d\n", params->scan_type);
+
+ params->nprobes = htod32(params->nprobes);
+ params->active_time = htod32(params->active_time);
+ params->passive_time = htod32(params->passive_time);
+ params->home_time = htod32(params->home_time);
+
+ /* if request is null just exit so it will be all channel broadcast scan */
+ if (!request)
+ return;
+
+ n_ssids = request->n_ssids;
+ n_channels = request->n_channels;
+
+ /* Copy channel array if applicable */
+ AP6210_DEBUG("### List of channelspecs to scan ###\n");
+ if (n_channels > 0) {
+ for (i = 0; i < n_channels; i++) {
+ chanspec = 0;
+ channel = ieee80211_frequency_to_channel(request->channels[i]->center_freq);
+ /* SKIP DFS channels for Secondary interface */
+ if ((wl->escan_info.ndev != wl_to_prmry_ndev(wl)) &&
+ (request->channels[i]->flags &
+ (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN)))
+ continue;
+
+ if (request->channels[i]->band == IEEE80211_BAND_2GHZ) {
+#ifdef WL_HOST_BAND_MGMT
+ if (wl->curr_band == WLC_BAND_5G) {
+ AP6210_DEBUG("In 5G only mode, omit 2G channel:%d\n", channel);
+ continue;
+ }
+#endif /* WL_HOST_BAND_MGMT */
+ chanspec |= WL_CHANSPEC_BAND_2G;
+ } else {
+#ifdef WL_HOST_BAND_MGMT
+ if (wl->curr_band == WLC_BAND_2G) {
+ AP6210_DEBUG("In 2G only mode, omit 5G channel:%d\n", channel);
+ continue;
+ }
+#endif /* WL_HOST_BAND_MGMT */
+ chanspec |= WL_CHANSPEC_BAND_5G;
+ }
+
+ chanspec |= WL_CHANSPEC_BW_20;
+ chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+
+ params->channel_list[j] = channel;
+ params->channel_list[j] &= WL_CHANSPEC_CHAN_MASK;
+ params->channel_list[j] |= chanspec;
+ AP6210_DEBUG("Chan : %d, Channel spec: %x \n",
+ channel, params->channel_list[j]);
+ params->channel_list[j] = wl_chspec_host_to_driver(params->channel_list[j]);
+ j++;
+ }
+ } else {
+ AP6210_DEBUG("Scanning all channels\n");
+ }
+ n_channels = j;
+ /* Copy ssid array if applicable */
+ AP6210_DEBUG("### List of SSIDs to scan ###\n");
+ if (n_ssids > 0) {
+ offset = offsetof(wl_scan_params_t, channel_list) + n_channels * sizeof(u16);
+ offset = roundup(offset, sizeof(u32));
+ ptr = (char*)params + offset;
+ for (i = 0; i < n_ssids; i++) {
+ memset(&ssid, 0, sizeof(wlc_ssid_t));
+ ssid.SSID_len = request->ssids[i].ssid_len;
+ memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len);
+ if (!ssid.SSID_len)
+ AP6210_DEBUG("%d: Broadcast scan\n", i);
+ else
+ AP6210_DEBUG("%d: scan for %s size =%d\n", i,
+ ssid.SSID, ssid.SSID_len);
+ memcpy(ptr, &ssid, sizeof(wlc_ssid_t));
+ ptr += sizeof(wlc_ssid_t);
+ }
+ } else {
+ AP6210_DEBUG("Broadcast scan\n");
+ }
+ /* Adding mask to channel numbers */
+ params->channel_num =
+ htod32((n_ssids << WL_SCAN_PARAMS_NSSID_SHIFT) |
+ (n_channels & WL_SCAN_PARAMS_COUNT_MASK));
+
+ if (n_channels == 1 && wl_get_drv_status_all(wl, CONNECTED)) {
+ params->active_time = WL_SCAN_CONNECT_DWELL_TIME_MS;
+ }
+}
+
+static s32
+wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, u16 action)
+{
+ u32 n_channels;
+ u32 n_ssids;
+ s32 params_size =
+ (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
+ struct wl_iscan_params *params = NULL;
+ s32 err = 0;
+
+ if (request != NULL) {
+ n_channels = request->n_channels;
+ n_ssids = request->n_ssids;
+ /* Allocate space for populating ssids in wl_iscan_params struct */
+ if (n_channels % 2)
+ /* If n_channels is odd, add a padd of u16 */
+ params_size += sizeof(u16) * (n_channels + 1);
+ else
+ params_size += sizeof(u16) * n_channels;
+
+ /* Allocate space for populating ssids in wl_iscan_params struct */
+ params_size += sizeof(struct wlc_ssid) * n_ssids;
+ }
+ params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
+ if (!params) {
+ err = -ENOMEM;
+ goto done;
+ }
+ wl_scan_prep(&params->params, request);
+
+ params->version = htod32(ISCAN_REQ_VERSION);
+ params->action = htod16(action);
+ params->scan_duration = htod16(0);
+
+ if (params_size + sizeof("iscan") >= WLC_IOCTL_MEDLEN) {
+ AP6210_ERR("ioctl buffer length is not sufficient\n");
+ err = -ENOMEM;
+ goto done;
+ }
+ err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
+ iscan->ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
+ if (unlikely(err)) {
+ if (err == -EBUSY) {
+ AP6210_ERR("system busy : iscan canceled\n");
+ } else {
+ AP6210_ERR("error (%d)\n", err);
+ }
+ }
+
+done:
+ if (params)
+ kfree(params);
+ return err;
+}
+
+static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request)
+{
+ struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ s32 passive_scan;
+ s32 err = 0;
+
+ iscan->state = WL_ISCAN_STATE_SCANING;
+
+ passive_scan = wl->active_scan ? 0 : 1;
+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+ &passive_scan, sizeof(passive_scan), true);
+ if (unlikely(err)) {
+ AP6210_DEBUG("error (%d)\n", err);
+ return err;
+ }
+ wl->iscan_kickstart = true;
+ wl_run_iscan(iscan, request, WL_SCAN_ACTION_START);
+ mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms));
+ iscan->timer_on = 1;
+
+ return err;
+}
+
+static s32
+wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size)
+{
+ wl_uint32_list_t *list;
+ s32 err = BCME_OK;
+ if (valid_chan_list == NULL || size <= 0)
+ return -ENOMEM;
+
+ memset(valid_chan_list, 0, size);
+ list = (wl_uint32_list_t *)(void *) valid_chan_list;
+ list->count = htod32(WL_NUMCHANNELS);
+ err = wldev_ioctl(ndev, WLC_GET_VALID_CHANNELS, valid_chan_list, size, false);
+ if (err != 0) {
+ AP6210_ERR("get channels failed with %d\n", err);
+ }
+
+ return err;
+}
+
+static s32
+wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
+ struct cfg80211_scan_request *request, uint16 action)
+{
+ s32 err = BCME_OK;
+ u32 n_channels;
+ u32 n_ssids;
+ s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
+ wl_escan_params_t *params = NULL;
+ u8 chan_buf[sizeof(u32)*(WL_NUMCHANNELS + 1)];
+ u32 num_chans = 0;
+ s32 channel;
+ s32 n_valid_chan;
+ s32 search_state = WL_P2P_DISC_ST_SCAN;
+ u32 i, j, n_nodfs = 0;
+ u16 *default_chan_list = NULL;
+ wl_uint32_list_t *list;
+ struct net_device *dev = NULL;
+
+ AP6210_DEBUG("Enter \n");
+
+ if (!wl) {
+ err = -EINVAL;
+ goto exit;
+ }
+ if (!wl->p2p_supported || !p2p_scan(wl)) {
+ /* LEGACY SCAN TRIGGER */
+ AP6210_DEBUG(" LEGACY E-SCAN START\n");
+
+ /* if scan request is not empty parse scan request paramters */
+ if (request != NULL) {
+ n_channels = request->n_channels;
+ n_ssids = request->n_ssids;
+ /* Allocate space for populating ssids in wl_iscan_params struct */
+ if (n_channels % 2)
+ /* If n_channels is odd, add a padd of u16 */
+ params_size += sizeof(u16) * (n_channels + 1);
+ else
+ params_size += sizeof(u16) * n_channels;
+
+ /* Allocate space for populating ssids in wl_iscan_params struct */
+ params_size += sizeof(struct wlc_ssid) * n_ssids;
+ }
+ params = (wl_escan_params_t *) kzalloc(params_size, GFP_KERNEL);
+ if (params == NULL) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ wl_scan_prep(&params->params, request);
+
+ params->version = htod32(ESCAN_REQ_VERSION);
+ params->action = htod16(action);
+ params->sync_id = htod16(0x1234);
+ if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) {
+ AP6210_ERR("ioctl buffer length not sufficient\n");
+ kfree(params);
+ err = -ENOMEM;
+ goto exit;
+ }
+ err = wldev_iovar_setbuf(ndev, "escan", params, params_size,
+ wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
+ if (unlikely(err)) {
+ if (err == BCME_EPERM)
+ /* Scan Not permitted at this point of time */
+ AP6210_DEBUG(" Escan not permitted at this time (%d)\n", err);
+ else
+ AP6210_ERR(" Escan set error (%d)\n", err);
+ }
+ kfree(params);
+ }
+ else if (p2p_is_on(wl) && p2p_scan(wl)) {
+ /* P2P SCAN TRIGGER */
+ s32 _freq = 0;
+ n_nodfs = 0;
+ if (request && request->n_channels) {
+ num_chans = request->n_channels;
+ AP6210_DEBUG(" chann number : %d\n", num_chans);
+ default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
+ GFP_KERNEL);
+ if (default_chan_list == NULL) {
+ AP6210_ERR("channel list allocation failed \n");
+ err = -ENOMEM;
+ goto exit;
+ }
+ if (!wl_get_valid_channels(ndev, chan_buf, sizeof(chan_buf))) {
+ list = (wl_uint32_list_t *) chan_buf;
+ n_valid_chan = dtoh32(list->count);
+ for (i = 0; i < num_chans; i++)
+ {
+#ifdef WL_HOST_BAND_MGMT
+ int channel_band = 0;
+#endif /* WL_HOST_BAND_MGMT */
+ _freq = request->channels[i]->center_freq;
+ channel = ieee80211_frequency_to_channel(_freq);
+#ifdef WL_HOST_BAND_MGMT
+ channel_band = (channel > CH_MAX_2G_CHANNEL) ?
+ WLC_BAND_5G : WLC_BAND_2G;
+ if ((wl->curr_band != WLC_BAND_AUTO) &&
+ (wl->curr_band != channel_band) &&
+ !IS_P2P_SOCIAL_CHANNEL(channel))
+ continue;
+#endif /* WL_HOST_BAND_MGMT */
+
+ /* ignore DFS channels */
+ if (request->channels[i]->flags &
+ (IEEE80211_CHAN_RADAR
+ | IEEE80211_CHAN_PASSIVE_SCAN))
+ continue;
+
+ for (j = 0; j < n_valid_chan; j++) {
+ /* allows only supported channel on
+ * current reguatory
+ */
+ if (channel == (dtoh32(list->element[j])))
+ default_chan_list[n_nodfs++] =
+ channel;
+ }
+
+ }
+ }
+ if (num_chans == 3 && (
+ (default_chan_list[0] == SOCIAL_CHAN_1) &&
+ (default_chan_list[1] == SOCIAL_CHAN_2) &&
+ (default_chan_list[2] == SOCIAL_CHAN_3))) {
+ /* SOCIAL CHANNELS 1, 6, 11 */
+ search_state = WL_P2P_DISC_ST_SEARCH;
+ AP6210_DEBUG("P2P SEARCH PHASE START \n");
+ } else if ((dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)) &&
+ (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP)) {
+ /* If you are already a GO, then do SEARCH only */
+ AP6210_DEBUG("Already a GO. Do SEARCH Only");
+ search_state = WL_P2P_DISC_ST_SEARCH;
+ num_chans = n_nodfs;
+
+ } else {
+ AP6210_DEBUG("P2P SCAN STATE START \n");
+ num_chans = n_nodfs;
+ }
+
+ }
+ err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list,
+ search_state, action,
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ kfree(default_chan_list);
+ }
+exit:
+ if (unlikely(err)) {
+ /* Don't print Error incase of Scan suppress */
+ if ((err == BCME_EPERM) && wl->scan_suppressed)
+ AP6210_DEBUG("Escan failed: Scan Suppressed \n");
+ else
+ AP6210_ERR("error (%d)\n", err);
+ }
+ return err;
+}
+
+
+static s32
+wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request)
+{
+ s32 err = BCME_OK;
+ s32 passive_scan;
+ wl_scan_results_t *results;
+ AP6210_DEBUG("Enter \n");
+ mutex_lock(&wl->usr_sync);
+ results = (wl_scan_results_t *) wl->escan_info.escan_buf;
+ results->version = 0;
+ results->count = 0;
+ results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
+
+ wl->escan_info.ndev = ndev;
+ wl->escan_info.wiphy = wiphy;
+ wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
+ passive_scan = wl->active_scan ? 0 : 1;
+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+ &passive_scan, sizeof(passive_scan), true);
+ if (unlikely(err)) {
+ AP6210_ERR("error (%d)\n", err);
+ goto exit;
+ }
+
+ err = wl_run_escan(wl, ndev, request, WL_SCAN_ACTION_START);
+exit:
+ mutex_unlock(&wl->usr_sync);
+ return err;
+}
+
+static s32
+__wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request,
+ struct cfg80211_ssid *this_ssid)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct cfg80211_ssid *ssids;
+ struct wl_scan_req *sr = wl_to_sr(wl);
+ struct ether_addr primary_mac;
+ s32 passive_scan;
+ bool iscan_req;
+ bool escan_req = false;
+ bool p2p_ssid;
+#ifdef WL11U
+ bcm_tlv_t *interworking_ie;
+ u32 ie_len;
+#endif
+ s32 err = 0;
+ s32 bssidx = -1;
+ s32 i;
+
+ unsigned long flags;
+ static s32 busy_count = 0;
+
+ /* If scan req comes for p2p0, send it over primary I/F
+ * Scan results will be delivered corresponding to cfg80211_scan_request
+ */
+ if (ndev == wl->p2p_net) {
+ ndev = wl_to_prmry_ndev(wl);
+ }
+
+ if (WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl)) {
+ AP6210_ERR("Sending Action Frames. Try it again.\n");
+ return -EAGAIN;
+ }
+
+ AP6210_DEBUG("Enter wiphy (%p)\n", wiphy);
+ if (wl_get_drv_status_all(wl, SCANNING)) {
+ if (wl->scan_request == NULL) {
+ wl_clr_drv_status_all(wl, SCANNING);
+ AP6210_DEBUG("<<<<<<<<<<<Force Clear Scanning Status>>>>>>>>>>>\n");
+ } else {
+ AP6210_ERR("Scanning already\n");
+ return -EAGAIN;
+ }
+ }
+ if (wl_get_drv_status(wl, SCAN_ABORTING, ndev)) {
+ AP6210_ERR("Scanning being aborted\n");
+ return -EAGAIN;
+ }
+ if (request && request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
+ AP6210_ERR("request null or n_ssids > WL_SCAN_PARAMS_SSID_MAX\n");
+ return -EOPNOTSUPP;
+ }
+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL)) {
+ AP6210_DEBUG("Remain_on_channel bit is set, somehow it didn't get cleared\n");
+ wl_notify_escan_complete(wl, ndev, true, true);
+ }
+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+
+ /* Arm scan timeout timer */
+ mod_timer(&wl->scan_timeout, jiffies + msecs_to_jiffies(WL_SCAN_TIMER_INTERVAL_MS));
+ iscan_req = false;
+ if (request) { /* scan bss */
+ ssids = request->ssids;
+ if (wl->iscan_on && (!ssids || !ssids->ssid_len || request->n_ssids != 1)) {
+ iscan_req = true;
+ } else if (wl->escan_on) {
+ escan_req = true;
+ p2p_ssid = false;
+ for (i = 0; i < request->n_ssids; i++) {
+ if (ssids[i].ssid_len &&
+ IS_P2P_SSID(ssids[i].ssid, ssids[i].ssid_len)) {
+ p2p_ssid = true;
+ break;
+ }
+ }
+ if (p2p_ssid) {
+ if (wl->p2p_supported) {
+ /* p2p scan trigger */
+ if (p2p_on(wl) == false) {
+ /* p2p on at the first time */
+ p2p_on(wl) = true;
+ wl_cfgp2p_set_firm_p2p(wl);
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac,
+ &wl->p2p->dev_addr, &wl->p2p->int_addr);
+ }
+ wl_clr_p2p_status(wl, GO_NEG_PHASE);
+ AP6210_DEBUG("P2P: GO_NEG_PHASE status cleared \n");
+ p2p_scan(wl) = true;
+ }
+ } else {
+ /* legacy scan trigger
+ * So, we have to disable p2p discovery if p2p discovery is on
+ */
+ if (wl->p2p_supported) {
+ p2p_scan(wl) = false;
+ /* If Netdevice is not equals to primary and p2p is on
+ * , we will do p2p scan using P2PAPI_BSSCFG_DEVICE.
+ */
+
+ if (p2p_scan(wl) == false) {
+ if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
+ err = wl_cfgp2p_discover_enable_search(wl,
+ false);
+ if (unlikely(err)) {
+ goto scan_out;
+ }
+
+ }
+ }
+ }
+ if (!wl->p2p_supported || !p2p_scan(wl)) {
+ bssidx = wl_cfgp2p_find_idx(wl, ndev);
+
+#ifdef WL11U
+ if ((interworking_ie = wl_cfg80211_find_interworking_ie(
+ (u8 *)request->ie, request->ie_len)) != NULL) {
+ ie_len = interworking_ie->len;
+
+ err = wl_cfg80211_add_iw_ie(wl, ndev, bssidx,
+ VNDR_IE_CUSTOM_FLAG, interworking_ie->id,
+ interworking_ie->data, interworking_ie->len);
+
+ if (unlikely(err)) {
+ goto scan_out;
+ }
+ } else if (wl->iw_ie_len != 0) {
+ /* we have to clear IW IE and disable gratuitous APR */
+ wl_cfg80211_add_iw_ie(wl, ndev, bssidx,
+ VNDR_IE_CUSTOM_FLAG,
+ DOT11_MNG_INTERWORKING_ID,
+ 0, 0);
+
+ wldev_iovar_setint_bsscfg(ndev, "grat_arp", 0,
+ bssidx);
+ /* we don't care about error */
+ }
+#endif /* WL11U */
+ err = wl_cfgp2p_set_management_ie(wl, ndev, bssidx,
+ VNDR_IE_PRBREQ_FLAG, (u8 *)request->ie,
+ request->ie_len);
+
+ if (unlikely(err)) {
+ goto scan_out;
+ }
+
+ }
+ }
+ }
+ } else { /* scan in ibss */
+ /* we don't do iscan in ibss */
+ ssids = this_ssid;
+ }
+ wl->scan_request = request;
+ wl_set_drv_status(wl, SCANNING, ndev);
+ if (iscan_req) {
+ err = wl_do_iscan(wl, request);
+ if (likely(!err))
+ goto scan_success;
+ else
+ goto scan_out;
+ } else if (escan_req) {
+ if (wl->p2p_supported) {
+ if (p2p_on(wl) && p2p_scan(wl)) {
+
+ /* find my listen channel */
+ wl->afx_hdl->my_listen_chan =
+ wl_find_listen_channel(wl, (u8 *)request->ie,
+ request->ie_len);
+ err = wl_cfgp2p_enable_discovery(wl, ndev,
+ request->ie, request->ie_len);
+
+ if (unlikely(err)) {
+ goto scan_out;
+ }
+ }
+ }
+ err = wl_do_escan(wl, wiphy, ndev, request);
+ if (likely(!err))
+ goto scan_success;
+ else
+ goto scan_out;
+
+
+ } else {
+ memset(&sr->ssid, 0, sizeof(sr->ssid));
+ sr->ssid.SSID_len =
+ min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
+ if (sr->ssid.SSID_len) {
+ memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
+ sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
+ AP6210_DEBUG("Specific scan ssid=\"%s\" len=%d\n",
+ sr->ssid.SSID, sr->ssid.SSID_len);
+ } else {
+ AP6210_DEBUG("Broadcast scan\n");
+ }
+ AP6210_DEBUG("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len);
+ passive_scan = wl->active_scan ? 0 : 1;
+ err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+ &passive_scan, sizeof(passive_scan), true);
+ if (unlikely(err)) {
+ AP6210_DEBUG("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
+ goto scan_out;
+ }
+ err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
+ sizeof(sr->ssid), false);
+ if (err) {
+ if (err == -EBUSY) {
+ AP6210_ERR("system busy : scan for \"%s\" "
+ "canceled\n", sr->ssid.SSID);
+ } else {
+ AP6210_ERR("WLC_SCAN error (%d)\n", err);
+ }
+ goto scan_out;
+ }
+ }
+
+scan_success:
+
+ busy_count = 0;
+
+ return 0;
+
+scan_out:
+
+ if (err == BCME_BUSY || err == BCME_NOTREADY) {
+ AP6210_ERR("Scan err = (%d), busy?%d", err, -EBUSY);
+ err = -EBUSY;
+ }
+
+#define SCAN_EBUSY_RETRY_LIMIT 10
+ if (err == -EBUSY) {
+ if (busy_count++ > SCAN_EBUSY_RETRY_LIMIT) {
+ struct ether_addr bssid;
+ s32 ret = 0;
+ busy_count = 0;
+ AP6210_ERR("Unusual continuous EBUSY error, %d %d %d %d %d %d %d %d %d\n",
+ wl_get_drv_status(wl, SCANNING, ndev),
+ wl_get_drv_status(wl, SCAN_ABORTING, ndev),
+ wl_get_drv_status(wl, CONNECTING, ndev),
+ wl_get_drv_status(wl, CONNECTED, ndev),
+ wl_get_drv_status(wl, DISCONNECTING, ndev),
+ wl_get_drv_status(wl, AP_CREATING, ndev),
+ wl_get_drv_status(wl, AP_CREATED, ndev),
+ wl_get_drv_status(wl, SENDING_ACT_FRM, ndev),
+ wl_get_drv_status(wl, SENDING_ACT_FRM, ndev));
+
+ bzero(&bssid, sizeof(bssid));
+ if ((ret = wldev_ioctl(ndev, WLC_GET_BSSID,
+ &bssid, ETHER_ADDR_LEN, false)) == 0)
+ AP6210_ERR("FW is connected with " MACDBG "/n",
+ MAC2STRDBG(bssid.octet));
+ else
+ AP6210_ERR("GET BSSID failed with %d\n", ret);
+
+ wl_cfg80211_disconnect(wiphy, ndev, DOT11_RC_DISASSOC_LEAVING);
+ }
+ } else {
+ busy_count = 0;
+ }
+ wl_clr_drv_status(wl, SCANNING, ndev);
+ if (timer_pending(&wl->scan_timeout))
+ del_timer_sync(&wl->scan_timeout);
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ wl->scan_request = NULL;
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+ return err;
+}
+
+static s32
+wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request)
+{
+ s32 err = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+
+ AP6210_DEBUG("Enter \n");
+ CHECK_SYS_UP(wl);
+
+ err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
+ if (unlikely(err)) {
+ if ((err == BCME_EPERM) && wl->scan_suppressed)
+ AP6210_DEBUG("scan not permitted at this time (%d)\n", err);
+ else
+ AP6210_ERR("scan error (%d)\n", err);
+ return err;
+ }
+
+ return err;
+}
+
+static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
+{
+ s32 err = 0;
+
+ err = wldev_iovar_setint(dev, "rtsthresh", rts_threshold);
+ if (unlikely(err)) {
+ AP6210_ERR("Error (%d)\n", err);
+ return err;
+ }
+ return err;
+}
+
+static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
+{
+ s32 err = 0;
+
+ err = wldev_iovar_setint_bsscfg(dev, "fragthresh", frag_threshold, 0);
+ if (unlikely(err)) {
+ AP6210_ERR("Error (%d)\n", err);
+ return err;
+ }
+ return err;
+}
+
+static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
+{
+ s32 err = 0;
+ u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
+
+ retry = htod32(retry);
+ err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), true);
+ if (unlikely(err)) {
+ AP6210_ERR("cmd (%d) , error (%d)\n", cmd, err);
+ return err;
+ }
+ return err;
+}
+
+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+ struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ s32 err = 0;
+
+ CHECK_SYS_UP(wl);
+ AP6210_DEBUG("Enter\n");
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
+ (wl->conf->rts_threshold != wiphy->rts_threshold)) {
+ wl->conf->rts_threshold = wiphy->rts_threshold;
+ err = wl_set_rts(ndev, wl->conf->rts_threshold);
+ if (!err)
+ return err;
+ }
+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
+ (wl->conf->frag_threshold != wiphy->frag_threshold)) {
+ wl->conf->frag_threshold = wiphy->frag_threshold;
+ err = wl_set_frag(ndev, wl->conf->frag_threshold);
+ if (!err)
+ return err;
+ }
+ if (changed & WIPHY_PARAM_RETRY_LONG &&
+ (wl->conf->retry_long != wiphy->retry_long)) {
+ wl->conf->retry_long = wiphy->retry_long;
+ err = wl_set_retry(ndev, wl->conf->retry_long, true);
+ if (!err)
+ return err;
+ }
+ if (changed & WIPHY_PARAM_RETRY_SHORT &&
+ (wl->conf->retry_short != wiphy->retry_short)) {
+ wl->conf->retry_short = wiphy->retry_short;
+ err = wl_set_retry(ndev, wl->conf->retry_short, false);
+ if (!err) {
+ return err;
+ }
+ }
+
+ return err;
+}
+
+static s32
+wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ibss_params *params)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct cfg80211_bss *bss;
+ struct ieee80211_channel *chan;
+ struct wl_join_params join_params;
+ struct cfg80211_ssid ssid;
+ s32 scan_retry = 0;
+ s32 err = 0;
+ bool rollback_lock = false;
+
+ AP6210_DEBUG("In\n");
+ CHECK_SYS_UP(wl);
+ if (params->bssid) {
+ AP6210_ERR("Invalid bssid\n");
+ return -EOPNOTSUPP;
+ }
+ bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
+ if (!bss) {
+ memcpy(ssid.ssid, params->ssid, params->ssid_len);
+ ssid.ssid_len = params->ssid_len;
+ do {
+ if (unlikely
+ (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
+ -EBUSY)) {
+ wl_delay(150);
+ } else {
+ break;
+ }
+ } while (++scan_retry < WL_SCAN_RETRY_MAX);
+ /* to allow scan_inform to propagate to cfg80211 plane */
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
+
+ /* wait 4 secons till scan done.... */
+ schedule_timeout_interruptible(msecs_to_jiffies(4000));
+ if (rollback_lock)
+ rtnl_lock();
+ bss = cfg80211_get_ibss(wiphy, NULL,
+ params->ssid, params->ssid_len);
+ }
+ if (bss) {
+ wl->ibss_starter = false;
+ AP6210_DEBUG("Found IBSS\n");
+ } else {
+ wl->ibss_starter = true;
+ }
+ chan = params->channel;
+ if (chan)
+ wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
+ /*
+ * Join with specific BSSID and cached SSID
+ * If SSID is zero join based on BSSID only
+ */
+ memset(&join_params, 0, sizeof(join_params));
+ memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
+ params->ssid_len);
+ join_params.ssid.SSID_len = htod32(params->ssid_len);
+ if (params->bssid)
+ memcpy(&join_params.params.bssid, params->bssid,
+ ETHER_ADDR_LEN);
+ else
+ memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
+
+ err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
+ sizeof(join_params), true);
+ if (unlikely(err)) {
+ AP6210_ERR("Error (%d)\n", err);
+ return err;
+ }
+ return err;
+}
+
+static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ s32 err = 0;
+
+ CHECK_SYS_UP(wl);
+ wl_link_down(wl);
+
+ return err;
+}
+
+static s32
+wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct wl_security *sec;
+ s32 val = 0;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
+ val = WPA_AUTH_PSK |
+ WPA_AUTH_UNSPECIFIED;
+ else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
+ val = WPA2_AUTH_PSK|
+ WPA2_AUTH_UNSPECIFIED;
+ else
+ val = WPA_AUTH_DISABLED;
+
+ if (is_wps_conn(sme))
+ val = WPA_AUTH_DISABLED;
+
+#ifdef BCMWAPI_WPI
+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
+ AP6210_DEBUG(" * wl_set_wpa_version, set wpa_auth"
+ " to WPA_AUTH_WAPI 0x400");
+ val = WAPI_AUTH_PSK; /* | WAPI_AUTH_UNSPECIFIED; */
+ }
+#endif
+ AP6210_DEBUG("setting wpa_auth to 0x%0x\n", val);
+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
+ if (unlikely(err)) {
+ AP6210_ERR("set wpa_auth failed (%d)\n", err);
+ return err;
+ }
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
+ sec->wpa_versions = sme->crypto.wpa_versions;
+ return err;
+}
+
+#ifdef BCMWAPI_WPI
+static s32
+wl_set_set_wapi_ie(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ AP6210_DEBUG(" %s \n", __FUNCTION__);
+
+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
+ err = wldev_iovar_setbuf_bsscfg(dev, "wapiie", sme->ie,
+ sme->ie_len, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ if (unlikely(err)) {
+ AP6210_ERR("===> set_wapi_ie Error (%d)\n", err);
+ return err;
+ }
+ } else
+ AP6210_DEBUG(" * skip \n");
+ return err;
+}
+#endif /* BCMWAPI_WPI */
+
+static s32
+wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct wl_security *sec;
+ s32 val = 0;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+ switch (sme->auth_type) {
+ case NL80211_AUTHTYPE_OPEN_SYSTEM:
+ val = WL_AUTH_OPEN_SYSTEM;
+ AP6210_DEBUG("open system\n");
+ break;
+ case NL80211_AUTHTYPE_SHARED_KEY:
+ val = WL_AUTH_SHARED_KEY;
+ AP6210_DEBUG("shared key\n");
+ break;
+ case NL80211_AUTHTYPE_AUTOMATIC:
+ val = WL_AUTH_OPEN_SHARED;
+ AP6210_DEBUG("automatic\n");
+ break;
+ default:
+ val = WL_AUTH_OPEN_SHARED;
+ AP6210_ERR("invalid auth type (%d)\n", sme->auth_type);
+ break;
+ }
+
+ err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
+ if (unlikely(err)) {
+ AP6210_ERR("set auth failed (%d)\n", err);
+ return err;
+ }
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
+ sec->auth_type = sme->auth_type;
+ return err;
+}
+
+static s32
+wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct wl_security *sec;
+ s32 pval = 0;
+ s32 gval = 0;
+ s32 err = 0;
+#ifdef BCMWAPI_WPI
+ s32 val = 0;
+#endif
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ if (sme->crypto.n_ciphers_pairwise) {
+ switch (sme->crypto.ciphers_pairwise[0]) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ pval = WEP_ENABLED;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ pval = TKIP_ENABLED;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ pval = AES_ENABLED;
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ pval = AES_ENABLED;
+ break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ val = SMS4_ENABLED;
+ pval = SMS4_ENABLED;
+ break;
+#endif
+ default:
+ AP6210_ERR("invalid cipher pairwise (%d)\n",
+ sme->crypto.ciphers_pairwise[0]);
+ return -EINVAL;
+ }
+ }
+ if (sme->crypto.cipher_group) {
+ switch (sme->crypto.cipher_group) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ gval = WEP_ENABLED;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ gval = TKIP_ENABLED;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ gval = AES_ENABLED;
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ gval = AES_ENABLED;
+ break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ val = SMS4_ENABLED;
+ gval = SMS4_ENABLED;
+ break;
+#endif
+ default:
+ AP6210_ERR("invalid cipher group (%d)\n",
+ sme->crypto.cipher_group);
+ return -EINVAL;
+ }
+ }
+
+ AP6210_DEBUG("pval (%d) gval (%d)\n", pval, gval);
+
+ if (is_wps_conn(sme)) {
+ if (sme->privacy)
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
+#ifdef BCMWAPI_WPI
+ else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_SMS4) {
+ AP6210_DEBUG(" NO, is_wps_conn, WAPI set to SMS4_ENABLED");
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", val, bssidx);
+ }
+#endif
+ else
+ /* WPS-2.0 allows no security */
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx);
+ } else {
+ AP6210_DEBUG(" NO, is_wps_conn, Set pval | gval to WSEC");
+ err = wldev_iovar_setint_bsscfg(dev, "wsec",
+ pval | gval, bssidx);
+ }
+ if (unlikely(err)) {
+ AP6210_ERR("error (%d)\n", err);
+ return err;
+ }
+
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
+ sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
+ sec->cipher_group = sme->crypto.cipher_group;
+
+ return err;
+}
+
+static s32
+wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct wl_security *sec;
+ s32 val = 0;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ if (sme->crypto.n_akm_suites) {
+ err = wldev_iovar_getint(dev, "wpa_auth", &val);
+ if (unlikely(err)) {
+ AP6210_ERR("could not get wpa_auth (%d)\n", err);
+ return err;
+ }
+ if (val & (WPA_AUTH_PSK |
+ WPA_AUTH_UNSPECIFIED)) {
+ switch (sme->crypto.akm_suites[0]) {
+ case WLAN_AKM_SUITE_8021X:
+ val = WPA_AUTH_UNSPECIFIED;
+ break;
+ case WLAN_AKM_SUITE_PSK:
+ val = WPA_AUTH_PSK;
+ break;
+ default:
+ AP6210_ERR("invalid cipher group (%d)\n",
+ sme->crypto.cipher_group);
+ return -EINVAL;
+ }
+ } else if (val & (WPA2_AUTH_PSK |
+ WPA2_AUTH_UNSPECIFIED)) {
+ switch (sme->crypto.akm_suites[0]) {
+ case WLAN_AKM_SUITE_8021X:
+ val = WPA2_AUTH_UNSPECIFIED;
+ break;
+ case WLAN_AKM_SUITE_PSK:
+ val = WPA2_AUTH_PSK;
+ break;
+ default:
+ AP6210_ERR("invalid cipher group (%d)\n",
+ sme->crypto.cipher_group);
+ return -EINVAL;
+ }
+ }
+#ifdef BCMWAPI_WPI
+ else if (val & (WAPI_AUTH_PSK | WAPI_AUTH_UNSPECIFIED)) {
+ switch (sme->crypto.akm_suites[0]) {
+ case WLAN_AKM_SUITE_WAPI_CERT:
+ val = WAPI_AUTH_UNSPECIFIED;
+ break;
+ case WLAN_AKM_SUITE_WAPI_PSK:
+ val = WAPI_AUTH_PSK;
+ break;
+ default:
+ AP6210_ERR("invalid cipher group (%d)\n",
+ sme->crypto.cipher_group);
+ return -EINVAL;
+ }
+ }
+#endif
+ AP6210_DEBUG("setting wpa_auth to %d\n", val);
+
+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
+ if (unlikely(err)) {
+ AP6210_ERR("could not set wpa_auth (%d)\n", err);
+ return err;
+ }
+ }
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
+ sec->wpa_auth = sme->crypto.akm_suites[0];
+
+ return err;
+}
+
+static s32
+wl_set_set_sharedkey(struct net_device *dev,
+ struct cfg80211_connect_params *sme)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct wl_security *sec;
+ struct wl_wsec_key key;
+ s32 val;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ AP6210_DEBUG("key len (%d)\n", sme->key_len);
+ if (sme->key_len) {
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
+ AP6210_DEBUG("wpa_versions 0x%x cipher_pairwise 0x%x\n",
+ sec->wpa_versions, sec->cipher_pairwise);
+ if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 |
+ NL80211_WPA_VERSION_2
+#ifdef BCMWAPI_WPI
+ | NL80211_WAPI_VERSION_1
+#endif
+ )) &&
+ (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
+ WLAN_CIPHER_SUITE_WEP104
+#ifdef BCMWAPI_WPI
+ | WLAN_CIPHER_SUITE_SMS4
+#endif
+ )))
+ {
+ memset(&key, 0, sizeof(key));
+ key.len = (u32) sme->key_len;
+ key.index = (u32) sme->key_idx;
+ if (unlikely(key.len > sizeof(key.data))) {
+ AP6210_ERR("Too long key length (%u)\n", key.len);
+ return -EINVAL;
+ }
+ memcpy(key.data, sme->key, key.len);
+ key.flags = WL_PRIMARY_KEY;
+ switch (sec->cipher_pairwise) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ key.algo = CRYPTO_ALGO_WEP1;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ key.algo = CRYPTO_ALGO_WEP128;
+ break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ key.algo = CRYPTO_ALGO_SMS4;
+ break;
+#endif
+ default:
+ AP6210_ERR("Invalid algorithm (%d)\n",
+ sme->crypto.ciphers_pairwise[0]);
+ return -EINVAL;
+ }
+ /* Set the new key/index */
+ AP6210_DEBUG("key length (%d) key index (%d) algo (%d)\n",
+ key.len, key.index, key.algo);
+ AP6210_DEBUG("key \"%s\"\n", key.data);
+ swap_key_from_BE(&key);
+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_SET_KEY error (%d)\n", err);
+ return err;
+ }
+ if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
+ AP6210_DEBUG("set auth_type to shared key\n");
+ val = WL_AUTH_SHARED_KEY; /* shared key */
+ err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
+ if (unlikely(err)) {
+ AP6210_ERR("set auth failed (%d)\n", err);
+ return err;
+ }
+ }
+ }
+ }
+ return err;
+}
+
+#ifdef ESCAN_RESULT_PATCH
+static u8 connect_req_bssid[6];
+static u8 broad_bssid[6];
+#endif
+
+
+static s32
+wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_connect_params *sme)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct ieee80211_channel *chan = sme->channel;
+ wl_extjoin_params_t *ext_join_params;
+ struct wl_join_params join_params;
+ size_t join_params_size;
+ s32 err = 0;
+ wpa_ie_fixed_t *wpa_ie;
+ bcm_tlv_t *wpa2_ie;
+ u8* wpaie = 0;
+ u32 wpaie_len = 0;
+ u32 chan_cnt = 0;
+ struct ether_addr bssid;
+ int ret;
+
+ AP6210_DEBUG("In\n");
+
+ if (unlikely(!sme->ssid)) {
+ AP6210_ERR("Invalid ssid\n");
+ return -EOPNOTSUPP;
+ }
+
+ CHECK_SYS_UP(wl);
+
+ /*
+ * Cancel ongoing scan to sync up with sme state machine of cfg80211.
+ */
+#if !defined(ESCAN_RESULT_PATCH)
+ if (wl->scan_request) {
+ wl_notify_escan_complete(wl, dev, true, true);
+ }
+#endif
+#ifdef ESCAN_RESULT_PATCH
+ if (sme->bssid) {
+ memcpy(connect_req_bssid, sme->bssid, ETHER_ADDR_LEN);
+ }
+ else {
+ bzero(connect_req_bssid, ETHER_ADDR_LEN);
+ }
+ bzero(broad_bssid, ETHER_ADDR_LEN);
+#endif
+
+ bzero(&bssid, sizeof(bssid));
+ if (!wl_get_drv_status(wl, CONNECTED, dev)&&
+ (ret = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false)) == 0) {
+ if (!ETHER_ISNULLADDR(&bssid)) {
+ scb_val_t scbval;
+ wl_set_drv_status(wl, DISCONNECTING, dev);
+ scbval.val = DOT11_RC_DISASSOC_LEAVING;
+ memcpy(&scbval.ea, &bssid, ETHER_ADDR_LEN);
+ scbval.val = htod32(scbval.val);
+
+ AP6210_DEBUG("drv status CONNECTED is not set, but connected in FW!" MACDBG "\n",
+ MAC2STRDBG(bssid.octet));
+ err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
+ sizeof(scb_val_t), true);
+ if (unlikely(err)) {
+ wl_clr_drv_status(wl, DISCONNECTING, dev);
+ AP6210_ERR("error (%d)\n", err);
+ return err;
+ }
+ while (wl_get_drv_status(wl, DISCONNECTING, dev)) {
+ AP6210_ERR("Waiting for disconnection terminated.\n");
+ msleep(20);
+ }
+ } else
+ AP6210_DEBUG("Currently not associated!\n");
+ }
+
+ /* Clean BSSID */
+ bzero(&bssid, sizeof(bssid));
+ if (!wl_get_drv_status(wl, DISCONNECTING, dev))
+ wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
+
+ if (p2p_is_on(wl) && (dev != wl_to_prmry_ndev(wl))) {
+ /* we only allow to connect using virtual interface in case of P2P */
+ wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
+ VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
+ } else if (dev == wl_to_prmry_ndev(wl)) {
+ /* find the RSN_IE */
+ if ((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len,
+ DOT11_MNG_RSN_ID)) != NULL) {
+ AP6210_DEBUG(" WPA2 IE is found\n");
+ }
+ /* find the WPA_IE */
+ if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)sme->ie,
+ sme->ie_len)) != NULL) {
+ AP6210_DEBUG(" WPA IE is found\n");
+ }
+ if (wpa_ie != NULL || wpa2_ie != NULL) {
+ wpaie = (wpa_ie != NULL) ? (u8 *)wpa_ie : (u8 *)wpa2_ie;
+ wpaie_len = (wpa_ie != NULL) ? wpa_ie->length : wpa2_ie->len;
+ wpaie_len += WPA_RSN_IE_TAG_FIXED_LEN;
+ wldev_iovar_setbuf(dev, "wpaie", wpaie, wpaie_len,
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ } else {
+ wldev_iovar_setbuf(dev, "wpaie", NULL, 0,
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ }
+
+ err = wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
+ VNDR_IE_ASSOCREQ_FLAG, (u8 *)sme->ie, sme->ie_len);
+ if (unlikely(err)) {
+ return err;
+ }
+ }
+
+ if (chan) {
+ wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
+ chan_cnt = 1;
+ AP6210_DEBUG("channel (%d), center_req (%d), %d channels\n", wl->channel,
+ chan->center_freq, chan_cnt);
+ } else
+ wl->channel = 0;
+
+#ifdef BCMWAPI_WPI
+ AP6210_DEBUG("1. enable wapi auth\n");
+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
+ AP6210_DEBUG("2. set wapi ie \n");
+ err = wl_set_set_wapi_ie(dev, sme);
+ if (unlikely(err))
+ return err;
+ } else
+ AP6210_DEBUG("2. Not wapi ie \n");
+#endif
+ AP6210_DEBUG("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
+ AP6210_DEBUG("3. set wapi version \n");
+ err = wl_set_wpa_version(dev, sme);
+ if (unlikely(err)) {
+ AP6210_ERR("Invalid wpa_version\n");
+ return err;
+ }
+#ifdef BCMWAPI_WPI
+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
+ AP6210_DEBUG("4. WAPI Dont Set wl_set_auth_type\n");
+ else {
+ AP6210_DEBUG("4. wl_set_auth_type\n");
+#endif
+ err = wl_set_auth_type(dev, sme);
+ if (unlikely(err)) {
+ AP6210_ERR("Invalid auth type\n");
+ return err;
+ }
+#ifdef BCMWAPI_WPI
+
+ }
+#endif
+
+ err = wl_set_set_cipher(dev, sme);
+ if (unlikely(err)) {
+ AP6210_ERR("Invalid ciper\n");
+ return err;
+ }
+
+ err = wl_set_key_mgmt(dev, sme);
+ if (unlikely(err)) {
+ AP6210_ERR("Invalid key mgmt\n");
+ return err;
+ }
+
+ err = wl_set_set_sharedkey(dev, sme);
+ if (unlikely(err)) {
+ AP6210_ERR("Invalid shared key\n");
+ return err;
+ }
+
+ /*
+ * Join with specific BSSID and cached SSID
+ * If SSID is zero join based on BSSID only
+ */
+ join_params_size = WL_EXTJOIN_PARAMS_FIXED_SIZE +
+ chan_cnt * sizeof(chanspec_t);
+ ext_join_params = (wl_extjoin_params_t*)kzalloc(join_params_size, GFP_KERNEL);
+ if (ext_join_params == NULL) {
+ err = -ENOMEM;
+ wl_clr_drv_status(wl, CONNECTING, dev);
+ goto exit;
+ }
+ ext_join_params->ssid.SSID_len = min(sizeof(ext_join_params->ssid.SSID), sme->ssid_len);
+ memcpy(&ext_join_params->ssid.SSID, sme->ssid, ext_join_params->ssid.SSID_len);
+ wl_update_prof(wl, dev, NULL, &ext_join_params->ssid, WL_PROF_SSID);
+ ext_join_params->ssid.SSID_len = htod32(ext_join_params->ssid.SSID_len);
+ /* increate dwell time to receive probe response or detect Beacon
+ * from target AP at a noisy air only during connect command
+ */
+ ext_join_params->scan.active_time = WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS;
+ ext_join_params->scan.passive_time = WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS;
+ /* Set up join scan parameters */
+ ext_join_params->scan.scan_type = -1;
+ ext_join_params->scan.nprobes
+ = (ext_join_params->scan.active_time/WL_SCAN_JOIN_PROBE_INTERVAL_MS);
+ ext_join_params->scan.home_time = -1;
+
+ if (sme->bssid)
+ memcpy(&ext_join_params->assoc.bssid, sme->bssid, ETH_ALEN);
+ else
+ memcpy(&ext_join_params->assoc.bssid, &ether_bcast, ETH_ALEN);
+ ext_join_params->assoc.chanspec_num = chan_cnt;
+ if (chan_cnt) {
+ u16 channel, band, bw, ctl_sb;
+ chanspec_t chspec;
+ channel = wl->channel;
+ band = (channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G
+ : WL_CHANSPEC_BAND_5G;
+ bw = WL_CHANSPEC_BW_20;
+ ctl_sb = WL_CHANSPEC_CTL_SB_NONE;
+ chspec = (channel | band | bw | ctl_sb);
+ ext_join_params->assoc.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
+ ext_join_params->assoc.chanspec_list[0] |= chspec;
+ ext_join_params->assoc.chanspec_list[0] =
+ wl_chspec_host_to_driver(ext_join_params->assoc.chanspec_list[0]);
+ }
+ ext_join_params->assoc.chanspec_num = htod32(ext_join_params->assoc.chanspec_num);
+ if (ext_join_params->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
+ AP6210_DEBUG("ssid \"%s\", len (%d)\n", ext_join_params->ssid.SSID,
+ ext_join_params->ssid.SSID_len);
+ }
+ wl_set_drv_status(wl, CONNECTING, dev);
+ err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size,
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, wl_cfgp2p_find_idx(wl, dev), &wl->ioctl_buf_sync);
+ kfree(ext_join_params);
+ if (err) {
+ wl_clr_drv_status(wl, CONNECTING, dev);
+ if (err == BCME_UNSUPPORTED) {
+ AP6210_DEBUG("join iovar is not supported\n");
+ goto set_ssid;
+ } else
+ AP6210_ERR("error (%d)\n", err);
+ } else
+ goto exit;
+
+set_ssid:
+ memset(&join_params, 0, sizeof(join_params));
+ join_params_size = sizeof(join_params.ssid);
+
+ join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
+ memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
+ join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
+ wl_update_prof(wl, dev, NULL, &join_params.ssid, WL_PROF_SSID);
+ if (sme->bssid)
+ memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN);
+ else
+ memcpy(&join_params.params.bssid, &ether_bcast, ETH_ALEN);
+
+ wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
+ AP6210_DEBUG("join_param_size %d\n", join_params_size);
+
+ if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
+ AP6210_DEBUG("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
+ join_params.ssid.SSID_len);
+ }
+ wl_set_drv_status(wl, CONNECTING, dev);
+ err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true);
+ if (err) {
+ AP6210_ERR("error (%d)\n", err);
+ wl_clr_drv_status(wl, CONNECTING, dev);
+ }
+exit:
+ return err;
+}
+
+static s32
+wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+ u16 reason_code)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ scb_val_t scbval;
+ bool act = false;
+ s32 err = 0;
+ u8 *curbssid;
+ AP6210_ERR("Reason %d\n", reason_code);
+ CHECK_SYS_UP(wl);
+ act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT);
+ curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID);
+ if (act) {
+ /*
+ * Cancel ongoing scan to sync up with sme state machine of cfg80211.
+ */
+#if !defined(ESCAN_RESULT_PATCH)
+ /* Let scan aborted by F/W */
+ if (wl->scan_request) {
+ wl_notify_escan_complete(wl, dev, true, true);
+ }
+#endif /* ESCAN_RESULT_PATCH */
+ wl_set_drv_status(wl, DISCONNECTING, dev);
+ scbval.val = reason_code;
+ memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
+ scbval.val = htod32(scbval.val);
+ err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
+ sizeof(scb_val_t), true);
+ if (unlikely(err)) {
+ wl_clr_drv_status(wl, DISCONNECTING, dev);
+ AP6210_ERR("error (%d)\n", err);
+ return err;
+ }
+ }
+
+ return err;
+}
+
+static s32
+wl_cfg80211_set_tx_power(struct wiphy *wiphy,
+ enum nl80211_tx_power_setting type, s32 dbm)
+{
+
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ u16 txpwrmw;
+ s32 err = 0;
+ s32 disable = 0;
+
+ CHECK_SYS_UP(wl);
+ switch (type) {
+ case NL80211_TX_POWER_AUTOMATIC:
+ break;
+ case NL80211_TX_POWER_LIMITED:
+ if (dbm < 0) {
+ AP6210_ERR("TX_POWER_LIMITTED - dbm is negative\n");
+ return -EINVAL;
+ }
+ break;
+ case NL80211_TX_POWER_FIXED:
+ if (dbm < 0) {
+ AP6210_ERR("TX_POWER_FIXED - dbm is negative..\n");
+ return -EINVAL;
+ }
+ break;
+ }
+ /* Make sure radio is off or on as far as software is concerned */
+ disable = WL_RADIO_SW_DISABLE << 16;
+ disable = htod32(disable);
+ err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), true);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_SET_RADIO error (%d)\n", err);
+ return err;
+ }
+
+ if (dbm > 0xffff)
+ txpwrmw = 0xffff;
+ else
+ txpwrmw = (u16) dbm;
+ err = wldev_iovar_setint(ndev, "qtxpower",
+ (s32) (bcm_mw_to_qdbm(txpwrmw)));
+ if (unlikely(err)) {
+ AP6210_ERR("qtxpower error (%d)\n", err);
+ return err;
+ }
+ wl->conf->tx_power = dbm;
+
+ return err;
+}
+
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ s32 txpwrdbm;
+ u8 result;
+ s32 err = 0;
+
+ CHECK_SYS_UP(wl);
+ err = wldev_iovar_getint(ndev, "qtxpower", &txpwrdbm);
+ if (unlikely(err)) {
+ AP6210_ERR("error (%d)\n", err);
+ return err;
+ }
+ result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
+ *dbm = (s32) bcm_qdbm_to_mw(result);
+
+ return err;
+}
+
+static s32
+wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, bool unicast, bool multicast)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ u32 index;
+ s32 wsec;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ AP6210_DEBUG("key index (%d)\n", key_idx);
+ CHECK_SYS_UP(wl);
+ err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_GET_WSEC error (%d)\n", err);
+ return err;
+ }
+ if (wsec & WEP_ENABLED) {
+ /* Just select a new current key */
+ index = (u32) key_idx;
+ index = htod32(index);
+ err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
+ sizeof(index), true);
+ if (unlikely(err)) {
+ AP6210_ERR("error (%d)\n", err);
+ }
+ }
+ return err;
+}
+
+static s32
+wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, const u8 *mac_addr, struct key_params *params)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct wl_wsec_key key;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+ s32 mode = wl_get_mode_by_netdev(wl, dev);
+ memset(&key, 0, sizeof(key));
+ key.index = (u32) key_idx;
+
+ if (!ETHER_ISMULTI(mac_addr))
+ memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
+ key.len = (u32) params->key_len;
+
+ /* check for key index change */
+ if (key.len == 0) {
+ /* key delete */
+ swap_key_from_BE(&key);
+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ if (unlikely(err)) {
+ AP6210_ERR("key delete error (%d)\n", err);
+ return err;
+ }
+ } else {
+ if (key.len > sizeof(key.data)) {
+ AP6210_ERR("Invalid key length (%d)\n", key.len);
+ return -EINVAL;
+ }
+ AP6210_DEBUG("Setting the key index %d\n", key.index);
+ memcpy(key.data, params->key, key.len);
+
+ if ((mode == WL_MODE_BSS) &&
+ (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
+ u8 keybuf[8];
+ memcpy(keybuf, &key.data[24], sizeof(keybuf));
+ memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+ memcpy(&key.data[16], keybuf, sizeof(keybuf));
+ }
+
+ /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
+ if (params->seq && params->seq_len == 6) {
+ /* rx iv */
+ u8 *ivptr;
+ ivptr = (u8 *) params->seq;
+ key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
+ (ivptr[3] << 8) | ivptr[2];
+ key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
+ key.iv_initialized = true;
+ }
+
+ switch (params->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ key.algo = CRYPTO_ALGO_WEP1;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP40\n");
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ key.algo = CRYPTO_ALGO_WEP128;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP104\n");
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ key.algo = CRYPTO_ALGO_TKIP;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_TKIP\n");
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ key.algo = CRYPTO_ALGO_AES_CCM;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_AES_CMAC\n");
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ key.algo = CRYPTO_ALGO_AES_CCM;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_CCMP\n");
+ break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ key.algo = CRYPTO_ALGO_SMS4;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_SMS4\n");
+ break;
+#endif
+ default:
+ AP6210_ERR("Invalid cipher (0x%x)\n", params->cipher);
+ return -EINVAL;
+ }
+ swap_key_from_BE(&key);
+ /* need to guarantee EAPOL 4/4 send out before set key */
+ dhd_wait_pend8021x(dev);
+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_SET_KEY error (%d)\n", err);
+ return err;
+ }
+ }
+ return err;
+}
+
+static s32
+wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, bool pairwise, const u8 *mac_addr,
+ struct key_params *params)
+{
+ struct wl_wsec_key key;
+ s32 val = 0;
+ s32 wsec = 0;
+ s32 err = 0;
+ u8 keybuf[8];
+ s32 bssidx = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ s32 mode = wl_get_mode_by_netdev(wl, dev);
+ AP6210_DEBUG("key index (%d)\n", key_idx);
+ CHECK_SYS_UP(wl);
+
+ bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ if (mac_addr) {
+ wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
+ goto exit;
+ }
+ memset(&key, 0, sizeof(key));
+
+ key.len = (u32) params->key_len;
+ key.index = (u32) key_idx;
+
+ if (unlikely(key.len > sizeof(key.data))) {
+ AP6210_ERR("Too long key length (%u)\n", key.len);
+ return -EINVAL;
+ }
+ memcpy(key.data, params->key, key.len);
+
+ key.flags = WL_PRIMARY_KEY;
+ switch (params->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ key.algo = CRYPTO_ALGO_WEP1;
+ val = WEP_ENABLED;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP40\n");
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ key.algo = CRYPTO_ALGO_WEP128;
+ val = WEP_ENABLED;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP104\n");
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ key.algo = CRYPTO_ALGO_TKIP;
+ val = TKIP_ENABLED;
+ /* wpa_supplicant switches the third and fourth quarters of the TKIP key */
+ if (mode == WL_MODE_BSS) {
+ bcopy(&key.data[24], keybuf, sizeof(keybuf));
+ bcopy(&key.data[16], &key.data[24], sizeof(keybuf));
+ bcopy(keybuf, &key.data[16], sizeof(keybuf));
+ }
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_TKIP\n");
+ break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ key.algo = CRYPTO_ALGO_AES_CCM;
+ val = AES_ENABLED;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_AES_CMAC\n");
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ key.algo = CRYPTO_ALGO_AES_CCM;
+ val = AES_ENABLED;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_CCMP\n");
+ break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ key.algo = CRYPTO_ALGO_SMS4;
+ val = SMS4_ENABLED;
+ AP6210_DEBUG(" * wl_cfg80211_add_key, set key "
+ " to WLAN_CIPHER_SUITE_SMS4\n");
+ break;
+#endif /* BCMWAPI_WPI */
+ default:
+ AP6210_ERR("Invalid cipher (0x%x)\n", params->cipher);
+ return -EINVAL;
+ }
+
+ /* Set the new key/index */
+ swap_key_from_BE(&key);
+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf,
+ WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_SET_KEY error (%d)\n", err);
+ return err;
+ }
+
+exit:
+ err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
+ if (unlikely(err)) {
+ AP6210_ERR("get wsec error (%d)\n", err);
+ return err;
+ }
+
+ wsec |= val;
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
+ if (unlikely(err)) {
+ AP6210_ERR("set wsec error (%d)\n", err);
+ return err;
+ }
+
+ return err;
+}
+
+static s32
+wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, bool pairwise, const u8 *mac_addr)
+{
+ struct wl_wsec_key key;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ AP6210_DEBUG("Enter\n");
+#ifndef IEEE80211W
+ if ((key_idx >= DOT11_MAX_DEFAULT_KEYS) && (key_idx < DOT11_MAX_DEFAULT_KEYS+2))
+ return -EINVAL;
+#endif
+ CHECK_SYS_UP(wl);
+ memset(&key, 0, sizeof(key));
+
+ key.flags = WL_PRIMARY_KEY;
+ key.algo = CRYPTO_ALGO_OFF;
+ key.index = (u32) key_idx;
+
+ AP6210_DEBUG("key index (%d)\n", key_idx);
+ /* Set the new key/index */
+ swap_key_from_BE(&key);
+ err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf,
+ WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ if (unlikely(err)) {
+ if (err == -EINVAL) {
+ if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
+ /* we ignore this key index in this case */
+ AP6210_DEBUG("invalid key index (%d)\n", key_idx);
+ }
+ } else {
+ AP6210_ERR("WLC_SET_KEY error (%d)\n", err);
+ }
+ return err;
+ }
+ return err;
+}
+
+static s32
+wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+ u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
+ void (*callback) (void *cookie, struct key_params * params))
+{
+ struct key_params params;
+ struct wl_wsec_key key;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct wl_security *sec;
+ s32 wsec;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ AP6210_DEBUG("key index (%d)\n", key_idx);
+ CHECK_SYS_UP(wl);
+ memset(&key, 0, sizeof(key));
+ key.index = key_idx;
+ swap_key_to_BE(&key);
+ memset(&params, 0, sizeof(params));
+ params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
+ memcpy(params.key, key.data, params.key_len);
+
+ wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_GET_WSEC error (%d)\n", err);
+ return err;
+ }
+ switch (wsec & ~SES_OW_ENABLED) {
+ case WEP_ENABLED:
+ sec = wl_read_prof(wl, dev, WL_PROF_SEC);
+ if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
+ params.cipher = WLAN_CIPHER_SUITE_WEP40;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP40\n");
+ } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
+ params.cipher = WLAN_CIPHER_SUITE_WEP104;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_WEP104\n");
+ }
+ break;
+ case TKIP_ENABLED:
+ params.cipher = WLAN_CIPHER_SUITE_TKIP;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_TKIP\n");
+ break;
+ case AES_ENABLED:
+ params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+ AP6210_DEBUG("WLAN_CIPHER_SUITE_AES_CMAC\n");
+ break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ key.algo = CRYPTO_ALGO_SMS4;
+ AP6210_DEBUG(" * wl_cfg80211_add_key, set key"
+ "to WLAN_CIPHER_SUITE_SMS4\n");
+ break;
+#endif
+ default:
+ AP6210_ERR("Invalid algo (0x%x)\n", wsec);
+ return -EINVAL;
+ }
+
+ callback(cookie, &params);
+ return err;
+}
+
+static s32
+wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
+ struct net_device *dev, u8 key_idx)
+{
+ AP6210_DEBUG("Not supported\n");
+ return -EOPNOTSUPP;
+}
+
+static s32
+wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_info *sinfo)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ scb_val_t scb_val;
+ s32 rssi;
+ s32 rate;
+ s32 err = 0;
+ sta_info_t *sta;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+ s8 eabuf[ETHER_ADDR_STR_LEN];
+#endif
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ CHECK_SYS_UP(wl);
+ if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
+ err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac,
+ ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_SMLEN, &wl->ioctl_buf_sync);
+ if (err < 0) {
+ AP6210_ERR("GET STA INFO failed, %d\n", err);
+ return err;
+ }
+ sinfo->filled = STATION_INFO_INACTIVE_TIME;
+ sta = (sta_info_t *)wl->ioctl_buf;
+ sta->len = dtoh16(sta->len);
+ sta->cap = dtoh16(sta->cap);
+ sta->flags = dtoh32(sta->flags);
+ sta->idle = dtoh32(sta->idle);
+ sta->in = dtoh32(sta->in);
+ sinfo->inactive_time = sta->idle * 1000;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+ if (sta->flags & WL_STA_ASSOC) {
+ sinfo->filled |= STATION_INFO_CONNECTED_TIME;
+ sinfo->connected_time = sta->in;
+ }
+ AP6210_DEBUG("STA %s : idle time : %d sec, connected time :%d ms\n",
+ bcm_ether_ntoa((const struct ether_addr *)mac, eabuf), sinfo->inactive_time,
+ sta->idle * 1000);
+#endif
+ } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
+ get_pktcnt_t pktcnt;
+ u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
+ if (!wl_get_drv_status(wl, CONNECTED, dev) ||
+ (dhd_is_associated(dhd, NULL, &err) == FALSE)) {
+ AP6210_ERR("NOT assoc\n");
+ if (err == -ERESTARTSYS)
+ return err;
+ err = -ENODEV;
+ return err;
+ }
+ if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) {
+ AP6210_ERR("Wrong Mac address: "MACDBG" != "MACDBG"\n",
+ MAC2STRDBG(mac), MAC2STRDBG(curmacp));
+ }
+
+ /* Report the current tx rate */
+ err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
+ if (err) {
+ AP6210_ERR("Could not get rate (%d)\n", err);
+ } else {
+ rate = dtoh32(rate);
+ sinfo->filled |= STATION_INFO_TX_BITRATE;
+ sinfo->txrate.legacy = rate * 5;
+ AP6210_DEBUG("Rate %d Mbps\n", (rate / 2));
+ }
+
+ memset(&scb_val, 0, sizeof(scb_val));
+ scb_val.val = 0;
+ err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
+ sizeof(scb_val_t), false);
+ if (err) {
+ AP6210_ERR("Could not get rssi (%d)\n", err);
+ goto get_station_err;
+ }
+ rssi = dtoh32(scb_val.val);
+#if defined(RSSIOFFSET)
+ rssi = wl_update_rssi_offset(rssi);
+#endif
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = rssi;
+ AP6210_DEBUG("RSSI %d dBm\n", rssi);
+ err = wldev_ioctl(dev, WLC_GET_PKTCNTS, &pktcnt,
+ sizeof(pktcnt), false);
+ if (!err) {
+ sinfo->filled |= (STATION_INFO_RX_PACKETS |
+ STATION_INFO_RX_DROP_MISC |
+ STATION_INFO_TX_PACKETS |
+ STATION_INFO_TX_FAILED);
+ sinfo->rx_packets = pktcnt.rx_good_pkt;
+ sinfo->rx_dropped_misc = pktcnt.rx_bad_pkt;
+ sinfo->tx_packets = pktcnt.tx_good_pkt;
+ sinfo->tx_failed = pktcnt.tx_bad_pkt;
+ }
+get_station_err:
+ if (err && (err != -ERESTARTSYS)) {
+ /* Disconnect due to zero BSSID or error to get RSSI */
+ AP6210_ERR("force cfg80211_disconnected\n");
+ wl_clr_drv_status(wl, CONNECTED, dev);
+ cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL);
+ wl_link_down(wl);
+ }
+ }
+
+ return err;
+}
+
+/* Function to update sta power save mode for Kernel wifi stack */
+int wl_cfg80211_update_power_mode(struct net_device *dev)
+{
+ int pm = -1;
+ int err;
+
+ err = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), false);
+ if (err || (pm == -1)) {
+ AP6210_ERR("error (%d)\n", err);
+ } else {
+ pm = (pm == PM_OFF) ? false : true;
+ AP6210_DEBUG("%s: %d\n", __func__, pm);
+ if (dev->ieee80211_ptr)
+ dev->ieee80211_ptr->ps = pm;
+ }
+ return err;
+}
+
+static s32
+wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+ bool enabled, s32 timeout)
+{
+ s32 pm;
+ s32 err = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_info *_net_info = wl_get_netinfo_by_netdev(wl, dev);
+#if !defined(SUPPORT_PM2_ONLY)
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+#endif /* (OEM_ANDROID) */
+ CHECK_SYS_UP(wl);
+
+ if (wl->p2p_net == dev || _net_info == NULL) {
+ return err;
+ }
+ AP6210_DEBUG("%s: Enter power save enabled %d\n", dev->name, enabled);
+
+#if !defined(SUPPORT_PM2_ONLY)
+ /* android has special hooks to change pm when kernel suspended */
+ pm = enabled ? ((dhd->in_suspend) ? PM_MAX : PM_FAST) : PM_OFF;
+#else
+ pm = enabled ? PM_FAST : PM_OFF;
+#endif /* SUPPORT_PM2_ONLY */
+
+ if (_net_info->pm_block || wl->vsdb_mode) {
+ /* Do not enable the power save if it is p2p interface or vsdb mode is set */
+ AP6210_DEBUG("%s:Do not enable the power save for pm_block %d or vsdb_mode %d\n",
+ dev->name, _net_info->pm_block, wl->vsdb_mode);
+ pm = PM_OFF;
+ }
+ pm = htod32(pm);
+ AP6210_DEBUG("%s:power save %s\n", dev->name, (pm ? "enabled" : "disabled"));
+ err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
+ if (unlikely(err)) {
+ if (err == -ENODEV)
+ AP6210_DEBUG("net_device is not ready yet\n");
+ else
+ AP6210_ERR("error (%d)\n", err);
+ return err;
+ }
+ return err;
+}
+
+static __used u32 wl_find_msb(u16 bit16)
+{
+ u32 ret = 0;
+
+ if (bit16 & 0xff00) {
+ ret += 8;
+ bit16 >>= 8;
+ }
+
+ if (bit16 & 0xf0) {
+ ret += 4;
+ bit16 >>= 4;
+ }
+
+ if (bit16 & 0xc) {
+ ret += 2;
+ bit16 >>= 2;
+ }
+
+ if (bit16 & 2)
+ ret += bit16 & 2;
+ else if (bit16)
+ ret += bit16;
+
+ return ret;
+}
+
+static s32 wl_cfg80211_resume(struct wiphy *wiphy)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ s32 err = 0;
+
+ if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
+ AP6210_DEBUG("device is not ready\n");
+ return 0;
+ }
+
+ wl_invoke_iscan(wl);
+
+ return err;
+}
+
+static s32
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
+wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
+#else
+wl_cfg80211_suspend(struct wiphy *wiphy)
+#endif
+{
+#ifdef DHD_CLEAR_ON_SUSPEND
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_info *iter, *next;
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ unsigned long flags;
+ if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
+ AP6210_DEBUG("device is not ready : status (%d)\n",
+ (int)wl->status);
+ return 0;
+ }
+ for_each_ndev(wl, iter, next)
+ wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev);
+ wl_term_iscan(wl);
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ if (wl->scan_request) {
+ cfg80211_scan_done(wl->scan_request, true);
+ wl->scan_request = NULL;
+ }
+ for_each_ndev(wl, iter, next) {
+ wl_clr_drv_status(wl, SCANNING, iter->ndev);
+ wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev);
+ }
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+ for_each_ndev(wl, iter, next) {
+ if (wl_get_drv_status(wl, CONNECTING, iter->ndev)) {
+ wl_bss_connect_done(wl, iter->ndev, NULL, NULL, false);
+ }
+ }
+#endif /* DHD_CLEAR_ON_SUSPEND */
+ return 0;
+}
+
+static s32
+wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
+ s32 err)
+{
+ int i, j;
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct net_device *primary_dev = wl_to_prmry_ndev(wl);
+
+ if (!pmk_list) {
+ AP6210_DEBUG("pmk_list is NULL\n");
+ return -EINVAL;
+ }
+ /* pmk list is supported only for STA interface i.e. primary interface
+ * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
+ */
+ if (primary_dev != dev) {
+ AP6210_DEBUG("Not supporting Flushing pmklist on virtual"
+ " interfaces than primary interface\n");
+ return err;
+ }
+
+ AP6210_DEBUG("No of elements %d\n", pmk_list->pmkids.npmkid);
+ for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
+ AP6210_DEBUG("PMKID[%d]: %pM =\n", i,
+ &pmk_list->pmkids.pmkid[i].BSSID);
+ for (j = 0; j < WPA2_PMKID_LEN; j++) {
+ AP6210_DEBUG("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
+ }
+ }
+ if (likely(!err)) {
+ err = wldev_iovar_setbuf(dev, "pmkid_info", (char *)pmk_list,
+ sizeof(*pmk_list), wl->ioctl_buf, WLC_IOCTL_MAXLEN, NULL);
+ }
+
+ return err;
+}
+
+static s32
+wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_pmksa *pmksa)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ s32 err = 0;
+ int i;
+
+ CHECK_SYS_UP(wl);
+ for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
+ if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
+ ETHER_ADDR_LEN))
+ break;
+ if (i < WL_NUM_PMKIDS_MAX) {
+ memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
+ ETHER_ADDR_LEN);
+ memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
+ WPA2_PMKID_LEN);
+ if (i == wl->pmk_list->pmkids.npmkid)
+ wl->pmk_list->pmkids.npmkid++;
+ } else {
+ err = -EINVAL;
+ }
+ AP6210_DEBUG("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
+ &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].BSSID);
+ for (i = 0; i < WPA2_PMKID_LEN; i++) {
+ AP6210_DEBUG("%02x\n",
+ wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].
+ PMKID[i]);
+ }
+
+ err = wl_update_pmklist(dev, wl->pmk_list, err);
+
+ return err;
+}
+
+static s32
+wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_pmksa *pmksa)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct _pmkid_list pmkid;
+ s32 err = 0;
+ int i;
+
+ CHECK_SYS_UP(wl);
+ memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
+ memcpy(pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
+
+ AP6210_DEBUG("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
+ &pmkid.pmkid[0].BSSID);
+ for (i = 0; i < WPA2_PMKID_LEN; i++) {
+ AP6210_DEBUG("%02x\n", pmkid.pmkid[0].PMKID[i]);
+ }
+
+ for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
+ if (!memcmp
+ (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
+ ETHER_ADDR_LEN))
+ break;
+
+ if ((wl->pmk_list->pmkids.npmkid > 0) &&
+ (i < wl->pmk_list->pmkids.npmkid)) {
+ memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
+ for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
+ memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
+ &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
+ ETHER_ADDR_LEN);
+ memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
+ &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
+ WPA2_PMKID_LEN);
+ }
+ wl->pmk_list->pmkids.npmkid--;
+ } else {
+ err = -EINVAL;
+ }
+
+ err = wl_update_pmklist(dev, wl->pmk_list, err);
+
+ return err;
+
+}
+
+static s32
+wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ s32 err = 0;
+ CHECK_SYS_UP(wl);
+ memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
+ err = wl_update_pmklist(dev, wl->pmk_list, err);
+ return err;
+
+}
+
+static wl_scan_params_t *
+wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
+{
+ wl_scan_params_t *params;
+ int params_size;
+ int num_chans;
+
+ *out_params_size = 0;
+
+ /* Our scan params only need space for 1 channel and 0 ssids */
+ params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16);
+ params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL);
+ if (params == NULL) {
+ AP6210_ERR("%s: mem alloc failed (%d bytes)\n", __func__, params_size);
+ return params;
+ }
+ memset(params, 0, params_size);
+ params->nprobes = nprobes;
+
+ num_chans = (channel == 0) ? 0 : 1;
+
+ memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
+ params->bss_type = DOT11_BSSTYPE_ANY;
+ params->scan_type = DOT11_SCANTYPE_ACTIVE;
+ params->nprobes = htod32(1);
+ params->active_time = htod32(-1);
+ params->passive_time = htod32(-1);
+ params->home_time = htod32(10);
+ if (channel == -1)
+ params->channel_list[0] = htodchanspec(channel);
+ else
+ params->channel_list[0] = wl_ch_host_to_driver(channel);
+
+ /* Our scan params have 1 channel and 0 ssids */
+ params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
+ (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
+
+ *out_params_size = params_size; /* rtn size to the caller */
+ return params;
+}
+
+static s32
+wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
+ struct ieee80211_channel * channel,
+ enum nl80211_channel_type channel_type,
+ unsigned int duration, u64 *cookie)
+{
+ s32 target_channel;
+ u32 id;
+ struct ether_addr primary_mac;
+ struct net_device *ndev = NULL;
+
+ s32 err = BCME_OK;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+
+ AP6210_DEBUG("Enter, ifindex: %d, channel: %d, duration ms (%d) SCANNING ?? %s \n",
+ dev->ifindex, ieee80211_frequency_to_channel(channel->center_freq),
+ duration, (wl_get_drv_status(wl, SCANNING, ndev)) ? "YES":"NO");
+
+ if (wl->p2p_net == dev) {
+ ndev = wl_to_prmry_ndev(wl);
+ } else {
+ ndev = dev;
+ }
+
+ if (!wl->p2p) {
+ AP6210_ERR("wl->p2p is not initialized\n");
+ err = BCME_ERROR;
+ goto exit;
+ }
+
+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ if (wl_get_drv_status(wl, SCANNING, ndev)) {
+ wl_notify_escan_complete(wl, ndev, true, true);
+ }
+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+
+ target_channel = ieee80211_frequency_to_channel(channel->center_freq);
+ memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel));
+ wl->remain_on_chan_type = channel_type;
+ id = ++wl->last_roc_id;
+ if (id == 0)
+ id = ++wl->last_roc_id;
+ *cookie = id;
+
+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ if (wl_get_drv_status(wl, SCANNING, ndev)) {
+ struct timer_list *_timer;
+ AP6210_DEBUG("scan is running. go to fake listen state\n");
+
+ wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev);
+
+ if (timer_pending(&wl->p2p->listen_timer)) {
+ AP6210_DEBUG("cancel current listen timer \n");
+ del_timer_sync(&wl->p2p->listen_timer);
+ }
+
+ _timer = &wl->p2p->listen_timer;
+ wl_clr_p2p_status(wl, LISTEN_EXPIRED);
+
+ INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration, 0);
+
+ err = BCME_OK;
+ goto exit;
+ }
+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+
+#ifdef WL_CFG80211_SYNC_GON
+ if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) {
+ /* do not enter listen mode again if we are in listen mode already for next af.
+ * remain on channel completion will be returned by waiting next af completion.
+ */
+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev);
+#else
+ wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev);
+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+ goto exit;
+ }
+#endif /* WL_CFG80211_SYNC_GON */
+ if (wl->p2p && !wl->p2p->on) {
+ /* In case of p2p_listen command, supplicant send remain_on_channel
+ * without turning on P2P
+ */
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
+ p2p_on(wl) = true;
+ }
+
+ if (p2p_is_on(wl)) {
+ err = wl_cfgp2p_enable_discovery(wl, ndev, NULL, 0);
+ if (unlikely(err)) {
+ goto exit;
+ }
+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev);
+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+ err = wl_cfgp2p_discover_listen(wl, target_channel, duration);
+
+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ if (err == BCME_OK) {
+ wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev);
+ } else {
+ /* if failed, firmware may be internal scanning state.
+ * so other scan request shall not abort it
+ */
+ wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev);
+ }
+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+ /* WAR: set err = ok to prevent cookie mismatch in wpa_supplicant
+ * and expire timer will send a completion to the upper layer
+ */
+ err = BCME_OK;
+ }
+
+exit:
+ if (err == BCME_OK) {
+ AP6210_DEBUG("Success\n");
+ cfg80211_ready_on_channel(dev, *cookie, channel,
+ channel_type, duration, GFP_KERNEL);
+ } else {
+ AP6210_ERR("Fail to Set (err=%d cookie:%llu)\n", err, *cookie);
+ }
+ return err;
+}
+
+static s32
+wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
+ u64 cookie)
+{
+ s32 err = 0;
+ AP6210_DEBUG(" enter ) netdev_ifidx: %d \n", dev->ifindex);
+ return err;
+}
+
+static void
+wl_cfg80211_afx_handler(struct work_struct *work)
+{
+ struct afx_hdl *afx_instance;
+ struct wl_priv *wl = wlcfg_drv_priv;
+ s32 ret = BCME_OK;
+
+ afx_instance = container_of(work, struct afx_hdl, work);
+ if (afx_instance != NULL && wl->afx_hdl->is_active) {
+ if (wl->afx_hdl->is_listen && wl->afx_hdl->my_listen_chan) {
+ ret = wl_cfgp2p_discover_listen(wl, wl->afx_hdl->my_listen_chan,
+ (100 * (1 + (random32() % 3)))); /* 100ms ~ 300ms */
+ } else {
+ ret = wl_cfgp2p_act_frm_search(wl, wl->afx_hdl->dev,
+ wl->afx_hdl->bssidx, wl->afx_hdl->peer_listen_chan);
+ }
+ if (unlikely(ret != BCME_OK)) {
+ AP6210_ERR("ERROR occurred! returned value is (%d)\n", ret);
+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL))
+ complete(&wl->act_frm_scan);
+ }
+ }
+}
+
+static s32
+wl_cfg80211_af_searching_channel(struct wl_priv *wl, struct net_device *dev)
+{
+ u32 max_retry = WL_CHANNEL_SYNC_RETRY;
+
+ if (dev == NULL)
+ return -1;
+
+ AP6210_DEBUG(" enter ) \n");
+
+ wl_set_drv_status(wl, FINDING_COMMON_CHANNEL, dev);
+ wl->afx_hdl->is_active = TRUE;
+
+ /* Loop to wait until we find a peer's channel or the
+ * pending action frame tx is cancelled.
+ */
+ while ((wl->afx_hdl->retry < max_retry) &&
+ (wl->afx_hdl->peer_chan == WL_INVALID)) {
+ wl->afx_hdl->is_listen = FALSE;
+ wl_set_drv_status(wl, SCANNING, dev);
+ AP6210_DEBUG("Scheduling the action frame for sending.. retry %d\n",
+ wl->afx_hdl->retry);
+ /* search peer on peer's listen channel */
+ schedule_work(&wl->afx_hdl->work);
+ wait_for_completion_timeout(&wl->act_frm_scan,
+ msecs_to_jiffies(MAX_WAIT_TIME));
+
+ if ((wl->afx_hdl->peer_chan != WL_INVALID) ||
+ !(wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev)))
+ break;
+
+ if (wl->afx_hdl->my_listen_chan) {
+ AP6210_DEBUG("Scheduling Listen peer in my listen channel = %d\n",
+ wl->afx_hdl->my_listen_chan);
+ /* listen on my listen channel */
+ wl->afx_hdl->is_listen = TRUE;
+ schedule_work(&wl->afx_hdl->work);
+ wait_for_completion_timeout(&wl->act_frm_scan,
+ msecs_to_jiffies(MAX_WAIT_TIME));
+ }
+ if (!wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev))
+ break;
+ wl->afx_hdl->retry++;
+
+ WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl);
+ }
+
+ wl->afx_hdl->is_active = FALSE;
+
+ wl_clr_drv_status(wl, SCANNING, dev);
+ wl_clr_drv_status(wl, FINDING_COMMON_CHANNEL, dev);
+
+ return (wl->afx_hdl->peer_chan);
+}
+
+struct p2p_config_af_params {
+ s32 max_tx_retry; /* max tx retry count if tx no ack */
+ /* To make sure to send successfully action frame, we have to turn off mpc
+ * 0: off, 1: on, (-1): do nothing
+ */
+ s32 mpc_onoff;
+#ifdef WL_CFG80211_SYNC_GON
+ bool extra_listen;
+#endif
+ bool search_channel; /* 1: search peer's channel to send af */
+};
+
+static s32
+wl_cfg80211_config_p2p_pub_af_tx(struct wiphy *wiphy,
+ wl_action_frame_t *action_frame, wl_af_params_t *af_params,
+ struct p2p_config_af_params *config_af_params)
+{
+ s32 err = BCME_OK;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ wifi_p2p_pub_act_frame_t *act_frm =
+ (wifi_p2p_pub_act_frame_t *) (action_frame->data);
+
+ /* initialize default value */
+#ifdef WL_CFG80211_SYNC_GON
+ config_af_params->extra_listen = true;
+#endif
+ config_af_params->search_channel = false;
+ config_af_params->max_tx_retry = WL_AF_TX_MAX_RETRY;
+ config_af_params->mpc_onoff = -1;
+
+ switch (act_frm->subtype) {
+ case P2P_PAF_GON_REQ: {
+ AP6210_DEBUG("P2P: GO_NEG_PHASE status set \n");
+ wl_set_p2p_status(wl, GO_NEG_PHASE);
+
+ config_af_params->mpc_onoff = 0;
+ config_af_params->search_channel = true;
+ wl->next_af_subtype = act_frm->subtype + 1;
+
+ /* increase dwell time to wait for RESP frame */
+ af_params->dwell_time = WL_MED_DWELL_TIME;
+
+ break;
+ }
+ case P2P_PAF_GON_RSP: {
+ wl->next_af_subtype = act_frm->subtype + 1;
+ /* increase dwell time to wait for CONF frame */
+ af_params->dwell_time = WL_MED_DWELL_TIME;
+ break;
+ }
+ case P2P_PAF_GON_CONF: {
+ /* If we reached till GO Neg confirmation reset the filter */
+ AP6210_DEBUG("P2P: GO_NEG_PHASE status cleared \n");
+ wl_clr_p2p_status(wl, GO_NEG_PHASE);
+
+ /* turn on mpc again if go nego is done */
+ config_af_params->mpc_onoff = 1;
+
+ /* minimize dwell time */
+ af_params->dwell_time = WL_MIN_DWELL_TIME;
+
+#ifdef WL_CFG80211_SYNC_GON
+ config_af_params->extra_listen = false;
+#endif /* WL_CFG80211_SYNC_GON */
+ break;
+ }
+ case P2P_PAF_INVITE_REQ: {
+ config_af_params->search_channel = true;
+ wl->next_af_subtype = act_frm->subtype + 1;
+
+ /* increase dwell time */
+ af_params->dwell_time = WL_MED_DWELL_TIME;
+ break;
+ }
+ case P2P_PAF_INVITE_RSP:
+ /* minimize dwell time */
+ af_params->dwell_time = WL_MIN_DWELL_TIME;
+#ifdef WL_CFG80211_SYNC_GON
+ config_af_params->extra_listen = false;
+#endif /* WL_CFG80211_SYNC_GON */
+ break;
+ case P2P_PAF_DEVDIS_REQ: {
+ config_af_params->search_channel = true;
+
+ wl->next_af_subtype = act_frm->subtype + 1;
+ /* maximize dwell time to wait for RESP frame */
+ af_params->dwell_time = WL_LONG_DWELL_TIME;
+ break;
+ }
+ case P2P_PAF_DEVDIS_RSP:
+ /* minimize dwell time */
+ af_params->dwell_time = WL_MIN_DWELL_TIME;
+#ifdef WL_CFG80211_SYNC_GON
+ config_af_params->extra_listen = false;
+#endif /* WL_CFG80211_SYNC_GON */
+ break;
+ case P2P_PAF_PROVDIS_REQ: {
+ if (IS_PROV_DISC_WITHOUT_GROUP_ID(&act_frm->elts[0],
+ action_frame->len)) {
+ config_af_params->search_channel = true;
+ }
+
+ config_af_params->mpc_onoff = 0;
+ wl->next_af_subtype = act_frm->subtype + 1;
+ /* increase dwell time to wait for RESP frame */
+ af_params->dwell_time = WL_MED_DWELL_TIME;
+ break;
+ }
+ case P2P_PAF_PROVDIS_RSP: {
+ wl->next_af_subtype = P2P_PAF_GON_REQ;
+ /* increase dwell time to MED level */
+ af_params->dwell_time = WL_MED_DWELL_TIME;
+#ifdef WL_CFG80211_SYNC_GON
+ config_af_params->extra_listen = false;
+#endif /* WL_CFG80211_SYNC_GON */
+ break;
+ }
+ default:
+ AP6210_DEBUG("Unknown p2p pub act frame subtype: %d\n",
+ act_frm->subtype);
+ err = BCME_BADARG;
+ }
+ return err;
+}
+
+
+static bool
+wl_cfg80211_send_action_frame(struct wiphy *wiphy, struct net_device *dev,
+ struct net_device *ndev, wl_af_params_t *af_params,
+ wl_action_frame_t *action_frame, u16 action_frame_len, s32 bssidx)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ bool ack = false;
+ u8 category, action;
+ s32 tx_retry;
+ struct p2p_config_af_params config_af_params;
+#ifdef VSDB
+ ulong off_chan_started_jiffies = 0;
+#endif
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+
+ wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len);
+
+ category = action_frame->data[DOT11_ACTION_CAT_OFF];
+ action = action_frame->data[DOT11_ACTION_ACT_OFF];
+
+ /* initialize variables */
+ tx_retry = 0;
+ wl->next_af_subtype = P2P_PAF_SUBTYPE_INVALID;
+ config_af_params.max_tx_retry = WL_AF_TX_MAX_RETRY;
+ config_af_params.mpc_onoff = -1;
+ config_af_params.search_channel = false;
+#ifdef WL_CFG80211_SYNC_GON
+ config_af_params.extra_listen = false;
+#endif
+
+ /* config parameters */
+ /* Public Action Frame Process - DOT11_ACTION_CAT_PUBLIC */
+ if (category == DOT11_ACTION_CAT_PUBLIC) {
+ if ((action == P2P_PUB_AF_ACTION) &&
+ (action_frame_len >= sizeof(wifi_p2p_pub_act_frame_t))) {
+ /* p2p public action frame process */
+ if (BCME_OK != wl_cfg80211_config_p2p_pub_af_tx(wiphy,
+ action_frame, af_params, &config_af_params)) {
+ AP6210_DEBUG("Unknown subtype.\n");
+ }
+
+ } else if (action_frame_len >= sizeof(wifi_p2psd_gas_pub_act_frame_t)) {
+ /* service discovery process */
+ if (action == P2PSD_ACTION_ID_GAS_IREQ ||
+ action == P2PSD_ACTION_ID_GAS_CREQ) {
+ /* configure service discovery query frame */
+
+ config_af_params.search_channel = true;
+
+ /* save next af suptype to cancel remained dwell time */
+ wl->next_af_subtype = action + 1;
+
+ af_params->dwell_time = WL_MED_DWELL_TIME;
+ } else if (action == P2PSD_ACTION_ID_GAS_IRESP ||
+ action == P2PSD_ACTION_ID_GAS_CRESP) {
+ /* configure service discovery response frame */
+ af_params->dwell_time = WL_MIN_DWELL_TIME;
+ } else {
+ AP6210_DEBUG("Unknown action type: %d\n", action);
+ }
+ } else {
+ AP6210_DEBUG("Unknown Frame: category 0x%x, action 0x%x, length %d\n",
+ category, action, action_frame_len);
+ }
+ } else if (category == P2P_AF_CATEGORY) {
+ /* do not configure anything. it will be sent with a default configuration */
+ } else {
+ AP6210_DEBUG("Unknown Frame: category 0x%x, action 0x%x\n",
+ category, action);
+ if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+ wl_clr_drv_status(wl, SENDING_ACT_FRM, dev);
+ return false;
+ }
+ }
+
+ /* To make sure to send successfully action frame, we have to turn off mpc */
+ if (config_af_params.mpc_onoff == 0) {
+ wldev_iovar_setint(dev, "mpc", 0);
+ }
+
+ /* validate channel and p2p ies */
+ if (config_af_params.search_channel && IS_P2P_SOCIAL(af_params->channel) &&
+ wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) {
+ config_af_params.search_channel = true;
+ } else {
+ config_af_params.search_channel = false;
+ }
+
+#ifdef WL11U
+ if (ndev == wl_to_prmry_ndev(wl))
+ config_af_params.search_channel = false;
+#endif /* WL11U */
+
+#ifdef VSDB
+ /* if connecting on primary iface, sleep for a while before sending af tx for VSDB */
+ if (wl_get_drv_status(wl, CONNECTING, wl_to_prmry_ndev(wl))) {
+ msleep(50);
+ }
+#endif
+
+ /* if scan is ongoing, abort current scan. */
+ if (wl_get_drv_status_all(wl, SCANNING)) {
+ wl_notify_escan_complete(wl, ndev, true, true);
+ }
+
+ /* set status and destination address before sending af */
+ if (wl->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) {
+ /* set this status to cancel the remained dwell time in rx process */
+ wl_set_drv_status(wl, WAITING_NEXT_ACT_FRM, dev);
+ }
+ wl_set_drv_status(wl, SENDING_ACT_FRM, dev);
+ memcpy(wl->afx_hdl->tx_dst_addr.octet,
+ af_params->action_frame.da.octet,
+ sizeof(wl->afx_hdl->tx_dst_addr.octet));
+
+ /* save af_params for rx process */
+ wl->afx_hdl->pending_tx_act_frm = af_params;
+
+ /* search peer's channel */
+ if (config_af_params.search_channel) {
+ /* initialize afx_hdl */
+ wl->afx_hdl->bssidx = wl_cfgp2p_find_idx(wl, dev);
+ wl->afx_hdl->dev = dev;
+ wl->afx_hdl->retry = 0;
+ wl->afx_hdl->peer_chan = WL_INVALID;
+
+ if (wl_cfg80211_af_searching_channel(wl, dev) == WL_INVALID) {
+ AP6210_ERR("couldn't find peer's channel.\n");
+ goto exit;
+ }
+
+ /* Suspend P2P discovery's search-listen to prevent it from
+ * starting a scan or changing the channel.
+ */
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+/* Do not abort scan for VSDB. Scan will be aborted in firmware if necessary */
+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ wl_notify_escan_complete(wl, dev, true, true);
+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+ wl_cfgp2p_discover_enable_search(wl, false);
+
+ /* update channel */
+ af_params->channel = wl->afx_hdl->peer_chan;
+ }
+
+#ifdef VSDB
+ off_chan_started_jiffies = jiffies;
+#endif /* VSDB */
+
+ /* Now send a tx action frame */
+ ack = wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx) ? false : true;
+
+ /* if failed, retry it. tx_retry_max value is configure by .... */
+ while ((ack == false) && (tx_retry++ < config_af_params.max_tx_retry)) {
+#ifdef VSDB
+ if (af_params->channel) {
+ if (jiffies_to_msecs(jiffies - off_chan_started_jiffies) >
+ OFF_CHAN_TIME_THRESHOLD_MS) {
+ WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl);
+ off_chan_started_jiffies = jiffies;
+ }
+ }
+#endif /* VSDB */
+ ack = wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx) ?
+ false : true;
+ }
+ if (ack == false) {
+ AP6210_ERR("Failed to send Action Frame(retry %d)\n", tx_retry);
+ }
+exit:
+ /* Clear SENDING_ACT_FRM after all sending af is done */
+ wl_clr_drv_status(wl, SENDING_ACT_FRM, dev);
+
+#ifdef WL_CFG80211_SYNC_GON
+ /* WAR: sometimes dongle does not keep the dwell time of 'actframe'.
+ * if we coundn't get the next action response frame and dongle does not keep
+ * the dwell time, go to listen state again to get next action response frame.
+ */
+ if (ack && config_af_params.extra_listen &&
+ wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM) &&
+ wl->af_sent_channel == wl->afx_hdl->my_listen_chan) {
+ s32 extar_listen_time;
+
+ extar_listen_time = af_params->dwell_time -
+ jiffies_to_msecs(jiffies - wl->af_tx_sent_jiffies);
+
+ if (extar_listen_time > 50) {
+ wl_set_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, dev);
+ AP6210_DEBUG("Wait more time! actual af time:%d,"
+ "calculated extar listen:%d\n",
+ af_params->dwell_time, extar_listen_time);
+ if (wl_cfgp2p_discover_listen(wl, wl->af_sent_channel,
+ extar_listen_time + 100) == BCME_OK) {
+ wait_for_completion_timeout(&wl->wait_next_af,
+ msecs_to_jiffies(extar_listen_time + 100 + 300));
+ }
+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, dev);
+ }
+ }
+#endif /* WL_CFG80211_SYNC_GON */
+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, dev);
+
+ if (wl->afx_hdl->pending_tx_act_frm)
+ wl->afx_hdl->pending_tx_act_frm = NULL;
+
+ AP6210_DEBUG("-- sending Action Frame is %s, listen chan: %d\n",
+ (ack) ? "Succeeded!!":"Failed!!", wl->afx_hdl->my_listen_chan);
+
+
+ /* if all done, turn mpc on again */
+ if (config_af_params.mpc_onoff == 1) {
+ wldev_iovar_setint(dev, "mpc", 1);
+ }
+
+ return ack;
+}
+
+static s32
+wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
+ struct ieee80211_channel *channel, bool offchan,
+ enum nl80211_channel_type channel_type,
+ bool channel_type_valid, unsigned int wait,
+ const u8* buf, size_t len,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+ bool no_cck,
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+ bool dont_wait_for_ack,
+#endif
+ u64 *cookie)
+{
+ wl_action_frame_t *action_frame;
+ wl_af_params_t *af_params;
+ scb_val_t scb_val;
+ const struct ieee80211_mgmt *mgmt;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *dev = NULL;
+ s32 err = BCME_OK;
+ s32 bssidx = 0;
+ u32 id;
+ bool ack = false;
+ s8 eabuf[ETHER_ADDR_STR_LEN];
+
+ AP6210_DEBUG("Enter \n");
+
+ if (ndev == wl->p2p_net) {
+ dev = wl_to_prmry_ndev(wl);
+ } else {
+ /* If TX req is for any valid ifidx. Use as is */
+ dev = ndev;
+ }
+
+ /* find bssidx based on ndev */
+ bssidx = wl_cfgp2p_find_idx(wl, dev);
+ if (bssidx == -1) {
+
+ AP6210_ERR("Can not find the bssidx for dev( %p )\n", dev);
+ return -ENODEV;
+ }
+ if (p2p_is_on(wl)) {
+ /* Suspend P2P discovery search-listen to prevent it from changing the
+ * channel.
+ */
+ if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) {
+ AP6210_ERR("Can not disable discovery mode\n");
+ return -EFAULT;
+ }
+ }
+ *cookie = 0;
+ id = wl->send_action_id++;
+ if (id == 0)
+ id = wl->send_action_id++;
+ *cookie = id;
+ mgmt = (const struct ieee80211_mgmt *)buf;
+ if (ieee80211_is_mgmt(mgmt->frame_control)) {
+ if (ieee80211_is_probe_resp(mgmt->frame_control)) {
+ s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
+ s32 ie_len = len - ie_offset;
+ if (dev == wl_to_prmry_ndev(wl))
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+ wl_cfgp2p_set_management_ie(wl, dev, bssidx,
+ VNDR_IE_PRBRSP_FLAG, (u8 *)(buf + ie_offset), ie_len);
+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
+ goto exit;
+ } else if (ieee80211_is_disassoc(mgmt->frame_control) ||
+ ieee80211_is_deauth(mgmt->frame_control)) {
+ memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN);
+ scb_val.val = mgmt->u.disassoc.reason_code;
+ err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
+ sizeof(scb_val_t), true);
+ if (err < 0)
+ AP6210_ERR("WLC_SCB_DEAUTHENTICATE_FOR_REASON error %d\n", err);
+ AP6210_DEBUG("Disconnect STA : %s scb_val.val %d\n",
+ bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf),
+ scb_val.val);
+ wl_delay(400);
+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
+ goto exit;
+
+ } else if (ieee80211_is_action(mgmt->frame_control)) {
+ /* Abort the dwell time of any previous off-channel
+ * action frame that may be still in effect. Sending
+ * off-channel action frames relies on the driver's
+ * scan engine. If a previous off-channel action frame
+ * tx is still in progress (including the dwell time),
+ * then this new action frame will not be sent out.
+ */
+/* Do not abort scan for VSDB. Scan will be aborted in firmware if necessary.
+ * And previous off-channel action frame must be ended before new af tx.
+ */
+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ wl_notify_escan_complete(wl, dev, true, true);
+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+ }
+
+ } else {
+ AP6210_ERR("Driver only allows MGMT packet type\n");
+ goto exit;
+ }
+
+ af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
+
+ if (af_params == NULL)
+ {
+ AP6210_ERR("unable to allocate frame\n");
+ return -ENOMEM;
+ }
+
+ action_frame = &af_params->action_frame;
+
+ /* Add the packet Id */
+ action_frame->packetId = *cookie;
+ AP6210_DEBUG("action frame %d\n", action_frame->packetId);
+ /* Add BSSID */
+ memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN);
+ memcpy(&af_params->BSSID, &mgmt->bssid[0], ETHER_ADDR_LEN);
+
+ /* Add the length exepted for 802.11 header */
+ action_frame->len = len - DOT11_MGMT_HDR_LEN;
+ AP6210_DEBUG("action_frame->len: %d\n", action_frame->len);
+
+ /* Add the channel */
+ af_params->channel =
+ ieee80211_frequency_to_channel(channel->center_freq);
+
+ /* Save listen_chan for searching common channel */
+ wl->afx_hdl->peer_listen_chan = af_params->channel;
+ AP6210_DEBUG("channel from upper layer %d\n", wl->afx_hdl->peer_listen_chan);
+
+ /* Add the default dwell time
+ * Dwell time to stay off-channel to wait for a response action frame
+ * after transmitting an GO Negotiation action frame
+ */
+ af_params->dwell_time = WL_DWELL_TIME;
+
+ memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
+
+ ack = wl_cfg80211_send_action_frame(wiphy, dev, ndev, af_params,
+ action_frame, action_frame->len, bssidx);
+
+ cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
+
+ kfree(af_params);
+exit:
+ return err;
+}
+
+
+static void
+wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev,
+ u16 frame_type, bool reg)
+{
+
+ AP6210_DEBUG("%s: frame_type: %x, reg: %d\n", __func__, frame_type, reg);
+
+ if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
+ return;
+
+ return;
+}
+
+
+static s32
+wl_cfg80211_change_bss(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct bss_parameters *params)
+{
+ if (params->use_cts_prot >= 0) {
+ }
+
+ if (params->use_short_preamble >= 0) {
+ }
+
+ if (params->use_short_slot_time >= 0) {
+ }
+
+ if (params->basic_rates) {
+ }
+
+ if (params->ap_isolate >= 0) {
+ }
+
+ if (params->ht_opmode >= 0) {
+ }
+
+ return 0;
+}
+
+static s32
+wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type)
+{
+ s32 _chan;
+ chanspec_t chspec = 0;
+ chanspec_t fw_chspec = 0;
+ u32 bw = WL_CHANSPEC_BW_20;
+
+ s32 err = BCME_OK;
+ s32 bw_cap = 0;
+ struct {
+ u32 band;
+ u32 bw_cap;
+ } param = {0, 0};
+ struct wl_priv *wl = wiphy_priv(wiphy);
+
+ if (wl->p2p_net == dev) {
+ dev = wl_to_prmry_ndev(wl);
+ }
+ _chan = ieee80211_frequency_to_channel(chan->center_freq);
+ AP6210_ERR("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
+ dev->ifindex, channel_type, _chan);
+
+
+ if (chan->band == IEEE80211_BAND_5GHZ) {
+ param.band = WLC_BAND_5G;
+ err = wldev_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
+ wl->ioctl_buf, WLC_IOCTL_SMLEN, &wl->ioctl_buf_sync);
+ if (err) {
+ if (err != BCME_UNSUPPORTED) {
+ AP6210_ERR("bw_cap failed, %d\n", err);
+ return err;
+ } else {
+ err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
+ if (err) {
+ AP6210_ERR("error get mimo_bw_cap (%d)\n", err);
+ }
+ if (bw_cap != WLC_N_BW_20ALL)
+ bw = WL_CHANSPEC_BW_40;
+ }
+ } else {
+ if (WL_BW_CAP_80MHZ(wl->ioctl_buf[0]))
+ bw = WL_CHANSPEC_BW_80;
+ else if (WL_BW_CAP_40MHZ(wl->ioctl_buf[0]))
+ bw = WL_CHANSPEC_BW_40;
+ else
+ bw = WL_CHANSPEC_BW_20;
+
+ }
+
+ } else if (chan->band == IEEE80211_BAND_2GHZ)
+ bw = WL_CHANSPEC_BW_20;
+set_channel:
+ chspec = wf_channel2chspec(_chan, bw);
+ if (wf_chspec_valid(chspec)) {
+ fw_chspec = wl_chspec_host_to_driver(chspec);
+ if (fw_chspec != INVCHANSPEC) {
+ if ((err = wldev_iovar_setint(dev, "chanspec",
+ fw_chspec)) == BCME_BADCHAN) {
+ if (bw == WL_CHANSPEC_BW_80)
+ goto change_bw;
+ err = wldev_ioctl(dev, WLC_SET_CHANNEL,
+ &_chan, sizeof(_chan), true);
+ if (err < 0) {
+ AP6210_ERR("WLC_SET_CHANNEL error %d"
+ "chip may not be supporting this channel\n", err);
+ }
+ } else if (err) {
+ AP6210_ERR("failed to set chanspec error %d\n", err);
+ }
+ } else {
+ AP6210_ERR("failed to convert host chanspec to fw chanspec\n");
+ err = BCME_ERROR;
+ }
+ } else {
+change_bw:
+ if (bw == WL_CHANSPEC_BW_80)
+ bw = WL_CHANSPEC_BW_40;
+ else if (bw == WL_CHANSPEC_BW_40)
+ bw = WL_CHANSPEC_BW_20;
+ else
+ bw = 0;
+ if (bw)
+ goto set_channel;
+ AP6210_ERR("Invalid chanspec 0x%x\n", chspec);
+ err = BCME_ERROR;
+ }
+ return err;
+}
+
+static s32
+wl_validate_opensecurity(struct net_device *dev, s32 bssidx)
+{
+ s32 err = BCME_OK;
+
+ /* set auth */
+ err = wldev_iovar_setint_bsscfg(dev, "auth", 0, bssidx);
+ if (err < 0) {
+ AP6210_ERR("auth error %d\n", err);
+ return BCME_ERROR;
+ }
+ /* set wsec */
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx);
+ if (err < 0) {
+ AP6210_ERR("wsec error %d\n", err);
+ return BCME_ERROR;
+ }
+ /* set upper-layer auth */
+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", WPA_AUTH_NONE, bssidx);
+ if (err < 0) {
+ AP6210_ERR("wpa_auth error %d\n", err);
+ return BCME_ERROR;
+ }
+
+ return 0;
+}
+
+static s32
+wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
+{
+ s32 len = 0;
+ s32 err = BCME_OK;
+ u16 auth = 0; /* d11 open authentication */
+ u32 wsec;
+ u32 pval = 0;
+ u32 gval = 0;
+ u32 wpa_auth = 0;
+ wpa_suite_mcast_t *mcast;
+ wpa_suite_ucast_t *ucast;
+ wpa_suite_auth_key_mgmt_t *mgmt;
+
+ u16 suite_count;
+ u8 rsn_cap[2];
+ u32 wme_bss_disable;
+
+ if (wpa2ie == NULL)
+ goto exit;
+
+ AP6210_DEBUG("Enter \n");
+ len = wpa2ie->len;
+ /* check the mcast cipher */
+ mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN];
+ switch (mcast->type) {
+ case WPA_CIPHER_NONE:
+ gval = 0;
+ break;
+ case WPA_CIPHER_WEP_40:
+ case WPA_CIPHER_WEP_104:
+ gval = WEP_ENABLED;
+ break;
+ case WPA_CIPHER_TKIP:
+ gval = TKIP_ENABLED;
+ break;
+ case WPA_CIPHER_AES_CCM:
+ gval = AES_ENABLED;
+ break;
+#ifdef BCMWAPI_WPI
+ case WAPI_CIPHER_SMS4:
+ gval = SMS4_ENABLED;
+ break;
+#endif
+ default:
+ AP6210_ERR("No Security Info\n");
+ break;
+ }
+ if ((len -= WPA_SUITE_LEN) <= 0)
+ return BCME_BADLEN;
+
+ /* check the unicast cipher */
+ ucast = (wpa_suite_ucast_t *)&mcast[1];
+ suite_count = ltoh16_ua(&ucast->count);
+ switch (ucast->list[0].type) {
+ case WPA_CIPHER_NONE:
+ pval = 0;
+ break;
+ case WPA_CIPHER_WEP_40:
+ case WPA_CIPHER_WEP_104:
+ pval = WEP_ENABLED;
+ break;
+ case WPA_CIPHER_TKIP:
+ pval = TKIP_ENABLED;
+ break;
+ case WPA_CIPHER_AES_CCM:
+ pval = AES_ENABLED;
+ break;
+#ifdef BCMWAPI_WPI
+ case WAPI_CIPHER_SMS4:
+ pval = SMS4_ENABLED;
+ break;
+#endif
+ default:
+ AP6210_ERR("No Security Info\n");
+ }
+ if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) <= 0)
+ return BCME_BADLEN;
+
+ /* FOR WPS , set SEC_OW_ENABLED */
+ wsec = (pval | gval | SES_OW_ENABLED);
+ /* check the AKM */
+ mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[suite_count];
+ suite_count = ltoh16_ua(&mgmt->count);
+ switch (mgmt->list[0].type) {
+ case RSN_AKM_NONE:
+ wpa_auth = WPA_AUTH_NONE;
+ break;
+ case RSN_AKM_UNSPECIFIED:
+ wpa_auth = WPA2_AUTH_UNSPECIFIED;
+ break;
+ case RSN_AKM_PSK:
+ wpa_auth = WPA2_AUTH_PSK;
+ break;
+ default:
+ AP6210_ERR("No Key Mgmt Info\n");
+ }
+
+ if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) {
+ rsn_cap[0] = *(u8 *)&mgmt->list[suite_count];
+ rsn_cap[1] = *((u8 *)&mgmt->list[suite_count] + 1);
+
+ if (rsn_cap[0] & (RSN_CAP_16_REPLAY_CNTRS << RSN_CAP_PTK_REPLAY_CNTR_SHIFT)) {
+ wme_bss_disable = 0;
+ } else {
+ wme_bss_disable = 1;
+ }
+
+ /* set wme_bss_disable to sync RSN Capabilities */
+ err = wldev_iovar_setint_bsscfg(dev, "wme_bss_disable", wme_bss_disable, bssidx);
+ if (err < 0) {
+ AP6210_ERR("wme_bss_disable error %d\n", err);
+ return BCME_ERROR;
+ }
+ } else {
+ AP6210_DEBUG("There is no RSN Capabilities. remained len %d\n", len);
+ }
+
+ /* set auth */
+ err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
+ if (err < 0) {
+ AP6210_ERR("auth error %d\n", err);
+ return BCME_ERROR;
+ }
+ /* set wsec */
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
+ if (err < 0) {
+ AP6210_ERR("wsec error %d\n", err);
+ return BCME_ERROR;
+ }
+ /* set upper-layer auth */
+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
+ if (err < 0) {
+ AP6210_ERR("wpa_auth error %d\n", err);
+ return BCME_ERROR;
+ }
+exit:
+ return 0;
+}
+
+static s32
+wl_validate_wpaie(struct net_device *dev, wpa_ie_fixed_t *wpaie, s32 bssidx)
+{
+ wpa_suite_mcast_t *mcast;
+ wpa_suite_ucast_t *ucast;
+ wpa_suite_auth_key_mgmt_t *mgmt;
+ u16 auth = 0; /* d11 open authentication */
+ u16 count;
+ s32 err = BCME_OK;
+ s32 len = 0;
+ u32 i;
+ u32 wsec;
+ u32 pval = 0;
+ u32 gval = 0;
+ u32 wpa_auth = 0;
+ u32 tmp = 0;
+
+ if (wpaie == NULL)
+ goto exit;
+ AP6210_DEBUG("Enter \n");
+ len = wpaie->length; /* value length */
+ len -= WPA_IE_TAG_FIXED_LEN;
+ /* check for multicast cipher suite */
+ if (len < WPA_SUITE_LEN) {
+ AP6210_DEBUG("no multicast cipher suite\n");
+ goto exit;
+ }
+
+ /* pick up multicast cipher */
+ mcast = (wpa_suite_mcast_t *)&wpaie[1];
+ len -= WPA_SUITE_LEN;
+ if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) {
+ if (IS_WPA_CIPHER(mcast->type)) {
+ tmp = 0;
+ switch (mcast->type) {
+ case WPA_CIPHER_NONE:
+ tmp = 0;
+ break;
+ case WPA_CIPHER_WEP_40:
+ case WPA_CIPHER_WEP_104:
+ tmp = WEP_ENABLED;
+ break;
+ case WPA_CIPHER_TKIP:
+ tmp = TKIP_ENABLED;
+ break;
+ case WPA_CIPHER_AES_CCM:
+ tmp = AES_ENABLED;
+ break;
+ default:
+ AP6210_ERR("No Security Info\n");
+ }
+ gval |= tmp;
+ }
+ }
+ /* Check for unicast suite(s) */
+ if (len < WPA_IE_SUITE_COUNT_LEN) {
+ AP6210_DEBUG("no unicast suite\n");
+ goto exit;
+ }
+ /* walk thru unicast cipher list and pick up what we recognize */
+ ucast = (wpa_suite_ucast_t *)&mcast[1];
+ count = ltoh16_ua(&ucast->count);
+ len -= WPA_IE_SUITE_COUNT_LEN;
+ for (i = 0; i < count && len >= WPA_SUITE_LEN;
+ i++, len -= WPA_SUITE_LEN) {
+ if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
+ if (IS_WPA_CIPHER(ucast->list[i].type)) {
+ tmp = 0;
+ switch (ucast->list[i].type) {
+ case WPA_CIPHER_NONE:
+ tmp = 0;
+ break;
+ case WPA_CIPHER_WEP_40:
+ case WPA_CIPHER_WEP_104:
+ tmp = WEP_ENABLED;
+ break;
+ case WPA_CIPHER_TKIP:
+ tmp = TKIP_ENABLED;
+ break;
+ case WPA_CIPHER_AES_CCM:
+ tmp = AES_ENABLED;
+ break;
+ default:
+ AP6210_ERR("No Security Info\n");
+ }
+ pval |= tmp;
+ }
+ }
+ }
+ len -= (count - i) * WPA_SUITE_LEN;
+ /* Check for auth key management suite(s) */
+ if (len < WPA_IE_SUITE_COUNT_LEN) {
+ AP6210_DEBUG(" no auth key mgmt suite\n");
+ goto exit;
+ }
+ /* walk thru auth management suite list and pick up what we recognize */
+ mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count];
+ count = ltoh16_ua(&mgmt->count);
+ len -= WPA_IE_SUITE_COUNT_LEN;
+ for (i = 0; i < count && len >= WPA_SUITE_LEN;
+ i++, len -= WPA_SUITE_LEN) {
+ if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
+ if (IS_WPA_AKM(mgmt->list[i].type)) {
+ tmp = 0;
+ switch (mgmt->list[i].type) {
+ case RSN_AKM_NONE:
+ tmp = WPA_AUTH_NONE;
+ break;
+ case RSN_AKM_UNSPECIFIED:
+ tmp = WPA_AUTH_UNSPECIFIED;
+ break;
+ case RSN_AKM_PSK:
+ tmp = WPA_AUTH_PSK;
+ break;
+ default:
+ AP6210_ERR("No Key Mgmt Info\n");
+ }
+ wpa_auth |= tmp;
+ }
+ }
+
+ }
+ /* FOR WPS , set SEC_OW_ENABLED */
+ wsec = (pval | gval | SES_OW_ENABLED);
+ /* set auth */
+ err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
+ if (err < 0) {
+ AP6210_ERR("auth error %d\n", err);
+ return BCME_ERROR;
+ }
+ /* set wsec */
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
+ if (err < 0) {
+ AP6210_ERR("wsec error %d\n", err);
+ return BCME_ERROR;
+ }
+ /* set upper-layer auth */
+ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
+ if (err < 0) {
+ AP6210_ERR("wpa_auth error %d\n", err);
+ return BCME_ERROR;
+ }
+exit:
+ return 0;
+}
+
+static s32
+wl_cfg80211_bcn_validate_sec(
+ struct net_device *dev,
+ struct parsed_ies *ies,
+ u32 dev_role,
+ s32 bssidx)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+ if (dev_role == NL80211_IFTYPE_P2P_GO && (ies->wpa2_ie)) {
+ /* For P2P GO, the sec type is WPA2-PSK */
+ AP6210_DEBUG("P2P GO: validating wpa2_ie");
+ if (wl_validate_wpa2ie(dev, ies->wpa2_ie, bssidx) < 0)
+ return BCME_ERROR;
+
+ } else if (dev_role == NL80211_IFTYPE_AP) {
+
+ AP6210_DEBUG("SoftAP: validating security");
+ /* If wpa2_ie or wpa_ie is present validate it */
+ if ((ies->wpa2_ie || ies->wpa_ie) &&
+ ((wl_validate_wpa2ie(dev, ies->wpa2_ie, bssidx) < 0 ||
+ wl_validate_wpaie(dev, ies->wpa_ie, bssidx) < 0))) {
+ wl->ap_info->security_mode = false;
+ return BCME_ERROR;
+ }
+
+ wl->ap_info->security_mode = true;
+ if (wl->ap_info->rsn_ie) {
+ kfree(wl->ap_info->rsn_ie);
+ wl->ap_info->rsn_ie = NULL;
+ }
+ if (wl->ap_info->wpa_ie) {
+ kfree(wl->ap_info->wpa_ie);
+ wl->ap_info->wpa_ie = NULL;
+ }
+ if (wl->ap_info->wps_ie) {
+ kfree(wl->ap_info->wps_ie);
+ wl->ap_info->wps_ie = NULL;
+ }
+ if (ies->wpa_ie != NULL) {
+ /* WPAIE */
+ wl->ap_info->rsn_ie = NULL;
+ wl->ap_info->wpa_ie = kmemdup(ies->wpa_ie,
+ ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
+ GFP_KERNEL);
+ } else if (ies->wpa2_ie != NULL) {
+ /* RSNIE */
+ wl->ap_info->wpa_ie = NULL;
+ wl->ap_info->rsn_ie = kmemdup(ies->wpa2_ie,
+ ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
+ GFP_KERNEL);
+ }
+
+ if (!ies->wpa2_ie && !ies->wpa_ie) {
+ wl_validate_opensecurity(dev, bssidx);
+ wl->ap_info->security_mode = false;
+ }
+
+ if (ies->wps_ie) {
+ wl->ap_info->wps_ie = kmemdup(ies->wps_ie, ies->wps_ie_len, GFP_KERNEL);
+ }
+ }
+
+ return 0;
+
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+static s32 wl_cfg80211_bcn_set_params(
+ struct cfg80211_ap_settings *info,
+ struct net_device *dev,
+ u32 dev_role, s32 bssidx)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ s32 err = BCME_OK;
+
+ AP6210_DEBUG("interval (%d) \ndtim_period (%d) \n",
+ info->beacon_interval, info->dtim_period);
+
+ if (info->beacon_interval) {
+ if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD,
+ &info->beacon_interval, sizeof(s32), true)) < 0) {
+ AP6210_ERR("Beacon Interval Set Error, %d\n", err);
+ return err;
+ }
+ }
+
+ if (info->dtim_period) {
+ if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
+ &info->dtim_period, sizeof(s32), true)) < 0) {
+ AP6210_ERR("DTIM Interval Set Error, %d\n", err);
+ return err;
+ }
+ }
+
+ if ((info->ssid) && (info->ssid_len > 0) &&
+ (info->ssid_len <= 32)) {
+ AP6210_DEBUG("SSID (%s) len:%d \n", info->ssid, info->ssid_len);
+ if (dev_role == NL80211_IFTYPE_AP) {
+ /* Store the hostapd SSID */
+ memset(wl->hostapd_ssid.SSID, 0x00, 32);
+ memcpy(wl->hostapd_ssid.SSID, info->ssid, info->ssid_len);
+ wl->hostapd_ssid.SSID_len = info->ssid_len;
+ } else {
+ /* P2P GO */
+ memset(wl->p2p->ssid.SSID, 0x00, 32);
+ memcpy(wl->p2p->ssid.SSID, info->ssid, info->ssid_len);
+ wl->p2p->ssid.SSID_len = info->ssid_len;
+ }
+ }
+
+ if (info->hidden_ssid) {
+ if ((err = wldev_iovar_setint(dev, "closednet", 1)) < 0)
+ AP6210_ERR("failed to set hidden : %d\n", err);
+ AP6210_DEBUG("hidden_ssid_enum_val: %d \n", info->hidden_ssid);
+ }
+
+ return err;
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
+
+static s32
+wl_cfg80211_parse_ies(u8 *ptr, u32 len, struct parsed_ies *ies)
+{
+ s32 err = BCME_OK;
+
+ memset(ies, 0, sizeof(struct parsed_ies));
+
+ /* find the WPSIE */
+ if ((ies->wps_ie = wl_cfgp2p_find_wpsie(ptr, len)) != NULL) {
+ AP6210_DEBUG("WPSIE in beacon \n");
+ ies->wps_ie_len = ies->wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
+ } else {
+ AP6210_ERR("No WPSIE in beacon \n");
+ }
+
+ /* find the RSN_IE */
+ if ((ies->wpa2_ie = bcm_parse_tlvs(ptr, len,
+ DOT11_MNG_RSN_ID)) != NULL) {
+ AP6210_DEBUG(" WPA2 IE found\n");
+ ies->wpa2_ie_len = ies->wpa2_ie->len;
+ }
+
+ /* find the WPA_IE */
+ if ((ies->wpa_ie = wl_cfgp2p_find_wpaie(ptr, len)) != NULL) {
+ AP6210_DEBUG(" WPA found\n");
+ ies->wpa_ie_len = ies->wpa_ie->length;
+ }
+
+ return err;
+
+}
+
+static s32
+wl_cfg80211_bcn_bringup_ap(
+ struct net_device *dev,
+ struct parsed_ies *ies,
+ u32 dev_role, s32 bssidx)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct wl_join_params join_params;
+ bool is_bssup = false;
+ s32 infra = 1;
+ s32 join_params_size = 0;
+ s32 ap = 1;
+ s32 err = BCME_OK;
+
+ AP6210_DEBUG("Enter dev_role: %d\n", dev_role);
+
+ /* Common code for SoftAP and P2P GO */
+ wldev_iovar_setint(dev, "mpc", 0);
+
+ if (dev_role == NL80211_IFTYPE_P2P_GO) {
+ is_bssup = wl_cfgp2p_bss_isup(dev, bssidx);
+ if (!is_bssup && (ies->wpa2_ie != NULL)) {
+
+ err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+ if (err < 0) {
+ AP6210_ERR("SET INFRA error %d\n", err);
+ goto exit;
+ }
+
+ err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p->ssid,
+ sizeof(wl->p2p->ssid), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
+ bssidx, &wl->ioctl_buf_sync);
+ if (err < 0) {
+ AP6210_ERR("GO SSID setting error %d\n", err);
+ goto exit;
+ }
+
+ if ((err = wl_cfgp2p_bss(wl, dev, bssidx, 1)) < 0) {
+ AP6210_ERR("GO Bring up error %d\n", err);
+ goto exit;
+ }
+ } else
+ AP6210_DEBUG("Bss is already up\n");
+ } else if ((dev_role == NL80211_IFTYPE_AP) &&
+ (wl_get_drv_status(wl, AP_CREATING, dev))) {
+ /* Device role SoftAP */
+ err = wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), true);
+ if (err < 0) {
+ AP6210_ERR("WLC_DOWN error %d\n", err);
+ goto exit;
+ }
+ err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+ if (err < 0) {
+ AP6210_ERR("SET INFRA error %d\n", err);
+ goto exit;
+ }
+ if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) {
+ AP6210_ERR("setting AP mode failed %d \n", err);
+ goto exit;
+ }
+
+ err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_UP error (%d)\n", err);
+ goto exit;
+ }
+
+ memset(&join_params, 0, sizeof(join_params));
+ /* join parameters starts with ssid */
+ join_params_size = sizeof(join_params.ssid);
+ memcpy(join_params.ssid.SSID, wl->hostapd_ssid.SSID,
+ wl->hostapd_ssid.SSID_len);
+ join_params.ssid.SSID_len = htod32(wl->hostapd_ssid.SSID_len);
+
+ /* create softap */
+ if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
+ join_params_size, true)) == 0) {
+ AP6210_DEBUG("SoftAP set SSID (%s) success\n", join_params.ssid.SSID);
+ wl_clr_drv_status(wl, AP_CREATING, dev);
+ wl_set_drv_status(wl, AP_CREATED, dev);
+ }
+ }
+
+
+exit:
+ return err;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+s32
+wl_cfg80211_parse_set_ies(
+ struct net_device *dev,
+ struct cfg80211_beacon_data *info,
+ struct parsed_ies *ies,
+ u32 dev_role,
+ s32 bssidx)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct parsed_ies prb_ies;
+ s32 err = BCME_OK;
+
+ memset(ies, 0, sizeof(struct parsed_ies));
+ memset(&prb_ies, 0, sizeof(struct parsed_ies));
+
+ /* Parse Beacon IEs */
+ if (wl_cfg80211_parse_ies((u8 *)info->tail,
+ info->tail_len, ies) < 0) {
+ AP6210_ERR("Beacon get IEs failed \n");
+ err = -EINVAL;
+ goto fail;
+ }
+
+ /* Set Beacon IEs to FW */
+ if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx,
+ VNDR_IE_BEACON_FLAG, (u8 *)info->tail,
+ info->tail_len)) < 0) {
+ AP6210_ERR("Set Beacon IE Failed \n");
+ } else {
+ AP6210_DEBUG("Applied Vndr IEs for Beacon \n");
+ }
+
+ /* Parse Probe Response IEs */
+ if (wl_cfg80211_parse_ies((u8 *)info->proberesp_ies,
+ info->proberesp_ies_len, &prb_ies) < 0) {
+ AP6210_ERR("PRB RESP get IEs failed \n");
+ err = -EINVAL;
+ goto fail;
+ }
+
+ /* Set Probe Response IEs to FW */
+ if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx,
+ VNDR_IE_PRBRSP_FLAG, (u8 *)info->proberesp_ies,
+ info->proberesp_ies_len)) < 0) {
+ AP6210_ERR("Set Probe Resp IE Failed \n");
+ } else {
+ AP6210_DEBUG("Applied Vndr IEs for Probe Resp \n");
+ }
+
+fail:
+
+ return err;
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
+
+static s32 wl_cfg80211_hostapd_sec(
+ struct net_device *dev,
+ struct parsed_ies *ies,
+ s32 bssidx)
+{
+ bool update_bss = 0;
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+
+ if (ies->wps_ie) {
+ if (wl->ap_info->wps_ie &&
+ memcmp(wl->ap_info->wps_ie, ies->wps_ie, ies->wps_ie_len)) {
+ AP6210_DEBUG(" WPS IE is changed\n");
+ kfree(wl->ap_info->wps_ie);
+ wl->ap_info->wps_ie = kmemdup(ies->wps_ie, ies->wps_ie_len, GFP_KERNEL);
+ } else if (wl->ap_info->wps_ie == NULL) {
+ AP6210_DEBUG(" WPS IE is added\n");
+ wl->ap_info->wps_ie = kmemdup(ies->wps_ie, ies->wps_ie_len, GFP_KERNEL);
+ }
+ if ((ies->wpa_ie != NULL || ies->wpa2_ie != NULL)) {
+ if (!wl->ap_info->security_mode) {
+ /* change from open mode to security mode */
+ update_bss = true;
+ if (ies->wpa_ie != NULL) {
+ wl->ap_info->wpa_ie = kmemdup(ies->wpa_ie,
+ ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
+ GFP_KERNEL);
+ } else {
+ wl->ap_info->rsn_ie = kmemdup(ies->wpa2_ie,
+ ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
+ GFP_KERNEL);
+ }
+ } else if (wl->ap_info->wpa_ie) {
+ /* change from WPA2 mode to WPA mode */
+ if (ies->wpa_ie != NULL) {
+ update_bss = true;
+ kfree(wl->ap_info->rsn_ie);
+ wl->ap_info->rsn_ie = NULL;
+ wl->ap_info->wpa_ie = kmemdup(ies->wpa_ie,
+ ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
+ GFP_KERNEL);
+ } else if (memcmp(wl->ap_info->rsn_ie,
+ ies->wpa2_ie, ies->wpa2_ie->len
+ + WPA_RSN_IE_TAG_FIXED_LEN)) {
+ update_bss = true;
+ kfree(wl->ap_info->rsn_ie);
+ wl->ap_info->rsn_ie = kmemdup(ies->wpa2_ie,
+ ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
+ GFP_KERNEL);
+ wl->ap_info->wpa_ie = NULL;
+ }
+ }
+ if (update_bss) {
+ wl->ap_info->security_mode = true;
+ wl_cfgp2p_bss(wl, dev, bssidx, 0);
+ if (wl_validate_wpa2ie(dev, ies->wpa2_ie, bssidx) < 0 ||
+ wl_validate_wpaie(dev, ies->wpa_ie, bssidx) < 0) {
+ return BCME_ERROR;
+ }
+ wl_cfgp2p_bss(wl, dev, bssidx, 1);
+ }
+ }
+ } else {
+ AP6210_ERR("No WPSIE in beacon \n");
+ }
+ return 0;
+}
+
+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \
+ 2, 0))
+static s32
+wl_cfg80211_del_station(
+ struct wiphy *wiphy,
+ struct net_device *ndev,
+ u8* mac_addr)
+{
+ struct net_device *dev;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ scb_val_t scb_val;
+ s8 eabuf[ETHER_ADDR_STR_LEN];
+
+ AP6210_DEBUG("Entry\n");
+ if (mac_addr == NULL) {
+ AP6210_DEBUG("mac_addr is NULL ignore it\n");
+ return 0;
+ }
+
+ if (ndev == wl->p2p_net) {
+ dev = wl_to_prmry_ndev(wl);
+ } else {
+ dev = ndev;
+ }
+
+ if (p2p_is_on(wl)) {
+ /* Suspend P2P discovery search-listen to prevent it from changing the
+ * channel.
+ */
+ if ((wl_cfgp2p_discover_enable_search(wl, false)) < 0) {
+ AP6210_ERR("Can not disable discovery mode\n");
+ return -EFAULT;
+ }
+ }
+
+ memcpy(scb_val.ea.octet, mac_addr, ETHER_ADDR_LEN);
+ scb_val.val = DOT11_RC_DEAUTH_LEAVING;
+ if (wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
+ sizeof(scb_val_t), true))
+ AP6210_ERR("WLC_SCB_DEAUTHENTICATE_FOR_REASON failed\n");
+ AP6210_DEBUG("Disconnect STA : %s scb_val.val %d\n",
+ bcm_ether_ntoa((const struct ether_addr *)mac_addr, eabuf),
+ scb_val.val);
+ wl_delay(400);
+ return 0;
+}
+#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VER >= KERNEL_VERSION(3, 2, 0)) */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+static s32
+wl_cfg80211_start_ap(
+ struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_ap_settings *info)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ s32 err = BCME_OK;
+ struct parsed_ies ies;
+ s32 bssidx = 0;
+ u32 dev_role = 0;
+
+ AP6210_DEBUG("Enter \n");
+ if (dev == wl_to_prmry_ndev(wl)) {
+ AP6210_DEBUG("Start AP req on primary iface: Softap\n");
+ dev_role = NL80211_IFTYPE_AP;
+ } else if (dev == wl->p2p_net) {
+ /* Group Add request on p2p0 */
+ AP6210_DEBUG("Start AP req on P2P iface: GO\n");
+ dev = wl_to_prmry_ndev(wl);
+ dev_role = NL80211_IFTYPE_P2P_GO;
+ }
+
+ bssidx = wl_cfgp2p_find_idx(wl, dev);
+ if (p2p_is_on(wl) &&
+ (bssidx == wl_to_p2p_bss_bssidx(wl,
+ P2PAPI_BSSCFG_CONNECTION))) {
+ dev_role = NL80211_IFTYPE_P2P_GO;
+ AP6210_DEBUG("Start AP req on P2P connection iface\n");
+ }
+
+ if ((err = wl_cfg80211_bcn_set_params(info, dev,
+ dev_role, bssidx)) < 0) {
+ AP6210_ERR("Beacon params set failed \n");
+ goto fail;
+ }
+
+ /* Set IEs to FW */
+ if ((err = wl_cfg80211_parse_set_ies(dev, &info->beacon,
+ &ies, dev_role, bssidx) < 0)) {
+ AP6210_ERR("Set IEs failed \n");
+ goto fail;
+ }
+
+ if ((wl_cfg80211_bcn_validate_sec(dev, &ies,
+ dev_role, bssidx)) < 0)
+ {
+ AP6210_ERR("Beacon set security failed \n");
+ goto fail;
+ }
+
+ if ((err = wl_cfg80211_bcn_bringup_ap(dev, &ies,
+ dev_role, bssidx)) < 0) {
+ AP6210_ERR("Beacon bring up AP/GO failed \n");
+ goto fail;
+ }
+
+ AP6210_DEBUG("** AP/GO Created **\n");
+
+fail:
+ if (err) {
+ AP6210_ERR("ADD/SET beacon failed\n");
+ wldev_iovar_setint(dev, "mpc", 1);
+ }
+
+ return err;
+}
+
+static s32
+wl_cfg80211_stop_ap(
+ struct wiphy *wiphy,
+ struct net_device *dev)
+{
+ int err = 0;
+ u32 dev_role = 0;
+ int infra = 0;
+ int ap = 0;
+ s32 bssidx = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+
+ AP6210_DEBUG("Enter \n");
+ if (dev == wl_to_prmry_ndev(wl)) {
+ dev_role = NL80211_IFTYPE_AP;
+ } else if (dev == wl->p2p_net) {
+ /* Group Add request on p2p0 */
+ dev = wl_to_prmry_ndev(wl);
+ dev_role = NL80211_IFTYPE_P2P_GO;
+ }
+ bssidx = wl_cfgp2p_find_idx(wl, dev);
+ if (p2p_is_on(wl) &&
+ (bssidx == wl_to_p2p_bss_bssidx(wl,
+ P2PAPI_BSSCFG_CONNECTION))) {
+ dev_role = NL80211_IFTYPE_P2P_GO;
+ }
+
+ if (dev_role == NL80211_IFTYPE_AP) {
+ /* SoftAp on primary Interface.
+ * Shut down AP and turn on MPC
+ */
+ err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+ if (err < 0) {
+ AP6210_ERR("SET INFRA error %d\n", err);
+ err = -ENOTSUPP;
+ goto exit;
+ }
+ if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) {
+ AP6210_ERR("setting AP mode failed %d \n", err);
+ err = -ENOTSUPP;
+ goto exit;
+ }
+
+ err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_UP error (%d)\n", err);
+ err = -EINVAL;
+ goto exit;
+ }
+
+ wl_clr_drv_status(wl, AP_CREATED, dev);
+ /* Turn on the MPC */
+ wldev_iovar_setint(dev, "mpc", 1);
+ } else {
+ AP6210_DEBUG("Stopping P2P GO \n");
+ }
+
+exit:
+ return err;
+}
+
+static s32
+wl_cfg80211_change_beacon(
+ struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_beacon_data *info)
+{
+ s32 err = BCME_OK;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct parsed_ies ies;
+ u32 dev_role = 0;
+ s32 bssidx = 0;
+
+ AP6210_DEBUG("Enter \n");
+
+ if (dev == wl_to_prmry_ndev(wl)) {
+ dev_role = NL80211_IFTYPE_AP;
+ } else if (dev == wl->p2p_net) {
+ /* Group Add request on p2p0 */
+ dev = wl_to_prmry_ndev(wl);
+ dev_role = NL80211_IFTYPE_P2P_GO;
+ }
+
+ bssidx = wl_cfgp2p_find_idx(wl, dev);
+ if (p2p_is_on(wl) &&
+ (bssidx == wl_to_p2p_bss_bssidx(wl,
+ P2PAPI_BSSCFG_CONNECTION))) {
+ dev_role = NL80211_IFTYPE_P2P_GO;
+ }
+
+ /* Set IEs to FW */
+ if ((err = wl_cfg80211_parse_set_ies(dev, info,
+ &ies, dev_role, bssidx) < 0)) {
+ AP6210_ERR("Set IEs failed \n");
+ goto fail;
+ }
+
+ if (dev_role == NL80211_IFTYPE_AP) {
+ if (wl_cfg80211_hostapd_sec(dev, &ies, bssidx) < 0) {
+ AP6210_ERR("Hostapd update sec failed \n");
+ err = -EINVAL;
+ goto fail;
+ }
+ }
+
+fail:
+ return err;
+}
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) */
+static s32
+wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
+ struct beacon_parameters *info)
+{
+ s32 err = BCME_OK;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ s32 ie_offset = 0;
+ s32 bssidx = 0;
+ u32 dev_role = NL80211_IFTYPE_AP;
+ struct parsed_ies ies;
+ bcm_tlv_t *ssid_ie;
+ bool pbc = 0;
+
+ AP6210_DEBUG("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
+ info->interval, info->dtim_period, info->head_len, info->tail_len);
+
+ if (dev == wl_to_prmry_ndev(wl)) {
+ dev_role = NL80211_IFTYPE_AP;
+ } else if (dev == wl->p2p_net) {
+ /* Group Add request on p2p0 */
+ dev = wl_to_prmry_ndev(wl);
+ dev_role = NL80211_IFTYPE_P2P_GO;
+ }
+
+ bssidx = wl_cfgp2p_find_idx(wl, dev);
+ if (p2p_is_on(wl) &&
+ (bssidx == wl_to_p2p_bss_bssidx(wl,
+ P2PAPI_BSSCFG_CONNECTION))) {
+ dev_role = NL80211_IFTYPE_P2P_GO;
+ }
+
+ ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
+ /* find the SSID */
+ if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
+ info->head_len - ie_offset,
+ DOT11_MNG_SSID_ID)) != NULL) {
+ if (dev_role == NL80211_IFTYPE_AP) {
+ /* Store the hostapd SSID */
+ memset(&wl->hostapd_ssid.SSID[0], 0x00, 32);
+ memcpy(&wl->hostapd_ssid.SSID[0], ssid_ie->data, ssid_ie->len);
+ wl->hostapd_ssid.SSID_len = ssid_ie->len;
+ } else {
+ /* P2P GO */
+ memset(&wl->p2p->ssid.SSID[0], 0x00, 32);
+ memcpy(wl->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len);
+ wl->p2p->ssid.SSID_len = ssid_ie->len;
+ }
+ }
+
+ if (wl_cfg80211_parse_ies((u8 *)info->tail,
+ info->tail_len, &ies) < 0) {
+ AP6210_ERR("Beacon get IEs failed \n");
+ err = -EINVAL;
+ goto fail;
+ }
+
+ if (wl_cfgp2p_set_management_ie(wl, dev, bssidx,
+ VNDR_IE_BEACON_FLAG, (u8 *)info->tail,
+ info->tail_len) < 0) {
+ AP6210_ERR("Beacon set IEs failed \n");
+ goto fail;
+ } else {
+ AP6210_DEBUG("Applied Vndr IEs for Beacon \n");
+ }
+ if (!wl_cfgp2p_bss_isup(dev, bssidx) &&
+ (wl_cfg80211_bcn_validate_sec(dev, &ies, dev_role, bssidx) < 0))
+ {
+ AP6210_ERR("Beacon set security failed \n");
+ goto fail;
+ }
+
+ /* Set BI and DTIM period */
+ if (info->interval) {
+ if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD,
+ &info->interval, sizeof(s32), true)) < 0) {
+ AP6210_ERR("Beacon Interval Set Error, %d\n", err);
+ return err;
+ }
+ }
+ if (info->dtim_period) {
+ if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
+ &info->dtim_period, sizeof(s32), true)) < 0) {
+ AP6210_ERR("DTIM Interval Set Error, %d\n", err);
+ return err;
+ }
+ }
+
+ if (wl_cfg80211_bcn_bringup_ap(dev, &ies, dev_role, bssidx) < 0) {
+ AP6210_ERR("Beacon bring up AP/GO failed \n");
+ goto fail;
+ }
+
+ if (wl_get_drv_status(wl, AP_CREATED, dev)) {
+ /* Soft AP already running. Update changed params */
+ if (wl_cfg80211_hostapd_sec(dev, &ies, bssidx) < 0) {
+ AP6210_ERR("Hostapd update sec failed \n");
+ err = -EINVAL;
+ goto fail;
+ }
+ }
+
+ /* Enable Probe Req filter */
+ if (((dev_role == NL80211_IFTYPE_P2P_GO) ||
+ (dev_role == NL80211_IFTYPE_AP)) && (ies.wps_ie != NULL)) {
+ wl_validate_wps_ie((char *) ies.wps_ie, ies.wps_ie_len, &pbc);
+ if (pbc)
+ wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, true);
+ }
+
+ AP6210_DEBUG("** ADD/SET beacon done **\n");
+
+fail:
+ if (err) {
+ AP6210_ERR("ADD/SET beacon failed\n");
+ wldev_iovar_setint(dev, "mpc", 1);
+ }
+ return err;
+
+}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) */
+
+#ifdef WL_SCHED_SCAN
+#define PNO_TIME 30
+#define PNO_REPEAT 4
+#define PNO_FREQ_EXPO_MAX 2
+int wl_cfg80211_sched_scan_start(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_sched_scan_request *request)
+{
+ ushort pno_time = PNO_TIME;
+ int pno_repeat = PNO_REPEAT;
+ int pno_freq_expo_max = PNO_FREQ_EXPO_MAX;
+ wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct cfg80211_ssid *ssid = NULL;
+ int ssid_count = 0;
+ int i;
+ int ret = 0;
+
+ AP6210_DEBUG("Enter \n");
+ AP6210_DEBUG(">>> SCHED SCAN START\n");
+ AP6210_DEBUG("Enter n_match_sets:%d n_ssids:%d \n",
+ request->n_match_sets, request->n_ssids);
+ AP6210_DEBUG("ssids:%d pno_time:%d pno_repeat:%d pno_freq:%d \n",
+ request->n_ssids, pno_time, pno_repeat, pno_freq_expo_max);
+
+
+ if (!request || !request->n_ssids || !request->n_match_sets) {
+ AP6210_ERR("Invalid sched scan req!! n_ssids:%d \n", request->n_ssids);
+ return -EINVAL;
+ }
+
+ memset(&ssids_local, 0, sizeof(ssids_local));
+
+ if (request->n_match_sets > 0) {
+ for (i = 0; i < request->n_match_sets; i++) {
+ ssid = &request->match_sets[i].ssid;
+ memcpy(ssids_local[i].SSID, ssid->ssid, ssid->ssid_len);
+ ssids_local[i].SSID_len = ssid->ssid_len;
+ AP6210_DEBUG(">>> PNO filter set for ssid (%s) \n", ssid->ssid);
+ ssid_count++;
+ }
+ }
+
+ if (request->n_ssids > 0) {
+ for (i = 0; i < request->n_ssids; i++) {
+ /* Active scan req for ssids */
+ AP6210_DEBUG(">>> Active scan req for ssid (%s) \n", request->ssids[i].ssid);
+
+ /* match_set ssids is a supert set of n_ssid list, so we need
+ * not add these set seperately
+ */
+ }
+ }
+
+ if (ssid_count) {
+ if ((ret = dhd_dev_pno_set(dev, ssids_local, request->n_match_sets,
+ pno_time, pno_repeat, pno_freq_expo_max)) < 0) {
+ AP6210_ERR("PNO setup failed!! ret=%d \n", ret);
+ return -EINVAL;
+ }
+
+ /* Enable the PNO */
+ if (dhd_dev_pno_enable(dev, 1) < 0) {
+ AP6210_ERR("PNO enable failed!! ret=%d \n", ret);
+ return -EINVAL;
+ }
+ wl->sched_scan_req = request;
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
+{
+ struct wl_priv *wl = wiphy_priv(wiphy);
+
+ AP6210_DEBUG("Enter \n");
+ AP6210_DEBUG(">>> SCHED SCAN STOP\n");
+
+ if (dhd_dev_pno_enable(dev, 0) < 0)
+ AP6210_ERR("PNO disable failed");
+
+ if (dhd_dev_pno_reset(dev) < 0)
+ AP6210_ERR("PNO reset failed");
+
+ if (wl->scan_request && wl->sched_scan_running) {
+ AP6210_DEBUG(">>> Sched scan running. Aborting it..\n");
+ wl_notify_escan_complete(wl, dev, true, true);
+ }
+
+ wl->sched_scan_req = NULL;
+ wl->sched_scan_running = FALSE;
+
+ return 0;
+}
+#endif /* WL_SCHED_SCAN */
+
+static struct cfg80211_ops wl_cfg80211_ops = {
+ .add_virtual_intf = wl_cfg80211_add_virtual_iface,
+ .del_virtual_intf = wl_cfg80211_del_virtual_iface,
+ .change_virtual_intf = wl_cfg80211_change_virtual_iface,
+ .scan = wl_cfg80211_scan,
+ .set_wiphy_params = wl_cfg80211_set_wiphy_params,
+ .join_ibss = wl_cfg80211_join_ibss,
+ .leave_ibss = wl_cfg80211_leave_ibss,
+ .get_station = wl_cfg80211_get_station,
+ .set_tx_power = wl_cfg80211_set_tx_power,
+ .get_tx_power = wl_cfg80211_get_tx_power,
+ .add_key = wl_cfg80211_add_key,
+ .del_key = wl_cfg80211_del_key,
+ .get_key = wl_cfg80211_get_key,
+ .set_default_key = wl_cfg80211_config_default_key,
+ .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
+ .set_power_mgmt = wl_cfg80211_set_power_mgmt,
+ .connect = wl_cfg80211_connect,
+ .disconnect = wl_cfg80211_disconnect,
+ .suspend = wl_cfg80211_suspend,
+ .resume = wl_cfg80211_resume,
+ .set_pmksa = wl_cfg80211_set_pmksa,
+ .del_pmksa = wl_cfg80211_del_pmksa,
+ .flush_pmksa = wl_cfg80211_flush_pmksa,
+ .remain_on_channel = wl_cfg80211_remain_on_channel,
+ .cancel_remain_on_channel = wl_cfg80211_cancel_remain_on_channel,
+ .mgmt_tx = wl_cfg80211_mgmt_tx,
+ .mgmt_frame_register = wl_cfg80211_mgmt_frame_register,
+ .change_bss = wl_cfg80211_change_bss,
+ .set_channel = wl_cfg80211_set_channel,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
+ .set_beacon = wl_cfg80211_add_set_beacon,
+ .add_beacon = wl_cfg80211_add_set_beacon,
+#else
+ .change_beacon = wl_cfg80211_change_beacon,
+ .start_ap = wl_cfg80211_start_ap,
+ .stop_ap = wl_cfg80211_stop_ap,
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) */
+#ifdef WL_SCHED_SCAN
+ .sched_scan_start = wl_cfg80211_sched_scan_start,
+ .sched_scan_stop = wl_cfg80211_sched_scan_stop,
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */
+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \
+ 2, 0))
+ .del_station = wl_cfg80211_del_station,
+ .mgmt_tx_cancel_wait = wl_cfg80211_mgmt_tx_cancel_wait,
+#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VERSION >= (3,2,0) */
+};
+
+s32 wl_mode_to_nl80211_iftype(s32 mode)
+{
+ s32 err = 0;
+
+ switch (mode) {
+ case WL_MODE_BSS:
+ return NL80211_IFTYPE_STATION;
+ case WL_MODE_IBSS:
+ return NL80211_IFTYPE_ADHOC;
+ case WL_MODE_AP:
+ return NL80211_IFTYPE_AP;
+ default:
+ return NL80211_IFTYPE_UNSPECIFIED;
+ }
+
+ return err;
+}
+
+static int
+wl_cfg80211_reg_notifier(
+ struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy);
+ wl_country_t cspec = {{0}, 0, {0} };
+ int ret = 0;
+
+ if (!request || !wl) {
+ AP6210_ERR("Invalid arg\n");
+ return -EINVAL;
+ }
+
+ AP6210_DEBUG("ccode: %c%c Initiator: %d\n",
+ request->alpha2[0], request->alpha2[1], request->initiator);
+
+ /* We support only REGDOM_SET_BY_USER as of now */
+ if (request->initiator != NL80211_REGDOM_SET_BY_USER) {
+ AP6210_ERR("reg_notifier for intiator:%d not supported \n",
+ request->initiator);
+ return -ENOTSUPP;
+ }
+
+ if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
+ /* world domain */
+ AP6210_ERR("World domain. Setting XY/4 \n");
+ strncpy(cspec.country_abbrev, "XY", strlen("XY"));
+ cspec.rev = 4;
+ } else {
+ memcpy(cspec.country_abbrev, request->alpha2, 2);
+ cspec.country_abbrev[3] = '\0';
+ cspec.rev = -1; /* Unspecified */
+ }
+
+ if ((ret = wldev_iovar_setbuf(wl_to_prmry_ndev(wl), "country", (char *)&cspec,
+ sizeof(cspec), wl->ioctl_buf, WLC_IOCTL_SMLEN, NULL)) < 0) {
+ AP6210_ERR("set country Failed :%d\n", ret);
+ goto exit;
+ }
+
+ if ((ret = wl_update_wiphybands(wl, false)) < 0) {
+ AP6210_ERR("wl_update_wiphybands failed\n");
+ goto exit;
+ }
+
+ AP6210_DEBUG("%s: set country '%s/%d' done\n",
+ __FUNCTION__, cspec.country_abbrev, cspec.rev);
+
+exit:
+ return ret;
+}
+
+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev)
+{
+ s32 err = 0;
+ wdev->wiphy =
+ wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv));
+ if (unlikely(!wdev->wiphy)) {
+ AP6210_ERR("Couldn not allocate wiphy device\n");
+ err = -ENOMEM;
+ return err;
+ }
+ set_wiphy_dev(wdev->wiphy, sdiofunc_dev);
+ wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
+ /* Report how many SSIDs Driver can support per Scan request */
+ wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX;
+ wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
+#ifdef WL_SCHED_SCAN
+ wdev->wiphy->max_sched_scan_ssids = MAX_PFN_LIST_COUNT;
+ wdev->wiphy->max_match_sets = MAX_PFN_LIST_COUNT;
+ wdev->wiphy->max_sched_scan_ie_len = WL_SCAN_IE_LEN_MAX;
+ wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+#endif /* WL_SCHED_SCAN */
+ wdev->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION)
+#if !(defined(WLP2P) && defined(WL_ENABLE_P2P_IF))
+ | BIT(NL80211_IFTYPE_MONITOR)
+#endif
+ | BIT(NL80211_IFTYPE_AP);
+
+ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
+
+ wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+ wdev->wiphy->cipher_suites = __wl_cipher_suites;
+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
+ wdev->wiphy->max_remain_on_channel_duration = 5000;
+ wdev->wiphy->mgmt_stypes = wl_cfg80211_default_mgmt_stypes;
+#ifndef WL_POWERSAVE_DISABLED
+ wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
+#else
+ wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+#endif /* !WL_POWERSAVE_DISABLED */
+ wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK |
+ WIPHY_FLAG_4ADDR_AP |
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)
+ WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS |
+#endif
+ WIPHY_FLAG_4ADDR_STATION;
+ /* If driver advertises FW_ROAM, the supplicant wouldn't
+ * send the BSSID & Freq in the connect command allowing the
+ * the driver to choose the AP to connect to. But unless we
+ * support ROAM_CACHE in firware this will delay the ASSOC as
+ * as the FW need to do a full scan before attempting to connect
+ * So that feature will just increase assoc. The better approach
+ * to let Supplicant to provide channel info and FW letter may roam
+ * if needed so DON'T advertise that featur eto Supplicant.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
+ /* wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+ wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
+ WIPHY_FLAG_OFFCHAN_TX;
+#endif
+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \
+ 4, 0))
+ /* From 3.4 kernel ownards AP_SME flag can be advertised
+ * to remove the patch from supplicant
+ */
+ wdev->wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
+#endif
+
+ wdev->wiphy->reg_notifier = wl_cfg80211_reg_notifier;
+
+ AP6210_DEBUG("Registering custom regulatory)\n");
+ wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+ wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
+ /* Now we can register wiphy with cfg80211 module */
+ err = wiphy_register(wdev->wiphy);
+ if (unlikely(err < 0)) {
+ AP6210_ERR("Couldn not register wiphy device (%d)\n", err);
+ wiphy_free(wdev->wiphy);
+ }
+ return err;
+}
+
+static void wl_free_wdev(struct wl_priv *wl)
+{
+ struct wireless_dev *wdev = wl->wdev;
+ struct wiphy *wiphy;
+ if (!wdev) {
+ AP6210_ERR("wdev is invalid\n");
+ return;
+ }
+ wiphy = wdev->wiphy;
+ wiphy_unregister(wdev->wiphy);
+ wdev->wiphy->dev.parent = NULL;
+
+ wl_delete_all_netinfo(wl);
+ wiphy_free(wiphy);
+ /* PLEASE do NOT call any function after wiphy_free, the driver's private structure "wl",
+ * which is the private part of wiphy, has been freed in wiphy_free !!!!!!!!!!!
+ */
+}
+
+#if defined(RSSIAVG)
+static wl_rssi_cache_ctrl_t g_rssi_cache_ctrl;
+#endif
+#if defined(BSSCACHE)
+static wl_bss_cache_ctrl_t g_bss_cache_ctrl;
+#endif
+
+static s32 wl_inform_bss(struct wl_priv *wl)
+{
+ struct wl_scan_results *bss_list;
+ struct wl_bss_info *bi = NULL; /* must be initialized */
+ s32 err = 0;
+ s32 i;
+#if defined(RSSIAVG)
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+#endif
+#if defined(BSSCACHE)
+ wl_bss_cache_t *node;
+#endif
+
+ bss_list = wl->bss_list;
+#if defined(BSSCACHE)
+ if (g_bss_cache_ctrl.m_timer_expired || (p2p_is_on(wl) && p2p_scan(wl))) {
+#if defined(RSSIAVG)
+ wl_free_rssi_cache(&g_rssi_cache_ctrl);
+#endif
+ wl_free_bss_cache(&g_bss_cache_ctrl);
+ g_bss_cache_ctrl.m_timer_expired ^= 1;
+ }
+ wl_update_bss_cache(&g_bss_cache_ctrl, bss_list);
+ wl_delete_dirty_bss_cache(&g_bss_cache_ctrl);
+ wl_reset_bss_cache(&g_bss_cache_ctrl);
+#endif
+
+#if defined(RSSIAVG)
+#if defined(BSSCACHE)
+ node = g_bss_cache_ctrl.m_cache_head;
+ for (;node;) {
+ wl_update_rssi_cache(&g_rssi_cache_ctrl, &node->results);
+ node = node->next;
+ }
+#else
+ wl_update_rssi_cache(&g_rssi_cache_ctrl, bss_list);
+#endif
+ if (!in_atomic())
+ wl_update_connected_rssi_cache(&g_rssi_cache_ctrl, ndev);
+ wl_delete_dirty_rssi_cache(&g_rssi_cache_ctrl);
+ wl_reset_rssi_cache(&g_rssi_cache_ctrl);
+#endif
+
+ AP6210_DEBUG("scanned AP count (%d)\n", bss_list->count);
+
+#if defined(BSSCACHE)
+ node = g_bss_cache_ctrl.m_cache_head;
+ for (i=0; node && i<WL_AP_MAX; i++) {
+ bi = node->results.bss_info;
+ err = wl_inform_single_bss(wl, bi, 0);
+ if (unlikely(err))
+ break;
+ node = node->next;
+ }
+ wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0);
+ wl_run_bss_cache_timer(&g_bss_cache_ctrl, 1);
+#else
+ bi = next_bss(bss_list, bi);
+ for_each_bss(bss_list, bi, i) {
+ err = wl_inform_single_bss(wl, bi, 0);
+ if (unlikely(err))
+ break;
+ }
+#endif
+ return err;
+}
+
+static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done)
+{
+ struct wiphy *wiphy = wl_to_wiphy(wl);
+ struct ieee80211_mgmt *mgmt;
+ struct ieee80211_channel *channel;
+ struct ieee80211_supported_band *band;
+ struct wl_cfg80211_bss_info *notif_bss_info;
+ struct wl_scan_req *sr = wl_to_sr(wl);
+ struct beacon_proberesp *beacon_proberesp;
+ struct cfg80211_bss *cbss = NULL;
+ s32 mgmt_type;
+ s32 signal;
+ u32 freq;
+ s32 err = 0;
+ gfp_t aflags;
+ u8 *ie_offset = NULL;
+
+ if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
+ AP6210_DEBUG("Beacon is larger than buffer. Discarding\n");
+ return err;
+ }
+ aflags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
+ notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt)
+ - sizeof(u8) + WL_BSS_INFO_MAX, aflags);
+ if (unlikely(!notif_bss_info)) {
+ AP6210_ERR("notif_bss_info alloc failed\n");
+ return -ENOMEM;
+ }
+ mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
+ notif_bss_info->channel =
+ bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(wl_chspec_driver_to_host(bi->chanspec));
+
+ if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ else
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ if (!band) {
+ AP6210_ERR("No valid band");
+ kfree(notif_bss_info);
+ return -EINVAL;
+ }
+ notif_bss_info->rssi = dtoh16(bi->RSSI);
+#if defined(RSSIAVG)
+ notif_bss_info->rssi = wl_get_avg_rssi(&g_rssi_cache_ctrl, &bi->BSSID);
+#endif
+#if defined(RSSIOFFSET)
+ notif_bss_info->rssi = wl_update_rssi_offset(notif_bss_info->rssi);
+#endif
+ memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
+ mgmt_type = wl->active_scan ?
+ IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
+ if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type);
+ }
+ beacon_proberesp = wl->active_scan ?
+ (struct beacon_proberesp *)&mgmt->u.probe_resp :
+ (struct beacon_proberesp *)&mgmt->u.beacon;
+ beacon_proberesp->timestamp = 0;
+ beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
+ beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
+ wl_rst_ie(wl);
+
+ ie_offset = ((u8 *) bi) + bi->ie_offset;
+
+ if (is_roam_done && ((int)(*(ie_offset)) == WLAN_EID_SSID &&
+ ((int)(*(ie_offset+1)) == 0 || (int)(*(ie_offset+2)) == 0))) {
+ u8 *ie_new_offset = NULL;
+ uint8 ie_new_length;
+
+ AP6210_ERR("WAR trace: Changing the SSID Info, from beacon %d\n",
+ bi->flags & WL_BSS_FLAGS_FROM_BEACON);
+
+ ie_new_offset = (u8 *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+ if (ie_new_offset) {
+ *(ie_new_offset) = WLAN_EID_SSID;
+ *(ie_new_offset+1) = bi->SSID_len;
+ memcpy(ie_new_offset+2, bi->SSID, bi->SSID_len);
+ ie_new_length = bi->ie_length - *(ie_offset+1) + bi->SSID_len;
+
+ /* Copy the remaining IE apart from SSID IE from bi */
+ memcpy(ie_new_offset+2 + bi->SSID_len,
+ ie_offset+2 + *(ie_offset+1),
+ bi->ie_length - 2 - *(ie_offset+1));
+ wl_mrg_ie(wl, ie_new_offset, ie_new_length);
+ kfree(ie_new_offset);
+ } else {
+ wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
+ }
+ } else {
+ wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
+ }
+
+ wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
+ offsetof(struct wl_cfg80211_bss_info, frame_buf));
+ notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
+ u.beacon.variable) + wl_get_ielen(wl);
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+ freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
+ (void)band->band;
+#else
+ freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
+#endif
+ if (freq == 0) {
+ AP6210_ERR("Invalid channel, fail to chcnage channel to freq\n");
+ kfree(notif_bss_info);
+ return -EINVAL;
+ }
+ channel = ieee80211_get_channel(wiphy, freq);
+ if (unlikely(!channel)) {
+ AP6210_ERR("ieee80211_get_channel error\n");
+ kfree(notif_bss_info);
+ return -EINVAL;
+ }
+ AP6210_DEBUG("BSSID %pM, channel %d, rssi %d, capability 0x04%x, mgmt_type %d, "
+ "frame_len %d, SSID \"%s\"\n", &bi->BSSID, notif_bss_info->channel,
+ notif_bss_info->rssi, mgmt->u.beacon.capab_info, mgmt_type,
+ notif_bss_info->frame_len, bi->SSID);
+
+ signal = notif_bss_info->rssi * 100;
+ if (!mgmt->u.probe_resp.timestamp) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+ struct timespec ts;
+ get_monotonic_boottime(&ts);
+ mgmt->u.probe_resp.timestamp = ((u64)ts.tv_sec*1000000)
+ + ts.tv_nsec / 1000;
+#else
+ struct timeval tv;
+ do_gettimeofday(&tv);
+ mgmt->u.probe_resp.timestamp = ((u64)tv.tv_sec*1000000)
+ + tv.tv_usec;
+#endif
+ }
+
+ cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+ le16_to_cpu(notif_bss_info->frame_len), signal, aflags);
+ if (unlikely(!cbss)) {
+ AP6210_ERR("cfg80211_inform_bss_frame error\n");
+ kfree(notif_bss_info);
+ return -EINVAL;
+ }
+
+ cfg80211_put_bss(cbss);
+ kfree(notif_bss_info);
+ return err;
+}
+
+static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev)
+{
+ u32 event = ntoh32(e->event_type);
+ u32 status = ntoh32(e->status);
+ u16 flags = ntoh16(e->flags);
+
+ AP6210_DEBUG("event %d, status %d flags %x\n", event, status, flags);
+ if (event == WLC_E_SET_SSID) {
+ if (status == WLC_E_STATUS_SUCCESS) {
+ if (!wl_is_ibssmode(wl, ndev))
+ return true;
+ }
+ } else if (event == WLC_E_LINK) {
+ if (flags & WLC_EVENT_MSG_LINK)
+ return true;
+ }
+
+ AP6210_DEBUG("wl_is_linkup false\n");
+ return false;
+}
+
+static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
+{
+ u32 event = ntoh32(e->event_type);
+ u16 flags = ntoh16(e->flags);
+
+ if (event == WLC_E_DEAUTH_IND ||
+ event == WLC_E_DISASSOC_IND ||
+ event == WLC_E_DISASSOC ||
+ event == WLC_E_DEAUTH) {
+#if (WL_DBG_LEVEL > 0)
+ AP6210_ERR("Link down Reason : WLC_E_%s\n", wl_dbg_estr[event]);
+#endif /* (WL_DBG_LEVEL > 0) */
+ return true;
+ } else if (event == WLC_E_LINK) {
+ if (!(flags & WLC_EVENT_MSG_LINK)) {
+#if (WL_DBG_LEVEL > 0)
+ AP6210_ERR("Link down Reason : WLC_E_%s\n", wl_dbg_estr[event]);
+#endif /* (WL_DBG_LEVEL > 0) */
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
+{
+ u32 event = ntoh32(e->event_type);
+ u32 status = ntoh32(e->status);
+
+ if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS)
+ return true;
+ if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS)
+ return true;
+
+ return false;
+}
+
+/* The mainline kernel >= 3.2.0 has support for indicating new/del station
+ * to AP/P2P GO via events. If this change is backported to kernel for which
+ * this driver is being built, then define WL_CFG80211_STA_EVENT. You
+ * should use this new/del sta event mechanism for BRCM supplicant >= 22.
+ */
+static s32
+wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ s32 err = 0;
+ u32 event = ntoh32(e->event_type);
+ u32 reason = ntoh32(e->reason);
+ u32 len = ntoh32(e->datalen);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT)
+ bool isfree = false;
+ u8 *mgmt_frame;
+ u8 bsscfgidx = e->bsscfgidx;
+ s32 freq;
+ s32 channel;
+ u8 *body = NULL;
+ u16 fc = 0;
+
+ struct ieee80211_supported_band *band;
+ struct ether_addr da;
+ struct ether_addr bssid;
+ struct wiphy *wiphy = wl_to_wiphy(wl);
+ channel_info_t ci;
+#else
+ struct station_info sinfo;
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !WL_CFG80211_STA_EVENT */
+
+ AP6210_DEBUG("event %d status %d reason %d\n", event, ntoh32(e->status), reason);
+ /* if link down, bsscfg is disabled. */
+ if (event == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS &&
+ wl_get_p2p_status(wl, IF_DELETING) && (ndev != wl_to_prmry_ndev(wl))) {
+ wl_add_remove_eventmsg(ndev, WLC_E_PROBREQ_MSG, false);
+ AP6210_DEBUG("AP mode link down !! \n");
+ complete(&wl->iface_disable);
+ return 0;
+ }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT)
+ AP6210_DEBUG("Enter \n");
+ if (!len && (event == WLC_E_DEAUTH)) {
+ len = 2; /* reason code field */
+ data = &reason;
+ }
+ if (len) {
+ body = kzalloc(len, GFP_KERNEL);
+
+ if (body == NULL) {
+ AP6210_ERR("wl_notify_connect_status: Failed to allocate body\n");
+ return WL_INVALID;
+ }
+ }
+ memset(&bssid, 0, ETHER_ADDR_LEN);
+ AP6210_DEBUG("Enter event %d ndev %p\n", event, ndev);
+ if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID) {
+ kfree(body);
+ return WL_INVALID;
+ }
+ if (len)
+ memcpy(body, data, len);
+
+ wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, bsscfgidx, &wl->ioctl_buf_sync);
+ memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
+ err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+ switch (event) {
+ case WLC_E_ASSOC_IND:
+ fc = FC_ASSOC_REQ;
+ break;
+ case WLC_E_REASSOC_IND:
+ fc = FC_REASSOC_REQ;
+ break;
+ case WLC_E_DISASSOC_IND:
+ fc = FC_DISASSOC;
+ break;
+ case WLC_E_DEAUTH_IND:
+ fc = FC_DISASSOC;
+ break;
+ case WLC_E_DEAUTH:
+ fc = FC_DISASSOC;
+ break;
+ default:
+ fc = 0;
+ goto exit;
+ }
+ if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false))) {
+ kfree(body);
+ return err;
+ }
+
+ channel = dtoh32(ci.hw_channel);
+ if (channel <= CH_MAX_2G_CHANNEL)
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ else
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ if (!band) {
+ AP6210_ERR("No valid band");
+ if (body)
+ kfree(body);
+ return -EINVAL;
+ }
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+ freq = ieee80211_channel_to_frequency(channel);
+ (void)band->band;
+#else
+ freq = ieee80211_channel_to_frequency(channel, band->band);
+#endif
+
+ err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
+ &mgmt_frame, &len, body);
+ if (err < 0)
+ goto exit;
+ isfree = true;
+
+ if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
+#else
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
+ } else if (event == WLC_E_DISASSOC_IND) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
+#else
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
+ } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, len, GFP_ATOMIC);
+#else
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
+ }
+
+exit:
+ if (isfree)
+ kfree(mgmt_frame);
+ if (body)
+ kfree(body);
+ return err;
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */
+ sinfo.filled = 0;
+ if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) &&
+ reason == DOT11_SC_SUCCESS) {
+ sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
+ if (!data) {
+ AP6210_ERR("No IEs present in ASSOC/REASSOC_IND");
+ return -EINVAL;
+ }
+ sinfo.assoc_req_ies = data;
+ sinfo.assoc_req_ies_len = len;
+ cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC);
+ } else if (event == WLC_E_DISASSOC_IND) {
+ cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
+ } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+ cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
+ }
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */
+ return err;
+}
+
+static s32
+wl_get_auth_assoc_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e)
+{
+ u32 reason = ntoh32(e->reason);
+ u32 event = ntoh32(e->event_type);
+ struct wl_security *sec = wl_read_prof(wl, ndev, WL_PROF_SEC);
+ AP6210_DEBUG("event type : %d, reason : %d\n", event, reason);
+ if (sec) {
+ switch (event) {
+ case WLC_E_ASSOC:
+ case WLC_E_AUTH:
+ sec->auth_assoc_res_status = reason;
+ default:
+ break;
+ }
+ } else
+ AP6210_ERR("sec is NULL\n");
+ return 0;
+}
+
+static s32
+wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ bool act;
+ s32 err = 0;
+ u32 event = ntoh32(e->event_type);
+
+ if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
+ wl_notify_connect_status_ap(wl, ndev, e, data);
+ } else {
+ AP6210_DEBUG("wl_notify_connect_status : event %d status : %d ndev %p\n",
+ ntoh32(e->event_type), ntoh32(e->status), ndev);
+ if (event == WLC_E_ASSOC || event == WLC_E_AUTH) {
+ wl_get_auth_assoc_status(wl, ndev, e);
+ return err;
+ }
+ if (wl_is_linkup(wl, e, ndev)) {
+ wl_link_up(wl);
+ act = true;
+ if (wl_is_ibssmode(wl, ndev)) {
+ AP6210_DEBUG("cfg80211_ibss_joined\n");
+ cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
+ GFP_KERNEL);
+ AP6210_DEBUG("joined in IBSS network\n");
+ } else {
+ if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) {
+ AP6210_DEBUG("wl_bss_connect_done succeeded with " MACDBG "\n",
+ MAC2STRDBG((u8*)(&e->addr)));
+ wl_bss_connect_done(wl, ndev, e, data, true);
+ AP6210_DEBUG("joined in BSS network \"%s\"\n",
+ ((struct wlc_ssid *)
+ wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID);
+ }
+ }
+ wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
+ wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
+
+ } else if (wl_is_linkdown(wl, e)) {
+ if (wl->scan_request) {
+ if (wl->escan_on) {
+ wl_notify_escan_complete(wl, ndev, true, true);
+ } else {
+ del_timer_sync(&wl->scan_timeout);
+ wl_iscan_aborted(wl);
+ }
+ }
+ if (wl_get_drv_status(wl, CONNECTED, ndev)) {
+ scb_val_t scbval;
+ u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
+ s32 reason = 0;
+ if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND)
+ reason = ntoh32(e->reason);
+ /* WLAN_REASON_UNSPECIFIED is used for hang up event in Android */
+ reason = (reason == WLAN_REASON_UNSPECIFIED)? 0 : reason;
+
+ AP6210_DEBUG("link down if %s may call cfg80211_disconnected. "
+ "event : %d, reason=%d from " MACDBG "\n",
+ ndev->name, event, ntoh32(e->reason),
+ MAC2STRDBG((u8*)(&e->addr)));
+ if (memcmp(curbssid, &e->addr, ETHER_ADDR_LEN) != 0) {
+ AP6210_ERR("BSSID of event is not the connected BSSID"
+ "(ignore it) cur: " MACDBG " event: " MACDBG"\n",
+ MAC2STRDBG(curbssid), MAC2STRDBG((u8*)(&e->addr)));
+ return 0;
+ }
+ wl_clr_drv_status(wl, CONNECTED, ndev);
+ if (! wl_get_drv_status(wl, DISCONNECTING, ndev)) {
+ /* To make sure disconnect, explictly send dissassoc
+ * for BSSID 00:00:00:00:00:00 issue
+ */
+ scbval.val = WLAN_REASON_DEAUTH_LEAVING;
+
+ memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
+ scbval.val = htod32(scbval.val);
+ err = wldev_ioctl(ndev, WLC_DISASSOC, &scbval,
+ sizeof(scb_val_t), true);
+ if (err < 0) {
+ AP6210_ERR("WLC_DISASSOC error %d\n", err);
+ err = 0;
+ }
+ cfg80211_disconnected(ndev, reason, NULL, 0, GFP_KERNEL);
+ wl_link_down(wl);
+ wl_init_prof(wl, ndev);
+ }
+ }
+ else if (wl_get_drv_status(wl, CONNECTING, ndev)) {
+ AP6210_DEBUG("link down, during connecting\n");
+#ifdef ESCAN_RESULT_PATCH
+ if ((memcmp(connect_req_bssid, broad_bssid, ETHER_ADDR_LEN) == 0) ||
+ (memcmp(&e->addr, broad_bssid, ETHER_ADDR_LEN) == 0) ||
+ (memcmp(&e->addr, connect_req_bssid, ETHER_ADDR_LEN) == 0))
+ /* In case this event comes while associating another AP */
+#endif /* ESCAN_RESULT_PATCH */
+ wl_bss_connect_done(wl, ndev, e, data, false);
+ }
+ wl_clr_drv_status(wl, DISCONNECTING, ndev);
+
+ /* if link down, bsscfg is diabled */
+ if (ndev != wl_to_prmry_ndev(wl))
+ complete(&wl->iface_disable);
+
+ } else if (wl_is_nonetwork(wl, e)) {
+ AP6210_DEBUG("connect failed event=%d e->status %d e->reason %d \n",
+ event, (int)ntoh32(e->status), (int)ntoh32(e->reason));
+ /* Clean up any pending scan request */
+ if (wl->scan_request) {
+ if (wl->escan_on) {
+ wl_notify_escan_complete(wl, ndev, true, true);
+ } else {
+ del_timer_sync(&wl->scan_timeout);
+ wl_iscan_aborted(wl);
+ }
+ }
+ if (wl_get_drv_status(wl, CONNECTING, ndev))
+ wl_bss_connect_done(wl, ndev, e, data, false);
+ } else {
+ AP6210_DEBUG("%s nothing\n", __FUNCTION__);
+ }
+ }
+ return err;
+}
+
+static s32
+wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ bool act;
+ s32 err = 0;
+ u32 event = be32_to_cpu(e->event_type);
+ u32 status = be32_to_cpu(e->status);
+ AP6210_DEBUG("Enter \n");
+ if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
+ if (wl_get_drv_status(wl, CONNECTED, ndev))
+ wl_bss_roaming_done(wl, ndev, e, data);
+ else
+ wl_bss_connect_done(wl, ndev, e, data, true);
+ act = true;
+ wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
+ wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
+ }
+ return err;
+}
+
+static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
+{
+ wl_assoc_info_t assoc_info;
+ struct wl_connect_info *conn_info = wl_to_conn(wl);
+ s32 err = 0;
+
+ AP6210_DEBUG("Enter \n");
+ err = wldev_iovar_getbuf(ndev, "assoc_info", NULL, 0, wl->extra_buf,
+ WL_ASSOC_INFO_MAX, NULL);
+ if (unlikely(err)) {
+ AP6210_ERR("could not get assoc info (%d)\n", err);
+ return err;
+ }
+ memcpy(&assoc_info, wl->extra_buf, sizeof(wl_assoc_info_t));
+ assoc_info.req_len = htod32(assoc_info.req_len);
+ assoc_info.resp_len = htod32(assoc_info.resp_len);
+ assoc_info.flags = htod32(assoc_info.flags);
+ if (conn_info->req_ie_len) {
+ conn_info->req_ie_len = 0;
+ bzero(conn_info->req_ie, sizeof(conn_info->req_ie));
+ }
+ if (conn_info->resp_ie_len) {
+ conn_info->resp_ie_len = 0;
+ bzero(conn_info->resp_ie, sizeof(conn_info->resp_ie));
+ }
+ if (assoc_info.req_len) {
+ err = wldev_iovar_getbuf(ndev, "assoc_req_ies", NULL, 0, wl->extra_buf,
+ WL_ASSOC_INFO_MAX, NULL);
+ if (unlikely(err)) {
+ AP6210_ERR("could not get assoc req (%d)\n", err);
+ return err;
+ }
+ conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req);
+ if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
+ conn_info->req_ie_len -= ETHER_ADDR_LEN;
+ }
+ if (conn_info->req_ie_len <= MAX_REQ_LINE)
+ memcpy(conn_info->req_ie, wl->extra_buf, conn_info->req_ie_len);
+ else {
+ AP6210_ERR("%s IE size %d above max %d size \n",
+ __FUNCTION__, conn_info->req_ie_len, MAX_REQ_LINE);
+ return err;
+ }
+ } else {
+ conn_info->req_ie_len = 0;
+ }
+ if (assoc_info.resp_len) {
+ err = wldev_iovar_getbuf(ndev, "assoc_resp_ies", NULL, 0, wl->extra_buf,
+ WL_ASSOC_INFO_MAX, NULL);
+ if (unlikely(err)) {
+ AP6210_ERR("could not get assoc resp (%d)\n", err);
+ return err;
+ }
+ conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
+ if (conn_info->resp_ie_len <= MAX_REQ_LINE)
+ memcpy(conn_info->resp_ie, wl->extra_buf, conn_info->resp_ie_len);
+ else {
+ AP6210_ERR("%s IE size %d above max %d size \n",
+ __FUNCTION__, conn_info->resp_ie_len, MAX_REQ_LINE);
+ return err;
+ }
+ } else {
+ conn_info->resp_ie_len = 0;
+ }
+ AP6210_DEBUG("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
+ conn_info->resp_ie_len);
+
+ return err;
+}
+
+static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
+ size_t *join_params_size)
+{
+ chanspec_t chanspec = 0;
+ if (ch != 0) {
+ join_params->params.chanspec_num = 1;
+ join_params->params.chanspec_list[0] = ch;
+
+ if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
+ chanspec |= WL_CHANSPEC_BAND_2G;
+ else
+ chanspec |= WL_CHANSPEC_BAND_5G;
+
+ chanspec |= WL_CHANSPEC_BW_20;
+ chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+
+ *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
+ join_params->params.chanspec_num * sizeof(chanspec_t);
+
+ join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
+ join_params->params.chanspec_list[0] |= chanspec;
+ join_params->params.chanspec_list[0] =
+ wl_chspec_host_to_driver(join_params->params.chanspec_list[0]);
+
+ join_params->params.chanspec_num =
+ htod32(join_params->params.chanspec_num);
+ AP6210_DEBUG("join_params->params.chanspec_list[0]= %X, %d channels\n",
+ join_params->params.chanspec_list[0],
+ join_params->params.chanspec_num);
+ }
+}
+
+static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev, u8 is_roam_done)
+{
+ struct cfg80211_bss *bss;
+ struct wl_bss_info *bi;
+ struct wlc_ssid *ssid;
+ struct bcm_tlv *tim;
+ s32 beacon_interval;
+ s32 dtim_period;
+ size_t ie_len;
+ u8 *ie;
+ u8 *ssidie;
+ u8 *curbssid;
+ s32 err = 0;
+ struct wiphy *wiphy;
+
+ wiphy = wl_to_wiphy(wl);
+
+ if (wl_is_ibssmode(wl, ndev))
+ return err;
+
+ ssid = (struct wlc_ssid *)wl_read_prof(wl, ndev, WL_PROF_SSID);
+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
+ bss = cfg80211_get_bss(wiphy, NULL, curbssid,
+ ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
+ WLAN_CAPABILITY_ESS);
+
+ mutex_lock(&wl->usr_sync);
+ if (!bss) {
+ AP6210_DEBUG("Could not find the AP\n");
+ *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
+ err = wldev_ioctl(ndev, WLC_GET_BSS_INFO,
+ wl->extra_buf, WL_EXTRA_BUF_MAX, false);
+ if (unlikely(err)) {
+ AP6210_ERR("Could not get bss info %d\n", err);
+ goto update_bss_info_out;
+ }
+ bi = (struct wl_bss_info *)(wl->extra_buf + 4);
+ if (memcmp(bi->BSSID.octet, curbssid, ETHER_ADDR_LEN)) {
+ err = -EIO;
+ goto update_bss_info_out;
+ }
+
+ ie = ((u8 *)bi) + bi->ie_offset;
+ ie_len = bi->ie_length;
+ ssidie = (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ie, ie_len);
+ if (ssidie && ssidie[1] == bi->SSID_len && !ssidie[2] && bi->SSID[0])
+ memcpy(ssidie + 2, bi->SSID, bi->SSID_len);
+
+ err = wl_inform_single_bss(wl, bi, is_roam_done);
+ if (unlikely(err))
+ goto update_bss_info_out;
+
+ ie = ((u8 *)bi) + bi->ie_offset;
+ ie_len = bi->ie_length;
+ beacon_interval = cpu_to_le16(bi->beacon_period);
+ } else {
+ AP6210_DEBUG("Found the AP in the list - BSSID %pM\n", bss->bssid);
+ ie = bss->information_elements;
+ ie_len = bss->len_information_elements;
+ beacon_interval = bss->beacon_interval;
+ cfg80211_put_bss(bss);
+ }
+
+ tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
+ if (tim) {
+ dtim_period = tim->data[1];
+ } else {
+ /*
+ * active scan was done so we could not get dtim
+ * information out of probe response.
+ * so we speficially query dtim information.
+ */
+ err = wldev_ioctl(ndev, WLC_GET_DTIMPRD,
+ &dtim_period, sizeof(dtim_period), false);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_GET_DTIMPRD error (%d)\n", err);
+ goto update_bss_info_out;
+ }
+ }
+
+ wl_update_prof(wl, ndev, NULL, &beacon_interval, WL_PROF_BEACONINT);
+ wl_update_prof(wl, ndev, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
+
+update_bss_info_out:
+ mutex_unlock(&wl->usr_sync);
+ return err;
+}
+
+static s32
+wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ struct wl_connect_info *conn_info = wl_to_conn(wl);
+ s32 err = 0;
+ u8 *curbssid;
+
+ wl_get_assoc_ies(wl, ndev);
+ wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
+ wl_update_bss_info(wl, ndev, 1);
+ wl_update_pmklist(ndev, wl->pmk_list, err);
+ AP6210_DEBUG("wl_bss_roaming_done succeeded to " MACDBG "\n",
+ MAC2STRDBG((u8*)(&e->addr)));
+
+ cfg80211_roamed(ndev,
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+ NULL, /* struct cfg80211_bss *bss */
+#elif LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
+ NULL,
+#endif
+ curbssid,
+ conn_info->req_ie, conn_info->req_ie_len,
+ conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
+ AP6210_DEBUG("Report roaming result\n");
+
+ wl_set_drv_status(wl, CONNECTED, ndev);
+
+ return err;
+}
+
+static s32
+wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data, bool completed)
+{
+ struct wl_connect_info *conn_info = wl_to_conn(wl);
+ struct wl_security *sec = wl_read_prof(wl, ndev, WL_PROF_SEC);
+ s32 err = 0;
+ u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
+ if (!sec) {
+ AP6210_ERR("sec is NULL\n");
+ return -ENODEV;
+ }
+ AP6210_DEBUG(" enter\n");
+#ifdef ESCAN_RESULT_PATCH
+ if (wl_get_drv_status(wl, CONNECTED, ndev)) {
+ if (memcmp(curbssid, connect_req_bssid, ETHER_ADDR_LEN) == 0) {
+ AP6210_DEBUG(" Connected event of connected device e=%d s=%d, ignore it\n",
+ ntoh32(e->event_type), ntoh32(e->status));
+ return err;
+ }
+ }
+ if (memcmp(curbssid, broad_bssid, ETHER_ADDR_LEN) == 0 &&
+ memcmp(broad_bssid, connect_req_bssid, ETHER_ADDR_LEN) != 0) {
+ AP6210_DEBUG("copy bssid\n");
+ memcpy(curbssid, connect_req_bssid, ETHER_ADDR_LEN);
+ }
+
+#else
+ if (wl->scan_request) {
+ wl_notify_escan_complete(wl, ndev, true, true);
+ }
+#endif /* ESCAN_RESULT_PATCH */
+ if (wl_get_drv_status(wl, CONNECTING, ndev)) {
+ wl_clr_drv_status(wl, CONNECTING, ndev);
+ if (completed) {
+ wl_get_assoc_ies(wl, ndev);
+ wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
+ curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
+ wl_update_bss_info(wl, ndev, 0);
+ wl_update_pmklist(ndev, wl->pmk_list, err);
+ wl_set_drv_status(wl, CONNECTED, ndev);
+ }
+ cfg80211_connect_result(ndev,
+ curbssid,
+ conn_info->req_ie,
+ conn_info->req_ie_len,
+ conn_info->resp_ie,
+ conn_info->resp_ie_len,
+ completed ? WLAN_STATUS_SUCCESS :
+ (sec->auth_assoc_res_status) ?
+ sec->auth_assoc_res_status :
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
+ if (completed)
+ AP6210_DEBUG("Report connect result - connection succeeded\n");
+ else
+ AP6210_ERR("Report connect result - connection failed\n");
+ }
+ return err;
+}
+
+static s32
+wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ u16 flags = ntoh16(e->flags);
+ enum nl80211_key_type key_type;
+
+ mutex_lock(&wl->usr_sync);
+ if (flags & WLC_EVENT_MSG_GROUP)
+ key_type = NL80211_KEYTYPE_GROUP;
+ else
+ key_type = NL80211_KEYTYPE_PAIRWISE;
+
+ cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
+ NULL, GFP_KERNEL);
+ mutex_unlock(&wl->usr_sync);
+
+ return 0;
+}
+
+#ifdef PNO_SUPPORT
+static s32
+wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ AP6210_ERR(">>> PNO Event\n");
+
+#ifndef WL_SCHED_SCAN
+ mutex_lock(&wl->usr_sync);
+ /* TODO: Use cfg80211_sched_scan_results(wiphy); */
+ cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
+ mutex_unlock(&wl->usr_sync);
+#else
+ /* If cfg80211 scheduled scan is supported, report the pno results via sched
+ * scan results
+ */
+ wl_notify_sched_scan_results(wl, ndev, e, data);
+#endif /* WL_SCHED_SCAN */
+ return 0;
+}
+#endif /* PNO_SUPPORT */
+
+static s32
+wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ struct channel_info channel_inform;
+ struct wl_scan_results *bss_list;
+ u32 len = WL_SCAN_BUF_MAX;
+ s32 err = 0;
+ unsigned long flags;
+
+ AP6210_DEBUG("Enter \n");
+ if (!wl_get_drv_status(wl, SCANNING, ndev)) {
+ AP6210_ERR("scan is not ready \n");
+ return err;
+ }
+ if (wl->iscan_on && wl->iscan_kickstart)
+ return wl_wakeup_iscan(wl_to_iscan(wl));
+
+ mutex_lock(&wl->usr_sync);
+ wl_clr_drv_status(wl, SCANNING, ndev);
+ err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
+ sizeof(channel_inform), false);
+ if (unlikely(err)) {
+ AP6210_ERR("scan busy (%d)\n", err);
+ goto scan_done_out;
+ }
+ channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
+ if (unlikely(channel_inform.scan_channel)) {
+
+ AP6210_DEBUG("channel_inform.scan_channel (%d)\n",
+ channel_inform.scan_channel);
+ }
+ wl->bss_list = wl->scan_results;
+ bss_list = wl->bss_list;
+ memset(bss_list, 0, len);
+ bss_list->buflen = htod32(len);
+ err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, false);
+ if (unlikely(err) && unlikely(!wl->scan_suppressed)) {
+ AP6210_ERR("%s Scan_results error (%d)\n", ndev->name, err);
+ err = -EINVAL;
+ goto scan_done_out;
+ }
+ bss_list->buflen = dtoh32(bss_list->buflen);
+ bss_list->version = dtoh32(bss_list->version);
+ bss_list->count = dtoh32(bss_list->count);
+
+ err = wl_inform_bss(wl);
+
+scan_done_out:
+ del_timer_sync(&wl->scan_timeout);
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ if (wl->scan_request) {
+ cfg80211_scan_done(wl->scan_request, false);
+ wl->scan_request = NULL;
+ }
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+ AP6210_DEBUG("cfg80211_scan_done\n");
+ mutex_unlock(&wl->usr_sync);
+ return err;
+}
+static s32
+wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
+ const struct ether_addr *sa, const struct ether_addr *bssid,
+ u8 **pheader, u32 *body_len, u8 *pbody)
+{
+ struct dot11_management_header *hdr;
+ u32 totlen = 0;
+ s32 err = 0;
+ u8 *offset;
+ u32 prebody_len = *body_len;
+ switch (fc) {
+ case FC_ASSOC_REQ:
+ /* capability , listen interval */
+ totlen = DOT11_ASSOC_REQ_FIXED_LEN;
+ *body_len += DOT11_ASSOC_REQ_FIXED_LEN;
+ break;
+
+ case FC_REASSOC_REQ:
+ /* capability, listen inteval, ap address */
+ totlen = DOT11_REASSOC_REQ_FIXED_LEN;
+ *body_len += DOT11_REASSOC_REQ_FIXED_LEN;
+ break;
+ }
+ totlen += DOT11_MGMT_HDR_LEN + prebody_len;
+ *pheader = kzalloc(totlen, GFP_KERNEL);
+ if (*pheader == NULL) {
+ AP6210_ERR("memory alloc failed \n");
+ return -ENOMEM;
+ }
+ hdr = (struct dot11_management_header *) (*pheader);
+ hdr->fc = htol16(fc);
+ hdr->durid = 0;
+ hdr->seq = 0;
+ offset = (u8*)(hdr + 1) + (totlen - DOT11_MGMT_HDR_LEN - prebody_len);
+ bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN);
+ bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN);
+ bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN);
+ if ((pbody != NULL) && prebody_len)
+ bcopy((const char*)pbody, offset, prebody_len);
+ *body_len = totlen;
+ return err;
+}
+
+
+void
+wl_stop_wait_next_action_frame(struct wl_priv *wl, struct net_device *ndev)
+{
+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM) &&
+ (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) ||
+ wl_get_p2p_status(wl, ACTION_TX_NOACK))) {
+ AP6210_DEBUG("*** Wake UP ** abort actframe iovar\n");
+ /* if channel is not zero, "actfame" uses off channel scan.
+ * So abort scan for off channel completion.
+ */
+ if (wl->af_sent_channel)
+ /* wl_cfg80211_scan_abort(wl, ndev); */
+ wl_notify_escan_complete(wl,
+ (ndev == wl->p2p_net) ? wl_to_prmry_ndev(wl) : ndev, true, true);
+ }
+#ifdef WL_CFG80211_SYNC_GON
+ else if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) {
+ AP6210_DEBUG("*** Wake UP ** abort listen for next af frame\n");
+ /* So abort scan to cancel listen */
+ wl_notify_escan_complete(wl,
+ (ndev == wl->p2p_net) ? wl_to_prmry_ndev(wl) : ndev, true, true);
+ }
+#endif /* WL_CFG80211_SYNC_GON */
+}
+
+static s32
+wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ struct ieee80211_supported_band *band;
+ struct wiphy *wiphy = wl_to_wiphy(wl);
+ struct ether_addr da;
+ struct ether_addr bssid;
+ bool isfree = false;
+ s32 err = 0;
+ s32 freq;
+ struct net_device *dev = NULL;
+ wifi_p2p_pub_act_frame_t *act_frm = NULL;
+ wifi_p2p_action_frame_t *p2p_act_frm = NULL;
+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL;
+ wl_event_rx_frame_data_t *rxframe =
+ (wl_event_rx_frame_data_t*)data;
+ u32 event = ntoh32(e->event_type);
+ u8 *mgmt_frame;
+ u8 bsscfgidx = e->bsscfgidx;
+ u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t);
+ u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK));
+
+ memset(&bssid, 0, ETHER_ADDR_LEN);
+
+ if (wl->p2p_net == ndev) {
+ dev = wl_to_prmry_ndev(wl);
+ } else {
+ dev = ndev;
+ }
+
+ if (channel <= CH_MAX_2G_CHANNEL)
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ else
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ if (!band) {
+ AP6210_ERR("No valid band");
+ return -EINVAL;
+ }
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+ freq = ieee80211_channel_to_frequency(channel);
+ (void)band->band;
+#else
+ freq = ieee80211_channel_to_frequency(channel, band->band);
+#endif
+ if (event == WLC_E_ACTION_FRAME_RX) {
+ wldev_iovar_getbuf_bsscfg(dev, "cur_etheraddr",
+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, bsscfgidx, &wl->ioctl_buf_sync);
+
+ err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+ if (err < 0)
+ AP6210_ERR("WLC_GET_BSSID error %d\n", err);
+ memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
+ err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid,
+ &mgmt_frame, &mgmt_frame_len,
+ (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1));
+ if (err < 0) {
+ AP6210_ERR("%s: Error in receiving action frame len %d channel %d freq %d\n",
+ __func__, mgmt_frame_len, channel, freq);
+ goto exit;
+ }
+ isfree = true;
+ if (wl_cfgp2p_is_pub_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
+ act_frm = (wifi_p2p_pub_act_frame_t *)
+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
+ } else if (wl_cfgp2p_is_p2p_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
+ p2p_act_frm = (wifi_p2p_action_frame_t *)
+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
+ (void) p2p_act_frm;
+ } else if (wl_cfgp2p_is_gas_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
+ mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)
+ (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
+ if (sd_act_frm && wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM)) {
+ if (wl->next_af_subtype == sd_act_frm->action) {
+ AP6210_DEBUG("We got a right next frame of SD!(%d)\n",
+ sd_act_frm->action);
+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM,
+ (ndev == wl->p2p_net) ?
+ wl_to_prmry_ndev(wl) : ndev);
+
+ /* Stop waiting for next AF. */
+ wl_stop_wait_next_action_frame(wl, ndev);
+ }
+ }
+ (void) sd_act_frm;
+ } else {
+ /*
+ * if we got normal action frame and ndev is p2p0,
+ * we have to change ndev from p2p0 to wlan0
+ */
+ if (wl->p2p_net == ndev)
+ ndev = wl_to_prmry_ndev(wl);
+ }
+
+ if (act_frm) {
+
+ if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM)) {
+ if (wl->next_af_subtype == act_frm->subtype) {
+ AP6210_DEBUG("We got a right next frame!(%d)\n",
+ act_frm->subtype);
+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM,
+ (ndev == wl->p2p_net) ?
+ wl_to_prmry_ndev(wl) : ndev);
+
+ /* Stop waiting for next AF. */
+ wl_stop_wait_next_action_frame(wl, ndev);
+ }
+ }
+ }
+
+ wl_cfgp2p_print_actframe(false, &mgmt_frame[DOT11_MGMT_HDR_LEN],
+ mgmt_frame_len - DOT11_MGMT_HDR_LEN);
+ /*
+ * After complete GO Negotiation, roll back to mpc mode
+ */
+ if (act_frm && ((act_frm->subtype == P2P_PAF_GON_CONF) ||
+ (act_frm->subtype == P2P_PAF_PROVDIS_RSP))) {
+ wldev_iovar_setint(dev, "mpc", 1);
+ }
+ if (act_frm && (act_frm->subtype == P2P_PAF_GON_CONF)) {
+ AP6210_DEBUG("P2P: GO_NEG_PHASE status cleared \n");
+ wl_clr_p2p_status(wl, GO_NEG_PHASE);
+ }
+ } else {
+ mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
+
+ /* wpa supplicant use probe request event for restarting another GON Req.
+ * but it makes GON Req repetition.
+ * so if src addr of prb req is same as my target device,
+ * do not send probe request event during sending action frame.
+ */
+ if (event == WLC_E_P2P_PROBREQ_MSG) {
+ AP6210_DEBUG(" Event %s\n", (event == WLC_E_P2P_PROBREQ_MSG) ?
+ "WLC_E_P2P_PROBREQ_MSG":"WLC_E_PROBREQ_MSG");
+
+
+ /* Filter any P2P probe reqs arriving during the
+ * GO-NEG Phase
+ */
+ if (wl->p2p &&
+ wl_get_p2p_status(wl, GO_NEG_PHASE)) {
+ AP6210_DEBUG("Filtering P2P probe_req while "
+ "being in GO-Neg state\n");
+ return 0;
+ }
+ }
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+ cfg80211_rx_mgmt(ndev, freq, 0, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
+#else
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
+
+ AP6210_DEBUG("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__,
+ mgmt_frame_len, ntoh32(e->datalen), channel, freq);
+exit:
+ if (isfree)
+ kfree(mgmt_frame);
+ return 0;
+}
+
+#ifdef WL_SCHED_SCAN
+/* If target scan is not reliable, set the below define to "1" to do a
+ * full escan
+ */
+#define FULL_ESCAN_ON_PFN_NET_FOUND 0
+static s32
+wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ wl_pfn_net_info_t *netinfo, *pnetinfo;
+ struct cfg80211_scan_request request;
+ struct wiphy *wiphy = wl_to_wiphy(wl);
+ int err = 0;
+ struct cfg80211_ssid ssid[MAX_PFN_LIST_COUNT];
+ struct ieee80211_channel *channel = NULL;
+ int channel_req = 0;
+ int band = 0;
+ struct wl_pfn_scanresults *pfn_result = (struct wl_pfn_scanresults *)data;
+
+ AP6210_DEBUG("Enter\n");
+
+ if (e->event_type == WLC_E_PFN_NET_LOST) {
+ AP6210_DEBUG("PFN NET LOST event. Do Nothing \n");
+ return 0;
+ }
+ AP6210_DEBUG(">>> PFN NET FOUND event. count:%d \n", pfn_result->count);
+ if (pfn_result->count > 0) {
+ int i;
+
+ memset(&request, 0x00, sizeof(struct cfg80211_scan_request));
+ memset(&ssid, 0x00, sizeof(ssid));
+ request.wiphy = wiphy;
+
+ pnetinfo = (wl_pfn_net_info_t *)(data + sizeof(wl_pfn_scanresults_t)
+ - sizeof(wl_pfn_net_info_t));
+ channel = (struct ieee80211_channel *)kzalloc(
+ (sizeof(struct ieee80211_channel) * MAX_PFN_LIST_COUNT),
+ GFP_KERNEL);
+ if (!channel) {
+ AP6210_ERR("No memory");
+ err = -ENOMEM;
+ goto out_err;
+ }
+
+ for (i = 0; i < pfn_result->count; i++) {
+ netinfo = &pnetinfo[i];
+ if (!netinfo) {
+ AP6210_ERR("Invalid netinfo ptr. index:%d", i);
+ err = -EINVAL;
+ goto out_err;
+ }
+ AP6210_DEBUG(">>> SSID:%s Channel:%d \n",
+ netinfo->pfnsubnet.SSID, netinfo->pfnsubnet.channel);
+ /* PFN result doesn't have all the info which are required by the supplicant
+ * (For e.g IEs) Do a target Escan so that sched scan results are reported
+ * via wl_inform_single_bss in the required format. Escan does require the
+ * scan request in the form of cfg80211_scan_request. For timebeing, create
+ * cfg80211_scan_request one out of the received PNO event.
+ */
+ memcpy(ssid[i].ssid, netinfo->pfnsubnet.SSID,
+ netinfo->pfnsubnet.SSID_len);
+ ssid[i].ssid_len = netinfo->pfnsubnet.SSID_len;
+ request.n_ssids++;
+
+ channel_req = netinfo->pfnsubnet.channel;
+ band = (channel_req <= CH_MAX_2G_CHANNEL) ? NL80211_BAND_2GHZ
+ : NL80211_BAND_5GHZ;
+ channel[i].center_freq = ieee80211_channel_to_frequency(channel_req, band);
+ channel[i].band = band;
+ channel[i].flags |= IEEE80211_CHAN_NO_HT40;
+ request.channels[i] = &channel[i];
+ request.n_channels++;
+ }
+
+ /* assign parsed ssid array */
+ if (request.n_ssids)
+ request.ssids = &ssid[0];
+
+ if (wl_get_drv_status_all(wl, SCANNING)) {
+ /* Abort any on-going scan */
+ wl_notify_escan_complete(wl, ndev, true, true);
+ }
+
+ if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
+ AP6210_DEBUG(">>> P2P discovery was ON. Disabling it\n");
+ err = wl_cfgp2p_discover_enable_search(wl, false);
+ if (unlikely(err)) {
+ wl_clr_drv_status(wl, SCANNING, ndev);
+ goto out_err;
+ }
+ }
+
+ wl_set_drv_status(wl, SCANNING, ndev);
+#if FULL_ESCAN_ON_PFN_NET_FOUND
+ AP6210_DEBUG(">>> Doing Full ESCAN on PNO event\n");
+ err = wl_do_escan(wl, wiphy, ndev, NULL);
+#else
+ AP6210_DEBUG(">>> Doing targeted ESCAN on PNO event\n");
+ err = wl_do_escan(wl, wiphy, ndev, &request);
+#endif
+ if (err) {
+ wl_clr_drv_status(wl, SCANNING, ndev);
+ goto out_err;
+ }
+ wl->sched_scan_running = TRUE;
+ }
+ else {
+ AP6210_ERR("FALSE PNO Event. (pfn_count == 0) \n");
+ }
+out_err:
+ if (channel)
+ kfree(channel);
+ return err;
+}
+#endif /* WL_SCHED_SCAN */
+
+static void wl_init_conf(struct wl_conf *conf)
+{
+ AP6210_DEBUG("Enter \n");
+ conf->frag_threshold = (u32)-1;
+ conf->rts_threshold = (u32)-1;
+ conf->retry_short = (u32)-1;
+ conf->retry_long = (u32)-1;
+ conf->tx_power = -1;
+}
+
+static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev)
+{
+ unsigned long flags;
+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
+
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ memset(profile, 0, sizeof(struct wl_profile));
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+}
+
+static void wl_init_event_handler(struct wl_priv *wl)
+{
+ memset(wl->evt_handler, 0, sizeof(wl->evt_handler));
+
+ wl->evt_handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
+ wl->evt_handler[WLC_E_AUTH] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_ASSOC] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_LINK] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_DEAUTH] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_ROAM] = wl_notify_roaming_status;
+ wl->evt_handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
+ wl->evt_handler[WLC_E_SET_SSID] = wl_notify_connect_status;
+ wl->evt_handler[WLC_E_ACTION_FRAME_RX] = wl_notify_rx_mgmt_frame;
+ wl->evt_handler[WLC_E_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
+ wl->evt_handler[WLC_E_P2P_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
+ wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete;
+ wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
+ wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
+#ifdef PNO_SUPPORT
+ wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status;
+#endif /* PNO_SUPPORT */
+}
+
+static s32 wl_init_priv_mem(struct wl_priv *wl)
+{
+ AP6210_DEBUG("Enter \n");
+ wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
+ if (unlikely(!wl->scan_results)) {
+ AP6210_ERR("Scan results alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
+ if (unlikely(!wl->conf)) {
+ AP6210_ERR("wl_conf alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->scan_req_int =
+ (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
+ if (unlikely(!wl->scan_req_int)) {
+ AP6210_ERR("Scan req alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
+ if (unlikely(!wl->ioctl_buf)) {
+ AP6210_ERR("Ioctl buf alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->escan_ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
+ if (unlikely(!wl->escan_ioctl_buf)) {
+ AP6210_ERR("Ioctl buf alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
+ if (unlikely(!wl->extra_buf)) {
+ AP6210_ERR("Extra buf alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
+ if (unlikely(!wl->iscan)) {
+ AP6210_ERR("Iscan buf alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
+ if (unlikely(!wl->pmk_list)) {
+ AP6210_ERR("pmk list alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->sta_info = (void *)kzalloc(sizeof(*wl->sta_info), GFP_KERNEL);
+ if (unlikely(!wl->sta_info)) {
+ AP6210_ERR("sta info alloc failed\n");
+ goto init_priv_mem_out;
+ }
+
+#if defined(STATIC_WL_PRIV_STRUCT)
+ wl->conn_info = (void *)kzalloc(sizeof(*wl->conn_info), GFP_KERNEL);
+ if (unlikely(!wl->conn_info)) {
+ AP6210_ERR("wl->conn_info alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->ie = (void *)kzalloc(sizeof(*wl->ie), GFP_KERNEL);
+ if (unlikely(!wl->ie)) {
+ AP6210_ERR("wl->ie alloc failed\n");
+ goto init_priv_mem_out;
+ }
+ wl->escan_info.escan_buf = dhd_os_prealloc(NULL, DHD_PREALLOC_WIPHY_ESCAN0, 0);
+ bzero(wl->escan_info.escan_buf, ESCAN_BUF_SIZE);
+#endif /* STATIC_WL_PRIV_STRUCT */
+ wl->afx_hdl = (void *)kzalloc(sizeof(*wl->afx_hdl), GFP_KERNEL);
+ if (unlikely(!wl->afx_hdl)) {
+ AP6210_ERR("afx hdl alloc failed\n");
+ goto init_priv_mem_out;
+ } else {
+ init_completion(&wl->act_frm_scan);
+ init_completion(&wl->wait_next_af);
+
+ INIT_WORK(&wl->afx_hdl->work, wl_cfg80211_afx_handler);
+ }
+ return 0;
+
+init_priv_mem_out:
+ wl_deinit_priv_mem(wl);
+
+ return -ENOMEM;
+}
+
+static void wl_deinit_priv_mem(struct wl_priv *wl)
+{
+ kfree(wl->scan_results);
+ wl->scan_results = NULL;
+ kfree(wl->conf);
+ wl->conf = NULL;
+ kfree(wl->scan_req_int);
+ wl->scan_req_int = NULL;
+ kfree(wl->ioctl_buf);
+ wl->ioctl_buf = NULL;
+ kfree(wl->escan_ioctl_buf);
+ wl->escan_ioctl_buf = NULL;
+ kfree(wl->extra_buf);
+ wl->extra_buf = NULL;
+ kfree(wl->iscan);
+ wl->iscan = NULL;
+ kfree(wl->pmk_list);
+ wl->pmk_list = NULL;
+ kfree(wl->sta_info);
+ wl->sta_info = NULL;
+#if defined(STATIC_WL_PRIV_STRUCT)
+ kfree(wl->conn_info);
+ wl->conn_info = NULL;
+ kfree(wl->ie);
+ wl->ie = NULL;
+ wl->escan_info.escan_buf = NULL;
+#endif /* STATIC_WL_PRIV_STRUCT */
+ if (wl->afx_hdl) {
+ cancel_work_sync(&wl->afx_hdl->work);
+ kfree(wl->afx_hdl);
+ wl->afx_hdl = NULL;
+ }
+
+ if (wl->ap_info) {
+ kfree(wl->ap_info->wpa_ie);
+ kfree(wl->ap_info->rsn_ie);
+ kfree(wl->ap_info->wps_ie);
+ kfree(wl->ap_info);
+ wl->ap_info = NULL;
+ }
+}
+
+static s32 wl_create_event_handler(struct wl_priv *wl)
+{
+ int ret = 0;
+ AP6210_DEBUG("Enter \n");
+
+ /* Do not use DHD in cfg driver */
+ wl->event_tsk.thr_pid = -1;
+
+#ifdef USE_KTHREAD_API
+ PROC_START2(wl_event_handler, wl, &wl->event_tsk, 0, "wl_event_handler");
+#else
+ PROC_START(wl_event_handler, wl, &wl->event_tsk, 0);
+#endif
+ if (wl->event_tsk.thr_pid < 0)
+ ret = -ENOMEM;
+ return ret;
+}
+
+static void wl_destroy_event_handler(struct wl_priv *wl)
+{
+ if (wl->event_tsk.thr_pid >= 0)
+ PROC_STOP(&wl->event_tsk);
+}
+
+static void wl_term_iscan(struct wl_priv *wl)
+{
+ struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+ AP6210_DEBUG("In\n");
+ if (wl->iscan_on && iscan->tsk) {
+ iscan->state = WL_ISCAN_STATE_IDLE;
+ AP6210_DEBUG("SIGTERM\n");
+ send_sig(SIGTERM, iscan->tsk, 1);
+ AP6210_DEBUG("kthread_stop\n");
+ kthread_stop(iscan->tsk);
+ iscan->tsk = NULL;
+ }
+}
+
+static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
+{
+ struct wl_priv *wl = iscan_to_wl(iscan);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ unsigned long flags;
+
+ AP6210_DEBUG("Enter \n");
+ if (!wl_get_drv_status(wl, SCANNING, ndev)) {
+ wl_clr_drv_status(wl, SCANNING, ndev);
+ AP6210_ERR("Scan complete while device not scanning\n");
+ return;
+ }
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ wl_clr_drv_status(wl, SCANNING, ndev);
+ if (likely(wl->scan_request)) {
+ cfg80211_scan_done(wl->scan_request, aborted);
+ wl->scan_request = NULL;
+ }
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+ wl->iscan_kickstart = false;
+}
+
+static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
+{
+ if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
+ AP6210_DEBUG("wake up iscan\n");
+ up(&iscan->sync);
+ return 0;
+ }
+
+ return -EIO;
+}
+
+static s32
+wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
+ struct wl_scan_results **bss_list)
+{
+ struct wl_iscan_results list;
+ struct wl_scan_results *results;
+ struct wl_iscan_results *list_buf;
+ s32 err = 0;
+
+ AP6210_DEBUG("Enter \n");
+ memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
+ list_buf = (struct wl_iscan_results *)iscan->scan_buf;
+ results = &list_buf->results;
+ results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+ results->version = 0;
+ results->count = 0;
+
+ memset(&list, 0, sizeof(list));
+ list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
+ err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list,
+ WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
+ WL_ISCAN_BUF_MAX, NULL);
+ if (unlikely(err)) {
+ AP6210_ERR("error (%d)\n", err);
+ return err;
+ }
+ results->buflen = dtoh32(results->buflen);
+ results->version = dtoh32(results->version);
+ results->count = dtoh32(results->count);
+ AP6210_DEBUG("results->count = %d\n", results->count);
+ AP6210_DEBUG("results->buflen = %d\n", results->buflen);
+ *status = dtoh32(list_buf->status);
+ *bss_list = results;
+
+ return err;
+}
+
+static s32 wl_iscan_done(struct wl_priv *wl)
+{
+ struct wl_iscan_ctrl *iscan = wl->iscan;
+ s32 err = 0;
+
+ iscan->state = WL_ISCAN_STATE_IDLE;
+ mutex_lock(&wl->usr_sync);
+ wl_inform_bss(wl);
+ wl_notify_iscan_complete(iscan, false);
+ mutex_unlock(&wl->usr_sync);
+
+ return err;
+}
+
+static s32 wl_iscan_pending(struct wl_priv *wl)
+{
+ struct wl_iscan_ctrl *iscan = wl->iscan;
+ s32 err = 0;
+
+ /* Reschedule the timer */
+ mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms));
+ iscan->timer_on = 1;
+
+ return err;
+}
+
+static s32 wl_iscan_inprogress(struct wl_priv *wl)
+{
+ struct wl_iscan_ctrl *iscan = wl->iscan;
+ s32 err = 0;
+
+ mutex_lock(&wl->usr_sync);
+ wl_inform_bss(wl);
+ wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
+ mutex_unlock(&wl->usr_sync);
+ /* Reschedule the timer */
+ mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms));
+ iscan->timer_on = 1;
+
+ return err;
+}
+
+static s32 wl_iscan_aborted(struct wl_priv *wl)
+{
+ struct wl_iscan_ctrl *iscan = wl->iscan;
+ s32 err = 0;
+
+ iscan->state = WL_ISCAN_STATE_IDLE;
+ mutex_lock(&wl->usr_sync);
+ wl_notify_iscan_complete(iscan, true);
+ mutex_unlock(&wl->usr_sync);
+
+ return err;
+}
+
+static s32 wl_iscan_thread(void *data)
+{
+ struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
+ struct wl_priv *wl = iscan_to_wl(iscan);
+ u32 status;
+ int err = 0;
+
+ allow_signal(SIGTERM);
+ status = WL_SCAN_RESULTS_PARTIAL;
+ while (likely(!down_interruptible(&iscan->sync))) {
+ if (kthread_should_stop())
+ break;
+ if (iscan->timer_on) {
+ del_timer_sync(&iscan->timer);
+ iscan->timer_on = 0;
+ }
+ mutex_lock(&wl->usr_sync);
+ err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
+ if (unlikely(err)) {
+ status = WL_SCAN_RESULTS_ABORTED;
+ AP6210_ERR("Abort iscan\n");
+ }
+ mutex_unlock(&wl->usr_sync);
+ iscan->iscan_handler[status] (wl);
+ }
+ if (iscan->timer_on) {
+ del_timer_sync(&iscan->timer);
+ iscan->timer_on = 0;
+ }
+ AP6210_DEBUG("%s was terminated\n", __func__);
+
+ return 0;
+}
+
+static void wl_scan_timeout(unsigned long data)
+{
+ wl_event_msg_t msg;
+ struct wl_priv *wl = (struct wl_priv *)data;
+
+ if (!(wl->scan_request)) {
+ AP6210_ERR("timer expired but no scan request\n");
+ return;
+ }
+ bzero(&msg, sizeof(wl_event_msg_t));
+ AP6210_ERR("timer expired\n");
+ if (wl->escan_on) {
+ msg.event_type = hton32(WLC_E_ESCAN_RESULT);
+ msg.status = hton32(WLC_E_STATUS_TIMEOUT);
+ msg.reason = 0xFFFFFFFF;
+ wl_cfg80211_event(wl_to_prmry_ndev(wl), &msg, NULL);
+ } else {
+ AP6210_ERR("SCAN Timeout(ISCAN)\n");
+ wl_notify_iscan_complete(wl_to_iscan(wl), true);
+ }
+}
+static void wl_iscan_timer(unsigned long data)
+{
+ struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
+
+ if (iscan) {
+ iscan->timer_on = 0;
+ AP6210_DEBUG("timer expired\n");
+ wl_wakeup_iscan(iscan);
+ }
+}
+
+static s32 wl_invoke_iscan(struct wl_priv *wl)
+{
+ struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+ int err = 0;
+
+ if (wl->iscan_on && !iscan->tsk) {
+ iscan->state = WL_ISCAN_STATE_IDLE;
+ sema_init(&iscan->sync, 0);
+ iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
+ if (IS_ERR(iscan->tsk)) {
+ AP6210_ERR("Could not create iscan thread\n");
+ iscan->tsk = NULL;
+ return -ENOMEM;
+ }
+ }
+
+ return err;
+}
+
+static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan)
+{
+ memset(iscan->iscan_handler, 0, sizeof(iscan->iscan_handler));
+ iscan->iscan_handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
+ iscan->iscan_handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
+ iscan->iscan_handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
+ iscan->iscan_handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
+ iscan->iscan_handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
+}
+
+static s32
+wl_cfg80211_netdev_notifier_call(struct notifier_block * nb,
+ unsigned long state,
+ void *ndev)
+{
+ struct net_device *dev = ndev;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wl_priv *wl = wlcfg_drv_priv;
+ int refcnt = 0;
+
+ AP6210_DEBUG("Enter \n");
+ if (!wdev || !wl || dev == wl_to_prmry_ndev(wl))
+ return NOTIFY_DONE;
+ switch (state) {
+ case NETDEV_DOWN:
+ while (work_pending(&wdev->cleanup_work) && refcnt < 100) {
+ if (refcnt%5 == 0)
+ AP6210_ERR("%s : [NETDEV_DOWN] work_pending (%d th)\n",
+ __FUNCTION__, refcnt);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(100);
+ set_current_state(TASK_RUNNING);
+ refcnt++;
+ }
+ break;
+
+ case NETDEV_UNREGISTER:
+ /* after calling list_del_rcu(&wdev->list) */
+ wl_dealloc_netinfo(wl, ndev);
+ break;
+ case NETDEV_GOING_DOWN:
+ /* At NETDEV_DOWN state, wdev_cleanup_work work will be called.
+ * In front of door, the function checks
+ * whether current scan is working or not.
+ * If the scanning is still working, wdev_cleanup_work call WARN_ON and
+ * make the scan done forcibly.
+ */
+ if (wl_get_drv_status(wl, SCANNING, dev)) {
+ if (wl->escan_on) {
+ wl_notify_escan_complete(wl, dev, true, true);
+ }
+ }
+ break;
+ }
+ return NOTIFY_DONE;
+}
+static struct notifier_block wl_cfg80211_netdev_notifier = {
+ .notifier_call = wl_cfg80211_netdev_notifier_call,
+};
+
+static s32 wl_notify_escan_complete(struct wl_priv *wl,
+ struct net_device *ndev,
+ bool aborted, bool fw_abort)
+{
+ wl_scan_params_t *params = NULL;
+ s32 params_size = 0;
+ s32 err = BCME_OK;
+ unsigned long flags;
+ struct net_device *dev;
+
+ AP6210_DEBUG("Enter \n");
+
+ if (wl->escan_info.ndev != ndev)
+ {
+ AP6210_ERR("ndev is different %p %p\n", wl->escan_info.ndev, ndev);
+ return err;
+ }
+
+ if (wl->scan_request) {
+ if (wl->scan_request->dev == wl->p2p_net)
+ dev = wl_to_prmry_ndev(wl);
+ else
+ dev = wl->scan_request->dev;
+ }
+ else {
+ AP6210_DEBUG("wl->scan_request is NULL may be internal scan."
+ "doing scan_abort for ndev %p primary %p p2p_net %p",
+ ndev, wl_to_prmry_ndev(wl), wl->p2p_net);
+ dev = ndev;
+ }
+ if (fw_abort && !in_atomic()) {
+ /* Our scan params only need space for 1 channel and 0 ssids */
+ params = wl_cfg80211_scan_alloc_params(-1, 0, &params_size);
+ if (params == NULL) {
+ AP6210_ERR("scan params allocation failed \n");
+ err = -ENOMEM;
+ } else {
+ /* Do a scan abort to stop the driver's scan engine */
+ err = wldev_ioctl(dev, WLC_SCAN, params, params_size, true);
+ if (err < 0) {
+ AP6210_ERR("scan abort failed \n");
+ }
+ }
+ }
+ if (timer_pending(&wl->scan_timeout))
+ del_timer_sync(&wl->scan_timeout);
+#if defined(ESCAN_RESULT_PATCH)
+ if (likely(wl->scan_request)) {
+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+ wl_inform_bss(wl);
+ }
+#endif /* ESCAN_RESULT_PATCH */
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+#ifdef WL_SCHED_SCAN
+ if (wl->sched_scan_req && !wl->scan_request) {
+ AP6210_DEBUG(">>> REPORTING SCHED SCAN RESULTS \n");
+ if (aborted)
+ cfg80211_sched_scan_stopped(wl->sched_scan_req->wiphy);
+ else
+ cfg80211_sched_scan_results(wl->sched_scan_req->wiphy);
+ wl->sched_scan_running = FALSE;
+ wl->sched_scan_req = NULL;
+ }
+#endif /* WL_SCHED_SCAN */
+ if (likely(wl->scan_request)) {
+ cfg80211_scan_done(wl->scan_request, aborted);
+ wl->scan_request = NULL;
+ }
+ if (p2p_is_on(wl))
+ wl_clr_p2p_status(wl, SCANNING);
+ wl_clr_drv_status(wl, SCANNING, dev);
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+ if (params)
+ kfree(params);
+
+ return err;
+}
+
+static s32 wl_escan_handler(struct wl_priv *wl,
+ struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ s32 err = BCME_OK;
+ s32 status = ntoh32(e->status);
+ wl_bss_info_t *bi;
+ wl_escan_result_t *escan_result;
+ wl_bss_info_t *bss = NULL;
+ wl_scan_results_t *list;
+ wifi_p2p_ie_t * p2p_ie;
+ u32 bi_length;
+ u32 i;
+ u8 *p2p_dev_addr = NULL;
+
+ AP6210_DEBUG(" enter event type : %d, status : %d \n",
+ ntoh32(e->event_type), ntoh32(e->status));
+
+ mutex_lock(&wl->usr_sync);
+ /* P2P SCAN is coming from primary interface */
+ if (wl_get_p2p_status(wl, SCANNING)) {
+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM))
+ ndev = wl->afx_hdl->dev;
+ else
+ ndev = wl->escan_info.ndev;
+
+ }
+ if (!ndev || !wl->escan_on ||
+ (!wl_get_drv_status(wl, SCANNING, ndev) &&
+ !wl->sched_scan_running)) {
+ AP6210_ERR("escan is not ready ndev %p wl->escan_on %d drv_status 0x%x\n",
+ ndev, wl->escan_on, wl_get_drv_status(wl, SCANNING, ndev));
+ goto exit;
+ }
+ if (status == WLC_E_STATUS_PARTIAL) {
+ AP6210_DEBUG("WLC_E_STATUS_PARTIAL \n");
+ escan_result = (wl_escan_result_t *) data;
+ if (!escan_result) {
+ AP6210_ERR("Invalid escan result (NULL pointer)\n");
+ goto exit;
+ }
+ if (dtoh16(escan_result->bss_count) != 1) {
+ AP6210_ERR("Invalid bss_count %d: ignoring\n", escan_result->bss_count);
+ goto exit;
+ }
+ bi = escan_result->bss_info;
+ if (!bi) {
+ AP6210_ERR("Invalid escan bss info (NULL pointer)\n");
+ goto exit;
+ }
+ bi_length = dtoh32(bi->length);
+ if (bi_length != (dtoh32(escan_result->buflen) - WL_ESCAN_RESULTS_FIXED_SIZE)) {
+ AP6210_ERR("Invalid bss_info length %d: ignoring\n", bi_length);
+ goto exit;
+ }
+
+ if (!(wl_to_wiphy(wl)->interface_modes & BIT(NL80211_IFTYPE_ADHOC))) {
+ if (dtoh16(bi->capability) & DOT11_CAP_IBSS) {
+ AP6210_DEBUG("Ignoring IBSS result\n");
+ goto exit;
+ }
+ }
+
+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) {
+ p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length);
+ if (p2p_dev_addr && !memcmp(p2p_dev_addr,
+ wl->afx_hdl->tx_dst_addr.octet, ETHER_ADDR_LEN)) {
+ s32 channel = CHSPEC_CHANNEL(
+ wl_chspec_driver_to_host(bi->chanspec));
+ AP6210_DEBUG("ACTION FRAME SCAN : Peer " MACDBG " found, channel : %d\n",
+ MAC2STRDBG(wl->afx_hdl->tx_dst_addr.octet), channel);
+ wl_clr_p2p_status(wl, SCANNING);
+ wl->afx_hdl->peer_chan = channel;
+ complete(&wl->act_frm_scan);
+ goto exit;
+ }
+
+ } else {
+ int cur_len = WL_SCAN_RESULTS_FIXED_SIZE;
+ list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
+ if (wl->p2p_net && wl->scan_request &&
+ wl->scan_request->dev == wl->p2p_net)
+#else
+ if (p2p_is_on(wl) && p2p_scan(wl))
+#endif
+ {
+#ifdef WL_HOST_BAND_MGMT
+ s32 channel = 0;
+ s32 channel_band = 0;
+#endif /* WL_HOST_BAND_MGMT */
+ /* p2p scan && allow only probe response */
+ if (bi->flags & WL_BSS_FLAGS_FROM_BEACON)
+ goto exit;
+ if ((p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset,
+ bi->ie_length)) == NULL) {
+ AP6210_ERR("Couldn't find P2PIE in probe"
+ " response/beacon\n");
+ goto exit;
+ }
+#ifdef WL_HOST_BAND_MGMT
+ channel = CHSPEC_CHANNEL(wl_chspec_driver_to_host(bi->chanspec));
+ channel_band = (channel > CH_MAX_2G_CHANNEL) ?
+ WLC_BAND_5G : WLC_BAND_2G;
+
+
+ if ((wl->curr_band == WLC_BAND_5G) &&
+ (channel_band == WLC_BAND_2G)) {
+ /* Avoid sending the GO results in band conflict */
+ if (wl_cfgp2p_retreive_p2pattrib(p2p_ie,
+ P2P_SEID_GROUP_ID) != NULL)
+ goto exit;
+ }
+#endif /* WL_HOST_BAND_MGMT */
+ }
+ for (i = 0; i < list->count; i++) {
+ bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
+ : list->bss_info;
+
+ if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
+ (CHSPEC_BAND(wl_chspec_driver_to_host(bi->chanspec))
+ == CHSPEC_BAND(wl_chspec_driver_to_host(bss->chanspec))) &&
+ bi->SSID_len == bss->SSID_len &&
+ !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
+
+ /* do not allow beacon data to update
+ *the data recd from a probe response
+ */
+ if (!(bss->flags & WL_BSS_FLAGS_FROM_BEACON) &&
+ (bi->flags & WL_BSS_FLAGS_FROM_BEACON))
+ goto exit;
+
+ AP6210_DEBUG("%s("MACDBG"), i=%d prev: RSSI %d"
+ " flags 0x%x, new: RSSI %d flags 0x%x\n",
+ bss->SSID, MAC2STRDBG(bi->BSSID.octet), i,
+ bss->RSSI, bss->flags, bi->RSSI, bi->flags);
+
+ if ((bss->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) ==
+ (bi->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL)) {
+ /* preserve max RSSI if the measurements are
+ * both on-channel or both off-channel
+ */
+ AP6210_DEBUG("%s("MACDBG"), same onchan"
+ ", RSSI: prev %d new %d\n",
+ bss->SSID, MAC2STRDBG(bi->BSSID.octet),
+ bss->RSSI, bi->RSSI);
+ bi->RSSI = MAX(bss->RSSI, bi->RSSI);
+ } else if ((bss->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) &&
+ (bi->flags & WL_BSS_FLAGS_RSSI_ONCHANNEL) == 0) {
+ /* preserve the on-channel rssi measurement
+ * if the new measurement is off channel
+ */
+ AP6210_DEBUG("%s("MACDBG"), prev onchan"
+ ", RSSI: prev %d new %d\n",
+ bss->SSID, MAC2STRDBG(bi->BSSID.octet),
+ bss->RSSI, bi->RSSI);
+ bi->RSSI = bss->RSSI;
+ bi->flags |= WL_BSS_FLAGS_RSSI_ONCHANNEL;
+ }
+ if (dtoh32(bss->length) != bi_length) {
+ u32 prev_len = dtoh32(bss->length);
+
+ AP6210_DEBUG("bss info replacement"
+ " is occured(bcast:%d->probresp%d)\n",
+ bss->ie_length, bi->ie_length);
+ AP6210_DEBUG("%s("MACDBG"), replacement!(%d -> %d)\n",
+ bss->SSID, MAC2STRDBG(bi->BSSID.octet),
+ prev_len, bi_length);
+
+ if (list->buflen - prev_len + bi_length
+ > ESCAN_BUF_SIZE) {
+ AP6210_ERR("Buffer is too small: keep the"
+ " previous result of this AP\n");
+ /* Only update RSSI */
+ bss->RSSI = bi->RSSI;
+ bss->flags |= (bi->flags
+ & WL_BSS_FLAGS_RSSI_ONCHANNEL);
+ goto exit;
+ }
+
+ if (i < list->count - 1) {
+ /* memory copy required by this case only */
+ memmove((u8 *)bss + bi_length,
+ (u8 *)bss + prev_len,
+ list->buflen - cur_len - prev_len);
+ }
+ list->buflen -= prev_len;
+ list->buflen += bi_length;
+ }
+ list->version = dtoh32(bi->version);
+ memcpy((u8 *)bss, (u8 *)bi, bi_length);
+ goto exit;
+ }
+ cur_len += dtoh32(bss->length);
+ }
+ if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
+ AP6210_ERR("Buffer is too small: ignoring\n");
+ goto exit;
+ }
+ if (strlen(bi->SSID) == 0) { // terence: fix for hidden SSID
+ AP6210_DEBUG("Skip hidden SSID %pM\n", &bi->BSSID);
+ goto exit;
+ }
+ memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length);
+ list->version = dtoh32(bi->version);
+ list->buflen += bi_length;
+ list->count++;
+ }
+
+ }
+ else if (status == WLC_E_STATUS_SUCCESS) {
+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) {
+ AP6210_DEBUG("ACTION FRAME SCAN DONE\n");
+ wl_clr_p2p_status(wl, SCANNING);
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+ if (wl->afx_hdl->peer_chan == WL_INVALID)
+ complete(&wl->act_frm_scan);
+ } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
+ AP6210_DEBUG("ESCAN COMPLETED\n");
+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+ wl_inform_bss(wl);
+ wl_notify_escan_complete(wl, ndev, false, false);
+ }
+ }
+ else if (status == WLC_E_STATUS_ABORT) {
+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) {
+ AP6210_DEBUG("ACTION FRAME SCAN DONE\n");
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+ wl_clr_p2p_status(wl, SCANNING);
+ if (wl->afx_hdl->peer_chan == WL_INVALID)
+ complete(&wl->act_frm_scan);
+ } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
+ AP6210_DEBUG("ESCAN ABORTED\n");
+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+ wl_inform_bss(wl);
+ wl_notify_escan_complete(wl, ndev, true, false);
+ }
+ }
+ else if (status == WLC_E_STATUS_NEWSCAN)
+ {
+ escan_result = (wl_escan_result_t *) data;
+ AP6210_ERR("WLC_E_STATUS_NEWSCAN : scan_request[%p]\n", wl->scan_request);
+ AP6210_ERR("sync_id[%d], bss_count[%d]\n", escan_result->sync_id,
+ escan_result->bss_count);
+ } else if (status == WLC_E_STATUS_TIMEOUT) {
+ AP6210_ERR("WLC_E_STATUS_TIMEOUT : scan_request[%p]\n", wl->scan_request);
+ AP6210_ERR("escan_on[%d], reason[0x%x]\n", wl->escan_on, e->reason);
+ if (e->reason == 0xFFFFFFFF) {
+ wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true);
+ }
+ } else {
+ AP6210_ERR("unexpected Escan Event %d : abort\n", status);
+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+ if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) {
+ AP6210_DEBUG("ACTION FRAME SCAN DONE\n");
+ wl_clr_p2p_status(wl, SCANNING);
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+ if (wl->afx_hdl->peer_chan == WL_INVALID)
+ complete(&wl->act_frm_scan);
+ } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+ wl_inform_bss(wl);
+ wl_notify_escan_complete(wl, ndev, true, false);
+ }
+ }
+exit:
+ mutex_unlock(&wl->usr_sync);
+ return err;
+}
+static void wl_cfg80211_concurrent_roam(struct wl_priv *wl, int enable)
+{
+ u32 connected_cnt = wl_get_drv_status_all(wl, CONNECTED);
+ struct net_info *iter, *next;
+ int err;
+
+ if (!wl->roamoff_on_concurrent)
+ return;
+ if (enable && connected_cnt > 1) {
+ for_each_ndev(wl, iter, next) {
+ /* Save the current roam setting */
+ if ((err = wldev_iovar_getint(iter->ndev, "roam_off",
+ (s32 *)&iter->roam_off)) != BCME_OK) {
+ AP6210_ERR("%s:Failed to get current roam setting err %d\n",
+ iter->ndev->name, err);
+ continue;
+ }
+ if ((err = wldev_iovar_setint(iter->ndev, "roam_off", 1)) != BCME_OK) {
+ AP6210_ERR(" %s:failed to set roam_off : %d\n",
+ iter->ndev->name, err);
+ }
+ }
+ }
+ else if (!enable) {
+ for_each_ndev(wl, iter, next) {
+ if (iter->roam_off != WL_INVALID) {
+ if ((err = wldev_iovar_setint(iter->ndev, "roam_off",
+ iter->roam_off)) == BCME_OK)
+ iter->roam_off = WL_INVALID;
+ else {
+ AP6210_ERR(" %s:failed to set roam_off : %d\n",
+ iter->ndev->name, err);
+ }
+ }
+ }
+ }
+ return;
+}
+
+static void wl_cfg80211_determine_vsdb_mode(struct wl_priv *wl)
+{
+ struct net_info *iter, *next;
+ u32 chan = 0;
+ u32 chanspec = 0;
+ u32 prev_chan = 0;
+ u32 connected_cnt = wl_get_drv_status_all(wl, CONNECTED);
+ wl->vsdb_mode = false;
+
+ if (connected_cnt <= 1) {
+ return;
+ }
+ for_each_ndev(wl, iter, next) {
+ chanspec = 0;
+ chan = 0;
+ if (wl_get_drv_status(wl, CONNECTED, iter->ndev)) {
+ if (wldev_iovar_getint(iter->ndev, "chanspec",
+ (s32 *)&chanspec) == BCME_OK) {
+ chan = CHSPEC_CHANNEL(chanspec);
+ if (CHSPEC_IS40(chanspec)) {
+ if (CHSPEC_SB_UPPER(chanspec))
+ chan += CH_10MHZ_APART;
+ else
+ chan -= CH_10MHZ_APART;
+ }
+ wl_update_prof(wl, iter->ndev, NULL,
+ &chan, WL_PROF_CHAN);
+ }
+ if (!prev_chan && chan)
+ prev_chan = chan;
+ else if (prev_chan && (prev_chan != chan))
+ wl->vsdb_mode = true;
+ }
+ }
+ return;
+}
+static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_info,
+ enum wl_status state, bool set)
+{
+ s32 pm = PM_FAST;
+ s32 err = BCME_OK;
+ u32 chan = 0;
+ struct net_info *iter, *next;
+ struct net_device *primary_dev = wl_to_prmry_ndev(wl);
+ AP6210_DEBUG("Enter state %d set %d _net_info->pm_restore %d iface %s\n",
+ state, set, _net_info->pm_restore, _net_info->ndev->name);
+
+ if (state != WL_STATUS_CONNECTED)
+ return 0;
+
+ if (set) {
+ wl_cfg80211_concurrent_roam(wl, 1);
+
+ if (wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) {
+ pm = PM_OFF;
+ AP6210_DEBUG("%s:AP power save %s\n", _net_info->ndev->name,
+ pm ? "enabled" : "disabled");
+ if ((err = wldev_ioctl(_net_info->ndev, WLC_SET_PM,
+ &pm, sizeof(pm), true)) != 0) {
+ if (err == -ENODEV)
+ AP6210_DEBUG("%s:net_device is not ready\n",
+ _net_info->ndev->name);
+ else
+ AP6210_ERR("%s:error (%d)\n", _net_info->ndev->name, err);
+ }
+ if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, false))
+ AP6210_ERR(" failed to unset WLC_E_P2P_PROPREQ_MSG\n");
+ return 0;
+ }
+ wl_cfg80211_determine_vsdb_mode(wl);
+ pm = PM_OFF;
+ for_each_ndev(wl, iter, next) {
+ if ((!wl->vsdb_mode) && (iter->ndev != _net_info->ndev)) {
+ /* Do not touch the other interfaces power save
+ * if we are not in vsdb mode
+ */
+ continue;
+ }
+ /* Save the current power mode */
+ iter->pm_restore = true;
+ err = wldev_ioctl(iter->ndev, WLC_GET_PM, &iter->pm,
+ sizeof(iter->pm), false);
+ AP6210_DEBUG("%s:power save %s\n", iter->ndev->name,
+ iter->pm ? "enabled" : "disabled");
+ if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm,
+ sizeof(pm), true)) != 0) {
+ if (err == -ENODEV)
+ AP6210_DEBUG("%s:netdev not ready\n", iter->ndev->name);
+ else
+ AP6210_ERR("%s:error (%d)\n", iter->ndev->name, err);
+ iter->ndev->ieee80211_ptr->ps = pm ? true: false;
+ }
+ }
+ }
+ else { /* clear */
+ chan = 0;
+ /* clear chan information when the net device is disconnected */
+ wl_update_prof(wl, _net_info->ndev, NULL, &chan, WL_PROF_CHAN);
+ wl_cfg80211_determine_vsdb_mode(wl);
+ for_each_ndev(wl, iter, next) {
+ if (iter->pm_restore) {
+ AP6210_DEBUG("%s:restoring power save %s\n",
+ iter->ndev->name, (iter->pm ? "enabled" : "disabled"));
+ err = wldev_ioctl(iter->ndev,
+ WLC_SET_PM, &iter->pm, sizeof(iter->pm), true);
+ if (unlikely(err)) {
+ if (err == -ENODEV)
+ AP6210_DEBUG("%s:netdev not ready\n", iter->ndev->name);
+ else
+ AP6210_ERR("%s:error(%d)\n", iter->ndev->name, err);
+ break;
+ }
+ iter->pm_restore = 0;
+ }
+ }
+ wl_cfg80211_concurrent_roam(wl, 0);
+ }
+ return err;
+}
+
+static s32 wl_init_scan(struct wl_priv *wl)
+{
+ struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+ int err = 0;
+
+ if (wl->iscan_on) {
+ iscan->dev = wl_to_prmry_ndev(wl);
+ iscan->state = WL_ISCAN_STATE_IDLE;
+ wl_init_iscan_handler(iscan);
+ iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
+ init_timer(&iscan->timer);
+ iscan->timer.data = (unsigned long) iscan;
+ iscan->timer.function = wl_iscan_timer;
+ sema_init(&iscan->sync, 0);
+ iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
+ if (IS_ERR(iscan->tsk)) {
+ AP6210_ERR("Could not create iscan thread\n");
+ iscan->tsk = NULL;
+ return -ENOMEM;
+ }
+ iscan->data = wl;
+ } else if (wl->escan_on) {
+ wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler;
+ wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+ }
+ /* Init scan_timeout timer */
+ init_timer(&wl->scan_timeout);
+ wl->scan_timeout.data = (unsigned long) wl;
+ wl->scan_timeout.function = wl_scan_timeout;
+
+ return err;
+}
+
+static s32 wl_init_priv(struct wl_priv *wl)
+{
+ struct wiphy *wiphy = wl_to_wiphy(wl);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ s32 err = 0;
+
+ wl->scan_request = NULL;
+ wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
+ wl->iscan_on = false;
+ wl->escan_on = true;
+ wl->roam_on = false;
+ wl->iscan_kickstart = false;
+ wl->active_scan = true;
+ wl->rf_blocked = false;
+ wl->vsdb_mode = false;
+ wl->wlfc_on = false;
+ wl->roamoff_on_concurrent = true;
+ /* register interested state */
+ set_bit(WL_STATUS_CONNECTED, &wl->interrested_state);
+ spin_lock_init(&wl->cfgdrv_lock);
+ mutex_init(&wl->ioctl_buf_sync);
+ init_waitqueue_head(&wl->netif_change_event);
+ init_completion(&wl->send_af_done);
+ init_completion(&wl->iface_disable);
+ wl_init_eq(wl);
+ err = wl_init_priv_mem(wl);
+ if (err)
+ return err;
+ if (wl_create_event_handler(wl))
+ return -ENOMEM;
+ wl_init_event_handler(wl);
+ mutex_init(&wl->usr_sync);
+ mutex_init(&wl->event_sync);
+ err = wl_init_scan(wl);
+ if (err)
+ return err;
+ wl_init_conf(wl->conf);
+ wl_init_prof(wl, ndev);
+ wl_link_down(wl);
+ DNGL_FUNC(dhd_cfg80211_init, (wl));
+
+ return err;
+}
+
+static void wl_deinit_priv(struct wl_priv *wl)
+{
+ DNGL_FUNC(dhd_cfg80211_deinit, (wl));
+ wl_destroy_event_handler(wl);
+ wl_flush_eq(wl);
+ wl_link_down(wl);
+ del_timer_sync(&wl->scan_timeout);
+ wl_term_iscan(wl);
+ wl_deinit_priv_mem(wl);
+ unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier);
+}
+
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
+static s32 wl_cfg80211_attach_p2p(void)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+ AP6210_DEBUG("Enter \n");
+
+ if (wl_cfgp2p_register_ndev(wl) < 0) {
+ AP6210_ERR("%s: P2P attach failed. \n", __func__);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static s32 wl_cfg80211_detach_p2p(void)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct wireless_dev *wdev = wl->p2p_wdev;
+
+ AP6210_DEBUG("Enter \n");
+ if (!wdev || !wl) {
+ AP6210_ERR("Invalid Ptr\n");
+ return -EINVAL;
+ }
+
+ wl_cfgp2p_unregister_ndev(wl);
+
+ wl->p2p_wdev = NULL;
+ wl->p2p_net = NULL;
+ AP6210_DEBUG("Freeing 0x%08x \n", (unsigned int)wdev);
+ kfree(wdev);
+
+ return 0;
+}
+#endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */
+
+s32 wl_cfg80211_attach_post(struct net_device *ndev)
+{
+ struct wl_priv * wl = NULL;
+ s32 err = 0;
+ AP6210_DEBUG("In\n");
+ if (unlikely(!ndev)) {
+ AP6210_ERR("ndev is invaild\n");
+ return -ENODEV;
+ }
+ wl = wlcfg_drv_priv;
+ if (unlikely(!wl)) {
+ AP6210_ERR("wl is invaild\n");
+ return -EINVAL;
+ }
+ if (!wl_get_drv_status(wl, READY, ndev)) {
+ if (wl->wdev &&
+ wl_cfgp2p_supported(wl, ndev)) {
+#if !defined(WL_ENABLE_P2P_IF)
+ wl->wdev->wiphy->interface_modes |=
+ (BIT(NL80211_IFTYPE_P2P_CLIENT)|
+ BIT(NL80211_IFTYPE_P2P_GO));
+#endif
+ if ((err = wl_cfgp2p_init_priv(wl)) != 0)
+ goto fail;
+
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
+ if (wl->p2p_net) {
+ /* Update MAC addr for p2p0 interface here. */
+ memcpy(wl->p2p_net->dev_addr, ndev->dev_addr, ETH_ALEN);
+ wl->p2p_net->dev_addr[0] |= 0x02;
+ AP6210_ERR("%s: p2p_dev_addr="MACDBG "\n",
+ wl->p2p_net->name,
+ MAC2STRDBG(wl->p2p_net->dev_addr));
+ } else {
+ AP6210_ERR("p2p_net not yet populated."
+ " Couldn't update the MAC Address for p2p0 \n");
+ return -ENODEV;
+ }
+#endif /* defined(WLP2P) && (WL_ENABLE_P2P_IF) */
+
+ wl->p2p_supported = true;
+ }
+ }
+ wl_set_drv_status(wl, READY, ndev);
+fail:
+ return err;
+}
+
+s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
+{
+ struct wireless_dev *wdev;
+ struct wl_priv *wl;
+ s32 err = 0;
+ struct device *dev;
+
+ AP6210_DEBUG("In\n");
+ if (!ndev) {
+ AP6210_ERR("ndev is invaild\n");
+ return -ENODEV;
+ }
+ AP6210_DEBUG("func %p\n", wl_cfg80211_get_parent_dev());
+ dev = wl_cfg80211_get_parent_dev();
+
+ wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+ if (unlikely(!wdev)) {
+ AP6210_ERR("Could not allocate wireless device\n");
+ return -ENOMEM;
+ }
+ err = wl_setup_wiphy(wdev, dev);
+ if (unlikely(err)) {
+ kfree(wdev);
+ return -ENOMEM;
+ }
+ wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
+ wl = (struct wl_priv *)wiphy_priv(wdev->wiphy);
+ wl->wdev = wdev;
+ wl->pub = data;
+ INIT_LIST_HEAD(&wl->net_list);
+ ndev->ieee80211_ptr = wdev;
+ SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
+ wdev->netdev = ndev;
+ wl->state_notifier = wl_notifier_change_state;
+ err = wl_alloc_netinfo(wl, ndev, wdev, WL_MODE_BSS, PM_ENABLE);
+ if (err) {
+ AP6210_ERR("Failed to alloc net_info (%d)\n", err);
+ goto cfg80211_attach_out;
+ }
+ err = wl_init_priv(wl);
+ if (err) {
+ AP6210_ERR("Failed to init iwm_priv (%d)\n", err);
+ goto cfg80211_attach_out;
+ }
+
+ err = wl_setup_rfkill(wl, TRUE);
+ if (err) {
+ AP6210_ERR("Failed to setup rfkill %d\n", err);
+ goto cfg80211_attach_out;
+ }
+ err = register_netdevice_notifier(&wl_cfg80211_netdev_notifier);
+ if (err) {
+ AP6210_ERR("Failed to register notifierl %d\n", err);
+ goto cfg80211_attach_out;
+ }
+#if defined(COEX_DHCP)
+ if (wl_cfg80211_btcoex_init(wl))
+ goto cfg80211_attach_out;
+#endif
+#if defined(BSSCACHE)
+ wl_init_bss_cache_ctrl(&g_bss_cache_ctrl);
+#endif
+
+ wlcfg_drv_priv = wl;
+
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
+ err = wl_cfg80211_attach_p2p();
+ if (err)
+ goto cfg80211_attach_out;
+#endif
+
+ return err;
+
+cfg80211_attach_out:
+ err = wl_setup_rfkill(wl, FALSE);
+ wl_free_wdev(wl);
+ return err;
+}
+
+void wl_cfg80211_detach(void *para)
+{
+ struct wl_priv *wl;
+
+ (void)para;
+ wl = wlcfg_drv_priv;
+
+ AP6210_DEBUG("In\n");
+
+#if defined(COEX_DHCP)
+ wl_cfg80211_btcoex_deinit(wl);
+#endif
+
+ wl_setup_rfkill(wl, FALSE);
+ if (wl->p2p_supported) {
+ if (timer_pending(&wl->p2p->listen_timer))
+ del_timer_sync(&wl->p2p->listen_timer);
+ wl_cfgp2p_deinit_priv(wl);
+ }
+
+#if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
+ wl_cfg80211_detach_p2p();
+#endif
+ wl_deinit_priv(wl);
+ wlcfg_drv_priv = NULL;
+ wl_cfg80211_clear_parent_dev();
+ wl_free_wdev(wl);
+#if defined(RSSIAVG)
+ wl_free_rssi_cache(&g_rssi_cache_ctrl);
+#endif
+#if defined(BSSCACHE)
+ wl_release_bss_cache_ctrl(&g_bss_cache_ctrl);
+#endif
+ /* PLEASE do NOT call any function after wl_free_wdev, the driver's private structure "wl",
+ * which is the private part of wiphy, has been freed in wl_free_wdev !!!!!!!!!!!
+ */
+}
+
+static void wl_wakeup_event(struct wl_priv *wl)
+{
+ if (wl->event_tsk.thr_pid >= 0) {
+ DHD_OS_WAKE_LOCK(wl->pub);
+ up(&wl->event_tsk.sema);
+ }
+}
+
+static int wl_is_p2p_event(struct wl_event_q *e)
+{
+ switch (e->etype) {
+ /* We have to seperate out the P2P events received
+ * on primary interface so that it can be send up
+ * via p2p0 interface.
+ */
+ case WLC_E_P2P_PROBREQ_MSG:
+ case WLC_E_P2P_DISC_LISTEN_COMPLETE:
+ case WLC_E_ACTION_FRAME_RX:
+ case WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE:
+ case WLC_E_ACTION_FRAME_COMPLETE:
+
+ if (e->emsg.ifidx != 0) {
+ AP6210_DEBUG("P2P Event on Virtual I/F (ifidx:%d) \n",
+ e->emsg.ifidx);
+ /* We are only bothered about the P2P events received
+ * on primary interface. For rest of them return false
+ * so that it is sent over the interface corresponding
+ * to the ifidx.
+ */
+ return FALSE;
+ } else {
+ AP6210_DEBUG("P2P Event on Primary I/F (ifidx:%d)."
+ " Sent it to p2p0 \n", e->emsg.ifidx);
+ return TRUE;
+ }
+ break;
+
+ default:
+ AP6210_DEBUG("NON-P2P Event %d on ifidx (ifidx:%d) \n",
+ e->etype, e->emsg.ifidx);
+ return FALSE;
+ }
+}
+
+static s32 wl_event_handler(void *data)
+{
+ struct net_device *netdev;
+ struct wl_priv *wl = NULL;
+ struct wl_event_q *e;
+ tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+
+ wl = (struct wl_priv *)tsk->parent;
+#ifndef USE_KTHREAD_API
+ DAEMONIZE("dhd_cfg80211_event");
+ complete(&tsk->completed);
+#else
+ AP6210_ERR("tsk Enter, tsk = 0x%08x\n", (unsigned int)tsk);
+#endif
+
+ while (down_interruptible (&tsk->sema) == 0) {
+ SMP_RD_BARRIER_DEPENDS();
+ if (tsk->terminated)
+ break;
+ while ((e = wl_deq_event(wl))) {
+ AP6210_DEBUG("event type (%d), if idx: %d\n", e->etype, e->emsg.ifidx);
+ /* All P2P device address related events comes on primary interface since
+ * there is no corresponding bsscfg for P2P interface. Map it to p2p0
+ * interface.
+ */
+ if ((wl_is_p2p_event(e) == TRUE) && (wl->p2p_net)) {
+ netdev = wl->p2p_net;
+ } else {
+ netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx);
+ }
+ if (!netdev)
+ netdev = wl_to_prmry_ndev(wl);
+ if (e->etype < WLC_E_LAST && wl->evt_handler[e->etype]) {
+ wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata);
+ } else {
+ AP6210_DEBUG("Unknown Event (%d): ignoring\n", e->etype);
+ }
+ wl_put_event(e);
+ }
+ DHD_OS_WAKE_UNLOCK(wl->pub);
+ }
+ AP6210_ERR("%s was terminated\n", __func__);
+ complete_and_exit(&tsk->completed, 0);
+ return 0;
+}
+
+void
+wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
+{
+ u32 event_type = ntoh32(e->event_type);
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+#if (WL_DBG_LEVEL > 0)
+ s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
+ wl_dbg_estr[event_type] : (s8 *) "Unknown";
+ AP6210_DEBUG("event_type (%d):" "WLC_E_" "%s\n", event_type, estr);
+#endif /* (WL_DBG_LEVEL > 0) */
+
+ if (event_type == WLC_E_PFN_NET_FOUND) {
+ AP6210_DEBUG(" PNOEVENT: PNO_NET_FOUND\n");
+ }
+ else if (event_type == WLC_E_PFN_NET_LOST) {
+ AP6210_DEBUG(" PNOEVENT: PNO_NET_LOST\n");
+ }
+
+ if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
+ wl_wakeup_event(wl);
+}
+
+static void wl_init_eq(struct wl_priv *wl)
+{
+ wl_init_eq_lock(wl);
+ INIT_LIST_HEAD(&wl->eq_list);
+}
+
+static void wl_flush_eq(struct wl_priv *wl)
+{
+ struct wl_event_q *e;
+ unsigned long flags;
+
+ flags = wl_lock_eq(wl);
+ while (!list_empty(&wl->eq_list)) {
+ e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
+ list_del(&e->eq_list);
+ kfree(e);
+ }
+ wl_unlock_eq(wl, flags);
+}
+
+/*
+* retrieve first queued event from head
+*/
+
+static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
+{
+ struct wl_event_q *e = NULL;
+ unsigned long flags;
+
+ flags = wl_lock_eq(wl);
+ if (likely(!list_empty(&wl->eq_list))) {
+ e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
+ list_del(&e->eq_list);
+ }
+ wl_unlock_eq(wl, flags);
+
+ return e;
+}
+
+/*
+ * push event to tail of the queue
+ */
+
+static s32
+wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg,
+ void *data)
+{
+ struct wl_event_q *e;
+ s32 err = 0;
+ uint32 evtq_size;
+ uint32 data_len;
+ unsigned long flags;
+ gfp_t aflags;
+
+ data_len = 0;
+ if (data)
+ data_len = ntoh32(msg->datalen);
+ evtq_size = sizeof(struct wl_event_q) + data_len;
+ aflags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
+ e = kzalloc(evtq_size, aflags);
+ if (unlikely(!e)) {
+ AP6210_ERR("event alloc failed\n");
+ return -ENOMEM;
+ }
+ e->etype = event;
+ memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
+ if (data)
+ memcpy(e->edata, data, data_len);
+ flags = wl_lock_eq(wl);
+ list_add_tail(&e->eq_list, &wl->eq_list);
+ wl_unlock_eq(wl, flags);
+
+ return err;
+}
+
+static void wl_put_event(struct wl_event_q *e)
+{
+ kfree(e);
+}
+
+static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype)
+{
+ s32 infra = 0;
+ s32 err = 0;
+ s32 mode = 0;
+ switch (iftype) {
+ case NL80211_IFTYPE_MONITOR:
+ case NL80211_IFTYPE_WDS:
+ AP6210_ERR("type (%d) : currently we do not support this mode\n",
+ iftype);
+ err = -EINVAL;
+ return err;
+ case NL80211_IFTYPE_ADHOC:
+ mode = WL_MODE_IBSS;
+ break;
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ mode = WL_MODE_BSS;
+ infra = 1;
+ break;
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
+ mode = WL_MODE_AP;
+ infra = 1;
+ break;
+ default:
+ err = -EINVAL;
+ AP6210_ERR("invalid type (%d)\n", iftype);
+ return err;
+ }
+ infra = htod32(infra);
+ err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), true);
+ if (unlikely(err)) {
+ AP6210_ERR("WLC_SET_INFRA error (%d)\n", err);
+ return err;
+ }
+
+ wl_set_mode_by_netdev(wl, ndev, mode);
+
+ return 0;
+}
+
+void wl_cfg80211_add_to_eventbuffer(struct wl_eventmsg_buf *ev, u16 event, bool set)
+{
+ if (!ev || (event > WLC_E_LAST))
+ return;
+
+ if (ev->num < MAX_EVENT_BUF_NUM) {
+ ev->event[ev->num].type = event;
+ ev->event[ev->num].set = set;
+ ev->num++;
+ } else {
+ AP6210_ERR("evenbuffer doesn't support > %u events. Update"
+ " the define MAX_EVENT_BUF_NUM \n", MAX_EVENT_BUF_NUM);
+ ASSERT(0);
+ }
+}
+
+s32 wl_cfg80211_apply_eventbuffer(
+ struct net_device *ndev,
+ struct wl_priv *wl,
+ wl_eventmsg_buf_t *ev)
+{
+ char eventmask[WL_EVENTING_MASK_LEN];
+ int i, ret = 0;
+ s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
+
+ if (!ev || (!ev->num))
+ return -EINVAL;
+
+ mutex_lock(&wl->event_sync);
+
+ /* Read event_msgs mask */
+ bcm_mkiovar("event_msgs", NULL, 0, iovbuf,
+ sizeof(iovbuf));
+ ret = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
+ if (unlikely(ret)) {
+ AP6210_ERR("Get event_msgs error (%d)\n", ret);
+ goto exit;
+ }
+ memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+
+ /* apply the set bits */
+ for (i = 0; i < ev->num; i++) {
+ if (ev->event[i].set)
+ setbit(eventmask, ev->event[i].type);
+ else
+ clrbit(eventmask, ev->event[i].type);
+ }
+
+ /* Write updated Event mask */
+ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+ sizeof(iovbuf));
+ ret = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
+ if (unlikely(ret)) {
+ AP6210_ERR("Set event_msgs error (%d)\n", ret);
+ }
+
+exit:
+ mutex_unlock(&wl->event_sync);
+ return ret;
+}
+
+s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
+{
+ s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
+ s8 eventmask[WL_EVENTING_MASK_LEN];
+ s32 err = 0;
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+ if (!ndev || !wl)
+ return -ENODEV;
+
+ mutex_lock(&wl->event_sync);
+
+ /* Setup event_msgs */
+ bcm_mkiovar("event_msgs", NULL, 0, iovbuf,
+ sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
+ if (unlikely(err)) {
+ AP6210_ERR("Get event_msgs error (%d)\n", err);
+ goto eventmsg_out;
+ }
+ memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+ if (add) {
+ setbit(eventmask, event);
+ } else {
+ clrbit(eventmask, event);
+ }
+ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+ sizeof(iovbuf));
+ err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
+ if (unlikely(err)) {
+ AP6210_ERR("Set event_msgs error (%d)\n", err);
+ goto eventmsg_out;
+ }
+
+eventmsg_out:
+ mutex_unlock(&wl->event_sync);
+ return err;
+}
+
+static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap)
+{
+ struct net_device *dev = wl_to_prmry_ndev(wl);
+ struct ieee80211_channel *band_chan_arr = NULL;
+ wl_uint32_list_t *list;
+ u32 i, j, index, n_2g, n_5g, band, channel, array_size;
+ u32 *n_cnt = NULL;
+ chanspec_t c = 0;
+ s32 err = BCME_OK;
+ bool update;
+ bool ht40_allowed;
+ u8 *pbuf = NULL;
+
+#define LOCAL_BUF_LEN 1024
+ pbuf = kzalloc(LOCAL_BUF_LEN, GFP_KERNEL);
+
+ if (pbuf == NULL) {
+ AP6210_ERR("failed to allocate local buf\n");
+ return -ENOMEM;
+ }
+ list = (wl_uint32_list_t *)(void *) pbuf;
+ list->count = htod32(WL_NUMCHANSPECS);
+
+
+ err = wldev_iovar_getbuf_bsscfg(dev, "chanspecs", NULL,
+ 0, pbuf, LOCAL_BUF_LEN, 0, &wl->ioctl_buf_sync);
+ if (err != 0) {
+ AP6210_ERR("get chanspecs failed with %d\n", err);
+ kfree(pbuf);
+ return err;
+ }
+#undef LOCAL_BUF_LEN
+
+ list = (wl_uint32_list_t *)(void *)pbuf;
+ band = array_size = n_2g = n_5g = 0;
+ for (i = 0; i < dtoh32(list->count); i++) {
+ index = 0;
+ update = false;
+ ht40_allowed = false;
+ c = (chanspec_t)dtoh32(list->element[i]);
+ c = wl_chspec_driver_to_host(c);
+ channel = CHSPEC_CHANNEL(c);
+ if (CHSPEC_IS40(c)) {
+ if (CHSPEC_SB_UPPER(c))
+ channel += CH_10MHZ_APART;
+ else
+ channel -= CH_10MHZ_APART;
+ } else if (CHSPEC_IS80(c)) {
+ AP6210_DEBUG("HT80 center channel : %d\n", channel);
+ continue;
+ }
+ if (CHSPEC_IS2G(c) && (channel >= CH_MIN_2G_CHANNEL) &&
+ (channel <= CH_MAX_2G_CHANNEL)) {
+ band_chan_arr = __wl_2ghz_channels;
+ array_size = ARRAYSIZE(__wl_2ghz_channels);
+ n_cnt = &n_2g;
+ band = IEEE80211_BAND_2GHZ;
+ ht40_allowed = (bw_cap == WLC_N_BW_40ALL)? true : false;
+ } else if (CHSPEC_IS5G(c) && channel >= CH_MIN_5G_CHANNEL) {
+ band_chan_arr = __wl_5ghz_a_channels;
+ array_size = ARRAYSIZE(__wl_5ghz_a_channels);
+ n_cnt = &n_5g;
+ band = IEEE80211_BAND_5GHZ;
+ ht40_allowed = (bw_cap == WLC_N_BW_20ALL)? false : true;
+ } else {
+ AP6210_ERR("Invalid channel Sepc. 0x%x.\n", c);
+ continue;
+ }
+ if (!ht40_allowed && CHSPEC_IS40(c))
+ continue;
+ for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
+ if (band_chan_arr[j].hw_value == channel) {
+ update = true;
+ break;
+ }
+ }
+ if (update)
+ index = j;
+ else
+ index = *n_cnt;
+ if (index < array_size) {
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+ band_chan_arr[index].center_freq =
+ ieee80211_channel_to_frequency(channel);
+#else
+ band_chan_arr[index].center_freq =
+ ieee80211_channel_to_frequency(channel, band);
+#endif
+ band_chan_arr[index].hw_value = channel;
+
+ if (CHSPEC_IS40(c) && ht40_allowed) {
+ /* assuming the order is HT20, HT40 Upper,
+ HT40 lower from chanspecs
+ */
+ u32 ht40_flag = band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40;
+ if (CHSPEC_SB_UPPER(c)) {
+ if (ht40_flag == IEEE80211_CHAN_NO_HT40)
+ band_chan_arr[index].flags &=
+ ~IEEE80211_CHAN_NO_HT40;
+ band_chan_arr[index].flags |= IEEE80211_CHAN_NO_HT40PLUS;
+ } else {
+ /* It should be one of
+ IEEE80211_CHAN_NO_HT40 or IEEE80211_CHAN_NO_HT40PLUS
+ */
+ band_chan_arr[index].flags &= ~IEEE80211_CHAN_NO_HT40;
+ if (ht40_flag == IEEE80211_CHAN_NO_HT40)
+ band_chan_arr[index].flags |=
+ IEEE80211_CHAN_NO_HT40MINUS;
+ }
+ } else {
+ band_chan_arr[index].flags = IEEE80211_CHAN_NO_HT40;
+ if (band == IEEE80211_BAND_2GHZ)
+ channel |= WL_CHANSPEC_BAND_2G;
+ else
+ channel |= WL_CHANSPEC_BAND_5G;
+ channel |= WL_CHANSPEC_BW_20;
+ channel = wl_chspec_host_to_driver(channel);
+ err = wldev_iovar_getint(dev, "per_chan_info", &channel);
+ if (!err) {
+ if (channel & WL_CHAN_RADAR)
+ band_chan_arr[index].flags |=
+ (IEEE80211_CHAN_RADAR |
+ IEEE80211_CHAN_NO_IBSS);
+ if (channel & WL_CHAN_PASSIVE)
+ band_chan_arr[index].flags |=
+ IEEE80211_CHAN_PASSIVE_SCAN;
+ }
+ }
+ if (!update)
+ (*n_cnt)++;
+ }
+
+ }
+ __wl_band_2ghz.n_channels = n_2g;
+ __wl_band_5ghz_a.n_channels = n_5g;
+ kfree(pbuf);
+ return err;
+}
+
+s32 wl_update_wiphybands(struct wl_priv *wl, bool notify)
+{
+ struct wiphy *wiphy;
+ struct net_device *dev;
+ u32 bandlist[3];
+ u32 nband = 0;
+ u32 i = 0;
+ s32 err = 0;
+ s32 index = 0;
+ s32 nmode = 0;
+ bool rollback_lock = false;
+ s32 bw_cap = 0;
+ s32 cur_band = -1;
+ struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS] = {NULL, };
+
+ if (wl == NULL) {
+ wl = wlcfg_drv_priv;
+ mutex_lock(&wl->usr_sync);
+ rollback_lock = true;
+ }
+ dev = wl_to_prmry_ndev(wl);
+
+ memset(bandlist, 0, sizeof(bandlist));
+ err = wldev_ioctl(dev, WLC_GET_BANDLIST, bandlist,
+ sizeof(bandlist), false);
+ if (unlikely(err)) {
+ AP6210_ERR("error read bandlist (%d)\n", err);
+ goto end_bands;
+ }
+
+ wiphy = wl_to_wiphy(wl);
+
+ err = wldev_ioctl(dev, WLC_GET_BAND, &cur_band,
+ sizeof(s32), false);
+ if (unlikely(err)) {
+ AP6210_ERR("error (%d)\n", err);
+ goto end_bands;
+ }
+
+ err = wldev_iovar_getint(dev, "nmode", &nmode);
+ if (unlikely(err)) {
+ AP6210_ERR("error reading nmode (%d)\n", err);
+ } else {
+ /* For nmodeonly check bw cap */
+ err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
+ if (unlikely(err)) {
+ AP6210_ERR("error get mimo_bw_cap (%d)\n", err);
+ }
+ }
+
+ err = wl_construct_reginfo(wl, bw_cap);
+ if (err) {
+ AP6210_ERR("wl_construct_reginfo() fails err=%d\n", err);
+ if (err != BCME_UNSUPPORTED)
+ goto end_bands;
+ err = 0;
+ }
+
+ nband = bandlist[0];
+
+ for (i = 1; i <= nband && i < ARRAYSIZE(bandlist); i++) {
+ index = -1;
+ if (bandlist[i] == WLC_BAND_5G && __wl_band_5ghz_a.n_channels > 0) {
+ bands[IEEE80211_BAND_5GHZ] =
+ &__wl_band_5ghz_a;
+ index = IEEE80211_BAND_5GHZ;
+ if (bw_cap == WLC_N_BW_40ALL || bw_cap == WLC_N_BW_20IN2G_40IN5G)
+ bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+ }
+ else if (bandlist[i] == WLC_BAND_2G && __wl_band_2ghz.n_channels > 0) {
+ bands[IEEE80211_BAND_2GHZ] =
+ &__wl_band_2ghz;
+ index = IEEE80211_BAND_2GHZ;
+ if (bw_cap == WLC_N_BW_40ALL)
+ bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+ }
+
+ if ((index >= 0) && nmode) {
+ bands[index]->ht_cap.cap |=
+ (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40);
+ bands[index]->ht_cap.ht_supported = TRUE;
+ bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+ bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+ /* An HT shall support all EQM rates for one spatial stream */
+ bands[index]->ht_cap.mcs.rx_mask[0] = 0xff;
+ }
+
+ }
+
+ wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
+ wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
+
+ if (notify)
+ wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
+
+end_bands:
+ if (rollback_lock)
+ mutex_unlock(&wl->usr_sync);
+ return err;
+}
+
+static s32 __wl_cfg80211_up(struct wl_priv *wl)
+{
+ s32 err = 0;
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ struct wireless_dev *wdev = ndev->ieee80211_ptr;
+
+ AP6210_DEBUG("In\n");
+
+ err = dhd_config_dongle(wl, false);
+ if (unlikely(err))
+ return err;
+
+ err = wl_config_ifmode(wl, ndev, wdev->iftype);
+ if (unlikely(err && err != -EINPROGRESS)) {
+ AP6210_ERR("wl_config_ifmode failed\n");
+ }
+ err = wl_update_wiphybands(wl, true);
+ if (unlikely(err)) {
+ AP6210_ERR("wl_update_wiphybands failed\n");
+ }
+
+ err = dhd_monitor_init(wl->pub);
+ err = wl_invoke_iscan(wl);
+
+#ifdef WL_HOST_BAND_MGMT
+ /* By default the curr_band is initialized to BAND_AUTO */
+ if (wl_cfg80211_set_band(ndev, WLC_BAND_AUTO) < 0) {
+ AP6210_ERR("roam_band set failed\n");
+ err = -1;
+ }
+#endif /* WL_HOST_BAND_MGMT */
+
+#if defined(DHCP_SCAN_SUPPRESS)
+ /* wlan scan_supp timer and work thread info */
+ init_timer(&wl->scan_supp_timer);
+ wl->scan_supp_timer.data = (ulong)wl;
+ wl->scan_supp_timer.function = wl_cfg80211_scan_supp_timerfunc;
+ INIT_WORK(&wl->wlan_work, wl_cfg80211_work_handler);
+#endif /* DHCP_SCAN_SUPPRESS */
+
+ wl_set_drv_status(wl, READY, ndev);
+ return err;
+}
+
+static s32 __wl_cfg80211_down(struct wl_priv *wl)
+{
+ s32 err = 0;
+ unsigned long flags;
+ struct net_info *iter, *next;
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ struct net_device *p2p_net = wl->p2p_net;
+ u32 bssidx = wl_cfgp2p_find_idx(wl, ndev);
+ AP6210_DEBUG("In\n");
+
+#if defined(DHCP_SCAN_SUPPRESS)
+ /* Force clear of scan_suppress */
+ if (wl->scan_suppressed)
+ wl_cfg80211_scan_suppress(ndev, 0);
+ if (timer_pending(&wl->scan_supp_timer))
+ del_timer_sync(&wl->scan_supp_timer);
+ cancel_work_sync(&wl->wlan_work);
+#endif /* DHCP_SCAN_SUPPRESS */
+
+ /* If BSS is operational (e.g SoftAp), bring it down */
+ if (wl_cfgp2p_bss_isup(ndev, bssidx)) {
+ if (wl_cfgp2p_bss(wl, ndev, bssidx, 0) < 0)
+ AP6210_ERR("BSS down failed \n");
+ }
+
+ /* Check if cfg80211 interface is already down */
+ if (!wl_get_drv_status(wl, READY, ndev))
+ return err; /* it is even not ready */
+
+ for_each_ndev(wl, iter, next)
+ wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev);
+
+ wl_term_iscan(wl);
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ if (wl->scan_request) {
+ cfg80211_scan_done(wl->scan_request, true);
+ wl->scan_request = NULL;
+ }
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+
+ for_each_ndev(wl, iter, next) {
+ wl_clr_drv_status(wl, READY, iter->ndev);
+ wl_clr_drv_status(wl, SCANNING, iter->ndev);
+ wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev);
+ wl_clr_drv_status(wl, CONNECTING, iter->ndev);
+ wl_clr_drv_status(wl, CONNECTED, iter->ndev);
+ wl_clr_drv_status(wl, DISCONNECTING, iter->ndev);
+ wl_clr_drv_status(wl, AP_CREATED, iter->ndev);
+ wl_clr_drv_status(wl, AP_CREATING, iter->ndev);
+ }
+ wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype =
+ NL80211_IFTYPE_STATION;
+ if (p2p_net)
+ dev_close(p2p_net);
+ DNGL_FUNC(dhd_cfg80211_down, (wl));
+ wl_flush_eq(wl);
+ wl_link_down(wl);
+ if (wl->p2p_supported)
+ wl_cfgp2p_down(wl);
+ dhd_monitor_uninit();
+
+ return err;
+}
+
+s32 wl_cfg80211_up(void *para)
+{
+ struct wl_priv *wl;
+ s32 err = 0;
+ int val = 1;
+ dhd_pub_t *dhd;
+
+ (void)para;
+ AP6210_DEBUG("In\n");
+ wl = wlcfg_drv_priv;
+
+ if ((err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_VERSION, &val,
+ sizeof(int), false) < 0)) {
+ AP6210_ERR("WLC_GET_VERSION failed, err=%d\n", err);
+ return err;
+ }
+ val = dtoh32(val);
+ if (val != WLC_IOCTL_VERSION && val != 1) {
+ AP6210_ERR("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
+ val, WLC_IOCTL_VERSION);
+ return BCME_VERSION;
+ }
+ ioctl_version = val;
+ AP6210_DEBUG("WLC_GET_VERSION=%d\n", ioctl_version);
+
+ mutex_lock(&wl->usr_sync);
+ dhd = (dhd_pub_t *)(wl->pub);
+ if (!(dhd->op_mode & DHD_FLAG_HOSTAP_MODE)) {
+ err = wl_cfg80211_attach_post(wl_to_prmry_ndev(wl));
+ if (unlikely(err))
+ return err;
+ }
+ err = __wl_cfg80211_up(wl);
+ if (unlikely(err))
+ AP6210_ERR("__wl_cfg80211_up failed\n");
+ mutex_unlock(&wl->usr_sync);
+ return err;
+}
+
+/* Private Event to Supplicant with indication that chip hangs */
+int wl_cfg80211_hang(struct net_device *dev, u16 reason)
+{
+ struct wl_priv *wl;
+ wl = wlcfg_drv_priv;
+
+ AP6210_ERR("In : chip crash eventing\n");
+ cfg80211_disconnected(dev, reason, NULL, 0, GFP_KERNEL);
+#if defined(RSSIAVG)
+ wl_free_rssi_cache(&g_rssi_cache_ctrl);
+#endif
+#if defined(BSSCACHE)
+ wl_free_bss_cache(&g_bss_cache_ctrl);
+ wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0);
+#endif
+ if (wl != NULL) {
+ wl_link_down(wl);
+ }
+ return 0;
+}
+
+s32 wl_cfg80211_down(void *para)
+{
+ struct wl_priv *wl;
+ s32 err = 0;
+
+ (void)para;
+ AP6210_DEBUG("In\n");
+ wl = wlcfg_drv_priv;
+ mutex_lock(&wl->usr_sync);
+#if defined(RSSIAVG)
+ wl_free_rssi_cache(&g_rssi_cache_ctrl);
+#endif
+#if defined(BSSCACHE)
+ wl_free_bss_cache(&g_bss_cache_ctrl);
+ wl_run_bss_cache_timer(&g_bss_cache_ctrl, 0);
+#endif
+ err = __wl_cfg80211_down(wl);
+ mutex_unlock(&wl->usr_sync);
+
+ return err;
+}
+
+static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item)
+{
+ unsigned long flags;
+ void *rptr = NULL;
+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
+
+ if (!profile)
+ return NULL;
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ switch (item) {
+ case WL_PROF_SEC:
+ rptr = &profile->sec;
+ break;
+ case WL_PROF_ACT:
+ rptr = &profile->active;
+ break;
+ case WL_PROF_BSSID:
+ rptr = profile->bssid;
+ break;
+ case WL_PROF_SSID:
+ rptr = &profile->ssid;
+ break;
+ case WL_PROF_CHAN:
+ rptr = &profile->channel;
+ break;
+ }
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+ if (!rptr)
+ AP6210_ERR("invalid item (%d)\n", item);
+ return rptr;
+}
+
+static s32
+wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data, s32 item)
+{
+ s32 err = 0;
+ struct wlc_ssid *ssid;
+ unsigned long flags;
+ struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
+
+ if (!profile)
+ return WL_INVALID;
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ switch (item) {
+ case WL_PROF_SSID:
+ ssid = (wlc_ssid_t *) data;
+ memset(profile->ssid.SSID, 0,
+ sizeof(profile->ssid.SSID));
+ memcpy(profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
+ profile->ssid.SSID_len = ssid->SSID_len;
+ break;
+ case WL_PROF_BSSID:
+ if (data)
+ memcpy(profile->bssid, data, ETHER_ADDR_LEN);
+ else
+ memset(profile->bssid, 0, ETHER_ADDR_LEN);
+ break;
+ case WL_PROF_SEC:
+ memcpy(&profile->sec, data, sizeof(profile->sec));
+ break;
+ case WL_PROF_ACT:
+ profile->active = *(bool *)data;
+ break;
+ case WL_PROF_BEACONINT:
+ profile->beacon_interval = *(u16 *)data;
+ break;
+ case WL_PROF_DTIMPERIOD:
+ profile->dtim_period = *(u8 *)data;
+ break;
+ case WL_PROF_CHAN:
+ profile->channel = *(u32*)data;
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+
+ if (err == EOPNOTSUPP)
+ AP6210_ERR("unsupported item (%d)\n", item);
+
+ return err;
+}
+
+void wl_cfg80211_dbg_level(u32 level)
+{
+ /*
+ * prohibit to change debug level
+ * by insmod parameter.
+ * eventually debug level will be configured
+ * in compile time by using CONFIG_XXX
+ */
+ /* wl_dbg_level = level; */
+}
+
+static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev)
+{
+ return wl_get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS;
+}
+
+static __used bool wl_is_ibssstarter(struct wl_priv *wl)
+{
+ return wl->ibss_starter;
+}
+
+static void wl_rst_ie(struct wl_priv *wl)
+{
+ struct wl_ie *ie = wl_to_ie(wl);
+
+ ie->offset = 0;
+}
+
+static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
+{
+ struct wl_ie *ie = wl_to_ie(wl);
+ s32 err = 0;
+
+ if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
+ AP6210_ERR("ei crosses buffer boundary\n");
+ return -ENOSPC;
+ }
+ ie->buf[ie->offset] = t;
+ ie->buf[ie->offset + 1] = l;
+ memcpy(&ie->buf[ie->offset + 2], v, l);
+ ie->offset += l + 2;
+
+ return err;
+}
+
+static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
+{
+ struct wl_ie *ie = wl_to_ie(wl);
+ s32 err = 0;
+
+ if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
+ AP6210_ERR("ei_stream crosses buffer boundary\n");
+ return -ENOSPC;
+ }
+ memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
+ ie->offset += ie_size;
+
+ return err;
+}
+
+static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
+{
+ struct wl_ie *ie = wl_to_ie(wl);
+ s32 err = 0;
+
+ if (unlikely(ie->offset > dst_size)) {
+ AP6210_ERR("dst_size is not enough\n");
+ return -ENOSPC;
+ }
+ memcpy(dst, &ie->buf[0], ie->offset);
+
+ return err;
+}
+
+static u32 wl_get_ielen(struct wl_priv *wl)
+{
+ struct wl_ie *ie = wl_to_ie(wl);
+
+ return ie->offset;
+}
+
+static void wl_link_up(struct wl_priv *wl)
+{
+ wl->link_up = true;
+}
+
+static void wl_link_down(struct wl_priv *wl)
+{
+ struct wl_connect_info *conn_info = wl_to_conn(wl);
+
+ AP6210_DEBUG("In\n");
+ wl->link_up = false;
+ conn_info->req_ie_len = 0;
+ conn_info->resp_ie_len = 0;
+}
+
+static unsigned long wl_lock_eq(struct wl_priv *wl)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&wl->eq_lock, flags);
+ return flags;
+}
+
+static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags)
+{
+ spin_unlock_irqrestore(&wl->eq_lock, flags);
+}
+
+static void wl_init_eq_lock(struct wl_priv *wl)
+{
+ spin_lock_init(&wl->eq_lock);
+}
+
+static void wl_delay(u32 ms)
+{
+ if (in_atomic() || (ms < jiffies_to_msecs(1))) {
+ mdelay(ms);
+ } else {
+ msleep(ms);
+ }
+}
+
+s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ struct ether_addr p2pif_addr;
+ struct ether_addr primary_mac;
+ if (!wl->p2p)
+ return -1;
+ if (!p2p_is_on(wl)) {
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac, p2pdev_addr, &p2pif_addr);
+ } else {
+ memcpy(p2pdev_addr->octet,
+ wl->p2p->dev_addr.octet, ETHER_ADDR_LEN);
+ }
+
+
+ return 0;
+}
+s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len)
+{
+ struct wl_priv *wl;
+
+ wl = wlcfg_drv_priv;
+
+ return wl_cfgp2p_set_p2p_noa(wl, net, buf, len);
+}
+
+s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len)
+{
+ struct wl_priv *wl;
+ wl = wlcfg_drv_priv;
+
+ return wl_cfgp2p_get_p2p_noa(wl, net, buf, len);
+}
+
+s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len)
+{
+ struct wl_priv *wl;
+ wl = wlcfg_drv_priv;
+
+ return wl_cfgp2p_set_p2p_ps(wl, net, buf, len);
+}
+
+s32 wl_cfg80211_channel_to_freq(u32 channel)
+{
+ int freq = 0;
+
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
+ freq = ieee80211_channel_to_frequency(channel);
+#else
+ {
+ u16 band = 0;
+ if (channel <= CH_MAX_2G_CHANNEL)
+ band = IEEE80211_BAND_2GHZ;
+ else
+ band = IEEE80211_BAND_5GHZ;
+ freq = ieee80211_channel_to_frequency(channel, band);
+ }
+#endif
+ return freq;
+}
+
+s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len,
+ enum wl_management_type type)
+{
+ struct wl_priv *wl;
+ struct net_device *ndev = NULL;
+ struct ether_addr primary_mac;
+ s32 ret = 0;
+ s32 bssidx = 0;
+ s32 pktflag = 0;
+ wl = wlcfg_drv_priv;
+
+ if (wl_get_drv_status(wl, AP_CREATING, net) ||
+ wl_get_drv_status(wl, AP_CREATED, net)) {
+ ndev = net;
+ bssidx = 0;
+ } else if (wl->p2p) {
+ if (net == wl->p2p_net) {
+ net = wl_to_prmry_ndev(wl);
+ }
+ if (!wl->p2p->on) {
+ get_primary_mac(wl, &primary_mac);
+ wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr,
+ &wl->p2p->int_addr);
+ /* In case of p2p_listen command, supplicant send remain_on_channel
+ * without turning on P2P
+ */
+
+ p2p_on(wl) = true;
+ ret = wl_cfgp2p_enable_discovery(wl, net, NULL, 0);
+
+ if (unlikely(ret)) {
+ goto exit;
+ }
+ }
+ if (net != wl_to_prmry_ndev(wl)) {
+ if (wl_get_mode_by_netdev(wl, net) == WL_MODE_AP) {
+ ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION);
+ }
+ } else {
+ ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+ }
+ }
+ if (ndev != NULL) {
+ switch (type) {
+ case WL_BEACON:
+ pktflag = VNDR_IE_BEACON_FLAG;
+ break;
+ case WL_PROBE_RESP:
+ pktflag = VNDR_IE_PRBRSP_FLAG;
+ break;
+ case WL_ASSOC_RESP:
+ pktflag = VNDR_IE_ASSOCRSP_FLAG;
+ break;
+ }
+ if (pktflag)
+ ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len);
+ }
+exit:
+ return ret;
+}
+
+static const struct rfkill_ops wl_rfkill_ops = {
+ .set_block = wl_rfkill_set
+};
+
+static int wl_rfkill_set(void *data, bool blocked)
+{
+ struct wl_priv *wl = (struct wl_priv *)data;
+
+ AP6210_DEBUG("Enter \n");
+ AP6210_DEBUG("RF %s\n", blocked ? "blocked" : "unblocked");
+
+ if (!wl)
+ return -EINVAL;
+
+ wl->rf_blocked = blocked;
+
+ return 0;
+}
+
+static int wl_setup_rfkill(struct wl_priv *wl, bool setup)
+{
+ s32 err = 0;
+
+ AP6210_DEBUG("Enter \n");
+ if (!wl)
+ return -EINVAL;
+ if (setup) {
+ wl->rfkill = rfkill_alloc("brcmfmac-wifi",
+ wl_cfg80211_get_parent_dev(),
+ RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl);
+
+ if (!wl->rfkill) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ err = rfkill_register(wl->rfkill);
+
+ if (err)
+ rfkill_destroy(wl->rfkill);
+ } else {
+ if (!wl->rfkill) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ rfkill_unregister(wl->rfkill);
+ rfkill_destroy(wl->rfkill);
+ }
+
+err_out:
+ return err;
+}
+
+struct device *wl_cfg80211_get_parent_dev(void)
+{
+ return cfg80211_parent_dev;
+}
+
+void wl_cfg80211_set_parent_dev(void *dev)
+{
+ cfg80211_parent_dev = dev;
+}
+
+static void wl_cfg80211_clear_parent_dev(void)
+{
+ cfg80211_parent_dev = NULL;
+}
+
+static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac)
+{
+ wldev_iovar_getbuf_bsscfg(wl_to_prmry_ndev(wl), "cur_etheraddr", NULL,
+ 0, wl->ioctl_buf, WLC_IOCTL_SMLEN, 0, &wl->ioctl_buf_sync);
+ memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN);
+}
+
+int wl_cfg80211_do_driver_init(struct net_device *net)
+{
+ struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net);
+
+ if (!wl || !wl->wdev)
+ return -EINVAL;
+
+ if (dhd_do_driver_init(wl->wdev->netdev) < 0)
+ return -1;
+
+ return 0;
+}
+
+void wl_cfg80211_enable_trace(u32 level)
+{
+ wl_dbg_level = level;
+ AP6210_DEBUG("%s: wl_dbg_level = 0x%x\n", __FUNCTION__, wl_dbg_level);
+}
+
+#if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \
+ 2, 0))
+static s32
+wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+ struct net_device *dev, u64 cookie)
+{
+ /* CFG80211 checks for tx_cancel_wait callback when ATTR_DURATION
+ * is passed with CMD_FRAME. This callback is supposed to cancel
+ * the OFFCHANNEL Wait. Since we are already taking care of that
+ * with the tx_mgmt logic, do nothing here.
+ */
+
+ return 0;
+}
+#endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL >= 3.2.0 */
+
+#ifdef WL11U
+bcm_tlv_t *
+wl_cfg80211_find_interworking_ie(u8 *parse, u32 len)
+{
+ bcm_tlv_t *ie;
+
+ while ((ie = bcm_parse_tlvs(parse, (u32)len, DOT11_MNG_INTERWORKING_ID))) {
+ return (bcm_tlv_t *)ie;
+ }
+ return NULL;
+}
+
+static s32
+wl_cfg80211_add_iw_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag,
+ uint8 ie_id, uint8 *data, uint8 data_len)
+{
+ s32 err = BCME_OK;
+ s32 buf_len;
+ s32 iecount;
+ ie_setbuf_t *ie_setbuf;
+
+ if (ie_id != DOT11_MNG_INTERWORKING_ID)
+ return BCME_UNSUPPORTED;
+
+ /* Validate the pktflag parameter */
+ if ((pktflag & ~(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG |
+ VNDR_IE_ASSOCRSP_FLAG | VNDR_IE_AUTHRSP_FLAG |
+ VNDR_IE_PRBREQ_FLAG | VNDR_IE_ASSOCREQ_FLAG|
+ VNDR_IE_CUSTOM_FLAG))) {
+ AP6210_ERR("cfg80211 Add IE: Invalid packet flag 0x%x\n", pktflag);
+ return -1;
+ }
+
+ /* use VNDR_IE_CUSTOM_FLAG flags for none vendor IE . currently fixed value */
+ pktflag = htod32(pktflag);
+
+ buf_len = sizeof(ie_setbuf_t) + data_len - 1;
+ ie_setbuf = (ie_setbuf_t *) kzalloc(buf_len, GFP_KERNEL);
+
+ if (!ie_setbuf) {
+ AP6210_ERR("Error allocating buffer for IE\n");
+ return -ENOMEM;
+ }
+
+ if (wl->iw_ie_len == data_len && !memcmp(wl->iw_ie, data, data_len)) {
+ AP6210_ERR("Previous IW IE is equals to current IE\n");
+ return err;
+ }
+
+ strncpy(ie_setbuf->cmd, "add", VNDR_IE_CMD_LEN - 1);
+ ie_setbuf->cmd[VNDR_IE_CMD_LEN - 1] = '\0';
+
+ /* Buffer contains only 1 IE */
+ iecount = htod32(1);
+ memcpy((void *)&ie_setbuf->ie_buffer.iecount, &iecount, sizeof(int));
+ memcpy((void *)&ie_setbuf->ie_buffer.ie_list[0].pktflag, &pktflag, sizeof(uint32));
+
+ /* Now, add the IE to the buffer */
+ ie_setbuf->ie_buffer.ie_list[0].ie_data.id = ie_id;
+
+ /* if already set with previous values, delete it first */
+ if (wl->iw_ie_len != 0) {
+ AP6210_DEBUG("Different IW_IE was already set. clear first\n");
+
+ ie_setbuf->ie_buffer.ie_list[0].ie_data.len = 0;
+
+ err = wldev_iovar_setbuf_bsscfg(ndev, "ie", ie_setbuf, buf_len,
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+
+ if (err != BCME_OK)
+ return err;
+ }
+
+ ie_setbuf->ie_buffer.ie_list[0].ie_data.len = data_len;
+ memcpy((uchar *)&ie_setbuf->ie_buffer.ie_list[0].ie_data.data[0], data, data_len);
+
+ err = wldev_iovar_setbuf_bsscfg(ndev, "ie", ie_setbuf, buf_len,
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+
+ if (err == BCME_OK) {
+ memcpy(wl->iw_ie, data, data_len);
+ wl->iw_ie_len = data_len;
+ wl->wl11u = TRUE;
+
+ err = wldev_iovar_setint_bsscfg(ndev, "grat_arp", 1, bssidx);
+ }
+
+ kfree(ie_setbuf);
+ return err;
+}
+#endif /* WL11U */
+
+#ifdef WL_HOST_BAND_MGMT
+s32
+wl_cfg80211_set_band(struct net_device *ndev, int band)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ int ret = 0;
+ char ioctl_buf[50];
+
+ if ((band < WLC_BAND_AUTO) || (band > WLC_BAND_2G)) {
+ AP6210_ERR("Invalid band\n");
+ return -EINVAL;
+ }
+
+ if ((ret = wldev_iovar_setbuf(ndev, "roam_band", &band,
+ sizeof(int), ioctl_buf, sizeof(ioctl_buf), NULL)) < 0) {
+ AP6210_ERR("seting roam_band failed code=%d\n", ret);
+ return ret;
+ }
+
+ AP6210_DEBUG("Setting band to %d\n", band);
+ wl->curr_band = band;
+
+ return 0;
+}
+#endif /* WL_HOST_BAND_MGMT */
+
+#if defined(DHCP_SCAN_SUPPRESS)
+static void wl_cfg80211_scan_supp_timerfunc(ulong data)
+{
+ struct wl_priv *wl = (struct wl_priv *)data;
+
+ AP6210_DEBUG("Enter \n");
+ schedule_work(&wl->wlan_work);
+}
+
+static void wl_cfg80211_work_handler(struct work_struct *work)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+
+ wl = container_of(work, struct wl_priv, wlan_work);
+
+ if (!wl) {
+ AP6210_ERR("wl_priv ptr NULL\n");
+ return;
+ }
+
+ if (wl->scan_suppressed) {
+ /* There is pending scan_suppress. Clean it */
+ AP6210_ERR("Clean up from timer after %d msec\n", WL_SCAN_SUPPRESS_TIMEOUT);
+ wl_cfg80211_scan_suppress(wl_to_prmry_ndev(wl), 0);
+ }
+}
+
+int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ int ret = 0;
+
+ if (!dev || !wl || ((suppress != 0) && (suppress != 1)))
+ return -EINVAL;
+
+ if (suppress == wl->scan_suppressed) {
+ AP6210_DEBUG("No change in scan_suppress state. Ignoring cmd..\n");
+ return 0;
+ }
+
+ if (timer_pending(&wl->scan_supp_timer))
+ del_timer_sync(&wl->scan_supp_timer);
+
+ if ((ret = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS,
+ &suppress, sizeof(int), true)) < 0) {
+ AP6210_ERR("Scan suppress setting failed ret:%d \n", ret);
+ } else {
+ AP6210_DEBUG("Scan suppress %s \n", suppress ? "Enabled" : "Disabled");
+ wl->scan_suppressed = suppress;
+ }
+
+ /* If scan_suppress is set, Start a timer to monitor it (just incase) */
+ if (wl->scan_suppressed) {
+ if (ret) {
+ AP6210_ERR("Retry scan_suppress reset at a later time \n");
+ mod_timer(&wl->scan_supp_timer,
+ jiffies + msecs_to_jiffies(WL_SCAN_SUPPRESS_RETRY));
+ } else {
+ AP6210_DEBUG("Start wlan_timer to clear of scan_suppress \n");
+ mod_timer(&wl->scan_supp_timer,
+ jiffies + msecs_to_jiffies(WL_SCAN_SUPPRESS_TIMEOUT));
+ }
+ }
+
+ return ret;
+}
+#endif /* DHCP_SCAN_SUPPRESS */
diff --git a/drivers/net/wireless/ap6210/wl_cfg80211.h b/drivers/net/wireless/ap6210/wl_cfg80211.h
new file mode 100644
index 0000000..01dd136
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_cfg80211.h
@@ -0,0 +1,791 @@
+/*
+ * Linux cfg80211 driver
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_cfg80211.h 374275 2012-12-12 11:44:18Z $
+ */
+
+#ifndef _wl_cfg80211_h_
+#define _wl_cfg80211_h_
+
+#include <linux/wireless.h>
+#include <typedefs.h>
+#include <proto/ethernet.h>
+#include <wlioctl.h>
+#include <linux/wireless.h>
+#include <net/cfg80211.h>
+#include <linux/rfkill.h>
+
+#include <wl_cfgp2p.h>
+
+struct wl_conf;
+struct wl_iface;
+struct wl_priv;
+struct wl_security;
+struct wl_ibss;
+
+
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+
+#define WL_DBG_NONE 0
+#define WL_DBG_P2P_ACTION (1 << 5)
+#define WL_DBG_TRACE (1 << 4)
+#define WL_DBG_SCAN (1 << 3)
+#define WL_DBG_DBG (1 << 2)
+#define WL_DBG_INFO (1 << 1)
+#define WL_DBG_ERR (1 << 0)
+
+/* 0 invalidates all debug messages. default is 1 */
+#define WL_DBG_LEVEL 0xFF
+
+#define WL_SCAN_RETRY_MAX 3
+#define WL_NUM_PMKIDS_MAX MAXPMKID
+#define WL_SCAN_BUF_MAX (1024 * 8)
+#define WL_TLV_INFO_MAX 1500
+#define WL_SCAN_IE_LEN_MAX 2048
+#define WL_BSS_INFO_MAX 2048
+#define WL_ASSOC_INFO_MAX 512
+#define WL_IOCTL_LEN_MAX 1024
+#define WL_EXTRA_BUF_MAX 2048
+#define WL_ISCAN_BUF_MAX 2048
+#define WL_ISCAN_TIMER_INTERVAL_MS 3000
+#define WL_SCAN_ERSULTS_LAST (WL_SCAN_RESULTS_NO_MEM+1)
+#define WL_AP_MAX 256
+#define WL_FILE_NAME_MAX 256
+#define WL_DWELL_TIME 200
+#define WL_MED_DWELL_TIME 400
+#define WL_MIN_DWELL_TIME 100
+#define WL_LONG_DWELL_TIME 1000
+#define IFACE_MAX_CNT 2
+#define WL_SCAN_CONNECT_DWELL_TIME_MS 200
+#define WL_SCAN_JOIN_PROBE_INTERVAL_MS 20
+#define WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
+#define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
+#define WL_AF_TX_MAX_RETRY 5
+
+#define WL_SCAN_TIMER_INTERVAL_MS 8000 /* Scan timeout */
+#define WL_CHANNEL_SYNC_RETRY 5
+#define WL_INVALID -1
+
+/* Bring down SCB Timeout to 20secs from 60secs default */
+#ifndef WL_SCB_TIMEOUT
+#define WL_SCB_TIMEOUT 20
+#endif
+
+/* SCAN_SUPPRESS timer values in ms */
+#define WL_SCAN_SUPPRESS_TIMEOUT 31000 /* default Framwork DHCP timeout is 30 sec */
+#define WL_SCAN_SUPPRESS_RETRY 3000
+
+/* driver status */
+enum wl_status {
+ WL_STATUS_READY = 0,
+ WL_STATUS_SCANNING,
+ WL_STATUS_SCAN_ABORTING,
+ WL_STATUS_CONNECTING,
+ WL_STATUS_CONNECTED,
+ WL_STATUS_DISCONNECTING,
+ WL_STATUS_AP_CREATING,
+ WL_STATUS_AP_CREATED,
+ /* whole sending action frame procedure:
+ * includes a) 'finding common channel' for public action request frame
+ * and b) 'sending af via 'actframe' iovar'
+ */
+ WL_STATUS_SENDING_ACT_FRM,
+ /* find a peer to go to a common channel before sending public action req frame */
+ WL_STATUS_FINDING_COMMON_CHANNEL,
+ /* waiting for next af to sync time of supplicant.
+ * it includes SENDING_ACT_FRM and WAITING_NEXT_ACT_FRM_LISTEN
+ */
+ WL_STATUS_WAITING_NEXT_ACT_FRM,
+#ifdef WL_CFG80211_SYNC_GON
+ /* go to listen state to wait for next af after SENDING_ACT_FRM */
+ WL_STATUS_WAITING_NEXT_ACT_FRM_LISTEN,
+#endif /* WL_CFG80211_SYNC_GON */
+ /* it will be set when upper layer requests listen and succeed in setting listen mode.
+ * if set, other scan request can abort current listen state
+ */
+ WL_STATUS_REMAINING_ON_CHANNEL,
+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ /* it's fake listen state to keep current scan state.
+ * it will be set when upper layer requests listen but scan is running. then just run
+ * a expire timer without actual listen state.
+ * if set, other scan request does not need to abort scan.
+ */
+ WL_STATUS_FAKE_REMAINING_ON_CHANNEL
+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+};
+
+/* wi-fi mode */
+enum wl_mode {
+ WL_MODE_BSS,
+ WL_MODE_IBSS,
+ WL_MODE_AP
+};
+
+/* driver profile list */
+enum wl_prof_list {
+ WL_PROF_MODE,
+ WL_PROF_SSID,
+ WL_PROF_SEC,
+ WL_PROF_IBSS,
+ WL_PROF_BAND,
+ WL_PROF_CHAN,
+ WL_PROF_BSSID,
+ WL_PROF_ACT,
+ WL_PROF_BEACONINT,
+ WL_PROF_DTIMPERIOD
+};
+
+/* driver iscan state */
+enum wl_iscan_state {
+ WL_ISCAN_STATE_IDLE,
+ WL_ISCAN_STATE_SCANING
+};
+
+/* donlge escan state */
+enum wl_escan_state {
+ WL_ESCAN_STATE_IDLE,
+ WL_ESCAN_STATE_SCANING
+};
+/* fw downloading status */
+enum wl_fw_status {
+ WL_FW_LOADING_DONE,
+ WL_NVRAM_LOADING_DONE
+};
+
+enum wl_management_type {
+ WL_BEACON = 0x1,
+ WL_PROBE_RESP = 0x2,
+ WL_ASSOC_RESP = 0x4
+};
+/* beacon / probe_response */
+struct beacon_proberesp {
+ __le64 timestamp;
+ __le16 beacon_int;
+ __le16 capab_info;
+ u8 variable[0];
+} __attribute__ ((packed));
+
+/* driver configuration */
+struct wl_conf {
+ u32 frag_threshold;
+ u32 rts_threshold;
+ u32 retry_short;
+ u32 retry_long;
+ s32 tx_power;
+ struct ieee80211_channel channel;
+};
+
+typedef s32(*EVENT_HANDLER) (struct wl_priv *wl,
+ struct net_device *ndev, const wl_event_msg_t *e, void *data);
+
+/* bss inform structure for cfg80211 interface */
+struct wl_cfg80211_bss_info {
+ u16 band;
+ u16 channel;
+ s16 rssi;
+ u16 frame_len;
+ u8 frame_buf[1];
+};
+
+/* basic structure of scan request */
+struct wl_scan_req {
+ struct wlc_ssid ssid;
+};
+
+/* basic structure of information element */
+struct wl_ie {
+ u16 offset;
+ u8 buf[WL_TLV_INFO_MAX];
+};
+
+/* event queue for cfg80211 main event */
+struct wl_event_q {
+ struct list_head eq_list;
+ u32 etype;
+ wl_event_msg_t emsg;
+ s8 edata[1];
+};
+
+/* security information with currently associated ap */
+struct wl_security {
+ u32 wpa_versions;
+ u32 auth_type;
+ u32 cipher_pairwise;
+ u32 cipher_group;
+ u32 wpa_auth;
+ u32 auth_assoc_res_status;
+};
+
+/* ibss information for currently joined ibss network */
+struct wl_ibss {
+ u8 beacon_interval; /* in millisecond */
+ u8 atim; /* in millisecond */
+ s8 join_only;
+ u8 band;
+ u8 channel;
+};
+
+/* wl driver profile */
+struct wl_profile {
+ u32 mode;
+ s32 band;
+ u32 channel;
+ struct wlc_ssid ssid;
+ struct wl_security sec;
+ struct wl_ibss ibss;
+ u8 bssid[ETHER_ADDR_LEN];
+ u16 beacon_interval;
+ u8 dtim_period;
+ bool active;
+};
+
+struct net_info {
+ struct net_device *ndev;
+ struct wireless_dev *wdev;
+ struct wl_profile profile;
+ s32 mode;
+ s32 roam_off;
+ unsigned long sme_state;
+ bool pm_restore;
+ bool pm_block;
+ s32 pm;
+ struct list_head list; /* list of all net_info structure */
+};
+typedef s32(*ISCAN_HANDLER) (struct wl_priv *wl);
+
+/* iscan controller */
+struct wl_iscan_ctrl {
+ struct net_device *dev;
+ struct timer_list timer;
+ u32 timer_ms;
+ u32 timer_on;
+ s32 state;
+ struct task_struct *tsk;
+ struct semaphore sync;
+ ISCAN_HANDLER iscan_handler[WL_SCAN_ERSULTS_LAST];
+ void *data;
+ s8 ioctl_buf[WLC_IOCTL_SMLEN];
+ s8 scan_buf[WL_ISCAN_BUF_MAX];
+};
+
+/* association inform */
+#define MAX_REQ_LINE 1024
+struct wl_connect_info {
+ u8 req_ie[MAX_REQ_LINE];
+ s32 req_ie_len;
+ u8 resp_ie[MAX_REQ_LINE];
+ s32 resp_ie_len;
+};
+
+/* firmware /nvram downloading controller */
+struct wl_fw_ctrl {
+ const struct firmware *fw_entry;
+ unsigned long status;
+ u32 ptr;
+ s8 fw_name[WL_FILE_NAME_MAX];
+ s8 nvram_name[WL_FILE_NAME_MAX];
+};
+
+/* assoc ie length */
+struct wl_assoc_ielen {
+ u32 req_len;
+ u32 resp_len;
+};
+
+/* wpa2 pmk list */
+struct wl_pmk_list {
+ pmkid_list_t pmkids;
+ pmkid_t foo[MAXPMKID - 1];
+};
+
+
+#define ESCAN_BUF_SIZE (64 * 1024)
+
+struct escan_info {
+ u32 escan_state;
+#if defined(STATIC_WL_PRIV_STRUCT)
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+#error STATIC_WL_PRIV_STRUCT should be used with CONFIG_DHD_USE_STATIC_BUF
+#endif
+ u8 *escan_buf;
+#else
+ u8 escan_buf[ESCAN_BUF_SIZE];
+#endif /* STATIC_WL_PRIV_STRUCT */
+ struct wiphy *wiphy;
+ struct net_device *ndev;
+};
+
+struct ap_info {
+/* Structure to hold WPS, WPA IEs for a AP */
+ u8 probe_res_ie[VNDR_IES_MAX_BUF_LEN];
+ u8 beacon_ie[VNDR_IES_MAX_BUF_LEN];
+ u32 probe_res_ie_len;
+ u32 beacon_ie_len;
+ u8 *wpa_ie;
+ u8 *rsn_ie;
+ u8 *wps_ie;
+ bool security_mode;
+};
+struct btcoex_info {
+ struct timer_list timer;
+ u32 timer_ms;
+ u32 timer_on;
+ u32 ts_dhcp_start; /* ms ts ecord time stats */
+ u32 ts_dhcp_ok; /* ms ts ecord time stats */
+ bool dhcp_done; /* flag, indicates that host done with
+ * dhcp before t1/t2 expiration
+ */
+ s32 bt_state;
+ struct work_struct work;
+ struct net_device *dev;
+};
+
+struct sta_info {
+ /* Structure to hold WPS IE for a STA */
+ u8 probe_req_ie[VNDR_IES_BUF_LEN];
+ u8 assoc_req_ie[VNDR_IES_BUF_LEN];
+ u32 probe_req_ie_len;
+ u32 assoc_req_ie_len;
+};
+
+struct afx_hdl {
+ wl_af_params_t *pending_tx_act_frm;
+ struct ether_addr tx_dst_addr;
+ struct net_device *dev;
+ struct work_struct work;
+ u32 bssidx;
+ u32 retry;
+ s32 peer_chan;
+ s32 peer_listen_chan; /* search channel: configured by upper layer */
+ s32 my_listen_chan; /* listen chanel: extract it from prb req or gon req */
+ bool is_listen;
+ bool ack_recv;
+ bool is_active;
+};
+
+struct parsed_ies {
+ wpa_ie_fixed_t *wps_ie;
+ u32 wps_ie_len;
+ wpa_ie_fixed_t *wpa_ie;
+ u32 wpa_ie_len;
+ bcm_tlv_t *wpa2_ie;
+ u32 wpa2_ie_len;
+};
+
+
+#ifdef WL11U
+/* Max length of Interworking element */
+#define IW_IES_MAX_BUF_LEN 9
+#endif
+
+#define MAX_EVENT_BUF_NUM 16
+typedef struct wl_eventmsg_buf {
+ u16 num;
+ struct {
+ u16 type;
+ bool set;
+ } event [MAX_EVENT_BUF_NUM];
+} wl_eventmsg_buf_t;
+
+/* private data of cfg80211 interface */
+struct wl_priv {
+ struct wireless_dev *wdev; /* representing wl cfg80211 device */
+
+ struct wireless_dev *p2p_wdev; /* representing wl cfg80211 device for P2P */
+ struct net_device *p2p_net; /* reference to p2p0 interface */
+
+ struct wl_conf *conf;
+ struct cfg80211_scan_request *scan_request; /* scan request object */
+ EVENT_HANDLER evt_handler[WLC_E_LAST];
+ struct list_head eq_list; /* used for event queue */
+ struct list_head net_list; /* used for struct net_info */
+ spinlock_t eq_lock; /* for event queue synchronization */
+ spinlock_t cfgdrv_lock; /* to protect scan status (and others if needed) */
+ struct completion act_frm_scan;
+ struct completion iface_disable;
+ struct completion wait_next_af;
+ struct mutex usr_sync; /* maily for up/down synchronization */
+ struct wl_scan_results *bss_list;
+ struct wl_scan_results *scan_results;
+
+ /* scan request object for internal purpose */
+ struct wl_scan_req *scan_req_int;
+ /* information element object for internal purpose */
+#if defined(STATIC_WL_PRIV_STRUCT)
+ struct wl_ie *ie;
+#else
+ struct wl_ie ie;
+#endif
+ struct wl_iscan_ctrl *iscan; /* iscan controller */
+
+ /* association information container */
+#if defined(STATIC_WL_PRIV_STRUCT)
+ struct wl_connect_info *conn_info;
+#else
+ struct wl_connect_info conn_info;
+#endif
+
+ struct wl_pmk_list *pmk_list; /* wpa2 pmk list */
+ tsk_ctl_t event_tsk; /* task of main event handler thread */
+ void *pub;
+ u32 iface_cnt;
+ u32 channel; /* current channel */
+ u32 af_sent_channel; /* channel action frame is sent */
+ /* next af subtype to cancel the remained dwell time in rx process */
+ u8 next_af_subtype;
+#ifdef WL_CFG80211_SYNC_GON
+ ulong af_tx_sent_jiffies;
+#endif /* WL_CFG80211_SYNC_GON */
+ bool iscan_on; /* iscan on/off switch */
+ bool iscan_kickstart; /* indicate iscan already started */
+ bool escan_on; /* escan on/off switch */
+ struct escan_info escan_info; /* escan information */
+ bool active_scan; /* current scan mode */
+ bool ibss_starter; /* indicates this sta is ibss starter */
+ bool link_up; /* link/connection up flag */
+
+ /* indicate whether chip to support power save mode */
+ bool pwr_save;
+ bool roam_on; /* on/off switch for self-roaming */
+ bool scan_tried; /* indicates if first scan attempted */
+ bool wlfc_on;
+ bool vsdb_mode;
+ bool roamoff_on_concurrent;
+ u8 *ioctl_buf; /* ioctl buffer */
+ struct mutex ioctl_buf_sync;
+ u8 *escan_ioctl_buf;
+ u8 *extra_buf; /* maily to grab assoc information */
+ struct dentry *debugfsdir;
+ struct rfkill *rfkill;
+ bool rf_blocked;
+ struct ieee80211_channel remain_on_chan;
+ enum nl80211_channel_type remain_on_chan_type;
+ u64 send_action_id;
+ u64 last_roc_id;
+ wait_queue_head_t netif_change_event;
+ struct completion send_af_done;
+ struct afx_hdl *afx_hdl;
+ struct ap_info *ap_info;
+ struct sta_info *sta_info;
+ struct p2p_info *p2p;
+ bool p2p_supported;
+ struct btcoex_info *btcoex_info;
+ struct timer_list scan_timeout; /* Timer for catch scan event timeout */
+ s32(*state_notifier) (struct wl_priv *wl,
+ struct net_info *_net_info, enum wl_status state, bool set);
+ unsigned long interrested_state;
+ wlc_ssid_t hostapd_ssid;
+#ifdef WL11U
+ bool wl11u;
+ u8 iw_ie[IW_IES_MAX_BUF_LEN];
+ u32 iw_ie_len;
+#endif /* WL11U */
+ bool sched_scan_running; /* scheduled scan req status */
+#ifdef WL_SCHED_SCAN
+ struct cfg80211_sched_scan_request *sched_scan_req; /* scheduled scan req */
+#endif /* WL_SCHED_SCAN */
+#ifdef WL_HOST_BAND_MGMT
+ u8 curr_band;
+#endif /* WL_HOST_BAND_MGMT */
+ bool scan_suppressed;
+ struct timer_list scan_supp_timer;
+ struct work_struct wlan_work;
+ struct mutex event_sync; /* maily for up/down synchronization */
+};
+
+
+static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
+{
+ return bss = bss ?
+ (struct wl_bss_info *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info;
+}
+static inline s32
+wl_alloc_netinfo(struct wl_priv *wl, struct net_device *ndev,
+ struct wireless_dev * wdev, s32 mode, bool pm_block)
+{
+ struct net_info *_net_info;
+ s32 err = 0;
+ if (wl->iface_cnt == IFACE_MAX_CNT)
+ return -ENOMEM;
+ _net_info = kzalloc(sizeof(struct net_info), GFP_KERNEL);
+ if (!_net_info)
+ err = -ENOMEM;
+ else {
+ _net_info->mode = mode;
+ _net_info->ndev = ndev;
+ _net_info->wdev = wdev;
+ _net_info->pm_restore = 0;
+ _net_info->pm = 0;
+ _net_info->pm_block = pm_block;
+ _net_info->roam_off = WL_INVALID;
+ wl->iface_cnt++;
+ list_add(&_net_info->list, &wl->net_list);
+ }
+ return err;
+}
+static inline void
+wl_dealloc_netinfo(struct wl_priv *wl, struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev)) {
+ list_del(&_net_info->list);
+ wl->iface_cnt--;
+ if (_net_info->wdev) {
+ kfree(_net_info->wdev);
+ ndev->ieee80211_ptr = NULL;
+ }
+ kfree(_net_info);
+ }
+ }
+
+}
+static inline void
+wl_delete_all_netinfo(struct wl_priv *wl)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ list_del(&_net_info->list);
+ if (_net_info->wdev)
+ kfree(_net_info->wdev);
+ kfree(_net_info);
+ }
+ wl->iface_cnt = 0;
+}
+static inline u32
+wl_get_status_all(struct wl_priv *wl, s32 status)
+
+{
+ struct net_info *_net_info, *next;
+ u32 cnt = 0;
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (_net_info->ndev &&
+ test_bit(status, &_net_info->sme_state))
+ cnt++;
+ }
+ return cnt;
+}
+static inline void
+wl_set_status_all(struct wl_priv *wl, s32 status, u32 op)
+{
+ struct net_info *_net_info, *next;
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ switch (op) {
+ case 1:
+ return; /* set all status is not allowed */
+ case 2:
+ clear_bit(status, &_net_info->sme_state);
+ if (wl->state_notifier &&
+ test_bit(status, &(wl->interrested_state)))
+ wl->state_notifier(wl, _net_info, status, false);
+ break;
+ case 4:
+ return; /* change all status is not allowed */
+ default:
+ return; /* unknown operation */
+ }
+ }
+}
+static inline void
+wl_set_status_by_netdev(struct wl_priv *wl, s32 status,
+ struct net_device *ndev, u32 op)
+{
+
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev)) {
+ switch (op) {
+ case 1:
+ set_bit(status, &_net_info->sme_state);
+ if (wl->state_notifier &&
+ test_bit(status, &(wl->interrested_state)))
+ wl->state_notifier(wl, _net_info, status, true);
+ break;
+ case 2:
+ clear_bit(status, &_net_info->sme_state);
+ if (wl->state_notifier &&
+ test_bit(status, &(wl->interrested_state)))
+ wl->state_notifier(wl, _net_info, status, false);
+ break;
+ case 4:
+ change_bit(status, &_net_info->sme_state);
+ break;
+ }
+ }
+
+ }
+
+}
+
+static inline u32
+wl_get_status_by_netdev(struct wl_priv *wl, s32 status,
+ struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ return test_bit(status, &_net_info->sme_state);
+ }
+ return 0;
+}
+
+static inline s32
+wl_get_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ return _net_info->mode;
+ }
+ return -1;
+}
+
+
+static inline void
+wl_set_mode_by_netdev(struct wl_priv *wl, struct net_device *ndev,
+ s32 mode)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ _net_info->mode = mode;
+ }
+}
+static inline struct wl_profile *
+wl_get_profile_by_netdev(struct wl_priv *wl, struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ return &_net_info->profile;
+ }
+ return NULL;
+}
+static inline struct net_info *
+wl_get_netinfo_by_netdev(struct wl_priv *wl, struct net_device *ndev)
+{
+ struct net_info *_net_info, *next;
+
+ list_for_each_entry_safe(_net_info, next, &wl->net_list, list) {
+ if (ndev && (_net_info->ndev == ndev))
+ return _net_info;
+ }
+ return NULL;
+}
+#define wl_to_wiphy(w) (w->wdev->wiphy)
+#define wl_to_prmry_ndev(w) (w->wdev->netdev)
+#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
+#define wl_to_sr(w) (w->scan_req_int)
+#if defined(STATIC_WL_PRIV_STRUCT)
+#define wl_to_ie(w) (w->ie)
+#define wl_to_conn(w) (w->conn_info)
+#else
+#define wl_to_ie(w) (&w->ie)
+#define wl_to_conn(w) (&w->conn_info)
+#endif
+#define iscan_to_wl(i) ((struct wl_priv *)(i->data))
+#define wl_to_iscan(w) (w->iscan)
+#define wiphy_from_scan(w) (w->escan_info.wiphy)
+#define wl_get_drv_status_all(wl, stat) \
+ (wl_get_status_all(wl, WL_STATUS_ ## stat))
+#define wl_get_drv_status(wl, stat, ndev) \
+ (wl_get_status_by_netdev(wl, WL_STATUS_ ## stat, ndev))
+#define wl_set_drv_status(wl, stat, ndev) \
+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 1))
+#define wl_clr_drv_status(wl, stat, ndev) \
+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 2))
+#define wl_clr_drv_status_all(wl, stat) \
+ (wl_set_status_all(wl, WL_STATUS_ ## stat, 2))
+#define wl_chg_drv_status(wl, stat, ndev) \
+ (wl_set_status_by_netdev(wl, WL_STATUS_ ## stat, ndev, 4))
+
+#define for_each_bss(list, bss, __i) \
+ for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
+
+#define for_each_ndev(wl, iter, next) \
+ list_for_each_entry_safe(iter, next, &wl->net_list, list)
+
+
+/* In case of WPS from wpa_supplicant, pairwise siute and group suite is 0.
+ * In addtion to that, wpa_version is WPA_VERSION_1
+ */
+#define is_wps_conn(_sme) \
+ ((wl_cfgp2p_find_wpsie((u8 *)_sme->ie, _sme->ie_len) != NULL) && \
+ (!_sme->crypto.n_ciphers_pairwise) && \
+ (!_sme->crypto.cipher_group))
+extern s32 wl_cfg80211_attach(struct net_device *ndev, void *data);
+extern s32 wl_cfg80211_attach_post(struct net_device *ndev);
+extern void wl_cfg80211_detach(void *para);
+
+extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e,
+ void *data);
+void wl_cfg80211_set_parent_dev(void *dev);
+struct device *wl_cfg80211_get_parent_dev(void);
+
+extern s32 wl_cfg80211_up(void *para);
+extern s32 wl_cfg80211_down(void *para);
+extern s32 wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
+ void* _net_attach);
+extern s32 wl_cfg80211_ifdel_ops(struct net_device *net);
+extern s32 wl_cfg80211_notify_ifdel(void);
+extern s32 wl_cfg80211_is_progress_ifadd(void);
+extern s32 wl_cfg80211_is_progress_ifchange(void);
+extern s32 wl_cfg80211_is_progress_ifadd(void);
+extern s32 wl_cfg80211_notify_ifchange(void);
+extern void wl_cfg80211_dbg_level(u32 level);
+extern s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr);
+extern s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len);
+extern s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len);
+extern s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len,
+ enum wl_management_type type);
+extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len);
+extern int wl_cfg80211_hang(struct net_device *dev, u16 reason);
+extern s32 wl_mode_to_nl80211_iftype(s32 mode);
+int wl_cfg80211_do_driver_init(struct net_device *net);
+void wl_cfg80211_enable_trace(u32 level);
+extern s32 wl_update_wiphybands(struct wl_priv *wl, bool notify);
+extern s32 wl_cfg80211_if_is_group_owner(void);
+extern chanspec_t wl_ch_host_to_driver(u16 channel);
+extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
+extern void wl_stop_wait_next_action_frame(struct wl_priv *wl, struct net_device *ndev);
+extern s32 wl_cfg80211_set_band(struct net_device *ndev, int band);
+extern int wl_cfg80211_update_power_mode(struct net_device *dev);
+#if defined(DHCP_SCAN_SUPPRESS)
+extern int wl_cfg80211_scan_suppress(struct net_device *dev, int suppress);
+#endif /* OEM_ANDROID */
+extern void wl_cfg80211_add_to_eventbuffer(wl_eventmsg_buf_t *ev, u16 event, bool set);
+extern s32 wl_cfg80211_apply_eventbuffer(struct net_device *ndev,
+ struct wl_priv *wl, wl_eventmsg_buf_t *ev);
+#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/ap6210/wl_cfgp2p.c b/drivers/net/wireless/ap6210/wl_cfgp2p.c
new file mode 100644
index 0000000..eb7df08
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_cfgp2p.c
@@ -0,0 +1,2393 @@
+/*
+ * Linux cfgp2p driver
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_cfgp2p.c 372668 2012-12-04 14:07:12Z $
+ *
+ */
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <proto/ethernet.h>
+#include <proto/802.11.h>
+
+#include <wl_cfg80211.h>
+#include <wl_cfgp2p.h>
+#include <wldev_common.h>
+#include <wl_android.h>
+
+#include <ap6210.h>
+
+static s8 scanparambuf[WLC_IOCTL_SMLEN];
+static s8 g_mgmt_ie_buf[2048];
+static bool
+wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type);
+
+static u32
+wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag,
+ s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd);
+
+static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev);
+static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd);
+static int wl_cfgp2p_if_open(struct net_device *net);
+static int wl_cfgp2p_if_stop(struct net_device *net);
+static s32 wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev,
+ bool notify);
+
+static const struct net_device_ops wl_cfgp2p_if_ops = {
+ .ndo_open = wl_cfgp2p_if_open,
+ .ndo_stop = wl_cfgp2p_if_stop,
+ .ndo_do_ioctl = wl_cfgp2p_do_ioctl,
+ .ndo_start_xmit = wl_cfgp2p_start_xmit,
+};
+
+bool wl_cfgp2p_is_pub_action(void *frame, u32 frame_len)
+{
+ wifi_p2p_pub_act_frame_t *pact_frm;
+
+ if (frame == NULL)
+ return false;
+ pact_frm = (wifi_p2p_pub_act_frame_t *)frame;
+ if (frame_len < sizeof(wifi_p2p_pub_act_frame_t) -1)
+ return false;
+
+ if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
+ pact_frm->action == P2P_PUB_AF_ACTION &&
+ pact_frm->oui_type == P2P_VER &&
+ memcmp(pact_frm->oui, P2P_OUI, sizeof(pact_frm->oui)) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+bool wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len)
+{
+ wifi_p2p_action_frame_t *act_frm;
+
+ if (frame == NULL)
+ return false;
+ act_frm = (wifi_p2p_action_frame_t *)frame;
+ if (frame_len < sizeof(wifi_p2p_action_frame_t) -1)
+ return false;
+
+ if (act_frm->category == P2P_AF_CATEGORY &&
+ act_frm->type == P2P_VER &&
+ memcmp(act_frm->OUI, P2P_OUI, DOT11_OUI_LEN) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+/*
+* Currently Action frame just pass to P2P interface regardless real dst.
+* but GAS Action can be used for Hotspot2.0 as well
+* Need to distingush that it's for P2P or HS20
+*/
+#ifdef WL11U
+#define GAS_RESP_LEN 2
+#define DOUBLE_TLV_BODY_OFF 4
+#define GAS_RESP_OFFSET 4
+#define GAS_CRESP_OFFSET 5
+
+bool wl_cfgp2p_find_gas_subtype(u8 subtype, u8* data, u32 len)
+{
+ bcm_tlv_t *ie = (bcm_tlv_t *)data;
+ u8 *frame = NULL;
+ u16 id, flen;
+
+ /* Skipped first ANQP Element, if frame has anqp elemnt */
+ ie = bcm_parse_tlvs(ie, (int)len, DOT11_MNG_ADVERTISEMENT_ID);
+
+ if (ie == NULL)
+ return false;
+
+ frame = (uint8 *)ie + ie->len + TLV_HDR_LEN + GAS_RESP_LEN;
+ id = ((u16) (((frame)[1] << 8) | (frame)[0]));
+ flen = ((u16) (((frame)[3] << 8) | (frame)[2]));
+
+ /* If the contents match the OUI and the type */
+ if (flen >= WFA_OUI_LEN + 1 &&
+ id == P2PSD_GAS_NQP_INFOID &&
+ !bcmp(&frame[DOUBLE_TLV_BODY_OFF], (const uint8*)WFA_OUI, WFA_OUI_LEN) &&
+ subtype == frame[DOUBLE_TLV_BODY_OFF+WFA_OUI_LEN]) {
+ return true;
+ }
+
+ return false;
+}
+#endif /* WL11U */
+
+bool wl_cfgp2p_is_gas_action(void *frame, u32 frame_len)
+{
+
+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm;
+
+ if (frame == NULL)
+ return false;
+
+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
+ if (frame_len < sizeof(wifi_p2psd_gas_pub_act_frame_t) - 1)
+ return false;
+ if (sd_act_frm->category != P2PSD_ACTION_CATEGORY)
+ return false;
+
+#ifdef WL11U
+ if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP)
+ return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE,
+ (u8 *)sd_act_frm->query_data + GAS_RESP_OFFSET,
+ frame_len);
+
+ else if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP)
+ return wl_cfgp2p_find_gas_subtype(P2PSD_GAS_OUI_SUBTYPE,
+ (u8 *)sd_act_frm->query_data + GAS_CRESP_OFFSET,
+ frame_len);
+ else if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ ||
+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ)
+ return true;
+ else
+ return false;
+#else
+ if (sd_act_frm->action == P2PSD_ACTION_ID_GAS_IREQ ||
+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_IRESP ||
+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_CREQ ||
+ sd_act_frm->action == P2PSD_ACTION_ID_GAS_CRESP)
+ return true;
+ else
+ return false;
+#endif /* WLC11U */
+}
+void wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len)
+{
+ wifi_p2p_pub_act_frame_t *pact_frm;
+ wifi_p2p_action_frame_t *act_frm;
+ wifi_p2psd_gas_pub_act_frame_t *sd_act_frm;
+ if (!frame || frame_len <= 2)
+ return;
+
+ if (wl_cfgp2p_is_pub_action(frame, frame_len)) {
+ pact_frm = (wifi_p2p_pub_act_frame_t *)frame;
+ switch (pact_frm->subtype) {
+ case P2P_PAF_GON_REQ:
+ AP6210_DEBUG("%s P2P Group Owner Negotiation Req Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_PAF_GON_RSP:
+ AP6210_DEBUG("%s P2P Group Owner Negotiation Rsp Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_PAF_GON_CONF:
+ AP6210_DEBUG("%s P2P Group Owner Negotiation Confirm Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_PAF_INVITE_REQ:
+ AP6210_DEBUG("%s P2P Invitation Request Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_PAF_INVITE_RSP:
+ AP6210_DEBUG("%s P2P Invitation Response Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_PAF_DEVDIS_REQ:
+ AP6210_DEBUG("%s P2P Device Discoverability Request Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_PAF_DEVDIS_RSP:
+ AP6210_DEBUG("%s P2P Device Discoverability Response Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_PAF_PROVDIS_REQ:
+ AP6210_DEBUG("%s P2P Provision Discovery Request Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_PAF_PROVDIS_RSP:
+ AP6210_DEBUG("%s P2P Provision Discovery Response Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ default:
+ AP6210_DEBUG("%s Unknown P2P Public Action Frame\n",
+ (tx)? "TX": "RX");
+
+ }
+
+ } else if (wl_cfgp2p_is_p2p_action(frame, frame_len)) {
+ act_frm = (wifi_p2p_action_frame_t *)frame;
+ switch (act_frm->subtype) {
+ case P2P_AF_NOTICE_OF_ABSENCE:
+ AP6210_DEBUG("%s P2P Notice of Absence Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_AF_PRESENCE_REQ:
+ AP6210_DEBUG("%s P2P Presence Request Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_AF_PRESENCE_RSP:
+ AP6210_DEBUG("%s P2P Presence Response Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ case P2P_AF_GO_DISC_REQ:
+ AP6210_DEBUG("%s P2P Discoverability Request Frame\n",
+ (tx)? "TX": "RX");
+ break;
+ default:
+ AP6210_DEBUG("%s Unknown P2P Action Frame\n",
+ (tx)? "TX": "RX");
+ }
+
+ } else if (wl_cfgp2p_is_gas_action(frame, frame_len)) {
+ sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)frame;
+ switch (sd_act_frm->action) {
+ case P2PSD_ACTION_ID_GAS_IREQ:
+ AP6210_DEBUG("%s P2P GAS Initial Request\n",
+ (tx)? "TX" : "RX");
+ break;
+ case P2PSD_ACTION_ID_GAS_IRESP:
+ AP6210_DEBUG("%s P2P GAS Initial Response\n",
+ (tx)? "TX" : "RX");
+ break;
+ case P2PSD_ACTION_ID_GAS_CREQ:
+ AP6210_DEBUG("%s P2P GAS Comback Request\n",
+ (tx)? "TX" : "RX");
+ break;
+ case P2PSD_ACTION_ID_GAS_CRESP:
+ AP6210_DEBUG("%s P2P GAS Comback Response\n",
+ (tx)? "TX" : "RX");
+ break;
+ default:
+ AP6210_DEBUG("%s Unknown P2P GAS Frame\n",
+ (tx)? "TX" : "RX");
+ }
+
+
+ }
+}
+
+/*
+ * Initialize variables related to P2P
+ *
+ */
+s32
+wl_cfgp2p_init_priv(struct wl_priv *wl)
+{
+ if (!(wl->p2p = kzalloc(sizeof(struct p2p_info), GFP_KERNEL))) {
+ AP6210_ERR("struct p2p_info allocation failed\n");
+ return -ENOMEM;
+ }
+#define INIT_IE(IE_TYPE, BSS_TYPE) \
+ do { \
+ memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \
+ sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \
+ wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \
+ } while (0);
+
+ INIT_IE(probe_req, P2PAPI_BSSCFG_PRIMARY);
+ INIT_IE(probe_res, P2PAPI_BSSCFG_PRIMARY);
+ INIT_IE(assoc_req, P2PAPI_BSSCFG_PRIMARY);
+ INIT_IE(assoc_res, P2PAPI_BSSCFG_PRIMARY);
+ INIT_IE(beacon, P2PAPI_BSSCFG_PRIMARY);
+ INIT_IE(probe_req, P2PAPI_BSSCFG_DEVICE);
+ INIT_IE(probe_res, P2PAPI_BSSCFG_DEVICE);
+ INIT_IE(assoc_req, P2PAPI_BSSCFG_DEVICE);
+ INIT_IE(assoc_res, P2PAPI_BSSCFG_DEVICE);
+ INIT_IE(beacon, P2PAPI_BSSCFG_DEVICE);
+ INIT_IE(probe_req, P2PAPI_BSSCFG_CONNECTION);
+ INIT_IE(probe_res, P2PAPI_BSSCFG_CONNECTION);
+ INIT_IE(assoc_req, P2PAPI_BSSCFG_CONNECTION);
+ INIT_IE(assoc_res, P2PAPI_BSSCFG_CONNECTION);
+ INIT_IE(beacon, P2PAPI_BSSCFG_CONNECTION);
+#undef INIT_IE
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY) = wl_to_prmry_ndev(wl);
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY) = 0;
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL;
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0;
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = NULL;
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = 0;
+ return BCME_OK;
+
+}
+/*
+ * Deinitialize variables related to P2P
+ *
+ */
+void
+wl_cfgp2p_deinit_priv(struct wl_priv *wl)
+{
+ AP6210_DEBUG("In\n");
+ if (wl->p2p) {
+ kfree(wl->p2p);
+ wl->p2p = NULL;
+ }
+ wl->p2p_supported = 0;
+}
+/*
+ * Set P2P functions into firmware
+ */
+s32
+wl_cfgp2p_set_firm_p2p(struct wl_priv *wl)
+{
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ struct ether_addr null_eth_addr = { { 0, 0, 0, 0, 0, 0 } };
+ s32 ret = BCME_OK;
+ s32 val = 0;
+ /* Do we have to check whether APSTA is enabled or not ? */
+ wldev_iovar_getint(ndev, "apsta", &val);
+ if (val == 0) {
+ val = 1;
+ ret = wldev_ioctl(ndev, WLC_DOWN, &val, sizeof(s32), true);
+ if (ret < 0) {
+ AP6210_ERR("WLC_DOWN error %d\n", ret);
+ return ret;
+ }
+ wldev_iovar_setint(ndev, "apsta", val);
+ ret = wldev_ioctl(ndev, WLC_UP, &val, sizeof(s32), true);
+ if (ret < 0) {
+ AP6210_ERR("WLC_UP error %d\n", ret);
+ return ret;
+ }
+ }
+
+ /* In case of COB type, firmware has default mac address
+ * After Initializing firmware, we have to set current mac address to
+ * firmware for P2P device address
+ */
+ ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
+ sizeof(null_eth_addr), wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
+ if (ret && ret != BCME_UNSUPPORTED) {
+ AP6210_ERR("failed to update device address ret %d\n", ret);
+ }
+ return ret;
+}
+
+/* Create a new P2P BSS.
+ * Parameters:
+ * @mac : MAC address of the BSS to create
+ * @if_type : interface type: WL_P2P_IF_GO or WL_P2P_IF_CLIENT
+ * @chspec : chspec to use if creating a GO BSS.
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
+ chanspec_t chspec)
+{
+ wl_p2p_if_t ifreq;
+ s32 err;
+ u32 scb_timeout = WL_SCB_TIMEOUT;
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+
+ ifreq.type = if_type;
+ ifreq.chspec = chspec;
+ memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet));
+
+ AP6210_DEBUG("---wl p2p_ifadd "MACDBG" %s %u\n",
+ MAC2STRDBG(ifreq.addr.octet),
+ (if_type == WL_P2P_IF_GO) ? "go" : "client",
+ (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT);
+
+ err = wldev_iovar_setbuf(ndev, "p2p_ifadd", &ifreq, sizeof(ifreq),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+
+ if (unlikely(err < 0))
+ AP6210_DEBUG("'wl p2p_ifadd' error %d\n", err);
+ else if (if_type == WL_P2P_IF_GO) {
+ err = wldev_ioctl(ndev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true);
+ if (unlikely(err < 0))
+ AP6210_DEBUG("'wl scb_timeout' error %d\n", err);
+ }
+ return err;
+}
+
+/* Disable a P2P BSS.
+ * Parameters:
+ * @mac : MAC address of the BSS to create
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_ifdisable(struct wl_priv *wl, struct ether_addr *mac)
+{
+ s32 ret;
+ struct net_device *netdev = wl_to_prmry_ndev(wl);
+
+ AP6210_DEBUG("------primary idx %d : wl p2p_ifdis "MACDBG"\n",
+ netdev->ifindex, MAC2STRDBG(mac->octet));
+ ret = wldev_iovar_setbuf(netdev, "p2p_ifdis", mac, sizeof(*mac),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ if (unlikely(ret < 0)) {
+ AP6210_DEBUG("'wl p2p_ifdis' error %d\n", ret);
+ }
+ return ret;
+}
+
+/* Delete a P2P BSS.
+ * Parameters:
+ * @mac : MAC address of the BSS to create
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac)
+{
+ s32 ret;
+ struct net_device *netdev = wl_to_prmry_ndev(wl);
+
+ AP6210_DEBUG("------primary idx %d : wl p2p_ifdel "MACDBG"\n",
+ netdev->ifindex, MAC2STRDBG(mac->octet));
+ ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ if (unlikely(ret < 0)) {
+ AP6210_DEBUG("'wl p2p_ifdel' error %d\n", ret);
+ }
+ return ret;
+}
+
+/* Change a P2P Role.
+ * Parameters:
+ * @mac : MAC address of the BSS to change a role
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
+ chanspec_t chspec)
+{
+ wl_p2p_if_t ifreq;
+ s32 err;
+ u32 scb_timeout = WL_SCB_TIMEOUT;
+
+ struct net_device *netdev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
+
+ ifreq.type = if_type;
+ ifreq.chspec = chspec;
+ memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet));
+
+ AP6210_DEBUG("---wl p2p_ifchange "MACDBG" %s %u"
+ " chanspec 0x%04x\n", MAC2STRDBG(ifreq.addr.octet),
+ (if_type == WL_P2P_IF_GO) ? "go" : "client",
+ (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT,
+ ifreq.chspec);
+
+ err = wldev_iovar_setbuf(netdev, "p2p_ifupd", &ifreq, sizeof(ifreq),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+
+ if (unlikely(err < 0)) {
+ AP6210_DEBUG("'wl p2p_ifupd' error %d\n", err);
+ } else if (if_type == WL_P2P_IF_GO) {
+ err = wldev_ioctl(netdev, WLC_SET_SCB_TIMEOUT, &scb_timeout, sizeof(u32), true);
+ if (unlikely(err < 0))
+ AP6210_DEBUG("'wl scb_timeout' error %d\n", err);
+ }
+ return err;
+}
+
+
+/* Get the index of a created P2P BSS.
+ * Parameters:
+ * @mac : MAC address of the created BSS
+ * @index : output: index of created BSS
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_ifidx(struct wl_priv *wl, struct ether_addr *mac, s32 *index)
+{
+ s32 ret;
+ u8 getbuf[64];
+ struct net_device *dev = wl_to_prmry_ndev(wl);
+
+ AP6210_DEBUG("---wl p2p_if "MACDBG"\n", MAC2STRDBG(mac->octet));
+
+ ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac), getbuf,
+ sizeof(getbuf), wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY), NULL);
+
+ if (ret == 0) {
+ memcpy(index, getbuf, sizeof(s32));
+ AP6210_DEBUG("---wl p2p_if ==> %d\n", *index);
+ }
+
+ return ret;
+}
+
+static s32
+wl_cfgp2p_set_discovery(struct wl_priv *wl, s32 on)
+{
+ s32 ret = BCME_OK;
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ AP6210_DEBUG("enter\n");
+
+ ret = wldev_iovar_setint(ndev, "p2p_disc", on);
+
+ if (unlikely(ret < 0)) {
+ AP6210_ERR("p2p_disc %d error %d\n", on, ret);
+ }
+
+ return ret;
+}
+
+/* Set the WL driver's P2P mode.
+ * Parameters :
+ * @mode : is one of WL_P2P_DISC_ST_{SCAN,LISTEN,SEARCH}.
+ * @channel : the channel to listen
+ * @listen_ms : the time (milli seconds) to wait
+ * @bssidx : bss index for BSSCFG
+ * Returns 0 if success
+ */
+
+s32
+wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode, u32 channel, u16 listen_ms, int bssidx)
+{
+ wl_p2p_disc_st_t discovery_mode;
+ s32 ret;
+ struct net_device *dev;
+ AP6210_DEBUG("enter\n");
+
+ if (unlikely(bssidx == WL_INVALID || bssidx >= P2PAPI_BSSCFG_MAX)) {
+ AP6210_ERR(" %d index out of range\n", bssidx);
+ return -1;
+ }
+
+ dev = wl_to_p2p_bss_ndev(wl, bssidx);
+ if (unlikely(dev == NULL)) {
+ AP6210_ERR("bssidx %d is not assigned\n", bssidx);
+ return BCME_NOTFOUND;
+ }
+
+ /* Put the WL driver into P2P Listen Mode to respond to P2P probe reqs */
+ discovery_mode.state = mode;
+ discovery_mode.chspec = wl_ch_host_to_driver(channel);
+ discovery_mode.dwell = listen_ms;
+ ret = wldev_iovar_setbuf_bsscfg(dev, "p2p_state", &discovery_mode,
+ sizeof(discovery_mode), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
+ bssidx, &wl->ioctl_buf_sync);
+
+ return ret;
+}
+
+/* Get the index of the P2P Discovery BSS */
+static s32
+wl_cfgp2p_get_disc_idx(struct wl_priv *wl, s32 *index)
+{
+ s32 ret;
+ struct net_device *dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
+
+ ret = wldev_iovar_getint(dev, "p2p_dev", index);
+ AP6210_DEBUG("p2p_dev bsscfg_idx=%d ret=%d\n", *index, ret);
+
+ if (unlikely(ret < 0)) {
+ AP6210_ERR("'p2p_dev' error %d\n", ret);
+ return ret;
+ }
+ return ret;
+}
+
+s32
+wl_cfgp2p_init_discovery(struct wl_priv *wl)
+{
+
+ s32 index = 0;
+ s32 ret = BCME_OK;
+
+ AP6210_DEBUG("enter\n");
+
+ if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) != 0) {
+ AP6210_ERR("do nothing, already initialized\n");
+ return ret;
+ }
+
+ ret = wl_cfgp2p_set_discovery(wl, 1);
+ if (ret < 0) {
+ AP6210_ERR("set discover error\n");
+ return ret;
+ }
+ /* Enable P2P Discovery in the WL Driver */
+ ret = wl_cfgp2p_get_disc_idx(wl, &index);
+
+ if (ret < 0) {
+ return ret;
+ }
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) =
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = index;
+
+ /* Set the initial discovery state to SCAN */
+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+
+ if (unlikely(ret != 0)) {
+ AP6210_ERR("unable to set WL_P2P_DISC_ST_SCAN\n");
+ wl_cfgp2p_set_discovery(wl, 0);
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0;
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL;
+ return 0;
+ }
+ return ret;
+}
+
+/* Deinitialize P2P Discovery
+ * Parameters :
+ * @wl : wl_private data
+ * Returns 0 if succes
+ */
+static s32
+wl_cfgp2p_deinit_discovery(struct wl_priv *wl)
+{
+ s32 ret = BCME_OK;
+ AP6210_DEBUG("enter\n");
+
+ if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) {
+ AP6210_ERR("do nothing, not initialized\n");
+ return -1;
+ }
+ /* Set the discovery state to SCAN */
+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ /* Disable P2P discovery in the WL driver (deletes the discovery BSSCFG) */
+ ret = wl_cfgp2p_set_discovery(wl, 0);
+
+ /* Clear our saved WPS and P2P IEs for the discovery BSS. The driver
+ * deleted these IEs when wl_cfgp2p_set_discovery() deleted the discovery
+ * BSS.
+ */
+
+ /* Clear the saved bsscfg index of the discovery BSSCFG to indicate we
+ * have no discovery BSS.
+ */
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = WL_INVALID;
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL;
+
+ return ret;
+
+}
+/* Enable P2P Discovery
+ * Parameters:
+ * @wl : wl_private data
+ * @ie : probe request ie (WPS IE + P2P IE)
+ * @ie_len : probe request ie length
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev,
+ const u8 *ie, u32 ie_len)
+{
+ s32 ret = BCME_OK;
+ s32 bssidx = (wl_to_prmry_ndev(wl) == dev) ?
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) : wl_cfgp2p_find_idx(wl, dev);
+ if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
+ AP6210_DEBUG(" DISCOVERY is already initialized, we have nothing to do\n");
+ goto set_ie;
+ }
+
+ wl_set_p2p_status(wl, DISCOVERY_ON);
+
+ AP6210_DEBUG("enter\n");
+
+ ret = wl_cfgp2p_init_discovery(wl);
+ if (unlikely(ret < 0)) {
+ AP6210_ERR(" init discovery error %d\n", ret);
+ goto exit;
+ }
+ /* Set wsec to any non-zero value in the discovery bsscfg to ensure our
+ * P2P probe responses have the privacy bit set in the 802.11 WPA IE.
+ * Some peer devices may not initiate WPS with us if this bit is not set.
+ */
+ ret = wldev_iovar_setint_bsscfg(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE),
+ "wsec", AES_ENABLED, wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ if (unlikely(ret < 0)) {
+ AP6210_ERR(" wsec error %d\n", ret);
+ }
+set_ie:
+ if (ie_len) {
+ ret = wl_cfgp2p_set_management_ie(wl, dev,
+ bssidx,
+ VNDR_IE_PRBREQ_FLAG, ie, ie_len);
+
+ if (unlikely(ret < 0)) {
+ AP6210_ERR("set probreq ie occurs error %d\n", ret);
+ goto exit;
+ }
+ }
+exit:
+ return ret;
+}
+
+/* Disable P2P Discovery
+ * Parameters:
+ * @wl : wl_private_data
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_disable_discovery(struct wl_priv *wl)
+{
+ s32 ret = BCME_OK;
+ AP6210_DEBUG(" enter\n");
+ wl_clr_p2p_status(wl, DISCOVERY_ON);
+
+ if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) {
+ AP6210_ERR(" do nothing, not initialized\n");
+ goto exit;
+ }
+
+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+
+ if (unlikely(ret < 0)) {
+
+ AP6210_ERR("unable to set WL_P2P_DISC_ST_SCAN\n");
+ }
+ /* Do a scan abort to stop the driver's scan engine in case it is still
+ * waiting out an action frame tx dwell time.
+ */
+ wl_clr_p2p_status(wl, DISCOVERY_ON);
+ ret = wl_cfgp2p_deinit_discovery(wl);
+
+exit:
+ return ret;
+}
+
+s32
+wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active,
+ u32 num_chans, u16 *channels,
+ s32 search_state, u16 action, u32 bssidx)
+{
+ s32 ret = BCME_OK;
+ s32 memsize;
+ s32 eparams_size;
+ u32 i;
+ s8 *memblk;
+ wl_p2p_scan_t *p2p_params;
+ wl_escan_params_t *eparams;
+ wlc_ssid_t ssid;
+ /* Scan parameters */
+#define P2PAPI_SCAN_NPROBES 1
+#define P2PAPI_SCAN_DWELL_TIME_MS 80
+#define P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS 40
+#define P2PAPI_SCAN_HOME_TIME_MS 60
+#define P2PAPI_SCAN_NPROBS_TIME_MS 30
+#define P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS 100
+
+ struct net_device *pri_dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
+ /* Allocate scan params which need space for 3 channels and 0 ssids */
+ eparams_size = (WL_SCAN_PARAMS_FIXED_SIZE +
+ OFFSETOF(wl_escan_params_t, params)) +
+ num_chans * sizeof(eparams->params.channel_list[0]);
+
+ memsize = sizeof(wl_p2p_scan_t) + eparams_size;
+ memblk = scanparambuf;
+ if (memsize > sizeof(scanparambuf)) {
+ AP6210_ERR(" scanpar buf too small (%u > %u)\n",
+ memsize, sizeof(scanparambuf));
+ return -1;
+ }
+ memset(memblk, 0, memsize);
+ memset(wl->ioctl_buf, 0, WLC_IOCTL_MAXLEN);
+ if (search_state == WL_P2P_DISC_ST_SEARCH) {
+ /*
+ * If we in SEARCH STATE, we don't need to set SSID explictly
+ * because dongle use P2P WILDCARD internally by default
+ */
+ wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SEARCH, 0, 0, bssidx);
+ ssid.SSID_len = htod32(0);
+
+ } else if (search_state == WL_P2P_DISC_ST_SCAN) {
+ /* SCAN STATE 802.11 SCAN
+ * WFD Supplicant has p2p_find command with (type=progressive, type= full)
+ * So if P2P_find command with type=progressive,
+ * we have to set ssid to P2P WILDCARD because
+ * we just do broadcast scan unless setting SSID
+ */
+ strncpy(ssid.SSID, WL_P2P_WILDCARD_SSID, sizeof(ssid.SSID) - 1);
+ ssid.SSID[sizeof(ssid.SSID) - 1] = 0;
+ ssid.SSID_len = htod32(WL_P2P_WILDCARD_SSID_LEN);
+ wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0, bssidx);
+ }
+ else {
+ AP6210_ERR(" invalid search state %d\n", search_state);
+ return -1;
+ }
+
+
+ /* Fill in the P2P scan structure at the start of the iovar param block */
+ p2p_params = (wl_p2p_scan_t*) memblk;
+ p2p_params->type = 'E';
+ /* Fill in the Scan structure that follows the P2P scan structure */
+ eparams = (wl_escan_params_t*) (p2p_params + 1);
+ eparams->params.bss_type = DOT11_BSSTYPE_ANY;
+ if (active)
+ eparams->params.scan_type = DOT11_SCANTYPE_ACTIVE;
+ else
+ eparams->params.scan_type = DOT11_SCANTYPE_PASSIVE;
+
+ memcpy(&eparams->params.bssid, &ether_bcast, ETHER_ADDR_LEN);
+ if (ssid.SSID_len)
+ memcpy(&eparams->params.ssid, &ssid, sizeof(wlc_ssid_t));
+
+ eparams->params.home_time = htod32(P2PAPI_SCAN_HOME_TIME_MS);
+
+ /* SOCIAL_CHAN_CNT + 1 takes care of the Progressive scan supported by
+ * the supplicant
+ */
+ if ((num_chans == SOCIAL_CHAN_CNT) || (num_chans == SOCIAL_CHAN_CNT + 1))
+ eparams->params.active_time = htod32(P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS);
+ else if (num_chans == AF_PEER_SEARCH_CNT)
+ eparams->params.active_time = htod32(P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS);
+ else if (wl_get_drv_status_all(wl, CONNECTED))
+ eparams->params.active_time = -1;
+ else
+ eparams->params.active_time = htod32(P2PAPI_SCAN_DWELL_TIME_MS);
+ eparams->params.nprobes = htod32((eparams->params.active_time /
+ P2PAPI_SCAN_NPROBS_TIME_MS));
+
+ /* Override scan params to find a peer for a connection */
+ if (num_chans == 1) {
+ eparams->params.active_time = htod32(WL_SCAN_CONNECT_DWELL_TIME_MS);
+ eparams->params.nprobes = htod32(eparams->params.active_time /
+ WL_SCAN_JOIN_PROBE_INTERVAL_MS);
+ }
+
+ if (eparams->params.nprobes <= 0)
+ eparams->params.nprobes = 1;
+ AP6210_DEBUG("nprobes # %d, active_time %d\n",
+ eparams->params.nprobes, eparams->params.active_time);
+ eparams->params.passive_time = htod32(-1);
+ eparams->params.channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
+ (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
+
+ for (i = 0; i < num_chans; i++) {
+ eparams->params.channel_list[i] = wl_ch_host_to_driver(channels[i]);
+ }
+ eparams->version = htod32(ESCAN_REQ_VERSION);
+ eparams->action = htod16(action);
+ eparams->sync_id = htod16(0x1234);
+ AP6210_DEBUG("SCAN CHANNELS : ");
+
+ for (i = 0; i < num_chans; i++) {
+ if (i == 0) AP6210_DEBUG("%d", channels[i]);
+ else AP6210_DEBUG(",%d", channels[i]);
+ }
+
+ AP6210_DEBUG("\n");
+
+ ret = wldev_iovar_setbuf_bsscfg(pri_dev, "p2p_scan",
+ memblk, memsize, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+ if (ret == BCME_OK)
+ wl_set_p2p_status(wl, SCANNING);
+ return ret;
+}
+
+/* search function to reach at common channel to send action frame
+ * Parameters:
+ * @wl : wl_private data
+ * @ndev : net device for bssidx
+ * @bssidx : bssidx for BSS
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev,
+ s32 bssidx, s32 channel)
+{
+ s32 ret = 0;
+ u32 chan_cnt = 0;
+ u16 *default_chan_list = NULL;
+ if (!p2p_is_on(wl) || ndev == NULL || bssidx == WL_INVALID)
+ return -BCME_ERROR;
+ AP6210_DEBUG(" Enter\n");
+ if (bssidx == P2PAPI_BSSCFG_PRIMARY)
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+ if (channel)
+ chan_cnt = AF_PEER_SEARCH_CNT;
+ else
+ chan_cnt = SOCIAL_CHAN_CNT;
+ default_chan_list = kzalloc(chan_cnt * sizeof(*default_chan_list), GFP_KERNEL);
+ if (default_chan_list == NULL) {
+ AP6210_ERR("channel list allocation failed \n");
+ ret = -ENOMEM;
+ goto exit;
+ }
+ if (channel) {
+ u32 i;
+ /* insert same channel to the chan_list */
+ for (i = 0; i < chan_cnt; i++) {
+ default_chan_list[i] = channel;
+ }
+ } else {
+ default_chan_list[0] = SOCIAL_CHAN_1;
+ default_chan_list[1] = SOCIAL_CHAN_2;
+ default_chan_list[2] = SOCIAL_CHAN_3;
+ }
+ ret = wl_cfgp2p_escan(wl, ndev, true, chan_cnt,
+ default_chan_list, WL_P2P_DISC_ST_SEARCH,
+ WL_SCAN_ACTION_START, bssidx);
+ kfree(default_chan_list);
+exit:
+ return ret;
+}
+
+/* Check whether pointed-to IE looks like WPA. */
+#define wl_cfgp2p_is_wpa_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
+ (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPA_OUI_TYPE)
+/* Check whether pointed-to IE looks like WPS. */
+#define wl_cfgp2p_is_wps_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
+ (const uint8 *)WPS_OUI, WPS_OUI_LEN, WPS_OUI_TYPE)
+/* Check whether the given IE looks like WFA P2P IE. */
+#define wl_cfgp2p_is_p2p_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
+ (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_P2P)
+/* Check whether the given IE looks like WFA WFDisplay IE. */
+#define WFA_OUI_TYPE_WFD 0x0a /* WiFi Display OUI TYPE */
+#define wl_cfgp2p_is_wfd_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
+ (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_WFD)
+
+static s32
+wl_cfgp2p_parse_vndr_ies(u8 *parse, u32 len,
+ struct parsed_vndr_ies *vndr_ies)
+{
+ s32 err = BCME_OK;
+ vndr_ie_t *vndrie;
+ bcm_tlv_t *ie;
+ struct parsed_vndr_ie_info *parsed_info;
+ u32 count = 0;
+ s32 remained_len;
+
+ remained_len = (s32)len;
+ memset(vndr_ies, 0, sizeof(*vndr_ies));
+
+ AP6210_DEBUG("---> len %d\n", len);
+ ie = (bcm_tlv_t *) parse;
+ if (!bcm_valid_tlv(ie, remained_len))
+ ie = NULL;
+ while (ie) {
+ if (count >= MAX_VNDR_IE_NUMBER)
+ break;
+ if (ie->id == DOT11_MNG_VS_ID) {
+ vndrie = (vndr_ie_t *) ie;
+ /* len should be bigger than OUI length + one data length at least */
+ if (vndrie->len < (VNDR_IE_MIN_LEN + 1)) {
+ AP6210_ERR("%s: invalid vndr ie. length is too small %d\n",
+ __FUNCTION__, vndrie->len);
+ goto end;
+ }
+ /* if wpa or wme ie, do not add ie */
+ if (!bcmp(vndrie->oui, (u8*)WPA_OUI, WPA_OUI_LEN) &&
+ ((vndrie->data[0] == WPA_OUI_TYPE) ||
+ (vndrie->data[0] == WME_OUI_TYPE))) {
+ AP6210_DEBUG("Found WPA/WME oui. Do not add it\n");
+ goto end;
+ }
+
+ parsed_info = &vndr_ies->ie_info[count++];
+
+ /* save vndr ie information */
+ parsed_info->ie_ptr = (char *)vndrie;
+ parsed_info->ie_len = (vndrie->len + TLV_HDR_LEN);
+ memcpy(&parsed_info->vndrie, vndrie, sizeof(vndr_ie_t));
+
+ vndr_ies->count = count;
+
+ AP6210_DEBUG("\t ** OUI %02x %02x %02x, type 0x%02x \n",
+ parsed_info->vndrie.oui[0], parsed_info->vndrie.oui[1],
+ parsed_info->vndrie.oui[2], parsed_info->vndrie.data[0]);
+ }
+end:
+ ie = bcm_next_tlv(ie, &remained_len);
+ }
+ return err;
+}
+
+
+/* Delete and Set a management vndr ie to firmware
+ * Parameters:
+ * @wl : wl_private data
+ * @ndev : net device for bssidx
+ * @bssidx : bssidx for BSS
+ * @pktflag : packet flag for IE (VNDR_IE_PRBREQ_FLAG,VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG,
+ * VNDR_IE_ASSOCREQ_FLAG)
+ * @ie : VNDR IE (such as P2P IE , WPS IE)
+ * @ie_len : VNDR IE Length
+ * Returns 0 if success.
+ */
+
+s32
+wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
+ s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len)
+{
+ s32 ret = BCME_OK;
+ u8 *curr_ie_buf = NULL;
+ u8 *mgmt_ie_buf = NULL;
+ u32 mgmt_ie_buf_len = 0;
+ u32 *mgmt_ie_len = 0;
+ u32 del_add_ie_buf_len = 0;
+ u32 total_ie_buf_len = 0;
+ u32 parsed_ie_buf_len = 0;
+ struct parsed_vndr_ies old_vndr_ies;
+ struct parsed_vndr_ies new_vndr_ies;
+ s32 i;
+ u8 *ptr;
+ s32 remained_buf_len;
+
+#define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie)
+#define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie_len)
+ memset(g_mgmt_ie_buf, 0, sizeof(g_mgmt_ie_buf));
+ curr_ie_buf = g_mgmt_ie_buf;
+ AP6210_DEBUG(" bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag);
+ if (wl->p2p != NULL) {
+ switch (pktflag) {
+ case VNDR_IE_PRBREQ_FLAG :
+ mgmt_ie_buf = IE_TYPE(probe_req, bssidx);
+ mgmt_ie_len = &IE_TYPE_LEN(probe_req, bssidx);
+ mgmt_ie_buf_len = sizeof(IE_TYPE(probe_req, bssidx));
+ break;
+ case VNDR_IE_PRBRSP_FLAG :
+ mgmt_ie_buf = IE_TYPE(probe_res, bssidx);
+ mgmt_ie_len = &IE_TYPE_LEN(probe_res, bssidx);
+ mgmt_ie_buf_len = sizeof(IE_TYPE(probe_res, bssidx));
+ break;
+ case VNDR_IE_ASSOCREQ_FLAG :
+ mgmt_ie_buf = IE_TYPE(assoc_req, bssidx);
+ mgmt_ie_len = &IE_TYPE_LEN(assoc_req, bssidx);
+ mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_req, bssidx));
+ break;
+ case VNDR_IE_ASSOCRSP_FLAG :
+ mgmt_ie_buf = IE_TYPE(assoc_res, bssidx);
+ mgmt_ie_len = &IE_TYPE_LEN(assoc_res, bssidx);
+ mgmt_ie_buf_len = sizeof(IE_TYPE(assoc_res, bssidx));
+ break;
+ case VNDR_IE_BEACON_FLAG :
+ mgmt_ie_buf = IE_TYPE(beacon, bssidx);
+ mgmt_ie_len = &IE_TYPE_LEN(beacon, bssidx);
+ mgmt_ie_buf_len = sizeof(IE_TYPE(beacon, bssidx));
+ break;
+ default:
+ mgmt_ie_buf = NULL;
+ mgmt_ie_len = NULL;
+ AP6210_ERR("not suitable type\n");
+ return -1;
+ }
+ } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
+ switch (pktflag) {
+ case VNDR_IE_PRBRSP_FLAG :
+ mgmt_ie_buf = wl->ap_info->probe_res_ie;
+ mgmt_ie_len = &wl->ap_info->probe_res_ie_len;
+ mgmt_ie_buf_len = sizeof(wl->ap_info->probe_res_ie);
+ break;
+ case VNDR_IE_BEACON_FLAG :
+ mgmt_ie_buf = wl->ap_info->beacon_ie;
+ mgmt_ie_len = &wl->ap_info->beacon_ie_len;
+ mgmt_ie_buf_len = sizeof(wl->ap_info->beacon_ie);
+ break;
+ default:
+ mgmt_ie_buf = NULL;
+ mgmt_ie_len = NULL;
+ AP6210_ERR("not suitable type\n");
+ return -1;
+ }
+ bssidx = 0;
+ } else if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_BSS) {
+ switch (pktflag) {
+ case VNDR_IE_PRBREQ_FLAG :
+ mgmt_ie_buf = wl->sta_info->probe_req_ie;
+ mgmt_ie_len = &wl->sta_info->probe_req_ie_len;
+ mgmt_ie_buf_len = sizeof(wl->sta_info->probe_req_ie);
+ break;
+ case VNDR_IE_ASSOCREQ_FLAG :
+ mgmt_ie_buf = wl->sta_info->assoc_req_ie;
+ mgmt_ie_len = &wl->sta_info->assoc_req_ie_len;
+ mgmt_ie_buf_len = sizeof(wl->sta_info->assoc_req_ie);
+ break;
+ default:
+ mgmt_ie_buf = NULL;
+ mgmt_ie_len = NULL;
+ AP6210_ERR("not suitable type\n");
+ return -1;
+ }
+ bssidx = 0;
+ } else {
+ AP6210_ERR("not suitable type\n");
+ return -1;
+ }
+
+ if (vndr_ie_len > mgmt_ie_buf_len) {
+ AP6210_ERR("extra IE size too big\n");
+ ret = -ENOMEM;
+ } else {
+ /* parse and save new vndr_ie in curr_ie_buff before comparing it */
+ if (vndr_ie && vndr_ie_len && curr_ie_buf) {
+ ptr = curr_ie_buf;
+
+ wl_cfgp2p_parse_vndr_ies((u8*)vndr_ie,
+ vndr_ie_len, &new_vndr_ies);
+
+ for (i = 0; i < new_vndr_ies.count; i++) {
+ struct parsed_vndr_ie_info *vndrie_info =
+ &new_vndr_ies.ie_info[i];
+
+ memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
+ vndrie_info->ie_len);
+ parsed_ie_buf_len += vndrie_info->ie_len;
+ }
+ }
+
+ if (mgmt_ie_buf != NULL) {
+ if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
+ (memcmp(mgmt_ie_buf, curr_ie_buf, parsed_ie_buf_len) == 0)) {
+ AP6210_DEBUG("Previous mgmt IE is equals to current IE");
+ goto exit;
+ }
+
+ /* parse old vndr_ie */
+ wl_cfgp2p_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len,
+ &old_vndr_ies);
+
+ /* make a command to delete old ie */
+ for (i = 0; i < old_vndr_ies.count; i++) {
+ struct parsed_vndr_ie_info *vndrie_info =
+ &old_vndr_ies.ie_info[i];
+
+ AP6210_DEBUG("DELETED ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
+ vndrie_info->vndrie.id, vndrie_info->vndrie.len,
+ vndrie_info->vndrie.oui[0], vndrie_info->vndrie.oui[1],
+ vndrie_info->vndrie.oui[2]);
+
+ del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf,
+ bssidx, pktflag, vndrie_info->vndrie.oui,
+ vndrie_info->vndrie.id,
+ vndrie_info->ie_ptr + VNDR_IE_FIXED_LEN,
+ vndrie_info->ie_len - VNDR_IE_FIXED_LEN,
+ "del");
+
+ curr_ie_buf += del_add_ie_buf_len;
+ total_ie_buf_len += del_add_ie_buf_len;
+ }
+ }
+
+ *mgmt_ie_len = 0;
+ /* Add if there is any extra IE */
+ if (mgmt_ie_buf && parsed_ie_buf_len) {
+ ptr = mgmt_ie_buf;
+
+ remained_buf_len = mgmt_ie_buf_len;
+
+ /* make a command to add new ie */
+ for (i = 0; i < new_vndr_ies.count; i++) {
+ struct parsed_vndr_ie_info *vndrie_info =
+ &new_vndr_ies.ie_info[i];
+
+ AP6210_DEBUG("ADDED ID : %d, Len: %d(%d), OUI:%02x:%02x:%02x\n",
+ vndrie_info->vndrie.id, vndrie_info->vndrie.len,
+ vndrie_info->ie_len - 2,
+ vndrie_info->vndrie.oui[0], vndrie_info->vndrie.oui[1],
+ vndrie_info->vndrie.oui[2]);
+
+ del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf,
+ bssidx, pktflag, vndrie_info->vndrie.oui,
+ vndrie_info->vndrie.id,
+ vndrie_info->ie_ptr + VNDR_IE_FIXED_LEN,
+ vndrie_info->ie_len - VNDR_IE_FIXED_LEN,
+ "add");
+
+ /* verify remained buf size before copy data */
+ if (remained_buf_len >= vndrie_info->ie_len) {
+ remained_buf_len -= vndrie_info->ie_len;
+ } else {
+ AP6210_ERR("no space in mgmt_ie_buf: pktflag = %d, "
+ "found vndr ies # = %d(cur %d), remained len %d, "
+ "cur mgmt_ie_len %d, new ie len = %d\n",
+ pktflag, new_vndr_ies.count, i, remained_buf_len,
+ *mgmt_ie_len, vndrie_info->ie_len);
+ break;
+ }
+
+ /* save the parsed IE in wl struct */
+ memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
+ vndrie_info->ie_len);
+ *mgmt_ie_len += vndrie_info->ie_len;
+
+ curr_ie_buf += del_add_ie_buf_len;
+ total_ie_buf_len += del_add_ie_buf_len;
+ }
+ }
+ if (total_ie_buf_len) {
+ ret = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", g_mgmt_ie_buf,
+ total_ie_buf_len, wl->ioctl_buf, WLC_IOCTL_MAXLEN,
+ bssidx, &wl->ioctl_buf_sync);
+ if (ret)
+ AP6210_ERR("vndr ie set error : %d\n", ret);
+ }
+ }
+#undef IE_TYPE
+#undef IE_TYPE_LEN
+exit:
+ return ret;
+}
+
+/* Clear the manament IE buffer of BSSCFG
+ * Parameters:
+ * @wl : wl_private data
+ * @bssidx : bssidx for BSS
+ *
+ * Returns 0 if success.
+ */
+s32
+wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx)
+{
+ s32 vndrie_flag[] = {VNDR_IE_BEACON_FLAG, VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG,
+ VNDR_IE_PRBREQ_FLAG, VNDR_IE_ASSOCREQ_FLAG};
+ s32 index = -1;
+ struct net_device *ndev = wl_cfgp2p_find_ndev(wl, bssidx);
+#define INIT_IE(IE_TYPE, BSS_TYPE) \
+ do { \
+ memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \
+ sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \
+ wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \
+ } while (0);
+
+ if (bssidx < 0 || ndev == NULL) {
+ AP6210_ERR("invalid %s\n", (bssidx < 0) ? "bssidx" : "ndev");
+ return BCME_BADARG;
+ }
+ for (index = 0; index < ARRAYSIZE(vndrie_flag); index++) {
+ /* clean up vndr ies in dongle */
+ wl_cfgp2p_set_management_ie(wl, ndev, bssidx, vndrie_flag[index], NULL, 0);
+ }
+ INIT_IE(probe_req, bssidx);
+ INIT_IE(probe_res, bssidx);
+ INIT_IE(assoc_req, bssidx);
+ INIT_IE(assoc_res, bssidx);
+ INIT_IE(beacon, bssidx);
+ return BCME_OK;
+}
+
+
+/* Is any of the tlvs the expected entry? If
+ * not update the tlvs buffer pointer/length.
+ */
+static bool
+wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type)
+{
+ /* If the contents match the OUI and the type */
+ if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
+ !bcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
+ type == ie[TLV_BODY_OFF + oui_len]) {
+ return TRUE;
+ }
+
+ if (tlvs == NULL)
+ return FALSE;
+ /* point to the next ie */
+ ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
+ /* calculate the length of the rest of the buffer */
+ *tlvs_len -= (int)(ie - *tlvs);
+ /* update the pointer to the start of the buffer */
+ *tlvs = ie;
+
+ return FALSE;
+}
+
+wpa_ie_fixed_t *
+wl_cfgp2p_find_wpaie(u8 *parse, u32 len)
+{
+ bcm_tlv_t *ie;
+
+ while ((ie = bcm_parse_tlvs(parse, (u32)len, DOT11_MNG_VS_ID))) {
+ if (wl_cfgp2p_is_wpa_ie((u8*)ie, &parse, &len)) {
+ return (wpa_ie_fixed_t *)ie;
+ }
+ }
+ return NULL;
+}
+
+wpa_ie_fixed_t *
+wl_cfgp2p_find_wpsie(u8 *parse, u32 len)
+{
+ bcm_tlv_t *ie;
+
+ while ((ie = bcm_parse_tlvs(parse, (u32)len, DOT11_MNG_VS_ID))) {
+ if (wl_cfgp2p_is_wps_ie((u8*)ie, &parse, &len)) {
+ return (wpa_ie_fixed_t *)ie;
+ }
+ }
+ return NULL;
+}
+
+wifi_p2p_ie_t *
+wl_cfgp2p_find_p2pie(u8 *parse, u32 len)
+{
+ bcm_tlv_t *ie;
+
+ while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) {
+ if (wl_cfgp2p_is_p2p_ie((uint8*)ie, &parse, &len)) {
+ return (wifi_p2p_ie_t *)ie;
+ }
+ }
+ return NULL;
+}
+
+wifi_wfd_ie_t *
+wl_cfgp2p_find_wfdie(u8 *parse, u32 len)
+{
+ bcm_tlv_t *ie;
+
+ while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) {
+ if (wl_cfgp2p_is_wfd_ie((uint8*)ie, &parse, &len)) {
+ return (wifi_wfd_ie_t *)ie;
+ }
+ }
+ return NULL;
+}
+static u32
+wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag,
+ s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd)
+{
+ vndr_ie_setbuf_t hdr; /* aligned temporary vndr_ie buffer header */
+ s32 iecount;
+ u32 data_offset;
+
+ /* Validate the pktflag parameter */
+ if ((pktflag & ~(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG |
+ VNDR_IE_ASSOCRSP_FLAG | VNDR_IE_AUTHRSP_FLAG |
+ VNDR_IE_PRBREQ_FLAG | VNDR_IE_ASSOCREQ_FLAG))) {
+ AP6210_ERR("p2pwl_vndr_ie: Invalid packet flag 0x%x\n", pktflag);
+ return -1;
+ }
+
+ /* Copy the vndr_ie SET command ("add"/"del") to the buffer */
+ strncpy(hdr.cmd, add_del_cmd, VNDR_IE_CMD_LEN - 1);
+ hdr.cmd[VNDR_IE_CMD_LEN - 1] = '\0';
+
+ /* Set the IE count - the buffer contains only 1 IE */
+ iecount = htod32(1);
+ memcpy((void *)&hdr.vndr_ie_buffer.iecount, &iecount, sizeof(s32));
+
+ /* Copy packet flags that indicate which packets will contain this IE */
+ pktflag = htod32(pktflag);
+ memcpy((void *)&hdr.vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag,
+ sizeof(u32));
+
+ /* Add the IE ID to the buffer */
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = ie_id;
+
+ /* Add the IE length to the buffer */
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len =
+ (uint8) VNDR_IE_MIN_LEN + datalen;
+
+ /* Add the IE OUI to the buffer */
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[0] = oui[0];
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[1] = oui[1];
+ hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[2] = oui[2];
+
+ /* Copy the aligned temporary vndr_ie buffer header to the IE buffer */
+ memcpy(iebuf, &hdr, sizeof(hdr) - 1);
+
+ /* Copy the IE data to the IE buffer */
+ data_offset =
+ (u8*)&hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[0] -
+ (u8*)&hdr;
+ memcpy(iebuf + data_offset, data, datalen);
+ return data_offset + datalen;
+
+}
+
+/*
+ * Search the bssidx based on dev argument
+ * Parameters:
+ * @wl : wl_private data
+ * @ndev : net device to search bssidx
+ * Returns bssidx for ndev
+ */
+s32
+wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev)
+{
+ u32 i;
+ s32 index = -1;
+
+ if (ndev == NULL) {
+ AP6210_ERR(" ndev is NULL\n");
+ goto exit;
+ }
+ if (!wl->p2p_supported) {
+ return P2PAPI_BSSCFG_PRIMARY;
+ }
+ for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
+ if (ndev == wl_to_p2p_bss_ndev(wl, i)) {
+ index = wl_to_p2p_bss_bssidx(wl, i);
+ break;
+ }
+ }
+ if (index == -1)
+ return P2PAPI_BSSCFG_PRIMARY;
+exit:
+ return index;
+}
+
+struct net_device *
+wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx)
+{
+ u32 i;
+ struct net_device *ndev = NULL;
+ if (bssidx < 0) {
+ AP6210_ERR(" bsscfg idx is invalid\n");
+ goto exit;
+ }
+
+ for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
+ if (bssidx == wl_to_p2p_bss_bssidx(wl, i)) {
+ ndev = wl_to_p2p_bss_ndev(wl, i);
+ break;
+ }
+ }
+
+exit:
+ return ndev;
+}
+
+/*
+ * Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE
+ */
+s32
+wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ s32 ret = BCME_OK;
+ struct net_device *netdev;
+ if (!wl || !wl->p2p)
+ return BCME_ERROR;
+ if (wl->p2p_net == ndev) {
+ netdev = wl_to_prmry_ndev(wl);
+ } else {
+ netdev = ndev;
+ }
+ AP6210_DEBUG(" Enter\n");
+ if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) {
+ wl_set_p2p_status(wl, LISTEN_EXPIRED);
+ if (timer_pending(&wl->p2p->listen_timer)) {
+ del_timer_sync(&wl->p2p->listen_timer);
+ }
+
+ if (wl->afx_hdl->is_listen == TRUE &&
+ wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL)) {
+ AP6210_DEBUG("Listen DONE for action frame\n");
+ complete(&wl->act_frm_scan);
+ }
+#ifdef WL_CFG80211_SYNC_GON
+ else if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) {
+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, netdev);
+ AP6210_DEBUG("Listen DONE and wake up wait_next_af !!(%d)\n",
+ jiffies_to_msecs(jiffies - wl->af_tx_sent_jiffies));
+
+ if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM))
+ wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, netdev);
+
+ complete(&wl->wait_next_af);
+ }
+#endif /* WL_CFG80211_SYNC_GON */
+
+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL)) {
+#else
+ if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL) ||
+ wl_get_drv_status_all(wl, FAKE_REMAINING_ON_CHANNEL)) {
+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+ AP6210_DEBUG("Listen DONE for ramain on channel expired\n");
+ wl_clr_drv_status(wl, REMAINING_ON_CHANNEL, netdev);
+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ wl_clr_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, netdev);
+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+ if (ndev && (ndev->ieee80211_ptr != NULL)) {
+ cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
+ &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL);
+ }
+ }
+ if (wl_add_remove_eventmsg(wl_to_prmry_ndev(wl),
+ WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) {
+ AP6210_ERR(" failed to unset WLC_E_P2P_PROPREQ_MSG\n");
+ }
+ } else
+ wl_clr_p2p_status(wl, LISTEN_EXPIRED);
+
+ return ret;
+
+}
+
+/*
+ * Timer expire callback function for LISTEN
+ * We can't report cfg80211_remain_on_channel_expired from Timer ISR context,
+ * so lets do it from thread context.
+ */
+void
+wl_cfgp2p_listen_expired(unsigned long data)
+{
+ wl_event_msg_t msg;
+ struct wl_priv *wl = (struct wl_priv *) data;
+ AP6210_DEBUG(" Enter\n");
+ bzero(&msg, sizeof(wl_event_msg_t));
+ msg.event_type = hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE);
+ wl_cfg80211_event(wl->p2p_net ? wl->p2p_net :
+ wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL);
+}
+/*
+ * Routine for cancelling the P2P LISTEN
+ */
+static s32
+wl_cfgp2p_cancel_listen(struct wl_priv *wl, struct net_device *ndev,
+ bool notify)
+{
+ AP6210_DEBUG("Enter \n");
+ /* Irrespective of whether timer is running or not, reset
+ * the LISTEN state.
+ */
+ if (timer_pending(&wl->p2p->listen_timer)) {
+ del_timer_sync(&wl->p2p->listen_timer);
+ if (notify)
+ if (ndev && ndev->ieee80211_ptr) {
+ cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id,
+ &wl->remain_on_chan, wl->remain_on_chan_type,
+ GFP_KERNEL);
+ }
+ }
+ return 0;
+}
+/*
+ * Do a P2P Listen on the given channel for the given duration.
+ * A listen consists of sitting idle and responding to P2P probe requests
+ * with a P2P probe response.
+ *
+ * This fn assumes dongle p2p device discovery is already enabled.
+ * Parameters :
+ * @wl : wl_private data
+ * @channel : channel to listen
+ * @duration_ms : the time (milli seconds) to wait
+ */
+s32
+wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
+{
+#define EXTRA_DELAY_TIME 100
+ s32 ret = BCME_OK;
+ struct timer_list *_timer;
+ s32 extra_delay;
+ struct net_device *netdev = wl_to_prmry_ndev(wl);
+
+ AP6210_DEBUG(" Enter Listen Channel : %d, Duration : %d\n", channel, duration_ms);
+ if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) {
+
+ AP6210_ERR(" Discovery is not set, so we have noting to do\n");
+
+ ret = BCME_NOTREADY;
+ goto exit;
+ }
+ if (timer_pending(&wl->p2p->listen_timer)) {
+ AP6210_DEBUG("previous LISTEN is not completed yet\n");
+ goto exit;
+
+ }
+#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ else
+ wl_clr_p2p_status(wl, LISTEN_EXPIRED);
+#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+ if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, true) != BCME_OK) {
+ AP6210_ERR(" failed to set WLC_E_P2P_PROPREQ_MSG\n");
+ }
+
+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms,
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ _timer = &wl->p2p->listen_timer;
+
+ /* We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle ,
+ * otherwise we will wait up to duration_ms + 100ms + duration / 10
+ */
+ if (ret == BCME_OK) {
+ extra_delay = EXTRA_DELAY_TIME + (duration_ms / 10);
+ } else {
+ /* if failed to set listen, it doesn't need to wait whole duration. */
+ duration_ms = 100 + duration_ms / 20;
+ extra_delay = 0;
+ }
+
+ INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration_ms, extra_delay);
+#ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+ wl_clr_p2p_status(wl, LISTEN_EXPIRED);
+#endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
+
+#undef EXTRA_DELAY_TIME
+exit:
+ return ret;
+}
+
+
+s32
+wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable)
+{
+ s32 ret = BCME_OK;
+ AP6210_DEBUG(" Enter\n");
+ if (!wl_get_p2p_status(wl, DISCOVERY_ON)) {
+
+ AP6210_DEBUG(" do nothing, discovery is off\n");
+ return ret;
+ }
+ if (wl_get_p2p_status(wl, SEARCH_ENABLED) == enable) {
+ AP6210_DEBUG("already : %d\n", enable);
+ return ret;
+ }
+
+ wl_chg_p2p_status(wl, SEARCH_ENABLED);
+ /* When disabling Search, reset the WL driver's p2p discovery state to
+ * WL_P2P_DISC_ST_SCAN.
+ */
+ if (!enable) {
+ wl_clr_p2p_status(wl, SCANNING);
+ ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+ }
+
+ return ret;
+}
+
+/*
+ * Callback function for WLC_E_ACTION_FRAME_COMPLETE, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE
+ */
+s32
+wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data)
+{
+ s32 ret = BCME_OK;
+ u32 event_type = ntoh32(e->event_type);
+ u32 status = ntoh32(e->status);
+ AP6210_DEBUG(" Enter\n");
+ if (event_type == WLC_E_ACTION_FRAME_COMPLETE) {
+
+ AP6210_DEBUG(" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status);
+ if (status == WLC_E_STATUS_SUCCESS) {
+ wl_set_p2p_status(wl, ACTION_TX_COMPLETED);
+ AP6210_DEBUG("WLC_E_ACTION_FRAME_COMPLETE : ACK\n");
+ }
+ else {
+ wl_set_p2p_status(wl, ACTION_TX_NOACK);
+ AP6210_DEBUG("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n");
+ wl_stop_wait_next_action_frame(wl, ndev);
+ }
+ } else {
+ AP6210_DEBUG(" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received,"
+ "status : %d\n", status);
+
+ if (wl_get_drv_status_all(wl, SENDING_ACT_FRM))
+ complete(&wl->send_af_done);
+ }
+ return ret;
+}
+/* Send an action frame immediately without doing channel synchronization.
+ *
+ * This function does not wait for a completion event before returning.
+ * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action
+ * frame is transmitted.
+ * The WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE event will be received when an
+ * 802.11 ack has been received for the sent action frame.
+ */
+s32
+wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
+ wl_af_params_t *af_params, s32 bssidx)
+{
+ s32 ret = BCME_OK;
+ s32 timeout = 0;
+ wl_eventmsg_buf_t buf;
+
+
+ AP6210_DEBUG("\n");
+ AP6210_DEBUG("channel : %u , dwell time : %u\n",
+ af_params->channel, af_params->dwell_time);
+
+ wl_clr_p2p_status(wl, ACTION_TX_COMPLETED);
+ wl_clr_p2p_status(wl, ACTION_TX_NOACK);
+
+ bzero(&buf, sizeof(wl_eventmsg_buf_t));
+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, true);
+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, true);
+ if ((ret = wl_cfg80211_apply_eventbuffer(wl_to_prmry_ndev(wl), wl, &buf)) < 0)
+ return ret;
+
+#define MAX_WAIT_TIME 2000
+ if (bssidx == P2PAPI_BSSCFG_PRIMARY)
+ bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
+
+ wl->af_sent_channel = af_params->channel;
+#ifdef WL_CFG80211_SYNC_GON
+ wl->af_tx_sent_jiffies = jiffies;
+#endif /* WL_CFG80211_SYNC_GON */
+
+ ret = wldev_iovar_setbuf_bsscfg(dev, "actframe", af_params, sizeof(*af_params),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+
+ if (ret < 0) {
+ AP6210_ERR(" sending action frame is failed\n");
+ goto exit;
+ }
+
+ timeout = wait_for_completion_timeout(&wl->send_af_done, msecs_to_jiffies(MAX_WAIT_TIME));
+
+ if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) {
+ AP6210_DEBUG("tx action frame operation is completed\n");
+ ret = BCME_OK;
+ } else {
+ ret = BCME_ERROR;
+ AP6210_DEBUG("tx action frame operation is failed\n");
+ }
+ /* clear status bit for action tx */
+ wl_clr_p2p_status(wl, ACTION_TX_COMPLETED);
+ wl_clr_p2p_status(wl, ACTION_TX_NOACK);
+
+exit:
+ AP6210_DEBUG(" via act frame iovar : status = %d\n", ret);
+
+ bzero(&buf, sizeof(wl_eventmsg_buf_t));
+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE, false);
+ wl_cfg80211_add_to_eventbuffer(&buf, WLC_E_ACTION_FRAME_COMPLETE, false);
+ if ((ret = wl_cfg80211_apply_eventbuffer(wl_to_prmry_ndev(wl), wl, &buf)) < 0)
+ AP6210_ERR("TX frame events revert back failed \n");
+
+#undef MAX_WAIT_TIME
+ return ret;
+}
+
+/* Generate our P2P Device Address and P2P Interface Address from our primary
+ * MAC address.
+ */
+void
+wl_cfgp2p_generate_bss_mac(struct ether_addr *primary_addr,
+ struct ether_addr *out_dev_addr, struct ether_addr *out_int_addr)
+{
+ memset(out_dev_addr, 0, sizeof(*out_dev_addr));
+ memset(out_int_addr, 0, sizeof(*out_int_addr));
+
+ /* Generate the P2P Device Address. This consists of the device's
+ * primary MAC address with the locally administered bit set.
+ */
+ memcpy(out_dev_addr, primary_addr, sizeof(*out_dev_addr));
+ out_dev_addr->octet[0] |= 0x02;
+
+ /* Generate the P2P Interface Address. If the discovery and connection
+ * BSSCFGs need to simultaneously co-exist, then this address must be
+ * different from the P2P Device Address.
+ */
+ memcpy(out_int_addr, out_dev_addr, sizeof(*out_int_addr));
+ out_int_addr->octet[4] ^= 0x80;
+
+}
+
+/* P2P IF Address change to Virtual Interface MAC Address */
+void
+wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id)
+{
+ wifi_p2p_ie_t *ie = (wifi_p2p_ie_t*) buf;
+ u16 len = ie->len;
+ u8 *subel;
+ u8 subelt_id;
+ u16 subelt_len;
+ AP6210_DEBUG(" Enter\n");
+
+ /* Point subel to the P2P IE's subelt field.
+ * Subtract the preceding fields (id, len, OUI, oui_type) from the length.
+ */
+ subel = ie->subelts;
+ len -= 4; /* exclude OUI + OUI_TYPE */
+
+ while (len >= 3) {
+ /* attribute id */
+ subelt_id = *subel;
+ subel += 1;
+ len -= 1;
+
+ /* 2-byte little endian */
+ subelt_len = *subel++;
+ subelt_len |= *subel++ << 8;
+
+ len -= 2;
+ len -= subelt_len; /* for the remaining subelt fields */
+
+ if (subelt_id == element_id) {
+ if (subelt_id == P2P_SEID_INTINTADDR) {
+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
+ AP6210_DEBUG("Intended P2P Interface Address ATTR FOUND\n");
+ } else if (subelt_id == P2P_SEID_DEV_ID) {
+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
+ AP6210_DEBUG("Device ID ATTR FOUND\n");
+ } else if (subelt_id == P2P_SEID_DEV_INFO) {
+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
+ AP6210_DEBUG("Device INFO ATTR FOUND\n");
+ } else if (subelt_id == P2P_SEID_GROUP_ID) {
+ memcpy(subel, p2p_int_addr->octet, ETHER_ADDR_LEN);
+ AP6210_DEBUG("GROUP ID ATTR FOUND\n");
+ } return;
+ } else {
+ AP6210_DEBUG("OTHER id : %d\n", subelt_id);
+ }
+ subel += subelt_len;
+ }
+}
+/*
+ * Check if a BSS is up.
+ * This is a common implementation called by most OSL implementations of
+ * p2posl_bss_isup(). DO NOT call this function directly from the
+ * common code -- call p2posl_bss_isup() instead to allow the OSL to
+ * override the common implementation if necessary.
+ */
+bool
+wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx)
+{
+ s32 result, val;
+ bool isup = false;
+ s8 getbuf[64];
+
+ /* Check if the BSS is up */
+ *(int*)getbuf = -1;
+ result = wldev_iovar_getbuf_bsscfg(ndev, "bss", &bsscfg_idx,
+ sizeof(bsscfg_idx), getbuf, sizeof(getbuf), 0, NULL);
+ if (result != 0) {
+ AP6210_ERR("'wl bss -C %d' failed: %d\n", bsscfg_idx, result);
+ AP6210_ERR("NOTE: this ioctl error is normal "
+ "when the BSS has not been created yet.\n");
+ } else {
+ val = *(int*)getbuf;
+ val = dtoh32(val);
+ AP6210_DEBUG("---wl bss -C %d ==> %d\n", bsscfg_idx, val);
+ isup = (val ? TRUE : FALSE);
+ }
+ return isup;
+}
+
+
+/* Bring up or down a BSS */
+s32
+wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up)
+{
+ s32 ret = BCME_OK;
+ s32 val = up ? 1 : 0;
+
+ struct {
+ s32 cfg;
+ s32 val;
+ } bss_setbuf;
+
+ bss_setbuf.cfg = htod32(bsscfg_idx);
+ bss_setbuf.val = htod32(val);
+ AP6210_DEBUG("---wl bss -C %d %s\n", bsscfg_idx, up ? "up" : "down");
+ ret = wldev_iovar_setbuf(ndev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+
+ if (ret != 0) {
+ AP6210_ERR("'bss %d' failed with %d\n", up, ret);
+ }
+
+ return ret;
+}
+
+/* Check if 'p2p' is supported in the driver */
+s32
+wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
+{
+ s32 ret = BCME_OK;
+ s32 p2p_supported = 0;
+ ret = wldev_iovar_getint(ndev, "p2p",
+ &p2p_supported);
+ if (ret < 0) {
+ AP6210_ERR("wl p2p error %d\n", ret);
+ return 0;
+ }
+ if (p2p_supported == 1) {
+ AP6210_DEBUG("p2p is supported\n");
+ } else {
+ AP6210_DEBUG("p2p is unsupported\n");
+ p2p_supported = 0;
+ }
+ return p2p_supported;
+}
+
+/* Cleanup P2P resources */
+s32
+wl_cfgp2p_down(struct wl_priv *wl)
+{
+ s32 i = 0, index = -1;
+ wl_cfgp2p_cancel_listen(wl,
+ wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl), TRUE);
+ for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) {
+ index = wl_to_p2p_bss_bssidx(wl, i);
+ if (index != WL_INVALID)
+ wl_cfgp2p_clear_management_ie(wl, index);
+ }
+ wl_cfgp2p_deinit_priv(wl);
+ return 0;
+}
+
+s32
+wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
+{
+ s32 ret = -1;
+ int count, start, duration;
+ wl_p2p_sched_t dongle_noa;
+
+ AP6210_DEBUG(" Enter\n");
+
+ memset(&dongle_noa, 0, sizeof(dongle_noa));
+
+ if (wl->p2p && wl->p2p->vif_created) {
+
+ wl->p2p->noa.desc[0].start = 0;
+
+ sscanf(buf, "%10d %10d %10d", &count, &start, &duration);
+ AP6210_DEBUG("set_p2p_noa count %d start %d duration %d\n",
+ count, start, duration);
+ if (count != -1)
+ wl->p2p->noa.desc[0].count = count;
+
+ /* supplicant gives interval as start */
+ if (start != -1)
+ wl->p2p->noa.desc[0].interval = start;
+
+ if (duration != -1)
+ wl->p2p->noa.desc[0].duration = duration;
+
+ if (wl->p2p->noa.desc[0].count != 255) {
+ wl->p2p->noa.desc[0].start = 200;
+ dongle_noa.type = WL_P2P_SCHED_TYPE_REQ_ABS;
+ dongle_noa.action = WL_P2P_SCHED_ACTION_GOOFF;
+ dongle_noa.option = WL_P2P_SCHED_OPTION_TSFOFS;
+ }
+ else {
+ /* Continuous NoA interval. */
+ dongle_noa.action = WL_P2P_SCHED_ACTION_NONE;
+ dongle_noa.type = WL_P2P_SCHED_TYPE_ABS;
+ if ((wl->p2p->noa.desc[0].interval == 102) ||
+ (wl->p2p->noa.desc[0].interval == 100)) {
+ wl->p2p->noa.desc[0].start = 100 -
+ wl->p2p->noa.desc[0].duration;
+ dongle_noa.option = WL_P2P_SCHED_OPTION_BCNPCT;
+ }
+ else {
+ dongle_noa.option = WL_P2P_SCHED_OPTION_NORMAL;
+ }
+ }
+ /* Put the noa descriptor in dongle format for dongle */
+ dongle_noa.desc[0].count = htod32(wl->p2p->noa.desc[0].count);
+ if (dongle_noa.option == WL_P2P_SCHED_OPTION_BCNPCT) {
+ dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start);
+ dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration);
+ }
+ else {
+ dongle_noa.desc[0].start = htod32(wl->p2p->noa.desc[0].start*1000);
+ dongle_noa.desc[0].duration = htod32(wl->p2p->noa.desc[0].duration*1000);
+ }
+ dongle_noa.desc[0].interval = htod32(wl->p2p->noa.desc[0].interval*1000);
+
+ ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
+ "p2p_noa", &dongle_noa, sizeof(dongle_noa), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
+ &wl->ioctl_buf_sync);
+
+ if (ret < 0) {
+ AP6210_ERR("fw set p2p_noa failed %d\n", ret);
+ }
+ }
+ else {
+ AP6210_ERR("ERROR: set_noa in non-p2p mode\n");
+ }
+ return ret;
+}
+s32
+wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int buf_len)
+{
+
+ wifi_p2p_noa_desc_t *noa_desc;
+ int len = 0, i;
+ char _buf[200];
+
+ AP6210_DEBUG(" Enter\n");
+ buf[0] = '\0';
+ if (wl->p2p && wl->p2p->vif_created) {
+ if (wl->p2p->noa.desc[0].count || wl->p2p->ops.ops) {
+ _buf[0] = 1; /* noa index */
+ _buf[1] = (wl->p2p->ops.ops ? 0x80: 0) |
+ (wl->p2p->ops.ctw & 0x7f); /* ops + ctw */
+ len += 2;
+ if (wl->p2p->noa.desc[0].count) {
+ noa_desc = (wifi_p2p_noa_desc_t*)&_buf[len];
+ noa_desc->cnt_type = wl->p2p->noa.desc[0].count;
+ noa_desc->duration = wl->p2p->noa.desc[0].duration;
+ noa_desc->interval = wl->p2p->noa.desc[0].interval;
+ noa_desc->start = wl->p2p->noa.desc[0].start;
+ len += sizeof(wifi_p2p_noa_desc_t);
+ }
+ if (buf_len <= len * 2) {
+ AP6210_ERR("ERROR: buf_len %d in not enough for"
+ "returning noa in string format\n", buf_len);
+ return -1;
+ }
+ /* We have to convert the buffer data into ASCII strings */
+ for (i = 0; i < len; i++) {
+ snprintf(buf, 3, "%02x", _buf[i]);
+ buf += 2;
+ }
+ buf[i*2] = '\0';
+ }
+ }
+ else {
+ AP6210_ERR("ERROR: get_noa in non-p2p mode\n");
+ return -1;
+ }
+ return len * 2;
+}
+s32
+wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len)
+{
+ int ps, ctw;
+ int ret = -1;
+ s32 legacy_ps;
+
+ AP6210_DEBUG(" Enter\n");
+ if (wl->p2p && wl->p2p->vif_created) {
+ sscanf(buf, "%10d %10d %10d", &legacy_ps, &ps, &ctw);
+ AP6210_DEBUG(" Enter legacy_ps %d ps %d ctw %d\n", legacy_ps, ps, ctw);
+ if (ctw != -1) {
+ wl->p2p->ops.ctw = ctw;
+ ret = 0;
+ }
+ if (ps != -1) {
+ wl->p2p->ops.ops = ps;
+ ret = wldev_iovar_setbuf(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
+ "p2p_ops", &wl->p2p->ops, sizeof(wl->p2p->ops),
+ wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
+ if (ret < 0) {
+ AP6210_ERR("fw set p2p_ops failed %d\n", ret);
+ }
+ }
+
+ if ((legacy_ps != -1) && ((legacy_ps == PM_MAX) || (legacy_ps == PM_OFF))) {
+#if !defined(SUPPORT_PM2_ONLY)
+ if (legacy_ps == PM_MAX)
+ legacy_ps = PM_FAST;
+#endif /* SUPPORT_PM2_ONLY */
+
+ ret = wldev_ioctl(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
+ WLC_SET_PM, &legacy_ps, sizeof(legacy_ps), true);
+ if (unlikely(ret)) {
+ AP6210_ERR("error (%d)\n", ret);
+ } else {
+ wl_cfg80211_update_power_mode(ndev);
+ }
+ }
+ else
+ AP6210_ERR("ilegal setting\n");
+ }
+ else {
+ AP6210_ERR("ERROR: set_p2p_ps in non-p2p mode\n");
+ ret = -1;
+ }
+ return ret;
+}
+
+u8 *
+wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id)
+{
+ wifi_p2p_ie_t *ie = NULL;
+ u16 len = 0;
+ u8 *subel;
+ u8 subelt_id;
+ u16 subelt_len;
+
+ if (!buf) {
+ AP6210_ERR("P2P IE not present");
+ return 0;
+ }
+
+ ie = (wifi_p2p_ie_t*) buf;
+ len = ie->len;
+
+ /* Point subel to the P2P IE's subelt field.
+ * Subtract the preceding fields (id, len, OUI, oui_type) from the length.
+ */
+ subel = ie->subelts;
+ len -= 4; /* exclude OUI + OUI_TYPE */
+
+ while (len >= 3) {
+ /* attribute id */
+ subelt_id = *subel;
+ subel += 1;
+ len -= 1;
+
+ /* 2-byte little endian */
+ subelt_len = *subel++;
+ subelt_len |= *subel++ << 8;
+
+ len -= 2;
+ len -= subelt_len; /* for the remaining subelt fields */
+
+ if (subelt_id == element_id) {
+ /* This will point to start of subelement attrib after
+ * attribute id & len
+ */
+ return subel;
+ }
+
+ /* Go to next subelement */
+ subel += subelt_len;
+ }
+
+ /* Not Found */
+ return NULL;
+}
+
+#define P2P_GROUP_CAPAB_GO_BIT 0x01
+u8 *
+wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length)
+{
+ wifi_p2p_ie_t * p2p_ie = NULL;
+ u8 *capability = NULL;
+ bool p2p_go = 0;
+ u8 *ptr = NULL;
+
+ if (!(p2p_ie = wl_cfgp2p_find_p2pie(((u8 *) bi) + bi->ie_offset, bi->ie_length))) {
+ AP6210_ERR("P2P IE not found");
+ return NULL;
+ }
+
+ if (!(capability = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_P2P_INFO))) {
+ AP6210_ERR("P2P Capability attribute not found");
+ return NULL;
+ }
+
+ /* Check Group capability for Group Owner bit */
+ p2p_go = capability[1] & P2P_GROUP_CAPAB_GO_BIT;
+ if (!p2p_go) {
+ return bi->BSSID.octet;
+ }
+
+ /* In probe responses, DEVICE INFO attribute will be present */
+ if (!(ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_INFO))) {
+ /* If DEVICE_INFO is not found, this might be a beacon frame.
+ * check for DEVICE_ID in the beacon frame.
+ */
+ ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_ID);
+ }
+
+ if (!ptr)
+ AP6210_ERR(" Both DEVICE_ID & DEVICE_INFO attribute not present in P2P IE ");
+
+ return ptr;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+static void
+wl_cfgp2p_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
+{
+ snprintf(info->driver, sizeof(info->driver), "p2p");
+ snprintf(info->version, sizeof(info->version), "%lu", (unsigned long)(0));
+}
+
+struct ethtool_ops cfgp2p_ethtool_ops = {
+ .get_drvinfo = wl_cfgp2p_ethtool_get_drvinfo
+};
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */
+
+s32
+wl_cfgp2p_register_ndev(struct wl_priv *wl)
+{
+ int ret = 0;
+ struct net_device* net = NULL;
+ struct wireless_dev *wdev = NULL;
+ uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x33, 0x22, 0x11 };
+
+ if (wl->p2p_net) {
+ AP6210_ERR("p2p_net defined already.\n");
+ return -EINVAL;
+ }
+
+ /* Allocate etherdev, including space for private structure */
+ if (!(net = alloc_etherdev(sizeof(struct wl_priv *)))) {
+ AP6210_ERR("%s: OOM - alloc_etherdev\n", __FUNCTION__);
+ return -ENODEV;
+ }
+
+ wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+ if (unlikely(!wdev)) {
+ AP6210_ERR("Could not allocate wireless device\n");
+ free_netdev(net);
+ return -ENOMEM;
+ }
+
+ strncpy(net->name, "p2p%d", sizeof(net->name) - 1);
+ net->name[IFNAMSIZ - 1] = '\0';
+
+ /* Copy the reference to wl_priv */
+ memcpy((void *)netdev_priv(net), &wl, sizeof(struct wl_priv *));
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+ ASSERT(!net->open);
+ net->do_ioctl = wl_cfgp2p_do_ioctl;
+ net->hard_start_xmit = wl_cfgp2p_start_xmit;
+ net->open = wl_cfgp2p_if_open;
+ net->stop = wl_cfgp2p_if_stop;
+#else
+ ASSERT(!net->netdev_ops);
+ net->netdev_ops = &wl_cfgp2p_if_ops;
+#endif
+
+ /* Register with a dummy MAC addr */
+ memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN);
+
+ wdev->wiphy = wl->wdev->wiphy;
+
+ wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
+
+ net->ieee80211_ptr = wdev;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+ net->ethtool_ops = &cfgp2p_ethtool_ops;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */
+
+ SET_NETDEV_DEV(net, wiphy_dev(wdev->wiphy));
+
+ /* Associate p2p0 network interface with new wdev */
+ wdev->netdev = net;
+
+ ret = register_netdev(net);
+ if (ret) {
+ AP6210_ERR(" register_netdevice failed (%d)\n", ret);
+ free_netdev(net);
+ kfree(wdev);
+ return -ENODEV;
+ }
+
+ /* store p2p net ptr for further reference. Note that iflist won't have this
+ * entry as there corresponding firmware interface is a "Hidden" interface.
+ */
+ wl->p2p_wdev = wdev;
+ wl->p2p_net = net;
+
+ AP6210_DEBUG("%s: P2P Interface Registered\n", net->name);
+
+ return ret;
+}
+
+s32
+wl_cfgp2p_unregister_ndev(struct wl_priv *wl)
+{
+
+ if (!wl || !wl->p2p_net) {
+ AP6210_ERR("Invalid Ptr\n");
+ return -EINVAL;
+ }
+
+ unregister_netdev(wl->p2p_net);
+ free_netdev(wl->p2p_net);
+
+ return 0;
+}
+static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ if (skb)
+ {
+ AP6210_DEBUG("(%s) is not used for data operations.Droping the packet.\n",
+ ndev->name);
+ dev_kfree_skb_any(skb);
+ }
+
+ return 0;
+}
+
+static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd)
+{
+ int ret = 0;
+ struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net);
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+
+ /* There is no ifidx corresponding to p2p0 in our firmware. So we should
+ * not Handle any IOCTL cmds on p2p0 other than ANDROID PRIVATE CMDs.
+ * For Android PRIV CMD handling map it to primary I/F
+ */
+ if (cmd == SIOCDEVPRIVATE+1) {
+ ret = wl_android_priv_cmd(ndev, ifr, cmd);
+
+ } else {
+ AP6210_ERR("%s: IOCTL req 0x%x on p2p0 I/F. Ignoring. \n",
+ __FUNCTION__, cmd);
+ return -1;
+ }
+
+ return ret;
+}
+
+static int wl_cfgp2p_if_open(struct net_device *net)
+{
+ extern struct wl_priv *wlcfg_drv_priv;
+ struct wireless_dev *wdev = net->ieee80211_ptr;
+ struct wl_priv *wl = NULL;
+ wl = wlcfg_drv_priv;
+ if (!wdev || !wl || !wl->p2p)
+ return -EINVAL;
+ AP6210_DEBUG("Enter\n");
+ /* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now,
+ * do it here. This will make sure that in concurrent mode, supplicant
+ * is not dependent on a particular order of interface initialization.
+ * i.e you may give wpa_supp -iwlan0 -N -ip2p0 or wpa_supp -ip2p0 -N
+ * -iwlan0.
+ */
+ wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT)
+ | BIT(NL80211_IFTYPE_P2P_GO));
+ wl_cfg80211_do_driver_init(net);
+
+ return 0;
+}
+
+static int wl_cfgp2p_if_stop(struct net_device *net)
+{
+ extern struct wl_priv *wlcfg_drv_priv;
+ struct wl_priv *wl = NULL;
+ unsigned long flags;
+ struct wireless_dev *wdev = net->ieee80211_ptr;
+ int clear_flag = 0;
+ if (!wdev)
+ return -EINVAL;
+
+ AP6210_DEBUG("Enter\n");
+ wl = wlcfg_drv_priv;
+ if (!wl)
+ return -EINVAL;
+ spin_lock_irqsave(&wl->cfgdrv_lock, flags);
+ if (wl->scan_request && wl->scan_request->dev == net) {
+ cfg80211_scan_done(wl->scan_request, true);
+ wl->scan_request = NULL;
+ clear_flag = 1;
+ }
+ spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
+ if (clear_flag)
+ wl_clr_drv_status(wl, SCANNING, net);
+ wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes)
+ & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)|
+ BIT(NL80211_IFTYPE_P2P_GO)));
+ return 0;
+}
+
+bool wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops)
+{
+ return (if_ops == &wl_cfgp2p_if_ops);
+}
diff --git a/drivers/net/wireless/ap6210/wl_cfgp2p.h b/drivers/net/wireless/ap6210/wl_cfgp2p.h
new file mode 100644
index 0000000..d3552d6
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_cfgp2p.h
@@ -0,0 +1,311 @@
+/*
+ * Linux cfgp2p driver
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_cfgp2p.h 368091 2012-11-12 04:28:31Z $
+ */
+#ifndef _wl_cfgp2p_h_
+#define _wl_cfgp2p_h_
+#include <proto/802.11.h>
+#include <proto/p2p.h>
+
+struct wl_priv;
+extern u32 wl_dbg_level;
+
+typedef struct wifi_p2p_ie wifi_wfd_ie_t;
+/* Enumeration of the usages of the BSSCFGs used by the P2P Library. Do not
+ * confuse this with a bsscfg index. This value is an index into the
+ * saved_ie[] array of structures which in turn contains a bsscfg index field.
+ */
+typedef enum {
+ P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
+ P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
+ P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
+ P2PAPI_BSSCFG_MAX
+} p2p_bsscfg_type_t;
+
+/* vendor ies max buffer length for probe response or beacon */
+#define VNDR_IES_MAX_BUF_LEN 1400
+/* normal vendor ies buffer length */
+#define VNDR_IES_BUF_LEN 512
+
+/* Structure to hold all saved P2P and WPS IEs for a BSSCFG */
+struct p2p_saved_ie {
+ u8 p2p_probe_req_ie[VNDR_IES_BUF_LEN];
+ u8 p2p_probe_res_ie[VNDR_IES_MAX_BUF_LEN];
+ u8 p2p_assoc_req_ie[VNDR_IES_BUF_LEN];
+ u8 p2p_assoc_res_ie[VNDR_IES_BUF_LEN];
+ u8 p2p_beacon_ie[VNDR_IES_MAX_BUF_LEN];
+ u32 p2p_probe_req_ie_len;
+ u32 p2p_probe_res_ie_len;
+ u32 p2p_assoc_req_ie_len;
+ u32 p2p_assoc_res_ie_len;
+ u32 p2p_beacon_ie_len;
+};
+
+struct p2p_bss {
+ u32 bssidx;
+ struct net_device *dev;
+ struct p2p_saved_ie saved_ie;
+ void *private_data;
+};
+
+struct p2p_info {
+ bool on; /* p2p on/off switch */
+ bool scan;
+ bool vif_created;
+ s8 vir_ifname[IFNAMSIZ];
+ unsigned long status;
+ struct ether_addr dev_addr;
+ struct ether_addr int_addr;
+ struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
+ struct timer_list listen_timer;
+ wl_p2p_sched_t noa;
+ wl_p2p_ops_t ops;
+ wlc_ssid_t ssid;
+};
+
+#define MAX_VNDR_IE_NUMBER 5
+
+struct parsed_vndr_ie_info {
+ char *ie_ptr;
+ u32 ie_len; /* total length including id & length field */
+ vndr_ie_t vndrie;
+};
+
+struct parsed_vndr_ies {
+ u32 count;
+ struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
+};
+
+/* dongle status */
+enum wl_cfgp2p_status {
+ WLP2P_STATUS_DISCOVERY_ON = 0,
+ WLP2P_STATUS_SEARCH_ENABLED,
+ WLP2P_STATUS_IF_ADD,
+ WLP2P_STATUS_IF_DEL,
+ WLP2P_STATUS_IF_DELETING,
+ WLP2P_STATUS_IF_CHANGING,
+ WLP2P_STATUS_IF_CHANGED,
+ WLP2P_STATUS_LISTEN_EXPIRED,
+ WLP2P_STATUS_ACTION_TX_COMPLETED,
+ WLP2P_STATUS_ACTION_TX_NOACK,
+ WLP2P_STATUS_SCANNING,
+ WLP2P_STATUS_GO_NEG_PHASE,
+ WLP2P_STATUS_DISC_IN_PROGRESS
+};
+
+
+#define wl_to_p2p_bss_ndev(wl, type) ((wl)->p2p->bss_idx[type].dev)
+#define wl_to_p2p_bss_bssidx(wl, type) ((wl)->p2p->bss_idx[type].bssidx)
+#define wl_to_p2p_bss_saved_ie(wl, type) ((wl)->p2p->bss_idx[type].saved_ie)
+#define wl_to_p2p_bss_private(wl, type) ((wl)->p2p->bss_idx[type].private_data)
+#define wl_to_p2p_bss(wl, type) ((wl)->p2p->bss_idx[type])
+#define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : test_bit(WLP2P_STATUS_ ## stat, \
+ &(wl)->p2p->status))
+#define wl_set_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : set_bit(WLP2P_STATUS_ ## stat, \
+ &(wl)->p2p->status))
+#define wl_clr_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : clear_bit(WLP2P_STATUS_ ## stat, \
+ &(wl)->p2p->status))
+#define wl_chg_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0:change_bit(WLP2P_STATUS_ ## stat, \
+ &(wl)->p2p->status))
+#define p2p_on(wl) ((wl)->p2p->on)
+#define p2p_scan(wl) ((wl)->p2p->scan)
+#define p2p_is_on(wl) ((wl)->p2p && (wl)->p2p->on)
+
+/* dword align allocation */
+#define WLC_IOCTL_MAXLEN 8192
+
+#define INIT_TIMER(timer, func, duration, extra_delay) \
+ do { \
+ init_timer(timer); \
+ timer->function = func; \
+ timer->expires = jiffies + msecs_to_jiffies(duration + extra_delay); \
+ timer->data = (unsigned long) wl; \
+ add_timer(timer); \
+ } while (0);
+extern void
+wl_cfgp2p_listen_expired(unsigned long data);
+extern bool
+wl_cfgp2p_is_pub_action(void *frame, u32 frame_len);
+extern bool
+wl_cfgp2p_is_p2p_action(void *frame, u32 frame_len);
+extern bool
+wl_cfgp2p_is_gas_action(void *frame, u32 frame_len);
+extern void
+wl_cfgp2p_print_actframe(bool tx, void *frame, u32 frame_len);
+extern s32
+wl_cfgp2p_init_priv(struct wl_priv *wl);
+extern void
+wl_cfgp2p_deinit_priv(struct wl_priv *wl);
+extern s32
+wl_cfgp2p_set_firm_p2p(struct wl_priv *wl);
+extern s32
+wl_cfgp2p_set_p2p_mode(struct wl_priv *wl, u8 mode,
+ u32 channel, u16 listen_ms, int bssidx);
+extern s32
+wl_cfgp2p_ifadd(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
+ chanspec_t chspec);
+extern s32
+wl_cfgp2p_ifdisable(struct wl_priv *wl, struct ether_addr *mac);
+extern s32
+wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac);
+extern s32
+wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type, chanspec_t chspec);
+
+extern s32
+wl_cfgp2p_ifidx(struct wl_priv *wl, struct ether_addr *mac, s32 *index);
+
+extern s32
+wl_cfgp2p_init_discovery(struct wl_priv *wl);
+extern s32
+wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8 *ie, u32 ie_len);
+extern s32
+wl_cfgp2p_disable_discovery(struct wl_priv *wl);
+extern s32
+wl_cfgp2p_escan(struct wl_priv *wl, struct net_device *dev, u16 active, u32 num_chans,
+ u16 *channels,
+ s32 search_state, u16 action, u32 bssidx);
+
+extern s32
+wl_cfgp2p_act_frm_search(struct wl_priv *wl, struct net_device *ndev,
+ s32 bssidx, s32 channel);
+
+extern wpa_ie_fixed_t *
+wl_cfgp2p_find_wpaie(u8 *parse, u32 len);
+
+extern wpa_ie_fixed_t *
+wl_cfgp2p_find_wpsie(u8 *parse, u32 len);
+
+extern wifi_p2p_ie_t *
+wl_cfgp2p_find_p2pie(u8 *parse, u32 len);
+
+extern wifi_wfd_ie_t *
+wl_cfgp2p_find_wfdie(u8 *parse, u32 len);
+extern s32
+wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
+ s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len);
+extern s32
+wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx);
+
+extern s32
+wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev);
+extern struct net_device *
+wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx);
+
+
+extern s32
+wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+extern s32
+wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms);
+
+extern s32
+wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable);
+
+extern s32
+wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
+ const wl_event_msg_t *e, void *data);
+extern s32
+wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
+ wl_af_params_t *af_params, s32 bssidx);
+
+extern void
+wl_cfgp2p_generate_bss_mac(struct ether_addr *primary_addr, struct ether_addr *out_dev_addr,
+ struct ether_addr *out_int_addr);
+
+extern void
+wl_cfg80211_change_ifaddr(u8* buf, struct ether_addr *p2p_int_addr, u8 element_id);
+extern bool
+wl_cfgp2p_bss_isup(struct net_device *ndev, int bsscfg_idx);
+
+extern s32
+wl_cfgp2p_bss(struct wl_priv *wl, struct net_device *ndev, s32 bsscfg_idx, s32 up);
+
+
+extern s32
+wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev);
+
+extern s32
+wl_cfgp2p_down(struct wl_priv *wl);
+
+extern s32
+wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len);
+
+extern s32
+wl_cfgp2p_get_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf, int len);
+
+extern s32
+wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf, int len);
+
+extern u8 *
+wl_cfgp2p_retreive_p2pattrib(void *buf, u8 element_id);
+
+extern u8 *
+wl_cfgp2p_retreive_p2p_dev_addr(wl_bss_info_t *bi, u32 bi_length);
+
+extern s32
+wl_cfgp2p_register_ndev(struct wl_priv *wl);
+
+extern s32
+wl_cfgp2p_unregister_ndev(struct wl_priv *wl);
+
+extern bool
+wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops);
+
+/* WiFi Direct */
+#define SOCIAL_CHAN_1 1
+#define SOCIAL_CHAN_2 6
+#define SOCIAL_CHAN_3 11
+#define IS_P2P_SOCIAL_CHANNEL(channel) ((channel == SOCIAL_CHAN_1) || \
+ (channel == SOCIAL_CHAN_2) || \
+ (channel == SOCIAL_CHAN_3))
+#define SOCIAL_CHAN_CNT 3
+#define AF_PEER_SEARCH_CNT 2
+#define WL_P2P_WILDCARD_SSID "DIRECT-"
+#define WL_P2P_WILDCARD_SSID_LEN 7
+#define WL_P2P_INTERFACE_PREFIX "p2p"
+#define WL_P2P_TEMP_CHAN 11
+
+/* If the provision discovery is for JOIN operations,
+ * then we need not do an internal scan to find GO.
+ */
+#define IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len) \
+ (wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID) == NULL)
+
+#define IS_GAS_REQ(frame, len) (wl_cfgp2p_is_gas_action(frame, len) && \
+ ((frame->action == P2PSD_ACTION_ID_GAS_IREQ) || \
+ (frame->action == P2PSD_ACTION_ID_GAS_CREQ)))
+#define IS_P2P_PUB_ACT_REQ(frame, p2p_ie, len) \
+ (wl_cfgp2p_is_pub_action(frame, len) && \
+ ((frame->subtype == P2P_PAF_GON_REQ) || \
+ (frame->subtype == P2P_PAF_INVITE_REQ) || \
+ ((frame->subtype == P2P_PAF_PROVDIS_REQ) && \
+ IS_PROV_DISC_WITHOUT_GROUP_ID(p2p_ie, len))))
+#define IS_P2P_PUB_ACT_RSP_SUBTYPE(subtype) ((subtype == P2P_PAF_GON_RSP) || \
+ ((subtype == P2P_PAF_GON_CONF) || \
+ (subtype == P2P_PAF_INVITE_RSP) || \
+ (subtype == P2P_PAF_PROVDIS_RSP)))
+#define IS_P2P_SOCIAL(ch) ((ch == SOCIAL_CHAN_1) || (ch == SOCIAL_CHAN_2) || (ch == SOCIAL_CHAN_3))
+#define IS_P2P_SSID(ssid, len) (!memcmp(ssid, WL_P2P_WILDCARD_SSID, WL_P2P_WILDCARD_SSID_LEN) && \
+ (len == WL_P2P_WILDCARD_SSID_LEN))
+#endif /* _wl_cfgp2p_h_ */
diff --git a/drivers/net/wireless/ap6210/wl_iw.c b/drivers/net/wireless/ap6210/wl_iw.c
new file mode 100644
index 0000000..8e067f4
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_iw.c
@@ -0,0 +1,3622 @@
+/*
+ * Linux Wireless Extensions support
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_iw.c 352251 2012-08-22 06:08:38Z $
+ */
+
+#if defined(USE_IW)
+#define LINUX_PORT
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <proto/ethernet.h>
+
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+
+
+typedef const struct si_pub si_t;
+#include <wlioctl.h>
+
+
+#include <wl_iw.h>
+
+#include <ap6210.h>
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+#include <linux/rtnetlink.h>
+#endif
+#if defined(SOFTAP)
+struct net_device *ap_net_dev = NULL;
+tsk_ctl_t ap_eth_ctl; /* apsta AP netdev waiter thread */
+#endif /* SOFTAP */
+
+extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status,
+ uint32 reason, char* stringBuf, uint buflen);
+
+uint iw_msg_level = WL_ERROR_VAL;
+
+#define MAX_WLIW_IOCTL_LEN 1024
+
+/* IOCTL swapping mode for Big Endian host with Little Endian dongle. Default to off */
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+
+extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev);
+extern int dhd_wait_pend8021x(struct net_device *dev);
+
+#if WIRELESS_EXT < 19
+#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
+#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST)
+#endif /* WIRELESS_EXT < 19 */
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define DAEMONIZE(a) daemonize(a); \
+ allow_signal(SIGKILL); \
+ allow_signal(SIGTERM);
+#else /* Linux 2.4 (w/o preemption patch) */
+#define RAISE_RX_SOFTIRQ() \
+ cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ)
+#define DAEMONIZE(a) daemonize(); \
+ do { if (a) \
+ strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \
+ } while (0);
+#endif /* LINUX_VERSION_CODE */
+
+#define ISCAN_STATE_IDLE 0
+#define ISCAN_STATE_SCANING 1
+
+/* the buf lengh can be WLC_IOCTL_MAXLEN (8K) to reduce iteration */
+#define WLC_IW_ISCAN_MAXLEN 2048
+typedef struct iscan_buf {
+ struct iscan_buf * next;
+ char iscan_buf[WLC_IW_ISCAN_MAXLEN];
+} iscan_buf_t;
+
+typedef struct iscan_info {
+ struct net_device *dev;
+ struct timer_list timer;
+ uint32 timer_ms;
+ uint32 timer_on;
+ int iscan_state;
+ iscan_buf_t * list_hdr;
+ iscan_buf_t * list_cur;
+
+ /* Thread to work on iscan */
+ long sysioc_pid;
+ struct semaphore sysioc_sem;
+ struct completion sysioc_exited;
+
+
+ char ioctlbuf[WLC_IOCTL_SMLEN];
+} iscan_info_t;
+iscan_info_t *g_iscan = NULL;
+static void wl_iw_timerfunc(ulong data);
+static void wl_iw_set_event_mask(struct net_device *dev);
+static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action);
+
+/* priv_link becomes netdev->priv and is the link between netdev and wlif struct */
+typedef struct priv_link {
+ wl_iw_t *wliw;
+} priv_link_t;
+
+/* dev to priv_link */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
+#define WL_DEV_LINK(dev) (priv_link_t*)(dev->priv)
+#else
+#define WL_DEV_LINK(dev) (priv_link_t*)netdev_priv(dev)
+#endif
+
+/* dev to wl_iw_t */
+#define IW_DEV_IF(dev) ((wl_iw_t*)(WL_DEV_LINK(dev))->wliw)
+
+static void swap_key_from_BE(
+ wl_wsec_key_t *key
+)
+{
+ key->index = htod32(key->index);
+ key->len = htod32(key->len);
+ key->algo = htod32(key->algo);
+ key->flags = htod32(key->flags);
+ key->rxiv.hi = htod32(key->rxiv.hi);
+ key->rxiv.lo = htod16(key->rxiv.lo);
+ key->iv_initialized = htod32(key->iv_initialized);
+}
+
+static void swap_key_to_BE(
+ wl_wsec_key_t *key
+)
+{
+ key->index = dtoh32(key->index);
+ key->len = dtoh32(key->len);
+ key->algo = dtoh32(key->algo);
+ key->flags = dtoh32(key->flags);
+ key->rxiv.hi = dtoh32(key->rxiv.hi);
+ key->rxiv.lo = dtoh16(key->rxiv.lo);
+ key->iv_initialized = dtoh32(key->iv_initialized);
+}
+
+static int
+dev_wlc_ioctl(
+ struct net_device *dev,
+ int cmd,
+ void *arg,
+ int len
+)
+{
+ struct ifreq ifr;
+ wl_ioctl_t ioc;
+ mm_segment_t fs;
+ int ret;
+
+ memset(&ioc, 0, sizeof(ioc));
+ ioc.cmd = cmd;
+ ioc.buf = arg;
+ ioc.len = len;
+
+ strcpy(ifr.ifr_name, dev->name);
+ ifr.ifr_data = (caddr_t) &ioc;
+
+#ifndef LINUX_HYBRID
+ /* Causes an extraneous 'up'. If specific ioctls are failing due
+ to device down, then we can investigate those ioctls.
+ */
+ dev_open(dev);
+#endif
+
+ fs = get_fs();
+ set_fs(get_ds());
+#if defined(WL_USE_NETDEV_OPS)
+ ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+#else
+ ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+#endif
+ set_fs(fs);
+
+ return ret;
+}
+
+/*
+set named driver variable to int value and return error indication
+calling example: dev_wlc_intvar_set(dev, "arate", rate)
+*/
+
+static int
+dev_wlc_intvar_set(
+ struct net_device *dev,
+ char *name,
+ int val)
+{
+ char buf[WLC_IOCTL_SMLEN];
+ uint len;
+
+ val = htod32(val);
+ len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
+ ASSERT(len);
+
+ return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len));
+}
+
+static int
+dev_iw_iovar_setbuf(
+ struct net_device *dev,
+ char *iovar,
+ void *param,
+ int paramlen,
+ void *bufptr,
+ int buflen)
+{
+ int iolen;
+
+ iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+ ASSERT(iolen);
+ BCM_REFERENCE(iolen);
+
+ return (dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen));
+}
+
+static int
+dev_iw_iovar_getbuf(
+ struct net_device *dev,
+ char *iovar,
+ void *param,
+ int paramlen,
+ void *bufptr,
+ int buflen)
+{
+ int iolen;
+
+ iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+ ASSERT(iolen);
+ BCM_REFERENCE(iolen);
+
+ return (dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen));
+}
+
+#if WIRELESS_EXT > 17
+static int
+dev_wlc_bufvar_set(
+ struct net_device *dev,
+ char *name,
+ char *buf, int len)
+{
+ char *ioctlbuf;
+ uint buflen;
+ int error;
+
+ ioctlbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL);
+ if (!ioctlbuf)
+ return -ENOMEM;
+
+ buflen = bcm_mkiovar(name, buf, len, ioctlbuf, MAX_WLIW_IOCTL_LEN);
+ ASSERT(buflen);
+ error = dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen);
+
+ kfree(ioctlbuf);
+ return error;
+}
+#endif /* WIRELESS_EXT > 17 */
+
+/*
+get named driver variable to int value and return error indication
+calling example: dev_wlc_bufvar_get(dev, "arate", &rate)
+*/
+
+static int
+dev_wlc_bufvar_get(
+ struct net_device *dev,
+ char *name,
+ char *buf, int buflen)
+{
+ char *ioctlbuf;
+ int error;
+
+ uint len;
+
+ ioctlbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL);
+ if (!ioctlbuf)
+ return -ENOMEM;
+ len = bcm_mkiovar(name, NULL, 0, ioctlbuf, MAX_WLIW_IOCTL_LEN);
+ ASSERT(len);
+ BCM_REFERENCE(len);
+ error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN);
+ if (!error)
+ bcopy(ioctlbuf, buf, buflen);
+
+ kfree(ioctlbuf);
+ return (error);
+}
+
+/*
+get named driver variable to int value and return error indication
+calling example: dev_wlc_intvar_get(dev, "arate", &rate)
+*/
+
+static int
+dev_wlc_intvar_get(
+ struct net_device *dev,
+ char *name,
+ int *retval)
+{
+ union {
+ char buf[WLC_IOCTL_SMLEN];
+ int val;
+ } var;
+ int error;
+
+ uint len;
+ uint data_null;
+
+ len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf));
+ ASSERT(len);
+ error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len);
+
+ *retval = dtoh32(var.val);
+
+ return (error);
+}
+
+/* Maintain backward compatibility */
+#if WIRELESS_EXT < 13
+struct iw_request_info
+{
+ __u16 cmd; /* Wireless Extension command */
+ __u16 flags; /* More to come ;-) */
+};
+
+typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
+ void *wrqu, char *extra);
+#endif /* WIRELESS_EXT < 13 */
+
+#if WIRELESS_EXT > 12
+static int
+wl_iw_set_leddc(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ int dc = *(int *)extra;
+ int error;
+
+ error = dev_wlc_intvar_set(dev, "leddc", dc);
+ return error;
+}
+
+static int
+wl_iw_set_vlanmode(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ int mode = *(int *)extra;
+ int error;
+
+ mode = htod32(mode);
+ error = dev_wlc_intvar_set(dev, "vlan_mode", mode);
+ return error;
+}
+
+static int
+wl_iw_set_pm(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ int pm = *(int *)extra;
+ int error;
+
+ pm = htod32(pm);
+ error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+ return error;
+}
+#endif /* WIRELESS_EXT > 12 */
+
+int
+wl_iw_send_priv_event(
+ struct net_device *dev,
+ char *flag
+)
+{
+ union iwreq_data wrqu;
+ char extra[IW_CUSTOM_MAX + 1];
+ int cmd;
+
+ cmd = IWEVCUSTOM;
+ memset(&wrqu, 0, sizeof(wrqu));
+ if (strlen(flag) > sizeof(extra))
+ return -1;
+
+ strcpy(extra, flag);
+ wrqu.data.length = strlen(extra);
+ wireless_send_event(dev, cmd, &wrqu, extra);
+ AP6210_DEBUG("Send IWEVCUSTOM Event as %s\n", extra);
+
+ return 0;
+}
+
+static int
+wl_iw_config_commit(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ void *zwrq,
+ char *extra
+)
+{
+ wlc_ssid_t ssid;
+ int error;
+ struct sockaddr bssid;
+
+ AP6210_DEBUG("%s: SIOCSIWCOMMIT\n", dev->name);
+
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid))))
+ return error;
+
+ ssid.SSID_len = dtoh32(ssid.SSID_len);
+
+ if (!ssid.SSID_len)
+ return 0;
+
+ bzero(&bssid, sizeof(struct sockaddr));
+ if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) {
+ AP6210_ERR("%s: WLC_REASSOC failed (%d)\n", __FUNCTION__, error);
+ return error;
+ }
+
+ return 0;
+}
+
+static int
+wl_iw_get_name(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *cwrq,
+ char *extra
+)
+{
+ int phytype, err;
+ uint band[3];
+ char cap[5];
+
+ AP6210_DEBUG("%s: SIOCGIWNAME\n", dev->name);
+
+ cap[0] = 0;
+ if ((err = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype))) < 0)
+ goto done;
+ if ((err = dev_wlc_ioctl(dev, WLC_GET_BANDLIST, band, sizeof(band))) < 0)
+ goto done;
+
+ band[0] = dtoh32(band[0]);
+ switch (phytype) {
+ case WLC_PHY_TYPE_A:
+ strcpy(cap, "a");
+ break;
+ case WLC_PHY_TYPE_B:
+ strcpy(cap, "b");
+ break;
+ case WLC_PHY_TYPE_LP:
+ case WLC_PHY_TYPE_G:
+ if (band[0] >= 2)
+ strcpy(cap, "abg");
+ else
+ strcpy(cap, "bg");
+ break;
+ case WLC_PHY_TYPE_N:
+ if (band[0] >= 2)
+ strcpy(cap, "abgn");
+ else
+ strcpy(cap, "bgn");
+ break;
+ }
+done:
+ snprintf(cwrq->name, IFNAMSIZ, "IEEE 802.11%s", cap);
+ return 0;
+}
+
+static int
+wl_iw_set_freq(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *fwrq,
+ char *extra
+)
+{
+ int error, chan;
+ uint sf = 0;
+
+ AP6210_DEBUG("%s: SIOCSIWFREQ\n", dev->name);
+
+ /* Setting by channel number */
+ if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) {
+ chan = fwrq->m;
+ }
+
+ /* Setting by frequency */
+ else {
+ /* Convert to MHz as best we can */
+ if (fwrq->e >= 6) {
+ fwrq->e -= 6;
+ while (fwrq->e--)
+ fwrq->m *= 10;
+ } else if (fwrq->e < 6) {
+ while (fwrq->e++ < 6)
+ fwrq->m /= 10;
+ }
+ /* handle 4.9GHz frequencies as Japan 4 GHz based channelization */
+ if (fwrq->m > 4000 && fwrq->m < 5000)
+ sf = WF_CHAN_FACTOR_4_G; /* start factor for 4 GHz */
+
+ chan = wf_mhz2channel(fwrq->m, sf);
+ }
+ chan = htod32(chan);
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan))))
+ return error;
+
+ /* -EINPROGRESS: Call commit handler */
+ return -EINPROGRESS;
+}
+
+static int
+wl_iw_get_freq(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *fwrq,
+ char *extra
+)
+{
+ channel_info_t ci;
+ int error;
+
+ AP6210_DEBUG("%s: SIOCGIWFREQ\n", dev->name);
+
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci))))
+ return error;
+
+ /* Return radio channel in channel form */
+ fwrq->m = dtoh32(ci.hw_channel);
+ fwrq->e = dtoh32(0);
+ return 0;
+}
+
+static int
+wl_iw_set_mode(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ __u32 *uwrq,
+ char *extra
+)
+{
+ int infra = 0, ap = 0, error = 0;
+
+ AP6210_DEBUG("%s: SIOCSIWMODE\n", dev->name);
+
+ switch (*uwrq) {
+ case IW_MODE_MASTER:
+ infra = ap = 1;
+ break;
+ case IW_MODE_ADHOC:
+ case IW_MODE_AUTO:
+ break;
+ case IW_MODE_INFRA:
+ infra = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ infra = htod32(infra);
+ ap = htod32(ap);
+
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) ||
+ (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap))))
+ return error;
+
+ /* -EINPROGRESS: Call commit handler */
+ return -EINPROGRESS;
+}
+
+static int
+wl_iw_get_mode(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ __u32 *uwrq,
+ char *extra
+)
+{
+ int error, infra = 0, ap = 0;
+
+ AP6210_DEBUG("%s: SIOCGIWMODE\n", dev->name);
+
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) ||
+ (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap))))
+ return error;
+
+ infra = dtoh32(infra);
+ ap = dtoh32(ap);
+ *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC;
+
+ return 0;
+}
+
+static int
+wl_iw_get_range(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ struct iw_range *range = (struct iw_range *) extra;
+ static int channels[MAXCHANNEL+1];
+ wl_uint32_list_t *list = (wl_uint32_list_t *) channels;
+ wl_rateset_t rateset;
+ int error, i, k;
+ uint sf, ch;
+
+ int phytype;
+ int bw_cap = 0, sgi_tx = 0, nmode = 0;
+ channel_info_t ci;
+ uint8 nrate_list2copy = 0;
+ uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130},
+ {14, 29, 43, 58, 87, 116, 130, 144},
+ {27, 54, 81, 108, 162, 216, 243, 270},
+ {30, 60, 90, 120, 180, 240, 270, 300}};
+
+ AP6210_DEBUG("%s: SIOCGIWRANGE\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ dwrq->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(*range));
+
+ /* We don't use nwids */
+ range->min_nwid = range->max_nwid = 0;
+
+ /* Set available channels/frequencies */
+ list->count = htod32(MAXCHANNEL);
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, sizeof(channels))))
+ return error;
+ for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) {
+ range->freq[i].i = dtoh32(list->element[i]);
+
+ ch = dtoh32(list->element[i]);
+ if (ch <= CH_MAX_2G_CHANNEL)
+ sf = WF_CHAN_FACTOR_2_4_G;
+ else
+ sf = WF_CHAN_FACTOR_5_G;
+
+ range->freq[i].m = wf_channel2mhz(ch, sf);
+ range->freq[i].e = 6;
+ }
+ range->num_frequency = range->num_channels = i;
+
+ /* Link quality (use NDIS cutoffs) */
+ range->max_qual.qual = 5;
+ /* Signal level (use RSSI) */
+ range->max_qual.level = 0x100 - 200; /* -200 dBm */
+ /* Noise level (use noise) */
+ range->max_qual.noise = 0x100 - 200; /* -200 dBm */
+ /* Signal level threshold range (?) */
+ range->sensitivity = 65535;
+
+#if WIRELESS_EXT > 11
+ /* Link quality (use NDIS cutoffs) */
+ range->avg_qual.qual = 3;
+ /* Signal level (use RSSI) */
+ range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD;
+ /* Noise level (use noise) */
+ range->avg_qual.noise = 0x100 - 75; /* -75 dBm */
+#endif /* WIRELESS_EXT > 11 */
+
+ /* Set available bitrates */
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset))))
+ return error;
+ rateset.count = dtoh32(rateset.count);
+ range->num_bitrates = rateset.count;
+ for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++)
+ range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; /* convert to bps */
+ dev_wlc_intvar_get(dev, "nmode", &nmode);
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype))))
+ return error;
+
+ if (nmode == 1 && ((phytype == WLC_PHY_TYPE_SSN) || (phytype == WLC_PHY_TYPE_LCN) ||
+ (phytype == WLC_PHY_TYPE_LCN40))) {
+ dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap);
+ dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx);
+ dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t));
+ ci.hw_channel = dtoh32(ci.hw_channel);
+
+ if (bw_cap == 0 ||
+ (bw_cap == 2 && ci.hw_channel <= 14)) {
+ if (sgi_tx == 0)
+ nrate_list2copy = 0;
+ else
+ nrate_list2copy = 1;
+ }
+ if (bw_cap == 1 ||
+ (bw_cap == 2 && ci.hw_channel >= 36)) {
+ if (sgi_tx == 0)
+ nrate_list2copy = 2;
+ else
+ nrate_list2copy = 3;
+ }
+ range->num_bitrates += 8;
+ for (k = 0; i < range->num_bitrates; k++, i++) {
+ /* convert to bps */
+ range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000;
+ }
+ }
+
+ /* Set an indication of the max TCP throughput
+ * in bit/s that we can expect using this interface.
+ * May be use for QoS stuff... Jean II
+ */
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i))))
+ return error;
+ i = dtoh32(i);
+ if (i == WLC_PHY_TYPE_A)
+ range->throughput = 24000000; /* 24 Mbits/s */
+ else
+ range->throughput = 1500000; /* 1.5 Mbits/s */
+
+ /* RTS and fragmentation thresholds */
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+
+ range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS;
+ range->num_encoding_sizes = 4;
+ range->encoding_size[0] = WEP1_KEY_SIZE;
+ range->encoding_size[1] = WEP128_KEY_SIZE;
+#if WIRELESS_EXT > 17
+ range->encoding_size[2] = TKIP_KEY_SIZE;
+#else
+ range->encoding_size[2] = 0;
+#endif
+ range->encoding_size[3] = AES_KEY_SIZE;
+
+ /* Do not support power micro-management */
+ range->min_pmp = 0;
+ range->max_pmp = 0;
+ range->min_pmt = 0;
+ range->max_pmt = 0;
+ range->pmp_flags = 0;
+ range->pm_capa = 0;
+
+ /* Transmit Power - values are in mW */
+ range->num_txpower = 2;
+ range->txpower[0] = 1;
+ range->txpower[1] = 255;
+ range->txpower_capa = IW_TXPOW_MWATT;
+
+#if WIRELESS_EXT > 10
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 19;
+
+ /* Only support retry limits */
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->r_time_flags = 0;
+ /* SRL and LRL limits */
+ range->min_retry = 1;
+ range->max_retry = 255;
+ /* Retry lifetime limits unsupported */
+ range->min_r_time = 0;
+ range->max_r_time = 0;
+#endif /* WIRELESS_EXT > 10 */
+
+#if WIRELESS_EXT > 17
+ range->enc_capa = IW_ENC_CAPA_WPA;
+ range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;
+ range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
+ range->enc_capa |= IW_ENC_CAPA_WPA2;
+#if (defined(BCMSUP_PSK) && defined(WLFBT))
+ /* Tell the host (e.g. wpa_supplicant) to let us do the handshake */
+ range->enc_capa |= IW_ENC_CAPA_4WAY_HANDSHAKE;
+#endif /* (defined (BCMSUP_PSK) && defined(WLFBT)) */
+
+ /* Event capability (kernel) */
+ IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+ /* Event capability (driver) */
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCREQIE);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVASSOCRESPIE);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND);
+
+#if WIRELESS_EXT >= 22 && defined(IW_SCAN_CAPA_ESSID)
+ /* FC7 wireless.h defines EXT 22 but doesn't define scan_capa bits */
+ range->scan_capa = IW_SCAN_CAPA_ESSID;
+#endif
+#endif /* WIRELESS_EXT > 17 */
+
+ return 0;
+}
+
+static int
+rssi_to_qual(int rssi)
+{
+ if (rssi <= WL_IW_RSSI_NO_SIGNAL)
+ return 0;
+ else if (rssi <= WL_IW_RSSI_VERY_LOW)
+ return 1;
+ else if (rssi <= WL_IW_RSSI_LOW)
+ return 2;
+ else if (rssi <= WL_IW_RSSI_GOOD)
+ return 3;
+ else if (rssi <= WL_IW_RSSI_VERY_GOOD)
+ return 4;
+ else
+ return 5;
+}
+
+static int
+wl_iw_set_spy(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_iw_t *iw = IW_DEV_IF(dev);
+ struct sockaddr *addr = (struct sockaddr *) extra;
+ int i;
+
+ AP6210_DEBUG("%s: SIOCSIWSPY\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ iw->spy_num = MIN(ARRAYSIZE(iw->spy_addr), dwrq->length);
+ for (i = 0; i < iw->spy_num; i++)
+ memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN);
+ memset(iw->spy_qual, 0, sizeof(iw->spy_qual));
+
+ return 0;
+}
+
+static int
+wl_iw_get_spy(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_iw_t *iw = IW_DEV_IF(dev);
+ struct sockaddr *addr = (struct sockaddr *) extra;
+ struct iw_quality *qual = (struct iw_quality *) &addr[iw->spy_num];
+ int i;
+
+ AP6210_DEBUG("%s: SIOCGIWSPY\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ dwrq->length = iw->spy_num;
+ for (i = 0; i < iw->spy_num; i++) {
+ memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN);
+ addr[i].sa_family = AF_UNIX;
+ memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality));
+ iw->spy_qual[i].updated = 0;
+ }
+
+ return 0;
+}
+
+static int
+wl_iw_set_wap(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *awrq,
+ char *extra
+)
+{
+ int error = -EINVAL;
+
+ AP6210_DEBUG("%s: SIOCSIWAP\n", dev->name);
+
+ if (awrq->sa_family != ARPHRD_ETHER) {
+ AP6210_ERR("%s: Invalid Header...sa_family\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ /* Ignore "auto" or "off" */
+ if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) {
+ scb_val_t scbval;
+ bzero(&scbval, sizeof(scb_val_t));
+ if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) {
+ AP6210_ERR("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error);
+ }
+ return 0;
+ }
+ /* WL_ASSOC(("Assoc to %s\n", bcm_ether_ntoa((struct ether_addr *)&(awrq->sa_data),
+ * eabuf)));
+ */
+ /* Reassociate to the specified AP */
+ if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, awrq->sa_data, ETHER_ADDR_LEN))) {
+ AP6210_ERR("%s: WLC_REASSOC failed (%d).\n", __FUNCTION__, error);
+ return error;
+ }
+
+ return 0;
+}
+
+static int
+wl_iw_get_wap(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *awrq,
+ char *extra
+)
+{
+ AP6210_DEBUG("%s: SIOCGIWAP\n", dev->name);
+
+ awrq->sa_family = ARPHRD_ETHER;
+ memset(awrq->sa_data, 0, ETHER_ADDR_LEN);
+
+ /* Ignore error (may be down or disassociated) */
+ (void) dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN);
+
+ return 0;
+}
+
+#if WIRELESS_EXT > 17
+static int
+wl_iw_mlme(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *awrq,
+ char *extra
+)
+{
+ struct iw_mlme *mlme;
+ scb_val_t scbval;
+ int error = -EINVAL;
+
+ AP6210_DEBUG("%s: SIOCSIWMLME\n", dev->name);
+
+ mlme = (struct iw_mlme *)extra;
+ if (mlme == NULL) {
+ AP6210_ERR("Invalid ioctl data.\n");
+ return error;
+ }
+
+ scbval.val = mlme->reason_code;
+ bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN);
+
+ if (mlme->cmd == IW_MLME_DISASSOC) {
+ scbval.val = htod32(scbval.val);
+ error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t));
+ }
+ else if (mlme->cmd == IW_MLME_DEAUTH) {
+ scbval.val = htod32(scbval.val);
+ error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval,
+ sizeof(scb_val_t));
+ }
+ else {
+ AP6210_ERR("%s: Invalid ioctl data.\n", __FUNCTION__);
+ return error;
+ }
+
+ return error;
+}
+#endif /* WIRELESS_EXT > 17 */
+
+static int
+wl_iw_get_aplist(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_scan_results_t *list;
+ struct sockaddr *addr = (struct sockaddr *) extra;
+ struct iw_quality qual[IW_MAX_AP];
+ wl_bss_info_t *bi = NULL;
+ int error, i;
+ uint buflen = dwrq->length;
+
+ AP6210_DEBUG("%s: SIOCGIWAPLIST\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ /* Get scan results (too large to put on the stack) */
+ list = kmalloc(buflen, GFP_KERNEL);
+ if (!list)
+ return -ENOMEM;
+ memset(list, 0, buflen);
+ list->buflen = htod32(buflen);
+ if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) {
+ AP6210_ERR("%d: Scan results error %d\n", __LINE__, error);
+ kfree(list);
+ return error;
+ }
+ list->buflen = dtoh32(list->buflen);
+ list->version = dtoh32(list->version);
+ list->count = dtoh32(list->count);
+ ASSERT(list->version == WL_BSS_INFO_VERSION);
+
+ for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) {
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info;
+ ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
+ buflen));
+
+ /* Infrastructure only */
+ if (!(dtoh16(bi->capability) & DOT11_CAP_ESS))
+ continue;
+
+ /* BSSID */
+ memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN);
+ addr[dwrq->length].sa_family = ARPHRD_ETHER;
+ qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI));
+ qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI);
+ qual[dwrq->length].noise = 0x100 + bi->phy_noise;
+
+ /* Updated qual, level, and noise */
+#if WIRELESS_EXT > 18
+ qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+#else
+ qual[dwrq->length].updated = 7;
+#endif /* WIRELESS_EXT > 18 */
+
+ dwrq->length++;
+ }
+
+ kfree(list);
+
+ if (dwrq->length) {
+ memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length);
+ /* Provided qual */
+ dwrq->flags = 1;
+ }
+
+ return 0;
+}
+
+static int
+wl_iw_iscan_get_aplist(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_scan_results_t *list;
+ iscan_buf_t * buf;
+ iscan_info_t *iscan = g_iscan;
+
+ struct sockaddr *addr = (struct sockaddr *) extra;
+ struct iw_quality qual[IW_MAX_AP];
+ wl_bss_info_t *bi = NULL;
+ int i;
+
+ AP6210_DEBUG("%s: SIOCGIWAPLIST\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ if ((!iscan) || (iscan->sysioc_pid < 0)) {
+ return wl_iw_get_aplist(dev, info, dwrq, extra);
+ }
+
+ buf = iscan->list_hdr;
+ /* Get scan results (too large to put on the stack) */
+ while (buf) {
+ list = &((wl_iscan_results_t*)buf->iscan_buf)->results;
+ ASSERT(list->version == WL_BSS_INFO_VERSION);
+
+ bi = NULL;
+ for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) {
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info;
+ ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
+ WLC_IW_ISCAN_MAXLEN));
+
+ /* Infrastructure only */
+ if (!(dtoh16(bi->capability) & DOT11_CAP_ESS))
+ continue;
+
+ /* BSSID */
+ memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN);
+ addr[dwrq->length].sa_family = ARPHRD_ETHER;
+ qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI));
+ qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI);
+ qual[dwrq->length].noise = 0x100 + bi->phy_noise;
+
+ /* Updated qual, level, and noise */
+#if WIRELESS_EXT > 18
+ qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+#else
+ qual[dwrq->length].updated = 7;
+#endif /* WIRELESS_EXT > 18 */
+
+ dwrq->length++;
+ }
+ buf = buf->next;
+ }
+ if (dwrq->length) {
+ memcpy(&addr[dwrq->length], qual, sizeof(struct iw_quality) * dwrq->length);
+ /* Provided qual */
+ dwrq->flags = 1;
+ }
+
+ return 0;
+}
+
+#if WIRELESS_EXT > 13
+static int
+wl_iw_set_scan(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ wlc_ssid_t ssid;
+
+ AP6210_DEBUG("%s: SIOCSIWSCAN\n", dev->name);
+
+ /* default Broadcast scan */
+ memset(&ssid, 0, sizeof(ssid));
+
+#if WIRELESS_EXT > 17
+ /* check for given essid */
+ if (wrqu->data.length == sizeof(struct iw_scan_req)) {
+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+ ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len);
+ memcpy(ssid.SSID, req->essid, ssid.SSID_len);
+ ssid.SSID_len = htod32(ssid.SSID_len);
+ }
+ }
+#endif
+ /* Ignore error (most likely scan in progress) */
+ (void) dev_wlc_ioctl(dev, WLC_SCAN, &ssid, sizeof(ssid));
+
+ return 0;
+}
+
+static int
+wl_iw_iscan_set_scan(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra
+)
+{
+ wlc_ssid_t ssid;
+ iscan_info_t *iscan = g_iscan;
+
+ AP6210_DEBUG("%s: SIOCSIWSCAN\n", dev->name);
+
+ /* use backup if our thread is not successful */
+ if ((!iscan) || (iscan->sysioc_pid < 0)) {
+ return wl_iw_set_scan(dev, info, wrqu, extra);
+ }
+ if (iscan->iscan_state == ISCAN_STATE_SCANING) {
+ return 0;
+ }
+
+ /* default Broadcast scan */
+ memset(&ssid, 0, sizeof(ssid));
+
+#if WIRELESS_EXT > 17
+ /* check for given essid */
+ if (wrqu->data.length == sizeof(struct iw_scan_req)) {
+ if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+ ssid.SSID_len = MIN(sizeof(ssid.SSID), req->essid_len);
+ memcpy(ssid.SSID, req->essid, ssid.SSID_len);
+ ssid.SSID_len = htod32(ssid.SSID_len);
+ }
+ }
+#endif
+
+ iscan->list_cur = iscan->list_hdr;
+ iscan->iscan_state = ISCAN_STATE_SCANING;
+
+
+ wl_iw_set_event_mask(dev);
+ wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
+
+ iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms);
+ add_timer(&iscan->timer);
+ iscan->timer_on = 1;
+
+ return 0;
+}
+
+#if WIRELESS_EXT > 17
+static bool
+ie_is_wpa_ie(uint8 **wpaie, uint8 **tlvs, int *tlvs_len)
+{
+/* Is this body of this tlvs entry a WPA entry? If */
+/* not update the tlvs buffer pointer/length */
+ uint8 *ie = *wpaie;
+
+ /* If the contents match the WPA_OUI and type=1 */
+ if ((ie[1] >= 6) &&
+ !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) {
+ return TRUE;
+ }
+
+ /* point to the next ie */
+ ie += ie[1] + 2;
+ /* calculate the length of the rest of the buffer */
+ *tlvs_len -= (int)(ie - *tlvs);
+ /* update the pointer to the start of the buffer */
+ *tlvs = ie;
+ return FALSE;
+}
+
+static bool
+ie_is_wps_ie(uint8 **wpsie, uint8 **tlvs, int *tlvs_len)
+{
+/* Is this body of this tlvs entry a WPS entry? If */
+/* not update the tlvs buffer pointer/length */
+ uint8 *ie = *wpsie;
+
+ /* If the contents match the WPA_OUI and type=4 */
+ if ((ie[1] >= 4) &&
+ !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) {
+ return TRUE;
+ }
+
+ /* point to the next ie */
+ ie += ie[1] + 2;
+ /* calculate the length of the rest of the buffer */
+ *tlvs_len -= (int)(ie - *tlvs);
+ /* update the pointer to the start of the buffer */
+ *tlvs = ie;
+ return FALSE;
+}
+#endif /* WIRELESS_EXT > 17 */
+
+
+static int
+wl_iw_handle_scanresults_ies(char **event_p, char *end,
+ struct iw_request_info *info, wl_bss_info_t *bi)
+{
+#if WIRELESS_EXT > 17
+ struct iw_event iwe;
+ char *event;
+
+ event = *event_p;
+ if (bi->ie_length) {
+ /* look for wpa/rsn ies in the ie list... */
+ bcm_tlv_t *ie;
+ uint8 *ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t);
+ int ptr_len = bi->ie_length;
+
+ if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID))) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie->len + 2;
+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie);
+ }
+ ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t);
+
+#if defined(WLFBT)
+ if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_MDIE_ID))) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie->len + 2;
+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie);
+ }
+ ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t);
+#endif /* WLFBT */
+
+ while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {
+ /* look for WPS IE */
+ if (ie_is_wps_ie(((uint8 **)&ie), &ptr, &ptr_len)) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie->len + 2;
+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie);
+ break;
+ }
+ }
+
+ ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t);
+ ptr_len = bi->ie_length;
+ while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {
+ if (ie_is_wpa_ie(((uint8 **)&ie), &ptr, &ptr_len)) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie->len + 2;
+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie);
+ break;
+ }
+ }
+
+ *event_p = event;
+ }
+
+#endif /* WIRELESS_EXT > 17 */
+ return 0;
+}
+static int
+wl_iw_get_scan(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ channel_info_t ci;
+ wl_scan_results_t *list;
+ struct iw_event iwe;
+ wl_bss_info_t *bi = NULL;
+ int error, i, j;
+ char *event = extra, *end = extra + dwrq->length, *value;
+ uint buflen = dwrq->length;
+
+ AP6210_DEBUG("%s: SIOCGIWSCAN\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ /* Check for scan in progress */
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci))))
+ return error;
+ ci.scan_channel = dtoh32(ci.scan_channel);
+ if (ci.scan_channel)
+ return -EAGAIN;
+
+ /* Get scan results (too large to put on the stack) */
+ list = kmalloc(buflen, GFP_KERNEL);
+ if (!list)
+ return -ENOMEM;
+ memset(list, 0, buflen);
+ list->buflen = htod32(buflen);
+ if ((error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen))) {
+ kfree(list);
+ return error;
+ }
+ list->buflen = dtoh32(list->buflen);
+ list->version = dtoh32(list->version);
+ list->count = dtoh32(list->count);
+
+ ASSERT(list->version == WL_BSS_INFO_VERSION);
+
+ for (i = 0; i < list->count && i < IW_MAX_AP; i++) {
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info;
+ ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
+ buflen));
+
+ /* First entry must be the BSSID */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN);
+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN);
+
+ /* SSID */
+ iwe.u.data.length = dtoh32(bi->SSID_len);
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
+
+ /* Mode */
+ if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) {
+ iwe.cmd = SIOCGIWMODE;
+ if (dtoh16(bi->capability) & DOT11_CAP_ESS)
+ iwe.u.mode = IW_MODE_INFRA;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN);
+ }
+
+ /* Channel */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec),
+ CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ?
+ WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
+ iwe.u.freq.e = 6;
+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
+
+ /* Channel quality */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI));
+ iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI);
+ iwe.u.qual.noise = 0x100 + bi->phy_noise;
+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN);
+
+ /* WPA, WPA2, WPS, WAPI IEs */
+ wl_iw_handle_scanresults_ies(&event, end, info, bi);
+
+ /* Encryption */
+ iwe.cmd = SIOCGIWENCODE;
+ if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ iwe.u.data.length = 0;
+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
+
+ /* Rates */
+ if (bi->rateset.count) {
+ value = event + IW_EV_LCP_LEN;
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+ for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
+ iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
+ value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
+ IW_EV_PARAM_LEN);
+ }
+ event = value;
+ }
+ }
+
+ kfree(list);
+
+ dwrq->length = event - extra;
+ dwrq->flags = 0; /* todo */
+
+ return 0;
+}
+
+static int
+wl_iw_iscan_get_scan(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_scan_results_t *list;
+ struct iw_event iwe;
+ wl_bss_info_t *bi = NULL;
+ int ii, j;
+ int apcnt;
+ char *event = extra, *end = extra + dwrq->length, *value;
+ iscan_info_t *iscan = g_iscan;
+ iscan_buf_t * p_buf;
+
+ AP6210_DEBUG("%s: SIOCGIWSCAN\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ /* use backup if our thread is not successful */
+ if ((!iscan) || (iscan->sysioc_pid < 0)) {
+ return wl_iw_get_scan(dev, info, dwrq, extra);
+ }
+
+ /* Check for scan in progress */
+ if (iscan->iscan_state == ISCAN_STATE_SCANING)
+ return -EAGAIN;
+
+ apcnt = 0;
+ p_buf = iscan->list_hdr;
+ /* Get scan results */
+ while (p_buf != iscan->list_cur) {
+ list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results;
+
+ if (list->version != WL_BSS_INFO_VERSION) {
+ AP6210_ERR("list->version %d != WL_BSS_INFO_VERSION\n", list->version);
+ }
+
+ bi = NULL;
+ for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) {
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info;
+ ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
+ WLC_IW_ISCAN_MAXLEN));
+
+ /* overflow check cover fields before wpa IEs */
+ if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN +
+ IW_EV_QUAL_LEN >= end)
+ return -E2BIG;
+ /* First entry must be the BSSID */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN);
+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN);
+
+ /* SSID */
+ iwe.u.data.length = dtoh32(bi->SSID_len);
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
+
+ /* Mode */
+ if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) {
+ iwe.cmd = SIOCGIWMODE;
+ if (dtoh16(bi->capability) & DOT11_CAP_ESS)
+ iwe.u.mode = IW_MODE_INFRA;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN);
+ }
+
+ /* Channel */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec),
+ CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ?
+ WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
+ iwe.u.freq.e = 6;
+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
+
+ /* Channel quality */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI));
+ iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI);
+ iwe.u.qual.noise = 0x100 + bi->phy_noise;
+ event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN);
+
+ /* WPA, WPA2, WPS, WAPI IEs */
+ wl_iw_handle_scanresults_ies(&event, end, info, bi);
+
+ /* Encryption */
+ iwe.cmd = SIOCGIWENCODE;
+ if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ iwe.u.data.length = 0;
+ event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
+
+ /* Rates */
+ if (bi->rateset.count <= sizeof(bi->rateset.rates)) {
+ if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end)
+ return -E2BIG;
+
+ value = event + IW_EV_LCP_LEN;
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+ for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
+ iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
+ value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
+ IW_EV_PARAM_LEN);
+ }
+ event = value;
+ }
+ }
+ p_buf = p_buf->next;
+ } /* while (p_buf) */
+
+ dwrq->length = event - extra;
+ dwrq->flags = 0; /* todo */
+
+ return 0;
+}
+
+#endif /* WIRELESS_EXT > 13 */
+
+
+static int
+wl_iw_set_essid(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wlc_ssid_t ssid;
+ int error;
+
+ AP6210_DEBUG("%s: SIOCSIWESSID\n", dev->name);
+
+ /* default Broadcast SSID */
+ memset(&ssid, 0, sizeof(ssid));
+ if (dwrq->length && extra) {
+#if WIRELESS_EXT > 20
+ ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length);
+#else
+ ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length-1);
+#endif
+ memcpy(ssid.SSID, extra, ssid.SSID_len);
+ ssid.SSID_len = htod32(ssid.SSID_len);
+
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid))))
+ return error;
+ }
+ /* If essid null then it is "iwconfig <interface> essid off" command */
+ else {
+ scb_val_t scbval;
+ bzero(&scbval, sizeof(scb_val_t));
+ if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t))))
+ return error;
+ }
+ return 0;
+}
+
+static int
+wl_iw_get_essid(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wlc_ssid_t ssid;
+ int error;
+
+ AP6210_DEBUG("%s: SIOCGIWESSID\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)))) {
+ AP6210_ERR("Error getting the SSID\n");
+ return error;
+ }
+
+ ssid.SSID_len = dtoh32(ssid.SSID_len);
+
+ /* Get the current SSID */
+ memcpy(extra, ssid.SSID, ssid.SSID_len);
+
+ dwrq->length = ssid.SSID_len;
+
+ dwrq->flags = 1; /* active */
+
+ return 0;
+}
+
+static int
+wl_iw_set_nick(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_iw_t *iw = IW_DEV_IF(dev);
+ AP6210_DEBUG("%s: SIOCSIWNICKN\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ /* Check the size of the string */
+ if (dwrq->length > sizeof(iw->nickname))
+ return -E2BIG;
+
+ memcpy(iw->nickname, extra, dwrq->length);
+ iw->nickname[dwrq->length - 1] = '\0';
+
+ return 0;
+}
+
+static int
+wl_iw_get_nick(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_iw_t *iw = IW_DEV_IF(dev);
+ AP6210_DEBUG("%s: SIOCGIWNICKN\n", dev->name);
+
+ if (!extra)
+ return -EINVAL;
+
+ strcpy(extra, iw->nickname);
+ dwrq->length = strlen(extra) + 1;
+
+ return 0;
+}
+
+static int wl_iw_set_rate(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ wl_rateset_t rateset;
+ int error, rate, i, error_bg, error_a;
+
+ AP6210_DEBUG("%s: SIOCSIWRATE\n", dev->name);
+
+ /* Get current rateset */
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset))))
+ return error;
+
+ rateset.count = dtoh32(rateset.count);
+
+ if (vwrq->value < 0) {
+ /* Select maximum rate */
+ rate = rateset.rates[rateset.count - 1] & 0x7f;
+ } else if (vwrq->value < rateset.count) {
+ /* Select rate by rateset index */
+ rate = rateset.rates[vwrq->value] & 0x7f;
+ } else {
+ /* Specified rate in bps */
+ rate = vwrq->value / 500000;
+ }
+
+ if (vwrq->fixed) {
+ /*
+ Set rate override,
+ Since the is a/b/g-blind, both a/bg_rate are enforced.
+ */
+ error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate);
+ error_a = dev_wlc_intvar_set(dev, "a_rate", rate);
+
+ if (error_bg && error_a)
+ return (error_bg | error_a);
+ } else {
+ /*
+ clear rate override
+ Since the is a/b/g-blind, both a/bg_rate are enforced.
+ */
+ /* 0 is for clearing rate override */
+ error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0);
+ /* 0 is for clearing rate override */
+ error_a = dev_wlc_intvar_set(dev, "a_rate", 0);
+
+ if (error_bg && error_a)
+ return (error_bg | error_a);
+
+ /* Remove rates above selected rate */
+ for (i = 0; i < rateset.count; i++)
+ if ((rateset.rates[i] & 0x7f) > rate)
+ break;
+ rateset.count = htod32(i);
+
+ /* Set current rateset */
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset))))
+ return error;
+ }
+
+ return 0;
+}
+
+static int wl_iw_get_rate(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, rate;
+
+ AP6210_DEBUG("%s: SIOCGIWRATE\n", dev->name);
+
+ /* Report the current tx rate */
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate))))
+ return error;
+ rate = dtoh32(rate);
+ vwrq->value = rate * 500000;
+
+ return 0;
+}
+
+static int
+wl_iw_set_rts(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, rts;
+
+ AP6210_DEBUG("%s: SIOCSIWRTS\n", dev->name);
+
+ if (vwrq->disabled)
+ rts = DOT11_DEFAULT_RTS_LEN;
+ else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN)
+ return -EINVAL;
+ else
+ rts = vwrq->value;
+
+ if ((error = dev_wlc_intvar_set(dev, "rtsthresh", rts)))
+ return error;
+
+ return 0;
+}
+
+static int
+wl_iw_get_rts(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, rts;
+
+ AP6210_DEBUG("%s: SIOCGIWRTS\n", dev->name);
+
+ if ((error = dev_wlc_intvar_get(dev, "rtsthresh", &rts)))
+ return error;
+
+ vwrq->value = rts;
+ vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN);
+ vwrq->fixed = 1;
+
+ return 0;
+}
+
+static int
+wl_iw_set_frag(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, frag;
+
+ AP6210_DEBUG("%s: SIOCSIWFRAG\n", dev->name);
+
+ if (vwrq->disabled)
+ frag = DOT11_DEFAULT_FRAG_LEN;
+ else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN)
+ return -EINVAL;
+ else
+ frag = vwrq->value;
+
+ if ((error = dev_wlc_intvar_set(dev, "fragthresh", frag)))
+ return error;
+
+ return 0;
+}
+
+static int
+wl_iw_get_frag(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, fragthreshold;
+
+ AP6210_DEBUG("%s: SIOCGIWFRAG\n", dev->name);
+
+ if ((error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold)))
+ return error;
+
+ vwrq->value = fragthreshold;
+ vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN);
+ vwrq->fixed = 1;
+
+ return 0;
+}
+
+static int
+wl_iw_set_txpow(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, disable;
+ uint16 txpwrmw;
+ AP6210_DEBUG("%s: SIOCSIWTXPOW\n", dev->name);
+
+ /* Make sure radio is off or on as far as software is concerned */
+ disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0;
+ disable += WL_RADIO_SW_DISABLE << 16;
+
+ disable = htod32(disable);
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable))))
+ return error;
+
+ /* If Radio is off, nothing more to do */
+ if (disable & WL_RADIO_SW_DISABLE)
+ return 0;
+
+ /* Only handle mW */
+ if (!(vwrq->flags & IW_TXPOW_MWATT))
+ return -EINVAL;
+
+ /* Value < 0 means just "on" or "off" */
+ if (vwrq->value < 0)
+ return 0;
+
+ if (vwrq->value > 0xffff) txpwrmw = 0xffff;
+ else txpwrmw = (uint16)vwrq->value;
+
+
+ error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw)));
+ return error;
+}
+
+static int
+wl_iw_get_txpow(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, disable, txpwrdbm;
+ uint8 result;
+
+ AP6210_DEBUG("%s: SIOCGIWTXPOW\n", dev->name);
+
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable))) ||
+ (error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm)))
+ return error;
+
+ disable = dtoh32(disable);
+ result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE);
+ vwrq->value = (int32)bcm_qdbm_to_mw(result);
+ vwrq->fixed = 0;
+ vwrq->disabled = (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0;
+ vwrq->flags = IW_TXPOW_MWATT;
+
+ return 0;
+}
+
+#if WIRELESS_EXT > 10
+static int
+wl_iw_set_retry(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, lrl, srl;
+
+ AP6210_DEBUG("%s: SIOCSIWRETRY\n", dev->name);
+
+ /* Do not handle "off" or "lifetime" */
+ if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME))
+ return -EINVAL;
+
+ /* Handle "[min|max] limit" */
+ if (vwrq->flags & IW_RETRY_LIMIT) {
+ /* "max limit" or just "limit" */
+#if WIRELESS_EXT > 20
+ if ((vwrq->flags & IW_RETRY_LONG) ||(vwrq->flags & IW_RETRY_MAX) ||
+ !((vwrq->flags & IW_RETRY_SHORT) || (vwrq->flags & IW_RETRY_MIN))) {
+#else
+ if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) {
+#endif /* WIRELESS_EXT > 20 */
+
+ lrl = htod32(vwrq->value);
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl))))
+ return error;
+ }
+ /* "min limit" or just "limit" */
+#if WIRELESS_EXT > 20
+ if ((vwrq->flags & IW_RETRY_SHORT) ||(vwrq->flags & IW_RETRY_MIN) ||
+ !((vwrq->flags & IW_RETRY_LONG) || (vwrq->flags & IW_RETRY_MAX))) {
+#else
+ if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) {
+#endif /* WIRELESS_EXT > 20 */
+
+ srl = htod32(vwrq->value);
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl))))
+ return error;
+ }
+ }
+
+ return 0;
+}
+
+static int
+wl_iw_get_retry(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, lrl, srl;
+
+ AP6210_DEBUG("%s: SIOCGIWRETRY\n", dev->name);
+
+ vwrq->disabled = 0; /* Can't be disabled */
+
+ /* Do not handle lifetime queries */
+ if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
+ return -EINVAL;
+
+ /* Get retry limits */
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl))) ||
+ (error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl))))
+ return error;
+
+ lrl = dtoh32(lrl);
+ srl = dtoh32(srl);
+
+ /* Note : by default, display the min retry number */
+ if (vwrq->flags & IW_RETRY_MAX) {
+ vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ vwrq->value = lrl;
+ } else {
+ vwrq->flags = IW_RETRY_LIMIT;
+ vwrq->value = srl;
+ if (srl != lrl)
+ vwrq->flags |= IW_RETRY_MIN;
+ }
+
+ return 0;
+}
+#endif /* WIRELESS_EXT > 10 */
+
+static int
+wl_iw_set_encode(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_wsec_key_t key;
+ int error, val, wsec;
+
+ AP6210_DEBUG("%s: SIOCSIWENCODE\n", dev->name);
+
+ memset(&key, 0, sizeof(key));
+
+ if ((dwrq->flags & IW_ENCODE_INDEX) == 0) {
+ /* Find the current key */
+ for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) {
+ val = htod32(key.index);
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val))))
+ return error;
+ val = dtoh32(val);
+ if (val)
+ break;
+ }
+ /* Default to 0 */
+ if (key.index == DOT11_MAX_DEFAULT_KEYS)
+ key.index = 0;
+ } else {
+ key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+ return -EINVAL;
+ }
+
+ /* Interpret "off" to mean no encryption */
+ wsec = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED;
+
+ if ((error = dev_wlc_intvar_set(dev, "wsec", wsec)))
+ return error;
+
+ /* Old API used to pass a NULL pointer instead of IW_ENCODE_NOKEY */
+ if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) {
+ /* Just select a new current key */
+ val = htod32(key.index);
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val))))
+ return error;
+ } else {
+ key.len = dwrq->length;
+
+ if (dwrq->length > sizeof(key.data))
+ return -EINVAL;
+
+ memcpy(key.data, extra, dwrq->length);
+
+ key.flags = WL_PRIMARY_KEY;
+ switch (key.len) {
+ case WEP1_KEY_SIZE:
+ key.algo = CRYPTO_ALGO_WEP1;
+ break;
+ case WEP128_KEY_SIZE:
+ key.algo = CRYPTO_ALGO_WEP128;
+ break;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+ case TKIP_KEY_SIZE:
+ key.algo = CRYPTO_ALGO_TKIP;
+ break;
+#endif
+ case AES_KEY_SIZE:
+ key.algo = CRYPTO_ALGO_AES_CCM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Set the new key/index */
+ swap_key_from_BE(&key);
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))
+ return error;
+ }
+
+ /* Interpret "restricted" to mean shared key authentication */
+ val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0;
+ val = htod32(val);
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))
+ return error;
+
+ return 0;
+}
+
+static int
+wl_iw_get_encode(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_wsec_key_t key;
+ int error, val, wsec, auth;
+
+ AP6210_DEBUG("%s: SIOCGIWENCODE\n", dev->name);
+
+ /* assure default values of zero for things we don't touch */
+ bzero(&key, sizeof(wl_wsec_key_t));
+
+ if ((dwrq->flags & IW_ENCODE_INDEX) == 0) {
+ /* Find the current key */
+ for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) {
+ val = key.index;
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val))))
+ return error;
+ val = dtoh32(val);
+ if (val)
+ break;
+ }
+ } else
+ key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+
+ if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+ key.index = 0;
+
+ /* Get info */
+
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec))) ||
+ (error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth))))
+ return error;
+
+ swap_key_to_BE(&key);
+
+ wsec = dtoh32(wsec);
+ auth = dtoh32(auth);
+ /* Get key length */
+ dwrq->length = MIN(IW_ENCODING_TOKEN_MAX, key.len);
+
+ /* Get flags */
+ dwrq->flags = key.index + 1;
+ if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) {
+ /* Interpret "off" to mean no encryption */
+ dwrq->flags |= IW_ENCODE_DISABLED;
+ }
+ if (auth) {
+ /* Interpret "restricted" to mean shared key authentication */
+ dwrq->flags |= IW_ENCODE_RESTRICTED;
+ }
+
+ /* Get key */
+ if (dwrq->length && extra)
+ memcpy(extra, key.data, dwrq->length);
+
+ return 0;
+}
+
+static int
+wl_iw_set_power(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, pm;
+
+ AP6210_DEBUG("%s: SIOCSIWPOWER\n", dev->name);
+
+ pm = vwrq->disabled ? PM_OFF : PM_MAX;
+
+ pm = htod32(pm);
+ if ((error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm))))
+ return error;
+
+ return 0;
+}
+
+static int
+wl_iw_get_power(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error, pm;
+
+ AP6210_DEBUG("%s: SIOCGIWPOWER\n", dev->name);
+
+ if ((error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))))
+ return error;
+
+ pm = dtoh32(pm);
+ vwrq->disabled = pm ? 0 : 1;
+ vwrq->flags = IW_POWER_ALL_R;
+
+ return 0;
+}
+
+#if WIRELESS_EXT > 17
+static int
+wl_iw_set_wpaie(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *iwp,
+ char *extra
+)
+{
+ dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length);
+
+ return 0;
+}
+
+static int
+wl_iw_get_wpaie(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *iwp,
+ char *extra
+)
+{
+ AP6210_DEBUG("%s: SIOCGIWGENIE\n", dev->name);
+ iwp->length = 64;
+ dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length);
+ return 0;
+}
+
+static int
+wl_iw_set_encodeext(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *dwrq,
+ char *extra
+)
+{
+ wl_wsec_key_t key;
+ int error;
+ struct iw_encode_ext *iwe;
+
+ AP6210_DEBUG("%s: SIOCSIWENCODEEXT\n", dev->name);
+
+ memset(&key, 0, sizeof(key));
+ iwe = (struct iw_encode_ext *)extra;
+
+ /* disable encryption completely */
+ if (dwrq->flags & IW_ENCODE_DISABLED) {
+
+ }
+
+ /* get the key index */
+ key.index = 0;
+ if (dwrq->flags & IW_ENCODE_INDEX)
+ key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+
+ key.len = iwe->key_len;
+
+ /* Instead of bcast for ea address for default wep keys, driver needs it to be Null */
+ if (!ETHER_ISMULTI(iwe->addr.sa_data))
+ bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN);
+
+ /* check for key index change */
+ if (key.len == 0) {
+ if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ AP6210_DEBUG("Changing the the primary Key to %d\n", key.index);
+ /* change the key index .... */
+ key.index = htod32(key.index);
+ error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY,
+ &key.index, sizeof(key.index));
+ if (error)
+ return error;
+ }
+ /* key delete */
+ else {
+ swap_key_from_BE(&key);
+ error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+ if (error)
+ return error;
+ }
+ }
+#if (defined(BCMSUP_PSK) && defined(WLFBT))
+ /* This case is used to allow an external 802.1x supplicant
+ * to pass the PMK to the in-driver supplicant for use in
+ * the 4-way handshake.
+ */
+ else if (iwe->alg == IW_ENCODE_ALG_PMK) {
+ int j;
+ wsec_pmk_t pmk;
+ char keystring[WSEC_MAX_PSK_LEN + 1];
+ char* charptr = keystring;
+ uint len;
+
+ /* copy the raw hex key to the appropriate format */
+ for (j = 0; j < (WSEC_MAX_PSK_LEN / 2); j++) {
+ sprintf(charptr, "%02x", iwe->key[j]);
+ charptr += 2;
+ }
+ len = strlen(keystring);
+ pmk.key_len = htod16(len);
+ bcopy(keystring, pmk.key, len);
+ pmk.flags = htod16(WSEC_PASSPHRASE);
+
+ error = dev_wlc_ioctl(dev, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk));
+ if (error)
+ return error;
+ }
+#endif /* (defined (BCMSUP_PSK) && defined(WLFBT)) */
+
+ else {
+ if (iwe->key_len > sizeof(key.data))
+ return -EINVAL;
+
+ AP6210_DEBUG("Setting the key index %d\n", key.index);
+ if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ AP6210_DEBUG("key is a Primary Key\n");
+ key.flags = WL_PRIMARY_KEY;
+ }
+
+ bcopy((void *)iwe->key, key.data, iwe->key_len);
+
+ if (iwe->alg == IW_ENCODE_ALG_TKIP) {
+ uint8 keybuf[8];
+ bcopy(&key.data[24], keybuf, sizeof(keybuf));
+ bcopy(&key.data[16], &key.data[24], sizeof(keybuf));
+ bcopy(keybuf, &key.data[16], sizeof(keybuf));
+ }
+
+ /* rx iv */
+ if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ uchar *ivptr;
+ ivptr = (uchar *)iwe->rx_seq;
+ key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
+ (ivptr[3] << 8) | ivptr[2];
+ key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
+ key.iv_initialized = TRUE;
+ }
+
+ switch (iwe->alg) {
+ case IW_ENCODE_ALG_NONE:
+ key.algo = CRYPTO_ALGO_OFF;
+ break;
+ case IW_ENCODE_ALG_WEP:
+ if (iwe->key_len == WEP1_KEY_SIZE)
+ key.algo = CRYPTO_ALGO_WEP1;
+ else
+ key.algo = CRYPTO_ALGO_WEP128;
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ key.algo = CRYPTO_ALGO_TKIP;
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ key.algo = CRYPTO_ALGO_AES_CCM;
+ break;
+ default:
+ break;
+ }
+ swap_key_from_BE(&key);
+
+ dhd_wait_pend8021x(dev);
+
+ error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+ if (error)
+ return error;
+ }
+ return 0;
+}
+
+
+#if WIRELESS_EXT > 17
+struct {
+ pmkid_list_t pmkids;
+ pmkid_t foo[MAXPMKID-1];
+} pmkid_list;
+static int
+wl_iw_set_pmksa(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ struct iw_pmksa *iwpmksa;
+ uint i;
+ char eabuf[ETHER_ADDR_STR_LEN];
+ pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid;
+
+ AP6210_DEBUG("%s: SIOCSIWPMKSA\n", dev->name);
+ iwpmksa = (struct iw_pmksa *)extra;
+ bzero((char *)eabuf, ETHER_ADDR_STR_LEN);
+ if (iwpmksa->cmd == IW_PMKSA_FLUSH) {
+ AP6210_DEBUG("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n");
+ bzero((char *)&pmkid_list, sizeof(pmkid_list));
+ }
+ if (iwpmksa->cmd == IW_PMKSA_REMOVE) {
+ pmkid_list_t pmkid, *pmkidptr;
+ pmkidptr = &pmkid;
+ bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, ETHER_ADDR_LEN);
+ bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN);
+ {
+ uint j;
+ AP6210_DEBUG("wl_iw_set_pmksa,IW_PMKSA_REMOVE - PMKID: %s = ",
+ bcm_ether_ntoa(&pmkidptr->pmkid[0].BSSID,
+ eabuf));
+ for (j = 0; j < WPA2_PMKID_LEN; j++)
+ AP6210_DUMP("%02x ", pmkidptr->pmkid[0].PMKID[j]);
+ AP6210_DUMP("\n");
+ }
+ for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
+ if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID,
+ ETHER_ADDR_LEN))
+ break;
+ for (; i < pmkid_list.pmkids.npmkid; i++) {
+ bcopy(&pmkid_array[i+1].BSSID,
+ &pmkid_array[i].BSSID,
+ ETHER_ADDR_LEN);
+ bcopy(&pmkid_array[i+1].PMKID,
+ &pmkid_array[i].PMKID,
+ WPA2_PMKID_LEN);
+ }
+ pmkid_list.pmkids.npmkid--;
+ }
+ if (iwpmksa->cmd == IW_PMKSA_ADD) {
+ bcopy(&iwpmksa->bssid.sa_data[0],
+ &pmkid_array[pmkid_list.pmkids.npmkid].BSSID,
+ ETHER_ADDR_LEN);
+ bcopy(&iwpmksa->pmkid[0], &pmkid_array[pmkid_list.pmkids.npmkid].PMKID,
+ WPA2_PMKID_LEN);
+ {
+ uint j;
+ uint k;
+ k = pmkid_list.pmkids.npmkid;
+ BCM_REFERENCE(k);
+ AP6210_DEBUG("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ",
+ bcm_ether_ntoa(&pmkid_array[k].BSSID,
+ eabuf));
+ for (j = 0; j < WPA2_PMKID_LEN; j++)
+ AP6210_DUMP("%02x ", pmkid_array[k].PMKID[j]);
+ AP6210_DUMP("\n");
+ }
+ pmkid_list.pmkids.npmkid++;
+ }
+ AP6210_DEBUG("PRINTING pmkid LIST - No of elements %d\n", pmkid_list.pmkids.npmkid);
+ for (i = 0; i < pmkid_list.pmkids.npmkid; i++) {
+ uint j;
+ AP6210_DEBUG("PMKID[%d]: %s = ", i,
+ bcm_ether_ntoa(&pmkid_array[i].BSSID,
+ eabuf));
+ for (j = 0; j < WPA2_PMKID_LEN; j++)
+ AP6210_DUMP("%02x ", pmkid_array[i].PMKID[j]);
+ AP6210_DEBUG("\n");
+ }
+ AP6210_DEBUG("\n");
+ dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, sizeof(pmkid_list));
+ return 0;
+}
+#endif /* WIRELESS_EXT > 17 */
+
+static int
+wl_iw_get_encodeext(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ AP6210_DEBUG("%s: SIOCGIWENCODEEXT\n", dev->name);
+ return 0;
+}
+
+static int
+wl_iw_set_wpaauth(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error = 0;
+ int paramid;
+ int paramval;
+ uint32 cipher_combined;
+ int val = 0;
+ wl_iw_t *iw = IW_DEV_IF(dev);
+
+ AP6210_DEBUG("%s: SIOCSIWAUTH\n", dev->name);
+
+ paramid = vwrq->flags & IW_AUTH_INDEX;
+ paramval = vwrq->value;
+
+ AP6210_DEBUG("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n",
+ dev->name, paramid, paramval);
+
+ switch (paramid) {
+
+ case IW_AUTH_WPA_VERSION:
+ /* supported wpa version disabled or wpa or wpa2 */
+ if (paramval & IW_AUTH_WPA_VERSION_DISABLED)
+ val = WPA_AUTH_DISABLED;
+ else if (paramval & (IW_AUTH_WPA_VERSION_WPA))
+ val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
+ else if (paramval & IW_AUTH_WPA_VERSION_WPA2)
+ val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+ AP6210_DEBUG("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val);
+ if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val)))
+ return error;
+ break;
+
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+
+ if (paramid == IW_AUTH_CIPHER_PAIRWISE) {
+ iw->pwsec = paramval;
+ }
+ else {
+ iw->gwsec = paramval;
+ }
+
+ if ((error = dev_wlc_intvar_get(dev, "wsec", &val)))
+ return error;
+
+ cipher_combined = iw->gwsec | iw->pwsec;
+ val &= ~(WEP_ENABLED | TKIP_ENABLED | AES_ENABLED);
+ if (cipher_combined & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
+ val |= WEP_ENABLED;
+ if (cipher_combined & IW_AUTH_CIPHER_TKIP)
+ val |= TKIP_ENABLED;
+ if (cipher_combined & IW_AUTH_CIPHER_CCMP)
+ val |= AES_ENABLED;
+
+ if (iw->privacy_invoked && !val) {
+ AP6210_DEBUG("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming "
+ "we're a WPS enrollee\n", dev->name, __FUNCTION__);
+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) {
+ AP6210_DEBUG("Failed to set iovar is_WPS_enrollee\n");
+ return error;
+ }
+ } else if (val) {
+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) {
+ AP6210_DEBUG("Failed to clear iovar is_WPS_enrollee\n");
+ return error;
+ }
+ }
+
+ if ((error = dev_wlc_intvar_set(dev, "wsec", val)))
+ return error;
+#ifdef WLFBT
+ if ((paramid == IW_AUTH_CIPHER_PAIRWISE) && (val | AES_ENABLED)) {
+ if ((error = dev_wlc_intvar_set(dev, "sup_wpa", 1)))
+ return error;
+ }
+ else if (val == 0) {
+ if ((error = dev_wlc_intvar_set(dev, "sup_wpa", 0)))
+ return error;
+ }
+#endif /* WLFBT */
+ break;
+
+ case IW_AUTH_KEY_MGMT:
+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+ return error;
+
+ if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
+ if (paramval & IW_AUTH_KEY_MGMT_PSK)
+ val = WPA_AUTH_PSK;
+ else
+ val = WPA_AUTH_UNSPECIFIED;
+ }
+ else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
+ if (paramval & IW_AUTH_KEY_MGMT_PSK)
+ val = WPA2_AUTH_PSK;
+ else
+ val = WPA2_AUTH_UNSPECIFIED;
+ }
+ AP6210_DEBUG("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val);
+ if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val)))
+ return error;
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ dev_wlc_bufvar_set(dev, "tkip_countermeasures", (char *)&paramval, 1);
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ /* open shared */
+ AP6210_ERR("Setting the D11auth %d\n", paramval);
+ if (paramval & IW_AUTH_ALG_OPEN_SYSTEM)
+ val = 0;
+ else if (paramval & IW_AUTH_ALG_SHARED_KEY)
+ val = 1;
+ else
+ error = 1;
+ if (!error && (error = dev_wlc_intvar_set(dev, "auth", val)))
+ return error;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ if (paramval == 0) {
+ val = 0;
+ AP6210_DEBUG("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val);
+ error = dev_wlc_intvar_set(dev, "wpa_auth", val);
+ return error;
+ }
+ else {
+ /* If WPA is enabled, wpa_auth is set elsewhere */
+ }
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)&paramval, 1);
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", (char *)&paramval, 1);
+ break;
+
+#if WIRELESS_EXT > 17
+
+ case IW_AUTH_ROAMING_CONTROL:
+ AP6210_DEBUG("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__);
+ /* driver control or user space app control */
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED: {
+ int wsec;
+
+ if (paramval == 0) {
+ iw->privacy_invoked = FALSE;
+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) {
+ AP6210_DEBUG("Failed to clear iovar is_WPS_enrollee\n");
+ return error;
+ }
+ } else {
+ iw->privacy_invoked = TRUE;
+ if ((error = dev_wlc_intvar_get(dev, "wsec", &wsec)))
+ return error;
+
+ if (!WSEC_ENABLED(wsec)) {
+ /* if privacy is true, but wsec is false, we are a WPS enrollee */
+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) {
+ AP6210_DEBUG("Failed to set iovar is_WPS_enrollee\n");
+ return error;
+ }
+ } else {
+ if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) {
+ AP6210_DEBUG("Failed to clear iovar is_WPS_enrollee\n");
+ return error;
+ }
+ }
+ }
+ break;
+ }
+
+
+#endif /* WIRELESS_EXT > 17 */
+
+
+ default:
+ break;
+ }
+ return 0;
+}
+#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK))
+
+static int
+wl_iw_get_wpaauth(
+ struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *vwrq,
+ char *extra
+)
+{
+ int error;
+ int paramid;
+ int paramval = 0;
+ int val;
+ wl_iw_t *iw = IW_DEV_IF(dev);
+
+ AP6210_DEBUG("%s: SIOCGIWAUTH\n", dev->name);
+
+ paramid = vwrq->flags & IW_AUTH_INDEX;
+
+ switch (paramid) {
+ case IW_AUTH_WPA_VERSION:
+ /* supported wpa version disabled or wpa or wpa2 */
+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+ return error;
+ if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED))
+ paramval = IW_AUTH_WPA_VERSION_DISABLED;
+ else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED))
+ paramval = IW_AUTH_WPA_VERSION_WPA;
+ else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED))
+ paramval = IW_AUTH_WPA_VERSION_WPA2;
+ break;
+
+ case IW_AUTH_CIPHER_PAIRWISE:
+ paramval = iw->pwsec;
+ break;
+
+ case IW_AUTH_CIPHER_GROUP:
+ paramval = iw->gwsec;
+ break;
+
+ case IW_AUTH_KEY_MGMT:
+ /* psk, 1x */
+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+ return error;
+ if (VAL_PSK(val))
+ paramval = IW_AUTH_KEY_MGMT_PSK;
+ else
+ paramval = IW_AUTH_KEY_MGMT_802_1X;
+
+ break;
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ dev_wlc_bufvar_get(dev, "tkip_countermeasures", (char *)&paramval, 1);
+ break;
+
+ case IW_AUTH_DROP_UNENCRYPTED:
+ dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)&paramval, 1);
+ break;
+
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", (char *)&paramval, 1);
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ /* open, shared, leap */
+ if ((error = dev_wlc_intvar_get(dev, "auth", &val)))
+ return error;
+ if (!val)
+ paramval = IW_AUTH_ALG_OPEN_SYSTEM;
+ else
+ paramval = IW_AUTH_ALG_SHARED_KEY;
+ break;
+ case IW_AUTH_WPA_ENABLED:
+ if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+ return error;
+ if (val)
+ paramval = TRUE;
+ else
+ paramval = FALSE;
+ break;
+
+#if WIRELESS_EXT > 17
+
+ case IW_AUTH_ROAMING_CONTROL:
+ AP6210_ERR("%s: IW_AUTH_ROAMING_CONTROL\n", __FUNCTION__);
+ /* driver control or user space app control */
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ paramval = iw->privacy_invoked;
+ break;
+
+#endif /* WIRELESS_EXT > 17 */
+ }
+ vwrq->value = paramval;
+ return 0;
+}
+#endif /* WIRELESS_EXT > 17 */
+
+static const iw_handler wl_iw_handler[] =
+{
+ (iw_handler) wl_iw_config_commit, /* SIOCSIWCOMMIT */
+ (iw_handler) wl_iw_get_name, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) wl_iw_set_freq, /* SIOCSIWFREQ */
+ (iw_handler) wl_iw_get_freq, /* SIOCGIWFREQ */
+ (iw_handler) wl_iw_set_mode, /* SIOCSIWMODE */
+ (iw_handler) wl_iw_get_mode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL, /* SIOCSIWRANGE */
+ (iw_handler) wl_iw_get_range, /* SIOCGIWRANGE */
+ (iw_handler) NULL, /* SIOCSIWPRIV */
+ (iw_handler) NULL, /* SIOCGIWPRIV */
+ (iw_handler) NULL, /* SIOCSIWSTATS */
+ (iw_handler) NULL, /* SIOCGIWSTATS */
+ (iw_handler) wl_iw_set_spy, /* SIOCSIWSPY */
+ (iw_handler) wl_iw_get_spy, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) wl_iw_set_wap, /* SIOCSIWAP */
+ (iw_handler) wl_iw_get_wap, /* SIOCGIWAP */
+#if WIRELESS_EXT > 17
+ (iw_handler) wl_iw_mlme, /* SIOCSIWMLME */
+#else
+ (iw_handler) NULL, /* -- hole -- */
+#endif
+ (iw_handler) wl_iw_iscan_get_aplist, /* SIOCGIWAPLIST */
+#if WIRELESS_EXT > 13
+ (iw_handler) wl_iw_iscan_set_scan, /* SIOCSIWSCAN */
+ (iw_handler) wl_iw_iscan_get_scan, /* SIOCGIWSCAN */
+#else /* WIRELESS_EXT > 13 */
+ (iw_handler) NULL, /* SIOCSIWSCAN */
+ (iw_handler) NULL, /* SIOCGIWSCAN */
+#endif /* WIRELESS_EXT > 13 */
+ (iw_handler) wl_iw_set_essid, /* SIOCSIWESSID */
+ (iw_handler) wl_iw_get_essid, /* SIOCGIWESSID */
+ (iw_handler) wl_iw_set_nick, /* SIOCSIWNICKN */
+ (iw_handler) wl_iw_get_nick, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) wl_iw_set_rate, /* SIOCSIWRATE */
+ (iw_handler) wl_iw_get_rate, /* SIOCGIWRATE */
+ (iw_handler) wl_iw_set_rts, /* SIOCSIWRTS */
+ (iw_handler) wl_iw_get_rts, /* SIOCGIWRTS */
+ (iw_handler) wl_iw_set_frag, /* SIOCSIWFRAG */
+ (iw_handler) wl_iw_get_frag, /* SIOCGIWFRAG */
+ (iw_handler) wl_iw_set_txpow, /* SIOCSIWTXPOW */
+ (iw_handler) wl_iw_get_txpow, /* SIOCGIWTXPOW */
+#if WIRELESS_EXT > 10
+ (iw_handler) wl_iw_set_retry, /* SIOCSIWRETRY */
+ (iw_handler) wl_iw_get_retry, /* SIOCGIWRETRY */
+#endif /* WIRELESS_EXT > 10 */
+ (iw_handler) wl_iw_set_encode, /* SIOCSIWENCODE */
+ (iw_handler) wl_iw_get_encode, /* SIOCGIWENCODE */
+ (iw_handler) wl_iw_set_power, /* SIOCSIWPOWER */
+ (iw_handler) wl_iw_get_power, /* SIOCGIWPOWER */
+#if WIRELESS_EXT > 17
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) wl_iw_set_wpaie, /* SIOCSIWGENIE */
+ (iw_handler) wl_iw_get_wpaie, /* SIOCGIWGENIE */
+ (iw_handler) wl_iw_set_wpaauth, /* SIOCSIWAUTH */
+ (iw_handler) wl_iw_get_wpaauth, /* SIOCGIWAUTH */
+ (iw_handler) wl_iw_set_encodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) wl_iw_get_encodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) wl_iw_set_pmksa, /* SIOCSIWPMKSA */
+#endif /* WIRELESS_EXT > 17 */
+};
+
+#if WIRELESS_EXT > 12
+enum {
+ WL_IW_SET_LEDDC = SIOCIWFIRSTPRIV,
+ WL_IW_SET_VLANMODE,
+ WL_IW_SET_PM
+};
+
+static iw_handler wl_iw_priv_handler[] = {
+ wl_iw_set_leddc,
+ wl_iw_set_vlanmode,
+ wl_iw_set_pm
+};
+
+static struct iw_priv_args wl_iw_priv_args[] = {
+ {
+ WL_IW_SET_LEDDC,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_leddc"
+ },
+ {
+ WL_IW_SET_VLANMODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_vlanmode"
+ },
+ {
+ WL_IW_SET_PM,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "set_pm"
+ }
+};
+
+const struct iw_handler_def wl_iw_handler_def =
+{
+ .num_standard = ARRAYSIZE(wl_iw_handler),
+ .num_private = ARRAY_SIZE(wl_iw_priv_handler),
+ .num_private_args = ARRAY_SIZE(wl_iw_priv_args),
+ .standard = (iw_handler *) wl_iw_handler,
+ .private = wl_iw_priv_handler,
+ .private_args = wl_iw_priv_args,
+#if WIRELESS_EXT >= 19
+ get_wireless_stats: dhd_get_wireless_stats,
+#endif /* WIRELESS_EXT >= 19 */
+ };
+#endif /* WIRELESS_EXT > 12 */
+
+int
+wl_iw_ioctl(
+ struct net_device *dev,
+ struct ifreq *rq,
+ int cmd
+)
+{
+ struct iwreq *wrq = (struct iwreq *) rq;
+ struct iw_request_info info;
+ iw_handler handler;
+ char *extra = NULL;
+ size_t token_size = 1;
+ int max_tokens = 0, ret = 0;
+
+ if (cmd < SIOCIWFIRST ||
+ IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) ||
+ !(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)]))
+ return -EOPNOTSUPP;
+
+ switch (cmd) {
+
+ case SIOCSIWESSID:
+ case SIOCGIWESSID:
+ case SIOCSIWNICKN:
+ case SIOCGIWNICKN:
+ max_tokens = IW_ESSID_MAX_SIZE + 1;
+ break;
+
+ case SIOCSIWENCODE:
+ case SIOCGIWENCODE:
+#if WIRELESS_EXT > 17
+ case SIOCSIWENCODEEXT:
+ case SIOCGIWENCODEEXT:
+#endif
+ max_tokens = IW_ENCODING_TOKEN_MAX;
+ break;
+
+ case SIOCGIWRANGE:
+ max_tokens = sizeof(struct iw_range);
+ break;
+
+ case SIOCGIWAPLIST:
+ token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality);
+ max_tokens = IW_MAX_AP;
+ break;
+
+#if WIRELESS_EXT > 13
+ case SIOCGIWSCAN:
+ if (g_iscan)
+ max_tokens = wrq->u.data.length;
+ else
+ max_tokens = IW_SCAN_MAX_DATA;
+ break;
+#endif /* WIRELESS_EXT > 13 */
+
+ case SIOCSIWSPY:
+ token_size = sizeof(struct sockaddr);
+ max_tokens = IW_MAX_SPY;
+ break;
+
+ case SIOCGIWSPY:
+ token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality);
+ max_tokens = IW_MAX_SPY;
+ break;
+ default:
+ break;
+ }
+
+ if (max_tokens && wrq->u.data.pointer) {
+ if (wrq->u.data.length > max_tokens)
+ return -E2BIG;
+
+ if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL)))
+ return -ENOMEM;
+
+ if (copy_from_user(extra, wrq->u.data.pointer, wrq->u.data.length * token_size)) {
+ kfree(extra);
+ return -EFAULT;
+ }
+ }
+
+ info.cmd = cmd;
+ info.flags = 0;
+
+ ret = handler(dev, &info, &wrq->u, extra);
+
+ if (extra) {
+ if (copy_to_user(wrq->u.data.pointer, extra, wrq->u.data.length * token_size)) {
+ kfree(extra);
+ return -EFAULT;
+ }
+
+ kfree(extra);
+ }
+
+ return ret;
+}
+
+/* Convert a connection status event into a connection status string.
+ * Returns TRUE if a matching connection status string was found.
+ */
+bool
+wl_iw_conn_status_str(uint32 event_type, uint32 status, uint32 reason,
+ char* stringBuf, uint buflen)
+{
+ typedef struct conn_fail_event_map_t {
+ uint32 inEvent; /* input: event type to match */
+ uint32 inStatus; /* input: event status code to match */
+ uint32 inReason; /* input: event reason code to match */
+ const char* outName; /* output: failure type */
+ const char* outCause; /* output: failure cause */
+ } conn_fail_event_map_t;
+
+ /* Map of WLC_E events to connection failure strings */
+# define WL_IW_DONT_CARE 9999
+ const conn_fail_event_map_t event_map [] = {
+ /* inEvent inStatus inReason */
+ /* outName outCause */
+ {WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE,
+ "Conn", "Success"},
+ {WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE,
+ "Conn", "NoNetworks"},
+ {WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+ "Conn", "ConfigMismatch"},
+ {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH,
+ "Conn", "EncrypMismatch"},
+ {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH,
+ "Conn", "RsnMismatch"},
+ {WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE,
+ "Conn", "AuthTimeout"},
+ {WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+ "Conn", "AuthFail"},
+ {WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE,
+ "Conn", "AuthNoAck"},
+ {WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+ "Conn", "ReassocFail"},
+ {WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE,
+ "Conn", "ReassocTimeout"},
+ {WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE,
+ "Conn", "ReassocAbort"},
+ {WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE,
+ "Sup", "ConnSuccess"},
+ {WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+ "Sup", "WpaHandshakeFail"},
+ {WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+ "Conn", "Deauth"},
+ {WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+ "Conn", "DisassocInd"},
+ {WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+ "Conn", "Disassoc"}
+ };
+
+ const char* name = "";
+ const char* cause = NULL;
+ int i;
+
+ /* Search the event map table for a matching event */
+ for (i = 0; i < sizeof(event_map)/sizeof(event_map[0]); i++) {
+ const conn_fail_event_map_t* row = &event_map[i];
+ if (row->inEvent == event_type &&
+ (row->inStatus == status || row->inStatus == WL_IW_DONT_CARE) &&
+ (row->inReason == reason || row->inReason == WL_IW_DONT_CARE)) {
+ name = row->outName;
+ cause = row->outCause;
+ break;
+ }
+ }
+
+ /* If found, generate a connection failure string and return TRUE */
+ if (cause) {
+ memset(stringBuf, 0, buflen);
+ snprintf(stringBuf, buflen, "%s %s %02d %02d",
+ name, cause, status, reason);
+ AP6210_DEBUG("Connection status: %s\n", stringBuf);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+#if (WIRELESS_EXT > 14)
+/* Check if we have received an event that indicates connection failure
+ * If so, generate a connection failure report string.
+ * The caller supplies a buffer to hold the generated string.
+ */
+static bool
+wl_iw_check_conn_fail(wl_event_msg_t *e, char* stringBuf, uint buflen)
+{
+ uint32 event = ntoh32(e->event_type);
+ uint32 status = ntoh32(e->status);
+ uint32 reason = ntoh32(e->reason);
+
+ if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) {
+ return TRUE;
+ } else
+ {
+ return FALSE;
+ }
+}
+#endif /* WIRELESS_EXT > 14 */
+
+#ifndef IW_CUSTOM_MAX
+#define IW_CUSTOM_MAX 256 /* size of extra buffer used for translation of events */
+#endif /* IW_CUSTOM_MAX */
+
+void
+wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
+{
+#if WIRELESS_EXT > 13
+ union iwreq_data wrqu;
+ char extra[IW_CUSTOM_MAX + 1];
+ int cmd = 0;
+ uint32 event_type = ntoh32(e->event_type);
+ uint16 flags = ntoh16(e->flags);
+ uint32 datalen = ntoh32(e->datalen);
+ uint32 status = ntoh32(e->status);
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ memset(extra, 0, sizeof(extra));
+
+ memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN);
+ wrqu.addr.sa_family = ARPHRD_ETHER;
+
+ switch (event_type) {
+ case WLC_E_TXFAIL:
+ cmd = IWEVTXDROP;
+ break;
+#if WIRELESS_EXT > 14
+ case WLC_E_JOIN:
+ case WLC_E_ASSOC_IND:
+ case WLC_E_REASSOC_IND:
+ cmd = IWEVREGISTERED;
+ break;
+ case WLC_E_DEAUTH_IND:
+ case WLC_E_DISASSOC_IND:
+ cmd = SIOCGIWAP;
+ wrqu.data.length = strlen(extra);
+ bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
+ bzero(&extra, ETHER_ADDR_LEN);
+ break;
+
+ case WLC_E_LINK:
+ case WLC_E_NDIS_LINK:
+ cmd = SIOCGIWAP;
+ wrqu.data.length = strlen(extra);
+ if (!(flags & WLC_EVENT_MSG_LINK)) {
+ bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
+ bzero(&extra, ETHER_ADDR_LEN);
+ }
+ break;
+ case WLC_E_ACTION_FRAME:
+ cmd = IWEVCUSTOM;
+ if (datalen + 1 <= sizeof(extra)) {
+ wrqu.data.length = datalen + 1;
+ extra[0] = WLC_E_ACTION_FRAME;
+ memcpy(&extra[1], data, datalen);
+ AP6210_DEBUG("WLC_E_ACTION_FRAME len %d \n", wrqu.data.length);
+ }
+ break;
+
+ case WLC_E_ACTION_FRAME_COMPLETE:
+ cmd = IWEVCUSTOM;
+ if (sizeof(status) + 1 <= sizeof(extra)) {
+ wrqu.data.length = sizeof(status) + 1;
+ extra[0] = WLC_E_ACTION_FRAME_COMPLETE;
+ memcpy(&extra[1], &status, sizeof(status));
+ AP6210_DEBUG("wl_iw_event status %d \n", status);
+ }
+ break;
+#endif /* WIRELESS_EXT > 14 */
+#if WIRELESS_EXT > 17
+ case WLC_E_MIC_ERROR: {
+ struct iw_michaelmicfailure *micerrevt = (struct iw_michaelmicfailure *)&extra;
+ cmd = IWEVMICHAELMICFAILURE;
+ wrqu.data.length = sizeof(struct iw_michaelmicfailure);
+ if (flags & WLC_EVENT_MSG_GROUP)
+ micerrevt->flags |= IW_MICFAILURE_GROUP;
+ else
+ micerrevt->flags |= IW_MICFAILURE_PAIRWISE;
+ memcpy(micerrevt->src_addr.sa_data, &e->addr, ETHER_ADDR_LEN);
+ micerrevt->src_addr.sa_family = ARPHRD_ETHER;
+
+ break;
+ }
+
+ case WLC_E_ASSOC_REQ_IE:
+ cmd = IWEVASSOCREQIE;
+ wrqu.data.length = datalen;
+ if (datalen < sizeof(extra))
+ memcpy(extra, data, datalen);
+ break;
+
+ case WLC_E_ASSOC_RESP_IE:
+ cmd = IWEVASSOCRESPIE;
+ wrqu.data.length = datalen;
+ if (datalen < sizeof(extra))
+ memcpy(extra, data, datalen);
+ break;
+
+ case WLC_E_PMKID_CACHE: {
+ struct iw_pmkid_cand *iwpmkidcand = (struct iw_pmkid_cand *)&extra;
+ pmkid_cand_list_t *pmkcandlist;
+ pmkid_cand_t *pmkidcand;
+ int count;
+
+ if (data == NULL)
+ break;
+
+ cmd = IWEVPMKIDCAND;
+ pmkcandlist = data;
+ count = ntoh32_ua((uint8 *)&pmkcandlist->npmkid_cand);
+ wrqu.data.length = sizeof(struct iw_pmkid_cand);
+ pmkidcand = pmkcandlist->pmkid_cand;
+ while (count) {
+ bzero(iwpmkidcand, sizeof(struct iw_pmkid_cand));
+ if (pmkidcand->preauth)
+ iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH;
+ bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data,
+ ETHER_ADDR_LEN);
+ wireless_send_event(dev, cmd, &wrqu, extra);
+ pmkidcand++;
+ count--;
+ }
+ break;
+ }
+#endif /* WIRELESS_EXT > 17 */
+
+ case WLC_E_SCAN_COMPLETE:
+#if WIRELESS_EXT > 14
+ cmd = SIOCGIWSCAN;
+#endif
+ AP6210_DEBUG("event WLC_E_SCAN_COMPLETE\n");
+ if ((g_iscan) && (g_iscan->sysioc_pid >= 0) &&
+ (g_iscan->iscan_state != ISCAN_STATE_IDLE))
+ up(&g_iscan->sysioc_sem);
+ break;
+
+ default:
+ /* Cannot translate event */
+ break;
+ }
+
+ if (cmd) {
+ if (cmd == SIOCGIWSCAN)
+ wireless_send_event(dev, cmd, &wrqu, NULL);
+ else
+ wireless_send_event(dev, cmd, &wrqu, extra);
+ }
+
+#if WIRELESS_EXT > 14
+ /* Look for WLC events that indicate a connection failure.
+ * If found, generate an IWEVCUSTOM event.
+ */
+ memset(extra, 0, sizeof(extra));
+ if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) {
+ cmd = IWEVCUSTOM;
+ wrqu.data.length = strlen(extra);
+ wireless_send_event(dev, cmd, &wrqu, extra);
+ }
+#endif /* WIRELESS_EXT > 14 */
+
+#endif /* WIRELESS_EXT > 13 */
+}
+
+int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
+{
+ int res = 0;
+ wl_cnt_t cnt;
+ int phy_noise;
+ int rssi;
+ scb_val_t scb_val;
+
+ phy_noise = 0;
+ if ((res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise, sizeof(phy_noise))))
+ goto done;
+
+ phy_noise = dtoh32(phy_noise);
+ AP6210_DEBUG("wl_iw_get_wireless_stats phy noise=%d\n *****", phy_noise);
+
+ scb_val.val = 0;
+ if ((res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t))))
+ goto done;
+
+ rssi = dtoh32(scb_val.val);
+ AP6210_DEBUG("wl_iw_get_wireless_stats rssi=%d ****** \n", rssi);
+ if (rssi <= WL_IW_RSSI_NO_SIGNAL)
+ wstats->qual.qual = 0;
+ else if (rssi <= WL_IW_RSSI_VERY_LOW)
+ wstats->qual.qual = 1;
+ else if (rssi <= WL_IW_RSSI_LOW)
+ wstats->qual.qual = 2;
+ else if (rssi <= WL_IW_RSSI_GOOD)
+ wstats->qual.qual = 3;
+ else if (rssi <= WL_IW_RSSI_VERY_GOOD)
+ wstats->qual.qual = 4;
+ else
+ wstats->qual.qual = 5;
+
+ /* Wraps to 0 if RSSI is 0 */
+ wstats->qual.level = 0x100 + rssi;
+ wstats->qual.noise = 0x100 + phy_noise;
+#if WIRELESS_EXT > 18
+ wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM);
+#else
+ wstats->qual.updated |= 7;
+#endif /* WIRELESS_EXT > 18 */
+
+#if WIRELESS_EXT > 11
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters=%d\n *****", (int)sizeof(wl_cnt_t));
+
+ memset(&cnt, 0, sizeof(wl_cnt_t));
+ res = dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t));
+ if (res)
+ {
+ AP6210_ERR("wl_iw_get_wireless_stats counters failed error=%d ****** \n", res);
+ goto done;
+ }
+
+ cnt.version = dtoh16(cnt.version);
+ if (cnt.version != WL_CNT_T_VERSION) {
+ AP6210_DEBUG("\tIncorrect version of counters struct: expected %d; got %d\n",
+ WL_CNT_T_VERSION, cnt.version);
+ goto done;
+ }
+
+ wstats->discard.nwid = 0;
+ wstats->discard.code = dtoh32(cnt.rxundec);
+ wstats->discard.fragment = dtoh32(cnt.rxfragerr);
+ wstats->discard.retries = dtoh32(cnt.txfail);
+ wstats->discard.misc = dtoh32(cnt.rxrunt) + dtoh32(cnt.rxgiant);
+ wstats->miss.beacon = 0;
+
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n",
+ dtoh32(cnt.txframe), dtoh32(cnt.txbyte));
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", dtoh32(cnt.rxfrmtoolong));
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", dtoh32(cnt.rxbadplcp));
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxundec=%d\n", dtoh32(cnt.rxundec));
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxfragerr=%d\n", dtoh32(cnt.rxfragerr));
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters txfail=%d\n", dtoh32(cnt.txfail));
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxrunt=%d\n", dtoh32(cnt.rxrunt));
+ AP6210_DEBUG("wl_iw_get_wireless_stats counters rxgiant=%d\n", dtoh32(cnt.rxgiant));
+
+#endif /* WIRELESS_EXT > 11 */
+
+done:
+ return res;
+}
+
+static void
+wl_iw_timerfunc(ulong data)
+{
+ iscan_info_t *iscan = (iscan_info_t *)data;
+ iscan->timer_on = 0;
+ if (iscan->iscan_state != ISCAN_STATE_IDLE) {
+ AP6210_DEBUG("timer trigger\n");
+ up(&iscan->sysioc_sem);
+ }
+}
+
+static void
+wl_iw_set_event_mask(struct net_device *dev)
+{
+ char eventmask[WL_EVENTING_MASK_LEN];
+ char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */
+
+ dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf));
+ bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN);
+ setbit(eventmask, WLC_E_SCAN_COMPLETE);
+ dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN,
+ iovbuf, sizeof(iovbuf));
+
+}
+
+static int
+wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid)
+{
+ int err = 0;
+
+ memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
+ params->bss_type = DOT11_BSSTYPE_ANY;
+ params->scan_type = 0;
+ params->nprobes = -1;
+ params->active_time = -1;
+ params->passive_time = -1;
+ params->home_time = -1;
+ params->channel_num = 0;
+
+ params->nprobes = htod32(params->nprobes);
+ params->active_time = htod32(params->active_time);
+ params->passive_time = htod32(params->passive_time);
+ params->home_time = htod32(params->home_time);
+ if (ssid && ssid->SSID_len)
+ memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
+
+ return err;
+}
+
+static int
+wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action)
+{
+ int params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params));
+ wl_iscan_params_t *params;
+ int err = 0;
+
+ if (ssid && ssid->SSID_len) {
+ params_size += sizeof(wlc_ssid_t);
+ }
+ params = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL);
+ if (params == NULL) {
+ return -ENOMEM;
+ }
+ memset(params, 0, params_size);
+ ASSERT(params_size < WLC_IOCTL_SMLEN);
+
+ err = wl_iw_iscan_prep(&params->params, ssid);
+
+ if (!err) {
+ params->version = htod32(ISCAN_REQ_VERSION);
+ params->action = htod16(action);
+ params->scan_duration = htod16(0);
+
+ /* params_size += OFFSETOF(wl_iscan_params_t, params); */
+ (void) dev_iw_iovar_setbuf(iscan->dev, "iscan", params, params_size,
+ iscan->ioctlbuf, WLC_IOCTL_SMLEN);
+ }
+
+ kfree(params);
+ return err;
+}
+
+static uint32
+wl_iw_iscan_get(iscan_info_t *iscan)
+{
+ iscan_buf_t * buf;
+ iscan_buf_t * ptr;
+ wl_iscan_results_t * list_buf;
+ wl_iscan_results_t list;
+ wl_scan_results_t *results;
+ uint32 status;
+
+ /* buffers are allocated on demand */
+ if (iscan->list_cur) {
+ buf = iscan->list_cur;
+ iscan->list_cur = buf->next;
+ }
+ else {
+ buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL);
+ if (!buf)
+ return WL_SCAN_RESULTS_ABORTED;
+ buf->next = NULL;
+ if (!iscan->list_hdr)
+ iscan->list_hdr = buf;
+ else {
+ ptr = iscan->list_hdr;
+ while (ptr->next) {
+ ptr = ptr->next;
+ }
+ ptr->next = buf;
+ }
+ }
+ memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN);
+ list_buf = (wl_iscan_results_t*)buf->iscan_buf;
+ results = &list_buf->results;
+ results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+ results->version = 0;
+ results->count = 0;
+
+ memset(&list, 0, sizeof(list));
+ list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN);
+ (void) dev_iw_iovar_getbuf(
+ iscan->dev,
+ "iscanresults",
+ &list,
+ WL_ISCAN_RESULTS_FIXED_SIZE,
+ buf->iscan_buf,
+ WLC_IW_ISCAN_MAXLEN);
+ results->buflen = dtoh32(results->buflen);
+ results->version = dtoh32(results->version);
+ results->count = dtoh32(results->count);
+ AP6210_DEBUG("results->count = %d\n", results->count);
+
+ AP6210_DEBUG("results->buflen = %d\n", results->buflen);
+ status = dtoh32(list_buf->status);
+ return status;
+}
+
+static void wl_iw_send_scan_complete(iscan_info_t *iscan)
+{
+ union iwreq_data wrqu;
+
+ memset(&wrqu, 0, sizeof(wrqu));
+
+ /* wext expects to get no data for SIOCGIWSCAN Event */
+ wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL);
+}
+
+static int
+_iscan_sysioc_thread(void *data)
+{
+ uint32 status;
+ iscan_info_t *iscan = (iscan_info_t *)data;
+
+ DAEMONIZE("iscan_sysioc");
+
+ status = WL_SCAN_RESULTS_PARTIAL;
+ while (down_interruptible(&iscan->sysioc_sem) == 0) {
+ if (iscan->timer_on) {
+ del_timer(&iscan->timer);
+ iscan->timer_on = 0;
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ rtnl_lock();
+#endif
+ status = wl_iw_iscan_get(iscan);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ rtnl_unlock();
+#endif
+
+ switch (status) {
+ case WL_SCAN_RESULTS_PARTIAL:
+ AP6210_DEBUG("iscanresults incomplete\n");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ rtnl_lock();
+#endif
+ /* make sure our buffer size is enough before going next round */
+ wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+ rtnl_unlock();
+#endif
+ /* Reschedule the timer */
+ iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms);
+ add_timer(&iscan->timer);
+ iscan->timer_on = 1;
+ break;
+ case WL_SCAN_RESULTS_SUCCESS:
+ AP6210_DEBUG("iscanresults complete\n");
+ iscan->iscan_state = ISCAN_STATE_IDLE;
+ wl_iw_send_scan_complete(iscan);
+ break;
+ case WL_SCAN_RESULTS_PENDING:
+ AP6210_DEBUG("iscanresults pending\n");
+ /* Reschedule the timer */
+ iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms);
+ add_timer(&iscan->timer);
+ iscan->timer_on = 1;
+ break;
+ case WL_SCAN_RESULTS_ABORTED:
+ AP6210_DEBUG("iscanresults aborted\n");
+ iscan->iscan_state = ISCAN_STATE_IDLE;
+ wl_iw_send_scan_complete(iscan);
+ break;
+ default:
+ AP6210_DEBUG("iscanresults returned unknown status %d\n", status);
+ break;
+ }
+ }
+ complete_and_exit(&iscan->sysioc_exited, 0);
+}
+
+int
+wl_iw_attach(struct net_device *dev, void * dhdp)
+{
+ iscan_info_t *iscan = NULL;
+
+ if (!dev)
+ return 0;
+
+ iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL);
+ if (!iscan)
+ return -ENOMEM;
+ memset(iscan, 0, sizeof(iscan_info_t));
+ iscan->sysioc_pid = -1;
+ /* we only care about main interface so save a global here */
+ g_iscan = iscan;
+ iscan->dev = dev;
+ iscan->iscan_state = ISCAN_STATE_IDLE;
+
+
+ /* Set up the timer */
+ iscan->timer_ms = 2000;
+ init_timer(&iscan->timer);
+ iscan->timer.data = (ulong)iscan;
+ iscan->timer.function = wl_iw_timerfunc;
+
+ sema_init(&iscan->sysioc_sem, 0);
+ init_completion(&iscan->sysioc_exited);
+ iscan->sysioc_pid = kernel_thread(_iscan_sysioc_thread, iscan, 0);
+ if (iscan->sysioc_pid < 0)
+ return -ENOMEM;
+ return 0;
+}
+
+void wl_iw_detach(void)
+{
+ iscan_buf_t *buf;
+ iscan_info_t *iscan = g_iscan;
+ if (!iscan)
+ return;
+ if (iscan->sysioc_pid >= 0) {
+ KILL_PROC(iscan->sysioc_pid, SIGTERM);
+ wait_for_completion(&iscan->sysioc_exited);
+ }
+
+ while (iscan->list_hdr) {
+ buf = iscan->list_hdr->next;
+ kfree(iscan->list_hdr);
+ iscan->list_hdr = buf;
+ }
+ kfree(iscan);
+ g_iscan = NULL;
+}
+
+#endif /* USE_IW */
diff --git a/drivers/net/wireless/ap6210/wl_iw.h b/drivers/net/wireless/ap6210/wl_iw.h
new file mode 100644
index 0000000..c675a56
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_iw.h
@@ -0,0 +1,161 @@
+/*
+ * Linux Wireless Extensions support
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wl_iw.h 291086 2011-10-21 01:17:24Z $
+ */
+
+#ifndef _wl_iw_h_
+#define _wl_iw_h_
+
+#include <linux/wireless.h>
+
+#include <typedefs.h>
+#include <proto/ethernet.h>
+#include <wlioctl.h>
+
+#define WL_SCAN_PARAMS_SSID_MAX 10
+#define GET_SSID "SSID="
+#define GET_CHANNEL "CH="
+#define GET_NPROBE "NPROBE="
+#define GET_ACTIVE_ASSOC_DWELL "ACTIVE="
+#define GET_PASSIVE_ASSOC_DWELL "PASSIVE="
+#define GET_HOME_DWELL "HOME="
+#define GET_SCAN_TYPE "TYPE="
+
+#define BAND_GET_CMD "GETBAND"
+#define BAND_SET_CMD "SETBAND"
+#define DTIM_SKIP_GET_CMD "DTIMSKIPGET"
+#define DTIM_SKIP_SET_CMD "DTIMSKIPSET"
+#define SETSUSPEND_CMD "SETSUSPENDOPT"
+#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR"
+/* Lin - Is the extra space needed? */
+#define PNOSETUP_SET_CMD "PNOSETUP " /* TLV command has extra end space */
+#define PNOENABLE_SET_CMD "PNOFORCE"
+#define PNODEBUG_SET_CMD "PNODEBUG"
+#define TXPOWER_SET_CMD "TXPOWER"
+
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+/* Structure to keep global parameters */
+typedef struct wl_iw_extra_params {
+ int target_channel; /* target channel */
+} wl_iw_extra_params_t;
+
+struct cntry_locales_custom {
+ char iso_abbrev[WLC_CNTRY_BUF_SZ]; /* ISO 3166-1 country abbreviation */
+ char custom_locale[WLC_CNTRY_BUF_SZ]; /* Custom firmware locale */
+ int32 custom_locale_rev; /* Custom local revisin default -1 */
+};
+/* ============================================== */
+/* Defines from wlc_pub.h */
+#define WL_IW_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */
+#define WL_IW_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */
+#define WL_IW_RSSI_VERY_LOW -80 /* Very low quality cutoffs */
+#define WL_IW_RSSI_LOW -70 /* Low quality cutoffs */
+#define WL_IW_RSSI_GOOD -68 /* Good quality cutoffs */
+#define WL_IW_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */
+#define WL_IW_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */
+#define WL_IW_RSSI_INVALID 0 /* invalid RSSI value */
+#define MAX_WX_STRING 80
+#define SSID_FMT_BUF_LEN ((4 * 32) + 1)
+#define isprint(c) bcm_isprint(c)
+#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1)
+#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3)
+#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5)
+#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7)
+#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9)
+#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11)
+#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13)
+
+#define G_SCAN_RESULTS 8*1024
+#define WE_ADD_EVENT_FIX 0x80
+#define G_WLAN_SET_ON 0
+#define G_WLAN_SET_OFF 1
+
+
+typedef struct wl_iw {
+ char nickname[IW_ESSID_MAX_SIZE];
+
+ struct iw_statistics wstats;
+
+ int spy_num;
+ uint32 pwsec; /* pairwise wsec setting */
+ uint32 gwsec; /* group wsec setting */
+ bool privacy_invoked; /* IW_AUTH_PRIVACY_INVOKED setting */
+ struct ether_addr spy_addr[IW_MAX_SPY];
+ struct iw_quality spy_qual[IW_MAX_SPY];
+ void *wlinfo;
+} wl_iw_t;
+
+struct wl_ctrl {
+ struct timer_list *timer;
+ struct net_device *dev;
+ long sysioc_pid;
+ struct semaphore sysioc_sem;
+ struct completion sysioc_exited;
+};
+
+
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+extern const struct iw_handler_def wl_iw_handler_def;
+#endif /* WIRELESS_EXT > 12 */
+
+extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data);
+extern int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats);
+int wl_iw_attach(struct net_device *dev, void * dhdp);
+int wl_iw_send_priv_event(struct net_device *dev, char *flag);
+
+void wl_iw_detach(void);
+
+#define CSCAN_COMMAND "CSCAN "
+#define CSCAN_TLV_PREFIX 'S'
+#define CSCAN_TLV_VERSION 1
+#define CSCAN_TLV_SUBVERSION 0
+#define CSCAN_TLV_TYPE_SSID_IE 'S'
+#define CSCAN_TLV_TYPE_CHANNEL_IE 'C'
+#define CSCAN_TLV_TYPE_NPROBE_IE 'N'
+#define CSCAN_TLV_TYPE_ACTIVE_IE 'A'
+#define CSCAN_TLV_TYPE_PASSIVE_IE 'P'
+#define CSCAN_TLV_TYPE_HOME_IE 'H'
+#define CSCAN_TLV_TYPE_STYPE_IE 'T'
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
+ iwe_stream_add_event(info, stream, ends, iwe, extra)
+#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \
+ iwe_stream_add_value(info, event, value, ends, iwe, event_len)
+#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \
+ iwe_stream_add_point(info, stream, ends, iwe, extra)
+#else
+#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
+ iwe_stream_add_event(stream, ends, iwe, extra)
+#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \
+ iwe_stream_add_value(event, value, ends, iwe, event_len)
+#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \
+ iwe_stream_add_point(stream, ends, iwe, extra)
+#endif
+
+#endif /* _wl_iw_h_ */
diff --git a/drivers/net/wireless/ap6210/wl_linux_mon.c b/drivers/net/wireless/ap6210/wl_linux_mon.c
new file mode 100644
index 0000000..3210664
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wl_linux_mon.c
@@ -0,0 +1,422 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Linux monitor network interface
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_linux_mon.c 280623 2011-08-30 14:49:39Z $
+ */
+
+#include <osl.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <linux/ieee80211.h>
+#include <linux/rtnetlink.h>
+#include <net/ieee80211_radiotap.h>
+
+#include <wlioctl.h>
+#include <bcmutils.h>
+#include <dhd_dbg.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+
+#include <ap6210.h>
+
+typedef enum monitor_states
+{
+ MONITOR_STATE_DEINIT = 0x0,
+ MONITOR_STATE_INIT = 0x1,
+ MONITOR_STATE_INTERFACE_ADDED = 0x2,
+ MONITOR_STATE_INTERFACE_DELETED = 0x4
+} monitor_states_t;
+int dhd_add_monitor(char *name, struct net_device **new_ndev);
+extern int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
+int dhd_del_monitor(struct net_device *ndev);
+int dhd_monitor_init(void *dhd_pub);
+int dhd_monitor_uninit(void);
+
+/**
+ * Local declarations and defintions (not exposed)
+ */
+#ifndef DHD_MAX_IFS
+#define DHD_MAX_IFS 16
+#endif
+
+typedef struct monitor_interface {
+ int radiotap_enabled;
+ struct net_device* real_ndev; /* The real interface that the monitor is on */
+ struct net_device* mon_ndev;
+} monitor_interface;
+
+typedef struct dhd_linux_monitor {
+ void *dhd_pub;
+ monitor_states_t monitor_state;
+ monitor_interface mon_if[DHD_MAX_IFS];
+ struct mutex lock; /* lock to protect mon_if */
+} dhd_linux_monitor_t;
+
+static dhd_linux_monitor_t g_monitor;
+
+static struct net_device* lookup_real_netdev(char *name);
+static monitor_interface* ndev_to_monif(struct net_device *ndev);
+static int dhd_mon_if_open(struct net_device *ndev);
+static int dhd_mon_if_stop(struct net_device *ndev);
+static int dhd_mon_if_subif_start_xmit(struct sk_buff *skb, struct net_device *ndev);
+static void dhd_mon_if_set_multicast_list(struct net_device *ndev);
+static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr);
+
+static const struct net_device_ops dhd_mon_if_ops = {
+ .ndo_open = dhd_mon_if_open,
+ .ndo_stop = dhd_mon_if_stop,
+ .ndo_start_xmit = dhd_mon_if_subif_start_xmit,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
+ .ndo_set_rx_mode = dhd_mon_if_set_multicast_list,
+#else
+ .ndo_set_multicast_list = dhd_mon_if_set_multicast_list,
+#endif
+ .ndo_set_mac_address = dhd_mon_if_change_mac,
+};
+
+/**
+ * Local static function defintions
+ */
+
+/* Look up dhd's net device table to find a match (e.g. interface "eth0" is a match for "mon.eth0"
+ * "p2p-eth0-0" is a match for "mon.p2p-eth0-0")
+ */
+static struct net_device* lookup_real_netdev(char *name)
+{
+ struct net_device *ndev_found = NULL;
+
+ int i;
+ int len = 0;
+ int last_name_len = 0;
+ struct net_device *ndev;
+
+ /* We need to find interface "p2p-p2p-0" corresponding to monitor interface "mon-p2p-0",
+ * Once mon iface name reaches IFNAMSIZ, it is reset to p2p0-0 and corresponding mon
+ * iface would be mon-p2p0-0.
+ */
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ ndev = dhd_idx2net(g_monitor.dhd_pub, i);
+
+ /* Skip "p2p" and look for "-p2p0-x" in monitor interface name. If it
+ * it matches, then this netdev is the corresponding real_netdev.
+ */
+ if (ndev && strstr(ndev->name, "p2p-p2p0")) {
+ len = strlen("p2p");
+ } else {
+ /* if p2p- is not present, then the IFNAMSIZ have reached and name
+ * would have got reset. In this casse,look for p2p0-x in mon-p2p0-x
+ */
+ len = 0;
+ }
+ if (ndev && strstr(name, (ndev->name + len))) {
+ if (strlen(ndev->name) > last_name_len) {
+ ndev_found = ndev;
+ last_name_len = strlen(ndev->name);
+ }
+ }
+ }
+
+ return ndev_found;
+}
+
+static monitor_interface* ndev_to_monif(struct net_device *ndev)
+{
+ int i;
+
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ if (g_monitor.mon_if[i].mon_ndev == ndev)
+ return &g_monitor.mon_if[i];
+ }
+
+ return NULL;
+}
+
+static int dhd_mon_if_open(struct net_device *ndev)
+{
+ int ret = 0;
+
+ AP6210_DEBUG("enter\n");
+ return ret;
+}
+
+static int dhd_mon_if_stop(struct net_device *ndev)
+{
+ int ret = 0;
+
+ AP6210_DEBUG("enter\n");
+ return ret;
+}
+
+static int dhd_mon_if_subif_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ int ret = 0;
+ int rtap_len;
+ int qos_len = 0;
+ int dot11_hdr_len = 24;
+ int snap_len = 6;
+ unsigned char *pdata;
+ unsigned short frame_ctl;
+ unsigned char src_mac_addr[6];
+ unsigned char dst_mac_addr[6];
+ struct ieee80211_hdr *dot11_hdr;
+ struct ieee80211_radiotap_header *rtap_hdr;
+ monitor_interface* mon_if;
+
+ AP6210_DEBUG("enter\n");
+
+ mon_if = ndev_to_monif(ndev);
+ if (mon_if == NULL || mon_if->real_ndev == NULL) {
+ AP6210_DEBUG(" cannot find matched net dev, skip the packet\n");
+ goto fail;
+ }
+
+ if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
+ goto fail;
+
+ rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
+ if (unlikely(rtap_hdr->it_version))
+ goto fail;
+
+ rtap_len = ieee80211_get_radiotap_len(skb->data);
+ if (unlikely(skb->len < rtap_len))
+ goto fail;
+
+ AP6210_DEBUG("radiotap len (should be 14): %d\n", rtap_len);
+
+ /* Skip the ratio tap header */
+ skb_pull(skb, rtap_len);
+
+ dot11_hdr = (struct ieee80211_hdr *)skb->data;
+ frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
+ /* Check if the QoS bit is set */
+ if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
+ /* Check if this ia a Wireless Distribution System (WDS) frame
+ * which has 4 MAC addresses
+ */
+ if (dot11_hdr->frame_control & 0x0080)
+ qos_len = 2;
+ if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
+ dot11_hdr_len += 6;
+
+ memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
+ memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
+
+ /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
+ * for two MAC addresses
+ */
+ skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
+ pdata = (unsigned char*)skb->data;
+ memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
+ memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
+ PKTSETPRIO(skb, 0);
+
+ AP6210_DEBUG("if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name);
+
+ /* Use the real net device to transmit the packet */
+ ret = dhd_start_xmit(skb, mon_if->real_ndev);
+
+ return ret;
+ }
+fail:
+ dev_kfree_skb(skb);
+ return 0;
+}
+
+static void dhd_mon_if_set_multicast_list(struct net_device *ndev)
+{
+ monitor_interface* mon_if;
+
+ mon_if = ndev_to_monif(ndev);
+ if (mon_if == NULL || mon_if->real_ndev == NULL) {
+ AP6210_DEBUG(" cannot find matched net dev, skip the packet\n");
+ } else {
+ AP6210_DEBUG("enter, if name: %s, matched if name %s\n",
+ ndev->name, mon_if->real_ndev->name);
+ }
+}
+
+static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr)
+{
+ int ret = 0;
+ monitor_interface* mon_if;
+
+ mon_if = ndev_to_monif(ndev);
+ if (mon_if == NULL || mon_if->real_ndev == NULL) {
+ AP6210_DEBUG(" cannot find matched net dev, skip the packet\n");
+ } else {
+ AP6210_DEBUG("enter, if name: %s, matched if name %s\n",
+ ndev->name, mon_if->real_ndev->name);
+ }
+ return ret;
+}
+
+/**
+ * Global function definitions (declared in dhd_linux_mon.h)
+ */
+
+int dhd_add_monitor(char *name, struct net_device **new_ndev)
+{
+ int i;
+ int idx = -1;
+ int ret = 0;
+ struct net_device* ndev = NULL;
+ dhd_linux_monitor_t **dhd_mon;
+
+ mutex_lock(&g_monitor.lock);
+
+ AP6210_DEBUG("enter, if name: %s\n", name);
+ if (!name || !new_ndev) {
+ AP6210_DEBUG("invalid parameters\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * Find a vacancy
+ */
+ for (i = 0; i < DHD_MAX_IFS; i++)
+ if (g_monitor.mon_if[i].mon_ndev == NULL) {
+ idx = i;
+ break;
+ }
+ if (idx == -1) {
+ AP6210_DEBUG("exceeds maximum interfaces\n");
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ndev = alloc_etherdev(sizeof(dhd_linux_monitor_t*));
+ if (!ndev) {
+ AP6210_DEBUG("failed to allocate memory\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ndev->type = ARPHRD_IEEE80211_RADIOTAP;
+ strncpy(ndev->name, name, IFNAMSIZ);
+ ndev->name[IFNAMSIZ - 1] = 0;
+ ndev->netdev_ops = &dhd_mon_if_ops;
+
+ ret = register_netdevice(ndev);
+ if (ret) {
+ AP6210_DEBUG(" register_netdevice failed (%d)\n", ret);
+ goto out;
+ }
+
+ *new_ndev = ndev;
+ g_monitor.mon_if[idx].radiotap_enabled = TRUE;
+ g_monitor.mon_if[idx].mon_ndev = ndev;
+ g_monitor.mon_if[idx].real_ndev = lookup_real_netdev(name);
+ dhd_mon = (dhd_linux_monitor_t **)netdev_priv(ndev);
+ *dhd_mon = &g_monitor;
+ g_monitor.monitor_state = MONITOR_STATE_INTERFACE_ADDED;
+ AP6210_DEBUG("net device returned: 0x%p\n", ndev);
+ AP6210_DEBUG("found a matched net device, name %s\n", g_monitor.mon_if[idx].real_ndev->name);
+
+out:
+ if (ret && ndev)
+ free_netdev(ndev);
+
+ mutex_unlock(&g_monitor.lock);
+ return ret;
+
+}
+
+int dhd_del_monitor(struct net_device *ndev)
+{
+ int i;
+ bool rollback_lock = false;
+ if (!ndev)
+ return -EINVAL;
+ mutex_lock(&g_monitor.lock);
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ if (g_monitor.mon_if[i].mon_ndev == ndev ||
+ g_monitor.mon_if[i].real_ndev == ndev) {
+ g_monitor.mon_if[i].real_ndev = NULL;
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
+ unregister_netdev(g_monitor.mon_if[i].mon_ndev);
+ free_netdev(g_monitor.mon_if[i].mon_ndev);
+ g_monitor.mon_if[i].mon_ndev = NULL;
+ g_monitor.monitor_state = MONITOR_STATE_INTERFACE_DELETED;
+ break;
+ }
+ }
+ if (rollback_lock) {
+ rtnl_lock();
+ rollback_lock = false;
+ }
+
+ if (g_monitor.monitor_state !=
+ MONITOR_STATE_INTERFACE_DELETED)
+ AP6210_DEBUG("interface not found in monitor IF array, is this a monitor IF? 0x%p\n",
+ ndev);
+ mutex_unlock(&g_monitor.lock);
+
+ return 0;
+}
+
+int dhd_monitor_init(void *dhd_pub)
+{
+ if (g_monitor.monitor_state == MONITOR_STATE_DEINIT) {
+ g_monitor.dhd_pub = dhd_pub;
+ mutex_init(&g_monitor.lock);
+ g_monitor.monitor_state = MONITOR_STATE_INIT;
+ }
+ return 0;
+}
+
+int dhd_monitor_uninit(void)
+{
+ int i;
+ struct net_device *ndev;
+ bool rollback_lock = false;
+ mutex_lock(&g_monitor.lock);
+ if (g_monitor.monitor_state != MONITOR_STATE_DEINIT) {
+ for (i = 0; i < DHD_MAX_IFS; i++) {
+ ndev = g_monitor.mon_if[i].mon_ndev;
+ if (ndev) {
+ if (rtnl_is_locked()) {
+ rtnl_unlock();
+ rollback_lock = true;
+ }
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+ g_monitor.mon_if[i].real_ndev = NULL;
+ g_monitor.mon_if[i].mon_ndev = NULL;
+ if (rollback_lock) {
+ rtnl_lock();
+ rollback_lock = false;
+ }
+ }
+ }
+ g_monitor.monitor_state = MONITOR_STATE_DEINIT;
+ }
+ mutex_unlock(&g_monitor.lock);
+ return 0;
+}
diff --git a/drivers/net/wireless/ap6210/wldev_common.c b/drivers/net/wireless/ap6210/wldev_common.c
new file mode 100644
index 0000000..596e448
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wldev_common.c
@@ -0,0 +1,374 @@
+/*
+ * Common function shared by Linux WEXT, cfg80211 and p2p drivers
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wldev_common.c,v 1.1.4.1.2.14 2011-02-09 01:40:07 $
+ */
+
+#include <osl.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/netdevice.h>
+
+#include <wldev_common.h>
+#include <bcmutils.h>
+
+#include <ap6210.h>
+
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+
+extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd);
+
+s32 wldev_ioctl(
+ struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)
+{
+ s32 ret = 0;
+ struct wl_ioctl ioc;
+
+
+ memset(&ioc, 0, sizeof(ioc));
+ ioc.cmd = cmd;
+ ioc.buf = arg;
+ ioc.len = len;
+ ioc.set = set;
+
+ ret = dhd_ioctl_entry_local(dev, &ioc, cmd);
+
+ return ret;
+}
+
+/* Format a iovar buffer, not bsscfg indexed. The bsscfg index will be
+ * taken care of in dhd_ioctl_entry. Internal use only, not exposed to
+ * wl_iw, wl_cfg80211 and wl_cfgp2p
+ */
+static s32 wldev_mkiovar(
+ s8 *iovar_name, s8 *param, s32 paramlen,
+ s8 *iovar_buf, u32 buflen)
+{
+ s32 iolen = 0;
+
+ iolen = bcm_mkiovar(iovar_name, param, paramlen, iovar_buf, buflen);
+ return iolen;
+}
+
+s32 wldev_iovar_getbuf(
+ struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
+{
+ s32 ret = 0;
+ if (buf_sync) {
+ mutex_lock(buf_sync);
+ }
+ wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
+ ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
+ if (buf_sync)
+ mutex_unlock(buf_sync);
+ return ret;
+}
+
+
+s32 wldev_iovar_setbuf(
+ struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
+{
+ s32 ret = 0;
+ s32 iovar_len;
+ if (buf_sync) {
+ mutex_lock(buf_sync);
+ }
+ iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
+ if (iovar_len > 0)
+ ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE);
+ else
+ ret = BCME_BUFTOOSHORT;
+ if (buf_sync)
+ mutex_unlock(buf_sync);
+ return ret;
+}
+
+s32 wldev_iovar_setint(
+ struct net_device *dev, s8 *iovar, s32 val)
+{
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+
+ val = htod32(val);
+ memset(iovar_buf, 0, sizeof(iovar_buf));
+ return wldev_iovar_setbuf(dev, iovar, &val, sizeof(val), iovar_buf,
+ sizeof(iovar_buf), NULL);
+}
+
+
+s32 wldev_iovar_getint(
+ struct net_device *dev, s8 *iovar, s32 *pval)
+{
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+ s32 err;
+
+ memset(iovar_buf, 0, sizeof(iovar_buf));
+ err = wldev_iovar_getbuf(dev, iovar, pval, sizeof(*pval), iovar_buf,
+ sizeof(iovar_buf), NULL);
+ if (err == 0)
+ {
+ memcpy(pval, iovar_buf, sizeof(*pval));
+ *pval = dtoh32(*pval);
+ }
+ return err;
+}
+
+/** Format a bsscfg indexed iovar buffer. The bsscfg index will be
+ * taken care of in dhd_ioctl_entry. Internal use only, not exposed to
+ * wl_iw, wl_cfg80211 and wl_cfgp2p
+ */
+s32 wldev_mkiovar_bsscfg(
+ const s8 *iovar_name, s8 *param, s32 paramlen,
+ s8 *iovar_buf, s32 buflen, s32 bssidx)
+{
+ const s8 *prefix = "bsscfg:";
+ s8 *p;
+ u32 prefixlen;
+ u32 namelen;
+ u32 iolen;
+
+ if (bssidx == 0) {
+ return wldev_mkiovar((s8*)iovar_name, (s8 *)param, paramlen,
+ (s8 *) iovar_buf, buflen);
+ }
+
+ prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */
+ namelen = (u32) strlen(iovar_name) + 1; /* lengh of iovar name + null */
+ iolen = prefixlen + namelen + sizeof(u32) + paramlen;
+
+ if (buflen < 0 || iolen > (u32)buflen)
+ {
+ AP6210_ERR("%s: buffer is too short\n", __FUNCTION__);
+ return BCME_BUFTOOSHORT;
+ }
+
+ p = (s8 *)iovar_buf;
+
+ /* copy prefix, no null */
+ memcpy(p, prefix, prefixlen);
+ p += prefixlen;
+
+ /* copy iovar name including null */
+ memcpy(p, iovar_name, namelen);
+ p += namelen;
+
+ /* bss config index as first param */
+ bssidx = htod32(bssidx);
+ memcpy(p, &bssidx, sizeof(u32));
+ p += sizeof(u32);
+
+ /* parameter buffer follows */
+ if (paramlen)
+ memcpy(p, param, paramlen);
+
+ return iolen;
+
+}
+
+s32 wldev_iovar_getbuf_bsscfg(
+ struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
+{
+ s32 ret = 0;
+ if (buf_sync) {
+ mutex_lock(buf_sync);
+ }
+
+ wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
+ ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
+ if (buf_sync) {
+ mutex_unlock(buf_sync);
+ }
+ return ret;
+
+}
+
+s32 wldev_iovar_setbuf_bsscfg(
+ struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
+{
+ s32 ret = 0;
+ s32 iovar_len;
+ if (buf_sync) {
+ mutex_lock(buf_sync);
+ }
+ iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
+ if (iovar_len > 0)
+ ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE);
+ else {
+ ret = BCME_BUFTOOSHORT;
+ }
+
+ if (buf_sync) {
+ mutex_unlock(buf_sync);
+ }
+ return ret;
+}
+
+s32 wldev_iovar_setint_bsscfg(
+ struct net_device *dev, s8 *iovar, s32 val, s32 bssidx)
+{
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+
+ val = htod32(val);
+ memset(iovar_buf, 0, sizeof(iovar_buf));
+ return wldev_iovar_setbuf_bsscfg(dev, iovar, &val, sizeof(val), iovar_buf,
+ sizeof(iovar_buf), bssidx, NULL);
+}
+
+
+s32 wldev_iovar_getint_bsscfg(
+ struct net_device *dev, s8 *iovar, s32 *pval, s32 bssidx)
+{
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+ s32 err;
+
+ memset(iovar_buf, 0, sizeof(iovar_buf));
+ err = wldev_iovar_getbuf_bsscfg(dev, iovar, pval, sizeof(*pval), iovar_buf,
+ sizeof(iovar_buf), bssidx, NULL);
+ if (err == 0)
+ {
+ memcpy(pval, iovar_buf, sizeof(*pval));
+ *pval = dtoh32(*pval);
+ }
+ return err;
+}
+
+int wldev_get_link_speed(
+ struct net_device *dev, int *plink_speed)
+{
+ int error;
+
+ if (!plink_speed)
+ return -ENOMEM;
+ error = wldev_ioctl(dev, WLC_GET_RATE, plink_speed, sizeof(int), 0);
+ if (unlikely(error))
+ return error;
+
+ /* Convert internal 500Kbps to Kbps */
+ *plink_speed *= 500;
+ return error;
+}
+
+int wldev_get_rssi(
+ struct net_device *dev, int *prssi)
+{
+ scb_val_t scb_val;
+ int error;
+
+ if (!prssi)
+ return -ENOMEM;
+ bzero(&scb_val, sizeof(scb_val_t));
+
+ error = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t), 0);
+ if (unlikely(error))
+ return error;
+
+ *prssi = dtoh32(scb_val.val);
+ return error;
+}
+
+int wldev_get_ssid(
+ struct net_device *dev, wlc_ssid_t *pssid)
+{
+ int error;
+
+ if (!pssid)
+ return -ENOMEM;
+ error = wldev_ioctl(dev, WLC_GET_SSID, pssid, sizeof(wlc_ssid_t), 0);
+ if (unlikely(error))
+ return error;
+ pssid->SSID_len = dtoh32(pssid->SSID_len);
+ return error;
+}
+
+int wldev_get_band(
+ struct net_device *dev, uint *pband)
+{
+ int error;
+
+ error = wldev_ioctl(dev, WLC_GET_BAND, pband, sizeof(uint), 0);
+ return error;
+}
+
+int wldev_set_band(
+ struct net_device *dev, uint band)
+{
+ int error = -1;
+
+ if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) {
+ error = wldev_ioctl(dev, WLC_SET_BAND, &band, sizeof(band), true);
+ if (!error)
+ dhd_bus_band_set(dev, band);
+ }
+ return error;
+}
+
+int wldev_set_country(
+ struct net_device *dev, char *country_code)
+{
+ int error = -1;
+ wl_country_t cspec = {{0}, 0, {0}};
+ scb_val_t scbval;
+ char smbuf[WLC_IOCTL_SMLEN];
+
+ if (!country_code)
+ return error;
+
+ error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec),
+ smbuf, sizeof(smbuf), NULL);
+ if (error < 0)
+ AP6210_ERR("%s: get country failed = %d\n", __FUNCTION__, error);
+
+ if ((error < 0) ||
+ (strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) {
+ bzero(&scbval, sizeof(scb_val_t));
+ error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
+ if (error < 0) {
+ AP6210_ERR("%s: set country failed due to Disassoc error %d\n",
+ __FUNCTION__, error);
+ return error;
+ }
+ cspec.rev = -1;
+ memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
+ memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
+ get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
+ error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
+ smbuf, sizeof(smbuf), NULL);
+ if (error < 0) {
+ AP6210_ERR("%s: set country for %s as %s rev %d failed\n",
+ __FUNCTION__, country_code, cspec.ccode, cspec.rev);
+ return error;
+ }
+ dhd_bus_country_set(dev, &cspec);
+ AP6210_ERR("%s: set country for %s as %s rev %d\n",
+ __FUNCTION__, country_code, cspec.ccode, cspec.rev);
+ }
+ return 0;
+}
diff --git a/drivers/net/wireless/ap6210/wldev_common.h b/drivers/net/wireless/ap6210/wldev_common.h
new file mode 100644
index 0000000..f9bf425
--- /dev/null
+++ b/drivers/net/wireless/ap6210/wldev_common.h
@@ -0,0 +1,111 @@
+/*
+ * Common function shared by Linux WEXT, cfg80211 and p2p drivers
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: wldev_common.h,v 1.1.4.1.2.14 2011-02-09 01:40:07 $
+ */
+#ifndef __WLDEV_COMMON_H__
+#define __WLDEV_COMMON_H__
+
+#include <wlioctl.h>
+
+/* wl_dev_ioctl - get/set IOCTLs, will call net_device's do_ioctl (or
+ * netdev_ops->ndo_do_ioctl in new kernels)
+ * @dev: the net_device handle
+ */
+s32 wldev_ioctl(
+ struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set);
+
+/** Retrieve named IOVARs, this function calls wl_dev_ioctl with
+ * WLC_GET_VAR IOCTL code
+ */
+s32 wldev_iovar_getbuf(
+ struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync);
+
+/** Set named IOVARs, this function calls wl_dev_ioctl with
+ * WLC_SET_VAR IOCTL code
+ */
+s32 wldev_iovar_setbuf(
+ struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync);
+
+s32 wldev_iovar_setint(
+ struct net_device *dev, s8 *iovar, s32 val);
+
+s32 wldev_iovar_getint(
+ struct net_device *dev, s8 *iovar, s32 *pval);
+
+/** The following function can be implemented if there is a need for bsscfg
+ * indexed IOVARs
+ */
+
+s32 wldev_mkiovar_bsscfg(
+ const s8 *iovar_name, s8 *param, s32 paramlen,
+ s8 *iovar_buf, s32 buflen, s32 bssidx);
+
+/** Retrieve named and bsscfg indexed IOVARs, this function calls wl_dev_ioctl with
+ * WLC_GET_VAR IOCTL code
+ */
+s32 wldev_iovar_getbuf_bsscfg(
+ struct net_device *dev, s8 *iovar_name, void *param, s32 paramlen,
+ void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync);
+
+/** Set named and bsscfg indexed IOVARs, this function calls wl_dev_ioctl with
+ * WLC_SET_VAR IOCTL code
+ */
+s32 wldev_iovar_setbuf_bsscfg(
+ struct net_device *dev, s8 *iovar_name, void *param, s32 paramlen,
+ void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync);
+
+s32 wldev_iovar_getint_bsscfg(
+ struct net_device *dev, s8 *iovar, s32 *pval, s32 bssidx);
+
+s32 wldev_iovar_setint_bsscfg(
+ struct net_device *dev, s8 *iovar, s32 val, s32 bssidx);
+
+extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec);
+extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec);
+extern void dhd_bus_band_set(struct net_device *dev, uint band);
+extern int wldev_set_country(struct net_device *dev, char *country_code);
+extern int net_os_wake_lock(struct net_device *dev);
+extern int net_os_wake_unlock(struct net_device *dev);
+extern int net_os_wake_lock_timeout(struct net_device *dev);
+extern int net_os_wake_lock_timeout_enable(struct net_device *dev, int val);
+extern int net_os_set_dtim_skip(struct net_device *dev, int val);
+extern int net_os_set_suspend_disable(struct net_device *dev, int val);
+extern int net_os_set_suspend(struct net_device *dev, int val, int force);
+extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid,
+ int max, int *bytes_left);
+
+/* Get the link speed from dongle, speed is in kpbs */
+int wldev_get_link_speed(struct net_device *dev, int *plink_speed);
+
+int wldev_get_rssi(struct net_device *dev, int *prssi);
+
+int wldev_get_ssid(struct net_device *dev, wlc_ssid_t *pssid);
+
+int wldev_get_band(struct net_device *dev, uint *pband);
+
+int wldev_set_band(struct net_device *dev, uint band);
+
+#endif /* __WLDEV_COMMON_H__ */
diff --git a/firmware/Makefile b/firmware/Makefile
index 0d15a3d..934cd24 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -109,6 +109,10 @@ fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \
fw-shipped-$(CONFIG_USB_KAWETH) += kaweth/new_code.bin kaweth/trigger_code.bin \
kaweth/new_code_fix.bin \
kaweth/trigger_code_fix.bin
+fw-shipped-$(CONFIG_AP6210) += ap6210/bcm20710a1.hcd ap6210/fw_bcm40181a2.bin \
+ ap6210/fw_bcm40181a2_apsta.bin \
+ ap6210/fw_bcm40181a2_p2p.bin \
+ ap6210/nvram_ap6210.txt
ifdef CONFIG_FIRMWARE_IN_KERNEL
fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_MPR) += keyspan/mpr.fw
fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_USA18X) += keyspan/usa18x.fw
diff --git a/firmware/ap6210/bcm20710a1.hcd.ihex b/firmware/ap6210/bcm20710a1.hcd.ihex
new file mode 100644
index 0000000..28e8935
--- /dev/null
+++ b/firmware/ap6210/bcm20710a1.hcd.ihex
@@ -0,0 +1,1665 @@
+:100000004CFC2C00000900010800EEC4EC420790F3
+:100010006524FD0400FFFFFFFF4006000000A00272
+:100020007020020A00280009000000000000004CB7
+:10003000FCFF2800090041290042434D323037308F
+:100040003241312047656E657269632055415254D3
+:1000500020436C61737320312040203236204D489C
+:100060007A0069020000005D0C000A64E6B000003E
+:100070008898425A33435F09003C28010004000479
+:10008000F70C0A6F0098160800C600F3025D0066C0
+:10009000033000C900E10268005C033600C300E2DF
+:1000A000026A0053033C00C200E1026C004E0341AF
+:1000B00000C500D60272004A034300C300CE027995
+:1000C0000042034800C500C00283003A034E00C846
+:1000D00000BF0282003B034E00C900BC028400370F
+:1000E0000352000808070707070707060606060564
+:1000F00005050502C0680194FC0E00FFFF000066C4
+:1001000002000030FC0E00FFFF0F0063040000003F
+:10011000FD0E00FFFF0F006802000088FC0E00FFCC
+:10012000FF0000000400002CFC0E00FFFF0000494F
+:10013000044CFCFF23010900000070FC0E00FFFFCF
+:1001400000000B09000074FC0E00FFFF00002E01F0
+:100150000000D8FF0E00FFFF000062190000D0FC75
+:100160000E00FFFF000020C90000C8FC0E00FFFFCA
+:10017000000038850000DCFC0E00FFFF00001CC8FA
+:100180000000CCFD0E00FFFF0000048000005CFCBE
+:100190000E00FFFF00000200000020FC0E00FFFF29
+:1001A000000019210000E0FC0E00008000000000AB
+:1001B0000000C0FC0E00FFFF000022000000948F32
+:1001C0000800FFFFFFFF00120012988F0800FFFFDA
+:1001D0000000001200009C8F080000FFFFFF0009D4
+:1001E0000909CCFC0E00FFFF00002B450000780041
+:1001F0000F00FFFFFFFF0D08090968000F00FF0057
+:10020000FFFF0D000D0D6C000F00FF00FFFF0D0044
+:100210000D0D90000F00000000FF000000800C0199
+:100220000F000000FFFF0000080888000F00F0002A
+:100230000000804CFCFF1E0209000000002C010F92
+:1002400000FF0000000700000024010F0000000074
+:10025000FF0000000530010F0000FF000000080053
+:100260000020010F00000000FF00000006D07B000E
+:1002700001040A08FC0E00FFFF00002E3600000CEF
+:10028000FC0E00FFFF00002CAE000010FC0E00FF73
+:10029000FF00002AAC000014FC0E00FFFF0000A2CB
+:1002A00022000018FC0E00FFFF00001D2000001CB3
+:1002B000FC0E00FFFF00000D15000020FC0E00FFEB
+:1002C000FF0000858D000024FC0E00FFFF0000836E
+:1002D00011000028FC0E00FFFF0000000100009844
+:1002E000FF0E00FFFF00003E410000C31600126930
+:1002F0001419310870047836042430607180764A0D
+:100300003108290A6F210002301905CB000000BA1C
+:10031000147F7100A700000092000000001400008C
+:1003200000000000000000000A0800F40A080000B5
+:1003300001000058014CFCFF19030900001FCF0900
+:1003400000100F0C6EF0B009F060D1090001040339
+:10035000036B1420206B1A2400FF0108080A1306FF
+:1003600011020FFE0DFA0BF609F207EE050A13064D
+:1003700011020FFE0DFA0BF609F207EE050301005C
+:100380000182D600040602020A233C5A6E7D8000D8
+:100390008000800080008000800080028002800257
+:1003A00080028002800214FF20880AFF61000000A2
+:1003B0000000000000000000000014FF20820AFF7F
+:1003C000610000000000000000000000000014FFB9
+:1003D00020000AFF61000000000000000000000093
+:1003E000000014FF20080AFF610000000000000068
+:1003F00000000000000014FF200B0AFF6100000055
+:100400000000000000000000000014FF20100AFFA0
+:10041000610000000000000000000000000040FF3C
+:10042000FF68027B0000000040FFFF68027B0000C5
+:10043000000040FFFF68024CFCFF140409007B0031
+:1004400000000040FFFF68027B0000000040FFFF4B
+:1004500069027B0000000040FFFF69027B00000092
+:100460000082D600FF0602020A233C5A6E7D8000FD
+:100470008000800080008000800080028002800276
+:1004800080028002800214FF19880AFF2000000009
+:100490000000000000000000000014FF19820AFFA5
+:1004A000430000000000000000000000000014FFF6
+:1004B00019000AFF660000000000000000000000B4
+:1004C000000014FF19080AFF660000000000000089
+:1004D00000000000000014FF190B0AFF4300000099
+:1004E0000000000000000000000014FF19100AFFC7
+:1004F000200000000000000000000000000041009B
+:100500000000007B0000000041000000007B0000B4
+:10051000000041000000007B0000000041000000DE
+:10052000007B0000000041000000007B0000000094
+:1005300041000000007B0000004CFCFF0F0509009B
+:100540000086120004130040080000401300010060
+:100550000180FF000113C15E007CCB1E85B47CCB03
+:100560001E85B42604B104B204B304B404B504B6C1
+:1005700004B704B804B904BA04BB04BC04BD04BE87
+:1005800004BF04C004C104C204C304C404C504C637
+:1005900004C704C804C904CA04CB04CC04CD04CEE7
+:1005A00004CF04D004D104D204D304D404D504D697
+:1005B00004D704D8280C000B04000E4C09000B04CF
+:1005C00000E44C09000B0400524E0900082500000D
+:1005D000B0DB010078F01EFC1600F0630900281C57
+:1005E000FEF733FF281C5F3000210170391C321DDB
+:1005F00087F7D7FB080F000184E0000030BD00B58D
+:100600000000000000000817000288E0000087F0EA
+:1006100048F908001C53090000F002F800BD000072
+:10062000081D0003C46200008FF059FB0E007A59C8
+:10063000090001B4FFF769FF01BC704CFCFF0A061A
+:100640000900F7A9FC000008150004586600008F97
+:10065000F08CF9060074590900FFF796FF30BD0BC6
+:1006600004001A5B09000B0400445B090008150034
+:1006700005C08400008DF000FE0600C4600900FF84
+:10068000F7A6FF30BD082D0006B47702006EF08992
+:10069000FC1E00CA60090002B461684907C90F3036
+:1006A0001C91F7F5FC02BC002902D0F06991F76AB1
+:1006B000FB91F76CFB080F000724B500000FE0C0AA
+:1006C00046000000000000080F0008C44F000010A2
+:1006D000E0C046000000000000086700091CF003AD
+:1006E0000057F064F85800E860090070B5061C0C6B
+:1006F0001C151C002B21D104A8008840281DD10501
+:10070000A80088202819D15A2917D8081C15D00408
+:10071000F0BEF8002811D1032D0FD02204121408C6
+:10072000210748002304F0BBF8002806D1221C2929
+:100730001C301CA9F733F8012000E000204CFCFF1E
+:100740000507090070BD18650800080F000A9880A9
+:1007500000005808042B0000000000000817000BE0
+:10076000680C040055F06AFA08004061090000F0C6
+:1007700002F870BD00000819000C64D4000088F075
+:10078000EEFE0A0044620900281CFEF7E3FF77F73B
+:1007900020F90813000D08D6000088F021FE04009F
+:1007A0004E62090077F7DEF9080F000E80DA0000CC
+:1007B000C046C0460000000000000815000F24528B
+:1007C000000091F015F806005262090000F001F8EF
+:1007D000F0BD0B0400B463090008190010845C022A
+:1007E0000070F0BFFB0A00066409009B005859EF37
+:1007F000188FF73CFC0817001164F8000086F0D44D
+:10080000FD08001064090000F002F8F0BD000008C7
+:100810001700123CF5000086F0D4FF0800E86409D8
+:100820000000F002F830BD0000082F0013C4F601EC
+:100830000076F04EFF200064650900054B30B44C93
+:10084000FCFF00080900054CE57949190C06211642
+:1008500030BC195489F7A7F8C046903408008C03BF
+:10086000080008170014487C02006EF09CFC080089
+:100870008465090000F002F870BD0000082B001527
+:10088000D4BA00008AF092FD1C00FC6509000AB48D
+:10089000201C311C00F009F80ABC012803D0042BED
+:1008A00001D175F762FA75F763FA081F00162CF08C
+:1008B000000087F001FB10003266090001B483F7E5
+:1008C0003FFC01BC00F024F878F7F7FC082500177E
+:1008D000E4A203005CF0ADF91600426609000028AE
+:1008E00006D100F007F8002802D10120A3F774FE1A
+:1008F000A3F74AFE08170018C06A02006FF0EAFD6D
+:1009000008009866090000F002F830BD00000823D6
+:100910000019C47202006FF088FA1400D867090049
+:1009200008B4301C0122012300F004F808BC90F741
+:1009300071FD0000920600A3008000141908170042
+:100940001A4CFCFFFB0809002848020072F09AF8D4
+:1009500008006069090000F069FA8DF7BDFF08170B
+:10096000001BB473020070F0FAFC0800AC7D0900B3
+:10097000FFF75DFE8FF791FB080F001C34C40100E8
+:10098000C046201C0000000000000817001D24477E
+:10099000020072F020F908006869090000F0F7F918
+:1009A0008DF7EFFE0817001E6847020072F002F98B
+:1009B00008007069090000F009FA8DF707FF0817B1
+:1009C000001F0C4D020071F034FE08007869090028
+:1009D00000F099FA8EF7DEF908170020404D02006A
+:1009E00071F01EFE08008069090000F0AFFA8EF772
+:1009F000F8F9081700217C4D020071F004FE080090
+:100A00008869090000F007FC8EF70CFA081700222D
+:100A10007854020072F088FC08008C7D0900FFF712
+:100A200058FD8DF783FB081700230C57020072F066
+:100A300042FB0800947D0900FFF7B4FD8DF706FD29
+:100A40000819004CFCFFF6090900244472010080DB
+:100A5000F0A3FF0A008E810900FFF7F5FF7FF75A28
+:100A6000F80000081700254C58020072F0A6FA089A
+:100A7000009C7D0900FFF724FF8DF76DFE0817002D
+:100A8000265C46020073F0AAFB0800B47D0900FE54
+:100A9000F774FE8CF75FFC081700270865010080DB
+:100AA000F042FA08009069090000F0FDFD7FF7D2DE
+:100AB000FD0817002834AE01007DF076FA08002406
+:100AC00083090002B0FFF757FF70BD08170029081F
+:100AD0006E000090F0CCFF0800A47D0900FFF7F93C
+:100AE000FD6FF76AF8087F012AA444000094F04AD9
+:100AF000F870013C85090000B528490B6826490BB0
+:100B00006024490B6822490B601E490B682D490B74
+:100B100060434B43490B6034490B680120C0030319
+:100B2000430B6040490B78002B04D02F490B6840E1
+:100B30000303430B602D4A13685B085B0013603AA4
+:100B40004B3B4A13604CFCFFF10A0900B0F7E6FE8C
+:100B5000B1F70FFBB1F75EFEB2F704F80D2136488E
+:100B600001F0A5FE364A9068002803D099F70FF8E7
+:100B7000B0F7ABFD2448244A11684160244A60E084
+:100B8000C046C0B00800FFF2011A48A50900848FD2
+:100B9000B002D08B0E00A0800E004CA50900148B73
+:100BA0000E0050A509006CE5050054A509008C1540
+:100BB000080023840900538409002D850900A984B5
+:100BC0000900158509005C000F0094830E00FF00EA
+:100BD000FFFF608B0E0040230001E08A0E00E02C36
+:100BE0000800A4860E0088B2080005000080850079
+:100BF00000801C800E0014800E00848F0800048387
+:100C00000E00108B0E00C8FC0E00C42C0800CC2C6B
+:100C10000800D02C0800C82C0800D42C0800D4FFF1
+:100C20000E00BC8B0E00AD020000CC8B0E001CCD64
+:100C3000080010325476D48B0E00009D0800ECCCD6
+:100C4000080011684161054CFCFFEC0B09004A11DA
+:100C5000688160054A13680360044A1368044A13F4
+:100C60006000BDC046D02C0800C82C0800D42C0859
+:100C700000D4FF0E000861002B0044000093F094A4
+:100C8000FF52002C83090010B5A448002383700490
+:100C900023437001230370A14BA2480360A24BA21F
+:100CA0004C2360A24C2368A24C2360A24C2368A270
+:100CB0004C23602C22A249A248BCF711FBA148A1F9
+:100CC0004C2060A149C160A1494162A1490161A1D3
+:100CD0004B8361A14BC36110BD080F002CD0B80439
+:100CE00000A5F809E00000000000000817002D2012
+:100CF000BA04004DF09CF808005C8B0900FFF7D4A3
+:100D0000FF30BD00000817002E3069040052F020AB
+:100D1000FA0800748D0900FFF7C4FFADF7F8FD086D
+:100D200019002F545D040053F012F80A007C8D095D
+:100D300000B4F770F8FFF7B2FF30BD08190030E0DB
+:100D4000A504004EF0D1FB0A004CFCFFE70C0900A3
+:100D5000868D090000F003F803B0F0BD000008170D
+:100D60000031E882040050F0A0FD08002C8E09003C
+:100D700000F002F830BD000008170032B0B10400E6
+:100D80004DF0BAFE0800288F090000F002F830BDCF
+:100D90000000082B0033DCC004004CF086FF1C0070
+:100DA000EC8F0900FF233D3343430448C0189F30B4
+:100DB0000078002800D101207047C046349D08000B
+:100DC000081B003494AC04004EF0C2F90C001C90D7
+:100DD0000900201C00F003F8B1F73AFE0000081BE0
+:100DE0000035ACAC04004EF002FA0C00B4900900DF
+:100DF000201C00F003F8B1F7FAFD000008230036CC
+:100E00003CC104004CF064FF14000890090029184C
+:100E10007F231B02FF339D4200D35D1EFF23B3F7E8
+:100E200092F808170037981B030067F004FB0800CE
+:100E3000A4910900FFF7D2FF30BD0000082B003855
+:100E40001C7B040051F05EFB1C00DC4CFCFFE20D3F
+:100E5000090091090004910FB4301CFFF7E3FF0172
+:100E60002802D10FBC05B0F0BD0FBC062DAEF79423
+:100E7000FC081F003918AC04004EF02AFB1000706B
+:100E800092090003D1FFF7C1FFB1F7D2FCB1F7D14E
+:100E9000FC0000080F003A1C730400C046C0460066
+:100EA00000000000000817003B807A040051F0ACFD
+:100EB000FC0800DC9309000420AEF75AFF10BD08BF
+:100EC00017003C9882040051F0A4F80800E493094C
+:100ED00000FFF7CAFF30BD00000817003D6CA804F2
+:100EE000004EF072FE080054950900FFF74AFFF02B
+:100EF000BD00000815003E94A304004FF07EFA06E2
+:100F00000094980900FFF7E8FF10BD080F003F0CA0
+:100F1000A3040000F01DF8000000000000082300FA
+:100F2000404894000090F027FA14009A98090001B4
+:100F30002B02D10020287001E06FF7DCFD62686FA2
+:100F4000F718FE081D0041A4CC04004CF04CFCFF37
+:100F5000DD0E090003FE0E00AE9809002878B2F7F6
+:100F600079F9201C00F001F830BD080F0042C4A937
+:100F700004005E4A2068000000000000080F0043E3
+:100F8000A4630400FE23F533000000000000081FE6
+:100F90000044D472000092F0FCFA1000D0980900CE
+:100FA000301C049900F004F8009988426DF7FCFCAD
+:100FB000081700459897040050F0C8F808002C99CD
+:100FC0000900FFF79FFEF0BD000008170046E49DF2
+:100FD00004004FF094FF0800109D090000F002F893
+:100FE000F0BD000008150047D099010080F0E8FA34
+:100FF0000600A49F0900FFF7B2FF00BD08150048D6
+:1010000068E901007BF01FFB0600AA9F0900FFF7BB
+:10101000C2FF00BD08210049A4E901007BF004FBE8
+:101020001200B09F09000FB4301CFFF7C6FF0FBCC1
+:101030000A22311C84F7F3FC080F004AC889030018
+:10104000402303600000000000000819004B884C9A
+:10105000FCFED80F090085030061F01BFD0A00C2E9
+:101060009F090000F003F89EF743FB000008BF0053
+:101070004C5464020073F01EFEB00094A0090000FE
+:10108000B51E4B1A680D2A2ED0092A04D108430434
+:10109000D09EF760FB01E00C2A04D11F490B6800C9
+:1010A00020186028E0072A26D09BF712FF13490B6F
+:1010B00068012B12D112490B681B010ED41A490B7F
+:1010C00068002B0AD00E480368DB0102D5124908DC
+:1010D0006806E010490B68580002E000280BD002B7
+:1010E000E00E490B68186001209EF731FE0F490B96
+:1010F00068202003430B6000BDC046B0C808004014
+:101100001B0800B45F0800400B080023C30800D48C
+:10111000CA0800F40A08000C0B0800E40A0800E4FE
+:10112000CA080053860300E4C7080020040E000824
+:101130001B004DD06C020073F0A6FA0C0020A2092F
+:1011400000019800F003F802B0F0BD0000FE0000BE
+:101150004CFCFF004B0900F0B5484C484B49480394
+:1011600060494B4948036001F0F4FE00F098FB0031
+:10117000F0AEF900F058FB00F0B6FA00F0C8FA0340
+:10118000F06FFE424A151CE435424B2B60424E3351
+:101190006802263343404E33604048036880218B09
+:1011A00043036000233E4E33703E490B1C23333D06
+:1011B0004E33603D4B3E4E33603E4B3E4E33600BF4
+:1011C0001C12333D4E33603D4B3E4E33603E483E35
+:1011D0004B3F4E3360031C0E333E4E336012233DB3
+:1011E0004E33700B1C11333C4E33603C4B3D4E3341
+:1011F000603D4B3D4E33603D4E31603D4B3E4E3386
+:10120000603E4E33683E4E33603E4B3E4E33603E52
+:101210004B6B673E4B061C071DC8C40E363D4FC8BE
+:10122000C4991C0E30061CC2C43B4BD36200233A47
+:101230004E336004F034FE394B6B65E4209EF73D7D
+:10124000FB0007000F042805D13F20C043354A505A
+:1012500073004CFCFFFB4B09000A907300233349D9
+:101260000B703348E862F0BC08BC184700B5314841
+:101270003249086032480749C86400F024F900BDCB
+:10128000C04614A4090091520900BCC80800955238
+:101290000900F0C40800A0190800455309006C01BA
+:1012A0000F0040150800FD0708001E4500006CA453
+:1012B000090020C9000070A409001CC8000074A423
+:1012C000090078A40900388500007CA409005E04A8
+:1012D000000044050000881308008C1308009013D8
+:1012E0000800781308000EC90000801308000AC81F
+:1012F00000007C1308008413080026850000741386
+:101300000800D8FF0E0080A409006216000084A423
+:101310000900F95809004205000062190000819295
+:10132000090068A409004D650900B8130800BAA5B2
+:101330000900599E0900014B0900900008007963DB
+:10134000090070B500200F49104B4B6114E06B0988
+:101350009C00EB064CFCFFF64C0900DB0E01259DC2
+:10136000400B592B430B5143004C69C50052195295
+:1013700068012632432725AD03AA1A1A5301300506
+:101380004AC3009D58922DE5D370BDC0464C1B0842
+:1013900000ACA509000CA3090000207047002070D4
+:1013A00047002801D0002000E00120704700207095
+:1013B0004710B5037814490B700620A9F75FFD04A8
+:1013C0001E10D00E230370042343700023437101C9
+:1013D000238370F723C370FC230371A9F779FD20E1
+:1013E0001CA9F750FD012010BC08BC1847810589D5
+:1013F0000D030AFC201840FC2803D1F72901D10372
+:101400004800E000207047C046BAA509004D4D09CC
+:101410000004280AD106480378002B06D0054803AB
+:10142000785B065B0E0370012000E000207047C06F
+:1014300046BAA5090039C3080030B50124827812E4
+:1014400002437813439A05920D1B0AFC252B400C8E
+:101450002B2DD0FC2B244CFCFFF14D0900D11C2A74
+:101460001CD0B52A0DD0B62A0FD0C22A10D0C32A5C
+:1014700011D0E62A02D0F52A1AD112E003F04CFC72
+:1014800017E001F05FFE012016E001F091FEFAE79F
+:1014900001F0C0FEF7E701F006FFF4E705F088F978
+:1014A000F1E703F0AFF9EEE7202B04D0042B02D1D3
+:1014B0000024201C00E0002030BC08BC1847024873
+:1014C000024908607047C046D54D090018C9080098
+:1014D000002070470148024988607047654E090046
+:1014E000201A080072487349C8607047F0B583B08D
+:1014F000041C012906D164300023C372251C9435D5
+:10150000AB73EB736C4803689B079B0F032B02D0F4
+:1015100071F722FAC8E00023A381E07B484000D1A4
+:10152000B6E070F7BDFC002803D1644803691B01D5
+:1015300001D5012100E00021271C64373E1CFB6817
+:1015400080208343C8010343F3600C365C4A107863
+:10155000431006D0C3071B0E4CFCFFEC4E090031B4
+:10156000688020814319433160564803691B01029A
+:10157000D4381C94F79AF9BB69002B02D03B681B46
+:10158000063BD4338868460380E37B012B0DD025CE
+:101590001C94356B7B002B10D02B88042B0DD3EBC8
+:1015A0007C022B0AD3AB7D002B07D1A72303201885
+:1015B00055009B78208343002106E00121E9740057
+:1015C0009B78208343082003431F208002834388A5
+:1015D00002034300931B041B0C3C4A1360012030A0
+:1015E00072384A13691B0152D400984006010F005B
+:1015F000231A1C012094F77AFB45E0E07B002802C7
+:10160000D1A72301221A55012804D1E37C042B0120
+:10161000D072F76DFCF37A002B06D00023F37233FF
+:101620006801204002434033600121B172251C94BF
+:1016300035A97323480369DB0002D5201C87F77D99
+:10164000FD338821490B60B0884860381C70F79DD5
+:10165000FC30684006030F1D48C04CFCFFE74F09F3
+:10166000005C3072431EA381E37B002B0FD101216C
+:10167000387F8140194A1068084008D1E37C042B68
+:1016800005D016480378AB7516480378EB750E48FD
+:1016900003691B010FD5201C94F7D3FE0BE0271C18
+:1016A00064373B727B7270F72BFC636C002B02D0AB
+:1016B0005A231B5BA38103B0F0BC08BC1847814EC2
+:1016C000090000020800188B0E0054200800DCC836
+:1016D0000800CC8A0E009EBB0500B4010800F5018D
+:1016E0000800F601080030B50D1C041C75F777FEE4
+:1016F0006B075B0F012B05D1E37B002B02D1A07B95
+:101700009CF7B6FD30BC08BC184700B52C22044934
+:101710000548BFF774FC034804494161044B186055
+:1017200000BD0CBD050088A409006D500900E4024D
+:10173000080010B53F4C3F4B1C602C223F49201C39
+:10174000BFF75DFC3E48606210BDF0B5041C051C8F
+:10175000876A28353B4B4233187800284CFCFFE25F
+:1017600050090066D1201C012172F7D1F9061E4BE9
+:10177000DD022804DB201C77F74BFA002859D161E1
+:101780008C8B1F9E4223DA304A13689C420BD0395F
+:101790001CAB310878013800D30870731C59102035
+:1017A0001C76F7D8FF30E0731C5810E37B002B0544
+:1017B000D07B6C002B02D06B7F002B25D02F89B8FB
+:1017C0004222D36A89002A06D1A389002B03D120A3
+:1017D0001C71F7DFFD18E0BA4200DA3A1C904201B2
+:1017E000D90C2310E04B23A27C1B5D9A420CD10242
+:1017F000280AD36B7F002B05D01448037899420147
+:10180000D9282300E03823A374211C4D3108780027
+:10181000280FD00238087000060BD1E37B012B02A1
+:10182000D0237D0C2B05D0321C201C0523022177F0
+:10183000F734F9F0BC08BC1847B4A4090000030849
+:101840000074BD0500D15009006C210800F40208A5
+:101850000000B52C2216491748BFF7D4FB154CFCE5
+:10186000FFDD51090048164B18601649016100BDA3
+:1018700030B50D1C041C78F71CF8022D09D16B2320
+:10188000185D002805D0201C87F705FB201C87F772
+:101890003DFB30BC08BC184700B5011C6831CB7853
+:1018A000002B07D04B7A002B04D18B78002B01D072
+:1018B00087F714FB00BDC0462CBE0500E0A409005C
+:1018C00030030800E951090000B57CF752FA00BD69
+:1018D00000B52C220B490C48BFF798FB0A4B0B486C
+:1018E000036000BD0A49CB6ADB0007D5094AD388EB
+:1018F0005B00418C8B4201DC012100E000215A3069
+:1019000001707047B0CB05000CA50900F403080076
+:1019100054200800942008000020704730B5041CB3
+:1019200000292BD0012925D140051BD426E0174DD5
+:10193000291C1748B7F7C7FF2988281C262902D178
+:1019400003F04BFD0EE0042902D17CF712FA09E006
+:101950000F2902D104F032FB04E089000D4A8958B6
+:101960004CFC48D8520900C6F7EDFA0A48B7F7C64A
+:10197000FF0028DFD00A4B1C4003E0022901D17B85
+:10198000F7CBFF201C30BC08BC18470548064908A7
+:10199000607047F4440800284508009CBE0500FF1D
+:1019A000FBFFFF95520900F0C408004CFCFF2453D4
+:1019B000090000B5431E04490B6004490B78032B52
+:1019C00001D1BFF7E8FF00BDC046E08A0E0038082D
+:1019D0000800F0B587B0061C0491081C0021039193
+:1019E000A34C2064211C4431009100238B70A0483B
+:1019F0008568002D00D16EE2AB7D002B09D001225D
+:101A000003920023AB756361237810208343237016
+:101A100006E06069002803D0012E01D970F701FFAC
+:101A200022691D27FF03002A50D0607A012803D1C4
+:101A30009389002B4AD047E08F4B1B5C002B43D18E
+:101A4000BB68DB0742D4137D092B3DD204281AD191
+:101A5000012E18D1967562612378102003432370FC
+:101A600023683B6085490B687233187802282DD0B3
+:101A7000002382490B608249086882490B68036031
+:101A80000B68036022E002280AD1012E08D1967566
+:101A90006261237810200343237023683B6015E0C4
+:101AA000032803D179498B78022B0FD0064CFCFF19
+:101AB0001F5409002801D0032805D1012E03D1BBF2
+:101AC000689B0600D5C0E1122803D0102801D07011
+:101AD000F72BFE6A4B985D029000287DD00123DB36
+:101AE00007334301936B4B6C490868986301236B80
+:101AF000490B606B490B689B0C9B040B600B68697E
+:101B0000490868034366490B6001230099CB70665E
+:101B1000490B6866490B6066490B6866490B60288B
+:101B20007C1A281DD164490B6864490B6064490B19
+:101B30006864490B6064490B6864490B6064490B35
+:101B40006864490B6064490B6864490B6064490B25
+:101B50006850490B60634908686349086063492D10
+:101B6000E063490B6855490B6062490B6855490BA6
+:101B70006061490B6855490B6060490B6855490B1A
+:101B8000605F490B6855490B6019280ED1FF20177B
+:101B9000302B562A3309DD5B490B683E490B605AEE
+:101BA00049086851490860594908E059490B684C8F
+:101BB000FCFF1A55090039490B60584908684C491F
+:101BC00008605749086857490860A87B231804280B
+:101BD00001D3187800E0205C6F2290431870C2E0B7
+:101BE000A87B225C0F218A433107090F0A43225444
+:101BF00023180428049802D38107101C01E08107F0
+:101C00001878490E6022904308431870234B4649C8
+:101C100008689863009AD378002B00D1A1E022498C
+:101C20000B689B0C9B040B600B68404908680343DE
+:101C30001D490B600023D3703D490B681D490B60A3
+:101C40003C490B681D490B603B490B681D490B6003
+:101C50003A490B6821490B6039490B681B490B60F5
+:101C600038490B681B490B6037490B681D490B60ED
+:101C700036490B6809490B6035496BE0642C080054
+:101C80006C210800ECBB0500DC02080060000F00BE
+:101C9000AC2C080044020800882B08002CFC0E0025
+:101CA00060020800E08A0E00B88A0E005C0208009C
+:101CB0006C4CFCFF15560900130800D8FC0E007090
+:101CC000130800E0FC0E006CA40900CCFC0E0074AC
+:101CD000A40900DCFC0E0070A40900D0FC0E007CFE
+:101CE000A40900C8FC0E0078A40900D4FF0E002C43
+:101CF000A4090030A4090030FC0E0034A4090078C7
+:101D00001308007C13080080130800741308008473
+:101D100013080014A4090018A409001CA409002039
+:101D2000A4090024A4090028A40900D8FF0E00B8C3
+:101D30002C080048020800BC2C0800C02C0800C475
+:101D40002C0800C82C0800CC2C0800D02C0800D48B
+:101D50002C0800D82C0800DC2C08000868934908DF
+:101D60006093490B6893490B6000210191286882B8
+:101D70006A281C0021C6F7EDF8002810D026231A87
+:101D80005C002A0CD08368002B09D002980028043C
+:101D9000D0802301981843019001E0012200E00067
+:101DA00022237880208343D0010343237020200422
+:101DB0009908404CFCFF1057090001D00120C003D6
+:101DC0007F4908600499090704D47D490B68802085
+:101DD00083430B600499880801214140A278802048
+:101DE0008243C8010243A2702868826A281C03212A
+:101DF000C6F7B3F874490B78012B01D077F753F885
+:101E000005A9714A13687020034018099CF7A0F8CF
+:101E10002369002B14D0637A032B11D188F701FCBE
+:101E2000002806D16A480368032B02D00368062BFA
+:101E300006D12B7C122B03D101230098837058E02C
+:101E400005988007800F06D003280ED1069B6049B5
+:101E50000888834209D30398012800D1656170F78F
+:101E60006EFC012300994B7043E00820B860A87B0A
+:101E7000786223683B603B1C1833221D0392920753
+:101E8000920F02D1039909680FE00399891A03910F
+:101E9000D2000968D140049120218A1A0399496827
+:101EA000914001B40598014301BC1960BA69331C23
+:101EB000103B042B0D4CFCFF0B580900D2474B1371
+:101EC00040FF22013282401343BB61102E07D144F0
+:101ED0004908684449086002E040481040B8610180
+:101EE00098002800D07861E5602672002300990BE5
+:101EF000704B70281C8CF7B5FC012007B0F0BC08B3
+:101F0000BC1847394B3949087A185C39490B6800C5
+:101F10002814D00120800303430B60364A1368362F
+:101F2000480340364A117849020B43354A1360355D
+:101F30004A1368302083431020184308E0324803D6
+:101F4000400B602C490B682E490B602E4908682F06
+:101F5000490860704710B5254C234B607A185C0027
+:101F60002802D070F75FFF15E06069002801D0708B
+:101F7000F769FC27490868637A012B01D1254A00DB
+:101F8000E0254A13680360116801600023234A13A7
+:101F90006070F774FE002322490B60E360236163E5
+:101FA0007244340120207010BD002803D10348037F
+:101FB000680348036000204CFC7206590900704712
+:101FC00030FC0E0080A40900D8FF0E00648B0E00C8
+:101FD000A4860E00D4C1080024860E001C840E00C6
+:101FE000E4B60800FFF0FFFF9406080064FC0E0052
+:101FF000ECBB0500642C0800808B0E00B02C0800A0
+:10200000FFC1FFFF9013080088FC0E00B42C0800ED
+:10201000FFBFFFFFCCFD0E00AC2C08004002080003
+:102020004402080060000F0018800E004CFCFF887E
+:1020300059090070B582B0061C654801688906021E
+:10204000D5022072F71FFC624C2568A3682360004C
+:102050002D26D0002E18D19EF7F4F9002814D0C3F5
+:102060000703D52A68916900290BD1430703D52AB4
+:1020700068D169002905D1830706D52A68116A004D
+:102080002902D0281CC5F76CFF9EF7F8F9011C2A1D
+:10209000685269002A04D0002802D0281CC5F75DC8
+:1020A000FFA0680026A84218D0002D21D02A68126F
+:1020B00069002A03D0281C0521C5F74FFFAE8123F4
+:1020C000699D4200D126612B7D092B11D3281C73F9
+:1020D000F7E8FD281C73F76DF90AE0002808D063C3
+:1020E00069984205D166613B4800220121B7F71D7E
+:1020F000FF3A48C16E002904D0A368002B01D1C566
+:10210000F72FFF70F7B6FBA06800284BD08681033D
+:102110007D092B20D26369984205D166612E480063
+:10212000220121B7F702FFA068A84206D1014CFCAA
+:10213000FF835A0900684968002902D00523037506
+:1021400008E0017D032901D0042905D1016849680F
+:10215000002901D0C5F708FFA068022303750168B4
+:102160000A69002A02D00221C5F7FBFEA068807B25
+:102170001D4A136870210B401909884216D169461F
+:102180009BF7EAFE70F760FC002801D0174800E0DA
+:102190001748028800998907890F04D0032905D1BF
+:1021A000019B934202D33F2301201855A0688CF76E
+:1021B000E0F901208CF7F0F9A66066603C342671E6
+:1021C0006671012002B070BC08BC18470948044978
+:1021D00088617047C046C4C408006C2108000C2DFB
+:1021E0000800201A080024860E0066020800640217
+:1021F0000800895909009F48A0498865704700B5C3
+:102200009F4A9007800F01D1116808E0121AC000A0
+:102210001368C3402021081A516881401943C90F2F
+:1022200098480170984A1068002817D0974A0260B1
+:102230004CFCFF7E5B0900974A8260974AC26001AE
+:1022400023964A13700023964A1360964A136096A9
+:102250004A1360012902D100F007F802E04068C586
+:10226000F785FE08BC1847000000B500F003F80829
+:10227000BC1847000010B564238C48037000238C01
+:102280004803608C4803608C4C236000F04FF87D5D
+:102290004A9007800F01D1116808E0121AC000139C
+:1022A00068C3402021081A51688140194301204029
+:1022B00007014015D081490B68001403430B60806F
+:1022C000490B68804803400B6004390B680120808B
+:1022D0000303430B607C4B7D490B6003037C490B7C
+:1022E00060684A9007800F01D1116808E0121AC097
+:1022F000001368C3402021081A516881401943C95E
+:102300000011D5744C2368002B02D0201CB7F705B0
+:10231000FC7149201C00231A1CB7F7E0FB6F480131
+:1023200068201CB7F7E6FB8EF762FA10BD10B56C9B
+:102330004C234CFCFF795C090068012423436A4C60
+:10234000236001239B03694C2360504A9007800F50
+:1023500001D1116808E0121AC0001368C34020219F
+:10236000081A516881401943090105D55E48036880
+:10237000022003435C4803605D4800218160F42132
+:10238000C16020210161E8218161E92141611021C1
+:1023900041624021C161016205239B04036010BDBD
+:1023A000F0B582B0071C01910C1C002200920123A1
+:1023B0005B0250490B604E490E68360C3604211CF6
+:1023C000242903D0151C25291CD102E008240A2148
+:1023D0000AE070300078022802D10824464801E063
+:1023E000012446480278012123010D031D431307F0
+:1023F0001B0D1E43FB7B002B00D1E4E00123DB031C
+:102400001E43E0E0019B5B003D481C5A3D498C4265
+:1024100011D18023DA5D3C48135C1B013B4818183E
+:102420008388002B07D0374C1034837A012B06D1D8
+:10243000344C20344CFCFF745D090003E0002C0197
+:10244000D1251CC3E0381C8CF79CFB002800D04031
+:102450002431480368002B07D0602C01D1E02464AC
+:10246000E0702C08D1D02460E00198042801D0024B
+:102470002801D101252D04302C4FD17023D85D00C7
+:10248000284BD0214C703450E0C0464D5B0900A071
+:10249000190800C005080030C8080044060800B14B
+:1024A0005B0900E15C0900155F0900B8050800340C
+:1024B000C8080038C808003CC80800D0050800401B
+:1024C000C8080048C808004CC808009C800E0010CE
+:1024D000800E00FFBFFFFFFF030000BC820E001054
+:1024E000000C0068500800673D0200D40508007029
+:1024F000010F005C000F0074820E000C800E00982B
+:1025000006080090060800D8050800100100009099
+:1025100005080024500800D4C40800502C05D13B05
+:102520006FDB0502D501235B041D432543FF231107
+:102530003370339C42034CFCFF6F5E0900D02309CB
+:102540005D48C15C0091302C0BD17023D85D002810
+:1025500007D1381C2830037D807A19180906090E26
+:102560000091009803031D43FB7B002B02D0012345
+:10257000DB031E43FB7C032B04D1788CC306180FAE
+:1025800003021E43402C25D14C480378002B06D073
+:10259000381C8DF774FE03071B0A1D431AE0012344
+:1025A000DB041D43B87B9BF7FFFC4008444A1060E6
+:1025B000444A11689BF793FC434A1060434A1368EE
+:1025C000984204D2381C8DF73AFE002802D001232D
+:1025D0003A4803703E480560466002B0F0BC08BC53
+:1025E0001847F0B582B00F1C051C00220092019024
+:1025F0008CF7CBFA364E002844D034682F48017847
+:1026000000291AD1A87B9BF7CFFC40082C4A106008
+:102610002C4A11689BF763FC2B4A10602B4A136805
+:10262000984204D2281C8DF70AFE00281BD00123F3
+:1026300022480370274B1C404CFCFF6A5F090015C1
+:10264000E06B6E1B0612D4012910D1281C8DF7FAFD
+:10265000FD00280BD1A87B9BF7AAFC41081A4A1160
+:10266000600023174A13700123DB041C4314480342
+:1026700078002B03D001988CF734FF0090174B1C87
+:1026800040009803071B0A1C433460042F01D0024A
+:102690002F05D13368012109040B43012107E01004
+:1026A000480378002B06D033680E490B40002133D5
+:1026B000600B48017002B0F0BC08BC184724060843
+:1026C00000B805080038C8080034C808003CC8082D
+:1026D00000CC05080070820E00FFFFF7FFFFFF0F20
+:1026E000FF45C80800FFFFFEFF30B5041CC37C0394
+:1026F0002B27D1037D0C2B24D11830437B002B20BA
+:10270000D121490B699C4202D18B68002B13D04127
+:102710008900680B1858010509A07B9BF748FC85C8
+:102720004201D3281A03E0431B01200007C01A838B
+:102730001F1648834205D3201C734CFC6365600957
+:1027400000F7C8FA201C72F756FF237D022B03D036
+:10275000032B01D0042B07D10F480379002B16D08F
+:10276000201C70F79FFD12E00C480369002B02D07B
+:10277000201C70F734F806494123585C012804D026
+:10278000002804D10B689C4201D172F7C2FA30BD17
+:102790006C210800FBFFFF07A42C0800642C080034
+:1027A0004CFCFF4861090070B5041C002538484303
+:1027B0006912219B0708D5364A1068364A106050C6
+:1027C000304079122800D8011C43209DF76CF83264
+:1027D0004BA360324B2361201C0830AAF70DFF2168
+:1027E00068086063681D60AAF776FF201C1030AA95
+:1027F000F703FF216808600420AAF785FF606106DF
+:102800002801DAAAF768FF201C0830AAF7F5FE2194
+:102810006808606368002018600420AAF774FFE06D
+:1028200060201C1030AAF7E8FE2168086063680089
+:102830002018600420AAF767FF6061E368C61A30B9
+:102840001CAAF7B7FF042817DD01350C2D14D03072
+:102850001C042E08DDAAF7ADFF8100081A216908C3
+:102860001802382061CFE7AAF7A4FF8100081AA157
+:1028700068081A0230A060C6E7A16820690B1AE355
+:10288000614018C30F18184310236270BDC046186A
+:102890001B0800D4CC080034A70900FF0300000186
+:1028A000FCFF4CFC0543620900FF4CFCFF58620929
+:1028B00000F0B5444D2B68987B9BF73BFB46082BFB
+:1028C00068996C301C9BF7D0FA041C2868011C9492
+:1028D000314A88002A10D094420ED9037D0B2B0B6D
+:1028E000D00D2B09D070F79FFB2B686433197F0143
+:1028F0002000037BF771F864E00B7D002B06D0CB42
+:1029000088F31A1B041B0C9C4200D81C1CC36F6468
+:1029100030002B06D00B89F31A1B041B0C9C4200C1
+:10292000D81C1C8A88B31A1A04120C944200D814BA
+:102930001C0B881F1FBA4204D3CB7C022B01D3008F
+:1029400023CB74214E33889C4204D80020BA422EF7
+:10295000D303202CE073889C4201D8042228E0B3E2
+:10296000889C420BD9007F74F7C1FE002814D00365
+:102970007C112B11D115494B889C4203D8296894AE
+:1029800031052215E08B889C420DD82968943106C8
+:10299000224A745E2383740CE0F3889C4203D82996
+:1029A000689431062204E029689431074CFCA15355
+:1029B0006309002200E0021C4A740B7E012B04D143
+:1029C000531F012B01D804234B74F0BDB421080020
+:1029D00034020800EC02080010B5A3F7D3FB0B4942
+:1029E0004B699B070FD50A48036801200343084839
+:1029F00003600A249BF750FD013CFBD104480368A7
+:102A00005B085B00036010BC08BC1847181B08007B
+:102A1000F0FC0E0010B5094C2C220949201CBEF711
+:102A2000E1FA0849E160084B1C6010BDC27B4A40D6
+:102A300002D0838C05490B607047C04638A7090057
+:102A400034CC0500CD63090010040800CC8A0E00C8
+:102A50004CFCD418640900F0B581B0041C002100BE
+:102A600091C56D8726F600002D04D1301C9BF7A67A
+:102A7000F8051E03D0301C9BF7A1F80090264F3BB1
+:102A800068002B08D1301C08309BF798F83860316B
+:102A90001C0831BEF7B8FD20480368002B0DD1306B
+:102AA0001C08309BF78BF81C4A1060311C0831BEA3
+:102AB000F7AAFD19480368002B07D03B68002B04D8
+:102AC000D0002D02D00098002817D1E02300201854
+:102AD00051E565E4210B59DB0208D4635810480323
+:102AE000430B515022206807217DF7D6FA0D480389
+:102AF00068002B0DD19BF76EF80AE0E5656060E495
+:102B0000221359064883431351206807217DF7E5B6
+:102B1000FA002001B0F0BD444408009C44080000C5
+:102B2000001000600308004CFC78F064090030B528
+:102B3000E4221358012109058B431350051C79F732
+:102B40002AFA0024002800D0EC65E86D002802D0A5
+:102B50009BF75BF8EC656868002802D09BF755F896
+:102B60006C60074D2868002802D09BF74EF82C6057
+:102B7000054D2868002802D09BF747F82C6030BD2F
+:102B8000C046444408009C44080000231360012808
+:102B900005D10123DB040B6007239B0313607047FF
+:102BA00000004CFC748C650900B0B503685B01192A
+:102BB00048C21880270F404906490E906800282710
+:102BC000D00568281C041C002F06D0437B8B4201D3
+:102BD000D0002300E0012306E0037B5B088B420169
+:102BE000D0002300E00123002B0FD0A84205D11311
+:102BF0007C002B02D1D37F022B0AD0111C08319B01
+:102C0000F7BCFD201C9AF7AAFF02E00068A842D991
+:102C1000D1B0BDC0467C2908004CFC1E18660900D6
+:102C200010B5002907D0041C70F798F9201C6EF726
+:102C300003F9012000E0081C10BD4CFC4458660953
+:102C40000000B50D48B6F707FE00BD30B5051C0005
+:102C5000240A49A300C818C378AB4204D1A300C812
+:102C6000180421BEF7A5FC0134082CF1D330BD00B7
+:102C7000B50068FFF7EAFF00BDB8520800504708EA
+:102C8000004CFCFFA066090030B5104D0D24281C37
+:102C90000022111C90F720FA281C90F713FA203517
+:102CA000013CF4D130236343094818182C23195CE4
+:102CB000022904D1406A002801D09AF77BFF013431
+:102CC000022CEFD390F7C8F930BDC0467C2908002C
+:102CD00080590800F0B582B0051C0E1C041CB034ED
+:102CE0006946207B9BF7D3F82C482D4A1178431A6C
+:102CF000F6000198991940182A4B984201D30320F5
+:102D000005E00121284B984200D30221081C0099BC
+:102D100043185808031D5808860176092188301C7D
+:102D20009BF76AF86788391C77F7E6FA381A430880
+:102D3000AB80831958014009A0601422291C1B484C
+:102D400003F0A8FD02B0F0BD10B5041C18490868D6
+:102D50000007000F01280BD80B683F20000203403A
+:102D6000190A144A906EFFF7B5FF134A9378A374BB
+:102D700010BC08BC184710B5041CB3F7B7F80F49CE
+:102D80008B78004CFC419B6709002B07D1A37C0B7F
+:102D9000498878834202D0201CB3F787FE10BC0814
+:102DA000BC18470E02000038A40900A903000071F6
+:102DB00002000000980E00A88B0E0038B0080074C6
+:102DC000150800AC2108004CFCFFEC670900F0B5C9
+:102DD00084B0061C181C01AB07C300252C1C03F093
+:102DE0005EFD00902F1C0199002918D0F37F022B63
+:102DF00015D1337C351C002B01D00C3500E0083593
+:102E00002A68101E00D01068002A07D0116891426D
+:102E100001D12C6001E00B6813600C6014E0357484
+:102E200012E00A6801928A4201D1F76001E013685A
+:102E30000B6001990F60002C04D02368136022609E
+:102E4000141C01E0141C1260F1680029E9D115E09E
+:102E50001A680193111C9A4201D1B76004E013680B
+:102E600001B40298036001BC0F60002C04D02368F9
+:102E700013602260141C01E0141C1260B368002B64
+:102E8000E6D1002D0BD02A68002A05D01368036014
+:102E90002B681860286007E02860006004E0F37F7A
+:102EA000022B01D10323F377009803F000FD12E019
+:102EB0002068051CA04201D1002401E003682360C2
+:102EC0002F600399002904D0024CFC7DE7680900BB
+:102ED0009900229CF731FE01E09AF726FE002CEAC9
+:102EE000D104B0F0BD0A480B4908600B480B4908F3
+:102EF000600B480C4908600C4B0C490B600C4B0DE7
+:102F0000490B600D4B0D490B600D4B0E490B60706A
+:102F100047C970090064C80800236F090068C80821
+:102F200000E975090080C80800196A090054C8083A
+:102F300000096D090070C808006976090078C808A2
+:102F40000064A30900B00608004CFCFF9869090062
+:102F500070B5051C7CF755F8011C041CEA691204C5
+:102F6000D20F2273032363730C34414B186800099A
+:102F70000226800706D5F42043599B0702D5A67088
+:102F80003C480660F4204359DB0601D4002A01D1F5
+:102F9000002000E038484860281C90F7E6FC002339
+:102FA000364A137070BD30B5041C0D1C7CF729F82F
+:102FB00033494B681A7BD207D20F02730523437340
+:102FC0008573304A4260011C201C90F7CEFC30BD56
+:102FD00010B5041C0321FFF7E6FF294A5368987BCC
+:102FE000244A1060201C8DF7D0FF10BC08BC184785
+:102FF00070B5041C7CF705F8011CE2691204D20FBD
+:10300000027304234373F8231D59837B0126B343C2
+:1030100035402B438373F8263559AD07ED0F022653
+:10302000B3436D002B4383730C30002A0CD1164A36
+:10303000537815785B199578EB18D578EB181579D6
+:10304000EB185279D31800E00023C34CFCFF936ABD
+:103050000900700F484860201C90F78AFC70BD0082
+:10306000B5094A5168897B8B07DA0FC907C90F8DEB
+:10307000F7CCFF00BDC046641B080088500800D391
+:103080004902005CC80800F44408008B710900E89C
+:10309000500800094A020010B5041C6D4A1068C0AF
+:1030A0000702D4112323702BE008790002C97808A5
+:1030B00043012178F76FF8002803D0F8221158490E
+:1030C0000701D51223EEE7C169090403D4F4210BEB
+:1030D000589B060DD55F4B19684906490FF422121B
+:1030E000589207920F914203D15B490B78002B0154
+:1030F000D00C23D7E701230B7028342370FFF72B64
+:10310000FF10BD30B5051C0C1C031C283301201812
+:103110007001F0F4FA002801D10C2022E02079009F
+:1031200002E1780843012178F735F800280BD0F840
+:10313000221158490701D40B2013E0F43003685BD7
+:103140000601D40E200DE04249086840064CFCFF01
+:103150008E6B0900400F022808D1414A1188601D7A
+:1031600001F040FA002801D10D20287030BD30B5A3
+:103170008A7B002A01D1122340E0374CCB782068AB
+:103180000225002B06D0012318432060364803682F
+:103190002B4305E001239843206032480368AB438A
+:1031A000036031480B7903704B7943708B798370DE
+:1031B0002F48CB79202B02D12E4B186002E02D48EE
+:1031C000402BF9D0487A00020B7A184340102A4B62
+:1031D0001860C0006080C87A00028B7A1843204BC8
+:1031E0001880487B00020B7B1843244B188024482E
+:1031F0000280CB7B244803700B7C2348037030BDD6
+:10320000164A1168C907C90F817317490B78C37330
+:103210004B7803748B784374164A1168090A8174D9
+:10322000164A11684900C174090A01750D4A1188CE
+:103230004175090A8175114A1188C175090A01761B
+:1032400010490B8843760F490B7883760F490B4C56
+:10325000FCFF896C090078C3760E23C3707047C0E9
+:1032600046641B08005CC8080060A40900301B0805
+:1032700000A80608001E200000940608003A40003E
+:10328000009006080062A4090064A4090065A7096B
+:103290000066A7090010B5041CFF20052193F779EB
+:1032A000FF002806D016238370C470210A01719391
+:1032B000F7FBFE10BD10B5041CFF20052193F76934
+:1032C000FF002806D018238370C470210A0171936F
+:1032D000F7EBFE10BD10B50024201C00F0F0FB0140
+:1032E00034042CF9D31821AB48BEF754F901F04C43
+:1032F000F8A9480268D10708D55106490F022904E8
+:10330000D1A64A116872230B4313600023A4490B12
+:1033100070A4490B704088C010A3490860A3490BF2
+:103320007010BC08BC184730B5051C00244E236340
+:10333000439F481818811C281C062203F0B5FA0088
+:103340002803D1201C00F0BBFB02E00134042CED6B
+:10335000D34CFCFF846D090030BD00B500214E2028
+:103360004843954A8218507800021278104302D0E0
+:103370008DF7D8FC07E001310429F0D300238F49F1
+:103380000B708DF708FE00BDF0B5061C0425002467
+:10339000894F4E206043C019811C301C2830062202
+:1033A00003F086FA002801D1251C02E00134042C28
+:1033B000EED3042D0DD100244E206043C11948786E
+:1033C00000020978084301D1251C02E00134042CD5
+:1033D000F2D3042D18D24E236B43DC19311C283153
+:1033E000A01C0622BDF7B8FD5C20805B2070000A9F
+:1033F0006070311C201C083000F0F6F9311C2831B7
+:103400006F480622BDF7A8FDF0BDF0B5041C0F1CE7
+:1034100000264E207043684BC518A91C381C062294
+:1034200003F046FA002803D00136042EF1D326E03B
+:10343000201C78F77EFA291C0831201C00F085FA40
+:10344000E0690F21C9050843E061201C0F230386B2
+:103450003030864CFCFF7F6E09008D69780C022AA3
+:10346000781443A64205D0584A0121B14013688B15
+:10347000431360554A0123A3401168194311608426
+:1034800085012000E00020F0BD10B582B006224F7B
+:10349000496846BDF764FD0024694606236343403E
+:1034A000481818062203F007FA002801D00120036B
+:1034B000E00134042CF0D3002002B010BDF0B5823E
+:1034C000B0071C062243496846BDF749FD00243475
+:1034D0004E0622151C65436946A81903F0ECF90055
+:1034E0002806D1391CA8190622BDF739FD01200391
+:1034F000E00134042CEBD3002002B0F0BDF0B504A1
+:103500001C0E1C171C344DFF2001302058002801D0
+:10351000D0B6F794FAF8210859C00700D491E0001A
+:103520002E00D18EE0002F00D1A5E00859800700C1
+:10353000D4A1E0201C6DF7C3FCE069F8218843406A
+:10354000210843E061F822105904229043F8221028
+:1035500051201C90F74CFCFF7A6F09007DFD20681C
+:1035600000216DF7EBFC164A1378002B0AD0E069B6
+:1035700000043CD41B4880791B4A1178014001D1DA
+:10358000002832D1261C5C36318800231A1C181CF6
+:1035900094F7A2F83088FFF798FE00232B700848B4
+:1035A00003701048037022E0C046BBA50900641BED
+:1035B0000800301B08005CC808005DC808009006C1
+:1035C000080065A70900D3A50900BFC10800B7C15D
+:1035D0000800D020080054A309005CA3090064A7D8
+:1035E000090038A5090066A7090001232B70201CDB
+:1035F00028308DF787FBE069000414D48DF7A4FB15
+:103600008DF774FE012801D18DF793FB982108599D
+:10361000C00008D5E06C032189068843E064201CC3
+:10362000012181F77FF80023B9490B70A36B1B07B9
+:103630002FD5E06900042CD4B6494B681B0528D56A
+:10364000201C01218DF739FE23E0B249086880076C
+:1036500015D5F8221059084CFCFF75700900210897
+:103660004310518021E069000400D44900AC4A11A4
+:10367000600120000778F716FE002E0DD1201C8D6A
+:10368000F7C2FC09E0E069000403D5201C8DF76E49
+:10369000FD02E00123A34803700120F0BC08BC1820
+:1036A0004700B5FC300068002801D0B6F7CEF9001D
+:1036B000BD70B59D4D03685B019C49CE18041CFF8D
+:1036C000F76DFEE069000403D4201C00218DF7F89B
+:1036D000FD20687CF7AFFC201CFFF7E2FFE06900EB
+:1036E00006C00E0A2817D1012120688140904803A6
+:1036F000688B430360201C74F7C1FCE069F82188E3
+:103700004340210843E061206883F7E4FF201CA0C8
+:1037100030042103F0DFF8211C301C01228FF7DC7C
+:10372000FCE069F821884318210843E061F821088A
+:10373000590721084340218843F821085120680196
+:10374000218140CA437B490B6813400B606DF70E23
+:10375000FBE069000402D42B784CFCFF7071090077
+:10376000012B04D05C342088FFF7A6FD01E0002384
+:103770002B70012070BC08BC184700B5011C1D202F
+:1037800078F708FE08BC18470000F0B5071C0024B5
+:103790006B4E0622151C6543391CA81903F096F8D8
+:1037A000002805D1A8190621BDF706FF012003E076
+:1037B0000134042CECD30020F0BD70B5061C0025AC
+:1037C0004E236B435F481C18A11C301C062203F0DB
+:1037D0007DF8002803D00135042DF1D310E0221C20
+:1037E00025329107890F01D1106808E0521AC900EB
+:1037F0001368CB402020411A50688840184300E0ED
+:10380000002070BDF0B5002900D1ABE0041C00D150
+:10381000A8E0C8694005400F2070C8698004400FC7
+:103820006070486BA21C93079B0F01D1106006E0EB
+:103830001070000A5070000A9070000AD070886BF7
+:10384000A21D93079B0F01D1106006E01070000AC3
+:103850005070000A9070000AD070C84CFCFF6B7268
+:1038600009006B221C0A3293079B0F01D1106006DE
+:10387000E01070000A5070000A9070000AD07008C2
+:103880006C221C0E3293079B0F01D1106006E010D2
+:1038900070000A5070000A9070000AD0700D1C5021
+:1038A000352888A074000AE074AB782375EB786340
+:1038B00075CB7BA3758B7EE375CB7E237624480383
+:1038C00078637698204058400FA076E889E076002B
+:1038D0000A20770F1C9C37B86D221C1D3293079B62
+:1038E0000F01D1106006E01070000A5070000A90BD
+:1038F00070000AD070261C2036C86C4001C00F70C2
+:1039000070C86C0001C00FB070C86CC000C00FF070
+:1039100070C86C8000C00F30711022291C103170EB
+:103920001D17E05CC80800181B0800641B0800D4C1
+:103930005008005DC8080064A709007C290800E45D
+:10394000C70800B4C40800BBA50900D3A509003C02
+:10395000A40900BDF712FB1022291C20314CFCFFEA
+:1039600066730900301C1530BDF70BFB4534F87841
+:103970002070F0BDF0B5002800D1B8E00C1C00D1DB
+:10398000B5E04978CB0022785207520F1343C26941
+:103990003F2109028A439906890C0A43C261A31C8C
+:1039A0009A07920F01D1196808E09B1AD2001D688E
+:1039B000D54020218A1A5968914029434163A31DAB
+:1039C0009A07920F01D1196808E09B1AD2001D686E
+:1039D000D54020218A1A5968914029438163231CCC
+:1039E0000A339A07920F01D1196808E09B1AD20096
+:1039F0001D68D54020218A1A596891402943C16326
+:103A0000231C0E339A07920F01D1196808E09B1A04
+:103A1000D2001D68D54020218A1A59689140294357
+:103A20000164061C5036E17C0902A27C11433180FE
+:103A3000637DF370237DB370A37DC373E37D8376D1
+:103A4000237EC376A37E98210A58D200D208191C7F
+:103A50001D2349070A4398210A50217F0902E24C9D
+:103A6000FCFF617409007E1143F181071C9C372221
+:103A70001C1D329107890F01D1156808E0521AC93F
+:103A8000001368CB402025691A55688D401D43BD41
+:103A900065251C20356B78002B04D0C16C01229267
+:103AA000061143C164AB78002B04D0C16C0122D253
+:103AB000061143C164EB78002B04D0C16C012212C3
+:103AC000071143C1642B79002B04D0C16C01225231
+:103AD000071143C1641022691D301C1030BDF7541A
+:103AE000FA1022291C1531301C2030BDF74DFA4543
+:103AF000342078F870F0BD10B5042810D24E214162
+:103B00004334484418002020706070A01C0621BD7A
+:103B1000F75DFD314A1188201C0830BDF757FD10B4
+:103B2000BD70B5FF230133C458002C03D0201CB551
+:103B3000F79AFF0CE0061CC518142099F7EDFF0456
+:103B40001E0ED02860321C25490023B5F76DFF24D6
+:103B50004A11682448BDF754FE011C201CB5F76FBC
+:103B6000FF4CFCFF5C75090070BD10B5041E13D03E
+:103B7000F830006840070FD5201C28308DF7D7F8A3
+:103B80001B490B68FF2B01D08DF7F3F8E069F82192
+:103B9000884340210843E06110BD10B5041CFFF7C5
+:103BA000E4FF13225C23195B002093F74EFCE069CD
+:103BB0000006C00E0A2803D10A21201C79F785F8D7
+:103BC000201C7FF75AF8201C7FF785F9201C7FF70F
+:103BD00071F8206877F7CDFC10BDC046D3A5090069
+:103BE0003EA40900F345020040A40900D4300000BF
+:103BF0008C06080010B5AC4AAC4900780302AC4C06
+:103C000020680004184308601078C302086818434D
+:103C100008606068000423681B0C184348605078F3
+:103C200088600020C860012010BC08BC184710B58F
+:103C3000041C00290AD18DF7F3FD70342078042884
+:103C400015D19C484379012B11D10EE0022906D1F0
+:103C50005030407F76F71DFD0023A38107E0052942
+:103C600005D1004CFCFF57760900F0E7F800280169
+:103C7000D18DF7B9FB10BC08BC184770B5904D2B1F
+:103C800068FF2B56D1002077F7E0FA2860FF285014
+:103C9000D001238B4803608B4803708B4C0323E3D4
+:103CA000748B480168201C6FF71DF92523237402CB
+:103CB0002363743323A374201C7030042303700027
+:103CC00023437023632384824803685B0063842456
+:103CD0002000230355E3818EF771F8286877F77386
+:103CE000FD7D4E30607368802003437360286877E1
+:103CF000F7F2FC211C503103680B77C269C86807D2
+:103D000026B0433240104301225202104380221059
+:103D100043C8600023CB750B6813430B6001238BF2
+:103D20007702234B776D496D488DF7A8FB201C6FF8
+:103D3000F75CF8012070BC08BC184770B5061C047D
+:103D40001C0023674803605F480378002B04D140C0
+:103D5000235C490B60980527E04B0704D57034209D
+:103D600078042867D14CFCFF5277090044E08B07A8
+:103D700024D5351C70352B78022B5FD169785648D5
+:103D800002685A4803684B43301C934213D95300CE
+:103D9000638418360123737304232B703323A374B5
+:103DA00000236B706FF7C2FA2023474E3360D805AB
+:103DB00078F791FA42E0013169701EE0CB073DD5FA
+:103DC000351C70352878022838D315D0042817D32D
+:103DD00034D147490868430E47490B6047488DF77F
+:103DE00044FB02232B704823A37440490B685B00FB
+:103DF0006384183401236373301C6FF797FA1DE056
+:103E0000102331480360180678F765FA33480368D1
+:103E10005B00638418340123637304232B70002335
+:103E20006B70301C6FF7E0F835493548062202F018
+:103E300062FD002802D133486FF7D6F870BC08BC89
+:103E4000184731498868002805D0007C24380128AB
+:103E500001D8012000E00020704700B51D211C485A
+:103E600002F051FD1921274CFCFF4D780900480252
+:103E7000F04DFDFF23274A1360144A1360002326E8
+:103E80004A1370FF23254A13608DF7B4FA00BD1062
+:103E9000B583B0041C0C22E92109036846BDF782F2
+:103EA000F8694600200A7801312254174B1A540150
+:103EB000300628F7D34B78A37103B010BD65A7096E
+:103EC00000B8890E0038800E00A42C08008C06086B
+:103ED00000D4500800BEC10800F0500800B0060829
+:103EE000009006080000820E00D850080064000808
+:103EF0000018800E009806080098830E00E4500811
+:103F000000E05008000BA70900E8500800645108C1
+:103F1000006C21080088060800BFC1080050A409F1
+:103F20000000B5002346490B7046490B7046486FA8
+:103F3000F79DF846490868FF2804D077F724FBFF6F
+:103F40002342490B60012342480360424803780141
+:103F50002B04D18DF782FE00233E490B7000BD106B
+:103F6000B5041C70342378022B4CFCFF48790900FF
+:103F700024D13B4B1968043B1A68CB0717D4530371
+:103F800015D54B0313D50723DB040B400FD1530684
+:103F90001A0F032A0BD18B05DA0E082A01D00C2A3E
+:103FA00005D13048FFF777FF0323237006E0CB07E6
+:103FB00004D46378013363706FF7BFF910BC08BC99
+:103FC000184730B582B0041C27490B7E002B39D12D
+:103FD00026490B68702003401D09A37BAB4231D0FA
+:103FE00023490B68FE20034000D00123002B26D17B
+:103FF0000020B2F7D5FE002821D11E490B689B0690
+:104000001DD48BF70BFE002819D16946281C9AF79E
+:1040100070F868466FF7F7FE68469AF79DF800203B
+:104020009AF7FDF81448002343628362009B9B08C3
+:104030009B00416B59180B011B09436302E0A07BF5
+:104040009AF7EDF802B030BD5CC80800BEC10800A8
+:10405000F05008008C060800D4500800BFC10800CA
+:104060002C8B0E0038A509002C2D084CFCFF437A40
+:1040700009000024860E00B4C4080008800E006CFD
+:10408000210800037B0C30FF2B04D14378202B0147
+:10409000D1002000E001207047F0B582B00C1C0177
+:1040A000D10420A3E0051C52480268002A08D02849
+:1040B0001CC3F715FF002803D0FF300006000E9543
+:1040C000E0F82148590007800F01282DD1E8690048
+:1040D000042AD4237B5B0827D0474908688007233C
+:1040E000D5201CFFF7CEFF00281ED0281C28308DBD
+:1040F000F73DF9F822505902229043F822505120FE
+:104100001C99F735FD0821281C7EF789FC8CF77077
+:10411000FF0123394A1370394A1168281C8CF7575C
+:10412000FF281C8DF793F8BBE72F687B0135481EED
+:1041300018F37F012B55D0237B5B080ED1637B05E1
+:104140002B02D1304900910DE030490091042B0938
+:10415000D0DB002E48C218009204E0201C0C307AFC
+:10416000F75AFD009000990B79637700234CFCFF10
+:104170003E7B0900236002F0BCFB01900099486877
+:1041800040010BD4B068002805D003682360B368F1
+:104190001C60B46011E0B46024600EE0F068002898
+:1041A00005D003682360F3681C60F46001E0F460EC
+:1041B0002460211C281C90F78CF80123BB40164971
+:1041C000086818430860019802F09BFBE869000644
+:1041D000C00E0A2803D1381C73F7A5FF09E0082890
+:1041E00007D1381C6CF758FE03E0201C99F7C3FC7C
+:1041F0005AE7002002B0F0BDC046BCC80800641BEE
+:104200000800BFC10800885008007C29080044A3AA
+:1042100009004CA309006CCF05007429080070B593
+:1042200082B0002301935F490868202800D1B6E0DE
+:1042300010285AD15D49086877F75FFA051C5B4E74
+:10424000301C76F782FF002811D0041CF822135886
+:1042500001221343F8221350EB69C06907210B4078
+:1042600088431843E061286877F798F90CE02C4CF4
+:10427000FCFF397C09001C311C281C28300622BC9C
+:10428000F79FFEF820435902208343F82043513121
+:104290001C201C8CF7E5FD002805D0F820035901EF
+:1042A000200343F8200351201CFFF756FC02F024A2
+:1042B000FB012321688B40404A11681943116002B9
+:1042C000F023FB20686CF7F9FCE369F820834310C6
+:1042D000200343E361206801216CF75DFE201C8F01
+:1042E000F799FE201CFEF7C6FEFF233148036059F4
+:1042F000E0FF23013398424AD12E4876F729FF0484
+:104300001E50D077F795FBE369012000068343F840
+:1043100020834310200343E361E36C5B005B08E30D
+:1043200064EC210B59000683430B51201C00217BB8
+:10433000F70DFC201C00217BF764FC6B4601AA21D1
+:104340001C4C31201C283096F764FA002806D00156
+:104350009B002B03D0201C7BF75CF803E0211C00A2
+:104360002078F73EF8FF23124803601448036801E1
+:104370002B4CFC5C347D090018D1E3691B0415D477
+:1043800011480368002B03D1104803680E480360EE
+:104390008CF700FD0AE0402802D18DF7D8FC05E03B
+:1043A00001235B02984201D18DF769FC012002B024
+:1043B00070BDC046D45008008C060800E8500800C4
+:1043C000B4C4080088C808008850080048A4090040
+:1043D0004CFCFFBC7D09009F480023036083607094
+:1043E0004770B59D490B68180A9D4A402803D19C27
+:1043F00049D1609C4906E09C490143D16003021900
+:10440000189B4BC9189B4D29609B4C9B4963685B6B
+:104410000E2468E407E40F634009D0402807D17FE9
+:104420002464020B68964D2B400125ED0406E0FD47
+:104430002424020B68924D2B400325AD040B600B26
+:10444000682B430B6000238E4E336003040B21095D
+:104450000459182143032631438B4E31600F30102D
+:104460006070BD10B57C4A1368002B05D061210136
+:10447000220A546EF75BFF05E0041C6EF7B5FD20C1
+:104480001C00F0B0F810BC08BC184710B5041C7E26
+:1044900048416A002902D1836A022B09D903290401
+:1044A000D1836AFF203630834202D2201C6EF7F798
+:1044B000FF60237648195D405C80210143754A11F5
+:1044C000606D480368744A136043681720800603D0
+:1044D00043534CFCFFB77E090060FFF785FFA37BC9
+:1044E000704A136000236F4A1360082113206DF790
+:1044F00067FE10BD30B5041C002927D1FFF7C9FFA6
+:104500006A4D61342178694A0023D056012907D1C8
+:104510007DF7B5FF0006010C2868654A104006E0EB
+:104520007DF7ADFF0006000E2968090A090208435D
+:1045300028604A4A11685F484143494A1068000AA6
+:104540000430BDF76CF95C4A106014E0022907D111
+:1045500001235A490B604034607F76F7A5F80AE0E2
+:10456000052908D1002355490B60FFF76EFC002890
+:1045700001D18CF740FF30BC08BC184700B5374A62
+:10458000011C1368002B0DD09368002B0AD193896E
+:10459000936060310A780023022A00D2531C0B700A
+:1045A0006EF7C8FE08BC184700002C49037D022B9B
+:1045B00007D10868431E00D30B608868431E00D3F0
+:1045C0008B60704710B5037D092B0CD13D4C3D4AE3
+:1045D000106877F74CFC70B27F090000F92060602A
+:1045E000688021884360603A4AD078206210BC0815
+:1045F000BC184770B583B00024364E4E256543ABDA
+:1046000019991C3548062202F07DF9002803D001D3
+:1046100034042CF1D305E0A9194878000209780880
+:104620004300E0002001A9C8700821000A02AA1076
+:1046300070012301A883706846831D2848032293D4
+:10464000F70DF803B070BD4CFCFF1E800900F0B5FB
+:10465000061C0F1C054C6368FF2B45D1012076F723
+:1046600003FE6060FF283FD100207FE04CA40900DA
+:1046700094060800C8890E0040C07DC0447E00003A
+:1046800000D07DC0043E00008C800E0040A50900D3
+:10469000B88A0E00FFFFC3FF94830E0098830E00BC
+:1046A0006C210800A8060800A4860E0040820E00B7
+:1046B00000830E00F8800E0004830E0092030800B1
+:1046C000FF00FFFF710200009C830E00F0FC0E0053
+:1046D00000820E0050A409000BA70900D3A5090011
+:1046E000B7C10800B6FC00002A4D0123EB74216914
+:1046F000281C6EF706FC2760A389A360264979432E
+:1047000026480068000A0430BDF790F82449086084
+:1047100024232B7402236B743123AB74281C603068
+:10472000002303700123437000238370C3702B6246
+:104730005D2002234355606877F754F8A87301237E
+:10474000EB73184F391C301C8C4CFC791981090013
+:10475000F7A7FE606877F749F8391C6EF74AFA3117
+:104760001C13480622BCF729FC2169281C6EF7DBC4
+:10477000FB0120F0BD09480368002B00D001230095
+:104780002B09D0007D002806D0072801D00020008A
+:10479000E00120002800D00120704764510800711A
+:1047A000020000940608009C830E0040A509000B3F
+:1047B000A7090000B5F8210B585B0702D40421803B
+:1047C000F720FB00BD4CFCFF9881090030B5051CAB
+:1047D000041C08790002C9780843012176F715FD09
+:1047E000002802D112232B700EE00834F42109585E
+:1047F0004907490F00D00121A1715C300088E071A8
+:10480000000A20720323EB7030BD000070B582B047
+:10481000051C0024200123181B0145481E18F821FF
+:10482000885940071AD4306876F7DEFF69688842F5
+:1048300014D1301C77F704F900280FD03D4B69469E
+:104840000B8002238B705C23985BC870000A01A95F
+:104850000870394A6946301C81F78AF801340B2CFC
+:10486000D8D30123354A1376686872F732FE686838
+:1048700073F746FB6868B2F773F9696830486EF7FA
+:1048800028FE69682F486EF724FE69682E486EF787
+:1048900020FE69682D486EF71CFE6C68002C45D11F
+:1048A0000C2363432A481D18A87A022831D3042810
+:1048B0000ED32ED1281C82F704FF061C288000236B
+:1048C0006B72E87976F7184CFC9593820900FFA08B
+:1048D0003006810C3028E0281C82F7F6FE28800084
+:1048E000236B72EB7999005B189B011B495E1831B1
+:1048F0001CB831487100230B71C436B379002B15F5
+:10490000D073792B80B3796B8033796B72281C82DA
+:10491000F7DBFE7071301D07E0002807D0281C82ED
+:10492000F7D3FE2880281C09300023037001340EC1
+:104930002CB9D302B070BD88380800530C00004376
+:10494000720100CC2F0800B42E0800682E08001C4D
+:104950002E0800D037080040490800140B08004C0E
+:10496000FCFF7E830900F0B5051C13235B049F4FF9
+:104970003B60082105206DF706FC9D4F3B689D4874
+:1049800003403B603B68C00703433B608B4F3B6881
+:1049900002273B43894F3B60974C98482062012394
+:1049A000974F3B60974FB868606278686065A86908
+:1049B0002430C17880220A43934F3A60934E837823
+:1049C000B07B002B0ED1924D0021B0F72FF9B169C9
+:1049D000081C243042781302007B18430022B0F7F1
+:1049E0003CFB09E00121B0F721F98A4D8A4A13689E
+:1049F0000120400603431360884805608848838A85
+:104A00008848036000232360F0BD05238381836908
+:104A10002633187801280FD10021CB4382490B603F
+:104A200000234B607D490B68802003430B607A496B
+:104A30000B68800403430B60704700B5C369002B0B
+:104A400023D013235B04694A13605F4A13685D4AED
+:104A500013605B4A1368594A1360554A1368644AE5
+:104A6000134CFCC779840900607248724A1168418E
+:104A700060724A11684161714A11688160714A131C
+:104A8000680360704A1368704A136061486EF70FDC
+:104A9000FB08BC1847000030B5052383816C4A1120
+:104AA0006806220A40062A02D181692A3108E08B71
+:104AB0000702D481692C3103E04B0704D481692EAD
+:104AC000310B8801330B8013235B0449490B605081
+:104AD00049CB69002B12D1524C2568C37B012B0CAA
+:104AE000D12368802083432360022099F747FC800C
+:104AF000231D43A06899040843A060256030BC08CA
+:104B0000BC184713235B043A4803604148C369005B
+:104B10002B02D1434803680360704700B5002901A8
+:104B2000D1FFF724FF08BC184700004CFCFFAC86FF
+:104B30000900F0B581B0051C0C1C08790002C97889
+:104B4000084352D00020ADF798FBFF2801D109237C
+:104B50004CE0071CADF752FB0023038121790902C9
+:104B6000E27811438186C186051C83F79BF82E1CD1
+:104B7000B03673885808E8806379252B0ED23948FF
+:104B800000900521BCF763FC6179C8084907490F0B
+:104B900001228A40009B195C11431954B07BFF230A
+:104BA0003D334343314819180091281CAFF74EFD9F
+:104BB0002F4885662521281CFDF7DBFF307B00216F
+:104BC000AFF783FF0523AB80381CAFF7CEFD00990C
+:104BD0009E3101200870381C002100F035F8A279C0
+:104BE000E179381C00F005F801E012232B7001B0C8
+:104BF000F0BDF0B50C1C171CADF700FB061C201D0A
+:104C0000B4F7DFFB051E1ED0B18D0B051B0D012077
+:104C100040031843210408432B1CA907890F01D125
+:104C2000186006E01870000A5870000A984CFCFFE3
+:104C3000A787090070000AD8703A06120E210409ED
+:104C40000C281D91F75BF9281CB2F74AFFF0BD3024
+:104C5000B50C1CFF233D3343430548C51801F074D0
+:104C6000FDA2352C8001F078FD30BDC046F44E0821
+:104C700000349D080038B0080000B5C37B012B0547
+:104C8000D1AC490B78002B01D101230B70B2F7593D
+:104C9000FA08BC1847000000B52C22A749A748BC59
+:104CA000F7B7F8A648A64B1860A6494160A6498107
+:104CB00061A649C16100BD00B5017D032901D00491
+:104CC0002902D1B2F7A2FA09E0037D062B02D10036
+:104CD000F008F803E0092B01D1B2F7C8FA08BC18B4
+:104CE00047000070B582B0051C041C8034E37A00D4
+:104CF0002B08D0036DBE3319780820AEF707FD00EE
+:104D000023A376E3726378032B28D0A87B99F72B33
+:104D1000F84008218C431A1E04360C618C00291DB2
+:104D2000D08E421BD36078012806D1688CBCF74C2A
+:104D3000FCFFA2880900D4FC062803D13E2002E033
+:104D4000042803D008202B6DAF3318700323637041
+:104D5000281C6EF786F82B6DBE3319780520AEF748
+:104D6000D9FC31E06068002808D00090002301934E
+:104D70006946A87B99F74DF9002363606378032B9C
+:104D800011D0FF201930285A864209D8A87B85F710
+:104D90006DFB002804D1281CB2F7A7FD002802D023
+:104DA0006D49C8780CE06378002B07D16B4BA87B6A
+:104DB000185C032802D26849887801E0664948787F
+:104DC000A874281CB2F783FC02B070BD70B5041C37
+:104DD0000E1C5A4D2878002802D0013828702878F7
+:104DE000012804D85E4A13685E490B40136000280E
+:104DF00016D0201C9830C378002B02D18188CA06B7
+:104E00000ED58379002B11D0311C201CB0F7D1F9BD
+:104E10002B78012B0AD9311C201CB0F79DF905E035
+:104E2000201CAFF762FE201CB2F70BFC70BDF0B582
+:104E3000814CFCFF9D890900B0041C051C803500D5
+:104E400027AF81EF76FF230533C618F37D0133F3D7
+:104E500075C37B012B13D17378002B19D144480300
+:104E6000689B0715D5A07B98F785FF80084100A0B7
+:104E70006981420DD098F719FF4000686008E00191
+:104E800023737036480378A3740123DB07B361B73B
+:104E900070374800680090830722D535490B685B5E
+:104EA0000602D40098430710D5A07B98F763FF4013
+:104EB0000828846B78012B08D102236B70236D586E
+:104EC0008900016884201CB2F7AAFAF37D012B0740
+:104ED000D17DF709FA011C201CAEF7A0FC01F0E51A
+:104EE000F97DF701FAB074009906220A40062A1EDD
+:104EF000D1236DBE33187885F7EDFA201C00F0BF82
+:104F0000F8F078012804D81B4980000B5C01330BB2
+:104F100054E37B0099201C002B02D1FFF75AFF01BC
+:104F2000E000F06DF8201CAFF7E3FDAF7234E0B79E
+:104F3000758B074CFCC8988A09002AD5A87A1049B5
+:104F40000B78984225D21EE0C046FDCC080078E4DC
+:104F5000050080A50900781508002B8809009B89A9
+:104F60000900ED87090074150800E3C008001C80E3
+:104F70000E00FFBFFFFFBC8B0E0040150800ECB019
+:104F800008001CCD0800E37B002B02D00130A87282
+:104F900006E02B7E002B00D02F76201CB2F758FBAA
+:104FA00001B0F0BC08BC18470000F0B5061E20D0C8
+:104FB0000768002F1DD0407CADF72EF9051C707CD2
+:104FC000182141430C484418786890F7CDFD98F7B4
+:104FD0004EFD381C98F705FD00233360217A01311E
+:104FE0002172217A05480278A88D90F702FD0023EE
+:104FF0002372F0BDC046F4B008007C1508004CFCDC
+:10500000FF648B090070B5051C0E1C041C8034A3C2
+:105010007F002B1ED0B0F7D3F8184A537C012B0920
+:10502000D9E37E002B02D1A08BC10603D5311C2809
+:105030001CB0F798F8CD23585D00280AD0FF23054F
+:1050400033E818837D002B04D04378002B01D10175
+:105050002383700B490B681B070FD56378022B0C59
+:10506000D1FF201630285C002807D0A0898004805A
+:105070000E0023002800D10123237670BDECCC085C
+:1050800000E02C0800F0B5041C051C3A480668989E
+:1050900035A8880712F306D90FE9707307D90F03F3
+:1050A00007DA0F002F04D0344803685B0300D511E2
+:1050B0001CFF231533E0184378002B03D10029018E
+:1050C000D0012343708A4216D0AB79002B15D10052
+:1050D0002F08D0D0231859C168C91BC16002D483DE
+:1050E00068DB1983600122AA71201CB2F7EDFB2056
+:1050F0001CAFF7E0FB01E0002383713307DA0FA850
+:105100004CFCFF5F8C0900884307D90F8A4234D1D9
+:105110001C4F397C0A0702D5B304990E2DD1184AC9
+:1051200013689B0303D5B3079B0F032B25D00421E2
+:105130004840A880251C5035AE87B304980E1CD07B
+:1051400020221149BB68181D01F004FBCC342078E3
+:10515000800712D50D490B68012080030340580BCE
+:105160000BD02B68BE331878ADF759F8AF303D211E
+:105170000170012028870023AB87F0BDA88B0E00AB
+:10518000E02C0800ECCC080080980E00BC8B0E00D0
+:1051900010B51F4C2068002805D08008800098F7C3
+:1051A00023FC0023236010BDF0B5051CC668B4695C
+:1051B000002C16D0B0F797F9002812D1154F3A1CE1
+:1051C000211C1331E01CB0F76FF8381C00F00AF80E
+:1051D0000023AB60EB60A008800098F705FC00237B
+:1051E000B361F0BD00B582B0262369460B80019003
+:1051F000081C76F789FF02B000BD00B54368002B9C
+:1052000004D04CFC1E5A8D09001022044800219243
+:10521000F768F900BDC046E49C08001CA709001708
+:105220002000004CFCA0908D0900F0B583B00291E5
+:10523000FF233D3343432248C618356D01F08BFAF6
+:10524000371C90372C1CB0348E239A5B02998A1A33
+:105250001204120C638853433A6FD2185101490962
+:10526000019101F080FAF37B012B0ED16B8B5B0077
+:105270000093288B4000019A101841014909181C1D
+:10528000BCF725FAA0800098E080281C82F714FD66
+:10529000F37B002B0ED1E68870086883A188019803
+:1052A00098F703FDE288011C101CBCF710FA301AB5
+:1052B000400828830298431E3B800123BB7203B041
+:1052C000F0BD349D08004CFCF8348E0900F0B58127
+:1052D000B00090ACF79CFF041C0027364E336BDB0C
+:1052E000071FD5B4421DD0251C2C354223A97D9A19
+:1052F0005D914216D1291C1031301C3C3006220130
+:10530000F039FA00280DD101F025FA051CBE36301F
+:105310007800F036F8281C01F025FA3078AFF75203
+:10532000FA03E0C03601370F2FD8DB0098B2F7A39D
+:10533000FB251C0123EB852C35201C80F78BFE0000
+:10534000980021AEF78BF81C4A13681021DB060386
+:10535000D5A971201CB3F717FA201CB1F7D5FBBEF5
+:10536000342178FF223D325143144BC9187F23FF6B
+:105370002023300B54A623FF2017300B5401B0F02C
+:10538000BD10B5FF233D3343430C48C418201C8097
+:10539000304178012907D1418C608CBCF7A3F90614
+:1053A0002803D13E2002E0042903D00820236DAF5A
+:1053B00033187010BD2890080040150800349D086F
+:1053C000004CFCC0308F0900F0B5061C046D2B4862
+:1053D00003689E4201D1B0F7EBF8301CAFF727FF0E
+:1053E000351C8035288901380ED32881288904236B
+:1053F0006B70002808D1301C6DF735FDBE34217864
+:105400000520AEF789F938E0687800281FD1B07B15
+:1054100098F7AFFC4008B034A16898F745FC012329
+:105420009B0698420CD267883B1859014909381CE1
+:10543000BCF730F97843A168081840014009A06022
+:10544000A06800236B700223F374B06112E002289D
+:1054500010D1AB7E002B0DD0E889298A431A18049D
+:10546000000C074B984205D2EB7A002B02D1301C7E
+:10547000B2F77FF8301C6DF798FEF0BD6C21080084
+:10548000FF7F00004CFC9028900900F0B5051C1F20
+:1054900049FF230533C418E378980000230B5443D5
+:1054A00018581C00230370AF692B6D1889421C2605
+:1054B0007C688C5043B04063681B18580140093821
+:1054C0001A01239B06984220D2B31D20789840A34E
+:1054D00068D901EB7B002B00D15143E26882420086
+:1054E000D3101CBCF7BCF8011C802800D980219F78
+:1054F000352970074803789E4202D2701C2074043C
+:10550000E000230434191C381C0BC4F0BDC046EC69
+:10551000B008006F1508004CFCE8C0900900F0B519
+:10552000061C071C9C373888102101401D490BD0F0
+:105530001D4BF518EB7898000A5C9301AA68D21805
+:10554000AA604318597811E0174BF518EB789800CA
+:105550004118487800280DD08C780978614389017A
+:10556000BCF77BF8A9680918A960211C8B01E868C1
+:10557000C018E8602B7C002B11D1E86800280ED001
+:10558000AB68D901F37B002B03D1336D1A8901324B
+:105590005143BCF762F8802800D98020F870F0BD34
+:1055A000C046ECB0080004010000F0B50D1C114C21
+:1055B00020600B68DB0701D598F758FB0F4E0020E1
+:1055C000706637680E483840306098F764FE98F788
+:1055D00062FE2868E0606868A0600220706698F744
+:1055E0005AFE98F758FE98F756FE37600020E060A4
+:1055F000A060F0BDC04600820E001C800E00FFFFC0
+:10560000FFFD4CFC34AC91090000B54068084A131A
+:10561000681979002909D1074A13681B0605D400C7
+:105620002801D098F7BBF9012000E0002000BDC0A0
+:1056300046C04F0800E02C08004CFC7CF8910900A3
+:1056400030B5041C80304378002B1BD10323E37456
+:10565000252101230B55837E002B07D0236DD98B89
+:1056600009014184A36903840123C372618CA06989
+:1056700074F772FD238C984204D02084216DB031E0
+:1056800088800880FF230133E158E518A06998F766
+:10569000E3FA216DB2310A88011C101CBBF7D2FF5E
+:1056A000011C201CB2F726F8A3692B60201CAFF761
+:1056B00034FF00236B7130BD4CFCFF80920900F079
+:1056C000B581B02F4806682F4805682F4803780039
+:1056D0002B52D12E480368AB4203D12D480368B347
+:1056E000424AD02C4C2D4FFE20284007D1002D03DC
+:1056F000D02B480368DB0301D5002E1CD063681B48
+:10570000071B0F022B02D0022098F739FE25480014
+:1057100078606324480078A06366F7B7FF01F00D56
+:10572000F8822141432068642250436430BBF785EE
+:10573000FF431C3B6018E063681B0702D000209801
+:10574000F71EFE00206063A063184A1368009317D9
+:105750004A1088392109014143181CBBF76EFF38F4
+:105760006014490098BBF769FF134908603868A0C6
+:105770006107490D6007490E6001B0F0BC08BC1814
+:1057800047C04614CD0800B4C4080008C30800B8D8
+:10579000CA080068A409000C000F00DC5E0800FCC9
+:1057A0000A080009C308000AC30800C02D0800E861
+:1057B0000A080020CF01009C000F4CFC657B930978
+:1057C000000030B5041C13490B685D78B0F75DFF2D
+:1057D000022C01D0042C16D1281C203081F7A9FE00
+:1057E000042C07D10D4800231A1C191C91F745FE03
+:1057F000022102E0022C03D10821281CADF705FE8E
+:10580000281CACF782FD05490B689879012801D165
+:10581000ACF7E4FD30BDC49C08000E200000C89C1D
+:1058200008004CFCFFEC930900F0B5041C00216E4D
+:10583000F74CF8002803DA01234E4843716FE00665
+:105840001C251C7835687A00280DD1A07B98F76359
+:10585000FA4008236DB833196898F7FFF900280457
+:10586000DC687A002805D0002E03DD201CB1F7BDCE
+:10587000FE55E0E37B012B03D1002801D101236B0E
+:1058800072A878802101433C4A1160082105206CF0
+:10589000F7A4FB384A5379002B41D1AFF75BFE37B1
+:1058A0004F381C052100F040FF03233B74201C00EF
+:1058B000F037F8AFF70CFEEB8A002B0AD1FF201669
+:1058C00030205C002805D1AFF745FE3B7C08200363
+:1058D000433B740023AB74FF230533E6180023F326
+:1058E00075201CB1F788FF264A13780021002B0091
+:1058F000D101211170F078FF2806D16B7A022B03B9
+:10590000D1081CF070A3697360012805D8F1708B71
+:10591000001C48C0187B7C8370201CAEF7ADFFF0E4
+:10592000BD30B5844CFC71E79409007C18490B78B4
+:105930008374051C012200216DF769FEAC742C6D87
+:10594000B223195B0239884200DB081C114941432C
+:10595000E5208000BBF774FEFF210531695C8842B9
+:1059600000D3081C32342178490701D5012801D819
+:10597000002800D101200349487430BDA42C080040
+:10598000A4860E00ECCC08006C150800ECB00800F2
+:1059900074150800710200004CFCFF5C950900F0D2
+:1059A000B583B0012100910027C0237B431A481C16
+:1059B00018206BC00729D5251CBC356B78002B241B
+:1059C000D1261CE38D2C36002B1FD0B379002B027F
+:1059D000D00021009119E0211C0C310F4805220054
+:1059E000F09EFE002811D00223B371201CB2F72ACA
+:1059F000FE01A9201CB2F712FE01A9A878B1F7ACEC
+:105A0000FE082201A9A878B2F72EFF01370F2FCB8D
+:105A1000D3009803B0F0BD28900800004F08001094
+:105A2000B5002912D140498B79002B0BD03F490B8F
+:105A300069834207D13E4C2368DB0603D54631011A
+:105A40002008700EE0AFF751FF0BE0022909D101E9
+:105A50001C48318A880B7E9B18013383814B889BBD
+:105A60001A4B8010BC08BC184730B5314A11680B7E
+:105A700006D90F884218D12F4D2C68ACF798FCC17D
+:105A8000780B028178194302791304194342791380
+:105A90000619438C4208D12A1F134CFCFF57960964
+:105AA00000681A0C41780B0200781843824201D03A
+:105AB000002000E0012030BDF0B583B0051C00914E
+:105AC0000026041C58342379002B2CD0012601A871
+:105AD000B0F723FA071C6379002B13D0E378012B6E
+:105AE00007D13023585DFFF7C3FF002801D1061C02
+:105AF00019E02835AB79012B04D101A9381CB0F786
+:105B0000C1F8061C0F480378002B0CD0012F0AD1D6
+:105B1000029B03208003034001208003834202D1C3
+:105B2000012300980360301C03B0F0BDC046AC21D7
+:105B30000800642C080008800E00A88B0E008898CE
+:105B40000E006C9C0800F0B50D1C041C002D14D137
+:105B50004B488379002B0CD04A480369A34208D1F3
+:105B6000494A1368DB0604D5031C4633012018702C
+:105B700036E0201CB0F7B5FD32E0FFF754FF022DF0
+:105B80002ED1414A131C5421085B0004271C5237B4
+:105B90003988084318644433251C56354CFCFF52A1
+:105BA000970900A807800F01D12E6808E02D1AC0C0
+:105BB000002968C1402026301A6E6886400E431EB8
+:105BC00060A36B002B0CD1A06EC16B91603C304583
+:105BD0007908212D0200792843D06013680B431304
+:105BE00060A06E806A9064F0BC08BC1847F0B58273
+:105BF000B0041C051CB0F75BF858352B79002B312D
+:105C0000D0EB78012B10D1201C28308379012B0B8D
+:105C1000D16B79002B08D1007AFFF72DFF00280304
+:105C2000D1201C6CF796FC1DE0EB78012B1AD8A64E
+:105C30006E6846B0F775F96B79002B0CD1071C69BB
+:105C400046301C3C300622BBF7C5F8423637706C34
+:105C5000340120207012E02E231B5D012B02D1693C
+:105C600046B0F713F8A37C0B498878834202D12011
+:105C70001CB0F768FE201C0121AFF712FF02B0F044
+:105C8000BC08BC1847AC210800642C080008800E32
+:105C900000808B0E0074150800034B0448034CFC75
+:105CA0004B4D98090060044B044803607047C046A0
+:105CB000BCA3090050150800E8A3090064150800FA
+:105CC00010B5041C6CF749FC201C6DF7ACF84A2396
+:105CD000002018536523195D0220ADF7FDFCA36E6B
+:105CE000BC3318780021AEF7D9FE10BD4CFC18BCAF
+:105CF00098090000B5011C32310B78FB2213400BD0
+:105D000070AEF7E5F800BD4CFC50E0980900F0B526
+:105D1000061C0F1C104D2C68A07B97F7F5FF800820
+:105D20004300991C608CA26983185801400997F7B9
+:105D300086FF041C002F0BD0B17B2B68987B6DF77E
+:105D4000BBFF002804D1032C01D8002400E0033C51
+:105D5000201CF0BDC0466C2108004CFCFF349909A2
+:105D600000F0B586B0061C4568039581780A0712D5
+:105D70000F0092C07802908F0943191A790592009A
+:105D8000200490C04A13681879002804D1BE490B3A
+:105D9000681B0600D4C9E10098062800D9CAE105AD
+:105DA00098002808D0122806D0301CAEF783FA00DD
+:105DB0002800D1BAE1BEE1B54C2378B54908798312
+:105DC0004202D3201CADF772FAB148418800292362
+:105DD000D00378002B10D06378002B04D0AD489806
+:105DE000F75DFB002818D000236370A370A84A5009
+:105DF0008850214143A74805E02378A648002B049A
+:105E0000D15022514398F7FFFA06E098F747FB007C
+:105E10002802D0201CADF74AFA20782923191C410A
+:105E2000430191E11C8807800F01D10A6808E0094D
+:105E30001AC0000B68C3402022101A4A6882401A18
+:105E4000430198954B0099C95C81548018009903CF
+:105E50002901D0052957D18C4A13681B4CFCFF2F10
+:105E60009A09000600D44EE1477002998B1F037215
+:105E7000291C09300622BAF79FFF0635E11C880766
+:105E8000800F01D10A6808E0091AC0000B68C340FE
+:105E90002022101A4A6882401A4301988018023062
+:105EA000291C0622BAF788FF0098052817D1063565
+:105EB000E11C8807800F01D10B6808E0091AC000B7
+:105EC0000A68C2402023181A4B6883401343019983
+:105ED000C8180F30029A0C3A291CBAF76DFFE11C62
+:105EE0008807800F01D10B6808E0091AC0000A6812
+:105EF000C2402023181A4B68834013430199C818E5
+:105F00002830F17872688918C9780170FEE0FF07BF
+:105F1000FF0F0098042806D05C4A1368F178706877
+:105F20000818C078587259490868C379012B18D1EC
+:105F3000391C281CADF7F0FC009A042A05D1ADF7F6
+:105F40000DFD002800D1E4E04CE0FF2803D1391C0E
+:105F5000281CADF736FDADF716FD002800D14CFC2E
+:105F6000FF2A9B0900D8E040E050490B78002B3C09
+:105F7000D0009A042A17D14D480490291C103006ED
+:105F80002200F0C9FB002800D0C6E00499887D03F8
+:105F9000071B0FBB4200D0BFE08023034000D1BBF2
+:105FA000E04006400E1FE009228356012008568378
+:105FB0004200DAB1E03E480490291C10300622006D
+:105FC000F0AAFB002806D10499887D03071B0FBBAC
+:105FD0004200D1A1E0291C049810300622BAF7EF44
+:105FE000FE8023381C18430499887501210491E12F
+:105FF0001C8807800F01D10A6808E0091AC0000B4D
+:1060000068C3402022101A4A6882401A43019880CF
+:10601000184770291C02300622BAF7D1FE20480327
+:1060200078002B19D0E11C8807800F01D10A68087D
+:10603000E0091AC0000B68C3402022101A4A688287
+:10604000401A4301998818F17872688918ADF7D71A
+:10605000FD0006000EFF285FD106350298FA3000D9
+:106060004CFCEF259C090006000E02900098E11CF4
+:10607000012822D18807800F01D10B6808E0091A96
+:10608000C0000A68C2402023181A4B68834013439B
+:106090000199C8180021017225E0C04F0800E02CCA
+:1060A00008005DC30800BC9C080093C3080014E30B
+:1060B000050068C30800B8AF08008807800F01D149
+:1060C0000B6808E0091AC0000A68C2402023181AA9
+:1060D0004B68834013430199C818029A0272291C25
+:1060E0000930BAF770FEE11C8807800F01D10B68F8
+:1060F00008E0091AC0000A68C2402023181A4B6839
+:10610000834013430199C8182830F17872688918C0
+:10611000C97801700498002802D0237801332370D5
+:1061200023780A490879834202D3201CADF7C9F8C5
+:106130000598122804D1AEF781F9AEF7B6F904E05C
+:106140000398002801D097F71CFC06B0F0BDBC9C5A
+:1061500008004CFCFF189D0900F0B586B0041C0136
+:106160002203920292002200923249051C08682004
+:1061700035EB7A012B02D1304A117801E02E4A51D9
+:1061800078A17406220240062A51D12C4A166832A0
+:1061900007120F019201070BD529490B68987B0064
+:1061A0002805D0301CAFF7F0FF0090029000E0030C
+:1061B00090244F019805282BD1EB7A012B28D83356
+:1061C00006D90F287B414023D1ACF7F0F879680459
+:1061D00091B968059104A90231062200F09FFA00E6
+:1061E0002816D10398002813D00298002810D02038
+:1061F0001CB0F7B5F8009900290AD0201C6CF7A153
+:10620000F911490B68DB0703D4201C0021AFF75EAE
+:10621000FF0E490B681B060AD50198052801D0031B
+:106220002805D1391C3004000C0022ADF7F4FA0621
+:10623000B0F0BDC046BC8B0E005C150800A88B0EEC
+:1062400000B89C080080980E0008800E00E02C0822
+:106250000010B5564CFCFF139E09004C822099F7A4
+:1062600025FA000600160022A15600290ED0CB10F8
+:10627000CA1AC310D2187F23DB439A4201DA181CD2
+:1062800004E07F207F2A01DC1006001601060916B3
+:106290002170494A1368002B01D14848C17710BDCD
+:1062A00070B5002644480368002B01D184F784FDB3
+:1062B000434C4449201C0F300522BAF787FD0025C6
+:1062C0002819C07B97F74AFF36180135052DF7D3FB
+:1062D0003D48C36A5B011CD53C4803685B0518D484
+:1062E00000253B4803789E4213D001200A2D00D997
+:1062F000022040194100374885F7D4FC002805D01A
+:10630000291C201C0F3085F7DFFC013E0135252DAF
+:10631000E7D3211C0F313048052200F003FA002892
+:1063200009D0211C0F312C480522BAF74FFD6369B3
+:106330000120834363616369DB0707D4FFF732FB06
+:10634000616901229143104001436161002070BCEA
+:1063500008BC184700B54CFC9A0E9F090075F7035E
+:10636000FB00280BD11F480368002B07D114490BF1
+:10637000681D490868834201D1012000E000200027
+:10638000BD00B5B821194800F0D8F900230B4A1315
+:106390007000BD10B5041C15480368002B0BD020FD
+:1063A0001C002185F794FC1821201C85F790FC4ED9
+:1063B00021201C85F78CFC10BDC0466CA70900B4D9
+:1063C000C4080050370800F4460800F44E08005492
+:1063D00020080020040800A4030800E0340800009E
+:1063E0004F080010CD0800E4C708009034080014DE
+:1063F000CD08004CFCCCCC9F090030B55049086852
+:10640000504D09280DD14F4A1068411C1820BBF788
+:1064100034F903234D4A1370AB78834250DAA870E5
+:106420004EE000234A490B704A4C012801D007284E
+:106430001CD120680022191C99F7BAFB464908684C
+:10644000FF230133984203D20122002199F7B0FBC8
+:106450009BF782FF2B68DB0102D53F49086802E009
+:106460003E490B6858003D490B6818602B685B007B
+:1064700002D501233B48037031490868012801D047
+:10648000072811D120680022012199F791FB20688B
+:106490000122022199F78CFB3349206899F712FCFD
+:1064A0002068012199F7EBFB254803680C2B07D1E5
+:1064B0002C480378012B01D9012303709EF7A9FE14
+:1064C00030BD4CFCE044A10900F0B5324A106883AD
+:1064D000025C0F8307DD0F4303DE0FCB780727FF36
+:1064E00004B8435F07BF0A384310600B795B004F65
+:1064F00079FF07FF0F3B435B008F79FF07FF0F3BDF
+:10650000433E27B843DF06BF0E38431060CB790106
+:106510002189048843D907490B0843106083025B33
+:106520000F9C420AD1002C34D110688307DB0F9DE9
+:106530004203D14303DB0F9E422BD017480478005F
+:106540002C27D1A00023189B0114481D18D02148E6
+:1065500059C0041BD5E4214859C004C00E072815B2
+:10656000D300F06EF8061C281C8EF767F90C4B9AC6
+:106570008AD0235859000B00031105090D08435810
+:1065800051281C8DF762FF301C00F062F8013403C3
+:106590002CD7D3F0BD4C0B0800DEC00800941C08BB
+:1065A00000942008004CFCFF2CA2090070B5051CCB
+:1065B000006813498B7B002B1DD012498B79002B6F
+:1065C00019D0030CDC1D10480440201CB2F776FEE5
+:1065D000061C08D0221C291CBAF794FB281C97F72C
+:1065E000B5F9301C08E0281C97F7B0F900209CF79B
+:1065F000D8FF032002E0281CB1F7ECF970BDC046BB
+:10660000300B080080150800FCFF000078470000F0
+:1066100000C09FE51CFF2FE1E05105007847000016
+:1066200000C09FE51CFF2FE17410050078470000B3
+:1066300000C09FE51CFF2FE160E8010078470000E3
+:1066400000C09FE51CFF2FE17CD7040078470000C5
+:1066500000C09FE51CFF2FE190D7040078470000A1
+:1066600000C09FE51CFF2FE1FC40050078470000BB
+:1066700000C09FE51CFF2FE1304F05007847000068
+:1066800000C09FE51CFF2FE1CC5105002300000056
+:10669000394D090024000000354D09002500000097
+:1066A0003D4D09003500004CFCFF27A309000049BF
+:1066B0004D090088000000894D09008D000000ADE3
+:1066C0004D090092000000000000000000000003DF
+:1066D0000000025946020004000100000000000012
+:1066E00000000000000000000000000000000000AA
+:1066F00000000000000000955102002376090029E7
+:106700007709003F79090000000000000000000048
+:106710000000006754020000000000A37F09000091
+:1067200000000000000000D37E0900497E0900003F
+:106730000000005B7F090000000000897F090087DE
+:106740005102009F9504006D9904007F930400009E
+:10675000000000DD95090000000000A7960400007D
+:106760000000000000000005990400C39304009F8E
+:106770009504006D99040091A2040000000000FD42
+:10678000960900000000009D97090093A304006192
+:106790006709008F670900C3930400420500005E8B
+:1067A0000400006204000042054CFC4A22A40900D7
+:1067B00000006C04000062190000440500006C0435
+:1067C0000000621900000A00000001002100A086FC
+:1067D00001000C0019000200000000180000FF007A
+:1067E0000000800200008002000090A30900001851
+:0D67F0000008030000004EFC04FFFFFFFF47
+:00000001FF
diff --git a/firmware/ap6210/fw_bcm40181a2.bin.ihex b/firmware/ap6210/fw_bcm40181a2.bin.ihex
new file mode 100644
index 0000000..a8e3092
--- /dev/null
+++ b/firmware/ap6210/fw_bcm40181a2.bin.ihex
@@ -0,0 +1,13727 @@
+:100000000000000091EC000055EB000055EB0000F3
+:1000100055EB000055EB000055EB000055EB0000E0
+:1000200055EB000055EB000055EB000055EB0000D0
+:1000300055EB000055EB000055EB000055EB0000C0
+:1000400055EB000055EB000055EB000055EB0000B0
+:1000500055EB000055EB000055EB000055EB0000A0
+:1000600055EB000055EB000055EB000055EB000090
+:1000700055EB000055EB000055EB000055EB000080
+:100080000048004791EC0000000000000000000064
+:100090000000000000000000000000000000000060
+:1000A0000000000000000000000000000000000050
+:1000B0000000000000000000000000000000000040
+:1000C0000000000000000000000000000000000030
+:1000D0000000000000000000000000000000000020
+:1000E0000000000000000000000000000000000010
+:1000F0000000000000000000000000000000000000
+:10010000D11E8000B5228000BD248000491F8000E0
+:10011000F9218000A9160100F1208000D120800083
+:10012000594880006948800015648000E1628000C1
+:10013000296280003D6580008D628000C56280007C
+:10014000596380005D6580007D6380009D63800051
+:100150000D668000A961800061618000756080008B
+:1001600095608000DD6380009D65800029668000C9
+:10017000FD618000B96580001D618000F16580002F
+:100180009D6680006D658000916C8000CD6B800065
+:10019000316C80008D6B8000556C8000AD6A8000F2
+:1001A000C16A8000D56A8000496B80001D6A8000AA
+:1001B000FD6A8000AD688000C1698000D168800060
+:1001C000356B8000B16980004DF10000D166800080
+:1001D000E16780008D678000CD6780009D688000AA
+:1001E000ED678000BD678000A1678000ED6680003C
+:1001F00009678000616780004D4880001D488000CD
+:1002000085988000DD96800051948000B19B80002D
+:100210003994800005988000199880002D988000FE
+:10022000C59B8000D19A8000899D8000D193800079
+:10023000D9918000ED9A80002129000099170100D2
+:1002400079290000C1170100519B8000BD290000E1
+:1002500049A9800099988000F529000031A8800004
+:1002600005A7800021A28000BD938000DD9380005F
+:10027000199E80007D93800045988000E59B80005A
+:100280006DA68000C19C8000C59F8000A19D80005C
+:10029000F5988000851701005517010029AA8000F4
+:1002A000B9A9800075AA8000E1A9800039AA800060
+:1002B0008DAA80005DAA80000DAA8000C5A98000DB
+:1002C0009DA98000A90C8000850D8000C1068000DA
+:1002D00029088000694680004D468000D94480008E
+:1002E0004146800021448000F54380001544800091
+:1002F000E1438000E1428000854680007544800033
+:100300002D448000A9428000F9428000CD43800046
+:10031000B9458000F544800039458000090080001F
+:100320003D00800049018000D10480000D04800060
+:10033000910380004D038000E503800035038000B9
+:100340006503800029028000CD02800051028000F8
+:1003500085028000F5028000950680003906800045
+:100360008105800005068000FD048000690F800083
+:100370002516800015168000451380001513800097
+:100380002513800009138000351380000D1E8000A6
+:10039000F91D8000291D80001D1C8000391C800073
+:1003A0003116800059138000192C0200951380002B
+:1003B000B91C8000C5270000452D0200751D800076
+:1003C000A90F01003D1D80000D1B8000E910800079
+:1003D000790F8000A9168000311480002D11800053
+:1003E000A51E8000B11E8000BD1E8000692B80000C
+:1003F000AD28800011298000892B8000FD2B800012
+:10040000E128800065288000B52C8000912C8000B8
+:100410001D2B8000752D8000252C80004D30800024
+:10042000DD2D800059278000313180002118010026
+:100430008D268000C5268000E5248000FD268000F2
+:1004400021258000B12A80006525800025288000B4
+:100450006129800041298000D92980009D298000E0
+:1004600081298000893080004D2E8000B12B8000D2
+:10047000312C8000E12C8000613280002D32800020
+:10048000C93380004D368000693A8000B535800060
+:10049000F9348000A93480003D3380009D33800012
+:1004A000013480003536800031388000353A8000D4
+:1004B000213A8000AD3280000D338000DD328000B3
+:1004C000953A8000D937800099368000193780002E
+:1004D000593880004938800019398000313D80004A
+:1004E000D53A8000C93C8000E13B8000513D80004E
+:1004F000D93D8000AD3E8000593F80009941800089
+:1005000041478000CD5B8000895380002D4D8000E5
+:10051000A94C8000E14D8000E94F8000B14F800080
+:10052000C94E80008D4E8000F15180005D528000E8
+:10053000D15180002D52800001528000C94F8000AF
+:10054000594C80006D4C8000455B8000395680001E
+:10055000155A8000C9588000315A800081578000A8
+:10056000F95980001D568000AD55800091558000DE
+:100570004D5A80002D558000714B800071548000D1
+:1005800009548000F54D80001D4C8000F94B80001F
+:10059000094C8000114E800015588000C9110100DF
+:1005A0002D508000E5588000555680007D5A80000F
+:1005B000054F8000354E8000D9558000515880008D
+:1005C0009D57800059518000614D8000B1488000E6
+:1005D0005D5B800081528000494C80003515010030
+:1005E000F15B8000E55C8000E15F8000A55E80003B
+:1005F0007D5E80008D5C8000015C8000A15F8000DA
+:10060000895D800005608000395D8000D15E8000DA
+:10061000495E8000ED6C8000656D8000DD6D8000BE
+:100620000D6D8000296D8000896D8000F96C80005F
+:10063000D96C80003D6E8000616F8000756E800017
+:10064000056E8000A974800055758000D574800007
+:1006500005748000D17C8000457D8000757C800021
+:10066000117E8000897E8000E97E8000917D80007F
+:100670003D7E8000517F8000A581800065848000E0
+:10068000418480008D8380006583800035858000F3
+:10069000E58480009D848000218580007584800031
+:1006A000BD8380005D858000BD858000158F800042
+:1006B000918D8000D58980001986800019AB80005B
+:1006C0005DAC8000A1AA8000B5AB80005DAB80006E
+:1006D000FDB080007DB1800065B080006DAE80000F
+:1006E00085AE8000EDAD800041AF80001DAE800082
+:1006F00031B180003DB18000B9AE8000F5B180001D
+:1007000079B08000FDAD800009B180008DB080001F
+:1007100049B1800069B180004DAE80003DAE8000DF
+:1007200095AE800029B38000C9AE8000CDAF8000B7
+:10073000E5AF800025B080008DAF8000B5B28000AD
+:10074000FDB2800019B38000EDB080005DAE800086
+:100750002DAE800029B28000A9B08000A1B1800038
+:1007600005B2800039B28000A9AE80007DAF800064
+:10077000ADB38000A9BD80009DC1800025C7800069
+:10078000DDC8800065CA8000E1CB8000DDCE80003E
+:1007900019CE800099CE800015CF8000E52C000096
+:1007A0000DD88000DDD7800091D78000B110010006
+:1007B000CD2B000069D880007DCF800045D9800016
+:1007C000FD10010099D1800025110100F9E08000A1
+:1007D00071F58000152D0000D1DE80008D21010013
+:1007E00009EA8000A1E4800045200100E1EC8000DE
+:1007F00011E3800039EA800039E3800099E380004A
+:1008000029DF800005220100A120010075220100DE
+:10081000352301007D230100BDEB8000952D0000F4
+:10082000152E00001922010091220100CD210100A6
+:10083000E1E18000A9E980007D210100F9200100AB
+:10084000EDF58000D90081009DF68000C5F780009D
+:1008500085FF800045018100D50281004D038100A4
+:10086000E50081007DF6800081F78000D5F58000ED
+:1008700051F9800031FB8000F1F68000F9F580002D
+:1008800041FF8000D9F98000DDFC8000A9F78000DD
+:10089000C12E000059FB80008DF78000A5F9800073
+:1008A0008DF9800029F68000A1F880005DF78000B6
+:1008B00065F6800095FD8000912F0000F502810013
+:1008C0002D0281008901810005018100A93000000D
+:1008D00099FF800019F7800089F68000C1F680003A
+:1008E0008D10010085F5800005F78000DDF68000A1
+:1008F000B1F68000AD6A8100BD6A8100DD2F810004
+:10090000E1578100F56D8200A98D820009258200E2
+:10091000196E820001AA81005D608200A537820005
+:10092000ED69810079598200E55882001D598200E5
+:10093000FD6D8100493A810041BC8200E95A820084
+:10094000CD608100D59681001D6181002961810003
+:1009500089BF81001DAB810069320000893200002F
+:10096000D132000005A6810021AD82002958810006
+:10097000BD3E8100A540810035958100599B8100D5
+:100980003D3682001D4582000928810099A0810022
+:10099000D1288100E93B81008D288100416E8200D1
+:1009A000859B8100295D81006D398200FD398200BF
+:1009B000253A820095698100C97A810091578100AA
+:1009C0005D57810075308200852F82003557810088
+:1009D000D12F82002157810049578100F5288100DD
+:1009E00095A882002DA2820089D38100D56B810059
+:1009F0005959810075598100F55A820005AD810071
+:100A0000F1D2810039378100ED718100C5968100F6
+:100A10008957820091618200CD618200A9588100CE
+:100A20001D2782004543820001448200156A81002F
+:100A3000614A8100ED4E810071228200055A8100D9
+:100A40004D8A81007549810071248200B14981007D
+:100A5000B144810075AC8200292B8200595281007B
+:100A6000E12A8200B529820071A7810035A78100A3
+:100A700001D48100F5BE810055B48100D16A8200A5
+:100A8000D19C81009D9C8100959B8100B59D81003A
+:100A9000459D8100C59D81006170820009358100FE
+:100AA000A1AB82008DAB820075AB8200F193810017
+:100AB0009968810015D7810071C182007D2B81006A
+:100AC000E92F81000DB6810025BD82008D4F810088
+:100AD0000D5081008543820031D78100B1BD820075
+:100AE00095C182005DB38200B90D01008DD18100F6
+:100AF000A9368100E9BC820029378100E9368100EE
+:100B0000A1D68100A53B81006DAB810041B0810081
+:100B100045AE8100DDB1810041BD820095BE8200FD
+:100B2000CD2E82009D6B8100CD458200453981002C
+:100B3000353B8100BD3A8100F1D58100419F8100A4
+:100B4000119F810071A48200ADD58100C130810068
+:100B5000A13982004D618100995B8100A5728100FD
+:100B600089DA810061BF81006157820081218200A2
+:100B7000A9218200D1AD820009BC8200B5A181000B
+:100B80009DCA8100B92F8200D9BB8200113082003A
+:100B90007DAD8200CDA4810099A48100CDAB8200FF
+:100BA00015AB8200C1AA8200B998810081A581009D
+:100BB000D9D08100A9CF8100E93B8200EDCF81002F
+:100BC00065D1810079D1810051D0810065D081004B
+:100BD000E521820011228200D1340000B9480000D2
+:100BE000FD9C81009145820055AE820041B4810098
+:100BF00095BD8100F18A8200098B820079D981003C
+:100C00007D618200CDA4820041918100A13F8200DC
+:100C10003594820049948200898982005DC18200F6
+:100C2000F1C18200D13B8200D5958200E560810050
+:100C300009208200E5170100BD3B820075A18200FA
+:100C400025A58200253B8200E93A8200753A8200A0
+:100C5000F1308200B130820071D781004599820065
+:100C600091D7810089948200DDC18200A96A820047
+:100C7000256B8200C944810029458100596B8100A0
+:100C800059498100EDAA810069618200AD2482008A
+:100C900005368100D535810079D08100A5D081004D
+:100CA000715C8100E1AD8100EDD0810049C9810016
+:100CB0004DD88100893D82004920820065968200DE
+:100CC000F925820089CF8100856A82001593820010
+:100CD0002D5D8200E9CA81006D4082006130820092
+:100CE00015488200313C810061D68100114E81009F
+:100CF0000129810041A1810015A681000999820086
+:100D0000E5C98100B1D7810035C08200294A810040
+:100D100041AD8100EDBE82002DBE820005BE820085
+:100D200079BE820055328100A5958100B1598100BC
+:100D3000E54781009152810015638100956481002F
+:100D40008D668100592C8100392C8100212E810073
+:100D500065358200D5578200352B8200996082006C
+:100D6000016182001D4082001D2082001DD881008B
+:100D7000A9AC8200F1AB8200F52B820041AE82006B
+:100D800011120100356A810009AE8200696D82008E
+:100D9000098C8100D58B8100116F810081908100C9
+:100DA000296C8200DDA18100E92B8100552F820092
+:100DB000398C8100A55A8200355C820045BB8200D7
+:100DC00091BE81002D6E8100115C8200258A810018
+:100DD0004D93810089388200D5378200555A8100B1
+:100DE000013882008D038100E9208200E13E82000B
+:100DF000914581002D6D81000D58820021478200B0
+:100E0000FDCE810011CA81005936820051CB81008C
+:100E100025CB8100912E81002D2F8100B93A8200CF
+:100E2000A10D0100DDA9810031D48100D1B3820080
+:100E3000ADA98100D53882008DD88100555E820031
+:100E4000719A81001541820035DA810019258200EE
+:100E50006926820035358100D90D01003D71810080
+:100E6000012D810009A282000D238200FD71810005
+:100E7000D960820051728100416182004528810061
+:100E8000C12382008D6C81006D2382009547810013
+:100E9000B9D98100B534810075C98100F134810070
+:100EA0002DBF810059AF8200D93C8100494F81009C
+:100EB000E5AB8100F51501007931810005958200CF
+:100EC0006D638200DD938200A56682000DC88100FB
+:100ED000095E81007D758100156281009159810054
+:100EE000D575810011498100C1488100B9BF8100D9
+:100EF000A5458200F5598200F1A9820041A6820031
+:100F000039588200BD428200BDA782004D22820076
+:100F100071A78200A5A78200E15C8100ED418200FB
+:100F2000D1A78200D1688100B5CC810015AF8200C5
+:100F300095418100E1C8810089AA8100E99681007C
+:100F40007D2F810081470000494282005944820080
+:100F5000F90D010031318200614982004D49820062
+:100F60000DA58100095E8200253E8200CDCD810065
+:100F700029B382002151810045B18200A91D820060
+:100F800079BC8200D1568100599D8100999D8100D4
+:100F9000191C8200513F82001D308100C9BD8100B3
+:100FA00015388100794A8100DD9B8100199E8100FE
+:100FB00069618100896E8100B5708100D132820043
+:100FC000F1578100A93382009D5A81003D3582008E
+:100FD00089338200D96E810045708100FD618100F6
+:100FE000594B81000D9C8100558B8200F18E82004F
+:100FF000E59A8100BD35820049368100291F8200B3
+:10100000655C820009150100516F8100299B8100F8
+:10101000A56D8100B5A28200E1AF8200A9568200D1
+:10102000894481003D578200E16F8200016F820098
+:10103000DD728200E53E810095518100FDD4810082
+:10104000F5BC810081B48100F199810019318100E2
+:10105000358A8200DDDA8100413D81002D3E81002C
+:10106000E9898200C1D48100FD8D820099B681009A
+:10107000BDA781003D9F82005D0381006D928200CB
+:10108000218B8200599A8100ED278100ED94820026
+:10109000FD8A81009D8A8100416B8100E16F8100A2
+:1010A0005D468200A19482009D898200C9928200DF
+:1010B00079998100B1908200219182001D348100D4
+:1010C00099B28200DD6A82008DC9810059278200B1
+:1010D00021120100D9908100A56B82006D3C820035
+:1010E000E56D820005C28200C96A8100ED4582007B
+:1010F000816B8100353F8200FD90820071BC8100D0
+:10110000F16B81003D4E8200514A82003DA2810078
+:10111000190E010079738200B97E8200698882000D
+:10112000695A8200DD2E810015138200117381003F
+:10113000698082009D9181005D8B8100816C8200BD
+:101140008D8F81004D8F810009888100BD6D8200E7
+:10115000018E81001D5E820091718100C127810096
+:10116000797582002DBE81002D5B8200E9A5820089
+:10117000B5728200255B0000217D82004D808200D7
+:101180008D7F820001A08100ED7F82002D418100D2
+:10119000F98481006185820045728200F9548100E2
+:1011A000692B820069518100C5558100315681004B
+:1011B000A1A6810071508100392A8200615381000B
+:1011C000C573810035620000F1978100A99B810001
+:1011D000FD3B820025A08200DD398100715D810028
+:1011E000BD1401004995810009CC810021A3820032
+:1011F00045AA8100AD818200916782002962820048
+:101200007D708200E12F8200E97D000081DB81009A
+:10121000952482006989820089C38200C5C4820046
+:1012200039180100B1EB820009CB82000DCC82009D
+:1012300059EB820061E9820015F18200E9CD82005C
+:1012400045DF820009F182008DF782008DCA82009D
+:1012500089F38200D5CA8200A1098300C9F7820000
+:10126000FDEF820099F8820025F9820039FA8200A8
+:1012700089ED8200ADE08200ADE5820065DA820092
+:101280007DC582002DE6820065EE820031E4820099
+:10129000E5F182009DC8820055F3820075150100BA
+:1012A00061C78200CDE182006DE18200A5E282008B
+:1012B00059DF820029F4820009C7820055EF8200BD
+:1012C000E9EC8200E9DB8200BDDD8200E1C582003D
+:1012D0004DE5820005E08200A5F982000DC582007F
+:1012E00089F48200ADA1000085A2000091E6820091
+:1012F000BDCC8200FDE982008DD182002DF18200FB
+:101300002DF7820095FB820069CE8200A1F0820059
+:10131000D5F08200F5CC820035A3000081D982008F
+:1013200045C58200FDCB820025CB8200BDEB82004B
+:101330001DDB820015CD820019E78200CDE6820018
+:101340004DCF82009DCB8200450C8300E50D8300CC
+:10135000590E8300410E8300010B83004D0A830068
+:10136000D10D8300310C8300590C8300710A830076
+:10137000650E8300F10D8300410B8300A11E8300E5
+:10138000B11E8300012B8300F54E8300112B8300D7
+:10139000B127830099238300014A8300ED4983002C
+:1013A000FD478300CD4C8300BD4C8300714C83000E
+:1013B000D52783004D25830095258300E14C8300CC
+:1013C000414C83000912010065118300E144830050
+:1013D00021288300BD2883007929830065288300A4
+:1013E000652B830041458300D5298300491D830077
+:1013F000A12A83005D30830051488300E5488300C3
+:1014000029488300F5238300114A8300793483003F
+:1014100091188300A5338300ED3483001D118300F0
+:101420009D4E8300954D8300B51A8300614783006C
+:101430001D4D8300ED1083000D458300C11E830008
+:1014400001208300E9218300F1258300F91D830039
+:10145000F513010059B3000049108300C10F830048
+:1014600021248300A5248300B94A8300B52F83007B
+:10147000C1458300FD1C8300711D8300F5188300A6
+:1014800059198300F1198300190F0100492A8300BB
+:1014900011B40000B957830029578300654F8300BA
+:1014A00001608300E559830039518300F54F8300C3
+:1014B000555483001D5E83002152830065598300CB
+:1014C00079508300714F8300095983003D63830085
+:1014D000C5578300815C8300B15B8300DD538300CB
+:1014E000115383009D4F830029508300254F8300B3
+:1014F000D5588300CD62830039608300F95C830096
+:101500004D6183005D5F83002D548300DD508300B7
+:1015100039578300A555830091638300A16283003E
+:10152000C15D83002D5E8300455F8300A151830070
+:101530004D5E8300195B83006D5A8300A9568300BA
+:10154000A5508300095783000D748300DD63830079
+:10155000297A830001668300B9B28300D5A783008E
+:101560007D848300819383005DB38300A193830016
+:10157000E9938300E10E010071BA0000B1BA0000E6
+:10158000717A83005D67830051668300CD708300AC
+:1015900055718300DD7483008DAA830051A88300F8
+:1015A000A9B183009D918300D184830039BB0000E1
+:1015B00061848300AD77830081818300158283007D
+:1015C000B1808300E5B583006D7E8300B57983002B
+:1015D0002DBC0000916E8300758F830055878300BA
+:1015E0002913010015C1000025678300C18883000D
+:1015F000D98F8300F5AC8300E97783009D6D83006C
+:10160000A1A78300FD998300C9A4830051C40000F1
+:10161000558B8300E58A8300CD6A8300F5868300BD
+:10162000596A8300B9AA83001566830051B283000A
+:101630009DB38300D9B6830059B1830091828300A2
+:10164000D5B0830081868300C97A83000585830035
+:10165000797C83008965830055A58300C9AF830029
+:101660008D1501007999830091898300C5B58300A8
+:101670000DB8830099D483002DC083009DC28300E0
+:10168000ADC38300A1C68300B1C68300C5C2830079
+:10169000A9D0830055BF8300F9CF830029BF830001
+:1016A000C5E18300C1C0830095C083004DD883008D
+:1016B0000DD7830015D88300F1D7830079BD83004F
+:1016C000A1E1830035C28300C5E08300DDE0830033
+:1016D000C5DC830099DA830001DA83004DB883000A
+:1016E00075C0830019C28300F9C983003DD6830009
+:1016F00015BE8300C9D683005DBA830029D6830056
+:1017000031B9830035BC83009DD883005DDC830044
+:1017100029C18300A9C28300E5C0830025DB8300C3
+:1017200075C283001DD083005DBC830061C6830049
+:10173000D5C2830005BC830001C98300B5C88300FE
+:10174000EDC8830055D6830015D98300A5D1830049
+:10175000F1D5830001D9830081B8830089E083003B
+:10176000E1BC8300A5DB8300EDE1830071C1830050
+:10177000E9B783006DC783008DC183001DC8830056
+:10178000B5D1830071DC8300E1C18300A9C183006E
+:1017900019DC830039D883004DCB8300A5B78300C3
+:1017A00069CB83008DC98300C9D48300A5C500001F
+:1017B00099D68300E5DC83004DD483001DC38300EC
+:1017C00021DD830045D983007DD383003DD2830092
+:1017D00041DA8300CDD88300D9BF830095BD830053
+:1017E000EDBD830051C083002DB8830049BB830049
+:1017F00031BB8300CDDA8300D5D0830049CA830092
+:101800009DD5830081BF8300D5CF83003DC9830070
+:10181000DDD18300B9D7830025C78300D1C800007C
+:101820005DBE830021E18300F9E0830071B983008C
+:101830008DE1830025D9830049D78300DDDB830058
+:10184000A9B9830085BA83000917010059EB830009
+:10185000C5E7830041E2830025E283006DF5830044
+:1018600065EB830085F2830089F78300B1F2830082
+:10187000A9F58300AD008400E100840019FD830018
+:1018800035EE8300FDF38300D1D1000089FB830096
+:10189000B9FA830021F98300F1FA8300D9F88300B3
+:1018A000D9F9830031008400C5FE830049E7830035
+:1018B000050084004DFF83006DF3830059FE830013
+:1018C00001FE830025EB83000DEB830031018400D2
+:1018D00035FD830081EB830059FD830011F88300FF
+:1018E000FDF78300C5ED8300ADED8300A101840009
+:1018F000E9E78300B1F38300DDF2830025F3830081
+:10190000F9E68300E5E28300F9120100A5E983000E
+:101910008DF5830051EE830079F8830071E2830036
+:10192000F1E8830045E6830099F783006DEE8300BC
+:1019300041F48300B9EB830075E78300B1E88300CD
+:10194000BDD3000061F183000518010089EE83001A
+:10195000F5D40000FDE58300A9FD83000D1301000F
+:10196000B5FB8300F1F183002D108400E1158400A4
+:10197000B1198400C5158400D90F8400CD218400DD
+:10198000491E84004D1F8400E1128400ED0884008C
+:10199000F10184002D0F8400ED238400F51E8400E6
+:1019A000E520840049208400AD128400F11A8400EF
+:1019B000711F8400C9198400AD188400450B840090
+:1019C000910B84000D2484008D2384000D18840065
+:1019D000210684008D168400310384006909840087
+:1019E000FD158400E902840001028400A909840035
+:1019F0008D148400811E8400E10B8400751C84001A
+:101A0000AD0A840049108400712084000121840003
+:101A1000850A8400291D840045078400390C840050
+:101A200029198400551E840089038400E51D840063
+:101A30002125840049138400291A8400DD12010045
+:101A4000ED12840045068400010D84008943840062
+:101A50006D2A8400014D84001528840069288400C3
+:101A6000DD0B010009408400112C8400F92784005B
+:101A7000912D8400794C84008934840019338400CA
+:101A80006D2F8400C92D8400F12E84007D2E8400EA
+:101A900065258400DD348400FD2584001929840037
+:101AA000B5408400D944840079298400B92B84008E
+:101AB0003D45840095328400B9288400D1388400E3
+:101AC00031488400A93084006D2C8400994384003F
+:101AD000D13284006D338400FD2F84005D45840085
+:101AE00011348400B54A840075488400C5488400D8
+:101AF000B1278400314A8400D949840059328400D6
+:101B0000014C840039388400314D840055448400F0
+:101B1000D93D840055438400513C840091398400B0
+:101B20009536840091378400F5368400E1478400BF
+:101B300015478400CD4C8400F52B84002546840095
+:101B4000E53A8400C937840049428400292A840088
+:101B5000A53F840059268400952A8400452B8400E3
+:101B6000C95D8400C1230100A156840095568400FC
+:101B700019578400E956840005578400355F8400B6
+:101B80001D628400B557840065638400ED628400A3
+:101B900021638400BD628400194E8400B95384001F
+:101BA000B15D8400B5518400D55F8400F95584008F
+:101BB0006560840059538400E5538400E94D840036
+:101BC00049240100E15F8400212501005125010025
+:101BD000B55B840031568400A5638400CD60840029
+:101BE00091638400ED5084002D5E840031518400A7
+:101BF000155C840061548400F55E8400F15D84000E
+:101C0000352401007152840059588400815C84009D
+:101C1000715784002557840071588400AD568400A4
+:101C2000415984006D4F840029508400E1548400A0
+:101C3000BD6184006D61840005598400A56684003F
+:101C4000D9678400456684000D658400916784002F
+:101C5000B96384005D67840079678400F966840055
+:101C60002165840021678400C56684008D66840038
+:101C70006566840011688400516C8400AD6E840038
+:101C8000016E8400F97084004D7F84007D6C8400B7
+:101C90002D748400456A84000D7B840001120100CC
+:101CA000156E8400457A8400E56C8400456F8400DD
+:101CB000C17C8400297E8400756D8400956B84004E
+:101CC000B56D84007D7D84005D6B8400D56A8400E1
+:101CD000816A840085748400B1808400857E8400DC
+:101CE000CD7F84004981840069818400ED8984006E
+:101CF0006D8A8400FD8984008D8984009D8984001B
+:101D0000E9858400F982840025858400518A840055
+:101D100075858400958484008181840071838400AA
+:101D2000C18984005D898400D58984006D8984001F
+:101D30007D8984000D8A840009868400798C840062
+:101D40007D8A84000D8B8400499484008D928400E8
+:101D5000E98D84009D8B8400FD8C84007990840043
+:101D60000D8C8400458C8400E9A68400A5AD840018
+:101D700029968400C598840015C1840009A98400AF
+:101D800099C2840045B7840031C18400D1B8840071
+:101D90008D998400B99A840025AC8400D9BF840051
+:101DA000C9BE8400A196840025B18400519B8400A3
+:101DB000919884004D9784001D9784007DA684002F
+:101DC000D1B784002DAB84008595840019B08400C0
+:101DD000F5AD840029A98400C1A98400219F840055
+:101DE00025A28400B1AE8400C1AF8400D5A38400D5
+:101DF00075B7840041A28400E1BC84006DA8840012
+:101E0000BD9D840095B884005D95840075BE8400F6
+:101E100051B98400A9958400C5C18400599A8400F1
+:101E2000419684003DB884009DA88400E5A8840004
+:101E3000A59B8400F5A684003DAF8400159A84001C
+:101E4000F9988400EDA984006DB18400FDF0840050
+:101E500025DF840025ED8400E5D08400CDF18400E9
+:101E600009F2840035F2840055F28400CDF284003A
+:101E7000B1D38400F5D384002DD48400C1D4840070
+:101E8000A5048500F90585006D0585009904850088
+:101E90008D04850079D4840045E88400B1C58400B0
+:101EA00095DF840031DF840075E484001DE0840048
+:101EB000BDC9840005ED8400A500850091FB840068
+:101EC000F9ED840091EF84009DFB840081EA840099
+:101ED00079E28400E1E500006DE60000A1EB8400FA
+:101EE000D1E484009D028500F1E7000015CC840058
+:101EF0005DFB840081C5840015D5840099D68400DB
+:101F000035E78400B9DF840045F48400B9C7840054
+:101F100001DF84002D018500E1C7840025D1840004
+:101F2000B5E60000BDDD84004DF38400E1C9840006
+:101F300041E084002DCA84009DD4840091E7000014
+:101F4000D900850079CB840021FC8400B9E88400A5
+:101F5000B5D8840031FD8400BDFB84001D048500DC
+:101F60005D04850031ED8400450685005DEC84004C
+:101F700025C384001DF38400D9C684002DEC8400A1
+:101F8000F1C5840059E9840019C884005112010088
+:101F9000B100850049D3840001C98400E1D28400E6
+:101FA0008DCB8400DDEB840011F4840009FC8400F7
+:101FB000D9F3840069C38400A1C884002DEE840095
+:101FC00071D68400790185004112010025D8840072
+:101FD000DDF9840009F0840035F784008DE8000005
+:101FE000D9FC840015D78400DDD584001DDE840073
+:101FF00001E9000019F1840099F1840049F184009D
+:10200000BDE90000A1F48400F1D084003DCC84003F
+:1020100069D2840089E98400F51D0100C9D38400D8
+:102020008506850089078500E90685004D0785003E
+:102030001107850025078500710685009506850036
+:10204000BD06850075078500B10785009D078500E1
+:10205000A9068500D1068500FD06850039078500A3
+:10206000610785005D0685001509850079098500F1
+:10207000350A8500BD0985000D0A850091EA00003A
+:10208000711201004D0A8500A90985002509850006
+:10209000DD0A85006D0A850081088500C507850079
+:1020A0000D0B8500590F8500ED118500C9128500C3
+:1020B00021108500F90D8500D5118500511085008E
+:1020C000AD118500011185006D108500B1D10100B1
+:1020D000850F850085108500990D850011128500FA
+:1020E0000D22850041178500D917850075208500D0
+:1020F0007D2C8500352F8500B92285002D25850092
+:102100009D238500612F8500A5278500C92A8500AC
+:102110006D2985009D22850031228500A52485003A
+:10212000E1238500B12F8500BD2C85005914850061
+:10213000C9138500A11C8500452C8500A9178500C1
+:10214000B1208500311A8500FD178500291D850005
+:1021500021148500AD218500B5308500453185000D
+:1021600035278500D1318500C5148500BD2D85003A
+:102170002D23850059238500891485004D4685004F
+:102180006547850025368500514785003D46850019
+:102190008D3C8500514A8500994A85007547850028
+:1021A0001D478500553685005D468500D53B850079
+:1021B00049498500D53A8500E139850041398500D6
+:1021C000E53885000937850045358500C93C85001F
+:1021D000754B8500B9458500ED4885002146850091
+:1021E000213A8500A940850001328500F53285003D
+:1021F000FD378500894E8500DD508500ED50850056
+:102200005D57850009558500495085005D50850062
+:10221000D1528500F5528500E54E8500C9558500EF
+:1022200065568500C9508500094F850071D20100AF
+:102230009D5585000D538500A94C8500B957850033
+:10224000A55785000D518500FD5A8500D5518500A3
+:10225000A9518500B15285009D53850039558500EF
+:102260009D4E8500C95785006D578500954C8500AA
+:10227000095785008D4F8500DDD20100FD5985008D
+:10228000014D8500ED598500D9598500194C85000F
+:10229000756C8500816E8500516C8500295C850018
+:1022A000416E8500795E8500210F0100AD6E8500CD
+:1022B000B56C85006D6585001D5F8500196B850017
+:1022C0008579850071738500B58E8500E19585005F
+:1022D00001828500519085002D828500D190850076
+:1022E000FD908500BD9285006D8F8500CD928500A3
+:1022F00055968500C58E8500857285005D8D8500AB
+:1023000001838500C1918500257085000D918500B0
+:10231000C17685006971850041718500F97F85006E
+:1023200079708500F19385009D958500F574850091
+:10233000497485006D788500BD728500ED8A850041
+:10234000C98C850099918500597D8500BD718500F6
+:10235000758185000D818500A9798500217785002B
+:102360002193850089928500D194850095968500FA
+:1023700065838500D97385006582850021D30100BE
+:102380005975850021768500556F85006D9585000E
+:10239000E583850029848500AD8F8500F16E850079
+:1023A0009D2E010075280100292E0100A53601008F
+:1023B000F52D01001D2B0100992B0100A531010015
+:1023C0005D2B01002D2B0100252B0100613C01003C
+:1023D000692E010041370100952801007530010088
+:1023E000FD310100C52A0100D1280100C13F0100D3
+:1023F000CD280100C1400100F1420100DD2D0100A6
+:10240000DD2A01004D2E01009D32010091360100B0
+:10241000ED2D0100C5280100BD280100613001003B
+:1024200031340100253401005930010055330100D9
+:10243000813001008D320100152D0100F92B0100C2
+:10244000D1450100192D0100F92D0100012E0100D7
+:1024500089300100A53A0100F93A0100B12C0100D0
+:10246000D52D0100853501009DEB0000D9EB000062
+:1024700015EC000059EF00009DF40000E12C020073
+:1024800005F500000DF5000049F8000049F90000CD
+:10249000B1F9000009FB0000452F000011310000D8
+:1024A000493100006D31000079310000C931000070
+:1024B000D500010011020100D931000039330000BC
+:1024C00045340000710D0100F93500006D0D01006B
+:1024D000E54F00006D6B00005D750000B19E0000CF
+:1024E0005D0D0100610D0100690D0100650D010028
+:1024F000F5160100A9C60000450D0100410D0100BF
+:10250000310D0100390D0100D90B0100510D010001
+:102510004D0D0100550D0100590D01002D0D01005B
+:10252000350D01003D0D0100490D01004DD50000A4
+:1025300031D5000039D5000041D5000059D5000043
+:10254000FD0B0100190C0100390C0100F90B010011
+:10255000F50B0100350C0100150C0100110C0100F8
+:102560000D0C0100090C0100050C0100010C01001B
+:10257000890C0100950C0100C50C0100E50C01005F
+:10258000E90C0100FD0C0100F90C0100F50C010043
+:10259000F10C0100ED0C0100990D0100910D0100FD
+:1025A000890D01009D0D0100850D0100790D0100CF
+:1025B0008D0D0100750D01007D0D0100950D0100CF
+:1025C000010D010001000000200000001F000000BC
+:1025D00050000000020000000100000001000000A7
+:1025E000010000000000000061D401000A0708009B
+:1025F000B533020051FB80006D310000C12E000098
+:1026000000000000D1F980000000000029FB8000DC
+:1026100000000000000000009C1800409600FFFF32
+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10263000FFFFAAAA0300409600000000000000006F
+:10264000000000000000000000000000000000008A
+:10265000000000000000000000000000000000007A
+:10266000000000000000000000000000000000006A
+:10267000000000000000000000000000000000005A
+:10268000000000000000000000000000000000004A
+:10269000000000000000000000000000000000003A
+:1026A000000000000000000000000000000000002A
+:1026B000000000000000000000000000000000001A
+:1026C000000000000000000000000000000000000A
+:1026D00000000000000000000000000000000000FA
+:1026E00000000000000000000000000000000000EA
+:1026F00000000000000000000000000000000000DA
+:1027000000000000000000000000000000000000C9
+:1027100000000000000000000000000000000000B9
+:1027200000000000000000000000000000000000A9
+:102730000000000000000000000000000000000099
+:102740000000000000000000000000000000000089
+:102750000000000000000000000000000000000079
+:102760000000000000000000000000000000000069
+:102770000000000000000000000000000000000059
+:102780000000000000000000000000000000000049
+:102790000000000000000000000000000000000039
+:1027A0000000000000000000000000000000000029
+:1027B0000000000000000000000000000000000019
+:1027C000000000002DE97043994605460E469046EC
+:1027D00020F086FA436831469C69284642464B46BB
+:1027E000A047BDE87083C0462DE9F74F0029054694
+:1027F00092469B46009153DB438A828A514403FBF5
+:1028000002F399424CDA806808F038DB002101902D
+:10281000A86808F005DD4369044643F000434FF023
+:102820000008436124E000989BF8007008EB000664
+:102830004FF0000903E00136D04517D07F0817F0AC
+:10284000010F0CD0284621463246FEF3EDF630B19A
+:1028500063694FF0FF3023F00043636122E009F128
+:102860000109B9F1080F08F10108E4D10BF1010BDE
+:10287000D045D8DB6369A86823F000436361002179
+:1028800008F03EDCA868012108F03ADC2846214621
+:1028900020F0C2F9A868019908F0C2DC002001E02C
+:1028A0006FF01C00BDE8FE8F407C704713B500F050
+:1028B0008FD8024608B904460FE000240AE010460B
+:1028C00001A90022FFF344F7019A13782C2B08BFCB
+:1028D000013201341378002BF1D120461CBDC046D3
+:1028E000B0F8423070B50446C3B142F2197503E046
+:1028F0000A2003F031DF0A3D236B1B6913F070439C
+:1029000007D0B3F1005F04D0B3F1405F01D0092DCF
+:10291000EED1226B136823F01003136070BDC04624
+:1029200070B590F878310546FF2B1FD0104C406AE7
+:10293000E36E9847D4F89C30686A984701280BD812
+:1029400095F8141241B90B4628460A4A03F030DEC6
+:10295000012385F8143209E0054B686AD3F89C30EE
+:1029600095F805419847241885F8064170BDC04682
+:10297000E0A685003D98800010B5084671B191F839
+:102980000832012B0AD091F875313BB14B691A6AB4
+:10299000034B02EA03030BB10EF0FEFE10BDC0466E
+:1029A00000FC0101D0F8943110B59942044601D9D8
+:1029B000002002E00EF0F0FEE08D10BDD0F8801196
+:1029C00010B5044691B10223C068D4F8842108F000
+:1029D00005DB074B1B684BB9D4F88011D4F8842170
+:1029E000E06881EA0202023308F0F8DA10BDC0465E
+:1029F000AC2702002DE9F04190F817320446012B74
+:102A000077D00123002780F8173243E0A0683146D1
+:102A100000F082DBD4F8F0301B68984205D92846D4
+:102A20000021324600F00EDB42E02046FFF778FF3F
+:102A300035690023AB7194F8783131462B7294F8E4
+:102A4000063184F80731DBB26B72D4F8FC31606A6E
+:102A50000133C4F8FC316A79274BD20982F00102B4
+:102A60005B6A9847B0B9D4F8F8106B7900293CD06C
+:102A700013F00F0F39D06A782B7843EA02230F3313
+:102A80001B091A0A0A6918BF0023937194F8783158
+:102A900013722AE0D4F8F0301B68012B08D904F136
+:102AA00028052846002100F04FDA06460028ADD15F
+:102AB000002384F81732C4F8F8302FB16269043368
+:102AC0005364204607F03CDFE28DD4F8C8319A42C7
+:102AD00003D9206901F0C4DD0BE0D4F8CC319A426F
+:102AE00007D2206901F0AEDD03E00127C4F8F860E9
+:102AF000D0E7BDE8F081C046E0A685002DE9F041B1
+:102B00000746884616461D4642F2197403E00A201D
+:102B100003F022DE0A3C79690B6D002B02DA092CE6
+:102B2000F5D11FE0AB191B0243F00042069BB3F145
+:102B3000807F04D198F8003043F08073D21842F2BD
+:102B400019740A6503E00A2003F006DE0A3C7B697B
+:102B50001B6D002B02DA092CF5D103E0012088F867
+:102B6000003000E00020BDE8F081C0460022C36BC9
+:102B70000BB1013BC363531CDAB21030102AF6D1FB
+:102B80007047C0462DE9F041066805460F4670685B
+:102B90004FF4BC7104F09CD808B9044612E000213F
+:102BA0004FF4BC720446FFF34BF2D5F86031266057
+:102BB000C4F8603195F86431C4F8687184F8643100
+:102BC0006B6863602046BDE8F081C04603682DE96C
+:102BD000F74F012A14BF2A25322506460F465868AA
+:102BE0002946914604F0CCD8834640B93368013871
+:102BF0001B68D3F88C20136D013313656CE007F16B
+:102C00000E0A04695146042201A8FFF3B5F1019BA5
+:102C100006F1280803F47F421B0643EA02234AF622
+:102C2000FE12B2EB134F0BBF2C4907F108012046EF
+:102C300020460622FFF3A0F10622A01D4146FFF325
+:102C40009BF104F10C02B9F1000F0DD02B0A237394
+:102C500004F10E00557022490622FFF38DF108237E
+:102C600023750623637503E008232373062353703B
+:102C70006419A4F11C05394606222846FFF37CF1AD
+:102C8000002304F8163C023304F8153C41460622A2
+:102C900005F10800FFF370F107F11801042205F1B6
+:102CA0000E00FFF369F107F10801062205F1120099
+:102CB000FFF362F15146042205F11800FFF35CF1C5
+:102CC000D6F85C3130680133C6F85C315946D6F825
+:102CD000682125F067DA0120BDE8FE8F2C9E850073
+:102CE00014D2850010B50368D3F800481B6893F828
+:102CF000AB306BB1FFF73AFF08E0A16829B10120C2
+:102D000000F0CAF808B1FFF731FF2468002CF4D1B5
+:102D1000002010BD7047C046C3682DE9F04106464B
+:102D20000D4658683821174603F0D2DF044610B923
+:102D30006FF01A002BE000213822FFF381F101230C
+:102D4000294623606360A360062204F10C00FFF3B0
+:102D500013F16B8E05F10901A3742B7A04F11400B1
+:102D6000E3742A7AFFF308F16D8D3046A586E78675
+:102D70002146382221230BF013DE00B907E0F36867
+:102D800021465868382203F0B3DF4FF0FF30BDE82A
+:102D9000F081C04630B50C4690F8CF1091B0944603
+:102DA0009E460380194D91B94FF0FF330293039370
+:102DB000049305930D3300940191069107910891B6
+:102DC00009910A950B900C930D910E9115E04FF01F
+:102DD000FF33029303930493059300F1D00306930A
+:102DE0004BB2002207930C2300940192089209929F
+:102DF0000A950B900C930D920E927146044A63460D
+:102E0000C06824F079D811B030BDC046F920010067
+:102E10002C9E85001FB5836D0446012B17D1B0F899
+:102E2000583113F0010F12D1C36893F8703273B99F
+:102E300002AA01A903AB0FF0E5F9029A3AB12046C4
+:102E40000199039BFFF7A6FF08B90223A3651FBDE5
+:102E500010B579B1B0F8583143F00103A0F85831FA
+:102E6000836D022B15D1C3680C21D3F8680151F092
+:102E70009FDB0EE0B0F8583113F0010F09D023F0BA
+:102E80000103A0F85831836D1BB101238365FFF75F
+:102E9000C1FF002010BDC046012801D0002000E085
+:102EA0008868704710B50C4641B18B6823B9C06F74
+:102EB0000968FFF767FEA060A06800E0C06F10BD62
+:102EC0002DE9F0418C692369994202D100273E46E1
+:102ED00004E0CE6A0EB9374600E0376863681146F1
+:102EE000D86803F03BDFA36805461B6893F895306C
+:102EF0001BB1C38A43F08003C382636893F8AB308D
+:102F00008BB120463146FFF7CDFF60B129460AF06C
+:102F10003FD9022807D163682946D868012203F007
+:102F2000FFDE01200BE0204629460CF039DCA068CA
+:102F300029463A4625F036D9003818BF0120BDE8A9
+:102F4000F081C04637B5144605461146406FFFF77D
+:102F5000E1FE6368112B08D0122B01D0102B15D184
+:102F6000A37803F001032B7510E002AA002342F8B6
+:102F7000043DA86894F82F103CF080D930B18379D3
+:102F800023B96188C1F3800127F03AD93EBDC0461C
+:102F90002DE9F0470446084615460DF003FF80462C
+:102FA00010B9D4F8109001E0D0F80490A368D9F8D3
+:102FB00024701B682A6993F895303BB1EB8A13F4AF
+:102FC000006301D001262AE01E460AE0537B127BF3
+:102FD00043EA022348F66C02934214BF00260126FE
+:102FE000EEB9204629460CF0CDDB636893F8AB3090
+:102FF000ABB120464146FFF755FF80B1294609F0A5
+:10300000B9DF042801D0012804D163682946D868B3
+:10301000002244E0052802D14FF0010801E04FF002
+:103020000008636893F895301BB116B9AB8A2D334D
+:10303000AB82002F2FD0EEB9FB6913F0010F07D040
+:10304000637D2BB1204629460CF0A8DC024668B10E
+:10305000B8F1000F0ED1636893F8963053B1D4F8ED
+:10306000840029460EF004F9024618B9636829461F
+:10307000D86814E063682946D86803F0ABDE3B6982
+:103080000446DB68484639462246984748B1204600
+:1030900003F0DCDD05E063682946D8683A4603F0B2
+:1030A0003FDEBDE8F087C0464B6A10B591F843207B
+:1030B00043F480134B62D0F8883002F00702D21834
+:1030C00092F88030013382F88030D0F888200123D4
+:1030D00082F88630D0F8881091F8812091F87B3002
+:1030E0009A4211D291F8802091F87A309A420BD20C
+:1030F00091F8822091F87C309A4205D291F8832091
+:1031000091F87D309A4201D30DF0F0D8002010BD27
+:103110001FB5084B02460093074B08460193074B27
+:103120000749DB6902931268064BFFF3F5F105B01E
+:1031300000BDC046DDD60100A0D601000028020077
+:10314000AED60100D1D6010010B5436804461B7EFF
+:1031500053B1D0F880000CF049FDA06801F048FEA2
+:103160006268002382F8203010BDC04610B5806927
+:10317000FFF7EAFF002010BD70B504466368806861
+:103180001E7E0EB1002515E001F0F4FC054620B9C5
+:10319000D4F880000CF058FD05460CF0D5F86368B3
+:1031A000D3F89C1031B10B7823B1034B3246186829
+:1031B000FFF33AF5284670BD2428020010B5806858
+:1031C00001F0FEFD002010BD10B50446FFF7F6FF2C
+:1031D000A06806F083FE10BD61290DDC602940DA8D
+:1031E00054293ED003DC2F293BD0442912E0A1F121
+:1031F0005C03012B0FD834E0AC2932D005DC7C29EC
+:103200002FD0A1292DD06A2904E0DE2929D0F42964
+:1032100027D0CD2925D0642911DC632921DA4A2958
+:103220001FD006DC07291ADB08291ADD3C2918D033
+:1032300015E0502915D012DBA1F15C030DE0C32984
+:1032400005DCC2290DDAA1F1A803022B06E0B1F5D5
+:10325000847F06D003DBA1F58973012B01D90020FF
+:1032600001E06FF01600704731B1036B1B689942A3
+:1032700002D06FF00C0006E090F82930002B14BF4C
+:1032800000206FF00A00704730B5072A1C469DF8F1
+:103290000C5001DD496809B9036B1968032906D090
+:1032A0004B1E012B10D8036B1B6899420CD12DB11A
+:1032B00090F8293013B96FF00A0007E00CB92046E6
+:1032C00004E00020216001E06FF00C0030BDC0463A
+:1032D0001FB59646BEF1070F1A4601DC002300E039
+:1032E0005B685F2903930ADC5E2914DA4A2916D049
+:1032F00002DC3C2913D00CE05C290ADB0FE0AA2990
+:103300000DD002DCA82904DB0DE0C22907D0C329B7
+:1033100009D000200EE01946FFF7A6FF0AE00021C1
+:10332000FFF7A2FF06E000230093114603AB7246AD
+:10333000FFF7AAFF05B000BDC88810F0080018BF4D
+:103340006FF016007047C046D1F8D83270B5054608
+:10335000188C164610BB8B6D40F2371203EA02023E
+:10336000002A0CBF012411242A6B1368022B07D1F9
+:1033700095F85C360133DBB2012B98BF44F0200492
+:10338000537D53B1B06B06F13C0122F063DE20B1F6
+:1033900095F947360BB144F48064204670BDC046B1
+:1033A00091F801C030B5BCF1010F45DDCA788B78CA
+:1033B00043EA0223012B3FD1ACF10203032B3EDD94
+:1033C000ACF10603012B3ADD0B1D1D1D6A781B793C
+:1033D000002043EA0222864600E00130ACF10803F7
+:1033E000904203EB0E0406D0AEF1040EACF10403E0
+:1033F0007344042BF1DCC0EB0203A4EB830001282F
+:103400001DDD05EB8203DA789B7843EA022E821EEB
+:10341000002301E00133043A734501D0032AF9DCAB
+:10342000C3EB0E03A2EB8303012B08DD023B06D0A6
+:10343000C3EB0C034B7002E06FF0160000E00020BD
+:1034400030BDC0462F2A30B50446964602D86FF0EC
+:103450000D0034E0B0F88031056B0B60B0F88231BC
+:10346000AA894B60EB891B0743EA023302688B6031
+:103470001069BEF13B0FC36BCB6093680B61836A2D
+:103480004B61C36A8B61B2F87A30CB61D4F8843176
+:103490004B62D2F8B0300B6243688B62836BCB62B5
+:1034A0000CD92B8900220B636B89BEF13F0F4B6354
+:1034B0008A6303D9036C1046CB6300E0002030BD63
+:1034C00010B519B14068302203F012DC10BDC046BF
+:1034D00010B50446D0F860068E46C37A90F80AC04C
+:1034E00093B182894FF6FF739A420DD0837B43B923
+:1034F0008378012B05D0037B03F0010383F00101E6
+:1035000000E00021C9B20BE0216B71450ED1837B35
+:103510002BB98378012B02D091F84C1000E00021E8
+:103520008C4503D08172206938F0BADE002010BDCE
+:103530004FF0FF33A0F83C3210B5044600F50E7092
+:10354000063000210C22FEF37BF523685B6B23B968
+:103550004FF0FF33A4F840320DE04FF00F03A4F812
+:103560003E324FF0F003A4F840324FF47063A4F8F9
+:1035700042324FF20003A4F8443210BD70B5044645
+:10358000D4F8741580680CF069D8D4F8F816D0F126
+:10359000010538BF0025A0680CF060D800B90135DE
+:1035A000A068D4F8FC160CF059D800B90135D4F84D
+:1035B000E036A068196A0CF051D800B90135D4F88A
+:1035C000E0260023D360A068D4F83C150CF046D860
+:1035D00000B90135A068D4F894170CF03FD800B9B1
+:1035E0000135284670BDC04610B5044625F0F2DE10
+:1035F000204617F00BD810BD2DE9F04F0746106993
+:10360000A5B0D1F81090884601F124011A900792D4
+:103610000693189199F80130D2F87CA199F800200E
+:10362000339C42EA0323C3F38102022A7868089399
+:103630000B9201D0002302E0089DC5F3C013DBB25A
+:1036400041461693FFF3E6F504300A90329888B1AC
+:10365000037A0B2B08D197F8F0375BB197F8F13765
+:1036600043B18379072B05D832990A9A91F90F3023
+:10367000D2180A92D7F88831002B1CDA329BD3B1CA
+:103680001B7A022B17D197F8A034A3B91A9DAB6D02
+:1036900013F0080F0FD132988379292B0BD8032B05
+:1036A00009D90B2B07D82F99012904D10A9A19910E
+:1036B00008320A9201E000231993D8F81030B8F8C4
+:1036C0001420A3F1760676329D1FA8F8142000215D
+:1036D0007022C8F8106030460595FEF3B1F41898D2
+:1036E000036813F4806F01D0828827E00799A64B06
+:1036F0004A6802EA0303D3B1089A02F0FC03882B5C
+:1037000015D199F8043013F0010F10D1B8F8163024
+:103710002F9D03F007032E9801EB43016B1E984287
+:10372000B1F8BE200AD1531CA1F8BE3006E00B99B7
+:10373000012914D000224FF0100B04E00B9B012B49
+:103740000DD04FF0000B2E9D05F00F0343EA02133E
+:103750009BB289F816301B0A89F8173001E04FF048
+:10376000000B3098042807D138461A9932460FF0DA
+:1037700047D8ADF88C0019E02F992E9D4B1E9D4225
+:10378000B7F8462502D1531CA7F846352E98309934
+:1037900000F00F0343EA02135B0147F6E07203EA0D
+:1037A000020201F007031A43ADF88C20079A92F841
+:1037B000DF3023B9089D05F0FC03802B01D14BF0CD
+:1037C000200B724B04EA03031BB1002020942194C8
+:1037D0001FE00B99012906D9189A1368002B02DB08
+:1037E00013F0100008D0079C002594F8483003F02F
+:1037F0007F032093219349E0396B644B8A6C02EA82
+:10380000030343B199F8043013F0010F03D0209261
+:1038100021920F903BE099F8043013F0010009D099
+:103820000798002190F848300F9103F07F03209310
+:1038300021932CE04A6C554B02EA0303002BE6D19E
+:1038400020ABD7F8600100930DF18F0301930DF1C8
+:103850008E0302930DF18A03039323AA21AB0799E8
+:103860004FF028DA189A136843F00062189B1A6028
+:10387000BDF88A3013F0010F03D0189C42F40053B6
+:1038800023602E9DD5F1010538BF00250F95D7F88F
+:103890006036219A9C7A3B6893F8463013F0030116
+:1038A00000F0358112F0006F02F07F0104D007298B
+:1038B00006D9202904D02EE0354B5B56002B2ADA9E
+:1038C00012F0804F01D1002A25DB22F4401121F4AF
+:1038D000605112F0006F21911AD0D7F860068378FA
+:1038E000012B15D93B6B93F94D20012A0BD0079D75
+:1038F0006B6813F0804F0BD0B2F1FF3F08D1037B10
+:1039000013F0040F04D041F4801343F4805301E01A
+:1039100041EAC4232193209911F0006F01F07F0246
+:1039200004D0072A06D9202A04D036E0184B9B562B
+:10393000002B32DA219B13F0804F01D1002B2CDBBE
+:1039400021F4401222F4605211F0006F209221D035
+:10395000D7F860068378012B1CD93B6B93F94D1087
+:1039600001290BD0079D6B6813F0804F12D0B1F185
+:10397000FF3F0FD1037B13F0040F0BD042F48013F1
+:1039800043F4805308E0C046400001807F000008F7
+:10399000401B860042EAC4232093B7F8283603F47C
+:1039A0004063B3F5406F30D13B6B18690FF0BEF840
+:1039B000219B00F44070B0F5007F14BF0222032267
+:1039C00013F0006F03F07F0111D0202902D11546BA
+:1039D00005222EE097F9CA34B3F1FF3F12D10798C0
+:1039E000436813F4002F23D01546042221E09C4B9A
+:1039F0005B56002BB4BF97F9C93497F9C834B3F1BB
+:103A0000FF3F15D015469AB213E0219B03F07F03C8
+:103A1000202B04BF4FF000632193209B03F07F0312
+:103A2000202B04BF4FF00063209302252A4600E0BC
+:103A30001546219B110223F4E06341EA030321931D
+:103A4000209B23F4E06213F0006F14BF41EA0203ED
+:103A500042EA05232092219A209312F0006F06D0AB
+:103A600097F9DC31012B02D142F4000304E097F90D
+:103A7000DC3113B922F400032193209A12F0006F75
+:103A800006D097F9DC31012B02D142F4000304E0A7
+:103A900097F9DC3113B922F40003209307993846D3
+:103AA00012F03ED9219911F0006202D111920E92CA
+:103AB0001DE0D7F8583693F90530022B02D00022CA
+:103AC0000E9207E0C1F30223043B012B8CBF0023BD
+:103AD00001230E9311F4000F05D001F07F03072B93
+:103AE00003D9202B01D0119001E0042311932099D8
+:103AF00011F0006201D112921DE011F4000F16D0F6
+:103B000001F07F03072B14D9202B12D00FE0209B4C
+:103B100022F4E06223F4E06342F4007243F40073A1
+:103B200002252192209311910E91129103E012909F
+:103B300001E0042412940F9888B11A99219BD1F8BE
+:103B400010231A9801EBC201C1F814332F9C0132E3
+:103B5000E3B202F03F02C1F81833C0F81023BAF103
+:103B6000000F36D0FA68DAF80434D2F880410AEB54
+:103B7000C303C3F80442D2F884013A4AC3F80802E6
+:103B8000B8F8163003F00703D35C022B11D1DAF832
+:103B900000100AEBC102C2F80441C2F80801219BDF
+:103BA000013153602F9C01F01F01E3B29360CAF80A
+:103BB0000010DAF80424219B0AEBC201C1F8083492
+:103BC0002F980132C3B202F03F02C1F80C34CAF898
+:103BD0000424219911F000642AD011F4000F01F49B
+:103BE000E06312D01B0A043B012B1F4801F07F0247
+:103BF00005D8142302FB0303D3F80C801AE0142326
+:103C000002FB0303D3F8088014E01B0A043B012BDA
+:103C1000154801F07F0205D8142302FB0303D3F8F3
+:103C2000048007E0142302FB03F353F8008001E053
+:103C300001F07F080B9A022A00D0BAB9B7F83836DB
+:103C40000A98984204DC189A136813F0806F0DD01C
+:103C500099F8043083F0010303F0010307E0C04644
+:103C6000401B8600C4D285008418860000230D9373
+:103C70003B6B587D50B1D7F858361B7833B12CB90F
+:103C8000924A01F07F03D356002B0BDB3B6893F87D
+:103C9000463013F0030F2CD05CB3D7F8583693F9A5
+:103CA000053033B32F9A012A13D9D7F858361B7829
+:103CB0000BB1162300E03023189C20932193236836
+:103CC00023F000632360209B43EA05232093219384
+:103CD0000FE070B1D7F858361B7853B14CB97B4A16
+:103CE00001F07F030E98D35630EA230028BF01204D
+:103CF0000E90219A12F0006F15D102F07F03022B73
+:103D000005D0042B03D00B2B01D0162B0BD1069919
+:103D100039B1022B05D097F95C36013B18BF01235E
+:103D200000E000231193209B13F0006F16D103F0E5
+:103D30007F03022B05D0042B03D00B2B01D0162BB5
+:103D40000CD1069C44B1022B06D097F95C36013B9E
+:103D500018BF0123129301E0002012900B99079CD9
+:103D6000022904BF079BC3F86021636813F4803FF6
+:103D700040D097F8CE31002B3CD097F8D131002BB2
+:103D800038D0D7F8583693F90530032B32D0219B21
+:103D900013F0006F09D103F07F03022B2AD0042B0C
+:103DA00028D00B2B26D0162B24D099F8043013F0F2
+:103DB000010F1FD1089800F0FC03882B1AD1189925
+:103DC00001240B684BF4A04B43F480530B60079B1A
+:103DD0001094D3F8F0204FF69F73002A0CBF1822DE
+:103DE0001E2239F8021001EA030343F0200329F8E8
+:103DF000023001E000201090384621990A9A059B74
+:103E00000DF17A0419F028DC2346384620990A9AE5
+:103E100019F022DC062206F136002146FEF3ACF052
+:103E2000209B13F0006F10D103F07F03022B05D00D
+:103E3000042B03D00B2B01D0162B06D10A99C1F30A
+:103E4000072386F83A1086F83B30189B1A6812F45C
+:103E5000806F13D0219B13F0006F0FD0329C14B1F0
+:103E6000237A042B0AD1189842F40063036097F870
+:103E7000C3340D99002B18BF01210D91219911F028
+:103E8000006F0AD1114A01F07F03D356002B04DAE8
+:103E9000059A137803F00F0301E0059B1B78089C3B
+:103EA0000C93A42C14D099F8043013F0010F0FD107
+:103EB000109878B9119A319B38460FF06FDE89F867
+:103EC0000200C0F30F2089F803001DE0401B8600AC
+:103ED000109A62B1119A384640F62A1319F052D955
+:103EE000023080B289F80200000A89F80300089BBA
+:103EF000A42B09D199F8023099F8032043EA022350
+:103F000086F83C301B0A09E099F8043013F0010FE1
+:103F100001D1109C2CB1002386F83C3086F83D304E
+:103F20000BE02099129A319B38460FF037DE86F865
+:103F30003C00C0F30F2086F83D001898036813F486
+:103F4000007F0DD083894BF4005B86F842301B0A5A
+:103F500086F84330C38986F844301B0A86F845301A
+:103F60002E9909B94BF0080B09F104021B9299F83C
+:103F7000043013F0010F14D1189B1A6812F4805FFB
+:103F80000FD197F8D03113B112F0400F09D112F4CC
+:103F9000806F04D1169C14B197F8F8310BB94BF02F
+:103FA000010B0B98022814D197F8CE318BB1B8F1E0
+:103FB000040F0ED9AB4B30995B5C07EB4303B3F8AE
+:103FC000FE3123B1189A136813F4806F01D04BF4BB
+:103FD000805B3B6B18690EF0A9FD199B00F44060F3
+:103FE000B0F5406F08BF4BF4807B0BB14BF4004B36
+:103FF0004FEA1B2386F800B07370329CECB197F83F
+:10400000A034D3B91A98836D13F0080F15D1237A11
+:104010000B2B08D197F8F0377BB197F8F13763B1E4
+:10402000A379072B09D832998A79292A05D80B7BDD
+:1040300003F0070343EA021A01E04FF0000A189A5E
+:10404000129C1368494613F0005F18BF4AF0080A33
+:10405000631EDBB2012B98BF4AF4005A301D0222C6
+:10406000FDF38AF70023B371F37186F82C3086F8DC
+:104070002D303298002849D097F8A034002B45D134
+:104080001A998B6D13F0080040D1329B1A7A0B2AD3
+:104090000BD197F8F037002B38D097F8F137002B79
+:1040A00034D0329CA379072B30D832998B79292BC5
+:1040B0002CD8089C09F1180104F44073B3F5407F33
+:1040C000169B08BF09F11E0103B10231022A11D16A
+:1040D0003246329C2318B3F8BC309375C3F30723E0
+:1040E000D375831C02320A2B1846F2D106F1200048
+:1040F000032209E00B2A06F1160002D10231053233
+:1041000002E0329B93F90E20FDF336F706221B994D
+:1041100006F12600FDF330F79DF88C30002486F878
+:104120004C309DF88D3086F84D30D7F84C011A99F7
+:104130004AF0EEDF96F8463096F8472080B243EA20
+:10414000022343EA00239BB286F846301B0A86F816
+:10415000473086F84E4086F84F4086F8504086F843
+:10416000514086F8524086F8534086F8544086F80D
+:10417000554086F8564086F857400D9808B10E9481
+:1041800003E00E99002900F01D81002221992B46A1
+:10419000384622F051DE00228046209938462B46D0
+:1041A00022F04ADE18F000628346099206D12E4BB7
+:1041B00008F07F029B56002B2ADA36E018F4000F35
+:1041C00008F4E06310D01B0A043B012B274808F0D9
+:1041D0007F0204D8142302FB0303DB6814E01423DA
+:1041E00002FB03039B680FE01B0A043B012B1F48E3
+:1041F00008F07F0204D8142302FB03035B6803E08A
+:10420000142302FB03F31B58023B18BF012302E0F7
+:10421000931E18BF012343B197F95C36012B04D0DC
+:1042200001234AF4804A139301E0002413941BF005
+:10423000006F06D10C4B0BF07F029B56002B30DA3F
+:104240003CE01BF4000F0BF4E06316D01B0A043BA8
+:10425000012B06480BF07F020AD8142302FB03034C
+:10426000DB681AE098E08500401B86008418860011
+:10427000142302FB03039B680FE01B0A043B012B82
+:104280009D480BF07F0204D8142302FB03035B68F4
+:1042900003E0142302FB03F31B58023B18BF012366
+:1042A00002E0931E18BF012343B197F95C36012B3E
+:1042B00004D001254AF4004A149501E0002014902E
+:1042C0000E993278737821B142EA032343F40063F4
+:1042D00003E042EA032343F0060333701B0A7370C2
+:1042E0000E9B06F15802002B0CBF14250E251592CB
+:1042F0001DAC2A4638464146159B19F0ADD92346D8
+:104300002A463846594619F0A7D92146062206F111
+:104310002E00FDF331F6139C119D0A9800940024A1
+:104320000E99219B0195029042460394384619F05C
+:10433000B3D986F86000C0F30F2086F861001499A5
+:10434000129A0A9B009101920E9902930394209B6A
+:1043500038465A4619F0A0D986F83400C0F30F2029
+:1043600086F835000E9D06F162004DB16FF03B03FB
+:1043700009F10A01062286F85E3086F85F4008E0FF
+:104380006FF04B0386F85E300E990C2286F85F10B2
+:104390001B99FDF3F1F5099A52B9584A08F07F03C9
+:1043A000D356002B04DA159C237803F00F0301E0A9
+:1043B00096F858300C9D1B0243EA050506F15E098C
+:1043C0000C951BE00E99062206F15800FDF338F615
+:1043D0000E99102206F15E00FDF332F606F12E0072
+:1043E0000E990622FDF32CF60E9886F8340086F816
+:1043F00035008146139014908046834618990B68C7
+:1044000013F4806F0BD0219A12F0006F07D0D7F809
+:10441000400107990A9B2AF0B3DF86F833004FEA80
+:104420001A23F37086F802A00C9A130AB274F3747C
+:10443000209B13F0006F02D097F8C0A40EE003F0A9
+:104440007F03022B07D0042B05D00B2B03D0163B88
+:1044500018BF012300E000231FFA83FA18F0006F51
+:1044600003D097F8C0349D000EE008F07F03022BC4
+:1044700007D0042B05D00B2B03D0163B18BF01230C
+:1044800000E000239B009DB21BF0006F03D097F863
+:10449000C0341C010EE00BF07F03022B07D0042B6D
+:1044A00005D00B2B03D0163B18BF012300E00023DF
+:1044B0001B019CB23B6B18690EF038FB45EA0A03FE
+:1044C0002343C0B243EA002333751B0A7375219B53
+:1044D00013F0006F02D097F8C04413E003F07F039D
+:1044E000022B0DD0042B0BD00B2B09D0B3F11600EF
+:1044F00018BF012005E0C04684188600401B8600D6
+:10450000002084B2119D6B1EDBB2012B07D83B68E3
+:1045100044F01004D3F88C209369013393612199FE
+:10452000384615F02BDB44EA000080B23072000AF6
+:104530007072219938461FF055DEB072C0F30F201B
+:10454000F072209938461FF04DDE3073C0F30F2013
+:1045500070730D9808B90E9979B1414638461FF02D
+:1045600041DEB073C0F30F20F073594638461FF098
+:1045700039DE3074C0F30F207074219911F0006F90
+:104580000CD0119A042A09D10A9A384618F0ACDEE8
+:1045900086F83E00C0F30F2086F83F00209911F006
+:1045A000006F0CD0129B042B09D10A9A384618F0E0
+:1045B0009BDE86F84000C0F30F2086F84100079C80
+:1045C000636813F0400F00F0CE80169D002D00F0C0
+:1045D000CA806A4B30981B5C179307EB4303B3F810
+:1045E000FE31002B00F0BF8018990B6813F4806F28
+:1045F00040F08D802E9A002A40F08980219C384618
+:104600002146119A0A9B18F0BDDD8246B9F1000FD0
+:104610001AD04146139A38460FF082D8149A0446AD
+:10462000594638460FF07CD899F8032099F80230A3
+:1046300043EA022303EB040896F8352096F8343059
+:1046400043EA022318181BE0109B13B1804648462A
+:1046500016E02146119A4B4638460FF09FDA209C0F
+:10466000129A21460A9B00EB0A08384618F08ADDA8
+:1046700021460546129A38464B460FF08FDA40190C
+:104680001FFA88F3B3711B0AF37183B286F82C30DA
+:104690001B0A86F82D30179C07EB4403B3F8FE5134
+:1046A000CAEB0804A54225D31898036813F0400FFD
+:1046B00002D0309901291DD038462199119AC4EBB6
+:1046C00005030FF035D8FF2802D84FF4807304E0BB
+:1046D000B7F82A36834228BF034699B2309B07EBCE
+:1046E0004302B2F82C368B4204D0A2F82C1638467E
+:1046F00026F0CCD83B6893F84430002B33D0309C64
+:10470000032C30D8D7F864011799424628E03B685B
+:1047100093F844303BB3309D032D24D8B9F1000FFA
+:104720000CD0139A384641460EF0FADF99F8032070
+:1047300099F8023043EA02231A180EE0219C119ADC
+:1047400021460A9B384618F01DDD119A0546214680
+:1047500038464B460FF022DA4219D7F86401179910
+:10476000079B3DF02FDD1898036843F08403036036
+:10477000BDF88C0025B0BDE8F08FC04698E08500FC
+:104780002DE9F0479946536A064613F4007F8846A0
+:1047900017469DF920A0146902F1240515D0E86898
+:1047A00083B2000C84F8423084F844001B0A000AEB
+:1047B00084F8433084F845002378607843EA002386
+:1047C00043F4005323701B0A637033682D6993F818
+:1047D000443093B1F36A03EB4803B3F91C3063B977
+:1047E0005DB12B69D3F8D43293F89D30032B04D9F3
+:1047F000D6F864012B463DF0C5DDB8F1040F22D197
+:1048000094F84D3094F84C2042EA0324336893F82E
+:104810003830D3B1384612F045D906EB8000D0F8D5
+:104820004C12D1F85835D1F860055A1CC1F85825FA
+:10483000C369A1F8C8409A4288BFC261D1F8602517
+:10484000136A013313624FF6FF74B9F1000F05D0FC
+:10485000F26A02EB4802938B534493834FF6FF7343
+:104860009C4204D03069A821224639F0F3D933693B
+:10487000394603EB8803D8680C4B4A465B6A984775
+:10488000002810DA0A480CF00FFF0A4A13680133B7
+:104890001360B9F1000F06D0F26A02EB4802938B65
+:1048A000CAEB03039383BDE8F087C046E0A685000A
+:1048B000BC568600E827020070B50D46D0F8601699
+:1048C0000446CB7AAB420CD025B10C31B0F8282687
+:1048D00015F098D9D4F860362046DD72216BFEF7CA
+:1048E000F7FD002070BDC0462DE9F04F89B00023D0
+:1048F0000D46179907460492149CDDF854800793DF
+:104900000693DDF848B0DDF84C903AF073DD049A78
+:10491000824602F001060096386829462246434640
+:104920001EF0D2DC0590002840F0ED80B5F906308D
+:10493000002B1CDAA9882A895EB1169BCDF800806D
+:1049400003930194CDF8088049003869013123466A
+:1049500009E0169BCDF8009003930194CDF80880F0
+:10496000386949005B4638F0FBD80590CBE0B9F1D7
+:10497000030F0DD9042207A85946FDF3FDF2B9F142
+:10498000070F05D906A80BF104010422FDF3F4F288
+:10499000049A0799931E1F2B21D8DFE813F02300F8
+:1049A0002500270029002E00310038003A004B0076
+:1049B0004D0053005500570059005B005D005F003B
+:1049C000200065006C0074007600870089008D006F
+:1049D0008F00940096009B002000A6009D006FF0C1
+:1049E00016038FE04A4B09E0494B71E0494B05E063
+:1049F000002900F38580474B05E0474B1B6879E0B1
+:104A000000297DDB444B1960444B002239E0444BC4
+:104A1000F4E719B1434B1B68002B71D0404B0022C7
+:104A20001960414B1A60414B1A60414B1A60414B6F
+:104A3000013A26E03B4BE1E73A4A1368002B5FDD81
+:104A4000116060E03C4BD9E73B4B41E03B4BD5E785
+:104A50003A4B3DE0344BD1E7334B39E0D7F86C3279
+:104A6000D3F8D8329B6845E0354B1A68354B1B6844
+:104A700043EA02433EE0324B0A141A60314B01F024
+:104A8000FF021A603FE0304BB8E72F4B1960002956
+:104A900039D02E4B002119602D4B4FF0FF321A6098
+:104AA0002C4B1A602C4B19602C4B11E02C4BA5E7BA
+:104AB000002925DD2A4B0BE02A4B9FE74B1E092BD3
+:104AC0001ED8284B04E0284B98E7002918DD264B18
+:104AD000196018E0254B91E79AF8063063B9244B2A
+:104AE0000A1E18BF01221A700DE09AF806301BB991
+:104AF0001F4B1B78236006E06FF00602059202E070
+:104B00006FF01C030593059809B0BDE8F08FC0460F
+:104B1000EC270200D8270200E0270200B827020095
+:104B2000C0270200401E0200D4270200D027020046
+:104B3000C8270200B42702002C1E0200441E0200F7
+:104B4000142C0200102C0200BC270200E4270200F3
+:104B5000281E0200381E0200C4270200DC270200C3
+:104B6000341E02003C1E0200241E0200CC2702005C
+:104B7000B027020037B5036804465B7E002B40F087
+:104B8000C480026992F8EA305BB1D36ED3F8202179
+:104B900040F2044302EA0303B3F5806F40F0B580AE
+:104BA00005E0106E0AF050FE002840F0AE80236849
+:104BB00093F8203033B9206907F062FE22680123A0
+:104BC00082F8203023681B6FFBB9206907F0D6FDFF
+:104BD00010F1090F19D12268136F13F0020114D1DB
+:104BE00043F0020313670D4604EB8503D3F84C1220
+:104BF00041B18B7933B94B7923B18B7C13B120460A
+:104C00003AF03ED90135082DEED123681D6F1DB154
+:104C1000204612F079D976E0012384F82930204625
+:104C200021F004D82368596B39B103234FF4807203
+:104C3000009320462946134605E0032300932046AF
+:104C40004FF480720B461EF0BFDFA0680AF02CDD27
+:104C5000236801221A7694F89D3173B120460CF036
+:104C6000C1FDD4F840352046598E23F0DFDE002305
+:104C700084F89D3120461DF0C3D9B4F85C17204656
+:104C800021F04CDF206907F0DFFF236893F82F3015
+:104C90001BB1D4F8340730F03DD8236893F8313095
+:104CA0007BB1002504EB8503D3F84C1231B18B792D
+:104CB00023B94B7913B1204635F0FADE0135082DC2
+:104CC000F0D1204615F00EDF204618F0EDFA012550
+:104CD000D4F8AC114FF448720123A0680AF076DCD6
+:104CE000204684F8F15125F0D1DD204614F072DF22
+:104CF000204626F02DD950B1204626F007D920466F
+:104D0000294626F00DDB002001E06FF008003EBDD3
+:104D1000D0F8403570B55D8E064605F44063B3F5B6
+:104D2000406F22D1036893F8463013F0030F0BD085
+:104D300005F47041D0F85C01B1F5805F14BF00212B
+:104D4000012141F0B7DA80B92846FEF36BF2044640
+:104D50002846FEF367F244F430640E288CBF4FF40B
+:104D600080504FF400500443A5B2326B05F47043F9
+:104D70005268B3F5805F14BF00230123934205D02E
+:104D8000D6F85C01012140F0B9DD0546D6F85C019A
+:104D9000294641F003DB80B905F47043B3F5805F29
+:104DA00014BF38233C23F358346BD6F85C013363CB
+:104DB000012140F0A3DD34630546284670BDC0469E
+:104DC00070B50025044680F8E85124F0B7DDE36AA9
+:104DD0002946986A8022FDF333F1206908F0BAF978
+:104DE000D4F840012AF09EDCC4F8885670BDC04655
+:104DF0002DE9F04390F8A03187B00446002B40F035
+:104E0000ED8003681B7E002B00F0E880012380F812
+:104E1000A031006907F0E6FE2269074692F8EA3001
+:104E20005BB1D36ED3F8202140F2044302EA0303BE
+:104E3000B3F5806518BF012503E0106E0AF004FD8C
+:104E40000546002D6FD1D4F8680104214FF0B0DB86
+:104E5000204621F0A3DE00B90137A94604EB09037F
+:104E6000D3F84C62002E59D096F80680B8F1000FA6
+:104E700054D1304633F06ADC73793F18002B4DD0A3
+:104E8000236893F83130002B3FD0D6F8CC3013F0A4
+:104E9000010F3AD0204631460CF0B4FC23683F188D
+:104EA00093F89530002B39D0D4F86C122046BC31E1
+:104EB00050F074DC0546002830D02046294622F008
+:104EC0008BD82B7E13F0020F19D02846022150F008
+:104ED000B7D8B17CD4F86C32D1F1010138BF0021D0
+:104EE000082201920291204631460332BC33CDF8AC
+:104EF0000080CDF80C80CDF8108017F00FDED4F8CC
+:104F00006C22012382F8F03008E02046314639F067
+:104F1000B7DF3F184FF47A6001F01EDC09F1040995
+:104F2000B9F1200F9AD10025D4F8B434EA18136BE4
+:104F300013B1506A98473F18343540F2AC439D4254
+:104F4000F2D194F8F1314BB1A068D4F8AC110AF069
+:104F500085DB00B90137002384F8F1312046FEF7E4
+:104F60000DFB236800211976236B4FF0FF32C61921
+:104F700018690DF0B3FD204615F08ADAD4F878529E
+:104F800007E00023291D606801220093FDF35AF712
+:104F90002D68002DF5D1236893F82F3073B1631974
+:104FA000D3F84C1239B18B792BB10B791BB1204658
+:104FB0000CF028FC36180435202DF0D1D4F87C02F2
+:104FC00010B10BF03BFE3618206907F0BDFD002341
+:104FD000801984F8293084F8A03100E0002007B05F
+:104FE000BDE8F0832DE9F04F9BB005462598089267
+:104FF0000793827AC37A0F4642EA0323269A00F186
+:105000000C010C3A08980A9113930B92C27D837D90
+:105010000DF1580943EA0223C3F3C70ABAF10E0F90
+:1050200094BF002101210F91079918F0C1F8249A2B
+:1050300028460A32114609920F9A50F0B9DB002433
+:10504000804615AE28462599269A4B461594169407
+:1050500000961CF0DFDF30B928462599269A4B468A
+:1050600000961EF0D7DFB8F1000F06D0D8F8043054
+:1050700013F0010F01D00C9427E00B990A9832220B
+:10508000FDF31CF3014620B14078023120F0E2DF4D
+:1050900058B90B990A980122FDF310F3014638B173
+:1050A0004078023120F0D6DF10B101230C9301E0EB
+:1050B00000200C90B8F1000F07D00C9929B9D8F84E
+:1050C000043043F00103C8F804300A980B99032216
+:1050D000FDF3F4F2044608B14378A3B92B6893F8C2
+:1050E0003F3053B1B5F82606C3B2534503D0FEF3A3
+:1050F00099F0504501D1012300E0002300225FFA1E
+:1051000083FB0D9211E02B6893F83F3043B1B5F863
+:105110002606FEF387F0A378834201D1012300E045
+:1051200000235FFA83FBCDF834B0BBF1000F01D14F
+:105130005B4602E03B1E18BF01235FFA83FA2B682F
+:1051400093F8463013F0030002D11090119024E040
+:1051500095F8723263B9BAF1000F09D0D7F8D4329A
+:10516000DB8813F0200003D110901190129018E00A
+:105170000A990B9A284620F0DFDF0A9911900B9AC2
+:10518000284620F0A5DF2B68109093F94C0020B141
+:1051900028460A990B9A1DF0C9DC1290BAF1000F4B
+:1051A00069D02B6893F8463013F0030F63D0109B3F
+:1051B000002B60D0119800285DD019785A782846C5
+:1051C0000FF0E0DEB5F82696064609F47043B3F515
+:1051D000005F0CBF38233C23EC58D5F85C016168B4
+:1051E00040F08CDA10F0080F01D0002104E094F8B0
+:1051F000EC30191E18BF0121119A137813F0020325
+:1052000017BF10981A464378C3F3800209F440632D
+:10521000B3F5406F18D1B5F82636B34202D100215C
+:105220000E912EE02B6893F82F30002B40F05B841A
+:105230003046FDF3F7F70446B5F82606FDF3F2F71E
+:10524000844240F0508414E0A9B1A2B106F4406356
+:10525000B3F5406F0FD12B6893F82F3073B93046F8
+:10526000FDF3E0F70446B5F82606FDF3DBF78442CC
+:1052700004D10E9605E000220E9202E000230E9368
+:105280009A462B6B5B7D002B3AD0BBF1000F37D0D9
+:1052900095F8723233B995F87432002B30D0BAF1E8
+:1052A000000F2DD195F849365BB1159B002B08DD19
+:1052B000169B1B7813F0040F03D0D5F8582604234F
+:1052C000136195F8493653B10C9850B9139911F000
+:1052D000200F0ED1D5F858260423D36009E00C9A8C
+:1052E0003AB1159B002B08DD169B1B7813F0010FBC
+:1052F00003D0D5F8582604231362284625F06CDE27
+:105300002B6893F8463013F0030F46D0BBF1000F23
+:1053100043D095F8723233B995F87432002B3CD0F3
+:10532000BAF1000F39D1B5F8263603F44063B3F56E
+:10533000406F14BF00210121109B13B90C9830B9A4
+:1053400016E0109A937803F00303032B05D1D5F8E8
+:10535000582604239361109B53B11098837803F06F
+:105360000303022B04D119B1D5F858260233D362B6
+:10537000119A7AB1109B6BB111985A78037813F097
+:10538000020F07D112F0040F04D019B1D5F8582636
+:105390000423D362284625F0D1DE2B6893F82F3002
+:1053A000E3B1D5F8FC341B78C3B10D99B1B92846E7
+:1053B00011992FF01FDA88B128460D992FF01CDBC8
+:1053C00028462FF00FDBB5F8263603F44063B3F51B
+:1053D000406F03D1284601212FF080DAB8F1000F89
+:1053E00029D0D8F8F03033B300230B99824A0A98B9
+:1053F00000931CF087DF41460246284620F0C0D9C2
+:105400002B6893F8463013F0030F14D0119A2AB189
+:10541000129B28460093109B41460AE0D8F80430BE
+:1054200013F4803F07D01198119A00904146284606
+:1054300013461DF0DBDB95F87032002B00F06C8317
+:105440000FB93E4601E0D7F8DC62BAF1000F00F078
+:1054500083802B6893F8463013F0030F3DD0BB7C5C
+:1054600043B9B8F1000F08D1284609990F9A50F0B6
+:10547000B9DA8046B8F1000F2FD01199C9B1D7F829
+:10548000CC3013F4005F05D0B7F8343543F0200377
+:10549000A7F83435129A109B009228464146119A7B
+:1054A0001DF0A4DBB7F8343523F02003A7F834351A
+:1054B0000DE0BB7C5BB9D8F8043013F4803F06D014
+:1054C000119B284641461A4600931DF08FDB284663
+:1054D0000A990B9A434620F079D9089928461EF07C
+:1054E0005BDA41B238461EF099DA38461EF0EED942
+:1054F0000899284612F0E4DA0146384611F046DAF7
+:10550000BB797BB9D7F8E032D7F8D422188A9B8AC6
+:105510005085938573792BB9BB7C1BB1384601212B
+:1055200035F038DF0023B371F371BC7CA4B996F871
+:105530008530012B10D186F88540D5F8400126F042
+:10554000FDDF284639460F22234600940194029439
+:105550000394049417F0E2DA002F5AD0BB79002BA1
+:1055600057D1BB7C002B54D0259925988B784A784D
+:105570001B0443EA02230A781343CA78043143EA3E
+:1055800002698B784A781B0443EA022302791343A9
+:10559000CA7843EA0264F26912B9336A13B935E092
+:1055A000944204D3944231D1336A99452ED2DDF826
+:1055B00090E0002300930193029303930493284601
+:1055C000394616220EF1100317F0A8DA384608996A
+:1055D000079A259B24F0A2DFBBF1000F16D0FB79C0
+:1055E00063B1BB7C23B107F1BC00FDF3B5F128B971
+:1055F00007F1BC0104E0C0460FD4010007F1D60159
+:10560000002228461346009222F02ADDC6F8209098
+:10561000F461BAF1000F00F01F82BB79002B40F05B
+:105620009681BB7C002B00F0928114AB00932599EE
+:105630003846269A0DF1670316F016DBBDF85010B8
+:10564000D7F8E462A7F8201595F8EB41002C65D156
+:1056500000284FD03378022B19D138462146B6F8AE
+:1056600026900BF0DDFDB5F8303885F8324803B1EF
+:10567000F38438461EF0A6DFD7F8E432A6F8269069
+:105680005B8B002B4AD0384611F062DA46E02B687B
+:105690005B6B4BB195F8FA3133B1B8F1000F14D010
+:1056A00098F8D2300F2B10D0B27822B12846394664
+:1056B00023F0D6D832E04FF0FF330093284607F1AD
+:1056C000BC01134622F0CCDC28E095F80D372BB353
+:1056D000B3785BB1B8F1000F05D0D8F8043023F0EF
+:1056E0000063C8F80430384616F09CDB384623F0D7
+:1056F000B9DD13E0337A23B1718911B9384623F04B
+:10570000DFDDD7F8E4325B8B43B13378022B05D170
+:10571000336A012B02D138461EF040DFF3781BB10B
+:105720003846002123F0C0DC737A1BB138460021D3
+:1057300023F0B2DE2B6B5B7D002B41D0139A284601
+:10574000C2F3802124F0B2DD169A002A38D0159BCE
+:10575000002B35DDD5F8581691F90130B3F1FF3F34
+:1057600009D11378C3F340020B78934203D0284643
+:10577000012120F0FDD8169B1B7813F0040318BFFD
+:10578000012385F8463695F94636012B03D0D5F826
+:1057900058361B690BB1002300E0012385F842361F
+:1057A000B8F1000F0CD0D8F8043023F00402C8F888
+:1057B000042095F946361BB942F00403C8F80430BA
+:1057C0002B6893F8463013F0030F36D0109B002B54
+:1057D00033D0D5F8582692F90630B3F1FF3F27D1E0
+:1057E000109892F90520837803F003039A4204D0BD
+:1057F00028460B211A4620F0BBD810998B78C3F3AA
+:105800008002D5F85836DB79934203D028460D2123
+:1058100020F0AED8109A9378C3F30012D5F858361A
+:105820009B7A934209D02846102120F0A1D804E0A9
+:10583000012B0CBF032300235371D5F85C01B5F88D
+:10584000261640F073DB90B1D5F85C01B5F826164A
+:105850003FF0ACDF2B6B18690DF068F9B5F8263610
+:10586000834204D1002128460A461EF095DBB8F198
+:10587000000F3FD0D8F8043013F0400F00F03F8104
+:105880000A9B0B981893179006E02846214618AA01
+:1058900017AB1DF063DE40B918981799DD22FCF3B1
+:1058A0000DF704460028F0D122E1A11C0E79012E4B
+:1058B00040F025818A7995F80C3202F00F0203F04E
+:1058C0000F039A4200F01B8105F500740634204650
+:1058D0001822FCF351F32B6893F830303BB1D5F824
+:1058E0003407214600F563701822FCF345F338466F
+:1058F000314602E128460A990B9A10F087DC01280C
+:1059000002D128460EF018DA0E9929B195F86D35B6
+:1059100013B9284618F0DED8259A079B0092D5F8CF
+:105920004C013946089A49F07DDAD7F8CC3013F4A7
+:10593000005F00F0F180259B269800930190394686
+:10594000D5F84C01089A079B4AF0C2D9E4E0BB7C29
+:10595000002B40F081800C9909B1012102E0139ADB
+:10596000C2F34011CCB2B8F1000F15D0D8F8043012
+:1059700014B143F0040301E023F00403C8F8043039
+:105980000B990023664A0A9800931CF0BBDC414641
+:10599000024628461FF0F4DE2B6B5B7D13B3159B8C
+:1059A000002B11DD169B1B7813F0040F03D0D5F8E4
+:1059B000582604231361169B1B7813F0020F03D0A3
+:1059C000D5F85826042353620C9B1BB9D5F85826EA
+:1059D0000433D3611CB9D5F858260423D360284674
+:1059E00025F0FADA2B6893F8463013F0030F00F035
+:1059F0009380109840B1837803F00303032B03D105
+:105A0000D5F85826013393621199C9B1119BB5F8A5
+:105A100026165A781B7843EA022010F0100F03D1A3
+:105A2000D5F858260423536310F0020F08D101F46F
+:105A30004063B3F5406F03D1D5F8582604231363B0
+:105A4000109828B90C9919B1D5F858260423536138
+:105A5000284625F073DB5FE095F85735002B5BD0C7
+:105A6000BBF1000F58D0139A12F0020F54D00A98CD
+:105A70000B990022FCF322F6034600284CD028465E
+:105A8000991C5A7839F06EDC0446002844D0837C97
+:105A9000002B41D10899079A16F0B4DE00283BD0BC
+:105AA000259BD4F8D06226980093249B019003F1A3
+:105AB0001002284608990123029620F053DC024682
+:105AC00050BB296BD5F86036503106F138009B7811
+:105AD0004BF054DA269808990090079A2046259BA7
+:105AE00034F034DD18E000218A460E91FFF7C9BB7F
+:105AF000022385F80E32384601211CF051D90023CB
+:105B00000B990A98064A00931CF0FCDB41460246BA
+:105B100028461FF035DEEDE61BB0BDE8F08FC0462D
+:105B20000FD401002DE9F04FD2F81080C1B0D8F8A1
+:105B3000D8A2064609910892DAF82C00DAF830105B
+:105B400000220793FCF3BAF520B1831C109342782E
+:105B50000B9205E0099A099B093210921B7A0B936C
+:105B60002CAF002128223846FCF36AF200212822BB
+:105B700022A8FCF365F2DAF830100122DAF82C00E2
+:105B8000FCF39CF5DAF8301004463222DAF82C00E7
+:105B9000FCF394F505463CB16278102A04D8381D10
+:105BA000A11C2C92FCF3E8F13DB16A78102A04D8CC
+:105BB00023A8A91C2292FCF3DFF1099AD38813F0E1
+:105BC000010F17D0316B4B7DA3B10A6D2CAC201D9A
+:105BD00054312C92FCF3D0F1D8F8CC3013F4005FA0
+:105BE00005D0D6F84C014146224649F0E3DF0023B8
+:105BF000229309E022AB0093099B304603F138025F
+:105C000041462CAB20F022D9B8F86250DAF82C408B
+:105C1000B5F5806FDAF8307059D0B5F5006F04D162
+:105C20000022934611920C9257E020463946FDF32C
+:105C300051F3119020B143784FF0000B0C930BE01F
+:105C4000204639463022FCF339F5834610B9119AC3
+:105C50000C9201E043780C93402D09D0802D07D0A1
+:105C6000102D05D0B5F5807F02D0B5F5007F33D17A
+:105C7000D8F8582040F2371302EA030363B30C9AB2
+:105C8000BBF1000F08BF1422402D0C922ED14FF013
+:105C900000094F4616E0162307FB03F303F5B47320
+:105CA00008EB03040998211D0622FCF349F140B9D1
+:105CB00040AB03EB890204F10A0342F8B83C09F156
+:105CC00001090137D8F8CC329F42E4D310E000221A
+:105CD000934611920C9200E045B1D8F8582040F25A
+:105CE000371302EA03030BB118230C934FF000099A
+:105CF00040F2EE5301933FAB0293079B099A002BAE
+:105D000014BF20210021304608F1C20300921CF08C
+:105D100053DB0D9030B930460D99B8F80C2332F0B2
+:105D2000DDDE83E23F9A304602F5BC630E330A9211
+:105D30004146099A0E93FDF707FB0A9A1070C0F3CB
+:105D40000F2050709AF8223093709AF82330D37055
+:105D5000131D3F93079B8BB10AF124042046FCF3EB
+:105D6000FBF510B93F98214602E03F9808F1D601B3
+:105D70000622FCF301F13F9B06333F933F9A00213B
+:105D80000F921046109B0B9A26F0EED92DAB0121F5
+:105D90002C9A3F9026F0E8D90C9B3F90002B7CD0AA
+:105DA000BBF1000F11D0B9F1000F03D030465946B6
+:105DB000FDF7F6FA3F9C5946204617F0A7DC3F90C6
+:105DC0009BF80130A346637019E0402D09D0802D67
+:105DD00007D0102D05D0B5F5807F02D0B5F5007F36
+:105DE0005BD1A649834617F091DC099B3F9003F1F4
+:105DF0007B02304641460BF1040313F0F5DA402DE7
+:105E000009D0802D07D0102D05D0B5F5807F02D0A8
+:105E1000B5F5007F41D1B9F1000F01D14C4626E024
+:105E20009BF801300BF1020202F80390D7184FEAF9
+:105E300019237B709BF80130002402338BF801306A
+:105E40003F9B02333F9312AB07EB041053F824102F
+:105E500002301022FCF390F09BF801300134103333
+:105E60008BF801303F9B10334C453F93EBD1D6F874
+:105E70006C32D3F8D8325B68022B0ED16CB10022A1
+:105E800000920192CDF808B09BF801303046023301
+:105E90000393572113461DF00BDE229A2AB13F9837
+:105EA000322123AB26F060D93F90DAF82C401CE079
+:105EB0006278C1F102031B199B18671C83421CD82E
+:105EC000119BA34219D02378012B0BD9302B09D079
+:105ED00002323F982146FCF34FF03F9B6278023339
+:105EE0009B183F933B78A21CD41834B1DAF82C10DD
+:105EF000DAF830000B189C42DAD3336893F8463056
+:105F000013F0030F18D0089A536813F4803F13D08E
+:105F1000326B0DF1DB041368404621466532022BDB
+:105F200014BF0023012326F081D83F982D211A2287
+:105F3000234626F019D93F9096F8653633B106F519
+:105F4000CC613F98043117F0E1DB3F90336893F860
+:105F5000463013F0030F1FD0089A536813F4803FA4
+:105F60001AD0326B0DF1DB0113684046022B14BFCF
+:105F700000230123653226F059D83F990E9B8B42AE
+:105F800001D2002202E00E9BC1EB030230460DF16C
+:105F9000DB0325F009DF3F9033685B6B4BB3099A55
+:105FA000D38813F0040F24D00DF1F50034490322F7
+:105FB000FBF3E2F702238DF8F83000238DF8F93077
+:105FC00001338DF8FA3096F8FA313BB1099A92F91B
+:105FD0006A30002B02DA96F80A3700E000238DF8C9
+:105FE000FB303F98DD2107220DF1F50326F0BCD8E8
+:105FF0003F90B5F5806F02D0B5F5006F06D1D8F8A7
+:106000002C3543B33F98D8F8281505E00C9B13B303
+:10601000119A2AB13F98114617F078DB3F901AE0A9
+:10602000402D18D0802D16D0102D14D0B5F5807FBE
+:1060300011D0B5F5007F0ED03F9C1249204617F0D5
+:1060400065DB099B3F9003F16B023046414604F14A
+:10605000080313F0C9D96B1E9BB2012B03D9042D81
+:1060600001D0082D10D1099A506E002838D0B2F80E
+:1060700068100C300C39FDF32DF11BE0CCD28500FB
+:1060800017D40100E2D28500402D09D0802D07D021
+:10609000102D05D0B5F5807F02D0B5F5007F1FD15A
+:1060A000099B586EE0B1B3F868100C300C393022FF
+:1060B000FCF304F3A0B1D6F86C32D3F8D8325B68A5
+:1060C000022B0DD14378102B0AD902330022029003
+:1060D0000393304657210123009201921DF0E8DC22
+:1060E000D8F8583013F0040F01D004230EE013F059
+:1060F000020F01D0022309E013F0010F01D00123A8
+:1061000004E013F4807318BF4FF48073089A13648B
+:10611000336893F8463013F0030F2DD0089A136CB0
+:10612000013B012B09D8536813F4802F05D0114689
+:106130003046062224F0B4DD1EE0089A536813F4BA
+:10614000802F19D011463046062224F04DDD30460E
+:1061500016F07ADF012801460ED1D6F8F83742F260
+:106160000E721B88013B9BB2934202D83046013924
+:1061700000E0304628F0AADF3F9C0E9BA34201D2EC
+:10618000002302E00E9AC4EB020300932023019344
+:10619000002123464FF0FF32404639F0C5DF0F9B08
+:1061A00000273F90C01A03930490414655223B4676
+:1061B000304600970197029716F0B0DC0A9A3F9B91
+:1061C000A2F11805C5EB0304DAF834100D9B9C828C
+:1061D00021B17068DAF8382000F08ADD0A9A706818
+:1061E000C5EB0203E41A214600F072DDCAF8340060
+:1061F00040B1079BCAF838408AF83C300A992246D9
+:10620000FBF3BAF6099A3046B2F862300197C3F34D
+:10621000401300930297089B0D99D6F804281FF0AD
+:1062200081DC0D9B002808BF00230D930D9841B021
+:10623000BDE8F08F2DE9F04F95B0079119690692EE
+:1062400005930A9101F106098A7999F80130064609
+:1062500042EA0323069A0893C0F87828C3F381051D
+:1062600013465B79127942EA0323099303F003038F
+:10627000022B08D1089C14F4004F04D0D5F101037F
+:1062800038BF002300E00023DBB205990B930B9A83
+:106290008B8AA3F10A0893001DB918339845C0F200
+:1062A000A081089B03F0FC07A42F03D0842F01D00A
+:1062B000942F03D1B8F10F0F40F3938199F8043074
+:1062C00009F1040A13F001030C9303D00024109485
+:1062D0000D9408E05146304639F020D8011E18BF11
+:1062E000012110900D9125B1002293460E920F923C
+:1062F00010E009F110043046214638F0EBDF0E9033
+:1063000010B183460F9505E03046214639F04CD850
+:1063100083460F9096F8C83123B9326892F82C3032
+:1063200033B925E030460699059A00230FF068DD61
+:10633000A42F03D0842F01D0942F01D10D9B53BBE8
+:10634000802F28D0502F26D0002D40F006840D9CA1
+:106350000CBB5046FCF3F0F2002800F0FE83BBF1CA
+:10636000000F18D109F11000FCF3E6F298B9F4E33C
+:106370000C9981B90D9B43B192F838305BB155B996
+:10638000BBF1000F07D1109C2CB9D2F88C20936F71
+:1063900001339367E1E396F8C8317BB9BBF1000F95
+:1063A00001D05C4601E0D6F86C4294F8E5302BB1A0
+:1063B00030460699059AA3680FF022DD012D10D111
+:1063C000C42F0ED0D42F0CD009F10A00FCF3C4F274
+:1063D000002840F0C28399F80A3013F0010F40F012
+:1063E000BC83059930460B69A1F8148006330B6114
+:1063F00033684946D3F88C20D36C0133D3641FFA39
+:1064000088F30093069A13AB12F072D830B1336858
+:10641000D3F88C20D36F0133D3679EE3139A12B164
+:1064200033689B6A1362012D39D1059A059B106967
+:10643000998A00F11002059C1A61A1F11003A38250
+:106440000B9B2BB100F11402A1F114032261A38272
+:106450000599A42F8C8A0FD113990B699B79002B76
+:1064600000F07B8391F8DF30002B00F0768330461C
+:10647000089A2FF0DDDD70E3336893F84230002B8B
+:1064800000F06B83842F02D0942F40F06683D6F8FF
+:10649000400113992346009728F0C2DF5DE3069A76
+:1064A000937DD27D43EA0223C3F3C7030E2BD4BFEF
+:1064B0000023012311930C9B002B62D199F8163015
+:1064C00099F8172043EA0228139B33B9304609F1A3
+:1064D0000A01119A4FF06CD91390089C14F4006AC9
+:1064E00005D0139B1BB1B3F8BC30434525D0139B9B
+:1064F0000BB1A3F8BC80139B8BB142E006EBC20347
+:1065000003F5F3642046FCF327F270B909F10A00A1
+:1065100021460622FBF314F5013508B906E01D46B5
+:1065200096F8E837EAB29342E8D20024BAF1000FB5
+:106530000CD064B1E388434521D13368D3F88C2073
+:10654000D2F8BC310133C2F8BC3106E3BCB996F8CD
+:10655000E83709F10A0106EBC30202F5F3640133DF
+:1065600086F8E83706222046FBF306F596F8E8178A
+:106570000A23B1FBF3F202FB131386F8E837A4F801
+:1065800006800D9961B10E9A52B19BF806303BB965
+:10659000DBF8E4321B7A1BB15846089910F0B4DEE0
+:1065A000059B059C1869998A00F118021A619246A8
+:1065B0000B9AA1F11803A38232B100F11C02A1F1E0
+:1065C0001C032261A3829246059C0899099BB4F89A
+:1065D000148011F48044C3F3C0150DD0B8F1070F37
+:1065E00006DC3368D3F88C20536E01335366B4E273
+:1065F000B02F40F0B28227E0502F00F087800ED8F5
+:10660000202F00F0768205D8002F00F07282102F24
+:1066100045D0A2E2302F42D0402F56D09DE2B02F7D
+:106620000ED006D8802F00F09080A02F00F055816A
+:1066300093E2C02F00F0AC81D02F00F07B828CE27F
+:10664000B8F1050F40F38382BBF1000F00F08582A3
+:106650009BF80630A3B19BF80430002B00F07D823C
+:10666000069ACDF800800195137CD6F8340703F024
+:106670000803029359464A46534604F06DFE6CE205
+:10668000D6F8403593F93430002B00F06682584636
+:10669000494652464346009532F09ADC5DE2B8F135
+:1066A000050F40F35482BBF1000F00F056829BF8B7
+:1066B0000630002B40F05182139B58460093494608
+:1066C0005246434632F042DA47E2336893F8953057
+:1066D00013B996F872326BB108F118030393304680
+:1066E0002C2109F10A02234600940194CDF8089068
+:1066F0001DF0DED9069B0A9C0093D6F84C01494652
+:1067000052464346019449F00FDB26E2B8F10B0FE5
+:1067100040F31D82D6F84C015146424649F0BEDC9A
+:10672000D6F868319B79002B00F017820D9900296B
+:1067300000F01382304606990A9A4B46CDF800A025
+:10674000CDF8048010F042DF07E2B8F10B0F40F300
+:10675000FE810A9B30460E99069ACDF80090CDF83E
+:1067600004A0CDF80880FEF73DFCD6F868319B798F
+:106770004BB1304606990A9A4B46CDF800A0CDF8A9
+:10678000048010F023DF96F87232002B2ED19AF895
+:106790000A3013F0010F29D030465146424617F017
+:1067A00039D818BB069A937DD27D43EA0223C3F3FE
+:1067B000C7040E2C8CBF0023012363B10AF10C0027
+:1067C000A8F10C010322FBF379F778B143786BB1A0
+:1067D0008378A3420AD1336B18690CF0A7F9C0B2D1
+:1067E000844203D1D6F868014EF0AAD80F9B0BB1B2
+:1067F0001D4607E0304609F1100138F0D5DD0546A9
+:10680000002846D0AA79002A43D10AF10C00A8F149
+:106810000C01D5F8D842D5F8DC72FBF34FF7A2682B
+:1068200081460B2A08D1284606990A9A5346CDF884
+:10683000008033F08BDE0DE0336893F831304BB1DC
+:106840000F2A07D1284606990A9A5346CDF80080A8
+:1068500034F04CDAAB7CE3B197F85A30CBB1D6F8D0
+:106860006801494601224EF013D930B197F85930EA
+:106870001BB9013387F859300BE0D6F86801494657
+:1068800001224EF005D920B997F859300BB187F89D
+:1068900059000E9C002C00F06081DBF8D8329B6818
+:1068A0000C2B40F05A815346584606990A9A23F019
+:1068B00035DE5846002131F0FFDF336893F82F3082
+:1068C00023B1D6F834072EF025DA46E1DBF8E432BE
+:1068D000584699780AF0A4FC3FE1B8F1010F40F363
+:1068E0003681BBF1000F00F038819BF80630BAF812
+:1068F00000505BBB3046139920F06EDB1398037E8B
+:1069000013F0020F14D002214EF09ADB139B1B7E72
+:1069100013F0080F0CD130465946224609F10A03FC
+:1069200000950194CDF808A0CDF80C800AF0D8FAB3
+:106930000E99002900F01181DBF8D8329B6813B161
+:10694000584631F003DF58460321ADE013990B6937
+:106950005B4540F00281304620F03EDB1398037E19
+:1069600013F0020F10D012214EF06ADB3046594668
+:10697000224609F10A0300950194CDF808A0CDF84C
+:106980000C800AF0ADFAAFE010214EF059DBE4E0E4
+:10699000B8F1010F40F3DB80BBF1000F01D05F467F
+:1069A00004E0109A002A00F0D880174600252C46F3
+:1069B0003319D3F84C1241B109F11000BC31062251
+:1069C000FBF3BEF2002808BF01250434202CEFD1D0
+:1069D000002D00F0C280139BBAF8004033B9304656
+:1069E00009F10A01119A4EF0E3DE1390139911B1E7
+:1069F000304620F0F1DABB791398002B57D10028EC
+:106A00003CD012214EF01CDB1398037E13F0010FD3
+:106A100003D1436813F0005F30D001214EF010DB4A
+:106A2000A4F10D039BB2092B07D83368D3F88C204F
+:106A3000D2F8F8310133C2F8F83197F91030022B4F
+:106A400003D1F8680E2152F08DDD13990B7E13F0FF
+:106A500004020ED100944B683046C3F34073019397
+:106A6000394609F10A03CDF808A0CDF80C8032F0C0
+:106A7000B7DC139A536823F0005353600E9B002B2E
+:106A80006BD09BF81230002B67D0DBF8D82253680C
+:106A9000022B02D19368082B5FD8936813B1584634
+:106AA00031F054DE5846022134F074DC55E0002801
+:106AB00053D00169B94250D1D0F8F0301BB14368CE
+:106AC00023F400734360139B1B7E13F0010F44D02B
+:106AD0000022304609F10A0300940192CDF808A083
+:106AE000CDF80C8032F07CDC304613994EF068DE35
+:106AF00033E0B8F1030F2ADDBBF1000F2DD09BF876
+:106B0000043053B39BF806303BB309F110000BF18E
+:106B1000BC010622FBF314F2F8B9139BD6F8340734
+:106B2000019359464A465346CDF8008002950AF033
+:106B300061FC12E00A99069C0291304613994A467C
+:106B40005346CDF80080019410F038DC05E033683E
+:106B5000D3F88C20136F013313670798059900222F
+:106B600000F0DED815B0BDE8F08FC0462DE9F04F3B
+:106B7000436899B0164689460493918B96F82A305B
+:106B8000126880460292D9F810A00BB9059302E072
+:106B900096F82220059296F82C00B0B911F4006FF7
+:106BA00013D0059A09EB4203B3F8AC20B6F87E3057
+:106BB0009A420AD1D8F80030D3F88C20D2F8BC31F0
+:106BC0000133C2F8BC3100F065BC9AF80630C1F35D
+:106BD000802B7BBBDAF8E442237A6BB160B9BBF15E
+:106BE000000F09D199F8D230726A134113F0010FE6
+:106BF00002D1504610F088DBD8F800305B6BCBB187
+:106C0000237EBBB196F82A30A3B196F828308BB119
+:106C10000021504621F0BEDEDAF8CC3013F4005FDC
+:106C200008D0B38B13F4005204D1D8F84C0151466C
+:106C300048F0AAD9338C13F0040440F02B84B38BB2
+:106C400003F4804373634BB9DAF8582040F23713EA
+:106C500002EA03032BB39AF8603013B3059BB463C5
+:106C60000093404604994A4633464FF051DF08B13D
+:106C700022460EE0736B23B1D9F86C310133C9F8A9
+:106C80006C31D8F8003093F89530002B00F0028476
+:106C90000122736B33B1D9F868310133C9F8683117
+:106CA00000E0002296F82C300BB1002708E005998F
+:106CB00009EB4103B6F87E10B3F8AC70A3F8AC1042
+:106CC000D8F8000090F8953013B1002A40F0E28324
+:106CD00096F82C50002D40F00081B6F87E20059BE0
+:106CE00012F00F0C4FEA830E40F081800EEB090783
+:106CF000F96E41B104982A4600F012D8FD66C7F833
+:106D00008C50C7F83051BBF1000F00F0E68073697A
+:106D1000F168FB66D8F800307269DB6903919C6802
+:106D20001169D368908ACB1892681B189B1A0918AE
+:106D30005B1AA34223DA0498214600F021D8F866B2
+:106D4000002800F0A7837369006919699C689A8A12
+:106D5000C4EB0104091BA218FBF30EF17169FA6E72
+:106D600008698B68C01A13691B181361938A1B1A70
+:106D700093828B8A049893822A46FFF3D1F7D8F83E
+:106D80000030D8F82828DB6903999B68AA489B1A29
+:106D90005B1A063BC7F88C3071680822FBF3D0F011
+:106DA00050B1A64871680622FBF3CAF048B973686F
+:106DB000DB88B3F5407F04D1D9F8043043F00803F1
+:106DC00003E0D9F8043023F00803C9F804309C48E4
+:106DD00071680822FBF3B4F0D9F8083010B943F019
+:106DE000200301E023F02003C9F8083075E00EEB22
+:106DF0000904E16E11B9D0F88C2017E022F00F02DF
+:106E000027F00F039A4204D107F00F0301339C458A
+:106E100010D02A460498FFF383F7D8F80030E566CF
+:106E2000D3F88C20C4F88C50C4F83051136E013361
+:106E300013662FE3B068D4F88C309842E9D8049BED
+:106E400009EB0E020090019340468C3273680CF0FF
+:106E5000C7D8049871692A46FFF362F7BBF1000FA7
+:106E60003BD1E36EC4F88CB07361C4F86CB0736945
+:106E7000C4F830B11A69998A02F118037360A1F15C
+:106E80001803B36096F829303260F1602BB102F13B
+:106E90001E037360A1F11E03B36096F82A3043B15C
+:106EA0007368059902337360B36886F82210023B59
+:106EB000B36032681378527843EA0223B383736B6A
+:106EC0005BB1B16B49B191F90E2073689B18736087
+:106ED00091F90E20B3689B1AB360B36B73B11B7A40
+:106EE000042B03D1404631464FF0C0DEB36B1B7A12
+:106EF0000B2B03D1404631464FF0D4DFBBF1000FDE
+:106F000040F02283D8F8003093F89530002B73D0EE
+:106F1000DAF808309B7913F0010F40F0DA826BE069
+:106F200010F4000F00F4E06310D01B0A043B012BA7
+:106F3000444A00F07F0004D8142300FB0323DA68DE
+:106F400014E0142300FB03239A680FE01B0A043BA0
+:106F5000012B3C4A00F07F0004D8142300FB0323DC
+:106F60005A6803E0142300FB03F39A584FF4FA73B2
+:106F7000B2FBF3F007E000F07F034FF4FA7203FB7B
+:106F800002F3B3FBF2F0C0F307238DF825300DF1C7
+:106F90001B05C0F307438DF824008DF82630012728
+:106FA000030E316805F10F0018228DF827308DF897
+:106FB0002970FAF3E1F796F82F30DBB19DF82B201A
+:106FC0009DF82A3005F1190443EA022343F40073C3
+:106FD0008DF82A3021461B0A062205F11F008DF884
+:106FE0002B30FAF3C9F7D8F86C122046BC310622D0
+:106FF000FAF3C2F7BB4601E04FF0000BD8F80030BF
+:1070000093F8953013B91C461A4602E00DF11B04A3
+:107010002D2273695B6A13F0400F15D013F0800FB7
+:1070200000F038820092D8F83C01494632462346A7
+:1070300029F00EDE88E2C046401E86002CD40100F6
+:10704000481E86008418860031680DF15A07043105
+:1070500006223846FAF390F7316815AD0A31062258
+:107060002846FAF389F731680DF14E0420461031B5
+:107070000622FAF381F796F829302BB1316812A86D
+:1070800018310622FAF378F7B38B13F4807F03F4F8
+:10709000007305D1002B14BF23462B46776704E00D
+:1070A00074670BB9356701E012AB33677468BBF1E5
+:1070B000000F00F0EE803368F3662378AA2B23D10B
+:1070C0006378AA2B20D1A378032B1DD1E378DBB9F9
+:1070D0002379CBB9637943B9A379E179404641EA91
+:1070E00003210BF0F1DB50B10EE0F82B0CD1A379AA
+:1070F000E179404641EA03210BF0E6DB20B1A279B9
+:10710000E37943EA022500E03589D8F8003093F8A6
+:107110009530D3B1DAF8E0305BB9736BABB9DAF81C
+:10712000582040F2371302EA030373B19AF8603033
+:107130005BB1059A40460192494652463346009556
+:107140000DF022DA002840F0A581B36B6BB11B7AF9
+:10715000012B0AD0032B08D0404604994A463346F7
+:1071600009F0DEFE002800F09581736F1B7813F0A4
+:10717000010F08D0D8F80030D3F88C20D2F8D031E5
+:107180000133C2F8D031B36B33B11B7A022B03D178
+:10719000404631464FF06ADD726B22B996F82A30CC
+:1071A00023B3144602E0B36B93F90E4096F82A30ED
+:1071B0005BB1336802341A78597842EA012222F02E
+:1071C000800292B21A70120A5A707368581E03E055
+:1071D00063421B5C00F8013971690A699042F7D279
+:1071E0008B8A12191B1B0A618B82326096F82F3032
+:1071F000BBB130684278037800F10A0443EA022305
+:1072000043F4007303701B0A4370214606221030BA
+:10721000FAF3B2F6D8F86C122046BC310622FAF323
+:10722000ABF69AF9103093B148F68E039D420ED119
+:107230003168726BDAF80C001231003A18BF012283
+:107240000AF1180351F0AEDE002840F02381716985
+:107250000A698B8A9B18CA68D21A2C2A40F21A81B2
+:1072600000238DF829308B8A08692D2218180DF11A
+:107270001B01FAF381F6716996F82220CB8A02F09D
+:10728000070223F007031A43CA8296F829200091C7
+:10729000FAE0D6F814B02378DBF81070AA2BC7EB0D
+:1072A000040529D16378AA2B26D1A378032B23D1F7
+:1072B000E3780BBB2379FBB9637943B9A379E1790F
+:1072C000404641EA03210BF0FFDA50B114E0F82BFD
+:1072D00012D1A379E179404641EA03210BF0F4DAB7
+:1072E00050B17269A91F7B18CBF81030938A5B1AD2
+:1072F00093821369F36628E0DAF8583013F0200F10
+:107300000FD0204692490822FAF31AF648B972695A
+:10731000281D1169938A09181B1A11619382F1665D
+:1073200013E07269A5F10E00938A11691B1A93820A
+:1073300033890918116103F0FF021B0A43EA022393
+:10734000F1660B73C3F30F234B73B36B6BB11B7AF3
+:10735000012B0AD0032B08D0404604994A463346F5
+:1073600009F0DEFD002800F09580B36B33B11B7A85
+:10737000022B03D1404631464FF078DC0622716F74
+:10738000F06EFAF3F9F5F06E06220630316FFAF37B
+:10739000F3F5716996F82220CB8A02F0070223F0F8
+:1073A00007031A43736FCA821B7813F0010F08D0CA
+:1073B000D8F80030D3F88C20D2F8D0310133C2F89D
+:1073C000D0319AF8613093B199F8183013F0100F5A
+:1073D0000DD1F36E1A7B5B7B43EA022348F68E02E3
+:1073E000934204D073695B6A13F0100F52D09AF87D
+:1073F0006530BBB199F8183013F0100F12D1F36E4D
+:107400001A7B5B7B43EA022248F6B4039A4209D016
+:10741000263B9A4206D073695B6A002B02DB13F0AD
+:10742000100F37D09AF8063023B9DAF8E422013386
+:1074300082F82A3098F83238013388F832389AF9CD
+:107440001030EBB1F16E0B7B4A7B42EA032248F627
+:107450008E039A4214D10B8A03F0FF021B0A43EAFF
+:107460000223B2680C3A934214D8726BDAF80C001B
+:10747000003A18BF01220AF1180351F093DD48B910
+:10748000736996F82920009340464946736F1FF0B0
+:107490007BD959E0D8F80000436BA3B171692D4A3C
+:1074A000CB8AD0F8904003F00703D25C2A4B0498B3
+:1074B0009B5C04EBC304636EA56E01336366FBF350
+:1074C000A9F64019A066049871690022FFF328F418
+:1074D0003AE0D8F8303005991A8940468DF81B20DB
+:1074E000130A120E8DF81C308DF81E200023B2698D
+:1074F0008DF81D30937DD27D43EA0223C3F3C70389
+:107500008DF81F3009EB410393F8AC30D6F88010AA
+:1075100003F00F0301338DF828301CF03DDA029A96
+:1075200040B2030E8DF82000911FD6F880008DF830
+:1075300021308DF822308DF8233015F039FE10F00F
+:10754000006F7FF4EDAC16E519B0BDE8F08FC046D2
+:10755000F7E38500C4D2850098E085002DE9F04F5F
+:107560000024A7B08DF832408DF83B408DF83840AC
+:107570008DF870408DF83F409A4609939B8A0546E6
+:10758000212B02911746259412940D940A9224926D
+:107590001B9450D9DAF810901046494615F008FEB1
+:1075A00009F1060203900492527899F8063043EAF2
+:1075B0000223ADF82C30C3F38103ADF82E30BDF8B3
+:1075C0002C30C3F3031203F44073B3F5407F14BFB0
+:1075D000002301238DF83930BDF82E30ADF830206E
+:1075E000022B0ABFBDF830302346C3F3C0038DF829
+:1075F0003A303B7903F00303022B08D1BDF92C305C
+:10760000002B04DABDF83030C3F3C00300E00023E0
+:10761000D9B29DF839009DF83A308DF83B1000281A
+:107620000CBF2222282203B1023201B10432099B8D
+:107630009B8A934206D22B68D3F88C20536E013379
+:107640005366A5E304990B7903F001038DF83C30F0
+:1076500020B100231E468DF8403015E0BDF82C30D7
+:1076600013F4807F01D0043105E013F4007F01D0D2
+:107670000A3100E01031284637F02CDE031E18BF17
+:10768000012306468DF840309DF83C303BB9049903
+:107690002846043137F042DE08B1012400E000241E
+:1076A00095F8C83123B92B6893F82C3033B92FE003
+:1076B00028463946099A00230EF0A2DB2B6893F87E
+:1076C0003F300BB98DF8403054BBBDF82C3013F46B
+:1076D000807F05D19DF83C3013B19DF840303BBB15
+:1076E0009DF8393013B19DF83C300BBB2B6893F8F3
+:1076F0002C30002B00F04C839DF84030002B00F024
+:107700004783B379002B40F043834FF0010B11E026
+:107710009DF83C301BB9002C00F03A8300E03CB1EE
+:107720009DF8393023B99DF84030002B00F03083AC
+:107730004FF0000B2B6893F895304BB346B39DF890
+:107740003C30D6F8DC405BB914F0010F00F0208328
+:10775000049806F1C20104300622FAF3F1F314E0B2
+:1077600004980430FBF3E8F020B114F0080F00F0A7
+:107770000F830DE014F0040F0AD114F0020F00F093
+:107780000783284604990EF0A7DA002840F000830A
+:10779000099A136906331361938A063B9382049A0C
+:1077A00002F1180305939DF8393013B102F11E035D
+:1077B000059300238DF83D309DF83A306BB3059B5F
+:1077C0005A781B7843EA0221C1F3C0138DF83D308B
+:1077D0007BB126B196F81935002B40F0D98295F887
+:1077E000CF31002B00F0D482099A536A43F0400352
+:1077F0005362844B01F007028DF832209A5C824B71
+:107800009B5C0D93C1F300138DF83830059B023358
+:1078100005939DF832308DF870309DF83D3023B9D6
+:10782000099A938A043B938206E002980999FBF334
+:1078300069F1838A043B8382099A059C938A1269C1
+:107840000793A41A1B1B514602980693FBF3E2F41C
+:107850000499001B08908B7DCA7D43EA0223ADF892
+:107860008E30BBF1000F2ED1079B284600933A467D
+:1078700025AB10F03DDE002840F08A82BDF82C30A8
+:1078800013F4407F3BD1BA7DFB7D049942EA032289
+:10789000C2F3C70228460A310E2AD4BF00220122B1
+:1078A0004EF0A0D8259030B92B68D3F88C20D36E39
+:1078B0000133D3666CE20369D3F8CC30C3F3C01351
+:1078C0008DF83F301BE0BDF82C3013F4407F16D00C
+:1078D0009DF839309BB9259B8BB9BA7DFB7D284635
+:1078E00042EA0322C2F3C7020A310E2AD4BF0022A1
+:1078F00001224EF077D82590002800F04982259B80
+:107900001C69D4F8DC82BBF1000F23D19DF839301B
+:1079100003BB9DF83C3023B1BDF82C3013F4807FBD
+:1079200011D1A379BDF82C201BB112F4807F0AD0AD
+:1079300010E0A37C02F44072002B14BF4FF40073DC
+:1079400000239A4206D02B68D3F88C20936D013324
+:1079500093651DE295F82D370AF1240A33B99DF895
+:107960003F1019B9A3790BB10E4608E028463946F5
+:107970001CF012D8C0B246B208B18AF80900A37947
+:10798000FBB99DF83F30E3B9314620461CF046D89C
+:1079900020461BF09BDF3946284610F091D801465F
+:1079A00020460EF0F3DF9DF8403053B1A37C43B185
+:1079B000E37933B198F805301BB92046012133F043
+:1079C000E9DC95F82D3733B99DF83F301BB9259B7D
+:1079D000D3F8FC3073B16EB1259AD2F8F810D2F812
+:1079E000F43043F82160D2F8F830013303F0070394
+:1079F000C2F8F8309DF8393043B1B4F86200ADF800
+:107A0000780040E0C4D2850098E08500A3792599EC
+:107A1000002B35D08A8FADF878204A6812F0400FDD
+:107A200020D09DF83A30EBB1049B9B7D13F00F0FF3
+:107A300018D191F8DF30ABB18B7E13F0010F11D16B
+:107A4000BDF82C3013F4805F0CD012F4003F09D045
+:107A50000D9A91F8D130134113F0010F02D028464E
+:107A60002DF034DFBDF82C30259913F4805F15BF5D
+:107A70004B684B6843F4003323F400334B6002E05F
+:107A8000898FADF8781095F82D371BB9259BD3F861
+:107A9000FC3073B16EB1259AD2F8F810D2F8F430F8
+:107AA00043F82160D2F8F830013303F00703C2F83D
+:107AB000F830259BD3F87C1159B1D1F808360398DA
+:107AC00001EB8302013303F03F03C2F80C06C1F857
+:107AD0000836A3795BB9A37C4BB19DF83C3033B930
+:107AE000BBF1000F03D188F806B088F807B09DF805
+:107AF0003C30FBB1A379002B40F04A81A37C4BB111
+:107B0000296804984E3110300622FAF319F2002841
+:107B100000F03E8104980430FAF30EF750B92B6858
+:107B200093F83E3033B9284604990EF0D5D8002892
+:107B300040F02E81039ACAF814209DF83C308BB98E
+:107B400099F8022099F80130134399F800201A435C
+:107B500008D0BB7CFA7CD5F86001039943EA022285
+:107B60004BF022DADAF8142012F0006F26D012F46B
+:107B7000000F02F4E06310D01B0A043B012B96486F
+:107B800002F07F0204D8142302FB0303DA6817E033
+:107B9000142302FB03039A6812E01B0A043B012B27
+:107BA0008D4802F07F0204D8142302FB03035A68B5
+:107BB00006E0142302FB03F31A5801E002F07F02EF
+:107BC000864B1A6099F90330002B07DA2B68D3F83B
+:107BD0008C20D2F8D8320133C2F8D83299F8033069
+:107BE00003F03003102B07D12B68D3F88C20D2F888
+:107BF000E0320133C2F8E0329DF83C30002B40F017
+:107C00009780DAF814102B6811F0006FD3F88C20ED
+:107C100026D011F4000F01F4E06310D01B0A043BDE
+:107C2000012B6D4801F07F0104D8142301FB0303ED
+:107C3000D96817E0142301FB0303996812E01B0ABB
+:107C4000043B012B644801F07F0104D8142301FB9D
+:107C50000303596806E0142301FB03F3195801E0FC
+:107C600001F07F0116293AD00CD80B2925D004D871
+:107C7000022916D004291AD05AE00C2923D012293F
+:107C800027D055E030293CD004D818292DD02429FC
+:107C900031D04DE0602940D06C2944D0482936D0FD
+:107CA00046E0D2F870320133C2F8703240E0D2F8C8
+:107CB00074320133C2F874323AE0D2F878320133C8
+:107CC000C2F8783234E0D2F87C320133C2F87C3228
+:107CD0002EE0D2F880320133C2F8803228E0D2F8A8
+:107CE00084320133C2F8843222E0D2F88832013380
+:107CF000C2F888321CE0D2F88C320133C2F88C32E0
+:107D000016E0D2F890320133C2F8903210E0D2F887
+:107D100094320133C2F894320AE0D2F89832013337
+:107D2000C2F8983204E0D2F89C320133C2F89C3297
+:107D300025994B6813F4802F0BD09DF83C3043B944
+:107D4000BBF1000F05D1D5F8400104AA27F098DB5C
+:107D500003E0284604AAFEF709FF049B1B7C13F0EE
+:107D6000010F05D1259AD2F858310133C2F85831A4
+:107D7000049B1B7C13F0010F05D0259AD2F85C31CF
+:107D80000133C2F85C31259B0398C3F864011FE0FE
+:107D90002868436BBBB19DF83C30A3B90999104AE0
+:107DA000CB8AD0F8904003F00703D25C0D4B0298C9
+:107DB0009B5C04EBC304636EA56E01336366FBF347
+:107DC00029F24019A066029809990022FEF3A8F74B
+:107DD00027B0BDE8F08FC04684188600CC2702008B
+:107DE000C4D2850098E085002DE9F04FADF50F7DF8
+:107DF000DDF860B28A46594617469946064637F07E
+:107E0000F9DAD0F8D412D0F8D822D0F8DC32D0F891
+:107E1000E4428046089109920A930B94BBF1000F4B
+:107E200001D1D0F808B000238DF837328B9330465B
+:107E300051463A464B46FBF7CFF9041EC2F2338057
+:107E400033685B7EEBB9326992F8EA305BB1D36E8E
+:107E5000D3F8202140F2044302EA0303B3F5806023
+:107E600018BF012005E0106E07F0EEFC003818BFC7
+:107E7000012030B1B068FBF767F94FF0FF3402F032
+:107E800012B847B1B9F1030F05D98CA839460422BD
+:107E9000FAF372F001E000238C93BAF1A30F8C9DEA
+:107EA000F168706827D00DDCBAF11C0F07DCBAF15D
+:107EB0001B0F20DAAAF10203012B15D81BE0BAF13F
+:107EC000340F10E040F20B139A4514D005DCBAF1E0
+:107ED000D60F10D0BAF1FB0F05E0BAF58B7F0AD0B0
+:107EE00040F21B139A4506D0002F01F09587B9F197
+:107EF000000F41F3918740F23B132A1E18BF012265
+:107F00009A4501F2618701A454F82AF0098400001F
+:107F1000138400001D8400008F840000C99D0000B0
+:107F2000C99D0000C99D0000C99D0000C99D0000B9
+:107F3000E7840000F5840000C99D0000558500001D
+:107F4000C99D0000CF850000C99D0000C99D0000AB
+:107F5000C99D0000C99D0000DB850000E785000089
+:107F60000786000023860000558600007986000001
+:107F7000AB86000019870000979C0000899C0000D8
+:107F8000D987000019880000D7890000E389000024
+:107F9000438A00004F8A0000F38A0000FF8A000035
+:107FA000158B0000218B0000638B0000C99D000031
+:107FB000C99D0000C99D0000C99D0000858B00007F
+:107FC000418C0000478D0000FB8C0000C99D000023
+:107FD000C99D0000538D0000958D0000C78D0000E5
+:107FE000F38D00008F8E0000DD8E00002D8F0000CD
+:107FF000758F0000B38F0000BF8F0000979C0000BA
+:10800000F188000001890000418900007B8900009F
+:10801000C99D0000C99D0000C98F0000D58F0000D8
+:10802000EB8F000019900000C7900000F79000004F
+:10803000C99D0000979C0000199200004592000025
+:108040005D9200008D920000A3920000C99D000087
+:108050006F8B00007B8B0000CD9900000384000033
+:10806000E7920000F3920000C99D0000C99D000046
+:10807000C99D0000C99D0000C99D0000979C00009B
+:10808000979C0000979C0000979C0000C99D0000F1
+:10809000C99D000049930000C99D0000C99D0000D2
+:1080A000C99D0000C99D0000C99D0000C99D000038
+:1080B0007D90000089900000118500001D85000062
+:1080C000BD970000CF9700007D97000087970000C4
+:1080D000A789000093900000C99D0000C99D000081
+:1080E000D793000057930000E5930000F993000038
+:1080F0008794000087940000C99D0000C99D00007E
+:10810000239500004395000059950000C99D00008B
+:10811000C99D0000C99D0000C99D0000C99D0000C7
+:10812000FD95000011960000979C00004596000008
+:10813000C5950000C99D0000C99D0000B1960000D2
+:10814000BF960000D39600000D9400001D9700001C
+:108150002797000031970000C99D0000C99D0000CD
+:10816000E79700001598000023980000C99D0000C3
+:10817000C99D0000C99D0000C99D0000C99D000067
+:10818000C99D0000C99D0000C99D0000B584000084
+:10819000C1840000A98400006984000025960000C5
+:1081A00031960000C99D0000C99D0000979C000009
+:1081B000979C0000979C0000039900003D980000E8
+:1081C000C99D0000C99D0000C99D0000C99D000017
+:1081D000C99D0000F397000001980000DD960000A3
+:1081E000C99D0000C99D0000578C0000C99D00007A
+:1081F000C99D0000C99D0000C99D0000C99D0000E7
+:10820000C99D0000C99D0000C99D00005399000050
+:108210005D990000979C0000979C0000C99D00009C
+:10822000C99D0000C99D0000C99D0000C99D0000B6
+:1082300013940000C99D0000C99D0000C99D000065
+:108240002799000045990000C99D0000C99D0000C4
+:10825000C99D0000C99D0000979C0000979C0000EC
+:10826000EB990000F5990000C99D0000C99D000030
+:10827000019A00007D9A0000879A0000978800000C
+:10828000A3880000979A0000AB9A0000199E000096
+:10829000199E0000938A0000A18A0000C18A000094
+:1082A000CF8A0000C99D0000C99D0000BD9A000052
+:1082B000C99D0000C99D0000C59A0000ED9A00000C
+:1082C000C99D0000C99D0000C99D0000C99D000016
+:1082D000C99D0000C99D0000C99D0000C99D000006
+:1082E000C99D0000C99D0000C99D0000C99D0000F6
+:1082F000C99D0000339B0000C99D0000C99D00007E
+:10830000C99D0000C99D0000C99D0000739C00002C
+:10831000C99D0000C99D0000C99D0000699A000028
+:10832000739A0000FD830000FD830000C99D0000DA
+:10833000C99D0000C99D0000C99D00008D9B0000E3
+:10834000C99D0000C99D0000C99D0000C99D000095
+:10835000C99D0000B19B0000B19B0000C99D0000B9
+:10836000C99D000065910000D1910000DD910000E1
+:10837000E7910000F99100000B920000C99D0000F8
+:10838000DB9B0000EB9B0000F99B0000C99D0000F7
+:10839000C99D0000C99D0000C99D0000C99D000045
+:1083A000C99D0000C99D0000C99D0000C99D000035
+:1083B000C99D0000C99D0000C99D0000C99D000025
+:1083C0004F9C0000619C0000279C0000C99D00009C
+:1083D000C99D0000C99D0000C99D0000C99D000005
+:1083E000C99D0000C99D0000979C0000979C00005B
+:1083F0008D9D0000A19D0000B59D0000002101F0B1
+:108400009EBB002401F0B9BAC14B00243B6001F0CF
+:108410004ABD012300243B6001F045BD33685B7E0B
+:10842000002B41F0F38486F89F3186F8A231304664
+:1084300009F06AF830460EF04BDD30460EF036DEBD
+:108440003268137E002B41F0DF84136F13F0030FAB
+:1084500041F01D8513F0040F41F0D68413F0080F8E
+:1084600001F0DD8401F0D0BC33685D7E002D41F069
+:10847000CD84012486F8A241304609F045F886F8FB
+:108480009F41304608F072FC2C4601F00CBD0123E0
+:1084900086F89F3133685C7E002C41F0B584B0686B
+:1084A000FAF752FE01F0FFBC336800241B7E3B60EC
+:1084B00001F0F9BC96F8293000243B6001F0F3BCD0
+:1084C00031680B7E002B41F0CB844C7E002C41F0B8
+:1084D000DE8411463069079235F06AD9079A86F82A
+:1084E000292001F0E0BC3368002493F82C303B6075
+:1084F00001F0D9BC336883F82C2096F82930002B82
+:1085000001F0828430461BF0EBDA002401F0CBBC92
+:1085100096F8C83100243B6001F0C5BC86F8C8213C
+:1085200086F8CB21304608F0EFFF96F82930002B73
+:1085300001F06A8430461BF099DA30461BF0D0DA3D
+:10854000B0688C9907F0C4DD304620F0CBDF002402
+:1085500001F0A9BC40461AF083D810F0006F2AD071
+:1085600010F4000F00F4E06310D01B0A043B012B51
+:10857000684900F07F0004D8142300FB0313DA6875
+:1085800014E0142300FB03139A680FE01B0A043B5A
+:10859000012B604900F07F0004D8142300FB031373
+:1085A0005A6803E0142300FB03F35A584FF4FA739C
+:1085B000B2FBF3F007E000F07F034FF4FA7203FB25
+:1085C00002F3B3FBF2F00024386001F06CBC3368B6
+:1085D00000245B683B6001F066BC98F81230002410
+:1085E0003B6001F060BC98F8063013B1002D01F03B
+:1085F0002284D6F840252B1E18BF0123002482F8C0
+:10860000343001F050BCB8F95E300BB1022004E008
+:10861000B8F95C30181E18BF01200024386001F042
+:1086200042BC022D0AD14FF000014FF0010200249C
+:10863000A8F85C10A8F85E2001F035BC2B1E18BF0E
+:108640000123A8F85C3000244FF00003A8F85E3046
+:1086500001F029BCB8F80630002B01F0E983B9F12C
+:10866000050F41F3F483384608F1BC010622F9F303
+:1086700083F4002401F017BC98F80440002C41F06A
+:10868000EF83B9F1050F41F3E28308F1BC003946ED
+:108690000622F9F371F496F82930002B01F0B48327
+:1086A000404620F09DD901F0FEBBB9F1230F41F304
+:1086B000CE83384600212422F9F3C2F498F80650FC
+:1086C0005DB198F8192008F11A0147F8042B3846D3
+:1086D000F9F352F4002401F0E6BB98F80740381D86
+:1086E00054B1089C237A04F109013B60227AF9F322
+:1086F00043F42C4601F0D7BBD6F84025137A02F19B
+:1087000009013B60127AF9F337F401F0CCBBC046A3
+:10871000776CE41484188600B9F1030F41F3978352
+:108720003A68131D9945C1F29283202A03D96FF04C
+:10873000110401F062BB07F1040A3046514636F0DD
+:1087400011DE10B1404541F06A8398F806309BB1C4
+:10875000404651463A6836F00FDA3046414636F028
+:108760008FDB98F819303BB13046414636F03CDD9E
+:108770000446002841F0418398F80630002B41F070
+:108780004383B9F1310F02D819461A4619E07A8DA0
+:1087900022B1FB6A13B90125FA6200E000253046D8
+:1087A00007F12C01A9F12C020AF034DC04460DB1CA
+:1087B0000023FB62002C41F0208307F12402A9F181
+:1087C00024013B683046009201915246414631F007
+:1087D000CFD8002401F067BB336B18690AF0A6F903
+:1087E000C0B2386098F807301BB1089991F8323060
+:1087F00003E0D6F8403593F832300024D6F868010B
+:108800007B60BC608379002B01F0FE824BF09CDF23
+:10881000C0B2B86001F047BB0E2DCCBF4FF4805200
+:108820004FF40052E02D03D96FF0120401F0E5BAC5
+:1088300045F4306342EA03039DB2D6F85C01294651
+:108840003DF0ACDD18B96FF0130401F0D6BAD6F8DC
+:10885000403532685D86137E002B01F0D58292F898
+:108860003F40002C41F0D082336B18690AF05EF96A
+:10887000A84201F0C9822946304620F091DA3046FC
+:1088800008F0B0FF3046294620F0D0D8304619F025
+:10889000B7DB01F008BB96F8683700243B6001F0B5
+:1088A00002BB642D01F2BE8286F8685730699DF8DC
+:1088B000301235F021D833681B7E002B01F0A482E2
+:1088C000D6F868319D79002D41F09E82304608F03F
+:1088D00089FF3046D6F85C410DF066D80146204647
+:1088E0003CF042DF304619F08BDB2C4601F0DBBA5E
+:1088F000D6F86036002493F907303B6001F0D3BA14
+:10890000304669B211F024D9041EC1F276828C9BE4
+:10891000D6F86026D37133681B7E002B01F06B8282
+:10892000304608F05FFF304611F054D93046D6F893
+:10893000AC1614F005D8304619F062DB01F05BBAD2
+:108940003368187E30B9D6F8603604469B793B60B0
+:1089500001F0A9BA336B89A918690AF065FA0446CF
+:1089600028B19DF8243200243B6001F09CBAD6F86F
+:1089700060369B793B6001F096BA6B1C042B01F2C8
+:108980005182B5F1FF3F01D103238C93D6F86036B5
+:108990008C9A00249A71336B9DF8301218690AF092
+:1089A00081FE01F080BA33681B7E002B01F0498202
+:1089B000B1F8E8339AB24DF6AD639A4201F02F82D6
+:1089C0004FF6FF739A4201F02A82C2F3401300244B
+:1089D0003B6001F068BAB6F83A3600243B6001F01B
+:1089E00062BA6B1EFE2B01F21D82A9B2A6F83A16DE
+:1089F0003069B6F83C2634F029DEB6F82032B6F8F5
+:108A00003A2623F00F031343A6F82032B6F8223299
+:108A1000304623F00F031343A6F82232B6F824326F
+:108A2000002423F00F031343A6F82432B6F82632AD
+:108A300023F00F031343A6F8263212F053D801F0A7
+:108A400032BAB6F83C3600243B6001F02CBA6B1EFB
+:108A5000FE2B01F2E781AAB2B6F83A16A6F83C2638
+:108A6000306934F0F3DD3146B1F82022B6F83C36F7
+:108A700022F4706242EA0322A1F8202206F10803E0
+:108A800002319942F0D1304612F02CD8002401F086
+:108A90000ABA336B0024B3F806313B6001F003BA25
+:108AA00096F82930002B01F0C9816B1EFE2B01F2D4
+:108AB000B9813046A9B220F023D8002401F0F3B9DF
+:108AC000336B0024B3F808313B6001F0ECB996F841
+:108AD0002930002B01F0B281A5F1FF03B3F5E06F5F
+:108AE00001F2A0813046A9B21FF0FEDF002401F0A0
+:108AF000DAB996F95C3600243B6001F0D4B96B1CFE
+:108B0000012B02D9012D41F08D81002486F85C569D
+:108B100001F0C9B9336800241B6F3B6001F0C3B991
+:108B20002A0C01F07F8122F00303002B41F07A81AF
+:108B3000A9B221F00303002B41F07481D04310EA65
+:108B4000010441F06F813268136F00EA03030B43A5
+:108B5000304613670EF0BCD930460EF0A7DA01F0AC
+:108B6000A2B9336B00241B893B6001F09CB998F8D3
+:108B7000603000243B6001F096B9002488F8602042
+:108B800001F091B9832D01F2508106EB8503B9F113
+:108B9000A30FD3F8804241F35A8145AD2846002106
+:108BA000A422F9F34DF2002C42D0E37947A82B60C0
+:108BB000226904F114016A60F9F3DEF1237A61930A
+:108BC00096F8A0349BB9D8F8583013F0080F0ED19E
+:108BD000237A0B2B08D196F8F03743B196F8F1378A
+:108BE0002BB1A379072B02D8A379292B03D9629B38
+:108BF00043F001036293638913F0020F03D0629B79
+:108C000043F002036293638913F0200F03D0629B49
+:108C100043F010036293638913F0100F03D0629B3B
+:108C200043F0200362936CA821460622F9F3A4F1D5
+:108C3000384645A9A422F9F39FF1002401F033B985
+:108C4000A549012330460097CDF804900293CDF852
+:108C50000CB000F096BFB9F1070F41F3F880304631
+:108C600036F08EDD80450BD08C9B032B01F2DD802E
+:108C700008EB83035B6F002B01F0D7809B798C930B
+:108C80008C9B832B01F2D18006EB8303D3F88042C7
+:108C9000002C01F0CA802369002B01F0C680B8F8CF
+:108CA000623013F0010F08D02046F9F355F620B1D9
+:108CB000B8F86C30D8F8680003E0B4F8B830D4F8ED
+:108CC000B4008DF818321B0A8DF81932030A8DF89A
+:108CD0001B32030C00248DF81A028DF81C3286A971
+:108CE000030E082238468DF81D328DF81E428DF88D
+:108CF0001F42F9F341F101F0D6B8336893F83F30E1
+:108D0000002B41F0B380D6F86801837923B10421A8
+:108D100007924BF04DDC079A96F8723286F850278E
+:108D200086F85925002B41F06F80D6F85C011AB106
+:108D300006F5AA610E3102E006F5AA610A313DF09E
+:108D400011DA01F057B896F8503700243B6001F073
+:108D5000AAB80325304639464A4600230095CDF887
+:108D600004800BF0BBD8044638B110F1190F01F0A4
+:108D70004480C6F8245501F040B80223C6F82435D3
+:108D800096F8F437C6F8285523F0010386F8F4372F
+:108D900001F089B8B9F10B0F41F23E803B680B2B13
+:108DA000899341F239804B45C8BFCDF82492899B05
+:108DB00030460C3B8993394689AAD6F8243510F001
+:108DC000EDDB01F017B896F829303BB933681B6F1B
+:108DD00013F0040F01F0328001F016B898F8064045
+:108DE000002C41F028803046414636F049D801F049
+:108DF0005AB833681B7E002B01F02380B9F1050FB0
+:108E000041F22580B9F10D0F0CD9304607F1080168
+:108E1000A9F108020AF0FED83D460446002840F0B9
+:108E2000EC870AE082AC204639460622F9F3A4F02A
+:108E3000002384934FF00E09254698F80640CCB9DC
+:108E40000A9AD2F8901039B1706892F89420FDF324
+:108E50004FF70A9BC3F890400A9C494684F89490C7
+:108E60007068FDF335F7C4F8900018B129464A46FA
+:108E7000F9F382F02946404632F028D90A9904468F
+:108E8000D1F89030002B40F0BF8700F0B4BF002332
+:108E90000093304639464A468BABFAF7F5F904465B
+:108EA000002840F0AA878B99032900F0ED87326BE8
+:108EB0001368994204D1D2F8F0303B6000F0F3BF60
+:108EC0005368002B14BF38233C23F358D3F8F030F9
+:108ED0003B6000F0E8BFC0467B7286000023009331
+:108EE000304639464A468BABFAF7CEF9044600289D
+:108EF00040F083878C9A02F16403672B00F292871B
+:108F00008B99032904D0336B1B68994240F0CB87BF
+:108F1000002A04DB3046316B32F01CDA0246336B38
+:108F2000C3F8FC20C3F8F02000F0BDBF002300937D
+:108F3000304639464A468BABFAF7A6F90446002874
+:108F400040F05B878B99032900F09E87326B136892
+:108F5000994204D1D2F8F4303B6000F0A4BF5368CA
+:108F6000002B14BF38233C23F358D3F8F4303B6074
+:108F700000F099BF00230093304639464A468BAB38
+:108F8000FAF782F90446002840F037878C9A642A61
+:108F900000F27A878B99032904D0336B1B689942BE
+:108FA00040F08187336BC3F80021C3F8F42000F050
+:108FB0007ABF0A9A0024D36A3B6000F074BF0A9B10
+:108FC0000024DD6200F06FBF98F83A3000243B6067
+:108FD00000F069BFBB49012330460097CDF80490EB
+:108FE0000293CDF80CB000F0CCBDD8F84C2006248C
+:108FF000531C03FB04F39945C0F2298747F8042B5F
+:10900000D8F84C20384602FB04F2D8F85410F8F394
+:10901000B3F7002400F047BF3B68402B00F2028703
+:10902000062403FB04F304339945C0F21087D8F8F3
+:10903000541049B1D8F84C2002FB04F20432FDF37D
+:1090400057F60023C8F84C303968706801FB04F10A
+:109050000431FDF33DF6C8F8540018B96FF01A0456
+:1090600000F0CBBE57F8042BC8F84C20394602FB61
+:1090700004F2F8F381F7002400F015BFD8F850305F
+:1090800000243B6000F00FBF0024C8F8505000F0EF
+:109090000ABF98F807301BB1089C04F1380203E0BE
+:1090A000D6F8403503F1380211680B1D9945C0F21E
+:1090B000CE8647F8041B3846111D1268F8F35CF79A
+:1090C000002400F0F0BE78AC282200212046F8F3FE
+:1090D000B7F73046214614F0A9DC789A131D99455C
+:1090E000C0F2B58647F8042B211D3846F8F344F743
+:1090F000002400F0D8BE3A68131D9945C0F2A78637
+:10910000102A00F2AA8678AC002128222046F8F323
+:1091100097F757F8042B201D39467892F8F32CF76F
+:10912000336893F8463013F0030F0ED098F80730E9
+:1091300004F115001BB1089A02F14D0102E0D6F8C6
+:1091400040154D311022F8F317F7304678A910F08A
+:109150008BDC0446002840F0508630460DF04AD89B
+:1091600000F0A1BE6DB100243046414623222346C3
+:109170000094019402940394049413F0CFDC00F063
+:1091800092BE98F806303BB9D6F8680104214BF03E
+:109190000FDA40462FF0DADAD6F878122B467068EC
+:1091A000043101220095F9F34DF698F8063043B9E1
+:1091B000404601212A462B4602F0ACFF2C4600F027
+:1091C00072BE3046414635F05BDE2C4600F06BBE89
+:1091D000D6F84C3500243B6000F065BE0024C6F88C
+:1091E0004C5500F060BE384606F5AA610622F8F339
+:1091F000C3F6002400F057BE06F5AA6039460622E1
+:10920000F8F3BAF6002400F04EBE304641460AF0AC
+:1092100089DF002400F047BE98F8060058B998F896
+:10922000123043B198F807302BB1089CE38D044607
+:109230003B6000F038BED6F840350024DB8D3B6043
+:1092400000F031BE6A1E4FF6FE739A4200F2EA85C4
+:10925000D6F840350024DD8500F025BE98F80600DC
+:1092600060B998F812304BB198F8073033B10899CB
+:10927000044691F860303B6000F015BED6F84035EA
+:10928000002493F860303B6000F00DBE6B1EFE2B97
+:1092900000F2C885D6F84035002483F8605000F00D
+:1092A00002BE3A6845F2AB539A420FD106490023F9
+:1092B00030463B600097CDF804900293CDF80CB097
+:1092C0000DE0C046AB728600DD7286000023A04927
+:1092D0000097CDF804900293CDF80CB030463A4692
+:1092E0004B4600F050BC0B9A002413783B6000F012
+:1092F000DABD022D00F293850B9B1D7033681B7E37
+:109300004BB140460DF062DCD8F8E4325B8B13B110
+:1093100040461BF043D90B9C637E0BB18C9B33B949
+:109320008C994046003918BF012107F079FF40466B
+:109330001CF05CDB0146404622F000DC404631F088
+:10934000B7DF002400F0AFBD304639464A46FAF791
+:1093500079F800F04FBD316891F830300F7E1BB1C5
+:1093600015B96FF0190400E0002491F8953013B19D
+:10937000002D40F08F85002C40F03F8591F82F3074
+:10938000934200F0908527B1B0680792F9F7DCFEB0
+:10939000079A3368304683F82F20414636F0F8D9D3
+:1093A000326892F8443023B192F82F300BB182F832
+:1093B0004440304612F004DD002386F8DD3186F8A3
+:1093C000DE311FB1B068F9F7D7FE0446304608F029
+:1093D0009BF800F010BD3368002493F82F303B60F9
+:1093E00000F061BD5B49002230460097CDF8049043
+:1093F0000292CDF80CB0C5E35649012330460097E0
+:10940000CDF804900293CDF80CB0BAE304238C930A
+:1094100004E0B9F10B0F40F31A85043798F80630D1
+:10942000002B30D13B78304613F0010F39463D46D2
+:1094300018BF08F1BC054CF0B1D9044628B1436807
+:1094400013F4805F01D04BF02FDF98F81230002B1F
+:1094500000F0DA84002140460A460B4602F05AFE2C
+:1094600054B1BDF830323046019329462A4608F1FE
+:10947000C20300941EF086DD3046414635F000DD23
+:10948000002400F010BDAAF179033846DDF83092CF
+:10949000012B8CBF01251025F9F34EF2BAF1790F9B
+:1094A00014BF4FF0000B4FF0010B044638B3D6F851
+:1094B00000058AA94BF00EDE19E0D2F8F030B3B9FE
+:1094C0001369434513D1102D03D1137E13F0020FFE
+:1094D00004E0012D03D1137E13F0010F07D03046B5
+:1094E00041465B460095CDF804904BF00BDF8AA80F
+:1094F0004BF0F8DD02460028DFD100F085BC304695
+:1095000039464CF04BD90246002800F07D843046A5
+:1095100041465B460095CDF804904BF0F3DE00F039
+:10952000C2BC98F8070028B1089900240B8E3B6054
+:1095300000F0B9BCD6F8403504461B8E3B6000F005
+:10954000B2BCD6F8403500241D8600F0ACBCC04645
+:10955000E3728600E8728600002F00F05D84B9F1A6
+:109560000C0F1FD13B79391D13F0010440F05484D6
+:1095700030464CF013D938B1012386F82D374BF023
+:10958000A3DE386000F08FBC98F8060018B16FF0C9
+:109590001D0400F032BCD8F8E03204461B693B6081
+:1095A00000F081BCB9F1040F40F0368498F8060051
+:1095B000002840F03184D8F8E03204461B693B6053
+:1095C00000F071BC304620F0B9D93368D3F88C0074
+:1095D000036C3B60836C7B60D0F8D831BB60D0F803
+:1095E000B03102699B18B9F1130FFB6040F30C8492
+:1095F000D0F83C3100243B6100F055BC9D4900226D
+:1096000030460097CDF804900292CDF80CB0B9E244
+:109610009849012330460097CDF804900293CDF885
+:109620000CB0AEE2B8F8623000243B6000F03BBC06
+:109630009149012330460097CDF804900293CDF86C
+:109640000CB09EE2832D40F30284336B3D1D1869FC
+:1096500009F0FCFB089A4FF0000982F861008C9B2E
+:109660003046043B08992A46CDF8009009F0EEDD1B
+:10967000AB6F84333B6098F80630002B00F0C48356
+:1096800007F11704204649462022F8F3D9F498F848
+:1096900019202046AA7408F11A01F8F36DF407F1B5
+:1096A0000C0008F1BC010622F8F366F44C46FAE31C
+:1096B00001233B60336B00241B687B60F3E396F867
+:1096C0009C310BB9184601E0336B186800243860F0
+:1096D000E9E33046294612F053DC8BE3B9F1020F7F
+:1096E00040F3B583336B188968B1022801D1653026
+:1096F0000FE0052801D167300BE0042801D16A3062
+:1097000007E0072801D1613003E0082814BF3F209B
+:10971000632000231C4638707B70C4E396F8433600
+:1097200000243B60BFE396F9473600243B60BAE370
+:109730006B1C012B02D9012D40F07483EAB2316811
+:1097400086F84726087E48B191F83F40002C40F04B
+:109750005B833046214620F0A9DDA4E351B2B1F18C
+:10976000FF3F03D1044686F843069CE3012914BF5A
+:1097700000230123044686F8433694E396F84836DE
+:1097800000243B608FE396F84836934200F03C8318
+:10979000336886F8482693F82F30002B00F0348386
+:1097A00096F82930002B00F02F83304621F0AEDBF5
+:1097B0003046012121F0B4DD002474E3306B0368EE
+:1097C000022B40F02183437D00243B606BE3336830
+:1097D00093F83F30002B40F049833046E9B2012234
+:1097E0001FF0B4D906E3D6F8583600241B783B6046
+:1097F00059E3D6F85836002493F903303B6052E31E
+:10980000022D00F20F83304604216AB21CF0B0D85A
+:10981000002448E3D6F85836002493F901303B6021
+:1098200041E36B1C012B02D9012D40F0FB82304635
+:1098300002216AB21CF09CD8002434E3B9F1270F4E
+:1098400040F30583282278A83946F8F395F3789CED
+:10985000102C00F20883336B5B7D002B00F0FA8242
+:1098600064B906F5AE600C3021462822F8F3E8F31F
+:1098700019E3C046177386001C73860033686EAC0C
+:1098800093F84630214613F0030317BFD8F8CC30C5
+:109890001846C3F3003383F0010000227F230093B6
+:1098A0000190134678A847F027DCD6F860360022EE
+:1098B0009B782046AC4947F061DB789A6E9B9A42D0
+:1098C00040F0D18206F5AE6028220C302146F8F334
+:1098D00053F33268137E002B00F0968292F82F30FB
+:1098E000002B00F0918292F83F30002B00F08C8228
+:1098F000304621F00BDB3046012121F011DD002440
+:10990000D1E2336B5B7D002B00F0A482B9F1270F0D
+:1099100040F39D8206F5AE6138460C312822F8F3FB
+:109920002BF30024BFE225B1022D02D0012D40F01F
+:109930009182D8F8E832404683F8E05030F046DFB4
+:109940000024B0E2D8F8E832002493F8E0303B601D
+:10995000A9E2B6F87A3500243B60A4E23368187EA9
+:10996000002840F07D824FF6FE739D4200F25A823D
+:109970000446A6F87A5596E201344C4502DAE35DD6
+:10998000002BF9D1032C00F3688288AD002104225A
+:109990002846F8F355F3224639462846F8F308F4EA
+:1099A000D6F85C0129463CF0DDDB0446002840F097
+:1099B000248230460DF07ADB06F5AA600A3029468B
+:1099C0000322F8F3F5F386F859456CE2B9F1030F79
+:1099D00040F33D82D6F85C013BF05EDE0422014696
+:1099E0003846F8F3C9F200245DE2D6F80C350024BD
+:1099F0003B6058E233681B7E002B00F0228229E294
+:109A0000B9F1030F40F32382A9F1040399083B68DD
+:109A10008B4288BF396000252C460E2C8CBF4FF43A
+:109A200080514FF4005144F430631943D6F85C017F
+:109A300089B23CF0B3DC10B10DAB5C55013501349B
+:109A4000E02CEAD13B68AB4201D3002107E03D6046
+:109A5000FDE10DAA8A5C07EB81035A600131A9423E
+:109A6000F7D100243D601EE2304639463BF064DF0A
+:109A7000C0E13046394608F0DDFCBBE196F8CE3156
+:109A800000243B600FE286F8CE21304600210AF028
+:109A90005FDF002407E23368114683F84120336B0F
+:109AA0000024186909F0A6F9FDE13368002493F851
+:109AB0004130003B18BF01233B60F4E133680024D0
+:109AC0003B60F0E1D8F87030B3F1FF3F00F0AD81BA
+:109AD00008EB8303586F002800F0A781C3790024A6
+:109AE000AB4214BF002301233B60DCE140466FF032
+:109AF00007040025416FB9B1CA798C9B9A4213D1F2
+:109B0000D8F87030B3F1FF3F07D008EB83035A6FEA
+:109B10001AB1538923F0020353814B89C8F870505E
+:109B200043F002034B81002401350430042DE1D1C0
+:109B300061E1B9F1090F40F38A8185E101314945BD
+:109B400000F08581CB5D002BF8D1A6E100230293C4
+:109B5000304639463A19C4EB09030097CDF8049012
+:109B6000CDF80CB00FE0C0460C1886003B19C4EBD2
+:109B700009020093012301920293CDF80CB0304604
+:109B800039460022134619F00BDC33E198F8063011
+:109B9000002B40F0598198F81130002B00F05481CF
+:109BA000D8F80C00394698F8072013F0B9FB21E1EA
+:109BB00019F0010440F0308101230293AD49AE4B0E
+:109BC00040F21312924518BF1946304622460097BC
+:109BD000CDF80490CDF80CB0D4E73846B16B4FF413
+:109BE0008672F8F3C9F100245DE138460899AC2289
+:109BF000F8F3C2F1002456E1099C099AA36B516B5A
+:109C000047F8043B926B3846F8F3B6F1099B099C80
+:109C10009A6B5B6CB818BB50216C626C0430F8F323
+:109C2000ABF100243FE1336893F83F30002B00F0A4
+:109C3000FF800899002900F0FB80496E002900F0A0
+:109C4000F78038460822F8F397F100242BE1089AB0
+:109C5000384602F16B011022F8F38EF1002422E164
+:109C6000089B384603F17B011022F8F385F10024AC
+:109C700019E133681B7E002B00F0E3803046394643
+:109C80004A460AF065DFB5E033680121186901F042
+:109C90000DDB002407E1304651464A463B46F9F7C2
+:109CA00017FB0446002840F0A880BAF13C0F49D1C8
+:109CB0003D1D00F0AE807B6813F0006F40F0A9807E
+:109CC00003F07F03022B06D0042B04D00B2B02D011
+:109CD000162B40F09E806EAC3046214613F0A6DE77
+:109CE000304621461CF01ED8286810F0006F26D0A0
+:109CF00010F4000F00F4E06310D01B0A043B012BAA
+:109D00005E4900F07F0204D8142302FB0313D868D5
+:109D100017E0142302FB0313986812E01B0A043BAC
+:109D2000012B564900F07F0204D8142302FB0313D1
+:109D3000586806E0142302FB03F3585801E000F0D2
+:109D40007F002860336B514618698CAB0733009352
+:109D50004A463B460AF0B4F9BAF13C0F044608D033
+:109D6000BAF15C0F05D0BAF14A0F02D0BAF15D0F1B
+:109D700041D1002C41D1002F00F095803B68326822
+:109D8000003B18BF012382F840308CE03C490022A0
+:109D900030460097CDF804900292CDF80CB0F1E671
+:109DA0003749012330460097CDF804900293CDF84F
+:109DB0000CB0E6E63349012330460097CDF8049015
+:109DC0000293CDF80CB0DCE6D6F8680151463A466D
+:109DD0004B46CDF800B04AF0C9DC10F1170F04462D
+:109DE00009D1D6F8340751463A464B46CDF800B073
+:109DF00029F030D90446002C55D004F12A032A2B2F
+:109E000002D83368DC664EE000244CE06FF00804B2
+:109E100049E06FF0010446E06FF00104EDE74FF018
+:109E2000FF34EAE76FF01C04E7E76FF00704E4E7AC
+:109E30006FF01004E1E76FF00604DEE76FF00A044C
+:109E4000DBE76FF00304D8E76FF01604D5E76FF097
+:109E50000D04D2E76FF00C04CFE76FF00E04CCE7EF
+:109E60006FF00404C9E76FF00B04C6E76FF01B0442
+:109E7000C3E7C0467ED701002F7386008418860092
+:109E8000507386005D7386006FF00204B5E76FF0D3
+:109E90000804B2E76FF01904AFE74C1CBAF5837FF2
+:109EA0003FF454AE62E620460DF50F7DBDE8F08F1D
+:109EB0002DE9F341089C05460E4617469846009446
+:109EC00007F0A6FD10F1170F06D1284631463A4695
+:109ED00043460094FDF788FFBDE8FC812DE9F04181
+:109EE0000368054693F83F30D0F80C8013B1B0F802
+:109EF000267602E0FAF70CFF074600222869394669
+:109F000003F0E2F85621286933F08ADBD5F888316E
+:109F10004000002BC5F8040506DA2869B22133F0A9
+:109F20007FDB4000C5F80805A221286933F078DB03
+:109F30004000C5F8EC07284612F03AD895F8CD3124
+:109F40003BB928694C2133F06BDBC0F3C71085F8AF
+:109F5000CD0128461CF092DDD5F84C0104F02EFD11
+:109F600028463DF05FDA002605EB8603D3F84C4225
+:109F70002CB120461EF03EDF20461EF031DD0136BA
+:109F8000082EF1D12B6893F83F309BB1002205EBEE
+:109F90008203D3F84C0250B1037943B1D0F8D432E4
+:109FA000DB8D1B04C8F888311FF05CD902E0013258
+:109FB000082AECD12846394609F0AAD82846742147
+:109FC000B5F87A2522F006D995F8D13142F210720F
+:109FD000002B18BF4FF4BC622846822122F0FAD829
+:109FE0002B6B95F8D111186909F04AF80122134634
+:109FF000B5F8781728460AF063DA0123B5F87A171E
+:10A00000002228460AF05CDAD5F8400125F0D8DBBA
+:10A010002846F9F7E9FA2B685B6B5BB1B8F888362C
+:10A02000D5F86C029BB243F00403A8F888360021EF
+:10A0300017F0B6DE2846F9F77BFAD5F8841161B936
+:10A0400028461CF08DD80404C5F884412846022116
+:10A050001CF086D82043C5F884012B6893F8A13002
+:10A06000012B03D1D5F8400126F096DC284617F0E5
+:10A07000C7DF284608F0B6DBB5F85C1728461CF0A9
+:10A080004DDD284610F004DA424BEA68002185F8DD
+:10A090004410C2F8DC33012385F8A83185F8AA31D1
+:10A0A0002B6893F838303BB14A1901314FF0FF3338
+:10A0B000082982F89538F7D100244FF440763146CC
+:10A0C00028461CF04DD805EB4401B1F8203213F0BE
+:10A0D0000F0F06D123F00F0300F00F021343A1F876
+:10A0E0002032B1F8202212F0F00F06D100F0F00378
+:10A0F00022F0F0021343A1F82032B1F8202212F42A
+:10A10000706F06D100F4706322F470621343A1F8FB
+:10A110002032B1F820321A0B06D11B0500F4704230
+:10A120001B0D1A43A1F8202201340236042CC6D19B
+:10A130002B68284693F94C100BF076DA2A68137EC8
+:10A1400003B392F82F30EBB1002605EB8603D3F86A
+:10A150004C426CB1A3795BB12B6893F838302BB1CA
+:10A160002846D4F84C15002235F0F2DD0023E371C7
+:10A170000136082EE9D1002385F87232D5F834076C
+:10A180002AF0C8DDD5F8680104214AF011DABDE8EB
+:10A19000F081C0468096980003681A6819B10123BF
+:10A1A00082F8AA3001E082F8AA1070472DE9F04742
+:10A1B0001746937AD27A056843EA022A3B79064623
+:10A1C00003F007044FF0000938E00B6968681A785B
+:10A1D0005B7842EA0328D6F87822936E01339366BF
+:10A1E0000122FCF39DF52B6893F8A130012B03D0DD
+:10A1F000C8F34123032B17E0182304FB0362B2F8D2
+:10A200008232B2F88612284699420CBFB2F88032E8
+:10A210004B1CA2F886322146012220F0E5DB09F131
+:10A2200001031FFA83F9D1450AD02B69022103EB00
+:10A230008403D868124B9B6B984701460029C4D110
+:10A240002B6893F8A130012B05D02846214696F9BA
+:10A250002C2020F0C9DBBB7913F0020F0ED00024B4
+:10A2600006E00120FCF378F2631CDCB20B2C05D075
+:10A27000EB68D3F8703113F0010FF2D0BDE8F0872E
+:10A28000E0A685002DE9F347D0F80090044601A927
+:10A29000D9F800054AF01EDF00263AE07B6813F487
+:10A2A000802F36D063684FF00008FD58AA46D5F8D5
+:10A2B000F8205FFA88FE32B391781379002918BF2D
+:10A2C00001261BB100231371D3701CE0D9B1D378E0
+:10A2D0000133D9B2D1707B6813F4807F14BF628ED2
+:10A2E000A28E6423B2FBF3F291420BD3D4F878220E
+:10A2F0004846D2F8C43051460133C2F8C4307246E1
+:10A3000023F030DF012608F101080435B8F1080F09
+:10A31000CDD101A84AF0E6DE07460028BED136B905
+:10A32000236884F8A3639868A16B05F097D9BDE80A
+:10A33000FC87C0464368F7B5CE5805460027FCB2F7
+:10A3400028463146224622F0DBD901370123284630
+:10A350003146224622F040D9082FF0D12A68002346
+:10A360000093506806F110010122F8F36BF5FEBD71
+:10A37000D0F8AC037047C046D0F8C0037047C04661
+:10A38000C0F8C0137047C046D0F8AC331B68DB6917
+:10A3900018690528A8BF05207047C0462DE9F04F71
+:10A3A000F3B00890894608999DF8F8010792D1F812
+:10A3B000B0231C46D9F8D4320690D1F8AC730C9275
+:10A3C000002148A828226F9115937C9DDDF8F48127
+:10A3D000F7F336F607980C99037803F0FC03202B6B
+:10A3E00014BF002301230D9391F82F3033B1D7F818
+:10A3F0006801837913B104214AF0DAD80D9A0AB1C1
+:10A40000092D00E0032D40F2E58522786378211DB7
+:10A4100042EA032AA278E37842EA03230E930D9BD3
+:10A4200023B9043D8B4613950F9304E00A3D04F1D4
+:10A430000A0B13950F911398012840F2CB859BF8D6
+:10A44000013002339842C0F2C58548AB00933846CC
+:10A450005946139A002319F059DE002840F045832D
+:10A4600097F838279DF834319A4240F03E8399F8A6
+:10A4700019309BF801209A4240F03E8309F11A00FE
+:10A480000BF10201F7F35CF5002840F0358398F8F2
+:10A49000183013F0020F0BD098F8DF3023B1384694
+:10A4A000414601222BF0CEDC4046FE214AF0C8DDB9
+:10A4B00099F94820002AC0F21F8398F8183013F049
+:10A4C000010F00F01983082392FBF3F34344197D35
+:10A4D000A44B02EA0303002B05DA013B6FEA437346
+:10A4E0006FEA5373013351FA03F313F0010F00F0D5
+:10A4F000038319A80021C8F81090A8F800A101381A
+:10A500006D22F7F39DF50024214613E072AA53183B
+:10A5100013F8A43C03F07F026C2A0AD89248835CAB
+:10A520003BB119AB013B9A54835634EA230428BF4C
+:10A5300001240131489B9942E8D3D8F8043023F034
+:10A5400007023B6BC8F804205B7D23B11CB942F0C5
+:10A550000103C8F804303B6B5B7D43B11AF4806F94
+:10A5600005D1D8F8043043F00203C8F804301AF0DB
+:10A57000200405D0D8F8043043F00403C8F80430B0
+:10A58000159B0021986B0FE0159A531893F83C2007
+:10A5900012F0800F07D019AB013B02F07F029B5CE9
+:10A5A000002B00F0A28201318142EDD10C9890F88D
+:10A5B000463013F0030F45D05946139A38461BF026
+:10A5C0009BDD00260546414638462A46334600961E
+:10A5D00018F00CDBB5B14DA8E91C01301022F7F3DF
+:10A5E000CBF431467B1872A893F8EB24431813F888
+:10A5F000933C02EA0303934240F077820131102931
+:10A60000F0D105E00C9991F84730002B40F06D82B5
+:10A6100038465946139A43461BF0D8D83B22584631
+:10A620001399F8F34BF0024660B141784B1EDBB250
+:10A630001E2B07D888F80B1108F58670911C5278EC
+:10A64000F7F39AF4B9F862200023A8F83C20C8F880
+:10A650004030B9F8623033B1D9F8582040F237139E
+:10A6600002EA030343B9D9F8583013F0400003D18C
+:10A670000646119016905EE0139B58461946CDF899
+:10A68000C0B16E9326F02EDD119038B14378042BC3
+:10A6900040F239820020064616904CE070986E9980
+:10A6A000F8F318F6119050B108F1400300930898A0
+:10A6B0004946119A08F13C0327F092DD10E0584614
+:10A6C00013993022F7F3FAF770B1119008F14003B3
+:10A6D000009308984946119A08F13C0327F08CDC56
+:10A6E000002840F0108223E0584613994422F7F3E3
+:10A6F000E5F7119080B108F14003009308984946AE
+:10A70000119A08F13C0327F0D7DB002840F0FB81C9
+:10A7100001210E4616910EE0D9F8583013F0410F82
+:10A7200000F0F181119A1646A8F83C20169202E03A
+:10A73000002301261693D8F8043023F4001323F0E5
+:10A740004003C8F804303B685B6B002B3AD0D9F863
+:10A75000CC3013F0020F35D11398CDF8C0B16E9004
+:10A760000BE0C04607000080401B860038462946A3
+:10A7700070AA6EAB18F0F2DE38B970986E99DD22CF
+:10A78000F7F39CF705460028F0D1404600211BF066
+:10A79000ADD9BDB1D8F8043043F04003C8F8043057
+:10A7A00097F8FA3173B14046297A1BF09FD998F88F
+:10A7B000D13013F00F0F05D0D8F8043043F4001354
+:10A7C000C8F8043000231399304A5846009317F014
+:10A7D00099DD4146024638461AF0D2DF1AF01005DC
+:10A7E0000DD0D9F8582040F2371302EA030333B9E9
+:10A7F00012F0400F00F08D81002E40F08A810C99FC
+:10A8000091F8303053B93B6B1B68022B06D197F996
+:10A810005C361BB914B94FF0130A24E03B6B1B687C
+:10A82000022B08D1089A53782BB11AF4806402D114
+:10A830004FF0190A17E0384611F074DB0899D1F887
+:10A84000C033984211D303230093079B002403F1E4
+:10A850000A0238461721012301940294039419F047
+:10A8600027D94FF0110A10945AE10C9890F838301B
+:10A8700073B13846494612F079D8D9F85035984224
+:10A8800006D300214FF0110A109149E148D401008C
+:10A890000C9A92F8463013F0030F27D0D9F85820BD
+:10A8A00040F2371302EA030303B397F8692712F063
+:10A8B000020F08D0D8F8043013F4803F03D0D8F842
+:10A8C0004030022B0BD012F0010F0FD0D8F804301B
+:10A8D00013F4803F0AD0D8F84030012B06D1002273
+:10A8E000384641461346009218F080D9D9F8CC304A
+:10A8F00013F4005F09D0D7F84C0141465A46139B28
+:10A9000003F0D8FE002840F00481D8F8043013F09A
+:10A91000010F02D0012387F84D36D8F8043013F028
+:10A92000011F02D1012387F84E36D8F8043013F402
+:10A93000801F02D0012387F85136D8F8043013F471
+:10A94000002F09D11598438E03F44063B3F5406F8F
+:10A9500002D1012387F85236D8F8043013F0020FE1
+:10A9600002D0012387F84F36D8F8043013F0040FD3
+:10A9700002D1012387F85036D8F8043013F4001FB1
+:10A9800002D0012387F8FB31D7F8344720462AF05C
+:10A9900091D930B120462AF095D910B120462AF03D
+:10A9A00063D9D8F8043013F0007F1DD0012487F854
+:10A9B00054460C9991F8463013F0030F14D091F9D6
+:10A9C0004C308BB10221384618F0CAD8159A538EF4
+:10A9D00003F44063B3F5406F06D138462AF002D83D
+:10A9E0003846214629F07ADFD8F8043003F40413FE
+:10A9F000B3F5001F02D1012387F853363B6B5B7D13
+:10AA000013B1384620F0E8DA0C9890F8463013F08D
+:10AA1000030F02D0384620F091DBD8F8403043B91C
+:10AA20003DB1D9F8583013F0010F02D00123C8F816
+:10AA300040300C99D9F8582091F838301BB9D7F824
+:10AA40006C32994524D0B9F8620008BB12F0010FAE
+:10AA50001ED0D9F87030B3F1FF3F19D009EB830352
+:10AA60005C6FACB1217A012901D0032910D1628930
+:10AA7000E379009204F11402029208F11A020191A2
+:10AA80000490059003923846494622693CF0F6DC72
+:10AA9000B8F8D4302BB9D8F8100034F081DDA8F81C
+:10AAA000D400B8F8D4200C98109290F8463013F0E7
+:10AAB000030F33D0D8F84030013B012B0AD8D8F827
+:10AAC000043013F4802F05D038464146062220F08A
+:10AAD000E7D823E0D8F8043013F4802F1ED038468E
+:10AAE0004146062220F080D818E000214FF0120ADB
+:10AAF00011911091169113E000224FF00C0A11925F
+:10AB0000109216920CE000234FF00C0A169310934B
+:10AB100006E000204FF00C0A109001E04FF0000A10
+:10AB20003EAC00212822204634ADF7F389F22846B6
+:10AB300000212822F7F384F2D7F87C3533B107F5EA
+:10AB4000AE6120460C312822F7F316F21599234600
+:10AB50003831099138464946099A00951BF076D953
+:10AB60003E9B03F10804349B0BB10233E418D8F880
+:10AB700004304846002BB8BF14340421002235F0BD
+:10AB800091DA97F8653604190BB10233E418D8F856
+:10AB900004300DF5A57013F0400F18BF1A340021D2
+:10ABA0002022F7F34DF2D8F8043013F4803F05D09B
+:10ABB000D7F8FC3434341B7803B11334D8F8083098
+:10ABC00013F0400F06D0D7F84C014146524645F0ED
+:10ABD00041DC2418079A09F1C2030A3217920D9A30
+:10ABE0000A9309F1BC006FAB0B9000900293002A0E
+:10ABF0000CBF102130213846179A0A9B019417F098
+:10AC0000DBDB1490002800F0E5816F980123041924
+:10AC100012940370013B43703B6B1B68022B05D100
+:10AC200097F95C2612B91F3303704270D9F8582087
+:10AC300040F2371302EA03035BB199F8603043B185
+:10AC40000378427843EA022343F0100303701B0A9F
+:10AC5000437097F843365BB13B6B5B7D43B1037840
+:10AC6000427843EA022343F4806303701B0A437073
+:10AC7000002380F802A0C370109B037110990B0A87
+:10AC80004371012106303FAB3E9A21F06DDAD8F8CE
+:10AC900004300646002B06DA0C21122207F5037356
+:10ACA00021F062DA0646349A2AB13046322135ABB9
+:10ACB00021F05ADA0646D7F8603648AC00229B7875
+:10ACC0002046099946F05AD9D8F8043013F4803F49
+:10ACD0003FD03B6B0DF5B5751B6804F11502022BD7
+:10ACE00014BF002301234846294661AC21F09ED9B8
+:10ACF0004846214621F0F6D830462D211A222B460F
+:10AD000021F032DA23463D21162221F02DDAD7F840
+:10AD1000FC3406461B78E3B172AB012203F8012D27
+:10AD20007F2121F021DAD7F8FC140DF5D574054602
+:10AD300024310E222046F7F31FF138462146002227
+:10AD400017F0EEDE28464A210E22234621F00CDAC7
+:10AD50000646129AB24201D2002002E0129BC6EBD4
+:10AD600003000423009001934846334600214FF02E
+:10AD7000FF3235F0D9D997F8653604462BB107F57F
+:10AD8000CC61043112F0C2DC0446D8F8043013F070
+:10AD9000400F08D007F500732046DD211822063346
+:10ADA00021F0E2D90446D8F8083013F0400F06D05D
+:10ADB000D7F84C0141465246234645F02BDB069816
+:10ADC0000023D9F808200090019302933846149983
+:10ADD000D26843461AF0A6DEBAF1000F40F0FA80BE
+:10ADE0001099159AA8F8D41092F860300E989BB27A
+:10ADF000834238BF0346A8F80231022140464AF098
+:10AE00007FDB404649464AF0C5DAD9F8CC3013F426
+:10AE1000801F09D03846494611F0A8DD012803D12A
+:10AE20003846494634F002D80C990D9A8B6AC8F816
+:10AE300024305AB10B980F990622F7F381F028B10C
+:10AE400008981799D9F8082027F0CEDBD9F8082000
+:10AE50000898179926F0CCDFD9F8CC2012F40053CB
+:10AE60000CBF1C4602243B6893F8463013F0030FD6
+:10AE700007D012F4805F04D1B8F8063003F0010265
+:10AE800000E000227F2300930192234648A808F1A6
+:10AE90004401002246F030D9384641464AF032D9C2
+:10AEA0000C9890F82F3063B1D8F8E81049B1C06819
+:10AEB000D8F8EC20FBF31CF70023C8F8EC30C8F8F6
+:10AEC000E830B9F86230002B33D0D9F8582040F27E
+:10AED000371302EA030363B312F0010F01D1119992
+:10AEE00039B398F8DE300BB1119AB2B90C9890F8DA
+:10AEF0002F30F3B11199E1B14978C0680231FBF309
+:10AF0000E7F6C8F8E800A0B1119B5A78194602325A
+:10AF1000C8F8EC20F7F330F00BE00224384608F1D3
+:10AF20001A010B9A0A9BCDF8008001941DF02AD8D3
+:10AF3000A246D9F8CC3013F4005F04D0D7F84C0106
+:10AF4000494644F0FFD938464946012216F0E8DF69
+:10AF500000231398009302930D9B0490002B0CBFC9
+:10AF600008220A2238464946179BCDF804A0CDF89E
+:10AF70000CB011F0D3DD169860B3D9F87030B3F18E
+:10AF8000FF3F03D009EB83035B6F13B90DF5CD725F
+:10AF900002E003F5997312E0362313700DF5CD71BD
+:10AFA00026335370023201F110039A42F4D10C9A05
+:10AFB00092F82F3013B137238DF89A310B46009356
+:10AFC000F12301933846494608F11A02D8F8E830CF
+:10AFD00020F0FAD973B0BDE8F08FC0462DE9F04FEC
+:10AFE000D0F8ACA3D1B0D0F8B00389469DF86C116D
+:10AFF0000890DAF86801079206911E4683799DF859
+:10B00000704113B1042149F0D3DA99F8063023B125
+:10B0100099F80430002B00F09B813278737842EA73
+:10B020000328B278F37842EA0323079A0993537806
+:10B030001B0213F4804040F07D81099B012B00F03E
+:10B04000828083460E2545E1DBF8D830002B00F0E6
+:10B050007F81F3789F0914B30AEB8703D3F88052FA
+:10B06000EDB12B69DBB12B7ACBB14CAC314603226D
+:10B070002046F6F381F705F114012A69E01CF6F386
+:10B080007BF729690DF12E05204603312A46FDF391
+:10B0900061F25A9A301D111F2A46FDF38BF2032FDD
+:10B0A00040D809EB87035B6F002B3BD01A695A9895
+:10B0B0003146143301F02ADF002833D0321D3179B4
+:10B0C000537841EA03289178D378B8F1010F41EA27
+:10B0D000032309931FD1032B1DD1B37A06F10A0272
+:10B0E000102B18D1DBF8D80006F10C010230527891
+:10B0F000F6F326F7044670B95846414699F94820B8
+:10B100004AF016DA8BF8DE805846414622464AF06D
+:10B110000FDA25460BE05846012199F9482049F0FD
+:10B1200099DF03E003234FF0010809930F25DBF8B3
+:10B13000D810089E4A78F0680232FBF3D9F5002354
+:10B14000CBF8D830C6E0D9F85050D9F84C60D9F8CF
+:10B150005410ADB10C46074609E00799062201F1EB
+:10B160000A002146F6F3ECF6063410B10137B74277
+:10B17000F3DB012D02D1B74206DB01E0022D01D045
+:10B18000002512E0B742FBDB03230093079B00245A
+:10B1900003F10A02504617212346019402940394B6
+:10B1A00018F086DC0125A346AFE0BAF8822144F20C
+:10B1B00021339A4214D00E3B9A4211D007339A425F
+:10B1C0000ED010339A420BD0143B9A4208D007336A
+:10B1D0009A4205D010339A4202D025339A4200D1C8
+:10B1E0000125079E504606F10A0421462A464AF0E8
+:10B1F000DFDA014610B150464AF0E2DA0135002D9F
+:10B20000D3DD504621464AF0E3DB8346002800F0B8
+:10B210009C8049464AF0BED8DBF8042012F4805FD7
+:10B2200009D0089991F83030002B40F08E8022F43C
+:10B230008053CBF80430504659461BF0CDDEB8F1B0
+:10B24000000F03D0B8F1010F16D041E0B9F95C301E
+:10B2500099F9482023B9584601214AF069D903E0F9
+:10B260005846012149F0F6DE9BF8183013F0010F23
+:10B2700069D000252C4632E0DBF8D81041B1089B9C
+:10B280004A78D8680232FBF333F50023CBF8D83084
+:10B29000B9F86250002D56D1089E8221F068FBF368
+:10B2A00017F5044608B945462FE0102303706FF0E8
+:10B2B0007F0343702946DAF80C30B3F85A26631836
+:10B2C000013180299A70F6D10025CBF8D84006E0EC
+:10B2D0000D2502E0099903293AD80024ADB9BBF144
+:10B2E000000F12D09BF8183013F0010F0DD0079EFD
+:10B2F00050464946042206F10A0300950195CDF80F
+:10B3000008800395049511F009DC0999069A4B1CF5
+:10B31000019300230393079B059203F10A0148461A
+:10B3200009F1BC025B46CDF80080029504941CF044
+:10B33000F3DC0DE0079A504602F10A014AF02EDADA
+:10B34000834628B180E60D2500E001250024DCE7D6
+:10B3500051B0BDE8F08FC0467FB5089D9DF82440F0
+:10B360009DF82860009501940296FFF737FE7FBD97
+:10B3700002292DE9F0410646D0F8AC5301D0002453
+:10B3800001E000F575742B68D3F88C205368126CBB
+:10B390009B1822692361C2EB0302A3699A422378B6
+:10B3A0000ED24BB9E26863699A4205D30123237038
+:10B3B00063680133636028E0E3680133E36024E0FD
+:10B3C0000027E7600BB3012904D1284602311EF0A3
+:10B3D00025DE18E0022916D1A868D6F8D01304F0AB
+:10B3E0003DD9D6F8CC3373B12B6893F87430012B68
+:10B3F00007D02869012132F063D82A68012382F836
+:10B400007430C6F8CC7300232370BDE8F081C046C9
+:10B410002DE9F04F97B0DDF894B0D0F8AC6300237D
+:10B42000D0F8B0930C460746594630460392DDF8F3
+:10B4300088A014931393129333F0DCDF039905462D
+:10B4400001F001030093484621465246239B17F022
+:10B450003BDF1490002840F00783219A032A0DD97E
+:10B46000042213A82099F6F387F5219B072B05D911
+:10B47000209A12A8111D0422F6F37EF5139C129A4D
+:10B48000B4F1000818BF4FF00108BBF1000F01D163
+:10B49000D5F808B003998B1E472B00F2E182DFE854
+:10B4A00013F0F900FE00010104016A007D008C0028
+:10B4B000DF028E00DF029700DF0207010A01480069
+:10B4C00058007F0195010D011F014E015401280212
+:10B4D000DF029900A000AD00B00033013601FC008E
+:10B4E000DF023E024202DF02DF02DF02DF02DF0292
+:10B4F000DF02DF02DF02DF02DF02DF02DF02DF0244
+:10B50000770289028E02E500EF00E202A402DF0268
+:10B51000DF02B402B702C002C302C602C902CC02F3
+:10B52000DF02DC02CF02DF02DF02DF02DF021402F1
+:10B530001B02D9F83430002B00F092820DAC30465B
+:10B5400007F56371224620F077DB50462146102232
+:10B55000C3E0D9F83430002B00F0828211AC5146A0
+:10B5600004222046F6F308F5304607F563712246BB
+:10B5700020F07EDB1FE0219A0023052A8DF857304A
+:10B5800040F22781384620990DF1570227F084DADE
+:10B590009DF8573014908AF8003064E251463046E6
+:10B5A0004AF0FCD80146002800F0268238469AF876
+:10B5B000062029F06FDC149055E29B4B00E09B4B7A
+:10B5C0000093384629465246239B27F0FFD9F2E7DD
+:10B5D000974BF5E7D6F83407FEF7CEFECAF8000021
+:10B5E00041E2D6F834572846FEF7CEFE844200F3F7
+:10B5F0002E8228462146FEF7C3FE34E2D5F85035A8
+:10B600003BE03368DB691F692B79002B40F06B81CD
+:10B61000BC4200F31C82C5F85045139C18461946DD
+:10B620007318D3F84C2222B1937913B1954218BF05
+:10B63000013004312029F3D1002800F01482C4EB3A
+:10B64000070393FBF0F000217318D3F84C224AB1A2
+:10B6500093793BB1954205D0D2F85035834288BFEB
+:10B66000C2F8500504312029EED1FCE196F9A83842
+:10B67000002B01DA002300E00123CAF80030F2E1D8
+:10B68000B8F1000F01D0002301E04FF0FF3386F83E
+:10B69000A838E8E195F83C30EFE7AB79EDE785F8BD
+:10B6A0003C80E0E1D6F82837E7E7C6F82847DAE13A
+:10B6B000D7F8BC33E1E7C7F8BC43D4E16A7E049213
+:10B6C00022B105A805F11A01F6F356F4049B1A1DE0
+:10B6D000239B93427DDB504604A9F6F34DF4C2E16F
+:10B6E000202C02D96FF01103BCE12399231D99424C
+:10B6F0006FDB2B79002B40F0F68028460AF104011D
+:10B70000224633F039DAAEE195F83A30B5E7AB7955
+:10B7100085F83A8085F83B80002B00F0A4812B79D6
+:10B72000002B00F0A0813046294611F0BFDA3046E8
+:10B730004FF000614FEAC86218F03CDA93E199F8E3
+:10B740003830003B18BF012397E799F838301C1EAA
+:10B7500018BF0124444500F0868130461FF076DB97
+:10B7600010B96FF015037DE154B1304601F0C2FE0F
+:10B77000736A23F4C0137362002389F8383072E1CE
+:10B78000736A304643F400237362022389F8383029
+:10B79000D6F8AC38013B86F8A93805F081FE62E1A5
+:10B7A000219A032A15D9002C05DB3046214614AA1C
+:10B7B00033F064DD05460DB12B795EE7149B13F180
+:10B7C0001E0F40F05081CAF800504CE1239B072B1C
+:10B7D00002DC6FF00D0345E1032A01D1002703E0ED
+:10B7E000022A14BF00270127002C2DDB30462146FA
+:10B7F00014AA33F043DD054630BB149B13F11E0F32
+:10B8000022D1129B002B1FDD87F0010300932A46F3
+:10B810002B463046139933F0CBD9054650B96FF01B
+:10B820001A03149310E0C046991E8300A91E8300DA
+:10B83000F92A83003046294633F0A4DE149018B16B
+:10B840003046294633F0F8DD129B032B00F00B81C4
+:10B85000022B00F00881149A3AB112F11E0F40F049
+:10B860000281002B40F0FF80FCE0002B24DD2B79CF
+:10B87000002B40F0F88033681B6F13F0030F02D0E9
+:10B880006FF00803EEE0AB7923B13046294633F080
+:10B89000ABDC90E6D5F8CC3013F4005202D04FF078
+:10B8A000FF33DFE06B7E304600920192294605F1BE
+:10B8B0001A022EF05DD8D6E06B79002B00F0D38011
+:10B8C0003046294633F0DCDACDE015B195F9643520
+:10B8D000D3E6CAF800501FE0F5B1002C1CDB012CA8
+:10B8E0001ADC2B7913B16FF00403BBE085F86445D3
+:10B8F000B9E099F818307BB199F82F3063B199F815
+:10B9000030304BB999F83F3033B9D6F868319B796C
+:10B9100013B9B6F81637B0E66FF00103A2E033684A
+:10B9200093F83030A9E6336893F83030434500F09F
+:10B930009A80304633F024DF0446B8F1000F05D07A
+:10B9400043791BB13046214633F09ADA214630461E
+:10B9500088F0010233F01CDF04461490002840F008
+:10B9600082803368012283F82F20B8F1000F03D0C2
+:10B97000D6F8403583F834203368304683F8308079
+:10B9800010F01EDA86F8DD41304605F0BDFD6AE0B4
+:10B99000BAF80200F7F360F4E8B99AF80400BAF8CC
+:10B9A00002109AF800209AF801300090284628F0FA
+:10B9B000C3DD00E6D6F83437B3F8A4335DE624B926
+:10B9C000D6F83437A3F8A4434DE0D6F85C01A1B211
+:10B9D0003AF0E4DC10B96FF0130343E0D6F83437E3
+:10B9E000BDF84C10A3F8A4133DE0BBF1000F03D049
+:10B9F0009BF80430022B02D06FF01D0332E0384672
+:10BA0000DBF8101027F01CD8D5E597F8F03334E6B2
+:10BA1000E3B287F8D53387F8F033384626F0D6DE20
+:10BA200021E0D7F8E83328E6C7F8E8431BE0D7F869
+:10BA3000EC3322E6C7F8EC4315E097F8D4331CE664
+:10BA4000D6F86C32D3F8D432DB8D9C4202DD6FF035
+:10BA50001C0307E0A7F8C84305E0B7F8C8330CE6B5
+:10BA60006FF016031493149817B0BDE8F08FC0461A
+:10BA70002DE9F0410468074686B020460E46904600
+:10BA80001D461BF0B3D910B120461BF0A7D90C9B63
+:10BA90002046029300230393049339460B22434626
+:10BAA0000096019511F03AD806B0BDE8F081C04685
+:10BAB00070B5114686B00546164649F06FDE04465D
+:10BAC00008B390F8DF3023B12846214601222AF03E
+:10BAD000B9D9204649F0E8DBE3681BB12846214686
+:10BAE0003CF0CCD9002203230092019302920392EE
+:10BAF0000492284621690532334611F00FD82846B2
+:10BB0000214649F05DDE06B070BDC04670B5036BDE
+:10BB1000002680F8D068D0F85C410546186907F027
+:10BB200005F8014620463AF001DA20B12846012105
+:10BB3000324618F031DA70BDF0B505688BB00646B4
+:10BB40000021EF681DF0D6DA304610F01BDFD5F883
+:10BB5000E4366BB1A868D5F8741503F07FDD0023D7
+:10BB6000C5F8E43695F8583503F0FD0385F85835E7
+:10BB7000D5F85C013AF0BAD92A6992F8EA3063B193
+:10BB8000D36ED3F8202140F2044302EA0303B3F555
+:10BB9000806F14BF0020012006E0106E03F054FEF9
+:10BBA000D0F1010038BF002000283CD0284605F025
+:10BBB00019FE2B6BD5F85C41186906F0B7FF0146FA
+:10BBC00020463AF0B3D930B195F8D0281AB92846B2
+:10BBD000012118F0E1D9304611F06EDC4FF000433E
+:10BBE000C7F888310F21286931F010DE286940F24A
+:10BBF000FF3131F0F9DD2B6B1B68022B04D1286972
+:10BC000095F8431631F05EDE284616F02DDC284606
+:10BC100016F0F6D900232846694600931AF082D818
+:10BC200028461DF0D7DB0BB0F0BDC0462DE9F04F24
+:10BC30000668D0F8D022D0F8D81297B00746D0F8CE
+:10BC4000E8B23046069107921DF04CDC069BB068C6
+:10BC5000196803F003DD384602212CF02DDEF7E1F0
+:10BC6000D6F8D83603EB82035D686C8E04F470431B
+:10BC7000B3F5805F14BF38233C2356F8039004F4D7
+:10BC80004063B3F5406F28D1336893F8463013F022
+:10BC9000030F15D0D6F85C01D9F8041039F02EDD69
+:10BCA00010F0080F0CD199F8EC304BB1D9F80030F6
+:10BCB000022B12D1D6F8FC349B7813F0020F0CD073
+:10BCC0002046F7F3AFF20E2894BF4FF400534FF421
+:10BCD000805340F4306003439CB2D6F85C012146A7
+:10BCE0003AF05CDB002800F0AE81688EF7F39AF240
+:10BCF0000446688EF7F396F244F430640E288CBF45
+:10BD00004FF480504FF400500443A1B238462BF05A
+:10BD100087DE002800F09781D7F8E832002B78D032
+:10BD2000D3F8DC30002B74D04FF00001A7F85C1082
+:10BD300095F8AA004FF00C0800FB08B0EA8814A997
+:10BD400082F08002C2F3C0121C30F7F3D1F3BDF8C9
+:10BD500050200DF1540AA7F8622095F8AA00514628
+:10BD600000FB08B02030F7F321F4159B33BB95F8A6
+:10BD7000AA1013AC01FB08B1042224312046F6F3CB
+:10BD8000FBF020469A490422F6F3DAF048B995F818
+:10BD9000A920A2F10803DBB2022B40F254818DF8F6
+:10BDA0004F2020465146F7F301F4024630B9009087
+:10BDB000CDF8048095F832300293FAE0159B8D4956
+:10BDC00013F0040F1CBF43F002031593159B30467C
+:10BDD00013F0020F1CBF43F00103159315AB009342
+:10BDE0000423019301230293BB68002203931346AB
+:10BDF00017F0D6DA002207230192009395F8AA30B3
+:10BE00003046029303920492394618322B4610F0C2
+:10BE100085DEB5F8623013F0100F0FD0BA6D40F226
+:10BE2000371302EA03034BB9734B1A7832B9012373
+:10BE30000092019395F832300293FCE02846F6F325
+:10BE40007BF518B100230222009327E03B6D002B05
+:10BE500032D0336893F83030002B2DD11C469846F1
+:10BE600009E0796D284641440622F6F369F008F1AD
+:10BE7000060818B10134FB6C9C42F2D33B6D012BD8
+:10BE800003D1FB6C9C4206D316E0022B14D1FB6C51
+:10BE90009C420DD210E0002300930322019295F8FA
+:10BEA0003220039302920493304639461722C7E0AA
+:10BEB000002304220093F1E7336893F8953083B1AF
+:10BEC000D6F84C35012B09D1284606F5AA61062281
+:10BED000F6F336F0002840F0B68002E0022B00F0C6
+:10BEE000B28095F9344074B9D6F85C01698E3AF0A5
+:10BEF000E9D840B105230094019395F832300394BA
+:10BF000002930494D0E7B7F862306BB1BA6D40F297
+:10BF1000371302EA03033BB1304639462A462BF079
+:10BF2000A1DF002840F08F80D9F80030022B0AD121
+:10BF300099F815203AB9FD33009305F1380009A9A5
+:10BF40000123019214E0336805F1380093F846307C
+:10BF500009A913F0030317BFD7F8CC301A46C3F36F
+:10BF6000003383F001020192FF2300220093134665
+:10BF700045F0C2D8336B09F1500493F8EC1039B195
+:10BF80006B8E03F44063B3F5406F14BF1421282176
+:10BF9000204645F059D8D6F86036002209A8214637
+:10BFA0009B7844F0EBDF024630B9009009230193FF
+:10BFB00002920392049277E79DF8382096F838377A
+:10BFC0009A4240D195F93430C3B96A8E304602F4B2
+:10BFD0007042B2F5805F14BF0222012205F13801E0
+:10BFE0002BF0E4DC024648B90A230090DFE7C046A4
+:10BFF00058D4010017738600B0270200336893F805
+:10C00000303053B32946304649F0C8DB014620B3EF
+:10C01000037E13F0020F06D0436813F4805202D15E
+:10C020000D230092C3E7D1F8F030B3B100220F2303
+:10C0300000920193029203920492304639461732DD
+:10C040002B4610F06BDDD6F8DC36013BC6F8DC364B
+:10C05000D6F8DC26002A7FF403AED6F8DC36FBB136
+:10C06000069B00219977D6F8DC26D6F8D836013A17
+:10C0700003EB8203C6F8DC26069A9C685368012B02
+:10C080000AD0009101910291039104913046394602
+:10C090002022234610F042DD38462EF011DA35E03A
+:10C0A000D7F8CC3013F4005F06D0FB7923B9D6F86B
+:10C0B0004C01394643F0F8DF0799FA7991F93430A9
+:10C0C0004AB1002238460121934214BF00230123C4
+:10C0D0002CF0DAD809E038460121D3F1010338BF4A
+:10C0E0000023009201922CF009DA97F91030022B0C
+:10C0F00003D1F86800214DF035DA96F875323846EC
+:10C1000023F0040386F875322CF0A6D917B0BDE8E9
+:10C11000F08FC0462DE9F04F9B460568D0F8D0322D
+:10C1200089B003932B68064693F83F308A469046C1
+:10C13000D0F8D872D0F8D492002B00F08281C37965
+:10C14000002B00F07E81837C0DF1160013B106F107
+:10C15000D60100E049460622F5F30EF700242B68CD
+:10C1600085F84A4593F844301BB1D5F8640135F0A1
+:10C1700067DFB37C2BB1D5F84C013146224605F080
+:10C1800067F82A6992F8EA305BB1D36ED3F82021C0
+:10C1900040F2044302EA0303B3F5806418BF0124AC
+:10C1A00005E0106E03F050FB041E18BF0124CCB153
+:10C1B000002130462FF012DA3046FFF7BDFCB37C89
+:10C1C0003046D3F1010338BF0023009300210DF165
+:10C1D00016020823FFF74CFC002130460A4632F0D5
+:10C1E000CBDC1AE1B37C002B00F08F80D6F8DC3278
+:10C1F000D3F8901041B193F894206868FAF378F579
+:10C20000D6F8DC32C3F89040BB6823B10D2B02D0C6
+:10C2100030462CF09BDAD5F86801042148F0C8D9E3
+:10C220000DF11601284649F0B9DA002421460746E7
+:10C2300086F8944030461CF06FDC2146304619F0F9
+:10C240002DDC304621460FF01FDEBAF1000F45D03D
+:10C2500006F1BC00F6F380F300283FD12B6BB9F850
+:10C260003240186906F062FC844237D1D5F85C018F
+:10C27000B9F8321039F0AADE30B9D5F85C01B9F856
+:10C28000321039F01FDF80B1B8F1000F0DD1D5F8B1
+:10C290005C01B9F8321039F049DE30B9DFF8ACA1F1
+:10C2A0000123C34685F8D03800E0C24608230DF1CB
+:10C2B00016010193284606F1C2030A4600971BF0B7
+:10C2C00091DE034658B1BAF1000F08D02846514616
+:10C2D0005A4618F053D810B9824600E0C2460FB94A
+:10C2E0003C462FE038460E2148F0AADE2B6893F832
+:10C2F000443023B1D5F86401394635F0B5DE28461F
+:10C3000039461AF069DE00241CE02B6893F895305A
+:10C3100093B1D5F8000507A948F0DCDE06E05368C4
+:10C3200013F0005F1CBF23F00053536007A848F0D0
+:10C33000D9DE02460028F2D10124B474304616F04A
+:10C34000B3DEC246304600212FF048D905F5007112
+:10C35000284606311FF0E2DC2B6893F83F20A2B993
+:10C3600095F9473685F84226B3F1FF3F08BF85F8B7
+:10C370004326284619F0B2DA2B6893F8463013F0BA
+:10C38000030F02D0284619F0C5DA06F1BC00F6F317
+:10C39000E3F2014630B930460DF11602082300944D
+:10C3A000FFF766FB95F872323BB9D5F86C329E42C6
+:10C3B00003D13046FFF7C0FB05E0304611F07CD8D2
+:10C3C000304610F0DFDAD9F8641049B16868B9F87E
+:10C3D0006820FAF38DF40023C9F86430A9F86830B6
+:10C3E00002230DF11602009328463346002117F070
+:10C3F0002FD93046002117F0FDDA304617F066DA03
+:10C40000284605F081F8BAF1000F03D02846002134
+:10C410005A46D047B8F1000F01D0002013E0304653
+:10C420004146424632F0A8DB414606220398F5F326
+:10C4300007F606F1BC0041460622F5F301F6404638
+:10C4400001E04FF0FF3009B0BDE8F08F0DBB0000F8
+:10C450002DE9F04F062989B007460D4692469B46C6
+:10C460009DF848900468D0F8D86246D061BBB9F115
+:10C47000000F03D12046394633F098DB94F872322E
+:10C48000002B3AD0D4F8000507A948F023DE03E0DA
+:10C490001B7E13F0020F30D107A848F023DE0346BD
+:10C4A0000028F5D151E0236B186906F03FFBD7F85F
+:10C4B000D4325B8E834220D0204628F00DD8D4F8A9
+:10C4C000340728F027DC18E0B368093B012B14D8A7
+:10C4D0002046114649F062D910B10C2148F0B0DD78
+:10C4E000022D07D0A068316803F0B8D8052D01D01F
+:10C4F000012D02D14FF0010801E04FF00008139B1D
+:10C500000095CDF804B00293336C20460393736C0E
+:10C5100039460493B9F1000F0CBF07220922534694
+:10C5200010F0FCDAB8F1000F13D0052D01D0022D68
+:10C5300007D1B27F337F9A4203D238462DF0C0DF55
+:10C5400007E03846FFF772FB03E07368032BAAD1BC
+:10C55000D3E709B0BDE8F08F0048704760E70100FD
+:10C560000048704780E8010010B5836F40F2EE226A
+:10C570001C6A044B94219C4208BF4FF4166231F0B0
+:10C5800069DB10BD50200800816F10B508310446EA
+:10C590002FF06CDEFFF7E0FF014620462FF046DE6D
+:10C5A00010BDC0462DE9F04104460D469046BDF849
+:10C5B00018E09DF81C701E4633B18368DA6A02EBFE
+:10C5C0004102938BFB1893834FF6FF739E4503D074
+:10C5D000A821724631F03EDB04EB8503D868084B96
+:10C5E000414632465B6A9847002807DA36B1A368AD
+:10C5F000DA6A02EB4502938BDB1B9383BDE8F08183
+:10C60000E0A6850010B507490446406EF6F3E0F158
+:10C61000034620B9606E0449F6F3DAF10346184682
+:10C6200010BDC04699D501000AAA860070B50D4616
+:10C630000669144608460A220021F5F301F56B88C5
+:10C640001C43F36C6C8013F0200F03D02B8843F451
+:10C6500080632B80B16F42F250030A8C9A4206D15C
+:10C660004B8C052B03D86B8843F004036B8070BDA3
+:10C670004FEA810210B513188E468168DB6F52189D
+:10C680008367936B0B6390F8EB3063B190F8E830FD
+:10C690004BB94FF40051006EBEF1000F0CBF0A46BB
+:10C6A0000022FEF3BFF310BDB1F1FF3F2DE9F041D1
+:10C6B00004460E4605D1836F596A09B90E4600E05B
+:10C6C0009E6994F8E9701FB9204639462FF004DBC3
+:10C6D000206EFEF307F580B1002504EB8503D868D2
+:10C6E00010B1254B9B6898470135062DF5D1E368BD
+:10C6F0001BB1204600212FF03BDB94F8E8203AB133
+:10C70000A3680022DA612046032130F071DC30E0BA
+:10C71000206E46F0040184F8EA20FEF393F3A06F44
+:10C72000012184F8EA1018B1406A08B106F0D0F887
+:10C7300020462FF0F5DBE26E206ED2F8E0310121C9
+:10C7400023F02003C2F8E031F9F326F4002120465B
+:10C750002FF0C2DA204630F03DDD2046012130F0D6
+:10C7600011D9A2680023D3611FB9204602212FF0FE
+:10C77000B3DABDE8F081C046E0A6850070B50121BE
+:10C78000044631F0ABDA206E03F05CF8204600215D
+:10C790002FF0A2DA204630F0FDDE054630B120460B
+:10C7A000002131F09BDA6FF0080005E020464FF0E1
+:10C7B000FF31FFF779FF284670BDC04673B50469A5
+:10C7C000054620460E46FFF7DFFEA36F3146586A46
+:10C7D00007F0F6FB2A68012382F8743020462FF018
+:10C7E0007DDCA36F2046998A31F010D8A36F2046D4
+:10C7F000D98A30F0F9DF204694F886102FF0FED960
+:10C80000A36F204652219A8B31F024DAA36F502176
+:10C81000DA8B204631F01EDA20462FF081DC2046EC
+:10C82000FFF7A2FE032300932046042108220023E1
+:10C8300030F0F0DB20462EF0B1DF7CBD10B504698E
+:10C840004FF440412046002230F0D2DBD4F8F830DB
+:10C850001B691BB120462EF0A1DF02E020462FF01D
+:10C8600059DDE26C206E02F00202002A0CBF114674
+:10C870004FF400710A460023FEF384F310BDC04656
+:10C8800070B5836804461B6893F82050F5B9012100
+:10C8900031F024DA206E02F0D5FF204629462FF031
+:10C8A0001BDA20462FF036DDA068D0F848381B7818
+:10C8B0000BB12FF061DBA36F586A05F0FBFFA36893
+:10C8C00084F85E501A68012382F8203070BDC0469B
+:10C8D00070B5082986B005460C4602DD6FF00100F0
+:10C8E0002DE1836897491B685869F6F345F0082CD9
+:10C8F00024D12A6E936913F0005F03D0D36913F03B
+:10C90000010F0BD0EB6C13F0010F0BD02B6D13F05C
+:10C91000800F07D1D36913F0010F03D06B6D13F0B3
+:10C92000005F05D12B6D13F0800101D10C4612E0A0
+:10C9300043B2022B40F30181052400E05CB1D5F83D
+:10C94000F8305B68022B06DDAB6D13F0005F02D19F
+:10C950006FF00200F3E00A220DF10E000021F5F362
+:10C960006FF3D5F8F8304FF000021A8195F8903047
+:10C970000BB91E4604E0EB6ED3F8203103F001063C
+:10C9800095F8903053B164B9D5F8F8301B68002B96
+:10C9900000F0888028462FF0BDDC83E0002C00F0FA
+:10C9A0008180BDF80E30D5F8F82043F01003ADF8C3
+:10C9B0000E305368022B6B6D03D123F000536B656F
+:10C9C00039E043F0005314F0040F6B6503D1138971
+:10C9D00043F0140313812A6E936913F0005F03D0B0
+:10C9E000D36913F0010F0BD0EB6C13F0010F12D0D1
+:10C9F0002B6D13F0800F0ED1D36913F0010F0AD005
+:10CA00006B6D13F0005F06D0D5F8F820138943F062
+:10CA1000400313810FE0D5F8F8305B68042B05D193
+:10CA2000BDF8123043F40053ADF81230D5F8F820B9
+:10CA300000231361D360D5F8F8205368022B12D17C
+:10CA4000EB6C13F4804FBDF8103008D043F48073C2
+:10CA5000ADF810303023D3602023136103E023F4BA
+:10CA60008073ADF8103014F0020FD5F8F81003D031
+:10CA70000B8943F0010304E00A894FF6FE7302EAD2
+:10CA8000030314F0040F0B81D5F8F81003D00B89C1
+:10CA900043F0080304E00A894FF6F77302EA030340
+:10CAA0000B8109E0BDF80E3023F01003ADF80E3015
+:10CAB0006B6D23F000536B65D5F8F8301C60AB6FDD
+:10CAC000696D586A06F08AF995F890301BB116B175
+:10CAD000284630F033DF0224BDF80E30284600210E
+:10CAE0001022009430F096DABDF81030284601216B
+:10CAF0004FF48072009430F08DDABDF81230284681
+:10CB000021464FF40052009430F084DA28462FF08A
+:10CB1000A1D895F8903073B1AB6F1B68A34206D1D2
+:10CB2000D5F8F8301B6813B128462EF037DE16B161
+:10CB300028462FF05DDF002001E00124FFE606B06B
+:10CB400070BDC046C65C860070B5054690F8900082
+:10CB5000002846D0AB6F002185F89010586A05F088
+:10CB6000BDFEAB681A6992F8EA305BB1D36ED3F8B8
+:10CB7000202140F2044302EA0303B3F5806018BFAA
+:10CB8000012002E0106E02F05FFE68B10024AB6F7E
+:10CB900085F8EB4085F8EA40586A214605F098FE92
+:10CBA000A8682FF033D91BE0286EFEF39BF20446F1
+:10CBB00080B1EB6ED3F8203113F0010F02D028467C
+:10CBC00030F0BCDEAB689868F6F7F8FA0446284601
+:10CBD00031F0A2D895F8E81011B9284631F07ED886
+:10CBE000204670BD70B5054690F8900050B3AB6814
+:10CBF0001A6992F8EA305BB1D36ED3F8202140F283
+:10CC0000044302EA0303B3F5806418BF012403E080
+:10CC1000106E02F019FE0446AA6814B100231362D4
+:10CC20000CE0906802F056DD284621462FF054D8DB
+:10CC300095F8E83013B928462FF06CDBAB6F586AD3
+:10CC400006F014FB70BDC0460121836F10B580F85B
+:10CC500090100446586A05F041FE204602212FF04C
+:10CC60003BD8A368986802F03FDD002010BDC046A5
+:10CC70002DE9F3418668062733680DF10204DB696C
+:10CC800005461B6AD0F86C80C6F8AC3830493A4685
+:10CC90002046F5F371F16B6C2E48214603FB07002B
+:10CCA0003A46F5F369F10423C6F8AC38013B86F83F
+:10CCB000A938A8681EF0CAD808B93C4604E0D6F8DE
+:10CCC000AC389B0001339CB2D5F8B8700026F05DFB
+:10CCD00004F0FF01201880B2421E02F0FF0341EA77
+:10CCE000032102F48072C4F300231A43330243F495
+:10CCF000004301369BB2062EA8F840350446A8F83A
+:10CD00002015A8F82C25A8F84035E0D12846982110
+:10CD10007A7830F09FDFD5F8B83028469A219A7893
+:10CD200030F098DFD5F8B8302846DC781A789C21A6
+:10CD300042EA042230F08EDFD5F8B83028465C791C
+:10CD40001A799E2142EA042230F084DFBDE8FC819A
+:10CD500061DB0100301E02002DE9FF410569074635
+:10CD60009221284630F05CDC400080B2A7F84200F7
+:10CD700000282FD04FF000080DF101060F2130469A
+:10CD8000154A4346F5F3A0F1686E3146F5F320F6F7
+:10CD900060B13146686EB7F84240F5F3EDF504EB4B
+:10CDA000480482B22146284630F054DF08F10108D9
+:10CDB000B8F1770FE0D1686E0849F5F309F648B18C
+:10CDC000686E0649D5F8F840F5F3D6F52081284677
+:10CDD0002EF040DFBDE8FF81AEAC8600177C8600F8
+:10CDE0002DE9F041056986B04FF0FF31AC4A80462D
+:10CDF0002846EE6E30F0FCD8D5F8F8302846196891
+:10CE0000FFF766FDAB6D3BB14FF00303A6F8B436F8
+:10CE10004FF0FF03A6F8B836EB6C13F0010F27D0E4
+:10CE2000A04A136823BB012111602B6D286E13F0FB
+:10CE3000800F03D0023102F0BBFD19E002F0B8FD13
+:10CE40002B6D13F0005F13D12846922130F0E8DB00
+:10CE5000400080B260B100F1CE042146284630F097
+:10CE6000DFDB40F040022146284692B230F0F2DE8D
+:10CE70004FF0FF31C6F8281128468B4A30F0B8D859
+:10CE80008A4C03E00A20F9F367F40A3CD6F828310B
+:10CE900013F0010F01D1092CF4D14046D6F8283106
+:10CEA000FFF7CCFCD5F8F4302BB92B6E9A6A40F220
+:10CEB00094539A4213D1286E7D4B826BD318012B69
+:10CEC00007D94AF6E6039A4203D04AF6E5039A42A6
+:10CED00005D10823002128220093FDF3D7F7002174
+:10CEE0000A46286EFDF3B6F7FFF73AFB01462846DF
+:10CEF0002FF09CD92846FFF7BBFE4FF480330093F8
+:10CF00002846062398210DF10E022FF0CFDCD8F829
+:10CF1000003093F83830D3B140461DF097DF012838
+:10CF200015D100231C461F4605930AE04FF4C02389
+:10CF300000933946284605AA04232FF0DDDC01348E
+:10CF40002437D8F80030DB691B6A9C42EED32846B0
+:10CF50008021082230F07EDE28465C210A2230F053
+:10CF600079DE4FF08073534AC6F8003128465249A3
+:10CF700030F03ED84FF00043C6F8883103F1024349
+:10CF8000C6F88C314FF48043C6F8283103F540438E
+:10CF900073620121284630F019D8286E02F0A0FCF7
+:10CFA00083B2A8F818001621A6F8A8362846B5F8C6
+:10CFB000442030F04FDE2846C021B5F8542030F030
+:10CFC00049DE2846C221B5F8562030F043DE3B4BFF
+:10CFD0002846C6F86031D6F86031B5F8883044216B
+:10CFE000C6F86431364BB5F88C20C6F86031D6F8F7
+:10CFF0006031B5F88A30C6F8643130F02BDE28464F
+:10D000004621B5F88E2030F025DEB6F888361B05AF
+:10D010001B0DA6F888364FF00103A6F89C360023B6
+:10D02000C8F848301C4605EB8403D86810B1254B7E
+:10D030005B6898470134062CF5D1224CE868236DD3
+:10D040009847E36EE86898474046FFF785FE2B6EE9
+:10D050009A6B4AF662139A421ED1EB6C13F0010FE1
+:10D060001AD02B6D13F0800F16D113F0005F13D17F
+:10D070002846922130F0D4DA400080B260B100F14D
+:10D08000CE042146284630F0CBDA40F0400221465B
+:10D09000284692B230F0DEDD06B0BDE8F081C04631
+:10D0A00004040004F02702000204020449420F00B5
+:10D0B0001D57FFFF0000024000000640060002006E
+:10D0C00007000200E0A685002DE9F04790F8E9701E
+:10D0D00004460E469046856817B939462EF0FCDDA9
+:10D0E000A86802F0F7DA06F47041B1F5805F14BF6A
+:10D0F0000021012181462046FFF7BAFAA36F31468D
+:10D10000586A05F00FFDA36F586A05F0EDFB28463D
+:10D11000FFF766FEB8F1000F04D0012120460A4651
+:10D120002FF0D4DF28463146FFF748FBA868494670
+:10D1300002F0E4DAD4F8D43043F00403C4F8D43075
+:10D140000123C4F8D0301FB9204602212EF0C4DDDF
+:10D15000BDE8F087816810B50B680446D3F88C20D1
+:10D16000D2F8B4300133C2F8B4300A6992F8EA3028
+:10D1700063B1D36ED3F8202140F2044302EA0303E3
+:10D18000B3F5806F14BF0020012006E0106E02F09E
+:10D190005BFBD0F1010038BF002020B120464FF0EA
+:10D1A000FF31FFF781FAA0682EF030DEA06819F099
+:10D1B0008BDC10BDD0F8EC1010B5044631B100681E
+:10D1C0000C22F9F395F50023C4F8EC3010BDC046ED
+:10D1D0002DE9F04FD1F8D43289B0B3F832A0D0F8AD
+:10D1E0004C31804603938B798946D0F80CB0002BE4
+:10D1F00000F0B58000273E4608EB8603D3F84C527A
+:10D200008DB1AB797BB9EB796BB1D5F8D432588E4F
+:10D21000F6F308F004465046F6F304F0844201D0D9
+:10D220002F4606E02F460136082EE5D1002F00F0EC
+:10D230009680D7F8D432588EF5F3F4F7044650466A
+:10D24000F5F3F0F7844205D0D7F8D432D9F8D422D8
+:10D25000DB8DD385404605A904AA18F08BDF39463B
+:10D26000D8F84C0141F0E2DF182300FB03F4D8F8B2
+:10D270004C0104F13A0142F0C3DC38B9049A059B31
+:10D28000039839460092019301F0DCFA04F1400161
+:10D29000D8F84C0142F0B4DCD7F8D4320599DB8DD4
+:10D2A00040019E02CE42079001D3B04209D321F043
+:10D2B0007F4323F460038219984201D21046F6E7B7
+:10D2C000079006AC07AD22462B46049803F0FAFC03
+:10D2D000384618F0E5D929460346002220461DF0BD
+:10D2E000EDDDD9F8D4327608DB8D29469F02204641
+:10D2F000334600221DF0FCDD3B46012101E049469A
+:10D300001346DA19B34201F10109F8D306A807A9B7
+:10D31000002204AC05AD1DF0EBDD20462946069A3F
+:10D32000079B1DF0E5DD059B2046CBF88031049B73
+:10D330002946CBF88431002304930593069A079B72
+:10D340001DF0D6DDD8F84C010499059A42F010DFA3
+:10D35000BB01CBF8883107FB09F3CBF88C3109B05E
+:10D36000BDE8F08F2DE9F34100EB8101D1F84C428B
+:10D37000064690461D469DF8207014B94FF0FF33C5
+:10D3800019E004F11A0000212022F4F359F60023D9
+:10D39000637615B9336803F14E054346304621469E
+:10D3A0002A46009730F09ADF034620B930462146DE
+:10D3B00032F0E8D803461846BDE8FC81D1F8CC30FD
+:10D3C00073B543F40053C1F8CC3005460C4632F037
+:10D3D000D9D80646002840F08880B5F8822144F26A
+:10D3E00021339A421AD00E3B9A4217D007339A4201
+:10D3F00014D010339A4211D0143B9A420ED0073306
+:10D400009A420BD010339A4208D025339A4205D065
+:10D41000AB6B5B7D13B96FF00B0666E02B6B93F87B
+:10D42000EC300BB91E4608E0B5F8263603F440632D
+:10D43000B3F5406F14BF142628262B6893F84630A6
+:10D4400013F0030305D0D4F8CC30C3F3003383F0DA
+:10D4500001030093284633462146022231F024DAA4
+:10D460000646002841D1D4F8CC3013F4803F0AD1CD
+:10D47000D5F84C01214641F0E1DFC4F8F00280B953
+:10D480006FF01A0631E0062204F1BC0004F1C2017B
+:10D49000F4F372F5D4F8D432B5F8262683F8346064
+:10D4A0005A86A379D3B194F8F532312B11D82B6871
+:10D4B0001B7E2BB1284694F8F4120D4A1BF0B6DF00
+:10D4C000D5F84C0194F8F41241F0FCDE322384F8D4
+:10D4D000F43294F8F53284F8F43206E0D5F84C01D1
+:10D4E00004F53D7141F0B2DE064630467CBDC046D3
+:10D4F000329E85002DE9F041054632F041D90026E3
+:10D500000746AB19D3F84C426CB1A3795BB1BC426E
+:10D5100009D063791BB12846214631F0B1DC284699
+:10D52000214631F089DF0436202EEAD1BDE8F081B2
+:10D53000002010607047C04610B505F021F810BDFE
+:10D5400010B504F05DFFC0B210BDC04610B508466E
+:10D55000114604F037FF10BD2DE9F0470446884618
+:10D560004768002110469146C922F4F369F5204628
+:10D57000414638F013DF78B997F85037002B00F0A8
+:10D58000D08707F5AA6138460E3138F061D90646D2
+:10D59000002800F0C68700E0266908F47043B3F560
+:10D5A000805F14BF38233C233078FF5804F0D0FF4D
+:10D5B0000446B07804F0B4FF637C5FFA88F513F09A
+:10D5C0000102064602D097F904E106E097F904311A
+:10D5D000182BD4BF9646A3F1180E934B9C4203D14F
+:10D5E00058214FF0520C0BE0904B9C4205D0904BD1
+:10D5F0009C4202D04FF07F0C01E04FF0580C614686
+:10D600003B68022B5FD1012D01D8002303E00A2DD6
+:10D610008CBF02230123E31893F90620854B9C421B
+:10D6200003D10B2D10D14C2240E0834B9C4203D1FF
+:10D630000E2D3BD1362239E0804B9C4202D0804BEC
+:10D640009C4204D10B2D30D00E2D2ED02EE07D4BE0
+:10D650009C4203D10E2D29D12A2227E07A4B9C42ED
+:10D6600007D1022D01D1582220E00A2D1ED15422CB
+:10D670001CE0764B9C4203D10A2D17D1502215E0B5
+:10D68000734B9C4203D10E2D10D128220EE0714B1A
+:10D690009C4203D10B2D09D13E2207E06E4B9C42E8
+:10D6A00004D10C2D02D1442200E04022CEEB020333
+:10D6B00023EAE3738B42A8BF0B46002202F809302D
+:10D6C0000132042AFAD1654B9C4208D0644B9C423B
+:10D6D00005D0644B9C4202D0634B9C4207D197F922
+:10D6E0000431182BD4BF4FF0000EA3F1180E3A6886
+:10D6F000022A40F01081012D01D8032303E00A2DF6
+:10D700008CBF05230423E31893F90600494B9C4280
+:10D7100001D10B2D6CE0554B9C4204D1022D00F041
+:10D720000E810A2DCFE0444B9C4201D10B2D58E0D5
+:10D73000424B9C4202D0424B9C4201D10B2D11E046
+:10D740004B4B9C4202D04B4B9C4204D10D2D40F0E0
+:10D7500007812E2004E1484B9C4206D10B2D00F09E
+:10D76000F2800D2D00F0F380FAE03E4B9C4258D041
+:10D77000344B9C4204D10B2D40F0F2803E20EFE070
+:10D78000314B9C4219D0314B9C4206D1022D00F006
+:10D79000E4800A2D00F0E180E2E0384B9C4206D1A3
+:10D7A000022D00F0D8800A2D00F0D580D8E0344B4F
+:10D7B0009C4202D0334B9C4206D1022D00F0C9801E
+:10D7C0000A2D00F0C680CBE02F4B9C420CD1022DDD
+:10D7D00000F0BD800A2D00F0BA80032D00F0BF805C
+:10D7E000092D00F0BC80BBE0284B9C4203D10A2DE0
+:10D7F00000F0A780B4E0164B9C4205D1A5F10C03C4
+:10D80000012B40F2A280ABE0214B9C4203D10B2DB7
+:10D8100000F29D80A4E01F4B9C423DD10C2D00F0F6
+:10D8200096800D2D75E0C046BC108600F010860075
+:10D8300024118600400986002CDC0100BC0C860007
+:10D84000D00C8600700D86007C0986009009860049
+:10D85000840D8600DCDC010094DE0100340D8600BE
+:10D860005C0D860080118600FC0D860080DE0100C4
+:10D87000E40C86000C0D8600FCE30100CC09860058
+:10D88000A4098600B8098600F409860018098600F4
+:10D89000980D8600381186008C4B9C4203D1022DD6
+:10D8A00055D00A2D26E08A4B9C4231D0894B9C42B0
+:10D8B00003D10B2D54D1322052E0874B9C4204D12E
+:10D8C0000B2D40D00C2D3AD04AE0844B9C4205D120
+:10D8D0000C2D44D00D2D43D13A2041E0804B9C4289
+:10D8E00004D1A5F10B03012B29D939E07D4B9C42D2
+:10D8F00002D10B2D29D033E07B4B9C4205D10C2D5E
+:10D900002BD00D2D2CD144202AE0784B9C4227D1DE
+:10D910000B2D18D024E0332D01D800200BE03D2D35
+:10D9200001D8012007E0632D01D8022003E0942DE7
+:10D930008CBF04200320231893F9060010E04A202E
+:10D940000EE042200CE038200AE03C2008E04020B5
+:10D9500006E0502004E0482002E04C2000E0462091
+:10D96000CEEB000323EAE3736345B4BF1846604679
+:10D97000022A04D199F800309842A8BF1846002224
+:10D9800009EB02030132082A1871F9D1C0B2CC4662
+:10D990004A4600210023013182F83430107382F8A6
+:10D9A0003C3001320829F5D1337F13F0010202D057
+:10D9B00097F9040106E097F90431182BD4BF1046FB
+:10D9C000A3F118003B68022B01D16B1E0FE0332D31
+:10D9D00001D800230BE03D2D01D8012307E0632D82
+:10D9E00001D8022303E0942D8CBF04230323F256B5
+:10D9F0009B19997B3E4B9E4205D1A5F16403022BF6
+:10DA000001D83E2110E03B4B49B29E4203D1642D28
+:10DA100000F05C850BE0384B9E4205D1A5F1640314
+:10DA2000022B01D83E2108E0344B9E420ED0344BED
+:10DA30009E420BD0334B9E4208D0334B9E4205D0C2
+:10DA4000324B9E4202D0324B9E4214D1A5F1680364
+:10DA5000242B10D82B4B9E421BD02B4B9E4218D010
+:10DA60002B4B9E4215D0264B9E4223D0274B9E42E5
+:10DA700020D044224A21274B9E420CD1A5F16803B5
+:10DA8000202B03D98C2D00F03F8549E04422402112
+:10DA900001E042224A21204B9E420DD1642D06D046
+:10DAA000A5F168030C2B3BD840223C216CE04022BE
+:10DAB000342101E044210A46184B9E4230D1A5F1A1
+:10DAC0006403102B2CD85222422160E068098600A2
+:10DAD000DCDC0100B4DC010010DD010094DE01009B
+:10DAE00014E10100A8DE0100BCDE0100C8DC010079
+:10DAF000B50886005BE30100D2088600DC058600DD
+:10DB00002E0586004B058600680586008505860083
+:10DB100033068600F90586006D0686008A068600B3
+:10DB20009C4B9E421AD1A5F16403082B98BF30216B
+:10DB3000A5F16E0398BF3422162B98BF4621A5F19C
+:10DB40008603022B98BF3E218C2D08BF3622A5F1FB
+:10DB5000950308BF48210F2B98BF44228E4B9E424D
+:10DB600012D1A5F16E03162BA5F1860398BF3A22B8
+:10DB700098BF4421022B98BF3A2298BF3E218C2D9A
+:10DB800008BF362208BF4821844B9E4202D0844BF6
+:10DB90009E4204D1A5F18403082B98BF2C22814B0F
+:10DBA0009E4202D1262D08BF2C21C0EB020323EA9E
+:10DBB000E377C0EB010323EAE37E4A4613790021B1
+:10DBC000137582F8441009F1080301329A42F5D125
+:10DBD0004B460A4601321F7783F84CE00133082A8E
+:10DBE000F8D1714B9E425BD0704B9E4258D0704B27
+:10DBF0009E4255D06F4B9E4252D06F4B9E424FD0AB
+:10DC00006E4B9E4236D06E4B9E4249D06D4B9E422B
+:10DC100046D06D4B9E4243D06C4B9E4240D06C4BE5
+:10DC20009E423DD06B4B9E423AD06B4B9E423DD0C4
+:10DC30006A4B9E4234D06A4B9E4231D0694B9E4221
+:10DC40002ED0694B9E422BD0684B9E4228D0684B09
+:10DC50009E4225D0674B9E4222D0674B9E421FD0EA
+:10DC6000664B9E421CD0664B9E4219D0654B9E422D
+:10DC700016D052E0032D02D14FF03C0E0FE02B1FC7
+:10DC8000042B0AD9092D00F04384A5F10C03012BC4
+:10DC900000F217842C2700F015BC4FF0400E4027EF
+:10DCA0004D4B9E4202D04D4B9E4207D1EB1E082B9E
+:10DCB00094BF4FF0400E4FF0000E4027524B9E4253
+:10DCC00022D1A5F124030C2B03D838274FF0300EB6
+:10DCD0001AE0A5F13403082B03D84FF0440E774621
+:10DCE00012E0A5F16403022B03D834274FF03E0E57
+:10DCF0000AE0A5F16803202B03D844274FF04A0E11
+:10DD000002E08C2D08BF32274B46002201321F75DE
+:10DD100083F844E00133082AF8D14B460022002161
+:10DD2000013283F8241083F854100133082AF6D105
+:10DD30004B460A46013283F82C7083F85CE00133CD
+:10DD4000082AF7D1184B89F864E09E4206D0174B99
+:10DD50009E425BD0174B9E4270D0CEE0012D00F06A
+:10DD6000A780022D00F09980032D00F0A6802B1FC4
+:10DD7000042B04D84C273C2338243E21A1E0092D54
+:10DD800001D14C2750E00A2D00F087800B2D00F0C8
+:10DD90008F808EE0A2058600BF0586002C078600D6
+:10DDA000F40486002CE201007E0A86009B0A8600AD
+:10DDB000B80A8600F20A8600BD0B8600980E86001F
+:10DDC00040DC01006AE0010097DC010046DE010052
+:10DDD00001DF0100E4DE0100630F860014108600FD
+:10DDE000B50E860024DD010041DD0100D2DD010019
+:10DDF000EFDD01005DDC01007ADC01000CDE0100DA
+:10DE000029DE0100880C8600DC058600012D4FD03C
+:10DE1000022D44D0032D01D14C2743E02B1F042BAE
+:10DE20004BD9092D04D14A2734233024362148E028
+:10DE30000A2D34D00B2D3CD136273AE0012D01D1EB
+:10DE40002C2736E0022D31D0EB1E052B18D8032DE0
+:10DE500004D144272C2328242E2132E0042D20D065
+:10DE6000082D1ED06B1F022B4FF044078CBF0023E0
+:10DE700038238CBF002434248CBF00213A2120E0B9
+:10DE8000092D04D142272E232A24302119E00A2DFE
+:10DE90000CD00B2D0DD12A270BE0402709E03E279F
+:10DEA00007E044273623322438210AE03C2700E0EB
+:10DEB000382700231C46194603E04C273823342416
+:10DEC0003A214A460020042894BF82F84C4082F848
+:10DED0004C300130177701320828F4D1FCB24A46A1
+:10DEE0000020032894BF82F85C3082F85C10013077
+:10DEF00082F82C4001320828F3D1A74B9E4206D06D
+:10DF0000A64B9E420DD0A64B9E4221D062E0032D2F
+:10DF100045D0092D43D02B1F042B38D83024342270
+:10DF200033E0032D03D14224462248203AE0042D59
+:10DF300031D06B1F022B03D84C245022522031E0E9
+:10DF4000082D28D0092D22D13E244222442029E048
+:10DF5000032D03D12E243022322023E0042D03D1BF
+:10DF60003024322234201DE06B1F022B03D83224D0
+:10DF700036223A2016E0082D03D1302434223820EE
+:10DF800010E0092D03D12E24322236200AE000228F
+:10DF90001446104606E046244A224C2002E028247B
+:10DFA0002C222E204B460021042994BF83F84C409C
+:10DFB00083F84C20013101330829F5D14B4600216B
+:10DFC000032994BF83F85C2083F85C00013101339E
+:10DFD0000829F5D1734B9E422AD1032D0CD02B1F5B
+:10DFE000042B03D838203C213E2408E0092D03D01F
+:10DFF000002108460C4602E0342038213A244B46E2
+:10E000000022042A94BF83F84C0083F84C1001329C
+:10E010000133082AF5D14B460022032A94BF83F826
+:10E020005C1083F85C4001320133082AF5D134E0FA
+:10E030005D4B9E422AD1A5F124030C2B01D8382731
+:10E0400004E0A5F134030C2B03D83A274FF0340E2B
+:10E0500012E0A5F16403282B03D83C274FF0400EB3
+:10E060000AE0A5F19503102B8CBF002746278CBF33
+:10E070004FF0000E4FF0480E4B46002201321F7544
+:10E0800083F844E00133082AF8D10AE0474B9E4266
+:10E0900069D0474B9E4200F0DF80464B9E4200F025
+:10E0A000DB80454B9E4200F0D780444B9E4200F0FF
+:10E0B000D380434B9E4200F0CF80424B9E4200F003
+:10E0C000CB80414B9E4200F0C780404B9E4200F007
+:10E0D000C3803F4B9E4200F0BF803E4B9E4200F00B
+:10E0E000BB803D4B9E4200F0B7803C4B9E4200F00F
+:10E0F000B3803B4B9E4200F0AF803A4B9E4200F013
+:10E10000AB80394B9E4200F0A780384B9E4200F016
+:10E11000A380374B9E4200F09F80364B9E4200F01A
+:10E120009B80354B9E4200F09780344B9E4200F01E
+:10E13000F481334B9E4200F08F80324B9E4200F0C0
+:10E140008E80314B9E4200F08780304B9E4200F023
+:10E1500083802F4B9E427FD02E4B9E427CD02E4BF5
+:10E160009E4271D0B5E0A5F12403082B02D84FF0F0
+:10E17000380E67E0A5F12E03022B40F29880A5F13E
+:10E180003403082B01D8382792E0A5F13E03022B77
+:10E1900044D8342747E0C046D50A8600A00B860045
+:10E1A000DA0B86004E0C860011058600F905860004
+:10E1B00049E2010066E20100A9E301001EDF01005F
+:10E1C0004DE0010013E0010098DD0100D8E00100FE
+:10E1D000F0DC0100F6DF0100F5E001008CE3010056
+:10E1E00075DF010083E2010030E001000CDC01007A
+:10E1F000BCDF01005BE30100DCE3010063DE010042
+:10E200005EDD01007BDD01003EE30100D9DF01009E
+:10E210003BDF010058DF010016068600A5F164030C
+:10E22000082B03D844274FF0380E49E0A5F16E03C0
+:10E230001E2B01D832273BE0A5F19503102B36D9D0
+:10E240004FF0000E77463BE0A5F124030C2B37D8A6
+:10E2500038274FF0340E33E09E4B9E4201D1242DDF
+:10E260005CE19D4B9E4203D18C2D29D13A2727E0BA
+:10E270009A4B9E4204D1642D1FD08C2D1DD01FE0DF
+:10E28000974B9E4203D1A5F19503102B0DE0954BC2
+:10E290009E4215D1A5F124030C2B10D9A5F134030E
+:10E2A0000C2B0CD9A5F16403282B08D908E04427CE
+:10E2B0004FF0400E04E0382702E0482700E03C27FA
+:10E2C0004B46002201321F7583F844E00133082ACF
+:10E2D000F8D1854B9E420BD0844B9E4208D0844B94
+:10E2E0009E4205D0834B9E4202D0834B9E426DD10D
+:10E2F000A5F12403082B0DD87F4B9E4201D13A2073
+:10E3000006E07E4B9E4202D13420014655E0342087
+:10E31000382152E0A5F12E03022B08D8774B9E42FC
+:10E3200014BF3821342114BF4220402045E0A5F11C
+:10E330003403082B02D8462144203EE0A5F13E03D9
+:10E34000022B06D86D4B3A219E4214BF34202C205C
+:10E3500033E0A5F16403082B06D8684B3E209E42AB
+:10E3600014BF44213A2128E0A5F16E031E2B17D8D3
+:10E37000A5F18603022B09D85F4B9E4201D14420B0
+:10E3800005E05E4B9E4201D13C2000E048208C2DF0
+:10E3900010D1594B9E420FD0584B9E420CD009E0F1
+:10E3A000A5F19503102B8CBF002146218CBF0020C6
+:10E3B0004A2002E0442100E03C214B460022013289
+:10E3C000197583F844000133082AF8D14C4B9E425A
+:10E3D00002D04C4B9E421ED1A5F124030C2B01D838
+:10E3E00038210EE0A5F134030C2B09D9A5F1640303
+:10E3F000282B05D9A5F19503102B01D9002100E0A8
+:10E40000402108464B4600220132187583F844101B
+:10E410000133082AF8D14846002202EB090191F89D
+:10E420003C301BB990F84C3081F83C304AB999F82F
+:10E430003D300BB1013204E090F84C30012289F8F4
+:10E440003D3001320130072AE7D94A46002192F8CF
+:10E4500044301BB992F84C3082F84430013101321B
+:10E460000829F4D14846002202EB090191F8343022
+:10E470001BB990F8443081F834304AB999F83530F6
+:10E480000BB1013204E090F84430012289F83530B4
+:10E4900001320130072AE7D900229CF824301BB949
+:10E4A0009CF81C308CF824309CF854301BB99CF834
+:10E4B0004C308CF854300132082A0CF1010CECD1AC
+:10E4C0002FE040274FF0000EFFF7F8BB3822FFF790
+:10E4D000ABBAC0467BDD01003EE301003BDF01003B
+:10E4E000F6DF01008CE301004B058600680586001D
+:10E4F0008505860033068600A2058600BF058600D6
+:10E50000A70686005006860036210A46FFF708BB9C
+:10E5100040274FF0380EFFF7C3BB642D3FF4CBAE5E
+:10E52000CEE6BDE8F087C0462DE9F041069D0746DE
+:10E530000E4610461946002A4ED0002B4CD0002D16
+:10E540004AD0B30A012B3FD914790EF031FEE40909
+:10E5500001460023384622460FF046D895F8651547
+:10E56000012911D195F86725531C0F2A85F86735C5
+:10E5700032D90023C5F86865064685F8653585F803
+:10E58000661585F8673527E095F8662532B90123C9
+:10E59000114685F86635C5F8686513E0D5F8683525
+:10E5A000F11A09D48B12012B06D995F86725531C53
+:10E5B0000F2A85F8673505D9002385F86735C5F832
+:10E5C000686519460E1807E0012385F86535013B9B
+:10E5D00085F8673585F866353046BDE8F081C04678
+:10E5E0002DE9F3410A9D0B9E9846002304463360B3
+:10E5F00017462B600846D9B18B784A781B0443EA4A
+:10E6000002230A781343CA78043143EA0263336071
+:10E610008B784A781B0443EA022302791343CA78B1
+:10E6200043EA02632B60427A037A53EA022001D163
+:10E630004FF48060296832680EF0A2DE0C9B014620
+:10E6400000933A4643462046FFF76EFF04463146A4
+:10E650002846002223461CF04BDC0898099900222A
+:10E6600023461CF045DCBDE8FC81C046F0B50768D8
+:10E670001C460E4687B019463846154617F07ADD17
+:10E680002268D6F8A0309A4202D22B68013B2B6058
+:10E69000D6F8A030002223600C9B384602930D9BD5
+:10E6A000716E03931346009501940492FFF798FF4F
+:10E6B00007B0F0BD2DE9F04F8A460668002189B009
+:10E6C000834690461F4689460D460791069105915F
+:10E6D000029103912BE063789D1C029B43B907AB29
+:10E6E0000093304621462A4602233EF017DD029071
+:10E6F000B9F1000F08D106AB0093304621462A46F7
+:10E700000D233EF00BDD8146039B43B905AB00931F
+:10E71000304621462A4610233EF000DD0390C5EB2B
+:10E7200007031B1B03EB080704EB05080125404604
+:10E730003946F4F3B7F504460028CCD1304607A992
+:10E740003EF036D8304606A93EF032D8CDB1DAF8E0
+:10E75000083043F04003CAF80830029B9BB1B9F17E
+:10E76000000F01D1039B73B1DBF810305AF803306E
+:10E770003BB9584651463DF0FFDE10B16FF01A002C
+:10E7800003E0002001E04FF0FF3009B0BDE8F08F5A
+:10E790002DE9704F066886B08B46104619469046A4
+:10E7A0009A460F9C109D0EF003FD014630460EF078
+:10E7B000F9DE41468146224630462B4617F002DDFF
+:10E7C0002046294600224B461CF078DB119B304640
+:10E7D0000293129B0E99039342465346009401956F
+:10E7E000CDF810B0FFF7FCFE06B0BDE8708FC04654
+:10E7F00043682DE9F04106460C4617460568F3B11B
+:10E8000099421CD12B681B7E73B1284691F8F412F3
+:10E8100004F1C2021AF00ADE7368212293F8F4129E
+:10E82000284613461AF00CDEF37B022B07D13B6817
+:10E830002BB9384606F114012422F3F39DF3BDE809
+:10E84000F081C0462DE9F7430A9C0B9D0F46814697
+:10E85000164698460094019540F00ED94346484626
+:10E86000394632460094019540F0F4D901224846D9
+:10E87000394640F0D7D9B7F8343513F0100F03D02C
+:10E88000484639463EF008D8BDE8FE8370B58B791E
+:10E8900006461546002B2DD0D1F8CC3013F4005F7E
+:10E8A00028D0107828B15378092B02D86FF00100D6
+:10E8B00024E0D1F8F042237F834204D1E8B1627FA3
+:10E8C0006B789A4219D020776B786377638843F02E
+:10E8D000020313F0080F63800FD0304621463EF04C
+:10E8E00063DD304621463EF043D9304621463EF0B6
+:10E8F000BBDE02E04FF0FF3000E0002070BDC046FC
+:10E900002DE9F743D0F8009004460027E31993F867
+:10E910003B80B8F1FF0F4CD0FD0000262046294671
+:10E9200041F06ED9002840D020462946002241F00F
+:10E9300085DE4846414601AA30F0A0DC002834D0EC
+:10E94000D0F8F01221B9002E2FD10EF059D92CE0B9
+:10E95000837933B1D0F8CC3013F4005F01D0037960
+:10E960001BB34B8813F0080F1FD0032E1DD8DFE810
+:10E9700006F002060F1620463EF0C8DE15E013F042
+:10E98000020F12D00B7F83B120463EF0FBD80CE083
+:10E9900013F0010F09D020463DF0AEDF05E013F083
+:10E9A000010F02D020463FF035DA01360235042E41
+:10E9B000B4D10137042FA9D1BDE8FE832DE9F3417D
+:10E9C000D0F8008007463EF021D9AE21404617F02E
+:10E9D000C7DB4000B8641421404617F0C1DB262491
+:10E9E000A7F84C0021464046284A1AF01FDD214670
+:10E9F000002340464FF6FF7201341AF021DD322C1D
+:10EA0000F0D126E0294600223846013441F016DED6
+:10EA100002350C2CF6D118369A2E1BD11DE0294652
+:10EA200000223846013441F009DE0235042CF6D1CB
+:10EA30000836202E12D114E029460022384601342F
+:10EA400041F0FCDD0235042CF6D10836BA2E09D18E
+:10EA50000BE03A2635460024D4E70026354600244C
+:10EA6000DDE79A2635460024E6E7384620210022D5
+:10EA700041F0E4DD032310220093404604211346B5
+:10EA800015F0A2D80020BDE8FC81C046329E85006A
+:10EA9000F0B50E4649691569908A0A68002A01DABC
+:10EAA000821831D44C68131983422DD8B36801F110
+:10EAB000080C0CEB040705EB020E6BB9184608E0D6
+:10EAC00010F80E3010F80C20C15D134099421BD194
+:10EAD0000130A042F4DB19E0012B15D12B18C4EB57
+:10EAE00003050DE010F80E3010F80C20C15D134046
+:10EAF000994203D10130A042F4DB07E00EF1010E90
+:10EB0000AE4501D80020F6E7002000E00120337B6D
+:10EB10000BB180F00100F0BD036870B50446586881
+:10EB2000A36A0D46164623B99021F8F3D1F0A062EE
+:10EB300070B1A06A0123AA8A03607F3382604660B5
+:10EB4000C360296910309A4228BF1A46F3F314F2C1
+:10EB500070BDC04668468369416920300BB52038D6
+:10EB600003695A4651460EB44A46414606B4C36844
+:10EB700082684168FEB40368C269EFF303810EB492
+:10EB80008269EFF3058106B4034801680029FED0CD
+:10EB90006846884714B000BD3CEC00000A490842B2
+:10EBA00002D062B6C94308400849084202D061B6A3
+:10EBB000C943084006490840002803D005490A68AF
+:10EBC00002430A607047000000000080000000401F
+:10EBD000FFFF000000E100E00A49084202D072B6DF
+:10EBE000C94308400849084202D071B6C9430840E9
+:10EBF00006490840002804D005490A68C04302407D
+:10EC00000A6070470000008000000040FFFF000025
+:10EC100080E100E0024909689022885870470000AE
+:10EC200048EC0000024909689C22885070470000A7
+:10EC300048EC0000DDBAADBB0000000000000000A1
+:10EC400000000000000000000000000000000000C4
+:10EC50000000000000000000024A11681060081C5B
+:10EC6000704700003CEC0000024A11681060081C6C
+:10EC70007047000040EC0000034908600348016849
+:10EC80000029FED08847FEE734EC000040EC00008D
+:10EC90006348644900220A500168634A0A40634F8E
+:10ECA0000F403F4232D1002398469A46604A0A40BC
+:10ECB0001821CA405F4943585F4C1C405F4DAC422D
+:10ECC00004D180465E4D4519A9460EE05D4DAC422B
+:10ECD0000BD182465A4D4519AB460F241D1C2340CB
+:10ECE000594C25402D0A2B439C460023984501D0C2
+:10ECF0009A4504D1554BC018013ADCD105E0504685
+:10ED0000004202D04046004229D1FEE7FC21415892
+:10ED10000A680F2313400F2BF1D0012B01D00431CF
+:10ED2000F6E708314A4B13404A4CA34206D100F0A3
+:10ED3000BBF8804600F0C4F88146E9E7464CA342A0
+:10ED4000E6D10B1F1B68454C23401824E3409C462A
+:10ED500000F0AAF8824600F0B3F88346D8E74049AD
+:10ED6000212242502E4A3F498958FF23194219D087
+:10ED700051683D4B194215D011683C4B1940D36A7C
+:10ED800010E0A3420ED0C0460CE039498958194220
+:10ED900008D03849895819409942FAD12B4B11694A
+:10EDA0001942FCD049463F4204D19823CB58102445
+:10EDB000E34001E0304BCB581C242340002B01D012
+:10EDC00000F08CF840462D49086048462C49086000
+:10EDD00050462C49086060462B4908602B490F605B
+:10EDE0002B4D2C490D60043DAD46009DEC43102396
+:10EDF000DD41AC4201D081B009E0240CA400264DD5
+:10EE00002C606B461B1B254D2B60043B9D46244804
+:10EE10002449002204C08142FCD80EF0E5FAFEE746
+:10EE20000000001814060000F8FF0000000000F0C9
+:10EE30000000000FFC0F0000F08F0000A082000017
+:10EE4000000F0000E08000000070000000100000D3
+:10EE500000FF0F00002A0800000E0800000000FF5D
+:10EE6000E00100000406000000003800FFFF000081
+:10EE7000180600000C0600000804000048EC000022
+:10EE80004CEC000050EC000054EC000044EC00009E
+:10EE900000C00300F81E0200001F0200FC1E02005A
+:10EEA000AC270200182C020008680F22043102402F
+:10EEB000052AF9D1014A1040F746000000F0FFFF93
+:10EEC00008680F2204310240052AF9D1802210423D
+:10EED000F6D0014A1040F74600F0FFFFFEE70000C1
+:10EEE00010B57146034802F0DFFB40F61100FFF752
+:10EEF000C3FE10BD8E1F860010B5002128220446D7
+:10EF0000F3F39EF00A4B23600A4B63600A4BA36045
+:10EF10000A4BE3600A4B23610A4B63610A4BA3610E
+:10EF20000A4BE3610A4B23620A4B636210BDC04681
+:10EF300000000000C71D0200C81D0200AC2702002F
+:10EF4000AC270200182C0200182C020021D202006B
+:10EF500024D20200005903002DE9F04399B00CA817
+:10EF6000FFF7CAFF0C9B0D99DFF8DC91C91A0F9DC2
+:10EF70000E9BD9F80060ED1A119C109B06F5A05667
+:10EF80006048E41A76180B9102F08EFB0B9905F598
+:10EF90007E7376190733361901F57E729B0A019448
+:10EFA00004F57E740732009307340523A40A920AFD
+:10EFB000039355482B460294DFF8848102F074FBDA
+:10EFC000524BD8F800401968D9F80050C4EB01033F
+:10EFD00003F57E7001F57E7207300194039504F508
+:10EFE0007E7405F57E75800A073207340735920A6C
+:10EFF0000090A40AAD0A46480294049502F054FB1E
+:10F00000444B45481968D8F80030C91806F57E7396
+:10F0100001F57E7207339B0A0732920A009333464A
+:10F0200002F042FB3D4B3E48196802F03DFB3D4B70
+:10F030001F683D4B3A689A4203D03C4802F034FBCB
+:10F0400024E0179705E03268374B9A4205D1331D0B
+:10F050001793179E16AB9E42F5D3354BC7EB0600B0
+:10F060001A6817ABC7EB0301C3EB0204C6EB02053A
+:10F070000092019102910390049039462D48324646
+:10F08000059406940795089502F00EFB2A4C20681B
+:10F09000002834D0C588F3F363F52368013D5C890B
+:10F0A0004FF4806104FB05F6443405FB04F406F5D7
+:10F0B0007E73073393FBF1F3009304F57E730733FC
+:10F0C00093FBF1F302460293294633461B48019411
+:10F0D00002F0EAFA1A4B0F4A1B681268C6EB0306E5
+:10F0E0009B181B1B03F57E7106F57E720731890A9A
+:10F0F0000732009113483146920A02F0D5FA19B04E
+:10F10000BDE8F083E11F8600F01F8600C8260000DE
+:10F110002E208600A4260000722086009026000083
+:10F12000AC208600F82702004B415453C6208600CD
+:10F13000FC270200E9208600BC260000662186002C
+:10F140008826000092218600CC2600000D4B10B5C9
+:10F150001A680D4CD2F81416D2F8143699420B4B9B
+:10F1600018BFD2F8141622681B68C2EB010098423F
+:10F1700001D2002004E0B0FBF3F003FB0023236086
+:10F1800010BDC0469C260000E4260000C8250000F3
+:10F190002DE9F04301688FB0022907461AD15A4B76
+:10F1A0005A481A6800235361046814F4805F11D030
+:10F1B000574B584A1960C169043B1960136804230E
+:10F1C000136024F4805343F400530360524802F068
+:10F1D0006BFA96E03B680C2B14D14C4C236813F46B
+:10F1E000005F0FD023F4005343F400632360676093
+:10F1F0004A48F96C02F058FA236803F40063002BC4
+:10F20000FDD17EE03B68103B0F2B02D8F7F3E2F014
+:10F2100077E03E4B4248D96902F046FABA6C786C06
+:10F22000BC68FD683968FB6C009201903A463D4825
+:10F230000294039502F038FA3B4B7E6C1B68F86928
+:10F24000D7F828E03C6A7D6A9B1B39697A694FEAE6
+:10F250009309BB6900903548CDF80CE00194029504
+:10F2600002F022FAB86BFC6B3D6CF96A3A6B7B6B6F
+:10F2700000902F480194029502F016FAF068316868
+:10F280007268B36800902B4802F00EFAF069316999
+:10F290007269B3690090284802F006FA04A8FFF7E3
+:10F2A0002BFE264802F000FA0024A04625461CE06A
+:10F2B000725912F0010F13D0FF2A11D9059B9A42FF
+:10F2C00008D91F4B1B0D1B059A4209D303F5801368
+:10F2D0009A4205D81B48294602F0E6F908F10108D0
+:10F2E0000435B8F10F0F02D801344C45E0D1074A7C
+:10F2F00040F203301368576043F480631360FFF7F4
+:10F30000BBFC0FB0BDE8F0837428020000280200A7
+:10F31000241000E0281000E0C4E50100C8E5010069
+:10F32000D4E50100E1E50100F81E020015E6010048
+:10F3300048E6010077E6010095E60100FC1C860026
+:10F340009D668000B2E60100F0B51F4E8BB06846A6
+:10F35000FFF7D2FD3578F5B90698079B1C1A07D040
+:10F3600029462246F2F36CF606982146F6F358F742
+:10F370002146164802F098F9154B1D700123337091
+:10F38000144B1968E9B10B78DBB1134B2A461868A6
+:10F39000F3F34AF415E0114F3D7895B90898099BAD
+:10F3A0001C1A07D029462246F2F34AF6089821464D
+:10F3B000F6F336F70A48214602F076F90123357054
+:10F3C0003B700BB0F0BDC0463C280200C9E601000E
+:10F3D0003E280200BC260000242802003D2802002E
+:10F3E000FBE6010010B50446FBF384F60146204617
+:10F3F00000F034F910BDC04670B50446FBF37AF650
+:10F400002046FBF3B7F505462046FBF337F500220F
+:10F41000064640F62A012046FBF3F0F60123AB40F6
+:10F420008269134201D0002500E0013520463146B3
+:10F43000FBF3F6F6284670BD10B5FFF7DDFF10BDF3
+:10F440002DE9F04107460C46FBF354F63846FBF332
+:10F4500015F540F62A01804600223846FBF3CEF629
+:10F4600083690646456944B14FF4004043F00044C7
+:10F4700045F00045FFF792FB07E04FF4004023F012
+:10F48000004425F00045FFF7A7FBB46138467561DD
+:10F490004146FBF3C5F6BDE8F081C0462DE9F041D9
+:10F4A0000E465021804617461D46F7F311F40446D8
+:10F4B00018B300215022F2F3C3F540F23C736363AA
+:10F4C000A3F55573E363A3F5737323640C2363649B
+:10F4D00004230020E56026606760C4F80880A36408
+:10F4E0000749F3F349F2C0B284F84C000138C0B2C6
+:10F4F000012802D9022384F84C302046BDE8F0816F
+:10F500003E2986000048704718F9010000487047FE
+:10F5100090F901000048704700A60E00D2F80036AE
+:10F5200070B50546C3F38404FFF7ECFF03E083786E
+:10F53000A34204D00C3020B10388002BF7D10388FC
+:10F5400013B92846FFF7E2FF03884FF47A7003FBF4
+:10F5500000F070BD0123C2F8603610B5D2F86446E1
+:10F56000FFF7D8FF04F0FF04B0FBF4F34FF47A7018
+:10F5700003FB00F010BDC0462DE9F0411C460646D5
+:10F580001546FBF37BF4002107463046FBF348F6B3
+:10F590000223C0F8583654B1D0F85C3605F03F026B
+:10F5A00023F4FC4343EA4223C0F85C3603E0D0F87E
+:10F5B0005C36C3F3452530463946FBF331F6284621
+:10F5C000BDE8F0812DE9F041DFF860800646D8F80B
+:10F5D000004034BBFBF352F4214607463046FBF3B0
+:10F5E0001FF6D0F81456D0F8143604469D4218BFC2
+:10F5F000D0F8145642F21070F7F3AEF0D4F8142697
+:10F60000D4F8143630469A4218BFD4F81426394636
+:10F61000C5EB0203642203FB02F3C8F80030FBF3DE
+:10F62000FFF5024B1868BDE8F081C046842802004F
+:10F6300070B504460D46FBF321F400210646204632
+:10F64000FBF3EEF5294602462046FFF783FF3146DD
+:10F6500005462046FBF3E4F5284670BD10B5FFF7DC
+:10F66000E7FF10BD70B504460D46FBF307F400211B
+:10F6700006462046FBF3D4F5294602462046FFF70E
+:10F680004DFF314605462046FBF3CAF5284670BDBE
+:10F690002DE9F04F1746C7F820361D46036A85B09E
+:10F6A0000C2BCBBFD2F82836D2F82836C3F3094B3F
+:10F6B000C3F3072B01230024AB4080468946029404
+:10F6C00003940094F6F30AF30646012212FA04F3B7
+:10F6D000334207D00092404649463A46F6F3FEF2DE
+:10F6E00026EA000601341F2CEFD1404603A902AAE6
+:10F6F000F6F31EF3039B00256FEA030A2C46012351
+:10F70000A34006EA0A021A4208D0404649463A4651
+:10F71000E3B2FFF7BDFF854238BF054601341F2C19
+:10F72000EDD10BF10200401905B0BDE8F08FC046E5
+:10F730002DE9704305468846FBF3A0F3002181467E
+:10F740002846FBF36DF50446284600F0F3F8224600
+:10F750000646414618232846FFF79AFF0B2302303E
+:10F7600000FB03F0074C49463419B4FBF6F404FBE4
+:10F7700000F42846FBF354F50A23B4FBF3F4A0B2DB
+:10F78000BDE870833F420F0073B5044616461D4620
+:10F7900000914FF4CB6200214FF0FF33FBF376F37F
+:10F7A0002046002140F25C6233460095FBF36EF385
+:10F7B0007CBDC046002270B513460C4604210546A8
+:10F7C000FFF7E2FF012C20F0F07308BF43F0F07365
+:10F7D000284604214FF0FF32FFF7D6FF012C03D15A
+:10F7E00049F64040F6F3B8F770BDC04610B50021A9
+:10F7F000FFF7E0FF10BDC04610B50121FFF7DAFFAB
+:10F8000010BDC04610B508B1F6F366F510BDC04690
+:10F8100070B5094B06461D6808E030462C68FBF3BE
+:10F8200069F429466A68F7F363F22546002DF4D19E
+:10F83000014B1D6070BDC0466C270000002343666D
+:10F840007047C0467047C0460020704710B5FFF7AC
+:10F85000D3FF10BD10B5FFF7C9FF10BD2DE9F04172
+:10F8600006460D461446FBF30DF4804618B93046A3
+:10F870000121FBF345F4304613F032FA074610B984
+:10F880006FF01D0415E014B96FF0190418E04FF083
+:10F8900000032B80002404F182013846F2F34AF27F
+:10F8A000C0B2A0402B8801341843052C2880F2D127
+:10F8B0000024B8F1000F03D130464146FBF320F499
+:10F8C0002046BDE8F081C04607B54FF0000302A90D
+:10F8D00021F8023D0122FFF7C1FFBDF806000EBD71
+:10F8E000416E2DE9F041044661B1D0F8C83000EB1B
+:10F8F0008303D3F8D020C36D9A4203D1006E8847AA
+:10F90000064600E000262046616DFFF711FFA56E58
+:10F9100007465DB1D4F8C83004EB8303D3F8D02098
+:10F92000E36D9A4202D1206E3146A8473846BDE8C1
+:10F93000F081C04610B50446FBF3DCF301462046D7
+:10F94000FFF740FE10BDC04610B50446FBF3D2F3EE
+:10F9500001462046FFF786FE10BDC046416E2DE9E8
+:10F96000F041044661B1D0F8C83000EB8303D3F80E
+:10F97000D020C36D9A4203D1006E8847064600E04E
+:10F9800000262046616DFFF753FEA56E07465DB168
+:10F99000D4F8C83004EB8303D3F8D020E36D9A4247
+:10F9A00002D1206E3146A8473846BDE8F081C046F6
+:10F9B00043692DE9F743222B06460F4640F3A0800A
+:10F9C000FBF314F4002800F09B80072F00F29880CE
+:10F9D000B268B2F5026F01D101220AE040F60403D9
+:10F9E0009A4201D0002204E0F3680C2B94BF00225D
+:10F9F00001225FFA82F8B8F1000F0BD130464FF4C4
+:10FA000000614246D6F8C890FBF3F8F3054600289B
+:10FA100077D006E0D6F8843013F5405571D04FF01A
+:10FA20000009032F03D030460121FBF379F4D5F808
+:10FA3000303123F00403C5F8303101239F42C5F86B
+:10FA4000303103D9042F01D0083300E00D23C5F86D
+:10FA50003031D5F83031012F23F00103C5F83031B2
+:10FA600001D9042F36D1FF2400214FF4E27223463E
+:10FA700030460094FBF30AF22223009300214FF456
+:10FA8000EE7223463046FBF301F228230093002157
+:10FA90004FF4E67223463046FBF3F8F181230093DE
+:10FAA00000214FF4E87223463046FBF3EFF10123C7
+:10FAB000009300214FF4A4724FF0FF333046FBF364
+:10FAC000E5F1304600214FF4A6724FF6FF73009423
+:10FAD000FBF3DCF1D5F8303123F0700343EA071370
+:10FAE000C5F83031D5F8303123F00803C5F830318E
+:10FAF000B8F1000F05D130464946FBF391F300E021
+:10FB000000252846BDE8FE8370B50446FBF36EF37E
+:10FB1000002839D0A268B2F5026F01D101220AE0B3
+:10FB200040F604039A4201D0002204E0E3680C2B63
+:10FB300094BF00220122D5B24DB920464FF4006196
+:10FB40002A46D4F8C860FBF359F3E8B105E0D4F8CD
+:10FB5000843013F5405017D00026D0F8303123F010
+:10FB60000403C0F8303143F00103C0F83031C3F36F
+:10FB70000213032B03D020460021FBF3D1F31DB960
+:10FB800020463146FBF34CF370BDC0462DE977416A
+:10FB90000022012113460546F6F352F10024804667
+:10FBA00021462822234628460094FBF36FF10121C9
+:10FBB0000646434628464FF0FF32F6F341F1284609
+:10FBC000214628224FF0FF330096FBF35FF1BDE89A
+:10FBD0007E81C046D0F86C32994201D0002004E00A
+:10FBE0008B79D3F1010038BF002070472DE9F04137
+:10FBF000002605460446374608E02B68216A9868C7
+:10FC0000FFF32CF500B90136013718346B689F42B9
+:10FC1000F3DB3046BDE8F08103682DE9F0411E6852
+:10FC20000546B7688846144638462969FFF316F535
+:10FC300044B133681B7E2BB1384629694246012303
+:10FC4000FFF3C4F4BDE8F08170B505460446002614
+:10FC50000DE0616949B1236A3BB1182006FB00F051
+:10FC6000103028180122FFF7D7FF013618346B68CF
+:10FC70009E42EEDB002070BD2DE9F3411F46036874
+:10FC8000044601910092DDF820801E6809B10D291B
+:10FC900041DD61680022FFF7BFFFE1680025656074
+:10FCA00031B1236822891B685868F7F321F0E560B9
+:10FCB000009B2BB1B3F5967F02DA6FF01C002CE0AD
+:10FCC00030464146FFF786FF28B3019969B12368A2
+:10FCD0001B685868F6F3FCF7E06010B96FF01A0083
+:10FCE0001BE03946019AF2F347F101A90422C4F856
+:10FCF000148004F10800F2F33FF1201D694604224C
+:10FD0000F2F33AF1009840B1204661680122FFF712
+:10FD100083FF002001E06FF00100BDE8FC81C046D8
+:10FD20002DE9F047154686B00268DDF84080DDF821
+:10FD300044A005F00103009306465346106842466E
+:10FD4000DDF84C9013F0C0DA0746002840F0A1809F
+:10FD5000022D54D0032D1FD0012D02D06FF01607B5
+:10FD600097E04146042203A8F2F306F1022208F1CB
+:10FD700004010DF11600F2F3FFF056F8100B49469E
+:10FD8000BDF81640039D2FF035DB214600902A4632
+:10FD9000304608F106032EE00222414605A8F2F3A0
+:10FDA000EBF0042208F1040103A8F2F3E5F00222CB
+:10FDB0000DF1160008F10801F2F3DEF0BDF8143081
+:10FDC000012B02D06FF0240763E098F80A70736883
+:10FDD0009F425CDA49463068BDF81640039D2FF01B
+:10FDE00009DB182307FB03F3103300902146F018BA
+:10FDF0002A4608F10B03FFF73FFF074649E00E9B39
+:10FE00001A6873689A4242DA002A40DB4FF0010315
+:10FE1000ADF8143004924FF00B030DF116012A4691
+:10FE200008F10200ADF81630F2F3A6F005A92A4653
+:10FE30004046F2F3A1F004991824013101FB04615A
+:10FE40002A4608F10800F2F397F0012204A908F10C
+:10FE50000A00F2F391F00499042201FB046108F115
+:10FE600004001431F2F388F0049B013303FB04F324
+:10FE70009A5B991902F10B039A4502D26FF00D07B4
+:10FE800007E008F10B004968F2F376F001E06FF04B
+:10FE90000107384606B0BDE8F087C046F7B50168EF
+:10FEA00005460E6896F87032002B2CD002894769FF
+:10FEB0003AB9304607F1BC011346009218F0D0D889
+:10FEC00021E0898970688918F6F35AF72A68044690
+:10FED00018B993680133936015E09289A38A006989
+:10FEE0009B1A8018A382E9682A892061F2F344F002
+:10FEF00004F124025389304643F0400353812146E4
+:10FF0000BA6818F04FD9FEBD13B54FF0000310F0DA
+:10FF10000104ADF8063006D0002904DD10F8013BDD
+:10FF200001398DF8073010F0030F05D0012903DDEA
+:10FF300030F8022B023913E0002211E00368D218D6
+:10FF4000436828BF0132D218836828BF0132D21813
+:10FF5000C36828BF0132D21828BF013210301039CF
+:10FF600031F00F03EAD113041B0C03EB124203E040
+:10FF700030F8023C0239D218034602300129F7DC7E
+:10FF800004BF1B788DF80630BDF80630D3181A046C
+:10FF9000120C02EB134213041B0C03EB124024B1AE
+:10FFA000030243EA10231804000C1CBD10B5FFF730
+:10FFB000ABFF02E003041B0C9818020CFAD1C043FB
+:10FFC00080B210BD2DE9F041BDF818500C4629460D
+:10FFD00016469846FFF798FF3204120C02EB1442C3
+:10FFE0002404240C121905F0FF0302EB16421B0235
+:10FFF00002EB082243EA1523D218101802E003048A
+:020000021000EC
+:100000001B0C9818020CFAD1C04380B2BDE8F081F5
+:100010002DE9F0418D8A16460D2D1F460C6952DDE3
+:10002000A38904F10C0003F0FF021B0A43EA022338
+:10003000B3F5C06F0BD2152D45DD254804F10E0137
+:100040000622F1F37DF700283DD104F11400038866
+:1000500003F0FF021B0A43EA0223B3F5014F0AD162
+:100060000430821C63199A422DD8038803F0FF02E2
+:100070001B0A43EA0223B3F5006F24D1811CC4EBB1
+:100080000103C3EB0504132C1DDD82781309042B37
+:1000900019D102F00F039A00132A14D9A24212DCDC
+:1000A0008A78CB7843EA0223A34201DA1C4600E0B7
+:1000B00009DC8A79CB7943EA02239804800C10B9D1
+:1000C00031603C6001E04FF0FF30BDE8F081C04698
+:1000D00035FA01002DE9F043436887B013F0020FB1
+:1000E0000546884600F08F8005AA04ABFFF790FF15
+:1000F0000028C0F288800598037803F00F039E0063
+:100100003146FFF753FF48B1B8F8163023F010031B
+:10011000A8F816302B6A01332B6274E0EB69059F57
+:100120000133EB6197F80990B9F1060F24D107F17B
+:100130000C01042202A8049CF1F31EF70599042285
+:100140001031A41B03A8F1F317F7A4B2B819029950
+:10015000039A4B460094FFF735FF48B1B8F81630C4
+:1001600023F01003A8F81630AB6A0133AB624AE003
+:100170006B6A01336B623EE0B9F1110F24D107F1D4
+:100180000C01042203A8049CF1F3F6F6059904225D
+:100190001031A41B02A8F1F3EFF6A4B2B819039929
+:1001A000029A4B460094FFF70DFF48B1B8F816309D
+:1001B00023F01003A8F816302B6B01332B6322E0D9
+:1001C000EB6A0133EB6216E0B9F1010F13D1049928
+:1001D000B819891B89B2FFF7E9FE48B1B8F81630A3
+:1001E00023F01003A8F81630AB6B0133AB630AE0C1
+:1001F0006B6B01336B63B8F81630002043F01003CB
+:10020000A8F8163001E04FF0FF3007B0BDE8F083EA
+:100210002DE9F043436887B013F0010F804600F0EA
+:100220008780CB8A13F0080F03D183680133836082
+:100230007EE005AA04ABFFF7EBFE002878DB059A09
+:1002400000271378977203F00F039E00D772314690
+:100250000598FFF7ABFE059B9872C0F30F20D8728C
+:10026000D8F80C3005990133C8F80C3091F8099092
+:10027000B9F1060F21D18D19049C0C3104222F7481
+:100280006F7402A8F1F378F6059904221031A41BCB
+:1002900003A8F1F371F6A4B24B4628460299039ADB
+:1002A0000094FFF78FFE2874C0F30F206874D8F80D
+:1002B00010300133C8F810303AE0B9F1110F22D1F3
+:1002C0008D19049CAF71EF71059904220C3103A8BC
+:1002D000F1F352F6059904221031A41B02A8F1F3A0
+:1002E0004BF6A4B24B4628460399029A0094FFF7B6
+:1002F00069FEA871C0F30F20E871D8F814300133FB
+:10030000C8F8143014E0B9F1010F11D18C19049917
+:100310002046891BA770E77089B2FFF747FEA070DF
+:10032000C0F30F20E070D8F818300133C8F8183047
+:1003300007B0BDE8F083C0462DE9F34114460A9F9B
+:100340000268DDF82C8004F0010300930546434663
+:1003500010683A4612F0B8DF064618BB052C04D8E0
+:10036000DFE804F00A061403030D6FF0160619E027
+:10037000281D3946042213E06B683B6012E005F14A
+:10038000080000214C22F1F35BF60BE0B8F14B0FB3
+:1003900002D86FF00D0605E0384605F108014C2241
+:1003A000F1F3EAF53046BDE8FC81C04610B58C6B30
+:1003B00000200BE00B1893F83C30064A03F07F0353
+:1003C000D356002B01DA012003E00130A042F1D125
+:1003D000002010BD401B86002DE9F84F02298346FE
+:1003E0000E4690469A4614BF4FF0FF37002714BFC1
+:1003F000002401244FF000092EE0022E14BF4FF01C
+:10040000FF3300239F4211D0022E08D1B8F1040F10
+:1004100007D0B8F1060F04D0B8F1080F01D00422BC
+:1004200000E00022C7EB0403934214DD0E2CCCBF86
+:100430004FF480534FF4005344F4306213439DB2A1
+:10044000DBF85C01294635F0A9DF20B12AF8195004
+:10045000274609F101090134022E0CBF0E230023A7
+:100460009C4202DCB9F11F0FC7D90A9BC3F8009068
+:10047000BDE8F88F2DE9F04F88469BB0402100275A
+:10048000DDF890B09DF894900646C0F82077C0F84B
+:100490001C1740689A46F6F31BF40446C6F8180782
+:1004A00010B96FF0150473E0D8F800306BB9203341
+:1004B000C6F82037336B30461A8906F5E46300939B
+:1004C00059462346FFF788FF1FE0202B6CD845468E
+:1004D00017E0AC88D6F85C01214635F05FDF0028D4
+:1004E00062D01FB12B78E2B29A425DD9D6F820379C
+:1004F000D6F81827013722F813400133C6F8203701
+:100500000435D8F800309F42E3D3D6F82037002BCB
+:100510004AD070681021F6F3DBF30746002835D087
+:10052000279B002411AD446083600473214606605C
+:1005300080F80DB080F80E9024222846F1F380F563
+:10054000A24514BF0023012301934FF0FF33029310
+:10055000039304930593D6F8183730460693D6F8DC
+:10056000203702210793144B144A0A9303230C9358
+:100570000123089409940D940E9400950B9716F09E
+:10058000BBDC044698B9269B7B6010E06FF01A0430
+:10059000D6F8181759B17068D6F81C27F6F3A8F3E7
+:1005A0000023C6F8183702E06FF00104F0E7204698
+:1005B0001BB0BDE8F08FC046410B01002C9E8500AA
+:1005C00030B590F8143789B00446002B3ED0D0F8EF
+:1005D00068319D79002D62D1036880F814571B7E25
+:1005E000002B5CD0B0F81637002B58D0036B18697D
+:1005F00002F09CFAB4F81617884250D0204618F042
+:10060000CFDB204601F0EEF82046B4F8161718F0BC
+:100610000DDA236893F82F306BB1D4F86C32204692
+:10062000D3F8D412383113F0B9D80146C4F8AC0667
+:1006300020460CF051D920461AF068DC20462946A5
+:100640001AF06EDE204611F0DBDC28E003681B7E2A
+:100650002BB3D0F868319B790BBBD0F8000507A904
+:1006600044F038DD03E02B7E13F0020F17D107A80A
+:1006700044F038DD05460028F5D1236B05901B6852
+:1006800005A90093032301930290039001222046C1
+:100690002B46FFF7EFFE10B9012384F8143709B099
+:1006A00030BDC0462DE9F74F0192D0F800A090F878
+:1006B0000D801F460C464FF0000BE5E0072200219D
+:1006C0002046F1F3BDF40C9AB8F1020F12F81B00AA
+:1006D000207001D0022308E0042F05D0062F03D09C
+:1006E000082F01D0434600E00023C3EB0002B8F11D
+:1006F000020F14BF002301239A4210DBB8F1020F4E
+:1007000001D0022108E0042F05D0062F03D0082FC6
+:1007100001D0414600E00021C1EB00060FE0B8F136
+:10072000020F14BF0026012606E0DAF85C0131460C
+:1007300035F0F2DD18B9013623789E42F5D9B8F1CB
+:10074000020F207802D0002202230BE0042F07D0F2
+:10075000062F00F0A680082F00F0A3804346A1E0FA
+:100760000E2200231B1893420FDCB8F1020F01D0B8
+:10077000022108E0042F05D0062F03D0082F01D056
+:10078000414600E000210D180FE0B8F1020F0CBF48
+:100790000E25002506E0DAF85C01294635F0BCDDBF
+:1007A00018B9013D23789D42F5D24FF0000963E06E
+:1007B00002EB89039968CB88B1F832E013F020038B
+:1007C0005FFA8EF00DD00EF44072B2F5807F02D148
+:1007D000821C023806E0B2F5007F02D1821E023090
+:1007E00000E00246B04201D3A84203D9B24241D34D
+:1007F000AA423FD8B3B1B04214D3A84212D80EF4E3
+:100800004073B3F5807F05D12379FF2B0AD00133E4
+:10081000237107E0B3F5007F04D16379FF2B01D08A
+:1008200001336371CB8813F0200F0BD0B24209D390
+:10083000AA4207D8824205D0A379FF2B1AD00133F0
+:10084000A37117E023780E2B0FD85046FFF7AEFDAB
+:1008500028B1E378FF2B0DD00133E3700AE0A378D1
+:10086000FF2B07D00133A37004E06378FF2B01D086
+:100870000133637009F10109DAF818251368994505
+:1008800096D30BF1010B07340D9B9B4504DA019ABB
+:1008900013689B45FFF612AF019BC3F800B0BDE89B
+:1008A000FE8F00230E225DE72DE9F84F5FFA83FCEF
+:1008B0001E4603F44073B3F5007F14BF4FF00009E8
+:1008C0004FF0010905468A4693460CF10200ACF14F
+:1008D0000203B9F1000F02D08646984601E09E4619
+:1008E00080460027394629E011F80A40ACF105039B
+:1008F0009C4221DB0CF105039C421DDC0AEB01004C
+:1009000082783AB9C3782BB903791BB943790BB90B
+:1009100083798BB1744506D1837993B9B9F1000F0E
+:1009200008D0037907E044450BD152B9C37843B9E5
+:10093000037933B9437923B9013707315F45D3DBF5
+:100940001BE0BEF10E0FD4BF4FF400534FF48053A1
+:100950004EF4306213439CB2D5F8FC341B7893B14B
+:100960002846002124F048D8284624F03BD80AE045
+:100970002846012124F040D804E0D5F8FC341B7847
+:10098000002BF5D134462046BDE8F88F2DE9F04F15
+:10099000D0F8008090F80DA0D8F83010DDB00989AB
+:1009A000814614464FF0000B5B9300E004210022C7
+:1009B0005B98964608E01EF804300EF1070E052BF2
+:1009C00001D9934602E001328242F4DB082900F2A9
+:1009D000B08001A252F821F0FD090100330B0100A3
+:1009E000030A0100330B0100AF0A0100330B0100C1
+:1009F000330B0100330B0100AD0901004FF6FF7608
+:100A00001AE00025AE464FF6FF7612E00EEB0B0221
+:100A100092FBF0F300FB1323072203FB02F16218A1
+:100A2000937823B9D378B3423CBF655C1E460EF180
+:100A3000010E8645EADB15B90025AC4621E00E2DF6
+:100A400094BF4FF400524FF4805245F4306343EAB0
+:100A500002006FE00CEB0B0292FBF0F300FB1323A0
+:100A6000072203FB02FE04EB0E0359789A78DB7829
+:100A70005218D218B242BCBF14F80E5096B20CF104
+:100A8000010C8445E6DB3DB99BFBF0F300FB13B39F
+:100A9000072203FB02F31D5D0E2D94BF4FF400539C
+:100AA0004FF4805345EA030343F4306042E0BAF167
+:100AB000020F3ED15AAB00930024404651465246A5
+:100AC0004AAB5A94FFF788FCD8F818771FB3D8F8C8
+:100AD000206706B35A99254610E000243AAB37F850
+:100AE0001520E05A904205D15CAA02EB410323F89D
+:100AF000480C01310234402CF0D10135B542ECDB19
+:100B000020230E485B935A9100F0CEFD4AAB009330
+:100B10005A9B02AC04E020233AAA5B9302AC0092F9
+:100B20000193214648465BAA0223FFF7BBFD022141
+:100B30003DE700205DB0BDE8F08FC046B4FA01008B
+:100B4000F0B50546BDB004680E4609B108292DD19F
+:100B50002023D4F818273B93236B03AF1B89009203
+:100B6000D4F82027394601923BAAFFF79BFD6B7B07
+:100B7000022B13D1D4F8FC341B787BB1D4F8343772
+:100B8000B3F8A4E30EF44063B3F5406F06D12046FA
+:100B900039463B9A7346FFF787FE05E02846002159
+:100BA00003AA3B9BFFF7F2FEA4F816076B6813B18C
+:100BB000A86831469847D4F81817D4F81C276068FD
+:100BC000F6F396F00023C4F818376068294610221F
+:100BD000F6F38EF03DB0F0BD7047C04610B5C3F8D7
+:100BE000A010082019461C4631F03ADE84F8A40013
+:100BF00010BDC0467047C0460020704700207047B7
+:100C0000002070477047C0467047C0467047C046D6
+:100C1000002070477047C04603680246D3F86C3224
+:100C2000D3F8E432987818B1938A181E18BF0120BF
+:100C30007047C0467047C0467047C04670B5037DD8
+:100C400004469BB1457D8DB9C068A169FEF306F5E8
+:100C500001236375E36906460BB1A0689847D6F196
+:100C6000010038BF00206575257500E0002070BDCB
+:100C70000846002110B5016141810172017306220D
+:100C8000F1F3DEF110BDC04610B50068F4F7B0F81E
+:100C900010BDC04690F832007047C0460246086852
+:100CA000430D5B056BB922F07F4323F46003520DC3
+:100CB00083422CBF4FF40013002352059B180343BB
+:100CC0000B60704770B510600D461C46084619460B
+:100CD0001646FFF7E3FF2368AB4202D233680133C5
+:100CE000336070BD002070477047C04600207047D9
+:100CF000002070477047C0467047C0467047C046E6
+:100D000030B50568B5B061B10DF107040171C922B4
+:100D100000212046F1F394F12B6B2146186902F073
+:100D20001BFF35B030BDC046406B70477047C046B2
+:100D3000002070477047C046002070477047C0468B
+:100D4000002070477047C046002070477047C0467B
+:100D50007047C0467047C0467047C0460020704785
+:100D60007047C0467047C046002070477047C04675
+:100D70007047C0467047C0467047C0464FF0FF30CE
+:100D80007047C0467047C04600207047002070473B
+:100D90007047C0467047C0467047C0460020704745
+:100DA0007047C04603490A6812B100230B60104621
+:100DB0007047C046E82B020070B515460C464E6CD5
+:100DC00018F00CD9024628B915F4001F02D0636C44
+:100DD0006664A364104670BD73B500EB420440F630
+:100DE0002A15B4F82C66A4F82C56069D009503F03D
+:100DF0008FDCA4F82C667CBD10B511F0F7DC024640
+:100E000040B1416A11F4002F04D1036813B141F4D9
+:100E100000234362104610BD2DE9F3411E460368CE
+:100E200004461B7E0F469046002B4BD090F875323F
+:100E3000002B47D10D682846FFF776FF016902466F
+:100E40008B79B3B1837E13F0010F12D0D1F8CC307F
+:100E500013F4806F0DD1B4F8263603F47043B3F564
+:100E6000805F14BF40234423CB5813B193F8DF3085
+:100E700043BB5168002925DB164B01EA03030BB97C
+:100E8000184602E0EB8A03F0070011F0400F19D07A
+:100E9000114B02A91B5C204641F8043D336009F068
+:100EA000EFDDB0F1FF3F0DD0019A3368934209D0D6
+:100EB0000A4B32609A5CEB8A02F0070223F00703C8
+:100EC0001A43EA82204639464246334614F06CD82B
+:100ED000BDE8FC8140000180C4D28500301E0200C4
+:100EE000F0B585B00A9C0D4600940B9C1F460194FA
+:100EF0000C9C064602940D9C039428F02FDBAB79E2
+:100F000043B13946304644F063DD014610B1304606
+:100F100044F056DC05B0F0BD10B520F00BDE10BD7E
+:100F20002DE9FF4107461D469E6B146945F0C8DB5D
+:100F30008046002834D1337A022B31D1A3797BB398
+:100F4000B5F8683063B3A26D40F2371302EA0303C9
+:100F500033B394F884301BBBD4F888303A6853B963
+:100F6000D2F88C30D3F8E4210132C3F8E4213C23D9
+:100F7000C4F8883009E0D2F88C30D3F8E42101328B
+:100F8000C3F8E421012384F89430002394F9482025
+:100F9000384600930293296F1133019644F068DFBD
+:100FA000404604B0BDE8F0812DE9F74F80460E467B
+:100FB00093461F46002B5FD001295DD14FF4C073CB
+:100FC0000193FAF397F04FF440718246F5F380F6FF
+:100FD000044610B94FF0FF3555E000214FF4407240
+:100FE000F1F32EF040463146224601ABF0F3BEF657
+:100FF00010F11E0F3AD1019B4FF0FF325D004A23E2
+:1010000023700B23637015332371042363716FF016
+:101010002F03A371923323726FF0560363724FF064
+:1010200002096319A270E27084F8079003F8022C99
+:1010300003F8012C07F10C039D4202DC6FF00E0552
+:101040000DE059463A4604F10A00F0F395F795FB96
+:10105000F9F340463146224611F074FE05465046EB
+:1010600021464FF44072F5F343F60CE0504621461A
+:101070004FF44072F5F33CF6404631465A463B4643
+:10108000EFF3A0F705462846BDE8FE8F70B504468D
+:101090001E46FEF39FF3054640B1636893F8AB30FC
+:1010A00023B1E06F3146F1F76DFDA860284670BDB1
+:1010B0002DE9F0411F4603680C461B68164693F85D
+:1010C000953005460969A28A1BB1E38A13F0800FA7
+:1010D00009D0152A07DD08480E310622F0F330F753
+:1010E00008B9013805E02846214632463B46FCF364
+:1010F000A5F4BDE8F081C046BAD4010010B59E4603
+:10110000D0F8683103B19B68054C23607346FCF34B
+:10111000F3F1B0F1FF3F01D10023236010BDC046C1
+:10112000E82B02002DE9F04F87B0DDF854808946A6
+:1011300015469A46129FDDF84CB00446B8F1000FF0
+:1011400006D0D8F8081019B10120F1F7A5FE044621
+:1011500014B96FF0160632E0226805F0010300931F
+:10116000106849463A465B4612F0AED8064630BB98
+:10117000112D02D0132D09D00FE03846F1F3ECF316
+:10118000E8B904F5B8703946062203E004F5B670F4
+:1011900039460422F0F3F0F611E0109B204600934C
+:1011A000119B49460193149B2A4604935346029788
+:1011B000CDF80CB0CDF81480FCF3C2F006463046F2
+:1011C00007B0BDE8F08FC04670B50546D0F8B40052
+:1011D00058B103784BB1F1F767FB044630B9D5F845
+:1011E000B4000121F1F31AF500E001242846F3F3DD
+:1011F000DBF724B9D5F8B4002146F1F30FF570BD43
+:1012000010B5FFF735FD10BD10B5FAF7B1F810BDF8
+:10121000B0F8543810B50BB119F03ED910BDC04626
+:1012200010B5044638B102682AB121B992F80B37DB
+:101230000BB182F80B17204617F090DF10BDC046A7
+:1012400010B521B11AB1536E0BB13DF037DE10BDB0
+:1012500010B50C4651B1002381F8653581F866352B
+:1012600081F86735C1F868353DF0A2DE10BDC04693
+:10127000036A10B50C46002B2CD0036809691B6863
+:10128000B4F814E093F895302BB1E38A13F0800F93
+:1012900001D11E2200E00C2202F10B039E4519D35E
+:1012A0008B188A5C591C5B7803EB02239BB2B3F565
+:1012B000006F0FD14B784A1C1B09042B0AD1537ABB
+:1012C000012B07D1436A01334362C3680133C36012
+:1012D000002002E021463FF03BDD10BD036810B561
+:1012E0001A68536B2BB192F8443013B130F0AEDF73
+:1012F00000E0002010BDC04610B50C462DF0C0D94E
+:1013000018B994F8F53284F8F43210BD70B50122A2
+:1013100005460C46D1F84C152EF01ADD284621461C
+:101320002DF0EAD870BDC0460C2A2DE9F0410446E4
+:101330000F46154651D80122AA4041F2485302EA0D
+:101340000303002B49D0D0F8B4364BB1D3F8D832D0
+:1013500033B15B68012B40D0032B3ED0022B3CD035
+:10136000204615F043DD002837D1D4F868315B6999
+:10137000012B32D0D4F81808FEF3F6F0064628B157
+:10138000D4F86801092143F013D91AE0082D01D0DF
+:101390000C2D04D1D4F868319B7923BB11E0D4F82B
+:1013A0006801837913B3D4F82835022B04D094F85C
+:1013B000F43713F0010F16D0092143F0F9D8304665
+:1013C00015E0082D12D1204639460222002325F0CF
+:1013D0003BD958B14FF0FF3009E0204639462A4644
+:1013E00029F0E6DC03E06FF0180000E00020BDE823
+:1013F000F081C0462DE9F04F85B005469B468846F2
+:1014000091460F9F9DF840A0F8F7B2FFD5F8B06362
+:1014100004460AF087DDD5F8C03398420CD3032385
+:10142000009300230193029303932046172109F1AF
+:101430000A02013312F03CDB96F8463013F0030F3A
+:1014400019D0D8F8582040F2371302EA030393B1B9
+:1014500094F8693713F0010F0DD07B6813F4803FC7
+:1014600009D03B6C012B06D1002220463946134699
+:10147000009211F0BBDB094C7F2323600E9B2846B2
+:10148000009341465B464A460197CDF808A0F8F71D
+:1014900085FF0023236005B0BDE8F08F0C2C02000F
+:1014A00010B50446F5F346F0B0F5C05F05DD204603
+:1014B00043F006DE204643F003DE10BD2DE9F04187
+:1014C000074619F0DFDF0026BB19D3F84C42B4B150
+:1014D000D4F88C509DB9A3798BB1A36D13F0020F92
+:1014E0000DD094F8843053B1F5F38CF0D4F890100B
+:1014F00027F042DF18B1C4F8885084F884500436CD
+:10150000202EE1D1BDE8F08170B590F8A1310546FB
+:1015100063B903681B6F4BB1D0F81C48F5F372F048
+:10152000D5F82038E41A2418C5F81C48284614F0C9
+:10153000BBDB70BD10B588B00A9C00940B9C019475
+:101540000C9C02940D9C03940E9C04940F9C059497
+:10155000109C0694119C0794F3F3C2F1044B0421F0
+:10156000D3F88C300A4604469847204608B010BD90
+:10157000E0A6850070B504460D461EF04BD92946FD
+:1015800006462046F8F708FE304670BD2DE9F041CA
+:101590000546D5F8D8320E465B681746012B006821
+:1015A000D5F8DC4202D14FF0000805E0042914BF51
+:1015B0004FF000084FF001080368DB691A6D636A99
+:1015C000934238BF62624EB9D4F8901031B140688E
+:1015D00094F89420F5F38CF3C4F8906028463146D3
+:1015E0003A4625F0F5D8B8F1000F01D00023636228
+:1015F000BDE8F0812DE9F04385B00C9F0546984683
+:10160000D7F80090D2F8D462144600970AF0F0DCC4
+:10161000296891F8463013F0030F3FD0D4F8CC205E
+:1016200012F4805F3AD196F93430002B36D14B6BEF
+:10163000002B33D012F0020F30D13B680DF10900BE
+:101640001849032208EB0304F0F396F495F8FA31F5
+:1016500033B196F96A30002B02DA95F80A0700E0F8
+:10166000002008EB0901A14201D2002100E0091B82
+:1016700002238DF80C3000238DF80D3001338DF8E6
+:101680000E300DF109038DF80F000093204607235B
+:10169000DD221AF07BDD3B6809333B6005B0BDE815
+:1016A000F083C046C1D401000FB430B5104BADF586
+:1016B000037D9E4501D1002513E002A887AB0538C4
+:1016C00040F20121869A8193F0F3F0F5002405465B
+:1016D00005E002AB053BE05CF5F332F20134AC42CD
+:1016E000F7DB28460DF5037DBDE8304004B07047B8
+:1016F000DB62820010B502490248FFF7D5FF10BD3A
+:10170000CCFB0100E3FB0100C36970B513F4006F6B
+:101710000E460546016915D00368D3F88C20936BFB
+:101720005C1C4FF47A739463B4FBF3F202FB134333
+:1017300023B90748C96B2246FFF7B6FFEB6923F4CC
+:101740000063EB61284631462CF03CDB70BDC0469F
+:101750007CDB010010B590F81632044663B1084BEB
+:101760001B684BB1D0F88011D0F884210223C068E7
+:1017700081EA0202F9F332F42046F7F36FF610BD66
+:10178000AC27020010B50446F7F3B8F7002384F83D
+:10179000173284F8183210BD10B5074C2378012B8E
+:1017A00009D0064B1B78012B05D001232370F8F3D9
+:1017B00073F70023237010BD002C0200EC2B0200F5
+:1017C00070B50546F1F7EEF80128014607DD044C37
+:1017D000012328462370F8F3EDF50023237070BD34
+:1017E000EC2B020010B5064902690B782BB1D2F838
+:1017F000D03013B100230B7001E018F051DD10BDA3
+:10180000F42B020010B58B7913B1044B01221A702E
+:101810002DF0B6DB014B00221A7010BDF42B020034
+:1018200070B5044C8568A54201D1002001E0F0F3B9
+:1018300009F770BD0800002070B505460E461AF085
+:101840002BDD0446C0B13146284640F26C521AF0F6
+:1018500035DE064620B9284621461AF091DD0AE019
+:10186000214640F26552F0F387F32846214640F2C4
+:101870006552F5F33DF23446204670BD2DE9F04146
+:101880008AB088460023159917460546129C09938D
+:101890002DF0B0DD07F001030093414606462246D5
+:1018A0002868139B11F010DD8046002840F0AA80C4
+:1018B000119B032B04D909A810990422F0F35CF3BF
+:1018C0000D2F08D8DFE807F00A0F07071722363C6C
+:1018D0004B07074E93976FF0160892E0284608F0E2
+:1018E0002DDA40B22AE02846099908F051DA00289A
+:1018F00000F0858085E0B6F95E300BB102201DE076
+:10190000B6F95C30181E18BF012017E0099B022BA6
+:1019100006D14FF00003A6F85C304FF0010306E05B
+:10192000003B18BF0123A6F85C304FF00003A6F877
+:101930005E3066E0D5F83407F8F71EFD206060E001
+:10194000099BD5F834070393F8F71EFD039B8342E8
+:1019500055DCD5F834070999F8F712FD51E0B5F8D0
+:10196000BE3846E02B6893F8A030002B3FD00DF135
+:101970001608264906224046F0F3FEF221460422CC
+:1019800008A8F0F3F9F2211D042207A8F0F3F4F2FD
+:10199000404604F108010622F0F3EEF2079F57B922
+:1019A000D5F86821937993B95369012B0FD02B682F
+:1019B00093F83F305BB904F1100301932846314698
+:1019C000089A3B46CDF8008015F084DC0DE02B68CA
+:1019D0001B7E13B96FF0030813E0284631460DF162
+:1019E000160204F1100315F061DC804609E095F859
+:1019F000C334236005E0099B85F8C33401E06FF030
+:101A00001C0840460AB0BDE8F081C0462C9E850007
+:101A10002DE9F04790B0DDF860A00C461E46514617
+:101A20000023054617460F932DF0E4DC8046D0F8DE
+:101A3000DC9277B1032E04D90FA839460422F0F3C3
+:101A40009BF237B1032E04D90FA839460422F0F3D4
+:101A500093F2352C6BD010DC162C00F07C8105DC69
+:101A60000B2C21D0152C00F065811AE01C2C00F005
+:101A700086812F2C00F0288113E0382C00F0E580BF
+:101A800006DC362C00F09880372C00F0B58008E09A
+:101A90009F2C00F07A81A52C00F03F81392C00F0BA
+:101AA000F5806FF01604A1E12B6893F8A030002BAD
+:101AB0003DD00DF12606A24906223046F0F35CF235
+:101AC000394604220DA8F0F357F2391D04220CA860
+:101AD000F0F352F2304607F108010622F0F34CF21F
+:101AE0000C9C54B9D5F8682193798BB95369012BB3
+:101AF0000ED02B6893F83F3053B907F110030193D0
+:101B0000284641460D9A2346009615F0E3DB0CE08B
+:101B10002B681B7E002B00F05D81284641460DF1AD
+:101B2000260207F1100315F0C1DB04465EE12B68C5
+:101B30001B7E002B00F04E81052E40F24E810D2EB3
+:101B40000BD9284607F10801A6F1080201F062DA74
+:101B50000446002840F04A8109E005AC3946204699
+:101B60000622F0F309F2002307930E26274698F881
+:101B70000640B4B9D9F8901031B1686899F894204A
+:101B8000F5F3B6F0C9F8904089F89460686831467A
+:101B9000F5F39EF0C9F8900018B139463246F0F3DB
+:101BA000EBF14046394629F091DAD9F890300446F5
+:101BB000002B40F01A8119E1002300932846394692
+:101BC00032460EABF1F760FB0446002840F00E8170
+:101BD0000E99032900F004812A6B1368994202D1FF
+:101BE000D2F8F03050E05368002B14BF38233C2368
+:101BF000EB58D3F8F03047E00023009328463946ED
+:101C000032460EABF1F740FB0446002840F0EE8070
+:101C10000F9A02F16403672B02D96FF01C04E5E010
+:101C20000E99032904D02B6B1B68994240F0DE808B
+:101C3000002A04DB2846296B29F08CDB02462B6B3B
+:101C4000C3F8FC20C3F8F020D0E00023009328461E
+:101C5000394632460EABF1F717FB0446002840F038
+:101C6000C5800E99032900F0BB802A6B1368994246
+:101C700002D1D2F8F43007E05368002B14BF3823A8
+:101C80003C23EB58D3F8F4303B60AFE000230093E3
+:101C90002846394632460EABF1F7F6FA04460028DC
+:101CA00040F0A4800F9A642A00F29A800E990329CA
+:101CB00004D02B6B1B68994240F098802B6BC3F8C3
+:101CC0000021C3F8F42091E02B680F9C93F83F307B
+:101CD00013B16FF01B0489E0D5F86801837913B163
+:101CE000042142F065DC95F87232221E18BF0122F1
+:101CF00085F8502785F85925002B76D12AB105F5AE
+:101D0000AA61D5F85C010E3104E005F5AA61D5F8A9
+:101D10005C010A3134F026DA07E70123002202933E
+:101D200028460849134600970196CDF80CA011F0FB
+:101D300037DBFAE6B8F95E3033B1022009E0C0467D
+:101D40002C9E85001C738600B8F95C30181E18BFE5
+:101D50000120386049E00F9B022B06D14FF00003B1
+:101D6000A8F85C304FF0010306E0003B18BF0123E8
+:101D7000A8F85C304FF00003A8F85E3035E02B681F
+:101D800001211869F9F392F22FE0331F0622B3FB09
+:101D9000F2F33B60D5F8000500230BA90F9343F045
+:101DA00099D910E00B7E13F0020F0CD00F9B5C1C36
+:101DB0000F943B68A34210D3B81E062204FB020016
+:101DC0001A31F0F3D9F00BA843F08CD90146002862
+:101DD000E8D108E06FF0030408E06FF00D0405E0BF
+:101DE0006FF0020402E00F9B3B600024204610B01D
+:101DF000BDE8F0872DE9F04F056889B082460C46B2
+:101E00001E4628460023179907939346DDF848801D
+:101E10002DF0F0DA139B032B04D907A841460422C6
+:101E2000F0F3AAF0BBF10D0F56D12846414698F8C1
+:101E3000066098F8087098F809402DF06FDA10B134
+:101E40006FF00107F1E098F80630003E18BF012658
+:101E5000022B14BF4FF400594FF4811947EA0427AD
+:101E60006EB13846F1F3F8F1002840F0E080D5F883
+:101E70005C01394634F092DA002800F0D880284618
+:101E80002DF070DBB0F1FF3F014600F0D280284614
+:101E90004A46434600962CF08BDE0446002800F0AC
+:101EA000C88028462146FBF789FA20B128462146FA
+:101EB0002DF0C2DABDE0002E00F0B9803946284688
+:101EC000A2683BF0CDD90746002800F0AE80284636
+:101ED00021462DF0B1DA12E0139B50460193149B7A
+:101EE00021460293159B5A460393169BCDF800801A
+:101EF0000493179B059333463AF03ADF074617F1F0
+:101F0000170F40F09280DAF80060002330461799EE
+:101F100006932DF06FDA139B0446032B04D906A811
+:101F200041460422F0F328F0BBF11B0F7DD130466F
+:101F3000414698F8065098F8089098F809702DF0E6
+:101F4000EDD9034620B1A04202D06FF0010373E047
+:101F5000B5F1000A18BF4FF0010ABAF1000F0BD01B
+:101F6000032D0BD09A68304649EA07213BF078D917
+:101F70000346002860D111E0032D0FD130462146E1
+:101F80002CF070DF012394F94810304600934FF491
+:101F90008802013BFBF7E6F903464DE0D4F8CC306C
+:101FA000304643F40003C4F8CC3021462CF05ADF0D
+:101FB000A37913B1322384F8F43294F8F41231295E
+:101FC0000FD833681B7E1BB130461D4A17F02EDA3E
+:101FD000D6F84C0194F8F4123DF074D9322384F809
+:101FE000F4324146062204F1C200EFF3C5F784F84B
+:101FF00006A030462146FBF7E1F9054640B1D4F88A
+:10200000CC3023F40003C4F8CC304FF0FF3313E09E
+:1020100030460321A26811F087D8D4F8CC3023F4DD
+:102020000003C4F8CC302B4606E03B4604E0002712
+:10203000FBE74FF0FF37F8E7184609B0BDE8F08F2F
+:10204000329E85002DE9F04704468946FCF3F4F7FB
+:10205000F4F3D8F294F854318046012B1ED825466B
+:10206000002717E06E69B379022B11D1B4F86C30F8
+:1020700013F4807F0CD0204649464246F0F74CFED0
+:1020800030B90423B37194F8CD30013B84F8CD30DE
+:1020900001370435B4F910309F42E3DBBDE8F08727
+:1020A00030B54FF0000E044691B08C461546704690
+:1020B00009E023185A690EF1010ED1794DF800108C
+:1020C000536B0430D371B4F910309E45F1DB2046D8
+:1020D00061462A46FCF3A4F10020014606E063189D
+:1020E0005A695DF801300130D3710431B4F9103010
+:1020F0009842F4DB11B030BD2DE9F0410C290446C3
+:102100000D46164690F853710DD100210122FCF3C3
+:1021100087F1204600210122FCF33EF1002384F8E0
+:10212000CE3084F8CD30A36E2046B3F1FF3F08BF18
+:1021300084F8563129463246FCF392F2B4F86C30FA
+:1021400003F0C003C02B16D1D4F85C319BB194F8D6
+:102150005331BB420FD9E368A1689868FDF37EF262
+:10216000E368A1689868D4F85C210123FDF32EF29E
+:102170004FF0FF33A366BDE8F081C046836E10B513
+:10218000B3F1FF3F01D0FBF39FF510BD2DE9F04106
+:1021900004460D46866EFCF3C5F6074690B9042248
+:1021A00004F5AE7005F11401EFF3E6F6D4F85C31F6
+:1021B0004FF47A7203FB02F3B6F1FF3FC4F85C31CF
+:1021C00008BFA6663846BDE8F081C0460E2937B57F
+:1021D00005468E4614460BD00F2910D1114601A892
+:1021E0000422EFF3C9F628460199F0F731FE08E022
+:1021F000B0F85831002003F00103136001E0FCF354
+:10220000E9F13EBD70B514460546FCF39FF1236825
+:102210000BB10223AB6570BD70B50D460446FBF3F0
+:10222000FDF7014610BBA36DEDB1FBB9D4F8542105
+:102230000F4B02EA03037BB194F85431022B04D113
+:1022400094F8573113F0010F05E0012B07D194F8F2
+:10225000573113F0020F02D16FF0010300E00023A9
+:1022600084F8563102E00BB184F85601084670BD7F
+:10227000FF0000FF10B50446FBF362F7002384F86B
+:102280005731A4F85831C4F85C3184F8563110BD88
+:102290002DE9F041A2B0882205460C4690F8558100
+:1022A00090F8567190F854616846EFF365F6284649
+:1022B0002146FBF3AFF60246002836D1009B85F895
+:1022C00056719E4285F854612CD01BB995F8573150
+:1022D00073B112E0022B04D195F8573113F0010FBE
+:1022E00005E0012B07D195F8573113F0020F02D109
+:1022F0006FF0010314E096B90DE0012E02D113F046
+:10230000010F05E0022E05D195F8573113F0020FA9
+:1023100005D107E036B995F85531434502D200237F
+:1023200085F85631009B85F85431104622B0BDE83F
+:10233000F081C0462DE9F04104460E46154690F85E
+:102340005671FBF363F48646A0B92A4601460DE0B8
+:102350007318DB88083113F0100F06D194F8573149
+:1023600043F0010384F8573102E0083A072AEFD816
+:1023700084F856717046BDE8F081C0462DE9F04101
+:1023800004460D46164690F85671FBF3DBF386467D
+:1023900098B9294632460CE04B6A13F0100F06D16B
+:1023A00094F8573143F0020384F8573103E0383A88
+:1023B0003831372AF0D884F856717046BDE8F0817C
+:1023C000002070472DE9F0410B4C07460E460025D2
+:1023D0000BE038462146EFF3A1F620B923799E425F
+:1023E00001D1A06806E001350C34044B1B689D4206
+:1023F000EFD30020BDE8F08120FC0100F02B0200AB
+:1024000070B50D4600240AE00849284601EBC401D6
+:102410000422EFF395F508B9013005E00134044BCF
+:102420001B689C42F0D3002070BDC04620FC010018
+:10243000F82B020010B5034C216033F0F9DA0023C9
+:10244000236010BD082C02002DE9F0412A4B0646FE
+:10245000D3F800800F4600250BE0284B304603EBF5
+:10246000C5042146EFF35AF610B9E3789F4241D0F4
+:1024700001354545F1D1224B0025D3F800800FE00E
+:10248000204B304603EBC5042146EFF347F630B945
+:10249000E3789F4203D11C4B01221A7010E00135F2
+:1024A0004545EDD117BB194B3D46D3F800800AE0F6
+:1024B000174B304603EBC5042146EFF32FF608B95E
+:1024C000201D17E001354545F2D1124B124DD3F8CE
+:1024D0000080002408E029463046EFF31FF604355B
+:1024E00008B90E4806E001344445F4D13046394677
+:1024F00032F074DEBDE8F081042C0200E3FB010041
+:102500009421020018FC010098210200F82B02001F
+:1025100020FC0100FC2B020018FC0100CA0286000E
+:1025200010B5084B02461B783BB1074B1B6898421D
+:1025300003D2064B53F8200010B9104632F026DFC4
+:1025400010BDC046982102007C200200781F0200C6
+:1025500010B5084B02461B783BB1074B1B689842ED
+:1025600003D2064B53F8200010B9104633F006DBB7
+:1025700010BDC04698210200802002008420020085
+:102580002DE9F04F234B8FB01C68234B82468946C0
+:10259000D3F800B00CB9204638E0036BA168186985
+:1025A00007AA00F0FFFD00261C4DB0462BE0A368F3
+:1025B0006F1F012B03D12878FFF702FF03E015F806
+:1025C000010CFFF7C5FF694633F00EDC002107ABB5
+:1025D0001DF80120CB5C1A420FD05046394632F02C
+:1025E000E5DD40B1B9F1000F05D009EB86003946B1
+:1025F0000422EFF3DDF5013602E001311C29E6D1BA
+:1026000008F101080835D845D1D130460FB0BDE8F2
+:10261000F08FC046082C0200F82B020025FC0100B8
+:10262000012902D14FF6FF7010E0D0F8BC304FF016
+:102630000002082BD0F8B03008BF41F40071A3F8B5
+:10264000D813B3F8DA33A0F8202698B27047C04602
+:10265000D0F8B030A3F8D813A3F8DA237047C046F7
+:10266000D0F8B0300021A3F8D8134FF0010230B5F4
+:10267000B3F8DA434FF00205A3F8D823B3F8DA230E
+:10268000A3F8D853B3F8DA3392B29BB2A0F820166D
+:10269000C4F3031040EA047042EA032240EA023025
+:1026A00030BDC04670B505460E461446FFF7B8FF6C
+:1026B000314600EA04022846FFF7CAFF70BDC04653
+:1026C00070B505460E461446FFF7AAFF40EA04021D
+:1026D0003146284692B2FFF7BBFF70BD2DE9F041AD
+:1026E0001546064688461C46FFF79AFF2C4020EA0E
+:1026F000050222433046414692B2FFF7A9FFBDE8EA
+:10270000F081C0462DE9F0411C46069B9046198099
+:10271000079D0E46FFF784FF089B28801E802B88AC
+:1027200004EA080423EA0803099A23431380BDE856
+:10273000F081C046D0F8B0304FF00002A3F8FC138F
+:10274000A0F82026B3F8FE0380B27047D0F8B0306E
+:1027500041EA0242C3F8FC237047C046D0F8B030CB
+:10276000A3F8FC13B3F8FE130A40A3F8FE234FF0BE
+:102770000003A0F82036704710B5D0F8B040A4F898
+:10278000FC13B4F8FE339BB21A434FF00003A4F8D5
+:10279000FE23A0F8203610BD10B5D0F8B04013408D
+:1027A000A4F8FC13B4F8FE1389B221EA02010B432A
+:1027B000A4F8FE334FF00003A0F8203610BDC04649
+:1027C0002DE9F04106460C462CE0254635F8023B43
+:1027D000571E990403F44043890CB3F5804F11D080
+:1027E00001DC3BB11CE0B3F5004F10D0B3F5404F16
+:1027F00012D015E03046628835F8023FFFF7CCFF73
+:10280000013F0DE030466288FFF7A0FF08E0304648
+:102810006288FFF7A3FF03E030466288FFF7ACFF52
+:10282000AC1C7A1E002AD0DCBDE8F0812DE9F04115
+:102830001C46069B90461980079D0E46FFF77AFFBF
+:10284000089B28801E802B8804EA080423EA0803DA
+:10285000099A23431380BDE8F081C04600234FF05E
+:10286000FF3280F8E33041F21A03C25403F59B7340
+:10287000C254704710B531B140F23B414FF6F87287
+:10288000FFF76CFF03E002490422FFF799FF10BD38
+:102890002E03020060B1B0F8DE00B0F5006F05D085
+:1028A000B0F5406F04D1A0F5386002E0402000E0B0
+:1028B00000207047012380F8E130704780F824162B
+:1028C0007047C04690F924067047C0467047C0461E
+:1028D00010B1C06900B141777047C04610B1C069FE
+:1028E00000B101777047C04610B590F8E330044658
+:1028F000002B49D14FF064014FF44872A0F88428AE
+:10290000A0F87C18A0F87E18C0F880381A46A318E2
+:1029100002324FF06401102AA3F88618F7D14FF065
+:102920000003A4F82E38A4F8AC37A4F8AE374FF063
+:102930000A034FF00A02A4F83E38A4F83C38A4F881
+:102940004038636A4FF01401A4F83228A4F84428F0
+:10295000A4F83428A4F84628A4F82A28A4F828289B
+:10296000A4F82C28A4F89027A4F892274FF050023E
+:10297000A4F83018A4F89427A4F842180BB1204604
+:102980009847012384F8E33010BDC04610B5FFF727
+:1029900067FE10BD2DE9F84F0C46D1F810A00D6868
+:1029A0009B468968E368064643EA812311469AB24A
+:1029B000BDF82880FFF7CAFE0027B9461EE0BAF12D
+:1029C000200F0BD159F8052030465946120CFFF75D
+:1029D000BDFE39F80520304641460AE0BAF1100F35
+:1029E00004D135F817203046414602E07A5D304682
+:1029F0004146FFF7ABFE013709F1040963689F42C6
+:102A0000DDD3BDE8F88FC0462DE9F74F0D460193A1
+:102A1000D1F810B00E68EB688968074643EA812355
+:102A200011469AB2BDF83090FFF790FE4FF00008C3
+:102A3000C24626E0BBF1200F0FD149463846FFF7CA
+:102A400079FE019904464AF806003846FFF772FEFF
+:102A500044EA00444AF806400FE0BBF1100F06D1EB
+:102A600038464946FFF766FE26F8180005E0384666
+:102A70004946FFF75FFE08F8060008F101080AF171
+:102A8000040A6B689845D5D3BDE8FE8F7FB50293E5
+:102A9000089B03910593099B0192049301A90A9B4A
+:102AA000984707B000BDC0467FB50293089B0391CD
+:102AB0000593099B0192049301A90A9B984707B0CB
+:102AC00000BDC0460B46D0F8F81012B141EA03032E
+:102AD00001E021EA0303C0F8F830704700B5D0F8F0
+:102AE000F8308E4621B143F01003C0F8F83012E000
+:102AF00023F0100312F0010FC0F8F8300BD041F2B0
+:102B0000D413C258C369196A986E814294BF714642
+:102B1000091AC2F8901000BD00207047A0F8DE101E
+:102B20007047C046A0F8DA107047C046B0F8DA0027
+:102B30007047C04640F6C313984201D800200BE00E
+:102B400041F2C843984201D8012005E041F24463B4
+:102B500098428CBF032002207047C0467047C04691
+:102B600000B5002286460748910030F822307345B0
+:102B700002D10B18588803E001320E2AF3D100204D
+:102B800000BDC046A8FC010010B5C8B2FFF7E8FFC1
+:102B9000FFF7D0FF10BDC04610B541F22823C45C3A
+:102BA0004FF0000C134B3CF803E0BEF10E0F8CBF4E
+:102BB0004FF480524FF400524EF4306342EA030067
+:102BC0002CB1BEF1940F02D9BEF1A50F0AD902298A
+:102BD00003D1BEF10E0F0BD904E0012902D1BEF1E1
+:102BE0000E0F05D80CF1040CBCF1380FDAD1FF2020
+:102BF00010BDC046A8FC010010B590F8B2321446D2
+:102C00000B6090F82B3653B190F8F83690F92A26DD
+:102C100023B1534243F080430B6000E00A6014B1DB
+:102C200090F8F7362370002010BDC04610B58646D8
+:102C30001C4641F21B031EF8033002989B000E292C
+:102C4000137008D80028ACBF0EEB00030EF1000390
+:102C500093F81E3127E07F23237030EA200028BF3D
+:102C600004200022114BD35A994202D00432382A50
+:102C7000F8D1A1F122031E2B04D80EEB000393F828
+:102C800083312370A1F16403282B04D80EEB0003D9
+:102C900093F8E8312370A1F19503102B04D80EEBC3
+:102CA000000393F84D32237010BDC046A8FC01000C
+:102CB0002DE9FF4700250746884691469A46FF269C
+:102CC0002C461EE0009341460DF10E020DF10F035C
+:102CD0003846FFF7ABFF41F2E623FA5C9DF80F1090
+:102CE00053B2994201DC002302E0C2EB0103DBB2E4
+:102CF0008DF80F30AB4228BF1D46B34238BF1E4689
+:102D00000134142CE3B2DDD189F800508AF8006058
+:102D1000BDE8FF877047C04690F829067047C04657
+:102D2000B0F8DA3003F47043B3F5805F09D1032AB9
+:102D300018DDA2F16503032B14D9A2F1C9030F2BEF
+:102D400010D9132A0EDCA2F13403642B0AD9A2F1A4
+:102D5000A9031F2B06D9A2F1D103072B94BF002092
+:102D6000012000E00020704770B590F8DA5004466A
+:102D70002846FFF7F5FEB4F8DA3003F47043B3F5F4
+:102D8000005F01D0002004E02B1903F59A530F33A4
+:102D9000187940B270BDC04600B54FF0000E00EB90
+:102DA0000E021EF801300EF1010EBEF1040F82F882
+:102DB0002C36F4D14FF0000E01EB0E0200EB0E03A7
+:102DC00012790EF1010EBEF1080F83F83026F3D10F
+:102DD00000BDC04680F8E0107047C046C3699961E5
+:102DE0007047C04680F8D5104176704780F8D910FA
+:102DF0007047C0467047C04690F81A067047C046F4
+:102E000041F22403C35C33B141F21C2380F81A164B
+:102E100080F81B16C154704790F8D83013B10023C6
+:102E200080F8D83000207047C369012093F88130C2
+:102E30000B70704722B10023C0F8E83FA0F8EC3FC8
+:102E400000F58153012019607047C0460022C16916
+:102E500010460B1893F982300130D2180828F8D1A7
+:102E600092FBF0F040B270477047C0466FF016001A
+:102E70007047C04670B541F21E23C35C04468B42C6
+:102E80000D46164603D0D0F8883003B1984704F5B4
+:102E900091531E8041F21E23E55470BD0021C36989
+:102EA000CB180131082983F88220F8D10021C369A9
+:102EB0006FF05B02CB180131082983F88220F6D12C
+:102EC000C2690023C2F88C30D36E032B08D1D0F82E
+:102ED000F83F13F0010F03D0136A0833C0F8F03F36
+:102EE00000F58A531233002204E0002241F2D2138B
+:102EF000C25470474FF6A47101321980198402330D
+:102F0000102AF7D1F1E7C04649F675334B6000232C
+:102F10000B60F0B50C469842ACBF01214FF0FF3179
+:102F200003F5340301FB03F103F53403081890FBA8
+:102F3000F3F202FB1303581A03D4C31301335B10DB
+:102F400004E04342DB1301335B105B425A2BD4BFD6
+:102F50000023012313B1A0F5340014E0002803DBA3
+:102F6000C31301335B1004E04342DB1301335B10F6
+:102F70005B4213F15A0FACBF002301230BB90126AA
+:102F800003E000F534004FF0FF364FF0000EF4463A
+:102F90007546604561682268144F0BDD41FA0EF3F7
+:102FA0009B18236042FA0EF3C3EB01036360EB59F5
+:102FB0009C440BE041FA0EF3C3EB0203236042FA98
+:102FC0000EF35B186360EB59C3EB0C0C0EF1010EB2
+:102FD0000435BEF1120FDCD1636806FB03F36360B6
+:102FE000236806FB03F32360F0BDC046F4FC010038
+:102FF00080EAE071A1EBE0710022D0B251FA00F357
+:103000000132002BF9DC70470146002000B58646EE
+:103010004FF0804343FA0EF31A188A424FEA5000E9
+:1030200002D8891A43EA00000EF1020EBEF1200F09
+:10303000EED1884238BF013000BDC046C36983F875
+:103040009010C36983F89120C36983F89210C36913
+:1030500083F893207047C046C36983F89210704785
+:1030600041F21633C256013BC0568242B4BF012022
+:10307000022070470048704750FD01000020704753
+:103080007047C046084670470020704741F2D81389
+:10309000C05803E0C3888B4202D000680028F9D1F1
+:1030A0007047C04610B5B0F8DA10FFF7EFFF10BD5B
+:1030B000C3699B6913F0005F09D0D0F8B0304FF0BE
+:1030C0000302A3F8B4264FF0FF02A3F8B826704716
+:1030D000D0F8F83013F0060F0CBF00200120704725
+:1030E0002DE9F0410F46B0F8DA10044615461E46A9
+:1030F000FFF74AFD40B9B4F9FC302B60B4F9FE305B
+:103100003360B4F900313B60BDE8F081D0F8A8002D
+:103110007047C04670B541F2D813C15805460AE061
+:103120000B6841F2D8142B51EB694FF43D7298684B
+:10313000F3F3DEF529590029F2D141F2D81305F550
+:1031400090523032E950043BEA504FF6CE70F033E3
+:10315000E852C2F8901070BD10B590F8E93094B004
+:1031600043F0010380F8E93004460021302201A831
+:10317000EEF366F7002110220DA8EEF361F70021AF
+:10318000042213A8EEF35CF711A800210822EEF345
+:1031900057F794F8E930002023F0010384F8E93070
+:1031A00014B010BD70B506460D46104614460021F9
+:1031B0001C22EEF345F700200F4BC25A41F22823A0
+:1031C000F35C1BB1942A01D9A52A10D9022D02D192
+:1031D0000E2A04D90BE0012D09D10E2A07D9D108F6
+:1031E00002F0070301229A40635C134363540430E6
+:1031F0003828E1D170BDC046A8FC010010B50C46CE
+:10320000002103F025F82070012010BD10B5002129
+:1032100003F01EF840B210BD41F2D41310B5C458EB
+:10322000F433C15819B1C36918693DF095DA002328
+:103230006370A37010BDC04610B59E462BB941F215
+:103240000723C35C704613600FE041B1012906D02B
+:10325000022904D0032902D06FF01C0005E041F2DE
+:103260000723C154FFF7D8FF002010BD41F2C82347
+:10327000C15810B509B9084607E0C36918693DF09F
+:103280006BDAD0F1010038BF002010BD10B541F25B
+:10329000F423C35C0BB104F097FD10BD10B503F02F
+:1032A000B5FB10BDC36970B5DC681B6D054613F036
+:1032B000010F0E4608D02046F7F3FAF520B1EB696E
+:1032C0009B6913F0005F12D1EA69136D13F0010FCF
+:1032D0003BD0536D13F0800F37D1D068F7F386F7EA
+:1032E000002832D0EB699B6913F0005F2DD0D5F830
+:1032F000F83013F0020F28D1EEB106F47043B3F5A5
+:10330000005F18D163691149232BB4BF00230C233C
+:10331000F2B2B8BF0F2120469A400123F7F3D0F54F
+:1033200063690B49222B2046D8BF7021CCBF4FF4D4
+:103330000072102206E0636904492046222BD8BFA0
+:103340000F2100220123F7F3BBF570BD00F05555A6
+:10335000000E5555D0F8B030C269D3F82031136D46
+:1033600070B513F0010F04460D4608D0D068F7F38E
+:103370009FF520B1E3699B6913F0005F11D1E26909
+:10338000136D13F0010F18D0536D13F0800F14D18B
+:10339000D068F7F32BF780B1E3699B6913F0005F06
+:1033A0000BD025B920462946FFF77CFF0AE02046CE
+:1033B000B4F8DA10FFF776FF00E01DB104492046AB
+:1033C000062202E0034920460E22FFF7F9F970BDFC
+:1033D000360302008CFC010010B514299E46D0F87B
+:1033E000A82004D015290CD06FF016000CE092F93B
+:1033F0001A3002A941F8043F70460422EEF3BCF5EE
+:1034000001E0039B9376002010BDC04610B590F8F4
+:103410001A360C462BB10231224601F091FDA378F9
+:10342000637010BD10B5012103F072FA10BDC046E3
+:103430002DE9F0418A79CB790D4642EA03216B7977
+:103440002A79074642EA0328C3695B690A2B07D930
+:10345000EB7C1B0213F4807002D10123EB7735E083
+:103460002A7A6B7A384601F0FF0442EA0326FFF716
+:103470004DFE7F2C1B4AC8BFA4F58074B30AD356F7
+:1034800090F85F00E21818F4006F14BF41F23B336C
+:1034900041F23A33FB56D11843B2C918AA7DEB7DED
+:1034A0007F2942EA0322C2F3C702C8BFA1F5807197
+:1034B0000E2AD4BF4FF400534FF4805342F43062CD
+:1034C000384649B243EA0202FFF7DCFD6A79C1B22D
+:1034D0002977384649B2C2F3801201F00DFBBDE8EE
+:1034E000F081C0461A22020010B590F8E9309646E5
+:1034F00053B313F0010F19D0D0F8F0308B420FD135
+:10350000C369D3F88C209B1883F882E0C269D2F893
+:103510008C30072B01D1002300E00133C2F88C303E
+:1035200090F8E93023F0010380F8E93090F8E930B1
+:1035300013F0020F08D023F0020380F8E930C369CA
+:10354000724618693DF01CD910BDC04690F8E930AC
+:1035500010B5ABB9012902D0022902D003E0C0F8AE
+:10356000F02080F8E910C3691B6AC0F8EC3041F222
+:103570000503C35C23B111466FF05E02FFF7B4FF91
+:1035800010BDC04637B5044602F01CFFE3691A6A55
+:1035900001321A6294F8E830002B77D041F262339E
+:1035A000E35A1BB1A4F86E38A4F8703841F26633C0
+:1035B000E35A1BB1A4F86838A4F8643841F26433C4
+:1035C000E35A1BB1A4F86238A4F86638E369196AB3
+:1035D0001A6EB1FBF2F302FB131323B92046B4F8C1
+:1035E000DA10FFF75FFED4F8F83013F00E0F05D1B4
+:1035F0002046012194F8DA20FFF7A8FF94F8E9307B
+:103600004BB1E369D4F8EC201B6A9B1A052B02D955
+:10361000002384F8E93041F22805615929B1E369B2
+:103620001A6A1B6E521A9A420BD3D4F8F83013F070
+:10363000020F06D12046FFF76FFA10B1E3691B6A4B
+:103640006351D4F8F83013F00F0F1FD1D4F88C3039
+:103650000BB120469847E36918693DF005D868B179
+:10366000E36901A918690DF107023DF007D820466A
+:103670009DF80710BDF80420FFF7FCFBD4F8F830E4
+:1036800013F00F0F02D1204603F0C0F900203EBD19
+:1036900010B50446FFF74AFA0221C2B22046FFF7EE
+:1036A00055FF10BDC36973B5012983F88110044625
+:1036B0000D46C36906D9186901220323009300212E
+:1036C000134605E0186900210323009301220B46ED
+:1036D0003CF0FADFE269537F002B30D0D4F8B030F1
+:1036E000D3F8203183F0010313F0010602D11069F1
+:1036F0003DF050D8012D0FD90222134620464FF439
+:103700008261FFF749F820464FF482610122022DC1
+:1037100014BF002301230BE020464FF482610222F4
+:103720000023FFF739F820464FF4826101222B462F
+:10373000FFF732F81EB9E36918693DF017D87CBD70
+:10374000C36970B547F67F750446582118692A4643
+:103750003CF0EEDFE3695A2118692A463CF0E8DFC5
+:10376000E369702118692A463CF0E2DFE3697221BF
+:1037700018692A463CF0DCDF70BDC046F7B5C26967
+:103780000546537F002B62D090F81A36002B45D0A7
+:10379000106928213F223CF0CBDFEB692421186916
+:1037A00010223CF0C5DFEB6995F82926186926211F
+:1037B00012013CF0BDDFEB6932211869B5F8FC2637
+:1037C0003CF0B6DF2E460027EB691869204BF95C08
+:1037D0003CF086DFEB6996F914250446A11D1869B3
+:1037E00092B23CF0A5DF96F914250223E96992FB19
+:1037F000F3F25242086992B204F10E0101373CF033
+:1038000097DF0136082FDFD1EA690323009310699F
+:103810008022012113463CF057DF18E001460420C6
+:1038200091F914350822073393FBF2F3DB000130E2
+:1038300081F8143501310C28F2D195F91425EB6982
+:10384000073218694E21C2F3CF023CF071DFFEBD92
+:103850002503020010B5012102F0B6FC40B210BDF4
+:1038600010B500210446621801317F23652982F8D2
+:103870009136F8D12046FFF7EDFF2046FFF7C6FC52
+:1038800010BDC0462DE9F04FB0F8DA30A5B003F412
+:103890007041B1F5805F14BF022201220592D0F879
+:1038A000A83004460693C3695A6C40F239539A42D1
+:1038B00004D052339A4201D0002304E0B1F5805F76
+:1038C00014BF00230123DBB2002165220DF1290082
+:1038D0000893EEF3B5F3B4F8DAA00AF44073B3F545
+:1038E000407F02D15FFA8AF810E0B3F5007F5FFAFB
+:1038F0008AF104D1DD2904D801F1020806E0022989
+:1039000002D84FF0000801E0A1F102082046059915
+:10391000FFF7A6FF2046FFF727FA4FF0000BC0B2D3
+:10392000FF255E4607900395CDF810B070E0204665
+:1039300051462A46FFF7F4F9002867D005EB040941
+:1039400099F8B26224AA571907F8676C94F8AC305A
+:1039500043B1059A204641462B46FFF78FFB3018AE
+:1039600007F8670C41460DF18E020DF18F032046DA
+:103970000095FFF75BF999F82C269DF88F309A4255
+:1039800034BF1146194641F2E623E25C53B2994234
+:1039900001DC002002E0C2EB0103D8B224AB5919CC
+:1039A00011F8673C984234BF02461A4601F8672C6A
+:1039B00094F8E030642B06D803FB02F3642293FBF7
+:1039C000F2F301F8673C11F8673C9DF88E20079EE2
+:1039D0009A4238BF1A462B1993F891368DF88F000A
+:1039E000934294BFC6EB0306C6EB0206049AF3B2F9
+:1039F0005B4588BF2A46049201F8673C039D5B45FE
+:103A000028BF9B46AB4238BF1D460395099E013631
+:103A10000996099A142AD5B289D104F5A260002129
+:103A20005132EEF30DF3039B049D84F8293684F89C
+:103A30002A360023184684F818B684F8F83684F835
+:103A4000195616E024AE731813F8672C94F81A363A
+:103A5000091981F875250BB1089B1BB194F818362C
+:103A60009B1A03E094F82936C3EB020381F8103562
+:103A700001301428C1B2E5D121460020069D91F9FC
+:103A80001035B5F9E623D218431CD8B281F81025B9
+:103A900001310428F2D1E36A0BB12046984725B0E2
+:103AA000BDE8F08F70B505460E462C46FFF774F959
+:103AB000294600203218137D03B91379013081F8AB
+:103AC000383601310828F5D10021721892F84430B7
+:103AD00003B91379013184F8483601340829F4D147
+:103AE000EB6918693CF056DE2846FFF7CBFEEB6920
+:103AF00018693CF03BDE70BD7F2970B5044601D9E2
+:103B0000052028E0002213190132652A83F8B21239
+:103B1000F9D10023E26984F8F736137FD3B1D4F8E2
+:103B2000F83013F0020F15D1D4F8B030D3F82031AB
+:103B300083F0010313F0010502D110693CF02ADE85
+:103B40002046FFF79FFE2DB9E36918693CF00EDEB1
+:103B5000284600E0002070BD70B5054600F52C70C9
+:103B6000042202300C46EEF307F205F52C70211DFD
+:103B700008220630EEF300F205F52E70082206301A
+:103B800004F10C01EEF3F8F105F538700822063067
+:103B900004F13401EEF3F0F105F53A700822063035
+:103BA00004F13C01EEF3E8F105F53070082206302F
+:103BB00004F11401EEF3E0F105F53270082206304D
+:103BC00004F11C01EEF3D8F105F53470082206303B
+:103BD00004F12401EEF3D0F105F536700822063029
+:103BE00004F12C01EEF3C8F105F53C700822063013
+:103BF00004F14401EEF3C0F105F53E7004F14C010F
+:103C000008220630EEF3B8F105F5407008220630C0
+:103C100004F15401EEF3B0F105F5427006300822CC
+:103C200004F15C01EEF3A8F194F8643085F81633E2
+:103C3000D5F8B030D3F8203113F0010309D11C4678
+:103C40002846FFF71FFE54B1EB6918693CF08EDD82
+:103C500005E0EB69012418693CF09CDDF0E770BDDC
+:103C60002DE9F0410F460546FFF710FA07F47043BF
+:103C7000B3F5805FEB69FAB208BF42F48072044684
+:103C8000A02118693CF054DDAE6A2CB104F517721E
+:103C900041F2D413EA5005E005F59053303341F278
+:103CA000D412AB5016B128463946B0472CB341F276
+:103CB000D413EA58537873B1EB6941F2C8242959F7
+:103CC00018693CF049DDEB6900221869295913464F
+:103CD0003CF0C0DC11E041F20723EB5C6BB1032B3D
+:103CE0000BD0E969D2F890200B6A9B1A8A6E934236
+:103CF00003D328460221FFF7D5F928463946FFF7B6
+:103D0000D1FABDE8F081C046E02910B50B46044663
+:103D100002DD6FF0120012E043F430630E29D4BFCD
+:103D20004FF400514FF48051194389B2FFF798FFC7
+:103D30000123204684F8D83008F092FF002010BDFF
+:103D400070B50C460546FFF767F844B9284605F0FC
+:103D5000D9FE28464FF4404106F0AEF910E0214666
+:103D600028460022FFF7D0FF044648B928462146DE
+:103D70007022234605F04AFB28465E2106F0EEFD40
+:103D8000204670BD2DE9F0410D460446FFF744F88A
+:103D900045B92046294602F0B3FC2F4641F2D42310
+:103DA000E55213E0204629460122FFF7ADFF074602
+:103DB00060B941F2D426A35B23B920460A21FEF75D
+:103DC000B9FCA0532046294602F09AFC3846BDE8CB
+:103DD000F081C04670B50E460546D0F8B040FFF7FA
+:103DE0001BF83EBB41F2D6240A2128462A5BFEF787
+:103DF000ADFC284640F24B413246FEF7A7FC284670
+:103E0000314602F0DDFBEB692E531B6D13F0020F00
+:103E100056D041F2D823D5F8B020EB5A4FF47A703F
+:103E2000A2F89C3441F2DC23EB5AA2F89E34F2F360
+:103E300093F445E0EB691B6D13F0020F1FD0D5F82A
+:103E4000B01041F2D822B1F89C344FF47A709BB292
+:103E5000AB50B1F89E3404329BB2AB50B4F89C34F2
+:103E600023F400731B041B0CA4F89C34B4F89E3498
+:103E70009BB243F40073A4F89E34F2F36DF4314620
+:103E800028460122FFF740FF0646C8B941F2D62472
+:103E90002B5B5BB90A212846FEF74CFC40F24B41F4
+:103EA00028534FF6FF722846FEF750FC28460121A2
+:103EB00002F086FB28460A214FF49472FEF75CFC60
+:103EC000304670BD2DE9F0418AB005AED0F8B07033
+:103ED00005468846142238493046EEF34DF0142248
+:103EE00036496846EEF348F0EB6900216C461869E4
+:103EF000142288450CBF234633463CF023DC4FF0A8
+:103F00000003A7F86835B8F1000F4FF48073A7F8E5
+:103F1000C0370CBF40234123A7F80C3541F60223DC
+:103F2000A7F814354FF00003A7F80835A7F80A35AD
+:103F3000A7F84C354FF01403A7F86A3540F626036E
+:103F4000A7F868354FF00003A7F800354FF0D0030D
+:103F5000A7F80235B7F802350CBFFA251E25002454
+:103F600002E00A20F2F3F8F3AC420ADAB7F80E35B1
+:103F7000013413F0800FF4D103E00A20F2F3ECF3E4
+:103F800000E0002401340B2C09D0B7F80E3513F4EF
+:103F9000806FF2D003E00A20F2F3DEF300E00024A9
+:103FA00001340B2C04D0B7F8903613F4807FF2D193
+:103FB0000AB0BDE8F081C046E0FC01003CFD010014
+:103FC00070B590F8E2200446002A6CD1012380F8F5
+:103FD000E230D0F8B030A0F8DA10D3F8203100F594
+:103FE00081531A60D0F8F82012F0020F06D190F831
+:103FF000803E1BB942F02003C0F8F830256A002D3E
+:1040000051D001212046FEF735FCB4F8DA30B4F87F
+:10401000DE2003F44061914203D0E36918693CF06B
+:1040200035DB012141F2CD23E1542046FFF792F91F
+:104030002046A847002384F8E1302046FFF79EFB86
+:10404000E369204693F88110FFF72CFBE26992F8B0
+:104050008030012BB4F8DA300BD103F47043B3F5A0
+:10406000005F01D1936F0BE0D36F012B88BF00235A
+:1040700006E003F47043B3F5005F0CBF136F536F9A
+:10408000D366E3690022D96E2046FEF7D3FE0023F3
+:1040900084F8E230E369922118693CF02BDB41F2AD
+:1040A00022234000E05270BDC36910B518693CF08E
+:1040B0002BDB10BDC36910B518693CF02FDB10BDB8
+:1040C000F7B5089F04460D461E463BB1032A05D9A5
+:1040D000684619460422EDF34FF701E000230093F0
+:1040E000A82D009900F0FB8015DC5C2D00F0AE805F
+:1040F00008DC3C2D00F0A0804A2D00F093801B2DA1
+:104100002AD020E05E2D30D0C0F2A8805F2D3DD0B7
+:10411000872D1BD017E0C32D75D006DCAA2D49D002
+:104120007BDBC22D00F0DB800DE0D42D00F0AB80F6
+:1041300003DCD32D00F09B8005E0A5F59A73033BCB
+:10414000012B40F2D2806FF01605CFE02046FEF73B
+:104150007DFE40B23060C8E0E3691D7F002D40F075
+:10416000B8802046FEF77AFBC0E001233B70E3698C
+:104170005B7F002B00F0B0802046FFF79BFF2046BE
+:10418000BDF80010FEF7D6FA30600FE001233B7057
+:10419000E3695B7F002B00F09F802046FFF78AFFDA
+:1041A000009A204691B2120CFEF7D0FA2046FFF793
+:1041B0007BFF9AE0E269537F002B00F08D8010694D
+:1041C0003CF0E8DA00252046FFF774FF3560D4F8AC
+:1041D000BC30082B13D10DF1060220460DF107016A
+:1041E0008DF807508DF8065000F0AAFE9DF90720C3
+:1041F0009DF9063092B29BB243EA02233360204617
+:10420000FFF752FF60E0E3691B7F002B6AD0338821
+:10421000022B64D96FF0010568E0E3691B7F002B76
+:1042200060D05CE0E3691B7F002B52D1236B002B35
+:104230005BD02046984718E0E3691B7F002B48D1EC
+:1042400020467268B368FFF7C5FD0EE0E3691B7F87
+:10425000002B3ED12046FFF773FD06E0E3691B7F8C
+:10426000002B36D12046FFF78DFD05463EE0E36981
+:10427000DA6E3260D4F8F83F13F0010F35D042F017
+:104280008003336031E0042902D96FF01C052DE072
+:10429000E269D36E8B4228D0137FD1662BB31069AD
+:1042A0003CF078DA009B23B1204600210122FEF782
+:1042B000C1FDE36901222046D96EFEF7BBFD00284F
+:1042C00014BF00256FF00205E36918693CF04EDA6F
+:1042D0000CE06FF0040509E06FF00A0506E06FF0EE
+:1042E0000C0503E06FF0030500E000252846FEBD45
+:1042F0002DE9F04389B09946109B0026032B074611
+:104300000C46DDF84480139D079604D907A849465A
+:104310000422EDF331F6079940F286230A1E18BFF6
+:1043200001229C4200F013812CD80C3B9C427CD093
+:104330000FD8532C08D8522C80F04081502C00F01C
+:104340003D81512C6AD02DE140F26A239C4250D02D
+:1043500028E1B4F5207F00F0E48009D840F27B2307
+:104360009C4200F0A48003339C4200F0D58019E108
+:10437000B4F5217F00F0E48040F285239C4200F0F8
+:10438000DB800FE140F2D6239C4200F0178114D865
+:10439000413B9C423ED006D8043B9C4234D0023381
+:1043A0009C4234D0FEE0B4F5277F00F0D78040F285
+:1043B0009D239C4200F0D680F4E040F2DD239C4235
+:1043C00000F0EB8008D8033B9C4200F0D180B4F5AC
+:1043D000377F00F0D680E5E0B4F53D7F00F0F38054
+:1043E000C0F0E080A4F53E73063B012B00F2DA80BA
+:1043F000E9E03846FFF75EFE38464146FFF706F82B
+:104400003846FFF751FE50E041F2623304E041F2DA
+:10441000643301E041F26633F95246E00123009330
+:1044200038464346FEF722FDCFE0FA69137F13B901
+:104430006FF00300C9E0D7F8B030D3F8203183F033
+:10444000010313F0010902D110693CF0A3D93846E9
+:10445000FEF72EFE3846FFF72DFE41F2E61341F23D
+:10446000E910F95C385C0133FA5C013317F803E0BA
+:10447000009041F2EA103D5C01303C5C1630385C43
+:10448000734603903846019502940496FEF764FE45
+:10449000C8F800003846FFF707FEB9F1000F40F0FA
+:1044A0008D80FB6918693CF061D930468DE0C1F31D
+:1044B000036CBCF1010F00F28380C1F3015EBEF119
+:1044C000010F7DD8C1F38155032D79D0C1F3034489
+:1044D000012C75D8C1F30722A2F10A03DBB2052B28
+:1044E0006ED8C8B2012801D9032869D10E2A28BF85
+:1044F0000E2241F2E613FA540133F8540133FC540E
+:10450000013307F803E00133FD54013307F803C01A
+:104510000A0F1633FA54C8E708A9012341F8043DED
+:1045200007E0B7F8DA103846FEF72EFB08A941F885
+:10453000040D40462A462DE041F21B03F954B4E72E
+:1045400041F21B03FB5C08A941F8043D17E0D7F8D2
+:10455000F830C3F30013C8F80030A6E738464246E7
+:10456000334602E0384642460123FEF765FE9CE7EB
+:104570000121384601F03AFF08A941F8046D404690
+:1045800007E007AC38463146224601F093FF40462B
+:1045900021460422EDF3F0F487E73846324601F075
+:1045A00089FF82E701910292384621464A464346F6
+:1045B0000095FEF711FF10F1170F04D0002004E062
+:1045C0006FF01C0001E06FF0160009B0BDE8F08349
+:1045D0002DE9F04391460A6801230B7342F008036A
+:1045E0000B60B0F9FA3685B0B3F1FF3F04BF42F07B
+:1045F00009030B6090F81A3605460C461BB10B6890
+:1046000043F002030B602F4626464FF0000897F850
+:10461000B2322846B37749460DF10E030DF10F0271
+:10462000CDF80080FEF702FB9DF80E3008F101087E
+:1046300086F8B03197F87535013786F8793201364A
+:10464000B8F1140FE3D195F81A3633B3EB691B7F39
+:104650001BB32846FFF72EFD95F818362846A3759C
+:1046600095F81836E37595F81936A37695F8193646
+:10467000E37600F05BFC236810B143F0030301E034
+:1046800023F003032846236004F10D0104F1150211
+:1046900000F056FC2846FFF707FD05B0BDE8F083A3
+:1046A00010B5054B1B78012B03D1013B18461B703D
+:1046B00001E014F00BFE10BD3C28020010B5054BC4
+:1046C0001B78012B03D1013B18461B7001E014F04D
+:1046D00023FE10BD3C2802002DE9F04105460E46A0
+:1046E00017461C46FFF7EAFF30B1234628463146FD
+:1046F0003A4614F04BFE04462046BDE8F081C04621
+:1047000010B50023FFF7E8FF10BDC04610B51446F2
+:10471000FFF7D4FF20B100210A46EEF319F004465A
+:10472000204610BD10B50022FFF7F0FF10BDC046B7
+:104730001FB5079B0C890093089B11460193099BA9
+:10474000224602930A9B03930069069B28F02EDD04
+:1047500004B010BD00B5B0FBF1FE01FB1E0001F07E
+:10476000010C0CEB51010BE0884228BFC1EB0003A8
+:104770004FEA4E0E26BF0CEB43000EF1010E400037
+:10478000531EDAB2FF2AEFD1884228BF0EF1010E84
+:10479000704600BD00FB01F19202800103FB002086
+:1047A00001F5004101EB4000490090FBF1F070473A
+:1047B000D0F8A8304FF001025A8670472DE9F04733
+:1047C00098469DF820308A4691469DF82470B3B1F2
+:1047D00000246FF000462546204651464A4643468F
+:1047E000FFF7D8FFB04204DA6B1CDDB2BD421AD02D
+:1047F00006460134802CEFD16FF0004013E07F2497
+:104800004FF0FF361D46204651464A464346FFF7C5
+:10481000C1FFB04204DD6B1CDDB2BD4203D00646D1
+:10482000013CF0D22046BDE8F087C04610B5B0F894
+:10483000DA300446DAB203F47043B3F5005FD0F81F
+:10484000A81003D1531893F8E72486E0702A5ED0AD
+:104850001CD8382A49D00CD82C2A3DD004D8242A78
+:1048600034D0282A35D02FE0302A38D0342A39D015
+:104870002AE0642A42D004D83C2A39D0402A3AD0CF
+:1048800022E0682A3DD06C2A3ED01DE0882A50D014
+:104890000CD87C2A44D004D8742A3BD0782A3CD047
+:1048A00012E0802A3FD0842A40D00DE0992A49D0D6
+:1048B00004D88C2A40D0952A41D005E0A12A47D0BF
+:1048C000A52A48D09D2A40D0002246E091F8F6243F
+:1048D00043E091F8F72440E091F8F8243DE091F8A6
+:1048E000F9243AE091F8FA2437E091F8FB2434E017
+:1048F00091F8FC2431E091F8FD242EE091F8FE249B
+:104900002BE091F8FF2428E091F8002525E091F8AC
+:10491000012522E091F802251FE091F803251CE013
+:1049200091F8042519E091F8052516E091F806257F
+:1049300013E091F8072510E091F808250DE091F8B3
+:1049400009250AE091F80A2507E091F80B2504E013
+:1049500091F80C2501E091F80D25D1F8E40494F8C4
+:104960002A36C01A801840B210BDC04608467047AB
+:1049700049B24B1C5B104910C3F10803083141EAEE
+:10498000031188B27047C046B0F8DA3003F47043C0
+:10499000B3F5005FD0F8A82005D192F83C05FF28B8
+:1049A00001D0C0B200E000207047C04670B5054697
+:1049B000D0F8A840FFF7E8FF10B994F8460540B1D9
+:1049C000B5F8DA3003F47043B3F5005F14BF00208C
+:1049D000012070BD10B50C468EB0D0F8A8109646D8
+:1049E000002000220DF10603C25401303228F8D114
+:1049F000BEF1FF3F91F8E93306D114B1B1F93EE5BC
+:104A000003E0B1F940E514E09CB1A02B09D00023EC
+:104A10008DF806308DF807308DF808308DF80930A4
+:104A200004E000238DF806308DF808308DF80A3048
+:104A300033E0A02B17D001238DF81A308DF81B30EE
+:104A40006FF0010300228DF81E308DF81F30013306
+:104A50008DF81C208DF81D208DF820208DF8213038
+:104A60008DF8242019E002238DF81A306FF003032B
+:104A70008DF81E30023300228DF81F308DF8203063
+:104A80008DF8213006338DF81B208DF81C208DF811
+:104A90001D208DF824208DF832300EAA02EB0E0373
+:104AA00013F9320C0EB010BD30B5C46900F5805357
+:104AB000226A1B68D0F8A8509A4202D3C3EB0201C5
+:104AC00001E0DB43991895F8BC2290F8DA309A425D
+:104AD00001D0012004E0A36E994234BF00200120E0
+:104AE00030BDC0467047C046D0F8A83093F80604E1
+:104AF000002808BF1020704700B5D0F8A8008E46E7
+:104B0000D0F8D4240EF0FF0343EA0223110EC0F8BC
+:104B1000D434D0F8D8347F29C8BFA1F5807173444C
+:104B20005B1AC0F8D8349B10C0F8DC3400BDC04616
+:104B3000844610221B4810B5964600244EF34603C7
+:104B40005FFA83FE10EA0C0F4FFA8EF104D0884012
+:104B50000EEB0203DAB203E0C840CEEB0203DAB296
+:104B60000134042CEAD110EA0C0FD3B201D1013B7D
+:104B7000DAB251B2032301FB03F30329DAB20EDDEB
+:104B8000CB1E2CFA03F00D2801D9D31C06E00A280D
+:104B900001D9931C02E0082801D9531CDAB250B2A3
+:104BA00010BDC0460000FFFFD0F8A820002382F807
+:104BB000903382F8913382F8923382F8933382F8FB
+:104BC000943370477047C04670B540F22341D0F827
+:104BD000A8500446FDF7AEFDC0B2A5F864034FF43B
+:104BE000AA612046FDF7A6FD8005800DA5F86803A3
+:104BF00040F234412046FDF79DFDC0B27F28C8BF7A
+:104C0000A0F58073A5F8660340F23241C8BFA5F84D
+:104C100066332046FDF78EFDC0B27F28C4BFA0F5E5
+:104C2000807398B285F8BC0370BDC0462DE9F0478B
+:104C3000884640F2B76104469146FDF77BFD40F29D
+:104C4000B66105462046FDF775FD40F2B5610646A2
+:104C50002046FDF76FFD40F2B46107462046FDF7A0
+:104C600069FD4FF0000C6246644650FA04F313F0FD
+:104C7000010101D0012103E00CF101035FFA83FC83
+:104C8000531CDAB2102A12D001340029EDD00EE004
+:104C9000A2F1100357FA03F313F0010F01D0012121
+:104CA00003E00CF101035FFA83FC531CDAB21F2A04
+:104CB00011D80029ECD00EE0A2F1200356FA03F33C
+:104CC00013F0010F01D0012103E00CF101035FFAA1
+:104CD00083FC531CDAB22F2A11D80029ECD00EE045
+:104CE000A2F1300355FA03F313F0010F01D00121B3
+:104CF00003E00CF101035FFA83FC531CDAB23F2A94
+:104D000001D80029ECD04FF03F0E00220F2455FAB5
+:104D100004F313F0010101D0012103E00EF1FF3390
+:104D20005FFA83FE531CDAB2102A12D0013C00292C
+:104D3000EDD00EE0C2F11F0356FA03F313F0010F9A
+:104D400001D0012103E00EF1FF335FFA83FE531C13
+:104D5000DAB21F2A11D80029ECD00EE0C2F12F03DD
+:104D600057FA03F313F0010F01D0012103E00EF114
+:104D7000FF335FFA83FE531CDAB22F2A11D80029C1
+:104D8000ECD00EE0C2F13F0350FA03F313F0010F31
+:104D900001D0012103E00EF1FF335FFA83FE531CC3
+:104DA000DAB23F2A01D80029ECD088F800E089F86F
+:104DB00000C0BDE8F087C04670B50D4640F23941ED
+:104DC0000646FDF7B7FCC0F3C210E88040F2B541DB
+:104DD0003046FDF7AFFC40F2FB4104463046FDF79C
+:104DE000A9FC04F0FF03C0B2C4F307242B806C803D
+:104DF000A88070BD2DE9F047B0F8DA30074603F41B
+:104E00007043B3F5805FD0F8A82009D1B2F89205BD
+:104E100003B2B3F1FF3F0CBF4FF4C87080B24CE057
+:104E2000B2F8904523B2B3F1FF3F01D0A0B244E005
+:104E300040F2A541FDF77EFC40F2A541814638468F
+:104E4000FDF778FC40F20D4106463846FDF772FC4E
+:104E500040F20D4104463846FDF76CFC40F2A24199
+:104E600005463846FDF766FC40F2A24180463846CA
+:104E7000FDF760FCC6F30236012313FA06F6C0F311
+:104E80000220C5F3022513FA05F58340E4B25FFA68
+:104E900089F94C44B6B2A419ADB29BB25FFA88F856
+:104EA0006419434404EB430464005034A4B2B4F5E1
+:104EB000C86F2CBF20464FF4C860BDE8F087C046DD
+:104EC00010B540F2FB41FDF735FCC0F3062010BDE4
+:104ED00070B540F2A4410446D0F8A850FDF72AFC72
+:104EE000C0F38130032814D141F22403E35C83B181
+:104EF000204640F27341FDF71DFC95F96635C0056B
+:104F0000C00D013303FB00F3022293FBF2F3D8B28E
+:104F100001E095F8C10240B270BDC04610B540F244
+:104F2000A441FDF707FC00F4404010BD10B5FFF7A9
+:104F3000F5FFB0F5404F14BF0020012010BDC04662
+:104F400070B5002313700B7041F22403C35C044658
+:104F50000D4616461BB340F2AB41FDF7EBFB10F4D8
+:104F6000004F03D0204640F2AB410AE0204640F219
+:104F70003C61FDF7DFFB10F4004F07D0204640F204
+:104F80003C61FDF7D7FBC0F3470028702046FFF7D0
+:104F9000CDFF08B194F810052B781B18337070BD45
+:104FA0002DE9F04140F2FF340E4605469046334667
+:104FB000224640F24561FDF7EFFB28462246434674
+:104FC00040F24661FDF7E8FB28462246334640F2B0
+:104FD0004761FDF7E1FB2846224643464FF4C9618D
+:104FE000FDF7DAFB28462246334640F24961FDF7D9
+:104FF000D3FB284640F24A6122464346FDF7CCFBEC
+:10500000BDE8F08170B5002914BF4FF48073002310
+:1050100004460D1E18BF01254FF480724FF49661AF
+:10502000FDF7BAFB0122204640F24C412B46FDF72A
+:10503000B3FB2B0320464FF496614FF4805203F4E8
+:105040007043FDF7A9FB6B0320464FF496614FF4C4
+:10505000005203F46043FDF79FFB6B0120229BB2DB
+:1050600020464FF49661FDF797FB6B0203F47E43F5
+:10507000204640F2AE414FF40072FDF78DFBB4F8CC
+:10508000DA3003F47043B3F5005F11D1AB02204670
+:105090004FF496614FF4806203F47C43FDF77CFB90
+:1050A000EB009BB2204640F2E5410822FDF774FB7D
+:1050B00070BDC04670B50C02A4B20546234640F24E
+:1050C000FB414FF4FE42FDF767FB284640F2FD41ED
+:1050D0004FF4FE422346FDF75FFB70BD70B500291B
+:1050E00014BF802300230C1E18BF012480224FF41C
+:1050F00096610546FDF750FBA303A40128464FF433
+:1051000096614FF4804203F44043A4B2FDF744FBA0
+:10511000284640F23B4140222346FDF73DFB70BD4F
+:1051200070B540F239440D4621460646FDF702FBB4
+:1051300040F67F4300EA030343EAC51330462146A5
+:1051400040F6FF729BB2FDF727FB70BD2DE970435F
+:105150000C460646FFF7B4FE628823884FF6FF79B7
+:1051600043EA022305464A46304640F2B5419BB227
+:10517000FDF712FB2D02A388ADB247F6FF7830464B
+:10518000424645EA030340F2FB41FDF705FB628816
+:105190002388304643EA022340F2FC414A469BB250
+:1051A000FDF7FAFAA3883046424645EA030340F287
+:1051B000FD41FDF7F1FA3046E188FFF7B1FF3046D7
+:1051C0000121FFF78BFFBDE87083C04610B502498F
+:1051D0000C22FDF7F5FA10BD380D02002DE9F0475D
+:1051E0009846BDF82CA0BDF824308946BDF82010A3
+:1051F0000AF00304164603F00F03BDF8282044EA22
+:10520000032301F00F0102F0030243EA013343EAF2
+:10521000821343EA021343EA840340F2B6414FF695
+:10522000FF720746BDF83050FDF7B6FA0F2208EAC4
+:105230000203384640F2B741FDF7AEFA4FEACA23FF
+:105240009CB22346384640F2B1414FF460522D03E0
+:10525000FDF7A2FAADB2062238462049FDF7B0FAB2
+:105260007602384640F2AE414FF470422B46FDF7CD
+:1052700093FA384640F2B1414FF4007206F47E438F
+:10528000FDF78AFAD9F1010338BF0023012238461D
+:1052900040F24D41FDF780FAB7F8DA3003F470437D
+:1052A000B3F5005F10D1384640F2B1414FF4C0521F
+:1052B0002346FDF771FA4FEACA039BB2384640F223
+:1052C000E6411822FDF768FA384640F2AE414FF445
+:1052D00070422B46FDF760FABDE8F087A209020094
+:1052E00010B5044686B021B90D490E22FDF768FAC3
+:1052F00014E00C490922FDF763FA0021032206237A
+:10530000009302920423039220460A4604910193DB
+:10531000FFF764FF20460121FFF774FE06B010BDC1
+:10532000420702005E07020010B5D0F8A830D3F89B
+:10533000741529B1C3694FF420729868F1F3D8F459
+:1053400010BDC0462DE9F041D0F8A8300646D3F88C
+:105350007C55D3F8787500240DE0142302FB03F389
+:10536000EA1811695268F06902FB01F28068E95895
+:10537000D208F1F3BDF4E2B20134BA42EDD3BDE894
+:10538000F081C04670B5D0F8A8500446D5F87C35F9
+:105390006BB10121FFF7D6FFE369D5F878451422F8
+:1053A0009868D5F87C1504FB02F2F1F3A1F470BD06
+:1053B00041F2F023C15810B5044629B1C36942F641
+:1053C00008529868F1F394F42046FFF7ADFF2046A9
+:1053D000FFF7D8FFE369D4F8A81098684FF4B962D2
+:1053E000F1F386F410BDC04610B54FF48052044668
+:1053F000002340F2C961FDF7CFF9D4F8A820B2F834
+:10540000C234EBB192F8E933A02B04D1204640F22C
+:105410008961232203E0204640F289613022FDF7B2
+:1054200095F9D4F8A830B3F8C234022B0ED14FF45A
+:105430008052204640F2C9611346FDF7ADF905E000
+:10544000204640F289612322FDF780F9042220469C
+:105450002749FDF7B5F90022204640F27961FDF7B2
+:1054600075F9082220462349FDF7AAF9D4F8A83097
+:105470002046B3F8C2244FF4D961FDF767F906223C
+:1054800020461D49FDF79CF9D4F8A8304FF48072EE
+:10549000B3F8C23420461A41013A4FF4D06192B2B7
+:1054A000FDF754F9D4F8A8304FF4A072B3F8C23421
+:1054B00020461A41013A92B240F28161FDF746F965
+:1054C000D4F8A830B3F8C224012A04D0022A14BFA9
+:1054D0003422082200E01822204640F27F61FDF7C6
+:1054E00035F9204605490E22FDF76AF910BDC04680
+:1054F000440B02004C0B02002E0C02003A0C02007E
+:105500002DE9F04740F23C4631460446FDF712F9DA
+:1055100040F23B48824641462046FDF70BF94AF0EF
+:10552000010281463146204692B2FDF70FF949F05B
+:105530000102204641464FF6FE7592B2FDF706F98C
+:10554000204631460AEA0502FDF700F920464146A9
+:1055500009EA0502FDF7FAF8204631465246FDF702
+:10556000F5F8204641464A46FDF7F0F8BDE8F087D9
+:10557000802270B513460C4640F2D1610546FDF716
+:105580000BF90CB1012C05D128464FF4DA610F223A
+:10559000FDF7DCF82846FFF7B3FF70BD2DE9704337
+:1055A0000E46B0F8DA10054601F47041B1F5005F1F
+:1055B00014BFA521892199469046FDF731F8B5F829
+:1055C000DA10044601F47041B1F5005F14BFA52163
+:1055D00089212846FDF724F804F00F04C0F30310D6
+:1055E000241A3470B5F8DA10284601F47041B1F588
+:1055F000005F14BFA6218A21FDF712F8B5F8DA1072
+:10560000044601F47041B1F5005F14BFA6218A2160
+:105610002846FDF705F804F00F04C0F30310241A20
+:1056200088F80040B5F8DA10284601F47041B1F569
+:10563000005F14BFA7218B21FCF7F2FFB5F8DA1049
+:10564000044601F47041B1F5005F14BFA7218B211E
+:105650002846FCF7E5FF04F00F04C0F30310241AFA
+:1056600089F80040B5F8DA10284601F47041B1F528
+:10567000005F14BFA8218C21FCF7D2FFB5F8DA1027
+:10568000044601F470412846B1F5005F14BFA8211B
+:105690008C21FCF7C5FF04F00F04C0F30310069B38
+:1056A000241A1C70BDE87083B0F8DA1010B501F44C
+:1056B00070410446B1F5005F14BFA52189218822FD
+:1056C000FCF7C6FFB4F8DA10204601F47041B1F5DA
+:1056D000005F14BFA6218A218822FCF7B9FFB4F825
+:1056E000DA10204601F47041B1F5005F14BFA72124
+:1056F0008B218822FCF7ACFFB4F8DA10204601F4C5
+:105700007041B1F5005F14BFA8218C218822FCF7FD
+:105710009FFF10BD10B5D0F8A830044693F8E933C8
+:10572000A02B03D110490422FDF74AF8204600229D
+:105730004FF48E71FCF78CFF204618220B49FDF7C1
+:105740003FF841F2EE23E35A2046FF2240F2346153
+:10575000002B08BF0C23FDF71FF82046044909223F
+:10576000FDF72EF810BDC046580D0200600D020076
+:10577000900D020070B504220D4607490646FDF75C
+:105780001FF80024054B625BE15A30460234FCF7F7
+:105790005FFF302CF6D170BDD60B0200D2040200A0
+:1057A0002DE97043054698461646B0F8DA40FFF7F3
+:1057B000DFF804F47044B4F5005F14BFA524892415
+:1057C0000246214628469DF81890FCF741FF3146D5
+:1057D0002846FFF7CDF8B5F8DA40024604F47044E5
+:1057E000B4F5005F14BFA6248A2428462146FCF79E
+:1057F0002FFF41462846FFF7BBF8B5F8DA400246CE
+:1058000004F47044B4F5005F14BFA7248B24284629
+:105810002146FCF71DFF49462846FFF7A9F8B5F8D1
+:10582000DA40024604F47044B4F5005F14BFA824C3
+:105830008C2428462146FCF70BFFBDE87083C04648
+:1058400070B505460E460024074BA25BE15A284678
+:105850000234FCF7FDFE182CF6D1284603492246F7
+:10586000FCF7AEFF70BDC046800B0200880C020042
+:1058700070B506220E4644490446FCF7A1FF0025F8
+:10588000424B2046E95AFCF7CBFEA8530235182DAF
+:10589000F6D1072101222046FCF7DAFE1022FF2173
+:1058A00013462046FCF71AFF04221346204640F216
+:1058B0001F11FCF713FF0C2220463549FCF780FF2F
+:1058C00001223A2113462046FCF708FF04223A2120
+:1058D00013462046FCF702FF0822134620464FF4E9
+:1058E0008D71FCF7FBFE0822052113462046FCF7CC
+:1058F000F5FE0122134620464FF48D71FCF7EEFEB3
+:10590000122220462349FCF75BFF20228221134606
+:105910002046FCF7E3FEB4F8DA3003F47043B3F545
+:10592000005F02D000252E4608E0D4F8A8309A7A0D
+:10593000D97A42F400721D7B42EA01160122204608
+:1059400013464FF49B61FCF727FF2046B3004FF44A
+:105950009B6140F6FC72FCF71FFF022220461346B3
+:105960004FF49B61FCF718FF2B0320464FF49B611B
+:105970004FF4E04203F47043FCF70EFF2046064963
+:105980000622FCF71DFF70BD16080200800B020006
+:10599000AE090200C6090200EA0902002DE9F74F2C
+:1059A000D0F8A830814693F80B809C7A1A7E1F7B32
+:1059B0004FEA081844F4007493F817B09E7D44EA47
+:1059C0000804009293F814A0DD7C44EA07345B7D60
+:1059D00047F2FF38A4B2092223490193FCF7F0FEF5
+:1059E00048464246234640F2DB41FCF7D5FE484696
+:1059F0004246234640F2DC41FCF7CEFE4846424692
+:105A0000234640F20A41FCF7C7FE4FEA0A1A019BFF
+:105A100045F4007545EA0A0545EA0335484642461D
+:105A2000ABB240F20B41FCF7B7FE4FEA0B1B009AFA
+:105A300046F4007646EA0B0646EA023648464246F7
+:105A4000B3B240F20C41FCF7A7FE20224846822167
+:105A50001346FCF743FE012248467C211346FCF71F
+:105A60003DFEBDE8FE8FC046C40B0200012970B5A3
+:105A700005460C4616D106222949FCF7A1FE284608
+:105A80003A2122462346FCF729FE082228461346DF
+:105A90004FF48D71FCF722FE28467F210022FCF78F
+:105AA000D7FD33E079B91F490622FCF789FE284665
+:105AB0003A2101222346FCF711FE082228464FF422
+:105AC0008D71134620E0022920D1B0F8DA3003F4BA
+:105AD0007043B3F5005F02D17D21032201E07D21F7
+:105AE0002246FCF7B5FD284628210F220123FCF7AA
+:105AF000F5FD8022134628464FF48971FCF7EEFD30
+:105B00002846052107220223FCF7E8FD284640F23B
+:105B100037614FF440420023FCF73EFE70BDC046A3
+:105B2000AE060200560C02002DE9F047C369D0F81A
+:105B3000A8501B6D0C4613F4805F40F2234114BF44
+:105B40004FF006094FF00909064695F844A3FCF703
+:105B5000F1FD40F2344107463046FCF7EBFD2046AC
+:105B6000FEF7E6FF95F84433C1B2B5F8642395F823
+:105B700048030BB9012092E007F0FF07C0EB0103D7
+:105B8000C2EB07029B1A5FFA83F84FFA88F4002CE5
+:105B90001DDAF36930461B6D03F48053002B0CBFF4
+:105BA0000B21042114BF0322082263429A42A8BF9A
+:105BB0001A46B5F8683301FB02324FF4AA6192B27B
+:105BC000FCF7C4FD14F1030F06DAFB1C05E0032CFF
+:105BD00002DDFB1E9BB200E0BBB2B5F8640319B254
+:105BE00002B2D31C994201DDC31C03E09142ACBF59
+:105BF0000B4613469CB2BAF1000F13D023B2BB423E
+:105C000010D02346304640F22341FF22FCF7C4FD6A
+:105C1000304624490422FCF7D3FD1420F0F39CF510
+:105C2000002700E00127B5F866434FFA88F220B25A
+:105C3000C9EB000352429A42B8BFC9EB040391B2C8
+:105C4000B8BF99B20AB200F109039A42C4BF04F185
+:105C5000090399B2B6F8DA3003F47043B3F5005F84
+:105C60000CBF95F94B3395F94C335B189BB2BAF1E5
+:105C7000000F05D0304640F23441FF22FCF78CFD86
+:105C8000304640F22341FCF755FD95F8BC33C0B2D5
+:105C900085F8BD0385F8BE0385F8BF333846BDE8F7
+:105CA000F087C0465C0B020070B5D0F8A8500446DF
+:105CB000FF22B5F8663340F23441FCF76DFDB5F8CC
+:105CC00064332046FF2240F22341FCF765FD204665
+:105CD000B5F868234FF4AA61FCF738FD2046044963
+:105CE0000422FCF76DFD1420F0F336F570BDC046BC
+:105CF0008A050200082270B5134605465721FCF7B5
+:105D0000EDFC56212846FCF78BFC00F0F8045621E8
+:105D100022462846FCF79CFC0120F0F31DF5562195
+:105D200044F003022846FCF793FC0120F0F314F53D
+:105D3000562144F007022846FCF78AFC4FF496707F
+:105D4000F0F30AF52846572108220023FCF7C6FC89
+:105D500070BDC0462DE9F04140F24A4631468046CA
+:105D6000FCF7E8FC40F04404A4B24FF6BF7540468F
+:105D70003146224604EA0505FCF7E8FC31462A468E
+:105D80004046FCF7E3FC25F004050420F0F3E4F4BE
+:105D9000404631462A46FCF7D9FCBDE8F081C046B2
+:105DA0002DE9F04706460C461546384906221F469F
+:105DB000DDF82090BDF82480FCF702FD304640F26B
+:105DC00082414FF6FF722346FCF7E6FC304640F274
+:105DD0008141FF222B46FCF7DFFC3FB9304640F201
+:105DE00081414FF480723B46FCF7D6FC304628498F
+:105DF0000322FCF7E5FC0A2308FB03F5002407E077
+:105E0000AC4201DD002439E06420F0F3A5F4013454
+:105E1000304640F28141FCF78DFC10F4007FEFD159
+:105E200040F283413046FCF785FC40F28441044651
+:105E30003046FCF77FFC40EA0440C9F8000040F21D
+:105E400085413046FCF776FC40F2864104463046F8
+:105E5000FCF770FC40EA0440C9F8040040F28741B6
+:105E60003046FCF767FC4FF4916104463046FCF77E
+:105E700061FC40EA0440C9F80800012430460549A5
+:105E80000622FCF79DFC2046BDE8F087980702003B
+:105E9000F40502002A06020070B50546002407E05A
+:105EA0006420F0F359F4013441F289339C4207D065
+:105EB000284640F25141FCF73DFC10F4404FEFD131
+:105EC000284640F25141FCF735FC10F4404F14BF16
+:105ED0000020012070BDC04610B540F24C414FF685
+:105EE000FC72FCF73BFC10BDC36970B504460D465F
+:105EF00018698E2116463AF0FDDBE3694119490025
+:105F0000186932463AF014DC70BDC046C36970B5FA
+:105F100004460D4618698E213AF0ECDBE36941191D
+:105F2000490018693AF0E6DB70BDC0462DE9F04142
+:105F30000C46272180461646FFF7E8FF10F00103C4
+:105F400002D101271D4605E04FF6F07500EA050570
+:105F50004FF6F07728214046FFF7D8FF3840A84297
+:105F600001D1012009E0013C631C002B02DD14205B
+:105F7000F0F3F2F3002CEDDC002006B13460BDE854
+:105F8000F081C0462DE9F0410646D0F8A850FEF752
+:105F9000C5FFB0F5404F46D1F369E02118693AF0EA
+:105FA000A9DBEC8D8046C4EB000440F2A5413046ED
+:105FB000FCF7C0FB0123C0F30227BB40A4B29C4204
+:105FC00031DD95F8C134A5F82E80BB4208D90137E0
+:105FD000304640F2A5414FF4E0623B02FCF7DCFBA7
+:105FE0003046FEF775FF40B280B22886B6F8DA3048
+:105FF0006F8603F47043B3F5005F0CBF85F854045B
+:1060000085F85504D6F8A8202B8E92F966255B00FA
+:10601000013293FBF2F3304640F2A44140F2FF120A
+:106020009BB2FCF7B9FBBDE8F081C0462DE9F04F0B
+:10603000044685B00D46D0F8A860FFF7A3FFD4F85A
+:10604000B030D3F8203183F0010313F00103039340
+:1060500003D1E36918693AF09DDB07212046FCF77C
+:10606000DFFAFF2101902046FCF7DAFA40F21F1117
+:1060700002902046FCF7D4FA40F23B41834620468A
+:10608000FCF758FB40F23C4182462046FCF752FBAD
+:1060900040F2D74181462046FCF74CFB4FF49B6110
+:1060A00080462046FCF746FB0F224649074620461D
+:1060B000FCF786FB0122072113462046FCF70EFB66
+:1060C0001022FF2113462046FCF708FB042213464A
+:1060D00040F21F112046FCF701FB0A20F0F33CF3CD
+:1060E000202220464FF49A611346FCF755FB0A2004
+:1060F000F0F332F3012D21D140F276412046FCF736
+:1061000019FB40F27741C5052046FCF713FBC0059B
+:10611000C00DED0DFF288ABFA0F5007302469AB2AC
+:10612000FF2D88BFA5F50073A6F86E058CBF98B249
+:106130002846C0EB0203A6F86C550AE0204640F260
+:106140007541FCF7F7FAC005C00DFF2803D9A0F58B
+:1061500000739DB200E00546019B2046DAB207219C
+:10616000FCF776FA029B2046DAB2FF21FCF770FAC0
+:10617000204640F21F115FFA8BF2FCF769FA2046C5
+:1061800040F23B415246FCF7E1FA204640F23C41E6
+:106190004A46FCF7DBFA204640F2D7414246FCF77C
+:1061A000D5FA20464FF49B613A46FCF7CFFA039BA1
+:1061B0001BB9E36918693AF0D9DA28B205B0BDE82D
+:1061C000F08FC046F807020070B5D0F8A83001295A
+:1061D000D3F8DC63D3F8D853D3F8E04304D10131CA
+:1061E000FFF724FF02B20AE040F27541FCF7A2FA81
+:1061F000C005C00DFF288CBFA0F500720246631FCA
+:1062000001209840801905FB1200231F184140B25D
+:1062100070BDC04610B50129D0F8A83003D1FFF7F2
+:1062200005FF00B212E0B3F86C25B3F86E35FF2B12
+:1062300086BFA3F5007399B21946FF2A86BFA2F55F
+:1062400000739BB21346C3EB010318B210BDC046E6
+:1062500070B5D0F8A830D3F8D443D3F8D053D3F8DE
+:10626000CC63FFF7D7FF621E0123934000B25B1996
+:1062700006FB1030204140B270BDC0462DE9F04110
+:10628000B0F8DA20074602F47043B3F5005FD0F8A7
+:10629000A85004D1B5F85463B5F8844513E0D3B2DF
+:1062A000942B03D9B5F88645022308E0632B03D964
+:1062B000B5F88845012302E0B5F88A45002305EBCF
+:1062C0004303B3F85663FF2E1ED001213846FFF773
+:1062D000BFFF40B2193804FB00F000B20028CCBF69
+:1062E00000F5FA73A0F5FA734FF47A7293FBF2F3A8
+:1062F00098B28419A4B2384640F23441FF222346B2
+:10630000FCF74AFAA5F86643BDE8F08170B505468A
+:10631000D0F8A8600C4689B340F2DA6142F2080274
+:10632000FCF72AFA284640F2A6510522FCF70EFA9D
+:10633000284640F2A251C322FCF708FA284640F250
+:10634000A5510722FCF702FA284640F283514FF488
+:106350004872FCF7FBF9284640F284510022FCF712
+:10636000F5F9284640F285514FF40072FCF7EEF93A
+:10637000284640F286510022FCF7E8F928462721FA
+:10638000FFF7C4FD1CB140F001039CB203E04FF6DF
+:10639000FE7400EA040496F894332846F31893F840
+:1063A0009523052302FB03F22621042A98BF1A46EF
+:1063B000FFF79AFD04F110022846272192B2FFF759
+:1063C00093FD70BD70B5D0F8A850044695F84233DF
+:1063D0005BB10021FFF79AFF204619210022FFF749
+:1063E000A5FD10B9012385F8453370BD70B5D0F80F
+:1063F000A840054694F8423393B990F8E93013F079
+:10640000010F1CBF23F0010380F8E93090F8E93058
+:1064100013F0020F2DD023F0020380F8E93028E0BA
+:1064200094F847330BB1012303E0D1F1010338BFE6
+:10643000002384F84733E1B100230126C4F86C330C
+:1064400084F8453384F846632846FFF7BBFF94F889
+:106450004333003B18BF012384F8443313B128466B
+:10646000FFF722FC2846FEF79FFB28463146FFF740
+:106470004DFF70BD70B5D0F8A83000260C4683F8EB
+:10648000466331460546FFF741FF14B12846FFF742
+:106490000BFC03222846134640F67A01FCF77CF9F0
+:1064A000284640F2DA6142F208023346FCF774F9FA
+:1064B00070BDC04670B50546D0F8A84016467AB102
+:1064C00094F8433394F842438C2144EA4304C3696B
+:1064D000146018693AF00ED944EA004434600FE0C1
+:1064E000CB080DD101F0010384F84233C1F340031E
+:1064F00084F8433394F8423313B90121FFF7BAFF0C
+:1065000070BDC04610B500210446FFF7B3FF20461A
+:10651000FEF74AFB10BDC04610B50122044640F606
+:106520000501FCF729F920460722052340F22F41F7
+:10653000FCF732F920463021F8234FF4FF62FCF7D4
+:106540002BF90623204630210722FCF725F92046A7
+:1065500040F2144141F61062FCF7F8F8204640F290
+:1065600015414FF4C862FCF7F1F8204640F2DF41D4
+:106570004FF47F424FF47743FCF70EF92046FFF7C4
+:10658000E9FB204602492D22FCF71AF910BDC0464E
+:10659000680E0200002914BF0223002310B5002A50
+:1065A00018BF43F001030446032240F24D41FCF7BB
+:1065B000F3F8204640F24C410322FCF7DDF810BD11
+:1065C00010B5044611B91049132219E012220F49DF
+:1065D000FCF7F6F8012100222046FFF7DBFF2046FA
+:1065E0000B490622FCF7ECF8B4F8DA3003F47043F8
+:1065F000B3F5005F07BF20460649204606491E2224
+:10660000FCF7DEF810BDC04692080200B808020090
+:10661000DC080200660A0200E80802002DE9F041E9
+:1066200004460D46164640F2DA6148F280021F46E3
+:106630009DF81880FCF7A0F82046FEF7B7F9B8B12E
+:1066400040F652112046FCF775F8FF22C3B240F61F
+:1066500048112046FCF7A0F840F653112046FCF7FD
+:1066600069F840F64911C3B2FF222046FCF794F8BE
+:10667000D4F8A83093F8463573B140F2EB41204688
+:10668000FCF758F8C0F3402340F2EB4120464FF4AA
+:1066900080629B02FCF780F86B1EFF22204640F2CE
+:1066A00042619BB24FF6FF75FCF776F8AE4201D01F
+:1066B000731E9EB220464FF4C8612A463346FCF74B
+:1066C0006BF8204640F241612A463B46FCF764F8ED
+:1066D000B8F1000F05D0204608490422FCF770F8F5
+:1066E00009E0204640F23F610122FCF72FF82046E6
+:1066F0000121FFF765FFBDE8F081C046DE0B020017
+:106700002DE9F0410C4640F23B410546FCF712F8FA
+:1067100040F23C4107462846FCF70CF8064674B1A7
+:106720000E2228460F49FCF74BF828460121FFF7B7
+:1067300047FF28460C490722FCF742F810E028469C
+:106740000A490422FCF73CF8284640F23B413A460D
+:10675000FBF7FCFF284640F23C413246FBF7F6FFD0
+:10676000BDE8F08186090200980B0200500D02007E
+:106770002DE9F04F0546C5B001910092FDF79AFC56
+:10678000EB694FF0805118690A4639F093DF052014
+:10679000EFF3E2F7002328464FF489614FF480427B
+:1067A000FBF7FAFF284640F255414FF4A842FBF7A9
+:1067B000CDFF284640F25641FBF7BCFF00F00F002A
+:1067C000052809D14FF4A842284640F25541FBF76D
+:1067D000BDFF4FF4807207E045F20142284640F2C7
+:1067E0005541FBF7B3FFFE22803A521022EAE272D3
+:1067F000102AA8BF10225100002301F18006C2EB2D
+:10680000060B1F46994698469A464393429340E0AA
+:1068100040F256412846FBF78DFF40F25741C0F346
+:106820000B142846FBF786FF5E4544EA003021DC66
+:10683000BAF17F0F1EDC8104890CB1F5005FC8BF7F
+:10684000A1F5804101F50063B3F5805F23D802AB69
+:1068500023F8191044AB03EB880252F8083C0AF104
+:10686000010ACB1842F8083C08EB090383F0400901
+:1068700088F00108C0F3033303F00C0343EA071365
+:1068800016F0010F9FB203D007F0FF03402B02D197
+:10689000013E002EBCDCEB69002218694FF08051EC
+:1068A00039F008DF2846FDF7FFFB429B9B1142931E
+:1068B000439B9B11BAF1800F43931DD0002022E02F
+:1068C00041EA801202AB33F9123001315B1B4029DF
+:1068D00003FB0344F4D1013002280FD1009AA3092D
+:1068E0001460019A1360A3F53A63084A183B934277
+:1068F0008CBF0020012006E00020044642AB53F884
+:1069000020500021DCE745B0BDE8F08F48F4FF0FD0
+:1069100070B504460D46FDF7CDFB20226B012046E5
+:106920004FF49661FBF738FF0023204640F2B14157
+:106930004FF40072FBF730FFB4F8DA3003F4704321
+:10694000B3F5005F02D04FF0000E04E0D5F1010E68
+:1069500038BF4FF0000E002D0CBF2023002343EA68
+:106960008E13204660224FF48261FBF715FF20460C
+:106970004FF482618022EB01FBF70EFF2046FDF70A
+:1069800093FB70BD2DE9F047044688461746D0F8C2
+:10699000A890FCF78DFB20460121FFF7B9FF0025E9
+:1069A0002E460CE0012100222046FDF78BFA3846E6
+:1069B000EFF3D2F62046FEF78BFA40B285B2F3B27F
+:1069C00001364345EED320460021FFF7A1FF89F8A9
+:1069D000C052BDE8F087C04670B505460846FEF7D0
+:1069E000A7F8EB69A02144B2186939F083DE9D3C19
+:1069F000A4B26FF0610324B29C42B8BF1C46C1B27E
+:106A000062B22846FCF770FD70BDC04673B5D0F881
+:106A1000A840064694F84233002B00F0DC8094F83E
+:106A20004633002B00F0D780D0F8B030D3F82031B7
+:106A300013F0010F00F0CF8000230093019394F82E
+:106A40004553002D40F0AA8029462A46FFF76EFAEA
+:106A5000002800F0A380304601A96A46FFF788FEAF
+:106A6000002800F09B80009BC4F86C3394F84633F8
+:106A7000012B40F0938094F891030199AC46AE4607
+:106A80001FE045B204EB8502D2F87033994201D37E
+:106A9000002203E0C2F870131946012204EB8503BB
+:106AA000D3F870339C440EF101035FFA83FE431C5C
+:106AB000D8B243B2072BC8BF002012B1019101998F
+:106AC00019E094F990334FFA8EF29A42D9DBF5E748
+:106AD00043B204EB8303D3F87023C3F87013431C51
+:106AE000D8B243B2072BC8BF00200EF101038C447B
+:106AF0005FFA83FE11464FFA8EF3072BE8DD019112
+:106B000094F8902353B2072B05DC002384F89233CA
+:106B1000531C84F8903394F99033082B3ED194F8A9
+:106B20009433E31893F8972393F8995394F8923396
+:106B3000FC2B02D8013384F8923394F892339342B9
+:106B40002CD194F89133013384F891335BB2072B45
+:106B500002DD002384F8913394F890333046023BF1
+:106B600084F890336146FEF7DFFF18B93046FEF730
+:106B70001BF810E094F89333FC2B02D8013384F80F
+:106B8000933394F89333AB4205D194F8943313B90B
+:106B9000013384F89433002384F8923394F8461335
+:106BA0000023012984F8453303D13046FFF7AEFBBB
+:106BB00003E030461946FFF75DFC3046D4F86C130D
+:106BC000FFF70AFF002384F8473394F89C3313B986
+:106BD000013384F89C337CBD2DE9F04F0746D0F893
+:106BE000A800E1B00B9041F22403FB5C0C46002BA3
+:106BF00000F09C82FB696A21186939F07BDD400056
+:106C00001FFA80FBBBF1000F00F090823846FEF7C0
+:106C100085F9FB69024610B91869594684E218697A
+:106C2000594639F067DD012800F080820BF1060338
+:106C30009BB20C930BF13A039BB20D930BF16E03D5
+:106C40009BB20E930BF1AA039BB20F93002C00F0A2
+:106C50005A82384640F2F941FBF76CFD10F0080FFC
+:106C600040F064824CAD38ACAB1C0193A31C039381
+:106C70003846002340F2764140F2FF12009502941C
+:106C8000FBF7D4FD2B1D0093AB1D0193231D029335
+:106C9000A31D03933846002340F2774140F2FF12D0
+:106CA000FBF7C4FD05F10803009305F10A03019306
+:106CB00004F10803029304F10A030393384640F2F7
+:106CC000AA4148F2FF1248F27F03FBF7AFFD05F13E
+:106CD0000C03009305F10E03019304F10C0316223B
+:106CE000029304F10E0303933846134640F23B41EE
+:106CF000FBF79CFD05F11003009305F112030193CE
+:106D000004F11003029304F1120346220393384660
+:106D1000002340F23C41FBF789FDB7F8DA3005F17A
+:106D2000140E03F47043B3F5005F05F11C030A93DE
+:106D300005F11E03099304F11C03089304F11E03DB
+:106D4000079305F12003069304F1200305F11602D1
+:106D500004F1140104F1160005F1180605F11A08F2
+:106D600004F1180904F11A0A05F12205059304F14A
+:106D7000220437D1019241F22B0213460291039073
+:106D800040F24C413846CDF800E0FBF74FFD384665
+:106D900040F24D4144F22B0244F20A030096CDF832
+:106DA0000480CDF80890CDF80CA0FBF73FFD089AC1
+:106DB0000A980999079B0292072200900191039378
+:106DC0003846134640F2F941FBF730FD0698059925
+:106DD000072200900291384640F2FA41134601958D
+:106DE000039436E0019241F22B0213460291039084
+:106DF00040F24C413846CDF800E0FBF717FD38462D
+:106E000040F24D4144F22B0244F222030096CDF8A9
+:106E10000480CDF80890CDF80CA0FBF707FD0A9A86
+:106E2000099B089807990092072201930290134644
+:106E30000391384640F2F941FBF7F8FC069A059BAE
+:106E40000092029301950394384640F2FA410722DA
+:106E5000002324ACFBF7EAFCA31C019310AB012236
+:106E600002930DF142030721039338461346009421
+:106E7000FBF748FC231D0093A31D019311AB1022C7
+:106E800002930DF14603FF21039338461346FBF7A7
+:106E900039FC04F10803009304F10A03019312ABD7
+:106EA000042202930DF14A034CAE03933846134675
+:106EB00040F21F11FBF726FC06F1240338AD0093C6
+:106EC00006F12603019305F1240340F644020293E0
+:106ED00005F1260303933846134640F63811FBF7B5
+:106EE000A5FC06F12803009306F12A03019305F19E
+:106EF0002803029305F12A030393384640F639111B
+:106F000040F6440240F60403FBF790FC04F10C0346
+:106F1000009304F10E03019313AB012202930DF1D0
+:106F20004E033A21039338461346FBF7EBFB04F17B
+:106F30001003009304F11203019314AB082202938F
+:106F40000DF152030393384613464FF48D71FBF74E
+:106F5000D9FB04F11403009304F11603019315AB5C
+:106F6000082202930DF15603052103933846134678
+:106F7000FBF7C8FB04F11803009304F11A03019313
+:106F800016AB042202930DF15A033A2103933846BB
+:106F90001346FBF7B7FB04F11C03009304F11E0337
+:106FA000019317AB012202930DF15E030393384660
+:106FB00013464FF48D71FBF7A5FB06F12C030093EC
+:106FC00006F12E03019305F12C03029305F12E0324
+:106FD0000393384640F2D74147F2CB0242F24B03CB
+:106FE000FBF724FC04F12003009318AB202202934A
+:106FF0000DF1620382212234039338461346019433
+:10700000FBF780FB0B98037B827AC17A1B0342F467
+:10701000007242EA011243F0030343EA820306F1DD
+:107020003002009205F13002323602923235384693
+:107030004FF49B6147F6FF729BB201960395FBF7F5
+:10704000F5FBDDF83090DDF834800026FB694CACB0
+:10705000325B1869494639F06BDBFB6938AD725B0E
+:107060001869414639F064DBFB69A419186909F114
+:107070000201628839F05CDBFB69AD1908F102019D
+:1070800018696A88043639F053DB342E09F1040993
+:1070900008F10408DAD1DDF83890DDF83C800026EC
+:1070A000FB6924AC325B1869494639F041DBFB6966
+:1070B00010AD725B1869414639F03ADBFB69A419DF
+:1070C000186909F10201628839F032DBFB69AD19F8
+:1070D00008F1020118696A88043639F029DB242E88
+:1070E00009F1040908F10408DAD1FB690BF1020186
+:1070F00018690D2239F01CDBFB690BF104011869DA
+:10710000092239F015DBFB690B991A6A18690B9B88
+:10711000C1F83824B3F83C240BF1E60139F008DB60
+:10712000FB6959461869012239F002DB61B0BDE8FC
+:10713000F08FC0462DE9F04F8DB007460F220E4666
+:107140000DF12100B249EAF317F7D7F8A880002221
+:10715000B04D14016359B34203D001320E2AF7D166
+:1071600075E3384691210022FBF772FA3846382140
+:107170000722FBF76DFA0A2238468821FBF768FAE6
+:10718000D7F8A83093F882251AB138468821FBF742
+:107190005FFA64192A213846227AFBF759FA30211E
+:1071A00003223846637AFBF799FA91210322384685
+:1071B000A37AFBF793FAE37A38210F223846FBF7DC
+:1071C0008DFA912100223846FBF742FA3821072236
+:1071D0003846FBF73DFA237B30210C229B003846D2
+:1071E000FBF77CFA5E210F223846637BFBF776FAC9
+:1071F000A37B5E211B01F0223846FBF76FFA6C215E
+:107200003846E27BFBF724FA384638210822FBF7A0
+:107210001FFA384691210322FBF71AFA0CA98B19A1
+:1072200013F8102C38465E21FBF712FA012238467B
+:107230007E21FBF70DFA98F8EE231AB13846382173
+:10724000FBF706FA0722134638462A21FBF746FACF
+:1072500038462C210022FBF7FBF938462A210C2264
+:10726000FBF7F6F9012238462C21FBF7F1F9D7F8A4
+:10727000A82092F852352BB338465E2192F8532558
+:10728000FBF7E6F9D7F8A830384693F854252A21B9
+:10729000FBF7DEF9D7F8A830384693F855252B21AF
+:1072A000FBF7D6F9D7F8A830384693F856252C21A5
+:1072B000FBF7CEF9D7F8A83038462D2193F857259B
+:1072C000FBF7C6F9B7F8DA3003F47043B3F5805F23
+:1072D00004D13846BF21EE22FBF7BAF90222134649
+:1072E000384640F21F11FBF7F9F90422F721134643
+:1072F0003846FBF7F3F9F121032200233846FBF768
+:10730000EDF9F221F82290233846FBF7E7F9A223A2
+:10731000F321FF223846FBF7E1F9B7F8DA3003F43E
+:107320007043B3F5005F04D1D7F8A83093F818354F
+:1073300006E0B3F5805F06D1D7F8A83093F8193589
+:10734000012B00F07B82042238469D210023FBF7AD
+:10735000C5F90022079244213846FBF761F940F253
+:107360002B1101903846FBF75BF94421029007226C
+:107370003846FBF7A5F9384640F22B110E22FBF7F1
+:107380009FF941F2080357F803A0079B0BB9554634
+:1073900001E04FEA4A05204B9A4502D84FF0010917
+:1073A00006E01E4B9A4594BF4FF002094FF00409C6
+:1073B000B7F8DA3003F47043B3F5005F03D000216F
+:1073C0000591069106E06268032302FB03F2059231
+:1073D0006A000692124C102221465046FDF7BAF977
+:1073E000102221462846FDF7B5F91022049009FB2A
+:1073F00004F15046FDF7AEF9B7F8DA30039003F424
+:107400007043B3F5005F0DD04FF0000B10E0C046A5
+:10741000C80602001424020080BA8C01007519030A
+:1074200040420F00059802211022FDF793F9834690
+:107430004F2102223846FBF70BF9CD4B4FEACA0524
+:1074400009FB03F3B5FBF3F301335B08013B5FFA80
+:1074500083F85221072238464FEA9803FBF73EF99A
+:1074600008F101065321602238464FEA4813FBF722
+:1074700035F909FB06F3BF4CB5FBF3F5BE4B2C19F0
+:10748000B4FBF3F4013CE4B2512122463846FBF749
+:10749000DFF8039B10221D0158462946FDF75AF9D3
+:1074A000013406FB04F600FB06F000280BDB58460F
+:1074B00029461022FDF74EF900FB06F0C0130130FB
+:1074C0004010441E0EE0584629461022FDF742F9AE
+:1074D0006FEA080303FB04F300FB03F0C013013061
+:1074E0006FEA6004C4F3072353210F223846FBF7E9
+:1074F000F5F85421E2B23846FBF7AAF806999F4BFB
+:107500000A22B1FBF3F30599384601FB02F2B2FB04
+:10751000F3F803FB1822590802F0010401EB0454AC
+:107520005208B4FBF3F49B0803EB0253B3FBF1F3F3
+:10753000E41845211F22C8F30713FBF7CFF84FEAE1
+:107540000813462138464FF4F87203F0F003FBF7B6
+:10755000C5F8C4F3074346210F223846FBF7BEF8AF
+:107560004721C4F307223846FBF772F84821E2B2FC
+:107570003846FBF76DF8079A41F29416002A08BFC7
+:107580004FF4FA56A6F5D8760CBF4FF482794FF433
+:10759000E1794FF4F572033E96FBF2F606FB02F535
+:1075A00005F52A754FF425636D02B5FBF3F540F23E
+:1075B0007C6405FB04F4A4F55834A4F5C064B4FB62
+:1075C000F2F4640AC4F3820242EAC6023846422157
+:1075D00092B2A4B2FBF73CF804F0030204F01F04DB
+:1075E00044EA421238464321FBF732F84FEA492475
+:1075F0004FF48773B4FBF3F404FB05F4604B640AA7
+:10760000604AB3FBF4F39A184FF41243B2FBF3F25F
+:107610005D4B02F00F02B3FBF4F3A3F54C23A3F58B
+:1076200000631B0C42EA03123846402192B2FBF77A
+:107630000FF84FF02552554BB2FBF4F2B3FBF4F3C5
+:10764000A2F546324FF4B841A2F50072A3F56E33AD
+:10765000B2FBF1F2A3F50073B3FBF1F302F00F02FA
+:1076600042EA03123846412192B20BF17444FAF710
+:10767000EFFF04F590044FF4966394FBF3F4292391
+:1076800004FB03F44FF45C7308FB03F840F22B5344
+:1076900006FB03F606F5E46109FB08F00C31102245
+:1076A000FDF758F804F5D81400EB640090FBF4F0F3
+:1076B000C0B23C2894BF0025012515B14308043B06
+:1076C00000E0031FDCB23C213F2223463846FBF793
+:1076D00005F8AB013C2140223846FAF7FFFFB7F826
+:1076E000DA3004F1040603F47043B3F5005F05F1EA
+:1076F000010404D1D7F8A83093F8273506E0B3F594
+:10770000805F19D1D7F8A83093F82835012B13D111
+:10771000049B40F245105946102203FB00F0FDF790
+:1077200019F804FB06F39E2100FB03F4C02238463F
+:107730004023FAF7D3FF0BE00499962001FB00F0F9
+:1077400010225946FDF706F804FB06F300FB03F48C
+:10775000B4F5160FD4BF002501256B1C032203FBD3
+:1077600002F394FBF3F0B0F5003F11D5002315E0D0
+:10777000404B4C003F420F0040420F00A0860100EA
+:10778000000068600021F6FF000084A30000302A9A
+:10779000A0F5C033DB130133C3F347033D213F2280
+:1077A0003846FAF79BFFAB013D2140223846FAF7F5
+:1077B00095FF284B9A4504D9202238465721134675
+:1077C00003E03846572120220023FAF787FF224B97
+:1077D0009A4504D9102238465721134603E038460B
+:1077E000572110220023FAF779FF049AB2F5341FCB
+:1077F00005DD38464A210222FAF762FF04E03846E6
+:107800004A21FD22FAF74EFF0C2244211346384646
+:10781000FAF764FF0120EEF39FF73846FEF76AFAA5
+:10782000019B38464421DAB2FAF712FF029B384630
+:1078300040F22B11DAB2FAF70BFF08E004229D2187
+:1078400038461346FAF74AFF0121079183E50DB048
+:10785000BDE8F08F80BA8C010075190341F208036E
+:107860002DE9F047C4588A4B4FF48475B4FBF3F408
+:1078700004FB05F41A235721B4FBF3F40646FAF788
+:10788000CFFE172181463046FAF7CAFE182130464E
+:10789000FAF7C6FE40F20511FB2207463046FAF71A
+:1078A00001FF304604214022FAF70AFF30464FF428
+:1078B00090711022FAF704FF304657210222FAF79E
+:1078C000FFFE304640F205110422FAF7F9FE304679
+:1078D0004FF483712A22FAF7BBFEA4B2304640F27D
+:1078E00007116E22FAF7B4FEE2B230462946FAF7E3
+:1078F000AFFEC4F30422304640F20911FAF7A8FEA5
+:10790000304640F20511FD22FAF7CCFE30464FF426
+:1079100083710122FAF7D4FE3220EEF31DF75D4C9D
+:1079200003E00A20EEF318F70A3C30464FF4857165
+:10793000FAF776FE10F0010F01D1092CF1D1304693
+:107940004FF48571FAF76CFE10F0010F08D1FAB20E
+:1079500030461821FAF7B4FE4FF00B0847460CE00A
+:10796000304640F20F11FAF75BFE00F01F071D2FA3
+:107970008CBF4FF00B0807F1020819213046FAF7C7
+:107980004FFE4FF48371FE2205463046FAF78AFE19
+:10799000304640F20511FB22FAF784FE304640F2F1
+:1079A00005110422FAF78CFE304640F2051102223E
+:1079B000FAF786FE30464FF483710122FAF780FE13
+:1079C0003220EEF3C9F6334C03E00A20EEF3C4F69E
+:1079D0000A3C30464FF48571FAF722FE10F0010F91
+:1079E00001D1092CF1D130464FF48571FAF718FE18
+:1079F00010F0010F06D1EAB230461921FAF728FE3D
+:107A0000092506E030464FF48871FAF709FE00F0C8
+:107A10001F053046FE224FF483716C01FAF742FED7
+:107A200044EA85243046FB2240F20511FAF73AFE7B
+:107A30002C43304657215FFA89F2FAF709FE3046A7
+:107A4000224640F63311FAF781FE2246BC02304648
+:107A500044EA471440F63411FAF778FE304645EA16
+:107A6000040240F63511FAF771FE304644EA070287
+:107A700040F63611FAF76AFE48EA4812D205304657
+:107A800040F63711D20DFAF761FEBDE8F087C04627
+:107A900040420F008996980070B55B210446FD2294
+:107AA000FAF700FE204604214022FAF709FE20469C
+:107AB0004FF490711022FAF703FE204678218022BD
+:107AC000FAF7FEFD204640F229110222FAF7F8FDEE
+:107AD000204657210122FAF7F3FD20465B210222BE
+:107AE000FAF7EEFD41F28830EEF336F6154D03E07D
+:107AF0000A20EEF331F60A3D5C212046FAF790FDAC
+:107B000010F0200F01D1092DF2D15C212046FAF7A7
+:107B100087FD10F0200F03D020465C21FAF780FD8E
+:107B200020465B21FD22FAF7BDFD20465721FE22AB
+:107B3000FAF7B8FD204640F22911FD22FAF7B2FD0E
+:107B400070BDC0468996980070B504460E46002563
+:107B50006E4B2046E95AFAF763FDA8530235302DE3
+:107B6000F6D1182220466A49FAF72AFE3A21FB226A
+:107B70002046FAF797FD012220464FF48D71FAF75F
+:107B80009FFD362101222046FAF79AFD10224FF47C
+:107B90008D712046FAF794FD1420EEF3DDF53A21BD
+:107BA00001222046FAF78CFD1420EEF3D5F5B4F847
+:107BB000DA3003F47043B3F5005F03D120463A2175
+:107BC000012208E020463A2101220023FAF786FD2F
+:107BD0002046CA2104221346FAF780FD08222046D7
+:107BE0004FF48D71FAF76CFD25210E222046FAF72D
+:107BF0002FFD252101222046FAF762FDB4F8DA3084
+:107C000003F47043B3F5805F04D1204628211E227F
+:107C1000082303E0204628211E220C23FAF75EFDEC
+:107C20001420EEF399F5052108222046FAF710FDFD
+:107C300080224FF489712046FAF742FD1420EEF3BA
+:107C40008BF5FF2110222046FAF73AFD442240F23C
+:107C50001F112046FAF734FD1420EEF37DF50B21B9
+:107C600007222046FAF72CFD102240F2131120467D
+:107C7000FAF726FD1420EEF36FF5072101222046C6
+:107C8000FAF7E6FC1420EEF367F502230322204600
+:107C9000FC21FAF723FDFD212046A622FAF7D8FCA5
+:107CA000442240F21F112046FAF70AFD1420EEF399
+:107CB00053F5FF2110222046FAF702FD1420EEF3BF
+:107CC0004BF5B4F8DA3003F47043B3F5805F03D1B9
+:107CD00010492046082202E00F4920460622FAF702
+:107CE0006FFD20465921CC22FAF7B2FC20465C21D8
+:107CF0002E22FAF7ADFC20467821D722FAF7A8FC0D
+:107D0000204692211522FAF7A3FC70BDD20402008E
+:107D1000360A0200040B0200140B02002DE9F04F9A
+:107D200004468BB0894609B98B4608E040F2D7413A
+:107D3000FAF700FD01A983462046FDF799FD2022B0
+:107D400013464FF49A612046FAF726FD6420EEF3BD
+:107D500003F540F276412046FAF7ECFC40F2A641EA
+:107D600080462046FAF7E6FC09A9824608AA204682
+:107D700007ABFBF7B5F9099F089E079DB9F1000F06
+:107D800009D0204601A9FDF75BFD204640F2D7410E
+:107D90005A46FAF7DBFC4FEAC850C00D4FEACA5307
+:107DA00080F48070DB0D00F5FE70033083F4807387
+:107DB000C01A8010394632462B46FCF7EBFC4000D7
+:107DC0000BB0BDE8F08FC046F0B5D0F8A85085B034
+:107DD00095F858340646002B7BD00023019302937C
+:107DE0000393FDF775F8C7B20FB17F2F71D101ABC7
+:107DF00002AA304603A9FBF773F940F23E61304610
+:107E0000FAF798FC40F2A641C4053046FAF792FC16
+:107E1000C005C00DE40DFF288ABFA0F5807300F5F2
+:107E200080729AB2FF2C84BFA4F5807398B2C2F519
+:107E3000FE7398BF04F5807003331B18C3F38F00E3
+:107E4000C7B995F856340133DBB2042B85F85634A4
+:107E50003FD985F85674029A019B0399FCF79AFC66
+:107E6000D5F848244310043B9342B8BF1346C5F8E5
+:107E700044341AE07F2F2CD195F857340133DBB20C
+:107E8000042B85F8573424D9002385F85734029AF7
+:107E9000019B0399FCF77EFCD5F84424431004337E
+:107EA0009342A8BF1346C5F84834D6F8A8109BB231
+:107EB000D1F8442430469342A8BF1346D1F8482451
+:107EC00040F2A7419342B8BF13469BB2FF22FAF794
+:107ED00063FC05B0F0BDC0462DE9F04F474B87B0BD
+:107EE00003AC80460D4693E8070084E8070040F2A3
+:107EF00045614046D8F8A8B0FAF71CFC40F246614C
+:107F000087054046FAF716FC3D498605062240469D
+:107F1000FAF756FC00210A464046FDF741F84FF4B7
+:107F2000FA730193404629462022A3F5FA73009480
+:107F3000FDF736FFBF0DB60D8246002849D0049DDF
+:107F4000DDF81490039C09EB0503012B02D84FF0D8
+:107F5000000A3EE02046FBF74BF806464846FBF792
+:107F600047F8A6F114031AB2002A06DB35FA02F12B
+:107F70003FD0013235FA02F206E0534215FA03F11E
+:107F800037D0D24315FA02F233B2C3F11E0314FA0A
+:107F900003F3C3EB0204A0F10B031BB2002B0A4650
+:107FA00002DB35FA03F102E05B4215FA03F120D05F
+:107FB00003B2C3F11F0309FA03F394FBF2F493FB3A
+:107FC000F1F004FB1400FBF71FF8A7058605BF0DB1
+:107FD000B60D404639463246FCF7E2FF40460949B5
+:107FE0000622FAF7EDFB5046ABF8B872ABF8BA626E
+:107FF00000E0002007B0BDE8F08FC046BC060200DC
+:10800000C20E0200DC0E020070B504460D46C9B176
+:1080100004221249FAF7D4FBD4F8A83093F8E933D4
+:10802000A02B05D1204640F64A1140F24F1203E042
+:10803000204640F64A11A722FAF788FB0849204655
+:108040000E2201E007490A22FAF7BAFBE369291E6A
+:1080500018BF0121186938F0A7DB70BDBE0D020002
+:10806000A20D0200D80D020070B50C46062226496A
+:10807000E4B20546D0F8A860FAF7A2FB0C2C01D8B0
+:10808000002405E041F25013EB561C1E18BF0124DA
+:1080900096F81A35002B31D0284640F64211FAF7EF
+:1080A00049FB14B10F280BD100E0A8B9D5F8F8307E
+:1080B00013F0060F22D196F82C30A3421ED05CB1EB
+:1080C000EB690122D8689968EDF398F728460121F9
+:1080D000FFF79AFF01230AE0EB690022D86899684C
+:1080E000EDF38CF728460021FFF78EFF002386F87A
+:1080F0002C30284605490C22FAF762FB2846044931
+:108100000422FAF75DFB70BDB6070200700702009B
+:108110008807020070B50D46B0F8DA101646D0F8A0
+:10812000A840FAF731FD28B994F84C342B7094F834
+:108130004D3401E000232B70337070BD2DE9F04702
+:108140004FF0000886B0054602ABCDF81080CDF8A0
+:108150000C80CDF8088003AA8A4604A9D0F8A8901C
+:10816000FAF7BEFF28460DF117010DF11602FFF7D1
+:10817000D1FF9DF8173004990193039A029B0124C3
+:1081800028460094FCF71AFB9DF816300746019329
+:108190002846029B0499039ACDF80080FCF70EFB59
+:1081A00099F8E83306460BB39DF81700B5F902219C
+:1081B000B5F90431B5F906110190284603920293EE
+:1081C00004910094FCF7FAFA9DF8163004460193E6
+:1081D00028460499039A029BCDF80080FCF7EEFA3A
+:1081E000A742B8BF27468642A8BF0646BAF1010F8C
+:1081F00002D0BAF1030F02D17B10C9F84434AAF1BE
+:108200000203DBB2012B02D87310C9F8483406B060
+:10821000BDE8F08707B540F25643009340F255425F
+:108220000133FAF7F1FB0EBD2DE9F04340F2DF41D7
+:1082300089B0D0F8A8400546FAF77CFAC3B27F2B84
+:10824000A4F84C30C0F30720C4BFA3F58073A4F892
+:108250004C307F28C8BFA0F58073A4F84E0001AF52
+:10826000C8BFA4F84E301123039320262A330DF102
+:1082700018094FF00208284639460493CDF80490B7
+:10828000CDF808800596FFF7C5FF069B3F2B01D967
+:10829000803B0693069B2365079B3F2B01D9803BC0
+:1082A0000793079B40F2344163652846FAF742FA88
+:1082B000C0B27F28C4BFA0F5807398B284F858007C
+:1082C00040F224412846FAF735FAC0F30720A4F813
+:1082D0005A0040F225412846FAF72CFA0D23C0B285
+:1082E000A4F85C00039328460F3339460493CDF875
+:1082F0000490CDF808800596FFF78CFF069B236459
+:10830000079B636409B0BDE8F083C0462DE9F041E6
+:10831000B2F1FF3F8AB0064688461746D0F8A8500B
+:1083200002D1FCF7E1FB47B295F966355FFA88F4B4
+:10833000013394FBF3F407230393193305930123CB
+:10834000E4B2029301AD07AB0193304604F5A0738C
+:1083500029460493FFF75EFF079BC034C3F307531E
+:108360000793304606AB294601930494FFF752FF6A
+:10837000002107980DF126020DF12203F0F31AF007
+:108380000021402008AB09AAF0F314F0BDF9223017
+:10839000BDF920108B4209DABDF92400C91AF0F3A7
+:1083A000BBF0BDF82240ADF8240009E0BDF926007D
+:1083B000C1EB0301F0F3B0F0BDF82040ADF82600AA
+:1083C000BDF92600BDF92410F0F3B0F023B2032B61
+:1083D00080B201DD231F01E0C4F104039AB212B29E
+:1083E00008FA02F103B2052003FB0010911E0123DD
+:1083F0008B40013AC018104107FB00F0C0F3CF00DA
+:108400000AB0BDE8F081C04670B5182386B0D0F838
+:10841000A840039300238022049340F27666203321
+:1084200005460593314613460292FAF7B5F904F171
+:108430009C03284601A90193FFF7ECFE40F271610D
+:108440002846FAF777F940F27361A4F89C022846AF
+:10845000FAF770F940F27461A4F89E022846FAF720
+:1084600069F940F27561A4F8A2022846FAF762F9A8
+:1084700040F27961A4F8A0022846FAF75BF9314688
+:10848000A4F8A4022846FAF755F940F2DA61A4F8F4
+:10849000A6022846FAF74EF940F22551A4F8A802A0
+:1084A0002846FAF747F994F86735A4F8AA0284F841
+:1084B000AC324FF48F612846FAF73CF94FF49A61D9
+:1084C000A4F8AE022846FAF735F940F22451A4F890
+:1084D000B0022846FAF72EF9B4F86835C0F3C03078
+:1084E000A4F8B43294F80734A4F8B20284F8B6328F
+:1084F00094F8083484F8B73206B070BD7FB5002315
+:108500000293103304930DF116030093012301939A
+:10851000694654330393FFF77DFEBDF8160007B09C
+:1085200000BDC0462DE9F84FD0F8A860074696F880
+:1085300046355BB9FFF7E2FF40F3072340B21FFA6D
+:1085400083F81FFA80F9C246CB4607E0B6F84A85A1
+:10855000B6F84C95B6F84EA5B6F850B5B7F8DA307F
+:10856000384603F47043B3F5005F0CBFB6F866609D
+:10857000B6F868604FF0FF320121FCF72BFA36B2F3
+:108580000121324684B23846FCF724FA0021241A2D
+:108590004FF0FF323846FCF71DFA0121324685B212
+:1085A0003846FCF717FAA4B2C4EB0806B6B2C4EB1F
+:1085B00009042D1AFF2238463346A4B240F6521160
+:1085C000FAF7EAF83846FF22234640F65311FAF745
+:1085D000E3F83846FF22334640F65611FAF7DCF846
+:1085E000ADB23846FF22234640F65711FAF7D4F8C9
+:1085F000C5EB0A033846FF2240F648119BB2C5EB93
+:108600000B05FAF7C9F8384640F64911FF22ABB21C
+:10861000FAF7C2F8BDE8F88F2DE9F04F93B00DF1ED
+:1086200026080C46D0F8A8503B49064693464046DB
+:10863000222201AFE9F3A0F4384638492222E9F3B7
+:108640009BF4BCB10022304640F60F11FAF77EF8D9
+:1086500095F8E933324AA02B324B14BF052403248A
+:1086600014BF1046184614BF4FF0100A4FF0110AFD
+:10867000B94616E0012230464FF41161FAF766F868
+:1086800095F8E933284AA02B284B14BF0E240A245E
+:1086900014BF1046184614BF4FF0100A4FF0110ACD
+:1086A000C1460022114604E00B5A013224319B4599
+:1086B00006D0A2421FFA82F8F6D14FF6FF7416E0F8
+:1086C0000FFA88F2242302FB03070024254607E063
+:1086D00035F80910304637F81420FAF737F8023524
+:1086E00001340AF101039C42F2D11FFA88F43046AA
+:1086F000FCF74AF910B13046FFF714FF3046FCF79B
+:1087000065FD20B2B0F1FF3F0CBF4FF0FF300020FD
+:1087100013B0BDE8F08FC046E20A0200680802000C
+:10872000F826020040220200F4240200AC220200DB
+:108730002DE9F0438BB006460F4691460DF1060039
+:108740001D492222E9F318F4D6F8A83093F8E9334A
+:10875000A02B14BF4FF010084FF0110817B93D4679
+:108760003C4619E000252C4609E00DF10603E15ACC
+:108770003046F9F7DFFF013524F80900023445459A
+:10878000F3D10BE00DF10603E15A34F8092030462D
+:10879000F9F7DCFF013502344545F3D13046FCF7EB
+:1087A000F3F810B13046FFF7BDFE17B93046FCF7BD
+:1087B0000DFD0BB0BDE8F0830C0C020030B587B0A6
+:1087C00005AB0093022301930023029350330C4620
+:1087D00003936946102315460493FFF71BFDBDF86C
+:1087E00014302380BDF816302B8007B030BDC04652
+:1087F0007FB50DF11603009301230193013B029312
+:1088000057330393694610230493FFF703FDBDF824
+:108810001600000A07B000BD07B540F256430093AA
+:1088200040F255420133FAF7B5F80EBDF0B5B0F895
+:10883000DA30D0F8A85003F47043B3F5005F0CBFF2
+:1088400095F8403395F8413387B085F8423395F871
+:108850004233064685F84333B0F8DA3003F4704308
+:10886000B3F5005F14D195F8492353B2002B02DD14
+:1088700085F8482309E0C3691B6D13F4805F01D0BC
+:10888000342300E0302385F8483395F85C3313E057
+:1088900095F84A2353B2002B02DD85F8482309E0FE
+:1088A000C3691B6D13F0805F01D0342300E03023D7
+:1088B00085F8483395F85D335BB2002B4CDD03221D
+:1088C000022BA8BF022303FB02F340F2DF41304634
+:1088D000DFB2F9F72FFFC1B27F29C0F30720C4BF71
+:1088E000A1F5807399B203B27F2BC8BFA0F5807346
+:1088F0007AB2C8BF98B292B2C2EB0003C2EB0102D7
+:10890000DBB202F0FF0242EA0322304640F2DF41CE
+:10891000F9F71CFF0DF116030093022301930F33A7
+:1089200002930F2303933046082369460493FFF70D
+:1089300071FC9DF81630FAB29B1A8DF816309DF82E
+:10894000173030469B1A69468DF81730FFF764FFE1
+:1089500030466C46FDF7FEF94FF0FF3385F89A3349
+:1089600095F84D33002285F8472385F89C23BBB149
+:1089700085F8422385F84323304640F22341FF32F5
+:10898000B5F85033F9F708FF30464FF4AA61B5F84F
+:108990006023F9F7DBFE304604490422F9F710FFA3
+:1089A0003046FCF711F907B0F0BDC046EC0D0200EF
+:1089B0002DE9F04FC3690C464FF08051BBB005461E
+:1089C000D0F8A870164618690A4637F073DE0520FD
+:1089D000EDF3C2F628464FF489614FF4804200233C
+:1089E000F9F7DAFE0122284640F20A511346F9F758
+:1089F000D3FE0DF1E70334930123359310333693FF
+:108A00000F2337932846082334A93893FFF702FC35
+:108A10000CB1314612E0B5F8DA3003F47043B3F527
+:108A2000005F40F03E81EB6997F8BF641B6D13F463
+:108A3000805F0CBF08210621FF2E00D10E469DF855
+:108A4000E720032306FB13238DF8E6300DF1E60340
+:108A500034932846102334A93793FFF7DDFE7300C3
+:108A6000FE229BB2284640F20A51F9F795FE97F88C
+:108A7000C044FF2C00F0EA80002C00F0C980102CCC
+:108A800028BF1024C4F12403D9B272B24BB29A4267
+:108A900001DDCEB202E0002E08BF012670B2A04276
+:108AA000019002DC5FFA86F902E0631C5FFA83F949
+:108AB00004F1010BC9EB0B035FFA83F80D23369326
+:108AC000133338934FFA89F35B004FFA88F204931B
+:108AD00009AB03EBC203570003937B1CDBB2079384
+:108AE0006300013305934FEA4B03029206934FF064
+:108AF000000A0198049AA042CABF73B2CDF8DCB054
+:108B00003793379B34A953445B003793039B284624
+:108B100035923493FFF77EFB07990AE03AA800EB01
+:108B2000810353F8C42C42F0800243F8C42C8B1C00
+:108B3000D9B2059A9142F1DD002111E03AAB03EB85
+:108B4000810203EB870353F8C43C3AA842F8C43CC3
+:108B500000EB870353F8C03C42F8C03C8B1CD9B2F1
+:108B6000B942EBDB069A09AB349328464FEA4A0335
+:108B700034A90AF1250A35923793FFF74DFEBAF171
+:108B80004A0FB6D1019B4FFA88F2A342C4BF73B219
+:108B900037934FFA89F335930DF1AE0303EB42039C
+:108BA000D8BFCDF8DCB034931023389328460E2379
+:108BB00034A93693FFF72EFB0CE03AAE06EB4803E0
+:108BC00033F83A2C42F4006223F83A2C08F10103FE
+:108BD0005FFA83F8A045F0D9002109E0029E3AA887
+:108BE00000EB430200EB460333F83A3C22F83A3CF0
+:108BF0000298CBB201318342F0DB0DF1AE03349326
+:108C00002846002334A9CDF8D4B03793FFF704FEEB
+:108C100001221346284640F20E51F9F7BDFD4FF4EC
+:108C20007E4263021340284640F20E51F9F7B4FD2C
+:108C3000284640F20F517F222346F9F7ADFD284622
+:108C400040F20F514FF47E52E3011BE0284640F200
+:108C50000E5101220023F9F79FFD284640F20E51E4
+:108C60004FF47E420023F9F797FD284640F20F515A
+:108C70007F220023F9F790FD284640F20F514FF470
+:108C80007E520023F9F788FDEB694FF08051186997
+:108C9000002237F00FDD2846FDF75CF83BB0BDE859
+:108CA000F08F2146CAE6C0462DE9F041D0F8A86011
+:108CB0000746D6F87C45002505E021463846FFF7F3
+:108CC000ABFD01351434D6F878359D42F5D3BDE8B7
+:108CD000F081C046F0B5C369D0F8A85087B0074608
+:108CE00080219868EDF3F4F7044600286DD0B5F8BC
+:108CF0001C34002603F4807C03F4007E30464FF0E1
+:108D0000000316F0100206F00101035316D0BEF165
+:108D1000000F03D0D5F81C34C3F3802116F0080FE0
+:108D200002D095F81A3408E0D5F8183416F0200F60
+:108D300014BFC3F3072303F0FF030353BCF1000F79
+:108D400000D062BB16F0040F09D016F0020F025BD0
+:108D500002D0D5F80C340EE0D5F80C3418E016F03B
+:108D6000200F06F002030CD0025B13B1D5F81034CB
+:108D700001E0D5F8143409B11B0E0EE0C3F307432C
+:108D80000BE0025B13B1D5F8103401E0D5F81434D0
+:108D900011B1C3F3072300E0DBB2134303530136E1
+:108DA0000230402EABD10F230393002304933846A7
+:108DB000103301A9059302960194FFF72DFDFB697D
+:108DC000214698688022EDF393F707B0F0BDC046C6
+:108DD0002DE9F041002486B00594D0F8A88006461D
+:108DE000FBF782FE072302931933049307460123FE
+:108DF0002546019316E00BB90C4603E011F0010F74
+:108E00000FD14C0830467AB2FFF780FA06AB43F830
+:108E1000040D0093304604F5107369460393FFF781
+:108E2000FBFC0135802DE9B298F96635E3D17BB1C1
+:108E300001230193402405AB0093304604F51073E1
+:108E400069460393FFF7E8FC631CDCB2802CF2D187
+:108E500006B0BDE8F081C0462DE9F04FB0F8DA3039
+:108E600089B003F47043B3F5005F07468B46D0F832
+:108E7000A85002D1B5F8C42304E0B3F5805F08D14F
+:108E8000B5F8C62313B2B3F1FF3F02D01FFA82FA3E
+:108E900001E04FF0700A072304931933069301236E
+:108EA0004FF00009039307AB0293C846CDF8049036
+:108EB000019B18F0010F0BEB0306F378009303D02E
+:108EC00095F96635002B59D1B7F8DA3003F47043C1
+:108ED000B3F5005F03D0019B13F80B9012E0B5F8D7
+:108EE000402413B2B3F1FF3F18BF1FFA82F9B5F85F
+:108EF0003E2408BF4FF00F0913B2B3F1FF3F1CBF70
+:108F000092B20092B37872781B0443EA022343EAD8
+:108F10000A6343EA0903079395F9663502AC013306
+:108F2000B8FBF3F3C033384621460593FFF774FCD2
+:108F300007AB029395F9663538460133B8FBF3F376
+:108F400003F5A07321460593FFF764F93279009B7E
+:108F5000120542EA0372079B384623F07F4323F44D
+:108F600070031A43079295F9663521460133B8FB21
+:108F7000F3F303F5A0730593FFF74EFC019B08F193
+:108F800001080533B8F1800F019391D195F9663549
+:108F9000002B36D05E4608F1800896F8423196F8EC
+:108FA00041211B0443EA022302AC43EA0A6343EA79
+:108FB00009033846214608F180050793CDF814804F
+:108FC000FFF72AFC07AB3846214602930595FFF7C9
+:108FD00021F996F84421009B120542EA0372079B8F
+:108FE000384623F07F4323F470031A43214608F1E7
+:108FF0000108079205950536FFF70EFCB8F5A07F2E
+:10900000CBD109B0BDE8F08F10B5B0F8DA30D0F8A8
+:10901000A82003F47043B3F5005F03D1D2F87415B0
+:10902000FFF71AFF10BDC0462DE9F043054687B093
+:10903000D0F8A890002940D0072399F8C272029373
+:1090400019330493012301934FF0000805AB0093FB
+:109050002AE007F1C003284669460393FFF7DAF8D0
+:1090600006F1C003284669460393FFF7D5FB07F5D1
+:10907000A073284669460393FFF7CCF806F5A07362
+:10908000284669460393FFF7C7FB07F51073284688
+:1090900069460393FFF7BEF806F510732846694644
+:1090A0006C460393FFF7B8FB99F8C2325FFA88F673
+:1090B000B34208F10108CCD20CE0B0F8DA3003F486
+:1090C0007043B3F5005F02D10449FFF7C5FE28469F
+:1090D000FFF77EFE07B0BDE8F083C04684C90200FA
+:1090E0002DE9F041D0F8A84086B094F907144FF06C
+:1090F000FF3289B20646FFF709F994F9673505464C
+:10910000022B01D0002007E094F90814304689B200
+:109110004FF0FF32FFF7FAF8072302931933049355
+:109120000123C0EB05070193304605ABB4F8681581
+:109130004FF0FF320093FFF7E9F84FF000084FF0CF
+:109140000003C019A4F86A3548BFA4F86A0521E0F5
+:1091500094F8662512B111F0010F19D1B4F86835F1
+:10916000B4F96A558B4253B238BFED1B013391FB02
+:10917000F3F3DBB203F5107330464FF0FF32039385
+:10918000FFF7C4F8401B059069463046FFF744FBE3
+:1091900008F10108B8F1800F5FFA88F1D8D194F98D
+:1091A00066357BB10123019305AB0093402404F5A0
+:1091B0001073304669460393FFF72EFB631CDCB245
+:1091C000802CF4D106B0BDE8F081C04630B518233C
+:1091D00087B0D0F8A8400393083305936033029317
+:1091E00000230546049301A904F19C030193FFF7B2
+:1091F00013FB2846B4F89C2240F27161F9F7A6FAF5
+:109200002846B4F89E2240F27361F9F79FFA284687
+:10921000B4F8A22240F27461F9F798FA2846B4F83B
+:10922000A02240F27561F9F791FA2846B4F8A42219
+:1092300040F27961F9F78AFA2846B4F8A62240F29A
+:109240007661F9F783FA2846B4F8A82240F2DA6189
+:10925000F9F77CFA2846B4F8AA2240F22551F9F72A
+:1092600075FA2846B4F8AE224FF48F61F9F76EFA1A
+:109270002846B4F8B0224FF49A61F9F767FAB4F8C7
+:10928000B2324FF40042DB032846134040F224512F
+:10929000F9F782FA94F8AC32284684F86735B4F8C6
+:1092A000B432A4F8683594F8B63284F8073494F8E8
+:1092B000B73284F80834FFF713FF07B030BDC0465B
+:1092C0002DE9F04F8DB0039202930BAB0646D0F818
+:1092D000A8708B4600930DF12F010DF12D030DF1B8
+:1092E0002E02FCF75BF930460DF12A010AAAFFF7BE
+:1092F00065FA3046FFF702F90723069319330893FE
+:1093000009AB04934FF000080123059381464FF405
+:1093100050735D46C246079338E097F8662522B140
+:109320000AEB0B0313F0010F2DD153B2013304AC40
+:10933000B5FBF3F303F5A073304621460793FEF720
+:1093400069FF099BBDF828201B0D92051B05920D96
+:109350001A43BDF82A3030469B059B0D42EA83280C
+:109360002146CDF82480FFF757FACDF8249097F9DD
+:10937000663530460133B5FBF3F303F5E073214660
+:109380000793FFF749FA01350AF1010A039A95425A
+:10939000C3D997F96635C3B17F2A16D14FF4C0758A
+:1093A00004AC304621460795CDF82480FFF734FA07
+:1093B00005F18003304621460135CDF8249007930E
+:1093C000FFF72AFAB5F5E07FEAD1029A07EB4203EC
+:1093D000BDF82A20A3F86C20BDF82820A3F87890C7
+:1093E000A3F872209DF82F3087F87E309DF82E303C
+:1093F00087F87F309DF82D3087F880309DF82C302D
+:1094000087F881300DB0BDE8F08FC0462DE9F04FF0
+:109410008DB00393C369D0F8A86005460C469868E0
+:109420004FF480619346EDF353F40746002800F0B3
+:109430008A80C5F8FC4F28460121FDF769FA96F8A5
+:109440002C3043B1284641490622F9F7B9F928469C
+:109450000021FEF7D9FDA4B101203D4984EAE47260
+:10946000A2EBE47200FB01F1B1FBF2F39EB202FB4E
+:1094700006F2431C8A4298B2EFD1B6F5807F01D93B
+:109480005AE00226242304FB03F349F6404293FBEF
+:10949000F2F300241B04642293FBF2FAA146A046D7
+:1094A0002EE048460AA9F9F72FFD0B9B03FB0BF3AF
+:1094B000002B04DBDB130133C3F3490206E05B42FC
+:1094C000DB1301335B105B429A05920D0A9B03FB91
+:1094D0000BF3002B04DBDB130133C3F3490306E07A
+:1094E0005B42DB1301335B105B429B059B0D43EA40
+:1094F000822347F82830631CD1449CB208F101084C
+:10950000B442CED1062228461249F9F759F915235B
+:10951000079300240B33284605A90993059706965F
+:109520000894FFF779F9039B2846009331464FF6DC
+:10953000FF722346FDF772F8EB69394698684FF4DD
+:109540008062EDF3D5F30DB0BDE8F08FCE070200D9
+:10955000005A6202C207020030B587B005AB009323
+:1095600001230193173302930833002204934FF42D
+:109570000023054603920593144628466946FFF7E3
+:109580004BF9039B01330393631CDCB2802CF4D1B1
+:1095900007B030BDF0B5D0F8A83087B093F89A2561
+:1095A0000746002A2DD1324B324D1E68144605E085
+:1095B00029463846FFF730F901341435B442F7D163
+:1095C0002D4A002453683846019310230293082340
+:1095D00004931368694600930394FFF71DF9FB6930
+:1095E0001B6B082B0DD1254A3846536869460193F9
+:1095F000122302930E330493136803940093FFF72E
+:109600000BF9102304930DF1160300934FF072032E
+:1096100008260125ADF81630384600236946039325
+:1096200002960195FFF7F8F84FF082033846694635
+:10963000ADF816300395FFF7EFF84FF006036946D3
+:109640003846ADF816300396FFF7E6F83846FFF7D0
+:10965000DBFC3846FFF728FB3846FFF73BFB384674
+:10966000FFF7B6FB38466C46FFF776FF07B0F0BD54
+:10967000F8100200D4150200181D0200F41C0200AC
+:1096800070B5B0F8DA30054603F47043B3F5005F07
+:10969000D0F8A8200CD192F9F133B3F1FF3F37D1C4
+:1096A000B2F9F833B3F1FF3F32D1B2F92C352CE0E7
+:1096B000B3F5805F35D192F95B35B3F1FF3F27D128
+:1096C00092F9F333B3F1FF3F22D192F95C35B3F154
+:1096D000FF3F1DD1B2F90034B3F1FF3F18D1B2F909
+:1096E0003035B3F1FF3F13D1B2F90234B3F1FF3F8C
+:1096F0000ED1B2F93435B3F1FF3F09D1B2F90434D8
+:10970000B3F1FF3F04D1B2F93835B3F1FF3F08D0D0
+:10971000012482F86645102228464FF49A611346C8
+:1097200007E0002482F8664528464FF49A6110222B
+:109730002346F9F731F84FF48F6103222346284678
+:10974000F9F72AF82846FFF725FF2846FBF7E2FF3E
+:109750002846FCF7E1FE2846FFF768F870BDC046D2
+:1097600010B5002388B00593103307930DF106035D
+:10977000039301230446ADF80610049303A9543360
+:109780000693FFF749F82046FBF7FEF810B1204694
+:10979000FEF7C8FE08B010BD2DE9F041D0F8A87062
+:1097A0000646002419E0B6F8DA3003F47043B3F546
+:1097B000805F07D1A218137923B1890492783046CB
+:1097C000890C07E06B4BE21853792BB18904D278EE
+:1097D0003046890CF8F73CFF0634664A4FF6FF73B3
+:1097E000A15A9942DFD1304673210022F8F730FFA9
+:1097F000304632216A22F8F72BFF192230463321F6
+:10980000F8F726FF97F8EC231AB130463321F8F722
+:109810001FFFC2216F223046F8F71AFF9021102255
+:109820003046F8F715FF102100223046F8F710FFF8
+:109830009B2107223046F8F70BFF1D2102223046FC
+:10984000F8F706FF1E2106223046F8F701FF3046E2
+:1098500040F2EA4144F28862F8F778FFB6F8DA306D
+:1098600003F47043B3F5005F0DD197F8E933B6F810
+:10987000DE1FA02B14BF022204220BB2B3F1FF3F64
+:109880000DD0CAB20BE0B3F5805F07D1B6F8E02F78
+:1098900013B2B3F1FF3F01D0D2B200E0022253B2C3
+:1098A0001FFA83F807224346304640F2EB41F8F7AF
+:1098B00073FFB6F8DA3003F47043B3F5005F05D0F8
+:1098C000B3F5805F04D197F83B350BB9002400E075
+:1098D00001242346254624010F22A4B2304640F23B
+:1098E000F241F8F759FFF0222346304640F2F241A8
+:1098F000F8F752FF0F22304640F2F1412B46F8F7BD
+:109900004BFFF0222346304640F2F141F8F744FF86
+:109910004FEA0823304640F2F2414FF4E06203F48C
+:109920007F43F8F739FFB6F8DA30304603F4704376
+:10993000B3F5805F0CBF03F53B7341F2EA23F45AA1
+:1099400040F2EB41630203F47E434FF40072F8F7F8
+:1099500023FFB6F8DA3003F47043B3F5805F0BD021
+:1099600041F23433F25A13B2B3F1FF3F04D0930201
+:1099700003E0C046EC260200A3024FF4806203F429
+:109980007C43304640F2EB41F8F706FF40F2EB41F2
+:109990003046D6F8A840F8F7CDFEC0F3802084F812
+:1099A000470540F2EB413046D6F8A840F8F7C2FE32
+:1099B000C0F3402084F84805D6F8A820304692F835
+:1099C000481592F847355B1A18BF012382F84635CF
+:1099D000FAF7ECFF830203F47C43304640F646116D
+:1099E0004FF48062F8F7D8FE304643490622F8F774
+:1099F000E7FE41F21D23F35C2BB10F2230467721A5
+:109A00001346F8F76BFE30460021FFF7A9FE97F8E2
+:109A10009A352BB93046FEF73FF83046FDF71EFF6A
+:109A2000F3697A21186936F065DE97F8EC23400077
+:109A300084B22AB124B1F369A11C186936F078DE2A
+:109A400097F8ED232AB124B1F3692146186936F05D
+:109A50006FDE97F8BB34DBB104221346304640F288
+:109A60001D11F8F73BFE30469F213F2297F8BC348A
+:109A7000F8F734FE30469E213F2297F8BD34F8F7C0
+:109A80002DFE304677210F2297F8BE34F8F726FED8
+:109A9000B6F8DA3003F47043B3F5805F29D197F953
+:109AA000583533B3B42124223046F8F7D1FDB7211D
+:109AB00024223046F8F7CCFD0322B8213046F8F7CF
+:109AC000C7FD97F95825022A07D13046B821F8F783
+:109AD000BFFD3046B521012209E0032A09D13046F5
+:109AE000B821013AF8F7B4FD3046B5210022F8F765
+:109AF000AFFDBDE8F081C046C604020010B5FFF717
+:109B00004BFE10BD70B50026D0F8A850C0F8FC6F11
+:109B100095F82C3004463BB12A490622F8F750FE4E
+:109B200020460121FEF770FA204640F24461F8F722
+:109B300001FE10F0010309D020463146FCF740FD3C
+:109B40000222204640F23F61134607E010F0020F68
+:109B500006D0204640F253414FF40042F8F71CFE75
+:109B6000204619490922F8F72BFE20460021FCF770
+:109B7000CFFE2046FAF71AFF30B12046FEF7BEFCB2
+:109B800001462046FFF7ECFD95F8473520469B023D
+:109B900003F47C4340F2EB414FF48062F8F7FCFDA4
+:109BA000B5F84E356BB1204640F64811FF22F8F764
+:109BB000F3FD204640F64911FF22B5F85035F8F77D
+:109BC000EBFD70BDE60B0200F20B020070B50C4617
+:109BD00088B00546F9F720F944B92846FFF792FF07
+:109BE00028462146FCF794FE204622E028462146DE
+:109BF0000122FAF789F8064608B1012019E0284643
+:109C00000121FCF785FE0C4B40240393152305939B
+:109C10002846102303A9079304940696FEF7FCFD3B
+:109C2000284621464FF6FF7233460096FCF7F6FCB5
+:109C3000304608B070BDC0469A21020070B50023BE
+:109C400086B002931033049305AB009302230446BD
+:109C5000ADF8141001930D464E3369461646ADF823
+:109C600016200393FEF7D8FD2046FAF79FFE78B33F
+:109C7000204640F6461140F2FF322B46F8F78CFDA5
+:109C8000204640F6471140F2FF323346F8F784FD94
+:109C900020464FF4156140F2FF322B46F8F77CFD69
+:109CA000204640F6511140F2FF323346F8F774FD7A
+:109CB000204640F6541140F2FF322B46F8F76CFD77
+:109CC000204640F6551140F2FF323346F8F764FD66
+:109CD00006B070BD2DE9F04F8DB004910392D0F81D
+:109CE000A860074606EB4303B3F872B0B3F86C10F4
+:109CF000B3F878905A460591FFF7A0FF38464946D9
+:109D0000FFF72EFD0723089319330A934FF000083D
+:109D10000123049D0793C2460BAB069337E096F8E8
+:109D200066252AB104990AEB010313F0010F2BD128
+:109D300053B2013306ACB5FBF3F303F5A073384619
+:109D400021460993FEF766FA0B9B05994FEA8B5261
+:109D50001B0D1B05920D1A438B059B0D42EA8328B0
+:109D600038462146CDF82C80FEF756FD96F966352B
+:109D700038460133B5FBF3F303F5E073214609934D
+:109D8000CDF82C90FEF748FD01350AF1010A039A3F
+:109D90009542C4D996F96635C3B17F2A16D14FF4DE
+:109DA000C07506AC384621460995CDF82C80FEF7E3
+:109DB00033FD05F18003384621460135CDF82C905E
+:109DC0000993FEF729FDB5F5E07FEAD196F8810009
+:109DD00096F87E1096F87F2096F8803000903846EE
+:109DE000FBF7DEFC0DB0BDE8F08FC04670B500217A
+:109DF0000446D0F8A8500B467F22FFF76BFF2046A1
+:109E0000FFF7E4F92046B5F8B812B5F8BA22FBF727
+:109E1000C7F8204640F2D16104220023F8F7BCFCC9
+:109E200070BDC04670B50446D0F8A8300D4699B153
+:109E300093F8BC3233B3FFF7D9FF20460422002346
+:109E400040F2D161F8F7A8FC8022204640F276610A
+:109E50001346F8F7A1FC15E00422134640F2D16145
+:109E6000F8F79AFC8022204640F276612B46F8F7FC
+:109E700093FC20462946FFF773FC204629462A46D4
+:109E8000FFF7DCFE70BDC04630B500238BB00893F1
+:109E9000079306930733054603930A4609B90491CD
+:109EA00002E04FF4307304932023059309AB019330
+:109EB000012302933AB9284608A907AA06ABF9F785
+:109EC0000FF9002409E0B5F902310793B5F904311F
+:109ED0000693B5F906310893F3E70899069B2046E7
+:109EE000079AFAF757FC01A909902846FEF794FC57
+:109EF000049B01340133802C0493EED10BB030BDB0
+:109F0000F0B5284B8BB005AC05460F460FCB84E867
+:109F10000F0041F22403EB5CD5F8A8601BB196F862
+:109F2000E034002B3BD028461F490822F8F748FCB4
+:109F3000072302931933049304230193009403F538
+:109F40004F7301240393284686F86A406946FEF75A
+:109F500063FC0023099309AB019400934FF45174FF
+:109F6000284669460394FEF757FC013440F25E33FD
+:109F70009C42F5D128460D491222F8F721FC7B00BE
+:109F80009BB2284640F2A94140F2FF12F8F704FCC8
+:109F9000284640F2A36110220023F8F7FDFB0BB026
+:109FA000F0BDC04668050200620C020054090200C0
+:109FB00030B5D0F8A8509BB004460022A31893F9FE
+:109FC000103501A95B4241F822300132142AF5D143
+:109FD00095F86A3063B907331793193319931591BC
+:109FE00003F54873204615A916921893FEF714FC42
+:109FF000D4F8A81094F82936D1F844242046934286
+:10A00000A8BF1346D1F8482440F2A7419342B8BFF5
+:10A0100013469BB2FF22F8F7BFFB95F8E833F3B184
+:10A02000B5F8E62394F8293620469B1A1B024FF414
+:10A030007F42134040F2D141F8F7AEFB94F8292655
+:10A0400095F825352046C3EB420395F8E62340F208
+:10A05000D1419B1A5BB2FF229BB2F8F79DFB2046D1
+:10A06000FAF7A6FB1BB030BD70B5C6B001ACD0F896
+:10A07000A8500646002120464FF48072E7F3E0F72F
+:10A080000723439319334593419495F86A3043B9B4
+:10A090001E33429330464FF4507341A94493FEF768
+:10A0A000BBFB402342933046DB1841A94493FEF7A3
+:10A0B000B3FB46B070BDC0462DE9F04106460C46E4
+:10A0C000FAF72CFF214605463046FAF74FFC2946A1
+:10A0D00004463046FAF74AFC4022B4F5404F0CBF24
+:10A0E00013460023054640F2DA613046D6F8A870E0
+:10A0F000F8F752FB1022B4F5404F14BF134600236B
+:10A10000304640F2A361F8F747FB0122B4F5404F17
+:10A1100014BF00230123304640F26E41F8F73CFBA8
+:10A12000A54200F09580B5F5404F02D13046FFF7CB
+:10A130009BFFB4F5404F3CD13046FFF739FFD6F8CE
+:10A14000A8203B8E92F966255B00013293FBF2F367
+:10A15000304640F2A44140F2FF129BB2F8F71CFBDC
+:10A160007B8E30461B0240F2A5414FF4E06203F4BF
+:10A170007F43F8F711FB04223046002340F21F1101
+:10A18000F8F7ACFAF369E021186936F0B3DA002188
+:10A19000F8853046FAF7A2FF4FF0FF3387F83430E6
+:10A1A000304640F2A9414FF400420133F8F7F4FA87
+:10A1B00003E030460121FAF791FF304640F2A44116
+:10A1C0004FF460422346F8F7E7FAB4F5404F0FD159
+:10A1D0003046FAF7EBFB40F2A44100280CBF4FF4E5
+:10A1E000005300234FF400523046F8F7D5FA15E03B
+:10A1F0004EF201039C4211D13046FAF717FB01469B
+:10A200003046FFF77DFE304640F2A941F8F792FA5A
+:10A210000223C0B290FBF3F087F8C10297F96735CB
+:10A22000012B0DDD40F2A4413046F8F783FAC0F36C
+:10A23000803340F2255130464FF40042DB0305E005
+:10A24000304640F225514FF400420023F8F7A4FABB
+:10A25000BDE8F08170B50023D0F8A82080F82B3637
+:10A2600092F8E03405468BB190F92A16D2F84834BA
+:10A27000994203DBD2F81035994207DA4EF2010118
+:10A28000FFF71AFF012385F82B3612E041F2240371
+:10A29000EB5C73B12846FAF741FE002104462846DC
+:10A2A000FFF70AFF2846FFF783FE28462146FFF7FF
+:10A2B00003FF70BD30B5072389B0D0F8A8400393E1
+:10A2C0001933059306AB0193012302930546013B25
+:10A2D000049308E0284601A9FEF79EFA049B013387
+:10A2E0000493069B01330693069B7F2BF2D94FF410
+:10A2F00030730493A3F5307308E0284601A9FEF7F4
+:10A300008BFA049B01330493069B01330693069B4F
+:10A310007F2BF2D9092228465B49F8F751FA01212F
+:10A320002846FBF7A3FB242228465849F8F748FAA9
+:10A330002846FAF75FFDC0F34F00E62801DDFF2352
+:10A3400005E02846FAF756FD4008193083B2FF228F
+:10A3500040F2A5412846F8F71FFA2846FFF784FE89
+:10A36000B4F8E623B4F8E433284603EB42039B0138
+:10A370009BB24FF49A6147F6C072F8F70DFA0922C2
+:10A3800028464349F8F71CFAB5F8DA30282103F4D7
+:10A3900070431E22B3F5005F14BF18231C23284608
+:10A3A000F8F79CF901223A2113462846F8F796F966
+:10A3B0000822134628464FF48D71F8F78FF92521AE
+:10A3C0000C222846F8F744F9B5F8DA3003F4704364
+:10A3D000B3F5005F04D1022228463A21134603E078
+:10A3E00028463A2102220023F8F778F9082213467A
+:10A3F00028460521F8F772F9284606222549F8F77C
+:10A40000DFF947F20802284640F2D7414FF40053E3
+:10A41000F8F7C2F92846FAF7EDFC102305930DF181
+:10A420001E03019301230824ADF81E000293284661
+:10A43000053301A904930394FEF7EEF928460F2291
+:10A440001549F8F7BDF928463521FF220023F8F712
+:10A4500045F92846362103220023F8F73FF928461C
+:10A46000224623464FF48D71F8F738F94FF4806295
+:10A47000284640F2A4411346F8F78EF92846FBF728
+:10A480008DFA09B030BDC046C60D02009A05020023
+:10A49000A4070200F40D0200000E02007FB50902BD
+:10A4A00006AB23F8021D009301230193013B0293A5
+:10A4B00057330393694610230493FEF7ADF907B0B1
+:10A4C00000BDC0462DE9F041D0F8A8308AB083F82D
+:10A4D000341083F8C11293F9663506460F466BB106
+:10A4E00011F0010304D04FF48F610C22082302E025
+:10A4F0004FF48F610C22F8F74FF97F08072303937D
+:10A5000001AC07F5A07320254FF0010804933046F5
+:10A5100009AB214601930595CDF80880FDF77AFE39
+:10A5200007F1C003049330460DEB05032146019368
+:10A530000595FDF76FFE089B304603F0FF02ADF86E
+:10A540001820C3F30722C3F30743ADF81C30099B5F
+:10A5500006A9C3F30273ADF81A20ADF81E30FAF75E
+:10A56000F5FD09993046C1F30751FFF797FF3046D3
+:10A570004146FAF7B3FD0AB0BDE8F0812DE9F04F8E
+:10A5800091B0BDF8783002AC0193BDF87C3007463D
+:10A590000093534B9DF880601D460FCD0FC495E886
+:10A5A0000F009DF8748084E80F0038464D4904225E
+:10A5B000BDF87090BDF884A0BDF888B0F8F700F938
+:10A5C000384640F2A36102227300F8F7E5F8B8F1CB
+:10A5D000000F18D010AB4FF4002243F8042D0A935B
+:10A5E00001230B9317330C9308330E9300230D9321
+:10A5F0001C4638460AA9FEF70FF90D9B01340133BA
+:10A60000402C0D93F5D1032409FB04F43846FAF7E6
+:10A61000EBFE0134384640F2A1615246F8F796F855
+:10A62000A4B2384640F2A2615A46F8F78FF82246A3
+:10A63000384640F27E61F8F789F838462A49042204
+:10A64000F8F7BEF80134142304FB03F4013CA2B272
+:10A6500038464FF4C861F8F779F80022384640F2DE
+:10A660007761F8F773F808230B930D330C930B33D2
+:10A6700000240E93384602AB0AA90A930D94FEF704
+:10A68000CBF8384640F27B61019AF8F75FF838461C
+:10A6900040F27C61009AF8F759F82246384640F2B9
+:10A6A0007D61F8F753F821463846FFF7F7FE384644
+:10A6B0000E490422F8F784F80D4C03E00A20ECF36D
+:10A6C0004BF00A3C384640F27661F8F733F810F068
+:10A6D000010F01D0092CF1D111B0BDE8F08FC046B7
+:10A6E000B80C0200780B02008A0802001E0E02005D
+:10A6F00049420F002DE9F043D0F8A8908BB00646F0
+:10A700008846052503270F2DA8BF0F250024ABB2CF
+:10A71000019330460121224623460094029403947B
+:10A720000494FAF75BFDDB2302934FF4AF630493C9
+:10A730004FF482430593A3F58143012207933046EA
+:10A740002146234600940194039206940894FFF74F
+:10A7500015FFB8F1000F1DD140F2BA613046F7F78E
+:10A76000E9FF40F2BB6104B23046F7F7E3FFA40112
+:10A77000A4B244F3891404FB04F440F3090000FB81
+:10A780000043B3F5005F01DAED1B03E0B3F5804F42
+:10A7900004DBED1917B17B1EDFB2B4E7092D01DD33
+:10A7A000092501E025EAE5752846C9F838500BB0BF
+:10A7B000BDE8F0832DE9F043D0F8A8608DB096F99C
+:10A7C000663507468846CCB2D3B1634B01EA030332
+:10A7D000002B05DA013B6FEAC3736FEAD3730133D1
+:10A7E000012B04D14FF48F610C22073303E04FF4A7
+:10A7F0008F610C220023F7F7CFFF022398FBF3F8B9
+:10A80000072386F8344086F8C14201AD039308F56A
+:10A81000A07320244FF00109049338460BAB29465E
+:10A8200001930594CDF80890FDF7F4FC08F1C003FE
+:10A83000049338460AAB294601930594FDF7EAFCD8
+:10A840000A9B384603F0FF02ADF81820C3F3072235
+:10A85000C3F30743ADF81C300B9B06A9C3F3027387
+:10A86000ADF81E30ADF81A20FAF770FC9DF82B10E9
+:10A87000384601F07F01FAF71DFC0B993846C1F309
+:10A880000751FFF70BFE38464946FAF727FC0B9AAB
+:10A890003846C2F389219205920DFFF7CFF908F5EA
+:10A8A000E0730493384609AB29460193FDF7B2FCE7
+:10A8B0003846BDF82410FEF753FF08F510730493D3
+:10A8C00038460DEB040329460193FDF7A3FC089BD2
+:10A8D0003846DB009BB240F2A66141F6FF72F7F703
+:10A8E0005BFF96F967354B4532DD40F2255138461E
+:10A8F000F7F720FF4FF48072C3B29845D4BF00240D
+:10A90000012438469845CCBF1346002340F2255118
+:10A91000F7F742FF6302384640F225514FF40072C8
+:10A9200003F47E43F7F738FFA302384640F225517F
+:10A930004FF4806203F47C43E402F7F72DFF3846BE
+:10A9400040F225514FF4006204F47843F7F724FFF6
+:10A950000DB0BDE8F083C0460100008070B504462C
+:10A960000D460021FFF7A8FB20462946FFF722FFEE
+:10A9700070BDC0462DE9F04F89B0054600920191A7
+:10A98000FAF7CCFA40F23B4103902846F7F7D2FEA3
+:10A9900004A902902846FAF70FFA00244FF47A70BF
+:10A9A0000134EBF3D9F6022CF8D141F2F023EA5846
+:10A9B00092F820301F1E18BF012792F821300BB1EA
+:10A9C0007B1C9FB292F822300BB17B1C9FB292F895
+:10A9D00023300BB17B1C9FB24FF00009C8464FF0EB
+:10A9E000140ABCE0D5F8B030D3F8203183F001036D
+:10A9F00013F0010403D1EB69186935F0CBDE28466A
+:10AA0000F8F756FB41F2F023EB58284603EB4803D6
+:10AA1000998CFFF7A3FF28465146FFF73FFD1CB96D
+:10AA2000EB69186935F0A2DE4FF40042284640F287
+:10AA3000A4411346F7F7B0FE002441F288300134F8
+:10AA4000EBF38AF6032CF8D1284640F2A641F7F73B
+:10AA500071FEC005C00DFF2886BFA0F580731FFAE8
+:10AA600083FB00F5807B00263446284640F23E6199
+:10AA7000F7F760FE631CC005C00D9CB23618102CA1
+:10AA8000F3D1C6F30F13FF2B8CBFA3F5807303F52F
+:10AA90008073504600210DF11E029EB20DF11A0383
+:10AAA000EDF388F441F2F023EB580021434493F88E
+:10AAB000200007AA06ABEDF37DF4BDF91A30BDF90D
+:10AAC00018108B4209DABDF91C00C91AEDF324F500
+:10AAD000BDF81A40ADF81C0009E0BDF91E00C1EB3D
+:10AAE0000301EDF319F5BDF81840ADF81E00BDF9EE
+:10AAF0001C10BDF91E00EDF319F523B2032B81B232
+:10AB000001DD231F01E0C4F1040398B200B2431E2B
+:10AB100001229A4009B2052301FB032353FA00F0F6
+:10AB200000F10C03182B16D841F2F023EB58019AD0
+:10AB300003EB88031B69C31802F809304FEA9B0333
+:10AB4000C3F17F03009A03EB960302F8093009F181
+:10AB500001031FFA83F908F101031FFA83F8B845CE
+:10AB6000FFF440AF0AF101035FFA83FABAF1640F10
+:10AB700002D84FF00008F2E7029B2846C3F3801189
+:10AB8000FAF7ACFA284604A9FAF7E0FA284603993E
+:10AB9000FFF792FA484609B0BDE8F08F2DE9F04F73
+:10ABA0001E46C369A9B0D0F8A88004460F4698682D
+:10ABB0004FF483711546ECF38BF00790002800F0FA
+:10ABC000EF81022E0FD016E00E4694F8DA3011F81D
+:10ABD0000629013D9A420BD17188B2882046FAF7C6
+:10ABE000DFF90126CCE1062305FB03F3063BF91848
+:10ABF000002DE9D1C3E1012E40F0C1812046FAF7D2
+:10AC00008DF9002108902046FFF756FA0025934B56
+:10AC10002046E95AF7F704FD1AABE8520235182D21
+:10AC2000F5D140F231612046F7F784FD15220B90F3
+:10AC300040F231612046F7F79FFD40F24C4120463B
+:10AC4000F7F778FD40F24D410C902046F7F772FD82
+:10AC50004FF496610D902046F7F76CFD40F2B1413C
+:10AC60000E902046F7F766FD40F2F9410F9020461E
+:10AC7000F7F760FD40F2FA4110902046F7F75AFDD1
+:10AC800040F6381111902046F7F754FD40F639117F
+:10AC900012902046F7F74EFD40F23B4114902046BB
+:10ACA000F7F748FD40F23C4115902046F7F742FD8A
+:10ACB00040F2DA6116902046F7F73CFD40F2DB6186
+:10ACC00018902046F7F736FD40F2B741199020461C
+:10ACD000F7F730FD40F23B4113902046F7F72AFD8D
+:10ACE000C0F380100A9008B9099007E0204626A911
+:10ACF000FAF762F898F8C182CDF82480204632999C
+:10AD0000FFF72CFE062220465549F7F759FDB4F807
+:10AD1000DA3003F47043B3F5005F04D12046982184
+:10AD20000322F7F795FC20464E491922F7F748FD14
+:10AD300020464D491822F7F743FDB4F8DA304FF0BA
+:10AD4000030B03F47043B3F5005F14BF0423002327
+:10AD5000179322E11FFA88F300931FFA89F3002664
+:10AD600001931FFA8BF3324602932046179B31461C
+:10AD700003960496FAF732FA20460121FAF742F9CF
+:10AD80003346204639493C22FEF740FB20464FF42B
+:10AD900089713246F7F75CFC20AB00934FF4FA7AE6
+:10ADA00020464FF4806120223346CDF804A0FAF704
+:10ADB000F7FF054620B92E48F6F776FC2F4636E019
+:10ADC0003346204629497822FEF720FB20464FF4DF
+:10ADD00089713246F7F73CFC23AB009320464FF4D1
+:10ADE000806120223346CDF804A0FAF7D9FF18B9C4
+:10ADF0002048F6F759FC1AE0219A24982299B0EBE2
+:10AE0000420F0ED993009B1898420AD2259AB2EBB2
+:10AE1000410F06D98B005B189A422CBF00270127EF
+:10AE200000E00027B8F1010801D3002F92D0B9F15A
+:10AE3000010902D3002F00F0AC80BBF1010B02D35B
+:10AE4000002F00F0AA80204640F2D16104220023A6
+:10AE5000F7F7A2FC87B93E4614E0C046020502009F
+:10AE60001A05020026050200FA05020080841E0071
+:10AE7000EC0602000607020020464FF48061FDF751
+:10AE80002BF806462046FEF73DFE204640F2316193
+:10AE90000B9AF7F75BFC204640F24C410C9AF7F70F
+:10AEA00055FC204640F24D410D9AF7F74FFC2046E5
+:10AEB0004FF496610E9AF7F749FC204640F2B141F3
+:10AEC0000F9AF7F743FC204640F2F941109AF7F742
+:10AED0003DFC204640F2FA41119AF7F737FC204634
+:10AEE00040F63811129AF7F731FC204640F6391136
+:10AEF000149AF7F72BFC204640F23B41159AF7F7DE
+:10AF000025FC204640F23C41169AF7F71FFC2046EC
+:10AF100040F2DA61189AF7F719FC204640F2DB613B
+:10AF2000199AF7F713FC204640F2B741139AF7F746
+:10AF30000DFC204640F24C4104220023F7F72CFC84
+:10AF40000025194B2046E95A1AABEA5A0235F7F7A1
+:10AF50007FFB182DF5D10A9B23B120460999FFF7F5
+:10AF6000FDFC03E020460A99FAF7B8F82046089954
+:10AF7000FFF7A2F820460021FAF744F800E0002687
+:10AF8000E369079998684FF48372EBF3B1F63046A2
+:10AF900006E000274FF00608DCE64FF00409F8E76A
+:10AFA00029B0BDE8F08FC046020502002DE9F04F40
+:10AFB000B3B00F939DF8F8409DF8F4300D940E93C4
+:10AFC0009DF800419DF8FC300B940C93012405463C
+:10AFD0001646D0F8A89088469DF8F0B0BDF80471E8
+:10AFE0008DF8C7408DF8C640FDF702FC40F2D7410E
+:10AFF00012902846F7F79EFB40F2D7411090284662
+:10B00000F7F798FB3449119006222846F7F7D8FB4A
+:10B01000284632490F22F7F7D3FB284621461AAAC1
+:10B02000FDF786FB284621460022FDF7F5FABBF125
+:10B03000000F02D00023199318E028462146FBF7A1
+:10B0400067FCD5F8B030D3F8203183F0010313F05A
+:10B05000010319930AD1EB69B821186942F2107201
+:10B0600035F066DBEB69186935F094DB2846012181
+:10B07000F9F7C8FF28460121FBF7A2FA284601216B
+:10B08000FAF72EF940F2EA412846F7F753FB40F26F
+:10B09000EB4117902846F7F74DFB40F2EB41189033
+:10B0A0002846F7F747FB00F0070340F2EB4128463C
+:10B0B0003822DB00F7F770FB28462DA999F8C1A2CA
+:10B0C000F9F77AFE86B1337A53B12846717AFFF7E1
+:10B0D00045FC96F809A007E0F6090200A60B02005D
+:10B0E00028463146FAF732F840F29C412846F7F7F5
+:10B0F00021FB40F2316113902846F7F71BFB40F229
+:10B10000D66115902846F7F715FB40F2DA611490E6
+:10B110002846F7F70FFB002116902846FAF728FA81
+:10B12000284688490722F7F74BFB2FAB23930123CF
+:10B1300024930633259376B199F96625737A013203
+:10B1400093FBF2F303F5107326932846202323A9DB
+:10B150002793FDF75FF82F9A2846D2002F9240F2EE
+:10B16000716192B2F7F7F2FA284677490C22F7F7A5
+:10B1700027FB0024754B284633F81410F7F750FAD4
+:10B180000DF1A203E0540134122CF3D1072228461A
+:10B190004FF48B71F7F75CFAB5F8DA3003F47043CB
+:10B1A000B3F5005F05D1284640F22D110122F7F7D3
+:10B1B0004FFA072228464FF49671F7F749FAB5F887
+:10B1C000DA3003F47043B3F5005F14D128466A21E6
+:10B1D000C222F7F73DFA284698210C22F7F738FAF1
+:10B1E000284640F22F110322F7F732FA284697211A
+:10B1F000F922F7F72DFA0B2107222846F7F728FA4C
+:10B200001022284640F21311F7F722FA1D210122DD
+:10B210002846F7F71DFA012228464FF48A71F7F7FE
+:10B2200017FAB5F8DA3003F47043B3F5005F04D1D0
+:10B2300028462E211022F7F70BFA082228464FF451
+:10B240009571F7F705FA092102222846F7F700FA67
+:10B2500004221346284640F21F11F7F73FFAFF2158
+:10B26000102200232846F7F739FA0721012200238C
+:10B270002846F7F733FA0521082200232846F7F776
+:10B280002DFA4FF400421346284640F2DA61F7F7F0
+:10B2900083FA41460F9A53462846FFF72BFA0024BB
+:10B2A00080B2012101902246284623460094029450
+:10B2B00003940494F9F792FF0E9BA74208BF4FF442
+:10B2C000824700930D9B284601930C9B41460293B5
+:10B2D0000B9B224603934FF4AF630493A3F59F6344
+:10B2E00007935B46059706940894FFF747F90DF11D
+:10B2F000C60228460DF1C701F9F798FC9DF8C62053
+:10B300003F2A53D89DF9C730A3424FDB3F2B4DDC7A
+:10B3100052B29A424ADCB8F1000F27D123AC18236D
+:10B3200021462593284630AB26922393FCF772FFE3
+:10B330009DF9C73021462846309E2693FCF76AFFC8
+:10B3400044460EE0020A0200200D0200260E020012
+:10B3500030AB284623A9269430962393FDF75CFA58
+:10B3600001349DF9C62063B29A42F1DC182323AC64
+:10B37000259326332693284630AB21462393FCF7AA
+:10B3800049FF3F23284621462693FDF745FA01232E
+:10B39000284621462693FCF73DFF002328462146F8
+:10B3A0002693FDF739FA2846FDF72EF8284640F295
+:10B3B000EA41179AF7F7CAF9284640F2EB41189A82
+:10B3C000F7F7C4F92846D72102220023F7F786F9B8
+:10B3D000082213462846D721F7F780F9002328468C
+:10B3E0004FF494710822F7F779F928464FF48B71DE
+:10B3F0000022F7F72DF9284640F29C41139AF7F7FF
+:10B40000A5F9284640F23161159AF7F79FF92846C9
+:10B4100040F2D661149AF7F799F9169C284644F041
+:10B42000010292B240F2DA61F7F790F92846012161
+:10B43000FAF79EF8109C082204EA0203284640F21C
+:10B44000D741F7F7A9F9119C4FF4E04204EA02034F
+:10B45000284640F2D741F7F79FF92846FAF73CFD16
+:10B460000024234B284633F814100DF1A203E25CAC
+:10B470000134F7F7EDF8122CF3D14FF400620023FA
+:10B48000284640F24C41F7F787F928460021FBF7A0
+:10B4900097F828460021F9F7B5FD284640F23B41D0
+:10B4A00001220023F7F778F900234FF400622846C1
+:10B4B00040F63811F7F770F928460021FBF728FA13
+:10B4C000284600211AAAFDF733F9284609490F2218
+:10B4D000F7F776F9199B1BB9EB69186935F046D96E
+:10B4E00028461299FEF7DAFF33B0BDE8F08FC04668
+:10B4F000260E0200C40A02002DE9F04FD0F8A83051
+:10B5000091B093F8F49318230C930FAB0A93202374
+:10B510000E93012317460B9301FB01FB3E330521DC
+:10B5200000228046B9F1FF0F08BF4FF001090D93CB
+:10B530000791099206230024039347F6FF733A46C6
+:10B540000125059340462346214600940194029428
+:10B550000495FFF72BFD40460AA9FCF75BFE0F9A06
+:10B5600042F30B3303FB03F342F30B0202FB023201
+:10B570007B7A5A45069303D307990894CEB206E026
+:10B58000B9F1000F4DD1079908954B42DEB273B265
+:10B5900006999DB26B189CB24FF0000A06990AEB0F
+:10B5A000010308999BB221B15A4506D99B1B7B72B6
+:10B5B0002DE0089B0BB95A4529D322B27F2A26DCFD
+:10B5C0000AEB0503002A1FFA83FA20DB06237C72AC
+:10B5D000039301230021049347F6FF733A46059332
+:10B5E00040460B46009101910291FFF7DFFC404677
+:10B5F0000AA9FCF70FFE0F9A42F30B3303FB03F388
+:10B6000042F30B0202FB023263199CB2C6E70799B0
+:10B61000099A41F346030132DBB2032A07930992E8
+:10B6200088D111B0BDE8F08F2DE9F04F8DB0DDF875
+:10B6300058A01F460123834616468AF808304FF06B
+:10B6400000094FF0640808EB09030021C3F34F051C
+:10B65000DB238AF8095001245246039358460B46CF
+:10B6600000910191029105910494FFF79FFC18232A
+:10B670000893273309930BAB06935846202306A95A
+:10B680000A930794FCF7C6FD0B9B43F30B3202FBB6
+:10B6900002F243F30B0303FB03231A464FEAE27360
+:10B6A000BB4202D803D1B24201D9A94600E0A84664
+:10B6B0000B484FF0FF31801941EB07018B4202D854
+:10B6C00006D1824204D99F4206D801D1964203D8BE
+:10B6D000C9EB0803012BB6DC28460DB0BDE8F08F9E
+:10B6E00030F8FFFFF7B50546D0F8A87090F8DA00FB
+:10B6F0000E46F7F735FA40F6B41398420446B5F80B
+:10B70000DA2001D11E480AE0D3B2012B02D14FF456
+:10B71000523004E00302A3F5C420A0F580600022AB
+:10B720004FF47A71F9F716F8A0FB0023284600962B
+:10B73000FFF77AFFA0F128039BB21D2B1BD9272806
+:10B7400002D84FF434300BE040F6B4139C4202D1DF
+:10B750004FF4703004E02302A3F5BE20A0F5007082
+:10B7600000224FF47A71F8F7F5FFA0FB002328467A
+:10B770000096FFF759FF031F87F8C232FEBDC0468F
+:10B78000008E03002DE9F04390F8DA30D0F8A8607D
+:10B790008BB086F8BC32D0F8B0300546D3F82031F3
+:10B7A00083F0010313F001090AD1C369B8211869B4
+:10B7B00042F2107234F0BCDFEB69186934F0EADF52
+:10B7C00040F2A5412846F6F7B5FF04462846F9F7AA
+:10B7D000A5FB002180462846FEF76EFC4FF4404151
+:10B7E0002846FEF769FC2846FEF73EFCD5F8A8205F
+:10B7F0002846D2F84434D2F84824402BA8BF40232E
+:10B800009342B8BF134640F2A741FF229BB2F6F71E
+:10B81000C3FF0023284640F2A5414FF4E062F6F74B
+:10B82000BBFF4FF47A7232212846FBF7ABF80121B7
+:10B83000284696F8C072FBF76BF82846F7F738FCF5
+:10B840004FF4E06204EA0203284640F2A541F6F70D
+:10B85000A3FF00212846FEF72FFC96F8C4420DF105
+:10B860001E0E012C35D171462846FFF73BFF2846B6
+:10B870002146FDF7D9FBD5F8A8202846D2F8443454
+:10B88000D2F848243E2BA8BF3E239342B8BF1346AC
+:10B8900040F2A741FF229BB2F6F77EFF0023284625
+:10B8A00040F2A5414FF4E062F6F776FF28463221D8
+:10B8B0004FF47A72FBF766F896F8C032DBB996F867
+:10B8C000C2322846043386F8C2322146FDF7ACFB6B
+:10B8D00011E000210122DB238DF82620039304923E
+:10B8E000284672460B468DF827700091019102910F
+:10B8F0000591FFF75BFB28464146FEF7DDFB284636
+:10B9000008490422F6F75CFFB9F1000F03D1EB6997
+:10B91000186934F02BDF28460021FAF7F9FF0BB045
+:10B92000BDE8F083800C02002DE9F04F044695B08D
+:10B93000D0F8A86040F2E7300F46EAF30DF7072190
+:10B940002046F6F76DFEC0B20390FF212046F6F7C1
+:10B9500067FEC0B2049040F21F112046F6F760FE69
+:10B96000C0B2059005212046F6F75AFE25215FFA60
+:10B9700080FB2046F6F754FE4FF489715FFA80FA97
+:10B980002046F6F74DFE00250190864B2046E95AE9
+:10B99000F6F7D0FE07ABE85202351C2DF5D1D4F8EE
+:10B9A000B030D3F8203183F0010313F00103029388
+:10B9B00003D1E369186934F0EDDE40F2A44120467A
+:10B9C000F6F72EFE002181462046FEF775FB7F210B
+:10B9D000204696F8C182FEF7C1FF012207211346D7
+:10B9E0002046F6F77BFE1022FF2113462046F6F78D
+:10B9F00075FE04221346204640F21F11F6F76EFE34
+:10BA0000362220466849F6F7DBFE2046F9F7F2F9C0
+:10BA1000C0F34F00E62801DDFF2305E02046F9F7DB
+:10BA2000E9F94008193083B2FF22204640F2A541CF
+:10BA3000F6F7B2FE25210C222046F6F709FE082271
+:10BA4000134605212046F6F749FE092257492046AC
+:10BA5000F6F7B6FE2046F9F7CDF91023129301232D
+:10BA6000ADF84E0008260F9306250DF14E03204633
+:10BA70000EA910960E931195FCF7CEFE012F0CD156
+:10BA80002A4620464A49F6F79BFE2022204682217C
+:10BA90001346F6F723FE042506E02A4620464549CC
+:10BAA000F6F78EFE07260A250122134620464FF49C
+:10BAB0009B61F6F771FE45F4007343EA06139B00A1
+:10BAC00020464FF49B6140F6FC72F6F765FE0222B9
+:10BAD000134620464FF49B61F6F75EFE20464FF476
+:10BAE0009B614FF4E0424FF40053F6F755FE2022DD
+:10BAF000134620464FF49A61F6F74EFE01210022CC
+:10BB00002046F8F7DFF9204640F27641F6F712FEBC
+:10BB100010F4004F02D10A20EAF31EF62046072156
+:10BB2000039AF6F795FD2046FF21049AF6F790FD5B
+:10BB3000204640F21F11059AF6F78AFD204605219E
+:10BB40005A46F6F785FD204625215246F6F780FD38
+:10BB5000019B20464FF48971DAB2F6F779FD002592
+:10BB6000104B2046E95A07ABEA5A0235F6F7EEFDCC
+:10BB70001C2DF5D120464FFA88F1FEF7EFFE204646
+:10BB800040F2A4414A46F6F763FD029B1BB9E36904
+:10BB9000186934F0EBDD40F2E730EAF3DDF515B07B
+:10BBA000BDE8F08F1A0A020036060200780502008E
+:10BBB000A2060200740C02002DE9F04FBDB007464A
+:10BBC0000C469146002116220DF15E000493E6F327
+:10BBD00037F2A8490E220DF19E00E6F3CDF1A649F9
+:10BBE0000E2224A8E6F3C8F148F2670148F2452284
+:10BBF000ADF8EA10ADF8E820A04908220DF1C60022
+:10BC0000E6F3BAF19E490E220DF18200E6F3B4F19B
+:10BC10009C4908220DF1BE00E6F3AEF19A490E22CE
+:10BC20001DA8E6F3A9F147F69733002108220DF18C
+:10BC3000B600ADF8E630ADF8E430E6F301F2FB69AA
+:10BC400030219868D7F8A880EBF342F005900028DF
+:10BC500000F0AB8240F2DB613846F6F76BFD40F254
+:10BC6000DA610B903846F6F765FD88490A900422A0
+:10BC70003846F6F7A5FDB9F1070F0BD8DFE809F054
+:10BC800011040A0A0A22352D1DAA069224AB0DF1D1
+:10BC90005E0214E00DF18202002306921A46079319
+:10BCA00019E000210A460B4638460091F9F778FD65
+:10BCB0000DF1820106910DF15E020DF19E03072147
+:10BCC00007933EE00DF1E6030DF1EA01069308F15A
+:10BCD0008202079101230E9334E039A906913AAB11
+:10BCE00008F18202012107932BE03BAB00930DF199
+:10BCF000EF010DF1EE020DF1ED033846F9F74EFCC0
+:10BD00009DF8EF209DF8EE300DF1BE0143EA0223CD
+:10BD10004FF00002ADF86C30ADF86E209DF8EC30BD
+:10BD20009DF8ED20069143EA0223ADF870304FF004
+:10BD30000003ADF872300DF1C6030DF15E020793FA
+:10BD400004210E911023009330330193504B0021B6
+:10BD5000029338460B23F6F7A7FE05224D493846D5
+:10BD6000F6F72EFD3846F9F7D9F84FF4805213460E
+:10BD7000089040F2A4413846F6F70EFD00213846FF
+:10BD8000FEF79AF940F2DB413846F6F7D3FC424918
+:10BD9000062209903846F6F713FDB7F8DA3003F4B7
+:10BDA0007043B3F5005F07BF38463C4938463C490D
+:10BDB0001222F6F705FD40F2D7413846F6F7BAFCF5
+:10BDC000059911903846FBF7BFFE384640F23B41DB
+:10BDD000F6F7B0FCC0F380100C9020B138460DF19E
+:10BDE000B601F8F7E9FF64B90C9A22B93846B8F8F9
+:10BDF0003010FEF7B3FD0DF1CE0438462146F8F7BA
+:10BE0000DBFF638822881B0143EA0223A2882146C4
+:10BE100013439EB2B7F8DA30082203F470430DF1F1
+:10BE2000D600B3F5805F14BF00250125E6F3A4F02A
+:10BE30000A222BA80021E6F303F11A4B002233F863
+:10BE40001540104633E0184B53F82530C1180B88C5
+:10BE50001230B3422AD14B882BA8ADF8D6308A884D
+:10BE6000ADF8D82031F8063F0A22ADF8DA30E6F313
+:10BE700083F01EE078090200CE0E020022080200C4
+:10BE800058050200BC0A02005A080200900702008E
+:10BE900019880100D806020024090200FC0C0200E7
+:10BEA00030090200720C0200F80C02000132A242BA
+:10BEB000C9D138460DF1D601F9F748F9002404221A
+:10BEC00038463749374DF6F77BFC10260A233846AB
+:10BED0002146354A009601940295F6F7E5FD2023A8
+:10BEE000019338460A2321462F4A00960295F6F719
+:10BEF000DBFD40F25341384640F2A472F6F726FCCF
+:10BF0000B8F8C81340F6A663A14208BF1946B9F1B4
+:10BF1000050F01D14B4299B2D7F8FC3F0CB22BB1BF
+:10BF20003846FDF7EFFD0520EAF316F44FF47A7179
+:10BF300001235822384604FB01F1FDF767FA40F26D
+:10BF4000DA614FF6FF723846F6F700FCB7F8DA30E0
+:10BF5000384603F47043B3F5005F0CBF98F895952D
+:10BF600098F89695F8F7B4FF0021C0B2FF228B46EF
+:10BF700010900D910F929AE04FF000030799ADF8E1
+:10BF8000E0303BF80130C3F30324B9F1000F1AD0BD
+:10BF9000042C0BD00F9A042A13D110990EE0C0463E
+:10BFA000A20A020019880100640B0200109901EB3B
+:10BFB0000903D9B211F0800F18BF7F213846FEF770
+:10BFC00081FAE2B20F92069B3CA93BF8032001EBF9
+:10BFD000440333F8441C21B102F0FF0343EA012378
+:10BFE0009AB2384640F25241F6F7B0FBE31E1FFA10
+:10BFF00083FABAF1010F16D86D4B10254524029330
+:10C00000384600210DF1E202012300950194F6F774
+:10C010003DFD684B38460293002138AA0123009564
+:10C020000194F6F741FD079B384640F251413BF839
+:10C030000320F6F78BFB3846F9F72EFF00287CD05B
+:10C040005B4A602112AC10250B2301910292002162
+:10C05000384622460095574EF6F718FD40230193C7
+:10C0600000210B233846224600950296F6F71CFD68
+:10C07000BAF1010F0AD845230193384600210DF18A
+:10C08000E202012300950296F6F70EFD484960236F
+:10C090000193029108F18202384600210B2300959A
+:10C0A000F6F7F4FC0D9A0BF1020B01320D920D9B89
+:10C0B0000E998B427FF460AF602301933C4B08F1F3
+:10C0C0008206102402933846002132460B23394D54
+:10C0D0000094F6F7DBFC4FF001025023A8F89820FB
+:10C0E0003846019300213246042300940295F6F766
+:10C0F000DBFC552301933846002108F18C02022312
+:10C1000000940295F6F7D0FC3846F8F74FFCA0B142
+:10C1100038A90DF1DE023846FCF750FB3846FCF733
+:10C12000EDF9BDF8E0100446BDF8DE203846FDF715
+:10C1300085FD38462146FDF713FB049B13B93846AD
+:10C14000FDF7E0FC38460599F9F714FB384640F254
+:10C15000D741119AF6F7FAFAFB69059998683022E7
+:10C16000EAF3C6F5384640F2DB41099AF6F7EEFAF3
+:10C1700040F2534138460022F6F7E8FA0C9921B113
+:10C1800038460DF1B601F8F7E1FF38460899FDF79A
+:10C1900093FF384640F2DA610A9AF6F7D7FA384642
+:10C1A00040F2DB610B9AF6F7D1FA3DB0BDE8F08FB3
+:10C1B00015820100198801002DE9F0470546D0F8E5
+:10C1C000A8404FEA0118F8F783FE40F2D74147B282
+:10C1D0002846F6F7AFFA94F925258146B2F1FF3FDC
+:10C1E00011D0042392FBF3F3984505DA284640F278
+:10C1F000D7414022002304E04022284640F2D741A4
+:10C200001346F6F7C9FAD5F8FC3F53B12846FDF7B7
+:10C2100079FC0520EAF3A0F21C492846702200238D
+:10C2200002E01A4928467022FDF7F0F82846394600
+:10C23000FEF794FB002601212846FBF76FFD04233F
+:10C24000C8EB00047A1E94FBF3F3D2187F2AA8BF30
+:10C250007F2222EAE277284639460434FEF77EFB45
+:10C26000082C03D90A2E01D00136E4E72846FDF751
+:10C2700049FC284640F2D7414A46F6F767FA284675
+:10C28000F8F726FE40B2BDE8F087C04600093D0041
+:10C290002DE9F04391B08046D0F8A860F8F718FE79
+:10C2A0001C23B8F8DA208DF83B3001238DF83A30A2
+:10C2B00002F47043B3F5805F5FFA80F907D1D3B21F
+:10C2C000402B01D81B2300E02D238DF83B30B8F81C
+:10C2D000DA2002F47043B3F5005F33D1B6F82A25B3
+:10C2E00013B2B3F1FF3F04D04FF6FF73002A08BF2B
+:10C2F0001A46B6F8F6130BB2B3F1FF3F02D14FF472
+:10C30000917104E04FF6FF73002908BF1946B6F893
+:10C310002C5596F8F0032BB2B3F1FF3F04D04FF643
+:10C32000FF73002D08BF1D46B6F8F84323B2B3F1E2
+:10C33000FF3F04D04FF6FF73002C08BF1C4696F851
+:10C34000F1739FE0D3B2402B33D8B6F82E2513B249
+:10C35000B3F1FF3F04D04FF6FF73002A08BF1A461F
+:10C36000B6F8FA130BB2B3F1FF3F02D14FF491715B
+:10C3700004E04FF6FF73002908BF1946B6F83055A0
+:10C3800096F859052BB2B3F1FF3F04D04FF6FF7377
+:10C39000002D08BF1D46B6F8004423B2B3F1FF3F9D
+:10C3A00004D04FF6FF73002C08BF1C4696F85B754F
+:10C3B00068E08C2B33D8B6F8322513B2B3F1FF3FC7
+:10C3C00004D04FF6FF73002A08BF1A46B6F8FC13D4
+:10C3D0000BB2B3F1FF3F02D14FF4917104E04FF67D
+:10C3E000FF73002908BF1946B6F8345596F8F203D2
+:10C3F0002BB2B3F1FF3F04D04FF6FF73002D08BFFF
+:10C400001D46B6F8024423B2B3F1FF3F04D04FF605
+:10C41000FF73002C08BF1C4696F8F37332E0B6F8A1
+:10C42000362513B2B3F1FF3F04D04FF6FF73002A55
+:10C4300008BF1A46B6F8FE130BB2B3F1FF3F02D1A4
+:10C440004FF4917104E04FF6FF73002908BF1946BD
+:10C45000B6F8385596F85A052BB2B3F1FF3F04D021
+:10C460004FF6FF73002D08BF1D46B6F8044423B2F3
+:10C47000B3F1FF3F04D04FF6FF73002C08BF1C46FA
+:10C4800096F85C7513B2B3F1FF3F04D040461946ED
+:10C49000FFF792FE0DE009B2B1F1FF3F07D0404631
+:10C4A0000DF13202FFF728F89DF83B3007E0FF2836
+:10C4B00002D086F8070404E09DF83B300BB186F803
+:10C4C000073429B2B1F1FF3F05D04046FFF774FEB3
+:10C4D00086F8080411E021B2B1F1FF3F09D04046CF
+:10C4E0000DF13202FFF708F89DF83B3086F808346A
+:10C4F00003E0FF2F18BF86F8087496F9EF33B3F105
+:10C50000FF3F1CBF4FF0FF3386F8083496F808044D
+:10C5100041B2B1F1FF3F76D096F8072453B2994269
+:10C52000D8BF86F8082496F80834D8BF86F80704E0
+:10C5300000248DF83B30DB2301250393404623463E
+:10C5400021460DF132020495009401940294059461
+:10C55000FEF72CFD18230993083308950B93254605
+:10C5600007AC0FAB4046214607930A95FBF752FEF6
+:10C5700005F140034046214601350A93FCF74CF98A
+:10C58000402DEDD196F9072496F908349B18022224
+:10C5900093FBF2F3A6F86835B8F8DA2002F470439A
+:10C5A000B3F5005F02D1B6F85E3583B9D3B2402B44
+:10C5B00005D8B6F8602512B1A6F8682509E08C2BDD
+:10C5C00002D8B6F8623513B9B6F864350BB1A6F8DF
+:10C5D0006835404640F224514FF400420023F6F7FC
+:10C5E000DBF896F96625B6F86835013293FBF2F36D
+:10C5F0009BB2404640F22551FF22F6F7CDF80223C8
+:10C6000086F8673529E0012386F86735404640F211
+:10C610002551FF227E33F6F7BFF8404640F2255100
+:10C620004FF480720023F6F7B7F8404640F22551E8
+:10C630004FF400720023F6F7AFF8404640F2255160
+:10C640004FF480620023F6F7A7F8404640F22551E8
+:10C650004FF400620023F6F79FF84FF00003A6F8AE
+:10C660006A35404640F2255196F96645F6F762F87C
+:10C670000134C0B204FB00F496F96635A6F86845AB
+:10C6800013B14046FCF72CFD96F8EF330DF1320262
+:10C69000FF2B08BF96F8073400218DF83B30DB23D1
+:10C6A00003930123049340460B46009101910291AC
+:10C6B0000591FEF77BFC40464946FEF74FF94046A0
+:10C6C00040F27161F6F736F8B6F96A3540F27161F9
+:10C6D000A0EBC30292B24046F6F738F84046FBF7AB
+:10C6E00093FE11B0BDE8F08370B58E46BEF1FF3FFA
+:10C6F0000546144619469DF9106002D006EB0E015E
+:10C700000DE022B990F82916FFF756FD02E0B2F1CC
+:10C71000FF3F04D021462846FFF74EFD81192846E9
+:10C72000FEF71CF970BDC0462DE9F04F87B00446F6
+:10C73000F8F7F4FB04A981462046D4F8A850F8F78E
+:10C740003BFB2046F8F7BCFB40F2D741834620462E
+:10C75000F5F7F0FF03902046FCF74AF88246B9F15E
+:10C76000000F02D0FF23029304E02046F8F7B0FB4D
+:10C7700040B20290B4F8DA304FF02A0803F4704364
+:10C78000B3F5005F0CBF95F81E1595F81F152046F0
+:10C790004FB239460F223C23CDF80080FFF7A4FFAB
+:10C7A00095F84665002E00F09080204640F2EB415F
+:10C7B000F5F7C0FF1221C0F3402301222046F5F710
+:10C7C0008DFF6A780021521A18BF01220B462046BD
+:10C7D000FFF7F2F92046FBF791FE40F3072340B242
+:10C7E000A5F84A35A5F84C0540F2EB412046F5F78F
+:10C7F000A1FFC0F380235B02204640F2EB414FF4DF
+:10C800000072F5F7C9FF002107220B462046FFF70B
+:10C81000D3F92046FBF772FE40F3072340B2A5F898
+:10C820004E35A5F85005FF222046B5F84A3540F6AA
+:10C830005211F5F7B1FF2046FF22B5F84C3540F60E
+:10C840005311F5F7A9FF2046FF22B5F84A3540F607
+:10C850005611F5F7A1FF2046FF22B5F84C3540F6FA
+:10C860005711F5F799FF2046FF22B5F84E3540F6EF
+:10C870004811F5F791FFFF222046B5F8503540F6F4
+:10C880004911F5F789FF95F84A3595F84C1520467A
+:10C8900041EA0321FCF764FF95F8473520469B02E7
+:10C8A00040F2EB414FF4806203F47C43F5F774FFF0
+:10C8B00095F8483520465B0240F2EB414FF4007298
+:10C8C00003F47E43F5F768FF10E0204639460F2257
+:10C8D0003C23CDF80080FFF707FF6A7820463146F9
+:10C8E000003A18BF01223346FFF766F92046F8F7F1
+:10C8F0004BF810B12046FBF715FE00217F220B46B6
+:10C900002046FCF7DDFC20465146FDF7C7FD2046DA
+:10C910005946F8F7CFFB204604A9F8F717FC204644
+:10C9200040F2D741039AF5F711FFB9F1000F04D097
+:10C9300020464946FDF7C0FB03E020460299FEF77A
+:10C940000DF807B0BDE8F08F2DE9F04F89B004462F
+:10C95000D0F8A870F8F7E2FA04902046F8F7B8FA91
+:10C960004FF489715FFA80FA2046F5F759FE0721E6
+:10C9700005902046F5F754FEFF2101902046F5F77B
+:10C980004FFE40F21F1102902046F5F749FE40F29B
+:10C99000AB4103902046F5F7CDFED4F8B030D3F884
+:10C9A000203183F0010313F0010B03D1E36918690F
+:10C9B00033F0F0DE00212046FDF77EFB2046F6F73F
+:10C9C00077FB40F23B412046F5F7B4FE0DF1180924
+:10C9D000494680462046F8F7EFF920460121F8F74E
+:10C9E0007DFB20467F21FDF7B9FF0122134620463B
+:10C9F0000721F5F773FE102213462046FF21F5F7B5
+:10CA00006DFE0422134640F21F112046F5F766FE24
+:10CA10002046FDF74FFC06224B492046F5F7D0FE95
+:10CA20002046FBF7E5FE002106462046FDF736FDD1
+:10CA3000002220460121F7F745FA40F2AB4120469B
+:10CA4000F5F778FE40F23E612046F5F773FEC50526
+:10CA5000ED0D2B46204640F2A64140F2FF12F5F7BD
+:10CA60009BFE97F8E8330BB3204638490922F5F7C7
+:10CA7000A7FE002220460121F7F724FA40F2AB413D
+:10CA80002046F5F757FE40F23E612046F5F752FE8C
+:10CA9000C30540F29A41204640F2FF12DB0DF5F744
+:10CAA0007BFE20462A490922F5F78AFE2B462046BE
+:10CAB00040F2A64140F2FF12F5F76EFE00234FF45C
+:10CAC0008052204640F24C41F5F766FE2046314642
+:10CAD000FDF7E4FC2046C8F38011F8F7FFFA204682
+:10CAE0004946F8F733FB20465146FDF737FF20460D
+:10CAF0000499FDF7E1FA20464FF48971059AF5F79C
+:10CB0000A7FD019D012205EA020320460721F5F752
+:10CB1000E5FD029D102205EA02032046FF21F5F7FC
+:10CB2000DDFD039D0422204640F21F1105EA0203A9
+:10CB3000F5F7D4FDBBF1000F03D1E369186933F0B9
+:10CB400015DE09B0BDE8F08FD80C0200E205020046
+:10CB5000E40C02002DE9F3410446F8F7DFF9E3693C
+:10CB6000D4F8A8501A6A04F580531A6094F8DA30A1
+:10CB7000002685F8BC3241F20403E654D4F8B03004
+:10CB80008046D3F8203183F0010313F001070AD166
+:10CB9000E369B821186942F2107233F0C9DDE36924
+:10CBA000186933F0F7DD20460121F9F7B1FE0F22B5
+:10CBB00023492046F5F704FE2046F8F775FD204688
+:10CBC0003146FCF7CDFD204631463246FDF736F8BA
+:10CBD0002046F6F76DFA41F22403E35C6BB1204680
+:10CBE000FFF7B2FE20463146FDF74EF995F8E833DF
+:10CBF0001BB120460121FDF747F92046FFF794FDC0
+:10CC000000217F230A46009320460123FDF7C6FF3B
+:10CC10004FF0FF3385F8073485F808342046FFF7D6
+:10CC200037FB20464146FDF747FA20460021F9F739
+:10CC30006FFE1FB9E369186933F098DDBDE8FC8128
+:10CC4000DA070200082910B503D00A2904D0022906
+:10CC500004D1FFF77FFF01E0FEF794FD10BDC04651
+:10CC600010B50446F6F724FA20460021FDF724FA11
+:10CC700020460821FFF7E6FF10BDC04670B541F21F
+:10CC80000403C35C0446D0F8A85013B9F7F70CFFAF
+:10CC9000F0B1D4F8F83013F0070F06D194F8F5305E
+:10CCA0001BB920460921FFF7CDFFD4F8F82012F078
+:10CCB0000F0F0DD141F20C03E3564BB912F0800F68
+:10CCC00006D194F8F5301BB920460221FFF7BAFFD0
+:10CCD000D4F8F83013F00E0F02D12046F9F752F9CC
+:10CCE000D4F8F83013F0060F3ED1D5F8340448B329
+:10CCF000E169D5F838240B6A9B1A834234D308695A
+:10CD00006A2133F0F7DC400081B2B1B1E369186900
+:10CD100033F0F0DC88B940F276412046F5F70AFDA1
+:10CD2000C005C00DA5F86C0540F277412046F5F727
+:10CD300001FDC005C00DA5F86E0520460021F9F7DC
+:10CD40004BFF11E040F276412046F5F7F3FCC005B9
+:10CD5000C00DA5F86C0540F277412046F5F7EAFCD6
+:10CD6000C005C00DA5F86E052046F8F7D7F8B0F558
+:10CD7000404F0CD02046F8F7ABF8C0B220B10023EA
+:10CD80007F2885F8563402D0002385F8573470BDCB
+:10CD90002DE9F047CCB20746D0F8A8602046894676
+:10CDA000F5F7DEFE494680463846F5F7BBFE3846C5
+:10CDB000B7F8DA10FBF758F9042238465B49F5F763
+:10CDC000FFFC21463846FAF7B5F90A20E9F3C4F426
+:10CDD0004FF4004213464FF489613846F5F7DCFC06
+:10CDE0003846F8F78DFB052100224FEA4800F7F797
+:10CDF000B1FC0022054641464FF42010F7F7AAFC8B
+:10CE000040F257610446AAB23846F5F79FFC38460F
+:10CE10004FF4CB61A2B2F5F799FC4FF4007338469A
+:10CE20004FF489614FF44072F5F7B6FC97F8DA30A9
+:10CE30000E2B01D11E2206E0B6F8622013B2B3F128
+:10CE4000FF3F08BF1522A6F840253846002112B240
+:10CE5000FBF7E2FB20B1384600211422FBF7DCFB94
+:10CE600097F8DA3038220E2B0CBF182300233846EF
+:10CE700040F2EB41F5F790FCB7F8DA30384603F4AE
+:10CE80007043B3F5005F0CBFB6F86620B6F86820B3
+:10CE9000012113B2B3F1FF3F08BF0222A6F83E25DD
+:10CEA00012B2FBF7B9FB182238462149F5F788FC86
+:10CEB0003846F6F70DF996F8BC2298B10E2AB7F865
+:10CEC000DA3003D9DBB20E2B03D805E0DBB20E2B30
+:10CED00002D83846012101E0384600214A46FCF7D5
+:10CEE000A1FF21E097F8DA309A4201D1012A04D15A
+:10CEF00038460821FFF7A6FE02E03846FCF776FF29
+:10CF000000210A463846FBF753FD3846F9F7B6F9D3
+:10CF100038460121F9F76AFA41F22403FB5C1BB1A0
+:10CF200038460321FBF70AF9BDE8F08792050200B5
+:10CF30002A080200D0F8B03073B5D3F82031044687
+:10CF400083F0010313F00106D0F8A85003D1C369A0
+:10CF5000186933F01FDC41F22403E25C42BBB4F8F1
+:10CF6000DA3003F47043B3F5005F08D14FF00403E7
+:10CF7000ADF800304FF00C03ADF8023007E04FF091
+:10CF8000FF03ADF80030ADF802304FF0F00320465B
+:10CF90006946ADF80430ADF80620F8F7D7F820461A
+:10CFA0009621FDF77BFA20460121FEF7BDFC56E0F5
+:10CFB0002046FFF7C9FC2046FDF756F82046002121
+:10CFC000FCF762FF204635490F22F5F7F9FB95F88B
+:10CFD000E833DBB120460121FCF756FF95F92435F3
+:10CFE000204640F2D141FF229BB2F5F7D5FB95F8E0
+:10CFF0002535204640F2D1414FF47F421B02F5F720
+:10D00000CBFB204626490C22F5F7DAFB0522204609
+:10D010002449F5F7D5FBD4F8A8202046D2F84434AB
+:10D02000D2F848243C2BA8BF3C239342B8BF1346F8
+:10D0300040F2A741FF229BB2F5F7AEFBB4F8DA301D
+:10D04000204603F47043B3F5005F0CBF95F85434E9
+:10D0500095F855344FF440412B86FDF72DF840F2FA
+:10D0600076412046F5F766FBC005C00DA5F86C05B6
+:10D0700040F277412046F5F75DFBD5F83434C00522
+:10D08000C00DA5F86E051BB120460121F9F7A4FDDE
+:10D090001EB9E369186933F069DB7CBD4A0E0200F2
+:10D0A0002A070200100A02002DE9F041D0F8A8601A
+:10D0B000012386F86130013B86F8C033B0F8DA30DE
+:10D0C000074603F47043B3F5005F02D196F8C1330D
+:10D0D00004E0B3F5805F06D196F8C233022B02D18B
+:10D0E000012386F8C033B7F8DA30384603F47043CA
+:10D0F000B3F5805F0CBF96F8EB3396F8EA33002463
+:10D1000086F8E933738B0125A6F8BE320422234941
+:10D11000347086F8C24286F8C34286F8C44286F864
+:10D120006755F5F74DFB38462946F8F721FA0422F2
+:10D130001B493846F5F744FB3846FCF7A1FA384658
+:10D14000FCF7DCFC3846FFF7F5FE86F82C40B7F814
+:10D15000DA103846F6F784FD3846FBF765F84FF4E9
+:10D16000804213464FF489613846F5F715FB642079
+:10D17000E9F3F2F2234638464FF489614FF48042D6
+:10D18000F5F70AFB38464FF44041FCF795FF41F2B2
+:10D190008833F38686F89A55BDE8F08122070200AD
+:10D1A000040C020010B58068F2F36AF210BDC046AC
+:10D1B00010B5437902790C4642EA032E0EF00303C0
+:10D1C000012B0AD0022B0ED013B14FF400702EE0C9
+:10D1D0000A780523B2FBF3F029E00B78144A03F038
+:10D1E0000703D05C23E00978E378227911F0800FFF
+:10D1F00043EA022201F07F0343F0006002D040F4D2
+:10D20000806006E01EF0200F1CBF20F4E06343F4B2
+:10D21000407012F0800F18BF40F4000012F0400F71
+:10D2200018BF40F48000C2F3011340EA035010BD60
+:10D2300050FD010070B585680446D4F8F811A8685F
+:10D24000F2F30CF24FF0FF3384F8E231A36123686C
+:10D2500000229A712B6B064602211869F5F732FC01
+:10D26000204636F00FDDD6F1010038BF002070BD3A
+:10D2700070B50D460968044671B1D1F87C1129B129
+:10D28000036840F20C72D868E9F332F52368296824
+:10D29000D8686269E9F32CF523682946D86810221A
+:10D2A000E9F326F570BDC04637B5054601A9D0F8AB
+:10D2B000000537F00FDF09E02846214638F06AD92B
+:10D2C000636C1BB92846214638F07ADA01A837F09A
+:10D2D00009DF04460028EFD13EBDC046036870B5A3
+:10D2E00010210546D868E9F3F3F408B9064615E0BD
+:10D2F0002B6806466969D868E9F3EAF404463060A9
+:10D3000028B931462846FFF7B3FF264606E000233A
+:10D31000C0F87C313146284637F0BCDD304670BD60
+:10D320002DE9F3470D469246002853D0002951D0ED
+:10D330000B88D0F80490D0F89843D0F89463002B71
+:10D340004BD00027E780A7804B880A8813F001089C
+:10D3500024D0402A14D1043120463B4600973BF0AC
+:10D36000DBDFB8423BDBB6F8023113F0400F34D0BC
+:10D37000BAF1000F31D0D9F80C003AF06FDF0BE0B2
+:10D38000A2F108039BB2372B29D804F1080004311D
+:10D39000E4F3F2F52D88A580384622E0202A19D83A
+:10D3A000043104F14800E4F3E7F5A4F804802D8883
+:10D3B0000123E580C6F8CC30B6F8023113F0400FF7
+:10D3C0000BD0BAF1000F08D0D9F80C003AF046DFC4
+:10D3D000404606E06FF0010003E0002001E04FF05E
+:10D3E000FF30BDE8FC87C04610B50DF09DFD04463A
+:10D3F000F1F7AAFF2046E8F3BDF710BDAAAA030083
+:10D400001958000040960000904C00001472000073
+:10D41000101800000FAC000050F2000050F20100A4
+:10D420000050F20200000050F2020100AAAA03001C
+:10D43000195800000000000050F2040000147200AF
+:10D44000000FAC000050F200001018000050F20075
+:10D45000000FAC0000409600000000000000101813
+:10D4600000696C306D6163616464723D30303A31E3
+:10D47000313A32323A33333A34343A353500626F26
+:10D48000617264747970653D3078666666660062C4
+:10D490006F6172647265763D3078313000626F6121
+:10D4A0007264666C6167733D38006161303D3300C2
+:10D4B00073726F6D7265763D3200AAAA0300195827
+:10D4C000000050F200000000594D80009557800088
+:10D4D00049588000315680000D5A8000C1588000A4
+:10D4E000295A8000455A8000795780004D568000A7
+:10D4F000755A800025558000F15980000D58800034
+:10D5000069548000C14E8000E9518000555280006E
+:10D51000C9518000DD58800051518000D1558000F4
+:10D52000A555800015568000E14F80008955800088
+:10D53000FD4E800025508000C9110100ED4D800096
+:10D54000854E8000A94F8000D94D8000094E800093
+:10D55000514C8000654C800000000000000000007D
+:10D5600000000000C14F800025528000F95180006A
+:10D57000E12800002800000073645F6C6576656C2C
+:10D580005F74726967676572007370695F70755F59
+:10D59000656E6162006172705F6D61636164647287
+:10D5A000006172705F72656D6F7465697000000074
+:10D5B000F83B86000000000007000000FF3B8600EB
+:10D5C00001000000070000000B3C86000200000084
+:10D5D000000000001B3C8600030000000700000064
+:10D5E000263C86000400000000000000373C860056
+:10D5F0000500000008003000413C860006000000E5
+:10D600000000000095D501000800000006000000A1
+:10D61000A1D5010009000000070000000000000083
+:10D62000000000000000000070666E5F737573708C
+:10D63000656E640058408600000000000800140079
+:10D6400060408600010000000800880068408600F5
+:10D65000020000000800380070408600030000004F
+:10D66000080008007E408600040000000100000061
+:10D670008240860005000000000000008B4086000C
+:10D68000060000000800380028D60100070000004E
+:10D690000100000000000000000000000000000089
+:10D6A000352E39302E3139352E38392E3600776CFB
+:10D6B00025643A2025732025732076657273696F7F
+:10D6C0006E20257320465749442030312D25780A95
+:10D6D0000041707220323220323031330031343A1E
+:10D6E00035303A3030000000DA4386000000000098
+:10D6F00008000000E3438600010000000100000074
+:10D700000000000000000000000000005C782530F0
+:10D71000325800253034780A007478636861696E85
+:10D72000007278636861696E00776C635F696F7619
+:10D730006172733200727373695F6F6666736574CA
+:10D740000064796E74785F7164626D5F6F76657284
+:10D75000726964650064796E74785F726174655F84
+:10D76000616C6C00505A443A2025643E2564206F59
+:10D77000722025643E256420613D25640A006F7493
+:10D780007077006164640064656C006C6F775F7231
+:10D790007373695F74726967676572006C6F775F36
+:10D7A000727373695F6475726174696F6E0074631C
+:10D7B0005F656E61626C650074635F706572696F4E
+:10D7C000640074635F68695F776D0074635F6C6F9A
+:10D7D0005F776D0074635F73746174757300617358
+:10D7E000736F635F73746174650064796E7478003D
+:10D7F00074785F737461745F63686B0074785F73CF
+:10D800007461745F63686B5F7072640074785F73D7
+:10D810007461745F63686B5F726174696F007478C0
+:10D820005F737461745F63686B5F6E756D007278AF
+:10D830005F726174650069735F5750535F656E7204
+:10D840006F6C6C65650069735F7770735F656E728E
+:10D850006F6C6C65650002000000000035D70100A8
+:10D8600001000000060000008BD70100020000004C
+:10D87000060000009CD70100030000000600000025
+:10D88000AED701000400000006000000B8D7010078
+:10D890000500000006000000C2D7010006000000DD
+:10D8A00006000000CBD701000700000006000000C2
+:10D8B000D4D701000800000006000000DED70100F8
+:10D8C0000900000006000000EAD701000A0000007D
+:10D8D00006000000F0D701000B0000000600000069
+:10D8E000FCD701000C000000060000000CD801006D
+:10D8F0000D000000060000001ED801000E00000010
+:10D90000060000002ED801000F00000006000000F5
+:10D9100036D80100100000000100000046D80100C8
+:10D9200010000000010000000000000000000000E6
+:10D930000000000005A58100FDA581000000000099
+:10D94000000000000DCD820089E68200F5CB820048
+:10D95000EDCC820067898600000080000100000095
+:10D96000458B860001000000080002004F8B8600F6
+:10D970001D000000080002005C8B86000F00000004
+:10D98000030000006A8B8600100080000700000082
+:10D990007A8B860002000000080007008B8B86004F
+:10D9A00003000000080007009C8B86000400800034
+:10D9B00001000000AE8B860006000000020000009F
+:10D9C000B98B86000C00000002000000C88B8600A6
+:10D9D00021008000030000000000000000000000A3
+:10D9E000000000004CDB01001000000006000000F9
+:10D9F000529B860001000000010000005D9B860034
+:10DA000002002000070000006F9B8600030040001A
+:10DA1000080007007C9B860004004000080004000A
+:10DA20008B9B860005004000080004009A9B86003E
+:10DA300006000000080004004FDB01000D0010008C
+:10DA400007000000A79B86000E00200007000000D2
+:10DA5000B49B86000700100007000000BF9B8600F3
+:10DA6000080000000800100058DB01000900000059
+:10DA700006000000C99B860024000000060000008C
+:10DA80005CDB01000A00000006000000AB728600AB
+:10DA90000F00000001000000D59B86000B008000F5
+:10DAA00001000000DA9B86000C0000000500000069
+:10DAB000E59B86001D00000003000000FA9B860025
+:10DAC0001E00000007000000139C86001F000000DD
+:10DAD00007000000259C86002100000005000000D2
+:10DAE0003B9C86002000000003000000499C86004B
+:10DAF00011008000010000004F9C860018004000CB
+:10DB000008000600539C8600190000000500000074
+:10DB1000619C86001A000000010000006C9C8600D9
+:10DB20001B00400001000000000000000000000099
+:10DB3000000000000050F20201010000013200006C
+:10DB400027A4000041325E0061212F006170006D4A
+:10DB500061786173736F63006273730073736964D8
+:10DB600000092F160E0E057573696E6720703270EE
+:10DB7000206D6963726F636F64650A00776C25645A
+:10DB80003A205048595458206572726F72282564A3
+:10DB9000290A000091BA8600000080000100000000
+:10DBA00030BB860002000000080044003ABB86003B
+:10DBB000030000000800440044BB8600040000008D
+:10DBC000080000004FBB860005000000080044006C
+:10DBD00059BB8600060000000800000067BB8600F5
+:10DBE0000700000008004C0074BB8600080000001D
+:10DBF00008004C0081BB8600090080000200000084
+:10DC000000000000000000000000000054545454C4
+:10DC10005400000000000000000050505050500020
+:10DC200000000000000000002300000003000000CE
+:10DC300000084C4C4C4C4C4C1414140000010000D7
+:10DC400064646464646464646464646464000000C0
+:10DC5000000000000000000000000000013C424203
+:10DC6000424242424242423C0000000000000000AA
+:10DC700000000000000000000000344A4E4E4E4EEE
+:10DC80004E4E4E4A38000000000000000000000028
+:10DC9000000000000000004C4C4C4C4C4C4C4C4CD8
+:10DCA0004C4C4C4C00000040404040404040000084
+:10DCB00000000001030000000001424242324242E3
+:10DCC0001414140000000000030000000008444485
+:10DCD0004438444414141400000000000300000001
+:10DCE00000013E3E42343E42141414000000000085
+:10DCF00054545400540000000000000000000000D4
+:10DD000000000000000000000000000023000000F0
+:10DD1000030000000001444444384440141414003B
+:10DD200000000000484A4A4A4A4A4A4A4A4A4A4A7D
+:10DD300048000000343434343434343434000000C7
+:10DD4000004E4E4E4E4E4E4E4E4E4E4E4E4E0000DD
+:10DD50000000000000000000000000000008545413
+:10DD6000540054000000000000000000505050001B
+:10DD700050000000000000000000233A3E3800423E
+:10DD80000000000000000000000000000000000093
+:10DD9000000000000000000A000000006400000015
+:10DDA000000000000000000000005800000000001B
+:10DDB00000000000013242424242424242424232AC
+:10DDC00042420000000000000000000000000000CF
+:10DDD000000836444444444444444444364A4000E1
+:10DDE0000000000000000000000000000000082EFD
+:10DDF0004444444444444444442E463A0000000011
+:10DE00000000000000000000000000083C3E3E3E14
+:10DE10003E3E3E3E3E3E3C3E3E00000000000000D6
+:10DE2000000000000000000008344444444444441E
+:10DE3000444444384440000000000000000000005A
+:10DE40000000000000085C5C5C5C5C5C5C5C5C5C32
+:10DE50005C5C5C00005050505050505050500000DE
+:10DE6000000001383E383E42000000000000000083
+:10DE70000000000000000000000000000000000A98
+:10DE80000100000000014E4E4E344C381E1E1E0094
+:10DE90000000000003000000000142444230443012
+:10DEA00014141400000000000300000000013E3EB6
+:10DEB0003E3C3E3E1414140000000000030000002D
+:10DEC0000001444444364C3814141400000000008F
+:10DED0000300000000013E3E30363A2C14141400BA
+:10DEE000000000004242424242424242424242421A
+:10DEF000420000002E343434343434343400000012
+:10DF0000004A4A4A4A4A4A4A4A4A4A4A4A4A00004F
+:10DF1000002E34343434343434340000000054548B
+:10DF20005400540000000000000000004848480071
+:10DF300048000000000000000000233E3E3E4A0072
+:10DF40000000000000000000002828284000000019
+:10DF500000000000000000004644444A00000000A9
+:10DF600000000000000000000000000000000000B1
+:10DF7000000000000A545454005400000000000047
+:10DF80000000004848480048000000000000000071
+:10DF900000230000030000000000424242424242CF
+:10DFA00014141400000000000300000000003E3EB6
+:10DFB0003E3E3E3E141414000000000054545454DD
+:10DFC0000000000000000000000050505050000011
+:10DFD0000000000000000000233844444A4A0000CA
+:10DFE0000000000000000000000000000000000031
+:10DFF00000000000000A00000000340000000000E3
+:10E0000000000000000000003400000000000000DC
+:10E01000000000545454545400000000000000005C
+:10E020000048484848480000000000000000002365
+:10E03000545454545400000000000000000050509C
+:10E04000505050000000000000000000235C5C5CA9
+:10E050000050000000000000000000504850004444
+:10E06000000000000000000000234C4C4C4C4C4CC5
+:10E070004C4C4C4C4C4C4C0000000000000000008C
+:10E0800000000000000009000100000000013E3E09
+:10E090003E323E361414140000000000010000005F
+:10E0A00000013E3E3E343E381414140000000000CF
+:10E0B0000100000000014242423C423C1E1E1E0084
+:10E0C000000000000100000000014E4E4E364C38AA
+:10E0D0001E1E1E0000000000545454545400000042
+:10E0E00000000000000048484848480000000000C8
+:10E0F0000000000023000000006400000000000099
+:10E1000000000000000000580000000000000000B7
+:10E1100000010000030000000000464646484A484F
+:10E120001717170000000000610A86007E0A8600AB
+:10E130009B0A86000F0B8600490B8600660B860043
+:10E14000630F8600240E8600410E860014108600A0
+:10E150006B108600311086009C108600D01086005F
+:10E160000411860060118600B1118600830B8600C1
+:10E17000A00B86000C0F8600F70B8600CE118600E0
+:10E18000310C86006B0C860094118600DA0B860039
+:10E190005E0E86004E0C8600290F8600B80A8600A7
+:10E1A000D50A8600F20A86007B0E86004E10860095
+:10E1B000BD0B8600980E86009D0F8600B50E86006A
+:10E1C000880C8600D20E8600140C8600290F86006B
+:10E1D000BA0F86002C0B8600440A8600800F86004A
+:10E1E000460F8600EF0E8600B5DD0100D2DD01008E
+:10E1F000EFDD01005DDC010024DD01000CDE01002B
+:10E2000001DF010046DE010097DC01006AE0010049
+:10E2100040DC01007ADC010041DD010029DE010063
+:10E22000E4DE010021E3010004E30100383838385E
+:10E2300038000000000000000000343434343400A2
+:10E240000000000000000000003A3A3A3A460000A0
+:10E2500000000000000000000000000000000000BE
+:10E26000000000000008384444444A000000000058
+:10E27000000000000000000000000000000000009E
+:10E2800000002A0000000054000000000000000010
+:10E290000000000000440000000000000000000139
+:10E2A00018098600C00D8600E80D8600200D860046
+:10E2B000AC0D8600DCDC01009CE00100C8E301003D
+:10E2C000A8DF010088E0010094DF0100B4DC010058
+:10E2D00010DD010094DE0100B0E0010014E1010056
+:10E2E000A8DE0100FCE3010080DE010078E301000C
+:10E2F00010E40100C4E00100BCDE0100D0DE01003A
+:10E30000C8DC010038444444444444444444384450
+:10E31000440000002C3838383838303434000000DD
+:10E3200000343A3A3A3A3A3A3A3A3A3A2C2C00001D
+:10E3300000323C3C3C3C3C000000000000003E48F9
+:10E3400048424600000000000000000000000000FD
+:10E35000000000000000000000000A0038383E42C3
+:10E3600000000000000000000000000000000000AD
+:10E37000000000000000000A030000000000444408
+:10E38000444C4C4C17171700000000003232323852
+:10E39000000000000000000000003838383800009D
+:10E3A0000000000000000000004C0000004C0000D5
+:10E3B00000000000000000500000005000000000BD
+:10E3C00000000000000100000300000000004242C5
+:10E3D00042424242171717000000000054545400F4
+:10E3E000000000000000000000005050500000003D
+:10E3F00000000000000000002300000003000000F7
+:10E400000001444444344444141414000000000047
+:10E410000300000000006464646464642424240035
+:10E42000000100003CE486000000800001000000C4
+:10E4300084E5860001000000080024008DE58600C8
+:10E44000020000000100000096E5860003000000C5
+:10E45000030000009EE586000400000008000000A4
+:10E46000A7E586000500000008000200B1E586006F
+:10E470000600000008000800BBE586000700000059
+:10E4800008000600C5E58600080000000800060038
+:10E49000CCE586000900000008000200D4E58600F3
+:10E4A0000A00000008000300DCE586000B00000005
+:10E4B00007000000E9E586000C00000008000600E7
+:10E4C000EDE401000D00000008000700F7E4010082
+:10E4D0000E0000000100000000000000000000002D
+:10E4E000000000006368616E7370656300703270D5
+:10E4F0005F6966757064007032705F646566696537
+:10E5000000000000C8E686000000000008000C00C3
+:10E51000D7E686000100000007000400E9E6860057
+:10E520000200000008000800FBE68600030000006F
+:10E53000070004000BE786000400000008001C0030
+:10E540001BE786000500000008000C002CE7860091
+:10E55000060000000700040043E7860007000000F3
+:10E560000700040094E50100080000000700040013
+:10E57000A4E501000900000007000400B8E501005F
+:10E580000A000000080090000000000000000000E9
+:10E5900000000000706B745F66696C7465725F697F
+:10E5A000636D7000706B745F66696C7465725F692F
+:10E5B000636D705F636E740077616B655F7061633C
+:10E5C0006B6574005365742042525054206174206E
+:10E5D00025780A000A465749442030312D25780A0B
+:10E5E000000A54524150202578282578293A207075
+:10E5F000632025782C206C722025782C20737020C5
+:10E6000025782C207073722025782C2078707372F6
+:10E610002025780A00202072302025782C207231A5
+:10E620002025782C2072322025782C20723320254A
+:10E63000782C2072342025782C2072352025782CD7
+:10E640002072362025780A00202072372025782C69
+:10E650002072382025782C2072392025782C2072C1
+:10E6600031302025782C207231312025782C2072F1
+:10E6700031322025780A000A20202073702B3020A8
+:10E6800025303878202530387820253038782025F6
+:10E690003038780A00202073702B31302025303834
+:10E6A0007820253038782025303878202530387883
+:10E6B0000A0073702B257820253038780A006465AD
+:10E6C00061646D616E5F746F007265636C61696D2A
+:10E6D0002073656374696F6E20313A2052657475DA
+:10E6E000726E656420256420627974657320746F8E
+:10E6F0002074686520686561700A007265636C61EA
+:10E70000696D2073656374696F6E20303A205265BD
+:10E710007475726E65642025642062797465732057
+:10E72000746F2074686520686561700A0072616D9D
+:10E730007374627964697300706125643D30782573
+:10E74000257800706425643D3078252578006E7644
+:10E7500072616D5F6F7665727269646500000000BA
+:10E7600086060200D0090000800602003E3E00003E
+:10E77000820602003E020000000702003C0000008A
+:10E780008406020012020000600104000300010080
+:10E7900064010200C00000006001040003000100E9
+:10E7A000660102000A00000060010400040001008C
+:10E7B0006401020014000000600104000700010071
+:10E7C00064010200830100006001040025000100D3
+:10E7D00064010200F40100006001040096050100DC
+:10E7E000660102002B04000060010400970501008F
+:10E7F000640102000001000060010400D701010073
+:10E80000640102003C00000060010400DC01010022
+:10E81000660102003400000060010400E201010012
+:10E82000640102003000000060010400E701010003
+:10E83000660102002C00000060010400ED010100EF
+:10E84000640102002C00000060010400F2010100DC
+:10E85000660102002800000060010400F8010100C8
+:10E86000640102002800000060010400FD010100B5
+:10E870006601020028000000FFFF00000000000009
+:10E880006001040005000103640104000000190098
+:10E89000240104000400000028010400000000001E
+:10E8A0002C01040000000000300104000000000002
+:10E8B000340104000A04700034010400EFBED400E7
+:10E8C00034010400050000FF3401040001FF02FFD1
+:10E8D0003001040018000000340104000A04E000C4
+:10E8E00034010400EFBE480034010400050000FFBD
+:10E8F0003401040001FF02FF34010400001018017C
+:10E9000034010400020300103401040018F1F2F392
+:10E9100034010400BBCC0000300104006806000094
+:10E92000340104001404700034010400EFBE5801E7
+:10E9300034010400000000FF3401040001FF02FF65
+:10E94000340104000010180134010400020303091B
+:10E9500034010400BF000010340104000000000076
+:10E960003001040038000000340104000000000001
+:10E970003001040088060000340104001404800003
+:10E9800034010400EFBE1802340104000000030942
+:10E9900034010400BF00000334010400000102033D
+:10E9A00034010400040500013401040002030405DD
+:10E9B0003401040000000000300104005800000091
+:10E9C00034010400000000003001040038000000A1
+:10E9D000340104000F2000073401040000009400FB
+:10E9E000340104000000009034010400747576774F
+:10E9F00034010400000000003401040000000500A0
+:10EA000034010400FFFFFFFF300104006802000032
+:10EA1000340104006E84330034010400DCBA500079
+:10EA200034010400D40000AB34010400BADABADACD
+:10EA300034010400001018F134010400F2F3001056
+:10EA40003401040018F1F2F3340104001000000056
+:10EA500034010400000000003401040000000A003A
+:10EA6000340104000100000E340104004252434D01
+:10EA7000340104005F54455334010400545F535380
+:10EA800034010400494401043401040082848B965B
+:10EA900034010400030101063401040002000000F7
+:10EAA0003001040068000000340104000A04280258
+:10EAB00034010400DCBA8000340104000000FFFFD0
+:10EAC00034010400FFFFFFFF34010400001018F1BF
+:10EAD00034010400F2F300103401040018F1F2F3E1
+:10EAE00034010400D0AF0000340104000000000035
+:10EAF0003401040000000001340104000200000E93
+:10EB0000340104004252434D340104005F54455324
+:10EB100034010400545F5353340104004944010498
+:10EB20003401040082848B96340104000301010641
+:10EB300034010400020100003001040068040000F8
+:10EB4000340104000A04280234010400DCBA800005
+:10EB5000340104000000FFFF34010400FFFFFFFF49
+:10EB600034010400001018F134010400F2F3001025
+:10EB70003401040018F1F2F334010400D0AF0000B6
+:10EB80003401040000000000340104000000000112
+:10EB9000340104000200000E340104004252434DCF
+:10EBA000340104005F54455334010400545F53534F
+:10EBB00034010400494401043401040082848B962A
+:10EBC00034010400030101063401040002010000C5
+:10EBD0000001040000000001900402000000000099
+:10EBE000A0040200F1F30000B0040200EFFD0000F9
+:10EBF000A8040200FFFF0000A804020000000000BB
+:10EC0000AA04020000000000A4040200CF1A0000C1
+:10EC1000AC04020000000000BC0402000000000080
+:10EC2000A6040200D7020000B6040200FFFD0000A7
+:10EC3000AE040200FFFF0000060402000100000015
+:10EC400006040200000000000C040200180000008E
+:10EC5000060402000000000048040200000C00004E
+:10EC600002040200A00700000205020000000000EC
+:10EC70000005020000400000020502000400000040
+:10EC8000000502000040000002050200080000002C
+:10EC90000005020000400000020502000C00000018
+:10ECA000000502000040000002050200C000000054
+:10ECB00080050200FFFF000082050200FFFF000048
+:10ECC00084050200FFFF000086050200FFFF000030
+:10ECD00088050200FFFF00009C050200F0FF000015
+:10ECE000400502000080000020050200060F000021
+:10ECF0004005020000800000400502000081000085
+:10ED000020050200101D00004005020000810000E7
+:10ED10004005020000820000200502001E280000BD
+:10ED20004005020000820000400502000083000050
+:10ED30002005020029310000400502000083000088
+:10ED4000400502000084000020050200323F000060
+:10ED5000400502000084000040050200008500001C
+:10ED6000200502004041000040050200008500002F
+:10ED700012060200010000002E060200CDCC0000A9
+:10ED8000300602000C0000000006020004800000B3
+:10ED900096060200080000009A060200E400000047
+:10EDA00088060200000000009C060200020000002D
+:10EDB00088060200001000009C060200020000000D
+:10EDC00088060200002000009C06020002000000ED
+:10EDD00088060200003000009C06020002000000CD
+:10EDE000880602000B0F00009E06020007000000CC
+:10EDF000100502000B00000050040200014E00004C
+:10EE0000520402005B010000E404020090000000D4
+:10EE100004040200B400000054050200FF3F00009B
+:10EE2000600104000400010364010400000000000C
+:10EE300064010400B40000006401040047004700BE
+:10EE40006401040000006400640104003009400013
+:10EE5000600104000D0001036401040002000200CF
+:10EE6000640104000100800064010400050000004A
+:10EE70006401040000008000640104006400640078
+:10EE8000640104000E004700640104000005000056
+:10EE90006001040015000103640104000000420841
+:10EEA00064010400E00B0700640104000A00000094
+:10EEB000600104001A0001036401040000C0660B35
+:10EEC000600104001D00010364010400102700001C
+:10EED0006401040000007A036001040020000103C3
+:10EEE00064010400060010276001040023000103F0
+:10EEF000640104000000F606640104000000AA0A90
+:10EF00006401040000003200640104000A0E0B09D1
+:10EF1000640104000E020000640104000000520AB3
+:10EF20006401040000003F0164010400FFFF000CC5
+:10EF30006401040032046E06640104000200F20958
+:10EF4000600104002E000103640104000000008041
+:10EF50006001040032000103640104000000320B70
+:10EF60006001040034000103640104000000CC05CA
+:10EF70006001040058000103640104004252434D43
+:10EF8000640104005F54455364010400545F53530B
+:10EF900064010400494400006001040060000103B2
+:10EFA0006401040039000000640104005000000006
+:10EFB00064010400C000000060010400700001034F
+:10EFC00064010400AA03AA0364010400AA03AA03BB
+:10EFD00064010400AA03AA0364010400AA03AA03AB
+:10EFE00064010400EC03D60364010400C003AA0317
+:10EFF00064010400F703E10364010400CB03B503DB
+:10F0000064010400AA03AA0364010400AA03AA037A
+:10F0100064010400AA03AA0364010400AA03AA036A
+:10F0200064010400EC03D60364010400C003AA03D6
+:10F0300064010400F703E10364010400CB03B5039A
+:10F0400064010400020402046401040002040204D6
+:10F05000640104000E0402046401040002041A04A2
+:10F0600064010400020402046401040002040204B6
+:10F070006401040002040204640104002604020482
+:10F080006401040002040204640104000204020496
+:10F09000640104000E0402046401040002041A0462
+:10F0A0006401040002040204640104000204020476
+:10F0B0006401040002040204640104002604020442
+:10F0C0006401040000001F0064010400FF031F002E
+:10F0D000640104000200000064010400020000005A
+:10F0E00060010400980001036401040000001F0097
+:10F0F00064010400FF031F0064010400010000001C
+:10F10000640104000100000060010400A00001038C
+:10F110006401040000001F0064010400FF031F00DD
+:10F12000640104000100000064010400010000000B
+:10F1300060010400A80001036401040000001F0036
+:10F1400064010400FF031F006401040001000000CB
+:10F15000640104000100000060010400B800010324
+:10F1600064010400E700EC006401040000007B007F
+:10F17000640104007E00000064010400000000003F
+:10F180006401040000004F51640104003F000000CE
+:10F19000640104000000001060010400C0000103CD
+:10F1A0006401040037243724640104003724372421
+:10F1B0006001040093010103640104000F0040009A
+:10F1C00064010400E60600006001040097010103E9
+:10F1D000640104001A08000060010400A00101039A
+:10F1E00064010400FFFFFFFF64010400FFFFFFFF55
+:10F1F00064010400FFFFFFFF64010400FFFFFFFF45
+:10F2000064010400FFFFFFFF64010400FFFFFFFF34
+:10F2100064010400FFFFFFFF64010400FFFFFFFF24
+:10F2200060010400BC01010364010400000005004A
+:10F2300060010400C5010103640104000000100323
+:10F2400064010400E000FFFF640104000309BF0043
+:10F25000640104000000030964010400BF00001001
+:10F26000640104000309BF006401040000030000FE
+:10F2700060010400CD01010364010400FFFFFFFFF2
+:10F2800064010400FFFFFFFF64010400FFFFFFFFB4
+:10F2900064010400FFFFFFFF64010400FFFFFFFFA4
+:10F2A00064010400FFFFFFFF64010400FFFFFFFF94
+:10F2B00064010400FFFFFFFF640104002000CB0194
+:10F2C0006401040000005400640104000000AB0865
+:10F2D00064010400000010046401040084000200C2
+:10F2E000640104000000140064010400CF01020066
+:10F2F000640104004400000064010400AF0802003F
+:10F3000064010400100464006401040002020000AF
+:10F31000640104001000CA016401040002003C0002
+:10F32000640104000000AA08640104000200100443
+:10F330006401040054000208640104000000080095
+:10F3400064010400CE0100006401040034000000E8
+:10F3500064010400AE0800006401040010044400CD
+:10F3600064010400020A0000640104000800C901ED
+:10F370006401040002003000640104000000A908D8
+:10F380006401040002001004640104003C00021047
+:10F39000640104000000040064010400CD010000C9
+:10F3A000640104002C00000064010400AD080000AA
+:10F3B000640104001004340064010400021200001F
+:10F3C000640104000400C8016401040000002C0072
+:10F3D000640104000000A808640104000000100497
+:10F3E0006401040030000219640104000000000000
+:10F3F00064010400CC010200640104002C00000040
+:10F4000064010400AC080200640104001004300030
+:10F4100064010400021A000064010400C0000A0430
+:10F420006401040070000000640104003A010A0451
+:10F430006401040028022CC064010400F2020A04E2
+:10F440006401040000000001640104006000140471
+:10F450006401040038000000640104000201140487
+:10F460006401040014012CC064010400DE011404D2
+:10F4700064010400000080006401040022003704DD
+:10F48000640104001500000064010400DF0037047B
+:10F490006401040065002CC0640104002E013704DF
+:10F4A0006401040000002F006401040011006E8458
+:10F4B000640104000B00000064010400D4006E84A9
+:10F4C0006401040033002CC064010400FC006E845D
+:10F4D00064010400000018006401040002008A9D19
+:10F4E00064010400FB00020864010400C54EFA0038
+:10F4F00064010400020A833464010400FE00021067
+:10F50000640104006227F900640104000212421A37
+:10F5100064010400FD00021964010400B113F80045
+:10F5200064010400021A811164010400FC00021C41
+:10F5300064010400C10FFC00600104007B030103AF
+:10F540006401040007001400640104001E000000B0
+:10F55000600104008303010364010400000000F063
+:10F5600064010400C3301092640104005031802211
+:10F5700064010400C330000060010400880301033B
+:10F580006401040000001004600104008C03010306
+:10F590006401040080000000600104008E03010388
+:10F5A0006401040005000000600104000B04010375
+:10F5B0006401040000000702600104001404010358
+:10F5C000640104000100000060010400160401034E
+:10F5D000640104000C0000006001040053050103F5
+:10F5E00064010400000018006001040055050103D7
+:10F5F00064010400983A983A64010400A60E64007D
+:10F60000640104000000F40164010400050000002E
+:10F6100064010400A861A8616401040030751E0043
+:10F62000600104005D0501036401040050C3000093
+:10F63000600104005F05010364010400000014057B
+:10F640006401040050C3000060010400630501036D
+:10F6500064010400204E00006401040000000F005B
+:10F6600064010400F4010400600104006905010361
+:10F670006401040000003100640104000000030084
+:10F68000640104000100070064010400C8AF000029
+:10F690006401040088130000640104002C17FF00BB
+:10F6A00060010400700501036401040000002C01E6
+:10F6B000640104000000A00F600104007305010351
+:10F6C00064010400000003006401040000002C0138
+:10F6D00064010400C00000006401040088130000FD
+:10F6E000640104006400000064010400DC05401FA4
+:10F6F000600104007A0501036401040001000100B7
+:10F700006401040002000000600104007D050103A3
+:10F710006401040002000000640104000000409C39
+:10F7200064010400204E000064010400B80B0000D6
+:10F730006001040082050103640104000000204E02
+:10F74000640104000000050064010400DC053F00C2
+:10F7500064010400710200006401040030750000BF
+:10F76000600104008A05010364010400C409A00FBC
+:10F77000600104008D050103640104000A00D00744
+:10F78000600104008F05010364010400204E204E37
+:10F79000600104009505010364010400BE0000003F
+:10F7A00060010400B105010364010400E8030000E6
+:10F7B00060010400ED050103640104000000000085
+:10F7C00060010400F60501036401040088130000D1
+:10F7D0006001040003000200640104001F00000037
+:10F7E000600104000400020064010400FF03000043
+:10F7F0006001040005000200640104001F00000015
+:10F80000600104000600020064010400070000001B
+:10F81000600104000700020064010400040000000D
+:10F82000600104000800020064010400FFFF000002
+:10F8300060010400090002006401040000000000EF
+:10F84000600104000A0002006401040000000000DE
+:10F85000600104000B0002006401040000000000CD
+:10F86000600104000C0002006401040000000000BC
+:10F87000600104000D0002006401040000000000AB
+:10F88000600104000E00020064010400000000009A
+:10F89000600104000F000200640104000000000089
+:10F8A0006001040010000200640104001F00000059
+:10F8B0006001040011000200640104000000000067
+:10F8C0006001040012000200640104000000000056
+:10F8D0006001040013000200640104000000000045
+:10F8E0006001040015000200640104000000000033
+:10F8F0006001040016000200640104000000000022
+:10F90000FFFF000000000000636275636B5F7377A8
+:10F910006672657100000000E02E010101500000D8
+:10F9200000000000C832020101490000899DD80092
+:10F930004038030101420000AAAAAA00003C0401C9
+:10F94000013E000000008000483F05010139000031
+:10F95000D05E4200A0410601013900004992240016
+:10F96000004B07010132000000000000584D080163
+:10F9700001300000071F7C00204E0901013000000B
+:10F9800000000000A8610A0101260000666666000A
+:10F9900090650B0101240000C44EEC0030750C0191
+:10F9A000012000000000000018920D020133000049
+:10F9B000F93E560000960E020132000000000000E1
+:10F9C000409C0F02013000000000000080BB1002CC
+:10F9D00001280000000000000000000000000000FE
+:10F9E0000000000009FA0100000000000800080003
+:10F9F00008FA01000100000008000B0000000000F0
+:10FA000000000000000000006D6B6565705F616CB8
+:10FA100069766500746F655F6F6C00746F655F7306
+:10FA20007461747300746F655F73746174735F6382
+:10FA30006C65617200AAAA030000000014FA0100BC
+:10FA400000000000070000001BFA01000100000098
+:10FA500008004C0025FA0100020000000000000030
+:10FA6000000000000000000000000000D58D8600AE
+:10FA70000C00800001000000A98E86000B00000031
+:10FA800001000000B58E86000300000005000000A4
+:10FA9000C18E86000400000007000000D08E8600A2
+:10FAA00005008000010000000000000000000000D0
+:10FAB000000000005B574C414E5D636F756E742013
+:10FAC0003D2025640A000000D550830021578300A3
+:10FAD0000000000000000000627461006274616D4B
+:10FAE00070006274616D705F666C61677300627450
+:10FAF000616D705F6368616E006274616D705F312B
+:10FB0000316E5F737570706F7274006274616D70C6
+:10FB10005F6662006274616D705F73746174656CBE
+:10FB20006F6700414D502D253032782D25303278C9
+:10FB30002D253032782D253032782D253032782D14
+:10FB400025303278000000007DC5860000000000EE
+:10FB50000800240084C586000100000008000000A1
+:10FB600093C586000200000008000C00A4C58600B2
+:10FB7000030000000800E402AFC586000400000096
+:10FB800007000000C0C58600050000000800240032
+:10FB9000C9C586000600000001000000D1C586002E
+:10FBA0000700000007000000DBC586000800000019
+:10FBB0000100000049C586000900000001000000A6
+:10FBC000000000000000000000000000776C635F90
+:10FBD00061757468656E74696361746F725F646F78
+:10FBE000776E0025733A2063616C6C65640A00705F
+:10FBF000617463685F696F76617273006F747072AD
+:10FC00006177006175746800666162696400616DA6
+:10FC10007064755F727473005856000243004000B0
+:10FC2000207986000000004003000000FCFB01007A
+:10FC300007000800080000003D7D860001000880E4
+:10FC40000800000003FC0100020000400600000064
+:10FC50004FDB0100030010000700000008FC01005A
+:10FC60000400000005000000647D8600050000001F
+:10FC700008001C000EFC010006000000010000004E
+:10FC80000000000000000000000000004D84FF8321
+:10FC90004CC4001FB784FF80B184FFDFB0C40808E4
+:10FCA000FA84F7FFF9C4080001006C090200710929
+:10FCB0000300760904007B09050080090600850918
+:10FCC00007008A0908008F09090094090A009909A8
+:10FCD0000B009E090C00A3090D00A8090E00B40931
+:10FCE000CC0102000000D400000000000000000170
+:10FCF0000000000000002D00A7901A0047090E0028
+:10FD0000012007008B93030038CA01002AE5000098
+:10FD1000977200004C390000A61C0000530E000032
+:10FD20002907000095030000CA010000E50000005B
+:10FD300073000000390000001D0000006E840B00FD
+:10FD40000000D400000000000000000100000000DE
+:10FD50006030180C6C482412776C25643A20536389
+:10FD6000616E20696E2070726F67726573732C20EC
+:10FD7000736B697070696E67207478706F776572E5
+:10FD800020636F6E74726F6C0A00706F77657220FB
+:10FD900061646A210A002E6661622E0025732E6658
+:10FDA00061622E25640063636B6277323032677064
+:10FDB0006F0063636B62773230756C3267706F000F
+:10FDC0006C65676F66646D627732303267706F00A2
+:10FDD0006C65676F66646D62773230756C32677020
+:10FDE0006F006D6373627732303267706F006D63DE
+:10FDF0007362773230756C3267706F006D63736257
+:10FE00007734303267706F006C65676F66646D625F
+:10FE100077323035676C706F006C65676F66646D44
+:10FE200062773230756C35676C706F006C65676F28
+:10FE300066646D6277323035676D706F006C656730
+:10FE40006F66646D62773230756C35676D706F0008
+:10FE50006C65676F66646D62773230356768706FA6
+:10FE6000006C65676F66646D62773230756C3567FC
+:10FE700068706F006D63736277323035676C706FD6
+:10FE8000006D637362773230756C35676C706F002C
+:10FE90006D63736277343035676C706F006D6373B8
+:10FEA0006277323035676D706F006D6373627732E1
+:10FEB00030756C35676D706F006D637362773430C9
+:10FEC00035676D706F006D637362773230356768C8
+:10FED000706F006D637362773230756C3567687070
+:10FEE0006F006D637362773430356768706F006DD3
+:10FEF00063733332706F006C65676F66646D3430A6
+:10FF0000647570706F00616E7473776974636800F4
+:10FF1000616135670074737369706F733267006570
+:10FF2000787470616761696E3267007064657472BD
+:10FF3000616E6765326700747269736F3267006162
+:10FF40006E74737763746C32670074737369706F67
+:10FF50007335670065787470616761696E35670035
+:10FF60007064657472616E67653567007472697379
+:10FF70006F356700616E74737763746C35670070FA
+:10FF80006132677730613300706132677731613396
+:10FF9000006D61787032676130006D617870326732
+:10FFA00061310070613267773061300070613267B3
+:10FFB0007730613100706132677731613000706194
+:10FFC00032677731613100706132677732613000BA
+:10FFD0007061326777326131006D61787035676CBE
+:10FFE0006130006D61787035676C6131007061352A
+:10FFF000676C7730613000706135676C77306131E4
+:020000022000DC
+:1000000000706135676C7731613000706135676C05
+:100010007731613100706135676C77326130007023
+:100020006135676C77326131006D61787035676179
+:1000300030006D61787035676131007061356777C8
+:100040003061300070613567773061310070613543
+:1000500067773161300070613567773161310070E9
+:1000600061356777326130007061356777326131B1
+:10007000006D6178703567686130006D617870354A
+:100080006768613100706135676877306130007092
+:100090006135676877306131007061356768773145
+:1000A00061300070613567687731613100706135AA
+:1000B0006768773261300070613567687732613127
+:1000C000006D61787035676133006D6178703567F8
+:1000D0006C61330070613567773061330070613572
+:1000E000676C773061330070613567773161330059
+:1000F000706135676C7731613300706135677732D5
+:10010000613300706135676C773261330062773438
+:1001100030706F00636464706F0073746263706F3B
+:10012000006277647570706F00747870696432670C
+:100130006130007478706964326761310069747489
+:100140003267613000697474326761310063636BD8
+:100150003267706F006F66646D3267706F006D6339
+:10016000733267706F30006D63733267706F310088
+:100170006D63733267706F32006D63733267706FD7
+:1001800033006D63733267706F34006D6373326771
+:10019000706F35006D63733267706F36006D637317
+:1001A0003267706F3700747870696435676C6130DE
+:1001B00000747870696435676C6131006F66646DD6
+:1001C00035676C706F006D637335676C706F3000EE
+:1001D0006D637335676C706F31006D637335676C79
+:1001E000706F32006D637335676C706F33006D63D1
+:1001F0007335676C706F34006D637335676C706F47
+:1002000035006D637335676C706F36006D637335E1
+:10021000676C706F3700747870696435676130009F
+:100220007478706964356761310069747435676129
+:10023000300069747435676131006F66646D3567CD
+:10024000706F006D63733567706F30006D63733569
+:1002500067706F31006D63733567706F32006D6367
+:10026000733567706F33006D63733567706F34007B
+:100270006D63733567706F35006D63733567706FCD
+:1002800036006D63733567706F370074787069641A
+:10029000356768613000747870696435676861310A
+:1002A000006F66646D356768706F006D63733567E6
+:1002B00068706F30006D6373356768706F31006D03
+:1002C0006373356768706F32006D6373356768708C
+:1002D0006F33006D6373356768706F34006D6373DF
+:1002E000356768706F35006D6373356768706F369A
+:1002F000006D6373356768706F3700656C6E6132CF
+:100300006700656C6E6135670074656D706F666659
+:100310007365740070687963616C5F74656D706497
+:10032000656C7461000C1218243048606C003CC489
+:1003300007003BC407004C84FFE0B084F7F7F98462
+:10034000F7FF000008040200350108300800030030
+:100350001204020043010000010000001C0402001E
+:1003600048010800030000002C04020049010800B5
+:1003700003000000390402004A01080003000000E5
+:10038000470402004E01080003000000520402006E
+:100390003D014000070007005E0402007A010004EE
+:1003A000070000006C0402003F010000060000008E
+:1003B00077040200400100000200000082040200F5
+:1003C0007C010000020000008F04020042010000D6
+:1003D000070000009B040200280008000300000042
+:1003E000AC0402002900000001000000B904020072
+:1003F0007F0100000200000000000000000000007B
+:1004000000000000706879007478696E737470770A
+:1004100072007068795F6D75746564007068795FEB
+:10042000676C697463687468727368007068795F78
+:100430006E6F6973655F7570007068795F6E6F6964
+:1004400073655F64776E007068795F706572636171
+:100450006C007068795F7278697165737400706898
+:10046000796E6F6973655F73726F6D006E756D5F26
+:1004700073747265616D0062616E645F72616E6754
+:10048000650073756262616E643567766572006DD2
+:10049000696E5F7478706F776572007068795F6FEE
+:1004A000636C736364656E61626C65007068795F2C
+:1004B0007278616E7473656C007068795F637273D3
+:1004C0005F7761720000EB04C00100006A04FFFF67
+:1004D000190036001A013A00250028000500120113
+:1004E000FF001F010B0013010700FC00FD00FF00CF
+:1004F000C000CA00C5001200570059005C00780017
+:100500009200980016012C016A000B001B001301D9
+:100510001D0014012E002A011201F904010001003E
+:10052000FA04010000004C04001800184D0400609B
+:1005300000603809FF01FF013909FF019E003B04FB
+:10054000030003003C0403000000DA46FFFFDBC6A3
+:100550000300D10604000400977A977A977A977A75
+:10056000877A877A977B000006000000060000006B
+:1005700006000000060000003809040004003909E4
+:1005800004000400A404001000104AC444004A44BB
+:1005900080004AC444004A448000A4040040000093
+:1005A000A40400800080D00420000000A404FF0107
+:1005B0000000A504FF00FF00A50400700050A50482
+:1005C000000700000D04FF0040000D0400070004B8
+:1005D000A204FF004000A20400070004A804FF00DA
+:1005E0000100D70401000100D704400000003706D5
+:1005F00000C00080810400020002B704007F006C8C
+:10060000B10400200000390900020000380900028E
+:100610000002B00408000800B0040008000839090E
+:10062000000800003809000800081004080008004D
+:10063000DA062000000003050100000003050400A5
+:100640000000A40400400000A40400800000D004C6
+:1006500020000000A504FF00FF00A504007000506A
+:10066000A504000700000D04FF0040000D04000772
+:100670000006A204FF004000A20400070006D904FF
+:1006800070002000D90400070003D9040070001096
+:10069000DA0400100000DA0400200020A604008024
+:1006A0000080D70408000800D70400700010D904A7
+:1006B00004000000D9040800080000000000000049
+:1006C0000000000000000000FFEEDDCCBB99887741
+:1006D0006655443322110000DA46FFFF0305080087
+:1006E000080025642009202564200A004572726FE5
+:1006F000722067657474696E67206C6F772069710A
+:10070000206573740A004572726F72206765747495
+:10071000696E672068696768206971206573740A6B
+:1007200000004AC480004A847F00D0040200000018
+:10073000D204FF000000D20400FF0000D004080033
+:1007400000004C04000800084D0400200000B00424
+:1007500000010001B644FFFFB7040F000F004C0476
+:10076000000800084D0400200020B0040001000132
+:100770003B04010001003C04010001003C040100B5
+:1007800000003B04010000004AC444004A448000C9
+:10079000DAC64000DBC60300DA06200020001004A1
+:1007A00008000000A60400800080A604FF01FF00EE
+:1007B0009A04FF01FF008007000400048007000284
+:1007C0000002D60603000000DA06080008004249CD
+:1007D00002003B4900003C49000076068000000012
+:1007E000DA06010000006C08040000006C084000FC
+:1007F00000006C0800040000D70408000000D804C2
+:1008000001000000D804020000003B0404000400C2
+:100810003C04040000003B04040004003C04040009
+:10082000000084806782568034823B04010001000E
+:100830003C04010001003C04010000003B040100F5
+:1008400000003B04020002003C04020002003C04E1
+:10085000020000003B0402000000977A977A977A22
+:10086000977A877A877A977B0F0900090109060929
+:10087000070908090209030909090A090B090409FA
+:1008800005090C090D090E09110987466000424649
+:1008900007003B84EDFF3C04020002004C84D0EFD3
+:1008A0004D84D7BF4D04040004004D040300010033
+:1008B000F984F8FFFA84F8FF3B04020002003C04CC
+:1008C000020000003B04100010003C044000000047
+:1008D0004C04001000104D04004000404D04040082
+:1008E00000004C04040004004C04080008004D04FF
+:1008F000080000004C04200020004D0420002000CF
+:10090000F90402000200FA0402000000F9040400E5
+:100910000400FA0404000000F90401000100FA04D4
+:1009200001000000DB04FF03A602DB0400700020CE
+:100930009A05FF0326009B05FF03A5009C05FF0306
+:10094000A6009C0500FC00289D05003C001C9D05A0
+:10095000FF03A800A40400800080A404004000401D
+:10096000A40400200020B004800000003B044000EC
+:100970000000A904008000802184238434838480C3
+:100980006782568034823B04020002003C0402006D
+:1009900000003B04100010003C04400000004B44E9
+:1009A000FFFFB10400040000B1040080000038091A
+:1009B00040004000380904000400390940000000EC
+:1009C000390904000400D70402000200D7048000A3
+:1009D0000000D70401000100D70440004000D70404
+:1009E00008000800D70400700020DA06400040002C
+:1009F000A40400200000D70408000800D7040070F9
+:100A0000002031C61500D60603000000DAC68F00AC
+:100A1000100480000000A8440A000305A404D004C8
+:100A2000D904DA04A60438093909D804D004D70453
+:100A3000A5040D04A2044C04001000104D04004055
+:100A400000404C04000800084D04002000003B0456
+:100A5000020002003C04020000003B04010001000F
+:100A60003C04010000004C04080008004D0408008C
+:100A700008004C04200020004D0420000000F90470
+:100A800002000200FA0402000200F904040004005B
+:100A9000FA0404000400F90401000100FA04010052
+:100AA00001005344A90A3D49C000000000000000B5
+:100AB000000000000000000000000000977A877A24
+:100AC000877A977B760680008000DA0601000100B5
+:100AD0006C08040004006C08400040006C0800042E
+:100AE000000410091E091F092409250926092009E7
+:100AF000210927092809290922092309300931096F
+:100B000032091209D7440000D70401000100D704BC
+:100B100040000000D70401000100D704400040005D
+:100B20001004020000001004010000001004020084
+:100B30000000100401000100100402000200100473
+:100B4000010000007A46030073467017744644049F
+:100B500075463F00704681068C4649004AC44400F1
+:100B60004A448000004001400240034004400540E8
+:100B700006400740075B0780A3C60100A386FEFF6F
+:100B80000700FF001F013A001A01050082008600DD
+:100B90002E0113017D002800340600FF0000DAC694
+:100BA00080000AC02802760680000000DA060100F4
+:100BB00000006C08040000006C08400000006C0895
+:100BC00000040000D80401000000D8040200000066
+:100BD000D704080000004C84FFE73B840C005384DA
+:100BE000FF7F53C40080424907003B4917203C491E
+:100BF000C527D60603000100DA0608000000DA0661
+:100C0000800000000A46A0006A4419000F0900098C
+:100C100001090609070908090209030909090A095E
+:100C20000B09040905090C090D090E091109C9462A
+:100C300000068046FF0081463F01CE460000CB46BD
+:100C40000000CC460000CD4600009D46FF07A446AC
+:100C50000000A5460000D90404000400D9040800DF
+:100C60000000A40400400040A40400400000DAC6D4
+:100C700040000100D70408000800D70400700030CD
+:100C80004AC444004A4480003B0404000000380980
+:100C900040000000380904000000D70402000000F2
+:100CA000D70401000000D70408000000D8040100A8
+:100CB0000000D8040200000000FC070069A5050040
+:100CC000FF010000695D0A0000040800975E0A0049
+:100CD0000102000097A60500D70401000100D70417
+:100CE00040004000D70401000000D90401000100C9
+:100CF000D904020000000000AA0A02009A05FF03BE
+:100D000026009B05FF0389009C05FF038A009C05C4
+:100D100000FC00209D05003C002C9D05FF038C007D
+:100D20003B04010001003C040100000038090008F8
+:100D30000008390900080008DA0600800080D306A0
+:100D400000800080D30600800000DA0600800000EA
+:100D50000A80D7FDDA867FFFD7C6010031C60018AA
+:100D60003B4400003C4400004C440000E6440000CA
+:100D7000F9440000B044000038490000B0440000CD
+:100D80004E44000067C503004AC444004A44800042
+:100D90004804000300010806FF0017000406FF07CF
+:100DA000EA0342490F004249000042490F004A4409
+:100DB00084004A448000D3462222D34620223B4965
+:100DC00017203C49C5270305010000000305040066
+:100DD00000000305100010004249000042490F00C6
+:100DE000424900003B4917003C49C5074AC444003A
+:100DF0004A448000D70408000000D7040070002097
+:100E0000380904000400390904000400A404001097
+:100E10000010D70404000400D704000F00008B4624
+:100E200000007646A1B816012D012C016A00980039
+:100E300097002F010B0013011D0014012E002A0141
+:100E400009001F010700FF000500D0040100000099
+:100E5000D304FF000000D30400FF0000D004100002
+:100E60000000D004040000003A0980008000230440
+:100E7000FF0049003404FF00FCFF1604FF00A4FF3C
+:100E8000160400FF009F240400FF002A230400FF33
+:100E9000002D2504FF000F000005FF000F000005D6
+:100EA00000FF000F2004FF000A00340400070001C7
+:100EB0003204FF00BF00320400FF00B8FF0400FC52
+:100EC0000018D106040000004B06400040002184B9
+:100ED0002384348384806782568034824B060100E9
+:100EE00001004B06080008005F36291F5F36291FE6
+:100EF0005F36291F5F36291F000000000000000038
+:100F000000000000000000000000000000000000E1
+:100F100000000000000000000400000000000000CD
+:100F200004000000080000000100000005000000AF
+:100F3000090000000D0000004D0000008D000000C1
+:100F40000D0000004D0000008D000000CD000000ED
+:100F50005200000092000000D2000000D600000005
+:100F600016010000160500001609000056090000D1
+:100F7000560D000056110000961100009651000019
+:100F80009691000096D1000096110100000000002B
+:100F90000000000000000000000000000000000051
+:100FA0000000000004000000000000000400000039
+:100FB000080000000100000005000000090000001A
+:100FC0000D0000004D0000008D0000000D0000002D
+:100FD0004D0000008D000000CD0000005200000018
+:100FE00092000000D2000000D600000016010000B0
+:100FF000160500001609000056090000560D0000F5
+:1010000056110000565100005691000056D10000C4
+:1010100056110100565101005691010056D10100B0
+:1010200000000000000000000000000000000000C0
+:1010300000000000000000000000000000000000B0
+:1010400000000000000000000000000000000000A0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:1010700000000000000000000A0009000600050052
+:101080000A000900060005000A0009000600050024
+:101090000A000900060005000A0009000600050014
+:1010A0000A000900060005000A0009000600050004
+:1010B0000A000900060005000A00090006000500F4
+:1010C0000A000900060005000A00090006000500E4
+:1010D0000A000900060005000A00090006000500D4
+:1010E0000A000900060005000A00090006000500C4
+:1010F0000A000900060005000E00000000020003BF
+:10110000000400060008000B00100110021003107C
+:10111000041005100610071007170720072D0740B9
+:1011200000000000000000000000000000000000BF
+:1011300000000000000000000000000000020003AA
+:10114000000400060008000B00100110021003103C
+:10115000041005100610071007170720072D074079
+:10116000000000000000000000000000000000007F
+:10117000000000000000000000000000000000006F
+:10118000000000000000000000000000000000005F
+:10119000000000000000000000000000000000004F
+:1011A00000000000000000000000004000000000FF
+:1011B000000000000000000000000000000000002F
+:1011C000000000000000000000000000000000001F
+:1011D000000000000000000000000000000000000F
+:1011E00000000000000000000000000000000000FF
+:1011F00000000000000000000000000000000000EF
+:1012000000000000000000000000000000000000DE
+:1012100000000000000000000000000000000000CE
+:1012200000000000000000000000000000000000BE
+:1012300000000000000000000000000000000000AE
+:10124000000000000000000000000000000000009E
+:1012500000000000F8410100F8210000FB2100001F
+:10126000FB410000DBFE01007B2100003321000078
+:10127000EB400000A3FE01004B0200004D014D01B8
+:101280004D014D014D014D014D014D014D014D01EE
+:101290004D014D014D014D014D014D014D014D01DE
+:1012A0004D014D014D014D014D014D014D014D01CE
+:1012B0004D014D014D014D014D014D014D014D01BE
+:1012C0004D014D014D014D014D014D014D014D01AE
+:1012D0004D014D014D014D014D014D014D014D019E
+:1012E0004D014D014D014D014D014D014D014D018E
+:1012F0004D014D014D014D014D014D01090F1418D6
+:10130000FE070B0FFBFE0105080B0E111417000062
+:1013100000000000000306090C0F1200000000008E
+:1013200000000000000306090C0F1215181B000036
+:101330000000000003EB000001001000100020007E
+:101340000100300010004000220050002201600027
+:101350002202700022038000220490002205A000D7
+:101360002206B0002207C0002208D0002209F000A7
+:10137000220A1000220B2000220C3000220D400017
+:10138000220E5000220F600000000000000000004C
+:10139000000000000000000000000000000000004D
+:1013A0000000000000000000040000000000000039
+:1013B000040000000800000001000000050000001B
+:1013C000090000000D0000004D0000008D0000002D
+:1013D0000D0000004D0000008D000000CD00000059
+:1013E0004F0000008F000000CF000000D30000007D
+:1013F0001301000013050000130900005309000049
+:10140000530D000053110000931100009351000090
+:101410009391000093D1000093110100000000009F
+:1014200000000000000000000000000000000000BC
+:1014300000000000040000000000000004000000A4
+:101440000800000001000000050000000900000085
+:101450000D0000004D0000008D0000000D00000098
+:101460004D0000008D000000CD0000004F00000086
+:101470008F000000CF000000D30000001301000027
+:10148000130500001309000053090000530D00006C
+:1014900053110000535100005391000053D100003C
+:1014A00053110100535101005391010053D1010028
+:1014B000000000000000000000000000000000002C
+:1014C000000000000000000000000000000000001C
+:1014D000000000000000000000000000000000000C
+:1014E00000000000000000000000000000000000FC
+:1014F00000000000000000000000000000000000EC
+:1015000000000000000000000104020403040404C1
+:10151000050406040704080409040A048B058C0565
+:101520008D058E058F059000910092009301940126
+:10153000950196019701980199019A019B019C01DF
+:101540009D019E019F01A001A101A201A301A4018F
+:10155000A5010000010101010101010101010101D9
+:10156000010101010101010101010101010101016B
+:101570000101020301030201010101010101010155
+:10158000010101010101010101010101010101014B
+:10159000010101010101010101010101010101013B
+:1015A000010101010101010101010101010101012B
+:1015B0000101020301030201010101010101010115
+:1015C000010101010101010101010101010101010B
+:1015D000010101017C120200400000000200000035
+:1015E0000000000010000000D411020040000000C4
+:1015F0000100000000000000100000005412020072
+:101600000A0000000B0000000000000020000000A5
+:1016100038130200140000000C000000000000005D
+:1016200020000000A41A0200940000000D00000039
+:101630000000000020000000081502002600000045
+:101640000E000000000000001000000078100200F2
+:10165000400000000F00000000000000100000002B
+:10166000081D020010000000100000000000000033
+:1016700008000000FC1202003C0000001100000005
+:101680000000000008000000881302006000000055
+:1016900012000000000000002000000054150200AD
+:1016A000800000001400000000000000080000009E
+:1016B000EC1602009A000000170000000000000075
+:1016C00010000000FC1002006C0000000000000090
+:1016D000000000001000000020180200A000000020
+:1016E0001800000000000000200000001A00340074
+:1016F0004E0068009C00D000EA000401340068003D
+:101700009C00D0003801A001D40108024E009C00CA
+:10171000EA003801D4017002BE020C036800D00058
+:101720003801A00170024003A803100418009C00B7
+:10173000D0000401EA0038018601D0000401040150
+:1017400038016C016C01A001380186018601D401C9
+:10175000220222027002040138016C0138016C017E
+:10176000A001D401A001D401080208023C028601B4
+:10177000D4012202D40122027002BE027002BE0213
+:101780000C030C035A0336006C00A200D80044017D
+:10179000B001E6011C026C00D8004401B0018802CF
+:1017A0006003CC033804A2004401E6018802CC03A4
+:1017B0001005B2055406D800B00188026003100578
+:1017C000C0069807700818004401B0011C02E60129
+:1017D00088022A03B0011C021C028802F402F402EF
+:1017E000600388022A032A03CC036E046E041005EA
+:1017F0001C028802F4028802F4026003CC03600336
+:10180000CC0338043804A4042A03CC036E04CC03AC
+:101810006E041005B2051005B20554065406F6060E
+:101820000000080000000800000008000000080098
+:101830000000080000000800000008000000080088
+:101840000000080000000800000008000000080078
+:101850000000080000000800000008000000080068
+:101860000000080000000800000008000000080058
+:101870000000080000000800000008000000080048
+:101880000000080000000800000008000000080038
+:101890000000080000000800000008000000080028
+:1018A0000000080000000800000008000000080018
+:1018B0000000080000000800000008000000080008
+:1018C00000000800000008000000080000000800F8
+:1018D00000000800000008000000080000000800E8
+:1018E00000000800000008000000080000000800D8
+:1018F00000000800000008000000080000000800C8
+:1019000000000800000008000000080000000800B7
+:1019100000000800000008000000080000000800A7
+:101920000000080000000800000008000000080097
+:101930000000080000000800000008000000080087
+:101940000000080000000800000008000000080077
+:101950000000080000000800000008000000080067
+:101960000000080000000800000008000000080057
+:101970000000080000000800000008000000080047
+:101980000000080000000800000008000000080037
+:101990000000080000000800000008000000080027
+:1019A0000000080000000800000008000000080017
+:1019B0000000080000000800000008000000080007
+:1019C00000000800000008000000080000000800F7
+:1019D00000000800000008000000080000000800E7
+:1019E00000000800000008000000080000000800D7
+:1019F00000000800000008000000080000000800C7
+:101A000000000800000008000000080000000800B6
+:101A100000000800000008000000080000000800A6
+:101A20000000080000000800000008000000080096
+:101A30000000080000000800000008000000080086
+:101A40000000080000000800000008000000080076
+:101A50000000080000000800000008000000080066
+:101A60000000080000000800000008000000080056
+:101A70000000080000000800000008000000080046
+:101A80000000080000000800000008000000080036
+:101A90000000080000000800000008000000080026
+:101AA0000500000000000000000000000000001021
+:101AB00000000000000000200000000000000030D6
+:101AC0000000000000000040000000000000005086
+:101AD0000000000000000060000000000000007036
+:101AE00000000000000000800000000000000090E6
+:101AF00008000000000000A008000000000000B086
+:101B000008000000000000C008000000000000D035
+:101B100008000000000000E008000000000000F0E5
+:101B20000800000000000000090000000000001094
+:101B30000900000000000020190000000000003033
+:101B400019000000000000401900000000000050D3
+:101B50001900000000000060190000000000007083
+:101B60001900000000000080190000000000009033
+:101B700019000000000000A019000000000000B0E3
+:101B800019000000000000C019000000000000D093
+:101B900019000000000000E019000000000000F043
+:101BA00019000000000000001A00000000000010F2
+:101BB0001A000000000000201A00000000000030A1
+:101BC0001A000000000000401A0000000000005051
+:101BD0000200000000000060020000000000007031
+:101BE00002000000000000800200000000000090E1
+:101BF00002000000000000A002000000000000B091
+:101C000002000000000000C00A000000000000D038
+:101C10000A000000000000E00A000000000000F0E0
+:101C20000A000000000000000B000000000000108F
+:101C30000B000000000000200B000000000000303E
+:101C40000B000000000000400B00000000000050EE
+:101C50001B000000000000601B000000000000707E
+:101C60001B000000000000801B000000000000902E
+:101C70001B000000000000A01B000000000000B0DE
+:101C80001B000000000000C01B000000000000D08E
+:101C90001B000000000000E01B000000000000F03E
+:101CA0001B000000000000001C00000000000010ED
+:101CB0001C000000000000201C000000000000309C
+:101CC0001C000000000000401C000000000000504C
+:101CD0001C000000000000601C00000000000070FC
+:101CE0001C000000000000801C00000000000090AC
+:101CF0001C000000F80E020060000000120000004E
+:101D000000000000200000005F36291F5F36291FF9
+:101D10005F36291F5F36291FE80E02001000000001
+:101D200010000000000000000800000090E886009D
+:101D30000000800001000000000000000000000022
+:101D4000000000007363616E0000000044EB860039
+:101D50000100204005000000A2A5860002002040EE
+:101D60000500000090A5860003002040050000004B
+:101D70007EA58600040020400500000075998600BD
+:101D80000500104005000000EBE88600060020403A
+:101D9000020000004CEB86000C0000000100000077
+:101DA0005EEB860007002000080000000000000035
+:101DB00000000000000000006E6F63726300534477
+:101DC000494F0043444300000D1680008D138000EE
+:101DD00025118000291480001D138000A1168000A9
+:101DE000A90F0100011380002D13800000000000E6
+:101DF0001D168000E9270000776C0000000000003D
+:101E00000000000000000000F025000000000000BD
+:101E100000000000000000000000000000000000C2
+:101E20000000000005000000FFFFFFFF140000009D
+:101E30000100050605000000FFFFFFFF0500000090
+:101E400005000000050000000E0E0E0E0E02090D2A
+:101E50000A080D01090D0A080D01090D0A080D01F6
+:101E6000090D0A080D01090E0A090E060A0E0B09D2
+:101E70000E02093A160E0E05093A160E0E050A0E46
+:101E80000B090E050A0E0B090E020A0E0B090E02B3
+:101E900014C0C015110514C0C015110514C0C0151B
+:101EA000110514C0C015110514C0C0151105093A5B
+:101EB000160E0E0514C0C015110514C0C01511056D
+:101EC000093A160E0E05093A160E0E05093A160EB7
+:101ED0000E0514C0C0151105093A160E0E05093A73
+:101EE000160E0E05093A160E0E0509B21C0E0E0549
+:101EF00012B11911110800000000000000000000DC
+:101F00000000000065660200416602002D660200C6
+:101F100055AA80000000000021AA800085AA800048
+:101F200031AA80006DAA8000C993800095A9800025
+:101F3000BDA98000D5938000B59380007593800083
+:101F4000D191800000000000B1A98000736470632B
+:101F50006D6465760000000000000000041F0200B0
+:101F60000000000000000000000000000000000071
+:101F70000000000000000000000000000000000061
+:101F80000000000000000000000000000000000051
+:101F90000000000000000000000000000000000041
+:101FA0000000000000000000000000000000000031
+:101FB0000000000000000000000000000000000021
+:101FC0000000000000000000000000000000000011
+:101FD0000000000000000000000000000000000001
+:101FE00000000000000000000000000000000000F1
+:101FF00000000000000000000000000000000000E1
+:1020000000000000000000000000000000000000D0
+:1020100000000000000000000000000000000000C0
+:1020200000000000000000000000000000000000B0
+:1020300000000000000000000000000000000000A0
+:102040000000000000000000000000000000000090
+:102050000000000000000000000000000000000080
+:102060000000000000000000000000000000000070
+:10207000000000000000000004E301004100000037
+:10208000440000000000000000000000000000000C
+:102090000000000000000000000000000000000040
+:1020A0000000000000000000000000000000000030
+:1020B0000000000000000000000000000000000020
+:1020C0000000000000000000000000000000000010
+:1020D0000000000000000000000000000000000000
+:1020E00000000000000000000000000000000000F0
+:1020F00000000000000000000000000000000000E0
+:1021000000000000000000000000000000000000CF
+:1021100000000000000000000000000000000000BF
+:1021200000000000000000000000000000000000AF
+:10213000000000000000000000000000000000009F
+:10214000000000000000000000000000000000008F
+:10215000000000000000000000000000000000007F
+:10216000000000000000000000000000000000006F
+:10217000000000000000000000000000000000005F
+:10218000000000000000000000000000000000004F
+:10219000C8DC0100010000000100F918010DE40095
+:1021A000F4DEF106FC0F27FAFF1DF01018090AF201
+:1021B00010E01714041114F1FAF2DBF7FCE2FBE172
+:1021C000EE130DFF1CE91A17180300DAE803E617EF
+:1021D000E4E9F3FF121305E104E225F706F2ECF15E
+:1021E000FC11E914F0E0F6F2E8091010011DD9FA2B
+:1021F000040F0F060CDE1C00FF0D07181AF60EE484
+:10220000160FF905EC181B0A1EFF0026E2FFE50A6F
+:1022100014180705EA0FF2E4E6F6080808080808AB
+:1022200008090A0808070701020202020202020264
+:102230000202020202020202020201010000000088
+:1022400000000000C5011DFFE0FFC0FFE0FF00002F
+:10225000000000FF000000006B0382FEE7FFCCFFE0
+:10226000E7FF080002000000D7010BFFEEFFDCFFD4
+:10227000EEFFA7033CFEECFF1700ECFF720385FEA8
+:10228000AEFEF801AEFE070004000000980160FFFA
+:10229000CBFF96FFCBFF9C0345FE2500C1FF250029
+:1022A000B10316FEE4FEA501E4FE070014000100E0
+:1022B000BF0131FFF20049FEF200870361FE33FFE8
+:1022C000620133FF800378FEDAFEE900DAFE0800DF
+:1022D00015000100BF0131FF18010EFE1801870330
+:1022E00061FE16FF7C0116FF800378FE8FFF9300CE
+:1022F0008FFF090016000100BF0131FF620055FF8A
+:102300006200870361FE1FFF6B011FFF79037EFEE2
+:10231000F4FE5D00F4FE080017000100BC0131FF6F
+:10232000740042FF7400870361FE52FF020152FFF6
+:10233000800378FE7FFFF1FF7FFF08001800010097
+:10234000B40131FFDFFF1D00DFFF880361FE87FF5F
+:1023500090FF87FF7F0378FECDFEF401CDFE0800DD
+:1023600019000100AD0131FFB8FF3E00B8FF820344
+:1023700061FEAAFFB1FFAAFF7F0378FEC7FEFE0140
+:10238000C7FE08001A000100930154FFD9FF0C009A
+:10239000D9FF1B03C7FE4CFF38004CFF3303B8FEC8
+:1023A00080FF280080FF08001B000100890154FF06
+:1023B000CFFF1300CFFF1703C7FE00FF500000FF41
+:1023C0002E03BDFE8BFF25008BFF08001E000100C1
+:1023D000BB0119FFC3FF1D00C3FF6B0361FE66FF56
+:1023E000480066FF7C0378FE56FF4F0056FF08004A
+:1023F0002C000100BF0131FFE00071FEE000870307
+:1024000061FE8BFFC4008BFF800378FEB2FEC0002C
+:10241000B2FE0800010000006C0900000B0A000772
+:102420000A88888002000000710900000B0A00077A
+:102430000A88888003000000760900000B0A000764
+:102440000A888880040000007B0900000B0A00074E
+:102450000A88888005000000800900000B0A000738
+:102460000A88888006000000850900000B0A000722
+:102470000A888880070000008A0900000B0A00070C
+:102480000A888880080000008F0900000B0A0007F6
+:102490000A88888009000000940900000B0A0007E0
+:1024A0000A8888800A000000990900000B0A0007CA
+:1024B0000A8888800B0000009E0900000B0A0007B4
+:1024C0000A8888800C000000A30900000B0A00079E
+:1024D0000A8888800D000000A80900000B0A000788
+:1024E0000A8888800E000000B40900000B0A00076B
+:1024F0000A888880000001009F0152074000800088
+:102500004000180378064000800040000A032E06B1
+:1025100040008000400008000100010092013707E0
+:1025200003013B0003019F02020744003600440000
+:10253000600247075D00A7005D000800020001007F
+:102540009F01520740008000400018037806C00039
+:102550008001C0000A032E064000800040000800F1
+:10256000030001002E013107810002018100920267
+:10257000B806CD009A01CD00F202E006AA0054018F
+:10258000AA0008001400010068015CFFF200C6FE0A
+:10259000F200F002B8FE33FFCB0033FFFF02E0FE93
+:1025A00003FF49FF03FF08001500010068015CFFFD
+:1025B000950052FF9500F002B8FE33FFA40033FFF0
+:1025C000FF02E0FE00FFEFFE00FF08001600010022
+:1025D00068015CFF62009CFF6200F002B8FE33FFFE
+:1025E0007C0033FFFF02E0FE00FFA0FE00FF0800BA
+:1025F000170001005E015CFF8CFF52008CFFF002AF
+:10260000B8FE33FF280033FFFF02E0FE7FFF15FF17
+:102610007FFF08001800010045015CFFE0FFD8FFC4
+:10262000E0FFF402B8FE00FF29FE00FFFE02E0FE1C
+:10263000FAFEAA00FAFE0800190001002B015CFF57
+:10264000CDFFC0FFCDFFE002B8FE00FF29FE00FF76
+:10265000FD02E0FEFAFEAA00FAFE08001A000100E0
+:10266000150197FFD9FF8BFFA8FF7D022EFFC0FF4A
+:1026700040FF70FF660248FF80FF80FEE0FE08001A
+:102680001B000100F50097FFCFFF6DFF92FF720264
+:102690002EFF5EFF1BFE95FE650248FFC2FF46FF50
+:1026A00075FF08001E0001002E0131FFC3FF86FFE9
+:1026B000C3FF9202B8FE33FF66FE33FFF202E0FE74
+:1026C00056FFACFE56FF08002800010068015CFFC1
+:1026D000F200C6FEF200F002B8FECD0035FFCD00DC
+:1026E000FF02E0FEFF017201FF0108000501000882
+:1026F0000001FFFF0000000000000000A200000039
+:1027000000FF00FF00000000000000FF00000000CC
+:102710007802A0FE80FF00FF80FF0800010000009B
+:10272000760179FFF0FFE0FFF0FF1F0374FECEFF9C
+:10273000E0FFCEFFEE022BFE2CFF32002CFF080044
+:1027400002000000770116FFDBFFB4FFDBFF1F0371
+:1027500074FEE0FFECFFE0FFEC02F2FE80FF1E00E3
+:1027600080FF080003000000770116FFDBFFB4FFC5
+:10277000DBFF1F0374FEE0FFECFFE0FFEC02F2FE64
+:102780006CFF23006CFF0800040000003301AEFF63
+:10279000CBFF96FFCBFF0B0385FECBFF0A00CBFFE1
+:1027A000FD022BFE2CFFCA002CFF080000000000D9
+:1027B0000000000000000000000000000000000019
+:1027C0000000000000000000000000000000000009
+:1027D00000000000000000000000000000000000F9
+:1027E00000000000000000000000000000000000E9
+:1027F00000000000000000000000000000000000D9
+:1028000000000000000000000000000000000000C8
+:1028100000000000000000000000000000000000B8
+:1028200000000000000000000000000000000000A8
+:102830000000000000000000000000000000000098
+:102840000000000000000000000000000000000088
+:102850000000000000000000000000000000000078
+:102860000000000000000000000000000000000068
+:102870000000000000000000000000000000000058
+:102880000000000000000000000000000000000048
+:102890000000000000000000000000000000000038
+:1028A0000000000000000000000000000000000028
+:1028B0000000000000000000000000000000000018
+:1028C0000000000000000000000000000000000008
+:1028D00000000000000000000000000000000000F8
+:1028E00000000000000000000000000000000000E8
+:1028F00000000000000000000000000000000000D8
+:1029000000000000000000000000000000000000C7
+:1029100000000000000000000000000000000000B7
+:1029200000000000000000000000000000000000A7
+:102930000000000000000000000000000000000097
+:102940000000000000000000000000000000000087
+:102950000000000000000000000000000000000077
+:102960000000000000000000000000000000000067
+:102970000000000000000000000000000000000057
+:102980000000000000000000000000000000000047
+:102990000000000000000000000000000000000037
+:1029A0000000000000000000000000000000000027
+:1029B0000000000000000000000000000000000017
+:1029C0000000000000000000000000000000000007
+:1029D00000000000000000000000000000000000F7
+:1029E00000000000000000000000000000000000E7
+:1029F00000000000000000000000000000000000D7
+:102A000000000000000000000000000000000000C6
+:102A100000000000000000000000000000000000B6
+:102A200000000000000000000000000000000000A6
+:102A30000000000000000000000000000000000096
+:102A40000000000000000000000000000000000086
+:102A50000000000000000000000000000000000076
+:102A60000000000000000000000000000000000066
+:102A70000000000000000000000000000000000056
+:102A80000000000000000000000000000000000046
+:102A90000000000000000000000000000000000036
+:102AA0000000000000000000000000000000000026
+:102AB0000000000000000000000000000000000016
+:102AC0000000000000000000000000000000000006
+:102AD00000000000000000000000000000000000F6
+:102AE00000000000000000000000000000000000E6
+:102AF00000000000000000000000000000000000D6
+:102B000000000000000000000000000000000000C5
+:102B100000000000000000000000000000000000B5
+:102B200000000000000000000000000000000000A5
+:102B30000000000000000000000000000000000095
+:102B40000000000000000000000000000000000085
+:102B50000000000000000000000000000000000075
+:102B60000000000000000000000000000000000065
+:102B70000000000000000000000000000000000055
+:102B80000000000000000000000000000000000045
+:102B90000000000000000000000000000000000035
+:102BA0000000000000000000000000000000000025
+:102BB0000000000000000000000000000000000015
+:102BC0000000000000000000000000000000000005
+:102BD00000000000000000000000000000000000F5
+:102BE00000000000000000000000000000000000E5
+:102BF00000000000000000000000000000000000D5
+:102C000000000000000000000000000000000000C4
+:102C1000000000000000000083682DE9F0415B69BE
+:102C20000546152B0F460AD0182B08D01B2B06D0B3
+:102C3000242B01D0272B04D12B8A7F2B05D80C23E2
+:102C400004E0172B01D0182B01DD1423AB624FF0E9
+:102C500004430022BB6100E00132BB69002B03DAB0
+:102C60001D4B9A42F8D134E01C4B9A4231D8AE6ADF
+:102C70003C69331DAB83AC61A868298ADEF346F357
+:102C8000022390FBF3F014F4807F68840AD0284676
+:102C900039463246DEF352F3C0F30F1083B2E883B5
+:102CA0002B8403E0AB8B2B846B8CEB83AB6913F42D
+:102CB000007F0AD0AA6A284639460132DEF33EF385
+:102CC000C0F30F1083B2688400E02B8CAB842B8A96
+:102CD000EB84BDE8F081C046809698007F9698000E
+:102CE00070B50446DEF33CF1002144220546DFF3D3
+:102CF000A7F16369152B2B6001D0162B01D9104B5E
+:102D00006B60686808B9054617E0AC602046E8F3D8
+:102D1000F1F1E8602046E8F3B5F1064618B920461F
+:102D20000121E8F3EDF16B6820469B689847054662
+:102D30001EB920463146E8F3E3F1284670BDC0468F
+:102D4000C81D02002DE9F0470546884691469A467F
+:102D5000E8F398F1074618B928460121E8F3D0F1C5
+:102D60002846E8F38FF1D0B12846E8F381F1B0B9F5
+:102D70002846FFF7B5FF064610B94FF0FF3410E0C4
+:102D80002846ECF763FD736830465C6941464A4665
+:102D90005346A04704462846ECF75CFD01E06FF07F
+:102DA00018041FB928463946E8F3AAF12046BDE8C1
+:102DB000F087C0460523C0F894310223C0F898314B
+:102DC0001E33C0F89C31234B4FF010021B68002BC0
+:102DD0000CBF07230023C0F8A0314FF00103C0F857
+:102DE000AC3103F16303C0F8B0314FF00603C0F813
+:102DF000C03140F23C73C0F8C4314FF00803C0F852
+:102E0000C83103F10D03C0F8A421C0F8B821C0F8FF
+:102E1000BC21C0F8CC31C0F8D02101D1032302E09D
+:102E20000D4B1B68013BC0F8D4311C230422C0F8B1
+:102E3000DC310C23C0F8E0319B18C0F8E4310623E4
+:102E4000C0F8EC310023C0F8D821C0F8E821C0F860
+:102E5000F0317047EC260000D4250000D0F81012A5
+:102E600070B5044609B90D460CE08068DFF39CF6A6
+:102E7000D4F810120546E822A068E3F339F70023DE
+:102E8000C4F81032284670BD70B50024054680F89D
+:102E90007541006903F04AFC2846E6F30DF7E8683F
+:102EA0002146E7F3C7F7D5F8900128B1E3F306F21E
+:102EB000D5F89001E3F34CF2D5F88C0128B1E3F397
+:102EC000FDF1D5F88C01E3F343F2E86805F0CAFCA4
+:102ED000D5F8103223B11B7813B12846FFF7BEFF97
+:102EE000A86829464FF40772E3F302F770BDC046A5
+:102EF0001FB5044606238068E8210393E3F3E8F650
+:102F0000C4F8100210B94FF0FF300CE00021E822A5
+:102F1000DFF396F000230093A068D4F8101203AA00
+:102F20001C33DFF3D9F604B010BDC0462DE9F047DD
+:102F30008AB01F46129D9C4B08461D601146904664
+:102F4000E6F33CF6002800F02A8138464FF407717A
+:102F5000E3F3BEF60446002800F0218100214FF47F
+:102F600007720646DFF36CF0A76065612046FFF745
+:102F700021FF8E4B1B68C4F80C320BB99A4605E052
+:102F80001B78B3F1000A18BF4FF0010A884B04F117
+:102F900028001A680121002A14BF31221122DFF310
+:102FA0006DF70023009301930293404639462A4669
+:102FB000139B05F095FDE060002800F0EA80E7F340
+:102FC00051F72060E068E7F36BF7656960606B6854
+:102FD000784A83F00103784903F00103002B0CBF0A
+:102FE00088469046226884F8763140F629039A4252
+:102FF000D4F80890D4F80CC00AD120B905F5007EA9
+:1030000005F5047508E005F5007E05F5087503E093
+:1030100005F5007E05F50475D4F8B831D4F8BC2167
+:10302000D4F8C411D4F8C00101934FF0FF330493D6
+:1030300009330693002302920391059007934846B3
+:103040004146624673460095EEF774FA60620028C6
+:1030500000F09F80D4F80C12C1B10B78B3B1E1F34A
+:10306000C7F556492246D4F80C02DFF389F5D4F8A7
+:103070000C0253492246DFF3BDF5BAF1000F05D02B
+:103080002046FFF735FF002840F0838001210A46E3
+:10309000606AE1F3B5F520460021E2683B4603F0A3
+:1030A00051FB2061002874D000210B462046454A80
+:1030B000E3F370F10023C4F8900184F879314248B9
+:1030C000E4F3D4F518B3DFF303F2012383403F4860
+:1030D000C4F88031E4F3CAF510B1DFF3F9F108B1B7
+:1030E000D4F88001C4F8840139490020DFF344F4A6
+:1030F000030CA4F888319BB2A4F88A013BB10021EB
+:103100002046344A0B46E3F345F1C4F88C01002015
+:103110003149DFF331F4012809D184F816022F492F
+:103120000138DFF329F4012804BF2D4B1860204635
+:10313000E6F3A4F320B30025C4F8A051284629499A
+:10314000DFF31AF428B1012384F8F9312648EEF7A9
+:10315000ABFA28462549DFF30FF488B12349284606
+:10316000DFF30AF44FF0807300F00F000AA901F8B2
+:10317000010D4FF44072009320460F23DFF7BEFC91
+:103180001B481C492246E3F3B5F41B48EBF76CFDE2
+:1031900006E0A06821464FF40772E3F3A9F5002684
+:1031A00030460AB0BDE8F087F4260000BC260000D7
+:1031B000EC260000AE278600B6278600DD9B800047
+:1031C0007929000065A68000052886000E28860063
+:1031D00017288600499B80001F28860078D50100AB
+:1031E000AC2702002A2886003428860089D50100F1
+:1031F0004D288600E59A8000D596800010B50446DB
+:1032000060B1036806491868224600F09DDE236815
+:10321000214658684FF4BC72E3F36AF510BDC0460E
+:10322000853B86007FB505464FF4BC714068E3F3EB
+:103230004FF508B9064619E000214FF4BC72064666
+:10324000DEF3FEF60B4B356000930B4B002401932D
+:103250002868334609490A4A0294039400F03CDE88
+:103260004FF49663C6F8603186F86441304604B086
+:1032700070BDC04625110100E52C0000B0D501004D
+:10328000853B860070B5044608B906462AE0816889
+:1032900009B90E460CE0C3689868ECF3DFF1E36807
+:1032A000D0F1010638BF0026A1689868ECF3E8F178
+:1032B000616F0025A56529B1E368A26F5868E3F343
+:1032C00017F565672046EEF7D5FFE36806491868ED
+:1032D000224600F039DEE368214658684FF4B072A8
+:1032E000E3F306F5304670BDEB3D860030B54FF494
+:1032F000B07185B005464068E3F3EAF40446E0B1F6
+:1033000000214FF4B072DEF39BF6E560C5F8184873
+:10331000A8680D4922460023ECF3CEF1A06060B10D
+:103320000A4B2868009300230193029303930849F2
+:10333000084A234600F0D0DD18B12046FFF7A2FF6F
+:103340000024204605B030BD152E0000D9E18000D4
+:1033500034D60100EB3D8600034B012210B51A70F4
+:10336000EBF7F2FF10BDC0463C28020070B50446E2
+:10337000D0F884000D4608B102F0D8FCD4F88000E3
+:1033800008B105F0E5FBE06F08B1FFF737FFA06F6C
+:1033900008B105F06BFC606F08B1FFF773FFA06820
+:1033A00008B100F0CDFB284621468C22E3F3A0F4BF
+:1033B00070BDC0462DE9F04F064689B00D4600208D
+:1033C0008C2191469846139FE3F382F4044600282B
+:1033D00077D000218C22DEF333F62760304605F0EB
+:1033E000B1F807AB0190059383464FF0000A2046E1
+:1033F00041F2E44142463B460295CDF800A0CDF8AB
+:103400000C90049400F06EFD054600285BD0A0608F
+:1034100002F066DB2B696060E3602F4B1021A36430
+:103420002E4A3B46266164643046DEF34DF62B6936
+:1034300039461B6E2A489A6B2A4BEEF735F93A4605
+:1034400050461299284B0096CDF8049002F0ECFDFE
+:103450000746002837D16368012683F87860362153
+:103460003246D5F87C0223F08FD9204B2846E363FF
+:10347000FFF73CFF606730B36368284683F8A460B9
+:1034800005F006FCA067F0B12846FFF7CBFEE06729
+:10349000C8B1284605F088FBC4F8800098B12846DA
+:1034A00002F072FCC4F8840068B1114B01970093DC
+:1034B0000297039728680F490F4A234600F00CDD56
+:1034C00008B9204604E020465946FFF74FFF002088
+:1034D00009B0BDE8F08FC04655F78000FB4186007B
+:1034E00008B10200A0D6010029FB8000EFBEAD0D9F
+:1034F00099F88000E8D60100C542860041F2E44315
+:10350000984201D00020AFE044F22033994200F00D
+:10351000AA800533994200F0A680223B994200F030
+:10352000A2801E33994200F09E800333994200F03E
+:103530009A800C3B994200F096800133994200F04A
+:1035400092800133994200F08E80093B994200F04D
+:103550008A800233994200F08680013B994200F054
+:103560008280023399427ED0013399427BD001336D
+:10357000994278D00533994275D00133994272D07F
+:10358000013399426FD001F53C43D8339BB2022BF3
+:1035900069D94BF6D543CB189BB2022B63D944F2C1
+:1035A000413399425FD0013B99425CD001F53C43E5
+:1035B000B0339BB2022B56D944F25333994252D0C6
+:1035C000043399424FD04AF69D1399424BD044F2AE
+:1035D0005433994247D0253B994244D0013B99420C
+:1035E00041D0063399423ED0013399423BD001335A
+:1035F000994238D04BF6C943CB189BB2022B32D933
+:1036000044F2167399422ED0113399422BD0A3F570
+:103610007973994227D001F53C43A0339BB2012B2B
+:1036200021D901F53C43BA339BB2022B1BD94BF68F
+:10363000CF43CB189BB2012B15D94BF6AB43CB181C
+:103640009BB2012B0FD901F53C43A8339BB2012B50
+:1036500009D944F26333994205D00D33994214BF1E
+:103660000020012000E001207047C0462DE9F84FFE
+:1036700000264FF0010842F601334FF0FF344FF0BF
+:10368000640B0746A0F8283680F8474680F8C44403
+:103690000221224680F8288080F868B780F84266C8
+:1036A00080F84C8680F8436680F8498680F8466644
+:1036B00002F05ED938464146324602F059D90C2113
+:1036C0002246384602F054D90B213846324602F0E1
+:1036D0004FD90E212246384602F04AD90D213846EC
+:1036E000324602F045D90F212246384602F040D931
+:1036F00004210222384602F03BD9D7F860364FF059
+:10370000030987F8488683F80690D7F860364FF0AB
+:10371000020A83F8079040F62A13A7F82A36A7F87A
+:103720002C369BB2A7F82E3640F62A13A7F830366F
+:10373000A7F83236A7F83436A7F8363640F62B13FA
+:10374000A7F838363B68A7F87A6583F895604FF09C
+:103750000703A7F83A364FF00403A7F83C360F23C7
+:1037600087F80C37D7F89034A7F83E96C7F8803220
+:10377000A7F840A6A7F87C68A7F87EB887F8EA61A2
+:1037800087F8EB6187F81E6287F8EE6187F8EC61D5
+:1037900087F8FA8187F80B6787F8A0649E71D7F8DD
+:1037A00094340B22C7F8843283F80680D7F8983413
+:1037B0003146C7F8883283F806A0D7F89C343546DE
+:1037C000C7F88C3283F806903B6887F8506783F817
+:1037D0004D805C633B6807F5CC6483F842803B68AE
+:1037E000043483F843603B6887F8CF6183F839601D
+:1037F0003B68204683F8AA803B6887F8DF6187F83A
+:10380000E081C7F8E46187F8E161DE66DEF318F471
+:103810006FF0220387F864362C3387F865364A4602
+:1038200004EB0A001A49DEF3A7F33B6887F869A6A0
+:1038300087F8568587F8578583F84C603A6887F88B
+:103840009267A7F89067A7F88CB892F8463013F003
+:10385000030F0CD092F94C304BB1D7F8FC04243054
+:10386000F1F3F6F4D7F8FC043230F1F3F1F44FF44D
+:103870004873A7F85C373B68012287F8252883F84E
+:10388000A2203A684FF0FF3382F8B530BDE8F88FD8
+:103890000FD40100836B70B5002483F84C40C36BD8
+:1038A000012583F84C500646816BDFF711FEF16B62
+:1038B0003046DFF70DFE21463046F6F349F2B36B92
+:1038C000304683F84D40F36B294683F84D40D6F8D7
+:1038D00060364FF0FF34DD72D6F860369C81F6F327
+:1038E00037F2D6F860369B78AB4214D9B36B83F8C5
+:1038F0004D40F26B4FF0FF3382F84D3096F8CB34E9
+:1039000096F8CC2443EA022343F0800386F8CB34B4
+:103910001B0A86F8CC3470BDD0F8AC1110B5044643
+:1039200029B18068EBF3ACF60023C4F8AC31D4F8CD
+:10393000C41129B1A068EBF3A3F60023C4F8C43185
+:10394000D4F8741529B1A068EBF39AF60023C4F8F3
+:103950007435D4F8F81629B1A068EBF391F600237A
+:10396000C4F8F836D4F8FC1629B1A068EBF388F651
+:103970000023C4F8FC36D4F8E036196A31B1A068E7
+:10398000EBF37EF6D4F8E02600231362D4F83C155E
+:1039900029B1A068EBF374F60023C4F83C35D4F8E1
+:1039A000941729B1A068EBF36BF60023C4F89437A1
+:1039B000D4F8B01829B1A068EBF362F60023C4F87C
+:1039C000B03810BD70B505462D4980682A460023E1
+:1039D000EBF372F6C5F8AC0100284ED0A86829496F
+:1039E0002A460023EBF368F6C5F8C401002844D04A
+:1039F000A86825492A460023EBF35EF6C5F874054E
+:103A000000283AD0A86821492A460023EBF354F64F
+:103A1000C5F8F806002830D0A8681D492A460023BA
+:103A2000EBF34AF6C5F8FC0638B3A86819492A46EC
+:103A30000023D5F8E046EBF33FF62062E8B1A86832
+:103A400015492A460023EBF337F6C5F83C05A0B12B
+:103A5000A86812492A460023EBF32EF6C5F894070E
+:103A600058B1A8680E492A460023EBF325F6C5F89D
+:103A7000B008003818BF012000E0002070BDC0462B
+:103A80003DAA81003D708100253E81009591810015
+:103A9000858F8100256E810089598100396B8100F5
+:103AA000496F810010B50446006805F0B3FED4F8F4
+:103AB000583113B10023C4F85831D4F83C0120B177
+:103AC00005F00EF90023C4F83C31D4F8400120B1D0
+:103AD00001F080F80023C4F84031D4F84C0120B143
+:103AE00002F09AF80023C4F84C31D4F8540120B104
+:103AF00005F070FA0023C4F85431D4F8600120B105
+:103B000007F000F80023C4F86031D4F8383113B15D
+:103B10000023C4F83831D4F8640120B101F0FEFE6E
+:103B20000023C4F86431D4F8000520B107F026F969
+:103B30000023C4F80035204605F0D2FA10BDC04677
+:103B40002DE9F041054608B9074695E001F046FB2E
+:103B50000746284602F06AD800B90137D5F8F016B2
+:103B600049B16868D5F8F426E3F3C2F00023C5F83C
+:103B7000F436C5F8F0362846D5F81815F8F38AF764
+:103B80002846D5F8D816F8F385F7D5F82015284635
+:103B9000F8F380F7D5F82C1521B168684FF49662D8
+:103BA000E3F3A6F0D5F87C0220B105F051FA00232A
+:103BB000C5F87C3200242B19D3F84C1211B12846D9
+:103BC0001BF03ADC0434202CF5D10121284631F0D9
+:103BD000C9DD284601F078FE2E6BB16911B1284687
+:103BE00031F054D80024B461D5F85C0101F05EFFD7
+:103BF0002846FFF791FE2846FFF754FF2846D5F8E0
+:103C00002C18DFF75DFCC5F82C48D5F8B84404E063
+:103C100068681022E468E3F36BF02146002CF7D1CA
+:103C2000C5F8B844286816492A4600F08DD9D5F859
+:103C3000340718B101F010F9C5F83447D5F8680118
+:103C400018B106F0C5FFC5F86841D5F8181759B185
+:103C50006868D5F81C27E3F34BF0C5F8184703E074
+:103C60002846696807F0B0D8D5F87822002AF7D13D
+:103C70002846696800F034FD3846BDE8F081C0464A
+:103C8000BB5C8600036870B55E6905461449304622
+:103C9000DEF372F6C0B218B930461249DEF36CF6A4
+:103CA00040B2431E0E2B0ED8012803D1D5F8603642
+:103CB000002204E0022806D1D5F8603601229A716C
+:103CC000D5F86036DA71084930462C6BDEF354F6CD
+:103CD00084F804012846EFF3EFF1012070BDC046DF
+:103CE000C65C8600CB5C86000E5D8600036870B5FE
+:103CF0001B490546D0F860465869DEF33DF6207052
+:103D00002B6818495869D5F86046DEF335F6E0703F
+:103D1000D5F8602613780BB10F2B01D10123137056
+:103D2000D5F8603601211A785A70D5F860462046D9
+:103D3000DEF3DEF3A070D5F86026D3780BB10F2B3D
+:103D400001D10123D370D5F860360121DA781A71D8
+:103D5000D5F86046E01CDEF3CBF3607170BDC04661
+:103D600019D7010021D7010070B50446214600682B
+:103D700007F012F8C4F8000508B929305EE02068A1
+:103D800005F050FD2068214601F08AF8C4F8340798
+:103D900008B92A3052E02A4B2046C4F8583104F0C2
+:103DA000B9FFC4F83C0108B9313047E0204600F0C3
+:103DB0004BFFC4F8400108B932303FE0204606F01E
+:103DC000B3FEC4F8600108B9353037E020682146F9
+:103DD000A2681C4B05F058F9C4F87C0208B93930C8
+:103DE0002CE0204601F0EAFDC4F8640108B93C303B
+:103DF00024E0154B0125C4F838310023A4F83038ED
+:103E000084F8883884F88A3884F88958204601F084
+:103E100013FFC4F84C0108B93F300FE02368214676
+:103E200083F83A50236883F8A950206805F062F9B6
+:103E300008B1452002E0236883F8A05070BDC04659
+:103E4000EFBEADDE9D6D8100EFBEAD0DF0B5D0F8DB
+:103E500040750021AC2287B006463846DEF3F0F00C
+:103E60004FF06403FB85032387F8603000220123B1
+:103E7000D6F85C014FF42C5121F0D4DFFF2804D197
+:103E8000336B18691968EEF787FE31687886A6F8F3
+:103E9000260691F84640336B00F44065FF201A89EE
+:103EA00000211B68B5F5406F14BF1425282501902B
+:103EB00004F00304D6F8600600910294039580781C
+:103EC000049007F138002DF0D9D8336893F84630C4
+:103ED00013F0030F03D0FB8843F02003FB8007B0EF
+:103EE000F0BDC0462DE9F04F8DB01A9F9A460023D1
+:103EF00007910B930646934610461799189A199BFB
+:103F00009DF85890009709F08DF9044610B11E23D2
+:103F10000B937FE3FFF720FA179851460BAA00F0A6
+:103F20000DFD0546002800F07583179AD0F860361D
+:103F300042604FF0FF32D0F8008083F81C21836B81
+:103F4000C8F804A00363436B8660C362179BC0F884
+:103F50007871C8F80C30B54B88F82190C8F8B030AB
+:103F6000032380F86937C0F8CC2880F89D4151467A
+:103F7000FFF77CFB2846F7F323F7284605F0D4F833
+:103F80000446002840F04F8328463146179A53468E
+:103F900006F03EFEC5F8680108B91F23D3E2A44B22
+:103FA0000194009302940394A249A34A2B462868E3
+:103FB000FFF392F7A14B0194009302940394A0495C
+:103FC000A04A2B462868FFF387F7189A199B179E7B
+:103FD00002920393284607995A465346CDF800901B
+:103FE0000196049701F04AFA04460B90002840F02D
+:103FF0001A832B69186EEBF767FCA5F8BE082846F4
+:10400000F5F38EF508B914239DE2264631460AAA37
+:104010002846F7F311F231462846BDF8282001362C
+:10402000F7F314F2062EF1D1012488F89A4005F531
+:10403000BE72286908F1140118F054DC8249D8F8DE
+:104040001400DEF399F481498146D8F81400DEF3B8
+:1040500093F47F49A5F86208D8F81400DEF38CF4D5
+:10406000B5F86228A5F86408A5F87827A5F87A07B6
+:104070007849D8F81400DEF37FF47749A5F854089E
+:10408000D8F81400DEF378F485F856087349D8F8A8
+:104090001400DEF371F485F858087149D8F814005B
+:1040A000DEF36AF485F85A086E49D8F81400DEF396
+:1040B00063F485F857086C49D8F81400DEF35CF413
+:1040C00085F859086949D8F81400DEF355F485F8E5
+:1040D0005B086749D8F81400DEF34EF485F85C08F5
+:1040E0006449D8F81400DEF347F485F85E086249A5
+:1040F000D8F81400DEF340F485F860085F49D8F87A
+:104100001400DEF339F485F85D085D49D8F8140031
+:10411000DEF332F485F85F085A49D8F81400DEF36C
+:104120002BF485F861082846FFF7E0FDD5F86026F6
+:104130002B6B85F8F04785F8F14718691178D2782C
+:10414000EEF77CFF2869EA6AD0F8A03005F5CB7459
+:104150005360D0F8A43021469360D0F8A830D360E3
+:10416000D0F8AC301361D0F8B0305361D0F8B4302F
+:10417000936118F0E7DC08F14E0021463246DDF38A
+:10418000FBF6B5F8822144F221339A4217D00E3B58
+:104190009A4214D007339A4211D010339A420ED06B
+:1041A000143B9A420BD007339A4208D010339A42FC
+:1041B00005D025339A4214BF0024012400E00124D5
+:1041C00005EB84039B6B28462B63FFF75BFD08B967
+:1041D0001823B8E1296B4FF00F0340F2FF36A1F826
+:1041E000063101F1FC0201F58073A1F8086128464F
+:1041F00000F0B4FE2A6BD2F8FC30C2F8F830C2F8F6
+:10420000F030D2F80031C2F8F4301368022B07D135
+:10421000013B53752B6B284603215A7D01F0A8DB27
+:1042200019F0010F30D000222FE0C0465F7D5A0503
+:1042300079DB810078D48500BB5C8600E94800000A
+:104240005CD8010029D70100D6688600E2688600A4
+:10425000F5688600076986001C6986002B69860060
+:104260003A698600496986005A6986006B6986004A
+:104270007C6986008A69860098698600A66986003E
+:10428000B6698600C6698600012288F846200A21A0
+:10429000284601F06DDB296B28461C31F9F3C6F383
+:1042A0007F23296B00932B68002293F8463001F19D
+:1042B0001C0003F003030193503113462CF01CDF64
+:1042C000B4F1FF3F3FF45DAF2846F5F383F44FF4BC
+:1042D000D163C5F874382846FFF746FD04460B90B5
+:1042E000002840F0A0812869214619F00FDB2869D9
+:1042F00098F83A1018F052DF28465146FFF762FB53
+:1043000008B920231FE1284601F0DAFBC5F85C015B
+:1043100008B9212317E12846FFF798FD2146AD4A49
+:10432000AD4B28460094019506F008FDAB4B6E4658
+:104330001A1D07CA1B6886E80700072128462A4677
+:1043400006F094DC04212846A54AA64B009401956A
+:1043500006F0F4FC0028C5F88C0701DA2223F2E00D
+:104360002846179906F006DD08B96423EBE0C5F886
+:1043700004084FF0FF3728469B499C4A9C4B009706
+:10438000FEF342F6C5F82C08002800F04C812846C0
+:1043900001F0A4FA044608B12323D4E02B684FF0BF
+:1043A000060293F8A130A8F86420012B04BF402333
+:1043B000A8F86430D8F88C304FF006064FF4397204
+:1043C0001E805A80D8F890304FF0C4024FF001069A
+:1043D00005F5007128461E805A80063107F09EDCE4
+:1043E000D5F83C010CF028DD08B185F8CF61022337
+:1043F00085F8C0341C3385F8CB3410222B6B85F83C
+:10440000CC245B89022B02D81C2385F8CB342846A8
+:10441000214685F8CA7485F8C97485F8C874F6F31E
+:104420003BF12B68284683F8B4402146C5F8D47187
+:10443000F1F34AF185F8DC412846FFF72BFA19F031
+:10444000080F18BF85F8DC4119F0100F03D028467B
+:104450002146F1F339F119F0020F13D0AB6B83F859
+:104460004D40EB6B83F84D4095F8CB3495F8CC2458
+:1044700043EA022323F080039BB285F8CB341B0A66
+:1044800085F8CC3419F0040F03D028462146F5F303
+:104490007FF419F0800F0DD095F8CB3495F8CC242B
+:1044A00043EA022323F010039BB285F8CB341B0AA6
+:1044B00085F8CC342B6893F842308BB119F0600F3B
+:1044C0000ED019F0200F0CBFFF21002119F0400F72
+:1044D000284649B214BF00226FF0000200F068FBCA
+:1044E00006220DF122004349DDF346F5B5F882219D
+:1044F00044F221339A4217D00E3B9A4214D007332C
+:104500009A4211D010339A420ED0143B9A420BD0EB
+:1045100007339A4208D010339A4205D025339A4285
+:1045200014BF0027012700E0012705EB8706B46BC5
+:104530000DF122012846224630F06ADBB16BA06102
+:10454000886910B937230B936DE04430503128222D
+:10455000DDF312F5B36BB7F1FF3F9B699F62BFD0EC
+:10456000D8F85C30179E43F00403C8F85C30224B47
+:10457000F560B3602846ECF7C7FF1B9A0AB1002329
+:1045800013602B681D495869DEF322F230B1002117
+:104590000A46DEF3DDF01A4BC0B218602B681949E9
+:1045A0005869DEF315F230B100210A46DEF3D0F08F
+:1045B000154BC0B218602B6814495869DEF308F235
+:1045C00030B100210A46DEF3C3F0114BC0B21860CF
+:1045D00028462CE039AE820001AE820034D90100B9
+:1045E000D5A18100ADA181002D57810041578100E7
+:1045F0001957810056D80100B542820035D7010015
+:10460000EC27020041D70100102C020055D7010011
+:10461000142C02001B9B0BB9184608E00B9B1B9E39
+:104620000020336003E02846FFF78AFAF2E70DB076
+:10463000BDE8F08F20230360436040F23C73836049
+:10464000092330B50361836107330362303383622A
+:104650000F230822036340F29E3304240125002126
+:1046600042618263C3640322A3F56773C460C561BA
+:104670004462C46244630164456402654166436503
+:104680008465C265036630BD70B505460C4631B31E
+:10469000496D11B1C022E2F32BF3D4F88C1039B17B
+:1046A00028464FF43972E2F323F30023C4F88C3028
+:1046B000D4F8901031B12846C422E2F319F3002354
+:1046C000C4F89030E16929B128466822E2F310F37A
+:1046D0000023E36128462146B822E2F309F370BDC6
+:1046E00070B50D460446002800F0E580D0F8181596
+:1046F00039B128464FF48472E2F3FAF20023C4F889
+:104700001835D4F8201539B128464FF48472E2F3F5
+:10471000EFF20023C4F82035D4F8B41439B1284698
+:1047200040F2AC42E2F3E4F20023C4F8B434D4F82B
+:10473000401531B12846AC22E2F3DAF20023C4F886
+:104740004035D4F86C1229B1284607F019DE002351
+:10475000C4F86C32D4F8FC1431B128464022E2F39C
+:10476000C7F20023C4F8FC34D4F8841671B123686E
+:1047700063B1DB6953B19B690C22013303FB02F285
+:104780002846E2F3B5F20023C4F88436D4F8BC140A
+:1047900019B12846B422E2F3ABF2D4F8901421B157
+:1047A00028464FF4AE62E2F3A3F2D4F8581631B1C2
+:1047B00028463822E2F39CF20023C4F85836D4F895
+:1047C000601639B128464FF49072E2F391F200235B
+:1047D000C4F86036D4F8F81731B128460622E2F35F
+:1047E00087F20023C4F8F837D4F8D81639B1284630
+:1047F0004FF48472E2F37CF20023C4F8D836D4F884
+:10480000E01631B128462422E2F372F20023C4F804
+:10481000E036D4F8EC1631B128466822E2F368F2AB
+:104820000023C4F8EC36D4F8441731B12846EC2202
+:10483000E2F35EF20023C4F84437A16B21B12846AD
+:104840004FF40672E2F354F2616B79B1896A31B1C7
+:1048500080222846E2F34CF2626B002393622846E2
+:10486000616B2C22E2F344F200236363216821B1DF
+:104870002846FFF709FF002323602369ABB1D3F873
+:10488000F81028461822E2F333F223690026D96F84
+:10489000C3F8F86019B128465822E2F329F22846F5
+:1048A0002169FC22E2F324F226612846214640F6E3
+:1048B000D402E2F31DF270BD2DE9F0411646B82294
+:1048C00007460D4607F0FADD044610B940F2E93319
+:1048D0002BE038462946682207F0F0DDE06110B988
+:1048E00040F2044321E0FFF7A5FE38462946C022E6
+:1048F00007F0E4DD606510B940F2EB3315E03846AF
+:1049000029464FF4397207F0D9DDC4F88C0010B98C
+:104910004FF47B7309E038462946C42207F0CEDD08
+:10492000C4F8900038B940F2ED3321463360384680
+:10493000FFF7AAFE00242046BDE8F0812DE9F041F2
+:10494000174640F6D40280460E4607F0B7DD05460E
+:1049500000283BD02623C0F82838314640463A4646
+:10496000FFF7AAFF2860002800F018818F4B056030
+:104970001B683146C0F89C30FC22404607F09EDDA3
+:104980000446286110B940F2ED3306E185603146F6
+:104990004046182207F092DDC4F8F800B0B1404656
+:1049A000314658222C6907F089DDE06770B12B6928
+:1049B0004046DA6F31462C32C3F880204FF48472BF
+:1049C00007F07CDDC5F8180518B105E040F2EE33BC
+:1049D000E3E040F2EF33E0E0404631464FF48472CA
+:1049E00007F06CDDC5F8200510B94FF47C73D4E0F6
+:1049F0004046314640F2AC4207F060DDC5F8B404F1
+:104A000010B940F2F133C8E040463146AC2207F01D
+:104A100055DDC5F8400510B940F2F233BDE031462E
+:104A20004046ECF709FF0146C5F86C0210B940F2A8
+:104A3000F333B2E028461AF091D84046314640227E
+:104A400007F03CDDC5F8FC0410B94FF47D73A4E019
+:104A50002B680C22DB6940469B693146013303FB1E
+:104A600002F207F02BDDC5F8840610B940F2F533E9
+:104A700093E040463146B42207F020DDC5F8BC047F
+:104A800010B940F2F63388E0404631464FF4AE624A
+:104A900007F014DDC5F8900410B940F2F7337CE05C
+:104AA0002A464FF4AE71D5F89034CB1801F5AE71AB
+:104AB000C2F894340432B1F5AE6FF4D140463146B9
+:104AC000382207F0FBDCC5F8580610B94FF47E73A6
+:104AD00063E0404631464FF4907207F0EFDCC5F8D2
+:104AE000600638B140463146062207F0E7DCC5F8DB
+:104AF000F80710B940F2F9334FE0404631464FF421
+:104B0000847207F0DBDCC5F8D80610B940F2FA333E
+:104B100043E040463146242207F0D0DCC5F8E006E9
+:104B200010B940F2FD3338E040463146682207F0C4
+:104B3000C5DCC5F8EC0610B940F2FE332DE0404666
+:104B40003146EC2207F0BADCC5F8440710B940F250
+:104B5000FF3322E0404631464FF4067207F0AEDCE8
+:104B6000A86358B100F58673EB63404631462C22AA
+:104B700007F0A4DC0446686318B105E040F2014385
+:104B80000BE040F2024308E040463146802207F045
+:104B900095DCA06238B940F203433B6028464146A9
+:104BA000FFF79EFD00252846BDE8F081BC260000E9
+:104BB000D0F84031B1F1FF3F18BF83F89C13B2F138
+:104BC000FF3F83F89E1383F89F2318BF83F89D232C
+:104BD0007047C04670B50446002831D000256319DF
+:104BE000D3F8501221B12368F4225868E2F380F020
+:104BF0000435282DF3D1A16B69B194F8A3331BB10F
+:104C000023689868EAF32AF52368A16B9868EAF3A9
+:104C100037F50023A363D4F8781221B12368E82282
+:104C20005868E2F365F02368064918682246FFF3E6
+:104C30008BF12368214658684FF46A72E2F358F00A
+:104C400070BDC046678986002DE9F0434FF46A7154
+:104C500085B006464068E2F33BF0054608B9814658
+:104C6000CFE000214FF46A728146DDF3E9F12E6056
+:104C70007068E821E2F32CF0C9F87802002800F00F
+:104C8000B1800021E822DDF3DBF1002101236A1865
+:104C9000C91808299372F9D1013B2B746B742B73DB
+:104CA000EB721A460121AB185218082A83F89413A4
+:104CB000F8D11023EB74062385F827304FF0FF332B
+:104CC00085F82830213385F8A233052385F829306B
+:104CD0004FF47A736B864FF0C803AB86002385F8D8
+:104CE0002A30023385F82B302B682A75A9741B688B
+:104CF0002A4693F8A1308B4218BF032385F82C3045
+:104D00004FF0FF3385F89E3385F89F334FF40063EF
+:104D1000EB63012385F82D3004336B750223AB75EB
+:104D20006B7DD375AB7DD377013205F108039A42D1
+:104D3000F6D100244FF0010895F82910284685F88F
+:104D40002E4085F82F8007F09DDE284686F8C38424
+:104D500009F0B8DC042130462C4A2D4B0094019513
+:104D600005F0ECFFA04268603CDB2A4B3068009302
+:104D7000294B2A4901932A4B2A4A03932B46029432
+:104D8000FFF3AAF0074668BBB06827492A463B46AE
+:104D9000EAF392F4A86328B3244C85F87C82231D9F
+:104DA00093E807006B4683E807002A4623683046ED
+:104DB000062105F05BDF4FF0FF3385F8A133336840
+:104DC000284693F842100AF0DDDCC823C5F8E0322B
+:104DD000284609F0BDDE28464146ECF7CBFB85F8B6
+:104DE000A3730EE0D5F8781219B17068E822E1F3E8
+:104DF0007FF7706829464FF46A72E1F379F74FF054
+:104E00000009484605B0BDE8F083C04695CB820056
+:104E10001DCB820045CF820011E7820054D90100EA
+:104E200079D982006789860085A2000044D90100F3
+:104E300070B5182686B00C46324668460549DDF343
+:104E40009BF02046694632466D46DDF395F006B08C
+:104E500070BDC04634DB010070B5D0F8AC530446D9
+:104E6000D0F8B063284603F09DFFD4F8D013A868AB
+:104E7000EAF3F4F3A868D4F8D013EAF301F40023BA
+:104E80002246C4F8D03330460449FFF35DF0F068A1
+:104E900021464FF47E72E1F32BF770BDAB9986008B
+:104EA0002DE9FF413C23C1F824370523C1F82837F9
+:104EB00007460D46C0684FF47E71E1F309F70446DA
+:104EC00000283DD000214FF47E724FF00008DDF342
+:104ED000B7F0C4F8AC53C4F8B07384F8018020462E
+:104EE000E5F752FAC4F8C003284603F071FF0646FE
+:104EF00038B1F86821464FF47E72E1F3F9F6404686
+:104F00001FE0204604F56371FFF792FFA8680E4981
+:104F100022463346EAF3D0F3C4F8D00380B12046EA
+:104F20000DF054DC094B38460093094B09490193B5
+:104F3000094A234602960396FEF3CEF7204600E088
+:104F4000002004B0BDE8F0818D25830011B400007D
+:104F5000190F0100E4D90100AB99860010B5044691
+:104F60000846B0F80CE0194642F256039E4506D8B2
+:104F7000013B9E452ED2053B9E4509D02AE042F2D8
+:104F800060039E451BD04EF2F5439E451CD021E0A8
+:104F9000C389012B04D16FF03B0313604B3303E053
+:104FA0006FF0450313605A330B602368D3F88030E9
+:104FB00013F4805F13D01368023B13600FE06FF0AF
+:104FC0004A0313605A3309E06FF09503136003F549
+:104FD000967303E06FF04A0313605F330B6010BDFC
+:104FE00070B504460025E06820B1054B1B68984762
+:104FF0000023E36001350434062DF4D170BDC046B2
+:10500000E0A685000D4B82685362002380F886304D
+:105010004FF00303A0F88C304FF00203A0F88E305D
+:105020004FF00703A0F888304FF00403A0F88A304F
+:1050300042F60133A0F89C307047C04664A8E7BE32
+:10504000426C1F2A01D9002004E04FF00073134185
+:1050500003F001007047C046026EB0F84A1010B568
+:10506000946AB9B1FF2901D8012014E00B0B013B70
+:10507000012B0FD8C1F30323092B0BD853B1C1F374
+:105080000313092B06D801F00F03092B8CBF002056
+:10509000012000E00020D26A41F2E4439A4210D19C
+:1050A000A4F58263073B012B01D83F2907E040F2BA
+:1050B0000C439C4204D015339C4202D1502900D8A5
+:1050C000002010BD00B58E46C16E4FF0407394466F
+:1050D0007046C1F8603115E00379C2781B0443EAD9
+:1050E000026382791343427943EA0223C1F86431AF
+:1050F000437802781B0243EA024382780730134365
+:10510000C1F86431CEEB00036345E5D300BDC04672
+:10511000C16E4FF48030C1F860011D4AD1F8603192
+:1051200010B5D1F86441C1F86001D1F86031C1F81F
+:105130006421C1F86001D1F86031D1F86431934243
+:1051400024D1144AC1F86001D1F86031C1F864215A
+:10515000C1F86001D1F86031D1F86431934215D1C2
+:10516000C1F86001D1F860310023C1F86441C1F891
+:105170008C31D1F82001084B984201D1012006E082
+:10518000064B984214BF0020012000E0002010BD13
+:10519000AA5555AA55AAAA55000400040004008483
+:1051A000D0F8501810B5044641B1D0F84C284068EA
+:1051B0009200E1F39DF50023C4F85038D4F8481864
+:1051C00059B16068DDF3F0F46068D4F84818E8225B
+:1051D000E1F38EF50023C4F8483810BD70B50469BA
+:1051E0000646206E08B1EAF729FB2046FFF7F8FED5
+:1051F000A56F686A18B104F035F800236B62606F20
+:1052000003F0C2FF206F05F05BFC616E29B12068DE
+:10521000A26EE1F36DF500236366206E18B103F012
+:1052200021FB002323662046E7F7C4FF3046FFF743
+:10523000B7FF002070BDC0462DE9F04F0368076935
+:105240008FB00890DE691446FB6B0CA80821704AE9
+:10525000DCF33AF7FB68002B40F0CE80F96E386E35
+:1052600001F50071D7F800B0DFF31EF3BB6801460B
+:105270009868EAF3B7F1002800F0C680D7F860E03C
+:105280000CB9A44602E0FB6E03F5007CFB6E03F54F
+:10529000087504B13468B168BB687268F068D3F807
+:1052A000283803915B490DF130094FF0FF38029225
+:1052B0000590724606930791634649465846009505
+:1052C0000194CDF81080ECF735F93168F8603A6E4A
+:1052D000FB6E01914F4900240546079103F51073B9
+:1052E00049465846009402940394CDF810800594E2
+:1052F0000694ECF71FF9316838613A6EFB6E019144
+:1053000044490990079103F5207349465846009493
+:1053100002940394CDF8108005940694ECF70AF9F2
+:10532000316878613A6EFB6E01913A490A900791B3
+:1053300003F5307349465846009402940394CDF81F
+:10534000108005940694ECF7F5F83168B8613A6E70
+:10535000FB6E01912F490B90079103F5407349466D
+:105360005846009402940394CDF810800594069456
+:10537000ECF7E0F83168F8613A6EFB6E019125496F
+:105380008246079103F550734946584600940294AB
+:105390000394CDF8108005940694ECF7CBF8099AA5
+:1053A000A54214BF002501250A9BA24208BF45F073
+:1053B00001050B99A34208BF45F00105A14208BFB2
+:1053C00045F00105A24508BF45F001053862A0423D
+:1053D00014BF284645F00100B0B90F4B3C46D3F846
+:1053E00084600546E06818B10C49B047C4F8A000D5
+:1053F00001350434062DF5D1B96F08980831002223
+:10540000E7F714F9012000E000200FB0BDE8F08FAD
+:10541000FB41860014260000E0A68500C326860016
+:105420001FB5022303930C330446C0F84C383821CF
+:105430004068E1F34DF4C4F85008D0B1D4F84C28DA
+:1054400000219200DCF3FCF56068E821E1F340F410
+:10545000C4F8480868B10021E822DCF3F1F5012323
+:1054600000936068D4F8481803AAB333DDF334F42A
+:1054700001E04FF0FF3004B010BDC0462DE9F04F01
+:10548000056997B0DDF884A014469B469DF88020FE
+:10549000EB63EB6FA860AB672A710746C5F800A005
+:1054A00028460E46FFF7AEFD249B05F1640205F188
+:1054B000680100930192029120465146229A239B53
+:1054C00003F00EFB2866002800F0D581D5F8648033
+:1054D00095494046DDF37CF220B100210A46DDF318
+:1054E00037F186B240469149DDF372F248B10021AE
+:1054F0000A46DDF32DF14FF6FF7380B2984218BFD4
+:10550000044630462146FDF7F9FF08B90C30B7E1F3
+:1055100040F612010022A5F84060A5F84240286E2E
+:10552000E5F36CF6E866286EE5F3BAF4D5F86C900E
+:105530006864C7F80C902846FFF782FD08B90D3063
+:105540009EE1286EEAF77EF92846002116F0C4DBBA
+:1055500028464FF0FF31E7F7A7F82846FFF7D8FDB8
+:1055600008B90E308CE140467149DDF305F2FF28A1
+:1055700008BF0120A5F84A002846FFF76DFD08B9CD
+:105580000F307DE16B494046DDF3F6F16A4985F85D
+:1055900048004046DDF3F0F16849E8644046DDF339
+:1055A000EBF1296E2865CA6A41F26B039A420AD16F
+:1055B0008B6A4E2B07D1B5F84A30402B03D9EB6CE0
+:1055C00043F00203EB64EB6C13F0200F04D00121D5
+:1055D00028460A4617F036DFB5F840200123A7F821
+:1055E0008021C5F89830B5F842303A68A7F8823182
+:1055F0002B6E284613616B6C936095F8483082F8E7
+:105600007C303A68B5F84A30B968A2F87A30EB6C69
+:10561000C2F880302B6DC2F88430D5F898305362D0
+:105620003A4605F057FA286708B9193028E12B6E79
+:10563000CDF810A005932B6FCDF81CB0B5F8402025
+:1056400006936B6CADF8302008932A6EB5F84230A3
+:10565000CDF82C80ADF83230936B04A80D93D36B4A
+:105660000E93136C0F9395F848301093936A11932F
+:10567000B5F84A301293D36A1393EB6C14932B6DE5
+:10568000159353680993D3680A9303F085FD6867FF
+:1056900008B91030F4E0B5F8421044F221339942D1
+:1056A00017D00E3B994214D00733994211D01033D2
+:1056B00099420ED0143B99420BD00733994208D03F
+:1056C0001033994205D02533994214BF0026012694
+:1056D00000E0012631462846E6F7CAFFAA6F002EF1
+:1056E0000CBF02230123136056603A6B286E1360CF
+:1056F0005660FC6AE5F3C2F32060D9F85C31696C4E
+:105700000F4A6B65AB65062301FB0323AC6FC5F83D
+:10571000B830686F49462268434603F0D5FE6062A0
+:1057200080B91130ACE0C046D1AD86004837860064
+:1057300084AE8600E5AE8600863786009E798600B8
+:10574000301E0200AB6F696D586AEDF747FBAB6F17
+:1057500003F1220203F11C01586A009203F11E02B8
+:10576000203303F0F9FCAC6F606A03F005FD84F8A8
+:105770002800AB6F3C6B586A03F0FEFC2075AC6FE1
+:10578000606A03F0FDFCA96FA061CB8B032B01D0F5
+:10579000122075E03B6B4A6A38461A618A8B1A817F
+:1057A000CA8B5A810A8C9A814A8CDA8140F2FF3284
+:1057B0004FF00F03CA828B8201223146FFF73CFD76
+:1057C00008B913305CE0B6F1FF3F3FF464AFAB6F54
+:1057D0003A68586A92F89910EDF704FB00212846C0
+:1057E00016F062DF08212846E7F772F8284618F01D
+:1057F00093DA286E2449254A00230097E5F3BAF48A
+:105800002846002118F06ADA2846E6F7FBFE08B9B8
+:10581000153035E005F1DC042146DCF3CDF62046F9
+:10582000DDF38AF048BB2046DDF396F0044620BB4A
+:10583000284616F099D8AB681B68D3F89C00F0B1E5
+:105840000378E3B112492A46DDF39AF1AB681149B6
+:105850001B682A46D3F89C00DDF3CCF1A868FFF75B
+:10586000DFFDE86858B1AB681B68D3F89C10DFF324
+:10587000BFF1204604E00B2002E0162000E00020EB
+:1058800017B0BDE8F08FC04669C1830085C18300B1
+:1058900025C0830049C0830010B590F85E300446EF
+:1058A0005BB90648EBF700FF054B20461A6805492F
+:1058B000FFF708FC012384F85E3010BD67DB0100B0
+:1058C000FC580300A4D2020010B5044619F058DFBA
+:1058D00001220146204619F0CBDF10BD37B5054641
+:1058E00019F04EDF0023C5F84C0280F848302A68D2
+:1058F000044692F82F10284600914E32214618F0A7
+:10590000EDDC30B12846214619F096DD4FF0FF302E
+:1059100003E02846214619F035DE3EBD37B5044682
+:10592000002847D0D0F8201131B103689868E9F316
+:10593000A7F60023C4F820312268136893F82F30AB
+:105940003BB3D2F8000501A92FF0C4DB13E0536884
+:1059500013F0400F0FD0D4F82C31D51807E00B68A6
+:105960004822C5F8103123685868E1F3C1F1D5F831
+:1059700010110029F3D101A82FF0B4DB0246002852
+:10598000E5D106E00B684068C4F840314822E1F3F5
+:10599000AFF1D4F8401120680029F3D1064922461E
+:1059A0000068FEF3D1F22368214658684FF4A472D0
+:1059B000E1F39EF13EBDC04691BA8600F0B54FF4CA
+:1059C000A47185B005464068E1F382F1064608B946
+:1059D000074655E000214FF4A4720746DCF330F38C
+:1059E000294B35600093294B29490193294B002409
+:1059F00003932868284A33460294FEF36DF2314639
+:105A00002A6B1368022B03D1537D0BB9163300E0C8
+:105A1000302301340B744431042CF1D1A8681F49A0
+:105A20002A460023E9F348F60446C6F8200130B9B7
+:105A3000686831464FF4A472E1F35AF11FE04FF465
+:105A40009673C6F81C3145F27353A6F838314FF0FF
+:105A50004603A6F83A31124B0024C6F840412846C6
+:105A600000934FF48A710F4A0F4B019505F066F9C8
+:105A7000A042C6F82C0103DA3046FFF74FFF274655
+:105A8000384605B0F0BDC046F90C8400DD120100B7
+:105A900094DB01007D0A840091BA86003D068400F3
+:105AA000D9128400E5128400A512840010B50146C5
+:105AB00020B10368B022D868E1F31AF110BDC046E6
+:105AC0002DE9F34107680546B021F868E1F300F1DC
+:105AD000064608B980468BE00021B02201AC804622
+:105AE000DCF3AEF20422002137607560C5F85C611A
+:105AF0002046DCF3A5F22A6892F87C30012B07D906
+:105B00003D495069DCF364F7014690B120460AE054
+:105B100050693A49DCF330F70928034609D8384977
+:105B2000204601EB83010322DCF342F300238DF8CE
+:105B3000073001AC0322214606F10800DCF338F3FC
+:105B40000023F3722B682F495869DCF315F7396984
+:105B5000F060CA6A41F26B039A420CD18B6A8B2BBC
+:105B600009D1022807D1204627490422DCF300F39B
+:105B700008B90323F360396941F26B03CA6A9A4298
+:105B80000DD18B6A932B0AD101A820490422DCF3A2
+:105B9000EFF220B9F368042B01D10233F36001AFB7
+:105BA000284639461FF054DE044650B91849384695
+:105BB0000322DCF3FDF2284639468DF807401FF03A
+:105BC00047DE05F5AA60394603220A30DCF3F0F21D
+:105BD000002405F5AA600F4985F85D450E300322C3
+:105BE000DCF3E6F285F861453046394620F0BADA52
+:105BF0004046BDE8FC81C046B3C48600B9C48600F7
+:105C0000CE028600BCC48600C3C4860071C2860072
+:105C1000C6C48600CAC4860070B50568044622461C
+:105C200028680449FEF390F1686821465022E1F3A8
+:105C30005FF070BD3CE486002DE9FF410546502130
+:105C40004068E1F345F0064608B904465AE00021F1
+:105C500050220446DCF3F4F1FF210422356006F102
+:105C60003B00DCF3EDF1284619F08ADD002790F8BF
+:105C7000483080F8387586F83B3096F840304FF061
+:105C8000FF3843F00803202186F840301F4AC6F849
+:105C9000488006F11800DCF317F27061304626F0F8
+:105CA000B5DF042128461A4A1A4B0097019605F0E1
+:105CB00045F8B84230611FDB174B02970093174B32
+:105CC00017490193174B184A039328683346FEF38C
+:105CD00003F188B9012586F83A50304629F00ADAEE
+:105CE00018B13046294627F0FFD9A37BA4F84C8091
+:105CF00043F00203A37305E0686831465022E0F3E5
+:105D0000F7F70024204604B0BDE8F08140E48600A7
+:105D10001DDF8400F9DE8400F51D01001DED840007
+:105D200024E40100DDD084003CE4860070B5054623
+:105D3000002826D00368134918682A46FEF304F1A8
+:105D40006B6905E01C68596828462AF0E7DD2346A0
+:105D5000002BF7D12B6905E01C68596828462AF00A
+:105D6000DDDD2346002BF7D1A96A21B12B689022F3
+:105D70005868E0F3BDF72B68294658682C22E0F3F9
+:105D8000B7F770BD91E6860030B52C21044685B08A
+:105D90004068E0F39DF708B9054618E000212C2281
+:105DA0000546DCF34DF10823AB610A4B2C600093F0
+:105DB0000023019302930393074A2B462068074967
+:105DC000FEF38AF02268012382F896302B71284670
+:105DD00005B030BD050B850091E6860004E50100A5
+:105DE0002DE9F047154680460F461E46E5F346F07E
+:105DF000002181464046E5F313F200220446114695
+:105E00000F480B185B6873B90C3302FB03F31D508A
+:105E10001A18636A576096600A4A45EA03031360DA
+:105E20006362012404E001320C31052AE8D1002428
+:105E300040464946E5F3F4F12046BDE8F087C04608
+:105E40003C260000782600002DE9F04705468846EC
+:105E5000E5F350F100212846E5F3E2F10646284635
+:105E60006C69AF69E9F7E8FA0A2C814616D90F2C5C
+:105E700019D02846E9F768FD142C054603D9B36804
+:105E800023F00803B360B36843F00103B36003D9A0
+:105E9000B36843F00803B360012211E0022C02D87A
+:105EA000174D30220CE02846E9F758FDD6F8A4300B
+:105EB000054623F0FF0343F00203C6F8A430022294
+:105EC000B36813F0010F07D107F01803082B14BFB4
+:105ED0004FF4E115B5FBF2F507F0030700240BE0E2
+:105EE00006F54073B8F1000F05D003EB04204946D6
+:105EF0002A460023C0470134BC42F1DBBDE8F087ED
+:105F000000C63E0537B5134B1546136001E0114B33
+:105F100013600432ADF17C039A42F8D3033020F0D1
+:105F200003000D4BC0EB01041C600C4B00211960F9
+:105F30000B4B05F5A05219600A4B083C19600A4B3F
+:105F400041601D60094B1A60094B1960094B0460E0
+:105F500058603EBD4B415453C826000088260000BF
+:105F6000A4260000CC260000F8270200FC2702002F
+:105F700090260000C0260000436910B5142B01DDF7
+:105F800002F09CFB10BDC0461FB5E8200021E0F3E5
+:105F90003DF20C4C2060A0B10021E822DCF350F06F
+:105FA00004AA012342F8043D013B0093064B2168FB
+:105FB000186840F23C73DCF38FF620680E21DCF3A6
+:105FC000D5F61FBDBC26000024280200B1F5E06F05
+:105FD00073B505460C46164606D1036900910021AB
+:105FE00001911C680A460CE00D4B00221868E5F38D
+:105FF00005F1014680B12B690022009401921C68D2
+:1060000028463346A04738B1064AA86113680020E5
+:106010002B626E61156001E04FF0FF307CBDC04621
+:106020008C260000202802002DE9F04710200E46A3
+:10603000002117469946E0F3E9F1044610B96FF0E4
+:106040001A001EE0104D2868E4F318F7099B8046FB
+:1060500023B9286831463A46E5F3D0F02868E4F3DE
+:1060600089F701238340094AE360089BC4F8049040
+:10607000A36013682868236041461460E5F3D0F0FC
+:106080000020BDE8F087C0468C260000982600005E
+:1060900007B50021E5F3C4F0074B4FF40061186029
+:1060A000064B00F57060186000200246044B00901B
+:1060B0000190FFF7B9FF0EBD9C260000F4270200F7
+:1060C0006D60800037B5234B234C02AD00211C22AC
+:1060D00045F8043D2046DBF3B3F7012323601F4B53
+:1060E000A5F5A0551B6843F8044C00F00DF92946AE
+:1060F0002A461B48FFF706FFE0F344F300F042F89E
+:10610000002002F01FFA174B174C186002F0BCFC7D
+:106110002060FFF7BDFF206800F01EF9E9F716F8D0
+:10612000206800F0A5F8002210481149E0F3E2F4DD
+:10613000002210481049E0F3DDF410490022104815
+:10614000E0F3D8F42068FFF717FFFFF71DFF206882
+:106150003EBDC046ADDEADDE00280200F81E0200E6
+:1061600000590300242802008C260000D81F860056
+:1061700059EF0000DB1F8600656580008D608000A0
+:10618000DE1F860070B5A4200021E0F33FF1124D20
+:10619000286080B10021A422DBF352F74FF4806025
+:1061A00000212C68E0F332F1A060286884682CB9E3
+:1061B000E0F392F02C604FF0FF300CE04FF480627F
+:1061C000C2608460446100212046DBF339F72A680D
+:1061D000024B00201A6070BD38280200D42600004F
+:1061E00070B51C4D06462B6833B91B4C23680BB9A0
+:1061F000FFF7C8FF23682B60164C184B20685861C6
+:1062000030B3002505604560336CC0F89C500E3BF0
+:10621000012B03D930461249FFF716FE114A936845
+:1062200013B12368C3F89C20246807E0D4F89C00CD
+:1062300018B1A368595DE0F349F4013523699D4223
+:10624000F4D3094809492246E0F354F4014B186895
+:1062500070BDC046D4260000382802000028020085
+:106260009562020028280200BD218600A5688000F2
+:1062700010B54022002305490446FFF7B1FD044B49
+:1062800000229A602046FFF7ABFF10BDA96980008D
+:106290002828020070B51B4DAE68002E31D11409BC
+:1062A0002C60AB8104F561444FF4E13394FBF3F4CB
+:1062B000A8606960284603218022E0F3FDF32846A8
+:1062C0003146E2B2E0F3F8F3284601212212E0F36E
+:1062D000F3F303210A462846E0F3EEF301210A46D0
+:1062E0002846E0F3E9F3284604210822E0F3E4F32A
+:1062F000284602210122E0F3DFF34FF47A70E0F345
+:106300002BF270BD28280200104A0721136843F0C1
+:1063100010031360136843F008031360136823F439
+:1063200000731360E832136843F0807343F48033E2
+:106330001360074B00221960043B1A6008331A6887
+:106340001960044B20221A607047C04614ED00E02B
+:10635000241000E000E400E02DE9F041054600F0E3
+:10636000ADF82A48E8F778FC2846E9F73BF8284BCF
+:10637000284AC318B3FBF2F3274A28461360E9F70B
+:10638000D9FA00F5787007304FF47A73B0FBF3F068
+:10639000224B234A18602B6A2249002BCCBF6FF096
+:1063A0007F4340F2FF3313601D4A1F4F1368B3FB56
+:1063B000F0F31360284620220023FFF711FD002090
+:1063C0001A49DCF3D9F204463860E8B12846E9F707
+:1063D00009F8B4FBF0F0861E002E15DD144C0021E8
+:1063E00034222046DBF32CF6124B4FF47A71A36073
+:1063F0006560204606FB01F10122DFF3FBF618B1D0
+:1064000028463968DEF306F2BDE8F08191F100001C
+:106410003F420F0040420F00D0250000C825000079
+:10642000CC25000001678000E8260000BEE60100E0
+:1064300040280200E56680002DE9F04707461E4629
+:1064400015460C46E4F356F63846E4F317F52946AC
+:10645000324681463846E4F3D1F63846E4F38AF50D
+:1064600040F62A01064600223846E4F3C7F6054600
+:106470008CB1012414FA06F3826932EA030802D1CE
+:106480002046E8F7A9FB701C14FA00F0E8F786FB39
+:10649000C5F818800CE00124701C14FA00F0E8F72D
+:1064A0009BFB2046B440E8F779FBAB691C43AC6129
+:1064B00038464946E4F3B4F6BDE8F0872DE9F047E5
+:1064C0000746E4F317F6384640F60E010022E4F3DF
+:1064D00095F60446002831D0D0F80080056838468B
+:1064E000E4F3DEF40428064604D827D1C5F30243BA
+:1064F000032B23D100204849DCF33EF2F0B9474991
+:10650000C8F3031212E0013A072E22610AD90C2EB9
+:1065100008D0236C13F4806F02D013F4006F01D104
+:1065200008B903E0012041F004516161002AEAD179
+:10653000D4F8E83123F01003C4F8E831002240F623
+:106540002A013846E4F35AF6354C20603846E4F325
+:10655000A7F4344B22681860136843F6A12443F073
+:1065600080731360136843F0020313600023C2F8C2
+:10657000E03103E00A20E0F3EFF00A3CDFF8A090FE
+:10658000D9F80030D3F8E03113F4003F01D1092CE1
+:10659000F0D100210B4638464FF40062FFF74CFF64
+:1065A00000210B46384640F61202FFF745FF002156
+:1065B0000B46384640F62902FFF73EFF38460121D8
+:1065C000E8F73EFF00201849DCF3D6F1E0B1384689
+:1065D000E4F354F440F62A01804600223846E4F3FE
+:1065E0000DF646690446D0F898503846E4F346F470
+:1065F0000123834045F00105334363613846C4F805
+:1066000098504146E4F30CF6D9F80020136A43F0A1
+:1066100003031362BDE8F0872DE70100FF7F01004F
+:106620007428020078280200BEE6010010B58469D3
+:10663000A068FCF729FCE068E9F7E4F8002010BD49
+:1066400010B584690021342204F11C00DBF3F8F456
+:10665000034BA06863622462EBF794F8002010BD3E
+:1066600005AA80002DE9F347DFF8AC809946D8F8F9
+:1066700000300546072B0F46924643DC01F062FFCF
+:1066800050210646E0F324F3044600283AD00021C6
+:106690005022DBF3D5F4D8F8003065602360A4F80D
+:1066A00014902761E660204641F2E4414A463346B1
+:1066B0000097CDF804A0FCF739FCA06010B30020CF
+:1066C0000A990B9A114B0095CDF804A0FFF7ACFC8A
+:1066D00018B1A068FCF7D8FB14E0A068E2F3B4F6A8
+:1066E0000B49A061D8F800202846DBF3FDF40948E7
+:1066F0002946EAF7D9FFD8F8003020460133C8F818
+:10670000003000E00020BDE8FC87C04631AA8000D0
+:106710005CB102003CB102007C280200014610B5C9
+:1067200050228068E0F3E4F210BDC046C36B10B5A0
+:106730001BB100225A62836B5A62C068FFF7EEFFFA
+:1067400010BDC0462DE9F041184E1C46337807466F
+:10675000072B904626D820464C21E0F3B9F2054697
+:1067600000B300214C22DBF36BF46C602F60C5F8A2
+:1067700008803378204685F8443001333370022393
+:10678000AB640821E0F3A4F20446286420B10021A0
+:106790000822DBF355F406E029464C22E0F3A8F288
+:1067A000254600E000252846BDE8F081802802004B
+:1067B0002DE9F04FD1F8FC3091B00F93054603F569
+:1067C0006063079335E10FAF0E2200232846394658
+:1067D000D9F37AF60F28044600F0368100222846C5
+:1067E00039461346D9F370F610F00E0640F02681B4
+:1067F00040F23B43B3EB145FC4F30B21C0F3041826
+:1068000004D140F6FF73994200F01381C0F3442293
+:106810000992002A00F00D81C0F3C443C0F3843B09
+:1068200013EB0B02089319D140F26733994240F001
+:1068300000810EAB01930DAB02930CAB03930BAB3A
+:1068400004932846394613460092D9F3DBF5002815
+:1068500000F0EF800E9BC5F85433EAE0D5F8CCA0E9
+:1068600005EB8A03C3F8D4423446C3F81403C3F8D3
+:10687000D0100BE00122284631461346D9F324F606
+:1068800000F00E00022840F0D980013444450FAEDC
+:10689000F0D1002213460DF138090DF134080CAF88
+:1068A0000BAC284631460092CDF80490CDF8088014
+:1068B00003970494D9F3A6F50246E8B94023009360
+:1068C000284631461346CDF80490CDF8088003974A
+:1068D0000494D9F397F510B14FF001080EE00D9B29
+:1068E000002B40F0AB800B9B002B40F0A7800C9B53
+:1068F000B3F5805F40F0A2804FF000080E9A05EBE0
+:106900008A03C3F810210C9A0124C3F8D0210EABDE
+:1069100001930DAB02930CAB03930BAB00220493DA
+:1069200028460FA923460092D9F36CF508B9012730
+:1069300027E0012C40F086800C99B1F5805F40F093
+:1069400081800E9B05EB8A02C2F89031C2F81012CA
+:1069500078E00024002300930EAB01930DAB02936B
+:106960000CAB03930BAB049328460FA93A4623467E
+:10697000661CD9F347F508B13446EBE7002E5DD02D
+:106980000137099A9742E4D100241FE0C023009305
+:106990000EAB01930DAB02930CAB03930BAB0493C3
+:1069A00028460FA922460023D9F32CF5002845D00C
+:1069B0000B9B002B42D10C9BB3F5805F3ED124B9D9
+:1069C0000E9B05EB8A02C2F8943201345C45DDD19E
+:1069D000002423E0802300930EAB01930DAB0293C0
+:1069E0000CAB03930BAB049328460FA9012F0CBFEC
+:1069F0002246621C0023D9F305F5F8B10B9BEBB9D5
+:106A00000C9BB3F5805F19D1BBF1000F05D124B900
+:106A10000E9B05EB8A02C2F894320134089B9C421B
+:106A2000D8D1B8F1000F04D1D5F8CC300133C5F876
+:106A3000CC300F9B079A9342FFF4C5AE0023C5F8F4
+:106A4000CC3001E0013462E711B0BDE8F08FC04600
+:106A500082604160016070470EB4F3B581680646FC
+:106A6000012901D8002044E008AB4068079A01934F
+:106A7000DBF31CF4B0F1FF3F074603D0B368023BE1
+:106A8000984203DD00231846B36032E070683D2170
+:106A9000DBF33AF330B373683568C3EB00041EE0F0
+:106AA00028462246DBF34CF2A8B92B5D3D2B12D1D0
+:106AB0002846DBF355F37268441CBA1829190132D1
+:106AC0002846521ADBF38EF273681B1B7360B3689F
+:106AD0001B19B36006E015F8013B002BFBD1716870
+:106AE0008D42DDD3B368781C1B1AB36073681B1822
+:106AF0007360BDE8FC4003B07047C0462DE9F0412B
+:106B0000C1EB0204012C0E461F46DDF8188010DD93
+:106B10002146E0F3DDF0054610B96FF01A000DE0F4
+:106B200031462246DBF328F200203D60C8F80040E1
+:106B300004E000233B60C8F800301846BDE8F0814F
+:106B40002DE9F04FA5B008914FF4805109900792BC
+:106B50000693E0F3BDF00A9018B96FF0010401F05C
+:106B600029B921A80A994FF48052FFF771FF4FF419
+:106B700080520A980021DBF363F200234FF0FF32CA
+:106B80008DF844300B930D930E9201F0DEB80D9BFF
+:106B9000089A002152F8239001230C910F930F9B28
+:106BA00019F8012073B1531EDBB2FD2B01F101086E
+:106BB00098BF19F808B016468CBF4FF0000B08F1CB
+:106BC00001080CE002F1FF33DBB2FE2B93462CBF31
+:106BD0001646802628BF4FF0000B01F101080BEB91
+:106BE0000803B3F5607F81F2AD80202E2AD005D84E
+:106BF000152E0AD01B2E6DD001F078B8222E3AD077
+:106C000036D3802E72D001F071B808EB09035A78A0
+:106C100019F8083003EB0223072B13DD09F10204F6
+:106C2000444421AD874922462846FFF715FF2046F8
+:106C3000DBF396F209F1030200EB080382492846D0
+:106C4000D2184FE008EB0904637819F8082021AD49
+:106C500002EB032228467D49FFF7FEFEE378A27887
+:106C600028467B4902EB0322FFF7F6FE01F03EB80F
+:106C700019F8082003E00C9B0C2B03D100220C9286
+:106C800001F036B89DF84430002B41F0318019F8FE
+:106C90000830042B41F02C8009F1020404EB0805B4
+:106CA0002846DBF359F6002841F0228014F808301A
+:106CB00013F0010F41F01C80284611A9DBF394F476
+:106CC0000E9BB3F1FF3F41F0138008EB09039A7963
+:106CD000DB790DE108EB0903DC799A795D4921A89C
+:106CE00042EA0422FFF7B8FE01F002B819F80830B2
+:106CF000822B00F2FD87DFE813F09200B300380129
+:106D00003B02D4021102CB01DA014701EA02FB0285
+:106D100010031703FB077F020302FB073603570329
+:106D200097007A037F0390039503F700E903FB07BD
+:106D3000770107047F01FB07FB07FB071004220410
+:106D4000270472045305FB07FB0721068D0088000A
+:106D50008300AE06D306DA06E106FB0726037101BF
+:106D6000FB07FB070001F007E806FB07FB07FB0733
+:106D7000FB07FB07FB07FB07FB0787011307280738
+:106D8000490764077F079907B307CD07D407FB07B7
+:106D90008E01FB07FB07FB07FB07FB07FB07FB0756
+:106DA000FB07FB07FB07FB07FB07FB07FB07FB07D3
+:106DB000FB07FB07FB07FB07FB07FB07FB07FB07C3
+:106DC000FB07FB07FB07FB07FB07FB07FB07FB07B3
+:106DD000FB07FB07FB07FB07FB07FB07FB07FB07A3
+:106DE000FB07FB07FB07FB07FB07FB07FB07FB0793
+:106DF000FB07FB07FB07FB07FB07FB07FB07DE07A0
+:106E000009EB0804002500F00BBE09EB080400257F
+:106E100000F0F4BD09EB0804002500F0DEBD0E49CA
+:106E200008EB090321A8DDE008EB0901CA780B791A
+:106E3000120442EA03624B7821A81A438B7807496F
+:106E40007EE2C04640B202009CB40200FEB10200E5
+:106E500093B5020062B80200D9B3020075B1020016
+:106E600008EB0904A378627821AE02EB0322AE4955
+:106E70003046FFF7F1FD2379E2783046AB4902EB6B
+:106E80000322FFF7E9FDBBF1060F40F23187A3793A
+:106E900062793046A64902EB0322FFF7DDFDBBF124
+:106EA000080F40F22587237AE2793046A14902EBA8
+:106EB0000322FFF7D1FDBBF10A0F40F2198709F158
+:106EC0000A0409F1090514F8083015F808209A4950
+:106ED00002EB03223046FFF7BFFD14F8083015F827
+:106EE0000820964930464CE008EB09039A785B7815
+:106EF00003EB02220E9200F0FBBE0623904ABBFB7E
+:106F0000F3F309EB08074FF0000A137027E019ADFF
+:106F1000534610218B4A1DAE2846DBF3D5F053466D
+:106F20001021894A3046DBF3CFF0BB787A7821AC68
+:106F300042EA032229462046FFF78EFD7A79BB7983
+:106F4000120442EA0362FB7820461A433B79314639
+:106F500042EA0322FFF780FD0AF1010A0637784B67
+:106F60001B789A45D3DB00F0C3BEBBF1020F21A80A
+:106F700008EB090202D175495278B3E69378734958
+:106F8000527802EB0322ADE608EB0904A27863789D
+:106F9000BBF1040F03EB022505D92379E2781B0628
+:106FA00003EB02431D4321AE304669492A46FFF7F1
+:106FB00053FDBBF1060F40F29B86A2796379BBF1CA
+:106FC000080F03EB022505D9237AE2791B0603EBB0
+:106FD00002431D435F4930462A4683E65E4908EB7B
+:106FE000090321A85A787DE608EB09039C785A78B2
+:106FF000524921A800F05BBE0BF101035FFA83FB4D
+:1070000000230F9300F074BE08EB09039C785A78B4
+:10701000524921A864E64A4B4FEADB0209EB080714
+:107020004FF0000A1A702DE01DAD53461021454A5D
+:1070300019AE2846DBF348F053461021424A304649
+:10704000DBF342F0FA783B79120442EA03627B7880
+:1070500021AC1A43BB78294642EA03222046FFF7B7
+:10706000FBFCFA793B7A120442EA03627B79204600
+:107070001A43BB79314642EA0322FFF7EDFC0AF1DD
+:10708000010A08372E4B1B789A45CDDB00F030BE45
+:1070900021AD08EB0904284631496278FFF7DCFC92
+:1070A000BBF1020F40F224862E49284659E121AD5A
+:1070B00008EB0904002228462B496378FFF7CCFC33
+:1070C000BBF1020F40F20F86012228462649A37821
+:1070D000FFF7C2FCBBF1030F00F005860222284631
+:1070E0002149E378FFF7B8FCBBF1040F00F0FB8502
+:1070F00028461D4903222379FFF7AEFC00F0F3BDBB
+:1071000021AC08EB090517496A782046FFF7A4FC73
+:107110001549AB782046012200F0DCBD134908EB8D
+:10712000090321A85EE7C046B4B6020075B70200A5
+:10713000BEB502000AB2020021B3020021B2020071
+:107140008128020038E7010043E7010056B302003E
+:1071500037B7020082B2020054B40200CAB702007C
+:1071600081B10200ACB7020081B4020045B8020050
+:10717000ABF10203082B00F2BB85DFE813F0090036
+:10718000B905B905B905B9052B001C0015000E009D
+:10719000A74908EB090321A824E708EB090321A864
+:1071A000A4495A7AFFF758FC08EB090321A8A04923
+:1071B0001A7AFFF751FC09F1070521AC9E4915F831
+:1071C00008202046FFF748FC20469C4915F8082077
+:1071D000FFF742FC9A4D09EB0804A3786278294630
+:1071E00002EB032221A8FFF737FC964B0935023446
+:1071F0009D42F2D100F07CBDBBF1140F19D0BBF160
+:10720000170F04D0BBF1130F1AD000F071BD21ACE1
+:1072100008EB09058C49AA7D2046FFF71DFC8B4928
+:107220006A7D2046FFF718FC204689492A7DFFF732
+:1072300013FC08EB090321A88649DA7CFFF70CFC54
+:10724000854D09EB0804A3786278294602EB0322F6
+:1072500021A8FFF701FC814B093502349D42F2D190
+:1072600009EB08057E4E2C46237AE279314602EB83
+:10727000032221A8FFF7F0FB7A4B0B3602349E4223
+:10728000F2D1794CAB7B6A7B214602EB032221A829
+:10729000FFF7E2FB754B0B3402359C42F2D100F054
+:1072A00027BD08EB0901C8784A788B7800900879E7
+:1072B00001904879029088790390C8790490097AFE
+:1072C00021A805916A49FFF7C7FB00F011BD09EB42
+:1072D000080400256378FF2B04D021A865492A46BD
+:1072E000FFF7BAFB01350134042DF3D100F000BDE6
+:1072F00008EB09035A780AB19B7823B921A85E49A3
+:10730000FFF7AAFB03E021A85C49FFF7A5FB08EB08
+:1073100009035B49DA7821A8E4E408EB09039C78C7
+:107320005A78584921A8DBE408EB0901CA780B799F
+:10733000120442EA03624B7821A81A438B7852491F
+:1073400042EA0322CEE421AD08EB090428464F4966
+:107350006278FFF781FBBBF1020F40F2C9844C4910
+:107360002846A278BEE409F1010515F8082021ACF1
+:10737000484902F00F022046FFF76EFB15F808207F
+:107380004549120909F102052046FFF765FB15F88A
+:107390000820424902F007022046FFF75DFB15F87E
+:1073A00008203F4920461FE009F1010515F8082093
+:1073B00021AC3C4902F00F022046FFF74DFB15F8C7
+:1073C00008203949120909F102052046FFF744FB5C
+:1073D00015F80820354902F007022046FFF73CFB6C
+:1073E00015F8082032492046C2F3C1027AE4314937
+:1073F00008EB090321A8F5E521AC08EB09052E49A6
+:107400006A782046FFF728FB2C49AA782046FFF728
+:1074100023FB2B49EA78204664E42A4908EB090358
+:1074200021A8DFE5284908EB090321A8DAE5C046D1
+:10743000ECB60200ADB602009FB50200E3B1020057
+:1074400022B402003DB40200D4B10200EDB2020049
+:1074500049B30200F1B1020002B602001DB60200FB
+:10746000EEB302000FB40200F9B602001AB7020030
+:1074700050B7020097B1020025B802003AB80200E6
+:1074800058B802005DB4020004B80200B6B70200AA
+:10749000E4B3020068B102003DB40200B3B10200DF
+:1074A00047B7020091B7020075B20200F7B70200B9
+:1074B000C1B7020010B8020068B40200A4B602000E
+:1074C0004AB4020046B502000AB3020009F1010401
+:1074D00004EB08052846DBF33FF2002840F008845F
+:1074E00014F8083013F0010F40F00284284611A967
+:1074F000DBF37AF00E9BB3F1FF3F40F0F98308EB2A
+:1075000009035A799B79F3E408EB09039A785C78CC
+:107510008C49120621A8FFF7E3BB08EB090421AD53
+:10752000894962782846FFF797FA8849A278284661
+:10753000FFF792FA2379E2788549284621E58549C3
+:1075400008EB090321A84DE508EB0906B378747828
+:1075500021AD04EB0324A4B2E20A7F492846FFF7D9
+:107560007BFA7E49C4F302222846FFF775FA7C496C
+:10757000C4F3C4022846FFF76FFA7A49C4F3410204
+:107580002846FFF769FA2846774904F00102FFF719
+:1075900063FABBF1040F40F2AB833379F47873499B
+:1075A00004EB0324A4B2E20A2846FFF755FA704917
+:1075B000C4F302222846FFF74FFA6E49C4F3C4020F
+:1075C0002846FFF749FA6C49C4F341022846FFF701
+:1075D00043FA6A49284604F00102FFF783BB08EB2F
+:1075E000090621AF664972783846FFF735FA4FF041
+:1075F000000A6449B2783846FFF72EFACDF800A0A9
+:107600003279F378604903EB022301930222534657
+:107610003846FFF721FACDF800A0B27973795A49BC
+:1076200003EB02230193022201233846FFF714FAE9
+:10763000CDF800A0327AF379384603EB0223022218
+:10764000019351491346FFF707FABBF11E0F40F2B1
+:107650004F834E49727A3846FFF7FEF94C49B27AA9
+:107660003846FFF7F9F94B49F27A3846FFF7F4F953
+:107670004949327B3846FFF7EFF9CDF800A0B27BDD
+:10768000737B414903EB022301930522534638469D
+:10769000FFF7E2F9CDF800A0327CF37B3A4903EB27
+:1076A00002230193052201233846FFF7D5F9CDF8CF
+:1076B00000A0B27C737C344903EB022301930522C2
+:1076C00002233846FFF7C8F9CDF800A0CDF804A092
+:1076D000327DF37C314903EB0223029305226C23B4
+:1076E00001253846FFF7B8F90095CDF804A0B27D22
+:1076F000737D2A4903EB0223029305226C2338464B
+:107700000224FFF7A9F90094CDF804A0327EF37D9E
+:10771000224903EB0223029305226C233846FFF72C
+:107720009BF9CDF800A0CDF804A0B27E737E384658
+:1077300003EB02230293194905226823FFF78CF912
+:107740000095DFE0D7B5020086B5020050B5020013
+:1077500077B502002BB70200E7B7020093B2020030
+:10776000A0B2020071B80200A4B1020046B6020045
+:107770008EB80200C1B802008BB40200D8B7020074
+:10778000E3B102005DB5020080B702002AB6020034
+:107790002FB30200E4B5020048B202000FB40200A9
+:1077A00008EB090621AFAF4972783846FFF754F964
+:1077B0004FF0010AAC49B2783846FFF74DF9CDF8E1
+:1077C00000A03279F378A94903EB02230193022246
+:1077D00000233846FFF740F9CDF800A0B27973795D
+:1077E000A24903EB02230193022253463846FFF7D6
+:1077F00033F9CDF800A0327AF379384603EB02234F
+:107800000222019399491346FFF726F9BBF11E0F97
+:1078100040F26E829649727A3846FFF71DF9954913
+:10782000B27A3846FFF718F99349F27A3846FFF7EB
+:1078300013F99249327B3846FFF70EF9CDF800A0D4
+:10784000B27B737B894903EB02230193052200235A
+:107850003846FFF701F9CDF800A0327CF37B83496D
+:1078600003EB02230193052253463846FFF7F4F851
+:10787000CDF800A0B27C737C7C4903EB022301931A
+:107880000522022300253846FFF7E6F80095CDF8DB
+:1078900004A0327DF37C7A4903EB02230293052294
+:1078A0006C233846FFF7D8F8CDF800A0CDF804A037
+:1078B000B27D737D724903EB0223029305226C2390
+:1078C00038460224FFF7C8F80094CDF804A0327EB1
+:1078D000F37D6B4903EB0223029305226C233846A8
+:1078E000FFF7BAF80095CDF804A0B27E737E384653
+:1078F00003EB02230293624905226823FFF7ACF8E9
+:10790000CDF800A0CDF804A0327FF37E384603EB1B
+:1079100002230293052268235949FFF79DF800943A
+:10792000CDF804A0B27F737F384603EB02230293A5
+:10793000534905226823FFF78FF8D9E108EB0904C2
+:10794000A378627821AD02EB03224E492846FFF767
+:1079500083F86279A379120402EB0362E378284684
+:10796000D2182379484902EB0322FFF775F8BBF1DF
+:10797000120F40F2BD81627AA37A120402EB036215
+:10798000E3794249D218237A284602EB0322FFF713
+:1079900063F8627BA37B120402EB0362E37A28465E
+:1079A000D218237B3A4902EB0322FFF755F8627C99
+:1079B000A37C120402EB0362E37BD218237CABE0CE
+:1079C000A278637821A803EB0223009331492B4668
+:1079D0000222FFF741F801350234B5EB5B0FEFDD12
+:1079E00086E1A278637821A803EB0223009329495A
+:1079F0002B460522FFF730F801350234B5EB5B0F5B
+:107A0000EFDD75E10095A278637821A803EB0223EE
+:107A10000193214905226C23FFF71EF8013502343A
+:107A20004FEA9B06B542EDDD002411E008EB5B0355
+:107A30004B44009403EB44039A785B7821A803EB52
+:107A400002230193144905226823FFF705F8013446
+:107A5000B442EBDD4CE108EB09039C785A780F49FE
+:107A600021A824E1FCB202006AB5020080B702003E
+:107A700038B602003CB30200F3B5020057B2020070
+:107A80000FB402004BB802009EB70200C9B5020055
+:107A900066B2020030B2020056B60200ABB4020079
+:107AA00008EB09039C785A78934921A8FFE008EB7A
+:107AB00009039C785A78914921A8F8E008EB09035A
+:107AC0009C785A788E4921A8F1E008EB0904E27805
+:107AD0002379120402EB0362637821ADD218A378F4
+:107AE000884902EB03222846FEF7B6FFE279237AA3
+:107AF000120402EB036263792846D218A379824903
+:107B000002EB0322FEF7A8FFE27A237B120402EBCA
+:107B10000362637AD218A37A7C492846FFF731BA08
+:107B200008EB0904A378627821AD2846784902EB76
+:107B30000322FEF791FFBBF1040F40F2D9802379B5
+:107B4000E27874492846FFF71CBA08EB0904E2788A
+:107B50002379120402EB0362637821ADD218A37873
+:107B600028466D4902EB0322FEF776FFBBF1060FB4
+:107B700040F2BE80E279237A120402EB0362637959
+:107B80006649D218A3792846FFF7FBB9644E09EB82
+:107B900008040225AB45C0F2AB80E27823791204D9
+:107BA00002EB036263783146D218A37821A802EB76
+:107BB00003220435FEF750FF043418361A2DE9D19C
+:107BC00096E0584E09EB08040225AB45C0F29080C0
+:107BD000E2782379120402EB036263783146D2180B
+:107BE000A37821A802EB03220435FEF735FF043405
+:107BF00013360E2DE9D17BE04B4E09EB080402252C
+:107C0000AB4575DBE2782379120402EB03626378FB
+:107C10003146D218A37821A802EB03220435FEF7DF
+:107C20001BFF043414360E2DEAD161E03F4E09EB00
+:107C300008040225AB455BDBE2782379120402EBF2
+:107C4000036263783146D218A37821A802EB03229D
+:107C50000435FEF701FF043414360E2DEAD147E057
+:107C6000334E09EB08040225AB4541DBE27823796A
+:107C7000120402EB036263783146D218A37821A87C
+:107C800002EB03220435FEF7E7FE043414360E2D12
+:107C9000EAD12DE008EB09039C785A78254921A800
+:107CA00005E008EB09039C785A78234921A802EBE8
+:107CB0000422FFF717B808EB0901CB780A791B04F7
+:107CC00003EB02634A788C789B181C4921A8012297
+:107CD00003EB0423FEF7C0FE0AE0194908EB090391
+:107CE00021A8FFF77FB901220B9201E0FF2E29D0D6
+:107CF0000BEB0801FEF753BF19B802008BB102006D
+:107D00001DB60200C9B5020066B2020072B40200DC
+:107D10009BB80200AEB80200C0B60200D6B60200A0
+:107D2000B6B4020064B30200B1B202009DB3020017
+:107D300068B6020014B30200C0B102001AB7020014
+:107D4000ACB502000D9B01330D930D9A079B9A422F
+:107D50007EF41DAF0E9AB2F1FF3F03D021A8174960
+:107D6000FEF77AFE9DF8443023B121A8144911AAE8
+:107D7000FEF772FE00201349DAF32AF638B90B9B9E
+:107D80002BB91A4621A81049FF33FEF765FE229A47
+:107D9000002302F8013B2E9B0A9900930998069B49
+:107DA0002292FEF7ABFE0A9904464FF480520998DE
+:107DB000DEF39EF7204625B0BDE8F08F82B80200C2
+:107DC0002FB802000E5D860081B402002DE9F04F4D
+:107DD0009A468FB000230D936D4B06461C7889465A
+:107DE0000592002C40F0C180142208A82146DAF345
+:107DF00027F17369232B05DC01224FF0040B069455
+:107E0000079214E01C222346304621460094E3F3F7
+:107E10003DF00028ACBF03230123ACBF00220122A8
+:107E200007930692ACBF4FF00C0B4FF0020B30469D
+:107E3000E2F3E0F70128054602D0022806D013E05D
+:107E400030464946DAF330F040000CE03046FAF7AD
+:107E500047FF044640B1D9F3D5F710F4807F03D033
+:107E60002046D9F3C5F70D900D99002900F08480C4
+:107E70004846DEF32DF7044610B96FF01A0083E090
+:107E8000012D0746DDF8348003D0022D0ED00025E9
+:107E90001CE0002102900091CDF80480039130464F
+:107EA000059A4B46D9F3FAF705460DE00EAB4FEABB
+:107EB000580243F8042D304601212246D9F356F7E3
+:107EC0000D9B05465B000D93002D45D123884FF691
+:107ED000FD72013B9BB2934205D94846214642467A
+:107EE000DEF306F74AE0069B1BB104EB4B03089355
+:107EF00015E0638804EB0B01227901EB132303EBFC
+:107F00000223A3F580530993E3880891CB18A3F5C6
+:107F100080530A932389C918A1F580510B91DDB9CB
+:107F2000189A4846009208A9079A5346FEF708FE99
+:107F300090B91849DAF320F538B1189B3046DAF8D1
+:107F400000101A6800F024FB06E0189B3046DAF8AF
+:107F500000101A6800F004FB27B148463946424633
+:107F6000DEF3C6F60A4B01221A700023189A18464F
+:107F7000CAF80030136007E00D468846064B00271C
+:107F8000089301230793CAE70FB0BDE8F08FC046FE
+:107F9000402700004EE7010019B2020013B5049C0F
+:107FA0009E4605994CB141B1002323600B600091BE
+:107FB00023467146FFF70AFF00E000201CBDC046C3
+:107FC000094A13888B4201D1002206E093888B4234
+:107FD00002D04FF0FF3005E00122034B03EB820398
+:107FE00093F902007047C0461CB902002DE9F04128
+:107FF000074614461E46002B7ED0E7F783FA054657
+:1080000002E0B34205D00C35002D75D02B88002B33
+:10801000F7D12B88002B6FD0D4F80036AA78C3F3A1
+:108020008403934268D0D4F81836642023F0C073D8
+:10803000C4F81836D4F81C3643F6A12623F0C073D2
+:10804000C4F81C36DEF388F303E00A20DEF384F381
+:108050000A3ED4F8E03113F4003F01D0092EF4D1E8
+:108060000023C4F86036EA782B79D4F864161B062E
+:10807000120502F4700203F07063134321F07F6174
+:108080000B43C4F864360223C4F86036D4F864366F
+:108090006A7923F0FE5323F4781343EA025343F43E
+:1080A0008023C4F864360323C4F86036D4F8642609
+:1080B000AB6802F07F4223F07F431343C4F8643679
+:1080C0003B6A012B05DDD4F8003643F48063C4F825
+:1080D0000036AA782988D4F8000692004FF68373F8
+:1080E0007F3102F07C0200EA0303C9111A4301390F
+:1080F00042EA0142C4F80026BDE8F081036A70B587
+:10810000092B054601DC00242CE0E2F3B7F6002140
+:1081100006462846E3F384F0D0F80836044613F404
+:10812000807001D1044619E04FF00043C4F86C366A
+:108130004FF47A70DEF310F3D4F86C360022DB04CF
+:10814000DB0C5B03C4F86C2603F54243064A03F5D7
+:10815000A873B3FBF2F3642203FB02F42846314612
+:10816000E3F35EF0204670BDA086010070B50446C2
+:10817000E2F384F6002105462046E3F351F0236A3A
+:10818000012B04D1D0F8003623F4007304E005DDA0
+:10819000D0F8003643F40073C0F800362046294674
+:1081A000E3F33EF070BDC0462DE9F04104461646AB
+:1081B0000D46E2F363F6002180462046E3F330F0FB
+:1081C0002946024633462046FFF710FF2046414627
+:1081D000E3F326F0BDE8F0812DE9F043002485B0FB
+:1081E000074603940294E2F349F621468146384655
+:1081F000E3F316F07B6A4E4A0546C3F3042605E016
+:10820000137AC5F82036D368C5F82836494B083AA2
+:108210009A42F5D14FF0000820E008216846464A0E
+:108220004346D9F351F700206946DAF3D1F398B108
+:1082300000210A46DAF38CF23B6A0C2B08DDB0F51C
+:10824000803F05D200F0FF02C0F3072342EA03405B
+:10825000C5F82086C5F8280608F10108B045DCD12C
+:10826000364C28E0E36A13B13846984710B3002132
+:108270001EE001238B40226A134218D0C5F8201655
+:1082800094F924302BB1012B05D0B3F1FF3F07D077
+:108290000DE0A36A09E0D5F82436A26A134304E08E
+:1082A000D5F82436A26A23EA0203C5F82436013140
+:1082B000B142DED1103C224B9C42D3D1002614E0C7
+:1082C000082168461F4A3346D9F3FEF60020694666
+:1082D0006C46DAF37DF338B10021C5F820660A4612
+:1082E000DAF336F2C5F8240601364645E8D103A98B
+:1082F00002AA3846DDF31CF5029B039941EA03020A
+:10830000D5F81C3642EA0303C5F81C360AB1C5F895
+:108310001C2609B1C5F818164FF4FA600292DEF374
+:108320001BF238464946E2F37BF705B0BDE8F0831F
+:1083300014B90200F4B8020051368600D4B8020025
+:10834000A4B80200563686002DE9F04385B00546F4
+:10835000E2F394F5002181462846E2F361F72B6AA7
+:108360008046042B6B6A01DDDF0E01E0C3F3436737
+:10837000002614E0102168460D4A3346D9F3A4F6CE
+:10838000002069466C46DAF323F338B100210A462F
+:10839000DAF3DEF1C8F85066C8F854060136BE427A
+:1083A000E8D128464946E2F33BF705B0BDE8F08343
+:1083B0005B3686002DE9F043036A85B0042B436ADF
+:1083C0000546CCBFC3F38458C3F34358E2F356F5D4
+:1083D000002181462846E2F323F70026074615E0F0
+:1083E000102168460E4A3346D9F36EF600206946DE
+:1083F0006C46DAF3EDF238B100210A46DAF3A8F15F
+:10840000C7F85866C7F85C06731CDEB24645E7D16C
+:1084100028464946E2F304F705B0BDE8F083C046BC
+:1084200063368600F7B5053A06461F46062A2BD85E
+:10843000DFE802F00A0C12040E2A060005250CE003
+:108440001125032402230AE0012502E0052500E0AE
+:1084500011250F24042302E000251F240323009389
+:1084600000214FF4CB624FF0FF333046E2F30EF5BC
+:1084700004EA0703AB4030460093002140F25C62FF
+:1084800014FA05F3E2F302F5FEBDC0462DE9F04112
+:1084900005460E4600201749DAF36EF2164984B2FB
+:1084A0000020DAF369F240F2DC51002C18BF2146BB
+:1084B000C7B22846FFF784FDC0B210F0800F0CD180
+:1084C000C4B23146284607222346FFF7ABFF2846B1
+:1084D000314608222346FFF7A5FF2FB12846314633
+:1084E0003A460123E7F748F828463146FFF762FF8E
+:1084F000BDE8F0816F36860008F9010070B50546C9
+:108500000C46FFF721FF002221462846DDF364F5E3
+:108510002846E2F3B3F40A4904460020DAF32CF2C9
+:108520004FF4002210F001034FF00001284618BF5D
+:108530001346DDF385F428462146E2F371F670BD5B
+:108540007836860070B5002105461020DDF35EF711
+:10855000002110220446D9F373F52046656070BDF2
+:1085600070B50C461546E2F3C5F51021DEF3B0F305
+:1085700010B96FF01A0008E0044A10234360136832
+:10858000C460036085601060002070BD6C2700002F
+:1085900070B515460C46E2F3ADF51021DEF398F305
+:1085A000024610B96FF01A0010E01023436008492A
+:1085B000002303600B68C46085601BB9086018461F
+:1085C00004E0034618680028FBD11A6070BDC0465D
+:1085D0006C27000070B50C461546E2F38BF51021B0
+:1085E000DEF376F310B96FF01A0008E0044A1023A6
+:1085F00043601368C460036085601060002070BD34
+:108600006C270000064B10B51B683BB9054B196879
+:1086100021B1054B1A680AB1FFF7DCFF002010BD3D
+:108620006C270000FC1E0200001F020001207047A2
+:108630000020704710B50020DAF39EF110BDC0464F
+:1086400010B50B490446FFF7F5FF80B278B9E06F2B
+:108650000749DAF391F180B248B9E06F0549DAF3DE
+:108660008BF14FF6FF7380B2002808BF184610BD8B
+:10867000483786004E37860041F2E44370B5C36246
+:1086800004460D4629B108460949DAF375F1A0629E
+:1086900040B900200749DAF36FF1A06210B94FF634
+:1086A000FF73A36228460449DAF366F1206370BDC4
+:1086B000543786005B37860086378600836973B53A
+:1086C00013F0005F04466FD08268B2F5026F01D1EB
+:1086D00001220AE040F604039A4201D0002204E09D
+:1086E000C3680C2B94BF002201224FF00003D5B2C7
+:1086F000ADF8063055B920464FF400612A46D4F84B
+:10870000C860E2F37BF500284ED005E0D4F8843051
+:1087100013F5405048D000266369222B03DC002368
+:10872000C0F8683100E00023C0F86431C0F860315F
+:108730006369222B03DC1F4BC0F8443105E00123A1
+:10874000C0F84831FE33C0F84C316369222B07DC96
+:108750000023C0F88031C0F87C31C0F8783104E0E3
+:108760000023C0F87431C0F870311DB9204631467D
+:10877000E2F356F520460DF10601FFF759FF0546D5
+:10878000A8B9BDF8063093B163690B49222B204686
+:10879000D8BF4FF48021CCBF40224FF480222B461B
+:1087A000E2F38EF3284603E04FF0FF3000E00020B4
+:1087B0007CBDC0460000FBBF400055552DE9F04789
+:1087C000002104461F46DDF82080DDF82490E2F306
+:1087D00027F505462046E2F363F360610A28C4BF2B
+:1087E000EB6A63646B68A3616369222BC4BFD5F82D
+:1087F000AC30E361A36913F0805F05D0D5F804368F
+:10880000636203F0FF0323624FF4E063A3604FF061
+:10881000FF33E360254612330026236116E031461C
+:108820002046E2F3FDF42046E2F31CF32046E2F397
+:1088300037F31FB1D5F810319F4203D0D5F88830F7
+:10884000994501D1C8F8006001360435D4F8CC3020
+:108850009E42E4D32046D8F80010E2F3E1F4012070
+:10886000BDE8F08730B585B00190002504A840F838
+:10887000045D01A90422D9F37FF3019CD4B12246FF
+:108880002946D2F8883013B10023C2F8883001316C
+:1088900004321029F5D10398D9F30CF30398E6F7C5
+:1088A000B7FF054B9C4205D0606D21464FF45672D0
+:1088B000DEF31EF205B030BD8C2802002DE9FF4723
+:1088C0000C9E1446DDF834808A464FF4567200211F
+:1088D00005461F46DDF83890012E08BF0026D9F363
+:1088E000AFF311232B61C5F88470C5F858806C650F
+:1088F0006E60002E40F0B98028463146524643460D
+:10890000FFF794FE002800F0B0804FF0C0542268BA
+:108910002846130F2B6013041B0CAB63C2F30343F5
+:10892000C2F303522A640E3A012A8CBF00220122AC
+:10893000EB6385F8482021465246FDF739FFD5F80C
+:10894000CC30002B00F0918004AB43F8046D009311
+:1089500028462146324633460197FFF72FFF00286D
+:1089600000F083802846FFF74DFE0F9A6B6D284676
+:10897000019231463A46CDF80090FFF70FFB0028F0
+:1089800073D1B9F1000F01D14E4601E0D9F8006072
+:1089900028463146FFF770FE364B1C78002C30D14C
+:1089A0006B69132B0BDD4FF4006128462246E2F37E
+:1089B00025F48465C46503992846E2F331F428461A
+:1089C000696DFFF7D3FB2846696DFFF797FD3046C9
+:1089D0002949D9F3D1F7024620B92846696DFFF736
+:1089E0008DFB02462846696DFFF7DEFB2846696D60
+:1089F000FFF7F2FB2846696DFFF748FD1D4B01228A
+:108A00001A706B690F2B0FDD1C493046D9F3B4F790
+:108A10001B4B0021002808BF1846009088222846DA
+:108A20004FF0FF33E2F332F230461649D9F3D0F774
+:108A300038B114493046D9F39FF701462846E7F785
+:108A4000A5F86B69142B11DD00242146082223466A
+:108A500028460094E2F31AF2214640F0040308226B
+:108A600028460093E2F312F200E00025284604B005
+:108A7000BDE8F087E42B0200E2388600EB38860080
+:108A80005A000A00F13886001FB5104C864621783E
+:108A9000C9B90F4A0F4B002808BF024608BF03465A
+:108AA00000910191029303920B4844F210717246B7
+:108AB0004FF0C053FFF702FF00B905E0074A20233B
+:108AC000136001232370044804B010BD88280200FD
+:108AD0000C290200082902008C28020074270000DB
+:108AE0002DE9FF4781460D4608464FF456719246E0
+:108AF0001E460D9FDDF83880DEF3EAF0044610B321
+:108B00000C9B494601932A46534600960297CDF89E
+:108B10000C80FFF7D3FE064638B9284621464FF4AD
+:108B20005672DEF3E5F030460EE00FB93B4600E04A
+:108B30003B68E367B8F1000F01D1434601E0D8F884
+:108B40000030C4F88030204604B0BDE8F087C0464D
+:108B500070B5044628B30368124918682246FBF32F
+:108B6000F3F12546002610E0296A29B123689868A8
+:108B7000E6F386F500232B62E96921B123682A8B8D
+:108B80005868DEF3B5F00136183561688E42EBDBCC
+:108B9000182201FB02F22368214658681032DEF3E6
+:108BA000A7F070BD08FA01002DE9F043036885B015
+:108BB00081467021D868DEF38BF0044608B906467A
+:108BC00048E0002170220646D9F33AF2042363609C
+:108BD00027464FF0B40325464FF00008C4F8009034
+:108BE000A38112E0182208FB02F210322C61D9F89E
+:108BF00008001A49A2180023E6F35EF5286218352A
+:108C000008B905461CE008F1010863689845E9DBEE
+:108C1000134BD9F8000000930023019302930393B0
+:108C20001049114A2346FBF357F113E0396A29B181
+:108C300023689868E6F324F500233B620135183772
+:108C400063689D42F2DB2368214658687022DEF398
+:108C50004FF00026304605B0BDE8F0839DFE0000D1
+:108C600021FD0000E4F9010009FA010010B50446F5
+:108C700058B10368054918682246FBF365F123687B
+:108C8000214658685422DEF333F010BD2B7A86005B
+:108C900030B55421044685B04068DEF319F008B9B8
+:108CA000054611E0002154220546D9F3C9F1084BCD
+:108CB0002C600093002301930293039320680549DD
+:108CC000054A2B46FBF308F1284605B030BDC046E7
+:108CD000390301003CFA01002B7A8600002070471E
+:108CE00010B5044698B107F0ADDE09496068224628
+:108CF000FBF32AF1E16E21B163683C22D868DDF311
+:108D0000F7F763682146D8687022DDF3F1F710BDEC
+:108D1000D58D86007FB5054670214068DDF3D8F714
+:108D2000064608B9044631E0002170220446D9F312
+:108D300087F12B683560736068683C21DDF3C8F704
+:108D4000E066F8B100213C22D9F37AF1114B1249C7
+:108D50000093002301930293104B114A0393706810
+:108D60003346FBF3B9F068B94FF001037382B38265
+:108D700030462946FFF7B2FF002803DB304607F0F4
+:108D80005DDF03E03046FFF7ABFF0024204604B070
+:108D900070BDC046390B83006CFA0100290C8300BA
+:108DA000D58D860070B5D0F8305704466DB10749AF
+:108DB00022460068FBF3C8F0606829464FF40A6257
+:108DC000DDF396F70023C4F8303770BD529E86005D
+:108DD0002DE9FF4106464FF40A614068DDF378F75C
+:108DE000074618B9C6F830070138E1E000214FF412
+:108DF0000A62D9F325F107F120033B6033680822AA
+:108E000000247A613C61DC211A6630466A4A6B4B69
+:108E10000094019601F092FFA042B86105DA304655
+:108E2000FFF7C0FF6FF00100C2E0A6462546644B85
+:108E300000221EF0010FEA501FD0624B19780D2955
+:108E400002DD4FF4004C03E04A1C012303FA02FC4C
+:108E50005C4BD8780D2802DD4FF4004403E0421C3F
+:108E6000012313FA02F4012313FA00F28B401A4390
+:108E700042EA0C02524B2243EA501EF0020F24D069
+:108E80004F4B55F803804F4B58780D2802DD4FF4B7
+:108E9000004C03E0421C012303FA02FC494B997881
+:108EA0000D2902DD4FF4004403E04A1C012313FAAC
+:108EB00002F4012313FA01F283401A4342EA0C023E
+:108EC00022433F4B42EA0802EA501EF0040F24D02E
+:108ED0003B4B55F803803B4B18790D2802DD4FF4CE
+:108EE000004C03E0421C012303FA02FC354B597984
+:108EF0000D2902DD4FF4004403E04A1C012313FA5C
+:108F000002F4012313FA01F283401A4342EA0C02ED
+:108F100022432B4B42EA0802EA501EF0080F24D0ED
+:108F2000274B55F80380274B98790D2802DD4FF425
+:108F3000004C03E0421C012303FA02FC214BD979C7
+:108F40000D2902DD4FF4004403E04A1C012313FA0B
+:108F500002F4012313FA01F283401A4342EA0C029D
+:108F60002243174B42EA0802EA500EF1010E043583
+:108F7000BEF1100F7FF45BAF134B0025134C03932E
+:108F80002946134A33463068009501950295FAF355
+:108F9000A3F7231D93E807006B4683E807003046DC
+:108FA00023680321324601F061DEC6F83077284697
+:108FB00004B0BDE8F081C04601578300A15683008C
+:108FC0008427000090E085009D508300C8FA0100CE
+:108FD000529E86002DE9F041066805461B4930681F
+:108FE0002A46FAF3B1F72C460027D4F8081121B12C
+:108FF0007068B4F81021DDF37BF6D4F80C1121B1C0
+:109000007068B4F81221DDF373F601374034042F91
+:10901000EBD1D5F80C1221B17068B5F81022DDF350
+:1090200067F6D5F81C1211B1B068E6F329F3D5F84C
+:10903000201219B170683A46DDF35AF67068294675
+:109040004FF42372DDF354F6BDE8F081D8FA010045
+:1090500010B50446E7F7F2FDA16961B1237D23B1A4
+:10906000E068E6F3FBF200232375E068A169E6F30C
+:1090700007F30023A36123692146D8682C22DDF37E
+:1090800037F6002010BDC0462DE9F041074688465E
+:10909000C0682C2114461E46DDF31AF608B90546B1
+:1090A00019E0054600212C22D8F3CAF7EC602046CF
+:1090B000EE61C5F808802F6108492A460023E6F3CF
+:1090C000FBF20446A86130B92B692946D8682C22E6
+:1090D000DDF30EF625462846BDE8F0813D668400A6
+:1090E00010B5034900220068FAF32EF7002010BDE6
+:1090F00049C586001FB5094A0B460092002201921D
+:10910000029203920649074AFAF3E6F6002814BFD2
+:109110004FF0FF30002005B000BDC0460968840054
+:1091200048FB010049C586001FB5084A0346009266
+:1091300000220192029203920549064A0068FAF35E
+:10914000CBF6003818BF012005B000BD7D18010026
+:1091500020FC0100EFFB010010B5B0F8BC400C8012
+:10916000B0F8C0101180B0F8C6201A8090F8C8205E
+:10917000029B01201A8010BD90F8D4007047C046B1
+:10918000D0F8CC007047C04610B5014618B18068D1
+:109190009822DDF3ADF510BD70B598210446006846
+:1091A000DDF396F508B9054633E00021982205461F
+:1091B000D8F346F72368AB606368EB60A3682B6164
+:1091C000E3686B6023696B61238CAB84638CEB84F5
+:1091D000636AAB62A36AEB62E36A2B63236B6B6324
+:1091E000636B6B64A36BAB64E36BEB64236C2B6509
+:1091F000636C6B656369AB65A369EB650F232B66D5
+:109200002D336B663C33AB660323EB66002385F896
+:109210009430284670BDC04670B501210446E9F778
+:1092200029FB2046E9F7B2FBC0F30F33A4F8C630A0
+:10923000B4F8C620030F84F8C83042F2640300F08B
+:109240000F009A4284F8C90005D002339A4202D036
+:109250004FF0FF3500E0002520460021EAF77AF8BC
+:10926000284670BD70B5044600282DD0D0F8E430F3
+:109270005D1EC0F8E4503DBB41F2C826815921B1C2
+:10928000C3691869F3F78EFFA55141F2DD13E55468
+:109290002046E9F73FFFE1690A68A24203D1D4F80A
+:1092A000B4300B6005E0D2F8B430A34208BFC2F876
+:1092B000B450E36E0BB120469847E36921469868A5
+:1092C00041F26832DDF314F570BDC04670B5D0F8D8
+:1092D000B8400E46E9B10846D8F342F70546C0B19A
+:1092E0000FE0204631462A46D8F32AF628B9635DB6
+:1092F0003D2B02D1631C58190CE014F8013B002BE4
+:10930000FBD114B12378002BEBD13046DEF3AEF461
+:1093100000E0002070BDC0462DE9F34141F2383530
+:10932000435B064688462BB30846D8F319F7044634
+:109330001448D8F315F724181034F369A7B29868C5
+:109340003946DDF3C5F4044608B9054617E0735BFA
+:109350000D4A009339464346D8F3B6F621463046C7
+:10936000EBF79EF9F3690546214698683A46DDF326
+:10937000BFF425B930464146EBF792F90546284639
+:10938000BDE8FC8196FD01009CFD01002DE9F04F38
+:1093900041F2383B85B0039330F80B3006468946DE
+:1093A0009246D0F8B880002B38D00846D8F3D8F6CB
+:1093B00004462448D8F3D4F62418F3691034A7B22D
+:1093C00098683946DDF384F4054608B9044634E06C
+:1093D00036F80B30394600931B4A4B46D8F374F6E7
+:1093E00030462946EBF76AF9834668B1404629467C
+:1093F000D9F75CFA40B1504506DD40462946524651
+:10940000D9F3C8F2044600E0039CF3692946986842
+:109410003A46DDF36DF4BBF1000F0ED140464946EC
+:10942000D9F744FA40B1504506DD40464946524618
+:10943000D9F3B0F2044600E0039C204605B0BDE835
+:10944000F08FC04696FD01009CFD010070B590F8BC
+:10945000C43001229A401A49013A0446D5B2EBF7CA
+:1094600061F941F21202C0B2A0540138C0B2FD2825
+:1094700001D97323A354A25C41F21303E2542046A2
+:109480001049EBF74FF941F21402C0B2A05408B1F1
+:109490000F2801D10523A35441F21203E25C0233E9
+:1094A000E35CD21A41F21503E25400220133E25484
+:1094B0000233E25445EA0512013BE25470BDC04656
+:1094C00075B902004FB902002DE9F84F8846002116
+:1094D000846807469246C0680A469B46E1F3BAF4A0
+:1094E00010F0080F814615D03E689EB130465146B7
+:1094F00000F084FA002800F07481F369D6F8CC10EB
+:10950000186927F0CDD8D6F8E43030460133C6F8D4
+:10951000E4306DE1204641F26831DDF3D9F30546D0
+:10952000002800F05C81002141F268320646D8F341
+:1095300087F5012105F59053303341F2D41285F8B7
+:10954000E110AB50FA6C41F26B039A42C5F8B0805F
+:10955000EF6105D17B6C932B02D1A5F8221603E0B5
+:109560004FF01802A5F822266423002185F8E03088
+:1095700041F218230422E9540133EA540133E95437
+:109580000133BAF1020FC5F8B8B0EA5406D119F0A8
+:10959000010F1CBF4FF40053C5F8CC30EB69D5F870
+:1095A000CC10186927F07CD8D5F8B030B3F8E03388
+:1095B0009CB2EB69D868E6F787F941F23833E85294
+:1095C000C4F30323C5F8BC3004F00F03C5F8C03062
+:1095D000EB699A6A874BD318012B06D94AF6E60342
+:1095E0009A4202D0043B9A4207D1EB69DB6A023B04
+:1095F000012B02D80923C5F8C030D5F8BC30092B9F
+:1096000007D10423C5F8BC30D5F8C0301033C5F8F5
+:10961000C030012385F8C430230BC5F8D030D5F80D
+:10962000BC30022B0CD9042B0AD0052B08D0062BFA
+:1096300006D0082B04D00A2B02D0072B40F0D18093
+:109640003C23C5F8F43F0023C5F8F83F4FF400630E
+:10965000A5F8DE3042F6013241F62433BAF1020FAA
+:1096600008BF1346A5F8DA3095F8DA30284685F8B1
+:1096700000376149EBF722F890B15F492846EC6961
+:10968000EBF750F85C4920672846EC69EBF74AF89D
+:10969000EA69BAF1020F60670CBF136F536FD366AC
+:1096A0000A2241F2E613EA5403210133E95401236B
+:1096B000002485F8E83005F59053013A1C7041F21A
+:1096C0001B03EA54EB6985F8E94585F8EE4585F812
+:1096D000F34585F8F84585F8FD45284683F893104D
+:1096E000FFF7B4FE41F21903EC544FF6CE7241F28B
+:1096F000C423EA5285F8F440621901347F23652CB3
+:1097000082F82C3682F8913682F8B232F4D14FF0DA
+:10971000FF33A5F8FA36002385F8AC3028465146C9
+:1097200001F03AF900285CD02846E9F797F8284676
+:10973000FFF772FD0446002853D13049062228461F
+:10974000EAF7E4FF41F2E623E8542D4901222846D6
+:10975000EAF7DCFF41F2F423E8542A49224628467E
+:10976000EAF7D4FF41F23A33E85427492846072262
+:10977000EAF7CCFF41F23B33E8542246284623491E
+:10978000EAF7BEFF631903F5985301343833182CF8
+:109790001871F2D10024224628461D49EAF7B0FF8D
+:1097A000631903F59A53013410330E2C1871F2D15A
+:1097B000D5F8E430EA690133C5F8E4301368D068BD
+:1097C000C5F8B4303D60FEF779FF05F1B803C5F880
+:1097D000B830284605F1BC011C22D8F3CDF3284649
+:1097E00006E0B868314641F26832DDF381F20020CC
+:1097F000BDE8F88F1D57FFFF80B9020024B90200B1
+:1098000043B9020036B9020060B902006EB9020025
+:109810002FB9020010B502490268FAF395F310BDA2
+:10982000040402001FB5094B09490093002301936A
+:1098300002930393074A0368FAF34EF3002814BF18
+:109840004FF0FF30002005B000BDC0463147010099
+:1098500044030200040402002DE9F0410025804683
+:109860000F4616462C4607E004EB0800E1190522D6
+:10987000D8F382F301350534B542F5D1BDE8F08166
+:10988000022970B505460C460AD0032911D00129DA
+:1098900016D106220B49E8F793FFEA69002305E099
+:1098A00006220949E8F78CFFEA69012382F8813032
+:1098B00006E006490622E8F783FFEB6983F881405A
+:1098C00070BDC046200B02002C0B0200380B0200BA
+:1098D00070B5D0F8A840002394F8C113C4F87435CB
+:1098E0000F4A104B022914BF15461D46C3694FF499
+:1098F00020719868DDF3ECF1C4F8740578B180222A
+:109900002946FFF7A9FF94F83A35022B06D1D4F87F
+:1099100074050549A0301522FFF79EFF012070BD98
+:1099200084C90200A8C4020048CC02002DE9F04717
+:10993000D0F8A8308146D3F87C55D3F878A54FF0FD
+:10994000000817E0142403FB04F42B191A695B6860
+:109950002F5903FB02F3DE08D9F81C303146986812
+:10996000DDF3B6F108F10108285140B1394632461D
+:10997000D8F302F35FFA88F35345E3D30120BDE83F
+:10998000F087C0462DE9F041194BD0F8A8501A686D
+:10999000C369002614210746C5F87C65C5F87825FB
+:1099A000986802FB01F1DDF393F10446C5F87C05EC
+:1099B000E0B1B0460FE0FB6906EB04001B6D08F157
+:1099C000010813F4805F14BF0A490B49142271186F
+:1099D000D8F3D2F21436D5F878359845EBD338461B
+:1099E0000121FFF7A3FF003818BF0120BDE8F08177
+:1099F000A01A0200C4C2020084D102002DE9F04185
+:109A0000884686B07A490546D0F8A860EAF78AFE0B
+:109A1000784930722846EAF785FE77497072284601
+:109A2000EAF780FE7549A5F8FC002846EAF77AFEB9
+:109A30007349A5F8FE002846EAF774FE7149A5F8B7
+:109A400000012846EAF73AFE38B128466D49EAF7A0
+:109A500069FE10B1012386F8E83396F8E8330BB3BA
+:109A600068492846EAF75EFE6749A5F802012846DC
+:109A7000EAF758FE6549A5F804012846EAF752FEC0
+:109A80006349A5F806012846EAF74CFE614986F8C5
+:109A900024052846EAF746FE002241F21B0386F819
+:109AA0002505EA545C492846EAF73CFE5B49C6F8BE
+:109AB000340414222846EAF729FE5949A6F83C0442
+:109AC0005A222846EAF722FE564986F8540408220C
+:109AD0002846EAF71BFE544986F84C040322284620
+:109AE000EAF714FE514986F84D0408222846EAF7A1
+:109AF0000DFE4F4986F84E0403222846EAF706FE7B
+:109B00004C4986F84F0408222846EAF7FFFD4A49E7
+:109B100086F8500403222846EAF7F8FD474986F8FC
+:109B2000510408222846EAF7F1FD032286F8520480
+:109B300043492846EAF7EAFD424986F85304284695
+:109B4000EAF7F0FD404986F8580402222846EAF771
+:109B5000DDFD3E4986F8C1042846EAF7AFFD28B18D
+:109B600028463A49EAF7DEFDF07400E0F074284632
+:109B70003749EAF7A3FD28B128463549EAF7D2FD6F
+:109B8000307501E00823337528463249EAF796FD1F
+:109B900028B128462F49EAF7C5FD707501E0022378
+:109BA000737528462C49EAF789FD28B128462A49C9
+:109BB000EAF7B8FDB07501E00423B37528462749DC
+:109BC000EAF77CFD28B128462449EAF7ABFDF07599
+:109BD00001E00823F37528462149EAF76FFD0028C4
+:109BE00040D028461E49EAF79DFD30763CE0C0464D
+:109BF00045C10200E3C002002ABE020030BE0200DE
+:109C000036BE0200C3C00200E2BD0200CDBC0200AD
+:109C1000D5BA0200EABA02009AC202006BBD020085
+:109C2000A6C102001DC202007EBF0200EBC10200FD
+:109C3000ABB90200FCC10200BCB90200DAC10200EB
+:109C4000B3C202009ABC02000BBB02001ABC0200A5
+:109C500007BC020065C0020015C202000DC202006E
+:109C60003DC1020002233376B7492846EAF75AFD80
+:109C7000B649B0722846EAF755FDB549F072284654
+:109C8000EAF750FDB17AF27AC3B230737173B273EE
+:109C9000F37331747274B374AE492846EAF742FD27
+:109CA000B5F8FC2041F21A33EA5205F599531A80AF
+:109CB000B5F8FE2041F21C33EA520633EA52B5F8F9
+:109CC0000021043BC7B2EA52063385F81A71EA5202
+:109CD0002846A149EAF726FD002480B22A1900F09F
+:109CE0000F030134A7EB43030009042C82F81E3153
+:109CF000F4D128469949EAF715FD2A1900F00F0317
+:109D00000134A7EB430300090C2C82F81E31F4D177
+:109D100093492846EAF706FD924904462846EAF7A1
+:109D200001FD80B240EA0441716014202A1801F05C
+:109D30000F030130A7EB430309091C2882F81631F1
+:109D4000F4D189492846EAF7EDFC88497083284612
+:109D5000EAF7E8FC864930772846EAF7E3FC8549CC
+:109D600070772846EAF7DEFC8349B0772846EAF7A1
+:109D7000D9FC8249F0772846EAF7D4FC804986F876
+:109D800022002846EAF7CEFC7E4986F821002846C4
+:109D9000EAF7C8FC7C4986F8E0042846EAF7C2FCEA
+:109DA0000127C6F8E40401AC784920463A46D8F3C6
+:109DB0009BF1D5F8B8002146D8F30AF630B100215E
+:109DC0000A46D8F3C5F4F31983F8E70401370F2FD7
+:109DD000E9D16F492846EAF7A5FC6E4986F8F604F2
+:109DE0002846EAF79FFC6C4986F8F7042846EAF70C
+:109DF00099FC6A4986F8F8042846EAF793FC684912
+:109E000086F8F9042846EAF78DFC664986F8FA04D4
+:109E10002846EAF787FC644986F8FB042846EAF7F7
+:109E200081FC624986F8FC042846EAF77BFC60491D
+:109E300086F8FD042846EAF775FC5E4986F8FE04BC
+:109E40002846EAF76FFC5C4986F8FF042846EAF7E3
+:109E500069FC5A4986F800052846EAF763FC584928
+:109E600086F801052846EAF75DFC564986F80205A2
+:109E70002846EAF757FC544986F803052846EAF7CE
+:109E800051FC524986F804052846EAF74BFC504934
+:109E900086F805052846EAF745FC4E4986F806058A
+:109EA0002846EAF73FFC4C4986F807052846EAF7BA
+:109EB00039FC4A4986F808052846EAF733FC484940
+:109EC00086F809052846EAF72DFC464986F80A0572
+:109ED0002846EAF727FC444986F80B052846EAF7A6
+:109EE00021FC424986F80C052846EAF71BFC40494C
+:109EF00086F80D052846EAF715FC3E49A6F8140534
+:109F00002846EAF70FFC4FF00042A6F816053A493A
+:109F10002846EAF7FBFB3949C6F810052846EAF758
+:109F200001FC374986F824002846EAF7FBFB35494F
+:109F300086F823002846EAF7F5FB334986F8200027
+:109F40002846EAF7EFFB61E0E7B902000CBF020028
+:109F5000C5BD0200F2BD020077BD020044BC020094
+:109F600096B902008DB902008DBE0200DDB9020073
+:109F7000F6BF020001C00200CDB90200B2BC02006F
+:109F8000E3BC0200B9BE0200FFBE020033BC020007
+:109F90003CBE02008CBF02009DBF0200B7BF0200A2
+:109FA000FEC002000FC102002BC202004CC2020020
+:109FB0006FBE02009ABE0200C7BE020020C10200AE
+:109FC0000CC0020056C1020068C102007AC1020042
+:109FD0006DC202007FC2020031BA02005BBA020009
+:109FE00074BB02009DBB020088BC0200A9BA02003B
+:109FF000FCBA020034BD020059BB0200B1C102002C
+:10A00000BDC102005DC2020046C00200B94985F828
+:10A0100026062846EAF786FBB74986F8C103284694
+:10A02000EAF780FBB54986F8C2032846EAF77AFBCF
+:10A0300086F8C30395F8261611B12846FFF720FCD1
+:10A040004FF0FF32AE492846EAF760FB80B210F4C9
+:10A05000004F18BF4FF0FF324FF0FF33A6F86200F9
+:10A06000A6F8663018BFA6F86220A6F86830284621
+:10A07000A449EAF723FB58B12846A249EAF752FB64
+:10A0800080B210F4004F04BFA6F86600A6F868007E
+:10A0900028469D49EAF712FB48B128469A49EAF753
+:10A0A00041FB80B210F4004F08BFA6F866002846B6
+:10A0B0009649EAF703FB48B128469449EAF732FB90
+:10A0C00080B210F4004F08BFA6F8680090494FF026
+:10A0D000FF322846EAF71AFB4FF0FF32A6F8C40316
+:10A0E0008C492846EAF712FB8B49A6F8C603284696
+:10A0F000EAF718FB8949A6F8C8034FF4CF7228463F
+:10A10000EAF704FB8649C6F8CC0347F69A6228466C
+:10A11000EAF7FCFA8349C6F8D0030A222846EAF790
+:10A12000F5FA8149C6F8D40308222846EAF7EEFA80
+:10A130007E49C6F8D80341F26E022846EAF7E6FAED
+:10A140000A22C6F8DC037A492846EAF7DFFA794999
+:10A15000C6F8E0032846EAF7E5FA7749A6F8E403EB
+:10A160002846EAF7DFFA96F8E83380B2A6F8E60365
+:10A170002BB103B2002BC4BF0022A6F8E623502265
+:10A180006E492846EAF7C2FA6D4986F8EA0328467E
+:10A19000EAF7C8FA6B4986F8EC032846EAF7C2FAF0
+:10A1A000694986F8ED032846EAF7BCFA674986F85C
+:10A1B000EE034FF0FF322846EAF7A8FA644986F822
+:10A1C000F0034FF0FF322846EAF7A0FA4FF0FF34D1
+:10A1D00086F8F1035F49224686F8EF432846EAF7FE
+:10A1E00095FA5D4986F8F20322462846EAF78EFA88
+:10A1F0005A4986F8590522462846EAF787FA584907
+:10A2000086F85A0522462846EAF780FA554986F824
+:10A21000F30322462846EAF779FA534986F85B05A4
+:10A2200022462846EAF772FA504986F85C0522462B
+:10A230002846EAF76BFA4E4986F8F4032246284688
+:10A24000EAF764FA4B4985F8DA0522462846EAF728
+:10A250005DFA4949A6F8F60322462846EAF756FA77
+:10A260004649A6F8F80322462846EAF74FFA444939
+:10A27000A6F8FA0322462846EAF748FA4149A6F822
+:10A28000FC0322462846EAF741FA3F49A6F8FE03B6
+:10A2900022462846EAF73AFA3C49A6F80004224644
+:10A2A0002846EAF733FA3A49A6F802042246284635
+:10A2B000EAF72CFA0022A6F8040436492846EAF701
+:10A2C00025FA0022A6F85E0533492846EAF71EFA69
+:10A2D0000022A6F8600531492846EAF717FA00225D
+:10A2E000A6F862052E492846EAF710FA2D49A6F885
+:10A2F000640559E04FBA020043BA0200A7C0020049
+:10A300008DBD02004BC0020094C10200C0BB020020
+:10A31000D2BB020067BF020035BB02005BC0020077
+:10A32000A0BA0200BEBD0200D9BB02004DC10200AE
+:10A33000EBBD02009AC002007FBD0200BCBC02005F
+:10A34000AEBF020010BA0200DCBF020095BA0200E4
+:10A3500002BD020032C1020039C0020090BB0200FF
+:10A36000A6BC02003EBB0200BBBA0200F0BB02006A
+:10A37000EBBE02001FBE0200C9BA02006DC002009F
+:10A38000B3BD02004CBB0200F4BC020016BF0200C9
+:10A390005CBC02007AC002006EBF020059BF02001E
+:10A3A000D3C00200C6BC02002846EAF7BBF9B8F1E8
+:10A3B000020F86F8060414D12846A449EAF77EF96C
+:10A3C000002800F0A382344600273A4628469F49D9
+:10A3D000EAF796F90137C4F80C040434052FF4D1D8
+:10A3E00016E0B8F1010F13D128469949EAF766F94A
+:10A3F000002800F08B82344600273A4628469449CC
+:10A40000EAF77EF90137C4F820040434052FF4D1AB
+:10A4100090494FF0FF322846EAF778F98E49A6F8BE
+:10A420003E044FF0FF322846EAF770F98B49A6F850
+:10A4300040044FF0FF322846EAF768F98849A5F84A
+:10A44000DE0F2846EAF73AF930B128468449EAF7A0
+:10A4500069F941F2EA23E852824928464FF0FF3277
+:10A46000EAF754F941F23433E8527F492846EAF7D3
+:10A4700025F930B128467C49EAF754F941F2EE2338
+:10A48000E852284679490022EAF740F9C0B286F836
+:10A490004D0358B176492846EAF744F97549C6F89C
+:10A4A00050032846EAF73EF9C6F860032846724989
+:10A4B000EAF704F928B3D5F8B8006F49D8F7F6F9E8
+:10A4C00006281ED1344600273A466B49D5F8B80015
+:10A4D000D8F360F284F895037A1C6749D5F8B80080
+:10A4E000D8F358F284F89703BA1CD5F8B80062493B
+:10A4F000D8F350F2033784F899030134062FE3D1DF
+:10A5000011E0012386F89533313386F896330E3304
+:10A5100086F8973386F89833042386F899334FF0FA
+:10A52000FF3386F89A3355492846FF22EAF7EEF8BA
+:10A530004FF0FF03A6F85403A6F85633A6F8583395
+:10A54000A6F85A3328464E49EAF7B8F828B3D5F8A2
+:10A55000B8004B49D8F7AAF934460328B4BF80465F
+:10A560004FF00308002707E03A4628464449EAF737
+:10A57000C7F80137A4F8540302344745F4DB06EB6F
+:10A58000470303F55473063304E0B6F85623013746
+:10A5900023F8022C0233022FF7DD01223949284625
+:10A5A000EAF7B4F8384986F840032846EAF7BAF8DB
+:10A5B000012286F84B0335492846EAF7A7F83449C3
+:10A5C00086F841032846EAF7ADF8324986F84C038D
+:10A5D0004FF0FF322846EAF799F82F4986F84903E9
+:10A5E0004FF0FF322846EAF791F82C4986F84A03E3
+:10A5F0004FF0FF322846EAF789F8294986F85C03CC
+:10A600004FF0FF322846EAF781F8264986F85D03C5
+:10A610002846EAF753F8002846D0012421490022B1
+:10A6200086F8BB442846EAF76BF81E4986F8BC0456
+:10A6300022462846EAF764F81A4986F8BD04022241
+:10A640002846EAF75DF886F8BE042FE0E3BB020077
+:10A65000EFBA02001ABD0200CCC002000CBE02001C
+:10A660000EBD02003CC202001EC0020066BB02001A
+:10A67000C8BF020050BD0200AFBB020037BF0200DE
+:10A68000A3C20200EAC002006ABC020016BB0200BC
+:10A6900022BF020079BA0200FBBD0200E5BF020042
+:10A6A0004DBE020091C2020086F8BB04FF22994908
+:10A6B0002846EAF72BF8FF2286F8BF049649284679
+:10A6C000EAF724F8954986F8C0042846EAF72AF8FC
+:10A6D0000022A6F8C20492492846EAF717F8002299
+:10A6E00086F818058F492846EAF710F8C0B286F8B0
+:10A6F0001A05EB69DB685B6C03F00703052B03D9D4
+:10A7000010B1002386F81A35874900222846E9F758
+:10A71000FDFF864986F81C0500222846E9F7F6FF6A
+:10A72000834986F81D054FF0FF322846E9F7EEFF12
+:10A73000804986F81E0500222846E9F7E7FF7E4992
+:10A7400086F895054FF0FF322846E9F7DFFF7B4991
+:10A75000A6F8200501222846E9F7D8FF784986F8AF
+:10A7600027054FF0FF322846E9F7D0FF7549A6F8D4
+:10A770002A054FF0FF322846E9F7C8FF7249A6F8CC
+:10A780002C0500222846E9F7C1FF704986F83A05F2
+:10A7900000222846E9F7BAFF6D4986F83B054FF0DD
+:10A7A000FF322846E9F7B2FF6A4986F83C05284699
+:10A7B000E9F784FF30B128466649E9F7B3FF86F828
+:10A7C000420503E04FF0FF3386F8423528466249E0
+:10A7D000E9F774FF30B128465F49E9F7A3FFA6F80F
+:10A7E000440503E04FF0FF33A6F844355B492846A3
+:10A7F0004FF0FF32E9F78AFF5949A6F8900528463D
+:10A80000E9F75CFF30B301245549002286F8524530
+:10A810002846E9F775FF524986F85305224628462F
+:10A82000E9F76EFF4E4986F8540502222846E9F7FB
+:10A8300067FF4B4986F8550503222846E9F760FF74
+:10A84000474986F8560504222846E9F759FF86F855
+:10A85000570501E086F8520542494FF0FF3228467D
+:10A86000E9F754FF404986F858054FF0FF32284673
+:10A87000E9F74CFF3D4986F859054FF0FF3228466D
+:10A88000E9F744FF3A4986F85A0500222846E9F7D5
+:10A890003DFF384986F8700500222846E9F736FF63
+:10A8A000032286F8800534492846E9F72FFF33490B
+:10A8B00086F881052846E9F735FF314986F8820593
+:10A8C0002846E9F72FFF2F49A6F884052846E9F71F
+:10A8D00029FF2D49A6F886052846E9F723FF2B49CD
+:10A8E000A6F888052846E9F71DFF2949A6F88A0534
+:10A8F0002846E9F717FF2749C6F88C0500222846A5
+:10A90000E9F704FF86F89405012000E0002006B076
+:10A91000BDE8F08145C102008CC10200DABA020034
+:10A920001DBA0200CFBD02005EBE0200B2C002002E
+:10A93000ACBE020003BA0200FABB0200F1B9020089
+:10A940002ABB020081BE020086BB02009FB9020042
+:10A950009CBD0200D6BC02006DBA02000FBC020012
+:10A960008ABA0200A6BD020039C0020090BB0200F4
+:10A9700043BD02004DBC020022BC02007FBC0200AD
+:10A9800028C0020088C00200D9BE020047BF0200F2
+:10A9900022BD0200CBC10200C36970B504460E4659
+:10A9A00098684FF4B961DCF393F1C4F8A80000286B
+:10A9B0005CD000214FF4B962D7F342F3E369D4F8D5
+:10A9C000A8501B6D13F4803F05D1012241F22403EE
+:10A9D00084F81A26E254E369D868E4F7B5FF41F237
+:10A9E0000803E0500023EB63214B20462362214BF8
+:10A9F00031466362204BA362204BE362204BA36786
+:10AA0000204BE367204BC4F89030204BC4F88430CF
+:10AA10001F4B23631F4B63631F4BE3631F4B636435
+:10AA20001F4B63651F4BA3651F4BC4F88C301F4B36
+:10AA3000C4F888301E4BE3661E4BC4F89C301E4B96
+:10AA4000C4F8A0301D4BC4F8A430FEF7D7FF68B19E
+:10AA50002046EBF757FD2046FEF73AFF30B120467F
+:10AA6000FEF790FF003818BF012000E0002070BD05
+:10AA7000A9D00100E54A010091CD010055A20100D5
+:10AA8000B9A001001D4F010075A901005DA90100D9
+:10AA9000CD9B0100BD8701003D9C0100FD840100AC
+:10AAA0009D550100A15701007DCC0100C54B01005F
+:10AAB000B1530100198801001582010045CC010045
+:10AAC00010B5014620B103680C221868DCF310F1C0
+:10AAD00010BDC0462DE9F04105460F4600680C2127
+:10AAE0001646DCF3F5F008B9044607E004460021F9
+:10AAF0000C22D7F3A5F225606660A7602046BDE86A
+:10AB0000F081C04610B5044650B10649224640685F
+:10AB1000F9F31AF263682146D8688822DCF3E8F07A
+:10AB200010BDC04603E88600F0B5882185B0054613
+:10AB30004068DCF3CDF0074608B904463BE000214D
+:10AB400088220446D7F37CF22B683D607B600026A8
+:10AB500004212846194A1A4B0096019700F0EEF896
+:10AB6000B042B86021DB174B019600930296039622
+:10AB700078681549154A3B46F9F3AEF1A8B91E238A
+:10AB80007B610423FB7302233B74083301227B7433
+:10AB90004FF6AF7384F82000FA773A73BA61A07465
+:10ABA0006073A073BB83BA7705E068683946882272
+:10ABB000DCF39EF00024204605B0F0BD5123850053
+:10ABC00025238500811485002C1D020003E88600E2
+:10ABD00070B50468CCB1D4F8F811A56829B1A8689B
+:10ABE000E4F34EF50023C4F8F831084928682246FA
+:10ABF000F9F3AAF1216819B168681C22DCF378F036
+:10AC0000686821466269DCF373F070BD441D020080
+:10AC10002DE9FF4740F2C45681468A461046314628
+:10AC200017469846DCF354F00446002879D00021FA
+:10AC30003246D7F305F238461C21DCF349F00546CD
+:10AC4000206030B9384621463246DCF351F02846C0
+:10AC500067E000211C22D7F3F3F122684FF0FF33A5
+:10AC6000A36100254FF014036661C4F80890E76003
+:10AC7000C4F804809571A4F808324FF02803A4F8B2
+:10AC800006324FF02D03A4F804324FF0FA03A4F873
+:10AC90000A320223146084F80C324FF06403A4F8E3
+:10ACA0003E3284F80D5250461F4922462B46E4F3AB
+:10ACB00003F5C4F8F80108B30523C4F81C32373390
+:10ACC000C4F8283204F51072184BC4F81822C4F8DE
+:10ACD000142204F53D72C4F82422C4F82022009303
+:10ACE000134BD9F8000003931249134A23460195E8
+:10ACF0000295F9F3F1F008B9206812E0D4F8F811E0
+:10AD000011B15046E4F3BCF4216819B138461C2255
+:10AD1000DBF3EEF73846214640F2C452DBF3E8F7A6
+:10AD2000002004B0BDE8F087C13C8500F537850000
+:10AD300035D201004C1D0200441D020070B5D0F850
+:10AD400000451E46A3698E460F2B154602D94FF0CB
+:10AD5000FF3011E01801E1690133A361049B42183F
+:10AD60009360059B5660D36062694550D31C734461
+:10AD700023F003036361104670BDC04610B5014661
+:10AD800040B190F820200368D200D86802F5927292
+:10AD9000DBF3AEF710BDC046C36908221B692DE97D
+:10ADA000F041073393FBF2F3DFB2FB0003F5927639
+:10ADB00005463146C068DBF38BF708B9044614E05A
+:10ADC000044632460021D7F33BF104F12403E3614A
+:10ADD000FAB204F59273E36003EB820323614FF44C
+:10ADE0000373256084F8207063612046BDE8F0811C
+:10ADF0007047C0462DE9F04F3B4F89B038683B495A
+:10AE0000D7F3BAF50128DFF81881DFF8189157D089
+:10AE1000DFF800C1364EDCF8001000220091354901
+:10AE200013680968344D354C0291316834480193F8
+:10AE300004912B68216803930691036831490593B7
+:10AE40000B68DFF8D4E007932A4B02602E481A60A3
+:10AE50000A602E4B08F10401D7F800A0DEF800B01C
+:10AE60003A60CEF80020CCF8002032602260091A47
+:10AE7000013A2B60D7F3D4F5254B9842FCD11A4BFD
+:10AE80000099C3F800A0234B1960234B0021C3F89D
+:10AE900000B00A68214B1A60019A164B0A600299A9
+:10AEA000039A1960144B04991A60114B059A1960A2
+:10AEB000134B06991A60114B079A1960114B1A60CF
+:10AEC00098F81B3089F8003098F81C3089F8013068
+:10AED00098F81D3089F8023098F81E3089F8033050
+:10AEE00009B0BDE8F08FC046FC1E0200B81D02008C
+:10AEF00044EC000048EC000034EC000050EC000092
+:10AF00004CEC000054EC000000000000DDBAADBBCA
+:10AF1000E320BBDE001F0200F81E020038EC000038
+:10AF2000005903001C2802002DE9F04F91B0FFF7F3
+:10AF300061FF684B1B68043B012B03D8664B186804
+:10AF4000FFF756FFFBF7BEF800210746E0F3AEF12E
+:10AF500038460021E0F364F128B1036A002BBCBF3E
+:10AF60004FF0004303620EA90822B86BD7F3F6F244
+:10AF7000FA6B0B9038460C92E4F7E6FC574E00F55E
+:10AF8000424000F5A870B0FBF6F00D903846E4F7AB
+:10AF9000DBFC04463846E4F7D7FC00F54248384667
+:10AFA000E4F7DCFC00F5424A3846E4F7D7FC04F548
+:10AFB000424408F5A87804F5A874B8FBF6F808FB35
+:10AFC000164804463846E4F7C9FC00F542453846C1
+:10AFD000E4F708FA00F542493846E4F703FA04F5C5
+:10AFE000424405F5A87504F5A874B5FBF6F505FB14
+:10AFF000164504463846E4F7F5F9394A00F542406B
+:10B00000019204F542440B9A00F5A870B0FBF6F0EB
+:10B010000AF5A87A09F5A87904F5A874BAFBF6FA36
+:10B02000B9FBF6F9029200FB16460C9ADFF8D4B091
+:10B0300003920D9A2B4B04922B492C4AB8FBFBF838
+:10B04000B5FBFBF5B6FBFBF629480093CDF8148061
+:10B05000CDF818A00795CDF820900996E6F724FBC7
+:10B06000244840F60D0144F2F432FAF7AFFF48B13C
+:10B07000204840F6290144F2F432FAF7A7FF08B15C
+:10B08000002403E01C4A1D4B1A4C1A603846FDF799
+:10B09000D7FA44F218334FF6FF72904214BF0246BB
+:10B0A0001A4640F612011648FAF790FF144B002892
+:10B0B0000CBF194600214CB141B1104B20461B6812
+:10B0C0005B689847236920465B689847384611B00B
+:10B0D000BDE8F08F54EC000050EC000040420F003F
+:10B0E000A0D60100ABFF8600BE1D0200C31D0200FA
+:10B0F000E8D102004C1F0200281F0200F8260000C1
+:10B10000F81D0200A0860100776C25643A20427287
+:10B110006F6164636F6D2042434D25642038303287
+:10B120002E313120576972656C65737320436F6EE1
+:10B1300074726F6C6C65722025730A0025733A2057
+:10B1400042726F6164636F6D20534450434D4420DD
+:10B15000434443206472697665720A0073647063C5
+:10B160006D6463646325640072737369736D663222
+:10B17000673D2564007874616C667265713D256475
+:10B1800000616132673D3078257800627734307035
+:10B190006F3D30782578006C6564626825643D30C9
+:10B1A0007825780074737369706F7332673D3078F7
+:10B1B0002578007273736973617632673D25640088
+:10B1C0006C65676F66646D3430647570706F3D30A8
+:10B1D0007825780070613168696D61787077723DAB
+:10B1E0002564006D617870326761303D3078257874
+:10B1F000007061316974737369743D2564006D6119
+:10B200006E6669643D307825780073756276656E88
+:10B210006469643D30782578002004D0023643FF0D
+:10B22000FF626F617264747970653D3078257800D3
+:10B230006D6373256467706F25643D3078257800F1
+:10B240006D616E663D2573006D61787035676C6168
+:10B25000303D30782578006D61787035676C6131EC
+:10B260003D30782578006F66646D35676C706F3D92
+:10B27000307825780072737369736D6335673D2587
+:10B280006400626F617264666C616773323D30782E
+:10B29000257800747269736F32673D3078257800C5
+:10B2A0007064657472616E676532673D30782578C9
+:10B2B000006D63736277323035676C706F3D307844
+:10B2C00025780000006D637362773230756C3567E6
+:10B2D0006C706F3D30782578006D63736277343021
+:10B2E00035676C706F3D30782578000000706131F3
+:10B2F0006C6F6D61787077723D2564006D61787058
+:10B30000326761313D30782578007278706F35672B
+:10B310003D2564006D63733332706F3D307825785E
+:10B320000073756264657669643D307825780069DC
+:10B330007474356761303D307825780069747435F0
+:10B340006761313D30782578007061316D617870CA
+:10B3500077723D256400626F6172647265763D307C
+:10B36000782578006D6373627732303267706F3D95
+:10B37000307825780000006D637362773230756C29
+:10B380003267706F3D30782578006D637362773473
+:10B39000303267706F3D307825780000006D637340
+:10B3A0006277323035676D706F3D307825780000F8
+:10B3B000006D637362773230756C35676D706F3D09
+:10B3C00030782578006D63736277343035676D703F
+:10B3D0006F3D3078257800000073726F6D7265766E
+:10B3E0003D2564007770736C65643D256400706171
+:10B3F000316C6F62303D2564007061316C6F623179
+:10B400003D2564007061316C6F62323D25640070CF
+:10B410006125646725637725646125643D3078255F
+:10B42000780070613062303D2564007061306231B7
+:10B430003D25640070613062323D25640072737393
+:10B4400069736D6332673D2564007472693567689E
+:10B450003D25640075736266733D25640063636B0C
+:10B46000706F3D307825780074726935676C3D25C2
+:10B4700064006F66646D356768706F3D307825785D
+:10B4800000616725643D30782578006578747061C7
+:10B490006761696E35673D307825780070726F643A
+:10B4A0007563746E616D653D257300636464706FD0
+:10B4B0003D30782578006C65676F66646D62773221
+:10B4C0003035676C706F3D307825780000006C6512
+:10B4D000676F66646D62773230756C35676C706F5C
+:10B4E0003D30782578006C65676F66646D627732F1
+:10B4F0003035676D706F3D307825780000006C65E1
+:10B50000676F66646D62773230756C35676D706F2A
+:10B510003D30782578006C65676F66646D627732C0
+:10B5200030356768706F3D307825780000006C65B5
+:10B53000676F66646D62773230756C356768706FFF
+:10B540003D30782578007278706F32673D25640051
+:10B550007278636861696E3D30782578006974742B
+:10B56000326761303D3078257800697474326761E4
+:10B57000313D3078257800616E7473776974636843
+:10B580003D30782578007478636861696E3D307865
+:10B5900025780070726F6469643D3078257800709A
+:10B5A00061306974737369743D25640063636B640F
+:10B5B000696766696C74747970653D2564006368B9
+:10B5C00069707265763D2564006F66646D356770DD
+:10B5D0006F3D30782578006C656464633D30782574
+:10B5E000303478006D61787035676861303D30784F
+:10B5F0002578006D61787035676861313D30782558
+:10B60000780070613162303D2564007061316231D3
+:10B610003D25640070613162323D256400627764CB
+:10B620007570706F3D30782578006D617870356782
+:10B6300061303D30782578006D6178703567613113
+:10B640003D3078257800616E74737763746C35676C
+:10B650003D30782578006D63732564672563706FCE
+:10B6600025643D30782578006D637362773230351C
+:10B670006768706F3D307825780000006D637362F5
+:10B68000773230756C356768706F3D30782578009B
+:10B690006D637362773430356768706F3D3078253D
+:10B6A0007800000074726935673D2564006F706F23
+:10B6B0003D25640076656E6469643D3078257800C8
+:10B6C0006C65676F66646D627732303267706F3DAC
+:10B6D0003078257800006C65676F66646D6277323C
+:10B6E00030756C3267706F3D307825787061306DE1
+:10B6F00061787077723D25640070613168696230ED
+:10B700003D256400706131686962313D25640070D7
+:10B710006131686962323D256400637573746F6DD1
+:10B7200076617225643D30782578007265677265B0
+:10B73000763D3078257800626F617264666C61676F
+:10B74000733D307825780062786132673D2564006A
+:10B750006F656D3D2530327825303278253032786E
+:10B7600025303278253032782530327825303278DD
+:10B77000253032780064657669643D30782578003C
+:10B7800070612564677725646125643D307825788C
+:10B790000072737369736D6635673D2564006F666B
+:10B7A000646D3267706F3D30782578006161356770
+:10B7B0003D30782578007770736770696F3D256438
+:10B7C0000062786135673D25640075736265706E4F
+:10B7D000756D3D307825780074737369706F7335BB
+:10B7E000673D3078257800616E74737763746C32CE
+:10B7F000673D3078257800727373697361763567B9
+:10B800003D2564006F66646D706F3D30782578006B
+:10B8100074726932673D25640073746263706F3DB2
+:10B82000307825780063636F64653D307830006D53
+:10B830006163616464723D25730063636F64653D99
+:10B84000256325630063633D25640063636B326792
+:10B85000706F3D30782578006363746C3D307825D7
+:10B86000780072656777696E646F77737A3D2564D7
+:10B870000065787470616761696E32673D30782564
+:10B880007800626F6172646E756D3D25640074723C
+:10B8900069736F35673D307825780063636B627735
+:10B8A00032303267706F3D30782578000000636376
+:10B8B0006B62773230756C3267706F3D3078257807
+:10B8C000007064657472616E676535673D30782518
+:10B8D0007800000080000000FF0000000C00000065
+:10B8E0000000000000040000FF0000000C00000049
+:10B8F0000000000000000800FF0000000E00000033
+:10B90000000000000200000001000400030000002D
+:10B91000010002000A00000002006000DC050000D7
+:10B9200008071700747870777262636B6F66003275
+:10B93000675F6367610072737369636F72726E6FC2
+:10B94000726D00747373696C696D75636F640074F4
+:10B95000656D70735F687973746572657369730080
+:10B9600072737369636F7272617474656E003567A8
+:10B970005F6367610074656D7074687265736800F9
+:10B98000696E746572666572656E6365006D63737A
+:10B990003267706F30006D63733267706F3100749F
+:10B9A000786761696E74626C356700747373696F70
+:10B9B00066667365746D696E35676C007473736960
+:10B9C0006F66667365746D696E35676D0074656D5D
+:10B9D0007073656E73655F736C6F7065006D656124
+:10B9E00073706F7765720072737369736D66326717
+:10B9F00000706C6C646F75626C65725F6D6F64650E
+:10BA000032670069716C6F7374316F6666326700FC
+:10BA100072667265673033335F63636B00706C6CA2
+:10BA2000646F75626C65725F656E61626C653267CA
+:10BA3000006F70656E6C706761696E696478613102
+:10BA400034300065787470616761696E35670065D0
+:10BA5000787470616761696E3267006F70656E6CD3
+:10BA6000706761696E69647861313439007478692E
+:10BA7000716C6F7061673267006E6F6973655F63C9
+:10BA8000616C5F7265665F3267006C6F67656E5FE1
+:10BA90006D6F646500706163616C69647832670022
+:10BAA00074656D705F616464006F70656E6C706763
+:10BAB00061696E6964786131363500706163616C0B
+:10BAC000696478356768693100706163616C6174BD
+:10BAD0006832673100706D696E00706163616C700F
+:10BAE000756C7365776964746800706D6178007354
+:10BAF000776374726C6D61705F3567006F70656E2F
+:10BB00006C7074656D70636F727200747373696DBD
+:10BB100061786E7074006E6F6973655F63616C5FEE
+:10BB2000656E61626C655F356700706163616C7042
+:10BB30007772326700747869716C6F746600706137
+:10BB400063616C69647835676C6F31007061636143
+:10BB50006C61746835676869006F70656E6C7070D1
+:10BB600077726C696D006E6F6973655F63616C5F9E
+:10BB7000646267006F70656E6C706761696E69649E
+:10BB800078613135330074786761696E74626C0076
+:10BB9000706163616C69647835676869006F7065AE
+:10BBA0006E6C706761696E69647861313537006EFB
+:10BBB0006F6973655F63616C5F7570646174650064
+:10BBC0006F66646D64696766696C747479706535F5
+:10BBD000670070616763326700766261745F6D75DC
+:10BBE0006C740073776374726C6D61705F326700A0
+:10BBF000706163616C616C696D0069716C6F636128
+:10BC00006C70777232670076626174736D63006185
+:10BC10006463726673657132670076626174736D16
+:10BC2000660072786761696E6261636B6F666676E3
+:10BC3000616C006F70656E6C706761696E696478C5
+:10BC4000622564006F66646D3267706F007278679A
+:10BC500061696E74626C776C6267610070616361C8
+:10BC60006C6174683567686931006E6F6973655F10
+:10BC700063616C5F706F5F626961735F32670072EE
+:10BC800066726567303838006F70656E6C7067611A
+:10BC9000696E696478613136310064796E707772EB
+:10BCA0006C696D656E00706163616C69647835679D
+:10BCB000310074656D70636F7272780064616372D5
+:10BCC0006174653267007061726670730070613014
+:10BCD00062325F6C6F00747869716C6F706170753F
+:10BCE00032670074656D7073656E73655F6F707435
+:10BCF000696F6E00706163616C61746835676C6F49
+:10BD00003100706163616C69647832673100747806
+:10BD1000616C706662797032670064616367633278
+:10BD20006700756E6D6F645F727373695F6F6666CF
+:10BD3000736574006F70656E6C70766F6C74636F92
+:10BD400072720072786761696E74626C31303000B3
+:10BD50006E6F6973655F63616C5F6E665F7375625A
+:10BD60007374726163745F76616C00747373697469
+:10BD70007864656C61790063636B3267706F006330
+:10BD8000636B507772496478436F72720063636BC0
+:10BD900064696766696C7474797065006C6F63635D
+:10BDA0006D6F646531006C6F696461636D6F6465AC
+:10BDB000356700706163616C617468356700746534
+:10BDC0006D705F71007273736973617632670073AF
+:10BDD00070757261766F69645F656E61626C653201
+:10BDE000670070613062315F6C6F00766261745F12
+:10BDF00071006D61787032676130006E6F697365D4
+:10BE00005F63616C5F7265665F3567006F66646D66
+:10BE1000616E616C6F6766696C746277326700701F
+:10BE20006163616C61746832670070613062300018
+:10BE30007061306231007061306232006F70656E27
+:10BE40006C706761696E696478613336006E6F6922
+:10BE500073655F63616C5F61646A5F356700697118
+:10BE60006C6F63616C69647832676F666673006FCC
+:10BE700070656E6C706761696E69647861313030CD
+:10BE800000706163616C7077723267310072617744
+:10BE900074656D7073656E7365006F70656E6C7040
+:10BEA0006761696E696478613130340069716C6F03
+:10BEB00063616C6964783267006F70656E6C707076
+:10BEC00077726374726C006F70656E6C7067616915
+:10BED0006E696478613130380072786761696E74B8
+:10BEE000656D70636F727235676D0074785F746F23
+:10BEF0006E655F706F7765725F696E646578006FFD
+:10BF000070656E6C707265667077720072737369BB
+:10BF1000736D63326700706163616C61746835676B
+:10BF200031006E6F6973655F63616C5F706F5F6234
+:10BF30006961735F3567006E6F6973655F63616C1C
+:10BF40005F706F5F32670072786761696E74656DEC
+:10BF500070636F727235676C00706163616C6964E5
+:10BF600078356731746800706167633567007061A8
+:10BF700063616C69647835676C6F317468007473E1
+:10BF800073696F66667365746D696E006F70656E58
+:10BF90006C706761696E696478613430006F7065D8
+:10BFA0006E6C706761696E696478613434007266C2
+:10BFB000726567303333006F70656E6C70676169EE
+:10BFC0006E696478613438006E6F6973655F6361B0
+:10BFD0006C5F686967685F6761696E007266726549
+:10BFE00067303338006E6F6973655F63616C5F61E2
+:10BFF000646A5F3267006D656173706F7765723177
+:10C00000006D656173706F77657232006F70656E79
+:10C010006C706761696E6964786131313600627095
+:10C0200068797363616C650072786761696E7465C5
+:10C030006D70636F7272326700706163616C696406
+:10C040007835676C6F0061613267006F66646D649C
+:10C05000696766696C74747970650074656D705F8A
+:10C060006D756C74007662617473617600706163E3
+:10C07000616C61746835676C6F00706163616C69D5
+:10C08000647832673174680072786761696E7465CC
+:10C090006D70636F72723567680063636B5077729F
+:10C0A0004F6666736574007478707772696E646544
+:10C0B000780069716C6F63616C69647835676F666D
+:10C0C00066730070613062305F6C6F00676D67632C
+:10C0D000326700706163616C6964783567686931E3
+:10C0E0007468007278706F3267006E6F6973655F95
+:10C0F00063616C5F656E61626C655F3267006F7073
+:10C10000656E6C706761696E696478613532006F65
+:10C1100070656E6C706761696E6964786135360050
+:10C120006F70656E6C706761696E696478613131DA
+:10C130003200706163616C69647835670074656DA5
+:10C140007073617600747269736F32670076626132
+:10C15000745F616464006F70656E6C706761696EB6
+:10C1600069647861313230006F70656E6C70676140
+:10C17000696E69647861313234006F70656E6C701D
+:10C180006761696E6964786131323800747269641C
+:10C19000783267006F66646D64696766696C747491
+:10C1A000797065326700696E69747869647832679E
+:10C1B0000068775F697163616C5F656E00697163C8
+:10C1C000616C5F7377705F646973006D75785F672A
+:10C1D00061696E5F7461626C6500747373696F6628
+:10C1E000667365746D617835676800747373696F21
+:10C1F00066667365746D617835676C007473736916
+:10C200006F66667365746D617835676D0074656D12
+:10C2100070736D630074656D70736D660074737315
+:10C22000696F66667365746D6178006F70656E6CBA
+:10C23000706761696E696478613630007478616C2A
+:10C24000706662797032675F63636B006F70656EF2
+:10C250006C706761696E6964786136340066726516
+:10C26000716F66667365745F636F7272006F70657D
+:10C270006E6C706761696E69647861313332006F2A
+:10C2800070656E6C706761696E69647861313336B0
+:10C29000007874616C6D6F646500747373697469A0
+:10C2A0006D65006E6F6973655F63616C5F706F5F72
+:10C2B000356700747373696F66667365746D696E54
+:10C2C00035676800B8C70200600000001200000077
+:10C2D000000000002000000028C702002600000027
+:10C2E0000E0000000000000010000000B4CC0200AE
+:10C2F000980000000D000000000000002000000079
+:10C3000074C702004400000011000000000000009B
+:10C310000800000074D102001000000010000000AE
+:10C3200000000000080000000000000040000000C5
+:10C3300080000000C00000000100000005000000B7
+:10C3400002000000060000000A0000004A00000091
+:10C350008A000000CA0000000A0100004A01000033
+:10C360008A0100008A0500008A0900008A0D000089
+:10C370008A1100008A5100008A9100008AD10000D1
+:10C380008A1101008A5101008A9101008900000090
+:10C390008AD101008A1102000000000000000000A4
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000003001300410300131F
+:10C4B000004003001200410300120040030011007D
+:10C4C0004103001100400300100041030010004030
+:10C4D000030010003E030010003C030010003A036C
+:10C4E000000F003D03000F003B03000E003D030062
+:10C4F0000E003C03000E003A03000D003C03000D4B
+:10C50000003B03000C003E03000C003C03000C0049
+:10C510003A03000B003E03000B003C03000B003B02
+:10C5200003000B003903000A003D03000A003B032F
+:10C53000000A0039030009003E030009003C030023
+:10C5400009003A0300090039030008003E0300080F
+:10C55000003C030008003A0300080039030008000B
+:10C5600037030007003D030007003C030007003AC3
+:10C5700003000700380300070037030006003E03EE
+:10C580000006003C030006003A03000600390300E1
+:10C5900006003703000600360300060034030005DA
+:10C5A000003D030005003B030005003903000500C2
+:10C5B000380300050036030005003503000500338D
+:10C5C000030004003E030004003C030004003A039F
+:10C5D00000040039030004003703000400360300A0
+:10C5E000040034030004003303000400310300049A
+:10C5F0000030030004002E030003003C030003008E
+:10C600003A03000300390300030037030003003638
+:10C61000030003003403000300330300030031036D
+:10C6200000030030030003002E030003002D03006D
+:10C6300003002C030003002B030003002903000266
+:10C64000003D030002003B0300020039030002002A
+:10C6500038030002003603000200350300020033F5
+:10C6600003000200320300020030030002002F0327
+:10C670000002002E030002002C030002002B030026
+:10C6800002002A030002002903000200270300021F
+:10C69000002603000200250300020024030002001C
+:10C6A00023030002002203000200210300020020F5
+:10C6B000030001003F030001003D030001003B03B4
+:10C6C00000010039030001003803000100360300B7
+:10C6D00001003503000100330300010032030001B3
+:10C6E0000030030001002F030001002E03000100B1
+:10C6F0002C030001002B030001002A030001002984
+:10C7000003000100270300010026030001002503A8
+:10C7100000010024030001002303000100220300A4
+:10C7200001002103000100200004000400040004B3
+:10C7300000040004000400040004000400040104D8
+:10C7400080048204830484040004000400040004C0
+:10C7500000040004000400040004010480048204B6
+:10C760008304840485048604050506050705080579
+:10C7700009050A05090C12181818090C12181818BE
+:10C7800000000C076F7A060C0F7B7E0105080B0E6C
+:10C79000110000000000000000000306090C0F1249
+:10C7A000000000000000000000000306090C00006B
+:10C7B0000000000000000000000000000400000075
+:10C7C0004000000080000000C000000001000000E8
+:10C7D000050000004500000085000000C5000000C5
+:10C7E00005010000450100008501000085050000ED
+:10C7F00085090000850D000089090000890D0000F1
+:10C8000089110000895100008991000089D1000040
+:10C8100089110100854D0000858D000085CD000047
+:10C820008951010089910100000000000000000012
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000008000800080008000F7
+:10C9400080008000800080008000810082008300E1
+:10C9500084008500040105018000800080008000C3
+:10C9600080008000800081008200830084008500B8
+:10C9700004010501060107011901870188018901E8
+:10C980008A018B0107001F004807001F00460700AF
+:10C990001F004407001E004307001D004407001C41
+:10C9A000004407001B004507001A00460700190055
+:10C9B0004607001800470700170048070017004601
+:10C9C0000700160047070015004807001500460736
+:10C9D000001500440700150042070015004007003D
+:10C9E00015003F0700140040070013004107001323
+:10C9F000004007001200410700120040070011002C
+:10CA000041070011004007001000410700100040DE
+:10CA1000070010003E070010003C070010003A0716
+:10CA2000000F003D07000F003B07000E003D070010
+:10CA30000E003C07000E003A07000D003C07000DF9
+:10CA4000003B07000C003E07000C003C07000C00F8
+:10CA50003A07000B003E07000B003C07000B003BB1
+:10CA600007000B003907000A003D07000A003B07DA
+:10CA7000000A0039070009003E070009003C0700D2
+:10CA800009003A0700090039070008003E070008BE
+:10CA9000003C070008003A070008003907000800BA
+:10CAA00037070007003D070007003C070007003A72
+:10CAB00007000700380700070037070006003E0799
+:10CAC0000006003C070006003A0700060039070090
+:10CAD0000600370700060036070006003407000589
+:10CAE000003D070005003B07000500390700050071
+:10CAF000380700050036070005003507000500333C
+:10CB0000070004003E070004003C070004003A0749
+:10CB1000000400390700040037070004003607004E
+:10CB20000400340700040033070004003107000448
+:10CB30000030070004002E070003003C070003003C
+:10CB40003A070003003907000300370700030036E7
+:10CB50000700030034070003003307000300310718
+:10CB600000030030070003002E070003002D07001C
+:10CB700003002C070003002B070003002907000215
+:10CB8000003D070002003B070002003907000200D9
+:10CB900038070002003607000200350700020033A4
+:10CBA00007000200320700020030070002002F07D2
+:10CBB0000002002E070002002C070002002B0700D5
+:10CBC00002002A07000200290700020027070002CE
+:10CBD00000260700020025070002002407000200CB
+:10CBE00023070002002207000200210700020020A4
+:10CBF000070001003F070001003D070001003B075F
+:10CC000000010039090C12181818090C121818180C
+:10CC100000000C076F7A060C0F7B7E0105080B0ED7
+:10CC2000110000000000000000000306090C0F12B4
+:10CC3000000000000000000000000306090C0000D6
+:10CC4000000000000000000007001000390700107D
+:10CC500000380700100036070010003407001000ED
+:10CC60003307001000310700100030070010002FBC
+:10CC7000070010002D070010002C070010002B07E4
+:10CC80000010002A070010002807001000270700E6
+:10CC900010002607001000250700100024070010D0
+:10CCA00000230700100022070010002107001000D9
+:10CCB0002000000000000000400000000000000014
+:10CCC00040000000000000004000000000000000E4
+:10CCD00040000000000000004000000000000000D4
+:10CCE00040000000000000004000000000000000C4
+:10CCF00040000000000000004000000000000000B4
+:10CD00004000000000000000400000000000001093
+:10CD1000400000000000000048000000000000206B
+:10CD20004800000000000030480000000000004003
+:10CD300048000000000000504800000000000060B3
+:10CD4000480000000000005050000000000000609B
+:10CD50005000000000000070500000000000008043
+:10CD6000500000000000009050000000000000A0F3
+:10CD700050000000000000B050000000000000C0A3
+:10CD800050000000000000D050000000000000E053
+:10CD900050000000000000F050000000000000E023
+:10CDA00058000000000000005900000000000010C2
+:10CDB0005900000000000020590000000000003071
+:10CDC0005900000000000040590000000000005021
+:10CDD0005900000000000060590000000000000041
+:10CDE00040000000000000004000000000000000C3
+:10CDF00040000000000000004000000000000000B3
+:10CE000040000000000000004000000000000000A2
+:10CE10004000000000000000400000000000000092
+:10CE20004000000000000010400000000000000072
+:10CE30004800000000000020480000000000003012
+:10CE400048000000000000404800000000000050C2
+:10CE50004800000000000060480000000000005092
+:10CE60005000000000000060500000000000007052
+:10CE70005000000000000080500000000000009002
+:10CE800050000000000000A050000000000000B0B2
+:10CE900050000000000000C050000000000000D062
+:10CEA00050000000000000E050000000000000F012
+:10CEB00050000000000000705100000000000080E1
+:10CEC0005100000000000090510000000000002010
+:10CED0005900000000000030590000000000004030
+:10CEE00059000000000000505900000000000060E0
+:10CEF00059000000000000A059000000000000B030
+:10CF000059000000000000000000000000000000C8
+:10CF10000000000000000000080000000000000009
+:10CF200008000000000000000800000000000000F1
+:10CF300008000000000000000800000000000000E1
+:10CF400008000000000000000800000000000000D1
+:10CF500008000000000000000800000000000010B1
+:10CF60000800000000000020080000000000003061
+:10CF70000800000000000040080000000000005011
+:10CF800008000000000000401000000000000050F9
+:10CF900010000000000000601000000000000070A1
+:10CFA0001000000000000080100000000000007071
+:10CFB0001800000000000080180000000000009031
+:10CFC00018000000000000A018000000000000B0E1
+:10CFD00018000000000000C018000000000000D091
+:10CFE00018000000000000E018000000000000F041
+:10CFF00018000000000000001900000000000010F0
+:10D00000190000000000002019000000000000309E
+:10D01000190000000000004019000000000000504E
+:10D0200019000000000000601900000000000070FE
+:10D03000190000000000008019000000000000003E
+:10D0400008000000000000000800000000000000D0
+:10D0500008000000000000000800000000000000C0
+:10D0600008000000000000000800000000000000B0
+:10D070000800000000000010080000000000002070
+:10D080000800000000000030080000000000004020
+:10D0900008000000000000500800000000000040F0
+:10D0A00010000000000000501000000000000060B0
+:10D0B0001000000000000070100000000000009050
+:10D0C0001100000000000070180000000000008047
+:10D0D000180000000000009018000000000000A0F0
+:10D0E00018000000000000B018000000000000C0A0
+:10D0F00018000000000000D018000000000000E050
+:10D1000018000000000000F01800000000000000FF
+:10D1100019000000000000101900000000000020AD
+:10D12000190000000000003019000000000000405D
+:10D13000190000000000005019000000000000600D
+:10D1400019000000000000701900000000000080BD
+:10D1500019000000000000A019000000000000B04D
+:10D1600019000000000000000000000000000000A6
+:10D17000000000005F36291F5F36291F5F36291F18
+:10D180005F36291F28C30200600000001200000063
+:10D19000000000002000000038C902002600000046
+:10D1A0000E000000000000001000000014CF02007C
+:10D1B000980000000D0000000000000020000000AA
+:10D1C00004CC020044000000110000000000000038
+:10D1D0000800000074D102001000000010000000E0
+:10D1E00000000000080000000A5254452028257362
+:10D1F0002D25732573257329202573206F6E2042FA
+:10D20000434D25732072256420402025642E25641B
+:10D210002F25642E25642F25642E25644D487A0A17
+:10D22000000000002DE9FF4106460D460846FC219E
+:10D2300017469846D9F34CF5044608B91E302DE040
+:10D240000021FC22D4F3FCF60A9B04F1640204F1F1
+:10D250006801009301920291304629463A464346BE
+:10D26000FBF73EFC206608B90B2017E040F61201E0
+:10D270000022DDF3C3F700210A46E0662560206E38
+:10D28000DDF3E0F52046F8F707FB206EFBF7EAFA3E
+:10D2900028462146FC22D9F32BF5002004B0BDE836
+:10D2A000F081C04601BC600300104E03BFDE02F0F7
+:10D2B0000C0E0280C12700000403BFDE02F00D6FD8
+:10D2C000035B5E02F0000601BC6013001043000126
+:10D2D0005E02F0000000025E02F0117A00025E02BF
+:10D2E000F0118F020200BF00007302045EFF000015
+:10D2F0000E006B446557800E01846002F7F7BF0192
+:10D30000BC6003000AAE00025E02F00F960202DE6D
+:10D31000FF000013006B44655620130182E002F702
+:10D32000F7BF03BFDE02F005A200682B6F000018F4
+:10D330000280DEFF000073006B44655B6073018454
+:10D34000E006F577AB00025E02F0112F020480C701
+:10D3500000001A028180C700001C01806002F7F7FC
+:10D36000BF01BC6003000AE200682B070000270031
+:10D37000E844655837A1006DDE8557402300682BCF
+:10D380004300002700E844655A17A1006DDE855769
+:10D39000402503BFDE02F0002701BC6003000AC283
+:10D3A00001BC6003000AC101BC6003000AD001BCDB
+:10D3B0006003000AC80202DEB300002A0200420332
+:10D3C00000002A00025E02F00B1602845EB3000029
+:10D3D000730068AB0F0000730283DEB700002E02FB
+:10D3E0000180C700004800B02ACB0017A202802BA2
+:10D3F000F300003500B02B230017A1006DDE855C23
+:10D40000E06400685E8700003500682C0700003586
+:10D4100000B02C070017A200682B0B00003A00E8B0
+:10D4200044655857A1006DDE86F4406400E05E85D7
+:10D4300055F7A1006DDE86F440640202DEBB0000F9
+:10D440004800682ABB00004800E8446556D7A100A0
+:10D45000E02ABB0157A2006EDE86F440420182E062
+:10D4600002F5D7AE01BC6003000AAE03BFDE02F0D6
+:10D47000004800E82ABAF437A100902ABB0037A27E
+:10D48000006E2ABEF4404600B02ABF0017A2006911
+:10D49000DE86F4404803BFDE02F000640283DEB79C
+:10D4A00000005C028881AB00005A02035EB70000F6
+:10D4B00073020480C700004D02005EFF00005A02A4
+:10D4C0008080BF00005A0204DEB700005100682BC4
+:10D4D0001708607303BFDE02F0005A028400C70021
+:10D4E0000053028600C700005500682B0B00005A4D
+:10D4F00002812C4700005A00E844655737A1006DAF
+:10D50000DE8558005A006CC46557607300B04467EC
+:10D51000000ABB02845EB700007300025E02F011D5
+:10D520004903BFDE02F0007301BC63FF1FF7A100D7
+:10D53000684586F4205A0203C57300006402845EC5
+:10D54000B7000064020100C7000073006B44655718
+:10D5500080730020E3FE1460730282DEBB00007360
+:10D5600002022C470000670282DEBB00006703BF97
+:10D57000DE02F0005A028881AB0000730282DEB343
+:10D58000000073028080BF0000730284DEAF0000E1
+:10D590007302825EBB00007303A0DE02F0006F0224
+:10D5A00000420300006F00025E02F00B1601836070
+:10D5B00002F5B7AD0184E006F577AB01BC6003006E
+:10D5C0000AC300B04467000AC4018060020D906C79
+:10D5D00003595E02F0007503D85E02F0007603D8AE
+:10D5E000DE02F0007701BC618300112900B0007BEE
+:10D5F00000112B01BC630300112303125E02F00A29
+:10D600008F03975E02F00B2703D05E02F002F40353
+:10D61000D0DE02F0051003D5DE02F00A4C03915E65
+:10D6200002F005760396DE02F00A470288C1730015
+:10D63000009E03C45E02F006E703C75E02F0071611
+:10D6400003DCDE02F011CF03AA5E02F00759038665
+:10D65000DE02F00A870287C037000A8703835E0272
+:10D66000F008AB0391DE02F005F803C2DE02F00A17
+:10D67000EC00025E02F00F9500025E02F0117A03E8
+:10D68000D4DE02F0068103A3DE02F0000200025E97
+:10D6900002F00C6300025E02F00EC403A25E02F010
+:10D6A000009B03565E02F000980186600609104850
+:10D6B000031F5E02F00098006A5E2300009700B02E
+:10D6C000002700178800E85E2300378803A65E0263
+:10D6D000F0010500025E02F00F5D0028600E08E117
+:10D6E0002803C4DE02F00B5E0020C20300213003D9
+:10D6F000BFDE02F0017D03815E02F000A00300DEC8
+:10D7000002F000820188E0020B905C03BFDE02F0B1
+:10D7100002F1028740630000A20282C1070000A359
+:10D7200001866006F43018028640630000A500B050
+:10D730005E870017A10002DE02F00000028740634E
+:10D740000000A800B05E8B0010190186E006F430DE
+:10D75000180281DEAF0000AD0286C0630000AC009D
+:10D76000B05E870017A10002DE02F0000001BC607D
+:10D77000030280060280DE070000B901DA6002F0D1
+:10D78000178002085E070000C901BC60031E17A1D4
+:10D7900000E05E02F4306501BC60031C17A100E0EC
+:10D7A0005E02F4306401BC600300281803BFDE028F
+:10D7B000F000CF01105E030017A100885E870037DC
+:10D7C000A200E05E86F457A100E0015AF430630243
+:10D7D0008600C30000C200B0560B00106200B054B7
+:10D7E0000300106201BC600300281803BFDE02F0D2
+:10D7F00000D100B0418F0010620109DE030017A1C3
+:10D8000000885E870057A100E05E850597A100E0D3
+:10D810005E8703C00601BC600300481803BFDE0238
+:10D82000F000D101BC60070217A100E05E02F430F5
+:10D830006501BC60070017A100E05E02F4306401DE
+:10D84000BC600318000601BC600300081800B05A51
+:10D850000300106200B0580300106301050143008B
+:10D8600017A10088001AF420060002DE02F0000072
+:10D8700001BC600306379201BC63FF1FF0C301BC0B
+:10D8800060031890E301BC63FF1FF0C501BC63FF98
+:10D890001FF0C601BC63FF1FF0C700B02C5B001077
+:10D8A000E500B02C5F0010E600B02C630010E7022A
+:10D8B00080AC470000E701BC600300101000B040DE
+:10D8C0004300180000B040470010E501BC600300B1
+:10D8D000301000B0404300180000B040470010E690
+:10D8E00001BC600300501000B0404300180000B0BD
+:10D8F00040470010E701BC63FF1FF0C40002DE02D6
+:10D90000F0000000E840330097A100B0400B001782
+:10D91000A3006D5E86F460EE00905E8F0037A30377
+:10D92000BFDE02F000EF00905E870037A301BC600D
+:10D930001F1417A100E05E8EF437A301F041970099
+:10D9400017A1006DDE86F461030287C1970000F71E
+:10D9500001385A030017A1013C5A030017A203BF64
+:10D96000DE02F000F9013C5A030017A101385A0702
+:10D970000017A200685E86F480FE00D85E8B003738
+:10D98000A200E14196F4506500E1C19700306503C3
+:10D99000BFDE02F000F100D85E8B0037A200E1414B
+:10D9A00096F457A100E1DE870037A101F05E870001
+:10D9B00017A1006EDE86F4610401BC63FF1FF7A4AB
+:10D9C0000002DE02F000000020E38E090002031EC8
+:10D9D000DE02F0010B039F5E02F0010B01BC60430D
+:10D9E0000117A100A84122F4304803BFDE02F00075
+:10D9F0000200689B6F0000990208411F00010801A6
+:10DA0000816005620B1000025E02F00B1600B00090
+:10DA1000AB00108600B0016300108A00025E02F0C5
+:10DA20000D9601BC600304179200B0003B00111D6D
+:10DA30000190600609104803A1DE02F00122018175
+:10DA4000E00609104801BC600300904201BC60037D
+:10DA500000112D039EDE02F0012501846002F29781
+:10DA60009400B0451700178F00B05E1700179002A2
+:10DA700000441F00012001856002091048018160F7
+:10DA80000700104701F0DE0F0037A100A044B6F4F4
+:10DA90003145039EDE02F0012501BC613712B080E2
+:10DAA00003BFDE02F0000200A044B42A314501BCED
+:10DAB000612712708003BFDE02F000020020E082C6
+:10DAC000090002010CDE530017A101885E870010D7
+:10DAD0004701BC60030050420108411F0017A1012B
+:10DAE0008CDE86F2979403BFDE02F000020002DEB5
+:10DAF00002F000000020E07E09000200025E02F059
+:10DB00000F670283C21F000002020280F300013A85
+:10DB100000B044670017A1017C5E862357A30283EF
+:10DB20005EFF00013900E000FAF46830018360060E
+:10DB3000F7F7BF006BDE8D06013E0206D003000141
+:10DB40004200E950862337A100E8D08A2357A2007B
+:10DB500069DE8B00014200025E02F00B160191604B
+:10DB60001684F42700E020C300883003BFDE02F0F3
+:10DB700002CC00025E02F002CF020400BF00014AA4
+:10DB800003945E02F000020020C28F02000200A097
+:10DB9000428F01F78000685E002DC00200025E0225
+:10DBA000F00B1603BFDE02F000040201C28F00007A
+:10DBB00002011400630017A100685E870060020084
+:10DBC000025E02F00B160194600F00001800025E66
+:10DBD00002F0015103BFDE02F000040114006300F3
+:10DBE00017A100B05E870010A501BC601311106082
+:10DBF00000685E8700015800E0418306D06000E8BD
+:10DC00005E870037A103BFDE02F00154028050C3DB
+:10DC1000000162018760040310A000B000630010DF
+:10DC2000B400B042D3001800008841830030B60130
+:10DC3000BC60030B10B500B0006300B0B40317DE86
+:10DC400002F0015F0397DE02F0016001806006864A
+:10DC500014300002DE02F000000020E01280417C5F
+:10DC6000018760040310A000B000630010B401BC81
+:10DC700060030E10B500B0006300F0B401BC605743
+:10DC80000490B600B000630010B401BC600302D081
+:10DC9000B50207500B00017901BC600303D0B50148
+:10DCA0008E6002F297940204500B0001720204D0BD
+:10DCB0000B00017201866006F2979400E042D700E3
+:10DCC000D0B500A0500B1117A10068DE87110178B4
+:10DCD0000186E006F2979400E042D70050B50207B3
+:10DCE000D00B00017800E042D70090B500B042D7D9
+:10DCF0000011E100B0006300B0B40317DE02F001D0
+:10DD00007A0397DE02F0017B0002DE02F0000000E1
+:10DD10006820DF000180006CC46506E00401BC607F
+:10DD200003000837006820D7000183006CC4650633
+:10DD3000C00401BC60030008350020E0BE090002F9
+:10DD400003905E02F0000403A25E02F001BE020234
+:10DD500000BF0001880203C5730001B100682F6B8A
+:10DD600000018C00E844657B57A1006D5E857B2136
+:10DD7000B101BC6003000BDA00682D9B0001B10209
+:10DD800082C1070001B1028042030001B10285C5D2
+:10DD9000230001B1028640370001B10181E006F5A0
+:10DDA00077AB00B02D9F0017A101BC602F1077A2A8
+:10DDB00001BC60030017A300025E02F0131200B062
+:10DDC0002DA30017A101BC602F1777A201BC60032F
+:10DDD0000017A300025E02F0132001BC60131A17A3
+:10DDE000A100025E02F000A200B040670417A2008A
+:10DDF000025E02F000A800E0446700D7A1006CC4F6
+:10DE000066F4219F01BC60130ED7A100025E02F0F0
+:10DE100000A200A040673FF7A201BC601314D7A185
+:10DE200001BC62030017A300B05E8AF477A200026F
+:10DE30005E02F000A800B02D9F0017A101BC602F6A
+:10DE40000D37A201BC60030017A300025E02F013AD
+:10DE50001200B02DA30017A101BC602F13B7A201BF
+:10DE6000BC60030017A300025E02F013200181E0F2
+:10DE700002F577AB01BC6003000B6600025E02F0A6
+:10DE80000E74020200BF0001BD0284DEAF0001B8C3
+:10DE900002035EB70001BD00025E02F010FB020348
+:10DEA0005EB70001BD03BFDE02F0000202035EB7F1
+:10DEB0000001BB020480C70001BD02805EFF0001BB
+:10DEC000BD00025E02F010BC03BFDE02F0000200E3
+:10DED000025E02F00F670200421F0001D600684296
+:10DEE000F30001C1006D42F30041D601140063004C
+:10DEF00017A100B05E870017A203A25E02F001CA5C
+:10DF00000183E0020D906C03145E02F001D8006EF4
+:10DF1000C4568061D8028145230001D8006E5E8717
+:10DF20000061D601BC60030077A200886006F45748
+:10DF3000A300885E8B01001800E85E8B0037A2000A
+:10DF400020C28EF461D0006ADE86F441CA03BFDECF
+:10DF500002F001D6020400BF00020200900063013B
+:10DF60000165008085970217A100E064820DA1661B
+:10DF700000025E02F00F1D03BFDE02F0020201820A
+:10DF8000600209104803BFDE02F0000201BC60031A
+:10DF900000111500B0017F0017A6031F5E02F001FB
+:10DFA000E7020300C30001DD0020C28F0201E1038C
+:10DFB000255E02F001E70020C28F0201E1006881C6
+:10DFC00053FFE00403BFDE02F001E301946013009D
+:10DFD000001803BFDE02F00202039EDE02F001E63B
+:10DFE0000068DE980BC1E60201411F000CB40185F8
+:10DFF000600209104800685E980BC1EB00695E9FE3
+:10E000000062070298428F0001EB03BFDE02F002BC
+:10E01000070201411F000CB4020400BF0001F2021C
+:10E0200018428F000CB400025E02F00EFF00025E88
+:10E0300002F00F1D0194058700001803BFDE02F0F7
+:10E040000202020013BB0001FB0200156B0001FE7F
+:10E0500000B013470017A10068DE84A7A1FB00B041
+:10E06000134B0017A10068DE84A7C1FB00B0134F5B
+:10E070000017A10068DE84A7E1FB029E1397000150
+:10E08000FE0201C28F0002000194600F000018031D
+:10E09000BFDE02F002020201C28F000200018060B6
+:10E0A000060D906C0200C28F000CB4019460070052
+:10E0B000001800025E02F00151020400BF000237A6
+:10E0C000028500630002370183E0060D906C03BFF8
+:10E0D000DE02F0023701BC60031810600129500B0A
+:10E0E00000179200B0017B001065006800EB000291
+:10E0F0001000885A130117A100E84466F437A10004
+:10E100006EDE8407421000E0029B0020A603BFDE03
+:10E1100002F0067A019060120910480194601F0015
+:10E12000001801085A0F00178101885E0681540A01
+:10E1300001345A0F00178000025E02F000AF00B0F9
+:10E14000017B00106500B056230017A100E05E8639
+:10E15000A097A100E85E8400F40300E85E8400F468
+:10E160001600B05A0300141300B05A07001414002C
+:10E17000B05A0B0014150068DE0700422800E800C2
+:10E18000970057A101BC5E86F0141B017C5E8700DE
+:10E19000F41C00B0206300178100025E02F00D9AAB
+:10E1A00000B0017B00106501085A0F00178100B014
+:10E1B0005E8700141E03BFDE02F0022B00B056176C
+:10E1C00000141B00B0561B00141C00B054130014A4
+:10E1D0001E00B05013001086006D00A700823101B0
+:10E1E00090016300108A00B0418F00106200025E4F
+:10E1F00002F0119C00B0422B00140601BC60031811
+:10E2000017A1006DC18C20023401BC60030297A1EC
+:10E2100000E05E840377A100E05E86B0111D03BFBD
+:10E22000DE02F002AB020300C7000247020CD0037B
+:10E23000000247011400630017A102850063000279
+:10E24000470080DE8701F7A201BC601B0257A200D5
+:10E25000E05E8A0DB06500B041970014320080DEA8
+:10E260008700B7A201BC60171FD7A200E05E8A0D2D
+:10E27000B06400B041930014330068D81300025218
+:10E2800002005A1B0002490180600684F42703BF84
+:10E29000DE02F005A20201D00300024900B0509B4B
+:10E2A00000142F0281D0C70002C900025E02F002F2
+:10E2B000CF010BD0030017A1013C502B0017A20186
+:10E2C0008C5E86F457A1014801430017A200685EE6
+:10E2D00086F442520191601284F42703BFDE02F0FB
+:10E2E00002CC00025E02F0016300B0501300108601
+:10E2F00000B0501700108A00682FC300025D029121
+:10E30000D01700025B0291D01B00025B0291D01F6C
+:10E3100000025B0291D02300025B03BFDE02F00229
+:10E320005D0191600284F42703BFDE02F002CC039A
+:10E33000A25E02F0028A020CD003000279020300FE
+:10E34000C700027800B050CB00106500025E02F0FA
+:10E350001235020350C700026601BC60230097A17A
+:10E3600000A85002F4340003BFDE02F0027D020474
+:10E3700081AB000268006D4246C0800400B05A13B1
+:10E3800000178000025E02F000B900B0540F0014C4
+:10E390001E00B05A070017A100B05A1300178001E1
+:10E3A000875A16F0178000B0418F00106500025E9A
+:10E3B00002F011A500E05E86A0740302875E0300F0
+:10E3C00002770109DE030017A300E05E8B0077A24D
+:10E3D00000E05E8AF477A200885E8B0037A100E03F
+:10E3E0005E86F4508903BFDE02F0027D006D424A72
+:10E3F000848004010650070017A1028CD00300029C
+:10E400007C00685E8700027D0182DE8686343101F1
+:10E410008260028634310020D00304028300B050B1
+:10E420004F0011F200B050530011F300B0505700EC
+:10E4300011F401BC60030091F003945E02F0028AC3
+:10E44000020650030002860287DEAF00028A0281C4
+:10E4500050030004F10202D0C70002890208502BC9
+:10E4600000028A0285D003000508019060128634FC
+:10E470003103A25E02F0029700B0500F00111602A5
+:10E4800002D0C700028F00B0505B0011160282D08C
+:10E4900003000297028147C30002900280504F00A0
+:10E4A0000295002047C73F82970020C7DB00C2CB00
+:10E4B00003BFDE02F0029703A55E02F0029702801E
+:10E4C000C7DF0002CB028850C70002B10129500B00
+:10E4D000001792020300C70002A4020CD00300023E
+:10E4E000A4028350C70002A400B050CB0010650105
+:10E4F000385A1300178001825A17005781010E5AAB
+:10E50000130017A1018E5E86F037810202D0C7008A
+:10E5100002B100B0501B00108A03BFDE02F002B14E
+:10E520000282D0C70002AB013850270017800108D3
+:10E530005013001781010250130017A101825E865B
+:10E54000F0378100B0507F00108903BFDE02F00277
+:10E55000B10138506F0017800108502B001781015E
+:10E5600006D0070017A101825E86F0378100B05007
+:10E570001B00108A00B0508300108900025E02F078
+:10E5800000AF00025E02F00D8D0102421B001781F8
+:10E5900001825E0503178100025E02F00D9A00E021
+:10E5A0005E840117A101D9DE8700108301BC6137A9
+:10E5B00003B79100685E4B0282DF020400BF0002D5
+:10E5C000BD028750030002BD03945E02F002BE0349
+:10E5D000225E02F002C001BC610300308003BFDE96
+:10E5E00002F0000201BC613303B791032BDE02F09D
+:10E5F00002C6009000630097A100E06482F43065D9
+:10E60000006E5A130022C60188E006F237910068B6
+:10E61000DE4B0482C801BC61BB03B79103BFDE02BD
+:10E62000F002DF0191600E84F42703BFDE02F002E6
+:10E63000CC0191600684F42701BC60030010B40192
+:10E6400081E00686343103BFDE02F005A2011C50D2
+:10E650008F0017A100E0015EF43065010C5A4700FD
+:10E6600017A10080DE870197A200E0015E0DB06572
+:10E6700002805A7F0002DE02815A7F0002DA020322
+:10E68000DA7F0002DE00685A870002DE008860063A
+:10E69000F437A1002019FAF422DE00025E02F00B2A
+:10E6A000160191601E84F42700015E02F000000351
+:10E6B000BFDE02F002CC0002DE02F0000003C4DE86
+:10E6C00002F00B5E020650030002E70207DEAF0015
+:10E6D00002E701BC6103003791020750030002E525
+:10E6E00001BC620300F79100E0010B00204203BF70
+:10E6F000DE02F002E801BC600300204200B05E4789
+:10E70000001080020400BF0002F000B0058B001072
+:10E7100064006E45170000020068DE4B0282EF00C5
+:10E72000A044B42A314503BFDE02F0000200025EBD
+:10E7300002F00DA70068C51700000203D05E02F0CA
+:10E7400002F400025E02F00DA703BFDE02F0000239
+:10E7500001836002F7F7BF01BC600300900400A8CA
+:10E76000412330104801BC620F0011E001816002BA
+:10E77000F5D7AE020200BF0003050068DE4B0202BF
+:10E78000FC00025E02F0130C0068DE4B062305025B
+:10E79000045EB30003050200456F00030500E84472
+:10E7A000655737A100E82AB6F437A100695E8708EB
+:10E7B00023050183E0022B915C020701AB000305F6
+:10E7C0000180E00209D04E0187E002F577AB0068D6
+:10E7D000810B00230800B044670000430182E0067B
+:10E7E000091048018160020D906C01826006289139
+:10E7F000440188E0020B905C00025E02F00F95017C
+:10E8000085E002F7F7BF0288421B0003100185E094
+:10E8100006F7F7BF035B5E02F0031201BC60130052
+:10E82000104301BC600300108501BC60030010B8F8
+:10E83000008850770090B90208502B000319013866
+:10E8400050730017A1017C506EF437A100885E87D9
+:10E850000090B9020047A300031D01BC6003001132
+:10E86000EA009042E70091EB00B047A300D1E80234
+:10E870000047B300031F01B0E08E3D91EC01D2E0F0
+:10E880000210908403A95E02F0041601BC6003002C
+:10E89000108400E001C30020700320DE02F0037347
+:10E8A00001816006F5B7AD0068DE4B04A3370203B3
+:10E8B000DEBB00032900E02C9300106503BFDE02DD
+:10E8C000F0032A01BC602301D06500A05E7FFE102A
+:10E8D000EC00B05A030010ED00B05A070010EE0033
+:10E8E000B05A0B0010EF00B05A0F0010F001BC63DB
+:10E8F000FF1EF08401BC600300308501BC60030092
+:10E9000010B401BC600301D0A601BC60030450B583
+:10E9100001BC602304D0B400E002AF0020AB03BF11
+:10E92000DE02F003BB0068DE4B05233D01BC600343
+:10E930000010B401BC60071350A601BC600302D0F4
+:10E94000B501BC602304D0B403BFDE02F00347006E
+:10E9500068DE4B0243540285C38F00034000E05E33
+:10E960002700378901DA5E270010EE01BC63FF1F24
+:10E97000F0CE01BC60030010B401BC600300D0A65F
+:10E9800001BC600303D0B501BC602304D0B400E037
+:10E9900001D300207401BC61FF1FF08401BC60033F
+:10E9A000001085018460070011E00282DEB30004DC
+:10E9B000D802045EB30004D80183E00609104800C1
+:10E9C000B0412300180001BC600306B78E0181E04E
+:10E9D00006F5D7AE00B054130017A100E05E840125
+:10E9E00017A100885E8700708303BFDE02F004D8A1
+:10E9F00001BC60031FF0840103DE530017A200680E
+:10EA0000121B00035900B0121B0017A2009019FA44
+:10EA1000F457A202005EFF00035B01BC60030037F5
+:10EA2000A200682B6F00035D01BC60030037A201E8
+:10EA3000865E8A1C70E3006AC39300036700E843A4
+:10EA40009000D0E40202421B0003650090001B000E
+:10EA500037A10020421B00436400B020B30017A17F
+:10EA600000E04392F430E40069C39300036701BC03
+:10EA700060030010E400682B6F00036900E043911D
+:10EA80005C30E401BC60030010B401BC6003001002
+:10EA9000A601BC60030210B501BC602304D0B40021
+:10EAA000685E4B06A37100E001CB00207201BC60E0
+:10EAB0000300083803BFDE02F003BB00E001CF0013
+:10EAC000207303BFDE02F003BB03205E02F003C22B
+:10EAD0000181E00209104800E001D7002075031E03
+:10EAE000DE02F003A201BC60030017A2006A5E23ED
+:10EAF00000037B0102428F0017A201855E8A091084
+:10EB0000480180E0061030810284DE530003820059
+:10EB1000B000770017A100E05E840437A100885E92
+:10EB2000870057A100E05E870D57A103BFDE02F00A
+:10EB3000038301BC60030D57A1006800270003A2F6
+:10EB400000E05E8401F7A101BC60230150650088EC
+:10EB500041970030B601BC60030010B400905E879E
+:10EB60000050A601BC60030110B501BC602300B0D9
+:10EB7000B40317DE02F0038B0397DE02F0038C0070
+:10EB800020DE870043950020DE8700239201B85ED7
+:10EB900022D0168001805E8AD0368103BFDE02F06B
+:10EBA000039B01BC5E22D0168001845E8AD0368130
+:10EBB00003BFDE02F0039B0020DE8700239901B82B
+:10EBC0005E22D0368101805E8AD0568203BFDE028B
+:10EBD000F0039B01BC5E22D0368101845E8AD05650
+:10EBE0008201886002F430A800B05A030010B0001F
+:10EBF000B05A070010B1028042A300039E00E04219
+:10EC0000A30090A800B05A0B0010B000B05A0F003B
+:10EC100010B10187600610908400E05E27003789FC
+:10EC200001DA5E270010EE01BC60030010B401BCE5
+:10EC300060030350A600B000330010B50284DE5319
+:10EC40000003AC00E0606803B0A600E04298043026
+:10EC5000A600B000370010B501BC602304D0B40199
+:10EC6000846006F2979401866002091048039EDED4
+:10EC700002F003B60280441F0003B900B05E3F00FB
+:10EC8000114501BC600300178F00B05E430017857B
+:10EC900000B05E0F00179003BFDE02F003B900B0B2
+:10ECA0005E0F0017850280441F0003B900A044B620
+:10ECB000F0B14501BC600301104201836006F29788
+:10ECC00094018460070011E003A05E02F004D60204
+:10ECD000065EAF0004D80186E006F577AB01BC60A4
+:10ECE0000300108000025E02F00B1C03BFDE02F086
+:10ECF00005F803A15E02F0043D011400630017A1B2
+:10ED00000068DE8700E3C70181600609104803BF81
+:10ED1000DE02F0043D01816006F5D7AE011C508F84
+:10ED20000017A100E0015EF43064010C58470004B4
+:10ED3000870206508F0003D100B044670010F30033
+:10ED4000B0446B0010F401BC63FF1FF0D301BC633F
+:10ED5000FF1FF0D400B042170310850020600E861C
+:10ED600023F5018760040310A000B000630010B415
+:10ED700001BC60030B10B500B0006300F0B40203E7
+:10ED800000C70003E3020CD0030003E3028050C776
+:10ED90000003DB00B054130017A100E05E8680740E
+:10EDA0001A00B0506B0010E400B04213021084024D
+:10EDB00009502B0003E300B0421300308401D2E07D
+:10EDC0003AA030E0028050C70003E901D2E052A02F
+:10EDD00030E003BFDE02F003E90202D0C70003E91E
+:10EDE00000B0505F0010E000B050630010E100B0D0
+:10EDF00050670010E200B0506B0010E400B0421306
+:10EE000002F084020050C70003F000B0006300105D
+:10EE1000B401BC60030210B500B0006304D0B401BB
+:10EE20008460070011E001BC600300178E03BFDEA1
+:10EE300002F004DA00E001C700207100B0006300B6
+:10EE400010B401BC600302D0B500B0006304D0B4BC
+:10EE500003BFDE02F0046D01856006F7F7BF010312
+:10EE600050030017A100B85E870037A101875E86B6
+:10EE7000101080020CD00300043C020300C7000401
+:10EE80000C00B050CB00106501BC6003001685007B
+:10EE9000E05A3300368C020350C700040100E05AE8
+:10EEA0002700368903BFDE02F0043D01BC60030089
+:10EEB00017B200B05A0B000B2501385A130017A1E6
+:10EEC00001BC5A06F430E0013C5A130017A1017C42
+:10EED0005A06F430E10181E0061090840185E007D4
+:10EEE0000010E30185E0070010C30282D0C70004D0
+:10EEF0001103BFDE02F004140202D0C700041600A2
+:10EF0000B02A4B0017A101B8506EF430E000B050A9
+:10EF1000730017A101B82A4EF430E10282421300B7
+:10EF2000041400B0507B0010E400B04213021084BF
+:10EF30000185E0061C30E100B042130070840187B7
+:10EF400060040310A0020300C700042B00B050CBE4
+:10EF5000001065006D5ECAD1C41C0185E002187006
+:10EF6000C300E05ECB00368E01BC601B09D065009B
+:10EF7000E04196F6506500B050970016800068DEBC
+:10EF8000CB00042301BC60230150B800682C97001B
+:10EF9000242903BFDE02F0043500B05ECB0010B5BB
+:10EFA00000B000630870B4028342D300042501BCA2
+:10EFB00060030170B80068AC9700243501BC6003A1
+:10EFC0000170B802BC506700043403BFDE02F004D5
+:10EFD00033010CD0030017A103A95E02F004300135
+:10EFE000BC60230150B800685E8700643303BFDE55
+:10EFF00002F0043501BC60030170B800685E870050
+:10F00000443501BC60030170B80181E0021710B8FB
+:10F0100001BC600300F0A501BC60030E10B500B098
+:10F0200000630010B400B0006300F0B400B042D33D
+:10F03000001800018860080310B4018160060D907B
+:10F040006C03BFDE02F0046D0202D0C7000443006F
+:10F05000B0506F0010E000B050730010E100B050ED
+:10F06000770010E20282421300044200B0507B009D
+:10F0700010E400B0421302F08400E05E9F0037A766
+:10F0800003A15E02F0044C01BC60030017A70187D6
+:10F0900060040310A000B000630010B401BC600362
+:10F0A0000E10B500B0006300F0B4018860080310D2
+:10F0B000B403BFDE02F0046200B0017B0010650003
+:10F0C000B05A030010E501BC63FF1FF0C500B05A41
+:10F0D000070010E601BC63FF1FF0C600B05A0B002A
+:10F0E00010E701BC63FF1FF0C70068A0670004556C
+:10F0F00000E05E2700378900682067000459018519
+:10F10000E0070010E30185E0070010C300B04213E0
+:10F1100001108401DA5E270010EE0187600610906E
+:10F120008400B042131C108401BC60030010B400C2
+:10F13000E0606803B0A600B000970010B501BC60A5
+:10F140002304D0B4018460070011E003BFDE02F0A5
+:10F1500004C601085E4B0017A100685E8700246D9D
+:10F160000202500300046C029E509F0004690201D9
+:10F17000D00300046900E05E2700378901585E274C
+:10F1800000142D01DA50B70010EE018760061090D0
+:10F190008403BFDE02F0046D01BC600300142D0186
+:10F1A00004C1070017A10068121F00047200B0120A
+:10F1B0001F0017A1009019FAF437A103BFDE02F077
+:10F1C000047403225E02F004740103DE530017A1ED
+:10F1D00000B05E870017A202005EFF00047701BC4A
+:10F1E00060030037A200682B6F00047901BC600344
+:10F1F0000037A202885E4B00047C00685E4B0684E8
+:10F200007C01BC60030017A20068921F00047E010D
+:10F2100083DE86F297940183DE8684F4270281C21E
+:10F220001300048401865E8B0010E30186600700F2
+:10F2300010C30181E00610908403BFDE02F0048653
+:10F2400001865E8A1C70E3018660061870C302B8EE
+:10F2500047A70004C202A047B70004C403A95E0286
+:10F26000F0048E01085E4B0017A100685E87002441
+:10F27000C3021E509F00048E0185E0061C70E3014E
+:10F2800085E0061870C3011400630017A10068DE52
+:10F290008700849700B001530017A20068DE8BFF3F
+:10F2A000E493006842470024940068DE8A84C4978F
+:10F2B000018560020910480186E0021C70E30186A6
+:10F2C000E0061870C3011050070017A600685E9B87
+:10F2D0000004C301BC60030011E4013A50070017A9
+:10F2E0008000885E0300778000E000AEF0106400CC
+:10F2F00068DE9B0044A80207D0030004A201BC60A2
+:10F300002B12B7A200E05E000B37A300025E02F0F2
+:10F310000DE801BC602307978100E0418301706321
+:10F3200000E0418F00B06500025E02F00DBD01BC3F
+:10F33000602307506401BC60470017A200025E0210
+:10F34000F00E1000685E9B0044C401A46046F47196
+:10F35000E00068DE9B00C4B601BC611300B7A102E7
+:10F360000600F30004AF01BC601300B7A10192C214
+:10F370001AF437A203295E02F004B401BC60030052
+:10F3800011EE009042E70091EF0192E00EF437A2F7
+:10F3900000B05E8B0011EC03BFDE02F004C4006815
+:10F3A0005E9B0064BB00685E9B00A4BB00B0502F56
+:10F3B0000011E200B050330011E203BFDE02F0049E
+:10F3C000C4018760023D11E80068DE9B00A4BE0115
+:10F3D0008760063D11E801BC60030011EA0090421D
+:10F3E000E70091EB0192C21B00B7A201B85E8A3D13
+:10F3F00011E803BFDE02F004C4018460070011E0DD
+:10F4000001BC600300112D00B0448300142C03A341
+:10F41000DE02F004D901BC600300178E00685E4B69
+:10F4200005A4CA020050030004D30183E0060910BA
+:10F430004800B0412300180001BC600304B78E03EC
+:10F44000A95E02F004D800685E4B0424D801BC60B9
+:10F450000306378E00685E4B05A4D801BC60030626
+:10F46000B78E03BFDE02F004D801816006F577ABEA
+:10F4700000B05E0F00178500025E02F00DA701BC10
+:10F48000600300178C01BC600300178D0323DE02AC
+:10F49000F004DA0187E0061070830185E002F5B719
+:10F4A000AD03295E02F004EE020300C70004E90088
+:10F4B000B050CB0010650282D0C70004E100E05AD2
+:10F4C0002300368803BFDE02F004E200E05A270082
+:10F4D000368900682C970024E900E05ECB0037B243
+:10F4E000010A5ECB0017A100E050CAF4306500D0DD
+:10F4F0006006F657A200205A1AF444E903BFDE0260
+:10F50000F004E300025E02F00F9503D5DE02F00A7C
+:10F510004C03D6DE02F00A640350DE02F004E90375
+:10F52000BFDE02F0051002055EAF0004F00187E0C7
+:10F530000626713303BFDE02F000020190600A86E6
+:10F5400034310282D0C70004FA013C5027001780F2
+:10F550000109502B001781010750070017A10182F4
+:10F560005E86F0378100B0501F00108A00B0500F47
+:10F5700000111603BFDE02F005000138505F0017CE
+:10F5800080010A502B0017810107D0070017A10145
+:10F59000825E86F0378100B0502300108A00B050A0
+:10F5A0005B001116020300C7000505020CD0030022
+:10F5B000050502085E07000505013854070017809D
+:10F5C0000190422AA1308A028050C700050E01BC7A
+:10F5D000600305B79203BFDE02F0028F0190600660
+:10F5E000863431020300C70004F2020CD003000489
+:10F5F000F200B0001F0017A100E05E8680741A03BD
+:10F60000BFDE02F004F201BC600306379203BFDEE6
+:10F6100002F0028F02055EFF00051F01856002F700
+:10F62000F7BF032BDE02F0051F020000F3000516F2
+:10F6300000E8002300514201BC600A2851420394B3
+:10F640005E02F0051B00B0058B00106400685803D3
+:10F6500000051B00B0446700111200B058030011F0
+:10F66000150068451F00051F03A25E02F0051F017B
+:10F6700085E006F577AB00025E02F00ED70201C20C
+:10F68000E3000549020300C700052400682C970029
+:10F690002534006E4246F6453403BFDE02F00526EF
+:10F6A000006E4247002534020300C70005310355B0
+:10F6B000DE02F00526018060028614300138508396
+:10F6C0000017A100B050CB001065006DDA32F42AAB
+:10F6D0004C00A84123141048011400630010650079
+:10F6E000E041970ED06500E05A0300368001BC620D
+:10F6F0001F0011E003BFDE02F000040181E0068676
+:10F7000034310191600E84F42703BFDE02F0054915
+:10F71000013C50670017A101AC5E861750BA01BCCE
+:10F7200060030190B8020300C70005430068AC976E
+:10F7300000253E0181E0021710B803D5DE02F00A71
+:10F740004C03D6DE02F00A640350DE02F0053A03F1
+:10F75000BFDE02F0054900E82C97002B2500B05EC3
+:10F76000CB0010B500B000630870B4028342D30030
+:10F77000054103BFDE02F005440186E0040310A04A
+:10F7800000025E02F0015A03D5DE02F00A4C03D6F5
+:10F79000DE02F00A640350DE02F0054503BFDE021C
+:10F7A000F0031001BC600300F0A50182E002091023
+:10F7B0004801BC621F0011E001BC60030011EC01B4
+:10F7C000BC600F0011E80285500B000550018260FB
+:10F7D0000209104803A0DE02F0055403D5DE02F052
+:10F7E0000A4C03D6DE02F00A6403205E02F00556DE
+:10F7F0000188600209104803BFDE02F0000401BC6A
+:10F8000060030037A100025E02F00C5303A3DE0286
+:10F81000F00004020050C700056201BC6003001044
+:10F820008001826006091048018060028634310040
+:10F8300068921F0005600104C1070017A10183DE63
+:10F8400086F2979400E001CB00207203BFDE02F045
+:10F85000017D00B0010B0017A1006DDE840805A238
+:10F8600000E844640877A1006E5E840825A2018741
+:10F87000E006F577AB020200BF000575028881AB98
+:10F88000000575028400C70005750129500B00179B
+:10F89000A10068DE870205750282DEBB00057502E5
+:10F8A00003C5730005740283DEB30005740282DEB3
+:10F8B000BB00057100682B07000575006DDE2F0188
+:10F8C000E5750182E006F7F7BF00E04465564AB1EE
+:10F8D00003BFDE02F0000403BFDE02F005A20282D5
+:10F8E0005EAF00058501826006F577AB00B0446726
+:10F8F00000082300B0014B0017A20208421B0005BC
+:10F900007C00B0016B0017A200685E8B00058200CE
+:10F9100090452B0097A10080DE86F457A1006E2051
+:10F92000D60DA58200B041B700083500E020D623EF
+:10F9300028360185E002F5B7AD02055EAF0005850A
+:10F9400001BC610300113300E844650477A500B0F1
+:10F950004467000BDA006D5E97010080020200BF71
+:10F960000005940068DE4B06A58B0184E002F7F7E2
+:10F97000BF0068DE4B04058E0282DEB300058E01F7
+:10F98000BC6003000B1202045EB30005910068DE48
+:10F990004B06259100025E02F0112300025E02F088
+:10F9A0000F9603A3DE02F005940183E002F597AC05
+:10F9B00001BC60131497A100025E02F000A201BC1A
+:10F9C00063830017A100A04066F437A20068DE8AB6
+:10F9D000F425A001BC60130E77A100025E02F000C6
+:10F9E000A200A040673FF7A200985E8B0037A200FC
+:10F9F000685E8B00059F0068DE8B0FE5A001BC6090
+:10FA00002300104301826002F577AB03D15E02F060
+:10FA10000002020050C30005F10325DE02F005A636
+:10FA20000183600684F42703BFDE02F005D8020CD0
+:10FA3000D0030005D6020300C70005C5011400630A
+:10FA40000017A1006DDE870085D601BC600300179A
+:10FA50008000B050CB00106500B050CF00106401A2
+:10FA60008160060D906C0182600686343100B05AC8
+:10FA7000230017A101BC600300168801BC5A2AF4B8
+:10FA800037A101BC600300168A00B05E8700148FA6
+:10FA900000B05A270017A101BC600300168901BC01
+:10FAA0005A2EF437A101BC600300168B00B05E87AC
+:10FAB00000149000B05A1B00148D00B05A1F00149F
+:10FAC0008E01BC60030016040068DE030005C2025C
+:10FAD0000350C70005C10100509F00178001805EE0
+:10FAE0000291B48D01BC5E0292149001BC600300CF
+:10FAF000378000025E02F0128100B05E0300148CB9
+:10FB000003BFDE02F005D10068C2470005CA0181CB
+:10FB1000E0068634310191600E84F42701BC600355
+:10FB200000143003BFDE02F0000200B0509F001747
+:10FB3000A100025E02F0015900B05E8700142701A7
+:10FB400086E0040310A000B04283001800010CD02E
+:10FB5000030017A10068DE870065C5010250C700D9
+:10FB600017A101805E8684F427018AE00E84F427C1
+:10FB700000B050BF00142603BFDE02F005D8018696
+:10FB8000E0040310A00200509F0005D80286C107C0
+:10FB90000005EC03295E02F005DD00B052330014CD
+:10FBA0002D00B052370017A1019E5E8684F4270015
+:10FBB000B0509F0017A10180DE86F437A100B0503D
+:10FBC000BB00108F00B050B700108E00B0509B00EB
+:10FBD000108D01806006F4308C020250C70005EBE6
+:10FBE00000B0524300108F00B0523F00108E00B0A2
+:10FBF000523B00108D011A52370017A10198DE8781
+:10FC00000437A101B85E8691B08C0182600286340F
+:10FC100031018160020D906C0325DE02F005EF01D9
+:10FC20009C600284F42703BFDE02F005F3028550D6
+:10FC30000B0005F100A850C70D143101BC60030092
+:10FC4000143001816002F5D7AE0183600284F4278D
+:10FC50000185E00209104801BC600300142E03A2D4
+:10FC60005E02F0017D03BFDE02F000040323DE022A
+:10FC7000F0065C03A35E02F0065C03A2DE02F0065F
+:10FC80005C01816006F577AB03AA5E02F0065C01B9
+:10FC900083E0020910480351DE02F0061B02045EF5
+:10FCA000B300060801846002F597AC0183E0020905
+:10FCB000104800B02B5F0017A1006D2B0EF420023E
+:10FCC00000E0027B00209E01BC6003000AC300022A
+:10FCD0005E02F0112603BFDE02F000020203DEB373
+:10FCE0000006180183E002F597AC00E02A9B002A89
+:10FCF000A602015EBB00061800B02A9F0017A100F3
+:10FD00006D2A9AF4261301BC6003000AA600E002E3
+:10FD10007F00209F03A95E02F006160191601A84FD
+:10FD2000F42703BFDE02F002CC01BC63FF1FF7A182
+:10FD300000025E02F00C5303295E02F006180191E6
+:10FD4000601A84F42703BFDE02F0061800E0026B9D
+:10FD500000209A0180E006F577AB03BFDE02F006D3
+:10FD6000200301DE02F0061E00685E4F06261E011B
+:10FD7000BC60030017A803A45E02F0062003C1DEE6
+:10FD800002F0065F01846002091048020400BF000F
+:10FD9000062501BC6003001115011400630017A1C2
+:10FDA00000E06602F4306500025E02F00DAC0182F4
+:10FDB000600209104803A95E02F0064000685E3B3D
+:10FDC00004A63001F0DE1700378500A05E16F0971C
+:10FDD0008500685E3B0626300201500300062F02B4
+:10FDE0008780BF00062F0185E0060910480280D0F9
+:10FDF0000300064000B05E1B0017A300B0008B009C
+:10FE000017A4020400BF000636006E419730663624
+:10FE100001185A030017A3011A5A030017A4006817
+:10FE2000C18318063900E002930020A403BFDE025C
+:10FE3000F0063B006D5E2EF4863B0182E0068634C0
+:10FE40003100E05E3300378C0068DE32F4663E003D
+:10FE5000B05E0F001785006DDE2EF4664C03BFDE2A
+:10FE600002F0065700B05E1F0017A300B0008F001D
+:10FE700017A4020400BF000646006E419730664694
+:10FE8000011C5A030017A3011E5A030017A4006D9A
+:10FE90005E2EF486480182E00686343100E05E374B
+:10FEA00000378D0068DE36F4664B00B05E0F001739
+:10FEB00085006D5E2EF466570185E0020910480347
+:10FEC000D1DE02F0064E00025E02F00DA70068418E
+:10FED0008318067A020300C7000655020CD00300FF
+:10FEE0000655028350C70006550068DE4B05A6552F
+:10FEF00003BFDE02F011FF0181E00686343103BF4B
+:10FF0000DE02F005A200025E02F00DA70181600290
+:10FF100009104803295E02F0065C028300C7001145
+:10FF2000FF03BFDE02F005A203D1DE02F0065D038F
+:10FF3000A5DE02F005A203BFDE02F00004020650B7
+:10FF40000300066500B001030017A1006D810AF4EB
+:10FF5000266500E844640877A1006E5E8408266583
+:10FF60000187E006F577AB01085E4B0017A100683A
+:10FF70005E8700266800B05E0F00178500025E02F3
+:10FF8000F00DA700685E3B06266E01BC60030017FB
+:10FF90008C0200D00300067301BC600300178D03C0
+:10FFA000BFDE02F0067301BC600300178C02030081
+:10FFB000C700017D020CD00300017D019C6002841A
+:10FFC000F42703BFDE02F0017D0068418318067943
+:10FFD0000180600684F42703295E02F005A20182F5
+:10FFE0006006863431028300C70011FF03BFDE02C2
+:10FFF000F005A200E002970020A50181600209102F
+:020000023000CC
+:100000004801BC600300081900E0017B00A05E010C
+:10001000BC601310D7A1006D017AF4200401BC600C
+:100020001309405E03BFDE02F0000400025E02F02E
+:100030000B160338DE02F00004039EDE02F000041B
+:1000400000E8444C00F7A100E85E840117A1006AB3
+:10005000DE8401068A00E85E8401118701BC60032A
+:1000600000118801A5E02230118001BC600300115D
+:100070001301BC600300111400B044670017A10015
+:10008000B0446B0017A200B05E8700110400B05EA0
+:100090008B00110503B8DE02F0068C03BFDE02F010
+:1000A000000401BC600304B79201BC60030417A103
+:1000B00001BC63FF1FF0CB01BC63FF1FF0CC01BC90
+:1000C00063FF1FF0CD01BC63FF1FF0CE01BC63FFD7
+:1000D0001FF0CF01BC63FF1FF0D000B0521700101B
+:1000E000E801BC63FF1FF0C800B0521B0010E9011B
+:1000F000BC63FF1FF0C900B0521F0010EA01BC63CF
+:10010000FF1FF0CA01BC60030010E4028600C300B8
+:1001100006AD00B0540F0017A20069DE8A9086A5D4
+:1001200000E85212F450E40068A0630006AD01BC80
+:1001300060030010E400B054270010E000B0542F1A
+:100140000010E103BFDE02F006B603A4DE02F008F1
+:10015000AB03A9DE02F008AB01BC600301D7A1022A
+:100160000600C30006AF0280DE5F0006B400B05494
+:10017000070010E0006820630006B201D2DE86A00E
+:1001800030E000B0540B0010E103BFDE02F006B611
+:1001900001BC5E869010E001BC601F0010E101BC54
+:1001A00060030010E200B052230010E501BC63FFC1
+:1001B0001FF0C500B052270010E601BC63FF1FF01E
+:1001C000C600B0522B0010E701BC63FF1FF0C70050
+:1001D000B0004700108601082063001781013852E3
+:1001E000030017800102C0270017A600025E02F07C
+:1001F0001198006820630046C400B05407001780BF
+:1002000000025E02F00D8D006820630026CD0068BC
+:10021000A0630006C8021A54070006CD006800A7B4
+:100220000106CB0103C0270017A103BFDE02F006C1
+:10023000CC0106C03B0017A101825E8610D0860368
+:10024000A9DE02F008EB00685E4F0426DF01BC6304
+:10025000FF1FF0C300685E4F05A6D501BC60031AFE
+:1002600090E301BC600306B79200685E4F0526DF8D
+:1002700003BFDE02F006D901BC6003063792029884
+:1002800044070009C0028046070009C001BC6003A2
+:100290001890E300B0206300178100025E02F00DA9
+:1002A0009A00E85E8400D7A1006A5E869086DF002F
+:1002B000E85212F430E403BFDE02F006E201BC6053
+:1002C000030010E40338DE02F006E20187E0061CBA
+:1002D00090E40190600A09104801BC610304379161
+:1002E00000685E4F05A9C003835E02F008AB03BF40
+:1002F000DE02F0000201866002F7F7BF0182E00231
+:10030000F5B7AD0185E002F5B7AD02044163000623
+:10031000F2018460020B105802055EAF0006EE0188
+:1003200087E006267133020400BF0006F10185E074
+:1003300002F577AB00025E02F00ED703BFDE02F0DB
+:1003400000020283C0370006FA006CC4656C26FB0D
+:1003500001BC601B1A77A100025E02F000A20180BE
+:10036000E0060337A200025E02F000A80180E0026E
+:10037000F457A200025E02F000A800E044656C4B56
+:10038000610285C52300070A018460060B1058022C
+:1003900000DEFF0007010180E002F7F7BF00682BD5
+:1003A0006F00070100E044655B4ADB0207AC0F0009
+:1003B000070A0280456F00070A01BC63FF1FF7A10F
+:1003C0000068DE862C270A01BC60130217A1000218
+:1003D0005E02F000A201882C0E0337A200025E022A
+:1003E000F000A801BC6003000B0302055EAF00072C
+:1003F0000C01BC6103001133020580BF000712012C
+:10040000BC60131157A100025E02F000A2019660C9
+:100410000E03301900B040670017A200025E02F020
+:1004200000A80283C03700000400E0021F002087FC
+:100430000182600628914403BFDE02F000040281BD
+:100440004013000002020042030007190184600209
+:10045000F597AC01BC600300108003A3DE02F00737
+:100460001C0190600209104800B0446700179E000C
+:10047000B0446B00179D00B0446F00179C00B0445F
+:100480007300179B0068DE7A23271C00E00223001C
+:1004900020880115403B00179700B001430017A1C9
+:1004A00001C9DE8405280501BC6003107795019120
+:1004B000E0020D906C0286403700072A00E002BB84
+:1004C0000020AE03BFDE02F00A8A01BC6003001404
+:1004D0008001BC600300148101B8600A049024010B
+:1004E000BC600304082B01BC600300482A01BC6007
+:1004F0000300D02A01B3600700100401BC600300B0
+:10050000080E01BC600300080F01BC600300081066
+:1005100001BC60030008110183E002F5D7AE028739
+:10052000C037000A8600025E02F0117A00025E0205
+:10053000F00F9503435E02F00736006D403300CAAA
+:10054000F700685E5F00474E00685E5F00274B0063
+:100550006800A700C740006800A701074000688046
+:10056000A700A74100E0446690283701BC62C300A1
+:1005700017A102805203000744019652030017A1FD
+:100580000080DE8690379A0203520300074900E09C
+:100590005E6A90379A0207D20300074900E85E6B53
+:1005A00000379A029E5E6B000AF703BFDE02F00777
+:1005B000530152D2030017A10185D206F4379A03E2
+:1005C000BFDE02F00753013C52030017A101BC52E9
+:1005D00006F4379A006E5E680BAAF700682FC30016
+:1005E0000753028E5207000AF70204C03B00075D62
+:1005F0000181E0060D906C02874037000A8A0002F4
+:100600005E02F0117A00025E02F00F950287C0AF21
+:100610000007550287C0AF000A86015840AF001797
+:100620009A01BC603F1E17A1006DDE6AF42A8603A2
+:100630005B5E02F0075F01BC601300104300B04135
+:100640002328104801806002F297940184E0020997
+:100650001048015840AF00102A006840AB002A86BD
+:1006600001BB5E5600900402035E5700076E020055
+:1006700047A300076B01BC621E3C11E001BC600394
+:100680000011EA00B05E6B0011EB0198601E3D1195
+:10069000E8020047B300076E00B05E6B0011EF0187
+:1006A000B0E0CE3D91EC03835E02F0077200025E83
+:1006B00002F0117A00025E02F00F95006D403304E3
+:1006C000C76E03AADE02F0078E01BC63FF1FE4863B
+:1006D00001BC601B19D06401BC600300B7A101BC60
+:1006E00063FF1FE66D00E04186F4306501BC63FFE7
+:1006F0001FF60000E05E870077A100025E02F00CAA
+:10070000AE0200C077000784012940770017A200DD
+:100710006D5E8B04C78200E85E8B04D60001BC606E
+:100720001B0FF06300E0418EC01063010C56030004
+:1007300004860068DE8701678400B05E8B00066D6A
+:10074000006DDE8701C78700E0419300306403BF7E
+:10075000DE02F0077703B05E02F0078D01836002CE
+:100760000D906C00681B3BFFE78E01BC601B0FF017
+:100770006500E04194D9D06502005A0300078E015C
+:100780008360060D906C0020402F08A79001BC608C
+:100790000300048601BC60030008020188E00F002A
+:1007A0000803006D40330208A50129520F0017937A
+:1007B0000109520F0017AA01966002F2979400E017
+:1007C000418701F06501BC600F0017A10028DE869B
+:1007D00090679C01866006F2979400E04197007054
+:1007E0006500E020AF00C82B01065E530017A20091
+:1007F000A05E4F0477A10068DE870447AA0186E067
+:1008000006F2979400B85E8B0037A200B05A03003E
+:1008100017A0020ADA030007A401876006F2979482
+:100820000284C03B0007AA0203DA030007AA03AB55
+:100830005E02F007A8020441070007AA01806005D4
+:1008400000680301065E530017A20182DE8A009051
+:100850000403AADE02F007DB03AB5E02F007C50269
+:1008600087D2130007DB00B0521300118601A5E008
+:100870000A301180018460020D906C01BC63FF1F7F
+:10088000F79900B01B430017A20068DEAB0027B742
+:1008900000A05E4FFF77A10068DE870727C303BF74
+:1008A000DE02F007B90284520F0007C30204D20F20
+:1008B0000007BC03B15E02F007C200B01B3F001787
+:1008C000A203BFDE02F007BD03B35E02F007C2025F
+:1008D0000052170007C300685E8BFFE7C300E0010A
+:1008E0005EF4506502015A470007C300B019B70013
+:1008F0001799018460060D906C020052170007DB07
+:1009000003315E02F007DB01866002301180018056
+:10091000E001620B10020052170007C90202AB4F40
+:100920000007D60068DE5F0007D600B02BB70017BF
+:10093000A100682ABB0007D600B02BB30017A200A5
+:100940006DAABAF447D60068DEAB0047D2006D2B23
+:10095000BAF427D100B02C6B000B190184E006F724
+:10096000F7BF0068DE4F0287D600025E02F0130C6C
+:100970000206DEFF0007D600E02BE7002AF9006838
+:10098000DE5F0007D90068DEAB0047D90180E005D3
+:10099000620B1000682B6F0007DB0180E006F7F7A1
+:1009A000BF0207520F000856028047A300085302F7
+:1009B0008047B300085300E020AF00882B00E820F8
+:1009C000AB00882A01BC60030011E401BC63FF1F77
+:1009D000F7A501BC600303D1E102065E530007E501
+:1009E00001BC60030491E10206DE530007E900E068
+:1009F00047870051E10207D20F0007E900E047876F
+:100A00000091E1006D403302C8A500685E4F058784
+:100A1000EC0068DEAB00485603AB5E02F007EF0265
+:100A2000005217000856020580F30007F500681908
+:100A3000B7FFE7F200B019B70017A500E05E970016
+:100A400097A50068DE97FFE7F50280521700085669
+:100A5000020700BF00085601BC601F1417A20090D7
+:100A6000478700306500E04196F4506500E0478715
+:100A700001082103835E02F007FD00025E02F0110F
+:100A80007A00025E02F00F95006D40310427F900F4
+:100A90006D40310428A501BC600B1D57A10068DE24
+:100AA00097FFE80D010F5A070017A5031EDE02F09D
+:100AB000080D0200521700080D032C5E02F00856C4
+:100AC00000685E67FFE80D00E05E6700979900E050
+:100AD0005E66F43064012A58030017990100DE971E
+:100AE0000017A500E05E66F4B79900E05E67003786
+:100AF00099011558030017A603BFDE02F0081D0078
+:100B0000E05E96F43064012A5803001799020580CC
+:100B1000F300081C0182E002F3379902005217002B
+:100B2000081C0116D8030017A6010F5A070017A4C6
+:100B3000010CD8030017A10068DE92F4281800E029
+:100B40005E6702179903BFDE02F00821010DD8038A
+:100B50000017A10068DE92F4285600E05E670417D3
+:100B60009903BFDE02F00821011058030017A60008
+:100B700068DE9B00C8210181DA030017A100B85E7E
+:100B800086C017A10281DE8700085600885E6700D4
+:100B9000778000E000AEF0106401AADE6500480234
+:100BA0000068DE9B00483B0207818700082E006D2D
+:100BB000DE030C082E0285520F00082E0298523BCD
+:100BC00000082E0181E00500680300E05E000B379D
+:100BD000A300E05E8F0097A300E041870077A200AA
+:100BE000025E02F00DE800E820AB01082A01BC60BB
+:100BF0002307978100885E970077A100E85E86F45E
+:100C0000B06301BC60070E17A100E0418EF43063B1
+:100C100000B056170017A100B0561B0017A20068BD
+:100C2000DE86D048560068DE8AD0685600025E0232
+:100C3000F00DBD01BC602307506401BC624F00177A
+:100C4000A200025E02F00E1000685E9B0048530195
+:100C5000BC621EF471E00068DE9B00C84601BC6106
+:100C60001300B7A1020600F300084201BC601300A4
+:100C7000B7A101BC60030011EE00B05E6B0011EF84
+:100C80000192E00EF431EC03BFDE02F0085300687D
+:100C90005E9B0068480068DE9B00A85301986006D0
+:100CA0003D11E800E020AF00882B00E820AB008871
+:100CB0002A01BC60030011EA0068DE5F00484E00B4
+:100CC000B05E6B0011EB0192DE5E3D11E8018760C2
+:100CD000023D11E80068DE9B00A852018760063DD6
+:100CE00011E8019860163D11E80181E00500480215
+:100CF00001AADE6500480203BFDE02F0085B01BC0A
+:100D0000620F0011E001BC60030011E40181E00109
+:100D100000680301BC600F0011E801BC6003001112
+:100D2000EC0200200F00086200E020AAF3482A002D
+:100D3000B020AF00102500E820AA04A82A006AA06D
+:100D4000AB01C86201B860060490240182E006F29B
+:100D500097940188600A00900401BC60031877959D
+:100D600003A0DE02F0086F00685E4F06A874013829
+:100D7000520300178000B05E5F0017810203DEB7E8
+:100D800000086E00685E0700086D01BC6003017713
+:100D90008001BC600300378103BFDE02F0086E01F2
+:100DA000BC600301578000025E02F000AF0068DE05
+:100DB000AB00487400A05E4F0477A100685E870016
+:100DC0004A3500685E87044A3503BFDE02F00BE94E
+:100DD0000386DE02F00A870287C037000A86000217
+:100DE0005E02F0117A00025E02F00F9503035E02CC
+:100DF000F0087403A9DE02F0088000025E02F01120
+:100E00007A00025E02F00F950207403700087A036D
+:100E100086DE02F00A870287C037000A8600025E7B
+:100E200002F00C60006E40300208AB0301DE02F0FD
+:100E300008AB0068DEAB000892032B5E02F0088668
+:100E400000E0022B00208A03BFDE02F0088A028045
+:100E5000521700088900E0024300209003BFDE0221
+:100E6000F0088A00E0025700209500685E4F040BEE
+:100E70006900685E4F028B6900685E4F0209C70017
+:100E8000685E4F048A2E00685E4F050BDA00685ECC
+:100E90004F060BDA00685E4F068BE303BFDE02F0FD
+:100EA0000BE90068DEAB0028A3032B5E02F0089676
+:100EB00000E0022F00208B03BFDE02F0089A0280C0
+:100EC000521700089900E0024700209103BFDE029C
+:100ED000F0089A00E0025B00209600685E4F06A9C9
+:100EE0009B00685E4F042C0100685E4F04AC01005B
+:100EF000685E4F05AA3B00685E4F06299B00685E4E
+:100F00004F052BD800A05E4FFF77A100685E8707D2
+:100F10002BF403BFDE02F009C000E00213002084BE
+:100F200003BFDE02F009C400E0020F00208301BC11
+:100F300060030011EC01BC600F0011E80284C03BAB
+:100F40000008560184E00609104803BFDE02F008DD
+:100F5000560200C09300000203A35E02F008AF0334
+:100F6000C35E02F008AE03BFDE02F00AF300025EC9
+:100F700002F0117A00025E02F00F950207C0AF0086
+:100F800008B3020740370008AF0107C0AF0017A140
+:100F900000B85E870037A101825E860D906C00B0BC
+:100FA000447F000804018360020910480287C037AB
+:100FB000000A860386DE02F00A8700025E02F01154
+:100FC0007A00025E02F00F9503435E02F008B80259
+:100FD00087C037000A860301DE02F008D303305EC3
+:100FE00002F008D301BC601B1F506500E04194DF94
+:100FF0003065012D406B0017A200885E8B0137A27F
+:101000000138402B001680028840270008C7018461
+:101010006006D0168000B05A02F456800205C02740
+:101020000008CA0187E006D0168001BC601B0DD7FE
+:10103000A100025E02F000A200B04067001681012C
+:10104000BC601B0DF7A100025E02F000A200B040E0
+:101050006700168200E01BE70066F900691BE701E4
+:1010600088D301BC60030006F90280200F0008D578
+:10107000006E40300209960381DE02F008DF00E0D6
+:10108000021700208503A9DE02F008DB0184E006D8
+:101090000910480180E0020910480184E002F7F7D6
+:1010A000BF0386DE02F00A87018060050048020166
+:1010B000806006F2979403BFDE02F009620183604C
+:1010C00002F7F7BF0386DE02F00A87032B5E02F009
+:1010D000090503A9DE02F008E80068DEAB00490557
+:1010E00000B0523B00179F00B0523B0017BE01BC3E
+:1010F000600300280E03BFDE02F0090502875E537D
+:1011000000091203A0DE02F008F403BFDE02F006BD
+:10111000920182E0060D906C0190600A091048006F
+:10112000B0523B00179F00B0523B0017BE019E5EBD
+:101130008300B0EB0106520F0017A100B85E8700D4
+:1011400037A10182DE86F577AB01BC6103003080F8
+:1011500000E8523AF3F7A2006BD23AF3E8F700E85E
+:101160005E7E91D7A200905E8B0097A101BC6023A8
+:1011700001D064006B523AF3E90201185E87001750
+:10118000A2010A5E870017A300886006F457A20038
+:10119000E04192F4706400B05802F45600006BDE37
+:1011A000FA91C90500B0523B0017BE03BFDE02F042
+:1011B000090500025E02F011EA00B0203B00280E93
+:1011C00000B0523B00179F0320DE02F00912020715
+:1011D0005E530009090180E00209104803BFDE02E6
+:1011E000F009120068DE5F00090F021A54070009B7
+:1011F0000D0103C0270017A101825E8610D0860171
+:1012000002C0270017A100E0422AF4308A0180E0E2
+:101210000500480203A9DE02F0091200B05E470093
+:10122000108001085E4F0017A100685E8700293614
+:1012300003AB5E02F0093A0200521700092500686C
+:10124000DEAB00491800E0025300209402865E5392
+:101250000009620284520F000AF70284D20F0009CB
+:101260001D03AC5E02F0092303BFDE02F0092E036A
+:101270002C5E02F0092E00685E4F0409230106D29D
+:101280000F0017A10080921B0197A200E0015E0DE4
+:10129000B0640181DE86C3F61F00685E4F020962FA
+:1012A00003BFDE02F00952031EDE02F0092B0331F8
+:1012B0005E02F0092B0068DEAB00492B0080921B18
+:1012C0000197A200E0015E0DB0640181E002C3F667
+:1012D0001F0068DEAB00493000E0023F00208F03B2
+:1012E000BFDE02F0093300685EAB00493302805272
+:1012F0002F0009620202410700093300685E4F04B3
+:10130000096200685E4F0289620284410700096237
+:1013100001806006F2979403BFDE02F00962032B9E
+:101320005E02F0096200685E4F05A95200685E4FD8
+:1013300005295203BFDE02F009620068DEAB0049F6
+:101340004201BC6003000ABD01826002F5D7AE0213
+:10135000805EFF00094000682B6F00094200E044F6
+:10136000655B4ADB00682B8BFFC94200E02B8B00DA
+:101370002AE202065E5300094500E002630020985D
+:1013800003BFDE02F009620323DE02F0094D0129EA
+:10139000500B0017A30068DE8F05294D0187E0027E
+:1013A0001070830184600209104800B05E87001746
+:1013B000A1006EE00300294C03D1DE02F0094D00CC
+:1013C00068DEAB00494F00E0022700208900685E1C
+:1013D0004F00096200685E4F01096200685E4F05B8
+:1013E0008962028047C70009940329DE02F0095888
+:1013F0000102DEAF0017A10106520F0017A200384C
+:101400005E86F449620182DE8AF577AB00B0522332
+:101410000011F200B052270011F300B0522B00115E
+:10142000F40106520F0017A100E05E870031F500BD
+:10143000B0005B0011F000B047C30018000134C7D2
+:10144000C70017A1006EDE8402A96201BC60030818
+:1014500010420283C1070009660301DE02F009653C
+:1014600003B55E02F0096602805E53000AF700B021
+:1014700040330017A10108A00F0017A200685E8B7F
+:1014800000696E00E840310577A10281200F000954
+:101490006E00B020AF0017A10280A00F00096E00FF
+:1014A000B05E630017A1006E5E8402099600B05E14
+:1014B000870007FA018160010048020202C01300A0
+:1014C000097400E05E840347FA0181600500480268
+:1014D0000201200F00098F01035E530017A101874D
+:1014E000DE850048020386DE02F00A8700025E0203
+:1014F000F0117A00025E02F00F9503855E02F0099A
+:1015000077018E60023D11E80107C7830017A10132
+:10151000825E850048020201A00F0009810103C715
+:10152000970017A101825E8500680300B0204B0080
+:1015300017A1018E5E850068030207C0AF000C444E
+:1015400001BC60030011EC01BC600F0011E80184D4
+:10155000600500680300B040270007FC00B0402B86
+:101560000007FD00B0406B0007FE00B0406F0007B1
+:10157000FF0184600500680300025E02F00C600158
+:10158000BC63FF1FD7A800025E02F00DAC00025E34
+:1015900002F00C4401A8600A0090040201200F0030
+:1015A00011D500A8401300500403BFDE02F005F877
+:1015B00000E002870020A103BFDE02F0099700E0EF
+:1015C000020B00208203A9DE02F00AF70184600604
+:1015D0000910480184E00609104803BFDE02F00A42
+:1015E000F7032B5E02F009B80068DE4F06A99F00E2
+:1015F000E0023B00208E03BFDE02F009A000E00203
+:101600003700208D0323DE02F009C00068DE4EF1B2
+:10161000C9C00187E002107083018460020910488C
+:1016200000B05E870017A1006EE0030029A603D179
+:10163000DE02F009A700685E4F0629B601BC600310
+:10164000000AA603295E02F009AC0203DEB300091A
+:10165000AD0191601A84F4270183E002F597AC0292
+:101660000200BF0009B50203456F0009B00185E023
+:10167000062B715B02045EB30009B50187E002101E
+:1016800070830183E00209104800025E02F0112716
+:1016900003BFDE02F009C00205500B0009C0018241
+:1016A000600609104803BFDE02F009C0028700C3CC
+:1016B0000009BD0068DE4F06A9BD0068D21300090D
+:1016C000BD01BC600300118301BC600300118200F6
+:1016D00068DE4F0629C000E0024F00209303BFDE02
+:1016E00002F009C003AB5E02F009C2020441070028
+:1016F00009C5028341070008AB03BFDE02F009C53C
+:10170000028441070008AB01806006F2979403BF92
+:10171000DE02F008AB039F5E02F009CA039EDE0200
+:10172000F00BE902035E53000BE902048143000958
+:10173000CE010001630017A10102C0270017A2001B
+:1017400038DE86F449C403AB5E02F009D0020052D1
+:10175000170009C40280522F0009D203335E02F041
+:101760000BE902181B330009F201BC601F15F0657C
+:1017700001BC60031BB7A400025E02F000E900B0E8
+:101780005E8F0017A60068DE931BA9EE0207C197C3
+:101790000009DF01385A070017A1013C5A0700175A
+:1017A000A201BC5A0AF457A2013C5A0B0017A3012C
+:1017B000BC5A0EF477A303BFDE02F009E2013C5AE3
+:1017C000030017A100B05A070017A200B05A0B007F
+:1017D00017A3006D5E870089E801BC61BF0A17A5E9
+:1017E0000068DE8AF4A9E801BC60271357A50068E9
+:1017F000DE8EF4A9E803BFDE02F00A2A00D85E8775
+:101800000037A100E14196F4306500E1C197003056
+:101810006501F041970017A200E05E8B0077A200FF
+:101820006D5E8AF4C9D500E840330097A5006E5E6E
+:1018300096004A2A00B01B2F0017A10068DE840A18
+:101840000BE9023C523F000A03013C523F0017A142
+:101850000068DE84048A2801BC600316106401BCA1
+:10186000601F16106500685E870029FF00B05A03EC
+:101870000017A20068DE8AC00A2800E04197003005
+:101880006500E0419300306400E85E870057A100E6
+:101890006A5E870029F800685E87000A0401385AEA
+:1018A000030017A1013858030017A20068DE86F470
+:1018B0004A2803BFDE02F00A040285C107000BE9D3
+:1018C00001BC601F15F06501BC600305B7A40002F0
+:1018D0005E02F000E9028000C3000A2801BC601328
+:1018E00010D7A600E0017F00B7A5006D5E96F4CA90
+:1018F0000C01BC60130957A500685E940BCA2C004C
+:10190000B0017B00106500B052270017A200B05252
+:101910002B0017A3006841940BEA170068DE8ED0F5
+:101920004A1300685E8AD02A2800E0419700B0651B
+:10193000006D4196F4CA1001BC601309506503BFE5
+:10194000DE02F00A1000E0028B0020A200B0017F4E
+:1019500000106500B0522300168000B05227001618
+:101960008100B0522B0016820080921B0197A200CA
+:10197000E0015E0DB0640203587F000A2101BC60E3
+:101980002F0037A103BFDE02F00A2201BC5202F28F
+:10199000F7A101A95E02F436830090446701168422
+:1019A000020281AB000A260068DE9305AA270184A3
+:1019B0006006D0968400B05E9700005F020781AB9E
+:1019C000000A2A01806006F2979403AB5E02F006DB
+:1019D000AA03BFDE02F008AB00E0028F0020A303E1
+:1019E000BFDE02F009C4039EDE02F00BE903AB5E2A
+:1019F00002F00A31020052170009C403335E02F0FC
+:101A00000BE901846006F2979403AB5E02F006AA2C
+:101A100003BFDE02F008AB03835E02F00A38000267
+:101A20005E02F0117A006D4033038A35006D403359
+:101A30000389C4032B5E02F00BED03BFDE02F00648
+:101A4000AA032B5E02F00A3E00E0023300208C0362
+:101A5000BFDE02F006AC00E0024B0020920103C0A2
+:101A60002700178101825E0503178100025E02F0E4
+:101A70000D9A008800230037A200E05E8800F7A2DC
+:101A800000E05E86F451890186E00630118003BFD4
+:101A9000DE02F009C003A2DE02F0008103A3DE0231
+:101AA000F00A6400E001FF00207F01BC6003001722
+:101AB000A303BFDE02F00A66018760040310A001E1
+:101AC000BC60030051E400B0479300180001BC6003
+:101AD0000302900401BC620F0011E001BC600F0121
+:101AE00031E800B047A300180001BC600F0011E806
+:101AF00001BC60030131EC00B047B300180001BC29
+:101B000060030011EC018460060910480020601E8B
+:101B1000090A5B00E001FB00207E03BFDE02F00A41
+:101B20006C01BC60030ED7A1011400630017A20072
+:101B3000E05E86F4506500E05A0300368002030040
+:101B4000C7000A6103A95E02F00A660291509F0075
+:101B50000A650191601A84F42703BFDE02F00A656A
+:101B600000E001FF00207F01BC60030037A30323D6
+:101B7000DE02F00A6C0183E0020910480184600271
+:101B8000F597AC01BC600300178E0187E00210706E
+:101B9000830182600209104803D0DE02F00A6D035F
+:101BA000D05E02F00A6E0182E00209104803D5DE21
+:101BB00002F00A7001BC60030010B401BC600300B5
+:101BC000F7A1006800A7000A740185421AF437A142
+:101BD00000025E02F000A200B040670017A501BC41
+:101BE00063FF1FF7A200025E02F000A800886007F2
+:101BF0000157A400B85E86F497A100025E02F000CF
+:101C0000A80283C21F000A7B00E044670117A102FB
+:101C1000044523000A80006B4466F42A7D00025EBE
+:101C200002F0116100685E8F0000020020E01E09D2
+:101C30000A8400B05E9700142E03BFDE02F002CCCF
+:101C400000A8412300F04803BFDE02F00002018338
+:101C5000600209104801BC6007001042006E40306D
+:101C6000020A8A00E0027700209D00025E02F01264
+:101C7000A703A35E02F008AB03C6DE02F00A8D01E3
+:101C800084E00609104803BFDE02F00AF70068206E
+:101C9000E3000A9500E844650717A101BC609F02B4
+:101CA00017A2006D5E86F44A9501BC6003000838F7
+:101CB00000025E02F00B160020E10209007C002009
+:101CC000628A090A9900025E02F0117A03BFDE02FD
+:101CD000F0007C0284452300007C03915E02F0004A
+:101CE0007C0396DE02F0007C03965E02F0007C002E
+:101CF000025E02F00B1601BC600300602000680168
+:101D000073000AAF00025E02F000D400B044670026
+:101D1000083800B001730010E401BC600300000645
+:101D200001BC600300005C01BC600301D78201D2EA
+:101D3000DE087570E000B00EB30010E100B000479F
+:101D400000108600B00ECF00108A01BC600300377F
+:101D50008100025E02F00D8D0190600A09104801B9
+:101D6000BC610300308003BFDE02F0000201BC60F2
+:101D7000030030420187E00224712300025E02F07A
+:101D8000109301BC600306778000680DEF000AB66F
+:101D900000B00DEF00178100025E02F00E440397C1
+:101DA0005E02F00B2703125E02F00AB601BC60036C
+:101DB00000402001BC618300112500B0007B0011B0
+:101DC0002701BC600702578000025E02F00E3F0050
+:101DD000B05E07000B3001BC600702778000025E36
+:101DE00002F00E3F00B05E07000B3101BC6013092A
+:101DF00097A100025E02F000A200B04067000B63F2
+:101E000001BC601309405E01BC601309405F0180A2
+:101E1000E006F5D7AE0107C1070017A101805E8675
+:101E2000F577AB01BC600F0011E801BC620F001137
+:101E3000E000025E02F00AD801BC61CF0C105C0128
+:101E4000BC600300105D01BC61CF01F05E01BC60AD
+:101E50003B0AF05F00025E02F0106301BC60030009
+:101E60000835020300C700000401BC60030006023D
+:101E700001BC600300060701BC600300060C01BC46
+:101E8000600300061103BFDE02F0000401BC6043E2
+:101E90000017BB00A04122F770480185E002F5B7AA
+:101EA000AD01BC63FF1FF05401BC63FF1FF055017F
+:101EB000BC63BF1FF05601BC63FF0FF05700025E0A
+:101EC00002F012A70187E00624712301BC60030021
+:101ED000105401BC600300105501BC600300105693
+:101EE00001BC600300105701BC600F002017010601
+:101EF000C1070017A101825E8402E01701074107B4
+:101F00000017A100B85E870037A10180DE870000BE
+:101F1000160002DE02F000000285C0370000020059
+:101F2000025E02F0117A00025E02F00F9502864016
+:101F300037000AEC00E0021B0020860386DE02F078
+:101F40000A870287C037000A870158600300102AF9
+:101F500001BC600300900400B040130017A103BF50
+:101F6000DE02F0000401B8600A04902403AA5E02B5
+:101F7000F00AFA0158600300102A01BC60030290C5
+:101F80000400B040130018000183600209104801EA
+:101F9000BC60030051E400B0479300180001BC622C
+:101FA0000F0011E00180600100680300025E02F092
+:101FB0000F9503855E02F00B0101BC620F0011E07A
+:101FC00001BC600F0131E800B047A300180001BC5C
+:101FD000600F0011E801BC60030157A100E85E87B3
+:101FE0000037A10068DE87000B0801BC6003029087
+:101FF0000400B0401300180001BC60030131EC0084
+:10200000B047B300180001BC60030011EC0324DEEC
+:1020100002F005F801866006F577AB00025E02F07B
+:102020000B160180600610308100B05E870017A19A
+:102030000180600210308103BFDE02F005F801BCB0
+:10204000610300108000B04203001800006EE0033E
+:10205000002B1903505E02F00B1C00015E02F00021
+:102060000003BFDE02F002F401846002F597AC00C9
+:10207000A8412304F048018260020910480206DEEC
+:10208000AF000B2203D5DE02F00B220350DE02F07C
+:102090000B2001BC60030010B40284C783000B2531
+:1020A00001BC600B0011E0018E6002F577AB00020D
+:1020B000DE02F0000003A2DE02F0007C02BC4287D8
+:1020C000000B2E01BC60030037A401BC60031FF7A6
+:1020D000A3011400630017A200886006F457A2034E
+:1020E000BFDE02F00B33008860070117A401BC6358
+:1020F000FF0017A3011400630017A200E05E8B012C
+:1021000017A200886006F457A201BC601311106585
+:1021100001BC601B02506401BC60030017A50020D5
+:10212000C286F48B3D00E0419706D06500E0419304
+:1021300001F06400E05E970037A500885E930037E9
+:10214000A400205E92F46B5C03BFDE02F00B36004D
+:1021500068DE92F44B4200680083006B4203A0DE0D
+:1021600002F00B420020C123160B3700025E02F082
+:102170000B16006DDE93200B58020300C7000B4CBA
+:10218000006DDE97008B4C01BC600300160801BC9B
+:10219000600300160901BC600300160A01BC60035D
+:1021A00000160B01BC600300160C01BC6003001696
+:1021B0000D01BC600300160E02005AC3000B57024B
+:1021C0003C5A9F000B5700680083006B570385DE65
+:1021D00002F0007C03855E02F0007C03A2DE02F0C8
+:1021E000007C03A3DE02F0007C0397DE02F0007C9B
+:1021F00000B041970010600191600A84F42703BF8A
+:10220000DE02F002CC01806002D616B000B05E9310
+:102210000010A101836002F7F7BF01BC600300302A
+:102220004303BFDE02F00B370068808300607C034D
+:10223000BFDE02F00AB70283C21F00000200B05ED8
+:10224000870017A103D0DE02F0051001BC60030473
+:102250001042039EDE02F0000400B05E3F00114514
+:1022600001BC600300178F00B05E4300178500B00B
+:102270005E0F00179000025E02F00B1603BFDE0235
+:10228000F00004006D40330589C503AC5E02F00B1D
+:102290006E00685E4F028BC000E002670020990369
+:1022A000BFDE02F00BC000685E4F028BC000E00290
+:1022B0005F00209701856002F5B7AD01826002F5ED
+:1022C000D7AE01BC6003000ABD039EDE02F00B82A4
+:1022D0000321DE02F00B8200E0026F00209B00026F
+:1022E0005E02F00B16018660020910480180600250
+:1022F0000910480181E00209104801BC6003021086
+:10230000420280441F000B8100B05E3F0011450176
+:10231000BC600300178F00B05E4300178500B05EFD
+:102320000F00179003BFDE02F00B8200A044B6F04E
+:102330007145028200C3000BC000B000730017A1FA
+:1023400000E05E86B017A100E15E7AF4379E00E1FE
+:10235000DE7700179D00E1DE7300179C00E0DE6F62
+:1023600000179B039EDE02F00B91006E5E6E924B97
+:10237000D6006D5E6E924B91006E5E72922BD6000F
+:102380006D5E72922B91006E5E76920BD6006D5E42
+:1023900076920B91006DDE7A91EBD6028201AB0052
+:1023A0000BA200B0446700083400B0446B0008334F
+:1023B00000B0446F00083200B04473000831006878
+:1023C000A0D2232B9100E920D2F3D79E00E9A0CE22
+:1023D000F3B79D00E9A0CAF3979C00E8A0C6F37785
+:1023E0009B00E15E7A91F7A100B05E8700111900B1
+:1023F000E1DE7692111A00E1DE7292311B00E0DE1E
+:102400006E92511C0068DE86232B9B03BFDE02F018
+:102410000BC000E9523EF3D7A100E9D242F3B7A2C4
+:1024200000E9D246F397A300E8D24AF377A40088E4
+:10243000121B0057A500E0015EF4B06400E95E865F
+:10244000C9A6D200E9DE8AC9C6D300E9DE8EC9E694
+:10245000D400E8DE92CA06D50080921B0197A50140
+:10246000BC601B11778000E05E020DB06500885AE9
+:102470000F00B7A500B05E970217A50125DA0F007F
+:1024800017A600E95E94DA57A500E8DE98DA77A689
+:10249000017ADE96F4D7A500685E96D06BC000E89E
+:1024A0005E96D077A600B05E9700168300685A1338
+:1024B000000BBA00E05A16F4D68500685A1B000BD0
+:1024C000BC00E05A1EF4D68700B05E8700164D00AF
+:1024D000B05E8B00164E00B05E8F00164F00B05EEF
+:1024E00093001650031EDE02F00BD6039F5E02F02F
+:1024F0000BD600685E4F028BD6032C5E02F00BD623
+:1025000001BC601F16B06501BC600300B7A40002E7
+:102510005E02F000E90068DE9300ABD60207C197C7
+:10252000000BCC013C5A07001788013C5A0B0017DE
+:10253000A103BFDE02F00BCE01385A070017880155
+:10254000385A0B0017A10080921B0197A200E001EE
+:102550005E0DB06400B05E230016280181DE86C3E4
+:10256000F61F0187DE86249124020680F3000BD635
+:102570000181E002C3F61F0187E00224912403AB2E
+:102580005E02F006AA03BFDE02F008AB032B5E0278
+:10259000F009C403BFDE02F006AA03AB5E02F00B33
+:1025A000DD032C5E02F009C403BFDE02F00BED0078
+:1025B000B052230011F200B052270011F300B052C4
+:1025C0002B0011F401BC60030091F500B0005B002A
+:1025D00011F003BFDE02F006AA0138523F0017A136
+:1025E00002065E53000BE60138524B0017A100684B
+:1025F000DE87008BE903AB5E02F006AA03BFDE02B2
+:10260000F008AB0068DE4F020BEC020781AB000B59
+:10261000EC01806006F2979403AB5E02F006AA021A
+:102620000000F3000BF20206DE53000BF201185E0D
+:10263000830017A10068DE8700ABF201BC600B02CB
+:102640005142020052170009C403BFDE02F008AB7A
+:1026500001BC600300118301BC6003001182032CE4
+:102660005E02F00BF90199E00620110003BFDE02C3
+:10267000F00BFD0119402F0017A100685E870009CB
+:10268000C00199DE8620110003315E02F009C0000E
+:10269000A05E3B0097A200205E4EF449C00184601A
+:1026A0000209104803BFDE02F009C0032B5E02F0EE
+:1026B00009C00068DE4F042C0600B0523300179F9B
+:1026C00000B0522F0010EB0281522F00069200E062
+:1026D00002AB0020AA0281522F0009A003295E024A
+:1026E000F00C0C0203DEB3000C0C0191601A84F4B0
+:1026F000270183E002F597AC0208522F0006AA03D7
+:10270000BFDE02F008AB01BC600300106701BC60D3
+:10271000030010460180E0060930490282C11F0013
+:102720000C1601BC602F1FF06501BC600300168011
+:1027300000E841970030650069C197000C1301BCA7
+:10274000600B00179401BC60030017AB01BC600371
+:102750000017AC01BC60030017AD01BC600300179B
+:10276000AE01BC60030017BF01BC60030020200164
+:10277000BC60030017A100025E02F000A201384015
+:1027800067000028011C406700002901BC600300AD
+:10279000504901BC60030017A701BC60030017A8E3
+:1027A00001BC60030017A901BC60030017AC01BCA9
+:1027B00060030017AD0182E0060F10780206C1E346
+:1027C000000C28006880A7000C2B03BFDE02F00C71
+:1027D0002C006880A7008C2C01BC600B1EA000019F
+:1027E000BC600300200101BC634F01A00201BC6179
+:1027F000DB06800301BC600300400401BC604309A8
+:10280000200501BC601F14106101BC601317D0606B
+:1028100001BC600300082900B05E0F00178500A00E
+:1028200044B6F07145028741D7000C3701BC600304
+:10283000000BF001BC600300107D01BC60030010C0
+:102840007C01BC606300107B01BC600300107A0156
+:10285000AC607F00107501BC63470897A10068C198
+:10286000DAF42C43011A41DF0017A10068DE87016A
+:102870006C4301BC637B15ABF003BFDE02F00A9E24
+:1028800001885E5CFF87FC01BC601F1F500701BC14
+:102890006003019008018860060090040386DE0250
+:1028A000F00A870305DE02F00C480386DE02F00A18
+:1028B000870385DE02F00C4A00B05E870017A10096
+:1028C0006EE003002C4E0386DE02F00A87006EC025
+:1028D000146F2C5101BC60070010420207C0AF000A
+:1028E00007590002DE02F0000003215E02F00C57DF
+:1028F00000E02066F4281900B0206700178B03BFA2
+:10290000DE02F00C5F028150C7000C5C011C509F7E
+:1029100000178B00E05E2EF4378B019C5E2E84F452
+:102920002703BFDE02F00C5F011E509F00178B00D3
+:10293000E05E2EF4378B019E5E2E84F4270002DECB
+:1029400002F000000107402700082800E020A30053
+:1029500028280002DE02F0000000B044670017A241
+:10296000017ADE8A2357A10090012F00B7A601BC8F
+:10297000601B11706501BC60030017A201BC601BE5
+:102980000DD06401BC601B1B906300685A03000CEF
+:10299000A8006B5E86D06C7E00B05A030017A300BF
+:1029A000E05A0EF4D58000E05A0EF4768300E85A1F
+:1029B0002F00368B0069DA2F000C7200E85A0700EE
+:1029C000368B006CDA0EF42C6D01BC60030036000F
+:1029D00001BC600B00104301BC60030026DA00203C
+:1029E0005A0B080C7901BC60030026DB03BFDE0232
+:1029F000F00C7E00205A0B140C7E01856006F5B7A2
+:102A0000AD0088009B00D1260090009B0151280159
+:102A1000BC6303001124006B5E86B00C8600685A0C
+:102A200013000C8301886006D0568200B056030064
+:102A300017A400E05E92D0968500E05A0EF4D5808F
+:102A400000205A0B080C8601BC60030006DB0068FE
+:102A50005A13000C8E006B5E86D0AC8E0188600A23
+:102A6000D0568200B056030017A400E05E92D096C4
+:102A70008501BC600300360101BC600B00104301FE
+:102A8000BC60030026DA00685A1B000CA8006B5ECD
+:102A900086D0ECA802015A0B000C9D00E85A1B00DE
+:102AA000368600B05A270017A300E05A1EF4768736
+:102AB00001BC601B1C106200E0418AF4506200B04F
+:102AC0005A2B0017A300E05402F475000202D4034D
+:102AD000000C9B00E05A1F003687012054030015AC
+:102AE0000001816002D0568203BFDE02F00CA0001C
+:102AF000B05A230017A300E05A1EF47687018160C4
+:102B000006D0568200685A1B000CA2006CDA1EF434
+:102B10002C9002015A0B000CA501BC600300360288
+:102B200003BFDE02F00CA601BC600300360301BC4B
+:102B3000600B00104301BC60030026DA00E04197FF
+:102B400001906500E05E8B0037A200E041930090A9
+:102B50006400E0418F003063006D5E8B008C6A0082
+:102B600002DE02F0000000B05A0300101F00B05A4D
+:102B70000700102000B05A0B0010210180600700F0
+:102B8000101D02804077000CB20002DE02F000004F
+:102B90000187E002F577AB03915E02F000020020AE
+:102BA000E3FE09000200025E02F00C6301BC601B40
+:102BB00011706400E041930617A20068D82F000C42
+:102BC000BC0281D80B00000200E041930190640038
+:102BD0006D4192F44CBA0287C49300000200689BD6
+:102BE0006F00000202815E53000CC90283411F0086
+:102BF0000CC30281DE53000CCF01BC6003001151F5
+:102C000001BC600300115201BC620300115301BCFE
+:102C1000600300515001896006F2979403BFDE0201
+:102C2000F000020280C54300000201F0C547001118
+:102C3000560107C5470017A101F0C54AF4315501F7
+:102C400089600AF2979401BC60030810470392DE82
+:102C500002F00D1C01BC601B11706501BC6003001B
+:102C600037A101BC63FF1FF7A201BC60030017A3DB
+:102C700001BC60030017A600685A03000D0B01BCDD
+:102C800060030017A502035A0B000CDE02805A0BEA
+:102C9000000D1C00E944080977BB00E8C40F0017C9
+:102CA000A4017ADEEEF497A400685A13000CEA033C
+:102CB000BFDE02F00CE70203DA0B000CF200B05AA0
+:102CC0000F0017A400685A07002CE300685A2F0071
+:102CD0002CE301BC60030037A500685A13000CE721
+:102CE000006CDE92D0ACE700B05A170017A401BC0C
+:102CF00060030037A5002019FAF42CEA00685A1B7B
+:102D0000000D0503BFDE02F00CED00885E87009722
+:102D1000BB002019FAF76D1C02015A0B000D1C00B4
+:102D20006CDE92D0ED0500B05A1F0017A4002019E8
+:102D3000FAF42CF101BC60030037A503BFDE02F0FA
+:102D40000D050202DA0B000D0B0204C107000D1C79
+:102D500000B05A0F0017A400E85A2F0037BB0069D3
+:102D6000DEEF000CF800E85A070037BB013C016FAA
+:102D70000017800068DE03000CFE0138016F0017A9
+:102D80008000685E03000D0100E85E030037BB03AE
+:102D9000BFDE02F00D0100E85E030037800080DE38
+:102DA00002D0378000E05EEE0DB7BB00685EEF003A
+:102DB0000D0500E05E92D017A400E85EEF0037BB7F
+:102DC00003BFDE02F00D0100685E8F000D08006B8E
+:102DD0005E92F44D0903BFDE02F00D0B01BC6003EF
+:102DE0000037A300B05E930017A200B05E970017F3
+:102DF000A600885E870037A100E04197019065003A
+:102E00006D5E87020CD500685E8F000D1C00B0441B
+:102E1000670017A5017ADE962357A500E85E8AF4BD
+:102E2000B7A400885E9300A6D700905E930166D891
+:102E300000B0012B0017A300689B63000D17006E04
+:102E40009B5EF46D1C03A65E02F00D1C00B05E9B41
+:102E50000006D900E91B5EF4681400E89B630008D3
+:102E60001503BFDE02F00D1E00681B6700000203A1
+:102E7000BFDE02F00D6F01BC610300112300692069
+:102E800057000D220180E006F2979403BFDE02F0A6
+:102E90000D240180E002F2979403BFDE02F00002ED
+:102EA00000684127000D3002844523000D2500B045
+:102EB00044670017A100E84466F437A2006D5E8BFA
+:102EC000004D270280C127000D2B0392DE02F00D7A
+:102ED0006F0392DE02F00ACA00025E02F010970051
+:102EE000025E02F00E4F00025E02F00E4A00025E29
+:102EF00002F00E5A01BC600F0011E8031EDE02F062
+:102F00000D3701BC600300105C01BC600300105D64
+:102F100001BC605304105E01BC600300105F03BF7E
+:102F2000DE02F00D3B01BC600B00105C01BC6003D5
+:102F300000105D01BC604304105E01BC6003001022
+:102F40005F01BC6003008020028500BF000D80008F
+:102F5000B0205300115100B02057001152006E20D4
+:102F6000522A8D430068A057000D4300E0205223F1
+:102F7000281603BFDE02F00D4500B04467000816B6
+:102F800001BC600300315001BC60030C90400000A4
+:102F9000DE02F000000068C103000D4A02804543D4
+:102FA000000D45006B446502CD4501BC6003001176
+:102FB0005002844543000D4B00B044670017A10048
+:102FC000685E86232D4D01BC6003004020018660B1
+:102FD0000620110000E920522A37A100E8A0562A55
+:102FE00057A200E14466F4311900E1C46AF4511AB1
+:102FF00000E1C46F00111B00E0C47300111C00B09D
+:10300000441F001800008844230157A30090442364
+:1030100000D7A400B0440B0017A100B0440F001764
+:10302000A200E95E862337A100E8DE8A2357A200CA
+:1030300069DE8B000D6500E1440AF4710200E0C412
+:103040000EF4910300E02AF7002ABD00E85E230099
+:1030500037880069DE23000D5900E8002700378813
+:1030600003BFDE02F00D59018660022011000068E6
+:10307000C103000D6F00681B67000D6F01BC60434A
+:103080000017A100E04466F4378001BC600300062D
+:10309000DA00025E02F00C63006C4466F00D6F0013
+:1030A000681B6B000D6B03BFDE02F00CCF0200DE6D
+:1030B00053000D820180E002F2979400025E02F05C
+:1030C0000E4D01BC600300104003BFDE02F00D7521
+:1030D000020080C3000D7900E044640957A100E8B4
+:1030E0005E862137A1006CC466F42D7703BFDE0233
+:1030F000F00D8200E8012A21281401BC60030008B9
+:103100001500B0205300115101BC600300115201A1
+:10311000BC600300315002804543000D7E03BFDEDA
+:1031200002F00D4F01BC600300104000B0012B0005
+:1031300011090068AAE7000D8300B0012F001109F2
+:1031400001BC61CF0C105C01BC600300105D01BCD0
+:1031500061CF01F05E01BC603B0AF05F00025E02DD
+:10316000F00E5600025E02F00E5F00025E02F00EEC
+:103170005301BC60030006D903BFDE02F00ACA0196
+:10318000885E0610D08601025E070017A101825EEC
+:103190008610D08601BC600306778000B00DEF007A
+:1031A00017810288421B000D9400B00DEB001781BF
+:1031B00000685E07000D9600025E02F00E44020BEE
+:1031C000421B000D9803BFDE02F00D99018B20A277
+:1031D00010D0860002DE02F0000000B05413001789
+:1031E000A10200DE07000DA100B0418B00106501B7
+:1031F000BC600301D7A100025E02F011A500E05EF1
+:103200008400F7A103BFDE02F00DA6020480F300E4
+:103210000DA602025E07000DA602805E07000DA645
+:103220000090001B0037A200E85412F457A10002DE
+:10323000DE02F00000020400BF000DAA00025E02E0
+:10324000F00F4E03BFDE02F00DAB00A044B6F0B1AC
+:10325000450002DE02F00000020000BF000DBC00CD
+:1032600068AC0F000DBC00E05EA30037A8006D5EE7
+:10327000A005CDBC00B02CB70017A100025E02F083
+:1032800000A200B040670017A20068DEA3FFEDB9FE
+:1032900000B05E8965D7A2006D00A7008DB8006DF3
+:1032A000A0A3004DBA03BFDE02F00DB90068A0A3D1
+:1032B000000DBA00B85E8965D7A200025E02F00078
+:1032C000A801BC60030017A80002DE02F0000000A5
+:1032D000D85A030117A201B85A06F457A200B056F3
+:1032E0000300083C00B0560700083D00B0560B0034
+:1032F000083E00B0560F00083F00B05613000840CB
+:1033000000E05612F4484100B05A0300083A013870
+:103310005E8B00083B00B021070017A401BC6003CE
+:103320000017A200B0419300106500B85E92D0175C
+:10333000A400E05E06F4506300F05E930017A30063
+:10334000F05E930077A400E05E8B0037A200B85EC9
+:1033500092F477A400E04192F4506500E05602F444
+:10336000958000B056030017A4006EDE8B00ADCA36
+:1033700000B85E92C0D7A200D85E8B0037A200E0F2
+:1033800020F2F4483C00B020F30017A400B85E928D
+:10339000C0F7A200D85E8B0037A200E020F6F44808
+:1033A0003D00D820F70037A200E020FAF4483E00A4
+:1033B000D820FB0037A200E020FEF4483F00D820D0
+:1033C000FF0037A200E02102F4484000D8210300AA
+:1033D00037A200E02106F4484100B021070017A2FF
+:1033E00000B85E8AC017A200905E8B0037A201BCB5
+:1033F0005E8907683B0002DE02F000000180600683
+:103400003C91E4018760063CD1E601A860023CD112
+:10341000E6018B60023CD1E600B05E8F00106300D5
+:10342000B056030011E700B056070011E700B05690
+:103430000B0011E700B0560F0011E701A960423CF4
+:1034400091E401A860023CD1E6018B60063CD1E624
+:1034500000B05E8B00106301BC60030057A1020442
+:103460005603000DF801BC60030117A100E0418E76
+:10347000F4306300B056030011E700B056070011A6
+:10348000E700B0560B0011E700B05E8B001063013F
+:10349000BC600300B7A10204D603000E0201BC60A9
+:1034A000030117A102065E53000E0201BC60030176
+:1034B00097A100E0418EF4306300B056030011E79D
+:1034C00000B056070011E700B0560B0011E701BC31
+:1034D00060030017A10206DE53000E0D00B05E8BE4
+:1034E00000106302065E53000E0C00A0563F01F769
+:1034F000A103BFDE02F00E0D00A0563301F7A100BC
+:10350000B05E870011E701BC60030011E70002DE36
+:1035100002F0000000685E9B00CE2A01BC6007023A
+:1035200011E30068DE9B004E1D00E847870111E1B2
+:1035300001BC60030011E201BC60030011E201BCA8
+:1035400060030011E201BC60030011E201BC6003F2
+:103550000011E201BC60030011E201BC6003001134
+:10356000E201BC60030011E200B06142F451E000EE
+:10357000B058030011E200B058070011E200B05843
+:103580000B0011E200B0580F0011E200B058130018
+:1035900011E200B058170011E200B0581B0011E210
+:1035A00000B0581F0011E200B05E9B0017A4006835
+:1035B000DE9B00AE2801BC60030077A40192DE937D
+:1035C0000217A30002DE02F0000001BC6007001138
+:1035D000E300B058030011E200B058070011E20008
+:1035E000B0580B0011E200B0580F0011E200B058C3
+:1035F000130011E200B058170011E200B0581B0090
+:1036000011E200B0581F0011E200E00146F0106422
+:1036100001BC60070031E300B058030011E200B0C4
+:1036200058070011E200B0580B0011E200B0580F2B
+:103630000011E200B058130011E200B05817001159
+:10364000E200B0581B0011E200B0581F0011E20167
+:1036500092E01B0017A30002DE02F0000002874088
+:10366000C3000E3F01866006F01030028640C300A2
+:103670000E4100B040C70017810002DE02F00000DA
+:10368000028740C3000E4400B05E0700103101867F
+:10369000E006F010300002DE02F00000006800A733
+:1036A0000112E303BFDE02F00E5E00025E02F00EC6
+:1036B0004D00025E02F00E5F0002DE02F00000002C
+:1036C0006800A70112AC0002DE02F0000001816078
+:1036D00006093049006800A7008E5200025E02F021
+:1036E0000E6F0002DE02F0000000025E02F00E6FBC
+:1036F000018160020930490002DE02F00000018809
+:10370000E00E09304900B0412700180000B0002B3E
+:103710000010020002DE02F0000001BC6003001095
+:10372000020182E0020F107801BC60030010490022
+:10373000B041270018000002DE02F000000068001F
+:10374000A7010E600280DE53000E6601BC60130705
+:1037500077A100025E02F000A2019060020337A28E
+:1037600000025E02F000A80002DE02F0000001BCD0
+:1037700060130797A100025E02F000A20190601E94
+:103780000337A200025E02F000A801BC60130777B5
+:10379000A100025E02F000A20190601E0337A200A9
+:1037A000025E02F000A80002DE02F000000100DE6E
+:1037B000530017A60181DE9A09304900B041270065
+:1037C00018000002DE02F000000002DE02F000003D
+:1037D00000B044670017A2017D5E8A2357A300B0A2
+:1037E0001C770017A100B85E84E3D7A2025A5E8B53
+:1037F000000E7C0180E006F4271E01825E86F297AF
+:103800009400B05E8F00071B02001C7B000EC300FB
+:10381000E85E8CE377A2006D5E88E38EC300E0442F
+:10382000670287210285C523000EC00020E3FE0940
+:103830000EC001BC60130997A100025E02F000A255
+:103840000068C067000EC001BC60131617A100021B
+:103850005E02F000A20068C067000EC001BC6013E9
+:1038600009D7A100025E02F000A20068C067000E46
+:10387000C001BC63FF1FF7A10068DE862C2EC002CA
+:10388000009C7B000EB40180E000E3C71E01BC6019
+:10389000230F57A100025E02F000A200B0406700B3
+:1038A00077A400B05E930017A200025E02F000A8A9
+:1038B00001BC601B1B57A100025E02F000A2018147
+:1038C000E0060337A20186E006F457A200025E027A
+:1038D000F000A801BC601714D7A101BC600300B7B9
+:1038E000A200025E02F000A801BC60171457A101FB
+:1038F000BC60031877A200025E02F000A801BC6061
+:103900001714B7A101BC600300F7A200025E02F029
+:1039100000A801BC60171077A101BC600F0417A2BA
+:1039200000025E02F000A801BC60171097A101BC64
+:1039300060030017A200025E02F000A801BC60173D
+:1039400010B7A101BC600B0017A200025E02F000DC
+:10395000A801BC601710D7A101BC60030017A2002A
+:10396000025E02F000A801BC60171017A101BC6044
+:103970000B0037A200025E02F000A801BC60230F1A
+:1039800057A100A85E930077A200025E02F000A893
+:1039900001BC60171017A100025E02F000A2020035
+:1039A0004067000EB9006CC464E42E8003BFDE02E1
+:1039B000F00EC001BC60171277A100025E02F00099
+:1039C000A20068C0671FEEC001806000E3C71E014F
+:1039D000BC600300904301806000E3C71E01826069
+:1039E00002F297940180E004E3C71E01BC6003006B
+:1039F000071A03BFDE02F00EC30002DE02F0000071
+:103A00000201C11F000ED602855EAF000EC90185FE
+:103A10006006F577AB00B0446700082500B0446B42
+:103A200000082600E9446504B7A100E8C46904D78A
+:103A3000A200D05E870077A101E1DE8AF437A20000
+:103A4000E95E862697A100E8DE8A26B7A200695EB5
+:103A50008B000ED601BC610300113300E144DAF49F
+:103A6000313600E144DEF4513701856002F577AB71
+:103A700001BC600301104701BC6003005043000219
+:103A8000DE02F0000000B0451F00178100B005B74E
+:103A90000017A601BC600704106401BC601311107C
+:103AA0006501BC60030017A10205DEAF000EEF0048
+:103AB000B0580F00178000685E842C2EF702005E5D
+:103AC0009B000EEF0280DA03000EE50118581F007C
+:103AD000178200E05E0B00378201985E0AC0F6078D
+:103AE00003BFDE02F00EE8011A581F00178200E043
+:103AF0005E0B003782019A5E0AC0F60701F0DE0312
+:103B000000378000A05E02C0578000B05E03001640
+:103B10000300A044B6F0178200B05E0B001605004B
+:103B2000E05E0AC0960603BFDE02F00EF700B05852
+:103B30001300178200E85E06F057A5006ADE9700C2
+:103B40000EF500E85816F4B6050069D817000EF512
+:103B500001BC600300160500B058170017A500E06F
+:103B60005812F4B60600E0419302106400E0419759
+:103B700006D06500E05E870037A100905E9B0037AD
+:103B8000A60068DE87008EDC01BC600300114701DF
+:103B9000BC600300016D0002DE02F0000001BC60A9
+:103BA0000300016C01BC600300016D01BC60070AE9
+:103BB000106401BC60030077A100B0428F00178041
+:103BC00000A05E0301F78000B05E0300016E01BC3F
+:103BD00063FF1FF7A20068DE03000F0901BC60034A
+:103BE0000017A200886006F43781002005BAF02F84
+:103BF0000E0068DE8AC0CF0E00E005B300216C0025
+:103C0000B005B6F0216D00685E03000F1200205E63
+:103C100006F00F18006EDE8AC0CF1803BFDE02F078
+:103C20000F13006DDE8AC0CF1800B05E870017A3A7
+:103C300000B0419300016600B0581B0017A201BC00
+:103C4000600300016C01BC600300016D00E841935A
+:103C500002106400E85E870037A10069DE87000F6C
+:103C60000900B05E8F0001650002DE02F000000076
+:103C7000B0059B001064006E581B002F2100E05817
+:103C80001B00314503BFDE02F00F2200B0581B00BD
+:103C9000114500B0059B00016200B005970001616D
+:103CA00000B0580F00178500B0580700178300B008
+:103CB000580B0017840118581F00178C011A581F41
+:103CC00000178D0002DE02F0000000B0059700171B
+:103CD0008000685E002C2F4D01BC600300111201B2
+:103CE000BC600300111500B0059B00106402004584
+:103CF00023000F3700B0451F00178100E80592F040
+:103D00003780006ADE03000F3500B05E0300114506
+:103D100003BFDE02F00F3801BC600300314503BF72
+:103D2000DE02F00F3800B0059300114500B00583A6
+:103D300000016900B0058B00016A00B0058F000129
+:103D40006B00B0058700016800B005AB001065028C
+:103D5000845A1F000F4100B05E1700168301985E61
+:103D600032D0F687019A5E36D0F68701846002D0A1
+:103D7000F68700B0059300016000B0059B0001626A
+:103D800000B0059F00016300B0059700016100B01D
+:103D9000058B00106400B0580F00178500B058075D
+:103DA00000178300B0580B0017840198581EF19734
+:103DB0008C019A581EF1B78D03BFDE02F00F4D0043
+:103DC00002DE02F0000000B0058B001064006E41BE
+:103DD000932A0F5B00A044B6F0B7A100B05E870045
+:103DE000160500E05812F4360600B0581B001145C5
+:103DF000020000F3000F58006D4193280F58020095
+:103E0000DEAF000F5801BC600B02514200B05E876C
+:103E100000016F02015EAF000F5B00B05E1700167D
+:103E20000301816002F577AB0002DE02F0000002C0
+:103E3000014523000F660287C493000F660182606C
+:103E400002F5D7AE02012C43000F6300E02C4B00BB
+:103E50002B1201816001620B1002055EB7000F6634
+:103E600000E02AF7002ABD01856002F5B7AD000227
+:103E7000DE02F00000020200BF000F7400025E02CA
+:103E8000F00F960202DEB3000F6C0020428F000C90
+:103E9000B403BFDE02F00002028881AB000F74029F
+:103EA000845EFF000F6A02845EB3000F6A0282DE46
+:103EB000FF000F6A02822B4F000F7200682ABB00BE
+:103EC0000F740284DEAF000F6A02835EB7000F6AD0
+:103ED00000B05E870017A10002DE02F00000018240
+:103EE000E002F597AC0203DEFF000F7E028445235B
+:103EF000000F7E02012B4F000F7E0180E006F2973B
+:103F00009400025E02F00E6F0180E002F2979400CE
+:103F1000025E02F00E6F0180E002F29794028400CC
+:103F2000C7000E4803BFDE02F00E4A020400C700BD
+:103F30000F880284C56F000F9402844523000F850B
+:103F400002004203000F9400685E4B04AF940068C7
+:103F50005E4B06AF9400685E4B062F940182E0062C
+:103F6000F597AC02844523000F8B0323DE02F00F8C
+:103F70008C0183E006F597AC0180E006F29794028D
+:103F80008400C7000E4800B02AF70017A2006DDEBB
+:103F900089560E4802872B4F000E4A02005EFF0032
+:103FA0000E480287AB4F000E4A03BFDE02F00E48F8
+:103FB0000002DE02F00000020200BF0013000068F1
+:103FC0002B0B000F9B00E844655857A101BC63F719
+:103FD0001D17A2006D5E86F44F9B00E84466F44A0C
+:103FE000C2006CC465576F9D00E84467002ABB029D
+:103FF00080456F000FD10203DEB70010580183E047
+:1040000002F5B7AD0202DEB3000FA3018360062BF9
+:10401000915C00025E02F00F7602835EBB000FA689
+:1040200000E845895BF7A1006E5E8555AFBE0204CE
+:10403000DEB7000FBA00E02BB7002AED01BC600329
+:10404000000AEF00682C67000FAB00E82C67002B1C
+:104050001900B02BB70017A201856002F5B7AD02B9
+:1040600004DEFF000FB0006D5E895DCFB00184E01B
+:1040700002F7F7BF0206DEFF000FBA00E02BE702EF
+:104080000AF900B04467000B0401182BE70017A1E0
+:10409000011A2BE70017A2006E5E87000FB8006DB3
+:1040A000DE895F4FB803BFDE02F00FBA01BC6003C8
+:1040B000000AF90186E002F7F7BF02025EFF001076
+:1040C000580068AB0B00105800B02AE7000AC20085
+:1040D00002DE02F000000182E002F7F7BF02025E9A
+:1040E000FF000FC8020600C7000FC102025EFF00FA
+:1040F0000FC800E845895BF7A1006DDE85614FC6FA
+:1041000000E844656177A1006D5E85618FC800B0ED
+:104110004467000AC20002DE02F000000204DEB7BB
+:10412000000FD000E8446556CABE00682C67000F37
+:10413000CC00E82C67002B1900E02BBF002AEF0011
+:10414000B02BC30017A1006D2BBEF42FD001BC60B3
+:1041500003000AED0002DE02F000000203DEB700F9
+:104160000FD80282DEB30010580203C57300104A54
+:1041700000E844655737A1006D5E8556B05801834D
+:104180006006F5D7AE03BFDE02F0105801BC600335
+:10419000000ADF006D45871F4FDB00B04587000A2E
+:1041A000DF00E044655BF7BB00E85EEE2C2AB90156
+:1041B000836002F5D7AE0183E006F5B7AD0184E078
+:1041C00002F5B7AD01826002F7F7BF01846002F526
+:1041D000B7AD0101456F0017A101875E86F577AB8A
+:1041E00001BC6003000B0D00025E02F0130100E849
+:1041F00044655737A1006D5E855ECFE6006D5E8534
+:1042000056AFEA00E02B83002AE000B02AB3001783
+:10421000B3020680C7000FED02075EAF000FF00289
+:104220000680C7000FF20184600561AB0D03BFDE9D
+:1042300002F00FF201826006F7F7BF00B02AE70034
+:104240000AC10200C56F000FF601846006F5B7AD24
+:10425000020480C3000FF60184E00561AB0D020289
+:10426000DEBB000FFC0284DEFF000FF90206DEFF5A
+:10427000000FFC00B02BB70017A1006DDE855DCFED
+:10428000FC0182E00561AB0D00E05ECD55B7B301E6
+:10429000826002F5D7AE00B02C4B0017A100B02A07
+:1042A000F70017A2006D5E8956100302855EB70005
+:1042B000100C03BFDE02F01005006D5E8560F00E8D
+:1042C00002812C4300100C00B0440B0017A300B077
+:1042D000440F0017A200E95E8E2337A300E8DE8AB0
+:1042E0002357A200695E8B00100E0068DE8B001061
+:1042F0000E006E5E8EF6700E01826006F5D7AE007F
+:10430000025E02F0114902045EB70010230206802B
+:10431000C700101102075EAF00102300682ADB00FF
+:10432000101C00E8446556D7A201BC60371597A35E
+:10433000006D5E8AF47023006E5E895D90230184B7
+:10434000E006F5B7AD00685E8B00101C00B05E8B18
+:10435000000AAE0182E006F5D7AE006E5E896110FC
+:104360001C0182600561AB0D00E844655737A10070
+:10437000B044670017A300E85E8EF42AB60068AB6D
+:104380001708902200B02BCB0017A200E82ADAF41D
+:104390004AB601846002F7F7BF0282DEB30010580C
+:1043A0000203C57300104A00B02ACB0017A200B068
+:1043B0002AD30017A300685E8F00102D00682B0B16
+:1043C00000102D00E844655857A100E05E8EF457B8
+:1043D000A2006D5E86F4502D0181600561AB0D0277
+:1043E00081AB4F00103202005EFF00103202044524
+:1043F0002300103203A0DE02F010320183E00561D9
+:10440000AB0D0281AC4700104702862C37001058D4
+:104410000286AC37001058028080BF00105802821C
+:104420005EBB00105802822BF30010470281AC37AC
+:104430000010470280AC3700104702812C37001073
+:104440004702822C37001047028881AB00104702D8
+:1044500082AC3700104002842C370010470284AC35
+:10446000370010470283AC3700104702835EB70065
+:1044700010460204DEAF0010460281DEBB0010468B
+:104480000184E002F577AB00025E02F0113303BF56
+:10449000DE02F010580183E0022B915C020701ABB1
+:1044A00000104A0180E00209D04E00E84465573709
+:1044B000A1006D5E8555B058028101AB001050021D
+:1044C0000081AB00105202842C370010520280ACE5
+:1044D00037001052018360022B915C03BFDE02F0B3
+:1044E0001058018360022B915C00025E02F00F8184
+:1044F00002835EB70010580184E006F577AB00E058
+:104500002B47002AD103BFDE02F0111B0002DE029E
+:10451000F000000184E002F5B7AD01836002F5D739
+:10452000AE0182E002F5D7AE0182E002F7F7BF01EB
+:1045300084E002F7F7BF01BC6003000ADB01BC6046
+:1045400003000AD001BC6003000AC8018760016053
+:104550006B030002DE02F00000020200BF001089BF
+:104560000283DEFF0010920183E006F7F7BF01BC73
+:10457000600302115D00B02AB700115E018560067C
+:104580000B705B018560060BF05F0280456B0010CD
+:104590006D018B60022B915C0188600E2B515A00DB
+:1045A000682ADB00107001846006F7F7BF01BC6069
+:1045B00003000AB600025E02F0105900E844696088
+:1045C000D7A1006EDE8700307A00B02BF7000AF822
+:1045D00001BC6003000AF700682B0B00107A00B0E2
+:1045E0004467000AC100E84465564AC200B02AD3B5
+:1045F0000017A100E82B0AF42AC2028080BF001035
+:10460000800281DEBB0010840200456F0010800232
+:1046100083C57300108001BC63FF1FF7A10068C54C
+:1046200086F43084018B600E2B915C0183E002F5EF
+:10463000B7AD0184E002F577AB03BFDE02F01126CF
+:10464000018360022B915C00025E02F00F81018306
+:10465000E006F5B7AD0184E006F577AB03BFDE02F7
+:10466000F01126018D60020BF05F0188600E2B5166
+:104670005A028181AB00108E018B60062B915C0386
+:10468000BFDE02F0108F018B60022B915C0183E092
+:1046900002F5B7AD0184E002F577AB00025E02F0EF
+:1046A00010590002DE02F0000000B0446B000B065F
+:1046B0000202DEB3001097018360062B915C0002BA
+:1046C0005E02F00F76020200BF00109F0183E0023D
+:1046D000F7F7BF0203C57300109D020080BF0010F2
+:1046E0009D018B600E2B915C03BFDE02F0109E01DA
+:1046F0008B60022B915C0182E002F597AC0002DE38
+:1047000002F0000001BC600300701001BC63FF1FD9
+:10471000F0C501BC63FF1FF0CB00B040470010E5BF
+:1047200000B040470010EB01BC600300901001BCDA
+:1047300063FF1FF0C601BC63FF1FF0CC00B0404711
+:104740000010E600B040470010EC01BC600300B070
+:104750001001BC63FF1FF0C701BC63FF1FF0CD0059
+:10476000B040470010E700B040470010ED01BC60CA
+:104770000300101000B0404300180001BC63FF1F8D
+:10478000F0C800B040470010E801BC6003003010E2
+:1047900000B0404300180001BC63FF1FF0C900B027
+:1047A00040470010E901BC600300501000B04043D6
+:1047B00000180001BC63FF1FF0CA00B040470010A2
+:1047C000EA0002DE02F0000001BC60030037A20034
+:1047D00020E3FE0910FA0020E0420D90FA02804228
+:1047E000030010FA028445230010FA03915E02F0E0
+:1047F00010FA0068AB6F0010FA0282DEFF0010FAB8
+:1048000002805EFF00112F020180C7001126028284
+:10481000DEB30010FA020480C70010E700685E8B68
+:104820000010D300B02BA30017A1006EAB8AF430A8
+:10483000D30203C5730010E700682ABB0010D20042
+:10484000682ADB0010D300E8446556D7A100E82AA7
+:10485000BAF437A1006ADE8555F0E7006ADE855BB1
+:1048600050E700682B070010E70203DE530010D664
+:1048700000B02BA7000AAF03BFDE02F0112601BC77
+:10488000600302579201BC63FF1FF0C301BC6003C9
+:104890000910E301865E8A1C70E3018460061C70C7
+:1048A000E300682B0F0010DD0185E0061C70E301BA
+:1048B000BC600303978200025E02F0110401BC6336
+:1048C000FF1FF0C400B054130010E400E043915CFB
+:1048D00030E400025E02F010A001BC60030010EEA4
+:1048E00001BC63FF1FF0CE00E02B0F002AC303BF03
+:1048F000DE02F010F402835EB70010FA00025E02DE
+:10490000F000D400B05ECF0010E400682ABB0010B5
+:10491000F100B02AFB0010E40280456F0010F100A6
+:10492000E8446556D7A100E82ABAF437A100695EC9
+:10493000870010F100E05E8557D0E401BC60030100
+:10494000D78200025E02F0110403BFDE02F010F411
+:1049500000B0004700108600025E02F011980002CD
+:104960005E02F00D8D0190600A0910480184600616
+:10497000F597AC01BC61330070800002DE02F000EC
+:104980000002805EFF0010FF0281DEBB0010FF020C
+:104990000180C7001126020480C700112601806033
+:1049A00002F7F7BF0280C28F0011270201DEBB00B1
+:1049B000112701BC60030017A203BFDE02F010BD87
+:1049C00001BC63FF1FF0C001BC63FF1FF0C1028583
+:1049D000DEFF00111400685E4B06310D00B02B574E
+:1049E0000017A1006DAB0EF4311401BC6003013758
+:1049F0008000B02B5B0017A1006D2B0EF4310F026D
+:104A0000812BF300110F01BC600301778001BC60B2
+:104A10000300378100025E02F000AF01D2DE0AA07F
+:104A200030E000B0540B0010E103BFDE02F0111AB9
+:104A30000280ABF300110D01BC600301578001BC83
+:104A4000600300178100025E02F000AF00B054075F
+:104A50000010E000885E0B0070E10002DE02F00052
+:104A60000000682B130011260204DEAF001126009F
+:104A7000E844655897A4006E5E9155F12600885E63
+:104A8000930037A4006D5E9155F12600025E02F09E
+:104A9000115603BFDE02F0113300E844655897A4B5
+:104AA00000885E930037A400025E02F0115603BF37
+:104AB000DE02F011330284DEAF00112A0181E00230
+:104AC000F5D7AE03BFDE02F0113300682B8700116B
+:104AD0002F00E044655C2ADB00682B8B00112E0060
+:104AE000E044655B4ADB0002DE02F000000180600A
+:104AF00006F7F7BF00682B1300113300E844655830
+:104B000097A400025E02F0115601846002F597AC92
+:104B100001BC6003000AC401BC6003000ADB01BCE5
+:104B20006003000AC30104DEAF0017A101835E86A3
+:104B3000F5B7AD0284DEAF00113C018060060D9038
+:104B40006C0002DE02F00000028600C700113E0287
+:104B5000025EFF00114400B02AAF0017A302040058
+:104B6000C300114100B02ACF0017A30202DEBB0030
+:104B7000114300B02AAB0017A300E04466F46ABBFF
+:104B800000B04467000B0B0183E0022B915C02072D
+:104B900001AB0011480180E00209D04E0002DE02A4
+:104BA000F000000202DEB300114C018360062B917D
+:104BB0005C00025E02F00F760203C5730011510221
+:104BC00084DEAF0011510281DEBB00115102805E14
+:104BD000FF00115102035EB7001155018B600E2BCF
+:104BE000915C01836006F5B7AD0184E002F577AB17
+:104BF00001BC6003000AC30002DE02F0000000688E
+:104C00002B7B00115800B02B7B0017A4006D5E9128
+:104C100056515A00B02ACB0017A400882B27003722
+:104C2000A500E82B2AF4AACA00885E930037A400E6
+:104C3000E02B2AF48ACA00902B2B00AAC900B02BC3
+:104C400027000AAF0002DE02F000000286410700E2
+:104C5000116101BC60130917A100025E02F000A2FD
+:104C6000018760060337A200025E02F000A800B0D0
+:104C70005E870017A100B05E870017A100B05E87B5
+:104C80000017A101876002F457A200025E02F00043
+:104C9000A801BC60130957A100025E02F000A20146
+:104CA0008060060337A200025E02F000A800E00266
+:104CB000B30020AC01806002F457A200025E02F053
+:104CC00000A801BC60270857A100025E02F000A204
+:104CD0000068C06701F17901BC60030017A20002FF
+:104CE0005E02F000A801BC600301F7A200025E02B0
+:104CF000F000A80002DE02F0000003905E02F01156
+:104D00008D03875E02F0118D0390DE02F0118D029B
+:104D10000445230011840283C21F00118D0068A086
+:104D2000B700118100B0446700082D00E844650514
+:104D3000B7A1006E5E877D118803BFDE02F0118E81
+:104D40000286C03700118D00E0446700D7A102063B
+:104D5000403700118D006CC466F4318600025E029B
+:104D6000F00B1600025E02F0116101BC6003000846
+:104D70002D00025E02F00AD803BFDE02F00004013B
+:104D8000BC600300082D0002DE02F0000002804239
+:104D900003001197028545230011960285DEB700B6
+:104DA00011940185E006F5B7AD00E0446B002B21BE
+:104DB000006CC46964319700025E02F011610185E4
+:104DC000E002F5B7AD0002DE02F00000010C814305
+:104DD0000017A101BC600300508A00685E07001143
+:104DE0009C00685E8700119C00685E070011A401AA
+:104DF00090422AA1308A00685E070031A4019042E7
+:104E00002AA0108A0109DE030017A2018F5E8A1111
+:104E1000508A00685E8B0011A40191E00E11508A47
+:104E20000002DE02F000000109DE030017A400E02A
+:104E30005A06F497A500905E96F497A50203DE0348
+:104E40000011AC0282DE030011AC01BC61EF085717
+:104E5000A60080DE96F4D7A50116DE870017A30012
+:104E6000885E870077A100E15E8702D7A100E0DEBF
+:104E70008F0017A301BC60030017A2020E5E03009F
+:104E800011B301BC60030037A200905E96F457A5F1
+:104E90000080DE96F437A100E141B7FFF7A600E1FC
+:104EA000DE8701F7A10080DE96F477A300E1DE86BD
+:104EB0000DB7A100E0DE8F0017A3017A5E86F477BC
+:104EC000A100885E86F457A100B05E870017A20299
+:104ED00087DE030011C000885E870057A103BFDE94
+:104EE00002F011CD02875E030011C701BC639B0C69
+:104EF000D7A50080DE86F4B7A100E141B7FFF7A592
+:104F000000E0DE870017A100885E870057A103BF7D
+:104F1000DE02F011CD00885E870057A101BC639BC3
+:104F20000CF7A50080DE86F4B7A101BC6203001770
+:104F3000A500E141B6F4B7A500E0DE870017A100A7
+:104F4000E05E8400D7A10002DE02F0000002002033
+:104F50000F0000040282DE530011D50188600204B4
+:104F6000902400E020AEF3082B00E820AAF3082AE2
+:104F700003BFDE02F0096201B8601604902401BC90
+:104F8000600301D02503055E02F011E70287C037F8
+:104F9000000A860386DE02F00A8700025E02F00F36
+:104FA0009500025E02F0117A035CDE02F011D70078
+:104FB000D8409B0117A100E05E8702379800A85EE9
+:104FC000630077980102DE530017A10182E002F22C
+:104FD00097940188DE85006803006EA0AAF311E7AC
+:104FE00000E85E6301D02501B8600604902403BF89
+:104FF000DE02F000020181600500680301B8600A6A
+:1050000004902403BFDE02F0000202285E87001134
+:10501000FD00B041930017A400E0419300706401CB
+:105020000A5E870017A200E84192F4506301185EFF
+:10503000870017A100E86042F437A200885602F406
+:1050400036000068418EF491F900E8418F0030632A
+:1050500000E8419300306400685E8B0211F100901B
+:105060005602F457A300B05806F4760103BFDE02DF
+:10507000F011F100684192F491FD00E84193003095
+:105080006401BC600300160003BFDE02F011F900EA
+:10509000B05E870017A10002DE02F0000001806010
+:1050A0000286143000B050CB0010650138508300E8
+:1050B00017A10068DE3B06320500E05A3300368C4B
+:1050C000006EDA32F4200400B05A0B0017A200E0A0
+:1050D00001F700207D00E001D2F4407401BC63FFC1
+:1050E0001FF7A300B050CF001064006EDA32F43224
+:1050F0000C00B05A370017A300B0581300178201F4
+:10510000BC600300160401BC601B09D7B60102D0C5
+:10511000C70017A100E04196F4306500E050CB00D5
+:10512000D06401BC60030017B401BC6003001780A9
+:1051300001BC6003003781018760040310A0009068
+:1051400052330097A400E0418701B7B500685ED2F2
+:10515000F0523300E05EDAF690630020D802F032BD
+:1051600027020250C700122D009056030097A1009D
+:10517000E85E86F497A1019E6002F437A1006DDE1F
+:105180008708122D010A5E870017A201DA6002F477
+:1051900037A100E05ED6F4506300886006F437A1C2
+:1051A00000205602F4322D00B05802F0360000E024
+:1051B0005A2B00368A006ADED2F472290068DED2E9
+:1051C000F0122E00E05E0300378000685E030032BC
+:1051D0002E0186E0040310A003BFDE02F0122E00B1
+:1051E0006ADED2F4722900E05ED30037B400D05EEC
+:1051F0000700378102985ED300121800E041930047
+:10520000306403BFDE02F0121800685E0300000481
+:1052100003BFDE02F005AB0282D0C700123D00B032
+:105220002A4F0017A101B82A4AF43684010250130C
+:10523000001685013C50830017A100B050A700174D
+:10524000A4006D5A32F432460182E00686343102FF
+:1052500088502B00124200B05A330017A1019E5E05
+:105260008684F427018360068634310002DE02F072
+:10527000000000B050730017A101B8506EF43684DE
+:105280000106D00700168500B050AB0017A400D06F
+:105290006006C0978000E0419700D7B5010A581317
+:1052A0000017A100E05ED6F437B500B0580F00102B
+:1052B00063011656030017810068D81300125B01C2
+:1052C0001400630017A10068DE87001251008801F6
+:1052D0003B01168003BFDE02F012560068DE870035
+:1052E000725400A0013BE0168003BFDE02F01256AC
+:1052F00000E05E870970620088540301168000E8B0
+:105300005A0330168001BC600300168101BC6003A3
+:1053100000168201BC600300168303BFDE02F01298
+:105320006000E0418EC09063006EC18EC0326000AC
+:10533000E8418EC0306300E858030037A100E04127
+:105340008EF43063013850A30017A500685813038A
+:10535000F27B0068418EC0527B006DDA0AF4B27BAA
+:10536000011656030017A10068DE86F0327B015853
+:1053700056030017A100E05E870DD7A200B05ED7EC
+:105380000010620020DE02A0127200E05E86D037BC
+:10539000A300E05E8ED077A3006D5A02F4527B002A
+:1053A0006E5E8EF4927B00E86002F4368300B05E9D
+:1053B0008F00168100A05A0F00768300E05A0B0080
+:1053C000368200E85A02F4568000D05E030037802F
+:1053D00000E0581300360400E0418F00306302986B
+:1053E000581300127800E05ED70037B5006EC18E0A
+:1053F000C0326100B0580300106303BFDE02F01238
+:105400006100B058130017A10068DA3700127E005F
+:10541000B05E8700168D006DDE86D1B28000B05E72
+:105420008700168D0002DE02F0000001BC60030060
+:1054300017A1018760040310A001BC60030990B5A7
+:1054400000B0006300F0B401BC60570490B601BC2A
+:1054500060030090B500B0006300B0B400B042D368
+:105460000018000317DE02F012890397DE02F01223
+:105470008A00B02A4B00142F018EE00C0310A0000C
+:105480006DDE02D1B29000E85A36F0168D03BFDE11
+:1054900002F0129201BC600300168C01BC60030094
+:1054A000168D006E5A3AF0129501BC600300168EFC
+:1054B00003BFDE02F0129600E85A3AF0168E00B0F2
+:1054C00058070017A100E0580EF01603006ED80E22
+:1054D000F4329C00E85E86C017A100E8580EF4364E
+:1054E0000300E8580F00360301185E030017A100FF
+:1054F0006DDE030212A400E86042F437A200905A65
+:105500001AF4368600885A1EF457A200905A1EF4E8
+:10551000368700B05A1AF4568603BFDE02F012A690
+:1055200000905A1EF4368601BC6003001687000204
+:10553000DE02F000000158600300102A01B8600A82
+:1055400004902401BC60030290040189E0020D90E4
+:105550006C0002DE02F000000200DE530012D101F6
+:10556000BC601309B7A100025E02F000A201A560B1
+:10557000020337A20199E002F457A200025E02F092
+:1055800000A801BC60130997A100025E02F000A20E
+:1055900001A4607E0337A20199E03EF457A2000205
+:1055A0005E02F000A801BC601316F7A100025E02C3
+:1055B000F000A201B460020337A200025E02F00014
+:1055C000A801BC60131637A100025E02F000A20120
+:1055D00086E0020337A201856002F457A200025E52
+:1055E00002F000A801BC60131617A100025E02F0D1
+:1055F00000A20181E0060337A20185E006F457A26C
+:1056000001836006F457A200025E02F000A801BC0C
+:1056100060131F57A100025E02F000A20181E002A8
+:105620000337A2028600C70012CB0181E0060337D0
+:10563000A200025E02F000A801BC60131F37A100A7
+:10564000025E02F000A20181E0060337A200025EC2
+:1056500002F000A80002DE02F0000001BC601309A5
+:1056600097A100025E02F000A201A460020337A22B
+:105670000199E002F457A201886002F457A20002E7
+:105680005E02F000A801BC60131617A100025E02C2
+:10569000F000A20181E0020337A20185E002F45785
+:1056A000A201836002F457A200025E02F000A80289
+:1056B0000600C70012E201BC60131F37A100025EA2
+:1056C00002F000A20181E0020337A200025E02F0B4
+:1056D00000A80002DE02F000000200DE530012D13A
+:1056E00001BC601309B7A100025E02F000A20187AD
+:1056F00060020337A20181E002F457A2018860062C
+:10570000F457A200025E02F000A801BC60130997E2
+:10571000A100025E02F000A2020400C70012EF0125
+:1057200088600E0337A203BFDE02F012F10186602B
+:10573000060337A20181E006F457A200025E02F0E0
+:1057400000A803BFDE02F012C60068DE930012F765
+:1057500000E05E030057A201095E8B0017A103BFA2
+:10576000DE02F012FF0068DE930032FB01105E03E0
+:105770000017A200E05E8B0097A103BFDE02F012CB
+:10578000FF01305E030017A200E05E8B0197A100CD
+:105790006D5E870592FF01BC60030597A10002DEE4
+:1057A00002F000000200456F00130B02872C0F006F
+:1057B000130B01BC60130217A100025E02F000A2ED
+:1057C0000200C06700130B0287AC0F00130801082A
+:1057D0004067000B030187E005606B0301886006EA
+:1057E0000337A200025E02F000A801876005606B2B
+:1057F000030002DE02F0000000682BEB0013110032
+:10580000B02C130017A100E05E8560B7A1006BDE2D
+:10581000862333110186E006F7F7BF0002DE02F0AF
+:10582000000000B05E8F00106400B05E870017A318
+:1058300000B05E8B00106500B05A030017A100682D
+:10584000419300131A00025E02F000A200B040670C
+:1058500000160100E0419300506400B05A070017A1
+:10586000A200025E02F000A800E04197005065002F
+:10587000E85E8F0037A30068DE8F0013150002DE9C
+:1058800002F0000000B05E8F00106400B05E870080
+:1058900017A300B05E8B00106500B05A030017809C
+:1058A0000068419300132800025E02F00E3F00B032
+:1058B0005E0700160100E0419300506400B05A07F3
+:1058C00000178100025E02F00E4400E04197005094
+:1058D0006500E85E8F0037A30068DE8F00132300A9
+:1058E00002DE02F00000020200BF0001880203C5D0
+:1058F000730001B1000000000000000057860000A6
+:10590000A5C1E142055AC359DC0175513E5B2349EB
+:105910004728676945005E55F8F5C97D420AB30915
+:1059200001BD32080100343333363261322D726FDB
+:105930006D6C2F7364696F2D672D706E6F2D706B9A
+:105940007466696C7465722D6B656570616C6976DF
+:10595000652D776170692D776D652D7032702056D9
+:10596000657273696F6E3A20352E39302E313935B4
+:105970002E3839204352433A20626431653365350D
+:105980006120446174653A204D6F6E2032303133AE
+:105990002D30342D32322031373A32343A343420FB
+:0559A0004353547D009B
+:00000001FF
diff --git a/firmware/ap6210/fw_bcm40181a2_apsta.bin.ihex b/firmware/ap6210/fw_bcm40181a2_apsta.bin.ihex
new file mode 100644
index 0000000..df14f32
--- /dev/null
+++ b/firmware/ap6210/fw_bcm40181a2_apsta.bin.ihex
@@ -0,0 +1,12890 @@
+:100000000000000019A40000DDA20000DDA2000035
+:10001000DDA20000DDA20000DDA20000DDA20000E4
+:10002000DDA20000DDA20000DDA20000DDA20000D4
+:10003000DDA20000DDA20000DDA20000DDA20000C4
+:10004000DDA20000DDA20000DDA20000DDA20000B4
+:10005000DDA20000DDA20000DDA20000DDA20000A4
+:10006000DDA20000DDA20000DDA20000DDA2000094
+:10007000DDA20000DDA20000DDA20000DDA2000084
+:100080000048004719A40000000000000000000024
+:100090000000000000000000000000000000000060
+:1000A0000000000000000000000000000000000050
+:1000B0000000000000000000000000000000000040
+:1000C0000000000000000000000000000000000030
+:1000D0000000000000000000000000000000000020
+:1000E0000000000000000000000000000000000010
+:1000F0000000000000000000000000000000000000
+:10010000D11E8000B5228000BD248000491F8000E0
+:10011000F9218000BDF00000F1208000D120800096
+:10012000594880006948800015648000E1628000C1
+:10013000296280003D6580008D628000C56280007C
+:10014000596380005D6580007D6380009D63800051
+:100150000D668000A961800061618000756080008B
+:1001600095608000DD6380009D65800029668000C9
+:10017000FD618000B96580001D618000F16580002F
+:100180009D6680006D658000916C8000CD6B800065
+:10019000316C80008D6B8000556C8000AD6A8000F2
+:1001A000C16A8000D56A8000496B80001D6A8000AA
+:1001B000FD6A8000AD688000C1698000D168800060
+:1001C000356B8000B1698000D5A80000D166800041
+:1001D000E16780008D678000CD6780009D688000AA
+:1001E000ED678000BD678000A1678000ED6680003C
+:1001F00009678000616780004D4880001D488000CD
+:1002000085988000DD96800051948000B19B80002D
+:100210003994800005988000199880002D988000FE
+:10022000C59B8000D19A8000899D8000D193800079
+:10023000D9918000ED9A8000892800007DF10000AE
+:1002400059290000A5F10000519B80009D29000064
+:1002500049A9800099988000D529000031A8800024
+:1002600005A7800021A28000BD938000DD9380005F
+:10027000199E80007D93800045988000E59B80005A
+:100280006DA68000C19C8000C59F8000A19D80005C
+:10029000F598800069F10000DD2A000029AA80009D
+:1002A000B9A9800075AA8000E1A9800039AA800060
+:1002B0008DAA80005DAA80000DAA8000C5A98000DB
+:1002C0009DA98000A90C8000850D8000C1068000DA
+:1002D00029088000694680004D468000D94480008E
+:1002E0004146800021448000F54380001544800091
+:1002F000E1438000E1428000854680007544800033
+:100300002D448000A9428000F9428000CD43800046
+:10031000B9458000F544800039458000090080001F
+:100320003D00800049018000D10480000D04800060
+:10033000910380004D038000E503800035038000B9
+:100340006503800029028000CD02800051028000F8
+:1003500085028000F5028000950680003906800045
+:100360008105800005068000FD048000690F800083
+:100370002516800015168000451380001513800097
+:100380002513800009138000351380000D1E8000A6
+:10039000F91D8000291D80001D1C8000391C800073
+:1003A0003116800059138000F1F801009513800088
+:1003B000B91C8000F11B8000211E8000751D80008B
+:1003C000E1EA00003D1D80000D1B8000E910800067
+:1003D000790F8000A9168000311480002D11800053
+:1003E000A51E8000B11E8000BD1E8000692B80000C
+:1003F000AD28800011298000892B8000FD2B800012
+:10040000E128800065288000B52C8000912C8000B8
+:100410001D2B8000752D8000252C80004D30800024
+:10042000DD2D80005927800031318000D9F2000095
+:100430008D268000C5268000E5248000FD268000F2
+:1004400021258000B12A80006525800025288000B4
+:100450006129800041298000D92980009D298000E0
+:1004600081298000893080004D2E8000B12B8000D2
+:10047000312C8000E12C8000613280002D32800020
+:10048000C93380004D368000693A8000B535800060
+:10049000F9348000A93480003D3380009D33800012
+:1004A000013480003536800031388000353A8000D4
+:1004B000213A8000AD3280000D338000DD328000B3
+:1004C000953A8000D937800099368000193780002E
+:1004D000593880004938800019398000313D80004A
+:1004E000D53A8000C93C8000E13B8000513D80004E
+:1004F000D93D8000AD3E8000593F80009941800089
+:1005000041478000CD5B8000895380002D4D8000E5
+:10051000A94C8000E14D8000E94F8000B14F800080
+:10052000C94E80008D4E8000F15180005D528000E8
+:10053000D15180002D52800001528000C94F8000AF
+:10054000594C80006D4C8000455B8000395680001E
+:10055000155A8000C9588000315A800081578000A8
+:10056000F95980001D568000AD55800091558000DE
+:100570004D5A80002D558000714B800071548000D1
+:1005800009548000F54D80001D4C8000F94B80001F
+:10059000094C8000114E80001558800061EC00006D
+:1005A0002D508000E5588000555680007D5A80000F
+:1005B000054F8000354E8000D9558000515880008D
+:1005C0009D57800059518000614D8000B1488000E6
+:1005D0005D5B800081528000494C800049EF000043
+:1005E000F15B8000E55C8000E15F8000A55E80003B
+:1005F0007D5E80008D5C8000015C8000A15F8000DA
+:10060000895D800005608000395D8000D15E8000DA
+:10061000495E8000ED6C8000656D8000DD6D8000BE
+:100620000D6D8000296D8000896D8000F96C80005F
+:10063000D96C80003D6E8000616F8000756E800017
+:10064000056E8000A974800055758000D574800007
+:1006500005748000D17C8000457D8000757C800021
+:10066000117E8000897E8000E97E8000917D80007F
+:100670003D7E8000517F8000A581800065848000E0
+:10068000418480008D8380006583800035858000F3
+:10069000E58480009D848000218580007584800031
+:1006A000BD8380005D858000BD858000158F800042
+:1006B000918D8000D58980001986800019AB80005B
+:1006C0005DAC8000A1AA8000B5AB80005DAB80006E
+:1006D000FDB080007DB1800065B080006DAE80000F
+:1006E00085AE8000EDAD800041AF80001DAE800082
+:1006F00031B180003DB18000B9AE8000F5B180001D
+:1007000079B08000FDAD800009B180008DB080001F
+:1007100049B1800069B180004DAE80003DAE8000DF
+:1007200095AE800029B38000C9AE8000CDAF8000B7
+:10073000E5AF800025B080008DAF8000B5B28000AD
+:10074000FDB2800019B38000EDB080005DAE800086
+:100750002DAE800029B28000A9B08000A1B1800038
+:1007600005B2800039B28000A9AE80007DAF800064
+:10077000ADB38000A9BD80009DC1800025C7800069
+:10078000DDC8800065CA8000E1CB8000DDCE80003E
+:1007900019CE800099CE800015CF80000531000071
+:1007A0000DD88000DDD7800091D78000FD2D00009E
+:1007B000B92E000069D880007DCF800045D9800027
+:1007C000D12F000099D18000C5EB0000F9E0800036
+:1007D00071F5800035310000D1DE8000C5F60000E3
+:1007E00009EA8000A1E480007DF50000E1EC8000D2
+:1007F00011E3800039EA800039E3800099E380004A
+:1008000029DF80003DF70000D9F50000ADF70000BA
+:100810006DF80000B5F80000BDEB8000B5310000B8
+:100820003532000051F70000C9F7000005F700005D
+:10083000E1E18000A9E98000B5F6000031F6000092
+:10084000EDF58000D90081009DF68000C5F780009D
+:1008500085FF800045018100D50281004D038100A4
+:10086000E50081007DF6800081F78000D5F58000ED
+:1008700051F9800031FB8000F1F68000F9F580002D
+:1008800041FF8000D9F98000DDFC8000A9F78000DD
+:100890002DB6000059FB80008DF78000A5F980007F
+:1008A0008DF9800029F68000A1F880005DF78000B6
+:1008B00065F6800095FD8000A1B70000F50281007B
+:1008C0002D028100890181000501810091B800009D
+:1008D00099FF800019F7800089F68000C1F680003A
+:1008E00009B7000085F5800005F78000DDF680007F
+:1008F000B1F68000AD6A8100BD6A8100DD2F810004
+:10090000E1578100F56D8200A98D820009258200E2
+:10091000196E820001AA81005D608200A537820005
+:10092000ED69810079598200E55882001D598200E5
+:10093000FD6D8100493A810041BC8200E95A820084
+:10094000CD608100D59681001D6181002961810003
+:1009500089BF81001DAB8100A93282000D330000E8
+:100960002569810005A6810021AD820029588100FA
+:10097000BD3E8100A540810035958100599B8100D5
+:100980003D3682001D4582000928810099A0810022
+:10099000D1288100E93B81008D288100416E8200D1
+:1009A000859B8100295D81006D398200FD398200BF
+:1009B000253A820095698100C97A810091578100AA
+:1009C0005D57810075308200852F82003557810088
+:1009D000D12F82002157810049578100F5288100DD
+:1009E00095A8820009EC000089D38100D56B8100B5
+:1009F0005959810075598100F55A820005AD810071
+:100A0000F1D2810039378100ED718100C5968100F6
+:100A10008957820091618200CD618200A9588100CE
+:100A20001D2782004543820001448200156A81002F
+:100A3000614A8100ED4E810071228200055A8100D9
+:100A40004D8A81007549810071248200B14981007D
+:100A5000B144810075AC8200292B8200595281007B
+:100A6000E12A8200B529820071A7810035A78100A3
+:100A700001D48100F5BE810055B48100D16A8200A5
+:100A8000D19C81009D9C8100959B8100B59D81003A
+:100A9000459D8100C59D81006170820009358100FE
+:100AA000A1AB82008DAB820075AB8200F193810017
+:100AB0009968810015D7810071C182007D2B81006A
+:100AC000E92F81000DB6810025BD82008D4F810088
+:100AD0000D5081008543820031D78100B1BD820075
+:100AE00095C182005DB38200DD3400008DD18100AC
+:100AF000A9368100E9BC820029378100E9368100EE
+:100B0000A1D68100A53B81006DAB810041B0810081
+:100B100045AE8100C9F1000041BD820095BE820052
+:100B2000CD2E82009D6B8100CD458200453981002C
+:100B3000353B8100BD3A8100F1D58100419F8100A4
+:100B4000119F810071A48200ADD58100C130810068
+:100B5000A13982004D618100995B8100A5728100FD
+:100B600089DA810061BF81006157820081218200A2
+:100B7000A9218200D1AD820009BC8200B5A181000B
+:100B80009DCA8100B92F8200D9BB8200113082003A
+:100B90007DAD8200CDA4810099A48100CDAB8200FF
+:100BA00015AB8200C1AA8200B998810081A581009D
+:100BB000D9D08100A9CF8100E93B8200EDCF81002F
+:100BC00065D1810079D1810051D0810065D081004B
+:100BD000E521820011228200D1350000FD4900008C
+:100BE000FD9C81009145820055AE820041B4810098
+:100BF00095BD8100F18A8200098B820079D981003C
+:100C00007D618200CDA4820041918100A13F8200DC
+:100C10003594820049948200898982005DC18200F6
+:100C2000F1C18200D13B8200D5958200E560810050
+:100C30000920820015F20000BD3B820075A18200F0
+:100C400025A58200253B8200E93A8200753A8200A0
+:100C5000F1308200B130820071D781004599820065
+:100C600091D7810089948200DDC18200A96A820047
+:100C7000256B8200C944810029458100596B8100A0
+:100C800059498100EDAA810069618200AD2482008A
+:100C900005368100D535810079D08100A5D081004D
+:100CA000715C8100E1AD8100EDD0810049C9810016
+:100CB0004DD88100893D82004920820065968200DE
+:100CC000F925820089CF8100856A82001593820010
+:100CD0002D5D8200E9CA81006D4082006130820092
+:100CE00015488200313C810061D68100114E81009F
+:100CF0000129810041A1810015A681000999820086
+:100D0000E5C98100B1D7810035C08200294A810040
+:100D100041AD8100EDBE82002DBE820005BE820085
+:100D200079BE820055328100A5958100B1598100BC
+:100D3000E54781009152810015638100956481002F
+:100D40008D668100592C8100392C8100212E810073
+:100D500065358200D5578200352B8200996082006C
+:100D6000016182001D4082001D2082001DD881008B
+:100D7000A9AC8200F1AB8200F52B820041AE82006B
+:100D8000A9EC0000356A810009AE8200696D82001D
+:100D9000098C8100D58B8100116F810081908100C9
+:100DA000296C8200DDA18100E92B8100552F820092
+:100DB000398C8100A55A8200355C820045BB8200D7
+:100DC00091BE81002D6E8100115C8200258A810018
+:100DD0004D93810089388200D5378200555A8100B1
+:100DE000013882008D038100E9208200E13E82000B
+:100DF000914581002D6D81000D58820021478200B0
+:100E0000FDCE810011CA81005936820051CB81008C
+:100E100025CB8100912E81002D2F8100B93A8200CF
+:100E2000CDE80000DDA9810031D48100D1B382007A
+:100E3000ADA98100D53882008DD88100555E820031
+:100E4000719A81001541820035DA810019258200EE
+:100E50006926820035358100E93600003D71810048
+:100E6000012D810009A282000D238200FD71810005
+:100E7000D960820051728100416182004528810061
+:100E8000C12382008D6C81006D2382009547810013
+:100E9000B9D98100B534810075C98100F134810070
+:100EA0002DBF810059AF8200D93C8100494F81009C
+:100EB000E5AB810009F000007931810005958200E1
+:100EC0006D638200DD938200A56682000DC88100FB
+:100ED000095E81007D758100156281009159810054
+:100EE000D575810011498100C1488100B9BF8100D9
+:100EF000A5458200F5598200F1A9820041A6820031
+:100F000039588200BD428200BDA782004D22820076
+:100F100071A78200A5A78200E15C8100ED418200FB
+:100F2000D1A78200D1688100B5CC810015AF8200C5
+:100F300095418100E1C8810089AA8100E99681007C
+:100F40007D2F8100C548000049428200594482003B
+:100F5000D1E80000313182006149820051F2000085
+:100F60000DA58100095E8200253E8200CDCD810065
+:100F700029B382002151810045B18200A91D820060
+:100F800079BC8200D1568100599D8100999D8100D4
+:100F9000191C8200513F82001D308100C9BD8100B3
+:100FA00015388100794A8100DD9B8100199E8100FE
+:100FB00069618100896E8100B5708100D132820043
+:100FC000F1578100A93382009D5A81003D3582008E
+:100FD00089338200D96E810045708100FD618100F6
+:100FE000594B81000D9C8100558B8200F18E82004F
+:100FF000E59A8100BD35820049368100291F8200B3
+:10100000655C82001DEF0000516F8100299B81000B
+:10101000A56D8100B5A28200E1AF8200A9568200D1
+:10102000894481003D578200E16F8200016F820098
+:10103000DD728200E53E810095518100FDD4810082
+:10104000F5BC810081B48100F199810019318100E2
+:10105000358A8200DDDA8100413D81002D3E81002C
+:10106000E9898200C1D48100FD8D820099B681009A
+:10107000BDA781003D9F82005D0381006D928200CB
+:10108000218B8200599A8100ED278100ED94820026
+:10109000FD8A81009D8A8100416B8100E16F8100A2
+:1010A0005D468200A19482009D898200C9928200DF
+:1010B00079998100B1908200219182001D348100D4
+:1010C00099B28200DD6A82008DC9810059278200B1
+:1010D000B9EC0000D9908100A56B82006D3C8200C4
+:1010E000E56D820005C28200C96A8100ED4582007B
+:1010F000816B8100353F8200FD90820071BC8100D0
+:10110000F16B81003D4E8200514A82003DA2810078
+:10111000F1E8000079738200B97E8200698882005C
+:10112000695A8200DD2E810015138200117381003F
+:10113000698082009D9181005D8B8100816C8200BD
+:101140008D8F81004D8F810009888100BD6D8200E7
+:10115000018E81001D5E820091718100C127810096
+:10116000797582002DBE81002D5B8200E9A5820089
+:10117000B5728200FD5C0000217D82004D808200FE
+:101180008D7F820001A08100ED7F82002D418100D2
+:10119000F98481006185820045728200F9548100E2
+:1011A000692B820069518100C5558100315681004B
+:1011B000A1A6810071508100392A8200615381000B
+:1011C000C5738100F5630000F1978100A99B810040
+:1011D000FD3B820025A08200DD398100715D810028
+:1011E000D1EE00004995810009CC810021A3820045
+:1011F00045AA8100AD818200916782002962820048
+:101200007D708200E12F8200E903810081DB810093
+:10121000952482006989820089C38200C5C4820046
+:10122000F1F20000B1EB820009CB82000DCC82000C
+:1012300059EB820061E9820015F18200E9CD82005C
+:1012400045DF820009F182008DF782008DCA82009D
+:1012500089F38200D5CA8200A1098300C9F7820000
+:10126000FDEF820099F8820025F9820039FA8200A8
+:1012700089ED820069810000ADE5820065DA8200B7
+:101280007DC582002DE6820065EE820031E4820099
+:10129000E5F182009DC8820055F3820089EF0000CD
+:1012A00061C78200CDE182006DE18200A5E282008B
+:1012B00059DF820029F4820009C7820055EF8200BD
+:1012C000E9EC8200E9DB8200BDDD8200E1C582003D
+:1012D0004DE5820005E08200A5F982000DC582007F
+:1012E00039820000D18400008D85000091E68200E3
+:1012F000BDCC8200FDE982008DD182002DF18200FB
+:101300002DF7820095FB820069CE8200A1F0820059
+:10131000D5F08200F5CC820059CB820081D98200C1
+:1013200045C58200FDCB820025CB8200BDEB82004B
+:101330001DDB820015CD820071860000CDE68200A3
+:101340004DCF82009DCB8200450C8300E50D8300CC
+:10135000590E8300410E8300010B83004D0A830068
+:10136000D10D8300310C8300590C8300710A830076
+:10137000650E8300F10D8300410B8300A11E8300E5
+:10138000B11E8300012B8300F54E8300112B8300D7
+:10139000B127830099238300014A8300ED4983002C
+:1013A000FD478300CD4C8300BD4C8300714C83000E
+:1013B000D52783004D25830095258300E14C8300CC
+:1013C000414C8300A1EC000065118300E1448300DF
+:1013D00021288300BD2883007929830065288300A4
+:1013E000652B830041458300D5298300491D830077
+:1013F000A12A83005D30830051488300E5488300C3
+:1014000029488300F5238300114A8300793483003F
+:1014100091188300A5338300ED3483001D118300F0
+:101420009D4E8300954D8300B51A8300614783006C
+:101430001D4D8300ED1083000D458300C11E830008
+:1014400001208300E9218300F1258300F91D830039
+:1014500061EE0000B52B830049108300C10F8300AB
+:1014600021248300A5248300B94A8300B52F83007B
+:10147000C1458300FD1C8300711D8300F5188300A6
+:1014800059198300F1198300F9E90000492A830002
+:1014900085890000B957830029578300654F830071
+:1014A00001608300E559830039518300F54F8300C3
+:1014B000555483001D5E83002152830065598300CB
+:1014C00079508300714F8300095983003D63830085
+:1014D000C5578300815C8300B15B8300DD538300CB
+:1014E000115383009D4F830029508300254F8300B3
+:1014F000D5588300CD62830039608300F95C830096
+:1015000069F200005D5F83002D548300DD5083008D
+:1015100039578300A555830091638300A16283003E
+:10152000C15D83002D5E8300455F8300A151830070
+:10153000D58F0000195B83006D5A8300A956830084
+:10154000A5508300095783000D748300DD63830079
+:10155000297A830001668300B9B28300D5A783008E
+:101560007D848300819383005DB38300A193830016
+:10157000E9938300C1E90000BD90000035910000AF
+:10158000717A83005D67830051668300CD708300AC
+:1015900055718300DD7483008DAA830051A88300F8
+:1015A000A9B183009D918300D18483008992830037
+:1015B00061848300AD77830081818300158283007D
+:1015C000B1808300E5B583006D7E8300B57983002B
+:1015D00091910000916E8300758F83005587830081
+:1015E000A1ED00001996830025678300C188830060
+:1015F000D98F8300F5AC8300E97783009D6D83006C
+:10160000A1A78300FD998300C9A48300619600000F
+:10161000558B8300E58A8300CD6A8300F5868300BD
+:10162000596A8300B9AA83001566830051B283000A
+:101630009DB38300D9B6830059B1830091828300A2
+:10164000D5B0830081868300C97A83000585830035
+:10165000797C83008965830055A58300C9AF830029
+:10166000A1EF00007999830091898300C5B58300BB
+:101670000DB8830099D483002DC083009DC28300E0
+:10168000ADC38300A1C68300B1C68300C5C2830079
+:10169000A9D0830055BF8300F9CF830029BF830001
+:1016A000C5E18300C1C0830095C083004DD883008D
+:1016B0000DD7830015D88300F1D7830079BD83004F
+:1016C000A1E1830035C28300C5E08300DDE0830033
+:1016D000C5DC830099DA830001DA83004DB883000A
+:1016E00075C0830019C28300F9C983003DD6830009
+:1016F00015BE8300C9D683005DBA830029D6830056
+:1017000031B9830035BC83009DD883005DDC830044
+:1017100029C18300A9C28300E5C0830025DB8300C3
+:1017200075C283001DD083005DBC830061C6830049
+:10173000D5C2830005BC830001C98300B5C88300FE
+:10174000EDC8830055D6830015D98300A5D1830049
+:10175000F1D5830001D9830081B8830089E083003B
+:10176000E1BC8300A5DB8300EDE1830071C1830050
+:10177000E9B783006DC783008DC183001DC8830056
+:10178000B5D1830071DC8300E1C18300A9C183006E
+:1017900019DC830039D883004DCB8300A5B78300C3
+:1017A00069CB83008DC98300C9D48300B59700003D
+:1017B00099D68300E5DC83004DD483001DC38300EC
+:1017C00021DD830045D983007DD383003DD2830092
+:1017D00041DA8300CDD88300D9BF830095BD830053
+:1017E000EDBD830051C083002DB8830049BB830049
+:1017F00031BB8300CDDA8300D5D0830049CA830092
+:101800009DD5830081BF8300D5CF83003DC9830070
+:10181000DDD18300B9D7830025C78300BDC3830012
+:101820005DBE830021E18300F9E0830071B983008C
+:101830008DE1830025D9830049D78300DDDB830058
+:10184000A9B9830085BA83001DF1000059EB83001C
+:10185000C5E7830041E2830025E283006DF5830044
+:1018600065EB830085F2830089F78300B1F2830082
+:10187000A9F58300AD008400E100840019FD830018
+:1018800035EE8300FDF383003DEC830089FB83008C
+:10189000B9FA830021F98300F1FA8300D9F88300B3
+:1018A000D9F9830031008400C5FE830049E7830035
+:1018B000050084004DFF83006DF3830059FE830013
+:1018C00001FE830025EB83000DEB830031018400D2
+:1018D00035FD830081EB830059FD830011F88300FF
+:1018E000FDF78300C5ED8300ADED8300A101840009
+:1018F000E9E78300B1F38300DDF2830025F3830081
+:10190000F9E68300E5E2830071ED0000A5E98300BC
+:101910008DF5830051EE830079F8830071E2830036
+:10192000F1E8830045E6830099F783006DEE8300BC
+:1019300041F48300B9EB830075E78300B1E88300CD
+:10194000DDA0000061F1830035F2000089EE830024
+:10195000E9A10000FDE58300A9FD830085ED0000FD
+:10196000B5FB8300F1F183002D108400E1158400A4
+:10197000B1198400C5158400D90F8400CD218400DD
+:10198000491E84004D1F8400E1128400ED0884008C
+:10199000F10184002D0F8400ED238400F51E8400E6
+:1019A000E520840049208400AD128400F11A8400EF
+:1019B000711F8400C9198400AD188400450B840090
+:1019C000910B84000D2484008D2384000D18840065
+:1019D000210684008D168400310384006909840087
+:1019E000FD158400E902840001028400A909840035
+:1019F0008D148400811E8400E10B8400751C84001A
+:101A0000AD0A840049108400712084000121840003
+:101A1000850A8400291D840045078400390C840050
+:101A200029198400551E840089038400E51D840063
+:101A30002125840049138400291A840055ED0000F3
+:101A4000ED12840045068400010D84008943840062
+:101A50006D2A8400014D84001528840069288400C3
+:101A600021D7000009408400112C8400F92784004C
+:101A7000912D8400794C84008934840019338400CA
+:101A80006D2F8400C92D8400F12E84007D2E8400EA
+:101A900065258400DD348400FD2584001929840037
+:101AA000B5408400D944840079298400B92B84008E
+:101AB0003D45840095328400B9288400D1388400E3
+:101AC00031488400A93084006D2C8400994384003F
+:101AD000D13284006D338400FD2F84005D45840085
+:101AE00011348400B54A840075488400C5488400D8
+:101AF000B1278400314A8400D949840059328400D6
+:101B0000014C840039388400314D840055448400F0
+:101B1000D93D840055438400513C840091398400B0
+:101B20009536840091378400F5368400E1478400BF
+:101B300015478400CD4C8400F52B84002546840095
+:101B4000E53A8400C937840049428400292A840088
+:101B5000A53F840059268400952A8400452B8400E3
+:101B6000C95D8400A95B8400A15684009556840059
+:101B700019578400E956840005578400355F8400B6
+:101B80001D628400B557840065638400ED628400A3
+:101B900021638400BD628400194E8400B95384001F
+:101BA000B15D8400B5518400D55F8400F95584008F
+:101BB0006560840059538400E5538400E94D840036
+:101BC000DD518400E15F84008D5384007D5B8400DF
+:101BD000B55B840031568400A5638400CD60840029
+:101BE00091638400ED5084002D5E840031518400A7
+:101BF000155C840061548400F55E8400F15D84000E
+:101C0000315A84007152840059588400815C8400E8
+:101C1000715784002557840071588400AD568400A4
+:101C2000415984006D4F840029508400E1548400A0
+:101C3000BD6184006D61840005598400A56684003F
+:101C4000D9678400456684000D658400916784002F
+:101C5000B96384005D67840079678400F966840055
+:101C60002165840021678400C56684008D66840038
+:101C70006566840011688400516C8400AD6E840038
+:101C8000016E8400F97084004D7F84007D6C8400B7
+:101C90002D748400456A84000D7B840099EC00005B
+:101CA000156E8400457A8400E56C8400456F8400DD
+:101CB000C17C8400297E8400756D8400956B84004E
+:101CC000B56D84007D7D84005D6B8400D56A8400E1
+:101CD000816A840085748400B1808400857E8400DC
+:101CE000CD7F84004981840069818400ED8984006E
+:101CF0006D8A8400FD8984008D8984009D8984001B
+:101D0000E9858400F982840025858400518A840055
+:101D100075858400958484008181840071838400AA
+:101D2000C18984005D898400D58984006D8984001F
+:101D30007D8984000D8A840009868400798C840062
+:101D40007D8A84000D8B8400499484008D928400E8
+:101D5000E98D84009D8B8400FD8C84007990840043
+:101D60000D8C8400458C8400E9A68400A5AD840018
+:101D700029968400C598840015C1840009A98400AF
+:101D800099C2840045B7840031C18400D1B8840071
+:101D90008D998400B99A840025AC8400D9BF840051
+:101DA000C9BE8400A196840025B18400519B8400A3
+:101DB000919884004D9784001D9784007DA684002F
+:101DC000D1B784002DAB84008595840019B08400C0
+:101DD000F5AD840029A98400C1A98400219F840055
+:101DE00025A28400B1AE8400C1AF8400D5A38400D5
+:101DF00075B7840041A28400E1BC84006DA8840012
+:101E0000BD9D840095B884005D95840075BE8400F6
+:101E100051B98400A9958400C5C18400599A8400F1
+:101E2000419684003DB884009DA88400E5A8840004
+:101E3000A59B8400F5A684003DAF8400159A84001C
+:101E4000F9988400EDA984006DB18400FDF0840050
+:101E500025DF840025ED8400E5D08400CDF18400E9
+:101E600009F2840035F2840055F28400CDF284003A
+:101E7000B1D38400F5D384002DD48400C1D4840070
+:101E8000A5048500F90585006D0585009904850088
+:101E90008D04850079D4840045E88400B1C58400B0
+:101EA00095DF840031DF840075E484001DE0840048
+:101EB000BDC9840005ED8400A500850091FB840068
+:101EC000F9ED840091EF84009DFB840081EA840099
+:101ED00079E2840059C6840061EB8400A1EB8400A0
+:101EE000D1E484009D028500A1F3840015CC840018
+:101EF0005DFB840081C5840015D5840099D68400DB
+:101F000035E78400B9DF840045F48400B9C7840054
+:101F100001DF84002D018500E1C7840025D1840004
+:101F20006DFA8400BDDD84004DF38400E1C98400B6
+:101F300041E084002DCA84009DD4840005EB840018
+:101F4000D900850079CB840021FC8400B9E88400A5
+:101F5000B5D8840031FD8400BDFB84001D048500DC
+:101F60005D048500B9E90000450685005DEC84004C
+:101F700025C384001DF38400D9C684002DEC8400A1
+:101F8000F1C5840059E9840019C88400B1EF8400C8
+:101F9000B100850049D3840001C98400E1D28400E6
+:101FA0008DCB8400DDEB840011F4840009FC8400F7
+:101FB000D9F3840069C38400A1C884002DEE840095
+:101FC00071D6840079018500D9EC000025D8840001
+:101FD000DDF9840009F0840035F7840029F98400D4
+:101FE000D9FC840015D78400DDD584001DDE840073
+:101FF000D9F5840019F1840099F1840049F1840035
+:10200000F1F48400A1F48400F1D084003DCC84007C
+:1020100069D2840089E9840071CD8400C9D3840029
+:102020008506850089078500E90685004D0785003E
+:102030001107850025078500710685009506850036
+:10204000BD06850075078500B10785009D078500E1
+:10205000A9068500D1068500FD06850039078500A3
+:10206000610785005D0685001509850079098500F1
+:10207000350A8500BD0985000D0A850019A20000FA
+:10208000E9EC00004D0A8500A909850025098500B5
+:10209000DD0A85006D0A850081088500C507850079
+:1020A0000D0B8500590F8500ED118500C9128500C3
+:1020B00021108500F90D8500D5118500511085008E
+:1020C000AD118500011185006D10850065A401002A
+:1020D000850F850085108500990D850011128500FA
+:1020E0000D22850041178500D917850075208500D0
+:1020F0007D2C8500352F8500B92285002D25850092
+:102100009D238500612F8500A5278500C92A8500AC
+:102110006D2985009D22850031228500A52485003A
+:10212000E1238500B12F8500BD2C85005914850061
+:10213000C9138500A11C8500452C8500A9178500C1
+:10214000B1208500311A8500FD178500291D850005
+:1021500021148500AD218500B5308500453185000D
+:1021600035278500D1318500C5148500BD2D85003A
+:102170002D23850059238500891485004D4685004F
+:102180006547850025368500514785003D46850019
+:102190008D3C8500514A8500994A85007547850028
+:1021A0001D478500553685005D468500D53B850079
+:1021B00049498500D53A8500E139850041398500D6
+:1021C000E53885000937850045358500C93C85001F
+:1021D000754B8500B9458500ED4885002146850091
+:1021E000213A8500A940850001328500F53285003D
+:1021F000FD378500894E8500DD508500ED50850056
+:102200005D57850009558500495085005D50850062
+:10221000D1528500F5528500E54E8500C9558500EF
+:1022200065568500C9508500094F850025A5010028
+:102230009D5585000D538500A94C8500B957850033
+:10224000A55785000D518500FD5A8500D5518500A3
+:10225000A9518500B15285009D53850039558500EF
+:102260009D4E8500C95785006D578500954C8500AA
+:10227000095785008D4F850091A50100FD59850006
+:10228000014D8500ED598500D9598500194C85000F
+:10229000756C8500816E8500516C8500295C850018
+:1022A000416E8500795E850059EA0000AD6E8500BB
+:1022B000B56C85006D6585001D5F8500196B850017
+:1022C0008579850071738500B58E8500E19585005F
+:1022D00001828500519085002D828500D190850076
+:1022E000FD908500BD9285006D8F8500CD928500A3
+:1022F00055968500C58E8500857285005D8D8500AB
+:1023000001838500C1918500257085000D918500B0
+:10231000C17685006971850041718500F97F85006E
+:1023200079708500F19385009D958500F574850091
+:10233000497485006D788500BD728500ED8A850041
+:10234000C98C850099918500597D8500BD718500F6
+:10235000758185000D818500A9798500217785002B
+:102360002193850089928500D194850095968500FA
+:1023700065838500D973850065828500D5A5010038
+:102380005975850021768500556F85006D9585000E
+:10239000E583850029848500AD8F8500F16E850079
+:1023A0006D0101004DFB0000F90001007109010001
+:1023B000C5000100EDFD000069FE0000750401008C
+:1023C0002DFE0000FDFD0000F5FD00002D0F0100B9
+:1023D000390101000D0A01006DFB000045030100F9
+:1023E000CD04010095FD0000A9FB0000851201004D
+:1023F000A5FB000085130100B5150100AD0001002B
+:10240000ADFD00001D0101006D0501005D09010029
+:10241000BD0001009DFB000095FB000031030100A1
+:1024200001070100F506010029030100250601004E
+:10243000510301005D050100E5FF0000C9FE000039
+:1024400095180100E9FF0000C9000100D10001005A
+:1024500059030100710D0100C50D010081FF00004D
+:10246000A50001005108010025A3000061A30000A0
+:102470009DA30000E1A6000025AC0000B9F9010011
+:102480008DAC000095AC000055AF000045B00000D9
+:10249000ADB0000005B20000B9B60000F9B8000008
+:1024A00031B9000055B9000061B90000B1B90000B0
+:1024B0008DBB0000C9BC0000B932000055330000DC
+:1024C000613400009DE800006537000099E80000D5
+:1024D000D5510000C16B0000E9750000757E000059
+:1024E0002DC7000065C800008DD10000C5D50000D3
+:1024F00009F10000B998000081E800007DE80000C3
+:102500006DE8000075E800001DD700008DE80000B0
+:1025100089E8000091E8000095E8000069E8000003
+:1025200071E8000079E8000085E8000039D7000074
+:102530003DD7000045D7000049D700004DD7000027
+:1025400039E7000055E7000075E7000035E70000B7
+:1025500031E7000071E7000051E700004DE700009F
+:1025600049E7000045E7000041E700003DE70000C3
+:10257000C5E70000D1E7000001E8000021E8000005
+:1025800025E8000039E8000035E8000031E80000E7
+:102590002DE8000029E80000C5E80000BDE80000C3
+:1025A000B5E80000C9E80000B1E80000A5E80000B7
+:1025B000B9E80000A1E80000A9E80000C1E80000B7
+:1025C0003DE8000001000000200000001F000000A6
+:1025D00050000000020000000100000001000000A7
+:1025E000010000000000000015A701000A07080014
+:1025F0002157020051FB800055B900002DB60000A4
+:1026000000000000D1F980000000000029FB8000DC
+:1026100000000000000000009C1800409600FFFF32
+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10263000FFFFAAAA0300409600000000000000006F
+:10264000000000000000000000000000000000008A
+:10265000000000000000000000000000000000007A
+:10266000000000000000000000000000000000006A
+:10267000000000000000000000000000000000005A
+:10268000000000000000000000000000000000004A
+:10269000000000000000000000000000000000003A
+:1026A000000000000000000000000000000000002A
+:1026B000000000000000000000000000000000001A
+:1026C000000000000000000000000000000000000A
+:1026D00000000000000000000000000000000000FA
+:1026E00000000000000000000000000000000000EA
+:1026F00000000000000000000000000000000000DA
+:1027000000000000000000000000000000000000C9
+:1027100000000000000000000000000000000000B9
+:1027200000000000000000000000000000000000A9
+:102730000000000000000000000000000000000099
+:102740000000000000000000000000000000000089
+:102750000000000000000000000000000000000079
+:102760000000000000000000000000000000000069
+:102770000000000000000000000000000000000059
+:102780000000000000000000000000000000000049
+:102790000000000000000000000000000000000039
+:1027A0000000000000000000000000000000000029
+:1027B0000000000000000000000000000000000019
+:1027C00000000000407C704713B500F001D90246BC
+:1027D00008B904460FE000240AE0104601A90022CF
+:1027E000FFF3B6F7019A13782C2B08BF013201349E
+:1027F0001378002BF1D120461CBDC046B0F8423002
+:1028000070B50446C3B142F2197503E00A2003F023
+:10281000A3DF0A3D236B1B6913F0704307D0B3F1AC
+:10282000005F04D0B3F1405F01D0092DEED1226BDF
+:10283000136823F01003136070BDC04670B50446E2
+:10284000D0F8B40030B1037823B1FFF7BBFF0546E1
+:1028500010B10BE0012509E0D4F8B400012100F02B
+:10286000DDD903E0606A002204F05ADA0121204633
+:1028700002F0BCDA01460028F4D125B9D4F8B4003E
+:10288000294600F0CBD970BD70B590F87831054677
+:10289000FF2B1FD0104C406AE36E9847D4F89C3051
+:1028A000686A984701280BD895F8141241B90B466D
+:1028B00028460A4A03F07CDE012385F8143209E039
+:1028C000054B686AD3F89C3095F805419847241861
+:1028D00085F8064170BDC046E0A685003D988000A1
+:1028E00070B590F818320446012B32D00123002530
+:1028F00080F8183206E025B1A0682946012204F0CC
+:102900000FDA3546134B606A00219B6B98470646E9
+:102910000028F0D1D5B1D4F80C323BB11B782BB1E3
+:10292000A0682946012204F0FBD908E0D4F8F4108D
+:1029300019B1A068012204F0F3D9C4F8F450D4F816
+:10294000F830AB4202D10023C4F8F830002384F8F9
+:10295000183270BDE0A6850010B5084671B191F837
+:102960000832012B0AD091F875313BB14B691A6AD4
+:10297000034B02EA03030BB10CF000FC10BDC04690
+:1029800000FC0101D0F8943110B59942044601D9F8
+:10299000002002E00CF0F2FBE08D10BDD0F88011B9
+:1029A00010B5044691B10223C068D4F8842108F020
+:1029B00015DB074B1B684BB9D4F88011D4F8842180
+:1029C000E06881EA0202023308F008DB10BDC0466D
+:1029D000A8F401002DE9F04190F817320446012BCC
+:1029E00077D00123002780F8173243E0A0683146F2
+:1029F00000F092DBD4F8F0301B68984205D92846E5
+:102A00000021324600F01EDB42E02046FFF73CFF8B
+:102A100035690023AB7194F8783131462B7294F804
+:102A2000063184F80731DBB26B72D4F8FC31606A8E
+:102A30000133C4F8FC316A79274BD20982F00102D4
+:102A40005B6A9847B0B9D4F8F8106B7900293CD08C
+:102A500013F00F0F39D06A782B7843EA02230F3333
+:102A60001B091A0A0A6918BF0023937194F8783178
+:102A700013722AE0D4F8F0301B68012B08D904F156
+:102A800028052846002100F05FDA06460028ADD16F
+:102A9000002384F81732C4F8F8302FB16269043388
+:102AA0005364204607F04CDFE28DD4F8C8319A42D7
+:102AB00003D9206901F0D4DD0BE0D4F8CC319A427F
+:102AC00007D2206901F0BEDD03E00127C4F8F860F9
+:102AD000D0E7BDE8F081C046E0A685002DE9F041D1
+:102AE00090F816520023066A044603626DB18D4BBE
+:102AF0001B686BB3D0F88011D0F88421022381EADF
+:102B00000202C06808F06ADA22E090F87931FBB17D
+:102B1000D0F88011E1B1D0F884210223C06881EAA5
+:102B2000020208F05BDA94F8153284F8795184F8DF
+:102B30007C5123B1204607F06BD984F8155294F8E4
+:102B40007B312BB1D4F88C0103F0B8DB84F87B51D6
+:102B500016F0804706D0204607F0AED820460CF08D
+:102B600003FB34E0002E2FDA63695B6813F0040581
+:102B700018D094F8743133B92046394607F0BEDDD9
+:102B8000204607F009D9206984F8747101F044DC0B
+:102B9000626920461368022143F00403136006F0C3
+:102BA00077DE11E0012384F87431206901F044DDFF
+:102BB0002046294607F0A2DD204607F0EDD86269DD
+:102BC000136823F00403136094F874510DB10027C7
+:102BD000A5E016F0010F07D02046012107F08EDD99
+:102BE0002046012106F054DE16F0020F09D0012321
+:102BF00084F87731D4F8FC301BB12046294606F022
+:102C000047DE16F4807F04D0D4F864310133C4F871
+:102C1000643116F4007F12D0D4F86831D4F8F4107F
+:102C20000133C4F8683131B1A068012204F078D8CA
+:102C30000023C4F8F4302046002107F05FDD16F0D1
+:102C4000007F04D0D4F86C310133C4F86C3116F035
+:102C5000806F04D0D4F870310133C4F87031324839
+:102C600006EA000018B12046314606F03FDE16F0B5
+:102C7000040F074623D0D4F8801101B30123626901
+:102C800084F87931136A526A134013F0F00503D0C7
+:102C9000204607F055DE12E0D4F884210223E068D4
+:102CA00081EA020208F09AD994F87B3184F87C51C9
+:102CB0002BB1D4F88C0103F001DB84F87B51E68D55
+:102CC0006EB3D4F8A051012D02D0072D0CD023E013
+:102CD00094F87A211ABBD4F89001D4F8981103F033
+:102CE00089DA84F87A511AE094F87A3173B1D4F819
+:102CF00094319E420AD2002104F1280000F05AD9F2
+:102D000003695B7803F00F03032B08D1012E03D96D
+:102D1000204631460CF046FA2046FFF75BFE384667
+:102D2000BDE8F081A8F4010000FC01012DE9F041AB
+:102D30000746884616461D4642F2197403E00A20EB
+:102D400003F00ADD0A3C79690B6D002B02DA092CCD
+:102D5000F5D11FE0AB191B0243F00042069BB3F113
+:102D6000807F04D198F8003043F08073D21842F28B
+:102D700019740A6503E00A2003F0EEDC0A3C7B6963
+:102D80001B6D002B02DA092CF5D103E0012088F835
+:102D9000003000E00020BDE8F081C0460022C36B97
+:102DA0000BB1013BC363531CDAB21030102AF6D1C9
+:102DB0007047C0462DE9F041066805460F46706829
+:102DC0004FF4BC7103F084DF08B9044612E000211F
+:102DD0004FF4BC720446FFF333F1D5F8603126603E
+:102DE000C4F8603195F86431C4F8687184F86431CE
+:102DF0006B6863602046BDE8F081C0462DE9F04174
+:102E00009846036817461B680C6993F895308E8ABC
+:102E10003BB1CB8A13F0800F03D104F11E010120D6
+:102E200020E00D2E3FDD04F10C014B78227B43EABC
+:102E30000223B3F5C06F01DB002013E0152E32DD55
+:102E400004F10E051A4829460622FFF379F018B955
+:102E500004F11401013005E0294606221548FFF36C
+:102E60006FF020E04A780B7842EA0322B2F5014F76
+:102E700008D104318A1CA3199A4214D84A780B78D5
+:102E800042EA032240F606039A420CD18A1CC4EBA4
+:102E90000203C3EB06031C2B00DC04D13A6088F864
+:102EA0000000002001E04FF0FF30BDE8F081C04697
+:102EB00014D28500B0A6010003682DE9F74F012A5E
+:102EC00014BF2A25322506460F46586829469146E2
+:102ED00003F056DF834640B9336801381B68D3F8E6
+:102EE0008C20136D013313656CE007F10E0A046941
+:102EF0005146042201A8FFF33FF0019B06F1280888
+:102F000003F47F421B0643EA02234AF6FE12B2EBA9
+:102F1000134F0BBF2C4907F108012046204606221B
+:102F2000FFF32AF00622A01D4146FFF325F004F12D
+:102F30000C02B9F1000F0DD02B0A237304F10E001F
+:102F4000557022490622FFF317F008232375062344
+:102F5000637503E008232373062353706419A4F1F7
+:102F60001C05394606222846FFF306F0002304F824
+:102F7000163C023304F8153C4146062205F10800D0
+:102F8000FEF3FAF707F11801042205F10E00FEF333
+:102F9000F3F707F10801062205F11200FEF3ECF742
+:102FA0005146042205F11800FEF3E6F7D6F85C312D
+:102FB00030680133C6F85C315946D6F8682125F0EF
+:102FC000F1D80120BDE8FE8F2C9E850014D285002B
+:102FD0002DE9F74F012B14BF2A25322599460368A6
+:102FE00006460F465868A91C934603F0C9DE804682
+:102FF00040B9336801381B68D3F88C20136D013356
+:10300000136579E0036907F1180A9C1C838A51460D
+:10301000023B83820422046101A8FEF3ADF7019B09
+:1030200003F47F421B0643EA02234AF6FE12B2EB88
+:10303000134F0BBF314907F10801204620460622F5
+:10304000FEF39AF70622A01D5946FEF395F704F108
+:103050000C02B9F1000F0DD02B0A237304F10E00FE
+:10306000557027490622FEF387F7082323750623A8
+:10307000637503E008232373062353706419A4F1D6
+:103080001C05394606222846FEF376F7002304F88D
+:10309000163C023304F8153C5946062205F1080097
+:1030A000FEF36AF75146042205F10E00FEF364F7C1
+:1030B00007F10801062205F11200FEF35DF707F1A2
+:1030C0000E0105F118000422FEF356F7D6F8483138
+:1030D000D6F868110133C6F84831012386F8643107
+:1030E0003368986801B189680123424608F058FBAB
+:1030F000002386F864310220BDE8FE8F2C9E8500F7
+:1031000014D2850010B50368D3F800481B6893F803
+:10311000AB306BB1FFF742FE08E0A16829B1012096
+:1031200008F070FA08B1FFF739FE2468002CF4D1DA
+:10313000002010BD7047C046C3682DE9F041064627
+:103140000D4658683821174603F0C2DD044610B911
+:103150006FF01A002BE000213822FEF371F70123F3
+:10316000294623606360A360062204F10C00FEF38D
+:1031700003F76B8E05F10901A3742B7A04F1140097
+:10318000E3742A7AFEF3F8F66D8D3046A586E7865D
+:103190002146382221230BF003DC00B907E0F36855
+:1031A00021465868382203F0A3DD4FF0FF30BDE818
+:1031B000F081C04630B50C4690F8CF1091B09446DF
+:1031C0009E460380194D91B94FF0FF33029303934C
+:1031D000049305930D330094019106910791089192
+:1031E00009910A950B900C930D910E9115E04FF0FB
+:1031F000FF33029303930493059300F1D0030693E6
+:103200004BB2002207930C2300940192089209927A
+:103210000A950B900C930D920E927146044A6346E8
+:10322000C06823F069DE11B030BDC04631F6000041
+:103230002C9E85001FB5836D0446012B17D1B0F875
+:10324000583113F0010F12D1C36893F8703273B97B
+:1032500002AA01A903AB0CF071FA029A3AB1204616
+:103260000199039BFFF7A6FF08B90223A3651FBDC1
+:1032700010B579B1B0F8583143F00103A0F85831D6
+:10328000836D022B15D1C3680C21D3F8680151F06E
+:103290008FD90EE0B0F8583113F0010F09D023F0A8
+:1032A0000103A0F85831836D1BB101238365FFF73B
+:1032B000C1FF002010BDC046642912DC632920DA5A
+:1032C0004A291ED006DC07291EDB082919DD3C2906
+:1032D00017D019E0502914D016DBA1F15C03032BA1
+:1032E0000EE0C32905DCC2290BDAA1F1A803022BE9
+:1032F00006E0B1F5847F04D006DBA1F58973012BCC
+:1033000002D86FF0160000E00020704730B5072AA1
+:103310001C469DF80C5001DD496809B9036B19681A
+:10332000032906D04B1E012B10D8036B1B68994252
+:103330000CD12DB190F8293013B96FF00A0007E0D5
+:103340000CB9204604E00020216001E06FF00C0081
+:1033500030BDC046C88810F0080018BF6FF01600D6
+:103360007047C046D1F8D83270B50546188C16465D
+:1033700010BB8B6D40F2371203EA0202002A0CBF29
+:10338000012411242A6B1368022B07D195F85C36AF
+:103390000133DBB2012B98BF44F02004537D53B1BD
+:1033A000B06B06F13C0122F055DE20B195F94736AD
+:1033B0000BB144F48064204670BDC04691F801C052
+:1033C00030B5BCF1010F45DDCA788B7843EA0223A2
+:1033D000012B3FD1ACF10203032B3EDDACF1060320
+:1033E000012B3ADD0B1D1D1D6A781B79002043EA75
+:1033F0000222864600E00130ACF10803904203EB64
+:103400000E0406D0AEF1040EACF104037344042B99
+:10341000F1DCC0EB0203A4EB830001281DDD05EB0A
+:103420008203DA789B7843EA022E821E002301E0B1
+:103430000133043A734501D0032AF9DCC3EB0E03D0
+:10344000A2EB8303012B08DD023B06D0C3EB0C0388
+:103450004B7002E06FF0160000E0002030BDC04667
+:103460002F2A30B50446964602D86FF00D0034E09E
+:10347000B0F88031056B0B60B0F88231AA894B60DF
+:10348000EB891B0743EA023302688B601069BEF1C7
+:103490003B0FC36BCB6093680B61836A4B61C36A5C
+:1034A0008B61B2F87A30CB61D4F884314B62D2F8B8
+:1034B000B0300B6243688B62836BCB620CD92B8973
+:1034C00000220B636B89BEF13F0F4B638A6303D904
+:1034D000036C1046CB6300E0002030BD2DE9F041C5
+:1034E000064633680F4693F84630154613F0030F2F
+:1034F000C2F3072402F07F00C2F3C01E15D0BEF154
+:10350000000F12D0032C54D8202807D1B6F8263645
+:1035100003F44063B3F5406F4BD10CE0072801D9A9
+:10352000032419E0032C44D015E0244B00F07F0263
+:103530009B56002B02DA012C3BD80CE0022A05D066
+:10354000042A03D00B2A01D0162A32D13B68022B61
+:103550002FD174BB05E024B1D6F860369B78012BDF
+:1035600027D00146BEF1000F05D0022C40F00061CB
+:1035700008BF40F0016141EAC42415F0804F18BF34
+:1035800044F0804415F4000F18BF44F4000430B137
+:10359000304621463A68012327F0DCDE48B1C5F306
+:1035A000405044F0004110B10020B96403E0796458
+:1035B00001E06FF01C00BDE8F081C046401B8600B2
+:1035C00010B519B14068302203F092DB10BDC0463F
+:1035D00010B50446D0F860068E46C37A90F80AC04B
+:1035E00093B182894FF6FF739A420DD0837B43B922
+:1035F0008378012B05D0037B03F0010383F00101E5
+:1036000000E00021C9B20BE0216B71450ED1837B34
+:103610002BB98378012B02D091F84C1000E00021E7
+:103620008C4503D08172206938F03ADE002010BD4D
+:103630004FF0FF33A0F83C3210B5044600F50E7091
+:10364000063000210C22FEF3FBF423685B6B23B9E8
+:103650004FF0FF33A4F840320DE04FF00F03A4F811
+:103660003E324FF0F003A4F840324FF47063A4F8F8
+:1036700042324FF20003A4F8443210BD70B5044644
+:10368000D4F8741580680BF0E9DFD4F8F816D0F19F
+:10369000010538BF0025A0680BF0E0DF00B9013557
+:1036A000A068D4F8FC160BF0D9DF00B90135D4F8C6
+:1036B000E036A068196A0BF0D1DF00B90135D4F803
+:1036C000E0260023D360A068D4F83C150BF0C6DFD9
+:1036D00000B90135A068D4F894170BF0BFDF00B92A
+:1036E0000135284670BDC0462DE9F041069F0646CB
+:1036F0000C46A3F10E0519F0A7DC18B1304621469F
+:103700000FF014DFB5F5106F1DD3D4F8F01040F6AC
+:103710000E1240F6081300290CBF114619466268C4
+:103720000B4B02EA030303B102398D420BD9A37E8E
+:1037300013F0010F07D121F001026B1E9B18B3FBA0
+:10374000F2F03A6001E03D600120BDE8F081C04642
+:103750004000018010B5044625F03CDE204616F0FE
+:1037600055DF10BD2DE9F04F07461069A5B0D1F81F
+:103770001090884601F124011A900792069318913F
+:1037800099F80130D2F87CA199F80020339C42EAE4
+:103790000323C3F38102022A786808930B9201D0B5
+:1037A000002302E0089DC5F3C013DBB24146169327
+:1037B000FFF330F504300A90329888B1037A0B2B6E
+:1037C00008D197F8F0375BB197F8F13743B18379B7
+:1037D000072B05D832990A9A91F90F30D2180A921C
+:1037E000D7F88831002B1CDA329BD3B11B7A022B1D
+:1037F00017D197F8A034A3B91A9DAB6D13F0080F39
+:103800000FD132988379292B0BD8032B09D90B2B95
+:1038100007D82F99012904D10A9A199108320A92DE
+:1038200001E000231993D8F81030B8F81420A3F160
+:10383000760676329D1FA8F8142000217022C8F861
+:10384000106030460595FEF3FBF31898036813F4F7
+:10385000806F01D0828827E00799A64B4A6802EA68
+:103860000303D3B1089A02F0FC03882B15D199F811
+:10387000043013F0010F10D1B8F816302F9D03F06B
+:1038800007032E9801EB43016B1E9842B1F8BE204E
+:103890000AD1531CA1F8BE3006E00B99012914D0BF
+:1038A00000224FF0100B04E00B9B012B0DD04FF0CA
+:1038B000000B2E9D05F00F0343EA02139BB289F81B
+:1038C00016301B0A89F8173001E04FF0000B3098D2
+:1038D000042807D138461A9932460EF091DFADF828
+:1038E0008C0019E02F992E9D4B1E9D42B7F846255E
+:1038F00002D1531CA7F846352E98309900F00F03DB
+:1039000043EA02135B0147F6E07203EA020201F0A8
+:1039100007031A43ADF88C20079A92F8DF3023B9D9
+:10392000089D05F0FC03802B01D14BF0200B724B5E
+:1039300004EA03031BB10020209421941FE00B999B
+:10394000012906D9189A1368002B02DB13F0100026
+:1039500008D0079C002594F8483003F07F0320939B
+:10396000219349E0396B644B8A6C02EA030343B14B
+:1039700099F8043013F0010F03D0209221920F9098
+:103980003BE099F8043013F0010009D007980021BA
+:1039900090F848300F9103F07F03209321932CE09F
+:1039A0004A6C554B02EA0303002BE6D120ABD7F853
+:1039B000600100930DF18F0301930DF18E030293CB
+:1039C0000DF18A03039323AA21AB07994FF072D913
+:1039D000189A136843F00062189B1A60BDF88A3089
+:1039E00013F0010F03D0189C42F4005323602E9D66
+:1039F000D5F1010538BF00250F95D7F86036219A1B
+:103A00009C7A3B6893F8463013F0030100F035814F
+:103A100012F0006F02F07F0104D0072906D9202997
+:103A200004D02EE0354B5B56002B2ADA12F0804F83
+:103A300001D1002A25DB22F4401121F4605112F05B
+:103A4000006F21911AD0D7F860068378012B15D921
+:103A50003B6B93F94D20012A0BD0079D6B6813F047
+:103A6000804F0BD0B2F1FF3F08D1037B13F0040F5E
+:103A700004D041F4801343F4805301E041EAC423AD
+:103A80002193209911F0006F01F07F0204D0072AE2
+:103A900006D9202A04D036E0184B9B56002B32DA88
+:103AA000219B13F0804F01D1002B2CDB21F440121D
+:103AB00022F4605211F0006F209221D0D7F86006F6
+:103AC0008378012B1CD93B6B93F94D1001290BD046
+:103AD000079D6B6813F0804F12D0B1F1FF3F0FD1FB
+:103AE000037B13F0040F0BD042F4801343F4805394
+:103AF00008E0C046400001807F000008401B8600AF
+:103B000042EAC4232093B7F8283603F44063B3F5A0
+:103B1000406F30D13B6B18690CF070F9219B00F4B9
+:103B20004070B0F5007F14BF0222032213F0006F33
+:103B300003F07F0111D0202902D1154605222EE085
+:103B400097F9CA34B3F1FF3F12D10798436813F4D1
+:103B5000002F23D01546042221E09C4B5B56002BFE
+:103B6000B4BF97F9C93497F9C834B3F1FF3F15D002
+:103B700015469AB213E0219B03F07F03202B04BF6C
+:103B80004FF000632193209B03F07F03202B04BFA1
+:103B90004FF00063209302252A4600E01546219B42
+:103BA000110223F4E06341EA03032193209B23F4F1
+:103BB000E06213F0006F14BF41EA020342EA0523FA
+:103BC0002092219A209312F0006F06D097F9DC31F1
+:103BD000012B02D142F4000304E097F9DC3113B960
+:103BE00022F400032193209A12F0006F06D097F977
+:103BF000DC31012B02D142F4000304E097F9DC31FF
+:103C000013B922F4000320930799384612F088D89C
+:103C1000219911F0006202D111920E921DE0D7F8A5
+:103C2000583693F90530022B02D000220E9207E09D
+:103C3000C1F30223043B012B8CBF002301230E930D
+:103C400011F4000F05D001F07F03072B03D9202BBF
+:103C500001D0119001E004231193209911F000622A
+:103C600001D112921DE011F4000F16D001F07F0374
+:103C7000072B14D9202B12D00FE0209B22F4E062F6
+:103C800023F4E06342F4007243F4007302252192AE
+:103C9000209311910E91129103E0129001E00424FF
+:103CA00012940F9888B11A99219BD1F810231A9871
+:103CB00001EBC201C1F814332F9C0132E3B202F0D0
+:103CC0003F02C1F81833C0F81023BAF1000F36D004
+:103CD000FA68DAF80434D2F880410AEBC303C3F877
+:103CE0000442D2F884013A4AC3F80802B8F8163000
+:103CF00003F00703D35C022B11D1DAF800100AEBB2
+:103D0000C102C2F80441C2F80801219B013153608D
+:103D10002F9C01F01F01E3B29360CAF80010DAF89B
+:103D20000424219B0AEBC201C1F808342F98013208
+:103D3000C3B202F03F02C1F80C34CAF8042421993E
+:103D400011F000642AD011F4000F01F4E06312D0E6
+:103D50001B0A043B012B1F4801F07F0205D81423E6
+:103D600002FB0303D3F80C801AE0142302FB0303C5
+:103D7000D3F8088014E01B0A043B012B154801F01E
+:103D80007F0205D8142302FB0303D3F8048007E065
+:103D9000142302FB03F353F8008001E001F07F08D5
+:103DA0000B9A022A00D0BAB9B7F838360A98984266
+:103DB00004DC189A136813F0806F0DD099F8043062
+:103DC00083F0010303F0010307E0C046401B8600B7
+:103DD000C4D285008418860000230D933B6B587D68
+:103DE00050B1D7F858361B7833B12CB9924A01F04C
+:103DF0007F03D356002B0BDB3B6893F8463013F060
+:103E0000030F2CD05CB3D7F8583693F9053033B391
+:103E10002F9A012A13D9D7F858361B780BB11623DD
+:103E200000E03023189C20932193236823F0006343
+:103E30002360209B43EA0523209321930FE070B178
+:103E4000D7F858361B7853B14CB97B4A01F07F0341
+:103E50000E98D35630EA230028BF01200E90219AF5
+:103E600012F0006F15D102F07F03022B05D0042B56
+:103E700003D00B2B01D0162B0BD1069939B1022B95
+:103E800005D097F95C36013B18BF012300E0002301
+:103E90001193209B13F0006F16D103F07F03022BC8
+:103EA00005D0042B03D00B2B01D0162B0CD1069C74
+:103EB00044B1022B06D097F95C36013B18BF0123B1
+:103EC000129301E0002012900B99079C022904BF75
+:103ED000079BC3F86021636813F4803F40D097F8D4
+:103EE000CE31002B3CD097F8D131002B38D0D7F809
+:103EF000583693F90530032B32D0219B13F0006F15
+:103F000009D103F07F03022B2AD0042B28D00B2BDE
+:103F100026D0162B24D099F8043013F0010F1FD1AE
+:103F2000089800F0FC03882B1AD1189901240B681B
+:103F30004BF4A04B43F480530B60079B1094D3F8D1
+:103F4000F0204FF69F73002A0CBF18221E2239F86A
+:103F5000021001EA030343F0200329F8023001E0D4
+:103F600000201090384621990A9A059B0DF17A0499
+:103F700019F072DB2346384620990A9A19F06CDB57
+:103F8000062206F136002146FDF3F6F7209B13F0DA
+:103F9000006F10D103F07F03022B05D0042B03D058
+:103FA0000B2B01D0162B06D10A99C1F3072386F8F3
+:103FB0003A1086F83B30189B1A6812F4806F13D0C1
+:103FC000219B13F0006F0FD0329C14B1237A042B85
+:103FD0000AD1189842F40063036097F8C3340D992E
+:103FE000002B18BF01210D91219911F0006F0AD10A
+:103FF000114A01F07F03D356002B04DA059A137897
+:1040000003F00F0301E0059B1B78089C0C93A42C84
+:1040100014D099F8043013F0010F0FD1109878B92B
+:10402000119A319B38460FF0B9DD89F80200C0F3D0
+:104030000F2089F803001DE0401B8600109A62B132
+:10404000119A384640F62A1319F09CD8023080B2F3
+:1040500089F80200000A89F80300089BA42B09D103
+:1040600099F8023099F8032043EA022386F83C309D
+:104070001B0A09E099F8043013F0010F01D1109CDC
+:104080002CB1002386F83C3086F83D300BE02099B7
+:10409000129A319B38460FF081DD86F83C00C0F360
+:1040A0000F2086F83D001898036813F4007F0DD0A8
+:1040B00083894BF4005B86F842301B0A86F8433054
+:1040C000C38986F844301B0A86F845302E9909B911
+:1040D0004BF0080B09F104021B9299F8043013F01D
+:1040E000010F14D1189B1A6812F4805F0FD197F852
+:1040F000D03113B112F0400F09D112F4806F04D106
+:10410000169C14B197F8F8310BB94BF0010B0B98D2
+:10411000022814D197F8CE318BB1B8F1040F0ED923
+:10412000A44B30995B5C07EB4303B3F8FE3123B13A
+:10413000189A136813F4806F01D04BF4805B3B6BCB
+:1041400018690BF05BFE199B00F44060B0F5406FFE
+:1041500008BF4BF4807B0BB14BF4004B4FEA1B23A1
+:1041600086F800B07370329CECB197F8A034D3B9E4
+:104170001A98836D13F0080F15D1237A0B2B08D1F1
+:1041800097F8F0377BB197F8F13763B1A379072B34
+:1041900009D832998A79292A05D80B7B03F00703BD
+:1041A00043EA021A01E04FF0000A189A129C1368C1
+:1041B000494613F0005F18BF4AF0080A631EDBB2DD
+:1041C000012B98BF4AF4005A301D0222FDF3D4F6A9
+:1041D0000023B371F37186F82C3086F82D303298B5
+:1041E000002849D097F8A034002B45D11A998B6D3F
+:1041F00013F0080040D1329B1A7A0B2A0BD197F8A2
+:10420000F037002B38D097F8F137002B34D0329CA0
+:10421000A379072B30D832998B79292B2CD8089C7D
+:1042200009F1180104F44073B3F5407F169B08BFF1
+:1042300009F11E0103B10231022A11D13246329C2A
+:104240002318B3F8BC309375C3F30723D375831CCD
+:1042500002320A2B1846F2D106F12000032209E0AF
+:104260000B2A06F1160002D10231053202E0329B20
+:1042700093F90E20FDF380F6062206F126001B9925
+:10428000FDF37AF69DF88C30002286F84C309DF8CC
+:104290008D3086F84E2086F84D3086F84F2086F80F
+:1042A000502086F8512086F8522086F8532086F850
+:1042B000542086F8552086F8562086F857200D9C05
+:1042C0000CB10E9203E00E98002800F01D81002230
+:1042D00021992B46384622F0AFDD209980460022F6
+:1042E00038462B4622F0A8DD18F00061834609917C
+:1042F00006D1314B08F07F029B56002B2ADA36E0BC
+:1043000018F4000F08F4E06310D01B0A043B012BE3
+:104310002A4808F07F0204D8142302FB0303DB6859
+:1043200014E0142302FB03039B680FE01B0A043B09
+:10433000012B224808F07F0204D8142302FB030358
+:104340005B6803E0142302FB03F31B58023B18BF16
+:10435000012302E0931E18BF012343B197F95C3695
+:10436000012B04D001224AF4804A139201E0002379
+:1043700013931BF0006F06D10F4B0BF07F029B567F
+:10438000002B31DA3DE01BF4000F0BF4E06317D093
+:104390001B0A043B012B09480BF07F0204D81423AD
+:1043A00002FB0303DB681BE0142302FB03039B688F
+:1043B00016E0C04698E08500401B86008418860001
+:1043C0001B0A043B012B9D480BF07F0204D81423E9
+:1043D00002FB03035B6803E0142302FB03F31B5897
+:1043E000023B18BF012302E0931E18BF012343B113
+:1043F00097F95C36012B04D001244AF4004A149446
+:1044000001E0002514950E983278737820B142EAC5
+:10441000032343F4006303E042EA032343F006036B
+:1044200033701B0A73700E9A06F158011591002A19
+:104430000CBF14250E252A461DAC38464146159B57
+:1044400019F00AD923462A463846594619F004D9A4
+:104450002146062206F12E00FDF38EF5119C139BDA
+:104460000A9D019400240E9900934246219B0295D7
+:104470000394384619F010D986F86000C0F30F2075
+:1044800086F8610014981299209B009001915A4679
+:104490000E9902950394384619F0FED886F8340038
+:1044A000C0F30F2086F835000E9A06F162004AB17B
+:1044B0006FF03B0309F10A01062286F85E3086F8A8
+:1044C0005F4008E06FF04B0386F85E300E9B0C22D5
+:1044D00086F85F301B99FDF34FF5099C54B9584A93
+:1044E00008F07F03D356002B04DA159D2B7803F0D8
+:1044F0000F0301E096F858300C981B0243EA0000C5
+:1045000006F15E090C901BE00E99062206F1580098
+:10451000FDF396F50E99102206F15E00FDF390F57D
+:104520000E9906F12E000622FDF38AF50E9986F803
+:10453000341086F8351089461391149188468B46BD
+:10454000189A136813F4806F0BD0219A12F0006F41
+:1045500007D0D7F8400107990A9B2AF011DF86F8A7
+:1045600033004FEA1A2386F802A0F3700C9BB37451
+:104570000C9C230AF374209B13F0006F02D097F871
+:10458000C0A40EE003F07F03022B07D0042B05D05C
+:104590000B2B03D0163B18BF012300E000231FFAAA
+:1045A00083FA18F0006F03D097F8C0349D000EE036
+:1045B00008F07F03022B07D0042B05D00B2B03D070
+:1045C000163B18BF012300E000239B009DB21BF0A7
+:1045D000006F03D097F8C0341C010EE00BF07F038E
+:1045E000022B07D0042B05D00B2B03D0163B18BF92
+:1045F000012300E000231B019CB23B6B18690BF008
+:10460000FDFB45EA0A032343C0B243EA00233375A6
+:104610001B0A7375219B13F0006F02D097F8C044FA
+:1046200012E003F07F03022B0CD0042B0AD00B2BDB
+:1046300008D0B3F1160018BF012004E084188600EA
+:10464000401B8600002084B2119D6B1EDBB2012B43
+:1046500007D83B6844F01004D3F88C2093690133E9
+:1046600093612199384615F089DA44EA000080B256
+:104670003072000A7072219938461FF0B3DDB072B3
+:10468000C0F30F20F072209938461FF0ABDD307375
+:10469000C0F30F2070730D9808B90E9979B1414697
+:1046A00038461FF09FDDB073C0F30F20F0735946FA
+:1046B00038461FF097DD3074C0F30F2070742199D5
+:1046C00011F0006F0CD0119A042A09D10A9A3846C9
+:1046D00018F00ADE86F83E00C0F30F2086F83F008F
+:1046E000209911F0006F0CD0129B042B09D10A9A6B
+:1046F000384618F0F9DD86F84000C0F30F2086F840
+:104700004100079C636813F0400F00F0CE80169DB7
+:10471000002D00F0CA806A4B30981B5C179307EBA2
+:104720004303B3F8FE31002B00F0BF8018990B68EB
+:1047300013F4806F40F08D802E9A002A40F089801B
+:10474000219C38462146119A0A9B18F01BDD8246AF
+:10475000B9F1000F1AD04146139A38460EF0E0DF47
+:10476000149A0446594638460EF0DADF99F80320C9
+:1047700099F8023043EA022303EB040896F8352047
+:1047800096F8343043EA022318181BE0109B13B14B
+:104790008046484616E02146119A4B4638460FF0AF
+:1047A000FDD9209C129A21460A9B00EB0A08384644
+:1047B00018F0E8DC21460546129A38464B460FF0C1
+:1047C000EDD940191FFA88F3B3711B0AF37183B254
+:1047D00086F82C301B0A86F82D30179C07EB440313
+:1047E000B3F8FE51CAEB0804A54225D31898036814
+:1047F00013F0400F02D0309901291DD0384621997D
+:10480000119AC4EB05030EF093DFFF2802D84FF492
+:10481000807304E0B7F82A36834228BF034699B272
+:10482000309B07EB4302B2F82C368B4204D0A2F83F
+:104830002C16384626F02AD83B6893F84430002BD3
+:1048400033D0309C032C30D8D7F8640117994246F6
+:1048500028E03B6893F844303BB3309D032D24D8C7
+:10486000B9F1000F0CD0139A384641460EF058DFCC
+:1048700099F8032099F8023043EA02231A180EE04F
+:10488000219C119A21460A9B384618F07BDC119A2C
+:104890000546214638464B460FF080D94219D7F8D5
+:1048A00064011799079B3DF08DDC1898036843F06D
+:1048B00084030360BDF88C0025B0BDE8F08FC046CE
+:1048C00098E085002DE9F0479946536A064613F4AF
+:1048D000007F884617469DF920A0146902F124053F
+:1048E00015D0E86883B2000C84F8423084F84400A4
+:1048F0001B0A000A84F8433084F845002378607866
+:1049000043EA002343F4005323701B0A63703368A7
+:104910002D6993F8443093B1F36A03EB4803B3F97C
+:104920001C3063B95DB12B69D3F8D43293F89D3054
+:10493000032B04D9D6F864012B463DF023DDB8F1F2
+:10494000040F22D194F84D3094F84C2042EA03240D
+:10495000336893F83830D3B1384612F0A3D806EB59
+:104960008000D0F84C12D1F85835D1F860055A1CA7
+:10497000C1F85825C369A1F8C8409A4288BFC261EE
+:10498000D1F86025136A013313624FF6FF74B9F151
+:10499000000F05D0F26A02EB4802938B53449383D5
+:1049A0004FF6FF739C4204D03069A821224639F0AB
+:1049B00051D93369394603EB8803D8680C4B4A4612
+:1049C0005B6A9847002810DA0A480AF077FB0A4A1F
+:1049D000136801331360B9F1000F06D0F26A02EBDD
+:1049E0004802938BCAEB03039383BDE8F087C0466C
+:1049F000E0A68500BC568600E4F4010070B50D46C3
+:104A0000D0F860160446CB7AAB420CD025B10C31FD
+:104A1000B0F8282615F0F6D8D4F860362046DD72B6
+:104A2000216BFEF7D5FD002070BDC0462DE9F04F8B
+:104A30008FB000230C461D99074604921A9DDDF89D
+:104A40006C800D930C93DDF860B0DDF864903AF063
+:104A5000D1DC049A824602F00106009638682146AD
+:104A60002A4643461EF030DC0590002840F0438182
+:104A7000B4F90630002B1CDAA18822895EB11C9B98
+:104A8000CDF8008003930195CDF80880490038697E
+:104A900001312B4609E01C9BCDF800900393019552
+:104AA000CDF80880386949005B4638F059D8059040
+:104AB00021E1B9F1030F0DD904220DA85946FDF3E8
+:104AC0005BF2B9F1070F05D90CA80BF10401042220
+:104AD000FDF352F2049A0D99931E202B22D8DFE8A1
+:104AE00013F02400260028002A002F0032003A008C
+:104AF0003C004E005000570059005B005D005F0015
+:104B00006100630021006900700078007A008C0069
+:104B10008E009200940099009B00A0002100AC0040
+:104B2000A200B4006FF01603E4E0754B09E0744B8B
+:104B300075E0744B05E0002900F3DA80714B06E064
+:104B4000714B1B687FE00029C0F2D2806E4B196068
+:104B50006E4B00223BE06E4BF3E721B16D4B1B68BF
+:104B6000002B00F0C5806A4B002219606A4B1A6066
+:104B70006A4B1A606A4B1A606A4B013A27E0654B30
+:104B8000DFE7644A1368002B40F3B2801160B2E0A3
+:104B9000654BD6E7644B42E0644BD2E7634B3EE0A3
+:104BA0005D4BCEE75C4B3AE0D7F86C32D3F8D832A5
+:104BB0009B6848E05E4B1A685E4B1B6843EA024301
+:104BC00041E05B4B0A141A605A4B01F0FF021A6075
+:104BD00091E0594BB5E7584B1960002900F08B80E4
+:104BE000564B00211960564B4FF0FF321A60554B5F
+:104BF0001A60554B1960554B11E0554BA1E7002940
+:104C000076DD534B0BE0534B9BE74B1E092B6FD8C4
+:104C1000504B04E0504B94E7002969DD4E4B19607E
+:104C200069E04E4B8DE79AF80630002B5CD14C4B77
+:104C30000A1E18BF01221A705DE09AF80630002B98
+:104C400052D1474B1B782B6055E038468E2121F01E
+:104C500087DA400080B200F10A03ADF8243000F199
+:104C60001003ADF8263000F11603ADF8283000F13E
+:104C70001C03ADF82A3000F10C03ADF81C3000F134
+:104C800012034FF00008ADF81E3000F118031E307B
+:104C9000ADF82030ADF822004646C14609AB39F8E0
+:104CA0000310384621F05CDA07AB044639F80310EC
+:104CB000384621F055DA24B200B2241A032304FB4B
+:104CC00003F40BAAC4F34714B45464B21F2C01DDDF
+:104CD0001C33B354B3560136042E984409F102092B
+:104CE000DCD1C5F8008006E06FF00602059202E014
+:104CF0006FF01C03059305980FB0BDE8F08FC04618
+:104D0000E8F40100D4F40100DCF40100B4F4010083
+:104D1000BCF4010030ED0100D0F40100CCF401003E
+:104D2000C4F40100B0F4010020ED010034ED0100F5
+:104D3000ECF80100E8F80100B8F40100E0F401002B
+:104D40001CED010028ED0100C0F40100D8F40100C1
+:104D500024ED01002CED010018ED0100C8F4010064
+:104D6000ACF4010037B5036804465B7E002B40F0CD
+:104D7000C480026992F8EA305BB1D36ED3F8202187
+:104D800040F2044302EA0303B3F5806F40F0B580BC
+:104D900005E0106E06F0DEF8002840F0AE802368D3
+:104DA00093F8203033B9206904F072FE22680123A1
+:104DB00082F8203023681B6FFBB9206904F0E6FD00
+:104DC00010F1090F19D12268136F13F0020114D1E9
+:104DD00043F0020313670D4604EB8503D3F84C122E
+:104DE00041B18B7933B94B7923B18B7C13B1204618
+:104DF0003AF046D80135082DEED123681D6F1DB15C
+:104E0000204612F081D876E0012384F8293020462C
+:104E100020F00CDF2368596B39B103234FF4807203
+:104E2000009320462946134605E0032300932046BD
+:104E30004FF480720B461EF0C7DEA0680AF034DC27
+:104E4000236801221A7694F89D3173B120460AF046
+:104E5000E1F9D4F840352046598E23F0E7DD0023F0
+:104E600084F89D3120461DF0CBD8B4F85C1720465D
+:104E700021F054DE206904F0B3FE236893F82F304C
+:104E80001BB1D4F834072FF045DF236893F8313095
+:104E90007BB1002504EB8503D3F84C1231B18B793B
+:104EA00023B94B7913B1204635F002DE0135082DC8
+:104EB000F0D1204615F016DE204615F04FFB0125F7
+:104EC000D4F8AC114FF47A720123A0680AF07EDBAB
+:104ED000204684F8F15125F0D9DC204614F07ADE22
+:104EE000204626F035D850B1204626F00FD820466F
+:104EF000294626F015DA002001E06FF008003EBDDB
+:104F0000D0F8403570B55D8E064605F44063B3F5C4
+:104F1000406F22D1036893F8463013F0030F0BD093
+:104F200005F47041D0F85C01B1F5805F14BF002139
+:104F3000012141F0BFD980B92846FEF373F1044640
+:104F40002846FEF36FF144F430640E288CBF4FF412
+:104F500080504FF400500443A5B2326B05F4704307
+:104F60005268B3F5805F14BF00230123934205D03C
+:104F7000D6F85C01012140F0C1DC0546D6F85C01A1
+:104F8000294641F00BDA80B905F47043B3F5805F30
+:104F900014BF38233C23F358346BD6F85C013363D9
+:104FA000012140F0ABDC34630546284670BDC046A5
+:104FB00070B50025044680F8E85124F0BFDCE36AB0
+:104FC0002946986A8022FDF33BF0206905F048F8F5
+:104FD000D4F840012AF0A6DBC4F8885670BDC0465C
+:104FE0002DE9F04390F8A03187B00446002B40F043
+:104FF000ED8003681B7E002B00F0E880012380F821
+:10500000A031006904F0BAFD2269074692F8EA303F
+:105010005BB1D36ED3F8202140F2044302EA0303CC
+:10502000B3F5806518BF012503E0106E05F092FF0F
+:105030000546002D6FD1D4F8680104214FF0B8DA8D
+:10504000204621F0ABDD00B90137A94604EB090386
+:10505000D3F84C62002E59D096F80680B8F1000FB4
+:1050600054D1304633F072DB73793F18002B4DD0AA
+:10507000236893F83130002B3FD0D6F8CC3013F0B2
+:10508000010F3AD0204631460AF0D4F823683F1881
+:1050900093F89530002B39D0D4F86C122046BC31EF
+:1050A00050F07CDB0546002830D02046294621F010
+:1050B00093DF2B7E13F0020F19D0284602214FF008
+:1050C000BFDFB17CD4F86C32D1F1010138BF0021CF
+:1050D000082201920291204631460332BC33CDF8BA
+:1050E0000080CDF80C80CDF8108017F017DDD4F8D3
+:1050F0006C22012382F8F03008E02046314639F076
+:10510000BFDE3F184FF47A6001F026DB09F1040995
+:10511000B9F1200F9AD10025D4F8B434EA18136BF2
+:1051200013B1506A98473F18343540F2AC439D4262
+:10513000F2D194F8F1314BB1A068D4F8AC110AF077
+:105140008DDA00B90137002384F8F1312046FEF7EB
+:1051500095FA236800211976236B4FF0FF32C619A8
+:1051600018690AF023FE204615F092D9D4F8785237
+:1051700007E00023291D606801220093FDF362F619
+:105180002D68002DF5D1236893F82F3073B1631982
+:10519000D3F84C1239B18B792BB10B791BB1204666
+:1051A0000AF048F836180435202DF0D1D4F87C02E6
+:1051B00010B109F0E1FA3618206904F091FC0023DF
+:1051C000801984F8293084F8A03100E0002007B06D
+:1051D000BDE8F0832DE9F04F9DB005462798089271
+:1051E0000793827AC37A0F4642EA0323289A00F192
+:1051F0000C010C3A08980B9115930C92C27D837D9B
+:105200000DF1600943EA0223C3F3C70ABAF10E0F96
+:1052100094BF00210121109102794379079942EA54
+:105220000323099315F01EF9269A11900A321146AC
+:105230000A922846109A50F0BBDA0024804617AE36
+:1052400028462799289A4B461794189400961CF0E4
+:10525000E1DE30B928462799289A4B4600961EF081
+:10526000D9DEB8F1000F06D0D8F8043013F0010FE2
+:1052700001D00D9427E00C990B983222FDF31EF219
+:10528000014620B14078023120F0E4DE58B90C9993
+:105290000B980122FDF312F2014638B14078023139
+:1052A00020F0D8DE10B101230D9301E000200D9015
+:1052B000B8F1000F07D00D9929B9D8F8043043F0A0
+:1052C0000103C8F804300B980C990322FDF3F6F1A2
+:1052D000044608B14378A3B92B6893F83F3053B123
+:1052E000B5F82606C3B2534503D0FDF39BF75045EE
+:1052F00001D1012300E0002300225FFA83FB0E921C
+:1053000011E02B6893F83F3043B1B5F82606FDF362
+:1053100089F7A378834201D1012300E000235FFADB
+:1053200083FBCDF838B0BBF1000F01D15B4602E042
+:105330003B1E18BF01235FFA83FA2B6893F84630AF
+:1053400013F0030002D11290139024E095F872320A
+:1053500063B9BAF1000F09D0D7F8D432DB8813F063
+:10536000200003D112901390149018E00B990C9A1E
+:10537000284620F0E1DE0B9913900C9A284620F085
+:10538000A7DE2B68129093F94C0020B128460B99A8
+:105390000C9A1DF0CBDB1490BAF1000F69D02B688A
+:1053A00093F8463013F0030F63D0129B002B60D0AC
+:1053B000139800285DD019785A7828460FF0E2DD5E
+:1053C000B5F82696064609F47043B3F5005F0CBFA6
+:1053D00038233C23EC58D5F85C01616840F08ED945
+:1053E00010F0080F01D0002104E094F8EC30191EF1
+:1053F00018BF0121139A137813F0020317BF1298F4
+:105400001A464378C3F3800209F44063B3F5406F52
+:1054100018D1B5F82636B34202D100210F912EE003
+:105420002B6893F82F30002B40F04A843046FDF370
+:10543000F9F60446B5F82606FDF3F4F6844240F08A
+:105440003F8414E0A9B1A2B106F44063B3F5406F04
+:105450000FD12B6893F82F3073B93046FDF3E2F685
+:105460000446B5F82606FDF3DDF6844204D10F9616
+:1054700005E000220F9202E000230F939A462B6B67
+:105480005B7D002B3AD0BBF1000F37D095F872321C
+:1054900033B995F87432002B30D0BAF1000F2DD10A
+:1054A00095F849365BB1179B002B08DD189B1B78DC
+:1054B00013F0040F03D0D5F858260423136195F890
+:1054C000493653B10D9850B9159911F0200F0ED1EE
+:1054D000D5F858260423D36009E00D9A3AB1179BFA
+:1054E000002B08DD189B1B7813F0010F03D0D5F8B3
+:1054F000582604231362284625F06EDD2B6893F8A6
+:10550000463013F0030F46D0BBF1000F43D095F89F
+:10551000723233B995F87432002B3CD0BAF1000FD7
+:1055200039D1B5F8263603F44063B3F5406F14BFA4
+:1055300000210121129B13B90D9830B916E0129A7F
+:10554000937803F00303032B05D1D5F858260423E1
+:105550009361129B53B11298837803F00303022BDB
+:1055600004D119B1D5F858260233D362139A7AB10F
+:10557000129B6BB113985A78037813F0020F07D17E
+:1055800012F0040F04D019B1D5F858260423D362C1
+:10559000284625F0D3DD2B6893F82F30E3B1D5F8FA
+:1055A000FC341B78C3B10E99B1B9284613992FF07A
+:1055B00021D988B128460E992FF01EDA28462FF0FF
+:1055C00011DAB5F8263603F44063B3F5406F03D122
+:1055D000284601212FF082D9B8F1000F29D0D8F840
+:1055E000F03033B300230C997C4A0B9800931CF0E5
+:1055F00089DE41460246284620F0C2D82B6893F83F
+:10560000463013F0030F14D0139A2AB1149B284686
+:105610000093129B41460AE0D8F8043013F4803F0F
+:1056200007D01398139A00904146284613461DF060
+:10563000DDDA95F87032002B00F05B830FB93E463F
+:1056400001E0D7F8DC62BAF1000F77D02B6893F84D
+:10565000463013F0030F32D0BB7C43B9B8F1000FD2
+:1056600008D128460A99109A50F0BCD98046B8F162
+:10567000000F24D0139971B1149A129B00922846FE
+:105680004146139A1DF0B2DAB7F8343523F02003FF
+:10569000A7F834350DE0BB7C5BB9D8F8043013F4BF
+:1056A000803F06D0139B284641461A4600931DF0C2
+:1056B0009DDA28460B990C9A434620F087D8089922
+:1056C00028461EF069D941B238461EF0A7D938469F
+:1056D0001EF0FCD80899284612F0F2D90146384647
+:1056E00011F054D9BB797BB9D7F8E032D7F8D4227E
+:1056F000188A9B8A5085938573792BB9BB7C1BB123
+:105700003846012135F046DE0023B371F371BC7CCD
+:10571000A4B996F88530012B10D186F88540D5F8CC
+:10572000400126F00BDF284639460F22234600941D
+:10573000019402940394049417F0F0D9002F5AD0E6
+:10574000BB79002B57D1BB7C002B54D027992798CD
+:105750008B784A781B0443EA02230A781343CA78F9
+:10576000043143EA02698B784A781B0443EA022336
+:1057700002791343CA7843EA0264F26912B9336AC0
+:1057800013B935E0944204D3944231D1336A994538
+:105790002ED2DDF898E00023009301930293039347
+:1057A00004932846394616220EF1100317F0B6D995
+:1057B00038460899079A279B24F0B0DEBBF1000F0A
+:1057C00016D0FB7963B1BB7C23B107F1BC00FDF3BC
+:1057D000C3F028B907F1BC0104E0C046C3A601002C
+:1057E00007F1D601002228461346009222F038DC49
+:1057F000C6F82090F461BAF1000F00F01A82BB796C
+:10580000002B40F09181BB7C002B00F08D8116AB0A
+:10581000009327993846289A0DF16F0316F024DA81
+:10582000BDF85810D7F8E462A7F8201595F8EB41B9
+:10583000002C65D100284FD03378022B19D138467F
+:105840002146B6F8269009F037FAB5F8303885F8D1
+:10585000324803B1F38438461EF0B4DED7F8E432A0
+:10586000A6F826905B8B002B4AD0384611F070D9F1
+:1058700046E02B685B6B4BB195F8FA3133B1B8F168
+:10588000000F14D098F8D2300F2B10D0B27822B17C
+:105890002846394622F0E4DF32E04FF0FF33009330
+:1058A000284607F1BC01134622F0DADB28E095F820
+:1058B0000D372BB3B3785BB1B8F1000F05D0D8F832
+:1058C000043023F00063C8F80430384616F0AADA32
+:1058D000384623F0C7DC13E0337A23B1718911B95C
+:1058E000384623F0EDDCD7F8E4325B8B43B13378F4
+:1058F000022B05D1336A012B02D138461EF04EDE51
+:10590000F3781BB13846002123F0CEDB737A3BB924
+:1059100038460EF095D818B13846012123F0BCDD89
+:10592000737A5BB1099A3846C2F3C011279B119A6A
+:1059300024F09ADD3846002123F0AEDD2B6B5B7D31
+:10594000002B41D0159B2846C3F3802124F0AEDC08
+:10595000189A002A38D0179B002B35DDD5F8581639
+:1059600091F90130B3F1FF3F09D11378C3F340023D
+:105970000B78934203D0284601211FF0F9DF189BD2
+:105980001B7813F0040318BF012385F8463695F9F8
+:105990004636012B03D0D5F858361B690BB10023CE
+:1059A00000E0012385F84236B8F1000F0CD0D8F89A
+:1059B000043023F00402C8F8042095F946361BB9D8
+:1059C00042F00403C8F804302B6893F8463013F013
+:1059D000030F35D01298002832D0D5F8582692F906
+:1059E0000630B3F1FF3F26D1837892F9052003F00A
+:1059F00003039A4204D028460B211A461FF0B8DF51
+:105A000012998B78C3F38002D5F85836DB7993422C
+:105A100003D028460D211FF0ABDF129A9378C3F311
+:105A20000012D5F858369B7A934209D028461021A7
+:105A30001FF09EDF04E0012B0CBF032300235371F2
+:105A4000D5F85C01B5F8261640F070DA90B1D5F8BB
+:105A50005C01B5F826163FF0A9DE2B6B18690AF039
+:105A6000CDF9B5F82636834204D1002128460A46EE
+:105A70001EF092DAB8F1000F3FD0D8F8043013F0DE
+:105A8000400F00F029810B9B0C981A93199006E0A7
+:105A9000284621461AAA19AB1DF060DD40B91A98B4
+:105AA0001999DD22FCF30AF604460028F0D10CE136
+:105AB000A11C0E79012E40F00F818A7995F80C32E5
+:105AC00002F00F0203F00F039A4200F0058105F582
+:105AD0000074063420461822FCF34EF22B6893F82B
+:105AE00030303BB1D5F83407214600F563701822F9
+:105AF000FCF342F238463146ECE028460B990C9A0A
+:105B000010F084DB012802D128460EF015D90F9938
+:105B1000002900F0EE8095F86D35002B40F0E9800B
+:105B2000284617F0D7DFE4E0BB7C002B40F08180F3
+:105B30000D9A0AB1012102E0159BC3F34011CCB2CA
+:105B4000B8F1000F15D0D8F8043014B143F00403B5
+:105B500001E023F00403C8F804300C990023664ADE
+:105B60000B9800931CF0CEDB4146024628461FF0FE
+:105B700007DE2B6B5B7D13B3179B002B11DD189B8E
+:105B80001B7813F0040F03D0D5F8582604231361B3
+:105B9000189B1B7813F0020F03D0D5F85826042366
+:105BA00053620D9818B9D5F858260423D3611CB94F
+:105BB000D5F858260423D360284625F00DDA2B6843
+:105BC00093F8463013F0030F00F09380129941B11F
+:105BD0008B7803F00303032B03D1D5F85826013348
+:105BE0009362139ACAB1139852780378B5F82616BF
+:105BF00043EA022010F0100F03D1D5F858260423F1
+:105C0000536310F0020F08D101F44063B3F5406F05
+:105C100003D1D5F8582604231363129929B90D9A94
+:105C20001AB1D5F8582604235361284625F086DAA0
+:105C30005FE095F85735002B5BD0BBF1000F58D0D3
+:105C4000159B13F0020F54D00B980C990022FCF313
+:105C500035F5034600284CD02846991C5A7839F06F
+:105C600081DB0446002844D0837C002B41D1089975
+:105C7000079A16F0C7DD00283BD027982899269B65
+:105C8000D4F8D06203F110020090019128460899DF
+:105C90000123029620F066DB024650BB296BD5F843
+:105CA0006036503106F138009B784BF067D9289860
+:105CB00008990090079A2046279B34F047DC18E0AB
+:105CC00000218A460F91FFF7DABB022385F80E32D6
+:105CD000384601211CF064D800230C990B98064A21
+:105CE00000931CF00FDB4146024628461FF048DDBA
+:105CF00003E71DB0BDE8F08FC3A601002DE9F04F0A
+:105D0000D2F81080C1B0D8F8D8A2064609910892FE
+:105D1000DAF82C00DAF8301000220793FCF3CEF406
+:105D200020B1831C109342780B9205E0099A099BDD
+:105D3000093210921B7A0B932CAF0021282238468F
+:105D4000FCF37EF10021282222A8FCF379F1DAF895
+:105D500030100122DAF82C00FCF3B0F4DAF830103D
+:105D600004463222DAF82C00FCF3A8F405463CB1D4
+:105D70006278102A04D8381DA11C2C92FCF3FCF088
+:105D80003DB16A78102A04D823A8A91C2292FCF3FA
+:105D9000F3F0099AD38813F0010F0BD0316B4B7DD0
+:105DA00043B10A6D2DA854312C92FCF3E5F0002389
+:105DB000229309E022AB0093099B304603F138029D
+:105DC00041462CAB20F042D8B8F86250DAF82C40AB
+:105DD000B5F5806FDAF8307059D0B5F5006F04D1A1
+:105DE0000022934611920C9257E020463946FDF36B
+:105DF00071F2119020B143784FF0000B0C930BE03F
+:105E0000204639463022FCF359F4834610B9119AE2
+:105E10000C9201E043780C93402D09D0802D07D0DF
+:105E2000102D05D0B5F5807F02D0B5F5007F33D1B8
+:105E3000D8F8582040F2371302EA030363B30C9AF0
+:105E4000BBF1000F08BF1422402D0C922ED14FF051
+:105E500000094F4616E0162307FB03F303F5B4735E
+:105E600008EB03040998211D0622FCF369F040B9F0
+:105E700040AB03EB890204F10A0342F8B83C09F194
+:105E800001090137D8F8CC329F42E4D310E0002258
+:105E9000934611920C9200E045B1D8F8582040F298
+:105EA000371302EA03030BB118230C934FF00009D8
+:105EB00040F2EE5301933FAB0293079B099A002BEC
+:105EC00014BF20210021304608F1C20300921CF0CB
+:105ED00073DA0D9030B930460D99B8F80C2332F0D2
+:105EE000FDDD83E23F9A304602F5BC630E330A9231
+:105EF0004146099A0E93FDF735FA0A9A1070C0F3DD
+:105F00000F2050709AF8223093709AF82330D37093
+:105F1000131D3F93079B8BB10AF124042046FCF329
+:105F20001BF510B93F98214602E03F9808F1D601D1
+:105F30000622FCF321F03F9B06333F933F9A00215A
+:105F40000F921046109B0B9A26F00ED92DAB012113
+:105F50002C9A3F9026F008D90C9B3F90002B7CD0C8
+:105F6000BBF1000F11D0B9F1000F03D030465946F4
+:105F7000FDF724FA3F9C5946204617F0C7DB3F90B7
+:105F80009BF80130A346637019E0402D09D0802DA5
+:105F900007D0102D05D0B5F5807F02D0B5F5007F74
+:105FA0005BD1A649834617F0B1DB099B3F9003F113
+:105FB0007B02304641460BF1040313F015DA402D05
+:105FC00009D0802D07D0102D05D0B5F5807F02D0E7
+:105FD000B5F5007F41D1B9F1000F01D14C4626E063
+:105FE0009BF801300BF1020202F80390D7184FEA38
+:105FF00019237B709BF80130002402338BF80130A9
+:106000003F9B02333F9312AB07EB041053F824106D
+:1060100002301022FBF3B0F79BF80130013410334B
+:106020008BF801303F9B10334C453F93EBD1D6F8B2
+:106030006C32D3F8D8325B68022B0ED16CB10022DF
+:1060400000920192CDF808B09BF80130304602333F
+:106050000393572113461DF02BDD229A2AB13F9856
+:10606000322123AB26F080D83F90DAF82C401CE098
+:106070006278C1F102031B199B18671C83421CD86C
+:10608000119BA34219D02378012B0BD9302B09D0B7
+:1060900002323F982146FBF36FF73F9B6278023351
+:1060A0009B183F933B78A21CD41834B1DAF82C101B
+:1060B000DAF830000B189C42DAD3336893F8463094
+:1060C00013F0030F18D0089A536813F4803F13D0CD
+:1060D000326B0DF1DB041368404621466532022B1A
+:1060E00014BF0023012325F0A1DF3F982D211A22A0
+:1060F000234626F039D83F9096F8653633B106F539
+:10610000CC613F98043117F001DB3F90336893F87E
+:10611000463013F0030F1FD0089A536813F4803FE2
+:106120001AD0326B0DF1DB0113684046022B14BF0D
+:1061300000230123653225F079DF3F990E9B8B42C6
+:1061400001D2002202E00E9BC1EB030230460DF1AA
+:10615000DB0325F029DE3F9033685B6B4BB3099A74
+:10616000D38813F0040F24D00DF1F5003449032235
+:10617000FBF302F702238DF8F83000238DF8F93095
+:1061800001338DF8FA3096F8FA313BB1099A92F959
+:106190006A30002B02DA96F80A3700E000238DF807
+:1061A000FB303F98DD2107220DF1F50325F0DCDF00
+:1061B0003F90B5F5806F02D0B5F5006F06D1D8F8E5
+:1061C0002C3543B33F98D8F8281505E00C9B13B342
+:1061D000119A2AB13F98114617F098DA3F901AE0C9
+:1061E000402D18D0802D16D0102D14D0B5F5807FFD
+:1061F00011D0B5F5007F0ED03F9C1249204617F014
+:1062000085DA099B3F9003F16B023046414604F169
+:10621000080313F0E9D86B1E9BB2012B03D9042DA0
+:1062200001D0082D10D1099A506E002838D0B2F84C
+:1062300068100C300C39FDF34DF01BE0CCD285001A
+:10624000CBA60100E2D28500402D09D0802D07D0D9
+:10625000102D05D0B5F5807F02D0B5F5007F1FD198
+:10626000099B586EE0B1B3F868100C300C3930223D
+:10627000FCF324F2A0B1D6F86C32D3F8D8325B68C4
+:10628000022B0DD14378102B0AD902330022029041
+:106290000393304657210123009201921DF008DC40
+:1062A000D8F8583013F0040F01D004230EE013F097
+:1062B000020F01D0022309E013F0010F01D00123E6
+:1062C00004E013F4807318BF4FF48073089A1364CA
+:1062D000336893F8463013F0030F2DD0089A136CEF
+:1062E000013B012B09D8536813F4802F05D01146C8
+:1062F0003046062224F0D4DC1EE0089A536813F4DA
+:10630000802F19D011463046062224F06DDC30462D
+:1063100016F09ADE012801460ED1D6F8F83742F27F
+:106320000E721B88013B9BB2934202D83046013962
+:1063300000E0304628F0CADE3F9C0E9BA34201D20B
+:10634000002302E00E9AC4EB020300932023019382
+:10635000002123464FF0FF32404639F0E5DE0F9B27
+:1063600000273F90C01A03930490414655223B46B4
+:10637000304600970197029716F0D0DB0A9A3F9BB0
+:10638000A2F11805C5EB0304DAF834100D9B9C82CA
+:1063900021B17068DAF8382000F0AADC0A9A706837
+:1063A000C5EB0203E41A214600F092DCCAF834007F
+:1063B00040B1079BCAF838408AF83C300A99224617
+:1063C000FBF3DAF5099A3046B2F862300197C3F36D
+:1063D000401300930297089B0D99D6F804281FF0EC
+:1063E000A1DB0D9B002808BF00230D930D9841B041
+:1063F000BDE8F08F2DE9F04F93B006911969059231
+:1064000004930A9101F1060A8A799AF80130064646
+:1064100042EA0323059A0793C0F87828C3F381055D
+:1064200013465B79127942EA0323089303F00303CE
+:10643000022B08D1079C14F4004F04D0D5F10103BE
+:1064400038BF002300E00023DBB204990B930B9AC2
+:106450008B8AA3F10A0993001DB918339945C0F23C
+:10646000A881079B03F0FC08B8F1A40F05D0B8F190
+:10647000840F02D0B8F1940F03D1B9F10F0F40F39C
+:1064800098810AF1040409949AF8043013F0010386
+:106490000C9303D000210F460D9108E03046099976
+:1064A00038F03CDF021E18BF012207460D9225B1CD
+:1064B00000239B460E930F9310E00AF11004304620
+:1064C000214638F007DF0E9010B183460F9505E0A6
+:1064D0003046214638F068DF83460F9096F8C83181
+:1064E00023B9326892F82C3033B92AE03046059946
+:1064F000049A00230FF084DCB8F1A40F05D0B8F1A2
+:10650000840F02D0B8F1940F01D10D9C5CBBB8F19F
+:10651000800F28D0B8F1500F25D0002D40F04883CF
+:106520000D9901BB0998FCF307F2002800F04083A5
+:10653000BBF1000F17D10AF11000FCF3FDF190B987
+:1065400036E30C9B7BB90D9C3CB192F8383053B1CB
+:106550004DB9BBF1000F06D12FB9D2F88C20936F43
+:106560000133936724E396F8C8317BB9BBF1000F80
+:1065700001D05C4601E0D6F86C4294F8E5302BB1CE
+:1065800030460599049AA3680FF03ADC012D12D128
+:10659000B8F1C40F0FD0B8F1D40F0CD00AF10A0033
+:1065A000FCF3DAF1002840F003839AF80A3013F084
+:1065B000010F40F0FD82049930460B69A1F8149058
+:1065C00006330B6133685146D3F88C20D36C01330A
+:1065D000D3641FFA89F30093059A11AB11F088DF99
+:1065E00030B13368D3F88C20D36F0133D367DFE247
+:1065F000119A12B133689B6A1362012D3DD1049A3E
+:10660000049B1069998A00F11002049C1A61A1F19F
+:106610001003A3820B9B2BB100F11402A1F1140310
+:106620002261A3820499B8F1A40F8C8A0FD1119929
+:106630000B699B79002B00F0BB8291F8DF30002BB7
+:1066400000F0B6823046079A2FF0F2DCB0E23368F1
+:1066500093F84230002B00F0AB82B8F1840F03D0E6
+:10666000B8F1940F40F0A482D6F840011199234666
+:10667000CDF8008028F0D4DE9AE2059B0C9C9A7D30
+:10668000DB7D42EA0321002C66D19AF816309AF895
+:10669000172043EA0227119B5BB9C1F3C7023046BA
+:1066A0000AF10A010E2AD4BF002201224FF080D83D
+:1066B0001190079911F4006905D0119B1BB1B3F833
+:1066C000BC30BB4225D0119B0BB1A3F8BC70119B11
+:1066D0008BB141E006EBC20303F5F3642046FCF303
+:1066E0003BF170B90AF10A0021460622FBF328F4B7
+:1066F000013508B906E01D4696F8E837EAB293423C
+:10670000E8D20024B9F1000F0CD064B1E388BB4299
+:1067100021D13368D3F88C20D2F8BC310133C2F8D0
+:10672000BC3145E2BCB996F8E8370AF10A0106EB3C
+:10673000C30202F5F364013386F8E83706222046E7
+:10674000FBF31AF496F8E8170A23B1FBF3F202FB05
+:10675000131386F8E837E7800D9A62B10E9B53B1A8
+:106760009BF806303BB9DBF8E4321B7A1BB1584684
+:10677000079910F0C9DD049C2069A18A00F1180274
+:10678000226191460B9AA1F11803A38232B100F164
+:106790001C02A1F11C032261A3829146049C07996B
+:1067A000089BA78A11F48044C3F3C0150DD0072FAE
+:1067B00006DC3368D3F88C20536E01335366F7E15F
+:1067C000B8F1B00F40F0F48130E0B8F1500F00F0B4
+:1067D000848013D8B8F1200F00F0B98107D8B8F140
+:1067E000000F00F0B481B8F1100F49D0E0E1B8F12A
+:1067F000300F45D0B8F1400F57D0D9E1B8F1B00F04
+:1068000011D007D8B8F1800F7ED0B8F1A00F00F0FA
+:106810003E81CDE1B8F1C00F00F09681B8F1D00F04
+:1068200000F0B481C4E1052F40F3BC81BBF1000F3F
+:1068300000F0BE819BF806309BB19BF80430002B22
+:1068400000F0B681059A00970195137CD6F83407BD
+:1068500003F008030293594652464B462CF0A6D942
+:10686000A6E1D6F8403593F93430002B00F0A08132
+:10687000584651464A463B46009532F0A9DB97E11F
+:10688000052F40F38F81BBF1000F00F091819BF841
+:106890000630002B40F08C81119B584600935146E6
+:1068A0004A463B4632F052D982E1336893F895303C
+:1068B00023B996F87232002B00F07A8107F11803A1
+:1068C000039330462C210AF10A02234600940194D6
+:1068D000CDF808A01DF0ECD86AE10B2F40F36281DF
+:1068E000D6F868319B79002B00F062810D9B002B5C
+:1068F00000F05E81304605990A9A5346CDF8009023
+:10690000019710F063DE53E10B2F40F34B810A9B9C
+:1069100030460E99059ACDF800A0CDF80490029764
+:10692000FEF758FCD6F868319B7943B1304605999B
+:106930000A9A5346CDF80090019710F047DE96F87A
+:106940007232002B2ED199F80A3013F0010F29D0A2
+:10695000304649463A4616F05DDF18BB059CA37DDC
+:10696000E27D43EA0223C3F3C7040E2C8CBF00234D
+:10697000012363B109F10C00A7F10C010322FBF321
+:106980009DF678B143786BB18378A3420AD1336B1B
+:10699000186909F033FAC0B2844203D1D6F868010D
+:1069A0004DF0CEDF0F9909B10D4607E030460AF1F0
+:1069B000100138F0F9DC0546002844D0AA79002AF5
+:1069C00041D109F10C00A7F10C01D5F8D842D5F856
+:1069D000DC82FBF373F6A26882460B2A07D12846B5
+:1069E00005990A9A4B46009733F0B0DD0CE0336806
+:1069F00093F8313043B10F2A06D1284605990A9AF7
+:106A00004B46009734F072D9AB7CE3B198F85A301A
+:106A1000CBB1D6F86801514601224EF039D830B1D9
+:106A200098F859301BB9013388F859300BE0D6F883
+:106A30006801514601224EF02BD820B998F8593000
+:106A40000BB188F859000E9A002A00F0B180DBF8EB
+:106A5000D8329B680C2B40F0AB804B4658460599CA
+:106A60000A9A23F05BDD5846002131F025DF3368B8
+:106A700093F82F3023B1D6F834072EF04BD997E096
+:106A8000DBF8E4325846997808F016F990E0012FC7
+:106A900040F38880BBF1000F00F08A809BF806303D
+:106AA000B9F80050002B2BD13046119920F094DA20
+:106AB0001198037E13F0020F13D002214EF0C0DABA
+:106AC000119B1B7E13F0080F0BD13046594622460E
+:106AD0000AF10A0300950194CDF80890039707F096
+:106AE0006FFF0E9B002B63D0DBF8D8329B6813B18D
+:106AF000584631F02BDE5846032134F04BDC57E08A
+:106B000011990B695B4553D1304620F065DA119835
+:106B1000037E13F0020F13D012214EF091DA3046AB
+:106B2000594622460AF10A0300950194CDF80890CF
+:106B3000039707F045FF304611994EF041DE37E0EC
+:106B400010214EF07DDA33E0012F2BDD30E0032FF2
+:106B500028DDBBF1000F2BD09BF8043043B39BF82A
+:106B600006302BB30AF110000BF1BC010622FBF337
+:106B7000E7F1E8B9119BD6F834070193594652461C
+:106B80004B460097029508F06BF911E00A99059CB5
+:106B900002913046119952464B460097019410F0ED
+:106BA0000DDC05E03368D3F88C20136F01331367D5
+:106BB00006980499002200F0B3D813B0BDE8F08F16
+:106BC0002DE9F04F436899B0164689460493918B9E
+:106BD00096F82A30126880460292D9F810A00BB9B4
+:106BE000059302E096F82220059296F82C00B0B9A1
+:106BF00011F4006F13D0059A09EB4203B3F8AC20EF
+:106C0000B6F87E309A420AD1D8F80030D3F88C20FA
+:106C1000D2F8BC310133C2F8BC3100F082BC9AF822
+:106C20000630C1F3802B0BBBDAF8E442237A6BB158
+:106C300060B9BBF1000F09D199F8D230726A1341E3
+:106C400013F0010F02D1504610F05EDBD8F800308F
+:106C50005B6B5BB1237E4BB196F82A3033B196F86B
+:106C600028301BB15046002121F094DE338C13F004
+:106C7000040440F05684B38B03F4804373634BB930
+:106C8000DAF8582040F2371302EA03032BB39AF8DC
+:106C9000603013B3059BB4630093404604994A46A1
+:106CA00033464FF035DF08B122460EE0736B23B157
+:106CB000D9F86C310133C9F86C31D8F8003093F849
+:106CC0009530002B00F02D840122736B33B1D9F87D
+:106CD00068310133C9F8683100E0002296F82C30A1
+:106CE0000BB1002708E0059909EB4103B6F87E10C7
+:106CF000B3F8AC70A3F8AC10D8F8000090F8953059
+:106D000013B1002A40F00D8496F82C50002D40F06D
+:106D10000081B6F87E20059B12F00F0C4FEA830E1F
+:106D200040F081800EEB0907F96E41B104982A46C4
+:106D3000FFF3F6F7FD66C7F88C50C7F83051BBF18A
+:106D4000000F00F0E6807369F168FB66D8F8003048
+:106D50007269DB6903919C681169D368908ACB18CA
+:106D600092681B189B1A09185B1AA34223DA04982D
+:106D7000214600F005D8F866002800F0D283736938
+:106D8000006919699C689A8AC4EB0104091BA2185E
+:106D9000FBF3F2F07169FA6E08698B68C01A136927
+:106DA0001B181361938A1B1A93828B8A049893820F
+:106DB0002A46FFF3B5F7D8F80030D8F82828DB6961
+:106DC00003999B68AA489B1A5B1A063BC7F88C304C
+:106DD00071680822FBF3B4F050B1A648716806222E
+:106DE000FBF3AEF048B97368DB88B3F5407F04D19C
+:106DF000D9F8043043F0080303E0D9F8043023F055
+:106E00000803C9F804309C4871680822FBF398F025
+:106E1000D9F8083010B943F0200301E023F0200333
+:106E2000C9F8083075E00EEB0904E16E11B9D0F82D
+:106E30008C2017E022F00F0227F00F039A4204D1B2
+:106E400007F00F0301339C4510D02A460498FFF346
+:106E500067F7D8F80030E566D3F88C20C4F88C507A
+:106E6000C4F83051136E013313665AE3B068D4F896
+:106E70008C309842E9D8049B09EB0E0200900193F4
+:106E800040468C3273680CF0ABD8049871692A467E
+:106E9000FFF346F7BBF1000F3BD1E36EC4F88CB0B3
+:106EA0007361C4F86CB07369C4F830B11A69998A17
+:106EB00002F118037360A1F11803B36096F829304A
+:106EC0003260F1602BB102F11E037360A1F11E0369
+:106ED000B36096F82A3043B1736805990233736042
+:106EE000B36886F82210023BB36032681378527898
+:106EF00043EA0223B383736B5BB1B16B49B191F980
+:106F00000E2073689B18736091F90E20B3689B1A6A
+:106F1000B360B36B73B11B7A042B03D14046314687
+:106F20004FF0A4DEB36B1B7A0B2B03D140463146E6
+:106F30004FF0B8DFBBF1000F40F04D83D8F80030C0
+:106F400093F89530002B73D0DAF808309B7913F062
+:106F5000010F40F005836BE010F4000F00F4E063D4
+:106F600010D01B0A043B012B444A00F07F0004D8D8
+:106F7000142300FB0323DA6814E0142300FB03232B
+:106F80009A680FE01B0A043B012B3C4A00F07F008B
+:106F900004D8142300FB03235A6803E0142300FBE6
+:106FA00003F39A584FF4FA73B2FBF3F007E000F0E2
+:106FB0007F034FF4FA7203FB02F3B3FBF2F0C0F36A
+:106FC00007238DF825300DF11B05C0F307438DF81D
+:106FD00024008DF826300127030E316805F10F00DB
+:106FE00018228DF827308DF82970FAF3C5F796F836
+:106FF0002F30DBB19DF82B209DF82A3005F11904C4
+:1070000043EA022343F400738DF82A3021461B0A19
+:10701000062205F11F008DF82B30FAF3ADF7D8F8F2
+:107020006C122046BC310622FAF3A6F7BB4601E0FB
+:107030004FF0000BD8F8003093F8953013B91C4688
+:107040001A4602E00DF11B042D2273695B6A13F0EE
+:10705000400F15D013F0800F00F063820092D8F833
+:107060003C0149463246234629F0F2DDB3E2C046F0
+:10707000401E8600E0A60100481E86008418860097
+:1070800031680DF15A07043106223846FAF374F7D5
+:10709000316815AD0A3106222846FAF36DF73168DA
+:1070A0000DF14E04204610310622FAF365F796F8EA
+:1070B00029302BB1316812A818310622FAF35CF797
+:1070C000B38B13F4807F03F4007305D1002B14BF3E
+:1070D00023462B46776704E074670BB9356701E0F8
+:1070E00012AB33677468BBF1000F00F003813368A3
+:1070F000F3662378AA2B23D16378AA2B20D1A37817
+:10710000032B1DD1E378DBB92379CBB9637943B97C
+:10711000A379E179404641EA03210BF0D5DB50B178
+:107120000EE0F82B0CD1A379E179404641EA032126
+:107130000BF0CADB20B1A279E37943EA022500E033
+:107140003589D8F8003093F89530D3B1DAF8E030CB
+:107150005BB9736BABB9DAF8582040F2371302EA27
+:10716000030373B19AF860305BB1059A404601920F
+:1071700049465246334600950DF006DA002840F0A5
+:10718000D081B36B6BB11B7A012B0AD0032B08D0D3
+:10719000404604994A46334607F05EFC002800F05A
+:1071A000C081736F1B7813F0010F08D0D8F800303E
+:1071B000D3F88C20D2F8D0310133C2F8D031B36B80
+:1071C00033B11B7A022B03D1404631464FF04EDDDE
+:1071D000726B22B996F82A3023B3144602E0B36BDF
+:1071E00093F90E4096F82A305BB1336802341A786E
+:1071F000597842EA012222F0800292B21A70120AF1
+:107200005A707368581E03E063421B5C00F8013932
+:1072100071690A699042F7D28B8A12191B1B0A61A5
+:107220008B82326096F82F30BBB130684278037899
+:1072300000F10A0443EA022343F4007303701B0ABB
+:107240004370214606221030FAF396F6D8F86C12F5
+:107250002046BC310622FAF38FF69AF9103093B12A
+:1072600048F68E039D420ED13168726BDAF80C003D
+:107270001231003A18BF01220AF1180351F092DED0
+:10728000002840F04E819AF830358BB148F68E03D5
+:107290009D420DD13168726BDAF814001231003A58
+:1072A00018BF01224B4606F013F9002840F039813F
+:1072B00071690A698B8A9B18CA68D21A2C2A40F213
+:1072C000308100238DF829308B8A08692D22181807
+:1072D0000DF11B01FAF350F6716996F82220CB8A62
+:1072E00002F0070223F007031A43CA8296F8292006
+:1072F000009110E1D6F814B02378DBF81070AA2BB7
+:10730000C7EB040529D16378AA2B26D1A378032BD8
+:1073100023D1E3780BBB2379FBB9637943B9A37914
+:10732000E179404641EA03210BF0CEDA50B114E096
+:10733000F82B12D1A379E179404641EA03210BF001
+:10734000C3DA50B17269A91F7B18CBF81030938A49
+:107350005B1A93821369F36628E0DAF8583013F069
+:10736000200F0FD020469D490822FAF3E9F548B9CD
+:107370007269281D1169938A09181B1A1161938279
+:10738000F16613E07269A5F10E00938A11691B1A68
+:10739000938233890918116103F0FF021B0A43EA43
+:1073A0000223F1660B73C3F30F234B73B36B6BB103
+:1073B0001B7A012B0AD0032B08D0404604994A4679
+:1073C000334607F049FB002800F0AB80B36B33B1C4
+:1073D0001B7A022B03D1404631464FF047DC062290
+:1073E000716FF06EFAF3C8F5F06E06220630316F59
+:1073F000FAF3C2F5716996F82220CB8A02F00702EF
+:1074000023F007031A43736FCA821B7813F0010F2E
+:1074100008D0D8F80030D3F88C20D2F8D03101331E
+:10742000C2F8D0319AF8613093B199F8183013F05E
+:10743000100F0DD1F36E1A7B5B7B43EA022348F6F3
+:107440008E02934204D073695B6A13F0100F68D008
+:107450009AF86530BBB199F8183013F0100F12D1BB
+:10746000F36E1A7B5B7B43EA022248F6B4039A422E
+:1074700009D0263B9A4206D073695B6A002B02DB77
+:1074800013F0100F4DD09AF8063023B9DAF8E42241
+:10749000013382F82A3098F83238013388F83238CC
+:1074A0009AF91030EBB1F16E0B7B4A7B42EA032272
+:1074B00048F68E039A4214D10B8A03F0FF021B0A8E
+:1074C00043EA0223B2680C3A93422AD8726BDAF884
+:1074D0000C00003A18BF01220AF1180351F062DDD6
+:1074E000F8B99AF8303593B1F16E0B7B4A7B42EADA
+:1074F000032248F68E039A4209D1726BDAF814001F
+:10750000003A18BF01224B4605F0E2FF48B9736903
+:1075100096F82920009340464946736F1FF034D9EE
+:1075200059E0D8F80000436BA3B171692C4ACB8AAB
+:10753000D0F8904003F00703D25C2A4B04989B5C80
+:1075400004EBC304636EA56E01336366FBF362F65E
+:107550004019A066049871690022FFF3E1F33AE054
+:10756000D8F8303005991A8940468DF81B20130A47
+:10757000120E8DF81C308DF81E200023B2698DF894
+:107580001D30937DD27D43EA0223C3F3C7038DF8F8
+:107590001F3009EB410393F8AC30D6F8801003F0AC
+:1075A0000F0301338DF828301CF0F6D9029A40B24F
+:1075B000030E8DF82000911FD6F880008DF8213041
+:1075C0008DF822308DF8233012F04CFF10F0006F50
+:1075D0007FF4C2ACEBE419B0BDE8F08FF7E38500AF
+:1075E000C4D2850098E085002DE9F04F0024A7B0B3
+:1075F0008DF832408DF83B408DF838408DF8704062
+:107600008DF83F409A4609939B8A0546212B0291AB
+:107610001746259412940D940A9224921B9450D9E3
+:10762000DAF810901046494612F01CFF09F10602E4
+:1076300003900492527899F8063043EA0223ADF899
+:107640002C30C3F38103ADF82E30BDF82C30C3F3DA
+:10765000031203F44073B3F5407F14BF00230123EA
+:107660008DF83930BDF82E30ADF83020022B0ABF2E
+:10767000BDF830302346C3F3C0038DF83A303B7970
+:1076800003F00303022B08D1BDF92C30002B04DAE0
+:10769000BDF83030C3F3C00300E00023D9B29DF839
+:1076A00039009DF83A308DF83B1000280CBF22229B
+:1076B000282203B1023201B10432099B9B8A934212
+:1076C00006D22B68D3F88C20536E01335366A5E3A2
+:1076D00004990B7903F001038DF83C3020B10023AD
+:1076E0001E468DF8403015E0BDF82C3013F4807F35
+:1076F00001D0043105E013F4007F01D00A3100E02D
+:107700001031284637F0E6DD031E18BF0123064678
+:107710008DF840309DF83C303BB90499284604313F
+:1077200037F0FCDD08B1012400E0002495F8C831F1
+:1077300023B92B6893F82C3033B92FE0284639460B
+:10774000099A00230EF05CDB2B6893F83F300BB9ED
+:107750008DF8403054BBBDF82C3013F4807F05D138
+:107760009DF83C3013B19DF840303BBB9DF839305B
+:1077700013B19DF83C300BBB2B6893F82C30002BD9
+:1077800000F04C839DF84030002B00F04783B37924
+:10779000002B40F043834FF0010B11E09DF83C308B
+:1077A0001BB9002C00F03A8300E03CB19DF8393061
+:1077B00023B99DF84030002B00F030834FF0000BD0
+:1077C0002B6893F895304BB346B39DF83C30D6F810
+:1077D000DC405BB914F0010F00F02083049806F13F
+:1077E000C20104300622FAF3ABF314E0049804302B
+:1077F000FBF3A2F020B114F0080F00F00F830DE0AE
+:1078000014F0040F0AD114F0020F00F00783284689
+:1078100004990EF061DA002840F00083099A136998
+:1078200006331361938A063B9382049A02F118038C
+:1078300005939DF8393013B102F11E03059300231F
+:107840008DF83D309DF83A306BB3059B5A781B7824
+:1078500043EA0221C1F3C0138DF83D307BB126B15C
+:1078600096F81935002B40F0D98295F8CF31002BCE
+:1078700000F0D482099A536A43F040035362844B68
+:1078800001F007028DF832209A5C824B9B5C0D93CD
+:10789000C1F300138DF83830059B023305939DF832
+:1078A00032308DF870309DF83D3023B9099A938AB3
+:1078B000043B938206E002980999FBF323F1838A43
+:1078C000043B8382099A059C938A12690793A41A40
+:1078D0001B1B514602980693FBF39CF40499001B72
+:1078E00008908B7DCA7D43EA0223ADF88E30BBF150
+:1078F000000F2ED1079B284600933A4625AB10F087
+:10790000F7DD002840F08A82BDF82C3013F4407F68
+:107910003BD1BA7DFB7D049942EA0322C2F3C70240
+:1079200028460A310E2AD4BF002201224EF05AD82E
+:10793000259030B92B68D3F88C20D36E0133D366F1
+:107940006CE20369D3F8CC30C3F3C0138DF83F3039
+:107950001BE0BDF82C3013F4407F16D09DF8393071
+:107960009BB9259B8BB9BA7DFB7D284642EA032251
+:10797000C2F3C7020A310E2AD4BF002201224EF000
+:1079800031D82590002800F04982259B1C69D4F845
+:10799000DC82BBF1000F23D19DF8393003BB9DF889
+:1079A0003C3023B1BDF82C3013F4807F11D1A37982
+:1079B000BDF82C201BB112F4807F0AD010E0A37C0C
+:1079C00002F44072002B14BF4FF4007300239A425C
+:1079D00006D02B68D3F88C20936D013393651DE29C
+:1079E00095F82D370AF1240A33B99DF83F1019B9DB
+:1079F000A3790BB10E4608E0284639461BF0CCDFD0
+:107A0000C0B246B208B18AF80900A379FBB99DF863
+:107A10003F30E3B9314620461CF000D820461BF029
+:107A200055DF3946284610F04BD8014620460EF067
+:107A3000ADDF9DF8403053B1A37C43B1E37933B15E
+:107A400098F805301BB92046012133F0A3DC95F8E6
+:107A50002D3733B99DF83F301BB9259BD3F8FC3047
+:107A600073B16EB1259AD2F8F810D2F8F43043F819
+:107A70002160D2F8F830013303F00703C2F8F83080
+:107A80009DF8393043B1B4F86200ADF8780040E0B9
+:107A9000C4D2850098E08500A3792599002B35D0C4
+:107AA0008A8FADF878204A6812F0400F20D09DF8F8
+:107AB0003A30EBB1049B9B7D13F00F0F18D191F876
+:107AC000DF30ABB18B7E13F0010F11D1BDF82C303C
+:107AD00013F4805F0CD012F4003F09D00D9A91F896
+:107AE000D130134113F0010F02D028462DF0EEDE05
+:107AF000BDF82C30259913F4805F15BF4B684B6897
+:107B000043F4003323F400334B6002E0898FADF877
+:107B1000781095F82D371BB9259BD3F8FC3073B13D
+:107B20006EB1259AD2F8F810D2F8F43043F82160FB
+:107B3000D2F8F830013303F00703C2F8F830259B80
+:107B4000D3F87C1159B1D1F80836039801EB8302C0
+:107B5000013303F03F03C2F80C06C1F80836A379DD
+:107B60005BB9A37C4BB19DF83C3033B9BBF1000F3E
+:107B700003D188F806B088F807B09DF83C30FBB117
+:107B8000A379002B40F04A81A37C4BB1296804986B
+:107B90004E3110300622FAF3D3F1002800F03E8176
+:107BA00004980430FAF3C8F650B92B6893F83E30C5
+:107BB00033B9284604990EF08FD8002840F02E8162
+:107BC000039ACAF814209DF83C308BB999F802202A
+:107BD00099F80130134399F800201A4308D0BB7C70
+:107BE000FA7CD5F86001039943EA02224BF0DCD914
+:107BF000DAF8142012F0006F26D012F4000F02F40D
+:107C0000E06310D01B0A043B012B964802F07F0270
+:107C100004D8142302FB0303DA6817E0142302FBE1
+:107C200003039A6812E01B0A043B012B8D4802F003
+:107C30007F0204D8142302FB03035A6806E01423CE
+:107C400002FB03F31A5801E002F07F02864B1A6030
+:107C500099F90330002B07DA2B68D3F88C20D2F87F
+:107C6000D8320133C2F8D83299F8033003F0300328
+:107C7000102B07D12B68D3F88C20D2F8E0320133D7
+:107C8000C2F8E0329DF83C30002B40F09780DAF8E3
+:107C900014102B6811F0006FD3F88C2026D011F44B
+:107CA000000F01F4E06310D01B0A043B012B6D4868
+:107CB00001F07F0104D8142301FB0303D96817E006
+:107CC000142301FB0303996812E01B0A043B012BF8
+:107CD000644801F07F0104D8142301FB03035968B1
+:107CE00006E0142301FB03F3195801E001F07F01C2
+:107CF00016293AD00CD80B2925D004D8022916D041
+:107D000004291AD05AE00C2923D0122927D055E093
+:107D100030293CD004D818292DD0242931D04DE069
+:107D2000602940D06C2944D0482936D046E0D2F8AA
+:107D300070320133C2F8703240E0D2F8743201334D
+:107D4000C2F874323AE0D2F878320133C2F87832AD
+:107D500034E0D2F87C320133C2F87C322EE0D2F823
+:107D600080320133C2F8803228E0D2F88432013305
+:107D7000C2F8843222E0D2F888320133C2F8883265
+:107D80001CE0D2F88C320133C2F88C3216E0D2F803
+:107D900090320133C2F8903210E0D2F894320133BD
+:107DA000C2F894320AE0D2F898320133C2F898321D
+:107DB00004E0D2F89C320133C2F89C3225994B681A
+:107DC00013F4802F0BD09DF83C3043B9BBF1000F6A
+:107DD00005D1D5F8400104AA00F02EFA03E02846A8
+:107DE00004AAFEF7EDFE049B1B7C13F0010F05D1E6
+:107DF000259AD2F858310133C2F85831049B1B7CC4
+:107E000013F0010F05D0259AD2F85C310133C2F886
+:107E10005C31259B0398C3F864011FE02868436B1D
+:107E2000BBB19DF83C30A3B90999104ACB8AD0F870
+:107E3000904003F00703D25C0D4B02989B5C04EB6F
+:107E4000C304636EA56E01336366FBF3E3F140196F
+:107E5000A066029809990022FEF362F727B0BDE8F8
+:107E6000F08FC04684188600C8F40100C4D2850093
+:107E700098E085002DE9F341089C05460E4617461B
+:107E80009846009407F0D2FA10F1170F06D1284651
+:107E900031463A464346009408F0A2DABDE8FC8138
+:107EA0002DE9F0410368054693F83F30D0F80C8087
+:107EB00013B1B0F8267602E0FDF722F8074600225B
+:107EC0002869394602F086F85621286935F0A8DB82
+:107ED000D5F888314000002BC5F8040506DA28697A
+:107EE000B22135F09DDB4000C5F80805A2212869C4
+:107EF00035F096DB4000C5F8EC07284614F058D85A
+:107F000095F8CD313BB928694C2135F089DBC0F3B8
+:107F1000C71085F8CD0128461EF0B0DD28463FF099
+:107F200081DA002605EB8603D3F84C422CB12046BB
+:107F300020F060DF204620F053DD0136082EF1D11D
+:107F40002B6893F83F309BB1002205EB8203D3F8F6
+:107F50004C0250B1037943B1D0F8D432DB8D1B040D
+:107F6000C8F8883121F07ED902E00132082AECD12C
+:107F7000284639460BF0CCD828467421B5F87A2526
+:107F800024F028D995F8D13142F21072002B18BF95
+:107F90004FF4BC622846822124F01CD92B6B95F843
+:107FA000D111186908F0D4F901221346B5F87817F1
+:107FB00028460CF085DA0123B5F87A170022284606
+:107FC0000CF07EDAD5F8400127F0FADB2846FBF703
+:107FD000C1FB2B685B6B5BB1B8F88836D5F86C02D7
+:107FE0009BB243F00403A8F88836002119F0D8DECC
+:107FF0002846FBF71DFBD5F8841161B928461EF011
+:10800000AFD80404C5F88441284602211EF0A8D840
+:108010002043C5F884012B6893F8A130012B03D1CC
+:10802000D5F8400128F0B8DC284619F0E9DF2846E9
+:108030000AF0D8DBB5F85C1728461EF06FDD28463D
+:1080400012F026DA424BEA68002185F84410C2F8A3
+:10805000DC33012385F8A83185F8AA312B6893F821
+:1080600038303BB14A1901314FF0FF33082982F80B
+:108070009538F7D100244FF44076314628461EF05B
+:108080006FD805EB4401B1F8203213F00F0F06D181
+:1080900023F00F0300F00F021343A1F82032B1F8D0
+:1080A000202212F0F00F06D100F0F00322F0F002CF
+:1080B0001343A1F82032B1F8202212F4706F06D1D8
+:1080C00000F4706322F470621343A1F82032B1F817
+:1080D00020321A0B06D11B0500F470421B0D1A4307
+:1080E000A1F8202201340236042CC6D12B68284680
+:1080F00093F94C100DF098DA2A68137E03B392F8C6
+:108100002F30EBB1002605EB8603D3F84C426CB15F
+:10811000A3795BB12B6893F838302BB12846D4F89B
+:108120004C15002237F014DE0023E3710136082ECF
+:10813000E9D1002385F87232D5F834072CF0EADD56
+:10814000D5F8680104214CF033DABDE8F081C0466F
+:108150008096980003681A6819B1012382F8AA3042
+:1081600001E082F8AA1070472DE9F04717469846BB
+:10817000D2F8F030D278894603EB4203B3F8BE2040
+:10818000B7F85630B7F85A100133D21A1205120D4B
+:1081900008EB02038B4207DD036842461B68244854
+:1081A000596806F08BFF40E0C2EB0103C8EB030304
+:1081B000A7F85A30BB784344BB7033E0F97809F133
+:1081C0001000FAF3C1F6436AD7F8F01043F4806365
+:1081D0004362FB78024601EB4301B1F8BE0007F1B0
+:1081E0004406431CA1F8BE30C0F3C20504050121BA
+:1081F00000F007008140240D1485735D0B43735517
+:10820000D7F8F010A7F85640D1F82C31FC789D6CC7
+:10821000D86C084B04F007041B5DA84708F1FF3336
+:108220001FFA83F8B8F1000FC8D1BDE8F087C04647
+:10823000E0AB010090E085002DE9FF47138C054677
+:10824000082B0F46164692F822A0D0F8008001D0E5
+:10825000404623E04368126851F80390941F09EBED
+:108260008A03D3F8F800E0B9B3691B7903F003037C
+:10827000022B10D112F8033C13F0080F0BD009EBBE
+:108280004A02012382F81831D5F87822D2F8B430A6
+:108290000133C2F8B430404639463246FEF790FC0E
+:1082A00014E14B6813F4803F16D1B3691B7903F0D6
+:1082B0000303022B10D112F8033C13F0080F0BD06C
+:1082C00009EB4A02012382F81831D5F87822D2F856
+:1082D000B4300133C2F8B430B3691B7903F003033F
+:1082E000022B35D1E17811F0080F1DD0D5F8782296
+:1082F000D2F89C300133C2F89C30D2F8A030013360
+:1083000011F0800FC2F8A03004D0D2F8AC300133A5
+:10831000C2F8AC3001F03003102B20D1D2F8B030CD
+:108320000133C2F8B0301AE0A278637813432278A0
+:108330001A43D5F8782205D1D2F8A0300133C2F81B
+:10834000A0300CE0D2F8A4300133C2F8A43006E02B
+:10835000D5F87822D2F8A8300133C2F8A830B6F8A0
+:108360007E3013F00F0F40F09C801A09C3889A42A8
+:1083700024D101230371D3181B051B0D0DF10A0431
+:10838000C380BD6A07F11A0106222046F9F3F4F50D
+:10839000404639463246FEF713FC404621462A46FF
+:1083A0004DF006DA002800F09180B84240F08E804F
+:1083B00040464946524625F071DF87E0C3EB020391
+:1083C00002F00F0741781A05120D8A4203D200EB22
+:1083D00087039B6813B9B2F5006F0DD90022D8F856
+:1083E00004007169FEF39CF4D5F87822D2F8C0300D
+:1083F0000133C2F8C03069E08A4234D3C1F10103CD
+:10840000D3189BB240464946524625F0DBDE09EBC5
+:108410008A03D3F8F8404CB1736904EB8702936088
+:10842000D6F880309364A3780133A3705246404657
+:10843000494625F033DFD5F87832D3F8C820013229
+:10844000C3F8C820A378002B40D095F8A333002BA5
+:108450003CD1013385F8A333D8F80800A96B642216
+:1084600007F0B4D832E0736900EB87029360D6F866
+:108470008030936483780133837095F8A33343B9D4
+:10848000013385F8A333D8F80800A96B642207F0FC
+:108490009DD8D5F87822D2F8BC300133C2F8BC3070
+:1084A00014E0D8F8040071690022FEF339F4D5F81D
+:1084B00078322846D3F8DC2049460132C3F8DC2064
+:1084C000012300935246013B26F03CD8BDE8FF87CC
+:1084D0002DE9F0471546937AD27A046843EA022AD6
+:1084E0002B79074603F007064FF0000929E00B69D6
+:1084F00060681A785B7842EA0328D7F87822936E8E
+:10850000013393660122FEF30BF4236893F8A12054
+:10851000012A03D0C8F34123032B08E0204631464B
+:1085200022F062DA09F101031FFA83F9D1450AD07A
+:108530002369022103EB8603D868134B9B6B984792
+:1085400001460029D3D1236893F8A130012B05D02F
+:108550002046314697F92C2022F046DAAB7913F009
+:10856000020F0ED0002506E00120FEF3F5F06B1C93
+:10857000DDB20B2D05D0E368D3F8703113F0010F95
+:10858000F2D0BDE8F087C046E0A685002DE9F347AC
+:10859000D0F80090044601A9D9F800054CF09ADD06
+:1085A00000263AE07B6813F4802F36D063684FF0E2
+:1085B0000008FD58AA46D5F8F8205FFA88FE32B3C5
+:1085C00091781379002918BF01261BB1002313717C
+:1085D000D3701CE0D9B1D3780133D9B2D1707B68A4
+:1085E00013F4807F14BF628EA28E6423B2FBF3F279
+:1085F00091420BD3D4F878224846D2F8C430514681
+:108600000133C2F8C430724625F0ACDD012608F112
+:1086100001080435B8F1080FCDD101A84CF062DD96
+:1086200007460028BED136B9236884F8A36398684A
+:10863000A16B07F013D8BDE8FC87C04610B50368EE
+:1086400004465B7E6BB90749074806F037FD2046B4
+:10865000FCF7C6FC0548034906F030FD2046FCF750
+:1086600081FB10BD36AC01001CAC01002AAC01003E
+:108670002DE9F04FD0F800B089B0064607A9DBF825
+:1086800000054CF027DD00220492E8E0039A5368CD
+:1086900013F4802F00F0E380DBF840315B6852F880
+:1086A00003800023C146C2460593059ADAF8F830E4
+:1086B000D7B223B1002388F8193188F8183198F817
+:1086C0001831A3B198F8193100240133DBB2022B21
+:1086D00088F8184188F8193109D9262388F81941F2
+:1086E0003046009349463A46234625F02BDFDAF818
+:1086F000D840002C00F0A9802378032B00F2A5803D
+:10870000DFE803F092025D7A3046494622460123B3
+:1087100025F048DF94F8E750DDB1012D11D1E17863
+:1087200009F11000FAF310F4014650B1DBF8003003
+:108730002A46D868FEF3F4F2D6F87822D36B0133D8
+:10874000D363002284F8E7203046214625F06CDE12
+:108750007BE094F8E830312B08D92723009330468A
+:1087600049463A46012325F0EDDE6EE094F8E63006
+:1087700023B184F8E65084F8EB5066E0A37823B187
+:1087800094F8EB30013384F8EB3094F8EB30022BA3
+:108790005BD1D6F8783230465A6E494601325A6675
+:1087A000272300933A46012325F0CCDE01233046EF
+:1087B00049463A4623F010DF0123049345E094F83C
+:1087C000E920531C032A84F8E93004D9484621469D
+:1087D00023F0D0DE39E0B27CF37C009296F82E20B4
+:1087E0003068019203993A4626F0E4D9D6F8782207
+:1087F000136D0133136528E094F8EA20531C012A15
+:1088000084F8EA3009D9D6F878223046536E4946C2
+:10881000013353663A46012303E0304649463A465F
+:10882000002323F0D9DE10E094F8EC20531C3B2AFF
+:1088300084F8EC3009D9304649463A46002325F001
+:1088400069D910B1042380F8E930059A0AF1040AC5
+:108850000132082A059208F102087FF426AF07A822
+:108860004CF040DC039000287FF410AF049B0A4AD0
+:1088700013B11368013300E0049B074C13602368B5
+:10888000012B04DD5846FFF7D9FE002323600020AA
+:1088900009B0BDE8F08FC046ECF40100D0F8AC039D
+:1088A0007047C046D0F8C0037047C046C0F8C01338
+:1088B0007047C046D0F8AC331B68DB6918690A28DA
+:1088C000A8BF0A207047C04610B50446FDF332F633
+:1088D000B0F5C05F05DD20464CF0F2DB20464CF0E1
+:1088E000EFDB10BD02292DE9F0410646D0F8AC536C
+:1088F00001D0002401E000F575742B68D3F88C20BA
+:108900005368126C9B1822692361C2EB0302A369AE
+:108910009A4223780ED24BB9E26863699A4205D332
+:108920000123237063680133636028E0E368013347
+:10893000E36024E00027E7600BB3012904D1284657
+:10894000023121F06BDB18E0022916D1A868D6F8B5
+:10895000D01306F083DED6F8CC3373B12B6893F8CE
+:108960007430012B07D02869012134F0A9DD2A6871
+:10897000012382F87430C6F8CC7300232370BDE85D
+:10898000F081C0462DE9F04F97B0DDF894B0D0F8F3
+:10899000AC630023D0F8B0930C46074659463046E6
+:1089A0000392DDF888A014931393129336F022DD1E
+:1089B0000399054601F001030093484621465246BB
+:1089C000239B1AF081DC1490002840F0FF82219A4A
+:1089D000032A0DD9042213A82099F9F3CDF2219B83
+:1089E000072B05D9209A12A8111D0422F9F3C4F20D
+:1089F000139C129AB4F1000818BF4FF00108BBF1A4
+:108A0000000F01D1D5F808B003998B1E472B00F257
+:108A1000D982DFE813F0F900FE00010104016A00C9
+:108A20007D008C00D7028E00D7029700D702070185
+:108A30000A01480058007F0195010D011F014E01F8
+:108A400054012002D7029900A000AD00B00033010C
+:108A50003601FC00D70236023A02D702D702D7020B
+:108A6000D702D702D702D702D702D702D702D7023E
+:108A7000D702D7026F0281028602E500EF00DA0218
+:108A80009C02D702D702AC02AF02B802BB02BE0200
+:108A9000C102C402D702D402C702D702D702D7024A
+:108AA000D7020C021302D9F83430002B00F08A826E
+:108AB0000DAC304607F56371224623F0BDD8504611
+:108AC00021461022C3E0D9F83430002B00F07A821E
+:108AD00011AC514604222046F9F34EF2304607F518
+:108AE0006371224623F0C4D81FE0219A0023052A8F
+:108AF0008DF8573040F22781384620990DF1570202
+:108B000029F0CADF9DF8573014908AF800305CE2F3
+:108B1000514630464CF042DE0146002800F01E82ED
+:108B200038469AF806202CF0B5D914904DE29B4BAC
+:108B300000E09B4B0093384629465246239B29F080
+:108B400045DFF2E7974BF5E7D6F83407FFF7AAFEC3
+:108B5000CAF8000039E2D6F834572846FFF7AAFED3
+:108B6000844200F3268228462146FFF79FFE2CE22E
+:108B7000D5F850353BE03368DB691F692B79002B52
+:108B800040F06381BC4200F31482C5F85045139C49
+:108B9000184619467318D3F84C2222B1937913B1B1
+:108BA000954218BF013004312029F3D1002800F08C
+:108BB0000C82C4EB070393FBF0F000217318D3F889
+:108BC0004C224AB193793BB1954205D0D2F8503549
+:108BD000834288BFC2F8500504312029EED1F4E168
+:108BE00096F9A838002B01DA002300E00123CAF827
+:108BF0000030EAE1B8F1000F01D0002301E04FF0AE
+:108C0000FF3386F8A838E0E195F83C30EFE7AB7920
+:108C1000EDE785F83C80D8E1D6F82837E7E7C6F8D5
+:108C20002847D2E1D7F8BC33E1E7C7F8BC43CCE131
+:108C30006A7E049222B105A805F11A01F9F39CF1AC
+:108C4000049B1A1D239B93427DDB504604A9F9F334
+:108C500093F1BAE1202C02D96FF01103B4E123990A
+:108C6000231D99426FDB2B79002B40F0EE802846C4
+:108C70000AF10401224635F07FDFA6E195F83A308B
+:108C8000B5E7AB7985F83A8085F83B80002B00F09A
+:108C90009C812B79002B00F098813046294614F0F6
+:108CA00005D830464FF000614FEAC8621AF082DF03
+:108CB0008BE199F83830003B18BF012397E799F80A
+:108CC00038301C1E18BF0124444500F07E81304618
+:108CD00022F0BCD810B96FF0150375E154B13046DD
+:108CE00001F082FA736A23F4C0137362002389F8D7
+:108CF00038306AE1736A304643F40023736202231A
+:108D000089F83830D6F8AC38013B86F8A938FFF737
+:108D1000DBFD5AE1219A032A15D9002C05DB3046E8
+:108D2000214614AA36F0AADA05460DB12B795EE782
+:108D3000149B13F11E0F40F04881CAF8005044E123
+:108D4000239B072B02DC6FF00D033DE1032A01D1C9
+:108D5000002703E0022A14BF00270127002C2DDB87
+:108D60003046214614AA36F089DA054630BB149BFA
+:108D700013F11E0F22D1129B002B1FDD87F0010380
+:108D800000932A462B463046139935F011DF0546ED
+:108D900050B96FF01A03149310E0C046991E830077
+:108DA000A91E8300F92A83003046294636F0EADB03
+:108DB000149018B13046294636F03EDB129B032B47
+:108DC00000F00381022B00F00081149A3AB112F1F5
+:108DD0001E0F40F0FA80002B40F0F780F4E0002BEB
+:108DE0001CDD2B79002B40F0F08033681B6F13F0F3
+:108DF000030F02D06FF00803E6E0AA7922B13046F3
+:108E0000294636F0F1D990E66B7E30460092019209
+:108E1000294605F11A0230F0ABDDD6E06B79002B64
+:108E200000F0D3803046294636F02AD8CDE015B17F
+:108E300095F96435DBE6CAF800501FE0F5B1002C67
+:108E40001CDB012C1ADC2B7913B16FF00403BBE09F
+:108E500085F86445B9E099F818307BB199F82F305E
+:108E600063B199F830304BB999F83F3033B9D6F83F
+:108E700068319B7913B9B6F81637B8E66FF001037D
+:108E8000A2E0336893F83030B1E6336893F83030BD
+:108E9000434500F09A80304636F072DC0446B8F163
+:108EA000000F05D043791BB13046214635F0E8DF8D
+:108EB0002146304688F0010236F06ADC0446149000
+:108EC000002840F082803368012283F82F20B8F117
+:108ED000000F03D0D6F8403583F83420336830468D
+:108EE00083F8308012F06CDF86F8DD41304606F002
+:108EF00015F86AE0BAF80200FAF3AEF1E8B99AF8A8
+:108F00000400BAF802109AF800209AF80130009094
+:108F100028462BF011DB08E6D6F83437B3F8A43333
+:108F200065E624B9D6F83437A3F8A4434DE0D6F863
+:108F30005C01A1B23DF032DA10B96FF0130343E0E7
+:108F4000D6F83437BDF84C10A3F8A4133DE0BBF1BC
+:108F5000000F03D09BF80430022B02D06FF01D03EA
+:108F600032E03846DBF8101029F06ADDDDE597F8CD
+:108F7000F0333CE6E3B287F8D53387F8F033384670
+:108F800029F024DC21E0D7F8E83330E6C7F8E843DD
+:108F90001BE0D7F8EC332AE6C7F8EC4315E097F866
+:108FA000D43324E6D6F86C32D3F8D432DB8D9C422D
+:108FB00002DD6FF01C0307E0A7F8C84305E0B7F82F
+:108FC000C83314E66FF016031493149817B0BDE875
+:108FD000F08FC0462DE9F7430F699146D0F830274E
+:108FE0000E46136897F948104FF4887401FB043457
+:108FF0009369054606EB0308D4F80431013BC4F835
+:109000000431D369013BD361002386F8DF3096F841
+:10901000781101222CF006DAB368284623F4F043D5
+:10902000B3603146032221F03BDED4F8043143BB68
+:10903000D7F8CC3013F4806F23D1B5F8263603F47B
+:109040007043B3F5805F14BF40234423F9582B6865
+:1090500093F838301BB128462CF00AD811E081F87B
+:10906000DF30EB6AB3F924305BB195F8763243B95F
+:1090700001214022009385F87612284613461AF003
+:10908000A3DD002388F8C83088F8CA3088F8CC30CF
+:10909000C8F8D030B9F1000F09D1284631464FF653
+:1090A000FF7200232CF0B8D80028F6D103E0284640
+:1090B00031462CF071D8BDE8FE83C0462DE9F0435F
+:1090C0000568064687B028468946174698461DF02B
+:1090D0008DDE10B128461DF081DE284639464CF061
+:1090E00077DC044698B1B268A86894F8783102B188
+:1090F000527900923946072207F000D8D5F8440883
+:1091000094F8781107F0E2D8002384F878310E9BA8
+:109110002846029300230393049331460B223B46D7
+:10912000CDF80090CDF8048013F0F8DC07B0BDE86E
+:10913000F083C04670B5114686B0054616464CF021
+:109140002DDB044608B390F8DF3023B128462146D2
+:109150000122FFF73FFF20464CF0A6D8E3681BB181
+:10916000284621463EF08ADE002203230092019326
+:10917000029203920492284621690532334613F085
+:10918000CDDC284621464CF01BDB06B070BDC04646
+:109190002DE9F04F0668D0F8D022D0F8D81297B059
+:1091A0000746D0F8E8B230460691079220F09AD9E7
+:1091B000069BB068196806F051DA384602212FF094
+:1091C0007BDBF7E1D6F8D83603EB82035D686C8E63
+:1091D00004F47043B3F5805F14BF38233C2356F882
+:1091E000039004F44063B3F5406F28D1336893F8DB
+:1091F000463013F0030F15D0D6F85C01D9F80410EF
+:109200003CF07CDA10F0080F0CD199F8EC304BB13F
+:10921000D9F80030022B12D1D6F8FC349B7813F029
+:10922000020F0CD02046F9F3FDF70E2894BF4FF43F
+:1092300000534FF4805340F4306003439CB2D6F89F
+:109240005C0121463DF0AAD8002800F0AE81688E6E
+:10925000F9F3E8F70446688EF9F3E4F744F4306470
+:109260000E288CBF4FF480504FF400500443A1B23D
+:1092700038462EF0D5DB002800F09781D7F8E83289
+:10928000002B78D0D3F8DC30002B74D04FF00001E5
+:10929000A7F85C1095F8AA004FF00C0800FB08B086
+:1092A000EA8814A982F08002C2F3C0121C30FAF3DB
+:1092B0001FF1BDF850200DF1540AA7F8622095F86F
+:1092C000AA00514600FB08B02030FAF36FF1159B5D
+:1092D00033BB95F8AA1013AC01FB08B1042224316A
+:1092E0002046F8F349F620469A490422F8F328F676
+:1092F00048B995F8A920A2F10803DBB2022B40F28D
+:1093000054818DF84F2020465146FAF34FF1024622
+:1093100030B90090CDF8048095F832300293FAE02D
+:10932000159B8D4913F0040F1CBF43F002031593E6
+:10933000159B304613F0020F1CBF43F00103159339
+:1093400015AB00930423019301230293BB68002211
+:10935000039313461AF024D80022072301920093A6
+:1093600095F8AA3030460293039204923946183297
+:109370002B4613F0D3DBB5F8623013F0100F0FD08B
+:10938000BA6D40F2371302EA03034BB9734B1A78F4
+:1093900032B901230092019395F832300293FCE038
+:1093A0002846F9F3C9F218B100230222009327E0FE
+:1093B0003B6D002B32D0336893F83030002B2DD129
+:1093C0001C46984609E0796D284641440622F8F388
+:1093D000B7F508F1060818B10134FB6C9C42F2D3D2
+:1093E0003B6D012B03D1FB6C9C4206D316E0022B94
+:1093F00014D1FB6C9C420DD210E000230093032299
+:10940000019295F832200393029204933046394634
+:109410001722C7E0002304220093F1E7336893F892
+:10942000953083B1D6F84C35012B09D1284606F585
+:10943000AA610622F8F384F5002840F0B68002E025
+:10944000022B00F0B28095F9344074B9D6F85C0173
+:10945000698E3CF037DE40B105230094019395F806
+:109460003230039402930494D0E7B7F862306BB1C2
+:10947000BA6D40F2371302EA03033BB13046394676
+:109480002A462EF0EFDC002840F08F80D9F800301B
+:10949000022B0AD199F815203AB9FD33009305F152
+:1094A000380009A90123019214E0336805F138005E
+:1094B00093F8463009A913F0030317BFD7F8CC304F
+:1094C0001A46C3F3003383F001020192FF23002206
+:1094D0000093134647F010DE336B09F1500493F804
+:1094E000EC1039B16B8E03F44063B3F5406F14BFD9
+:1094F00014212821204647F0A7DDD6F86036002247
+:1095000009A821469B7847F039DD024630B9009022
+:109510000923019302920392049277E79DF8382081
+:1095200096F838379A4240D195F93430C3B96A8EEB
+:10953000304602F47042B2F5805F14BF022201226D
+:1095400005F138012EF032DA024648B90A230090BC
+:10955000DFE7C0460CA7010017738600ACF40100DA
+:10956000336893F8303053B3294630464CF016D95F
+:10957000014620B3037E13F0020F06D0436813F4B4
+:10958000805202D10D230092C3E7D1F8F030B3B17D
+:1095900000220F230092019302920392049230461C
+:1095A000394617322B4613F0B9DAD6F8DC36013BD0
+:1095B000C6F8DC36D6F8DC26002A7FF403AED6F8EF
+:1095C000DC46FCB1069B00219977D6F8DC26D6F85C
+:1095D000D836013A03EB8203C6F8DC26069A9C686B
+:1095E0005368012B0AD000910191029103910491DB
+:1095F000304639462022234613F090DA384630F0C0
+:109600005FDF29E00799FA7991F934304AB1384699
+:1096100001212246D3F1010338BF00232EF034DEAE
+:1096200009E038460121D3F1010338BF002300923D
+:1096300001922EF063DF97F91030022B03D1F86806
+:1096400000214FF08FDF96F87532384623F004037F
+:1096500086F875322EF000DF17B0BDE8F08FC046F7
+:109660002DE9F04F062989B007460D4692469B46E4
+:109670009DF848900468D0F8D86246D061BBB9F133
+:10968000000F03D12046394636F090DA94F8723252
+:10969000002B3AD0D4F8000507A94BF01BDD03E0FE
+:1096A0001B7E13F0020F30D107A84BF01BDD0346E1
+:1096B0000028F5D151E0236B186906F09FFBD7F81D
+:1096C000D4325B8E834220D020462AF005DFD4F8C6
+:1096D00034072BF01FDB18E0B368093B012B14D8CB
+:1096E000204611464CF05AD810B10C214BF0A8DCA2
+:1096F000022D07D0A068316805F0B0DF052D01D03C
+:10970000012D02D14FF0010801E04FF00008139B3A
+:109710000095CDF804B00293336C20460393736C2C
+:1097200039460493B9F1000F0CBF072209225346B2
+:1097300013F0F4D9B8F1000F13D0052D01D0022D8C
+:1097400007D1B27F337F9A4203D2384630F0B8DE79
+:1097500007E03846FFF71CFD03E07368032BAAD12E
+:10976000D3E709B0BDE8F08F00487047F0B00100C2
+:109770000048704710B2010010B5836F40F2EE222E
+:109780001C6A044B94219C4208BF4FF4166234F0CB
+:1097900061DA10BD50200800816F10B50831044611
+:1097A00032F064DDFFF7E0FF0146204632F03EDD97
+:1097B00010BDC0462DE9F04104460D469046BDF867
+:1097C00018E09DF81C701E4633B18368DA6A02EB1C
+:1097D0004102938BFB1893834FF6FF739E4503D092
+:1097E000A821724634F036DA04EB8503D868084BBA
+:1097F000414632465B6A9847002807DA36B1A368CB
+:10980000DA6A02EB4502938BDB1B9383BDE8F081A0
+:10981000E0A6850010B507490446406EF9F3D8F07C
+:10982000034620B9606E0449F9F3D2F003461846A6
+:1098300010BDC04649A801000AAA860070B50D46B1
+:109840000669144608460A220021F8F3F9F36B88EA
+:109850001C43F36C6C8013F0200F03D02B8843F46F
+:1098600080632B80B16F42F250030A8C9A4206D17A
+:109870004B8C052B03D86B8843F004036B8070BDC1
+:109880004FEA810210B513188E468168DB6F5218BB
+:109890008367936B0B6390F8EB3063B190F8E8301B
+:1098A0004BB94FF40051006EBEF1000F0CBF0A46D9
+:1098B000002201F0B7DA10BDB1F1FF3F2DE9F04110
+:1098C00004460E4605D1836F596A09B90E4600E079
+:1098D0009E6994F8E9701FB92046394632F0FCD9E8
+:1098E000206E01F0FFDB80B1002504EB8503D86812
+:1098F00010B1254B9B6898470135062DF5D1E368DB
+:109900001BB12046002132F033DA94F8E8203AB156
+:10991000A3680022DA612046032133F069DB30E0DE
+:10992000206E46F0040184F8EA2001F08BDAA06F83
+:10993000012184F8EA1018B1406A08B106F034F940
+:10994000204632F0EDDAE26E206ED2F8E0310121ED
+:1099500023F02003C2F8E031FCF31EF3002120467F
+:1099600032F0BAD9204633F035DC2046012133F0FD
+:1099700009D8A2680023D3611FB92046022132F022
+:10998000ABD9BDE8F081C046E0A6850070B50121E5
+:10999000044634F0A3D9206E01F0DAFA2046002103
+:1099A00032F09AD9204633F0F5DD054630B1204635
+:1099B000002134F093D96FF0080005E020464FF005
+:1099C000FF31FFF779FF284670BDC04673B50469C3
+:1099D000054620460E46FFF7DFFEA36F3146586A64
+:1099E00007F050FC2A68012382F87430204632F0D8
+:1099F00075DBA36F2046998A33F008DFA36F2046FA
+:109A0000D98A33F0F1DE204694F8861032F0F6D889
+:109A1000A36F204652219A8B34F01CD9A36F50219A
+:109A2000DA8B204634F016D9204632F079DB204616
+:109A3000FFF7A2FE032300932046042108220023FF
+:109A400033F0E8DA204631F0A9DE7CBD10B50469B8
+:109A50004FF440412046002233F0CADAD4F8F830FF
+:109A60001B691BB1204631F099DE02E0204632F03E
+:109A700051DCE26C206E02F00202002A0CBF11469B
+:109A80004FF400710A46002301F07CDA10BDC04695
+:109A900070B5836804461B6893F82050F5B901211E
+:109AA00034F01CD9206E01F053FA2046294632F0DA
+:109AB00013D9204632F02EDCA068D0F848381B7845
+:109AC0000BB132F059DAA36F586A06F05FF8A36859
+:109AD00084F85E501A68012382F8203070BDC046B9
+:109AE00070B5054690F89000002846D0AB6F002175
+:109AF00085F89010586A06F05DF8AB681A6992F81C
+:109B0000EA305BB1D36ED3F8202140F2044302EA7D
+:109B10000303B3F5806018BF012002E0106E01F06E
+:109B200019FA68B10024AB6F85F8EB4085F8EA407C
+:109B3000586A214606F038F8A86832F067D91BE069
+:109B4000286E01F0CFDA044680B1EB6ED3F82031F5
+:109B500013F0010F02D0284633F0F0DEAB689868AE
+:109B600001F020FF0446284634F0D6D895F8E810D6
+:109B700011B9284634F0B2D8204670BD70B50546FC
+:109B800090F8900050B3AB681A6992F8EA305BB174
+:109B9000D36ED3F8202140F2044302EA0303B3F565
+:109BA000806418BF012403E0106E01F0D3F904466D
+:109BB000AA6814B1002313620CE0906805F08ADDF6
+:109BC0002846214632F088D895F8E83013B928465F
+:109BD00032F0A0DBAB6F586A06F0B0FC70BDC04637
+:109BE0000121836F10B580F890100446586A05F083
+:109BF000E1FF2046022132F06FD8A368986805F093
+:109C000073DD002010BDC0462DE9F34186680627AC
+:109C100033680DF10204DB6905461B6AD0F86C80DD
+:109C2000C6F8AC3830493A462046F8F3A5F16B6CDB
+:109C30002E48214603FB07003A46F8F39DF1042322
+:109C4000C6F8AC38013B86F8A938A86821F0FED8E0
+:109C500008B93C4604E0D6F8AC389B0001339CB20E
+:109C6000D5F8B8700026F05D04F0FF01201880B22E
+:109C7000421E02F0FF0341EA032102F48072C4F3A2
+:109C800000231A43330243F4004301369BB2062EED
+:109C9000A8F840350446A8F82015A8F82C25A8F8FF
+:109CA0004035E0D1284698217A7833F0D3DFD5F8D3
+:109CB000B83028469A219A7833F0CCDFD5F8B830FE
+:109CC0002846DC781A789C2142EA042233F0C2DF6D
+:109CD000D5F8B83028465C791A799E2142EA0422E8
+:109CE00033F0B8DFBDE8FC8113AE010020ED0100C8
+:109CF0002DE9FF41056907469221284633F090DCA3
+:109D0000400080B2A7F8420000282FD04FF0000892
+:109D10000DF101060F213046154A4346F8F3D4F100
+:109D2000686E3146F8F354F660B13146686EB7F8A4
+:109D30004240F8F321F604EB480482B2214628465B
+:109D400033F088DF08F10108B8F1770FE0D1686ED1
+:109D50000849F8F33DF648B1686E0649D5F8F84071
+:109D6000F8F30AF62081284631F074DFBDE8FF8160
+:109D7000AEAC8600177C86002DE9F041056986B0FF
+:109D80004FF0FF318A4A80462846EC6E33F030D9D6
+:109D9000D5F8F8302846196832F00CDBAB6D3BB1D2
+:109DA0004FF00303A4F8B4364FF0FF03A4F8B8361D
+:109DB000EB6C13F0010F09D02B6D286E13F0800FA0
+:109DC00001D0032100E0012101F070F94FF0FF31D3
+:109DD000C4F828112846774A33F00AD9764E03E0B2
+:109DE0000A20FCF3B9F40A3ED4F8283113F0010F2D
+:109DF00001D1092EF4D14046D4F82831FFF726FED0
+:109E0000D5F8F4302BB92B6E9A6A40F294539A42EB
+:109E100013D1286E694B826BD318012B07D94AF6F0
+:109E2000E6039A4203D04AF6E5039A4205D1082395
+:109E300000212822009301F029D800210A46286E2B
+:109E400001F008D8FFF794FC0146284632F0EED91D
+:109E50002846FFF7D9FE4FF48033009328460623A7
+:109E600098210DF10E0232F021DDD8F8003093F880
+:109E70003830D3B1404620F0E9DF012815D1002366
+:109E80001E461F4605930AE04FF4C023009339464F
+:109E9000284605AA042332F02FDD01362437D8F8EE
+:109EA0000030DB691B6A9E42EED3284680210822DF
+:109EB00033F0D0DE28465C210A2233F0CBDE4FF0AF
+:109EC00080733F4AC4F8003128463E4933F090D8A9
+:109ED0004FF00043C4F8883103F10243C4F88C31D9
+:109EE0004FF48043C4F8283103F5404363620121F5
+:109EF000284633F06BD8286E01F070F883B2A8F8CA
+:109F000018001621A4F8A8362846B5F8442033F0E6
+:109F1000A1DE2846C021B5F8542033F09BDE284648
+:109F2000C221B5F8562033F095DE274B2846C4F8F9
+:109F30006031D4F86031B5F888304421C4F8643118
+:109F4000224BB5F88C20C4F86031D4F86031B5F8F4
+:109F50008A30C4F8643133F07DDE28464621B5F8F6
+:109F60008E2033F077DEB4F888361B051B0DA4F87D
+:109F700088364FF00103A4F89C360023C8F8483017
+:109F80001C4605EB8403D86810B1114B5B689847F9
+:109F90000134062CF5D10E4CE868236D9847E36E2A
+:109FA000E86898474046FFF7A3FE06B0BDE8F08199
+:109FB000040400040204020449420F001D57FFFF7D
+:109FC00000000240000006400600020007000200F8
+:109FD000E0A685002DE9F04790F8E97004460E46AA
+:109FE0009046856817B9394631F076DEA86805F0E5
+:109FF00071DB06F47041B1F5805F14BF00210121CF
+:10A0000081462046FFF73CFCA36F3146586A05F0B5
+:10A01000F1FEA36F586A05F0D3FD2846FFF7ACFEAA
+:10A02000B8F1000F04D0012120460A4633F04ED883
+:10A0300028463146FFF7CAFCA868494605F05EDBB2
+:10A04000D4F8D43043F00403C4F8D4300123C4F866
+:10A05000D0301FB92046022131F03EDEBDE8F08746
+:10A06000816810B50B680446D3F88C20D2F8B43060
+:10A070000133C2F8B4300A6992F8EA3063B1D36EA2
+:10A08000D3F8202140F2044302EA0303B3F5806FC2
+:10A0900014BF0020012006E0106E00F05BFFD0F13D
+:10A0A000010038BF002020B120464FF0FF31FFF7FC
+:10A0B00003FCA06831F0AADEA0681CF005DD10BD2D
+:10A0C000D0F8EC1010B5044631B100680C22FCF356
+:10A0D0000FF60023C4F8EC3010BDC046D1F8CC30E8
+:10A0E00073B543F40053C1F8CC3005460C4635F047
+:10A0F00049DA0646002873D1B5F8822144F22133AB
+:10A100009A421AD00E3B9A4217D007339A4214D083
+:10A1100010339A4211D0143B9A420ED007339A4220
+:10A120000BD010339A4208D025339A4205D0AB6B3E
+:10A130005B7D13B96FF00B0652E02B6B93F8EC309C
+:10A140000BB91E4608E0B5F8263603F44063B3F5B4
+:10A15000406F14BF142628262B6893F8463013F05E
+:10A16000030305D0D4F8CC30C3F3003383F00103EC
+:10A170000093284633462146022234F095DB0646FA
+:10A1800070BBD5F84C01214645F058D9C4F8F0020F
+:10A1900010B96FF01A0623E0A379D3B194F8F53221
+:10A1A000312B11D82B681B7E2BB1284694F8F41262
+:10A1B0000C4A1FF03BD9D5F84C0194F8F41245F045
+:10A1C00081D8322384F8F43294F8F53284F8F432EA
+:10A1D00006E0D5F84C0104F53D7145F037D8064648
+:10A1E00030467CBD329E850070B505460026AB1911
+:10A1F000D3F84C425CB1A3794BB163791BB12846CB
+:10A20000214634F03DDE2846214635F015D9043686
+:10A21000202EECD170BDC046F0B50E4649691569D7
+:10A22000908A0A68002A01DA821831D44C6813191E
+:10A2300083422DD8B36801F1080C0CEB040705EB41
+:10A24000020E6BB9184608E010F80E3010F80C201A
+:10A25000C15D134099421BD10130A042F4DB19E0EB
+:10A26000012B15D12B18C4EB03050DE010F80E30AF
+:10A2700010F80C20C15D1340994203D10130A04277
+:10A28000F4DB07E00EF1010EAE4501D80020F6E741
+:10A29000002000E00120337B0BB180F00100F0BD15
+:10A2A000036870B504465868A36A0D46164623B97C
+:10A2B0009021FCF30DF5A06270B1A06A0123AA8A77
+:10A2C00003607F3382604660C360296910309A4220
+:10A2D00028BF1A46F7F350F670BDC046684683693A
+:10A2E000416920300BB5203803695A4651460EB4F7
+:10A2F0004A46414606B4C36882684168FEB40368B2
+:10A30000C269EFF303810EB48269EFF3058106B4ED
+:10A31000034801680029FED06846884714B000BD94
+:10A32000C4A300000A49084202D062B6C9430840EB
+:10A330000849084202D061B6C943084006490840AE
+:10A34000002803D005490A6802430A6070470000EC
+:10A350000000008000000040FFFF000000E100E07E
+:10A360000A49084202D072B6C94308400849084267
+:10A3700002D071B6C943084006490840002804D0FD
+:10A3800005490A68C04302400A6070470000008027
+:10A3900000000040FFFF000080E100E00249096882
+:10A3A0009022885870470000D0A300000249096835
+:10A3B0009C22885070470000D0A30000DDBAADBBDE
+:10A3C000000000000000000000000000000000008D
+:10A3D000000000000000000000000000000000007D
+:10A3E000024A11681060081C70470000C4A30000F6
+:10A3F000024A11681060081C70470000C8A30000E2
+:10A4000003490860034801680029FED08847FEE739
+:10A41000BCA30000C8A300006348644900220A509E
+:10A420000168634A0A40634F0F403F4232D1002324
+:10A4300098469A46604A0A401821CA405F494358E4
+:10A440005F4C1C405F4DAC4204D180465E4D4519C7
+:10A45000A9460EE05D4DAC420BD182465A4D4519DE
+:10A46000AB460F241D1C2340594C25402D0A2B437D
+:10A470009C460023984501D09A4504D1554BC018FD
+:10A48000013ADCD105E05046004202D0404600428D
+:10A4900029D1FEE7FC2141580A680F2313400F2BF6
+:10A4A000F1D0012B01D00431F6E708314A4B1340BB
+:10A4B0004A4CA34206D100F0BBF8804600F0C4F835
+:10A4C0008146E9E7464CA342E6D10B1F1B68454C89
+:10A4D00023401824E3409C4600F0AAF8824600F08E
+:10A4E000B3F88346D8E74049212242502E4A3F49DB
+:10A4F0008958FF23194219D051683D4B194215D094
+:10A5000011683C4B1940D36A10E0A3420ED0C046FC
+:10A510000CE039498958194208D0384989581940FE
+:10A520009942FAD12B4B11691942FCD049463F425E
+:10A5300004D19823CB581024E34001E0304BCB5892
+:10A540001C242340002B01D000F08CF840462D49FC
+:10A55000086048462C49086050462C49086060460F
+:10A560002B4908602B490F602B4D2C490D60043D91
+:10A57000AD46009DEC431023DD41AC4201D081B0DB
+:10A5800009E0240CA400264D2C606B461B1B254DB6
+:10A590002B60043B9D4624482449002204C081428C
+:10A5A000FCD810F07BF8FEE700000018140600004D
+:10A5B000F8FF0000000000F00000000FFC0F00009A
+:10A5C000F08F0000A0820000000F0000E08000007B
+:10A5D000007000000010000000FF0F00002A0800BB
+:10A5E000000E0800000000FFE0010000040600006B
+:10A5F00000003800FFFF0000180600000C060000F5
+:10A6000008040000D0A30000D4A30000D8A30000D9
+:10A61000DCA30000CCA3000000C00300E8ED0100B3
+:10A62000F0ED0100ECED0100A8F40100F0F80100EC
+:10A6300008680F2204310240052AF9D1014A10406E
+:10A64000F746000000F0FFFF08680F2204310240C7
+:10A65000052AF9D180221042F6D0014A1040F7466F
+:10A6600000F0FFFFFEE7000010B57146034804F05C
+:10A6700025FD40F2E370FFF7C3FE10BD8E1F86007C
+:10A6800010B5002128220446F7F3DAF40A4B2360C0
+:10A690000A4B63600A4BA3600A4BE3600A4B2361D9
+:10A6A0000A4B63610A4BA3610A4BE3610A4B2362C5
+:10A6B0000A4B636210BDC04600000000EBEC0100D5
+:10A6C000ECEC0100A8F40100A8F40100F0F801008E
+:10A6D000F0F80100F59D0200F89D0200BE24030081
+:10A6E0002DE9F04399B00CA8FFF7CAFF0C9B0D9918
+:10A6F000DFF8DC91C91A0F9D0E9BD9F80060ED1AA6
+:10A70000119C109B06F5A0566048E41A76180B9130
+:10A7100004F0D4FC0B9905F57E73761907333619CE
+:10A7200001F57E729B0A019404F57E740732009352
+:10A7300007340523A40A920A039355482B46029432
+:10A74000DFF8848104F0BAFC524BD8F80040196855
+:10A75000D9F80050C4EB010303F57E7001F57E7259
+:10A7600007300194039504F57E7405F57E75800A23
+:10A77000073207340735920A0090A40AAD0A46480A
+:10A780000294049504F09AFC444B45481968D8F8A3
+:10A790000030C91806F57E7301F57E7207339B0AF7
+:10A7A0000732920A0093334604F088FC3D4B3E4842
+:10A7B000196804F083FC3D4B1F683D4B3A689A4290
+:10A7C00003D03C4804F07AFC24E0179705E0326897
+:10A7D000374B9A4205D1331D1793179E16AB9E42F5
+:10A7E000F5D3354BC7EB06001A6817ABC7EB03016F
+:10A7F000C3EB0204C6EB02050092019102910390A3
+:10A80000049039462D4832460594069407950895DC
+:10A8100004F054FC2A4C2068002834D0C588F8F392
+:10A820009FF12368013D5C894FF4806104FB05F6CC
+:10A83000443405FB04F406F57E73073393FBF1F310
+:10A84000009304F57E73073393FBF1F30246029302
+:10A85000294633461B48019404F030FC1A4B0F4A3A
+:10A860001B681268C6EB03069B181B1B03F57E7161
+:10A8700006F57E720731890A073200911348314686
+:10A88000920A04F01BFC19B0BDE8F083E11F8600BA
+:10A89000F01F8600C82600002E208600A426000097
+:10A8A0007220860090260000AC208600F4F401009F
+:10A8B0004B415453C6208600F8F40100E92086007D
+:10A8C000BC260000662186008826000092218600B2
+:10A8D000CC2600000D4B10B51A680D4CD2F814169A
+:10A8E000D2F8143699420B4B18BFD2F814162268CE
+:10A8F0001B68C2EB0100984201D2002004E0B0FBCB
+:10A90000F3F003FB0023236010BDC0469C2600002B
+:10A91000E4260000C82500002DE9F04301688FB04F
+:10A92000022907461AD15A4B5A481A680023536124
+:10A93000046814F4805F11D0574B584A1960C169FC
+:10A94000043B196013680423136024F4805343F418
+:10A9500000530360524804F0B1FB96E03B680C2BB7
+:10A9600014D14C4C236813F4005F0FD023F4005330
+:10A9700043F40063236067604A48F96C04F09EFB6F
+:10A98000236803F40063002BFDD17EE03B68103B9D
+:10A990000F2B02D8FBF31EF577E03E4B4248D969F6
+:10A9A00004F08CFBBA6C786CBC68FD683968FB6C91
+:10A9B000009201903A463D480294039504F07EFBD4
+:10A9C0003B4B7E6C1B68F869D7F828E03C6A7D6ACF
+:10A9D0009B1B39697A694FEA9309BB690090354836
+:10A9E000CDF80CE00194029504F068FBB86BFC6BA9
+:10A9F0003D6CF96A3A6B7B6B00902F48019402958D
+:10AA000004F05CFBF06831687268B36800902B4812
+:10AA100004F054FBF06931697269B3690090284809
+:10AA200004F04CFB04A8FFF72BFE264804F046FB7D
+:10AA30000024A04625461CE0725912F0010F13D0E5
+:10AA4000FF2A11D9059B9A4208D91F4B1B0D1B05E4
+:10AA50009A4209D303F580139A4205D81B48294628
+:10AA600004F02CFB08F101080435B8F10F0F02D8EF
+:10AA700001344C45E0D1074A40F203301368576077
+:10AA800043F480631360FFF7BBFC0FB0BDE8F083B5
+:10AA900070F50100FCF40100241000E0281000E033
+:10AAA00054AF010058AF010064AF010071AF010065
+:10AAB000E8ED0100A5AF0100D8AF010007B001002B
+:10AAC00025B00100FC1C86009D66800042B001009C
+:10AAD000F0B51F4E8BB06846FFF7D2FD3578F5B95B
+:10AAE0000698079B1C1A07D029462246F7F3A8F2BE
+:10AAF00006982146FBF394F32146164804F0DEFA4B
+:10AB0000154B1D7001233370144B1968E9B10B7894
+:10AB1000DBB1134B2A461868F8F386F015E0114FA5
+:10AB20003D7895B90898099B1C1A07D029462246FA
+:10AB3000F7F386F208982146FBF372F30A482146A0
+:10AB400004F0BCFA012335703B700BB0F0BDC04679
+:10AB500038F5010059B001003AF50100BC260000AB
+:10AB600020F5010039F501008BB0010010B5044655
+:10AB700000F0C0DA0146204600F0FEF810BDC046E5
+:10AB800070B5044600F0B6DA204600F0F3D9054669
+:10AB9000204600F073D90022064640F62A012046DE
+:10ABA00000F02CDB0123AB408269134201D0002569
+:10ABB00000E001352046314600F032DB284670BD0A
+:10ABC00010B5FFF7DDFF10BD2DE9F04107460C463B
+:10ABD00000F090DA384600F051D940F62A0180465C
+:10ABE0000022384600F00ADB83690646456944B115
+:10ABF0004FF4004043F0004445F00045FFF792FB5E
+:10AC000007E04FF4004023F0004425F00045FFF733
+:10AC1000A7FBB46138467561414600F001DBBDE831
+:10AC2000F081C0462DE9F0410E465021804617467E
+:10AC30001D46FCF34DF0044618B300215022F7F3F3
+:10AC4000FFF140F23C736363A3F55573E363A3F52F
+:10AC5000737323640C23636404230020E56026607F
+:10AC60006760C4F80880A3640749F7F385F6C0B2AB
+:10AC700084F84C000138C0B2012802D9022384F8BC
+:10AC80004C302046BDE8F0813E29860000487047E0
+:10AC9000A8C201000048704720C301000048704767
+:10ACA00000A60E00D2F8003670B50546C3F3840442
+:10ACB000FFF7ECFF03E08378A34204D00C3020B10F
+:10ACC0000388002BF7D1038813B92846FFF7E2FF6A
+:10ACD00003884FF47A7003FB00F070BD0123C2F8C3
+:10ACE000603610B5D2F86446FFF7D8FF04F0FF04D1
+:10ACF000B0FBF4F34FF47A7003FB00F010BDC046D4
+:10AD00002DE9F0411C460646154600F0B7D8002153
+:10AD10000746304600F084DA0223C0F8583654B1B2
+:10AD2000D0F85C3605F03F0223F4FC4343EA4223AB
+:10AD3000C0F85C3603E0D0F85C36C3F345253046F6
+:10AD4000394600F06DDA2846BDE8F08170B504465A
+:10AD50000D4600F093D800210646204600F060DA48
+:10AD6000294602462046FFF7B9FF314605462046F0
+:10AD700000F056DA284670BD10B5FFF7E7FF10BDAA
+:10AD800070B504460D4600F079D8002106462046ED
+:10AD900000F046DA294602462046FFF783FF314697
+:10ADA0000546204600F03CDA284670BD2DE9F0410A
+:10ADB000DFF860800646D8F8004034BB00F05ED86B
+:10ADC00021460746304600F02BDAD0F81456D0F86A
+:10ADD000143604469D4218BFD0F8145642F2107043
+:10ADE000FBF3BAF4D4F81426D4F8143630469A4259
+:10ADF00018BFD4F814263946C5EB0203642203FBBE
+:10AE000002F3C8F8003000F00BDA024B1868BDE816
+:10AE1000F081C04680F501002DE9F04F1746C7F8D4
+:10AE200020361D46036A85B00C2BCBBFD2F82836DE
+:10AE3000D2F82836C3F3094BC3F3072B01230024B0
+:10AE4000AB4080468946029403940094FAF346F797
+:10AE50000646012212FA04F3334207D0009240461C
+:10AE600049463A46FAF33AF726EA000601341F2C1F
+:10AE7000EFD1404603A902AAFAF35AF7039B002533
+:10AE80006FEA030A2C460123A34006EA0A021A428B
+:10AE900008D0404649463A46E3B2FFF7BDFF854237
+:10AEA00038BF054601341F2CEDD10BF102004019CB
+:10AEB00005B0BDE8F08FC0462DE9704305468846D1
+:10AEC000FFF3DCF700218146284600F0A9D90446AB
+:10AED000284600F0ADF8224606464146182328468B
+:10AEE000FFF79AFF0B23023000FB03F0074C4946A3
+:10AEF0003419B4FBF6F404FB00F4284600F090D9B2
+:10AF00000A23B4FBF3F4A0B2BDE870833F420F0004
+:10AF100010B508B1FBF3E0F110BDC04670B5094BA8
+:10AF200006461D6808E030462C6800F0E3D8294644
+:10AF30006A68FBF3DDF62546002DF4D1014B1D6058
+:10AF400070BDC0466C270000002343667047C046B2
+:10AF50007047C046002070472DE9F04106460D4677
+:10AF6000144600F08FD8804618B93046012100F011
+:10AF7000C7D8304614F020FD074610B96FF01D0405
+:10AF800015E014B96FF0190418E04FF000032B809E
+:10AF9000002404F182013846F6F3CCF6C0B2A0409A
+:10AFA0002B8801341843052C2880F2D10024B8F1F5
+:10AFB000000F03D13046414600F0A2D82046BDE83C
+:10AFC000F081C04607B54FF0000302A921F8023D09
+:10AFD0000122FFF7C1FFBDF806000EBD416E2DE94D
+:10AFE000F041044661B1D0F8C83000EB8303D3F8D8
+:10AFF000D020C36D9A4203D1006E8847064600E018
+:10B0000000262046616DFFF757FFA56E07465DB12C
+:10B01000D4F8C83004EB8303D3F8D020E36D9A4210
+:10B0200002D1206E3146A8473846BDE8F081C046BF
+:10B0300010B5044600F05ED801462046FFF7B6FE84
+:10B0400010BDC04610B5044600F054D80146204655
+:10B05000FFF796FE10BDC046416E2DE9F041044653
+:10B0600061B1D0F8C83000EB8303D3F8D020C36DB2
+:10B070009A4203D1006E8847064600E0002620462B
+:10B08000616DFFF763FEA56E07465DB1D4F8C83069
+:10B0900004EB8303D3F8D020E36D9A4202D1206EF3
+:10B0A0003146A8473846BDE8F081C04643692DE9DE
+:10B0B000F743222B06460F4640F3A08000F096D8B7
+:10B0C000002800F09B80072F00F29880B268B2F54C
+:10B0D000026F01D101220AE040F604039A4201D036
+:10B0E000002204E0F3680C2B94BF002201225FFAD7
+:10B0F00082F8B8F1000F0BD130464FF400614246A0
+:10B10000D6F8C89000F07AD80546002877D006E037
+:10B11000D6F8843013F5405571D04FF00009032F55
+:10B1200003D03046012100F0FBD8D5F8303123F0B0
+:10B130000403C5F8303101239F42C5F8303103D9EB
+:10B14000042F01D0083300E00D23C5F83031D5F8C5
+:10B150003031012F23F00103C5F8303101D9042F1C
+:10B1600036D1FF2400214FF4E2722346304600948A
+:10B17000FFF38CF62223009300214FF4EE72234656
+:10B180003046FFF383F62823009300214FF4E67244
+:10B1900023463046FFF37AF68123009300214FF4D3
+:10B1A000E87223463046FFF371F601230093002135
+:10B1B0004FF4A4724FF0FF333046FFF367F630468A
+:10B1C00000214FF4A6724FF6FF730094FFF35EF672
+:10B1D000D5F8303123F0700343EA0713C5F8303156
+:10B1E000D5F8303123F00803C5F83031B8F1000F3D
+:10B1F00005D13046494600F013D800E00025284626
+:10B20000BDE8FE8370B50446FFF3F0F7002839D09F
+:10B21000A268B2F5026F01D101220AE040F60403F0
+:10B220009A4201D0002204E0E3680C2B94BF002274
+:10B230000122D5B24DB920464FF400612A46D4F818
+:10B24000C860FFF3DBF7E8B105E0D4F8843013F50C
+:10B25000405017D00026D0F8303123F00403C0F856
+:10B26000303143F00103C0F83031C3F30213032B34
+:10B2700003D02046002100F053D81DB920463146A6
+:10B28000FFF3CEF770BDC0462DE9774100220121C2
+:10B2900013460546FAF3D4F50024804621462822B9
+:10B2A000234628460094FFF3F1F501210646434664
+:10B2B00028464FF0FF32FAF3C3F5284621462822EC
+:10B2C0004FF0FF330096FFF3E1F5BDE87E81C04605
+:10B2D000D0F86C32994201D0002004E08B79D3F190
+:10B2E000010038BF002070472DE9F04100260546D7
+:10B2F0000446374608E02B68216A986804F0AED906
+:10B3000000B90136013718346B689F42F3DB3046D1
+:10B31000BDE8F08103682DE9F0411E680546B76875
+:10B32000884614463846296904F098D944B13368F0
+:10B330001B7E2BB1384629694246012304F046D9C9
+:10B34000BDE8F08170B50546044600260DE0616950
+:10B3500049B1236A3BB1182006FB00F010302818D1
+:10B360000122FFF7D7FF013618346B689E42EEDBEF
+:10B37000002070BD2DE9F3411F460368044601918A
+:10B380000092DDF820801E6809B10D2941DD616859
+:10B390000022FFF7BFFFE1680025656031B1236837
+:10B3A00022891B685868FBF3A3F4E560009B2BB16E
+:10B3B000B3F5967F02DA6FF01C002CE03046414670
+:10B3C000FFF786FF28B3019969B123681B685868A5
+:10B3D000FBF37EF4E06010B96FF01A001BE0394611
+:10B3E000019AF6F3C9F501A90422C4F8148004F106
+:10B3F0000800F6F3C1F5201D69460422F6F3BCF5FA
+:10B40000009840B1204661680122FFF783FF0020C9
+:10B4100001E06FF00100BDE8FC81C0462DE9F04776
+:10B42000154686B00268DDF84080DDF844A005F0DE
+:10B43000010300930646534610684246DDF84C90DF
+:10B4400017F042DF0746002840F0A180022D54D0BB
+:10B45000032D1FD0012D02D06FF0160797E0414653
+:10B46000042203A8F6F388F5022208F104010DF185
+:10B470001600F6F381F556F8100B4946BDF8164054
+:10B48000039D33F0B7DF214600902A46304608F18D
+:10B4900006032EE00222414605A8F6F36DF50422CC
+:10B4A00008F1040103A8F6F367F502220DF1160076
+:10B4B00008F10801F6F360F5BDF81430012B02D055
+:10B4C0006FF0240763E098F80A7073689F425CDAB3
+:10B4D00049463068BDF81640039D33F08BDF1823D2
+:10B4E00007FB03F3103300902146F0182A4608F1B9
+:10B4F0000B03FFF73FFF074649E00E9B1A6873688E
+:10B500009A4242DA002A40DB4FF00103ADF81430D2
+:10B5100004924FF00B030DF116012A4608F10200C8
+:10B52000ADF81630F6F328F505A92A464046F6F39D
+:10B5300023F504991824013101FB04612A4608F11E
+:10B540000800F6F319F5012204A908F10A00F6F340
+:10B5500013F50499042201FB046108F1040014317D
+:10B56000F6F30AF5049B013303FB04F39A5B991984
+:10B5700002F10B039A4502D26FF00D0707E008F1C4
+:10B580000B004968F6F3F8F401E06FF00107384664
+:10B5900006B0BDE8F087C046F7B5016805460E68FD
+:10B5A00096F87032002B2CD0028947693AB93046A0
+:10B5B00007F1BC01134600921CF052DD21E089899D
+:10B5C00070688918FBF3DCF32A68044618B993689D
+:10B5D0000133936015E09289A38A00699B1A801851
+:10B5E000A382E9682A892061F6F3C6F404F12402F3
+:10B5F0005389304643F0400353812146BA681CF01A
+:10B60000D1DDFEBD012801D0002000E08868704730
+:10B6100010B50C4641B18B6823B9C06F0968F7F7C4
+:10B62000C9FBA060A06800E0C06F10BD2DE9F0412B
+:10B630008D692B69994202D100273E4604E0CE6A0B
+:10B640000EB9374600E037686B681146D868FBF3DF
+:10B6500085F3AB6804461B6893F895301BB1C38A29
+:10B6600043F08003C3822846214604F033DB98B9B7
+:10B670006B6893F8AB308BB128463146FFF7C8FFB3
+:10B6800060B1214601F084DD022807D16B682146B4
+:10B69000D8680122FBF344F301200BE02846214641
+:10B6A00004F07ED8A86821463A461CF07BDD0038BD
+:10B6B00018BF0120BDE8F081536873B5112B064611
+:10B6C000154608D0122B01D0102B1CD1AB7803F0FB
+:10B6D0000103337517E002AA002342F8043D806895
+:10B6E00095F82F1033F0CADD044660B1837923B991
+:10B6F0006988C1F380011EF083DDA3791BB1B068B6
+:10B70000214600F0CFFF7CBD2DE9F3471F4643687B
+:10B710000646D3F80C9003699246D3F82480B8F11A
+:10B72000000F34D048463C21FBF3D2F200282ED043
+:10B73000054605F10C0400213C22F6F381F46C600F
+:10B740002F6004F03BD873682061A661CDF800A09B
+:10B750001021114A5B682046F6F3B6F40F4BE56200
+:10B760001B6840465B682146984700280ADD7871CF
+:10B77000736893F8AB305BB1F06F3946F7F71AFB9B
+:10B78000A86005E0484629463C22FBF3B1F20025BB
+:10B790002846BDE8FC87C04647438600F8260000DF
+:10B7A0002DE9F341044601920E4611B9D0F81080FC
+:10B7B00001E0D1F804800199D8F82450CB8A13F421
+:10B7C000006201D001271CE02046174603F0DADFB3
+:10B7D000636893F8AB30A3B120463146FFF718FFFA
+:10B7E00078B1019901F0C6DB042801D0012804D109
+:10B7F00063680199D8683A4646E0052801D10126D8
+:10B8000000E00026636893F8953023B11FB9019AD0
+:10B81000938A2D339382002D32D0DFB9EB6913F078
+:10B82000010F07D0637D2BB12046019904F0B6D8F3
+:10B83000024658B176B9636893F8963053B1D4F89C
+:10B840008400019903F050FA024618B9636801991F
+:10B85000D86819E0204601A904F098DAB0B9636805
+:10B860000199D868FBF3B6F22B690446DB684046C1
+:10B8700029462246984748B12046FBF3E7F105E008
+:10B8800063680199D8682A46FBF34AF2BDE8FC8157
+:10B890004B6A10B591F8432043F480134B62D0F803
+:10B8A000883002F00702D21892F88030013382F813
+:10B8B0008030D0F88820012382F88630D0F88810B4
+:10B8C00091F8812091F87B309A4211D291F8802032
+:10B8D00091F87A309A420BD291F8822091F87C301C
+:10B8E0009A4205D291F8832091F87D309A4201D393
+:10B8F00004F0FCDC002010BD1FB5084B024600938D
+:10B90000074B08460193074B0749DB69029312680E
+:10B91000064BF6F301F605B000BDC046E1C30100D9
+:10B92000A4C30100FCF40100B2C30100D5C30100AF
+:10B9300010B5436804461B7E53B1D0F88000FFF772
+:10B94000D3FCA068F9F74CFB6268002382F8203032
+:10B9500010BDC04610B58069FFF7EAFF002010BD9A
+:10B9600070B50446636880681E7E0EB1002515E040
+:10B97000F9F7F8F9054620B9D4F88000FFF7E2FCA2
+:10B980000546FFF7A5F86368D3F89C1031B10B7832
+:10B9900023B1034B32461868F7F346F1284670BDD1
+:10B9A00020F5010010B58068F9F702FB002010BDFA
+:10B9B00010B50446FFF7F6FFA068FCF771FA10BD5A
+:10B9C00013B54FF0000310F00104ADF8063006D0B7
+:10B9D000002904DD10F8013B01398DF8073010F023
+:10B9E000030F05D0012903DD30F8022B023913E0E3
+:10B9F000002211E00368D218436828BF0132D21830
+:10BA0000836828BF0132D218C36828BF0132D21818
+:10BA100028BF01321030103931F00F03EAD113047E
+:10BA20001B0C03EB124203E030F8023C0239D2183F
+:10BA3000034602300129F7DC04BF1B788DF806307D
+:10BA4000BDF80630D3181A04120C02EB134213048B
+:10BA50001B0C03EB124024B1030243EA1023180429
+:10BA6000000C1CBD10B5FFF7ABFF02E003041B0C7C
+:10BA70009818020CFAD1C04380B210BD2DE9F041F4
+:10BA8000BDF818500C46294616469846FFF798FF11
+:10BA90003204120C02EB14422404240C121905F097
+:10BAA000FF0302EB16421B0202EB082243EA1523B6
+:10BAB000D218101802E003041B0C9818020CFAD1DB
+:10BAC000C04380B2BDE8F0812DE9F0418D8A164671
+:10BAD0000D2D1F460C6952DDA38904F10C0003F003
+:10BAE000FF021B0A43EA0223B3F5C06F0BD2152DE8
+:10BAF00045DD254804F10E010622F6F321F2002867
+:10BB00003DD104F11400038803F0FF021B0A43EA4D
+:10BB10000223B3F5014F0AD10430821C63199A4203
+:10BB20002DD8038803F0FF021B0A43EA0223B3F572
+:10BB3000006F24D1811CC4EB0103C3EB0504132C5B
+:10BB40001DDD82781309042B19D102F00F039A002E
+:10BB5000132A14D9A24212DC8A78CB7843EA022352
+:10BB6000A34201DA1C4600E009DC8A79CB7943EA7A
+:10BB700002239804800C10B931603C6001E04FF062
+:10BB8000FF30BDE8F081C04631C401002DE9F0432B
+:10BB9000436887B013F0020F0546884600F08F8097
+:10BBA00005AA04ABFFF790FF0028C0F28880059833
+:10BBB000037803F00F039E003146FFF753FF48B1AF
+:10BBC000B8F8163023F01003A8F816302B6A0133AA
+:10BBD0002B6274E0EB69059F0133EB6197F80990E4
+:10BBE000B9F1060F24D107F10C01042202A8049C2C
+:10BBF000F6F3C2F1059904221031A41B03A8F6F351
+:10BC0000BBF1A4B2B8190299039A4B460094FFF70E
+:10BC100035FF48B1B8F8163023F01003A8F81630F5
+:10BC2000AB6A0133AB624AE06B6A01336B623EE0A0
+:10BC3000B9F1110F24D107F10C01042203A8049CCF
+:10BC4000F6F39AF1059904221031A41B02A8F6F329
+:10BC500093F1A4B2B8190399029A4B460094FFF7E6
+:10BC60000DFF48B1B8F8163023F01003A8F81630CD
+:10BC70002B6B01332B6322E0EB6A0133EB6216E09E
+:10BC8000B9F1010F13D10499B819891B89B2FFF7D3
+:10BC9000E9FE48B1B8F8163023F01003A8F81630C2
+:10BCA000AB6B0133AB630AE06B6B01336B63B8F8CA
+:10BCB0001630002043F01003A8F8163001E04FF0D2
+:10BCC000FF3007B0BDE8F0832DE9F043436887B04B
+:10BCD00013F0010F804600F08780CB8A13F0080F25
+:10BCE00003D18368013383607EE005AA04ABFFF7CC
+:10BCF000EBFE002878DB059A00271378977203F093
+:10BD00000F039E00D77231460598FFF7ABFE059BE7
+:10BD10009872C0F30F20D872D8F80C30059901330F
+:10BD2000C8F80C3091F80990B9F1060F21D18D199E
+:10BD3000049C0C3104222F746F7402A8F6F31CF1DA
+:10BD4000059904221031A41B03A8F6F315F1A4B23F
+:10BD50004B4628460299039A0094FFF78FFE2874F9
+:10BD6000C0F30F206874D8F810300133C8F81030D1
+:10BD70003AE0B9F1110F22D18D19049CAF71EF7126
+:10BD8000059904220C3103A8F6F3F6F00599042274
+:10BD90001031A41B02A8F6F3EFF0A4B24B462846DC
+:10BDA0000399029A0094FFF769FEA871C0F30F206F
+:10BDB000E871D8F814300133C8F8143014E0B9F140
+:10BDC000010F11D18C1904992046891BA770E770C7
+:10BDD00089B2FFF747FEA070C0F30F20E070D8F8DB
+:10BDE00018300133C8F8183007B0BDE8F083C046FA
+:10BDF0002DE9F34114460A9F0268DDF82C8004F017
+:10BE0000010300930546434610683A4617F05CDA92
+:10BE1000064618BB052C04D8DFE804F00A06140314
+:10BE2000030D6FF0160619E0281D3946042213E0B1
+:10BE30006B683B6012E005F1080000214C22F6F32C
+:10BE4000FFF00BE0B8F14B0F02D86FF00D0605E0E4
+:10BE5000384605F108014C22F6F38EF03046BDE875
+:10BE6000FC81C04610B58C6B00200BE00B1893F8DA
+:10BE70003C30064A03F07F03D356002B01DA012041
+:10BE800003E00130A042F1D1002010BD401B86002C
+:10BE90002DE9F84F022983460E4690469A4614BF74
+:10BEA0004FF0FF37002714BF002401244FF0000992
+:10BEB0002EE0022E14BF4FF0FF3300239F4211D01B
+:10BEC000022E08D1B8F1040F07D0B8F1060F04D044
+:10BED000B8F1080F01D0042200E00022C7EB0403F0
+:10BEE000934214DD0E2CCCBF4FF480534FF400531B
+:10BEF00044F4306213439DB2DBF85C0129463AF00A
+:10BF00004DDA20B12AF81950274609F10109013408
+:10BF1000022E0CBF0E2300239C4202DCB9F11F0F3E
+:10BF2000C7D90A9BC3F80090BDE8F88F2DE9F04F00
+:10BF300088469BB040210027DDF890B09DF8949092
+:10BF40000646C0F82077C0F81C1740689A46FAF3F6
+:10BF5000BFF60446C6F8180710B96FF0150473E071
+:10BF6000D8F800306BB92033C6F82037336B304631
+:10BF70001A8906F5E463009359462346FFF788FFC4
+:10BF80001FE0202B6CD8454617E0AC88D6F85C0142
+:10BF900021463AF003DA002862D01FB12B78E2B2D2
+:10BFA0009A425DD9D6F82037D6F81827013722F8FB
+:10BFB00013400133C6F820370435D8F800309F42CB
+:10BFC000E3D3D6F82037002B4AD070681021FAF35B
+:10BFD0007FF60746002835D0279B002411AD44602A
+:10BFE000836004732146066080F80DB080F80E90DF
+:10BFF00024222846F6F324F0A24514BF002301238F
+:10C0000001934FF0FF330293039304930593D6F803
+:10C01000183730460693D6F8203702210793144B81
+:10C02000144A0A9303230C930123089409940D9452
+:10C030000E9400950B971AF05FDF044698B9269B83
+:10C040007B6010E06FF01A04D6F8181759B17068C9
+:10C05000D6F81C27FAF34CF60023C6F8183702E08E
+:10C060006FF00104F0E720461BB0BDE8F08FC0463A
+:10C07000F9C500002C9E850030B590F8143789B0C2
+:10C080000446002B3ED0D0F868319D79002D62D156
+:10C09000036880F814571B7E002B5CD0B0F816376D
+:10C0A000002B58D0036B186903F0A8FEB4F81617DC
+:10C0B000884250D020461CF073DE204603F0AAF8D8
+:10C0C0002046B4F816171CF0B1DC236893F82F3023
+:10C0D0006BB1D4F86C322046D3F8D412383117F053
+:10C0E0005DDB0146C4F8AC06204610F0F5DB2046C7
+:10C0F0001EF00CDF204629461FF012D9204615F00D
+:10C100007FDF28E003681B7E2BB3D0F868319B7972
+:10C110000BBBD0F8000507A948F0DCDF03E02B7E5D
+:10C1200013F0020F17D107A848F0DCDF05460028FE
+:10C13000F5D1236B05901B6805A900930323019398
+:10C1400002900390012220462B46FFF7EFFE10B924
+:10C15000012384F8143709B030BDC0462DE9F74FEC
+:10C160000192D0F800A090F80D801F460C464FF0C9
+:10C17000000BE5E0072200212046F5F361F70C9A59
+:10C18000B8F1020F12F81B00207001D0022308E062
+:10C19000042F05D0062F03D0082F01D0434600E01E
+:10C1A0000023C3EB0002B8F1020F14BF00230123E8
+:10C1B0009A4210DBB8F1020F01D0022108E0042FEF
+:10C1C00005D0062F03D0082F01D0414600E0002102
+:10C1D000C1EB00060FE0B8F1020F14BF00260126E4
+:10C1E00006E0DAF85C0131463AF096D818B9013623
+:10C1F00023789E42F5D9B8F1020F207802D00022B0
+:10C2000002230BE0042F07D0062F00F0A680082F92
+:10C2100000F0A3804346A1E00E2200231B189342A6
+:10C220000FDCB8F1020F01D0022108E0042F05D085
+:10C23000062F03D0082F01D0414600E000210D1841
+:10C240000FE0B8F1020F0CBF0E25002506E0DAF86A
+:10C250005C0129463AF060D818B9013D23789D4227
+:10C26000F5D24FF0000963E002EB89039968CB88AF
+:10C27000B1F832E013F020035FFA8EF00DD00EF427
+:10C280004072B2F5807F02D1821C023806E0B2F51E
+:10C29000007F02D1821E023000E00246B04201D38C
+:10C2A000A84203D9B24241D3AA423FD8B3B1B04267
+:10C2B00014D3A84212D80EF44073B3F5807F05D191
+:10C2C0002379FF2B0AD00133237107E0B3F5007FF8
+:10C2D00004D16379FF2B01D001336371CB8813F054
+:10C2E000200F0BD0B24209D3AA4207D8824205D010
+:10C2F000A379FF2B1AD00133A37117E023780E2BFB
+:10C300000FD85046FFF7AEFD28B1E378FF2B0DD0D4
+:10C310000133E3700AE0A378FF2B07D00133A37049
+:10C3200004E06378FF2B01D00133637009F1010948
+:10C33000DAF818251368994596D30BF1010B0734E9
+:10C340000D9B9B4504DA019A13689B45FFF612AFDB
+:10C35000019BC3F800B0BDE8FE8F00230E225DE70D
+:10C360002DE9F84F5FFA83FC1E4603F44073B3F5E2
+:10C37000007F14BF4FF000094FF0010905468A46BF
+:10C3800093460CF10200ACF10203B9F1000F02D0A8
+:10C390008646984601E09E4680460027394629E0B9
+:10C3A00011F80A40ACF105039C4221DB0CF10503B6
+:10C3B0009C421DDC0AEB010082783AB9C3782BB9A4
+:10C3C00003791BB943790BB983798BB1744506D1D5
+:10C3D000837993B9B9F1000F08D0037907E0444598
+:10C3E0000BD152B9C37843B9037933B9437923B92F
+:10C3F000013707315F45D3DB1BE0BEF10E0FD4BF21
+:10C400004FF400534FF480534EF4306213439CB208
+:10C41000D5F8FC341B7893B12846002128F0ECDADB
+:10C42000284628F0DFDA0AE02846012128F0E4DA7D
+:10C4300004E0D5F8FC341B78002BF5D134462046B7
+:10C44000BDE8F88F2DE9F04FD0F8008090F80DA0EE
+:10C45000D8F83010DDB00989814614464FF0000B42
+:10C460005B9300E0042100225B98964608E01EF8EA
+:10C4700004300EF1070E052B01D9934602E001327C
+:10C480008242F4DB082900F2B08001A252F821F0C8
+:10C49000B5C40000EBC50000BBC40000EBC5000044
+:10C4A00067C50000EBC50000EBC50000EBC5000050
+:10C4B00065C400004FF6FF761AE00025AE464FF641
+:10C4C000FF7612E00EEB0B0292FBF0F300FB13235E
+:10C4D000072203FB02F16218937823B9D378B342A1
+:10C4E0003CBF655C1E460EF1010E8645EADB15B9C0
+:10C4F0000025AC4621E00E2D94BF4FF400524FF4BE
+:10C50000805245F4306343EA02006FE00CEB0B020B
+:10C5100092FBF0F300FB1323072203FB02FE04EB64
+:10C520000E0359789A78DB785218D218B242BCBF01
+:10C5300014F80E5096B20CF1010C8445E6DB3DB9BF
+:10C540009BFBF0F300FB13B3072203FB02F31D5D1B
+:10C550000E2D94BF4FF400534FF4805345EA03036C
+:10C5600043F4306042E0BAF1020F3ED15AAB00937F
+:10C5700000244046514652464AAB5A94FFF788FC85
+:10C58000D8F818771FB3D8F8206706B35A9925460C
+:10C5900010E000243AAB37F81520E05A904205D15C
+:10C5A0005CAA02EB410323F8480C01310234402C11
+:10C5B000F0D10135B542ECDB20230E485B935A9154
+:10C5C00002F07CFD4AAB00935A9B02AC04E02023AE
+:10C5D0003AAA5B9302AC00920193214648465BAABB
+:10C5E0000223FFF7BBFD02213DE700205DB0BDE85F
+:10C5F000F08FC046B0C40100F0B50546BDB0046878
+:10C600000E4609B108292DD12023D4F818273B93D1
+:10C61000236B03AF1B890092D4F82027394601927F
+:10C620003BAAFFF79BFD6B7B022B13D1D4F8FC34A4
+:10C630001B787BB1D4F83437B3F8A4E30EF440632D
+:10C64000B3F5406F06D1204639463B9A7346FFF753
+:10C6500087FE05E02846002103AA3B9BFFF7F2FE78
+:10C66000A4F816076B6813B1A86831469847D4F848
+:10C670001817D4F81C276068FAF33AF30023C4F8BB
+:10C680001837606829461022FAF332F33DB0F0BD46
+:10C69000002070470020704700207047012380F879
+:10C6A0007A3070477FB591F8943006460C4643B314
+:10C6B000D0F8000503A948F00DDD10E02B7E13F043
+:10C6C000020F0CD02B69A34209D101230093DB1880
+:10C6D0000193304621462A46002348F013DE03A882
+:10C6E00048F000DD05460028E8D13C23C4F88C3032
+:10C6F000F9F388F70123C4F8900084F8945084F883
+:10C7000084307FBD036870B545680E4658680C21BB
+:10C71000FAF3DEF2044610B96FF01A0005E00021CA
+:10C720000C22F5F38DF47451002070BD70B50446F1
+:10C730000E4640684FF48471FAF3CAF208B9054610
+:10C740000AE000214FF484720546F5F379F4D4F839
+:10C7500048312C606E60AB60284670BD83682DE95F
+:10C76000F0415D6803684C5907460E4601EB050829
+:10C7700058684FF48471FAF3ABF2606000282FD050
+:10C780007359002158684FF48472F5F359F43B68EB
+:10C79000C42158687459FAF39BF2A06000B373592E
+:10C7A00000219868C422F5F34BF473592B499C6817
+:10C7B0003B683A4623603B689868002302F07CDFC0
+:10C7C000A06668B1735926499C683B683A469868E8
+:10C7D000002302F071DFC4F8C00008B100203AE085
+:10C7E000D8F80030996831B3896E41B13B689868D8
+:10C7F00002F046DFD8F800309A6800239366D8F834
+:10C8000000309B68D3F8C01049B13B68986802F0CB
+:10C8100037DFD8F800309A680023C2F8C0303B6890
+:10C82000D8F8002058689168C422FAF361F2D8F869
+:10C83000002000239360D8F80030596849B13B6864
+:10C840004FF484725868FAF353F2D8F800200023AA
+:10C8500053606FF01A00BDE8F081C046A9D6000011
+:10C86000E1D0000010B5014628B103684FF484728E
+:10C870005868FAF33DF210BDD0F8483170B55D68E4
+:10C880000646E9420C4640D0495900293DD0496846
+:10C8900059B14CF0DBDE63594FF48472596870680B
+:10C8A000FAF326F26259002353606359996800290C
+:10C8B0002BD0896E61B1B06802F0D0DE6359B068E8
+:10C8C0009B68996E02F0DCDE63599A6800239366D8
+:10C8D00063599B68D3F8C01071B1B06802F0BEDE36
+:10C8E0006359B0689B68D3F8C01002F0C9DE635981
+:10C8F0009A680023C2F8C0306359C42299687068EE
+:10C90000FAF3F6F162590023936070BDC16810B567
+:10C91000044621B10068FFF7AFFF0023E36010BDBC
+:10C9200070B5044600680D46FFF7A6FF2068002199
+:10C930004318D3F84C3233B15A6922B1D368AB42B1
+:10C9400001D10023D36004312029F1D164682B196F
+:10C950003BB1295929B140680C22FAF3C9F10023EF
+:10C960002B5170BD70B50568044604F1DE01284600
+:10C97000102215F0CFDE284604F1EE01102215F04A
+:10C98000C9DE70BD2DE97043A4B004680DF18306C3
+:10C9900081460DF163050D2230461949F5F3ECF29D
+:10C9A00020462946102215F0B5DE05F110011022AF
+:10C9B000204615F0AFDE3046F5F3D2F3D9F8042067
+:10C9C0002024C23200920622034601920DF1130880
+:10C9D00021463246284609F17E05CDF808800394A9
+:10C9E000FBF3B2F2414622462846F5F3C5F209F1BF
+:10C9F0009E0029462246F5F3BFF224B0BDE87083BD
+:10CA0000C2C4010070B500F17E0405462021204615
+:10CA1000F7F326F0204605F19E012022F5F390F26F
+:10CA200010B92846FFF79EFF70BDC046F0B58B6D6C
+:10CA3000DFB013F0010F07460C464CD113F0020F84
+:10CA400005D113F0040F46D04FF0100301E04FF072
+:10CA5000200359ADA7F87C302049142205AE2846A2
+:10CA6000F5F38AF204F1C201062207F1BE04304652
+:10CA7000F5F382F207F17E0120222046F5F37CF2E5
+:10CA80003846FFF7BFFF214620220DF11A00F5F3CB
+:10CA900073F22846F5F364F345AC26220096019222
+:10CAA0000294B7F87C200346039220212A4607F11E
+:10CAB000DE00FBF349F22146B7F87C2007F15A006B
+:10CAC000F5F35AF207F1FE0000210822F5F3B8F25F
+:10CAD0003846FFF7E3FD5FB0F0BDC046CFC40100AC
+:10CAE0007FB50292436802AE9B680D4600930068D2
+:10CAF000B72132460823FBF7BDF9044610B14FF0C9
+:10CB0000FF3005E0284631460822F5F335F220468D
+:10CB100004B070BD2DE9F04700F1FE088946924649
+:10CB20001788414690F87B200646FFF7D9FF20B1D1
+:10CB3000404600210822F5F383F209F171056FF0F8
+:10CB40002203EB5596F87C30EC1906336370A01C79
+:10CB500003221349F5F310F20123637196F87A303A
+:10CB6000BC1DA4B203F003032B55281906F15A018A
+:10CB7000B6F87C200230F5F3FFF1B6F87C3009F10D
+:10CB80004F00023341460822E418F5F3F5F1A4B250
+:10CB9000AAF80040B6F87C000830BDE8F087C0462F
+:10CBA0006EA701002DE9F74F99460368B0F87C4065
+:10CBB00005468B46586820219046FAF389F00746CF
+:10CBC00008B904467BE02B684FF480715868FAF38B
+:10CBD0007FF08246002862D02B684FF4817158683C
+:10CBE000FAF376F0064600286DD0B8F1010F03D0B5
+:10CBF000B8F1020F24D064E005F18E01102238460E
+:10CC0000F5F3BAF10BF19C01102207F11000F5F3D6
+:10CC1000B3F105F15A0122464846F5F3ADF1384625
+:10CC200020213246FBF396F4504632464FF4807191
+:10CC3000FBF3C0F4484621463246FBF3BBF42AE03E
+:10CC4000B5F87C300F2B09D805F15A000019C4F152
+:10CC500010020021F5F3F4F110240EE014F00703A4
+:10CC60000BD005F15A000019C3F108020021F5F3B9
+:10CC7000E7F124F0070308339CB210200BF19C016C
+:10CC8000224605F15A03CDF80090F3F359F2C0B9EA
+:10CC900004F108039CB20C9B1C80012414E006469E
+:10CCA00004462B68394658682022FAF321F036B141
+:10CCB0002B68314658684FF48172FAF319F0204618
+:10CCC0000AE0002008E004462B68514658684FF4FB
+:10CCD0008072FAF30DF0E4E7BDE8FE8F2DE9F04F26
+:10CCE0009FB0059202680746884606921E46002BB2
+:10CCF00000F0E88183685B68F358D3F804909B6880
+:10CD00000793059B022B37D0042B00F00A81002BE0
+:10CD100040F0D8811046796806F11A0271334AF062
+:10CD2000C9DA8246002800F0CD8105694FF4BE4281
+:10CD300005F112062A8205995F223046F5F380F14B
+:10CD400048F08802130AEB742A75B9F8182009F123
+:10CD50001C04130A6B75AA7521460698202215F04B
+:10CD6000D9DC214605F11F002022F5F305F1059CD1
+:10CD70000B23C9F80030A8E1B9F80221B2F5007F11
+:10CD800002D141F472780AE0802A04D141F49E581D
+:10CD900048F0080803E0042A08BF41F4E4787B68FF
+:10CDA000B9F804A09B6DADF876A013F0020F0CBF8C
+:10CDB00004250225802A30D118F4805F2DD03B8ACB
+:10CDC00013F001041BD13846FFF7CCFD38467968D3
+:10CDD000FFF72CFE97F87A20B7F87C3000920122FA
+:10CDE0000392019502940698796807F15A024CF073
+:10CDF000FBDA3B8A87F87B0043F001033B82B7F8FC
+:10CE00007C3010339AB2BDF8763013F0070105D0AC
+:10CE100002F108035B1A9AB200E000220AF17103E2
+:10CE2000D3180698796806F11A029BB24AF042DAE2
+:10CE30008246002800F0468105694FF05F0305F146
+:10CE4000120600215F222B823046F5F3F9F04FEAFB
+:10CE50001823EB7485F81480B9F8182009F11C0127
+:10CE6000130A6B75AA7505F11F002022F5F384F0F3
+:10CE7000B9F8042005F17100D9F80810F5F37CF039
+:10CE8000BDF8763003F0FF021B0A43EA022386F85E
+:10CE90005D30C3F30F2386F85E30B9F80231802B82
+:10CEA0002ED118F4805F2BD00DF17602384629463A
+:10CEB000FFF730FEBDF8763005F13F0003F0FF02CA
+:10CEC0001B0A43EA022386F85D30C3F30F2386F87A
+:10CED0005E30AB7B022B04D100211022F5F3B0F0C1
+:10CEE00004E007F18E011022F5F346F0304641468A
+:10CEF00009F19C020023F6F30BF5002800F0E48012
+:10CF000096F85D3096F85E2042EA03222B8AD2180A
+:10CF100092B202F0FF031B0243EA12232B820C237E
+:10CF200080E090F87A304FF000021B0103F03003EC
+:10CF300041EA0303ADF8762043F460731FFA83F8E7
+:10CF4000B0F87C30796871339CB218F0020F1CBFC6
+:10CF500004F108039CB2069806F11A0223464AF02F
+:10CF6000A9D98246002800F0AD8005694FF05F0323
+:10CF700005F112060021A4F112022B823046F5F3CE
+:10CF80005FF04FEA1823EB7485F81480B7F87C2023
+:10CF900007F1BE01130A6B75AA7505F11F00202267
+:10CFA00005F13F0407F18E0BF4F3E6F71022594622
+:10CFB0002046F4F3E1F7082207F1FE0105F14F00E6
+:10CFC000F4F3DAF70DF176030093384605F17103B7
+:10CFD000494608F00302FFF7E5FDAB7B022B05D1C4
+:10CFE000204600211022F5F32BF004E0204659469C
+:10CFF0001022F4F3C1F7BDF8762002F0FF01130A06
+:10D0000043EA012386F85D30C3F30F2386F85E30D0
+:10D010002B8AD21892B202F0FF031B0243EA1223BA
+:10D020002B820F230124C9F800304EE0022301E0D7
+:10D030006FF001033370701D09F15C010822F4F3F5
+:10D040009BF78CB10DF12604284608F0030109F185
+:10D050008C022346F6F31AF5002833D006F14D0072
+:10D0600021461022F4F388F7B9F80231B3F5007FB6
+:10D0700005D1DAF8243043F08073CAF82430069AD8
+:10D08000136893F895305BB1059B0BB1022B07D168
+:10D09000DAF8243023F4403343F48033CAF82430E0
+:10D0A0007B6851469A6806981BF07CD8069A079BC5
+:10D0B0009068D3F8C0104FF47A72002302F086DA39
+:10D0C000012009E0002007E004460323EB73B9F8D0
+:10D0D0000231802BAAD0ABE71FB0BDE8F08FC0466D
+:10D0E00070B5C5680446002D4FD083685B68EB5867
+:10D0F0005968002949D00B8A042B14BF0126022647
+:10D100000B680C2B1CD00F2B2AD00B2B3DD191F888
+:10D110000421531C022A81F8043108D9C16821B1C5
+:10D1200040681A310F224CF035DA20461FE001F139
+:10D130005C000821F6F394F420463146002221E0F9
+:10D1400091F80421531C022A81F804310FD801F10F
+:10D150005C000821F6F384F420463146022211E0F7
+:10D1600091F80421531C022A81F8043102D9FFF7F7
+:10D17000CDFB0AE001F15C000821F6F371F42046D2
+:10D18000314604222B46FFF7A9FD70BDF0B50C46D1
+:10D19000B5B00546002838D0002936D0038A4FF6AE
+:10D1A000FD7103EA010101826388228813F0010FF7
+:10D1B0001CD0A2F108039BB2382B26D8402A1AD1E2
+:10D1C00003AF00233846211D00934CF0A5D8064636
+:10D1D00088B905F11A0007F148012022F4F3CCF6D2
+:10D1E0002B8A304643F002032B8210E0202A0CD118
+:10D1F00041F002030382211D228805F11A00F4F395
+:10D20000BBF6248800202C8301E06FF0010035B0CC
+:10D21000F0BDC04613B58E46144601461A4670B19D
+:10D220006BB183685B68D3580A8B986852B1C38826
+:10D2300043B91A31734600944CF06ED803E04FF0B6
+:10D24000FF3000E000201CBD2DE9F04F89B00746FB
+:10D250000C46D0F800900593002B00F032818368D3
+:10D26000059A5B68D3585D68D3F808A0002D00F0DC
+:10D270002881BAF1000F00F024812B8A042B14BFFF
+:10D28000012302230793B5F80231802B05D0B3F5B3
+:10D29000007F02D0042B40F0148105F15C031A4694
+:10D2A00094F81380267D0120069304F117010823CA
+:10D2B000F6F3C8F1069A904200F005812B6846EA21
+:10D2C00008260C2B5FD00F2B00F0E1800B2B40F0D9
+:10D2D000FA8006F4DC73B3F5847F40F0F48005F146
+:10D2E0003C09202204F11F014846F4F345F6059B52
+:10D2F000796803F11A0B0AF148030093BAF8063073
+:10D3000005F18C080193CDF80880AB8AC2310393F4
+:10D31000584605F11C024B46F6F3FAF116F4807FED
+:10D3200008D0204606F003014246F6F351F20028E9
+:10D3300000F0C98094F8702094F86F3052EA03230B
+:10D3400008D0EA889A4205D104F17100E968F4F343
+:10D35000F7F528B17868594611224CF01BD9B2E094
+:10D3600085F804013B68DAF8C010986802F076D9B5
+:10D3700006980821F6F374F3384607990222059BB4
+:10D38000FFF7ACFC9FE006F4D873B3F5807F40F064
+:10D390009A8016F4807F09D0204606F0030105F13B
+:10D3A0008C02F6F315F2002800F08D80002385F83A
+:10D3B00004313B68DAF8C010986802F04FD9059A3A
+:10D3C0002B8B02F11A082A8ACDF804800092484675
+:10D3D000796805F1AC024CF077D8B5F80241802CA1
+:10D3E00002D110232B6034E0042C32D10D232B60AA
+:10D3F0003B8A13F0010622D13846FFF7B3FA3846CC
+:10D400007968FFF713FB97F87A20B7F87C30012A88
+:10D4100014BF0122022287F87A2000922A8A0296FB
+:10D420000192012203924846796807F15A024BF0B3
+:10D43000DBDF3B8A87F87B0043F001033B820698E1
+:10D440000821F6F30DF3384607992246059BFFF7AE
+:10D4500045FCB5F80231B3F5007F04D1D9F8440199
+:10D46000414601F075F9B5F80231802B01D0042B4B
+:10D4700008D17B6848469B68792100934246062381
+:10D48000FAF7F8FCB5F80231802B1CD115E016F440
+:10D49000807F07D0204606F0030105F18C02F6F3E9
+:10D4A00097F180B1002385F804313B68DAF8C010A9
+:10D4B000986802F0D3D810232B603846FFF726FA7D
+:10D4C00001E0002000E0012009B0BDE8F08FC04677
+:10D4D00070B50E46054670B1CC7B032C0BD1456967
+:10D4E000012D08D18C7C022C01D0FE2C03D1FFF73A
+:10D4F000ABFE284600E0002070BDC0462DE9F34792
+:10D50000DDF82C800646924699460C46002943D009
+:10D51000B8F1000F40D0836800685B6858F80330AA
+:10D520005D689F6829464CF091D809232B602378C9
+:10D530003068302B736829460BBFB3F86230B3F8FC
+:10D54000623003F0800303F00403A5F802310A9B64
+:10D55000224601935346CDF800904CF097D8D8B1AD
+:10D560007369012B01D1FB88B3B1002485F8044114
+:10D570003368D7F8C010986802F070D8298A0A2357
+:10D580002B603046042914BF012102212246434664
+:10D59000FFF7A4FB012000E00020BDE8FC87C046A7
+:10D5A00007B59E4660B101290AD14161059B11462C
+:10D5B0000093069B72460193049BFFF79FFF00E0D8
+:10D5C00000200EBD2DE9F04146681546D6F8D4324C
+:10D5D000D0F800805A8EADF5067D02F47042044604
+:10D5E000B2F5805F14BF00220122404648F0E0D827
+:10D5F0000746002853D04FF40073859345B1E36884
+:10D60000002B4CD120463946FFF7A8F8002846D118
+:10D61000A36820465B68FB589D68FFF7B3F9B6F82E
+:10D620006230BB8703B1E760238A13F0020F09D091
+:10D6300005F1480004F11A012022F4F39DF44FF0A3
+:10D640002003EB80EB88202B17D185AB009340465D
+:10D6500050213A6905AB01F0D7FC08AB0093859BDC
+:10D6600020460C3B0193E36801210293D7F8E820A0
+:10D67000D7F8EC30FFF794FF11E06368B3F862303D
+:10D68000B3F5007F04D1706906F1BC01062203E006
+:10D690007069727E06F11A013B46FFF7BBFD0DF57E
+:10D6A000067DBDE8F081C0462DE9F047C768054614
+:10D6B000D0F800907FB383685B68FB589C6854B3D4
+:10D6C00004F16C0630464FF48071FAF35DF3804646
+:10D6D000D0B904F1480120223046FAF395F34FF017
+:10D6E0002003E3806B6807F11A01B3F86230B3F5E9
+:10D6F000007F04D1D9F8440101F026F80BE0284658
+:10D700004246FFF75FFF06E00022D9F80800A16E4D
+:10D71000134601F05BDFBDE8F087C0467047C046A6
+:10D7200010B5C3F8A010082019461C4635F098D84B
+:10D7300084F8A40010BDC04600207047002010608F
+:10D740007047C04600207047002070472DE9F04721
+:10D75000044688464768002110469146C922F4F3E2
+:10D760006FF42046414638F019DE78B997F8503703
+:10D77000002B00F0DB8707F5AA6138460E3138F040
+:10D7800067D80646002800F0D18700E0266908F433
+:10D790007043B3F5805F14BF38233C233078FF58C3
+:10D7A00038F0E8D90446B07837F0ECDD637C5FFAF6
+:10D7B00088F513F00102064602D097F904E106E06D
+:10D7C00097F90431182BD4BF9646A3F1180E934B4A
+:10D7D0009C4203D158214FF0520C0BE0904B9C42DD
+:10D7E00005D0904B9C4202D04FF07F0C01E04FF0EF
+:10D7F000580C61463B68022B5FD1012D01D80023F4
+:10D8000003E00A2D8CBF02230123E31893F90620BD
+:10D81000854B9C4203D10B2D10D14C2240E0834B11
+:10D820009C4203D10E2D3BD1362239E0804B9C42E5
+:10D8300002D0804B9C4204D10B2D30D00E2D2ED027
+:10D840002EE07D4B9C4203D10E2D29D12A2227E0C8
+:10D850007A4B9C4207D1022D01D1582220E00A2D9B
+:10D860001ED154221CE0764B9C4203D10A2D17D1C5
+:10D87000502215E0734B9C4203D10E2D10D128226B
+:10D880000EE0714B9C4203D10B2D09D13E2207E0E3
+:10D890006E4B9C4204D10C2D02D1442200E0402268
+:10D8A000CEEB020323EAE3738B42A8BF0B460022B0
+:10D8B00002F809300132042AFAD1654B9C4208D0A3
+:10D8C000644B9C4205D0644B9C4202D0634B9C420B
+:10D8D00007D197F90431182BD4BF4FF0000EA3F1F4
+:10D8E000180E3A68022A40F00D81012D01D8032359
+:10D8F00003E00A2D8CBF05230423E31893F90600E7
+:10D90000494B9C4201D10B2D6CE0554B9C4204D1FC
+:10D91000022D00F00B810A2DD2E0444B9C4201D134
+:10D920000B2D58E0424B9C4202D0424B9C4201D10D
+:10D930000B2D11E04B4B9C4202D04B4B9C4204D12F
+:10D940000D2D40F004812E2001E1484B9C4206D170
+:10D950000B2D00F0F1800D2D00F0F080F7E03E4B34
+:10D960009C4258D0344B9C4204D10B2D40F0EF80A8
+:10D970003E20ECE0314B9C4219D0314B9C4206D109
+:10D98000022D00F0E1800A2D00F0DE80DFE0384B50
+:10D990009C4206D1022D00F0D5800A2D00F0D280E5
+:10D9A000D5E0344B9C4202D0334B9C4206D1022D31
+:10D9B00000F0C6800A2D00F0C380C8E02F4B9C42C7
+:10D9C0000CD1022D00F0BA800A2D00F0B780032D93
+:10D9D00000F0BC80092D00F0B980B8E0284B9C42D3
+:10D9E00003D10A2D00F0A480B1E0164B9C4205D172
+:10D9F000A5F10C03012B40F29D80A8E0214B9C4235
+:10DA000003D10B2D00F29A80A1E01F4B9C423DD127
+:10DA10000C2D00F093800D2D43E0C046BC10860015
+:10DA2000F0108600241186004009860080C50100A0
+:10DA3000BC0C8600D00C8600700D86007C09860028
+:10DA400090098600840D86001CC60100B8C701003D
+:10DA5000340D86005C0D860080118600FC0D86006A
+:10DA6000A4C70100E40C86000C0D8600A4CA0100C6
+:10DA7000CC098600A4098600B8098600F40986004E
+:10DA800018098600980D8600381186008B4B9C4241
+:10DA900003D1022D52D00A2D29E0894B9C4202D19C
+:10DAA0000B2D49D053E0874B9C4203D10B2D4ED117
+:10DAB00032204CE0844B9C4204D10B2D3CD00C2DE9
+:10DAC00034D044E0814B9C4205D10C2D3ED00D2D2D
+:10DAD0003DD13A203BE07E4B9C4204D1A5F10B03A3
+:10DAE000012B23D933E07B4B9C4202D10B2D21D05B
+:10DAF0002DE0794B9C422AD10C2D25D00D2D26D11D
+:10DB0000442024E0332D01D800200BE03D2D01D826
+:10DB1000012007E0632D01D8022003E0942D8CBF83
+:10DB200004200320231893F9060010E04A200EE099
+:10DB300042200CE03C200AE0382008E0402006E0CB
+:10DB4000502004E0482002E04C2000E04620CEEBCC
+:10DB5000000323EAE3736345B4BF18466046022A14
+:10DB600004D199F800309842A8BF1846002209EB6A
+:10DB700002030132082A1871F9D1C0B2CC464A46D4
+:10DB800000210023013182F83430107382F83C30D8
+:10DB900001320829F5D1337F13F0010202D097F941
+:10DBA000044106E097F90431182BD4BF1446A3F1C1
+:10DBB00018043B68022B01D16B1E0FE0332D01D8F6
+:10DBC00000230BE03D2D01D8012307E0632D01D890
+:10DBD000022303E0942D8CBF04230323F2569B19E8
+:10DBE000997B3E4B9E4205D1A5F16403022B01D8DF
+:10DBF0003E2110E03A4B49B29E4203D1642D00F021
+:10DC00006C850BE0374B9E4205D1A5F16403022BD6
+:10DC100001D83E2108E0344B9E420ED0334B9E4249
+:10DC20000BD0334B9E4208D0324B9E4205D0324B34
+:10DC30009E4202D0314B9E4214D1A5F16803242BA1
+:10DC400010D82B4B9E421BD02A4B9E4218D02B4BF8
+:10DC50009E4215D0254B9E4223D0274B9E4220D07A
+:10DC60004A214422264B9E420CD1A5F16803202B69
+:10DC700003D98C2D00F04E8548E04021442201E07C
+:10DC80004A2142221F4B9E420DD1642D06D0A5F1A0
+:10DC900068030C2B3AD83C2140226BE0342140220F
+:10DCA00001E044221146184B9E422FD1A5F1640396
+:10DCB000102B2BD8422152225FE0C0466809860013
+:10DCC0001CC6010008C6010050C60100B8C701000B
+:10DCD000A8C90100CCC70100E0C70100B508860053
+:10DCE00030CA0100D2088600DC0586002E058600B9
+:10DCF0004B0586006805860085058600330686008C
+:10DD0000F90586006D0686008A0686009F4B9E42B6
+:10DD10001AD1A5F16403082B98BF3021A5F16E0339
+:10DD200098BF3422162B98BF4621A5F18603022BFB
+:10DD300098BF3E218C2D08BF3622A5F1950308BF60
+:10DD400048210F2B98BF4422914B9E4212D1A5F13E
+:10DD50006E03162BA5F1860398BF442198BF3A2283
+:10DD6000022B98BF3E2198BF3A228C2D08BF482134
+:10DD700008BF3622874B9E4202D0874B9E4204D179
+:10DD8000A5F18403082B98BF2C22C4EB020323EADD
+:10DD9000E370C4EB010323EAE37E4A4613790021D2
+:10DDA000137582F8441009F1080301329A42F5D143
+:10DDB0004B460A460132187783F84CE00133082AB3
+:10DDC000F8D1764B9E425BD0754B9E4258D0754B36
+:10DDD0009E4255D0744B9E4252D0744B9E424FD0BF
+:10DDE000734B9E4236D0734B9E4249D0724B9E423B
+:10DDF00046D0724B9E4243D0714B9E4240D0714BF5
+:10DE00009E423DD0704B9E423AD0704B9E423DD0D8
+:10DE10006F4B9E4234D06F4B9E4231D06E4B9E4230
+:10DE20002ED06E4B9E422BD06D4B9E4228D06D4B18
+:10DE30009E4225D06C4B9E4222D06C4B9E421FD0FE
+:10DE40006B4B9E421CD06B4B9E4219D06A4B9E423C
+:10DE500016D050E0032D02D14FF03C0E0FE02B1FE7
+:10DE6000042B0AD9092D00F05984A5F10C03012BCC
+:10DE700000F22E842C2000F02CBC4FF0400E4020ED
+:10DE8000524B9E4202D0524B9E4206D1EB1E402086
+:10DE9000082B94BF86464FF0000E584B9E4221D16E
+:10DEA000A5F124030C2B03D84FF0300E382019E0D5
+:10DEB000A5F13403082B02D84420864612E0A5F1D0
+:10DEC0006403022B03D84FF03E0E34200AE0A5F184
+:10DED0006803202B03D84FF04A0E442002E08C2D1B
+:10DEE00008BF32204B4600220132187583F844E007
+:10DEF0000133082AF8D14B4600220021013283F871
+:10DF0000241083F854100133082AF6D14B460A46F0
+:10DF1000013283F82C0083F85CE00133082AF7D142
+:10DF20001E4B89F864E09E4206D01D4B9E4220D0D5
+:10DF30001D4B9E4277D0E5E0012D00F0BE80022D02
+:10DF400000F0A380032D00F0BD802B1F042B03D80D
+:10DF500038273C223E21B8E0092D03D13027342256
+:10DF60003621B2E00A2D00F090800B2D00F0A58044
+:10DF70009FE0012D00F0A180022D00F08B80032D89
+:10DF80003ED13227362238219FE0C046A2058600C6
+:10DF9000BF0586002C078600F40486007E0A8600F2
+:10DFA0009B0A8600B80A8600F20A8600BD0B86002E
+:10DFB000980E860094C5010050C90100EBC5010010
+:10DFC00069C7010011C80100F4C70100630F860092
+:10DFD00014108600B50E860064C6010081C60100DB
+:10DFE000F5C6010012C70100B1C50100CEC5010090
+:10DFF0002FC701004CC70100880C8600DC05860095
+:10E000002B1F042B5ED9092D04D130273422362151
+:10E010004A205BE00A2D3DD00B2D4AD10022174645
+:10E020001146362052E0012D04D100221746114638
+:10E030002C204BE0022D37D0EB1E052B15D8032DDD
+:10E0400003D128272C222E212CE0042D27D0082DA7
+:10E0500025D06B1F022B8CBF002734278CBF0022DA
+:10E0600038228CBF00213A211CE0092D04D12A2737
+:10E070002E223021422029E00A2D15D00B2D18D157
+:10E080000022174611462A2020E00022174611469A
+:10E0900040201BE00022174611463E2016E03227A2
+:10E0A00036223821442011E00022174611463C2038
+:10E0B0000CE000221746114608E0002217461146E0
+:10E0C000382003E0342738223A214C204B460024E4
+:10E0D000042C94BF83F84C7083F84C2001341877DB
+:10E0E0000133082CF4D1C7B24B460024032C94BF53
+:10E0F00083F85C2083F85C10013483F82C700133C2
+:10E10000082CF3D1A44B9E4206D0A44B9E420DD0C6
+:10E11000A34B9E4221D062E0032D45D0092D43D070
+:10E120002B1F042B38D83027342233E0032D03D1A2
+:10E130004227462248243AE0042D31D06B1F022B9F
+:10E1400003D84C275022522431E0082D28D0092D25
+:10E1500022D13E274222442429E0032D03D12E2739
+:10E160003022322423E0042D03D1302732223424FC
+:10E170001DE06B1F022B03D8322736223A2416E00B
+:10E18000082D03D130273422382410E0092D03D183
+:10E190002E27322236240AE000221746144606E0D3
+:10E1A00046274A224C2402E028272C222E244B46C4
+:10E1B0000021042994BF83F84C7083F84C2001316E
+:10E1C00001330829F5D14B460021032994BF83F878
+:10E1D0005C2083F85C40013101330829F5D1714B93
+:10E1E0009E422AD1032D0CD02B1F042B03D8382498
+:10E1F0003E213C2708E0092D03D000210C460F46A4
+:10E2000002E034243A2138274B460022042A94BFE6
+:10E2100083F84C4083F84C7001320133082AF5D161
+:10E220004B460022032A94BF83F85C7083F85C108D
+:10E2300001320133082AF5D136E05B4B9E422CD1E6
+:10E24000A5F124030C2B03D84FF0340E38201AE02C
+:10E25000A5F134030C2B03D84FF0340E3A2012E012
+:10E26000A5F16403282B03D84FF0400E3C200AE0B0
+:10E27000A5F19503102B8CBF4FF0000E4FF0480E08
+:10E280008CBF002046204B4600220132187583F8CF
+:10E2900044E00133082AF8D10AE0444B9E4269D099
+:10E2A000434B9E4200F0DF80424B9E4200F0DB80F9
+:10E2B000414B9E4200F0D780404B9E4200F0D380FD
+:10E2C0003F4B9E4200F0CF803E4B9E4200F0CB8001
+:10E2D0003D4B9E4200F0C7803C4B9E4200F0C38005
+:10E2E0003B4B9E4200F0BF803A4B9E4200F0BB8009
+:10E2F000394B9E4200F0B780384B9E4200F0B3800D
+:10E30000374B9E4200F0AF80364B9E4200F0AB8010
+:10E31000354B9E4200F0A780344B9E4200F0A38014
+:10E32000334B9E4200F09F80324B9E4200F09B8018
+:10E33000314B9E4200F09780304B9E4200F0F281BC
+:10E340002F4B9E4200F08F802E4B9E4200F08E801D
+:10E350002D4B9E4200F087802C4B9E4200F0838024
+:10E360002B4B9E427FD02B4B9E427CD02A4B9E4211
+:10E3700072D0B5E0A5F12403082B01D8382069E05C
+:10E38000A5F12E03022B40F29980A5F13403082B4E
+:10E3900044D84FF0400E95E0D50A8600A00B8600C9
+:10E3A000DA0B86004E0C860011058600F905860002
+:10E3B000BCC90100D9C901006ACA01002EC8010008
+:10E3C00033C90100F9C80100D8C601006DC90100B8
+:10E3D00030C60100DCC801008AC901004DCA010035
+:10E3E00085C80100F6C9010016C9010061C5010018
+:10E3F000A2C8010030CA010087CA010086C7010017
+:10E400009EC60100BBC6010013CA0100BFC80100BF
+:10E410004BC8010068C8010016068600A5F13E033E
+:10E42000022B03D84FF0380E342050E0A5F16403DE
+:10E43000082B02D84FF0380E42E0A5F16E031E2BD8
+:10E4400003D84FF0400E322041E0A5F19503102B88
+:10E4500034D9002086463AE0A5F124030C2B36D8A7
+:10E460004FF0340E2EE09E4B9E4201D1242D5AE1F6
+:10E470009C4B9E4203D18C2D29D13A2027E09A4B08
+:10E480009E4204D1642D1FD08C2D1DD01FE0974BD0
+:10E490009E4203D1A5F19503102B0DE0944B9E42B3
+:10E4A00015D1A5F124030C2B10D9A5F134030C2BA5
+:10E4B0000CD9A5F16403282B08D908E04FF0400ED1
+:10E4C000442004E0382002E0482000E03C204B4695
+:10E4D00000220132187583F844E00133082AF8D18C
+:10E4E000844B9E420BD0844B9E4208D0834B9E426D
+:10E4F00005D0834B9E4202D0824B9E426DD1A5F146
+:10E500002403082B0DD87F4B9E4201D13A2006E010
+:10E510007D4B9E4202D13420024655E03420382201
+:10E5200052E0A5F12E03022B08D8774B9E4214BF70
+:10E530004220402014BF3822342245E0A5F13403A4
+:10E54000082B02D8442046223EE0A5F13E03022BD0
+:10E5500006D86D4B3A229E4214BF34202C2033E063
+:10E56000A5F16403082B06D8674B3E209E4214BFDA
+:10E5700044223A2228E0A5F16E031E2B17D8A5F1FC
+:10E580008603022B09D85F4B9E4201D1442005E04F
+:10E590005D4B9E4201D13C2000E048208C2D10D1E3
+:10E5A000584B9E420FD0584B9E420CD009E0A5F12B
+:10E5B0009503102B8CBF00204A208CBF00224622DE
+:10E5C00002E0442200E03C224B46002101311A7552
+:10E5D00083F8440001330829F8D14C4B9E4202D005
+:10E5E0004B4B9E421ED1A5F124030C2B01D83821A0
+:10E5F0000EE0A5F134030C2B09D9A5F16403282BF7
+:10E6000005D9A5F19503102B01D9002100E0402187
+:10E6100008464B4600220132187583F84410013336
+:10E62000082AF8D14846002202EB090191F83C3053
+:10E630001BB990F84C3081F83C304AB999F83D301C
+:10E640000BB1013204E090F84C30012289F83D30E2
+:10E6500001320130072AE7D94A46002192F84430B6
+:10E660001BB992F84C3082F844300131013208294C
+:10E67000F4D14846002202EB090191F834301BB96D
+:10E6800090F8443081F834304AB999F835300BB1FC
+:10E69000013204E090F84430012289F8353001322B
+:10E6A0000130072AE7D900229CF824301BB99CF8D6
+:10E6B0001C308CF824309CF854301BB99CF84C303A
+:10E6C0008CF854300132082A0CF1010CECD12DE009
+:10E6D00040204FF0000EFFF7E0BB3822FFF79BBA57
+:10E6E000BBC6010013CA01004BC80100DCC8010011
+:10E6F0004DCA01004B058600680586008505860029
+:10E7000033068600A2058600BF058600A7068600A0
+:10E710005006860036221146FFF7F8BA4FF0380E41
+:10E72000FFF7ADBB642D3FF4CDAED0E6BDE8F0877A
+:10E730007047C04600207047002070470020704797
+:10E740007047C0467047C0467047C04600207047BB
+:10E750007047C04603680246D3F86C32D3F8E432FF
+:10E76000987818B1938A181E18BF01207047C046C8
+:10E770007047C0467047C04670B5037D04469BB1E4
+:10E78000457D8DB9C068A16900F068DF012363751C
+:10E79000E36906460BB1A0689847D6F1010038BF7F
+:10E7A00000206575257500E0002070BD0846002139
+:10E7B00010B501614181017201730622F3F340F447
+:10E7C00010BDC04610B50068F6F70AFC10BDC04683
+:10E7D00090F832007047C04602460868430D5B055A
+:10E7E0006BB922F07F4323F46003520D83422CBFA8
+:10E7F0004FF40013002352059B1803430B6070472E
+:10E8000070B510600D461C46084619461646FFF7BF
+:10E81000E3FF2368AB4202D233680133336070BD3B
+:10E82000002070477047C0460020704700207047A6
+:10E830007047C0467047C0467047C04630B505684F
+:10E84000B5B061B10DF107040171C9220021204664
+:10E85000F3F3F6F32B6B2146186902F0E3FA35B0B7
+:10E8600030BDC046406B70477047C04600207047BF
+:10E870007047C046002070477047C0460020704770
+:10E880007047C046002070477047C0467047C0467A
+:10E890007047C0467047C0467047C0467047C04684
+:10E8A0007047C0467047C0464FF0FF307047C046C3
+:10E8B0007047C04600207047002070477047C04630
+:10E8C0007047C0467047C046002070477047C0463A
+:10E8D00010B513F08BDF024640B1416A11F4002FEE
+:10E8E00004D1036813B141F400234362104610BD04
+:10E8F0002DE9F3411E46036804461B7E0F469046F1
+:10E90000002B4BD090F87532002B47D10D6828466C
+:10E91000FFF7A8FF016902468B79B3B1837E13F03C
+:10E92000010F12D0D1F8CC3013F4806F0DD1B4F8B0
+:10E93000263603F47043B3F5805F14BF40234423AD
+:10E94000CB5813B193F8DF3043BB5168002925DB66
+:10E95000164B01EA03030BB9184602E0EB8A03F0F9
+:10E96000070011F0400F19D0114B02A91B5C204683
+:10E9700041F8043D33600CF083D8B0F1FF3F0DD077
+:10E98000019A3368934209D00A4B32609A5CEB8A51
+:10E9900002F0070223F007031A43EA8220463946B1
+:10E9A0004246334616F000DBBDE8FC8140000180A2
+:10E9B000C4D2850038AB010010B540F0B9D910BD04
+:10E9C000F0B585B00A9C0D4600940B9C1F4601943F
+:10E9D0000C9C064602940D9C03942AF0BFDDAB7993
+:10E9E00043B13946304646F0F3DF014610B13046B8
+:10E9F00046F0E6DE05B0F0BD2DE9F041D0F8B043B9
+:10EA0000D0F8AC7323F096D894F82F30064603B3B1
+:10EA100000257B19D3F84C42C4B1A379B3B1237953
+:10EA2000A3B1A36D13F0020F10D094F884306BB132
+:10EA3000F7F3E8F5D4F890102AF09EDC30B100230B
+:10EA4000C4F88830C4F88C3084F884300435202D24
+:10EA5000DFD13046BDE8F0812DE9FF4107461D4674
+:10EA60009E6B146947F02CDE8046002834D1337A3F
+:10EA7000022B31D1A3797BB3B5F8683063B3A26DB3
+:10EA800040F2371302EA030333B394F884301BBB1C
+:10EA9000D4F888303A6853B9D2F88C30D3F8E421EE
+:10EAA0000132C3F8E4213C23C4F8883009E0D2F8ED
+:10EAB0008C30D3F8E4210132C3F8E421012384F837
+:10EAC0009430002394F94820384600930293296F2C
+:10EAD0001133019647F0CCD9404604B0BDE8F0812F
+:10EAE0002DE9F74F80460E4693461F46002B5FD018
+:10EAF00001295DD14FF4C0730193FCF3FBF24FF495
+:10EB000040718246F8F3E4F0044610B94FF0FF3547
+:10EB100055E000214FF44072F3F392F24046314643
+:10EB2000224601ABF3F322F110F11E0F3AD1019B03
+:10EB30004FF0FF325D004A2323700B2363701533BF
+:10EB40002371042363716FF02F03A3719233237237
+:10EB50006FF0560363724FF002096319A270E270FE
+:10EB600084F8079003F8022C03F8012C07F10C033A
+:10EB70009D4202DC6FF00E050DE059463A4604F165
+:10EB80000A00F3F3F9F195FBF9F3404631462246CA
+:10EB9000F3F342F10546504621464FF44072F8F334
+:10EBA000A7F00CE0504621464FF44072F8F3A0F075
+:10EBB000404631465A463B46F2F304F205462846A3
+:10EBC000BDE8FE8FF0B587B0119C0D4616461F4676
+:10EBD00024B1A16811B10120FCF714FD10B96FF048
+:10EBE00016000FE00C9B294600930D9B32460193C3
+:10EBF0000E9B059402930F9B0393109B04933B463B
+:10EC0000FEF39EF307B0F0BD2DE9F0411F4690F8EA
+:10EC10004038054613F0080F0E461ED0536A02F125
+:10EC2000240413F0100F18D1002B16DB896811F49F
+:10EC3000807F0CD15FB1E36913F0006007D1C1F3AD
+:10EC4000402223F0004343EAC273E36106E0284612
+:10EC500031463B461BF0EADA00E00020BDE8F081D7
+:10EC600070B50546D0F8B40058B103784BB1F3F74E
+:10EC7000A9FD044630B9D5F8B4000121F3F3CEF76D
+:10EC800000E001242846F6F38FF224B9D5F8B40049
+:10EC90002146F3F3C3F770BD10B5FFF787FD10BD34
+:10ECA00010B5F9F71FFE10BDB0F8543810B50BB110
+:10ECB0001BF0F2DB10BDC04610B5044638B1026847
+:10ECC0002AB121B992F80B370BB182F80B17204605
+:10ECD0001AF044DA10BDC04610B521B11AB1536E16
+:10ECE0000BB140F0EBD810BD036A10B50C46002BF9
+:10ECF0002CD0036809691B68B4F814E093F89530C8
+:10ED00002BB1E38A13F0800F01D11E2200E00C2208
+:10ED100002F10B039E4519D38B188A5C591C5B7852
+:10ED200003EB02239BB2B3F5006F0FD14B784A1C63
+:10ED30001B09042B0AD1537A012B07D1436A0133F3
+:10ED40004362C3680133C360002002E0214641F002
+:10ED5000FFDF10BD036810B51A68536B2BB192F832
+:10ED6000443013B133F072DA00E0002010BDC04629
+:10ED700010B50C462FF084DC18B994F8F53284F8FD
+:10ED8000F43210BD70B5012205460C46D1F84C1581
+:10ED900030F0DEDF284621462FF0AEDB70BDC046E6
+:10EDA0000C2A70B504460E4615464DD80122AA40DD
+:10EDB00041F2485302EA0303002B45D0D0F8B436A1
+:10EDC0004BB1D3F8D83233B15B68012B3CD0032B65
+:10EDD0003AD0022B38D0204618F008D8002833D17A
+:10EDE000D4F868014369012B2ED05EB1B3794BB1E1
+:10EDF000B36D13F0020F05D0D6F8883013B16FF061
+:10EE000019002BE0082D01D00C2D02D183790BBB0A
+:10EE10000EE083790BB3D4F82835022B04D094F894
+:10EE2000F43713F0010F15D0092145F0C1DB14E0D0
+:10EE3000082D12D1204631460222002327F004DC9F
+:10EE400058B14FF0FF3009E0204631462A462BF0FA
+:10EE5000AFDF03E06FF0180000E0002070BDC04697
+:10EE60002DE9F043054685B099460E4690460D9C27
+:10EE70009DF83870F9F712FDD5F8B03393F84630A5
+:10EE800013F0030F17D0B26D40F2371302EA0303F9
+:10EE90008BB190F8693713F0010F0CD0636813F44D
+:10EEA000803F08D0236C012B05D100222146134658
+:10EEB000009213F09BDE0C9B28460093314642469D
+:10EEC0004B460194029724F0DBDB05B0BDE8F083EC
+:10EED0002DE9F04107461CF0D5DA0026BB19D3F81E
+:10EEE0004C42B4B1D4F88C509DB9A3798BB1A36DC9
+:10EEF00013F0020F0DD094F8843053B1F7F382F37E
+:10EF0000D4F890102AF038DA18B1C4F8885084F890
+:10EF100084500436202EE1D1BDE8F08170B590F820
+:10EF2000A131054663B903681B6F4BB1D0F81C488B
+:10EF3000F7F368F3D5F82038E41A2418C5F81C480C
+:10EF4000284616F0B1DE70BD10B588B00A9C00945A
+:10EF50000B9C01940C9C02940D9C03940E9C0494B5
+:10EF60000F9C0594109C0694119C0794F5F3B8F43B
+:10EF7000044B0421D3F88C300A46044698472046B7
+:10EF800008B010BDE0A6850070B504460D4620F01F
+:10EF900041DC294606462046F9F7DCF8304670BDCC
+:10EFA0002DE9F0410546D5F8D8320E465B68174684
+:10EFB000012B0068D5F8DC4202D14FF0000805E0D3
+:10EFC000042914BF4FF000084FF001080368DB6903
+:10EFD0001A6D636A934238BF62624EB9D4F89010DA
+:10EFE00031B1406894F89420F7F382F6C4F8906049
+:10EFF000284631463A4627F0EBDBB8F1000F01D046
+:10F0000000236362BDE8F0812DE9F04385B00C9FD9
+:10F0100005469846D7F80090D2F8D4621446009777
+:10F020000CF0E6DF296891F8463013F0030F3FD06B
+:10F03000D4F8CC2012F4805F3AD196F93430002B0A
+:10F0400036D14B6B002B33D012F0020F30D13B681E
+:10F050000DF109001849032208EB0304F2F38CF7C1
+:10F0600095F8FA3133B196F96A30002B02DA95F847
+:10F070000A0700E0002008EB0901A14201D20021AB
+:10F0800000E0091B02238DF80C3000238DF80D30B1
+:10F0900001338DF80E300DF109038DF80F00009348
+:10F0A00020460723DD221DF071D83B6809333B6001
+:10F0B00005B0BDE8F083C04672A701000FB430B5BB
+:10F0C000104BADF5037D9E4501D1002513E002A84C
+:10F0D00087AB053840F20121869A8193F3F3E6F07D
+:10F0E0000024054605E002AB053BE05CF7F328F59C
+:10F0F0000134AC42F7DB28460DF5037DBDE8304016
+:10F1000004B07047DB62820010B502490248FFF785
+:10F11000D5FF10BD5FCB01003CCB0100C36970B5CA
+:10F1200013F4006F0E460546016915D00368D3F845
+:10F130008C20936B5C1C4FF47A739463B4FBF3F2F2
+:10F1400002FB134323B90748C96B2246FFF7B6FFFA
+:10F15000EB6923F40063EB61284631462EF032DE82
+:10F1600070BDC046FCAD010010B50446FAF3C6F20E
+:10F17000002384F8173284F8183210BD10B5074CFC
+:10F180002378012B09D0064B1B78012B05D00123D6
+:10F190002370FBF381F20023237010BDE2F801001D
+:10F1A000E3F8010070B50546F3F7ECFB01280146D2
+:10F1B00007DD044C012328462370FBF3FBF00023FA
+:10F1C000237070BDE3F801002DE9FF410B9F0D4650
+:10F1D000B7F862400A9E14F00F0FDDF8308014D0AB
+:10F1E00040F2371406EA04047CB100960197CDF88A
+:10F1F00008800BF0F3DF98F934302BB16B78022BD9
+:10F2000002D9023B02386B700546284604B0BDE8BF
+:10F21000F081C04610B5064902690B782BB1D2F8CF
+:10F22000D03013B100230B7001E01BF039D810BDB2
+:10F23000E4F8010010B58B7913B1044B01221A7068
+:10F240002FF09EDE014B00221A7010BDE4F8010081
+:10F2500010B5044C24780CB1002001E015F076DBE9
+:10F2600010BDC046E1F801002DE9F0410546084611
+:10F2700016461F460C46FFF7F5FA95F84038024649
+:10F2800013F0080F18D0D0F8F00008B91369986887
+:10F29000E38A0F4A03F00703D35CC0680D2B01DD3E
+:10F2A0000F2200E05A1C0C2302FB03039B8A032B52
+:10F2B00002D9084B01221A7032463B4628462146A5
+:10F2C00026F044DF034B00221A70BDE8F081C046EF
+:10F2D00090E08500E1F8010070B5044C8568A54216
+:10F2E00001D1002001E0F3F3ADF170BD0800002072
+:10F2F00070B505460E461CF0CFDF0446C0B131465E
+:10F30000284640F26C521DF0D9D8064620B928464E
+:10F3100021461DF035D80AE0214640F26552F2F34D
+:10F320002BF62846214640F26552F7F3E1F43446C5
+:10F33000204670BD2DE9F04385B000230C4611999D
+:10F3400017460546DDF83880039330F053D807F0B0
+:10F350000103009306462146286842460F9B13F09E
+:10F36000B3DF814600285ED10D9B032B04D903A88F
+:10F370000C990422F2F300F6092F06D8DFE807F013
+:10F38000080D0505141F333A474C6FF0160949E084
+:10F3900028460AF0D3DC40B229E0284603990AF057
+:10F3A000F7DC00283CD03DE0B6F95E300BB102201E
+:10F3B0001DE0B6F95C30181E18BF012017E0039B52
+:10F3C000022B06D14FF00003A6F85C304FF001038A
+:10F3D00006E0003B18BF0123A6F85C304FF00003A5
+:10F3E000A6F85E301EE0D5F83407F9F75BFAC8F8E6
+:10F3F000000017E0D5F83407039CF9F75BFA844264
+:10F400000EDCD5F834070399F9F750FA0AE095F8BD
+:10F41000C334C8F8003005E0039B85F8C33401E02D
+:10F420006FF01C09484605B0BDE8F0832DE9F041B6
+:10F4300086B00E4698460C9900230546174605935C
+:10F440002FF0D8DF044687B1B8F1030F04D905A81F
+:10F4500039460422F2F390F53FB1B8F1030F04D915
+:10F4600005A839460422F2F387F51C2E2ED004DCC1
+:10F47000152E0BD0162E15D005E0D72E56D0D82E2F
+:10F480005FD09F2E28D06FF0160074E0B4F95E3084
+:10F490000BB1022004E0B4F95C30181E18BF012043
+:10F4A000386067E0059B022B06D14FF00003A4F8FB
+:10F4B0005C304FF0010306E0003B18BF0123A4F8C5
+:10F4C0005C304FF00003A4F85E3053E02B6801215C
+:10F4D0001869FBF3EBF64DE0A8F104030622B3FB39
+:10F4E000F2F33B60D5F80005002304A9059345F02D
+:10F4F000F1DD14E0237E13F0020F10D0059B591CA0
+:10F500003B688B4202D26FF00D0034E0B81E062239
+:10F51000059101FB020004F11A01F2F32DF504A894
+:10F5200045F0E0DD04460028E4D121E02B681B7E95
+:10F53000DBB1D5F868319879B8B9B5F816373B60C2
+:10F5400019E02B681B7E83B1D5F868319C7964B9CA
+:10F550002B6B01221B6828460093394623460192F3
+:10F5600002940394FCF7E2FC05E06FF0010002E076
+:10F57000059B3B60002006B0BDE8F0812DE9F04717
+:10F5800004468946FFF358F5F7F33CF094F85431FC
+:10F590008046012B1ED82546002717E06E69B379F7
+:10F5A000022B11D1B4F86C3013F4807F0CD02046BC
+:10F5B00049464246F3F7C0FD30B90423B37194F8CD
+:10F5C000CD30013B84F8CD3001370435B4F910302B
+:10F5D0009F42E3DBBDE8F08730B54FF0000E0446F4
+:10F5E00091B08C461546704609E023185A690EF111
+:10F5F000010ED1794DF80010536B0430D371B4F97A
+:10F6000010309E45F1DB204661462A46FEF308F79E
+:10F610000020014606E063185A695DF801300130A8
+:10F62000D3710431B4F910309842F4DB11B030BD1D
+:10F630002DE9F0410C2904460D46164690F8537109
+:10F640000DD100210122FEF3EBF62046002101221C
+:10F65000FEF3A2F6002384F8CE3084F8CD30A36EFA
+:10F660002046B3F1FF3F08BF84F8563129463246A1
+:10F67000FEF3F6F7B4F86C3003F0C003C02B16D1DC
+:10F68000D4F85C319BB194F85331BB420FD9E36895
+:10F69000A1689868FFF3E2F7E368A1689868D4F876
+:10F6A0005C210123FFF392F74FF0FF33A366BDE81F
+:10F6B000F081C046836E10B5B3F1FF3F01D0FEF379
+:10F6C00003F310BD2DE9F04104460D46866EFFF3AD
+:10F6D00029F4074690B9042204F5AE7005F114012F
+:10F6E000F2F34AF4D4F85C314FF47A7203FB02F37C
+:10F6F000B6F1FF3FC4F85C3108BFA6663846BDE8E6
+:10F70000F081C0460E2937B505468E4614460BD00B
+:10F710000F2910D1114601A80422F2F32DF4284636
+:10F720000199F3F7A5FD08E0B0F85831002003F087
+:10F730000103136001E0FEF34DF73EBD70B51446C2
+:10F740000546FEF303F723680BB10223AB6570BDDA
+:10F7500070B50D460446FEF361F5014610BBA36D7E
+:10F76000EDB1FBB9D4F854210F4B02EA03037BB18E
+:10F7700094F85431022B04D194F8573113F0010F4F
+:10F7800005E0012B07D194F8573113F0020F02D195
+:10F790006FF0010300E0002384F8563102E00BB162
+:10F7A00084F85601084670BDFF0000FF10B50446FE
+:10F7B000FEF3C6F4002384F85731A4F85831C4F896
+:10F7C0005C3184F8563110BD2DE9F041A2B0882299
+:10F7D00005460C4690F8558190F8567190F85461A2
+:10F7E0006846F2F3C9F328462146FEF313F40246B5
+:10F7F000002836D1009B85F856719E4285F85461E9
+:10F800002CD01BB995F8573173B112E0022B04D1FB
+:10F8100095F8573113F0010F05E0012B07D195F84A
+:10F82000573113F0020F02D16FF0010314E096B9C3
+:10F830000DE0012E02D113F0010F05E0022E05D1DB
+:10F8400095F8573113F0020F05D107E036B995F856
+:10F850005531434502D2002385F85631009B85F887
+:10F860005431104622B0BDE8F081C0462DE9F04188
+:10F8700004460E46154690F85671FEF3C7F18646CB
+:10F88000A0B92A4601460DE07318DB88083113F051
+:10F89000100F06D194F8573143F0010384F8573123
+:10F8A00002E0083A072AEFD884F856717046BDE89E
+:10F8B000F081C0462DE9F04104460D46164690F809
+:10F8C0005671FEF33FF1864698B9294632460CE060
+:10F8D0004B6A13F0100F06D194F8573143F002032E
+:10F8E00084F8573103E0383A3831372AF0D884F8B1
+:10F8F00056717046BDE8F081012902D14FF6FF70C4
+:10F9000010E0D0F8BC304FF00002082BD0F8B03037
+:10F9100008BF41F40071A3F8D813B3F8DA33A0F8A4
+:10F92000202698B27047C046D0F8B030A3F8D8135C
+:10F93000A3F8DA237047C046D0F8B0300021A3F80E
+:10F94000D8134FF0010230B5B3F8DA434FF0020597
+:10F95000A3F8D823B3F8DA23A3F8D853B3F8DA33EB
+:10F9600092B29BB2A0F82016C4F3031040EA0470D0
+:10F9700042EA032240EA023030BDC04670B5054677
+:10F980000E461446FFF7B8FF314600EA0402284647
+:10F99000FFF7CAFF70BDC04670B505460E46144657
+:10F9A000FFF7AAFF40EA04023146284692B2FFF769
+:10F9B000BBFF70BD2DE9F0411546064688461C4642
+:10F9C000FFF79AFF2C4020EA0502224330464146C9
+:10F9D00092B2FFF7A9FFBDE8F081C0462DE9F041E2
+:10F9E0001C46069B90461980079D0E46FFF784FF34
+:10F9F000089B28801E802B8804EA080423EA080359
+:10FA0000099A23431380BDE8F081C046D0F8B03096
+:10FA10004FF00002A3F8FC13A0F82026B3F8FE0371
+:10FA200080B27047D0F8B03041EA0242C3F8FC23FC
+:10FA30007047C046D0F8B030A3F8FC13B3F8FE13FB
+:10FA40000A40A3F8FE234FF00003A0F820367047C9
+:10FA500010B5D0F8B040A4F8FC13B4F8FE339BB254
+:10FA60001A434FF00003A4F8FE23A0F8203610BD7F
+:10FA700010B5D0F8B0401340A4F8FC13B4F8FE134E
+:10FA800089B221EA02010B43A4F8FE334FF00003D0
+:10FA9000A0F8203610BDC0462DE9F04106460C46C0
+:10FAA0002CE0254635F8023B571E990403F44043E9
+:10FAB000890CB3F5804F11D001DC3BB11CE0B3F5EC
+:10FAC000004F10D0B3F5404F12D015E03046628899
+:10FAD00035F8023FFFF7CCFF013F0DE0304662886A
+:10FAE000FFF7A0FF08E030466288FFF7A3FF03E0BE
+:10FAF00030466288FFF7ACFFAC1C7A1E002AD0DCCF
+:10FB0000BDE8F0812DE9F0411C46069B9046198026
+:10FB1000079D0E46FFF77AFF089B28801E802B88E2
+:10FB200004EA080423EA0803099A23431380BDE882
+:10FB3000F081C046002380F8E3304FF0FF3241F2FD
+:10FB40000A03C25400F58A500270704710B531B1F3
+:10FB500040F23B414FF6F872FFF76CFF03E00249B9
+:10FB60000422FFF799FF10BD32D2010060B1B0F856
+:10FB7000DE00B0F5006F05D0B0F5406F04D1A0F500
+:10FB8000386002E0402000E000207047012380F848
+:10FB9000E130704780F824167047C04690F924067B
+:10FBA0007047C0467047C04610B1C06900B1417788
+:10FBB0007047C04610B1C06900B101777047C046B8
+:10FBC00010B590F8E3300446002B45D14FF06401A6
+:10FBD0004FF44872A0F87428A0F86C18A0F86E18BA
+:10FBE000C0F870381A46A31802324FF06401102A88
+:10FBF000A3F87618F7D14FF00003A4F82438A4F83E
+:10FC0000AC37A4F8AE374FF00A034FF00A02A4F85D
+:10FC10003038A4F83238636A4FF01401A4F8282869
+:10FC2000A4F83628A4F82A28A4F83828A4F820280C
+:10FC3000A4F82228A4F89027A4F892274FF05002A5
+:10FC4000A4F82618A4F89427A4F834180BB1204679
+:10FC50009847012384F8E33010BDC04610B5FFF784
+:10FC60006BFE10BD2DE9F84F0C46D1F810A00D68C1
+:10FC70009B468968E368064643EA812311469AB2A7
+:10FC8000BDF82880FFF7CEFE0027B9461EE0BAF186
+:10FC9000200F0BD159F8052030465946120CFFF7BA
+:10FCA000C1FE39F80520304641460AE0BAF1100F8E
+:10FCB00004D135F817203046414602E07A5D3046DF
+:10FCC0004146FFF7AFFE013709F1040963689F421F
+:10FCD000DDD3BDE8F88FC0462DE9F74F0D460193FF
+:10FCE000D1F810B00E68EB688968074643EA8123B3
+:10FCF00011469AB2BDF83090FFF794FE4FF000081D
+:10FD0000C24626E0BBF1200F0FD149463846FFF727
+:10FD10007DFE019904464AF806003846FFF776FE54
+:10FD200044EA00444AF806400FE0BBF1100F06D148
+:10FD300038464946FFF76AFE26F8180005E03846BF
+:10FD40004946FFF763FE08F8060008F101080AF1CA
+:10FD5000040A6B689845D5D3BDE8FE8F7FB5029342
+:10FD6000089B03910593099B0192049301A90A9BA7
+:10FD7000984707B000BDC0467FB50293089B03912A
+:10FD80000593099B0192049301A90A9B984707B028
+:10FD900000BDC0460B46D0F8F81012B141EA03038B
+:10FDA00001E021EA0303C0F8F830704700B5D0F84D
+:10FDB000F8308E4621B143F01003C0F8F83012E05D
+:10FDC00023F0100312F0010FC0F8F8300BD041F20D
+:10FDD000C413C258C369196A986E814294BF7146B0
+:10FDE000091AC2F8901000BD00207047A0F8DE107C
+:10FDF0007047C046A0F8DA107047C046B0F8DA0085
+:10FE00007047C04640F6C313984201D800200BE06B
+:10FE100041F2C843984201D8012005E041F2446311
+:10FE200098428CBF032002207047C0467047C046EE
+:10FE300000B5002286460748910030F8223073450D
+:10FE400002D10B18588803E001320E2AF3D10020AA
+:10FE500000BDC046C0CB010010B5C8B2FFF7E8FF37
+:10FE6000FFF7D0FF10BDC04610B541F21823C45CA7
+:10FE70004FF0000C134B3CF803E0BEF10E0F8CBFAB
+:10FE80004FF480524FF400524EF4306342EA0300C4
+:10FE90002CB1BEF1940F02D9BEF1A50F0AD90229E7
+:10FEA00003D1BEF10E0F0BD904E0012902D1BEF13E
+:10FEB0000E0F05D80CF1040CBCF1380FDAD1FF207D
+:10FEC00010BDC046C0CB010010B590F8B232144648
+:10FED0000B6090F82B3653B190F8F83690F92A263B
+:10FEE00023B1534243F080430B6000E00A6014B139
+:10FEF00090F8F7362370002010BDC04610B5864636
+:10FF00001C4641F20B031EF8033002989B000E2999
+:10FF1000137008D80028ACBF0EEB00030EF10003ED
+:10FF200093F81E3127E07F23237030EA200028BF9A
+:10FF300004200022114BD35A994202D00432382AAD
+:10FF4000F8D1A1F122031E2B04D80EEB000393F885
+:10FF500083312370A1F16403282B04D80EEB000336
+:10FF600093F8E8312370A1F19503102B04D80EEB20
+:10FF7000000393F84D32237010BDC046C0CB010082
+:10FF80002DE9FF4700250746884691469A46FF26F9
+:10FF90002C461EE0009341460DF10E020DF10F03B9
+:10FFA0003846FFF7ABFF41F2D623FA5C9DF80F10FD
+:10FFB00053B2994201DC002302E0C2EB0103DBB241
+:10FFC0008DF80F30AB4228BF1D46B34238BF1E46E6
+:10FFD0000134142CE3B2DDD189F800508AF80060B6
+:10FFE000BDE8FF877047C04690F829067047C046B5
+:10FFF000B0F8DA3003F47043B3F5805F09D1032A17
+:020000021000EC
+:1000000018DDA2F16503032B14D9A2F1C9030F2B4C
+:1000100010D9132A0EDCA2F13403642B0AD9A2F101
+:10002000A9031F2B06D9A2F1D103072B94BF0020EF
+:10003000012000E00020704770B590F8DA500446C7
+:100040002846FFF7F5FEB4F8DA3003F47043B3F551
+:10005000005F01D0002004E02B1903F598533F33D3
+:10006000187940B270BDC04600B54FF0000E00EBED
+:100070000E021EF801300EF1010EBEF1040F82F8DF
+:100080002C36F4D14FF0000E01EB0E0200EB0E0304
+:1000900012790EF1010EBEF1080F83F83026F3D16C
+:1000A00000BDC04680F8E0107047C046C369996142
+:1000B0007047C04680F8D5104176704780F8D91057
+:1000C0007047C0467047C04690F81A067047C04651
+:1000D00041F21403C35C33B141F20C2380F81A16C9
+:1000E00080F81B16C154704790F8D83013B1002324
+:1000F00080F8D83000207047C369012093F8813020
+:100100000B70704722B10023C0F8D83FA0F8DC3F45
+:1001100041F21003C15001207047C0460022C1695E
+:1001200010460B1893F982300130D2180828F8D104
+:1001300092FBF0F040B270477047C0466FF0160077
+:100140007047C04670B541F20E23C35C04468B4233
+:100150000D46164603D0D0F8883003B1984741F2D7
+:100160001023E652023BE55470BDC0460021C3692E
+:10017000CB180131082983F88220F8D10021C36906
+:100180006FF05B02CB180131082983F88220F6D189
+:10019000C2690023C2F88C30D36E032B08D1D0F88B
+:1001A000E83F13F0010F03D0136A0833C0F8E03FB3
+:1001B00000F58A530233002204E0002241F2C21308
+:1001C000C25470474FF6A47101321980198402336A
+:1001D000102AF7D1F1E7C04649F675334B6000238A
+:1001E0000B60F0B50C469842ACBF01214FF0FF31D7
+:1001F00003F5340301FB03F103F53403081890FB06
+:10020000F3F202FB1303581A03D4C31301335B1038
+:1002100004E04342DB1301335B105B425A2BD4BF33
+:100220000023012313B1A0F5340014E0002803DB00
+:10023000C31301335B1004E04342DB1301335B1053
+:100240005B4213F15A0FACBF002301230BB9012607
+:1002500003E000F534004FF0FF364FF0000EF44697
+:100260007546604561682268144F0BDD41FA0EF354
+:100270009B18236042FA0EF3C3EB01036360EB5952
+:100280009C440BE041FA0EF3C3EB0203236042FAF5
+:100290000EF35B186360EB59C3EB0C0C0EF1010E0F
+:1002A0000435BEF1120FDCD1636806FB03F3636013
+:1002B000236806FB03F32360F0BDC0460CCC0100AD
+:1002C00080EAE071A1EBE0710022D0B251FA00F3B4
+:1002D0000132002BF9DC70470146002000B586464C
+:1002E0004FF0804343FA0EF31A188A424FEA500047
+:1002F00002D8891A43EA00000EF1020EBEF1200F67
+:10030000EED1884238BF013000BDC046C36983F8D2
+:100310009010C36983F89120C36983F89210C36970
+:1003200083F893207047C046C36983F892107047E2
+:1003300041F20633C256013BC0568242B4BF01208F
+:10034000022070470048704754CC010000207047DD
+:100350007047C046084670470020704741F2C813F6
+:10036000C05803E0C3888B4202D000680028F9D14E
+:100370007047C04610B5B0F8DA10FFF7EFFF10BDB8
+:10038000C3699B6913F0005F09D0D0F8B0304FF01B
+:100390000302A3F8B4264FF0FF02A3F8B826704773
+:1003A000D0F8F83013F0060F0CBF00200120704782
+:1003B0002DE9F0410F46B0F8DA10044615461E4606
+:1003C000FFF74AFD40B9B4F9FC302B60B4F9FE30B8
+:1003D0003360B4F900313B60BDE8F081D0F8A8008B
+:1003E0007047C04670B541F2C813C15805460AE0CF
+:1003F0000B6841F2C8142B51EB694FF43D729868B9
+:10040000F6F376F429590029F2D141F2C81305F523
+:100410009152E950043BEA504FF6CE70F033E85267
+:10042000C2F8901070BDC04610B590F8E93094B095
+:1004300043F0010380F8E93004460021302201A88E
+:10044000F1F3FEF5002110220DA8F1F3F9F50021DA
+:10045000042213A8F1F3F4F511A800210822F1F306
+:10046000EFF594F8E930002023F0010384F8E93037
+:1004700014B010BD70B506460D4610461446002156
+:100480001C22F1F3DDF500200F4BC25A41F2182374
+:10049000F35C1BB1942A01D9A52A10D9022D02D1EF
+:1004A0000E2A04D90BE0012D09D10E2A07D9D10853
+:1004B00002F0070301229A40635C13436354043043
+:1004C0003828E1D170BDC046C0CB010010B50C4644
+:1004D000002103F01DF82070012010BD10B500218F
+:1004E00003F016F840B210BD41F2C41310B5C45861
+:1004F000F433C15819B1C369186940F02DD90023EC
+:100500006370A37010BDC04610B59E462BB941F272
+:10051000F713C35C704613600FE041B1012906D0A8
+:10052000022904D0032902D06FF01C0005E041F23B
+:10053000F713C154FFF7D8FF002010BD41F2B823D4
+:10054000C15810B509B9084607E0C369186940F0F9
+:1005500003D9D0F1010038BF002010BD10B541F221
+:10056000E423C35C0BB104F08BFD10BD10B503F0A8
+:10057000ADFB10BDC36970B5DC681B6D054613F09B
+:10058000010F0E4608D02046FAF392F420B1EB6931
+:100590009B6913F0005F12D1EA69136D13F0010F2C
+:1005A0003BD0536D13F0800F37D1D068FAF31EF6AD
+:1005B000002832D0EB699B6913F0005F2DD0D5F88D
+:1005C000F83013F0020F28D1EEB106F47043B3F502
+:1005D000005F18D163691149232BB4BF00230C239A
+:1005E000F2B2B8BF0F2120469A400123FAF368F413
+:1005F00063690B49222B2046D8BF7021CCBF4FF432
+:100600000072102206E0636904492046222BD8BFFD
+:100610000F2100220123FAF353F470BD00F0555569
+:10062000000E5555D0F8B030C269D3F82031136DA3
+:1006300070B513F0010F04460D4608D0D068FAF3E8
+:1006400037F420B1E3699B6913F0005F11D1E269CF
+:10065000136D13F0010F18D0536D13F0800F14D1E8
+:10066000D068FAF3C3F580B1E3699B6913F0005FCA
+:100670000BD025B920462946FFF77CFF0AE020462B
+:10068000B4F8DA10FFF776FF00E01DB10449204608
+:10069000062202E0034920460E22FFF7FDF970BD55
+:1006A0003AD2010046D2010010B514299E46D0F876
+:1006B000A82004D015290CD06FF016000CE092F998
+:1006C0001A3002A941F8043F70460422F1F354F4B1
+:1006D00001E0039B9376002010BDC04610B590F852
+:1006E0001A360C462BB10231224601F089FDA3785F
+:1006F000637010BD10B5012103F06AFA10BDC04649
+:100700002DE9F0418A79CB790D4642EA03216B79D4
+:100710002A79074642EA0328C3695B690A2B07D98D
+:10072000EB7C1B0213F4807002D10123EB7735E0E0
+:100730002A7A6B7A384601F0FF0442EA0326FFF773
+:100740004DFE7F2C1B4AC8BFA4F58074B30AD35654
+:1007500090F85F00E21818F4006F14BF41F22B33D9
+:1007600041F22A33FB56D11843B2C918AA7DEB7D5A
+:100770007F2942EA0322C2F3C702C8BFA1F58071F4
+:100780000E2AD4BF4FF400534FF4805342F430622A
+:10079000384649B243EA0202FFF7DCFD6A79C1B28A
+:1007A0002977384649B2C2F3801201F005FBBDE853
+:1007B000F081C04614EF010010B590F8E93096467C
+:1007C00053B313F0010F19D0D0F8F0308B420FD192
+:1007D000C369D3F88C209B1883F882E0C269D2F8F1
+:1007E0008C30072B01D1002300E00133C2F88C309C
+:1007F00090F8E93023F0010380F8E93090F8E9300F
+:1008000013F0020F08D023F0020380F8E930C36927
+:10081000724618693FF0B4DF10BDC04690F8E93069
+:1008200010B5A3B9012902D0022902D003E0C0F813
+:10083000F02080F8E910C3691B6AC0F8EC3090F82A
+:10084000F53F23B111466FF05E02FFF7B5FF10BD13
+:1008500037B5044602F016FFE3691A6A01321A62DC
+:1008600094F8E830002B77D041F25233E35A1BB1B1
+:10087000A4F85E38A4F8603841F25633E35A1BB14D
+:10088000A4F85838A4F8543841F25433E35A1BB151
+:10089000A4F85238A4F85638E369196A1A6EB1FB05
+:1008A000F2F302FB131323B92046B4F8DA10FFF772
+:1008B00061FED4F8F83013F00E0F05D12046012167
+:1008C00094F8DA20FFF7AAFF94F8E9304BB1E36916
+:1008D000D4F8EC201B6A9B1A052B02D9002384F85C
+:1008E000E93041F21805615929B1E3691A6A1B6EB2
+:1008F000521A9A420BD3D4F8F83013F0020F06D1F3
+:100900002046FFF771FA10B1E3691B6A6351D4F80E
+:10091000F83013F00F0F1FD1D4F88C300BB12046F4
+:100920009847E36918693FF09FDE68B1E36901A960
+:1009300018690DF107023FF0A1DE20469DF807106F
+:10094000BDF80420FFF7FEFBD4F8F83013F00F0FCA
+:1009500002D1204603F0BAF900203EBD10B504468E
+:10096000FFF74CFA0221C2B22046FFF757FF10BD35
+:10097000C36973B5012983F8811004460D46C36924
+:1009800006D918690122032300930021134605E0CC
+:10099000186900210323009301220B463FF094DEE7
+:1009A000E269537F002B30D0D4F8B030D3F8203137
+:1009B00083F0010313F0010602D110693FF0EADE73
+:1009C000012D0FD90222134620464FF48261FFF712
+:1009D0004FF820464FF482610122022D14BF0023FC
+:1009E00001230BE020464FF4826102220023FFF72F
+:1009F0003FF820464FF4826101222B46FFF738F87A
+:100A00001EB9E36918693FF0B1DE7CBDC36970B5FA
+:100A100047F67F750446582118692A463FF088DE5C
+:100A2000E3695A2118692A463FF082DEE3697021A2
+:100A300018692A463FF07CDEE369722118692A466C
+:100A40003FF076DE70BDC046F7B5C2690546537FFC
+:100A5000002B62D090F81A36002B45D0106928215F
+:100A60003F223FF065DEEB692421186910223FF038
+:100A70005FDEEB6995F829261869262112013FF0FF
+:100A800057DEEB6932211869B5F8FC263FF050DEDD
+:100A90002E460027EB691869204BF95C3FF020DEF9
+:100AA000EB6996F914250446A11D186992B23FF02E
+:100AB0003FDE96F914250223E96992FBF3F25242D4
+:100AC000086992B204F10E0101373FF031DE0136C0
+:100AD000082FDFD1EA6903230093106980220121E6
+:100AE00013463FF0F1DD18E00146042091F914357A
+:100AF0000822073393FBF2F3DB00013081F8143551
+:100B000001310C28F2D195F91425EB6907321869E7
+:100B10004E21C2F3CF023FF00BDEFEBD29D2010011
+:100B200010B5012102F0B0FC40B210BD10B500219B
+:100B30000446621801317F23652982F89136F8D185
+:100B40002046FFF7EDFF2046FFF7C8FC10BDC0466A
+:100B50002DE9F04FB0F8DA30A5B003F47041B1F5EB
+:100B6000805F14BF022201220592D0F8A83004460B
+:100B70000693C3695A6C40F239539A4204D05233F7
+:100B80009A4201D0002304E0B1F5805F14BF002336
+:100B90000123DBB2002165220DF129000893F1F356
+:100BA0004FF2B4F8DAA00AF44073B3F5407F02D1F3
+:100BB0005FFA8AF810E0B3F5007F5FFA8AF104D19A
+:100BC000DD2904D801F1020806E0022902D84FF01D
+:100BD000000801E0A1F1020820460599FFF7A6FFF1
+:100BE0002046FFF729FA4FF0000BC0B2FF255E4602
+:100BF00007900395CDF810B070E0204651462A4684
+:100C0000FFF7F6F9002867D005EB040999F8B262FE
+:100C100024AA571907F8676C94F8AC3043B1059AC9
+:100C2000204641462B46FFF791FB301807F8670C2A
+:100C300041460DF18E020DF18F0320460095FFF71E
+:100C40005DF999F82C269DF88F309A4234BF1146F1
+:100C5000194641F2D623E25C53B2994201DC0020EE
+:100C600002E0C2EB0103D8B224AB591911F8673C7A
+:100C7000984234BF02461A4601F8672C94F8E030D7
+:100C8000642B06D803FB02F3642293FBF2F301F812
+:100C9000673C11F8673C9DF88E20079E9A4238BF4A
+:100CA0001A462B1993F891368DF88F00934294BF12
+:100CB000C6EB0306C6EB0206049AF3B25B4588BF97
+:100CC0002A46049201F8673C039D5B4528BF9B467A
+:100CD000AB4238BF1D460395099E01360996099A15
+:100CE000142AD5B289D104F5A26000215132F1F362
+:100CF000A7F1039B049D84F8293684F82A36002343
+:100D0000184684F818B684F8F83684F8195616E0B0
+:100D100024AE731813F8672C94F81A36091981F861
+:100D200075250BB1089B1BB194F818369B1A03E08C
+:100D300094F82936C3EB020381F8103501301428EA
+:100D4000C1B2E5D121460020069D91F91035B5F9D3
+:100D5000E623D218431CD8B281F8102501310428AB
+:100D6000F2D1E36A0BB12046984725B0BDE8F08F79
+:100D700070B505460E462C46FFF776F92946002049
+:100D80003218137D03B91379013081F838360131F7
+:100D90000828F5D10021721892F8443003B913796C
+:100DA000013184F8483601340829F4D1EB69186917
+:100DB0003FF0F0DC2846FFF7CBFEEB6918693FF007
+:100DC000D5DC70BD7F2970B5044601D9052028E027
+:100DD000002213190132652A83F8B212F9D10023D7
+:100DE000E26984F8F736137FD3B1D4F8F83013F002
+:100DF000020F15D1D4F8B030D3F8203183F00103BD
+:100E000013F0010502D110693FF0C4DC2046FFF762
+:100E10009FFE2DB9E36918693FF0A8DC284600E081
+:100E2000002070BD70B5054600F52C70042202301C
+:100E30000C46F1F3A1F005F52C70211D08220630B7
+:100E4000F1F39AF005F52E700822063004F10C013A
+:100E5000F1F392F005F538700822063004F1340100
+:100E6000F1F38AF005F53A700822063004F13C01EE
+:100E7000F1F382F005F530700822063004F1140118
+:100E8000F1F37AF005F532700822063004F11C0106
+:100E9000F1F372F005F534700822063004F12401F4
+:100EA000F1F36AF005F536700822063004F12C01E2
+:100EB000F1F362F005F53C700822063004F14401BC
+:100EC000F1F35AF005F53E7004F14C0108220630AA
+:100ED000F1F352F005F540700822063004F1540198
+:100EE000F1F34AF005F542700630082204F15C0186
+:100EF000F1F342F094F8643085F81633D5F8B03049
+:100F0000D3F8203113F0010309D11C462846FFF71E
+:100F10001FFE54B1EB6918693FF028DC05E0EB696E
+:100F2000012418693FF036DCF0E770BD2DE9F0418F
+:100F30000F460546FFF712FA07F47043B3F5805FDA
+:100F4000EB69FAB208BF42F480720446A021186926
+:100F50003FF0EEDBAE6A14B104F5177201E005F55F
+:100F6000915241F2C413EA5016B128463946B047AF
+:100F70002CB341F2C413EA58537873B1EB6941F2D0
+:100F8000B824295918693FF0E7DBEB69002218699A
+:100F9000295913463FF05EDB11E041F2F713EB5C99
+:100FA0006BB1032B0BD0E969D2F890200B6A9B1A26
+:100FB0008A6E934203D328460221FFF7DBF92846C5
+:100FC0003946FFF7D7FABDE8F081C046E02910B5F1
+:100FD0000B46044602DD6FF0120012E043F430636A
+:100FE0000E29D4BF4FF400514FF48051194389B2F8
+:100FF000FFF79CFF0123204684F8D83008F08CFFCF
+:10100000002010BD70B50C460546FFF76DF844B9D9
+:10101000284605F0D5FE28464FF4404106F0AAF9CF
+:1010200010E0214628460022FFF7D0FF044648B9C9
+:10103000284621467022234605F046FB28465E21BD
+:1010400006F0EAFD204670BD2DE9F0410D4604464C
+:10105000FFF74AF845B92046294602F0B1FC2F4671
+:1010600041F2C423E55213E0204629460122FFF74E
+:10107000ADFF074660B941F2C426A35B23B9204601
+:101080000A21FEF7C3FCA0532046294602F098FC33
+:101090003846BDE8F081C04670B50E460546D0F82A
+:1010A000B040FFF721F83EBB41F2C6240A21284692
+:1010B0002A5BFEF7B7FC284640F24B413246FEF76A
+:1010C000B1FC2846314602F0DBFBEB692E531B6D69
+:1010D00013F0020F56D041F2C823D5F8B020EB5AD6
+:1010E0004FF47A70A2F89C3441F2CC23EB5AA2F868
+:1010F0009E34F5F331F345E0EB691B6D13F0020FFD
+:101100001FD0D5F8B01041F2C822B1F89C344FF48A
+:101110007A709BB2AB50B1F89E3404329BB2AB50A4
+:10112000B4F89C3423F400731B041B0CA4F89C3407
+:10113000B4F89E349BB243F40073A4F89E34F5F3E4
+:101140000BF3314628460122FFF740FF0646C8B997
+:1011500041F2C6242B5B5BB90A212846FEF756FCF8
+:1011600040F24B4128534FF6FF722846FEF75AFCD7
+:101170002846012102F084FB28460A214FF494728C
+:10118000FEF766FC304670BD2DE9F0418AB005AE31
+:10119000D0F8B07005468846142238493046F0F33E
+:1011A000EBF6142236496846F0F3E6F6EB690021C7
+:1011B0006C461869142288450CBF234633463FF01D
+:1011C000C1DA4FF00003A7F86835B8F1000F4FF40B
+:1011D0008073A7F8C0370CBF40234123A7F80C3514
+:1011E00041F60223A7F814354FF00003A7F808359D
+:1011F000A7F80A35A7F84C354FF01403A7F86A355D
+:1012000040F62603A7F868354FF00003A7F800352D
+:101210004FF0D003A7F80235B7F802350CBFFA2516
+:101220001E25002402E00A20F5F396F2AC420ADA09
+:10123000B7F80E35013413F0800FF4D103E00A2023
+:10124000F5F38AF200E0002401340B2C09D0B7F842
+:101250000E3513F4806FF2D003E00A20F5F37CF230
+:1012600000E0002401340B2C04D0B7F8903613F4BE
+:10127000807FF2D10AB0BDE8F081C04662D20100A1
+:10128000F8CB010070B590F8E2200446002A6CD13A
+:10129000012380F8E230D0F8B030A0F8DA10D3F8AB
+:1012A000203141F21003C250D0F8F82012F0020FA2
+:1012B00006D190F8703E1BB942F02003C0F8F83018
+:1012C000256A002D51D001212046FEF73FFCB4F8DD
+:1012D000DA30B4F8DE2003F44061914203D0E369D0
+:1012E00018693FF0D3D9012141F2BD23E1542046D2
+:1012F000FFF798F92046A847002384F8E1302046FC
+:10130000FFF7A2FBE369204693F88110FFF730FB5B
+:10131000E26992F88030012BB4F8DA300BD103F493
+:101320007043B3F5005F01D1936F0BE0D36F012BD6
+:1013300088BF002306E003F47043B3F5005F0CBFE1
+:10134000136F536FD366E3690022D96E2046FEF710
+:10135000D9FE002384F8E230E369922118693FF056
+:10136000C9D941F212234000E05270BDC36910B5E3
+:1013700018693FF0C9D910BDC36910B518693FF0AD
+:10138000CDD910BDF7B5089F04460D461E463BB1AA
+:10139000032A05D9684619460422F0F3EDF501E069
+:1013A00000230093A82D009900F0FB8015DC5C2D34
+:1013B00000F0AE8008DC3C2D00F0A0804A2D00F04B
+:1013C00093801B2D2AD020E05E2D30D0C0F2A88063
+:1013D0005F2D3DD0872D1BD017E0C32D75D006DCC7
+:1013E000AA2D49D07BDBC22D00F0DB800DE0D42D8F
+:1013F00000F0AB8003DCD32D00F09B8005E0A5F569
+:101400009A73033B012B40F2D2806FF01605CFE0B8
+:101410002046FEF783FE40B23060C8E0E3691D7FDE
+:10142000002D40F0B8802046FEF784FBC0E0012389
+:101430003B70E3695B7F002B00F0B0802046FFF734
+:101440009BFF2046BDF80010FEF7E0FA30600FE089
+:1014500001233B70E3695B7F002B00F09F802046F7
+:10146000FFF78AFF009A204691B2120CFEF7DAFAD3
+:101470002046FFF77BFF9AE0E269537F002B00F0E4
+:101480008D8010693FF086D900252046FFF774FF54
+:101490003560D4F8BC30082B13D10DF1060220467C
+:1014A0000DF107018DF807508DF8065000F0A8FEE9
+:1014B0009DF907209DF9063092B29BB243EA0223C0
+:1014C00033602046FFF752FF60E0E3691B7F002B8B
+:1014D0006AD03388022B64D96FF0010568E0E369B4
+:1014E0001B7F002B60D05CE0E3691B7F002B52D197
+:1014F000236B002B5BD02046984718E0E3691B7FE5
+:10150000002B48D120467268B368FFF7C5FD0EE096
+:10151000E3691B7F002B3ED12046FFF773FD06E0F9
+:10152000E3691B7F002B36D12046FFF78DFD054672
+:101530003EE0E369DA6E3260D4F8E83F13F0010F61
+:1015400035D042F08003336031E0042902D96FF0D6
+:101550001C052DE0E269D36E8B4228D0137FD16643
+:101560002BB310693FF016D9009B23B12046002110
+:101570000122FEF7C7FDE36901222046D96EFEF77E
+:10158000C1FD002814BF00256FF00205E36918694A
+:101590003FF0ECD80CE06FF0040509E06FF00A05AD
+:1015A00006E06FF00C0503E06FF0030500E0002596
+:1015B0002846FEBD2DE9F04389B09946109B0026D0
+:1015C000032B07460C46DDF84480139D079604D98B
+:1015D00007A849460422F0F3CFF4079940F2862386
+:1015E0000A1E18BF01229C4200F013812CD80C3B2C
+:1015F0009C427CD00FD8532C08D8522C80F04081CC
+:10160000502C00F03D81512C6AD02DE140F26A232C
+:101610009C4250D028E1B4F5207F00F0E48009D846
+:1016200040F27B239C4200F0A48003339C4200F0F4
+:10163000D58019E1B4F5217F00F0E48040F28523E4
+:101640009C4200F0DB800FE140F2D6239C4200F088
+:10165000178114D8413B9C423ED006D8043B9C42A3
+:1016600034D002339C4234D0FEE0B4F5277F00F042
+:10167000D78040F29D239C4200F0D680F4E040F2F7
+:10168000DD239C4200F0EB8008D8033B9C4200F035
+:10169000D180B4F5377F00F0D680E5E0B4F53D7F2A
+:1016A00000F0F380C0F0E080A4F53E73063B012B10
+:1016B00000F2DA80E9E03846FFF75EFE3846414640
+:1016C000FFF70CF83846FFF751FE50E041F2523375
+:1016D00004E041F2543301E041F25633F95246E05E
+:1016E0000123009338464346FEF728FDCFE0FA6910
+:1016F000137F13B96FF00300C9E0D7F8B030D3F807
+:10170000203183F0010313F0010902D110693FF089
+:1017100041D83846FEF734FE3846FFF72DFE41F239
+:10172000D61341F2D910F95C385C0133FA5C01330D
+:1017300017F803E0009041F2DA103D5C01303C5CA8
+:101740001630385C7346039038460195029404962F
+:10175000FEF76AFEC8F800003846FFF707FEB9F149
+:10176000000F40F08D80FB6918693EF0FFDF3046C6
+:101770008DE0C1F3036CBCF1010F00F28380C1F373
+:10178000015EBEF1010F7DD8C1F38155032D79D0E3
+:10179000C1F30344012C75D8C1F30722A2F10A0357
+:1017A000DBB2052B6ED8C8B2012801D9032869D154
+:1017B0000E2A28BF0E2241F2D613FA540133F854F0
+:1017C0000133FC54013307F803E00133FD540133C6
+:1017D00007F803C00A0F1633FA54C8E708A9012313
+:1017E00041F8043D07E0B7F8DA103846FEF734FB5D
+:1017F00008A941F8040D40462A462DE041F20B03AA
+:10180000F954B4E741F20B03FB5C08A941F8043D2D
+:1018100017E0D7F8F830C3F30013C8F80030A6E794
+:1018200038464246334602E0384642460123FEF738
+:101830006BFE9CE70121384601F038FF08A941F80A
+:10184000046D404607E007AC38463146224601F0B9
+:1018500091FF404621460422F0F38EF387E7384695
+:10186000324601F087FF82E7019102923846214615
+:101870004A4643460095FEF717FF10F1170F04D0B4
+:10188000002004E06FF01C0001E06FF0160009B0CA
+:10189000BDE8F0832DE9F04391460A6801230B73FC
+:1018A00042F008030B60B0F9FA3685B0B3F1FF3FA0
+:1018B00004BF42F009030B6090F81A3605460C4647
+:1018C0001BB10B6843F002030B602F4626464FF016
+:1018D000000897F8B2322846B37749460DF10E0357
+:1018E0000DF10F02CDF80080FEF708FB9DF80E30D9
+:1018F00008F1010886F8B03197F87535013786F898
+:1019000079320136B8F1140FE3D195F81A3633B3B2
+:10191000EB691B7F1BB32846FFF72EFD95F81836A1
+:101920002846A37595F81836E37595F81936A37609
+:1019300095F81936E37600F059FC236810B143F0AE
+:10194000030301E023F003032846236004F10D01A3
+:1019500004F1150200F054FC2846FFF707FD05B01E
+:10196000BDE8F08310B5054B1B78012B03D1013B7B
+:1019700018461B7001E014F095FA10BD38F501000F
+:1019800010B5054B1B78012B03D1013B18461B708A
+:1019900001E014F0ADFA10BD38F501002DE9F04179
+:1019A00005460E4617461C46FFF7EAFF30B12346B0
+:1019B000284631463A4614F0D5FA04462046BDE89A
+:1019C000F081C04610B50023FFF7E8FF10BDC04608
+:1019D00010B51446FFF7D4FF20B100210A46F0F3FA
+:1019E000B7F60446204610BD10B50022FFF7F0FF01
+:1019F00010BDC0461FB5079B0C890093089B11467C
+:101A00000193099B224602930A9B03930069069B5C
+:101A10002BF0CCDB04B010BD00B5B0FBF1FE01FB38
+:101A20001E0001F0010C0CEB51010BE0884228BFB5
+:101A3000C1EB00034FEA4E0E26BF0CEB43000EF144
+:101A4000010E4000531EDAB2FF2AEFD1884228BFB0
+:101A50000EF1010E704600BD00FB01F19202800103
+:101A600003FB002001F5004101EB4000490090FB21
+:101A7000F1F07047D0F8A8304FF001025A86704755
+:101A80002DE9F04798469DF820308A4691469DF80A
+:101A90002470B3B100246FF000462546204651461D
+:101AA0004A464346FFF7D8FFB04204DA6B1CDDB26A
+:101AB000BD421AD006460134802CEFD16FF00040B1
+:101AC00013E07F244FF0FF361D46204651464A461C
+:101AD0004346FFF7C1FFB04204DD6B1CDDB2BD42DF
+:101AE00003D00646013CF0D22046BDE8F087C04650
+:101AF00010B5B0F8DA300446DAB203F47043B3F547
+:101B0000005FD0F8A81003D1531893F8E72486E0BB
+:101B1000702A5ED01CD8382A49D00CD82C2A3DD047
+:101B200004D8242A34D0282A35D02FE0302A38D0BF
+:101B3000342A39D02AE0642A42D004D83C2A39D049
+:101B4000402A3AD022E0682A3DD06C2A3ED01DE0DF
+:101B5000882A50D00CD87C2A44D004D8742A3BD090
+:101B6000782A3CD012E0802A3FD0842A40D00DE071
+:101B7000992A49D004D88C2A40D0952A41D005E032
+:101B8000A12A47D0A52A48D09D2A40D0002246E06D
+:101B900091F8F62443E091F8F72440E091F8F82416
+:101BA0003DE091F8F9243AE091F8FA2437E091F811
+:101BB000FB2434E091F8FC2431E091F8FD242EE080
+:101BC00091F8FE242BE091F8FF2428E091F80025FD
+:101BD00025E091F8012522E091F802251FE091F817
+:101BE00003251CE091F8042519E091F8052516E07D
+:101BF00091F8062513E091F8072510E091F80825E3
+:101C00000DE091F809250AE091F80A2507E091F81E
+:101C10000B2504E091F80C2501E091F80D25D1F891
+:101C2000E40494F82A36C01A801840B210BDC046A9
+:101C30000846704749B24B1C5B104910C3F10803BA
+:101C4000083141EA031188B27047C046B0F8DA3073
+:101C500003F47043B3F5005FD0F8A82005D192F8E3
+:101C60003C05FF2801D0C0B200E000207047C0460C
+:101C700070B50546D0F8A840FFF7E8FF10B994F812
+:101C8000460540B1B5F8DA3003F47043B3F5005FB0
+:101C900014BF0020012070BD10B50C468EB0D0F8E6
+:101CA000A8109646002000220DF10603C254013010
+:101CB0003228F8D1BEF1FF3F91F8E93306D114B1D3
+:101CC000B1F93EE503E0B1F940E514E09CB1A02B89
+:101CD00009D000238DF806308DF807308DF80830D4
+:101CE0008DF8093004E000238DF806308DF80830B7
+:101CF0008DF80A3033E0A02B17D001238DF81A306D
+:101D00008DF81B306FF0010300228DF81E308DF826
+:101D10001F3001338DF81C208DF81D208DF82020F8
+:101D20008DF821308DF8242019E002238DF81A3027
+:101D30006FF003038DF81E30023300228DF81F3040
+:101D40008DF820308DF8213006338DF81B208DF86A
+:101D50001C208DF81D208DF824208DF832300EAA1D
+:101D600002EB0E0313F9320C0EB010BD30B5C4698E
+:101D7000D0F8F03F226AD0F8A8509A4202D3C3EBC1
+:101D8000020101E0DB43991895F8BC2290F8DA30A3
+:101D90009A4201D0012004E0A36E994234BF002092
+:101DA000012030BD7047C046D0F8A83093F8060433
+:101DB000002808BF1020704700B5D0F8A8008E4654
+:101DC000D0F8D4240EF0FF0343EA0223110EC0F82A
+:101DD000D434D0F8D8347F29C8BFA1F580717344BA
+:101DE0005B1AC0F8D8349B10C0F8DC3400BDC04684
+:101DF000844610221B4810B5964600244EF3460335
+:101E00005FFA83FE10EA0C0F4FFA8EF104D088407F
+:101E10000EEB0203DAB203E0C840CEEB0203DAB203
+:101E20000134042CEAD110EA0C0FD3B201D1013BEA
+:101E3000DAB251B2032301FB03F30329DAB20EDD58
+:101E4000CB1E2CFA03F00D2801D9D31C06E00A287A
+:101E500001D9931C02E0082801D9531CDAB250B210
+:101E600010BDC0460000FFFFD0F8A820002382F874
+:101E7000903382F8913382F8923382F8933382F868
+:101E8000943370477047C04670B540F22341D0F894
+:101E9000A8500446FDF7BAFDC0B2A5F864034FF49C
+:101EA000AA612046FDF7B2FD8005800DA5F8680304
+:101EB00040F234412046FDF7A9FDC0B27F28C8BFDB
+:101EC000A0F58073A5F8660340F23241C8BFA5F8BB
+:101ED00066332046FDF79AFDC0B27F28C4BFA0F547
+:101EE000807398B285F8BC0370BDC0462DE9F047F9
+:101EF000884640F2B76104469146FDF787FD40F2FF
+:101F0000B66105462046FDF781FD40F2B561064603
+:101F10002046FDF77BFD40F2B46107462046FDF701
+:101F200075FD4FF0000C6246644650FA04F313F05E
+:101F3000010101D0012103E00CF101035FFA83FCF0
+:101F4000531CDAB2102A12D001340029EDD00EE071
+:101F5000A2F1100357FA03F313F0010F01D001218E
+:101F600003E00CF101035FFA83FC531CDAB21F2A71
+:101F700011D80029ECD00EE0A2F1200356FA03F3A9
+:101F800013F0010F01D0012103E00CF101035FFA0E
+:101F900083FC531CDAB22F2A11D80029ECD00EE0B2
+:101FA000A2F1300355FA03F313F0010F01D0012120
+:101FB00003E00CF101035FFA83FC531CDAB23F2A01
+:101FC00001D80029ECD04FF03F0E00220F2455FA23
+:101FD00004F313F0010101D0012103E00EF1FF33FE
+:101FE0005FFA83FE531CDAB2102A12D0013C00299A
+:101FF000EDD00EE0C2F11F0356FA03F313F0010F08
+:1020000001D0012103E00EF1FF335FFA83FE531C80
+:10201000DAB21F2A11D80029ECD00EE0C2F12F034A
+:1020200057FA03F313F0010F01D0012103E00EF181
+:10203000FF335FFA83FE531CDAB22F2A11D800292E
+:10204000ECD00EE0C2F13F0350FA03F313F0010F9E
+:1020500001D0012103E00EF1FF335FFA83FE531C30
+:10206000DAB23F2A01D80029ECD088F800E089F8DC
+:1020700000C0BDE8F087C04670B50D4640F239415A
+:102080000646FDF7C3FCC0F3C210E88040F2B5413C
+:102090003046FDF7BBFC40F2FB4104463046FDF7FD
+:1020A000B5FC04F0FF03C0B2C4F307242B806C809E
+:1020B000A88070BD2DE9F047B0F8DA30074603F488
+:1020C0007043B3F5805FD0F8A82009D1B2F892052B
+:1020D00003B2B3F1FF3F0CBF4FF4C87080B24CE0C5
+:1020E000B2F8904523B2B3F1FF3F01D0A0B244E073
+:1020F00040F2A541FDF78AFC40F2A54181463846F1
+:10210000FDF784FC40F20D4106463846FDF77EFCA3
+:1021100040F20D4104463846FDF778FC40F2A241FA
+:1021200005463846FDF772FC40F2A241804638462B
+:10213000FDF76CFCC6F30236012313FA06F6C0F372
+:102140000220C5F3022513FA05F58340E4B25FFAD5
+:1021500089F94C44B6B2A419ADB29BB25FFA88F8C3
+:102160006419434404EB430464005034A4B2B4F54E
+:10217000C86F2CBF20464FF4C860BDE8F087C0464A
+:1021800010B540F2FB41FDF741FCC0F3062010BD45
+:1021900070B540F2A4410446D0F8A850FDF736FCD3
+:1021A000C0F38130032814D141F21403E35C83B1FE
+:1021B000204640F27341FDF729FC95F96635C005CC
+:1021C000C00D013303FB00F3022293FBF2F3D8B2FC
+:1021D00001E095F8C10240B270BDC04610B540F2B2
+:1021E000A441FDF713FC00F4404010BD10B5FFF70B
+:1021F000F5FFB0F5404F14BF0020012010BDC046D0
+:1022000070B5002313700B7041F21403C35C0446D5
+:102210000D4616461BB340F2AB41FDF7F7FB10F439
+:10222000004F03D0204640F2AB410AE0204640F286
+:102230003C61FDF7EBFB10F4004F07D0204640F265
+:102240003C61FDF7E3FBC0F3470028702046FFF731
+:10225000CDFF08B194F810052B781B18337070BDB2
+:102260002DE9F04140F2FF340E46054690463346D4
+:10227000224640F24561FDF7FBFB284622464346D5
+:1022800040F24661FDF7F4FB28462246334640F211
+:102290004761FDF7EDFB2846224643464FF4C961EE
+:1022A000FDF7E6FB28462246334640F24961FDF73A
+:1022B000DFFB284640F24A6122464346FDF7D8FB41
+:1022C000BDE8F08170B5002914BF4FF4807300237E
+:1022D00004460D1E18BF01254FF480724FF496611D
+:1022E000FDF7C6FB0122204640F24C412B46FDF78C
+:1022F000BFFB2B0320464FF496614FF4805203F44A
+:102300007043FDF7B5FB6B0320464FF496614FF425
+:10231000005203F46043FDF7ABFB6B0120229BB23C
+:1023200020464FF49661FDF7A3FB6B0203F47E4356
+:10233000204640F2AE414FF40072FDF799FBB4F82D
+:10234000DA3003F47043B3F5005F11D1AB022046DD
+:102350004FF496614FF4806203F47C43FDF788FBF1
+:10236000EB009BB2204640F2E5410822FDF780FBDE
+:1023700070BDC04670B50C02A4B20546234640F2BB
+:10238000FB414FF4FE42FDF773FB284640F2FD414E
+:102390004FF4FE422346FDF76BFB70BD70B500297C
+:1023A00014BF802300230C1E18BF012480224FF489
+:1023B00096610546FDF75CFBA303A40128464FF494
+:1023C00096614FF4804203F44043A4B2FDF750FB02
+:1023D000284640F23B4140222346FDF749FB70BDB1
+:1023E00070B540F239440D4621460646FDF70EFB16
+:1023F00040F67F4300EA030343EAC5133046214613
+:1024000040F6FF729BB2FDF733FB70BD2DE97043C0
+:102410000C460646FFF7B4FE628823884FF6FF7924
+:1024200043EA022305464A46304640F2B5419BB294
+:10243000FDF71EFB2D02A388ADB247F6FF783046AC
+:10244000424645EA030340F2FB41FDF711FB628877
+:102450002388304643EA022340F2FC414A469BB2BD
+:10246000FDF706FBA3883046424645EA030340F2E7
+:10247000FD41FDF7FDFA3046E188FFF7B1FF304638
+:102480000121FFF78BFFBDE87083C04610B50249FC
+:102490000C22FDF701FB10BDCADA01002DE9F0475F
+:1024A0009846BDF82CA0BDF824308946BDF8201010
+:1024B0000AF00304164603F00F03BDF8282044EA8F
+:1024C000032301F00F0102F0030243EA013343EA60
+:1024D000821343EA021343EA840340F2B6414FF603
+:1024E000FF720746BDF83050FDF7C2FA0F2208EA26
+:1024F0000203384640F2B741FDF7BAFA4FEACA2361
+:102500009CB22346384640F2B1414FF460522D034D
+:10251000FDF7AEFAADB2062238462049FDF7BCFA07
+:102520007602384640F2AE414FF470422B46FDF73A
+:102530009FFA384640F2B1414FF4007206F47E43F0
+:10254000FDF796FAD9F1010338BF0023012238467E
+:1025500040F24D41FDF78CFAB7F8DA3003F47043DE
+:10256000B3F5005F10D1384640F2B1414FF4C0528C
+:102570002346FDF77DFA4FEACA039BB2384640F284
+:10258000E6411822FDF774FA384640F2AE414FF4A6
+:1025900070422B46FDF76CFABDE8F0878ED501003E
+:1025A00010B5044686B021B90D490E22FDF774FA24
+:1025B00014E00C490922FDF76FFA002103220623DB
+:1025C000009302920423039220460A460491019349
+:1025D000FFF764FF20460121FFF774FE06B010BD2F
+:1025E000D6D40100F2D4010010B5D0F8A830D3F849
+:1025F000741529B1C3694FF420729868F4F378F325
+:1026000010BDC0462DE9F041D0F8A8300646D3F8F9
+:102610007C55D3F8787500240DE0142302FB03F3F6
+:10262000EA1811695268F06902FB01F28068E95802
+:10263000D208F4F35DF3E2B20134BA42EDD3BDE85F
+:10264000F081C04670B5D0F8A8500446D5F87C3566
+:102650006BB10121FFF7D6FFE369D5F87845142265
+:102660009868D5F87C1504FB02F2F4F341F370BDD1
+:1026700000F59753196810B5044629B1C36942F6AD
+:1026800008529868F4F334F32046FFF7ADFF204674
+:10269000FFF7D8FFE369D4F8A81098684FF4B9623F
+:1026A000F4F326F310BDC04610B54FF48052044633
+:1026B000002340F2C961FDF7DBF9D4F8A820B2F895
+:1026C000C234EBB192F8E933A02B04D1204640F29A
+:1026D0008961232203E0204640F289613022FDF720
+:1026E000A1F9D4F8A830B3F8C234022B0ED14FF4BC
+:1026F0008052204640F2C9611346FDF7B9F905E062
+:10270000204640F289612322FDF78CF904222046FD
+:102710002749FDF7C1F90022204640F27961FDF713
+:1027200081F9082220462349FDF7B6F9D4F8A830EC
+:102730002046B3F8C2244FF4D961FDF773F906229D
+:1027400020461D49FDF7A8F9D4F8A8304FF480724F
+:10275000B3F8C23420461A41013A4FF4D06192B224
+:10276000FDF760F9D4F8A8304FF4A072B3F8C23482
+:1027700020461A41013A92B240F28161FDF752F9C6
+:10278000D4F8A830B3F8C224012A04D0022A14BF16
+:102790003422082200E01822204640F27F61FDF733
+:1027A00041F9204605490E22FDF776F910BDC046D5
+:1027B00024D80100EEDA01002CD80100FEDA010075
+:1027C0002DE9F04740F23C4631460446FDF71EF93C
+:1027D00040F23B48824641462046FDF717F94AF051
+:1027E000010281463146204692B2FDF71BF949F0BD
+:1027F0000102204641464FF6FE7592B2FDF712F9EE
+:10280000204631460AEA0502FDF70CF9204641460A
+:1028100009EA0502FDF706F9204631465246FDF762
+:1028200001F9204641464A46FDF7FCF8BDE8F0872D
+:10283000802270B513460C4640F2D1610546FDF783
+:1028400017F90CB1012C05D128464FF4DA610F229B
+:10285000FDF7E8F82846FFF7B3FF70BD2DE9704398
+:102860000E46B0F8DA10054601F47041B1F5005F8C
+:1028700014BFA521892199469046FDF73DF8B5F88A
+:10288000DA10044601F47041B1F5005F14BFA521D0
+:1028900089212846FDF730F804F00F04C0F3031037
+:1028A000241A3470B5F8DA10284601F47041B1F5F5
+:1028B000005F14BFA6218A21FDF71EF8B5F8DA10D3
+:1028C000044601F47041B1F5005F14BFA6218A21CE
+:1028D0002846FDF711F804F00F04C0F30310241A82
+:1028E00088F80040B5F8DA10284601F47041B1F5D7
+:1028F000005F14BFA7218B21FCF7FEFFB5F8DA10AB
+:10290000044601F47041B1F5005F14BFA7218B218B
+:102910002846FCF7F1FF04F00F04C0F30310241A5B
+:1029200089F80040B5F8DA10284601F47041B1F595
+:10293000005F14BFA8218C21FCF7DEFFB5F8DA1088
+:10294000044601F470412846B1F5005F14BFA82188
+:102950008C21FCF7D1FF04F00F04C0F30310069B99
+:10296000241A1C70BDE87083B0F8DA1010B501F4B9
+:1029700070410446B1F5005F14BFA521892188226A
+:10298000FCF7D2FFB4F8DA10204601F47041B1F53B
+:10299000005F14BFA6218A218822FCF7C5FFB4F886
+:1029A000DA10204601F47041B1F5005F14BFA72191
+:1029B0008B218822FCF7B8FFB4F8DA10204601F426
+:1029C0007041B1F5005F14BFA8218C218822FCF76B
+:1029D000ABFF10BD10B5D0F8A830044693F8E9332A
+:1029E000A02B03D110490422FDF756F820460022FF
+:1029F0004FF48E71FCF798FF204618220B49FDF723
+:102A00004BF841F2DE23E35A2046FF2240F23461C4
+:102A1000002B08BF0C23FDF72BF8204604490922A0
+:102A2000FDF73AF810BDC046C0DD0100C8DD010069
+:102A300026D5010070B504220D4607490646FDF76C
+:102A40002BF80024054B625BE15A30460234FCF758
+:102A50006BFF302CF6D170BDFAD701005ED40100B7
+:102A60002DE97043054698461646B0F8DA40FFF760
+:102A7000E1F804F47044B4F5005F14BFA524892480
+:102A80000246214628469DF81890FCF74DFF314636
+:102A90002846FFF7CFF8B5F8DA40024604F4704450
+:102AA000B4F5005F14BFA6248A2428462146FCF70B
+:102AB0003BFF41462846FFF7BDF8B5F8DA4002462D
+:102AC00004F47044B4F5005F14BFA7248B24284697
+:102AD0002146FCF729FF49462846FFF7ABF8B5F831
+:102AE000DA40024604F47044B4F5005F14BFA82431
+:102AF0008C2428462146FCF717FFBDE87083C046AA
+:102B000070B505460E460024074BA25BE15A2846E5
+:102B10000234FCF709FF182CF6D128460349224657
+:102B2000FCF7BAFF70BDC046DCD901008ED80100A9
+:102B300070B506220E4644490446FCF7ADFF002559
+:102B4000424B2046E95AFCF7D7FEA8530235182D10
+:102B5000F6D1072101222046FCF7E6FE1022FF21D4
+:102B600013462046FCF726FF04221346204640F277
+:102B70001F11FCF71FFF0C2220463549FCF78CFF84
+:102B800001223A2113462046FCF714FF04223A2181
+:102B900013462046FCF70EFF0822134620464FF44A
+:102BA0008D71FCF707FF0822052113462046FCF72C
+:102BB00001FF0122134620464FF48D71FCF7FAFE07
+:102BC000122220462349FCF767FF20228221134668
+:102BD0002046FCF7EFFEB4F8DA3003F47043B3F5A7
+:102BE000005F02D000252E4608E0D4F8A8309A7A7B
+:102BF000D97A42F400721D7B42EA01160122204676
+:102C000013464FF49B61FCF733FF2046B3004FF4AB
+:102C10009B6140F6FC72FCF72BFF02222046134614
+:102C20004FF49B61FCF724FF2B0320464FF49B617C
+:102C30004FF4E04203F47043FCF71AFF20460649C4
+:102C40000622FCF729FF70BDBEDC0100DCD90100C3
+:102C5000B2DA01003ED6010062D601002DE9F74F3D
+:102C6000D0F8A830814693F80B809C7A1A7E1F7B9F
+:102C70004FEA081844F4007493F817B09E7D44EAB4
+:102C80000804009293F814A0DD7C44EA07345B7DCD
+:102C900047F2FF38A4B2092223490193FCF7FCFE56
+:102CA00048464246234640F2DB41FCF7E1FE4846F7
+:102CB0004246234640F2DC41FCF7DAFE48464246F3
+:102CC000234640F20A41FCF7D3FE4FEA0A1A019B61
+:102CD00045F4007545EA0A0545EA0335484642468B
+:102CE000ABB240F20B41FCF7C3FE4FEA0B1B009A5C
+:102CF00046F4007646EA0B0646EA02364846424665
+:102D0000B3B240F20C41FCF7B3FE202248468221C8
+:102D10001346FCF74FFE012248467C211346FCF780
+:102D200049FEBDE8FE8FC046E8D70100012970B515
+:102D300005460C4616D106222949FCF7ADFE284669
+:102D40003A2122462346FCF735FE08222846134640
+:102D50004FF48D71FCF72EFE28467F210022FCF7F0
+:102D6000E3FD33E079B91F490622FCF795FE2846BA
+:102D70003A2101222346FCF71DFE082228464FF483
+:102D80008D71134620E0022920D1B0F8DA3003F427
+:102D90007043B3F5005F02D17D21032201E07D2164
+:102DA0002246FCF7C1FD284628210F220123FCF70B
+:102DB00001FE8022134628464FF48971FCF7FAFD84
+:102DC0002846052107220223FCF7F4FD284640F29D
+:102DD00037614FF440420023FCF74AFE70BDC04605
+:102DE000FAD3010006D401002DE9F047C369D0F8F9
+:102DF000A8501B6D0C4613F4805F40F2234114BFB2
+:102E00004FF006094FF00909064695F844A3FCF770
+:102E1000FDFD40F2344107463046FCF7F7FD204601
+:102E2000FEF7E6FF95F84433C1B2B5F8642395F890
+:102E300048030BB9012092E007F0FF07C0EB010344
+:102E4000C2EB07029B1A5FFA83F84FFA88F4002C52
+:102E50001DDAF36930461B6D03F48053002B0CBF61
+:102E60000B21042114BF0322082263429A42A8BF07
+:102E70001A46B5F8683301FB02324FF4AA6192B2E8
+:102E8000FCF7D0FD14F1030F06DAFB1C05E0032C60
+:102E900002DDFB1E9BB200E0BBB2B5F8640319B2C1
+:102EA00002B2D31C994201DDC31C03E09142ACBFC6
+:102EB0000B4613469CB2BAF1000F13D023B2BB42AB
+:102EC00010D02346304640F22341FF22FCF7D0FDCC
+:102ED000304624490422FCF7DFFD1420F3F33CF4D0
+:102EE000002700E00127B5F866434FFA88F220B2C8
+:102EF000C9EB000352429A42B8BFC9EB040391B236
+:102F0000B8BF99B20AB200F109039A42C4BF04F1F2
+:102F1000090399B2B6F8DA3003F47043B3F5005FF1
+:102F20000CBF95F94B3395F94C335B189BB2BAF152
+:102F3000000F05D0304640F23441FF22FCF798FDE7
+:102F4000304640F22341FCF761FD95F8BC33C0B236
+:102F500085F8BD0385F8BE0385F8BF333846BDE864
+:102F6000F087C046ACD7010070B5D0F8A850044631
+:102F7000FF22B5F8663340F23441FCF779FDB5F82D
+:102F800064332046FF2240F22341FCF771FD2046C6
+:102F9000B5F868234FF4AA61FCF744FD20460449C4
+:102FA0000422FCF779FD1420F3F3D6F370BDC0467C
+:102FB0004EDD0100082270B5134605465721FCF787
+:102FC000F9FC56212846FCF797FC00F0F80456213E
+:102FD00022462846FCF7A8FC0120F3F3BDF3562156
+:102FE00044F003022846FCF79FFC0120F3F3B4F3FE
+:102FF000562144F007022846FCF796FC4FF49670E1
+:10300000F3F3AAF32846572108220023FCF7D2FC49
+:1030100070BDC0462DE9F04140F24A463146804637
+:10302000FCF7F4FC40F04404A4B24FF6BF754046F0
+:103030003146224604EA0505FCF7F4FC31462A46EF
+:103040004046FCF7EFFC25F004050420F3F384F37D
+:10305000404631462A46FCF7E5FCBDE8F081C04613
+:103060002DE9F04706460C461546384906221F460C
+:10307000DDF82090BDF82480FCF70EFD304640F2CC
+:1030800082414FF6FF722346FCF7F2FC304640F2D5
+:103090008141FF222B46FCF7EBFC3FB9304640F262
+:1030A00081414FF480723B46FCF7E2FC30462849F0
+:1030B0000322FCF7F1FC0A2308FB03F5002407E0D8
+:1030C000AC4201DD002439E06420F3F345F3013420
+:1030D000304640F28141FCF799FC10F4007FEFD1BB
+:1030E00040F283413046FCF791FC40F284410446B3
+:1030F0003046FCF78BFC40EA0440C9F8000040F27F
+:1031000085413046FCF782FC40F286410446304659
+:10311000FCF77CFC40EA0440C9F8040040F2874117
+:103120003046FCF773FC4FF4916104463046FCF7DF
+:103130006DFC40EA0440C9F8080001243046054906
+:103140000622FCF7A9FC2046BDE8F087ECDB010075
+:10315000F8DB0100FEDB010070B50546002407E046
+:103160006420F3F3F9F2013441F289339C4207D031
+:10317000284640F25141FCF749FC10F4404FEFD192
+:10318000284640F25141FCF741FC10F4404F14BF77
+:103190000020012070BDC04610B540F24C414FF6F2
+:1031A000FC72FCF747FC10BDC36970B504460D46C0
+:1031B00018698E2116463DF09DDAE36941194900F0
+:1031C000186932463DF0B4DA70BDC046C36970B5C7
+:1031D00004460D4618698E213DF08CDAE3694119E9
+:1031E000490018693DF086DA70BDC0462DE9F0410E
+:1031F0000C46272180461646FFF7E8FF10F0010332
+:1032000002D101271D4605E04FF6F07500EA0505DD
+:103210004FF6F07728214046FFF7D8FF3840A84204
+:1032200001D1012009E0013C631C002B02DD1420C8
+:10323000F3F392F2002CEDDC002006B13460BDE81F
+:10324000F081C0462DE9F0410646D0F8A850FEF7BF
+:10325000C5FFB0F5404F46D1F369E02118693DF054
+:1032600049DAEC8D8046C4EB000440F2A5413046BB
+:10327000FCF7CCFB0123C0F30227BB40A4B29C4265
+:1032800031DD95F8C134A5F82E80BB4208D901374D
+:10329000304640F2A5414FF4E0623B02FCF7E8FB08
+:1032A0003046FEF775FF40B280B22886B6F8DA30B5
+:1032B0006F8603F47043B3F5005F0CBF85F85404C8
+:1032C00085F85504D6F8A8202B8E92F966255B0068
+:1032D000013293FBF2F3304640F2A44140F2FF1278
+:1032E0009BB2FCF7C5FBBDE8F081C0462DE9F04F6D
+:1032F000044685B00D46D0F8A860FFF7A3FFD4F8C8
+:10330000B030D3F8203183F0010313F001030393AD
+:1033100003D1E36918693DF03DDA07212046FCF747
+:10332000EBFAFF2101902046FCF7E6FA40F21F116C
+:1033300002902046FCF7E0FA40F23B4183462046EB
+:10334000FCF764FB40F23C4182462046FCF75EFB02
+:1033500040F2D74181462046FCF758FB4FF49B6171
+:1033600080462046FCF752FB0F224649074620467E
+:10337000FCF792FB0122072113462046FCF71AFBBB
+:103380001022FF2113462046FCF714FB04221346AB
+:1033900040F21F112046FCF70DFB0A20F3F3DCF18D
+:1033A000202220464FF49A611346FCF761FB0A2065
+:1033B000F3F3D2F1012D21D140F276412046FCF702
+:1033C00025FB40F27741C5052046FCF71FFBC005F1
+:1033D000C00DED0DFF288ABFA0F5007302469AB21A
+:1033E000FF2D88BFA5F50073A6F86E058CBF98B2B7
+:1033F0002846C0EB0203A6F86C550AE0204640F2CE
+:103400007541FCF703FBC005C00DFF2803D9A0F5EB
+:1034100000739DB200E00546019B2046DAB2072109
+:10342000FCF782FA029B2046DAB2FF21FCF77CFA15
+:10343000204640F21F115FFA8BF2FCF775FA204626
+:1034400040F23B415246FCF7EDFA204640F23C4147
+:103450004A46FCF7E7FA204640F2D7414246FCF7DD
+:10346000E1FA20464FF49B613A46FCF7DBFA039BF6
+:103470001BB9E36918693DF079D928B205B0BDE8F8
+:10348000F08FC04640D4010070B5D0F8A8300129B3
+:10349000D3F8DC63D3F8D853D3F8E04304D1013137
+:1034A000FFF724FF02B20AE040F27541FCF7AEFAE2
+:1034B000C005C00DFF288CBFA0F500720246631F37
+:1034C00001209840801905FB1200231F184140B2CB
+:1034D00070BDC04610B50129D0F8A83003D1FFF760
+:1034E00005FF00B212E0B3F86C25B3F86E35FF2B80
+:1034F00086BFA3F5007399B21946FF2A86BFA2F5CD
+:1035000000739BB21346C3EB010318B210BDC04653
+:1035100070B5D0F8A830D3F8D443D3F8D053D3F84B
+:10352000CC63FFF7D7FF621E0123934000B25B1903
+:1035300006FB1030204140B270BDC0462DE9F0417D
+:10354000B0F8DA20074602F47043B3F5005FD0F814
+:10355000A85004D1B5F85463B5F8844513E0D3B24C
+:10356000942B03D9B5F88645022308E0632B03D9D1
+:10357000B5F88845012302E0B5F88A45002305EB3C
+:103580004303B3F85663FF2E1ED001213846FFF7E0
+:10359000BFFF40B2193804FB00F000B20028CCBFD6
+:1035A00000F5FA73A0F5FA734FF47A7293FBF2F315
+:1035B00098B28419A4B2384640F23441FF2223461F
+:1035C000FCF756FAA5F86643BDE8F08170B50546EC
+:1035D000D0F8A8600C4689B340F2DA6142F20802E2
+:1035E000FCF736FA284640F2A6510522FCF71AFAF3
+:1035F000284640F2A251C322FCF714FA284640F2B2
+:10360000A5510722FCF70EFA284640F283514FF4E9
+:103610004872FCF707FA284640F284510022FCF772
+:1036200001FA284640F285514FF40072FCF7FAF98E
+:10363000284640F286510022FCF7F4F9284627215B
+:10364000FFF7C4FD1CB140F001039CB203E04FF64C
+:10365000FE7400EA040496F894332846F31893F8AD
+:103660009523052302FB03F22621042A98BF1A465C
+:10367000FFF79AFD04F110022846272192B2FFF7C6
+:1036800093FD70BD70B5D0F8A850044695F842334C
+:103690005BB10021FFF79AFF204619210022FFF7B6
+:1036A000A5FD10B9012385F8453370BD70B5D0F87C
+:1036B000A840054694F8423393B990F8E93013F0E6
+:1036C000010F1CBF23F0010380F8E93090F8E930C6
+:1036D00013F0020F2DD023F0020380F8E93028E028
+:1036E00094F847330BB1012303E0D1F1010338BF54
+:1036F000002384F84733E1B100230126C4F86C337A
+:1037000084F8453384F846632846FFF7BBFF94F8F6
+:103710004333003B18BF012384F8443313B12846D8
+:10372000FFF722FC2846FEF79FFB28463146FFF7AD
+:103730004DFF70BD70B5D0F8A83000260C4683F858
+:10374000466331460546FFF741FF14B12846FFF7AF
+:103750000BFC03222846134640F67A01FCF788F951
+:10376000284640F2DA6142F208023346FCF780F95B
+:1037700070BDC04670B50546D0F8A84016467AB16F
+:1037800094F8433394F842438C2144EA4304C369D8
+:10379000146018693CF0AEDF44EA004434600FE086
+:1037A000CB080DD101F0010384F84233C1F340038B
+:1037B00084F8433394F8423313B90121FFF7BAFF79
+:1037C00070BDC04610B500210446FFF7B3FF204688
+:1037D000FEF74AFB10BDC04610B50122044640F674
+:1037E0000501FCF735F920460722052340F22F4159
+:1037F000FCF73EF920463021F8234FF4FF62FCF736
+:1038000037F90623204630210722FCF731F92046FC
+:1038100040F2144141F61062FCF704F9204640F2F0
+:1038200015414FF4C862FCF7FDF8204640F2DF4135
+:103830004FF47F424FF47743FCF71AF92046FFF725
+:10384000E9FB204602492722FCF726F910BDC046B5
+:1038500024D90100002914BF0223002310B5002A37
+:1038600018BF43F001030446032240F24D41FCF728
+:10387000FFF8204640F24C410322FCF7E9F810BD66
+:1038800010B5044611B91049132219E012220F494C
+:10389000FCF702F9012100222046FFF7DBFF20465A
+:1038A0000B490622FCF7F8F8B4F8DA3003F4704359
+:1038B000B3F5005F07BF20460649204606491E2291
+:1038C000FCF7EAF810BDC04638D501005ED501000E
+:1038D00082D50100CADC0100D8D601002DE9F041F3
+:1038E00004460D46164640F2DA6148F280021F4651
+:1038F0009DF81880FCF7ACF82046FEF7B9F9B8B18E
+:1039000040F652112046FCF781F8FF22C3B240F680
+:1039100048112046FCF7ACF840F653112046FCF75E
+:1039200075F840F64911C3B2FF222046FCF7A0F813
+:10393000D4F8A83093F8463573B140F2EB412046F5
+:10394000FCF764F8C0F3402340F2EB4120464FF40B
+:1039500080629B02FCF78CF86B1EFF22204640F22F
+:1039600042619BB24FF6FF75FCF782F8AE4201D080
+:10397000731E9EB220464FF4C8612A463346FCF7B8
+:1039800077F8204640F241612A463B46FCF770F842
+:10399000B8F1000F05D0204608490422FCF77CF856
+:1039A00009E0204640F23F610122FCF73BF8204647
+:1039B0000121FFF765FFBDE8F081C046A4D70100F3
+:1039C0002DE9F0410C4640F23B410546FCF71EF85C
+:1039D00040F23C4107462846FCF718F8064674B109
+:1039E0000E2228460F49FCF757F828460121FFF719
+:1039F00047FF28460C490722FCF74EF810E02846FE
+:103A00000A490422FCF748F8284640F23B413A466E
+:103A1000FCF708F8284640F23C413246FCF702F831
+:103A2000BDE8F081C4D7010080D80100B0D5010005
+:103A30002DE9F04F0546C5B001910092FDF79CFCC1
+:103A4000EB694FF0805118690A463CF033DE0520DF
+:103A5000F2F382F6002328464FF489614FF4804246
+:103A6000FCF706F8284640F255414FF4A842FBF710
+:103A7000D9FF284640F25641FBF7C8FF00F00F007F
+:103A8000052809D14FF4A842284640F25541FBF7DA
+:103A9000C9FF4FF4807207E045F20142284640F228
+:103AA0005541FBF7BFFFFE22803A521022EAE27234
+:103AB000102AA8BF10225100002301F18006C2EB9A
+:103AC000060B1F46994698469A464393429340E018
+:103AD00040F256412846FBF799FF40F25741C0F3A8
+:103AE0000B142846FBF792FF5E4544EA003021DCC8
+:103AF000BAF17F0F1EDC8104890CB1F5005FC8BFED
+:103B0000A1F5804101F50063B3F5805F23D802ABD6
+:103B100023F8191044AB03EB880252F8083C0AF171
+:103B2000010ACB1842F8083C08EB090383F040096E
+:103B300088F00108C0F3033303F00C0343EA0713D2
+:103B400016F0010F9FB203D007F0FF03402B02D104
+:103B5000013E002EBCDCEB69002218694FF0805159
+:103B60003CF0A8DD2846FDF701FC429B9B114293E7
+:103B7000439B9B11BAF1800F43931DD0002022E09C
+:103B800041EA801202AB33F9123001315B1B40294C
+:103B900003FB0344F4D1013002280FD1009AA3099A
+:103BA0001460019A1360A3F53A63084A183B9342E4
+:103BB0008CBF0020012006E00020044642AB53F8F1
+:103BC00020500021DCE745B0BDE8F08F48F4FF0F3E
+:103BD00070B504460D46FDF7CFFB20226B01204651
+:103BE0004FF49661FBF744FF0023204640F2B141B9
+:103BF0004FF40072FBF73CFFB4F8DA3003F4704383
+:103C0000B3F5005F02D04FF0000E04E0D5F1010ED5
+:103C100038BF4FF0000E002D0CBF2023002343EAD5
+:103C20008E13204660224FF48261FBF721FF20466D
+:103C30004FF482618022EB01FBF71AFF2046FDF76B
+:103C400095FB70BD2DE9F047044688461746D0F82D
+:103C5000A890FCF795FB20460121FFF7B9FF00254E
+:103C60002E460CE0012100222046FDF78DFA384651
+:103C7000F2F372F52046FEF78BFA40B285B2F3B24A
+:103C800001364345EED320460021FFF7A1FF89F816
+:103C9000C052BDE8F087C04670B505460846FEF73D
+:103CA000A7F8EB69A02144B218693CF023DD9D3CE4
+:103CB000A4B26FF0610324B29C42B8BF1C46C1B2EB
+:103CC00062B22846FCF778FD70BDC04673B5D0F8E7
+:103CD000A840064694F84233002B00F0DC8094F8AC
+:103CE0004633002B00F0D780D0F8B030D3F8203125
+:103CF00013F0010F00F0CF8000230093019394F89C
+:103D00004553002D40F0AA8029462A46FFF76EFA57
+:103D1000002800F0A380304601A96A46FFF788FE1C
+:103D2000002800F09B80009BC4F86C3394F8463365
+:103D3000012B40F0938094F891030199AC46AE4674
+:103D40001FE045B204EB8502D2F87033994201D3EB
+:103D5000002203E0C2F870131946012204EB850328
+:103D6000D3F870339C440EF101035FFA83FE431CC9
+:103D7000D8B243B2072BC8BF002012B101910199FC
+:103D800019E094F990334FFA8EF29A42D9DBF5E7B5
+:103D900043B204EB8303D3F87023C3F87013431CBE
+:103DA000D8B243B2072BC8BF00200EF101038C44E8
+:103DB0005FFA83FE11464FFA8EF3072BE8DD01917F
+:103DC00094F8902353B2072B05DC002384F8923338
+:103DD000531C84F8903394F99033082B3ED194F817
+:103DE0009433E31893F8972393F8995394F8923304
+:103DF000FC2B02D8013384F8923394F89233934227
+:103E00002CD194F89133013384F891335BB2072BB2
+:103E100002DD002384F8913394F890333046023B5E
+:103E200084F890336146FEF7DFFF18B93046FEF79D
+:103E30001BF810E094F89333FC2B02D8013384F87C
+:103E4000933394F89333AB4205D194F8943313B978
+:103E5000013384F89433002384F8923394F84613A2
+:103E60000023012984F8453303D13046FFF7AEFB28
+:103E700003E030461946FFF75DFC3046D4F86C137A
+:103E8000FFF70AFF002384F8473394F89C3313B9F3
+:103E9000013384F89C337CBD2DE9F04F0746D0F800
+:103EA000A800E1B00B9041F21403FB5C0C46002B20
+:103EB00000F09C82FB696A2118693CF01BDC400021
+:103EC0001FFA80FBBBF1000F00F090823846FEF72E
+:103ED00085F9FB69024610B91869594684E21869E8
+:103EE00059463CF007DC012800F080820BF1060304
+:103EF0009BB20C930BF13A039BB20D930BF16E0343
+:103F00009BB20E930BF1AA039BB20F93002C00F00F
+:103F10005A82384640F2F941FBF778FD10F0080F5D
+:103F200040F064824CAD38ACAB1C0193A31C0393EE
+:103F30003846002340F2764140F2FF120095029489
+:103F4000FBF7E0FD2B1D0093AB1D0193231D029396
+:103F5000A31D03933846002340F2774140F2FF123D
+:103F6000FBF7D0FD05F10803009305F10A03019367
+:103F700004F10803029304F10A030393384640F264
+:103F8000AA4148F2FF1248F27F03FBF7BBFD05F19F
+:103F90000C03009305F10E03019304F10C031622A8
+:103FA000029304F10E0303933846134640F23B415B
+:103FB000FBF7A8FD05F11003009305F1120301932F
+:103FC00004F11003029304F11203462203933846CE
+:103FD000002340F23C41FBF795FDB7F8DA3005F1DC
+:103FE000140E03F47043B3F5005F05F11C030A934C
+:103FF00005F11E03099304F11C03089304F11E0349
+:10400000079305F12003069304F1200305F116023E
+:1040100004F1140104F1160005F1180605F11A085F
+:1040200004F1180904F11A0A05F12205059304F1B7
+:10403000220437D1019241F22B02134602910390E0
+:1040400040F24C413846CDF800E0FBF75BFD3846C6
+:1040500040F24D4144F22B0244F20A030096CDF89F
+:104060000480CDF80890CDF80CA0FBF74BFD089A22
+:104070000A980999079B02920722009001910393E5
+:104080003846134640F2F941FBF73CFD0698059986
+:10409000072200900291384640F2FA4113460195FA
+:1040A000039436E0019241F22B02134602910390F1
+:1040B00040F24C413846CDF800E0FBF723FD38468E
+:1040C00040F24D4144F22B0244F222030096CDF817
+:1040D0000480CDF80890CDF80CA0FBF713FD0A9AE8
+:1040E000099B0898079900920722019302901346B2
+:1040F0000391384640F2F941FBF704FD069A059B0F
+:104100000092029301950394384640F2FA41072247
+:10411000002324ACFBF7F6FCA31C019310AB012297
+:1041200002930DF14203072103933846134600948E
+:10413000FBF754FC231D0093A31D019311AB102228
+:1041400002930DF14603FF21039338461346FBF714
+:1041500045FC04F10803009304F10A03019312AB38
+:10416000042202930DF14A034CAE039338461346E2
+:1041700040F21F11FBF732FC06F1240338AD009327
+:1041800006F12603019305F1240340F6440202934D
+:1041900005F1260303933846134640F63811FBF722
+:1041A000B1FC06F12803009306F12A03019305F1FF
+:1041B0002803029305F12A030393384640F6391188
+:1041C00040F6440240F60403FBF79CFC04F10C03A8
+:1041D000009304F10E03019313AB012202930DF13E
+:1041E0004E033A21039338461346FBF7F7FB04F1DD
+:1041F0001003009304F11203019314AB08220293FD
+:104200000DF152030393384613464FF48D71FBF7BB
+:10421000E5FB04F11403009304F11603019315ABBD
+:10422000082202930DF156030521039338461346E5
+:10423000FBF7D4FB04F11803009304F11A03019374
+:1042400016AB042202930DF15A033A210393384628
+:104250001346FBF7C3FB04F11C03009304F11E0398
+:10426000019317AB012202930DF15E0303933846CD
+:1042700013464FF48D71FBF7B1FB06F12C0300934D
+:1042800006F12E03019305F12C03029305F12E0391
+:104290000393384640F2D74147F2CB0242F24B0338
+:1042A000FBF730FC04F12003009318AB20220293AB
+:1042B0000DF16203822122340393384613460194A0
+:1042C000FBF78CFB0B98037B827AC17A1B0342F4C9
+:1042D000007242EA011243F0030343EA820306F14B
+:1042E0003002009205F13002323602923235384601
+:1042F0004FF49B6147F6FF729BB201960395FBF763
+:1043000001FCDDF83090DDF834800026FB694CAC10
+:10431000325B186949463CF00BDAFB6938AD725BD9
+:10432000186941463CF004DAFB69A419186909F1DF
+:10433000020162883CF0FCD9FB69AD1908F1020169
+:1043400018696A8804363CF0F3D9342E09F104095F
+:1043500008F10408DAD1DDF83890DDF83C80002659
+:10436000FB6924AC325B186949463CF0E1D9FB6932
+:1043700010AD725B186941463CF0DAD9FB69A419AB
+:10438000186909F1020162883CF0D2D9FB69AD19C4
+:1043900008F1020118696A8804363CF0C9D9242E54
+:1043A00009F1040908F10408DAD1FB690BF10201F3
+:1043B00018690D223CF0BCD9FB690BF104011869A6
+:1043C00009223CF0B5D9FB690B991A6A18690B9B55
+:1043D000C1F83824B3F83C240BF1E6013CF0A8D92D
+:1043E000FB695946186901223CF0A2D961B0BDE8C9
+:1043F000F08FC0462DE9F04F8DB007460F220E46D4
+:104400000DF12100B149EDF3B7F5D7F8A8800022EE
+:10441000AF4D14016359B34203D001320E2AF7D1D4
+:1044200073E3384691210022FBF77EFA38463821A3
+:104430000722FBF779FA0A2238468821FBF774FA3B
+:10444000D7F8A83093F882251AB138468821FBF7AF
+:104450006BFA64192A213846227AFBF765FA302173
+:1044600003223846637AFBF7A5FA912103223846E6
+:10447000A37AFBF79FFAE37A38210F223846FBF73D
+:1044800099FA912100223846FBF74EFA382107228B
+:104490003846FBF749FA237B30210C229B00384633
+:1044A000FBF788FA5E210F223846637BFBF782FA1E
+:1044B000A37B5E211B01F0223846FBF77BFA6C21BF
+:1044C0003846E27BFBF730FA384638210822FBF702
+:1044D0002BFA384691210322FBF726FA0CA98B19F7
+:1044E00013F8102C38465E21FBF71EFA01223846DD
+:1044F0007E21FBF719FA98F8EE231AB138463821D5
+:10450000FBF712FA0722134638462A21FBF752FA24
+:1045100038462C210022FBF707FA38462A210C22C4
+:10452000FBF702FA012238462C21FBF7FDF9D7F8F8
+:10453000A82092F852352BB338465E2192F85325C5
+:10454000FBF7F2F9D7F8A830384693F854252A211A
+:10455000FBF7EAF9D7F8A830384693F855252B2110
+:10456000FBF7E2F9D7F8A830384693F856252C2106
+:10457000FBF7DAF9D7F8A83038462D2193F85725FC
+:10458000FBF7D2F9B7F8DA3003F47043B3F5805F84
+:1045900004D13846BF21EE22FBF7C6F902221346AA
+:1045A000384640F21F11FBF705FA0422F7211346A3
+:1045B0003846FBF7FFF9F121032200233846FBF7C9
+:1045C000F9F9F221F82290233846FBF7F3F9A223F8
+:1045D000F321FF223846FBF7EDF9B7F8DA3003F4A0
+:1045E0007043B3F5005F04D1D7F8A83093F81835BD
+:1045F00006E0B3F5805F06D1D7F8A83093F81935F7
+:10460000012B00F07982042238469D210023FBF71C
+:10461000D1F90022079244213846FBF76DF940F2A8
+:104620002B1101903846FBF767F9442102900722CD
+:104630003846FBF7B1F9384640F22B110E22FBF752
+:10464000ABF9079BD7F8F8AF0BB9554601E04FEA35
+:104650004A05204B9A4502D84FF0010906E01E4B4F
+:104660009A4594BF4FF002094FF00409B7F8DA30C9
+:1046700003F47043B3F5005F03D000210591069168
+:1046800006E06268032302FB03F205926A000692C9
+:10469000124C102221465046FDF7BEF91022214649
+:1046A0002846FDF7B9F91022049009FB04F15046A1
+:1046B000FDF7B2F9B7F8DA30039003F47043B3F5BD
+:1046C000005F0DD04FF0000B10E0C04612D4010087
+:1046D000A8EF010080BA8C010075190340420F0059
+:1046E000059802211022FDF797F983464F210222F7
+:1046F0003846FBF719F9CD4B4FEACA0509FB03F31E
+:10470000B5FBF3F301335B08013B5FFA83F85221F9
+:10471000072238464FEA9803FBF74CF908F10106E7
+:104720005321602238464FEA4813FBF743F909FB4F
+:1047300006F3BF4CB5FBF3F5BE4B2C19B4FBF3F4F9
+:10474000013CE4B2512122463846FBF7EDF8039BC9
+:1047500010221D0158462946FDF75EF9013406FB7B
+:1047600004F600FB06F000280BDB58462946102211
+:10477000FDF752F900FB06F0C01301304010441E53
+:104780000EE0584629461022FDF746F96FEA080365
+:1047900003FB04F300FB03F0C01301306FEA600475
+:1047A000C4F3072353210F223846FBF703F95421A2
+:1047B000E2B23846FBF7B8F806999F4B0A22B1FBE4
+:1047C000F3F30599384601FB02F2B2FBF3F803FB61
+:1047D0001822590802F0010401EB04545208B4FBFA
+:1047E000F3F49B0803EB0253B3FBF1F3E418452108
+:1047F0001F22C8F30713FBF7DDF84FEA0813462121
+:1048000038464FF4F87203F0F003FBF7D3F8C4F323
+:10481000074346210F223846FBF7CCF84721C4F363
+:1048200007223846FBF780F84821E2B23846FBF70A
+:104830007BF8079A41F29416002A08BF4FF4FA5603
+:10484000A6F5D8760CBF4FF482794FF4E1794FF496
+:10485000F572033E96FBF2F606FB02F505F52A75A6
+:104860004FF425636D02B5FBF3F540F27C6405FB64
+:1048700004F4A4F55834A4F5C064B4FBF2F4640A5B
+:10488000C4F3820242EAC6023846422192B2A4B27E
+:10489000FBF74AF804F0030204F01F0444EA421252
+:1048A00038464321FBF740F84FEA49244FF4877319
+:1048B000B4FBF3F404FB05F4604B640A604AB3FBF9
+:1048C000F4F39A184FF41243B2FBF3F25D4B02F08B
+:1048D0000F02B3FBF4F3A3F54C23A3F500631B0C09
+:1048E00042EA03123846402192B2FBF71DF84FF01E
+:1048F0002552554BB2FBF4F2B3FBF4F3A2F546326A
+:104900004FF4B841A2F50072A3F56E33B2FBF1F299
+:10491000A3F50073B3FBF1F302F00F0242EA0312B6
+:104920003846412192B20BF17444FAF7FDFF04F5C9
+:1049300090044FF4966394FBF3F4292304FB03F4EF
+:104940004FF45C7308FB03F840F22B5306FB03F6AD
+:1049500006F5E46109FB08F00C311022FDF75CF864
+:1049600004F5D81400EB640090FBF4F0C0B23C28CE
+:1049700094BF0025012515B14308043B00E0031F47
+:10498000DCB23C213F2223463846FBF713F8AB014B
+:104990003C2140223846FBF70DF8B7F8DA3004F135
+:1049A000040603F47043B3F5005F05F1010404D17C
+:1049B000D7F8A83093F8273506E0B3F5805F19D112
+:1049C000D7F8A83093F82835012B13D1049B40F277
+:1049D00045105946102203FB00F0FDF71DF804FBBB
+:1049E00006F39E2100FB03F4C02238464023FAF769
+:1049F000E1FF0BE00499962001FB00F010225946DC
+:104A0000FDF70AF804FB06F300FB03F4B4F5160FF8
+:104A1000D4BF002501256B1C032203FB02F394FB8A
+:104A2000F3F0B0F5003F11D5002315E0404B4C00EA
+:104A30003F420F0040420F00A08601000000686066
+:104A40000021F6FF000084A30000302AA0F5C03347
+:104A5000DB130133C3F347033D213F223846FAF706
+:104A6000A9FFAB013D2140223846FAF7A3FF284BAE
+:104A70009A4504D9202238465721134603E0384688
+:104A8000572120220023FAF795FF224B9A4504D99B
+:104A9000102238465721134603E03846572110228A
+:104AA0000023FAF787FF049AB2F5341F05DD384674
+:104AB0004A210222FAF770FF04E038464A21FD221B
+:104AC000FAF75CFF0C22442113463846FAF772FFCE
+:104AD0000120F1F341F63846FEF76CFA019B3846A7
+:104AE0004421DAB2FAF720FF029B384640F22B113C
+:104AF000DAB2FAF719FF08E004229D21384613467E
+:104B0000FAF758FF0121079185E50DB0BDE8F08F58
+:104B100080BA8C01007519032DE9F0478A4BD0F853
+:104B2000F84F4FF48475B4FBF3F404FB05F41A2337
+:104B30005721B4FBF3F40646FAF7DEFE172181464F
+:104B40003046FAF7D9FE18213046FAF7D5FE40F282
+:104B50000511FB2207463046FAF710FF30460421C4
+:104B60004022FAF719FF30464FF490711022FAF7FD
+:104B700013FF304657210222FAF70EFF304640F26B
+:104B800005110422FAF708FF30464FF483712A22F8
+:104B9000FAF7CAFEA4B2304640F207116E22FAF7C5
+:104BA000C3FEE2B230462946FAF7BEFEC4F3042241
+:104BB000304640F20911FAF7B7FE304640F20511CF
+:104BC000FD22FAF7DBFE30464FF483710122FAF73B
+:104BD000E3FE3220F1F3C0F55C4C03E00A20F1F370
+:104BE000BBF50A3C30464FF48571FAF785FE10F0AC
+:104BF000010F01D1092CF1D130464FF48571FAF73C
+:104C00007BFE10F0010F08D1FAB230461821FAF7F6
+:104C1000C3FE4FF00B0847460CE0304640F20F1140
+:104C2000FAF76AFE00F01F071D2F8CBF4FF00B082C
+:104C300007F1020819213046FAF75EFE4FF483713E
+:104C4000FE2205463046FAF799FE304640F205113D
+:104C5000FB22FAF793FE304640F205110422FAF7E0
+:104C60009BFE304640F205110222FAF795FE3046CF
+:104C70004FF483710122FAF78FFE3220F1F36CF5C5
+:104C8000324C03E00A20F1F367F50A3C30464FF45A
+:104C90008571FAF731FE10F0010F01D1092CF1D125
+:104CA00030464FF48571FAF727FE10F0010F06D158
+:104CB000EAB230461921FAF737FE092506E03046F8
+:104CC0004FF48871FAF718FE00F01F053046FE22F7
+:104CD0004FF483716C01FAF751FE44EA85243046A3
+:104CE000FB2240F20511FAF749FE2C4330465721CA
+:104CF0005FFA89F2FAF718FE3046224640F6331181
+:104D0000FAF790FE2246BC02304644EA471440F6C9
+:104D10003411FAF787FE304645EA040240F63511B1
+:104D2000FAF780FE304644EA070240F63611FAF7F9
+:104D300079FE48EA4812D205304640F63711D20DC6
+:104D4000FAF770FEBDE8F08740420F0089969800A0
+:104D500070B55B210446FD22FAF710FE20460421BF
+:104D60004022FAF719FE20464FF490711022FAF70C
+:104D700013FE204678218022FAF70EFE204640F2EC
+:104D800029110222FAF708FE204657210122FAF7DC
+:104D900003FE20465B210222FAF7FEFD41F2883035
+:104DA000F1F3DAF4154D03E00A20F1F3D5F40A3DEE
+:104DB0005C212046FAF7A0FD10F0200F01D1092D4B
+:104DC000F2D15C212046FAF797FD10F0200F03D0B6
+:104DD00020465C21FAF790FD20465B21FD22FAF780
+:104DE000CDFD20465721FE22FAF7C8FD204640F2AD
+:104DF0002911FD22FAF7C2FD70BDC04689969800C0
+:104E000070B504460E4600256E4B2046E95AFAF767
+:104E100073FDA8530235302DF6D1182220466A4979
+:104E2000FAF73AFE3A21FB222046FAF7A7FD0122C3
+:104E300020464FF48D71FAF7AFFD3621012220464E
+:104E4000FAF7AAFD10224FF48D712046FAF7A4FD5F
+:104E50001420F1F381F43A2101222046FAF79CFD57
+:104E60001420F1F379F4B4F8DA3003F47043B3F5B5
+:104E7000005F03D120463A21012208E020463A2172
+:104E800001220023FAF796FD2046CA210422134688
+:104E9000FAF790FD082220464FF48D71FAF77CFD59
+:104EA00025210E222046FAF73FFD2521012220462A
+:104EB000FAF772FDB4F8DA3003F47043B3F5805FAB
+:104EC00004D1204628211E22082303E02046282161
+:104ED0001E220C23FAF76EFD1420F1F33DF4052198
+:104EE00008222046FAF720FD80224FF489712046DF
+:104EF000FAF752FD1420F1F32FF4FF21102220467F
+:104F0000FAF74AFD442240F21F112046FAF744FD09
+:104F10001420F1F321F40B2107222046FAF73CFD7F
+:104F2000102240F213112046FAF736FD1420F1F357
+:104F300013F4072101222046FAF7F6FC1420F1F3BE
+:104F40000BF4022303222046FC21FAF733FDFD2156
+:104F50002046A622FAF7E8FC442240F21F11204620
+:104F6000FAF71AFD1420F1F3F7F3FF21102220467F
+:104F7000FAF712FD1420F1F3EFF3B4F8DA3003F48A
+:104F80007043B3F5805F03D110492046082202E048
+:104F90000F4920460622FAF77FFD20465921CC22F0
+:104FA000FAF7C2FC20465C212E22FAF7BDFC20460F
+:104FB0007821D722FAF7B8FC204692211522FAF779
+:104FC000B3FC70BD5ED4010056DD01005ED7010068
+:104FD00086DD01002DE9F04F04468BB0894609B902
+:104FE0008B4608E040F2D741FAF710FD01A983464D
+:104FF0002046FDF79DFD202213464FF49A6120467E
+:10500000FAF736FD6420F1F3A7F340F2764120462B
+:10501000FAF7FCFC40F2A64180462046FAF7F6FC7F
+:1050200009A9824608AA204607ABFBF7C1F9099FE8
+:10503000089E079DB9F1000F09D0204601A9FDF790
+:105040005FFD204640F2D7415A46FAF7EBFC4FEAA3
+:10505000C850C00D4FEACA5380F48070DB0D00F5D4
+:10506000FE70033083F48073C01A801039463246D4
+:105070002B46FCF7F1FC40000BB0BDE8F08FC046BA
+:10508000F0B5D0F8A85085B095F858340646002BF6
+:105090007BD00023019302930393FDF779F8C7B205
+:1050A0000FB17F2F71D101AB02AA304603A9FBF7E4
+:1050B0007FF940F23E613046FAF7A8FC40F2A64183
+:1050C000C4053046FAF7A2FCC005C00DE40DFF2868
+:1050D0008ABFA0F5807300F580729AB2FF2C84BF5E
+:1050E000A4F5807398B2C2F5FE7398BF04F5807082
+:1050F00003331B18C3F38F00C7B995F85634013337
+:10510000DBB2042B85F856343FD985F85674029AE1
+:10511000019B0399FCF7A0FCD5F848244310043BFD
+:105120009342B8BF1346C5F844341AE07F2F2CD100
+:1051300095F857340133DBB2042B85F8573424D962
+:10514000002385F85734029A019B0399FCF784FCED
+:10515000D5F84424431004339342A8BF1346C5F83E
+:105160004834D6F8A8109BB2D1F844243046934274
+:10517000A8BF1346D1F8482440F2A7419342B8BFD4
+:1051800013469BB2FF22FAF773FC05B0F0BDC04690
+:105190002DE9F04F474B87B003AC80460D4693E8AE
+:1051A000070084E8070040F245614046D8F8A8B0FF
+:1051B000FAF72CFC40F2466187054046FAF726FCD8
+:1051C0003D49860506224046FAF766FC00210A465C
+:1051D0004046FDF745F84FF4FA73019340462946DF
+:1051E0002022A3F5FA730094FDF73AFFBF0DB60D28
+:1051F0008246002849D0049DDDF81490039C09EBF9
+:105200000503012B02D84FF0000A3EE02046FBF7D1
+:1052100057F806464846FBF753F8A6F114031AB2AE
+:10522000002A06DB35FA02F13FD0013235FA02F2EC
+:1052300006E0534215FA03F137D0D24315FA02F2D1
+:1052400033B2C3F11E0314FA03F3C3EB0204A0F15B
+:105250000B031BB2002B0A4602DB35FA03F102E016
+:105260005B4215FA03F120D003B2C3F11F0309FA20
+:1052700003F394FBF2F493FBF1F004FB1400FBF74F
+:105280002BF8A7058605BF0DB60D404639463246B8
+:10529000FCF7E6FF404609490622FAF7FDFB5046B7
+:1052A000ABF8B872ABF8BA6200E0002007B0BDE816
+:1052B000F08FC04634D4010074D801007ED90100BB
+:1052C00070B504460D46C9B104221249FAF7E4FB51
+:1052D000D4F8A83093F8E933A02B05D1204640F646
+:1052E0004A1140F24F1203E0204640F64A11A7222D
+:1052F000FAF798FB084920460E2201E007490A22E6
+:10530000FAF7CAFBE369291E18BF012118693BF0AF
+:105310004BDA70BDE0D70100BAD901000EDD010003
+:1053200070B50C4606222749E4B20546D0F8A860BD
+:10533000FAF7B2FB0C2C01D8002406E005F58A53DD
+:1053400093F900301C1E18BF012496F81A35002B63
+:1053500031D0284640F64211FAF758FB14B10F2815
+:105360000BD100E0A8B9D5F8F83013F0060F22D120
+:1053700096F82C30A3421ED05CB1EB690122D868AC
+:105380009968F0F33BF628460121FFF799FF0123C6
+:105390000AE0EB690022D8689968F0F32FF62846F6
+:1053A0000021FFF78DFF002386F82C3028460649A0
+:1053B0000C22FAF771FB284604490422FAF76CFB29
+:1053C00070BDC04692DD010046D70100F8DD010046
+:1053D00070B50D46B0F8DA101646D0F8A840FAF7C6
+:1053E0003BFD28B994F84C342B7094F84D3401E00F
+:1053F00000232B70337070BD2DE9F0474FF000088B
+:1054000086B0054602ABCDF81080CDF80C80CDF803
+:10541000088003AA8A4604A9D0F8A890FAF7C8FF22
+:1054200028460DF117010DF11602FFF7D1FF9DF887
+:10543000173004990193039A029B01242846009493
+:10544000FCF71EFB9DF81630074601932846029B89
+:105450000499039ACDF80080FCF712FB99F8E83321
+:1054600006460BB39DF81700B5F90221B5F90431D2
+:10547000B5F9061101902846039202930491009415
+:10548000FCF7FEFA9DF8163004460193284604996D
+:10549000039A029BCDF80080FCF7F2FAA742B8BF4E
+:1054A00027468642A8BF0646BAF1010F02D0BAF1DC
+:1054B000030F02D17B10C9F84434AAF10203DBB216
+:1054C000012B02D87310C9F8483406B0BDE8F08744
+:1054D00007B540F25643009340F255420133FAF7C4
+:1054E000FBFB0EBD2DE9F04340F2DF4189B0D0F85F
+:1054F000A8400546FAF78AFAC3B27F2BA4F84C30CD
+:10550000C0F30720C4BFA3F58073A4F84C307F28F4
+:10551000C8BFA0F58073A4F84E0001AFC8BFA4F8BF
+:105520004E301123039320262A330DF118094FF032
+:105530000208284639460493CDF80490CDF8088037
+:105540000596FFF7C5FF069B3F2B01D9803B0693CD
+:10555000069B2365079B3F2B01D9803B0793079B45
+:1055600040F2344163652846FAF750FAC0B27F280A
+:10557000C4BFA0F5807398B284F8580040F224416B
+:105580002846FAF743FAC0F30720A4F85A0040F27D
+:1055900025412846FAF73AFA0D23C0B2A4F85C0078
+:1055A000039328460F3339460493CDF80490CDF881
+:1055B00008800596FFF78CFF069B2364079B6364B6
+:1055C00009B0BDE8F083C0462DE9F041B2F1FF3FDC
+:1055D0008AB0064688461746D0F8A85002D1FCF794
+:1055E000E3FB47B295F966355FFA88F4013394FB23
+:1055F000F3F407230393193305930123E4B20293D1
+:1056000001AD07AB0193304604F5A073294604931E
+:10561000FFF75EFF079BC034C3F307530793304681
+:1056200006AB294601930494FFF752FF0021079827
+:105630000DF126020DF12203F2F3BCF60021402009
+:1056400008AB09AAF2F3B6F6BDF92230BDF9201075
+:105650008B4209DABDF92400C91AF2F35DF7BDF8EF
+:105660002240ADF8240009E0BDF92600C1EB03019A
+:10567000F2F352F7BDF82040ADF82600BDF9260040
+:10568000BDF92410F2F352F723B2032B80B201DDEF
+:10569000231F01E0C4F104039AB212B208FA02F126
+:1056A00003B2052003FB0010911E01238B40013A39
+:1056B000C018104107FB00F0C0F3CF000AB0BDE8EE
+:1056C000F081C04670B5182386B0D0F8A840039387
+:1056D00000238022049340F276662033054605932A
+:1056E000314613460292FAF7C3F904F19C032846A7
+:1056F00001A90193FFF7ECFE40F271612846FAF729
+:1057000085F940F27361A4F89C022846FAF77EF905
+:1057100040F27461A4F89E022846FAF777F940F245
+:105720007561A4F8A2022846FAF770F940F279618F
+:10573000A4F8A0022846FAF769F93146A4F8A402B1
+:105740002846FAF763F940F2DA61A4F8A60228467F
+:10575000FAF75CF940F22551A4F8A8022846FAF7B6
+:1057600055F994F86735A4F8AA0284F8AC324FF4DE
+:105770008F612846FAF74AF94FF49A61A4F8AE020D
+:105780002846FAF743F940F22451A4F8B00228461B
+:10579000FAF73CF9B4F86835C0F3C030A4F8B43275
+:1057A00094F80734A4F8B20284F8B63294F80834B6
+:1057B00084F8B73206B070BD7FB500230293103372
+:1057C00004930DF1160300930123019369465433AA
+:1057D0000393FFF77DFEBDF8160007B000BDC0467D
+:1057E0002DE9F84FD0F8A860074696F846355BB922
+:1057F000FFF7E2FF40F3072340B21FFA80F81FFAD9
+:1058000083F9C346CA4607E0B6F84AA5B6F84C8500
+:10581000B6F84E95B6F850B5B7F8DA30384603F416
+:105820007043B3F5005F0CBFB6F86660B6F8686009
+:105830004FF0FF320121FCF72FFA36B20121324638
+:1058400084B23846FCF728FA0021241A4FF0FF32C0
+:105850003846FCF721FA0121324685B23846FCF77A
+:105860001BFAA4B2C4EB0A06B6B2C4EB08042D1AA4
+:10587000FF2238463346A4B240F65211FAF7F8F840
+:105880003846FF22234640F65311FAF7F1F838461E
+:10589000FF22334640F65611FAF7EAF8ADB2384621
+:1058A000FF22234640F65711FAF7E2F8C5EB090349
+:1058B0003846FF2240F648119BB2C5EB0B05FAF7BC
+:1058C000D7F8384640F64911FF22ABB2FAF7D0F8C4
+:1058D000BDE8F88F2DE9F04F93B00DF126080C4686
+:1058E000D0F8A8503B49064693464046222201AFD5
+:1058F000ECF342F3384638492222ECF33DF3BCB1D5
+:105900000022304640F60F11FAF78CF895F8E9338B
+:10591000324AA02B324B14BF0524032414BF104677
+:10592000184614BF4FF0100A4FF0110AB94616E09E
+:10593000012230464FF41161FAF774F895F8E93313
+:10594000284AA02B284B14BF0E240A2414BF10464B
+:10595000184614BF4FF0100A4FF0110AC14600223A
+:10596000114604E00B5A013224319B4506D0A24275
+:105970001FFA82F8F6D14FF6FF7416E00FFA88F29C
+:10598000242302FB03070024254607E035F809100D
+:10599000304637F81420FAF745F8023501340AF199
+:1059A00001039C42F2D11FFA88F43046FCF74EF90D
+:1059B00010B13046FFF714FF3046FCF767FD20B208
+:1059C000B0F1FF3F0CBF4FF0FF30002013B0BDE837
+:1059D000F08FC046BED8010004D5010088F0010058
+:1059E0003AEF0100A4F201003CF101002DE9F0437F
+:1059F0008BB006460F4691460DF106001D49222246
+:105A0000ECF3BAF2D6F8A83093F8E933A02B14BF20
+:105A10004FF010084FF0110817B93D463C4619E009
+:105A200000252C4609E00DF10603E15A3046F9F74E
+:105A3000EDFF013524F8090002344545F3D10BE0B0
+:105A40000DF10603E15A34F809203046F9F7EAFF70
+:105A5000013502344545F3D13046FCF7F7F810B173
+:105A60003046FFF7BDFE17B93046FCF70FFD0BB00F
+:105A7000BDE8F0839EDD010030B587B005AB009333
+:105A8000022301930023029350330C46039369468B
+:105A9000102315460493FFF71BFDBDF81430238037
+:105AA000BDF816302B8007B030BDC0467FB50DF174
+:105AB0001603009301230193013B02935733039391
+:105AC000694610230493FFF703FDBDF81600000A92
+:105AD00007B000BD07B540F25643009340F255426F
+:105AE0000133FAF7BFF80EBDF0B5B0F8DA30D0F8F0
+:105AF000A85003F47043B3F5005F0CBF95F8403332
+:105B000095F8413387B085F8423395F8423306461D
+:105B100085F84333B0F8DA3003F47043B3F5005F2F
+:105B200014D195F8492353B2002B02DD85F84823A0
+:105B300009E0C3691B6D13F4805F01D0342300E0DA
+:105B4000302385F8483395F85C3313E095F84A2301
+:105B500053B2002B02DD85F8482309E0C3691B6DB1
+:105B600013F0805F01D0342300E0302385F8483300
+:105B700095F85D335BB2002B4CDD0322022BA8BFEE
+:105B8000022303FB02F340F2DF413046DFB2F9F7B4
+:105B90003DFFC1B27F29C0F30720C4BFA1F58073C8
+:105BA00099B203B27F2BC8BFA0F580737AB2C8BF89
+:105BB00098B292B2C2EB0003C2EB0102DBB202F078
+:105BC000FF0242EA0322304640F2DF41F9F72AFFA2
+:105BD0000DF116030093022301930F3302930F2359
+:105BE00003933046082369460493FFF771FC9DF840
+:105BF0001630FAB29B1A8DF816309DF817303046E1
+:105C00009B1A69468DF81730FFF764FF30466C46E3
+:105C1000FDF700FA4FF0FF3385F89A3395F84D33CE
+:105C2000002285F8472385F89C23BBB185F84223E1
+:105C300085F84323304640F22341FF32B5F8503314
+:105C4000F9F716FF30464FF4AA61B5F86023F9F76B
+:105C5000E9FE304604490422F9F71EFF3046FCF7FE
+:105C600013F907B0F0BDC0462ADB01002DE9F04F63
+:105C7000C3690C464FF08051BBB00546D0F8A87000
+:105C8000164618690A463AF015DD0520F0F364F56A
+:105C900028464FF489614FF480420023F9F7E8FE6B
+:105CA0000122284640F20A511346F9F7E1FE0DF1B0
+:105CB000E703349301233593103336930F2337933F
+:105CC0002846082334A93893FFF702FC0CB131466B
+:105CD00012E0B5F8DA3003F47043B3F5005F40F03A
+:105CE0003E81EB6997F8BF641B6D13F4805F0CBFB6
+:105CF00008210621FF2E00D10E469DF8E720032340
+:105D000006FB13238DF8E6300DF1E60334932846A5
+:105D1000102334A93793FFF7DDFE7300FE229BB2F8
+:105D2000284640F20A51F9F7A3FE97F8C044FF2C29
+:105D300000F0EA80002C00F0C980102C28BF10244D
+:105D4000C4F12403D9B272B24BB29A4201DDCEB291
+:105D500002E0002E08BF012670B2A042019002DCD2
+:105D60005FFA86F902E0631C5FFA83F904F1010B24
+:105D7000C9EB0B035FFA83F80D2336931333389383
+:105D80004FFA89F35B004FFA88F2049309AB03EBF7
+:105D9000C203570003937B1CDBB2079363000133FC
+:105DA00005934FEA4B03029206934FF0000A0198C5
+:105DB000049AA042CABF73B2CDF8DCB03793379BC8
+:105DC00034A953445B003793039B284635923493A0
+:105DD000FFF77EFB07990AE03AA800EB810353F82E
+:105DE000C42C42F0800243F8C42C8B1CD9B2059A13
+:105DF0009142F1DD002111E03AAB03EB810203EBAC
+:105E0000870353F8C43C3AA842F8C43C00EB87032C
+:105E100053F8C03C42F8C03C8B1CD9B2B942EBDB12
+:105E2000069A09AB349328464FEA4A0334A90AF18B
+:105E3000250A35923793FFF74DFEBAF14A0FB6D1D6
+:105E4000019B4FFA88F2A342C4BF73B237934FFA53
+:105E500089F335930DF1AE0303EB4203D8BFCDF8C0
+:105E6000DCB034931023389328460E2334A936939C
+:105E7000FFF72EFB0CE03AAE06EB480333F83A2C62
+:105E800042F4006223F83A2C08F101035FFA83F828
+:105E9000A045F0D9002109E0029E3AA800EB430298
+:105EA00000EB460333F83A3C22F83A3C0298CBB276
+:105EB00001318342F0DB0DF1AE0334932846002319
+:105EC00034A9CDF8D4B03793FFF704FE012213466E
+:105ED000284640F20E51F9F7CBFD4FF47E426302A3
+:105EE0001340284640F20E51F9F7C2FD284640F211
+:105EF0000F517F222346F9F7BBFD284640F20F5190
+:105F00004FF47E52E3011BE0284640F20E5101227D
+:105F10000023F9F7ADFD284640F20E514FF47E42C2
+:105F20000023F9F7A5FD284640F20F517F220023F8
+:105F3000F9F79EFD284640F20F514FF47E520023A0
+:105F4000F9F796FDEB694FF08051186900223AF09D
+:105F5000B1DB2846FDF75EF83BB0BDE8F08F214687
+:105F6000CAE6C0462DE9F041D0F8A8600746D6F849
+:105F70007C45002505E021463846FFF7ABFD01359D
+:105F80001434D6F878359D42F5D3BDE8F081C0468B
+:105F9000F0B5C369D0F8A85087B00746802198684B
+:105FA000F0F396F6044600286DD0B5F81C340026B0
+:105FB00003F4807C03F4007E30464FF0000316F0BB
+:105FC000100206F00101035316D0BEF1000F03D0FA
+:105FD000D5F81C34C3F3802116F0080F02D095F8D1
+:105FE0001A3408E0D5F8183416F0200F14BFC3F3A4
+:105FF000072303F0FF030353BCF1000F00D062BB83
+:1060000016F0040F09D016F0020F025B02D0D5F88B
+:106010000C340EE0D5F80C3418E016F0200F06F022
+:1060200002030CD0025B13B1D5F8103401E0D5F8AF
+:10603000143409B11B0E0EE0C3F307430BE0025BFF
+:1060400013B1D5F8103401E0D5F8143411B1C3F30D
+:10605000072300E0DBB21343035301360230402E26
+:10606000ABD10F230393002304933846103301A9C7
+:10607000059302960194FFF72DFDFB692146986870
+:106080008022F0F335F607B0F0BDC0462DE9F041AF
+:10609000002486B00594D0F8A8800646FBF784FE5D
+:1060A00007230293193304930746012325460193DE
+:1060B00016E00BB90C4603E011F0010F0FD14C08AC
+:1060C00030467AB2FFF780FA06AB43F8040D00932E
+:1060D000304604F5107369460393FFF7FBFC013566
+:1060E000802DE9B298F96635E3D17BB101230193A4
+:1060F000402405AB0093304604F5107369460393C2
+:10610000FFF7E8FC631CDCB2802CF2D106B0BDE8DE
+:10611000F081C0462DE9F04FB0F8DA3089B003F4D1
+:106120007043B3F5005F07468B46D0F8A85002D104
+:10613000B5F8C42304E0B3F5805F08D1B5F8C623F1
+:1061400013B2B3F1FF3F02D01FFA82FA01E04FF021
+:10615000700A072304931933069301234FF00009B3
+:10616000039307AB0293C846CDF80490019B18F047
+:10617000010F0BEB0306F378009303D095F9663516
+:10618000002B59D1B7F8DA3003F47043B3F5005F50
+:1061900003D0019B13F80B9012E0B5F8402413B222
+:1061A000B3F1FF3F18BF1FFA82F9B5F83E2408BFCC
+:1061B0004FF00F0913B2B3F1FF3F1CBF92B2009230
+:1061C000B37872781B0443EA022343EA0A6343EA82
+:1061D0000903079395F9663502AC0133B8FBF3F375
+:1061E000C033384621460593FFF774FC07AB029392
+:1061F00095F9663538460133B8FBF3F303F5A07320
+:1062000021460593FFF764F93279009B120542EAB3
+:106210000372079B384623F07F4323F470031A432D
+:10622000079295F9663521460133B8FBF3F303F580
+:10623000A0730593FFF74EFC019B08F1010805339D
+:10624000B8F1800F019391D195F96635002B36D0C6
+:106250005E4608F1800896F8423196F841211B0409
+:1062600043EA022302AC43EA0A6343EA09033846DD
+:10627000214608F180050793CDF81480FFF72AFC2A
+:1062800007AB3846214602930595FFF721F996F8AA
+:106290004421009B120542EA0372079B384623F013
+:1062A0007F4323F470031A43214608F10108079243
+:1062B00005950536FFF70EFCB8F5A07FCBD109B0E8
+:1062C000BDE8F08F10B5B0F8DA30D0F8A82003F4AC
+:1062D0007043B3F5005F03D1D2F87415FFF71AFFCE
+:1062E00010BDC0462DE9F043054687B0D0F8A89010
+:1062F000002940D0072399F8C272029319330493FE
+:10630000012301934FF0000805AB00932AE007F149
+:10631000C003284669460393FFF7DAF806F1C00385
+:10632000284669460393FFF7D5FB07F5A073284677
+:1063300069460393FFF7CCF806F5A0732846694633
+:106340000393FFF7C7FB07F51073284669460393CD
+:10635000FFF7BEF806F51073284669466C460393AE
+:10636000FFF7B8FB99F8C2325FFA88F6B34208F13A
+:106370000108CCD20CE0B0F8DA3003F47043B3F586
+:10638000005F02D10449FFF7C5FE2846FFF77EFEF5
+:1063900007B0BDE8F083C046589502002DE9F041F2
+:1063A000D0F8A84086B094F907144FF0FF3289B2B4
+:1063B0000646FFF709F994F967350546022B01D027
+:1063C000002007E094F90814304689B24FF0FF32FC
+:1063D000FFF7FAF807230293193304930123C0EB64
+:1063E00005070193304605ABB4F868154FF0FF324E
+:1063F0000093FFF7E9F84FF000084FF00003C019D1
+:10640000A4F86A3548BFA4F86A0521E094F8662527
+:1064100012B111F0010F19D1B4F86835B4F96A5509
+:106420008B4253B238BFED1B013391FBF3F3DBB268
+:1064300003F5107330464FF0FF320393FFF7C4F8B3
+:10644000401B059069463046FFF744FB08F1010800
+:10645000B8F1800F5FFA88F1D8D194F966357BB135
+:106460000123019305AB0093402404F510733046DB
+:1064700069460393FFF72EFB631CDCB2802CF4D13A
+:1064800006B0BDE8F081C04630B5182387B0D0F81B
+:10649000A840039308330593603302930023054615
+:1064A000049301A904F19C030193FFF713FB284611
+:1064B000B4F89C2240F27161F9F7B4FA2846B4F8B6
+:1064C0009E2240F27361F9F7ADFA2846B4F8A22291
+:1064D00040F27461F9F7A6FA2846B4F8A02240F217
+:1064E0007561F9F79FFA2846B4F8A42240F2796161
+:1064F000F9F798FA2846B4F8A62240F27661F9F73F
+:1065000091FA2846B4F8A82240F2DA61F9F78AFA3B
+:106510002846B4F8AA2240F22551F9F783FA284612
+:10652000B4F8AE224FF48F61F9F77CFA2846B4F83C
+:10653000B0224FF49A61F9F775FAB4F8B2324FF419
+:106540000042DB032846134040F22451F9F790FA49
+:1065500094F8AC32284684F86735B4F8B432A4F81D
+:10656000683594F8B63284F8073494F8B73284F872
+:106570000834FFF713FF07B030BDC0462DE9F04FD8
+:106580008DB0039202930BAB0646D0F8A8708B46F1
+:1065900000930DF12F010DF12D030DF12E02FCF7EB
+:1065A0005DF930460DF12A010AAAFFF765FA304677
+:1065B000FFF702F9072306931933089309AB0493F5
+:1065C0004FF000080123059381464FF450735D4658
+:1065D000C246079338E097F8662522B10AEB0B0311
+:1065E00013F0010F2DD153B2013304ACB5FBF3F31B
+:1065F00003F5A073304621460793FEF769FF099B18
+:10660000BDF828201B0D92051B05920D1A43BDF8FD
+:106610002A3030469B059B0D42EA83282146CDF85F
+:106620002480FFF757FACDF8249097F96635304665
+:106630000133B5FBF3F303F5E07321460793FFF74E
+:1066400049FA01350AF1010A039A9542C3D997F92B
+:106650006635C3B17F2A16D14FF4C07504AC3046FD
+:1066600021460795CDF82480FFF734FA05F1800321
+:10667000304621460135CDF824900793FFF72AFADA
+:10668000B5F5E07FEAD1029A07EB4203BDF82A2074
+:10669000A3F86C20BDF82820A3F87890A3F8722006
+:1066A0009DF82F3087F87E309DF82E3087F87F30A8
+:1066B0009DF82D3087F880309DF82C3087F8813098
+:1066C0000DB0BDE8F08FC0462DE9F04F8DB00393BB
+:1066D000C369D0F8A86005460C4698684FF48061FD
+:1066E0009346F0F3F5F20746002800F08A80C5F8DB
+:1066F000EC4F28460121FDF76BFA96F82C3043B198
+:10670000284641490622F9F7C7F928460021FEF735
+:10671000D7FDA4B101203D4984EAE472A2EBE47202
+:1067200000FB01F1B1FBF2F39EB202FB06F2431C47
+:106730008A4298B2EFD1B6F5807F01D95AE002269D
+:10674000242304FB03F349F6404293FBF2F30024B5
+:106750001B04642293FBF2FAA146A0462EE04846B1
+:106760000AA9F9F739FD0B9B03FB0BF3002B04DBA4
+:10677000DB130133C3F3490206E05B42DB13013351
+:106780005B105B429A05920D0A9B03FB0BF3002BF7
+:1067900004DBDB130133C3F3490306E05B42DB1385
+:1067A00001335B105B429B059B0D43EA822347F854
+:1067B0002830631CD1449CB208F10108B442CED108
+:1067C000062228461249F9F767F915230793002492
+:1067D0000B33284605A90993059706960894FFF7F9
+:1067E00079F9039B2846009331464FF6FF72234602
+:1067F000FDF774F8EB69394698684FF48062F0F35E
+:1068000077F20DB0BDE8F08FE2DA0100005A6202C3
+:1068100000DE010030B587B005AB00930123019382
+:10682000173302930833002204934FF400230546E4
+:1068300003920593144628466946FFF74BF9039BDC
+:1068400001330393631CDCB2802CF4D107B030BD5C
+:10685000F0B5D0F8A83087B093F89A250746002AFB
+:106860002DD1324B324D1E68144605E0294638467C
+:10687000FFF730F901341435B442F7D12D4A002422
+:106880005368384601931023029308230493136836
+:10689000694600930394FFF71DF9FB691B6B082BF6
+:1068A0000DD1254A38465368694601931223029355
+:1068B0000E330493136803940093FFF70BF910232E
+:1068C00004930DF1160300934FF07203082601257F
+:1068D000ADF81630384600236946039302960195B9
+:1068E000FFF7F8F84FF0820338466946ADF81630E6
+:1068F0000395FFF7EFF84FF0060369463846ADF809
+:1069000016300396FFF7E6F83846FFF7DBFC38460B
+:10691000FFF728FB3846FFF73BFB3846FFF7B6FB8F
+:1069200038466C46FFF776FF07B0F0BD1CE001006B
+:10693000F8E401003CEC010018EC010070B5B0F87F
+:10694000DA30054603F47043B3F5005FD0F8A820B1
+:106950000CD192F9F133B3F1FF3F37D1B2F9F833EB
+:10696000B3F1FF3F32D1B2F92C352CE0B3F5805FA3
+:1069700035D192F95B35B3F1FF3F27D192F9F3336B
+:10698000B3F1FF3F22D192F95C35B3F1FF3F1DD146
+:10699000B2F90034B3F1FF3F18D1B2F93035B3F199
+:1069A000FF3F13D1B2F90234B3F1FF3F0ED1B2F978
+:1069B0003435B3F1FF3F09D1B2F90434B3F1FF3FED
+:1069C00004D1B2F93835B3F1FF3F08D0012482F881
+:1069D0006645102228464FF49A61134607E00024CA
+:1069E00082F8664528464FF49A6110222346F9F74B
+:1069F0003FF84FF48F61032223462846F9F738F811
+:106A00002846FFF725FF2846FBF7E4FF2846FCF75A
+:106A1000E3FE2846FFF768F870BDC04610B50023B6
+:106A200088B00593103307930DF1060303930123F8
+:106A30000446ADF80610049303A954330693FFF7F8
+:106A400049F82046FBF702F910B12046FEF7C8FED0
+:106A500008B010BD2DE9F041D0F8A870064600241A
+:106A600019E0B6F8DA3003F47043B3F5805F07D16C
+:106A7000A218137923B1890492783046890C07E073
+:106A80006B4BE21853792BB18904D2783046890CCC
+:106A9000F8F74AFF0634664A4FF6FF73A15A994247
+:106AA000DFD1304673210022F8F73EFF3046322115
+:106AB0006A22F8F739FF192230463321F8F734FFFC
+:106AC00097F8EC231AB130463321F8F72DFFC22195
+:106AD0006F223046F8F728FF902110223046F8F751
+:106AE00023FF102100223046F8F71EFF9B210722CA
+:106AF0003046F8F719FF1D2102223046F8F714FF3F
+:106B00001E2106223046F8F70FFF304640F2EA41D8
+:106B100044F28862F8F786FFB6F8DA3003F470437F
+:106B2000B3F5005F0DD197F8E933B6F8CE1FA02B6F
+:106B300014BF022204220BB2B3F1FF3F0DD0CAB240
+:106B40000BE0B3F5805F07D1B6F8D02F13B2B3F1E5
+:106B5000FF3F01D0D2B200E0022253B21FFA83F805
+:106B600007224346304640F2EB41F8F781FFB6F882
+:106B7000DA3003F47043B3F5005F05D0B3F5805FFE
+:106B800004D197F83B350BB9002400E001242346DB
+:106B9000254624010F22A4B2304640F2F241F8F714
+:106BA00067FFF0222346304640F2F241F8F760FFDB
+:106BB0000F22304640F2F1412B46F8F759FFF02200
+:106BC0002346304640F2F141F8F752FF4FEA0823DE
+:106BD000304640F2F2414FF4E06203F47F43F8F7AD
+:106BE00047FFB6F8DA30304603F47043B3F5805F00
+:106BF0000CBF03F5377341F2DA23F45A40F2EB414C
+:106C0000630203F47E434FF40072F8F731FFB6F8E5
+:106C1000DA3003F47043B3F5805F0BD041F22433D4
+:106C2000F25A13B2B3F1FF3F04D0930203E0C0461F
+:106C30009CF40100A3024FF4806203F47C433046CD
+:106C400040F2EB41F8F714FF40F2EB413046D6F842
+:106C5000A840F8F7DBFEC0F3802084F8470540F237
+:106C6000EB413046D6F8A840F8F7D0FEC0F34020FC
+:106C700084F84805D6F8A820304692F8481592F8CE
+:106C800047355B1A18BF012382F84635FAF7F0FF43
+:106C9000830203F47C43304640F646114FF4806291
+:106CA000F8F7E6FE304643490622F8F7F5FE41F2D2
+:106CB0000D23F35C2BB10F22304677211346F8F7F2
+:106CC00079FE30460021FFF7A9FE97F89A352BB9D7
+:106CD0003046FEF73DF83046FDF71EFFF3697A2196
+:106CE000186939F007DD97F8EC23400084B22AB127
+:106CF00024B1F369A11C186939F01ADD97F8ED2366
+:106D00002AB124B1F3692146186939F011DD97F8E9
+:106D1000BB34DBB104221346304640F21D11F8F7B4
+:106D200049FE30469F213F2297F8BC34F8F742FED7
+:106D300030469E213F2297F8BD34F8F73BFE30469F
+:106D400077210F2297F8BE34F8F734FEB6F8DA3020
+:106D500003F47043B3F5805F29D197F9583533B305
+:106D6000B42124223046F8F7DFFDB7212422304633
+:106D7000F8F7DAFD0322B8213046F8F7D5FD97F988
+:106D80005825022A07D13046B821F8F7CDFD304604
+:106D9000B521012209E0032A09D13046B821013A80
+:106DA000F8F7C2FD3046B5210022F8F7BDFDBDE879
+:106DB000F081C04644D8010010B5FFF74BFE10BD6E
+:106DC00070B50026D0F8A850C0F8EC6F95F82C30BC
+:106DD00004463BB12A490622F8F75EFE204601210F
+:106DE000FEF76EFA204640F24461F8F70FFE10F00D
+:106DF000010309D020463146FCF742FD022220461D
+:106E000040F23F61134607E010F0020F06D0204623
+:106E100040F253414FF40042F8F72AFE2046194948
+:106E20000922F8F739FE20460021FCF7D1FE204662
+:106E3000FAF71EFF30B12046FEF7BEFC01462046A1
+:106E4000FFF7ECFD95F8473520469B0203F47C43A1
+:106E500040F2EB414FF48062F8F70AFEB5F84E3588
+:106E60006BB1204640F64811FF22F8F701FE20469C
+:106E700040F64911FF22B5F85035F8F7F9FD70BD1D
+:106E800002D801008AD9010070B50C4688B00546C9
+:106E9000F9F72AF944B92846FFF792FF2846214618
+:106EA000FCF796FE204622E0284621460122FAF70A
+:106EB0008DF8064608B1012019E028460121FCF7AB
+:106EC00087FE0C4B4024039315230593284610237B
+:106ED00003A9079304940696FEF7FCFD2846214675
+:106EE0004FF6FF7233460096FCF7F8FC304608B0C8
+:106EF00070BDC04694EE010070B5002386B00293C9
+:106F00001033049305AB009302230446ADF814102C
+:106F100001930D464E3369461646ADF8162003938D
+:106F2000FEF7D8FD2046FAF7A3FE78B3204640F6D8
+:106F3000461140F2FF322B46F8F79AFD204640F604
+:106F4000471140F2FF323346F8F792FD20464FF4E6
+:106F5000156140F2FF322B46F8F78AFD204640F6D5
+:106F6000511140F2FF323346F8F782FD204640F6D9
+:106F7000541140F2FF322B46F8F77AFD204640F6D6
+:106F8000551140F2FF323346F8F772FD06B070BD7E
+:106F90002DE9F04F8DB004910392D0F8A860074618
+:106FA00006EB4303B3F872B0B3F86C10B3F8789003
+:106FB0005A460591FFF7A0FF38464946FFF72EFDD8
+:106FC0000723089319330A934FF000080123049D07
+:106FD0000793C2460BAB069337E096F866252AB1B5
+:106FE00004990AEB010313F0010F2BD153B20133C3
+:106FF00006ACB5FBF3F303F5A073384621460993BD
+:10700000FEF766FA0B9B05994FEA8B521B0D1B0589
+:10701000920D1A438B059B0D42EA83283846214680
+:10702000CDF82C80FEF756FD96F9663538460133CB
+:10703000B5FBF3F303F5E07321460993CDF82C90EB
+:10704000FEF748FD01350AF1010A039A9542C4D9B9
+:1070500096F96635C3B17F2A16D14FF4C07506ACD8
+:10706000384621460995CDF82C80FEF733FD05F111
+:107070008003384621460135CDF82C900993FEF760
+:1070800029FDB5F5E07FEAD196F8810096F87E10EB
+:1070900096F87F2096F8803000903846FBF7E0FCA9
+:1070A0000DB0BDE8F08FC04670B500210446D0F8A1
+:1070B000A8500B467F22FFF76BFF2046FFF7E4F94D
+:1070C0002046B5F8B812B5F8BA22FBF7C9F8204641
+:1070D00040F2D16104220023F8F7CAFC70BDC0461B
+:1070E00070B50446D0F8A8300D4699B193F8BC327B
+:1070F00033B3FFF7D9FF20460422002340F2D161C9
+:10710000F8F7B6FC8022204640F276611346F8F785
+:10711000AFFC15E00422134640F2D161F8F7A8FC59
+:107120008022204640F276612B46F8F7A1FC2046EB
+:107130002946FFF773FC204629462A46FFF7DCFE66
+:1071400070BDC04630B500238BB0089307930693FB
+:107150000733054603930A4609B9049102E04FF448
+:10716000307304932023059309AB01930123029309
+:107170003AB9284608A907AA06ABF9F719F9002475
+:1071800009E0B5F902310793B5F904310693B5F971
+:1071900006310893F3E70899069B2046079AFAF709
+:1071A0005BFC01A909902846FEF794FC049B01347E
+:1071B0000133802C0493EED10BB030BDF0B5284BD9
+:1071C0008BB005AC05460F460FCB84E80F0041F2AB
+:1071D0001403EB5CD5F8A8601BB196F8E034002BE3
+:1071E0003BD028461F490822F8F756FC0723029394
+:1071F0001933049304230193009403F54F7301247E
+:107200000393284686F86A406946FEF763FC00232C
+:10721000099309AB019400934FF4517428466946D1
+:107220000394FEF757FC013440F25E339C42F5D1E3
+:1072300028460D491222F8F72FFC7B009BB2284606
+:1072400040F2A94140F2FF12F8F712FC284640F242
+:10725000A36110220023F8F70BFC0BB0F0BDC04671
+:1072600080DB0100B8D50100C8D5010030B5D0F8E9
+:10727000A8509BB004460022A31893F9103501A929
+:107280005B4241F822300132142AF5D195F86A3078
+:1072900063B90733179319331993159103F548739D
+:1072A000204615A916921893FEF714FCD4F8A810DE
+:1072B00094F82936D1F8442420469342A8BF1346B7
+:1072C000D1F8482440F2A7419342B8BF13469BB27D
+:1072D000FF22F8F7CDFB95F8E833F3B1B5F8E623D4
+:1072E00094F8293620469B1A1B024FF47F42134024
+:1072F00040F2D141F8F7BCFB94F8292695F82535E2
+:107300002046C3EB420395F8E62340F2D1419B1A95
+:107310005BB2FF229BB2F8F7ABFB2046FAF7AAFB61
+:107320001BB030BD70B5C6B001ACD0F8A850064651
+:10733000002120464FF48072EAF382F6072343933C
+:1073400019334593419495F86A3043B91E334293FB
+:1073500030464FF4507341A94493FEF7BBFB4023E2
+:1073600042933046DB1841A94493FEF7B3FB46B085
+:1073700070BDC0462DE9F04106460C46FAF72EFFD7
+:10738000214605463046FAF753FC29460446304666
+:10739000FAF74EFC4022B4F5404F0CBF13460023D1
+:1073A000054640F2DA613046D6F8A870F8F760FB7F
+:1073B0001022B4F5404F14BF13460023304640F26C
+:1073C000A361F8F755FB0122B4F5404F14BF002329
+:1073D0000123304640F26E41F8F74AFBA54200F027
+:1073E0009580B5F5404F02D13046FFF79BFFB4F5CD
+:1073F000404F3CD13046FFF739FFD6F8A8203B8EEE
+:1074000092F966255B00013293FBF2F3304640F2BD
+:10741000A44140F2FF129BB2F8F72AFB7B8E304664
+:107420001B0240F2A5414FF4E06203F47F43F8F7FA
+:107430001FFB04223046002340F21F11F8F7BAFA6E
+:10744000F369E021186939F055D90021F8853046F3
+:10745000FAF7A4FF4FF0FF3387F83430304640F29C
+:10746000A9414FF400420133F8F702FB03E0304634
+:107470000121FAF793FF304640F2A4414FF46042F5
+:107480002346F8F7F5FAB4F5404F0FD13046FAF736
+:10749000EFFB40F2A44100280CBF4FF4005300233F
+:1074A0004FF400523046F8F7E3FA15E04EF20103CC
+:1074B0009C4211D13046FAF71BFB01463046FFF7DC
+:1074C0007DFE304640F2A941F8F7A0FA0223C0B28F
+:1074D00090FBF3F087F8C10297F96735012B0DDDBA
+:1074E00040F2A4413046F8F791FAC0F3803340F2FD
+:1074F000255130464FF40042DB0305E0304640F2B0
+:1075000025514FF400420023F8F7B2FABDE8F081AC
+:1075100070B50023D0F8A82080F82B3692F8E0341C
+:1075200005468BB190F92A16D2F84834994203DB0C
+:10753000D2F81035994207DA4EF20101FFF71AFF2F
+:10754000012385F82B3612E041F21403EB5C73B192
+:107550002846FAF743FE002104462846FFF70AFFB3
+:107560002846FFF783FE28462146FFF703FF70BD3C
+:1075700030B5072389B0D0F8A84003931933059399
+:1075800006AB0193012302930546013B049308E0F7
+:10759000284601A9FEF79EFA049B01330493069B3B
+:1075A00001330693069B7F2BF2D94FF4307304937B
+:1075B000A3F5307308E0284601A9FEF78BFA049B77
+:1075C00001330493069B01330693069B7F2BF2D96C
+:1075D000092228465B49F8F75FFA01212846FBF7A4
+:1075E000A5FB242228465849F8F756FA2846FAF708
+:1075F00061FDC0F34F00E62801DDFF2305E02846CA
+:10760000FAF758FD4008193083B2FF2240F2A54135
+:107610002846F8F72DFA2846FFF784FEB4F8E6234B
+:10762000B4F8E433284603EB42039B019BB24FF4CA
+:107630009A6147F6C072F8F71BFA092228464349B7
+:10764000F8F72AFAB5F8DA30282103F470431E223D
+:10765000B3F5005F14BF18231C232846F8F7AAF9D6
+:1076600001223A2113462846F8F7A4F908221346C6
+:1076700028464FF48D71F8F79DF925210C222846F4
+:10768000F8F752F9B5F8DA3003F47043B3F5005F58
+:1076900004D1022228463A21134603E028463A2123
+:1076A00002220023F8F786F908221346284605210E
+:1076B000F8F780F9284606222549F8F7EDF947F250
+:1076C0000802284640F2D7414FF40053F8F7D0F9AA
+:1076D0002846FAF7EFFC102305930DF11E030193E2
+:1076E00001230824ADF81E0002932846053301A9A2
+:1076F00004930394FEF7EEF928460F221549F8F794
+:10770000CBF928463521FF220023F8F753F9284604
+:10771000362103220023F8F74DF928462246234656
+:107720004FF48D71F8F746F94FF48062284640F225
+:10773000A4411346F8F79CF92846FBF78FFA09B0E5
+:1077400030BDC04618DA01002ADA0100ECD501008C
+:1077500032DB01003EDB01007FB5090206AB23F8F6
+:10776000021D009301230193013B029357330393BE
+:10777000694610230493FEF7ADF907B000BDC0467B
+:107780002DE9F041D0F8A8308AB083F8341083F89E
+:10779000C11293F9663506460F466BB111F001032D
+:1077A00004D04FF48F610C22082302E04FF48F6164
+:1077B0000C22F8F75DF97F080723039301AC07F566
+:1077C000A07320254FF001080493304609AB2146F1
+:1077D00001930595CDF80880FDF77AFE07F1C00307
+:1077E000049330460DEB0503214601930595FDF703
+:1077F0006FFE089B304603F0FF02ADF81820C3F37C
+:107800000722C3F30743ADF81C30099B06A9C3F355
+:107810000273ADF81A20ADF81E30FAF7F7FD09999A
+:107820003046C1F30751FFF797FF30464146FAF75C
+:10783000B5FD0AB0BDE8F0812DE9F04F91B0BDF87B
+:10784000783002AC0193BDF87C3007460093534B6F
+:107850009DF880601D460FCD0FC495E80F009DF880
+:10786000748084E80F0038464D490422BDF87090BA
+:10787000BDF884A0BDF888B0F8F70EF9384640F29C
+:10788000A36102227300F8F7F3F8B8F1000F18D0E3
+:1078900010AB4FF4002243F8042D0A9301230B93FD
+:1078A00017330C9308330E9300230D931C46384670
+:1078B0000AA9FEF70FF90D9B01340133402C0D93FB
+:1078C000F5D1032409FB04F43846FAF7EDFE013440
+:1078D000384640F2A1615246F8F7A4F8A4B23846FF
+:1078E00040F2A2615A46F8F79DF82246384640F227
+:1078F0007E61F8F797F838462A490422F8F7CCF861
+:107900000134142304FB03F4013CA2B238464FF4C3
+:10791000C861F8F787F80022384640F27761F8F737
+:1079200081F808230B930D330C930B3300240E9333
+:10793000384602AB0AA90A930D94FEF7CBF83846F5
+:1079400040F27B61019AF8F76DF8384640F27C61AD
+:10795000009AF8F767F82246384640F27D61F8F75A
+:1079600061F821463846FFF7F7FE38460E490422F3
+:10797000F8F792F80D4C03E00A20EEF3EDF60A3C1E
+:10798000384640F27661F8F741F810F0010F01D067
+:10799000092CF1D111B0BDE8F08FC04694D601009A
+:1079A000B4D701006ED601006CD8010049420F0027
+:1079B0002DE9F043D0F8A8908BB0064688460525FF
+:1079C00003270F2DA8BF0F250024ABB2019330462B
+:1079D0000121224623460094029403940494FAF76A
+:1079E0005DFDDB2302934FF4AF6304934FF48243B6
+:1079F0000593A3F581430122079330462146234690
+:107A000000940194039206940894FFF715FFB8F1CF
+:107A1000000F1DD140F2BA613046F7F7F7FF40F290
+:107A2000BB6104B23046F7F7F1FFA401A4B244F3FE
+:107A3000891404FB04F440F3090000FB0043B3F590
+:107A4000005F01DAED1B03E0B3F5804F04DBED19B5
+:107A500017B17B1EDFB2B4E7092D01DD092501E076
+:107A600025EAE5752846C9F838500BB0BDE8F08323
+:107A70002DE9F043D0F8A8608DB096F96635074639
+:107A80008846CCB2D3B1634B01EA0303002B05DA7D
+:107A9000013B6FEAC3736FEAD3730133012B04D147
+:107AA0004FF48F610C22073303E04FF48F610C22F7
+:107AB0000023F7F7DDFF022398FBF3F8072386F88E
+:107AC000344086F8C14201AD039308F5A073202429
+:107AD0004FF00109049338460BAB294601930594F6
+:107AE000CDF80890FDF7F4FC08F1C0030493384684
+:107AF0000AAB294601930594FDF7EAFC0A9B384638
+:107B000003F0FF02ADF81820C3F30722C3F30743C5
+:107B1000ADF81C300B9B06A9C3F30273ADF81E3001
+:107B2000ADF81A20FAF772FC9DF82B10384601F0D8
+:107B30007F01FAF71FFC0B993846C1F30751FFF795
+:107B40000BFE38464946FAF729FC0B9A3846C2F331
+:107B500089219205920DFFF7CFF908F5E0730493A0
+:107B6000384609AB29460193FDF7B2FC3846BDF80B
+:107B70002410FEF753FF08F51073049338460DEBFD
+:107B8000040329460193FDF7A3FC089B3846DB005C
+:107B90009BB240F2A66141F6FF72F7F769FF96F9D2
+:107BA00067354B4532DD40F225513846F7F72EFF59
+:107BB0004FF48072C3B29845D4BF002401243846E4
+:107BC0009845CCBF1346002340F22551F7F750FFEC
+:107BD0006302384640F225514FF4007203F47E43AD
+:107BE000F7F746FFA302384640F225514FF4806272
+:107BF00003F47C43E402F7F73BFF384640F225519B
+:107C00004FF4006204F47843F7F732FF0DB0BDE89B
+:107C1000F083C0460100008070B504460D46002187
+:107C2000FFF7A8FB20462946FFF722FF70BDC0469C
+:107C30002DE9F04F89B0054600920191FAF7CEFA8E
+:107C400040F23B4103902846F7F7E0FE04A902907A
+:107C50002846FAF711FA00244FF47A700134EEF353
+:107C60007BF5022CF8D105F597531A6892F820306D
+:107C70001F1E18BF012792F821300BB17B1C9FB249
+:107C800092F822300BB17B1C9FB292F823300BB1DB
+:107C90007B1C9FB24FF00009C8464FF0140ABCE0AD
+:107CA000D5F8B030D3F8203183F0010313F001048C
+:107CB00003D1EB69186938F06DDD2846F8F760FBF1
+:107CC00005F597531B68284603EB4803998CFFF78B
+:107CD000A3FF28465146FFF73FFD1CB9EB69186921
+:107CE00038F044DD4FF40042284640F2A4411346E8
+:107CF000F7F7BEFE002441F288300134EEF32CF594
+:107D0000032CF8D1284640F2A641F7F77FFEC005C4
+:107D1000C00DFF2886BFA0F580731FFA83FB00F516
+:107D2000807B00263446284640F23E61F7F76EFE1F
+:107D3000631CC005C00D9CB23618102CF3D1C6F3DD
+:107D40000F13FF2B8CBFA3F5807303F58073504690
+:107D500000210DF11E029EB20DF11A03F0F32AF379
+:107D600005F597531B680021434493F8200007AAA8
+:107D700006ABF0F31FF3BDF91A30BDF918108B42B2
+:107D800009DABDF91C00C91AF0F3C6F3BDF81A40B0
+:107D9000ADF81C0009E0BDF91E00C1EB0301F0F3D2
+:107DA000BBF3BDF81840ADF81E00BDF91C10BDF9BD
+:107DB0001E00F0F3BBF323B2032B81B201DD231FBE
+:107DC00001E0C4F1040398B200B2431E01229A40BC
+:107DD00009B2052301FB032353FA00F000F10C0361
+:107DE000182B16D805F597531B68019A03EB8803E7
+:107DF0001B69C31802F809304FEA9B03C3F17F03E4
+:107E0000009A03EB960302F8093009F101031FFA07
+:107E100083F908F101031FFA83F8B845FFF440AF76
+:107E20000AF101035FFA83FABAF1640F02D84FF046
+:107E30000008F2E7029B2846C3F38011FAF7AEFA76
+:107E4000284604A9FAF7E2FA28460399FFF792FABE
+:107E5000484609B0BDE8F08F2DE9F04F1E46C369D2
+:107E6000A9B0D0F8A88004460F4698684FF48371F3
+:107E70001546EEF32DF70790002800F0EF81022E53
+:107E80000FD016E00E4694F8DA3011F80629013DBD
+:107E90009A420BD17188B2882046FAF7E1F901269F
+:107EA000CCE1062305FB03F3063BF918002DE9D1CD
+:107EB000C3E1012E40F0C1812046FAF78FF900217D
+:107EC00008902046FFF756FA0025934B2046E95AC2
+:107ED000F7F712FD1AABE8520235182DF5D140F232
+:107EE00031612046F7F792FD15220B9040F2316187
+:107EF0002046F7F7ADFD40F24C412046F7F786FDEE
+:107F000040F24D410C902046F7F780FD4FF496610A
+:107F10000D902046F7F77AFD40F2B1410E902046D1
+:107F2000F7F774FD40F2F9410F902046F7F76EFD28
+:107F300040F2FA4110902046F7F768FD40F63811FC
+:107F400011902046F7F762FD40F639111290204655
+:107F5000F7F75CFD40F23B4114902046F7F756FDE1
+:107F600040F23C4115902046F7F750FD40F2DA61AF
+:107F700016902046F7F74AFD40F2DB611890204644
+:107F8000F7F744FD40F2B74119902046F7F73EFD60
+:107F900040F23B4113902046F7F738FDC0F38010C4
+:107FA0000A9008B9099007E0204626A9FAF764F874
+:107FB00098F8C182CDF8248020463299FFF72CFE34
+:107FC000062220465549F7F767FDB4F8DA3003F486
+:107FD0007043B3F5005F04D1204698210322F7F7E0
+:107FE000A3FC20464E491922F7F756FD20464D497D
+:107FF0001822F7F751FDB4F8DA304FF0030B03F411
+:108000007043B3F5005F14BF04230023179322E1EC
+:108010001FFA88F300931FFA89F3002601931FFAD1
+:108020008BF3324602932046179B31460396049603
+:10803000FAF734FA20460121FAF744F9334620468C
+:1080400039493C22FEF740FB20464FF48971324605
+:10805000F7F76AFC20AB00934FF4FA7A20464FF40E
+:10806000806120223346CDF804A0FAF7F9FF0546D7
+:1080700020B92E48F7F722F82F4636E0334620463F
+:1080800029497822FEF720FB20464FF489713246B9
+:10809000F7F74AFC23AB009320464FF4806120227F
+:1080A0003346CDF804A0FAF7DBFF18B92048F7F7FC
+:1080B00005F81AE0219A24982299B0EB420F0ED9C4
+:1080C00093009B1898420AD2259AB2EB410F06D929
+:1080D0008B005B189A422CBF0027012700E0002785
+:1080E000B8F1010801D3002F92D0B9F1010902D3F0
+:1080F000002F00F0AC80BBF1010B02D3002F00F089
+:10810000AA80204640F2D16104220023F7F7B0FC98
+:1081100087B93E4614E0C0468ED4010072D90100F2
+:1081200014D7010090DB010080841E0008D60100F6
+:1081300022D6010020464FF48061FDF729F806465B
+:108140002046FEF73DFE204640F231610B9AF7F7DC
+:1081500069FC204640F24C410C9AF7F763FC20463C
+:1081600040F24D410D9AF7F75DFC20464FF49661C1
+:108170000E9AF7F757FC204640F2B1410F9AF7F7F5
+:1081800051FC204640F2F941109AF7F74BFC20468B
+:1081900040F2FA41119AF7F745FC204640F63811B3
+:1081A000129AF7F73FFC204640F63911149AF7F778
+:1081B00039FC204640F23B41159AF7F733FC204644
+:1081C00040F23C41169AF7F72DFC204640F2DA6166
+:1081D000189AF7F727FC204640F2DB61199AF7F767
+:1081E00021FC204640F2B741139AF7F71BFC2046CA
+:1081F00040F24C4104220023F7F73AFC0025194BCA
+:108200002046E95A1AABEA5A0235F7F78DFB182DCA
+:10821000F5D10A9B23B120460999FFF7FDFC03E045
+:1082200020460A99FAF7BAF820460899FFF7A2F80B
+:1082300020460021FAF746F800E00026E369079996
+:1082400098684FF48372EEF353F5304606E000274A
+:108250004FF00608DCE64FF00409F8E729B0BDE866
+:10826000F08FC0468ED401002DE9F04FB3B00F93CC
+:108270009DF8F8409DF8F4300D940E939DF8004160
+:108280009DF8FC300B940C93012405461646D0F85B
+:10829000A89088469DF8F0B0BDF804718DF8C740ED
+:1082A0008DF8C640FDF702FC40F2D74112902846F7
+:1082B000F7F7ACFB40F2D74110902846F7F7A6FB42
+:1082C0003449119006222846F7F7E6FB2846324942
+:1082D0000F22F7F7E1FB284621461AAAFDF786FB95
+:1082E000284621460022FDF7F5FABBF1000F02D027
+:1082F0000023199318E028462146FBF769FCD5F8BE
+:10830000B030D3F8203183F0010313F00103199347
+:108310000AD1EB69B821186942F2107238F008DA14
+:10832000EB69186938F036DA28460121F9F7CAFFF7
+:1083300028460121FBF7A4FA28460121FAF730F973
+:1083400040F2EA412846F7F761FB40F2EB41179013
+:108350002846F7F75BFB40F2EB4118902846F7F709
+:1083600055FB00F0070340F2EB4128463822DB00C2
+:10837000F7F77EFB28462DA999F8C1A2F9F77CFEF4
+:1083800086B1337A53B12846717AFFF745FC96F8E7
+:1083900009A007E038D801006ED701002846314611
+:1083A000FAF734F840F29C412846F7F72FFB40F2E9
+:1083B000316113902846F7F729FB40F2D6611590FA
+:1083C0002846F7F723FB40F2DA6114902846F7F7C6
+:1083D0001DFB002116902846FAF72AFA28468849FC
+:1083E0000722F7F759FB2FAB23930123249306337E
+:1083F000259376B199F96625737A013293FBF2F3EE
+:1084000003F5107326932846202323A92793FDF70D
+:108410005FF82F9A2846D2002F9240F2716192B2F3
+:10842000F7F700FB284677490C22F7F735FB0024C5
+:10843000754B284633F81410F7F75EFA0DF1A203D6
+:10844000E0540134122CF3D1072228464FF48B71EB
+:10845000F7F76AFAB5F8DA3003F47043B3F5005F62
+:1084600005D1284640F22D110122F7F75DFA0722C7
+:1084700028464FF49671F7F757FAB5F8DA3003F457
+:108480007043B3F5005F14D128466A21C222F7F782
+:108490004BFA284698210C22F7F746FA284640F274
+:1084A0002F110322F7F740FA28469721F922F7F710
+:1084B0003BFA0B2107222846F7F736FA1022284606
+:1084C00040F21311F7F730FA1D2101222846F7F781
+:1084D0002BFA012228464FF48A71F7F725FAB5F8EE
+:1084E000DA3003F47043B3F5005F04D128462E213F
+:1084F0001022F7F719FA082228464FF49571F7F77A
+:1085000013FA092102222846F7F70EFA042213462D
+:10851000284640F21F11F7F74DFAFF2110220023E1
+:108520002846F7F747FA0721012200232846F7F7E4
+:1085300041FA0521082200232846F7F73BFA4FF4B9
+:1085400000421346284640F2DA61F7F791FA4146B5
+:108550000F9A53462846FFF72BFA002480B20121D8
+:1085600001902246284623460094029403940494E2
+:10857000F9F794FF0E9BA74208BF4FF48247009380
+:108580000D9B284601930C9B414602930B9B224670
+:1085900003934FF4AF630493A3F59F6307935B4684
+:1085A000059706940894FFF747F90DF1C60228468F
+:1085B0000DF1C701F9F79AFC9DF8C6203F2A53D860
+:1085C0009DF9C730A3424FDB3F2B4DDC52B29A429C
+:1085D0004ADCB8F1000F27D123AC1823214625939C
+:1085E000284630AB26922393FCF772FF9DF9C730E3
+:1085F00021462846309E2693FCF76AFF44460EE04B
+:108600007ED601008CD701005CDB010030AB284630
+:1086100023A9269430962393FDF75CFA01349DF943
+:10862000C62063B29A42F1DC182323AC259326338B
+:108630002693284630AB21462393FCF749FF3F237E
+:10864000284621462693FDF745FA01232846214670
+:108650002693FCF73DFF0023284621462693FDF78D
+:1086600039FA2846FDF72EF8284640F2EA41179AD3
+:10867000F7F7D8F9284640F2EB41189AF7F7D2F904
+:108680002846D72102220023F7F794F9082213463F
+:108690002846D721F7F78EF9002328464FF4947126
+:1086A0000822F7F787F928464FF48B710022F7F775
+:1086B0003BF9284640F29C41139AF7F7B3F9284654
+:1086C00040F23161159AF7F7ADF9284640F2D661CC
+:1086D000149AF7F7A7F9169C284644F0010292B2C3
+:1086E00040F2DA61F7F79EF928460121FAF7A0F87F
+:1086F000109C082204EA0203284640F2D741F7F70B
+:10870000B7F9119C4FF4E04204EA0203284640F214
+:10871000D741F7F7ADF92846FAF73EFD0024234B81
+:10872000284633F814100DF1A203E25C0134F7F788
+:10873000FBF8122CF3D14FF400620023284640F2DC
+:108740004C41F7F795F928460021FBF799F82846A0
+:108750000021F9F7B7FD284640F23B4101220023F2
+:10876000F7F786F900234FF40062284640F63811E7
+:10877000F7F77EF928460021FBF72AFA2846002160
+:108780001AAAFDF733F9284609490F22F7F784F9A9
+:10879000199B1BB9EB69186937F0E8DF2846129975
+:1087A000FEF7DAFF33B0BDE8F08FC0465CDB0100B6
+:1087B000A0DC01002DE9F04FD0F8A83091B093F87B
+:1087C000F49318230C930FAB0A9320230E930123E9
+:1087D00017460B9301FB01FB3E3305210022804627
+:1087E000B9F1FF0F08BF4FF001090D9307910992EE
+:1087F00006230024039347F6FF733A4601250593A9
+:108800004046234621460094019402940495FFF7C4
+:108810002BFD40460AA9FCF75BFE0F9A42F30B338F
+:1088200003FB03F342F30B0202FB02327B7A5A454D
+:10883000069303D307990894CEB206E0B9F1000F6E
+:108840004DD1079908954B42DEB273B206999DB29D
+:108850006B189CB24FF0000A06990AEB01030899C5
+:108860009BB221B15A4506D99B1B7B722DE0089B18
+:108870000BB95A4529D322B27F2A26DC0AEB05031D
+:10888000002A1FFA83FA20DB06237C72039301235C
+:108890000021049347F6FF733A46059340460B4682
+:1088A000009101910291FFF7DFFC40460AA9FCF715
+:1088B0000FFE0F9A42F30B3303FB03F342F30B0259
+:1088C00002FB023263199CB2C6E70799099A41F389
+:1088D00046030132DBB2032A0793099288D111B013
+:1088E000BDE8F08F2DE9F04F8DB0DDF858A01F46A0
+:1088F0000123834616468AF808304FF000094FF0EE
+:10890000640808EB09030021C3F34F05DB238AF851
+:10891000095001245246039358460B460091019199
+:10892000029105910494FFF79FFC182308932733C5
+:1089300009930BAB06935846202306A90A93079484
+:10894000FCF7C6FD0B9B43F30B3202FB02F243F331
+:108950000B0303FB03231A464FEAE273BB4202D820
+:1089600003D1B24201D9A94600E0A8460B484FF016
+:10897000FF31801941EB07018B4202D806D18242B8
+:1089800004D99F4206D801D1964203D8C9EB080307
+:10899000012BB6DC28460DB0BDE8F08F30F8FFFFA4
+:1089A000F7B50546D0F8A87090F8DA000E46F7F74C
+:1089B0003FFA40F6B41398420446B5F8DA2001D1E4
+:1089C0001E480AE0D3B2012B02D14FF4523004E02A
+:1089D0000302A3F5C420A0F5806000224FF47A7151
+:1089E000F9F71AF8A0FB002328460096FFF77AFF54
+:1089F000A0F128039BB21D2B1BD9272802D84FF4C6
+:108A000034300BE040F6B4139C4202D14FF4703086
+:108A100004E02302A3F5BE20A0F5007000224FF46D
+:108A20007A71F8F7F9FFA0FB002328460096FFF7BC
+:108A300059FF031F87F8C232FEBDC046008E0300F7
+:108A40002DE9F04390F8DA30D0F8A8608BB086F8C2
+:108A5000BC32D0F8B0300546D3F8203183F00103A2
+:108A600013F001090AD1C369B821186942F21072E2
+:108A700037F05EDEEB69186937F08CDE40F2A54115
+:108A80002846F6F7C3FF04462846F9F7A7FB00215E
+:108A900080462846FEF76EFC4FF440412846FEF71C
+:108AA00069FC2846FEF73EFCD5F8A8202846D2F8F7
+:108AB0004434D2F84824402BA8BF40239342B8BF87
+:108AC000134640F2A741FF229BB2F6F7D1FF0023E5
+:108AD000284640F2A5414FF4E062F6F7C9FF4FF493
+:108AE0007A7232212846FBF7ADF80121284696F824
+:108AF000C072FBF76DF82846F7F742FC4FF4E062CE
+:108B000004EA0203284640F2A541F6F7B1FF00212E
+:108B10002846FEF72FFC96F8C4420DF11E0E012CDC
+:108B200035D171462846FFF73BFF28462146FDF721
+:108B3000D9FBD5F8A8202846D2F84434D2F84824E6
+:108B40003E2BA8BF3E239342B8BF134640F2A74135
+:108B5000FF229BB2F6F78CFF0023284640F2A54186
+:108B60004FF4E062F6F784FF284632214FF47A7220
+:108B7000FBF768F896F8C032DBB996F8C23228469F
+:108B8000043386F8C2322146FDF7ACFB11E0002128
+:108B90000122DB238DF82620039304922846724697
+:108BA0000B468DF827700091019102910591FFF716
+:108BB0005BFB28464146FEF7DDFB284608490422B8
+:108BC000F6F76AFFB9F1000F03D1EB69186937F0C6
+:108BD000CDDD28460021FAF7FBFF0BB0BDE8F0839E
+:108BE00076D601002DE9F04F044695B0D0F8A86084
+:108BF00040F2E7300F46EDF3AFF507212046F6F7D8
+:108C00007BFEC0B20390FF212046F6F775FEC0B28E
+:108C1000049040F21F112046F6F76EFEC0B2059098
+:108C200005212046F6F768FE25215FFA80FB2046E5
+:108C3000F6F762FE4FF489715FFA80FA2046F6F784
+:108C40005BFE00250190864B2046E95AF6F7DEFED2
+:108C500007ABE85202351C2DF5D1D4F8B030D3F86B
+:108C6000203183F0010313F00103029303D1E36980
+:108C7000186937F08FDD40F2A4412046F6F73CFE3C
+:108C8000002181462046FEF775FB7F21204696F89D
+:108C9000C182FEF7C1FF0122072113462046F6F7E5
+:108CA00089FE1022FF2113462046F6F783FE042298
+:108CB0001346204640F21F11F6F77CFE362220466E
+:108CC0006849F6F7E9FE2046F9F7F4F9C0F34F00DA
+:108CD000E62801DDFF2305E02046F9F7EBF940081F
+:108CE000193083B2FF22204640F2A541F6F7C0FEBC
+:108CF00025210C222046F6F717FE082213460521EF
+:108D00002046F6F757FE092257492046F6F7C4FEDB
+:108D10002046F9F7CFF9102312930123ADF84E0046
+:108D200008260F9306250DF14E0320460EA9109636
+:108D30000E931195FCF7CEFE012F0CD12A4620464A
+:108D40004A49F6F7A9FE2022204682211346F6F76B
+:108D500031FE042506E02A4620464549F6F79CFEEA
+:108D600007260A250122134620464FF49B61F6F799
+:108D70007FFE45F4007343EA06139B0020464FF440
+:108D80009B6140F6FC72F6F773FE02221346204602
+:108D90004FF49B61F6F76CFE20464FF49B614FF455
+:108DA000E0424FF40053F6F763FE202213462046BC
+:108DB0004FF49A61F6F75CFE012100222046F8F795
+:108DC000E3F9204640F27641F6F720FE10F4004F1A
+:108DD00002D10A20EDF3C0F420460721039AF6F7EA
+:108DE000A3FD2046FF21049AF6F79EFD204640F29F
+:108DF0001F11059AF6F798FD204605215A46F6F709
+:108E000093FD204625215246F6F78EFD019B204614
+:108E10004FF48971DAB2F6F787FD0025104B204632
+:108E2000E95A07ABEA5A0235F6F7FCFD1C2DF5D1DD
+:108E300020464FFA88F1FEF7EFFE204640F2A441AB
+:108E40004A46F6F771FD029B1BB9E369186937F0D2
+:108E50008DDC40F2E730EDF37FF415B0BDE8F08F24
+:108E600050D801000ADC010076DC010088DC01003A
+:108E700094DC01002DE9F04FBDB007460C46914649
+:108E8000002116220DF15E000493E9F3D9F0A84900
+:108E90000E220DF19E00E9F36FF0A6490E2224A8E0
+:108EA000E9F36AF048F2670148F24522ADF8EA10AA
+:108EB000ADF8E820A04908220DF1C600E9F35CF006
+:108EC0009E490E220DF18200E9F356F09C490822DA
+:108ED0000DF1BE00E9F350F09A490E221DA8E9F306
+:108EE0004BF047F69733002108220DF1B600ADF89C
+:108EF000E630ADF8E430E9F3A3F0FB69302198687F
+:108F0000D7F8A880EDF3E4F60590002800F0AB82D6
+:108F100040F2DB613846F6F779FD40F2DA610B90FA
+:108F20003846F6F773FD88490A9004223846F6F76A
+:108F3000B3FDB9F1070F0BD8DFE809F011040A0AF5
+:108F40000A22352D1DAA069224AB0DF15E0214E013
+:108F50000DF18202002306921A46079319E00021C0
+:108F60000A460B4638460091F9F77AFD0DF1820169
+:108F700006910DF15E020DF19E03072107933EE07D
+:108F80000DF1E6030DF1EA01069308F18202079163
+:108F900001230E9334E039A906913AAB08F182021D
+:108FA000012107932BE03BAB00930DF1EF010DF195
+:108FB000EE020DF1ED033846F9F750FC9DF8EF2075
+:108FC0009DF8EE300DF1BE0143EA02234FF000029E
+:108FD000ADF86C30ADF86E209DF8EC309DF8ED20CA
+:108FE000069143EA0223ADF870304FF00003ADF86C
+:108FF00072300DF1C6030DF15E02079304210E914C
+:109000001023009330330193504B002102933846D4
+:109010000B23F6F7B1FE05224D493846F6F73CFD25
+:109020003846F9F7DBF84FF480521346089040F2C7
+:10903000A4413846F6F71CFD00213846FEF79AF9A0
+:1090400040F2DB413846F6F7E1FC4249062209903E
+:109050003846F6F721FDB7F8DA3003F47043B3F57C
+:10906000005F07BF38463C4938463C491222F6F7B4
+:1090700013FD40F2D7413846F6F7C8FC0599119028
+:109080003846FBF7BDFE384640F23B41F6F7BEFCE2
+:10909000C0F380100C9020B138460DF1B601F8F7FE
+:1090A000EBFF64B90C9A22B93846B8F83010FEF7D5
+:1090B000B3FD0DF1CE0438462146F8F7DDFF638895
+:1090C00022881B0143EA0223A288214613439EB251
+:1090D000B7F8DA30082203F470430DF1D600B3F587
+:1090E000805F14BF00250125E8F346F70A222BA86C
+:1090F0000021E8F3A5F71A4B002233F8154010467B
+:1091000033E0184B53F82530C1180B881230B342A6
+:109110002AD14B882BA8ADF8D6308A88ADF8D82054
+:1091200031F8063F0A22ADF8DA30E8F325F71EE001
+:1091300030DD01000ED801001CD801001ADB01004F
+:10914000D8DB010022DD0100BCD70100D55A0100A7
+:109150009AD50100A4D50100B4D60100F4D90100CC
+:1091600028DB0100D8D901000132A242C9D138461A
+:109170000DF1D601F9F74AF900240422384637499F
+:10918000374DF6F789FC10260A2338462146354A22
+:10919000009601940295F6F7EFFD202301933846DF
+:1091A0000A2321462F4A00960295F6F7E5FD40F284
+:1091B0005341384640F2A472F6F734FCB8F8C813AD
+:1091C00040F6A663A14208BF1946B9F1050F01D1C7
+:1091D0004B4299B2D7F8EC3F0CB22BB13846FDF7B1
+:1091E000EFFD0520EDF3B8F24FF47A710123582218
+:1091F000384604FB01F1FDF767FA40F2DA614FF6F9
+:10920000FF723846F6F70EFCB7F8DA30384603F44A
+:109210007043B3F5005F0CBF98F8959598F8969554
+:10922000F8F7B6FF0021C0B2FF228B4610900D91D7
+:109230000F929AE04FF000030799ADF8E0303BF849
+:109240000130C3F30324B9F1000F1AD0042C0BD062
+:109250000F9A042A13D110990EE0C04606DD0100D2
+:10926000D55A010010D90100109901EB0903D9B2B8
+:1092700011F0800F18BF7F213846FEF781FAE2B265
+:109280000F92069B3CA93BF8032001EB440333F803
+:10929000441C21B102F0FF0343EA01239AB238468D
+:1092A00040F25241F6F7BEFBE31E1FFA83FABAF111
+:1092B000010F16D86D4B1025452402933846002126
+:1092C0000DF1E202012300950194F6F747FD684B8A
+:1092D00038460293002138AA012300950194F6F73D
+:1092E0004BFD079B384640F251413BF80320F6F70F
+:1092F00099FB3846F9F730FF00287CD05B4A6021A3
+:1093000012AC10250B23019102920021384622460F
+:109310000095574EF6F722FD4023019300210B23C1
+:109320003846224600950296F6F726FDBAF1010F5F
+:109330000AD845230193384600210DF1E2020123AA
+:1093400000950296F6F718FD4849602301930291B3
+:1093500008F18202384600210B230095F6F7FEFC47
+:109360000D9A0BF1020B01320D920D9B0E998B425F
+:109370007FF460AF602301933C4B08F18206102418
+:1093800002933846002132460B23394D0094F6F7FC
+:10939000E5FC4FF001025023A8F8982038460193CD
+:1093A00000213246042300940295F6F7E5FC55238C
+:1093B00001933846002108F18C02022300940295A3
+:1093C000F6F7DAFC3846F8F753FCA0B138A90DF1EE
+:1093D000DE023846FCF750FB3846FCF7EDF9BDF8E5
+:1093E000E0100446BDF8DE203846FDF785FD38461E
+:1093F0002146FDF713FB049B13B93846FDF7E0FC4B
+:1094000038460599F9F716FB384640F2D741119ACC
+:10941000F6F708FBFB69059998683022EDF368F4CC
+:10942000384640F2DB41099AF6F7FCFA40F2534124
+:1094300038460022F6F7F6FA0C9921B138460DF1BC
+:10944000B601F8F7E3FF38460899FDF793FF384671
+:1094500040F2DA610A9AF6F7E5FA384640F2DB6143
+:109460000B9AF6F7DFFA3DB0BDE8F08FD15401005A
+:10947000D55A01002DE9F0470546D0F8A8404FEA3B
+:109480000118F8F785FE40F2D74147B22846F6F7B3
+:10949000BDFA94F925258146B2F1FF3F11D004238E
+:1094A00092FBF3F3984505DA284640F2D741402273
+:1094B000002304E04022284640F2D7411346F6F745
+:1094C000D7FAD5F8EC3F53B12846FDF779FC0520D3
+:1094D000EDF342F11C4928467022002302E01A49AC
+:1094E00028467022FDF7F0F828463946FEF794FB2F
+:1094F000002601212846FBF76DFD0423C8EB00047C
+:109500007A1E94FBF3F3D2187F2AA8BF7F2222EAA7
+:10951000E277284639460434FEF77EFB082C03D94F
+:109520000A2E01D00136E4E72846FDF749FC28461B
+:1095300040F2D7414A46F6F775FA2846F8F728FE72
+:1095400040B2BDE8F087C04600093D002DE9F04378
+:1095500091B08046D0F8A860F8F71AFE1C23B8F83E
+:10956000DA208DF83B3001238DF83A3002F4704355
+:10957000B3F5805F5FFA80F907D1D3B2402B01D8F1
+:109580001B2300E02D238DF83B30B8F8DA2002F4DD
+:109590007043B3F5005F33D1B6F82A2513B2B3F1A7
+:1095A000FF3F04D04FF6FF73002A08BF1A46B6F8F3
+:1095B000F6130BB2B3F1FF3F02D14FF4917104E007
+:1095C0004FF6FF73002908BF1946B6F82C5596F8D8
+:1095D000F0032BB2B3F1FF3F04D04FF6FF73002D21
+:1095E00008BF1D46B6F8F84323B2B3F1FF3F04D0DD
+:1095F0004FF6FF73002C08BF1C4696F8F1739FE0EE
+:10960000D3B2402B33D8B6F82E2513B2B3F1FF3FB7
+:1096100004D04FF6FF73002A08BF1A46B6F8FA13B3
+:109620000BB2B3F1FF3F02D14FF4917104E04FF65A
+:10963000FF73002908BF1946B6F8305596F859054A
+:109640002BB2B3F1FF3F04D04FF6FF73002D08BFDC
+:109650001D46B6F8004423B2B3F1FF3F04D04FF6E5
+:10966000FF73002C08BF1C4696F85B7568E08C2BD6
+:1096700033D8B6F8322513B2B3F1FF3F04D04FF61A
+:10968000FF73002A08BF1A46B6F8FC130BB2B3F1F9
+:10969000FF3F02D14FF4917104E04FF6FF730029B0
+:1096A00008BF1946B6F8345596F8F2032BB2B3F159
+:1096B000FF3F04D04FF6FF73002D08BF1D46B6F8DC
+:1096C000024423B2B3F1FF3F04D04FF6FF73002CE6
+:1096D00008BF1C4696F8F37332E0B6F8362513B28D
+:1096E000B3F1FF3F04D04FF6FF73002A08BF1A46BC
+:1096F000B6F8FE130BB2B3F1FF3F02D14FF49171F4
+:1097000004E04FF6FF73002908BF1946B6F8385534
+:1097100096F85A052BB2B3F1FF3F04D04FF6FF7312
+:10972000002D08BF1D46B6F8044423B2B3F1FF3F35
+:1097300004D04FF6FF73002C08BF1C4696F85C75EA
+:1097400013B2B3F1FF3F04D040461946FFF792FE33
+:109750000DE009B2B1F1FF3F07D040460DF13202F2
+:10976000FFF728F89DF83B3007E0FF2802D086F885
+:10977000070404E09DF83B300BB186F8073429B2AA
+:10978000B1F1FF3F05D04046FFF774FE86F80804AC
+:1097900011E021B2B1F1FF3F09D040460DF1320294
+:1097A000FFF708F89DF83B3086F8083403E0FF2FF8
+:1097B00018BF86F8087496F9EF33B3F1FF3F1CBF6A
+:1097C0004FF0FF3386F8083496F8080441B2B1F13F
+:1097D000FF3F76D096F8072453B29942D8BF86F857
+:1097E000082496F80834D8BF86F8070400248DF8BA
+:1097F0003B30DB23012503934046234621460DF1F0
+:10980000320204950094019402940594FEF72CFD15
+:1098100018230993083308950B93254607AC0FAB23
+:109820004046214607930A95FBF752FE05F1400397
+:109830004046214601350A93FCF74CF9402DEDD105
+:1098400096F9072496F908349B18022293FBF2F349
+:10985000A6F86835B8F8DA2002F47043B3F5005F73
+:1098600002D1B6F85E3583B9D3B2402B05D8B6F82D
+:10987000602512B1A6F8682509E08C2B02D8B6F84D
+:10988000623513B9B6F864350BB1A6F868354046B1
+:1098900040F224514FF400420023F6F7E9F896F91C
+:1098A0006625B6F86835013293FBF2F39BB2404669
+:1098B00040F22551FF22F6F7DBF8022386F86735E0
+:1098C00029E0012386F86735404640F22551FF2202
+:1098D0007E33F6F7CDF8404640F225514FF48072C2
+:1098E0000023F6F7C5F8404640F225514FF40072C8
+:1098F0000023F6F7BDF8404640F225514FF4806250
+:109900000023F6F7B5F8404640F225514FF40062C7
+:109910000023F6F7ADF84FF00003A6F86A3540468D
+:1099200040F2255196F96645F6F770F80134C0B259
+:1099300004FB00F496F96635A6F8684513B1404675
+:10994000FCF72CFD96F8EF330DF13202FF2B08BF28
+:1099500096F8073400218DF83B30DB230393012375
+:10996000049340460B460091019102910591FEF748
+:109970007BFC40464946FEF74FF9404640F2716194
+:10998000F6F744F8B6F96A3540F27161A0EBC3020C
+:1099900092B24046F6F746F84046FBF793FE11B008
+:1099A000BDE8F08370B58E46BEF1FF3F0546144614
+:1099B00019469DF9106002D006EB0E010DE022B9A8
+:1099C00090F82916FFF756FD02E0B2F1FF3F04D0F0
+:1099D00021462846FFF74EFD81192846FEF71CF95F
+:1099E00070BDC0462DE9F04F87B00446F8F7F6FB8E
+:1099F00004A981462046D4F8A850F8F73DFB20463C
+:109A0000F8F7BEFB40F2D74183462046F5F7FEFF4C
+:109A100003902046FCF74AF88246B9F1000F02D0C5
+:109A2000FF23029304E02046F8F7B2FB40B2029015
+:109A3000B4F8DA304FF02A0803F47043B3F5005F4E
+:109A40000CBF95F81E1595F81F1520464FB23946E4
+:109A50000F223C23CDF80080FFF7A4FF95F8466560
+:109A6000002E00F09080204640F2EB41F5F7CEFF4B
+:109A70001221C0F3402301222046F5F79BFF6A78AC
+:109A80000021521A18BF01220B462046FFF7F2F9B7
+:109A90002046FBF791FE40F3072340B2A5F84A3574
+:109AA000A5F84C0540F2EB412046F5F7AFFFC0F3B7
+:109AB00080235B02204640F2EB414FF40072F5F741
+:109AC000D7FF002107220B462046FFF7D3F9204697
+:109AD000FBF772FE40F3072340B2A5F84E35A5F818
+:109AE0005005FF222046B5F84A3540F65211F5F7E9
+:109AF000BFFF2046FF22B5F84C3540F65311F5F76D
+:109B0000B7FF2046FF22B5F84A3540F65611F5F763
+:109B1000AFFF2046FF22B5F84C3540F65711F5F758
+:109B2000A7FF2046FF22B5F84E3540F64811F5F75D
+:109B30009FFFFF222046B5F8503540F64911F5F752
+:109B400097FF95F84A3595F84C15204641EA0321D0
+:109B5000FCF764FF95F8473520469B0240F2EB4145
+:109B60004FF4806203F47C43F5F782FF95F84835A3
+:109B700020465B0240F2EB414FF4007203F47E4357
+:109B8000F5F776FF10E0204639460F223C23CDF84A
+:109B90000080FFF707FF6A7820463146003A18BF79
+:109BA00001223346FFF766F92046F8F74FF810B167
+:109BB0002046FBF715FE00217F220B462046FCF7CE
+:109BC000DDFC20465146FDF7C7FD20465946F8F713
+:109BD000D1FB204604A9F8F719FC204640F2D741F2
+:109BE000039AF5F71FFFB9F1000F04D0204649464C
+:109BF000FDF7C0FB03E020460299FEF70DF807B021
+:109C0000BDE8F08F2DE9F04F89B00446D0F8A87078
+:109C1000F8F7E4FA04902046F8F7BAFA4FF489719D
+:109C20005FFA80FA2046F5F767FE07210590204687
+:109C3000F5F762FEFF2101902046F5F75DFE40F248
+:109C40001F1102902046F5F757FE40F2AB410390FA
+:109C50002046F5F7DBFED4F8B030D3F8203183F09E
+:109C6000010313F0010B03D1E369186936F092DDAB
+:109C700000212046FDF77EFB2046F6F781FB40F2EF
+:109C80003B412046F5F7C2FE0DF1180949468046D2
+:109C90002046F8F7F1F920460121F8F77FFB20462E
+:109CA0007F21FDF7B9FF0122134620460721F5F772
+:109CB00081FE102213462046FF21F5F77BFE042289
+:109CC000134640F21F112046F5F774FE2046FDF7BB
+:109CD0004FFC06224B492046F5F7DEFE2046FBF7F7
+:109CE000E5FE002106462046FDF736FD002220460F
+:109CF0000121F7F749FA40F2AB412046F5F786FE1D
+:109D000040F23E612046F5F781FEC505ED0D2B467C
+:109D1000204640F2A64140F2FF12F5F7A9FE97F85F
+:109D2000E8330BB3204638490922F5F7B5FE002287
+:109D300020460121F7F728FA40F2AB412046F5F71B
+:109D400065FE40F23E612046F5F760FEC30540F235
+:109D50009A41204640F2FF12DB0DF5F789FE2046BE
+:109D60002A490922F5F798FE2B46204640F2A641E3
+:109D700040F2FF12F5F77CFE00234FF4805220469C
+:109D800040F24C41F5F774FE20463146FDF7E4FC05
+:109D90002046C8F38011F8F701FB20464946F8F742
+:109DA00035FB20465146FDF737FF20460499FDF765
+:109DB000E1FA20464FF48971059AF5F7B5FD019D4A
+:109DC000012205EA020320460721F5F7F3FD029D73
+:109DD000102205EA02032046FF21F5F7EBFD039D63
+:109DE0000422204640F21F1105EA0203F5F7E2FDC6
+:109DF000BBF1000F03D1E369186936F0B7DC09B095
+:109E0000BDE8F08FE0D80100ECD80100FED80100D9
+:109E10002DE9F3410446F8F7E1F9E369D4F8A850D5
+:109E20001B6A0026C4F8F03F94F8DA30804685F8C3
+:109E3000BC32D4F8B03084F8F46FD3F8203183F01A
+:109E4000010313F001070AD1E369B821186942F24E
+:109E5000107236F06DDCE369186936F09BDC204641
+:109E60000121F9F7B5FE0F2223492046F5F714FE2C
+:109E70002046F8F779FD20463146FCF7CFFD204615
+:109E800031463246FDF738F82046F6F779FA41F2C6
+:109E90001403E35C6BB12046FFF7B4FE2046314665
+:109EA000FDF750F995F8E8331BB120460121FDF785
+:109EB00049F92046FFF796FD00217F230A460093CB
+:109EC00020460123FDF7C8FF4FF0FF3385F8073424
+:109ED00085F808342046FFF739FB20464146FDF758
+:109EE00049FA20460021F9F773FE1FB9E3691869A2
+:109EF00036F03CDCBDE8FC819CD90100082910B596
+:109F000003D00A2904D0022904D1FFF781FF01E020
+:109F1000FEF796FD10BDC04610B50446F6F730FAC0
+:109F200020460021FDF726FA20460821FFF7E6FF2C
+:109F300010BDC04670B590F8F43F0446D0F8A85064
+:109F400013B9F7F713FFE8B1D4F8F83013F0070F9F
+:109F500006D194F8F5301BB920460921FFF7CEFF52
+:109F6000D4F8F82012F00F0F0CD194F9FC3F4BB944
+:109F700012F0800F06D194F8F5301BB9204602216B
+:109F8000FFF7BCFFD4F8F83013F00E0F02D12046D3
+:109F9000F9F758F9D4F8F83013F0060F3ED1D5F898
+:109FA000340448B3E169D5F838240B6A9B1A83421C
+:109FB00034D308696A2136F09DDB400081B2B1B12B
+:109FC000E369186936F096DB88B940F2764120469D
+:109FD000F5F71CFDC005C00DA5F86C0540F27741F2
+:109FE0002046F5F713FDC005C00DA5F86E05204607
+:109FF0000021F9F751FF11E040F276412046F5F7D4
+:10A0000005FDC005C00DA5F86C0540F2774120465E
+:10A01000F5F7FCFCC005C00DA5F86E052046F8F765
+:10A02000DDF8B0F5404F0CD02046F8F7B1F8C0B2DB
+:10A0300020B100237F2885F8563402D0002385F80C
+:10A04000573470BD2DE9F047CCB20746D0F8A86070
+:10A0500020468946F5F7ECFE494680463846F5F736
+:10A06000C9FE3846B7F8DA10FBF75AF90422384629
+:10A070005B49F5F711FD21463846FAF7BBF90A208E
+:10A08000ECF36AF34FF4004213464FF4896138460B
+:10A09000F5F7EEFC3846F8F793FB052100224FEA6E
+:10A0A0004800F7F7B9FC0022054641464FF420105E
+:10A0B000F7F7B2FC40F257610446AAB23846F5F70A
+:10A0C000B1FC38464FF4CB61A2B2F5F7ABFC4FF4CC
+:10A0D000007338464FF489614FF44072F5F7C8FCBD
+:10A0E00097F8DA300E2B01D11E2206E0B6F8622076
+:10A0F00013B2B3F1FF3F08BF1522A6F8402538463A
+:10A10000002112B2FBF7E6FB20B1384600211422F1
+:10A11000FBF7E0FB97F8DA3038220E2B0CBF182340
+:10A120000023384640F2EB41F5F7A2FCB7F8DA30ED
+:10A13000384603F47043B3F5005F0CBFB6F86620F1
+:10A14000B6F86820012113B2B3F1FF3F08BF022225
+:10A15000A6F83E2512B2FBF7BDFB1822384621496E
+:10A16000F5F79AFC3846F6F71BF996F8BC2298B139
+:10A170000E2AB7F8DA3003D9DBB20E2B03D805E08C
+:10A18000DBB20E2B02D83846012101E0384600210F
+:10A190004A46FCF7A5FF21E097F8DA309A4201D150
+:10A1A000012A04D138460821FFF7A8FE02E038460C
+:10A1B000FCF77AFF00210A463846FBF757FD384680
+:10A1C000F9F7BCF938460121F9F770FA41F21403A6
+:10A1D000FB5C1BB138460321FBF70EF9BDE8F087A5
+:10A1E0008CD60100A6D40100D0F8B03073B5D3F8F6
+:10A1F0002031044683F0010313F00106D0F8A85083
+:10A2000003D1C369186936F0C5DA41F21403E25C80
+:10A2100042BBB4F8DA3003F47043B3F5005F08D101
+:10A220004FF00403ADF800304FF00C03ADF80230EE
+:10A2300007E04FF0FF03ADF80030ADF802304FF00B
+:10A24000F00320466946ADF80430ADF80620F8F773
+:10A25000DDF820469621FDF77FFA20460121FEF722
+:10A26000C1FC56E02046FFF7CDFC2046FDF75AF82A
+:10A2700020460021FCF766FF204635490F22F5F7FE
+:10A280000BFC95F8E833DBB120460121FCF75AFFBF
+:10A2900095F92435204640F2D141FF229BB2F5F7D3
+:10A2A000E7FB95F82535204640F2D1414FF47F4237
+:10A2B0001B02F5F7DDFB204626490C22F5F7ECFBE7
+:10A2C000052220462449F5F7E7FBD4F8A8202046CC
+:10A2D000D2F84434D2F848243C2BA8BF3C23934204
+:10A2E000B8BF134640F2A741FF229BB2F5F7C0FB6F
+:10A2F000B4F8DA30204603F47043B3F5005F0CBFC6
+:10A3000095F8543495F855344FF440412B86FDF7B9
+:10A3100031F840F276412046F5F778FBC005C00DD4
+:10A32000A5F86C0540F277412046F5F76FFBD5F8AC
+:10A330003434C005C00DA5F86E051BB120460121BF
+:10A34000F9F7AAFD1EB9E369186936F00FDA7CBD8A
+:10A3500072DA010090DA0100A8DA01002DE9F0417B
+:10A36000D0F8A860012386F86130013B86F8C0333D
+:10A37000B0F8DA30074603F47043B3F5005F02D15A
+:10A3800096F8C13304E0B3F5805F06D196F8C23386
+:10A39000022B02D1012386F8C033B7F8DA303846F1
+:10A3A00003F47043B3F5805F0CBF96F8EB3396F877
+:10A3B000EA33002486F8E933738B0125A6F8BE3210
+:10A3C00004222349347086F8C24286F8C34286F8D4
+:10A3D000C44286F86755F5F75FFB38462946F8F71B
+:10A3E00027FA04221B493846F5F756FB3846FCF796
+:10A3F000A5FA3846FCF7E0FC3846FFF7F5FE86F88C
+:10A400002C40B7F8DA103846F6F790FD3846FBF7DF
+:10A4100069F84FF4804213464FF489613846F5F7E6
+:10A4200027FB6420ECF398F1234638464FF489610A
+:10A430004FF48042F5F71CFB38464FF44041FCF7DF
+:10A4400099FF41F28833F38686F89A55BDE8F0818A
+:10A450003EDD010046DD010010B58068F5F310F126
+:10A4600010BDC04610B5437902790C4642EA032E6E
+:10A470000EF00303012B0AD0022B0ED013B14FF4C0
+:10A4800000702EE00A780523B2FBF3F029E00B7888
+:10A49000144A03F00703D05C23E00978E3782279BB
+:10A4A00011F0800F43EA022201F07F0343F00060C5
+:10A4B00002D040F4806006E01EF0200F1CBF20F4A4
+:10A4C000E06343F4407012F0800F18BF40F40000C6
+:10A4D00012F0400F18BF40F48000C2F3011340EAAD
+:10A4E000035010BD54CC010070B585680446D4F803
+:10A4F000F811A868F5F3B2F04FF0FF3384F8E231B9
+:10A50000A361236800229A712B6B06460221186909
+:10A51000F5F740FC204639F0B5DBD6F1010038BF35
+:10A52000002070BD70B50D460968044671B1D1F8C0
+:10A530007C1129B1036840F20C72D868ECF3D8F3AF
+:10A5400023682968D8686269ECF3D2F32368294646
+:10A55000D8681022ECF3CCF370BDC04637B5054681
+:10A5600001A9D0F800053AF0B5DD09E028462146FA
+:10A570003BF010D8636C1BB9284621463BF020D92C
+:10A5800001A83AF0AFDD04460028EFD13EBDC04639
+:10A59000036870B510210546D868ECF399F308B943
+:10A5A000064615E02B6806466969D868ECF390F317
+:10A5B0000446306028B931462846FFF7B3FF2646E7
+:10A5C00006E00023C0F87C31314628463AF062DCD0
+:10A5D000304670BD2DE9F3470D469246002853D012
+:10A5E000002951D00B88D0F80490D0F89843D0F8C7
+:10A5F0009463002B4BD00027E780A7804B880A8804
+:10A6000013F0010824D0402A14D1043120463B46DF
+:10A6100000973EF081DEB8423BDBB6F8023113F022
+:10A62000400F34D0BAF1000F31D0D9F80C003DF012
+:10A6300015DE0BE0A2F108039BB2372B29D804F1F9
+:10A6400008000431E7F398F42D88A580384622E00D
+:10A65000202A19D8043104F14800E7F38DF4A4F856
+:10A6600004802D880123E580C6F8CC30B6F802318D
+:10A6700013F0400F0BD0BAF1000F08D0D9F80C003E
+:10A680003DF0ECDD404606E06FF0010003E0002005
+:10A6900001E04FF0FF30BDE8FC87C04610B50DF07B
+:10A6A0002DFA0446F0F714FA2046EBF363F610BDDA
+:10A6B000AAAA03001958000040960000904C000020
+:10A6C00014720000101800000FAC000050F20000DF
+:10A6D00050F201000050F20200000050F2020100AE
+:10A6E000AAAA0300195800000000000050F204005C
+:10A6F00000147200000FAC000050F20000101800AF
+:10A700000050F200000FAC00004096000000000076
+:10A710000000101800696C306D6163616464723D03
+:10A7200030303A31313A32323A33333A34343A35DE
+:10A730003500626F617264747970653D3078666669
+:10A74000666600626F6172647265763D30783130A2
+:10A7500000626F617264666C6167733D38006161AD
+:10A76000303D330073726F6D7265763D3200000FBD
+:10A77000AC000050F2000000594D80009557800059
+:10A7800049588000315680000D5A8000C158800021
+:10A79000295A8000455A8000795780004D56800024
+:10A7A000755A800025558000F15980000D588000B1
+:10A7B00069548000C14E8000E951800055528000EC
+:10A7C000C9518000DD58800051518000D155800072
+:10A7D000A555800015568000E14F80008955800006
+:10A7E000FD4E80002550800061EC0000ED4D8000A2
+:10A7F000854E8000A94F8000D94D8000094E800011
+:10A80000514C8000654C80000000000000000000FA
+:10A8100000000000C14F800025528000F9518000E7
+:10A82000FD2700002800000073645F6C6576656C8E
+:10A830005F74726967676572007370695F70755FD6
+:10A84000656E6162006172705F6D61636164647204
+:10A85000006172705F72656D6F74656970000000F1
+:10A86000F83B86000000000007000000FF3B860068
+:10A8700001000000070000000B3C86000200000001
+:10A88000000000001B3C86000300000007000000E1
+:10A89000263C86000400000000000000373C8600D3
+:10A8A0000500000008003000413C86000600000062
+:10A8B0000000000045A8010008000000060000009C
+:10A8C00051A801000900000007000000000000007E
+:10A8D00000000000000000000200000000005C78A2
+:10A8E0002530325800253034780A00747863686166
+:10A8F000696E007278636861696E0025733A206240
+:10A900007373636667206973206E756C6C210A002F
+:10A91000776C635F696F766172733200727373690B
+:10A920005F6F66667365740064796E74785F7164D6
+:10A93000626D5F6F766572726964650064796E74CA
+:10A94000785F726174655F616C6C00505A443A20A4
+:10A9500025643E2564206F722025643E25642061B5
+:10A960003D25640A006F747077006164640064655B
+:10A970006C006C6F775F727373695F74726967677D
+:10A980006572006C6F775F727373695F6475726173
+:10A9900074696F6E0074635F656E61626C650074EC
+:10A9A000635F706572696F640074635F68695F7785
+:10A9B0006D0074635F6C6F5F776D0074635F7374B9
+:10A9C00061747573006173736F635F737461746531
+:10A9D0000064796E74780074785F737461745F6377
+:10A9E000686B0074785F737461745F63686B5F7029
+:10A9F00072640074785F737461745F63686B5F7214
+:10AA00006174696F0074785F737461745F63686BFD
+:10AA10005F6E756D0072785F726174650069735F57
+:10AA20005750535F656E726F6C6C65650069735F3C
+:10AA30007770735F656E726F6C6C656500676574C7
+:10AA4000736E72001CA901000100000006000000E6
+:10AA500072A90100020000000600000083A90100A5
+:10AA6000030000000600000095A90100040000009A
+:10AA7000060000009FA9010005000000060000007C
+:10AA8000A9A901000600000006000000B2A901000B
+:10AA90000700000006000000BBA90100080000003C
+:10AAA00006000000C5A90100090000000600000022
+:10AAB000D1A901000A00000006000000D7A901008A
+:10AAC0000B00000006000000E3A901000C000000DC
+:10AAD00006000000F3A901000D00000006000000C0
+:10AAE00005AA01000E0000000600000015AA0100E2
+:10AAF0000F000000060000001DAA01001000000069
+:10AB0000010000002DAA010010000000010000005B
+:10AB10003DAA010011000000060000000000000036
+:10AB2000000000000000000005A58100FDA58100D7
+:10AB30000000000000000000010005060000000009
+:10AB40000DCD820089E68200F5CB8200EDCC82003B
+:10AB5000678986000000800001000000458B8600A8
+:10AB600001000000080002004F8B86001D0000005D
+:10AB7000080002005C8B86000F000000030000004C
+:10AB80006A8B860010008000070000007A8B860028
+:10AB900002000000080007008B8B86000300000005
+:10ABA000080007009C8B8600040080000100000064
+:10ABB000AE8B86000600000002000000B98B860004
+:10ABC0000C00000002000000C88B860021008000FD
+:10ABD0000300000000000000000000000000000072
+:10ABE000776C25643A20776C635F616D7064755F84
+:10ABF00072656C656173653A2063616E6E6F742077
+:10AC000072656C6561736520256420286F757420FA
+:10AC10006F662077696E646F77290A0025733A2082
+:10AC2000776C20646F776E210A0025733A20776C69
+:10AC3000207570210A00776C635F616D7064755FC9
+:10AC40007265737461727400D6AD0100100000006B
+:10AC500006000000529B8600010000000100000079
+:10AC60005D9B860002002000070000006F9B8600AD
+:10AC700003004000080007007C9B860004004000A1
+:10AC8000080004008B9B86000500400008000400BB
+:10AC90009A9B86000600000008000400D9AD010060
+:10ACA0000D00100007000000A79B86000E0020008A
+:10ACB00007000000B49B860007001000070000009A
+:10ACC000BF9B86000800000008001000E2AD0100F4
+:10ACD0000900000006000000C99B86002400000057
+:10ACE00006000000E6AD01000A00000006000000BA
+:10ACF000AB7286000F00000001000000D59B8600AB
+:10AD00000B00800001000000DA9B86000C000000B0
+:10AD100005000000E59B86001D0000000300000008
+:10AD2000FA9B86001E00000007000000139C8600AE
+:10AD30001F00000007000000259C86002100000085
+:10AD4000050000003B9C860020000000030000007E
+:10AD5000499C860011008000010000004F9C860085
+:10AD60001800400008000600539C860019000000EF
+:10AD700005000000619C86001A0000000100000030
+:10AD80006C9C86001B0040000100000000000000D9
+:10AD900000000000000000000050F202010100006D
+:10ADA0000364000027A4000041435E0061322F00CD
+:10ADB00073656E74206F7574205052554E45204552
+:10ADC00056454E5420657863656564206D617861F1
+:10ADD00073736F630A006170006D61786173736FE4
+:10ADE000630062737300737369640000D55083005D
+:10ADF000215783000000000000000000776C2564EC
+:10AE00003A205048595458206572726F7228256450
+:10AE1000290A00092F160E0E0500000091BA8600BF
+:10AE2000000080000100000030BB8600020000002E
+:10AE3000080044003ABB86000300000008004400FC
+:10AE400044BB860004000000080000004FBB8600E1
+:10AE5000050000000800440059BB86000600000001
+:10AE60000800000067BB86000700000008004C00D7
+:10AE700074BB86000800000008004C0081BB8600FF
+:10AE80000900800002000000000000000000000037
+:10AE900000000000C8E686000000000008000C006A
+:10AEA000D7E686000100000007000400E9E68600FE
+:10AEB0000200000008000800FBE686000300000016
+:10AEC000070004000BE786000400000008001C00D7
+:10AED0001BE786000500000008000C002CE7860038
+:10AEE000060000000700040043E78600070000009A
+:10AEF0000700040024AF0100080000000700040060
+:10AF000034AF0100090000000700040048AF010051
+:10AF10000A0000000800900000000000000000008F
+:10AF200000000000706B745F66696C7465725F6925
+:10AF3000636D7000706B745F66696C7465725F69D5
+:10AF4000636D705F636E740077616B655F706163E2
+:10AF50006B65740053657420425250542061742014
+:10AF600025780A000A465749442030312D25780AB1
+:10AF7000000A54524150202578282578293A20701B
+:10AF8000632025782C206C722025782C207370206B
+:10AF900025782C207073722025782C20787073729D
+:10AFA0002025780A00202072302025782C2072314C
+:10AFB0002025782C2072322025782C2072332025F1
+:10AFC000782C2072342025782C2072352025782C7E
+:10AFD0002072362025780A00202072372025782C10
+:10AFE0002072382025782C2072392025782C207268
+:10AFF00031302025782C207231312025782C207298
+:10B0000031322025780A000A20202073702B30204E
+:10B01000253038782025303878202530387820259C
+:10B020003038780A00202073702B313020253038DA
+:10B030007820253038782025303878202530387829
+:10B040000A0073702B257820253038780A00646553
+:10B0500061646D616E5F746F007265636C61696DD0
+:10B060002073656374696F6E20313A205265747580
+:10B07000726E656420256420627974657320746F34
+:10B080002074686520686561700A007265636C6190
+:10B09000696D2073656374696F6E20303A20526564
+:10B0A0007475726E656420256420627974657320FE
+:10B0B000746F2074686520686561700A0072616D44
+:10B0C0007374627964697300706125643D3078251A
+:10B0D000257800706425643D3078252578006E76EB
+:10B0E00072616D5F6F766572726964650000000061
+:10B0F00086060200D0090000800602003E3E0000E5
+:10B10000820602003E020000000702003C00000030
+:10B110008406020012020000600104000300010026
+:10B1200064010200C000000060010400030001008F
+:10B13000660102000A000000600104000400010032
+:10B140006401020014000000600104000700010017
+:10B150006401020083010000600104002500010079
+:10B1600064010200F4010000600104009605010082
+:10B17000660102002B040000600104009705010035
+:10B18000640102000001000060010400D701010019
+:10B19000640102003C00000060010400DC010100C9
+:10B1A000660102003400000060010400E2010100B9
+:10B1B000640102003000000060010400E7010100AA
+:10B1C000660102002C00000060010400ED01010096
+:10B1D000640102002C00000060010400F201010083
+:10B1E000660102002800000060010400F80101006F
+:10B1F000640102002800000060010400FD0101005C
+:10B200006601020028000000FFFF000000000000AF
+:10B21000600104000500010364010400000019003E
+:10B2200024010400040000002801040000000000C4
+:10B230002C010400000000003001040000000000A8
+:10B24000340104000A04700034010400EFBED4008D
+:10B2500034010400050000FF3401040001FF02FF77
+:10B260003001040018000000340104000A04E0006A
+:10B2700034010400EFBE480034010400050000FF63
+:10B280003401040001FF02FF340104000010180122
+:10B2900034010400020300103401040018F1F2F339
+:10B2A00034010400BBCC000030010400680600003B
+:10B2B000340104001404700034010400EFBE58018E
+:10B2C00034010400000000FF3401040001FF02FF0C
+:10B2D00034010400001018013401040002030309C2
+:10B2E00034010400BF00001034010400000000001D
+:10B2F00030010400380000003401040000000000A8
+:10B3000030010400880600003401040014048000A9
+:10B3100034010400EFBE18023401040000000309E8
+:10B3200034010400BF0000033401040000010203E3
+:10B330003401040004050001340104000203040583
+:10B340003401040000000000300104005800000037
+:10B350003401040000000000300104003800000047
+:10B36000340104000F2000073401040000009400A1
+:10B3700034010400000000903401040074757677F5
+:10B380003401040000000000340104000000050046
+:10B3900034010400FFFFFFFF3001040068020000D9
+:10B3A000340104006E84330034010400DCBA500020
+:10B3B00034010400D40000AB34010400BADABADA74
+:10B3C00034010400001018F134010400F2F30010FD
+:10B3D0003401040018F1F2F33401040010000000FD
+:10B3E00034010400000000003401040000000A00E1
+:10B3F000340104000100000E340104004252434DA8
+:10B40000340104005F54455334010400545F535326
+:10B4100034010400494401043401040082848B9601
+:10B42000340104000301010634010400020000009D
+:10B430003001040068000000340104000A042802FE
+:10B4400034010400DCBA8000340104000000FFFF76
+:10B4500034010400FFFFFFFF34010400001018F165
+:10B4600034010400F2F300103401040018F1F2F387
+:10B4700034010400D0AF00003401040000000000DB
+:10B480003401040000000001340104000200000E39
+:10B49000340104004252434D340104005F544553CB
+:10B4A00034010400545F535334010400494401043F
+:10B4B0003401040082848B963401040003010106E8
+:10B4C000340104000201000030010400680400009F
+:10B4D000340104000A04280234010400DCBA8000AC
+:10B4E000340104000000FFFF34010400FFFFFFFFF0
+:10B4F00034010400001018F134010400F2F30010CC
+:10B500003401040018F1F2F334010400D0AF00005C
+:10B5100034010400000000003401040000000001B8
+:10B52000340104000200000E340104004252434D75
+:10B53000340104005F54455334010400545F5353F5
+:10B5400034010400494401043401040082848B96D0
+:10B55000340104000301010634010400020100006B
+:10B56000000104000000000190040200000000003F
+:10B57000A0040200F1F30000B0040200EFFD00009F
+:10B58000A8040200FFFF0000A80402000000000061
+:10B59000AA04020000000000A4040200CF1A000068
+:10B5A000AC04020000000000BC0402000000000027
+:10B5B000A6040200D7020000B6040200FFFD00004E
+:10B5C000AE040200FFFF00000604020001000000BC
+:10B5D00006040200000000000C0402001800000035
+:10B5E000060402000000000048040200000C0000F5
+:10B5F00002040200A0070000020502000000000093
+:10B6000000050200004000000205020004000000E6
+:10B6100000050200004000000205020008000000D2
+:10B620000005020000400000020502000C000000BE
+:10B63000000502000040000002050200C0000000FA
+:10B6400080050200FFFF000082050200FFFF0000EE
+:10B6500084050200FFFF000086050200FFFF0000D6
+:10B6600088050200FFFF00009C050200F0FF0000BB
+:10B67000400502000080000020050200060F0000C7
+:10B68000400502000080000040050200008100002B
+:10B6900020050200101D000040050200008100008E
+:10B6A0004005020000820000200502001E28000064
+:10B6B00040050200008200004005020000830000F7
+:10B6C000200502002931000040050200008300002F
+:10B6D000400502000084000020050200323F000007
+:10B6E00040050200008400004005020000850000C3
+:10B6F00020050200404100004005020000850000D6
+:10B7000012060200010000002E060200CDCC00004F
+:10B71000300602000C000000000602000480000059
+:10B7200096060200080000009A060200E4000000ED
+:10B7300088060200000000009C06020002000000D3
+:10B7400088060200001000009C06020002000000B3
+:10B7500088060200002000009C0602000200000093
+:10B7600088060200003000009C0602000200000073
+:10B77000880602000B0F00009E0602000700000072
+:10B78000100502000B00000050040200014E0000F2
+:10B79000520402005B010000E4040200900000007B
+:10B7A00004040200B400000054050200FF3F000042
+:10B7B00060010400040001036401040000000000B3
+:10B7C00064010400B4000000640104004700470065
+:10B7D00064010400000064006401040030094000BA
+:10B7E000600104000D000103640104000200020076
+:10B7F00064010400010080006401040005000000F1
+:10B80000640104000000800064010400640064001E
+:10B81000640104000E0047006401040000050000FC
+:10B8200060010400150001036401040000004208E7
+:10B8300064010400E00B0700640104000A0000003A
+:10B84000600104001A0001036401040000C0660BDB
+:10B85000600104001D0001036401040010270000C2
+:10B860006401040000007A03600104002000010369
+:10B870006401040006001027600104002300010396
+:10B88000640104000000F606640104000000AA0A36
+:10B890006401040000003200640104000A0E0B0978
+:10B8A000640104000E020000640104000000520A5A
+:10B8B0006401040000003F0164010400FFFF000C6C
+:10B8C0006401040032046E06640104000200F209FF
+:10B8D000600104002E0001036401040000000080E8
+:10B8E0006001040032000103640104000000320B17
+:10B8F0006001040034000103640104000000CC0571
+:10B900006001040058000103640104004252434DE9
+:10B91000640104005F54455364010400545F5353B1
+:10B920006401040049440000600104006000010358
+:10B9300064010400390000006401040050000000AC
+:10B9400064010400C00000006001040070000103F5
+:10B9500064010400AA03AA0364010400AA03AA0361
+:10B9600064010400AA03AA0364010400AA03AA0351
+:10B9700064010400EC03D60364010400C003AA03BD
+:10B9800064010400F703E10364010400CB03B50381
+:10B9900064010400AA03AA0364010400AA03AA0321
+:10B9A00064010400AA03AA0364010400AA03AA0311
+:10B9B00064010400EC03D60364010400C003AA037D
+:10B9C00064010400F703E10364010400CB03B50341
+:10B9D000640104000204020464010400020402047D
+:10B9E000640104000E0402046401040002041A0449
+:10B9F000640104000204020464010400020402045D
+:10BA00006401040002040204640104002604020428
+:10BA1000640104000204020464010400020402043C
+:10BA2000640104000E0402046401040002041A0408
+:10BA3000640104000204020464010400020402041C
+:10BA400064010400020402046401040026040204E8
+:10BA50006401040000001F0064010400FF031F00D4
+:10BA60006401040002000000640104000200000000
+:10BA700060010400980001036401040000001F003D
+:10BA800064010400FF031F006401040001000000C2
+:10BA9000640104000100000060010400A000010333
+:10BAA0006401040000001F0064010400FF031F0084
+:10BAB00064010400010000006401040001000000B2
+:10BAC00060010400A80001036401040000001F00DD
+:10BAD00064010400FF031F00640104000100000072
+:10BAE000640104000100000060010400B8000103CB
+:10BAF00064010400E700EC006401040000007B0026
+:10BB0000640104007E0000006401040000000000E5
+:10BB10006401040000004F51640104003F00000074
+:10BB2000640104000000001060010400C000010373
+:10BB300064010400372437246401040037243724C7
+:10BB40006001040093010103640104000F00400040
+:10BB500064010400E606000060010400970101038F
+:10BB6000640104001A08000060010400A001010340
+:10BB700064010400FFFFFFFF64010400FFFFFFFFFB
+:10BB800064010400FFFFFFFF64010400FFFFFFFFEB
+:10BB900064010400FFFFFFFF64010400FFFFFFFFDB
+:10BBA00064010400FFFFFFFF64010400FFFFFFFFCB
+:10BBB00060010400BC0101036401040000000500F1
+:10BBC00060010400C50101036401040000001003CA
+:10BBD00064010400E000FFFF640104000309BF00EA
+:10BBE000640104000000030964010400BF000010A8
+:10BBF000640104000309BF006401040000030000A5
+:10BC000060010400CD01010364010400FFFFFFFF98
+:10BC100064010400FFFFFFFF64010400FFFFFFFF5A
+:10BC200064010400FFFFFFFF64010400FFFFFFFF4A
+:10BC300064010400FFFFFFFF64010400FFFFFFFF3A
+:10BC400064010400FFFFFFFF640104002000CB013A
+:10BC50006401040000005400640104000000AB080B
+:10BC60006401040000001004640104008400020068
+:10BC7000640104000000140064010400CF0102000C
+:10BC8000640104004400000064010400AF080200E5
+:10BC90006401040010046400640104000202000056
+:10BCA000640104001000CA016401040002003C00A9
+:10BCB000640104000000AA086401040002001004EA
+:10BCC000640104005400020864010400000008003C
+:10BCD00064010400CE01000064010400340000008F
+:10BCE00064010400AE080000640104001004440074
+:10BCF00064010400020A0000640104000800C90194
+:10BD00006401040002003000640104000000A9087E
+:10BD10006401040002001004640104003C000210ED
+:10BD2000640104000000040064010400CD0100006F
+:10BD3000640104002C00000064010400AD08000050
+:10BD400064010400100434006401040002120000C5
+:10BD5000640104000400C8016401040000002C0018
+:10BD6000640104000000A80864010400000010043D
+:10BD700064010400300002196401040000000000A6
+:10BD800064010400CC010200640104002C000000E6
+:10BD900064010400AC0802006401040010043000D7
+:10BDA00064010400021A000064010400C0000A04D7
+:10BDB0006401040070000000640104003A010A04F8
+:10BDC0006401040028022CC064010400F2020A0489
+:10BDD0006401040000000001640104006000140418
+:10BDE000640104003800000064010400020114042E
+:10BDF0006401040014012CC064010400DE01140479
+:10BE00006401040000008000640104002200370483
+:10BE1000640104001500000064010400DF00370421
+:10BE20006401040065002CC0640104002E01370485
+:10BE30006401040000002F006401040011006E84FE
+:10BE4000640104000B00000064010400D4006E844F
+:10BE50006401040033002CC064010400FC006E8403
+:10BE600064010400000018006401040002008A9DBF
+:10BE700064010400FB00020864010400C54EFA00DE
+:10BE800064010400020A833464010400FE0002100D
+:10BE9000640104006227F900640104000212421ADE
+:10BEA00064010400FD00021964010400B113F800EC
+:10BEB00064010400021A811164010400FC00021CE8
+:10BEC00064010400C10FFC00600104007B03010356
+:10BED0006401040007001400640104001E00000057
+:10BEE000600104008303010364010400000000F00A
+:10BEF00064010400C33010926401040050318022B8
+:10BF000064010400C33000006001040088030103E1
+:10BF10006401040000001004600104008C030103AC
+:10BF20006401040080000000600104008E0301032E
+:10BF30006401040005000000600104000B0401031B
+:10BF400064010400000007026001040014040103FE
+:10BF500064010400010000006001040016040103F4
+:10BF6000640104000C00000060010400530501039B
+:10BF7000640104000000180060010400550501037D
+:10BF800064010400983A983A64010400A60E640023
+:10BF9000640104000000F4016401040005000000D5
+:10BFA00064010400A861A8616401040030751E00EA
+:10BFB000600104005D0501036401040050C300003A
+:10BFC000600104005F050103640104000000140522
+:10BFD0006401040050C30000600104006305010314
+:10BFE00064010400204E00006401040000000F0002
+:10BFF00064010400F4010400600104006905010308
+:10C00000640104000000310064010400000003002A
+:10C01000640104000100070064010400C8AF0000CF
+:10C020006401040088130000640104002C17FF0061
+:10C0300060010400700501036401040000002C018C
+:10C04000640104000000A00F6001040073050103F7
+:10C0500064010400000003006401040000002C01DE
+:10C0600064010400C00000006401040088130000A3
+:10C07000640104006400000064010400DC05401F4A
+:10C08000600104007A05010364010400010001005D
+:10C090006401040002000000600104007D0501034A
+:10C0A0006401040002000000640104000000409CE0
+:10C0B00064010400204E000064010400B80B00007D
+:10C0C0006001040082050103640104000000204EA9
+:10C0D000640104000000050064010400DC053F0069
+:10C0E0006401040071020000640104003075000066
+:10C0F000600104008A05010364010400C409A00F63
+:10C10000600104008D050103640104000A00D007EA
+:10C11000600104008F05010364010400204E204EDD
+:10C12000600104009505010364010400BE000000E5
+:10C1300060010400B105010364010400E80300008C
+:10C1400060010400ED05010364010400000000002B
+:10C1500060010400F6050103640104008813000077
+:10C160006001040003000200640104001F000000DD
+:10C17000600104000400020064010400FF030000E9
+:10C180006001040005000200640104001F000000BB
+:10C1900060010400060002006401040007000000C2
+:10C1A00060010400070002006401040004000000B4
+:10C1B000600104000800020064010400FFFF0000A9
+:10C1C0006001040009000200640104000000000096
+:10C1D000600104000A000200640104000000000085
+:10C1E000600104000B000200640104000000000074
+:10C1F000600104000C000200640104000000000063
+:10C20000600104000D000200640104000000000051
+:10C21000600104000E000200640104000000000040
+:10C22000600104000F00020064010400000000002F
+:10C230006001040010000200640104001F000000FF
+:10C24000600104001100020064010400000000000D
+:10C2500060010400120002006401040000000000FC
+:10C2600060010400130002006401040000000000EB
+:10C2700060010400150002006401040000000000D9
+:10C2800060010400160002006401040000000000C8
+:10C29000FFFF000000000000636275636B5F73774F
+:10C2A0006672657100000000E02E0101015000007F
+:10C2B00000000000C832020101490000899DD80039
+:10C2C0004038030101420000AAAAAA00003C040170
+:10C2D000013E000000008000483F050101390000D8
+:10C2E000D05E4200A04106010139000049922400BD
+:10C2F000004B07010132000000000000584D08010A
+:10C3000001300000071F7C00204E090101300000B1
+:10C3100000000000A8610A010126000066666600B0
+:10C3200090650B0101240000C44EEC0030750C0137
+:10C33000012000000000000018920D0201330000EF
+:10C34000F93E560000960E02013200000000000087
+:10C35000409C0F02013000000000000080BB100272
+:10C3600001280000000000000000000000000000A4
+:10C370000000000099C30100000000000800080050
+:10C3800098C301000100000008000B00000000003D
+:10C3900000000000000000006D6B6565705F616C5F
+:10C3A00069766500352E39302E3139352E32362EEC
+:10C3B0003300776C25643A20257320257320766539
+:10C3C0007273696F6E2025732046574944203031BF
+:10C3D0002D25780A00417567203133203230313203
+:10C3E0000031393A31303A3436000000DA43860001
+:10C3F0000000000008000000E34386000100000088
+:10C40000010000000000000000000000000000002B
+:10C41000746F655F6F6C00746F655F7374617473C4
+:10C4200000746F655F73746174735F636C656172D0
+:10C4300000AAAA030000000010C4010000000000D0
+:10C440000700000017C401000100000008004C00B4
+:10C4500021C40100020000000000000000000000F4
+:10C460000000000000000000D58D86000C00800058
+:10C4700001000000A98E86000B00000001000000F2
+:10C48000B58E86000300000005000000C18E860006
+:10C490000400000007000000D08E86000500800028
+:10C4A000010000000000000000000000000000008B
+:10C4B0005B574C414E5D636F756E74203D20256463
+:10C4C0000A00496E697420436F756E746572004787
+:10C4D000726F7570206B657920657870616E736915
+:10C4E0006F6E0061757468000000000000000000BD
+:10C4F00000000000627461006274616D700062741B
+:10C50000616D705F666C616773006274616D705F0E
+:10C510006368616E006274616D705F31316E5F736C
+:10C520007570706F7274006274616D705F66620026
+:10C530006274616D705F73746174656C6F670041E4
+:10C540004D502D253032782D253032782D25303242
+:10C55000782D253032782D253032782D25303278DF
+:10C5600000545454545400000000000000000050D7
+:10C570005050505000000000000000000023000058
+:10C580000300000000084C4C4C4C4C4C141414009C
+:10C5900000010000646464646464646464646464EA
+:10C5A0006400000000000000000000000000000027
+:10C5B000013C4242424242424242423C00000000B0
+:10C5C0000000000000000000000000000000344AED
+:10C5D0004E4E4E4E4E4E4E4A3800000000000000B7
+:10C5E00000000000000000000000004C4C4C4C4CCF
+:10C5F0004C4C4C4C4C4C4C4C00000040404040409B
+:10C600004040000000000001030000000001424221
+:10C6100042324242141414000000000003000000E3
+:10C6200000013E3E42343E4214141400000000005B
+:10C6300054545400540000000000000000000000AA
+:10C6400000000000000000000000000023000000C7
+:10C650000300000000014444443844401414140012
+:10C6600000000000484A4A4A4A4A4A4A4A4A4A4A54
+:10C67000480000003434343434343434340000009E
+:10C68000004E4E4E4E4E4E4E4E4E4E4E4E4E0000B4
+:10C6900000000000000000000000000000085454EA
+:10C6A00054005400000000000000000050505000F2
+:10C6B00050000000000000000000233A3E38004215
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000A0000000064000000EC
+:10C6E00000000000000000000000580000000000F2
+:10C6F0000000000001364444444444444444443669
+:10C700004A4000000000000000000000000000009F
+:10C7100000082E4444444444444444442E463A00D1
+:10C720000000000000000000000000000000083CC5
+:10C730003E3E3E3E3E3E3E3E3E3C3E3E0000000013
+:10C7400000000000000000000000000834444444E1
+:10C750004444444444443844400000000000000085
+:10C760000000000000000000085C5C5C5C5C5C5C3D
+:10C770005C5C5C5C5C5C0000505050505050505011
+:10C78000500000000001383E383E4200000000002A
+:10C790000000000000000000000000000000000099
+:10C7A00000000A000100000000014E4E4E344C38DB
+:10C7B0001E1E1E0000000000030000000001424495
+:10C7C0004230443014141400000000000300000044
+:10C7D00000013E3E3E3C3E3E1414140000000000AA
+:10C7E000030000000001444444364C381414140083
+:10C7F0000000000042424242424242424242424221
+:10C80000420000002E343434343434343400000018
+:10C81000004A4A4A4A4A4A4A4A4A4A4A4A4A000056
+:10C82000002E343434343434343400000000545492
+:10C830005400540000000000000000004848480078
+:10C8400048000000000000000000233E3E3E4A0079
+:10C850000000000000000000002828284000000020
+:10C8600000000000000000004644444A00000000B0
+:10C8700000000000000000000000000000000000B8
+:10C88000000000000A54545400540000000000004E
+:10C890000000004848480048000000000000000078
+:10C8A0000023545454540000000000000000000015
+:10C8B00050505050000000000000000000002338DD
+:10C8C00044444A4A0000000000000000000000004C
+:10C8D00000000000000000000000000A000000004E
+:10C8E00034000000000000000000000000003400E0
+:10C8F0000000000000000000005454545454000094
+:10C9000000000000000000484848484800000000BF
+:10C910000000000000235454545454000000000050
+:10C920000000000050505050500000000000000077
+:10C930000000235C5C5C0050000000000000000070
+:10C940000050485000440000000000000000002398
+:10C950004C4C4C4C4C4C4C4C4C4C4C4C4C000000FB
+:10C9600000000000000000000000000009545454C2
+:10C9700054540000000000000000004848484848A7
+:10C980000000000000000000002300000000640020
+:10C99000000000000000000000000000580000003F
+:10C9A00000000000000001000300000000004646F7
+:10C9B00046484A4817171700000000003A3A3A3A2A
+:10C9C0004600000000000000000000000000000021
+:10C9D000000000000000000008384444444A000001
+:10C9E0000000000000000000000000000000000047
+:10C9F00000000000002A00000000540000000000B9
+:10CA000000000000000000004400000000000000E2
+:10CA10000000013E484842460000000000000000BF
+:10CA20000000000000000000000000000000000AFC
+:10CA30000038383E42000000000000000000000006
+:10CA40000000000000000000000000000A32323246
+:10CA500038000000000000000000003838383800BE
+:10CA6000000000000000000000004C0000004C002E
+:10CA70000000000000000000500000005000000016
+:10CA800000000000000001545454000000000000A9
+:10CA900000000000005050500000000000000000A6
+:10CAA00000000023030000000001444444344444D7
+:10CAB00014141400000000007DC586000000000072
+:10CAC0000800240084C58600010000000800000062
+:10CAD00093C586000200000008000C00A4C5860073
+:10CAE000030000000800E402AFC586000400000057
+:10CAF00007000000C0C586000500000008002400F3
+:10CB0000C9C586000600000001000000D1C58600EE
+:10CB10000700000007000000DBC5860008000000D9
+:10CB20000100000049C58600090000000100000066
+:10CB300000000000000000000000000025733A2003
+:10CB400063616C6C65640A0070617463685F696F2F
+:10CB50007661727300616D7064755F7274730077D3
+:10CB60006C635F61757468656E74696361746F721C
+:10CB70005F646F776E00000020798600000000403F
+:10CB8000030000003D7D86000100088008000000D1
+:10CB9000E3C401000200004006000000D9AD01001E
+:10CBA000030010000700000055CB01000400000046
+:10CBB0000100000000000000000000000000000074
+:10CBC00001006C09020071090300760904007B0969
+:10CBD000050080090600850907008A0908008F09F9
+:10CBE000090094090A0099090B009E090C00A30989
+:10CBF0000D00A8090E00B4096E840B000000D400DB
+:10CC000000000000000000010000000000002D00F6
+:10CC1000A7901A0047090E00012007008B9303001C
+:10CC200038CA01002AE50000977200004C39000064
+:10CC3000A61C0000530E0000290700009503000009
+:10CC4000CA010000E5000000730000003900000088
+:10CC50001D0000006030180C6C482412776C2564AD
+:10CC60003A205363616E20696E2070726F6772653F
+:10CC700073732C20736B697070696E6720747870A1
+:10CC80006F77657220636F6E74726F6C0A00706FDD
+:10CC90007765722061646A210A002E6661622E0047
+:10CCA00025732E6661622E25640063636B627732A2
+:10CCB000303267706F0063636B62773230756C324D
+:10CCC00067706F006C65676F66646D6277323032D3
+:10CCD00067706F006C65676F66646D627732307580
+:10CCE0006C3267706F006D637362773230326770D9
+:10CCF0006F006D637362773230756C3267706F00EE
+:10CD00006D6373627734303267706F006C65676F84
+:10CD100066646D6277323035676C706F006C656782
+:10CD20006F66646D62773230756C35676C706F005A
+:10CD30006C65676F66646D6277323035676D706FF2
+:10CD4000006C65676F66646D62773230756C35674D
+:10CD50006D706F006C65676F66646D627732303539
+:10CD60006768706F006C65676F66646D62773230FC
+:10CD7000756C356768706F006D637362773230353C
+:10CD8000676C706F006D637362773230756C3567F6
+:10CD90006C706F006D63736277343035676C706FE1
+:10CDA000006D63736277323035676D706F006D634D
+:10CDB0007362773230756C35676D706F006D6373B9
+:10CDC0006277343035676D706F006D6373627732F0
+:10CDD00030356768706F006D637362773230756CE1
+:10CDE000356768706F006D637362773430356768DC
+:10CDF000706F006D63733332706F006C65676F66C0
+:10CE0000646D3430647570706F00616E747377692F
+:10CE100074636800616135670074737369706F7360
+:10CE200032670065787470616761696E326700709F
+:10CE300064657472616E6765326700747269736FDE
+:10CE4000326700616E74737763746C326700747359
+:10CE50007369706F733567006578747061676169B5
+:10CE60006E3567007064657472616E676535670062
+:10CE7000747269736F356700616E74737763746C75
+:10CE800035670070613267773061330070613267F7
+:10CE900077316133006D61787032676130006D61A8
+:10CEA00078703267613100706132677730613000CD
+:10CEB000706132677730613100706132677731615C
+:10CEC00030007061326777316131007061326777AD
+:10CED000326130007061326777326131006D6178A4
+:10CEE0007035676C6130006D61787035676C6131E9
+:10CEF00000706135676C7730613000706135676C48
+:10CF00007730613100706135676C77316130007066
+:10CF10006135676C7731613100706135676C7732EC
+:10CF2000613000706135676C77326131006D617816
+:10CF30007035676130006D61787035676131007000
+:10CF40006135677730613000706135677730613106
+:10CF50000070613567773161300070613567773116
+:10CF6000613100706135677732613000706135671B
+:10CF700077326131006D6178703567686130006DBE
+:10CF80006178703567686131007061356768773046
+:10CF900061300070613567687730613100706135EC
+:10CFA000676877316130007061356768773161316A
+:10CFB000007061356768773261300070613567688D
+:10CFC00077326131006D61787035676133006D6172
+:10CFD000787035676C613300706135677730613325
+:10CFE00000706135676C7730613300706135677749
+:10CFF00031613300706135676C7731613300706186
+:10D0000035677732613300706135676C7732613331
+:10D010000062773430706F00636464706F00737403
+:10D020006263706F006277647570706F00747870FF
+:10D0300069643267613000747870696432676131A5
+:10D0400000697474326761300069747432676131E9
+:10D050000063636B3267706F006F66646D32677078
+:10D060006F006D63733267706F30006D637332678A
+:10D07000706F31006D63733267706F32006D637370
+:10D080003267706F33006D63733267706F34006D99
+:10D0900063733267706F35006D63733267706F361C
+:10D0A000006D63733267706F370074787069643530
+:10D0B000676C613000747870696435676C61310049
+:10D0C0006F66646D35676C706F006D637335676C88
+:10D0D000706F30006D637335676C706F31006D6316
+:10D0E0007335676C706F32006D637335676C706F8A
+:10D0F00033006D637335676C706F34006D63733527
+:10D10000676C706F35006D637335676C706F3600D8
+:10D110006D637335676C706F370074787069643550
+:10D1200067613000747870696435676131006974D3
+:10D1300074356761300069747435676131006F66FA
+:10D14000646D3567706F006D63733567706F3000A5
+:10D150006D63733567706F31006D63733567706F22
+:10D1600032006D63733567706F33006D63733567BD
+:10D17000706F34006D63733567706F35006D637366
+:10D180003567706F36006D63733567706F37007485
+:10D1900078706964356768613000747870696435E7
+:10D1A00067686131006F66646D356768706F006D28
+:10D1B0006373356768706F30006D637335676870CF
+:10D1C0006F31006D6373356768706F32006D637324
+:10D1D000356768706F33006D6373356768706F34DF
+:10D1E000006D6373356768706F35006D6373356705
+:10D1F00068706F36006D6373356768706F370065F0
+:10D200006C6E61326700656C6E6135670074656DC8
+:10D21000706F66667365740070687963616C5F74C3
+:10D22000656D7064656C7461000C12182430486080
+:10D230006C003CC407003BC407004C84FFE0B08492
+:10D24000F7F7F984F7FF4D84FF834CC4001FB784C0
+:10D25000FF80B184FFDFB0C40808FA84F7FFF9C487
+:10D260000800CC0102000000D40000000000000013
+:10D2700000010000000000003CD30100350108302F
+:10D280000800030046D30100430100000100000034
+:10D2900050D30100480108000300000060D30100E2
+:10D2A00049010800030000006DD301004A01080095
+:10D2B000030000007BD301004E01080003000000C2
+:10D2C00086D301003D0140000700070092D3010012
+:10D2D0007A01000407000000A0D301003F01000014
+:10D2E00006000000ABD30100400100000200000076
+:10D2F000B6D301007C01000002000000C3D301008E
+:10D300004201000007000000CFD301002800080000
+:10D3100003000000E0D3010029000000010000002C
+:10D32000EDD301007F0100000200000000000000BA
+:10D330000000000000000000706879007478696ED9
+:10D340007374707772007068795F6D7574656400CE
+:10D350007068795F676C6974636874687273680079
+:10D360007068795F6E6F6973655F7570007068795A
+:10D370005F6E6F6973655F64776E007068795F7068
+:10D38000657263616C007068795F7278697165734A
+:10D3900074007068796E6F6973655F73726F6D008A
+:10D3A0006E756D5F73747265616D0062616E645F4E
+:10D3B00072616E67650073756262616E643567766F
+:10D3C0006572006D696E5F7478706F77657200705A
+:10D3D00068795F6F636C736364656E61626C65002E
+:10D3E0007068795F7278616E7473656C00706879CB
+:10D3F0005F6372735F7761720000D90404000000FC
+:10D40000D90408000800D90404000400D904080065
+:10D410000000FFEEDDCCBB998877665544332211BE
+:10D4200000000000000000000000000000000000FC
+:10D4300000000000000000000000000000000000EC
+:10D44000D70408000000D80401000000D80402003E
+:10D4500000003B04040004003C040400000036000B
+:10D460001A013A002500280005001201FF001F01E3
+:10D470000B0013010700FC00FD00FF00C000CA0004
+:10D48000C5001200570059005C0078009200980017
+:10D4900016012C016A000B001B0013011D00140172
+:10D4A0002E002A0112013B04010001003C0401008E
+:10D4B00001003C04010000003B04010000003B04AB
+:10D4C000020002003C04020002003C0402000000D2
+:10D4D0003B04020000004C04000800084D0400203A
+:10D4E0000000B00400010001B644FFFFB7040F00C4
+:10D4F0000F004C04000800084D0400200020B00478
+:10D50000000100010F0900090109060907090809BE
+:10D510000209030909090A090B09040905090C098B
+:10D520000D090E0911094804000300010806FF0057
+:10D5300017000406FF07EA033B84EDFF3C040200EA
+:10D5400002004C84D0EF4D84D7BF4D04040004008A
+:10D550004D0403000100F984F8FFFA84F8FF3B044E
+:10D56000020002003C04020000003B041000100016
+:10D570003C04400000004C04001000104D0400402A
+:10D5800000404D04040000004C0404000400B104F9
+:10D5900000040000B10400800000DA46FFFF03052C
+:10D5A00008000800DB04FF03A602DB040070002073
+:10D5B0000A80D7FDDA867FFFA40400400040A4045F
+:10D5C00000400000DAC64000A40400800080A404EB
+:10D5D00000400040A40400200020B00480000000AF
+:10D5E0003B0440000000A90400800080A6040080E5
+:10D5F0000080A604FF01FF009A04FF01FF002564DC
+:10D600002009202564200A004572726F7220676528
+:10D610007474696E67206C6F77206971206573740C
+:10D620000A004572726F722067657474696E6720B4
+:10D6300068696768206971206573740A0000D704FF
+:10D6400002000200D70480000000D704010001009E
+:10D65000D70440004000D70408000800D704007039
+:10D660000020DA0640004000A404002000008746A5
+:10D670006000424607004AC444004A44800031C664
+:10D680001500D60603000000DAC68F004AC4440025
+:10D690004A44800000FC070069A50500FF01000066
+:10D6A000695D0A0000040800975E0A00010200009C
+:10D6B00097A605009A05FF0326009B05FF03890036
+:10D6C0009C05FF038A009C0500FC00209D05003C92
+:10D6D000002C9D05FF038C004C04080008004D043D
+:10D6E000080000004C04200020004D042000200011
+:10D6F000F90402000200FA0402000000F904040028
+:10D700000400FA0404000000F90401000100FA0416
+:10D71000010000004C04001800184D040060006077
+:10D720003809FF01FF013909FF019E003B04030096
+:10D7300003003C0403000000DA46FFFFDBC60300E1
+:10D74000D106040004003B04010001003C04010078
+:10D7500001003C04010000003B0401000000D7442C
+:10D760000000D70401000100D70440000000760645
+:10D7700080000000DA06010000006C0804000000D0
+:10D780006C08400000006C08000400003B0401002D
+:10D7900001003C04010000003809000800083909B4
+:10D7A000000800085384FF7F53C400804AC444002B
+:10D7B0004A448000A3C60100A386FEFFDAC64000EB
+:10D7C000DBC603003B04020002003C040200000030
+:10D7D0003B04100010003C04400000004B44FFFFDD
+:10D7E0003B4917203C49C527D80401000000D80454
+:10D7F00002000000D704080000004C84FFE73B84CF
+:10D800000C00424907003B4917203C49C5272184A9
+:10D810002384348384806782568034828480678244
+:10D82000568034827A46030073467017C946000654
+:10D830008046FF0081463F01D70408000800D70456
+:10D8400000700020EB04C00100006A04FFFF190013
+:10D850000305A404D004D904DA04A604380939095C
+:10D86000D804D004D704A5040D04A2048B460000FC
+:10D870007646A1B8D106040000004B0640004000E7
+:10D88000340600FF0000DAC680000AC028023B040C
+:10D8900004000000380940000000380904000000BE
+:10D8A000D70402000000D70401000000D7040800DC
+:10D8B0000000D80401000000D80402000000100994
+:10D8C0001E091F09240925092609200921092709FC
+:10D8D00028092909220923093009310932091209C5
+:10D8E000D70401000100D70440004000D704010024
+:10D8F0000100D70440000000370600C00080D704B4
+:10D9000001000000D90401000100D9040200000058
+:10D9100000400140024003400440054006400740EB
+:10D92000075B07803A09800080002304FF0049005C
+:10D930003404FF00FCFF1604FF00A4FF160400FFE0
+:10D94000009F240400FF002A230400FF002D25046B
+:10D95000FF000F000005FF000F00000500FF000F93
+:10D960002004FF000A00340400070001FF0400FC4B
+:10D970000018F90401000100FA04010000004B0640
+:10D98000010001004B0608000800D6060300010054
+:10D99000DA0608000000DA06800000007606800043
+:10D9A0000000DA06010000006C08040000006C08AA
+:10D9B000400000006C080004000042490F0042498A
+:10D9C000000042490F004A4484004A448000D34684
+:10D9D0002222D3462022000022D401000700FF00AB
+:10D9E0001F013A001A010500820086002E01130172
+:10D9F0007D0028009A05FF0326009B05FF03A50074
+:10DA00009C05FF03A6009C0500FC00289D05003C2A
+:10DA1000001C9D05FF03A80003050100000003058D
+:10DA200004000000030510001000A40400400000E2
+:10DA3000A40400800080D00420000000A404FF01A2
+:10DA40000000A504FF00FF00A50400700050A5041D
+:10DA5000000700000D04FF0040000D040007000453
+:10DA6000A204FF004000A20400070004A804FF0075
+:10DA70000100D00401000000D304FF000000D30423
+:10DA800000FF0000D00410000000D00404000000DB
+:10DA9000D00402000000D204FF000000D20400FF06
+:10DAA0000000D00408000000100480000000A8441A
+:10DAB0000A00380940004000380904000400390910
+:10DAC00040000000390904000400DA0600800080EC
+:10DAD000D30600800080D30600800000DA060080B4
+:10DAE0000000424902003B4900003C4900007446E6
+:10DAF000440475463F00704681068C464900CE4678
+:10DB00000000CB460000CC460000CD4600009D46FC
+:10DB1000FF07A4460000A5460000977A977A977AF7
+:10DB2000977A877A877A977B01004AC444004A44EF
+:10DB30008000D70408000000D704007000203809D6
+:10DB400004000400390904000400A40400100010BB
+:10DB5000D70404000400D704000F000016012D01B3
+:10DB60002C016A00980097002F010B0013011D0083
+:10DB700014012E002A0109001F010700FF00050003
+:10DB8000060000000600000006000000060000007D
+:10DB9000B704007F006CB1040020000039090002C6
+:10DBA0000000380900020002B00408000800B004B8
+:10DBB00000080008390900080000380900080008BA
+:10DBC0001004020000001004010000001004020014
+:10DBD0000000100401000100977A877A877A977B0A
+:10DBE000100402000200100401000000DA06200008
+:10DBF000200010040800000081040002000210044C
+:10DC000008000800DA0620000000030501000000FB
+:10DC1000030504000000A40400400000A4040080E8
+:10DC20000000D00420000000A504FF00FF00A504B0
+:10DC300000700050A504000700000D04FF00400024
+:10DC40000D0400070006A204FF004000A204000724
+:10DC50000006D90470002000D90400070003D9048D
+:10DC600000700010DA0400100000DA040020002028
+:10DC7000A60400800080380904000400390904006B
+:10DC80000400A40400100010D70408000800D70402
+:10DC900000700010D70408000800D704007000309E
+:10DCA000760680008000DA06010001006C0804009E
+:10DCB00004006C08400040006C08000400043B04B1
+:10DCC000040004003C04040000004C0408000800A8
+:10DCD0004D04080008004C04200020004D042000E2
+:10DCE0000000F90402000200FA0402000200F90434
+:10DCF00004000400FA0404000400F9040100010017
+:10DD0000FA04010001005344A90A3D49C0004249F8
+:10DD1000000042490F00424900003B4917003C49BE
+:10DD2000C507977A977A977A977A877A877A977BCF
+:10DD300021842384348384806782568034824AC459
+:10DD400080004A847F000A46A0006A4419004AC441
+:10DD500044004A4480004C04001000104D04004070
+:10DD600000404C04000800084D04002000003B0463
+:10DD7000020002003C04020000003B04010001001C
+:10DD80003C0401000000D70401000100D70440005A
+:10DD900040008007000400048007000200020F0911
+:10DDA0000009010906090709080902090309090907
+:10DDB0000A090B09040905090C090D090E091109C5
+:10DDC000D7C6010031C600183B4400003C440000A7
+:10DDD0004C440000E6440000F9440000B044000058
+:10DDE00038490000B04400004E44000067C50300FD
+:10DDF0004AC444004A4480004AC444004A44800063
+:10DE0000D60603000000DA06080008005F36291F66
+:10DE10005F36291F5F36291F5F36291F000000006B
+:10DE200000000000000000000000000000000000F2
+:10DE300000000000000000000000000004000000DE
+:10DE400000000000040000000800000001000000C5
+:10DE500005000000090000000D0000004D0000005A
+:10DE60008D0000000D0000004D0000008D0000003E
+:10DE7000CD0000005200000092000000D20000001F
+:10DE8000D60000001601000016050000160900006B
+:10DE900056090000560D00005611000096110000B2
+:10DEA000965100009691000096D100009611010055
+:10DEB0000000000000000000000000000000000062
+:10DEC000000000000000000004000000000000004E
+:10DED0000400000008000000010000000500000030
+:10DEE000090000000D0000004D0000008D00000042
+:10DEF0000D0000004D0000008D000000CD0000006E
+:10DF00005200000092000000D2000000D600000085
+:10DF10001601000016050000160900005609000051
+:10DF2000560D000056110000565100005691000099
+:10DF300056D10000561101005651010056910100C2
+:10DF400056D10100000000000000000000000000A9
+:10DF500000000000000000000000000000000000C1
+:10DF600000000000000000000000000000000000B1
+:10DF700000000000000000000000000000000000A1
+:10DF80000000000000000000000000000000000091
+:10DF90000000000000000000000000000A0009006E
+:10DFA000060005000A000900060005000A00090035
+:10DFB000060005000A000900060005000A00090025
+:10DFC000060005000A000900060005000A00090015
+:10DFD000060005000A000900060005000A00090005
+:10DFE000060005000A000900060005000A000900F5
+:10DFF000060005000A000900060005000A000900E5
+:10E00000060005000A000900060005000A000900D4
+:10E01000060005000A000900060005000E000000C9
+:10E0200000020003000400060008000B00100110AD
+:10E030000210031004100510061007100717072020
+:10E04000072D074000000000000000000000000055
+:10E0500000000000000000000000000000000000C0
+:10E0600000020003000400060008000B001001106D
+:10E0700002100310041005100610071007170720E0
+:10E08000072D074000000000000000000000000015
+:10E090000000000000000000000000000000000080
+:10E0A0000000000000000000000000000000000070
+:10E0B0000000000000000000000000000000000060
+:10E0C0000000000000000000000000000000004010
+:10E0D0000000000000000000000000000000000040
+:10E0E0000000000000000000000000000000000030
+:10E0F0000000000000000000000000000000000020
+:10E10000000000000000000000000000000000000F
+:10E1100000000000000000000000000000000000FF
+:10E1200000000000000000000000000000000000EF
+:10E1300000000000000000000000000000000000DF
+:10E1400000000000000000000000000000000000CF
+:10E1500000000000000000000000000000000000BF
+:10E1600000000000000000000000000000000000AF
+:10E170000000000000000000F8410100F82100004C
+:10E18000FB210000FB410000DBFE01007B210000C1
+:10E1900033210000EB400000A3FE01004B02000011
+:10E1A0004D014D014D014D014D014D014D014D01FF
+:10E1B0004D014D014D014D014D014D014D014D01EF
+:10E1C0004D014D014D014D014D014D014D014D01DF
+:10E1D0004D014D014D014D014D014D014D014D01CF
+:10E1E0004D014D014D014D014D014D014D014D01BF
+:10E1F0004D014D014D014D014D014D014D014D01AF
+:10E200004D014D014D014D014D014D014D014D019E
+:10E210004D014D014D014D014D014D014D014D018E
+:10E22000090F1418FE070B0FFBFE0105080B0E115A
+:10E230001417000000000000000306090C0F120074
+:10E240000000000000000000000306090C0F12157A
+:10E25000181B00000000000003EB0000010010008C
+:10E26000100020000100300010004000220050008B
+:10E27000220160002202700022038000220490002C
+:10E280002205A0002206B0002207C0002208D0000C
+:10E290002209F000220A1000220B2000220C30007C
+:10E2A000220D4000220E5000220F600000000000EE
+:10E2B000000000000000000000000000000000005E
+:10E2C000000000000000000000000000040000004A
+:10E2D0000000000004000000080000000100000031
+:10E2E00005000000090000000D0000004D000000C6
+:10E2F0008D0000000D0000004D0000008D000000AA
+:10E30000CD0000004F0000008F000000CF00000093
+:10E31000D3000000130100001305000013090000E2
+:10E3200053090000530D0000531100009311000029
+:10E33000935100009391000093D1000093110100CC
+:10E3400000000000000000000000000000000000CD
+:10E3500000000000000000000400000000000000B9
+:10E36000040000000800000001000000050000009B
+:10E37000090000000D0000004D0000008D000000AD
+:10E380000D0000004D0000008D000000CD000000D9
+:10E390004F0000008F000000CF000000D3000000FD
+:10E3A00013010000130500001309000053090000C9
+:10E3B000530D000053110000535100005391000011
+:10E3C00053D100005311010053510100539101003A
+:10E3D00053D1010000000000000000000000000018
+:10E3E000000000000000000000000000000000002D
+:10E3F000000000000000000000000000000000001D
+:10E40000000000000000000000000000000000000C
+:10E4100000000000000000000000000000000000FC
+:10E4200000000000000000000000000001040204E1
+:10E4300003040404050406040704080409040A0488
+:10E440008B058C058D058E058F059000910092003F
+:10E4500093019401950196019701980199019A0100
+:10E460009B019C019D019E019F01A001A101A201B0
+:10E47000A301A401A50100000101010101010101A5
+:10E48000010101010101010101010101010101017C
+:10E490000101010101010203010302010101010166
+:10E4A000010101010101010101010101010101015C
+:10E4B000010101010101010101010101010101014C
+:10E4C000010101010101010101010101010101013C
+:10E4D0000101010101010203010302010101010126
+:10E4E000010101010101010101010101010101011C
+:10E4F0000101010101010101A0E101004000000052
+:10E50000020000000000000010000000F8E0010020
+:10E5100040000000010000000000000010000000AA
+:10E5200078E101000A0000000B000000000000007C
+:10E53000200000005CE20100140000000C0000005C
+:10E540000000000020000000C8E901009400000065
+:10E550000D00000000000000200000002CE401007D
+:10E56000260000000E000000000000001000000067
+:10E570009CDF0100400000000F00000000000000D0
+:10E58000100000002CEC0100100000001000000042
+:10E59000000000000800000020E201003C00000034
+:10E5A000110000000000000008000000ACE20100C3
+:10E5B00060000000120000000000000020000000C9
+:10E5C00078E401008000000014000000000000005A
+:10E5D0000800000010E601009A000000170000008B
+:10E5E000000000001000000020E001006C000000AE
+:10E5F00000000000000000001000000044E70100DF
+:10E60000A000000018000000000000002000000032
+:10E610001A0034004E0068009C00D000EA0004019B
+:10E62000340068009C00D0003801A001D401080229
+:10E630004E009C00EA003801D4017002BE020C03B7
+:10E640006800D0003801A00170024003A803100444
+:10E6500018009C00D0000401EA0038018601D000B7
+:10E660000401040138016C016C01A001380186012C
+:10E670008601D401220222027002040138016C01D9
+:10E6800038016C01A001D401A001D40108020802E4
+:10E690003C028601D4012202D40122027002BE0291
+:10E6A0007002BE020C030C035A0336006C00A20079
+:10E6B000D8004401B001E6011C026C00D8004401FE
+:10E6C000B00188026003CC033804A2004401E601D3
+:10E6D0008802CC031005B2055406D800B0018802A8
+:10E6E00060031005C0069807700818004401B001C7
+:10E6F0001C02E60188022A03B0011C021C028802E7
+:10E70000F402F402600388022A032A03CC036E0495
+:10E710006E0410051C028802F4028802F4026003F1
+:10E72000CC036003CC0338043804A4042A03CC03CC
+:10E730006E04CC036E041005B2051005B205540634
+:10E740005406F6060000080000000800000008005B
+:10E750000000080000000800000008000000080099
+:10E760000000080000000800000008000000080089
+:10E770000000080000000800000008000000080079
+:10E780000000080000000800000008000000080069
+:10E790000000080000000800000008000000080059
+:10E7A0000000080000000800000008000000080049
+:10E7B0000000080000000800000008000000080039
+:10E7C0000000080000000800000008000000080029
+:10E7D0000000080000000800000008000000080019
+:10E7E0000000080000000800000008000000080009
+:10E7F00000000800000008000000080000000800F9
+:10E8000000000800000008000000080000000800E8
+:10E8100000000800000008000000080000000800D8
+:10E8200000000800000008000000080000000800C8
+:10E8300000000800000008000000080000000800B8
+:10E8400000000800000008000000080000000800A8
+:10E850000000080000000800000008000000080098
+:10E860000000080000000800000008000000080088
+:10E870000000080000000800000008000000080078
+:10E880000000080000000800000008000000080068
+:10E890000000080000000800000008000000080058
+:10E8A0000000080000000800000008000000080048
+:10E8B0000000080000000800000008000000080038
+:10E8C0000000080000000800000008000000080028
+:10E8D0000000080000000800000008000000080018
+:10E8E0000000080000000800000008000000080008
+:10E8F00000000800000008000000080000000800F8
+:10E9000000000800000008000000080000000800E7
+:10E9100000000800000008000000080000000800D7
+:10E9200000000800000008000000080000000800C7
+:10E9300000000800000008000000080000000800B7
+:10E9400000000800000008000000080000000800A7
+:10E950000000080000000800000008000000080097
+:10E960000000080000000800000008000000080087
+:10E970000000080000000800000008000000080077
+:10E980000000080000000800000008000000080067
+:10E990000000080000000800000008000000080057
+:10E9A0000000080000000800000008000000080047
+:10E9B0000000080000000800000008000000080037
+:10E9C000000008000500000000000000000000003A
+:10E9D0000000001000000000000000200000000007
+:10E9E00000000030000000000000004000000000B7
+:10E9F0000000005000000000000000600000000067
+:10EA00000000007000000000000000800000000016
+:10EA10000000009008000000000000A008000000B6
+:10EA2000000000B008000000000000C00800000066
+:10EA3000000000D008000000000000E00800000016
+:10EA4000000000F0080000000000000009000000C5
+:10EA50000000001009000000000000201900000064
+:10EA60000000003019000000000000401900000004
+:10EA700000000050190000000000006019000000B4
+:10EA80000000007019000000000000801900000064
+:10EA90000000009019000000000000A01900000014
+:10EAA000000000B019000000000000C019000000C4
+:10EAB000000000D019000000000000E01900000074
+:10EAC000000000F019000000000000001A00000023
+:10EAD000000000101A000000000000201A000000D2
+:10EAE000000000301A000000000000401A00000082
+:10EAF0000000005002000000000000600200000062
+:10EB00000000007002000000000000800200000011
+:10EB10000000009002000000000000A002000000C1
+:10EB2000000000B002000000000000C00A00000069
+:10EB3000000000D00A000000000000E00A00000011
+:10EB4000000000F00A000000000000000B000000C0
+:10EB5000000000100B000000000000200B0000006F
+:10EB6000000000300B000000000000400B0000001F
+:10EB7000000000501B000000000000601B000000AF
+:10EB8000000000701B000000000000801B0000005F
+:10EB9000000000901B000000000000A01B0000000F
+:10EBA000000000B01B000000000000C01B000000BF
+:10EBB000000000D01B000000000000E01B0000006F
+:10EBC000000000F01B000000000000001C0000001E
+:10EBD000000000101C000000000000201C000000CD
+:10EBE000000000301C000000000000401C0000007D
+:10EBF000000000501C000000000000601C0000002D
+:10EC0000000000701C000000000000801C000000DC
+:10EC1000000000901C0000001CDE010060000000ED
+:10EC20001200000000000000200000005F36291FD5
+:10EC30005F36291F5F36291F5F36291F0CDE010052
+:10EC4000100000001000000000000000080000009C
+:10EC500090E8860000008000010000000000000035
+:10EC600000000000000000007363616E00000000FF
+:10EC700044EB86000100204005000000A2A58600AC
+:10EC8000020020400500000090A5860003002040FF
+:10EC9000050000007EA5860004002040050000005D
+:10ECA000759986000500104005000000EBE886001D
+:10ECB00006002040020000004CEB86000C00000023
+:10ECC000010000005EEB8600070020000800000045
+:10ECD0000000000000000000000000006E6F637282
+:10ECE00063005344494F0043444300000D16800025
+:10ECF0008D13800025118000291480001D138000D1
+:10ED0000A1168000E1EA0000011380002D138000AD
+:10ED1000000000001D16800005000000FFFFFFFF3F
+:10ED20001400000005000000FFFFFFFF05000000C9
+:10ED300005000000050000000E0E0E0E0E02090D6B
+:10ED40000A080D01090D0A080D01090D0A080D0137
+:10ED5000090D0A080D01090E0A090E060A0E0B0913
+:10ED60000E02093A160E0E05093A160E0E050A0E87
+:10ED70000B090E050A0E0B090E020A0E0B090E02F4
+:10ED800014C0C015110514C0C015110514C0C0155C
+:10ED9000110514C0C015110514C0C0151105093A9C
+:10EDA000160E0E0514C0C015110514C0C0151105AE
+:10EDB000093A160E0E05093A160E0E05093A160EF8
+:10EDC0000E0514C0C0151105093A160E0E05093AB4
+:10EDD000160E0E05093A160E0E0509B21C0E0E058A
+:10EDE00012B119111108000000000000000000001D
+:10EDF0000000000019300200F52F0200E12F020090
+:10EE000055AA80000000000021AA800085AA800089
+:10EE100031AA80006DAA8000C993800095A9800066
+:10EE2000BDA98000D5938000B593800075938000C4
+:10EE3000D191800000000000B1A98000736470636C
+:10EE40006D6465760000000000000000F4ED010034
+:10EE500000000000000000000000000000000000B2
+:10EE60000000000000000000776C000000000000BF
+:10EE70000000000000000000F0250000000000007D
+:10EE80000000000000000000000000000000000082
+:10EE900000000000F918010DE400F4DEF106FC0F9B
+:10EEA00027FAFF1DF01018090AF210E017140411D8
+:10EEB00014F1FAF2DBF7FCE2FBE1EE130DFF1CE9C3
+:10EEC0001A17180300DAE803E617E4E9F3FF121350
+:10EED00005E104E225F706F2ECF1FC11E914F0E09B
+:10EEE000F6F2E8091010011DD9FA040F0F060CDE26
+:10EEF0001C00FF0D07181AF60EE4160FF905EC18A2
+:10EF00001B0A1EFF0026E2FFE50A14180705EA0F98
+:10EF1000F2E4E6F608080808080808090A080807DD
+:10EF200007010202020202020202020202020202BD
+:10EF30000202020201010000000000000000C50101
+:10EF40001DFFE0FFC0FFE0FF0000000000FF000029
+:10EF500000006B0382FEE7FFCCFFE7FF0800020022
+:10EF60000000D7010BFFEEFFDCFFEEFFA7033CFE26
+:10EF7000ECFF1700ECFF720385FEAEFEF801AEFE5B
+:10EF8000070004000000980160FFCBFF96FFCBFF55
+:10EF90009C0345FE2500C1FF2500B10316FEE4FEDB
+:10EFA000A501E4FE07000000010000006C0900005C
+:10EFB0000B0A00070A88888002000000710900001F
+:10EFC0000B0A00070A888880030000007609000009
+:10EFD0000B0A00070A888880040000007B090000F3
+:10EFE0000B0A00070A8888800500000080090000DD
+:10EFF0000B0A00070A8888800600000085090000C7
+:10F000000B0A00070A888880070000008A090000B0
+:10F010000B0A00070A888880080000008F0900009A
+:10F020000B0A00070A888880090000009409000084
+:10F030000B0A00070A8888800A000000990900006E
+:10F040000B0A00070A8888800B0000009E09000058
+:10F050000B0A00070A8888800C000000A309000042
+:10F060000B0A00070A8888800D000000A80900002C
+:10F070000B0A00070A8888800E000000B40900000F
+:10F080000B0A00070A88888000000000A200000028
+:10F0900000FF00FF00000000000000FF0000000073
+:10F0A0007802A0FE80FF00FF80FF08000100000042
+:10F0B000760179FFF0FFE0FFF0FF1F0374FECEFF43
+:10F0C000E0FFCEFFEE022BFE2CFF32002CFF0800EB
+:10F0D00002000000770116FFDBFFB4FFDBFF1F0318
+:10F0E00074FEE0FFECFFE0FFEC02F2FE80FF1E008A
+:10F0F00080FF080003000000770116FFDBFFB4FF6C
+:10F10000DBFF1F0374FEE0FFECFFE0FFEC02F2FE0A
+:10F110006CFF23006CFF0800040000003301AEFF09
+:10F12000CBFF96FFCBFF0B0385FECBFF0A00CBFF87
+:10F13000FD022BFE2CFFCA002CFF0800140001006A
+:10F14000BF0131FFF20049FEF200870361FE33FF89
+:10F15000620133FF800378FEDAFEE900DAFE080080
+:10F1600015000100BF0131FF18010EFE18018703D1
+:10F1700061FE16FF7C0116FF800378FE8FFF93006F
+:10F180008FFF090016000100BF0131FF620055FF2B
+:10F190006200870361FE1FFF6B011FFF79037EFE84
+:10F1A000F4FE5D00F4FE080017000100BC0131FF11
+:10F1B000740042FF7400870361FE52FF020152FF98
+:10F1C000800378FE7FFFF1FF7FFF08001800010039
+:10F1D000B40131FFDFFF1D00DFFF880361FE87FF01
+:10F1E00090FF87FF7F0378FECDFEF401CDFE08007F
+:10F1F00019000100AD0131FFB8FF3E00B8FF8203E6
+:10F2000061FEAAFFB1FFAAFF7F0378FEC7FEFE01E1
+:10F21000C7FE08001A000100930154FFD9FF0C003B
+:10F22000D9FF1B03C7FE4CFF38004CFF3303B8FE69
+:10F2300080FF280080FF08001B000100890154FFA7
+:10F24000CFFF1300CFFF1703C7FE00FF500000FFE2
+:10F250002E03BDFE8BFF25008BFF08001E00010062
+:10F26000BB0119FFC3FF1D00C3FF6B0361FE66FFF7
+:10F27000480066FF7C0378FE56FF4F0056FF0800EB
+:10F280002C000100BF0131FFE00071FEE0008703A8
+:10F2900061FE8BFFC4008BFF800378FEB2FEC000CE
+:10F2A000B2FE0800000001009F01520740008000EC
+:10F2B0004000180378064000800040000A032E0634
+:10F2C0004000800040000800010001009201370763
+:10F2D00003013B0003019F02020744003600440083
+:10F2E000600247075D00A7005D0008000200010002
+:10F2F0009F01520740008000400018037806C000BC
+:10F300008001C0000A032E06400080004000080073
+:10F31000030001002E0131078100020181009202E9
+:10F32000B806CD009A01CD00F202E006AA00540111
+:10F33000AA0008001400010068015CFFF200C6FE8C
+:10F34000F200F002B8FE33FFCB0033FFFF02E0FE15
+:10F3500003FF49FF03FF08001500010068015CFF7F
+:10F36000950052FF9500F002B8FE33FFA40033FF72
+:10F37000FF02E0FE00FFEFFE00FF080016000100A4
+:10F3800068015CFF62009CFF6200F002B8FE33FF80
+:10F390007C0033FFFF02E0FE00FFA0FE00FF08003C
+:10F3A000170001005E015CFF8CFF52008CFFF00231
+:10F3B000B8FE33FF280033FFFF02E0FE7FFF15FF9A
+:10F3C0007FFF08001800010045015CFFE0FFD8FF47
+:10F3D000E0FFF402B8FE00FF29FE00FFFE02E0FE9F
+:10F3E000FAFEAA00FAFE0800190001002B015CFFDA
+:10F3F000CDFFC0FFCDFFE002B8FE00FF29FE00FFF9
+:10F40000FD02E0FEFAFEAA00FAFE08001A00010062
+:10F41000150197FFD9FF8BFFA8FF7D022EFFC0FFCC
+:10F4200040FF70FF660248FF80FF80FEE0FE08009C
+:10F430001B000100F50097FFCFFF6DFF92FF7202E6
+:10F440002EFF5EFF1BFE95FE650248FFC2FF46FFD2
+:10F4500075FF08001E0001002E0131FFC3FF86FF6B
+:10F46000C3FF9202B8FE33FF66FE33FFF202E0FEF6
+:10F4700056FFACFE56FF08002800010068015CFF43
+:10F48000F200C6FEF200F002B8FECD0035FFCD005E
+:10F49000FF02E0FEFF017201FF0108000501000804
+:10F4A0000001FFFF0000000000000000000000005D
+:10F4B000000000000000000000000000000000004C
+:10F4C000000000000000000000000000000000003C
+:10F4D000000000000000000000000000000000002C
+:10F4E000000000000000000000000000000000001C
+:10F4F000000000000000000000000000000000000C
+:10F5000000000000000000000000000000000000FB
+:10F5100000000000000000000000000000000000EB
+:10F5200000000000000000000000000000000000DB
+:10F5300000000000000000000000000000000000CB
+:10F5400000000000000000000000000000000000BB
+:10F5500000000000000000000000000000000000AB
+:10F56000000000000000000000000000000000009B
+:10F57000000000000000000000000000000000008B
+:10F58000000000000000000000000000000000007B
+:10F59000000000000000000000000000000000006B
+:10F5A000000000000000000000000000000000005B
+:10F5B000000000000000000000000000000000004B
+:10F5C000000000000000000000000000000000003B
+:10F5D000000000000000000000000000000000002B
+:10F5E000000000000000000000000000000000001B
+:10F5F000000000000000000000000000000000000B
+:10F6000000000000000000000000000000000000FA
+:10F6100000000000000000000000000000000000EA
+:10F6200000000000000000000000000000000000DA
+:10F6300000000000000000000000000000000000CA
+:10F6400000000000000000000000000000000000BA
+:10F6500000000000000000000000000000000000AA
+:10F66000000000000000000000000000000000009A
+:10F67000000000000000000000000000000000008A
+:10F68000000000000000000000000000000000007A
+:10F69000000000000000000000000000000000006A
+:10F6A000000000000000000000000000000000005A
+:10F6B000000000000000000000000000000000004A
+:10F6C000000000000000000000000000000000003A
+:10F6D000000000000000000000000000000000002A
+:10F6E000000000000000000000000000000000001A
+:10F6F000000000000000000000000000000000000A
+:10F7000000000000000000000000000000000000F9
+:10F7100000000000000000000000000000000000E9
+:10F7200000000000000000000000000000000000D9
+:10F7300000000000000000000000000000000000C9
+:10F7400000000000000000000000000000000000B9
+:10F7500000000000000000000000000000000000A9
+:10F760000000000000000000000000000000000099
+:10F770000000000000000000000000000000000089
+:10F780000000000000000000000000000000000079
+:10F790000000000000000000000000000000000069
+:10F7A0000000000000000000000000000000000059
+:10F7B0000000000000000000000000000000000049
+:10F7C0000000000000000000000000000000000039
+:10F7D0000000000000000000000000000000000029
+:10F7E0000000000000000000000000000000000019
+:10F7F0000000000000000000000000000000000009
+:10F8000000000000000000000000000000000000F8
+:10F8100000000000000000000000000000000000E8
+:10F8200000000000000000000000000000000000D8
+:10F8300000000000000000000000000000000000C8
+:10F8400000000000000000000000000000000000B8
+:10F8500000000000000000000000000000000000A8
+:10F860000000000000000000000000000000000098
+:10F870000000000000000000000000000000000088
+:10F880000000000000000000000000000000000078
+:10F890000000000000000000000000000000000068
+:10F8A0000000000000000000000000000000000058
+:10F8B0000000000000000000000000000000000048
+:10F8C0000000000000000000000000000000000038
+:10F8D0000000000000000000000000000000000028
+:10F8E0000000000000000000000000000000000018
+:10F8F00083682DE9F0415B690546152B0F460AD058
+:10F90000182B08D01B2B06D0242B01D0272B04D179
+:10F910002B8A7F2B05D80C2304E0172B01D0182B42
+:10F9200001DD1423AB624FF004430022BB6100E011
+:10F930000132BB69002B03DA1D4B9A42F8D134E047
+:10F940001C4B9A4231D8AE6A3C69331DAB83AC6123
+:10F95000A868298AE1F3DAF4022390FBF3F014F4A7
+:10F96000807F68840AD0284639463246E1F3E6F4BF
+:10F97000C0F30F1083B2E8832B8403E0AB8B2B849E
+:10F980006B8CEB83AB6913F4007F0AD0AA6A28461C
+:10F9900039460132E1F3D2F4C0F30F1083B2688428
+:10F9A00000E02B8CAB842B8AEB84BDE8F081C04651
+:10F9B000809698007F96980070B50446E1F3D0F2E7
+:10F9C000002144220546E2F33BF36369152B2B60CB
+:10F9D00001D0162B01D9104B6B60686808B9054639
+:10F9E00017E0AC602046EBF385F3E8602046EBF3CC
+:10F9F00049F3064618B920460121EBF381F36B6801
+:10FA000020469B68984705461EB920463146EBF3D1
+:10FA100077F3284670BDC046ECEC01000523C0F822
+:10FA200094310223C0F898311E33C0F89C31234B27
+:10FA30004FF010021B68002B0CBF07230023C0F8F7
+:10FA4000A0314FF00103C0F8AC3103F16303C0F8FB
+:10FA5000B0314FF00603C0F8C03140F23C73C0F83B
+:10FA6000C4314FF00803C0F8C83103F10D03C0F8EA
+:10FA7000A421C0F8B821C0F8BC21C0F8CC31C0F82E
+:10FA8000D02101D1032302E00D4B1B68013BC0F8DC
+:10FA9000D4311C230422C0F8DC310C23C0F8E0313F
+:10FAA0009B18C0F8E4310623C0F8EC310023C0F8FD
+:10FAB000D821C0F8E821C0F8F0317047EC260000EA
+:10FAC000D4250000D0F8101270B5044609B90D46CF
+:10FAD0000CE08068E3F368F0D4F810120546E822E1
+:10FAE000A068E7F305F10023C4F81032284670BD82
+:10FAF00070B50024054680F87541006903F0F0FAFE
+:10FB00002846EAF3D9F0E8682146EBF393F1D5F8FB
+:10FB1000900128B1E6F3D2F3D5F89001E6F318F49A
+:10FB2000D5F88C0128B1E6F3C9F3D5F88C01E6F3DA
+:10FB30000FF4E86805F070FBD5F8103223B11B789C
+:10FB400013B12846FFF7BEFFA86829464FF4077295
+:10FB5000E7F3CEF070BDC0461FB5044606238068AB
+:10FB6000E8210393E7F3B4F0C4F8100210B94FF0A2
+:10FB7000FF300CE00021E822E2F362F20023009360
+:10FB8000A068D4F8101203AA1C33E3F3A5F004B064
+:10FB900010BDC0462DE9F0478AB01F46129D9C4B10
+:10FBA00008461D6011469046EAF308F0002800F070
+:10FBB0002A8138464FF40771E7F38AF0044600289B
+:10FBC00000F0218100214FF407720646E2F338F27B
+:10FBD000A76065612046FFF721FF8E4B1B68C4F8C4
+:10FBE0000C320BB99A4605E01B78B3F1000A18BF36
+:10FBF0004FF0010A884B04F128001A680121002AFD
+:10FC000014BF31221122E3F339F100230093019351
+:10FC10000293404639462A46139B05F03BFCE060C0
+:10FC2000002800F0EA80EBF31DF12060E068EBF3C0
+:10FC300037F1656960606B68784A83F00103784941
+:10FC400003F00103002B0CBF88469046226884F81D
+:10FC5000763140F629039A42D4F80890D4F80CC0C3
+:10FC60000AD120B905F5007E05F5047508E005F513
+:10FC7000007E05F5087503E005F5007E05F50475C1
+:10FC8000D4F8B831D4F8BC21D4F8C411D4F8C001E8
+:10FC900001934FF0FF33049309330693002302923C
+:10FCA0000391059007934846414662467346009586
+:10FCB000EFF74AF96062002800F09F80D4F80C1238
+:10FCC000C1B10B78B3B1E4F393F756492246D4F8A7
+:10FCD0000C02E2F355F7D4F80C0253492246E2F342
+:10FCE00089F7BAF1000F05D02046FFF735FF00284D
+:10FCF00040F0838001210A46606AE4F381F72046E0
+:10FD00000021E2683B4603F0F7F92061002874D037
+:10FD100000210B462046454AE6F33CF30023C4F895
+:10FD2000900184F879314248E7F3A0F718B3E2F381
+:10FD3000CFF3012383403F48C4F88031E7F396F7BF
+:10FD400010B1E2F3C5F308B1D4F88001C4F884011E
+:10FD500039490020E2F310F6030CA4F888319BB275
+:10FD6000A4F88A013BB100212046344A0B46E6F351
+:10FD700011F3C4F88C0100203149E2F3FDF50128AC
+:10FD800009D184F816022F490138E2F3F5F501286C
+:10FD900004BF2D4B18602046E9F370F520B3002511
+:10FDA000C4F8A05128462949E2F3E6F528B1012319
+:10FDB00084F8F9312648EFF781F928462549E2F31E
+:10FDC000DBF588B123492846E2F3D6F54FF080737E
+:10FDD00000F00F000AA901F8010D4FF440720093E2
+:10FDE00020460F23E2F7A2FF1B481C492246E6F3F8
+:10FDF00081F61B48EAF7FCFA06E0A06821464FF4BA
+:10FE00000772E6F375F7002630460AB0BDE8F087C2
+:10FE1000F4260000BC260000EC260000AE27860079
+:10FE2000B6278600DD9B80005929000065A680006A
+:10FE3000052886000E28860017288600499B80002A
+:10FE40001F28860028A80100A8F401002A2886009F
+:10FE50003428860039A801004D288600E59A8000E4
+:10FE6000D596800010B5044660B10368064918684D
+:10FE7000224604F069D82368214658684FF4BC72C2
+:10FE8000E6F336F710BDC046853B86007FB50546D4
+:10FE90004FF4BC714068E6F31BF708B9064619E059
+:10FEA00000214FF4BC720646E2F3CAF00B4B3560FA
+:10FEB00000930B4B002401932868334609490A4AF2
+:10FEC0000294039404F008D84FF49663C6F86031A6
+:10FED00086F86441304604B070BDC046C5EB0000F2
+:10FEE0000531000060A80100853B860041F2E44333
+:10FEF000984201D00020AFE044F22033994200F054
+:10FF0000AA800533994200F0A680223B994200F076
+:10FF1000A2801E33994200F09E800333994200F084
+:10FF20009A800C3B994200F096800133994200F090
+:10FF300092800133994200F08E80093B994200F093
+:10FF40008A800233994200F08680013B994200F09A
+:10FF50008280023399427ED0013399427BD00133B3
+:10FF6000994278D00533994275D00133994272D0C5
+:10FF7000013399426FD001F53C43D8339BB2022B39
+:10FF800069D94BF6D543CB189BB2022B63D944F207
+:10FF9000413399425FD0013B99425CD001F53C432B
+:10FFA000B0339BB2022B56D944F25333994252D00C
+:10FFB000043399424FD04AF69D1399424BD044F2F4
+:10FFC0005433994247D0253B994244D0013B994252
+:10FFD00041D0063399423ED0013399423BD00133A0
+:10FFE000994238D04BF6C943CB189BB2022B32D979
+:10FFF00044F2167399422ED0113399422BD0A3F5B7
+:020000022000DC
+:100000007973994227D001F53C43A0339BB2012B71
+:1000100021D901F53C43BA339BB2022B1BD94BF6D5
+:10002000CF43CB189BB2012B15D94BF6AB43CB1862
+:100030009BB2012B0FD901F53C43A8339BB2012B96
+:1000400009D944F26333994205D00D33994214BF64
+:100050000020012000E001207047C0462DE9F84F44
+:1000600000264FF0010842F601334FF0FF344FF005
+:10007000640B0746A0F8283680F8474680F8C44449
+:100080000221224680F8288080F868B780F842660E
+:1000900080F84C8680F8436680F8498680F846668A
+:1000A00005F066DC38464146324605F061DC0C213D
+:1000B0002246384605F05CDC0B213846324605F016
+:1000C00057DC0E212246384605F052DC0D21384619
+:1000D000324605F04DDC0F212246384605F048DC5B
+:1000E00004210222384605F043DCD7F860364FF091
+:1000F000030987F8488683F80690D7F860364FF0F2
+:10010000020A83F8079040F62A13A7F82A36A7F8C0
+:100110002C369BB2A7F82E3640F62A13A7F83036B5
+:10012000A7F83236A7F83436A7F8363640F62B1340
+:10013000A7F838363B68A7F87A6583F895604FF0E2
+:100140000703A7F83A364FF00403A7F83C360F230D
+:1001500087F80C37D7F89034A7F83E96C7F8803266
+:10016000A7F840A6A7F87C68A7F87EB887F8EA61E8
+:1001700087F8EB6187F81E6287F8EE6187F8EC611B
+:1001800087F8FA8187F80B6787F8A0649E71D7F823
+:1001900094340B22C7F8843283F80680D7F8983459
+:1001A0003146C7F8883283F806A0D7F89C34354624
+:1001B000C7F88C3283F806903B6887F8506783F85D
+:1001C0004D805C633B6807F5CC6483F842803B68F4
+:1001D000043483F843603B6887F8CF6183F8396063
+:1001E0003B68204683F8AA803B6887F8DF6187F880
+:1001F000E081C7F8E46187F8E161DE66E1F320F7AA
+:100200006FF0220387F864362C3387F865364A4648
+:1002100004EB0A001A49E1F3AFF63B6887F869A6D8
+:1002200087F8568587F8578583F84C603A6887F8D1
+:100230009267A7F89067A7F88CB892F8463013F049
+:10024000030F0CD092F94C304BB1D7F8FC0424309A
+:10025000F4F3FEF7D7F8FC043230F4F3F9F74FF477
+:100260004873A7F85C373B68012287F8252883F894
+:10027000A2203A684FF0FF3382F8B530BDE8F88F1E
+:10028000C3A60100836B70B5002483F84C40C36B98
+:10029000012583F84C500646816BE3F799F9F16B21
+:1002A0003046E3F795F921463046F9F351F5B36B43
+:1002B000304683F84D40F36B294683F84D40D6F81D
+:1002C00060364FF0FF34DD72D6F860369C81F9F36A
+:1002D0003FF5D6F860369B78AB4214D9B36B83F800
+:1002E0004D40F26B4FF0FF3382F84D3096F8CB342F
+:1002F00096F8CC2443EA022343F0800386F8CB34FB
+:100300001B0A86F8CC3470BDD0F8AC1110B5044689
+:1003100029B18068EFF3B4F10023C4F8AC31D4F80C
+:10032000C41129B1A068EFF3ABF10023C4F8C431C4
+:10033000D4F8741529B1A068EFF3A2F10023C4F832
+:100340007435D4F8F81629B1A068EFF399F10023B9
+:10035000C4F8F836D4F8FC1629B1A068EFF390F190
+:100360000023C4F8FC36D4F8E036196A31B1A0682D
+:10037000EFF386F1D4F8E02600231362D4F83C159D
+:1003800029B1A068EFF37CF10023C4F83C35D4F820
+:10039000941729B1A068EFF373F10023C4F89437E0
+:1003A000D4F8B01829B1A068EFF36AF10023C4F8BB
+:1003B000B03810BD70B505462D4980682A46002327
+:1003C000EFF37AF1C5F8AC0100284ED0A8682949AE
+:1003D0002A460023EFF370F1C5F8C401002844D089
+:1003E000A86825492A460023EFF366F1C5F874058D
+:1003F00000283AD0A86821492A460023EFF35CF18F
+:10040000C5F8F806002830D0A8681D492A46002300
+:10041000EFF352F1C5F8FC0638B3A86819492A462B
+:100420000023D5F8E046EFF347F12062E8B1A86871
+:1004300015492A460023EFF33FF1C5F83C05A0B16A
+:10044000A86812492A460023EFF336F1C5F894074D
+:1004500058B1A8680E492A460023EFF32DF1C5F8DC
+:10046000B008003818BF012000E0002070BDC04671
+:100470003DAA81003D708100253E8100959181005B
+:10048000858F8100256E810089598100396B81003B
+:10049000496F810010B50446006805F0A7FFD4F845
+:1004A000480120B105F078FA0023C4F84831D4F8A7
+:1004B000583113B10023C4F85831D4F83C0120B1AD
+:1004C00005F008FA0023C4F83C31D4F8400120B10B
+:1004D00001F078F80023C4F84031D4F84C0120B181
+:1004E00002F0EEF80023C4F84C31D4F8540120B1E6
+:1004F00005F0A6FA0023C4F85431D4F8600120B105
+:1005000007F0EAF80023C4F86031D4F8383113B1A9
+:100510000023C4F83831D4F8640120B102F008F89F
+:100520000023C4F86431D4F8000520B107F010FAB4
+:100530000023C4F80035204605F0BEFB10BDC046C0
+:100540002DE9F041054608B9074695E001F068FC41
+:100550000746284605F06ADB00B90137D5F8F016E2
+:1005600049B16868D5F8F426E6F3C2F30023C5F86C
+:10057000F436C5F8F0362846D5F81815FCF38AF29B
+:100580002846D5F8D816FCF385F2D5F8201528466C
+:10059000FCF380F2D5F82C1521B168684FF496620F
+:1005A000E6F3A6F3D5F87C0220B105F03DFB00236D
+:1005B000C5F87C3200242B19D3F84C1211B128460F
+:1005C0001EF03ADF0434202CF5D10121284635F005
+:1005D000C9D8284601F082FF2E6BB16911B12846B7
+:1005E00034F054DB0024B461D5F85C0105F066FA00
+:1005F0002846FFF789FE2846FFF74CFF2846D5F826
+:100600002C18E2F7DDFFC5F82C48D5F8B84404E013
+:1006100068681022E468E6F36BF32146002CF7D1FA
+:10062000C5F8B844286816492A4603F08DDCD5F889
+:10063000340718B101F008F9C5F83447D5F8680156
+:1006400018B107F0AFF8C5F86841D5F8181759B1D7
+:100650006868D5F81C27E6F34BF3C5F8184703E0A4
+:10066000284669680AF0B0DBD5F87822002AF7D16D
+:100670002846696800F02CFD3846BDE8F081C04688
+:10068000BB5C8600036870B55E6905461449304658
+:10069000E2F372F1C0B218B930461249E2F36CF1DC
+:1006A00040B2431E0E2B0ED8012803D1D5F8603678
+:1006B000002204E0022806D1D5F8603601229A71A2
+:1006C000D5F86036DA71084930462C6BE2F354F104
+:1006D00084F804012846F2F3EFF4012070BDC0460F
+:1006E000C65C8600CB5C86000E5D8600036870B534
+:1006F0001B490546D0F860465869E2F33DF1207089
+:100700002B6818495869D5F86046E2F335F1E07076
+:10071000D5F8602613780BB10F2B01D1012313708C
+:10072000D5F8603601211A785A70D5F8604620460F
+:10073000E1F3DEF6A070D5F86026D3780BB10F2B6D
+:1007400001D10123D370D5F860360121DA781A710E
+:10075000D5F86046E01CE1F3CBF6607170BDC04691
+:10076000EBA80100F3A8010070B50446214600681B
+:1007700007F0FCF8C4F8000508B9293061E02068EA
+:1007800005F03CFE2068214601F082F8C4F83407E9
+:1007900008B92A3055E02B4B2046C4F8583105F0F3
+:1007A000B3F8C4F83C0108B931304AE0204600F003
+:1007B00043FFC4F8400108B9323042E0204606F059
+:1007C0009DFFC4F8600108B935303AE02068214641
+:1007D000A2681D4B05F044FAC4F87C0208B9393010
+:1007E0002FE0204601F0F4FEC4F8640108B93C3063
+:1007F00027E0164B0125C4F838310023A4F830381F
+:1008000084F8883884F88A3884F88958204605F0B6
+:10081000D5F8C4F8480108B9433012E023682146EE
+:1008200083F8A350236883F8A950236883F8A8505D
+:10083000206805F04BFA08B1452002E0236883F8F0
+:10084000A05070BDEFBEADDE9D6D8100EFBEAD0D61
+:10085000F0B5D0F840750021AC2287B00646384686
+:10086000E1F3EEF34FF06403FB85032387F8603078
+:1008700000220123D6F85C014FF42C5125F0D2DA86
+:10088000FF2804D1336B18691968EFF7EDFA316866
+:100890007886A6F8260691F84640336B00F440654A
+:1008A000FF201A8900211B68B5F5406F14BF14257D
+:1008B0002825019004F00304D6F860060091029404
+:1008C00003958078049007F1380030F0D7DB336867
+:1008D00093F8463013F0030F03D0FB8843F0200356
+:1008E000FB8007B0F0BDC0462DE9F04F8DB01A9FD8
+:1008F0009A46002307910B93064693461046179994
+:10090000189A199B9DF85890009709F075FA0446BB
+:1009100010B11E230B9375E304F082FE1798514625
+:100920000BAA00F003FD0546002800F06B83179A20
+:100930004FF0FF334260D0F86026D0F8008082F894
+:100940001C31836B86600363436BC8F804A0C362E9
+:10095000179BC0F87871C8F80C30B44B88F8219018
+:10096000C8F8B030032380F8693780F89D415146BC
+:10097000FFF774FB2846FBF323F2284605F0C0F985
+:100980000446002840F0478328463146179A5346CC
+:1009900006F028FFC5F8680108B91F23CAE2A44B76
+:1009A0000194009302940394A249A34A2B46286819
+:1009B00003F092DAA14B0194009302940394A049AE
+:1009C000A04A2B46286803F087DA189A199B179ECD
+:1009D00002920393284607995A465346CDF8009051
+:1009E0000196049701F06CFB04460B90002840F040
+:1009F00012832B69186EEAF7E5FAA5F8BE082846B7
+:100A0000F9F38EF008B9142394E2264631460AAA77
+:100A10002846FAF311F531462846BDF8282001365C
+:100A2000FAF314F5062EF1D1012488F89A4005F561
+:100A3000BE72286908F114011BF054DF8249D8F80E
+:100A40001400E1F399F781498146D8F81400E1F3E5
+:100A500093F77F49A5F86208D8F81400E1F38CF702
+:100A6000B5F86228A5F86408A5F87827A5F87A07EC
+:100A70007849D8F81400E1F37FF77749A5F85408CE
+:100A8000D8F81400E1F378F785F856087349D8F8D8
+:100A90001400E1F371F785F858087149D8F814008B
+:100AA000E1F36AF785F85A086E49D8F81400E1F3C3
+:100AB00063F785F857086C49D8F81400E1F35CF740
+:100AC00085F859086949D8F81400E1F355F785F815
+:100AD0005B086749D8F81400E1F34EF785F85C0825
+:100AE0006449D8F81400E1F347F785F85E086249D5
+:100AF000D8F81400E1F340F785F860085F49D8F8AA
+:100B00001400E1F339F785F85D085D49D8F8140061
+:100B1000E1F332F785F85F085A49D8F81400E1F399
+:100B20002BF785F861082846FFF7E0FDD5F8602629
+:100B30002B6B85F8F04785F8F14718691178D27862
+:100B4000EFF7E4FB2869EA6AD0F8A03005F5CB742A
+:100B50005360D0F8A43021469360D0F8A830D36019
+:100B6000D0F8AC301361D0F8B0305361D0F8B43065
+:100B700093611BF0E7DF08F14E0021463246E1F3B6
+:100B8000FBF1B5F8822144F221339A4217D00E3B93
+:100B90009A4214D007339A4211D010339A420ED0A1
+:100BA000143B9A420BD007339A4208D010339A4232
+:100BB00005D025339A4214BF0024012400E001240B
+:100BC00005EB84039B6B28462B63FFF75BFD08B99D
+:100BD0001823AFE1296B4FF00F0340F2FF36A1F865
+:100BE000063101F1FC0201F58073A1F80861284685
+:100BF00000F0C4FF2A6BD2F8FC30C2F8F830C2F81B
+:100C0000F030D2F80031C2F8F4301368022B07D16B
+:100C1000013B53752B6B284603215A7D04F0A8DE57
+:100C200019F0010F30D000222FE0C0461AC35A0538
+:100C300079DB810078D48500BB5C86002D4A0000FA
+:100C400044AA010010A90100D6688600E268860067
+:100C5000F5688600076986001C6986002B69860096
+:100C60003A698600496986005A6986006B69860080
+:100C70007C6986008A69860098698600A669860074
+:100C8000B6698600C6698600012288F846200A21D6
+:100C9000284604F06DDE296B28461C31FCF3C6F6AD
+:100CA0007F23296B00932B68002293F8463001F1D3
+:100CB0001C0003F0030301935031134630F01CDA9B
+:100CC000B4F1FF3F3FF45DAF2846F8F383F74FF4EC
+:100CD000D163C5F874382846FFF746FD04460B90EB
+:100CE000002840F0988128465146FFF763FB08B979
+:100CF00020231FE1284604F0EBFEC5F85C0108B98B
+:100D0000212317E12846FFF7A3FD2146AD4AAE4B4C
+:100D100028460094019506F0FBFDAC4B6E461A1D6B
+:100D200007CA1B6886E80700072128462A4609F0FB
+:100D30009DDF04212846A64AA64B0094019506F0A3
+:100D4000E7FD0028C5F88C0701DA2223F2E02846E7
+:100D500017990AF00FD808B96423EBE0C5F8040826
+:100D60004FF0FF3728469C499C4A9D4B009702F064
+:100D70004BD9C5F82C08002800F04D81284601F019
+:100D8000B7FB044608B12323D4E02B684FF00602DA
+:100D900093F8A130A8F86420012B04BF4023A8F8E1
+:100DA0006430D8F88C304FF006064FF439721E804C
+:100DB0005A80D8F890304FF0C4024FF0010605F584
+:100DC000007128461E805A8006310AF0A7DFD5F848
+:100DD0003C0110F031D808B185F8CF61022385F8C5
+:100DE000C0341C3385F8CB3410222B6B85F8CC240F
+:100DF0005B89022B02D81C2385F8CB342846214678
+:100E000085F8CA7485F8C97485F8C874F9F344F490
+:100E10002B68284683F8B4402146C5F8D471F4F312
+:100E200053F485F8DC412846FFF72CFA19F0080F37
+:100E300018BF85F8DC4119F0100F03D02846214671
+:100E4000F4F342F419F0020F13D0AB6B83F84D406A
+:100E5000EB6B83F84D4095F8CB3495F8CC2443EAFE
+:100E6000022323F080039BB285F8CB341B0A85F85C
+:100E7000CC3419F0040F03D028462146F8F388F744
+:100E800019F0800F0DD095F8CB3495F8CC2443EAB7
+:100E9000022323F010039BB285F8CB341B0A85F89C
+:100EA000CC342B6893F842308BB119F0600F0ED020
+:100EB00019F0200F0CBFFF21002119F0400F284628
+:100EC00049B214BF00226FF0000200F069FB062255
+:100ED0000DF122004349E1F34FF0B5F8822144F2CD
+:100EE00021339A4217D00E3B9A4214D007339A42CC
+:100EF00011D010339A420ED0143B9A420BD00733D4
+:100F00009A4208D010339A4205D025339A4214BF32
+:100F10000027012700E0012705EB8706B46B0DF1E0
+:100F200022012846224633F073DEB16BA061886946
+:100F300010B937230B936EE0443050312822E1F38F
+:100F40001BF0B36BB7F1FF3F9B699F62BFD0D8F82E
+:100F50005C30179E43F00403C8F85C30224BF56008
+:100F6000B3602846EDF7DAFF1B9A0AB1002313603D
+:100F70002B681E495869E1F32BF530B100210A4670
+:100F8000E1F3E6F31A4BC0B218602B6819495869AF
+:100F9000E1F31EF530B100210A46E1F3D9F3164B17
+:100FA000C0B218602B6815495869E1F311F530B1EA
+:100FB00000210A46E1F3CCF3114BC0B21860284679
+:100FC0002DE0C04639AE820001AE820028AB0100A0
+:100FD000D5A18100ADA181002D578100415781002D
+:100FE00019578100D8A80100B54282001CA9010050
+:100FF000E8F4010028A90100E8F801003CA901007B
+:10100000ECF801001B9B0BB9184608E00B9B1B9EDC
+:101010000020336003E02846FFF792FAF2E70DB0B4
+:10102000BDE8F08F20230360436040F23C7383608F
+:10103000092330B503618361073303623033836270
+:101040000F230822036340F29E330424012500216C
+:1010500042618263C3640322A3F56773C460C56100
+:101060004462C46244630164456402654166436549
+:101070008465C265036630BD70B505460C4631B364
+:10108000496D11B1C022E5F333F6D4F88C1039B1B3
+:1010900028464FF43972E5F32BF60023C4F88C3060
+:1010A000D4F8901031B12846C422E5F321F600238C
+:1010B000C4F89030E16929B128466822E5F318F6B2
+:1010C0000023E36128462146B822E5F311F670BDFE
+:1010D00070B50D460446002800F0E580D0F81815DC
+:1010E00039B128464FF48472E5F302F60023C4F8C0
+:1010F0001835D4F8201539B128464FF48472E5F339
+:10110000F7F50023C4F82035D4F8B41439B12846D3
+:1011100040F2AC42E5F3ECF50023C4F8B434D4F863
+:10112000401531B12846AC22E5F3E2F50023C4F8BE
+:101130004035D4F86C1229B128460BF021D9002390
+:10114000C4F86C32D4F8FC1431B128464022E5F3DF
+:10115000CFF50023C4F8FC34D4F8841671B12368A9
+:1011600063B1DB6953B19B690C22013303FB02F2CB
+:101170002846E5F3BDF50023C4F88436D4F8BC1442
+:1011800019B12846B422E5F3B3F5D4F8901421B18F
+:1011900028464FF4AE62E5F3ABF5D4F8581631B1FA
+:1011A00028463822E5F3A4F50023C4F85836D4F8CD
+:1011B000601639B128464FF49072E5F399F5002393
+:1011C000C4F86036D4F8F81731B128460622E5F3A2
+:1011D0008FF50023C4F8F837D4F8D81639B128466B
+:1011E0004FF48472E5F384F50023C4F8D836D4F8BC
+:1011F000E01631B128462422E5F37AF50023C4F83D
+:10120000E036D4F8EC1631B128466822E5F370F5E3
+:101210000023C4F8EC36D4F8441731B12846EC2248
+:10122000E5F366F50023C4F84437A16B21B12846E5
+:101230004FF40672E5F35CF5616B79B1896A31B1FF
+:1012400080222846E5F354F5626B0023936228461A
+:10125000616B2C22E5F34CF500236363216821B117
+:101260002846FFF709FF002323602369ABB1D3F8B9
+:10127000F81028461822E5F33BF523690026D96FBC
+:10128000C3F8F86019B128465822E5F331F528462D
+:101290002169FC22E5F32CF526612846214640F61B
+:1012A000CC02E5F325F570BD2DE9F0411646B822D4
+:1012B00007460D460BF002D9044610B940F2E93357
+:1012C0002BE03846294668220BF0F8D8E06110B9C7
+:1012D00040F2044321E0FFF7A5FE38462946C0222C
+:1012E0000BF0ECD8606510B940F2EB3315E03846EE
+:1012F00029464FF439720BF0E1D8C4F88C0010B9CC
+:101300004FF47B7309E038462946C4220BF0D6D847
+:10131000C4F8900038B940F2ED33214633603846C6
+:10132000FFF7AAFE00242046BDE8F0812DE9F04138
+:10133000174640F6CC0280460E460BF0BFD8054655
+:1013400000283BD02623C0F82838314640463A468C
+:10135000FFF7AAFF2860002800F018818F4B056076
+:101360001B683146C0F89C30FC2240460BF0A6D8E2
+:101370000446286110B940F2ED3306E1856031463C
+:10138000404618220BF09AD8C4F8F800B0B1404695
+:10139000314658222C690BF091D8E06770B12B6967
+:1013A0004046DA6F31462C32C3F880204FF4847205
+:1013B0000BF084D8C5F8180518B105E040F2EE33FB
+:1013C000E3E040F2EF33E0E0404631464FF4847210
+:1013D0000BF074D8C5F8200510B94FF47C73D4E035
+:1013E0004046314640F2AC420BF068D8C5F8B40430
+:1013F00010B940F2F133C8E040463146AC220BF060
+:101400005DD8C5F8400510B940F2F233BDE0314671
+:101410004046EDF76DFF0146C5F86C0210B940F289
+:10142000F333B2E028461DF099DB404631464022B6
+:101430000BF044D8C5F8FC0410B94FF47D73A4E058
+:101440002B680C22DB6940469B693146013303FB64
+:1014500002F20BF033D8C5F8840610B940F2F53328
+:1014600093E040463146B4220BF028D8C5F8BC04BE
+:1014700010B940F2F63388E0404631464FF4AE6290
+:101480000BF01CD8C5F8900410B940F2F7337CE09B
+:101490002A464FF4AE71D5F89034CB1801F5AE71F1
+:1014A000C2F894340432B1F5AE6FF4D140463146FF
+:1014B00038220BF003D8C5F8580610B94FF47E73E4
+:1014C00063E0404631464FF490720AF0F7DFC5F80A
+:1014D000600638B14046314606220AF0EFDFC5F813
+:1014E000F80710B940F2F9334FE0404631464FF467
+:1014F00084720AF0E3DFC5F8D80610B940F2FA3377
+:1015000043E04046314624220AF0D8DFC5F8E00621
+:1015100010B940F2FD3338E04046314668220AF007
+:10152000CDDFC5F8EC0610B940F2FE332DE04046A1
+:101530003146EC220AF0C2DFC5F8440710B940F288
+:10154000FF3322E0404631464FF406720AF0B6DF20
+:10155000A86358B100F58673EB63404631462C22F0
+:101560000AF0ACDF0446686318B105E040F20143BD
+:101570000BE040F2024308E04046314680220AF088
+:101580009DDFA06238B940F203433B6028464146E4
+:10159000FFF79EFD00252846BDE8F081BC2600002F
+:1015A000D0F84031B1F1FF3F18BF83F89C13B2F17E
+:1015B000FF3F83F89E1383F89F2318BF83F89D2372
+:1015C0007047C04670B50446002831D00025631925
+:1015D000D3F8501221B12368F4225868E5F388F358
+:1015E0000435282DF3D1A16B69B194F8A3331BB155
+:1015F00023689868EEF332F02368A16B9868EEF3E5
+:101600003FF00023A363D4F8781221B12368E822C5
+:101610005868E5F36DF3236806491868224602F01E
+:1016200093DC2368214658684FF46972E5F360F350
+:1016300070BDC046678986002DE9F0434FF469719B
+:1016400085B006464068E5F343F3054608B9814690
+:10165000CFE000214FF469728146E0F3F1F42E608F
+:101660007068E821E5F334F3C9F87802002800F047
+:10167000B1800021E822E0F3E3F4002101236A189D
+:10168000C91808299372F9D1013B2B746B742B7321
+:10169000EB721A460121AB185218082A83F89413EA
+:1016A000F8D14023EB74062385F827304FF0FF3341
+:1016B00085F82830213385F8A233052385F82930B1
+:1016C0004FF47A736B864FF0C803AB86002385F81E
+:1016D0002A30023385F82B302B682A75A9741B68D1
+:1016E0002A4693F8A1308B4218BF032385F82C308B
+:1016F0004FF0FF3385F89E3385F89F334FF4006336
+:10170000EB63012385F82D3004336B750223AB7531
+:101710006B7DD375AB7DD377013205F108039A4217
+:10172000F6D100244FF0010895F82910284685F8D5
+:101730002E4085F82F800BF0A5D9284686F8C38463
+:101740000CF0C0DF042130462C4A2D4B009401954B
+:1017500006F0DEF8A04268603CDB2A4B306800935C
+:10176000294B2A4901932A4B2A4A03932B46029478
+:1017700002F0B2DB074668BBB06827492A463B4601
+:10178000EDF39AF7A86328B3244C85F87C82231DD7
+:1017900093E807006B4683E807002A462368304633
+:1017A000062109F063DA4FF0FF3385F8A13333687F
+:1017B000284693F842100DF0E5DFC823C5F8E03263
+:1017C00028460DF0C5D928464146EDF7DDFB85F8E2
+:1017D000A3730EE0D5F8781219B17068E822E5F32A
+:1017E00087F2706829464FF46972E5F381F24FF091
+:1017F0000009484605B0BDE8F083C04695CB82009D
+:101800001DCB820045CF82007186000050AB0100E5
+:1018100079D98200678986008D85000040AB010080
+:1018200070B5182686B00C46324668460549E0F386
+:10183000A3F32046694632466D46E0F39DF306B0B9
+:1018400070BDC04698AD010070B5D0F8AC530446E9
+:10185000D0F8B063284600F079F8D4F8D013A8681F
+:10186000EDF3FCF6A868D4F8D013EDF309F70023E4
+:101870002246C4F8D0333046044902F065DBF068F4
+:1018800021464FF47E72E5F333F270BDAB998600CA
+:101890002DE9FF413C23C1F824370523C1F828373F
+:1018A00007460D46C0684FF47E71E5F311F2044619
+:1018B00000283DD000214FF47E724FF00008E0F385
+:1018C000BFF3C4F8AC53C4F8B07384F80180204669
+:1018D000E6F7F0FFC4F8C003284600F04DF80646CE
+:1018E00038B1F86821464FF47E72E5F301F24046C4
+:1018F0001FE0204604F56371FFF792FFA8680E49C8
+:1019000022463346EDF3D8F6C4F8D00380B1204622
+:1019100010F05CDF094B38460093094B09490193ED
+:10192000094A23460296039602F0D6DA204600E0E2
+:10193000002004B0BDE8F0818D258300858900007A
+:10194000F9E9000048AC0100AB99860070B5D0F809
+:10195000305704466DB107492246006802F0F4DAB8
+:10196000606829464FF40A62E5F3C2F10023C4F827
+:10197000303770BD529E86002DE9FF4106464FF478
+:101980000A614068E5F3A4F1074618B9C6F83007C4
+:101990000138E1E000214FF40A62E0F351F307F16E
+:1019A00020033B603368082200247A613C61DC211B
+:1019B0001A6630466A4A6B4B0094019605F0A8FF00
+:1019C000A042B86105DA3046FFF7C0FF6FF00100B2
+:1019D000C2E0A6462546644B00221EF0010FEA50E5
+:1019E0001FD0624B19780D2902DD4FF4004C03E043
+:1019F0004A1C012303FA02FC5C4BD8780D2802DD57
+:101A00004FF4004403E0421C012313FA02F40123C3
+:101A100013FA00F28B401A4342EA0C02524B224363
+:101A2000EA501EF0020F24D04F4B55F803804F4B65
+:101A300058780D2802DD4FF4004C03E0421C0123CE
+:101A400003FA02FC494B99780D2902DD4FF400445A
+:101A500003E04A1C012313FA02F4012313FA01F2F2
+:101A600083401A4342EA0C0222433F4B42EA0802F7
+:101A7000EA501EF0040F24D03B4B55F803803B4B3B
+:101A800018790D2802DD4FF4004C03E0421C0123BD
+:101A900003FA02FC354B59790D2902DD4FF400445D
+:101AA00003E04A1C012313FA02F4012313FA01F2A2
+:101AB00083401A4342EA0C0222432B4B42EA0802BB
+:101AC000EA501EF0080F24D0274B55F80380274B0F
+:101AD00098790D2802DD4FF4004C03E0421C0123ED
+:101AE00003FA02FC214BD9790D2902DD4FF40044A1
+:101AF00003E04A1C012313FA02F4012313FA01F252
+:101B000083401A4342EA0C022243174B42EA08027E
+:101B1000EA500EF1010E0435BEF1100F7FF45BAFF9
+:101B2000134B0025134C03932946134A3346306860
+:101B300000950195029502F0CFD9231D93E8070087
+:101B40006B4683E80700304623680321324609F0DC
+:101B50008DD8C6F83077284604B0BDE8F081C0467D
+:101B600001578300A15683008427000090E0850080
+:101B70009D508300ECAD0100529E860010B50446D6
+:101B80000846B0F80CE0194642F256039E4506D8C6
+:101B9000013B9E452ED2053B9E4509D02AE042F2EC
+:101BA00060039E451BD04EF2F5439E451CD021E0BC
+:101BB000C389012B04D16FF03B0313604B3303E067
+:101BC0006FF0450313605A330B602368D3F88030FD
+:101BD00013F4805F13D01368023B13600FE06FF0C3
+:101BE0004A0313605A3309E06FF09503136003F55D
+:101BF000967303E06FF04A0313605F330B6010BD10
+:101C000070B504460025E06820B1054B1B68984775
+:101C10000023E36001350434062DF4D170BDC046C5
+:101C2000E0A685000D4B82685362002380F8863061
+:101C30004FF00303A0F88C304FF00203A0F88E3071
+:101C40004FF00703A0F888304FF00403A0F88A3063
+:101C500042F60133A0F89C307047C04664A8E7BE46
+:101C6000426C1F2A01D9002004E04FF00073134199
+:101C700003F001007047C046026EB0F84A1010B57C
+:101C8000946AB9B1FF2901D8012014E00B0B013B84
+:101C9000012B0FD8C1F30323092B0BD853B1C1F388
+:101CA0000313092B06D801F00F03092B8CBF00206A
+:101CB000012000E00020D26A41F2E4439A4210D1B0
+:101CC000A4F58263073B012B01D83F2907E040F2CE
+:101CD0000C439C4204D015339C4202D1502900D8B9
+:101CE000002010BD00B58E46C16E4FF04073944683
+:101CF0007046C1F8603115E00379C2781B0443EAED
+:101D0000026382791343427943EA0223C1F86431C2
+:101D1000437802781B0243EA024382780730134378
+:101D2000C1F86431CEEB00036345E5D300BDC04686
+:101D300010B590F85E3004463BB9044B04491A686C
+:101D4000FFF7D0FF012384F85E3010BD789E0200BB
+:101D50007C9E0200C16E4FF48030C1F860011D4AC4
+:101D6000D1F8603110B5D1F86441C1F86001D1F803
+:101D70006031C1F86421C1F86001D1F86031D1F857
+:101D80006431934224D1144AC1F86001D1F8603122
+:101D9000C1F86421C1F86001D1F86031D1F8643133
+:101DA000934215D1C1F86001D1F860310023C1F828
+:101DB0006441C1F88C31D1F82001084B984201D11F
+:101DC000012006E0064B984214BF0020012000E0ED
+:101DD000002010BDAA5555AA55AAAA550004000412
+:101DE00000040084D0F8501810B5044641B1D0F872
+:101DF0004C2840689200E4F37BF70023C4F8503885
+:101E0000D4F8481859B16068E0F3CEF66068D4F8A9
+:101E10004818E822E4F36CF70023C4F8483810BDF2
+:101E200070B504690646206E08B1E9F78DF82046C2
+:101E3000FFF7E6FEA56F686A18B103F0FFFF002305
+:101E40006B62606F03F08CFF206F05F023FC616E06
+:101E500029B12068A26EE4F34BF700236366206E7D
+:101E600018B103F0D9F9002323662046E8F728F9D2
+:101E70003046FFF7B7FF002070BDC0462DE9F04F98
+:101E8000036807698FB00890DE691446FB6B0CA8E5
+:101E90000821704AE0F318F1FB68002B40F0CE8077
+:101EA000F96E386E01F50071D7F800B0E2F3FCF47A
+:101EB000BB6801469868EDF395F3002800F0C680F2
+:101EC000D7F860E00CB9A44602E0FB6E03F5007C95
+:101ED000FB6E03F5087504B13468B168BB687268BD
+:101EE000F068D3F8283803915B490DF130094FF0C1
+:101EF000FF38029205907246069307916346494661
+:101F0000584600950194CDF81080EDF71DF8316822
+:101F1000F8603A6EFB6E01914F4900240546079127
+:101F200003F5107349465846009402940394CDF883
+:101F3000108005940694EDF707F8316838613A6E21
+:101F4000FB6E019144490990079103F520734946BE
+:101F50005846009402940394CDF81080059406949A
+:101F6000ECF7F2FF316878613A6EFB6E01913A4905
+:101F70000A90079103F5307349465846009402943D
+:101F80000394CDF8108005940694ECF7DDFF3168DA
+:101F9000B8613A6EFB6E01912F490B90079103F5E2
+:101FA000407349465846009402940394CDF810803B
+:101FB00005940694ECF7C8FF3168F8613A6EFB6E41
+:101FC000019125498246079103F5507349465846C9
+:101FD000009402940394CDF8108005940694ECF7D5
+:101FE000B3FF099AA54214BF002501250A9BA2420E
+:101FF00008BF45F001050B99A34208BF45F0010554
+:10200000A14208BF45F00105A24508BF45F0010502
+:102010003862A04214BF284645F00100B0B90F4B0A
+:102020003C46D3F884600546E06818B10C49B047D7
+:10203000C4F8A00001350434062DF5D1B96F089815
+:1020400008310022E7F7FAFB012000E000200FB082
+:10205000BDE8F08FFB41860014260000E0A6850055
+:10206000C32686001FB5022303930D330446C0F830
+:102070004C383C214068E4F32BF6C4F85008D0B14A
+:10208000D4F84C2800219200DFF3DAF76068E821E9
+:10209000E4F31EF6C4F8480868B10021E822DFF333
+:1020A000CFF7012300936068D4F8481803AAB3332C
+:1020B000E0F312F601E04FF0FF3004B010BDC0466F
+:1020C0002DE9F04F056997B0DDF884A014469B46D2
+:1020D0009DF88020EB63EB6FA860AB672A71074621
+:1020E000C5F800A028460E46FFF79CFD249B05F18D
+:1020F000640205F168010093019202912046514665
+:10210000229A239B03F0C6F92866002800F0D581A7
+:10211000D5F8648095494046E0F35AF420B1002197
+:102120000A46E0F315F386B240469149E0F350F4D5
+:1021300048B100210A46E0F30BF34FF6FF7380B27B
+:10214000984218BF044630462146FDF7CFFE08B935
+:102150000C30B7E140F612010022A5F84060A5F866
+:102160004240286EE9F34AF0E866286EE8F398F6F4
+:10217000D5F86C906864C7F80C902846FFF770FD9E
+:1021800008B90D309EE1286EE8F7E2FE28460021EE
+:1021900019F0A2DD28464FF0FF31E7F78DFB284606
+:1021A000FFF7D8FD08B90E308CE140467149E0F3E5
+:1021B000E3F3FF2808BF0120A5F84A002846FFF7EF
+:1021C0005BFD08B90F307DE16B494046E0F3D4F385
+:1021D0006A4985F848004046E0F3CEF36849E86470
+:1021E0004046E0F3C9F3296E2865CA6A41F26B03E1
+:1021F0009A420AD18B6A4E2B07D1B5F84A30402B50
+:1022000003D9EB6C43F00203EB64EB6C13F0200F8B
+:1022100004D0012128460A461BF014D9B5F8402005
+:102220000123A7F88021C5F89830B5F842303A6804
+:10223000A7F882312B6E284613616B6C936095F87A
+:10224000483082F87C303A68B5F84A30B968A2F86C
+:102250007A30EB6CC2F880302B6DC2F88430D5F840
+:10226000983053623A4605F01FFA286708B91930CA
+:1022700028E12B6ECDF810A005932B6FCDF81CB084
+:10228000B5F8402006936B6CADF8302008932A6EA9
+:10229000B5F84230CDF82C80ADF83230936B04A8FD
+:1022A0000D93D36B0E93136C0F9395F848301093E6
+:1022B000936A1193B5F84A301293D36A1393EB6C77
+:1022C00014932B6D159353680993D3680A9303F005
+:1022D0004FFD686708B91030F4E0B5F8421044F2D9
+:1022E0002133994217D00E3B994214D007339942BB
+:1022F00011D0103399420ED0143B99420BD00733C2
+:10230000994208D01033994205D02533994214BF21
+:102310000026012600E0012631462846E7F7B0FAFC
+:10232000AA6F002E0CBF02230123136056603A6B84
+:10233000286E13605660FC6AE8F3A0F52060D9F8B7
+:102340005C31696C0F4A6B65AB65062301FB0323A7
+:10235000AC6FC5F8B830686F49462268434603F051
+:102360009FFE606280B91130ACE0C046D1AD8600FE
+:102370004837860084AE8600E5AE86008637860044
+:102380009E79860020ED0100AB6F696D586AEDF70C
+:102390008DFEAB6F03F1220203F11C01586A00921B
+:1023A00003F11E02203303F0C3FCAC6F606A03F03C
+:1023B000CFFC84F82800AB6F3C6B586A03F0C8FC74
+:1023C0002075AC6F606A03F0C7FCA96FA061CB8B6E
+:1023D000032B01D0122075E03B6B4A6A38461A6124
+:1023E0008A8B1A81CA8B5A810A8C9A814A8CDA812B
+:1023F00040F2FF324FF00F03CA828B820122314636
+:10240000FFF73CFD08B913305CE0B6F1FF3F3FF445
+:1024100064AFAB6F3A68586A92F89910EDF74AFECC
+:10242000002128461AF040D90821284619F0C2DFB9
+:1024300028461BF071DC286E2449254A00230097AA
+:10244000E8F398F6284600211BF048DC2846E7F719
+:10245000E1F908B9153035E005F1DC042146E0F377
+:10246000ABF02046E0F368F248BB2046E0F374F29C
+:10247000044620BB284619F077DAAB681B68D3F80E
+:102480009C00F0B10378E3B112492A46E0F378F3F7
+:10249000AB6811491B682A46D3F89C00E0F3AAF305
+:1024A000A868FFF7DFFDE86858B1AB681B68D3F890
+:1024B0009C10E2F39DF3204604E00B2002E016207E
+:1024C00000E0002017B0BDE8F08FC04669C183006E
+:1024D00085C1830025C0830049C0830010B5044630
+:1024E0001DF04ED90122014620461DF0C1D910BD74
+:1024F00037B505461DF044D90023C5F84C0280F8D5
+:1025000048302A68044692F82F10284600914E322F
+:1025100021461BF0E3DE30B1284621461CF08CDF5B
+:102520004FF0FF3003E0284621461DF02BD83EBD7A
+:1025300037B50446002847D0D0F8201131B10368E0
+:102540009868EDF39DF00023C4F8203122681368E9
+:1025500093F82F303BB3D2F8000501A932F0BADD71
+:1025600013E0536813F0400F0FD0D4F82C31D51876
+:1025700007E00B684822C5F8103123685868E4F377
+:10258000B7F3D5F810110029F3D101A832F0AADD74
+:1025900002460028E5D106E00B684068C4F84031E7
+:1025A0004822E4F3A5F3D4F8401120680029F3D1C0
+:1025B00006492246006801F0C7DC236821465868B6
+:1025C0004FF4A472E4F394F33EBDC04691BA860082
+:1025D000F0B54FF4A47185B005464068E4F378F394
+:1025E000064608B9074655E000214FF4A472074695
+:1025F000DFF326F5294B35600093294B29490193D8
+:10260000294B002403932868284A3346029401F09A
+:1026100063DC31462A6B1368022B03D1537D0BB95F
+:10262000163300E0302301340B744431042CF1D113
+:10263000A8681F492A460023EDF33EF00446C6F879
+:10264000200130B9686831464FF4A472E4F350F3C6
+:102650001FE04FF49673C6F81C3145F27353A6F889
+:1026600038314FF04603A6F83A31124B0024C6F831
+:102670004041284600934FF48A710F4A0F4B019551
+:1026800005F046F9A042C6F82C0103DA3046FFF700
+:102690004FFF2746384605B0F0BDC046F90C840010
+:1026A00055ED00001CAE01007D0A840091BA860041
+:1026B0003D068400D9128400E5128400A51284002E
+:1026C00070B50568044622462868044901F03CDCE0
+:1026D000686821465022E4F30BF370BD3CE48600A9
+:1026E00070B50546002826D00368134918682A46A5
+:1026F00001F02ADC6B6905E01C68596828462EF059
+:102700000DD92346002BF7D12B6905E01C685968C9
+:1027100028462EF003D92346002BF7D1A96A21B110
+:102720002B6890225868E4F3E3F22B682946586836
+:102730002C22E4F3DDF270BD91E6860030B52C2149
+:10274000044685B04068E4F3C3F208B9054618E0D2
+:1027500000212C220546DFF373F40823AB610A4BFA
+:102760002C6000930023019302930393074A2B46A6
+:102770002068074901F0B0DB2268012382F8963017
+:102780002B71284605B030BD050B850091E686000B
+:1027900094AE01002DE9F047154680460F461E46CF
+:1027A000E8F36CF3002181464046E8F339F5002256
+:1027B000044611460F480B185B6873B90C3302FBD3
+:1027C00003F31D501A18636A576096600A4A45EA77
+:1027D000030313606362012404E001320C31052A13
+:1027E000E8D1002440464946E8F31AF52046BDE802
+:1027F000F087C0463C260000782600002DE9F0470F
+:1028000005468846E8F376F400212846E8F308F503
+:10281000064628466C69AF69E8F7D2F90A2C81466A
+:1028200016D90F2C19D02846E8F70CFC142C0546B5
+:1028300003D9B36823F00803B360B36843F001031E
+:10284000B36003D9B36843F00803B360012211E019
+:10285000022C02D8174D30220CE02846E8F7FCFB8A
+:10286000D6F8A430054623F0FF0343F00203C6F870
+:10287000A4300222B36813F0010F07D107F0180348
+:10288000082B14BF4FF4E115B5FBF2F507F0030771
+:1028900000240BE006F54073B8F1000F05D003EB00
+:1028A000042049462A460023C0470134BC42F1DBDC
+:1028B000BDE8F08700C63E0537B5134B15461360DB
+:1028C00001E0114B13600432ADF17C039A42F8D35E
+:1028D000033020F003000D4BC0EB01041C600C4BD7
+:1028E000002119600B4B05F5A05219600A4B083CFA
+:1028F00019600A4B41601D60094B1A60094B196051
+:10290000094B046058603EBD4B415453C82600003B
+:1029100088260000A4260000CC260000F4F4010064
+:10292000F8F4010090260000C0260000436910B5AD
+:10293000142B01DD02F09CFB10BDC0461FB5E82042
+:102940000021E3F363F50C4C2060A0B10021E822E4
+:10295000DFF376F304AA012342F8043D013B009320
+:10296000064B2168186840F23C73E0F3B5F120682B
+:102970000F21E0F3FBF11FBDBC26000020F5010094
+:10298000B1F5E06F73B505460C46164606D10369EE
+:102990000091002101911C680A460CE00D4B0022B9
+:1029A0001868E8F32BF4014680B12B6900220094EB
+:1029B00001921C6828463346A04738B1064AA861F0
+:1029C000136800202B626E61156001E04FF0FF304C
+:1029D0007CBDC0468C2600001CF501002DE9F047A7
+:1029E00010200E46002117469946E3F30FF50446E2
+:1029F00010B96FF01A001EE0104D2868E8F33EF29F
+:102A0000099B804623B9286831463A46E8F3F6F335
+:102A10002868E8F3AFF201238340094AE360089B8A
+:102A2000C4F80490A36013682868236041461460CA
+:102A3000E8F3F6F30020BDE8F087C0468C260000DE
+:102A40009826000007B50021E8F3EAF3074B4FF49E
+:102A500000611860064B00F57060186000200246A7
+:102A6000044B00900190FFF7B9FF0EBD9C260000BB
+:102A7000F0F401006D60800037B5234B234C02ADAC
+:102A800000211C2245F8043D2046DFF3D9F2012342
+:102A900023601F4BA5F5A0551B6843F8044C00F0BC
+:102AA0000DF929462A461B48FFF706FFE3F36AF6AD
+:102AB00000F042F8002002F01FFA174B174C186084
+:102AC00002F0BCFC2060FFF7BDFF206800F01EF99B
+:102AD000E7F700FF206800F0A5F800221048114930
+:102AE000E4F308F0002210481049E4F303F0104921
+:102AF00000221048E3F3FEF72068FFF717FFFFF707
+:102B00001DFF20683EBDC046ADDEADDEFCF4010019
+:102B1000E8ED0100BE24030020F501008C26000032
+:102B2000D81F8600E1A60000DB1F860065658000D7
+:102B30008D608000DE1F860070B5A4200021E3F3C5
+:102B400065F4124D286080B10021A422DFF378F2F1
+:102B50004FF4806000212C68E3F358F4A0602868EB
+:102B600084682CB9E3F3B8F32C604FF0FF300CE02D
+:102B70004FF48062C2608460446100212046DFF32C
+:102B80005FF22A68024B00201A6070BD34F5010024
+:102B9000D426000070B51C4D06462B6833B91B4C7B
+:102BA00023680BB9FFF7C8FF23682B60164C184B3E
+:102BB0002068586130B3002505604560336CC0F86B
+:102BC0009C500E3B012B03D930461249FFF716FEED
+:102BD000114A936813B12368C3F89C20246807E066
+:102BE000D4F89C0018B1A368595DE3F36FF7013581
+:102BF00023699D42F4D3094809492246E3F37AF751
+:102C0000014B186870BDC046D426000034F50100A1
+:102C1000FCF40100492C020024F50100BD218600CE
+:102C2000A568800010B54022002305490446FFF73F
+:102C3000B1FD044B00229A602046FFF7ABFF10BDA8
+:102C4000A969800024F5010070B51B4DAE68002E07
+:102C500031D114092C60AB8104F561444FF4E133A8
+:102C600094FBF3F4A8606960284603218022E3F313
+:102C700023F728463146E2B2E3F31EF72846012146
+:102C80002212E3F319F703210A462846E3F314F767
+:102C900001210A462846E3F30FF7284604210822BB
+:102CA000E3F30AF7284602210122E3F305F74FF484
+:102CB0007A70E3F351F570BD24F50100104A072145
+:102CC000136843F010031360136843F008031360A4
+:102CD000136823F400731360E832136843F08073C1
+:102CE00043F480331360074B00221960043B1A60E1
+:102CF00008331A681960044B20221A607047C046D6
+:102D000014ED00E0241000E000E400E02DE9F041C3
+:102D1000054600F0ADF82A48E7F762FB2846E7F7DA
+:102D200025FF284B284AC318B3FBF2F3274A28464D
+:102D30001360E8F77DF900F5787007304FF47A7387
+:102D4000B0FBF3F0224B234A18602B6A2249002B78
+:102D5000CCBF6FF07F4340F2FF3313601D4A1F4F1B
+:102D60001368B3FBF0F31360284620220023FFF71B
+:102D700011FD00201A49DFF3FFF504463860E8B181
+:102D80002846E7F7F3FEB4FBF0F0861E002E15DDB3
+:102D9000144C002134222046DFF352F1124B4FF441
+:102DA0007A71A3606560204606FB01F10122E3F31E
+:102DB00021F218B128463968E1F32CF5BDE8F0811D
+:102DC00019A900003F420F0040420F00D02500002B
+:102DD000C8250000CC25000001678000E82600001F
+:102DE0004EB001003CF50100E56680002DE9F0479A
+:102DF00007461E4615460C46E8F37CF13846E8F3D4
+:102E00003DF02946324681463846E8F3F7F1384628
+:102E1000E8F3B0F040F62A01064600223846E8F30F
+:102E2000EDF105468CB1012414FA06F3826932EA09
+:102E3000030802D12046E7F793FA701C14FA00F059
+:102E4000E7F770FAC5F818800CE00124701C14FA3A
+:102E500000F0E7F785FA2046B440E7F763FAAB697C
+:102E60001C43AC6138464946E8F3DAF1BDE8F08727
+:102E70002DE9F0470746E8F33DF1384640F60E01EC
+:102E80000022E8F3BBF10446002831D0D0F80080DE
+:102E900005683846E8F304F00428064604D827D12C
+:102EA000C5F30243032B23D100204849DFF364F527
+:102EB000F0B94749C8F3031212E0013A072E226124
+:102EC0000AD90C2E08D0236C13F4806F02D013F4AF
+:102ED000006F01D108B903E0012041F004516161A4
+:102EE000002AEAD1D4F8E83123F01003C4F8E8311D
+:102EF000002240F62A013846E8F380F1354C206084
+:102F00003846E7F3CDF7344B22681860136843F670
+:102F1000A12443F080731360136843F0020313602D
+:102F20000023C2F8E03103E00A20E3F315F40A3C81
+:102F3000DFF8A090D9F80030D3F8E03113F4003F67
+:102F400001D1092CF0D100210B4638464FF4006224
+:102F5000FFF74CFF00210B46384640F61202FFF700
+:102F600045FF00210B46384640F62902FFF73EFF99
+:102F700038460121E7F728FE00201849DFF3FCF46A
+:102F8000E0B13846E7F37AF740F62A01804600229E
+:102F90003846E8F333F146690446D0F8985038468D
+:102FA000E7F36CF70123834045F001053343636188
+:102FB0003846C4F898504146E8F332F1D9F8002079
+:102FC000136A43F003031362BDE8F087BDB001004C
+:102FD000FF7F010070F5010074F501004EB00100A3
+:102FE00010B58469A068FCF783FDE068E7F790FFFF
+:102FF000002010BD10B584690021342204F11C00AA
+:10300000DFF31EF0034BA06863622462ECF7ACF8B8
+:10301000002010BD05AA80002DE9F347DFF8AC8041
+:103020009946D8F800300546072B0F46924643DCF8
+:1030300001F062FF50210646E3F34AF604460028F9
+:103040003AD000215022DEF3FBF7D8F8003065605B
+:103050002360A4F814902761E660204641F2E44121
+:103060004A4633460097CDF804A0FCF793FDA060D4
+:1030700010B300200A990B9A114B0095CDF804A0CB
+:10308000FFF7ACFC18B1A068FCF732FD14E0A068B3
+:10309000E6F3DAF10B49A061D8F800202846DFF307
+:1030A00023F009482946ECF709F8D8F80030204603
+:1030B0000133C8F8003000E00020BDE8FC87C046BE
+:1030C00031AA8000FC7C0200DC7C020078F5010063
+:1030D000014610B550228068E3F30AF610BDC046E1
+:1030E000C36B10B51BB100225A62836B5A62C06871
+:1030F000FFF7EEFF10BDC0462DE9F041184E1C460B
+:1031000033780746072B904626D820464C21E3F318
+:10311000DFF5054600B300214C22DEF391F76C6029
+:103120002F60C5F808803378204685F84430013395
+:1031300033700223AB640821E3F3CAF50446286424
+:1031400020B100210822DEF37BF706E029464C225D
+:10315000E3F3CEF5254600E000252846BDE8F081E2
+:103160007CF501002DE9F04FD1F8FC3091B00F93C0
+:10317000054603F56063079335E10FAF0E22002388
+:1031800028463946DDF3A0F10F28044600F03681C9
+:103190000022284639461346DDF396F110F00E065C
+:1031A00040F0268140F23B43B3EB145FC4F30B21A4
+:1031B000C0F3041804D140F6FF73994200F0138164
+:1031C000C0F344220992002A00F00D81C0F3C443E9
+:1031D000C0F3843B13EB0B02089319D140F2673321
+:1031E000994240F000810EAB01930DAB02930CAB02
+:1031F00003930BAB04932846394613460092DDF344
+:1032000001F1002800F0EF800E9BC5F85433EAE08E
+:10321000D5F8CCA005EB8A03C3F8D4423446C3F8F2
+:103220001403C3F8D0100BE00122284631461346A0
+:10323000DDF34AF100F00E00022840F0D98001349D
+:1032400044450FAEF0D1002213460DF138090DF1BF
+:1032500034080CAF0BAC284631460092CDF80490F0
+:10326000CDF8088003970494DDF3CCF00246E8B96A
+:1032700040230093284631461346CDF80490CDF8FC
+:10328000088003970494DDF3BDF010B14FF00108FE
+:103290000EE00D9B002B40F0AB800B9B002B40F011
+:1032A000A7800C9BB3F5805F40F0A2804FF0000830
+:1032B0000E9A05EB8A03C3F810210C9A0124C3F877
+:1032C000D0210EAB01930DAB02930CAB03930BAB70
+:1032D0000022049328460FA923460092DDF392F0C2
+:1032E00008B9012727E0012C40F086800C99B1F540
+:1032F000805F40F081800E9B05EB8A02C2F890311E
+:10330000C2F8101278E00024002300930EAB019362
+:103310000DAB02930CAB03930BAB049328460FA9A0
+:103320003A462346661CDDF36DF008B13446EBE700
+:10333000002E5DD00137099A9742E4D100241FE0A6
+:10334000C02300930EAB01930DAB02930CAB039320
+:103350000BAB049328460FA922460023DDF352F05D
+:10336000002845D00B9B002B42D10C9BB3F5805F0E
+:103370003ED124B90E9B05EB8A02C2F89432013487
+:103380005C45DDD1002423E0802300930EAB019344
+:103390000DAB02930CAB03930BAB049328460FA920
+:1033A000012F0CBF2246621C0023DDF32BF0F8B185
+:1033B0000B9BEBB90C9BB3F5805F19D1BBF1000FF0
+:1033C00005D124B90E9B05EB8A02C2F89432013470
+:1033D000089B9C42D8D1B8F1000F04D1D5F8CC306D
+:1033E0000133C5F8CC300F9B079A9342FFF4C5AE6A
+:1033F0000023C5F8CC3001E0013462E711B0BDE82C
+:10340000F08FC04682604160016070470EB4F3B532
+:1034100081680646012901D8002044E008AB4068D5
+:10342000079A0193DEF342F7B0F1FF3F074603D05E
+:10343000B368023B984203DD00231846B36032E0D4
+:1034400070683D21DEF360F630B373683568C3EB16
+:1034500000041EE028462246DEF372F5A8B92B5D73
+:103460003D2B12D12846DEF37BF67268441CBA1855
+:10347000291901322846521ADEF3B4F573681B1B72
+:103480007360B3681B19B36006E015F8013B002BAD
+:10349000FBD171688D42DDD3B368781C1B1AB36011
+:1034A00073681B187360BDE8FC4003B07047C046EA
+:1034B0002DE9F041C1EB0204012C0E461F46DDF858
+:1034C000188010DD2146E3F303F4054610B96FF0D0
+:1034D0001A000DE031462246DEF34EF500203D6035
+:1034E000C8F8004004E000233B60C8F800301846EC
+:1034F000BDE8F0812DE9F04FA5B008914FF480515F
+:10350000099007920693E3F3E3F30A9018B96FF07A
+:10351000010401F029B921A80A994FF48052FFF75C
+:1035200071FF4FF480520A980021DEF389F50023E1
+:103530004FF0FF328DF844300B930D930E9201F053
+:10354000DEB80D9B089A002152F8239001230C91BC
+:103550000F930F9B19F8012073B1531EDBB2FD2BA3
+:1035600001F1010898BF19F808B016468CBF4FF05A
+:10357000000B08F101080CE002F1FF33DBB2FE2B77
+:1035800093462CBF1646802628BF4FF0000B01F152
+:1035900001080BEB0803B3F5607F81F2AD80202EAC
+:1035A0002AD005D8152E0AD01B2E6DD001F078B880
+:1035B000222E3AD036D3802E72D001F071B808EBAB
+:1035C00009035A7819F8083003EB0223072B13DD9F
+:1035D00009F10204444421AD874922462846FFF7F9
+:1035E00015FF2046DEF3BCF509F1030200EB0803EA
+:1035F00082492846D2184FE008EB0904637819F88D
+:10360000082021AD02EB032228467D49FFF7FEFE8C
+:10361000E378A27828467B4902EB0322FFF7F6FE07
+:1036200001F03EB819F8082003E00C9B0C2B03D1E5
+:1036300000220C9201F036B89DF84430002B41F086
+:10364000318019F80830042B41F02C8009F1020474
+:1036500004EB08052846DFF37FF1002841F02280C3
+:1036600014F8083013F0010F41F01C80284611A90E
+:10367000DEF3BAF70E9BB3F1FF3F41F0138008EB86
+:1036800009039A79DB790DE108EB0903DC799A7972
+:103690005D4921A842EA0422FFF7B8FE01F002B812
+:1036A00019F80830822B00F2FD87DFE813F0920052
+:1036B000B30038013B02D4021102CB01DA01470109
+:1036C000EA02FB0210031703FB077F020302FB075A
+:1036D0003603570397007A037F0390039503F7009F
+:1036E000E903FB07770107047F01FB07FB07FB07E3
+:1036F00010042204270472045305FB07FB0721066C
+:103700008D0088008300AE06D306DA06E106FB07CB
+:1037100026037101FB07FB070001F007E806FB0722
+:10372000FB07FB07FB07FB07FB07FB07FB07870103
+:1037300013072807490764077F079907B307CD07D1
+:10374000D407FB078E01FB07FB07FB07FB07FB0703
+:10375000FB07FB07FB07FB07FB07FB07FB07FB0759
+:10376000FB07FB07FB07FB07FB07FB07FB07FB0749
+:10377000FB07FB07FB07FB07FB07FB07FB07FB0739
+:10378000FB07FB07FB07FB07FB07FB07FB07FB0729
+:10379000FB07FB07FB07FB07FB07FB07FB07FB0719
+:1037A000FB07FB07FB07FB07FB07FB07FB07FB0709
+:1037B000FB07DE0709EB0804002500F00BBE09EB50
+:1037C0000804002500F0F4BD09EB0804002500F012
+:1037D000DEBD0E4908EB090321A8DDE008EB090175
+:1037E000CA780B79120442EA03624B7821A81A4383
+:1037F0008B7807497EE2C046E07D02003C800200F3
+:103800009E7D02003381020002840200797F020063
+:10381000157D020008EB0904A378627821AE02EB63
+:103820000322AE493046FFF7F1FD2379E2783046B6
+:10383000AB4902EB0322FFF7E9FDBBF1060F40F2B3
+:103840003187A37962793046A64902EB0322FFF75C
+:10385000DDFDBBF1080F40F22587237AE27930467F
+:10386000A14902EB0322FFF7D1FDBBF10A0F40F2A1
+:10387000198709F10A0409F1090514F8083015F847
+:1038800008209A4902EB03223046FFF7BFFD14F8E7
+:10389000083015F80820964930464CE008EB09033B
+:1038A0009A785B7803EB02220E9200F0FBBE0623AF
+:1038B000904ABBFBF3F309EB08074FF0000A1370C3
+:1038C00027E019AD534610218B4A1DAE2846DEF382
+:1038D000FBF353461021894A3046DEF3F5F3BB78FB
+:1038E0007A7821AC42EA032229462046FFF78EFD72
+:1038F0007A79BB79120442EA0362FB7820461A43C4
+:103900003B79314642EA0322FFF780FD0AF1010AC2
+:103910000637784B1B789A45D3DB00F0C3BEBBF16A
+:10392000020F21A808EB090202D175495278B3E6CB
+:1039300093787349527802EB0322ADE608EB090451
+:10394000A2786378BBF1040F03EB022505D9237934
+:10395000E2781B0603EB02431D4321AE3046694962
+:103960002A46FFF753FDBBF1060F40F29B86A27972
+:103970006379BBF1080F03EB022505D9237AE279BD
+:103980001B0603EB02431D435F4930462A4683E68C
+:103990005E4908EB090321A85A787DE608EB090384
+:1039A0009C785A78524921A800F05BBE0BF10103C4
+:1039B0005FFA83FB00230F9300F074BE08EB09034A
+:1039C0009C785A78524921A864E64A4B4FEADB02B8
+:1039D00009EB08074FF0000A1A702DE01DAD5346A1
+:1039E0001021454A19AE2846DEF36EF353461021E6
+:1039F000424A3046DEF368F3FA783B79120442EA31
+:103A000003627B7821AC1A43BB78294642EA032241
+:103A10002046FFF7FBFCFA793B7A120442EA036284
+:103A20007B7920461A43BB79314642EA0322FFF7ED
+:103A3000EDFC0AF1010A08372E4B1B789A45CDDBC5
+:103A400000F030BE21AD08EB090428463149627808
+:103A5000FFF7DCFCBBF1020F40F224862E4928461A
+:103A600059E121AD08EB0904002228462B4963786F
+:103A7000FFF7CCFCBBF1020F40F20F860122284673
+:103A80002649A378FFF7C2FCBBF1030F00F00586BF
+:103A9000022228462149E378FFF7B8FCBBF1040F66
+:103AA00000F0FB8528461D4903222379FFF7AEFC71
+:103AB00000F0F3BD21AC08EB090517496A782046F0
+:103AC000FFF7A4FC1549AB782046012200F0DCBDCD
+:103AD000134908EB090321A85EE7C046548202009F
+:103AE000158302005E810200AA7D0200C17E0200F1
+:103AF000C17D02007DF50100C8B00100D3B0010016
+:103B0000F67E0200D7820200227E0200F47F0200CD
+:103B10006A830200217D02004C83020021800200A2
+:103B2000E5830200ABF10203082B00F2BB85DFE85E
+:103B300013F00900B905B905B905B9052B001C003A
+:103B400015000E00A74908EB090321A824E708EB9C
+:103B5000090321A8A4495A7AFFF758FC08EB090386
+:103B600021A8A0491A7AFFF751FC09F1070521ACF9
+:103B70009E4915F808202046FFF748FC20469C493E
+:103B800015F80820FFF742FC9A4D09EB0804A378CA
+:103B90006278294602EB032221A8FFF737FC964BF7
+:103BA000093502349D42F2D100F07CBDBBF1140F07
+:103BB00019D0BBF1170F04D0BBF1130F1AD000F0CE
+:103BC00071BD21AC08EB09058C49AA7D2046FFF7A1
+:103BD0001DFC8B496A7D2046FFF718FC2046894969
+:103BE0002A7DFFF713FC08EB090321A88649DA7C3C
+:103BF000FFF70CFC854D09EB0804A3786278294691
+:103C000002EB032221A8FFF701FC814B09350234A6
+:103C10009D42F2D109EB08057E4E2C46237AE279CB
+:103C2000314602EB032221A8FFF7F0FB7A4B0B365B
+:103C300002349E42F2D1794CAB7B6A7B214602EB87
+:103C4000032221A8FFF7E2FB754B0B3402359C429F
+:103C5000F2D100F027BD08EB0901C8784A788B78CB
+:103C60000090087901904879029088790390C8798A
+:103C70000490097A21A805916A49FFF7C7FB00F073
+:103C800011BD09EB080400256378FF2B04D021A89F
+:103C900065492A46FFF7BAFB01350134042DF3D1FB
+:103CA00000F000BD08EB09035A780AB19B7823B9EC
+:103CB00021A85E49FFF7AAFB03E021A85C49FFF7B2
+:103CC000A5FB08EB09035B49DA7821A8E4E408EBDB
+:103CD00009039C785A78584921A8DBE408EB0901CC
+:103CE000CA780B79120442EA03624B7821A81A437E
+:103CF0008B78524942EA0322CEE421AD08EB090455
+:103D000028464F496278FFF781FBBBF1020F40F272
+:103D1000C9844C492846A278BEE409F1010515F88A
+:103D2000082021AC484902F00F022046FFF76EFB45
+:103D300015F808204549120909F102052046FFF748
+:103D400065FB15F80820424902F007022046FFF7FC
+:103D50005DFB15F808203F4920461FE009F10105E9
+:103D600015F8082021AC3C4902F00F022046FFF76D
+:103D70004DFB15F808203949120909F102052046C2
+:103D8000FFF744FB15F80820354902F007022046EA
+:103D9000FFF73CFB15F8082032492046C2F3C10268
+:103DA0007AE4314908EB090321A8F5E521AC08EBD9
+:103DB00009052E496A782046FFF728FB2C49AA7886
+:103DC0002046FFF723FB2B49EA78204664E42A4982
+:103DD00008EB090321A8DFE5284908EB090321A81E
+:103DE000DAE5C0468C8202004D8202003F8102006B
+:103DF000837D0200C27F0200DD7F0200747D02002D
+:103E00008D7E0200E97E0200917D0200A281020007
+:103E1000BD8102008E7F0200AF7F02009982020006
+:103E2000BA820200F0820200377D0200C5830200E0
+:103E3000DA830200F8830200FD7F0200A4830200FF
+:103E400056830200847F0200087D0200DD7F0200AD
+:103E5000537D0200E782020031830200157E0200DA
+:103E60009783020061830200B08302000880020091
+:103E700044820200EA7F0200E6800200AA7E02007D
+:103E800009F1010404EB08052846DEF365F5002876
+:103E900040F0088414F8083013F0010F40F0028459
+:103EA000284611A9DEF3A0F30E9BB3F1FF3F40F0CB
+:103EB000F98308EB09035A799B79F3E408EB0903CA
+:103EC0009A785C788C49120621A8FFF7E3BB08EBCF
+:103ED000090421AD894962782846FFF797FA884995
+:103EE000A2782846FFF792FA2379E2788549284696
+:103EF00021E5854908EB090321A84DE508EB0906F2
+:103F0000B378747821AD04EB0324A4B2E20A7F49AC
+:103F10002846FFF77BFA7E49C4F302222846FFF7C2
+:103F200075FA7C49C4F3C4022846FFF76FFA7A4950
+:103F3000C4F341022846FFF769FA2846774904F09E
+:103F40000102FFF763FABBF1040F40F2AB83337950
+:103F5000F478734904EB0324A4B2E20A2846FFF77D
+:103F600055FA7049C4F302222846FFF74FFA6E490A
+:103F7000C4F3C4022846FFF749FA6C49C4F341026E
+:103F80002846FFF743FA6A49284604F00102FFF782
+:103F900083BB08EB090621AF664972783846FFF704
+:103FA00035FA4FF0000A6449B2783846FFF72EFA26
+:103FB000CDF800A03279F378604903EB0223019336
+:103FC000022253463846FFF721FACDF800A0B27915
+:103FD00073795A4903EB02230193022201233846E5
+:103FE000FFF714FACDF800A0327AF379384603EBE4
+:103FF00002230222019351491346FFF707FABBF14E
+:104000001E0F40F24F834E49727A3846FFF7FEF991
+:104010004C49B27A3846FFF7F9F94B49F27A3846FB
+:10402000FFF7F4F94949327B3846FFF7EFF9CDF84D
+:1040300000A0B27B737B414903EB0223019305226D
+:1040400053463846FFF7E2F9CDF800A0327CF37B07
+:104050003A4903EB02230193052201233846FFF777
+:10406000D5F9CDF800A0B27C737C344903EB022370
+:104070000193052202233846FFF7C8F9CDF800A0C6
+:10408000CDF804A0327DF37C314903EB0223029387
+:1040900005226C2301253846FFF7B8F90095CDF8C5
+:1040A00004A0B27D737D2A4903EB0223029305220B
+:1040B0006C2338460224FFF7A9F90094CDF804A038
+:1040C000327EF37D224903EB0223029305226C2307
+:1040D0003846FFF79BF9CDF800A0CDF804A0B27EDA
+:1040E000737E384603EB02230293194905226823A5
+:1040F000FFF78CF90095DFE077810200268102004E
+:10410000F080020017810200CB8202008783020048
+:10411000337E0200407E020011840200447D0200D2
+:10412000E68102002E840200618402002B800200DE
+:1041300078830200837D0200FD800200208302005C
+:10414000CA810200CF7E020084810200E87D020065
+:10415000AF7F020008EB090621AFAF4972783846FD
+:10416000FFF754F94FF0010AAC49B2783846FFF72F
+:104170004DF9CDF800A03279F378A94903EB022379
+:104180000193022200233846FFF740F9CDF800A042
+:10419000B2797379A24903EB0223019302225346B9
+:1041A0003846FFF733F9CDF800A0327AF379384674
+:1041B00003EB02230222019399491346FFF726F9E4
+:1041C000BBF11E0F40F26E829649727A3846FFF7B5
+:1041D0001DF99549B27A3846FFF718F99349F27AF2
+:1041E0003846FFF713F99249327B3846FFF70EF94C
+:1041F000CDF800A0B27B737B894903EB02230193C6
+:10420000052200233846FFF701F9CDF800A0327CE3
+:10421000F37B834903EB022301930522534638467F
+:10422000FFF7F4F8CDF800A0B27C737C7C4903EB77
+:10423000022301930522022300253846FFF7E6F802
+:104240000095CDF804A0327DF37C7A4903EB02237C
+:10425000029305226C233846FFF7D8F8CDF800A06A
+:10426000CDF804A0B27D737D724903EB0223029363
+:1042700005226C2338460224FFF7C8F80094CDF8D5
+:1042800004A0327EF37D6B4903EB022302930522E7
+:104290006C233846FFF7BAF80095CDF804A0B27E3B
+:1042A000737E384603EB022302936249052268239A
+:1042B000FFF7ACF8CDF800A0CDF804A0327FF37E74
+:1042C000384603EB02230293052268235949FFF77E
+:1042D0009DF80094CDF804A0B27F737F384603EBBD
+:1042E00002230293534905226823FFF78FF8D9E18F
+:1042F00008EB0904A378627821AD02EB03224E4952
+:104300002846FFF783F86279A379120402EB03626F
+:10431000E3782846D2182379484902EB0322FFF7B5
+:1043200075F8BBF1120F40F2BD81627AA37A1204D4
+:1043300002EB0362E3794249D218237A284602EB62
+:104340000322FFF763F8627BA37B120402EB036294
+:10435000E37A2846D218237B3A4902EB0322FFF77F
+:1043600055F8627CA37C120402EB0362E37BD21853
+:10437000237CABE0A278637821A803EB02230093AF
+:1043800031492B460222FFF741F801350234B5EBE3
+:104390005B0FEFDD86E1A278637821A803EB0223AF
+:1043A000009329492B460522FFF730F801350234E6
+:1043B000B5EB5B0FEFDD75E10095A278637821A87E
+:1043C00003EB02230193214905226C23FFF71EF81A
+:1043D000013502344FEA9B06B542EDDD002411E0C1
+:1043E00008EB5B034B44009403EB44039A785B783F
+:1043F00021A803EB02230193144905226823FFF748
+:1044000005F80134B442EBDD4CE108EB09039C787C
+:104410005A780F4921A824E19C7E02000A810200FB
+:1044200020830200D8810200DC7E0200938102001A
+:10443000F77D0200AF7F0200EB8302003E830200A3
+:1044400069810200067E0200D07D0200F681020032
+:104450004B80020008EB09039C785A78934921A805
+:10446000FFE008EB09039C785A78914921A8F8E00D
+:1044700008EB09039C785A788E4921A8F1E008EBF3
+:104480000904E2782379120402EB0362637821AD18
+:10449000D218A378884902EB03222846FEF7B6FF1C
+:1044A000E279237A120402EB036263792846D21878
+:1044B000A379824902EB0322FEF7A8FFE27A237B6D
+:1044C000120402EB0362637AD218A37A7C4928466D
+:1044D000FFF731BA08EB0904A378627821AD2846CA
+:1044E000784902EB0322FEF791FFBBF1040F40F283
+:1044F000D9802379E27874492846FFF71CBA08EB83
+:104500000904E2782379120402EB0362637821AD97
+:10451000D218A37828466D4902EB0322FEF776FFF6
+:10452000BBF1060F40F2BE80E279237A120402EB5F
+:10453000036263796649D218A3792846FFF7FBB96D
+:10454000644E09EB08040225AB45C0F2AB80E2786B
+:104550002379120402EB036263783146D218A37800
+:1045600021A802EB03220435FEF750FF043418366D
+:104570001A2DE9D196E0584E09EB08040225AB4507
+:10458000C0F29080E2782379120402EB0362637830
+:104590003146D218A37821A802EB03220435FEF796
+:1045A00035FF043413360E2DE9D17BE04B4E09EB79
+:1045B00008040225AB4575DBE2782379120402EB8F
+:1045C000036263783146D218A37821A802EB032254
+:1045D0000435FEF71BFF043414360E2DEAD161E0DA
+:1045E0003F4E09EB08040225AB455BDBE2782379FB
+:1045F000120402EB036263783146D218A37821A833
+:1046000002EB03220435FEF701FF043414360E2DAD
+:10461000EAD147E0334E09EB08040225AB4541DB04
+:10462000E2782379120402EB036263783146D218F0
+:10463000A37821A802EB03220435FEF7E7FE043439
+:1046400014360E2DEAD12DE008EB09039C785A7838
+:10465000254921A805E008EB09039C785A782349ED
+:1046600021A802EB0422FFF717B808EB0901CB7869
+:104670000A791B0403EB02634A788C789B181C4967
+:1046800021A8012203EB0423FEF7C0FE0AE019492A
+:1046900008EB090321A8FFF77FB901220B9201E083
+:1046A000FF2E29D00BEB0801FEF753BFB9830200A0
+:1046B0002B7D0200BD81020069810200067E02009E
+:1046C000128002003B8402004E84020060820200DD
+:1046D0007682020056800200047F0200517E0200B2
+:1046E0003D7F020008820200B47E0200607D02006D
+:1046F000BA8202004C8102000D9B01330D930D9A8A
+:10470000079B9A427EF41DAF0E9AB2F1FF3F03D091
+:1047100021A81749FEF77AFE9DF8443023B121A85D
+:10472000144911AAFEF772FE00201349DEF350F17E
+:1047300038B90B9B2BB91A4621A81049FF33FEF755
+:1047400065FE229A002302F8013B2E9B0A990093F2
+:104750000998069B2292FEF7ABFE0A9904464FF495
+:1047600080520998E2F3C4F2204625B0BDE8F08FEC
+:1047700022840200CF8302000E5D860021800200A9
+:104780002DE9F04F9A468FB000230D936D4B0646EE
+:104790001C7889460592002C40F0C180142208A89C
+:1047A0002146DDF34DF47369232B05DC01224FF024
+:1047B000040B0694079214E01C222346304621463F
+:1047C0000094E6F363F30028ACBF03230123ACBFDE
+:1047D0000022012207930692ACBF4FF00C0B4FF062
+:1047E000020B3046E6F306F30128054602D0022804
+:1047F00006D013E030464946DDF356F340000CE0A6
+:104800003046FBF7D9F8044640B1DDF3FBF210F473
+:10481000807F03D02046DDF3EBF20D900D99002947
+:1048200000F084804846E2F353F2044610B96FF07A
+:104830001A0083E0012D0746DDF8348003D0022DF5
+:104840000ED000251CE0002102900091CDF80480DC
+:1048500003913046059A4B46DDF320F305460DE003
+:104860000EAB4FEA580243F8042D30460121224690
+:10487000DDF37CF20D9B05465B000D93002D45D1C9
+:1048800023884FF6FD72013B9BB2934205D94846FF
+:1048900021464246E2F32CF24AE0069B1BB104EBB0
+:1048A0004B03089315E0638804EB0B01227901EBBD
+:1048B000132303EB0223A3F580530993E3880891A4
+:1048C000CB18A3F580530A932389C918A1F5805109
+:1048D0000B91DDB9189A4846009208A9079A5346E9
+:1048E000FEF708FE90B91849DEF346F038B1189B80
+:1048F0003046DAF800101A6800F024FB06E0189B36
+:104900003046DAF800101A6800F004FB27B1484678
+:1049100039464246E2F3ECF10A4B01221A700023B9
+:10492000189A1846CAF80030136007E00D4688460A
+:10493000064B0027089301230793CAE70FB0BDE891
+:10494000F08FC04640270000DEB00100B97D0200B4
+:1049500013B5049C9E4605994CB141B100232360D8
+:104960000B60009123467146FFF70AFF00E000202C
+:104970001CBDC046094A13888B4201D1002206E0C3
+:1049800093888B4202D04FF0FF3005E00122034BA9
+:1049900003EB820393F902007047C046BC84020017
+:1049A00070B50446E6F36AF2002105462046E6F3B8
+:1049B00037F4236A012B04D1D0F8003623F40073B6
+:1049C00004E005DDD0F8003643F40073C0F800368B
+:1049D00020462946E6F324F470BDC046036A70B54C
+:1049E000092B054601DC00242CE0E6F347F2002108
+:1049F00006462846E6F314F4D0F80836044613F4C5
+:104A0000807001D1044619E04FF00043C4F86C36C1
+:104A10004FF47A70E1F3A0F6D4F86C360022DB0490
+:104A2000DB0C5B03C4F86C2603F54243064A03F52E
+:104A3000A873B3FBF2F3642203FB02F42846314669
+:104A4000E6F3EEF3204670BDA08601002DE9F041AB
+:104A5000074614461E46002B7ED0E6F717F905469A
+:104A600002E0B34205D00C35002D75D02B88002B09
+:104A7000F7D12B88002B6FD0D4F80036AA78C3F377
+:104A80008403934268D0D4F81836642023F0C073AE
+:104A9000C4F81836D4F81C3643F6A12623F0C073A8
+:104AA000C4F81C36E1F358F603E00A20E1F354F6AB
+:104AB0000A3ED4F8E03113F4003F01D0092EF4D1BE
+:104AC0000023C4F86036EA782B79D4F864161B0604
+:104AD000120502F4700203F07063134321F07F614A
+:104AE0000B43C4F864360223C4F86036D4F8643645
+:104AF0006A7923F0FE5323F4781343EA025343F414
+:104B00008023C4F864360323C4F86036D4F86426DE
+:104B1000AB6802F07F4223F07F431343C4F864364E
+:104B20003B6A012B05DDD4F8003643F48063C4F8FA
+:104B30000036AA782988D4F8000692004FF68373CD
+:104B40007F3102F07C0200EA0303C9111A430139E4
+:104B500042EA0142C4F80026BDE8F0812DE9F041A7
+:104B6000044616460D46E6F389F1002180462046AC
+:104B7000E6F356F32946024633462046FFF766FF22
+:104B800020464146E6F34CF3BDE8F0812DE9F043C1
+:104B9000002485B0074603940294E6F36FF12146A2
+:104BA00081463846E6F33CF37B6A4E4A0546C3F33A
+:104BB000042605E0137AC5F82036D368C5F82836F0
+:104BC000494B083A9A42F5D14FF0000820E00821FD
+:104BD0006846464A4346DDF377F200206946DDF336
+:104BE000F7F698B100210A46DDF3B2F53B6A0C2BCB
+:104BF00008DDB0F5803F05D200F0FF02C0F30723C7
+:104C000042EA0340C5F82086C5F8280608F10108E5
+:104C1000B045DCD1364C28E0E36A13B138469847FA
+:104C200010B300211EE001238B40226A134218D0EA
+:104C3000C5F8201694F924302BB1012B05D0B3F11F
+:104C4000FF3F07D00DE0A36A09E0D5F82436A26A39
+:104C5000134304E0D5F82436A26A23EA0203C5F818
+:104C600024360131B142DED1103C224B9C42D3D1DB
+:104C7000002614E0082168461F4A3346DDF324F27B
+:104C8000002069466C46DDF3A3F638B10021C5F873
+:104C900020660A46DDF35CF5C5F824060136464574
+:104CA000E8D103A902AA3846E1F342F0029B039936
+:104CB00041EA0302D5F81C3642EA0303C5F81C3664
+:104CC0000AB1C5F81C2609B1C5F818164FF4FA60E8
+:104CD0000292E1F341F538464946E6F3A1F205B008
+:104CE000BDE8F083B484020094840200513686004B
+:104CF0007484020044840200563686002DE9F04395
+:104D000085B00546E6F3BAF0002181462846E6F371
+:104D100087F22B6A8046042B6B6A01DDDF0E01E00F
+:104D2000C3F34367002614E0102168460D4A33465A
+:104D3000DDF3CAF1002069466C46DDF349F638B16F
+:104D400000210A46DDF304F5C8F85066C8F8540699
+:104D50000136BE42E8D128464946E6F361F205B085
+:104D6000BDE8F0835B3686002DE9F043036A85B029
+:104D7000042B436A0546CCBFC3F38458C3F343589E
+:104D8000E6F37CF0002181462846E6F349F200264E
+:104D9000074615E0102168460E4A3346DDF394F1CC
+:104DA000002069466C46DDF313F638B100210A464F
+:104DB000DDF3CEF4C7F85866C7F85C06731CDEB2A4
+:104DC0004645E7D128464946E6F32AF205B0BDE854
+:104DD000F083C04663368600F7B5053A06461F469F
+:104DE000062A2BD8DFE802F00A0C12040E2A06006D
+:104DF00005250CE01125032402230AE0012502E029
+:104E0000052500E011250F24042302E000251F24BE
+:104E10000323009300214FF4CB624FF0FF33304661
+:104E2000E6F334F004EA0703AB4030460093002178
+:104E300040F25C6214FA05F3E6F328F0FEBDC046CA
+:104E40002DE9F04105460E4600201749DDF394F5A3
+:104E5000164984B20020DDF38FF540F2DC51002CBE
+:104E600018BF2146C7B22846FFF784FDC0B210F034
+:104E7000800F0CD1C4B23146284607222346FFF7E3
+:104E8000ABFF2846314608222346FFF7A5FF2FB186
+:104E9000284631463A460123E5F732FF2846314697
+:104EA000FFF762FFBDE8F0816F36860098C201000F
+:104EB00070B505460C46FFF721FF00222146284623
+:104EC000E1F38AF02846E5F3D9F70A4904460020C1
+:104ED000DDF352F54FF4002210F001034FF0000112
+:104EE000284618BF1346E0F3ABF728462146E6F301
+:104EF00097F170BD7836860070B500210546102008
+:104F0000E1F384F2002110220446DDF399F02046FB
+:104F1000656070BD70B50C461546E6F3EBF01021E8
+:104F2000E1F3D6F610B96FF01A0008E0044A102336
+:104F300043601368C460036085601060002070BD2A
+:104F40006C27000070B515460C46E6F3D3F010212F
+:104F5000E1F3BEF6024610B96FF01A0010E010231C
+:104F600043600849002303600B68C46085601BB977
+:104F70000860184604E0034618680028FBD11A6050
+:104F800070BDC0466C27000070B50C461546E6F3B0
+:104F9000B1F01021E1F39CF610B96FF01A0008E0AF
+:104FA000044A102343601368C46003608560106086
+:104FB000002070BD6C270000064B10B51B683BB984
+:104FC000054B196821B1054B1A680AB1FFF7DCFFE0
+:104FD000002010BD6C270000ECED0100F0ED010099
+:104FE000012070470020704710B50020DDF3C4F4A5
+:104FF00010BDC04610B50B490446FFF7F5FF80B25F
+:1050000078B9E06F0749DDF3B7F480B248B9E06FD3
+:105010000549DDF3B1F44FF6FF7380B2002808BFF5
+:10502000184610BD483786004E37860041F2E443EB
+:1050300070B5C36204460D4629B108460949DDF33F
+:105040009BF4A06240B900200749DDF395F4A0620B
+:1050500010B94FF6FF73A36228460449DDF38CF4C0
+:10506000206370BD543786005B3786008637860024
+:10507000836973B513F0005F04466FD08268B2F5A0
+:10508000026F01D101220AE040F604039A4201D0E6
+:10509000002204E0C3680C2B94BF002201224FF0D1
+:1050A0000003D5B2ADF8063055B920464FF4006183
+:1050B0002A46D4F8C860E6F3A1F000284ED005E0F7
+:1050C000D4F8843013F5405048D000266369222B71
+:1050D00003DC0023C0F8683100E00023C0F864312D
+:1050E000C0F860316369222B03DC1F4BC0F84431E8
+:1050F00005E00123C0F84831FE33C0F84C31636944
+:10510000222B07DC0023C0F88031C0F87C31C0F8C6
+:10511000783104E00023C0F87431C0F870311DB953
+:1051200020463146E6F37CF020460DF10601FFF7FC
+:1051300059FF0546A8B9BDF8063093B163690B491C
+:10514000222B2046D8BF4FF48021CCBF40224FF401
+:1051500080222B46E5F3B4F6284603E04FF0FF30FB
+:1051600000E000207CBDC0460000FBBF400055555C
+:105170002DE9F047002104461F46DDF82080DDF8C8
+:105180002490E6F34DF005462046E5F389F660618C
+:105190000A28C4BFEB6A63646B68A3616369222B4E
+:1051A000C4BFD5F8AC30E361A36913F0805F05D0CC
+:1051B000D5F80436636203F0FF0323624FF4E06323
+:1051C000A3604FF0FF33E3602546123300262361CE
+:1051D00016E031462046E6F323F02046E5F342F69A
+:1051E0002046E5F35DF61FB1D5F810319F4203D09C
+:1051F000D5F88830994501D1C8F8006001360435EA
+:10520000D4F8CC309E42E4D32046D8F80010E6F320
+:1052100007F00120BDE8F08730B585B0019000258A
+:1052200004A840F8045D01A90422DCF3A5F6019C62
+:10523000D4B122462946D2F8883013B10023C2F8EF
+:105240008830013104321029F5D10398DCF332F6AD
+:105250000398E5F763FE054B9C4205D0606D21463F
+:105260004FF45672E1F344F505B030BD88F5010006
+:105270002DE9FF470C9E1446DDF834808A464FF432
+:105280005672002105461F46DDF83890012E08BFF2
+:105290000026DCF3D5F611232B61C5F88470C5F820
+:1052A00058806C656E60002E40F0B980284631460B
+:1052B00052464346FFF794FE002800F0B0804FF0BE
+:1052C000C05422682846130F2B6013041B0CAB63D9
+:1052D000C2F30343C2F303522A640E3A012A8CBF7D
+:1052E00000220122EB6385F8482021465246FDF753
+:1052F00039FFD5F8CC30002B00F0918004AB43F897
+:10530000046D009328462146324633460197FFF745
+:105310002FFF002800F083802846FFF74DFE0F9AEC
+:105320006B6D2846019231463A46CDF80090FFF762
+:105330000FFB002873D1B9F1000F01D14E4601E0F7
+:10534000D9F8006028463146FFF770FE364B1C78CE
+:10535000002C30D16B69132B0BDD4FF40061284614
+:105360002246E5F34BF78465C46503992846E5F3C7
+:1053700057F72846696DFFF713FB2846696DFFF75D
+:1053800097FD30462949DDF3F7F2024620B9284659
+:10539000696DFFF723FB02462846696DFFF7DEFBC8
+:1053A0002846696DFFF7F2FB2846696DFFF748FD57
+:1053B0001D4B01221A706B690F2B0FDD1C49304603
+:1053C000DDF3DAF21B4B0021002808BF18460090DD
+:1053D000882228464FF0FF33E5F358F5304616494A
+:1053E000DDF3F6F238B114493046DDF3C5F201467B
+:1053F0002846E5F749FF6B69142B11DD002421468F
+:105400000822234628460094E5F340F5214640F063
+:105410000403082228460093E5F338F500E0002550
+:10542000284604B0BDE8F087E0F80100E2388600C5
+:10543000EB3886005A000A00F13886001FB5104C80
+:1054400086462178C9B90F4A0F4B002808BF02468B
+:1054500008BF034600910191029303920B4844F266
+:10546000107172464FF0C053FFF702FF00B905E01C
+:10547000074A2023136001232370044804B010BDA1
+:1054800084F5010008F6010004F6010088F501002A
+:10549000742700002DE9FF4781460D4608464FF46A
+:1054A000567192461E460D9FDDF83880E1F310F4E8
+:1054B000044610B30C9B494601932A465346009676
+:1054C0000297CDF80C80FFF7D3FE064638B9284680
+:1054D00021464FF45672E1F30BF430460EE00FB95B
+:1054E0003B4600E03B68E367B8F1000F01D143465B
+:1054F00001E0D8F80030C4F88030204604B0BDE8A0
+:10550000F087C04670B5044628B30368124918688E
+:105510002246FEF319F52546002610E0296A29B136
+:1055200023689868EAF3ACF000232B62E96921B1A3
+:1055300023682A8B5868E1F3DBF30136183561687C
+:105540008E42EBDB182201FB02F2236821465868E9
+:105550001032E1F3CDF370BD98C301002DE9F043A3
+:10556000036885B081467021D868E1F3B1F3044641
+:1055700008B9064648E0002170220646DCF360F5D3
+:105580000423636027464FF0B40325464FF000081C
+:10559000C4F80090A38112E0182208FB02F2103236
+:1055A0002C61D9F808001A49A2180023EAF384F004
+:1055B0002862183508B905461CE008F1010863683F
+:1055C0009845E9DB134BD9F80000009300230193C1
+:1055D000029303931049114A2346FEF37DF413E02E
+:1055E000396A29B123689868EAF34AF000233B62DC
+:1055F0000135183763689D42F2DB236821465868FD
+:105600007022E1F375F30026304605B0BDE8F08363
+:1056100099B500001DB4000074C3010099C30100D6
+:10562000034B012210B51A70E5F752FA10BDC046BF
+:1056300038F5010070B50446D0F884000D4608B175
+:10564000FDF74EF8D4F8800008B1FFF75BFFE06F7C
+:1056500008B1FAF707FCA06F08B100F001F9A068E3
+:1056600008B1FAF76DFF284621468C22E1F340F39A
+:1056700070BDC0460B682DE9F041DC694368054602
+:105680000E46D868A021E1F323F3C5F8880000286E
+:105690003ED00021A022DCF3D3F4D5F88820A36DFE
+:1056A000082182F87B30D5F88820636D82F87A3043
+:1056B000D5F88820E36D82F87C30236ED5F88820F9
+:1056C00082F87D306B68D868E1F302F3C6F84408CD
+:1056D000F0B1002108220127DCF3B2F486F841780A
+:1056E000D5F888402846C4F89C500B4922460B4BFD
+:1056F000E9F3E2F7C4F8980050B1D6F87C024A21E9
+:105700003A4621F041D80023184686F8403801E097
+:105710004FF0FF30BDE8F08191FF80008A418600A4
+:105720002DE9F04F064689B00D4600208C219146A8
+:105730009846139FE1F3CCF20446002874D0002170
+:105740008C22DCF37DF427603046FFF7D5FB07ABF6
+:105750000190059383464FF0000A204641F2E44150
+:1057600042463B460295CDF800A0CDF80C9004943B
+:10577000FBF7BAF80546002858D0A06000F0B0D971
+:105780002B696060E3602D4B1021A3642C4A3B46DB
+:10579000266164643046DCF397F42B6939461B6E4E
+:1057A00028489A6B284BE9F789FC504612993A46EB
+:1057B000264B0096CDF80490FDF710F9002835D15E
+:1057C00020462946FFF756FF064600282ED163687B
+:1057D000012283F878203621D5F87C0220F0D4DF2E
+:1057E0001B4B2846E36300F04DF8A067F0B1284654
+:1057F000FAF74CFBE067C8B12846FFF7AFFEC4F8E4
+:10580000800098B12846FCF799FFC4F8840068B17D
+:10581000104B019600930296039628680E490F4A92
+:105820002346FEF359F308B9204604E020465946C2
+:10583000FFF700FF002009B0BDE8F08F55F78000AA
+:10584000FB418600C4840200A4C3010029FB800040
+:10585000EFBEAD0D99F88000ECC30100C542860093
+:1058600010B5044658B10368054918682246FEF38E
+:105870006BF32368214658685422E1F339F210BDD6
+:105880002B7A860030B55421044685B04068E1F398
+:105890001FF208B9054611E0002154220546DCF349
+:1058A000CFF3084B2C6000930023019302930393E2
+:1058B00020680549054A2B46FEF30EF3284605B03D
+:1058C00030BDC046F1BD000038C401002B7A86000F
+:1058D0000020704710B5044698B10BF0B3D80949C1
+:1058E00060682246FEF330F3E16E21B163683C222A
+:1058F000D868E1F3FDF163682146D8687022E1F3CE
+:10590000F7F110BDD58D86007FB505467021406842
+:10591000E1F3DEF1064608B9044631E000217022C9
+:105920000446DCF38DF32B683560736068683C21B6
+:10593000E1F3CEF1E066F8B100213C22DCF380F324
+:10594000114B12490093002301930293104B114A0B
+:10595000039370683346FEF3BFF268B94FF001035A
+:105960007382B38230462946FFF7B2FF002803DB7B
+:1059700030460BF063D903E03046FFF7ABFF00245D
+:10598000204604B070BDC046390B830068C40100D6
+:10599000290C8300D58D860010B5044658B10368E4
+:1059A000054918682246FEF3CFF22368214658685D
+:1059B0000822E1F39DF110BDE3C40100F0B5082118
+:1059C00085B005464068E1F383F1064608B9044610
+:1059D00024E00021082200270446DCF331F30421EF
+:1059E0002846104A104B0097019601F091FFB842EB
+:1059F00070600FDB0D4B286800930D4B0D49019330
+:105A00000D4B0E4A039333460297FEF365F208B935
+:105A1000356003E03046FFF7BFFF0024204605B0A5
+:105A2000F0BDC04605C7000021C9000099C60000AE
+:105A300095C60000E8C4010091C60000E3C401005F
+:105A40002DE9F041066805461B4930682A46FEF3F9
+:105A50007BF22C460027D4F8081121B17068B4F805
+:105A60001021E1F345F1D4F80C1121B17068B4F8BC
+:105A70001221E1F33DF101374034042FEBD1D5F889
+:105A80000C1221B17068B5F81022E1F331F1D5F8AC
+:105A90001C1211B1B068E9F3F3F5D5F8201219B171
+:105AA00070683A46E1F324F1706829464FF4237296
+:105AB000E1F31EF1BDE8F081F4C4010010B5014628
+:105AC00020B10368B022D868E1F312F110BDC046DE
+:105AD0002DE9F34107680546B021F868E1F3F8F0D5
+:105AE000064608B980468BE00021B02201AC804612
+:105AF000DCF3A6F20422002137607560C5F85C6112
+:105B00002046DCF39DF22A6892F87C30012B07D9FD
+:105B10003D495069DCF35CF7014690B120460AE04C
+:105B200050693A49DCF328F70928034609D838496F
+:105B3000204601EB83010322DCF33AF300238DF8C6
+:105B4000073001AC0322214606F10800DCF330F3F4
+:105B50000023F3722B682F495869DCF30DF739697C
+:105B6000F060CA6A41F26B039A420CD18B6A8B2BAC
+:105B700009D1022807D1204627490422DCF3F8F294
+:105B800008B90323F360396941F26B03CA6A9A4288
+:105B90000DD18B6A932B0AD101A820490422DCF392
+:105BA000E7F220B9F368042B01D10233F36001AFAF
+:105BB000284639461FF04CDE044650B9184938468D
+:105BC0000322DCF3F5F2284639468DF807401FF032
+:105BD0003FDE05F5AA60394603220A30DCF3E8F21D
+:105BE000002405F5AA600F4985F85D450E300322B3
+:105BF000DCF3DEF285F861453046394620F0B2DA52
+:105C00004046BDE8FC81C046B3C48600B9C48600E6
+:105C1000CE028600BCC48600C3C4860071C2860062
+:105C2000C6C48600CAC4860010B50446E8F7A4FDC1
+:105C3000A16961B1237D23B1E068E9F30FF5002389
+:105C40002375E068A169E9F31BF50023A3612369CB
+:105C50002146D8682C22E1F34BF0002010BDC0464D
+:105C60002DE9F04107468846C0682C2114461E469F
+:105C7000E1F32EF008B9054619E0054600212C2273
+:105C8000DCF3DEF1EC602046EE61C5F808802F61A0
+:105C900008492A460023E9F30FF50446A86130B904
+:105CA0002B692946D8682C22E1F322F025462846A4
+:105CB000BDE8F0813D66840010B50349002200680C
+:105CC000FEF342F1002010BD49C586001FB5094A08
+:105CD0000B46009200220192029203920649074A63
+:105CE000FEF3FAF0002814BF4FF0FF30002005B09B
+:105CF00000BDC04609688400B8CA010049C58600D5
+:105D00001FB5084A034600920022019202920392B4
+:105D10000549064A0068FEF3DFF0003818BF01208D
+:105D200005B000BD35F3000078CB010048CB010081
+:105D300010B5B0F8BC400C80B0F8C0101180B0F8BD
+:105D4000C6201A8090F8C820029B01201A8010BD3E
+:105D500090F8D4007047C046D0F8CC007047C046D9
+:105D600010B5014618B180689822E0F3C1F710BD64
+:105D700070B5982104460068E0F3AAF708B9054613
+:105D800033E0002198220546DCF35AF12368AB602A
+:105D90006368EB60A3682B61E3686B6023696B61E8
+:105DA000238CAB84638CEB84636AAB62A36AEB6283
+:105DB000E36A2B63236B6B63636B6B64A36BAB64F2
+:105DC000E36BEB64236C2B65636C6B656369AB659C
+:105DD000A369EB650F232B662D336B663C33AB66F3
+:105DE0000323EB66002385F89430284670BDC04637
+:105DF00070B501210446E9F7A9FE2046E9F72EFF18
+:105E0000C0F30F33A4F8C630B4F8C620030F84F8EB
+:105E1000C83042F2640300F00F009A4284F8C900CF
+:105E200005D002339A4202D04FF0FF3500E0002542
+:105E300020460021EAF7F6FB284670BD70B50446FF
+:105E400000282DD0D0F8E4305D1EC0F8E4503DBBF2
+:105E500041F2B826815921B1C3691869F4F7FCFAF7
+:105E6000A55141F2CD13E5542046EAF7BBFAE169AA
+:105E70000A68A24203D1D4F8B4300B6005E0D2F82E
+:105E8000B430A34208BFC2F8B450E36E0BB1204651
+:105E90009847E3692146986841F25832E0F328F7C1
+:105EA00070BDC04670B5D0F8B8400E46E9B108469E
+:105EB000DCF356F10546C0B10FE0204631462A46D4
+:105EC000DCF33EF028B9635D3D2B02D1631C581909
+:105ED0000CE014F8013B002BFBD114B12378002B0C
+:105EE000EBD13046E1F3C2F600E0002070BDC046C1
+:105EF0002DE9F34141F22835435B064688462BB332
+:105F00000846DCF32DF104461448DCF329F124188B
+:105F10001034F369A7B298683946E0F3D9F604461D
+:105F200008B9054617E0735B0D4A009339464346AE
+:105F3000DCF3CAF021463046EBF714FDF369054661
+:105F4000214698683A46E0F3D3F625B930464146F3
+:105F5000EBF708FD05462846BDE8FC819ACC010018
+:105F6000A0CC01002DE9F04F41F2283B85B003930E
+:105F700030F80B30064689469246D0F8B880002BA0
+:105F800038D00846DCF3ECF004462448DCF3E8F0B3
+:105F90002418F3691034A7B298683946E0F398F6EC
+:105FA000054608B9044634E036F80B30394600930C
+:105FB0001B4A4B46DCF388F030462946EBF7E0FC01
+:105FC000834668B140462946DCF7FEFB40B15045A8
+:105FD00006DD404629465246DCF3DCF4044600E088
+:105FE000039CF369294698683A46E0F381F6BBF1D1
+:105FF000000F0ED140464946DCF7E6FB40B1504564
+:1060000006DD404649465246DCF3C4F4044600E04F
+:10601000039C204605B0BDE8F08FC0469ACC010035
+:10602000A0CC010070B590F8C43001229A401A4902
+:10603000013A0446D5B2EBF7D7FC41F20202C0B2F6
+:10604000A0540138C0B2FD2801D97323A354A25C27
+:1060500041F20303E25420461049EBF7C5FC41F23C
+:106060000402C0B2A05408B10F2801D10523A354E3
+:1060700041F20203E25C0233E35CD21A41F205030F
+:10608000E25400220133E2540233E25445EA05129D
+:10609000013BE25470BDC046178502002285020014
+:1060A0002DE9F84F88460021846807469246C0686B
+:1060B0000A469B46E4F3CEF610F0080F814615D051
+:1060C0003E689EB13046514600F084FA002800F048
+:1060D0007481F369D6F8CC1018692AF0E1DAD6F8A1
+:1060E000E43030460133C6F8E4306DE1204641F239
+:1060F0005831E0F3EDF50546002800F05C81002101
+:1061000041F258320646DBF39BF7012105F5915227
+:1061100041F2C41385F8E110EA50FA6CA3F5AC73B0
+:10612000013B9A42C5F8B080EF6105D17B6C932B9F
+:1061300002D1A5F8221603E04FF01802A5F8222696
+:106140006423002185F8E03041F208230422E95459
+:106150000133EA540133E9540133BAF1020FC5F8AF
+:10616000B8B0EA5406D119F0010F1CBF4FF4005328
+:10617000C5F8CC30EB69D5F8CC1018692AF090DA64
+:10618000D5F8B030B3F8E0339CB2EB69D868E4F7E7
+:1061900019FF41F22833E852C4F30323C5F8BC3099
+:1061A00004F00F03C5F8C030EB699A6A874BD31827
+:1061B000012B06D94AF6E6039A4202D0043B9A42E2
+:1061C00007D1EB69DB6A023B012B02D80923C5F832
+:1061D000C030D5F8BC30092B07D10423C5F8BC303A
+:1061E000D5F8C0301033C5F8C030012385F8C4306D
+:1061F000230BC5F8D030D5F8BC30022B0CD9042BBA
+:106200000AD0052B08D0062B06D0082B04D00A2B69
+:1062100002D0072B40F0D1803C23C5F8E43F002397
+:10622000C5F8E83F4FF40063A5F8DE3042F60132CE
+:1062300041F62433BAF1020F08BF1346A5F8DA304D
+:1062400095F8DA30284685F800376149EBF798FB76
+:1062500090B15F492846EC69EBF7C6FB5C492067C3
+:106260002846EC69EBF7C0FBEA69BAF1020F6067F8
+:106270000CBF136F536FD3660A2241F2D613EA5450
+:1062800003210133E9540123002485F8E83041F269
+:10629000F013EC54A3F5F273013A013BEA54EB69B5
+:1062A00085F8E94585F8EE4585F8F34585F8F84524
+:1062B00085F8FD45284683F89310FFF7B3FE41F2B9
+:1062C0000903EC544FF6CE7241F2B423EA5285F83A
+:1062D000F440621901347F23652C82F82C3682F851
+:1062E000913682F8B232F4D14FF0FF33A5F8FA3686
+:1062F000002385F8AC302846514601F037F90028D4
+:106300005BD02846E9F716FC2846FFF771FD0446E6
+:10631000002852D12F4906222846EBF759FB41F2BB
+:10632000D623E8542C4901222846EBF751FB41F2D1
+:10633000E423E854294922462846EBF749FB41F279
+:106340002A33E854264928460722EBF741FB41F25D
+:106350002B33E854224628462249EBF733FB6319D6
+:1063600003F5985301342833182C1871F2D1002406
+:10637000224628461C49EBF725FB6319013403F537
+:106380009A530E2C1871F3D1D5F8E430EA69013331
+:10639000C5F8E4301368D068C5F8B4303D60FEF746
+:1063A00067FE05F1B803C5F8B830284605F1BC0111
+:1063B0001C22DBF3E1F5284606E0B868314641F2DD
+:1063C0005832E0F395F40020BDE8F88F1D57FFFF29
+:1063D00054850200F8840200488502000A85020004
+:1063E00033850200418502000385020010B5024991
+:1063F0000268FDF3A9F510BD38D301001FB5094BA4
+:10640000094900930023019302930393074A036809
+:10641000FDF362F5002814BF4FF0FF30002005B0F7
+:1064200000BDC046F519010078D2010038D3010043
+:106430002DE9F041002580460F4616462C4607E020
+:1064400004EB0800E1190522DBF396F5013505346C
+:10645000B542F5D1BDE8F081022970B505460C467C
+:106460000AD0032911D0012916D106220B49E9F7D8
+:1064700013FBEA69002305E006220949E9F70CFB52
+:10648000EA69012382F8813006E006490622E9F72D
+:1064900003FBEB6983F8814070BDC046C0DB01009F
+:1064A000CCDB0100E0DB010070B5D0F8A840002390
+:1064B00094F8C113C4F874350F4A104B022914BF65
+:1064C00015461D46C3694FF420719868E0F300F447
+:1064D000C4F8740578B180222946FFF7A9FF94F823
+:1064E0003A35022B06D1D4F874050549A03015229F
+:1064F000FFF79EFF012070BD589502007C900200BE
+:106500001C9802002DE9F047D0F8A8308146D3F856
+:106510007C55D3F878A54FF0000817E0142403FB4E
+:1065200004F42B191A695B682F5903FB02F3DE0888
+:10653000D9F81C3031469868E0F3CAF308F1010835
+:10654000285140B139463246DBF316F55FFA88F33D
+:106550005345E3D30120BDE8F087C0462DE9F04163
+:10656000194BD0F8A8501A68C369002614210746B1
+:10657000C5F87C65C5F87825986802FB01F1E0F361
+:10658000A7F30446C5F87C05E0B1B0460FE0FB690F
+:1065900006EB04001B6D08F1010813F4805F14BFC3
+:1065A0000A490B4914227118DBF3E6F41436D5F8C6
+:1065B00078359845EBD338460121FFF7A3FF003823
+:1065C00018BF0120BDE8F081C4E90100988E0200E7
+:1065D000589D02002DE9F041884686B07A4905466B
+:1065E000D0F8A860EBF700FA784930722846EBF74C
+:1065F000FBF9774970722846EBF7F6F97549A5F86B
+:10660000FC002846EBF7F0F97349A5F8FE00284690
+:10661000EBF7EAF97149A5F800012846EBF7B0F964
+:1066200038B128466D49EBF7DFF910B1012386F840
+:10663000E83396F8E8330BB368492846EBF7D4F90A
+:106640006749A5F802012846EBF7CEF96549A5F898
+:1066500004012846EBF7C8F96349A5F80601284666
+:10666000EBF7C2F9614986F824052846EBF7BCF937
+:10667000002241F20B0386F82505EA545C492846BE
+:10668000EBF7B2F95B49C6F8340414222846EBF75D
+:106690009FF95949A6F83C045A222846EBF798F985
+:1066A000564986F8540408222846EBF791F95449D4
+:1066B00086F84C0403222846EBF78AF9514986F8FC
+:1066C0004D0408222846EBF783F94F4986F84E041B
+:1066D00003222846EBF77CF94C4986F84F04082240
+:1066E0002846EBF775F94A4986F8500403222846F4
+:1066F000EBF76EF9474986F8510408222846EBF774
+:1067000067F9032286F8520443492846EBF760F9FB
+:10671000424986F853042846EBF766F9404986F863
+:10672000580402222846EBF753F93E4986F8C10483
+:106730002846EBF725F928B128463A49EBF754F9F2
+:10674000F07400E0F07428463749EBF719F928B1E6
+:1067500028463549EBF748F9307501E008233375D1
+:1067600028463249EBF70CF928B128462F49EBF7B8
+:106770003BF9707501E00223737528462C49EBF74D
+:10678000FFF828B128462A49EBF72EF9B07501E049
+:106790000423B37528462749EBF7F2F828B12846B9
+:1067A0002449EBF721F9F07501E00823F375284639
+:1067B0002149EBF7E5F8002840D028461E49EBF7C1
+:1067C00013F930763CE0C046FA8C0200988C020047
+:1067D000DF890200E5890200EB890200BF8A02001E
+:1067E0009289020092880200858602009A86020041
+:1067F0006E8E0200388902006C8D0200E38D02006B
+:10680000338E0200B18D020073850200C28D02003A
+:1068100084850200A08D0200878E02006688020037
+:10682000B8860200E7870200D4870200EF870200E3
+:10683000DB8D0200D38D0200F28C0200022333763E
+:10684000B6492846EBF7D0F8B549B0722846EBF7C1
+:10685000CBF8B449F0722846EBF7C6F8B17AF27A71
+:10686000C3B230737173B273F37331747274B374EF
+:10687000AD492846EBF7B8F8B5F8FC2041F20A33E9
+:10688000EA520633EA52B5F8FE20043BEA520633D8
+:10689000EA52B5F80021043BC7B2EA52063385F844
+:1068A0001A71EA522846A149EBF79EF8002480B2FB
+:1068B0002A1900F00F030134A7EB43030009042C4D
+:1068C00082F81E31F4D128469949EBF78DF82A1940
+:1068D00000F00F030134A7EB430300090C2C82F8EE
+:1068E0001E31F4D193492846EBF77EF892490446CD
+:1068F0002846EBF779F880B240EA04417160142031
+:106900002A1801F00F030130A7EB430309091C28E3
+:1069100082F81631F4D189492846EBF765F88849A1
+:1069200070832846EBF760F8864930772846EBF706
+:106930005BF8854970772846EBF756F88349B077BE
+:106940002846EBF751F88249F0772846EBF74CF8E8
+:10695000804986F822002846EBF746F87E4986F8FB
+:1069600021002846EBF740F87C4986F8E0042846E9
+:10697000EBF73AF80127C6F8E40401AC7849204661
+:106980003A46DBF3B1F3D5F8B8002146DCF320F04A
+:1069900030B100210A46DBF3DBF6F31983F8E70494
+:1069A00001370F2FE9D16F492846EBF71DF86E49E3
+:1069B00086F8F6042846EBF717F86C4986F8F704D2
+:1069C0002846EBF711F86A4986F8F8042846EBF7F1
+:1069D0000BF8684986F8F9042846EBF705F866498C
+:1069E00086F8FA042846EAF7FFFF644986F8FB04B4
+:1069F0002846EAF7F9FF624986F8FC042846EAF7D8
+:106A0000F3FF604986F8FD042846EAF7EDFF5E498A
+:106A100086F8FE042846EAF7E7FF5C4986F8FF049B
+:106A20002846EAF7E1FF5A4986F800052846EAF7C2
+:106A3000DBFF584986F801052846EAF7D5FF564995
+:106A400086F802052846EAF7CFFF544986F8030581
+:106A50002846EAF7C9FF524986F804052846EAF7AE
+:106A6000C3FF504986F805052846EAF7BDFF4E49A1
+:106A700086F806052846EAF7B7FF4C4986F8070569
+:106A80002846EAF7B1FF4A4986F808052846EAF79A
+:106A9000ABFF484986F809052846EAF7A5FF4649AD
+:106AA00086F80A052846EAF79FFF444986F80B0551
+:106AB0002846EAF799FF424986F80C052846EAF786
+:106AC00093FF404986F80D052846EAF78DFF3E49B9
+:106AD000A6F814052846EAF787FF4FF00042A6F80B
+:106AE00016053A492846EAF773FF3949C6F81005F2
+:106AF0002846EAF779FF374986F824002846EAF75E
+:106B000073FF354986F823002846EAF76DFF3349BD
+:106B100086F820002846EAF767FF61E0AF850200AB
+:106B2000B58A020088890200A78902004489020010
+:106B3000F98B02006A85020061850200368A020034
+:106B4000A5850200978B0200A28B020095850200AA
+:106B50007E880200A8880200628A0200A88A0200D9
+:106B600008880200F1890200298B02003A8B02009A
+:106B70005B8D0200B38C0200C48C0200F18D020018
+:106B8000128E0200248A0200438A0200708A0200E8
+:106B9000D58C0200AD8B02000B8D02001D8D020012
+:106BA0002F8D0200418E0200538E0200F9850200F3
+:106BB00023860200218702004087020054880200D9
+:106BC00063870200A986020001890200068702008D
+:106BD000778D0200838D0200238E0200DA8B020083
+:106BE000B94985F826062846EAF7FEFEB74986F831
+:106BF000C1032846EAF7F8FEB54986F8C2032846DD
+:106C0000EAF7F2FE86F8C30395F8261611B1284676
+:106C1000FFF722FC4FF0FF32AE492846EAF7D8FED4
+:106C200080B210F4004F18BF4FF0FF324FF0FF3327
+:106C3000A6F86200A6F8663018BFA6F86220A6F88B
+:106C400068302846A449EAF79BFE58B12846A24975
+:106C5000EAF7CAFE80B210F4004F04BFA6F866003F
+:106C6000A6F8680028469D49EAF78AFE48B12846FA
+:106C70009A49EAF7B9FE80B210F4004F08BFA6F8AF
+:106C8000660028469649EAF77BFE48B128469449B3
+:106C9000EAF7AAFE80B210F4004F08BFA6F8680019
+:106CA00090494FF0FF322846EAF792FE4FF0FF324C
+:106CB000A6F8C4038C492846EAF78AFE8B49A6F851
+:106CC000C6032846EAF790FE8949A6F8C8034FF4A0
+:106CD000CF722846EAF77CFE8649C6F8CC0347F611
+:106CE0009A622846EAF774FE8349C6F8D0030A225E
+:106CF0002846EAF76DFE8149C6F8D40308222846E3
+:106D0000EAF766FE7E49C6F8D80341F26E022846CD
+:106D1000EAF75EFE0A22C6F8DC037A492846EAF75B
+:106D200057FE7949C6F8E0032846EAF75DFE774941
+:106D3000A6F8E4032846EAF757FE96F8E83380B24F
+:106D4000A6F8E6032BB103B2002BC4BF0022A6F8BD
+:106D5000E62350226E492846EAF73AFE6D4986F846
+:106D6000EA032846EAF740FE6B4986F8EC0328461A
+:106D7000EAF73AFE694986F8ED032846EAF734FE59
+:106D8000674986F8EE034FF0FF322846EAF720FE07
+:106D9000644986F8F0034FF0FF322846EAF718FE00
+:106DA0004FF0FF3486F8F1035F49224686F8EF433F
+:106DB0002846EAF70DFE5D4986F8F203224628468A
+:106DC000EAF706FE5A4986F8590522462846EAF7A8
+:106DD000FFFD584986F85A0522462846EAF7F8FD8D
+:106DE000554986F8F30322462846EAF7F1FD534950
+:106DF00086F85B0522462846EAF7EAFD504986F800
+:106E00005C0522462846EAF7E3FD4E4986F8F4037E
+:106E100022462846EAF7DCFD4B4985F8DA0522468A
+:106E20002846EAF7D5FD4949A6F8F6032246284642
+:106E3000EAF7CEFD4649A6F8F80322462846EAF7C7
+:106E4000C7FD4449A6F8FA0322462846EAF7C0FDE2
+:106E50004149A6F8FC0322462846EAF7B9FD3F4916
+:106E6000A6F8FE0322462846EAF7B2FD3C49A6F8FA
+:106E7000000422462846EAF7ABFD3A49A6F8020488
+:106E800022462846EAF7A4FD0022A6F80404364963
+:106E90002846EAF79DFD0022A6F85E0533492846FC
+:106EA000EAF796FD0022A6F8600531492846EAF780
+:106EB0008FFD0022A6F862052E492846EAF788FDD4
+:106EC0002D49A6F8640559E0178602000B860200DA
+:106ED000588C02005A890200DF8B0200498D0200A3
+:106EE0007587020087870200E88A0200E2860200B6
+:106EF000EF8B020068860200818902008E87020003
+:106F0000028D0200178C02004B8C02004C8902009B
+:106F1000888802004B8B0200D88502006F8B02002C
+:106F20005D860200C7880200E78C0200748C0200B4
+:106F30003387020072880200EB860200898B020010
+:106F4000A5870200948A0200D4890200718602009B
+:106F50001E8C020076890200F9860200B9880200C0
+:106F60009B890200288802002B8C0200EF8A020015
+:106F7000DA8A0200888C0200548B02002846EAF765
+:106F800033FDB8F1020F86F8060414D12846A4494F
+:106F9000EAF7F6FC002800F0A382344600273A46C0
+:106FA00028469F49EAF70EFD0137C4F80C04043463
+:106FB000052FF4D116E0B8F1010F13D128469949F5
+:106FC000EAF7DEFC002800F08B82344600273A46C0
+:106FD00028469449EAF7F6FC0137C4F82004043443
+:106FE000052FF4D190494FF0FF322846EAF7F0FC24
+:106FF0008E49A6F83E044FF0FF322846EAF7E8FC37
+:107000008B49A6F840044FF0FF322846EAF7E0FC2F
+:107010008849A5F8CE0F2846EAF7B2FC30B12846D9
+:107020008449EAF7E1FC41F2DA23E8528249284632
+:107030004FF0FF32EAF7CCFC41F22433E8527F49AB
+:107040002846EAF79DFC30B128467C49EAF7CCFC9B
+:1070500041F2DE23E852284679490022EAF7B8FCDB
+:10706000C0B286F84D0358B176492846EAF7BCFC11
+:107070007549C6F850032846EAF7B6FCC6F860031F
+:1070800028467249EAF77CFC28B3D5F8B8006F4966
+:10709000DBF79AFB06281ED1344600273A466B4997
+:1070A000D5F8B800DBF376F484F895037A1C6749C9
+:1070B000D5F8B800DBF36EF484F89703BA1CD5F862
+:1070C000B8006249DBF366F4033784F899030134AE
+:1070D000062FE3D111E0012386F89533313386F88A
+:1070E00096330E3386F8973386F89833042386F860
+:1070F00099334FF0FF3386F89A3355492846FF22DB
+:10710000EAF766FC4FF0FF03A6F85403A6F85633DF
+:10711000A6F85833A6F85A3328464E49EAF730FC09
+:1071200028B3D5F8B8004B49DBF74EFB34460328AB
+:10713000B4BF80464FF00308002707E03A462846D0
+:107140004449EAF73FFC0137A4F8540302344745A9
+:10715000F4DB06EB470303F55473063304E0B6F89B
+:107160005623013723F8022C0233022FF7DD0122C8
+:1071700039492846EAF72CFC384986F84003284666
+:10718000EAF732FC012286F84B0335492846EAF734
+:107190001FFC344986F841032846EAF725FC3249AA
+:1071A00086F84C034FF0FF322846EAF711FC2F49CE
+:1071B00086F849034FF0FF322846EAF709FC2C49CC
+:1071C00086F84A034FF0FF322846EAF701FC2949C6
+:1071D00086F85C034FF0FF322846EAF7F9FB2649B0
+:1071E00086F85D032846EAF7CBFB002846D0012449
+:1071F0002149002286F8BB442846EAF7E3FB1E49F2
+:1072000086F8BC0422462846EAF7DCFB1A4986F8D1
+:10721000BD0402222846EAF7D5FB86F8BE042FE01B
+:1072200098870200FF8A02007D860200818C02009E
+:10723000C1890200D3880200028E0200BF8B0200C7
+:10724000138702005B8B02001D8902005287020037
+:10725000DF880200778E02009F8C020036880200D1
+:10726000C3860200028C020041860200B08902003F
+:10727000788B0200028A0200658E020086F8BB0449
+:10728000FF2299492846EAF7A3FBFF2286F8BF04AC
+:1072900096492846EAF79CFB954986F8C00428469B
+:1072A000EAF7A2FB0022A6F8C20492492846EAF7B0
+:1072B0008FFB002286F818058F492846EAF788FBDD
+:1072C000C0B286F81A05EB69DB685B6C03F0070354
+:1072D000052B03D910B1002386F81A3587490022FF
+:1072E0002846EAF775FB864986F81C0500222846E1
+:1072F000EAF76EFB834986F81D054FF0FF322846FA
+:10730000EAF766FB804986F81E0500222846EAF760
+:107310005FFB7E4986F895054FF0FF322846EAF775
+:1073200057FB7B49A6F8200501222846EAF750FBC7
+:10733000784986F827054FF0FF322846EAF748FBE0
+:107340007549A6F82A054FF0FF322846EAF740FBB8
+:107350007249A6F82C0500222846EAF739FB704945
+:1073600086F83A0500222846EAF732FB6D4986F88E
+:107370003B054FF0FF322846EAF72AFB6A4986F8B8
+:107380003C052846EAF7FCFA30B128466649EAF798
+:107390002BFB86F8420503E04FF0FF3386F84235B9
+:1073A00028466249EAF7ECFA30B128465F49EAF725
+:1073B0001BFBA6F8440503E04FF0FF33A6F8443565
+:1073C0005B4928464FF0FF32EAF702FB5949A6F81D
+:1073D00090052846EAF7D4FA30B301245549002233
+:1073E00086F852452846EAF7EDFA524986F85305E1
+:1073F00022462846EAF7E6FA4E4986F85405022264
+:107400002846EAF7DFFA4B4986F855050322284655
+:10741000EAF7D8FA474986F8560504222846EAF7DB
+:10742000D1FA86F8570501E086F8520542494FF037
+:10743000FF322846EAF7CCFA404986F858054FF063
+:10744000FF322846EAF7C4FA3D4986F859054FF05D
+:10745000FF322846EAF7BCFA3A4986F85A05002274
+:107460002846EAF7B5FA384986F87005002228461A
+:10747000EAF7AEFA032286F8800534492846EAF78F
+:10748000A7FA334986F881052846EAF7ADFA31496B
+:1074900086F882052846EAF7A7FA2F49A6F8840558
+:1074A0002846EAF7A1FA2D49A6F886052846EAF704
+:1074B0009BFA2B49A6F888052846EAF795FA294948
+:1074C000A6F88A052846EAF78FFA2749C6F88C05F8
+:1074D00000222846EAF77CFA86F89405012000E0AD
+:1074E000002006B0BDE8F081FA8C0200418D020058
+:1074F0008A860200E58502000C8B0200138A0200D6
+:10750000638C0200558A0200CB850200AF8702001F
+:10751000B9850200D7860200BC8702009F86020060
+:10752000C88702001F8B02009B880200358602007C
+:10753000DC8702005286020069890200748C020016
+:10754000338702001089020019880200F7870200C1
+:107550004B880200C98B0200398C0200828A02002B
+:10756000C88A0200EF880200918D0200C36970B5DD
+:1075700004460E4698684FF4B961DFF3A9F3C4F8E6
+:10758000A80000285BD000214FF4B962DAF358F567
+:10759000E369D4F8A8501B6D13F4803F05D1012294
+:1075A00041F2140384F81A26E254E369D868E3F739
+:1075B00049FD0023C4F8F80FEB63224B20462362F9
+:1075C000214B31466362214BA362214BE362214B85
+:1075D000A367214BE367214BC4F89030204BC4F8DC
+:1075E0008430204B2363204B6363204BE363204BA9
+:1075F0006364204B6365204BA365204BC4F88C303B
+:107600001F4BC4F888301F4BE3661F4BC4F89C30F7
+:107610001E4BC4F8A0301E4BC4F8A430FEF7DAFFAE
+:1076200068B12046ECF7CEF82046FEF73DFF30B1BA
+:107630002046FEF793FF003818BF012000E000202D
+:1076400070BDC0465DA30100A51D010045A001005D
+:107650001175010075730100DD210100317C01000D
+:10766000197C0100896E0100795A0100F96E010050
+:10767000B95701005D280100612A0100359F010012
+:10768000851E010071260100D55A0100D154010068
+:10769000FD9E010010B5014620B103680C22186858
+:1076A000DFF326F310BDC0462DE9F04105460F4635
+:1076B00000680C211646DFF30BF308B9044607E017
+:1076C000044600210C22DAF3BBF425606660A76053
+:1076D0002046BDE8F081C04610B5044650B10649C9
+:1076E00022464068FCF330F463682146D86888225B
+:1076F000DFF3FEF210BDC04603E88600F0B5882136
+:1077000085B005464068DFF3E3F2074608B9044652
+:107710003BE0002188220446DAF392F42B683D60B6
+:107720007B60002604212846194A1A4B00960197CF
+:1077300000F0EEF8B042B86021DB174B01960093E1
+:107740000296039678681549154A3B46FCF3C4F344
+:10775000A8B91E237B610423FB7302233B74083307
+:1077600001227B744FF6AF7384F82000FA773A73E6
+:10777000BA61A0746073A073BB83BA7705E06868D0
+:1077800039468822DFF3B4F20024204605B0F0BD6C
+:1077900051238500252385008114850050EC0100CC
+:1077A00003E8860070B50468CCB1D4F8F811A56878
+:1077B00029B1A868E7F364F70023C4F8F831084951
+:1077C00028682246FCF3C0F3216819B168681C22BE
+:1077D000DFF38EF2686821466269DFF389F270BDDB
+:1077E00068EC01002DE9FF4740F2C45681468A4605
+:1077F0001046314617469846DFF36AF204460028E1
+:1078000079D000213246DAF31BF438461C21DFF32D
+:107810005FF20546206030B9384621463246DFF334
+:1078200067F2284667E000211C22DAF309F4226897
+:107830004FF0FF33A36100254FF014036661C4F8D5
+:107840000890E760C4F804809571A4F808324FF0FE
+:107850002803A4F806324FF02D03A4F804324FF0A9
+:10786000FA03A4F80A320223146084F80C324FF0B1
+:107870006403A4F83E3284F80D5250461F49224654
+:107880002B46E7F319F7C4F8F80108B30523C4F849
+:107890001C323733C4F8283204F51072184BC4F880
+:1078A0001822C4F8142204F53D72C4F82422C4F846
+:1078B00020220093134BD9F8000003931249134A76
+:1078C000234601950295FCF307F308B9206812E0FE
+:1078D000D4F8F81111B15046E7F3D2F6216819B186
+:1078E00038461C22DFF304F23846214640F2C452E7
+:1078F000DFF3FEF1002004B0BDE8F087C13C850055
+:10790000F5378500E9A4010070EC010068EC010086
+:1079100070B5D0F800451E46A3698E460F2B15465C
+:1079200002D94FF0FF3011E01801E1690133A36182
+:10793000049B42189360059B5660D3606269455072
+:10794000D31C734423F003036361104670BDC0462B
+:1079500010B5014640B190F820200368D200D868E5
+:1079600002F59272DFF3C4F110BDC046C36908226C
+:107970001B692DE9F041073393FBF2F3DFB2FB0003
+:1079800003F5927605463146C068DFF3A1F108B9E8
+:10799000044614E0044632460021DAF351F304F1C0
+:1079A0002403E361FAB204F59273E36003EB82030C
+:1079B00023614FF40373256084F8207063612046CF
+:1079C000BDE8F0817047C0462DE9F04F3B4F89B0CC
+:1079D00038683B49DAF3D0F70128DFF81881DFF87F
+:1079E000189157D0DFF800C1364EDCF800100022A5
+:1079F0000091354913680968344D354C029131685E
+:107A00003448019304912B6821680393069103681D
+:107A1000314905930B68DFF8D4E007932A4B0260E5
+:107A20002E481A600A602E4B08F10401D7F800A016
+:107A3000DEF800B03A60CEF80020CCF800203260CA
+:107A40002260091A013A2B60DAF3EAF7254B9842D3
+:107A5000FCD11A4B0099C3F800A0234B1960234BAB
+:107A60000021C3F800B00A68214B1A60019A164B36
+:107A70000A600299039A1960144B04991A60114B19
+:107A8000059A1960134B06991A60114B079A1960F1
+:107A9000114B1A6098F81B3089F8003098F81C30A8
+:107AA00089F8013098F81D3089F8023098F81E30B6
+:107AB00089F8033009B0BDE8F08FC046ECED010055
+:107AC000DCEC0100CCA30000D0A30000BCA30000AC
+:107AD000D8A30000D4A30000DCA300000000000035
+:107AE000DDBAADBBE320BBDEF0ED0100E8ED010047
+:107AF000C0A30000BE24030018F501002DE9F04FDB
+:107B000091B0FFF761FF684B1B68043B012B03D862
+:107B1000664B1868FFF756FFFAF7AEFF00210746DD
+:107B2000E3F3C4F338460021E3F37AF328B1036AA0
+:107B3000002BBCBF4FF0004303620EA90822B86BB4
+:107B4000DAF30CF5FA6B0B9038460C92E3F77AFAFD
+:107B5000574E00F5424000F5A870B0FBF6F00D90CE
+:107B60003846E3F76FFA04463846E3F76BFA00F558
+:107B700042483846E3F770FA00F5424A3846E3F7E0
+:107B80006BFA04F5424408F5A87804F5A874B8FB2C
+:107B9000F6F808FB164804463846E3F75DFA00F5A8
+:107BA00042453846E2F7E2FF00F542493846E2F73F
+:107BB000DDFF04F5424405F5A87504F5A874B5FB8E
+:107BC000F6F505FB164504463846E2F7CFFF394A7D
+:107BD00000F54240019204F542440B9A00F5A8706A
+:107BE000B0FBF6F00AF5A87A09F5A87904F5A874AF
+:107BF000BAFBF6FAB9FBF6F9029200FB16460C9AAC
+:107C0000DFF8D4B003920D9A2B4B04922B492C4AE7
+:107C1000B8FBFBF8B5FBFBF5B6FBFBF62948009378
+:107C2000CDF81480CDF818A00795CDF820900996CE
+:107C3000E7F744FA244840F60D0144F2F432FAF72B
+:107C40009FFE48B1204840F6290144F2F432FAF789
+:107C500097FE08B1002403E01C4A1D4B1A4C1A6021
+:107C60003846FDF7C7F944F218334FF6FF729042D9
+:107C700014BF02461A4640F612011648FAF780FE73
+:107C8000144B00280CBF194600214CB141B1104BD8
+:107C900020461B685B689847236920465B689847C5
+:107CA000384611B0BDE8F08FDCA30000D8A3000077
+:107CB00040420F00A4C30100ABFF8600E2EC0100CC
+:107CC000E7EC0100BC9D02003CEE010018EE010053
+:107CD000F826000068EE0100A086010025733A2016
+:107CE00042726F6164636F6D20534450434D442072
+:107CF000434443206472697665720A00736470635A
+:107D00006D6463646325640072737369736D6632B6
+:107D1000673D2564007874616C667265713D256409
+:107D200000616132673D30782578006277343070C9
+:107D30006F3D30782578006C6564626825643D305D
+:107D40007825780074737369706F7332673D30788B
+:107D50002578007273736973617632673D2564001C
+:107D60006C65676F66646D3430647570706F3D303C
+:107D70007825780070613168696D61787077723D3F
+:107D80002564006D617870326761303D3078257808
+:107D9000007061316974737369743D2564006D61AD
+:107DA0006E6669643D307825780073756276656E1D
+:107DB0006469643D30782578002004D0023643FFA2
+:107DC000FF626F617264747970653D307825780068
+:107DD0006D6373256467706F25643D307825780086
+:107DE0006D616E663D2573006D61787035676C61FD
+:107DF000303D30782578006D61787035676C613181
+:107E00003D30782578006F66646D35676C706F3D26
+:107E1000307825780072737369736D6335673D251B
+:107E20006400626F617264666C616773323D3078C2
+:107E3000257800747269736F32673D307825780059
+:107E40007064657472616E676532673D307825785D
+:107E5000006D63736277323035676C706F3D3078D8
+:107E600025780000006D637362773230756C35677A
+:107E70006C706F3D30782578006D637362773430B5
+:107E800035676C706F3D3078257800000070613187
+:107E90006C6F6D61787077723D2564006D617870EC
+:107EA000326761313D30782578007278706F3567C0
+:107EB0003D2564006D63733332706F3D30782578F3
+:107EC0000073756264657669643D30782578006971
+:107ED0007474356761303D30782578006974743585
+:107EE0006761313D30782578007061316D6178705F
+:107EF00077723D256400626F6172647265763D3011
+:107F0000782578006D6373627732303267706F3D29
+:107F1000307825780000006D637362773230756CBD
+:107F20003267706F3D30782578006D637362773407
+:107F3000303267706F3D307825780000006D6373D4
+:107F40006277323035676D706F3D3078257800008C
+:107F5000006D637362773230756C35676D706F3D9D
+:107F600030782578006D63736277343035676D70D3
+:107F70006F3D3078257800000073726F6D72657602
+:107F80003D2564007770736C65643D256400706105
+:107F9000316C6F62303D2564007061316C6F62310D
+:107FA0003D2564007061316C6F62323D2564007064
+:107FB0006125646725637725646125643D307825F4
+:107FC000780070613062303D25640070613062314C
+:107FD0003D25640070613062323D25640072737328
+:107FE00069736D6332673D25640074726935676833
+:107FF0003D25640075736266733D25640063636BA1
+:10800000706F3D307825780074726935676C3D2556
+:1080100064006F66646D356768706F3D30782578F1
+:1080200000616725643D307825780065787470615B
+:108030006761696E35673D307825780070726F64CE
+:108040007563746E616D653D257300636464706F64
+:108050003D30782578006C65676F66646D627732B5
+:108060003035676C706F3D307825780000006C65A6
+:10807000676F66646D62773230756C35676C706FF0
+:108080003D30782578006C65676F66646D62773285
+:108090003035676D706F3D307825780000006C6575
+:1080A000676F66646D62773230756C35676D706FBF
+:1080B0003D30782578006C65676F66646D62773255
+:1080C00030356768706F3D307825780000006C654A
+:1080D000676F66646D62773230756C356768706F94
+:1080E0003D30782578007278706F32673D256400E6
+:1080F0007278636861696E3D3078257800697474C0
+:10810000326761303D307825780069747432676178
+:10811000313D3078257800616E74737769746368D7
+:108120003D30782578007478636861696E3D3078F9
+:1081300025780070726F6469643D3078257800702E
+:1081400061306974737369743D25640063636B64A3
+:10815000696766696C74747970653D25640063684D
+:1081600069707265763D2564006F66646D35677071
+:108170006F3D30782578006C656464633D30782508
+:10818000303478006D61787035676861303D3078E3
+:108190002578006D61787035676861313D307825EC
+:1081A000780070613162303D256400706131623168
+:1081B0003D25640070613162323D25640062776460
+:1081C0007570706F3D30782578006D617870356717
+:1081D00061303D30782578006D61787035676131A8
+:1081E0003D3078257800616E74737763746C356701
+:1081F0003D30782578006D63732564672563706F63
+:1082000025643D30782578006D63736277323035B0
+:108210006768706F3D307825780000006D63736289
+:10822000773230756C356768706F3D30782578002F
+:108230006D637362773430356768706F3D307825D1
+:108240007800000074726935673D2564006F706FB7
+:108250003D25640076656E6469643D30782578005C
+:108260006C65676F66646D627732303267706F3D40
+:108270003078257800006C65676F66646D627732D0
+:1082800030756C3267706F3D307825787061306D75
+:1082900061787077723D2564007061316869623081
+:1082A0003D256400706131686962313D256400706C
+:1082B0006131686962323D256400637573746F6D66
+:1082C00076617225643D3078257800726567726545
+:1082D000763D3078257800626F617264666C616704
+:1082E000733D307825780062786132673D256400FF
+:1082F0006F656D3D25303278253032782530327803
+:108300002530327825303278253032782530327871
+:10831000253032780064657669643D3078257800D0
+:1083200070612564677725646125643D3078257820
+:108330000072737369736D6635673D2564006F66FF
+:10834000646D3267706F3D30782578006161356704
+:108350003D30782578007770736770696F3D2564CC
+:108360000062786135673D25640075736265706EE3
+:10837000756D3D307825780074737369706F73354F
+:10838000673D3078257800616E74737763746C3262
+:10839000673D30782578007273736973617635674D
+:1083A0003D2564006F66646D706F3D307825780000
+:1083B00074726932673D25640073746263706F3D47
+:1083C000307825780063636F64653D307830006DE8
+:1083D0006163616464723D25730063636F64653D2E
+:1083E000256325630063633D25640063636B326727
+:1083F000706F3D30782578006363746C3D3078256C
+:10840000780072656777696E646F77737A3D25646B
+:108410000065787470616761696E32673D307825F8
+:108420007800626F6172646E756D3D2564007472D0
+:1084300069736F35673D307825780063636B6277C9
+:1084400032303267706F3D3078257800000063630A
+:108450006B62773230756C3267706F3D307825789B
+:10846000007064657472616E676535673D307825AC
+:108470007800000080000000FF0000000C000000F9
+:108480000000000000040000FF0000000C000000DD
+:108490000000000000000800FF0000000E000000C7
+:1084A00000000000020000000100040003000000C2
+:1084B000010002000A00000002006000DC0500006C
+:1084C00008071700776C25643A2042726F61646375
+:1084D0006F6D2042434D2564203830322E313120DB
+:1084E000576972656C65737320436F6E74726F6C3D
+:1084F0006C65722025730A00747870777262636B02
+:108500006F660032675F6367610072737369636FE0
+:1085100072726E6F726D0074656D707468726573DF
+:10852000680074656D70735F6879737465726573E4
+:1085300069730072737369636F7272617474656ECC
+:108540000035675F63676100747373696C696D758B
+:10855000636F6400696E746572666572656E6365EB
+:10856000006D63733267706F30006D6373326770D4
+:108570006F3100747373696F66667365746D696ECD
+:1085800035676C00747373696F66667365746D69C3
+:108590006E35676D0074656D7073656E73655F73BE
+:1085A0006C6F7065006D656173706F7765720072D6
+:1085B000737369736D66326700706C6C646F75629B
+:1085C0006C65725F6D6F646532670069716C6F73A3
+:1085D00074316F6666326700726672656730333376
+:1085E0005F63636B00706C6C646F75626C65725F67
+:1085F000656E61626C653267006F70656E6C706786
+:1086000061696E69647861313430006578747061D5
+:108610006761696E35670065787470616761696E5E
+:108620003267006F70656E6C706761696E6964783F
+:108630006131343900747869716C6F7061673267C9
+:10864000006E6F6973655F63616C5F7265665F3250
+:1086500067006C6F67656E5F6D6F64650070616366
+:10866000616C69647832670074656D705F61646421
+:1086700000706163616C61746832673100646163CA
+:108680006763326700706D696E00706163616C7062
+:10869000756C7365776964746800706D61780074D7
+:1086A000786761696E74626C006F70656E6C70746F
+:1086B000656D70636F727200747373696D61786E4B
+:1086C0007074006E6F6973655F63616C5F656E6186
+:1086D000626C655F356700706163616C70777232E0
+:1086E0006700747869716C6F746600706163616CA7
+:1086F00069647835676C6F3100706163616C6174B7
+:108700006835676869006F70656E6C707077726C41
+:10871000696D006E6F6973655F63616C5F6462674A
+:10872000006F70656E6C706761696E696478613145
+:10873000353300706163616C69647835676869001E
+:108740006F70656E6C706761696E696478613135F0
+:1087500037006E6F6973655F63616C5F757064612C
+:108760007465006F70656E6C706761696E696478BE
+:1087700061313635006F66646D64696766696C7473
+:10878000747970653567007061676332670076627F
+:1087900061745F6D756C740073776374726C6D6176
+:1087A000705F326700706163616C616C696D006954
+:1087B000716C6F63616C70777232670070616361B6
+:1087C0006C7077723267310074786761696E7462B9
+:1087D0006C35670076626174736D63006164637207
+:1087E0006673657132670076626174736D660076D8
+:1087F0006261747361760072786761696E62616349
+:108800006B6F666676616C006F70656E6C70676129
+:10881000696E6964786225640072786761696E7454
+:10882000626C776C62676100706163616C6174682F
+:108830003567686931006E6F6973655F63616C5F8E
+:10884000706F5F626961735F32670072667265673D
+:10885000303838006F70656E6C706761696E69647E
+:1088600078613136310064796E7077726C696D654C
+:108870006E00706163616C6964783567310074659E
+:108880006D70636F727278006461637261746532D7
+:10889000670070613062325F6C6F00747869716C70
+:1088A0006F7061707532670074656D7073656E739B
+:1088B000655F6F7074696F6E00706163616C617485
+:1088C0006835676C6F3100706163616C6964783220
+:1088D0006731007478616C70666279703267006E1F
+:1088E0006F6973655F63616C5F706F5F326700759E
+:1088F0006E6D6F645F727373695F6F6666736574C4
+:10890000006F70656E6C70766F6C74636F7272005E
+:1089100072786761696E74626C313030006E6F69B5
+:1089200073655F63616C5F6E665F737562737472AB
+:108930006163745F76616C007473736974786465E5
+:108940006C61790063636B3267706F0063636B50B7
+:108950007772496478436F72720063636B6469670E
+:1089600066696C7474797065006C6F696461636DBD
+:108970006F6465356700706163616C617468356749
+:108980000074656D705F7100727373697361763224
+:10899000670070613062315F6C6F00706163616CA1
+:1089A000617468356731006D6178703267613000DD
+:1089B0006E6F6973655F63616C5F7265665F356773
+:1089C000006F66646D616E616C6F6766696C74627E
+:1089D00077326700706163616C6174683267007040
+:1089E000613062300070613062310070613062323B
+:1089F000006F70656E6C706761696E696478613371
+:108A000036006E6F6973655F63616C5F61646A5F96
+:108A100035670069716C6F63616C69647832676F88
+:108A2000666673006F70656E6C706761696E69640D
+:108A300078613130300072617774656D7073656E86
+:108A40007365006F70656E6C706761696E696478DC
+:108A5000613130340069716C6F63616C69647832C4
+:108A600067006F70656E6C707077726374726C0003
+:108A70006F70656E6C706761696E696478613130C2
+:108A8000380072786761696E74656D70636F7272B9
+:108A900035676D0074785F746F6E655F706F7765B2
+:108AA000725F696E646578006F70656E6C70726578
+:108AB000667077720072737369736D6332670070EA
+:108AC000613062305F6C6F0072786761696E7465E7
+:108AD0006D70636F727235676C00706163616C6991
+:108AE000647835673174680070616763356700705A
+:108AF0006163616C69647835676C6F3174680073A9
+:108B0000776374726C6D61705F3567007370757236
+:108B100061766F69645F656E61626C653267006C77
+:108B20006F63636D6F646531006F70656E6C706745
+:108B300061696E696478613430006F70656E6C7065
+:108B40006761696E69647861343400726672656762
+:108B500030333300706172667073006E6F697365D5
+:108B60005F63616C5F686967685F6761696E007207
+:108B700066726567303338006E6F6973655F636175
+:108B80006C5F61646A5F326700706163616C696425
+:108B9000783567686931006D656173706F776572EC
+:108BA00031006D656173706F77657232006F70654B
+:108BB0006E6C706761696E6964786131313600622C
+:108BC0007068797363616C650072786761696E744F
+:108BD000656D70636F727232670061613267006F3A
+:108BE00066646D64696766696C7474797065007435
+:108BF000656D705F6D756C74006F66646D32677063
+:108C00006F006E6F6973655F63616C5F706F5F6249
+:108C10006961735F356700766261745F71007061CE
+:108C200063616C61746835676C6F00706163616C5F
+:108C300069647832673174680072786761696E744C
+:108C4000656D70636F72723567680063636B507730
+:108C5000724F6666736574007478707772696E64BB
+:108C600065780069716C6F63616C69647835676FF2
+:108C700066667300706163616C69647835676C6FF8
+:108C800000676D6763326700706163616C69647867
+:108C900035676869317468007278706F3267006E8A
+:108CA0006F6973655F63616C5F656E61626C655F60
+:108CB0003267006F70656E6C706761696E696478A9
+:108CC000613532006F70656E6C706761696E6964E2
+:108CD00078613536006F70656E6C706761696E69BA
+:108CE00064786131313200706163616C6964783538
+:108CF000670074656D7073617600747269736F32AA
+:108D00006700766261745F616464006F70656E6CA9
+:108D1000706761696E69647861313230006F7065C7
+:108D20006E6C706761696E69647861313234006FAE
+:108D300070656E6C706761696E6964786131323834
+:108D40000074726964783267006F66646D64696785
+:108D500066696C74747970653267006F70656E6CEB
+:108D6000706761696E69647861343800696E69742E
+:108D70007869647832670068775F697163616C5FF6
+:108D8000656E00697163616C5F7377705F646973AE
+:108D9000006D75785F6761696E5F7461626C650014
+:108DA000747373696F66667365746D61783567682F
+:108DB00000747373696F66667365746D6178356787
+:108DC0006C00747373696F66667365746D61783572
+:108DD000676D0074656D70736D630074656D70739D
+:108DE0006D6600747373696F66667365746D617820
+:108DF000006F70656E6C706761696E69647861366A
+:108E000030007478616C706662797032675F63639A
+:108E10006B006F70656E6C706761696E6964786114
+:108E2000363400667265716F66667365745F636F72
+:108E3000727200747373696F66667365746D696EC0
+:108E4000006F70656E6C706761696E69647861311E
+:108E50003332006F70656E6C706761696E6964783B
+:108E600061313336007874616C6D6F6465007473C2
+:108E7000736974696D65006E6F6973655F63616CBA
+:108E80005F706F5F356700747373696F66667365D3
+:108E9000746D696E356768008C9302006000000095
+:108EA000120000000000000020000000FC92020000
+:108EB000260000000E00000000000000100000006E
+:108EC00088980200980000000D00000000000000DB
+:108ED0002000000048930200440000001100000040
+:108EE0000000000008000000489D02001000000083
+:108EF000100000000000000008000000000000005A
+:108F00004000000080000000C000000001000000E0
+:108F10000500000002000000060000000A0000003A
+:108F20004A0000008A000000CA0000000A01000098
+:108F30004A0100008A0100008A0500008A09000039
+:108F40008A0D00008A1100008A5100008A910000F9
+:108F50008AD100008A1101008A5101008A91010022
+:108F6000890000008AD101008A110200000000007F
+:108F700000000000000000000000000000000000F1
+:108F800000000000000000000000000000000000E1
+:108F900000000000000000000000000000000000D1
+:108FA00000000000000000000000000000000000C1
+:108FB00000000000000000000000000000000000B1
+:108FC00000000000000000000000000000000000A1
+:108FD0000000000000000000000000000000000091
+:108FE0000000000000000000000000000000000081
+:108FF0000000000000000000000000000000000071
+:109000000000000000000000000000000000000060
+:109010000000000000000000000000000000000050
+:109020000000000000000000000000000000000040
+:109030000000000000000000000000000000000030
+:109040000000000000000000000000000000000020
+:109050000000000000000000000000000000000010
+:109060000000000000000000000000000000000000
+:1090700000000000000000000000000003001300DA
+:10908000410300130040030012004103001200409E
+:1090900003001100410300110040030010004103D0
+:1090A00000100040030010003E030010003C0300CD
+:1090B00010003A03000F003D03000F003B03000EB9
+:1090C000003D03000E003C03000E003A03000D00BB
+:1090D0003C03000D003B03000C003E03000C003C71
+:1090E00003000C003A03000B003E03000B003C039E
+:1090F000000B003B03000B003903000A003D030096
+:109100000A003B03000A0039030009003E0300097E
+:10911000003C030009003A0300090039030008007D
+:109120003E030008003C030008003A030008003931
+:109130000300080037030007003D030007003C035D
+:109140000007003A03000700380300070037030058
+:1091500006003E030006003C030006003A0300063A
+:10916000003903000600370300060036030006003E
+:1091700034030005003D030005003B0300050039F2
+:109180000300050038030005003603000500350321
+:1091900000050033030004003E030004003C03000C
+:1091A00004003A03000400390300040037030004FC
+:1091B00000360300040034030004003303000400FD
+:1091C000310300040030030004002E030003003CC0
+:1091D000030003003A0300030039030003003703D0
+:1091E00000030036030003003403000300330300D0
+:1091F0000300310300030030030003002E030003CB
+:10920000002D030003002C030003002B03000300C8
+:1092100029030002003D030002003B030002003965
+:109220000300020038030002003603000200350389
+:10923000000200330300020032030002003003008A
+:1092400002002F030002002E030002002C03000284
+:10925000002B030002002A03000200290300020081
+:109260002703000200260300020025030002002459
+:109270000300020023030002002203000200210376
+:1092800000020020030001003F030001003D030035
+:1092900001003B0300010039030001003803000115
+:1092A0000036030001003503000100330300010014
+:1092B000320300010030030001002F030001002EE3
+:1092C000030001002C030001002B030001002A030E
+:1092D000000100290300010027030001002603000C
+:1092E0000100250300010024030001002303000105
+:1092F00000220300010021030001002000040004FB
+:10930000000400040004000400040004000400043D
+:109310000004010480048204830484040004000423
+:10932000000400040004000400040004000401041C
+:1093300080048204830484048504860405050605EC
+:109340000705080509050A05090C12181818090C63
+:109350001218181800000C076F7A060C0F7B7E019C
+:1093600005080B0E110000000000000000000306BD
+:10937000090C0F12000000000000000000000306AE
+:10938000090C0000000000000000000000000000C8
+:10939000040000004000000080000000C000000049
+:1093A00001000000050000004500000085000000ED
+:1093B000C500000005010000450100008501000016
+:1093C0008505000085090000850D00008909000061
+:1093D000890D000089110000895100008991000069
+:1093E00089D1000089110100854D0000858D0000A4
+:1093F00085CD000089510100899101000000000025
+:10940000000000000000000000000000000000005C
+:10941000000000000000000000000000000000004C
+:10942000000000000000000000000000000000003C
+:10943000000000000000000000000000000000002C
+:10944000000000000000000000000000000000001C
+:10945000000000000000000000000000000000000C
+:1094600000000000000000000000000000000000FC
+:1094700000000000000000000000000000000000EC
+:1094800000000000000000000000000000000000DC
+:1094900000000000000000000000000000000000CC
+:1094A00000000000000000000000000000000000BC
+:1094B00000000000000000000000000000000000AC
+:1094C000000000000000000000000000000000009C
+:1094D000000000000000000000000000000000008C
+:1094E000000000000000000000000000000000007C
+:1094F000000000000000000000000000000000006C
+:10950000000000000000000000000000800080005B
+:10951000800080008000800080008000800081004A
+:109520008200830084008500040105018000800022
+:109530008000800080008000800081008200830025
+:109540008400850004010501060107011901870156
+:10955000880189018A018B0107001F004807001F4D
+:10956000004607001F004407001E004307001D00BF
+:109570004407001C004407001B004507001A004672
+:1095800007001900460700180047070017004807A2
+:10959000001700460700160047070015004807009F
+:1095A0001500460700150044070015004207001586
+:1095B0000040070015003F0700140040070013009B
+:1095C000410700130040070012004107001200404D
+:1095D000070011004107001100400700100041077B
+:1095E00000100040070010003E070010003C07007C
+:1095F00010003A07000F003D07000F003B07000E68
+:10960000003D07000E003C07000E003A07000D0069
+:109610003C07000D003B07000C003E07000C003C1F
+:1096200007000C003A07000B003E07000B003C0748
+:10963000000B003B07000B003907000A003D070044
+:109640000A003B07000A0039070009003E0700092D
+:10965000003C070009003A0700090039070008002C
+:109660003E070008003C070008003A0700080039E0
+:109670000700080037070007003D070007003C0708
+:109680000007003A07000700380700070037070007
+:1096900006003E070006003C070006003A070006E9
+:1096A00000390700060037070006003607000600ED
+:1096B00034070005003D070005003B0700050039A1
+:1096C00007000500380700050036070005003507CC
+:1096D00000050033070004003E070004003C0700BB
+:1096E00004003A07000400390700040037070004AB
+:1096F00000360700040034070004003307000400AC
+:10970000310700040030070004002E070003003C6E
+:10971000070003003A07000300390700030037077A
+:10972000000300360700030034070003003307007E
+:109730000300310700030030070003002E07000379
+:10974000002D070003002C070003002B0700030077
+:1097500029070002003D070002003B070002003914
+:109760000700020038070002003607000200350734
+:109770000002003307000200320700020030070039
+:1097800002002F070002002E070002002C07000233
+:10979000002B070002002A07000200290700020030
+:1097A0002707000200260700020025070002002408
+:1097B0000700020023070002002207000200210721
+:1097C00000020020070001003F070001003D0700E4
+:1097D00001003B0700010039090C12181818090C88
+:1097E0001218181800000C076F7A060C0F7B7E0108
+:1097F00005080B0E11000000000000000000030629
+:10980000090C0F1200000000000000000000030619
+:10981000090C00000000000000000000070010001C
+:109820003907001000380700100036070010003418
+:109830000700100033070010003107001000300748
+:109840000010002F070010002D070010002C07004B
+:1098500010002B070010002A070010002807001036
+:109860000027070010002607001000250700100041
+:109870002407001000230700100022070010002119
+:109880000700100020000000000000004000000061
+:109890000000000040000000000000004000000048
+:1098A0000000000040000000000000004000000038
+:1098B0000000000040000000000000004000000028
+:1098C0000000000040000000000000004000000018
+:1098D0000000000040000000000000004000000008
+:1098E00000000010400000000000000048000000E0
+:1098F0000000002048000000000000304800000088
+:109900000000004048000000000000504800000037
+:1099100000000060480000000000005050000000FF
+:1099200000000060500000000000007050000000C7
+:109930000000008050000000000000905000000077
+:10994000000000A050000000000000B05000000027
+:10995000000000C050000000000000D050000000D7
+:10996000000000E050000000000000F05000000087
+:10997000000000E058000000000000005900000056
+:1099800000000010590000000000002059000000F5
+:1099900000000030590000000000004059000000A5
+:1099A0000000005059000000000000605900000055
+:1099B0000000000040000000000000004000000027
+:1099C0000000000040000000000000004000000017
+:1099D0000000000040000000000000004000000007
+:1099E00000000000400000000000000040000000F7
+:1099F00000000000400000000000001040000000D7
+:109A000000000000480000000000002048000000A6
+:109A10000000003048000000000000404800000046
+:109A200000000050480000000000006048000000F6
+:109A300000000050500000000000006050000000D6
+:109A40000000007050000000000000805000000086
+:109A50000000009050000000000000A05000000036
+:109A6000000000B050000000000000C050000000E6
+:109A7000000000D050000000000000E05000000096
+:109A8000000000F0500000000000007051000000D5
+:109A90000000008051000000000000905100000014
+:109AA00000000020590000000000003059000000B4
+:109AB0000000004059000000000000505900000064
+:109AC0000000006059000000000000A059000000E4
+:109AD000000000B05900000000000000000000007D
+:109AE000000000000000000000000000080000006E
+:109AF0000000000008000000000000000800000056
+:109B00000000000008000000000000000800000045
+:109B10000000000008000000000000000800000035
+:109B20000000000008000000000000000800000025
+:109B300000000010080000000000002008000000E5
+:109B40000000003008000000000000400800000095
+:109B5000000000500800000000000040100000005D
+:109B60000000005010000000000000601000000025
+:109B700000000070100000000000008010000000D5
+:109B800000000070180000000000008018000000B5
+:109B90000000009018000000000000A01800000065
+:109BA000000000B018000000000000C01800000015
+:109BB000000000D018000000000000E018000000C5
+:109BC000000000F018000000000000001900000074
+:109BD0000000001019000000000000201900000023
+:109BE00000000030190000000000004019000000D3
+:109BF0000000005019000000000000601900000083
+:109C00000000007019000000000000801900000032
+:109C10000000000008000000000000000800000034
+:109C20000000000008000000000000000800000024
+:109C30000000000008000000000000000800000014
+:109C400000000000080000000000001008000000F4
+:109C500000000020080000000000003008000000A4
+:109C60000000004008000000000000500800000054
+:109C70000000004010000000000000501000000034
+:109C800000000060100000000000007010000000E4
+:109C9000000000901100000000000070180000009B
+:109CA0000000008018000000000000901800000074
+:109CB000000000A018000000000000B01800000024
+:109CC000000000C018000000000000D018000000D4
+:109CD000000000E018000000000000F01800000084
+:109CE0000000000019000000000000101900000032
+:109CF00000000020190000000000003019000000E2
+:109D00000000004019000000000000501900000091
+:109D10000000006019000000000000701900000041
+:109D20000000008019000000000000A019000000E1
+:109D3000000000B01900000000000000000000005A
+:109D400000000000000000005F36291F5F36291F59
+:109D50005F36291F5F36291FFC8E0200600000005D
+:109D60001200000000000000200000000C9502001E
+:109D7000260000000E00000000000000100000009F
+:109D8000E89A0200980000000D00000000000000AA
+:109D900020000000D89702004400000011000000DD
+:109DA0000000000008000000489D020010000000B4
+:109DB0001000000000000000080000000A52544596
+:109DC000202825732D2573257325732920257320BD
+:109DD0006F6E2042434D257320722564204020255C
+:109DE000642E25642F25642E25642F25642E25647A
+:109DF0004D487A0A000000002DE9FF4106460D4655
+:109E00000846FC2117469846DCF362F7044608B979
+:109E10001E302DE00021FC22D8F312F10A9B04F140
+:109E2000640204F1680100930192029130462946D0
+:109E30003A464346FBF72EFB206608B90B2017E095
+:109E400040F612010022E1F3D9F100210A46E06652
+:109E50002560206EE0F3F6F72046F7F769FF206EE5
+:109E6000FBF7DAF928462146FC22DCF341F7002013
+:109E700004B0BDE8F081C0464286000001BC60032A
+:109E800000104E03BFDE02F00BF1035B5E02F00038
+:109E90000401BC601300104300015E02F0000000EA
+:109EA000025E02F0117700025E02F0118C020200E5
+:109EB000BF00008302045EFF00000C006B44655786
+:109EC000800C01846002F7F7BF01BC6003000AAE9A
+:109ED00000025E02F00F000202DEFF000011006BC4
+:109EE00044655620110182E002F7F7BF03BFDE028E
+:109EF000F005C100682B6F0000160280DEFF000035
+:109F000083006B44655B60830184E006F577AB00FA
+:109F1000025E02F01126020480C700001802818050
+:109F2000C700001A01806002F7F7BF01BC600300A0
+:109F30000AE200902C0300D7A200E02BFEF457A306
+:109F4000006D446AF4601E00B02BF7000AF8018728
+:109F50006002F7F7BF00682BDF00002500E94465C9
+:109F60005EF7A300E8C4695F77A20068DE8B00009B
+:109F700025006DDE8D5F002501876006F7F7BF02C3
+:109F800007DEFF00002A00E844655B37A2006D5E33
+:109F9000895B002A0187E002F7F7BF01BC6003007C
+:109FA0000AD900682B0700003500E844655837A13E
+:109FB000006DDE8557403100682B4300003500E816
+:109FC00044655A17A1006DDE8557403303BFDE029A
+:109FD000F0003501BC6003000AC201BC6003000A46
+:109FE000C101BC6003000AD001BC6003000AC802C2
+:109FF00002DEB30000380200420300003800025EB7
+:10A0000002F00B1902845EB30000830068AB0F00FE
+:10A0100000830283DEB700003C020180C7000056C7
+:10A0200000B02ACB0017A202802BF300004300B03F
+:10A030002B230017A1006DDE855CE07700685E874A
+:10A0400000004300682C0700004300B02C070017F5
+:10A05000A200682B0B00004800E844655857A10097
+:10A060006DDE86F4407700E05E8555F7A1006DDE79
+:10A0700086F440770202DEBB00005600682ABB006F
+:10A08000005600E8446556D7A100E02ABB0157A25C
+:10A09000006EDE86F440500182E002F5D7AE01BCCE
+:10A0A0006003000AAE03BFDE02F0005600E82ABAE1
+:10A0B000F437A100902ABB0037A2006E2ABEF440FC
+:10A0C0005400B02ABF0017A20069DE86F440560390
+:10A0D000BFDE02F000770283DEB700006F028881E6
+:10A0E000AB00006D02035EB7000083020480C7006E
+:10A0F000005B02005EFF00006D028080BF00006D0B
+:10A1000000682B4300006102802BF300006100B067
+:10A110002B4B0017BB006E2B22F7608303BFDE02C0
+:10A12000F0006D0204DEB700006400682B170860C1
+:10A130008303BFDE02F0006D028400C700006602E8
+:10A140008600C700006800682B0B00006D02812CA0
+:10A150004700006D00E844655737A1006DDE855863
+:10A16000006D006CC46557608300B04467000ABB93
+:10A1700002845EB700008300025E02F0114303BF59
+:10A18000DE02F0008301BC63FF1FF7A10068458673
+:10A19000F4206D0203C57300007702845EB70000EF
+:10A1A00077020100C7000083006B4465578083007D
+:10A1B00020E3FE1460830282DEBB000083028881FC
+:10A1C000AB0000830282DEB3000083028080BF0008
+:10A1D00000830284DEAF00008302825EBB00008346
+:10A1E00003A0DE02F0007F0200420300007F0002B5
+:10A1F0005E02F00B1901836002F5B7AD0184E00641
+:10A20000F577AB01BC6003000AC300B04467000AE5
+:10A21000C4018060020D906C03595E02F00085035A
+:10A22000D85E02F0008603D8DE02F0008701BC6130
+:10A230008300112900B0007B00112B01BC630300D7
+:10A24000112303125E02F00A9303975E02F00B2AB9
+:10A25000020181B300009A0285C52300009A02879B
+:10A2600081B300009303A3DE02F0009A03A0DE0294
+:10A27000F0009A00025E02F00B190187E0040D80E5
+:10A280006C00E044640DB7BD006B4466F7A0940118
+:10A29000BC600301978001BC600300378101BC6092
+:10A2A0006B00508A01BC600306379203BFDE02F0E8
+:10A2B00002D503D05E02F0030F03D0DE02F0051ECC
+:10A2C00003D5DE02F00A4D03915E02F00595039678
+:10A2D000DE02F00A480288C1730000BB03C45E02BC
+:10A2E000F0070803C75E02F0073703DCDE02F01157
+:10A2F000CC03AA5E02F0077A0386DE02F00A8B0224
+:10A3000087C037000A8B03835E02F008BC0391DE2E
+:10A3100002F0061703C2DE02F00AEF00025E02F04E
+:10A320000EFF00025E02F0117703D4DE02F006A1F8
+:10A3300003A3DE02F0000200025E02F00E2E03A272
+:10A340005E02F000B803565E02F000B501866006BA
+:10A35000091048031F5E02F000B5006A5E2300008A
+:10A36000B400B0002700178800E85E230037880398
+:10A37000A65E02F0012200025E02F00EC700286015
+:10A380000E08E14303C4DE02F00B610020C20300AB
+:10A39000215403BFDE02F001A003815E02F000BD84
+:10A3A0000300DE02F000A00188E0020B905C03BF16
+:10A3B000DE02F0030C028740630000BF0282C10787
+:10A3C0000000C001866006F4301802864063000079
+:10A3D000C200B05E870017A10002DE02F00000029A
+:10A3E0008740630000C500B05E8B0010190186E055
+:10A3F00006F430180281DEAF0000CA0286C0630096
+:10A4000000C900B05E870017A10002DE02F0000064
+:10A4100001BC60030280060280DE070000D601DA7C
+:10A420006002F0178002085E070000E601BC6003CE
+:10A430001E17A100E05E02F4306501BC60031C172A
+:10A44000A100E05E02F4306401BC60030028180340
+:10A45000BFDE02F000EC01105E030017A100885E71
+:10A46000870037A200E05E86F457A100E0015AF4AD
+:10A470003063028600C30000DF00B0560B0010629C
+:10A4800000B0540300106201BC600300281803BF31
+:10A49000DE02F000EE00B0418F0010620109DE0321
+:10A4A0000017A100885E870057A100E05E85059730
+:10A4B000A100E05E8703C00601BC600300481803EA
+:10A4C000BFDE02F000EE01BC60070217A100E05EF3
+:10A4D00002F4306501BC60070017A100E05E02F4E1
+:10A4E000306401BC600318000601BC60030008185A
+:10A4F00000B05A0300106200B05803001063010559
+:10A5000001430017A10088001AF420060002DE02B1
+:10A51000F0000001BC600306379201BC63FF1FF02E
+:10A52000C301BC60031890E301BC63FF1FF0C501C9
+:10A53000BC63FF1FF0C601BC63FF1FF0C700B02C57
+:10A540005B0010E500B02C5F0010E600B02C63004B
+:10A5500010E70280AC4700010401BC60030010104A
+:10A5600000B0404300180000B040470010E501BCB7
+:10A57000600300301000B0404300180000B04047B6
+:10A580000010E601BC600300501000B0404300180A
+:10A590000000B040470010E701BC63FF1FF0C4009B
+:10A5A00002DE02F0000000E840330097A100B04056
+:10A5B0000B0017A3006D5E86F4610B00905E8F00A8
+:10A5C00037A303BFDE02F0010C00905E870037A3C3
+:10A5D00001BC601F1417A100E05E8EF437A301F0E8
+:10A5E00041970017A1006DDE86F461200287C197B4
+:10A5F00000011401385A030017A1013C5A03001747
+:10A60000A203BFDE02F00116013C5A030017A101AC
+:10A61000385A070017A200685E86F4811B00D85ED6
+:10A620008B0037A200E14196F4506500E1C197002C
+:10A63000306503BFDE02F0010E00D85E8B0037A24A
+:10A6400000E14196F457A100E1DE870037A101F057
+:10A650005E870017A1006EDE86F4612101BC63FFF6
+:10A660001FF7A40002DE02F000000020E38E0900C4
+:10A6700002031EDE02F00127039F5E02F0012700A5
+:10A68000025E02F0014A03BFDE02F000020208414E
+:10A690001F00012501816005620B1000025E02F0BF
+:10A6A0000B1900B000AB00108600B0016300108AE7
+:10A6B00000025E02F00D0001BC600304179200B0BE
+:10A6C000003B00111D0190600609104803A1DE0245
+:10A6D000F0013D0181E00609104801BC60030090D3
+:10A6E0004201BC600300112D039EDE02F001400117
+:10A6F000846002F2979400B0451700178F00B05E97
+:10A70000170017900200441F00013B0185600209F9
+:10A7100010480181600700104701F0DE0F0037A1EB
+:10A7200000A044B6F43145039EDE02F0014001BCB6
+:10A73000613712B08003BFDE02F0000200A044B413
+:10A740002A314501BC612712708003BFDE02F00090
+:10A75000020020E082090002010CDE530017A10173
+:10A76000885E8700104701BC600300504201084129
+:10A770001F0017A1018CDE86F2979403BFDE02F062
+:10A78000000201BC600300904200E85E23003788AD
+:10A790000069DE2300014E00E800270037880186AB
+:10A7A000600209104801856006F5B7AD0088009B7E
+:10A7B00000D1260090009B01512801BC63030011C9
+:10A7C000240002DE02F000000020E07E090002000A
+:10A7D000025E02F00ED10283C21F0000020202805C
+:10A7E000F300015E00B044670017A1017C5E862380
+:10A7F00057A302835EFF00015D00E000FAF46830B9
+:10A8000001836006F7F7BF006BDE8D06016202066A
+:10A81000D00300016600E950862337A100E8D08A02
+:10A820002357A20069DE8B00016600025E02F00B76
+:10A83000190191601684F42700E020C300883003DA
+:10A84000BFDE02F002F2020400BF00016D03945E5D
+:10A8500002F000020020C28F02000200A0428F011D
+:10A86000F78000685E002DC00200025E02F00B1946
+:10A8700003BFDE02F000020201C28F0000020114D9
+:10A8800000630017A100685E8700600200025E029C
+:10A89000F00B190194600F00001800025E02F00135
+:10A8A0007403BFDE02F00002011400630017A10070
+:10A8B000B05E870010A501BC601311106000685ED7
+:10A8C0008700017B00E0418306D06000E85E8700DE
+:10A8D00037A103BFDE02F00177028050C30001857B
+:10A8E000018760040310A000B000630010B400B042
+:10A8F00042D3001800008841830030B601BC6003D9
+:10A900000B10B500B0006300B0B40317DE02F00115
+:10A91000820397DE02F00183018060068614300016
+:10A9200002DE02F000000020E01280419F018760FB
+:10A93000040310A000B000630010B401BC60030E5B
+:10A9400010B500B0006300F0B401BC60570490B6CD
+:10A9500000B000630010B401BC600302D0B5020770
+:10A96000500B00019C01BC600303D0B5018E600256
+:10A97000F297940204500B0001950204D00B0001E1
+:10A980009501866006F2979400E042D700D0B500AA
+:10A99000A0500B1117A10068DE8711019B0186E012
+:10A9A00006F2979400E042D70050B50207D00B00A2
+:10A9B000019B00E042D70090B500B042D70011E102
+:10A9C00000B0006300B0B40317DE02F0019D0397EE
+:10A9D000DE02F0019E0002DE02F00000006820DFCF
+:10A9E0000001A3006CC46506E00201BC600300081E
+:10A9F00037006820D70001A6006CC46506C00201BC
+:10AA0000BC60030008350020E0BE09000203905E30
+:10AA100002F0000203A25E02F001E1020200BF00A8
+:10AA200001AB0203C5730001D400682F6B0001AFB6
+:10AA300000E844657B57A1006D5E857B21D401BC95
+:10AA40006003000BDA00682D9B0001D40282C1076D
+:10AA50000001D4028042030001D40285C523000115
+:10AA6000D4028640370001D40181E006F577AB00BF
+:10AA7000B02D9F0017A101BC602F1077A201BC6010
+:10AA8000030017A300025E02F0130F00B02DA30015
+:10AA900017A101BC602F1777A201BC60030017A3A8
+:10AAA00000025E02F0131D01BC60131A17A1000220
+:10AAB0005E02F000BF00B040670417A200025E0211
+:10AAC000F000C500E0446700D7A1006CC466F42123
+:10AAD000C201BC60130ED7A100025E02F000BF00ED
+:10AAE000A040673FF7A201BC601314D7A101BC626C
+:10AAF000030017A300B05E8AF477A200025E02F0A2
+:10AB000000C500B02D9F0017A101BC602F0D37A21A
+:10AB100001BC60030017A300025E02F0130F00B037
+:10AB20002DA30017A101BC602F13B7A201BC6003C5
+:10AB30000017A300025E02F0131D0181E002F57709
+:10AB4000AB01BC6003000B6600025E02F00DDE028A
+:10AB50000200BF0001E00284DEAF0001DB02035E01
+:10AB6000B70001E000025E02F010F202035EB700DF
+:10AB700001E003BFDE02F0000202035EB70001DE67
+:10AB8000020480C70001E002805EFF0001E00002D5
+:10AB90005E02F010B303BFDE02F0000200025E02AC
+:10ABA000F00ED10200421F0001F9006842F30001DB
+:10ABB000E4006D42F30041F9011400630017A100A5
+:10ABC000B05E870017A203A25E02F001ED0183E0F0
+:10ABD000020D906C03145E02F001FB006EC45680FF
+:10ABE00061FB028145230001FB006E5E870061F975
+:10ABF00001BC60030077A200886006F457A30088B8
+:10AC00005E8B01001800E85E8B0037A20020C28E28
+:10AC1000F461F3006ADE86F441ED03BFDE02F00169
+:10AC2000F9020400BF0002250090006301016500E5
+:10AC30008085970217A100E064820DA16600025E84
+:10AC400002F00E8703BFDE02F002250182600209D6
+:10AC5000104803BFDE02F0000201BC6003001115C2
+:10AC600000B0017F0017A6031F5E02F0020A020374
+:10AC700000C30002000020C28F02020403255E020E
+:10AC8000F0020A0020C28F02020400688153FFE034
+:10AC90000203BFDE02F002060194601300001803F5
+:10ACA000BFDE02F00225039EDE02F002090068DE2C
+:10ACB000980BC2090201411F000C4C01856002097A
+:10ACC000104800685E980BC20E00695E9F00622A01
+:10ACD0000298428F00020E03BFDE02F0022A020138
+:10ACE000411F000C4C020400BF0002150218428FE5
+:10ACF000000C4C00025E02F00E6900025E02F00ED3
+:10AD0000870194058700001803BFDE02F0022502C8
+:10AD10000013BB00021E0200156B00022100B013DD
+:10AD2000470017A10068DE84A7A21E00B0134B00E5
+:10AD300017A10068DE84A7C21E00B0134F0017A140
+:10AD40000068DE84A7E21E029E1397000221020122
+:10AD5000C28F0002230194600F00001803BFDE02BF
+:10AD6000F002250201C28F000223018060060D90CF
+:10AD70006C0200C28F000C4C0194600700001800A8
+:10AD8000025E02F00174020400BF00025A02850054
+:10AD90006300025A0183E0060D906C03BFDE02F0EF
+:10ADA000025A01BC60031810600129500B00179271
+:10ADB00000B0017B001065006800EB0002330088E2
+:10ADC0005A130117A100E84466F437A1006EDE842F
+:10ADD00007423300E0029B0020A603BFDE02F0061C
+:10ADE0009A019060120910480194601F0000180138
+:10ADF000085A0F00178101885E0681540A01345AEF
+:10AE00000F00178000025E02F000CC00B0017B0052
+:10AE1000106500B056230017A100E05E86A097A140
+:10AE200000E85E8400F40300E85E8400F41600B0DD
+:10AE30005A0300141300B05A0700141400B05A0B40
+:10AE40000014150068DE0700424B00E80097005729
+:10AE5000A101BC5E86F0141B017C5E8700F41C001F
+:10AE6000B0206300178100025E02F00D0400B00103
+:10AE70007B00106501085A0F00178100B05E870043
+:10AE8000141E03BFDE02F0024E00B0561700141B62
+:10AE900000B0561B00141C00B0541300141E00B068
+:10AEA0005013001086006D00A700825401900163CA
+:10AEB00000108A00B0418F00106200025E02F011A3
+:10AEC0009900B0422B00140601BC60031817A100C2
+:10AED0006DC18C20025701BC60030297A100E05EA7
+:10AEE000840377A100E05E86B0111D03BFDE02F08F
+:10AEF00002CF020300C700026A020CD00300026AFC
+:10AF0000011400630017A10285006300026A00803B
+:10AF1000DE8701F7A201BC601B0257A200E05E8A37
+:10AF20000DB06500B041970014320080DE8700B795
+:10AF3000A201BC60171FD7A200E05E8A0DB06400BA
+:10AF4000B041930014330068D81300027402005A11
+:10AF50001B00026C0180600684F42703BFDE02F050
+:10AF600005C10201D00300026C00B0509B00142FF9
+:10AF70000281D0C70002EF010BD0030017A1013CF2
+:10AF8000502B0017A2018C5E86F457A101480143A3
+:10AF90000017A200685E86F442740191601284F486
+:10AFA0002703BFDE02F002F200025E02F00186001B
+:10AFB000B0501300108600B0501700108A00682FA0
+:10AFC000C300027F0291D01700027D0291D01B00C6
+:10AFD000027D0291D01F00027D0291D02300027DEC
+:10AFE00003BFDE02F0027F0191600284F42703BFF9
+:10AFF000DE02F002F203A25E02F002AE020CD00307
+:10B0000000029B020300C700029A00B050CB001060
+:10B010006500025E02F01232020350C7000288018E
+:10B02000BC60230097A100A85002F4340003BFDEE7
+:10B0300002F0029F020481AB00028A006D4246C00A
+:10B04000800200B05A1300178000025E02F000D6A2
+:10B0500000B0540F00141E00B05A070017A100B032
+:10B060005A1300178001875A16F0178000B0418FDD
+:10B0700000106500025E02F011A200E05E86A0747E
+:10B080000302875E030002990109DE030017A30093
+:10B09000E05E8B0077A200E05E8AF477A200885E13
+:10B0A0008B0037A100E05E86F4508903BFDE02F01A
+:10B0B000029F006D424A848002010650070017A1DA
+:10B0C000028CD00300029E00685E8700029F01820E
+:10B0D000DE86863431018260028634310020D0035E
+:10B0E0000402A500B0504F0011F200B050530011FF
+:10B0F000F300B050570011F401BC60030091F0025E
+:10B100000101B30002A70187E006F577AB03945E67
+:10B1100002F002AE020650030002AA0287DEAF0070
+:10B1200002AE028150030004FF0202D0C70002AD4C
+:10B130000208502B0002AE0285D0030005160190D4
+:10B14000601286343103A25E02F002BB00B0500FE1
+:10B150000011160202D0C70002B300B0505B00110C
+:10B16000160282D0030002BB028147C30002B40270
+:10B1700080504F0002B9002047C73F82BB0020C764
+:10B18000DB00C2F103BFDE02F002BB03A55E02F0EA
+:10B1900002BB0280C7DF0002F1028850C70002D55F
+:10B1A0000129500B001792020300C70002C8020CCD
+:10B1B000D0030002C8028350C70002C800B050CBC1
+:10B1C00000106501385A1300178001825A17005782
+:10B1D00081010E5A130017A1018E5E86F03781029D
+:10B1E00002D0C70002D500B0501B00108A03BFDE9A
+:10B1F00002F002D50282D0C70002CF0138502700EA
+:10B20000178001085013001781010250130017A185
+:10B2100001825E86F0378100B0507F00108903BF45
+:10B22000DE02F002D50138506F0017800108502B64
+:10B230000017810106D0070017A101825E86F03752
+:10B240008100B0501B00108A00B0508300108900AC
+:10B25000025E02F000CC00025E02F00CF701024236
+:10B260001B00178101825E0503178100025E02F058
+:10B270000D0400E05E840117A101D9DE8700108370
+:10B28000020001B30002DE01E001B700108301BC3F
+:10B29000613703B79100685E4B0282F5020400BF7C
+:10B2A0000002E3028750030002E303945E02F0020F
+:10B2B000E403225E02F002E601BC61030030800379
+:10B2C000BFDE02F0000201BC613303B791032BDE45
+:10B2D00002F002EC009000630097A100E06482F4A9
+:10B2E0003065006E5A130022EC0188E006F23791B7
+:10B2F0000068DE4B0482EE01BC61BB03B79103BF63
+:10B30000DE02F002F50191600E84F42703BFDE0235
+:10B31000F002F20191600684F42701BC6003001082
+:10B32000B40181E00686343103BFDE02F005C103BB
+:10B33000C4DE02F00B61020650030002FD0207DECC
+:10B34000AF0002FD01BC610300379102075003000A
+:10B3500002FB01BC620300F79100E0010B002042F8
+:10B3600003BFDE02F002FE01BC600300204200B019
+:10B370005E47001080020001B300030401826006F2
+:10B38000103081020181B300030401BC600305B7E2
+:10B390009303BFDE02F006CC020400BF00030B00E3
+:10B3A000B0058B001064006E45170000020068DED7
+:10B3B0004B02830A00A044B42A314503BFDE02F0E9
+:10B3C000000200025E02F00D110068C517000002C5
+:10B3D00003D05E02F0030F00025E02F00D1103BF06
+:10B3E000DE02F0000201836002F7F7BF01BC6003D8
+:10B3F00000900400A8412330104801BC620F0011E6
+:10B40000E001816002F5D7AE020200BF0003230015
+:10B4100068DE4B02031700025E02F013090068DECB
+:10B420004B06232302045EB30003230200456F0092
+:10B43000032300E844655737A100E82AB6F437A192
+:10B4400000695E870823230183E0022B915C0207D9
+:10B4500001AB0003200180E00209D04E01BC600373
+:10B4600018517800B045E3001800018060022F31C8
+:10B47000790187E002F577AB0068810B0023260095
+:10B48000B044670000430182E00609104801816072
+:10B49000020D906C018260062891440188E0020B45
+:10B4A000905C00025E02F00EFF0185E002F7F7BF3C
+:10B4B0000288421B00032E0185E006F7F7BF035BFD
+:10B4C0005E02F0033001BC601300104301BC600356
+:10B4D00000108501BC60030010B800885077009010
+:10B4E000B90208502B000337013850730017A1012F
+:10B4F0007C506EF437A100885E870090B902004747
+:10B50000A300033B01BC60030011EA009042E70086
+:10B5100091EB00B047A300D1E8020047B300033D20
+:10B5200001B0E08E3D91EC01D2E00210908403A9BD
+:10B530005E02F0042901BC600300108400E001C336
+:10B54000002070028181B30003730320DE02F00348
+:10B550008F01816006F5B7AD0068DE4B04A356028B
+:10B5600003DEBB00034800E02C9300106503BFDE40
+:10B5700002F0034901BC602301D06500A05E7FFE9C
+:10B5800010EC00B05A030010ED00B05A070010EEA6
+:10B5900000B05A0B0010EF00B05A0F0010F001BCC1
+:10B5A00063FF1EF08401BC600300308501BC6003B2
+:10B5B0000010B401BC600301D0A601BC60030450BC
+:10B5C000B501BC602304D0B400E002AF0020AB039F
+:10B5D000BFDE02F003D70068DE4B05235C01BC60D0
+:10B5E000030010B401BC60071350A601BC60030245
+:10B5F000D0B501BC602304D0B403BFDE02F0036603
+:10B600000068DE4B0243730285C38F00035F00E0D6
+:10B610005E2700378901DA5E270010EE01BC63FF68
+:10B620001FF0CE01BC60030010B401BC600300D069
+:10B63000A601BC600303D0B501BC602304D0B400F4
+:10B64000E001D300207401BC61FF1FF08401BC60E5
+:10B6500003001085018460070011E00282DEB30060
+:10B6600004E602045EB30004E60183E00609104824
+:10B6700000B0412300180001BC600306B78E0181B1
+:10B68000E006F5D7AE00B054130017A100E05E84C9
+:10B690000117A100885E8700708303BFDE02F004FB
+:10B6A000E601BC60031FF0840103DE530017A20211
+:10B6B000005EFF00037701BC60030037A200682B27
+:10B6C0006F00037901BC60030037A201865E8A1C0B
+:10B6D00070E3006AC39300038300E8439000D0E462
+:10B6E0000202421B0003810090001B0037A10020D2
+:10B6F000421B00438000B020B30017A100E043923A
+:10B70000F430E40069C39300038301BC60030010BC
+:10B71000E400682B6F00038500E043915C30E40196
+:10B72000BC60030010B401BC60030010A601BC6043
+:10B73000030210B501BC602304D0B400685E4B0660
+:10B74000A38D00E001CB00207201BC60030008382B
+:10B7500003BFDE02F003D700E001CF00207303BF78
+:10B76000DE02F003D703205E02F003DE0181E00277
+:10B7700009104800E001D7002075031EDE02F00327
+:10B78000BE01BC60030017A2006A5E23000397019C
+:10B7900002428F0017A201855E8A0910480180E0ED
+:10B7A000061030810284DE5300039E00B000770053
+:10B7B00017A100E05E840437A100885E870057A1CE
+:10B7C00000E05E870D57A103BFDE02F0039F01BCBE
+:10B7D00060030D57A1006800270003BE00E05E84EF
+:10B7E00001F7A101BC60230150650088419700303A
+:10B7F000B601BC60030010B400905E870050A60143
+:10B80000BC60030110B501BC602300B0B40317DEB7
+:10B8100002F003A70397DE02F003A80020DE8700F2
+:10B8200043B10020DE870023AE01B85E22D016802F
+:10B8300001805E8AD0368103BFDE02F003B701BC0F
+:10B840005E22D0168001845E8AD0368103BFDE027C
+:10B85000F003B70020DE870023B501B85E22D036A2
+:10B860008101805E8AD0568203BFDE02F003B701F9
+:10B87000BC5E22D0368101845E8AD0568201886007
+:10B8800002F430A800B05A030010B000B05A07000C
+:10B8900010B1028042A30003BA00E042A30090A8C6
+:10B8A00000B05A0B0010B000B05A0F0010B1018761
+:10B8B000600610908400E05E2700378901DA5E2779
+:10B8C0000010EE01BC60030010B401BC6003035023
+:10B8D000A600B000330010B50284DE530003C80098
+:10B8E000E0606803B0A600E042980430A600B00013
+:10B8F000370010B501BC602304D0B401846006F2A7
+:10B90000979401866002091048039EDE02F003D27C
+:10B910000280441F0003D500B05E3F00114501BC0A
+:10B92000600300178F00B05E4300178500B05E0F04
+:10B9300000179003BFDE02F003D500B05E0F0017C2
+:10B94000850280441F0003D500A044B6F0B1450134
+:10B95000BC600301104201836006F2979401846089
+:10B96000070011E003A05E02F004E402065EAF00EF
+:10B9700004E60186E006F577AB01BC6003001080A9
+:10B9800000025E02F00B1F03BFDE02F0061703A1E8
+:10B990005E02F00450011400630017A10068DE8706
+:10B9A00000E3E30181600609104803BFDE02F004F2
+:10B9B0005001816006F5D7AE0020600E8624080194
+:10B9C0008760040310A000B000630010B401BC60E5
+:10B9D000030B10B500B0006300F0B4020300C70011
+:10B9E00003F6020CD0030003F6028050C70003EEFA
+:10B9F00000B054130017A100E05E8680741A00B0F6
+:10BA0000506B0010E400B042130210840209502B66
+:10BA10000003F600B0421300308401D2E03AA030B7
+:10BA2000E0028050C70003FC01D2E052A030E003E6
+:10BA3000BFDE02F003FC0202D0C70003FC00B050DE
+:10BA40005F0010E000B050630010E100B0506700EC
+:10BA500010E200B0506B0010E400B0421302F0841A
+:10BA6000020050C700040300B000630010B401BC22
+:10BA700060030210B500B0006304D0B40184600715
+:10BA80000011E001BC600300178E03BFDE02F0046A
+:10BA9000E800E001C700207100B000630010B401AD
+:10BAA000BC600302D0B500B0006304D0B403BFDEB5
+:10BAB00002F0048001856006F7F7BF010350030020
+:10BAC00017A100B85E870037A101875E861010803D
+:10BAD000020CD00300044F020300C700041F00B093
+:10BAE00050CB00106501BC600300168500E05A339E
+:10BAF00000368C020350C700041400E05A270036B9
+:10BB00008903BFDE02F0045001BC60030017B200DD
+:10BB1000B05A0B000B2501385A130017A101BC5A6B
+:10BB200006F430E0013C5A130017A1017C5A06F4D8
+:10BB300030E10181E0061090840185E0070010E308
+:10BB40000185E0070010C30282D0C700042403BFB0
+:10BB5000DE02F004270202D0C700042900B02A4BFD
+:10BB60000017A101B8506EF430E000B05073001718
+:10BB7000A101B82A4EF430E10282421300042700EA
+:10BB8000B0507B0010E400B042130210840185E045
+:10BB9000061C30E100B0421300708401876004038A
+:10BBA00010A0020300C700043E00B050CB00106597
+:10BBB000006D5ECAD1C42F0185E0021870C300E099
+:10BBC0005ECB00368E01BC601B09D06500E041965B
+:10BBD000F6506500B050970016800068DECB000478
+:10BBE0003601BC60230150B800682C9700243C0348
+:10BBF000BFDE02F0044800B05ECB0010B500B0001C
+:10BC0000630870B4028342D300043801BC600301AE
+:10BC100070B80068AC9700244801BC60030170B89C
+:10BC200002BC506700044703BFDE02F00446010C6B
+:10BC3000D0030017A103A95E02F0044301BC6023F6
+:10BC40000150B800685E8700644603BFDE02F0045E
+:10BC50004801BC60030170B800685E870044480179
+:10BC6000BC60030170B80181E0021710B801BC602C
+:10BC70000300F0A501BC60030E10B500B000630026
+:10BC800010B400B0006300F0B400B042D30018005C
+:10BC9000018860080310B4018160060D906C03BF39
+:10BCA000DE02F004800202D0C700045600B0506FDC
+:10BCB0000010E000B050730010E100B050770010A9
+:10BCC000E20282421300045500B0507B0010E400F1
+:10BCD000B0421302F08400E05E9F0037A703A15E2C
+:10BCE00002F0045F01BC60030017A7018760040332
+:10BCF00010A000B000630010B401BC60030E10B5CA
+:10BD000000B0006300F0B4018860080310B403BF02
+:10BD1000DE02F0047500B0017B00106500B05A032C
+:10BD20000010E501BC63FF1FF0C500B05A0700100A
+:10BD3000E601BC63FF1FF0C600B05A0B0010E7011C
+:10BD4000BC63FF1FF0C70068A06700046800E05EE6
+:10BD5000270037890068206700046C0185E0070030
+:10BD600010E30185E0070010C300B0421301108406
+:10BD700001DA5E270010EE0187600610908400B0A3
+:10BD800042131C108401BC60030010B400E0606822
+:10BD900003B0A600B000970010B501BC602304D02A
+:10BDA000B4018460070011E003BFDE02F004D40197
+:10BDB000085E4B0017A100685E87002480020250D5
+:10BDC0000300047F029E509F00047C0201D0030008
+:10BDD000047C00E05E2700378901585E2700142D9F
+:10BDE00001DA50B70010EE0187600610908403BF9F
+:10BDF000DE02F0048001BC600300142D0104C107C1
+:10BE00000017A103225E02F004830103DE53001732
+:10BE1000A100B05E870017A202005EFF0004860149
+:10BE2000BC60030037A200682B6F00048801BC606F
+:10BE3000030037A202885E4B00048B00685E4B064D
+:10BE4000848B01BC60030017A20183DE86F2979405
+:10BE50000183DE8684F4270281C2130004920186E6
+:10BE60005E8B0010E3018660070010C30181E006CD
+:10BE700010908403BFDE02F0049401865E8A1C7079
+:10BE8000E3018660061870C302B847A70004D00219
+:10BE9000A047B70004D203A95E02F0049C01085E2B
+:10BEA0004B0017A100685E870024D1021E509F003E
+:10BEB000049C0185E0061C70E30185E0061870C350
+:10BEC000011400630017A10068DE870084A500B09C
+:10BED00001530017A20068DE8BFFE4A1006842470F
+:10BEE0000024A20068DE8A84C4A5018560020910CE
+:10BEF000480186E0021C70E30186E0061870C30169
+:10BF00001050070017A600685E9B0004D101BC60BA
+:10BF1000030011E4013A500700178000885E030017
+:10BF2000778000E000AEF010640068DE9B0044B64D
+:10BF30000207D0030004B001BC602B12B7A200E0DE
+:10BF40005E000B37A300025E02F00D5201BC6023BD
+:10BF500007978100E0418301706300E0418F00B0EA
+:10BF60006500025E02F00D2701BC602307506401EA
+:10BF7000BC60470017A200025E02F00D7A00685E06
+:10BF80009B0044D201A46046F471E00068DE9B008F
+:10BF9000C4C401BC611300B7A1020600F30004BDD4
+:10BFA00001BC601300B7A10192C21AF437A20329A1
+:10BFB0005E02F004C201BC60030011EE009042E793
+:10BFC0000091EF0192E00EF437A200B05E8B0011F9
+:10BFD000EC03BFDE02F004D200685E9B0064C9007F
+:10BFE000685E9B00A4C900B0502F0011E200B05061
+:10BFF000330011E203BFDE02F004D2018760023D8C
+:10C0000011E80068DE9B00A4CC018760063D11E8C2
+:10C0100001BC60030011EA009042E70091EB01923D
+:10C02000C21B00B7A201B85E8A3D11E803BFDE0261
+:10C03000F004D2018460070011E001BC600300112C
+:10C040002D00B0448300142C03A3DE02F004E701AA
+:10C05000BC600300178E00685E4B05A4D802005038
+:10C06000030004E10183E00609104800B041230009
+:10C07000180001BC600304B78E03A95E02F004E659
+:10C0800000685E4B0424E601BC600306378E00683E
+:10C090005E4B05A4E601BC600306B78E03BFDE025B
+:10C0A000F004E601816006F577AB00B05E0F001783
+:10C0B0008500025E02F00D1101BC600300178C01C7
+:10C0C000BC600300178D0323DE02F004E80187E063
+:10C0D000061070830185E002F5B7AD03295E02F01A
+:10C0E00004FC020300C70004F700B050CB00106549
+:10C0F0000282D0C70004EF00E05A2300368803BF55
+:10C10000DE02F004F000E05A2700368900682C9720
+:10C110000024F700E05ECB0037B2010A5ECB0017C7
+:10C12000A100E050CAF4306500D06006F657A200C6
+:10C13000205A1AF444F703BFDE02F004F100025E55
+:10C1400002F00EFF03D5DE02F00A4D03D6DE02F048
+:10C150000A650350DE02F004F703BFDE02F0051E9D
+:10C1600002055EAF0004FE0187E00626713303BFBF
+:10C17000DE02F000020190600A8634310282D0C7EC
+:10C18000000508013C50270017800109502B0017BB
+:10C1900081010750070017A101825E86F0378100F8
+:10C1A000B0501F00108A00B0500F00111603BFDE00
+:10C1B00002F0050E0138505F001780010A502B0075
+:10C1C00017810107D0070017A101825E86F0378131
+:10C1D00000B0502300108A00B0505B00111602031B
+:10C1E00000C7000513020CD00300051302085E0708
+:10C1F000000513013854070017800190422AA1302E
+:10C200008A028050C700051C01BC600305B7920379
+:10C21000BFDE02F002B301906006863431020300F3
+:10C22000C7000500020CD00300050000B0001F008D
+:10C2300017A100E05E8680741A03BFDE02F00500DD
+:10C2400001BC600306379203BFDE02F002B30205B1
+:10C250005EFF00052D01856002F7F7BF032BDE02AC
+:10C26000F0052D020000F300052400E80023005132
+:10C270004201BC600A28514203945E02F005290085
+:10C28000B0058B0010640068580300052900B04415
+:10C290006700111200B058030011150068451F0017
+:10C2A000052D03A25E02F0052D0185E006F577ABB2
+:10C2B00000025E02F00E410201C2E30005570203D4
+:10C2C00000C700053200682C97002542006E4246E8
+:10C2D000F6454203BFDE02F00534006E42470025FA
+:10C2E00042020300C700053F0355DE02F00534019A
+:10C2F000806002861430013850830017A100B050CE
+:10C30000CB001065006DDA32F42A4D00A8412314E9
+:10C3100010480114006300106500E041970ED065DD
+:10C3200000E05A0300368001BC621F0011E003BF29
+:10C33000DE02F000020181E0068634310191600ED8
+:10C3400084F42703BFDE02F00557013C5067001755
+:10C35000A101AC5E861750BA01BC60030190B8021F
+:10C360000300C70005510068AC9700254C0181E02F
+:10C37000021710B803D5DE02F00A4D03D6DE02F034
+:10C380000A650350DE02F0054803BFDE02F00557E0
+:10C3900000E82C97002B2500B05ECB0010B500B054
+:10C3A00000630870B4028342D300054F03BFDE026E
+:10C3B000F005520186E0040310A000025E02F001C5
+:10C3C0007D03D5DE02F00A4D03D6DE02F00A6503D6
+:10C3D00050DE02F0055303BFDE02F0032E01BC6005
+:10C3E0000300F0A50182E00209104801BC621F00B1
+:10C3F00011E001BC60030011EC01BC600F0011E80A
+:10C400000285500B00055E0182600209104802811E
+:10C4100081B300056503A0DE02F0056303D5DE02EB
+:10C42000F00A4D03D6DE02F00A6503205E02F00535
+:10C43000650188600209104803BFDE02F0000201B6
+:10C44000BC60030037A1020001B3000573020401C0
+:10C45000B300057200E901BB00206E00E881BF0057
+:10C46000006F006881BB000572006881BF00057223
+:10C47000028181B300056F01BC600300006C03BF43
+:10C48000DE02F005C101BC600300006C00025E0228
+:10C49000F00ADC03BFDE02F0000201BC60030017FB
+:10C4A000A100025E02F00C36020101B30005760322
+:10C4B000BFDE02F0000203A3DE02F0000202005021
+:10C4C000C700057F01BC600300108001826006097F
+:10C4D0001048018060028634310104C1070017A1B1
+:10C4E0000183DE86F2979400E001CB00207203BF47
+:10C4F000DE02F001A0020101B30005810187E00620
+:10C50000F577AB00B0010B0017A1006DDE840805C4
+:10C51000C100E844640877A1006E5E840825C1016B
+:10C5200087E006F577AB020200BF00059402888120
+:10C53000AB000594028400C70005940129500B004C
+:10C5400017A10068DE870205940282DEBB00059415
+:10C550000203C5730005930283DEB30005930282D4
+:10C56000DEBB00059000682B07000594006DDE2FF0
+:10C5700001E5940182E006F7F7BF00E04465564A02
+:10C58000B103BFDE02F0000203BFDE02F005C1020C
+:10C59000825EAF0005A401826006F577AB00B0446F
+:10C5A0006700082300B0014B0017A20208421B00DD
+:10C5B000059B00B0016B0017A200685E8B0005A10F
+:10C5C0000090452B0097A10080DE86F457A1006EF5
+:10C5D00020D60DA5A100B041B700083500E020D657
+:10C5E0002328360185E002F5B7AD02055EAF0005F0
+:10C5F000A401BC610300113300E844650477A50081
+:10C60000B04467000BDA006D5E9701009E020200E5
+:10C61000BF0005B30068DE4B06A5AA0184E002F75F
+:10C62000F7BF0068DE4B0405AD0282DEB30005AD46
+:10C6300001BC6003000B1202045EB30005B0006889
+:10C64000DE4B0625B000025E02F0111A00025E0207
+:10C65000F00F0003A3DE02F005B30183E002F597BB
+:10C66000AC01BC60131497A100025E02F000BF0190
+:10C67000BC63830017A100A04066F437A20068DE07
+:10C680008AF425BF01BC60130E77A100025E02F0A0
+:10C6900000BF00A040673FF7A200985E8B0037A262
+:10C6A00000685E8B0005BE0068DE8B0FE5BF01BC35
+:10C6B000602300104301826002F577AB03D15E0274
+:10C6C000F00002020050C30006100325DE02F00550
+:10C6D000C50183600684F42703BFDE02F005F7027C
+:10C6E0000CD0030005F5020300C70005E4011400A7
+:10C6F000630017A1006DDE870085F501BC600300B3
+:10C70000178000B050CB00106500B050CF0010640F
+:10C71000018160060D906C0182600686343100B0A4
+:10C720005A230017A101BC600300168801BC5A2AD5
+:10C73000F437A101BC600300168A00B05E870014C4
+:10C740008F00B05A270017A101BC600300168901B1
+:10C75000BC5A2EF437A101BC600300168B00B05EFA
+:10C760008700149000B05A1B00148D00B05A1F00AF
+:10C77000148E01BC60030016040068DE030005E1AE
+:10C78000020350C70005E00100509F0017800180A0
+:10C790005E0291B48D01BC5E0292149001BC6003F4
+:10C7A00000378000025E02F0127E00B05E030014CB
+:10C7B0008C03BFDE02F005F00068C2470005E90106
+:10C7C00081E0068634310191600E84F42701BC605B
+:10C7D0000300143003BFDE02F0000200B0509F00DF
+:10C7E00017A100025E02F0017C00B05E87001427F2
+:10C7F0000186E0040310A000B04283001800010C81
+:10C80000D0030017A10068DE870065E4010250C76D
+:10C810000017A101805E8684F427018AE00E84F46B
+:10C820002700B050BF00142603BFDE02F005F70159
+:10C8300086E0040310A00200509F0005F70286C1A5
+:10C840000700060B03295E02F005FC00B05233001E
+:10C85000142D00B052370017A1019E5E8684F42784
+:10C8600000B0509F0017A10180DE86F437A100B010
+:10C8700050BB00108F00B050B700108E00B0509B1E
+:10C8800000108D01806006F4308C020250C7000653
+:10C890000A00B0524300108F00B0523F00108E00CB
+:10C8A000B0523B00108D011A52370017A10198DEDB
+:10C8B000870437A101B85E8691B08C018260028640
+:10C8C0003431018160020D906C0325DE02F0060E0A
+:10C8D000019C600284F42703BFDE02F00612028589
+:10C8E000500B00061000A850C70D143101BC6003A6
+:10C8F00000143001816002F5D7AE0183600284F438
+:10C90000270185E00209104801BC600300142E03D2
+:10C91000A25E02F001A003BFDE02F000020323DEEC
+:10C9200002F0067B03A35E02F0067B03A2DE02F0A8
+:10C93000067B01816006F577AB03AA5E02F0067BF9
+:10C940000183E0020910480351DE02F0063A0204B6
+:10C950005EB300062701846002F597AC0183E00214
+:10C9600009104800B02B5F0017A1006D2B0EF420BA
+:10C970000200E0027B00209E01BC6003000AC300AD
+:10C98000025E02F0111D03BFDE02F000020203DEB0
+:10C99000B30006370183E002F597AC00E02A9B0064
+:10C9A0002AA602015EBB00063700B02A9F0017A12D
+:10C9B000006D2A9AF4263201BC6003000AA600E04A
+:10C9C000027F00209F03A95E02F006350191601AE4
+:10C9D00084F42703BFDE02F002F201BC63FF1FF7FD
+:10C9E000A100025E02F00C3603295E02F006370158
+:10C9F00091601A84F42703BFDE02F0063700E002DC
+:10CA00006B00209A0180E006F577AB03BFDE02F0F1
+:10CA1000063F0301DE02F0063D00685E4F06263D3C
+:10CA200001BC60030017A803A45E02F0063F03C127
+:10CA3000DE02F0067E01846002091048020400BF95
+:10CA400000064401BC6003001115011400630017C7
+:10CA5000A100E06602F4306500025E02F00D1601EE
+:10CA600082600209104803A95E02F0065F00685E5A
+:10CA70003B04A64F01F0DE1700378500A05E16F0DC
+:10CA8000978500685E3B06264F0201500300064E64
+:10CA9000028780BF00064E0185E00609104802802B
+:10CAA000D00300065F00B05E1B0017A300B0008B30
+:10CAB0000017A4020400BF000655006E41973066BF
+:10CAC0005501185A030017A3011A5A030017A400AE
+:10CAD00068C18318065800E002930020A403BFDE5B
+:10CAE00002F0065A006D5E2EF4865A0182E0068638
+:10CAF000343100E05E3300378C0068DE32F4665D6E
+:10CB000000B05E0F001785006DDE2EF4666B03BF6C
+:10CB1000DE02F0067600B05E1F0017A300B0008FA3
+:10CB20000017A4020400BF000665006E419730663E
+:10CB300065011C5A030017A3011E5A030017A40025
+:10CB40006D5E2EF486670182E00686343100E05E79
+:10CB50003700378D0068DE36F4666A00B05E0F007D
+:10CB60001785006D5E2EF466760185E00209104897
+:10CB700003D1DE02F0066D00025E02F00D110068C6
+:10CB8000418318069A020300C7000674020CD00302
+:10CB9000000674028350C70006740068DE4B05A6C9
+:10CBA0007403BFDE02F011FC0181E006863431031C
+:10CBB000BFDE02F005C100025E02F00D11018160CE
+:10CBC0000209104803295E02F0067B028300C700B9
+:10CBD00011FC03BFDE02F005C103D1DE02F0067CCA
+:10CBE00003A5DE02F005C103BFDE02F000020280F1
+:10CBF00001B30000020206500300068500B00103E5
+:10CC00000017A1006D810AF4268500E844640877C6
+:10CC1000A1006E5E840826850187E006F577AB01EA
+:10CC2000085E4B0017A100685E8700268800B05E92
+:10CC30000F00178500025E02F00D1100685E3B06D2
+:10CC4000268E01BC600300178C0200D003000693FF
+:10CC500001BC600300178D03BFDE02F0069301BC28
+:10CC6000600300178C020300C70001A0020CD00370
+:10CC70000001A0019C600284F42703BFDE02F001E2
+:10CC8000A0006841831806990180600684F4270398
+:10CC9000295E02F005C101826006863431028300FC
+:10CCA000C70011FC03BFDE02F005C100E0029700DF
+:10CCB00020A50181600209104801BC600300081929
+:10CCC00000E0017B00A05E01BC601310D7A1006DE5
+:10CCD000017AF4200201BC601309405E03BFDE024A
+:10CCE000F0000200025E02F00B190338DE02F000D1
+:10CCF00002039EDE02F0000200E8444C00F7A100AF
+:10CD0000E85E840117A1006ADE840106AA00E85EDD
+:10CD10008401118701BC600300118801A5E0223065
+:10CD2000118001BC600300111301BC6003001114E9
+:10CD300000B044670017A100B0446B0017A200B018
+:10CD40005E8700110400B05E8B00110503B8DE029F
+:10CD5000F006AC03BFDE02F0000201BC600304B7C2
+:10CD60009201BC60030417A101BC63FF1FF0CB015B
+:10CD7000BC63FF1FF0CC01BC63FF1FF0CD01BC639F
+:10CD8000FF1FF0CE01BC63FF1FF0CF01BC63FF1F8C
+:10CD9000F0D000B052170010E801BC63FF1FF0C8CC
+:10CDA00000B0521B0010E901BC63FF1FF0C900B0C6
+:10CDB000521F0010EA01BC63FF1FF0CA01BC6003F0
+:10CDC0000010E4028600C30006CD00B0540F001727
+:10CDD000A20069DE8A9086C500E85212F450E40091
+:10CDE00068A0630006CD01BC60030010E400B054ED
+:10CDF000270010E000B0542F0010E103BFDE02F066
+:10CE000006D603A4DE02F008BC03A9DE02F008BCCB
+:10CE100001BC600301D7A1020600C30006CF028057
+:10CE2000DE5F0006D400B054070010E00068206305
+:10CE30000006D201D2DE86A030E000B0540B001014
+:10CE4000E103BFDE02F006D601BC5E869010E00171
+:10CE5000BC601F0010E101BC60030010E200B05292
+:10CE6000230010E501BC63FF1FF0C500B05227008E
+:10CE700010E601BC63FF1FF0C600B0522B0010E7A4
+:10CE800001BC63FF1FF0C700B00047001086010817
+:10CE90002063001781013852030017800102C02768
+:10CEA0000017A600025E02F011950068206300469C
+:10CEB000E400B05407001780028181B30006E60049
+:10CEC000025E02F00CF7006820630026EE0068A006
+:10CED000630006E9021A54070006EE006800A70185
+:10CEE00006EC0103C0270017A103BFDE02F006ED28
+:10CEF0000106C03B0017A101825E8610D08603A9FF
+:10CF0000DE02F0091700685E4F04270001BC63FFD2
+:10CF10001FF0C300685E4F05A6F601BC60031A90BF
+:10CF2000E301BC600306B79200685E4F052700036B
+:10CF3000BFDE02F006FA01BC600306379202984495
+:10CF4000070009E6028046070009E601BC600318F5
+:10CF500090E300B0206300178100025E02F00D0430
+:10CF600000E85E8400D7A1006A5E8690870000E832
+:10CF70005212F430E403BFDE02F0070301BC600389
+:10CF80000010E40338DE02F007030187E0061C907E
+:10CF9000E40190600A09104801BC61030437910064
+:10CFA000685E4F05A9E603835E02F008BC03BFDE9E
+:10CFB00002F0000201866002F7F7BF0182E002F58D
+:10CFC000B7AD0185E002F5B7AD0204416300071378
+:10CFD000018460020B105802055EAF00070F018745
+:10CFE000E006267133020400BF0007120185E0024B
+:10CFF000F577AB00025E02F00E4103BFDE02F000E7
+:10D00000020283C03700071B006CC4656C271C013B
+:10D01000BC601B1A77A100025E02F000BF0180E035
+:10D02000060337A200025E02F000C50180E002F4B0
+:10D0300057A200025E02F000C500E044656C4B613F
+:10D040000285C52300072B018460060B10580200DF
+:10D05000DEFF0007220180E002F7F7BF00682B6FB8
+:10D0600000072200E044655B4ADB0207AC0F0007C3
+:10D070002B0280456F00072B01BC63FF1FF7A10047
+:10D0800068DE862C272B01BC60130217A100025E0C
+:10D0900002F000BF01882C0E0337A200025E02F0EE
+:10D0A00000C501BC6003000B0302055EAF00072D45
+:10D0B00001BC6103001133020580BF00073301BCCE
+:10D0C00060131157A100025E02F000BF0196600ECE
+:10D0D00003301900B040670017A200025E02F000A2
+:10D0E000C50283C03700000200E0021F0020870154
+:10D0F00082600628914403BFDE02F00002028140F4
+:10D10000130000020200420300073A01846002F5A6
+:10D1100097AC01BC600300108003A3DE02F0073D62
+:10D120000190600209104800B0446700179E00B0EB
+:10D13000446B00179D00B0446F00179C00B044730F
+:10D1400000179B0068DE7A23273D00E002230020C1
+:10D15000880115403B00179700B001430017A1015B
+:10D16000C9DE8405280501BC60031077950191E0B4
+:10D17000020D906C0286403700074B00E002BB00B6
+:10D1800020AE03BFDE02F00A8E01BC6003001480F3
+:10D1900001BC600300148101B8600A04902401BC42
+:10D1A000600304082B01BC600300482A01BC600333
+:10D1B00000D02A01B3600700100401BC600300081E
+:10D1C0000E01BC600300080F01BC600300081001E1
+:10D1D000BC60030008110183E002F5D7AE0287C0EE
+:10D1E00037000A8A00025E02F0117700025E02F048
+:10D1F0000EFF03435E02F00757006D403300CAFA8A
+:10D2000000685E5F00476F00685E5F00276C006823
+:10D2100000A700C761006800A7010761006880A738
+:10D2200000A76200E0446690283701BC62C3001783
+:10D23000A102805203000765019652030017A10066
+:10D2400080DE8690379A0203520300076A00E05E90
+:10D250006A90379A0207D20300076A00E85E6B0003
+:10D26000379A029E5E6B000AFA03BFDE02F0077473
+:10D270000152D2030017A10185D206F4379A03BFE9
+:10D28000DE02F00774013C52030017A101BC5206F4
+:10D29000F4379A006E5E680BAAFA00682FC3000785
+:10D2A00074028E5207000AFA0204C03B00077E0196
+:10D2B00081E0060D906C02874037000A8E00025E06
+:10D2C00002F0117700025E02F00EFF0287C0AF008D
+:10D2D00007760287C0AF000A8A015840AF00179A4C
+:10D2E00001BC603F1E17A1006DDE6AF42A8A035B51
+:10D2F0005E02F0078001BC601300104300B04123C0
+:10D3000028104801806002F297940184E00209101D
+:10D3100048015840AF00102A006840AB002A8A013B
+:10D32000BB5E5600900402035E5700078F02004761
+:10D33000A300078C01BC621E3C11E001BC6003002D
+:10D3400011EA00B05E6B0011EB0198601E3D11E820
+:10D35000020047B300078F00B05E6B0011EF01B011
+:10D36000E0CE3D91EC03835E02F0079300025E0283
+:10D37000F0117700025E02F00EFF006D403304C72B
+:10D380008F03AADE02F0079C018360020D906C02FD
+:10D390000200F300079A0280521700079C00E04148
+:10D3A0008700B06500025E02F00C460280C0770084
+:10D3B000079B03305E02F0079C018360060D906CB2
+:10D3C00001BC60030008020188E00F000803006D43
+:10D3D00040330208B60129520F0017930109520F7A
+:10D3E0000017AA01966002F2979400E0418701F0CD
+:10D3F0006501BC600F0017A10028DE869067A801B8
+:10D40000866006F2979400E0419700706500E02086
+:10D41000AF00C82B01065E530017A200A05E4F04A8
+:10D4200077A10068DE870447B60186E006F297948C
+:10D4300000B85E8B0037A200B05A030017A0020AA2
+:10D44000DA030007B001876006F297940284C03BBC
+:10D450000007B60203DA030007B603AB5E02F0076B
+:10D46000B4020441070007B60180600500680301AB
+:10D47000065E530017A20182DE8A00900403AADE32
+:10D4800002F007E703AB5E02F007D10287D2130078
+:10D4900007E700B0521300118601A5E00A301180A1
+:10D4A000018460020D906C01BC63FF1FF79900E0DE
+:10D4B00041870170650068DEAB0027C300A05E4FA6
+:10D4C000FF77A10068DE870727CF03BFDE02F007E2
+:10D4D000C50284520F0007CF0204D20F0007C80311
+:10D4E000B15E02F007CE00E0418701106503BFDEA8
+:10D4F00002F007C903B35E02F007CE020080F3001A
+:10D5000007CF020052170007CF00025E02F00C4660
+:10D510000200C0770007CF012940770017990184E6
+:10D5200060060D906C020052170007E703315E029F
+:10D53000F007E7018660023011800180E001620B94
+:10D5400010020052170007D50202AB4F0007E2009D
+:10D5500068DE5F0007E200B02BB70017A100682A61
+:10D56000BB0007E200B02BB30017A2006DAABAF40B
+:10D5700047E20068DEAB0047DE006D2BBAF427DD22
+:10D5800000B02C6B000B190184E006F7F7BF0068B0
+:10D59000DE4F0287E200025E02F013090206DEFFA0
+:10D5A0000007E200E02BE7002AF90068DE5F0007D1
+:10D5B000E50068DEAB0047E50180E005620B100086
+:10D5C000682B6F0007E70180E006F7F7BF020752FC
+:10D5D0000F000867028047A3000864028047B30079
+:10D5E000086400E020AF00882B00E820AB00882A08
+:10D5F00001BC60030011E401BC63FF1FF7A501BC7F
+:10D60000600303D1E102065E530007F101BC600331
+:10D610000491E10206DE530007F500E04787005160
+:10D62000E10207D20F0007F500E047870091E10013
+:10D630006D403302C8B600685E4F0587F80068DEAB
+:10D64000AB00486703AB5E02F007FB020052170015
+:10D650000867020580F300080600E04187011065B5
+:10D66000020200F30007FF0204D20F0007FF00E0F0
+:10D67000418700B06500025E02F00C460200C077F0
+:10D68000000803012940770017A500E05E97009786
+:10D69000A50068DE97FFE8060280521700086702BF
+:10D6A0000700BF00086701BC601F1417A200904765
+:10D6B0008700306500E04196F4506500E04787013F
+:10D6C000082103835E02F0080E00025E02F011776B
+:10D6D00000025E02F00EFF006D403104280A006D6A
+:10D6E00040310428B601BC600B1D57A10068DE97CD
+:10D6F000FFE81E010F5A070017A5031EDE02F008FF
+:10D700001E0200521700081E032C5E02F00867007C
+:10D71000685E67FFE81E00E05E6700979900E05EC4
+:10D7200066F43064012A58030017990100DE97005F
+:10D7300017A500E05E66F4B79900E05E67003799D0
+:10D74000011558030017A603BFDE02F0082E00E003
+:10D750005E96F43064012A5803001799020580F39D
+:10D7600000082D0182E002F33799020052170008E9
+:10D770002D0116D8030017A6010F5A070017A401A0
+:10D780000CD8030017A10068DE92F4282900E05E9F
+:10D790006702179903BFDE02F00832010DD80300BB
+:10D7A00017A10068DE92F4286700E05E670417990D
+:10D7B00003BFDE02F00832011058030017A600680C
+:10D7C000DE9B00C8320181DA030017A100B85E8633
+:10D7D000C017A10281DE8700086700885E670077B6
+:10D7E0008000E000AEF0106401AADE65004802008F
+:10D7F00068DE9B00484C0207818700083F006DDE11
+:10D80000030C083F0285520F00083F0298523B006C
+:10D81000083F0181E00500680300E05E000B37A3CC
+:10D8200000E05E8F0097A300E041870077A200022E
+:10D830005E02F00D5200E820AB01082A01BC602313
+:10D8400007978100885E970077A100E85E86F4B0B4
+:10D850006301BC60070E17A100E0418EF430630045
+:10D86000B056170017A100B0561B0017A20068DEC3
+:10D8700086D048670068DE8AD0686700025E02F0E2
+:10D880000D2701BC602307506401BC624F0017A242
+:10D8900000025E02F00D7A00685E9B00486401BCE5
+:10D8A000621EF471E00068DE9B00C85701BC611382
+:10D8B00000B7A1020600F300085301BC601300B7D3
+:10D8C000A101BC60030011EE00B05E6B0011EF011E
+:10D8D00092E00EF431EC03BFDE02F0086400685EF3
+:10D8E0009B0068590068DE9B00A864019860063DB3
+:10D8F00011E800E020AF00882B00E820AB00882A68
+:10D9000001BC60030011EA0068DE5F00485F00B000
+:10D910005E6B0011EB0192DE5E3D11E80187600253
+:10D920003D11E80068DE9B00A863018760063D1199
+:10D93000E8019860163D11E80181E0050048020108
+:10D94000AADE6500480203BFDE02F0086C01BC627B
+:10D950000F0011E001BC60030011E40181E001004F
+:10D96000680301BC600F0011E801BC60030011EC0A
+:10D970000200200F00087300E020AAF3482A00B03C
+:10D9800020AF00102500E820AA04A82A006AA0AB56
+:10D9900001C87301B860060490240182E006F29782
+:10D9A000940188600A00900401BC60031877950315
+:10D9B000A0DE02F0088000685E4F06A8850138529C
+:10D9C0000300178000B05E5F0017810203DEB7001E
+:10D9D000087F00685E0700087E01BC600301778055
+:10D9E00001BC600300378103BFDE02F0087F01BC89
+:10D9F000600301578000025E02F000CC0068DEABDD
+:10DA000000488500A05E4F0477A100685E87004A49
+:10DA10003600685E87044A3603BFDE02F00BCC0393
+:10DA200086DE02F00A8B0287C037000A8A00025E97
+:10DA300002F0117700025E02F00EFF03035E02F0B7
+:10DA4000088503A9DE02F0089100025E02F011775A
+:10DA500000025E02F00EFF0207403700088B0386CB
+:10DA6000DE02F00A8B0287C037000A8A00025E02DB
+:10DA7000F00C43006E40300208BC0301DE02F008E7
+:10DA8000BC0068DEAB0008A3032B5E02F008970021
+:10DA9000E0022B00208A03BFDE02F0089B028052C6
+:10DAA0001700089A00E0024300209003BFDE02F056
+:10DAB000089B00E0025700209500685E4F040B6C45
+:10DAC00000685E4F028B6C00685E4F0209ED0068D3
+:10DAD0005E4F048A2F00685E4F050BBD00685E4FE5
+:10DAE000060BBD00685E4F068BC603BFDE02F00B5F
+:10DAF000CC0068DEAB0028B4032B5E02F008A70060
+:10DB0000E0022F00208B03BFDE02F008AB02805240
+:10DB1000170008AA00E0024700209103BFDE02F0D0
+:10DB200008AB00E0025B00209600685E4F06A9C1CA
+:10DB300000685E4F042BE400685E4F04ABE40068AD
+:10DB40005E4F05AA3C00685E4F0629C100685E4F23
+:10DB5000052BBB00A05E4FFF77A100685E87072BF7
+:10DB6000D703BFDE02F009E600E0021300208403C1
+:10DB7000BFDE02F009EA00E0020F00208301BC6072
+:10DB8000030011EC01BC600F0011E80284C03B00EF
+:10DB900008670184E00609104803BFDE02F0086749
+:10DBA0000200C09300000203A35E02F008C003C39A
+:10DBB0005E02F008BF03BFDE02F00AF600025E025A
+:10DBC000F0117700025E02F00EFF0207C0AF0008FE
+:10DBD000C4020740370008C00107C0AF0017A1000A
+:10DBE000B85E870037A101825E860D906C00B0445C
+:10DBF0007F000804018360020910480287C03700D3
+:10DC00000A8A0386DE02F00A8B00025E02F01177B8
+:10DC100000025E02F00EFF03435E02F008C90287B5
+:10DC2000C037000A8A020081B30008E7018060065D
+:10DC3000F297940301DE02F008E70138520300175F
+:10DC40008000B05E5F0017A400025E02F012F001D7
+:10DC5000BC602F0657A400E05E86F4906500E05A91
+:10DC60000300368003B05E02F008DB00E00207002C
+:10DC7000208103BFDE02F008DC00E0020300208008
+:10DC8000028481B30008E10184E0040D806C01BCD2
+:10DC9000600300006E01BC600300006F03BFDE0282
+:10DCA000F008E600E8523AF7B7A100E85E870217ED
+:10DCB000A100905E870097A100E101BAF4206E00F8
+:10DCC000E081BF00006F00B0523B0017BD0301DED2
+:10DCD00002F008FD028081B30008EA03305E02F022
+:10DCE00008FD01BC601B1F506500E04194DF3065FA
+:10DCF000012D406B0017A200885E8B0137A201380E
+:10DD0000402B001680028840270008F1018460063D
+:10DD1000D0168000B05A02F456800205C0270008D1
+:10DD2000F40187E006D0168001BC601B0DD7A1006E
+:10DD3000025E02F000BF00B0406700168101BC60C7
+:10DD40001B0DF7A100025E02F000BF00B0406700AB
+:10DD5000168200E01BE70066F900691BE70188FDF9
+:10DD600001BC60030006F9020081B30008FF020550
+:10DD700001B3000AFA0280200F000901006E403052
+:10DD80000209BC0381DE02F0090B00E0021700204B
+:10DD90008503A9DE02F009070184E00609104801A5
+:10DDA00080E0020910480184E002F7F7BF0386DE35
+:10DDB00002F00A8B0180600500480201806006F2D3
+:10DDC000979403BFDE02F0098A01836002F7F7BF70
+:10DDD0000386DE02F00A8B032B5E02F0093103A9F1
+:10DDE000DE02F009140068DEAB00493100B0523B9E
+:10DDF00000179F00B0523B0017BE01BC6003002813
+:10DE00000E03BFDE02F0093102875E5300093E03B4
+:10DE1000A0DE02F0092003BFDE02F006B20182E0BC
+:10DE2000060D906C0190600A09104800B0523B004A
+:10DE3000179F00B0523B0017BE019E5E8300B0EBFF
+:10DE40000106520F0017A100B85E870037A10182BA
+:10DE5000DE86F577AB01BC610300308000E8523A02
+:10DE6000F3F7A2006BD23AF3E92300E85E7E91D784
+:10DE7000A200905E8B0097A101BC602301D06400DA
+:10DE80006B523AF3E92E01185E870017A2010A5E71
+:10DE9000870017A300886006F457A200E04192F4BF
+:10DEA000706400B05802F45600006BDEFA91C9317C
+:10DEB00000B0523B0017BE03BFDE02F00931000282
+:10DEC0005E02F011E700B0203B00280E00B0523B8C
+:10DED00000179F0320DE02F0093E02075E5300098F
+:10DEE000350180E00209104803BFDE02F0093E0060
+:10DEF00068DE5F00093B021A54070009390103C0BC
+:10DF0000270017A101825E8610D0860102C027007B
+:10DF100017A100E0422AF4308A0180E0050048029F
+:10DF200003A9DE02F0093E00B05E47001080010840
+:10DF30005E4F0017A100685E8700295E03AB5E029A
+:10DF4000F009620200521700094F0068DEAB004979
+:10DF50004400E0025300209402865E5300098A02C6
+:10DF600084520F000AFA0284D20F00094903AC5E02
+:10DF700002F0094D03BFDE02F00956032C5E02F0E9
+:10DF8000095600685E4F04094D0106D20F0017A123
+:10DF900001845E86F2979400685E4F02098A03BF8F
+:10DFA000DE02F0097A031EDE02F0095303315E023D
+:10DFB000F009530068DEAB00495301846002F29718
+:10DFC000940068DEAB00495800E0023F00208F0358
+:10DFD000BFDE02F0095B00685EAB00495B02805265
+:10DFE0002F00098A0202410700095B00685E4F04A6
+:10DFF000098A00685E4F02898A0284410700098A03
+:10E0000001806006F2979403BFDE02F0098A032BB9
+:10E010005E02F0098A00685E4F05A97A00685E4FCB
+:10E0200005297A03BFDE02F0098A0068DEAB0049E9
+:10E030006A01BC6003000ABD01826002F5D7AE022E
+:10E04000805EFF00096800682B6F00096A00E044E9
+:10E05000655B4ADB00682B8BFFC96A00E02B8B00F5
+:10E060002AE202065E5300096D00E0026300209878
+:10E0700003BFDE02F0098A0323DE02F009750129DD
+:10E08000500B0017A30068DE8F0529750187E00299
+:10E090001070830184600209104800B05E87001789
+:10E0A000A1006EE00300297403D1DE02F0097500BF
+:10E0B00068DEAB00497700E0022700208900685E37
+:10E0C0004F00098A00685E4F01098A00685E4F05AB
+:10E0D000898A028047C70009BA0329DE02F0098055
+:10E0E0000102DEAF0017A10106520F0017A200388F
+:10E0F0005E86F4498A0182DE8AF577AB00B052234E
+:10E100000011F200B052270011F300B0522B0011A1
+:10E11000F40106520F0017A100E05E870031F50000
+:10E12000B0005B0011F000B047C30018000134C715
+:10E13000C70017A1006EDE8402A98A01BC60030833
+:10E1400010420283C10700098C02805E53000AFA64
+:10E1500000B040330017A10108A00F0017A200680B
+:10E160005E8B00699400E840310577A10281200FA1
+:10E1700000099400B020AF0017A10280A00F000991
+:10E180009400B05E630017A1006E5E840209BC00BB
+:10E19000B05E870007FA018160010048020202C0F8
+:10E1A0001300099A00E05E840347FA0181600500CC
+:10E1B00048020201200F0009B501035E530017A1B8
+:10E1C0000187DE850048020386DE02F00A8B00022A
+:10E1D0005E02F0117700025E02F00EFF03855E0220
+:10E1E000F0099D018E60023D11E80107C783001709
+:10E1F000A101825E850048020201A00F0009A7016B
+:10E2000003C7970017A101825E8500680300B02054
+:10E210004B0017A1018E5E850068030207C0AF00A6
+:10E220000C2701BC60030011EC01BC600F0011E879
+:10E230000184600500680300B040270007FC00B0BF
+:10E24000402B0007FD00B0406B0007FE00B0406FA0
+:10E250000007FF0184600500680300025E02F00C05
+:10E260004301BC63FF1FD7A800025E02F00D160039
+:10E27000025E02F00C2701A8600A0090040201204F
+:10E280000F0011D200A8401300500403BFDE02F0BB
+:10E29000061700E002870020A103BFDE02F009BDDF
+:10E2A00000E0020B00208203A9DE02F00AFA0184DA
+:10E2B00060060910480184E00609104803BFDE0229
+:10E2C000F00AFA032B5E02F009DE0068DE4F06A9B1
+:10E2D000C500E0023B00208E03BFDE02F009C6004D
+:10E2E000E0023700208D0323DE02F009E60068DE3D
+:10E2F0004EF1C9E60187E0021070830184600209D3
+:10E30000104800B05E870017A1006EE0030029CC22
+:10E3100003D1DE02F009CD00685E4F0629DC01BCA6
+:10E320006003000AA603295E02F009D20203DEB3ED
+:10E330000009D30191601A84F4270183E002F59764
+:10E34000AC020200BF0009DB0203456F0009D601E1
+:10E3500085E0062B715B02045EB30009DB0187E0F8
+:10E36000021070830183E00209104800025E02F08F
+:10E37000111E03BFDE02F009E60205500B0009E69C
+:10E380000182600609104803BFDE02F009E6028739
+:10E3900000C30009E30068DE4F06A9E30068D2135A
+:10E3A0000009E301BC600300118301BC600300119C
+:10E3B000820068DE4F0629E600E0024F002093034A
+:10E3C000BFDE02F009E603AB5E02F009E802044199
+:10E3D000070009EB028341070008BC03BFDE02F01F
+:10E3E00009EB028441070008BC01806006F29794A3
+:10E3F00003BFDE02F008BC039F5E02F009F0039E3B
+:10E40000DE02F00BCC02035E53000BCC020481430E
+:10E410000009F4010001630017A10102C0270017E1
+:10E42000A20038DE86F449EA03AB5E02F009F60288
+:10E430000052170009EA0280522F0009F803335EE8
+:10E4400002F00BCC023C523F000A09013C523F0053
+:10E4500017A10068DE84048A2901BC6003161064D9
+:10E4600001BC601F16106500685E87002A0500B0B9
+:10E470005A030017A20068DE8AC00A2900E041970B
+:10E4800000306500E0419300306400E85E8700578B
+:10E49000A1006A5E870029FE00685E87000A0A0103
+:10E4A000385A030017A1013858030017A20068DE8C
+:10E4B00086F44A2903BFDE02F00A0A0285C107007A
+:10E4C0000BCC01BC601F15F06501BC600305B7A44F
+:10E4D00000025E02F00106028000C3000A2901BCAE
+:10E4E000601310D7A600E0017F00B7A5006D5E960F
+:10E4F000F4CA1201BC60130957A500685E940BCAE8
+:10E500002D00B0017B00106500B052270017A2005B
+:10E51000B0522B0017A3006841940BEA1D0068DE7F
+:10E520008ED04A1900685E8AD02A2900E0419700FF
+:10E53000B065006D4196F4CA1601BC6013095065C0
+:10E5400003BFDE02F00A1600E0028B0020A200B03A
+:10E55000017F00106500B0522300168000B05227E2
+:10E5600000168100B0522B00168201BC5202F2F755
+:10E57000A101A95E02F4368300904467011684026B
+:10E580000281AB000A270068DE9305AA2801846097
+:10E5900006D0968400B05E9700005F020781AB0052
+:10E5A0000A2B01806006F2979403AB5E02F006CA64
+:10E5B00003BFDE02F008BC00E0028F0020A303BF0F
+:10E5C000DE02F009EA039EDE02F00BCC03AB5E0232
+:10E5D000F00A32020052170009EA03335E02F00B20
+:10E5E000CC01846006F2979403AB5E02F006CA0386
+:10E5F000BFDE02F008BC03835E02F00A3900025E4F
+:10E6000002F01177006D4033038A36006D4033030A
+:10E6100089EA032B5E02F00BD003BFDE02F006CACC
+:10E62000032B5E02F00A3F00E0023300208C03BFA0
+:10E63000DE02F006CC00E0024B0020920103C0276E
+:10E6400000178101825E0503178100025E02F00D52
+:10E6500004008800230037A200E05E8800F7A200D3
+:10E66000E05E86F451890186E00630118003BFDE4A
+:10E6700002F009E603A2DE02F0009F03A3DE02F02F
+:10E680000A6500E001FF00207F01BC60030017A3C2
+:10E6900003BFDE02F00A67018760040310A001BC1B
+:10E6A00060030051E400B0479300180001BC600310
+:10E6B00002900401BC620F0011E001BC600F013147
+:10E6C000E800B047A300180001BC600F0011E8018A
+:10E6D000BC60030131EC00B047B300180001BC601E
+:10E6E000030011EC018460060910480020601E0937
+:10E6F0000A5C00E001FB00207E03BFDE02F00A6D31
+:10E7000001BC60030ED7A1011400630017A200E052
+:10E710005E86F4506500E05A03003680020300C7AD
+:10E72000000A6203A95E02F00A670291509F000A84
+:10E73000660191601A84F42703BFDE02F00A6600C6
+:10E74000E001FF00207F01BC60030037A30323DE4C
+:10E7500002F00A6D0183E00209104801846002F5AD
+:10E7600097AC01BC600300178E0187E00210708334
+:10E770000182600209104803D0DE02F00A6E03D065
+:10E780005E02F00A6F0182E00209104803D5DE0242
+:10E79000F00A7101BC60030010B401BC600300F713
+:10E7A000A1006800A7000A750185421AF437A1008C
+:10E7B000025E02F000BF00B040670017A501BC6315
+:10E7C000FF1FF7A200025E02F000C500886007018B
+:10E7D00057A400B85E86F497A100025E02F000C55F
+:10E7E0000283C21F000A7C00E044670117A10204F3
+:10E7F0004523000A81006B4466F42A7E00025E0213
+:10E80000F0115E00685E8F000002006801B3000A2C
+:10E810008501BC60030004EE03BFDE02F00A88003D
+:10E8200020E01E090A8800B05E9700142E03BFDEA8
+:10E8300002F002F200A8412300F04803BFDE02F01C
+:10E8400000020183600209104801BC600700104209
+:10E85000006E4030020A8E00E0027700209D000228
+:10E860005E02F012A403A35E02F008BC03C6DE023F
+:10E87000F00A910184E00609104803BFDE02F00AA5
+:10E88000FA006820E3000A9900E844650717A1012F
+:10E89000BC609F0217A2006D5E86F44A9901BC60BD
+:10E8A0000300083800025E02F00B190020E10209A3
+:10E8B000008C0020628A090A9D00025E02F0117736
+:10E8C00003BFDE02F0008C0284452300008C03911C
+:10E8D0005E02F0008C0396DE02F0008C03965E026E
+:10E8E000F0008C00025E02F00B1901BC60030060B6
+:10E8F0002000680173000AB300025E02F000F1001C
+:10E90000B0446700083800B001730010E401BC6037
+:10E910000300000601BC600300005C01BC60030151
+:10E92000D78201D2DE087570E000B00EB30010E1AE
+:10E9300000B0004700108600B00ECF00108A01BC66
+:10E94000600300378100025E02F00CF70190600A5C
+:10E9500009104801BC610300308003BFDE02F000F3
+:10E960000201BC60030030420187E00224712300F1
+:10E97000025E02F0108401BC600306778000680D1F
+:10E98000EF000ABA00B00DEF00178100025E02F03E
+:10E990000DAE03975E02F00B2A03125E02F00ABA74
+:10E9A00001BC600300402001BC618300112500B060
+:10E9B000007B00112701BC600702578000025E0245
+:10E9C000F00DA900B05E07000B3001BC60070277B4
+:10E9D0008000025E02F00DA900B05E07000B31015D
+:10E9E000BC60130997A100025E02F000BF00B040B6
+:10E9F00067000B6301BC601309405E01BC60130932
+:10EA0000405F0180E006F5D7AE0107C1070017A1FE
+:10EA100001805E86F577AB01BC600F0011E801BC98
+:10EA2000620F0011E000025E02F00ADC01BC61CF5F
+:10EA30000C105C01BC600300105D01BC61CF01F0F3
+:10EA40005E01BC603B0AF05F00025E02F01048010C
+:10EA5000BC6003000835020300C700000201BC606F
+:10EA60000300060201BC600300060701BC6003004E
+:10EA7000060C01BC600300061103BFDE02F00002B9
+:10EA800001BC60030010480185E002F5B7AD01BC90
+:10EA900063FF1FF05401BC63FF1FF05501BC63BF4F
+:10EAA0001FF05601BC63FF0FF05700025E02F01228
+:10EAB000A40187E00624712301BC60030010540107
+:10EAC000BC600300105501BC600300105601BC601F
+:10EAD0000300105701BC600F0020170106C107009A
+:10EAE00017A101825E8402E017010741070017A108
+:10EAF00000B85E870037A10180DE870000160002A3
+:10EB0000DE02F000000285C03700000200025E0253
+:10EB1000F0117700025E02F00EFF02864037000A15
+:10EB2000EF00E0021B0020860386DE02F00A8B0263
+:10EB300087C037000A8B0158600300102A01BC60AF
+:10EB40000300900400B040130017A103BFDE02F0E1
+:10EB5000000201B8600A04902403AA5E02F00AFDD4
+:10EB60000158600300102A01BC600302900400B049
+:10EB700040130018000183600209104801BC6003C3
+:10EB80000051E400B0479300180001BC620F00116F
+:10EB9000E00180600100680300025E02F00EFF03E6
+:10EBA000855E02F00B0401BC620F0011E001BC6045
+:10EBB0000F0131E800B047A300180001BC600F004E
+:10EBC00011E801BC60030157A100E85E870037A18E
+:10EBD0000068DE87000B0B01BC600302900400B0EC
+:10EBE000401300180001BC60030131EC00B047B3D2
+:10EBF00000180001BC60030011EC0324DE02F006E3
+:10EC00001701866006F577AB00025E02F00B190172
+:10EC100080600610308100B05E870017A10180601F
+:10EC20000210308103BFDE02F0061701BC61030051
+:10EC3000108000B04203001800006EE003002B1C9F
+:10EC400003505E02F00B1F00015E02F0000003BFE4
+:10EC5000DE02F0030F01846002F597AC00A84123A7
+:10EC600004F048018260020910480206DEAF000B82
+:10EC70002503D5DE02F00B250350DE02F00B230145
+:10EC8000BC60030010B40284C783000B2801BC6081
+:10EC90000B0011E0018E6002F577AB0002DE02F09E
+:10ECA000000003A2DE02F0008C02BC4287000B31A0
+:10ECB00001BC60030037A401BC60031FF7A301146B
+:10ECC00000630017A200886006F457A203BFDE02AB
+:10ECD000F00B36008860070117A401BC63FF001722
+:10ECE000A3011400630017A200E05E8B0117A200CD
+:10ECF000886006F457A201BC601311106501BC6066
+:10ED00001B02506401BC60030017A50020C286F4FA
+:10ED10008B4000E0419706D06500E0419301F0642C
+:10ED200000E05E970037A500885E930037A40020BE
+:10ED30005E92F46B5F03BFDE02F00B390068DE9277
+:10ED4000F44B4500680083006B4503A0DE02F00B26
+:10ED5000450020C123160B3A00025E02F00B190099
+:10ED60006DDE93200B5B020300C7000B4F006DDECE
+:10ED700097008B4F01BC600300160801BC600300C4
+:10ED8000160901BC600300160A01BC600300160BE3
+:10ED900001BC600300160C01BC600300160D01BC31
+:10EDA000600300160E02005AC3000B5A023C5A9F21
+:10EDB000000B5A00680083006B5A0385DE02F000E6
+:10EDC0008C03855E02F0008C03A2DE02F0008C034F
+:10EDD000A3DE02F0008C0397DE02F0008C00B0414D
+:10EDE000970010600191600A84F42703BFDE02F0EF
+:10EDF00002F201806002D616B000B05E930010A14E
+:10EE000001836002F7F7BF01BC600300304303BF1A
+:10EE1000DE02F00B3A0068808300608C03BFDE02E4
+:10EE2000F00ABB0283C21F00000200B05E87001719
+:10EE3000A103D0DE02F0051E01BC600304104203F2
+:10EE40009EDE02F0000200B05E3F00114501BC6092
+:10EE50000300178F00B05E4300178500B05E0F00FF
+:10EE6000179000025E02F00B1903BFDE02F00002F1
+:10EE7000006D40330589EB03AC5E02F00B71006856
+:10EE80005E4F028BA600E0026700209903BFDE02FE
+:10EE9000F00BA600685E4F028BA600E0025F002028
+:10EEA0009701856002F5B7AD01826002F5D7AE012A
+:10EEB000BC6003000ABD039F5E02F00BB9039EDE37
+:10EEC00002F00B860321DE02F00B8600E0026F00E9
+:10EED000209B00025E02F00B1901866002091048B7
+:10EEE000018060020910480181E00209104801BC5C
+:10EEF00060030210420280441F000B8500B05E3F99
+:10EF000000114501BC600300178F00B05E4300177D
+:10EF10008500B05E0F00179003BFDE02F00B860085
+:10EF2000A044B6F07145039F5E02F00BB902820067
+:10EF3000C3000BA603335E02F00BA600B000730003
+:10EF400017A100E05E86B017A100E15E7AF4379E5B
+:10EF500000E1DE7700179D00E1DE7300179C00E002
+:10EF6000DE6F00179B039EDE02F00B97006E5E6E55
+:10EF7000924BB9006D5E6E924B97006E5E72922B53
+:10EF8000B9006D5E72922B97006E5E76920BB9009F
+:10EF90006D5E76920B97006DDE7A91EBB900B0440E
+:10EFA0006700083400B0446B00083300B0446F00C1
+:10EFB000083200B044730008310068A0D2232B97B8
+:10EFC00000E920D2F3D79E00E9A0CEF3B79D00E977
+:10EFD000A0CAF3979C00E8A0C6F3779B00E15E7A95
+:10EFE00091F7A100B05E8700111900E1DE76921161
+:10EFF0001A00E1DE7292311B00E0DE6E92511C00BD
+:10F0000068DE86232BA0031EDE02F00BB9039F5E91
+:10F0100002F00BB900685E4F028BB903335E02F059
+:10F020000BB901BC601F16B06501BC600300B7A43A
+:10F0300000025E02F001060068DE9300ABB9020731
+:10F04000C197000BB2013C5A07001788013C5A0BCC
+:10F050000017A103BFDE02F00BB401385A070017F6
+:10F060008801385A0B0017A101845E86F29794013B
+:10F0700087DE86249124020680F3000BB9018460A8
+:10F0800002F297940187E00224912403AB5E02F020
+:10F0900006CA03BFDE02F008BC032B5E02F009EAD9
+:10F0A00003BFDE02F006CA03AB5E02F00BC0032C06
+:10F0B0005E02F009EA03BFDE02F00BD000B052237B
+:10F0C0000011F200B052270011F300B0522B0011D2
+:10F0D000F401BC60030091F500B0005B0011F00387
+:10F0E000BFDE02F006CA0138523F0017A102065ED9
+:10F0F00053000BC90138524B0017A10068DE87008E
+:10F100008BCC03AB5E02F006CA03BFDE02F008BC84
+:10F110000068DE4F020BCF020781AB000BCF0180EE
+:10F120006006F2979403AB5E02F006CA020000F399
+:10F13000000BD50206DE53000BD501185E830017C5
+:10F14000A10068DE8700ABD501BC600B0251420212
+:10F150000052170009EA03BFDE02F008BC01BC60E0
+:10F160000300118301BC6003001182032C5E02F0D6
+:10F170000BDC0199E00620110003BFDE02F00BE07A
+:10F180000119402F0017A100685E870009E6019968
+:10F19000DE8620110003315E02F009E600A05E3B2E
+:10F1A0000097A200205E4EF449E601846002091037
+:10F1B0004803BFDE02F009E6032B5E02F009E60019
+:10F1C00068DE4F042BE900B0523300179F00B052A5
+:10F1D0002F0010EB0281522F0006B200E002AB00BC
+:10F1E00020AA0281522F0009C603295E02F00BEF0C
+:10F1F0000203DEB3000BEF0191601A84F427018350
+:10F20000E002F597AC0208522F0006CA03BFDE02E7
+:10F21000F008BC01BC600300106701BC6003001073
+:10F22000460180E0060930490282C11F000BF90146
+:10F23000BC602F1FF06501BC600300168000E84130
+:10F24000970030650069C197000BF601BC600B00A8
+:10F25000179401BC60030017AB01BC60030017AC3E
+:10F2600001BC60030017AD01BC60030017AE01BC18
+:10F2700060030017BF01BC600300202001BC6003D5
+:10F280000017A100025E02F000BF013840670000D5
+:10F2900028011C406700002901BC6003005049019F
+:10F2A000BC60030017A701BC60030017A801BC6085
+:10F2B000030017A901BC60030017AC01BC60030088
+:10F2C00017AD0182E0060F10780206C1E3000C0BB7
+:10F2D000006880A7000C0E03BFDE02F00C0F006870
+:10F2E00080A7008C0F01BC600B1EA00001BC600356
+:10F2F00000200101BC631301200201BC62330AC07B
+:10F300000301BC600300000401BC60530D800501D3
+:10F31000BC601F14106101BC601317D06001BC6099
+:10F320000300082900B05E0F00178500A044B6F066
+:10F330007145028741D7000C1A01BC6003000BF035
+:10F3400001BC600300107D01BC600300107C01BCA7
+:10F35000606300107B01BC600300107A01AC607F29
+:10F3600000107501BC63470897A10068C1DAF42C4E
+:10F3700026011A41DF0017A10068DE87016C260113
+:10F38000BC637B15ABF003BFDE02F00AA201885E0E
+:10F390005CFF87FC01BC601F1F500701BC600301BC
+:10F3A0009008018860060090040386DE02F00A8B54
+:10F3B0000305DE02F00C2B0386DE02F00A8B0385C8
+:10F3C000DE02F00C2D00B05E870017A1006EE00396
+:10F3D000002C310386DE02F00A8B006EC0146F2C05
+:10F3E0003401BC60070010420207C0AF00077A007A
+:10F3F00002DE02F0000003215E02F00C3A00E02081
+:10F4000066F4281900B0206700178B03BFDE02F0F6
+:10F410000C42028150C7000C3F011C509F00178B0B
+:10F4200000E05E2EF4378B019C5E2E84F42703BF30
+:10F43000DE02F00C42011E509F00178B00E05E2E92
+:10F44000F4378B019E5E2E84F4270002DE02F0006A
+:10F45000000107402700082800E020A3002828001A
+:10F4600002DE02F0000000B05A0300101F00B05A84
+:10F470000700102000B05A0B001021018060070027
+:10F48000101D02804077000C4A0002DE02F00000EE
+:10F490000187E002F577AB03915E02F000020020E5
+:10F4A000E3FE09000202815E53000C580283411FF3
+:10F4B000000C520281DE53000C5E01BC600300119F
+:10F4C0005101BC600300115201BC620300115301E1
+:10F4D000BC600300515001896006F2979403BFDEBF
+:10F4E00002F000020280C54300000201F0C547009F
+:10F4F00011560107C5470017A101F0C54AF431555F
+:10F500000189600AF2979401BC60030810470392D6
+:10F51000DE02F000020204C107000002039EDE02C8
+:10F52000F00C6503B8DE02F0000200B0017F0017A6
+:10F53000A10068DE840BC00203BFDE02F00C67028C
+:10F5400003DE530000020068DE23000C6802845EC4
+:10F55000530000020287C4930000020282DEBB0057
+:10F560000C6B00682B07000C6E00682B8FFFE0020D
+:10F5700000B02AF70017A1006DDE8556000200B02A
+:10F58000012B0017A30282DEBB000C7100682B0761
+:10F59000000C7200E05E8D5C77A300B0440B001796
+:10F5A000A100B0440F0017A200E95E862337A10036
+:10F5B000E8DE8A2357A200E95E86F4681400E8DEDC
+:10F5C0008B00081500B0441F001800008844230178
+:10F5D00057A30090442300D7A4006E5E8AF48ACE1D
+:10F5E0000068816F000C7F00685E23002C9100682A
+:10F5F0000027002C9100E85E230037A10069DE8718
+:10F60000000C8200E05E840137A1013C016F00170D
+:10F61000A50068DE97000C890138016F0017A5006E
+:10F62000685E97000C8D00E85E970037A100685E69
+:10F6300087000C9103BFDE02F00C8D00E85E97009E
+:10F6400037A50080DE940137A500E05E860DB7A1E6
+:10F6500000685E87000C9100E12052F4681400E01D
+:10F66000A056F4881500E85E870037A1006A5E871F
+:10F67000000C8D01BC610300112300692057000CB0
+:10F68000950180E006F2979403BFDE02F00C97012B
+:10F6900080E002F2979403BFDE02F00002006841AE
+:10F6A00027000CA102844523000C9800B044670099
+:10F6B00017A100E84466F437A2006D5E8B004C9AF7
+:10F6C0000392DE02F00ACE00025E02F01088000211
+:10F6D0005E02F00DB900025E02F00DB400025E029F
+:10F6E000F00DC401BC600F0011E8031EDE02F00C37
+:10F6F000A801BC600300105C01BC600300105D0148
+:10F70000BC605304105E01BC600300105F03BFDEE9
+:10F7100002F00CAC01BC600B00105C01BC6003008B
+:10F72000105D01BC604304105E01BC600300105F0B
+:10F7300001BC6003008020028500BF000CE800B01F
+:10F74000205300115100B02057001152006E20527A
+:10F750002A8CB40068A057000CB400E02052232883
+:10F760001603BFDE02F00CB600B0446700081601B5
+:10F77000BC600300315001BC60030C90400000DE0F
+:10F7800002F000000068C103000CBB02804543008A
+:10F790000CB6006B446502CCB601BC60030011508E
+:10F7A00002844543000CBC00B044670017A1006808
+:10F7B0005E86232CBE01BC600300402001866006EB
+:10F7C00020110000E920522A37A100E8A0562A574C
+:10F7D000A200E14466F4311900E1C46AF4511A0050
+:10F7E000E1C46F00111B00E0C47300111C00B044A1
+:10F7F0001F001800008844230157A30090442300F1
+:10F80000D7A400B0440B0017A100B0440F0017A20A
+:10F8100000E95E862337A100E8DE8A2357A200694B
+:10F82000DE8B000CD600E1440AF4710200E0C40E45
+:10F83000F4910300E02AF7002ABD00E85E230037B8
+:10F84000880069DE23000CCA00E80027003788031F
+:10F85000BFDE02F00CCA018660022011000200DE49
+:10F8600053000CEA0180E002F2979400025E02F07D
+:10F870000DB701BC600300104003BFDE02F00CDDD9
+:10F88000020080C3000CE100E044640957A100E8D5
+:10F890005E862137A1006CC466F42CDF03BFDE0254
+:10F8A000F00CEA00E8012A21281401BC60030008DA
+:10F8B0001500B0205300115101BC6003001152012A
+:10F8C000BC600300315002804543000CE603BFDEFC
+:10F8D00002F00CC001BC600300104000B0012B001E
+:10F8E00011090068AAE7000CEC0000DE02F000003D
+:10F8F00003565E02F00CEE00025E02F0014A00B018
+:10F90000012F00110901BC61CF0C105C01BC600328
+:10F9100000105D01BC61CF01F05E01BC603B0AF0EC
+:10F920005F00025E02F00DC000025E02F00DC90031
+:10F93000025E02F00DBD03BFDE02F00ACE01885E5A
+:10F940000610D08601025E070017A101825E8610B4
+:10F95000D08601BC600306778000B00DEF001781F0
+:10F960000288421B000CFE00B00DEB0017810068FE
+:10F970005E07000D0000025E02F00DAE020B421B9E
+:10F98000000D0203BFDE02F00D03018B20A210D098
+:10F99000860002DE02F0000000B054130017A1023E
+:10F9A00000DE07000D0B00B0418B00106501BC604C
+:10F9B0000301D7A100025E02F011A200E05E840004
+:10F9C000F7A103BFDE02F00D10020480F3000D105A
+:10F9D00002025E07000D1002805E07000D1000900D
+:10F9E000001B0037A200E85412F457A10002DE0207
+:10F9F000F00000020400BF000D1400025E02F00ED1
+:10FA0000B803BFDE02F00D1500A044B6F0B145000A
+:10FA100002DE02F00000020000BF000D260068AC0C
+:10FA20000F000D2600E05EA30037A8006D5EA00564
+:10FA3000CD2600B02CB70017A100025E02F000BF77
+:10FA400000B040670017A20068DEA3FFED2300B0FE
+:10FA50005E8965D7A2006D00A7008D22006DA0A36E
+:10FA6000004D2403BFDE02F00D230068A0A3000DAB
+:10FA70002400B85E8965D7A200025E02F000C501CD
+:10FA8000BC60030017A80002DE02F0000000D85A94
+:10FA9000030117A201B85A06F457A200B05603009A
+:10FAA000083C00B0560700083D00B0560B00083E69
+:10FAB00000B0560F00083F00B0561300084000E0A9
+:10FAC0005612F4484100B05A0300083A01385E8BE0
+:10FAD00000083B00B021070017A401BC6003001719
+:10FAE000A200B0419300106500B85E92D017A40048
+:10FAF000E05E06F4506300F05E930017A300F05E32
+:10FB0000930077A400E05E8B0037A200B85E92F409
+:10FB100077A400E04192F4506500E05602F495802D
+:10FB200000B056030017A4006EDE8B00AD3400B8A1
+:10FB30005E92C0D7A200D85E8B0037A200E020F210
+:10FB4000F4483C00B020F30017A400B85E92C0F760
+:10FB5000A200D85E8B0037A200E020F6F4483D00FA
+:10FB6000D820F70037A200E020FAF4483E00D82061
+:10FB7000FB0037A200E020FEF4483F00D820FF0041
+:10FB800037A200E02102F4484000D821030037A248
+:10FB900000E02106F4484100B021070017A200B898
+:10FBA0005E8AC017A200905E8B0037A201BC5E89FE
+:10FBB00007683B0002DE02F00000018060063C9115
+:10FBC000E4018760063CD1E601A860023CD1E60171
+:10FBD0008B60023CD1E600B05E8F00106300B0562F
+:10FBE000030011E700B056070011E700B0560B0004
+:10FBF00011E700B0560F0011E701A960423C91E403
+:10FC000001A860023CD1E6018B60063CD1E600B061
+:10FC10005E8B00106301BC60030057A10204560311
+:10FC2000000D6201BC60030117A100E0418EF430B9
+:10FC30006300B056030011E700B056070011E7005B
+:10FC4000B0560B0011E700B05E8B00106301BC6082
+:10FC50000300B7A10204D603000D6C01BC600301D0
+:10FC600017A102065E53000D6C01BC60030197A151
+:10FC700000E0418EF4306300B056030011E700B09D
+:10FC800056070011E700B0560B0011E701BC6003F6
+:10FC90000017A10206DE53000D7700B05E8B001046
+:10FCA0006302065E53000D7600A0563F01F7A103E4
+:10FCB000BFDE02F00D7700A0563301F7A100B05E61
+:10FCC000870011E701BC60030011E70002DE02F0CB
+:10FCD000000000685E9B00CD9401BC60070211E348
+:10FCE0000068DE9B004D8700E847870111E101BCF9
+:10FCF00060030011E201BC60030011E201BC60037B
+:10FD00000011E201BC60030011E201BC60030011BC
+:10FD1000E201BC60030011E201BC60030011E201DA
+:10FD2000BC60030011E200B06142F451E000B05841
+:10FD3000030011E200B058070011E200B0580B00B8
+:10FD400011E200B0580F0011E200B058130011E2A8
+:10FD500000B058170011E200B0581B0011E200B0CB
+:10FD6000581F0011E200B05E9B0017A40068DE9BE4
+:10FD700000AD9201BC60030077A40192DE930217EC
+:10FD8000A30002DE02F0000001BC60070011E300E6
+:10FD9000B058030011E200B058070011E200B0585B
+:10FDA0000B0011E200B0580F0011E200B058130030
+:10FDB00011E200B058170011E200B0581B0011E228
+:10FDC00000B0581F0011E200E00146F0106401BCD1
+:10FDD00060070031E300B058030011E200B058079B
+:10FDE0000011E200B0580B0011E200B0580F0011F2
+:10FDF000E200B058130011E200B058170011E20001
+:10FE0000B0581B0011E200B0581F0011E20192E04F
+:10FE10001B0017A30002DE02F00000028740C300AF
+:10FE20000DA901866006F01030028640C3000DABBC
+:10FE300000B040C70017810002DE02F00000028718
+:10FE400040C3000DAE00B05E070010310186E00631
+:10FE5000F010300002DE02F00000006800A701127E
+:10FE6000E003BFDE02F00DC800025E02F00DB70035
+:10FE7000025E02F00DC90002DE02F0000000680020
+:10FE8000A70112A90002DE02F0000001816006094C
+:10FE90003049006800A7008DBC00025E02F00DD959
+:10FEA0000002DE02F0000000025E02F00DD90181C6
+:10FEB00060020930490002DE02F000000188E00E15
+:10FEC00009304900B0412700180000B0002B001095
+:10FED000020002DE02F0000001BC6003001002011B
+:10FEE00082E0020F107801BC600300104900B041AD
+:10FEF000270018000002DE02F00000006800A701E1
+:10FF00000DCA0280DE53000DD001BC60130777A13B
+:10FF100000025E02F000BF019060020337A20002FF
+:10FF20005E02F000C50002DE02F0000001BC6013BA
+:10FF30000797A100025E02F000BF0190601E033728
+:10FF4000A200025E02F000C501BC60130777A100A9
+:10FF5000025E02F000BF0190601E0337A200025E45
+:10FF600002F000C50002DE02F000000100DE5300D6
+:10FF700017A60181DE9A09304900B0412700180018
+:10FF80000002DE02F000000002DE02F0000000B01D
+:10FF900044670017A2017D5E8A2357A300B01C7737
+:10FFA0000017A100B85E84E3D7A2025A5E8B000D51
+:10FFB000E60180E006F4271E01825E86F297940037
+:10FFC000B05E8F00071B02001C7B000E2D00E85E58
+:10FFD0008CE377A2006D5E88E38E2D00E04467021B
+:10FFE00087210285C523000E2A0020E3FE090E2A80
+:10FFF00001BC60130997A100025E02F000BF006817
+:020000023000CC
+:10000000C067000E2A01BC60131617A100025E0231
+:10001000F000BF0068C067000E2A01BC601309D75A
+:10002000A100025E02F000BF0068C067000E2A0156
+:10003000BC63FF1FF7A10068DE862C2E2A02009CFD
+:100040007B000E1E0180E000E3C71E01BC60230F91
+:1000500057A100025E02F000BF00B040670077A425
+:1000600000B05E930017A200025E02F000C501BC62
+:10007000601B1B57A100025E02F000BF0181E00679
+:100080000337A20186E006F457A200025E02F000E8
+:10009000C501BC601714D7A101BC600300B7A20062
+:1000A000025E02F000C501BC60171457A101BC60DC
+:1000B000031877A200025E02F000C501BC601714AD
+:1000C000B7A101BC600300F7A200025E02F000C508
+:1000D00001BC60171077A101BC600F0417A20002D9
+:1000E0005E02F000C501BC60171097A101BC60035F
+:1000F0000017A200025E02F000C501BC601710B735
+:10010000A101BC600B0017A200025E02F000C50155
+:10011000BC601710D7A101BC60030017A200025EEB
+:1001200002F000C501BC60171017A101BC600B00F4
+:1001300037A200025E02F000C501BC60230F57A188
+:1001400000A85E930077A200025E02F000C501BC29
+:1001500060171017A100025E02F000BF02004067A6
+:10016000000E23006CC464E42DEA03BFDE02F00E2F
+:100170002A01BC60171277A100025E02F000BF00E6
+:1001800068C0671FEE2A01806000E3C71E01BC60E3
+:100190000300904301806000E3C71E01826002F209
+:1001A00097940180E004E3C71E01BC600300071AB6
+:1001B00003BFDE02F00E2D0002DE02F0000002019D
+:1001C000C11F000E4002855EAF000E330185600640
+:1001D000F577AB00B0446700082500B0446B000819
+:1001E0002600E9446504B7A100E8C46904D7A20069
+:1001F000D05E870077A101E1DE8AF437A200E95ED4
+:10020000862697A100E8DE8A26B7A200695E8B00E9
+:100210000E4001BC610300113300E144DAF43136D1
+:1002200000E144DEF4513701856002F577AB01BC93
+:10023000600301104701BC60030050430002DE026E
+:10024000F0000000B0451F00178100B005B700178F
+:10025000A601BC600704106401BC601311106501A5
+:10026000BC60030017A10205DEAF000E5900B058B4
+:100270000F00178000685E842C2E6102005E9B00D8
+:100280000E590280DA03000E4F0118581F00178222
+:1002900000E05E0B00378201985E0AC0F60703BFDC
+:1002A000DE02F00E52011A581F00178200E05E0BAA
+:1002B000003782019A5E0AC0F60701F0DE030037BC
+:1002C0008000A05E02C0578000B05E0300160300ED
+:1002D000A044B6F0178200B05E0B00160500E05E89
+:1002E0000AC0960603BFDE02F00E6100B05813008C
+:1002F000178200E85E06F057A5006ADE97000E5FE1
+:1003000000E85816F4B6050069D817000E5F01BC66
+:10031000600300160500B058170017A500E058123A
+:10032000F4B60600E0419302106400E0419706D065
+:100330006500E05E870037A100905E9B0037A60055
+:1003400068DE87008E4601BC600300114701BC6077
+:100350000300016D0002DE02F0000001BC6003003A
+:10036000016C01BC600300016D01BC60070A1064F0
+:1003700001BC60030077A100B0428F00178000A08D
+:100380005E0301F78000B05E0300016E01BC63FFF5
+:100390001FF7A20068DE03000E7301BC60030017A4
+:1003A000A200886006F43781002005BAF02E78009C
+:1003B00068DE8AC0CE7800E005B300216C00B0058D
+:1003C000B6F0216D00685E03000E7C00205E06F032
+:1003D0000E82006EDE8AC0CE8203BFDE02F00E7D8A
+:1003E000006DDE8AC0CE8200B05E870017A300B029
+:1003F000419300016600B0581B0017A201BC6003C6
+:1004000000016C01BC600300016D00E84193021023
+:100410006400E85E870037A10069DE87000E730084
+:10042000B05E8F0001650002DE02F0000000B00542
+:100430009B001064006E581B002E8B00E0581B00C0
+:10044000314503BFDE02F00E8C00B0581B00114591
+:1004500000B0059B00016200B0059700016100B08B
+:10046000580F00178500B0580700178300B0580BCD
+:100470000017840118581F00178C011A581F001705
+:100480008D0002DE02F0000000B00597001780002A
+:10049000685E002C2EB701BC600300111201BC6025
+:1004A0000300111500B0059B0010640200452300F5
+:1004B0000EA100B0451F00178100E80592F03780BB
+:1004C000006ADE03000E9F00B05E0300114503BF0B
+:1004D000DE02F00EA201BC600300314503BFDE0264
+:1004E000F00EA200B0059300114500B00583000195
+:1004F0006900B0058B00016A00B0058F00016B0038
+:10050000B0058700016800B005AB00106502845A91
+:100510001F000EAB00B05E1700168301985E32D04C
+:10052000F687019A5E36D0F68701846002D0F6879E
+:1005300000B0059300016000B0059B00016200B0AF
+:10054000059F00016300B0059700016100B0058BB5
+:1005500000106400B0580F00178500B0580700174E
+:100560008300B0580B0017840198581EF1978C0136
+:100570009A581EF1B78D03BFDE02F00EB70002DEFF
+:1005800002F0000000B0058B001064006E41932A59
+:100590000EC500A044B6F0B7A100B05E87001605F6
+:1005A00000E05812F4360600B0581B001145020056
+:1005B00000F3000EC2006D4193280EC20200DEAFB0
+:1005C000000EC201BC600B02514200B05E87000108
+:1005D0006F02015EAF000EC500B05E17001603018A
+:1005E000816002F577AB0002DE02F00000020145F7
+:1005F00023000ED00287C493000ED001826002F562
+:10060000D7AE02012C43000ECD00E02C4B002B1284
+:1006100001816001620B1002055EB7000ED000E0A0
+:100620002AF7002ABD01856002F5B7AD0002DE029F
+:10063000F00000020200BF000EDE00025E02F00FBA
+:10064000000202DEB3000ED60020428F000C4C03E5
+:10065000BFDE02F00002028881AB000EDE02845E83
+:10066000FF000ED402845EB3000ED40282DEFF00CF
+:100670000ED402822B4F000EDC00682ABB000EDE77
+:100680000284DEAF000ED402835EB7000ED400B049
+:100690005E870017A10002DE02F000000182E00286
+:1006A000F597AC0203DEFF000EE802844523000E3E
+:1006B000E802012B4F000EE80180E006F29794005B
+:1006C000025E02F00DD90180E002F2979400025E12
+:1006D00002F00DD90180E002F29794028400C70075
+:1006E0000DB203BFDE02F00DB4020400C7000EF22B
+:1006F0000284C56F000EFE02844523000EEF020047
+:100700004203000EFE00685E4B04AEFE00685E4BC6
+:1007100006AEFE00685E4B062EFE0182E006F597EF
+:10072000AC02844523000EF50323DE02F00EF60131
+:1007300083E006F597AC0180E006F297940284000E
+:10074000C7000DB200B02AF70017A2006DDE89566F
+:100750000DB202872B4F000DB402005EFF000DB2F8
+:100760000287AB4F000DB403BFDE02F00DB20002F2
+:10077000DE02F00000020200BF0012FD00682B0B39
+:10078000000F0500E844655857A101BC63F71D1729
+:10079000A2006D5E86F44F0500E84466F44AC2008C
+:1007A0006CC465576F0700E84467002ABB028045A8
+:1007B0006F000F430203DEB700103D0183E002F536
+:1007C000B7AD0202DEB3000F0D018360062B915C12
+:1007D00000025E02F00EE002835EBB000F1000E834
+:1007E00045895BF7A1006E5E8555AF280204DEB730
+:1007F000000F2400E02BB7002AED01BC6003000AC3
+:10080000EF00682C67000F1500E82C67002B19001B
+:10081000B02BB70017A201856002F5B7AD0204DE68
+:10082000FF000F1A006D5E895DCF1A0184E002F7A8
+:10083000F7BF0206DEFF000F2400E02BE7020AF9F3
+:1008400000B04467000B0401182BE70017A1011A40
+:100850002BE70017A2006E5E87000F22006DDE8975
+:100860005F4F2203BFDE02F00F2401BC6003000AC9
+:10087000F90186E002F7F7BF02025EFF00103D00BB
+:1008800068AB0B00103D00B02AE7000AC20002DE90
+:1008900002F000000182E002F7F7BF02025EFF00F3
+:1008A0000F35020600C7000F2E02802BF3000F2E1B
+:1008B00000B02B4B0017BB006E2B22F7703D0202DD
+:1008C0005EFF000F3500E845895BF7A1006DDE850E
+:1008D000614F3300E844656177A1006D5E85618FEB
+:1008E0003500B04467000AC20002DE02F0000002D8
+:1008F00004DEB7000F3D00E8446556CABE00682C10
+:1009000067000F3900E82C67002B1900E02BBF00AF
+:100910002AEF00B02BC30017A1006D2BBEF42F3DB2
+:1009200001BC6003000AED0068AB1700AF4000B0E7
+:100930004467000AF700B0446B000AFB0068AB177D
+:10094000012F4200B04467000B130002DE02F000EA
+:10095000000203DEB7000F4A0282DEB300103D0240
+:1009600003C57300102F00E844655737A1006D5E82
+:100970008556B03D01836006F5D7AE03BFDE02F0B9
+:10098000103D01BC6003000ADF006D45871F4F4D1D
+:1009900000B04587000ADF00E044655BF7BB00E874
+:1009A0005EEE2C2AB901836002F5D7AE0183E00622
+:1009B000F5B7AD0184E002F5B7AD01826002F7F74B
+:1009C000BF01846002F5B7AD0101456F0017A101B9
+:1009D000875E86F577AB01BC6003000B0D00025EFD
+:1009E00002F012FE00E844655737A1006D5E855E97
+:1009F000CF58006D5E8556AF5C00E02B83002AE087
+:100A000000B02AB30017B3028600C7000F690206C0
+:100A100080C7000F6002075EAF000F63020680C749
+:100A2000000F650184600561AB0D03BFDE02F00FAE
+:100A30006501826006F7F7BF00B02AE7000AC1022D
+:100A400000C56F000F6901846006F5B7AD02048030
+:100A5000C3000F690184E00561AB0D01BC600300B8
+:100A6000117800B045E300180000B045E7000ACC5B
+:100A700001BC600300317800B045E300180000B00D
+:100A800045E7000ACD01BC600300517800B045E3A2
+:100A900000180000B045E7000ACE0184600006009F
+:100AA000300207AB3B000F75018460040600300084
+:100AB000B02B330017BB012A5EEF000AC501BC60F2
+:100AC000131C57BB021E2B33000F7C011E2B33005F
+:100AD00017A60080DE9AF777BB00B041B70017B3C6
+:100AE000006E2B1701EF800088600558B7BB00200F
+:100AF000DEED5D4F8303BFDE02F00F8600E82B17AB
+:100B00000217BB00886006F777BB00205EED5D6FC3
+:100B10008601846006F5B7AD020480C3000F86012C
+:100B200084E00561AB0D006E2B1701EF8D006D2B7E
+:100B300017004F8A006E2B17006F8A0068AC6700A1
+:100B40000F910088600558B7BB0020DEED5B8F90E9
+:100B500003BFDE02F00F9100E82B170217BB0088DD
+:100B60006006F777BB00205EED5BAF910184600506
+:100B700061AB0D0068AB1702EF97010DAB370017A3
+:100B8000A1010EAB370017A200685E87000F970027
+:100B9000E05E86F457A100E05E87080AC50068ABF6
+:100BA0001700AFA102075EFF000FA1012C2B3B0035
+:100BB00017A3006DDE8D612FA100685E8F000FA16D
+:100BC0000280AB37000F9F0183600561AB0D03BF4F
+:100BD000DE02F00FA100B02BFB000AF800B0446B5E
+:100BE000000AFF0068AB17012FAE0281ABF3000FC4
+:100BF000AE01BC6003000AE200682C4F000FAE009B
+:100C0000E844656277A1006D5E85628FAB00B02C11
+:100C1000530017A200E05E8962B7A2006DDE86F481
+:100C20004FAD0200AC43000FAE0185600561AB0D16
+:100C300003BFDE02F00FAE0180E001620B1000681E
+:100C4000AB17010FB100B02AE7000AD90187E0060F
+:100C5000F7F7BF0207DEFF000FB30181E00561ABCC
+:100C60000D00682B17002FB700682B1701EFB70096
+:100C7000682B17030FB70068AB17008FC0018260A5
+:100C800006F7F7BF00B02AE7000AC10068AB1703F8
+:100C90000FBD00B00013000AC500B02B9F000AC8AA
+:100CA00003BFDE02F00FBF0068AB17008FC0011A50
+:100CB0002B37000AC800B02AE7000AD00202DEBBC8
+:100CC000000FC60284DEFF000FC30206DEFF000F26
+:100CD000C600B02BB70017A1006DDE855DCFC60141
+:100CE00082E00561AB0D00E05ECD55B7B3018260D7
+:100CF00002F5D7AE00B02C4B0017A100B02AF700C8
+:100D000017A2006D5E89560FCD02855EB7000FD623
+:100D100003BFDE02F00FCF006D5E8560EFD8028169
+:100D20002C43000FD600B0440B0017A300B0440FB3
+:100D30000017A200E95E8E2337A300E8DE8A23575E
+:100D4000A200695E8B000FD80068DE8B000FD80010
+:100D50006E5E8EF66FD801826006F5D7AE00025E39
+:100D600002F01143020600C7000FE601BC60131C2D
+:100D700057BB012C2B3B0017A20080DE8AF777BB04
+:100D800000B041B70017A200682B17004FEE0068B3
+:100D90002B17024FEE00682B17026FEE00682B171F
+:100DA000006FEE00682B17084FEE00682B17086FD6
+:100DB000EE00682B17088FEE03BFDE02F00FFB0377
+:100DC000BFDE02F00FEE02045EB7000FFB020680EA
+:100DD000C7000FE902075EAF000FFB00682ADB00C7
+:100DE0000FF400E8446556D7A201BC60371597A3FD
+:100DF000006D5E8AF46FFB006E5E895D8FFB01847F
+:100E0000E006F5B7AD00685E8B000FF400B05E8BB6
+:100E1000000AAE0182E006F5D7AE006E5E89610F72
+:100E2000F40182600561AB0D00E844655737A1000D
+:100E3000B044670017A300E85E8EF42AB60068ABE2
+:100E400017088FFA00B02BCB0017A200E82ADAF4BB
+:100E50004AB601846002F7F7BF0282DEB300103D9C
+:100E60000203C57300102F00B02ACB0017A200B0F8
+:100E70002AD30017A3020600C70010090068AB17A9
+:100E800000900902802BF300100900B02B230017FB
+:100E9000A1006D5E855970050180E00561AB0D0014
+:100EA000685E8700100900682C0700100900B02C4C
+:100EB000070017A200B02C0B0017A300685E8F007C
+:100EC000100F00682B0B00100F00E844655857A165
+:100ED00000E05E8EF457A2006D5E86F4500F018133
+:100EE000600561AB0D0281AB4F00101402005EFF84
+:100EF0000010140204452300101403A0DE02F010B9
+:100F0000140183E00561AB0D028080BF00103D023B
+:100F1000825EBB00103D02822BF30010290281ACDF
+:100F2000370010290280AC3700102902812C3700CD
+:100F3000102902822C37001029028881AB00102969
+:100F40000282AC3700102202802B37001029028366
+:100F50002C3700102202852C3700102202842C37F7
+:100F60000010290284AC370010290283AC3700102E
+:100F70002902835EB70010280204DEAF00102802A9
+:100F800081DEBB0010280184E002F577AB00025E31
+:100F900002F0112A03BFDE02F0103D0183E0022BB4
+:100FA000915C020701AB00102C0180E00209D04ED9
+:100FB00001BC600318517800B045E30018000180BF
+:100FC00060022F317900E844655737A1006D5E85D6
+:100FD00055B03D028101AB001035020081AB00101D
+:100FE0003702842C370010370280AC3700103701ED
+:100FF0008360022B915C03BFDE02F0103D01836031
+:10100000022B915C00025E02F00EEB02835EB700E1
+:10101000103D0184E006F577AB00E02B47002AD1B4
+:1010200003BFDE02F011120002DE02F000000184B4
+:10103000E002F5B7AD01836002F5D7AE0182E002B0
+:10104000F5D7AE0182E002F7F7BF0184E002F7F7BF
+:10105000BF01BC6003000ADB01BC6003000AD001D1
+:10106000BC6003000AC801876001606B030002DEF8
+:1010700002F00000020200BF0010740283DEFF00D5
+:1010800010830183E006F7F7BF01BC600302115D26
+:1010900000B02AB700115E018560060B705B018508
+:1010A00060060BF05F0280456B001055018B6002FB
+:1010B0002B915C01BC600318517800B045E3001827
+:1010C00000018060022F31790188600E2B515A0097
+:1010D000682ADB00105801846006F7F7BF01BC6086
+:1010E00003000AB600025E02F0103E00E8446960A8
+:1010F000D7A1006EDE8700306200B02BF7000AF83F
+:1011000001BC6003000AF700682B0B00106200B0FE
+:101110004467000AC100E84465564AC200B02AD3B9
+:101120000017A100E82B0AF42AC2028080BF001039
+:10113000680281DEBB00106F0200456F001068027C
+:1011400083C57300106801BC63FF1FF7A10068C569
+:1011500086F4306F018B600E2B915C01BC6003182C
+:10116000517800B045E3001800018B2B4E2F3179E8
+:101170000183E002F5B7AD0184E002F577AB03BF70
+:10118000DE02F0111D018360022B915C00025E0201
+:10119000F00EEB0183E006F5B7AD0184E006F577CC
+:1011A000AB03BFDE02F0111D018D60020BF05F0189
+:1011B00088600E2B515A028181AB00107C018B603C
+:1011C000062B915C01BC600318517800B045E30028
+:1011D0001800018060022F317903BFDE02F0108019
+:1011E000018B60022B915C01BC600318517800B048
+:1011F00045E3001800018060022F31790183E0028D
+:10120000F5B7AD0184E002F577AB00025E02F010A5
+:101210003E0002DE02F0000000B0446B000B06024C
+:1012200002DEB3001088018360062B915C00025E31
+:1012300002F00EE0020200BF0010960183E002F708
+:10124000F7BF0203C573001091020080BF00109128
+:10125000018B600E2B915C01BC600318517800B0CB
+:1012600045E3001800018B2B4E2F317903BFDE02BE
+:10127000F01095018B60022B915C01BC600318514A
+:101280007800B045E3001800018060022F31790139
+:1012900082E002F597AC0002DE02F0000001BC60C3
+:1012A0000300701001BC63FF1FF0C501BC63FF1F8A
+:1012B000F0CB00B040470010E500B040470010EB15
+:1012C00001BC600300901001BC63FF1FF0C601BCAD
+:1012D00063FF1FF0CC00B040470010E600B040476D
+:1012E0000010EC01BC600300B01001BC63FF1FF0F4
+:1012F000C701BC63FF1FF0CD00B040470010E700FE
+:10130000B040470010ED01BC600300101000B04079
+:101310004300180001BC63FF1FF0C800B040470045
+:1013200010E801BC600300301000B040430018001A
+:1013300001BC63FF1FF0C900B040470010E901BCC9
+:10134000600300501000B0404300180001BC63FF70
+:101350001FF0CA00B040470010EA0002DE02F000B1
+:101360000001BC60030037A20020E3FE0910F10079
+:1013700020E0420D90F1028042030010F10284450A
+:10138000230010F103915E02F010F10068AB6F00D2
+:1013900010F10282DEFF0010F102805EFF001126D4
+:1013A000020180C700111D0282DEB30010F10204A9
+:1013B00080C70010DE00685E8B0010CA00B02BA34F
+:1013C0000017A1006EAB8AF430CA0203C573001087
+:1013D000DE00682ABB0010C900682ADB0010CA00C2
+:1013E000E8446556D7A100E82ABAF437A1006ADEBE
+:1013F0008555F0DE006ADE855B50DE00682B070055
+:1014000010DE0203DE530010CD00B02BA7000AAFA0
+:1014100003BFDE02F0111D01BC600302579201BC44
+:1014200063FF1FF0C301BC60030910E301865E8AFD
+:101430001C70E3018460061C70E300682B0F001031
+:10144000D40185E0061C70E301BC600303978200B1
+:10145000025E02F010FB01BC63FF1FF0C400B05439
+:10146000130010E400E043915C30E400025E02F0FF
+:10147000109701BC60030010EE01BC63FF1FF0CEAB
+:1014800000E02B0F002AC303BFDE02F010EB028343
+:101490005EB70010F100025E02F000F100B05ECF16
+:1014A0000010E400682ABB0010E800B02AFB00101E
+:1014B000E40280456F0010E800E8446556D7A100BB
+:1014C000E82ABAF437A100695E870010E800E05E00
+:1014D0008557D0E401BC600301D78200025E02F0B0
+:1014E00010FB03BFDE02F010EB00B00047001086D7
+:1014F00000025E02F0119500025E02F00CF701900E
+:10150000600A09104801846006F597AC01BC61339C
+:101510000070800002DE02F0000002805EFF00101A
+:10152000F60281DEBB0010F6020180C700111D0229
+:101530000480C700111D01806002F7F7BF0280C25E
+:101540008F00111E0201DEBB00111E01BC600300F2
+:1015500017A203BFDE02F010B401BC63FF1FF0C08E
+:1015600001BC63FF1FF0C10285DEFF00110B0068A4
+:101570005E4B06310400B02B570017A1006DAB0E77
+:10158000F4310B01BC600301378000B02B5B001706
+:10159000A1006D2B0EF4310602812BF30011060120
+:1015A000BC600301778001BC600300378100025EEC
+:1015B00002F000CC01D2DE0AA030E000B0540B00F3
+:1015C00010E103BFDE02F011110280ABF300110441
+:1015D00001BC600301578001BC6003001781000259
+:1015E0005E02F000CC00B054070010E000885E0BF3
+:1015F0000070E10002DE02F0000000682B13001111
+:101600001D0204DEAF00111D00E844655897A400D8
+:101610006E5E9155F11D00885E930037A4006D5EEB
+:101620009155F11D00025E02F0115303BFDE02F07E
+:10163000112A00E844655897A400885E930037A4F7
+:1016400000025E02F0115303BFDE02F0112A028491
+:10165000DEAF0011210181E002F5D7AE03BFDE024B
+:10166000F0112A00682B8700112600E044655C2AEF
+:10167000DB00682B8B00112500E044655B4ADB0032
+:1016800002DE02F0000001806006F7F7BF00682B61
+:101690001300112A00E844655897A400025E02F086
+:1016A000115301846002F597AC01BC6003000AC4C9
+:1016B00001BC6003000ADB01BC6003000AC3010433
+:1016C000DEAF0017A101835E86F5B7AD0284DEAF01
+:1016D000001133018060060D906C0002DE02F00004
+:1016E00000028600C700113502025EFF00113B00B8
+:1016F000B02AAF0017A3020400C300113800B02ABB
+:10170000CF0017A30202DEBB00113A00B02AAB00E3
+:1017100017A300E04466F46ABB00B04467000B0BFB
+:101720000183E0022B915C020701AB00113F0180B5
+:10173000E00209D04E01BC600318517800B045E3C7
+:10174000001800018060022F31790002DE02F000F3
+:10175000000202DEB3001146018360062B915C009B
+:10176000025E02F00EE00203C57300114B0284DE3C
+:10177000AF00114B0281DEBB00114B02805EFF0007
+:10178000114B02035EB7001152018B600E2B915C6E
+:1017900001BC600318517800B045E3001800018BCC
+:1017A0002B4E2F317901836006F5B7AD0184E0023D
+:1017B000F577AB01BC6003000AC30002DE02F00053
+:1017C0000000682B7B00115500B02B7B0017A40094
+:1017D0006D5E9156515700B02ACB0017A400882B9C
+:1017E000270037A500E82B2AF4AACA00885E9300D8
+:1017F00037A400E02B2AF48ACA00902B2B00AAC938
+:1018000000B02B27000AAF0002DE02F000000286C3
+:10181000410700115E01BC60130917A100025E02BE
+:10182000F000BF018760060337A200025E02F000ED
+:10183000C500B05E870017A100B05E870017A10049
+:10184000B05E870017A101876002F457A200025E14
+:1018500002F000C501BC60130957A100025E02F04E
+:1018600000BF018060060337A200025E02F000C5DF
+:1018700000E002B30020AC01806002F457A2000235
+:101880005E02F000C501BC60270857A100025E029D
+:10189000F000BF0068C06701F17601BC600300176B
+:1018A000A200025E02F000C501BC600301F7A200C5
+:1018B000025E02F000C50002DE02F0000003905E4E
+:1018C00002F0118A03875E02F0118A0390DE02F0B3
+:1018D000118A020445230011810283C21F00118A6C
+:1018E0000068A0B700117E00B0446700082D00E832
+:1018F000446505B7A1006E5E877D118503BFDE02DA
+:10190000F0118B0286C03700118A00E0446700D7CF
+:10191000A10206403700118A006CC466F4318300CE
+:10192000025E02F00B1900025E02F0115E01BC6063
+:101930000300082D00025E02F00ADC03BFDE02F0A5
+:10194000000201BC600300082D0002DE02F000006E
+:101950000280420300119402854523001193028501
+:10196000DEB70011910185E006F5B7AD00E0446BEC
+:10197000002B21006CC46964319400025E02F011F6
+:101980005E0185E002F5B7AD0002DE02F000000165
+:101990000C81430017A101BC600300508A00685EFF
+:1019A0000700119900685E8700119900685E0700C2
+:1019B00011A10190422AA1308A00685E070031A17E
+:1019C0000190422AA0108A0109DE030017A2018FAC
+:1019D0005E8A11508A00685E8B0011A10191E00EB1
+:1019E00011508A0002DE02F000000109DE03001738
+:1019F000A400E05A06F497A500905E96F497A5021D
+:101A000003DE030011A90282DE030011A901BC61FB
+:101A1000EF0857A60080DE96F4D7A50116DE8700F2
+:101A200017A300885E870077A100E15E8702D7A137
+:101A300000E0DE8F0017A301BC60030017A2020EB6
+:101A40005E030011B001BC60030037A200905E96F7
+:101A5000F457A50080DE96F437A100E141B7FFF707
+:101A6000A600E1DE8701F7A10080DE96F477A300EF
+:101A7000E1DE860DB7A100E0DE8F0017A3017A5EDC
+:101A800086F477A100885E86F457A100B05E8700D7
+:101A900017A20287DE030011BD00885E870057A1F0
+:101AA00003BFDE02F011CA02875E030011C401BC4D
+:101AB000639B0CD7A50080DE86F4B7A100E141B797
+:101AC000FFF7A500E0DE870017A100885E870057BA
+:101AD000A103BFDE02F011CA00885E870057A10192
+:101AE000BC639B0CF7A50080DE86F4B7A101BC6245
+:101AF000030017A500E141B6F4B7A500E0DE8700BA
+:101B000017A100E05E8400D7A10002DE02F0000011
+:101B10000200200F0000020282DE530011D2018871
+:101B2000600204902400E020AEF3082B00E820AA15
+:101B3000F3082A03BFDE02F0098A01B86016049098
+:101B40002401BC600301D02503055E02F011E4020C
+:101B500087C037000A8A0386DE02F00A8B00025E25
+:101B600002F00EFF00025E02F01177035CDE02F06D
+:101B700011D400D8409B0117A100E05E870237987E
+:101B800000A85E630077980102DE530017A101826E
+:101B9000E002F297940188DE85006803006EA0AA37
+:101BA000F311E400E85E6301D02501B860060490FB
+:101BB0002403BFDE02F0000201816005006803011A
+:101BC000B8600A04902403BFDE02F0000202285E1F
+:101BD000870011FA00B041930017A400E041930080
+:101BE0007064010A5E870017A200E84192F4506316
+:101BF00001185E870017A100E86042F437A2008850
+:101C00005602F436000068418EF491F600E8418FE8
+:101C100000306300E8419300306400685E8B02117D
+:101C2000EE00905602F457A300B05806F476010374
+:101C3000BFDE02F011EE00684192F491FA00E84133
+:101C40009300306401BC600300160003BFDE02F0A5
+:101C500011F600B05E870017A10002DE02F000005E
+:101C60000180600286143000B050CB00106501384E
+:101C700050830017A10068DE3B06320200E05A33B1
+:101C800000368C006EDA32F4200200B05A0B0017D6
+:101C9000A200E001F700207D00E001D2F4407401D1
+:101CA000BC63FF1FF7A300B050CF001064006EDAD2
+:101CB00032F4320900B05A370017A300B0581300AD
+:101CC000178201BC600300160401BC601B09D7B673
+:101CD0000102D0C70017A100E04196F4306500E092
+:101CE00050CB00D06401BC60030017B401BC60039A
+:101CF00000178001BC600300378101876004031076
+:101D0000A0009052330097A400E0418701B7B500CE
+:101D1000685ED2F0523000E05EDAF690630020D8C0
+:101D200002F03224020250C700122A00905603002B
+:101D300097A100E85E86F497A1019E6002F437A1A6
+:101D4000006DDE8708122A010A5E870017A201DAF9
+:101D50006002F437A100E05ED6F4506300886006AC
+:101D6000F437A100205602F4322A00B05802F036AF
+:101D70000000E05A2B00368A006ADED2F472260098
+:101D800068DED2F0122B00E05E0300378000685E50
+:101D90000300322B0186E0040310A003BFDE02F033
+:101DA000122B006ADED2F4722600E05ED30037B454
+:101DB00000D05E0700378102985ED300121500E064
+:101DC000419300306403BFDE02F0121500685E0329
+:101DD00000000203BFDE02F005CA0282D0C7001273
+:101DE0003A00B02A4F0017A101B82A4AF4368401FC
+:101DF000025013001685013C50830017A100B0501B
+:101E0000A70017A4006D5A32F432430182E006861F
+:101E100034310288502B00123F00B05A330017A112
+:101E2000019E5E8684F427018360068634310002B9
+:101E3000DE02F0000000B050730017A101B8506E30
+:101E4000F436840106D00700168500B050AB0017A9
+:101E5000A400D06006C0978000E0419700D7B5018C
+:101E60000A58130017A100E05ED6F437B500B05849
+:101E70000F001063011656030017810068D8130085
+:101E80001258011400630017A10068DE8700124E8B
+:101E90000088013B01168003BFDE02F01253006888
+:101EA000DE8700725100A0013BE0168003BFDE0216
+:101EB000F0125300E05E8709706200885403011637
+:101EC0008000E85A0330168001BC600300168101CF
+:101ED000BC600300168201BC600300168303BFDEF2
+:101EE00002F0125D00E0418EC09063006EC18EC0B2
+:101EF000325D00E8418EC0306300E858030037A12E
+:101F000000E0418EF43063013850A30017A500684B
+:101F1000581303F2780068418EC05278006DDA0AD7
+:101F2000F4B278011656030017A10068DE86F0327D
+:101F300078015856030017A100E05E870DD7A20074
+:101F4000B05ED70010620020DE02A0126F00E05EDB
+:101F500086D037A300E05E8ED077A3006D5A02F4DE
+:101F60005278006E5E8EF4927800E86002F4368358
+:101F700000B05E8F00168100A05A0F00768300E04B
+:101F80005A0B00368200E85A02F4568000D05E03F5
+:101F900000378000E0581300360400E0418F003025
+:101FA000630298581300127500E05ED70037B50041
+:101FB0006EC18EC0325E00B0580300106303BFDEF6
+:101FC00002F0125E00B058130017A10068DA370063
+:101FD000127B00B05E8700168D006DDE86D1B27D6B
+:101FE00000B05E8700168D0002DE02F0000001BC2A
+:101FF00060030017A1018760040310A001BC600307
+:102000000990B500B0006300F0B401BC60570490C3
+:10201000B601BC60030090B500B0006300B0B4002E
+:10202000B042D30018000317DE02F012860397DED9
+:1020300002F0128700B02A4B00142F018EE00C032F
+:1020400010A0006DDE02D1B28D00E85A36F0168D78
+:1020500003BFDE02F0128F01BC600300168C01BCCE
+:10206000600300168D006E5A3AF0129201BC6003B4
+:1020700000168E03BFDE02F0129300E85A3AF01603
+:102080008E00B058070017A100E0580EF0160300AC
+:102090006ED80EF4329900E85E86C017A100E858A9
+:1020A0000EF4360300E8580F00360301185E0300F3
+:1020B00017A1006DDE030212A100E86042F437A20E
+:1020C00000905A1AF4368600885A1EF457A20090DF
+:1020D0005A1EF4368700B05A1AF4568603BFDE0241
+:1020E000F012A300905A1EF4368601BC600300165D
+:1020F000870002DE02F000000158600300102A0190
+:10210000B8600A04902401BC60030290040189E0D5
+:10211000020D906C0002DE02F000000200DE5300AF
+:1021200012CE01BC601309B7A100025E02F000BF2D
+:1021300001A560020337A20199E002F457A2000250
+:102140005E02F000C501BC60130997A100025E02A7
+:10215000F000BF01A4607E0337A20199E03EF4576E
+:10216000A200025E02F000C501BC601316F7A100D8
+:10217000025E02F000BF01B460020337A200025EFB
+:1021800002F000C501BC60131637A100025E02F028
+:1021900000BF0186E0020337A201856002F457A266
+:1021A00000025E02F000C501BC60131617A1000218
+:1021B0005E02F000BF0181E0060337A20185E00660
+:1021C000F457A201836006F457A200025E02F000F9
+:1021D000C501BC60131F57A100025E02F000BF01E1
+:1021E00081E0020337A2028600C70012C80181E025
+:1021F000060337A200025E02F000C501BC60131F97
+:1022000037A100025E02F000BF0181E0060337A2A1
+:1022100000025E02F000C50002DE02F0000001BC18
+:1022200060130997A100025E02F000BF01A46002E2
+:102230000337A20199E002F457A201886002F45723
+:10224000A200025E02F000C501BC60131617A100D7
+:10225000025E02F000BF0181E0020337A20185E0C7
+:1022600002F457A201836002F457A200025E02F05A
+:1022700000C5020600C70012DF01BC60131F37A1B2
+:1022800000025E02F000BF0181E0020337A20002FB
+:102290005E02F000C50002DE02F000000200DE5324
+:1022A0000012CE01BC601309B7A100025E02F0006B
+:1022B000BF018760020337A20181E002F457A20147
+:1022C000886006F457A200025E02F000C501BC60FF
+:1022D000130997A100025E02F000BF020400C700CC
+:1022E00012EC0188600E0337A203BFDE02F012EE8B
+:1022F000018660060337A20181E006F457A20002BE
+:102300005E02F000C503BFDE02F012C30068DE9378
+:102310000012F400E05E030057A201095E8B001773
+:10232000A103BFDE02F012FC0068DE930032F80168
+:10233000105E030017A200E05E8B0097A103BFDED2
+:1023400002F012FC01305E030017A200E05E8B0178
+:1023500097A1006D5E870592FC01BC60030597A103
+:102360000002DE02F000000200456F001308028741
+:102370002C0F00130801BC60130217A100025E02BB
+:10238000F000BF0200C0670013080287AC0F001303
+:102390000501084067000B030187E005606B03013E
+:1023A0008860060337A200025E02F000C501876064
+:1023B00005606B030002DE02F0000000682BEB00FA
+:1023C000130E00B02C130017A100E05E8560B7A1CA
+:1023D000006BDE8623330E0186E006F7F7BF0002AE
+:1023E000DE02F0000000B05E8F00106400B05E8777
+:1023F0000017A300B05E8B00106500B05A030017F1
+:10240000A10068419300131700025E02F000BF00B4
+:10241000B0406700160100E0419300506400B05ADC
+:10242000070017A200025E02F000C500E04197001D
+:10243000506500E85E8F0037A30068DE8F0013123E
+:102440000002DE02F0000000B05E8F00106400B0F9
+:102450005E870017A300B05E8B00106500B05A03C2
+:102460000017800068419300132500025E02F00D02
+:10247000A900B05E0700160100E04193005064001F
+:10248000B05A0700178100025E02F00DAE00E04175
+:102490009700506500E85E8F0037A30068DE8F006C
+:1024A00013200002DE02F00000020200BF0001ABB8
+:1024B0000203C5730001D400000000000000676241
+:1024C0004B17055AC31A14E12850005B234B2524EF
+:1024D0000A00B55A5C55D8F4A179397DBF0701BD12
+:1024E000320801002A756E6B6E6F776E2A2F736447
+:1024F000696F2D672D706F6F6C2D69647375702D0A
+:102500006964617574682D617073746120566572B9
+:1025100073696F6E3A20352E39302E3139352E32AF
+:1025200036204352433A20653862343964393820C2
+:10253000446174653A204D6F6E20323031322D3057
+:10254000382D31332031393A31323A323020435349
+:03255000546D00C7
+:00000001FF
diff --git a/firmware/ap6210/fw_bcm40181a2_p2p.bin.ihex b/firmware/ap6210/fw_bcm40181a2_p2p.bin.ihex
new file mode 100644
index 0000000..a8e3092
--- /dev/null
+++ b/firmware/ap6210/fw_bcm40181a2_p2p.bin.ihex
@@ -0,0 +1,13727 @@
+:100000000000000091EC000055EB000055EB0000F3
+:1000100055EB000055EB000055EB000055EB0000E0
+:1000200055EB000055EB000055EB000055EB0000D0
+:1000300055EB000055EB000055EB000055EB0000C0
+:1000400055EB000055EB000055EB000055EB0000B0
+:1000500055EB000055EB000055EB000055EB0000A0
+:1000600055EB000055EB000055EB000055EB000090
+:1000700055EB000055EB000055EB000055EB000080
+:100080000048004791EC0000000000000000000064
+:100090000000000000000000000000000000000060
+:1000A0000000000000000000000000000000000050
+:1000B0000000000000000000000000000000000040
+:1000C0000000000000000000000000000000000030
+:1000D0000000000000000000000000000000000020
+:1000E0000000000000000000000000000000000010
+:1000F0000000000000000000000000000000000000
+:10010000D11E8000B5228000BD248000491F8000E0
+:10011000F9218000A9160100F1208000D120800083
+:10012000594880006948800015648000E1628000C1
+:10013000296280003D6580008D628000C56280007C
+:10014000596380005D6580007D6380009D63800051
+:100150000D668000A961800061618000756080008B
+:1001600095608000DD6380009D65800029668000C9
+:10017000FD618000B96580001D618000F16580002F
+:100180009D6680006D658000916C8000CD6B800065
+:10019000316C80008D6B8000556C8000AD6A8000F2
+:1001A000C16A8000D56A8000496B80001D6A8000AA
+:1001B000FD6A8000AD688000C1698000D168800060
+:1001C000356B8000B16980004DF10000D166800080
+:1001D000E16780008D678000CD6780009D688000AA
+:1001E000ED678000BD678000A1678000ED6680003C
+:1001F00009678000616780004D4880001D488000CD
+:1002000085988000DD96800051948000B19B80002D
+:100210003994800005988000199880002D988000FE
+:10022000C59B8000D19A8000899D8000D193800079
+:10023000D9918000ED9A80002129000099170100D2
+:1002400079290000C1170100519B8000BD290000E1
+:1002500049A9800099988000F529000031A8800004
+:1002600005A7800021A28000BD938000DD9380005F
+:10027000199E80007D93800045988000E59B80005A
+:100280006DA68000C19C8000C59F8000A19D80005C
+:10029000F5988000851701005517010029AA8000F4
+:1002A000B9A9800075AA8000E1A9800039AA800060
+:1002B0008DAA80005DAA80000DAA8000C5A98000DB
+:1002C0009DA98000A90C8000850D8000C1068000DA
+:1002D00029088000694680004D468000D94480008E
+:1002E0004146800021448000F54380001544800091
+:1002F000E1438000E1428000854680007544800033
+:100300002D448000A9428000F9428000CD43800046
+:10031000B9458000F544800039458000090080001F
+:100320003D00800049018000D10480000D04800060
+:10033000910380004D038000E503800035038000B9
+:100340006503800029028000CD02800051028000F8
+:1003500085028000F5028000950680003906800045
+:100360008105800005068000FD048000690F800083
+:100370002516800015168000451380001513800097
+:100380002513800009138000351380000D1E8000A6
+:10039000F91D8000291D80001D1C8000391C800073
+:1003A0003116800059138000192C0200951380002B
+:1003B000B91C8000C5270000452D0200751D800076
+:1003C000A90F01003D1D80000D1B8000E910800079
+:1003D000790F8000A9168000311480002D11800053
+:1003E000A51E8000B11E8000BD1E8000692B80000C
+:1003F000AD28800011298000892B8000FD2B800012
+:10040000E128800065288000B52C8000912C8000B8
+:100410001D2B8000752D8000252C80004D30800024
+:10042000DD2D800059278000313180002118010026
+:100430008D268000C5268000E5248000FD268000F2
+:1004400021258000B12A80006525800025288000B4
+:100450006129800041298000D92980009D298000E0
+:1004600081298000893080004D2E8000B12B8000D2
+:10047000312C8000E12C8000613280002D32800020
+:10048000C93380004D368000693A8000B535800060
+:10049000F9348000A93480003D3380009D33800012
+:1004A000013480003536800031388000353A8000D4
+:1004B000213A8000AD3280000D338000DD328000B3
+:1004C000953A8000D937800099368000193780002E
+:1004D000593880004938800019398000313D80004A
+:1004E000D53A8000C93C8000E13B8000513D80004E
+:1004F000D93D8000AD3E8000593F80009941800089
+:1005000041478000CD5B8000895380002D4D8000E5
+:10051000A94C8000E14D8000E94F8000B14F800080
+:10052000C94E80008D4E8000F15180005D528000E8
+:10053000D15180002D52800001528000C94F8000AF
+:10054000594C80006D4C8000455B8000395680001E
+:10055000155A8000C9588000315A800081578000A8
+:10056000F95980001D568000AD55800091558000DE
+:100570004D5A80002D558000714B800071548000D1
+:1005800009548000F54D80001D4C8000F94B80001F
+:10059000094C8000114E800015588000C9110100DF
+:1005A0002D508000E5588000555680007D5A80000F
+:1005B000054F8000354E8000D9558000515880008D
+:1005C0009D57800059518000614D8000B1488000E6
+:1005D0005D5B800081528000494C80003515010030
+:1005E000F15B8000E55C8000E15F8000A55E80003B
+:1005F0007D5E80008D5C8000015C8000A15F8000DA
+:10060000895D800005608000395D8000D15E8000DA
+:10061000495E8000ED6C8000656D8000DD6D8000BE
+:100620000D6D8000296D8000896D8000F96C80005F
+:10063000D96C80003D6E8000616F8000756E800017
+:10064000056E8000A974800055758000D574800007
+:1006500005748000D17C8000457D8000757C800021
+:10066000117E8000897E8000E97E8000917D80007F
+:100670003D7E8000517F8000A581800065848000E0
+:10068000418480008D8380006583800035858000F3
+:10069000E58480009D848000218580007584800031
+:1006A000BD8380005D858000BD858000158F800042
+:1006B000918D8000D58980001986800019AB80005B
+:1006C0005DAC8000A1AA8000B5AB80005DAB80006E
+:1006D000FDB080007DB1800065B080006DAE80000F
+:1006E00085AE8000EDAD800041AF80001DAE800082
+:1006F00031B180003DB18000B9AE8000F5B180001D
+:1007000079B08000FDAD800009B180008DB080001F
+:1007100049B1800069B180004DAE80003DAE8000DF
+:1007200095AE800029B38000C9AE8000CDAF8000B7
+:10073000E5AF800025B080008DAF8000B5B28000AD
+:10074000FDB2800019B38000EDB080005DAE800086
+:100750002DAE800029B28000A9B08000A1B1800038
+:1007600005B2800039B28000A9AE80007DAF800064
+:10077000ADB38000A9BD80009DC1800025C7800069
+:10078000DDC8800065CA8000E1CB8000DDCE80003E
+:1007900019CE800099CE800015CF8000E52C000096
+:1007A0000DD88000DDD7800091D78000B110010006
+:1007B000CD2B000069D880007DCF800045D9800016
+:1007C000FD10010099D1800025110100F9E08000A1
+:1007D00071F58000152D0000D1DE80008D21010013
+:1007E00009EA8000A1E4800045200100E1EC8000DE
+:1007F00011E3800039EA800039E3800099E380004A
+:1008000029DF800005220100A120010075220100DE
+:10081000352301007D230100BDEB8000952D0000F4
+:10082000152E00001922010091220100CD210100A6
+:10083000E1E18000A9E980007D210100F9200100AB
+:10084000EDF58000D90081009DF68000C5F780009D
+:1008500085FF800045018100D50281004D038100A4
+:10086000E50081007DF6800081F78000D5F58000ED
+:1008700051F9800031FB8000F1F68000F9F580002D
+:1008800041FF8000D9F98000DDFC8000A9F78000DD
+:10089000C12E000059FB80008DF78000A5F9800073
+:1008A0008DF9800029F68000A1F880005DF78000B6
+:1008B00065F6800095FD8000912F0000F502810013
+:1008C0002D0281008901810005018100A93000000D
+:1008D00099FF800019F7800089F68000C1F680003A
+:1008E0008D10010085F5800005F78000DDF68000A1
+:1008F000B1F68000AD6A8100BD6A8100DD2F810004
+:10090000E1578100F56D8200A98D820009258200E2
+:10091000196E820001AA81005D608200A537820005
+:10092000ED69810079598200E55882001D598200E5
+:10093000FD6D8100493A810041BC8200E95A820084
+:10094000CD608100D59681001D6181002961810003
+:1009500089BF81001DAB810069320000893200002F
+:10096000D132000005A6810021AD82002958810006
+:10097000BD3E8100A540810035958100599B8100D5
+:100980003D3682001D4582000928810099A0810022
+:10099000D1288100E93B81008D288100416E8200D1
+:1009A000859B8100295D81006D398200FD398200BF
+:1009B000253A820095698100C97A810091578100AA
+:1009C0005D57810075308200852F82003557810088
+:1009D000D12F82002157810049578100F5288100DD
+:1009E00095A882002DA2820089D38100D56B810059
+:1009F0005959810075598100F55A820005AD810071
+:100A0000F1D2810039378100ED718100C5968100F6
+:100A10008957820091618200CD618200A9588100CE
+:100A20001D2782004543820001448200156A81002F
+:100A3000614A8100ED4E810071228200055A8100D9
+:100A40004D8A81007549810071248200B14981007D
+:100A5000B144810075AC8200292B8200595281007B
+:100A6000E12A8200B529820071A7810035A78100A3
+:100A700001D48100F5BE810055B48100D16A8200A5
+:100A8000D19C81009D9C8100959B8100B59D81003A
+:100A9000459D8100C59D81006170820009358100FE
+:100AA000A1AB82008DAB820075AB8200F193810017
+:100AB0009968810015D7810071C182007D2B81006A
+:100AC000E92F81000DB6810025BD82008D4F810088
+:100AD0000D5081008543820031D78100B1BD820075
+:100AE00095C182005DB38200B90D01008DD18100F6
+:100AF000A9368100E9BC820029378100E9368100EE
+:100B0000A1D68100A53B81006DAB810041B0810081
+:100B100045AE8100DDB1810041BD820095BE8200FD
+:100B2000CD2E82009D6B8100CD458200453981002C
+:100B3000353B8100BD3A8100F1D58100419F8100A4
+:100B4000119F810071A48200ADD58100C130810068
+:100B5000A13982004D618100995B8100A5728100FD
+:100B600089DA810061BF81006157820081218200A2
+:100B7000A9218200D1AD820009BC8200B5A181000B
+:100B80009DCA8100B92F8200D9BB8200113082003A
+:100B90007DAD8200CDA4810099A48100CDAB8200FF
+:100BA00015AB8200C1AA8200B998810081A581009D
+:100BB000D9D08100A9CF8100E93B8200EDCF81002F
+:100BC00065D1810079D1810051D0810065D081004B
+:100BD000E521820011228200D1340000B9480000D2
+:100BE000FD9C81009145820055AE820041B4810098
+:100BF00095BD8100F18A8200098B820079D981003C
+:100C00007D618200CDA4820041918100A13F8200DC
+:100C10003594820049948200898982005DC18200F6
+:100C2000F1C18200D13B8200D5958200E560810050
+:100C300009208200E5170100BD3B820075A18200FA
+:100C400025A58200253B8200E93A8200753A8200A0
+:100C5000F1308200B130820071D781004599820065
+:100C600091D7810089948200DDC18200A96A820047
+:100C7000256B8200C944810029458100596B8100A0
+:100C800059498100EDAA810069618200AD2482008A
+:100C900005368100D535810079D08100A5D081004D
+:100CA000715C8100E1AD8100EDD0810049C9810016
+:100CB0004DD88100893D82004920820065968200DE
+:100CC000F925820089CF8100856A82001593820010
+:100CD0002D5D8200E9CA81006D4082006130820092
+:100CE00015488200313C810061D68100114E81009F
+:100CF0000129810041A1810015A681000999820086
+:100D0000E5C98100B1D7810035C08200294A810040
+:100D100041AD8100EDBE82002DBE820005BE820085
+:100D200079BE820055328100A5958100B1598100BC
+:100D3000E54781009152810015638100956481002F
+:100D40008D668100592C8100392C8100212E810073
+:100D500065358200D5578200352B8200996082006C
+:100D6000016182001D4082001D2082001DD881008B
+:100D7000A9AC8200F1AB8200F52B820041AE82006B
+:100D800011120100356A810009AE8200696D82008E
+:100D9000098C8100D58B8100116F810081908100C9
+:100DA000296C8200DDA18100E92B8100552F820092
+:100DB000398C8100A55A8200355C820045BB8200D7
+:100DC00091BE81002D6E8100115C8200258A810018
+:100DD0004D93810089388200D5378200555A8100B1
+:100DE000013882008D038100E9208200E13E82000B
+:100DF000914581002D6D81000D58820021478200B0
+:100E0000FDCE810011CA81005936820051CB81008C
+:100E100025CB8100912E81002D2F8100B93A8200CF
+:100E2000A10D0100DDA9810031D48100D1B3820080
+:100E3000ADA98100D53882008DD88100555E820031
+:100E4000719A81001541820035DA810019258200EE
+:100E50006926820035358100D90D01003D71810080
+:100E6000012D810009A282000D238200FD71810005
+:100E7000D960820051728100416182004528810061
+:100E8000C12382008D6C81006D2382009547810013
+:100E9000B9D98100B534810075C98100F134810070
+:100EA0002DBF810059AF8200D93C8100494F81009C
+:100EB000E5AB8100F51501007931810005958200CF
+:100EC0006D638200DD938200A56682000DC88100FB
+:100ED000095E81007D758100156281009159810054
+:100EE000D575810011498100C1488100B9BF8100D9
+:100EF000A5458200F5598200F1A9820041A6820031
+:100F000039588200BD428200BDA782004D22820076
+:100F100071A78200A5A78200E15C8100ED418200FB
+:100F2000D1A78200D1688100B5CC810015AF8200C5
+:100F300095418100E1C8810089AA8100E99681007C
+:100F40007D2F810081470000494282005944820080
+:100F5000F90D010031318200614982004D49820062
+:100F60000DA58100095E8200253E8200CDCD810065
+:100F700029B382002151810045B18200A91D820060
+:100F800079BC8200D1568100599D8100999D8100D4
+:100F9000191C8200513F82001D308100C9BD8100B3
+:100FA00015388100794A8100DD9B8100199E8100FE
+:100FB00069618100896E8100B5708100D132820043
+:100FC000F1578100A93382009D5A81003D3582008E
+:100FD00089338200D96E810045708100FD618100F6
+:100FE000594B81000D9C8100558B8200F18E82004F
+:100FF000E59A8100BD35820049368100291F8200B3
+:10100000655C820009150100516F8100299B8100F8
+:10101000A56D8100B5A28200E1AF8200A9568200D1
+:10102000894481003D578200E16F8200016F820098
+:10103000DD728200E53E810095518100FDD4810082
+:10104000F5BC810081B48100F199810019318100E2
+:10105000358A8200DDDA8100413D81002D3E81002C
+:10106000E9898200C1D48100FD8D820099B681009A
+:10107000BDA781003D9F82005D0381006D928200CB
+:10108000218B8200599A8100ED278100ED94820026
+:10109000FD8A81009D8A8100416B8100E16F8100A2
+:1010A0005D468200A19482009D898200C9928200DF
+:1010B00079998100B1908200219182001D348100D4
+:1010C00099B28200DD6A82008DC9810059278200B1
+:1010D00021120100D9908100A56B82006D3C820035
+:1010E000E56D820005C28200C96A8100ED4582007B
+:1010F000816B8100353F8200FD90820071BC8100D0
+:10110000F16B81003D4E8200514A82003DA2810078
+:10111000190E010079738200B97E8200698882000D
+:10112000695A8200DD2E810015138200117381003F
+:10113000698082009D9181005D8B8100816C8200BD
+:101140008D8F81004D8F810009888100BD6D8200E7
+:10115000018E81001D5E820091718100C127810096
+:10116000797582002DBE81002D5B8200E9A5820089
+:10117000B5728200255B0000217D82004D808200D7
+:101180008D7F820001A08100ED7F82002D418100D2
+:10119000F98481006185820045728200F9548100E2
+:1011A000692B820069518100C5558100315681004B
+:1011B000A1A6810071508100392A8200615381000B
+:1011C000C573810035620000F1978100A99B810001
+:1011D000FD3B820025A08200DD398100715D810028
+:1011E000BD1401004995810009CC810021A3820032
+:1011F00045AA8100AD818200916782002962820048
+:101200007D708200E12F8200E97D000081DB81009A
+:10121000952482006989820089C38200C5C4820046
+:1012200039180100B1EB820009CB82000DCC82009D
+:1012300059EB820061E9820015F18200E9CD82005C
+:1012400045DF820009F182008DF782008DCA82009D
+:1012500089F38200D5CA8200A1098300C9F7820000
+:10126000FDEF820099F8820025F9820039FA8200A8
+:1012700089ED8200ADE08200ADE5820065DA820092
+:101280007DC582002DE6820065EE820031E4820099
+:10129000E5F182009DC8820055F3820075150100BA
+:1012A00061C78200CDE182006DE18200A5E282008B
+:1012B00059DF820029F4820009C7820055EF8200BD
+:1012C000E9EC8200E9DB8200BDDD8200E1C582003D
+:1012D0004DE5820005E08200A5F982000DC582007F
+:1012E00089F48200ADA1000085A2000091E6820091
+:1012F000BDCC8200FDE982008DD182002DF18200FB
+:101300002DF7820095FB820069CE8200A1F0820059
+:10131000D5F08200F5CC820035A3000081D982008F
+:1013200045C58200FDCB820025CB8200BDEB82004B
+:101330001DDB820015CD820019E78200CDE6820018
+:101340004DCF82009DCB8200450C8300E50D8300CC
+:10135000590E8300410E8300010B83004D0A830068
+:10136000D10D8300310C8300590C8300710A830076
+:10137000650E8300F10D8300410B8300A11E8300E5
+:10138000B11E8300012B8300F54E8300112B8300D7
+:10139000B127830099238300014A8300ED4983002C
+:1013A000FD478300CD4C8300BD4C8300714C83000E
+:1013B000D52783004D25830095258300E14C8300CC
+:1013C000414C83000912010065118300E144830050
+:1013D00021288300BD2883007929830065288300A4
+:1013E000652B830041458300D5298300491D830077
+:1013F000A12A83005D30830051488300E5488300C3
+:1014000029488300F5238300114A8300793483003F
+:1014100091188300A5338300ED3483001D118300F0
+:101420009D4E8300954D8300B51A8300614783006C
+:101430001D4D8300ED1083000D458300C11E830008
+:1014400001208300E9218300F1258300F91D830039
+:10145000F513010059B3000049108300C10F830048
+:1014600021248300A5248300B94A8300B52F83007B
+:10147000C1458300FD1C8300711D8300F5188300A6
+:1014800059198300F1198300190F0100492A8300BB
+:1014900011B40000B957830029578300654F8300BA
+:1014A00001608300E559830039518300F54F8300C3
+:1014B000555483001D5E83002152830065598300CB
+:1014C00079508300714F8300095983003D63830085
+:1014D000C5578300815C8300B15B8300DD538300CB
+:1014E000115383009D4F830029508300254F8300B3
+:1014F000D5588300CD62830039608300F95C830096
+:101500004D6183005D5F83002D548300DD508300B7
+:1015100039578300A555830091638300A16283003E
+:10152000C15D83002D5E8300455F8300A151830070
+:101530004D5E8300195B83006D5A8300A9568300BA
+:10154000A5508300095783000D748300DD63830079
+:10155000297A830001668300B9B28300D5A783008E
+:101560007D848300819383005DB38300A193830016
+:10157000E9938300E10E010071BA0000B1BA0000E6
+:10158000717A83005D67830051668300CD708300AC
+:1015900055718300DD7483008DAA830051A88300F8
+:1015A000A9B183009D918300D184830039BB0000E1
+:1015B00061848300AD77830081818300158283007D
+:1015C000B1808300E5B583006D7E8300B57983002B
+:1015D0002DBC0000916E8300758F830055878300BA
+:1015E0002913010015C1000025678300C18883000D
+:1015F000D98F8300F5AC8300E97783009D6D83006C
+:10160000A1A78300FD998300C9A4830051C40000F1
+:10161000558B8300E58A8300CD6A8300F5868300BD
+:10162000596A8300B9AA83001566830051B283000A
+:101630009DB38300D9B6830059B1830091828300A2
+:10164000D5B0830081868300C97A83000585830035
+:10165000797C83008965830055A58300C9AF830029
+:101660008D1501007999830091898300C5B58300A8
+:101670000DB8830099D483002DC083009DC28300E0
+:10168000ADC38300A1C68300B1C68300C5C2830079
+:10169000A9D0830055BF8300F9CF830029BF830001
+:1016A000C5E18300C1C0830095C083004DD883008D
+:1016B0000DD7830015D88300F1D7830079BD83004F
+:1016C000A1E1830035C28300C5E08300DDE0830033
+:1016D000C5DC830099DA830001DA83004DB883000A
+:1016E00075C0830019C28300F9C983003DD6830009
+:1016F00015BE8300C9D683005DBA830029D6830056
+:1017000031B9830035BC83009DD883005DDC830044
+:1017100029C18300A9C28300E5C0830025DB8300C3
+:1017200075C283001DD083005DBC830061C6830049
+:10173000D5C2830005BC830001C98300B5C88300FE
+:10174000EDC8830055D6830015D98300A5D1830049
+:10175000F1D5830001D9830081B8830089E083003B
+:10176000E1BC8300A5DB8300EDE1830071C1830050
+:10177000E9B783006DC783008DC183001DC8830056
+:10178000B5D1830071DC8300E1C18300A9C183006E
+:1017900019DC830039D883004DCB8300A5B78300C3
+:1017A00069CB83008DC98300C9D48300A5C500001F
+:1017B00099D68300E5DC83004DD483001DC38300EC
+:1017C00021DD830045D983007DD383003DD2830092
+:1017D00041DA8300CDD88300D9BF830095BD830053
+:1017E000EDBD830051C083002DB8830049BB830049
+:1017F00031BB8300CDDA8300D5D0830049CA830092
+:101800009DD5830081BF8300D5CF83003DC9830070
+:10181000DDD18300B9D7830025C78300D1C800007C
+:101820005DBE830021E18300F9E0830071B983008C
+:101830008DE1830025D9830049D78300DDDB830058
+:10184000A9B9830085BA83000917010059EB830009
+:10185000C5E7830041E2830025E283006DF5830044
+:1018600065EB830085F2830089F78300B1F2830082
+:10187000A9F58300AD008400E100840019FD830018
+:1018800035EE8300FDF38300D1D1000089FB830096
+:10189000B9FA830021F98300F1FA8300D9F88300B3
+:1018A000D9F9830031008400C5FE830049E7830035
+:1018B000050084004DFF83006DF3830059FE830013
+:1018C00001FE830025EB83000DEB830031018400D2
+:1018D00035FD830081EB830059FD830011F88300FF
+:1018E000FDF78300C5ED8300ADED8300A101840009
+:1018F000E9E78300B1F38300DDF2830025F3830081
+:10190000F9E68300E5E28300F9120100A5E983000E
+:101910008DF5830051EE830079F8830071E2830036
+:10192000F1E8830045E6830099F783006DEE8300BC
+:1019300041F48300B9EB830075E78300B1E88300CD
+:10194000BDD3000061F183000518010089EE83001A
+:10195000F5D40000FDE58300A9FD83000D1301000F
+:10196000B5FB8300F1F183002D108400E1158400A4
+:10197000B1198400C5158400D90F8400CD218400DD
+:10198000491E84004D1F8400E1128400ED0884008C
+:10199000F10184002D0F8400ED238400F51E8400E6
+:1019A000E520840049208400AD128400F11A8400EF
+:1019B000711F8400C9198400AD188400450B840090
+:1019C000910B84000D2484008D2384000D18840065
+:1019D000210684008D168400310384006909840087
+:1019E000FD158400E902840001028400A909840035
+:1019F0008D148400811E8400E10B8400751C84001A
+:101A0000AD0A840049108400712084000121840003
+:101A1000850A8400291D840045078400390C840050
+:101A200029198400551E840089038400E51D840063
+:101A30002125840049138400291A8400DD12010045
+:101A4000ED12840045068400010D84008943840062
+:101A50006D2A8400014D84001528840069288400C3
+:101A6000DD0B010009408400112C8400F92784005B
+:101A7000912D8400794C84008934840019338400CA
+:101A80006D2F8400C92D8400F12E84007D2E8400EA
+:101A900065258400DD348400FD2584001929840037
+:101AA000B5408400D944840079298400B92B84008E
+:101AB0003D45840095328400B9288400D1388400E3
+:101AC00031488400A93084006D2C8400994384003F
+:101AD000D13284006D338400FD2F84005D45840085
+:101AE00011348400B54A840075488400C5488400D8
+:101AF000B1278400314A8400D949840059328400D6
+:101B0000014C840039388400314D840055448400F0
+:101B1000D93D840055438400513C840091398400B0
+:101B20009536840091378400F5368400E1478400BF
+:101B300015478400CD4C8400F52B84002546840095
+:101B4000E53A8400C937840049428400292A840088
+:101B5000A53F840059268400952A8400452B8400E3
+:101B6000C95D8400C1230100A156840095568400FC
+:101B700019578400E956840005578400355F8400B6
+:101B80001D628400B557840065638400ED628400A3
+:101B900021638400BD628400194E8400B95384001F
+:101BA000B15D8400B5518400D55F8400F95584008F
+:101BB0006560840059538400E5538400E94D840036
+:101BC00049240100E15F8400212501005125010025
+:101BD000B55B840031568400A5638400CD60840029
+:101BE00091638400ED5084002D5E840031518400A7
+:101BF000155C840061548400F55E8400F15D84000E
+:101C0000352401007152840059588400815C84009D
+:101C1000715784002557840071588400AD568400A4
+:101C2000415984006D4F840029508400E1548400A0
+:101C3000BD6184006D61840005598400A56684003F
+:101C4000D9678400456684000D658400916784002F
+:101C5000B96384005D67840079678400F966840055
+:101C60002165840021678400C56684008D66840038
+:101C70006566840011688400516C8400AD6E840038
+:101C8000016E8400F97084004D7F84007D6C8400B7
+:101C90002D748400456A84000D7B840001120100CC
+:101CA000156E8400457A8400E56C8400456F8400DD
+:101CB000C17C8400297E8400756D8400956B84004E
+:101CC000B56D84007D7D84005D6B8400D56A8400E1
+:101CD000816A840085748400B1808400857E8400DC
+:101CE000CD7F84004981840069818400ED8984006E
+:101CF0006D8A8400FD8984008D8984009D8984001B
+:101D0000E9858400F982840025858400518A840055
+:101D100075858400958484008181840071838400AA
+:101D2000C18984005D898400D58984006D8984001F
+:101D30007D8984000D8A840009868400798C840062
+:101D40007D8A84000D8B8400499484008D928400E8
+:101D5000E98D84009D8B8400FD8C84007990840043
+:101D60000D8C8400458C8400E9A68400A5AD840018
+:101D700029968400C598840015C1840009A98400AF
+:101D800099C2840045B7840031C18400D1B8840071
+:101D90008D998400B99A840025AC8400D9BF840051
+:101DA000C9BE8400A196840025B18400519B8400A3
+:101DB000919884004D9784001D9784007DA684002F
+:101DC000D1B784002DAB84008595840019B08400C0
+:101DD000F5AD840029A98400C1A98400219F840055
+:101DE00025A28400B1AE8400C1AF8400D5A38400D5
+:101DF00075B7840041A28400E1BC84006DA8840012
+:101E0000BD9D840095B884005D95840075BE8400F6
+:101E100051B98400A9958400C5C18400599A8400F1
+:101E2000419684003DB884009DA88400E5A8840004
+:101E3000A59B8400F5A684003DAF8400159A84001C
+:101E4000F9988400EDA984006DB18400FDF0840050
+:101E500025DF840025ED8400E5D08400CDF18400E9
+:101E600009F2840035F2840055F28400CDF284003A
+:101E7000B1D38400F5D384002DD48400C1D4840070
+:101E8000A5048500F90585006D0585009904850088
+:101E90008D04850079D4840045E88400B1C58400B0
+:101EA00095DF840031DF840075E484001DE0840048
+:101EB000BDC9840005ED8400A500850091FB840068
+:101EC000F9ED840091EF84009DFB840081EA840099
+:101ED00079E28400E1E500006DE60000A1EB8400FA
+:101EE000D1E484009D028500F1E7000015CC840058
+:101EF0005DFB840081C5840015D5840099D68400DB
+:101F000035E78400B9DF840045F48400B9C7840054
+:101F100001DF84002D018500E1C7840025D1840004
+:101F2000B5E60000BDDD84004DF38400E1C9840006
+:101F300041E084002DCA84009DD4840091E7000014
+:101F4000D900850079CB840021FC8400B9E88400A5
+:101F5000B5D8840031FD8400BDFB84001D048500DC
+:101F60005D04850031ED8400450685005DEC84004C
+:101F700025C384001DF38400D9C684002DEC8400A1
+:101F8000F1C5840059E9840019C884005112010088
+:101F9000B100850049D3840001C98400E1D28400E6
+:101FA0008DCB8400DDEB840011F4840009FC8400F7
+:101FB000D9F3840069C38400A1C884002DEE840095
+:101FC00071D68400790185004112010025D8840072
+:101FD000DDF9840009F0840035F784008DE8000005
+:101FE000D9FC840015D78400DDD584001DDE840073
+:101FF00001E9000019F1840099F1840049F184009D
+:10200000BDE90000A1F48400F1D084003DCC84003F
+:1020100069D2840089E98400F51D0100C9D38400D8
+:102020008506850089078500E90685004D0785003E
+:102030001107850025078500710685009506850036
+:10204000BD06850075078500B10785009D078500E1
+:10205000A9068500D1068500FD06850039078500A3
+:10206000610785005D0685001509850079098500F1
+:10207000350A8500BD0985000D0A850091EA00003A
+:10208000711201004D0A8500A90985002509850006
+:10209000DD0A85006D0A850081088500C507850079
+:1020A0000D0B8500590F8500ED118500C9128500C3
+:1020B00021108500F90D8500D5118500511085008E
+:1020C000AD118500011185006D108500B1D10100B1
+:1020D000850F850085108500990D850011128500FA
+:1020E0000D22850041178500D917850075208500D0
+:1020F0007D2C8500352F8500B92285002D25850092
+:102100009D238500612F8500A5278500C92A8500AC
+:102110006D2985009D22850031228500A52485003A
+:10212000E1238500B12F8500BD2C85005914850061
+:10213000C9138500A11C8500452C8500A9178500C1
+:10214000B1208500311A8500FD178500291D850005
+:1021500021148500AD218500B5308500453185000D
+:1021600035278500D1318500C5148500BD2D85003A
+:102170002D23850059238500891485004D4685004F
+:102180006547850025368500514785003D46850019
+:102190008D3C8500514A8500994A85007547850028
+:1021A0001D478500553685005D468500D53B850079
+:1021B00049498500D53A8500E139850041398500D6
+:1021C000E53885000937850045358500C93C85001F
+:1021D000754B8500B9458500ED4885002146850091
+:1021E000213A8500A940850001328500F53285003D
+:1021F000FD378500894E8500DD508500ED50850056
+:102200005D57850009558500495085005D50850062
+:10221000D1528500F5528500E54E8500C9558500EF
+:1022200065568500C9508500094F850071D20100AF
+:102230009D5585000D538500A94C8500B957850033
+:10224000A55785000D518500FD5A8500D5518500A3
+:10225000A9518500B15285009D53850039558500EF
+:102260009D4E8500C95785006D578500954C8500AA
+:10227000095785008D4F8500DDD20100FD5985008D
+:10228000014D8500ED598500D9598500194C85000F
+:10229000756C8500816E8500516C8500295C850018
+:1022A000416E8500795E8500210F0100AD6E8500CD
+:1022B000B56C85006D6585001D5F8500196B850017
+:1022C0008579850071738500B58E8500E19585005F
+:1022D00001828500519085002D828500D190850076
+:1022E000FD908500BD9285006D8F8500CD928500A3
+:1022F00055968500C58E8500857285005D8D8500AB
+:1023000001838500C1918500257085000D918500B0
+:10231000C17685006971850041718500F97F85006E
+:1023200079708500F19385009D958500F574850091
+:10233000497485006D788500BD728500ED8A850041
+:10234000C98C850099918500597D8500BD718500F6
+:10235000758185000D818500A9798500217785002B
+:102360002193850089928500D194850095968500FA
+:1023700065838500D97385006582850021D30100BE
+:102380005975850021768500556F85006D9585000E
+:10239000E583850029848500AD8F8500F16E850079
+:1023A0009D2E010075280100292E0100A53601008F
+:1023B000F52D01001D2B0100992B0100A531010015
+:1023C0005D2B01002D2B0100252B0100613C01003C
+:1023D000692E010041370100952801007530010088
+:1023E000FD310100C52A0100D1280100C13F0100D3
+:1023F000CD280100C1400100F1420100DD2D0100A6
+:10240000DD2A01004D2E01009D32010091360100B0
+:10241000ED2D0100C5280100BD280100613001003B
+:1024200031340100253401005930010055330100D9
+:10243000813001008D320100152D0100F92B0100C2
+:10244000D1450100192D0100F92D0100012E0100D7
+:1024500089300100A53A0100F93A0100B12C0100D0
+:10246000D52D0100853501009DEB0000D9EB000062
+:1024700015EC000059EF00009DF40000E12C020073
+:1024800005F500000DF5000049F8000049F90000CD
+:10249000B1F9000009FB0000452F000011310000D8
+:1024A000493100006D31000079310000C931000070
+:1024B000D500010011020100D931000039330000BC
+:1024C00045340000710D0100F93500006D0D01006B
+:1024D000E54F00006D6B00005D750000B19E0000CF
+:1024E0005D0D0100610D0100690D0100650D010028
+:1024F000F5160100A9C60000450D0100410D0100BF
+:10250000310D0100390D0100D90B0100510D010001
+:102510004D0D0100550D0100590D01002D0D01005B
+:10252000350D01003D0D0100490D01004DD50000A4
+:1025300031D5000039D5000041D5000059D5000043
+:10254000FD0B0100190C0100390C0100F90B010011
+:10255000F50B0100350C0100150C0100110C0100F8
+:102560000D0C0100090C0100050C0100010C01001B
+:10257000890C0100950C0100C50C0100E50C01005F
+:10258000E90C0100FD0C0100F90C0100F50C010043
+:10259000F10C0100ED0C0100990D0100910D0100FD
+:1025A000890D01009D0D0100850D0100790D0100CF
+:1025B0008D0D0100750D01007D0D0100950D0100CF
+:1025C000010D010001000000200000001F000000BC
+:1025D00050000000020000000100000001000000A7
+:1025E000010000000000000061D401000A0708009B
+:1025F000B533020051FB80006D310000C12E000098
+:1026000000000000D1F980000000000029FB8000DC
+:1026100000000000000000009C1800409600FFFF32
+:10262000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA
+:10263000FFFFAAAA0300409600000000000000006F
+:10264000000000000000000000000000000000008A
+:10265000000000000000000000000000000000007A
+:10266000000000000000000000000000000000006A
+:10267000000000000000000000000000000000005A
+:10268000000000000000000000000000000000004A
+:10269000000000000000000000000000000000003A
+:1026A000000000000000000000000000000000002A
+:1026B000000000000000000000000000000000001A
+:1026C000000000000000000000000000000000000A
+:1026D00000000000000000000000000000000000FA
+:1026E00000000000000000000000000000000000EA
+:1026F00000000000000000000000000000000000DA
+:1027000000000000000000000000000000000000C9
+:1027100000000000000000000000000000000000B9
+:1027200000000000000000000000000000000000A9
+:102730000000000000000000000000000000000099
+:102740000000000000000000000000000000000089
+:102750000000000000000000000000000000000079
+:102760000000000000000000000000000000000069
+:102770000000000000000000000000000000000059
+:102780000000000000000000000000000000000049
+:102790000000000000000000000000000000000039
+:1027A0000000000000000000000000000000000029
+:1027B0000000000000000000000000000000000019
+:1027C000000000002DE97043994605460E469046EC
+:1027D00020F086FA436831469C69284642464B46BB
+:1027E000A047BDE87083C0462DE9F74F0029054694
+:1027F00092469B46009153DB438A828A514403FBF5
+:1028000002F399424CDA806808F038DB002101902D
+:10281000A86808F005DD4369044643F000434FF023
+:102820000008436124E000989BF8007008EB000664
+:102830004FF0000903E00136D04517D07F0817F0AC
+:10284000010F0CD0284621463246FEF3EDF630B19A
+:1028500063694FF0FF3023F00043636122E009F128
+:102860000109B9F1080F08F10108E4D10BF1010BDE
+:10287000D045D8DB6369A86823F000436361002179
+:1028800008F03EDCA868012108F03ADC2846214621
+:1028900020F0C2F9A868019908F0C2DC002001E02C
+:1028A0006FF01C00BDE8FE8F407C704713B500F050
+:1028B0008FD8024608B904460FE000240AE010460B
+:1028C00001A90022FFF344F7019A13782C2B08BFCB
+:1028D000013201341378002BF1D120461CBDC046D3
+:1028E000B0F8423070B50446C3B142F2197503E046
+:1028F0000A2003F031DF0A3D236B1B6913F070439C
+:1029000007D0B3F1005F04D0B3F1405F01D0092DCF
+:10291000EED1226B136823F01003136070BDC04624
+:1029200070B590F878310546FF2B1FD0104C406AE7
+:10293000E36E9847D4F89C30686A984701280BD812
+:1029400095F8141241B90B4628460A4A03F030DEC6
+:10295000012385F8143209E0054B686AD3F89C30EE
+:1029600095F805419847241885F8064170BDC04682
+:10297000E0A685003D98800010B5084671B191F839
+:102980000832012B0AD091F875313BB14B691A6AB4
+:10299000034B02EA03030BB10EF0FEFE10BDC0466E
+:1029A00000FC0101D0F8943110B59942044601D9D8
+:1029B000002002E00EF0F0FEE08D10BDD0F8801196
+:1029C00010B5044691B10223C068D4F8842108F000
+:1029D00005DB074B1B684BB9D4F88011D4F8842170
+:1029E000E06881EA0202023308F0F8DA10BDC0465E
+:1029F000AC2702002DE9F04190F817320446012B74
+:102A000077D00123002780F8173243E0A0683146D1
+:102A100000F082DBD4F8F0301B68984205D92846D4
+:102A20000021324600F00EDB42E02046FFF778FF3F
+:102A300035690023AB7194F8783131462B7294F8E4
+:102A4000063184F80731DBB26B72D4F8FC31606A6E
+:102A50000133C4F8FC316A79274BD20982F00102B4
+:102A60005B6A9847B0B9D4F8F8106B7900293CD06C
+:102A700013F00F0F39D06A782B7843EA02230F3313
+:102A80001B091A0A0A6918BF0023937194F8783158
+:102A900013722AE0D4F8F0301B68012B08D904F136
+:102AA00028052846002100F04FDA06460028ADD15F
+:102AB000002384F81732C4F8F8302FB16269043368
+:102AC0005364204607F03CDFE28DD4F8C8319A42C7
+:102AD00003D9206901F0C4DD0BE0D4F8CC319A426F
+:102AE00007D2206901F0AEDD03E00127C4F8F860E9
+:102AF000D0E7BDE8F081C046E0A685002DE9F041B1
+:102B00000746884616461D4642F2197403E00A201D
+:102B100003F022DE0A3C79690B6D002B02DA092CE6
+:102B2000F5D11FE0AB191B0243F00042069BB3F145
+:102B3000807F04D198F8003043F08073D21842F2BD
+:102B400019740A6503E00A2003F006DE0A3C7B697B
+:102B50001B6D002B02DA092CF5D103E0012088F867
+:102B6000003000E00020BDE8F081C0460022C36BC9
+:102B70000BB1013BC363531CDAB21030102AF6D1FB
+:102B80007047C0462DE9F041066805460F4670685B
+:102B90004FF4BC7104F09CD808B9044612E000213F
+:102BA0004FF4BC720446FFF34BF2D5F86031266057
+:102BB000C4F8603195F86431C4F8687184F8643100
+:102BC0006B6863602046BDE8F081C04603682DE96C
+:102BD000F74F012A14BF2A25322506460F465868AA
+:102BE0002946914604F0CCD8834640B93368013871
+:102BF0001B68D3F88C20136D013313656CE007F16B
+:102C00000E0A04695146042201A8FFF3B5F1019BA5
+:102C100006F1280803F47F421B0643EA02234AF622
+:102C2000FE12B2EB134F0BBF2C4907F108012046EF
+:102C300020460622FFF3A0F10622A01D4146FFF325
+:102C40009BF104F10C02B9F1000F0DD02B0A237394
+:102C500004F10E00557022490622FFF38DF108237E
+:102C600023750623637503E008232373062353703B
+:102C70006419A4F11C05394606222846FFF37CF1AD
+:102C8000002304F8163C023304F8153C41460622A2
+:102C900005F10800FFF370F107F11801042205F1B6
+:102CA0000E00FFF369F107F10801062205F1120099
+:102CB000FFF362F15146042205F11800FFF35CF1C5
+:102CC000D6F85C3130680133C6F85C315946D6F825
+:102CD000682125F067DA0120BDE8FE8F2C9E850073
+:102CE00014D2850010B50368D3F800481B6893F828
+:102CF000AB306BB1FFF73AFF08E0A16829B10120C2
+:102D000000F0CAF808B1FFF731FF2468002CF4D1B5
+:102D1000002010BD7047C046C3682DE9F04106464B
+:102D20000D4658683821174603F0D2DF044610B923
+:102D30006FF01A002BE000213822FFF381F101230C
+:102D4000294623606360A360062204F10C00FFF3B0
+:102D500013F16B8E05F10901A3742B7A04F11400B1
+:102D6000E3742A7AFFF308F16D8D3046A586E78675
+:102D70002146382221230BF013DE00B907E0F36867
+:102D800021465868382203F0B3DF4FF0FF30BDE82A
+:102D9000F081C04630B50C4690F8CF1091B0944603
+:102DA0009E460380194D91B94FF0FF330293039370
+:102DB000049305930D3300940191069107910891B6
+:102DC00009910A950B900C930D910E9115E04FF01F
+:102DD000FF33029303930493059300F1D00306930A
+:102DE0004BB2002207930C2300940192089209929F
+:102DF0000A950B900C930D920E927146044A63460D
+:102E0000C06824F079D811B030BDC046F920010067
+:102E10002C9E85001FB5836D0446012B17D1B0F899
+:102E2000583113F0010F12D1C36893F8703273B99F
+:102E300002AA01A903AB0FF0E5F9029A3AB12046C4
+:102E40000199039BFFF7A6FF08B90223A3651FBDE5
+:102E500010B579B1B0F8583143F00103A0F85831FA
+:102E6000836D022B15D1C3680C21D3F8680151F092
+:102E70009FDB0EE0B0F8583113F0010F09D023F0BA
+:102E80000103A0F85831836D1BB101238365FFF75F
+:102E9000C1FF002010BDC046012801D0002000E085
+:102EA0008868704710B50C4641B18B6823B9C06F74
+:102EB0000968FFF767FEA060A06800E0C06F10BD62
+:102EC0002DE9F0418C692369994202D100273E46E1
+:102ED00004E0CE6A0EB9374600E0376863681146F1
+:102EE000D86803F03BDFA36805461B6893F895306C
+:102EF0001BB1C38A43F08003C382636893F8AB308D
+:102F00008BB120463146FFF7CDFF60B129460AF06C
+:102F10003FD9022807D163682946D868012203F007
+:102F2000FFDE01200BE0204629460CF039DCA068CA
+:102F300029463A4625F036D9003818BF0120BDE8A9
+:102F4000F081C04637B5144605461146406FFFF77D
+:102F5000E1FE6368112B08D0122B01D0102B15D184
+:102F6000A37803F001032B7510E002AA002342F8B6
+:102F7000043DA86894F82F103CF080D930B18379D3
+:102F800023B96188C1F3800127F03AD93EBDC0461C
+:102F90002DE9F0470446084615460DF003FF80462C
+:102FA00010B9D4F8109001E0D0F80490A368D9F8D3
+:102FB00024701B682A6993F895303BB1EB8A13F4AF
+:102FC000006301D001262AE01E460AE0537B127BF3
+:102FD00043EA022348F66C02934214BF00260126FE
+:102FE000EEB9204629460CF0CDDB636893F8AB3090
+:102FF000ABB120464146FFF755FF80B1294609F0A5
+:10300000B9DF042801D0012804D163682946D868B3
+:10301000002244E0052802D14FF0010801E04FF002
+:103020000008636893F895301BB116B9AB8A2D334D
+:10303000AB82002F2FD0EEB9FB6913F0010F07D040
+:10304000637D2BB1204629460CF0A8DC024668B10E
+:10305000B8F1000F0ED1636893F8963053B1D4F8ED
+:10306000840029460EF004F9024618B9636829461F
+:10307000D86814E063682946D86803F0ABDE3B6982
+:103080000446DB68484639462246984748B1204600
+:1030900003F0DCDD05E063682946D8683A4603F0B2
+:1030A0003FDEBDE8F087C0464B6A10B591F843207B
+:1030B00043F480134B62D0F8883002F00702D21834
+:1030C00092F88030013382F88030D0F888200123D4
+:1030D00082F88630D0F8881091F8812091F87B3002
+:1030E0009A4211D291F8802091F87A309A420BD20C
+:1030F00091F8822091F87C309A4205D291F8832091
+:1031000091F87D309A4201D30DF0F0D8002010BD27
+:103110001FB5084B02460093074B08460193074B27
+:103120000749DB6902931268064BFFF3F5F105B01E
+:1031300000BDC046DDD60100A0D601000028020077
+:10314000AED60100D1D6010010B5436804461B7EFF
+:1031500053B1D0F880000CF049FDA06801F048FEA2
+:103160006268002382F8203010BDC04610B5806927
+:10317000FFF7EAFF002010BD70B504466368806861
+:103180001E7E0EB1002515E001F0F4FC054620B9C5
+:10319000D4F880000CF058FD05460CF0D5F86368B3
+:1031A000D3F89C1031B10B7823B1034B3246186829
+:1031B000FFF33AF5284670BD2428020010B5806858
+:1031C00001F0FEFD002010BD10B50446FFF7F6FF2C
+:1031D000A06806F083FE10BD61290DDC602940DA8D
+:1031E00054293ED003DC2F293BD0442912E0A1F121
+:1031F0005C03012B0FD834E0AC2932D005DC7C29EC
+:103200002FD0A1292DD06A2904E0DE2929D0F42964
+:1032100027D0CD2925D0642911DC632921DA4A2958
+:103220001FD006DC07291ADB08291ADD3C2918D033
+:1032300015E0502915D012DBA1F15C030DE0C32984
+:1032400005DCC2290DDAA1F1A803022B06E0B1F5D5
+:10325000847F06D003DBA1F58973012B01D90020FF
+:1032600001E06FF01600704731B1036B1B689942A3
+:1032700002D06FF00C0006E090F82930002B14BF4C
+:1032800000206FF00A00704730B5072A1C469DF8F1
+:103290000C5001DD496809B9036B1968032906D090
+:1032A0004B1E012B10D8036B1B6899420CD12DB11A
+:1032B00090F8293013B96FF00A0007E00CB92046E6
+:1032C00004E00020216001E06FF00C0030BDC0463A
+:1032D0001FB59646BEF1070F1A4601DC002300E039
+:1032E0005B685F2903930ADC5E2914DA4A2916D049
+:1032F00002DC3C2913D00CE05C290ADB0FE0AA2990
+:103300000DD002DCA82904DB0DE0C22907D0C329B7
+:1033100009D000200EE01946FFF7A6FF0AE00021C1
+:10332000FFF7A2FF06E000230093114603AB7246AD
+:10333000FFF7AAFF05B000BDC88810F0080018BF4D
+:103340006FF016007047C046D1F8D83270B5054608
+:10335000188C164610BB8B6D40F2371203EA02023E
+:10336000002A0CBF012411242A6B1368022B07D1F9
+:1033700095F85C360133DBB2012B98BF44F0200492
+:10338000537D53B1B06B06F13C0122F063DE20B1F6
+:1033900095F947360BB144F48064204670BDC046B1
+:1033A00091F801C030B5BCF1010F45DDCA788B78CA
+:1033B00043EA0223012B3FD1ACF10203032B3EDD94
+:1033C000ACF10603012B3ADD0B1D1D1D6A781B793C
+:1033D000002043EA0222864600E00130ACF10803F7
+:1033E000904203EB0E0406D0AEF1040EACF10403E0
+:1033F0007344042BF1DCC0EB0203A4EB830001282F
+:103400001DDD05EB8203DA789B7843EA022E821EEB
+:10341000002301E00133043A734501D0032AF9DCAB
+:10342000C3EB0E03A2EB8303012B08DD023B06D0A6
+:10343000C3EB0C034B7002E06FF0160000E00020BD
+:1034400030BDC0462F2A30B50446964602D86FF0EC
+:103450000D0034E0B0F88031056B0B60B0F88231BC
+:10346000AA894B60EB891B0743EA023302688B6031
+:103470001069BEF13B0FC36BCB6093680B61836A2D
+:103480004B61C36A8B61B2F87A30CB61D4F8843176
+:103490004B62D2F8B0300B6243688B62836BCB62B5
+:1034A0000CD92B8900220B636B89BEF13F0F4B6354
+:1034B0008A6303D9036C1046CB6300E0002030BD63
+:1034C00010B519B14068302203F012DC10BDC046BF
+:1034D00010B50446D0F860068E46C37A90F80AC04C
+:1034E00093B182894FF6FF739A420DD0837B43B923
+:1034F0008378012B05D0037B03F0010383F00101E6
+:1035000000E00021C9B20BE0216B71450ED1837B35
+:103510002BB98378012B02D091F84C1000E00021E8
+:103520008C4503D08172206938F0BADE002010BDCE
+:103530004FF0FF33A0F83C3210B5044600F50E7092
+:10354000063000210C22FEF37BF523685B6B23B968
+:103550004FF0FF33A4F840320DE04FF00F03A4F812
+:103560003E324FF0F003A4F840324FF47063A4F8F9
+:1035700042324FF20003A4F8443210BD70B5044645
+:10358000D4F8741580680CF069D8D4F8F816D0F126
+:10359000010538BF0025A0680CF060D800B90135DE
+:1035A000A068D4F8FC160CF059D800B90135D4F84D
+:1035B000E036A068196A0CF051D800B90135D4F88A
+:1035C000E0260023D360A068D4F83C150CF046D860
+:1035D00000B90135A068D4F894170CF03FD800B9B1
+:1035E0000135284670BDC04610B5044625F0F2DE10
+:1035F000204617F00BD810BD2DE9F04F0746106993
+:10360000A5B0D1F81090884601F124011A900792D4
+:103610000693189199F80130D2F87CA199F800200E
+:10362000339C42EA0323C3F38102022A7868089399
+:103630000B9201D0002302E0089DC5F3C013DBB25A
+:1036400041461693FFF3E6F504300A90329888B1AC
+:10365000037A0B2B08D197F8F0375BB197F8F13765
+:1036600043B18379072B05D832990A9A91F90F3023
+:10367000D2180A92D7F88831002B1CDA329BD3B1CA
+:103680001B7A022B17D197F8A034A3B91A9DAB6D02
+:1036900013F0080F0FD132988379292B0BD8032B05
+:1036A00009D90B2B07D82F99012904D10A9A19910E
+:1036B00008320A9201E000231993D8F81030B8F8C4
+:1036C0001420A3F1760676329D1FA8F8142000215D
+:1036D0007022C8F8106030460595FEF3B1F41898D2
+:1036E000036813F4806F01D0828827E00799A64B06
+:1036F0004A6802EA0303D3B1089A02F0FC03882B5C
+:1037000015D199F8043013F0010F10D1B8F8163024
+:103710002F9D03F007032E9801EB43016B1E984287
+:10372000B1F8BE200AD1531CA1F8BE3006E00B99B7
+:10373000012914D000224FF0100B04E00B9B012B49
+:103740000DD04FF0000B2E9D05F00F0343EA02133E
+:103750009BB289F816301B0A89F8173001E04FF048
+:10376000000B3098042807D138461A9932460FF0DA
+:1037700047D8ADF88C0019E02F992E9D4B1E9D4225
+:10378000B7F8462502D1531CA7F846352E98309934
+:1037900000F00F0343EA02135B0147F6E07203EA0D
+:1037A000020201F007031A43ADF88C20079A92F841
+:1037B000DF3023B9089D05F0FC03802B01D14BF0CD
+:1037C000200B724B04EA03031BB1002020942194C8
+:1037D0001FE00B99012906D9189A1368002B02DB08
+:1037E00013F0100008D0079C002594F8483003F02F
+:1037F0007F032093219349E0396B644B8A6C02EA82
+:10380000030343B199F8043013F0010F03D0209261
+:1038100021920F903BE099F8043013F0010009D099
+:103820000798002190F848300F9103F07F03209310
+:1038300021932CE04A6C554B02EA0303002BE6D19E
+:1038400020ABD7F8600100930DF18F0301930DF1C8
+:103850008E0302930DF18A03039323AA21AB0799E8
+:103860004FF028DA189A136843F00062189B1A6028
+:10387000BDF88A3013F0010F03D0189C42F40053B6
+:1038800023602E9DD5F1010538BF00250F95D7F88F
+:103890006036219A9C7A3B6893F8463013F0030116
+:1038A00000F0358112F0006F02F07F0104D007298B
+:1038B00006D9202904D02EE0354B5B56002B2ADA9E
+:1038C00012F0804F01D1002A25DB22F4401121F4AF
+:1038D000605112F0006F21911AD0D7F860068378FA
+:1038E000012B15D93B6B93F94D20012A0BD0079D75
+:1038F0006B6813F0804F0BD0B2F1FF3F08D1037B10
+:1039000013F0040F04D041F4801343F4805301E01A
+:1039100041EAC4232193209911F0006F01F07F0246
+:1039200004D0072A06D9202A04D036E0184B9B562B
+:10393000002B32DA219B13F0804F01D1002B2CDBBE
+:1039400021F4401222F4605211F0006F209221D035
+:10395000D7F860068378012B1CD93B6B93F94D1087
+:1039600001290BD0079D6B6813F0804F12D0B1F185
+:10397000FF3F0FD1037B13F0040F0BD042F48013F1
+:1039800043F4805308E0C046400001807F000008F7
+:10399000401B860042EAC4232093B7F8283603F47C
+:1039A0004063B3F5406F30D13B6B18690FF0BEF840
+:1039B000219B00F44070B0F5007F14BF0222032267
+:1039C00013F0006F03F07F0111D0202902D11546BA
+:1039D00005222EE097F9CA34B3F1FF3F12D10798C0
+:1039E000436813F4002F23D01546042221E09C4B9A
+:1039F0005B56002BB4BF97F9C93497F9C834B3F1BB
+:103A0000FF3F15D015469AB213E0219B03F07F03C8
+:103A1000202B04BF4FF000632193209B03F07F0312
+:103A2000202B04BF4FF00063209302252A4600E0BC
+:103A30001546219B110223F4E06341EA030321931D
+:103A4000209B23F4E06213F0006F14BF41EA0203ED
+:103A500042EA05232092219A209312F0006F06D0AB
+:103A600097F9DC31012B02D142F4000304E097F90D
+:103A7000DC3113B922F400032193209A12F0006F75
+:103A800006D097F9DC31012B02D142F4000304E0A7
+:103A900097F9DC3113B922F40003209307993846D3
+:103AA00012F03ED9219911F0006202D111920E92CA
+:103AB0001DE0D7F8583693F90530022B02D00022CA
+:103AC0000E9207E0C1F30223043B012B8CBF0023BD
+:103AD00001230E9311F4000F05D001F07F03072B93
+:103AE00003D9202B01D0119001E0042311932099D8
+:103AF00011F0006201D112921DE011F4000F16D0F6
+:103B000001F07F03072B14D9202B12D00FE0209B4C
+:103B100022F4E06223F4E06342F4007243F40073A1
+:103B200002252192209311910E91129103E012909F
+:103B300001E0042412940F9888B11A99219BD1F8BE
+:103B400010231A9801EBC201C1F814332F9C0132E3
+:103B5000E3B202F03F02C1F81833C0F81023BAF103
+:103B6000000F36D0FA68DAF80434D2F880410AEB54
+:103B7000C303C3F80442D2F884013A4AC3F80802E6
+:103B8000B8F8163003F00703D35C022B11D1DAF832
+:103B900000100AEBC102C2F80441C2F80801219BDF
+:103BA000013153602F9C01F01F01E3B29360CAF80A
+:103BB0000010DAF80424219B0AEBC201C1F8083492
+:103BC0002F980132C3B202F03F02C1F80C34CAF898
+:103BD0000424219911F000642AD011F4000F01F49B
+:103BE000E06312D01B0A043B012B1F4801F07F0247
+:103BF00005D8142302FB0303D3F80C801AE0142326
+:103C000002FB0303D3F8088014E01B0A043B012BDA
+:103C1000154801F07F0205D8142302FB0303D3F8F3
+:103C2000048007E0142302FB03F353F8008001E053
+:103C300001F07F080B9A022A00D0BAB9B7F83836DB
+:103C40000A98984204DC189A136813F0806F0DD01C
+:103C500099F8043083F0010303F0010307E0C04644
+:103C6000401B8600C4D285008418860000230D9373
+:103C70003B6B587D50B1D7F858361B7833B12CB90F
+:103C8000924A01F07F03D356002B0BDB3B6893F87D
+:103C9000463013F0030F2CD05CB3D7F8583693F9A5
+:103CA000053033B32F9A012A13D9D7F858361B7829
+:103CB0000BB1162300E03023189C20932193236836
+:103CC00023F000632360209B43EA05232093219384
+:103CD0000FE070B1D7F858361B7853B14CB97B4A16
+:103CE00001F07F030E98D35630EA230028BF01204D
+:103CF0000E90219A12F0006F15D102F07F03022B73
+:103D000005D0042B03D00B2B01D0162B0BD1069919
+:103D100039B1022B05D097F95C36013B18BF01235E
+:103D200000E000231193209B13F0006F16D103F0E5
+:103D30007F03022B05D0042B03D00B2B01D0162BB5
+:103D40000CD1069C44B1022B06D097F95C36013B9E
+:103D500018BF0123129301E0002012900B99079CD9
+:103D6000022904BF079BC3F86021636813F4803FF6
+:103D700040D097F8CE31002B3CD097F8D131002BB2
+:103D800038D0D7F8583693F90530032B32D0219B21
+:103D900013F0006F09D103F07F03022B2AD0042B0C
+:103DA00028D00B2B26D0162B24D099F8043013F0F2
+:103DB000010F1FD1089800F0FC03882B1AD1189925
+:103DC00001240B684BF4A04B43F480530B60079B1A
+:103DD0001094D3F8F0204FF69F73002A0CBF1822DE
+:103DE0001E2239F8021001EA030343F0200329F8E8
+:103DF000023001E000201090384621990A9A059B74
+:103E00000DF17A0419F028DC2346384620990A9AE5
+:103E100019F022DC062206F136002146FEF3ACF052
+:103E2000209B13F0006F10D103F07F03022B05D00D
+:103E3000042B03D00B2B01D0162B06D10A99C1F30A
+:103E4000072386F83A1086F83B30189B1A6812F45C
+:103E5000806F13D0219B13F0006F0FD0329C14B1F0
+:103E6000237A042B0AD1189842F40063036097F870
+:103E7000C3340D99002B18BF01210D91219911F028
+:103E8000006F0AD1114A01F07F03D356002B04DAE8
+:103E9000059A137803F00F0301E0059B1B78089C3B
+:103EA0000C93A42C14D099F8043013F0010F0FD107
+:103EB000109878B9119A319B38460FF06FDE89F867
+:103EC0000200C0F30F2089F803001DE0401B8600AC
+:103ED000109A62B1119A384640F62A1319F052D955
+:103EE000023080B289F80200000A89F80300089BBA
+:103EF000A42B09D199F8023099F8032043EA022350
+:103F000086F83C301B0A09E099F8043013F0010FE1
+:103F100001D1109C2CB1002386F83C3086F83D304E
+:103F20000BE02099129A319B38460FF037DE86F865
+:103F30003C00C0F30F2086F83D001898036813F486
+:103F4000007F0DD083894BF4005B86F842301B0A5A
+:103F500086F84330C38986F844301B0A86F845301A
+:103F60002E9909B94BF0080B09F104021B9299F83C
+:103F7000043013F0010F14D1189B1A6812F4805FFB
+:103F80000FD197F8D03113B112F0400F09D112F4CC
+:103F9000806F04D1169C14B197F8F8310BB94BF02F
+:103FA000010B0B98022814D197F8CE318BB1B8F1E0
+:103FB000040F0ED9AB4B30995B5C07EB4303B3F8AE
+:103FC000FE3123B1189A136813F4806F01D04BF4BB
+:103FD000805B3B6B18690EF0A9FD199B00F44060F3
+:103FE000B0F5406F08BF4BF4807B0BB14BF4004B36
+:103FF0004FEA1B2386F800B07370329CECB197F83F
+:10400000A034D3B91A98836D13F0080F15D1237A11
+:104010000B2B08D197F8F0377BB197F8F13763B1E4
+:10402000A379072B09D832998A79292A05D80B7BDD
+:1040300003F0070343EA021A01E04FF0000A189A5E
+:10404000129C1368494613F0005F18BF4AF0080A33
+:10405000631EDBB2012B98BF4AF4005A301D0222C6
+:10406000FDF38AF70023B371F37186F82C3086F8DC
+:104070002D303298002849D097F8A034002B45D134
+:104080001A998B6D13F0080040D1329B1A7A0B2AD3
+:104090000BD197F8F037002B38D097F8F137002B79
+:1040A00034D0329CA379072B30D832998B79292BC5
+:1040B0002CD8089C09F1180104F44073B3F5407F33
+:1040C000169B08BF09F11E0103B10231022A11D16A
+:1040D0003246329C2318B3F8BC309375C3F30723E0
+:1040E000D375831C02320A2B1846F2D106F1200048
+:1040F000032209E00B2A06F1160002D10231053233
+:1041000002E0329B93F90E20FDF336F706221B994D
+:1041100006F12600FDF330F79DF88C30002486F878
+:104120004C309DF88D3086F84D30D7F84C011A99F7
+:104130004AF0EEDF96F8463096F8472080B243EA20
+:10414000022343EA00239BB286F846301B0A86F816
+:10415000473086F84E4086F84F4086F8504086F843
+:10416000514086F8524086F8534086F8544086F80D
+:10417000554086F8564086F857400D9808B10E9481
+:1041800003E00E99002900F01D81002221992B46A1
+:10419000384622F051DE00228046209938462B46D0
+:1041A00022F04ADE18F000628346099206D12E4BB7
+:1041B00008F07F029B56002B2ADA36E018F4000F35
+:1041C00008F4E06310D01B0A043B012B274808F0D9
+:1041D0007F0204D8142302FB0303DB6814E01423DA
+:1041E00002FB03039B680FE01B0A043B012B1F48E3
+:1041F00008F07F0204D8142302FB03035B6803E08A
+:10420000142302FB03F31B58023B18BF012302E0F7
+:10421000931E18BF012343B197F95C36012B04D0DC
+:1042200001234AF4804A139301E0002413941BF005
+:10423000006F06D10C4B0BF07F029B56002B30DA3F
+:104240003CE01BF4000F0BF4E06316D01B0A043BA8
+:10425000012B06480BF07F020AD8142302FB03034C
+:10426000DB681AE098E08500401B86008418860011
+:10427000142302FB03039B680FE01B0A043B012B82
+:104280009D480BF07F0204D8142302FB03035B68F4
+:1042900003E0142302FB03F31B58023B18BF012366
+:1042A00002E0931E18BF012343B197F95C36012B3E
+:1042B00004D001254AF4004A149501E0002014902E
+:1042C0000E993278737821B142EA032343F40063F4
+:1042D00003E042EA032343F0060333701B0A7370C2
+:1042E0000E9B06F15802002B0CBF14250E251592CB
+:1042F0001DAC2A4638464146159B19F0ADD92346D8
+:104300002A463846594619F0A7D92146062206F111
+:104310002E00FDF331F6139C119D0A9800940024A1
+:104320000E99219B0195029042460394384619F05C
+:10433000B3D986F86000C0F30F2086F861001499A5
+:10434000129A0A9B009101920E9902930394209B6A
+:1043500038465A4619F0A0D986F83400C0F30F2029
+:1043600086F835000E9D06F162004DB16FF03B03FB
+:1043700009F10A01062286F85E3086F85F4008E0FF
+:104380006FF04B0386F85E300E990C2286F85F10B2
+:104390001B99FDF3F1F5099A52B9584A08F07F03C9
+:1043A000D356002B04DA159C237803F00F0301E0A9
+:1043B00096F858300C9D1B0243EA050506F15E098C
+:1043C0000C951BE00E99062206F15800FDF338F615
+:1043D0000E99102206F15E00FDF332F606F12E0072
+:1043E0000E990622FDF32CF60E9886F8340086F816
+:1043F00035008146139014908046834618990B68C7
+:1044000013F4806F0BD0219A12F0006F07D0D7F809
+:10441000400107990A9B2AF0B3DF86F833004FEA80
+:104420001A23F37086F802A00C9A130AB274F3747C
+:10443000209B13F0006F02D097F8C0A40EE003F0A9
+:104440007F03022B07D0042B05D00B2B03D0163B88
+:1044500018BF012300E000231FFA83FA18F0006F51
+:1044600003D097F8C0349D000EE008F07F03022BC4
+:1044700007D0042B05D00B2B03D0163B18BF01230C
+:1044800000E000239B009DB21BF0006F03D097F863
+:10449000C0341C010EE00BF07F03022B07D0042B6D
+:1044A00005D00B2B03D0163B18BF012300E00023DF
+:1044B0001B019CB23B6B18690EF038FB45EA0A03FE
+:1044C0002343C0B243EA002333751B0A7375219B53
+:1044D00013F0006F02D097F8C04413E003F07F039D
+:1044E000022B0DD0042B0BD00B2B09D0B3F11600EF
+:1044F00018BF012005E0C04684188600401B8600D6
+:10450000002084B2119D6B1EDBB2012B07D83B68E3
+:1045100044F01004D3F88C209369013393612199FE
+:10452000384615F02BDB44EA000080B23072000AF6
+:104530007072219938461FF055DEB072C0F30F201B
+:10454000F072209938461FF04DDE3073C0F30F2013
+:1045500070730D9808B90E9979B1414638461FF02D
+:1045600041DEB073C0F30F20F073594638461FF098
+:1045700039DE3074C0F30F207074219911F0006F90
+:104580000CD0119A042A09D10A9A384618F0ACDEE8
+:1045900086F83E00C0F30F2086F83F00209911F006
+:1045A000006F0CD0129B042B09D10A9A384618F0E0
+:1045B0009BDE86F84000C0F30F2086F84100079C80
+:1045C000636813F0400F00F0CE80169D002D00F0C0
+:1045D000CA806A4B30981B5C179307EB4303B3F810
+:1045E000FE31002B00F0BF8018990B6813F4806F28
+:1045F00040F08D802E9A002A40F08980219C384618
+:104600002146119A0A9B18F0BDDD8246B9F1000FD0
+:104610001AD04146139A38460FF082D8149A0446AD
+:10462000594638460FF07CD899F8032099F80230A3
+:1046300043EA022303EB040896F8352096F8343059
+:1046400043EA022318181BE0109B13B1804648462A
+:1046500016E02146119A4B4638460FF09FDA209C0F
+:10466000129A21460A9B00EB0A08384618F08ADDA8
+:1046700021460546129A38464B460FF08FDA40190C
+:104680001FFA88F3B3711B0AF37183B286F82C30DA
+:104690001B0A86F82D30179C07EB4403B3F8FE5134
+:1046A000CAEB0804A54225D31898036813F0400FFD
+:1046B00002D0309901291DD038462199119AC4EBB6
+:1046C00005030FF035D8FF2802D84FF4807304E0BB
+:1046D000B7F82A36834228BF034699B2309B07EBCE
+:1046E0004302B2F82C368B4204D0A2F82C1638467E
+:1046F00026F0CCD83B6893F84430002B33D0309C64
+:10470000032C30D8D7F864011799424628E03B685B
+:1047100093F844303BB3309D032D24D8B9F1000FFA
+:104720000CD0139A384641460EF0FADF99F8032070
+:1047300099F8023043EA02231A180EE0219C119ADC
+:1047400021460A9B384618F01DDD119A0546214680
+:1047500038464B460FF022DA4219D7F86401179910
+:10476000079B3DF02FDD1898036843F08403036036
+:10477000BDF88C0025B0BDE8F08FC04698E08500FC
+:104780002DE9F0479946536A064613F4007F8846A0
+:1047900017469DF920A0146902F1240515D0E86898
+:1047A00083B2000C84F8423084F844001B0A000AEB
+:1047B00084F8433084F845002378607843EA002386
+:1047C00043F4005323701B0A637033682D6993F818
+:1047D000443093B1F36A03EB4803B3F91C3063B977
+:1047E0005DB12B69D3F8D43293F89D30032B04D9F3
+:1047F000D6F864012B463DF0C5DDB8F1040F22D197
+:1048000094F84D3094F84C2042EA0324336893F82E
+:104810003830D3B1384612F045D906EB8000D0F8D5
+:104820004C12D1F85835D1F860055A1CC1F85825FA
+:10483000C369A1F8C8409A4288BFC261D1F8602517
+:10484000136A013313624FF6FF74B9F1000F05D0FC
+:10485000F26A02EB4802938B534493834FF6FF7343
+:104860009C4204D03069A821224639F0F3D933693B
+:10487000394603EB8803D8680C4B4A465B6A984775
+:10488000002810DA0A480CF00FFF0A4A13680133B7
+:104890001360B9F1000F06D0F26A02EB4802938B65
+:1048A000CAEB03039383BDE8F087C046E0A685000A
+:1048B000BC568600E827020070B50D46D0F8601699
+:1048C0000446CB7AAB420CD025B10C31B0F8282687
+:1048D00015F098D9D4F860362046DD72216BFEF7CA
+:1048E000F7FD002070BDC0462DE9F04F89B00023D0
+:1048F0000D46179907460492149CDDF854800793DF
+:104900000693DDF848B0DDF84C903AF073DD049A78
+:10491000824602F001060096386829462246434640
+:104920001EF0D2DC0590002840F0ED80B5F906308D
+:10493000002B1CDAA9882A895EB1169BCDF800806D
+:1049400003930194CDF8088049003869013123466A
+:1049500009E0169BCDF8009003930194CDF80880F0
+:10496000386949005B4638F0FBD80590CBE0B9F1D7
+:10497000030F0DD9042207A85946FDF3FDF2B9F142
+:10498000070F05D906A80BF104010422FDF3F4F288
+:10499000049A0799931E1F2B21D8DFE813F02300F8
+:1049A0002500270029002E00310038003A004B0076
+:1049B0004D0053005500570059005B005D005F003B
+:1049C000200065006C0074007600870089008D006F
+:1049D0008F00940096009B002000A6009D006FF0C1
+:1049E00016038FE04A4B09E0494B71E0494B05E063
+:1049F000002900F38580474B05E0474B1B6879E0B1
+:104A000000297DDB444B1960444B002239E0444BC4
+:104A1000F4E719B1434B1B68002B71D0404B0022C7
+:104A20001960414B1A60414B1A60414B1A60414B6F
+:104A3000013A26E03B4BE1E73A4A1368002B5FDD81
+:104A4000116060E03C4BD9E73B4B41E03B4BD5E785
+:104A50003A4B3DE0344BD1E7334B39E0D7F86C3279
+:104A6000D3F8D8329B6845E0354B1A68354B1B6844
+:104A700043EA02433EE0324B0A141A60314B01F024
+:104A8000FF021A603FE0304BB8E72F4B1960002956
+:104A900039D02E4B002119602D4B4FF0FF321A6098
+:104AA0002C4B1A602C4B19602C4B11E02C4BA5E7BA
+:104AB000002925DD2A4B0BE02A4B9FE74B1E092BD3
+:104AC0001ED8284B04E0284B98E7002918DD264B18
+:104AD000196018E0254B91E79AF8063063B9244B2A
+:104AE0000A1E18BF01221A700DE09AF806301BB991
+:104AF0001F4B1B78236006E06FF00602059202E070
+:104B00006FF01C030593059809B0BDE8F08FC0460F
+:104B1000EC270200D8270200E0270200B827020095
+:104B2000C0270200401E0200D4270200D027020046
+:104B3000C8270200B42702002C1E0200441E0200F7
+:104B4000142C0200102C0200BC270200E4270200F3
+:104B5000281E0200381E0200C4270200DC270200C3
+:104B6000341E02003C1E0200241E0200CC2702005C
+:104B7000B027020037B5036804465B7E002B40F087
+:104B8000C480026992F8EA305BB1D36ED3F8202179
+:104B900040F2044302EA0303B3F5806F40F0B580AE
+:104BA00005E0106E0AF050FE002840F0AE80236849
+:104BB00093F8203033B9206907F062FE22680123A0
+:104BC00082F8203023681B6FFBB9206907F0D6FDFF
+:104BD00010F1090F19D12268136F13F0020114D1DB
+:104BE00043F0020313670D4604EB8503D3F84C1220
+:104BF00041B18B7933B94B7923B18B7C13B120460A
+:104C00003AF03ED90135082DEED123681D6F1DB154
+:104C1000204612F079D976E0012384F82930204625
+:104C200021F004D82368596B39B103234FF4807203
+:104C3000009320462946134605E0032300932046AF
+:104C40004FF480720B461EF0BFDFA0680AF02CDD27
+:104C5000236801221A7694F89D3173B120460CF036
+:104C6000C1FDD4F840352046598E23F0DFDE002305
+:104C700084F89D3120461DF0C3D9B4F85C17204656
+:104C800021F04CDF206907F0DFFF236893F82F3015
+:104C90001BB1D4F8340730F03DD8236893F8313095
+:104CA0007BB1002504EB8503D3F84C1231B18B792D
+:104CB00023B94B7913B1204635F0FADE0135082DC2
+:104CC000F0D1204615F00EDF204618F0EDFA012550
+:104CD000D4F8AC114FF448720123A0680AF076DCD6
+:104CE000204684F8F15125F0D1DD204614F072DF22
+:104CF000204626F02DD950B1204626F007D920466F
+:104D0000294626F00DDB002001E06FF008003EBDD3
+:104D1000D0F8403570B55D8E064605F44063B3F5B6
+:104D2000406F22D1036893F8463013F0030F0BD085
+:104D300005F47041D0F85C01B1F5805F14BF00212B
+:104D4000012141F0B7DA80B92846FEF36BF2044640
+:104D50002846FEF367F244F430640E288CBF4FF40B
+:104D600080504FF400500443A5B2326B05F47043F9
+:104D70005268B3F5805F14BF00230123934205D02E
+:104D8000D6F85C01012140F0B9DD0546D6F85C019A
+:104D9000294641F003DB80B905F47043B3F5805F29
+:104DA00014BF38233C23F358346BD6F85C013363CB
+:104DB000012140F0A3DD34630546284670BDC0469E
+:104DC00070B50025044680F8E85124F0B7DDE36AA9
+:104DD0002946986A8022FDF333F1206908F0BAF978
+:104DE000D4F840012AF09EDCC4F8885670BDC04655
+:104DF0002DE9F04390F8A03187B00446002B40F035
+:104E0000ED8003681B7E002B00F0E880012380F812
+:104E1000A031006907F0E6FE2269074692F8EA3001
+:104E20005BB1D36ED3F8202140F2044302EA0303BE
+:104E3000B3F5806518BF012503E0106E0AF004FD8C
+:104E40000546002D6FD1D4F8680104214FF0B0DB86
+:104E5000204621F0A3DE00B90137A94604EB09037F
+:104E6000D3F84C62002E59D096F80680B8F1000FA6
+:104E700054D1304633F06ADC73793F18002B4DD0A3
+:104E8000236893F83130002B3FD0D6F8CC3013F0A4
+:104E9000010F3AD0204631460CF0B4FC23683F188D
+:104EA00093F89530002B39D0D4F86C122046BC31E1
+:104EB00050F074DC0546002830D02046294622F008
+:104EC0008BD82B7E13F0020F19D02846022150F008
+:104ED000B7D8B17CD4F86C32D1F1010138BF0021D0
+:104EE000082201920291204631460332BC33CDF8AC
+:104EF0000080CDF80C80CDF8108017F00FDED4F8CC
+:104F00006C22012382F8F03008E02046314639F067
+:104F1000B7DF3F184FF47A6001F01EDC09F1040995
+:104F2000B9F1200F9AD10025D4F8B434EA18136BE4
+:104F300013B1506A98473F18343540F2AC439D4254
+:104F4000F2D194F8F1314BB1A068D4F8AC110AF069
+:104F500085DB00B90137002384F8F1312046FEF7E4
+:104F60000DFB236800211976236B4FF0FF32C61921
+:104F700018690DF0B3FD204615F08ADAD4F878529E
+:104F800007E00023291D606801220093FDF35AF712
+:104F90002D68002DF5D1236893F82F3073B1631974
+:104FA000D3F84C1239B18B792BB10B791BB1204658
+:104FB0000CF028FC36180435202DF0D1D4F87C02F2
+:104FC00010B10BF03BFE3618206907F0BDFD002341
+:104FD000801984F8293084F8A03100E0002007B05F
+:104FE000BDE8F0832DE9F04F9BB005462598089267
+:104FF0000793827AC37A0F4642EA0323269A00F186
+:105000000C010C3A08980A9113930B92C27D837D90
+:105010000DF1580943EA0223C3F3C70ABAF10E0F90
+:1050200094BF002101210F91079918F0C1F8249A2B
+:1050300028460A32114609920F9A50F0B9DB002433
+:10504000804615AE28462599269A4B461594169407
+:1050500000961CF0DFDF30B928462599269A4B468A
+:1050600000961EF0D7DFB8F1000F06D0D8F8043054
+:1050700013F0010F01D00C9427E00B990A9832220B
+:10508000FDF31CF3014620B14078023120F0E2DF4D
+:1050900058B90B990A980122FDF310F3014638B173
+:1050A0004078023120F0D6DF10B101230C9301E0EB
+:1050B00000200C90B8F1000F07D00C9929B9D8F84E
+:1050C000043043F00103C8F804300A980B99032216
+:1050D000FDF3F4F2044608B14378A3B92B6893F8C2
+:1050E0003F3053B1B5F82606C3B2534503D0FEF3A3
+:1050F00099F0504501D1012300E0002300225FFA1E
+:1051000083FB0D9211E02B6893F83F3043B1B5F863
+:105110002606FEF387F0A378834201D1012300E045
+:1051200000235FFA83FBCDF834B0BBF1000F01D14F
+:105130005B4602E03B1E18BF01235FFA83FA2B682F
+:1051400093F8463013F0030002D11090119024E040
+:1051500095F8723263B9BAF1000F09D0D7F8D4329A
+:10516000DB8813F0200003D110901190129018E00A
+:105170000A990B9A284620F0DFDF0A9911900B9AC2
+:10518000284620F0A5DF2B68109093F94C0020B141
+:1051900028460A990B9A1DF0C9DC1290BAF1000F4B
+:1051A00069D02B6893F8463013F0030F63D0109B3F
+:1051B000002B60D0119800285DD019785A782846C5
+:1051C0000FF0E0DEB5F82696064609F47043B3F515
+:1051D000005F0CBF38233C23EC58D5F85C016168B4
+:1051E00040F08CDA10F0080F01D0002104E094F8B0
+:1051F000EC30191E18BF0121119A137813F0020325
+:1052000017BF10981A464378C3F3800209F440632D
+:10521000B3F5406F18D1B5F82636B34202D100215C
+:105220000E912EE02B6893F82F30002B40F05B841A
+:105230003046FDF3F7F70446B5F82606FDF3F2F71E
+:10524000844240F0508414E0A9B1A2B106F4406356
+:10525000B3F5406F0FD12B6893F82F3073B93046F8
+:10526000FDF3E0F70446B5F82606FDF3DBF78442CC
+:1052700004D10E9605E000220E9202E000230E9368
+:105280009A462B6B5B7D002B3AD0BBF1000F37D0D9
+:1052900095F8723233B995F87432002B30D0BAF1E8
+:1052A000000F2DD195F849365BB1159B002B08DD19
+:1052B000169B1B7813F0040F03D0D5F8582604234F
+:1052C000136195F8493653B10C9850B9139911F000
+:1052D000200F0ED1D5F858260423D36009E00C9A8C
+:1052E0003AB1159B002B08DD169B1B7813F0010FBC
+:1052F00003D0D5F8582604231362284625F06CDE27
+:105300002B6893F8463013F0030F46D0BBF1000F23
+:1053100043D095F8723233B995F87432002B3CD0F3
+:10532000BAF1000F39D1B5F8263603F44063B3F56E
+:10533000406F14BF00210121109B13B90C9830B9A4
+:1053400016E0109A937803F00303032B05D1D5F8E8
+:10535000582604239361109B53B11098837803F06F
+:105360000303022B04D119B1D5F858260233D362B6
+:10537000119A7AB1109B6BB111985A78037813F097
+:10538000020F07D112F0040F04D019B1D5F8582636
+:105390000423D362284625F0D1DE2B6893F82F3002
+:1053A000E3B1D5F8FC341B78C3B10D99B1B92846E7
+:1053B00011992FF01FDA88B128460D992FF01CDBC8
+:1053C00028462FF00FDBB5F8263603F44063B3F51B
+:1053D000406F03D1284601212FF080DAB8F1000F89
+:1053E00029D0D8F8F03033B300230B99824A0A98B9
+:1053F00000931CF087DF41460246284620F0C0D9C2
+:105400002B6893F8463013F0030F14D0119A2AB189
+:10541000129B28460093109B41460AE0D8F80430BE
+:1054200013F4803F07D01198119A00904146284606
+:1054300013461DF0DBDB95F87032002B00F06C8317
+:105440000FB93E4601E0D7F8DC62BAF1000F00F078
+:1054500083802B6893F8463013F0030F3DD0BB7C5C
+:1054600043B9B8F1000F08D1284609990F9A50F0B6
+:10547000B9DA8046B8F1000F2FD01199C9B1D7F829
+:10548000CC3013F4005F05D0B7F8343543F0200377
+:10549000A7F83435129A109B009228464146119A7B
+:1054A0001DF0A4DBB7F8343523F02003A7F834351A
+:1054B0000DE0BB7C5BB9D8F8043013F4803F06D014
+:1054C000119B284641461A4600931DF08FDB284663
+:1054D0000A990B9A434620F079D9089928461EF07C
+:1054E0005BDA41B238461EF099DA38461EF0EED942
+:1054F0000899284612F0E4DA0146384611F046DAF7
+:10550000BB797BB9D7F8E032D7F8D422188A9B8AC6
+:105510005085938573792BB9BB7C1BB1384601212B
+:1055200035F038DF0023B371F371BC7CA4B996F871
+:105530008530012B10D186F88540D5F8400126F042
+:10554000FDDF284639460F22234600940194029439
+:105550000394049417F0E2DA002F5AD0BB79002BA1
+:1055600057D1BB7C002B54D0259925988B784A784D
+:105570001B0443EA02230A781343CA78043143EA3E
+:1055800002698B784A781B0443EA022302791343A9
+:10559000CA7843EA0264F26912B9336A13B935E092
+:1055A000944204D3944231D1336A99452ED2DDF826
+:1055B00090E0002300930193029303930493284601
+:1055C000394616220EF1100317F0A8DA384608996A
+:1055D000079A259B24F0A2DFBBF1000F16D0FB79C0
+:1055E00063B1BB7C23B107F1BC00FDF3B5F128B971
+:1055F00007F1BC0104E0C0460FD4010007F1D60159
+:10560000002228461346009222F02ADDC6F8209098
+:10561000F461BAF1000F00F01F82BB79002B40F05B
+:105620009681BB7C002B00F0928114AB00932599EE
+:105630003846269A0DF1670316F016DBBDF85010B8
+:10564000D7F8E462A7F8201595F8EB41002C65D156
+:1056500000284FD03378022B19D138462146B6F8AE
+:1056600026900BF0DDFDB5F8303885F8324803B1EF
+:10567000F38438461EF0A6DFD7F8E432A6F8269069
+:105680005B8B002B4AD0384611F062DA46E02B687B
+:105690005B6B4BB195F8FA3133B1B8F1000F14D010
+:1056A00098F8D2300F2B10D0B27822B12846394664
+:1056B00023F0D6D832E04FF0FF330093284607F1AD
+:1056C000BC01134622F0CCDC28E095F80D372BB353
+:1056D000B3785BB1B8F1000F05D0D8F8043023F0EF
+:1056E0000063C8F80430384616F09CDB384623F0D7
+:1056F000B9DD13E0337A23B1718911B9384623F04B
+:10570000DFDDD7F8E4325B8B43B13378022B05D170
+:10571000336A012B02D138461EF040DFF3781BB10B
+:105720003846002123F0C0DC737A1BB138460021D3
+:1057300023F0B2DE2B6B5B7D002B41D0139A284601
+:10574000C2F3802124F0B2DD169A002A38D0159BCE
+:10575000002B35DDD5F8581691F90130B3F1FF3F34
+:1057600009D11378C3F340020B78934203D0284643
+:10577000012120F0FDD8169B1B7813F0040318BFFD
+:10578000012385F8463695F94636012B03D0D5F826
+:1057900058361B690BB1002300E0012385F842361F
+:1057A000B8F1000F0CD0D8F8043023F00402C8F888
+:1057B000042095F946361BB942F00403C8F80430BA
+:1057C0002B6893F8463013F0030F36D0109B002B54
+:1057D00033D0D5F8582692F90630B3F1FF3F27D1E0
+:1057E000109892F90520837803F003039A4204D0BD
+:1057F00028460B211A4620F0BBD810998B78C3F3AA
+:105800008002D5F85836DB79934203D028460D2123
+:1058100020F0AED8109A9378C3F30012D5F858361A
+:105820009B7A934209D02846102120F0A1D804E0A9
+:10583000012B0CBF032300235371D5F85C01B5F88D
+:10584000261640F073DB90B1D5F85C01B5F826164A
+:105850003FF0ACDF2B6B18690DF068F9B5F8263610
+:10586000834204D1002128460A461EF095DBB8F198
+:10587000000F3FD0D8F8043013F0400F00F03F8104
+:105880000A9B0B981893179006E02846214618AA01
+:1058900017AB1DF063DE40B918981799DD22FCF3B1
+:1058A0000DF704460028F0D122E1A11C0E79012E4B
+:1058B00040F025818A7995F80C3202F00F0203F04E
+:1058C0000F039A4200F01B8105F500740634204650
+:1058D0001822FCF351F32B6893F830303BB1D5F824
+:1058E0003407214600F563701822FCF345F338466F
+:1058F000314602E128460A990B9A10F087DC01280C
+:1059000002D128460EF018DA0E9929B195F86D35B6
+:1059100013B9284618F0DED8259A079B0092D5F8CF
+:105920004C013946089A49F07DDAD7F8CC3013F4A7
+:10593000005F00F0F180259B269800930190394686
+:10594000D5F84C01089A079B4AF0C2D9E4E0BB7C29
+:10595000002B40F081800C9909B1012102E0139ADB
+:10596000C2F34011CCB2B8F1000F15D0D8F8043012
+:1059700014B143F0040301E023F00403C8F8043039
+:105980000B990023664A0A9800931CF0BBDC414641
+:10599000024628461FF0F4DE2B6B5B7D13B3159B8C
+:1059A000002B11DD169B1B7813F0040F03D0D5F8E4
+:1059B000582604231361169B1B7813F0020F03D0A3
+:1059C000D5F85826042353620C9B1BB9D5F85826EA
+:1059D0000433D3611CB9D5F858260423D360284674
+:1059E00025F0FADA2B6893F8463013F0030F00F035
+:1059F0009380109840B1837803F00303032B03D105
+:105A0000D5F85826013393621199C9B1119BB5F8A5
+:105A100026165A781B7843EA022010F0100F03D1A3
+:105A2000D5F858260423536310F0020F08D101F46F
+:105A30004063B3F5406F03D1D5F8582604231363B0
+:105A4000109828B90C9919B1D5F858260423536138
+:105A5000284625F073DB5FE095F85735002B5BD0C7
+:105A6000BBF1000F58D0139A12F0020F54D00A98CD
+:105A70000B990022FCF322F6034600284CD028465E
+:105A8000991C5A7839F06EDC0446002844D0837C97
+:105A9000002B41D10899079A16F0B4DE00283BD0BC
+:105AA000259BD4F8D06226980093249B019003F1A3
+:105AB0001002284608990123029620F053DC024682
+:105AC00050BB296BD5F86036503106F138009B7811
+:105AD0004BF054DA269808990090079A2046259BA7
+:105AE00034F034DD18E000218A460E91FFF7C9BB7F
+:105AF000022385F80E32384601211CF051D90023CB
+:105B00000B990A98064A00931CF0FCDB41460246BA
+:105B100028461FF035DEEDE61BB0BDE8F08FC0462D
+:105B20000FD401002DE9F04FD2F81080C1B0D8F8A1
+:105B3000D8A2064609910892DAF82C00DAF830105B
+:105B400000220793FCF3BAF520B1831C109342782E
+:105B50000B9205E0099A099B093210921B7A0B936C
+:105B60002CAF002128223846FCF36AF200212822BB
+:105B700022A8FCF365F2DAF830100122DAF82C00E2
+:105B8000FCF39CF5DAF8301004463222DAF82C00E7
+:105B9000FCF394F505463CB16278102A04D8381D10
+:105BA000A11C2C92FCF3E8F13DB16A78102A04D8CC
+:105BB00023A8A91C2292FCF3DFF1099AD38813F0E1
+:105BC000010F17D0316B4B7DA3B10A6D2CAC201D9A
+:105BD00054312C92FCF3D0F1D8F8CC3013F4005FA0
+:105BE00005D0D6F84C014146224649F0E3DF0023B8
+:105BF000229309E022AB0093099B304603F138025F
+:105C000041462CAB20F022D9B8F86250DAF82C408B
+:105C1000B5F5806FDAF8307059D0B5F5006F04D162
+:105C20000022934611920C9257E020463946FDF32C
+:105C300051F3119020B143784FF0000B0C930BE01F
+:105C4000204639463022FCF339F5834610B9119AC3
+:105C50000C9201E043780C93402D09D0802D07D0A1
+:105C6000102D05D0B5F5807F02D0B5F5007F33D17A
+:105C7000D8F8582040F2371302EA030363B30C9AB2
+:105C8000BBF1000F08BF1422402D0C922ED14FF013
+:105C900000094F4616E0162307FB03F303F5B47320
+:105CA00008EB03040998211D0622FCF349F140B9D1
+:105CB00040AB03EB890204F10A0342F8B83C09F156
+:105CC00001090137D8F8CC329F42E4D310E000221A
+:105CD000934611920C9200E045B1D8F8582040F25A
+:105CE000371302EA03030BB118230C934FF000099A
+:105CF00040F2EE5301933FAB0293079B099A002BAE
+:105D000014BF20210021304608F1C20300921CF08C
+:105D100053DB0D9030B930460D99B8F80C2332F0B2
+:105D2000DDDE83E23F9A304602F5BC630E330A9211
+:105D30004146099A0E93FDF707FB0A9A1070C0F3CB
+:105D40000F2050709AF8223093709AF82330D37055
+:105D5000131D3F93079B8BB10AF124042046FCF3EB
+:105D6000FBF510B93F98214602E03F9808F1D601B3
+:105D70000622FCF301F13F9B06333F933F9A00213B
+:105D80000F921046109B0B9A26F0EED92DAB0121F5
+:105D90002C9A3F9026F0E8D90C9B3F90002B7CD0AA
+:105DA000BBF1000F11D0B9F1000F03D030465946B6
+:105DB000FDF7F6FA3F9C5946204617F0A7DC3F90C6
+:105DC0009BF80130A346637019E0402D09D0802D67
+:105DD00007D0102D05D0B5F5807F02D0B5F5007F36
+:105DE0005BD1A649834617F091DC099B3F9003F1F4
+:105DF0007B02304641460BF1040313F0F5DA402DE7
+:105E000009D0802D07D0102D05D0B5F5807F02D0A8
+:105E1000B5F5007F41D1B9F1000F01D14C4626E024
+:105E20009BF801300BF1020202F80390D7184FEAF9
+:105E300019237B709BF80130002402338BF801306A
+:105E40003F9B02333F9312AB07EB041053F824102F
+:105E500002301022FCF390F09BF801300134103333
+:105E60008BF801303F9B10334C453F93EBD1D6F874
+:105E70006C32D3F8D8325B68022B0ED16CB10022A1
+:105E800000920192CDF808B09BF801303046023301
+:105E90000393572113461DF00BDE229A2AB13F9837
+:105EA000322123AB26F060D93F90DAF82C401CE079
+:105EB0006278C1F102031B199B18671C83421CD82E
+:105EC000119BA34219D02378012B0BD9302B09D079
+:105ED00002323F982146FCF34FF03F9B6278023339
+:105EE0009B183F933B78A21CD41834B1DAF82C10DD
+:105EF000DAF830000B189C42DAD3336893F8463056
+:105F000013F0030F18D0089A536813F4803F13D08E
+:105F1000326B0DF1DB041368404621466532022BDB
+:105F200014BF0023012326F081D83F982D211A2287
+:105F3000234626F019D93F9096F8653633B106F519
+:105F4000CC613F98043117F0E1DB3F90336893F860
+:105F5000463013F0030F1FD0089A536813F4803FA4
+:105F60001AD0326B0DF1DB0113684046022B14BFCF
+:105F700000230123653226F059D83F990E9B8B42AE
+:105F800001D2002202E00E9BC1EB030230460DF16C
+:105F9000DB0325F009DF3F9033685B6B4BB3099A55
+:105FA000D38813F0040F24D00DF1F50034490322F7
+:105FB000FBF3E2F702238DF8F83000238DF8F93077
+:105FC00001338DF8FA3096F8FA313BB1099A92F91B
+:105FD0006A30002B02DA96F80A3700E000238DF8C9
+:105FE000FB303F98DD2107220DF1F50326F0BCD8E8
+:105FF0003F90B5F5806F02D0B5F5006F06D1D8F8A7
+:106000002C3543B33F98D8F8281505E00C9B13B303
+:10601000119A2AB13F98114617F078DB3F901AE0A9
+:10602000402D18D0802D16D0102D14D0B5F5807FBE
+:1060300011D0B5F5007F0ED03F9C1249204617F0D5
+:1060400065DB099B3F9003F16B023046414604F14A
+:10605000080313F0C9D96B1E9BB2012B03D9042D81
+:1060600001D0082D10D1099A506E002838D0B2F80E
+:1060700068100C300C39FDF32DF11BE0CCD28500FB
+:1060800017D40100E2D28500402D09D0802D07D021
+:10609000102D05D0B5F5807F02D0B5F5007F1FD15A
+:1060A000099B586EE0B1B3F868100C300C393022FF
+:1060B000FCF304F3A0B1D6F86C32D3F8D8325B68A5
+:1060C000022B0DD14378102B0AD902330022029003
+:1060D0000393304657210123009201921DF0E8DC22
+:1060E000D8F8583013F0040F01D004230EE013F059
+:1060F000020F01D0022309E013F0010F01D00123A8
+:1061000004E013F4807318BF4FF48073089A13648B
+:10611000336893F8463013F0030F2DD0089A136CB0
+:10612000013B012B09D8536813F4802F05D0114689
+:106130003046062224F0B4DD1EE0089A536813F4BA
+:10614000802F19D011463046062224F04DDD30460E
+:1061500016F07ADF012801460ED1D6F8F83742F260
+:106160000E721B88013B9BB2934202D83046013924
+:1061700000E0304628F0AADF3F9C0E9BA34201D2EC
+:10618000002302E00E9AC4EB020300932023019344
+:10619000002123464FF0FF32404639F0C5DF0F9B08
+:1061A00000273F90C01A03930490414655223B4676
+:1061B000304600970197029716F0B0DC0A9A3F9B91
+:1061C000A2F11805C5EB0304DAF834100D9B9C828C
+:1061D00021B17068DAF8382000F08ADD0A9A706818
+:1061E000C5EB0203E41A214600F072DDCAF8340060
+:1061F00040B1079BCAF838408AF83C300A992246D9
+:10620000FBF3BAF6099A3046B2F862300197C3F34D
+:10621000401300930297089B0D99D6F804281FF0AD
+:1062200081DC0D9B002808BF00230D930D9841B021
+:10623000BDE8F08F2DE9F04F95B0079119690692EE
+:1062400005930A9101F106098A7999F80130064609
+:1062500042EA0323069A0893C0F87828C3F381051D
+:1062600013465B79127942EA0323099303F003038F
+:10627000022B08D1089C14F4004F04D0D5F101037F
+:1062800038BF002300E00023DBB205990B930B9A83
+:106290008B8AA3F10A0893001DB918339845C0F200
+:1062A000A081089B03F0FC07A42F03D0842F01D00A
+:1062B000942F03D1B8F10F0F40F3938199F8043074
+:1062C00009F1040A13F001030C9303D00024109485
+:1062D0000D9408E05146304639F020D8011E18BF11
+:1062E000012110900D9125B1002293460E920F923C
+:1062F00010E009F110043046214638F0EBDF0E9033
+:1063000010B183460F9505E03046214639F04CD850
+:1063100083460F9096F8C83123B9326892F82C3032
+:1063200033B925E030460699059A00230FF068DD61
+:10633000A42F03D0842F01D0942F01D10D9B53BBE8
+:10634000802F28D0502F26D0002D40F006840D9CA1
+:106350000CBB5046FCF3F0F2002800F0FE83BBF1CA
+:10636000000F18D109F11000FCF3E6F298B9F4E33C
+:106370000C9981B90D9B43B192F838305BB155B996
+:10638000BBF1000F07D1109C2CB9D2F88C20936F71
+:1063900001339367E1E396F8C8317BB9BBF1000F95
+:1063A00001D05C4601E0D6F86C4294F8E5302BB1A0
+:1063B00030460699059AA3680FF022DD012D10D111
+:1063C000C42F0ED0D42F0CD009F10A00FCF3C4F274
+:1063D000002840F0C28399F80A3013F0010F40F012
+:1063E000BC83059930460B69A1F8148006330B6114
+:1063F00033684946D3F88C20D36C0133D3641FFA39
+:1064000088F30093069A13AB12F072D830B1336858
+:10641000D3F88C20D36F0133D3679EE3139A12B164
+:1064200033689B6A1362012D39D1059A059B106967
+:10643000998A00F11002059C1A61A1F11003A38250
+:106440000B9B2BB100F11402A1F114032261A38272
+:106450000599A42F8C8A0FD113990B699B79002B76
+:1064600000F07B8391F8DF30002B00F0768330461C
+:10647000089A2FF0DDDD70E3336893F84230002B8B
+:1064800000F06B83842F02D0942F40F06683D6F8FF
+:10649000400113992346009728F0C2DF5DE3069A76
+:1064A000937DD27D43EA0223C3F3C7030E2BD4BFEF
+:1064B0000023012311930C9B002B62D199F8163015
+:1064C00099F8172043EA0228139B33B9304609F1A3
+:1064D0000A01119A4FF06CD91390089C14F4006AC9
+:1064E00005D0139B1BB1B3F8BC30434525D0139B9B
+:1064F0000BB1A3F8BC80139B8BB142E006EBC20347
+:1065000003F5F3642046FCF327F270B909F10A00A1
+:1065100021460622FBF314F5013508B906E01D46B5
+:1065200096F8E837EAB29342E8D20024BAF1000FB5
+:106530000CD064B1E388434521D13368D3F88C2073
+:10654000D2F8BC310133C2F8BC3106E3BCB996F8CD
+:10655000E83709F10A0106EBC30202F5F3640133DF
+:1065600086F8E83706222046FBF306F596F8E8178A
+:106570000A23B1FBF3F202FB131386F8E837A4F801
+:1065800006800D9961B10E9A52B19BF806303BB965
+:10659000DBF8E4321B7A1BB15846089910F0B4DEE0
+:1065A000059B059C1869998A00F118021A619246A8
+:1065B0000B9AA1F11803A38232B100F11C02A1F1E0
+:1065C0001C032261A3829246059C0899099BB4F89A
+:1065D000148011F48044C3F3C0150DD0B8F1070F37
+:1065E00006DC3368D3F88C20536E01335366B4E273
+:1065F000B02F40F0B28227E0502F00F087800ED8F5
+:10660000202F00F0768205D8002F00F07282102F24
+:1066100045D0A2E2302F42D0402F56D09DE2B02F7D
+:106620000ED006D8802F00F09080A02F00F055816A
+:1066300093E2C02F00F0AC81D02F00F07B828CE27F
+:10664000B8F1050F40F38382BBF1000F00F08582A3
+:106650009BF80630A3B19BF80430002B00F07D823C
+:10666000069ACDF800800195137CD6F8340703F024
+:106670000803029359464A46534604F06DFE6CE205
+:10668000D6F8403593F93430002B00F06682584636
+:10669000494652464346009532F09ADC5DE2B8F135
+:1066A000050F40F35482BBF1000F00F056829BF8B7
+:1066B0000630002B40F05182139B58460093494608
+:1066C0005246434632F042DA47E2336893F8953057
+:1066D00013B996F872326BB108F118030393304680
+:1066E0002C2109F10A02234600940194CDF8089068
+:1066F0001DF0DED9069B0A9C0093D6F84C01494652
+:1067000052464346019449F00FDB26E2B8F10B0FE5
+:1067100040F31D82D6F84C015146424649F0BEDC9A
+:10672000D6F868319B79002B00F017820D9900296B
+:1067300000F01382304606990A9A4B46CDF800A025
+:10674000CDF8048010F042DF07E2B8F10B0F40F300
+:10675000FE810A9B30460E99069ACDF80090CDF83E
+:1067600004A0CDF80880FEF73DFCD6F868319B798F
+:106770004BB1304606990A9A4B46CDF800A0CDF8A9
+:10678000048010F023DF96F87232002B2ED19AF895
+:106790000A3013F0010F29D030465146424617F017
+:1067A00039D818BB069A937DD27D43EA0223C3F3FE
+:1067B000C7040E2C8CBF0023012363B10AF10C0027
+:1067C000A8F10C010322FBF379F778B143786BB1A0
+:1067D0008378A3420AD1336B18690CF0A7F9C0B2D1
+:1067E000844203D1D6F868014EF0AAD80F9B0BB1B2
+:1067F0001D4607E0304609F1100138F0D5DD0546A9
+:10680000002846D0AA79002A43D10AF10C00A8F149
+:106810000C01D5F8D842D5F8DC72FBF34FF7A2682B
+:1068200081460B2A08D1284606990A9A5346CDF884
+:10683000008033F08BDE0DE0336893F831304BB1DC
+:106840000F2A07D1284606990A9A5346CDF80080A8
+:1068500034F04CDAAB7CE3B197F85A30CBB1D6F8D0
+:106860006801494601224EF013D930B197F85930EA
+:106870001BB9013387F859300BE0D6F86801494657
+:1068800001224EF005D920B997F859300BB187F89D
+:1068900059000E9C002C00F06081DBF8D8329B6818
+:1068A0000C2B40F05A815346584606990A9A23F019
+:1068B00035DE5846002131F0FFDF336893F82F3082
+:1068C00023B1D6F834072EF025DA46E1DBF8E432BE
+:1068D000584699780AF0A4FC3FE1B8F1010F40F363
+:1068E0003681BBF1000F00F038819BF80630BAF812
+:1068F00000505BBB3046139920F06EDB1398037E8B
+:1069000013F0020F14D002214EF09ADB139B1B7E72
+:1069100013F0080F0CD130465946224609F10A03FC
+:1069200000950194CDF808A0CDF80C800AF0D8FAB3
+:106930000E99002900F01181DBF8D8329B6813B161
+:10694000584631F003DF58460321ADE013990B6937
+:106950005B4540F00281304620F03EDB1398037E19
+:1069600013F0020F10D012214EF06ADB3046594668
+:10697000224609F10A0300950194CDF808A0CDF84C
+:106980000C800AF0ADFAAFE010214EF059DBE4E0E4
+:10699000B8F1010F40F3DB80BBF1000F01D05F467F
+:1069A00004E0109A002A00F0D880174600252C46F3
+:1069B0003319D3F84C1241B109F11000BC31062251
+:1069C000FBF3BEF2002808BF01250434202CEFD1D0
+:1069D000002D00F0C280139BBAF8004033B9304656
+:1069E00009F10A01119A4EF0E3DE1390139911B1E7
+:1069F000304620F0F1DABB791398002B57D10028EC
+:106A00003CD012214EF01CDB1398037E13F0010FD3
+:106A100003D1436813F0005F30D001214EF010DB4A
+:106A2000A4F10D039BB2092B07D83368D3F88C204F
+:106A3000D2F8F8310133C2F8F83197F91030022B4F
+:106A400003D1F8680E2152F08DDD13990B7E13F0FF
+:106A500004020ED100944B683046C3F34073019397
+:106A6000394609F10A03CDF808A0CDF80C8032F0C0
+:106A7000B7DC139A536823F0005353600E9B002B2E
+:106A80006BD09BF81230002B67D0DBF8D82253680C
+:106A9000022B02D19368082B5FD8936813B1584634
+:106AA00031F054DE5846022134F074DC55E0002801
+:106AB00053D00169B94250D1D0F8F0301BB14368CE
+:106AC00023F400734360139B1B7E13F0010F44D02B
+:106AD0000022304609F10A0300940192CDF808A083
+:106AE000CDF80C8032F07CDC304613994EF068DE35
+:106AF00033E0B8F1030F2ADDBBF1000F2DD09BF876
+:106B0000043053B39BF806303BB309F110000BF18E
+:106B1000BC010622FBF314F2F8B9139BD6F8340734
+:106B2000019359464A465346CDF8008002950AF033
+:106B300061FC12E00A99069C0291304613994A467C
+:106B40005346CDF80080019410F038DC05E033683E
+:106B5000D3F88C20136F013313670798059900222F
+:106B600000F0DED815B0BDE8F08FC0462DE9F04F3B
+:106B7000436899B0164689460493918B96F82A305B
+:106B8000126880460292D9F810A00BB9059302E072
+:106B900096F82220059296F82C00B0B911F4006FF7
+:106BA00013D0059A09EB4203B3F8AC20B6F87E3057
+:106BB0009A420AD1D8F80030D3F88C20D2F8BC31F0
+:106BC0000133C2F8BC3100F065BC9AF80630C1F35D
+:106BD000802B7BBBDAF8E442237A6BB160B9BBF15E
+:106BE000000F09D199F8D230726A134113F0010FE6
+:106BF00002D1504610F088DBD8F800305B6BCBB187
+:106C0000237EBBB196F82A30A3B196F828308BB119
+:106C10000021504621F0BEDEDAF8CC3013F4005FDC
+:106C200008D0B38B13F4005204D1D8F84C0151466C
+:106C300048F0AAD9338C13F0040440F02B84B38BB2
+:106C400003F4804373634BB9DAF8582040F23713EA
+:106C500002EA03032BB39AF8603013B3059BB463C5
+:106C60000093404604994A4633464FF051DF08B13D
+:106C700022460EE0736B23B1D9F86C310133C9F8A9
+:106C80006C31D8F8003093F89530002B00F0028476
+:106C90000122736B33B1D9F868310133C9F8683117
+:106CA00000E0002296F82C300BB1002708E005998F
+:106CB00009EB4103B6F87E10B3F8AC70A3F8AC1042
+:106CC000D8F8000090F8953013B1002A40F0E28324
+:106CD00096F82C50002D40F00081B6F87E20059BE0
+:106CE00012F00F0C4FEA830E40F081800EEB090783
+:106CF000F96E41B104982A4600F012D8FD66C7F833
+:106D00008C50C7F83051BBF1000F00F0E68073697A
+:106D1000F168FB66D8F800307269DB6903919C6802
+:106D20001169D368908ACB1892681B189B1A0918AE
+:106D30005B1AA34223DA0498214600F021D8F866B2
+:106D4000002800F0A7837369006919699C689A8A12
+:106D5000C4EB0104091BA218FBF30EF17169FA6E72
+:106D600008698B68C01A13691B181361938A1B1A70
+:106D700093828B8A049893822A46FFF3D1F7D8F83E
+:106D80000030D8F82828DB6903999B68AA489B1A29
+:106D90005B1A063BC7F88C3071680822FBF3D0F011
+:106DA00050B1A64871680622FBF3CAF048B973686F
+:106DB000DB88B3F5407F04D1D9F8043043F00803F1
+:106DC00003E0D9F8043023F00803C9F804309C48E4
+:106DD00071680822FBF3B4F0D9F8083010B943F019
+:106DE000200301E023F02003C9F8083075E00EEB22
+:106DF0000904E16E11B9D0F88C2017E022F00F02DF
+:106E000027F00F039A4204D107F00F0301339C458A
+:106E100010D02A460498FFF383F7D8F80030E566CF
+:106E2000D3F88C20C4F88C50C4F83051136E013361
+:106E300013662FE3B068D4F88C309842E9D8049BED
+:106E400009EB0E020090019340468C3273680CF0FF
+:106E5000C7D8049871692A46FFF362F7BBF1000FA7
+:106E60003BD1E36EC4F88CB07361C4F86CB0736945
+:106E7000C4F830B11A69998A02F118037360A1F15C
+:106E80001803B36096F829303260F1602BB102F13B
+:106E90001E037360A1F11E03B36096F82A3043B15C
+:106EA0007368059902337360B36886F82210023B59
+:106EB000B36032681378527843EA0223B383736B6A
+:106EC0005BB1B16B49B191F90E2073689B18736087
+:106ED00091F90E20B3689B1AB360B36B73B11B7A40
+:106EE000042B03D1404631464FF0C0DEB36B1B7A12
+:106EF0000B2B03D1404631464FF0D4DFBBF1000FDE
+:106F000040F02283D8F8003093F89530002B73D0EE
+:106F1000DAF808309B7913F0010F40F0DA826BE069
+:106F200010F4000F00F4E06310D01B0A043B012BA7
+:106F3000444A00F07F0004D8142300FB0323DA68DE
+:106F400014E0142300FB03239A680FE01B0A043BA0
+:106F5000012B3C4A00F07F0004D8142300FB0323DC
+:106F60005A6803E0142300FB03F39A584FF4FA73B2
+:106F7000B2FBF3F007E000F07F034FF4FA7203FB7B
+:106F800002F3B3FBF2F0C0F307238DF825300DF1C7
+:106F90001B05C0F307438DF824008DF82630012728
+:106FA000030E316805F10F0018228DF827308DF897
+:106FB0002970FAF3E1F796F82F30DBB19DF82B201A
+:106FC0009DF82A3005F1190443EA022343F40073C3
+:106FD0008DF82A3021461B0A062205F11F008DF884
+:106FE0002B30FAF3C9F7D8F86C122046BC310622D0
+:106FF000FAF3C2F7BB4601E04FF0000BD8F80030BF
+:1070000093F8953013B91C461A4602E00DF11B04A3
+:107010002D2273695B6A13F0400F15D013F0800FB7
+:1070200000F038820092D8F83C01494632462346A7
+:1070300029F00EDE88E2C046401E86002CD40100F6
+:10704000481E86008418860031680DF15A07043105
+:1070500006223846FAF390F7316815AD0A31062258
+:107060002846FAF389F731680DF14E0420461031B5
+:107070000622FAF381F796F829302BB1316812A86D
+:1070800018310622FAF378F7B38B13F4807F03F4F8
+:10709000007305D1002B14BF23462B46776704E00D
+:1070A00074670BB9356701E012AB33677468BBF1E5
+:1070B000000F00F0EE803368F3662378AA2B23D10B
+:1070C0006378AA2B20D1A378032B1DD1E378DBB9F9
+:1070D0002379CBB9637943B9A379E179404641EA91
+:1070E00003210BF0F1DB50B10EE0F82B0CD1A379AA
+:1070F000E179404641EA03210BF0E6DB20B1A279B9
+:10710000E37943EA022500E03589D8F8003093F8A6
+:107110009530D3B1DAF8E0305BB9736BABB9DAF81C
+:10712000582040F2371302EA030373B19AF8603033
+:107130005BB1059A40460192494652463346009556
+:107140000DF022DA002840F0A581B36B6BB11B7AF9
+:10715000012B0AD0032B08D0404604994A463346F7
+:1071600009F0DEFE002800F09581736F1B7813F0A4
+:10717000010F08D0D8F80030D3F88C20D2F8D031E5
+:107180000133C2F8D031B36B33B11B7A022B03D178
+:10719000404631464FF06ADD726B22B996F82A30CC
+:1071A00023B3144602E0B36B93F90E4096F82A30ED
+:1071B0005BB1336802341A78597842EA012222F02E
+:1071C000800292B21A70120A5A707368581E03E055
+:1071D00063421B5C00F8013971690A699042F7D279
+:1071E0008B8A12191B1B0A618B82326096F82F3032
+:1071F000BBB130684278037800F10A0443EA022305
+:1072000043F4007303701B0A4370214606221030BA
+:10721000FAF3B2F6D8F86C122046BC310622FAF323
+:10722000ABF69AF9103093B148F68E039D420ED119
+:107230003168726BDAF80C001231003A18BF012283
+:107240000AF1180351F0AEDE002840F02381716985
+:107250000A698B8A9B18CA68D21A2C2A40F21A81B2
+:1072600000238DF829308B8A08692D2218180DF11A
+:107270001B01FAF381F6716996F82220CB8A02F09D
+:10728000070223F007031A43CA8296F829200091C7
+:10729000FAE0D6F814B02378DBF81070AA2BC7EB0D
+:1072A000040529D16378AA2B26D1A378032B23D1F7
+:1072B000E3780BBB2379FBB9637943B9A379E1790F
+:1072C000404641EA03210BF0FFDA50B114E0F82BFD
+:1072D00012D1A379E179404641EA03210BF0F4DAB7
+:1072E00050B17269A91F7B18CBF81030938A5B1AD2
+:1072F00093821369F36628E0DAF8583013F0200F10
+:107300000FD0204692490822FAF31AF648B972695A
+:10731000281D1169938A09181B1A11619382F1665D
+:1073200013E07269A5F10E00938A11691B1A93820A
+:1073300033890918116103F0FF021B0A43EA022393
+:10734000F1660B73C3F30F234B73B36B6BB11B7AF3
+:10735000012B0AD0032B08D0404604994A463346F5
+:1073600009F0DEFD002800F09580B36B33B11B7A85
+:10737000022B03D1404631464FF078DC0622716F74
+:10738000F06EFAF3F9F5F06E06220630316FFAF37B
+:10739000F3F5716996F82220CB8A02F0070223F0F8
+:1073A00007031A43736FCA821B7813F0010F08D0CA
+:1073B000D8F80030D3F88C20D2F8D0310133C2F89D
+:1073C000D0319AF8613093B199F8183013F0100F5A
+:1073D0000DD1F36E1A7B5B7B43EA022348F68E02E3
+:1073E000934204D073695B6A13F0100F52D09AF87D
+:1073F0006530BBB199F8183013F0100F12D1F36E4D
+:107400001A7B5B7B43EA022248F6B4039A4209D016
+:10741000263B9A4206D073695B6A002B02DB13F0AD
+:10742000100F37D09AF8063023B9DAF8E422013386
+:1074300082F82A3098F83238013388F832389AF9CD
+:107440001030EBB1F16E0B7B4A7B42EA032248F627
+:107450008E039A4214D10B8A03F0FF021B0A43EAFF
+:107460000223B2680C3A934214D8726BDAF80C001B
+:10747000003A18BF01220AF1180351F093DD48B910
+:10748000736996F82920009340464946736F1FF0B0
+:107490007BD959E0D8F80000436BA3B171692D4A3C
+:1074A000CB8AD0F8904003F00703D25C2A4B0498B3
+:1074B0009B5C04EBC304636EA56E01336366FBF350
+:1074C000A9F64019A066049871690022FFF328F418
+:1074D0003AE0D8F8303005991A8940468DF81B20DB
+:1074E000130A120E8DF81C308DF81E200023B2698D
+:1074F0008DF81D30937DD27D43EA0223C3F3C70389
+:107500008DF81F3009EB410393F8AC30D6F88010AA
+:1075100003F00F0301338DF828301CF03DDA029A96
+:1075200040B2030E8DF82000911FD6F880008DF830
+:1075300021308DF822308DF8233015F039FE10F00F
+:10754000006F7FF4EDAC16E519B0BDE8F08FC046D2
+:10755000F7E38500C4D2850098E085002DE9F04F5F
+:107560000024A7B08DF832408DF83B408DF83840AC
+:107570008DF870408DF83F409A4609939B8A0546E6
+:10758000212B02911746259412940D940A9224926D
+:107590001B9450D9DAF810901046494615F008FEB1
+:1075A00009F1060203900492527899F8063043EAF2
+:1075B0000223ADF82C30C3F38103ADF82E30BDF8B3
+:1075C0002C30C3F3031203F44073B3F5407F14BFB0
+:1075D000002301238DF83930BDF82E30ADF830206E
+:1075E000022B0ABFBDF830302346C3F3C0038DF829
+:1075F0003A303B7903F00303022B08D1BDF92C305C
+:10760000002B04DABDF83030C3F3C00300E00023E0
+:10761000D9B29DF839009DF83A308DF83B1000281A
+:107620000CBF2222282203B1023201B10432099B8D
+:107630009B8A934206D22B68D3F88C20536E013379
+:107640005366A5E304990B7903F001038DF83C30F0
+:1076500020B100231E468DF8403015E0BDF82C30D7
+:1076600013F4807F01D0043105E013F4007F01D0D2
+:107670000A3100E01031284637F02CDE031E18BF17
+:10768000012306468DF840309DF83C303BB9049903
+:107690002846043137F042DE08B1012400E000241E
+:1076A00095F8C83123B92B6893F82C3033B92FE003
+:1076B00028463946099A00230EF0A2DB2B6893F87E
+:1076C0003F300BB98DF8403054BBBDF82C3013F46B
+:1076D000807F05D19DF83C3013B19DF840303BBB15
+:1076E0009DF8393013B19DF83C300BBB2B6893F8F3
+:1076F0002C30002B00F04C839DF84030002B00F024
+:107700004783B379002B40F043834FF0010B11E026
+:107710009DF83C301BB9002C00F03A8300E03CB1EE
+:107720009DF8393023B99DF84030002B00F03083AC
+:107730004FF0000B2B6893F895304BB346B39DF890
+:107740003C30D6F8DC405BB914F0010F00F0208328
+:10775000049806F1C20104300622FAF3F1F314E0B2
+:1077600004980430FBF3E8F020B114F0080F00F0A7
+:107770000F830DE014F0040F0AD114F0020F00F093
+:107780000783284604990EF0A7DA002840F000830A
+:10779000099A136906331361938A063B9382049A0C
+:1077A00002F1180305939DF8393013B102F11E035D
+:1077B000059300238DF83D309DF83A306BB3059B5F
+:1077C0005A781B7843EA0221C1F3C0138DF83D308B
+:1077D0007BB126B196F81935002B40F0D98295F887
+:1077E000CF31002B00F0D482099A536A43F0400352
+:1077F0005362844B01F007028DF832209A5C824B71
+:107800009B5C0D93C1F300138DF83830059B023358
+:1078100005939DF832308DF870309DF83D3023B9D6
+:10782000099A938A043B938206E002980999FBF334
+:1078300069F1838A043B8382099A059C938A1269C1
+:107840000793A41A1B1B514602980693FBF3E2F41C
+:107850000499001B08908B7DCA7D43EA0223ADF892
+:107860008E30BBF1000F2ED1079B284600933A467D
+:1078700025AB10F03DDE002840F08A82BDF82C30A8
+:1078800013F4407F3BD1BA7DFB7D049942EA032289
+:10789000C2F3C70228460A310E2AD4BF00220122B1
+:1078A0004EF0A0D8259030B92B68D3F88C20D36E39
+:1078B0000133D3666CE20369D3F8CC30C3F3C01351
+:1078C0008DF83F301BE0BDF82C3013F4407F16D00C
+:1078D0009DF839309BB9259B8BB9BA7DFB7D284635
+:1078E00042EA0322C2F3C7020A310E2AD4BF0022A1
+:1078F00001224EF077D82590002800F04982259B80
+:107900001C69D4F8DC82BBF1000F23D19DF839301B
+:1079100003BB9DF83C3023B1BDF82C3013F4807FBD
+:1079200011D1A379BDF82C201BB112F4807F0AD0AD
+:1079300010E0A37C02F44072002B14BF4FF40073DC
+:1079400000239A4206D02B68D3F88C20936D013324
+:1079500093651DE295F82D370AF1240A33B99DF895
+:107960003F1019B9A3790BB10E4608E028463946F5
+:107970001CF012D8C0B246B208B18AF80900A37947
+:10798000FBB99DF83F30E3B9314620461CF046D89C
+:1079900020461BF09BDF3946284610F091D801465F
+:1079A00020460EF0F3DF9DF8403053B1A37C43B185
+:1079B000E37933B198F805301BB92046012133F043
+:1079C000E9DC95F82D3733B99DF83F301BB9259B7D
+:1079D000D3F8FC3073B16EB1259AD2F8F810D2F812
+:1079E000F43043F82160D2F8F830013303F0070394
+:1079F000C2F8F8309DF8393043B1B4F86200ADF800
+:107A0000780040E0C4D2850098E08500A3792599EC
+:107A1000002B35D08A8FADF878204A6812F0400FDD
+:107A200020D09DF83A30EBB1049B9B7D13F00F0FF3
+:107A300018D191F8DF30ABB18B7E13F0010F11D16B
+:107A4000BDF82C3013F4805F0CD012F4003F09D045
+:107A50000D9A91F8D130134113F0010F02D028464E
+:107A60002DF034DFBDF82C30259913F4805F15BF5D
+:107A70004B684B6843F4003323F400334B6002E05F
+:107A8000898FADF8781095F82D371BB9259BD3F861
+:107A9000FC3073B16EB1259AD2F8F810D2F8F430F8
+:107AA00043F82160D2F8F830013303F00703C2F83D
+:107AB000F830259BD3F87C1159B1D1F808360398DA
+:107AC00001EB8302013303F03F03C2F80C06C1F857
+:107AD0000836A3795BB9A37C4BB19DF83C3033B930
+:107AE000BBF1000F03D188F806B088F807B09DF805
+:107AF0003C30FBB1A379002B40F04A81A37C4BB111
+:107B0000296804984E3110300622FAF319F2002841
+:107B100000F03E8104980430FAF30EF750B92B6858
+:107B200093F83E3033B9284604990EF0D5D8002892
+:107B300040F02E81039ACAF814209DF83C308BB98E
+:107B400099F8022099F80130134399F800201A435C
+:107B500008D0BB7CFA7CD5F86001039943EA022285
+:107B60004BF022DADAF8142012F0006F26D012F46B
+:107B7000000F02F4E06310D01B0A043B012B96486F
+:107B800002F07F0204D8142302FB0303DA6817E033
+:107B9000142302FB03039A6812E01B0A043B012B27
+:107BA0008D4802F07F0204D8142302FB03035A68B5
+:107BB00006E0142302FB03F31A5801E002F07F02EF
+:107BC000864B1A6099F90330002B07DA2B68D3F83B
+:107BD0008C20D2F8D8320133C2F8D83299F8033069
+:107BE00003F03003102B07D12B68D3F88C20D2F888
+:107BF000E0320133C2F8E0329DF83C30002B40F017
+:107C00009780DAF814102B6811F0006FD3F88C20ED
+:107C100026D011F4000F01F4E06310D01B0A043BDE
+:107C2000012B6D4801F07F0104D8142301FB0303ED
+:107C3000D96817E0142301FB0303996812E01B0ABB
+:107C4000043B012B644801F07F0104D8142301FB9D
+:107C50000303596806E0142301FB03F3195801E0FC
+:107C600001F07F0116293AD00CD80B2925D004D871
+:107C7000022916D004291AD05AE00C2923D012293F
+:107C800027D055E030293CD004D818292DD02429FC
+:107C900031D04DE0602940D06C2944D0482936D0FD
+:107CA00046E0D2F870320133C2F8703240E0D2F8C8
+:107CB00074320133C2F874323AE0D2F878320133C8
+:107CC000C2F8783234E0D2F87C320133C2F87C3228
+:107CD0002EE0D2F880320133C2F8803228E0D2F8A8
+:107CE00084320133C2F8843222E0D2F88832013380
+:107CF000C2F888321CE0D2F88C320133C2F88C32E0
+:107D000016E0D2F890320133C2F8903210E0D2F887
+:107D100094320133C2F894320AE0D2F89832013337
+:107D2000C2F8983204E0D2F89C320133C2F89C3297
+:107D300025994B6813F4802F0BD09DF83C3043B944
+:107D4000BBF1000F05D1D5F8400104AA27F098DB5C
+:107D500003E0284604AAFEF709FF049B1B7C13F0EE
+:107D6000010F05D1259AD2F858310133C2F85831A4
+:107D7000049B1B7C13F0010F05D0259AD2F85C31CF
+:107D80000133C2F85C31259B0398C3F864011FE0FE
+:107D90002868436BBBB19DF83C30A3B90999104AE0
+:107DA000CB8AD0F8904003F00703D25C0D4B0298C9
+:107DB0009B5C04EBC304636EA56E01336366FBF347
+:107DC00029F24019A066029809990022FEF3A8F74B
+:107DD00027B0BDE8F08FC04684188600CC2702008B
+:107DE000C4D2850098E085002DE9F04FADF50F7DF8
+:107DF000DDF860B28A46594617469946064637F07E
+:107E0000F9DAD0F8D412D0F8D822D0F8DC32D0F891
+:107E1000E4428046089109920A930B94BBF1000F4B
+:107E200001D1D0F808B000238DF837328B9330465B
+:107E300051463A464B46FBF7CFF9041EC2F2338057
+:107E400033685B7EEBB9326992F8EA305BB1D36E8E
+:107E5000D3F8202140F2044302EA0303B3F5806023
+:107E600018BF012005E0106E07F0EEFC003818BFC7
+:107E7000012030B1B068FBF767F94FF0FF3402F032
+:107E800012B847B1B9F1030F05D98CA839460422BD
+:107E9000FAF372F001E000238C93BAF1A30F8C9DEA
+:107EA000F168706827D00DDCBAF11C0F07DCBAF15D
+:107EB0001B0F20DAAAF10203012B15D81BE0BAF13F
+:107EC000340F10E040F20B139A4514D005DCBAF1E0
+:107ED000D60F10D0BAF1FB0F05E0BAF58B7F0AD0B0
+:107EE00040F21B139A4506D0002F01F09587B9F197
+:107EF000000F41F3918740F23B132A1E18BF012265
+:107F00009A4501F2618701A454F82AF0098400001F
+:107F1000138400001D8400008F840000C99D0000B0
+:107F2000C99D0000C99D0000C99D0000C99D0000B9
+:107F3000E7840000F5840000C99D0000558500001D
+:107F4000C99D0000CF850000C99D0000C99D0000AB
+:107F5000C99D0000C99D0000DB850000E785000089
+:107F60000786000023860000558600007986000001
+:107F7000AB86000019870000979C0000899C0000D8
+:107F8000D987000019880000D7890000E389000024
+:107F9000438A00004F8A0000F38A0000FF8A000035
+:107FA000158B0000218B0000638B0000C99D000031
+:107FB000C99D0000C99D0000C99D0000858B00007F
+:107FC000418C0000478D0000FB8C0000C99D000023
+:107FD000C99D0000538D0000958D0000C78D0000E5
+:107FE000F38D00008F8E0000DD8E00002D8F0000CD
+:107FF000758F0000B38F0000BF8F0000979C0000BA
+:10800000F188000001890000418900007B8900009F
+:10801000C99D0000C99D0000C98F0000D58F0000D8
+:10802000EB8F000019900000C7900000F79000004F
+:10803000C99D0000979C0000199200004592000025
+:108040005D9200008D920000A3920000C99D000087
+:108050006F8B00007B8B0000CD9900000384000033
+:10806000E7920000F3920000C99D0000C99D000046
+:10807000C99D0000C99D0000C99D0000979C00009B
+:10808000979C0000979C0000979C0000C99D0000F1
+:10809000C99D000049930000C99D0000C99D0000D2
+:1080A000C99D0000C99D0000C99D0000C99D000038
+:1080B0007D90000089900000118500001D85000062
+:1080C000BD970000CF9700007D97000087970000C4
+:1080D000A789000093900000C99D0000C99D000081
+:1080E000D793000057930000E5930000F993000038
+:1080F0008794000087940000C99D0000C99D00007E
+:10810000239500004395000059950000C99D00008B
+:10811000C99D0000C99D0000C99D0000C99D0000C7
+:10812000FD95000011960000979C00004596000008
+:10813000C5950000C99D0000C99D0000B1960000D2
+:10814000BF960000D39600000D9400001D9700001C
+:108150002797000031970000C99D0000C99D0000CD
+:10816000E79700001598000023980000C99D0000C3
+:10817000C99D0000C99D0000C99D0000C99D000067
+:10818000C99D0000C99D0000C99D0000B584000084
+:10819000C1840000A98400006984000025960000C5
+:1081A00031960000C99D0000C99D0000979C000009
+:1081B000979C0000979C0000039900003D980000E8
+:1081C000C99D0000C99D0000C99D0000C99D000017
+:1081D000C99D0000F397000001980000DD960000A3
+:1081E000C99D0000C99D0000578C0000C99D00007A
+:1081F000C99D0000C99D0000C99D0000C99D0000E7
+:10820000C99D0000C99D0000C99D00005399000050
+:108210005D990000979C0000979C0000C99D00009C
+:10822000C99D0000C99D0000C99D0000C99D0000B6
+:1082300013940000C99D0000C99D0000C99D000065
+:108240002799000045990000C99D0000C99D0000C4
+:10825000C99D0000C99D0000979C0000979C0000EC
+:10826000EB990000F5990000C99D0000C99D000030
+:10827000019A00007D9A0000879A0000978800000C
+:10828000A3880000979A0000AB9A0000199E000096
+:10829000199E0000938A0000A18A0000C18A000094
+:1082A000CF8A0000C99D0000C99D0000BD9A000052
+:1082B000C99D0000C99D0000C59A0000ED9A00000C
+:1082C000C99D0000C99D0000C99D0000C99D000016
+:1082D000C99D0000C99D0000C99D0000C99D000006
+:1082E000C99D0000C99D0000C99D0000C99D0000F6
+:1082F000C99D0000339B0000C99D0000C99D00007E
+:10830000C99D0000C99D0000C99D0000739C00002C
+:10831000C99D0000C99D0000C99D0000699A000028
+:10832000739A0000FD830000FD830000C99D0000DA
+:10833000C99D0000C99D0000C99D00008D9B0000E3
+:10834000C99D0000C99D0000C99D0000C99D000095
+:10835000C99D0000B19B0000B19B0000C99D0000B9
+:10836000C99D000065910000D1910000DD910000E1
+:10837000E7910000F99100000B920000C99D0000F8
+:10838000DB9B0000EB9B0000F99B0000C99D0000F7
+:10839000C99D0000C99D0000C99D0000C99D000045
+:1083A000C99D0000C99D0000C99D0000C99D000035
+:1083B000C99D0000C99D0000C99D0000C99D000025
+:1083C0004F9C0000619C0000279C0000C99D00009C
+:1083D000C99D0000C99D0000C99D0000C99D000005
+:1083E000C99D0000C99D0000979C0000979C00005B
+:1083F0008D9D0000A19D0000B59D0000002101F0B1
+:108400009EBB002401F0B9BAC14B00243B6001F0CF
+:108410004ABD012300243B6001F045BD33685B7E0B
+:10842000002B41F0F38486F89F3186F8A231304664
+:1084300009F06AF830460EF04BDD30460EF036DEBD
+:108440003268137E002B41F0DF84136F13F0030FAB
+:1084500041F01D8513F0040F41F0D68413F0080F8E
+:1084600001F0DD8401F0D0BC33685D7E002D41F069
+:10847000CD84012486F8A241304609F045F886F8FB
+:108480009F41304608F072FC2C4601F00CBD0123E0
+:1084900086F89F3133685C7E002C41F0B584B0686B
+:1084A000FAF752FE01F0FFBC336800241B7E3B60EC
+:1084B00001F0F9BC96F8293000243B6001F0F3BCD0
+:1084C00031680B7E002B41F0CB844C7E002C41F0B8
+:1084D000DE8411463069079235F06AD9079A86F82A
+:1084E000292001F0E0BC3368002493F82C303B6075
+:1084F00001F0D9BC336883F82C2096F82930002B82
+:1085000001F0828430461BF0EBDA002401F0CBBC92
+:1085100096F8C83100243B6001F0C5BC86F8C8213C
+:1085200086F8CB21304608F0EFFF96F82930002B73
+:1085300001F06A8430461BF099DA30461BF0D0DA3D
+:10854000B0688C9907F0C4DD304620F0CBDF002402
+:1085500001F0A9BC40461AF083D810F0006F2AD071
+:1085600010F4000F00F4E06310D01B0A043B012B51
+:10857000684900F07F0004D8142300FB0313DA6875
+:1085800014E0142300FB03139A680FE01B0A043B5A
+:10859000012B604900F07F0004D8142300FB031373
+:1085A0005A6803E0142300FB03F35A584FF4FA739C
+:1085B000B2FBF3F007E000F07F034FF4FA7203FB25
+:1085C00002F3B3FBF2F00024386001F06CBC3368B6
+:1085D00000245B683B6001F066BC98F81230002410
+:1085E0003B6001F060BC98F8063013B1002D01F03B
+:1085F0002284D6F840252B1E18BF0123002482F8C0
+:10860000343001F050BCB8F95E300BB1022004E008
+:10861000B8F95C30181E18BF01200024386001F042
+:1086200042BC022D0AD14FF000014FF0010200249C
+:10863000A8F85C10A8F85E2001F035BC2B1E18BF0E
+:108640000123A8F85C3000244FF00003A8F85E3046
+:1086500001F029BCB8F80630002B01F0E983B9F12C
+:10866000050F41F3F483384608F1BC010622F9F303
+:1086700083F4002401F017BC98F80440002C41F06A
+:10868000EF83B9F1050F41F3E28308F1BC003946ED
+:108690000622F9F371F496F82930002B01F0B48327
+:1086A000404620F09DD901F0FEBBB9F1230F41F304
+:1086B000CE83384600212422F9F3C2F498F80650FC
+:1086C0005DB198F8192008F11A0147F8042B3846D3
+:1086D000F9F352F4002401F0E6BB98F80740381D86
+:1086E00054B1089C237A04F109013B60227AF9F322
+:1086F00043F42C4601F0D7BBD6F84025137A02F19B
+:1087000009013B60127AF9F337F401F0CCBBC046A3
+:10871000776CE41484188600B9F1030F41F3978352
+:108720003A68131D9945C1F29283202A03D96FF04C
+:10873000110401F062BB07F1040A3046514636F0DD
+:1087400011DE10B1404541F06A8398F806309BB1C4
+:10875000404651463A6836F00FDA3046414636F028
+:108760008FDB98F819303BB13046414636F03CDD9E
+:108770000446002841F0418398F80630002B41F070
+:108780004383B9F1310F02D819461A4619E07A8DA0
+:1087900022B1FB6A13B90125FA6200E000253046D8
+:1087A00007F12C01A9F12C020AF034DC04460DB1CA
+:1087B0000023FB62002C41F0208307F12402A9F181
+:1087C00024013B683046009201915246414631F007
+:1087D000CFD8002401F067BB336B18690AF0A6F903
+:1087E000C0B2386098F807301BB1089991F8323060
+:1087F00003E0D6F8403593F832300024D6F868010B
+:108800007B60BC608379002B01F0FE824BF09CDF23
+:10881000C0B2B86001F047BB0E2DCCBF4FF4805200
+:108820004FF40052E02D03D96FF0120401F0E5BAC5
+:1088300045F4306342EA03039DB2D6F85C01294651
+:108840003DF0ACDD18B96FF0130401F0D6BAD6F8DC
+:10885000403532685D86137E002B01F0D58292F898
+:108860003F40002C41F0D082336B18690AF05EF96A
+:10887000A84201F0C9822946304620F091DA3046FC
+:1088800008F0B0FF3046294620F0D0D8304619F025
+:10889000B7DB01F008BB96F8683700243B6001F0B5
+:1088A00002BB642D01F2BE8286F8685730699DF8DC
+:1088B000301235F021D833681B7E002B01F0A482E2
+:1088C000D6F868319D79002D41F09E82304608F03F
+:1088D00089FF3046D6F85C410DF066D80146204647
+:1088E0003CF042DF304619F08BDB2C4601F0DBBA5E
+:1088F000D6F86036002493F907303B6001F0D3BA14
+:10890000304669B211F024D9041EC1F276828C9BE4
+:10891000D6F86026D37133681B7E002B01F06B8282
+:10892000304608F05FFF304611F054D93046D6F893
+:10893000AC1614F005D8304619F062DB01F05BBAD2
+:108940003368187E30B9D6F8603604469B793B60B0
+:1089500001F0A9BA336B89A918690AF065FA0446CF
+:1089600028B19DF8243200243B6001F09CBAD6F86F
+:1089700060369B793B6001F096BA6B1C042B01F2C8
+:108980005182B5F1FF3F01D103238C93D6F86036B5
+:108990008C9A00249A71336B9DF8301218690AF092
+:1089A00081FE01F080BA33681B7E002B01F0498202
+:1089B000B1F8E8339AB24DF6AD639A4201F02F82D6
+:1089C0004FF6FF739A4201F02A82C2F3401300244B
+:1089D0003B6001F068BAB6F83A3600243B6001F01B
+:1089E00062BA6B1EFE2B01F21D82A9B2A6F83A16DE
+:1089F0003069B6F83C2634F029DEB6F82032B6F8F5
+:108A00003A2623F00F031343A6F82032B6F8223299
+:108A1000304623F00F031343A6F82232B6F824326F
+:108A2000002423F00F031343A6F82432B6F82632AD
+:108A300023F00F031343A6F8263212F053D801F0A7
+:108A400032BAB6F83C3600243B6001F02CBA6B1EFB
+:108A5000FE2B01F2E781AAB2B6F83A16A6F83C2638
+:108A6000306934F0F3DD3146B1F82022B6F83C36F7
+:108A700022F4706242EA0322A1F8202206F10803E0
+:108A800002319942F0D1304612F02CD8002401F086
+:108A90000ABA336B0024B3F806313B6001F003BA25
+:108AA00096F82930002B01F0C9816B1EFE2B01F2D4
+:108AB000B9813046A9B220F023D8002401F0F3B9DF
+:108AC000336B0024B3F808313B6001F0ECB996F841
+:108AD0002930002B01F0B281A5F1FF03B3F5E06F5F
+:108AE00001F2A0813046A9B21FF0FEDF002401F0A0
+:108AF000DAB996F95C3600243B6001F0D4B96B1CFE
+:108B0000012B02D9012D41F08D81002486F85C569D
+:108B100001F0C9B9336800241B6F3B6001F0C3B991
+:108B20002A0C01F07F8122F00303002B41F07A81AF
+:108B3000A9B221F00303002B41F07481D04310EA65
+:108B4000010441F06F813268136F00EA03030B43A5
+:108B5000304613670EF0BCD930460EF0A7DA01F0AC
+:108B6000A2B9336B00241B893B6001F09CB998F8D3
+:108B7000603000243B6001F096B9002488F8602042
+:108B800001F091B9832D01F2508106EB8503B9F113
+:108B9000A30FD3F8804241F35A8145AD2846002106
+:108BA000A422F9F34DF2002C42D0E37947A82B60C0
+:108BB000226904F114016A60F9F3DEF1237A61930A
+:108BC00096F8A0349BB9D8F8583013F0080F0ED19E
+:108BD000237A0B2B08D196F8F03743B196F8F1378A
+:108BE0002BB1A379072B02D8A379292B03D9629B38
+:108BF00043F001036293638913F0020F03D0629B79
+:108C000043F002036293638913F0200F03D0629B49
+:108C100043F010036293638913F0100F03D0629B3B
+:108C200043F0200362936CA821460622F9F3A4F1D5
+:108C3000384645A9A422F9F39FF1002401F033B985
+:108C4000A549012330460097CDF804900293CDF852
+:108C50000CB000F096BFB9F1070F41F3F880304631
+:108C600036F08EDD80450BD08C9B032B01F2DD802E
+:108C700008EB83035B6F002B01F0D7809B798C930B
+:108C80008C9B832B01F2D18006EB8303D3F88042C7
+:108C9000002C01F0CA802369002B01F0C680B8F8CF
+:108CA000623013F0010F08D02046F9F355F620B1D9
+:108CB000B8F86C30D8F8680003E0B4F8B830D4F8ED
+:108CC000B4008DF818321B0A8DF81932030A8DF89A
+:108CD0001B32030C00248DF81A028DF81C3286A971
+:108CE000030E082238468DF81D328DF81E428DF88D
+:108CF0001F42F9F341F101F0D6B8336893F83F30E1
+:108D0000002B41F0B380D6F86801837923B10421A8
+:108D100007924BF04DDC079A96F8723286F850278E
+:108D200086F85925002B41F06F80D6F85C011AB106
+:108D300006F5AA610E3102E006F5AA610A313DF09E
+:108D400011DA01F057B896F8503700243B6001F073
+:108D5000AAB80325304639464A4600230095CDF887
+:108D600004800BF0BBD8044638B110F1190F01F0A4
+:108D70004480C6F8245501F040B80223C6F82435D3
+:108D800096F8F437C6F8285523F0010386F8F4372F
+:108D900001F089B8B9F10B0F41F23E803B680B2B13
+:108DA000899341F239804B45C8BFCDF82492899B05
+:108DB00030460C3B8993394689AAD6F8243510F001
+:108DC000EDDB01F017B896F829303BB933681B6F1B
+:108DD00013F0040F01F0328001F016B898F8064045
+:108DE000002C41F028803046414636F049D801F049
+:108DF0005AB833681B7E002B01F02380B9F1050FB0
+:108E000041F22580B9F10D0F0CD9304607F1080168
+:108E1000A9F108020AF0FED83D460446002840F0B9
+:108E2000EC870AE082AC204639460622F9F3A4F02A
+:108E3000002384934FF00E09254698F80640CCB9DC
+:108E40000A9AD2F8901039B1706892F89420FDF324
+:108E50004FF70A9BC3F890400A9C494684F89490C7
+:108E60007068FDF335F7C4F8900018B129464A46FA
+:108E7000F9F382F02946404632F028D90A9904468F
+:108E8000D1F89030002B40F0BF8700F0B4BF002332
+:108E90000093304639464A468BABFAF7F5F904465B
+:108EA000002840F0AA878B99032900F0ED87326BE8
+:108EB0001368994204D1D2F8F0303B6000F0F3BF60
+:108EC0005368002B14BF38233C23F358D3F8F030F9
+:108ED0003B6000F0E8BFC0467B7286000023009331
+:108EE000304639464A468BABFAF7CEF9044600289D
+:108EF00040F083878C9A02F16403672B00F292871B
+:108F00008B99032904D0336B1B68994240F0CB87BF
+:108F1000002A04DB3046316B32F01CDA0246336B38
+:108F2000C3F8FC20C3F8F02000F0BDBF002300937D
+:108F3000304639464A468BABFAF7A6F90446002874
+:108F400040F05B878B99032900F09E87326B136892
+:108F5000994204D1D2F8F4303B6000F0A4BF5368CA
+:108F6000002B14BF38233C23F358D3F8F4303B6074
+:108F700000F099BF00230093304639464A468BAB38
+:108F8000FAF782F90446002840F037878C9A642A61
+:108F900000F27A878B99032904D0336B1B689942BE
+:108FA00040F08187336BC3F80021C3F8F42000F050
+:108FB0007ABF0A9A0024D36A3B6000F074BF0A9B10
+:108FC0000024DD6200F06FBF98F83A3000243B6067
+:108FD00000F069BFBB49012330460097CDF80490EB
+:108FE0000293CDF80CB000F0CCBDD8F84C2006248C
+:108FF000531C03FB04F39945C0F2298747F8042B5F
+:10900000D8F84C20384602FB04F2D8F85410F8F394
+:10901000B3F7002400F047BF3B68402B00F2028703
+:10902000062403FB04F304339945C0F21087D8F8F3
+:10903000541049B1D8F84C2002FB04F20432FDF37D
+:1090400057F60023C8F84C303968706801FB04F10A
+:109050000431FDF33DF6C8F8540018B96FF01A0456
+:1090600000F0CBBE57F8042BC8F84C20394602FB61
+:1090700004F2F8F381F7002400F015BFD8F850305F
+:1090800000243B6000F00FBF0024C8F8505000F0EF
+:109090000ABF98F807301BB1089C04F1380203E0BE
+:1090A000D6F8403503F1380211680B1D9945C0F21E
+:1090B000CE8647F8041B3846111D1268F8F35CF79A
+:1090C000002400F0F0BE78AC282200212046F8F3FE
+:1090D000B7F73046214614F0A9DC789A131D99455C
+:1090E000C0F2B58647F8042B211D3846F8F344F743
+:1090F000002400F0D8BE3A68131D9945C0F2A78637
+:10910000102A00F2AA8678AC002128222046F8F323
+:1091100097F757F8042B201D39467892F8F32CF76F
+:10912000336893F8463013F0030F0ED098F80730E9
+:1091300004F115001BB1089A02F14D0102E0D6F8C6
+:1091400040154D311022F8F317F7304678A910F08A
+:109150008BDC0446002840F0508630460DF04AD89B
+:1091600000F0A1BE6DB100243046414623222346C3
+:109170000094019402940394049413F0CFDC00F063
+:1091800092BE98F806303BB9D6F8680104214BF03E
+:109190000FDA40462FF0DADAD6F878122B467068EC
+:1091A000043101220095F9F34DF698F8063043B9E1
+:1091B000404601212A462B4602F0ACFF2C4600F027
+:1091C00072BE3046414635F05BDE2C4600F06BBE89
+:1091D000D6F84C3500243B6000F065BE0024C6F88C
+:1091E0004C5500F060BE384606F5AA610622F8F339
+:1091F000C3F6002400F057BE06F5AA6039460622E1
+:10920000F8F3BAF6002400F04EBE304641460AF0AC
+:1092100089DF002400F047BE98F8060058B998F896
+:10922000123043B198F807302BB1089CE38D044607
+:109230003B6000F038BED6F840350024DB8D3B6043
+:1092400000F031BE6A1E4FF6FE739A4200F2EA85C4
+:10925000D6F840350024DD8500F025BE98F80600DC
+:1092600060B998F812304BB198F8073033B10899CB
+:10927000044691F860303B6000F015BED6F84035EA
+:10928000002493F860303B6000F00DBE6B1EFE2B97
+:1092900000F2C885D6F84035002483F8605000F00D
+:1092A00002BE3A6845F2AB539A420FD106490023F9
+:1092B00030463B600097CDF804900293CDF80CB097
+:1092C0000DE0C046AB728600DD7286000023A04927
+:1092D0000097CDF804900293CDF80CB030463A4692
+:1092E0004B4600F050BC0B9A002413783B6000F012
+:1092F000DABD022D00F293850B9B1D7033681B7E37
+:109300004BB140460DF062DCD8F8E4325B8B13B110
+:1093100040461BF043D90B9C637E0BB18C9B33B949
+:109320008C994046003918BF012107F079FF40466B
+:109330001CF05CDB0146404622F000DC404631F088
+:10934000B7DF002400F0AFBD304639464A46FAF791
+:1093500079F800F04FBD316891F830300F7E1BB1C5
+:1093600015B96FF0190400E0002491F8953013B19D
+:10937000002D40F08F85002C40F03F8591F82F3074
+:10938000934200F0908527B1B0680792F9F7DCFEB0
+:10939000079A3368304683F82F20414636F0F8D9D3
+:1093A000326892F8443023B192F82F300BB182F832
+:1093B0004440304612F004DD002386F8DD3186F8A3
+:1093C000DE311FB1B068F9F7D7FE0446304608F029
+:1093D0009BF800F010BD3368002493F82F303B60F9
+:1093E00000F061BD5B49002230460097CDF8049043
+:1093F0000292CDF80CB0C5E35649012330460097E0
+:10940000CDF804900293CDF80CB0BAE304238C930A
+:1094100004E0B9F10B0F40F31A85043798F80630D1
+:10942000002B30D13B78304613F0010F39463D46D2
+:1094300018BF08F1BC054CF0B1D9044628B1436807
+:1094400013F4805F01D04BF02FDF98F81230002B1F
+:1094500000F0DA84002140460A460B4602F05AFE2C
+:1094600054B1BDF830323046019329462A4608F1FE
+:10947000C20300941EF086DD3046414635F000DD23
+:10948000002400F010BDAAF179033846DDF83092CF
+:10949000012B8CBF01251025F9F34EF2BAF1790F9B
+:1094A00014BF4FF0000B4FF0010B044638B3D6F851
+:1094B00000058AA94BF00EDE19E0D2F8F030B3B9FE
+:1094C0001369434513D1102D03D1137E13F0020FFE
+:1094D00004E0012D03D1137E13F0010F07D03046B5
+:1094E00041465B460095CDF804904BF00BDF8AA80F
+:1094F0004BF0F8DD02460028DFD100F085BC304695
+:1095000039464CF04BD90246002800F07D843046A5
+:1095100041465B460095CDF804904BF0F3DE00F039
+:10952000C2BC98F8070028B1089900240B8E3B6054
+:1095300000F0B9BCD6F8403504461B8E3B6000F005
+:10954000B2BCD6F8403500241D8600F0ACBCC04645
+:10955000E3728600E8728600002F00F05D84B9F1A6
+:109560000C0F1FD13B79391D13F0010440F05484D6
+:1095700030464CF013D938B1012386F82D374BF023
+:10958000A3DE386000F08FBC98F8060018B16FF0C9
+:109590001D0400F032BCD8F8E03204461B693B6081
+:1095A00000F081BCB9F1040F40F0368498F8060051
+:1095B000002840F03184D8F8E03204461B693B6053
+:1095C00000F071BC304620F0B9D93368D3F88C0074
+:1095D000036C3B60836C7B60D0F8D831BB60D0F803
+:1095E000B03102699B18B9F1130FFB6040F30C8492
+:1095F000D0F83C3100243B6100F055BC9D4900226D
+:1096000030460097CDF804900292CDF80CB0B9E244
+:109610009849012330460097CDF804900293CDF885
+:109620000CB0AEE2B8F8623000243B6000F03BBC06
+:109630009149012330460097CDF804900293CDF86C
+:109640000CB09EE2832D40F30284336B3D1D1869FC
+:1096500009F0FCFB089A4FF0000982F861008C9B2E
+:109660003046043B08992A46CDF8009009F0EEDD1B
+:10967000AB6F84333B6098F80630002B00F0C48356
+:1096800007F11704204649462022F8F3D9F498F848
+:1096900019202046AA7408F11A01F8F36DF407F1B5
+:1096A0000C0008F1BC010622F8F366F44C46FAE31C
+:1096B00001233B60336B00241B687B60F3E396F867
+:1096C0009C310BB9184601E0336B186800243860F0
+:1096D000E9E33046294612F053DC8BE3B9F1020F7F
+:1096E00040F3B583336B188968B1022801D1653026
+:1096F0000FE0052801D167300BE0042801D16A3062
+:1097000007E0072801D1613003E0082814BF3F209B
+:10971000632000231C4638707B70C4E396F8433600
+:1097200000243B60BFE396F9473600243B60BAE370
+:109730006B1C012B02D9012D40F07483EAB2316811
+:1097400086F84726087E48B191F83F40002C40F04B
+:109750005B833046214620F0A9DDA4E351B2B1F18C
+:10976000FF3F03D1044686F843069CE3012914BF5A
+:1097700000230123044686F8433694E396F84836DE
+:1097800000243B608FE396F84836934200F03C8318
+:10979000336886F8482693F82F30002B00F0348386
+:1097A00096F82930002B00F02F83304621F0AEDBF5
+:1097B0003046012121F0B4DD002474E3306B0368EE
+:1097C000022B40F02183437D00243B606BE3336830
+:1097D00093F83F30002B40F049833046E9B2012234
+:1097E0001FF0B4D906E3D6F8583600241B783B6046
+:1097F00059E3D6F85836002493F903303B6052E31E
+:10980000022D00F20F83304604216AB21CF0B0D85A
+:10981000002448E3D6F85836002493F901303B6021
+:1098200041E36B1C012B02D9012D40F0FB82304635
+:1098300002216AB21CF09CD8002434E3B9F1270F4E
+:1098400040F30583282278A83946F8F395F3789CED
+:10985000102C00F20883336B5B7D002B00F0FA8242
+:1098600064B906F5AE600C3021462822F8F3E8F31F
+:1098700019E3C046177386001C73860033686EAC0C
+:1098800093F84630214613F0030317BFD8F8CC30C5
+:109890001846C3F3003383F0010000227F230093B6
+:1098A0000190134678A847F027DCD6F860360022EE
+:1098B0009B782046AC4947F061DB789A6E9B9A42D0
+:1098C00040F0D18206F5AE6028220C302146F8F334
+:1098D00053F33268137E002B00F0968292F82F30FB
+:1098E000002B00F0918292F83F30002B00F08C8228
+:1098F000304621F00BDB3046012121F011DD002440
+:10990000D1E2336B5B7D002B00F0A482B9F1270F0D
+:1099100040F39D8206F5AE6138460C312822F8F3FB
+:109920002BF30024BFE225B1022D02D0012D40F01F
+:109930009182D8F8E832404683F8E05030F046DFB4
+:109940000024B0E2D8F8E832002493F8E0303B601D
+:10995000A9E2B6F87A3500243B60A4E23368187EA9
+:10996000002840F07D824FF6FE739D4200F25A823D
+:109970000446A6F87A5596E201344C4502DAE35DD6
+:10998000002BF9D1032C00F3688288AD002104225A
+:109990002846F8F355F3224639462846F8F308F4EA
+:1099A000D6F85C0129463CF0DDDB0446002840F097
+:1099B000248230460DF07ADB06F5AA600A3029468B
+:1099C0000322F8F3F5F386F859456CE2B9F1030F79
+:1099D00040F33D82D6F85C013BF05EDE0422014696
+:1099E0003846F8F3C9F200245DE2D6F80C350024BD
+:1099F0003B6058E233681B7E002B00F0228229E294
+:109A0000B9F1030F40F32382A9F1040399083B68DD
+:109A10008B4288BF396000252C460E2C8CBF4FF43A
+:109A200080514FF4005144F430631943D6F85C017F
+:109A300089B23CF0B3DC10B10DAB5C55013501349B
+:109A4000E02CEAD13B68AB4201D3002107E03D6046
+:109A5000FDE10DAA8A5C07EB81035A600131A9423E
+:109A6000F7D100243D601EE2304639463BF064DF0A
+:109A7000C0E13046394608F0DDFCBBE196F8CE3156
+:109A800000243B600FE286F8CE21304600210AF028
+:109A90005FDF002407E23368114683F84120336B0F
+:109AA0000024186909F0A6F9FDE13368002493F851
+:109AB0004130003B18BF01233B60F4E133680024D0
+:109AC0003B60F0E1D8F87030B3F1FF3F00F0AD81BA
+:109AD00008EB8303586F002800F0A781C3790024A6
+:109AE000AB4214BF002301233B60DCE140466FF032
+:109AF00007040025416FB9B1CA798C9B9A4213D1F2
+:109B0000D8F87030B3F1FF3F07D008EB83035A6FEA
+:109B10001AB1538923F0020353814B89C8F870505E
+:109B200043F002034B81002401350430042DE1D1C0
+:109B300061E1B9F1090F40F38A8185E101314945BD
+:109B400000F08581CB5D002BF8D1A6E100230293C4
+:109B5000304639463A19C4EB09030097CDF8049012
+:109B6000CDF80CB00FE0C0460C1886003B19C4EBD2
+:109B700009020093012301920293CDF80CB0304604
+:109B800039460022134619F00BDC33E198F8063011
+:109B9000002B40F0598198F81130002B00F05481CF
+:109BA000D8F80C00394698F8072013F0B9FB21E1EA
+:109BB00019F0010440F0308101230293AD49AE4B0E
+:109BC00040F21312924518BF1946304622460097BC
+:109BD000CDF80490CDF80CB0D4E73846B16B4FF413
+:109BE0008672F8F3C9F100245DE138460899AC2289
+:109BF000F8F3C2F1002456E1099C099AA36B516B5A
+:109C000047F8043B926B3846F8F3B6F1099B099C80
+:109C10009A6B5B6CB818BB50216C626C0430F8F323
+:109C2000ABF100243FE1336893F83F30002B00F0A4
+:109C3000FF800899002900F0FB80496E002900F0A0
+:109C4000F78038460822F8F397F100242BE1089AB0
+:109C5000384602F16B011022F8F38EF1002422E164
+:109C6000089B384603F17B011022F8F385F10024AC
+:109C700019E133681B7E002B00F0E3803046394643
+:109C80004A460AF065DFB5E033680121186901F042
+:109C90000DDB002407E1304651464A463B46F9F7C2
+:109CA00017FB0446002840F0A880BAF13C0F49D1C8
+:109CB0003D1D00F0AE807B6813F0006F40F0A9807E
+:109CC00003F07F03022B06D0042B04D00B2B02D011
+:109CD000162B40F09E806EAC3046214613F0A6DE77
+:109CE000304621461CF01ED8286810F0006F26D0A0
+:109CF00010F4000F00F4E06310D01B0A043B012BAA
+:109D00005E4900F07F0204D8142302FB0313D868D5
+:109D100017E0142302FB0313986812E01B0A043BAC
+:109D2000012B564900F07F0204D8142302FB0313D1
+:109D3000586806E0142302FB03F3585801E000F0D2
+:109D40007F002860336B514618698CAB0733009352
+:109D50004A463B460AF0B4F9BAF13C0F044608D033
+:109D6000BAF15C0F05D0BAF14A0F02D0BAF15D0F1B
+:109D700041D1002C41D1002F00F095803B68326822
+:109D8000003B18BF012382F840308CE03C490022A0
+:109D900030460097CDF804900292CDF80CB0F1E671
+:109DA0003749012330460097CDF804900293CDF84F
+:109DB0000CB0E6E63349012330460097CDF8049015
+:109DC0000293CDF80CB0DCE6D6F8680151463A466D
+:109DD0004B46CDF800B04AF0C9DC10F1170F04462D
+:109DE00009D1D6F8340751463A464B46CDF800B073
+:109DF00029F030D90446002C55D004F12A032A2B2F
+:109E000002D83368DC664EE000244CE06FF00804B2
+:109E100049E06FF0010446E06FF00104EDE74FF018
+:109E2000FF34EAE76FF01C04E7E76FF00704E4E7AC
+:109E30006FF01004E1E76FF00604DEE76FF00A044C
+:109E4000DBE76FF00304D8E76FF01604D5E76FF097
+:109E50000D04D2E76FF00C04CFE76FF00E04CCE7EF
+:109E60006FF00404C9E76FF00B04C6E76FF01B0442
+:109E7000C3E7C0467ED701002F7386008418860092
+:109E8000507386005D7386006FF00204B5E76FF0D3
+:109E90000804B2E76FF01904AFE74C1CBAF5837FF2
+:109EA0003FF454AE62E620460DF50F7DBDE8F08F1D
+:109EB0002DE9F341089C05460E4617469846009446
+:109EC00007F0A6FD10F1170F06D1284631463A4695
+:109ED00043460094FDF788FFBDE8FC812DE9F04181
+:109EE0000368054693F83F30D0F80C8013B1B0F802
+:109EF000267602E0FAF70CFF074600222869394669
+:109F000003F0E2F85621286933F08ADBD5F888316E
+:109F10004000002BC5F8040506DA2869B22133F0A9
+:109F20007FDB4000C5F80805A221286933F078DB03
+:109F30004000C5F8EC07284612F03AD895F8CD3124
+:109F40003BB928694C2133F06BDBC0F3C71085F8AF
+:109F5000CD0128461CF092DDD5F84C0104F02EFD11
+:109F600028463DF05FDA002605EB8603D3F84C4225
+:109F70002CB120461EF03EDF20461EF031DD0136BA
+:109F8000082EF1D12B6893F83F309BB1002205EBEE
+:109F90008203D3F84C0250B1037943B1D0F8D432E4
+:109FA000DB8D1B04C8F888311FF05CD902E0013258
+:109FB000082AECD12846394609F0AAD82846742147
+:109FC000B5F87A2522F006D995F8D13142F210720F
+:109FD000002B18BF4FF4BC622846822122F0FAD829
+:109FE0002B6B95F8D111186909F04AF80122134634
+:109FF000B5F8781728460AF063DA0123B5F87A171E
+:10A00000002228460AF05CDAD5F8400125F0D8DBBA
+:10A010002846F9F7E9FA2B685B6B5BB1B8F888362C
+:10A02000D5F86C029BB243F00403A8F888360021EF
+:10A0300017F0B6DE2846F9F77BFAD5F8841161B936
+:10A0400028461CF08DD80404C5F884412846022116
+:10A050001CF086D82043C5F884012B6893F8A13002
+:10A06000012B03D1D5F8400126F096DC284617F0E5
+:10A07000C7DF284608F0B6DBB5F85C1728461CF0A9
+:10A080004DDD284610F004DA424BEA68002185F8DD
+:10A090004410C2F8DC33012385F8A83185F8AA31D1
+:10A0A0002B6893F838303BB14A1901314FF0FF3338
+:10A0B000082982F89538F7D100244FF440763146CC
+:10A0C00028461CF04DD805EB4401B1F8203213F0BE
+:10A0D0000F0F06D123F00F0300F00F021343A1F876
+:10A0E0002032B1F8202212F0F00F06D100F0F00378
+:10A0F00022F0F0021343A1F82032B1F8202212F42A
+:10A10000706F06D100F4706322F470621343A1F8FB
+:10A110002032B1F820321A0B06D11B0500F4704230
+:10A120001B0D1A43A1F8202201340236042CC6D19B
+:10A130002B68284693F94C100BF076DA2A68137EC8
+:10A1400003B392F82F30EBB1002605EB8603D3F86A
+:10A150004C426CB1A3795BB12B6893F838302BB1CA
+:10A160002846D4F84C15002235F0F2DD0023E371C7
+:10A170000136082EE9D1002385F87232D5F834076C
+:10A180002AF0C8DDD5F8680104214AF011DABDE8EB
+:10A19000F081C0468096980003681A6819B10123BF
+:10A1A00082F8AA3001E082F8AA1070472DE9F04742
+:10A1B0001746937AD27A056843EA022A3B79064623
+:10A1C00003F007044FF0000938E00B6968681A785B
+:10A1D0005B7842EA0328D6F87822936E01339366BF
+:10A1E0000122FCF39DF52B6893F8A130012B03D0DD
+:10A1F000C8F34123032B17E0182304FB0362B2F8D2
+:10A200008232B2F88612284699420CBFB2F88032E8
+:10A210004B1CA2F886322146012220F0E5DB09F131
+:10A2200001031FFA83F9D1450AD02B69022103EB00
+:10A230008403D868124B9B6B984701460029C4D110
+:10A240002B6893F8A130012B05D02846214696F9BA
+:10A250002C2020F0C9DBBB7913F0020F0ED00024B4
+:10A2600006E00120FCF378F2631CDCB20B2C05D075
+:10A27000EB68D3F8703113F0010FF2D0BDE8F0872E
+:10A28000E0A685002DE9F347D0F80090044601A927
+:10A29000D9F800054AF01EDF00263AE07B6813F487
+:10A2A000802F36D063684FF00008FD58AA46D5F8D5
+:10A2B000F8205FFA88FE32B391781379002918BF2D
+:10A2C00001261BB100231371D3701CE0D9B1D378E0
+:10A2D0000133D9B2D1707B6813F4807F14BF628ED2
+:10A2E000A28E6423B2FBF3F291420BD3D4F878220E
+:10A2F0004846D2F8C43051460133C2F8C4307246E1
+:10A3000023F030DF012608F101080435B8F1080F09
+:10A31000CDD101A84AF0E6DE07460028BED136B905
+:10A32000236884F8A3639868A16B05F097D9BDE80A
+:10A33000FC87C0464368F7B5CE5805460027FCB2F7
+:10A3400028463146224622F0DBD901370123284630
+:10A350003146224622F040D9082FF0D12A68002346
+:10A360000093506806F110010122F8F36BF5FEBD71
+:10A37000D0F8AC037047C046D0F8C0037047C04661
+:10A38000C0F8C0137047C046D0F8AC331B68DB6917
+:10A3900018690528A8BF05207047C0462DE9F04F71
+:10A3A000F3B00890894608999DF8F8010792D1F812
+:10A3B000B0231C46D9F8D4320690D1F8AC730C9275
+:10A3C000002148A828226F9115937C9DDDF8F48127
+:10A3D000F7F336F607980C99037803F0FC03202B6B
+:10A3E00014BF002301230D9391F82F3033B1D7F818
+:10A3F0006801837913B104214AF0DAD80D9A0AB1C1
+:10A40000092D00E0032D40F2E58522786378211DB7
+:10A4100042EA032AA278E37842EA03230E930D9BD3
+:10A4200023B9043D8B4613950F9304E00A3D04F1D4
+:10A430000A0B13950F911398012840F2CB859BF8D6
+:10A44000013002339842C0F2C58548AB00933846CC
+:10A450005946139A002319F059DE002840F045832D
+:10A4600097F838279DF834319A4240F03E8399F8A6
+:10A4700019309BF801209A4240F03E8309F11A00FE
+:10A480000BF10201F7F35CF5002840F0358398F8F2
+:10A49000183013F0020F0BD098F8DF3023B1384694
+:10A4A000414601222BF0CEDC4046FE214AF0C8DDB9
+:10A4B00099F94820002AC0F21F8398F8183013F049
+:10A4C000010F00F01983082392FBF3F34344197D35
+:10A4D000A44B02EA0303002B05DA013B6FEA437346
+:10A4E0006FEA5373013351FA03F313F0010F00F0D5
+:10A4F000038319A80021C8F81090A8F800A101381A
+:10A500006D22F7F39DF50024214613E072AA53183B
+:10A5100013F8A43C03F07F026C2A0AD89248835CAB
+:10A520003BB119AB013B9A54835634EA230428BF4C
+:10A5300001240131489B9942E8D3D8F8043023F034
+:10A5400007023B6BC8F804205B7D23B11CB942F0C5
+:10A550000103C8F804303B6B5B7D43B11AF4806F94
+:10A5600005D1D8F8043043F00203C8F804301AF0DB
+:10A57000200405D0D8F8043043F00403C8F80430B0
+:10A58000159B0021986B0FE0159A531893F83C2007
+:10A5900012F0800F07D019AB013B02F07F029B5CE9
+:10A5A000002B00F0A28201318142EDD10C9890F88D
+:10A5B000463013F0030F45D05946139A38461BF026
+:10A5C0009BDD00260546414638462A46334600961E
+:10A5D00018F00CDBB5B14DA8E91C01301022F7F3DF
+:10A5E000CBF431467B1872A893F8EB24431813F888
+:10A5F000933C02EA0303934240F077820131102931
+:10A60000F0D105E00C9991F84730002B40F06D82B5
+:10A6100038465946139A43461BF0D8D83B22584631
+:10A620001399F8F34BF0024660B141784B1EDBB250
+:10A630001E2B07D888F80B1108F58670911C5278EC
+:10A64000F7F39AF4B9F862200023A8F83C20C8F880
+:10A650004030B9F8623033B1D9F8582040F237139E
+:10A6600002EA030343B9D9F8583013F0400003D18C
+:10A670000646119016905EE0139B58461946CDF899
+:10A68000C0B16E9326F02EDD119038B14378042BC3
+:10A6900040F239820020064616904CE070986E9980
+:10A6A000F8F318F6119050B108F1400300930898A0
+:10A6B0004946119A08F13C0327F092DD10E0584614
+:10A6C00013993022F7F3FAF770B1119008F14003B3
+:10A6D000009308984946119A08F13C0327F08CDC56
+:10A6E000002840F0108223E0584613994422F7F3E3
+:10A6F000E5F7119080B108F14003009308984946AE
+:10A70000119A08F13C0327F0D7DB002840F0FB81C9
+:10A7100001210E4616910EE0D9F8583013F0410F82
+:10A7200000F0F181119A1646A8F83C20169202E03A
+:10A73000002301261693D8F8043023F4001323F0E5
+:10A740004003C8F804303B685B6B002B3AD0D9F863
+:10A75000CC3013F0020F35D11398CDF8C0B16E9004
+:10A760000BE0C04607000080401B860038462946A3
+:10A7700070AA6EAB18F0F2DE38B970986E99DD22CF
+:10A78000F7F39CF705460028F0D1404600211BF066
+:10A79000ADD9BDB1D8F8043043F04003C8F8043057
+:10A7A00097F8FA3173B14046297A1BF09FD998F88F
+:10A7B000D13013F00F0F05D0D8F8043043F4001354
+:10A7C000C8F8043000231399304A5846009317F014
+:10A7D00099DD4146024638461AF0D2DF1AF01005DC
+:10A7E0000DD0D9F8582040F2371302EA030333B9E9
+:10A7F00012F0400F00F08D81002E40F08A810C99FC
+:10A8000091F8303053B93B6B1B68022B06D197F996
+:10A810005C361BB914B94FF0130A24E03B6B1B687C
+:10A82000022B08D1089A53782BB11AF4806402D114
+:10A830004FF0190A17E0384611F074DB0899D1F887
+:10A84000C033984211D303230093079B002403F1E4
+:10A850000A0238461721012301940294039419F047
+:10A8600027D94FF0110A10945AE10C9890F838301B
+:10A8700073B13846494612F079D8D9F85035984224
+:10A8800006D300214FF0110A109149E148D401008C
+:10A890000C9A92F8463013F0030F27D0D9F85820BD
+:10A8A00040F2371302EA030303B397F8692712F063
+:10A8B000020F08D0D8F8043013F4803F03D0D8F842
+:10A8C0004030022B0BD012F0010F0FD0D8F804301B
+:10A8D00013F4803F0AD0D8F84030012B06D1002273
+:10A8E000384641461346009218F080D9D9F8CC304A
+:10A8F00013F4005F09D0D7F84C0141465A46139B28
+:10A9000003F0D8FE002840F00481D8F8043013F09A
+:10A91000010F02D0012387F84D36D8F8043013F028
+:10A92000011F02D1012387F84E36D8F8043013F402
+:10A93000801F02D0012387F85136D8F8043013F471
+:10A94000002F09D11598438E03F44063B3F5406F8F
+:10A9500002D1012387F85236D8F8043013F0020FE1
+:10A9600002D0012387F84F36D8F8043013F0040FD3
+:10A9700002D1012387F85036D8F8043013F4001FB1
+:10A9800002D0012387F8FB31D7F8344720462AF05C
+:10A9900091D930B120462AF095D910B120462AF03D
+:10A9A00063D9D8F8043013F0007F1DD0012487F854
+:10A9B00054460C9991F8463013F0030F14D091F9D6
+:10A9C0004C308BB10221384618F0CAD8159A538EF4
+:10A9D00003F44063B3F5406F06D138462AF002D83D
+:10A9E0003846214629F07ADFD8F8043003F40413FE
+:10A9F000B3F5001F02D1012387F853363B6B5B7D13
+:10AA000013B1384620F0E8DA0C9890F8463013F08D
+:10AA1000030F02D0384620F091DBD8F8403043B91C
+:10AA20003DB1D9F8583013F0010F02D00123C8F816
+:10AA300040300C99D9F8582091F838301BB9D7F824
+:10AA40006C32994524D0B9F8620008BB12F0010FAE
+:10AA50001ED0D9F87030B3F1FF3F19D009EB830352
+:10AA60005C6FACB1217A012901D0032910D1628930
+:10AA7000E379009204F11402029208F11A020191A2
+:10AA80000490059003923846494622693CF0F6DC72
+:10AA9000B8F8D4302BB9D8F8100034F081DDA8F81C
+:10AAA000D400B8F8D4200C98109290F8463013F0E7
+:10AAB000030F33D0D8F84030013B012B0AD8D8F827
+:10AAC000043013F4802F05D038464146062220F08A
+:10AAD000E7D823E0D8F8043013F4802F1ED038468E
+:10AAE0004146062220F080D818E000214FF0120ADB
+:10AAF00011911091169113E000224FF00C0A11925F
+:10AB0000109216920CE000234FF00C0A169310934B
+:10AB100006E000204FF00C0A109001E04FF0000A10
+:10AB20003EAC00212822204634ADF7F389F22846B6
+:10AB300000212822F7F384F2D7F87C3533B107F5EA
+:10AB4000AE6120460C312822F7F316F21599234600
+:10AB50003831099138464946099A00951BF076D953
+:10AB60003E9B03F10804349B0BB10233E418D8F880
+:10AB700004304846002BB8BF14340421002235F0BD
+:10AB800091DA97F8653604190BB10233E418D8F856
+:10AB900004300DF5A57013F0400F18BF1A340021D2
+:10ABA0002022F7F34DF2D8F8043013F4803F05D09B
+:10ABB000D7F8FC3434341B7803B11334D8F8083098
+:10ABC00013F0400F06D0D7F84C014146524645F0ED
+:10ABD00041DC2418079A09F1C2030A3217920D9A30
+:10ABE0000A9309F1BC006FAB0B9000900293002A0E
+:10ABF0000CBF102130213846179A0A9B019417F098
+:10AC0000DBDB1490002800F0E5816F980123041924
+:10AC100012940370013B43703B6B1B68022B05D100
+:10AC200097F95C2612B91F3303704270D9F8582087
+:10AC300040F2371302EA03035BB199F8603043B185
+:10AC40000378427843EA022343F0100303701B0A9F
+:10AC5000437097F843365BB13B6B5B7D43B1037840
+:10AC6000427843EA022343F4806303701B0A437073
+:10AC7000002380F802A0C370109B037110990B0A87
+:10AC80004371012106303FAB3E9A21F06DDAD8F8CE
+:10AC900004300646002B06DA0C21122207F5037356
+:10ACA00021F062DA0646349A2AB13046322135ABB9
+:10ACB00021F05ADA0646D7F8603648AC00229B7875
+:10ACC0002046099946F05AD9D8F8043013F4803F49
+:10ACD0003FD03B6B0DF5B5751B6804F11502022BD7
+:10ACE00014BF002301234846294661AC21F09ED9B8
+:10ACF0004846214621F0F6D830462D211A222B460F
+:10AD000021F032DA23463D21162221F02DDAD7F840
+:10AD1000FC3406461B78E3B172AB012203F8012D27
+:10AD20007F2121F021DAD7F8FC140DF5D574054602
+:10AD300024310E222046F7F31FF138462146002227
+:10AD400017F0EEDE28464A210E22234621F00CDAC7
+:10AD50000646129AB24201D2002002E0129BC6EBD4
+:10AD600003000423009001934846334600214FF02E
+:10AD7000FF3235F0D9D997F8653604462BB107F57F
+:10AD8000CC61043112F0C2DC0446D8F8043013F070
+:10AD9000400F08D007F500732046DD211822063346
+:10ADA00021F0E2D90446D8F8083013F0400F06D05D
+:10ADB000D7F84C0141465246234645F02BDB069816
+:10ADC0000023D9F808200090019302933846149983
+:10ADD000D26843461AF0A6DEBAF1000F40F0FA80BE
+:10ADE0001099159AA8F8D41092F860300E989BB27A
+:10ADF000834238BF0346A8F80231022140464AF098
+:10AE00007FDB404649464AF0C5DAD9F8CC3013F426
+:10AE1000801F09D03846494611F0A8DD012803D12A
+:10AE20003846494634F002D80C990D9A8B6AC8F816
+:10AE300024305AB10B980F990622F7F381F028B10C
+:10AE400008981799D9F8082027F0CEDBD9F8082000
+:10AE50000898179926F0CCDFD9F8CC2012F40053CB
+:10AE60000CBF1C4602243B6893F8463013F0030FD6
+:10AE700007D012F4805F04D1B8F8063003F0010265
+:10AE800000E000227F2300930192234648A808F1A6
+:10AE90004401002246F030D9384641464AF032D9C2
+:10AEA0000C9890F82F3063B1D8F8E81049B1C06819
+:10AEB000D8F8EC20FBF31CF70023C8F8EC30C8F8F6
+:10AEC000E830B9F86230002B33D0D9F8582040F27E
+:10AED000371302EA030363B312F0010F01D1119992
+:10AEE00039B398F8DE300BB1119AB2B90C9890F8DA
+:10AEF0002F30F3B11199E1B14978C0680231FBF309
+:10AF0000E7F6C8F8E800A0B1119B5A78194602325A
+:10AF1000C8F8EC20F7F330F00BE00224384608F1D3
+:10AF20001A010B9A0A9BCDF8008001941DF02AD8D3
+:10AF3000A246D9F8CC3013F4005F04D0D7F84C0106
+:10AF4000494644F0FFD938464946012216F0E8DF69
+:10AF500000231398009302930D9B0490002B0CBFC9
+:10AF600008220A2238464946179BCDF804A0CDF89E
+:10AF70000CB011F0D3DD169860B3D9F87030B3F18E
+:10AF8000FF3F03D009EB83035B6F13B90DF5CD725F
+:10AF900002E003F5997312E0362313700DF5CD71BD
+:10AFA00026335370023201F110039A42F4D10C9A05
+:10AFB00092F82F3013B137238DF89A310B46009356
+:10AFC000F12301933846494608F11A02D8F8E830CF
+:10AFD00020F0FAD973B0BDE8F08FC0462DE9F04FEC
+:10AFE000D0F8ACA3D1B0D0F8B00389469DF86C116D
+:10AFF0000890DAF86801079206911E4683799DF859
+:10B00000704113B1042149F0D3DA99F8063023B125
+:10B0100099F80430002B00F09B813278737842EA73
+:10B020000328B278F37842EA0323079A0993537806
+:10B030001B0213F4804040F07D81099B012B00F03E
+:10B04000828083460E2545E1DBF8D830002B00F0E6
+:10B050007F81F3789F0914B30AEB8703D3F88052FA
+:10B06000EDB12B69DBB12B7ACBB14CAC314603226D
+:10B070002046F6F381F705F114012A69E01CF6F386
+:10B080007BF729690DF12E05204603312A46FDF391
+:10B0900061F25A9A301D111F2A46FDF38BF2032FDD
+:10B0A00040D809EB87035B6F002B3BD01A695A9895
+:10B0B0003146143301F02ADF002833D0321D3179B4
+:10B0C000537841EA03289178D378B8F1010F41EA27
+:10B0D000032309931FD1032B1DD1B37A06F10A0272
+:10B0E000102B18D1DBF8D80006F10C010230527891
+:10B0F000F6F326F7044670B95846414699F94820B8
+:10B100004AF016DA8BF8DE805846414622464AF06D
+:10B110000FDA25460BE05846012199F9482049F0FD
+:10B1200099DF03E003234FF0010809930F25DBF8B3
+:10B13000D810089E4A78F0680232FBF3D9F5002354
+:10B14000CBF8D830C6E0D9F85050D9F84C60D9F8CF
+:10B150005410ADB10C46074609E00799062201F1EB
+:10B160000A002146F6F3ECF6063410B10137B74277
+:10B17000F3DB012D02D1B74206DB01E0022D01D045
+:10B18000002512E0B742FBDB03230093079B00245A
+:10B1900003F10A02504617212346019402940394B6
+:10B1A00018F086DC0125A346AFE0BAF8822144F20C
+:10B1B00021339A4214D00E3B9A4211D007339A425F
+:10B1C0000ED010339A420BD0143B9A4208D007336A
+:10B1D0009A4205D010339A4202D025339A4200D1C8
+:10B1E0000125079E504606F10A0421462A464AF0E8
+:10B1F000DFDA014610B150464AF0E2DA0135002D9F
+:10B20000D3DD504621464AF0E3DB8346002800F0B8
+:10B210009C8049464AF0BED8DBF8042012F4805FD7
+:10B2200009D0089991F83030002B40F08E8022F43C
+:10B230008053CBF80430504659461BF0CDDEB8F1B0
+:10B24000000F03D0B8F1010F16D041E0B9F95C301E
+:10B2500099F9482023B9584601214AF069D903E0F9
+:10B260005846012149F0F6DE9BF8183013F0010F23
+:10B2700069D000252C4632E0DBF8D81041B1089B9C
+:10B280004A78D8680232FBF333F50023CBF8D83084
+:10B29000B9F86250002D56D1089E8221F068FBF368
+:10B2A00017F5044608B945462FE0102303706FF0E8
+:10B2B0007F0343702946DAF80C30B3F85A26631836
+:10B2C000013180299A70F6D10025CBF8D84006E0EC
+:10B2D0000D2502E0099903293AD80024ADB9BBF144
+:10B2E000000F12D09BF8183013F0010F0DD0079EFD
+:10B2F00050464946042206F10A0300950195CDF80F
+:10B3000008800395049511F009DC0999069A4B1CF5
+:10B31000019300230393079B059203F10A0148461A
+:10B3200009F1BC025B46CDF80080029504941CF044
+:10B33000F3DC0DE0079A504602F10A014AF02EDADA
+:10B34000834628B180E60D2500E001250024DCE7D6
+:10B3500051B0BDE8F08FC0467FB5089D9DF82440F0
+:10B360009DF82860009501940296FFF737FE7FBD97
+:10B3700002292DE9F0410646D0F8AC5301D0002453
+:10B3800001E000F575742B68D3F88C205368126CBB
+:10B390009B1822692361C2EB0302A3699A422378B6
+:10B3A0000ED24BB9E26863699A4205D30123237038
+:10B3B00063680133636028E0E3680133E36024E0FD
+:10B3C0000027E7600BB3012904D1284602311EF0A3
+:10B3D00025DE18E0022916D1A868D6F8D01304F0AB
+:10B3E0003DD9D6F8CC3373B12B6893F87430012B68
+:10B3F00007D02869012132F063D82A68012382F836
+:10B400007430C6F8CC7300232370BDE8F081C046C9
+:10B410002DE9F04F97B0DDF894B0D0F8AC6300237D
+:10B42000D0F8B0930C460746594630460392DDF8F3
+:10B4300088A014931393129333F0DCDF039905462D
+:10B4400001F001030093484621465246239B17F022
+:10B450003BDF1490002840F00783219A032A0DD97E
+:10B46000042213A82099F6F387F5219B072B05D911
+:10B47000209A12A8111D0422F6F37EF5139C129A4D
+:10B48000B4F1000818BF4FF00108BBF1000F01D163
+:10B49000D5F808B003998B1E472B00F2E182DFE854
+:10B4A00013F0F900FE00010104016A007D008C0028
+:10B4B000DF028E00DF029700DF0207010A01480069
+:10B4C00058007F0195010D011F014E015401280212
+:10B4D000DF029900A000AD00B00033013601FC008E
+:10B4E000DF023E024202DF02DF02DF02DF02DF0292
+:10B4F000DF02DF02DF02DF02DF02DF02DF02DF0244
+:10B50000770289028E02E500EF00E202A402DF0268
+:10B51000DF02B402B702C002C302C602C902CC02F3
+:10B52000DF02DC02CF02DF02DF02DF02DF021402F1
+:10B530001B02D9F83430002B00F092820DAC30465B
+:10B5400007F56371224620F077DB50462146102232
+:10B55000C3E0D9F83430002B00F0828211AC5146A0
+:10B5600004222046F6F308F5304607F563712246BB
+:10B5700020F07EDB1FE0219A0023052A8DF857304A
+:10B5800040F22781384620990DF1570227F084DADE
+:10B590009DF8573014908AF8003064E251463046E6
+:10B5A0004AF0FCD80146002800F0268238469AF876
+:10B5B000062029F06FDC149055E29B4B00E09B4B7A
+:10B5C0000093384629465246239B27F0FFD9F2E7DD
+:10B5D000974BF5E7D6F83407FEF7CEFECAF8000021
+:10B5E00041E2D6F834572846FEF7CEFE844200F3F7
+:10B5F0002E8228462146FEF7C3FE34E2D5F85035A8
+:10B600003BE03368DB691F692B79002B40F06B81CD
+:10B61000BC4200F31C82C5F85045139C18461946DD
+:10B620007318D3F84C2222B1937913B1954218BF05
+:10B63000013004312029F3D1002800F01482C4EB3A
+:10B64000070393FBF0F000217318D3F84C224AB1A2
+:10B6500093793BB1954205D0D2F85035834288BFEB
+:10B66000C2F8500504312029EED1FCE196F9A83842
+:10B67000002B01DA002300E00123CAF80030F2E1D8
+:10B68000B8F1000F01D0002301E04FF0FF3386F83E
+:10B69000A838E8E195F83C30EFE7AB79EDE785F8BD
+:10B6A0003C80E0E1D6F82837E7E7C6F82847DAE13A
+:10B6B000D7F8BC33E1E7C7F8BC43D4E16A7E049213
+:10B6C00022B105A805F11A01F6F356F4049B1A1DE0
+:10B6D000239B93427DDB504604A9F6F34DF4C2E16F
+:10B6E000202C02D96FF01103BCE12399231D99424C
+:10B6F0006FDB2B79002B40F0F68028460AF104011D
+:10B70000224633F039DAAEE195F83A30B5E7AB7955
+:10B7100085F83A8085F83B80002B00F0A4812B79D6
+:10B72000002B00F0A0813046294611F0BFDA3046E8
+:10B730004FF000614FEAC86218F03CDA93E199F8E3
+:10B740003830003B18BF012397E799F838301C1EAA
+:10B7500018BF0124444500F0868130461FF076DB97
+:10B7600010B96FF015037DE154B1304601F0C2FE0F
+:10B77000736A23F4C0137362002389F8383072E1CE
+:10B78000736A304643F400237362022389F8383029
+:10B79000D6F8AC38013B86F8A93805F081FE62E1A5
+:10B7A000219A032A15D9002C05DB3046214614AA1C
+:10B7B00033F064DD05460DB12B795EE7149B13F180
+:10B7C0001E0F40F05081CAF800504CE1239B072B1C
+:10B7D00002DC6FF00D0345E1032A01D1002703E0ED
+:10B7E000022A14BF00270127002C2DDB30462146FA
+:10B7F00014AA33F043DD054630BB149B13F11E0F32
+:10B8000022D1129B002B1FDD87F0010300932A46F3
+:10B810002B463046139933F0CBD9054650B96FF01B
+:10B820001A03149310E0C046991E8300A91E8300DA
+:10B83000F92A83003046294633F0A4DE149018B16B
+:10B840003046294633F0F8DD129B032B00F00B81C4
+:10B85000022B00F00881149A3AB112F11E0F40F049
+:10B860000281002B40F0FF80FCE0002B24DD2B79CF
+:10B87000002B40F0F88033681B6F13F0030F02D0E9
+:10B880006FF00803EEE0AB7923B13046294633F080
+:10B89000ABDC90E6D5F8CC3013F4005202D04FF078
+:10B8A000FF33DFE06B7E304600920192294605F1BE
+:10B8B0001A022EF05DD8D6E06B79002B00F0D38011
+:10B8C0003046294633F0DCDACDE015B195F9643520
+:10B8D000D3E6CAF800501FE0F5B1002C1CDB012CA8
+:10B8E0001ADC2B7913B16FF00403BBE085F86445D3
+:10B8F000B9E099F818307BB199F82F3063B199F815
+:10B9000030304BB999F83F3033B9D6F868319B796C
+:10B9100013B9B6F81637B0E66FF00103A2E033684A
+:10B9200093F83030A9E6336893F83030434500F09F
+:10B930009A80304633F024DF0446B8F1000F05D07A
+:10B9400043791BB13046214633F09ADA214630461E
+:10B9500088F0010233F01CDF04461490002840F008
+:10B9600082803368012283F82F20B8F1000F03D0C2
+:10B97000D6F8403583F834203368304683F8308079
+:10B9800010F01EDA86F8DD41304605F0BDFD6AE0B4
+:10B99000BAF80200F7F360F4E8B99AF80400BAF8CC
+:10B9A00002109AF800209AF801300090284628F0FA
+:10B9B000C3DD00E6D6F83437B3F8A4335DE624B926
+:10B9C000D6F83437A3F8A4434DE0D6F85C01A1B211
+:10B9D0003AF0E4DC10B96FF0130343E0D6F83437E3
+:10B9E000BDF84C10A3F8A4133DE0BBF1000F03D049
+:10B9F0009BF80430022B02D06FF01D0332E0384672
+:10BA0000DBF8101027F01CD8D5E597F8F03334E6B2
+:10BA1000E3B287F8D53387F8F033384626F0D6DE20
+:10BA200021E0D7F8E83328E6C7F8E8431BE0D7F869
+:10BA3000EC3322E6C7F8EC4315E097F8D4331CE664
+:10BA4000D6F86C32D3F8D432DB8D9C4202DD6FF035
+:10BA50001C0307E0A7F8C84305E0B7F8C8330CE6B5
+:10BA60006FF016031493149817B0BDE8F08FC0461A
+:10BA70002DE9F0410468074686B020460E46904600
+:10BA80001D461BF0B3D910B120461BF0A7D90C9B63
+:10BA90002046029300230393049339460B22434626
+:10BAA0000096019511F03AD806B0BDE8F081C04685
+:10BAB00070B5114686B00546164649F06FDE04465D
+:10BAC00008B390F8DF3023B12846214601222AF03E
+:10BAD000B9D9204649F0E8DBE3681BB12846214686
+:10BAE0003CF0CCD9002203230092019302920392EE
+:10BAF0000492284621690532334611F00FD82846B2
+:10BB0000214649F05DDE06B070BDC04670B5036BDE
+:10BB1000002680F8D068D0F85C410546186907F027
+:10BB200005F8014620463AF001DA20B12846012105
+:10BB3000324618F031DA70BDF0B505688BB00646B4
+:10BB40000021EF681DF0D6DA304610F01BDFD5F883
+:10BB5000E4366BB1A868D5F8741503F07FDD0023D7
+:10BB6000C5F8E43695F8583503F0FD0385F85835E7
+:10BB7000D5F85C013AF0BAD92A6992F8EA3063B193
+:10BB8000D36ED3F8202140F2044302EA0303B3F555
+:10BB9000806F14BF0020012006E0106E03F054FEF9
+:10BBA000D0F1010038BF002000283CD0284605F025
+:10BBB00019FE2B6BD5F85C41186906F0B7FF0146FA
+:10BBC00020463AF0B3D930B195F8D0281AB92846B2
+:10BBD000012118F0E1D9304611F06EDC4FF000433E
+:10BBE000C7F888310F21286931F010DE286940F24A
+:10BBF000FF3131F0F9DD2B6B1B68022B04D1286972
+:10BC000095F8431631F05EDE284616F02DDC284606
+:10BC100016F0F6D900232846694600931AF082D818
+:10BC200028461DF0D7DB0BB0F0BDC0462DE9F04F24
+:10BC30000668D0F8D022D0F8D81297B00746D0F8CE
+:10BC4000E8B23046069107921DF04CDC069BB068C6
+:10BC5000196803F003DD384602212CF02DDEF7E1F0
+:10BC6000D6F8D83603EB82035D686C8E04F470431B
+:10BC7000B3F5805F14BF38233C2356F8039004F4D7
+:10BC80004063B3F5406F28D1336893F8463013F022
+:10BC9000030F15D0D6F85C01D9F8041039F02EDD69
+:10BCA00010F0080F0CD199F8EC304BB1D9F80030F6
+:10BCB000022B12D1D6F8FC349B7813F0020F0CD073
+:10BCC0002046F7F3AFF20E2894BF4FF400534FF421
+:10BCD000805340F4306003439CB2D6F85C012146A7
+:10BCE0003AF05CDB002800F0AE81688EF7F39AF240
+:10BCF0000446688EF7F396F244F430640E288CBF45
+:10BD00004FF480504FF400500443A1B238462BF05A
+:10BD100087DE002800F09781D7F8E832002B78D032
+:10BD2000D3F8DC30002B74D04FF00001A7F85C1082
+:10BD300095F8AA004FF00C0800FB08B0EA8814A997
+:10BD400082F08002C2F3C0121C30F7F3D1F3BDF8C9
+:10BD500050200DF1540AA7F8622095F8AA00514628
+:10BD600000FB08B02030F7F321F4159B33BB95F8A6
+:10BD7000AA1013AC01FB08B1042224312046F6F3CB
+:10BD8000FBF020469A490422F6F3DAF048B995F818
+:10BD9000A920A2F10803DBB2022B40F254818DF8F6
+:10BDA0004F2020465146F7F301F4024630B9009087
+:10BDB000CDF8048095F832300293FAE0159B8D4956
+:10BDC00013F0040F1CBF43F002031593159B30467C
+:10BDD00013F0020F1CBF43F00103159315AB009342
+:10BDE0000423019301230293BB68002203931346AB
+:10BDF00017F0D6DA002207230192009395F8AA30B3
+:10BE00003046029303920492394618322B4610F0C2
+:10BE100085DEB5F8623013F0100F0FD0BA6D40F226
+:10BE2000371302EA03034BB9734B1A7832B9012373
+:10BE30000092019395F832300293FCE02846F6F325
+:10BE40007BF518B100230222009327E03B6D002B05
+:10BE500032D0336893F83030002B2DD11C469846F1
+:10BE600009E0796D284641440622F6F369F008F1AD
+:10BE7000060818B10134FB6C9C42F2D33B6D012BD8
+:10BE800003D1FB6C9C4206D316E0022B14D1FB6C51
+:10BE90009C420DD210E0002300930322019295F8FA
+:10BEA0003220039302920493304639461722C7E0AA
+:10BEB000002304220093F1E7336893F8953083B1AF
+:10BEC000D6F84C35012B09D1284606F5AA61062281
+:10BED000F6F336F0002840F0B68002E0022B00F0C6
+:10BEE000B28095F9344074B9D6F85C01698E3AF0A5
+:10BEF000E9D840B105230094019395F832300394BA
+:10BF000002930494D0E7B7F862306BB1BA6D40F297
+:10BF1000371302EA03033BB1304639462A462BF079
+:10BF2000A1DF002840F08F80D9F80030022B0AD121
+:10BF300099F815203AB9FD33009305F1380009A9A5
+:10BF40000123019214E0336805F1380093F846307C
+:10BF500009A913F0030317BFD7F8CC301A46C3F36F
+:10BF6000003383F001020192FF2300220093134665
+:10BF700045F0C2D8336B09F1500493F8EC1039B195
+:10BF80006B8E03F44063B3F5406F14BF1421282176
+:10BF9000204645F059D8D6F86036002209A8214637
+:10BFA0009B7844F0EBDF024630B9009009230193FF
+:10BFB00002920392049277E79DF8382096F838377A
+:10BFC0009A4240D195F93430C3B96A8E304602F4B2
+:10BFD0007042B2F5805F14BF0222012205F13801E0
+:10BFE0002BF0E4DC024648B90A230090DFE7C046A4
+:10BFF00058D4010017738600B0270200336893F805
+:10C00000303053B32946304649F0C8DB014620B3EF
+:10C01000037E13F0020F06D0436813F4805202D15E
+:10C020000D230092C3E7D1F8F030B3B100220F2303
+:10C0300000920193029203920492304639461732DD
+:10C040002B4610F06BDDD6F8DC36013BC6F8DC364B
+:10C05000D6F8DC26002A7FF403AED6F8DC36FBB136
+:10C06000069B00219977D6F8DC26D6F8D836013A17
+:10C0700003EB8203C6F8DC26069A9C685368012B02
+:10C080000AD0009101910291039104913046394602
+:10C090002022234610F042DD38462EF011DA35E03A
+:10C0A000D7F8CC3013F4005F06D0FB7923B9D6F86B
+:10C0B0004C01394643F0F8DF0799FA7991F93430A9
+:10C0C0004AB1002238460121934214BF00230123C4
+:10C0D0002CF0DAD809E038460121D3F1010338BF4A
+:10C0E0000023009201922CF009DA97F91030022B0C
+:10C0F00003D1F86800214DF035DA96F875323846EC
+:10C1000023F0040386F875322CF0A6D917B0BDE8E9
+:10C11000F08FC0462DE9F04F9B460568D0F8D0322D
+:10C1200089B003932B68064693F83F308A469046C1
+:10C13000D0F8D872D0F8D492002B00F08281C37965
+:10C14000002B00F07E81837C0DF1160013B106F107
+:10C15000D60100E049460622F5F30EF700242B68CD
+:10C1600085F84A4593F844301BB1D5F8640135F0A1
+:10C1700067DFB37C2BB1D5F84C013146224605F080
+:10C1800067F82A6992F8EA305BB1D36ED3F82021C0
+:10C1900040F2044302EA0303B3F5806418BF0124AC
+:10C1A00005E0106E03F050FB041E18BF0124CCB153
+:10C1B000002130462FF012DA3046FFF7BDFCB37C89
+:10C1C0003046D3F1010338BF0023009300210DF165
+:10C1D00016020823FFF74CFC002130460A4632F0D5
+:10C1E000CBDC1AE1B37C002B00F08F80D6F8DC3278
+:10C1F000D3F8901041B193F894206868FAF378F579
+:10C20000D6F8DC32C3F89040BB6823B10D2B02D0C6
+:10C2100030462CF09BDAD5F86801042148F0C8D9E3
+:10C220000DF11601284649F0B9DA002421460746E7
+:10C2300086F8944030461CF06FDC2146304619F0F9
+:10C240002DDC304621460FF01FDEBAF1000F45D03D
+:10C2500006F1BC00F6F380F300283FD12B6BB9F850
+:10C260003240186906F062FC844237D1D5F85C018F
+:10C27000B9F8321039F0AADE30B9D5F85C01B9F856
+:10C28000321039F01FDF80B1B8F1000F0DD1D5F8B1
+:10C290005C01B9F8321039F049DE30B9DFF8ACA1F1
+:10C2A0000123C34685F8D03800E0C24608230DF1CB
+:10C2B00016010193284606F1C2030A4600971BF0B7
+:10C2C00091DE034658B1BAF1000F08D02846514616
+:10C2D0005A4618F053D810B9824600E0C2460FB94A
+:10C2E0003C462FE038460E2148F0AADE2B6893F832
+:10C2F000443023B1D5F86401394635F0B5DE28461F
+:10C3000039461AF069DE00241CE02B6893F895305A
+:10C3100093B1D5F8000507A948F0DCDE06E05368C4
+:10C3200013F0005F1CBF23F00053536007A848F0D0
+:10C33000D9DE02460028F2D10124B474304616F04A
+:10C34000B3DEC246304600212FF048D905F5007112
+:10C35000284606311FF0E2DC2B6893F83F20A2B993
+:10C3600095F9473685F84226B3F1FF3F08BF85F8B7
+:10C370004326284619F0B2DA2B6893F8463013F0BA
+:10C38000030F02D0284619F0C5DA06F1BC00F6F317
+:10C39000E3F2014630B930460DF11602082300944D
+:10C3A000FFF766FB95F872323BB9D5F86C329E42C6
+:10C3B00003D13046FFF7C0FB05E0304611F07CD8D2
+:10C3C000304610F0DFDAD9F8641049B16868B9F87E
+:10C3D0006820FAF38DF40023C9F86430A9F86830B6
+:10C3E00002230DF11602009328463346002117F070
+:10C3F0002FD93046002117F0FDDA304617F066DA03
+:10C40000284605F081F8BAF1000F03D02846002134
+:10C410005A46D047B8F1000F01D0002013E0304653
+:10C420004146424632F0A8DB414606220398F5F326
+:10C4300007F606F1BC0041460622F5F301F6404638
+:10C4400001E04FF0FF3009B0BDE8F08F0DBB0000F8
+:10C450002DE9F04F062989B007460D4692469B46C6
+:10C460009DF848900468D0F8D86246D061BBB9F115
+:10C47000000F03D12046394633F098DB94F872322E
+:10C48000002B3AD0D4F8000507A948F023DE03E0DA
+:10C490001B7E13F0020F30D107A848F023DE0346BD
+:10C4A0000028F5D151E0236B186906F03FFBD7F85F
+:10C4B000D4325B8E834220D0204628F00DD8D4F8A9
+:10C4C000340728F027DC18E0B368093B012B14D8A7
+:10C4D0002046114649F062D910B10C2148F0B0DD78
+:10C4E000022D07D0A068316803F0B8D8052D01D01F
+:10C4F000012D02D14FF0010801E04FF00008139B1D
+:10C500000095CDF804B00293336C20460393736C0E
+:10C5100039460493B9F1000F0CBF07220922534694
+:10C5200010F0FCDAB8F1000F13D0052D01D0022D68
+:10C5300007D1B27F337F9A4203D238462DF0C0DF55
+:10C5400007E03846FFF772FB03E07368032BAAD1BC
+:10C55000D3E709B0BDE8F08F0048704760E70100FD
+:10C560000048704780E8010010B5836F40F2EE226A
+:10C570001C6A044B94219C4208BF4FF4166231F0B0
+:10C5800069DB10BD50200800816F10B508310446EA
+:10C590002FF06CDEFFF7E0FF014620462FF046DE6D
+:10C5A00010BDC0462DE9F04104460D469046BDF849
+:10C5B00018E09DF81C701E4633B18368DA6A02EBFE
+:10C5C0004102938BFB1893834FF6FF739E4503D074
+:10C5D000A821724631F03EDB04EB8503D868084B96
+:10C5E000414632465B6A9847002807DA36B1A368AD
+:10C5F000DA6A02EB4502938BDB1B9383BDE8F08183
+:10C60000E0A6850010B507490446406EF6F3E0F158
+:10C61000034620B9606E0449F6F3DAF10346184682
+:10C6200010BDC04699D501000AAA860070B50D4616
+:10C630000669144608460A220021F5F301F56B88C5
+:10C640001C43F36C6C8013F0200F03D02B8843F451
+:10C6500080632B80B16F42F250030A8C9A4206D15C
+:10C660004B8C052B03D86B8843F004036B8070BDA3
+:10C670004FEA810210B513188E468168DB6F52189D
+:10C680008367936B0B6390F8EB3063B190F8E830FD
+:10C690004BB94FF40051006EBEF1000F0CBF0A46BB
+:10C6A0000022FEF3BFF310BDB1F1FF3F2DE9F041D1
+:10C6B00004460E4605D1836F596A09B90E4600E05B
+:10C6C0009E6994F8E9701FB9204639462FF004DBC3
+:10C6D000206EFEF307F580B1002504EB8503D868D2
+:10C6E00010B1254B9B6898470135062DF5D1E368BD
+:10C6F0001BB1204600212FF03BDB94F8E8203AB133
+:10C70000A3680022DA612046032130F071DC30E0BA
+:10C71000206E46F0040184F8EA20FEF393F3A06F44
+:10C72000012184F8EA1018B1406A08B106F0D0F887
+:10C7300020462FF0F5DBE26E206ED2F8E0310121C9
+:10C7400023F02003C2F8E031F9F326F4002120465B
+:10C750002FF0C2DA204630F03DDD2046012130F0D6
+:10C7600011D9A2680023D3611FB9204602212FF0FE
+:10C77000B3DABDE8F081C046E0A6850070B50121BE
+:10C78000044631F0ABDA206E03F05CF8204600215D
+:10C790002FF0A2DA204630F0FDDE054630B120460B
+:10C7A000002131F09BDA6FF0080005E020464FF0E1
+:10C7B000FF31FFF779FF284670BDC04673B50469A5
+:10C7C000054620460E46FFF7DFFEA36F3146586A46
+:10C7D00007F0F6FB2A68012382F8743020462FF018
+:10C7E0007DDCA36F2046998A31F010D8A36F2046D4
+:10C7F000D98A30F0F9DF204694F886102FF0FED960
+:10C80000A36F204652219A8B31F024DAA36F502176
+:10C81000DA8B204631F01EDA20462FF081DC2046EC
+:10C82000FFF7A2FE032300932046042108220023E1
+:10C8300030F0F0DB20462EF0B1DF7CBD10B504698E
+:10C840004FF440412046002230F0D2DBD4F8F830DB
+:10C850001B691BB120462EF0A1DF02E020462FF01D
+:10C8600059DDE26C206E02F00202002A0CBF114674
+:10C870004FF400710A460023FEF384F310BDC04656
+:10C8800070B5836804461B6893F82050F5B9012100
+:10C8900031F024DA206E02F0D5FF204629462FF031
+:10C8A0001BDA20462FF036DDA068D0F848381B7818
+:10C8B0000BB12FF061DBA36F586A05F0FBFFA36893
+:10C8C00084F85E501A68012382F8203070BDC0469B
+:10C8D00070B5082986B005460C4602DD6FF00100F0
+:10C8E0002DE1836897491B685869F6F345F0082CD9
+:10C8F00024D12A6E936913F0005F03D0D36913F03B
+:10C90000010F0BD0EB6C13F0010F0BD02B6D13F05C
+:10C91000800F07D1D36913F0010F03D06B6D13F0B3
+:10C92000005F05D12B6D13F0800101D10C4612E0A0
+:10C9300043B2022B40F30181052400E05CB1D5F83D
+:10C94000F8305B68022B06DDAB6D13F0005F02D19F
+:10C950006FF00200F3E00A220DF10E000021F5F362
+:10C960006FF3D5F8F8304FF000021A8195F8903047
+:10C970000BB91E4604E0EB6ED3F8203103F001063C
+:10C9800095F8903053B164B9D5F8F8301B68002B96
+:10C9900000F0888028462FF0BDDC83E0002C00F0FA
+:10C9A0008180BDF80E30D5F8F82043F01003ADF8C3
+:10C9B0000E305368022B6B6D03D123F000536B656F
+:10C9C00039E043F0005314F0040F6B6503D1138971
+:10C9D00043F0140313812A6E936913F0005F03D0B0
+:10C9E000D36913F0010F0BD0EB6C13F0010F12D0D1
+:10C9F0002B6D13F0800F0ED1D36913F0010F0AD005
+:10CA00006B6D13F0005F06D0D5F8F820138943F062
+:10CA1000400313810FE0D5F8F8305B68042B05D193
+:10CA2000BDF8123043F40053ADF81230D5F8F820B9
+:10CA300000231361D360D5F8F8205368022B12D17C
+:10CA4000EB6C13F4804FBDF8103008D043F48073C2
+:10CA5000ADF810303023D3602023136103E023F4BA
+:10CA60008073ADF8103014F0020FD5F8F81003D031
+:10CA70000B8943F0010304E00A894FF6FE7302EAD2
+:10CA8000030314F0040F0B81D5F8F81003D00B89C1
+:10CA900043F0080304E00A894FF6F77302EA030340
+:10CAA0000B8109E0BDF80E3023F01003ADF80E3015
+:10CAB0006B6D23F000536B65D5F8F8301C60AB6FDD
+:10CAC000696D586A06F08AF995F890301BB116B175
+:10CAD000284630F033DF0224BDF80E30284600210E
+:10CAE0001022009430F096DABDF81030284601216B
+:10CAF0004FF48072009430F08DDABDF81230284681
+:10CB000021464FF40052009430F084DA28462FF08A
+:10CB1000A1D895F8903073B1AB6F1B68A34206D1D2
+:10CB2000D5F8F8301B6813B128462EF037DE16B161
+:10CB300028462FF05DDF002001E00124FFE606B06B
+:10CB400070BDC046C65C860070B5054690F8900082
+:10CB5000002846D0AB6F002185F89010586A05F088
+:10CB6000BDFEAB681A6992F8EA305BB1D36ED3F8B8
+:10CB7000202140F2044302EA0303B3F5806018BFAA
+:10CB8000012002E0106E02F05FFE68B10024AB6F7E
+:10CB900085F8EB4085F8EA40586A214605F098FE92
+:10CBA000A8682FF033D91BE0286EFEF39BF20446F1
+:10CBB00080B1EB6ED3F8203113F0010F02D028467C
+:10CBC00030F0BCDEAB689868F6F7F8FA0446284601
+:10CBD00031F0A2D895F8E81011B9284631F07ED886
+:10CBE000204670BD70B5054690F8900050B3AB6814
+:10CBF0001A6992F8EA305BB1D36ED3F8202140F283
+:10CC0000044302EA0303B3F5806418BF012403E080
+:10CC1000106E02F019FE0446AA6814B100231362D4
+:10CC20000CE0906802F056DD284621462FF054D8DB
+:10CC300095F8E83013B928462FF06CDBAB6F586AD3
+:10CC400006F014FB70BDC0460121836F10B580F85B
+:10CC500090100446586A05F041FE204602212FF04C
+:10CC60003BD8A368986802F03FDD002010BDC046A5
+:10CC70002DE9F3418668062733680DF10204DB696C
+:10CC800005461B6AD0F86C80C6F8AC3830493A4685
+:10CC90002046F5F371F16B6C2E48214603FB07002B
+:10CCA0003A46F5F369F10423C6F8AC38013B86F83F
+:10CCB000A938A8681EF0CAD808B93C4604E0D6F8DE
+:10CCC000AC389B0001339CB2D5F8B8700026F05DFB
+:10CCD00004F0FF01201880B2421E02F0FF0341EA77
+:10CCE000032102F48072C4F300231A43330243F495
+:10CCF000004301369BB2062EA8F840350446A8F83A
+:10CD00002015A8F82C25A8F84035E0D12846982110
+:10CD10007A7830F09FDFD5F8B83028469A219A7893
+:10CD200030F098DFD5F8B8302846DC781A789C21A6
+:10CD300042EA042230F08EDFD5F8B83028465C791C
+:10CD40001A799E2142EA042230F084DFBDE8FC819A
+:10CD500061DB0100301E02002DE9FF410569074635
+:10CD60009221284630F05CDC400080B2A7F84200F7
+:10CD700000282FD04FF000080DF101060F2130469A
+:10CD8000154A4346F5F3A0F1686E3146F5F320F6F7
+:10CD900060B13146686EB7F84240F5F3EDF504EB4B
+:10CDA000480482B22146284630F054DF08F10108D9
+:10CDB000B8F1770FE0D1686E0849F5F309F648B18C
+:10CDC000686E0649D5F8F840F5F3D6F52081284677
+:10CDD0002EF040DFBDE8FF81AEAC8600177C8600F8
+:10CDE0002DE9F041056986B04FF0FF31AC4A80462D
+:10CDF0002846EE6E30F0FCD8D5F8F8302846196891
+:10CE0000FFF766FDAB6D3BB14FF00303A6F8B436F8
+:10CE10004FF0FF03A6F8B836EB6C13F0010F27D0E4
+:10CE2000A04A136823BB012111602B6D286E13F0FB
+:10CE3000800F03D0023102F0BBFD19E002F0B8FD13
+:10CE40002B6D13F0005F13D12846922130F0E8DB00
+:10CE5000400080B260B100F1CE042146284630F097
+:10CE6000DFDB40F040022146284692B230F0F2DE8D
+:10CE70004FF0FF31C6F8281128468B4A30F0B8D859
+:10CE80008A4C03E00A20F9F367F40A3CD6F828310B
+:10CE900013F0010F01D1092CF4D14046D6F8283106
+:10CEA000FFF7CCFCD5F8F4302BB92B6E9A6A40F220
+:10CEB00094539A4213D1286E7D4B826BD318012B69
+:10CEC00007D94AF6E6039A4203D04AF6E5039A42A6
+:10CED00005D10823002128220093FDF3D7F7002174
+:10CEE0000A46286EFDF3B6F7FFF73AFB01462846DF
+:10CEF0002FF09CD92846FFF7BBFE4FF480330093F8
+:10CF00002846062398210DF10E022FF0CFDCD8F829
+:10CF1000003093F83830D3B140461DF097DF012838
+:10CF200015D100231C461F4605930AE04FF4C02389
+:10CF300000933946284605AA04232FF0DDDC01348E
+:10CF40002437D8F80030DB691B6A9C42EED32846B0
+:10CF50008021082230F07EDE28465C210A2230F053
+:10CF600079DE4FF08073534AC6F8003128465249A3
+:10CF700030F03ED84FF00043C6F8883103F1024349
+:10CF8000C6F88C314FF48043C6F8283103F540438E
+:10CF900073620121284630F019D8286E02F0A0FCF7
+:10CFA00083B2A8F818001621A6F8A8362846B5F8C6
+:10CFB000442030F04FDE2846C021B5F8542030F030
+:10CFC00049DE2846C221B5F8562030F043DE3B4BFF
+:10CFD0002846C6F86031D6F86031B5F8883044216B
+:10CFE000C6F86431364BB5F88C20C6F86031D6F8F7
+:10CFF0006031B5F88A30C6F8643130F02BDE28464F
+:10D000004621B5F88E2030F025DEB6F888361B05AF
+:10D010001B0DA6F888364FF00103A6F89C360023B6
+:10D02000C8F848301C4605EB8403D86810B1254B7E
+:10D030005B6898470134062CF5D1224CE868236DD3
+:10D040009847E36EE86898474046FFF785FE2B6EE9
+:10D050009A6B4AF662139A421ED1EB6C13F0010FE1
+:10D060001AD02B6D13F0800F16D113F0005F13D17F
+:10D070002846922130F0D4DA400080B260B100F14D
+:10D08000CE042146284630F0CBDA40F0400221465B
+:10D09000284692B230F0DEDD06B0BDE8F081C04631
+:10D0A00004040004F02702000204020449420F00B5
+:10D0B0001D57FFFF0000024000000640060002006E
+:10D0C00007000200E0A685002DE9F04790F8E9701E
+:10D0D00004460E469046856817B939462EF0FCDDA9
+:10D0E000A86802F0F7DA06F47041B1F5805F14BF6A
+:10D0F0000021012181462046FFF7BAFAA36F31468D
+:10D10000586A05F00FFDA36F586A05F0EDFB28463D
+:10D11000FFF766FEB8F1000F04D0012120460A4651
+:10D120002FF0D4DF28463146FFF748FBA868494670
+:10D1300002F0E4DAD4F8D43043F00403C4F8D43075
+:10D140000123C4F8D0301FB9204602212EF0C4DDDF
+:10D15000BDE8F087816810B50B680446D3F88C20D1
+:10D16000D2F8B4300133C2F8B4300A6992F8EA3028
+:10D1700063B1D36ED3F8202140F2044302EA0303E3
+:10D18000B3F5806F14BF0020012006E0106E02F09E
+:10D190005BFBD0F1010038BF002020B120464FF0EA
+:10D1A000FF31FFF781FAA0682EF030DEA06819F099
+:10D1B0008BDC10BDD0F8EC1010B5044631B100681E
+:10D1C0000C22F9F395F50023C4F8EC3010BDC046ED
+:10D1D0002DE9F04FD1F8D43289B0B3F832A0D0F8AD
+:10D1E0004C31804603938B798946D0F80CB0002BE4
+:10D1F00000F0B58000273E4608EB8603D3F84C527A
+:10D200008DB1AB797BB9EB796BB1D5F8D432588E4F
+:10D21000F6F308F004465046F6F304F0844201D0D9
+:10D220002F4606E02F460136082EE5D1002F00F0EC
+:10D230009680D7F8D432588EF5F3F4F7044650466A
+:10D24000F5F3F0F7844205D0D7F8D432D9F8D422D8
+:10D25000DB8DD385404605A904AA18F08BDF39463B
+:10D26000D8F84C0141F0E2DF182300FB03F4D8F8B2
+:10D270004C0104F13A0142F0C3DC38B9049A059B31
+:10D28000039839460092019301F0DCFA04F1400161
+:10D29000D8F84C0142F0B4DCD7F8D4320599DB8DD4
+:10D2A00040019E02CE42079001D3B04209D321F043
+:10D2B0007F4323F460038219984201D21046F6E7B7
+:10D2C000079006AC07AD22462B46049803F0FAFC03
+:10D2D000384618F0E5D929460346002220461DF0BD
+:10D2E000EDDDD9F8D4327608DB8D29469F02204641
+:10D2F000334600221DF0FCDD3B46012101E049469A
+:10D300001346DA19B34201F10109F8D306A807A9B7
+:10D31000002204AC05AD1DF0EBDD20462946069A3F
+:10D32000079B1DF0E5DD059B2046CBF88031049B73
+:10D330002946CBF88431002304930593069A079B72
+:10D340001DF0D6DDD8F84C010499059A42F010DFA3
+:10D35000BB01CBF8883107FB09F3CBF88C3109B05E
+:10D36000BDE8F08F2DE9F34100EB8101D1F84C428B
+:10D37000064690461D469DF8207014B94FF0FF33C5
+:10D3800019E004F11A0000212022F4F359F60023D9
+:10D39000637615B9336803F14E054346304621469E
+:10D3A0002A46009730F09ADF034620B930462146DE
+:10D3B00032F0E8D803461846BDE8FC81D1F8CC30FD
+:10D3C00073B543F40053C1F8CC3005460C4632F037
+:10D3D000D9D80646002840F08880B5F8822144F26A
+:10D3E00021339A421AD00E3B9A4217D007339A4201
+:10D3F00014D010339A4211D0143B9A420ED0073306
+:10D400009A420BD010339A4208D025339A4205D065
+:10D41000AB6B5B7D13B96FF00B0666E02B6B93F87B
+:10D42000EC300BB91E4608E0B5F8263603F440632D
+:10D43000B3F5406F14BF142628262B6893F84630A6
+:10D4400013F0030305D0D4F8CC30C3F3003383F0DA
+:10D4500001030093284633462146022231F024DAA4
+:10D460000646002841D1D4F8CC3013F4803F0AD1CD
+:10D47000D5F84C01214641F0E1DFC4F8F00280B953
+:10D480006FF01A0631E0062204F1BC0004F1C2017B
+:10D49000F4F372F5D4F8D432B5F8262683F8346064
+:10D4A0005A86A379D3B194F8F532312B11D82B6871
+:10D4B0001B7E2BB1284694F8F4120D4A1BF0B6DF00
+:10D4C000D5F84C0194F8F41241F0FCDE322384F8D4
+:10D4D000F43294F8F53284F8F43206E0D5F84C01D1
+:10D4E00004F53D7141F0B2DE064630467CBDC046D3
+:10D4F000329E85002DE9F041054632F041D90026E3
+:10D500000746AB19D3F84C426CB1A3795BB1BC426E
+:10D5100009D063791BB12846214631F0B1DC284699
+:10D52000214631F089DF0436202EEAD1BDE8F081B2
+:10D53000002010607047C04610B505F021F810BDFE
+:10D5400010B504F05DFFC0B210BDC04610B508466E
+:10D55000114604F037FF10BD2DE9F0470446884618
+:10D560004768002110469146C922F4F369F5204628
+:10D57000414638F013DF78B997F85037002B00F0A8
+:10D58000D08707F5AA6138460E3138F061D90646D2
+:10D59000002800F0C68700E0266908F47043B3F560
+:10D5A000805F14BF38233C233078FF5804F0D0FF4D
+:10D5B0000446B07804F0B4FF637C5FFA88F513F09A
+:10D5C0000102064602D097F904E106E097F904311A
+:10D5D000182BD4BF9646A3F1180E934B9C4203D14F
+:10D5E00058214FF0520C0BE0904B9C4205D0904BD1
+:10D5F0009C4202D04FF07F0C01E04FF0580C614686
+:10D600003B68022B5FD1012D01D8002303E00A2DD6
+:10D610008CBF02230123E31893F90620854B9C421B
+:10D6200003D10B2D10D14C2240E0834B9C4203D1FF
+:10D630000E2D3BD1362239E0804B9C4202D0804BEC
+:10D640009C4204D10B2D30D00E2D2ED02EE07D4BE0
+:10D650009C4203D10E2D29D12A2227E07A4B9C42ED
+:10D6600007D1022D01D1582220E00A2D1ED15422CB
+:10D670001CE0764B9C4203D10A2D17D1502215E0B5
+:10D68000734B9C4203D10E2D10D128220EE0714B1A
+:10D690009C4203D10B2D09D13E2207E06E4B9C42E8
+:10D6A00004D10C2D02D1442200E04022CEEB020333
+:10D6B00023EAE3738B42A8BF0B46002202F809302D
+:10D6C0000132042AFAD1654B9C4208D0644B9C423B
+:10D6D00005D0644B9C4202D0634B9C4207D197F922
+:10D6E0000431182BD4BF4FF0000EA3F1180E3A6886
+:10D6F000022A40F01081012D01D8032303E00A2DF6
+:10D700008CBF05230423E31893F90600494B9C4280
+:10D7100001D10B2D6CE0554B9C4204D1022D00F041
+:10D720000E810A2DCFE0444B9C4201D10B2D58E0D5
+:10D73000424B9C4202D0424B9C4201D10B2D11E046
+:10D740004B4B9C4202D04B4B9C4204D10D2D40F0E0
+:10D7500007812E2004E1484B9C4206D10B2D00F09E
+:10D76000F2800D2D00F0F380FAE03E4B9C4258D041
+:10D77000344B9C4204D10B2D40F0F2803E20EFE070
+:10D78000314B9C4219D0314B9C4206D1022D00F006
+:10D79000E4800A2D00F0E180E2E0384B9C4206D1A3
+:10D7A000022D00F0D8800A2D00F0D580D8E0344B4F
+:10D7B0009C4202D0334B9C4206D1022D00F0C9801E
+:10D7C0000A2D00F0C680CBE02F4B9C420CD1022DDD
+:10D7D00000F0BD800A2D00F0BA80032D00F0BF805C
+:10D7E000092D00F0BC80BBE0284B9C4203D10A2DE0
+:10D7F00000F0A780B4E0164B9C4205D1A5F10C03C4
+:10D80000012B40F2A280ABE0214B9C4203D10B2DB7
+:10D8100000F29D80A4E01F4B9C423DD10C2D00F0F6
+:10D8200096800D2D75E0C046BC108600F010860075
+:10D8300024118600400986002CDC0100BC0C860007
+:10D84000D00C8600700D86007C0986009009860049
+:10D85000840D8600DCDC010094DE0100340D8600BE
+:10D860005C0D860080118600FC0D860080DE0100C4
+:10D87000E40C86000C0D8600FCE30100CC09860058
+:10D88000A4098600B8098600F409860018098600F4
+:10D89000980D8600381186008C4B9C4203D1022DD6
+:10D8A00055D00A2D26E08A4B9C4231D0894B9C42B0
+:10D8B00003D10B2D54D1322052E0874B9C4204D12E
+:10D8C0000B2D40D00C2D3AD04AE0844B9C4205D120
+:10D8D0000C2D44D00D2D43D13A2041E0804B9C4289
+:10D8E00004D1A5F10B03012B29D939E07D4B9C42D2
+:10D8F00002D10B2D29D033E07B4B9C4205D10C2D5E
+:10D900002BD00D2D2CD144202AE0784B9C4227D1DE
+:10D910000B2D18D024E0332D01D800200BE03D2D35
+:10D9200001D8012007E0632D01D8022003E0942DE7
+:10D930008CBF04200320231893F9060010E04A202E
+:10D940000EE042200CE038200AE03C2008E04020B5
+:10D9500006E0502004E0482002E04C2000E0462091
+:10D96000CEEB000323EAE3736345B4BF1846604679
+:10D97000022A04D199F800309842A8BF1846002224
+:10D9800009EB02030132082A1871F9D1C0B2CC4662
+:10D990004A4600210023013182F83430107382F8A6
+:10D9A0003C3001320829F5D1337F13F0010202D057
+:10D9B00097F9040106E097F90431182BD4BF1046FB
+:10D9C000A3F118003B68022B01D16B1E0FE0332D31
+:10D9D00001D800230BE03D2D01D8012307E0632D82
+:10D9E00001D8022303E0942D8CBF04230323F256B5
+:10D9F0009B19997B3E4B9E4205D1A5F16403022BF6
+:10DA000001D83E2110E03B4B49B29E4203D1642D28
+:10DA100000F05C850BE0384B9E4205D1A5F1640314
+:10DA2000022B01D83E2108E0344B9E420ED0344BED
+:10DA30009E420BD0334B9E4208D0334B9E4205D0C2
+:10DA4000324B9E4202D0324B9E4214D1A5F1680364
+:10DA5000242B10D82B4B9E421BD02B4B9E4218D010
+:10DA60002B4B9E4215D0264B9E4223D0274B9E42E5
+:10DA700020D044224A21274B9E420CD1A5F16803B5
+:10DA8000202B03D98C2D00F03F8549E04422402112
+:10DA900001E042224A21204B9E420DD1642D06D046
+:10DAA000A5F168030C2B3BD840223C216CE04022BE
+:10DAB000342101E044210A46184B9E4230D1A5F1A1
+:10DAC0006403102B2CD85222422160E068098600A2
+:10DAD000DCDC0100B4DC010010DD010094DE01009B
+:10DAE00014E10100A8DE0100BCDE0100C8DC010079
+:10DAF000B50886005BE30100D2088600DC058600DD
+:10DB00002E0586004B058600680586008505860083
+:10DB100033068600F90586006D0686008A068600B3
+:10DB20009C4B9E421AD1A5F16403082B98BF30216B
+:10DB3000A5F16E0398BF3422162B98BF4621A5F19C
+:10DB40008603022B98BF3E218C2D08BF3622A5F1FB
+:10DB5000950308BF48210F2B98BF44228E4B9E424D
+:10DB600012D1A5F16E03162BA5F1860398BF3A22B8
+:10DB700098BF4421022B98BF3A2298BF3E218C2D9A
+:10DB800008BF362208BF4821844B9E4202D0844BF6
+:10DB90009E4204D1A5F18403082B98BF2C22814B0F
+:10DBA0009E4202D1262D08BF2C21C0EB020323EA9E
+:10DBB000E377C0EB010323EAE37E4A4613790021B1
+:10DBC000137582F8441009F1080301329A42F5D125
+:10DBD0004B460A4601321F7783F84CE00133082A8E
+:10DBE000F8D1714B9E425BD0704B9E4258D0704B27
+:10DBF0009E4255D06F4B9E4252D06F4B9E424FD0AB
+:10DC00006E4B9E4236D06E4B9E4249D06D4B9E422B
+:10DC100046D06D4B9E4243D06C4B9E4240D06C4BE5
+:10DC20009E423DD06B4B9E423AD06B4B9E423DD0C4
+:10DC30006A4B9E4234D06A4B9E4231D0694B9E4221
+:10DC40002ED0694B9E422BD0684B9E4228D0684B09
+:10DC50009E4225D0674B9E4222D0674B9E421FD0EA
+:10DC6000664B9E421CD0664B9E4219D0654B9E422D
+:10DC700016D052E0032D02D14FF03C0E0FE02B1FC7
+:10DC8000042B0AD9092D00F04384A5F10C03012BC4
+:10DC900000F217842C2700F015BC4FF0400E4027EF
+:10DCA0004D4B9E4202D04D4B9E4207D1EB1E082B9E
+:10DCB00094BF4FF0400E4FF0000E4027524B9E4253
+:10DCC00022D1A5F124030C2B03D838274FF0300EB6
+:10DCD0001AE0A5F13403082B03D84FF0440E774621
+:10DCE00012E0A5F16403022B03D834274FF03E0E57
+:10DCF0000AE0A5F16803202B03D844274FF04A0E11
+:10DD000002E08C2D08BF32274B46002201321F75DE
+:10DD100083F844E00133082AF8D14B460022002161
+:10DD2000013283F8241083F854100133082AF6D105
+:10DD30004B460A46013283F82C7083F85CE00133CD
+:10DD4000082AF7D1184B89F864E09E4206D0174B99
+:10DD50009E425BD0174B9E4270D0CEE0012D00F06A
+:10DD6000A780022D00F09980032D00F0A6802B1FC4
+:10DD7000042B04D84C273C2338243E21A1E0092D54
+:10DD800001D14C2750E00A2D00F087800B2D00F0C8
+:10DD90008F808EE0A2058600BF0586002C078600D6
+:10DDA000F40486002CE201007E0A86009B0A8600AD
+:10DDB000B80A8600F20A8600BD0B8600980E86001F
+:10DDC00040DC01006AE0010097DC010046DE010052
+:10DDD00001DF0100E4DE0100630F860014108600FD
+:10DDE000B50E860024DD010041DD0100D2DD010019
+:10DDF000EFDD01005DDC01007ADC01000CDE0100DA
+:10DE000029DE0100880C8600DC058600012D4FD03C
+:10DE1000022D44D0032D01D14C2743E02B1F042BAE
+:10DE20004BD9092D04D14A2734233024362148E028
+:10DE30000A2D34D00B2D3CD136273AE0012D01D1EB
+:10DE40002C2736E0022D31D0EB1E052B18D8032DE0
+:10DE500004D144272C2328242E2132E0042D20D065
+:10DE6000082D1ED06B1F022B4FF044078CBF0023E0
+:10DE700038238CBF002434248CBF00213A2120E0B9
+:10DE8000092D04D142272E232A24302119E00A2DFE
+:10DE90000CD00B2D0DD12A270BE0402709E03E279F
+:10DEA00007E044273623322438210AE03C2700E0EB
+:10DEB000382700231C46194603E04C273823342416
+:10DEC0003A214A460020042894BF82F84C4082F848
+:10DED0004C300130177701320828F4D1FCB24A46A1
+:10DEE0000020032894BF82F85C3082F85C10013077
+:10DEF00082F82C4001320828F3D1A74B9E4206D06D
+:10DF0000A64B9E420DD0A64B9E4221D062E0032D2F
+:10DF100045D0092D43D02B1F042B38D83024342270
+:10DF200033E0032D03D14224462248203AE0042D59
+:10DF300031D06B1F022B03D84C245022522031E0E9
+:10DF4000082D28D0092D22D13E244222442029E048
+:10DF5000032D03D12E243022322023E0042D03D1BF
+:10DF60003024322234201DE06B1F022B03D83224D0
+:10DF700036223A2016E0082D03D1302434223820EE
+:10DF800010E0092D03D12E24322236200AE000228F
+:10DF90001446104606E046244A224C2002E028247B
+:10DFA0002C222E204B460021042994BF83F84C409C
+:10DFB00083F84C20013101330829F5D14B4600216B
+:10DFC000032994BF83F85C2083F85C00013101339E
+:10DFD0000829F5D1734B9E422AD1032D0CD02B1F5B
+:10DFE000042B03D838203C213E2408E0092D03D01F
+:10DFF000002108460C4602E0342038213A244B46E2
+:10E000000022042A94BF83F84C0083F84C1001329C
+:10E010000133082AF5D14B460022032A94BF83F826
+:10E020005C1083F85C4001320133082AF5D134E0FA
+:10E030005D4B9E422AD1A5F124030C2B01D8382731
+:10E0400004E0A5F134030C2B03D83A274FF0340E2B
+:10E0500012E0A5F16403282B03D83C274FF0400EB3
+:10E060000AE0A5F19503102B8CBF002746278CBF33
+:10E070004FF0000E4FF0480E4B46002201321F7544
+:10E0800083F844E00133082AF8D10AE0474B9E4266
+:10E0900069D0474B9E4200F0DF80464B9E4200F025
+:10E0A000DB80454B9E4200F0D780444B9E4200F0FF
+:10E0B000D380434B9E4200F0CF80424B9E4200F003
+:10E0C000CB80414B9E4200F0C780404B9E4200F007
+:10E0D000C3803F4B9E4200F0BF803E4B9E4200F00B
+:10E0E000BB803D4B9E4200F0B7803C4B9E4200F00F
+:10E0F000B3803B4B9E4200F0AF803A4B9E4200F013
+:10E10000AB80394B9E4200F0A780384B9E4200F016
+:10E11000A380374B9E4200F09F80364B9E4200F01A
+:10E120009B80354B9E4200F09780344B9E4200F01E
+:10E13000F481334B9E4200F08F80324B9E4200F0C0
+:10E140008E80314B9E4200F08780304B9E4200F023
+:10E1500083802F4B9E427FD02E4B9E427CD02E4BF5
+:10E160009E4271D0B5E0A5F12403082B02D84FF0F0
+:10E17000380E67E0A5F12E03022B40F29880A5F13E
+:10E180003403082B01D8382792E0A5F13E03022B77
+:10E1900044D8342747E0C046D50A8600A00B860045
+:10E1A000DA0B86004E0C860011058600F905860004
+:10E1B00049E2010066E20100A9E301001EDF01005F
+:10E1C0004DE0010013E0010098DD0100D8E00100FE
+:10E1D000F0DC0100F6DF0100F5E001008CE3010056
+:10E1E00075DF010083E2010030E001000CDC01007A
+:10E1F000BCDF01005BE30100DCE3010063DE010042
+:10E200005EDD01007BDD01003EE30100D9DF01009E
+:10E210003BDF010058DF010016068600A5F164030C
+:10E22000082B03D844274FF0380E49E0A5F16E03C0
+:10E230001E2B01D832273BE0A5F19503102B36D9D0
+:10E240004FF0000E77463BE0A5F124030C2B37D8A6
+:10E2500038274FF0340E33E09E4B9E4201D1242DDF
+:10E260005CE19D4B9E4203D18C2D29D13A2727E0BA
+:10E270009A4B9E4204D1642D1FD08C2D1DD01FE0DF
+:10E28000974B9E4203D1A5F19503102B0DE0954BC2
+:10E290009E4215D1A5F124030C2B10D9A5F134030E
+:10E2A0000C2B0CD9A5F16403282B08D908E04427CE
+:10E2B0004FF0400E04E0382702E0482700E03C27FA
+:10E2C0004B46002201321F7583F844E00133082ACF
+:10E2D000F8D1854B9E420BD0844B9E4208D0844B94
+:10E2E0009E4205D0834B9E4202D0834B9E426DD10D
+:10E2F000A5F12403082B0DD87F4B9E4201D13A2073
+:10E3000006E07E4B9E4202D13420014655E0342087
+:10E31000382152E0A5F12E03022B08D8774B9E42FC
+:10E3200014BF3821342114BF4220402045E0A5F11C
+:10E330003403082B02D8462144203EE0A5F13E03D9
+:10E34000022B06D86D4B3A219E4214BF34202C205C
+:10E3500033E0A5F16403082B06D8684B3E209E42AB
+:10E3600014BF44213A2128E0A5F16E031E2B17D8D3
+:10E37000A5F18603022B09D85F4B9E4201D14420B0
+:10E3800005E05E4B9E4201D13C2000E048208C2DF0
+:10E3900010D1594B9E420FD0584B9E420CD009E0F1
+:10E3A000A5F19503102B8CBF002146218CBF0020C6
+:10E3B0004A2002E0442100E03C214B460022013289
+:10E3C000197583F844000133082AF8D14C4B9E425A
+:10E3D00002D04C4B9E421ED1A5F124030C2B01D838
+:10E3E00038210EE0A5F134030C2B09D9A5F1640303
+:10E3F000282B05D9A5F19503102B01D9002100E0A8
+:10E40000402108464B4600220132187583F844101B
+:10E410000133082AF8D14846002202EB090191F89D
+:10E420003C301BB990F84C3081F83C304AB999F82F
+:10E430003D300BB1013204E090F84C30012289F8F4
+:10E440003D3001320130072AE7D94A46002192F8CF
+:10E4500044301BB992F84C3082F84430013101321B
+:10E460000829F4D14846002202EB090191F8343022
+:10E470001BB990F8443081F834304AB999F83530F6
+:10E480000BB1013204E090F84430012289F83530B4
+:10E4900001320130072AE7D900229CF824301BB949
+:10E4A0009CF81C308CF824309CF854301BB99CF834
+:10E4B0004C308CF854300132082A0CF1010CECD1AC
+:10E4C0002FE040274FF0000EFFF7F8BB3822FFF790
+:10E4D000ABBAC0467BDD01003EE301003BDF01003B
+:10E4E000F6DF01008CE301004B058600680586001D
+:10E4F0008505860033068600A2058600BF058600D6
+:10E50000A70686005006860036210A46FFF708BB9C
+:10E5100040274FF0380EFFF7C3BB642D3FF4CBAE5E
+:10E52000CEE6BDE8F087C0462DE9F041069D0746DE
+:10E530000E4610461946002A4ED0002B4CD0002D16
+:10E540004AD0B30A012B3FD914790EF031FEE40909
+:10E5500001460023384622460FF046D895F8651547
+:10E56000012911D195F86725531C0F2A85F86735C5
+:10E5700032D90023C5F86865064685F8653585F803
+:10E58000661585F8673527E095F8662532B90123C9
+:10E59000114685F86635C5F8686513E0D5F8683525
+:10E5A000F11A09D48B12012B06D995F86725531C53
+:10E5B0000F2A85F8673505D9002385F86735C5F832
+:10E5C000686519460E1807E0012385F86535013B9B
+:10E5D00085F8673585F866353046BDE8F081C04678
+:10E5E0002DE9F3410A9D0B9E9846002304463360B3
+:10E5F00017462B600846D9B18B784A781B0443EA4A
+:10E6000002230A781343CA78043143EA0263336071
+:10E610008B784A781B0443EA022302791343CA78B1
+:10E6200043EA02632B60427A037A53EA022001D163
+:10E630004FF48060296832680EF0A2DE0C9B014620
+:10E6400000933A4643462046FFF76EFF04463146A4
+:10E650002846002223461CF04BDC0898099900222A
+:10E6600023461CF045DCBDE8FC81C046F0B50768D8
+:10E670001C460E4687B019463846154617F07ADD17
+:10E680002268D6F8A0309A4202D22B68013B2B6058
+:10E69000D6F8A030002223600C9B384602930D9BD5
+:10E6A000716E03931346009501940492FFF798FF4F
+:10E6B00007B0F0BD2DE9F04F8A460668002189B009
+:10E6C000834690461F4689460D460791069105915F
+:10E6D000029103912BE063789D1C029B43B907AB29
+:10E6E0000093304621462A4602233EF017DD029071
+:10E6F000B9F1000F08D106AB0093304621462A46F7
+:10E700000D233EF00BDD8146039B43B905AB00931F
+:10E71000304621462A4610233EF000DD0390C5EB2B
+:10E7200007031B1B03EB080704EB05080125404604
+:10E730003946F4F3B7F504460028CCD1304607A992
+:10E740003EF036D8304606A93EF032D8CDB1DAF8E0
+:10E75000083043F04003CAF80830029B9BB1B9F17E
+:10E76000000F01D1039B73B1DBF810305AF803306E
+:10E770003BB9584651463DF0FFDE10B16FF01A002C
+:10E7800003E0002001E04FF0FF3009B0BDE8F08F5A
+:10E790002DE9704F066886B08B46104619469046A4
+:10E7A0009A460F9C109D0EF003FD014630460EF078
+:10E7B000F9DE41468146224630462B4617F002DDFF
+:10E7C0002046294600224B461CF078DB119B304640
+:10E7D0000293129B0E99039342465346009401956F
+:10E7E000CDF810B0FFF7FCFE06B0BDE8708FC04654
+:10E7F00043682DE9F04106460C4617460568F3B11B
+:10E8000099421CD12B681B7E73B1284691F8F412F3
+:10E8100004F1C2021AF00ADE7368212293F8F4129E
+:10E82000284613461AF00CDEF37B022B07D13B6817
+:10E830002BB9384606F114012422F3F39DF3BDE809
+:10E84000F081C0462DE9F7430A9C0B9D0F46814697
+:10E85000164698460094019540F00ED94346484626
+:10E86000394632460094019540F0F4D901224846D9
+:10E87000394640F0D7D9B7F8343513F0100F03D02C
+:10E88000484639463EF008D8BDE8FE8370B58B791E
+:10E8900006461546002B2DD0D1F8CC3013F4005F7E
+:10E8A00028D0107828B15378092B02D86FF00100D6
+:10E8B00024E0D1F8F042237F834204D1E8B1627FA3
+:10E8C0006B789A4219D020776B786377638843F02E
+:10E8D000020313F0080F63800FD0304621463EF04C
+:10E8E00063DD304621463EF043D9304621463EF0B6
+:10E8F000BBDE02E04FF0FF3000E0002070BDC046FC
+:10E900002DE9F743D0F8009004460027E31993F867
+:10E910003B80B8F1FF0F4CD0FD0000262046294671
+:10E9200041F06ED9002840D020462946002241F00F
+:10E9300085DE4846414601AA30F0A0DC002834D0EC
+:10E94000D0F8F01221B9002E2FD10EF059D92CE0B9
+:10E95000837933B1D0F8CC3013F4005F01D0037960
+:10E960001BB34B8813F0080F1FD0032E1DD8DFE810
+:10E9700006F002060F1620463EF0C8DE15E013F042
+:10E98000020F12D00B7F83B120463EF0FBD80CE083
+:10E9900013F0010F09D020463DF0AEDF05E013F083
+:10E9A000010F02D020463FF035DA01360235042E41
+:10E9B000B4D10137042FA9D1BDE8FE832DE9F3417D
+:10E9C000D0F8008007463EF021D9AE21404617F02E
+:10E9D000C7DB4000B8641421404617F0C1DB262491
+:10E9E000A7F84C0021464046284A1AF01FDD214670
+:10E9F000002340464FF6FF7201341AF021DD322C1D
+:10EA0000F0D126E0294600223846013441F016DED6
+:10EA100002350C2CF6D118369A2E1BD11DE0294652
+:10EA200000223846013441F009DE0235042CF6D1CB
+:10EA30000836202E12D114E029460022384601342F
+:10EA400041F0FCDD0235042CF6D10836BA2E09D18E
+:10EA50000BE03A2635460024D4E70026354600244C
+:10EA6000DDE79A2635460024E6E7384620210022D5
+:10EA700041F0E4DD032310220093404604211346B5
+:10EA800015F0A2D80020BDE8FC81C046329E85006A
+:10EA9000F0B50E4649691569908A0A68002A01DABC
+:10EAA000821831D44C68131983422DD8B36801F110
+:10EAB000080C0CEB040705EB020E6BB9184608E0D6
+:10EAC00010F80E3010F80C20C15D134099421BD194
+:10EAD0000130A042F4DB19E0012B15D12B18C4EB57
+:10EAE00003050DE010F80E3010F80C20C15D134046
+:10EAF000994203D10130A042F4DB07E00EF1010E90
+:10EB0000AE4501D80020F6E7002000E00120337B6D
+:10EB10000BB180F00100F0BD036870B50446586881
+:10EB2000A36A0D46164623B99021F8F3D1F0A062EE
+:10EB300070B1A06A0123AA8A03607F3382604660B5
+:10EB4000C360296910309A4228BF1A46F3F314F2C1
+:10EB500070BDC04668468369416920300BB52038D6
+:10EB600003695A4651460EB44A46414606B4C36844
+:10EB700082684168FEB40368C269EFF303810EB492
+:10EB80008269EFF3058106B4034801680029FED0CD
+:10EB90006846884714B000BD3CEC00000A490842B2
+:10EBA00002D062B6C94308400849084202D061B6A3
+:10EBB000C943084006490840002803D005490A68AF
+:10EBC00002430A607047000000000080000000401F
+:10EBD000FFFF000000E100E00A49084202D072B6DF
+:10EBE000C94308400849084202D071B6C9430840E9
+:10EBF00006490840002804D005490A68C04302407D
+:10EC00000A6070470000008000000040FFFF000025
+:10EC100080E100E0024909689022885870470000AE
+:10EC200048EC0000024909689C22885070470000A7
+:10EC300048EC0000DDBAADBB0000000000000000A1
+:10EC400000000000000000000000000000000000C4
+:10EC50000000000000000000024A11681060081C5B
+:10EC6000704700003CEC0000024A11681060081C6C
+:10EC70007047000040EC0000034908600348016849
+:10EC80000029FED08847FEE734EC000040EC00008D
+:10EC90006348644900220A500168634A0A40634F8E
+:10ECA0000F403F4232D1002398469A46604A0A40BC
+:10ECB0001821CA405F4943585F4C1C405F4DAC422D
+:10ECC00004D180465E4D4519A9460EE05D4DAC422B
+:10ECD0000BD182465A4D4519AB460F241D1C2340CB
+:10ECE000594C25402D0A2B439C460023984501D0C2
+:10ECF0009A4504D1554BC018013ADCD105E0504685
+:10ED0000004202D04046004229D1FEE7FC21415892
+:10ED10000A680F2313400F2BF1D0012B01D00431CF
+:10ED2000F6E708314A4B13404A4CA34206D100F0A3
+:10ED3000BBF8804600F0C4F88146E9E7464CA342A0
+:10ED4000E6D10B1F1B68454C23401824E3409C462A
+:10ED500000F0AAF8824600F0B3F88346D8E74049AD
+:10ED6000212242502E4A3F498958FF23194219D087
+:10ED700051683D4B194215D011683C4B1940D36A7C
+:10ED800010E0A3420ED0C0460CE039498958194220
+:10ED900008D03849895819409942FAD12B4B11694A
+:10EDA0001942FCD049463F4204D19823CB58102445
+:10EDB000E34001E0304BCB581C242340002B01D012
+:10EDC00000F08CF840462D49086048462C49086000
+:10EDD00050462C49086060462B4908602B490F605B
+:10EDE0002B4D2C490D60043DAD46009DEC43102396
+:10EDF000DD41AC4201D081B009E0240CA400264DD5
+:10EE00002C606B461B1B254D2B60043B9D46244804
+:10EE10002449002204C08142FCD80EF0E5FAFEE746
+:10EE20000000001814060000F8FF0000000000F0C9
+:10EE30000000000FFC0F0000F08F0000A082000017
+:10EE4000000F0000E08000000070000000100000D3
+:10EE500000FF0F00002A0800000E0800000000FF5D
+:10EE6000E00100000406000000003800FFFF000081
+:10EE7000180600000C0600000804000048EC000022
+:10EE80004CEC000050EC000054EC000044EC00009E
+:10EE900000C00300F81E0200001F0200FC1E02005A
+:10EEA000AC270200182C020008680F22043102402F
+:10EEB000052AF9D1014A1040F746000000F0FFFF93
+:10EEC00008680F2204310240052AF9D1802210423D
+:10EED000F6D0014A1040F74600F0FFFFFEE70000C1
+:10EEE00010B57146034802F0DFFB40F61100FFF752
+:10EEF000C3FE10BD8E1F860010B5002128220446D7
+:10EF0000F3F39EF00A4B23600A4B63600A4BA36045
+:10EF10000A4BE3600A4B23610A4B63610A4BA3610E
+:10EF20000A4BE3610A4B23620A4B636210BDC04681
+:10EF300000000000C71D0200C81D0200AC2702002F
+:10EF4000AC270200182C0200182C020021D202006B
+:10EF500024D20200005903002DE9F04399B00CA817
+:10EF6000FFF7CAFF0C9B0D99DFF8DC91C91A0F9DC2
+:10EF70000E9BD9F80060ED1A119C109B06F5A05667
+:10EF80006048E41A76180B9102F08EFB0B9905F598
+:10EF90007E7376190733361901F57E729B0A019448
+:10EFA00004F57E740732009307340523A40A920AFD
+:10EFB000039355482B460294DFF8848102F074FBDA
+:10EFC000524BD8F800401968D9F80050C4EB01033F
+:10EFD00003F57E7001F57E7207300194039504F508
+:10EFE0007E7405F57E75800A073207340735920A6C
+:10EFF0000090A40AAD0A46480294049502F054FB1E
+:10F00000444B45481968D8F80030C91806F57E7396
+:10F0100001F57E7207339B0A0732920A009333464A
+:10F0200002F042FB3D4B3E48196802F03DFB3D4B70
+:10F030001F683D4B3A689A4203D03C4802F034FBCB
+:10F0400024E0179705E03268374B9A4205D1331D0B
+:10F050001793179E16AB9E42F5D3354BC7EB0600B0
+:10F060001A6817ABC7EB0301C3EB0204C6EB02053A
+:10F070000092019102910390049039462D48324646
+:10F08000059406940795089502F00EFB2A4C20681B
+:10F09000002834D0C588F3F363F52368013D5C890B
+:10F0A0004FF4806104FB05F6443405FB04F406F5D7
+:10F0B0007E73073393FBF1F3009304F57E730733FC
+:10F0C00093FBF1F302460293294633461B48019411
+:10F0D00002F0EAFA1A4B0F4A1B681268C6EB0306E5
+:10F0E0009B181B1B03F57E7106F57E720731890A9A
+:10F0F0000732009113483146920A02F0D5FA19B04E
+:10F10000BDE8F083E11F8600F01F8600C8260000DE
+:10F110002E208600A4260000722086009026000083
+:10F12000AC208600F82702004B415453C6208600CD
+:10F13000FC270200E9208600BC260000662186002C
+:10F140008826000092218600CC2600000D4B10B5C9
+:10F150001A680D4CD2F81416D2F8143699420B4B9B
+:10F1600018BFD2F8141622681B68C2EB010098423F
+:10F1700001D2002004E0B0FBF3F003FB0023236086
+:10F1800010BDC0469C260000E4260000C8250000F3
+:10F190002DE9F04301688FB0022907461AD15A4B76
+:10F1A0005A481A6800235361046814F4805F11D030
+:10F1B000574B584A1960C169043B1960136804230E
+:10F1C000136024F4805343F400530360524802F068
+:10F1D0006BFA96E03B680C2B14D14C4C236813F46B
+:10F1E000005F0FD023F4005343F400632360676093
+:10F1F0004A48F96C02F058FA236803F40063002BC4
+:10F20000FDD17EE03B68103B0F2B02D8F7F3E2F014
+:10F2100077E03E4B4248D96902F046FABA6C786C06
+:10F22000BC68FD683968FB6C009201903A463D4825
+:10F230000294039502F038FA3B4B7E6C1B68F86928
+:10F24000D7F828E03C6A7D6A9B1B39697A694FEAE6
+:10F250009309BB6900903548CDF80CE00194029504
+:10F2600002F022FAB86BFC6B3D6CF96A3A6B7B6B6F
+:10F2700000902F480194029502F016FAF068316868
+:10F280007268B36800902B4802F00EFAF069316999
+:10F290007269B3690090284802F006FA04A8FFF7E3
+:10F2A0002BFE264802F000FA0024A04625461CE06A
+:10F2B000725912F0010F13D0FF2A11D9059B9A42FF
+:10F2C00008D91F4B1B0D1B059A4209D303F5801368
+:10F2D0009A4205D81B48294602F0E6F908F10108D0
+:10F2E0000435B8F10F0F02D801344C45E0D1074A7C
+:10F2F00040F203301368576043F480631360FFF7F4
+:10F30000BBFC0FB0BDE8F0837428020000280200A7
+:10F31000241000E0281000E0C4E50100C8E5010069
+:10F32000D4E50100E1E50100F81E020015E6010048
+:10F3300048E6010077E6010095E60100FC1C860026
+:10F340009D668000B2E60100F0B51F4E8BB06846A6
+:10F35000FFF7D2FD3578F5B90698079B1C1A07D040
+:10F3600029462246F2F36CF606982146F6F358F742
+:10F370002146164802F098F9154B1D700123337091
+:10F38000144B1968E9B10B78DBB1134B2A461868A6
+:10F39000F3F34AF415E0114F3D7895B90898099BAD
+:10F3A0001C1A07D029462246F2F34AF6089821464D
+:10F3B000F6F336F70A48214602F076F90123357054
+:10F3C0003B700BB0F0BDC0463C280200C9E601000E
+:10F3D0003E280200BC260000242802003D2802002E
+:10F3E000FBE6010010B50446FBF384F60146204617
+:10F3F00000F034F910BDC04670B50446FBF37AF650
+:10F400002046FBF3B7F505462046FBF337F500220F
+:10F41000064640F62A012046FBF3F0F60123AB40F6
+:10F420008269134201D0002500E0013520463146B3
+:10F43000FBF3F6F6284670BD10B5FFF7DDFF10BDF3
+:10F440002DE9F04107460C46FBF354F63846FBF332
+:10F4500015F540F62A01804600223846FBF3CEF629
+:10F4600083690646456944B14FF4004043F00044C7
+:10F4700045F00045FFF792FB07E04FF4004023F012
+:10F48000004425F00045FFF7A7FBB46138467561DD
+:10F490004146FBF3C5F6BDE8F081C0462DE9F041D9
+:10F4A0000E465021804617461D46F7F311F40446D8
+:10F4B00018B300215022F2F3C3F540F23C736363AA
+:10F4C000A3F55573E363A3F5737323640C2363649B
+:10F4D00004230020E56026606760C4F80880A36408
+:10F4E0000749F3F349F2C0B284F84C000138C0B2C6
+:10F4F000012802D9022384F84C302046BDE8F0816F
+:10F500003E2986000048704718F9010000487047FE
+:10F5100090F901000048704700A60E00D2F80036AE
+:10F5200070B50546C3F38404FFF7ECFF03E083786E
+:10F53000A34204D00C3020B10388002BF7D10388FC
+:10F5400013B92846FFF7E2FF03884FF47A7003FBF4
+:10F5500000F070BD0123C2F8603610B5D2F86446E1
+:10F56000FFF7D8FF04F0FF04B0FBF4F34FF47A7018
+:10F5700003FB00F010BDC0462DE9F0411C460646D5
+:10F580001546FBF37BF4002107463046FBF348F6B3
+:10F590000223C0F8583654B1D0F85C3605F03F026B
+:10F5A00023F4FC4343EA4223C0F85C3603E0D0F87E
+:10F5B0005C36C3F3452530463946FBF331F6284621
+:10F5C000BDE8F0812DE9F041DFF860800646D8F80B
+:10F5D000004034BBFBF352F4214607463046FBF3B0
+:10F5E0001FF6D0F81456D0F8143604469D4218BFC2
+:10F5F000D0F8145642F21070F7F3AEF0D4F8142697
+:10F60000D4F8143630469A4218BFD4F81426394636
+:10F61000C5EB0203642203FB02F3C8F80030FBF3DE
+:10F62000FFF5024B1868BDE8F081C046842802004F
+:10F6300070B504460D46FBF321F400210646204632
+:10F64000FBF3EEF5294602462046FFF783FF3146DD
+:10F6500005462046FBF3E4F5284670BD10B5FFF7DC
+:10F66000E7FF10BD70B504460D46FBF307F400211B
+:10F6700006462046FBF3D4F5294602462046FFF70E
+:10F680004DFF314605462046FBF3CAF5284670BDBE
+:10F690002DE9F04F1746C7F820361D46036A85B09E
+:10F6A0000C2BCBBFD2F82836D2F82836C3F3094B3F
+:10F6B000C3F3072B01230024AB4080468946029404
+:10F6C00003940094F6F30AF30646012212FA04F3B7
+:10F6D000334207D00092404649463A46F6F3FEF2DE
+:10F6E00026EA000601341F2CEFD1404603A902AAE6
+:10F6F000F6F31EF3039B00256FEA030A2C46012351
+:10F70000A34006EA0A021A4208D0404649463A4651
+:10F71000E3B2FFF7BDFF854238BF054601341F2C19
+:10F72000EDD10BF10200401905B0BDE8F08FC046E5
+:10F730002DE9704305468846FBF3A0F3002181467E
+:10F740002846FBF36DF50446284600F0F3F8224600
+:10F750000646414618232846FFF79AFF0B2302303E
+:10F7600000FB03F0074C49463419B4FBF6F404FBE4
+:10F7700000F42846FBF354F50A23B4FBF3F4A0B2DB
+:10F78000BDE870833F420F0073B5044616461D4620
+:10F7900000914FF4CB6200214FF0FF33FBF376F37F
+:10F7A0002046002140F25C6233460095FBF36EF385
+:10F7B0007CBDC046002270B513460C4604210546A8
+:10F7C000FFF7E2FF012C20F0F07308BF43F0F07365
+:10F7D000284604214FF0FF32FFF7D6FF012C03D15A
+:10F7E00049F64040F6F3B8F770BDC04610B50021A9
+:10F7F000FFF7E0FF10BDC04610B50121FFF7DAFFAB
+:10F8000010BDC04610B508B1F6F366F510BDC04690
+:10F8100070B5094B06461D6808E030462C68FBF3BE
+:10F8200069F429466A68F7F363F22546002DF4D19E
+:10F83000014B1D6070BDC0466C270000002343666D
+:10F840007047C0467047C0460020704710B5FFF7AC
+:10F85000D3FF10BD10B5FFF7C9FF10BD2DE9F04172
+:10F8600006460D461446FBF30DF4804618B93046A3
+:10F870000121FBF345F4304613F032FA074610B984
+:10F880006FF01D0415E014B96FF0190418E04FF083
+:10F8900000032B80002404F182013846F2F34AF27F
+:10F8A000C0B2A0402B8801341843052C2880F2D127
+:10F8B0000024B8F1000F03D130464146FBF320F499
+:10F8C0002046BDE8F081C04607B54FF0000302A90D
+:10F8D00021F8023D0122FFF7C1FFBDF806000EBD71
+:10F8E000416E2DE9F041044661B1D0F8C83000EB1B
+:10F8F0008303D3F8D020C36D9A4203D1006E8847AA
+:10F90000064600E000262046616DFFF711FFA56E58
+:10F9100007465DB1D4F8C83004EB8303D3F8D02098
+:10F92000E36D9A4202D1206E3146A8473846BDE8C1
+:10F93000F081C04610B50446FBF3DCF301462046D7
+:10F94000FFF740FE10BDC04610B50446FBF3D2F3EE
+:10F9500001462046FFF786FE10BDC046416E2DE9E8
+:10F96000F041044661B1D0F8C83000EB8303D3F80E
+:10F97000D020C36D9A4203D1006E8847064600E04E
+:10F9800000262046616DFFF753FEA56E07465DB168
+:10F99000D4F8C83004EB8303D3F8D020E36D9A4247
+:10F9A00002D1206E3146A8473846BDE8F081C046F6
+:10F9B00043692DE9F743222B06460F4640F3A0800A
+:10F9C000FBF314F4002800F09B80072F00F29880CE
+:10F9D000B268B2F5026F01D101220AE040F60403D9
+:10F9E0009A4201D0002204E0F3680C2B94BF00225D
+:10F9F00001225FFA82F8B8F1000F0BD130464FF4C4
+:10FA000000614246D6F8C890FBF3F8F3054600289B
+:10FA100077D006E0D6F8843013F5405571D04FF01A
+:10FA20000009032F03D030460121FBF379F4D5F808
+:10FA3000303123F00403C5F8303101239F42C5F86B
+:10FA4000303103D9042F01D0083300E00D23C5F86D
+:10FA50003031D5F83031012F23F00103C5F83031B2
+:10FA600001D9042F36D1FF2400214FF4E27223463E
+:10FA700030460094FBF30AF22223009300214FF456
+:10FA8000EE7223463046FBF301F228230093002157
+:10FA90004FF4E67223463046FBF3F8F181230093DE
+:10FAA00000214FF4E87223463046FBF3EFF10123C7
+:10FAB000009300214FF4A4724FF0FF333046FBF364
+:10FAC000E5F1304600214FF4A6724FF6FF73009423
+:10FAD000FBF3DCF1D5F8303123F0700343EA071370
+:10FAE000C5F83031D5F8303123F00803C5F830318E
+:10FAF000B8F1000F05D130464946FBF391F300E021
+:10FB000000252846BDE8FE8370B50446FBF36EF37E
+:10FB1000002839D0A268B2F5026F01D101220AE0B3
+:10FB200040F604039A4201D0002204E0E3680C2B63
+:10FB300094BF00220122D5B24DB920464FF4006196
+:10FB40002A46D4F8C860FBF359F3E8B105E0D4F8CD
+:10FB5000843013F5405017D00026D0F8303123F010
+:10FB60000403C0F8303143F00103C0F83031C3F36F
+:10FB70000213032B03D020460021FBF3D1F31DB960
+:10FB800020463146FBF34CF370BDC0462DE977416A
+:10FB90000022012113460546F6F352F10024804667
+:10FBA00021462822234628460094FBF36FF10121C9
+:10FBB0000646434628464FF0FF32F6F341F1284609
+:10FBC000214628224FF0FF330096FBF35FF1BDE89A
+:10FBD0007E81C046D0F86C32994201D0002004E00A
+:10FBE0008B79D3F1010038BF002070472DE9F04137
+:10FBF000002605460446374608E02B68216A9868C7
+:10FC0000FFF32CF500B90136013718346B689F42B9
+:10FC1000F3DB3046BDE8F08103682DE9F0411E6852
+:10FC20000546B7688846144638462969FFF316F535
+:10FC300044B133681B7E2BB1384629694246012303
+:10FC4000FFF3C4F4BDE8F08170B505460446002614
+:10FC50000DE0616949B1236A3BB1182006FB00F051
+:10FC6000103028180122FFF7D7FF013618346B68CF
+:10FC70009E42EEDB002070BD2DE9F3411F46036874
+:10FC8000044601910092DDF820801E6809B10D291B
+:10FC900041DD61680022FFF7BFFFE1680025656074
+:10FCA00031B1236822891B685868F7F321F0E560B9
+:10FCB000009B2BB1B3F5967F02DA6FF01C002CE0AD
+:10FCC00030464146FFF786FF28B3019969B12368A2
+:10FCD0001B685868F6F3FCF7E06010B96FF01A0083
+:10FCE0001BE03946019AF2F347F101A90422C4F856
+:10FCF000148004F10800F2F33FF1201D694604224C
+:10FD0000F2F33AF1009840B1204661680122FFF712
+:10FD100083FF002001E06FF00100BDE8FC81C046D8
+:10FD20002DE9F047154686B00268DDF84080DDF821
+:10FD300044A005F00103009306465346106842466E
+:10FD4000DDF84C9013F0C0DA0746002840F0A1809F
+:10FD5000022D54D0032D1FD0012D02D06FF01607B5
+:10FD600097E04146042203A8F2F306F1022208F1CB
+:10FD700004010DF11600F2F3FFF056F8100B49469E
+:10FD8000BDF81640039D2FF035DB214600902A4632
+:10FD9000304608F106032EE00222414605A8F2F3A0
+:10FDA000EBF0042208F1040103A8F2F3E5F00222CB
+:10FDB0000DF1160008F10801F2F3DEF0BDF8143081
+:10FDC000012B02D06FF0240763E098F80A70736883
+:10FDD0009F425CDA49463068BDF81640039D2FF01B
+:10FDE00009DB182307FB03F3103300902146F018BA
+:10FDF0002A4608F10B03FFF73FFF074649E00E9B39
+:10FE00001A6873689A4242DA002A40DB4FF0010315
+:10FE1000ADF8143004924FF00B030DF116012A4691
+:10FE200008F10200ADF81630F2F3A6F005A92A4653
+:10FE30004046F2F3A1F004991824013101FB04615A
+:10FE40002A4608F10800F2F397F0012204A908F10C
+:10FE50000A00F2F391F00499042201FB046108F115
+:10FE600004001431F2F388F0049B013303FB04F324
+:10FE70009A5B991902F10B039A4502D26FF00D07B4
+:10FE800007E008F10B004968F2F376F001E06FF04B
+:10FE90000107384606B0BDE8F087C046F7B50168EF
+:10FEA00005460E6896F87032002B2CD002894769FF
+:10FEB0003AB9304607F1BC011346009218F0D0D889
+:10FEC00021E0898970688918F6F35AF72A68044690
+:10FED00018B993680133936015E09289A38A006989
+:10FEE0009B1A8018A382E9682A892061F2F344F002
+:10FEF00004F124025389304643F0400353812146E4
+:10FF0000BA6818F04FD9FEBD13B54FF0000310F0DA
+:10FF10000104ADF8063006D0002904DD10F8013BDD
+:10FF200001398DF8073010F0030F05D0012903DDEA
+:10FF300030F8022B023913E0002211E00368D218D6
+:10FF4000436828BF0132D218836828BF0132D21813
+:10FF5000C36828BF0132D21828BF013210301039CF
+:10FF600031F00F03EAD113041B0C03EB124203E040
+:10FF700030F8023C0239D218034602300129F7DC7E
+:10FF800004BF1B788DF80630BDF80630D3181A046C
+:10FF9000120C02EB134213041B0C03EB124024B1AE
+:10FFA000030243EA10231804000C1CBD10B5FFF730
+:10FFB000ABFF02E003041B0C9818020CFAD1C043FB
+:10FFC00080B210BD2DE9F041BDF818500C4629460D
+:10FFD00016469846FFF798FF3204120C02EB1442C3
+:10FFE0002404240C121905F0FF0302EB16421B0235
+:10FFF00002EB082243EA1523D218101802E003048A
+:020000021000EC
+:100000001B0C9818020CFAD1C04380B2BDE8F081F5
+:100010002DE9F0418D8A16460D2D1F460C6952DDE3
+:10002000A38904F10C0003F0FF021B0A43EA022338
+:10003000B3F5C06F0BD2152D45DD254804F10E0137
+:100040000622F1F37DF700283DD104F11400038866
+:1000500003F0FF021B0A43EA0223B3F5014F0AD162
+:100060000430821C63199A422DD8038803F0FF02E2
+:100070001B0A43EA0223B3F5006F24D1811CC4EBB1
+:100080000103C3EB0504132C1DDD82781309042B37
+:1000900019D102F00F039A00132A14D9A24212DCDC
+:1000A0008A78CB7843EA0223A34201DA1C4600E0B7
+:1000B00009DC8A79CB7943EA02239804800C10B9D1
+:1000C00031603C6001E04FF0FF30BDE8F081C04698
+:1000D00035FA01002DE9F043436887B013F0020FB1
+:1000E0000546884600F08F8005AA04ABFFF790FF15
+:1000F0000028C0F288800598037803F00F039E0063
+:100100003146FFF753FF48B1B8F8163023F010031B
+:10011000A8F816302B6A01332B6274E0EB69059F57
+:100120000133EB6197F80990B9F1060F24D107F17B
+:100130000C01042202A8049CF1F31EF70599042285
+:100140001031A41B03A8F1F317F7A4B2B819029950
+:10015000039A4B460094FFF735FF48B1B8F81630C4
+:1001600023F01003A8F81630AB6A0133AB624AE003
+:100170006B6A01336B623EE0B9F1110F24D107F1D4
+:100180000C01042203A8049CF1F3F6F6059904225D
+:100190001031A41B02A8F1F3EFF6A4B2B819039929
+:1001A000029A4B460094FFF70DFF48B1B8F816309D
+:1001B00023F01003A8F816302B6B01332B6322E0D9
+:1001C000EB6A0133EB6216E0B9F1010F13D1049928
+:1001D000B819891B89B2FFF7E9FE48B1B8F81630A3
+:1001E00023F01003A8F81630AB6B0133AB630AE0C1
+:1001F0006B6B01336B63B8F81630002043F01003CB
+:10020000A8F8163001E04FF0FF3007B0BDE8F083EA
+:100210002DE9F043436887B013F0010F804600F0EA
+:100220008780CB8A13F0080F03D183680133836082
+:100230007EE005AA04ABFFF7EBFE002878DB059A09
+:1002400000271378977203F00F039E00D772314690
+:100250000598FFF7ABFE059B9872C0F30F20D8728C
+:10026000D8F80C3005990133C8F80C3091F8099092
+:10027000B9F1060F21D18D19049C0C3104222F7481
+:100280006F7402A8F1F378F6059904221031A41BCB
+:1002900003A8F1F371F6A4B24B4628460299039ADB
+:1002A0000094FFF78FFE2874C0F30F206874D8F80D
+:1002B00010300133C8F810303AE0B9F1110F22D1F3
+:1002C0008D19049CAF71EF71059904220C3103A8BC
+:1002D000F1F352F6059904221031A41B02A8F1F3A0
+:1002E0004BF6A4B24B4628460399029A0094FFF7B6
+:1002F00069FEA871C0F30F20E871D8F814300133FB
+:10030000C8F8143014E0B9F1010F11D18C19049917
+:100310002046891BA770E77089B2FFF747FEA070DF
+:10032000C0F30F20E070D8F818300133C8F8183047
+:1003300007B0BDE8F083C0462DE9F34114460A9F9B
+:100340000268DDF82C8004F0010300930546434663
+:1003500010683A4612F0B8DF064618BB052C04D8E0
+:10036000DFE804F00A061403030D6FF0160619E027
+:10037000281D3946042213E06B683B6012E005F14A
+:10038000080000214C22F1F35BF60BE0B8F14B0FB3
+:1003900002D86FF00D0605E0384605F108014C2241
+:1003A000F1F3EAF53046BDE8FC81C04610B58C6B30
+:1003B00000200BE00B1893F83C30064A03F07F0353
+:1003C000D356002B01DA012003E00130A042F1D125
+:1003D000002010BD401B86002DE9F84F02298346FE
+:1003E0000E4690469A4614BF4FF0FF37002714BFC1
+:1003F000002401244FF000092EE0022E14BF4FF01C
+:10040000FF3300239F4211D0022E08D1B8F1040F10
+:1004100007D0B8F1060F04D0B8F1080F01D00422BC
+:1004200000E00022C7EB0403934214DD0E2CCCBF86
+:100430004FF480534FF4005344F4306213439DB2A1
+:10044000DBF85C01294635F0A9DF20B12AF8195004
+:10045000274609F101090134022E0CBF0E230023A7
+:100460009C4202DCB9F11F0FC7D90A9BC3F8009068
+:10047000BDE8F88F2DE9F04F88469BB0402100275A
+:10048000DDF890B09DF894900646C0F82077C0F84B
+:100490001C1740689A46F6F31BF40446C6F8180782
+:1004A00010B96FF0150473E0D8F800306BB9203341
+:1004B000C6F82037336B30461A8906F5E46300939B
+:1004C00059462346FFF788FF1FE0202B6CD845468E
+:1004D00017E0AC88D6F85C01214635F05FDF0028D4
+:1004E00062D01FB12B78E2B29A425DD9D6F820379C
+:1004F000D6F81827013722F813400133C6F8203701
+:100500000435D8F800309F42E3D3D6F82037002BCB
+:100510004AD070681021F6F3DBF30746002835D087
+:10052000279B002411AD446083600473214606605C
+:1005300080F80DB080F80E9024222846F1F380F563
+:10054000A24514BF0023012301934FF0FF33029310
+:10055000039304930593D6F8183730460693D6F8DC
+:10056000203702210793144B144A0A9303230C9358
+:100570000123089409940D940E9400950B9716F09E
+:10058000BBDC044698B9269B7B6010E06FF01A0430
+:10059000D6F8181759B17068D6F81C27F6F3A8F3E7
+:1005A0000023C6F8183702E06FF00104F0E7204698
+:1005B0001BB0BDE8F08FC046410B01002C9E8500AA
+:1005C00030B590F8143789B00446002B3ED0D0F8EF
+:1005D00068319D79002D62D1036880F814571B7E25
+:1005E000002B5CD0B0F81637002B58D0036B18697D
+:1005F00002F09CFAB4F81617884250D0204618F042
+:10060000CFDB204601F0EEF82046B4F8161718F0BC
+:100610000DDA236893F82F306BB1D4F86C32204692
+:10062000D3F8D412383113F0B9D80146C4F8AC0667
+:1006300020460CF051D920461AF068DC20462946A5
+:100640001AF06EDE204611F0DBDC28E003681B7E2A
+:100650002BB3D0F868319B790BBBD0F8000507A904
+:1006600044F038DD03E02B7E13F0020F17D107A80A
+:1006700044F038DD05460028F5D1236B05901B6852
+:1006800005A90093032301930290039001222046C1
+:100690002B46FFF7EFFE10B9012384F8143709B099
+:1006A00030BDC0462DE9F74F0192D0F800A090F878
+:1006B0000D801F460C464FF0000BE5E0072200219D
+:1006C0002046F1F3BDF40C9AB8F1020F12F81B00AA
+:1006D000207001D0022308E0042F05D0062F03D09C
+:1006E000082F01D0434600E00023C3EB0002B8F11D
+:1006F000020F14BF002301239A4210DBB8F1020F4E
+:1007000001D0022108E0042F05D0062F03D0082FC6
+:1007100001D0414600E00021C1EB00060FE0B8F136
+:10072000020F14BF0026012606E0DAF85C0131460C
+:1007300035F0F2DD18B9013623789E42F5D9B8F1CB
+:10074000020F207802D0002202230BE0042F07D0F2
+:10075000062F00F0A680082F00F0A3804346A1E0FA
+:100760000E2200231B1893420FDCB8F1020F01D0B8
+:10077000022108E0042F05D0062F03D0082F01D056
+:10078000414600E000210D180FE0B8F1020F0CBF48
+:100790000E25002506E0DAF85C01294635F0BCDDBF
+:1007A00018B9013D23789D42F5D24FF0000963E06E
+:1007B00002EB89039968CB88B1F832E013F020038B
+:1007C0005FFA8EF00DD00EF44072B2F5807F02D148
+:1007D000821C023806E0B2F5007F02D1821E023090
+:1007E00000E00246B04201D3A84203D9B24241D34D
+:1007F000AA423FD8B3B1B04214D3A84212D80EF4E3
+:100800004073B3F5807F05D12379FF2B0AD00133E4
+:10081000237107E0B3F5007F04D16379FF2B01D08A
+:1008200001336371CB8813F0200F0BD0B24209D390
+:10083000AA4207D8824205D0A379FF2B1AD00133F0
+:10084000A37117E023780E2B0FD85046FFF7AEFDAB
+:1008500028B1E378FF2B0DD00133E3700AE0A378D1
+:10086000FF2B07D00133A37004E06378FF2B01D086
+:100870000133637009F10109DAF818251368994505
+:1008800096D30BF1010B07340D9B9B4504DA019ABB
+:1008900013689B45FFF612AF019BC3F800B0BDE89B
+:1008A000FE8F00230E225DE72DE9F84F5FFA83FCEF
+:1008B0001E4603F44073B3F5007F14BF4FF00009E8
+:1008C0004FF0010905468A4693460CF10200ACF14F
+:1008D0000203B9F1000F02D08646984601E09E4619
+:1008E00080460027394629E011F80A40ACF105039B
+:1008F0009C4221DB0CF105039C421DDC0AEB01004C
+:1009000082783AB9C3782BB903791BB943790BB90B
+:1009100083798BB1744506D1837993B9B9F1000F0E
+:1009200008D0037907E044450BD152B9C37843B9E5
+:10093000037933B9437923B9013707315F45D3DBF5
+:100940001BE0BEF10E0FD4BF4FF400534FF48053A1
+:100950004EF4306213439CB2D5F8FC341B7893B14B
+:100960002846002124F048D8284624F03BD80AE045
+:100970002846012124F040D804E0D5F8FC341B7847
+:10098000002BF5D134462046BDE8F88F2DE9F04F15
+:10099000D0F8008090F80DA0D8F83010DDB00989AB
+:1009A000814614464FF0000B5B9300E004210022C7
+:1009B0005B98964608E01EF804300EF1070E052BF2
+:1009C00001D9934602E001328242F4DB082900F2A9
+:1009D000B08001A252F821F0FD090100330B0100A3
+:1009E000030A0100330B0100AF0A0100330B0100C1
+:1009F000330B0100330B0100AD0901004FF6FF7608
+:100A00001AE00025AE464FF6FF7612E00EEB0B0221
+:100A100092FBF0F300FB1323072203FB02F16218A1
+:100A2000937823B9D378B3423CBF655C1E460EF180
+:100A3000010E8645EADB15B90025AC4621E00E2DF6
+:100A400094BF4FF400524FF4805245F4306343EAB0
+:100A500002006FE00CEB0B0292FBF0F300FB1323A0
+:100A6000072203FB02FE04EB0E0359789A78DB7829
+:100A70005218D218B242BCBF14F80E5096B20CF104
+:100A8000010C8445E6DB3DB99BFBF0F300FB13B39F
+:100A9000072203FB02F31D5D0E2D94BF4FF400539C
+:100AA0004FF4805345EA030343F4306042E0BAF167
+:100AB000020F3ED15AAB00930024404651465246A5
+:100AC0004AAB5A94FFF788FCD8F818771FB3D8F8C8
+:100AD000206706B35A99254610E000243AAB37F850
+:100AE0001520E05A904205D15CAA02EB410323F89D
+:100AF000480C01310234402CF0D10135B542ECDB19
+:100B000020230E485B935A9100F0CEFD4AAB009330
+:100B10005A9B02AC04E020233AAA5B9302AC0092F9
+:100B20000193214648465BAA0223FFF7BBFD022141
+:100B30003DE700205DB0BDE8F08FC046B4FA01008B
+:100B4000F0B50546BDB004680E4609B108292DD19F
+:100B50002023D4F818273B93236B03AF1B89009203
+:100B6000D4F82027394601923BAAFFF79BFD6B7B07
+:100B7000022B13D1D4F8FC341B787BB1D4F8343772
+:100B8000B3F8A4E30EF44063B3F5406F06D12046FA
+:100B900039463B9A7346FFF787FE05E02846002159
+:100BA00003AA3B9BFFF7F2FEA4F816076B6813B18C
+:100BB000A86831469847D4F81817D4F81C276068FD
+:100BC000F6F396F00023C4F818376068294610221F
+:100BD000F6F38EF03DB0F0BD7047C04610B5C3F8D7
+:100BE000A010082019461C4631F03ADE84F8A40013
+:100BF00010BDC0467047C0460020704700207047B7
+:100C0000002070477047C0467047C0467047C046D6
+:100C1000002070477047C04603680246D3F86C3224
+:100C2000D3F8E432987818B1938A181E18BF0120BF
+:100C30007047C0467047C0467047C04670B5037DD8
+:100C400004469BB1457D8DB9C068A169FEF306F5E8
+:100C500001236375E36906460BB1A0689847D6F196
+:100C6000010038BF00206575257500E0002070BDCB
+:100C70000846002110B5016141810172017306220D
+:100C8000F1F3DEF110BDC04610B50068F4F7B0F81E
+:100C900010BDC04690F832007047C0460246086852
+:100CA000430D5B056BB922F07F4323F46003520DC3
+:100CB00083422CBF4FF40013002352059B180343BB
+:100CC0000B60704770B510600D461C46084619460B
+:100CD0001646FFF7E3FF2368AB4202D233680133C5
+:100CE000336070BD002070477047C04600207047D9
+:100CF000002070477047C0467047C0467047C046E6
+:100D000030B50568B5B061B10DF107040171C922B4
+:100D100000212046F1F394F12B6B2146186902F073
+:100D20001BFF35B030BDC046406B70477047C046B2
+:100D3000002070477047C046002070477047C0468B
+:100D4000002070477047C046002070477047C0467B
+:100D50007047C0467047C0467047C0460020704785
+:100D60007047C0467047C046002070477047C04675
+:100D70007047C0467047C0467047C0464FF0FF30CE
+:100D80007047C0467047C04600207047002070473B
+:100D90007047C0467047C0467047C0460020704745
+:100DA0007047C04603490A6812B100230B60104621
+:100DB0007047C046E82B020070B515460C464E6CD5
+:100DC00018F00CD9024628B915F4001F02D0636C44
+:100DD0006664A364104670BD73B500EB420440F630
+:100DE0002A15B4F82C66A4F82C56069D009503F03D
+:100DF0008FDCA4F82C667CBD10B511F0F7DC024640
+:100E000040B1416A11F4002F04D1036813B141F4D9
+:100E100000234362104610BD2DE9F3411E460368CE
+:100E200004461B7E0F469046002B4BD090F875323F
+:100E3000002B47D10D682846FFF776FF016902466F
+:100E40008B79B3B1837E13F0010F12D0D1F8CC307F
+:100E500013F4806F0DD1B4F8263603F47043B3F564
+:100E6000805F14BF40234423CB5813B193F8DF3085
+:100E700043BB5168002925DB164B01EA03030BB97C
+:100E8000184602E0EB8A03F0070011F0400F19D07A
+:100E9000114B02A91B5C204641F8043D336009F068
+:100EA000EFDDB0F1FF3F0DD0019A3368934209D0D6
+:100EB0000A4B32609A5CEB8A02F0070223F00703C8
+:100EC0001A43EA82204639464246334614F06CD82B
+:100ED000BDE8FC8140000180C4D28500301E0200C4
+:100EE000F0B585B00A9C0D4600940B9C1F460194FA
+:100EF0000C9C064602940D9C039428F02FDBAB79E2
+:100F000043B13946304644F063DD014610B1304606
+:100F100044F056DC05B0F0BD10B520F00BDE10BD7E
+:100F20002DE9FF4107461D469E6B146945F0C8DB5D
+:100F30008046002834D1337A022B31D1A3797BB398
+:100F4000B5F8683063B3A26D40F2371302EA0303C9
+:100F500033B394F884301BBBD4F888303A6853B963
+:100F6000D2F88C30D3F8E4210132C3F8E4213C23D9
+:100F7000C4F8883009E0D2F88C30D3F8E42101328B
+:100F8000C3F8E421012384F89430002394F9482025
+:100F9000384600930293296F1133019644F068DFBD
+:100FA000404604B0BDE8F0812DE9F74F80460E467B
+:100FB00093461F46002B5FD001295DD14FF4C073CB
+:100FC0000193FAF397F04FF440718246F5F380F6FF
+:100FD000044610B94FF0FF3555E000214FF4407240
+:100FE000F1F32EF040463146224601ABF0F3BEF657
+:100FF00010F11E0F3AD1019B4FF0FF325D004A23E2
+:1010000023700B23637015332371042363716FF016
+:101010002F03A371923323726FF0560363724FF064
+:1010200002096319A270E27084F8079003F8022C99
+:1010300003F8012C07F10C039D4202DC6FF00E0552
+:101040000DE059463A4604F10A00F0F395F795FB96
+:10105000F9F340463146224611F074FE05465046EB
+:1010600021464FF44072F5F343F60CE0504621461A
+:101070004FF44072F5F33CF6404631465A463B4643
+:10108000EFF3A0F705462846BDE8FE8F70B504468D
+:101090001E46FEF39FF3054640B1636893F8AB30FC
+:1010A00023B1E06F3146F1F76DFDA860284670BDB1
+:1010B0002DE9F0411F4603680C461B68164693F85D
+:1010C000953005460969A28A1BB1E38A13F0800FA7
+:1010D00009D0152A07DD08480E310622F0F330F753
+:1010E00008B9013805E02846214632463B46FCF364
+:1010F000A5F4BDE8F081C046BAD4010010B59E4603
+:10110000D0F8683103B19B68054C23607346FCF34B
+:10111000F3F1B0F1FF3F01D10023236010BDC046C1
+:10112000E82B02002DE9F04F87B0DDF854808946A6
+:1011300015469A46129FDDF84CB00446B8F1000FF0
+:1011400006D0D8F8081019B10120F1F7A5FE044621
+:1011500014B96FF0160632E0226805F0010300931F
+:10116000106849463A465B4612F0AED8064630BB98
+:10117000112D02D0132D09D00FE03846F1F3ECF316
+:10118000E8B904F5B8703946062203E004F5B670F4
+:1011900039460422F0F3F0F611E0109B204600934C
+:1011A000119B49460193149B2A4604935346029788
+:1011B000CDF80CB0CDF81480FCF3C2F006463046F2
+:1011C00007B0BDE8F08FC04670B50546D0F8B40052
+:1011D00058B103784BB1F1F767FB044630B9D5F845
+:1011E000B4000121F1F31AF500E001242846F3F3DD
+:1011F000DBF724B9D5F8B4002146F1F30FF570BD43
+:1012000010B5FFF735FD10BD10B5FAF7B1F810BDF8
+:10121000B0F8543810B50BB119F03ED910BDC04626
+:1012200010B5044638B102682AB121B992F80B37DB
+:101230000BB182F80B17204617F090DF10BDC046A7
+:1012400010B521B11AB1536E0BB13DF037DE10BDB0
+:1012500010B50C4651B1002381F8653581F866352B
+:1012600081F86735C1F868353DF0A2DE10BDC04693
+:10127000036A10B50C46002B2CD0036809691B6863
+:10128000B4F814E093F895302BB1E38A13F0800F93
+:1012900001D11E2200E00C2202F10B039E4519D35E
+:1012A0008B188A5C591C5B7803EB02239BB2B3F565
+:1012B000006F0FD14B784A1C1B09042B0AD1537ABB
+:1012C000012B07D1436A01334362C3680133C36012
+:1012D000002002E021463FF03BDD10BD036810B561
+:1012E0001A68536B2BB192F8443013B130F0AEDF73
+:1012F00000E0002010BDC04610B50C462DF0C0D94E
+:1013000018B994F8F53284F8F43210BD70B50122A2
+:1013100005460C46D1F84C152EF01ADD284621461C
+:101320002DF0EAD870BDC0460C2A2DE9F0410446E4
+:101330000F46154651D80122AA4041F2485302EA0D
+:101340000303002B49D0D0F8B4364BB1D3F8D832D0
+:1013500033B15B68012B40D0032B3ED0022B3CD035
+:10136000204615F043DD002837D1D4F868315B6999
+:10137000012B32D0D4F81808FEF3F6F0064628B157
+:10138000D4F86801092143F013D91AE0082D01D0DF
+:101390000C2D04D1D4F868319B7923BB11E0D4F82B
+:1013A0006801837913B3D4F82835022B04D094F85C
+:1013B000F43713F0010F16D0092143F0F9D8304665
+:1013C00015E0082D12D1204639460222002325F0CF
+:1013D0003BD958B14FF0FF3009E0204639462A4644
+:1013E00029F0E6DC03E06FF0180000E00020BDE823
+:1013F000F081C0462DE9F04F85B005469B468846F2
+:1014000091460F9F9DF840A0F8F7B2FFD5F8B06362
+:1014100004460AF087DDD5F8C03398420CD3032385
+:10142000009300230193029303932046172109F1AF
+:101430000A02013312F03CDB96F8463013F0030F3A
+:1014400019D0D8F8582040F2371302EA030393B1B9
+:1014500094F8693713F0010F0DD07B6813F4803FC7
+:1014600009D03B6C012B06D1002220463946134699
+:10147000009211F0BBDB094C7F2323600E9B2846B2
+:10148000009341465B464A460197CDF808A0F8F71D
+:1014900085FF0023236005B0BDE8F08F0C2C02000F
+:1014A00010B50446F5F346F0B0F5C05F05DD204603
+:1014B00043F006DE204643F003DE10BD2DE9F04187
+:1014C000074619F0DFDF0026BB19D3F84C42B4B150
+:1014D000D4F88C509DB9A3798BB1A36D13F0020F92
+:1014E0000DD094F8843053B1F5F38CF0D4F890100B
+:1014F00027F042DF18B1C4F8885084F884500436CD
+:10150000202EE1D1BDE8F08170B590F8A1310546FB
+:1015100063B903681B6F4BB1D0F81C48F5F372F048
+:10152000D5F82038E41A2418C5F81C48284614F0C9
+:10153000BBDB70BD10B588B00A9C00940B9C019475
+:101540000C9C02940D9C03940E9C04940F9C059497
+:10155000109C0694119C0794F3F3C2F1044B0421F0
+:10156000D3F88C300A4604469847204608B010BD90
+:10157000E0A6850070B504460D461EF04BD92946FD
+:1015800006462046F8F708FE304670BD2DE9F041CA
+:101590000546D5F8D8320E465B681746012B006821
+:1015A000D5F8DC4202D14FF0000805E0042914BF51
+:1015B0004FF000084FF001080368DB691A6D636A99
+:1015C000934238BF62624EB9D4F8901031B140688E
+:1015D00094F89420F5F38CF3C4F8906028463146D3
+:1015E0003A4625F0F5D8B8F1000F01D00023636228
+:1015F000BDE8F0812DE9F04385B00C9F0546984683
+:10160000D7F80090D2F8D462144600970AF0F0DCC4
+:10161000296891F8463013F0030F3FD0D4F8CC205E
+:1016200012F4805F3AD196F93430002B36D14B6BEF
+:10163000002B33D012F0020F30D13B680DF10900BE
+:101640001849032208EB0304F0F396F495F8FA31F5
+:1016500033B196F96A30002B02DA95F80A0700E0F8
+:10166000002008EB0901A14201D2002100E0091B82
+:1016700002238DF80C3000238DF80D3001338DF8E6
+:101680000E300DF109038DF80F000093204607235B
+:10169000DD221AF07BDD3B6809333B6005B0BDE815
+:1016A000F083C046C1D401000FB430B5104BADF586
+:1016B000037D9E4501D1002513E002A887AB0538C4
+:1016C00040F20121869A8193F0F3F0F5002405465B
+:1016D00005E002AB053BE05CF5F332F20134AC42CD
+:1016E000F7DB28460DF5037DBDE8304004B07047B8
+:1016F000DB62820010B502490248FFF7D5FF10BD3A
+:10170000CCFB0100E3FB0100C36970B513F4006F6B
+:101710000E460546016915D00368D3F88C20936BFB
+:101720005C1C4FF47A739463B4FBF3F202FB134333
+:1017300023B90748C96B2246FFF7B6FFEB6923F4CC
+:101740000063EB61284631462CF03CDB70BDC0469F
+:101750007CDB010010B590F81632044663B1084BEB
+:101760001B684BB1D0F88011D0F884210223C068E7
+:1017700081EA0202F9F332F42046F7F36FF610BD66
+:10178000AC27020010B50446F7F3B8F7002384F83D
+:10179000173284F8183210BD10B5074C2378012B8E
+:1017A00009D0064B1B78012B05D001232370F8F3D9
+:1017B00073F70023237010BD002C0200EC2B0200F5
+:1017C00070B50546F1F7EEF80128014607DD044C37
+:1017D000012328462370F8F3EDF50023237070BD34
+:1017E000EC2B020010B5064902690B782BB1D2F838
+:1017F000D03013B100230B7001E018F051DD10BDA3
+:10180000F42B020010B58B7913B1044B01221A702E
+:101810002DF0B6DB014B00221A7010BDF42B020034
+:1018200070B5044C8568A54201D1002001E0F0F3B9
+:1018300009F770BD0800002070B505460E461AF085
+:101840002BDD0446C0B13146284640F26C521AF0F6
+:1018500035DE064620B9284621461AF091DD0AE019
+:10186000214640F26552F0F387F32846214640F2C4
+:101870006552F5F33DF23446204670BD2DE9F04146
+:101880008AB088460023159917460546129C09938D
+:101890002DF0B0DD07F001030093414606462246D5
+:1018A0002868139B11F010DD8046002840F0AA80C4
+:1018B000119B032B04D909A810990422F0F35CF3BF
+:1018C0000D2F08D8DFE807F00A0F07071722363C6C
+:1018D0004B07074E93976FF0160892E0284608F0E2
+:1018E0002DDA40B22AE02846099908F051DA00289A
+:1018F00000F0858085E0B6F95E300BB102201DE076
+:10190000B6F95C30181E18BF012017E0099B022BA6
+:1019100006D14FF00003A6F85C304FF0010306E05B
+:10192000003B18BF0123A6F85C304FF00003A6F877
+:101930005E3066E0D5F83407F8F71EFD206060E001
+:10194000099BD5F834070393F8F71EFD039B8342E8
+:1019500055DCD5F834070999F8F712FD51E0B5F8D0
+:10196000BE3846E02B6893F8A030002B3FD00DF135
+:101970001608264906224046F0F3FEF221460422CC
+:1019800008A8F0F3F9F2211D042207A8F0F3F4F2FD
+:10199000404604F108010622F0F3EEF2079F57B922
+:1019A000D5F86821937993B95369012B0FD02B682F
+:1019B00093F83F305BB904F1100301932846314698
+:1019C000089A3B46CDF8008015F084DC0DE02B68CA
+:1019D0001B7E13B96FF0030813E0284631460DF162
+:1019E000160204F1100315F061DC804609E095F859
+:1019F000C334236005E0099B85F8C33401E06FF030
+:101A00001C0840460AB0BDE8F081C0462C9E850007
+:101A10002DE9F04790B0DDF860A00C461E46514617
+:101A20000023054617460F932DF0E4DC8046D0F8DE
+:101A3000DC9277B1032E04D90FA839460422F0F3C3
+:101A40009BF237B1032E04D90FA839460422F0F3D4
+:101A500093F2352C6BD010DC162C00F07C8105DC69
+:101A60000B2C21D0152C00F065811AE01C2C00F005
+:101A700086812F2C00F0288113E0382C00F0E580BF
+:101A800006DC362C00F09880372C00F0B58008E09A
+:101A90009F2C00F07A81A52C00F03F81392C00F0BA
+:101AA000F5806FF01604A1E12B6893F8A030002BAD
+:101AB0003DD00DF12606A24906223046F0F35CF235
+:101AC000394604220DA8F0F357F2391D04220CA860
+:101AD000F0F352F2304607F108010622F0F34CF21F
+:101AE0000C9C54B9D5F8682193798BB95369012BB3
+:101AF0000ED02B6893F83F3053B907F110030193D0
+:101B0000284641460D9A2346009615F0E3DB0CE08B
+:101B10002B681B7E002B00F05D81284641460DF1AD
+:101B2000260207F1100315F0C1DB04465EE12B68C5
+:101B30001B7E002B00F04E81052E40F24E810D2EB3
+:101B40000BD9284607F10801A6F1080201F062DA74
+:101B50000446002840F04A8109E005AC3946204699
+:101B60000622F0F309F2002307930E26274698F881
+:101B70000640B4B9D9F8901031B1686899F894204A
+:101B8000F5F3B6F0C9F8904089F89460686831467A
+:101B9000F5F39EF0C9F8900018B139463246F0F3DB
+:101BA000EBF14046394629F091DAD9F890300446F5
+:101BB000002B40F01A8119E1002300932846394692
+:101BC00032460EABF1F760FB0446002840F00E8170
+:101BD0000E99032900F004812A6B1368994202D1FF
+:101BE000D2F8F03050E05368002B14BF38233C2368
+:101BF000EB58D3F8F03047E00023009328463946ED
+:101C000032460EABF1F740FB0446002840F0EE8070
+:101C10000F9A02F16403672B02D96FF01C04E5E010
+:101C20000E99032904D02B6B1B68994240F0DE808B
+:101C3000002A04DB2846296B29F08CDB02462B6B3B
+:101C4000C3F8FC20C3F8F020D0E00023009328461E
+:101C5000394632460EABF1F717FB0446002840F038
+:101C6000C5800E99032900F0BB802A6B1368994246
+:101C700002D1D2F8F43007E05368002B14BF3823A8
+:101C80003C23EB58D3F8F4303B60AFE000230093E3
+:101C90002846394632460EABF1F7F6FA04460028DC
+:101CA00040F0A4800F9A642A00F29A800E990329CA
+:101CB00004D02B6B1B68994240F098802B6BC3F8C3
+:101CC0000021C3F8F42091E02B680F9C93F83F307B
+:101CD00013B16FF01B0489E0D5F86801837913B163
+:101CE000042142F065DC95F87232221E18BF0122F1
+:101CF00085F8502785F85925002B76D12AB105F5AE
+:101D0000AA61D5F85C010E3104E005F5AA61D5F8A9
+:101D10005C010A3134F026DA07E70123002202933E
+:101D200028460849134600970196CDF80CA011F0FB
+:101D300037DBFAE6B8F95E3033B1022009E0C0467D
+:101D40002C9E85001C738600B8F95C30181E18BFE5
+:101D50000120386049E00F9B022B06D14FF00003B1
+:101D6000A8F85C304FF0010306E0003B18BF0123E8
+:101D7000A8F85C304FF00003A8F85E3035E02B681F
+:101D800001211869F9F392F22FE0331F0622B3FB09
+:101D9000F2F33B60D5F8000500230BA90F9343F045
+:101DA00099D910E00B7E13F0020F0CD00F9B5C1C36
+:101DB0000F943B68A34210D3B81E062204FB020016
+:101DC0001A31F0F3D9F00BA843F08CD90146002862
+:101DD000E8D108E06FF0030408E06FF00D0405E0BF
+:101DE0006FF0020402E00F9B3B600024204610B01D
+:101DF000BDE8F0872DE9F04F056889B082460C46B2
+:101E00001E4628460023179907939346DDF848801D
+:101E10002DF0F0DA139B032B04D907A841460422C6
+:101E2000F0F3AAF0BBF10D0F56D12846414698F8C1
+:101E3000066098F8087098F809402DF06FDA10B134
+:101E40006FF00107F1E098F80630003E18BF012658
+:101E5000022B14BF4FF400594FF4811947EA0427AD
+:101E60006EB13846F1F3F8F1002840F0E080D5F883
+:101E70005C01394634F092DA002800F0D880284618
+:101E80002DF070DBB0F1FF3F014600F0D280284614
+:101E90004A46434600962CF08BDE0446002800F0AC
+:101EA000C88028462146FBF789FA20B128462146FA
+:101EB0002DF0C2DABDE0002E00F0B9803946284688
+:101EC000A2683BF0CDD90746002800F0AE80284636
+:101ED00021462DF0B1DA12E0139B50460193149B7A
+:101EE00021460293159B5A460393169BCDF800801A
+:101EF0000493179B059333463AF03ADF074617F1F0
+:101F0000170F40F09280DAF80060002330461799EE
+:101F100006932DF06FDA139B0446032B04D906A811
+:101F200041460422F0F328F0BBF11B0F7DD130466F
+:101F3000414698F8065098F8089098F809702DF0E6
+:101F4000EDD9034620B1A04202D06FF0010373E047
+:101F5000B5F1000A18BF4FF0010ABAF1000F0BD01B
+:101F6000032D0BD09A68304649EA07213BF078D917
+:101F70000346002860D111E0032D0FD130462146E1
+:101F80002CF070DF012394F94810304600934FF491
+:101F90008802013BFBF7E6F903464DE0D4F8CC306C
+:101FA000304643F40003C4F8CC3021462CF05ADF0D
+:101FB000A37913B1322384F8F43294F8F41231295E
+:101FC0000FD833681B7E1BB130461D4A17F02EDA3E
+:101FD000D6F84C0194F8F4123DF074D9322384F809
+:101FE000F4324146062204F1C200EFF3C5F784F84B
+:101FF00006A030462146FBF7E1F9054640B1D4F88A
+:10200000CC3023F40003C4F8CC304FF0FF3313E09E
+:1020100030460321A26811F087D8D4F8CC3023F4DD
+:102020000003C4F8CC302B4606E03B4604E0002712
+:10203000FBE74FF0FF37F8E7184609B0BDE8F08F2F
+:10204000329E85002DE9F04704468946FCF3F4F7FB
+:10205000F4F3D8F294F854318046012B1ED825466B
+:10206000002717E06E69B379022B11D1B4F86C30F8
+:1020700013F4807F0CD0204649464246F0F74CFED0
+:1020800030B90423B37194F8CD30013B84F8CD30DE
+:1020900001370435B4F910309F42E3DBBDE8F08727
+:1020A00030B54FF0000E044691B08C461546704690
+:1020B00009E023185A690EF1010ED1794DF800108C
+:1020C000536B0430D371B4F910309E45F1DB2046D8
+:1020D00061462A46FCF3A4F10020014606E063189D
+:1020E0005A695DF801300130D3710431B4F9103010
+:1020F0009842F4DB11B030BD2DE9F0410C290446C3
+:102100000D46164690F853710DD100210122FCF3C3
+:1021100087F1204600210122FCF33EF1002384F8E0
+:10212000CE3084F8CD30A36E2046B3F1FF3F08BF18
+:1021300084F8563129463246FCF392F2B4F86C30FA
+:1021400003F0C003C02B16D1D4F85C319BB194F8D6
+:102150005331BB420FD9E368A1689868FDF37EF262
+:10216000E368A1689868D4F85C210123FDF32EF29E
+:102170004FF0FF33A366BDE8F081C046836E10B513
+:10218000B3F1FF3F01D0FBF39FF510BD2DE9F04106
+:1021900004460D46866EFCF3C5F6074690B9042248
+:1021A00004F5AE7005F11401EFF3E6F6D4F85C31F6
+:1021B0004FF47A7203FB02F3B6F1FF3FC4F85C31CF
+:1021C00008BFA6663846BDE8F081C0460E2937B57F
+:1021D00005468E4614460BD00F2910D1114601A892
+:1021E0000422EFF3C9F628460199F0F731FE08E022
+:1021F000B0F85831002003F00103136001E0FCF354
+:10220000E9F13EBD70B514460546FCF39FF1236825
+:102210000BB10223AB6570BD70B50D460446FBF3F0
+:10222000FDF7014610BBA36DEDB1FBB9D4F8542105
+:102230000F4B02EA03037BB194F85431022B04D113
+:1022400094F8573113F0010F05E0012B07D194F8F2
+:10225000573113F0020F02D16FF0010300E00023A9
+:1022600084F8563102E00BB184F85601084670BD7F
+:10227000FF0000FF10B50446FBF362F7002384F86B
+:102280005731A4F85831C4F85C3184F8563110BD88
+:102290002DE9F041A2B0882205460C4690F8558100
+:1022A00090F8567190F854616846EFF365F6284649
+:1022B0002146FBF3AFF60246002836D1009B85F895
+:1022C00056719E4285F854612CD01BB995F8573150
+:1022D00073B112E0022B04D195F8573113F0010FBE
+:1022E00005E0012B07D195F8573113F0020F02D109
+:1022F0006FF0010314E096B90DE0012E02D113F046
+:10230000010F05E0022E05D195F8573113F0020FA9
+:1023100005D107E036B995F85531434502D200237F
+:1023200085F85631009B85F85431104622B0BDE83F
+:10233000F081C0462DE9F04104460E46154690F85E
+:102340005671FBF363F48646A0B92A4601460DE0B8
+:102350007318DB88083113F0100F06D194F8573149
+:1023600043F0010384F8573102E0083A072AEFD816
+:1023700084F856717046BDE8F081C0462DE9F04101
+:1023800004460D46164690F85671FBF3DBF386467D
+:1023900098B9294632460CE04B6A13F0100F06D16B
+:1023A00094F8573143F0020384F8573103E0383A88
+:1023B0003831372AF0D884F856717046BDE8F0817C
+:1023C000002070472DE9F0410B4C07460E460025D2
+:1023D0000BE038462146EFF3A1F620B923799E425F
+:1023E00001D1A06806E001350C34044B1B689D4206
+:1023F000EFD30020BDE8F08120FC0100F02B0200AB
+:1024000070B50D4600240AE00849284601EBC401D6
+:102410000422EFF395F508B9013005E00134044BCF
+:102420001B689C42F0D3002070BDC04620FC010018
+:10243000F82B020010B5034C216033F0F9DA0023C9
+:10244000236010BD082C02002DE9F0412A4B0646FE
+:10245000D3F800800F4600250BE0284B304603EBF5
+:10246000C5042146EFF35AF610B9E3789F4241D0F4
+:1024700001354545F1D1224B0025D3F800800FE00E
+:10248000204B304603EBC5042146EFF347F630B945
+:10249000E3789F4203D11C4B01221A7010E00135F2
+:1024A0004545EDD117BB194B3D46D3F800800AE0F6
+:1024B000174B304603EBC5042146EFF32FF608B95E
+:1024C000201D17E001354545F2D1124B124DD3F8CE
+:1024D0000080002408E029463046EFF31FF604355B
+:1024E00008B90E4806E001344445F4D13046394677
+:1024F00032F074DEBDE8F081042C0200E3FB010041
+:102500009421020018FC010098210200F82B02001F
+:1025100020FC0100FC2B020018FC0100CA0286000E
+:1025200010B5084B02461B783BB1074B1B6898421D
+:1025300003D2064B53F8200010B9104632F026DFC4
+:1025400010BDC046982102007C200200781F0200C6
+:1025500010B5084B02461B783BB1074B1B689842ED
+:1025600003D2064B53F8200010B9104633F006DBB7
+:1025700010BDC04698210200802002008420020085
+:102580002DE9F04F234B8FB01C68234B82468946C0
+:10259000D3F800B00CB9204638E0036BA168186985
+:1025A00007AA00F0FFFD00261C4DB0462BE0A368F3
+:1025B0006F1F012B03D12878FFF702FF03E015F806
+:1025C000010CFFF7C5FF694633F00EDC002107ABB5
+:1025D0001DF80120CB5C1A420FD05046394632F02C
+:1025E000E5DD40B1B9F1000F05D009EB86003946B1
+:1025F0000422EFF3DDF5013602E001311C29E6D1BA
+:1026000008F101080835D845D1D130460FB0BDE8F2
+:10261000F08FC046082C0200F82B020025FC0100B8
+:10262000012902D14FF6FF7010E0D0F8BC304FF016
+:102630000002082BD0F8B03008BF41F40071A3F8B5
+:10264000D813B3F8DA33A0F8202698B27047C04602
+:10265000D0F8B030A3F8D813A3F8DA237047C046F7
+:10266000D0F8B0300021A3F8D8134FF0010230B5F4
+:10267000B3F8DA434FF00205A3F8D823B3F8DA230E
+:10268000A3F8D853B3F8DA3392B29BB2A0F820166D
+:10269000C4F3031040EA047042EA032240EA023025
+:1026A00030BDC04670B505460E461446FFF7B8FF6C
+:1026B000314600EA04022846FFF7CAFF70BDC04653
+:1026C00070B505460E461446FFF7AAFF40EA04021D
+:1026D0003146284692B2FFF7BBFF70BD2DE9F041AD
+:1026E0001546064688461C46FFF79AFF2C4020EA0E
+:1026F000050222433046414692B2FFF7A9FFBDE8EA
+:10270000F081C0462DE9F0411C46069B9046198099
+:10271000079D0E46FFF784FF089B28801E802B88AC
+:1027200004EA080423EA0803099A23431380BDE856
+:10273000F081C046D0F8B0304FF00002A3F8FC138F
+:10274000A0F82026B3F8FE0380B27047D0F8B0306E
+:1027500041EA0242C3F8FC237047C046D0F8B030CB
+:10276000A3F8FC13B3F8FE130A40A3F8FE234FF0BE
+:102770000003A0F82036704710B5D0F8B040A4F898
+:10278000FC13B4F8FE339BB21A434FF00003A4F8D5
+:10279000FE23A0F8203610BD10B5D0F8B04013408D
+:1027A000A4F8FC13B4F8FE1389B221EA02010B432A
+:1027B000A4F8FE334FF00003A0F8203610BDC04649
+:1027C0002DE9F04106460C462CE0254635F8023B43
+:1027D000571E990403F44043890CB3F5804F11D080
+:1027E00001DC3BB11CE0B3F5004F10D0B3F5404F16
+:1027F00012D015E03046628835F8023FFFF7CCFF73
+:10280000013F0DE030466288FFF7A0FF08E0304648
+:102810006288FFF7A3FF03E030466288FFF7ACFF52
+:10282000AC1C7A1E002AD0DCBDE8F0812DE9F04115
+:102830001C46069B90461980079D0E46FFF77AFFBF
+:10284000089B28801E802B8804EA080423EA0803DA
+:10285000099A23431380BDE8F081C04600234FF05E
+:10286000FF3280F8E33041F21A03C25403F59B7340
+:10287000C254704710B531B140F23B414FF6F87287
+:10288000FFF76CFF03E002490422FFF799FF10BD38
+:102890002E03020060B1B0F8DE00B0F5006F05D085
+:1028A000B0F5406F04D1A0F5386002E0402000E0B0
+:1028B00000207047012380F8E130704780F824162B
+:1028C0007047C04690F924067047C0467047C0461E
+:1028D00010B1C06900B141777047C04610B1C069FE
+:1028E00000B101777047C04610B590F8E330044658
+:1028F000002B49D14FF064014FF44872A0F88428AE
+:10290000A0F87C18A0F87E18C0F880381A46A318E2
+:1029100002324FF06401102AA3F88618F7D14FF065
+:102920000003A4F82E38A4F8AC37A4F8AE374FF063
+:102930000A034FF00A02A4F83E38A4F83C38A4F881
+:102940004038636A4FF01401A4F83228A4F84428F0
+:10295000A4F83428A4F84628A4F82A28A4F828289B
+:10296000A4F82C28A4F89027A4F892274FF050023E
+:10297000A4F83018A4F89427A4F842180BB1204604
+:102980009847012384F8E33010BDC04610B5FFF727
+:1029900067FE10BD2DE9F84F0C46D1F810A00D6868
+:1029A0009B468968E368064643EA812311469AB24A
+:1029B000BDF82880FFF7CAFE0027B9461EE0BAF12D
+:1029C000200F0BD159F8052030465946120CFFF75D
+:1029D000BDFE39F80520304641460AE0BAF1100F35
+:1029E00004D135F817203046414602E07A5D304682
+:1029F0004146FFF7ABFE013709F1040963689F42C6
+:102A0000DDD3BDE8F88FC0462DE9F74F0D460193A1
+:102A1000D1F810B00E68EB688968074643EA812355
+:102A200011469AB2BDF83090FFF790FE4FF00008C3
+:102A3000C24626E0BBF1200F0FD149463846FFF7CA
+:102A400079FE019904464AF806003846FFF772FEFF
+:102A500044EA00444AF806400FE0BBF1100F06D1EB
+:102A600038464946FFF766FE26F8180005E0384666
+:102A70004946FFF75FFE08F8060008F101080AF171
+:102A8000040A6B689845D5D3BDE8FE8F7FB50293E5
+:102A9000089B03910593099B0192049301A90A9B4A
+:102AA000984707B000BDC0467FB50293089B0391CD
+:102AB0000593099B0192049301A90A9B984707B0CB
+:102AC00000BDC0460B46D0F8F81012B141EA03032E
+:102AD00001E021EA0303C0F8F830704700B5D0F8F0
+:102AE000F8308E4621B143F01003C0F8F83012E000
+:102AF00023F0100312F0010FC0F8F8300BD041F2B0
+:102B0000D413C258C369196A986E814294BF714642
+:102B1000091AC2F8901000BD00207047A0F8DE101E
+:102B20007047C046A0F8DA107047C046B0F8DA0027
+:102B30007047C04640F6C313984201D800200BE00E
+:102B400041F2C843984201D8012005E041F24463B4
+:102B500098428CBF032002207047C0467047C04691
+:102B600000B5002286460748910030F822307345B0
+:102B700002D10B18588803E001320E2AF3D100204D
+:102B800000BDC046A8FC010010B5C8B2FFF7E8FFC1
+:102B9000FFF7D0FF10BDC04610B541F22823C45C3A
+:102BA0004FF0000C134B3CF803E0BEF10E0F8CBF4E
+:102BB0004FF480524FF400524EF4306342EA030067
+:102BC0002CB1BEF1940F02D9BEF1A50F0AD902298A
+:102BD00003D1BEF10E0F0BD904E0012902D1BEF1E1
+:102BE0000E0F05D80CF1040CBCF1380FDAD1FF2020
+:102BF00010BDC046A8FC010010B590F8B2321446D2
+:102C00000B6090F82B3653B190F8F83690F92A26DD
+:102C100023B1534243F080430B6000E00A6014B1DB
+:102C200090F8F7362370002010BDC04610B58646D8
+:102C30001C4641F21B031EF8033002989B000E292C
+:102C4000137008D80028ACBF0EEB00030EF1000390
+:102C500093F81E3127E07F23237030EA200028BF3D
+:102C600004200022114BD35A994202D00432382A50
+:102C7000F8D1A1F122031E2B04D80EEB000393F828
+:102C800083312370A1F16403282B04D80EEB0003D9
+:102C900093F8E8312370A1F19503102B04D80EEBC3
+:102CA000000393F84D32237010BDC046A8FC01000C
+:102CB0002DE9FF4700250746884691469A46FF269C
+:102CC0002C461EE0009341460DF10E020DF10F035C
+:102CD0003846FFF7ABFF41F2E623FA5C9DF80F1090
+:102CE00053B2994201DC002302E0C2EB0103DBB2E4
+:102CF0008DF80F30AB4228BF1D46B34238BF1E4689
+:102D00000134142CE3B2DDD189F800508AF8006058
+:102D1000BDE8FF877047C04690F829067047C04657
+:102D2000B0F8DA3003F47043B3F5805F09D1032AB9
+:102D300018DDA2F16503032B14D9A2F1C9030F2BEF
+:102D400010D9132A0EDCA2F13403642B0AD9A2F1A4
+:102D5000A9031F2B06D9A2F1D103072B94BF002092
+:102D6000012000E00020704770B590F8DA5004466A
+:102D70002846FFF7F5FEB4F8DA3003F47043B3F5F4
+:102D8000005F01D0002004E02B1903F59A530F33A4
+:102D9000187940B270BDC04600B54FF0000E00EB90
+:102DA0000E021EF801300EF1010EBEF1040F82F882
+:102DB0002C36F4D14FF0000E01EB0E0200EB0E03A7
+:102DC00012790EF1010EBEF1080F83F83026F3D10F
+:102DD00000BDC04680F8E0107047C046C3699961E5
+:102DE0007047C04680F8D5104176704780F8D910FA
+:102DF0007047C0467047C04690F81A067047C046F4
+:102E000041F22403C35C33B141F21C2380F81A164B
+:102E100080F81B16C154704790F8D83013B10023C6
+:102E200080F8D83000207047C369012093F88130C2
+:102E30000B70704722B10023C0F8E83FA0F8EC3FC8
+:102E400000F58153012019607047C0460022C16916
+:102E500010460B1893F982300130D2180828F8D1A7
+:102E600092FBF0F040B270477047C0466FF016001A
+:102E70007047C04670B541F21E23C35C04468B42C6
+:102E80000D46164603D0D0F8883003B1984704F5B4
+:102E900091531E8041F21E23E55470BD0021C36989
+:102EA000CB180131082983F88220F8D10021C369A9
+:102EB0006FF05B02CB180131082983F88220F6D12C
+:102EC000C2690023C2F88C30D36E032B08D1D0F82E
+:102ED000F83F13F0010F03D0136A0833C0F8F03F36
+:102EE00000F58A531233002204E0002241F2D2138B
+:102EF000C25470474FF6A47101321980198402330D
+:102F0000102AF7D1F1E7C04649F675334B6000232C
+:102F10000B60F0B50C469842ACBF01214FF0FF3179
+:102F200003F5340301FB03F103F53403081890FBA8
+:102F3000F3F202FB1303581A03D4C31301335B10DB
+:102F400004E04342DB1301335B105B425A2BD4BFD6
+:102F50000023012313B1A0F5340014E0002803DBA3
+:102F6000C31301335B1004E04342DB1301335B10F6
+:102F70005B4213F15A0FACBF002301230BB90126AA
+:102F800003E000F534004FF0FF364FF0000EF4463A
+:102F90007546604561682268144F0BDD41FA0EF3F7
+:102FA0009B18236042FA0EF3C3EB01036360EB59F5
+:102FB0009C440BE041FA0EF3C3EB0203236042FA98
+:102FC0000EF35B186360EB59C3EB0C0C0EF1010EB2
+:102FD0000435BEF1120FDCD1636806FB03F36360B6
+:102FE000236806FB03F32360F0BDC046F4FC010038
+:102FF00080EAE071A1EBE0710022D0B251FA00F357
+:103000000132002BF9DC70470146002000B58646EE
+:103010004FF0804343FA0EF31A188A424FEA5000E9
+:1030200002D8891A43EA00000EF1020EBEF1200F09
+:10303000EED1884238BF013000BDC046C36983F875
+:103040009010C36983F89120C36983F89210C36913
+:1030500083F893207047C046C36983F89210704785
+:1030600041F21633C256013BC0568242B4BF012022
+:10307000022070470048704750FD01000020704753
+:103080007047C046084670470020704741F2D81389
+:10309000C05803E0C3888B4202D000680028F9D1F1
+:1030A0007047C04610B5B0F8DA10FFF7EFFF10BD5B
+:1030B000C3699B6913F0005F09D0D0F8B0304FF0BE
+:1030C0000302A3F8B4264FF0FF02A3F8B826704716
+:1030D000D0F8F83013F0060F0CBF00200120704725
+:1030E0002DE9F0410F46B0F8DA10044615461E46A9
+:1030F000FFF74AFD40B9B4F9FC302B60B4F9FE305B
+:103100003360B4F900313B60BDE8F081D0F8A8002D
+:103110007047C04670B541F2D813C15805460AE061
+:103120000B6841F2D8142B51EB694FF43D7298684B
+:10313000F3F3DEF529590029F2D141F2D81305F550
+:1031400090523032E950043BEA504FF6CE70F033E3
+:10315000E852C2F8901070BD10B590F8E93094B004
+:1031600043F0010380F8E93004460021302201A831
+:10317000EEF366F7002110220DA8EEF361F70021AF
+:10318000042213A8EEF35CF711A800210822EEF345
+:1031900057F794F8E930002023F0010384F8E93070
+:1031A00014B010BD70B506460D46104614460021F9
+:1031B0001C22EEF345F700200F4BC25A41F22823A0
+:1031C000F35C1BB1942A01D9A52A10D9022D02D192
+:1031D0000E2A04D90BE0012D09D10E2A07D9D108F6
+:1031E00002F0070301229A40635C134363540430E6
+:1031F0003828E1D170BDC046A8FC010010B50C46CE
+:10320000002103F025F82070012010BD10B5002129
+:1032100003F01EF840B210BD41F2D41310B5C458EB
+:10322000F433C15819B1C36918693DF095DA002328
+:103230006370A37010BDC04610B59E462BB941F215
+:103240000723C35C704613600FE041B1012906D02B
+:10325000022904D0032902D06FF01C0005E041F2DE
+:103260000723C154FFF7D8FF002010BD41F2C82347
+:10327000C15810B509B9084607E0C36918693DF09F
+:103280006BDAD0F1010038BF002010BD10B541F25B
+:10329000F423C35C0BB104F097FD10BD10B503F02F
+:1032A000B5FB10BDC36970B5DC681B6D054613F036
+:1032B000010F0E4608D02046F7F3FAF520B1EB696E
+:1032C0009B6913F0005F12D1EA69136D13F0010FCF
+:1032D0003BD0536D13F0800F37D1D068F7F386F7EA
+:1032E000002832D0EB699B6913F0005F2DD0D5F830
+:1032F000F83013F0020F28D1EEB106F47043B3F5A5
+:10330000005F18D163691149232BB4BF00230C233C
+:10331000F2B2B8BF0F2120469A400123F7F3D0F54F
+:1033200063690B49222B2046D8BF7021CCBF4FF4D4
+:103330000072102206E0636904492046222BD8BFA0
+:103340000F2100220123F7F3BBF570BD00F05555A6
+:10335000000E5555D0F8B030C269D3F82031136D46
+:1033600070B513F0010F04460D4608D0D068F7F38E
+:103370009FF520B1E3699B6913F0005F11D1E26909
+:10338000136D13F0010F18D0536D13F0800F14D18B
+:10339000D068F7F32BF780B1E3699B6913F0005F06
+:1033A0000BD025B920462946FFF77CFF0AE02046CE
+:1033B000B4F8DA10FFF776FF00E01DB104492046AB
+:1033C000062202E0034920460E22FFF7F9F970BDFC
+:1033D000360302008CFC010010B514299E46D0F87B
+:1033E000A82004D015290CD06FF016000CE092F93B
+:1033F0001A3002A941F8043F70460422EEF3BCF5EE
+:1034000001E0039B9376002010BDC04610B590F8F4
+:103410001A360C462BB10231224601F091FDA378F9
+:10342000637010BD10B5012103F072FA10BDC046E3
+:103430002DE9F0418A79CB790D4642EA03216B7977
+:103440002A79074642EA0328C3695B690A2B07D930
+:10345000EB7C1B0213F4807002D10123EB7735E083
+:103460002A7A6B7A384601F0FF0442EA0326FFF716
+:103470004DFE7F2C1B4AC8BFA4F58074B30AD356F7
+:1034800090F85F00E21818F4006F14BF41F23B336C
+:1034900041F23A33FB56D11843B2C918AA7DEB7DED
+:1034A0007F2942EA0322C2F3C702C8BFA1F5807197
+:1034B0000E2AD4BF4FF400534FF4805342F43062CD
+:1034C000384649B243EA0202FFF7DCFD6A79C1B22D
+:1034D0002977384649B2C2F3801201F00DFBBDE8EE
+:1034E000F081C0461A22020010B590F8E9309646E5
+:1034F00053B313F0010F19D0D0F8F0308B420FD135
+:10350000C369D3F88C209B1883F882E0C269D2F893
+:103510008C30072B01D1002300E00133C2F88C303E
+:1035200090F8E93023F0010380F8E93090F8E930B1
+:1035300013F0020F08D023F0020380F8E930C369CA
+:10354000724618693DF01CD910BDC04690F8E930AC
+:1035500010B5ABB9012902D0022902D003E0C0F8AE
+:10356000F02080F8E910C3691B6AC0F8EC3041F222
+:103570000503C35C23B111466FF05E02FFF7B4FF91
+:1035800010BDC04637B5044602F01CFFE3691A6A55
+:1035900001321A6294F8E830002B77D041F262339E
+:1035A000E35A1BB1A4F86E38A4F8703841F26633C0
+:1035B000E35A1BB1A4F86838A4F8643841F26433C4
+:1035C000E35A1BB1A4F86238A4F86638E369196AB3
+:1035D0001A6EB1FBF2F302FB131323B92046B4F8C1
+:1035E000DA10FFF75FFED4F8F83013F00E0F05D1B4
+:1035F0002046012194F8DA20FFF7A8FF94F8E9307B
+:103600004BB1E369D4F8EC201B6A9B1A052B02D955
+:10361000002384F8E93041F22805615929B1E369B2
+:103620001A6A1B6E521A9A420BD3D4F8F83013F070
+:10363000020F06D12046FFF76FFA10B1E3691B6A4B
+:103640006351D4F8F83013F00F0F1FD1D4F88C3039
+:103650000BB120469847E36918693DF005D868B179
+:10366000E36901A918690DF107023DF007D820466A
+:103670009DF80710BDF80420FFF7FCFBD4F8F830E4
+:1036800013F00F0F02D1204603F0C0F900203EBD19
+:1036900010B50446FFF74AFA0221C2B22046FFF7EE
+:1036A00055FF10BDC36973B5012983F88110044625
+:1036B0000D46C36906D9186901220323009300212E
+:1036C000134605E0186900210323009301220B46ED
+:1036D0003CF0FADFE269537F002B30D0D4F8B030F1
+:1036E000D3F8203183F0010313F0010602D11069F1
+:1036F0003DF050D8012D0FD90222134620464FF439
+:103700008261FFF749F820464FF482610122022DC1
+:1037100014BF002301230BE020464FF482610222F4
+:103720000023FFF739F820464FF4826101222B462F
+:10373000FFF732F81EB9E36918693DF017D87CBD70
+:10374000C36970B547F67F750446582118692A4643
+:103750003CF0EEDFE3695A2118692A463CF0E8DFC5
+:10376000E369702118692A463CF0E2DFE3697221BF
+:1037700018692A463CF0DCDF70BDC046F7B5C26967
+:103780000546537F002B62D090F81A36002B45D0A7
+:10379000106928213F223CF0CBDFEB692421186916
+:1037A00010223CF0C5DFEB6995F82926186926211F
+:1037B00012013CF0BDDFEB6932211869B5F8FC2637
+:1037C0003CF0B6DF2E460027EB691869204BF95C08
+:1037D0003CF086DFEB6996F914250446A11D1869B3
+:1037E00092B23CF0A5DF96F914250223E96992FB19
+:1037F000F3F25242086992B204F10E0101373CF033
+:1038000097DF0136082FDFD1EA690323009310699F
+:103810008022012113463CF057DF18E001460420C6
+:1038200091F914350822073393FBF2F3DB000130E2
+:1038300081F8143501310C28F2D195F91425EB6982
+:10384000073218694E21C2F3CF023CF071DFFEBD92
+:103850002503020010B5012102F0B6FC40B210BDF4
+:1038600010B500210446621801317F23652982F8D2
+:103870009136F8D12046FFF7EDFF2046FFF7C6FC52
+:1038800010BDC0462DE9F04FB0F8DA30A5B003F412
+:103890007041B1F5805F14BF022201220592D0F879
+:1038A000A83004460693C3695A6C40F239539A42D1
+:1038B00004D052339A4201D0002304E0B1F5805F76
+:1038C00014BF00230123DBB2002165220DF1290082
+:1038D0000893EEF3B5F3B4F8DAA00AF44073B3F545
+:1038E000407F02D15FFA8AF810E0B3F5007F5FFAFB
+:1038F0008AF104D1DD2904D801F1020806E0022989
+:1039000002D84FF0000801E0A1F102082046059915
+:10391000FFF7A6FF2046FFF727FA4FF0000BC0B2D3
+:10392000FF255E4607900395CDF810B070E0204665
+:1039300051462A46FFF7F4F9002867D005EB040941
+:1039400099F8B26224AA571907F8676C94F8AC305A
+:1039500043B1059A204641462B46FFF78FFB3018AE
+:1039600007F8670C41460DF18E020DF18F032046DA
+:103970000095FFF75BF999F82C269DF88F309A4255
+:1039800034BF1146194641F2E623E25C53B2994234
+:1039900001DC002002E0C2EB0103D8B224AB5919CC
+:1039A00011F8673C984234BF02461A4601F8672C6A
+:1039B00094F8E030642B06D803FB02F3642293FBF7
+:1039C000F2F301F8673C11F8673C9DF88E20079EE2
+:1039D0009A4238BF1A462B1993F891368DF88F000A
+:1039E000934294BFC6EB0306C6EB0206049AF3B2F9
+:1039F0005B4588BF2A46049201F8673C039D5B45FE
+:103A000028BF9B46AB4238BF1D460395099E013631
+:103A10000996099A142AD5B289D104F5A260002129
+:103A20005132EEF30DF3039B049D84F8293684F89C
+:103A30002A360023184684F818B684F8F83684F835
+:103A4000195616E024AE731813F8672C94F81A363A
+:103A5000091981F875250BB1089B1BB194F818362C
+:103A60009B1A03E094F82936C3EB020381F8103562
+:103A700001301428C1B2E5D121460020069D91F9FC
+:103A80001035B5F9E623D218431CD8B281F81025B9
+:103A900001310428F2D1E36A0BB12046984725B0E2
+:103AA000BDE8F08F70B505460E462C46FFF774F959
+:103AB000294600203218137D03B91379013081F8AB
+:103AC000383601310828F5D10021721892F84430B7
+:103AD00003B91379013184F8483601340829F4D147
+:103AE000EB6918693CF056DE2846FFF7CBFEEB6920
+:103AF00018693CF03BDE70BD7F2970B5044601D9E2
+:103B0000052028E0002213190132652A83F8B21239
+:103B1000F9D10023E26984F8F736137FD3B1D4F8E2
+:103B2000F83013F0020F15D1D4F8B030D3F82031AB
+:103B300083F0010313F0010502D110693CF02ADE85
+:103B40002046FFF79FFE2DB9E36918693CF00EDEB1
+:103B5000284600E0002070BD70B5054600F52C70C9
+:103B6000042202300C46EEF307F205F52C70211DFD
+:103B700008220630EEF300F205F52E70082206301A
+:103B800004F10C01EEF3F8F105F538700822063067
+:103B900004F13401EEF3F0F105F53A700822063035
+:103BA00004F13C01EEF3E8F105F53070082206302F
+:103BB00004F11401EEF3E0F105F53270082206304D
+:103BC00004F11C01EEF3D8F105F53470082206303B
+:103BD00004F12401EEF3D0F105F536700822063029
+:103BE00004F12C01EEF3C8F105F53C700822063013
+:103BF00004F14401EEF3C0F105F53E7004F14C010F
+:103C000008220630EEF3B8F105F5407008220630C0
+:103C100004F15401EEF3B0F105F5427006300822CC
+:103C200004F15C01EEF3A8F194F8643085F81633E2
+:103C3000D5F8B030D3F8203113F0010309D11C4678
+:103C40002846FFF71FFE54B1EB6918693CF08EDD82
+:103C500005E0EB69012418693CF09CDDF0E770BDDC
+:103C60002DE9F0410F460546FFF710FA07F47043BF
+:103C7000B3F5805FEB69FAB208BF42F48072044684
+:103C8000A02118693CF054DDAE6A2CB104F517721E
+:103C900041F2D413EA5005E005F59053303341F278
+:103CA000D412AB5016B128463946B0472CB341F276
+:103CB000D413EA58537873B1EB6941F2C8242959F7
+:103CC00018693CF049DDEB6900221869295913464F
+:103CD0003CF0C0DC11E041F20723EB5C6BB1032B3D
+:103CE0000BD0E969D2F890200B6A9B1A8A6E934236
+:103CF00003D328460221FFF7D5F928463946FFF7B6
+:103D0000D1FABDE8F081C046E02910B50B46044663
+:103D100002DD6FF0120012E043F430630E29D4BFCD
+:103D20004FF400514FF48051194389B2FFF798FFC7
+:103D30000123204684F8D83008F092FF002010BDFF
+:103D400070B50C460546FFF767F844B9284605F0FC
+:103D5000D9FE28464FF4404106F0AEF910E0214666
+:103D600028460022FFF7D0FF044648B928462146DE
+:103D70007022234605F04AFB28465E2106F0EEFD40
+:103D8000204670BD2DE9F0410D460446FFF744F88A
+:103D900045B92046294602F0B3FC2F4641F2D42310
+:103DA000E55213E0204629460122FFF7ADFF074602
+:103DB00060B941F2D426A35B23B920460A21FEF75D
+:103DC000B9FCA0532046294602F09AFC3846BDE8CB
+:103DD000F081C04670B50E460546D0F8B040FFF7FA
+:103DE0001BF83EBB41F2D6240A2128462A5BFEF787
+:103DF000ADFC284640F24B413246FEF7A7FC284670
+:103E0000314602F0DDFBEB692E531B6D13F0020F00
+:103E100056D041F2D823D5F8B020EB5A4FF47A703F
+:103E2000A2F89C3441F2DC23EB5AA2F89E34F2F360
+:103E300093F445E0EB691B6D13F0020F1FD0D5F82A
+:103E4000B01041F2D822B1F89C344FF47A709BB292
+:103E5000AB50B1F89E3404329BB2AB50B4F89C34F2
+:103E600023F400731B041B0CA4F89C34B4F89E3498
+:103E70009BB243F40073A4F89E34F2F36DF4314620
+:103E800028460122FFF740FF0646C8B941F2D62472
+:103E90002B5B5BB90A212846FEF74CFC40F24B41F4
+:103EA00028534FF6FF722846FEF750FC28460121A2
+:103EB00002F086FB28460A214FF49472FEF75CFC60
+:103EC000304670BD2DE9F0418AB005AED0F8B07033
+:103ED00005468846142238493046EEF34DF0142248
+:103EE00036496846EEF348F0EB6900216C461869E4
+:103EF000142288450CBF234633463CF023DC4FF0A8
+:103F00000003A7F86835B8F1000F4FF48073A7F8E5
+:103F1000C0370CBF40234123A7F80C3541F60223DC
+:103F2000A7F814354FF00003A7F80835A7F80A35AD
+:103F3000A7F84C354FF01403A7F86A3540F626036E
+:103F4000A7F868354FF00003A7F800354FF0D0030D
+:103F5000A7F80235B7F802350CBFFA251E25002454
+:103F600002E00A20F2F3F8F3AC420ADAB7F80E35B1
+:103F7000013413F0800FF4D103E00A20F2F3ECF3E4
+:103F800000E0002401340B2C09D0B7F80E3513F4EF
+:103F9000806FF2D003E00A20F2F3DEF300E00024A9
+:103FA00001340B2C04D0B7F8903613F4807FF2D193
+:103FB0000AB0BDE8F081C046E0FC01003CFD010014
+:103FC00070B590F8E2200446002A6CD1012380F8F5
+:103FD000E230D0F8B030A0F8DA10D3F8203100F594
+:103FE00081531A60D0F8F82012F0020F06D190F831
+:103FF000803E1BB942F02003C0F8F830256A002D3E
+:1040000051D001212046FEF735FCB4F8DA30B4F87F
+:10401000DE2003F44061914203D0E36918693CF06B
+:1040200035DB012141F2CD23E1542046FFF792F91F
+:104030002046A847002384F8E1302046FFF79EFB86
+:10404000E369204693F88110FFF72CFBE26992F8B0
+:104050008030012BB4F8DA300BD103F47043B3F5A0
+:10406000005F01D1936F0BE0D36F012B88BF00235A
+:1040700006E003F47043B3F5005F0CBF136F536F9A
+:10408000D366E3690022D96E2046FEF7D3FE0023F3
+:1040900084F8E230E369922118693CF02BDB41F2AD
+:1040A00022234000E05270BDC36910B518693CF08E
+:1040B0002BDB10BDC36910B518693CF02FDB10BDB8
+:1040C000F7B5089F04460D461E463BB1032A05D9A5
+:1040D000684619460422EDF34FF701E000230093F0
+:1040E000A82D009900F0FB8015DC5C2D00F0AE805F
+:1040F00008DC3C2D00F0A0804A2D00F093801B2DA1
+:104100002AD020E05E2D30D0C0F2A8805F2D3DD0B7
+:10411000872D1BD017E0C32D75D006DCAA2D49D002
+:104120007BDBC22D00F0DB800DE0D42D00F0AB80F6
+:1041300003DCD32D00F09B8005E0A5F59A73033BCB
+:10414000012B40F2D2806FF01605CFE02046FEF73B
+:104150007DFE40B23060C8E0E3691D7F002D40F075
+:10416000B8802046FEF77AFBC0E001233B70E3698C
+:104170005B7F002B00F0B0802046FFF79BFF2046BE
+:10418000BDF80010FEF7D6FA30600FE001233B7057
+:10419000E3695B7F002B00F09F802046FFF78AFFDA
+:1041A000009A204691B2120CFEF7D0FA2046FFF793
+:1041B0007BFF9AE0E269537F002B00F08D8010694D
+:1041C0003CF0E8DA00252046FFF774FF3560D4F8AC
+:1041D000BC30082B13D10DF1060220460DF107016A
+:1041E0008DF807508DF8065000F0AAFE9DF90720C3
+:1041F0009DF9063092B29BB243EA02233360204617
+:10420000FFF752FF60E0E3691B7F002B6AD0338821
+:10421000022B64D96FF0010568E0E3691B7F002B76
+:1042200060D05CE0E3691B7F002B52D1236B002B35
+:104230005BD02046984718E0E3691B7F002B48D1EC
+:1042400020467268B368FFF7C5FD0EE0E3691B7F87
+:10425000002B3ED12046FFF773FD06E0E3691B7F8C
+:10426000002B36D12046FFF78DFD05463EE0E36981
+:10427000DA6E3260D4F8F83F13F0010F35D042F017
+:104280008003336031E0042902D96FF01C052DE072
+:10429000E269D36E8B4228D0137FD1662BB31069AD
+:1042A0003CF078DA009B23B1204600210122FEF782
+:1042B000C1FDE36901222046D96EFEF7BBFD00284F
+:1042C00014BF00256FF00205E36918693CF04EDA6F
+:1042D0000CE06FF0040509E06FF00A0506E06FF0EE
+:1042E0000C0503E06FF0030500E000252846FEBD45
+:1042F0002DE9F04389B09946109B0026032B074611
+:104300000C46DDF84480139D079604D907A849465A
+:104310000422EDF331F6079940F286230A1E18BFF6
+:1043200001229C4200F013812CD80C3B9C427CD093
+:104330000FD8532C08D8522C80F04081502C00F01C
+:104340003D81512C6AD02DE140F26A239C4250D02D
+:1043500028E1B4F5207F00F0E48009D840F27B2307
+:104360009C4200F0A48003339C4200F0D58019E108
+:10437000B4F5217F00F0E48040F285239C4200F0F8
+:10438000DB800FE140F2D6239C4200F0178114D865
+:10439000413B9C423ED006D8043B9C4234D0023381
+:1043A0009C4234D0FEE0B4F5277F00F0D78040F285
+:1043B0009D239C4200F0D680F4E040F2DD239C4235
+:1043C00000F0EB8008D8033B9C4200F0D180B4F5AC
+:1043D000377F00F0D680E5E0B4F53D7F00F0F38054
+:1043E000C0F0E080A4F53E73063B012B00F2DA80BA
+:1043F000E9E03846FFF75EFE38464146FFF706F82B
+:104400003846FFF751FE50E041F2623304E041F2DA
+:10441000643301E041F26633F95246E00123009330
+:1044200038464346FEF722FDCFE0FA69137F13B901
+:104430006FF00300C9E0D7F8B030D3F8203183F033
+:10444000010313F0010902D110693CF0A3D93846E9
+:10445000FEF72EFE3846FFF72DFE41F2E61341F23D
+:10446000E910F95C385C0133FA5C013317F803E0BA
+:10447000009041F2EA103D5C01303C5C1630385C43
+:10448000734603903846019502940496FEF764FE45
+:10449000C8F800003846FFF707FEB9F1000F40F0FA
+:1044A0008D80FB6918693CF061D930468DE0C1F31D
+:1044B000036CBCF1010F00F28380C1F3015EBEF119
+:1044C000010F7DD8C1F38155032D79D0C1F3034489
+:1044D000012C75D8C1F30722A2F10A03DBB2052B28
+:1044E0006ED8C8B2012801D9032869D10E2A28BF85
+:1044F0000E2241F2E613FA540133F8540133FC540E
+:10450000013307F803E00133FD54013307F803C01A
+:104510000A0F1633FA54C8E708A9012341F8043DED
+:1045200007E0B7F8DA103846FEF72EFB08A941F885
+:10453000040D40462A462DE041F21B03F954B4E72E
+:1045400041F21B03FB5C08A941F8043D17E0D7F8D2
+:10455000F830C3F30013C8F80030A6E738464246E7
+:10456000334602E0384642460123FEF765FE9CE7EB
+:104570000121384601F03AFF08A941F8046D404690
+:1045800007E007AC38463146224601F093FF40462B
+:1045900021460422EDF3F0F487E73846324601F075
+:1045A00089FF82E701910292384621464A464346F6
+:1045B0000095FEF711FF10F1170F04D0002004E062
+:1045C0006FF01C0001E06FF0160009B0BDE8F08349
+:1045D0002DE9F04391460A6801230B7342F008036A
+:1045E0000B60B0F9FA3685B0B3F1FF3F04BF42F07B
+:1045F00009030B6090F81A3605460C461BB10B6890
+:1046000043F002030B602F4626464FF0000897F850
+:10461000B2322846B37749460DF10E030DF10F0271
+:10462000CDF80080FEF702FB9DF80E3008F101087E
+:1046300086F8B03197F87535013786F8793201364A
+:10464000B8F1140FE3D195F81A3633B3EB691B7F39
+:104650001BB32846FFF72EFD95F818362846A3759C
+:1046600095F81836E37595F81936A37695F8193646
+:10467000E37600F05BFC236810B143F0030301E034
+:1046800023F003032846236004F10D0104F1150211
+:1046900000F056FC2846FFF707FD05B0BDE8F083A3
+:1046A00010B5054B1B78012B03D1013B18461B703D
+:1046B00001E014F00BFE10BD3C28020010B5054BC4
+:1046C0001B78012B03D1013B18461B7001E014F04D
+:1046D00023FE10BD3C2802002DE9F04105460E46A0
+:1046E00017461C46FFF7EAFF30B1234628463146FD
+:1046F0003A4614F04BFE04462046BDE8F081C04621
+:1047000010B50023FFF7E8FF10BDC04610B51446F2
+:10471000FFF7D4FF20B100210A46EEF319F004465A
+:10472000204610BD10B50022FFF7F0FF10BDC046B7
+:104730001FB5079B0C890093089B11460193099BA9
+:10474000224602930A9B03930069069B28F02EDD04
+:1047500004B010BD00B5B0FBF1FE01FB1E0001F07E
+:10476000010C0CEB51010BE0884228BFC1EB0003A8
+:104770004FEA4E0E26BF0CEB43000EF1010E400037
+:10478000531EDAB2FF2AEFD1884228BF0EF1010E84
+:10479000704600BD00FB01F19202800103FB002086
+:1047A00001F5004101EB4000490090FBF1F070473A
+:1047B000D0F8A8304FF001025A8670472DE9F04733
+:1047C00098469DF820308A4691469DF82470B3B1F2
+:1047D00000246FF000462546204651464A4643468F
+:1047E000FFF7D8FFB04204DA6B1CDDB2BD421AD02D
+:1047F00006460134802CEFD16FF0004013E07F2497
+:104800004FF0FF361D46204651464A464346FFF7C5
+:10481000C1FFB04204DD6B1CDDB2BD4203D00646D1
+:10482000013CF0D22046BDE8F087C04610B5B0F894
+:10483000DA300446DAB203F47043B3F5005FD0F81F
+:10484000A81003D1531893F8E72486E0702A5ED0AD
+:104850001CD8382A49D00CD82C2A3DD004D8242A78
+:1048600034D0282A35D02FE0302A38D0342A39D015
+:104870002AE0642A42D004D83C2A39D0402A3AD0CF
+:1048800022E0682A3DD06C2A3ED01DE0882A50D014
+:104890000CD87C2A44D004D8742A3BD0782A3CD047
+:1048A00012E0802A3FD0842A40D00DE0992A49D0D6
+:1048B00004D88C2A40D0952A41D005E0A12A47D0BF
+:1048C000A52A48D09D2A40D0002246E091F8F6243F
+:1048D00043E091F8F72440E091F8F8243DE091F8A6
+:1048E000F9243AE091F8FA2437E091F8FB2434E017
+:1048F00091F8FC2431E091F8FD242EE091F8FE249B
+:104900002BE091F8FF2428E091F8002525E091F8AC
+:10491000012522E091F802251FE091F803251CE013
+:1049200091F8042519E091F8052516E091F806257F
+:1049300013E091F8072510E091F808250DE091F8B3
+:1049400009250AE091F80A2507E091F80B2504E013
+:1049500091F80C2501E091F80D25D1F8E40494F8C4
+:104960002A36C01A801840B210BDC04608467047AB
+:1049700049B24B1C5B104910C3F10803083141EAEE
+:10498000031188B27047C046B0F8DA3003F47043C0
+:10499000B3F5005FD0F8A82005D192F83C05FF28B8
+:1049A00001D0C0B200E000207047C04670B5054697
+:1049B000D0F8A840FFF7E8FF10B994F8460540B1D9
+:1049C000B5F8DA3003F47043B3F5005F14BF00208C
+:1049D000012070BD10B50C468EB0D0F8A8109646D8
+:1049E000002000220DF10603C25401303228F8D114
+:1049F000BEF1FF3F91F8E93306D114B1B1F93EE5BC
+:104A000003E0B1F940E514E09CB1A02B09D00023EC
+:104A10008DF806308DF807308DF808308DF80930A4
+:104A200004E000238DF806308DF808308DF80A3048
+:104A300033E0A02B17D001238DF81A308DF81B30EE
+:104A40006FF0010300228DF81E308DF81F30013306
+:104A50008DF81C208DF81D208DF820208DF8213038
+:104A60008DF8242019E002238DF81A306FF003032B
+:104A70008DF81E30023300228DF81F308DF8203063
+:104A80008DF8213006338DF81B208DF81C208DF811
+:104A90001D208DF824208DF832300EAA02EB0E0373
+:104AA00013F9320C0EB010BD30B5C46900F5805357
+:104AB000226A1B68D0F8A8509A4202D3C3EB0201C5
+:104AC00001E0DB43991895F8BC2290F8DA309A425D
+:104AD00001D0012004E0A36E994234BF00200120E0
+:104AE00030BDC0467047C046D0F8A83093F80604E1
+:104AF000002808BF1020704700B5D0F8A8008E46E7
+:104B0000D0F8D4240EF0FF0343EA0223110EC0F8BC
+:104B1000D434D0F8D8347F29C8BFA1F5807173444C
+:104B20005B1AC0F8D8349B10C0F8DC3400BDC04616
+:104B3000844610221B4810B5964600244EF34603C7
+:104B40005FFA83FE10EA0C0F4FFA8EF104D0884012
+:104B50000EEB0203DAB203E0C840CEEB0203DAB296
+:104B60000134042CEAD110EA0C0FD3B201D1013B7D
+:104B7000DAB251B2032301FB03F30329DAB20EDDEB
+:104B8000CB1E2CFA03F00D2801D9D31C06E00A280D
+:104B900001D9931C02E0082801D9531CDAB250B2A3
+:104BA00010BDC0460000FFFFD0F8A820002382F807
+:104BB000903382F8913382F8923382F8933382F8FB
+:104BC000943370477047C04670B540F22341D0F827
+:104BD000A8500446FDF7AEFDC0B2A5F864034FF43B
+:104BE000AA612046FDF7A6FD8005800DA5F86803A3
+:104BF00040F234412046FDF79DFDC0B27F28C8BF7A
+:104C0000A0F58073A5F8660340F23241C8BFA5F84D
+:104C100066332046FDF78EFDC0B27F28C4BFA0F5E5
+:104C2000807398B285F8BC0370BDC0462DE9F0478B
+:104C3000884640F2B76104469146FDF77BFD40F29D
+:104C4000B66105462046FDF775FD40F2B5610646A2
+:104C50002046FDF76FFD40F2B46107462046FDF7A0
+:104C600069FD4FF0000C6246644650FA04F313F0FD
+:104C7000010101D0012103E00CF101035FFA83FC83
+:104C8000531CDAB2102A12D001340029EDD00EE004
+:104C9000A2F1100357FA03F313F0010F01D0012121
+:104CA00003E00CF101035FFA83FC531CDAB21F2A04
+:104CB00011D80029ECD00EE0A2F1200356FA03F33C
+:104CC00013F0010F01D0012103E00CF101035FFAA1
+:104CD00083FC531CDAB22F2A11D80029ECD00EE045
+:104CE000A2F1300355FA03F313F0010F01D00121B3
+:104CF00003E00CF101035FFA83FC531CDAB23F2A94
+:104D000001D80029ECD04FF03F0E00220F2455FAB5
+:104D100004F313F0010101D0012103E00EF1FF3390
+:104D20005FFA83FE531CDAB2102A12D0013C00292C
+:104D3000EDD00EE0C2F11F0356FA03F313F0010F9A
+:104D400001D0012103E00EF1FF335FFA83FE531C13
+:104D5000DAB21F2A11D80029ECD00EE0C2F12F03DD
+:104D600057FA03F313F0010F01D0012103E00EF114
+:104D7000FF335FFA83FE531CDAB22F2A11D80029C1
+:104D8000ECD00EE0C2F13F0350FA03F313F0010F31
+:104D900001D0012103E00EF1FF335FFA83FE531CC3
+:104DA000DAB23F2A01D80029ECD088F800E089F86F
+:104DB00000C0BDE8F087C04670B50D4640F23941ED
+:104DC0000646FDF7B7FCC0F3C210E88040F2B541DB
+:104DD0003046FDF7AFFC40F2FB4104463046FDF79C
+:104DE000A9FC04F0FF03C0B2C4F307242B806C803D
+:104DF000A88070BD2DE9F047B0F8DA30074603F41B
+:104E00007043B3F5805FD0F8A82009D1B2F89205BD
+:104E100003B2B3F1FF3F0CBF4FF4C87080B24CE057
+:104E2000B2F8904523B2B3F1FF3F01D0A0B244E005
+:104E300040F2A541FDF77EFC40F2A541814638468F
+:104E4000FDF778FC40F20D4106463846FDF772FC4E
+:104E500040F20D4104463846FDF76CFC40F2A24199
+:104E600005463846FDF766FC40F2A24180463846CA
+:104E7000FDF760FCC6F30236012313FA06F6C0F311
+:104E80000220C5F3022513FA05F58340E4B25FFA68
+:104E900089F94C44B6B2A419ADB29BB25FFA88F856
+:104EA0006419434404EB430464005034A4B2B4F5E1
+:104EB000C86F2CBF20464FF4C860BDE8F087C046DD
+:104EC00010B540F2FB41FDF735FCC0F3062010BDE4
+:104ED00070B540F2A4410446D0F8A850FDF72AFC72
+:104EE000C0F38130032814D141F22403E35C83B181
+:104EF000204640F27341FDF71DFC95F96635C0056B
+:104F0000C00D013303FB00F3022293FBF2F3D8B28E
+:104F100001E095F8C10240B270BDC04610B540F244
+:104F2000A441FDF707FC00F4404010BD10B5FFF7A9
+:104F3000F5FFB0F5404F14BF0020012010BDC04662
+:104F400070B5002313700B7041F22403C35C044658
+:104F50000D4616461BB340F2AB41FDF7EBFB10F4D8
+:104F6000004F03D0204640F2AB410AE0204640F219
+:104F70003C61FDF7DFFB10F4004F07D0204640F204
+:104F80003C61FDF7D7FBC0F3470028702046FFF7D0
+:104F9000CDFF08B194F810052B781B18337070BD45
+:104FA0002DE9F04140F2FF340E4605469046334667
+:104FB000224640F24561FDF7EFFB28462246434674
+:104FC00040F24661FDF7E8FB28462246334640F2B0
+:104FD0004761FDF7E1FB2846224643464FF4C9618D
+:104FE000FDF7DAFB28462246334640F24961FDF7D9
+:104FF000D3FB284640F24A6122464346FDF7CCFBEC
+:10500000BDE8F08170B5002914BF4FF48073002310
+:1050100004460D1E18BF01254FF480724FF49661AF
+:10502000FDF7BAFB0122204640F24C412B46FDF72A
+:10503000B3FB2B0320464FF496614FF4805203F4E8
+:105040007043FDF7A9FB6B0320464FF496614FF4C4
+:10505000005203F46043FDF79FFB6B0120229BB2DB
+:1050600020464FF49661FDF797FB6B0203F47E43F5
+:10507000204640F2AE414FF40072FDF78DFBB4F8CC
+:10508000DA3003F47043B3F5005F11D1AB02204670
+:105090004FF496614FF4806203F47C43FDF77CFB90
+:1050A000EB009BB2204640F2E5410822FDF774FB7D
+:1050B00070BDC04670B50C02A4B20546234640F24E
+:1050C000FB414FF4FE42FDF767FB284640F2FD41ED
+:1050D0004FF4FE422346FDF75FFB70BD70B500291B
+:1050E00014BF802300230C1E18BF012480224FF41C
+:1050F00096610546FDF750FBA303A40128464FF433
+:1051000096614FF4804203F44043A4B2FDF744FBA0
+:10511000284640F23B4140222346FDF73DFB70BD4F
+:1051200070B540F239440D4621460646FDF702FBB4
+:1051300040F67F4300EA030343EAC51330462146A5
+:1051400040F6FF729BB2FDF727FB70BD2DE970435F
+:105150000C460646FFF7B4FE628823884FF6FF79B7
+:1051600043EA022305464A46304640F2B5419BB227
+:10517000FDF712FB2D02A388ADB247F6FF7830464B
+:10518000424645EA030340F2FB41FDF705FB628816
+:105190002388304643EA022340F2FC414A469BB250
+:1051A000FDF7FAFAA3883046424645EA030340F287
+:1051B000FD41FDF7F1FA3046E188FFF7B1FF3046D7
+:1051C0000121FFF78BFFBDE87083C04610B502498F
+:1051D0000C22FDF7F5FA10BD380D02002DE9F0475D
+:1051E0009846BDF82CA0BDF824308946BDF82010A3
+:1051F0000AF00304164603F00F03BDF8282044EA22
+:10520000032301F00F0102F0030243EA013343EAF2
+:10521000821343EA021343EA840340F2B6414FF695
+:10522000FF720746BDF83050FDF7B6FA0F2208EAC4
+:105230000203384640F2B741FDF7AEFA4FEACA23FF
+:105240009CB22346384640F2B1414FF460522D03E0
+:10525000FDF7A2FAADB2062238462049FDF7B0FAB2
+:105260007602384640F2AE414FF470422B46FDF7CD
+:1052700093FA384640F2B1414FF4007206F47E438F
+:10528000FDF78AFAD9F1010338BF0023012238461D
+:1052900040F24D41FDF780FAB7F8DA3003F470437D
+:1052A000B3F5005F10D1384640F2B1414FF4C0521F
+:1052B0002346FDF771FA4FEACA039BB2384640F223
+:1052C000E6411822FDF768FA384640F2AE414FF445
+:1052D00070422B46FDF760FABDE8F087A209020094
+:1052E00010B5044686B021B90D490E22FDF768FAC3
+:1052F00014E00C490922FDF763FA0021032206237A
+:10530000009302920423039220460A4604910193DB
+:10531000FFF764FF20460121FFF774FE06B010BDC1
+:10532000420702005E07020010B5D0F8A830D3F89B
+:10533000741529B1C3694FF420729868F1F3D8F459
+:1053400010BDC0462DE9F041D0F8A8300646D3F88C
+:105350007C55D3F8787500240DE0142302FB03F389
+:10536000EA1811695268F06902FB01F28068E95895
+:10537000D208F1F3BDF4E2B20134BA42EDD3BDE894
+:10538000F081C04670B5D0F8A8500446D5F87C35F9
+:105390006BB10121FFF7D6FFE369D5F878451422F8
+:1053A0009868D5F87C1504FB02F2F1F3A1F470BD06
+:1053B00041F2F023C15810B5044629B1C36942F641
+:1053C00008529868F1F394F42046FFF7ADFF2046A9
+:1053D000FFF7D8FFE369D4F8A81098684FF4B962D2
+:1053E000F1F386F410BDC04610B54FF48052044668
+:1053F000002340F2C961FDF7CFF9D4F8A820B2F834
+:10540000C234EBB192F8E933A02B04D1204640F22C
+:105410008961232203E0204640F289613022FDF7B2
+:1054200095F9D4F8A830B3F8C234022B0ED14FF45A
+:105430008052204640F2C9611346FDF7ADF905E000
+:10544000204640F289612322FDF780F9042220469C
+:105450002749FDF7B5F90022204640F27961FDF7B2
+:1054600075F9082220462349FDF7AAF9D4F8A83097
+:105470002046B3F8C2244FF4D961FDF767F906223C
+:1054800020461D49FDF79CF9D4F8A8304FF48072EE
+:10549000B3F8C23420461A41013A4FF4D06192B2B7
+:1054A000FDF754F9D4F8A8304FF4A072B3F8C23421
+:1054B00020461A41013A92B240F28161FDF746F965
+:1054C000D4F8A830B3F8C224012A04D0022A14BFA9
+:1054D0003422082200E01822204640F27F61FDF7C6
+:1054E00035F9204605490E22FDF76AF910BDC04680
+:1054F000440B02004C0B02002E0C02003A0C02007E
+:105500002DE9F04740F23C4631460446FDF712F9DA
+:1055100040F23B48824641462046FDF70BF94AF0EF
+:10552000010281463146204692B2FDF70FF949F05B
+:105530000102204641464FF6FE7592B2FDF706F98C
+:10554000204631460AEA0502FDF700F920464146A9
+:1055500009EA0502FDF7FAF8204631465246FDF702
+:10556000F5F8204641464A46FDF7F0F8BDE8F087D9
+:10557000802270B513460C4640F2D1610546FDF716
+:105580000BF90CB1012C05D128464FF4DA610F223A
+:10559000FDF7DCF82846FFF7B3FF70BD2DE9704337
+:1055A0000E46B0F8DA10054601F47041B1F5005F1F
+:1055B00014BFA521892199469046FDF731F8B5F829
+:1055C000DA10044601F47041B1F5005F14BFA52163
+:1055D00089212846FDF724F804F00F04C0F30310D6
+:1055E000241A3470B5F8DA10284601F47041B1F588
+:1055F000005F14BFA6218A21FDF712F8B5F8DA1072
+:10560000044601F47041B1F5005F14BFA6218A2160
+:105610002846FDF705F804F00F04C0F30310241A20
+:1056200088F80040B5F8DA10284601F47041B1F569
+:10563000005F14BFA7218B21FCF7F2FFB5F8DA1049
+:10564000044601F47041B1F5005F14BFA7218B211E
+:105650002846FCF7E5FF04F00F04C0F30310241AFA
+:1056600089F80040B5F8DA10284601F47041B1F528
+:10567000005F14BFA8218C21FCF7D2FFB5F8DA1027
+:10568000044601F470412846B1F5005F14BFA8211B
+:105690008C21FCF7C5FF04F00F04C0F30310069B38
+:1056A000241A1C70BDE87083B0F8DA1010B501F44C
+:1056B00070410446B1F5005F14BFA52189218822FD
+:1056C000FCF7C6FFB4F8DA10204601F47041B1F5DA
+:1056D000005F14BFA6218A218822FCF7B9FFB4F825
+:1056E000DA10204601F47041B1F5005F14BFA72124
+:1056F0008B218822FCF7ACFFB4F8DA10204601F4C5
+:105700007041B1F5005F14BFA8218C218822FCF7FD
+:105710009FFF10BD10B5D0F8A830044693F8E933C8
+:10572000A02B03D110490422FDF74AF8204600229D
+:105730004FF48E71FCF78CFF204618220B49FDF7C1
+:105740003FF841F2EE23E35A2046FF2240F2346153
+:10575000002B08BF0C23FDF71FF82046044909223F
+:10576000FDF72EF810BDC046580D0200600D020076
+:10577000900D020070B504220D4607490646FDF75C
+:105780001FF80024054B625BE15A30460234FCF7F7
+:105790005FFF302CF6D170BDD60B0200D2040200A0
+:1057A0002DE97043054698461646B0F8DA40FFF7F3
+:1057B000DFF804F47044B4F5005F14BFA524892415
+:1057C0000246214628469DF81890FCF741FF3146D5
+:1057D0002846FFF7CDF8B5F8DA40024604F47044E5
+:1057E000B4F5005F14BFA6248A2428462146FCF79E
+:1057F0002FFF41462846FFF7BBF8B5F8DA400246CE
+:1058000004F47044B4F5005F14BFA7248B24284629
+:105810002146FCF71DFF49462846FFF7A9F8B5F8D1
+:10582000DA40024604F47044B4F5005F14BFA824C3
+:105830008C2428462146FCF70BFFBDE87083C04648
+:1058400070B505460E460024074BA25BE15A284678
+:105850000234FCF7FDFE182CF6D1284603492246F7
+:10586000FCF7AEFF70BDC046800B0200880C020042
+:1058700070B506220E4644490446FCF7A1FF0025F8
+:10588000424B2046E95AFCF7CBFEA8530235182DAF
+:10589000F6D1072101222046FCF7DAFE1022FF2173
+:1058A00013462046FCF71AFF04221346204640F216
+:1058B0001F11FCF713FF0C2220463549FCF780FF2F
+:1058C00001223A2113462046FCF708FF04223A2120
+:1058D00013462046FCF702FF0822134620464FF4E9
+:1058E0008D71FCF7FBFE0822052113462046FCF7CC
+:1058F000F5FE0122134620464FF48D71FCF7EEFEB3
+:10590000122220462349FCF75BFF20228221134606
+:105910002046FCF7E3FEB4F8DA3003F47043B3F545
+:10592000005F02D000252E4608E0D4F8A8309A7A0D
+:10593000D97A42F400721D7B42EA01160122204608
+:1059400013464FF49B61FCF727FF2046B3004FF44A
+:105950009B6140F6FC72FCF71FFF022220461346B3
+:105960004FF49B61FCF718FF2B0320464FF49B611B
+:105970004FF4E04203F47043FCF70EFF2046064963
+:105980000622FCF71DFF70BD16080200800B020006
+:10599000AE090200C6090200EA0902002DE9F74F2C
+:1059A000D0F8A830814693F80B809C7A1A7E1F7B32
+:1059B0004FEA081844F4007493F817B09E7D44EA47
+:1059C0000804009293F814A0DD7C44EA07345B7D60
+:1059D00047F2FF38A4B2092223490193FCF7F0FEF5
+:1059E00048464246234640F2DB41FCF7D5FE484696
+:1059F0004246234640F2DC41FCF7CEFE4846424692
+:105A0000234640F20A41FCF7C7FE4FEA0A1A019BFF
+:105A100045F4007545EA0A0545EA0335484642461D
+:105A2000ABB240F20B41FCF7B7FE4FEA0B1B009AFA
+:105A300046F4007646EA0B0646EA023648464246F7
+:105A4000B3B240F20C41FCF7A7FE20224846822167
+:105A50001346FCF743FE012248467C211346FCF71F
+:105A60003DFEBDE8FE8FC046C40B0200012970B5A3
+:105A700005460C4616D106222949FCF7A1FE284608
+:105A80003A2122462346FCF729FE082228461346DF
+:105A90004FF48D71FCF722FE28467F210022FCF78F
+:105AA000D7FD33E079B91F490622FCF789FE284665
+:105AB0003A2101222346FCF711FE082228464FF422
+:105AC0008D71134620E0022920D1B0F8DA3003F4BA
+:105AD0007043B3F5005F02D17D21032201E07D21F7
+:105AE0002246FCF7B5FD284628210F220123FCF7AA
+:105AF000F5FD8022134628464FF48971FCF7EEFD30
+:105B00002846052107220223FCF7E8FD284640F23B
+:105B100037614FF440420023FCF73EFE70BDC046A3
+:105B2000AE060200560C02002DE9F047C369D0F81A
+:105B3000A8501B6D0C4613F4805F40F2234114BF44
+:105B40004FF006094FF00909064695F844A3FCF703
+:105B5000F1FD40F2344107463046FCF7EBFD2046AC
+:105B6000FEF7E6FF95F84433C1B2B5F8642395F823
+:105B700048030BB9012092E007F0FF07C0EB0103D7
+:105B8000C2EB07029B1A5FFA83F84FFA88F4002CE5
+:105B90001DDAF36930461B6D03F48053002B0CBFF4
+:105BA0000B21042114BF0322082263429A42A8BF9A
+:105BB0001A46B5F8683301FB02324FF4AA6192B27B
+:105BC000FCF7C4FD14F1030F06DAFB1C05E0032CFF
+:105BD00002DDFB1E9BB200E0BBB2B5F8640319B254
+:105BE00002B2D31C994201DDC31C03E09142ACBF59
+:105BF0000B4613469CB2BAF1000F13D023B2BB423E
+:105C000010D02346304640F22341FF22FCF7C4FD6A
+:105C1000304624490422FCF7D3FD1420F0F39CF510
+:105C2000002700E00127B5F866434FFA88F220B25A
+:105C3000C9EB000352429A42B8BFC9EB040391B2C8
+:105C4000B8BF99B20AB200F109039A42C4BF04F185
+:105C5000090399B2B6F8DA3003F47043B3F5005F84
+:105C60000CBF95F94B3395F94C335B189BB2BAF1E5
+:105C7000000F05D0304640F23441FF22FCF78CFD86
+:105C8000304640F22341FCF755FD95F8BC33C0B2D5
+:105C900085F8BD0385F8BE0385F8BF333846BDE8F7
+:105CA000F087C0465C0B020070B5D0F8A8500446DF
+:105CB000FF22B5F8663340F23441FCF76DFDB5F8CC
+:105CC00064332046FF2240F22341FCF765FD204665
+:105CD000B5F868234FF4AA61FCF738FD2046044963
+:105CE0000422FCF76DFD1420F0F336F570BDC046BC
+:105CF0008A050200082270B5134605465721FCF7B5
+:105D0000EDFC56212846FCF78BFC00F0F8045621E8
+:105D100022462846FCF79CFC0120F0F31DF5562195
+:105D200044F003022846FCF793FC0120F0F314F53D
+:105D3000562144F007022846FCF78AFC4FF496707F
+:105D4000F0F30AF52846572108220023FCF7C6FC89
+:105D500070BDC0462DE9F04140F24A4631468046CA
+:105D6000FCF7E8FC40F04404A4B24FF6BF7540468F
+:105D70003146224604EA0505FCF7E8FC31462A468E
+:105D80004046FCF7E3FC25F004050420F0F3E4F4BE
+:105D9000404631462A46FCF7D9FCBDE8F081C046B2
+:105DA0002DE9F04706460C461546384906221F469F
+:105DB000DDF82090BDF82480FCF702FD304640F26B
+:105DC00082414FF6FF722346FCF7E6FC304640F274
+:105DD0008141FF222B46FCF7DFFC3FB9304640F201
+:105DE00081414FF480723B46FCF7D6FC304628498F
+:105DF0000322FCF7E5FC0A2308FB03F5002407E077
+:105E0000AC4201DD002439E06420F0F3A5F4013454
+:105E1000304640F28141FCF78DFC10F4007FEFD159
+:105E200040F283413046FCF785FC40F28441044651
+:105E30003046FCF77FFC40EA0440C9F8000040F21D
+:105E400085413046FCF776FC40F2864104463046F8
+:105E5000FCF770FC40EA0440C9F8040040F28741B6
+:105E60003046FCF767FC4FF4916104463046FCF77E
+:105E700061FC40EA0440C9F80800012430460549A5
+:105E80000622FCF79DFC2046BDE8F087980702003B
+:105E9000F40502002A06020070B50546002407E05A
+:105EA0006420F0F359F4013441F289339C4207D065
+:105EB000284640F25141FCF73DFC10F4404FEFD131
+:105EC000284640F25141FCF735FC10F4404F14BF16
+:105ED0000020012070BDC04610B540F24C414FF685
+:105EE000FC72FCF73BFC10BDC36970B504460D465F
+:105EF00018698E2116463AF0FDDBE3694119490025
+:105F0000186932463AF014DC70BDC046C36970B5FA
+:105F100004460D4618698E213AF0ECDBE36941191D
+:105F2000490018693AF0E6DB70BDC0462DE9F04142
+:105F30000C46272180461646FFF7E8FF10F00103C4
+:105F400002D101271D4605E04FF6F07500EA050570
+:105F50004FF6F07728214046FFF7D8FF3840A84297
+:105F600001D1012009E0013C631C002B02DD14205B
+:105F7000F0F3F2F3002CEDDC002006B13460BDE854
+:105F8000F081C0462DE9F0410646D0F8A850FEF752
+:105F9000C5FFB0F5404F46D1F369E02118693AF0EA
+:105FA000A9DBEC8D8046C4EB000440F2A5413046ED
+:105FB000FCF7C0FB0123C0F30227BB40A4B29C4204
+:105FC00031DD95F8C134A5F82E80BB4208D90137E0
+:105FD000304640F2A5414FF4E0623B02FCF7DCFBA7
+:105FE0003046FEF775FF40B280B22886B6F8DA3048
+:105FF0006F8603F47043B3F5005F0CBF85F854045B
+:1060000085F85504D6F8A8202B8E92F966255B00FA
+:10601000013293FBF2F3304640F2A44140F2FF120A
+:106020009BB2FCF7B9FBBDE8F081C0462DE9F04F0B
+:10603000044685B00D46D0F8A860FFF7A3FFD4F85A
+:10604000B030D3F8203183F0010313F00103039340
+:1060500003D1E36918693AF09DDB07212046FCF77C
+:10606000DFFAFF2101902046FCF7DAFA40F21F1117
+:1060700002902046FCF7D4FA40F23B41834620468A
+:10608000FCF758FB40F23C4182462046FCF752FBAD
+:1060900040F2D74181462046FCF74CFB4FF49B6110
+:1060A00080462046FCF746FB0F224649074620461D
+:1060B000FCF786FB0122072113462046FCF70EFB66
+:1060C0001022FF2113462046FCF708FB042213464A
+:1060D00040F21F112046FCF701FB0A20F0F33CF3CD
+:1060E000202220464FF49A611346FCF755FB0A2004
+:1060F000F0F332F3012D21D140F276412046FCF736
+:1061000019FB40F27741C5052046FCF713FBC0059B
+:10611000C00DED0DFF288ABFA0F5007302469AB2AC
+:10612000FF2D88BFA5F50073A6F86E058CBF98B249
+:106130002846C0EB0203A6F86C550AE0204640F260
+:106140007541FCF7F7FAC005C00DFF2803D9A0F58B
+:1061500000739DB200E00546019B2046DAB207219C
+:10616000FCF776FA029B2046DAB2FF21FCF770FAC0
+:10617000204640F21F115FFA8BF2FCF769FA2046C5
+:1061800040F23B415246FCF7E1FA204640F23C41E6
+:106190004A46FCF7DBFA204640F2D7414246FCF77C
+:1061A000D5FA20464FF49B613A46FCF7CFFA039BA1
+:1061B0001BB9E36918693AF0D9DA28B205B0BDE82D
+:1061C000F08FC046F807020070B5D0F8A83001295A
+:1061D000D3F8DC63D3F8D853D3F8E04304D10131CA
+:1061E000FFF724FF02B20AE040F27541FCF7A2FA81
+:1061F000C005C00DFF288CBFA0F500720246631FCA
+:1062000001209840801905FB1200231F184140B25D
+:1062100070BDC04610B50129D0F8A83003D1FFF7F2
+:1062200005FF00B212E0B3F86C25B3F86E35FF2B12
+:1062300086BFA3F5007399B21946FF2A86BFA2F55F
+:1062400000739BB21346C3EB010318B210BDC046E6
+:1062500070B5D0F8A830D3F8D443D3F8D053D3F8DE
+:10626000CC63FFF7D7FF621E0123934000B25B1996
+:1062700006FB1030204140B270BDC0462DE9F04110
+:10628000B0F8DA20074602F47043B3F5005FD0F8A7
+:10629000A85004D1B5F85463B5F8844513E0D3B2DF
+:1062A000942B03D9B5F88645022308E0632B03D964
+:1062B000B5F88845012302E0B5F88A45002305EBCF
+:1062C0004303B3F85663FF2E1ED001213846FFF773
+:1062D000BFFF40B2193804FB00F000B20028CCBF69
+:1062E00000F5FA73A0F5FA734FF47A7293FBF2F3A8
+:1062F00098B28419A4B2384640F23441FF222346B2
+:10630000FCF74AFAA5F86643BDE8F08170B505468A
+:10631000D0F8A8600C4689B340F2DA6142F2080274
+:10632000FCF72AFA284640F2A6510522FCF70EFA9D
+:10633000284640F2A251C322FCF708FA284640F250
+:10634000A5510722FCF702FA284640F283514FF488
+:106350004872FCF7FBF9284640F284510022FCF712
+:10636000F5F9284640F285514FF40072FCF7EEF93A
+:10637000284640F286510022FCF7E8F928462721FA
+:10638000FFF7C4FD1CB140F001039CB203E04FF6DF
+:10639000FE7400EA040496F894332846F31893F840
+:1063A0009523052302FB03F22621042A98BF1A46EF
+:1063B000FFF79AFD04F110022846272192B2FFF759
+:1063C00093FD70BD70B5D0F8A850044695F84233DF
+:1063D0005BB10021FFF79AFF204619210022FFF749
+:1063E000A5FD10B9012385F8453370BD70B5D0F80F
+:1063F000A840054694F8423393B990F8E93013F079
+:10640000010F1CBF23F0010380F8E93090F8E93058
+:1064100013F0020F2DD023F0020380F8E93028E0BA
+:1064200094F847330BB1012303E0D1F1010338BFE6
+:10643000002384F84733E1B100230126C4F86C330C
+:1064400084F8453384F846632846FFF7BBFF94F889
+:106450004333003B18BF012384F8443313B128466B
+:10646000FFF722FC2846FEF79FFB28463146FFF740
+:106470004DFF70BD70B5D0F8A83000260C4683F8EB
+:10648000466331460546FFF741FF14B12846FFF742
+:106490000BFC03222846134640F67A01FCF77CF9F0
+:1064A000284640F2DA6142F208023346FCF774F9FA
+:1064B00070BDC04670B50546D0F8A84016467AB102
+:1064C00094F8433394F842438C2144EA4304C3696B
+:1064D000146018693AF00ED944EA004434600FE0C1
+:1064E000CB080DD101F0010384F84233C1F340031E
+:1064F00084F8433394F8423313B90121FFF7BAFF0C
+:1065000070BDC04610B500210446FFF7B3FF20461A
+:10651000FEF74AFB10BDC04610B50122044640F606
+:106520000501FCF729F920460722052340F22F41F7
+:10653000FCF732F920463021F8234FF4FF62FCF7D4
+:106540002BF90623204630210722FCF725F92046A7
+:1065500040F2144141F61062FCF7F8F8204640F290
+:1065600015414FF4C862FCF7F1F8204640F2DF41D4
+:106570004FF47F424FF47743FCF70EF92046FFF7C4
+:10658000E9FB204602492D22FCF71AF910BDC0464E
+:10659000680E0200002914BF0223002310B5002A50
+:1065A00018BF43F001030446032240F24D41FCF7BB
+:1065B000F3F8204640F24C410322FCF7DDF810BD11
+:1065C00010B5044611B91049132219E012220F49DF
+:1065D000FCF7F6F8012100222046FFF7DBFF2046FA
+:1065E0000B490622FCF7ECF8B4F8DA3003F47043F8
+:1065F000B3F5005F07BF20460649204606491E2224
+:10660000FCF7DEF810BDC04692080200B808020090
+:10661000DC080200660A0200E80802002DE9F041E9
+:1066200004460D46164640F2DA6148F280021F46E3
+:106630009DF81880FCF7A0F82046FEF7B7F9B8B12E
+:1066400040F652112046FCF775F8FF22C3B240F61F
+:1066500048112046FCF7A0F840F653112046FCF7FD
+:1066600069F840F64911C3B2FF222046FCF794F8BE
+:10667000D4F8A83093F8463573B140F2EB41204688
+:10668000FCF758F8C0F3402340F2EB4120464FF4AA
+:1066900080629B02FCF780F86B1EFF22204640F2CE
+:1066A00042619BB24FF6FF75FCF776F8AE4201D01F
+:1066B000731E9EB220464FF4C8612A463346FCF74B
+:1066C0006BF8204640F241612A463B46FCF764F8ED
+:1066D000B8F1000F05D0204608490422FCF770F8F5
+:1066E00009E0204640F23F610122FCF72FF82046E6
+:1066F0000121FFF765FFBDE8F081C046DE0B020017
+:106700002DE9F0410C4640F23B410546FCF712F8FA
+:1067100040F23C4107462846FCF70CF8064674B1A7
+:106720000E2228460F49FCF74BF828460121FFF7B7
+:1067300047FF28460C490722FCF742F810E028469C
+:106740000A490422FCF73CF8284640F23B413A460D
+:10675000FBF7FCFF284640F23C413246FBF7F6FFD0
+:10676000BDE8F08186090200980B0200500D02007E
+:106770002DE9F04F0546C5B001910092FDF79AFC56
+:10678000EB694FF0805118690A4639F093DF052014
+:10679000EFF3E2F7002328464FF489614FF480427B
+:1067A000FBF7FAFF284640F255414FF4A842FBF7A9
+:1067B000CDFF284640F25641FBF7BCFF00F00F002A
+:1067C000052809D14FF4A842284640F25541FBF76D
+:1067D000BDFF4FF4807207E045F20142284640F2C7
+:1067E0005541FBF7B3FFFE22803A521022EAE272D3
+:1067F000102AA8BF10225100002301F18006C2EB2D
+:10680000060B1F46994698469A464393429340E0AA
+:1068100040F256412846FBF78DFF40F25741C0F346
+:106820000B142846FBF786FF5E4544EA003021DC66
+:10683000BAF17F0F1EDC8104890CB1F5005FC8BF7F
+:10684000A1F5804101F50063B3F5805F23D802AB69
+:1068500023F8191044AB03EB880252F8083C0AF104
+:10686000010ACB1842F8083C08EB090383F0400901
+:1068700088F00108C0F3033303F00C0343EA071365
+:1068800016F0010F9FB203D007F0FF03402B02D197
+:10689000013E002EBCDCEB69002218694FF08051EC
+:1068A00039F008DF2846FDF7FFFB429B9B1142931E
+:1068B000439B9B11BAF1800F43931DD0002022E02F
+:1068C00041EA801202AB33F9123001315B1B4029DF
+:1068D00003FB0344F4D1013002280FD1009AA3092D
+:1068E0001460019A1360A3F53A63084A183B934277
+:1068F0008CBF0020012006E00020044642AB53F884
+:1069000020500021DCE745B0BDE8F08F48F4FF0FD0
+:1069100070B504460D46FDF7CDFB20226B012046E5
+:106920004FF49661FBF738FF0023204640F2B14157
+:106930004FF40072FBF730FFB4F8DA3003F4704321
+:10694000B3F5005F02D04FF0000E04E0D5F1010E68
+:1069500038BF4FF0000E002D0CBF2023002343EA68
+:106960008E13204660224FF48261FBF715FF20460C
+:106970004FF482618022EB01FBF70EFF2046FDF70A
+:1069800093FB70BD2DE9F047044688461746D0F8C2
+:10699000A890FCF78DFB20460121FFF7B9FF0025E9
+:1069A0002E460CE0012100222046FDF78BFA3846E6
+:1069B000EFF3D2F62046FEF78BFA40B285B2F3B27F
+:1069C00001364345EED320460021FFF7A1FF89F8A9
+:1069D000C052BDE8F087C04670B505460846FEF7D0
+:1069E000A7F8EB69A02144B2186939F083DE9D3C19
+:1069F000A4B26FF0610324B29C42B8BF1C46C1B27E
+:106A000062B22846FCF770FD70BDC04673B5D0F881
+:106A1000A840064694F84233002B00F0DC8094F83E
+:106A20004633002B00F0D780D0F8B030D3F82031B7
+:106A300013F0010F00F0CF8000230093019394F82E
+:106A40004553002D40F0AA8029462A46FFF76EFAEA
+:106A5000002800F0A380304601A96A46FFF788FEAF
+:106A6000002800F09B80009BC4F86C3394F84633F8
+:106A7000012B40F0938094F891030199AC46AE4607
+:106A80001FE045B204EB8502D2F87033994201D37E
+:106A9000002203E0C2F870131946012204EB8503BB
+:106AA000D3F870339C440EF101035FFA83FE431C5C
+:106AB000D8B243B2072BC8BF002012B1019101998F
+:106AC00019E094F990334FFA8EF29A42D9DBF5E748
+:106AD00043B204EB8303D3F87023C3F87013431C51
+:106AE000D8B243B2072BC8BF00200EF101038C447B
+:106AF0005FFA83FE11464FFA8EF3072BE8DD019112
+:106B000094F8902353B2072B05DC002384F89233CA
+:106B1000531C84F8903394F99033082B3ED194F8A9
+:106B20009433E31893F8972393F8995394F8923396
+:106B3000FC2B02D8013384F8923394F892339342B9
+:106B40002CD194F89133013384F891335BB2072B45
+:106B500002DD002384F8913394F890333046023BF1
+:106B600084F890336146FEF7DFFF18B93046FEF730
+:106B70001BF810E094F89333FC2B02D8013384F80F
+:106B8000933394F89333AB4205D194F8943313B90B
+:106B9000013384F89433002384F8923394F8461335
+:106BA0000023012984F8453303D13046FFF7AEFBBB
+:106BB00003E030461946FFF75DFC3046D4F86C130D
+:106BC000FFF70AFF002384F8473394F89C3313B986
+:106BD000013384F89C337CBD2DE9F04F0746D0F893
+:106BE000A800E1B00B9041F22403FB5C0C46002BA3
+:106BF00000F09C82FB696A21186939F07BDD400056
+:106C00001FFA80FBBBF1000F00F090823846FEF7C0
+:106C100085F9FB69024610B91869594684E218697A
+:106C2000594639F067DD012800F080820BF1060338
+:106C30009BB20C930BF13A039BB20D930BF16E03D5
+:106C40009BB20E930BF1AA039BB20F93002C00F0A2
+:106C50005A82384640F2F941FBF76CFD10F0080FFC
+:106C600040F064824CAD38ACAB1C0193A31C039381
+:106C70003846002340F2764140F2FF12009502941C
+:106C8000FBF7D4FD2B1D0093AB1D0193231D029335
+:106C9000A31D03933846002340F2774140F2FF12D0
+:106CA000FBF7C4FD05F10803009305F10A03019306
+:106CB00004F10803029304F10A030393384640F2F7
+:106CC000AA4148F2FF1248F27F03FBF7AFFD05F13E
+:106CD0000C03009305F10E03019304F10C0316223B
+:106CE000029304F10E0303933846134640F23B41EE
+:106CF000FBF79CFD05F11003009305F112030193CE
+:106D000004F11003029304F1120346220393384660
+:106D1000002340F23C41FBF789FDB7F8DA3005F17A
+:106D2000140E03F47043B3F5005F05F11C030A93DE
+:106D300005F11E03099304F11C03089304F11E03DB
+:106D4000079305F12003069304F1200305F11602D1
+:106D500004F1140104F1160005F1180605F11A08F2
+:106D600004F1180904F11A0A05F12205059304F14A
+:106D7000220437D1019241F22B0213460291039073
+:106D800040F24C413846CDF800E0FBF74FFD384665
+:106D900040F24D4144F22B0244F20A030096CDF832
+:106DA0000480CDF80890CDF80CA0FBF73FFD089AC1
+:106DB0000A980999079B0292072200900191039378
+:106DC0003846134640F2F941FBF730FD0698059925
+:106DD000072200900291384640F2FA41134601958D
+:106DE000039436E0019241F22B0213460291039084
+:106DF00040F24C413846CDF800E0FBF717FD38462D
+:106E000040F24D4144F22B0244F222030096CDF8A9
+:106E10000480CDF80890CDF80CA0FBF707FD0A9A86
+:106E2000099B089807990092072201930290134644
+:106E30000391384640F2F941FBF7F8FC069A059BAE
+:106E40000092029301950394384640F2FA410722DA
+:106E5000002324ACFBF7EAFCA31C019310AB012236
+:106E600002930DF142030721039338461346009421
+:106E7000FBF748FC231D0093A31D019311AB1022C7
+:106E800002930DF14603FF21039338461346FBF7A7
+:106E900039FC04F10803009304F10A03019312ABD7
+:106EA000042202930DF14A034CAE03933846134675
+:106EB00040F21F11FBF726FC06F1240338AD0093C6
+:106EC00006F12603019305F1240340F644020293E0
+:106ED00005F1260303933846134640F63811FBF7B5
+:106EE000A5FC06F12803009306F12A03019305F19E
+:106EF0002803029305F12A030393384640F639111B
+:106F000040F6440240F60403FBF790FC04F10C0346
+:106F1000009304F10E03019313AB012202930DF1D0
+:106F20004E033A21039338461346FBF7EBFB04F17B
+:106F30001003009304F11203019314AB082202938F
+:106F40000DF152030393384613464FF48D71FBF74E
+:106F5000D9FB04F11403009304F11603019315AB5C
+:106F6000082202930DF15603052103933846134678
+:106F7000FBF7C8FB04F11803009304F11A03019313
+:106F800016AB042202930DF15A033A2103933846BB
+:106F90001346FBF7B7FB04F11C03009304F11E0337
+:106FA000019317AB012202930DF15E030393384660
+:106FB00013464FF48D71FBF7A5FB06F12C030093EC
+:106FC00006F12E03019305F12C03029305F12E0324
+:106FD0000393384640F2D74147F2CB0242F24B03CB
+:106FE000FBF724FC04F12003009318AB202202934A
+:106FF0000DF1620382212234039338461346019433
+:10700000FBF780FB0B98037B827AC17A1B0342F467
+:10701000007242EA011243F0030343EA820306F1DD
+:107020003002009205F13002323602923235384693
+:107030004FF49B6147F6FF729BB201960395FBF7F5
+:10704000F5FBDDF83090DDF834800026FB694CACB0
+:10705000325B1869494639F06BDBFB6938AD725B0E
+:107060001869414639F064DBFB69A419186909F114
+:107070000201628839F05CDBFB69AD1908F102019D
+:1070800018696A88043639F053DB342E09F1040993
+:1070900008F10408DAD1DDF83890DDF83C800026EC
+:1070A000FB6924AC325B1869494639F041DBFB6966
+:1070B00010AD725B1869414639F03ADBFB69A419DF
+:1070C000186909F10201628839F032DBFB69AD19F8
+:1070D00008F1020118696A88043639F029DB242E88
+:1070E00009F1040908F10408DAD1FB690BF1020186
+:1070F00018690D2239F01CDBFB690BF104011869DA
+:10710000092239F015DBFB690B991A6A18690B9B88
+:10711000C1F83824B3F83C240BF1E60139F008DB60
+:10712000FB6959461869012239F002DB61B0BDE8FC
+:10713000F08FC0462DE9F04F8DB007460F220E4666
+:107140000DF12100B249EAF317F7D7F8A880002221
+:10715000B04D14016359B34203D001320E2AF7D166
+:1071600075E3384691210022FBF772FA3846382140
+:107170000722FBF76DFA0A2238468821FBF768FAE6
+:10718000D7F8A83093F882251AB138468821FBF742
+:107190005FFA64192A213846227AFBF759FA30211E
+:1071A00003223846637AFBF799FA91210322384685
+:1071B000A37AFBF793FAE37A38210F223846FBF7DC
+:1071C0008DFA912100223846FBF742FA3821072236
+:1071D0003846FBF73DFA237B30210C229B003846D2
+:1071E000FBF77CFA5E210F223846637BFBF776FAC9
+:1071F000A37B5E211B01F0223846FBF76FFA6C215E
+:107200003846E27BFBF724FA384638210822FBF7A0
+:107210001FFA384691210322FBF71AFA0CA98B19A1
+:1072200013F8102C38465E21FBF712FA012238467B
+:107230007E21FBF70DFA98F8EE231AB13846382173
+:10724000FBF706FA0722134638462A21FBF746FACF
+:1072500038462C210022FBF7FBF938462A210C2264
+:10726000FBF7F6F9012238462C21FBF7F1F9D7F8A4
+:10727000A82092F852352BB338465E2192F8532558
+:10728000FBF7E6F9D7F8A830384693F854252A21B9
+:10729000FBF7DEF9D7F8A830384693F855252B21AF
+:1072A000FBF7D6F9D7F8A830384693F856252C21A5
+:1072B000FBF7CEF9D7F8A83038462D2193F857259B
+:1072C000FBF7C6F9B7F8DA3003F47043B3F5805F23
+:1072D00004D13846BF21EE22FBF7BAF90222134649
+:1072E000384640F21F11FBF7F9F90422F721134643
+:1072F0003846FBF7F3F9F121032200233846FBF768
+:10730000EDF9F221F82290233846FBF7E7F9A223A2
+:10731000F321FF223846FBF7E1F9B7F8DA3003F43E
+:107320007043B3F5005F04D1D7F8A83093F818354F
+:1073300006E0B3F5805F06D1D7F8A83093F8193589
+:10734000012B00F07B82042238469D210023FBF7AD
+:10735000C5F90022079244213846FBF761F940F253
+:107360002B1101903846FBF75BF94421029007226C
+:107370003846FBF7A5F9384640F22B110E22FBF7F1
+:107380009FF941F2080357F803A0079B0BB9554634
+:1073900001E04FEA4A05204B9A4502D84FF0010917
+:1073A00006E01E4B9A4594BF4FF002094FF00409C6
+:1073B000B7F8DA3003F47043B3F5005F03D000216F
+:1073C0000591069106E06268032302FB03F2059231
+:1073D0006A000692124C102221465046FDF7BAF977
+:1073E000102221462846FDF7B5F91022049009FB2A
+:1073F00004F15046FDF7AEF9B7F8DA30039003F424
+:107400007043B3F5005F0DD04FF0000B10E0C046A5
+:10741000C80602001424020080BA8C01007519030A
+:1074200040420F00059802211022FDF793F9834690
+:107430004F2102223846FBF70BF9CD4B4FEACA0524
+:1074400009FB03F3B5FBF3F301335B08013B5FFA80
+:1074500083F85221072238464FEA9803FBF73EF99A
+:1074600008F101065321602238464FEA4813FBF722
+:1074700035F909FB06F3BF4CB5FBF3F5BE4B2C19F0
+:10748000B4FBF3F4013CE4B2512122463846FBF749
+:10749000DFF8039B10221D0158462946FDF75AF9D3
+:1074A000013406FB04F600FB06F000280BDB58460F
+:1074B00029461022FDF74EF900FB06F0C0130130FB
+:1074C0004010441E0EE0584629461022FDF742F9AE
+:1074D0006FEA080303FB04F300FB03F0C013013061
+:1074E0006FEA6004C4F3072353210F223846FBF7E9
+:1074F000F5F85421E2B23846FBF7AAF806999F4BFB
+:107500000A22B1FBF3F30599384601FB02F2B2FB04
+:10751000F3F803FB1822590802F0010401EB0454AC
+:107520005208B4FBF3F49B0803EB0253B3FBF1F3F3
+:10753000E41845211F22C8F30713FBF7CFF84FEAE1
+:107540000813462138464FF4F87203F0F003FBF7B6
+:10755000C5F8C4F3074346210F223846FBF7BEF8AF
+:107560004721C4F307223846FBF772F84821E2B2FC
+:107570003846FBF76DF8079A41F29416002A08BFC7
+:107580004FF4FA56A6F5D8760CBF4FF482794FF433
+:10759000E1794FF4F572033E96FBF2F606FB02F535
+:1075A00005F52A754FF425636D02B5FBF3F540F23E
+:1075B0007C6405FB04F4A4F55834A4F5C064B4FB62
+:1075C000F2F4640AC4F3820242EAC6023846422157
+:1075D00092B2A4B2FBF73CF804F0030204F01F04DB
+:1075E00044EA421238464321FBF732F84FEA492475
+:1075F0004FF48773B4FBF3F404FB05F4604B640AA7
+:10760000604AB3FBF4F39A184FF41243B2FBF3F25F
+:107610005D4B02F00F02B3FBF4F3A3F54C23A3F58B
+:1076200000631B0C42EA03123846402192B2FBF77A
+:107630000FF84FF02552554BB2FBF4F2B3FBF4F3C5
+:10764000A2F546324FF4B841A2F50072A3F56E33AD
+:10765000B2FBF1F2A3F50073B3FBF1F302F00F02FA
+:1076600042EA03123846412192B20BF17444FAF710
+:10767000EFFF04F590044FF4966394FBF3F4292391
+:1076800004FB03F44FF45C7308FB03F840F22B5344
+:1076900006FB03F606F5E46109FB08F00C31102245
+:1076A000FDF758F804F5D81400EB640090FBF4F0F3
+:1076B000C0B23C2894BF0025012515B14308043B06
+:1076C00000E0031FDCB23C213F2223463846FBF793
+:1076D00005F8AB013C2140223846FAF7FFFFB7F826
+:1076E000DA3004F1040603F47043B3F5005F05F1EA
+:1076F000010404D1D7F8A83093F8273506E0B3F594
+:10770000805F19D1D7F8A83093F82835012B13D111
+:10771000049B40F245105946102203FB00F0FDF790
+:1077200019F804FB06F39E2100FB03F4C02238463F
+:107730004023FAF7D3FF0BE00499962001FB00F0F9
+:1077400010225946FDF706F804FB06F300FB03F48C
+:10775000B4F5160FD4BF002501256B1C032203FBD3
+:1077600002F394FBF3F0B0F5003F11D5002315E0D0
+:10777000404B4C003F420F0040420F00A0860100EA
+:10778000000068600021F6FF000084A30000302A9A
+:10779000A0F5C033DB130133C3F347033D213F2280
+:1077A0003846FAF79BFFAB013D2140223846FAF7F5
+:1077B00095FF284B9A4504D9202238465721134675
+:1077C00003E03846572120220023FAF787FF224B97
+:1077D0009A4504D9102238465721134603E038460B
+:1077E000572110220023FAF779FF049AB2F5341FCB
+:1077F00005DD38464A210222FAF762FF04E03846E6
+:107800004A21FD22FAF74EFF0C2244211346384646
+:10781000FAF764FF0120EEF39FF73846FEF76AFAA5
+:10782000019B38464421DAB2FAF712FF029B384630
+:1078300040F22B11DAB2FAF70BFF08E004229D2187
+:1078400038461346FAF74AFF0121079183E50DB048
+:10785000BDE8F08F80BA8C010075190341F208036E
+:107860002DE9F047C4588A4B4FF48475B4FBF3F408
+:1078700004FB05F41A235721B4FBF3F40646FAF788
+:10788000CFFE172181463046FAF7CAFE182130464E
+:10789000FAF7C6FE40F20511FB2207463046FAF71A
+:1078A00001FF304604214022FAF70AFF30464FF428
+:1078B00090711022FAF704FF304657210222FAF79E
+:1078C000FFFE304640F205110422FAF7F9FE304679
+:1078D0004FF483712A22FAF7BBFEA4B2304640F27D
+:1078E00007116E22FAF7B4FEE2B230462946FAF7E3
+:1078F000AFFEC4F30422304640F20911FAF7A8FEA5
+:10790000304640F20511FD22FAF7CCFE30464FF426
+:1079100083710122FAF7D4FE3220EEF31DF75D4C9D
+:1079200003E00A20EEF318F70A3C30464FF4857165
+:10793000FAF776FE10F0010F01D1092CF1D1304693
+:107940004FF48571FAF76CFE10F0010F08D1FAB20E
+:1079500030461821FAF7B4FE4FF00B0847460CE00A
+:10796000304640F20F11FAF75BFE00F01F071D2FA3
+:107970008CBF4FF00B0807F1020819213046FAF7C7
+:107980004FFE4FF48371FE2205463046FAF78AFE19
+:10799000304640F20511FB22FAF784FE304640F2F1
+:1079A00005110422FAF78CFE304640F2051102223E
+:1079B000FAF786FE30464FF483710122FAF780FE13
+:1079C0003220EEF3C9F6334C03E00A20EEF3C4F69E
+:1079D0000A3C30464FF48571FAF722FE10F0010F91
+:1079E00001D1092CF1D130464FF48571FAF718FE18
+:1079F00010F0010F06D1EAB230461921FAF728FE3D
+:107A0000092506E030464FF48871FAF709FE00F0C8
+:107A10001F053046FE224FF483716C01FAF742FED7
+:107A200044EA85243046FB2240F20511FAF73AFE7B
+:107A30002C43304657215FFA89F2FAF709FE3046A7
+:107A4000224640F63311FAF781FE2246BC02304648
+:107A500044EA471440F63411FAF778FE304645EA16
+:107A6000040240F63511FAF771FE304644EA070287
+:107A700040F63611FAF76AFE48EA4812D205304657
+:107A800040F63711D20DFAF761FEBDE8F087C04627
+:107A900040420F008996980070B55B210446FD2294
+:107AA000FAF700FE204604214022FAF709FE20469C
+:107AB0004FF490711022FAF703FE204678218022BD
+:107AC000FAF7FEFD204640F229110222FAF7F8FDEE
+:107AD000204657210122FAF7F3FD20465B210222BE
+:107AE000FAF7EEFD41F28830EEF336F6154D03E07D
+:107AF0000A20EEF331F60A3D5C212046FAF790FDAC
+:107B000010F0200F01D1092DF2D15C212046FAF7A7
+:107B100087FD10F0200F03D020465C21FAF780FD8E
+:107B200020465B21FD22FAF7BDFD20465721FE22AB
+:107B3000FAF7B8FD204640F22911FD22FAF7B2FD0E
+:107B400070BDC0468996980070B504460E46002563
+:107B50006E4B2046E95AFAF763FDA8530235302DE3
+:107B6000F6D1182220466A49FAF72AFE3A21FB226A
+:107B70002046FAF797FD012220464FF48D71FAF75F
+:107B80009FFD362101222046FAF79AFD10224FF47C
+:107B90008D712046FAF794FD1420EEF3DDF53A21BD
+:107BA00001222046FAF78CFD1420EEF3D5F5B4F847
+:107BB000DA3003F47043B3F5005F03D120463A2175
+:107BC000012208E020463A2101220023FAF786FD2F
+:107BD0002046CA2104221346FAF780FD08222046D7
+:107BE0004FF48D71FAF76CFD25210E222046FAF72D
+:107BF0002FFD252101222046FAF762FDB4F8DA3084
+:107C000003F47043B3F5805F04D1204628211E227F
+:107C1000082303E0204628211E220C23FAF75EFDEC
+:107C20001420EEF399F5052108222046FAF710FDFD
+:107C300080224FF489712046FAF742FD1420EEF3BA
+:107C40008BF5FF2110222046FAF73AFD442240F23C
+:107C50001F112046FAF734FD1420EEF37DF50B21B9
+:107C600007222046FAF72CFD102240F2131120467D
+:107C7000FAF726FD1420EEF36FF5072101222046C6
+:107C8000FAF7E6FC1420EEF367F502230322204600
+:107C9000FC21FAF723FDFD212046A622FAF7D8FCA5
+:107CA000442240F21F112046FAF70AFD1420EEF399
+:107CB00053F5FF2110222046FAF702FD1420EEF3BF
+:107CC0004BF5B4F8DA3003F47043B3F5805F03D1B9
+:107CD00010492046082202E00F4920460622FAF702
+:107CE0006FFD20465921CC22FAF7B2FC20465C21D8
+:107CF0002E22FAF7ADFC20467821D722FAF7A8FC0D
+:107D0000204692211522FAF7A3FC70BDD20402008E
+:107D1000360A0200040B0200140B02002DE9F04F9A
+:107D200004468BB0894609B98B4608E040F2D7413A
+:107D3000FAF700FD01A983462046FDF799FD2022B0
+:107D400013464FF49A612046FAF726FD6420EEF3BD
+:107D500003F540F276412046FAF7ECFC40F2A641EA
+:107D600080462046FAF7E6FC09A9824608AA204682
+:107D700007ABFBF7B5F9099F089E079DB9F1000F06
+:107D800009D0204601A9FDF75BFD204640F2D7410E
+:107D90005A46FAF7DBFC4FEAC850C00D4FEACA5307
+:107DA00080F48070DB0D00F5FE70033083F4807387
+:107DB000C01A8010394632462B46FCF7EBFC4000D7
+:107DC0000BB0BDE8F08FC046F0B5D0F8A85085B034
+:107DD00095F858340646002B7BD00023019302937C
+:107DE0000393FDF775F8C7B20FB17F2F71D101ABC7
+:107DF00002AA304603A9FBF773F940F23E61304610
+:107E0000FAF798FC40F2A641C4053046FAF792FC16
+:107E1000C005C00DE40DFF288ABFA0F5807300F5F2
+:107E200080729AB2FF2C84BFA4F5807398B2C2F519
+:107E3000FE7398BF04F5807003331B18C3F38F00E3
+:107E4000C7B995F856340133DBB2042B85F85634A4
+:107E50003FD985F85674029A019B0399FCF79AFC66
+:107E6000D5F848244310043B9342B8BF1346C5F8E5
+:107E700044341AE07F2F2CD195F857340133DBB20C
+:107E8000042B85F8573424D9002385F85734029AF7
+:107E9000019B0399FCF77EFCD5F84424431004337E
+:107EA0009342A8BF1346C5F84834D6F8A8109BB231
+:107EB000D1F8442430469342A8BF1346D1F8482451
+:107EC00040F2A7419342B8BF13469BB2FF22FAF794
+:107ED00063FC05B0F0BDC0462DE9F04F474B87B0BD
+:107EE00003AC80460D4693E8070084E8070040F2A3
+:107EF00045614046D8F8A8B0FAF71CFC40F246614C
+:107F000087054046FAF716FC3D498605062240469D
+:107F1000FAF756FC00210A464046FDF741F84FF4B7
+:107F2000FA730193404629462022A3F5FA73009480
+:107F3000FDF736FFBF0DB60D8246002849D0049DDF
+:107F4000DDF81490039C09EB0503012B02D84FF0D8
+:107F5000000A3EE02046FBF74BF806464846FBF792
+:107F600047F8A6F114031AB2002A06DB35FA02F12B
+:107F70003FD0013235FA02F206E0534215FA03F11E
+:107F800037D0D24315FA02F233B2C3F11E0314FA0A
+:107F900003F3C3EB0204A0F10B031BB2002B0A4650
+:107FA00002DB35FA03F102E05B4215FA03F120D05F
+:107FB00003B2C3F11F0309FA03F394FBF2F493FB3A
+:107FC000F1F004FB1400FBF71FF8A7058605BF0DB1
+:107FD000B60D404639463246FCF7E2FF40460949B5
+:107FE0000622FAF7EDFB5046ABF8B872ABF8BA626E
+:107FF00000E0002007B0BDE8F08FC046BC060200DC
+:10800000C20E0200DC0E020070B504460D46C9B176
+:1080100004221249FAF7D4FBD4F8A83093F8E933D4
+:10802000A02B05D1204640F64A1140F24F1203E042
+:10803000204640F64A11A722FAF788FB0849204655
+:108040000E2201E007490A22FAF7BAFBE369291E6A
+:1080500018BF0121186938F0A7DB70BDBE0D020002
+:10806000A20D0200D80D020070B50C46062226496A
+:10807000E4B20546D0F8A860FAF7A2FB0C2C01D8B0
+:10808000002405E041F25013EB561C1E18BF0124DA
+:1080900096F81A35002B31D0284640F64211FAF7EF
+:1080A00049FB14B10F280BD100E0A8B9D5F8F8307E
+:1080B00013F0060F22D196F82C30A3421ED05CB1EB
+:1080C000EB690122D8689968EDF398F728460121F9
+:1080D000FFF79AFF01230AE0EB690022D86899684C
+:1080E000EDF38CF728460021FFF78EFF002386F87A
+:1080F0002C30284605490C22FAF762FB2846044931
+:108100000422FAF75DFB70BDB6070200700702009B
+:108110008807020070B50D46B0F8DA101646D0F8A0
+:10812000A840FAF731FD28B994F84C342B7094F834
+:108130004D3401E000232B70337070BD2DE9F04702
+:108140004FF0000886B0054602ABCDF81080CDF8A0
+:108150000C80CDF8088003AA8A4604A9D0F8A8901C
+:10816000FAF7BEFF28460DF117010DF11602FFF7D1
+:10817000D1FF9DF8173004990193039A029B0124C3
+:1081800028460094FCF71AFB9DF816300746019329
+:108190002846029B0499039ACDF80080FCF70EFB59
+:1081A00099F8E83306460BB39DF81700B5F902219C
+:1081B000B5F90431B5F906110190284603920293EE
+:1081C00004910094FCF7FAFA9DF8163004460193E6
+:1081D00028460499039A029BCDF80080FCF7EEFA3A
+:1081E000A742B8BF27468642A8BF0646BAF1010F8C
+:1081F00002D0BAF1030F02D17B10C9F84434AAF1BE
+:108200000203DBB2012B02D87310C9F8483406B060
+:10821000BDE8F08707B540F25643009340F255425F
+:108220000133FAF7F1FB0EBD2DE9F04340F2DF41D7
+:1082300089B0D0F8A8400546FAF77CFAC3B27F2B84
+:10824000A4F84C30C0F30720C4BFA3F58073A4F892
+:108250004C307F28C8BFA0F58073A4F84E0001AF52
+:10826000C8BFA4F84E301123039320262A330DF102
+:1082700018094FF00208284639460493CDF80490B7
+:10828000CDF808800596FFF7C5FF069B3F2B01D967
+:10829000803B0693069B2365079B3F2B01D9803BC0
+:1082A0000793079B40F2344163652846FAF742FA88
+:1082B000C0B27F28C4BFA0F5807398B284F858007C
+:1082C00040F224412846FAF735FAC0F30720A4F813
+:1082D0005A0040F225412846FAF72CFA0D23C0B285
+:1082E000A4F85C00039328460F3339460493CDF875
+:1082F0000490CDF808800596FFF78CFF069B236459
+:10830000079B636409B0BDE8F083C0462DE9F041E6
+:10831000B2F1FF3F8AB0064688461746D0F8A8500B
+:1083200002D1FCF7E1FB47B295F966355FFA88F4B4
+:10833000013394FBF3F407230393193305930123CB
+:10834000E4B2029301AD07AB0193304604F5A0738C
+:1083500029460493FFF75EFF079BC034C3F307531E
+:108360000793304606AB294601930494FFF752FF6A
+:10837000002107980DF126020DF12203F0F31AF007
+:108380000021402008AB09AAF0F314F0BDF9223017
+:10839000BDF920108B4209DABDF92400C91AF0F3A7
+:1083A000BBF0BDF82240ADF8240009E0BDF926007D
+:1083B000C1EB0301F0F3B0F0BDF82040ADF82600AA
+:1083C000BDF92600BDF92410F0F3B0F023B2032B61
+:1083D00080B201DD231F01E0C4F104039AB212B29E
+:1083E00008FA02F103B2052003FB0010911E0123DD
+:1083F0008B40013AC018104107FB00F0C0F3CF00DA
+:108400000AB0BDE8F081C04670B5182386B0D0F838
+:10841000A840039300238022049340F27666203321
+:1084200005460593314613460292FAF7B5F904F171
+:108430009C03284601A90193FFF7ECFE40F271610D
+:108440002846FAF777F940F27361A4F89C022846AF
+:10845000FAF770F940F27461A4F89E022846FAF720
+:1084600069F940F27561A4F8A2022846FAF762F9A8
+:1084700040F27961A4F8A0022846FAF75BF9314688
+:10848000A4F8A4022846FAF755F940F2DA61A4F8F4
+:10849000A6022846FAF74EF940F22551A4F8A802A0
+:1084A0002846FAF747F994F86735A4F8AA0284F841
+:1084B000AC324FF48F612846FAF73CF94FF49A61D9
+:1084C000A4F8AE022846FAF735F940F22451A4F890
+:1084D000B0022846FAF72EF9B4F86835C0F3C03078
+:1084E000A4F8B43294F80734A4F8B20284F8B6328F
+:1084F00094F8083484F8B73206B070BD7FB5002315
+:108500000293103304930DF116030093012301939A
+:10851000694654330393FFF77DFEBDF8160007B09C
+:1085200000BDC0462DE9F84FD0F8A860074696F880
+:1085300046355BB9FFF7E2FF40F3072340B21FFA6D
+:1085400083F81FFA80F9C246CB4607E0B6F84A85A1
+:10855000B6F84C95B6F84EA5B6F850B5B7F8DA307F
+:10856000384603F47043B3F5005F0CBFB6F866609D
+:10857000B6F868604FF0FF320121FCF72BFA36B2F3
+:108580000121324684B23846FCF724FA0021241A2D
+:108590004FF0FF323846FCF71DFA0121324685B212
+:1085A0003846FCF717FAA4B2C4EB0806B6B2C4EB1F
+:1085B00009042D1AFF2238463346A4B240F6521160
+:1085C000FAF7EAF83846FF22234640F65311FAF745
+:1085D000E3F83846FF22334640F65611FAF7DCF846
+:1085E000ADB23846FF22234640F65711FAF7D4F8C9
+:1085F000C5EB0A033846FF2240F648119BB2C5EB93
+:108600000B05FAF7C9F8384640F64911FF22ABB21C
+:10861000FAF7C2F8BDE8F88F2DE9F04F93B00DF1ED
+:1086200026080C46D0F8A8503B49064693464046DB
+:10863000222201AFE9F3A0F4384638492222E9F3B7
+:108640009BF4BCB10022304640F60F11FAF77EF8D9
+:1086500095F8E933324AA02B324B14BF052403248A
+:1086600014BF1046184614BF4FF0100A4FF0110AFD
+:10867000B94616E0012230464FF41161FAF766F868
+:1086800095F8E933284AA02B284B14BF0E240A245E
+:1086900014BF1046184614BF4FF0100A4FF0110ACD
+:1086A000C1460022114604E00B5A013224319B4599
+:1086B00006D0A2421FFA82F8F6D14FF6FF7416E0F8
+:1086C0000FFA88F2242302FB03070024254607E063
+:1086D00035F80910304637F81420FAF737F8023524
+:1086E00001340AF101039C42F2D11FFA88F43046AA
+:1086F000FCF74AF910B13046FFF714FF3046FCF79B
+:1087000065FD20B2B0F1FF3F0CBF4FF0FF300020FD
+:1087100013B0BDE8F08FC046E20A0200680802000C
+:10872000F826020040220200F4240200AC220200DB
+:108730002DE9F0438BB006460F4691460DF1060039
+:108740001D492222E9F318F4D6F8A83093F8E9334A
+:10875000A02B14BF4FF010084FF0110817B93D4679
+:108760003C4619E000252C4609E00DF10603E15ACC
+:108770003046F9F7DFFF013524F80900023445459A
+:10878000F3D10BE00DF10603E15A34F8092030462D
+:10879000F9F7DCFF013502344545F3D13046FCF7EB
+:1087A000F3F810B13046FFF7BDFE17B93046FCF7BD
+:1087B0000DFD0BB0BDE8F0830C0C020030B587B0A6
+:1087C00005AB0093022301930023029350330C4620
+:1087D00003936946102315460493FFF71BFDBDF86C
+:1087E00014302380BDF816302B8007B030BDC04652
+:1087F0007FB50DF11603009301230193013B029312
+:1088000057330393694610230493FFF703FDBDF824
+:108810001600000A07B000BD07B540F256430093AA
+:1088200040F255420133FAF7B5F80EBDF0B5B0F895
+:10883000DA30D0F8A85003F47043B3F5005F0CBFF2
+:1088400095F8403395F8413387B085F8423395F871
+:108850004233064685F84333B0F8DA3003F4704308
+:10886000B3F5005F14D195F8492353B2002B02DD14
+:1088700085F8482309E0C3691B6D13F4805F01D0BC
+:10888000342300E0302385F8483395F85C3313E057
+:1088900095F84A2353B2002B02DD85F8482309E0FE
+:1088A000C3691B6D13F0805F01D0342300E03023D7
+:1088B00085F8483395F85D335BB2002B4CDD03221D
+:1088C000022BA8BF022303FB02F340F2DF41304634
+:1088D000DFB2F9F72FFFC1B27F29C0F30720C4BF71
+:1088E000A1F5807399B203B27F2BC8BFA0F5807346
+:1088F0007AB2C8BF98B292B2C2EB0003C2EB0102D7
+:10890000DBB202F0FF0242EA0322304640F2DF41CE
+:10891000F9F71CFF0DF116030093022301930F33A7
+:1089200002930F2303933046082369460493FFF70D
+:1089300071FC9DF81630FAB29B1A8DF816309DF82E
+:10894000173030469B1A69468DF81730FFF764FFE1
+:1089500030466C46FDF7FEF94FF0FF3385F89A3349
+:1089600095F84D33002285F8472385F89C23BBB149
+:1089700085F8422385F84323304640F22341FF32F5
+:10898000B5F85033F9F708FF30464FF4AA61B5F84F
+:108990006023F9F7DBFE304604490422F9F710FFA3
+:1089A0003046FCF711F907B0F0BDC046EC0D0200EF
+:1089B0002DE9F04FC3690C464FF08051BBB005461E
+:1089C000D0F8A870164618690A4637F073DE0520FD
+:1089D000EDF3C2F628464FF489614FF4804200233C
+:1089E000F9F7DAFE0122284640F20A511346F9F758
+:1089F000D3FE0DF1E70334930123359310333693FF
+:108A00000F2337932846082334A93893FFF702FC35
+:108A10000CB1314612E0B5F8DA3003F47043B3F527
+:108A2000005F40F03E81EB6997F8BF641B6D13F463
+:108A3000805F0CBF08210621FF2E00D10E469DF855
+:108A4000E720032306FB13238DF8E6300DF1E60340
+:108A500034932846102334A93793FFF7DDFE7300C3
+:108A6000FE229BB2284640F20A51F9F795FE97F88C
+:108A7000C044FF2C00F0EA80002C00F0C980102CCC
+:108A800028BF1024C4F12403D9B272B24BB29A4267
+:108A900001DDCEB202E0002E08BF012670B2A04276
+:108AA000019002DC5FFA86F902E0631C5FFA83F949
+:108AB00004F1010BC9EB0B035FFA83F80D23369326
+:108AC000133338934FFA89F35B004FFA88F204931B
+:108AD00009AB03EBC203570003937B1CDBB2079384
+:108AE0006300013305934FEA4B03029206934FF064
+:108AF000000A0198049AA042CABF73B2CDF8DCB054
+:108B00003793379B34A953445B003793039B284624
+:108B100035923493FFF77EFB07990AE03AA800EB01
+:108B2000810353F8C42C42F0800243F8C42C8B1C00
+:108B3000D9B2059A9142F1DD002111E03AAB03EB85
+:108B4000810203EB870353F8C43C3AA842F8C43CC3
+:108B500000EB870353F8C03C42F8C03C8B1CD9B2F1
+:108B6000B942EBDB069A09AB349328464FEA4A0335
+:108B700034A90AF1250A35923793FFF74DFEBAF171
+:108B80004A0FB6D1019B4FFA88F2A342C4BF73B219
+:108B900037934FFA89F335930DF1AE0303EB42039C
+:108BA000D8BFCDF8DCB034931023389328460E2379
+:108BB00034A93693FFF72EFB0CE03AAE06EB4803E0
+:108BC00033F83A2C42F4006223F83A2C08F10103FE
+:108BD0005FFA83F8A045F0D9002109E0029E3AA887
+:108BE00000EB430200EB460333F83A3C22F83A3CF0
+:108BF0000298CBB201318342F0DB0DF1AE03349326
+:108C00002846002334A9CDF8D4B03793FFF704FEEB
+:108C100001221346284640F20E51F9F7BDFD4FF4EC
+:108C20007E4263021340284640F20E51F9F7B4FD2C
+:108C3000284640F20F517F222346F9F7ADFD284622
+:108C400040F20F514FF47E52E3011BE0284640F200
+:108C50000E5101220023F9F79FFD284640F20E51E4
+:108C60004FF47E420023F9F797FD284640F20F515A
+:108C70007F220023F9F790FD284640F20F514FF470
+:108C80007E520023F9F788FDEB694FF08051186997
+:108C9000002237F00FDD2846FDF75CF83BB0BDE859
+:108CA000F08F2146CAE6C0462DE9F041D0F8A86011
+:108CB0000746D6F87C45002505E021463846FFF7F3
+:108CC000ABFD01351434D6F878359D42F5D3BDE8B7
+:108CD000F081C046F0B5C369D0F8A85087B0074608
+:108CE00080219868EDF3F4F7044600286DD0B5F8BC
+:108CF0001C34002603F4807C03F4007E30464FF0E1
+:108D0000000316F0100206F00101035316D0BEF165
+:108D1000000F03D0D5F81C34C3F3802116F0080FE0
+:108D200002D095F81A3408E0D5F8183416F0200F60
+:108D300014BFC3F3072303F0FF030353BCF1000F79
+:108D400000D062BB16F0040F09D016F0020F025BD0
+:108D500002D0D5F80C340EE0D5F80C3418E016F03B
+:108D6000200F06F002030CD0025B13B1D5F81034CB
+:108D700001E0D5F8143409B11B0E0EE0C3F307432C
+:108D80000BE0025B13B1D5F8103401E0D5F81434D0
+:108D900011B1C3F3072300E0DBB2134303530136E1
+:108DA0000230402EABD10F230393002304933846A7
+:108DB000103301A9059302960194FFF72DFDFB697D
+:108DC000214698688022EDF393F707B0F0BDC046C6
+:108DD0002DE9F041002486B00594D0F8A88006461D
+:108DE000FBF782FE072302931933049307460123FE
+:108DF0002546019316E00BB90C4603E011F0010F74
+:108E00000FD14C0830467AB2FFF780FA06AB43F830
+:108E1000040D0093304604F5107369460393FFF781
+:108E2000FBFC0135802DE9B298F96635E3D17BB1C1
+:108E300001230193402405AB0093304604F51073E1
+:108E400069460393FFF7E8FC631CDCB2802CF2D187
+:108E500006B0BDE8F081C0462DE9F04FB0F8DA3039
+:108E600089B003F47043B3F5005F07468B46D0F832
+:108E7000A85002D1B5F8C42304E0B3F5805F08D14F
+:108E8000B5F8C62313B2B3F1FF3F02D01FFA82FA3E
+:108E900001E04FF0700A072304931933069301236E
+:108EA0004FF00009039307AB0293C846CDF8049036
+:108EB000019B18F0010F0BEB0306F378009303D02E
+:108EC00095F96635002B59D1B7F8DA3003F47043C1
+:108ED000B3F5005F03D0019B13F80B9012E0B5F8D7
+:108EE000402413B2B3F1FF3F18BF1FFA82F9B5F85F
+:108EF0003E2408BF4FF00F0913B2B3F1FF3F1CBF70
+:108F000092B20092B37872781B0443EA022343EAD8
+:108F10000A6343EA0903079395F9663502AC013306
+:108F2000B8FBF3F3C033384621460593FFF774FCD2
+:108F300007AB029395F9663538460133B8FBF3F376
+:108F400003F5A07321460593FFF764F93279009B7E
+:108F5000120542EA0372079B384623F07F4323F44D
+:108F600070031A43079295F9663521460133B8FB21
+:108F7000F3F303F5A0730593FFF74EFC019B08F193
+:108F800001080533B8F1800F019391D195F9663549
+:108F9000002B36D05E4608F1800896F8423196F8EC
+:108FA00041211B0443EA022302AC43EA0A6343EA79
+:108FB00009033846214608F180050793CDF814804F
+:108FC000FFF72AFC07AB3846214602930595FFF7C9
+:108FD00021F996F84421009B120542EA0372079B8F
+:108FE000384623F07F4323F470031A43214608F1E7
+:108FF0000108079205950536FFF70EFCB8F5A07F2E
+:10900000CBD109B0BDE8F08F10B5B0F8DA30D0F8A8
+:10901000A82003F47043B3F5005F03D1D2F87415B0
+:10902000FFF71AFF10BDC0462DE9F043054687B093
+:10903000D0F8A890002940D0072399F8C272029373
+:1090400019330493012301934FF0000805AB0093FB
+:109050002AE007F1C003284669460393FFF7DAF8D0
+:1090600006F1C003284669460393FFF7D5FB07F5D1
+:10907000A073284669460393FFF7CCF806F5A07362
+:10908000284669460393FFF7C7FB07F51073284688
+:1090900069460393FFF7BEF806F510732846694644
+:1090A0006C460393FFF7B8FB99F8C2325FFA88F673
+:1090B000B34208F10108CCD20CE0B0F8DA3003F486
+:1090C0007043B3F5005F02D10449FFF7C5FE28469F
+:1090D000FFF77EFE07B0BDE8F083C04684C90200FA
+:1090E0002DE9F041D0F8A84086B094F907144FF06C
+:1090F000FF3289B20646FFF709F994F9673505464C
+:10910000022B01D0002007E094F90814304689B200
+:109110004FF0FF32FFF7FAF8072302931933049355
+:109120000123C0EB05070193304605ABB4F8681581
+:109130004FF0FF320093FFF7E9F84FF000084FF0CF
+:109140000003C019A4F86A3548BFA4F86A0521E0F5
+:1091500094F8662512B111F0010F19D1B4F86835F1
+:10916000B4F96A558B4253B238BFED1B013391FB02
+:10917000F3F3DBB203F5107330464FF0FF32039385
+:10918000FFF7C4F8401B059069463046FFF744FBE3
+:1091900008F10108B8F1800F5FFA88F1D8D194F98D
+:1091A00066357BB10123019305AB0093402404F5A0
+:1091B0001073304669460393FFF72EFB631CDCB245
+:1091C000802CF4D106B0BDE8F081C04630B518233C
+:1091D00087B0D0F8A8400393083305936033029317
+:1091E00000230546049301A904F19C030193FFF7B2
+:1091F00013FB2846B4F89C2240F27161F9F7A6FAF5
+:109200002846B4F89E2240F27361F9F79FFA284687
+:10921000B4F8A22240F27461F9F798FA2846B4F83B
+:10922000A02240F27561F9F791FA2846B4F8A42219
+:1092300040F27961F9F78AFA2846B4F8A62240F29A
+:109240007661F9F783FA2846B4F8A82240F2DA6189
+:10925000F9F77CFA2846B4F8AA2240F22551F9F72A
+:1092600075FA2846B4F8AE224FF48F61F9F76EFA1A
+:109270002846B4F8B0224FF49A61F9F767FAB4F8C7
+:10928000B2324FF40042DB032846134040F224512F
+:10929000F9F782FA94F8AC32284684F86735B4F8C6
+:1092A000B432A4F8683594F8B63284F8073494F8E8
+:1092B000B73284F80834FFF713FF07B030BDC0465B
+:1092C0002DE9F04F8DB0039202930BAB0646D0F818
+:1092D000A8708B4600930DF12F010DF12D030DF1B8
+:1092E0002E02FCF75BF930460DF12A010AAAFFF7BE
+:1092F00065FA3046FFF702F90723069319330893FE
+:1093000009AB04934FF000080123059381464FF405
+:1093100050735D46C246079338E097F8662522B140
+:109320000AEB0B0313F0010F2DD153B2013304AC40
+:10933000B5FBF3F303F5A073304621460793FEF720
+:1093400069FF099BBDF828201B0D92051B05920D96
+:109350001A43BDF82A3030469B059B0D42EA83280C
+:109360002146CDF82480FFF757FACDF8249097F9DD
+:10937000663530460133B5FBF3F303F5E073214660
+:109380000793FFF749FA01350AF1010A039A95425A
+:10939000C3D997F96635C3B17F2A16D14FF4C0758A
+:1093A00004AC304621460795CDF82480FFF734FA07
+:1093B00005F18003304621460135CDF8249007930E
+:1093C000FFF72AFAB5F5E07FEAD1029A07EB4203EC
+:1093D000BDF82A20A3F86C20BDF82820A3F87890C7
+:1093E000A3F872209DF82F3087F87E309DF82E303C
+:1093F00087F87F309DF82D3087F880309DF82C302D
+:1094000087F881300DB0BDE8F08FC0462DE9F04FF0
+:109410008DB00393C369D0F8A86005460C469868E0
+:109420004FF480619346EDF353F40746002800F0B3
+:109430008A80C5F8FC4F28460121FDF769FA96F8A5
+:109440002C3043B1284641490622F9F7B9F928469C
+:109450000021FEF7D9FDA4B101203D4984EAE47260
+:10946000A2EBE47200FB01F1B1FBF2F39EB202FB4E
+:1094700006F2431C8A4298B2EFD1B6F5807F01D93B
+:109480005AE00226242304FB03F349F6404293FBEF
+:10949000F2F300241B04642293FBF2FAA146A046D7
+:1094A0002EE048460AA9F9F72FFD0B9B03FB0BF3AF
+:1094B000002B04DBDB130133C3F3490206E05B42FC
+:1094C000DB1301335B105B429A05920D0A9B03FB91
+:1094D0000BF3002B04DBDB130133C3F3490306E07A
+:1094E0005B42DB1301335B105B429B059B0D43EA40
+:1094F000822347F82830631CD1449CB208F101084C
+:10950000B442CED1062228461249F9F759F915235B
+:10951000079300240B33284605A90993059706965F
+:109520000894FFF779F9039B2846009331464FF6DC
+:10953000FF722346FDF772F8EB69394698684FF4DD
+:109540008062EDF3D5F30DB0BDE8F08FCE070200D9
+:10955000005A6202C207020030B587B005AB009323
+:1095600001230193173302930833002204934FF42D
+:109570000023054603920593144628466946FFF7E3
+:109580004BF9039B01330393631CDCB2802CF4D1B1
+:1095900007B030BDF0B5D0F8A83087B093F89A2561
+:1095A0000746002A2DD1324B324D1E68144605E085
+:1095B00029463846FFF730F901341435B442F7D163
+:1095C0002D4A002453683846019310230293082340
+:1095D00004931368694600930394FFF71DF9FB6930
+:1095E0001B6B082B0DD1254A3846536869460193F9
+:1095F000122302930E330493136803940093FFF72E
+:109600000BF9102304930DF1160300934FF072032E
+:1096100008260125ADF81630384600236946039325
+:1096200002960195FFF7F8F84FF082033846694635
+:10963000ADF816300395FFF7EFF84FF006036946D3
+:109640003846ADF816300396FFF7E6F83846FFF7D0
+:10965000DBFC3846FFF728FB3846FFF73BFB384674
+:10966000FFF7B6FB38466C46FFF776FF07B0F0BD54
+:10967000F8100200D4150200181D0200F41C0200AC
+:1096800070B5B0F8DA30054603F47043B3F5005F07
+:10969000D0F8A8200CD192F9F133B3F1FF3F37D1C4
+:1096A000B2F9F833B3F1FF3F32D1B2F92C352CE0E7
+:1096B000B3F5805F35D192F95B35B3F1FF3F27D128
+:1096C00092F9F333B3F1FF3F22D192F95C35B3F154
+:1096D000FF3F1DD1B2F90034B3F1FF3F18D1B2F909
+:1096E0003035B3F1FF3F13D1B2F90234B3F1FF3F8C
+:1096F0000ED1B2F93435B3F1FF3F09D1B2F90434D8
+:10970000B3F1FF3F04D1B2F93835B3F1FF3F08D0D0
+:10971000012482F86645102228464FF49A611346C8
+:1097200007E0002482F8664528464FF49A6110222B
+:109730002346F9F731F84FF48F6103222346284678
+:10974000F9F72AF82846FFF725FF2846FBF7E2FF3E
+:109750002846FCF7E1FE2846FFF768F870BDC046D2
+:1097600010B5002388B00593103307930DF106035D
+:10977000039301230446ADF80610049303A9543360
+:109780000693FFF749F82046FBF7FEF810B1204694
+:10979000FEF7C8FE08B010BD2DE9F041D0F8A87062
+:1097A0000646002419E0B6F8DA3003F47043B3F546
+:1097B000805F07D1A218137923B1890492783046CB
+:1097C000890C07E06B4BE21853792BB18904D278EE
+:1097D0003046890CF8F73CFF0634664A4FF6FF73B3
+:1097E000A15A9942DFD1304673210022F8F730FFA9
+:1097F000304632216A22F8F72BFF192230463321F6
+:10980000F8F726FF97F8EC231AB130463321F8F722
+:109810001FFFC2216F223046F8F71AFF9021102255
+:109820003046F8F715FF102100223046F8F710FFF8
+:109830009B2107223046F8F70BFF1D2102223046FC
+:10984000F8F706FF1E2106223046F8F701FF3046E2
+:1098500040F2EA4144F28862F8F778FFB6F8DA306D
+:1098600003F47043B3F5005F0DD197F8E933B6F810
+:10987000DE1FA02B14BF022204220BB2B3F1FF3F64
+:109880000DD0CAB20BE0B3F5805F07D1B6F8E02F78
+:1098900013B2B3F1FF3F01D0D2B200E0022253B2C3
+:1098A0001FFA83F807224346304640F2EB41F8F7AF
+:1098B00073FFB6F8DA3003F47043B3F5005F05D0F8
+:1098C000B3F5805F04D197F83B350BB9002400E075
+:1098D00001242346254624010F22A4B2304640F23B
+:1098E000F241F8F759FFF0222346304640F2F241A8
+:1098F000F8F752FF0F22304640F2F1412B46F8F7BD
+:109900004BFFF0222346304640F2F141F8F744FF86
+:109910004FEA0823304640F2F2414FF4E06203F48C
+:109920007F43F8F739FFB6F8DA30304603F4704376
+:10993000B3F5805F0CBF03F53B7341F2EA23F45AA1
+:1099400040F2EB41630203F47E434FF40072F8F7F8
+:1099500023FFB6F8DA3003F47043B3F5805F0BD021
+:1099600041F23433F25A13B2B3F1FF3F04D0930201
+:1099700003E0C046EC260200A3024FF4806203F429
+:109980007C43304640F2EB41F8F706FF40F2EB41F2
+:109990003046D6F8A840F8F7CDFEC0F3802084F812
+:1099A000470540F2EB413046D6F8A840F8F7C2FE32
+:1099B000C0F3402084F84805D6F8A820304692F835
+:1099C000481592F847355B1A18BF012382F84635CF
+:1099D000FAF7ECFF830203F47C43304640F646116D
+:1099E0004FF48062F8F7D8FE304643490622F8F774
+:1099F000E7FE41F21D23F35C2BB10F2230467721A5
+:109A00001346F8F76BFE30460021FFF7A9FE97F8E2
+:109A10009A352BB93046FEF73FF83046FDF71EFF6A
+:109A2000F3697A21186936F065DE97F8EC23400077
+:109A300084B22AB124B1F369A11C186936F078DE2A
+:109A400097F8ED232AB124B1F3692146186936F05D
+:109A50006FDE97F8BB34DBB104221346304640F288
+:109A60001D11F8F73BFE30469F213F2297F8BC348A
+:109A7000F8F734FE30469E213F2297F8BD34F8F7C0
+:109A80002DFE304677210F2297F8BE34F8F726FED8
+:109A9000B6F8DA3003F47043B3F5805F29D197F953
+:109AA000583533B3B42124223046F8F7D1FDB7211D
+:109AB00024223046F8F7CCFD0322B8213046F8F7CF
+:109AC000C7FD97F95825022A07D13046B821F8F783
+:109AD000BFFD3046B521012209E0032A09D13046F5
+:109AE000B821013AF8F7B4FD3046B5210022F8F765
+:109AF000AFFDBDE8F081C046C604020010B5FFF717
+:109B00004BFE10BD70B50026D0F8A850C0F8FC6F11
+:109B100095F82C3004463BB12A490622F8F750FE4E
+:109B200020460121FEF770FA204640F24461F8F722
+:109B300001FE10F0010309D020463146FCF740FD3C
+:109B40000222204640F23F61134607E010F0020F68
+:109B500006D0204640F253414FF40042F8F71CFE75
+:109B6000204619490922F8F72BFE20460021FCF770
+:109B7000CFFE2046FAF71AFF30B12046FEF7BEFCB2
+:109B800001462046FFF7ECFD95F8473520469B023D
+:109B900003F47C4340F2EB414FF48062F8F7FCFDA4
+:109BA000B5F84E356BB1204640F64811FF22F8F764
+:109BB000F3FD204640F64911FF22B5F85035F8F77D
+:109BC000EBFD70BDE60B0200F20B020070B50C4617
+:109BD00088B00546F9F720F944B92846FFF792FF07
+:109BE00028462146FCF794FE204622E028462146DE
+:109BF0000122FAF789F8064608B1012019E0284643
+:109C00000121FCF785FE0C4B40240393152305939B
+:109C10002846102303A9079304940696FEF7FCFD3B
+:109C2000284621464FF6FF7233460096FCF7F6FCB5
+:109C3000304608B070BDC0469A21020070B50023BE
+:109C400086B002931033049305AB009302230446BD
+:109C5000ADF8141001930D464E3369461646ADF823
+:109C600016200393FEF7D8FD2046FAF79FFE78B33F
+:109C7000204640F6461140F2FF322B46F8F78CFDA5
+:109C8000204640F6471140F2FF323346F8F784FD94
+:109C900020464FF4156140F2FF322B46F8F77CFD69
+:109CA000204640F6511140F2FF323346F8F774FD7A
+:109CB000204640F6541140F2FF322B46F8F76CFD77
+:109CC000204640F6551140F2FF323346F8F764FD66
+:109CD00006B070BD2DE9F04F8DB004910392D0F81D
+:109CE000A860074606EB4303B3F872B0B3F86C10F4
+:109CF000B3F878905A460591FFF7A0FF38464946D9
+:109D0000FFF72EFD0723089319330A934FF000083D
+:109D10000123049D0793C2460BAB069337E096F8E8
+:109D200066252AB104990AEB010313F0010F2BD128
+:109D300053B2013306ACB5FBF3F303F5A073384619
+:109D400021460993FEF766FA0B9B05994FEA8B5261
+:109D50001B0D1B05920D1A438B059B0D42EA8328B0
+:109D600038462146CDF82C80FEF756FD96F966352B
+:109D700038460133B5FBF3F303F5E073214609934D
+:109D8000CDF82C90FEF748FD01350AF1010A039A3F
+:109D90009542C4D996F96635C3B17F2A16D14FF4DE
+:109DA000C07506AC384621460995CDF82C80FEF7E3
+:109DB00033FD05F18003384621460135CDF82C905E
+:109DC0000993FEF729FDB5F5E07FEAD196F8810009
+:109DD00096F87E1096F87F2096F8803000903846EE
+:109DE000FBF7DEFC0DB0BDE8F08FC04670B500217A
+:109DF0000446D0F8A8500B467F22FFF76BFF2046A1
+:109E0000FFF7E4F92046B5F8B812B5F8BA22FBF727
+:109E1000C7F8204640F2D16104220023F8F7BCFCC9
+:109E200070BDC04670B50446D0F8A8300D4699B153
+:109E300093F8BC3233B3FFF7D9FF20460422002346
+:109E400040F2D161F8F7A8FC8022204640F276610A
+:109E50001346F8F7A1FC15E00422134640F2D16145
+:109E6000F8F79AFC8022204640F276612B46F8F7FC
+:109E700093FC20462946FFF773FC204629462A46D4
+:109E8000FFF7DCFE70BDC04630B500238BB00893F1
+:109E9000079306930733054603930A4609B90491CD
+:109EA00002E04FF4307304932023059309AB019330
+:109EB000012302933AB9284608A907AA06ABF9F785
+:109EC0000FF9002409E0B5F902310793B5F904311F
+:109ED0000693B5F906310893F3E70899069B2046E7
+:109EE000079AFAF757FC01A909902846FEF794FC57
+:109EF000049B01340133802C0493EED10BB030BDB0
+:109F0000F0B5284B8BB005AC05460F460FCB84E867
+:109F10000F0041F22403EB5CD5F8A8601BB196F862
+:109F2000E034002B3BD028461F490822F8F748FCB4
+:109F3000072302931933049304230193009403F538
+:109F40004F7301240393284686F86A406946FEF75A
+:109F500063FC0023099309AB019400934FF45174FF
+:109F6000284669460394FEF757FC013440F25E33FD
+:109F70009C42F5D128460D491222F8F721FC7B00BE
+:109F80009BB2284640F2A94140F2FF12F8F704FCC8
+:109F9000284640F2A36110220023F8F7FDFB0BB026
+:109FA000F0BDC04668050200620C020054090200C0
+:109FB00030B5D0F8A8509BB004460022A31893F9FE
+:109FC000103501A95B4241F822300132142AF5D143
+:109FD00095F86A3063B907331793193319931591BC
+:109FE00003F54873204615A916921893FEF714FC42
+:109FF000D4F8A81094F82936D1F844242046934286
+:10A00000A8BF1346D1F8482440F2A7419342B8BFF5
+:10A0100013469BB2FF22F8F7BFFB95F8E833F3B184
+:10A02000B5F8E62394F8293620469B1A1B024FF414
+:10A030007F42134040F2D141F8F7AEFB94F8292655
+:10A0400095F825352046C3EB420395F8E62340F208
+:10A05000D1419B1A5BB2FF229BB2F8F79DFB2046D1
+:10A06000FAF7A6FB1BB030BD70B5C6B001ACD0F896
+:10A07000A8500646002120464FF48072E7F3E0F72F
+:10A080000723439319334593419495F86A3043B9B4
+:10A090001E33429330464FF4507341A94493FEF768
+:10A0A000BBFB402342933046DB1841A94493FEF7A3
+:10A0B000B3FB46B070BDC0462DE9F04106460C46E4
+:10A0C000FAF72CFF214605463046FAF74FFC2946A1
+:10A0D00004463046FAF74AFC4022B4F5404F0CBF24
+:10A0E00013460023054640F2DA613046D6F8A870E0
+:10A0F000F8F752FB1022B4F5404F14BF134600236B
+:10A10000304640F2A361F8F747FB0122B4F5404F17
+:10A1100014BF00230123304640F26E41F8F73CFBA8
+:10A12000A54200F09580B5F5404F02D13046FFF7CB
+:10A130009BFFB4F5404F3CD13046FFF739FFD6F8CE
+:10A14000A8203B8E92F966255B00013293FBF2F367
+:10A15000304640F2A44140F2FF129BB2F8F71CFBDC
+:10A160007B8E30461B0240F2A5414FF4E06203F4BF
+:10A170007F43F8F711FB04223046002340F21F1101
+:10A18000F8F7ACFAF369E021186936F0B3DA002188
+:10A19000F8853046FAF7A2FF4FF0FF3387F83430E6
+:10A1A000304640F2A9414FF400420133F8F7F4FA87
+:10A1B00003E030460121FAF791FF304640F2A44116
+:10A1C0004FF460422346F8F7E7FAB4F5404F0FD159
+:10A1D0003046FAF7EBFB40F2A44100280CBF4FF4E5
+:10A1E000005300234FF400523046F8F7D5FA15E03B
+:10A1F0004EF201039C4211D13046FAF717FB01469B
+:10A200003046FFF77DFE304640F2A941F8F792FA5A
+:10A210000223C0B290FBF3F087F8C10297F96735CB
+:10A22000012B0DDD40F2A4413046F8F783FAC0F36C
+:10A23000803340F2255130464FF40042DB0305E005
+:10A24000304640F225514FF400420023F8F7A4FABB
+:10A25000BDE8F08170B50023D0F8A82080F82B3637
+:10A2600092F8E03405468BB190F92A16D2F84834BA
+:10A27000994203DBD2F81035994207DA4EF2010118
+:10A28000FFF71AFF012385F82B3612E041F2240371
+:10A29000EB5C73B12846FAF741FE002104462846DC
+:10A2A000FFF70AFF2846FFF783FE28462146FFF7FF
+:10A2B00003FF70BD30B5072389B0D0F8A8400393E1
+:10A2C0001933059306AB0193012302930546013B25
+:10A2D000049308E0284601A9FEF79EFA049B013387
+:10A2E0000493069B01330693069B7F2BF2D94FF410
+:10A2F00030730493A3F5307308E0284601A9FEF7F4
+:10A300008BFA049B01330493069B01330693069B4F
+:10A310007F2BF2D9092228465B49F8F751FA01212F
+:10A320002846FBF7A3FB242228465849F8F748FAA9
+:10A330002846FAF75FFDC0F34F00E62801DDFF2352
+:10A3400005E02846FAF756FD4008193083B2FF228F
+:10A3500040F2A5412846F8F71FFA2846FFF784FE89
+:10A36000B4F8E623B4F8E433284603EB42039B0138
+:10A370009BB24FF49A6147F6C072F8F70DFA0922C2
+:10A3800028464349F8F71CFAB5F8DA30282103F4D7
+:10A3900070431E22B3F5005F14BF18231C23284608
+:10A3A000F8F79CF901223A2113462846F8F796F966
+:10A3B0000822134628464FF48D71F8F78FF92521AE
+:10A3C0000C222846F8F744F9B5F8DA3003F4704364
+:10A3D000B3F5005F04D1022228463A21134603E078
+:10A3E00028463A2102220023F8F778F9082213467A
+:10A3F00028460521F8F772F9284606222549F8F77C
+:10A40000DFF947F20802284640F2D7414FF40053E3
+:10A41000F8F7C2F92846FAF7EDFC102305930DF181
+:10A420001E03019301230824ADF81E000293284661
+:10A43000053301A904930394FEF7EEF928460F2291
+:10A440001549F8F7BDF928463521FF220023F8F712
+:10A4500045F92846362103220023F8F73FF928461C
+:10A46000224623464FF48D71F8F738F94FF4806295
+:10A47000284640F2A4411346F8F78EF92846FBF728
+:10A480008DFA09B030BDC046C60D02009A05020023
+:10A49000A4070200F40D0200000E02007FB50902BD
+:10A4A00006AB23F8021D009301230193013B0293A5
+:10A4B00057330393694610230493FEF7ADF907B0B1
+:10A4C00000BDC0462DE9F041D0F8A8308AB083F82D
+:10A4D000341083F8C11293F9663506460F466BB106
+:10A4E00011F0010304D04FF48F610C22082302E025
+:10A4F0004FF48F610C22F8F74FF97F08072303937D
+:10A5000001AC07F5A07320254FF0010804933046F5
+:10A5100009AB214601930595CDF80880FDF77AFE39
+:10A5200007F1C003049330460DEB05032146019368
+:10A530000595FDF76FFE089B304603F0FF02ADF86E
+:10A540001820C3F30722C3F30743ADF81C30099B5F
+:10A5500006A9C3F30273ADF81A20ADF81E30FAF75E
+:10A56000F5FD09993046C1F30751FFF797FF3046D3
+:10A570004146FAF7B3FD0AB0BDE8F0812DE9F04F8E
+:10A5800091B0BDF8783002AC0193BDF87C3007463D
+:10A590000093534B9DF880601D460FCD0FC495E886
+:10A5A0000F009DF8748084E80F0038464D4904225E
+:10A5B000BDF87090BDF884A0BDF888B0F8F700F938
+:10A5C000384640F2A36102227300F8F7E5F8B8F1CB
+:10A5D000000F18D010AB4FF4002243F8042D0A935B
+:10A5E00001230B9317330C9308330E9300230D9321
+:10A5F0001C4638460AA9FEF70FF90D9B01340133BA
+:10A60000402C0D93F5D1032409FB04F43846FAF7E6
+:10A61000EBFE0134384640F2A1615246F8F796F855
+:10A62000A4B2384640F2A2615A46F8F78FF82246A3
+:10A63000384640F27E61F8F789F838462A49042204
+:10A64000F8F7BEF80134142304FB03F4013CA2B272
+:10A6500038464FF4C861F8F779F80022384640F2DE
+:10A660007761F8F773F808230B930D330C930B33D2
+:10A6700000240E93384602AB0AA90A930D94FEF704
+:10A68000CBF8384640F27B61019AF8F75FF838461C
+:10A6900040F27C61009AF8F759F82246384640F2B9
+:10A6A0007D61F8F753F821463846FFF7F7FE384644
+:10A6B0000E490422F8F784F80D4C03E00A20ECF36D
+:10A6C0004BF00A3C384640F27661F8F733F810F068
+:10A6D000010F01D0092CF1D111B0BDE8F08FC046B7
+:10A6E000B80C0200780B02008A0802001E0E02005D
+:10A6F00049420F002DE9F043D0F8A8908BB00646F0
+:10A700008846052503270F2DA8BF0F250024ABB2CF
+:10A71000019330460121224623460094029403947B
+:10A720000494FAF75BFDDB2302934FF4AF630493C9
+:10A730004FF482430593A3F58143012207933046EA
+:10A740002146234600940194039206940894FFF74F
+:10A7500015FFB8F1000F1DD140F2BA613046F7F78E
+:10A76000E9FF40F2BB6104B23046F7F7E3FFA40112
+:10A77000A4B244F3891404FB04F440F3090000FB81
+:10A780000043B3F5005F01DAED1B03E0B3F5804F42
+:10A7900004DBED1917B17B1EDFB2B4E7092D01DD33
+:10A7A000092501E025EAE5752846C9F838500BB0BF
+:10A7B000BDE8F0832DE9F043D0F8A8608DB096F99C
+:10A7C000663507468846CCB2D3B1634B01EA030332
+:10A7D000002B05DA013B6FEAC3736FEAD3730133D1
+:10A7E000012B04D14FF48F610C22073303E04FF4A7
+:10A7F0008F610C220023F7F7CFFF022398FBF3F8B9
+:10A80000072386F8344086F8C14201AD039308F56A
+:10A81000A07320244FF00109049338460BAB29465E
+:10A8200001930594CDF80890FDF7F4FC08F1C003FE
+:10A83000049338460AAB294601930594FDF7EAFCD8
+:10A840000A9B384603F0FF02ADF81820C3F3072235
+:10A85000C3F30743ADF81C300B9B06A9C3F3027387
+:10A86000ADF81E30ADF81A20FAF770FC9DF82B10E9
+:10A87000384601F07F01FAF71DFC0B993846C1F309
+:10A880000751FFF70BFE38464946FAF727FC0B9AAB
+:10A890003846C2F389219205920DFFF7CFF908F5EA
+:10A8A000E0730493384609AB29460193FDF7B2FCE7
+:10A8B0003846BDF82410FEF753FF08F510730493D3
+:10A8C00038460DEB040329460193FDF7A3FC089BD2
+:10A8D0003846DB009BB240F2A66141F6FF72F7F703
+:10A8E0005BFF96F967354B4532DD40F2255138461E
+:10A8F000F7F720FF4FF48072C3B29845D4BF00240D
+:10A90000012438469845CCBF1346002340F2255118
+:10A91000F7F742FF6302384640F225514FF40072C8
+:10A9200003F47E43F7F738FFA302384640F225517F
+:10A930004FF4806203F47C43E402F7F72DFF3846BE
+:10A9400040F225514FF4006204F47843F7F724FFF6
+:10A950000DB0BDE8F083C0460100008070B504462C
+:10A960000D460021FFF7A8FB20462946FFF722FFEE
+:10A9700070BDC0462DE9F04F89B0054600920191A7
+:10A98000FAF7CCFA40F23B4103902846F7F7D2FEA3
+:10A9900004A902902846FAF70FFA00244FF47A70BF
+:10A9A0000134EBF3D9F6022CF8D141F2F023EA5846
+:10A9B00092F820301F1E18BF012792F821300BB1EA
+:10A9C0007B1C9FB292F822300BB17B1C9FB292F895
+:10A9D00023300BB17B1C9FB24FF00009C8464FF0EB
+:10A9E000140ABCE0D5F8B030D3F8203183F001036D
+:10A9F00013F0010403D1EB69186935F0CBDE28466A
+:10AA0000F8F756FB41F2F023EB58284603EB4803D6
+:10AA1000998CFFF7A3FF28465146FFF73FFD1CB96D
+:10AA2000EB69186935F0A2DE4FF40042284640F287
+:10AA3000A4411346F7F7B0FE002441F288300134F8
+:10AA4000EBF38AF6032CF8D1284640F2A641F7F73B
+:10AA500071FEC005C00DFF2886BFA0F580731FFAE8
+:10AA600083FB00F5807B00263446284640F23E6199
+:10AA7000F7F760FE631CC005C00D9CB23618102CA1
+:10AA8000F3D1C6F30F13FF2B8CBFA3F5807303F52F
+:10AA90008073504600210DF11E029EB20DF11A0383
+:10AAA000EDF388F441F2F023EB580021434493F88E
+:10AAB000200007AA06ABEDF37DF4BDF91A30BDF90D
+:10AAC00018108B4209DABDF91C00C91AEDF324F500
+:10AAD000BDF81A40ADF81C0009E0BDF91E00C1EB3D
+:10AAE0000301EDF319F5BDF81840ADF81E00BDF9EE
+:10AAF0001C10BDF91E00EDF319F523B2032B81B232
+:10AB000001DD231F01E0C4F1040398B200B2431E2B
+:10AB100001229A4009B2052301FB032353FA00F0F6
+:10AB200000F10C03182B16D841F2F023EB58019AD0
+:10AB300003EB88031B69C31802F809304FEA9B0333
+:10AB4000C3F17F03009A03EB960302F8093009F181
+:10AB500001031FFA83F908F101031FFA83F8B845CE
+:10AB6000FFF440AF0AF101035FFA83FABAF1640F10
+:10AB700002D84FF00008F2E7029B2846C3F3801189
+:10AB8000FAF7ACFA284604A9FAF7E0FA284603993E
+:10AB9000FFF792FA484609B0BDE8F08F2DE9F04F73
+:10ABA0001E46C369A9B0D0F8A88004460F4698682D
+:10ABB0004FF483711546ECF38BF00790002800F0FA
+:10ABC000EF81022E0FD016E00E4694F8DA3011F81D
+:10ABD0000629013D9A420BD17188B2882046FAF7C6
+:10ABE000DFF90126CCE1062305FB03F3063BF91848
+:10ABF000002DE9D1C3E1012E40F0C1812046FAF7D2
+:10AC00008DF9002108902046FFF756FA0025934B56
+:10AC10002046E95AF7F704FD1AABE8520235182D21
+:10AC2000F5D140F231612046F7F784FD15220B90F3
+:10AC300040F231612046F7F79FFD40F24C4120463B
+:10AC4000F7F778FD40F24D410C902046F7F772FD82
+:10AC50004FF496610D902046F7F76CFD40F2B1413C
+:10AC60000E902046F7F766FD40F2F9410F9020461E
+:10AC7000F7F760FD40F2FA4110902046F7F75AFDD1
+:10AC800040F6381111902046F7F754FD40F639117F
+:10AC900012902046F7F74EFD40F23B4114902046BB
+:10ACA000F7F748FD40F23C4115902046F7F742FD8A
+:10ACB00040F2DA6116902046F7F73CFD40F2DB6186
+:10ACC00018902046F7F736FD40F2B741199020461C
+:10ACD000F7F730FD40F23B4113902046F7F72AFD8D
+:10ACE000C0F380100A9008B9099007E0204626A911
+:10ACF000FAF762F898F8C182CDF82480204632999C
+:10AD0000FFF72CFE062220465549F7F759FDB4F807
+:10AD1000DA3003F47043B3F5005F04D12046982184
+:10AD20000322F7F795FC20464E491922F7F748FD14
+:10AD300020464D491822F7F743FDB4F8DA304FF0BA
+:10AD4000030B03F47043B3F5005F14BF0423002327
+:10AD5000179322E11FFA88F300931FFA89F3002664
+:10AD600001931FFA8BF3324602932046179B31461C
+:10AD700003960496FAF732FA20460121FAF742F9CF
+:10AD80003346204639493C22FEF740FB20464FF42B
+:10AD900089713246F7F75CFC20AB00934FF4FA7AE6
+:10ADA00020464FF4806120223346CDF804A0FAF704
+:10ADB000F7FF054620B92E48F6F776FC2F4636E019
+:10ADC0003346204629497822FEF720FB20464FF4DF
+:10ADD00089713246F7F73CFC23AB009320464FF4D1
+:10ADE000806120223346CDF804A0FAF7D9FF18B9C4
+:10ADF0002048F6F759FC1AE0219A24982299B0EBE2
+:10AE0000420F0ED993009B1898420AD2259AB2EBB2
+:10AE1000410F06D98B005B189A422CBF00270127EF
+:10AE200000E00027B8F1010801D3002F92D0B9F15A
+:10AE3000010902D3002F00F0AC80BBF1010B02D35B
+:10AE4000002F00F0AA80204640F2D16104220023A6
+:10AE5000F7F7A2FC87B93E4614E0C046020502009F
+:10AE60001A05020026050200FA05020080841E0071
+:10AE7000EC0602000607020020464FF48061FDF751
+:10AE80002BF806462046FEF73DFE204640F2316193
+:10AE90000B9AF7F75BFC204640F24C410C9AF7F70F
+:10AEA00055FC204640F24D410D9AF7F74FFC2046E5
+:10AEB0004FF496610E9AF7F749FC204640F2B141F3
+:10AEC0000F9AF7F743FC204640F2F941109AF7F742
+:10AED0003DFC204640F2FA41119AF7F737FC204634
+:10AEE00040F63811129AF7F731FC204640F6391136
+:10AEF000149AF7F72BFC204640F23B41159AF7F7DE
+:10AF000025FC204640F23C41169AF7F71FFC2046EC
+:10AF100040F2DA61189AF7F719FC204640F2DB613B
+:10AF2000199AF7F713FC204640F2B741139AF7F746
+:10AF30000DFC204640F24C4104220023F7F72CFC84
+:10AF40000025194B2046E95A1AABEA5A0235F7F7A1
+:10AF50007FFB182DF5D10A9B23B120460999FFF7F5
+:10AF6000FDFC03E020460A99FAF7B8F82046089954
+:10AF7000FFF7A2F820460021FAF744F800E0002687
+:10AF8000E369079998684FF48372EBF3B1F63046A2
+:10AF900006E000274FF00608DCE64FF00409F8E76A
+:10AFA00029B0BDE8F08FC046020502002DE9F04F40
+:10AFB000B3B00F939DF8F8409DF8F4300D940E93C4
+:10AFC0009DF800419DF8FC300B940C93012405463C
+:10AFD0001646D0F8A89088469DF8F0B0BDF80471E8
+:10AFE0008DF8C7408DF8C640FDF702FC40F2D7410E
+:10AFF00012902846F7F79EFB40F2D7411090284662
+:10B00000F7F798FB3449119006222846F7F7D8FB4A
+:10B01000284632490F22F7F7D3FB284621461AAAC1
+:10B02000FDF786FB284621460022FDF7F5FABBF125
+:10B03000000F02D00023199318E028462146FBF7A1
+:10B0400067FCD5F8B030D3F8203183F0010313F05A
+:10B05000010319930AD1EB69B821186942F2107201
+:10B0600035F066DBEB69186935F094DB2846012181
+:10B07000F9F7C8FF28460121FBF7A2FA284601216B
+:10B08000FAF72EF940F2EA412846F7F753FB40F26F
+:10B09000EB4117902846F7F74DFB40F2EB41189033
+:10B0A0002846F7F747FB00F0070340F2EB4128463C
+:10B0B0003822DB00F7F770FB28462DA999F8C1A2CA
+:10B0C000F9F77AFE86B1337A53B12846717AFFF7E1
+:10B0D00045FC96F809A007E0F6090200A60B02005D
+:10B0E00028463146FAF732F840F29C412846F7F7F5
+:10B0F00021FB40F2316113902846F7F71BFB40F229
+:10B10000D66115902846F7F715FB40F2DA611490E6
+:10B110002846F7F70FFB002116902846FAF728FA81
+:10B12000284688490722F7F74BFB2FAB23930123CF
+:10B1300024930633259376B199F96625737A013203
+:10B1400093FBF2F303F5107326932846202323A9DB
+:10B150002793FDF75FF82F9A2846D2002F9240F2EE
+:10B16000716192B2F7F7F2FA284677490C22F7F7A5
+:10B1700027FB0024754B284633F81410F7F750FAD4
+:10B180000DF1A203E0540134122CF3D1072228461A
+:10B190004FF48B71F7F75CFAB5F8DA3003F47043CB
+:10B1A000B3F5005F05D1284640F22D110122F7F7D3
+:10B1B0004FFA072228464FF49671F7F749FAB5F887
+:10B1C000DA3003F47043B3F5005F14D128466A21E6
+:10B1D000C222F7F73DFA284698210C22F7F738FAF1
+:10B1E000284640F22F110322F7F732FA284697211A
+:10B1F000F922F7F72DFA0B2107222846F7F728FA4C
+:10B200001022284640F21311F7F722FA1D210122DD
+:10B210002846F7F71DFA012228464FF48A71F7F7FE
+:10B2200017FAB5F8DA3003F47043B3F5005F04D1D0
+:10B2300028462E211022F7F70BFA082228464FF451
+:10B240009571F7F705FA092102222846F7F700FA67
+:10B2500004221346284640F21F11F7F73FFAFF2158
+:10B26000102200232846F7F739FA0721012200238C
+:10B270002846F7F733FA0521082200232846F7F776
+:10B280002DFA4FF400421346284640F2DA61F7F7F0
+:10B2900083FA41460F9A53462846FFF72BFA0024BB
+:10B2A00080B2012101902246284623460094029450
+:10B2B00003940494F9F792FF0E9BA74208BF4FF442
+:10B2C000824700930D9B284601930C9B41460293B5
+:10B2D0000B9B224603934FF4AF630493A3F59F6344
+:10B2E00007935B46059706940894FFF747F90DF11D
+:10B2F000C60228460DF1C701F9F798FC9DF8C62053
+:10B300003F2A53D89DF9C730A3424FDB3F2B4DDC7A
+:10B3100052B29A424ADCB8F1000F27D123AC18236D
+:10B3200021462593284630AB26922393FCF772FFE3
+:10B330009DF9C73021462846309E2693FCF76AFFC8
+:10B3400044460EE0020A0200200D0200260E020012
+:10B3500030AB284623A9269430962393FDF75CFA58
+:10B3600001349DF9C62063B29A42F1DC182323AC64
+:10B37000259326332693284630AB21462393FCF7AA
+:10B3800049FF3F23284621462693FDF745FA01232E
+:10B39000284621462693FCF73DFF002328462146F8
+:10B3A0002693FDF739FA2846FDF72EF8284640F295
+:10B3B000EA41179AF7F7CAF9284640F2EB41189A82
+:10B3C000F7F7C4F92846D72102220023F7F786F9B8
+:10B3D000082213462846D721F7F780F9002328468C
+:10B3E0004FF494710822F7F779F928464FF48B71DE
+:10B3F0000022F7F72DF9284640F29C41139AF7F7FF
+:10B40000A5F9284640F23161159AF7F79FF92846C9
+:10B4100040F2D661149AF7F799F9169C284644F041
+:10B42000010292B240F2DA61F7F790F92846012161
+:10B43000FAF79EF8109C082204EA0203284640F21C
+:10B44000D741F7F7A9F9119C4FF4E04204EA02034F
+:10B45000284640F2D741F7F79FF92846FAF73CFD16
+:10B460000024234B284633F814100DF1A203E25CAC
+:10B470000134F7F7EDF8122CF3D14FF400620023FA
+:10B48000284640F24C41F7F787F928460021FBF7A0
+:10B4900097F828460021F9F7B5FD284640F23B41D0
+:10B4A00001220023F7F778F900234FF400622846C1
+:10B4B00040F63811F7F770F928460021FBF728FA13
+:10B4C000284600211AAAFDF733F9284609490F2218
+:10B4D000F7F776F9199B1BB9EB69186935F046D96E
+:10B4E00028461299FEF7DAFF33B0BDE8F08FC04668
+:10B4F000260E0200C40A02002DE9F04FD0F8A83051
+:10B5000091B093F8F49318230C930FAB0A93202374
+:10B510000E93012317460B9301FB01FB3E330521DC
+:10B5200000228046B9F1FF0F08BF4FF001090D93CB
+:10B530000791099206230024039347F6FF733A46C6
+:10B540000125059340462346214600940194029428
+:10B550000495FFF72BFD40460AA9FCF75BFE0F9A06
+:10B5600042F30B3303FB03F342F30B0202FB023201
+:10B570007B7A5A45069303D307990894CEB206E026
+:10B58000B9F1000F4DD1079908954B42DEB273B265
+:10B5900006999DB26B189CB24FF0000A06990AEB0F
+:10B5A000010308999BB221B15A4506D99B1B7B72B6
+:10B5B0002DE0089B0BB95A4529D322B27F2A26DCFD
+:10B5C0000AEB0503002A1FFA83FA20DB06237C72AC
+:10B5D000039301230021049347F6FF733A46059332
+:10B5E00040460B46009101910291FFF7DFFC404677
+:10B5F0000AA9FCF70FFE0F9A42F30B3303FB03F388
+:10B6000042F30B0202FB023263199CB2C6E70799B0
+:10B61000099A41F346030132DBB2032A07930992E8
+:10B6200088D111B0BDE8F08F2DE9F04F8DB0DDF875
+:10B6300058A01F460123834616468AF808304FF06B
+:10B6400000094FF0640808EB09030021C3F34F051C
+:10B65000DB238AF8095001245246039358460B46CF
+:10B6600000910191029105910494FFF79FFC18232A
+:10B670000893273309930BAB06935846202306A95A
+:10B680000A930794FCF7C6FD0B9B43F30B3202FBB6
+:10B6900002F243F30B0303FB03231A464FEAE27360
+:10B6A000BB4202D803D1B24201D9A94600E0A84664
+:10B6B0000B484FF0FF31801941EB07018B4202D854
+:10B6C00006D1824204D99F4206D801D1964203D8BE
+:10B6D000C9EB0803012BB6DC28460DB0BDE8F08F9E
+:10B6E00030F8FFFFF7B50546D0F8A87090F8DA00FB
+:10B6F0000E46F7F735FA40F6B41398420446B5F80B
+:10B70000DA2001D11E480AE0D3B2012B02D14FF456
+:10B71000523004E00302A3F5C420A0F580600022AB
+:10B720004FF47A71F9F716F8A0FB0023284600962B
+:10B73000FFF77AFFA0F128039BB21D2B1BD9272806
+:10B7400002D84FF434300BE040F6B4139C4202D1DF
+:10B750004FF4703004E02302A3F5BE20A0F5007082
+:10B7600000224FF47A71F8F7F5FFA0FB002328467A
+:10B770000096FFF759FF031F87F8C232FEBDC0468F
+:10B78000008E03002DE9F04390F8DA30D0F8A8607D
+:10B790008BB086F8BC32D0F8B0300546D3F82031F3
+:10B7A00083F0010313F001090AD1C369B8211869B4
+:10B7B00042F2107234F0BCDFEB69186934F0EADF52
+:10B7C00040F2A5412846F6F7B5FF04462846F9F7AA
+:10B7D000A5FB002180462846FEF76EFC4FF4404151
+:10B7E0002846FEF769FC2846FEF73EFCD5F8A8205F
+:10B7F0002846D2F84434D2F84824402BA8BF40232E
+:10B800009342B8BF134640F2A741FF229BB2F6F71E
+:10B81000C3FF0023284640F2A5414FF4E062F6F74B
+:10B82000BBFF4FF47A7232212846FBF7ABF80121B7
+:10B83000284696F8C072FBF76BF82846F7F738FCF5
+:10B840004FF4E06204EA0203284640F2A541F6F70D
+:10B85000A3FF00212846FEF72FFC96F8C4420DF105
+:10B860001E0E012C35D171462846FFF73BFF2846B6
+:10B870002146FDF7D9FBD5F8A8202846D2F8443454
+:10B88000D2F848243E2BA8BF3E239342B8BF1346AC
+:10B8900040F2A741FF229BB2F6F77EFF0023284625
+:10B8A00040F2A5414FF4E062F6F776FF28463221D8
+:10B8B0004FF47A72FBF766F896F8C032DBB996F867
+:10B8C000C2322846043386F8C2322146FDF7ACFB6B
+:10B8D00011E000210122DB238DF82620039304923E
+:10B8E000284672460B468DF827700091019102910F
+:10B8F0000591FFF75BFB28464146FEF7DDFB284636
+:10B9000008490422F6F75CFFB9F1000F03D1EB6997
+:10B91000186934F02BDF28460021FAF7F9FF0BB045
+:10B92000BDE8F083800C02002DE9F04F044695B08D
+:10B93000D0F8A86040F2E7300F46EAF30DF7072190
+:10B940002046F6F76DFEC0B20390FF212046F6F7C1
+:10B9500067FEC0B2049040F21F112046F6F760FE69
+:10B96000C0B2059005212046F6F75AFE25215FFA60
+:10B9700080FB2046F6F754FE4FF489715FFA80FA97
+:10B980002046F6F74DFE00250190864B2046E95AE9
+:10B99000F6F7D0FE07ABE85202351C2DF5D1D4F8EE
+:10B9A000B030D3F8203183F0010313F00103029388
+:10B9B00003D1E369186934F0EDDE40F2A44120467A
+:10B9C000F6F72EFE002181462046FEF775FB7F210B
+:10B9D000204696F8C182FEF7C1FF012207211346D7
+:10B9E0002046F6F77BFE1022FF2113462046F6F78D
+:10B9F00075FE04221346204640F21F11F6F76EFE34
+:10BA0000362220466849F6F7DBFE2046F9F7F2F9C0
+:10BA1000C0F34F00E62801DDFF2305E02046F9F7DB
+:10BA2000E9F94008193083B2FF22204640F2A541CF
+:10BA3000F6F7B2FE25210C222046F6F709FE082271
+:10BA4000134605212046F6F749FE092257492046AC
+:10BA5000F6F7B6FE2046F9F7CDF91023129301232D
+:10BA6000ADF84E0008260F9306250DF14E03204633
+:10BA70000EA910960E931195FCF7CEFE012F0CD156
+:10BA80002A4620464A49F6F79BFE2022204682217C
+:10BA90001346F6F723FE042506E02A4620464549CC
+:10BAA000F6F78EFE07260A250122134620464FF49C
+:10BAB0009B61F6F771FE45F4007343EA06139B00A1
+:10BAC00020464FF49B6140F6FC72F6F765FE0222B9
+:10BAD000134620464FF49B61F6F75EFE20464FF476
+:10BAE0009B614FF4E0424FF40053F6F755FE2022DD
+:10BAF000134620464FF49A61F6F74EFE01210022CC
+:10BB00002046F8F7DFF9204640F27641F6F712FEBC
+:10BB100010F4004F02D10A20EAF31EF62046072156
+:10BB2000039AF6F795FD2046FF21049AF6F790FD5B
+:10BB3000204640F21F11059AF6F78AFD204605219E
+:10BB40005A46F6F785FD204625215246F6F780FD38
+:10BB5000019B20464FF48971DAB2F6F779FD002592
+:10BB6000104B2046E95A07ABEA5A0235F6F7EEFDCC
+:10BB70001C2DF5D120464FFA88F1FEF7EFFE204646
+:10BB800040F2A4414A46F6F763FD029B1BB9E36904
+:10BB9000186934F0EBDD40F2E730EAF3DDF515B07B
+:10BBA000BDE8F08F1A0A020036060200780502008E
+:10BBB000A2060200740C02002DE9F04FBDB007464A
+:10BBC0000C469146002116220DF15E000493E6F327
+:10BBD00037F2A8490E220DF19E00E6F3CDF1A649F9
+:10BBE0000E2224A8E6F3C8F148F2670148F2452284
+:10BBF000ADF8EA10ADF8E820A04908220DF1C60022
+:10BC0000E6F3BAF19E490E220DF18200E6F3B4F19B
+:10BC10009C4908220DF1BE00E6F3AEF19A490E22CE
+:10BC20001DA8E6F3A9F147F69733002108220DF18C
+:10BC3000B600ADF8E630ADF8E430E6F301F2FB69AA
+:10BC400030219868D7F8A880EBF342F005900028DF
+:10BC500000F0AB8240F2DB613846F6F76BFD40F254
+:10BC6000DA610B903846F6F765FD88490A900422A0
+:10BC70003846F6F7A5FDB9F1070F0BD8DFE809F054
+:10BC800011040A0A0A22352D1DAA069224AB0DF1D1
+:10BC90005E0214E00DF18202002306921A46079319
+:10BCA00019E000210A460B4638460091F9F778FD65
+:10BCB0000DF1820106910DF15E020DF19E03072147
+:10BCC00007933EE00DF1E6030DF1EA01069308F15A
+:10BCD0008202079101230E9334E039A906913AAB11
+:10BCE00008F18202012107932BE03BAB00930DF199
+:10BCF000EF010DF1EE020DF1ED033846F9F74EFCC0
+:10BD00009DF8EF209DF8EE300DF1BE0143EA0223CD
+:10BD10004FF00002ADF86C30ADF86E209DF8EC30BD
+:10BD20009DF8ED20069143EA0223ADF870304FF004
+:10BD30000003ADF872300DF1C6030DF15E020793FA
+:10BD400004210E911023009330330193504B0021B6
+:10BD5000029338460B23F6F7A7FE05224D493846D5
+:10BD6000F6F72EFD3846F9F7D9F84FF4805213460E
+:10BD7000089040F2A4413846F6F70EFD00213846FF
+:10BD8000FEF79AF940F2DB413846F6F7D3FC424918
+:10BD9000062209903846F6F713FDB7F8DA3003F4B7
+:10BDA0007043B3F5005F07BF38463C4938463C490D
+:10BDB0001222F6F705FD40F2D7413846F6F7BAFCF5
+:10BDC000059911903846FBF7BFFE384640F23B41DB
+:10BDD000F6F7B0FCC0F380100C9020B138460DF19E
+:10BDE000B601F8F7E9FF64B90C9A22B93846B8F8F9
+:10BDF0003010FEF7B3FD0DF1CE0438462146F8F7BA
+:10BE0000DBFF638822881B0143EA0223A2882146C4
+:10BE100013439EB2B7F8DA30082203F470430DF1F1
+:10BE2000D600B3F5805F14BF00250125E6F3A4F02A
+:10BE30000A222BA80021E6F303F11A4B002233F863
+:10BE40001540104633E0184B53F82530C1180B88C5
+:10BE50001230B3422AD14B882BA8ADF8D6308A884D
+:10BE6000ADF8D82031F8063F0A22ADF8DA30E6F313
+:10BE700083F01EE078090200CE0E020022080200C4
+:10BE800058050200BC0A02005A080200900702008E
+:10BE900019880100D806020024090200FC0C0200E7
+:10BEA00030090200720C0200F80C02000132A242BA
+:10BEB000C9D138460DF1D601F9F748F9002404221A
+:10BEC00038463749374DF6F77BFC10260A233846AB
+:10BED0002146354A009601940295F6F7E5FD2023A8
+:10BEE000019338460A2321462F4A00960295F6F719
+:10BEF000DBFD40F25341384640F2A472F6F726FCCF
+:10BF0000B8F8C81340F6A663A14208BF1946B9F1B4
+:10BF1000050F01D14B4299B2D7F8FC3F0CB22BB1BF
+:10BF20003846FDF7EFFD0520EAF316F44FF47A7179
+:10BF300001235822384604FB01F1FDF767FA40F26D
+:10BF4000DA614FF6FF723846F6F700FCB7F8DA30E0
+:10BF5000384603F47043B3F5005F0CBF98F895952D
+:10BF600098F89695F8F7B4FF0021C0B2FF228B46EF
+:10BF700010900D910F929AE04FF000030799ADF8E1
+:10BF8000E0303BF80130C3F30324B9F1000F1AD0BD
+:10BF9000042C0BD00F9A042A13D110990EE0C0463E
+:10BFA000A20A020019880100640B0200109901EB3B
+:10BFB0000903D9B211F0800F18BF7F213846FEF770
+:10BFC00081FAE2B20F92069B3CA93BF8032001EBF9
+:10BFD000440333F8441C21B102F0FF0343EA012378
+:10BFE0009AB2384640F25241F6F7B0FBE31E1FFA10
+:10BFF00083FABAF1010F16D86D4B10254524029330
+:10C00000384600210DF1E202012300950194F6F774
+:10C010003DFD684B38460293002138AA0123009564
+:10C020000194F6F741FD079B384640F251413BF839
+:10C030000320F6F78BFB3846F9F72EFF00287CD05B
+:10C040005B4A602112AC10250B2301910292002162
+:10C05000384622460095574EF6F718FD40230193C7
+:10C0600000210B233846224600950296F6F71CFD68
+:10C07000BAF1010F0AD845230193384600210DF18A
+:10C08000E202012300950296F6F70EFD484960236F
+:10C090000193029108F18202384600210B2300959A
+:10C0A000F6F7F4FC0D9A0BF1020B01320D920D9B89
+:10C0B0000E998B427FF460AF602301933C4B08F1F3
+:10C0C0008206102402933846002132460B23394D54
+:10C0D0000094F6F7DBFC4FF001025023A8F89820FB
+:10C0E0003846019300213246042300940295F6F766
+:10C0F000DBFC552301933846002108F18C02022312
+:10C1000000940295F6F7D0FC3846F8F74FFCA0B142
+:10C1100038A90DF1DE023846FCF750FB3846FCF733
+:10C12000EDF9BDF8E0100446BDF8DE203846FDF715
+:10C1300085FD38462146FDF713FB049B13B93846AD
+:10C14000FDF7E0FC38460599F9F714FB384640F254
+:10C15000D741119AF6F7FAFAFB69059998683022E7
+:10C16000EAF3C6F5384640F2DB41099AF6F7EEFAF3
+:10C1700040F2534138460022F6F7E8FA0C9921B113
+:10C1800038460DF1B601F8F7E1FF38460899FDF79A
+:10C1900093FF384640F2DA610A9AF6F7D7FA384642
+:10C1A00040F2DB610B9AF6F7D1FA3DB0BDE8F08FB3
+:10C1B00015820100198801002DE9F0470546D0F8E5
+:10C1C000A8404FEA0118F8F783FE40F2D74147B282
+:10C1D0002846F6F7AFFA94F925258146B2F1FF3FDC
+:10C1E00011D0042392FBF3F3984505DA284640F278
+:10C1F000D7414022002304E04022284640F2D741A4
+:10C200001346F6F7C9FAD5F8FC3F53B12846FDF7B7
+:10C2100079FC0520EAF3A0F21C492846702200238D
+:10C2200002E01A4928467022FDF7F0F82846394600
+:10C23000FEF794FB002601212846FBF76FFD04233F
+:10C24000C8EB00047A1E94FBF3F3D2187F2AA8BF30
+:10C250007F2222EAE277284639460434FEF77EFB45
+:10C26000082C03D90A2E01D00136E4E72846FDF751
+:10C2700049FC284640F2D7414A46F6F767FA284675
+:10C28000F8F726FE40B2BDE8F087C04600093D0041
+:10C290002DE9F04391B08046D0F8A860F8F718FE79
+:10C2A0001C23B8F8DA208DF83B3001238DF83A30A2
+:10C2B00002F47043B3F5805F5FFA80F907D1D3B21F
+:10C2C000402B01D81B2300E02D238DF83B30B8F81C
+:10C2D000DA2002F47043B3F5005F33D1B6F82A25B3
+:10C2E00013B2B3F1FF3F04D04FF6FF73002A08BF2B
+:10C2F0001A46B6F8F6130BB2B3F1FF3F02D14FF472
+:10C30000917104E04FF6FF73002908BF1946B6F893
+:10C310002C5596F8F0032BB2B3F1FF3F04D04FF643
+:10C32000FF73002D08BF1D46B6F8F84323B2B3F1E2
+:10C33000FF3F04D04FF6FF73002C08BF1C4696F851
+:10C34000F1739FE0D3B2402B33D8B6F82E2513B249
+:10C35000B3F1FF3F04D04FF6FF73002A08BF1A461F
+:10C36000B6F8FA130BB2B3F1FF3F02D14FF491715B
+:10C3700004E04FF6FF73002908BF1946B6F83055A0
+:10C3800096F859052BB2B3F1FF3F04D04FF6FF7377
+:10C39000002D08BF1D46B6F8004423B2B3F1FF3F9D
+:10C3A00004D04FF6FF73002C08BF1C4696F85B754F
+:10C3B00068E08C2B33D8B6F8322513B2B3F1FF3FC7
+:10C3C00004D04FF6FF73002A08BF1A46B6F8FC13D4
+:10C3D0000BB2B3F1FF3F02D14FF4917104E04FF67D
+:10C3E000FF73002908BF1946B6F8345596F8F203D2
+:10C3F0002BB2B3F1FF3F04D04FF6FF73002D08BFFF
+:10C400001D46B6F8024423B2B3F1FF3F04D04FF605
+:10C41000FF73002C08BF1C4696F8F37332E0B6F8A1
+:10C42000362513B2B3F1FF3F04D04FF6FF73002A55
+:10C4300008BF1A46B6F8FE130BB2B3F1FF3F02D1A4
+:10C440004FF4917104E04FF6FF73002908BF1946BD
+:10C45000B6F8385596F85A052BB2B3F1FF3F04D021
+:10C460004FF6FF73002D08BF1D46B6F8044423B2F3
+:10C47000B3F1FF3F04D04FF6FF73002C08BF1C46FA
+:10C4800096F85C7513B2B3F1FF3F04D040461946ED
+:10C49000FFF792FE0DE009B2B1F1FF3F07D0404631
+:10C4A0000DF13202FFF728F89DF83B3007E0FF2836
+:10C4B00002D086F8070404E09DF83B300BB186F803
+:10C4C000073429B2B1F1FF3F05D04046FFF774FEB3
+:10C4D00086F8080411E021B2B1F1FF3F09D04046CF
+:10C4E0000DF13202FFF708F89DF83B3086F808346A
+:10C4F00003E0FF2F18BF86F8087496F9EF33B3F105
+:10C50000FF3F1CBF4FF0FF3386F8083496F808044D
+:10C5100041B2B1F1FF3F76D096F8072453B2994269
+:10C52000D8BF86F8082496F80834D8BF86F80704E0
+:10C5300000248DF83B30DB2301250393404623463E
+:10C5400021460DF132020495009401940294059461
+:10C55000FEF72CFD18230993083308950B93254605
+:10C5600007AC0FAB4046214607930A95FBF752FEF6
+:10C5700005F140034046214601350A93FCF74CF98A
+:10C58000402DEDD196F9072496F908349B18022224
+:10C5900093FBF2F3A6F86835B8F8DA2002F470439A
+:10C5A000B3F5005F02D1B6F85E3583B9D3B2402B44
+:10C5B00005D8B6F8602512B1A6F8682509E08C2BDD
+:10C5C00002D8B6F8623513B9B6F864350BB1A6F8DF
+:10C5D0006835404640F224514FF400420023F6F7FC
+:10C5E000DBF896F96625B6F86835013293FBF2F36D
+:10C5F0009BB2404640F22551FF22F6F7CDF80223C8
+:10C6000086F8673529E0012386F86735404640F211
+:10C610002551FF227E33F6F7BFF8404640F2255100
+:10C620004FF480720023F6F7B7F8404640F22551E8
+:10C630004FF400720023F6F7AFF8404640F2255160
+:10C640004FF480620023F6F7A7F8404640F22551E8
+:10C650004FF400620023F6F79FF84FF00003A6F8AE
+:10C660006A35404640F2255196F96645F6F762F87C
+:10C670000134C0B204FB00F496F96635A6F86845AB
+:10C6800013B14046FCF72CFD96F8EF330DF1320262
+:10C69000FF2B08BF96F8073400218DF83B30DB23D1
+:10C6A00003930123049340460B46009101910291AC
+:10C6B0000591FEF77BFC40464946FEF74FF94046A0
+:10C6C00040F27161F6F736F8B6F96A3540F27161F9
+:10C6D000A0EBC30292B24046F6F738F84046FBF7AB
+:10C6E00093FE11B0BDE8F08370B58E46BEF1FF3FFA
+:10C6F0000546144619469DF9106002D006EB0E015E
+:10C700000DE022B990F82916FFF756FD02E0B2F1CC
+:10C71000FF3F04D021462846FFF74EFD81192846E9
+:10C72000FEF71CF970BDC0462DE9F04F87B00446F6
+:10C73000F8F7F4FB04A981462046D4F8A850F8F78E
+:10C740003BFB2046F8F7BCFB40F2D741834620462E
+:10C75000F5F7F0FF03902046FCF74AF88246B9F15E
+:10C76000000F02D0FF23029304E02046F8F7B0FB4D
+:10C7700040B20290B4F8DA304FF02A0803F4704364
+:10C78000B3F5005F0CBF95F81E1595F81F152046F0
+:10C790004FB239460F223C23CDF80080FFF7A4FFAB
+:10C7A00095F84665002E00F09080204640F2EB415F
+:10C7B000F5F7C0FF1221C0F3402301222046F5F710
+:10C7C0008DFF6A780021521A18BF01220B462046BD
+:10C7D000FFF7F2F92046FBF791FE40F3072340B242
+:10C7E000A5F84A35A5F84C0540F2EB412046F5F78F
+:10C7F000A1FFC0F380235B02204640F2EB414FF4DF
+:10C800000072F5F7C9FF002107220B462046FFF70B
+:10C81000D3F92046FBF772FE40F3072340B2A5F898
+:10C820004E35A5F85005FF222046B5F84A3540F6AA
+:10C830005211F5F7B1FF2046FF22B5F84C3540F60E
+:10C840005311F5F7A9FF2046FF22B5F84A3540F607
+:10C850005611F5F7A1FF2046FF22B5F84C3540F6FA
+:10C860005711F5F799FF2046FF22B5F84E3540F6EF
+:10C870004811F5F791FFFF222046B5F8503540F6F4
+:10C880004911F5F789FF95F84A3595F84C1520467A
+:10C8900041EA0321FCF764FF95F8473520469B02E7
+:10C8A00040F2EB414FF4806203F47C43F5F774FFF0
+:10C8B00095F8483520465B0240F2EB414FF4007298
+:10C8C00003F47E43F5F768FF10E0204639460F2257
+:10C8D0003C23CDF80080FFF707FF6A7820463146F9
+:10C8E000003A18BF01223346FFF766F92046F8F7F1
+:10C8F0004BF810B12046FBF715FE00217F220B46B6
+:10C900002046FCF7DDFC20465146FDF7C7FD2046DA
+:10C910005946F8F7CFFB204604A9F8F717FC204644
+:10C9200040F2D741039AF5F711FFB9F1000F04D097
+:10C9300020464946FDF7C0FB03E020460299FEF77A
+:10C940000DF807B0BDE8F08F2DE9F04F89B004462F
+:10C95000D0F8A870F8F7E2FA04902046F8F7B8FA91
+:10C960004FF489715FFA80FA2046F5F759FE0721E6
+:10C9700005902046F5F754FEFF2101902046F5F77B
+:10C980004FFE40F21F1102902046F5F749FE40F29B
+:10C99000AB4103902046F5F7CDFED4F8B030D3F884
+:10C9A000203183F0010313F0010B03D1E36918690F
+:10C9B00033F0F0DE00212046FDF77EFB2046F6F73F
+:10C9C00077FB40F23B412046F5F7B4FE0DF1180924
+:10C9D000494680462046F8F7EFF920460121F8F74E
+:10C9E0007DFB20467F21FDF7B9FF0122134620463B
+:10C9F0000721F5F773FE102213462046FF21F5F7B5
+:10CA00006DFE0422134640F21F112046F5F766FE24
+:10CA10002046FDF74FFC06224B492046F5F7D0FE95
+:10CA20002046FBF7E5FE002106462046FDF736FDD1
+:10CA3000002220460121F7F745FA40F2AB4120469B
+:10CA4000F5F778FE40F23E612046F5F773FEC50526
+:10CA5000ED0D2B46204640F2A64140F2FF12F5F7BD
+:10CA60009BFE97F8E8330BB3204638490922F5F7C7
+:10CA7000A7FE002220460121F7F724FA40F2AB413D
+:10CA80002046F5F757FE40F23E612046F5F752FE8C
+:10CA9000C30540F29A41204640F2FF12DB0DF5F744
+:10CAA0007BFE20462A490922F5F78AFE2B462046BE
+:10CAB00040F2A64140F2FF12F5F76EFE00234FF45C
+:10CAC0008052204640F24C41F5F766FE2046314642
+:10CAD000FDF7E4FC2046C8F38011F8F7FFFA204682
+:10CAE0004946F8F733FB20465146FDF737FF20460D
+:10CAF0000499FDF7E1FA20464FF48971059AF5F79C
+:10CB0000A7FD019D012205EA020320460721F5F752
+:10CB1000E5FD029D102205EA02032046FF21F5F7FC
+:10CB2000DDFD039D0422204640F21F1105EA0203A9
+:10CB3000F5F7D4FDBBF1000F03D1E369186933F0B9
+:10CB400015DE09B0BDE8F08FD80C0200E205020046
+:10CB5000E40C02002DE9F3410446F8F7DFF9E3693C
+:10CB6000D4F8A8501A6A04F580531A6094F8DA30A1
+:10CB7000002685F8BC3241F20403E654D4F8B03004
+:10CB80008046D3F8203183F0010313F001070AD166
+:10CB9000E369B821186942F2107233F0C9DDE36924
+:10CBA000186933F0F7DD20460121F9F7B1FE0F22B5
+:10CBB00023492046F5F704FE2046F8F775FD204688
+:10CBC0003146FCF7CDFD204631463246FDF736F8BA
+:10CBD0002046F6F76DFA41F22403E35C6BB1204680
+:10CBE000FFF7B2FE20463146FDF74EF995F8E833DF
+:10CBF0001BB120460121FDF747F92046FFF794FDC0
+:10CC000000217F230A46009320460123FDF7C6FF3B
+:10CC10004FF0FF3385F8073485F808342046FFF7D6
+:10CC200037FB20464146FDF747FA20460021F9F739
+:10CC30006FFE1FB9E369186933F098DDBDE8FC8128
+:10CC4000DA070200082910B503D00A2904D0022906
+:10CC500004D1FFF77FFF01E0FEF794FD10BDC04651
+:10CC600010B50446F6F724FA20460021FDF724FA11
+:10CC700020460821FFF7E6FF10BDC04670B541F21F
+:10CC80000403C35C0446D0F8A85013B9F7F70CFFAF
+:10CC9000F0B1D4F8F83013F0070F06D194F8F5305E
+:10CCA0001BB920460921FFF7CDFFD4F8F82012F078
+:10CCB0000F0F0DD141F20C03E3564BB912F0800F68
+:10CCC00006D194F8F5301BB920460221FFF7BAFFD0
+:10CCD000D4F8F83013F00E0F02D12046F9F752F9CC
+:10CCE000D4F8F83013F0060F3ED1D5F8340448B329
+:10CCF000E169D5F838240B6A9B1A834234D308695A
+:10CD00006A2133F0F7DC400081B2B1B1E369186900
+:10CD100033F0F0DC88B940F276412046F5F70AFDA1
+:10CD2000C005C00DA5F86C0540F277412046F5F727
+:10CD300001FDC005C00DA5F86E0520460021F9F7DC
+:10CD40004BFF11E040F276412046F5F7F3FCC005B9
+:10CD5000C00DA5F86C0540F277412046F5F7EAFCD6
+:10CD6000C005C00DA5F86E052046F8F7D7F8B0F558
+:10CD7000404F0CD02046F8F7ABF8C0B220B10023EA
+:10CD80007F2885F8563402D0002385F8573470BDCB
+:10CD90002DE9F047CCB20746D0F8A8602046894676
+:10CDA000F5F7DEFE494680463846F5F7BBFE3846C5
+:10CDB000B7F8DA10FBF758F9042238465B49F5F763
+:10CDC000FFFC21463846FAF7B5F90A20E9F3C4F426
+:10CDD0004FF4004213464FF489613846F5F7DCFC06
+:10CDE0003846F8F78DFB052100224FEA4800F7F797
+:10CDF000B1FC0022054641464FF42010F7F7AAFC8B
+:10CE000040F257610446AAB23846F5F79FFC38460F
+:10CE10004FF4CB61A2B2F5F799FC4FF4007338469A
+:10CE20004FF489614FF44072F5F7B6FC97F8DA30A9
+:10CE30000E2B01D11E2206E0B6F8622013B2B3F128
+:10CE4000FF3F08BF1522A6F840253846002112B240
+:10CE5000FBF7E2FB20B1384600211422FBF7DCFB94
+:10CE600097F8DA3038220E2B0CBF182300233846EF
+:10CE700040F2EB41F5F790FCB7F8DA30384603F4AE
+:10CE80007043B3F5005F0CBFB6F86620B6F86820B3
+:10CE9000012113B2B3F1FF3F08BF0222A6F83E25DD
+:10CEA00012B2FBF7B9FB182238462149F5F788FC86
+:10CEB0003846F6F70DF996F8BC2298B10E2AB7F865
+:10CEC000DA3003D9DBB20E2B03D805E0DBB20E2B30
+:10CED00002D83846012101E0384600214A46FCF7D5
+:10CEE000A1FF21E097F8DA309A4201D1012A04D15A
+:10CEF00038460821FFF7A6FE02E03846FCF776FF29
+:10CF000000210A463846FBF753FD3846F9F7B6F9D3
+:10CF100038460121F9F76AFA41F22403FB5C1BB1A0
+:10CF200038460321FBF70AF9BDE8F08792050200B5
+:10CF30002A080200D0F8B03073B5D3F82031044687
+:10CF400083F0010313F00106D0F8A85003D1C369A0
+:10CF5000186933F01FDC41F22403E25C42BBB4F8F1
+:10CF6000DA3003F47043B3F5005F08D14FF00403E7
+:10CF7000ADF800304FF00C03ADF8023007E04FF091
+:10CF8000FF03ADF80030ADF802304FF0F00320465B
+:10CF90006946ADF80430ADF80620F8F7D7F820461A
+:10CFA0009621FDF77BFA20460121FEF7BDFC56E0F5
+:10CFB0002046FFF7C9FC2046FDF756F82046002121
+:10CFC000FCF762FF204635490F22F5F7F9FB95F88B
+:10CFD000E833DBB120460121FCF756FF95F92435F3
+:10CFE000204640F2D141FF229BB2F5F7D5FB95F8E0
+:10CFF0002535204640F2D1414FF47F421B02F5F720
+:10D00000CBFB204626490C22F5F7DAFB0522204609
+:10D010002449F5F7D5FBD4F8A8202046D2F84434AB
+:10D02000D2F848243C2BA8BF3C239342B8BF1346F8
+:10D0300040F2A741FF229BB2F5F7AEFBB4F8DA301D
+:10D04000204603F47043B3F5005F0CBF95F85434E9
+:10D0500095F855344FF440412B86FDF72DF840F2FA
+:10D0600076412046F5F766FBC005C00DA5F86C05B6
+:10D0700040F277412046F5F75DFBD5F83434C00522
+:10D08000C00DA5F86E051BB120460121F9F7A4FDDE
+:10D090001EB9E369186933F069DB7CBD4A0E0200F2
+:10D0A0002A070200100A02002DE9F041D0F8A8601A
+:10D0B000012386F86130013B86F8C033B0F8DA30DE
+:10D0C000074603F47043B3F5005F02D196F8C1330D
+:10D0D00004E0B3F5805F06D196F8C233022B02D18B
+:10D0E000012386F8C033B7F8DA30384603F47043CA
+:10D0F000B3F5805F0CBF96F8EB3396F8EA33002463
+:10D1000086F8E933738B0125A6F8BE320422234941
+:10D11000347086F8C24286F8C34286F8C44286F864
+:10D120006755F5F74DFB38462946F8F721FA0422F2
+:10D130001B493846F5F744FB3846FCF7A1FA384658
+:10D14000FCF7DCFC3846FFF7F5FE86F82C40B7F814
+:10D15000DA103846F6F784FD3846FBF765F84FF4E9
+:10D16000804213464FF489613846F5F715FB642079
+:10D17000E9F3F2F2234638464FF489614FF48042D6
+:10D18000F5F70AFB38464FF44041FCF795FF41F2B2
+:10D190008833F38686F89A55BDE8F08122070200AD
+:10D1A000040C020010B58068F2F36AF210BDC046AC
+:10D1B00010B5437902790C4642EA032E0EF00303C0
+:10D1C000012B0AD0022B0ED013B14FF400702EE0C9
+:10D1D0000A780523B2FBF3F029E00B78144A03F038
+:10D1E0000703D05C23E00978E378227911F0800FFF
+:10D1F00043EA022201F07F0343F0006002D040F4D2
+:10D20000806006E01EF0200F1CBF20F4E06343F4B2
+:10D21000407012F0800F18BF40F4000012F0400F71
+:10D2200018BF40F48000C2F3011340EA035010BD60
+:10D2300050FD010070B585680446D4F8F811A8685F
+:10D24000F2F30CF24FF0FF3384F8E231A36123686C
+:10D2500000229A712B6B064602211869F5F732FC01
+:10D26000204636F00FDDD6F1010038BF002070BD3A
+:10D2700070B50D460968044671B1D1F87C1129B129
+:10D28000036840F20C72D868E9F332F52368296824
+:10D29000D8686269E9F32CF523682946D86810221A
+:10D2A000E9F326F570BDC04637B5054601A9D0F8AB
+:10D2B000000537F00FDF09E02846214638F06AD92B
+:10D2C000636C1BB92846214638F07ADA01A837F09A
+:10D2D00009DF04460028EFD13EBDC046036870B5A3
+:10D2E00010210546D868E9F3F3F408B9064615E0BD
+:10D2F0002B6806466969D868E9F3EAF404463060A9
+:10D3000028B931462846FFF7B3FF264606E000233A
+:10D31000C0F87C313146284637F0BCDD304670BD60
+:10D320002DE9F3470D469246002853D0002951D0ED
+:10D330000B88D0F80490D0F89843D0F89463002B71
+:10D340004BD00027E780A7804B880A8813F001089C
+:10D3500024D0402A14D1043120463B4600973BF0AC
+:10D36000DBDFB8423BDBB6F8023113F0400F34D0BC
+:10D37000BAF1000F31D0D9F80C003AF06FDF0BE0B2
+:10D38000A2F108039BB2372B29D804F1080004311D
+:10D39000E4F3F2F52D88A580384622E0202A19D83A
+:10D3A000043104F14800E4F3E7F5A4F804802D8883
+:10D3B0000123E580C6F8CC30B6F8023113F0400FF7
+:10D3C0000BD0BAF1000F08D0D9F80C003AF046DFC4
+:10D3D000404606E06FF0010003E0002001E04FF05E
+:10D3E000FF30BDE8FC87C04610B50DF09DFD04463A
+:10D3F000F1F7AAFF2046E8F3BDF710BDAAAA030083
+:10D400001958000040960000904C00001472000073
+:10D41000101800000FAC000050F2000050F20100A4
+:10D420000050F20200000050F2020100AAAA03001C
+:10D43000195800000000000050F2040000147200AF
+:10D44000000FAC000050F200001018000050F20075
+:10D45000000FAC0000409600000000000000101813
+:10D4600000696C306D6163616464723D30303A31E3
+:10D47000313A32323A33333A34343A353500626F26
+:10D48000617264747970653D3078666666660062C4
+:10D490006F6172647265763D3078313000626F6121
+:10D4A0007264666C6167733D38006161303D3300C2
+:10D4B00073726F6D7265763D3200AAAA0300195827
+:10D4C000000050F200000000594D80009557800088
+:10D4D00049588000315680000D5A8000C1588000A4
+:10D4E000295A8000455A8000795780004D568000A7
+:10D4F000755A800025558000F15980000D58800034
+:10D5000069548000C14E8000E9518000555280006E
+:10D51000C9518000DD58800051518000D1558000F4
+:10D52000A555800015568000E14F80008955800088
+:10D53000FD4E800025508000C9110100ED4D800096
+:10D54000854E8000A94F8000D94D8000094E800093
+:10D55000514C8000654C800000000000000000007D
+:10D5600000000000C14F800025528000F95180006A
+:10D57000E12800002800000073645F6C6576656C2C
+:10D580005F74726967676572007370695F70755F59
+:10D59000656E6162006172705F6D61636164647287
+:10D5A000006172705F72656D6F7465697000000074
+:10D5B000F83B86000000000007000000FF3B8600EB
+:10D5C00001000000070000000B3C86000200000084
+:10D5D000000000001B3C8600030000000700000064
+:10D5E000263C86000400000000000000373C860056
+:10D5F0000500000008003000413C860006000000E5
+:10D600000000000095D501000800000006000000A1
+:10D61000A1D5010009000000070000000000000083
+:10D62000000000000000000070666E5F737573708C
+:10D63000656E640058408600000000000800140079
+:10D6400060408600010000000800880068408600F5
+:10D65000020000000800380070408600030000004F
+:10D66000080008007E408600040000000100000061
+:10D670008240860005000000000000008B4086000C
+:10D68000060000000800380028D60100070000004E
+:10D690000100000000000000000000000000000089
+:10D6A000352E39302E3139352E38392E3600776CFB
+:10D6B00025643A2025732025732076657273696F7F
+:10D6C0006E20257320465749442030312D25780A95
+:10D6D0000041707220323220323031330031343A1E
+:10D6E00035303A3030000000DA4386000000000098
+:10D6F00008000000E3438600010000000100000074
+:10D700000000000000000000000000005C782530F0
+:10D71000325800253034780A007478636861696E85
+:10D72000007278636861696E00776C635F696F7619
+:10D730006172733200727373695F6F6666736574CA
+:10D740000064796E74785F7164626D5F6F76657284
+:10D75000726964650064796E74785F726174655F84
+:10D76000616C6C00505A443A2025643E2564206F59
+:10D77000722025643E256420613D25640A006F7493
+:10D780007077006164640064656C006C6F775F7231
+:10D790007373695F74726967676572006C6F775F36
+:10D7A000727373695F6475726174696F6E0074631C
+:10D7B0005F656E61626C650074635F706572696F4E
+:10D7C000640074635F68695F776D0074635F6C6F9A
+:10D7D0005F776D0074635F73746174757300617358
+:10D7E000736F635F73746174650064796E7478003D
+:10D7F00074785F737461745F63686B0074785F73CF
+:10D800007461745F63686B5F7072640074785F73D7
+:10D810007461745F63686B5F726174696F007478C0
+:10D820005F737461745F63686B5F6E756D007278AF
+:10D830005F726174650069735F5750535F656E7204
+:10D840006F6C6C65650069735F7770735F656E728E
+:10D850006F6C6C65650002000000000035D70100A8
+:10D8600001000000060000008BD70100020000004C
+:10D87000060000009CD70100030000000600000025
+:10D88000AED701000400000006000000B8D7010078
+:10D890000500000006000000C2D7010006000000DD
+:10D8A00006000000CBD701000700000006000000C2
+:10D8B000D4D701000800000006000000DED70100F8
+:10D8C0000900000006000000EAD701000A0000007D
+:10D8D00006000000F0D701000B0000000600000069
+:10D8E000FCD701000C000000060000000CD801006D
+:10D8F0000D000000060000001ED801000E00000010
+:10D90000060000002ED801000F00000006000000F5
+:10D9100036D80100100000000100000046D80100C8
+:10D9200010000000010000000000000000000000E6
+:10D930000000000005A58100FDA581000000000099
+:10D94000000000000DCD820089E68200F5CB820048
+:10D95000EDCC820067898600000080000100000095
+:10D96000458B860001000000080002004F8B8600F6
+:10D970001D000000080002005C8B86000F00000004
+:10D98000030000006A8B8600100080000700000082
+:10D990007A8B860002000000080007008B8B86004F
+:10D9A00003000000080007009C8B86000400800034
+:10D9B00001000000AE8B860006000000020000009F
+:10D9C000B98B86000C00000002000000C88B8600A6
+:10D9D00021008000030000000000000000000000A3
+:10D9E000000000004CDB01001000000006000000F9
+:10D9F000529B860001000000010000005D9B860034
+:10DA000002002000070000006F9B8600030040001A
+:10DA1000080007007C9B860004004000080004000A
+:10DA20008B9B860005004000080004009A9B86003E
+:10DA300006000000080004004FDB01000D0010008C
+:10DA400007000000A79B86000E00200007000000D2
+:10DA5000B49B86000700100007000000BF9B8600F3
+:10DA6000080000000800100058DB01000900000059
+:10DA700006000000C99B860024000000060000008C
+:10DA80005CDB01000A00000006000000AB728600AB
+:10DA90000F00000001000000D59B86000B008000F5
+:10DAA00001000000DA9B86000C0000000500000069
+:10DAB000E59B86001D00000003000000FA9B860025
+:10DAC0001E00000007000000139C86001F000000DD
+:10DAD00007000000259C86002100000005000000D2
+:10DAE0003B9C86002000000003000000499C86004B
+:10DAF00011008000010000004F9C860018004000CB
+:10DB000008000600539C8600190000000500000074
+:10DB1000619C86001A000000010000006C9C8600D9
+:10DB20001B00400001000000000000000000000099
+:10DB3000000000000050F20201010000013200006C
+:10DB400027A4000041325E0061212F006170006D4A
+:10DB500061786173736F63006273730073736964D8
+:10DB600000092F160E0E057573696E6720703270EE
+:10DB7000206D6963726F636F64650A00776C25645A
+:10DB80003A205048595458206572726F72282564A3
+:10DB9000290A000091BA8600000080000100000000
+:10DBA00030BB860002000000080044003ABB86003B
+:10DBB000030000000800440044BB8600040000008D
+:10DBC000080000004FBB860005000000080044006C
+:10DBD00059BB8600060000000800000067BB8600F5
+:10DBE0000700000008004C0074BB8600080000001D
+:10DBF00008004C0081BB8600090080000200000084
+:10DC000000000000000000000000000054545454C4
+:10DC10005400000000000000000050505050500020
+:10DC200000000000000000002300000003000000CE
+:10DC300000084C4C4C4C4C4C1414140000010000D7
+:10DC400064646464646464646464646464000000C0
+:10DC5000000000000000000000000000013C424203
+:10DC6000424242424242423C0000000000000000AA
+:10DC700000000000000000000000344A4E4E4E4EEE
+:10DC80004E4E4E4A38000000000000000000000028
+:10DC9000000000000000004C4C4C4C4C4C4C4C4CD8
+:10DCA0004C4C4C4C00000040404040404040000084
+:10DCB00000000001030000000001424242324242E3
+:10DCC0001414140000000000030000000008444485
+:10DCD0004438444414141400000000000300000001
+:10DCE00000013E3E42343E42141414000000000085
+:10DCF00054545400540000000000000000000000D4
+:10DD000000000000000000000000000023000000F0
+:10DD1000030000000001444444384440141414003B
+:10DD200000000000484A4A4A4A4A4A4A4A4A4A4A7D
+:10DD300048000000343434343434343434000000C7
+:10DD4000004E4E4E4E4E4E4E4E4E4E4E4E4E0000DD
+:10DD50000000000000000000000000000008545413
+:10DD6000540054000000000000000000505050001B
+:10DD700050000000000000000000233A3E3800423E
+:10DD80000000000000000000000000000000000093
+:10DD9000000000000000000A000000006400000015
+:10DDA000000000000000000000005800000000001B
+:10DDB00000000000013242424242424242424232AC
+:10DDC00042420000000000000000000000000000CF
+:10DDD000000836444444444444444444364A4000E1
+:10DDE0000000000000000000000000000000082EFD
+:10DDF0004444444444444444442E463A0000000011
+:10DE00000000000000000000000000083C3E3E3E14
+:10DE10003E3E3E3E3E3E3C3E3E00000000000000D6
+:10DE2000000000000000000008344444444444441E
+:10DE3000444444384440000000000000000000005A
+:10DE40000000000000085C5C5C5C5C5C5C5C5C5C32
+:10DE50005C5C5C00005050505050505050500000DE
+:10DE6000000001383E383E42000000000000000083
+:10DE70000000000000000000000000000000000A98
+:10DE80000100000000014E4E4E344C381E1E1E0094
+:10DE90000000000003000000000142444230443012
+:10DEA00014141400000000000300000000013E3EB6
+:10DEB0003E3C3E3E1414140000000000030000002D
+:10DEC0000001444444364C3814141400000000008F
+:10DED0000300000000013E3E30363A2C14141400BA
+:10DEE000000000004242424242424242424242421A
+:10DEF000420000002E343434343434343400000012
+:10DF0000004A4A4A4A4A4A4A4A4A4A4A4A4A00004F
+:10DF1000002E34343434343434340000000054548B
+:10DF20005400540000000000000000004848480071
+:10DF300048000000000000000000233E3E3E4A0072
+:10DF40000000000000000000002828284000000019
+:10DF500000000000000000004644444A00000000A9
+:10DF600000000000000000000000000000000000B1
+:10DF7000000000000A545454005400000000000047
+:10DF80000000004848480048000000000000000071
+:10DF900000230000030000000000424242424242CF
+:10DFA00014141400000000000300000000003E3EB6
+:10DFB0003E3E3E3E141414000000000054545454DD
+:10DFC0000000000000000000000050505050000011
+:10DFD0000000000000000000233844444A4A0000CA
+:10DFE0000000000000000000000000000000000031
+:10DFF00000000000000A00000000340000000000E3
+:10E0000000000000000000003400000000000000DC
+:10E01000000000545454545400000000000000005C
+:10E020000048484848480000000000000000002365
+:10E03000545454545400000000000000000050509C
+:10E04000505050000000000000000000235C5C5CA9
+:10E050000050000000000000000000504850004444
+:10E06000000000000000000000234C4C4C4C4C4CC5
+:10E070004C4C4C4C4C4C4C0000000000000000008C
+:10E0800000000000000009000100000000013E3E09
+:10E090003E323E361414140000000000010000005F
+:10E0A00000013E3E3E343E381414140000000000CF
+:10E0B0000100000000014242423C423C1E1E1E0084
+:10E0C000000000000100000000014E4E4E364C38AA
+:10E0D0001E1E1E0000000000545454545400000042
+:10E0E00000000000000048484848480000000000C8
+:10E0F0000000000023000000006400000000000099
+:10E1000000000000000000580000000000000000B7
+:10E1100000010000030000000000464646484A484F
+:10E120001717170000000000610A86007E0A8600AB
+:10E130009B0A86000F0B8600490B8600660B860043
+:10E14000630F8600240E8600410E860014108600A0
+:10E150006B108600311086009C108600D01086005F
+:10E160000411860060118600B1118600830B8600C1
+:10E17000A00B86000C0F8600F70B8600CE118600E0
+:10E18000310C86006B0C860094118600DA0B860039
+:10E190005E0E86004E0C8600290F8600B80A8600A7
+:10E1A000D50A8600F20A86007B0E86004E10860095
+:10E1B000BD0B8600980E86009D0F8600B50E86006A
+:10E1C000880C8600D20E8600140C8600290F86006B
+:10E1D000BA0F86002C0B8600440A8600800F86004A
+:10E1E000460F8600EF0E8600B5DD0100D2DD01008E
+:10E1F000EFDD01005DDC010024DD01000CDE01002B
+:10E2000001DF010046DE010097DC01006AE0010049
+:10E2100040DC01007ADC010041DD010029DE010063
+:10E22000E4DE010021E3010004E30100383838385E
+:10E2300038000000000000000000343434343400A2
+:10E240000000000000000000003A3A3A3A460000A0
+:10E2500000000000000000000000000000000000BE
+:10E26000000000000008384444444A000000000058
+:10E27000000000000000000000000000000000009E
+:10E2800000002A0000000054000000000000000010
+:10E290000000000000440000000000000000000139
+:10E2A00018098600C00D8600E80D8600200D860046
+:10E2B000AC0D8600DCDC01009CE00100C8E301003D
+:10E2C000A8DF010088E0010094DF0100B4DC010058
+:10E2D00010DD010094DE0100B0E0010014E1010056
+:10E2E000A8DE0100FCE3010080DE010078E301000C
+:10E2F00010E40100C4E00100BCDE0100D0DE01003A
+:10E30000C8DC010038444444444444444444384450
+:10E31000440000002C3838383838303434000000DD
+:10E3200000343A3A3A3A3A3A3A3A3A3A2C2C00001D
+:10E3300000323C3C3C3C3C000000000000003E48F9
+:10E3400048424600000000000000000000000000FD
+:10E35000000000000000000000000A0038383E42C3
+:10E3600000000000000000000000000000000000AD
+:10E37000000000000000000A030000000000444408
+:10E38000444C4C4C17171700000000003232323852
+:10E39000000000000000000000003838383800009D
+:10E3A0000000000000000000004C0000004C0000D5
+:10E3B00000000000000000500000005000000000BD
+:10E3C00000000000000100000300000000004242C5
+:10E3D00042424242171717000000000054545400F4
+:10E3E000000000000000000000005050500000003D
+:10E3F00000000000000000002300000003000000F7
+:10E400000001444444344444141414000000000047
+:10E410000300000000006464646464642424240035
+:10E42000000100003CE486000000800001000000C4
+:10E4300084E5860001000000080024008DE58600C8
+:10E44000020000000100000096E5860003000000C5
+:10E45000030000009EE586000400000008000000A4
+:10E46000A7E586000500000008000200B1E586006F
+:10E470000600000008000800BBE586000700000059
+:10E4800008000600C5E58600080000000800060038
+:10E49000CCE586000900000008000200D4E58600F3
+:10E4A0000A00000008000300DCE586000B00000005
+:10E4B00007000000E9E586000C00000008000600E7
+:10E4C000EDE401000D00000008000700F7E4010082
+:10E4D0000E0000000100000000000000000000002D
+:10E4E000000000006368616E7370656300703270D5
+:10E4F0005F6966757064007032705F646566696537
+:10E5000000000000C8E686000000000008000C00C3
+:10E51000D7E686000100000007000400E9E6860057
+:10E520000200000008000800FBE68600030000006F
+:10E53000070004000BE786000400000008001C0030
+:10E540001BE786000500000008000C002CE7860091
+:10E55000060000000700040043E7860007000000F3
+:10E560000700040094E50100080000000700040013
+:10E57000A4E501000900000007000400B8E501005F
+:10E580000A000000080090000000000000000000E9
+:10E5900000000000706B745F66696C7465725F697F
+:10E5A000636D7000706B745F66696C7465725F692F
+:10E5B000636D705F636E740077616B655F7061633C
+:10E5C0006B6574005365742042525054206174206E
+:10E5D00025780A000A465749442030312D25780A0B
+:10E5E000000A54524150202578282578293A207075
+:10E5F000632025782C206C722025782C20737020C5
+:10E6000025782C207073722025782C2078707372F6
+:10E610002025780A00202072302025782C207231A5
+:10E620002025782C2072322025782C20723320254A
+:10E63000782C2072342025782C2072352025782CD7
+:10E640002072362025780A00202072372025782C69
+:10E650002072382025782C2072392025782C2072C1
+:10E6600031302025782C207231312025782C2072F1
+:10E6700031322025780A000A20202073702B3020A8
+:10E6800025303878202530387820253038782025F6
+:10E690003038780A00202073702B31302025303834
+:10E6A0007820253038782025303878202530387883
+:10E6B0000A0073702B257820253038780A006465AD
+:10E6C00061646D616E5F746F007265636C61696D2A
+:10E6D0002073656374696F6E20313A2052657475DA
+:10E6E000726E656420256420627974657320746F8E
+:10E6F0002074686520686561700A007265636C61EA
+:10E70000696D2073656374696F6E20303A205265BD
+:10E710007475726E65642025642062797465732057
+:10E72000746F2074686520686561700A0072616D9D
+:10E730007374627964697300706125643D30782573
+:10E74000257800706425643D3078252578006E7644
+:10E7500072616D5F6F7665727269646500000000BA
+:10E7600086060200D0090000800602003E3E00003E
+:10E77000820602003E020000000702003C0000008A
+:10E780008406020012020000600104000300010080
+:10E7900064010200C00000006001040003000100E9
+:10E7A000660102000A00000060010400040001008C
+:10E7B0006401020014000000600104000700010071
+:10E7C00064010200830100006001040025000100D3
+:10E7D00064010200F40100006001040096050100DC
+:10E7E000660102002B04000060010400970501008F
+:10E7F000640102000001000060010400D701010073
+:10E80000640102003C00000060010400DC01010022
+:10E81000660102003400000060010400E201010012
+:10E82000640102003000000060010400E701010003
+:10E83000660102002C00000060010400ED010100EF
+:10E84000640102002C00000060010400F2010100DC
+:10E85000660102002800000060010400F8010100C8
+:10E86000640102002800000060010400FD010100B5
+:10E870006601020028000000FFFF00000000000009
+:10E880006001040005000103640104000000190098
+:10E89000240104000400000028010400000000001E
+:10E8A0002C01040000000000300104000000000002
+:10E8B000340104000A04700034010400EFBED400E7
+:10E8C00034010400050000FF3401040001FF02FFD1
+:10E8D0003001040018000000340104000A04E000C4
+:10E8E00034010400EFBE480034010400050000FFBD
+:10E8F0003401040001FF02FF34010400001018017C
+:10E9000034010400020300103401040018F1F2F392
+:10E9100034010400BBCC0000300104006806000094
+:10E92000340104001404700034010400EFBE5801E7
+:10E9300034010400000000FF3401040001FF02FF65
+:10E94000340104000010180134010400020303091B
+:10E9500034010400BF000010340104000000000076
+:10E960003001040038000000340104000000000001
+:10E970003001040088060000340104001404800003
+:10E9800034010400EFBE1802340104000000030942
+:10E9900034010400BF00000334010400000102033D
+:10E9A00034010400040500013401040002030405DD
+:10E9B0003401040000000000300104005800000091
+:10E9C00034010400000000003001040038000000A1
+:10E9D000340104000F2000073401040000009400FB
+:10E9E000340104000000009034010400747576774F
+:10E9F00034010400000000003401040000000500A0
+:10EA000034010400FFFFFFFF300104006802000032
+:10EA1000340104006E84330034010400DCBA500079
+:10EA200034010400D40000AB34010400BADABADACD
+:10EA300034010400001018F134010400F2F3001056
+:10EA40003401040018F1F2F3340104001000000056
+:10EA500034010400000000003401040000000A003A
+:10EA6000340104000100000E340104004252434D01
+:10EA7000340104005F54455334010400545F535380
+:10EA800034010400494401043401040082848B965B
+:10EA900034010400030101063401040002000000F7
+:10EAA0003001040068000000340104000A04280258
+:10EAB00034010400DCBA8000340104000000FFFFD0
+:10EAC00034010400FFFFFFFF34010400001018F1BF
+:10EAD00034010400F2F300103401040018F1F2F3E1
+:10EAE00034010400D0AF0000340104000000000035
+:10EAF0003401040000000001340104000200000E93
+:10EB0000340104004252434D340104005F54455324
+:10EB100034010400545F5353340104004944010498
+:10EB20003401040082848B96340104000301010641
+:10EB300034010400020100003001040068040000F8
+:10EB4000340104000A04280234010400DCBA800005
+:10EB5000340104000000FFFF34010400FFFFFFFF49
+:10EB600034010400001018F134010400F2F3001025
+:10EB70003401040018F1F2F334010400D0AF0000B6
+:10EB80003401040000000000340104000000000112
+:10EB9000340104000200000E340104004252434DCF
+:10EBA000340104005F54455334010400545F53534F
+:10EBB00034010400494401043401040082848B962A
+:10EBC00034010400030101063401040002010000C5
+:10EBD0000001040000000001900402000000000099
+:10EBE000A0040200F1F30000B0040200EFFD0000F9
+:10EBF000A8040200FFFF0000A804020000000000BB
+:10EC0000AA04020000000000A4040200CF1A0000C1
+:10EC1000AC04020000000000BC0402000000000080
+:10EC2000A6040200D7020000B6040200FFFD0000A7
+:10EC3000AE040200FFFF0000060402000100000015
+:10EC400006040200000000000C040200180000008E
+:10EC5000060402000000000048040200000C00004E
+:10EC600002040200A00700000205020000000000EC
+:10EC70000005020000400000020502000400000040
+:10EC8000000502000040000002050200080000002C
+:10EC90000005020000400000020502000C00000018
+:10ECA000000502000040000002050200C000000054
+:10ECB00080050200FFFF000082050200FFFF000048
+:10ECC00084050200FFFF000086050200FFFF000030
+:10ECD00088050200FFFF00009C050200F0FF000015
+:10ECE000400502000080000020050200060F000021
+:10ECF0004005020000800000400502000081000085
+:10ED000020050200101D00004005020000810000E7
+:10ED10004005020000820000200502001E280000BD
+:10ED20004005020000820000400502000083000050
+:10ED30002005020029310000400502000083000088
+:10ED4000400502000084000020050200323F000060
+:10ED5000400502000084000040050200008500001C
+:10ED6000200502004041000040050200008500002F
+:10ED700012060200010000002E060200CDCC0000A9
+:10ED8000300602000C0000000006020004800000B3
+:10ED900096060200080000009A060200E400000047
+:10EDA00088060200000000009C060200020000002D
+:10EDB00088060200001000009C060200020000000D
+:10EDC00088060200002000009C06020002000000ED
+:10EDD00088060200003000009C06020002000000CD
+:10EDE000880602000B0F00009E06020007000000CC
+:10EDF000100502000B00000050040200014E00004C
+:10EE0000520402005B010000E404020090000000D4
+:10EE100004040200B400000054050200FF3F00009B
+:10EE2000600104000400010364010400000000000C
+:10EE300064010400B40000006401040047004700BE
+:10EE40006401040000006400640104003009400013
+:10EE5000600104000D0001036401040002000200CF
+:10EE6000640104000100800064010400050000004A
+:10EE70006401040000008000640104006400640078
+:10EE8000640104000E004700640104000005000056
+:10EE90006001040015000103640104000000420841
+:10EEA00064010400E00B0700640104000A00000094
+:10EEB000600104001A0001036401040000C0660B35
+:10EEC000600104001D00010364010400102700001C
+:10EED0006401040000007A036001040020000103C3
+:10EEE00064010400060010276001040023000103F0
+:10EEF000640104000000F606640104000000AA0A90
+:10EF00006401040000003200640104000A0E0B09D1
+:10EF1000640104000E020000640104000000520AB3
+:10EF20006401040000003F0164010400FFFF000CC5
+:10EF30006401040032046E06640104000200F20958
+:10EF4000600104002E000103640104000000008041
+:10EF50006001040032000103640104000000320B70
+:10EF60006001040034000103640104000000CC05CA
+:10EF70006001040058000103640104004252434D43
+:10EF8000640104005F54455364010400545F53530B
+:10EF900064010400494400006001040060000103B2
+:10EFA0006401040039000000640104005000000006
+:10EFB00064010400C000000060010400700001034F
+:10EFC00064010400AA03AA0364010400AA03AA03BB
+:10EFD00064010400AA03AA0364010400AA03AA03AB
+:10EFE00064010400EC03D60364010400C003AA0317
+:10EFF00064010400F703E10364010400CB03B503DB
+:10F0000064010400AA03AA0364010400AA03AA037A
+:10F0100064010400AA03AA0364010400AA03AA036A
+:10F0200064010400EC03D60364010400C003AA03D6
+:10F0300064010400F703E10364010400CB03B5039A
+:10F0400064010400020402046401040002040204D6
+:10F05000640104000E0402046401040002041A04A2
+:10F0600064010400020402046401040002040204B6
+:10F070006401040002040204640104002604020482
+:10F080006401040002040204640104000204020496
+:10F09000640104000E0402046401040002041A0462
+:10F0A0006401040002040204640104000204020476
+:10F0B0006401040002040204640104002604020442
+:10F0C0006401040000001F0064010400FF031F002E
+:10F0D000640104000200000064010400020000005A
+:10F0E00060010400980001036401040000001F0097
+:10F0F00064010400FF031F0064010400010000001C
+:10F10000640104000100000060010400A00001038C
+:10F110006401040000001F0064010400FF031F00DD
+:10F12000640104000100000064010400010000000B
+:10F1300060010400A80001036401040000001F0036
+:10F1400064010400FF031F006401040001000000CB
+:10F15000640104000100000060010400B800010324
+:10F1600064010400E700EC006401040000007B007F
+:10F17000640104007E00000064010400000000003F
+:10F180006401040000004F51640104003F000000CE
+:10F19000640104000000001060010400C0000103CD
+:10F1A0006401040037243724640104003724372421
+:10F1B0006001040093010103640104000F0040009A
+:10F1C00064010400E60600006001040097010103E9
+:10F1D000640104001A08000060010400A00101039A
+:10F1E00064010400FFFFFFFF64010400FFFFFFFF55
+:10F1F00064010400FFFFFFFF64010400FFFFFFFF45
+:10F2000064010400FFFFFFFF64010400FFFFFFFF34
+:10F2100064010400FFFFFFFF64010400FFFFFFFF24
+:10F2200060010400BC01010364010400000005004A
+:10F2300060010400C5010103640104000000100323
+:10F2400064010400E000FFFF640104000309BF0043
+:10F25000640104000000030964010400BF00001001
+:10F26000640104000309BF006401040000030000FE
+:10F2700060010400CD01010364010400FFFFFFFFF2
+:10F2800064010400FFFFFFFF64010400FFFFFFFFB4
+:10F2900064010400FFFFFFFF64010400FFFFFFFFA4
+:10F2A00064010400FFFFFFFF64010400FFFFFFFF94
+:10F2B00064010400FFFFFFFF640104002000CB0194
+:10F2C0006401040000005400640104000000AB0865
+:10F2D00064010400000010046401040084000200C2
+:10F2E000640104000000140064010400CF01020066
+:10F2F000640104004400000064010400AF0802003F
+:10F3000064010400100464006401040002020000AF
+:10F31000640104001000CA016401040002003C0002
+:10F32000640104000000AA08640104000200100443
+:10F330006401040054000208640104000000080095
+:10F3400064010400CE0100006401040034000000E8
+:10F3500064010400AE0800006401040010044400CD
+:10F3600064010400020A0000640104000800C901ED
+:10F370006401040002003000640104000000A908D8
+:10F380006401040002001004640104003C00021047
+:10F39000640104000000040064010400CD010000C9
+:10F3A000640104002C00000064010400AD080000AA
+:10F3B000640104001004340064010400021200001F
+:10F3C000640104000400C8016401040000002C0072
+:10F3D000640104000000A808640104000000100497
+:10F3E0006401040030000219640104000000000000
+:10F3F00064010400CC010200640104002C00000040
+:10F4000064010400AC080200640104001004300030
+:10F4100064010400021A000064010400C0000A0430
+:10F420006401040070000000640104003A010A0451
+:10F430006401040028022CC064010400F2020A04E2
+:10F440006401040000000001640104006000140471
+:10F450006401040038000000640104000201140487
+:10F460006401040014012CC064010400DE011404D2
+:10F4700064010400000080006401040022003704DD
+:10F48000640104001500000064010400DF0037047B
+:10F490006401040065002CC0640104002E013704DF
+:10F4A0006401040000002F006401040011006E8458
+:10F4B000640104000B00000064010400D4006E84A9
+:10F4C0006401040033002CC064010400FC006E845D
+:10F4D00064010400000018006401040002008A9D19
+:10F4E00064010400FB00020864010400C54EFA0038
+:10F4F00064010400020A833464010400FE00021067
+:10F50000640104006227F900640104000212421A37
+:10F5100064010400FD00021964010400B113F80045
+:10F5200064010400021A811164010400FC00021C41
+:10F5300064010400C10FFC00600104007B030103AF
+:10F540006401040007001400640104001E000000B0
+:10F55000600104008303010364010400000000F063
+:10F5600064010400C3301092640104005031802211
+:10F5700064010400C330000060010400880301033B
+:10F580006401040000001004600104008C03010306
+:10F590006401040080000000600104008E03010388
+:10F5A0006401040005000000600104000B04010375
+:10F5B0006401040000000702600104001404010358
+:10F5C000640104000100000060010400160401034E
+:10F5D000640104000C0000006001040053050103F5
+:10F5E00064010400000018006001040055050103D7
+:10F5F00064010400983A983A64010400A60E64007D
+:10F60000640104000000F40164010400050000002E
+:10F6100064010400A861A8616401040030751E0043
+:10F62000600104005D0501036401040050C3000093
+:10F63000600104005F05010364010400000014057B
+:10F640006401040050C3000060010400630501036D
+:10F6500064010400204E00006401040000000F005B
+:10F6600064010400F4010400600104006905010361
+:10F670006401040000003100640104000000030084
+:10F68000640104000100070064010400C8AF000029
+:10F690006401040088130000640104002C17FF00BB
+:10F6A00060010400700501036401040000002C01E6
+:10F6B000640104000000A00F600104007305010351
+:10F6C00064010400000003006401040000002C0138
+:10F6D00064010400C00000006401040088130000FD
+:10F6E000640104006400000064010400DC05401FA4
+:10F6F000600104007A0501036401040001000100B7
+:10F700006401040002000000600104007D050103A3
+:10F710006401040002000000640104000000409C39
+:10F7200064010400204E000064010400B80B0000D6
+:10F730006001040082050103640104000000204E02
+:10F74000640104000000050064010400DC053F00C2
+:10F7500064010400710200006401040030750000BF
+:10F76000600104008A05010364010400C409A00FBC
+:10F77000600104008D050103640104000A00D00744
+:10F78000600104008F05010364010400204E204E37
+:10F79000600104009505010364010400BE0000003F
+:10F7A00060010400B105010364010400E8030000E6
+:10F7B00060010400ED050103640104000000000085
+:10F7C00060010400F60501036401040088130000D1
+:10F7D0006001040003000200640104001F00000037
+:10F7E000600104000400020064010400FF03000043
+:10F7F0006001040005000200640104001F00000015
+:10F80000600104000600020064010400070000001B
+:10F81000600104000700020064010400040000000D
+:10F82000600104000800020064010400FFFF000002
+:10F8300060010400090002006401040000000000EF
+:10F84000600104000A0002006401040000000000DE
+:10F85000600104000B0002006401040000000000CD
+:10F86000600104000C0002006401040000000000BC
+:10F87000600104000D0002006401040000000000AB
+:10F88000600104000E00020064010400000000009A
+:10F89000600104000F000200640104000000000089
+:10F8A0006001040010000200640104001F00000059
+:10F8B0006001040011000200640104000000000067
+:10F8C0006001040012000200640104000000000056
+:10F8D0006001040013000200640104000000000045
+:10F8E0006001040015000200640104000000000033
+:10F8F0006001040016000200640104000000000022
+:10F90000FFFF000000000000636275636B5F7377A8
+:10F910006672657100000000E02E010101500000D8
+:10F9200000000000C832020101490000899DD80092
+:10F930004038030101420000AAAAAA00003C0401C9
+:10F94000013E000000008000483F05010139000031
+:10F95000D05E4200A0410601013900004992240016
+:10F96000004B07010132000000000000584D080163
+:10F9700001300000071F7C00204E0901013000000B
+:10F9800000000000A8610A0101260000666666000A
+:10F9900090650B0101240000C44EEC0030750C0191
+:10F9A000012000000000000018920D020133000049
+:10F9B000F93E560000960E020132000000000000E1
+:10F9C000409C0F02013000000000000080BB1002CC
+:10F9D00001280000000000000000000000000000FE
+:10F9E0000000000009FA0100000000000800080003
+:10F9F00008FA01000100000008000B0000000000F0
+:10FA000000000000000000006D6B6565705F616CB8
+:10FA100069766500746F655F6F6C00746F655F7306
+:10FA20007461747300746F655F73746174735F6382
+:10FA30006C65617200AAAA030000000014FA0100BC
+:10FA400000000000070000001BFA01000100000098
+:10FA500008004C0025FA0100020000000000000030
+:10FA6000000000000000000000000000D58D8600AE
+:10FA70000C00800001000000A98E86000B00000031
+:10FA800001000000B58E86000300000005000000A4
+:10FA9000C18E86000400000007000000D08E8600A2
+:10FAA00005008000010000000000000000000000D0
+:10FAB000000000005B574C414E5D636F756E742013
+:10FAC0003D2025640A000000D550830021578300A3
+:10FAD0000000000000000000627461006274616D4B
+:10FAE00070006274616D705F666C61677300627450
+:10FAF000616D705F6368616E006274616D705F312B
+:10FB0000316E5F737570706F7274006274616D70C6
+:10FB10005F6662006274616D705F73746174656CBE
+:10FB20006F6700414D502D253032782D25303278C9
+:10FB30002D253032782D253032782D253032782D14
+:10FB400025303278000000007DC5860000000000EE
+:10FB50000800240084C586000100000008000000A1
+:10FB600093C586000200000008000C00A4C58600B2
+:10FB7000030000000800E402AFC586000400000096
+:10FB800007000000C0C58600050000000800240032
+:10FB9000C9C586000600000001000000D1C586002E
+:10FBA0000700000007000000DBC586000800000019
+:10FBB0000100000049C586000900000001000000A6
+:10FBC000000000000000000000000000776C635F90
+:10FBD00061757468656E74696361746F725F646F78
+:10FBE000776E0025733A2063616C6C65640A00705F
+:10FBF000617463685F696F76617273006F747072AD
+:10FC00006177006175746800666162696400616DA6
+:10FC10007064755F727473005856000243004000B0
+:10FC2000207986000000004003000000FCFB01007A
+:10FC300007000800080000003D7D860001000880E4
+:10FC40000800000003FC0100020000400600000064
+:10FC50004FDB0100030010000700000008FC01005A
+:10FC60000400000005000000647D8600050000001F
+:10FC700008001C000EFC010006000000010000004E
+:10FC80000000000000000000000000004D84FF8321
+:10FC90004CC4001FB784FF80B184FFDFB0C40808E4
+:10FCA000FA84F7FFF9C4080001006C090200710929
+:10FCB0000300760904007B09050080090600850918
+:10FCC00007008A0908008F09090094090A009909A8
+:10FCD0000B009E090C00A3090D00A8090E00B40931
+:10FCE000CC0102000000D400000000000000000170
+:10FCF0000000000000002D00A7901A0047090E0028
+:10FD0000012007008B93030038CA01002AE5000098
+:10FD1000977200004C390000A61C0000530E000032
+:10FD20002907000095030000CA010000E50000005B
+:10FD300073000000390000001D0000006E840B00FD
+:10FD40000000D400000000000000000100000000DE
+:10FD50006030180C6C482412776C25643A20536389
+:10FD6000616E20696E2070726F67726573732C20EC
+:10FD7000736B697070696E67207478706F776572E5
+:10FD800020636F6E74726F6C0A00706F77657220FB
+:10FD900061646A210A002E6661622E0025732E6658
+:10FDA00061622E25640063636B6277323032677064
+:10FDB0006F0063636B62773230756C3267706F000F
+:10FDC0006C65676F66646D627732303267706F00A2
+:10FDD0006C65676F66646D62773230756C32677020
+:10FDE0006F006D6373627732303267706F006D63DE
+:10FDF0007362773230756C3267706F006D63736257
+:10FE00007734303267706F006C65676F66646D625F
+:10FE100077323035676C706F006C65676F66646D44
+:10FE200062773230756C35676C706F006C65676F28
+:10FE300066646D6277323035676D706F006C656730
+:10FE40006F66646D62773230756C35676D706F0008
+:10FE50006C65676F66646D62773230356768706FA6
+:10FE6000006C65676F66646D62773230756C3567FC
+:10FE700068706F006D63736277323035676C706FD6
+:10FE8000006D637362773230756C35676C706F002C
+:10FE90006D63736277343035676C706F006D6373B8
+:10FEA0006277323035676D706F006D6373627732E1
+:10FEB00030756C35676D706F006D637362773430C9
+:10FEC00035676D706F006D637362773230356768C8
+:10FED000706F006D637362773230756C3567687070
+:10FEE0006F006D637362773430356768706F006DD3
+:10FEF00063733332706F006C65676F66646D3430A6
+:10FF0000647570706F00616E7473776974636800F4
+:10FF1000616135670074737369706F733267006570
+:10FF2000787470616761696E3267007064657472BD
+:10FF3000616E6765326700747269736F3267006162
+:10FF40006E74737763746C32670074737369706F67
+:10FF50007335670065787470616761696E35670035
+:10FF60007064657472616E67653567007472697379
+:10FF70006F356700616E74737763746C35670070FA
+:10FF80006132677730613300706132677731613396
+:10FF9000006D61787032676130006D617870326732
+:10FFA00061310070613267773061300070613267B3
+:10FFB0007730613100706132677731613000706194
+:10FFC00032677731613100706132677732613000BA
+:10FFD0007061326777326131006D61787035676CBE
+:10FFE0006130006D61787035676C6131007061352A
+:10FFF000676C7730613000706135676C77306131E4
+:020000022000DC
+:1000000000706135676C7731613000706135676C05
+:100010007731613100706135676C77326130007023
+:100020006135676C77326131006D61787035676179
+:1000300030006D61787035676131007061356777C8
+:100040003061300070613567773061310070613543
+:1000500067773161300070613567773161310070E9
+:1000600061356777326130007061356777326131B1
+:10007000006D6178703567686130006D617870354A
+:100080006768613100706135676877306130007092
+:100090006135676877306131007061356768773145
+:1000A00061300070613567687731613100706135AA
+:1000B0006768773261300070613567687732613127
+:1000C000006D61787035676133006D6178703567F8
+:1000D0006C61330070613567773061330070613572
+:1000E000676C773061330070613567773161330059
+:1000F000706135676C7731613300706135677732D5
+:10010000613300706135676C773261330062773438
+:1001100030706F00636464706F0073746263706F3B
+:10012000006277647570706F00747870696432670C
+:100130006130007478706964326761310069747489
+:100140003267613000697474326761310063636BD8
+:100150003267706F006F66646D3267706F006D6339
+:10016000733267706F30006D63733267706F310088
+:100170006D63733267706F32006D63733267706FD7
+:1001800033006D63733267706F34006D6373326771
+:10019000706F35006D63733267706F36006D637317
+:1001A0003267706F3700747870696435676C6130DE
+:1001B00000747870696435676C6131006F66646DD6
+:1001C00035676C706F006D637335676C706F3000EE
+:1001D0006D637335676C706F31006D637335676C79
+:1001E000706F32006D637335676C706F33006D63D1
+:1001F0007335676C706F34006D637335676C706F47
+:1002000035006D637335676C706F36006D637335E1
+:10021000676C706F3700747870696435676130009F
+:100220007478706964356761310069747435676129
+:10023000300069747435676131006F66646D3567CD
+:10024000706F006D63733567706F30006D63733569
+:1002500067706F31006D63733567706F32006D6367
+:10026000733567706F33006D63733567706F34007B
+:100270006D63733567706F35006D63733567706FCD
+:1002800036006D63733567706F370074787069641A
+:10029000356768613000747870696435676861310A
+:1002A000006F66646D356768706F006D63733567E6
+:1002B00068706F30006D6373356768706F31006D03
+:1002C0006373356768706F32006D6373356768708C
+:1002D0006F33006D6373356768706F34006D6373DF
+:1002E000356768706F35006D6373356768706F369A
+:1002F000006D6373356768706F3700656C6E6132CF
+:100300006700656C6E6135670074656D706F666659
+:100310007365740070687963616C5F74656D706497
+:10032000656C7461000C1218243048606C003CC489
+:1003300007003BC407004C84FFE0B084F7F7F98462
+:10034000F7FF000008040200350108300800030030
+:100350001204020043010000010000001C0402001E
+:1003600048010800030000002C04020049010800B5
+:1003700003000000390402004A01080003000000E5
+:10038000470402004E01080003000000520402006E
+:100390003D014000070007005E0402007A010004EE
+:1003A000070000006C0402003F010000060000008E
+:1003B00077040200400100000200000082040200F5
+:1003C0007C010000020000008F04020042010000D6
+:1003D000070000009B040200280008000300000042
+:1003E000AC0402002900000001000000B904020072
+:1003F0007F0100000200000000000000000000007B
+:1004000000000000706879007478696E737470770A
+:1004100072007068795F6D75746564007068795FEB
+:10042000676C697463687468727368007068795F78
+:100430006E6F6973655F7570007068795F6E6F6964
+:1004400073655F64776E007068795F706572636171
+:100450006C007068795F7278697165737400706898
+:10046000796E6F6973655F73726F6D006E756D5F26
+:1004700073747265616D0062616E645F72616E6754
+:10048000650073756262616E643567766572006DD2
+:10049000696E5F7478706F776572007068795F6FEE
+:1004A000636C736364656E61626C65007068795F2C
+:1004B0007278616E7473656C007068795F637273D3
+:1004C0005F7761720000EB04C00100006A04FFFF67
+:1004D000190036001A013A00250028000500120113
+:1004E000FF001F010B0013010700FC00FD00FF00CF
+:1004F000C000CA00C5001200570059005C00780017
+:100500009200980016012C016A000B001B001301D9
+:100510001D0014012E002A011201F904010001003E
+:10052000FA04010000004C04001800184D0400609B
+:1005300000603809FF01FF013909FF019E003B04FB
+:10054000030003003C0403000000DA46FFFFDBC6A3
+:100550000300D10604000400977A977A977A977A75
+:10056000877A877A977B000006000000060000006B
+:1005700006000000060000003809040004003909E4
+:1005800004000400A404001000104AC444004A44BB
+:1005900080004AC444004A448000A4040040000093
+:1005A000A40400800080D00420000000A404FF0107
+:1005B0000000A504FF00FF00A50400700050A50482
+:1005C000000700000D04FF0040000D0400070004B8
+:1005D000A204FF004000A20400070004A804FF00DA
+:1005E0000100D70401000100D704400000003706D5
+:1005F00000C00080810400020002B704007F006C8C
+:10060000B10400200000390900020000380900028E
+:100610000002B00408000800B0040008000839090E
+:10062000000800003809000800081004080008004D
+:10063000DA062000000003050100000003050400A5
+:100640000000A40400400000A40400800000D004C6
+:1006500020000000A504FF00FF00A504007000506A
+:10066000A504000700000D04FF0040000D04000772
+:100670000006A204FF004000A20400070006D904FF
+:1006800070002000D90400070003D9040070001096
+:10069000DA0400100000DA0400200020A604008024
+:1006A0000080D70408000800D70400700010D904A7
+:1006B00004000000D9040800080000000000000049
+:1006C0000000000000000000FFEEDDCCBB99887741
+:1006D0006655443322110000DA46FFFF0305080087
+:1006E000080025642009202564200A004572726FE5
+:1006F000722067657474696E67206C6F772069710A
+:10070000206573740A004572726F72206765747495
+:10071000696E672068696768206971206573740A6B
+:1007200000004AC480004A847F00D0040200000018
+:10073000D204FF000000D20400FF0000D004080033
+:1007400000004C04000800084D0400200000B00424
+:1007500000010001B644FFFFB7040F000F004C0476
+:10076000000800084D0400200020B0040001000132
+:100770003B04010001003C04010001003C040100B5
+:1007800000003B04010000004AC444004A448000C9
+:10079000DAC64000DBC60300DA06200020001004A1
+:1007A00008000000A60400800080A604FF01FF00EE
+:1007B0009A04FF01FF008007000400048007000284
+:1007C0000002D60603000000DA06080008004249CD
+:1007D00002003B4900003C49000076068000000012
+:1007E000DA06010000006C08040000006C084000FC
+:1007F00000006C0800040000D70408000000D804C2
+:1008000001000000D804020000003B0404000400C2
+:100810003C04040000003B04040004003C04040009
+:10082000000084806782568034823B04010001000E
+:100830003C04010001003C04010000003B040100F5
+:1008400000003B04020002003C04020002003C04E1
+:10085000020000003B0402000000977A977A977A22
+:10086000977A877A877A977B0F0900090109060929
+:10087000070908090209030909090A090B090409FA
+:1008800005090C090D090E09110987466000424649
+:1008900007003B84EDFF3C04020002004C84D0EFD3
+:1008A0004D84D7BF4D04040004004D040300010033
+:1008B000F984F8FFFA84F8FF3B04020002003C04CC
+:1008C000020000003B04100010003C044000000047
+:1008D0004C04001000104D04004000404D04040082
+:1008E00000004C04040004004C04080008004D04FF
+:1008F000080000004C04200020004D0420002000CF
+:10090000F90402000200FA0402000000F9040400E5
+:100910000400FA0404000000F90401000100FA04D4
+:1009200001000000DB04FF03A602DB0400700020CE
+:100930009A05FF0326009B05FF03A5009C05FF0306
+:10094000A6009C0500FC00289D05003C001C9D05A0
+:10095000FF03A800A40400800080A404004000401D
+:10096000A40400200020B004800000003B044000EC
+:100970000000A904008000802184238434838480C3
+:100980006782568034823B04020002003C0402006D
+:1009900000003B04100010003C04400000004B44E9
+:1009A000FFFFB10400040000B1040080000038091A
+:1009B00040004000380904000400390940000000EC
+:1009C000390904000400D70402000200D7048000A3
+:1009D0000000D70401000100D70440004000D70404
+:1009E00008000800D70400700020DA06400040002C
+:1009F000A40400200000D70408000800D7040070F9
+:100A0000002031C61500D60603000000DAC68F00AC
+:100A1000100480000000A8440A000305A404D004C8
+:100A2000D904DA04A60438093909D804D004D70453
+:100A3000A5040D04A2044C04001000104D04004055
+:100A400000404C04000800084D04002000003B0456
+:100A5000020002003C04020000003B04010001000F
+:100A60003C04010000004C04080008004D0408008C
+:100A700008004C04200020004D0420000000F90470
+:100A800002000200FA0402000200F904040004005B
+:100A9000FA0404000400F90401000100FA04010052
+:100AA00001005344A90A3D49C000000000000000B5
+:100AB000000000000000000000000000977A877A24
+:100AC000877A977B760680008000DA0601000100B5
+:100AD0006C08040004006C08400040006C0800042E
+:100AE000000410091E091F092409250926092009E7
+:100AF000210927092809290922092309300931096F
+:100B000032091209D7440000D70401000100D704BC
+:100B100040000000D70401000100D704400040005D
+:100B20001004020000001004010000001004020084
+:100B30000000100401000100100402000200100473
+:100B4000010000007A46030073467017744644049F
+:100B500075463F00704681068C4649004AC44400F1
+:100B60004A448000004001400240034004400540E8
+:100B700006400740075B0780A3C60100A386FEFF6F
+:100B80000700FF001F013A001A01050082008600DD
+:100B90002E0113017D002800340600FF0000DAC694
+:100BA00080000AC02802760680000000DA060100F4
+:100BB00000006C08040000006C08400000006C0895
+:100BC00000040000D80401000000D8040200000066
+:100BD000D704080000004C84FFE73B840C005384DA
+:100BE000FF7F53C40080424907003B4917203C491E
+:100BF000C527D60603000100DA0608000000DA0661
+:100C0000800000000A46A0006A4419000F0900098C
+:100C100001090609070908090209030909090A095E
+:100C20000B09040905090C090D090E091109C9462A
+:100C300000068046FF0081463F01CE460000CB46BD
+:100C40000000CC460000CD4600009D46FF07A446AC
+:100C50000000A5460000D90404000400D9040800DF
+:100C60000000A40400400040A40400400000DAC6D4
+:100C700040000100D70408000800D70400700030CD
+:100C80004AC444004A4480003B0404000000380980
+:100C900040000000380904000000D70402000000F2
+:100CA000D70401000000D70408000000D8040100A8
+:100CB0000000D8040200000000FC070069A5050040
+:100CC000FF010000695D0A0000040800975E0A0049
+:100CD0000102000097A60500D70401000100D70417
+:100CE00040004000D70401000000D90401000100C9
+:100CF000D904020000000000AA0A02009A05FF03BE
+:100D000026009B05FF0389009C05FF038A009C05C4
+:100D100000FC00209D05003C002C9D05FF038C007D
+:100D20003B04010001003C040100000038090008F8
+:100D30000008390900080008DA0600800080D306A0
+:100D400000800080D30600800000DA0600800000EA
+:100D50000A80D7FDDA867FFFD7C6010031C60018AA
+:100D60003B4400003C4400004C440000E6440000CA
+:100D7000F9440000B044000038490000B0440000CD
+:100D80004E44000067C503004AC444004A44800042
+:100D90004804000300010806FF0017000406FF07CF
+:100DA000EA0342490F004249000042490F004A4409
+:100DB00084004A448000D3462222D34620223B4965
+:100DC00017203C49C5270305010000000305040066
+:100DD00000000305100010004249000042490F00C6
+:100DE000424900003B4917003C49C5074AC444003A
+:100DF0004A448000D70408000000D7040070002097
+:100E0000380904000400390904000400A404001097
+:100E10000010D70404000400D704000F00008B4624
+:100E200000007646A1B816012D012C016A00980039
+:100E300097002F010B0013011D0014012E002A0141
+:100E400009001F010700FF000500D0040100000099
+:100E5000D304FF000000D30400FF0000D004100002
+:100E60000000D004040000003A0980008000230440
+:100E7000FF0049003404FF00FCFF1604FF00A4FF3C
+:100E8000160400FF009F240400FF002A230400FF33
+:100E9000002D2504FF000F000005FF000F000005D6
+:100EA00000FF000F2004FF000A00340400070001C7
+:100EB0003204FF00BF00320400FF00B8FF0400FC52
+:100EC0000018D106040000004B06400040002184B9
+:100ED0002384348384806782568034824B060100E9
+:100EE00001004B06080008005F36291F5F36291FE6
+:100EF0005F36291F5F36291F000000000000000038
+:100F000000000000000000000000000000000000E1
+:100F100000000000000000000400000000000000CD
+:100F200004000000080000000100000005000000AF
+:100F3000090000000D0000004D0000008D000000C1
+:100F40000D0000004D0000008D000000CD000000ED
+:100F50005200000092000000D2000000D600000005
+:100F600016010000160500001609000056090000D1
+:100F7000560D000056110000961100009651000019
+:100F80009691000096D1000096110100000000002B
+:100F90000000000000000000000000000000000051
+:100FA0000000000004000000000000000400000039
+:100FB000080000000100000005000000090000001A
+:100FC0000D0000004D0000008D0000000D0000002D
+:100FD0004D0000008D000000CD0000005200000018
+:100FE00092000000D2000000D600000016010000B0
+:100FF000160500001609000056090000560D0000F5
+:1010000056110000565100005691000056D10000C4
+:1010100056110100565101005691010056D10100B0
+:1010200000000000000000000000000000000000C0
+:1010300000000000000000000000000000000000B0
+:1010400000000000000000000000000000000000A0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:1010700000000000000000000A0009000600050052
+:101080000A000900060005000A0009000600050024
+:101090000A000900060005000A0009000600050014
+:1010A0000A000900060005000A0009000600050004
+:1010B0000A000900060005000A00090006000500F4
+:1010C0000A000900060005000A00090006000500E4
+:1010D0000A000900060005000A00090006000500D4
+:1010E0000A000900060005000A00090006000500C4
+:1010F0000A000900060005000E00000000020003BF
+:10110000000400060008000B00100110021003107C
+:10111000041005100610071007170720072D0740B9
+:1011200000000000000000000000000000000000BF
+:1011300000000000000000000000000000020003AA
+:10114000000400060008000B00100110021003103C
+:10115000041005100610071007170720072D074079
+:10116000000000000000000000000000000000007F
+:10117000000000000000000000000000000000006F
+:10118000000000000000000000000000000000005F
+:10119000000000000000000000000000000000004F
+:1011A00000000000000000000000004000000000FF
+:1011B000000000000000000000000000000000002F
+:1011C000000000000000000000000000000000001F
+:1011D000000000000000000000000000000000000F
+:1011E00000000000000000000000000000000000FF
+:1011F00000000000000000000000000000000000EF
+:1012000000000000000000000000000000000000DE
+:1012100000000000000000000000000000000000CE
+:1012200000000000000000000000000000000000BE
+:1012300000000000000000000000000000000000AE
+:10124000000000000000000000000000000000009E
+:1012500000000000F8410100F8210000FB2100001F
+:10126000FB410000DBFE01007B2100003321000078
+:10127000EB400000A3FE01004B0200004D014D01B8
+:101280004D014D014D014D014D014D014D014D01EE
+:101290004D014D014D014D014D014D014D014D01DE
+:1012A0004D014D014D014D014D014D014D014D01CE
+:1012B0004D014D014D014D014D014D014D014D01BE
+:1012C0004D014D014D014D014D014D014D014D01AE
+:1012D0004D014D014D014D014D014D014D014D019E
+:1012E0004D014D014D014D014D014D014D014D018E
+:1012F0004D014D014D014D014D014D01090F1418D6
+:10130000FE070B0FFBFE0105080B0E111417000062
+:1013100000000000000306090C0F1200000000008E
+:1013200000000000000306090C0F1215181B000036
+:101330000000000003EB000001001000100020007E
+:101340000100300010004000220050002201600027
+:101350002202700022038000220490002205A000D7
+:101360002206B0002207C0002208D0002209F000A7
+:10137000220A1000220B2000220C3000220D400017
+:10138000220E5000220F600000000000000000004C
+:10139000000000000000000000000000000000004D
+:1013A0000000000000000000040000000000000039
+:1013B000040000000800000001000000050000001B
+:1013C000090000000D0000004D0000008D0000002D
+:1013D0000D0000004D0000008D000000CD00000059
+:1013E0004F0000008F000000CF000000D30000007D
+:1013F0001301000013050000130900005309000049
+:10140000530D000053110000931100009351000090
+:101410009391000093D1000093110100000000009F
+:1014200000000000000000000000000000000000BC
+:1014300000000000040000000000000004000000A4
+:101440000800000001000000050000000900000085
+:101450000D0000004D0000008D0000000D00000098
+:101460004D0000008D000000CD0000004F00000086
+:101470008F000000CF000000D30000001301000027
+:10148000130500001309000053090000530D00006C
+:1014900053110000535100005391000053D100003C
+:1014A00053110100535101005391010053D1010028
+:1014B000000000000000000000000000000000002C
+:1014C000000000000000000000000000000000001C
+:1014D000000000000000000000000000000000000C
+:1014E00000000000000000000000000000000000FC
+:1014F00000000000000000000000000000000000EC
+:1015000000000000000000000104020403040404C1
+:10151000050406040704080409040A048B058C0565
+:101520008D058E058F059000910092009301940126
+:10153000950196019701980199019A019B019C01DF
+:101540009D019E019F01A001A101A201A301A4018F
+:10155000A5010000010101010101010101010101D9
+:10156000010101010101010101010101010101016B
+:101570000101020301030201010101010101010155
+:10158000010101010101010101010101010101014B
+:10159000010101010101010101010101010101013B
+:1015A000010101010101010101010101010101012B
+:1015B0000101020301030201010101010101010115
+:1015C000010101010101010101010101010101010B
+:1015D000010101017C120200400000000200000035
+:1015E0000000000010000000D411020040000000C4
+:1015F0000100000000000000100000005412020072
+:101600000A0000000B0000000000000020000000A5
+:1016100038130200140000000C000000000000005D
+:1016200020000000A41A0200940000000D00000039
+:101630000000000020000000081502002600000045
+:101640000E000000000000001000000078100200F2
+:10165000400000000F00000000000000100000002B
+:10166000081D020010000000100000000000000033
+:1016700008000000FC1202003C0000001100000005
+:101680000000000008000000881302006000000055
+:1016900012000000000000002000000054150200AD
+:1016A000800000001400000000000000080000009E
+:1016B000EC1602009A000000170000000000000075
+:1016C00010000000FC1002006C0000000000000090
+:1016D000000000001000000020180200A000000020
+:1016E0001800000000000000200000001A00340074
+:1016F0004E0068009C00D000EA000401340068003D
+:101700009C00D0003801A001D40108024E009C00CA
+:10171000EA003801D4017002BE020C036800D00058
+:101720003801A00170024003A803100418009C00B7
+:10173000D0000401EA0038018601D0000401040150
+:1017400038016C016C01A001380186018601D401C9
+:10175000220222027002040138016C0138016C017E
+:10176000A001D401A001D401080208023C028601B4
+:10177000D4012202D40122027002BE027002BE0213
+:101780000C030C035A0336006C00A200D80044017D
+:10179000B001E6011C026C00D8004401B0018802CF
+:1017A0006003CC033804A2004401E6018802CC03A4
+:1017B0001005B2055406D800B00188026003100578
+:1017C000C0069807700818004401B0011C02E60129
+:1017D00088022A03B0011C021C028802F402F402EF
+:1017E000600388022A032A03CC036E046E041005EA
+:1017F0001C028802F4028802F4026003CC03600336
+:10180000CC0338043804A4042A03CC036E04CC03AC
+:101810006E041005B2051005B20554065406F6060E
+:101820000000080000000800000008000000080098
+:101830000000080000000800000008000000080088
+:101840000000080000000800000008000000080078
+:101850000000080000000800000008000000080068
+:101860000000080000000800000008000000080058
+:101870000000080000000800000008000000080048
+:101880000000080000000800000008000000080038
+:101890000000080000000800000008000000080028
+:1018A0000000080000000800000008000000080018
+:1018B0000000080000000800000008000000080008
+:1018C00000000800000008000000080000000800F8
+:1018D00000000800000008000000080000000800E8
+:1018E00000000800000008000000080000000800D8
+:1018F00000000800000008000000080000000800C8
+:1019000000000800000008000000080000000800B7
+:1019100000000800000008000000080000000800A7
+:101920000000080000000800000008000000080097
+:101930000000080000000800000008000000080087
+:101940000000080000000800000008000000080077
+:101950000000080000000800000008000000080067
+:101960000000080000000800000008000000080057
+:101970000000080000000800000008000000080047
+:101980000000080000000800000008000000080037
+:101990000000080000000800000008000000080027
+:1019A0000000080000000800000008000000080017
+:1019B0000000080000000800000008000000080007
+:1019C00000000800000008000000080000000800F7
+:1019D00000000800000008000000080000000800E7
+:1019E00000000800000008000000080000000800D7
+:1019F00000000800000008000000080000000800C7
+:101A000000000800000008000000080000000800B6
+:101A100000000800000008000000080000000800A6
+:101A20000000080000000800000008000000080096
+:101A30000000080000000800000008000000080086
+:101A40000000080000000800000008000000080076
+:101A50000000080000000800000008000000080066
+:101A60000000080000000800000008000000080056
+:101A70000000080000000800000008000000080046
+:101A80000000080000000800000008000000080036
+:101A90000000080000000800000008000000080026
+:101AA0000500000000000000000000000000001021
+:101AB00000000000000000200000000000000030D6
+:101AC0000000000000000040000000000000005086
+:101AD0000000000000000060000000000000007036
+:101AE00000000000000000800000000000000090E6
+:101AF00008000000000000A008000000000000B086
+:101B000008000000000000C008000000000000D035
+:101B100008000000000000E008000000000000F0E5
+:101B20000800000000000000090000000000001094
+:101B30000900000000000020190000000000003033
+:101B400019000000000000401900000000000050D3
+:101B50001900000000000060190000000000007083
+:101B60001900000000000080190000000000009033
+:101B700019000000000000A019000000000000B0E3
+:101B800019000000000000C019000000000000D093
+:101B900019000000000000E019000000000000F043
+:101BA00019000000000000001A00000000000010F2
+:101BB0001A000000000000201A00000000000030A1
+:101BC0001A000000000000401A0000000000005051
+:101BD0000200000000000060020000000000007031
+:101BE00002000000000000800200000000000090E1
+:101BF00002000000000000A002000000000000B091
+:101C000002000000000000C00A000000000000D038
+:101C10000A000000000000E00A000000000000F0E0
+:101C20000A000000000000000B000000000000108F
+:101C30000B000000000000200B000000000000303E
+:101C40000B000000000000400B00000000000050EE
+:101C50001B000000000000601B000000000000707E
+:101C60001B000000000000801B000000000000902E
+:101C70001B000000000000A01B000000000000B0DE
+:101C80001B000000000000C01B000000000000D08E
+:101C90001B000000000000E01B000000000000F03E
+:101CA0001B000000000000001C00000000000010ED
+:101CB0001C000000000000201C000000000000309C
+:101CC0001C000000000000401C000000000000504C
+:101CD0001C000000000000601C00000000000070FC
+:101CE0001C000000000000801C00000000000090AC
+:101CF0001C000000F80E020060000000120000004E
+:101D000000000000200000005F36291F5F36291FF9
+:101D10005F36291F5F36291FE80E02001000000001
+:101D200010000000000000000800000090E886009D
+:101D30000000800001000000000000000000000022
+:101D4000000000007363616E0000000044EB860039
+:101D50000100204005000000A2A5860002002040EE
+:101D60000500000090A5860003002040050000004B
+:101D70007EA58600040020400500000075998600BD
+:101D80000500104005000000EBE88600060020403A
+:101D9000020000004CEB86000C0000000100000077
+:101DA0005EEB860007002000080000000000000035
+:101DB00000000000000000006E6F63726300534477
+:101DC000494F0043444300000D1680008D138000EE
+:101DD00025118000291480001D138000A1168000A9
+:101DE000A90F0100011380002D13800000000000E6
+:101DF0001D168000E9270000776C0000000000003D
+:101E00000000000000000000F025000000000000BD
+:101E100000000000000000000000000000000000C2
+:101E20000000000005000000FFFFFFFF140000009D
+:101E30000100050605000000FFFFFFFF0500000090
+:101E400005000000050000000E0E0E0E0E02090D2A
+:101E50000A080D01090D0A080D01090D0A080D01F6
+:101E6000090D0A080D01090E0A090E060A0E0B09D2
+:101E70000E02093A160E0E05093A160E0E050A0E46
+:101E80000B090E050A0E0B090E020A0E0B090E02B3
+:101E900014C0C015110514C0C015110514C0C0151B
+:101EA000110514C0C015110514C0C0151105093A5B
+:101EB000160E0E0514C0C015110514C0C01511056D
+:101EC000093A160E0E05093A160E0E05093A160EB7
+:101ED0000E0514C0C0151105093A160E0E05093A73
+:101EE000160E0E05093A160E0E0509B21C0E0E0549
+:101EF00012B11911110800000000000000000000DC
+:101F00000000000065660200416602002D660200C6
+:101F100055AA80000000000021AA800085AA800048
+:101F200031AA80006DAA8000C993800095A9800025
+:101F3000BDA98000D5938000B59380007593800083
+:101F4000D191800000000000B1A98000736470632B
+:101F50006D6465760000000000000000041F0200B0
+:101F60000000000000000000000000000000000071
+:101F70000000000000000000000000000000000061
+:101F80000000000000000000000000000000000051
+:101F90000000000000000000000000000000000041
+:101FA0000000000000000000000000000000000031
+:101FB0000000000000000000000000000000000021
+:101FC0000000000000000000000000000000000011
+:101FD0000000000000000000000000000000000001
+:101FE00000000000000000000000000000000000F1
+:101FF00000000000000000000000000000000000E1
+:1020000000000000000000000000000000000000D0
+:1020100000000000000000000000000000000000C0
+:1020200000000000000000000000000000000000B0
+:1020300000000000000000000000000000000000A0
+:102040000000000000000000000000000000000090
+:102050000000000000000000000000000000000080
+:102060000000000000000000000000000000000070
+:10207000000000000000000004E301004100000037
+:10208000440000000000000000000000000000000C
+:102090000000000000000000000000000000000040
+:1020A0000000000000000000000000000000000030
+:1020B0000000000000000000000000000000000020
+:1020C0000000000000000000000000000000000010
+:1020D0000000000000000000000000000000000000
+:1020E00000000000000000000000000000000000F0
+:1020F00000000000000000000000000000000000E0
+:1021000000000000000000000000000000000000CF
+:1021100000000000000000000000000000000000BF
+:1021200000000000000000000000000000000000AF
+:10213000000000000000000000000000000000009F
+:10214000000000000000000000000000000000008F
+:10215000000000000000000000000000000000007F
+:10216000000000000000000000000000000000006F
+:10217000000000000000000000000000000000005F
+:10218000000000000000000000000000000000004F
+:10219000C8DC0100010000000100F918010DE40095
+:1021A000F4DEF106FC0F27FAFF1DF01018090AF201
+:1021B00010E01714041114F1FAF2DBF7FCE2FBE172
+:1021C000EE130DFF1CE91A17180300DAE803E617EF
+:1021D000E4E9F3FF121305E104E225F706F2ECF15E
+:1021E000FC11E914F0E0F6F2E8091010011DD9FA2B
+:1021F000040F0F060CDE1C00FF0D07181AF60EE484
+:10220000160FF905EC181B0A1EFF0026E2FFE50A6F
+:1022100014180705EA0FF2E4E6F6080808080808AB
+:1022200008090A0808070701020202020202020264
+:102230000202020202020202020201010000000088
+:1022400000000000C5011DFFE0FFC0FFE0FF00002F
+:10225000000000FF000000006B0382FEE7FFCCFFE0
+:10226000E7FF080002000000D7010BFFEEFFDCFFD4
+:10227000EEFFA7033CFEECFF1700ECFF720385FEA8
+:10228000AEFEF801AEFE070004000000980160FFFA
+:10229000CBFF96FFCBFF9C0345FE2500C1FF250029
+:1022A000B10316FEE4FEA501E4FE070014000100E0
+:1022B000BF0131FFF20049FEF200870361FE33FFE8
+:1022C000620133FF800378FEDAFEE900DAFE0800DF
+:1022D00015000100BF0131FF18010EFE1801870330
+:1022E00061FE16FF7C0116FF800378FE8FFF9300CE
+:1022F0008FFF090016000100BF0131FF620055FF8A
+:102300006200870361FE1FFF6B011FFF79037EFEE2
+:10231000F4FE5D00F4FE080017000100BC0131FF6F
+:10232000740042FF7400870361FE52FF020152FFF6
+:10233000800378FE7FFFF1FF7FFF08001800010097
+:10234000B40131FFDFFF1D00DFFF880361FE87FF5F
+:1023500090FF87FF7F0378FECDFEF401CDFE0800DD
+:1023600019000100AD0131FFB8FF3E00B8FF820344
+:1023700061FEAAFFB1FFAAFF7F0378FEC7FEFE0140
+:10238000C7FE08001A000100930154FFD9FF0C009A
+:10239000D9FF1B03C7FE4CFF38004CFF3303B8FEC8
+:1023A00080FF280080FF08001B000100890154FF06
+:1023B000CFFF1300CFFF1703C7FE00FF500000FF41
+:1023C0002E03BDFE8BFF25008BFF08001E000100C1
+:1023D000BB0119FFC3FF1D00C3FF6B0361FE66FF56
+:1023E000480066FF7C0378FE56FF4F0056FF08004A
+:1023F0002C000100BF0131FFE00071FEE000870307
+:1024000061FE8BFFC4008BFF800378FEB2FEC0002C
+:10241000B2FE0800010000006C0900000B0A000772
+:102420000A88888002000000710900000B0A00077A
+:102430000A88888003000000760900000B0A000764
+:102440000A888880040000007B0900000B0A00074E
+:102450000A88888005000000800900000B0A000738
+:102460000A88888006000000850900000B0A000722
+:102470000A888880070000008A0900000B0A00070C
+:102480000A888880080000008F0900000B0A0007F6
+:102490000A88888009000000940900000B0A0007E0
+:1024A0000A8888800A000000990900000B0A0007CA
+:1024B0000A8888800B0000009E0900000B0A0007B4
+:1024C0000A8888800C000000A30900000B0A00079E
+:1024D0000A8888800D000000A80900000B0A000788
+:1024E0000A8888800E000000B40900000B0A00076B
+:1024F0000A888880000001009F0152074000800088
+:102500004000180378064000800040000A032E06B1
+:1025100040008000400008000100010092013707E0
+:1025200003013B0003019F02020744003600440000
+:10253000600247075D00A7005D000800020001007F
+:102540009F01520740008000400018037806C00039
+:102550008001C0000A032E064000800040000800F1
+:10256000030001002E013107810002018100920267
+:10257000B806CD009A01CD00F202E006AA0054018F
+:10258000AA0008001400010068015CFFF200C6FE0A
+:10259000F200F002B8FE33FFCB0033FFFF02E0FE93
+:1025A00003FF49FF03FF08001500010068015CFFFD
+:1025B000950052FF9500F002B8FE33FFA40033FFF0
+:1025C000FF02E0FE00FFEFFE00FF08001600010022
+:1025D00068015CFF62009CFF6200F002B8FE33FFFE
+:1025E0007C0033FFFF02E0FE00FFA0FE00FF0800BA
+:1025F000170001005E015CFF8CFF52008CFFF002AF
+:10260000B8FE33FF280033FFFF02E0FE7FFF15FF17
+:102610007FFF08001800010045015CFFE0FFD8FFC4
+:10262000E0FFF402B8FE00FF29FE00FFFE02E0FE1C
+:10263000FAFEAA00FAFE0800190001002B015CFF57
+:10264000CDFFC0FFCDFFE002B8FE00FF29FE00FF76
+:10265000FD02E0FEFAFEAA00FAFE08001A000100E0
+:10266000150197FFD9FF8BFFA8FF7D022EFFC0FF4A
+:1026700040FF70FF660248FF80FF80FEE0FE08001A
+:102680001B000100F50097FFCFFF6DFF92FF720264
+:102690002EFF5EFF1BFE95FE650248FFC2FF46FF50
+:1026A00075FF08001E0001002E0131FFC3FF86FFE9
+:1026B000C3FF9202B8FE33FF66FE33FFF202E0FE74
+:1026C00056FFACFE56FF08002800010068015CFFC1
+:1026D000F200C6FEF200F002B8FECD0035FFCD00DC
+:1026E000FF02E0FEFF017201FF0108000501000882
+:1026F0000001FFFF0000000000000000A200000039
+:1027000000FF00FF00000000000000FF00000000CC
+:102710007802A0FE80FF00FF80FF0800010000009B
+:10272000760179FFF0FFE0FFF0FF1F0374FECEFF9C
+:10273000E0FFCEFFEE022BFE2CFF32002CFF080044
+:1027400002000000770116FFDBFFB4FFDBFF1F0371
+:1027500074FEE0FFECFFE0FFEC02F2FE80FF1E00E3
+:1027600080FF080003000000770116FFDBFFB4FFC5
+:10277000DBFF1F0374FEE0FFECFFE0FFEC02F2FE64
+:102780006CFF23006CFF0800040000003301AEFF63
+:10279000CBFF96FFCBFF0B0385FECBFF0A00CBFFE1
+:1027A000FD022BFE2CFFCA002CFF080000000000D9
+:1027B0000000000000000000000000000000000019
+:1027C0000000000000000000000000000000000009
+:1027D00000000000000000000000000000000000F9
+:1027E00000000000000000000000000000000000E9
+:1027F00000000000000000000000000000000000D9
+:1028000000000000000000000000000000000000C8
+:1028100000000000000000000000000000000000B8
+:1028200000000000000000000000000000000000A8
+:102830000000000000000000000000000000000098
+:102840000000000000000000000000000000000088
+:102850000000000000000000000000000000000078
+:102860000000000000000000000000000000000068
+:102870000000000000000000000000000000000058
+:102880000000000000000000000000000000000048
+:102890000000000000000000000000000000000038
+:1028A0000000000000000000000000000000000028
+:1028B0000000000000000000000000000000000018
+:1028C0000000000000000000000000000000000008
+:1028D00000000000000000000000000000000000F8
+:1028E00000000000000000000000000000000000E8
+:1028F00000000000000000000000000000000000D8
+:1029000000000000000000000000000000000000C7
+:1029100000000000000000000000000000000000B7
+:1029200000000000000000000000000000000000A7
+:102930000000000000000000000000000000000097
+:102940000000000000000000000000000000000087
+:102950000000000000000000000000000000000077
+:102960000000000000000000000000000000000067
+:102970000000000000000000000000000000000057
+:102980000000000000000000000000000000000047
+:102990000000000000000000000000000000000037
+:1029A0000000000000000000000000000000000027
+:1029B0000000000000000000000000000000000017
+:1029C0000000000000000000000000000000000007
+:1029D00000000000000000000000000000000000F7
+:1029E00000000000000000000000000000000000E7
+:1029F00000000000000000000000000000000000D7
+:102A000000000000000000000000000000000000C6
+:102A100000000000000000000000000000000000B6
+:102A200000000000000000000000000000000000A6
+:102A30000000000000000000000000000000000096
+:102A40000000000000000000000000000000000086
+:102A50000000000000000000000000000000000076
+:102A60000000000000000000000000000000000066
+:102A70000000000000000000000000000000000056
+:102A80000000000000000000000000000000000046
+:102A90000000000000000000000000000000000036
+:102AA0000000000000000000000000000000000026
+:102AB0000000000000000000000000000000000016
+:102AC0000000000000000000000000000000000006
+:102AD00000000000000000000000000000000000F6
+:102AE00000000000000000000000000000000000E6
+:102AF00000000000000000000000000000000000D6
+:102B000000000000000000000000000000000000C5
+:102B100000000000000000000000000000000000B5
+:102B200000000000000000000000000000000000A5
+:102B30000000000000000000000000000000000095
+:102B40000000000000000000000000000000000085
+:102B50000000000000000000000000000000000075
+:102B60000000000000000000000000000000000065
+:102B70000000000000000000000000000000000055
+:102B80000000000000000000000000000000000045
+:102B90000000000000000000000000000000000035
+:102BA0000000000000000000000000000000000025
+:102BB0000000000000000000000000000000000015
+:102BC0000000000000000000000000000000000005
+:102BD00000000000000000000000000000000000F5
+:102BE00000000000000000000000000000000000E5
+:102BF00000000000000000000000000000000000D5
+:102C000000000000000000000000000000000000C4
+:102C1000000000000000000083682DE9F0415B69BE
+:102C20000546152B0F460AD0182B08D01B2B06D0B3
+:102C3000242B01D0272B04D12B8A7F2B05D80C23E2
+:102C400004E0172B01D0182B01DD1423AB624FF0E9
+:102C500004430022BB6100E00132BB69002B03DAB0
+:102C60001D4B9A42F8D134E01C4B9A4231D8AE6ADF
+:102C70003C69331DAB83AC61A868298ADEF346F357
+:102C8000022390FBF3F014F4807F68840AD0284676
+:102C900039463246DEF352F3C0F30F1083B2E883B5
+:102CA0002B8403E0AB8B2B846B8CEB83AB6913F42D
+:102CB000007F0AD0AA6A284639460132DEF33EF385
+:102CC000C0F30F1083B2688400E02B8CAB842B8A96
+:102CD000EB84BDE8F081C046809698007F9698000E
+:102CE00070B50446DEF33CF1002144220546DFF3D3
+:102CF000A7F16369152B2B6001D0162B01D9104B5E
+:102D00006B60686808B9054617E0AC602046E8F3D8
+:102D1000F1F1E8602046E8F3B5F1064618B920461F
+:102D20000121E8F3EDF16B6820469B689847054662
+:102D30001EB920463146E8F3E3F1284670BDC0468F
+:102D4000C81D02002DE9F0470546884691469A467F
+:102D5000E8F398F1074618B928460121E8F3D0F1C5
+:102D60002846E8F38FF1D0B12846E8F381F1B0B9F5
+:102D70002846FFF7B5FF064610B94FF0FF3410E0C4
+:102D80002846ECF763FD736830465C6941464A4665
+:102D90005346A04704462846ECF75CFD01E06FF07F
+:102DA00018041FB928463946E8F3AAF12046BDE8C1
+:102DB000F087C0460523C0F894310223C0F898314B
+:102DC0001E33C0F89C31234B4FF010021B68002BC0
+:102DD0000CBF07230023C0F8A0314FF00103C0F857
+:102DE000AC3103F16303C0F8B0314FF00603C0F813
+:102DF000C03140F23C73C0F8C4314FF00803C0F852
+:102E0000C83103F10D03C0F8A421C0F8B821C0F8FF
+:102E1000BC21C0F8CC31C0F8D02101D1032302E09D
+:102E20000D4B1B68013BC0F8D4311C230422C0F8B1
+:102E3000DC310C23C0F8E0319B18C0F8E4310623E4
+:102E4000C0F8EC310023C0F8D821C0F8E821C0F860
+:102E5000F0317047EC260000D4250000D0F81012A5
+:102E600070B5044609B90D460CE08068DFF39CF6A6
+:102E7000D4F810120546E822A068E3F339F70023DE
+:102E8000C4F81032284670BD70B50024054680F89D
+:102E90007541006903F04AFC2846E6F30DF7E8683F
+:102EA0002146E7F3C7F7D5F8900128B1E3F306F21E
+:102EB000D5F89001E3F34CF2D5F88C0128B1E3F397
+:102EC000FDF1D5F88C01E3F343F2E86805F0CAFCA4
+:102ED000D5F8103223B11B7813B12846FFF7BEFF97
+:102EE000A86829464FF40772E3F302F770BDC046A5
+:102EF0001FB5044606238068E8210393E3F3E8F650
+:102F0000C4F8100210B94FF0FF300CE00021E822A5
+:102F1000DFF396F000230093A068D4F8101203AA00
+:102F20001C33DFF3D9F604B010BDC0462DE9F047DD
+:102F30008AB01F46129D9C4B08461D601146904664
+:102F4000E6F33CF6002800F02A8138464FF407717A
+:102F5000E3F3BEF60446002800F0218100214FF47F
+:102F600007720646DFF36CF0A76065612046FFF745
+:102F700021FF8E4B1B68C4F80C320BB99A4605E052
+:102F80001B78B3F1000A18BF4FF0010A884B04F117
+:102F900028001A680121002A14BF31221122DFF310
+:102FA0006DF70023009301930293404639462A4669
+:102FB000139B05F095FDE060002800F0EA80E7F340
+:102FC00051F72060E068E7F36BF7656960606B6854
+:102FD000784A83F00103784903F00103002B0CBF0A
+:102FE00088469046226884F8763140F629039A4252
+:102FF000D4F80890D4F80CC00AD120B905F5007EA9
+:1030000005F5047508E005F5007E05F5087503E093
+:1030100005F5007E05F50475D4F8B831D4F8BC2167
+:10302000D4F8C411D4F8C00101934FF0FF330493D6
+:1030300009330693002302920391059007934846B3
+:103040004146624673460095EEF774FA60620028C6
+:1030500000F09F80D4F80C12C1B10B78B3B1E1F34A
+:10306000C7F556492246D4F80C02DFF389F5D4F8A7
+:103070000C0253492246DFF3BDF5BAF1000F05D02B
+:103080002046FFF735FF002840F0838001210A46E3
+:10309000606AE1F3B5F520460021E2683B4603F0A3
+:1030A00051FB2061002874D000210B462046454A80
+:1030B000E3F370F10023C4F8900184F879314248B9
+:1030C000E4F3D4F518B3DFF303F2012383403F4860
+:1030D000C4F88031E4F3CAF510B1DFF3F9F108B1B7
+:1030E000D4F88001C4F8840139490020DFF344F4A6
+:1030F000030CA4F888319BB2A4F88A013BB10021EB
+:103100002046344A0B46E3F345F1C4F88C01002015
+:103110003149DFF331F4012809D184F816022F492F
+:103120000138DFF329F4012804BF2D4B1860204635
+:10313000E6F3A4F320B30025C4F8A051284629499A
+:10314000DFF31AF428B1012384F8F9312648EEF7A9
+:10315000ABFA28462549DFF30FF488B12349284606
+:10316000DFF30AF44FF0807300F00F000AA901F8B2
+:10317000010D4FF44072009320460F23DFF7BEFC91
+:103180001B481C492246E3F3B5F41B48EBF76CFDE2
+:1031900006E0A06821464FF40772E3F3A9F5002684
+:1031A00030460AB0BDE8F087F4260000BC260000D7
+:1031B000EC260000AE278600B6278600DD9B800047
+:1031C0007929000065A68000052886000E28860063
+:1031D00017288600499B80001F28860078D50100AB
+:1031E000AC2702002A2886003428860089D50100F1
+:1031F0004D288600E59A8000D596800010B50446DB
+:1032000060B1036806491868224600F09DDE236815
+:10321000214658684FF4BC72E3F36AF510BDC0460E
+:10322000853B86007FB505464FF4BC714068E3F3EB
+:103230004FF508B9064619E000214FF4BC72064666
+:10324000DEF3FEF60B4B356000930B4B002401932D
+:103250002868334609490A4A0294039400F03CDE88
+:103260004FF49663C6F8603186F86441304604B086
+:1032700070BDC04625110100E52C0000B0D501004D
+:10328000853B860070B5044608B906462AE0816889
+:1032900009B90E460CE0C3689868ECF3DFF1E36807
+:1032A000D0F1010638BF0026A1689868ECF3E8F178
+:1032B000616F0025A56529B1E368A26F5868E3F343
+:1032C00017F565672046EEF7D5FFE36806491868ED
+:1032D000224600F039DEE368214658684FF4B072A8
+:1032E000E3F306F5304670BDEB3D860030B54FF494
+:1032F000B07185B005464068E3F3EAF40446E0B1F6
+:1033000000214FF4B072DEF39BF6E560C5F8184873
+:10331000A8680D4922460023ECF3CEF1A06060B10D
+:103320000A4B2868009300230193029303930849F2
+:10333000084A234600F0D0DD18B12046FFF7A2FF6F
+:103340000024204605B030BD152E0000D9E18000D4
+:1033500034D60100EB3D8600034B012210B51A70F4
+:10336000EBF7F2FF10BDC0463C28020070B50446E2
+:10337000D0F884000D4608B102F0D8FCD4F88000E3
+:1033800008B105F0E5FBE06F08B1FFF737FFA06F6C
+:1033900008B105F06BFC606F08B1FFF773FFA06820
+:1033A00008B100F0CDFB284621468C22E3F3A0F4BF
+:1033B00070BDC0462DE9F04F064689B00D4600208D
+:1033C0008C2191469846139FE3F382F4044600282B
+:1033D00077D000218C22DEF333F62760304605F0EB
+:1033E000B1F807AB0190059383464FF0000A2046E1
+:1033F00041F2E44142463B460295CDF800A0CDF8AB
+:103400000C90049400F06EFD054600285BD0A0608F
+:1034100002F066DB2B696060E3602F4B1021A36430
+:103420002E4A3B46266164643046DEF34DF62B6936
+:1034300039461B6E2A489A6B2A4BEEF735F93A4605
+:1034400050461299284B0096CDF8049002F0ECFDFE
+:103450000746002837D16368012683F87860362153
+:103460003246D5F87C0223F08FD9204B2846E363FF
+:10347000FFF73CFF606730B36368284683F8A460B9
+:1034800005F006FCA067F0B12846FFF7CBFEE06729
+:10349000C8B1284605F088FBC4F8800098B12846DA
+:1034A00002F072FCC4F8840068B1114B01970093DC
+:1034B0000297039728680F490F4A234600F00CDD56
+:1034C00008B9204604E020465946FFF74FFF002088
+:1034D00009B0BDE8F08FC04655F78000FB4186007B
+:1034E00008B10200A0D6010029FB8000EFBEAD0D9F
+:1034F00099F88000E8D60100C542860041F2E44315
+:10350000984201D00020AFE044F22033994200F00D
+:10351000AA800533994200F0A680223B994200F030
+:10352000A2801E33994200F09E800333994200F03E
+:103530009A800C3B994200F096800133994200F04A
+:1035400092800133994200F08E80093B994200F04D
+:103550008A800233994200F08680013B994200F054
+:103560008280023399427ED0013399427BD001336D
+:10357000994278D00533994275D00133994272D07F
+:10358000013399426FD001F53C43D8339BB2022BF3
+:1035900069D94BF6D543CB189BB2022B63D944F2C1
+:1035A000413399425FD0013B99425CD001F53C43E5
+:1035B000B0339BB2022B56D944F25333994252D0C6
+:1035C000043399424FD04AF69D1399424BD044F2AE
+:1035D0005433994247D0253B994244D0013B99420C
+:1035E00041D0063399423ED0013399423BD001335A
+:1035F000994238D04BF6C943CB189BB2022B32D933
+:1036000044F2167399422ED0113399422BD0A3F570
+:103610007973994227D001F53C43A0339BB2012B2B
+:1036200021D901F53C43BA339BB2022B1BD94BF68F
+:10363000CF43CB189BB2012B15D94BF6AB43CB181C
+:103640009BB2012B0FD901F53C43A8339BB2012B50
+:1036500009D944F26333994205D00D33994214BF1E
+:103660000020012000E001207047C0462DE9F84FFE
+:1036700000264FF0010842F601334FF0FF344FF0BF
+:10368000640B0746A0F8283680F8474680F8C44403
+:103690000221224680F8288080F868B780F84266C8
+:1036A00080F84C8680F8436680F8498680F8466644
+:1036B00002F05ED938464146324602F059D90C2113
+:1036C0002246384602F054D90B213846324602F0E1
+:1036D0004FD90E212246384602F04AD90D213846EC
+:1036E000324602F045D90F212246384602F040D931
+:1036F00004210222384602F03BD9D7F860364FF059
+:10370000030987F8488683F80690D7F860364FF0AB
+:10371000020A83F8079040F62A13A7F82A36A7F87A
+:103720002C369BB2A7F82E3640F62A13A7F830366F
+:10373000A7F83236A7F83436A7F8363640F62B13FA
+:10374000A7F838363B68A7F87A6583F895604FF09C
+:103750000703A7F83A364FF00403A7F83C360F23C7
+:1037600087F80C37D7F89034A7F83E96C7F8803220
+:10377000A7F840A6A7F87C68A7F87EB887F8EA61A2
+:1037800087F8EB6187F81E6287F8EE6187F8EC61D5
+:1037900087F8FA8187F80B6787F8A0649E71D7F8DD
+:1037A00094340B22C7F8843283F80680D7F8983413
+:1037B0003146C7F8883283F806A0D7F89C343546DE
+:1037C000C7F88C3283F806903B6887F8506783F817
+:1037D0004D805C633B6807F5CC6483F842803B68AE
+:1037E000043483F843603B6887F8CF6183F839601D
+:1037F0003B68204683F8AA803B6887F8DF6187F83A
+:10380000E081C7F8E46187F8E161DE66DEF318F471
+:103810006FF0220387F864362C3387F865364A4602
+:1038200004EB0A001A49DEF3A7F33B6887F869A6A0
+:1038300087F8568587F8578583F84C603A6887F88B
+:103840009267A7F89067A7F88CB892F8463013F003
+:10385000030F0CD092F94C304BB1D7F8FC04243054
+:10386000F1F3F6F4D7F8FC043230F1F3F1F44FF44D
+:103870004873A7F85C373B68012287F8252883F84E
+:10388000A2203A684FF0FF3382F8B530BDE8F88FD8
+:103890000FD40100836B70B5002483F84C40C36BD8
+:1038A000012583F84C500646816BDFF711FEF16B62
+:1038B0003046DFF70DFE21463046F6F349F2B36B92
+:1038C000304683F84D40F36B294683F84D40D6F8D7
+:1038D00060364FF0FF34DD72D6F860369C81F6F327
+:1038E00037F2D6F860369B78AB4214D9B36B83F8C5
+:1038F0004D40F26B4FF0FF3382F84D3096F8CB34E9
+:1039000096F8CC2443EA022343F0800386F8CB34B4
+:103910001B0A86F8CC3470BDD0F8AC1110B5044643
+:1039200029B18068EBF3ACF60023C4F8AC31D4F8CD
+:10393000C41129B1A068EBF3A3F60023C4F8C43185
+:10394000D4F8741529B1A068EBF39AF60023C4F8F3
+:103950007435D4F8F81629B1A068EBF391F600237A
+:10396000C4F8F836D4F8FC1629B1A068EBF388F651
+:103970000023C4F8FC36D4F8E036196A31B1A068E7
+:10398000EBF37EF6D4F8E02600231362D4F83C155E
+:1039900029B1A068EBF374F60023C4F83C35D4F8E1
+:1039A000941729B1A068EBF36BF60023C4F89437A1
+:1039B000D4F8B01829B1A068EBF362F60023C4F87C
+:1039C000B03810BD70B505462D4980682A460023E1
+:1039D000EBF372F6C5F8AC0100284ED0A86829496F
+:1039E0002A460023EBF368F6C5F8C401002844D04A
+:1039F000A86825492A460023EBF35EF6C5F874054E
+:103A000000283AD0A86821492A460023EBF354F64F
+:103A1000C5F8F806002830D0A8681D492A460023BA
+:103A2000EBF34AF6C5F8FC0638B3A86819492A46EC
+:103A30000023D5F8E046EBF33FF62062E8B1A86832
+:103A400015492A460023EBF337F6C5F83C05A0B12B
+:103A5000A86812492A460023EBF32EF6C5F894070E
+:103A600058B1A8680E492A460023EBF325F6C5F89D
+:103A7000B008003818BF012000E0002070BDC0462B
+:103A80003DAA81003D708100253E81009591810015
+:103A9000858F8100256E810089598100396B8100F5
+:103AA000496F810010B50446006805F0B3FED4F8F4
+:103AB000583113B10023C4F85831D4F83C0120B177
+:103AC00005F00EF90023C4F83C31D4F8400120B1D0
+:103AD00001F080F80023C4F84031D4F84C0120B143
+:103AE00002F09AF80023C4F84C31D4F8540120B104
+:103AF00005F070FA0023C4F85431D4F8600120B105
+:103B000007F000F80023C4F86031D4F8383113B15D
+:103B10000023C4F83831D4F8640120B101F0FEFE6E
+:103B20000023C4F86431D4F8000520B107F026F969
+:103B30000023C4F80035204605F0D2FA10BDC04677
+:103B40002DE9F041054608B9074695E001F046FB2E
+:103B50000746284602F06AD800B90137D5F8F016B2
+:103B600049B16868D5F8F426E3F3C2F00023C5F83C
+:103B7000F436C5F8F0362846D5F81815F8F38AF764
+:103B80002846D5F8D816F8F385F7D5F82015284635
+:103B9000F8F380F7D5F82C1521B168684FF49662D8
+:103BA000E3F3A6F0D5F87C0220B105F051FA00232A
+:103BB000C5F87C3200242B19D3F84C1211B12846D9
+:103BC0001BF03ADC0434202CF5D10121284631F0D9
+:103BD000C9DD284601F078FE2E6BB16911B1284687
+:103BE00031F054D80024B461D5F85C0101F05EFFD7
+:103BF0002846FFF791FE2846FFF754FF2846D5F8E0
+:103C00002C18DFF75DFCC5F82C48D5F8B84404E063
+:103C100068681022E468E3F36BF02146002CF7D1CA
+:103C2000C5F8B844286816492A4600F08DD9D5F859
+:103C3000340718B101F010F9C5F83447D5F8680118
+:103C400018B106F0C5FFC5F86841D5F8181759B185
+:103C50006868D5F81C27E3F34BF0C5F8184703E074
+:103C60002846696807F0B0D8D5F87822002AF7D13D
+:103C70002846696800F034FD3846BDE8F081C0464A
+:103C8000BB5C8600036870B55E6905461449304622
+:103C9000DEF372F6C0B218B930461249DEF36CF6A4
+:103CA00040B2431E0E2B0ED8012803D1D5F8603642
+:103CB000002204E0022806D1D5F8603601229A716C
+:103CC000D5F86036DA71084930462C6BDEF354F6CD
+:103CD00084F804012846EFF3EFF1012070BDC046DF
+:103CE000C65C8600CB5C86000E5D8600036870B5FE
+:103CF0001B490546D0F860465869DEF33DF6207052
+:103D00002B6818495869D5F86046DEF335F6E0703F
+:103D1000D5F8602613780BB10F2B01D10123137056
+:103D2000D5F8603601211A785A70D5F860462046D9
+:103D3000DEF3DEF3A070D5F86026D3780BB10F2B3D
+:103D400001D10123D370D5F860360121DA781A71D8
+:103D5000D5F86046E01CDEF3CBF3607170BDC04661
+:103D600019D7010021D7010070B50446214600682B
+:103D700007F012F8C4F8000508B929305EE02068A1
+:103D800005F050FD2068214601F08AF8C4F8340798
+:103D900008B92A3052E02A4B2046C4F8583104F0C2
+:103DA000B9FFC4F83C0108B9313047E0204600F0C3
+:103DB0004BFFC4F8400108B932303FE0204606F01E
+:103DC000B3FEC4F8600108B9353037E020682146F9
+:103DD000A2681C4B05F058F9C4F87C0208B93930C8
+:103DE0002CE0204601F0EAFDC4F8640108B93C303B
+:103DF00024E0154B0125C4F838310023A4F83038ED
+:103E000084F8883884F88A3884F88958204601F084
+:103E100013FFC4F84C0108B93F300FE02368214676
+:103E200083F83A50236883F8A950206805F062F9B6
+:103E300008B1452002E0236883F8A05070BDC04659
+:103E4000EFBEADDE9D6D8100EFBEAD0DF0B5D0F8DB
+:103E500040750021AC2287B006463846DEF3F0F00C
+:103E60004FF06403FB85032387F8603000220123B1
+:103E7000D6F85C014FF42C5121F0D4DFFF2804D197
+:103E8000336B18691968EEF787FE31687886A6F8F3
+:103E9000260691F84640336B00F44065FF201A89EE
+:103EA00000211B68B5F5406F14BF1425282501902B
+:103EB00004F00304D6F8600600910294039580781C
+:103EC000049007F138002DF0D9D8336893F84630C4
+:103ED00013F0030F03D0FB8843F02003FB8007B0EF
+:103EE000F0BDC0462DE9F04F8DB01A9F9A460023D1
+:103EF00007910B930646934610461799189A199BFB
+:103F00009DF85890009709F08DF9044610B11E23D2
+:103F10000B937FE3FFF720FA179851460BAA00F0A6
+:103F20000DFD0546002800F07583179AD0F860361D
+:103F300042604FF0FF32D0F8008083F81C21836B81
+:103F4000C8F804A00363436B8660C362179BC0F884
+:103F50007871C8F80C30B54B88F82190C8F8B030AB
+:103F6000032380F86937C0F8CC2880F89D4151467A
+:103F7000FFF77CFB2846F7F323F7284605F0D4F833
+:103F80000446002840F04F8328463146179A53468E
+:103F900006F03EFEC5F8680108B91F23D3E2A44B22
+:103FA0000194009302940394A249A34A2B462868E3
+:103FB000FFF392F7A14B0194009302940394A0495C
+:103FC000A04A2B462868FFF387F7189A199B179E7B
+:103FD00002920393284607995A465346CDF800901B
+:103FE0000196049701F04AFA04460B90002840F02D
+:103FF0001A832B69186EEBF767FCA5F8BE082846F4
+:10400000F5F38EF508B914239DE2264631460AAA37
+:104010002846F7F311F231462846BDF8282001362C
+:10402000F7F314F2062EF1D1012488F89A4005F531
+:10403000BE72286908F1140118F054DC8249D8F8DE
+:104040001400DEF399F481498146D8F81400DEF3B8
+:1040500093F47F49A5F86208D8F81400DEF38CF4D5
+:10406000B5F86228A5F86408A5F87827A5F87A07B6
+:104070007849D8F81400DEF37FF47749A5F854089E
+:10408000D8F81400DEF378F485F856087349D8F8A8
+:104090001400DEF371F485F858087149D8F814005B
+:1040A000DEF36AF485F85A086E49D8F81400DEF396
+:1040B00063F485F857086C49D8F81400DEF35CF413
+:1040C00085F859086949D8F81400DEF355F485F8E5
+:1040D0005B086749D8F81400DEF34EF485F85C08F5
+:1040E0006449D8F81400DEF347F485F85E086249A5
+:1040F000D8F81400DEF340F485F860085F49D8F87A
+:104100001400DEF339F485F85D085D49D8F8140031
+:10411000DEF332F485F85F085A49D8F81400DEF36C
+:104120002BF485F861082846FFF7E0FDD5F86026F6
+:104130002B6B85F8F04785F8F14718691178D2782C
+:10414000EEF77CFF2869EA6AD0F8A03005F5CB7459
+:104150005360D0F8A43021469360D0F8A830D360E3
+:10416000D0F8AC301361D0F8B0305361D0F8B4302F
+:10417000936118F0E7DC08F14E0021463246DDF38A
+:10418000FBF6B5F8822144F221339A4217D00E3B58
+:104190009A4214D007339A4211D010339A420ED06B
+:1041A000143B9A420BD007339A4208D010339A42FC
+:1041B00005D025339A4214BF0024012400E00124D5
+:1041C00005EB84039B6B28462B63FFF75BFD08B967
+:1041D0001823B8E1296B4FF00F0340F2FF36A1F826
+:1041E000063101F1FC0201F58073A1F8086128464F
+:1041F00000F0B4FE2A6BD2F8FC30C2F8F830C2F8F6
+:10420000F030D2F80031C2F8F4301368022B07D135
+:10421000013B53752B6B284603215A7D01F0A8DB27
+:1042200019F0010F30D000222FE0C0465F7D5A0503
+:1042300079DB810078D48500BB5C8600E94800000A
+:104240005CD8010029D70100D6688600E2688600A4
+:10425000F5688600076986001C6986002B69860060
+:104260003A698600496986005A6986006B6986004A
+:104270007C6986008A69860098698600A66986003E
+:10428000B6698600C6698600012288F846200A21A0
+:10429000284601F06DDB296B28461C31F9F3C6F383
+:1042A0007F23296B00932B68002293F8463001F19D
+:1042B0001C0003F003030193503113462CF01CDF64
+:1042C000B4F1FF3F3FF45DAF2846F5F383F44FF4BC
+:1042D000D163C5F874382846FFF746FD04460B90B5
+:1042E000002840F0A0812869214619F00FDB2869D9
+:1042F00098F83A1018F052DF28465146FFF762FB53
+:1043000008B920231FE1284601F0DAFBC5F85C015B
+:1043100008B9212317E12846FFF798FD2146AD4A49
+:10432000AD4B28460094019506F008FDAB4B6E4658
+:104330001A1D07CA1B6886E80700072128462A4677
+:1043400006F094DC04212846A54AA64B009401956A
+:1043500006F0F4FC0028C5F88C0701DA2223F2E00D
+:104360002846179906F006DD08B96423EBE0C5F886
+:1043700004084FF0FF3728469B499C4A9C4B009706
+:10438000FEF342F6C5F82C08002800F04C812846C0
+:1043900001F0A4FA044608B12323D4E02B684FF0BF
+:1043A000060293F8A130A8F86420012B04BF402333
+:1043B000A8F86430D8F88C304FF006064FF4397204
+:1043C0001E805A80D8F890304FF0C4024FF001069A
+:1043D00005F5007128461E805A80063107F09EDCE4
+:1043E000D5F83C010CF028DD08B185F8CF61022337
+:1043F00085F8C0341C3385F8CB3410222B6B85F83C
+:10440000CC245B89022B02D81C2385F8CB342846A8
+:10441000214685F8CA7485F8C97485F8C874F6F31E
+:104420003BF12B68284683F8B4402146C5F8D47187
+:10443000F1F34AF185F8DC412846FFF72BFA19F031
+:10444000080F18BF85F8DC4119F0100F03D028467B
+:104450002146F1F339F119F0020F13D0AB6B83F859
+:104460004D40EB6B83F84D4095F8CB3495F8CC2458
+:1044700043EA022323F080039BB285F8CB341B0A66
+:1044800085F8CC3419F0040F03D028462146F5F303
+:104490007FF419F0800F0DD095F8CB3495F8CC242B
+:1044A00043EA022323F010039BB285F8CB341B0AA6
+:1044B00085F8CC342B6893F842308BB119F0600F3B
+:1044C0000ED019F0200F0CBFFF21002119F0400F72
+:1044D000284649B214BF00226FF0000200F068FBCA
+:1044E00006220DF122004349DDF346F5B5F882219D
+:1044F00044F221339A4217D00E3B9A4214D007332C
+:104500009A4211D010339A420ED0143B9A420BD0EB
+:1045100007339A4208D010339A4205D025339A4285
+:1045200014BF0027012700E0012705EB8706B46BC5
+:104530000DF122012846224630F06ADBB16BA06102
+:10454000886910B937230B936DE04430503128222D
+:10455000DDF312F5B36BB7F1FF3F9B699F62BFD0EC
+:10456000D8F85C30179E43F00403C8F85C30224B47
+:10457000F560B3602846ECF7C7FF1B9A0AB1002329
+:1045800013602B681D495869DEF322F230B1002117
+:104590000A46DEF3DDF01A4BC0B218602B681949E9
+:1045A0005869DEF315F230B100210A46DEF3D0F08F
+:1045B000154BC0B218602B6814495869DEF308F235
+:1045C00030B100210A46DEF3C3F0114BC0B21860CF
+:1045D00028462CE039AE820001AE820034D90100B9
+:1045E000D5A18100ADA181002D57810041578100E7
+:1045F0001957810056D80100B542820035D7010015
+:10460000EC27020041D70100102C020055D7010011
+:10461000142C02001B9B0BB9184608E00B9B1B9E39
+:104620000020336003E02846FFF78AFAF2E70DB076
+:10463000BDE8F08F20230360436040F23C73836049
+:10464000092330B50361836107330362303383622A
+:104650000F230822036340F29E3304240125002126
+:1046600042618263C3640322A3F56773C460C561BA
+:104670004462C46244630164456402654166436503
+:104680008465C265036630BD70B505460C4631B31E
+:10469000496D11B1C022E2F32BF3D4F88C1039B17B
+:1046A00028464FF43972E2F323F30023C4F88C3028
+:1046B000D4F8901031B12846C422E2F319F3002354
+:1046C000C4F89030E16929B128466822E2F310F37A
+:1046D0000023E36128462146B822E2F309F370BDC6
+:1046E00070B50D460446002800F0E580D0F8181596
+:1046F00039B128464FF48472E2F3FAF20023C4F889
+:104700001835D4F8201539B128464FF48472E2F3F5
+:10471000EFF20023C4F82035D4F8B41439B1284698
+:1047200040F2AC42E2F3E4F20023C4F8B434D4F82B
+:10473000401531B12846AC22E2F3DAF20023C4F886
+:104740004035D4F86C1229B1284607F019DE002351
+:10475000C4F86C32D4F8FC1431B128464022E2F39C
+:10476000C7F20023C4F8FC34D4F8841671B123686E
+:1047700063B1DB6953B19B690C22013303FB02F285
+:104780002846E2F3B5F20023C4F88436D4F8BC140A
+:1047900019B12846B422E2F3ABF2D4F8901421B157
+:1047A00028464FF4AE62E2F3A3F2D4F8581631B1C2
+:1047B00028463822E2F39CF20023C4F85836D4F895
+:1047C000601639B128464FF49072E2F391F200235B
+:1047D000C4F86036D4F8F81731B128460622E2F35F
+:1047E00087F20023C4F8F837D4F8D81639B1284630
+:1047F0004FF48472E2F37CF20023C4F8D836D4F884
+:10480000E01631B128462422E2F372F20023C4F804
+:10481000E036D4F8EC1631B128466822E2F368F2AB
+:104820000023C4F8EC36D4F8441731B12846EC2202
+:10483000E2F35EF20023C4F84437A16B21B12846AD
+:104840004FF40672E2F354F2616B79B1896A31B1C7
+:1048500080222846E2F34CF2626B002393622846E2
+:10486000616B2C22E2F344F200236363216821B1DF
+:104870002846FFF709FF002323602369ABB1D3F873
+:10488000F81028461822E2F333F223690026D96F84
+:10489000C3F8F86019B128465822E2F329F22846F5
+:1048A0002169FC22E2F324F226612846214640F6E3
+:1048B000D402E2F31DF270BD2DE9F0411646B82294
+:1048C00007460D4607F0FADD044610B940F2E93319
+:1048D0002BE038462946682207F0F0DDE06110B988
+:1048E00040F2044321E0FFF7A5FE38462946C022E6
+:1048F00007F0E4DD606510B940F2EB3315E03846AF
+:1049000029464FF4397207F0D9DDC4F88C0010B98C
+:104910004FF47B7309E038462946C42207F0CEDD08
+:10492000C4F8900038B940F2ED3321463360384680
+:10493000FFF7AAFE00242046BDE8F0812DE9F041F2
+:10494000174640F6D40280460E4607F0B7DD05460E
+:1049500000283BD02623C0F82838314640463A4646
+:10496000FFF7AAFF2860002800F018818F4B056030
+:104970001B683146C0F89C30FC22404607F09EDDA3
+:104980000446286110B940F2ED3306E185603146F6
+:104990004046182207F092DDC4F8F800B0B1404656
+:1049A000314658222C6907F089DDE06770B12B6928
+:1049B0004046DA6F31462C32C3F880204FF48472BF
+:1049C00007F07CDDC5F8180518B105E040F2EE33BC
+:1049D000E3E040F2EF33E0E0404631464FF48472CA
+:1049E00007F06CDDC5F8200510B94FF47C73D4E0F6
+:1049F0004046314640F2AC4207F060DDC5F8B404F1
+:104A000010B940F2F133C8E040463146AC2207F01D
+:104A100055DDC5F8400510B940F2F233BDE031462E
+:104A20004046ECF709FF0146C5F86C0210B940F2A8
+:104A3000F333B2E028461AF091D84046314640227E
+:104A400007F03CDDC5F8FC0410B94FF47D73A4E019
+:104A50002B680C22DB6940469B693146013303FB1E
+:104A600002F207F02BDDC5F8840610B940F2F533E9
+:104A700093E040463146B42207F020DDC5F8BC047F
+:104A800010B940F2F63388E0404631464FF4AE624A
+:104A900007F014DDC5F8900410B940F2F7337CE05C
+:104AA0002A464FF4AE71D5F89034CB1801F5AE71AB
+:104AB000C2F894340432B1F5AE6FF4D140463146B9
+:104AC000382207F0FBDCC5F8580610B94FF47E73A6
+:104AD00063E0404631464FF4907207F0EFDCC5F8D2
+:104AE000600638B140463146062207F0E7DCC5F8DB
+:104AF000F80710B940F2F9334FE0404631464FF421
+:104B0000847207F0DBDCC5F8D80610B940F2FA333E
+:104B100043E040463146242207F0D0DCC5F8E006E9
+:104B200010B940F2FD3338E040463146682207F0C4
+:104B3000C5DCC5F8EC0610B940F2FE332DE0404666
+:104B40003146EC2207F0BADCC5F8440710B940F250
+:104B5000FF3322E0404631464FF4067207F0AEDCE8
+:104B6000A86358B100F58673EB63404631462C22AA
+:104B700007F0A4DC0446686318B105E040F2014385
+:104B80000BE040F2024308E040463146802207F045
+:104B900095DCA06238B940F203433B6028464146A9
+:104BA000FFF79EFD00252846BDE8F081BC260000E9
+:104BB000D0F84031B1F1FF3F18BF83F89C13B2F138
+:104BC000FF3F83F89E1383F89F2318BF83F89D232C
+:104BD0007047C04670B50446002831D000256319DF
+:104BE000D3F8501221B12368F4225868E2F380F020
+:104BF0000435282DF3D1A16B69B194F8A3331BB10F
+:104C000023689868EAF32AF52368A16B9868EAF3A9
+:104C100037F50023A363D4F8781221B12368E82282
+:104C20005868E2F365F02368064918682246FFF3E6
+:104C30008BF12368214658684FF46A72E2F358F00A
+:104C400070BDC046678986002DE9F0434FF46A7154
+:104C500085B006464068E2F33BF0054608B9814658
+:104C6000CFE000214FF46A728146DDF3E9F12E6056
+:104C70007068E821E2F32CF0C9F87802002800F00F
+:104C8000B1800021E822DDF3DBF1002101236A1865
+:104C9000C91808299372F9D1013B2B746B742B73DB
+:104CA000EB721A460121AB185218082A83F89413A4
+:104CB000F8D11023EB74062385F827304FF0FF332B
+:104CC00085F82830213385F8A233052385F829306B
+:104CD0004FF47A736B864FF0C803AB86002385F8D8
+:104CE0002A30023385F82B302B682A75A9741B688B
+:104CF0002A4693F8A1308B4218BF032385F82C3045
+:104D00004FF0FF3385F89E3385F89F334FF40063EF
+:104D1000EB63012385F82D3004336B750223AB75EB
+:104D20006B7DD375AB7DD377013205F108039A42D1
+:104D3000F6D100244FF0010895F82910284685F88F
+:104D40002E4085F82F8007F09DDE284686F8C38424
+:104D500009F0B8DC042130462C4A2D4B0094019513
+:104D600005F0ECFFA04268603CDB2A4B3068009302
+:104D7000294B2A4901932A4B2A4A03932B46029432
+:104D8000FFF3AAF0074668BBB06827492A463B46AE
+:104D9000EAF392F4A86328B3244C85F87C82231D9F
+:104DA00093E807006B4683E807002A4623683046ED
+:104DB000062105F05BDF4FF0FF3385F8A133336840
+:104DC000284693F842100AF0DDDCC823C5F8E0322B
+:104DD000284609F0BDDE28464146ECF7CBFB85F8B6
+:104DE000A3730EE0D5F8781219B17068E822E1F3E8
+:104DF0007FF7706829464FF46A72E1F379F74FF054
+:104E00000009484605B0BDE8F083C04695CB820056
+:104E10001DCB820045CF820011E7820054D90100EA
+:104E200079D982006789860085A2000044D90100F3
+:104E300070B5182686B00C46324668460549DDF343
+:104E40009BF02046694632466D46DDF395F006B08C
+:104E500070BDC04634DB010070B5D0F8AC530446D9
+:104E6000D0F8B063284603F09DFFD4F8D013A868AB
+:104E7000EAF3F4F3A868D4F8D013EAF301F40023BA
+:104E80002246C4F8D03330460449FFF35DF0F068A1
+:104E900021464FF47E72E1F32BF770BDAB9986008B
+:104EA0002DE9FF413C23C1F824370523C1F82837F9
+:104EB00007460D46C0684FF47E71E1F309F70446DA
+:104EC00000283DD000214FF47E724FF00008DDF342
+:104ED000B7F0C4F8AC53C4F8B07384F8018020462E
+:104EE000E5F752FAC4F8C003284603F071FF0646FE
+:104EF00038B1F86821464FF47E72E1F3F9F6404686
+:104F00001FE0204604F56371FFF792FFA8680E4981
+:104F100022463346EAF3D0F3C4F8D00380B12046EA
+:104F20000DF054DC094B38460093094B09490193B5
+:104F3000094A234602960396FEF3CEF7204600E088
+:104F4000002004B0BDE8F0818D25830011B400007D
+:104F5000190F0100E4D90100AB99860010B5044691
+:104F60000846B0F80CE0194642F256039E4506D8B2
+:104F7000013B9E452ED2053B9E4509D02AE042F2D8
+:104F800060039E451BD04EF2F5439E451CD021E0A8
+:104F9000C389012B04D16FF03B0313604B3303E053
+:104FA0006FF0450313605A330B602368D3F88030E9
+:104FB00013F4805F13D01368023B13600FE06FF0AF
+:104FC0004A0313605A3309E06FF09503136003F549
+:104FD000967303E06FF04A0313605F330B6010BDFC
+:104FE00070B504460025E06820B1054B1B68984762
+:104FF0000023E36001350434062DF4D170BDC046B2
+:10500000E0A685000D4B82685362002380F886304D
+:105010004FF00303A0F88C304FF00203A0F88E305D
+:105020004FF00703A0F888304FF00403A0F88A304F
+:1050300042F60133A0F89C307047C04664A8E7BE32
+:10504000426C1F2A01D9002004E04FF00073134185
+:1050500003F001007047C046026EB0F84A1010B568
+:10506000946AB9B1FF2901D8012014E00B0B013B70
+:10507000012B0FD8C1F30323092B0BD853B1C1F374
+:105080000313092B06D801F00F03092B8CBF002056
+:10509000012000E00020D26A41F2E4439A4210D19C
+:1050A000A4F58263073B012B01D83F2907E040F2BA
+:1050B0000C439C4204D015339C4202D1502900D8A5
+:1050C000002010BD00B58E46C16E4FF0407394466F
+:1050D0007046C1F8603115E00379C2781B0443EAD9
+:1050E000026382791343427943EA0223C1F86431AF
+:1050F000437802781B0243EA024382780730134365
+:10510000C1F86431CEEB00036345E5D300BDC04672
+:10511000C16E4FF48030C1F860011D4AD1F8603192
+:1051200010B5D1F86441C1F86001D1F86031C1F81F
+:105130006421C1F86001D1F86031D1F86431934243
+:1051400024D1144AC1F86001D1F86031C1F864215A
+:10515000C1F86001D1F86031D1F86431934215D1C2
+:10516000C1F86001D1F860310023C1F86441C1F891
+:105170008C31D1F82001084B984201D1012006E082
+:10518000064B984214BF0020012000E0002010BD13
+:10519000AA5555AA55AAAA55000400040004008483
+:1051A000D0F8501810B5044641B1D0F84C284068EA
+:1051B0009200E1F39DF50023C4F85038D4F8481864
+:1051C00059B16068DDF3F0F46068D4F84818E8225B
+:1051D000E1F38EF50023C4F8483810BD70B50469BA
+:1051E0000646206E08B1EAF729FB2046FFF7F8FED5
+:1051F000A56F686A18B104F035F800236B62606F20
+:1052000003F0C2FF206F05F05BFC616E29B12068DE
+:10521000A26EE1F36DF500236366206E18B103F012
+:1052200021FB002323662046E7F7C4FF3046FFF743
+:10523000B7FF002070BDC0462DE9F04F0368076935
+:105240008FB00890DE691446FB6B0CA80821704AE9
+:10525000DCF33AF7FB68002B40F0CE80F96E386E35
+:1052600001F50071D7F800B0DFF31EF3BB6801460B
+:105270009868EAF3B7F1002800F0C680D7F860E03C
+:105280000CB9A44602E0FB6E03F5007CFB6E03F54F
+:10529000087504B13468B168BB687268F068D3F807
+:1052A000283803915B490DF130094FF0FF38029225
+:1052B0000590724606930791634649465846009505
+:1052C0000194CDF81080ECF735F93168F8603A6E4A
+:1052D000FB6E01914F4900240546079103F51073B9
+:1052E00049465846009402940394CDF810800594E2
+:1052F0000694ECF71FF9316838613A6EFB6E019144
+:1053000044490990079103F5207349465846009493
+:1053100002940394CDF8108005940694ECF70AF9F2
+:10532000316878613A6EFB6E01913A490A900791B3
+:1053300003F5307349465846009402940394CDF81F
+:10534000108005940694ECF7F5F83168B8613A6E70
+:10535000FB6E01912F490B90079103F5407349466D
+:105360005846009402940394CDF810800594069456
+:10537000ECF7E0F83168F8613A6EFB6E019125496F
+:105380008246079103F550734946584600940294AB
+:105390000394CDF8108005940694ECF7CBF8099AA5
+:1053A000A54214BF002501250A9BA24208BF45F073
+:1053B00001050B99A34208BF45F00105A14208BFB2
+:1053C00045F00105A24508BF45F001053862A0423D
+:1053D00014BF284645F00100B0B90F4B3C46D3F846
+:1053E00084600546E06818B10C49B047C4F8A000D5
+:1053F00001350434062DF5D1B96F08980831002223
+:10540000E7F714F9012000E000200FB0BDE8F08FAD
+:10541000FB41860014260000E0A68500C326860016
+:105420001FB5022303930C330446C0F84C383821CF
+:105430004068E1F34DF4C4F85008D0B1D4F84C28DA
+:1054400000219200DCF3FCF56068E821E1F340F410
+:10545000C4F8480868B10021E822DCF3F1F5012323
+:1054600000936068D4F8481803AAB333DDF334F42A
+:1054700001E04FF0FF3004B010BDC0462DE9F04F01
+:10548000056997B0DDF884A014469B469DF88020FE
+:10549000EB63EB6FA860AB672A710746C5F800A005
+:1054A00028460E46FFF7AEFD249B05F1640205F188
+:1054B000680100930192029120465146229A239B53
+:1054C00003F00EFB2866002800F0D581D5F8648033
+:1054D00095494046DDF37CF220B100210A46DDF318
+:1054E00037F186B240469149DDF372F248B10021AE
+:1054F0000A46DDF32DF14FF6FF7380B2984218BFD4
+:10550000044630462146FDF7F9FF08B90C30B7E1F3
+:1055100040F612010022A5F84060A5F84240286E2E
+:10552000E5F36CF6E866286EE5F3BAF4D5F86C900E
+:105530006864C7F80C902846FFF782FD08B90D3063
+:105540009EE1286EEAF77EF92846002116F0C4DBBA
+:1055500028464FF0FF31E7F7A7F82846FFF7D8FDB8
+:1055600008B90E308CE140467149DDF305F2FF28A1
+:1055700008BF0120A5F84A002846FFF76DFD08B9CD
+:105580000F307DE16B494046DDF3F6F16A4985F85D
+:1055900048004046DDF3F0F16849E8644046DDF339
+:1055A000EBF1296E2865CA6A41F26B039A420AD16F
+:1055B0008B6A4E2B07D1B5F84A30402B03D9EB6CE0
+:1055C00043F00203EB64EB6C13F0200F04D00121D5
+:1055D00028460A4617F036DFB5F840200123A7F821
+:1055E0008021C5F89830B5F842303A68A7F8823182
+:1055F0002B6E284613616B6C936095F8483082F8E7
+:105600007C303A68B5F84A30B968A2F87A30EB6C69
+:10561000C2F880302B6DC2F88430D5F898305362D0
+:105620003A4605F057FA286708B9193028E12B6E79
+:10563000CDF810A005932B6FCDF81CB0B5F8402025
+:1056400006936B6CADF8302008932A6EB5F84230A3
+:10565000CDF82C80ADF83230936B04A80D93D36B4A
+:105660000E93136C0F9395F848301093936A11932F
+:10567000B5F84A301293D36A1393EB6C14932B6DE5
+:10568000159353680993D3680A9303F085FD6867FF
+:1056900008B91030F4E0B5F8421044F221339942D1
+:1056A00017D00E3B994214D00733994211D01033D2
+:1056B00099420ED0143B99420BD00733994208D03F
+:1056C0001033994205D02533994214BF0026012694
+:1056D00000E0012631462846E6F7CAFFAA6F002EF1
+:1056E0000CBF02230123136056603A6B286E1360CF
+:1056F0005660FC6AE5F3C2F32060D9F85C31696C4E
+:105700000F4A6B65AB65062301FB0323AC6FC5F83D
+:10571000B830686F49462268434603F0D5FE6062A0
+:1057200080B91130ACE0C046D1AD86004837860064
+:1057300084AE8600E5AE8600863786009E798600B8
+:10574000301E0200AB6F696D586AEDF747FBAB6F17
+:1057500003F1220203F11C01586A009203F11E02B8
+:10576000203303F0F9FCAC6F606A03F005FD84F8A8
+:105770002800AB6F3C6B586A03F0FEFC2075AC6FE1
+:10578000606A03F0FDFCA96FA061CB8B032B01D0F5
+:10579000122075E03B6B4A6A38461A618A8B1A817F
+:1057A000CA8B5A810A8C9A814A8CDA8140F2FF3284
+:1057B0004FF00F03CA828B8201223146FFF73CFD76
+:1057C00008B913305CE0B6F1FF3F3FF464AFAB6F54
+:1057D0003A68586A92F89910EDF704FB00212846C0
+:1057E00016F062DF08212846E7F772F8284618F01D
+:1057F00093DA286E2449254A00230097E5F3BAF48A
+:105800002846002118F06ADA2846E6F7FBFE08B9B8
+:10581000153035E005F1DC042146DCF3CDF62046F9
+:10582000DDF38AF048BB2046DDF396F0044620BB4A
+:10583000284616F099D8AB681B68D3F89C00F0B1E5
+:105840000378E3B112492A46DDF39AF1AB681149B6
+:105850001B682A46D3F89C00DDF3CCF1A868FFF75B
+:10586000DFFDE86858B1AB681B68D3F89C10DFF324
+:10587000BFF1204604E00B2002E0162000E00020EB
+:1058800017B0BDE8F08FC04669C1830085C18300B1
+:1058900025C0830049C0830010B590F85E300446EF
+:1058A0005BB90648EBF700FF054B20461A6805492F
+:1058B000FFF708FC012384F85E3010BD67DB0100B0
+:1058C000FC580300A4D2020010B5044619F058DFBA
+:1058D00001220146204619F0CBDF10BD37B5054641
+:1058E00019F04EDF0023C5F84C0280F848302A68D2
+:1058F000044692F82F10284600914E32214618F0A7
+:10590000EDDC30B12846214619F096DD4FF0FF302E
+:1059100003E02846214619F035DE3EBD37B5044682
+:10592000002847D0D0F8201131B103689868E9F316
+:10593000A7F60023C4F820312268136893F82F30AB
+:105940003BB3D2F8000501A92FF0C4DB13E0536884
+:1059500013F0400F0FD0D4F82C31D51807E00B68A6
+:105960004822C5F8103123685868E1F3C1F1D5F831
+:1059700010110029F3D101A82FF0B4DB0246002852
+:10598000E5D106E00B684068C4F840314822E1F3F5
+:10599000AFF1D4F8401120680029F3D1064922461E
+:1059A0000068FEF3D1F22368214658684FF4A472D0
+:1059B000E1F39EF13EBDC04691BA8600F0B54FF4CA
+:1059C000A47185B005464068E1F382F1064608B946
+:1059D000074655E000214FF4A4720746DCF330F38C
+:1059E000294B35600093294B29490193294B002409
+:1059F00003932868284A33460294FEF36DF2314639
+:105A00002A6B1368022B03D1537D0BB9163300E0C8
+:105A1000302301340B744431042CF1D1A8681F49A0
+:105A20002A460023E9F348F60446C6F8200130B9B7
+:105A3000686831464FF4A472E1F35AF11FE04FF465
+:105A40009673C6F81C3145F27353A6F838314FF0FF
+:105A50004603A6F83A31124B0024C6F840412846C6
+:105A600000934FF48A710F4A0F4B019505F066F9C8
+:105A7000A042C6F82C0103DA3046FFF74FFF274655
+:105A8000384605B0F0BDC046F90C8400DD120100B7
+:105A900094DB01007D0A840091BA86003D068400F3
+:105AA000D9128400E5128400A512840010B50146C5
+:105AB00020B10368B022D868E1F31AF110BDC046E6
+:105AC0002DE9F34107680546B021F868E1F300F1DC
+:105AD000064608B980468BE00021B02201AC804622
+:105AE000DCF3AEF20422002137607560C5F85C611A
+:105AF0002046DCF3A5F22A6892F87C30012B07D906
+:105B00003D495069DCF364F7014690B120460AE054
+:105B100050693A49DCF330F70928034609D8384977
+:105B2000204601EB83010322DCF342F300238DF8CE
+:105B3000073001AC0322214606F10800DCF338F3FC
+:105B40000023F3722B682F495869DCF315F7396984
+:105B5000F060CA6A41F26B039A420CD18B6A8B2BBC
+:105B600009D1022807D1204627490422DCF300F39B
+:105B700008B90323F360396941F26B03CA6A9A4298
+:105B80000DD18B6A932B0AD101A820490422DCF3A2
+:105B9000EFF220B9F368042B01D10233F36001AFB7
+:105BA000284639461FF054DE044650B91849384695
+:105BB0000322DCF3FDF2284639468DF807401FF03A
+:105BC00047DE05F5AA60394603220A30DCF3F0F21D
+:105BD000002405F5AA600F4985F85D450E300322C3
+:105BE000DCF3E6F285F861453046394620F0BADA52
+:105BF0004046BDE8FC81C046B3C48600B9C48600F7
+:105C0000CE028600BCC48600C3C4860071C2860072
+:105C1000C6C48600CAC4860070B50568044622461C
+:105C200028680449FEF390F1686821465022E1F3A8
+:105C30005FF070BD3CE486002DE9FF410546502130
+:105C40004068E1F345F0064608B904465AE00021F1
+:105C500050220446DCF3F4F1FF210422356006F102
+:105C60003B00DCF3EDF1284619F08ADD002790F8BF
+:105C7000483080F8387586F83B3096F840304FF061
+:105C8000FF3843F00803202186F840301F4AC6F849
+:105C9000488006F11800DCF317F27061304626F0F8
+:105CA000B5DF042128461A4A1A4B0097019605F0E1
+:105CB00045F8B84230611FDB174B02970093174B32
+:105CC00017490193174B184A039328683346FEF38C
+:105CD00003F188B9012586F83A50304629F00ADAEE
+:105CE00018B13046294627F0FFD9A37BA4F84C8091
+:105CF00043F00203A37305E0686831465022E0F3E5
+:105D0000F7F70024204604B0BDE8F08140E48600A7
+:105D10001DDF8400F9DE8400F51D01001DED840007
+:105D200024E40100DDD084003CE4860070B5054623
+:105D3000002826D00368134918682A46FEF304F1A8
+:105D40006B6905E01C68596828462AF0E7DD2346A0
+:105D5000002BF7D12B6905E01C68596828462AF00A
+:105D6000DDDD2346002BF7D1A96A21B12B689022F3
+:105D70005868E0F3BDF72B68294658682C22E0F3F9
+:105D8000B7F770BD91E6860030B52C21044685B08A
+:105D90004068E0F39DF708B9054618E000212C2281
+:105DA0000546DCF34DF10823AB610A4B2C600093F0
+:105DB0000023019302930393074A2B462068074967
+:105DC000FEF38AF02268012382F896302B71284670
+:105DD00005B030BD050B850091E6860004E50100A5
+:105DE0002DE9F047154680460F461E46E5F346F07E
+:105DF000002181464046E5F313F200220446114695
+:105E00000F480B185B6873B90C3302FB03F31D508A
+:105E10001A18636A576096600A4A45EA03031360DA
+:105E20006362012404E001320C31052AE8D1002428
+:105E300040464946E5F3F4F12046BDE8F087C04608
+:105E40003C260000782600002DE9F04705468846EC
+:105E5000E5F350F100212846E5F3E2F10646284635
+:105E60006C69AF69E9F7E8FA0A2C814616D90F2C5C
+:105E700019D02846E9F768FD142C054603D9B36804
+:105E800023F00803B360B36843F00103B36003D9A0
+:105E9000B36843F00803B360012211E0022C02D87A
+:105EA000174D30220CE02846E9F758FDD6F8A4300B
+:105EB000054623F0FF0343F00203C6F8A430022294
+:105EC000B36813F0010F07D107F01803082B14BFB4
+:105ED0004FF4E115B5FBF2F507F0030700240BE0E2
+:105EE00006F54073B8F1000F05D003EB04204946D6
+:105EF0002A460023C0470134BC42F1DBBDE8F087ED
+:105F000000C63E0537B5134B1546136001E0114B33
+:105F100013600432ADF17C039A42F8D3033020F0D1
+:105F200003000D4BC0EB01041C600C4B00211960F9
+:105F30000B4B05F5A05219600A4B083C19600A4B3F
+:105F400041601D60094B1A60094B1960094B0460E0
+:105F500058603EBD4B415453C826000088260000BF
+:105F6000A4260000CC260000F8270200FC2702002F
+:105F700090260000C0260000436910B5142B01DDF7
+:105F800002F09CFB10BDC0461FB5E8200021E0F3E5
+:105F90003DF20C4C2060A0B10021E822DCF350F06F
+:105FA00004AA012342F8043D013B0093064B2168FB
+:105FB000186840F23C73DCF38FF620680E21DCF3A6
+:105FC000D5F61FBDBC26000024280200B1F5E06F05
+:105FD00073B505460C46164606D1036900910021AB
+:105FE00001911C680A460CE00D4B00221868E5F38D
+:105FF00005F1014680B12B690022009401921C68D2
+:1060000028463346A04738B1064AA86113680020E5
+:106010002B626E61156001E04FF0FF307CBDC04621
+:106020008C260000202802002DE9F04710200E46A3
+:10603000002117469946E0F3E9F1044610B96FF0E4
+:106040001A001EE0104D2868E4F318F7099B8046FB
+:1060500023B9286831463A46E5F3D0F02868E4F3DE
+:1060600089F701238340094AE360089BC4F8049040
+:10607000A36013682868236041461460E5F3D0F0FC
+:106080000020BDE8F087C0468C260000982600005E
+:1060900007B50021E5F3C4F0074B4FF40061186029
+:1060A000064B00F57060186000200246044B00901B
+:1060B0000190FFF7B9FF0EBD9C260000F4270200F7
+:1060C0006D60800037B5234B234C02AD00211C22AC
+:1060D00045F8043D2046DBF3B3F7012323601F4B53
+:1060E000A5F5A0551B6843F8044C00F00DF92946AE
+:1060F0002A461B48FFF706FFE0F344F300F042F89E
+:10610000002002F01FFA174B174C186002F0BCFC7D
+:106110002060FFF7BDFF206800F01EF9E9F716F8D0
+:10612000206800F0A5F8002210481149E0F3E2F4DD
+:10613000002210481049E0F3DDF410490022104815
+:10614000E0F3D8F42068FFF717FFFFF71DFF206882
+:106150003EBDC046ADDEADDE00280200F81E0200E6
+:1061600000590300242802008C260000D81F860056
+:1061700059EF0000DB1F8600656580008D608000A0
+:10618000DE1F860070B5A4200021E0F33FF1124D20
+:10619000286080B10021A422DBF352F74FF4806025
+:1061A00000212C68E0F332F1A060286884682CB9E3
+:1061B000E0F392F02C604FF0FF300CE04FF480627F
+:1061C000C2608460446100212046DBF339F72A680D
+:1061D000024B00201A6070BD38280200D42600004F
+:1061E00070B51C4D06462B6833B91B4C23680BB9A0
+:1061F000FFF7C8FF23682B60164C184B20685861C6
+:1062000030B3002505604560336CC0F89C500E3BF0
+:10621000012B03D930461249FFF716FE114A936845
+:1062200013B12368C3F89C20246807E0D4F89C00CD
+:1062300018B1A368595DE0F349F4013523699D4223
+:10624000F4D3094809492246E0F354F4014B186895
+:1062500070BDC046D4260000382802000028020085
+:106260009562020028280200BD218600A5688000F2
+:1062700010B54022002305490446FFF7B1FD044B49
+:1062800000229A602046FFF7ABFF10BDA96980008D
+:106290002828020070B51B4DAE68002E31D11409BC
+:1062A0002C60AB8104F561444FF4E13394FBF3F4CB
+:1062B000A8606960284603218022E0F3FDF32846A8
+:1062C0003146E2B2E0F3F8F3284601212212E0F36E
+:1062D000F3F303210A462846E0F3EEF301210A46D0
+:1062E0002846E0F3E9F3284604210822E0F3E4F32A
+:1062F000284602210122E0F3DFF34FF47A70E0F345
+:106300002BF270BD28280200104A0721136843F0C1
+:1063100010031360136843F008031360136823F439
+:1063200000731360E832136843F0807343F48033E2
+:106330001360074B00221960043B1A6008331A6887
+:106340001960044B20221A607047C04614ED00E02B
+:10635000241000E000E400E02DE9F041054600F0E3
+:10636000ADF82A48E8F778FC2846E9F73BF8284BCF
+:10637000284AC318B3FBF2F3274A28461360E9F70B
+:10638000D9FA00F5787007304FF47A73B0FBF3F068
+:10639000224B234A18602B6A2249002BCCBF6FF096
+:1063A0007F4340F2FF3313601D4A1F4F1368B3FB56
+:1063B000F0F31360284620220023FFF711FD002090
+:1063C0001A49DCF3D9F204463860E8B12846E9F707
+:1063D00009F8B4FBF0F0861E002E15DD144C0021E8
+:1063E00034222046DBF32CF6124B4FF47A71A36073
+:1063F0006560204606FB01F10122DFF3FBF618B1D0
+:1064000028463968DEF306F2BDE8F08191F100001C
+:106410003F420F0040420F00D0250000C825000079
+:10642000CC25000001678000E8260000BEE60100E0
+:1064300040280200E56680002DE9F04707461E4629
+:1064400015460C46E4F356F63846E4F317F52946AC
+:10645000324681463846E4F3D1F63846E4F38AF50D
+:1064600040F62A01064600223846E4F3C7F6054600
+:106470008CB1012414FA06F3826932EA030802D1CE
+:106480002046E8F7A9FB701C14FA00F0E8F786FB39
+:10649000C5F818800CE00124701C14FA00F0E8F72D
+:1064A0009BFB2046B440E8F779FBAB691C43AC6129
+:1064B00038464946E4F3B4F6BDE8F0872DE9F047E5
+:1064C0000746E4F317F6384640F60E010022E4F3DF
+:1064D00095F60446002831D0D0F80080056838468B
+:1064E000E4F3DEF40428064604D827D1C5F30243BA
+:1064F000032B23D100204849DCF33EF2F0B9474991
+:10650000C8F3031212E0013A072E22610AD90C2EB9
+:1065100008D0236C13F4806F02D013F4006F01D104
+:1065200008B903E0012041F004516161002AEAD179
+:10653000D4F8E83123F01003C4F8E831002240F623
+:106540002A013846E4F35AF6354C20603846E4F325
+:10655000A7F4344B22681860136843F6A12443F073
+:1065600080731360136843F0020313600023C2F8C2
+:10657000E03103E00A20E0F3EFF00A3CDFF8A090FE
+:10658000D9F80030D3F8E03113F4003F01D1092CE1
+:10659000F0D100210B4638464FF40062FFF74CFF64
+:1065A00000210B46384640F61202FFF745FF002156
+:1065B0000B46384640F62902FFF73EFF38460121D8
+:1065C000E8F73EFF00201849DCF3D6F1E0B1384689
+:1065D000E4F354F440F62A01804600223846E4F3FE
+:1065E0000DF646690446D0F898503846E4F346F470
+:1065F0000123834045F00105334363613846C4F805
+:1066000098504146E4F30CF6D9F80020136A43F0A1
+:1066100003031362BDE8F0872DE70100FF7F01004F
+:106620007428020078280200BEE6010010B58469D3
+:10663000A068FCF729FCE068E9F7E4F8002010BD49
+:1066400010B584690021342204F11C00DBF3F8F456
+:10665000034BA06863622462EBF794F8002010BD3E
+:1066600005AA80002DE9F347DFF8AC809946D8F8F9
+:1066700000300546072B0F46924643DC01F062FFCF
+:1066800050210646E0F324F3044600283AD00021C6
+:106690005022DBF3D5F4D8F8003065602360A4F80D
+:1066A00014902761E660204641F2E4414A463346B1
+:1066B0000097CDF804A0FCF739FCA06010B30020CF
+:1066C0000A990B9A114B0095CDF804A0FFF7ACFC8A
+:1066D00018B1A068FCF7D8FB14E0A068E2F3B4F6A8
+:1066E0000B49A061D8F800202846DBF3FDF40948E7
+:1066F0002946EAF7D9FFD8F8003020460133C8F818
+:10670000003000E00020BDE8FC87C04631AA8000D0
+:106710005CB102003CB102007C280200014610B5C9
+:1067200050228068E0F3E4F210BDC046C36B10B5A0
+:106730001BB100225A62836B5A62C068FFF7EEFFFA
+:1067400010BDC0462DE9F041184E1C46337807466F
+:10675000072B904626D820464C21E0F3B9F2054697
+:1067600000B300214C22DBF36BF46C602F60C5F8A2
+:1067700008803378204685F8443001333370022393
+:10678000AB640821E0F3A4F20446286420B10021A0
+:106790000822DBF355F406E029464C22E0F3A8F288
+:1067A000254600E000252846BDE8F081802802004B
+:1067B0002DE9F04FD1F8FC3091B00F93054603F569
+:1067C0006063079335E10FAF0E2200232846394658
+:1067D000D9F37AF60F28044600F0368100222846C5
+:1067E00039461346D9F370F610F00E0640F02681B4
+:1067F00040F23B43B3EB145FC4F30B21C0F3041826
+:1068000004D140F6FF73994200F01381C0F3442293
+:106810000992002A00F00D81C0F3C443C0F3843B09
+:1068200013EB0B02089319D140F26733994240F001
+:1068300000810EAB01930DAB02930CAB03930BAB3A
+:1068400004932846394613460092D9F3DBF5002815
+:1068500000F0EF800E9BC5F85433EAE0D5F8CCA0E9
+:1068600005EB8A03C3F8D4423446C3F81403C3F8D3
+:10687000D0100BE00122284631461346D9F324F606
+:1068800000F00E00022840F0D980013444450FAEDC
+:10689000F0D1002213460DF138090DF134080CAF88
+:1068A0000BAC284631460092CDF80490CDF8088014
+:1068B00003970494D9F3A6F50246E8B94023009360
+:1068C000284631461346CDF80490CDF8088003974A
+:1068D0000494D9F397F510B14FF001080EE00D9B29
+:1068E000002B40F0AB800B9B002B40F0A7800C9B53
+:1068F000B3F5805F40F0A2804FF000080E9A05EBE0
+:106900008A03C3F810210C9A0124C3F8D0210EABDE
+:1069100001930DAB02930CAB03930BAB00220493DA
+:1069200028460FA923460092D9F36CF508B9012730
+:1069300027E0012C40F086800C99B1F5805F40F093
+:1069400081800E9B05EB8A02C2F89031C2F81012CA
+:1069500078E00024002300930EAB01930DAB02936B
+:106960000CAB03930BAB049328460FA93A4623467E
+:10697000661CD9F347F508B13446EBE7002E5DD02D
+:106980000137099A9742E4D100241FE0C023009305
+:106990000EAB01930DAB02930CAB03930BAB0493C3
+:1069A00028460FA922460023D9F32CF5002845D00C
+:1069B0000B9B002B42D10C9BB3F5805F3ED124B9D9
+:1069C0000E9B05EB8A02C2F8943201345C45DDD19E
+:1069D000002423E0802300930EAB01930DAB0293C0
+:1069E0000CAB03930BAB049328460FA9012F0CBFEC
+:1069F0002246621C0023D9F305F5F8B10B9BEBB9D5
+:106A00000C9BB3F5805F19D1BBF1000F05D124B900
+:106A10000E9B05EB8A02C2F894320134089B9C421B
+:106A2000D8D1B8F1000F04D1D5F8CC300133C5F876
+:106A3000CC300F9B079A9342FFF4C5AE0023C5F8F4
+:106A4000CC3001E0013462E711B0BDE8F08FC04600
+:106A500082604160016070470EB4F3B581680646FC
+:106A6000012901D8002044E008AB4068079A01934F
+:106A7000DBF31CF4B0F1FF3F074603D0B368023BE1
+:106A8000984203DD00231846B36032E070683D2170
+:106A9000DBF33AF330B373683568C3EB00041EE0F0
+:106AA00028462246DBF34CF2A8B92B5D3D2B12D1D0
+:106AB0002846DBF355F37268441CBA1829190132D1
+:106AC0002846521ADBF38EF273681B1B7360B3689F
+:106AD0001B19B36006E015F8013B002BFBD1716870
+:106AE0008D42DDD3B368781C1B1AB36073681B1822
+:106AF0007360BDE8FC4003B07047C0462DE9F0412B
+:106B0000C1EB0204012C0E461F46DDF8188010DD93
+:106B10002146E0F3DDF0054610B96FF01A000DE0F4
+:106B200031462246DBF328F200203D60C8F80040E1
+:106B300004E000233B60C8F800301846BDE8F0814F
+:106B40002DE9F04FA5B008914FF4805109900792BC
+:106B50000693E0F3BDF00A9018B96FF0010401F05C
+:106B600029B921A80A994FF48052FFF771FF4FF419
+:106B700080520A980021DBF363F200234FF0FF32CA
+:106B80008DF844300B930D930E9201F0DEB80D9BFF
+:106B9000089A002152F8239001230C910F930F9B28
+:106BA00019F8012073B1531EDBB2FD2B01F101086E
+:106BB00098BF19F808B016468CBF4FF0000B08F1CB
+:106BC00001080CE002F1FF33DBB2FE2B93462CBF31
+:106BD0001646802628BF4FF0000B01F101080BEB91
+:106BE0000803B3F5607F81F2AD80202E2AD005D84E
+:106BF000152E0AD01B2E6DD001F078B8222E3AD077
+:106C000036D3802E72D001F071B808EB09035A78A0
+:106C100019F8083003EB0223072B13DD09F10204F6
+:106C2000444421AD874922462846FFF715FF2046F8
+:106C3000DBF396F209F1030200EB080382492846D0
+:106C4000D2184FE008EB0904637819F8082021AD49
+:106C500002EB032228467D49FFF7FEFEE378A27887
+:106C600028467B4902EB0322FFF7F6FE01F03EB80F
+:106C700019F8082003E00C9B0C2B03D100220C9286
+:106C800001F036B89DF84430002B41F0318019F8FE
+:106C90000830042B41F02C8009F1020404EB0805B4
+:106CA0002846DBF359F6002841F0228014F808301A
+:106CB00013F0010F41F01C80284611A9DBF394F476
+:106CC0000E9BB3F1FF3F41F0138008EB09039A7963
+:106CD000DB790DE108EB0903DC799A795D4921A89C
+:106CE00042EA0422FFF7B8FE01F002B819F80830B2
+:106CF000822B00F2FD87DFE813F09200B300380129
+:106D00003B02D4021102CB01DA014701EA02FB0285
+:106D100010031703FB077F020302FB073603570329
+:106D200097007A037F0390039503F700E903FB07BD
+:106D3000770107047F01FB07FB07FB071004220410
+:106D4000270472045305FB07FB0721068D0088000A
+:106D50008300AE06D306DA06E106FB0726037101BF
+:106D6000FB07FB070001F007E806FB07FB07FB0733
+:106D7000FB07FB07FB07FB07FB0787011307280738
+:106D8000490764077F079907B307CD07D407FB07B7
+:106D90008E01FB07FB07FB07FB07FB07FB07FB0756
+:106DA000FB07FB07FB07FB07FB07FB07FB07FB07D3
+:106DB000FB07FB07FB07FB07FB07FB07FB07FB07C3
+:106DC000FB07FB07FB07FB07FB07FB07FB07FB07B3
+:106DD000FB07FB07FB07FB07FB07FB07FB07FB07A3
+:106DE000FB07FB07FB07FB07FB07FB07FB07FB0793
+:106DF000FB07FB07FB07FB07FB07FB07FB07DE07A0
+:106E000009EB0804002500F00BBE09EB080400257F
+:106E100000F0F4BD09EB0804002500F0DEBD0E49CA
+:106E200008EB090321A8DDE008EB0901CA780B791A
+:106E3000120442EA03624B7821A81A438B7807496F
+:106E40007EE2C04640B202009CB40200FEB10200E5
+:106E500093B5020062B80200D9B3020075B1020016
+:106E600008EB0904A378627821AE02EB0322AE4955
+:106E70003046FFF7F1FD2379E2783046AB4902EB6B
+:106E80000322FFF7E9FDBBF1060F40F23187A3793A
+:106E900062793046A64902EB0322FFF7DDFDBBF124
+:106EA000080F40F22587237AE2793046A14902EBA8
+:106EB0000322FFF7D1FDBBF10A0F40F2198709F158
+:106EC0000A0409F1090514F8083015F808209A4950
+:106ED00002EB03223046FFF7BFFD14F8083015F827
+:106EE0000820964930464CE008EB09039A785B7815
+:106EF00003EB02220E9200F0FBBE0623904ABBFB7E
+:106F0000F3F309EB08074FF0000A137027E019ADFF
+:106F1000534610218B4A1DAE2846DBF3D5F053466D
+:106F20001021894A3046DBF3CFF0BB787A7821AC68
+:106F300042EA032229462046FFF78EFD7A79BB7983
+:106F4000120442EA0362FB7820461A433B79314639
+:106F500042EA0322FFF780FD0AF1010A0637784B67
+:106F60001B789A45D3DB00F0C3BEBBF1020F21A80A
+:106F700008EB090202D175495278B3E69378734958
+:106F8000527802EB0322ADE608EB0904A27863789D
+:106F9000BBF1040F03EB022505D92379E2781B0628
+:106FA00003EB02431D4321AE304669492A46FFF7F1
+:106FB00053FDBBF1060F40F29B86A2796379BBF1CA
+:106FC000080F03EB022505D9237AE2791B0603EBB0
+:106FD00002431D435F4930462A4683E65E4908EB7B
+:106FE000090321A85A787DE608EB09039C785A78B2
+:106FF000524921A800F05BBE0BF101035FFA83FB4D
+:1070000000230F9300F074BE08EB09039C785A78B4
+:10701000524921A864E64A4B4FEADB0209EB080714
+:107020004FF0000A1A702DE01DAD53461021454A5D
+:1070300019AE2846DBF348F053461021424A304649
+:10704000DBF342F0FA783B79120442EA03627B7880
+:1070500021AC1A43BB78294642EA03222046FFF7B7
+:10706000FBFCFA793B7A120442EA03627B79204600
+:107070001A43BB79314642EA0322FFF7EDFC0AF1DD
+:10708000010A08372E4B1B789A45CDDB00F030BE45
+:1070900021AD08EB0904284631496278FFF7DCFC92
+:1070A000BBF1020F40F224862E49284659E121AD5A
+:1070B00008EB0904002228462B496378FFF7CCFC33
+:1070C000BBF1020F40F20F86012228462649A37821
+:1070D000FFF7C2FCBBF1030F00F005860222284631
+:1070E0002149E378FFF7B8FCBBF1040F00F0FB8502
+:1070F00028461D4903222379FFF7AEFC00F0F3BDBB
+:1071000021AC08EB090517496A782046FFF7A4FC73
+:107110001549AB782046012200F0DCBD134908EB8D
+:10712000090321A85EE7C046B4B6020075B70200A5
+:10713000BEB502000AB2020021B3020021B2020071
+:107140008128020038E7010043E7010056B302003E
+:1071500037B7020082B2020054B40200CAB702007C
+:1071600081B10200ACB7020081B4020045B8020050
+:10717000ABF10203082B00F2BB85DFE813F0090036
+:10718000B905B905B905B9052B001C0015000E009D
+:10719000A74908EB090321A824E708EB090321A864
+:1071A000A4495A7AFFF758FC08EB090321A8A04923
+:1071B0001A7AFFF751FC09F1070521AC9E4915F831
+:1071C00008202046FFF748FC20469C4915F8082077
+:1071D000FFF742FC9A4D09EB0804A3786278294630
+:1071E00002EB032221A8FFF737FC964B0935023446
+:1071F0009D42F2D100F07CBDBBF1140F19D0BBF160
+:10720000170F04D0BBF1130F1AD000F071BD21ACE1
+:1072100008EB09058C49AA7D2046FFF71DFC8B4928
+:107220006A7D2046FFF718FC204689492A7DFFF732
+:1072300013FC08EB090321A88649DA7CFFF70CFC54
+:10724000854D09EB0804A3786278294602EB0322F6
+:1072500021A8FFF701FC814B093502349D42F2D190
+:1072600009EB08057E4E2C46237AE279314602EB83
+:10727000032221A8FFF7F0FB7A4B0B3602349E4223
+:10728000F2D1794CAB7B6A7B214602EB032221A829
+:10729000FFF7E2FB754B0B3402359C42F2D100F054
+:1072A00027BD08EB0901C8784A788B7800900879E7
+:1072B00001904879029088790390C8790490097AFE
+:1072C00021A805916A49FFF7C7FB00F011BD09EB42
+:1072D000080400256378FF2B04D021A865492A46BD
+:1072E000FFF7BAFB01350134042DF3D100F000BDE6
+:1072F00008EB09035A780AB19B7823B921A85E49A3
+:10730000FFF7AAFB03E021A85C49FFF7A5FB08EB08
+:1073100009035B49DA7821A8E4E408EB09039C78C7
+:107320005A78584921A8DBE408EB0901CA780B799F
+:10733000120442EA03624B7821A81A438B7852491F
+:1073400042EA0322CEE421AD08EB090428464F4966
+:107350006278FFF781FBBBF1020F40F2C9844C4910
+:107360002846A278BEE409F1010515F8082021ACF1
+:10737000484902F00F022046FFF76EFB15F808207F
+:107380004549120909F102052046FFF765FB15F88A
+:107390000820424902F007022046FFF75DFB15F87E
+:1073A00008203F4920461FE009F1010515F8082093
+:1073B00021AC3C4902F00F022046FFF74DFB15F8C7
+:1073C00008203949120909F102052046FFF744FB5C
+:1073D00015F80820354902F007022046FFF73CFB6C
+:1073E00015F8082032492046C2F3C1027AE4314937
+:1073F00008EB090321A8F5E521AC08EB09052E49A6
+:107400006A782046FFF728FB2C49AA782046FFF728
+:1074100023FB2B49EA78204664E42A4908EB090358
+:1074200021A8DFE5284908EB090321A8DAE5C046D1
+:10743000ECB60200ADB602009FB50200E3B1020057
+:1074400022B402003DB40200D4B10200EDB2020049
+:1074500049B30200F1B1020002B602001DB60200FB
+:10746000EEB302000FB40200F9B602001AB7020030
+:1074700050B7020097B1020025B802003AB80200E6
+:1074800058B802005DB4020004B80200B6B70200AA
+:10749000E4B3020068B102003DB40200B3B10200DF
+:1074A00047B7020091B7020075B20200F7B70200B9
+:1074B000C1B7020010B8020068B40200A4B602000E
+:1074C0004AB4020046B502000AB3020009F1010401
+:1074D00004EB08052846DBF33FF2002840F008845F
+:1074E00014F8083013F0010F40F00284284611A967
+:1074F000DBF37AF00E9BB3F1FF3F40F0F98308EB2A
+:1075000009035A799B79F3E408EB09039A785C78CC
+:107510008C49120621A8FFF7E3BB08EB090421AD53
+:10752000894962782846FFF797FA8849A278284661
+:10753000FFF792FA2379E2788549284621E58549C3
+:1075400008EB090321A84DE508EB0906B378747828
+:1075500021AD04EB0324A4B2E20A7F492846FFF7D9
+:107560007BFA7E49C4F302222846FFF775FA7C496C
+:10757000C4F3C4022846FFF76FFA7A49C4F3410204
+:107580002846FFF769FA2846774904F00102FFF719
+:1075900063FABBF1040F40F2AB833379F47873499B
+:1075A00004EB0324A4B2E20A2846FFF755FA704917
+:1075B000C4F302222846FFF74FFA6E49C4F3C4020F
+:1075C0002846FFF749FA6C49C4F341022846FFF701
+:1075D00043FA6A49284604F00102FFF783BB08EB2F
+:1075E000090621AF664972783846FFF735FA4FF041
+:1075F000000A6449B2783846FFF72EFACDF800A0A9
+:107600003279F378604903EB022301930222534657
+:107610003846FFF721FACDF800A0B27973795A49BC
+:1076200003EB02230193022201233846FFF714FAE9
+:10763000CDF800A0327AF379384603EB0223022218
+:10764000019351491346FFF707FABBF11E0F40F2B1
+:107650004F834E49727A3846FFF7FEF94C49B27AA9
+:107660003846FFF7F9F94B49F27A3846FFF7F4F953
+:107670004949327B3846FFF7EFF9CDF800A0B27BDD
+:10768000737B414903EB022301930522534638469D
+:10769000FFF7E2F9CDF800A0327CF37B3A4903EB27
+:1076A00002230193052201233846FFF7D5F9CDF8CF
+:1076B00000A0B27C737C344903EB022301930522C2
+:1076C00002233846FFF7C8F9CDF800A0CDF804A092
+:1076D000327DF37C314903EB0223029305226C23B4
+:1076E00001253846FFF7B8F90095CDF804A0B27D22
+:1076F000737D2A4903EB0223029305226C2338464B
+:107700000224FFF7A9F90094CDF804A0327EF37D9E
+:10771000224903EB0223029305226C233846FFF72C
+:107720009BF9CDF800A0CDF804A0B27E737E384658
+:1077300003EB02230293194905226823FFF78CF912
+:107740000095DFE0D7B5020086B5020050B5020013
+:1077500077B502002BB70200E7B7020093B2020030
+:10776000A0B2020071B80200A4B1020046B6020045
+:107770008EB80200C1B802008BB40200D8B7020074
+:10778000E3B102005DB5020080B702002AB6020034
+:107790002FB30200E4B5020048B202000FB40200A9
+:1077A00008EB090621AFAF4972783846FFF754F964
+:1077B0004FF0010AAC49B2783846FFF74DF9CDF8E1
+:1077C00000A03279F378A94903EB02230193022246
+:1077D00000233846FFF740F9CDF800A0B27973795D
+:1077E000A24903EB02230193022253463846FFF7D6
+:1077F00033F9CDF800A0327AF379384603EB02234F
+:107800000222019399491346FFF726F9BBF11E0F97
+:1078100040F26E829649727A3846FFF71DF9954913
+:10782000B27A3846FFF718F99349F27A3846FFF7EB
+:1078300013F99249327B3846FFF70EF9CDF800A0D4
+:10784000B27B737B894903EB02230193052200235A
+:107850003846FFF701F9CDF800A0327CF37B83496D
+:1078600003EB02230193052253463846FFF7F4F851
+:10787000CDF800A0B27C737C7C4903EB022301931A
+:107880000522022300253846FFF7E6F80095CDF8DB
+:1078900004A0327DF37C7A4903EB02230293052294
+:1078A0006C233846FFF7D8F8CDF800A0CDF804A037
+:1078B000B27D737D724903EB0223029305226C2390
+:1078C00038460224FFF7C8F80094CDF804A0327EB1
+:1078D000F37D6B4903EB0223029305226C233846A8
+:1078E000FFF7BAF80095CDF804A0B27E737E384653
+:1078F00003EB02230293624905226823FFF7ACF8E9
+:10790000CDF800A0CDF804A0327FF37E384603EB1B
+:1079100002230293052268235949FFF79DF800943A
+:10792000CDF804A0B27F737F384603EB02230293A5
+:10793000534905226823FFF78FF8D9E108EB0904C2
+:10794000A378627821AD02EB03224E492846FFF767
+:1079500083F86279A379120402EB0362E378284684
+:10796000D2182379484902EB0322FFF775F8BBF1DF
+:10797000120F40F2BD81627AA37A120402EB036215
+:10798000E3794249D218237A284602EB0322FFF713
+:1079900063F8627BA37B120402EB0362E37A28465E
+:1079A000D218237B3A4902EB0322FFF755F8627C99
+:1079B000A37C120402EB0362E37BD218237CABE0CE
+:1079C000A278637821A803EB0223009331492B4668
+:1079D0000222FFF741F801350234B5EB5B0FEFDD12
+:1079E00086E1A278637821A803EB0223009329495A
+:1079F0002B460522FFF730F801350234B5EB5B0F5B
+:107A0000EFDD75E10095A278637821A803EB0223EE
+:107A10000193214905226C23FFF71EF8013502343A
+:107A20004FEA9B06B542EDDD002411E008EB5B0355
+:107A30004B44009403EB44039A785B7821A803EB52
+:107A400002230193144905226823FFF705F8013446
+:107A5000B442EBDD4CE108EB09039C785A780F49FE
+:107A600021A824E1FCB202006AB5020080B702003E
+:107A700038B602003CB30200F3B5020057B2020070
+:107A80000FB402004BB802009EB70200C9B5020055
+:107A900066B2020030B2020056B60200ABB4020079
+:107AA00008EB09039C785A78934921A8FFE008EB7A
+:107AB00009039C785A78914921A8F8E008EB09035A
+:107AC0009C785A788E4921A8F1E008EB0904E27805
+:107AD0002379120402EB0362637821ADD218A378F4
+:107AE000884902EB03222846FEF7B6FFE279237AA3
+:107AF000120402EB036263792846D218A379824903
+:107B000002EB0322FEF7A8FFE27A237B120402EBCA
+:107B10000362637AD218A37A7C492846FFF731BA08
+:107B200008EB0904A378627821AD2846784902EB76
+:107B30000322FEF791FFBBF1040F40F2D9802379B5
+:107B4000E27874492846FFF71CBA08EB0904E2788A
+:107B50002379120402EB0362637821ADD218A37873
+:107B600028466D4902EB0322FEF776FFBBF1060FB4
+:107B700040F2BE80E279237A120402EB0362637959
+:107B80006649D218A3792846FFF7FBB9644E09EB82
+:107B900008040225AB45C0F2AB80E27823791204D9
+:107BA00002EB036263783146D218A37821A802EB76
+:107BB00003220435FEF750FF043418361A2DE9D19C
+:107BC00096E0584E09EB08040225AB45C0F29080C0
+:107BD000E2782379120402EB036263783146D2180B
+:107BE000A37821A802EB03220435FEF735FF043405
+:107BF00013360E2DE9D17BE04B4E09EB080402252C
+:107C0000AB4575DBE2782379120402EB03626378FB
+:107C10003146D218A37821A802EB03220435FEF7DF
+:107C20001BFF043414360E2DEAD161E03F4E09EB00
+:107C300008040225AB455BDBE2782379120402EBF2
+:107C4000036263783146D218A37821A802EB03229D
+:107C50000435FEF701FF043414360E2DEAD147E057
+:107C6000334E09EB08040225AB4541DBE27823796A
+:107C7000120402EB036263783146D218A37821A87C
+:107C800002EB03220435FEF7E7FE043414360E2D12
+:107C9000EAD12DE008EB09039C785A78254921A800
+:107CA00005E008EB09039C785A78234921A802EBE8
+:107CB0000422FFF717B808EB0901CB780A791B04F7
+:107CC00003EB02634A788C789B181C4921A8012297
+:107CD00003EB0423FEF7C0FE0AE0194908EB090391
+:107CE00021A8FFF77FB901220B9201E0FF2E29D0D6
+:107CF0000BEB0801FEF753BF19B802008BB102006D
+:107D00001DB60200C9B5020066B2020072B40200DC
+:107D10009BB80200AEB80200C0B60200D6B60200A0
+:107D2000B6B4020064B30200B1B202009DB3020017
+:107D300068B6020014B30200C0B102001AB7020014
+:107D4000ACB502000D9B01330D930D9A079B9A422F
+:107D50007EF41DAF0E9AB2F1FF3F03D021A8174960
+:107D6000FEF77AFE9DF8443023B121A8144911AAE8
+:107D7000FEF772FE00201349DAF32AF638B90B9B9E
+:107D80002BB91A4621A81049FF33FEF765FE229A47
+:107D9000002302F8013B2E9B0A9900930998069B49
+:107DA0002292FEF7ABFE0A9904464FF480520998DE
+:107DB000DEF39EF7204625B0BDE8F08F82B80200C2
+:107DC0002FB802000E5D860081B402002DE9F04F4D
+:107DD0009A468FB000230D936D4B06461C7889465A
+:107DE0000592002C40F0C180142208A82146DAF345
+:107DF00027F17369232B05DC01224FF0040B069455
+:107E0000079214E01C222346304621460094E3F3F7
+:107E10003DF00028ACBF03230123ACBF00220122A8
+:107E200007930692ACBF4FF00C0B4FF0020B30469D
+:107E3000E2F3E0F70128054602D0022806D013E05D
+:107E400030464946DAF330F040000CE03046FAF7AD
+:107E500047FF044640B1D9F3D5F710F4807F03D033
+:107E60002046D9F3C5F70D900D99002900F08480C4
+:107E70004846DEF32DF7044610B96FF01A0083E090
+:107E8000012D0746DDF8348003D0022D0ED00025E9
+:107E90001CE0002102900091CDF80480039130464F
+:107EA000059A4B46D9F3FAF705460DE00EAB4FEABB
+:107EB000580243F8042D304601212246D9F356F7E3
+:107EC0000D9B05465B000D93002D45D123884FF691
+:107ED000FD72013B9BB2934205D94846214642467A
+:107EE000DEF306F74AE0069B1BB104EB4B03089355
+:107EF00015E0638804EB0B01227901EB132303EBFC
+:107F00000223A3F580530993E3880891CB18A3F5C6
+:107F100080530A932389C918A1F580510B91DDB9CB
+:107F2000189A4846009208A9079A5346FEF708FE99
+:107F300090B91849DAF320F538B1189B3046DAF8D1
+:107F400000101A6800F024FB06E0189B3046DAF8AF
+:107F500000101A6800F004FB27B148463946424633
+:107F6000DEF3C6F60A4B01221A700023189A18464F
+:107F7000CAF80030136007E00D468846064B00271C
+:107F8000089301230793CAE70FB0BDE8F08FC046FE
+:107F9000402700004EE7010019B2020013B5049C0F
+:107FA0009E4605994CB141B1002323600B600091BE
+:107FB00023467146FFF70AFF00E000201CBDC046C3
+:107FC000094A13888B4201D1002206E093888B4234
+:107FD00002D04FF0FF3005E00122034B03EB820398
+:107FE00093F902007047C0461CB902002DE9F04128
+:107FF000074614461E46002B7ED0E7F783FA054657
+:1080000002E0B34205D00C35002D75D02B88002B33
+:10801000F7D12B88002B6FD0D4F80036AA78C3F3A1
+:108020008403934268D0D4F81836642023F0C073D8
+:10803000C4F81836D4F81C3643F6A12623F0C073D2
+:10804000C4F81C36DEF388F303E00A20DEF384F381
+:108050000A3ED4F8E03113F4003F01D0092EF4D1E8
+:108060000023C4F86036EA782B79D4F864161B062E
+:10807000120502F4700203F07063134321F07F6174
+:108080000B43C4F864360223C4F86036D4F864366F
+:108090006A7923F0FE5323F4781343EA025343F43E
+:1080A0008023C4F864360323C4F86036D4F8642609
+:1080B000AB6802F07F4223F07F431343C4F8643679
+:1080C0003B6A012B05DDD4F8003643F48063C4F825
+:1080D0000036AA782988D4F8000692004FF68373F8
+:1080E0007F3102F07C0200EA0303C9111A4301390F
+:1080F00042EA0142C4F80026BDE8F081036A70B587
+:10810000092B054601DC00242CE0E2F3B7F6002140
+:1081100006462846E3F384F0D0F80836044613F404
+:10812000807001D1044619E04FF00043C4F86C366A
+:108130004FF47A70DEF310F3D4F86C360022DB04CF
+:10814000DB0C5B03C4F86C2603F54243064A03F5D7
+:10815000A873B3FBF2F3642203FB02F42846314612
+:10816000E3F35EF0204670BDA086010070B50446C2
+:10817000E2F384F6002105462046E3F351F0236A3A
+:10818000012B04D1D0F8003623F4007304E005DDA0
+:10819000D0F8003643F40073C0F800362046294674
+:1081A000E3F33EF070BDC0462DE9F04104461646AB
+:1081B0000D46E2F363F6002180462046E3F330F0FB
+:1081C0002946024633462046FFF710FF2046414627
+:1081D000E3F326F0BDE8F0812DE9F043002485B0FB
+:1081E000074603940294E2F349F621468146384655
+:1081F000E3F316F07B6A4E4A0546C3F3042605E016
+:10820000137AC5F82036D368C5F82836494B083AA2
+:108210009A42F5D14FF0000820E008216846464A0E
+:108220004346D9F351F700206946DAF3D1F398B108
+:1082300000210A46DAF38CF23B6A0C2B08DDB0F51C
+:10824000803F05D200F0FF02C0F3072342EA03405B
+:10825000C5F82086C5F8280608F10108B045DCD12C
+:10826000364C28E0E36A13B13846984710B3002132
+:108270001EE001238B40226A134218D0C5F8201655
+:1082800094F924302BB1012B05D0B3F1FF3F07D077
+:108290000DE0A36A09E0D5F82436A26A134304E08E
+:1082A000D5F82436A26A23EA0203C5F82436013140
+:1082B000B142DED1103C224B9C42D3D1002614E0C7
+:1082C000082168461F4A3346D9F3FEF60020694666
+:1082D0006C46DAF37DF338B10021C5F820660A4612
+:1082E000DAF336F2C5F8240601364645E8D103A98B
+:1082F00002AA3846DDF31CF5029B039941EA03020A
+:10830000D5F81C3642EA0303C5F81C360AB1C5F895
+:108310001C2609B1C5F818164FF4FA600292DEF374
+:108320001BF238464946E2F37BF705B0BDE8F0831F
+:1083300014B90200F4B8020051368600D4B8020025
+:10834000A4B80200563686002DE9F04385B00546F4
+:10835000E2F394F5002181462846E2F361F72B6AA7
+:108360008046042B6B6A01DDDF0E01E0C3F3436737
+:10837000002614E0102168460D4A3346D9F3A4F6CE
+:10838000002069466C46DAF323F338B100210A462F
+:10839000DAF3DEF1C8F85066C8F854060136BE427A
+:1083A000E8D128464946E2F33BF705B0BDE8F08343
+:1083B0005B3686002DE9F043036A85B0042B436ADF
+:1083C0000546CCBFC3F38458C3F34358E2F356F5D4
+:1083D000002181462846E2F323F70026074615E0F0
+:1083E000102168460E4A3346D9F36EF600206946DE
+:1083F0006C46DAF3EDF238B100210A46DAF3A8F15F
+:10840000C7F85866C7F85C06731CDEB24645E7D16C
+:1084100028464946E2F304F705B0BDE8F083C046BC
+:1084200063368600F7B5053A06461F46062A2BD85E
+:10843000DFE802F00A0C12040E2A060005250CE003
+:108440001125032402230AE0012502E0052500E0AE
+:1084500011250F24042302E000251F240323009389
+:1084600000214FF4CB624FF0FF333046E2F30EF5BC
+:1084700004EA0703AB4030460093002140F25C62FF
+:1084800014FA05F3E2F302F5FEBDC0462DE9F04112
+:1084900005460E4600201749DAF36EF2164984B2FB
+:1084A0000020DAF369F240F2DC51002C18BF2146BB
+:1084B000C7B22846FFF784FDC0B210F0800F0CD180
+:1084C000C4B23146284607222346FFF7ABFF2846B1
+:1084D000314608222346FFF7A5FF2FB12846314633
+:1084E0003A460123E7F748F828463146FFF762FF8E
+:1084F000BDE8F0816F36860008F9010070B50546C9
+:108500000C46FFF721FF002221462846DDF364F5E3
+:108510002846E2F3B3F40A4904460020DAF32CF2C9
+:108520004FF4002210F001034FF00001284618BF5D
+:108530001346DDF385F428462146E2F371F670BD5B
+:108540007836860070B5002105461020DDF35EF711
+:10855000002110220446D9F373F52046656070BDF2
+:1085600070B50C461546E2F3C5F51021DEF3B0F305
+:1085700010B96FF01A0008E0044A10234360136832
+:10858000C460036085601060002070BD6C2700002F
+:1085900070B515460C46E2F3ADF51021DEF398F305
+:1085A000024610B96FF01A0010E01023436008492A
+:1085B000002303600B68C46085601BB9086018461F
+:1085C00004E0034618680028FBD11A6070BDC0465D
+:1085D0006C27000070B50C461546E2F38BF51021B0
+:1085E000DEF376F310B96FF01A0008E0044A1023A6
+:1085F00043601368C460036085601060002070BD34
+:108600006C270000064B10B51B683BB9054B196879
+:1086100021B1054B1A680AB1FFF7DCFF002010BD3D
+:108620006C270000FC1E0200001F020001207047A2
+:108630000020704710B50020DAF39EF110BDC0464F
+:1086400010B50B490446FFF7F5FF80B278B9E06F2B
+:108650000749DAF391F180B248B9E06F0549DAF3DE
+:108660008BF14FF6FF7380B2002808BF184610BD8B
+:10867000483786004E37860041F2E44370B5C36246
+:1086800004460D4629B108460949DAF375F1A0629E
+:1086900040B900200749DAF36FF1A06210B94FF634
+:1086A000FF73A36228460449DAF366F1206370BDC4
+:1086B000543786005B37860086378600836973B53A
+:1086C00013F0005F04466FD08268B2F5026F01D1EB
+:1086D00001220AE040F604039A4201D0002204E09D
+:1086E000C3680C2B94BF002201224FF00003D5B2C7
+:1086F000ADF8063055B920464FF400612A46D4F84B
+:10870000C860E2F37BF500284ED005E0D4F8843051
+:1087100013F5405048D000266369222B03DC002368
+:10872000C0F8683100E00023C0F86431C0F860315F
+:108730006369222B03DC1F4BC0F8443105E00123A1
+:10874000C0F84831FE33C0F84C316369222B07DC96
+:108750000023C0F88031C0F87C31C0F8783104E0E3
+:108760000023C0F87431C0F870311DB9204631467D
+:10877000E2F356F520460DF10601FFF759FF0546D5
+:10878000A8B9BDF8063093B163690B49222B204686
+:10879000D8BF4FF48021CCBF40224FF480222B461B
+:1087A000E2F38EF3284603E04FF0FF3000E00020B4
+:1087B0007CBDC0460000FBBF400055552DE9F04789
+:1087C000002104461F46DDF82080DDF82490E2F306
+:1087D00027F505462046E2F363F360610A28C4BF2B
+:1087E000EB6A63646B68A3616369222BC4BFD5F82D
+:1087F000AC30E361A36913F0805F05D0D5F804368F
+:10880000636203F0FF0323624FF4E063A3604FF061
+:10881000FF33E360254612330026236116E031461C
+:108820002046E2F3FDF42046E2F31CF32046E2F397
+:1088300037F31FB1D5F810319F4203D0D5F88830F7
+:10884000994501D1C8F8006001360435D4F8CC3020
+:108850009E42E4D32046D8F80010E2F3E1F4012070
+:10886000BDE8F08730B585B00190002504A840F838
+:10887000045D01A90422D9F37FF3019CD4B12246FF
+:108880002946D2F8883013B10023C2F8883001316C
+:1088900004321029F5D10398D9F30CF30398E6F7C5
+:1088A000B7FF054B9C4205D0606D21464FF45672D0
+:1088B000DEF31EF205B030BD8C2802002DE9FF4723
+:1088C0000C9E1446DDF834808A464FF4567200211F
+:1088D00005461F46DDF83890012E08BF0026D9F363
+:1088E000AFF311232B61C5F88470C5F858806C650F
+:1088F0006E60002E40F0B98028463146524643460D
+:10890000FFF794FE002800F0B0804FF0C0542268BA
+:108910002846130F2B6013041B0CAB63C2F30343F5
+:10892000C2F303522A640E3A012A8CBF00220122AC
+:10893000EB6385F8482021465246FDF739FFD5F80C
+:10894000CC30002B00F0918004AB43F8046D009311
+:1089500028462146324633460197FFF72FFF00286D
+:1089600000F083802846FFF74DFE0F9A6B6D284676
+:10897000019231463A46CDF80090FFF70FFB0028F0
+:1089800073D1B9F1000F01D14E4601E0D9F8006072
+:1089900028463146FFF770FE364B1C78002C30D14C
+:1089A0006B69132B0BDD4FF4006128462246E2F37E
+:1089B00025F48465C46503992846E2F331F428461A
+:1089C000696DFFF7D3FB2846696DFFF797FD3046C9
+:1089D0002949D9F3D1F7024620B92846696DFFF736
+:1089E0008DFB02462846696DFFF7DEFB2846696D60
+:1089F000FFF7F2FB2846696DFFF748FD1D4B01228A
+:108A00001A706B690F2B0FDD1C493046D9F3B4F790
+:108A10001B4B0021002808BF1846009088222846DA
+:108A20004FF0FF33E2F332F230461649D9F3D0F774
+:108A300038B114493046D9F39FF701462846E7F785
+:108A4000A5F86B69142B11DD00242146082223466A
+:108A500028460094E2F31AF2214640F0040308226B
+:108A600028460093E2F312F200E00025284604B005
+:108A7000BDE8F087E42B0200E2388600EB38860080
+:108A80005A000A00F13886001FB5104C864621783E
+:108A9000C9B90F4A0F4B002808BF024608BF03465A
+:108AA00000910191029303920B4844F210717246B7
+:108AB0004FF0C053FFF702FF00B905E0074A20233B
+:108AC000136001232370044804B010BD88280200FD
+:108AD0000C290200082902008C28020074270000DB
+:108AE0002DE9FF4781460D4608464FF456719246E0
+:108AF0001E460D9FDDF83880DEF3EAF0044610B321
+:108B00000C9B494601932A46534600960297CDF89E
+:108B10000C80FFF7D3FE064638B9284621464FF4AD
+:108B20005672DEF3E5F030460EE00FB93B4600E04A
+:108B30003B68E367B8F1000F01D1434601E0D8F884
+:108B40000030C4F88030204604B0BDE8F087C0464D
+:108B500070B5044628B30368124918682246FBF32F
+:108B6000F3F12546002610E0296A29B123689868A8
+:108B7000E6F386F500232B62E96921B123682A8B8D
+:108B80005868DEF3B5F00136183561688E42EBDBCC
+:108B9000182201FB02F22368214658681032DEF3E6
+:108BA000A7F070BD08FA01002DE9F043036885B015
+:108BB00081467021D868DEF38BF0044608B906467A
+:108BC00048E0002170220646D9F33AF2042363609C
+:108BD00027464FF0B40325464FF00008C4F8009034
+:108BE000A38112E0182208FB02F210322C61D9F89E
+:108BF00008001A49A2180023E6F35EF5286218352A
+:108C000008B905461CE008F1010863689845E9DBEE
+:108C1000134BD9F8000000930023019302930393B0
+:108C20001049114A2346FBF357F113E0396A29B181
+:108C300023689868E6F324F500233B620135183772
+:108C400063689D42F2DB2368214658687022DEF398
+:108C50004FF00026304605B0BDE8F0839DFE0000D1
+:108C600021FD0000E4F9010009FA010010B50446F5
+:108C700058B10368054918682246FBF365F123687B
+:108C8000214658685422DEF333F010BD2B7A86005B
+:108C900030B55421044685B04068DEF319F008B9B8
+:108CA000054611E0002154220546D9F3C9F1084BCD
+:108CB0002C600093002301930293039320680549DD
+:108CC000054A2B46FBF308F1284605B030BDC046E7
+:108CD000390301003CFA01002B7A8600002070471E
+:108CE00010B5044698B107F0ADDE09496068224628
+:108CF000FBF32AF1E16E21B163683C22D868DDF311
+:108D0000F7F763682146D8687022DDF3F1F710BDEC
+:108D1000D58D86007FB5054670214068DDF3D8F714
+:108D2000064608B9044631E0002170220446D9F312
+:108D300087F12B683560736068683C21DDF3C8F704
+:108D4000E066F8B100213C22D9F37AF1114B1249C7
+:108D50000093002301930293104B114A0393706810
+:108D60003346FBF3B9F068B94FF001037382B38265
+:108D700030462946FFF7B2FF002803DB304607F0F4
+:108D80005DDF03E03046FFF7ABFF0024204604B070
+:108D900070BDC046390B83006CFA0100290C8300BA
+:108DA000D58D860070B5D0F8305704466DB10749AF
+:108DB00022460068FBF3C8F0606829464FF40A6257
+:108DC000DDF396F70023C4F8303770BD529E86005D
+:108DD0002DE9FF4106464FF40A614068DDF378F75C
+:108DE000074618B9C6F830070138E1E000214FF412
+:108DF0000A62D9F325F107F120033B6033680822AA
+:108E000000247A613C61DC211A6630466A4A6B4B69
+:108E10000094019601F092FFA042B86105DA304655
+:108E2000FFF7C0FF6FF00100C2E0A6462546644B85
+:108E300000221EF0010FEA501FD0624B19780D2955
+:108E400002DD4FF4004C03E04A1C012303FA02FC4C
+:108E50005C4BD8780D2802DD4FF4004403E0421C3F
+:108E6000012313FA02F4012313FA00F28B401A4390
+:108E700042EA0C02524B2243EA501EF0020F24D069
+:108E80004F4B55F803804F4B58780D2802DD4FF4B7
+:108E9000004C03E0421C012303FA02FC494B997881
+:108EA0000D2902DD4FF4004403E04A1C012313FAAC
+:108EB00002F4012313FA01F283401A4342EA0C023E
+:108EC00022433F4B42EA0802EA501EF0040F24D02E
+:108ED0003B4B55F803803B4B18790D2802DD4FF4CE
+:108EE000004C03E0421C012303FA02FC354B597984
+:108EF0000D2902DD4FF4004403E04A1C012313FA5C
+:108F000002F4012313FA01F283401A4342EA0C02ED
+:108F100022432B4B42EA0802EA501EF0080F24D0ED
+:108F2000274B55F80380274B98790D2802DD4FF425
+:108F3000004C03E0421C012303FA02FC214BD979C7
+:108F40000D2902DD4FF4004403E04A1C012313FA0B
+:108F500002F4012313FA01F283401A4342EA0C029D
+:108F60002243174B42EA0802EA500EF1010E043583
+:108F7000BEF1100F7FF45BAF134B0025134C03932E
+:108F80002946134A33463068009501950295FAF355
+:108F9000A3F7231D93E807006B4683E807003046DC
+:108FA00023680321324601F061DEC6F83077284697
+:108FB00004B0BDE8F081C04601578300A15683008C
+:108FC0008427000090E085009D508300C8FA0100CE
+:108FD000529E86002DE9F041066805461B4930681F
+:108FE0002A46FAF3B1F72C460027D4F8081121B12C
+:108FF0007068B4F81021DDF37BF6D4F80C1121B1C0
+:109000007068B4F81221DDF373F601374034042F91
+:10901000EBD1D5F80C1221B17068B5F81022DDF350
+:1090200067F6D5F81C1211B1B068E6F329F3D5F84C
+:10903000201219B170683A46DDF35AF67068294675
+:109040004FF42372DDF354F6BDE8F081D8FA010045
+:1090500010B50446E7F7F2FDA16961B1237D23B1A4
+:10906000E068E6F3FBF200232375E068A169E6F30C
+:1090700007F30023A36123692146D8682C22DDF37E
+:1090800037F6002010BDC0462DE9F041074688465E
+:10909000C0682C2114461E46DDF31AF608B90546B1
+:1090A00019E0054600212C22D8F3CAF7EC602046CF
+:1090B000EE61C5F808802F6108492A460023E6F3CF
+:1090C000FBF20446A86130B92B692946D8682C22E6
+:1090D000DDF30EF625462846BDE8F0813D668400A6
+:1090E00010B5034900220068FAF32EF7002010BDE6
+:1090F00049C586001FB5094A0B460092002201921D
+:10910000029203920649074AFAF3E6F6002814BFD2
+:109110004FF0FF30002005B000BDC0460968840054
+:1091200048FB010049C586001FB5084A0346009266
+:1091300000220192029203920549064A0068FAF35E
+:10914000CBF6003818BF012005B000BD7D18010026
+:1091500020FC0100EFFB010010B5B0F8BC400C8012
+:10916000B0F8C0101180B0F8C6201A8090F8C8205E
+:10917000029B01201A8010BD90F8D4007047C046B1
+:10918000D0F8CC007047C04610B5014618B18068D1
+:109190009822DDF3ADF510BD70B598210446006846
+:1091A000DDF396F508B9054633E00021982205461F
+:1091B000D8F346F72368AB606368EB60A3682B6164
+:1091C000E3686B6023696B61238CAB84638CEB84F5
+:1091D000636AAB62A36AEB62E36A2B63236B6B6324
+:1091E000636B6B64A36BAB64E36BEB64236C2B6509
+:1091F000636C6B656369AB65A369EB650F232B66D5
+:109200002D336B663C33AB660323EB66002385F896
+:109210009430284670BDC04670B501210446E9F778
+:1092200029FB2046E9F7B2FBC0F30F33A4F8C630A0
+:10923000B4F8C620030F84F8C83042F2640300F08B
+:109240000F009A4284F8C90005D002339A4202D036
+:109250004FF0FF3500E0002520460021EAF77AF8BC
+:10926000284670BD70B5044600282DD0D0F8E430F3
+:109270005D1EC0F8E4503DBB41F2C826815921B1C2
+:10928000C3691869F3F78EFFA55141F2DD13E55468
+:109290002046E9F73FFFE1690A68A24203D1D4F80A
+:1092A000B4300B6005E0D2F8B430A34208BFC2F876
+:1092B000B450E36E0BB120469847E36921469868A5
+:1092C00041F26832DDF314F570BDC04670B5D0F8D8
+:1092D000B8400E46E9B10846D8F342F70546C0B19A
+:1092E0000FE0204631462A46D8F32AF628B9635DB6
+:1092F0003D2B02D1631C58190CE014F8013B002BE4
+:10930000FBD114B12378002BEBD13046DEF3AEF461
+:1093100000E0002070BDC0462DE9F34141F2383530
+:10932000435B064688462BB30846D8F319F7044634
+:109330001448D8F315F724181034F369A7B29868C5
+:109340003946DDF3C5F4044608B9054617E0735BFA
+:109350000D4A009339464346D8F3B6F621463046C7
+:10936000EBF79EF9F3690546214698683A46DDF326
+:10937000BFF425B930464146EBF792F90546284639
+:10938000BDE8FC8196FD01009CFD01002DE9F04F38
+:1093900041F2383B85B0039330F80B3006468946DE
+:1093A0009246D0F8B880002B38D00846D8F3D8F6CB
+:1093B00004462448D8F3D4F62418F3691034A7B22D
+:1093C00098683946DDF384F4054608B9044634E06C
+:1093D00036F80B30394600931B4A4B46D8F374F6E7
+:1093E00030462946EBF76AF9834668B1404629467C
+:1093F000D9F75CFA40B1504506DD40462946524651
+:10940000D9F3C8F2044600E0039CF3692946986842
+:109410003A46DDF36DF4BBF1000F0ED140464946EC
+:10942000D9F744FA40B1504506DD40464946524618
+:10943000D9F3B0F2044600E0039C204605B0BDE835
+:10944000F08FC04696FD01009CFD010070B590F8BC
+:10945000C43001229A401A49013A0446D5B2EBF7CA
+:1094600061F941F21202C0B2A0540138C0B2FD2825
+:1094700001D97323A354A25C41F21303E2542046A2
+:109480001049EBF74FF941F21402C0B2A05408B1F1
+:109490000F2801D10523A35441F21203E25C0233E9
+:1094A000E35CD21A41F21503E25400220133E25484
+:1094B0000233E25445EA0512013BE25470BDC04656
+:1094C00075B902004FB902002DE9F84F8846002116
+:1094D000846807469246C0680A469B46E1F3BAF4A0
+:1094E00010F0080F814615D03E689EB130465146B7
+:1094F00000F084FA002800F07481F369D6F8CC10EB
+:10950000186927F0CDD8D6F8E43030460133C6F8D4
+:10951000E4306DE1204641F26831DDF3D9F30546D0
+:10952000002800F05C81002141F268320646D8F341
+:1095300087F5012105F59053303341F2D41285F8B7
+:10954000E110AB50FA6C41F26B039A42C5F8B0805F
+:10955000EF6105D17B6C932B02D1A5F8221603E0B5
+:109560004FF01802A5F822266423002185F8E03088
+:1095700041F218230422E9540133EA540133E95437
+:109580000133BAF1020FC5F8B8B0EA5406D119F0A8
+:10959000010F1CBF4FF40053C5F8CC30EB69D5F870
+:1095A000CC10186927F07CD8D5F8B030B3F8E03388
+:1095B0009CB2EB69D868E6F787F941F23833E85294
+:1095C000C4F30323C5F8BC3004F00F03C5F8C03062
+:1095D000EB699A6A874BD318012B06D94AF6E60342
+:1095E0009A4202D0043B9A4207D1EB69DB6A023B04
+:1095F000012B02D80923C5F8C030D5F8BC30092B9F
+:1096000007D10423C5F8BC30D5F8C0301033C5F8F5
+:10961000C030012385F8C430230BC5F8D030D5F80D
+:10962000BC30022B0CD9042B0AD0052B08D0062BFA
+:1096300006D0082B04D00A2B02D0072B40F0D18093
+:109640003C23C5F8F43F0023C5F8F83F4FF400630E
+:10965000A5F8DE3042F6013241F62433BAF1020FAA
+:1096600008BF1346A5F8DA3095F8DA30284685F8B1
+:1096700000376149EBF722F890B15F492846EC6961
+:10968000EBF750F85C4920672846EC69EBF74AF89D
+:10969000EA69BAF1020F60670CBF136F536FD366AC
+:1096A0000A2241F2E613EA5403210133E95401236B
+:1096B000002485F8E83005F59053013A1C7041F21A
+:1096C0001B03EA54EB6985F8E94585F8EE4585F812
+:1096D000F34585F8F84585F8FD45284683F893104D
+:1096E000FFF7B4FE41F21903EC544FF6CE7241F28B
+:1096F000C423EA5285F8F440621901347F23652CB3
+:1097000082F82C3682F8913682F8B232F4D14FF0DA
+:10971000FF33A5F8FA36002385F8AC3028465146C9
+:1097200001F03AF900285CD02846E9F797F8284676
+:10973000FFF772FD0446002853D13049062228461F
+:10974000EAF7E4FF41F2E623E8542D4901222846D6
+:10975000EAF7DCFF41F2F423E8542A49224628467E
+:10976000EAF7D4FF41F23A33E85427492846072262
+:10977000EAF7CCFF41F23B33E8542246284623491E
+:10978000EAF7BEFF631903F5985301343833182CF8
+:109790001871F2D10024224628461D49EAF7B0FF8D
+:1097A000631903F59A53013410330E2C1871F2D15A
+:1097B000D5F8E430EA690133C5F8E4301368D068BD
+:1097C000C5F8B4303D60FEF779FF05F1B803C5F880
+:1097D000B830284605F1BC011C22D8F3CDF3284649
+:1097E00006E0B868314641F26832DDF381F20020CC
+:1097F000BDE8F88F1D57FFFF80B9020024B90200B1
+:1098000043B9020036B9020060B902006EB9020025
+:109810002FB9020010B502490268FAF395F310BDA2
+:10982000040402001FB5094B09490093002301936A
+:1098300002930393074A0368FAF34EF3002814BF18
+:109840004FF0FF30002005B000BDC0463147010099
+:1098500044030200040402002DE9F0410025804683
+:109860000F4616462C4607E004EB0800E1190522D6
+:10987000D8F382F301350534B542F5D1BDE8F08166
+:10988000022970B505460C460AD0032911D00129DA
+:1098900016D106220B49E8F793FFEA69002305E099
+:1098A00006220949E8F78CFFEA69012382F8813032
+:1098B00006E006490622E8F783FFEB6983F881405A
+:1098C00070BDC046200B02002C0B0200380B0200BA
+:1098D00070B5D0F8A840002394F8C113C4F87435CB
+:1098E0000F4A104B022914BF15461D46C3694FF499
+:1098F00020719868DDF3ECF1C4F8740578B180222A
+:109900002946FFF7A9FF94F83A35022B06D1D4F87F
+:1099100074050549A0301522FFF79EFF012070BD98
+:1099200084C90200A8C4020048CC02002DE9F04717
+:10993000D0F8A8308146D3F87C55D3F878A54FF0FD
+:10994000000817E0142403FB04F42B191A695B6860
+:109950002F5903FB02F3DE08D9F81C303146986812
+:10996000DDF3B6F108F10108285140B1394632461D
+:10997000D8F302F35FFA88F35345E3D30120BDE83F
+:10998000F087C0462DE9F041194BD0F8A8501A686D
+:10999000C369002614210746C5F87C65C5F87825FB
+:1099A000986802FB01F1DDF393F10446C5F87C05EC
+:1099B000E0B1B0460FE0FB6906EB04001B6D08F157
+:1099C000010813F4805F14BF0A490B49142271186F
+:1099D000D8F3D2F21436D5F878359845EBD338461B
+:1099E0000121FFF7A3FF003818BF0120BDE8F08177
+:1099F000A01A0200C4C2020084D102002DE9F04185
+:109A0000884686B07A490546D0F8A860EAF78AFE0B
+:109A1000784930722846EAF785FE77497072284601
+:109A2000EAF780FE7549A5F8FC002846EAF77AFEB9
+:109A30007349A5F8FE002846EAF774FE7149A5F8B7
+:109A400000012846EAF73AFE38B128466D49EAF7A0
+:109A500069FE10B1012386F8E83396F8E8330BB3BA
+:109A600068492846EAF75EFE6749A5F802012846DC
+:109A7000EAF758FE6549A5F804012846EAF752FEC0
+:109A80006349A5F806012846EAF74CFE614986F8C5
+:109A900024052846EAF746FE002241F21B0386F819
+:109AA0002505EA545C492846EAF73CFE5B49C6F8BE
+:109AB000340414222846EAF729FE5949A6F83C0442
+:109AC0005A222846EAF722FE564986F8540408220C
+:109AD0002846EAF71BFE544986F84C040322284620
+:109AE000EAF714FE514986F84D0408222846EAF7A1
+:109AF0000DFE4F4986F84E0403222846EAF706FE7B
+:109B00004C4986F84F0408222846EAF7FFFD4A49E7
+:109B100086F8500403222846EAF7F8FD474986F8FC
+:109B2000510408222846EAF7F1FD032286F8520480
+:109B300043492846EAF7EAFD424986F85304284695
+:109B4000EAF7F0FD404986F8580402222846EAF771
+:109B5000DDFD3E4986F8C1042846EAF7AFFD28B18D
+:109B600028463A49EAF7DEFDF07400E0F074284632
+:109B70003749EAF7A3FD28B128463549EAF7D2FD6F
+:109B8000307501E00823337528463249EAF796FD1F
+:109B900028B128462F49EAF7C5FD707501E0022378
+:109BA000737528462C49EAF789FD28B128462A49C9
+:109BB000EAF7B8FDB07501E00423B37528462749DC
+:109BC000EAF77CFD28B128462449EAF7ABFDF07599
+:109BD00001E00823F37528462149EAF76FFD0028C4
+:109BE00040D028461E49EAF79DFD30763CE0C0464D
+:109BF00045C10200E3C002002ABE020030BE0200DE
+:109C000036BE0200C3C00200E2BD0200CDBC0200AD
+:109C1000D5BA0200EABA02009AC202006BBD020085
+:109C2000A6C102001DC202007EBF0200EBC10200FD
+:109C3000ABB90200FCC10200BCB90200DAC10200EB
+:109C4000B3C202009ABC02000BBB02001ABC0200A5
+:109C500007BC020065C0020015C202000DC202006E
+:109C60003DC1020002233376B7492846EAF75AFD80
+:109C7000B649B0722846EAF755FDB549F072284654
+:109C8000EAF750FDB17AF27AC3B230737173B273EE
+:109C9000F37331747274B374AE492846EAF742FD27
+:109CA000B5F8FC2041F21A33EA5205F599531A80AF
+:109CB000B5F8FE2041F21C33EA520633EA52B5F8F9
+:109CC0000021043BC7B2EA52063385F81A71EA5202
+:109CD0002846A149EAF726FD002480B22A1900F09F
+:109CE0000F030134A7EB43030009042C82F81E3153
+:109CF000F4D128469949EAF715FD2A1900F00F0317
+:109D00000134A7EB430300090C2C82F81E31F4D177
+:109D100093492846EAF706FD924904462846EAF7A1
+:109D200001FD80B240EA0441716014202A1801F05C
+:109D30000F030130A7EB430309091C2882F81631F1
+:109D4000F4D189492846EAF7EDFC88497083284612
+:109D5000EAF7E8FC864930772846EAF7E3FC8549CC
+:109D600070772846EAF7DEFC8349B0772846EAF7A1
+:109D7000D9FC8249F0772846EAF7D4FC804986F876
+:109D800022002846EAF7CEFC7E4986F821002846C4
+:109D9000EAF7C8FC7C4986F8E0042846EAF7C2FCEA
+:109DA0000127C6F8E40401AC784920463A46D8F3C6
+:109DB0009BF1D5F8B8002146D8F30AF630B100215E
+:109DC0000A46D8F3C5F4F31983F8E70401370F2FD7
+:109DD000E9D16F492846EAF7A5FC6E4986F8F604F2
+:109DE0002846EAF79FFC6C4986F8F7042846EAF70C
+:109DF00099FC6A4986F8F8042846EAF793FC684912
+:109E000086F8F9042846EAF78DFC664986F8FA04D4
+:109E10002846EAF787FC644986F8FB042846EAF7F7
+:109E200081FC624986F8FC042846EAF77BFC60491D
+:109E300086F8FD042846EAF775FC5E4986F8FE04BC
+:109E40002846EAF76FFC5C4986F8FF042846EAF7E3
+:109E500069FC5A4986F800052846EAF763FC584928
+:109E600086F801052846EAF75DFC564986F80205A2
+:109E70002846EAF757FC544986F803052846EAF7CE
+:109E800051FC524986F804052846EAF74BFC504934
+:109E900086F805052846EAF745FC4E4986F806058A
+:109EA0002846EAF73FFC4C4986F807052846EAF7BA
+:109EB00039FC4A4986F808052846EAF733FC484940
+:109EC00086F809052846EAF72DFC464986F80A0572
+:109ED0002846EAF727FC444986F80B052846EAF7A6
+:109EE00021FC424986F80C052846EAF71BFC40494C
+:109EF00086F80D052846EAF715FC3E49A6F8140534
+:109F00002846EAF70FFC4FF00042A6F816053A493A
+:109F10002846EAF7FBFB3949C6F810052846EAF758
+:109F200001FC374986F824002846EAF7FBFB35494F
+:109F300086F823002846EAF7F5FB334986F8200027
+:109F40002846EAF7EFFB61E0E7B902000CBF020028
+:109F5000C5BD0200F2BD020077BD020044BC020094
+:109F600096B902008DB902008DBE0200DDB9020073
+:109F7000F6BF020001C00200CDB90200B2BC02006F
+:109F8000E3BC0200B9BE0200FFBE020033BC020007
+:109F90003CBE02008CBF02009DBF0200B7BF0200A2
+:109FA000FEC002000FC102002BC202004CC2020020
+:109FB0006FBE02009ABE0200C7BE020020C10200AE
+:109FC0000CC0020056C1020068C102007AC1020042
+:109FD0006DC202007FC2020031BA02005BBA020009
+:109FE00074BB02009DBB020088BC0200A9BA02003B
+:109FF000FCBA020034BD020059BB0200B1C102002C
+:10A00000BDC102005DC2020046C00200B94985F828
+:10A0100026062846EAF786FBB74986F8C103284694
+:10A02000EAF780FBB54986F8C2032846EAF77AFBCF
+:10A0300086F8C30395F8261611B12846FFF720FCD1
+:10A040004FF0FF32AE492846EAF760FB80B210F4C9
+:10A05000004F18BF4FF0FF324FF0FF33A6F86200F9
+:10A06000A6F8663018BFA6F86220A6F86830284621
+:10A07000A449EAF723FB58B12846A249EAF752FB64
+:10A0800080B210F4004F04BFA6F86600A6F868007E
+:10A0900028469D49EAF712FB48B128469A49EAF753
+:10A0A00041FB80B210F4004F08BFA6F866002846B6
+:10A0B0009649EAF703FB48B128469449EAF732FB90
+:10A0C00080B210F4004F08BFA6F8680090494FF026
+:10A0D000FF322846EAF71AFB4FF0FF32A6F8C40316
+:10A0E0008C492846EAF712FB8B49A6F8C603284696
+:10A0F000EAF718FB8949A6F8C8034FF4CF7228463F
+:10A10000EAF704FB8649C6F8CC0347F69A6228466C
+:10A11000EAF7FCFA8349C6F8D0030A222846EAF790
+:10A12000F5FA8149C6F8D40308222846EAF7EEFA80
+:10A130007E49C6F8D80341F26E022846EAF7E6FAED
+:10A140000A22C6F8DC037A492846EAF7DFFA794999
+:10A15000C6F8E0032846EAF7E5FA7749A6F8E403EB
+:10A160002846EAF7DFFA96F8E83380B2A6F8E60365
+:10A170002BB103B2002BC4BF0022A6F8E623502265
+:10A180006E492846EAF7C2FA6D4986F8EA0328467E
+:10A19000EAF7C8FA6B4986F8EC032846EAF7C2FAF0
+:10A1A000694986F8ED032846EAF7BCFA674986F85C
+:10A1B000EE034FF0FF322846EAF7A8FA644986F822
+:10A1C000F0034FF0FF322846EAF7A0FA4FF0FF34D1
+:10A1D00086F8F1035F49224686F8EF432846EAF7FE
+:10A1E00095FA5D4986F8F20322462846EAF78EFA88
+:10A1F0005A4986F8590522462846EAF787FA584907
+:10A2000086F85A0522462846EAF780FA554986F824
+:10A21000F30322462846EAF779FA534986F85B05A4
+:10A2200022462846EAF772FA504986F85C0522462B
+:10A230002846EAF76BFA4E4986F8F4032246284688
+:10A24000EAF764FA4B4985F8DA0522462846EAF728
+:10A250005DFA4949A6F8F60322462846EAF756FA77
+:10A260004649A6F8F80322462846EAF74FFA444939
+:10A27000A6F8FA0322462846EAF748FA4149A6F822
+:10A28000FC0322462846EAF741FA3F49A6F8FE03B6
+:10A2900022462846EAF73AFA3C49A6F80004224644
+:10A2A0002846EAF733FA3A49A6F802042246284635
+:10A2B000EAF72CFA0022A6F8040436492846EAF701
+:10A2C00025FA0022A6F85E0533492846EAF71EFA69
+:10A2D0000022A6F8600531492846EAF717FA00225D
+:10A2E000A6F862052E492846EAF710FA2D49A6F885
+:10A2F000640559E04FBA020043BA0200A7C0020049
+:10A300008DBD02004BC0020094C10200C0BB020020
+:10A31000D2BB020067BF020035BB02005BC0020077
+:10A32000A0BA0200BEBD0200D9BB02004DC10200AE
+:10A33000EBBD02009AC002007FBD0200BCBC02005F
+:10A34000AEBF020010BA0200DCBF020095BA0200E4
+:10A3500002BD020032C1020039C0020090BB0200FF
+:10A36000A6BC02003EBB0200BBBA0200F0BB02006A
+:10A37000EBBE02001FBE0200C9BA02006DC002009F
+:10A38000B3BD02004CBB0200F4BC020016BF0200C9
+:10A390005CBC02007AC002006EBF020059BF02001E
+:10A3A000D3C00200C6BC02002846EAF7BBF9B8F1E8
+:10A3B000020F86F8060414D12846A449EAF77EF96C
+:10A3C000002800F0A382344600273A4628469F49D9
+:10A3D000EAF796F90137C4F80C040434052FF4D1D8
+:10A3E00016E0B8F1010F13D128469949EAF766F94A
+:10A3F000002800F08B82344600273A4628469449CC
+:10A40000EAF77EF90137C4F820040434052FF4D1AB
+:10A4100090494FF0FF322846EAF778F98E49A6F8BE
+:10A420003E044FF0FF322846EAF770F98B49A6F850
+:10A4300040044FF0FF322846EAF768F98849A5F84A
+:10A44000DE0F2846EAF73AF930B128468449EAF7A0
+:10A4500069F941F2EA23E852824928464FF0FF3277
+:10A46000EAF754F941F23433E8527F492846EAF7D3
+:10A4700025F930B128467C49EAF754F941F2EE2338
+:10A48000E852284679490022EAF740F9C0B286F836
+:10A490004D0358B176492846EAF744F97549C6F89C
+:10A4A00050032846EAF73EF9C6F860032846724989
+:10A4B000EAF704F928B3D5F8B8006F49D8F7F6F9E8
+:10A4C00006281ED1344600273A466B49D5F8B80015
+:10A4D000D8F360F284F895037A1C6749D5F8B80080
+:10A4E000D8F358F284F89703BA1CD5F8B80062493B
+:10A4F000D8F350F2033784F899030134062FE3D1DF
+:10A5000011E0012386F89533313386F896330E3304
+:10A5100086F8973386F89833042386F899334FF0FA
+:10A52000FF3386F89A3355492846FF22EAF7EEF8BA
+:10A530004FF0FF03A6F85403A6F85633A6F8583395
+:10A54000A6F85A3328464E49EAF7B8F828B3D5F8A2
+:10A55000B8004B49D8F7AAF934460328B4BF80465F
+:10A560004FF00308002707E03A4628464449EAF737
+:10A57000C7F80137A4F8540302344745F4DB06EB6F
+:10A58000470303F55473063304E0B6F85623013746
+:10A5900023F8022C0233022FF7DD01223949284625
+:10A5A000EAF7B4F8384986F840032846EAF7BAF8DB
+:10A5B000012286F84B0335492846EAF7A7F83449C3
+:10A5C00086F841032846EAF7ADF8324986F84C038D
+:10A5D0004FF0FF322846EAF799F82F4986F84903E9
+:10A5E0004FF0FF322846EAF791F82C4986F84A03E3
+:10A5F0004FF0FF322846EAF789F8294986F85C03CC
+:10A600004FF0FF322846EAF781F8264986F85D03C5
+:10A610002846EAF753F8002846D0012421490022B1
+:10A6200086F8BB442846EAF76BF81E4986F8BC0456
+:10A6300022462846EAF764F81A4986F8BD04022241
+:10A640002846EAF75DF886F8BE042FE0E3BB020077
+:10A65000EFBA02001ABD0200CCC002000CBE02001C
+:10A660000EBD02003CC202001EC0020066BB02001A
+:10A67000C8BF020050BD0200AFBB020037BF0200DE
+:10A68000A3C20200EAC002006ABC020016BB0200BC
+:10A6900022BF020079BA0200FBBD0200E5BF020042
+:10A6A0004DBE020091C2020086F8BB04FF22994908
+:10A6B0002846EAF72BF8FF2286F8BF049649284679
+:10A6C000EAF724F8954986F8C0042846EAF72AF8FC
+:10A6D0000022A6F8C20492492846EAF717F8002299
+:10A6E00086F818058F492846EAF710F8C0B286F8B0
+:10A6F0001A05EB69DB685B6C03F00703052B03D9D4
+:10A7000010B1002386F81A35874900222846E9F758
+:10A71000FDFF864986F81C0500222846E9F7F6FF6A
+:10A72000834986F81D054FF0FF322846E9F7EEFF12
+:10A73000804986F81E0500222846E9F7E7FF7E4992
+:10A7400086F895054FF0FF322846E9F7DFFF7B4991
+:10A75000A6F8200501222846E9F7D8FF784986F8AF
+:10A7600027054FF0FF322846E9F7D0FF7549A6F8D4
+:10A770002A054FF0FF322846E9F7C8FF7249A6F8CC
+:10A780002C0500222846E9F7C1FF704986F83A05F2
+:10A7900000222846E9F7BAFF6D4986F83B054FF0DD
+:10A7A000FF322846E9F7B2FF6A4986F83C05284699
+:10A7B000E9F784FF30B128466649E9F7B3FF86F828
+:10A7C000420503E04FF0FF3386F8423528466249E0
+:10A7D000E9F774FF30B128465F49E9F7A3FFA6F80F
+:10A7E000440503E04FF0FF33A6F844355B492846A3
+:10A7F0004FF0FF32E9F78AFF5949A6F8900528463D
+:10A80000E9F75CFF30B301245549002286F8524530
+:10A810002846E9F775FF524986F85305224628462F
+:10A82000E9F76EFF4E4986F8540502222846E9F7FB
+:10A8300067FF4B4986F8550503222846E9F760FF74
+:10A84000474986F8560504222846E9F759FF86F855
+:10A85000570501E086F8520542494FF0FF3228467D
+:10A86000E9F754FF404986F858054FF0FF32284673
+:10A87000E9F74CFF3D4986F859054FF0FF3228466D
+:10A88000E9F744FF3A4986F85A0500222846E9F7D5
+:10A890003DFF384986F8700500222846E9F736FF63
+:10A8A000032286F8800534492846E9F72FFF33490B
+:10A8B00086F881052846E9F735FF314986F8820593
+:10A8C0002846E9F72FFF2F49A6F884052846E9F71F
+:10A8D00029FF2D49A6F886052846E9F723FF2B49CD
+:10A8E000A6F888052846E9F71DFF2949A6F88A0534
+:10A8F0002846E9F717FF2749C6F88C0500222846A5
+:10A90000E9F704FF86F89405012000E0002006B076
+:10A91000BDE8F08145C102008CC10200DABA020034
+:10A920001DBA0200CFBD02005EBE0200B2C002002E
+:10A93000ACBE020003BA0200FABB0200F1B9020089
+:10A940002ABB020081BE020086BB02009FB9020042
+:10A950009CBD0200D6BC02006DBA02000FBC020012
+:10A960008ABA0200A6BD020039C0020090BB0200F4
+:10A9700043BD02004DBC020022BC02007FBC0200AD
+:10A9800028C0020088C00200D9BE020047BF0200F2
+:10A9900022BD0200CBC10200C36970B504460E4659
+:10A9A00098684FF4B961DCF393F1C4F8A80000286B
+:10A9B0005CD000214FF4B962D7F342F3E369D4F8D5
+:10A9C000A8501B6D13F4803F05D1012241F22403EE
+:10A9D00084F81A26E254E369D868E4F7B5FF41F237
+:10A9E0000803E0500023EB63214B20462362214BF8
+:10A9F00031466362204BA362204BE362204BA36786
+:10AA0000204BE367204BC4F89030204BC4F88430CF
+:10AA10001F4B23631F4B63631F4BE3631F4B636435
+:10AA20001F4B63651F4BA3651F4BC4F88C301F4B36
+:10AA3000C4F888301E4BE3661E4BC4F89C301E4B96
+:10AA4000C4F8A0301D4BC4F8A430FEF7D7FF68B19E
+:10AA50002046EBF757FD2046FEF73AFF30B120467F
+:10AA6000FEF790FF003818BF012000E0002070BD05
+:10AA7000A9D00100E54A010091CD010055A20100D5
+:10AA8000B9A001001D4F010075A901005DA90100D9
+:10AA9000CD9B0100BD8701003D9C0100FD840100AC
+:10AAA0009D550100A15701007DCC0100C54B01005F
+:10AAB000B1530100198801001582010045CC010045
+:10AAC00010B5014620B103680C221868DCF310F1C0
+:10AAD00010BDC0462DE9F04105460F4600680C2127
+:10AAE0001646DCF3F5F008B9044607E004460021F9
+:10AAF0000C22D7F3A5F225606660A7602046BDE86A
+:10AB0000F081C04610B5044650B10649224640685F
+:10AB1000F9F31AF263682146D8688822DCF3E8F07A
+:10AB200010BDC04603E88600F0B5882185B0054613
+:10AB30004068DCF3CDF0074608B904463BE000214D
+:10AB400088220446D7F37CF22B683D607B600026A8
+:10AB500004212846194A1A4B0096019700F0EEF896
+:10AB6000B042B86021DB174B019600930296039622
+:10AB700078681549154A3B46F9F3AEF1A8B91E238A
+:10AB80007B610423FB7302233B74083301227B7433
+:10AB90004FF6AF7384F82000FA773A73BA61A07465
+:10ABA0006073A073BB83BA7705E068683946882272
+:10ABB000DCF39EF00024204605B0F0BD5123850053
+:10ABC00025238500811485002C1D020003E88600E2
+:10ABD00070B50468CCB1D4F8F811A56829B1A8689B
+:10ABE000E4F34EF50023C4F8F831084928682246FA
+:10ABF000F9F3AAF1216819B168681C22DCF378F036
+:10AC0000686821466269DCF373F070BD441D020080
+:10AC10002DE9FF4740F2C45681468A461046314628
+:10AC200017469846DCF354F00446002879D00021FA
+:10AC30003246D7F305F238461C21DCF349F00546CD
+:10AC4000206030B9384621463246DCF351F02846C0
+:10AC500067E000211C22D7F3F3F122684FF0FF33A5
+:10AC6000A36100254FF014036661C4F80890E76003
+:10AC7000C4F804809571A4F808324FF02803A4F8B2
+:10AC800006324FF02D03A4F804324FF0FA03A4F873
+:10AC90000A320223146084F80C324FF06403A4F8E3
+:10ACA0003E3284F80D5250461F4922462B46E4F3AB
+:10ACB00003F5C4F8F80108B30523C4F81C32373390
+:10ACC000C4F8283204F51072184BC4F81822C4F8DE
+:10ACD000142204F53D72C4F82422C4F82022009303
+:10ACE000134BD9F8000003931249134A23460195E8
+:10ACF0000295F9F3F1F008B9206812E0D4F8F811E0
+:10AD000011B15046E4F3BCF4216819B138461C2255
+:10AD1000DBF3EEF73846214640F2C452DBF3E8F7A6
+:10AD2000002004B0BDE8F087C13C8500F537850000
+:10AD300035D201004C1D0200441D020070B5D0F850
+:10AD400000451E46A3698E460F2B154602D94FF0CB
+:10AD5000FF3011E01801E1690133A361049B42183F
+:10AD60009360059B5660D36062694550D31C734461
+:10AD700023F003036361104670BDC04610B5014661
+:10AD800040B190F820200368D200D86802F5927292
+:10AD9000DBF3AEF710BDC046C36908221B692DE97D
+:10ADA000F041073393FBF2F3DFB2FB0003F5927639
+:10ADB00005463146C068DBF38BF708B9044614E05A
+:10ADC000044632460021D7F33BF104F12403E3614A
+:10ADD000FAB204F59273E36003EB820323614FF44C
+:10ADE0000373256084F8207063612046BDE8F0811C
+:10ADF0007047C0462DE9F04F3B4F89B038683B495A
+:10AE0000D7F3BAF50128DFF81881DFF8189157D089
+:10AE1000DFF800C1364EDCF8001000220091354901
+:10AE200013680968344D354C0291316834480193F8
+:10AE300004912B68216803930691036831490593B7
+:10AE40000B68DFF8D4E007932A4B02602E481A60A3
+:10AE50000A602E4B08F10401D7F800A0DEF800B01C
+:10AE60003A60CEF80020CCF8002032602260091A47
+:10AE7000013A2B60D7F3D4F5254B9842FCD11A4BFD
+:10AE80000099C3F800A0234B1960234B0021C3F89D
+:10AE900000B00A68214B1A60019A164B0A600299A9
+:10AEA000039A1960144B04991A60114B059A1960A2
+:10AEB000134B06991A60114B079A1960114B1A60CF
+:10AEC00098F81B3089F8003098F81C3089F8013068
+:10AED00098F81D3089F8023098F81E3089F8033050
+:10AEE00009B0BDE8F08FC046FC1E0200B81D02008C
+:10AEF00044EC000048EC000034EC000050EC000092
+:10AF00004CEC000054EC000000000000DDBAADBBCA
+:10AF1000E320BBDE001F0200F81E020038EC000038
+:10AF2000005903001C2802002DE9F04F91B0FFF7F3
+:10AF300061FF684B1B68043B012B03D8664B186804
+:10AF4000FFF756FFFBF7BEF800210746E0F3AEF12E
+:10AF500038460021E0F364F128B1036A002BBCBF3E
+:10AF60004FF0004303620EA90822B86BD7F3F6F244
+:10AF7000FA6B0B9038460C92E4F7E6FC574E00F55E
+:10AF8000424000F5A870B0FBF6F00D903846E4F7AB
+:10AF9000DBFC04463846E4F7D7FC00F54248384667
+:10AFA000E4F7DCFC00F5424A3846E4F7D7FC04F548
+:10AFB000424408F5A87804F5A874B8FBF6F808FB35
+:10AFC000164804463846E4F7C9FC00F542453846C1
+:10AFD000E4F708FA00F542493846E4F703FA04F5C5
+:10AFE000424405F5A87504F5A874B5FBF6F505FB14
+:10AFF000164504463846E4F7F5F9394A00F542406B
+:10B00000019204F542440B9A00F5A870B0FBF6F0EB
+:10B010000AF5A87A09F5A87904F5A874BAFBF6FA36
+:10B02000B9FBF6F9029200FB16460C9ADFF8D4B091
+:10B0300003920D9A2B4B04922B492C4AB8FBFBF838
+:10B04000B5FBFBF5B6FBFBF629480093CDF8148061
+:10B05000CDF818A00795CDF820900996E6F724FBC7
+:10B06000244840F60D0144F2F432FAF7AFFF48B13C
+:10B07000204840F6290144F2F432FAF7A7FF08B15C
+:10B08000002403E01C4A1D4B1A4C1A603846FDF799
+:10B09000D7FA44F218334FF6FF72904214BF0246BB
+:10B0A0001A4640F612011648FAF790FF144B002892
+:10B0B0000CBF194600214CB141B1104B20461B6812
+:10B0C0005B689847236920465B689847384611B00B
+:10B0D000BDE8F08F54EC000050EC000040420F003F
+:10B0E000A0D60100ABFF8600BE1D0200C31D0200FA
+:10B0F000E8D102004C1F0200281F0200F8260000C1
+:10B10000F81D0200A0860100776C25643A20427287
+:10B110006F6164636F6D2042434D25642038303287
+:10B120002E313120576972656C65737320436F6EE1
+:10B1300074726F6C6C65722025730A0025733A2057
+:10B1400042726F6164636F6D20534450434D4420DD
+:10B15000434443206472697665720A0073647063C5
+:10B160006D6463646325640072737369736D663222
+:10B17000673D2564007874616C667265713D256475
+:10B1800000616132673D3078257800627734307035
+:10B190006F3D30782578006C6564626825643D30C9
+:10B1A0007825780074737369706F7332673D3078F7
+:10B1B0002578007273736973617632673D25640088
+:10B1C0006C65676F66646D3430647570706F3D30A8
+:10B1D0007825780070613168696D61787077723DAB
+:10B1E0002564006D617870326761303D3078257874
+:10B1F000007061316974737369743D2564006D6119
+:10B200006E6669643D307825780073756276656E88
+:10B210006469643D30782578002004D0023643FF0D
+:10B22000FF626F617264747970653D3078257800D3
+:10B230006D6373256467706F25643D3078257800F1
+:10B240006D616E663D2573006D61787035676C6168
+:10B25000303D30782578006D61787035676C6131EC
+:10B260003D30782578006F66646D35676C706F3D92
+:10B27000307825780072737369736D6335673D2587
+:10B280006400626F617264666C616773323D30782E
+:10B29000257800747269736F32673D3078257800C5
+:10B2A0007064657472616E676532673D30782578C9
+:10B2B000006D63736277323035676C706F3D307844
+:10B2C00025780000006D637362773230756C3567E6
+:10B2D0006C706F3D30782578006D63736277343021
+:10B2E00035676C706F3D30782578000000706131F3
+:10B2F0006C6F6D61787077723D2564006D61787058
+:10B30000326761313D30782578007278706F35672B
+:10B310003D2564006D63733332706F3D307825785E
+:10B320000073756264657669643D307825780069DC
+:10B330007474356761303D307825780069747435F0
+:10B340006761313D30782578007061316D617870CA
+:10B3500077723D256400626F6172647265763D307C
+:10B36000782578006D6373627732303267706F3D95
+:10B37000307825780000006D637362773230756C29
+:10B380003267706F3D30782578006D637362773473
+:10B39000303267706F3D307825780000006D637340
+:10B3A0006277323035676D706F3D307825780000F8
+:10B3B000006D637362773230756C35676D706F3D09
+:10B3C00030782578006D63736277343035676D703F
+:10B3D0006F3D3078257800000073726F6D7265766E
+:10B3E0003D2564007770736C65643D256400706171
+:10B3F000316C6F62303D2564007061316C6F623179
+:10B400003D2564007061316C6F62323D25640070CF
+:10B410006125646725637725646125643D3078255F
+:10B42000780070613062303D2564007061306231B7
+:10B430003D25640070613062323D25640072737393
+:10B4400069736D6332673D2564007472693567689E
+:10B450003D25640075736266733D25640063636B0C
+:10B46000706F3D307825780074726935676C3D25C2
+:10B4700064006F66646D356768706F3D307825785D
+:10B4800000616725643D30782578006578747061C7
+:10B490006761696E35673D307825780070726F643A
+:10B4A0007563746E616D653D257300636464706FD0
+:10B4B0003D30782578006C65676F66646D62773221
+:10B4C0003035676C706F3D307825780000006C6512
+:10B4D000676F66646D62773230756C35676C706F5C
+:10B4E0003D30782578006C65676F66646D627732F1
+:10B4F0003035676D706F3D307825780000006C65E1
+:10B50000676F66646D62773230756C35676D706F2A
+:10B510003D30782578006C65676F66646D627732C0
+:10B5200030356768706F3D307825780000006C65B5
+:10B53000676F66646D62773230756C356768706FFF
+:10B540003D30782578007278706F32673D25640051
+:10B550007278636861696E3D30782578006974742B
+:10B56000326761303D3078257800697474326761E4
+:10B57000313D3078257800616E7473776974636843
+:10B580003D30782578007478636861696E3D307865
+:10B5900025780070726F6469643D3078257800709A
+:10B5A00061306974737369743D25640063636B640F
+:10B5B000696766696C74747970653D2564006368B9
+:10B5C00069707265763D2564006F66646D356770DD
+:10B5D0006F3D30782578006C656464633D30782574
+:10B5E000303478006D61787035676861303D30784F
+:10B5F0002578006D61787035676861313D30782558
+:10B60000780070613162303D2564007061316231D3
+:10B610003D25640070613162323D256400627764CB
+:10B620007570706F3D30782578006D617870356782
+:10B6300061303D30782578006D6178703567613113
+:10B640003D3078257800616E74737763746C35676C
+:10B650003D30782578006D63732564672563706FCE
+:10B6600025643D30782578006D637362773230351C
+:10B670006768706F3D307825780000006D637362F5
+:10B68000773230756C356768706F3D30782578009B
+:10B690006D637362773430356768706F3D3078253D
+:10B6A0007800000074726935673D2564006F706F23
+:10B6B0003D25640076656E6469643D3078257800C8
+:10B6C0006C65676F66646D627732303267706F3DAC
+:10B6D0003078257800006C65676F66646D6277323C
+:10B6E00030756C3267706F3D307825787061306DE1
+:10B6F00061787077723D25640070613168696230ED
+:10B700003D256400706131686962313D25640070D7
+:10B710006131686962323D256400637573746F6DD1
+:10B7200076617225643D30782578007265677265B0
+:10B73000763D3078257800626F617264666C61676F
+:10B74000733D307825780062786132673D2564006A
+:10B750006F656D3D2530327825303278253032786E
+:10B7600025303278253032782530327825303278DD
+:10B77000253032780064657669643D30782578003C
+:10B7800070612564677725646125643D307825788C
+:10B790000072737369736D6635673D2564006F666B
+:10B7A000646D3267706F3D30782578006161356770
+:10B7B0003D30782578007770736770696F3D256438
+:10B7C0000062786135673D25640075736265706E4F
+:10B7D000756D3D307825780074737369706F7335BB
+:10B7E000673D3078257800616E74737763746C32CE
+:10B7F000673D3078257800727373697361763567B9
+:10B800003D2564006F66646D706F3D30782578006B
+:10B8100074726932673D25640073746263706F3DB2
+:10B82000307825780063636F64653D307830006D53
+:10B830006163616464723D25730063636F64653D99
+:10B84000256325630063633D25640063636B326792
+:10B85000706F3D30782578006363746C3D307825D7
+:10B86000780072656777696E646F77737A3D2564D7
+:10B870000065787470616761696E32673D30782564
+:10B880007800626F6172646E756D3D25640074723C
+:10B8900069736F35673D307825780063636B627735
+:10B8A00032303267706F3D30782578000000636376
+:10B8B0006B62773230756C3267706F3D3078257807
+:10B8C000007064657472616E676535673D30782518
+:10B8D0007800000080000000FF0000000C00000065
+:10B8E0000000000000040000FF0000000C00000049
+:10B8F0000000000000000800FF0000000E00000033
+:10B90000000000000200000001000400030000002D
+:10B91000010002000A00000002006000DC050000D7
+:10B9200008071700747870777262636B6F66003275
+:10B93000675F6367610072737369636F72726E6FC2
+:10B94000726D00747373696C696D75636F640074F4
+:10B95000656D70735F687973746572657369730080
+:10B9600072737369636F7272617474656E003567A8
+:10B970005F6367610074656D7074687265736800F9
+:10B98000696E746572666572656E6365006D63737A
+:10B990003267706F30006D63733267706F3100749F
+:10B9A000786761696E74626C356700747373696F70
+:10B9B00066667365746D696E35676C007473736960
+:10B9C0006F66667365746D696E35676D0074656D5D
+:10B9D0007073656E73655F736C6F7065006D656124
+:10B9E00073706F7765720072737369736D66326717
+:10B9F00000706C6C646F75626C65725F6D6F64650E
+:10BA000032670069716C6F7374316F6666326700FC
+:10BA100072667265673033335F63636B00706C6CA2
+:10BA2000646F75626C65725F656E61626C653267CA
+:10BA3000006F70656E6C706761696E696478613102
+:10BA400034300065787470616761696E35670065D0
+:10BA5000787470616761696E3267006F70656E6CD3
+:10BA6000706761696E69647861313439007478692E
+:10BA7000716C6F7061673267006E6F6973655F63C9
+:10BA8000616C5F7265665F3267006C6F67656E5FE1
+:10BA90006D6F646500706163616C69647832670022
+:10BAA00074656D705F616464006F70656E6C706763
+:10BAB00061696E6964786131363500706163616C0B
+:10BAC000696478356768693100706163616C6174BD
+:10BAD0006832673100706D696E00706163616C700F
+:10BAE000756C7365776964746800706D6178007354
+:10BAF000776374726C6D61705F3567006F70656E2F
+:10BB00006C7074656D70636F727200747373696DBD
+:10BB100061786E7074006E6F6973655F63616C5FEE
+:10BB2000656E61626C655F356700706163616C7042
+:10BB30007772326700747869716C6F746600706137
+:10BB400063616C69647835676C6F31007061636143
+:10BB50006C61746835676869006F70656E6C7070D1
+:10BB600077726C696D006E6F6973655F63616C5F9E
+:10BB7000646267006F70656E6C706761696E69649E
+:10BB800078613135330074786761696E74626C0076
+:10BB9000706163616C69647835676869006F7065AE
+:10BBA0006E6C706761696E69647861313537006EFB
+:10BBB0006F6973655F63616C5F7570646174650064
+:10BBC0006F66646D64696766696C747479706535F5
+:10BBD000670070616763326700766261745F6D75DC
+:10BBE0006C740073776374726C6D61705F326700A0
+:10BBF000706163616C616C696D0069716C6F636128
+:10BC00006C70777232670076626174736D63006185
+:10BC10006463726673657132670076626174736D16
+:10BC2000660072786761696E6261636B6F666676E3
+:10BC3000616C006F70656E6C706761696E696478C5
+:10BC4000622564006F66646D3267706F007278679A
+:10BC500061696E74626C776C6267610070616361C8
+:10BC60006C6174683567686931006E6F6973655F10
+:10BC700063616C5F706F5F626961735F32670072EE
+:10BC800066726567303838006F70656E6C7067611A
+:10BC9000696E696478613136310064796E707772EB
+:10BCA0006C696D656E00706163616C69647835679D
+:10BCB000310074656D70636F7272780064616372D5
+:10BCC0006174653267007061726670730070613014
+:10BCD00062325F6C6F00747869716C6F706170753F
+:10BCE00032670074656D7073656E73655F6F707435
+:10BCF000696F6E00706163616C61746835676C6F49
+:10BD00003100706163616C69647832673100747806
+:10BD1000616C706662797032670064616367633278
+:10BD20006700756E6D6F645F727373695F6F6666CF
+:10BD3000736574006F70656E6C70766F6C74636F92
+:10BD400072720072786761696E74626C31303000B3
+:10BD50006E6F6973655F63616C5F6E665F7375625A
+:10BD60007374726163745F76616C00747373697469
+:10BD70007864656C61790063636B3267706F006330
+:10BD8000636B507772496478436F72720063636BC0
+:10BD900064696766696C7474797065006C6F63635D
+:10BDA0006D6F646531006C6F696461636D6F6465AC
+:10BDB000356700706163616C617468356700746534
+:10BDC0006D705F71007273736973617632670073AF
+:10BDD00070757261766F69645F656E61626C653201
+:10BDE000670070613062315F6C6F00766261745F12
+:10BDF00071006D61787032676130006E6F697365D4
+:10BE00005F63616C5F7265665F3567006F66646D66
+:10BE1000616E616C6F6766696C746277326700701F
+:10BE20006163616C61746832670070613062300018
+:10BE30007061306231007061306232006F70656E27
+:10BE40006C706761696E696478613336006E6F6922
+:10BE500073655F63616C5F61646A5F356700697118
+:10BE60006C6F63616C69647832676F666673006FCC
+:10BE700070656E6C706761696E69647861313030CD
+:10BE800000706163616C7077723267310072617744
+:10BE900074656D7073656E7365006F70656E6C7040
+:10BEA0006761696E696478613130340069716C6F03
+:10BEB00063616C6964783267006F70656E6C707076
+:10BEC00077726374726C006F70656E6C7067616915
+:10BED0006E696478613130380072786761696E74B8
+:10BEE000656D70636F727235676D0074785F746F23
+:10BEF0006E655F706F7765725F696E646578006FFD
+:10BF000070656E6C707265667077720072737369BB
+:10BF1000736D63326700706163616C61746835676B
+:10BF200031006E6F6973655F63616C5F706F5F6234
+:10BF30006961735F3567006E6F6973655F63616C1C
+:10BF40005F706F5F32670072786761696E74656DEC
+:10BF500070636F727235676C00706163616C6964E5
+:10BF600078356731746800706167633567007061A8
+:10BF700063616C69647835676C6F317468007473E1
+:10BF800073696F66667365746D696E006F70656E58
+:10BF90006C706761696E696478613430006F7065D8
+:10BFA0006E6C706761696E696478613434007266C2
+:10BFB000726567303333006F70656E6C70676169EE
+:10BFC0006E696478613438006E6F6973655F6361B0
+:10BFD0006C5F686967685F6761696E007266726549
+:10BFE00067303338006E6F6973655F63616C5F61E2
+:10BFF000646A5F3267006D656173706F7765723177
+:10C00000006D656173706F77657232006F70656E79
+:10C010006C706761696E6964786131313600627095
+:10C0200068797363616C650072786761696E7465C5
+:10C030006D70636F7272326700706163616C696406
+:10C040007835676C6F0061613267006F66646D649C
+:10C05000696766696C74747970650074656D705F8A
+:10C060006D756C74007662617473617600706163E3
+:10C07000616C61746835676C6F00706163616C69D5
+:10C08000647832673174680072786761696E7465CC
+:10C090006D70636F72723567680063636B5077729F
+:10C0A0004F6666736574007478707772696E646544
+:10C0B000780069716C6F63616C69647835676F666D
+:10C0C00066730070613062305F6C6F00676D67632C
+:10C0D000326700706163616C6964783567686931E3
+:10C0E0007468007278706F3267006E6F6973655F95
+:10C0F00063616C5F656E61626C655F3267006F7073
+:10C10000656E6C706761696E696478613532006F65
+:10C1100070656E6C706761696E6964786135360050
+:10C120006F70656E6C706761696E696478613131DA
+:10C130003200706163616C69647835670074656DA5
+:10C140007073617600747269736F32670076626132
+:10C15000745F616464006F70656E6C706761696EB6
+:10C1600069647861313230006F70656E6C70676140
+:10C17000696E69647861313234006F70656E6C701D
+:10C180006761696E6964786131323800747269641C
+:10C19000783267006F66646D64696766696C747491
+:10C1A000797065326700696E69747869647832679E
+:10C1B0000068775F697163616C5F656E00697163C8
+:10C1C000616C5F7377705F646973006D75785F672A
+:10C1D00061696E5F7461626C6500747373696F6628
+:10C1E000667365746D617835676800747373696F21
+:10C1F00066667365746D617835676C007473736916
+:10C200006F66667365746D617835676D0074656D12
+:10C2100070736D630074656D70736D660074737315
+:10C22000696F66667365746D6178006F70656E6CBA
+:10C23000706761696E696478613630007478616C2A
+:10C24000706662797032675F63636B006F70656EF2
+:10C250006C706761696E6964786136340066726516
+:10C26000716F66667365745F636F7272006F70657D
+:10C270006E6C706761696E69647861313332006F2A
+:10C2800070656E6C706761696E69647861313336B0
+:10C29000007874616C6D6F646500747373697469A0
+:10C2A0006D65006E6F6973655F63616C5F706F5F72
+:10C2B000356700747373696F66667365746D696E54
+:10C2C00035676800B8C70200600000001200000077
+:10C2D000000000002000000028C702002600000027
+:10C2E0000E0000000000000010000000B4CC0200AE
+:10C2F000980000000D000000000000002000000079
+:10C3000074C702004400000011000000000000009B
+:10C310000800000074D102001000000010000000AE
+:10C3200000000000080000000000000040000000C5
+:10C3300080000000C00000000100000005000000B7
+:10C3400002000000060000000A0000004A00000091
+:10C350008A000000CA0000000A0100004A01000033
+:10C360008A0100008A0500008A0900008A0D000089
+:10C370008A1100008A5100008A9100008AD10000D1
+:10C380008A1101008A5101008A9101008900000090
+:10C390008AD101008A1102000000000000000000A4
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000003001300410300131F
+:10C4B000004003001200410300120040030011007D
+:10C4C0004103001100400300100041030010004030
+:10C4D000030010003E030010003C030010003A036C
+:10C4E000000F003D03000F003B03000E003D030062
+:10C4F0000E003C03000E003A03000D003C03000D4B
+:10C50000003B03000C003E03000C003C03000C0049
+:10C510003A03000B003E03000B003C03000B003B02
+:10C5200003000B003903000A003D03000A003B032F
+:10C53000000A0039030009003E030009003C030023
+:10C5400009003A0300090039030008003E0300080F
+:10C55000003C030008003A0300080039030008000B
+:10C5600037030007003D030007003C030007003AC3
+:10C5700003000700380300070037030006003E03EE
+:10C580000006003C030006003A03000600390300E1
+:10C5900006003703000600360300060034030005DA
+:10C5A000003D030005003B030005003903000500C2
+:10C5B000380300050036030005003503000500338D
+:10C5C000030004003E030004003C030004003A039F
+:10C5D00000040039030004003703000400360300A0
+:10C5E000040034030004003303000400310300049A
+:10C5F0000030030004002E030003003C030003008E
+:10C600003A03000300390300030037030003003638
+:10C61000030003003403000300330300030031036D
+:10C6200000030030030003002E030003002D03006D
+:10C6300003002C030003002B030003002903000266
+:10C64000003D030002003B0300020039030002002A
+:10C6500038030002003603000200350300020033F5
+:10C6600003000200320300020030030002002F0327
+:10C670000002002E030002002C030002002B030026
+:10C6800002002A030002002903000200270300021F
+:10C69000002603000200250300020024030002001C
+:10C6A00023030002002203000200210300020020F5
+:10C6B000030001003F030001003D030001003B03B4
+:10C6C00000010039030001003803000100360300B7
+:10C6D00001003503000100330300010032030001B3
+:10C6E0000030030001002F030001002E03000100B1
+:10C6F0002C030001002B030001002A030001002984
+:10C7000003000100270300010026030001002503A8
+:10C7100000010024030001002303000100220300A4
+:10C7200001002103000100200004000400040004B3
+:10C7300000040004000400040004000400040104D8
+:10C7400080048204830484040004000400040004C0
+:10C7500000040004000400040004010480048204B6
+:10C760008304840485048604050506050705080579
+:10C7700009050A05090C12181818090C12181818BE
+:10C7800000000C076F7A060C0F7B7E0105080B0E6C
+:10C79000110000000000000000000306090C0F1249
+:10C7A000000000000000000000000306090C00006B
+:10C7B0000000000000000000000000000400000075
+:10C7C0004000000080000000C000000001000000E8
+:10C7D000050000004500000085000000C5000000C5
+:10C7E00005010000450100008501000085050000ED
+:10C7F00085090000850D000089090000890D0000F1
+:10C8000089110000895100008991000089D1000040
+:10C8100089110100854D0000858D000085CD000047
+:10C820008951010089910100000000000000000012
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000008000800080008000F7
+:10C9400080008000800080008000810082008300E1
+:10C9500084008500040105018000800080008000C3
+:10C9600080008000800081008200830084008500B8
+:10C9700004010501060107011901870188018901E8
+:10C980008A018B0107001F004807001F00460700AF
+:10C990001F004407001E004307001D004407001C41
+:10C9A000004407001B004507001A00460700190055
+:10C9B0004607001800470700170048070017004601
+:10C9C0000700160047070015004807001500460736
+:10C9D000001500440700150042070015004007003D
+:10C9E00015003F0700140040070013004107001323
+:10C9F000004007001200410700120040070011002C
+:10CA000041070011004007001000410700100040DE
+:10CA1000070010003E070010003C070010003A0716
+:10CA2000000F003D07000F003B07000E003D070010
+:10CA30000E003C07000E003A07000D003C07000DF9
+:10CA4000003B07000C003E07000C003C07000C00F8
+:10CA50003A07000B003E07000B003C07000B003BB1
+:10CA600007000B003907000A003D07000A003B07DA
+:10CA7000000A0039070009003E070009003C0700D2
+:10CA800009003A0700090039070008003E070008BE
+:10CA9000003C070008003A070008003907000800BA
+:10CAA00037070007003D070007003C070007003A72
+:10CAB00007000700380700070037070006003E0799
+:10CAC0000006003C070006003A0700060039070090
+:10CAD0000600370700060036070006003407000589
+:10CAE000003D070005003B07000500390700050071
+:10CAF000380700050036070005003507000500333C
+:10CB0000070004003E070004003C070004003A0749
+:10CB1000000400390700040037070004003607004E
+:10CB20000400340700040033070004003107000448
+:10CB30000030070004002E070003003C070003003C
+:10CB40003A070003003907000300370700030036E7
+:10CB50000700030034070003003307000300310718
+:10CB600000030030070003002E070003002D07001C
+:10CB700003002C070003002B070003002907000215
+:10CB8000003D070002003B070002003907000200D9
+:10CB900038070002003607000200350700020033A4
+:10CBA00007000200320700020030070002002F07D2
+:10CBB0000002002E070002002C070002002B0700D5
+:10CBC00002002A07000200290700020027070002CE
+:10CBD00000260700020025070002002407000200CB
+:10CBE00023070002002207000200210700020020A4
+:10CBF000070001003F070001003D070001003B075F
+:10CC000000010039090C12181818090C121818180C
+:10CC100000000C076F7A060C0F7B7E0105080B0ED7
+:10CC2000110000000000000000000306090C0F12B4
+:10CC3000000000000000000000000306090C0000D6
+:10CC4000000000000000000007001000390700107D
+:10CC500000380700100036070010003407001000ED
+:10CC60003307001000310700100030070010002FBC
+:10CC7000070010002D070010002C070010002B07E4
+:10CC80000010002A070010002807001000270700E6
+:10CC900010002607001000250700100024070010D0
+:10CCA00000230700100022070010002107001000D9
+:10CCB0002000000000000000400000000000000014
+:10CCC00040000000000000004000000000000000E4
+:10CCD00040000000000000004000000000000000D4
+:10CCE00040000000000000004000000000000000C4
+:10CCF00040000000000000004000000000000000B4
+:10CD00004000000000000000400000000000001093
+:10CD1000400000000000000048000000000000206B
+:10CD20004800000000000030480000000000004003
+:10CD300048000000000000504800000000000060B3
+:10CD4000480000000000005050000000000000609B
+:10CD50005000000000000070500000000000008043
+:10CD6000500000000000009050000000000000A0F3
+:10CD700050000000000000B050000000000000C0A3
+:10CD800050000000000000D050000000000000E053
+:10CD900050000000000000F050000000000000E023
+:10CDA00058000000000000005900000000000010C2
+:10CDB0005900000000000020590000000000003071
+:10CDC0005900000000000040590000000000005021
+:10CDD0005900000000000060590000000000000041
+:10CDE00040000000000000004000000000000000C3
+:10CDF00040000000000000004000000000000000B3
+:10CE000040000000000000004000000000000000A2
+:10CE10004000000000000000400000000000000092
+:10CE20004000000000000010400000000000000072
+:10CE30004800000000000020480000000000003012
+:10CE400048000000000000404800000000000050C2
+:10CE50004800000000000060480000000000005092
+:10CE60005000000000000060500000000000007052
+:10CE70005000000000000080500000000000009002
+:10CE800050000000000000A050000000000000B0B2
+:10CE900050000000000000C050000000000000D062
+:10CEA00050000000000000E050000000000000F012
+:10CEB00050000000000000705100000000000080E1
+:10CEC0005100000000000090510000000000002010
+:10CED0005900000000000030590000000000004030
+:10CEE00059000000000000505900000000000060E0
+:10CEF00059000000000000A059000000000000B030
+:10CF000059000000000000000000000000000000C8
+:10CF10000000000000000000080000000000000009
+:10CF200008000000000000000800000000000000F1
+:10CF300008000000000000000800000000000000E1
+:10CF400008000000000000000800000000000000D1
+:10CF500008000000000000000800000000000010B1
+:10CF60000800000000000020080000000000003061
+:10CF70000800000000000040080000000000005011
+:10CF800008000000000000401000000000000050F9
+:10CF900010000000000000601000000000000070A1
+:10CFA0001000000000000080100000000000007071
+:10CFB0001800000000000080180000000000009031
+:10CFC00018000000000000A018000000000000B0E1
+:10CFD00018000000000000C018000000000000D091
+:10CFE00018000000000000E018000000000000F041
+:10CFF00018000000000000001900000000000010F0
+:10D00000190000000000002019000000000000309E
+:10D01000190000000000004019000000000000504E
+:10D0200019000000000000601900000000000070FE
+:10D03000190000000000008019000000000000003E
+:10D0400008000000000000000800000000000000D0
+:10D0500008000000000000000800000000000000C0
+:10D0600008000000000000000800000000000000B0
+:10D070000800000000000010080000000000002070
+:10D080000800000000000030080000000000004020
+:10D0900008000000000000500800000000000040F0
+:10D0A00010000000000000501000000000000060B0
+:10D0B0001000000000000070100000000000009050
+:10D0C0001100000000000070180000000000008047
+:10D0D000180000000000009018000000000000A0F0
+:10D0E00018000000000000B018000000000000C0A0
+:10D0F00018000000000000D018000000000000E050
+:10D1000018000000000000F01800000000000000FF
+:10D1100019000000000000101900000000000020AD
+:10D12000190000000000003019000000000000405D
+:10D13000190000000000005019000000000000600D
+:10D1400019000000000000701900000000000080BD
+:10D1500019000000000000A019000000000000B04D
+:10D1600019000000000000000000000000000000A6
+:10D17000000000005F36291F5F36291F5F36291F18
+:10D180005F36291F28C30200600000001200000063
+:10D19000000000002000000038C902002600000046
+:10D1A0000E000000000000001000000014CF02007C
+:10D1B000980000000D0000000000000020000000AA
+:10D1C00004CC020044000000110000000000000038
+:10D1D0000800000074D102001000000010000000E0
+:10D1E00000000000080000000A5254452028257362
+:10D1F0002D25732573257329202573206F6E2042FA
+:10D20000434D25732072256420402025642E25641B
+:10D210002F25642E25642F25642E25644D487A0A17
+:10D22000000000002DE9FF4106460D460846FC219E
+:10D2300017469846D9F34CF5044608B91E302DE040
+:10D240000021FC22D4F3FCF60A9B04F1640204F1F1
+:10D250006801009301920291304629463A464346BE
+:10D26000FBF73EFC206608B90B2017E040F61201E0
+:10D270000022DDF3C3F700210A46E0662560206E38
+:10D28000DDF3E0F52046F8F707FB206EFBF7EAFA3E
+:10D2900028462146FC22D9F32BF5002004B0BDE836
+:10D2A000F081C04601BC600300104E03BFDE02F0F7
+:10D2B0000C0E0280C12700000403BFDE02F00D6FD8
+:10D2C000035B5E02F0000601BC6013001043000126
+:10D2D0005E02F0000000025E02F0117A00025E02BF
+:10D2E000F0118F020200BF00007302045EFF000015
+:10D2F0000E006B446557800E01846002F7F7BF0192
+:10D30000BC6003000AAE00025E02F00F960202DE6D
+:10D31000FF000013006B44655620130182E002F702
+:10D32000F7BF03BFDE02F005A200682B6F000018F4
+:10D330000280DEFF000073006B44655B6073018454
+:10D34000E006F577AB00025E02F0112F020480C701
+:10D3500000001A028180C700001C01806002F7F7FC
+:10D36000BF01BC6003000AE200682B070000270031
+:10D37000E844655837A1006DDE8557402300682BCF
+:10D380004300002700E844655A17A1006DDE855769
+:10D39000402503BFDE02F0002701BC6003000AC283
+:10D3A00001BC6003000AC101BC6003000AD001BCDB
+:10D3B0006003000AC80202DEB300002A0200420332
+:10D3C00000002A00025E02F00B1602845EB3000029
+:10D3D000730068AB0F0000730283DEB700002E02FB
+:10D3E0000180C700004800B02ACB0017A202802BA2
+:10D3F000F300003500B02B230017A1006DDE855C23
+:10D40000E06400685E8700003500682C0700003586
+:10D4100000B02C070017A200682B0B00003A00E8B0
+:10D4200044655857A1006DDE86F4406400E05E85D7
+:10D4300055F7A1006DDE86F440640202DEBB0000F9
+:10D440004800682ABB00004800E8446556D7A100A0
+:10D45000E02ABB0157A2006EDE86F440420182E062
+:10D4600002F5D7AE01BC6003000AAE03BFDE02F0D6
+:10D47000004800E82ABAF437A100902ABB0037A27E
+:10D48000006E2ABEF4404600B02ABF0017A2006911
+:10D49000DE86F4404803BFDE02F000640283DEB79C
+:10D4A00000005C028881AB00005A02035EB70000F6
+:10D4B00073020480C700004D02005EFF00005A02A4
+:10D4C0008080BF00005A0204DEB700005100682BC4
+:10D4D0001708607303BFDE02F0005A028400C70021
+:10D4E0000053028600C700005500682B0B00005A4D
+:10D4F00002812C4700005A00E844655737A1006DAF
+:10D50000DE8558005A006CC46557607300B04467EC
+:10D51000000ABB02845EB700007300025E02F011D5
+:10D520004903BFDE02F0007301BC63FF1FF7A100D7
+:10D53000684586F4205A0203C57300006402845EC5
+:10D54000B7000064020100C7000073006B44655718
+:10D5500080730020E3FE1460730282DEBB00007360
+:10D5600002022C470000670282DEBB00006703BF97
+:10D57000DE02F0005A028881AB0000730282DEB343
+:10D58000000073028080BF0000730284DEAF0000E1
+:10D590007302825EBB00007303A0DE02F0006F0224
+:10D5A00000420300006F00025E02F00B1601836070
+:10D5B00002F5B7AD0184E006F577AB01BC6003006E
+:10D5C0000AC300B04467000AC4018060020D906C79
+:10D5D00003595E02F0007503D85E02F0007603D8AE
+:10D5E000DE02F0007701BC618300112900B0007BEE
+:10D5F00000112B01BC630300112303125E02F00A29
+:10D600008F03975E02F00B2703D05E02F002F40353
+:10D61000D0DE02F0051003D5DE02F00A4C03915E65
+:10D6200002F005760396DE02F00A470288C1730015
+:10D63000009E03C45E02F006E703C75E02F0071611
+:10D6400003DCDE02F011CF03AA5E02F00759038665
+:10D65000DE02F00A870287C037000A8703835E0272
+:10D66000F008AB0391DE02F005F803C2DE02F00A17
+:10D67000EC00025E02F00F9500025E02F0117A03E8
+:10D68000D4DE02F0068103A3DE02F0000200025E97
+:10D6900002F00C6300025E02F00EC403A25E02F010
+:10D6A000009B03565E02F000980186600609104850
+:10D6B000031F5E02F00098006A5E2300009700B02E
+:10D6C000002700178800E85E2300378803A65E0263
+:10D6D000F0010500025E02F00F5D0028600E08E117
+:10D6E0002803C4DE02F00B5E0020C20300213003D9
+:10D6F000BFDE02F0017D03815E02F000A00300DEC8
+:10D7000002F000820188E0020B905C03BFDE02F0B1
+:10D7100002F1028740630000A20282C1070000A359
+:10D7200001866006F43018028640630000A500B050
+:10D730005E870017A10002DE02F00000028740634E
+:10D740000000A800B05E8B0010190186E006F430DE
+:10D75000180281DEAF0000AD0286C0630000AC009D
+:10D76000B05E870017A10002DE02F0000001BC607D
+:10D77000030280060280DE070000B901DA6002F0D1
+:10D78000178002085E070000C901BC60031E17A1D4
+:10D7900000E05E02F4306501BC60031C17A100E0EC
+:10D7A0005E02F4306401BC600300281803BFDE028F
+:10D7B000F000CF01105E030017A100885E870037DC
+:10D7C000A200E05E86F457A100E0015AF430630243
+:10D7D0008600C30000C200B0560B00106200B054B7
+:10D7E0000300106201BC600300281803BFDE02F0D2
+:10D7F00000D100B0418F0010620109DE030017A1C3
+:10D8000000885E870057A100E05E850597A100E0D3
+:10D810005E8703C00601BC600300481803BFDE0238
+:10D82000F000D101BC60070217A100E05E02F430F5
+:10D830006501BC60070017A100E05E02F4306401DE
+:10D84000BC600318000601BC600300081800B05A51
+:10D850000300106200B0580300106301050143008B
+:10D8600017A10088001AF420060002DE02F0000072
+:10D8700001BC600306379201BC63FF1FF0C301BC0B
+:10D8800060031890E301BC63FF1FF0C501BC63FF98
+:10D890001FF0C601BC63FF1FF0C700B02C5B001077
+:10D8A000E500B02C5F0010E600B02C630010E7022A
+:10D8B00080AC470000E701BC600300101000B040DE
+:10D8C0004300180000B040470010E501BC600300B1
+:10D8D000301000B0404300180000B040470010E690
+:10D8E00001BC600300501000B0404300180000B0BD
+:10D8F00040470010E701BC63FF1FF0C40002DE02D6
+:10D90000F0000000E840330097A100B0400B001782
+:10D91000A3006D5E86F460EE00905E8F0037A30377
+:10D92000BFDE02F000EF00905E870037A301BC600D
+:10D930001F1417A100E05E8EF437A301F041970099
+:10D9400017A1006DDE86F461030287C1970000F71E
+:10D9500001385A030017A1013C5A030017A203BF64
+:10D96000DE02F000F9013C5A030017A101385A0702
+:10D970000017A200685E86F480FE00D85E8B003738
+:10D98000A200E14196F4506500E1C19700306503C3
+:10D99000BFDE02F000F100D85E8B0037A200E1414B
+:10D9A00096F457A100E1DE870037A101F05E870001
+:10D9B00017A1006EDE86F4610401BC63FF1FF7A4AB
+:10D9C0000002DE02F000000020E38E090002031EC8
+:10D9D000DE02F0010B039F5E02F0010B01BC60430D
+:10D9E0000117A100A84122F4304803BFDE02F00075
+:10D9F0000200689B6F0000990208411F00010801A6
+:10DA0000816005620B1000025E02F00B1600B00090
+:10DA1000AB00108600B0016300108A00025E02F0C5
+:10DA20000D9601BC600304179200B0003B00111D6D
+:10DA30000190600609104803A1DE02F00122018175
+:10DA4000E00609104801BC600300904201BC60037D
+:10DA500000112D039EDE02F0012501846002F29781
+:10DA60009400B0451700178F00B05E1700179002A2
+:10DA700000441F00012001856002091048018160F7
+:10DA80000700104701F0DE0F0037A100A044B6F4F4
+:10DA90003145039EDE02F0012501BC613712B080E2
+:10DAA00003BFDE02F0000200A044B42A314501BCED
+:10DAB000612712708003BFDE02F000020020E082C6
+:10DAC000090002010CDE530017A101885E870010D7
+:10DAD0004701BC60030050420108411F0017A1012B
+:10DAE0008CDE86F2979403BFDE02F000020002DEB5
+:10DAF00002F000000020E07E09000200025E02F059
+:10DB00000F670283C21F000002020280F300013A85
+:10DB100000B044670017A1017C5E862357A30283EF
+:10DB20005EFF00013900E000FAF46830018360060E
+:10DB3000F7F7BF006BDE8D06013E0206D003000141
+:10DB40004200E950862337A100E8D08A2357A2007B
+:10DB500069DE8B00014200025E02F00B160191604B
+:10DB60001684F42700E020C300883003BFDE02F0F3
+:10DB700002CC00025E02F002CF020400BF00014AA4
+:10DB800003945E02F000020020C28F02000200A097
+:10DB9000428F01F78000685E002DC00200025E0225
+:10DBA000F00B1603BFDE02F000040201C28F00007A
+:10DBB00002011400630017A100685E870060020084
+:10DBC000025E02F00B160194600F00001800025E66
+:10DBD00002F0015103BFDE02F000040114006300F3
+:10DBE00017A100B05E870010A501BC601311106082
+:10DBF00000685E8700015800E0418306D06000E8BD
+:10DC00005E870037A103BFDE02F00154028050C3DB
+:10DC1000000162018760040310A000B000630010DF
+:10DC2000B400B042D3001800008841830030B60130
+:10DC3000BC60030B10B500B0006300B0B40317DE86
+:10DC400002F0015F0397DE02F0016001806006864A
+:10DC500014300002DE02F000000020E01280417C5F
+:10DC6000018760040310A000B000630010B401BC81
+:10DC700060030E10B500B0006300F0B401BC605743
+:10DC80000490B600B000630010B401BC600302D081
+:10DC9000B50207500B00017901BC600303D0B50148
+:10DCA0008E6002F297940204500B0001720204D0BD
+:10DCB0000B00017201866006F2979400E042D700E3
+:10DCC000D0B500A0500B1117A10068DE87110178B4
+:10DCD0000186E006F2979400E042D70050B50207B3
+:10DCE000D00B00017800E042D70090B500B042D7D9
+:10DCF0000011E100B0006300B0B40317DE02F001D0
+:10DD00007A0397DE02F0017B0002DE02F0000000E1
+:10DD10006820DF000180006CC46506E00401BC607F
+:10DD200003000837006820D7000183006CC4650633
+:10DD3000C00401BC60030008350020E0BE090002F9
+:10DD400003905E02F0000403A25E02F001BE020234
+:10DD500000BF0001880203C5730001B100682F6B8A
+:10DD600000018C00E844657B57A1006D5E857B2136
+:10DD7000B101BC6003000BDA00682D9B0001B10209
+:10DD800082C1070001B1028042030001B10285C5D2
+:10DD9000230001B1028640370001B10181E006F5A0
+:10DDA00077AB00B02D9F0017A101BC602F1077A2A8
+:10DDB00001BC60030017A300025E02F0131200B062
+:10DDC0002DA30017A101BC602F1777A201BC60032F
+:10DDD0000017A300025E02F0132001BC60131A17A3
+:10DDE000A100025E02F000A200B040670417A2008A
+:10DDF000025E02F000A800E0446700D7A1006CC4F6
+:10DE000066F4219F01BC60130ED7A100025E02F0F0
+:10DE100000A200A040673FF7A201BC601314D7A185
+:10DE200001BC62030017A300B05E8AF477A200026F
+:10DE30005E02F000A800B02D9F0017A101BC602F6A
+:10DE40000D37A201BC60030017A300025E02F013AD
+:10DE50001200B02DA30017A101BC602F13B7A201BF
+:10DE6000BC60030017A300025E02F013200181E0F2
+:10DE700002F577AB01BC6003000B6600025E02F0A6
+:10DE80000E74020200BF0001BD0284DEAF0001B8C3
+:10DE900002035EB70001BD00025E02F010FB020348
+:10DEA0005EB70001BD03BFDE02F0000202035EB7F1
+:10DEB0000001BB020480C70001BD02805EFF0001BB
+:10DEC000BD00025E02F010BC03BFDE02F0000200E3
+:10DED000025E02F00F670200421F0001D600684296
+:10DEE000F30001C1006D42F30041D601140063004C
+:10DEF00017A100B05E870017A203A25E02F001CA5C
+:10DF00000183E0020D906C03145E02F001D8006EF4
+:10DF1000C4568061D8028145230001D8006E5E8717
+:10DF20000061D601BC60030077A200886006F45748
+:10DF3000A300885E8B01001800E85E8B0037A2000A
+:10DF400020C28EF461D0006ADE86F441CA03BFDECF
+:10DF500002F001D6020400BF00020200900063013B
+:10DF60000165008085970217A100E064820DA1661B
+:10DF700000025E02F00F1D03BFDE02F0020201820A
+:10DF8000600209104803BFDE02F0000201BC60031A
+:10DF900000111500B0017F0017A6031F5E02F001FB
+:10DFA000E7020300C30001DD0020C28F0201E1038C
+:10DFB000255E02F001E70020C28F0201E1006881C6
+:10DFC00053FFE00403BFDE02F001E301946013009D
+:10DFD000001803BFDE02F00202039EDE02F001E63B
+:10DFE0000068DE980BC1E60201411F000CB40185F8
+:10DFF000600209104800685E980BC1EB00695E9FE3
+:10E000000062070298428F0001EB03BFDE02F002BC
+:10E01000070201411F000CB4020400BF0001F2021C
+:10E0200018428F000CB400025E02F00EFF00025E88
+:10E0300002F00F1D0194058700001803BFDE02F0F7
+:10E040000202020013BB0001FB0200156B0001FE7F
+:10E0500000B013470017A10068DE84A7A1FB00B041
+:10E06000134B0017A10068DE84A7C1FB00B0134F5B
+:10E070000017A10068DE84A7E1FB029E1397000150
+:10E08000FE0201C28F0002000194600F000018031D
+:10E09000BFDE02F002020201C28F000200018060B6
+:10E0A000060D906C0200C28F000CB4019460070052
+:10E0B000001800025E02F00151020400BF000237A6
+:10E0C000028500630002370183E0060D906C03BFF8
+:10E0D000DE02F0023701BC60031810600129500B0A
+:10E0E00000179200B0017B001065006800EB000291
+:10E0F0001000885A130117A100E84466F437A10004
+:10E100006EDE8407421000E0029B0020A603BFDE03
+:10E1100002F0067A019060120910480194601F0015
+:10E12000001801085A0F00178101885E0681540A01
+:10E1300001345A0F00178000025E02F000AF00B0F9
+:10E14000017B00106500B056230017A100E05E8639
+:10E15000A097A100E85E8400F40300E85E8400F468
+:10E160001600B05A0300141300B05A07001414002C
+:10E17000B05A0B0014150068DE0700422800E800C2
+:10E18000970057A101BC5E86F0141B017C5E8700DE
+:10E19000F41C00B0206300178100025E02F00D9AAB
+:10E1A00000B0017B00106501085A0F00178100B014
+:10E1B0005E8700141E03BFDE02F0022B00B056176C
+:10E1C00000141B00B0561B00141C00B054130014A4
+:10E1D0001E00B05013001086006D00A700823101B0
+:10E1E00090016300108A00B0418F00106200025E4F
+:10E1F00002F0119C00B0422B00140601BC60031811
+:10E2000017A1006DC18C20023401BC60030297A1EC
+:10E2100000E05E840377A100E05E86B0111D03BFBD
+:10E22000DE02F002AB020300C7000247020CD0037B
+:10E23000000247011400630017A102850063000279
+:10E24000470080DE8701F7A201BC601B0257A200D5
+:10E25000E05E8A0DB06500B041970014320080DEA8
+:10E260008700B7A201BC60171FD7A200E05E8A0D2D
+:10E27000B06400B041930014330068D81300025218
+:10E2800002005A1B0002490180600684F42703BF84
+:10E29000DE02F005A20201D00300024900B0509B4B
+:10E2A00000142F0281D0C70002C900025E02F002F2
+:10E2B000CF010BD0030017A1013C502B0017A20186
+:10E2C0008C5E86F457A1014801430017A200685EE6
+:10E2D00086F442520191601284F42703BFDE02F0FB
+:10E2E00002CC00025E02F0016300B0501300108601
+:10E2F00000B0501700108A00682FC300025D029121
+:10E30000D01700025B0291D01B00025B0291D01F6C
+:10E3100000025B0291D02300025B03BFDE02F00229
+:10E320005D0191600284F42703BFDE02F002CC039A
+:10E33000A25E02F0028A020CD003000279020300FE
+:10E34000C700027800B050CB00106500025E02F0FA
+:10E350001235020350C700026601BC60230097A17A
+:10E3600000A85002F4340003BFDE02F0027D020474
+:10E3700081AB000268006D4246C0800400B05A13B1
+:10E3800000178000025E02F000B900B0540F0014C4
+:10E390001E00B05A070017A100B05A1300178001E1
+:10E3A000875A16F0178000B0418F00106500025E9A
+:10E3B00002F011A500E05E86A0740302875E0300F0
+:10E3C00002770109DE030017A300E05E8B0077A24D
+:10E3D00000E05E8AF477A200885E8B0037A100E03F
+:10E3E0005E86F4508903BFDE02F0027D006D424A72
+:10E3F000848004010650070017A1028CD00300029C
+:10E400007C00685E8700027D0182DE8686343101F1
+:10E410008260028634310020D00304028300B050B1
+:10E420004F0011F200B050530011F300B0505700EC
+:10E4300011F401BC60030091F003945E02F0028AC3
+:10E44000020650030002860287DEAF00028A0281C4
+:10E4500050030004F10202D0C70002890208502BC9
+:10E4600000028A0285D003000508019060128634FC
+:10E470003103A25E02F0029700B0500F00111602A5
+:10E4800002D0C700028F00B0505B0011160282D08C
+:10E4900003000297028147C30002900280504F00A0
+:10E4A0000295002047C73F82970020C7DB00C2CB00
+:10E4B00003BFDE02F0029703A55E02F0029702801E
+:10E4C000C7DF0002CB028850C70002B10129500B00
+:10E4D000001792020300C70002A4020CD00300023E
+:10E4E000A4028350C70002A400B050CB0010650105
+:10E4F000385A1300178001825A17005781010E5AAB
+:10E50000130017A1018E5E86F037810202D0C7008A
+:10E5100002B100B0501B00108A03BFDE02F002B14E
+:10E520000282D0C70002AB013850270017800108D3
+:10E530005013001781010250130017A101825E865B
+:10E54000F0378100B0507F00108903BFDE02F00277
+:10E55000B10138506F0017800108502B001781015E
+:10E5600006D0070017A101825E86F0378100B05007
+:10E570001B00108A00B0508300108900025E02F078
+:10E5800000AF00025E02F00D8D0102421B001781F8
+:10E5900001825E0503178100025E02F00D9A00E021
+:10E5A0005E840117A101D9DE8700108301BC6137A9
+:10E5B00003B79100685E4B0282DF020400BF0002D5
+:10E5C000BD028750030002BD03945E02F002BE0349
+:10E5D000225E02F002C001BC610300308003BFDE96
+:10E5E00002F0000201BC613303B791032BDE02F09D
+:10E5F00002C6009000630097A100E06482F43065D9
+:10E60000006E5A130022C60188E006F237910068B6
+:10E61000DE4B0482C801BC61BB03B79103BFDE02BD
+:10E62000F002DF0191600E84F42703BFDE02F002E6
+:10E63000CC0191600684F42701BC60030010B40192
+:10E6400081E00686343103BFDE02F005A2011C50D2
+:10E650008F0017A100E0015EF43065010C5A4700FD
+:10E6600017A10080DE870197A200E0015E0DB06572
+:10E6700002805A7F0002DE02815A7F0002DA020322
+:10E68000DA7F0002DE00685A870002DE008860063A
+:10E69000F437A1002019FAF422DE00025E02F00B2A
+:10E6A000160191601E84F42700015E02F000000351
+:10E6B000BFDE02F002CC0002DE02F0000003C4DE86
+:10E6C00002F00B5E020650030002E70207DEAF0015
+:10E6D00002E701BC6103003791020750030002E525
+:10E6E00001BC620300F79100E0010B00204203BF70
+:10E6F000DE02F002E801BC600300204200B05E4789
+:10E70000001080020400BF0002F000B0058B001072
+:10E7100064006E45170000020068DE4B0282EF00C5
+:10E72000A044B42A314503BFDE02F0000200025EBD
+:10E7300002F00DA70068C51700000203D05E02F0CA
+:10E7400002F400025E02F00DA703BFDE02F0000239
+:10E7500001836002F7F7BF01BC600300900400A8CA
+:10E76000412330104801BC620F0011E001816002BA
+:10E77000F5D7AE020200BF0003050068DE4B0202BF
+:10E78000FC00025E02F0130C0068DE4B062305025B
+:10E79000045EB30003050200456F00030500E84472
+:10E7A000655737A100E82AB6F437A100695E8708EB
+:10E7B00023050183E0022B915C020701AB000305F6
+:10E7C0000180E00209D04E0187E002F577AB0068D6
+:10E7D000810B00230800B044670000430182E0067B
+:10E7E000091048018160020D906C01826006289139
+:10E7F000440188E0020B905C00025E02F00F95017C
+:10E8000085E002F7F7BF0288421B0003100185E094
+:10E8100006F7F7BF035B5E02F0031201BC60130052
+:10E82000104301BC600300108501BC60030010B8F8
+:10E83000008850770090B90208502B000319013866
+:10E8400050730017A1017C506EF437A100885E87D9
+:10E850000090B9020047A300031D01BC6003001132
+:10E86000EA009042E70091EB00B047A300D1E80234
+:10E870000047B300031F01B0E08E3D91EC01D2E0F0
+:10E880000210908403A95E02F0041601BC6003002C
+:10E89000108400E001C30020700320DE02F0037347
+:10E8A00001816006F5B7AD0068DE4B04A3370203B3
+:10E8B000DEBB00032900E02C9300106503BFDE02DD
+:10E8C000F0032A01BC602301D06500A05E7FFE102A
+:10E8D000EC00B05A030010ED00B05A070010EE0033
+:10E8E000B05A0B0010EF00B05A0F0010F001BC63DB
+:10E8F000FF1EF08401BC600300308501BC60030092
+:10E9000010B401BC600301D0A601BC60030450B583
+:10E9100001BC602304D0B400E002AF0020AB03BF11
+:10E92000DE02F003BB0068DE4B05233D01BC600343
+:10E930000010B401BC60071350A601BC600302D0F4
+:10E94000B501BC602304D0B403BFDE02F00347006E
+:10E9500068DE4B0243540285C38F00034000E05E33
+:10E960002700378901DA5E270010EE01BC63FF1F24
+:10E97000F0CE01BC60030010B401BC600300D0A65F
+:10E9800001BC600303D0B501BC602304D0B400E037
+:10E9900001D300207401BC61FF1FF08401BC60033F
+:10E9A000001085018460070011E00282DEB30004DC
+:10E9B000D802045EB30004D80183E00609104800C1
+:10E9C000B0412300180001BC600306B78E0181E04E
+:10E9D00006F5D7AE00B054130017A100E05E840125
+:10E9E00017A100885E8700708303BFDE02F004D8A1
+:10E9F00001BC60031FF0840103DE530017A200680E
+:10EA0000121B00035900B0121B0017A2009019FA44
+:10EA1000F457A202005EFF00035B01BC60030037F5
+:10EA2000A200682B6F00035D01BC60030037A201E8
+:10EA3000865E8A1C70E3006AC39300036700E843A4
+:10EA40009000D0E40202421B0003650090001B000E
+:10EA500037A10020421B00436400B020B30017A17F
+:10EA600000E04392F430E40069C39300036701BC03
+:10EA700060030010E400682B6F00036900E043911D
+:10EA80005C30E401BC60030010B401BC6003001002
+:10EA9000A601BC60030210B501BC602304D0B40021
+:10EAA000685E4B06A37100E001CB00207201BC60E0
+:10EAB0000300083803BFDE02F003BB00E001CF0013
+:10EAC000207303BFDE02F003BB03205E02F003C22B
+:10EAD0000181E00209104800E001D7002075031E03
+:10EAE000DE02F003A201BC60030017A2006A5E23ED
+:10EAF00000037B0102428F0017A201855E8A091084
+:10EB0000480180E0061030810284DE530003820059
+:10EB1000B000770017A100E05E840437A100885E92
+:10EB2000870057A100E05E870D57A103BFDE02F00A
+:10EB3000038301BC60030D57A1006800270003A2F6
+:10EB400000E05E8401F7A101BC60230150650088EC
+:10EB500041970030B601BC60030010B400905E879E
+:10EB60000050A601BC60030110B501BC602300B0D9
+:10EB7000B40317DE02F0038B0397DE02F0038C0070
+:10EB800020DE870043950020DE8700239201B85ED7
+:10EB900022D0168001805E8AD0368103BFDE02F06B
+:10EBA000039B01BC5E22D0168001845E8AD0368130
+:10EBB00003BFDE02F0039B0020DE8700239901B82B
+:10EBC0005E22D0368101805E8AD0568203BFDE028B
+:10EBD000F0039B01BC5E22D0368101845E8AD05650
+:10EBE0008201886002F430A800B05A030010B0001F
+:10EBF000B05A070010B1028042A300039E00E04219
+:10EC0000A30090A800B05A0B0010B000B05A0F003B
+:10EC100010B10187600610908400E05E27003789FC
+:10EC200001DA5E270010EE01BC60030010B401BCE5
+:10EC300060030350A600B000330010B50284DE5319
+:10EC40000003AC00E0606803B0A600E04298043026
+:10EC5000A600B000370010B501BC602304D0B40199
+:10EC6000846006F2979401866002091048039EDED4
+:10EC700002F003B60280441F0003B900B05E3F00FB
+:10EC8000114501BC600300178F00B05E430017857B
+:10EC900000B05E0F00179003BFDE02F003B900B0B2
+:10ECA0005E0F0017850280441F0003B900A044B620
+:10ECB000F0B14501BC600301104201836006F29788
+:10ECC00094018460070011E003A05E02F004D60204
+:10ECD000065EAF0004D80186E006F577AB01BC60A4
+:10ECE0000300108000025E02F00B1C03BFDE02F086
+:10ECF00005F803A15E02F0043D011400630017A1B2
+:10ED00000068DE8700E3C70181600609104803BF81
+:10ED1000DE02F0043D01816006F5D7AE011C508F84
+:10ED20000017A100E0015EF43064010C58470004B4
+:10ED3000870206508F0003D100B044670010F30033
+:10ED4000B0446B0010F401BC63FF1FF0D301BC633F
+:10ED5000FF1FF0D400B042170310850020600E861C
+:10ED600023F5018760040310A000B000630010B415
+:10ED700001BC60030B10B500B0006300F0B40203E7
+:10ED800000C70003E3020CD0030003E3028050C776
+:10ED90000003DB00B054130017A100E05E8680740E
+:10EDA0001A00B0506B0010E400B04213021084024D
+:10EDB00009502B0003E300B0421300308401D2E07D
+:10EDC0003AA030E0028050C70003E901D2E052A02F
+:10EDD00030E003BFDE02F003E90202D0C70003E91E
+:10EDE00000B0505F0010E000B050630010E100B0D0
+:10EDF00050670010E200B0506B0010E400B0421306
+:10EE000002F084020050C70003F000B0006300105D
+:10EE1000B401BC60030210B500B0006304D0B401BB
+:10EE20008460070011E001BC600300178E03BFDEA1
+:10EE300002F004DA00E001C700207100B0006300B6
+:10EE400010B401BC600302D0B500B0006304D0B4BC
+:10EE500003BFDE02F0046D01856006F7F7BF010312
+:10EE600050030017A100B85E870037A101875E86B6
+:10EE7000101080020CD00300043C020300C7000401
+:10EE80000C00B050CB00106501BC6003001685007B
+:10EE9000E05A3300368C020350C700040100E05AE8
+:10EEA0002700368903BFDE02F0043D01BC60030089
+:10EEB00017B200B05A0B000B2501385A130017A1E6
+:10EEC00001BC5A06F430E0013C5A130017A1017C42
+:10EED0005A06F430E10181E0061090840185E007D4
+:10EEE0000010E30185E0070010C30282D0C70004D0
+:10EEF0001103BFDE02F004140202D0C700041600A2
+:10EF0000B02A4B0017A101B8506EF430E000B050A9
+:10EF1000730017A101B82A4EF430E10282421300B7
+:10EF2000041400B0507B0010E400B04213021084BF
+:10EF30000185E0061C30E100B042130070840187B7
+:10EF400060040310A0020300C700042B00B050CBE4
+:10EF5000001065006D5ECAD1C41C0185E002187006
+:10EF6000C300E05ECB00368E01BC601B09D065009B
+:10EF7000E04196F6506500B050970016800068DEBC
+:10EF8000CB00042301BC60230150B800682C97001B
+:10EF9000242903BFDE02F0043500B05ECB0010B5BB
+:10EFA00000B000630870B4028342D300042501BCA2
+:10EFB00060030170B80068AC9700243501BC6003A1
+:10EFC0000170B802BC506700043403BFDE02F004D5
+:10EFD00033010CD0030017A103A95E02F004300135
+:10EFE000BC60230150B800685E8700643303BFDE55
+:10EFF00002F0043501BC60030170B800685E870050
+:10F00000443501BC60030170B80181E0021710B8FB
+:10F0100001BC600300F0A501BC60030E10B500B098
+:10F0200000630010B400B0006300F0B400B042D33D
+:10F03000001800018860080310B4018160060D907B
+:10F040006C03BFDE02F0046D0202D0C7000443006F
+:10F05000B0506F0010E000B050730010E100B050ED
+:10F06000770010E20282421300044200B0507B009D
+:10F0700010E400B0421302F08400E05E9F0037A766
+:10F0800003A15E02F0044C01BC60030017A70187D6
+:10F0900060040310A000B000630010B401BC600362
+:10F0A0000E10B500B0006300F0B4018860080310D2
+:10F0B000B403BFDE02F0046200B0017B0010650003
+:10F0C000B05A030010E501BC63FF1FF0C500B05A41
+:10F0D000070010E601BC63FF1FF0C600B05A0B002A
+:10F0E00010E701BC63FF1FF0C70068A0670004556C
+:10F0F00000E05E2700378900682067000459018519
+:10F10000E0070010E30185E0070010C300B04213E0
+:10F1100001108401DA5E270010EE0187600610906E
+:10F120008400B042131C108401BC60030010B400C2
+:10F13000E0606803B0A600B000970010B501BC60A5
+:10F140002304D0B4018460070011E003BFDE02F0A5
+:10F1500004C601085E4B0017A100685E8700246D9D
+:10F160000202500300046C029E509F0004690201D9
+:10F17000D00300046900E05E2700378901585E274C
+:10F1800000142D01DA50B70010EE018760061090D0
+:10F190008403BFDE02F0046D01BC600300142D0186
+:10F1A00004C1070017A10068121F00047200B0120A
+:10F1B0001F0017A1009019FAF437A103BFDE02F077
+:10F1C000047403225E02F004740103DE530017A1ED
+:10F1D00000B05E870017A202005EFF00047701BC4A
+:10F1E00060030037A200682B6F00047901BC600344
+:10F1F0000037A202885E4B00047C00685E4B0684E8
+:10F200007C01BC60030017A20068921F00047E010D
+:10F2100083DE86F297940183DE8684F4270281C21E
+:10F220001300048401865E8B0010E30186600700F2
+:10F2300010C30181E00610908403BFDE02F0048653
+:10F2400001865E8A1C70E3018660061870C302B8EE
+:10F2500047A70004C202A047B70004C403A95E0286
+:10F26000F0048E01085E4B0017A100685E87002441
+:10F27000C3021E509F00048E0185E0061C70E3014E
+:10F2800085E0061870C3011400630017A10068DE52
+:10F290008700849700B001530017A20068DE8BFF3F
+:10F2A000E493006842470024940068DE8A84C4978F
+:10F2B000018560020910480186E0021C70E30186A6
+:10F2C000E0061870C3011050070017A600685E9B87
+:10F2D0000004C301BC60030011E4013A50070017A9
+:10F2E0008000885E0300778000E000AEF0106400CC
+:10F2F00068DE9B0044A80207D0030004A201BC60A2
+:10F300002B12B7A200E05E000B37A300025E02F0F2
+:10F310000DE801BC602307978100E0418301706321
+:10F3200000E0418F00B06500025E02F00DBD01BC3F
+:10F33000602307506401BC60470017A200025E0210
+:10F34000F00E1000685E9B0044C401A46046F47196
+:10F35000E00068DE9B00C4B601BC611300B7A102E7
+:10F360000600F30004AF01BC601300B7A10192C214
+:10F370001AF437A203295E02F004B401BC60030052
+:10F3800011EE009042E70091EF0192E00EF437A2F7
+:10F3900000B05E8B0011EC03BFDE02F004C4006815
+:10F3A0005E9B0064BB00685E9B00A4BB00B0502F56
+:10F3B0000011E200B050330011E203BFDE02F0049E
+:10F3C000C4018760023D11E80068DE9B00A4BE0115
+:10F3D0008760063D11E801BC60030011EA0090421D
+:10F3E000E70091EB0192C21B00B7A201B85E8A3D13
+:10F3F00011E803BFDE02F004C4018460070011E0DD
+:10F4000001BC600300112D00B0448300142C03A341
+:10F41000DE02F004D901BC600300178E00685E4B69
+:10F4200005A4CA020050030004D30183E0060910BA
+:10F430004800B0412300180001BC600304B78E03EC
+:10F44000A95E02F004D800685E4B0424D801BC60B9
+:10F450000306378E00685E4B05A4D801BC60030626
+:10F46000B78E03BFDE02F004D801816006F577ABEA
+:10F4700000B05E0F00178500025E02F00DA701BC10
+:10F48000600300178C01BC600300178D0323DE02AC
+:10F49000F004DA0187E0061070830185E002F5B719
+:10F4A000AD03295E02F004EE020300C70004E90088
+:10F4B000B050CB0010650282D0C70004E100E05AD2
+:10F4C0002300368803BFDE02F004E200E05A270082
+:10F4D000368900682C970024E900E05ECB0037B243
+:10F4E000010A5ECB0017A100E050CAF4306500D0DD
+:10F4F0006006F657A200205A1AF444E903BFDE0260
+:10F50000F004E300025E02F00F9503D5DE02F00A7C
+:10F510004C03D6DE02F00A640350DE02F004E90375
+:10F52000BFDE02F0051002055EAF0004F00187E0C7
+:10F530000626713303BFDE02F000020190600A86E6
+:10F5400034310282D0C70004FA013C5027001780F2
+:10F550000109502B001781010750070017A10182F4
+:10F560005E86F0378100B0501F00108A00B0500F47
+:10F5700000111603BFDE02F005000138505F0017CE
+:10F5800080010A502B0017810107D0070017A10145
+:10F59000825E86F0378100B0502300108A00B050A0
+:10F5A0005B001116020300C7000505020CD0030022
+:10F5B000050502085E07000505013854070017809D
+:10F5C0000190422AA1308A028050C700050E01BC7A
+:10F5D000600305B79203BFDE02F0028F0190600660
+:10F5E000863431020300C70004F2020CD003000489
+:10F5F000F200B0001F0017A100E05E8680741A03BD
+:10F60000BFDE02F004F201BC600306379203BFDEE6
+:10F6100002F0028F02055EFF00051F01856002F700
+:10F62000F7BF032BDE02F0051F020000F3000516F2
+:10F6300000E8002300514201BC600A2851420394B3
+:10F640005E02F0051B00B0058B00106400685803D3
+:10F6500000051B00B0446700111200B058030011F0
+:10F66000150068451F00051F03A25E02F0051F017B
+:10F6700085E006F577AB00025E02F00ED70201C20C
+:10F68000E3000549020300C700052400682C970029
+:10F690002534006E4246F6453403BFDE02F00526EF
+:10F6A000006E4247002534020300C70005310355B0
+:10F6B000DE02F00526018060028614300138508396
+:10F6C0000017A100B050CB001065006DDA32F42AAB
+:10F6D0004C00A84123141048011400630010650079
+:10F6E000E041970ED06500E05A0300368001BC620D
+:10F6F0001F0011E003BFDE02F000040181E0068676
+:10F7000034310191600E84F42703BFDE02F0054915
+:10F71000013C50670017A101AC5E861750BA01BCCE
+:10F7200060030190B8020300C70005430068AC976E
+:10F7300000253E0181E0021710B803D5DE02F00A71
+:10F740004C03D6DE02F00A640350DE02F0053A03F1
+:10F75000BFDE02F0054900E82C97002B2500B05EC3
+:10F76000CB0010B500B000630870B4028342D30030
+:10F77000054103BFDE02F005440186E0040310A04A
+:10F7800000025E02F0015A03D5DE02F00A4C03D6F5
+:10F79000DE02F00A640350DE02F0054503BFDE021C
+:10F7A000F0031001BC600300F0A50182E002091023
+:10F7B0004801BC621F0011E001BC60030011EC01B4
+:10F7C000BC600F0011E80285500B000550018260FB
+:10F7D0000209104803A0DE02F0055403D5DE02F052
+:10F7E0000A4C03D6DE02F00A6403205E02F00556DE
+:10F7F0000188600209104803BFDE02F0000401BC6A
+:10F8000060030037A100025E02F00C5303A3DE0286
+:10F81000F00004020050C700056201BC6003001044
+:10F820008001826006091048018060028634310040
+:10F8300068921F0005600104C1070017A10183DE63
+:10F8400086F2979400E001CB00207203BFDE02F045
+:10F85000017D00B0010B0017A1006DDE840805A238
+:10F8600000E844640877A1006E5E840825A2018741
+:10F87000E006F577AB020200BF000575028881AB98
+:10F88000000575028400C70005750129500B00179B
+:10F89000A10068DE870205750282DEBB00057502E5
+:10F8A00003C5730005740283DEB30005740282DEB3
+:10F8B000BB00057100682B07000575006DDE2F0188
+:10F8C000E5750182E006F7F7BF00E04465564AB1EE
+:10F8D00003BFDE02F0000403BFDE02F005A20282D5
+:10F8E0005EAF00058501826006F577AB00B0446726
+:10F8F00000082300B0014B0017A20208421B0005BC
+:10F900007C00B0016B0017A200685E8B00058200CE
+:10F9100090452B0097A10080DE86F457A1006E2051
+:10F92000D60DA58200B041B700083500E020D623EF
+:10F9300028360185E002F5B7AD02055EAF0005850A
+:10F9400001BC610300113300E844650477A500B0F1
+:10F950004467000BDA006D5E97010080020200BF71
+:10F960000005940068DE4B06A58B0184E002F7F7E2
+:10F97000BF0068DE4B04058E0282DEB300058E01F7
+:10F98000BC6003000B1202045EB30005910068DE48
+:10F990004B06259100025E02F0112300025E02F088
+:10F9A0000F9603A3DE02F005940183E002F597AC05
+:10F9B00001BC60131497A100025E02F000A201BC1A
+:10F9C00063830017A100A04066F437A20068DE8AB6
+:10F9D000F425A001BC60130E77A100025E02F000C6
+:10F9E000A200A040673FF7A200985E8B0037A200FC
+:10F9F000685E8B00059F0068DE8B0FE5A001BC6090
+:10FA00002300104301826002F577AB03D15E02F060
+:10FA10000002020050C30005F10325DE02F005A636
+:10FA20000183600684F42703BFDE02F005D8020CD0
+:10FA3000D0030005D6020300C70005C5011400630A
+:10FA40000017A1006DDE870085D601BC600300179A
+:10FA50008000B050CB00106500B050CF00106401A2
+:10FA60008160060D906C0182600686343100B05AC8
+:10FA7000230017A101BC600300168801BC5A2AF4B8
+:10FA800037A101BC600300168A00B05E8700148FA6
+:10FA900000B05A270017A101BC600300168901BC01
+:10FAA0005A2EF437A101BC600300168B00B05E87AC
+:10FAB00000149000B05A1B00148D00B05A1F00149F
+:10FAC0008E01BC60030016040068DE030005C2025C
+:10FAD0000350C70005C10100509F00178001805EE0
+:10FAE0000291B48D01BC5E0292149001BC600300CF
+:10FAF000378000025E02F0128100B05E0300148CB9
+:10FB000003BFDE02F005D10068C2470005CA0181CB
+:10FB1000E0068634310191600E84F42701BC600355
+:10FB200000143003BFDE02F0000200B0509F001747
+:10FB3000A100025E02F0015900B05E8700142701A7
+:10FB400086E0040310A000B04283001800010CD02E
+:10FB5000030017A10068DE870065C5010250C700D9
+:10FB600017A101805E8684F427018AE00E84F427C1
+:10FB700000B050BF00142603BFDE02F005D8018696
+:10FB8000E0040310A00200509F0005D80286C107C0
+:10FB90000005EC03295E02F005DD00B052330014CD
+:10FBA0002D00B052370017A1019E5E8684F4270015
+:10FBB000B0509F0017A10180DE86F437A100B0503D
+:10FBC000BB00108F00B050B700108E00B0509B00EB
+:10FBD000108D01806006F4308C020250C70005EBE6
+:10FBE00000B0524300108F00B0523F00108E00B0A2
+:10FBF000523B00108D011A52370017A10198DE8781
+:10FC00000437A101B85E8691B08C0182600286340F
+:10FC100031018160020D906C0325DE02F005EF01D9
+:10FC20009C600284F42703BFDE02F005F3028550D6
+:10FC30000B0005F100A850C70D143101BC60030092
+:10FC4000143001816002F5D7AE0183600284F4278D
+:10FC50000185E00209104801BC600300142E03A2D4
+:10FC60005E02F0017D03BFDE02F000040323DE022A
+:10FC7000F0065C03A35E02F0065C03A2DE02F0065F
+:10FC80005C01816006F577AB03AA5E02F0065C01B9
+:10FC900083E0020910480351DE02F0061B02045EF5
+:10FCA000B300060801846002F597AC0183E0020905
+:10FCB000104800B02B5F0017A1006D2B0EF420023E
+:10FCC00000E0027B00209E01BC6003000AC300022A
+:10FCD0005E02F0112603BFDE02F000020203DEB373
+:10FCE0000006180183E002F597AC00E02A9B002A89
+:10FCF000A602015EBB00061800B02A9F0017A100F3
+:10FD00006D2A9AF4261301BC6003000AA600E002E3
+:10FD10007F00209F03A95E02F006160191601A84FD
+:10FD2000F42703BFDE02F002CC01BC63FF1FF7A182
+:10FD300000025E02F00C5303295E02F006180191E6
+:10FD4000601A84F42703BFDE02F0061800E0026B9D
+:10FD500000209A0180E006F577AB03BFDE02F006D3
+:10FD6000200301DE02F0061E00685E4F06261E011B
+:10FD7000BC60030017A803A45E02F0062003C1DEE6
+:10FD800002F0065F01846002091048020400BF000F
+:10FD9000062501BC6003001115011400630017A1C2
+:10FDA00000E06602F4306500025E02F00DAC0182F4
+:10FDB000600209104803A95E02F0064000685E3B3D
+:10FDC00004A63001F0DE1700378500A05E16F0971C
+:10FDD0008500685E3B0626300201500300062F02B4
+:10FDE0008780BF00062F0185E0060910480280D0F9
+:10FDF0000300064000B05E1B0017A300B0008B009C
+:10FE000017A4020400BF000636006E419730663624
+:10FE100001185A030017A3011A5A030017A4006817
+:10FE2000C18318063900E002930020A403BFDE025C
+:10FE3000F0063B006D5E2EF4863B0182E0068634C0
+:10FE40003100E05E3300378C0068DE32F4663E003D
+:10FE5000B05E0F001785006DDE2EF4664C03BFDE2A
+:10FE600002F0065700B05E1F0017A300B0008F001D
+:10FE700017A4020400BF000646006E419730664694
+:10FE8000011C5A030017A3011E5A030017A4006D9A
+:10FE90005E2EF486480182E00686343100E05E374B
+:10FEA00000378D0068DE36F4664B00B05E0F001739
+:10FEB00085006D5E2EF466570185E0020910480347
+:10FEC000D1DE02F0064E00025E02F00DA70068418E
+:10FED0008318067A020300C7000655020CD00300FF
+:10FEE0000655028350C70006550068DE4B05A6552F
+:10FEF00003BFDE02F011FF0181E00686343103BF4B
+:10FF0000DE02F005A200025E02F00DA70181600290
+:10FF100009104803295E02F0065C028300C7001145
+:10FF2000FF03BFDE02F005A203D1DE02F0065D038F
+:10FF3000A5DE02F005A203BFDE02F00004020650B7
+:10FF40000300066500B001030017A1006D810AF4EB
+:10FF5000266500E844640877A1006E5E8408266583
+:10FF60000187E006F577AB01085E4B0017A100683A
+:10FF70005E8700266800B05E0F00178500025E02F3
+:10FF8000F00DA700685E3B06266E01BC60030017FB
+:10FF90008C0200D00300067301BC600300178D03C0
+:10FFA000BFDE02F0067301BC600300178C02030081
+:10FFB000C700017D020CD00300017D019C6002841A
+:10FFC000F42703BFDE02F0017D0068418318067943
+:10FFD0000180600684F42703295E02F005A20182F5
+:10FFE0006006863431028300C70011FF03BFDE02C2
+:10FFF000F005A200E002970020A50181600209102F
+:020000023000CC
+:100000004801BC600300081900E0017B00A05E010C
+:10001000BC601310D7A1006D017AF4200401BC600C
+:100020001309405E03BFDE02F0000400025E02F02E
+:100030000B160338DE02F00004039EDE02F000041B
+:1000400000E8444C00F7A100E85E840117A1006AB3
+:10005000DE8401068A00E85E8401118701BC60032A
+:1000600000118801A5E02230118001BC600300115D
+:100070001301BC600300111400B044670017A10015
+:10008000B0446B0017A200B05E8700110400B05EA0
+:100090008B00110503B8DE02F0068C03BFDE02F010
+:1000A000000401BC600304B79201BC60030417A103
+:1000B00001BC63FF1FF0CB01BC63FF1FF0CC01BC90
+:1000C00063FF1FF0CD01BC63FF1FF0CE01BC63FFD7
+:1000D0001FF0CF01BC63FF1FF0D000B0521700101B
+:1000E000E801BC63FF1FF0C800B0521B0010E9011B
+:1000F000BC63FF1FF0C900B0521F0010EA01BC63CF
+:10010000FF1FF0CA01BC60030010E4028600C300B8
+:1001100006AD00B0540F0017A20069DE8A9086A5D4
+:1001200000E85212F450E40068A0630006AD01BC80
+:1001300060030010E400B054270010E000B0542F1A
+:100140000010E103BFDE02F006B603A4DE02F008F1
+:10015000AB03A9DE02F008AB01BC600301D7A1022A
+:100160000600C30006AF0280DE5F0006B400B05494
+:10017000070010E0006820630006B201D2DE86A00E
+:1001800030E000B0540B0010E103BFDE02F006B611
+:1001900001BC5E869010E001BC601F0010E101BC54
+:1001A00060030010E200B052230010E501BC63FFC1
+:1001B0001FF0C500B052270010E601BC63FF1FF01E
+:1001C000C600B0522B0010E701BC63FF1FF0C70050
+:1001D000B0004700108601082063001781013852E3
+:1001E000030017800102C0270017A600025E02F07C
+:1001F0001198006820630046C400B05407001780BF
+:1002000000025E02F00D8D006820630026CD0068BC
+:10021000A0630006C8021A54070006CD006800A7B4
+:100220000106CB0103C0270017A103BFDE02F006C1
+:10023000CC0106C03B0017A101825E8610D0860368
+:10024000A9DE02F008EB00685E4F0426DF01BC6304
+:10025000FF1FF0C300685E4F05A6D501BC60031AFE
+:1002600090E301BC600306B79200685E4F0526DF8D
+:1002700003BFDE02F006D901BC6003063792029884
+:1002800044070009C0028046070009C001BC6003A2
+:100290001890E300B0206300178100025E02F00DA9
+:1002A0009A00E85E8400D7A1006A5E869086DF002F
+:1002B000E85212F430E403BFDE02F006E201BC6053
+:1002C000030010E40338DE02F006E20187E0061CBA
+:1002D00090E40190600A09104801BC610304379161
+:1002E00000685E4F05A9C003835E02F008AB03BF40
+:1002F000DE02F0000201866002F7F7BF0182E00231
+:10030000F5B7AD0185E002F5B7AD02044163000623
+:10031000F2018460020B105802055EAF0006EE0188
+:1003200087E006267133020400BF0006F10185E074
+:1003300002F577AB00025E02F00ED703BFDE02F0DB
+:1003400000020283C0370006FA006CC4656C26FB0D
+:1003500001BC601B1A77A100025E02F000A20180BE
+:10036000E0060337A200025E02F000A80180E0026E
+:10037000F457A200025E02F000A800E044656C4B56
+:10038000610285C52300070A018460060B1058022C
+:1003900000DEFF0007010180E002F7F7BF00682BD5
+:1003A0006F00070100E044655B4ADB0207AC0F0009
+:1003B000070A0280456F00070A01BC63FF1FF7A10F
+:1003C0000068DE862C270A01BC60130217A1000218
+:1003D0005E02F000A201882C0E0337A200025E022A
+:1003E000F000A801BC6003000B0302055EAF00072C
+:1003F0000C01BC6103001133020580BF000712012C
+:10040000BC60131157A100025E02F000A2019660C9
+:100410000E03301900B040670017A200025E02F020
+:1004200000A80283C03700000400E0021F002087FC
+:100430000182600628914403BFDE02F000040281BD
+:100440004013000002020042030007190184600209
+:10045000F597AC01BC600300108003A3DE02F00737
+:100460001C0190600209104800B0446700179E000C
+:10047000B0446B00179D00B0446F00179C00B0445F
+:100480007300179B0068DE7A23271C00E00223001C
+:1004900020880115403B00179700B001430017A1C9
+:1004A00001C9DE8405280501BC6003107795019120
+:1004B000E0020D906C0286403700072A00E002BB84
+:1004C0000020AE03BFDE02F00A8A01BC6003001404
+:1004D0008001BC600300148101B8600A049024010B
+:1004E000BC600304082B01BC600300482A01BC6007
+:1004F0000300D02A01B3600700100401BC600300B0
+:10050000080E01BC600300080F01BC600300081066
+:1005100001BC60030008110183E002F5D7AE028739
+:10052000C037000A8600025E02F0117A00025E0205
+:10053000F00F9503435E02F00736006D403300CAAA
+:10054000F700685E5F00474E00685E5F00274B0063
+:100550006800A700C740006800A701074000688046
+:10056000A700A74100E0446690283701BC62C300A1
+:1005700017A102805203000744019652030017A1FD
+:100580000080DE8690379A0203520300074900E09C
+:100590005E6A90379A0207D20300074900E85E6B53
+:1005A00000379A029E5E6B000AF703BFDE02F00777
+:1005B000530152D2030017A10185D206F4379A03E2
+:1005C000BFDE02F00753013C52030017A101BC52E9
+:1005D00006F4379A006E5E680BAAF700682FC30016
+:1005E0000753028E5207000AF70204C03B00075D62
+:1005F0000181E0060D906C02874037000A8A0002F4
+:100600005E02F0117A00025E02F00F950287C0AF21
+:100610000007550287C0AF000A86015840AF001797
+:100620009A01BC603F1E17A1006DDE6AF42A8603A2
+:100630005B5E02F0075F01BC601300104300B04135
+:100640002328104801806002F297940184E0020997
+:100650001048015840AF00102A006840AB002A86BD
+:1006600001BB5E5600900402035E5700076E020055
+:1006700047A300076B01BC621E3C11E001BC600394
+:100680000011EA00B05E6B0011EB0198601E3D1195
+:10069000E8020047B300076E00B05E6B0011EF0187
+:1006A000B0E0CE3D91EC03835E02F0077200025E83
+:1006B00002F0117A00025E02F00F95006D403304E3
+:1006C000C76E03AADE02F0078E01BC63FF1FE4863B
+:1006D00001BC601B19D06401BC600300B7A101BC60
+:1006E00063FF1FE66D00E04186F4306501BC63FFE7
+:1006F0001FF60000E05E870077A100025E02F00CAA
+:10070000AE0200C077000784012940770017A200DD
+:100710006D5E8B04C78200E85E8B04D60001BC606E
+:100720001B0FF06300E0418EC01063010C56030004
+:1007300004860068DE8701678400B05E8B00066D6A
+:10074000006DDE8701C78700E0419300306403BF7E
+:10075000DE02F0077703B05E02F0078D01836002CE
+:100760000D906C00681B3BFFE78E01BC601B0FF017
+:100770006500E04194D9D06502005A0300078E015C
+:100780008360060D906C0020402F08A79001BC608C
+:100790000300048601BC60030008020188E00F002A
+:1007A0000803006D40330208A50129520F0017937A
+:1007B0000109520F0017AA01966002F2979400E017
+:1007C000418701F06501BC600F0017A10028DE869B
+:1007D00090679C01866006F2979400E04197007054
+:1007E0006500E020AF00C82B01065E530017A20091
+:1007F000A05E4F0477A10068DE870447AA0186E067
+:1008000006F2979400B85E8B0037A200B05A03003E
+:1008100017A0020ADA030007A401876006F2979482
+:100820000284C03B0007AA0203DA030007AA03AB55
+:100830005E02F007A8020441070007AA01806005D4
+:1008400000680301065E530017A20182DE8A009051
+:100850000403AADE02F007DB03AB5E02F007C50269
+:1008600087D2130007DB00B0521300118601A5E008
+:100870000A301180018460020D906C01BC63FF1F7F
+:10088000F79900B01B430017A20068DEAB0027B742
+:1008900000A05E4FFF77A10068DE870727C303BF74
+:1008A000DE02F007B90284520F0007C30204D20F20
+:1008B0000007BC03B15E02F007C200B01B3F001787
+:1008C000A203BFDE02F007BD03B35E02F007C2025F
+:1008D0000052170007C300685E8BFFE7C300E0010A
+:1008E0005EF4506502015A470007C300B019B70013
+:1008F0001799018460060D906C020052170007DB07
+:1009000003315E02F007DB01866002301180018056
+:10091000E001620B10020052170007C90202AB4F40
+:100920000007D60068DE5F0007D600B02BB70017BF
+:10093000A100682ABB0007D600B02BB30017A200A5
+:100940006DAABAF447D60068DEAB0047D2006D2B23
+:10095000BAF427D100B02C6B000B190184E006F724
+:10096000F7BF0068DE4F0287D600025E02F0130C6C
+:100970000206DEFF0007D600E02BE7002AF9006838
+:10098000DE5F0007D90068DEAB0047D90180E005D3
+:10099000620B1000682B6F0007DB0180E006F7F7A1
+:1009A000BF0207520F000856028047A300085302F7
+:1009B0008047B300085300E020AF00882B00E820F8
+:1009C000AB00882A01BC60030011E401BC63FF1F77
+:1009D000F7A501BC600303D1E102065E530007E501
+:1009E00001BC60030491E10206DE530007E900E068
+:1009F00047870051E10207D20F0007E900E047876F
+:100A00000091E1006D403302C8A500685E4F058784
+:100A1000EC0068DEAB00485603AB5E02F007EF0265
+:100A2000005217000856020580F30007F500681908
+:100A3000B7FFE7F200B019B70017A500E05E970016
+:100A400097A50068DE97FFE7F50280521700085669
+:100A5000020700BF00085601BC601F1417A20090D7
+:100A6000478700306500E04196F4506500E0478715
+:100A700001082103835E02F007FD00025E02F0110F
+:100A80007A00025E02F00F95006D40310427F900F4
+:100A90006D40310428A501BC600B1D57A10068DE24
+:100AA00097FFE80D010F5A070017A5031EDE02F09D
+:100AB000080D0200521700080D032C5E02F00856C4
+:100AC00000685E67FFE80D00E05E6700979900E050
+:100AD0005E66F43064012A58030017990100DE971E
+:100AE0000017A500E05E66F4B79900E05E67003786
+:100AF00099011558030017A603BFDE02F0081D0078
+:100B0000E05E96F43064012A5803001799020580CC
+:100B1000F300081C0182E002F3379902005217002B
+:100B2000081C0116D8030017A6010F5A070017A4C6
+:100B3000010CD8030017A10068DE92F4281800E029
+:100B40005E6702179903BFDE02F00821010DD8038A
+:100B50000017A10068DE92F4285600E05E670417D3
+:100B60009903BFDE02F00821011058030017A60008
+:100B700068DE9B00C8210181DA030017A100B85E7E
+:100B800086C017A10281DE8700085600885E6700D4
+:100B9000778000E000AEF0106401AADE6500480234
+:100BA0000068DE9B00483B0207818700082E006D2D
+:100BB000DE030C082E0285520F00082E0298523BCD
+:100BC00000082E0181E00500680300E05E000B379D
+:100BD000A300E05E8F0097A300E041870077A200AA
+:100BE000025E02F00DE800E820AB01082A01BC60BB
+:100BF0002307978100885E970077A100E85E86F45E
+:100C0000B06301BC60070E17A100E0418EF43063B1
+:100C100000B056170017A100B0561B0017A20068BD
+:100C2000DE86D048560068DE8AD0685600025E0232
+:100C3000F00DBD01BC602307506401BC624F00177A
+:100C4000A200025E02F00E1000685E9B0048530195
+:100C5000BC621EF471E00068DE9B00C84601BC6106
+:100C60001300B7A1020600F300084201BC601300A4
+:100C7000B7A101BC60030011EE00B05E6B0011EF84
+:100C80000192E00EF431EC03BFDE02F0085300687D
+:100C90005E9B0068480068DE9B00A85301986006D0
+:100CA0003D11E800E020AF00882B00E820AB008871
+:100CB0002A01BC60030011EA0068DE5F00484E00B4
+:100CC000B05E6B0011EB0192DE5E3D11E8018760C2
+:100CD000023D11E80068DE9B00A852018760063DD6
+:100CE00011E8019860163D11E80181E00500480215
+:100CF00001AADE6500480203BFDE02F0085B01BC0A
+:100D0000620F0011E001BC60030011E40181E00109
+:100D100000680301BC600F0011E801BC6003001112
+:100D2000EC0200200F00086200E020AAF3482A002D
+:100D3000B020AF00102500E820AA04A82A006AA06D
+:100D4000AB01C86201B860060490240182E006F29B
+:100D500097940188600A00900401BC60031877959D
+:100D600003A0DE02F0086F00685E4F06A874013829
+:100D7000520300178000B05E5F0017810203DEB7E8
+:100D800000086E00685E0700086D01BC6003017713
+:100D90008001BC600300378103BFDE02F0086E01F2
+:100DA000BC600301578000025E02F000AF0068DE05
+:100DB000AB00487400A05E4F0477A100685E870016
+:100DC0004A3500685E87044A3503BFDE02F00BE94E
+:100DD0000386DE02F00A870287C037000A86000217
+:100DE0005E02F0117A00025E02F00F9503035E02CC
+:100DF000F0087403A9DE02F0088000025E02F01120
+:100E00007A00025E02F00F950207403700087A036D
+:100E100086DE02F00A870287C037000A8600025E7B
+:100E200002F00C60006E40300208AB0301DE02F0FD
+:100E300008AB0068DEAB000892032B5E02F0088668
+:100E400000E0022B00208A03BFDE02F0088A028045
+:100E5000521700088900E0024300209003BFDE0221
+:100E6000F0088A00E0025700209500685E4F040BEE
+:100E70006900685E4F028B6900685E4F0209C70017
+:100E8000685E4F048A2E00685E4F050BDA00685ECC
+:100E90004F060BDA00685E4F068BE303BFDE02F0FD
+:100EA0000BE90068DEAB0028A3032B5E02F0089676
+:100EB00000E0022F00208B03BFDE02F0089A0280C0
+:100EC000521700089900E0024700209103BFDE029C
+:100ED000F0089A00E0025B00209600685E4F06A9C9
+:100EE0009B00685E4F042C0100685E4F04AC01005B
+:100EF000685E4F05AA3B00685E4F06299B00685E4E
+:100F00004F052BD800A05E4FFF77A100685E8707D2
+:100F10002BF403BFDE02F009C000E00213002084BE
+:100F200003BFDE02F009C400E0020F00208301BC11
+:100F300060030011EC01BC600F0011E80284C03BAB
+:100F40000008560184E00609104803BFDE02F008DD
+:100F5000560200C09300000203A35E02F008AF0334
+:100F6000C35E02F008AE03BFDE02F00AF300025EC9
+:100F700002F0117A00025E02F00F950207C0AF0086
+:100F800008B3020740370008AF0107C0AF0017A140
+:100F900000B85E870037A101825E860D906C00B0BC
+:100FA000447F000804018360020910480287C037AB
+:100FB000000A860386DE02F00A8700025E02F01154
+:100FC0007A00025E02F00F9503435E02F008B80259
+:100FD00087C037000A860301DE02F008D303305EC3
+:100FE00002F008D301BC601B1F506500E04194DF94
+:100FF0003065012D406B0017A200885E8B0137A27F
+:101000000138402B001680028840270008C7018461
+:101010006006D0168000B05A02F456800205C02740
+:101020000008CA0187E006D0168001BC601B0DD7FE
+:10103000A100025E02F000A200B04067001681012C
+:10104000BC601B0DF7A100025E02F000A200B040E0
+:101050006700168200E01BE70066F900691BE701E4
+:1010600088D301BC60030006F90280200F0008D578
+:10107000006E40300209960381DE02F008DF00E0D6
+:10108000021700208503A9DE02F008DB0184E006D8
+:101090000910480180E0020910480184E002F7F7D6
+:1010A000BF0386DE02F00A87018060050048020166
+:1010B000806006F2979403BFDE02F009620183604C
+:1010C00002F7F7BF0386DE02F00A87032B5E02F009
+:1010D000090503A9DE02F008E80068DEAB00490557
+:1010E00000B0523B00179F00B0523B0017BE01BC3E
+:1010F000600300280E03BFDE02F0090502875E537D
+:1011000000091203A0DE02F008F403BFDE02F006BD
+:10111000920182E0060D906C0190600A091048006F
+:10112000B0523B00179F00B0523B0017BE019E5EBD
+:101130008300B0EB0106520F0017A100B85E8700D4
+:1011400037A10182DE86F577AB01BC6103003080F8
+:1011500000E8523AF3F7A2006BD23AF3E8F700E85E
+:101160005E7E91D7A200905E8B0097A101BC6023A8
+:1011700001D064006B523AF3E90201185E87001750
+:10118000A2010A5E870017A300886006F457A20038
+:10119000E04192F4706400B05802F45600006BDE37
+:1011A000FA91C90500B0523B0017BE03BFDE02F042
+:1011B000090500025E02F011EA00B0203B00280E93
+:1011C00000B0523B00179F0320DE02F00912020715
+:1011D0005E530009090180E00209104803BFDE02E6
+:1011E000F009120068DE5F00090F021A54070009B7
+:1011F0000D0103C0270017A101825E8610D0860171
+:1012000002C0270017A100E0422AF4308A0180E0E2
+:101210000500480203A9DE02F0091200B05E470093
+:10122000108001085E4F0017A100685E8700293614
+:1012300003AB5E02F0093A0200521700092500686C
+:10124000DEAB00491800E0025300209402865E5392
+:101250000009620284520F000AF70284D20F0009CB
+:101260001D03AC5E02F0092303BFDE02F0092E036A
+:101270002C5E02F0092E00685E4F0409230106D29D
+:101280000F0017A10080921B0197A200E0015E0DE4
+:10129000B0640181DE86C3F61F00685E4F020962FA
+:1012A00003BFDE02F00952031EDE02F0092B0331F8
+:1012B0005E02F0092B0068DEAB00492B0080921B18
+:1012C0000197A200E0015E0DB0640181E002C3F667
+:1012D0001F0068DEAB00493000E0023F00208F03B2
+:1012E000BFDE02F0093300685EAB00493302805272
+:1012F0002F0009620202410700093300685E4F04B3
+:10130000096200685E4F0289620284410700096237
+:1013100001806006F2979403BFDE02F00962032B9E
+:101320005E02F0096200685E4F05A95200685E4FD8
+:1013300005295203BFDE02F009620068DEAB0049F6
+:101340004201BC6003000ABD01826002F5D7AE0213
+:10135000805EFF00094000682B6F00094200E044F6
+:10136000655B4ADB00682B8BFFC94200E02B8B00DA
+:101370002AE202065E5300094500E002630020985D
+:1013800003BFDE02F009620323DE02F0094D0129EA
+:10139000500B0017A30068DE8F05294D0187E0027E
+:1013A0001070830184600209104800B05E87001746
+:1013B000A1006EE00300294C03D1DE02F0094D00CC
+:1013C00068DEAB00494F00E0022700208900685E1C
+:1013D0004F00096200685E4F01096200685E4F05B8
+:1013E0008962028047C70009940329DE02F0095888
+:1013F0000102DEAF0017A10106520F0017A200384C
+:101400005E86F449620182DE8AF577AB00B0522332
+:101410000011F200B052270011F300B0522B00115E
+:10142000F40106520F0017A100E05E870031F500BD
+:10143000B0005B0011F000B047C30018000134C7D2
+:10144000C70017A1006EDE8402A96201BC60030818
+:1014500010420283C1070009660301DE02F009653C
+:1014600003B55E02F0096602805E53000AF700B021
+:1014700040330017A10108A00F0017A200685E8B7F
+:1014800000696E00E840310577A10281200F000954
+:101490006E00B020AF0017A10280A00F00096E00FF
+:1014A000B05E630017A1006E5E8402099600B05E14
+:1014B000870007FA018160010048020202C01300A0
+:1014C000097400E05E840347FA0181600500480268
+:1014D0000201200F00098F01035E530017A101874D
+:1014E000DE850048020386DE02F00A8700025E0203
+:1014F000F0117A00025E02F00F9503855E02F0099A
+:1015000077018E60023D11E80107C7830017A10132
+:10151000825E850048020201A00F0009810103C715
+:10152000970017A101825E8500680300B0204B0080
+:1015300017A1018E5E850068030207C0AF000C444E
+:1015400001BC60030011EC01BC600F0011E80184D4
+:10155000600500680300B040270007FC00B0402B86
+:101560000007FD00B0406B0007FE00B0406F0007B1
+:10157000FF0184600500680300025E02F00C600158
+:10158000BC63FF1FD7A800025E02F00DAC00025E34
+:1015900002F00C4401A8600A0090040201200F0030
+:1015A00011D500A8401300500403BFDE02F005F877
+:1015B00000E002870020A103BFDE02F0099700E0EF
+:1015C000020B00208203A9DE02F00AF70184600604
+:1015D0000910480184E00609104803BFDE02F00A42
+:1015E000F7032B5E02F009B80068DE4F06A99F00E2
+:1015F000E0023B00208E03BFDE02F009A000E00203
+:101600003700208D0323DE02F009C00068DE4EF1B2
+:10161000C9C00187E002107083018460020910488C
+:1016200000B05E870017A1006EE0030029A603D179
+:10163000DE02F009A700685E4F0629B601BC600310
+:10164000000AA603295E02F009AC0203DEB300091A
+:10165000AD0191601A84F4270183E002F597AC0292
+:101660000200BF0009B50203456F0009B00185E023
+:10167000062B715B02045EB30009B50187E002101E
+:1016800070830183E00209104800025E02F0112716
+:1016900003BFDE02F009C00205500B0009C0018241
+:1016A000600609104803BFDE02F009C0028700C3CC
+:1016B0000009BD0068DE4F06A9BD0068D21300090D
+:1016C000BD01BC600300118301BC600300118200F6
+:1016D00068DE4F0629C000E0024F00209303BFDE02
+:1016E00002F009C003AB5E02F009C2020441070028
+:1016F00009C5028341070008AB03BFDE02F009C53C
+:10170000028441070008AB01806006F2979403BF92
+:10171000DE02F008AB039F5E02F009CA039EDE0200
+:10172000F00BE902035E53000BE902048143000958
+:10173000CE010001630017A10102C0270017A2001B
+:1017400038DE86F449C403AB5E02F009D0020052D1
+:10175000170009C40280522F0009D203335E02F041
+:101760000BE902181B330009F201BC601F15F0657C
+:1017700001BC60031BB7A400025E02F000E900B0E8
+:101780005E8F0017A60068DE931BA9EE0207C197C3
+:101790000009DF01385A070017A1013C5A0700175A
+:1017A000A201BC5A0AF457A2013C5A0B0017A3012C
+:1017B000BC5A0EF477A303BFDE02F009E2013C5AE3
+:1017C000030017A100B05A070017A200B05A0B007F
+:1017D00017A3006D5E870089E801BC61BF0A17A5E9
+:1017E0000068DE8AF4A9E801BC60271357A50068E9
+:1017F000DE8EF4A9E803BFDE02F00A2A00D85E8775
+:101800000037A100E14196F4306500E1C197003056
+:101810006501F041970017A200E05E8B0077A200FF
+:101820006D5E8AF4C9D500E840330097A5006E5E6E
+:1018300096004A2A00B01B2F0017A10068DE840A18
+:101840000BE9023C523F000A03013C523F0017A142
+:101850000068DE84048A2801BC600316106401BCA1
+:10186000601F16106500685E870029FF00B05A03EC
+:101870000017A20068DE8AC00A2800E04197003005
+:101880006500E0419300306400E85E870057A100E6
+:101890006A5E870029F800685E87000A0401385AEA
+:1018A000030017A1013858030017A20068DE86F470
+:1018B0004A2803BFDE02F00A040285C107000BE9D3
+:1018C00001BC601F15F06501BC600305B7A40002F0
+:1018D0005E02F000E9028000C3000A2801BC601328
+:1018E00010D7A600E0017F00B7A5006D5E96F4CA90
+:1018F0000C01BC60130957A500685E940BCA2C004C
+:10190000B0017B00106500B052270017A200B05252
+:101910002B0017A3006841940BEA170068DE8ED0F5
+:101920004A1300685E8AD02A2800E0419700B0651B
+:10193000006D4196F4CA1001BC601309506503BFE5
+:10194000DE02F00A1000E0028B0020A200B0017F4E
+:1019500000106500B0522300168000B05227001618
+:101960008100B0522B0016820080921B0197A200CA
+:10197000E0015E0DB0640203587F000A2101BC60E3
+:101980002F0037A103BFDE02F00A2201BC5202F28F
+:10199000F7A101A95E02F436830090446701168422
+:1019A000020281AB000A260068DE9305AA270184A3
+:1019B0006006D0968400B05E9700005F020781AB9E
+:1019C000000A2A01806006F2979403AB5E02F006DB
+:1019D000AA03BFDE02F008AB00E0028F0020A303E1
+:1019E000BFDE02F009C4039EDE02F00BE903AB5E2A
+:1019F00002F00A31020052170009C403335E02F0FC
+:101A00000BE901846006F2979403AB5E02F006AA2C
+:101A100003BFDE02F008AB03835E02F00A38000267
+:101A20005E02F0117A006D4033038A35006D403359
+:101A30000389C4032B5E02F00BED03BFDE02F00648
+:101A4000AA032B5E02F00A3E00E0023300208C0362
+:101A5000BFDE02F006AC00E0024B0020920103C0A2
+:101A60002700178101825E0503178100025E02F0E4
+:101A70000D9A008800230037A200E05E8800F7A2DC
+:101A800000E05E86F451890186E00630118003BFD4
+:101A9000DE02F009C003A2DE02F0008103A3DE0231
+:101AA000F00A6400E001FF00207F01BC6003001722
+:101AB000A303BFDE02F00A66018760040310A001E1
+:101AC000BC60030051E400B0479300180001BC6003
+:101AD0000302900401BC620F0011E001BC600F0121
+:101AE00031E800B047A300180001BC600F0011E806
+:101AF00001BC60030131EC00B047B300180001BC29
+:101B000060030011EC018460060910480020601E8B
+:101B1000090A5B00E001FB00207E03BFDE02F00A41
+:101B20006C01BC60030ED7A1011400630017A20072
+:101B3000E05E86F4506500E05A0300368002030040
+:101B4000C7000A6103A95E02F00A660291509F0075
+:101B50000A650191601A84F42703BFDE02F00A656A
+:101B600000E001FF00207F01BC60030037A30323D6
+:101B7000DE02F00A6C0183E0020910480184600271
+:101B8000F597AC01BC600300178E0187E00210706E
+:101B9000830182600209104803D0DE02F00A6D035F
+:101BA000D05E02F00A6E0182E00209104803D5DE21
+:101BB00002F00A7001BC60030010B401BC600300B5
+:101BC000F7A1006800A7000A740185421AF437A142
+:101BD00000025E02F000A200B040670017A501BC41
+:101BE00063FF1FF7A200025E02F000A800886007F2
+:101BF0000157A400B85E86F497A100025E02F000CF
+:101C0000A80283C21F000A7B00E044670117A102FB
+:101C1000044523000A80006B4466F42A7D00025EBE
+:101C200002F0116100685E8F0000020020E01E09D2
+:101C30000A8400B05E9700142E03BFDE02F002CCCF
+:101C400000A8412300F04803BFDE02F00002018338
+:101C5000600209104801BC6007001042006E40306D
+:101C6000020A8A00E0027700209D00025E02F01264
+:101C7000A703A35E02F008AB03C6DE02F00A8D01E3
+:101C800084E00609104803BFDE02F00AF70068206E
+:101C9000E3000A9500E844650717A101BC609F02B4
+:101CA00017A2006D5E86F44A9501BC6003000838F7
+:101CB00000025E02F00B160020E10209007C002009
+:101CC000628A090A9900025E02F0117A03BFDE02FD
+:101CD000F0007C0284452300007C03915E02F0004A
+:101CE0007C0396DE02F0007C03965E02F0007C002E
+:101CF000025E02F00B1601BC600300602000680168
+:101D000073000AAF00025E02F000D400B044670026
+:101D1000083800B001730010E401BC600300000645
+:101D200001BC600300005C01BC600301D78201D2EA
+:101D3000DE087570E000B00EB30010E100B000479F
+:101D400000108600B00ECF00108A01BC600300377F
+:101D50008100025E02F00D8D0190600A09104801B9
+:101D6000BC610300308003BFDE02F0000201BC60F2
+:101D7000030030420187E00224712300025E02F07A
+:101D8000109301BC600306778000680DEF000AB66F
+:101D900000B00DEF00178100025E02F00E440397C1
+:101DA0005E02F00B2703125E02F00AB601BC60036C
+:101DB00000402001BC618300112500B0007B0011B0
+:101DC0002701BC600702578000025E02F00E3F0050
+:101DD000B05E07000B3001BC600702778000025E36
+:101DE00002F00E3F00B05E07000B3101BC6013092A
+:101DF00097A100025E02F000A200B04067000B63F2
+:101E000001BC601309405E01BC601309405F0180A2
+:101E1000E006F5D7AE0107C1070017A101805E8675
+:101E2000F577AB01BC600F0011E801BC620F001137
+:101E3000E000025E02F00AD801BC61CF0C105C0128
+:101E4000BC600300105D01BC61CF01F05E01BC60AD
+:101E50003B0AF05F00025E02F0106301BC60030009
+:101E60000835020300C700000401BC60030006023D
+:101E700001BC600300060701BC600300060C01BC46
+:101E8000600300061103BFDE02F0000401BC6043E2
+:101E90000017BB00A04122F770480185E002F5B7AA
+:101EA000AD01BC63FF1FF05401BC63FF1FF055017F
+:101EB000BC63BF1FF05601BC63FF0FF05700025E0A
+:101EC00002F012A70187E00624712301BC60030021
+:101ED000105401BC600300105501BC600300105693
+:101EE00001BC600300105701BC600F002017010601
+:101EF000C1070017A101825E8402E01701074107B4
+:101F00000017A100B85E870037A10180DE870000BE
+:101F1000160002DE02F000000285C0370000020059
+:101F2000025E02F0117A00025E02F00F9502864016
+:101F300037000AEC00E0021B0020860386DE02F078
+:101F40000A870287C037000A870158600300102AF9
+:101F500001BC600300900400B040130017A103BF50
+:101F6000DE02F0000401B8600A04902403AA5E02B5
+:101F7000F00AFA0158600300102A01BC60030290C5
+:101F80000400B040130018000183600209104801EA
+:101F9000BC60030051E400B0479300180001BC622C
+:101FA0000F0011E00180600100680300025E02F092
+:101FB0000F9503855E02F00B0101BC620F0011E07A
+:101FC00001BC600F0131E800B047A300180001BC5C
+:101FD000600F0011E801BC60030157A100E85E87B3
+:101FE0000037A10068DE87000B0801BC6003029087
+:101FF0000400B0401300180001BC60030131EC0084
+:10200000B047B300180001BC60030011EC0324DEEC
+:1020100002F005F801866006F577AB00025E02F07B
+:102020000B160180600610308100B05E870017A19A
+:102030000180600210308103BFDE02F005F801BCB0
+:10204000610300108000B04203001800006EE0033E
+:10205000002B1903505E02F00B1C00015E02F00021
+:102060000003BFDE02F002F401846002F597AC00C9
+:10207000A8412304F048018260020910480206DEEC
+:10208000AF000B2203D5DE02F00B220350DE02F07C
+:102090000B2001BC60030010B40284C783000B2531
+:1020A00001BC600B0011E0018E6002F577AB00020D
+:1020B000DE02F0000003A2DE02F0007C02BC4287D8
+:1020C000000B2E01BC60030037A401BC60031FF7A6
+:1020D000A3011400630017A200886006F457A2034E
+:1020E000BFDE02F00B33008860070117A401BC6358
+:1020F000FF0017A3011400630017A200E05E8B012C
+:1021000017A200886006F457A201BC601311106585
+:1021100001BC601B02506401BC60030017A50020D5
+:10212000C286F48B3D00E0419706D06500E0419304
+:1021300001F06400E05E970037A500885E930037E9
+:10214000A400205E92F46B5C03BFDE02F00B36004D
+:1021500068DE92F44B4200680083006B4203A0DE0D
+:1021600002F00B420020C123160B3700025E02F082
+:102170000B16006DDE93200B58020300C7000B4CBA
+:10218000006DDE97008B4C01BC600300160801BC9B
+:10219000600300160901BC600300160A01BC60035D
+:1021A00000160B01BC600300160C01BC6003001696
+:1021B0000D01BC600300160E02005AC3000B57024B
+:1021C0003C5A9F000B5700680083006B570385DE65
+:1021D00002F0007C03855E02F0007C03A2DE02F0C8
+:1021E000007C03A3DE02F0007C0397DE02F0007C9B
+:1021F00000B041970010600191600A84F42703BF8A
+:10220000DE02F002CC01806002D616B000B05E9310
+:102210000010A101836002F7F7BF01BC600300302A
+:102220004303BFDE02F00B370068808300607C034D
+:10223000BFDE02F00AB70283C21F00000200B05ED8
+:10224000870017A103D0DE02F0051001BC60030473
+:102250001042039EDE02F0000400B05E3F00114514
+:1022600001BC600300178F00B05E4300178500B00B
+:102270005E0F00179000025E02F00B1603BFDE0235
+:10228000F00004006D40330589C503AC5E02F00B1D
+:102290006E00685E4F028BC000E002670020990369
+:1022A000BFDE02F00BC000685E4F028BC000E00290
+:1022B0005F00209701856002F5B7AD01826002F5ED
+:1022C000D7AE01BC6003000ABD039EDE02F00B82A4
+:1022D0000321DE02F00B8200E0026F00209B00026F
+:1022E0005E02F00B16018660020910480180600250
+:1022F0000910480181E00209104801BC6003021086
+:10230000420280441F000B8100B05E3F0011450176
+:10231000BC600300178F00B05E4300178500B05EFD
+:102320000F00179003BFDE02F00B8200A044B6F04E
+:102330007145028200C3000BC000B000730017A1FA
+:1023400000E05E86B017A100E15E7AF4379E00E1FE
+:10235000DE7700179D00E1DE7300179C00E0DE6F62
+:1023600000179B039EDE02F00B91006E5E6E924B97
+:10237000D6006D5E6E924B91006E5E72922BD6000F
+:102380006D5E72922B91006E5E76920BD6006D5E42
+:1023900076920B91006DDE7A91EBD6028201AB0052
+:1023A0000BA200B0446700083400B0446B0008334F
+:1023B00000B0446F00083200B04473000831006878
+:1023C000A0D2232B9100E920D2F3D79E00E9A0CE22
+:1023D000F3B79D00E9A0CAF3979C00E8A0C6F37785
+:1023E0009B00E15E7A91F7A100B05E8700111900B1
+:1023F000E1DE7692111A00E1DE7292311B00E0DE1E
+:102400006E92511C0068DE86232B9B03BFDE02F018
+:102410000BC000E9523EF3D7A100E9D242F3B7A2C4
+:1024200000E9D246F397A300E8D24AF377A40088E4
+:10243000121B0057A500E0015EF4B06400E95E865F
+:10244000C9A6D200E9DE8AC9C6D300E9DE8EC9E694
+:10245000D400E8DE92CA06D50080921B0197A50140
+:10246000BC601B11778000E05E020DB06500885AE9
+:102470000F00B7A500B05E970217A50125DA0F007F
+:1024800017A600E95E94DA57A500E8DE98DA77A689
+:10249000017ADE96F4D7A500685E96D06BC000E89E
+:1024A0005E96D077A600B05E9700168300685A1338
+:1024B000000BBA00E05A16F4D68500685A1B000BD0
+:1024C000BC00E05A1EF4D68700B05E8700164D00AF
+:1024D000B05E8B00164E00B05E8F00164F00B05EEF
+:1024E00093001650031EDE02F00BD6039F5E02F02F
+:1024F0000BD600685E4F028BD6032C5E02F00BD623
+:1025000001BC601F16B06501BC600300B7A40002E7
+:102510005E02F000E90068DE9300ABD60207C197C7
+:10252000000BCC013C5A07001788013C5A0B0017DE
+:10253000A103BFDE02F00BCE01385A070017880155
+:10254000385A0B0017A10080921B0197A200E001EE
+:102550005E0DB06400B05E230016280181DE86C3E4
+:10256000F61F0187DE86249124020680F3000BD635
+:102570000181E002C3F61F0187E00224912403AB2E
+:102580005E02F006AA03BFDE02F008AB032B5E0278
+:10259000F009C403BFDE02F006AA03AB5E02F00B33
+:1025A000DD032C5E02F009C403BFDE02F00BED0078
+:1025B000B052230011F200B052270011F300B052C4
+:1025C0002B0011F401BC60030091F500B0005B002A
+:1025D00011F003BFDE02F006AA0138523F0017A136
+:1025E00002065E53000BE60138524B0017A100684B
+:1025F000DE87008BE903AB5E02F006AA03BFDE02B2
+:10260000F008AB0068DE4F020BEC020781AB000B59
+:10261000EC01806006F2979403AB5E02F006AA021A
+:102620000000F3000BF20206DE53000BF201185E0D
+:10263000830017A10068DE8700ABF201BC600B02CB
+:102640005142020052170009C403BFDE02F008AB7A
+:1026500001BC600300118301BC6003001182032CE4
+:102660005E02F00BF90199E00620110003BFDE02C3
+:10267000F00BFD0119402F0017A100685E870009CB
+:10268000C00199DE8620110003315E02F009C0000E
+:10269000A05E3B0097A200205E4EF449C00184601A
+:1026A0000209104803BFDE02F009C0032B5E02F0EE
+:1026B00009C00068DE4F042C0600B0523300179F9B
+:1026C00000B0522F0010EB0281522F00069200E062
+:1026D00002AB0020AA0281522F0009A003295E024A
+:1026E000F00C0C0203DEB3000C0C0191601A84F4B0
+:1026F000270183E002F597AC0208522F0006AA03D7
+:10270000BFDE02F008AB01BC600300106701BC60D3
+:10271000030010460180E0060930490282C11F0013
+:102720000C1601BC602F1FF06501BC600300168011
+:1027300000E841970030650069C197000C1301BCA7
+:10274000600B00179401BC60030017AB01BC600371
+:102750000017AC01BC60030017AD01BC600300179B
+:10276000AE01BC60030017BF01BC60030020200164
+:10277000BC60030017A100025E02F000A201384015
+:1027800067000028011C406700002901BC600300AD
+:10279000504901BC60030017A701BC60030017A8E3
+:1027A00001BC60030017A901BC60030017AC01BCA9
+:1027B00060030017AD0182E0060F10780206C1E346
+:1027C000000C28006880A7000C2B03BFDE02F00C71
+:1027D0002C006880A7008C2C01BC600B1EA000019F
+:1027E000BC600300200101BC634F01A00201BC6179
+:1027F000DB06800301BC600300400401BC604309A8
+:10280000200501BC601F14106101BC601317D0606B
+:1028100001BC600300082900B05E0F00178500A00E
+:1028200044B6F07145028741D7000C3701BC600304
+:10283000000BF001BC600300107D01BC60030010C0
+:102840007C01BC606300107B01BC600300107A0156
+:10285000AC607F00107501BC63470897A10068C198
+:10286000DAF42C43011A41DF0017A10068DE87016A
+:102870006C4301BC637B15ABF003BFDE02F00A9E24
+:1028800001885E5CFF87FC01BC601F1F500701BC14
+:102890006003019008018860060090040386DE0250
+:1028A000F00A870305DE02F00C480386DE02F00A18
+:1028B000870385DE02F00C4A00B05E870017A10096
+:1028C0006EE003002C4E0386DE02F00A87006EC025
+:1028D000146F2C5101BC60070010420207C0AF000A
+:1028E00007590002DE02F0000003215E02F00C57DF
+:1028F00000E02066F4281900B0206700178B03BFA2
+:10290000DE02F00C5F028150C7000C5C011C509F7E
+:1029100000178B00E05E2EF4378B019C5E2E84F452
+:102920002703BFDE02F00C5F011E509F00178B00D3
+:10293000E05E2EF4378B019E5E2E84F4270002DECB
+:1029400002F000000107402700082800E020A30053
+:1029500028280002DE02F0000000B044670017A241
+:10296000017ADE8A2357A10090012F00B7A601BC8F
+:10297000601B11706501BC60030017A201BC601BE5
+:102980000DD06401BC601B1B906300685A03000CEF
+:10299000A8006B5E86D06C7E00B05A030017A300BF
+:1029A000E05A0EF4D58000E05A0EF4768300E85A1F
+:1029B0002F00368B0069DA2F000C7200E85A0700EE
+:1029C000368B006CDA0EF42C6D01BC60030036000F
+:1029D00001BC600B00104301BC60030026DA00203C
+:1029E0005A0B080C7901BC60030026DB03BFDE0232
+:1029F000F00C7E00205A0B140C7E01856006F5B7A2
+:102A0000AD0088009B00D1260090009B0151280159
+:102A1000BC6303001124006B5E86B00C8600685A0C
+:102A200013000C8301886006D0568200B056030064
+:102A300017A400E05E92D0968500E05A0EF4D5808F
+:102A400000205A0B080C8601BC60030006DB0068FE
+:102A50005A13000C8E006B5E86D0AC8E0188600A23
+:102A6000D0568200B056030017A400E05E92D096C4
+:102A70008501BC600300360101BC600B00104301FE
+:102A8000BC60030026DA00685A1B000CA8006B5ECD
+:102A900086D0ECA802015A0B000C9D00E85A1B00DE
+:102AA000368600B05A270017A300E05A1EF4768736
+:102AB00001BC601B1C106200E0418AF4506200B04F
+:102AC0005A2B0017A300E05402F475000202D4034D
+:102AD000000C9B00E05A1F003687012054030015AC
+:102AE0000001816002D0568203BFDE02F00CA0001C
+:102AF000B05A230017A300E05A1EF47687018160C4
+:102B000006D0568200685A1B000CA2006CDA1EF434
+:102B10002C9002015A0B000CA501BC600300360288
+:102B200003BFDE02F00CA601BC600300360301BC4B
+:102B3000600B00104301BC60030026DA00E04197FF
+:102B400001906500E05E8B0037A200E041930090A9
+:102B50006400E0418F003063006D5E8B008C6A0082
+:102B600002DE02F0000000B05A0300101F00B05A4D
+:102B70000700102000B05A0B0010210180600700F0
+:102B8000101D02804077000CB20002DE02F000004F
+:102B90000187E002F577AB03915E02F000020020AE
+:102BA000E3FE09000200025E02F00C6301BC601B40
+:102BB00011706400E041930617A20068D82F000C42
+:102BC000BC0281D80B00000200E041930190640038
+:102BD0006D4192F44CBA0287C49300000200689BD6
+:102BE0006F00000202815E53000CC90283411F0086
+:102BF0000CC30281DE53000CCF01BC6003001151F5
+:102C000001BC600300115201BC620300115301BCFE
+:102C1000600300515001896006F2979403BFDE0201
+:102C2000F000020280C54300000201F0C547001118
+:102C3000560107C5470017A101F0C54AF4315501F7
+:102C400089600AF2979401BC60030810470392DE82
+:102C500002F00D1C01BC601B11706501BC6003001B
+:102C600037A101BC63FF1FF7A201BC60030017A3DB
+:102C700001BC60030017A600685A03000D0B01BCDD
+:102C800060030017A502035A0B000CDE02805A0BEA
+:102C9000000D1C00E944080977BB00E8C40F0017C9
+:102CA000A4017ADEEEF497A400685A13000CEA033C
+:102CB000BFDE02F00CE70203DA0B000CF200B05AA0
+:102CC0000F0017A400685A07002CE300685A2F0071
+:102CD0002CE301BC60030037A500685A13000CE721
+:102CE000006CDE92D0ACE700B05A170017A401BC0C
+:102CF00060030037A5002019FAF42CEA00685A1B7B
+:102D0000000D0503BFDE02F00CED00885E87009722
+:102D1000BB002019FAF76D1C02015A0B000D1C00B4
+:102D20006CDE92D0ED0500B05A1F0017A4002019E8
+:102D3000FAF42CF101BC60030037A503BFDE02F0FA
+:102D40000D050202DA0B000D0B0204C107000D1C79
+:102D500000B05A0F0017A400E85A2F0037BB0069D3
+:102D6000DEEF000CF800E85A070037BB013C016FAA
+:102D70000017800068DE03000CFE0138016F0017A9
+:102D80008000685E03000D0100E85E030037BB03AE
+:102D9000BFDE02F00D0100E85E030037800080DE38
+:102DA00002D0378000E05EEE0DB7BB00685EEF003A
+:102DB0000D0500E05E92D017A400E85EEF0037BB7F
+:102DC00003BFDE02F00D0100685E8F000D08006B8E
+:102DD0005E92F44D0903BFDE02F00D0B01BC6003EF
+:102DE0000037A300B05E930017A200B05E970017F3
+:102DF000A600885E870037A100E04197019065003A
+:102E00006D5E87020CD500685E8F000D1C00B0441B
+:102E1000670017A5017ADE962357A500E85E8AF4BD
+:102E2000B7A400885E9300A6D700905E930166D891
+:102E300000B0012B0017A300689B63000D17006E04
+:102E40009B5EF46D1C03A65E02F00D1C00B05E9B41
+:102E50000006D900E91B5EF4681400E89B630008D3
+:102E60001503BFDE02F00D1E00681B6700000203A1
+:102E7000BFDE02F00D6F01BC610300112300692069
+:102E800057000D220180E006F2979403BFDE02F0A6
+:102E90000D240180E002F2979403BFDE02F00002ED
+:102EA00000684127000D3002844523000D2500B045
+:102EB00044670017A100E84466F437A2006D5E8BFA
+:102EC000004D270280C127000D2B0392DE02F00D7A
+:102ED0006F0392DE02F00ACA00025E02F010970051
+:102EE000025E02F00E4F00025E02F00E4A00025E29
+:102EF00002F00E5A01BC600F0011E8031EDE02F062
+:102F00000D3701BC600300105C01BC600300105D64
+:102F100001BC605304105E01BC600300105F03BF7E
+:102F2000DE02F00D3B01BC600B00105C01BC6003D5
+:102F300000105D01BC604304105E01BC6003001022
+:102F40005F01BC6003008020028500BF000D80008F
+:102F5000B0205300115100B02057001152006E20D4
+:102F6000522A8D430068A057000D4300E0205223F1
+:102F7000281603BFDE02F00D4500B04467000816B6
+:102F800001BC600300315001BC60030C90400000A4
+:102F9000DE02F000000068C103000D4A02804543D4
+:102FA000000D45006B446502CD4501BC6003001176
+:102FB0005002844543000D4B00B044670017A10048
+:102FC000685E86232D4D01BC6003004020018660B1
+:102FD0000620110000E920522A37A100E8A0562A55
+:102FE00057A200E14466F4311900E1C46AF4511AB1
+:102FF00000E1C46F00111B00E0C47300111C00B09D
+:10300000441F001800008844230157A30090442364
+:1030100000D7A400B0440B0017A100B0440F001764
+:10302000A200E95E862337A100E8DE8A2357A200CA
+:1030300069DE8B000D6500E1440AF4710200E0C412
+:103040000EF4910300E02AF7002ABD00E85E230099
+:1030500037880069DE23000D5900E8002700378813
+:1030600003BFDE02F00D59018660022011000068E6
+:10307000C103000D6F00681B67000D6F01BC60434A
+:103080000017A100E04466F4378001BC600300062D
+:10309000DA00025E02F00C63006C4466F00D6F0013
+:1030A000681B6B000D6B03BFDE02F00CCF0200DE6D
+:1030B00053000D820180E002F2979400025E02F05C
+:1030C0000E4D01BC600300104003BFDE02F00D7521
+:1030D000020080C3000D7900E044640957A100E8B4
+:1030E0005E862137A1006CC466F42D7703BFDE0233
+:1030F000F00D8200E8012A21281401BC60030008B9
+:103100001500B0205300115101BC600300115201A1
+:10311000BC600300315002804543000D7E03BFDEDA
+:1031200002F00D4F01BC600300104000B0012B0005
+:1031300011090068AAE7000D8300B0012F001109F2
+:1031400001BC61CF0C105C01BC600300105D01BCD0
+:1031500061CF01F05E01BC603B0AF05F00025E02DD
+:10316000F00E5600025E02F00E5F00025E02F00EEC
+:103170005301BC60030006D903BFDE02F00ACA0196
+:10318000885E0610D08601025E070017A101825EEC
+:103190008610D08601BC600306778000B00DEF007A
+:1031A00017810288421B000D9400B00DEB001781BF
+:1031B00000685E07000D9600025E02F00E44020BEE
+:1031C000421B000D9803BFDE02F00D99018B20A277
+:1031D00010D0860002DE02F0000000B05413001789
+:1031E000A10200DE07000DA100B0418B00106501B7
+:1031F000BC600301D7A100025E02F011A500E05EF1
+:103200008400F7A103BFDE02F00DA6020480F300E4
+:103210000DA602025E07000DA602805E07000DA645
+:103220000090001B0037A200E85412F457A10002DE
+:10323000DE02F00000020400BF000DAA00025E02E0
+:10324000F00F4E03BFDE02F00DAB00A044B6F0B1AC
+:10325000450002DE02F00000020000BF000DBC00CD
+:1032600068AC0F000DBC00E05EA30037A8006D5EE7
+:10327000A005CDBC00B02CB70017A100025E02F083
+:1032800000A200B040670017A20068DEA3FFEDB9FE
+:1032900000B05E8965D7A2006D00A7008DB8006DF3
+:1032A000A0A3004DBA03BFDE02F00DB90068A0A3D1
+:1032B000000DBA00B85E8965D7A200025E02F00078
+:1032C000A801BC60030017A80002DE02F0000000A5
+:1032D000D85A030117A201B85A06F457A200B056F3
+:1032E0000300083C00B0560700083D00B0560B0034
+:1032F000083E00B0560F00083F00B05613000840CB
+:1033000000E05612F4484100B05A0300083A013870
+:103310005E8B00083B00B021070017A401BC6003CE
+:103320000017A200B0419300106500B85E92D0175C
+:10333000A400E05E06F4506300F05E930017A30063
+:10334000F05E930077A400E05E8B0037A200B85EC9
+:1033500092F477A400E04192F4506500E05602F444
+:10336000958000B056030017A4006EDE8B00ADCA36
+:1033700000B85E92C0D7A200D85E8B0037A200E0F2
+:1033800020F2F4483C00B020F30017A400B85E928D
+:10339000C0F7A200D85E8B0037A200E020F6F44808
+:1033A0003D00D820F70037A200E020FAF4483E00A4
+:1033B000D820FB0037A200E020FEF4483F00D820D0
+:1033C000FF0037A200E02102F4484000D8210300AA
+:1033D00037A200E02106F4484100B021070017A2FF
+:1033E00000B85E8AC017A200905E8B0037A201BCB5
+:1033F0005E8907683B0002DE02F000000180600683
+:103400003C91E4018760063CD1E601A860023CD112
+:10341000E6018B60023CD1E600B05E8F00106300D5
+:10342000B056030011E700B056070011E700B05690
+:103430000B0011E700B0560F0011E701A960423CF4
+:1034400091E401A860023CD1E6018B60063CD1E624
+:1034500000B05E8B00106301BC60030057A1020442
+:103460005603000DF801BC60030117A100E0418E76
+:10347000F4306300B056030011E700B056070011A6
+:10348000E700B0560B0011E700B05E8B001063013F
+:10349000BC600300B7A10204D603000E0201BC60A9
+:1034A000030117A102065E53000E0201BC60030176
+:1034B00097A100E0418EF4306300B056030011E79D
+:1034C00000B056070011E700B0560B0011E701BC31
+:1034D00060030017A10206DE53000E0D00B05E8BE4
+:1034E00000106302065E53000E0C00A0563F01F769
+:1034F000A103BFDE02F00E0D00A0563301F7A100BC
+:10350000B05E870011E701BC60030011E70002DE36
+:1035100002F0000000685E9B00CE2A01BC6007023A
+:1035200011E30068DE9B004E1D00E847870111E1B2
+:1035300001BC60030011E201BC60030011E201BCA8
+:1035400060030011E201BC60030011E201BC6003F2
+:103550000011E201BC60030011E201BC6003001134
+:10356000E201BC60030011E200B06142F451E000EE
+:10357000B058030011E200B058070011E200B05843
+:103580000B0011E200B0580F0011E200B058130018
+:1035900011E200B058170011E200B0581B0011E210
+:1035A00000B0581F0011E200B05E9B0017A4006835
+:1035B000DE9B00AE2801BC60030077A40192DE937D
+:1035C0000217A30002DE02F0000001BC6007001138
+:1035D000E300B058030011E200B058070011E20008
+:1035E000B0580B0011E200B0580F0011E200B058C3
+:1035F000130011E200B058170011E200B0581B0090
+:1036000011E200B0581F0011E200E00146F0106422
+:1036100001BC60070031E300B058030011E200B0C4
+:1036200058070011E200B0580B0011E200B0580F2B
+:103630000011E200B058130011E200B05817001159
+:10364000E200B0581B0011E200B0581F0011E20167
+:1036500092E01B0017A30002DE02F0000002874088
+:10366000C3000E3F01866006F01030028640C300A2
+:103670000E4100B040C70017810002DE02F00000DA
+:10368000028740C3000E4400B05E0700103101867F
+:10369000E006F010300002DE02F00000006800A733
+:1036A0000112E303BFDE02F00E5E00025E02F00EC6
+:1036B0004D00025E02F00E5F0002DE02F00000002C
+:1036C0006800A70112AC0002DE02F0000001816078
+:1036D00006093049006800A7008E5200025E02F021
+:1036E0000E6F0002DE02F0000000025E02F00E6FBC
+:1036F000018160020930490002DE02F00000018809
+:10370000E00E09304900B0412700180000B0002B3E
+:103710000010020002DE02F0000001BC6003001095
+:10372000020182E0020F107801BC60030010490022
+:10373000B041270018000002DE02F000000068001F
+:10374000A7010E600280DE53000E6601BC60130705
+:1037500077A100025E02F000A2019060020337A28E
+:1037600000025E02F000A80002DE02F0000001BCD0
+:1037700060130797A100025E02F000A20190601E94
+:103780000337A200025E02F000A801BC60130777B5
+:10379000A100025E02F000A20190601E0337A200A9
+:1037A000025E02F000A80002DE02F000000100DE6E
+:1037B000530017A60181DE9A09304900B041270065
+:1037C00018000002DE02F000000002DE02F000003D
+:1037D00000B044670017A2017D5E8A2357A300B0A2
+:1037E0001C770017A100B85E84E3D7A2025A5E8B53
+:1037F000000E7C0180E006F4271E01825E86F297AF
+:103800009400B05E8F00071B02001C7B000EC300FB
+:10381000E85E8CE377A2006D5E88E38EC300E0442F
+:10382000670287210285C523000EC00020E3FE0940
+:103830000EC001BC60130997A100025E02F000A255
+:103840000068C067000EC001BC60131617A100021B
+:103850005E02F000A20068C067000EC001BC6013E9
+:1038600009D7A100025E02F000A20068C067000E46
+:10387000C001BC63FF1FF7A10068DE862C2EC002CA
+:10388000009C7B000EB40180E000E3C71E01BC6019
+:10389000230F57A100025E02F000A200B0406700B3
+:1038A00077A400B05E930017A200025E02F000A8A9
+:1038B00001BC601B1B57A100025E02F000A2018147
+:1038C000E0060337A20186E006F457A200025E027A
+:1038D000F000A801BC601714D7A101BC600300B7B9
+:1038E000A200025E02F000A801BC60171457A101FB
+:1038F000BC60031877A200025E02F000A801BC6061
+:103900001714B7A101BC600300F7A200025E02F029
+:1039100000A801BC60171077A101BC600F0417A2BA
+:1039200000025E02F000A801BC60171097A101BC64
+:1039300060030017A200025E02F000A801BC60173D
+:1039400010B7A101BC600B0017A200025E02F000DC
+:10395000A801BC601710D7A101BC60030017A2002A
+:10396000025E02F000A801BC60171017A101BC6044
+:103970000B0037A200025E02F000A801BC60230F1A
+:1039800057A100A85E930077A200025E02F000A893
+:1039900001BC60171017A100025E02F000A2020035
+:1039A0004067000EB9006CC464E42E8003BFDE02E1
+:1039B000F00EC001BC60171277A100025E02F00099
+:1039C000A20068C0671FEEC001806000E3C71E014F
+:1039D000BC600300904301806000E3C71E01826069
+:1039E00002F297940180E004E3C71E01BC6003006B
+:1039F000071A03BFDE02F00EC30002DE02F0000071
+:103A00000201C11F000ED602855EAF000EC90185FE
+:103A10006006F577AB00B0446700082500B0446B42
+:103A200000082600E9446504B7A100E8C46904D78A
+:103A3000A200D05E870077A101E1DE8AF437A20000
+:103A4000E95E862697A100E8DE8A26B7A200695EB5
+:103A50008B000ED601BC610300113300E144DAF49F
+:103A6000313600E144DEF4513701856002F577AB71
+:103A700001BC600301104701BC6003005043000219
+:103A8000DE02F0000000B0451F00178100B005B74E
+:103A90000017A601BC600704106401BC601311107C
+:103AA0006501BC60030017A10205DEAF000EEF0048
+:103AB000B0580F00178000685E842C2EF702005E5D
+:103AC0009B000EEF0280DA03000EE50118581F007C
+:103AD000178200E05E0B00378201985E0AC0F6078D
+:103AE00003BFDE02F00EE8011A581F00178200E043
+:103AF0005E0B003782019A5E0AC0F60701F0DE0312
+:103B000000378000A05E02C0578000B05E03001640
+:103B10000300A044B6F0178200B05E0B001605004B
+:103B2000E05E0AC0960603BFDE02F00EF700B05852
+:103B30001300178200E85E06F057A5006ADE9700C2
+:103B40000EF500E85816F4B6050069D817000EF512
+:103B500001BC600300160500B058170017A500E06F
+:103B60005812F4B60600E0419302106400E0419759
+:103B700006D06500E05E870037A100905E9B0037AD
+:103B8000A60068DE87008EDC01BC600300114701DF
+:103B9000BC600300016D0002DE02F0000001BC60A9
+:103BA0000300016C01BC600300016D01BC60070AE9
+:103BB000106401BC60030077A100B0428F00178041
+:103BC00000A05E0301F78000B05E0300016E01BC3F
+:103BD00063FF1FF7A20068DE03000F0901BC60034A
+:103BE0000017A200886006F43781002005BAF02F84
+:103BF0000E0068DE8AC0CF0E00E005B300216C0025
+:103C0000B005B6F0216D00685E03000F1200205E63
+:103C100006F00F18006EDE8AC0CF1803BFDE02F078
+:103C20000F13006DDE8AC0CF1800B05E870017A3A7
+:103C300000B0419300016600B0581B0017A201BC00
+:103C4000600300016C01BC600300016D00E841935A
+:103C500002106400E85E870037A10069DE87000F6C
+:103C60000900B05E8F0001650002DE02F000000076
+:103C7000B0059B001064006E581B002F2100E05817
+:103C80001B00314503BFDE02F00F2200B0581B00BD
+:103C9000114500B0059B00016200B005970001616D
+:103CA00000B0580F00178500B0580700178300B008
+:103CB000580B0017840118581F00178C011A581F41
+:103CC00000178D0002DE02F0000000B0059700171B
+:103CD0008000685E002C2F4D01BC600300111201B2
+:103CE000BC600300111500B0059B00106402004584
+:103CF00023000F3700B0451F00178100E80592F040
+:103D00003780006ADE03000F3500B05E0300114506
+:103D100003BFDE02F00F3801BC600300314503BF72
+:103D2000DE02F00F3800B0059300114500B00583A6
+:103D300000016900B0058B00016A00B0058F000129
+:103D40006B00B0058700016800B005AB001065028C
+:103D5000845A1F000F4100B05E1700168301985E61
+:103D600032D0F687019A5E36D0F68701846002D0A1
+:103D7000F68700B0059300016000B0059B0001626A
+:103D800000B0059F00016300B0059700016100B01D
+:103D9000058B00106400B0580F00178500B058075D
+:103DA00000178300B0580B0017840198581EF19734
+:103DB0008C019A581EF1B78D03BFDE02F00F4D0043
+:103DC00002DE02F0000000B0058B001064006E41BE
+:103DD000932A0F5B00A044B6F0B7A100B05E870045
+:103DE000160500E05812F4360600B0581B001145C5
+:103DF000020000F3000F58006D4193280F58020095
+:103E0000DEAF000F5801BC600B02514200B05E876C
+:103E100000016F02015EAF000F5B00B05E1700167D
+:103E20000301816002F577AB0002DE02F0000002C0
+:103E3000014523000F660287C493000F660182606C
+:103E400002F5D7AE02012C43000F6300E02C4B00BB
+:103E50002B1201816001620B1002055EB7000F6634
+:103E600000E02AF7002ABD01856002F5B7AD000227
+:103E7000DE02F00000020200BF000F7400025E02CA
+:103E8000F00F960202DEB3000F6C0020428F000C90
+:103E9000B403BFDE02F00002028881AB000F74029F
+:103EA000845EFF000F6A02845EB3000F6A0282DE46
+:103EB000FF000F6A02822B4F000F7200682ABB00BE
+:103EC0000F740284DEAF000F6A02835EB7000F6AD0
+:103ED00000B05E870017A10002DE02F00000018240
+:103EE000E002F597AC0203DEFF000F7E028445235B
+:103EF000000F7E02012B4F000F7E0180E006F2973B
+:103F00009400025E02F00E6F0180E002F2979400CE
+:103F1000025E02F00E6F0180E002F29794028400CC
+:103F2000C7000E4803BFDE02F00E4A020400C700BD
+:103F30000F880284C56F000F9402844523000F850B
+:103F400002004203000F9400685E4B04AF940068C7
+:103F50005E4B06AF9400685E4B062F940182E0062C
+:103F6000F597AC02844523000F8B0323DE02F00F8C
+:103F70008C0183E006F597AC0180E006F29794028D
+:103F80008400C7000E4800B02AF70017A2006DDEBB
+:103F900089560E4802872B4F000E4A02005EFF0032
+:103FA0000E480287AB4F000E4A03BFDE02F00E48F8
+:103FB0000002DE02F00000020200BF0013000068F1
+:103FC0002B0B000F9B00E844655857A101BC63F719
+:103FD0001D17A2006D5E86F44F9B00E84466F44A0C
+:103FE000C2006CC465576F9D00E84467002ABB029D
+:103FF00080456F000FD10203DEB70010580183E047
+:1040000002F5B7AD0202DEB3000FA3018360062BF9
+:10401000915C00025E02F00F7602835EBB000FA689
+:1040200000E845895BF7A1006E5E8555AFBE0204CE
+:10403000DEB7000FBA00E02BB7002AED01BC600329
+:10404000000AEF00682C67000FAB00E82C67002B1C
+:104050001900B02BB70017A201856002F5B7AD02B9
+:1040600004DEFF000FB0006D5E895DCFB00184E01B
+:1040700002F7F7BF0206DEFF000FBA00E02BE702EF
+:104080000AF900B04467000B0401182BE70017A1E0
+:10409000011A2BE70017A2006E5E87000FB8006DB3
+:1040A000DE895F4FB803BFDE02F00FBA01BC6003C8
+:1040B000000AF90186E002F7F7BF02025EFF001076
+:1040C000580068AB0B00105800B02AE7000AC20085
+:1040D00002DE02F000000182E002F7F7BF02025E9A
+:1040E000FF000FC8020600C7000FC102025EFF00FA
+:1040F0000FC800E845895BF7A1006DDE85614FC6FA
+:1041000000E844656177A1006D5E85618FC800B0ED
+:104110004467000AC20002DE02F000000204DEB7BB
+:10412000000FD000E8446556CABE00682C67000F37
+:10413000CC00E82C67002B1900E02BBF002AEF0011
+:10414000B02BC30017A1006D2BBEF42FD001BC60B3
+:1041500003000AED0002DE02F000000203DEB700F9
+:104160000FD80282DEB30010580203C57300104A54
+:1041700000E844655737A1006D5E8556B05801834D
+:104180006006F5D7AE03BFDE02F0105801BC600335
+:10419000000ADF006D45871F4FDB00B04587000A2E
+:1041A000DF00E044655BF7BB00E85EEE2C2AB90156
+:1041B000836002F5D7AE0183E006F5B7AD0184E078
+:1041C00002F5B7AD01826002F7F7BF01846002F526
+:1041D000B7AD0101456F0017A101875E86F577AB8A
+:1041E00001BC6003000B0D00025E02F0130100E849
+:1041F00044655737A1006D5E855ECFE6006D5E8534
+:1042000056AFEA00E02B83002AE000B02AB3001783
+:10421000B3020680C7000FED02075EAF000FF00289
+:104220000680C7000FF20184600561AB0D03BFDE9D
+:1042300002F00FF201826006F7F7BF00B02AE70034
+:104240000AC10200C56F000FF601846006F5B7AD24
+:10425000020480C3000FF60184E00561AB0D020289
+:10426000DEBB000FFC0284DEFF000FF90206DEFF5A
+:10427000000FFC00B02BB70017A1006DDE855DCFED
+:10428000FC0182E00561AB0D00E05ECD55B7B301E6
+:10429000826002F5D7AE00B02C4B0017A100B02A07
+:1042A000F70017A2006D5E8956100302855EB70005
+:1042B000100C03BFDE02F01005006D5E8560F00E8D
+:1042C00002812C4300100C00B0440B0017A300B077
+:1042D000440F0017A200E95E8E2337A300E8DE8AB0
+:1042E0002357A200695E8B00100E0068DE8B001061
+:1042F0000E006E5E8EF6700E01826006F5D7AE007F
+:10430000025E02F0114902045EB70010230206802B
+:10431000C700101102075EAF00102300682ADB00FF
+:10432000101C00E8446556D7A201BC60371597A35E
+:10433000006D5E8AF47023006E5E895D90230184B7
+:10434000E006F5B7AD00685E8B00101C00B05E8B18
+:10435000000AAE0182E006F5D7AE006E5E896110FC
+:104360001C0182600561AB0D00E844655737A10070
+:10437000B044670017A300E85E8EF42AB60068AB6D
+:104380001708902200B02BCB0017A200E82ADAF41D
+:104390004AB601846002F7F7BF0282DEB30010580C
+:1043A0000203C57300104A00B02ACB0017A200B068
+:1043B0002AD30017A300685E8F00102D00682B0B16
+:1043C00000102D00E844655857A100E05E8EF457B8
+:1043D000A2006D5E86F4502D0181600561AB0D0277
+:1043E00081AB4F00103202005EFF00103202044524
+:1043F0002300103203A0DE02F010320183E00561D9
+:10440000AB0D0281AC4700104702862C37001058D4
+:104410000286AC37001058028080BF00105802821C
+:104420005EBB00105802822BF30010470281AC37AC
+:104430000010470280AC3700104702812C37001073
+:104440004702822C37001047028881AB00104702D8
+:1044500082AC3700104002842C370010470284AC35
+:10446000370010470283AC3700104702835EB70065
+:1044700010460204DEAF0010460281DEBB0010468B
+:104480000184E002F577AB00025E02F0113303BF56
+:10449000DE02F010580183E0022B915C020701ABB1
+:1044A00000104A0180E00209D04E00E84465573709
+:1044B000A1006D5E8555B058028101AB001050021D
+:1044C0000081AB00105202842C370010520280ACE5
+:1044D00037001052018360022B915C03BFDE02F0B3
+:1044E0001058018360022B915C00025E02F00F8184
+:1044F00002835EB70010580184E006F577AB00E058
+:104500002B47002AD103BFDE02F0111B0002DE029E
+:10451000F000000184E002F5B7AD01836002F5D739
+:10452000AE0182E002F5D7AE0182E002F7F7BF01EB
+:1045300084E002F7F7BF01BC6003000ADB01BC6046
+:1045400003000AD001BC6003000AC8018760016053
+:104550006B030002DE02F00000020200BF001089BF
+:104560000283DEFF0010920183E006F7F7BF01BC73
+:10457000600302115D00B02AB700115E018560067C
+:104580000B705B018560060BF05F0280456B0010CD
+:104590006D018B60022B915C0188600E2B515A00DB
+:1045A000682ADB00107001846006F7F7BF01BC6069
+:1045B00003000AB600025E02F0105900E844696088
+:1045C000D7A1006EDE8700307A00B02BF7000AF822
+:1045D00001BC6003000AF700682B0B00107A00B0E2
+:1045E0004467000AC100E84465564AC200B02AD3B5
+:1045F0000017A100E82B0AF42AC2028080BF001035
+:10460000800281DEBB0010840200456F0010800232
+:1046100083C57300108001BC63FF1FF7A10068C54C
+:1046200086F43084018B600E2B915C0183E002F5EF
+:10463000B7AD0184E002F577AB03BFDE02F01126CF
+:10464000018360022B915C00025E02F00F81018306
+:10465000E006F5B7AD0184E006F577AB03BFDE02F7
+:10466000F01126018D60020BF05F0188600E2B5166
+:104670005A028181AB00108E018B60062B915C0386
+:10468000BFDE02F0108F018B60022B915C0183E092
+:1046900002F5B7AD0184E002F577AB00025E02F0EF
+:1046A00010590002DE02F0000000B0446B000B065F
+:1046B0000202DEB3001097018360062B915C0002BA
+:1046C0005E02F00F76020200BF00109F0183E0023D
+:1046D000F7F7BF0203C57300109D020080BF0010F2
+:1046E0009D018B600E2B915C03BFDE02F0109E01DA
+:1046F0008B60022B915C0182E002F597AC0002DE38
+:1047000002F0000001BC600300701001BC63FF1FD9
+:10471000F0C501BC63FF1FF0CB00B040470010E5BF
+:1047200000B040470010EB01BC600300901001BCDA
+:1047300063FF1FF0C601BC63FF1FF0CC00B0404711
+:104740000010E600B040470010EC01BC600300B070
+:104750001001BC63FF1FF0C701BC63FF1FF0CD0059
+:10476000B040470010E700B040470010ED01BC60CA
+:104770000300101000B0404300180001BC63FF1F8D
+:10478000F0C800B040470010E801BC6003003010E2
+:1047900000B0404300180001BC63FF1FF0C900B027
+:1047A00040470010E901BC600300501000B04043D6
+:1047B00000180001BC63FF1FF0CA00B040470010A2
+:1047C000EA0002DE02F0000001BC60030037A20034
+:1047D00020E3FE0910FA0020E0420D90FA02804228
+:1047E000030010FA028445230010FA03915E02F0E0
+:1047F00010FA0068AB6F0010FA0282DEFF0010FAB8
+:1048000002805EFF00112F020180C7001126028284
+:10481000DEB30010FA020480C70010E700685E8B68
+:104820000010D300B02BA30017A1006EAB8AF430A8
+:10483000D30203C5730010E700682ABB0010D20042
+:10484000682ADB0010D300E8446556D7A100E82AA7
+:10485000BAF437A1006ADE8555F0E7006ADE855BB1
+:1048600050E700682B070010E70203DE530010D664
+:1048700000B02BA7000AAF03BFDE02F0112601BC77
+:10488000600302579201BC63FF1FF0C301BC6003C9
+:104890000910E301865E8A1C70E3018460061C70C7
+:1048A000E300682B0F0010DD0185E0061C70E301BA
+:1048B000BC600303978200025E02F0110401BC6336
+:1048C000FF1FF0C400B054130010E400E043915CFB
+:1048D00030E400025E02F010A001BC60030010EEA4
+:1048E00001BC63FF1FF0CE00E02B0F002AC303BF03
+:1048F000DE02F010F402835EB70010FA00025E02DE
+:10490000F000D400B05ECF0010E400682ABB0010B5
+:10491000F100B02AFB0010E40280456F0010F100A6
+:10492000E8446556D7A100E82ABAF437A100695EC9
+:10493000870010F100E05E8557D0E401BC60030100
+:10494000D78200025E02F0110403BFDE02F010F411
+:1049500000B0004700108600025E02F011980002CD
+:104960005E02F00D8D0190600A0910480184600616
+:10497000F597AC01BC61330070800002DE02F000EC
+:104980000002805EFF0010FF0281DEBB0010FF020C
+:104990000180C7001126020480C700112601806033
+:1049A00002F7F7BF0280C28F0011270201DEBB00B1
+:1049B000112701BC60030017A203BFDE02F010BD87
+:1049C00001BC63FF1FF0C001BC63FF1FF0C1028583
+:1049D000DEFF00111400685E4B06310D00B02B574E
+:1049E0000017A1006DAB0EF4311401BC6003013758
+:1049F0008000B02B5B0017A1006D2B0EF4310F026D
+:104A0000812BF300110F01BC600301778001BC60B2
+:104A10000300378100025E02F000AF01D2DE0AA07F
+:104A200030E000B0540B0010E103BFDE02F0111AB9
+:104A30000280ABF300110D01BC600301578001BC83
+:104A4000600300178100025E02F000AF00B054075F
+:104A50000010E000885E0B0070E10002DE02F00052
+:104A60000000682B130011260204DEAF001126009F
+:104A7000E844655897A4006E5E9155F12600885E63
+:104A8000930037A4006D5E9155F12600025E02F09E
+:104A9000115603BFDE02F0113300E844655897A4B5
+:104AA00000885E930037A400025E02F0115603BF37
+:104AB000DE02F011330284DEAF00112A0181E00230
+:104AC000F5D7AE03BFDE02F0113300682B8700116B
+:104AD0002F00E044655C2ADB00682B8B00112E0060
+:104AE000E044655B4ADB0002DE02F000000180600A
+:104AF00006F7F7BF00682B1300113300E844655830
+:104B000097A400025E02F0115601846002F597AC92
+:104B100001BC6003000AC401BC6003000ADB01BCE5
+:104B20006003000AC30104DEAF0017A101835E86A3
+:104B3000F5B7AD0284DEAF00113C018060060D9038
+:104B40006C0002DE02F00000028600C700113E0287
+:104B5000025EFF00114400B02AAF0017A302040058
+:104B6000C300114100B02ACF0017A30202DEBB0030
+:104B7000114300B02AAB0017A300E04466F46ABBFF
+:104B800000B04467000B0B0183E0022B915C02072D
+:104B900001AB0011480180E00209D04E0002DE02A4
+:104BA000F000000202DEB300114C018360062B917D
+:104BB0005C00025E02F00F760203C5730011510221
+:104BC00084DEAF0011510281DEBB00115102805E14
+:104BD000FF00115102035EB7001155018B600E2BCF
+:104BE000915C01836006F5B7AD0184E002F577AB17
+:104BF00001BC6003000AC30002DE02F0000000688E
+:104C00002B7B00115800B02B7B0017A4006D5E9128
+:104C100056515A00B02ACB0017A400882B27003722
+:104C2000A500E82B2AF4AACA00885E930037A400E6
+:104C3000E02B2AF48ACA00902B2B00AAC900B02BC3
+:104C400027000AAF0002DE02F000000286410700E2
+:104C5000116101BC60130917A100025E02F000A2FD
+:104C6000018760060337A200025E02F000A800B0D0
+:104C70005E870017A100B05E870017A100B05E87B5
+:104C80000017A101876002F457A200025E02F00043
+:104C9000A801BC60130957A100025E02F000A20146
+:104CA0008060060337A200025E02F000A800E00266
+:104CB000B30020AC01806002F457A200025E02F053
+:104CC00000A801BC60270857A100025E02F000A204
+:104CD0000068C06701F17901BC60030017A20002FF
+:104CE0005E02F000A801BC600301F7A200025E02B0
+:104CF000F000A80002DE02F0000003905E02F01156
+:104D00008D03875E02F0118D0390DE02F0118D029B
+:104D10000445230011840283C21F00118D0068A086
+:104D2000B700118100B0446700082D00E844650514
+:104D3000B7A1006E5E877D118803BFDE02F0118E81
+:104D40000286C03700118D00E0446700D7A102063B
+:104D5000403700118D006CC466F4318600025E029B
+:104D6000F00B1600025E02F0116101BC6003000846
+:104D70002D00025E02F00AD803BFDE02F00004013B
+:104D8000BC600300082D0002DE02F0000002804239
+:104D900003001197028545230011960285DEB700B6
+:104DA00011940185E006F5B7AD00E0446B002B21BE
+:104DB000006CC46964319700025E02F011610185E4
+:104DC000E002F5B7AD0002DE02F00000010C814305
+:104DD0000017A101BC600300508A00685E07001143
+:104DE0009C00685E8700119C00685E070011A401AA
+:104DF00090422AA1308A00685E070031A4019042E7
+:104E00002AA0108A0109DE030017A2018F5E8A1111
+:104E1000508A00685E8B0011A40191E00E11508A47
+:104E20000002DE02F000000109DE030017A400E02A
+:104E30005A06F497A500905E96F497A50203DE0348
+:104E40000011AC0282DE030011AC01BC61EF085717
+:104E5000A60080DE96F4D7A50116DE870017A30012
+:104E6000885E870077A100E15E8702D7A100E0DEBF
+:104E70008F0017A301BC60030017A2020E5E03009F
+:104E800011B301BC60030037A200905E96F457A5F1
+:104E90000080DE96F437A100E141B7FFF7A600E1FC
+:104EA000DE8701F7A10080DE96F477A300E1DE86BD
+:104EB0000DB7A100E0DE8F0017A3017A5E86F477BC
+:104EC000A100885E86F457A100B05E870017A20299
+:104ED00087DE030011C000885E870057A103BFDE94
+:104EE00002F011CD02875E030011C701BC639B0C69
+:104EF000D7A50080DE86F4B7A100E141B7FFF7A592
+:104F000000E0DE870017A100885E870057A103BF7D
+:104F1000DE02F011CD00885E870057A101BC639BC3
+:104F20000CF7A50080DE86F4B7A101BC6203001770
+:104F3000A500E141B6F4B7A500E0DE870017A100A7
+:104F4000E05E8400D7A10002DE02F0000002002033
+:104F50000F0000040282DE530011D50188600204B4
+:104F6000902400E020AEF3082B00E820AAF3082AE2
+:104F700003BFDE02F0096201B8601604902401BC90
+:104F8000600301D02503055E02F011E70287C037F8
+:104F9000000A860386DE02F00A8700025E02F00F36
+:104FA0009500025E02F0117A035CDE02F011D70078
+:104FB000D8409B0117A100E05E8702379800A85EE9
+:104FC000630077980102DE530017A10182E002F22C
+:104FD00097940188DE85006803006EA0AAF311E7AC
+:104FE00000E85E6301D02501B8600604902403BF89
+:104FF000DE02F000020181600500680301B8600A6A
+:1050000004902403BFDE02F0000202285E87001134
+:10501000FD00B041930017A400E0419300706401CB
+:105020000A5E870017A200E84192F4506301185EFF
+:10503000870017A100E86042F437A200885602F406
+:1050400036000068418EF491F900E8418F0030632A
+:1050500000E8419300306400685E8B0211F100901B
+:105060005602F457A300B05806F4760103BFDE02DF
+:10507000F011F100684192F491FD00E84193003095
+:105080006401BC600300160003BFDE02F011F900EA
+:10509000B05E870017A10002DE02F0000001806010
+:1050A0000286143000B050CB0010650138508300E8
+:1050B00017A10068DE3B06320500E05A3300368C4B
+:1050C000006EDA32F4200400B05A0B0017A200E0A0
+:1050D00001F700207D00E001D2F4407401BC63FFC1
+:1050E0001FF7A300B050CF001064006EDA32F43224
+:1050F0000C00B05A370017A300B0581300178201F4
+:10510000BC600300160401BC601B09D7B60102D0C5
+:10511000C70017A100E04196F4306500E050CB00D5
+:10512000D06401BC60030017B401BC6003001780A9
+:1051300001BC6003003781018760040310A0009068
+:1051400052330097A400E0418701B7B500685ED2F2
+:10515000F0523300E05EDAF690630020D802F032BD
+:1051600027020250C700122D009056030097A1009D
+:10517000E85E86F497A1019E6002F437A1006DDE1F
+:105180008708122D010A5E870017A201DA6002F477
+:1051900037A100E05ED6F4506300886006F437A1C2
+:1051A00000205602F4322D00B05802F0360000E024
+:1051B0005A2B00368A006ADED2F472290068DED2E9
+:1051C000F0122E00E05E0300378000685E030032BC
+:1051D0002E0186E0040310A003BFDE02F0122E00B1
+:1051E0006ADED2F4722900E05ED30037B400D05EEC
+:1051F0000700378102985ED300121800E041930047
+:10520000306403BFDE02F0121800685E0300000481
+:1052100003BFDE02F005AB0282D0C700123D00B032
+:105220002A4F0017A101B82A4AF43684010250130C
+:10523000001685013C50830017A100B050A700174D
+:10524000A4006D5A32F432460182E00686343102FF
+:1052500088502B00124200B05A330017A1019E5E05
+:105260008684F427018360068634310002DE02F072
+:10527000000000B050730017A101B8506EF43684DE
+:105280000106D00700168500B050AB0017A400D06F
+:105290006006C0978000E0419700D7B5010A581317
+:1052A0000017A100E05ED6F437B500B0580F00102B
+:1052B00063011656030017810068D81300125B01C2
+:1052C0001400630017A10068DE87001251008801F6
+:1052D0003B01168003BFDE02F012560068DE870035
+:1052E000725400A0013BE0168003BFDE02F01256AC
+:1052F00000E05E870970620088540301168000E8B0
+:105300005A0330168001BC600300168101BC6003A3
+:1053100000168201BC600300168303BFDE02F01298
+:105320006000E0418EC09063006EC18EC0326000AC
+:10533000E8418EC0306300E858030037A100E04127
+:105340008EF43063013850A30017A500685813038A
+:10535000F27B0068418EC0527B006DDA0AF4B27BAA
+:10536000011656030017A10068DE86F0327B015853
+:1053700056030017A100E05E870DD7A200B05ED7EC
+:105380000010620020DE02A0127200E05E86D037BC
+:10539000A300E05E8ED077A3006D5A02F4527B002A
+:1053A0006E5E8EF4927B00E86002F4368300B05E9D
+:1053B0008F00168100A05A0F00768300E05A0B0080
+:1053C000368200E85A02F4568000D05E030037802F
+:1053D00000E0581300360400E0418F00306302986B
+:1053E000581300127800E05ED70037B5006EC18E0A
+:1053F000C0326100B0580300106303BFDE02F01238
+:105400006100B058130017A10068DA3700127E005F
+:10541000B05E8700168D006DDE86D1B28000B05E72
+:105420008700168D0002DE02F0000001BC60030060
+:1054300017A1018760040310A001BC60030990B5A7
+:1054400000B0006300F0B401BC60570490B601BC2A
+:1054500060030090B500B0006300B0B400B042D368
+:105460000018000317DE02F012890397DE02F01223
+:105470008A00B02A4B00142F018EE00C0310A0000C
+:105480006DDE02D1B29000E85A36F0168D03BFDE11
+:1054900002F0129201BC600300168C01BC60030094
+:1054A000168D006E5A3AF0129501BC600300168EFC
+:1054B00003BFDE02F0129600E85A3AF0168E00B0F2
+:1054C00058070017A100E0580EF01603006ED80E22
+:1054D000F4329C00E85E86C017A100E8580EF4364E
+:1054E0000300E8580F00360301185E030017A100FF
+:1054F0006DDE030212A400E86042F437A200905A65
+:105500001AF4368600885A1EF457A200905A1EF4E8
+:10551000368700B05A1AF4568603BFDE02F012A690
+:1055200000905A1EF4368601BC6003001687000204
+:10553000DE02F000000158600300102A01B8600A82
+:1055400004902401BC60030290040189E0020D90E4
+:105550006C0002DE02F000000200DE530012D101F6
+:10556000BC601309B7A100025E02F000A201A560B1
+:10557000020337A20199E002F457A200025E02F092
+:1055800000A801BC60130997A100025E02F000A20E
+:1055900001A4607E0337A20199E03EF457A2000205
+:1055A0005E02F000A801BC601316F7A100025E02C3
+:1055B000F000A201B460020337A200025E02F00014
+:1055C000A801BC60131637A100025E02F000A20120
+:1055D00086E0020337A201856002F457A200025E52
+:1055E00002F000A801BC60131617A100025E02F0D1
+:1055F00000A20181E0060337A20185E006F457A26C
+:1056000001836006F457A200025E02F000A801BC0C
+:1056100060131F57A100025E02F000A20181E002A8
+:105620000337A2028600C70012CB0181E0060337D0
+:10563000A200025E02F000A801BC60131F37A100A7
+:10564000025E02F000A20181E0060337A200025EC2
+:1056500002F000A80002DE02F0000001BC601309A5
+:1056600097A100025E02F000A201A460020337A22B
+:105670000199E002F457A201886002F457A20002E7
+:105680005E02F000A801BC60131617A100025E02C2
+:10569000F000A20181E0020337A20185E002F45785
+:1056A000A201836002F457A200025E02F000A80289
+:1056B0000600C70012E201BC60131F37A100025EA2
+:1056C00002F000A20181E0020337A200025E02F0B4
+:1056D00000A80002DE02F000000200DE530012D13A
+:1056E00001BC601309B7A100025E02F000A20187AD
+:1056F00060020337A20181E002F457A2018860062C
+:10570000F457A200025E02F000A801BC60130997E2
+:10571000A100025E02F000A2020400C70012EF0125
+:1057200088600E0337A203BFDE02F012F10186602B
+:10573000060337A20181E006F457A200025E02F0E0
+:1057400000A803BFDE02F012C60068DE930012F765
+:1057500000E05E030057A201095E8B0017A103BFA2
+:10576000DE02F012FF0068DE930032FB01105E03E0
+:105770000017A200E05E8B0097A103BFDE02F012CB
+:10578000FF01305E030017A200E05E8B0197A100CD
+:105790006D5E870592FF01BC60030597A10002DEE4
+:1057A00002F000000200456F00130B02872C0F006F
+:1057B000130B01BC60130217A100025E02F000A2ED
+:1057C0000200C06700130B0287AC0F00130801082A
+:1057D0004067000B030187E005606B0301886006EA
+:1057E0000337A200025E02F000A801876005606B2B
+:1057F000030002DE02F0000000682BEB0013110032
+:10580000B02C130017A100E05E8560B7A1006BDE2D
+:10581000862333110186E006F7F7BF0002DE02F0AF
+:10582000000000B05E8F00106400B05E870017A318
+:1058300000B05E8B00106500B05A030017A100682D
+:10584000419300131A00025E02F000A200B040670C
+:1058500000160100E0419300506400B05A070017A1
+:10586000A200025E02F000A800E04197005065002F
+:10587000E85E8F0037A30068DE8F0013150002DE9C
+:1058800002F0000000B05E8F00106400B05E870080
+:1058900017A300B05E8B00106500B05A030017809C
+:1058A0000068419300132800025E02F00E3F00B032
+:1058B0005E0700160100E0419300506400B05A07F3
+:1058C00000178100025E02F00E4400E04197005094
+:1058D0006500E85E8F0037A30068DE8F00132300A9
+:1058E00002DE02F00000020200BF0001880203C5D0
+:1058F000730001B1000000000000000057860000A6
+:10590000A5C1E142055AC359DC0175513E5B2349EB
+:105910004728676945005E55F8F5C97D420AB30915
+:1059200001BD32080100343333363261322D726FDB
+:105930006D6C2F7364696F2D672D706E6F2D706B9A
+:105940007466696C7465722D6B656570616C6976DF
+:10595000652D776170692D776D652D7032702056D9
+:10596000657273696F6E3A20352E39302E313935B4
+:105970002E3839204352433A20626431653365350D
+:105980006120446174653A204D6F6E2032303133AE
+:105990002D30342D32322031373A32343A343420FB
+:0559A0004353547D009B
+:00000001FF
diff --git a/firmware/ap6210/nvram_ap6210.txt.ihex b/firmware/ap6210/nvram_ap6210.txt.ihex
new file mode 100644
index 0000000..250c1e9
--- /dev/null
+++ b/firmware/ap6210/nvram_ap6210.txt.ihex
@@ -0,0 +1,75 @@
+:10000000234150363231305F4E5652414D5F5631AA
+:100010002E325F30333139323031330D0A6D616E3B
+:100020006669643D30783264300D0A70726F6469BD
+:10003000643D30783439320D0A76656E6469643D0A
+:100040003078313465340D0A64657669643D307802
+:10005000343334330D0A626F617264747970653DB4
+:100060003078303539380D0A0D0A2320426F61721D
+:1000700064205265766973696F6E2069732050330E
+:1000800030372C2073616D65206E7672616D20664D
+:10009000696C652063616E206265207573656420FC
+:1000A000666F7220503330342C20503330352C2082
+:1000B0005033303620616E64205033303720617306
+:1000C0002074686520747373692070612070617298
+:1000D000616D732075736564206172652073616D55
+:1000E000650D0A23506C6561736520666F726365E8
+:1000F00020746865206175746F6D61746963205246
+:100100005820504552206461746120746F207468D7
+:1001100065207265737065637469766520626F61CE
+:100120007264206469726563746F727920696620F5
+:100130006E6F74207573696E67205033303720629C
+:100140006F6172642C20666F7220652E672E2066A8
+:100150006F72205033303520626F61726473206695
+:100160006F72636520746865206461746120696ED4
+:10017000746F2074686520666F6C6C6F77696E674A
+:10018000206469726563746F7279202F70726F6A70
+:10019000656374732F42434D34333336322F6131EC
+:1001A0005F6C6162646174612F626F617264746517
+:1001B0007374732F726573756C74732F7364675FD8
+:1001C000726576303330350D0A626F617264726524
+:1001D000763D3078313330370D0A626F6172646E6C
+:1001E000756D3D3737370D0A7874616C66726571CD
+:1001F0003D32363030300D0A626F617264666C6178
+:1002000067733D307838303230310D0A626F617279
+:1002100064666C616773323D307838300D0A7372F2
+:100220006F6D7265763D330D0A776C3069643D30D1
+:1002300078343331620D0A6D6163616464723D30FC
+:10024000303A39303A34633A30373A37313A31322A
+:100250000D0A616132673D310D0A6167303D320D33
+:100260000A6D617870326761303D37340D0A63631F
+:100270006B3267706F3D3078323232320D0A6F6602
+:10028000646D3267706F3D307834343434343434D4
+:10029000340D0A6D63733267706F303D30783636D7
+:1002A00036360D0A6D63733267706F313D307836C4
+:1002B0003636360D0A7061306D61787077723D3573
+:1002C000360D0A0D0A23503230372050412070611C
+:1002D00072616D730D0A2370613062303D353434C4
+:1002E000370D0A2370613062313D2D3635380D0AE5
+:1002F0002370613062323D2D3137353C6469763E82
+:100300003C2F6469763E0D0A0D0A2353616D65200A
+:10031000504120706172616D7320666F722050339E
+:1003200030342C503330352C20503330362C205084
+:100330003330370D0A0D0A70613062303D35343488
+:10034000370D0A70613062313D2D3630370D0A703D
+:10035000613062323D2D3136300D0A706130697482
+:10036000737369743D36320D0A7061316974737349
+:1003700069743D36320D0A0D0A0D0A63636B5077BE
+:10038000724F66667365743D350D0A63636F64650D
+:100390003D300D0A72737369736D6632673D307854
+:1003A000610D0A72737369736D6332673D30783320
+:1003B0000D0A7273736973617632673D3078370D59
+:1003C0000A747269736F32673D300D0A6E6F69731C
+:1003D000655F63616C5F656E61626C655F32673D2E
+:1003E000300D0A6E6F6973655F63616C5F706F5F7C
+:1003F00032673D300D0A73776374726C6D61705FA4
+:1004000032673D307830343034303430342C30780A
+:1004100030323032303230322C307830323032308C
+:100420003230322C30783031303130312C3078313C
+:1004300066660D0A74656D705F6164643D323937BC
+:1004400036370D0A74656D705F6D756C743D3432AE
+:10045000350D0A0D0A6274635F666C6167733D3027
+:1004600078360D0A6274635F706172616D73303D3E
+:10047000353030300D0A6274635F706172616D7384
+:10048000313D313030300D0A6274635F70617261EA
+:0A0490006D73363D36330D0A0D0A78
+:00000001FF