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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "siutils_priv.h" + +#include + +#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 +#include +#include +#include +#include +#include + +#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 + +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"); +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include + +#include /* BRCM API for SDIO clients (such as wl, dhd) */ +#include /* common SDIO/controller interface */ +#include /* SDIO device core hardware definitions. */ + +#include /* SDIO Device and Protocol Specs */ + +#include + +#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 +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 +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(OOB_INTR_ONLY) +#include +extern void dhdsdio_isr(void * args); +#include +#include +#include +#include +#include +#endif + +#include + +/** + * 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 **)®s, irq))) { + AP6210_ERR("%s: bcmsdh_attach failed\n", __FUNCTION__); + goto err; + } +#else + if (!(sdh = bcmsdh_attach(osh, (void *)r->start, + (void **)®s, 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 **)®s, 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 + +#include +#include +#include +#include +#include /* SDIO Device and Protocol Specs */ +#include /* Standard SDIO Host Controller Specification */ +#include /* bcmsdh to/from specific controller APIs */ +#include /* ioctl/iovars */ + +#include +#include +#include +#include + +#include +#include + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) +#include +extern volatile bool dhd_mmc_suspend; +#endif +#include "bcmsdh_sdmmc.h" + +#include + +#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, ®data)) != 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 +#include +#include /* SDIO Device and Protocol Specs */ +#include /* bcmsdh to/from specific controller APIs */ +#include /* to get msglevel bit values */ + +#include /* request_irq() */ + +#include +#include +#include +#include + +#include + +#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 + +#include + +#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 +#include +#include +#include +#ifdef BCMDRIVER + +#include +#include + +#else /* !BCMDRIVER */ + +#include +#include +#include + +#if defined(BCMEXTSUP) +#include +#endif + + +#endif /* !BCMDRIVER */ + +#include +#include +#include +#include +#include +#include +#include +void *_bcmutils_dummy_fn = NULL; + +#include + + +#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 "=\n" lines read from a file and ending in a NUL. + * also accepts nvram files which are already in the format of =\0\=\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 +#include + +#ifdef BCMDRIVER +#include +#include +#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) +#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) +#else +#include +#include +#include +#ifndef ASSERT +#define ASSERT(exp) +#endif +#endif /* BCMDRIVER */ + +#ifdef _bcmwifi_c_ +/* temporary for transitional compatibility */ +#include +#else +#include +#endif + +#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL)) +#include /* For wl/exe/GNUmakefile.brcm_wlu and GNUmakefile.wlm_dll */ +#endif + +#ifndef D11AC_IOTYPES + +/* Definitions for legacy Chanspec type */ + +/* Chanspec ASCII representation: + * + * digit [AB] [N] [UL] + * + * : channel number of the 10MHz or 20MHz channel, + * or control sideband channel of 40MHz channel. + * : A for 5GHz, B for 2.4GHz + * : N for 10MHz, nothing for 20MHz or 40MHz + * (ctl-sideband spec implies 40MHz) + * : U for upper, L for lower + * + * 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: + * [ 'g'] ['/' []['/'<1st80channel>'-'<2nd80channel>]] + * + * : + * (optional) 2, 3, 4, 5 for 2.4GHz, 3GHz, 4GHz, and 5GHz respectively. + * Default value is 2g if channel <= 14, otherwise 5g. + * : + * channel number of the 5MHz, 10MHz, 20MHz channel, + * or primary channel of 40MHz, 80MHz, 160MHz, or 80+80MHz channel. + * : + * (optional) 5, 10, 20, 40, 80, 160, or 80+80. Default value is 20. + * : + * (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: + * + * : + * primary channel of 40MHz, channel <= 14 is 2GHz, otherwise 5GHz + * : + * "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 g/ + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK) +#include +#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 +#include + + +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#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 +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + + +#ifdef PROP_TXSTATUS +#include +#include +#endif + +#include + +#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 = "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], ×tamp, 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 + +#include +#include +#include +#include + +#ifdef PKT_FILTER_SUPPORT +#include +#include +#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 +#include +#include +#include +#include + +#include + +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, ®_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 *)(®), 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 *)®_addr[0], (char *)addr, 4); + memcpy((char *)®_addr[4], (char *)val, 4); + + return (dev_wlc_bufvar_set(dev, name, (char *)®_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, ¶m27); + + 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 *)®addr, (char *)&saved_reg50); + regaddr = 51; + dev_wlc_intvar_set_reg(dev, "btc_params", + (char *)®addr, (char *)&saved_reg51); + regaddr = 64; + dev_wlc_intvar_set_reg(dev, "btc_params", + (char *)®addr, (char *)&saved_reg64); + regaddr = 65; + dev_wlc_intvar_set_reg(dev, "btc_params", + (char *)®addr, (char *)&saved_reg65); + regaddr = 71; + dev_wlc_intvar_set_reg(dev, "btc_params", + (char *)®addr, (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 *)®addr, (char *)&saved_reg66); + regaddr = 41; + dev_wlc_intvar_set_reg(dev, "btc_params", + (char *)®addr, (char *)&saved_reg41); + regaddr = 68; + dev_wlc_intvar_set_reg(dev, "btc_params", + (char *)®addr, (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 +#include + +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 +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#ifdef WL_CFG80211 +#include +#endif +#ifdef WLBTAMP +#include +#include +#endif +#ifdef SET_RANDOM_MAC_SOFTAP +#include +#include +#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 +#include +#endif + +#include +#include + +#ifdef WLMEDIA_HTSF +extern void htsf_update(struct dhd_info *dhd, void *data); +#endif +int dhd_msg_level = DHD_ERROR_VAL; + + +#include + +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 +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +extern void sunximmc_rescan_card(unsigned id, unsigned insert); + +#ifdef CUSTOMER_HW +#include +#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 +#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 + +#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 + +#include +#include + +#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 +#include + +#include +#include +#include +#include +#include + +#include + +#include + +/* 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_WAKELOCK +#include +#endif +#ifdef WL_CFG80211 +#include +#endif + +#ifdef WLBTAMP +#include +#include +#include +#endif + +#include +#include + +#ifdef WLMEDIA_HTSF +#include +#include + +#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 +#include +#endif +#ifdef PROP_TXSTATUS +#include +#include +#endif + +#include + +#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 +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 + +#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 +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 +#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 (dhd->iflist[ifidx] == NULL) { + AP6210_ERR("%s: null i/f %d\n", __FUNCTION__, ifidx); + return ""; + } + + if (dhd->iflist[ifidx]->net) + return dhd->iflist[ifidx]->net->name; + + return ""; +} + +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, ¶m); + } +#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, ¶m); + } +#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 + +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 +#include +#include +#include +#include + +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 +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef __BIG_ENDIAN +#include +#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, + ¶ms_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("\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(¶ms_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, + ¶ms->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, + ¶ms->params_batch.get_batch.scan_results_list, FALSE); + _dhd_pno_clear_all_batch_results(dhd, + ¶ms->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(¶ms->params_batch.get_batch.scan_results_list); + INIT_LIST_HEAD(¶ms->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, + ¶ms->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 +#include + +#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 +#include +#include + +#ifdef BCMEMBEDIMAGE +#include BCMEMBEDIMAGE +#endif /* BCMEMBEDIMAGE */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#if defined(DHD_DEBUG) +#include +#include +#endif /* defined(DHD_DEBUG) */ +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 +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, ®s->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, ®s->tosbmailboxdata, retries); + if (retries <= retry_limit) + W_SDREG(SMB_DEV_INT, ®s->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, ®s->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, ®s->tosbmailboxdata, retries); + if (retries <= retry_limit) + W_SDREG(SMB_DEV_INT, ®s->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, ®s->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, ®s->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, ®s->tohostmailboxdata, retries); + if (retries <= retry_limit) + W_SDREG(SMB_INT_ACK, ®s->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, ®s->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, ®s->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, ®s->intstatus, retries); + R_SDREG(newstatus, ®s->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, ®s->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 +#include + +#include +#include + +#include +#include + +#include +#include + +#ifdef PROP_TXSTATUS +#include +#include +#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 = "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], ×tamp, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 /* 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 + +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 _M BITFIELD_MASK(3) + * #define _S 4 + * ... + * regval = R_REG(osh, ®s->regfoo); + * field = GFIELD(regval, ); + * regval = SFIELD(regval, , 1); + * W_REG(osh, ®s->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 + +/* 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 +#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 + +#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 +#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 + + +/* require default structure packing */ +#define BWL_DEFAULT_PACKING +#include + + +/* 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 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 + +#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 + +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 + +#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 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 +#include + +/* + * 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 + +/* 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 + #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 /* use current 2.4.x calling conventions */ +#include /* for vsn/printf's */ +#include /* 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 /* for vsn/printf's */ +#include /* 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 /* 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 + +/* str* and mem* functions */ +#include + +/* *printf functions */ +#include + +/* 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 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) +#include +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) +#include +#else +#include +#endif +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) */ +#include + +#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 +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#include +#else +#include +#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 + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)) +#include +#else +#include +#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 +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) +#include +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) +#include +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) +#include +#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 +#include +#else +#include + +#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 +#endif + + +/* This marks the start of a packed structure section. */ +#include + +#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 + +#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 + +#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 + * + * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { + * some_struct_members; + * } BWL_POST_PACKED_STRUCT foobar_t; + * + * #include + * + * + * 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 + * + * typedef BWL_PRE_PACKED_STRUCT struct foobar_t { + * some_struct_members; + * } BWL_POST_PACKED_STRUCT foobar_t; + * + * #include + * + * + * 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 +#endif + +#ifndef _NET_ETHERNET_H_ +#include +#endif + +#include + +/* This marks the start of a packed structure section. */ +#include + + +#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 + +#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 +#endif + +/* This marks the start of a packed structure section. */ +#include + + +/* 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 + +#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 +#endif + +/* This marks the start of a packed structure section. */ +#include + +/* 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 + +#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 +#endif + +/* This marks the start of a packed structure section. */ +#include + +#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 + +#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 +#endif + +/* This marks the start of a packed structure section. */ +#include + + +/* 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 + +#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 + + +/* 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 + +#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 +#endif + +/* This marks the start of a packed structure section. */ +#include + +#include + +/* 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 + +#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 + + +/* + * 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 + +#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 +#endif +#include +#include + +/* This marks the start of a packed structure section. */ +#include + + +/* 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 + +#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 +#endif + +/* This marks the start of a packed structure section. */ +#include + +#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 + +#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 +#include + + +/* This marks the start of a packed structure section. */ +#include + +/* 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 + +#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_PLL_XX where is PMU corerev and 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, refcomp_pwrdn, dly_ch, 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 + +/* mdiv */ +#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) + +/* mdiv, 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 */ +#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, refcomp_pwrdn, dly_ch, 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 + +/* mdiv */ +#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 + +/* mdiv, 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 */ +#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__ */ +#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 + +/* require default structure packing */ +#define BWL_DEFAULT_PACKING +#include + +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 + +#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 + +#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 +#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 +#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 /* sys/types.h and linux/types.h are oil and water */ +#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */ + +#else + + +#include + +#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 +#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 +#include +#include +#include +#include +#include +#include + +#ifndef LINUX_POSTMOGRIFY_REMOVAL +#include +#include +#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 + + +#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 + +/* require strict packing */ +#include + +#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 + +#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 +#include +#include +#include +#include +#include +#include +#include + + +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "siutils_priv.h" + +#include + + +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "siutils_priv.h" + +#include + +/* 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, ®s->bankidx, bankidx); + bankinfo = R_REG(sii->osh, ®s->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, ®s->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, ®s->bankidx, bankidx); + bankinfo = R_REG(sii->osh, ®s->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, ®s->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, ®s->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, ®s->bankidx, bankidx); + bankinfo = R_REG(sii->osh, ®s->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, ®s->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, ®s->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, ®s->bankidx, bankidx); + bankinfo = R_REG(sii->osh, ®s->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, ®s->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, ®s->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, ®s->bankidx, i); + if (R_REG(sii->osh, ®s->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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WL_CFG80211 +#include +#endif +#if defined(CONFIG_WIFI_CONTROL_FUNC) +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) +#include +#else +#include +#endif +#endif /* CONFIG_WIFI_CONTROL_FUNC */ + +#include + +#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; jRSSI[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; jRSSI[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; jRSSI[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; jRSSI[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= -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 +#include +#include + +/* 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef PROP_TXSTATUS +#include +#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 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(¶ms->bssid, ðer_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(¶ms->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(¶ms->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(¶ms->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("<<<<<<<<<<>>>>>>>>>>\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, ðer_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, ðer_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(¶ms, 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, ¶ms); + 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(¶ms->bssid, ðer_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", ¶m, 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 && iresults.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, ¶ms_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 +#include +#include +#include +#include +#include +#include + +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +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, ðer_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 +#include + +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 +#include +#include + +#include +#include +#include + +#include +#include + + +typedef const struct si_pub si_t; +#include + + +#include + +#include + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) +#include +#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 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 *)¶mval, 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 *)¶mval, 1); + break; + + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", (char *)¶mval, 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 *)¶mval, 1); + break; + + case IW_AUTH_DROP_UNENCRYPTED: + dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)¶mval, 1); + break; + + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", (char *)¶mval, 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(¶ms->bssid, ðer_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(¶ms->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(¶ms->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 + +#include +#include +#include + +#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 +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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +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 +#include +#include +#include + +#include +#include + +#include + +#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 + +/* 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