diff --git a/arch/arm/src/rtl8720c/Kconfig b/arch/arm/src/rtl8720c/Kconfig new file mode 100644 index 00000000000..8553940d13f --- /dev/null +++ b/arch/arm/src/rtl8720c/Kconfig @@ -0,0 +1,395 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_CUSTOM + +comment "AMEBA Configuration Options" + +choice + prompt "AMEBA Chip Selection" + default ARCH_CHIP_AMEBAZ + +config ARCH_CHIP_AMEBAZ + bool "AmebaZ" + select ARCH_CORTEXM33 + +endchoice + +choice + prompt "AMEBAZ Chip Type Selection" + default ARCH_CHIP_AMEBAZ_C_CUT + depends on ARCH_CHIP_AMEBAZ + +config ARCH_CHIP_AMEBAZ_C_CUT + bool "AmebaZ_C_CUT" + +config ARCH_CHIP_AMEBAZ_D_CUT + bool "AmebaZ_D_CUT" + +endchoice + +config AMEBA_NR_IRQS + int "Interrupt Number" + +menuconfig AMEBA_UART + bool "AMEBA UART Chip support" + select ARCH_HAVE_SERIAL_TERMIOS + default n + +if AMEBA_UART + +config AMEBA_UART0 + bool "AMEBA UART0" + default n + +if AMEBA_UART0 + +config AMEBA_UART0_TX_PIN + int "AMEBA UART0 tx pin" + +config AMEBA_UART0_RX_PIN + int "AMEBA UART0 rx pin" + +config AMEBA_UART0_BAUD + int "AMEBA UART0 BAUD" + default 115200 + +config AMEBA_UART0_PARITY + int "AMEBA UART0 parity" + default 0 + range 0 2 + ---help--- + AMEBA UART0 parity. 0=None, 1=Odd, 2=Even. Default: None + +config AMEBA_UART0_BITS + int "AMEBA UART0 number of bits" + default 8 + ---help--- + AMEBA UART0 number of bits. Default: 8 + +config AMEBA_UART0_2STOP + int "AMEBA UART0 two stop bits" + default 0 + ---help--- + 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit + +config AMEBA_UART0_RXBUFSIZE + int "AMEBA UART0 Rx buffer size" + default 256 + ---help--- + AMEBA UART0 Rx buffer size. Default: 256 + +config AMEBA_UART0_TXBUFSIZE + int "AMEBA UART0 Tx buffer size" + default 256 + ---help--- + AMEBA UART0 Tx buffer size. Default: 256 + +config AMEBA_UART0_IFLOWCONTROL + bool "AMEBA UART0 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable AMEBA UART0 RTS flow control + +config AMEBA_UART0_OFLOWCONTROL + bool "AMEBA UART0 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable AMEBA UART0 CTS flow control + +endif # AMEBA_UART0 + +config AMEBA_UART1 + bool "AMEBA UART1" + default n + +if AMEBA_UART1 + +config AMEBA_UART1_TX_PIN + int "AMEBA UART1 tx pin" + +config AMEBA_UART1_RX_PIN + int "AMEBA UART1 rx pin" + +config AMEBA_UART1_BAUD + int "AMEBA UART1 BAUD" + default 115200 + +config AMEBA_UART1_PARITY + int "AMEBA UART1 parity" + default 0 + range 0 2 + ---help--- + AMEBA UART1 parity. 0=None, 1=Odd, 2=Even. Default: None + +config AMEBA_UART1_BITS + int "AMEBA UART1 number of bits" + default 8 + ---help--- + AMEBA UART1 number of bits. Default: 8 + +config AMEBA_UART1_2STOP + int "AMEBA UART1 two stop bits" + default 0 + ---help--- + 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit + +config AMEBA_UART1_RXBUFSIZE + int "AMEBA UART1 Rx buffer size" + default 256 + ---help--- + AMEBA UART1 Rx buffer size. Default: 256 + +config AMEBA_UART1_TXBUFSIZE + int "AMEBA UART1 Tx buffer size" + default 256 + ---help--- + AMEBA UART1 Tx buffer size. Default: 256 + +config AMEBA_UART1_IFLOWCONTROL + bool "AMEBA UART1 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable AMEBA UART1 RTS flow control + +config AMEBA_UART1_OFLOWCONTROL + bool "AMEBA UART1 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable AMEBA UART1 CTS flow control + +endif # AMEBA_UART1 + +config AMEBA_UART2 + bool "AMEBA UART2" + default n + +if AMEBA_UART2 + +config AMEBA_UART2_TX_PIN + int "AMEBA UART2 tx pin" + +config AMEBA_UART2_RX_PIN + int "AMEBA UART2 rx pin" + +config AMEBA_UART2_BAUD + int "AMEBA UART2 BAUD" + default 115200 + +config AMEBA_UART2_PARITY + int "AMEBA UART2 parity" + default 0 + range 0 2 + ---help--- + AMEBA UART2 parity. 0=None, 1=Odd, 2=Even. Default: None + +config AMEBA_UART2_BITS + int "AMEBA UART2 number of bits" + default 8 + ---help--- + AMEBA UART2 number of bits. Default: 8 + +config AMEBA_UART2_2STOP + int "AMEBA UART2 two stop bits" + default 0 + ---help--- + 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit + +config AMEBA_UART2_RXBUFSIZE + int "AMEBA UART2 Rx buffer size" + default 256 + ---help--- + AMEBA UART2 Rx buffer size. Default: 256 + +config AMEBA_UART2_TXBUFSIZE + int "AMEBA UART2 Tx buffer size" + default 256 + ---help--- + AMEBA UART2 Tx buffer size. Default: 256 + +config AMEBA_UART2_IFLOWCONTROL + bool "AMEBA UART2 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable AMEBA UART2 RTS flow control + +config AMEBA_UART2_OFLOWCONTROL + bool "AMEBA UART2 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable AMEBA UART2 CTS flow control + +endif # AMEBA_UART2 + +config AMEBA_UART3 + bool "AMEBA UART3" + default n + +if AMEBA_UART3 + +config AMEBA_UART3_TX_PIN + int "AMEBA UART3 tx pin" + +config AMEBA_UART3_RX_PIN + int "AMEBA UART3 rx pin" + +config AMEBA_UART3_BAUD + int "AMEBA UART3 BAUD" + default 115200 + +config AMEBA_UART3_PARITY + int "AMEBA UART3 parity" + default 0 + range 0 2 + ---help--- + AMEBA UART3 parity. 0=None, 1=Odd, 2=Even. Default: None + +config AMEBA_UART3_BITS + int "AMEBA UART3 number of bits" + default 8 + ---help--- + AMEBA UART3 number of bits. Default: 8 + +config AMEBA_UART3_2STOP + int "AMEBA UART3 two stop bits" + default 0 + ---help--- + 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit + +config AMEBA_UART3_RXBUFSIZE + int "AMEBA UART3 Rx buffer size" + default 256 + ---help--- + AMEBA UART3 Rx buffer size. Default: 256 + +config AMEBA_UART3_TXBUFSIZE + int "AMEBA UART3 Tx buffer size" + default 256 + ---help--- + AMEBA UART3 Tx buffer size. Default: 256 + +config AMEBA_UART3_IFLOWCONTROL + bool "AMEBA UART3 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable AMEBA UART3 RTS flow control + +config AMEBA_UART3_OFLOWCONTROL + bool "AMEBA UART3 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable AMEBA UART3 CTS flow control + +endif # AMEBA_UART3 + +choice + prompt "AMEBA Serial Console" + default AMEBA_NO_SERIAL_CONSOLE + depends on DEV_CONSOLE + +config AMEBA_UART0_SERIAL_CONSOLE + bool "AMEBA UART0 serial console" + depends on AMEBA_UART0 + select SERIAL_CONSOLE + +config AMEBA_UART1_SERIAL_CONSOLE + bool "AMEBA UART1 serial console" + depends on AMEBA_UART1 + select SERIAL_CONSOLE + +config AMEBA_UART2_SERIAL_CONSOLE + bool "AMEBA UART2 serial console" + depends on AMEBA_UART2 + select SERIAL_CONSOLE + +config AMEBA_UART3_SERIAL_CONSOLE + bool "AMEBA UART3 serial console" + depends on AMEBA_UART3 + select SERIAL_CONSOLE + +config AMEBA_NO_SERIAL_CONSOLE + bool "No AMEBA serial console" + +endchoice # AMEBA Serial Console + +config AMEBA_SUPRESS_CONFIG + bool "Suppress AMEBA configuration" + default n + +config AMEBA_SUPRESS_INITIAL_CONFIG + bool "Suppress initial AMEBA configuration" + depends on !AMEBA_SUPRESS_CONFIG + default n + ---help--- + This option is useful, for example, if you are using a bootloader + that configures the AMEBA_UART. In that case, you may want to + just leave the existing console configuration in place. Default: n + +config SERIAL_UART_ARCH_MMIO + bool "Platform access register through the memory mapping" + default n + +config SERIAL_UART_ARCH_IOCTL + bool "Platform has own custom IOCTL" + default n + +config AMEBA_REGINCR + int "Address increment between AMEBA registers" + default 1 + ---help--- + The address increment between AMEBA registers. Options are 1, 2, or 4. + Default: 1 + +config AMEBA_REGWIDTH + int "Bit width of AMEBA registers" + default 8 + ---help--- + The bit width of registers. Options are 8, 16, or 32. Default: 8 + +config AMEBA_ADDRWIDTH + int "Address width of AMEBA registers" + default 8 + ---help--- + The bit width of registers. Options are 8, 16, or 32. Default: 8 + +config AMEBA_HCI_DEV_NAME + string "Device Name of UART Device for Bluetooth" + default "/dev/ttyS2" + ---help--- + This option specifies the name of UART device to be used + for Bluetooth. + +config AMEBA_HCI_PROXY_DEV_NAME + string "Device Name of UART Device for Bluetooth" + default "/dev/ttyBT" + ---help--- + This option specifies the name of UART device to be used + for Bluetooth. + +endif # AMEBA_UART + +config IEEE80211_REALTEK_AMEBAZ + bool "Realtek amebaZ chip support" + default n + +if IEEE80211_REALTEK_AMEBAZ + +config IEEE80211_REALTEK_AMEBAZ_RECV_STACKSIZE + int "Realtek amebaZ recv stack size" + default 4096 + ---help--- + Default recv stack size + +endif + +endif # ARCH_CHIP_CUSTOM diff --git a/arch/arm/src/rtl8720c/Make.defs b/arch/arm/src/rtl8720c/Make.defs new file mode 100644 index 00000000000..ce08554a2b3 --- /dev/null +++ b/arch/arm/src/rtl8720c/Make.defs @@ -0,0 +1,76 @@ +############################################################################ +# arch/arm/src/rtl8720c/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +# arch/arm/src/common +# +CMN_CSRCS += arm_checkstack.c arm_createstack.c arm_exit.c arm_hostfs.c +CMN_CSRCS += arm_initialize.c arm_interruptcontext.c arm_modifyreg8.c +CMN_CSRCS += arm_modifyreg16.c arm_modifyreg32.c arm_pthread_start.c +CMN_CSRCS += arm_puts.c arm_releasestack.c arm_semi_syslog.c +CMN_CSRCS += arm_stackframe.c arm_task_start.c arm_usestack.c arm_vfork.c + +CMN_ASRCS += arm_exception.S + +# arch/arm/src/armv8-m +# +CMN_ASRCS += arm_fetchadd.S arm_fpu.S arm_setjmp.S +CMN_ASRCS += arm_fullcontextrestore.S arm_saveusercontext.S +CMN_ASRCS += arm_switchcontext.S arm_testset.S vfork.S + +CMN_UASRCS += arm_signal_handler.S + +CMN_CSRCS += arm_assert.c arm_blocktask.c arm_cache.c arm_copyarmstate.c +CMN_CSRCS += arm_copyfullstate.c arm_doirq.c arm_hardfault.c arm_initialstate.c +CMN_CSRCS += arm_itm_syslog.c arm_memfault.c arm_mpu.c arm_ramvec_attach.c +CMN_CSRCS += arm_ramvec_initialize.c arm_releasepending.c arm_reprioritizertr.c +CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_signal_dispatch.c +CMN_CSRCS += arm_stackcheck.c arm_svcall.c arm_systick.c arm_unblocktask.c + +# arch/arm/src/rtl8720c +# +CHIP_CSRCS += ameba_nvic.c ameba_heap.c ameba_idle.c ameba_uart.c ameba_start.c ameba_vectors.c +CHIP_CSRCS += ameba_efuse.c ameba_flash.c ameba_wdt.c ameba_hci.c + +CHIP_ASRCS += ameba_lto.S + +# arch/arm/src/rtl8720c/8710c/fwlib/source +# +CHIP_CSRCS += hal_efuse.c hal_flash.c hal_misc.c hal_spic.c hal_ssi.c hal_uart.c + +CFLAGS += -I$(TOPDIR)/arch/arm/include/rtl8720c +CFLAGS += -I$(TOPDIR)/arch/arm/src/rtl8720c +CFLAGS += -I$(TOPDIR)/arch/arm/src/rtl8720c/8710c/cmsis/cmsis-core/include +CFLAGS += -I$(TOPDIR)/arch/arm/src/rtl8720c/8710c/cmsis/rtl8710c/include +CFLAGS += -I$(TOPDIR)/arch/arm/src/rtl8720c/8710c/app/rtl_printf/include +CFLAGS += -I$(TOPDIR)/arch/arm/src/rtl8720c/8710c/app/stdio_port +CFLAGS += -I$(TOPDIR)/arch/arm/src/rtl8720c/8710c/misc/utilities/include +CFLAGS += -I$(TOPDIR)/arch/arm/src/rtl8720c/8710c/fwlib/include + +CFLAGS += -Wno-attributes + +ifeq ($(CONFIG_IEEE80211_REALTEK_AMEBAZ),y) +CHIP_CSRCS += amebaZ.c amebaz_driver.c amebaz_netdev.c amebaz_depend.c amebaz_wlan.c ameba_func.c +CHIP_CSRCS += amebaz_hci_board.c amebaz_coex.c amebaz_firmware.c +endif # CONFIG_IEEE80211_REALTEK_AMEBAZ + +VPATH += chip/8710c +VPATH += chip/8710c/fwlib/source/ram +VPATH += chip/8710c/fwlib/source/ram_s +VPATH += chip/8710c/fwlib/source/ram_ns diff --git a/arch/arm/src/rtl8720c/Toolchain.defs b/arch/arm/src/rtl8720c/Toolchain.defs new file mode 100644 index 00000000000..9be75a76442 --- /dev/null +++ b/arch/arm/src/rtl8720c/Toolchain.defs @@ -0,0 +1,101 @@ +############################################################################ +# arch/arm/src/rtl8720c/Toolchain.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + ARCHSCRIPT = -T "${shell cygpath -w $(LDSCRIPT)}" +else + ARCHSCRIPT = -T$(LDSCRIPT) +endif + +include ${TOPDIR}/arch/arm/src/armv8-m/Toolchain.defs + +LD = $(CROSSDEV)gcc + +ARCHOPTIMIZATION = +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g +endif + +# enable precise stack overflow tracking +ifeq ($(CONFIG_ARMV8M_STACKCHECK),y) + INSTRUMENTATIONDEFINES += -finstrument-functions -ffixed-r10 +endif + +ifeq ($(CONFIG_STACK_CANARIES),y) + ARCHOPTIMIZATION += -fstack-protector-all +endif + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer + ARCHOPTIMIZATION += -ffunction-sections -fdata-sections +ifneq ($(CONFIG_ARMV8M_STACKCHECK),y) + #ARCHOPTIMIZATION += -flto -fuse-linker-plugin +endif +endif + +ARCHCFLAGS = -fno-builtin -march=armv8-m.main+dsp -mthumb -mfloat-abi=soft -D__thumb2__ -g -gdwarf-3 -Os -fno-tree-scev-cprop +ARCHCXXFLAGS = -fno-builtin -nostdinc++ -std=c++11 +ifneq ($(CONFIG_CXX_EXCEPTION),y) + ARCHCXXFLAGS += -fno-exceptions -fcheck-new -fno-rtti +endif +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef + +CFLAGS := $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CFLAGS += -I$(TOPDIR)/arch/$(CONFIG_ARCH)/src/rtl8720c +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ + +# ELF module definitions + +CELFFLAGS = $(CFLAGS) -mlong-calls -fno-common +CXXELFFLAGS = $(CXXFLAGS) -mlong-calls -fno-common +AELFFLAGS = $(AFLAGS) +LDELFFLAGS = -r -e main -Bstatic $(LDFLAGS) +LDELFFLAGS += -T $(TOPDIR)/binfmt/libelf/gnu-elf.ld + +# Loadable module definitions + +CMODULEFLAGS = $(CFLAGS) -mlong-calls -fno-common + +LDMODULEFLAGS = -r -e module_initialize $(LDFLAGS) +ifeq ($(WINTOOL),y) + LDMODULEFLAGS += -T "${shell cygpath -w $(TOPDIR)/libs/libc/modlib/gnu-elf.ld}" +else + LDMODULEFLAGS += -T $(TOPDIR)/libs/libc/modlib/gnu-elf.ld +endif + +LDSTARTGROUP = -Wl,--start-group +LDENDGROUP = -Wl,--end-group + +ifeq ($(filter -nuttx-, $(CROSSDEV)),) + LDFLAGS += -nostartfiles -nodefaultlibs +endif +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + LDFLAGS += -g +endif + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + LDFLAGS += -Wl,--gc-sections +endif + +EXTRA_LIBS += -l_soc_is +EXTRA_LIBS += -l_wlan diff --git a/arch/arm/src/rtl8720c/amebaZ.c b/arch/arm/src/rtl8720c/amebaZ.c new file mode 100644 index 00000000000..adc9fce45c4 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaZ.c @@ -0,0 +1,47 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaZ.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "systick.h" +#include "hal_syson.h" +#include "hal_wdt.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_ARCH_CHIP_AMEBAZ +void up_timer_initialize(void) +{ + up_timer_set_lowerhalf(systick_initialize(true, 100000000, -1)); +} + +void ameba_reset(int status) +{ + hal_sys_set_fast_boot(0, 0); + hal_misc_rst_by_wdt(); +} + +#endif /* CONFIG_ARCH_CHIP_AMEBAZ */ diff --git a/arch/arm/src/rtl8720c/ameba_efuse.c b/arch/arm/src/rtl8720c/ameba_efuse.c new file mode 100644 index 00000000000..2c44e476d03 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_efuse.c @@ -0,0 +1,224 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_efuse.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hal_api.h" +#include "hal_efuse.h" +#include "hal_efuse_nsc.h" +#include "platform_conf.h" +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if CONFIG_EFUSE_EN +/* #define EFUSE_LOGICAL_SIM */ + +#define EFUSE_LOGICAL_MAP_SIZE 512 +#define EFUSE_LOGICAL_MAP_HW_SIZE 0xd0 /* sync with EFUSE_OOB_PROTECT_BYTES */ +#define EFUSE_LOGICAL_SBLOCK_OFFSET 0x19 +#ifdef EFUSE_LOGICAL_SIM +uint8_t ameba_efuse_sim_map[256]; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int ameba_efuse_logical_read(uint16_t laddr, uint16_t size, uint8_t *pbuf) +{ + uint8_t offset; + uint8_t wden; + uint8_t header; + uint8_t extheader; + uint8_t data; + uint16_t phy_addr = 0; + uint16_t i; + uint32_t ret; + if (!pbuf) + { + return -EIO; + } + + rtw_memset(pbuf, 0xff, size); + while (phy_addr < EFUSE_LOGICAL_MAP_HW_SIZE) + { + /* First two bytes are reserved for physical */ + + if (phy_addr == 0 || phy_addr == 1) + { + phy_addr++; + continue; + } + +#ifdef EFUSE_LOGICAL_SIM + static int map_inited = 0; + if (!map_inited) + { + map_inited = 1; + for (i = 0; i < EFUSE_LOGICAL_MAP_HW_SIZE; i++) + { + hal_efuse_read(i, &ameba_efuse_sim_map[i], + LDO_OUT_DEFAULT_VOLT); + } + } + + ret = _TRUE; + header = ameba_efuse_sim_map[phy_addr++]; +#else + ret = hal_efuse_read(phy_addr++, &header, LDO_OUT_DEFAULT_VOLT); +#endif + if (ret != _TRUE) + { + return -EIO; + } + + if (header == 0xff) + { + break; + } + + /* Check PG header for section num. */ + + if ((header & 0x1f) == 0x0f) + { + /* extended header */ + + offset = (header & 0xe0) >> 5; +#ifdef EFUSE_LOGICAL_SIM + ret = _TRUE; + extheader = ameba_efuse_sim_map[phy_addr++]; +#else + ret = hal_efuse_read(phy_addr++, &extheader, LDO_OUT_DEFAULT_VOLT); +#endif + if (ret != _TRUE) + { + return -EIO; + } + + if (((extheader & 0x0f) == 0x0f)) + { + continue; + } + + offset |= ((extheader & 0xf0) >> 1); + wden = (extheader & 0x0f); + } + + else + { + offset = ((header >> 4) & 0x0f); + wden = (header & 0x0f); + } + + /* One section has 8 bytes data, logical map has 512/8 = 64 sections */ + + if (offset < (EFUSE_LOGICAL_MAP_SIZE >> 3)) + { + uint16_t addr = 0; + + /* Get word enable value from PG header */ + + addr = offset * 8; + + /* Each section has 4 words data */ + + for (i = 0; i < 4; i++) + { + /* Check word enable condition in the section */ + + if (!(wden & (0x01 << i))) + { +#ifdef EFUSE_LOGICAL_SIM + ret = _TRUE; + data = ameba_efuse_sim_map[phy_addr++]; +#else + ret = hal_efuse_read(phy_addr++, &data, + LDO_OUT_DEFAULT_VOLT); +#endif + if (ret != _TRUE) + { + return -EIO; + } + + if (addr >= laddr && addr < (laddr + size)) + { + pbuf[addr - laddr] = data; + } + +#ifdef EFUSE_LOGICAL_SIM + ret = _TRUE; + data = ameba_efuse_sim_map[phy_addr++]; +#else + ret = hal_efuse_read(phy_addr++, &data, + LDO_OUT_DEFAULT_VOLT); +#endif + if (ret != _TRUE) + { + return -EIO; + } + + if ((addr + 1) >= laddr && (addr + 1) < (laddr + size)) + { + pbuf[addr + 1 - laddr] = data; + } + } + + addr += 2; + } + } + + else + { + uint8_t word_cnts = 0; + if (!(wden & BIT(0))) + { + word_cnts++; /* 0 : write enable */ + } + + if (!(wden & BIT(1))) + { + word_cnts++; + } + + if (!(wden & BIT(2))) + { + word_cnts++; + } + + if (!(wden & BIT(3))) + { + word_cnts++; + } + + phy_addr += word_cnts * 2; + } + } + + /* return used bytes */ + + return phy_addr - EIO; +} + +#endif diff --git a/arch/arm/src/rtl8720c/ameba_efuse.h b/arch/arm/src/rtl8720c/ameba_efuse.h new file mode 100644 index 00000000000..bfa4c31f87f --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_efuse.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_efuse.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_AMEBA_HCI_EFUSE_H +#define __INCLUDE_AMEBA_HCI_EFUSE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* #include "device.h" */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int ameba_efuse_logical_read(uint16_t laddr, uint16_t size, uint8_t *pbuf); +int ameba_efuse_logical_write(uint16_t addr, uint16_t cnts, uint8_t *data); +int ameba_efuse_fw_verify_enable(void); +int ameba_efuse_fw_verify_check(void); +int ameba_efuse_boot_message_disable(void); +int ameba_efuse_boot_message_enable(void); +#endif /* __INCLUDE_AMEBA_FLASH_H */ diff --git a/arch/arm/src/rtl8720c/ameba_flash.c b/arch/arm/src/rtl8720c/ameba_flash.c new file mode 100644 index 00000000000..70572953262 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_flash.c @@ -0,0 +1,335 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_flash.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ameba_flash.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Identifies the flash sector and block size */ + +#define AMEBA_SECTOR_SHIFT (12) +#define AMEBA_SECTOR_SIZE (1 << 12) /* Sector size 1 << 12 = 4KB */ +#define AMEBA_PAGE_SHIFT (8) +#define AMEBA_PAGE_SIZE (1 << 8) /* Block size 1 << 8 = 256B */ + +/* Flash Layout */ + +#define AMEBA_SECTOR_TOTAL_SIZE (2048 * 1024) /* Total flash size */ +#define AMEBA_SECTOR_SYSTEM_SIZE (16 * 1024) +#define AMEBA_SECTOR_BOOT_SIZE (32 * 1024) +#define AMEBA_SECTOR_FIRMWARE1_SIZE (864 * 1024) +#define AMEBA_SECTOR_FIRMWARE2_SIZE (864 * 1024) +#define AMEBA_SECTOR_OTA_SIZE (236 * 1024) +#define AMEBA_SECTOR_DATA_SIZE (24 * 1024) +#define AMEBA_SECTOR_BLUETOOTH_SIZE (12 * 1024) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum +{ + SPICONEIOMODE = 0, /* !< Define One IO mode, 1-1-1 */ + SPICDUALOUTPUTMODE = 1, /* !< Define Dual Output mode, 1-1-2 */ + SPICDUALIOMODE = 2, /* !< Define Dual IO mode, 1-2-2 */ + SPICQUADOUTPUTMODE = 3, /* !< Define Quad Output mode, 1-1-4 */ + SPICQUADIOMODE = 4, /* !< Define Quad IO mode, 1-4-4 */ + SPICQPIMODE = 5, /* !< Define QPI mode, 4-4-4 */ +}; + +struct ameba_flash_dev_s +{ + struct mtd_dev_s mtd; + void *adaptor; + uint32_t baseaddr; + uint16_t nsectors; +}; + +extern const hal_flash_func_stubs_t hal_flash_stubs; +extern hal_spic_adaptor_t hal_spic_adaptor; +extern hal_spic_adaptor_t *pglob_spic_adaptor; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct partition_s ptable[5] = +{ + { + .name = "fw1", + .firstblock = AMEBA_SECTOR_SYSTEM_SIZE + + AMEBA_SECTOR_BOOT_SIZE, + .nblocks = AMEBA_SECTOR_FIRMWARE1_SIZE, + }, + { + .name = "fw2", + .firstblock = AMEBA_SECTOR_SYSTEM_SIZE + + AMEBA_SECTOR_BOOT_SIZE + + AMEBA_SECTOR_FIRMWARE1_SIZE, + .nblocks = AMEBA_SECTOR_FIRMWARE2_SIZE, + }, + { + .name = "ota", + .firstblock = AMEBA_SECTOR_SYSTEM_SIZE + + AMEBA_SECTOR_BOOT_SIZE + + AMEBA_SECTOR_FIRMWARE1_SIZE + + AMEBA_SECTOR_FIRMWARE2_SIZE, + .nblocks = AMEBA_SECTOR_OTA_SIZE, + }, + { + .name = "data", + .firstblock = AMEBA_SECTOR_SYSTEM_SIZE + + AMEBA_SECTOR_BOOT_SIZE + + AMEBA_SECTOR_FIRMWARE1_SIZE + + AMEBA_SECTOR_FIRMWARE2_SIZE + + AMEBA_SECTOR_OTA_SIZE, + .nblocks = AMEBA_SECTOR_DATA_SIZE, + }, + { + .name = "bt", + .firstblock = AMEBA_SECTOR_SYSTEM_SIZE + + AMEBA_SECTOR_BOOT_SIZE + + AMEBA_SECTOR_FIRMWARE1_SIZE + + AMEBA_SECTOR_FIRMWARE2_SIZE + + AMEBA_SECTOR_OTA_SIZE + + AMEBA_SECTOR_DATA_SIZE, + .nblocks = AMEBA_SECTOR_BLUETOOTH_SIZE, + }, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static irqstate_t flash_resource_lock(void) +{ + irqstate_t state; + state = enter_critical_section(); + icache_disable(); + dcache_disable(); + return state; +} + +static void flash_resource_unlock(irqstate_t state) +{ + dcache_enable(); + icache_enable(); + icache_invalidate(); + leave_critical_section(state); +} + +static int ameba_flash_erase(FAR struct mtd_dev_s *dev, + off_t startblock, size_t nblocks) +{ + FAR struct ameba_flash_dev_s *priv = (FAR struct ameba_flash_dev_s *)dev; + uint32_t address = priv->baseaddr + (startblock << AMEBA_SECTOR_SHIFT); + irqstate_t state; + state = flash_resource_lock(); + hal_flash_stubs.hal_flash_sector_erase(priv->adaptor, address); + flash_resource_unlock(state); + return nblocks; +} + +static ssize_t ameba_flash_bread(FAR struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + FAR uint8_t *buf) +{ + FAR struct ameba_flash_dev_s *priv = (FAR struct ameba_flash_dev_s *)dev; + uint32_t address = priv->baseaddr + (startblock << AMEBA_PAGE_SHIFT); + uint32_t length = nblocks << AMEBA_PAGE_SHIFT; + irqstate_t state; + state = flash_resource_lock(); + dcache_invalidate_by_addr((uint32_t *)(SPI_FLASH_BASE + address), length); + hal_flash_stubs.hal_flash_stream_read(priv->adaptor, length, address, buf); + flash_resource_unlock(state); + return nblocks; +} + +static ssize_t ameba_flash_bwrite(FAR struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, FAR const uint8_t *buf) +{ + FAR struct ameba_flash_dev_s *priv = (FAR struct ameba_flash_dev_s *)dev; + uint32_t address = priv->baseaddr + (startblock << AMEBA_PAGE_SHIFT); + uint32_t length = nblocks << AMEBA_PAGE_SHIFT; + irqstate_t state; + state = flash_resource_lock(); + hal_flash_stubs.hal_flash_burst_write(priv->adaptor, + length, address, (uint8_t *)buf); + flash_resource_unlock(state); + return nblocks; +} + +static int ameba_flash_spic_init(struct ameba_flash_dev_s *priv) +{ + hal_status_t status; + irqstate_t state; + if (pglob_spic_adaptor == NULL) + { + status = spic_init(&hal_spic_adaptor, SPICDUALIOMODE, + &(hal_spic_adaptor.flash_pin_sel)); + if (status != HAL_OK) + { + DBG_SPIF_ERR("flash_init err(%d)\r\n", status); + } + + return status; + } + + priv->adaptor = pglob_spic_adaptor; + state = flash_resource_lock(); + hal_flash_stubs.hal_flash_read_id(pglob_spic_adaptor); + flash_resource_unlock(state); + if ((pglob_spic_adaptor->flash_id[0] == 0x0) + || (pglob_spic_adaptor->flash_id[0] == 0xff)) + { + return -EPERM; + } + + return 0; +} + +static int ameba_flash_ioctl(FAR struct mtd_dev_s *dev, + int cmd, unsigned long arg) +{ + FAR struct ameba_flash_dev_s *priv = (FAR struct ameba_flash_dev_s *)dev; + irqstate_t state; + int ret = OK; + switch (cmd) + { + case MTDIOC_GEOMETRY: + { + FAR struct mtd_geometry_s *geo = + (FAR struct mtd_geometry_s *)((uintptr_t)arg); + if (geo) + { + geo->blocksize = AMEBA_PAGE_SIZE; + geo->erasesize = AMEBA_SECTOR_SIZE; + geo->neraseblocks = priv->nsectors; + finfo("blocksize: %d erasesize: %d neraseblocks: %d\n", + geo->blocksize, geo->erasesize, geo->neraseblocks); + } + } + + break; + case MTDIOC_BULKERASE: + { + state = flash_resource_lock(); + hal_flash_stubs.hal_flash_64k_block_erase(priv->adaptor, + priv->baseaddr); + flash_resource_unlock(state); + } + + break; + default: + { + ret = -ENOTTY; + } + + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ameba_flash_initialize + * + * Description: + * Create and initialize an ameba spic flash MTD device instance + * that can be used to access the userdata memory. + * + ****************************************************************************/ + +static FAR struct mtd_dev_s *ameba_flash_initialize(void) +{ + struct ameba_flash_dev_s *priv; + priv = kmm_zalloc(sizeof(struct ameba_flash_dev_s)); + if (priv == NULL) + { + return NULL; + } + + priv->mtd.erase = ameba_flash_erase; + priv->mtd.bread = ameba_flash_bread; + priv->mtd.bwrite = ameba_flash_bwrite; + priv->mtd.ioctl = ameba_flash_ioctl; + priv->mtd.name = "ameba_flash"; + priv->baseaddr = 0; + priv->nsectors = AMEBA_SECTOR_TOTAL_SIZE / + AMEBA_SECTOR_SIZE; + if (ameba_flash_spic_init(priv) < 0) + { + ferr("ERROR: Flash Type Unrecognized\n"); + kmm_free(priv); + priv = NULL; + } + + return (FAR struct mtd_dev_s *)priv; +} + +static void ameba_partition_init(FAR const struct partition_s *part, + FAR const void *path) +{ + char dev[32]; + snprintf(dev, sizeof(dev), "/dev/%s", part->name); + register_mtdpartition(dev, 0, path, + part->firstblock / AMEBA_PAGE_SIZE, + part->nblocks / AMEBA_PAGE_SIZE); +} + +void ameba_flash_init(void) +{ + const struct partition_s *table; + char *path = "/dev/ameba_flash"; + FAR struct mtd_dev_s *mtd; + mtd = ameba_flash_initialize(); + if (mtd == NULL) + { + return; + } + + register_mtddriver(path, mtd, 0, mtd); + for (table = &ptable[0]; table->nblocks; table++) + { + ameba_partition_init(table, path); + } +} + diff --git a/arch/arm/src/rtl8720c/ameba_flash.h b/arch/arm/src/rtl8720c/ameba_flash.h new file mode 100644 index 00000000000..2deebb7c719 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_flash.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_flash.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_AMEBA_FLASH_H +#define __INCLUDE_AMEBA_FLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __INCLUDE_AMEBA_FLASH_H */ diff --git a/arch/arm/src/rtl8720c/ameba_hci.c b/arch/arm/src/rtl8720c/ameba_hci.c new file mode 100644 index 00000000000..f1c383f41e0 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_hci.c @@ -0,0 +1,509 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_hci.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include <../../../../net/netdev/netdev.h> +#include "amebaz_hci_board.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AMEBAZ_WIRELESS_NAME "wlan0" +#define H4_CMD 0x01 +#define H4_EVT 0x04 +#define HCI_H4_HDR_SIZE 1 +#define HCI_CMD_HDR_SIZE 3 +typedef struct +{ + struct file_operations i_ops; + struct file filep; +} hci_dev_t; +struct bt_hci_evt_hdr +{ + uint8_t evt; + uint8_t len; +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +static int hci_recv(FAR struct file *filep, FAR uint8_t *buf, size_t count) +{ + ssize_t ret; + ssize_t nread = 0; + while (count != nread) + { + ret = file_read(filep, buf + nread, count - nread); + if (ret < 0) + { + if (ret == -EAGAIN) + { + continue; + } + else + { + return ret; + } + } + + nread += ret; + } + + return nread; +} + +static int hci_send(FAR struct file *filep, FAR uint8_t *buf, size_t count) +{ + ssize_t ret; + ssize_t nwritten = 0; + while (nwritten != count) + { + ret = file_write(filep, buf + nwritten, count - nwritten); + if (ret < 0) + { + if (ret == -EAGAIN) + { + continue; + } + else + { + return ret; + } + } + + nwritten += ret; + } + + return nwritten; +} + +#ifdef HCI_START_IQK +static int hci_do_iqk(FAR struct file *filep) +{ + /* OpCode: 0xfd4a, h4 data_len: Cmd(8), Event(7) */ + + unsigned char command[8]; + struct t_data + { + uint8_t offset; + uint16_t value; + }; + + struct t_data data[4] = + { + {0x00, 0x4000}, + {0x01, 0x0f88}, + {0x02, 0x3400}, + {0x3f, 0x0700} + }; + + if (0 == hci_check_iqk()) + { + return 0; + } + + for (unsigned char i = 0; i < 4; i++) + { + command[0] = H4_CMD; + command[1] = 0x4a; + command[2] = 0xfd; + command[3] = 4; + command[4] = data[i].offset; + command[5] = (uint8_t)(data[i].value >> 0); + command[6] = (uint8_t)(data[i].value >> 8); + command[7] = 0; + if (hci_send(filep, command, 8) != 8) + { + return -EIO; + } + + hci_recv(filep, command, 1); + if (command[0] != H4_EVT) + { + return -EIO; + } + + hci_recv(filep, command + 1, sizeof(struct bt_hci_evt_hdr)); + hci_recv(filep, command + 3, command[2]); + + /* Check OpCode and Status */ + + if (!(command[4] == 0x4a && command[5] == 0xfd) || command[6] != 0x00) + { + return -EIO; + } + } + + if (hci_start_iqk()) + { + return -EIO; + } + + return 0; +} + +#endif +static int hci_check_local_ver(FAR struct file *filep) +{ + /* OpCode: 0x1001, h4 buf_len: Cmd(1+3=4), Event(1+14=15) */ + + unsigned char command[15]; + command[0] = H4_CMD; + command[1] = 0x01; + command[2] = 0x10; + command[3] = 0; + if (hci_send(filep, command, 4) != 4) + { + return -EIO; + } + + hci_recv(filep, command, 1); + if (command[0] != H4_EVT) + { + return -EIO; + } + + hci_recv(filep, command + 1, sizeof(struct bt_hci_evt_hdr)); + hci_recv(filep, command + 3, command[2]); + + /* Check OpCode and Status */ + + if (!(command[4] == 0x01 && command[5] == 0x10) || command[6] != 0x00) + { + return -EIO; + } + + /* Only Check LMP Subversion */ + + uint16_t lmp_sbuver = + ((uint16_t)command[13]) | (((uint16_t)command[14]) << 8); + if (BT_DEFAUT_LMP_SUBVER != lmp_sbuver) + { + return -EALREADY; + } + + return 0; +} + +static int hci_check_local_rom_ver(FAR struct file *filep) +{ + /* OpCode: 0xfc6d, h4 buf_len: Cmd(1+3=4), Event(1+7=8) */ + + unsigned char command[8]; + command[0] = H4_CMD; + command[1] = 0x6d; + command[2] = 0xfc; + command[3] = 0; + if (hci_send(filep, command, 4) != 4) + { + return -EIO; + } + + hci_recv(filep, command, 1); + if (command[0] != H4_EVT) + { + return -EIO; + } + + hci_recv(filep, command + 1, sizeof(struct bt_hci_evt_hdr)); + hci_recv(filep, command + 3, command[2]); + + /* Check OpCode and Status */ + + if (!(command[4] == 0x6d && command[5] == 0xfc) || command[6] != 0x00) + { + return -EIO; + } + + /* Get Chip Id (Rom_Ver+1) and Find Patch */ + + if (hci_find_fw_patch(command[7] + 1)) + { + return -EIO; + } + + return 0; +} + +static int hci_update_baudrate(FAR struct file *filep) +{ + /* OpCode: 0xfc17, h4 buf_len: Cmd(1+7=8), Event(1+6=7) */ + + unsigned char command[8]; + struct termios toptions; + uint32_t bt_baudrate; + uint32_t uart_baudrate; + command[0] = H4_CMD; + command[1] = 0x17; + command[2] = 0xfc; + command[3] = sizeof(uint32_t); + if (hci_get_baudrate(&bt_baudrate, &uart_baudrate)) + { + return -EIO; + } + + memcpy(&command[4], &bt_baudrate, sizeof(uint32_t)); + if (hci_send(filep, command, 8) != 8) + { + return -EIO; + } + + hci_recv(filep, command, 1); + if (command[0] != H4_EVT) + { + return -EIO; + } + + hci_recv(filep, command + 1, sizeof(struct bt_hci_evt_hdr)); + hci_recv(filep, command + 3, command[2]); + + /* Check OpCode and Status */ + + if (!(command[4] == 0x17 && command[5] == 0xfc) || command[6] != 0x00) + { + return -EIO; + } + + file_ioctl(filep, TCGETS, (unsigned long)&toptions); + cfsetispeed(&toptions, uart_baudrate); + cfsetospeed(&toptions, uart_baudrate); + return file_ioctl(filep, TCSETS, (unsigned long)&toptions); +} + +static int hci_load_firmware(FAR struct file *filep) +{ + int header_size = HCI_H4_HDR_SIZE + HCI_CMD_HDR_SIZE; + uint8_t command[AMEBAZ_COMMAND_FRAGMENT_SIZE + header_size]; + FAR struct net_driver_s *drv; + int buffer_size; + uint8_t *addr; + int i; + int ret; + drv = netdev_findbyname(AMEBAZ_WIRELESS_NAME); + if (drv == NULL) + { + return -EINVAL; + } + + addr = drv->d_mac.ether.ether_addr_octet; + if (hci_set_init_config_mac(addr, 1)) + { + return -EIO; + } + + while (hci_fetch_command(command) != AMEBAZ_COMMAND_DONE) + { + command[0] = H4_CMD; + command[1] = 0x20; + command[2] = 0xfc; + buffer_size = header_size + command[3]; + usleep(10); + ret = hci_send(filep, command, buffer_size); + if (ret != buffer_size) + { + return ret; + } + + hci_recv(filep, command, 1); + if (H4_EVT != command[0]) + { + return -EIO; + } + + hci_recv(filep, command + 1, 2); + hci_recv(filep, command + 3, command[2]); + + /* Check OpCode and Status */ + + if (!(command[4] == 0x20 && command[5] == 0xfc) || command[6] != 0x00) + { + return -EIO; + } + } + + return OK; +} + +static int hci_update_efuse_iqk(FAR struct file *filep) +{ + /* OpCode: 0xfd91, h4 buf_len: Cmd(1+15=16), Event(1+6=7) */ + + unsigned char command[16]; + command[0] = H4_CMD; + command[1] = 0x91; + command[2] = 0xfd; + if (hci_get_efuse_iqk_data(command + 3)) + { + return -EIO; + } + + if (hci_send(filep, command, sizeof(command)) != sizeof(command)) + { + return -EIO; + } + + hci_recv(filep, command, 1); + if (command[0] != H4_EVT) + { + return -EIO; + } + + hci_recv(filep, command + 1, sizeof(struct bt_hci_evt_hdr)); + hci_recv(filep, command + 3, command[2]); + return 0; +} + +static int hci_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR hci_dev_t *dev = inode->i_private; + int ret; + ret = file_open(&dev->filep, + CONFIG_AMEBA_HCI_DEV_NAME, O_RDWR | O_BINARY); + if (ret < 0) + { + return ret; + } + + if (hci_board_init()) + { + goto bail; + } + +#ifdef HCI_START_IQK + ret = hci_do_iqk(&dev->filep); + if (ret < 0) + { + goto bail; + } + +#endif + ret = hci_check_local_ver(&dev->filep); + if (ret < 0) + { + if (-EALREADY == ret) + { + ret = 0; + } + + goto bail; + } + + ret = hci_check_local_rom_ver(&dev->filep); + if (ret < 0) + { + goto bail; + } + + ret = hci_update_baudrate(&dev->filep); + if (ret < 0) + { + goto bail; + } + + ret = hci_load_firmware(&dev->filep); + if (ret < 0) + { + goto bail; + } + + ret = hci_update_efuse_iqk(&dev->filep); +bail: + ret = hci_board_init_done(); + if (ret < 0) + { + file_close(&dev->filep); + } + + return ret; +} + +static int hci_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR hci_dev_t *dev = inode->i_private; + + /* FIXME: BT PowerOff */ + + return file_close(&dev->filep); +} + +static ssize_t hci_read(FAR struct file *filep, + FAR char *buffer, size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR hci_dev_t *dev = inode->i_private; + return file_read(&dev->filep, buffer, buflen); +} + +static ssize_t hci_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR hci_dev_t *dev = inode->i_private; + return file_write(&dev->filep, buffer, buflen); +} + +static int hci_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR hci_dev_t *dev = inode->i_private; + return file_ioctl(&dev->filep, cmd, arg); +} + +static int hci_poll(FAR struct file *filep, + FAR struct pollfd *fds, bool setup) +{ + FAR struct inode *inode = filep->f_inode; + FAR hci_dev_t *dev = inode->i_private; + return file_poll(&dev->filep, fds, setup); +} + +static hci_dev_t g_hcidev = +{ + .i_ops = + { + .open = hci_open, + .close = hci_close, + .read = hci_read, + .write = hci_write, + .ioctl = hci_ioctl, + .poll = hci_poll + }, +}; + +int amebaz_bt_hci_uart_register(FAR const char *path) +{ + return register_driver(path, &g_hcidev.i_ops, 0666, &g_hcidev); +} + diff --git a/arch/arm/src/rtl8720c/ameba_heap.c b/arch/arm/src/rtl8720c/ameba_heap.c new file mode 100644 index 00000000000..f4ae9714c5b --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_heap.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_heap.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "chip.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define _START_HEAP ((uintptr_t)&__bss_end__) +#define _END_HEAP ((uintptr_t)&__sram_end__) +#ifdef CONFIG_HEAP_COLORATION +# define song_heap_color(start, size) memset(start, HEAP_COLOR, size) +#else +# define song_heap_color(start, size) +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern uint32_t __stack; +extern uint32_t __bss_end__; +extern uint32_t __sram_end__; +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +const uintptr_t __attribute__((weak)) g_idle_topstack = + ((uintptr_t)&__stack); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + * The following memory map is assumed for the flat build: + * + * .data region. Size determined at link time. + * .bss region Size determined at link time. + * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE. + * Heap. Extends to the end of SRAM. + * + * The following memory map is assumed for the kernel build: + * + * Kernel .data region. Size determined at link time. + * Kernel .bss region Size determined at link time. + * Kernel IDLE thread stack. Size determined by + * CONFIG_IDLETHREAD_STACKSIZE. + * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE. + * Padding for alignment + * User .data region. Size determined at link time. + * User .bss region Size determined at link time. + * User heap. Extends to the end of SRAM. + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + /* Return the heap settings */ + + *heap_start = (FAR void *)_START_HEAP; + *heap_size = _END_HEAP - _START_HEAP; + + /* Colorize the heap for debug */ + + song_heap_color(*heap_start, *heap_size); +} + diff --git a/arch/arm/src/rtl8720c/ameba_idle.c b/arch/arm/src/rtl8720c/ameba_idle.c new file mode 100644 index 00000000000..274ff493585 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_idle.c @@ -0,0 +1,66 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_idle.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + ****************************************************************************/ + +# define up_idlepm() up_cpu_idle() + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed + * when their is no other ready-to-run task. This is processor + * idle time and will continue until some interrupt occurs to + * cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., + * this is where power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +} + diff --git a/arch/arm/src/rtl8720c/ameba_lto.S b/arch/arm/src/rtl8720c/ameba_lto.S new file mode 100644 index 00000000000..30900f35f26 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_lto.S @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_lto.S + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .syntax unified + .arch armv8-m.main + .thumb + .file "ameba_lto.S" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + + .text + .thumb_func + .globl ameba_lto + .globl __aeabi_d2iz + .globl __aeabi_d2lz + .globl __aeabi_d2ulz + .globl __aeabi_dcmpeq + .globl __aeabi_dcmpge + .globl __aeabi_dcmplt + .globl __aeabi_ddiv + .globl __aeabi_fadd + .globl __aeabi_fcmpge + .globl __aeabi_fcmpgt + .globl __aeabi_fdiv + .globl __aeabi_fmul + .globl __aeabi_i2f + .globl __aeabi_idivmod + .globl __aeabi_ldivmod + .globl __aeabi_llsl + .globl __aeabi_llsr + .globl __aeabi_lmul + .globl __aeabi_uidiv + .globl __aeabi_uldivmod + .globl __bswapsi2 + .globl __clzsi2 + .globl __ctzsi2 + .globl __gnu_thumb1_case_shi + .globl __gnu_thumb1_case_si + .globl __gnu_thumb1_case_sqi + .globl __gnu_thumb1_case_uhi + .globl __gnu_thumb1_case_uqi + .globl __gnu_thumb1_case_uqi + .globl __popcountsi2 + .type ameba_lto, function +ameba_lto: + .size ameba_lto, .-ameba_lto + .end diff --git a/arch/arm/src/rtl8720c/ameba_nvic.c b/arch/arm/src/rtl8720c/ameba_nvic.c new file mode 100644 index 00000000000..6947a87f00c --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_nvic.c @@ -0,0 +1,458 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_nvic.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#ifdef CONFIG_ARCH_CORTEXM33 +#include +#include +#include +#include +#include "sched/sched.h" +#include "chip.h" +#include "nvic.h" +#include "ram_vectors.h" +#include "arm_arch.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ROUND_DOWN(v, q) (((v) / (q)) * (q)) + +/* Get a 32-bit version of the default priority */ + +#define NVIC_PRIORITY_DEFAULT32 (NVIC_SYSH_PRIORITY_DEFAULT << 24 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | \ + NVIC_SYSH_PRIORITY_DEFAULT) +/* Given the address of a NVIC ENABLE register, this is the offset to + * the corresponding NVIC CLEAR register. + */ +#define NVIC_ENABLE_OFFSET (NVIC_IRQ0_31_ENABLE - NVIC_IRQ0_31_ENABLE) +#define NVIC_CLEAR_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ +#ifdef CONFIG_SMP +volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; +#else +volatile uint32_t *g_current_regs[1]; +#endif + +/* extern int32_t __StackLimit; */ + +extern uint32_t _vectors[]; + +/**************************************************************************** + * Private Function Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static int (* __vectors[NR_IRQS - NVIC_IRQ_FIRST])(void); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +static inline uint32_t up_getsp(void) +{ + uint32_t sp; + __asm__ + ( + "\tmov %0, sp\n\t" + : "=r"(sp) + ); + return sp; +} + +/**************************************************************************** + * Name: nvic_irqinfo + * + * Description: + * Given an IRQ number, provide the register and bit setting to enable or + * disable the irq. + * + ****************************************************************************/ + +static int nvic_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, + uintptr_t offset) +{ + DEBUGASSERT(irq >= NVIC_IRQ_MEMFAULT && irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= NVIC_IRQ_FIRST) + { + irq = irq - NVIC_IRQ_FIRST; + *regaddr = NVIC_IRQ_ENABLE(irq) + offset; + *bit = (uint32_t)1 << (irq & 0x1f); + } + + /* Handle processor exceptions. Only a few can be disabled */ + + else + { + *regaddr = NVIC_SYSHCON; + if (irq == NVIC_IRQ_MEMFAULT) + { + *bit = NVIC_SYSHCON_MEMFAULTENA; + } + + else if (irq == NVIC_IRQ_BUSFAULT) + { + *bit = NVIC_SYSHCON_BUSFAULTENA; + } + + else if (irq == NVIC_IRQ_USAGEFAULT) + { + *bit = NVIC_SYSHCON_USGFAULTENA; + } + + else if (irq == NVIC_IRQ_DBGMONITOR) + { + *regaddr = NVIC_DEMCR; + *bit = NVIC_DEMCR_MONEN; + } + + else if (irq == NVIC_IRQ_SYSTICK) + { + *regaddr = NVIC_SYSTICK_CTRL; + *bit = NVIC_SYSTICK_CTRL_TICKINT; + } + + else + { + return ERROR; /* Invalid or unsupported exception */ + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void weak_function up_wic_initialize(void) +{ +} + +void weak_function up_wic_enable_irq(int irq) +{ +} + +void weak_function up_wic_disable_irq(int irq) +{ +} + +/**************************************************************************** + * Name: arm_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void arm_ack_irq(int irq) +{ +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * This function implements disabling of the device specified by 'irq' + * at the interrupt controller level if supported by the architecture + * (up_irq_save() supports the global level, the device level is hardware + * specific). + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t bit; + if (nvic_irqinfo(irq, ®addr, &bit, NVIC_CLEAR_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to disable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Clear Enable register. For other exceptions, we need to + * clear the bit in the System Handler Control and State Register. + */ + + if (irq >= NVIC_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + + else + { + modifyreg32(regaddr, bit, 0); + } + + up_wic_disable_irq(irq); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * On many architectures, there are three levels of interrupt enabling: (1) + * at the global level, (2) at the level of the interrupt controller, + * and (3) at the device level. In order to receive interrupts, they + * must be enabled at all three levels. + * + * This function implements enabling of the device specified by 'irq' + * at the interrupt controller level if supported by the architecture + * (up_irq_restore() supports the global level, the device level is + * hardware specific). + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + uintptr_t regaddr; + uint32_t bit; + if (nvic_irqinfo(irq, ®addr, &bit, NVIC_ENABLE_OFFSET) == 0) + { + /* Modify the appropriate bit in the register to enable the interrupt. + * For normal interrupts, we need to set the bit in the associated + * Interrupt Set Enable register. For other exceptions, we need to + * set the bit in the System Handler Control and State Register. + */ + + if (irq >= NVIC_IRQ_FIRST) + { + putreg32(bit, regaddr); + } + + else + { + modifyreg32(regaddr, 0, bit); + } + + up_wic_enable_irq(irq); + } +} + +/**************************************************************************** + * Name: up_trigger_irq + * + * Description: + * Trigger an IRQ by software. + * + ****************************************************************************/ + +void up_trigger_irq(int irq) +{ + uint32_t pend_bit = 0; + DEBUGASSERT(irq >= NVIC_IRQ_NMI && irq < NR_IRQS); + if (irq >= NVIC_IRQ_FIRST) + { + putreg32(irq - NVIC_IRQ_FIRST, NVIC_STIR); + } + + else + { + switch (irq) + { + case NVIC_IRQ_PENDSV: + pend_bit = NVIC_INTCTRL_PENDSVSET; + break; + case NVIC_IRQ_NMI: + pend_bit = NVIC_INTCTRL_NMIPENDSET; + break; + case NVIC_IRQ_SYSTICK: + pend_bit = NVIC_INTCTRL_PENDSTSET; + break; + } + + if (pend_bit) + { + modifyreg32(NVIC_INTCTRL, 0, pend_bit); + } + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +int up_prioritize_irq(int irq, int priority) +{ + uint32_t regaddr; + int shift; + DEBUGASSERT(irq >= NVIC_IRQ_MEMFAULT && irq < NR_IRQS && + priority >= NVIC_SYSH_PRIORITY_MAX && + priority <= NVIC_SYSH_PRIORITY_MIN); + if (irq < NVIC_IRQ_FIRST) + { + /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority + * registers (0-3 are invalid) + */ + + regaddr = NVIC_SYSH_PRIORITY(irq); + irq -= NVIC_IRQ_MEMFAULT; + } + + else + { + /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */ + + irq -= NVIC_IRQ_FIRST; + regaddr = NVIC_IRQ_PRIORITY(irq); + } + + shift = (irq & 3) << 3; + modifyreg32(regaddr, 0xff << shift, priority << shift); + return OK; +} + +/**************************************************************************** + * Name: _up_doirq + ****************************************************************************/ + +int _up_doirq(int irq, FAR void *context, FAR void *arg) +{ + if (irq < NVIC_IRQ_FIRST) + { + return ERROR; + } + + __vectors[irq - NVIC_IRQ_FIRST](); + return OK; +} + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int i; + + /* Disable all interrupts */ + + for (i = 0; i < NR_IRQS - NVIC_IRQ_FIRST; i += 32) + { + putreg32(0xffffffff, NVIC_IRQ_CLEAR(i)); + } + + /* Restore the NVIC vector location to local */ + + memcpy(&__vectors, (void *) * (volatile uint32_t *)(NVIC_VECTAB) + + NVIC_IRQ_FIRST * sizeof(uint32_t), sizeof(__vectors)); + + /* Set the NVIC vector location in case _vectors not equal zero. */ + + putreg32((uint32_t)_vectors, NVIC_VECTAB); + /* Now bits[7-5] are available in each 8bits, + * Take bits[7-6] as group priority, take bit[5] as subpriorities. + */ + + modifyreg32(NVIC_AIRCR, NVIC_AIRCR_VECTKEY_MASK | NVIC_AIRCR_PRIGROUP_MASK, + (0x5fa << NVIC_AIRCR_VECTKEY_SHIFT) | (0x5 << NVIC_AIRCR_PRIGROUP_SHIFT)); + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(NVIC_PRIORITY_DEFAULT32, NVIC_SYSH4_7_PRIORITY); + putreg32(NVIC_PRIORITY_DEFAULT32, NVIC_SYSH8_11_PRIORITY); + putreg32(NVIC_PRIORITY_DEFAULT32, NVIC_SYSH12_15_PRIORITY); + for (i = 0; i < NR_IRQS - NVIC_IRQ_FIRST; i += 4) + { + putreg32(NVIC_PRIORITY_DEFAULT32, NVIC_IRQ_PRIORITY(i)); + } + + up_wic_initialize(); + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(NVIC_IRQ_SVCALL, arm_svcall, NULL); + up_prioritize_irq(NVIC_IRQ_SVCALL, NVIC_SYSH_SVCALL_PRIORITY); + irq_attach(NVIC_IRQ_HARDFAULT, arm_hardfault, NULL); + + /* Attach and enable the Memory Management Fault handler */ + + irq_attach(NVIC_IRQ_MEMFAULT, arm_memfault, NULL); + up_enable_irq(NVIC_IRQ_MEMFAULT); + + /* Attach and enable the external interrupts */ + + for (i = NVIC_IRQ_FIRST; i < NR_IRQS; i++) + { + irq_attach(i, _up_doirq, NULL); + } + + up_disable_irq(NVIC_IRQ_BUSFAULT); + up_disable_irq(NVIC_IRQ_USAGEFAULT); + + /* And finally, enable interrupts */ + + up_irq_enable(); +} + +void up_irq_attach_workaround(void) +{ + extern void exception_common(void); + __vectors[NVIC_IRQ_WLAN - NVIC_IRQ_FIRST] = + (void *) *((uint32_t *) *(volatile uint32_t *)NVIC_VECTAB + + NVIC_IRQ_WLAN); + *((uint32_t *) * (volatile uint32_t *)NVIC_VECTAB + NVIC_IRQ_WLAN) = + (unsigned)exception_common; + up_prioritize_irq(NVIC_IRQ_WLAN, NVIC_SYSH_PRIORITY_DEFAULT); +} + +#endif diff --git a/arch/arm/src/rtl8720c/ameba_start.c b/arch/arm/src/rtl8720c/ameba_start.c new file mode 100644 index 00000000000..813becd5aed --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_start.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_start.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "arm_internal.h" +#include "rtl8710c_irq.h" +#include + +extern void ram_start(void); +extern void ameba_lto(void); +const hal_irq_api_t sys_irq_api = +{ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV8M_STACKCHECK + +/* We need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__((no_instrument_function)); +#endif +void __start(void) +{ +#ifdef CONFIG_ARMV8M_STACKCHECK + + /* Set the stack limit before we attempt to call any functions */ + + #define STACKSIZE_TEMP CONFIG_IDLETHREAD_STACKSIZE + __asm__ volatile("sub r10, sp, %0" : : "r" (STACKSIZE_TEMP - 64) :); +#endif + ram_start(); +} + +void mpu_init(void) +{ +} + +void promisc_deinit(void *padapter) +{ +} + +int promisc_recv_func(void *padapter, void *rframe) +{ + return 0; +} + +int promisc_recv_lens_func(void *padapter, uint8_t *payload, uint8_t plen) +{ + return 0; +} + +void app_start(void) +{ + __asm volatile("MSR msplim, %0" : : "r"(0)); + arm_earlyserialinit(); +#ifdef CONFIG_MBEDTLS240_AMEBAZ_HARDWARE_CRYPTO + extern int mbedtls_platform_set_calloc_free( + void *(*calloc_func)(size_t, size_t), void (*free_func)(void *)); + extern int chip_platform_set_malloc_free( + void *(*ssl_calloc)(unsigned int, unsigned int), + void (*ssl_free)(void *)); + mbedtls_platform_set_calloc_free(calloc, free); + chip_platform_set_malloc_free(calloc, free); +#endif + nx_start(); + ameba_lto(); +} + diff --git a/arch/arm/src/rtl8720c/ameba_uart.c b/arch/arm/src/rtl8720c/ameba_uart.c new file mode 100644 index 00000000000..377b60f3a10 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_uart.c @@ -0,0 +1,1097 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_uart.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ameba_uart.h" +#include +#ifdef CONFIG_AMEBA_UART + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum +{ + UART_0 = 0, /* !< 1-byte */ + UART_1 = 1, /* !< 4-byte/8-byte(for 8195B/8710C) */ + UART_2 = 2, /* !< 8-byte/16-byte(for 8195B/8710C) */ + UART_3 = 3, /* !< 14-byte/30-bytes(for 8195B/8710C) */ + MAX_UART_NUM = 4 +}; + +enum +{ + UART_PIN_TX = 0, + UART_PIN_RX = 1, + UART_PIN_RTS = 2, + UART_PIN_CTS = 3 +}; + +enum +{ + PIN_PULLNONE = 0, + PIN_PULLDOWN = 1, + PIN_PULLUP = 2, + PIN_PULLDEFAULT = PIN_PULLNONE +}; + +enum +{ + FIFOLV1BYTE = 0, /* !< 1-byte */ + FIFOLVQUARTER = 1, /* !< 4-byte/8-byte(for 8195B/8710C) */ + FIFOLVHALF = 2, /* !< 8-byte/16-byte(for 8195B/8710C) */ + FIFOLVFULL = 3 /* !< 14-byte/30-bytes(for 8195B/8710C) */ +}; + +enum +{ + FLOWCONTROLNONE, /* !priv; + int uart_idx; + uart_idx = hal_uart_stubs.hal_uart_pin_to_idx(priv->rx, UART_PIN_RX); + if (uart_idx != hal_uart_stubs.hal_uart_pin_to_idx(priv->tx, UART_PIN_TX) + || uart_idx > MAX_UART_PORT) + { + return -EINVAL; + } + + if (!priv->adapter.is_inited) + { + if (uart_idx <= UART_2) + { + hal_gpio_stubs.hal_gpio_pull_ctrl(priv->rx, PIN_PULLUP); + } + + if (uart_idx == UART_0) + { + hal_syson_wakeup_uart_func_reset(); + } + + else if (uart_idx == UART_2) + { + priv->adapter.is_inited = true; + } + + status = hal_uart_stubs.hal_uart_init(&priv->adapter, + priv->tx, priv->rx, NULL); + if (status != OK) + { + return status; + } + + if (uart_idx < UART_2) + { + hal_pinmux_register(priv->tx, (PID_UART0 + uart_idx)); + hal_pinmux_register(priv->rx, (PID_UART0 + uart_idx)); + } + + if (uart_idx == UART_3) + { + priv->adapter.base_addr->fcr_b.rxfifo_trigger_level = FIFOLVHALF; + hal_uart_stubs.hal_uart_set_flow_control(&priv->adapter, + FLOWCONTROLRTS); + } + + else + { + priv->adapter.base_addr->fcr_b.rxfifo_trigger_level = FIFOLV1BYTE; + hal_uart_stubs.hal_uart_set_flow_control(&priv->adapter, + FLOWCONTROLNONE); + } + } + + status = hal_uart_stubs.hal_uart_set_baudrate(&priv->adapter, priv->baud); + if (status != OK) + { + return status; + } + + status = hal_uart_stubs.hal_uart_set_format(&priv->adapter, + priv->bits, priv->parity, priv->stopbits2 ? 2 : 1); +#endif + return status; +} + +/**************************************************************************** + * Name: ameba_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void ameba_shutdown(struct uart_dev_s *dev) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + uint32_t uart_idx = priv->adapter.uart_idx; + if (uart_idx == UART_2) + { + priv->adapter.is_inited = false; + } + + hal_uart_stubs.hal_uart_deinit(&priv->adapter); + if (uart_idx > UART_2) + { + return; + } + + hal_pinmux_unregister(priv->adapter.tx_pin, (PID_UART0 + uart_idx)); + hal_pinmux_unregister(priv->adapter.rx_pin, (PID_UART0 + uart_idx)); +} + +/**************************************************************************** + * Name: ameba_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). The RX and + * TX interrupts are not enabled until the txint() and rxint() methods are + * called + * + ****************************************************************************/ + +static int ameba_attach(struct uart_dev_s *dev) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + hal_uart_stubs.hal_uart_txtd_hook(&priv->adapter, + ameba_interrupt, (uintptr_t)dev, 0); + hal_uart_stubs.hal_uart_rxind_hook(&priv->adapter, + ameba_interrupt, (uintptr_t)dev, 1); + return OK; +} + +/**************************************************************************** + * Name: ameba_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void ameba_detach(FAR struct uart_dev_s *dev) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + hal_uart_stubs.hal_uart_txtd_hook(&priv->adapter, + NULL, (uintptr_t)NULL, 0); + hal_uart_stubs.hal_uart_rxind_hook(&priv->adapter, + NULL, (uintptr_t)NULL, 0); +} + +/**************************************************************************** + * Name: ameba_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate ameba_s structure in order to call these functions. + * + ****************************************************************************/ + +static void ameba_interrupt(uint32_t id, uint32_t event) +{ + struct uart_dev_s *dev = (struct uart_dev_s *)id; + if (event == 0) + { + uart_xmitchars(dev); + } + + else + { + uart_recvchars(dev); + } +} + +/**************************************************************************** + * Name: ameba_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int ameba_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + int ret; +#ifdef CONFIG_SERIAL_UART_ARCH_IOCTL + ret = uart_ioctl(filep, cmd, arg); + if (ret != -ENOTTY) + { + return ret; + } + +#else + ret = OK; +#endif + switch (cmd) + { +#if defined(CONFIG_SERIAL_TERMIOS) && !defined(CONFIG_AMEBA_SUPRESS_CONFIG) + case TCGETS: + { + FAR struct termios *termiosp = (FAR struct termios *)arg; + irqstate_t flags; + if (!termiosp) + { + ret = -EINVAL; + break; + } + + flags = enter_critical_section(); + cfsetispeed(termiosp, priv->baud); + termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0); + termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + termiosp->c_cflag |= priv->flow ? CRTSCTS : 0; +#endif + switch (priv->bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + case 6: + termiosp->c_cflag |= CS6; + break; + case 7: + termiosp->c_cflag |= CS7; + break; + case 8: + default: + termiosp->c_cflag |= CS8; + break; + } + + leave_critical_section(flags); + } + + break; + case TCSETS: + { + FAR struct termios *termiosp = (FAR struct termios *)arg; + irqstate_t flags; + if (!termiosp) + { + ret = -EINVAL; + break; + } + + flags = enter_critical_section(); + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + priv->bits = 5; + break; + case CS6: + priv->bits = 6; + break; + case CS7: + priv->bits = 7; + break; + case CS8: + default: + priv->bits = 8; + break; + } + + if ((termiosp->c_cflag & PARENB) != 0) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + + else + { + priv->parity = 0; + } + + priv->baud = cfgetispeed(termiosp); + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + priv->flow = (termiosp->c_cflag & CRTSCTS) != 0; +#endif + ameba_setup(dev); + leave_critical_section(flags); + } + + break; +#endif + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: ameba_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int ameba_receive(struct uart_dev_s *dev, uint32_t *status) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + return hal_uart_stubs.hal_uart_getc(&priv->adapter); +} + +/**************************************************************************** + * Name: ameba_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void ameba_rxint(struct uart_dev_s *dev, bool enable) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + hal_uart_stubs.hal_uart_set_rts(&priv->adapter, enable); +} + +/**************************************************************************** + * Name: ameba_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool ameba_rxavailable(struct uart_dev_s *dev) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + return hal_uart_stubs.hal_uart_readable(&priv->adapter); +} + +/**************************************************************************** + * Name: ameba_dma* + * + * Description: + * Stubbed out DMA-related methods + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool ameba_rxflowcontrol(struct uart_dev_s *dev, + unsigned int nbuffered, + bool upper) +{ + return false; +} + +#endif + +/**************************************************************************** + * Name: ameba_dma* + * + * Description: + * Stub functions used when serial DMA is enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_TXDMA +static void ameba_dmasend(FAR struct uart_dev_s *dev) +{ +} + +#endif +#ifdef CONFIG_SERIAL_RXDMA +static void ameba_dmareceive(FAR struct uart_dev_s *dev) +{ +} + +static void ameba_dmarxfree(FAR struct uart_dev_s *dev) +{ +} + +#endif +#ifdef CONFIG_SERIAL_TXDMA +static void ameba_dmatxavail(FAR struct uart_dev_s *dev) +{ +} + +#endif + +/**************************************************************************** + * Name: ameba_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void ameba_send(struct uart_dev_s *dev, int ch) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + while (hal_uart_stubs.hal_uart_writeable(&priv->adapter) == 0); + hal_uart_stubs.hal_uart_putc(&priv->adapter, ch); +} + +/**************************************************************************** + * Name: ameba_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void ameba_txint(struct uart_dev_s *dev, bool enable) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + priv->adapter.base_addr->ier_b.etbei = enable; + if (enable) + { + uart_xmitchars(dev); + } +} + +/**************************************************************************** + * Name: ameba_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool ameba_txready(struct uart_dev_s *dev) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + return hal_uart_stubs.hal_uart_writeable(&priv->adapter); +} + +/**************************************************************************** + * Name: ameba_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool ameba_txempty(struct uart_dev_s *dev) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)dev->priv; + return priv->adapter.base_addr->tflvr_b.tx_fifo_lv > 0 ? 0 : 1; +} + +/**************************************************************************** + * Name: ameba_putc + * + * Description: + * Write one character to the UART (polled) + * + ****************************************************************************/ + +#ifdef HAVE_AMEBA_CONSOLE +static void ameba_putc(FAR struct ameba_s *priv, int ch) +{ + while (hal_uart_stubs.hal_uart_writeable(&priv->adapter) == 0); + hal_uart_stubs.hal_uart_putc(&priv->adapter, ch); +} + +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before uart_serialinit. + * + * NOTE: Configuration of the CONSOLE UART was performed by uart_lowsetup() + * very early in the boot sequence. + * + ****************************************************************************/ + +void arm_earlyserialinit(void) +{ + /* Configuration whichever one is the console */ + +#ifdef CONSOLE_DEV + CONSOLE_DEV.isconsole = true; +#ifndef CONFIG_AMEBA_SUPRESS_INITIAL_CONFIG + ameba_setup(&CONSOLE_DEV); +#endif +#endif +} + +/**************************************************************************** + * Name: arm_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * arm_earlyserialinit was called previously. + * + ****************************************************************************/ + +void arm_serialinit(void) +{ +#ifdef CONSOLE_DEV + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif +#ifdef TTYS0_DEV + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +#ifdef TTYS1_DEV + (void)uart_register("/dev/ttyS1", &TTYS1_DEV); +#endif +#ifdef TTYS2_DEV + (void)uart_register("/dev/ttyS2", &TTYS2_DEV); +#endif +#ifdef TTYS3_DEV + (void)uart_register("/dev/ttyS3", &TTYS3_DEV); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +#ifdef HAVE_AMEBA_CONSOLE +int up_putc(int ch) +{ + FAR struct ameba_s *priv = (FAR struct ameba_s *)CONSOLE_DEV.priv; + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + ameba_putc(priv, '\r'); + } + + ameba_putc(priv, ch); + return ch; +} + +#endif +#endif /* CONFIG_AMEBA_UART */ diff --git a/arch/arm/src/rtl8720c/ameba_uart.h b/arch/arm/src/rtl8720c/ameba_uart.h new file mode 100644 index 00000000000..9dd0a15a6ab --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_uart.h @@ -0,0 +1,178 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_uart.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SERIAL_UART_AMEBA_H +#define __INCLUDE_NUTTX_SERIAL_UART_AMEBA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#ifdef CONFIG_AMEBA_UART + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* CONFIGURATION */ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_AMEBA_UART0) || defined(CONFIG_AMEBA_UART1) || \ + defined(CONFIG_AMEBA_UART2) || defined(CONFIG_AMEBA_UART3) +# define HAVE_UART 1 +#endif +/* We need to be told the address increment between registers and + * the register bit width. + */ +#ifndef CONFIG_AMEBA_REGINCR +# error "CONFIG_AMEBA_REGINCR not defined" +#endif + +#if CONFIG_AMEBA_REGINCR != 1 && CONFIG_AMEBA_REGINCR != 2 && CONFIG_AMEBA_REGINCR != 4 +# error "CONFIG_AMEBA_REGINCR not supported" +#endif +#ifndef CONFIG_AMEBA_REGWIDTH +# error "CONFIG_AMEBA_REGWIDTH not defined" +#endif + +#if CONFIG_AMEBA_REGWIDTH != 8 && CONFIG_AMEBA_REGWIDTH != 16 && CONFIG_AMEBA_REGWIDTH != 32 +# error "CONFIG_AMEBA_REGWIDTH not supported" +#endif +#ifndef CONFIG_AMEBA_ADDRWIDTH +# error "CONFIG_AMEBA_ADDRWIDTH not defined" +#endif + +#if CONFIG_AMEBA_ADDRWIDTH != 8 && CONFIG_AMEBA_ADDRWIDTH != 16 && CONFIG_AMEBA_ADDRWIDTH != 32 +# error "CONFIG_AMEBA_ADDRWIDTH not supported" +#endif + +/* If a UART is enabled, then its base address, + * clock, and IRQ must also be provided + */ + +#ifdef CONFIG_AMEBA_UART0 +# ifndef CONFIG_AMEBA_UART0_TX_PIN +# error "CONFIG_AMEBA_UART0_TX_PIN not provided" +# undef CONFIG_AMEBA_UART0 +# endif +# ifndef CONFIG_AMEBA_UART0_RX_PIN +# error "CONFIG_AMEBA_UART0_RX_PIN not provided" +# undef CONFIG_AMEBA_UART0 +# endif +#endif +#ifdef CONFIG_AMEBA_UART1 +# ifndef CONFIG_AMEBA_UART1_TX_PIN +# error "CONFIG_AMEBA_UART1_TX_PIN not provided" +# undef CONFIG_AMEBA_UART1 +# endif +# ifndef CONFIG_AMEBA_UART1_RX_PIN +# error "CONFIG_AMEBA_UART1_RX_PIN not provided" +# undef CONFIG_AMEBA_UART1 +# endif +#endif +#ifdef CONFIG_AMEBA_UART2 +# ifndef CONFIG_AMEBA_UART2_TX_PIN +# error "CONFIG_AMEBA_UART2_TX_PIN not provided" +# undef CONFIG_AMEBA_UART2 +# endif +# ifndef CONFIG_AMEBA_UART2_RX_PIN +# error "CONFIG_AMEBA_UART2_RX_PIN not provided" +# undef CONFIG_AMEBA_UART2 +# endif +#endif +#ifdef CONFIG_AMEBA_UART3 +# ifndef CONFIG_AMEBA_UART3_TX_PIN +# error "CONFIG_AMEBA_UART3_TX_PIN not provided" +# undef CONFIG_AMEBA_UART3 +# endif +# ifndef CONFIG_AMEBA_UART3_RX_PIN +# error "CONFIG_AMEBA_UART3_RX_PIN not provided" +# undef CONFIG_AMEBA_UART3 +# endif +#endif +/* Is there a serial console? There should be at most one defined. + * It could be on any UARTn, n=0,1,2,3 + */ + +#if defined(CONFIG_AMEBA_UART0_SERIAL_CONSOLE) && defined(CONFIG_AMEBA_UART0) +# undef CONFIG_AMEBA_UART1_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART2_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART3_SERIAL_CONSOLE +# define HAVE_AMEBA_CONSOLE 1 +#elif defined(CONFIG_AMEBA_UART1_SERIAL_CONSOLE) && defined(CONFIG_AMEBA_UART1) +# undef CONFIG_AMEBA_UART0_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART2_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART3_SERIAL_CONSOLE +# define HAVE_AMEBA_CONSOLE 1 +#elif defined(CONFIG_AMEBA_UART2_SERIAL_CONSOLE) && defined(CONFIG_AMEBA_UART2) +# undef CONFIG_AMEBA_UART0_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART1_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART3_SERIAL_CONSOLE +# define HAVE_AMEBA_CONSOLE 1 +#elif defined(CONFIG_AMEBA_UART3_SERIAL_CONSOLE) && defined(CONFIG_AMEBA_UART3) +# undef CONFIG_AMEBA_UART0_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART1_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART2_SERIAL_CONSOLE +# define HAVE_AMEBA_CONSOLE 1 +#else +# undef CONFIG_AMEBA_UART0_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART1_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART2_SERIAL_CONSOLE +# undef CONFIG_AMEBA_UART3_SERIAL_CONSOLE +# undef HAVE_AMEBA_CONSOLE +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#if CONFIG_AMEBA_REGWIDTH == 8 +typedef uint8_t uart_datawidth_t; +#elif CONFIG_AMEBA_REGWIDTH == 16 +typedef uint16_t uart_datawidth_t; +#elif CONFIG_AMEBA_REGWIDTH == 32 +typedef uint32_t uart_datawidth_t; +#endif +#if CONFIG_AMEBA_ADDRWIDTH == 8 +typedef uint8_t uart_addrwidth_t; +#elif CONFIG_AMEBA_ADDRWIDTH == 16 +typedef uint16_t uart_addrwidth_t; +#elif CONFIG_AMEBA_ADDRWIDTH == 32 +typedef uint32_t uart_addrwidth_t; +#endif + +/**************************************************************************** + * Name: uart_getreg(), uart_putreg(), uart_ioctl() + * + * Description: + * These functions must be provided by the processor-specific code in order + * to correctly access AMEBA registers + * uart_ioctl() is optional to provide custom IOCTLs + * + ****************************************************************************/ + +struct file; /* Forward reference */ +int uart_ioctl(struct file *filep, int cmd, unsigned long arg); +#endif /* CONFIG_AMEBA_UART */ +#endif /* __INCLUDE_NUTTX_SERIAL_UART_AMEBA_H */ diff --git a/arch/arm/src/rtl8720c/ameba_vectors.c b/arch/arm/src/rtl8720c/ameba_vectors.c new file mode 100644 index 00000000000..88561f2f266 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_vectors.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_vectors.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +extern uint32_t __stack; +#define IDLE_STACK ((unsigned)&__stack - 4) +#ifndef ARMV8M_PERIPHERAL_INTERRUPTS +# error ARMV8M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Chip-specific entrypoint */ + +extern void ram_start(void); + +/* Common exception entrypoint */ + +extern void exception_common(void); + +/**************************************************************************** + * Public data + ****************************************************************************/ + +/* The v7m vector table consists of an array of function pointers, + * with the first + * slot (vector zero) used to hold the initial stack pointer. + * + * As all exceptions (interrupts) are routed via exception_common, + * we just need to + * fill this array with pointers to it. + * + * Note that the [ ... ] designated initialiser is a GCC extension. + */ + +unsigned _vectors[] __attribute__((section(".vectors"))) \ + __attribute__((aligned(0x100))) = +{ + /* Initial stack */ + + IDLE_STACK, + + /* Reset exception handler */ + + (unsigned) &ram_start, + + /* Vectors 2 - n point directly at the generic handler */ + + [2 ...(15 + ARMV8M_PERIPHERAL_INTERRUPTS)] = (unsigned) &exception_common +}; + diff --git a/arch/arm/src/rtl8720c/ameba_wdt.c b/arch/arm/src/rtl8720c/ameba_wdt.c new file mode 100644 index 00000000000..969a7070b33 --- /dev/null +++ b/arch/arm/src/rtl8720c/ameba_wdt.c @@ -0,0 +1,293 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/ameba_wdt.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "hal_wdt.h" +#if defined(CONFIG_WATCHDOG) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/** + * This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * well-known watchdog_lowerhalf_s structure. + */ + +struct ameba_lowerhalf_s +{ + FAR const struct watchdog_ops_s *ops; /* Lower half operations */ + uint32_t timeout; /* The (actual) selected timeout */ + uint32_t lastreset; /* The last reset time */ + bool started; /* true: The watchdog timer has + * been started + */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* "Lower half" driver methods */ + +static int ameba_start(FAR struct watchdog_lowerhalf_s *lower); +static int ameba_stop(FAR struct watchdog_lowerhalf_s *lower); +static int ameba_keepalive(FAR struct watchdog_lowerhalf_s *lower); +static int ameba_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status); +static int ameba_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* "Lower half" driver methods */ + +static const struct watchdog_ops_s g_wdgops = +{ + .start = ameba_start, + .stop = ameba_stop, + .keepalive = ameba_keepalive, + .getstatus = ameba_getstatus, + .settimeout = ameba_settimeout, + .capture = NULL, + .ioctl = NULL, +}; + +/* "Lower half" driver state */ + +static struct ameba_lowerhalf_s g_wdgdev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ameba_start + * + * Description: + * Start the watchdog timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation + * of the "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int ameba_start(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct ameba_lowerhalf_s *priv = (FAR struct ameba_lowerhalf_s *)lower; + irqstate_t flags; + flags = enter_critical_section(); + priv->started = true; + priv->lastreset = clock_systime_ticks(); + hal_misc_wdt_enable(); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: ameba_stop + * + * Description: + * Stop the watchdog timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int ameba_stop(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct ameba_lowerhalf_s *priv = (FAR struct ameba_lowerhalf_s *)lower; + irqstate_t flags; + flags = enter_critical_section(); + hal_misc_wdt_disable(); + priv->started = false; + priv->timeout = 0; + priv->lastreset = 0; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: ameba_keepalive + * + * Description: + * Reset the watchdog timer to the current timeout value, prevent any + * imminent watchdog timeouts. This is sometimes referred as "pinging" + * the watchdog timer or "petting the dog". + * + * The application program must write in the SAM_WDT_CLEAR register + * at regular intervals during normal operation to prevent an MCU reset. + * + * Input Parameters: + * lower - A pointer the publicly visible representation + * of the "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int ameba_keepalive(FAR struct watchdog_lowerhalf_s *lower) +{ + FAR struct ameba_lowerhalf_s *priv = (FAR struct ameba_lowerhalf_s *)lower; + irqstate_t flags; + + /* Reload the WDT timer */ + + flags = enter_critical_section(); + priv->lastreset = clock_systime_ticks(); + hal_misc_wdt_refresh(); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: ameba_getstatus + * + * Description: + * Get the current watchdog timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * status - The location to return the watchdog status information. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int ameba_getstatus(FAR struct watchdog_lowerhalf_s *lower, + FAR struct watchdog_status_s *status) +{ + FAR struct ameba_lowerhalf_s *priv = (FAR struct ameba_lowerhalf_s *)lower; + uint32_t elapsed; + uint32_t ticks; + + /* Return the status bit */ + + status->flags = WDFLAGS_RESET; + if (priv->started) + { + status->flags |= WDFLAGS_ACTIVE; + } + + /* Return the actual timeout in milliseconds */ + + status->timeout = priv->timeout; + + /* Get the elapsed time since the last ping */ + + ticks = clock_systime_ticks() - priv->lastreset; + elapsed = (int32_t)TICK2MSEC(ticks); + if (elapsed > priv->timeout) + { + elapsed = priv->timeout; + } + + /* Return the approximate time until the watchdog timer expiration */ + + status->timeleft = priv->timeout - elapsed; + return OK; +} + +/**************************************************************************** + * Name: ameba_settimeout + * + * Description: + * Set a new timeout value (and reset the watchdog timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * timeout - The new timeout value in millisecnds. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int ameba_settimeout(FAR struct watchdog_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct ameba_lowerhalf_s *priv = (FAR struct ameba_lowerhalf_s *)lower; + irqstate_t flags; + flags = enter_critical_section(); + priv->timeout = timeout; + hal_misc_wdt_init(timeout * 1000); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ameba_wdt_initialize + * + * Description: + * Initialize the WDT watchdog timer. The watchdog timer + * is initialized and registers as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the watchdog. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void ameba_wdt_initialize(void) +{ + FAR struct ameba_lowerhalf_s *priv = &g_wdgdev; + + /* Initialize the driver state structure. */ + + priv->ops = &g_wdgops; + (void)watchdog_register(CONFIG_WATCHDOG_DEVPATH, + (FAR struct watchdog_lowerhalf_s *)priv); +} + +#endif /* CONFIG_WATCHDOG */ diff --git a/arch/arm/src/rtl8720c/amebaz_coex.c b/arch/arm/src/rtl8720c/amebaz_coex.c new file mode 100644 index 00000000000..5ff7613e6d7 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_coex.c @@ -0,0 +1,220 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_coex.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "amebaz_coex.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define HCI_VENDOR_MAILBOX_CMD 0xfc8f + +/* static net_buf_simple *Xiaomi_buf; */ + +struct rtl_btinfo +{ + uint8_t cmd; + uint8_t len; + uint8_t data[6]; +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +unsigned int send_coex_mailbox_to_wifi_from_btapp(uint8_t state) +{ + uint8_t para[8]; + para[0] = 0x45; /* Mailbox ID */ + + para[1] = state; /* Data0 */ + + para[2] = 0; /* Data1 */ + + para[3] = 0; /* Data2 */ + + para[4] = 0; /* Data3 */ + + para[5] = 0; /* Data4 */ + + para[6] = 0; /* Data5 */ + + para[7] = 0; /* Data6 */ + + rltk_coex_mailbox_to_wifi(para, 8); + return 1; +} + +static void rtk_notify_info_to_wifi(uint8_t length, uint8_t *report_info) +{ + struct rtl_btinfo *report = (struct rtl_btinfo *)(report_info); + if (length) + { + printf("bt info: cmd %2.2X", report->cmd); + printf("bt info: len %2.2X", report->len); + printf("bt info: data %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X", + report->data[0], report->data[1], report->data[2], + report->data[3], report->data[4], report->data[5]); + } + + rltk_coex_mailbox_to_wifi(report_info, report->len + 2); + + /* send BT INFO to Wi-Fi driver */ +} + +void bt_coex_handle_cmd_complete_evt(uint16_t opcode, uint16_t cause, + uint8_t total_len, uint8_t *p) +{ + (void)cause; + if (opcode == HCI_VENDOR_MAILBOX_CMD) + { + uint8_t status; + status = *p++; /* jump the double subcmd */ + + total_len--; + if (total_len <= 1) + { + printf("bt_coex_handle_cmd_complete_evt: not reprot to wifi"); + return ; + } + + (void)status; + rltk_coex_mailbox_to_wifi(p, total_len); + + /* rtk_parse_vendor_mailbox_cmd_evt(p, total_len, status); */ + } +} + +void bt_coex_handle_specific_evt(uint8_t *p, uint8_t len) +{ + rltk_coex_mailbox_to_wifi(p, len); +} + +#ifndef MIN +# define MIN(a,b) (a < b ? a : b) +#endif +static const char *bt_hex_real(const void *buf, size_t len) +{ + static const char hex[] = "0123456789abcdef"; + static char str[129]; + const uint8_t *b = buf; + size_t i; + len = MIN(len, (sizeof(str) - 1) / 2); + for (i = 0; i < len; i++) + { + str[i * 2] = hex[b[i] >> 4]; + str[i * 2 + 1] = hex[b[i] & 0xf]; + } + + str[i * 2] = '\0'; + return str; +} + +static inline char *log_strdup(const char *str) +{ + return (char *)str; +} + +#define bt_hex(buf, len) log_strdup(bt_hex_real(buf, len)) +static void bt_coex_dump_buf(net_buf_simple *tmp_buf) +{ + printf("\n\r[%s] len=%d, buf = % s\n\r", __func__, + tmp_buf->len, + bt_hex(tmp_buf->data, + tmp_buf->len)); +} + +static int bt_coex_unpack_xiaomi_vendor_cmd(net_buf_simple *tmp_buf) +{ + if (tmp_buf-> data[0] == 0x25 && tmp_buf-> data[1] == 0x00) + { + tmp_buf -> data += 2; + tmp_buf -> len -= 2; + return 1; + } + + else + { + printf("[rtk_coex]Xiaomi vendor header not match.\n\r"); + return -1; + } +} + +bool bt_coex_handle_xiaomi_evt(net_buf_simple *xiaomi_buf) +{ + /* bt_coex_dump_buf(xiaomi_buf); */ + + bt_coex_unpack_xiaomi_vendor_cmd(xiaomi_buf); + + /* bt_coex_dump_buf(xiaomi_buf); */ + + rltk_coex_mailbox_to_wifi(xiaomi_buf->data, xiaomi_buf->len); + return true; +} + +typedef struct bt_sw_mailbox_info_s +{ + uint8_t data[8]; +}bt_sw_mailbox_info_t; + +static bt_sw_mailbox_info_t scan_enable; + +unsigned int bt_coex_sw_mailbox_set(unsigned int mailbox_control) +{ +#if 0 /* This function need to be removed */ + + uint8_t mailbox_len = 8; + memset(&scan_enable, 0, sizeof(scan_enable)); + switch (mailbox_control) + { + case BT_SW_MAILBOX_SCAN_OFF: + scan_enable.data[0] = 0x27; + scan_enable.data[1] = 6; + rtk_notify_info_to_wifi(mailbox_len, scan_enable.data); + break; + case BT_SW_MAILBOX_SCAN_ON: + scan_enable.data[0] = 0x27; + scan_enable.data[1] = 6; + scan_enable.data[5] = (0x0 | 0x1 << 5); /* BT scan EN bit */ + + rtk_notify_info_to_wifi(mailbox_len, scan_enable.data); + break; + default: + printf("[Err %s]No such sw mailbox command.\n\r", __func__); + break; + } + + return true; +#else + return true; +#endif +} + +void bt_coex_init(void) +{ + vendor_cmd_init(NULL); +} + diff --git a/arch/arm/src/rtl8720c/amebaz_coex.h b/arch/arm/src/rtl8720c/amebaz_coex.h new file mode 100644 index 00000000000..bac46e5c0c0 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_coex.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_coex.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +/* READ_ME + * Example usage + * \code{ble_app_main.c} + * + * void app_le_gap_init(void) + * { + * .... + * bt_coex_init(); + * } + * + */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BT_SW_MAILBOX_SCAN_OFF 0x00 +#define BT_SW_MAILBOX_SCAN_ON 0x01 + +typedef struct net_buf_simple_s +{ + /* * Pointer to the start of data in the buffer. */ + + uint8_t *data; + + /* * Length of the data behind the data pointer. */ + + uint16_t len; + + /* * Amount of data that this buffer can store. */ + + uint16_t size; + /** Start of the data storage. Not to be accessed directly + * (the data pointer should be used instead). + */ + + uint8_t *__buf; +} net_buf_simple; + +void bt_coex_handle_cmd_complete_evt(uint16_t opcode, + uint16_t cause, + uint8_t total_len, + uint8_t *p); +void bt_coex_handle_specific_evt(uint8_t *p, uint8_t len); +bool bt_coex_handle_xiaomi_evt(net_buf_simple *xiaomi_buf); +unsigned int bt_coex_sw_mailbox_set(unsigned int mailbox_control); +void bt_coex_init(void); +unsigned int send_coex_mailbox_to_wifi_from_btapp(uint8_t state); + diff --git a/arch/arm/src/rtl8720c/amebaz_depend.c b/arch/arm/src/rtl8720c/amebaz_depend.c new file mode 100644 index 00000000000..a40c088a242 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_depend.c @@ -0,0 +1,1108 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_depend.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "amebaz_depend.h" +#include +#include + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* stdio.h Wrapper Start */ + +int __wrap_printf(const char *fmt, ...) +{ + va_list ap; + int ret; + va_start(ap, fmt); + ret = nx_vsyslog(LOG_INFO, fmt, &ap); + va_end(ap); + return ret; +} + +/* stdio.h Wrapper End */ + +static int uxcriticalnesting = 0; + +/* Critical Opration Start */ + +void save_and_cli(void) +{ + enter_critical_section(); + uxcriticalnesting++; +} + +void restore_flags(void) +{ + ASSERT(uxcriticalnesting); + uxcriticalnesting--; + if (uxcriticalnesting == 0) + { + leave_critical_section(0); + } +} + +void rtw_enter_critical(void **plock, unsigned long *pirql) +{ + save_and_cli(); +} + +void rtw_exit_critical(void **plock, unsigned long *pirql) +{ + restore_flags(); +} + +void rtw_enter_critical_from_isr(void **plock, unsigned long *pirql) +{ + save_and_cli(); +} + +void rtw_exit_critical_from_isr(void **plock, unsigned long *pirql) +{ + restore_flags(); +} + +/* Critical Opration End */ + +/* arpa/inet.h Wrapper Start */ + +uint16_t _htons(uint16_t n) +{ + return htons(n); +} + +uint16_t _ntohs(uint16_t n) +{ + return _htons(n); +} + +/* arpa/inet.h Wrapper End */ + +/* stdlib.h Wrapper Start */ + +uint8_t *rtw_vmalloc(uint32_t n) +{ + return malloc(n); +} + +uint8_t *rtw_zvmalloc(uint32_t n) +{ + return calloc(1, n); +} + +void rtw_vmfree(uint8_t *pbuf, uint32_t n) +{ + return free(pbuf); +} + +uint8_t *rtw_malloc(uint32_t n) +{ + return rtw_vmalloc(n); +} + +uint8_t *rtw_zmalloc(uint32_t n) +{ + return rtw_zvmalloc(n); +} + +void rtw_mfree(uint8_t *pbuf, uint32_t n) +{ + return rtw_vmfree(pbuf, n); +} + +/* stdlib.h Wrapper End */ + +/* string.h Wrapper Start */ + +void rtw_memcpy(void *dst, void *src, uint32_t n) +{ + memcpy(dst, src, n); +} + +int rtw_memcmp(void *dst, void *src, uint32_t n) +{ + return memcmp(dst, src, n) ? 0 : 1; +} + +void rtw_memset(void *pbuf, int c, uint32_t n) +{ + memset(pbuf, c, n); +} + +/* string.h Wrapper End */ + +/* Semaphore Start */ + +void rtw_init_sema(void **sema, int init_val) +{ + sem_t *_sema; + _sema = calloc(1, sizeof(sem_t)); + if (!_sema) + { + return; + } + + if (sem_init(_sema, 0, init_val)) + { + free(_sema); + return; + } + + *sema = _sema; +} + +void rtw_free_sema(void **sema) +{ + sem_destroy(*sema); + free(*sema); + *sema = NULL; +} + +void rtw_up_sema(void **sema) +{ + sem_post(*sema); +} + +void rtw_up_sema_from_isr(void **sema) +{ + rtw_up_sema(sema); +} + +uint32_t rtw_down_timeout_sema(void **sema, uint32_t timeout) +{ + struct timespec abstime; + int ret; + if (timeout == 0xffffffff) + { + ret = sem_wait(*sema); + } + + else + { + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_sec += timeout / 1000; + abstime.tv_nsec += (timeout % 1000) * 1000 * 1000; + if (abstime.tv_nsec >= (1000 * 1000000)) + { + abstime.tv_sec += 1; + abstime.tv_nsec -= (1000 * 1000000); + } + + ret = sem_timedwait(*sema, &abstime); + } + + return !ret; +} + +uint32_t rtw_down_sema(void **sema) +{ + return rtw_down_timeout_sema(sema, 0xffffffff); +} + +/* Semaphore End */ + +/* MUTual EXclusion Start */ + +void rtw_mutex_init(void **pmutex) +{ + rtw_init_sema(pmutex, 1); +} + +void rtw_mutex_free(void **pmutex) +{ + rtw_free_sema(pmutex); +} + +void rtw_mutex_put(void **pmutex) +{ + rtw_up_sema(pmutex); +} + +void rtw_mutex_get(void **pmutex) +{ + rtw_down_sema(pmutex); +} + +int rtw_mutex_get_timeout(void **pmutex, uint32_t ms) +{ + return rtw_down_timeout_sema(pmutex, ms); +} + +int rtw_enter_critical_mutex(void **pmutex, unsigned long *pirql) +{ + return rtw_down_sema(pmutex); +} + +void rtw_exit_critical_mutex(void **pmutex, unsigned long *pirql) +{ + rtw_up_sema(pmutex); +} + +/* MUTual EXclusion End */ + +/* Spinlocks Start */ + +void rtw_spinlock_init(void **plock) +{ + rtw_init_sema(plock, 1); +} + +void rtw_spinlock_free(void **plock) +{ + rtw_free_sema(plock); +} + +void rtw_spin_lock(void **plock) +{ + rtw_down_sema(plock); +} + +void rtw_spin_unlock(void **plock) +{ + rtw_up_sema(plock); +} + +void rtw_spinlock_irqsave(void **plock, unsigned long *pirql) +{ + rtw_spin_lock(plock); +} + +void rtw_spinunlock_irqsave(void **plock, unsigned long *pirql) +{ + rtw_spin_unlock(plock); +} + +void rtw_enter_critical_bh(void **plock, unsigned long *pirql) +{ + rtw_spin_lock(plock); +} + +void rtw_exit_critical_bh(void **plock, unsigned long *pirql) +{ + rtw_spin_unlock(plock); +} + +/* Spinlocks End */ + +/* mqueue.h Wrapper Start */ + +int rtw_init_xqueue(void **queue, + const char *name, uint32_t size, uint32_t len) +{ + struct mq_attr attr; + struct file *mq; + int ret; + mq = malloc(sizeof(struct file)); + if (!mq) + { + return -ENOMEM; + } + + attr.mq_maxmsg = len; + attr.mq_msgsize = size; + attr.mq_curmsgs = 0; + attr.mq_flags = 0; + ret = file_mq_open(mq, name, O_RDWR | O_CREAT, 0644, &attr); + if (ret < 0) + { + free(mq); + return -ENOMEM; + } + + *queue = mq; + return 0; +} + +int rtw_push_to_xqueue(void **queue, void *message, uint32_t timeout_ms) +{ + struct file *mq = *queue; + struct mq_attr attr; + file_mq_getattr(mq, &attr); + return file_mq_send(mq, message, attr.mq_msgsize, 1); +} + +int rtw_pop_from_xqueue(void **queue, void *message, uint32_t timeout_ms) +{ + struct file *mq = *queue; + struct mq_attr attr; + unsigned int prio; + file_mq_getattr(mq, &attr); + return !file_mq_receive(mq, message, attr.mq_msgsize, &prio); +} + +int rtw_deinit_xqueue(void **queue) +{ + struct file *mq = *queue; + int ret; + ret = file_mq_close(mq); + if (ret >= 0) + { + free(mq); + } + + return ret; +} + +/* mqueue.h Wrapper End */ + +/* time.h Wrapper Start */ + +uint32_t rtw_get_current_time(void) +{ + return clock(); +} + +uint32_t rtw_systime_to_ms(uint32_t systime) +{ + return TICK2MSEC(systime); +} + +uint32_t rtw_systime_to_sec(uint32_t systime) +{ + return TICK2SEC(systime); +} + +uint32_t rtw_ms_to_systime(uint32_t ms) +{ + return MSEC2TICK(ms); +} + +uint32_t rtw_sec_to_systime(uint32_t sec) +{ + return SEC2TICK(sec); +} + +void rtw_yield_os(void) +{ + sched_yield(); +} + +void rtw_usleep_os(int us) +{ + usleep(us); +} + +void rtw_msleep_os(int ms) +{ + rtw_usleep_os(ms * 1000); +} + +void rtw_mdelay_os(int ms) +{ + rtw_msleep_os(ms); +} + +void rtw_udelay_os(int us) +{ + rtw_usleep_os(us); +} + +int32_t rtw_get_passing_time_ms(uint32_t start) +{ + return rtw_systime_to_ms(rtw_get_current_time() - start); +} + +int32_t rtw_get_time_interval_ms(uint32_t start, uint32_t end) +{ + return rtw_systime_to_ms(end - start); +} + +/* time.h Wrapper End */ + +/* Atomic Operation Start */ + +void ATOMIC_SET(atomic_t *v, int i) +{ + v->counter = i; +} + +int ATOMIC_READ(atomic_t *v) +{ + return v->counter; +} + +void ATOMIC_ADD(atomic_t *v, int i) +{ + save_and_cli(); + v->counter += i; + restore_flags(); +} + +void ATOMIC_SUB(atomic_t *v, int i) +{ + save_and_cli(); + v->counter -= i; + restore_flags(); +} + +void ATOMIC_INC(atomic_t *v) +{ + ATOMIC_ADD(v, 1); +} + +void ATOMIC_DEC(atomic_t *v) +{ + ATOMIC_SUB(v, 1); +} + +int ATOMIC_ADD_RETURN(atomic_t *v, int i) +{ + int temp; + save_and_cli(); + temp = v->counter; + temp += i; + v->counter = temp; + restore_flags(); + return temp; +} + +int ATOMIC_SUB_RETURN(atomic_t *v, int i) +{ + int temp; + save_and_cli(); + temp = v->counter; + temp -= i; + v->counter = temp; + restore_flags(); + return temp; +} + +int ATOMIC_INC_RETURN(atomic_t *v) +{ + return ATOMIC_ADD_RETURN(v, 1); +} + +int ATOMIC_DEC_RETURN(atomic_t *v) +{ + return ATOMIC_SUB_RETURN(v, 1); +} + +int ATOMIC_DEC_AND_TEST(atomic_t *v) +{ + return ATOMIC_DEC_RETURN(v) == 0; +} + +/* Atomic Operation End */ + +/* stdlib.h Wrapper Start */ + +static unsigned int __div64_32(uint64_t *n, unsigned int base) +{ + uint64_t rem = *n; + uint64_t b = base; + uint64_t res; + uint64_t d = 1; + unsigned int high = rem >> 32; + res = 0; + if (high >= base) + { + high /= base; + res = (uint64_t) high << 32; + rem -= (uint64_t)(high * base) << 32; + } + + while ((uint64_t)b > 0 && b < rem) + { + b = b + b; + d = d + d; + } + + do + { + if (rem >= b) + { + rem -= b; + res += d; + } + + b >>= 1; + d >>= 1; + } + while (d); + *n = res; + return rem; +} + +uint64_t rtw_modular64(uint64_t x, uint64_t y) +{ + unsigned int __base = (y); + unsigned int __rem; + if (((x) >> 32) == 0) + { + __rem = (unsigned int)(x) % __base; + (x) = (unsigned int)(x) / __base; + } + + else + { + __rem = __div64_32(&(x), __base); + } + + return __rem; +} + +static int arc4random(void) +{ + uint32_t res = rtw_get_current_time(); + static unsigned long rtw_seed = 0xdeadb00b; + rtw_seed = ((rtw_seed & 0x007f00ff) << 7) ^ + ((rtw_seed & 0x0f80ff00) >> 8) ^ + (res << 13) ^ (res >> 9); + return (int)rtw_seed; +} + +int rtw_get_random_bytes(void *dst, uint32_t size) +{ + unsigned int ranbuf; + unsigned int *lp; + int i; + int count; + count = size / sizeof(unsigned int); + lp = (unsigned int *)dst; + for (i = 0; i < count; i++) + { + lp[i] = arc4random(); + size -= sizeof(unsigned int); + } + + if (size > 0) + { + ranbuf = arc4random(); + memcpy(&lp[i], &ranbuf, size); + } + + return 0; +} + +/* stdlib.h Wrapper End */ + +/* Thread Wrapper Start */ + +static int nuttx_task_hook(int argc, FAR char *argv[]) +{ + struct task_struct *task; + struct nthread_wrapper *wrap; + task = (FAR struct task_struct *) + ((uintptr_t)strtoul(argv[1], NULL, 0)); + if (!task || !task->priv) + { + return 0; + } + + wrap = task->priv; + if (wrap->func) + { + wrap->func(wrap->thctx); + } + + return 0; +} + +int rtw_create_task(struct task_struct *task, const char *name, + uint32_t stack_size, uint32_t priority, + thread_func_t func, void *thctx) +{ + struct nthread_wrapper *wrap; + char *argv[2]; + char arg1[16]; + int pid; + snprintf(arg1, 16, "0x%" PRIxPTR, (uintptr_t)task); + argv[0] = arg1; + argv[1] = NULL; + wrap = malloc(sizeof(*wrap)); + if (!wrap) + { + return -ENOMEM; + } + + wrap->func = func; + wrap->thctx = thctx; + task->name = name; + task->priv = wrap; + if (!strcmp(name, "rtw_recv_tasklet")) + { + stack_size = + CONFIG_IEEE80211_REALTEK_AMEBAZ_RECV_STACKSIZE / sizeof(int); + } + + pid = kthread_create(name, + SCHED_PRIORITY_DEFAULT + priority, + stack_size * sizeof(int), + nuttx_task_hook, argv); + if (pid < 0) + { + free(wrap); + return pid; + } + + wrap->pid = pid; + return 1; +} + +void rtw_delete_task(struct task_struct *task) +{ + struct nthread_wrapper *wrap = task->priv; + if (kill(wrap->pid, SIGKILL)) + { + return; + } + + free(wrap); + task->priv = NULL; +} + +void rtw_set_priority_task(struct task_struct *task, + unsigned int newpriority) +{ +} + +int rtw_get_priority_task(struct task_struct *task) +{ +} + +void rtw_suspend_task(struct task_struct *task) +{ +} + +void rtw_resume_task(struct task_struct *task) +{ +} + +/* Thread Wrapper End */ + +/* Timer Wrapper Start */ + +void *rtw_timer_create(const signed char *pctimername, + unsigned long xtimerperiodinticks, + uint32_t uxautoreload, + void *pvtimerid, + thread_func_t pxcallbackfunction) +{ + struct ntimer_wrapper *wrap; + wrap = calloc(1, sizeof(*wrap)); + if (!wrap) + { + return NULL; + } + + wrap->callback = pxcallbackfunction; + return wrap; +} + +uint32_t rtw_timer_stop(void *xtimer, + unsigned long xblocktime) +{ + struct ntimer_wrapper *wrap = xtimer; + if (!work_available(&wrap->work)) + { + work_cancel(LPWORK, &wrap->work); + } + + return 1; +} + +uint32_t rtw_timer_delete(void *xtimer, + unsigned long xblocktime) +{ + struct ntimer_wrapper *wrap = xtimer; + rtw_timer_stop(xtimer, xblocktime); + free(wrap); + return 1; +} + +uint32_t rtw_timer_is_timer_active(void *xtimer) +{ + struct ntimer_wrapper *wrap = xtimer; + return !work_available(&wrap->work); +} + +uint32_t rtw_timer_change_period(void *xtimer, + unsigned long xnewperiod, + unsigned long xblocktime) +{ + struct ntimer_wrapper *wrap = xtimer; + if (work_available(&wrap->work)) + { + work_queue(LPWORK, &wrap->work, wrap->callback, wrap, xnewperiod); + } + + return 1; +} + +void *rtw_timer_get_id(void *xtimer) +{ + return xtimer; +} + +uint32_t rtw_timer_start(void *xtimer, unsigned long xblocktime) +{ + return rtw_timer_change_period(xtimer, 0, xblocktime); +} + +uint32_t rtw_timer_start_from_isr(void *xtimer, + long *pxhigherprioritytaskwoken) +{ + return rtw_timer_start(xtimer, 0); +} + +uint32_t rtw_timer_stop_from_isr(void *xtimer, + long *pxhigherprioritytaskwoken) +{ + return rtw_timer_stop(xtimer, 0); +} + +uint32_t rtw_timer_reset_from_isr(void *xtimer, + long *pxhigherprioritytaskwoken) +{ + return rtw_timer_start(xtimer, 0); +} + +uint32_t rtw_timer_change_period_from_isr(void *xtimer, + unsigned long xnewperiod, + long *pxhigherprioritytaskwoken) +{ + return rtw_timer_change_period(xtimer, xnewperiod, 0); +} + +uint32_t rtw_timer_reset(void *xtimer, unsigned long xblocktime) +{ + return rtw_timer_start(xtimer, 0); +} + +/* Timer Wrapper End */ + +/* List Wrapper Start */ + +static void _list_add(struct list_head *newitem, + struct list_head *prev, + struct list_head *next) +{ + next->prev = newitem; + newitem->next = next; + newitem->prev = prev; + prev->next = newitem; +} + +static void list_add(struct list_head *newitem, struct list_head *head) +{ + _list_add(newitem, head, head->next); +} + +static void list_add_tail(struct list_head *newitem, struct list_head *head) +{ + _list_add(newitem, head->prev, head); +} + +static void list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +void rtw_list_insert_head(struct list_head *plist, struct list_head *phead) +{ + list_add(plist, phead); +} + +void rtw_list_insert_tail(struct list_head *plist, struct list_head *phead) +{ + list_add_tail(plist, phead); +} + +void rtw_list_delete(struct list_head *plist) +{ + list_del(plist->prev, plist->next); + plist->next = plist->prev = plist; +} + +void rtw_init_listhead(struct list_head *list) +{ + list->next = list->prev = list; +} + +uint32_t rtw_is_list_empty(struct list_head *phead) +{ + return phead->next == phead; +} + +/* List Wrapper End */ + +/* Queue Wrapper Start */ + +void rtw_init_queue(_queue *pqueue) +{ + rtw_init_listhead(&(pqueue->queue)); + rtw_spinlock_init(&(pqueue->lock)); +} + +uint32_t rtw_queue_empty(_queue *pqueue) +{ + return (rtw_is_list_empty(&(pqueue->queue))); +} + +uint32_t rtw_end_of_queue_search(struct list_head *head, + struct list_head *plist) +{ + return (head == plist); +} + +/* Queue Wrapper End */ + +/* Device lock Wrapper Start */ + +static uint32_t mutex_init; +static void *device_mutex[5]; +static void device_mutex_init(uint32_t device) +{ + irqstate_t status; + if (!(mutex_init & (1 << device))) + { + status = enter_critical_section(); + if (!(mutex_init & (1 << device))) + { + rtw_mutex_init(&device_mutex[device]); + mutex_init |= (1 << device); + } + + leave_critical_section(status); + } +} + +void device_mutex_lock(uint32_t device) +{ + device_mutex_init(device); + rtw_mutex_get(&device_mutex[device]); +} + +void device_mutex_unlock(uint32_t device) +{ + device_mutex_init(device); + rtw_mutex_put(&device_mutex[device]); +} + +/* Device lock Wrapper End */ + +/* malloc.h Wrapper Start */ + +uint32_t rtw_get_free_heap_size(void) +{ + struct mallinfo mem; + mem = mallinfo(); + return mem.arena; +} + +/* malloc.h Wrapper End */ + +/* Unnecessary Start */ + +void init_mem_monitor(struct list_head *pmem_table, + int *used_num) +{ +} + +void deinit_mem_monitor(struct list_head *pmem_table, + int *used_num) +{ +} + +int rtw_netif_queue_stopped(void *pnetdev) +{ + return 0; +} + +void rtw_netif_wake_queue(void *pnetdev) +{ +} + +void rtw_netif_start_queue(void *pnetdev) +{ +} + +void rtw_netif_stop_queue(void *pnetdev) +{ +} + +void flush_signals_thread(void) +{ +} + +void rtw_wakeup_task(struct task_struct *task) +{ +} + +void rtw_thread_enter(char *name) +{ +} + +void rtw_thread_exit(void) +{ +} + +uint8_t rtw_get_scheduler_state(void) +{ + return 1; /* OS_SCHEDULER_RUNNING */ +} + +long xtask_get_scheduler_state(void) +{ + return 2; /* taskSCHEDULER_RUNNING */ +} + +void rtw_cpu_lock(void) +{ +} + +void rtw_cpu_unlock(void) +{ +} + +void rtw_create_secure_context(uint32_t n) +{ +} + +void rtw_acquire_wakelock(void) +{ +} + +void rtw_release_wakelock(void) +{ +} + +void rtw_wakelock_timeout(uint32_t ms) +{ +} + +void cli(void) +{ +} + +uint32_t xtask_get_tick_count(void) +{ + return rtw_get_current_time(); +} + +char *pctask_get_name(void *xtasktoquery) +{ + return NULL; +} + +/* Unnecessary End */ + +/* Legacy Start */ + +const struct osdep_service_ops osdep_service = +{ + .rtw_vmalloc = rtw_vmalloc, + .rtw_zvmalloc = rtw_zvmalloc, + .rtw_vmfree = rtw_vmfree, + .rtw_malloc = rtw_malloc, + .rtw_zmalloc = rtw_zmalloc, + .rtw_mfree = rtw_mfree, + .rtw_memcpy = rtw_memcpy, + .rtw_memcmp = rtw_memcmp, + .rtw_memset = rtw_memset, + .rtw_init_sema = rtw_init_sema, + .rtw_free_sema = rtw_free_sema, + .rtw_up_sema = rtw_up_sema, + .rtw_up_sema_from_isr = rtw_up_sema_from_isr, + .rtw_down_timeout_sema = rtw_down_timeout_sema, + .rtw_mutex_init = rtw_mutex_init, + .rtw_mutex_free = rtw_mutex_free, + .rtw_mutex_get = rtw_mutex_get, + .rtw_mutex_get_timeout = rtw_mutex_get_timeout, + .rtw_mutex_put = rtw_mutex_put, + .rtw_enter_critical = rtw_enter_critical, + .rtw_exit_critical = rtw_exit_critical, + .rtw_enter_critical_from_isr = rtw_enter_critical, + .rtw_exit_critical_from_isr = rtw_exit_critical, + .rtw_enter_critical_bh = NULL, + .rtw_exit_critical_bh = NULL, + .rtw_enter_critical_mutex = rtw_enter_critical_mutex, + .rtw_exit_critical_mutex = rtw_exit_critical_mutex, + .rtw_cpu_lock = rtw_cpu_lock, + .rtw_cpu_unlock = rtw_cpu_unlock, + .rtw_spinlock_init = rtw_spinlock_init, + .rtw_spinlock_free = rtw_spinlock_free, + .rtw_spin_lock = rtw_spin_lock, + .rtw_spin_unlock = rtw_spin_unlock, + .rtw_spinlock_irqsave = rtw_spinlock_irqsave, + .rtw_spinunlock_irqsave = rtw_spinunlock_irqsave, + .rtw_init_xqueue = rtw_init_xqueue, + .rtw_push_to_xqueue = rtw_push_to_xqueue, + .rtw_pop_from_xqueue = rtw_pop_from_xqueue, + .rtw_deinit_xqueue = rtw_deinit_xqueue, + .rtw_get_current_time = rtw_get_current_time, + .rtw_systime_to_ms = rtw_systime_to_ms, + .rtw_systime_to_sec = rtw_systime_to_sec, + .rtw_ms_to_systime = rtw_ms_to_systime, + .rtw_sec_to_systime = rtw_sec_to_systime, + .rtw_msleep_os = rtw_msleep_os, + .rtw_usleep_os = rtw_usleep_os, + .rtw_mdelay_os = rtw_msleep_os, + .rtw_udelay_os = rtw_usleep_os, + .rtw_yield_os = rtw_yield_os, + .ATOMIC_SET = ATOMIC_SET, + .ATOMIC_READ = ATOMIC_READ, + .ATOMIC_ADD = ATOMIC_ADD, + .ATOMIC_SUB = ATOMIC_SUB, + .ATOMIC_INC = ATOMIC_INC, + .ATOMIC_DEC = ATOMIC_DEC, + .ATOMIC_ADD_RETURN = ATOMIC_ADD_RETURN, + .ATOMIC_SUB_RETURN = ATOMIC_SUB_RETURN, + .ATOMIC_INC_RETURN = ATOMIC_INC_RETURN, + .ATOMIC_DEC_RETURN = ATOMIC_DEC_RETURN, + .rtw_modular64 = rtw_modular64, + .rtw_get_random_bytes = rtw_get_random_bytes, + .rtw_get_free_heap_size = rtw_get_free_heap_size, + .rtw_create_task = rtw_create_task, + .rtw_delete_task = rtw_delete_task, + .rtw_wakeup_task = NULL, + .rtw_thread_enter = rtw_thread_enter, + .rtw_thread_exit = rtw_thread_exit, + .rtw_timer_create = rtw_timer_create, + .rtw_timer_delete = rtw_timer_delete, + .rtw_timer_is_timer_active = rtw_timer_is_timer_active, + .rtw_timer_stop = rtw_timer_stop, + .rtw_timer_change_period = rtw_timer_change_period, + .rtw_timer_get_id = rtw_timer_get_id, + .rtw_timer_start = rtw_timer_start, + .rtw_timer_start_from_isr = rtw_timer_start_from_isr, + .rtw_timer_stop_from_isr = rtw_timer_stop_from_isr, + .rtw_timer_reset_from_isr = rtw_timer_reset_from_isr, + .rtw_timer_change_period_from_isr = rtw_timer_change_period_from_isr, + .rtw_timer_reset = rtw_timer_reset, + .rtw_acquire_wakelock = rtw_acquire_wakelock, + .rtw_release_wakelock = rtw_release_wakelock, + .rtw_wakelock_timeout = rtw_wakelock_timeout, + .rtw_get_scheduler_state = rtw_get_scheduler_state, + .rtw_create_secure_context = rtw_create_secure_context, +}; + +/* Legacy End */ + diff --git a/arch/arm/src/rtl8720c/amebaz_depend.h b/arch/arm/src/rtl8720c/amebaz_depend.h new file mode 100644 index 00000000000..ca5cf15e9e4 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_depend.h @@ -0,0 +1,181 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_depend.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_DEPEND_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_DEPEND_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +typedef struct __queue _queue; +typedef void (*thread_func_t)(void *context); +typedef struct +{ + volatile int counter; +} atomic_t; +struct list_head +{ + struct list_head *next; + struct list_head *prev; +}; +struct __queue +{ + struct list_head queue; + void *lock; +}; +struct task_struct +{ + const char *name; + void *priv; + void *wsema; + void *tsema; + uint32_t blocked; + uint32_t running; +}; +struct nthread_wrapper +{ + int pid; + thread_func_t func; + void *thctx; +}; +struct ntimer_wrapper +{ + struct work_s work; + void (*callback)(void *context); +}; +struct osdep_service_ops +{ + uint8_t *(*rtw_vmalloc)(uint32_t n); + uint8_t *(*rtw_zvmalloc)(uint32_t n); + void (*rtw_vmfree)(uint8_t *pbuf, uint32_t n); + uint8_t *(*rtw_malloc)(uint32_t n); + uint8_t *(*rtw_zmalloc)(uint32_t n); + void (*rtw_mfree)(uint8_t *pbuf, uint32_t n); + void (*rtw_memcpy)(void *dst, void *src, uint32_t n); + int (*rtw_memcmp)(void *dst, void *src, uint32_t n); + void (*rtw_memset)(void *pbuf, int c, uint32_t n); + void (*rtw_init_sema)(void **sema, int init_val); + void (*rtw_free_sema)(void **sema); + void (*rtw_up_sema)(void **sema); + void (*rtw_up_sema_from_isr)(void **sema); + uint32_t (*rtw_down_timeout_sema)(void **sema, uint32_t timeout); + void (*rtw_mutex_init)(void **pmutex); + void (*rtw_mutex_free)(void **pmutex); + void (*rtw_mutex_get)(void **pmutex); + int (*rtw_mutex_get_timeout)(void **pmutex, uint32_t timeout_ms); + void (*rtw_mutex_put)(void **pmutex); + void (*rtw_enter_critical)(void **plock, unsigned long *pirql); + void (*rtw_exit_critical)(void **plock, unsigned long *pirql); + void (*rtw_enter_critical_from_isr)(void **plock, unsigned long *pirql); + void (*rtw_exit_critical_from_isr)(void **plock, unsigned long *pirql); + void (*rtw_enter_critical_bh)(void **plock, unsigned long *pirql); + void (*rtw_exit_critical_bh)(void **plock, unsigned long *pirql); + int (*rtw_enter_critical_mutex)(void **pmutex, unsigned long *pirql); + void (*rtw_exit_critical_mutex)(void **pmutex, unsigned long *pirql); + void (*rtw_cpu_lock)(void); + void (*rtw_cpu_unlock)(void); + void (*rtw_spinlock_init)(void **plock); + void (*rtw_spinlock_free)(void **plock); + void (*rtw_spin_lock)(void **plock); + void (*rtw_spin_unlock)(void **plock); + void (*rtw_spinlock_irqsave)(void **plock, unsigned long *pirql); + void (*rtw_spinunlock_irqsave)(void **plock, unsigned long *pirql); + int (*rtw_init_xqueue)(void **queue, const char *name, uint32_t size, + uint32_t len); + int (*rtw_push_to_xqueue)(void **queue, void *message, + uint32_t timeout_ms); + int (*rtw_pop_from_xqueue)(void **queue, void *message, + uint32_t timeout_ms); + int (*rtw_deinit_xqueue)(void **queue); + uint32_t (*rtw_get_current_time)(void); + uint32_t (*rtw_systime_to_ms)(uint32_t systime); + uint32_t (*rtw_systime_to_sec)(uint32_t systime); + uint32_t (*rtw_ms_to_systime)(uint32_t ms); + uint32_t (*rtw_sec_to_systime)(uint32_t sec); + void (*rtw_msleep_os)(int ms); + void (*rtw_usleep_os)(int us); + void (*rtw_mdelay_os)(int ms); + void (*rtw_udelay_os)(int us); + void (*rtw_yield_os)(void); + void (*ATOMIC_SET)(atomic_t *v, int i); + int (*ATOMIC_READ)(atomic_t *v); + void (*ATOMIC_ADD)(atomic_t *v, int i); + void (*ATOMIC_SUB)(atomic_t *v, int i); + void (*ATOMIC_INC)(atomic_t *v); + void (*ATOMIC_DEC)(atomic_t *v); + int (*ATOMIC_ADD_RETURN)(atomic_t *v, int i); + int (*ATOMIC_SUB_RETURN)(atomic_t *v, int i); + int (*ATOMIC_INC_RETURN)(atomic_t *v); + int (*ATOMIC_DEC_RETURN)(atomic_t *v); + uint64_t (*rtw_modular64)(uint64_t x, uint64_t y); + int (*rtw_get_random_bytes)(void *dst, uint32_t size); + uint32_t (*rtw_get_free_heap_size)(void); + int (*rtw_create_task)(struct task_struct *task, const char *name, + uint32_t stack_size, + uint32_t priority, thread_func_t func, void *thctx); + void (*rtw_delete_task)(struct task_struct *task); + void (*rtw_wakeup_task)(struct task_struct *task); + void (*rtw_thread_enter)(char *name); + void (*rtw_thread_exit)(void); + void *(*rtw_timer_create)(const signed char *pctimername, + unsigned long xtimerperiodinticks, + uint32_t uxautoreload, + void *pvtimerid, + thread_func_t pxcallbackfunction); + uint32_t (*rtw_timer_delete)(void *xtimer, unsigned long xblocktime); + uint32_t (*rtw_timer_is_timer_active)(void *xtimer); + uint32_t (*rtw_timer_stop)(void *xtimer, unsigned long xblocktime); + uint32_t (*rtw_timer_change_period)(void *xtimer, unsigned long xnewperiod, + unsigned long xblocktime); + void *(*rtw_timer_get_id)(void *xtimer); + uint32_t (*rtw_timer_start)(void *xtimer, unsigned long xblocktime); + uint32_t (*rtw_timer_start_from_isr)(void *xtimer, + long *pxhigherprioritytaskwoken); + uint32_t (*rtw_timer_stop_from_isr)(void *xtimer, + long *pxhigherprioritytaskwoken); + uint32_t (*rtw_timer_reset_from_isr) (void *xtimer, + long *pxhigherprioritytaskwoken); + uint32_t (*rtw_timer_change_period_from_isr) (void *xtimer, + unsigned long xnewperiod, + long *pxhigherprioritytaskwoken); + uint32_t (*rtw_timer_reset)(void *xtimer, unsigned long xblocktime); + void (*rtw_acquire_wakelock)(void); + void (*rtw_release_wakelock)(void); + void (*rtw_wakelock_timeout)(uint32_t ms); + uint8_t (*rtw_get_scheduler_state)(void); + void (*rtw_create_secure_context)(uint32_t n); +}; +#endif diff --git a/arch/arm/src/rtl8720c/amebaz_driver.c b/arch/arm/src/rtl8720c/amebaz_driver.c new file mode 100644 index 00000000000..871a6847b02 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_driver.c @@ -0,0 +1,1195 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_driver.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include "amebaz_netdev.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AMEBAZ_SCAN_TIMEOUT_TICK (10 * CLOCKS_PER_SEC) +#define AMEBAZ_CONNECT_TIMEOUT_TICK (10 * CLOCKS_PER_SEC) +#define AMEBAZ_DEVICE_COUNT (2) +#define AMEBAZ_SCAN_ENTRY_COUNT (5) +#define AMEBAZ_DEFAULT_COUNTRY "CN" +#define SIOCDEVPRIVATE 0x89f0 +#define SIOCGIWPRIVPASSPHRASE 0x8bfc +#define SIOCSIWPRIVCOUNTRY 0x8bfd +#define SIOCSIWPRIVAPESSID 0x8bfe +#define SIOCSIWPRIVPASSPHRASE 0x8bff +struct _sockaddr_t +{ + uint8_t sa_len; + uint8_t sa_family; + char sa_data[14]; +}; + +static struct amebaz_dev_s *gp_wlan_dev[AMEBAZ_DEVICE_COUNT + 1]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +static void amebaz_state_timeout(wdparm_t arg) +{ + FAR struct amebaz_state_s *state = (FAR struct amebaz_state_s *)arg; + if (state->status < AMEBAZ_STATUS_RUN) + { + return; + } + + state->status = AMEBAZ_STATUS_TIMEOUT; + nxsem_post(&state->mutex); +} + +static int amebaz_state_run(FAR struct amebaz_state_s *state, int32_t delay) +{ + if (state->status == AMEBAZ_STATUS_RUN) + { + return -EBUSY; + } + + state->status = AMEBAZ_STATUS_RUN; + return wd_start(&state->timeout, delay, + amebaz_state_timeout, (wdparm_t)state); +} + +static int amebaz_state_wait(FAR struct amebaz_state_s *state) +{ + int ret = 0; + while (state->status == AMEBAZ_STATUS_RUN) + { + ret = nxsem_wait_uninterruptible(&state->mutex); + if (ret != 0) + { + break; + } + } + + return ret; +} + +static void amebaz_state_post(FAR struct amebaz_state_s *state, int status) +{ + int _status = state->status; + state->status = status; + if (_status == AMEBAZ_STATUS_RUN) + { + wd_cancel(&state->timeout); + nxsem_post(&state->mutex); + } +} + +static void amebaz_state_deinit(FAR struct amebaz_state_s *state) +{ + wd_cancel(&state->timeout); +} + +static int amebaz_state_init(FAR struct amebaz_state_s *state) +{ + if (nxsem_init(&state->mutex, 0, 0) != OK) + { + return -ENOMEM; + } + + state->status = AMEBAZ_STATUS_DISABLED; + return 0; +} + +void amebaz_wl_scan_handler(int index, union iwreq_data *wrqu, char *extra) +{ + FAR struct amebaz_dev_s *priv = gp_wlan_dev[index]; + FAR struct amebaz_state_s *state = &priv->scan; + rtw_scan_result_t *res, *cache, *tmp; + rtw_scan_result_t ap_res; + rtw_scan_ap_result_t *ap; + struct iwreq iwr; + int i; + int j; + if (state->status != AMEBAZ_STATUS_RUN) + { + return; + } + + if (wrqu->data.pointer == NULL) + { + memset(&iwr, 0, sizeof(iwr)); + snprintf(iwr.ifr_name, sizeof(iwr.ifr_name), "wlan%d", index); + iwr.u.data.pointer = priv->scan_data; + iwr.u.data.length = AMEBAZ_SCAN_AP_COUNT * sizeof(rtw_scan_result_t); + if (rltk_wlan_control(SIOCGIWSCAN, &iwr) != 0 || + iwr.u.data.flags != 1) + { + amebaz_state_post(state, AMEBAZ_STATUS_DONE); + return; + } + + ap = iwr.u.data.pointer; + ap_res.signal_strength = ap->signal_strength; + ap_res.bss_type = 0; + ap_res.security = ap->security; + ap_res.wps_type = ap->wps_type; + ap_res.channel = ap->channel; + ap_res.SSID.len = ap->len - sizeof(*ap) + 1; + memcpy(ap_res.SSID.val, ap->SSID, ap_res.SSID.len); + memcpy(ap_res.BSSID.octet, ap->BSSID, IFHWADDRLEN); + ap_res.SSID.val[ap_res.SSID.len - 1] = '\0'; + memcpy(priv->scan_data, &ap_res, sizeof(ap_res)); + priv->scan_count = 1; + amebaz_state_post(state, AMEBAZ_STATUS_DONE); + return; + } + + for (i = 0; i < wrqu->data.length / sizeof(rtw_scan_result_t); i++) + { + res = ((rtw_scan_result_t **)wrqu->data.pointer)[i]; + for (j = 0; j < priv->scan_count; j++) + { + cache = &priv->scan_data[j]; + if (memcmp(cache->BSSID.octet, res->BSSID.octet, IFHWADDRLEN)) + { + continue; + } + + if (cache->signal_strength < res->signal_strength) + { + memcpy(cache, res, sizeof(rtw_scan_result_t)); + } + + break; + } + + if (j != priv->scan_count) + { + continue; + } + + if (priv->scan_count >= AMEBAZ_SCAN_AP_COUNT) + { + tmp = NULL; + for (j = 0; j < priv->scan_count; j++) + { + cache = &priv->scan_data[j]; + if (!tmp || cache->signal_strength < tmp->signal_strength) + { + tmp = cache; + } + } + + memcpy(tmp, res, sizeof(rtw_scan_result_t)); + } + + else + { + cache = &priv->scan_data[priv->scan_count++]; + memcpy(cache, res, sizeof(rtw_scan_result_t)); + } + } +} + +static void amebaz_wl_post_connection_event(struct amebaz_dev_s *priv, + int status) +{ + FAR struct amebaz_state_s *state = &priv->conn; + if (status == AMEBAZ_STATUS_DONE) + { + netdev_carrier_on(&priv->dev); + } + + else + { + netdev_carrier_off(&priv->dev); + } + + amebaz_state_post(state, status); +} + +void amebaz_wl_connection_handler(int index, + union iwreq_data *wrqu, char *extra) +{ + const unsigned char fourway_done[] = "WPA/WPA2 handshake done"; + const unsigned char no_assoc_network[] = + "No Assoc Network After Scan Done"; + FAR struct amebaz_dev_s *priv = gp_wlan_dev[0]; + FAR struct amebaz_state_s *state = &priv->conn; + unsigned char null_mac[IFHWADDRLEN] = + { + }; + + bool mac_avalid; + if (gp_wlan_dev[1]->conn.status == AMEBAZ_STATUS_RUN) + { + priv = gp_wlan_dev[1]; + } + + mac_avalid = memcmp(wrqu->ap_addr.sa_data, null_mac, sizeof(null_mac)); + if (extra) + { + if (!memcmp(fourway_done, extra, sizeof(fourway_done))) + { + amebaz_wl_post_connection_event(priv, AMEBAZ_STATUS_DONE); + } + + else if (!memcmp(no_assoc_network, extra, sizeof(no_assoc_network)) || + !mac_avalid) + { + amebaz_wl_post_connection_event(priv, AMEBAZ_STATUS_DISABLED); + } + } + + else if (priv->assoc.alg == IW_ENCODE_ALG_NONE || + priv->mode == RTW_MODE_AP || priv->mode == RTW_MODE_STA_AP) + { + if (mac_avalid) + { + amebaz_wl_post_connection_event(priv, AMEBAZ_STATUS_DONE); + } + + else + { + amebaz_wl_post_connection_event(priv, AMEBAZ_STATUS_DISABLED); + } + } + + else if (state->status == AMEBAZ_STATUS_DONE && !mac_avalid) + { + amebaz_wl_post_connection_event(priv, AMEBAZ_STATUS_DISABLED); + } +} + +void amebaz_wl_netif_info_handler(int index, void *dev, unsigned char *addr) +{ + FAR struct amebaz_dev_s *priv = gp_wlan_dev[index]; + if (!priv || index != priv->devnum) + { + return; + } + + memcpy(priv->dev.d_mac.ether.ether_addr_octet, addr, IFHWADDRLEN); +} + +void amebaz_wl_notify_rx_handler(int index, unsigned int len) +{ + FAR struct amebaz_dev_s *priv = gp_wlan_dev[index]; + if (!priv || index != priv->devnum || !len) + { + return; + } + + amebaz_netdev_notify_receive(priv, index, len); +} + +static int amebaz_wl_set_channels(struct amebaz_dev_s *priv, + struct iw_freq *freqs, + uint8_t num_channels) +{ + uint8_t param[12 + 1 + 15 * 2] = + { + "PartialScan" + }; + + struct iwreq iwr = + { + }; + + int i; + if (!freqs || num_channels == 0) + { + return OK; + } + + if (num_channels > 15) + { + return -EINVAL; + } + + *(param + 12) = num_channels; + for (i = 0; i < num_channels; i++) + { + *(param + 13 + i) = freqs[i].m; + *(param + 13 + num_channels + i) = PSCAN_ENABLE; + } + + iwr.u.data.pointer = param; + iwr.u.data.length = 12 + 1 + num_channels * 2; + snprintf(iwr.ifr_name, IFNAMSIZ, "wlan%d", priv->devnum); + return rltk_wlan_control(SIOCDEVPRIVATE, &iwr); +} + +int amebaz_wl_start_scan(struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + enum + { + RTW_SCAN_COMMAMD = 0x01 + }; + + FAR struct amebaz_state_s *state = &priv->scan; + int scan_type = IW_SCAN_TYPE_ACTIVE; + int bss_type = RTW_BSS_TYPE_ANY; + struct iw_scan_req *req; + void *pointer = NULL; + uint16_t length; + int essid_len; + int ret; + iwr->u.data.flags = scan_type | (bss_type << 8); + if (iwr->u.data.pointer != NULL && + iwr->u.data.length == sizeof(*req)) + { + req = iwr->u.data.pointer; + ret = amebaz_wl_set_channels(priv, + req->channel_list, req->num_channels); + if (ret < 0) + { + return ret; + } + + essid_len = req->essid_len; + memcpy(priv->scan_data, &essid_len, sizeof(int)); + memcpy((char *)priv->scan_data + sizeof(int), + req->essid, req->essid_len); + pointer = iwr->u.data.pointer; + length = iwr->u.data.length; + iwr->u.data.pointer = priv->scan_data; + iwr->u.data.length = AMEBAZ_SCAN_AP_COUNT * sizeof(rtw_scan_result_t); + } + + else + { + iwr->u.data.flags |= RTW_SCAN_COMMAMD << 4; + } + + priv->scan_count = 0; + ret = amebaz_state_run(state, AMEBAZ_SCAN_TIMEOUT_TICK); + if (ret < 0) + { + return ret; + } + + ret = rltk_wlan_control(SIOCSIWSCAN, iwr); + if (pointer) + { + iwr->u.data.pointer = pointer; + iwr->u.data.length = length; + } + + if (ret < 0) + { + state->status = AMEBAZ_STATUS_DISABLED; + } + + return ret; +} + +static char *amebaz_wl_iwe_add_event(char *stream, char *stop, + struct iw_event *iwe, int event_len) +{ + if (stream + event_len > stop) + { + return stream; + } + + iwe->len = event_len; + return stream + event_len; +} + +static int amebaz_wl_format_scan_results(struct amebaz_dev_s *priv, + struct iwreq *iwr) +{ + rtw_scan_result_t *cache; + struct iw_event *iwe; + char *start; + char *stop; + int i; + start = iwr->u.data.pointer; + stop = (char *)iwr->u.data.pointer + iwr->u.data.length; + for (i = 0; i < priv->scan_count; i++) + { + cache = &priv->scan_data[i]; + iwe = (struct iw_event *)start; + iwe->cmd = SIOCGIWAP; + iwe->u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(&iwe->u.ap_addr.sa_data, cache->BSSID.octet, IFHWADDRLEN); + start = amebaz_wl_iwe_add_event(start, stop, iwe, IW_EV_LEN(ap_addr)); + iwe = (struct iw_event *)start; + iwe->cmd = SIOCGIWESSID; + iwe->u.essid.flags = 0; + iwe->u.essid.length = cache->SSID.len; + iwe->u.essid.pointer = (FAR void *)sizeof(iwe->u.essid); + memcpy(&iwe->u.essid + 1, cache->SSID.val, cache->SSID.len); + start = amebaz_wl_iwe_add_event(start, stop, iwe, + IW_EV_LEN(essid) + ((cache->SSID.len + 3) & -4)); + iwe = (struct iw_event *)start; + iwe->cmd = IWEVQUAL; + iwe->u.qual.qual = 0; + iwe->u.qual.level = cache->signal_strength; + iwe->u.qual.noise = 0; + iwe->u.qual.updated |= IW_QUAL_DBM; + start = amebaz_wl_iwe_add_event(start, stop, iwe, IW_EV_LEN(qual)); + iwe = (struct iw_event *)start; + iwe->cmd = SIOCGIWFREQ; + iwe->u.freq.e = 0; + iwe->u.freq.m = cache->channel; + start = amebaz_wl_iwe_add_event(start, stop, iwe, IW_EV_LEN(freq)); + iwe = (struct iw_event *)start; + iwe->cmd = SIOCGIWENCODE; + iwe->u.data.flags = IW_ENCODE_DISABLED; + iwe->u.data.length = 0; + iwe->u.essid.pointer = NULL; + start = amebaz_wl_iwe_add_event(start, stop, iwe, IW_EV_LEN(data)); + } + + return start - (char *)iwr->u.data.pointer; +} + +int amebaz_wl_get_scan_results(struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + FAR struct amebaz_state_s *state = &priv->scan; + int request_size; + int ret = OK; + if (state->status == AMEBAZ_STATUS_RUN) + { + ret = -EAGAIN; + goto exit_failed; + } + + if (state->status != AMEBAZ_STATUS_DONE) + { + ret = -EINVAL; + goto exit_failed; + } + + if ((ret = amebaz_state_wait(state)) < 0) + { + goto exit_failed; + } + + if (priv->scan_count <= 0) + { + ret = OK; + iwr->u.data.length = 0; + goto exit_sem_post; + } + + request_size = priv->scan_count * + AMEBAZ_SCAN_ENTRY_COUNT * + sizeof(struct iw_event); + if (iwr->u.data.pointer == NULL || + iwr->u.data.length < request_size) + { + ret = -E2BIG; + iwr->u.data.pointer = NULL; + iwr->u.data.length = request_size; + goto exit_sem_post; + } + + iwr->u.data.length = amebaz_wl_format_scan_results(priv, iwr); +exit_sem_post: + nxsem_post(&state->mutex); +exit_failed: + if (ret < 0) + { + iwr->u.data.length = 0; + } + + return ret; +} + +int amebaz_wl_process_command(struct amebaz_dev_s *priv, int cmd, void *req) +{ + return rltk_wlan_control(cmd, req); +} + +int amebaz_wl_set_encode_ext(struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + struct iw_encode_ext *ext; + struct iwreq _iwr = + { + }; + + int ret; + iwr->u.encoding.flags = IW_ENCODE_INDEX & 1; + iwr->u.encoding.flags |= IW_ENCODE_TEMP; + ret = rltk_wlan_control(SIOCSIWENCODEEXT, iwr); + if (ret < 0) + { + return ret; + } + + ext = iwr->u.encoding.pointer; + _iwr.u.data.pointer = (void *)ext->key; + _iwr.u.data.length = ext->key_len; + _iwr.u.data.flags = (ext->key_len != 0); + memcpy(_iwr.ifr_name, iwr->ifr_name, strlen(iwr->ifr_name)); + ret = rltk_wlan_control(SIOCSIWPRIVPASSPHRASE, &_iwr); + if (ret < 0) + { + return ret; + } + + priv->assoc.alg = ext->alg; + priv->assoc.mask |= AMEBAZ_ASSOCIATE_ALG; + return OK; +} + +int amebaz_wl_get_encode_ext(struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + struct iw_encode_ext *ext; + struct iwreq _iwr = + { + }; + + int ret; + ret = rltk_wlan_control(SIOCGIWENCODEEXT, iwr); + if (ret < 0) + { + return ret; + } + + ext = iwr->u.encoding.pointer; + _iwr.u.data.pointer = (void *)ext->key; + memcpy(_iwr.ifr_name, iwr->ifr_name, strlen(iwr->ifr_name)); + ret = rltk_wlan_control(SIOCGIWPRIVPASSPHRASE, &_iwr); + if (ret < 0) + { + return ret; + } + + ext->key_len = _iwr.u.data.length; + ext->key[ext->key_len] = '\0'; + return ret; +} + +static int amebaz_wl_add_custom_ie(FAR struct amebaz_dev_s *priv, + int devnum) +{ + struct rtw_custom_ie_t + { + uint8_t *ie; + uint8_t type; + }; + + enum + { + PROBE_REQ = 0x0001, + PROBE_RSP = 0x0002, + BEACON = 0x0004, + ASSOC_REQ = 0x0008, + }; + + uint8_t ie[8] = + { + 7, 6, 'C', 'N', '\0', 1, 13, 20 + }; + + struct rtw_custom_ie_t cie = + { + ie, PROBE_RSP | BEACON + }; + + char param[16] = "SetCusIE"; + uint32_t *cmd = (uint32_t *)(param + strlen(param) + 1); + struct iwreq iwr = + { + }; + + memcpy(&ie[2], priv->country, 2); + *cmd = (intptr_t)&cie; + *(cmd + 1) = (intptr_t)1; + iwr.u.data.pointer = param; + iwr.u.data.length = sizeof(param); + snprintf(iwr.ifr_name, IFNAMSIZ, "wlan%d", devnum); + return rltk_wlan_control(SIOCDEVPRIVATE, &iwr); +} + +int amebaz_wl_associate(FAR struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + FAR struct amebaz_state_s *state = &priv->conn; + rtw_network_info_t info = + { + }; + + rtw_network_info_t *pinfo; + struct iw_freq freq = + { + }; + + struct _sockaddr_t *addr; + bool bssid_conn = false; + struct iwreq _iwr = + { + }; + + char *data; + int ret; + if (priv->mode == RTW_MODE_STA) + { + if (priv->assoc.mask != + (AMEBAZ_ASSOCIATE_MASK & ~AMEBAZ_ASSOCIATE_ALG) && + priv->assoc.mask != AMEBAZ_ASSOCIATE_MASK) + { + return 0; + } + + if ((priv->assoc.mask & AMEBAZ_ASSOCIATE_ALG) == 0) + { + priv->assoc.alg = IW_ENCODE_ALG_NONE; + } + + snprintf(_iwr.ifr_name, IFNAMSIZ, "wlan%d", priv->devnum); + addr = (struct _sockaddr_t *)&_iwr.u.ap_addr; + addr->sa_family = ARPHRD_ETHER; + data = addr->sa_data; + memcpy(_iwr.u.ap_addr.sa_data, priv->assoc.mac.octet, IFHWADDRLEN); + freq.m = priv->assoc.channel; + if (amebaz_wl_set_channels(priv, &freq, 1) < 0) + { + return -EINVAL; + } + + data[IFHWADDRLEN] = '#'; + data[IFHWADDRLEN + 1] = '@'; + info.ssid.len = priv->assoc.ssid.len; + memcpy(info.ssid.val, priv->assoc.ssid.val, info.ssid.len); + memcpy(info.bssid.octet, priv->assoc.mac.octet, IFHWADDRLEN); + switch (priv->assoc.alg) + { + case IW_ENCODE_ALG_NONE: + info.security_type = RTW_SECURITY_OPEN; + break; + case IW_ENCODE_ALG_WEP: + info.security_type = RTW_SECURITY_WEP_PSK; + break; + case IW_ENCODE_ALG_CCMP: + default: + info.security_type = RTW_SECURITY_WPA2_MIXED_PSK; + } + + pinfo = &info; + memcpy(data + (IFHWADDRLEN + 2), &pinfo, sizeof(pinfo)); + bssid_conn = true; + } + + ret = amebaz_state_run(state, AMEBAZ_CONNECT_TIMEOUT_TICK); + if (ret < 0) + { + return ret; + } + + if ((priv->mode == RTW_MODE_AP && priv->devnum == 0) || + (priv->mode == RTW_MODE_STA_AP && priv->devnum == 1)) + { + ret = amebaz_wl_add_custom_ie(priv, priv->devnum); + if (ret < 0) + { + wlwarn("unable to update the custom ie\n"); + } + } + + if (priv->mode == RTW_MODE_AP || priv->mode == RTW_MODE_STA_AP) + { + ret = rltk_wlan_control(SIOCSIWPRIVAPESSID, iwr); + } + + else if (priv->mode == RTW_MODE_STA) + { + if (bssid_conn) + { + ret = rltk_wlan_control(SIOCSIWAP, &_iwr); + } + + else + { + ret = rltk_wlan_control(SIOCSIWESSID, iwr); + } + } + + else + { + ret = -EINVAL; + } + + if (ret < 0) + { + goto exit_failed; + } + + if ((ret = amebaz_state_wait(state)) < 0) + { + goto exit_failed; + } + + if (state->status == AMEBAZ_STATUS_TIMEOUT) + { + ret = -ETIME; + } + + else if (state->status != AMEBAZ_STATUS_DONE) + { + ret = -ENXIO; + } + +exit_failed: + if (ret < 0) + { + amebaz_state_post(state, AMEBAZ_STATUS_DISABLED); + priv->assoc.alg = IW_ENCODE_ALG_NONE; + } + + else + { + state->status = AMEBAZ_STATUS_DONE; + } + + priv->assoc.mask = 0; + return ret; +} + +int amebaz_wl_set_ssid(FAR struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + if (!iwr->u.essid.flags) + { + return rltk_wlan_control(SIOCSIWESSID, iwr); + } + + memcpy(priv->assoc.ssid.val, iwr->u.essid.pointer, iwr->u.essid.length); + priv->assoc.ssid.len = iwr->u.essid.length; + priv->assoc.mask |= AMEBAZ_ASSOCIATE_SSID; + return amebaz_wl_associate(priv, iwr); +} + +int amebaz_wl_set_bssid(FAR struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + struct _sockaddr_t *addr = (struct _sockaddr_t *)&iwr->u.ap_addr; + unsigned char null_mac[IFHWADDRLEN] = + { + }; + + char *data; + addr->sa_family = ARPHRD_ETHER; + data = addr->sa_data; + if (!memcmp(data, null_mac, sizeof(null_mac))) + { + /* set MAC address last byte to 1 + * since driver will filter the mac with all 0x00 or 0xff + */ + + data[IFHWADDRLEN - 1] = 1; + } + + else + { + memcpy(priv->assoc.mac.octet, data, IFHWADDRLEN); + priv->assoc.mask |= AMEBAZ_ASSOCIATE_BSSID; + return amebaz_wl_associate(priv, iwr); + } + + return rltk_wlan_control(SIOCSIWAP, iwr); +} + +static int amebaz_wl_disable_powersave(int devnum) +{ + char control[7 + 6] = "pm_set"; + struct iwreq iwr = + { + }; + + snprintf(iwr.ifr_name, IFNAMSIZ, "wlan%d", devnum); + /* Command format: + * Entry[0...n]: + * 1. Type + * 2. Set/Unset + * 3. Value + */ + + enum + { + AMEBA_PMSET_MODE_IPS, + AMEBA_PMSET_MODE_LPS, + AMEBA_PMSET_MODE_TDMA, + AMEBA_PMSET_MODE_DTIM, + AMEBA_PMSET_MODE_BEACON, + AMEBA_PMSET_MODE_LPS_LEVEL, + AMEBA_PMSET_MODE_LPS_THRESHOLD, + AMEBA_PMSET_MODE_LPS_RF, + AMEBA_PMSET_MODE_RESUME, + }; + + control[7] = AMEBA_PMSET_MODE_IPS; + control[8] = 1; + control[9] = 0; + control[10] = AMEBA_PMSET_MODE_LPS; + control[11] = 1; + control[12] = 0; + iwr.u.data.pointer = control; + iwr.u.data.length = sizeof(control); + return rltk_wlan_control(SIOCDEVPRIVATE, &iwr); +} + +int amebaz_wl_set_mode(FAR struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + int mode; + int ret; + int count; + int i; + if (priv->devnum == 1) + { + if (iwr->u.mode == IW_MODE_MASTER) + { + mode = RTW_MODE_STA_AP; + } + + else + { + return -EINVAL; + } + } + + else + { + if (rltk_wlan_running(1)) + { + mode = RTW_MODE_STA; + ret = 0; + goto errout; + } + + if (iwr->u.mode == IW_MODE_MASTER) + { + mode = RTW_MODE_AP; + } + + else if (iwr->u.mode == IW_MODE_INFRA) + { + mode = RTW_MODE_STA; + } + + else + { + return -EINVAL; + } + } + + if (priv->mode == mode) + { + return OK; + } + + if (priv->mode != RTW_MODE_NONE) + { + if (priv->mode == RTW_MODE_STA && mode == RTW_MODE_AP) + { + if (priv->conn.status == AMEBAZ_STATUS_DONE) + { + return -EINVAL; + } + } + + else if (priv->mode == RTW_MODE_AP && mode == RTW_MODE_STA) + { + return -EINVAL; + } + } + + if (priv->mode == RTW_MODE_NONE && + rltk_wlan_running(priv->devnum) == false) + { + if (priv->devnum == 1 && rltk_wlan_running(0) == true) + { + ret = rltk_set_mode_prehandle(RTW_MODE_STA, + RTW_MODE_STA_AP, "wlan0"); + if (ret < 0) + { + goto errout; + } + + rtw_msleep_os(50); + ret = rltk_set_mode_posthandle(RTW_MODE_STA, + RTW_MODE_STA_AP, "wlan0"); + if (ret < 0) + { + goto errout; + } + } + + else + { + count = (mode == RTW_MODE_STA_AP) ? AMEBAZ_DEVICE_COUNT : 1; + for (i = 0; i < count; i++) + { + ret = rltk_wlan_init(i, mode); + if (ret < 0) + { + goto errout; + } + + extern void up_irq_attach_workaround(void); + up_irq_attach_workaround(); + } + + for (i = 0; i < count; i++) + { + ret = rltk_wlan_start(i); + if (ret < 0) + { + goto errout; + } + } + + while (!rltk_wlan_running(priv->devnum)) + { + usleep(1000); + } + + ret = amebaz_wl_disable_powersave(0); + if (ret < 0) + { + goto errout; + } + } + } + + ret = rltk_wlan_control(SIOCSIWMODE, iwr); +errout: + if (ret) + { + rltk_wlan_deinit(); + mode = RTW_MODE_NONE; + } + + priv->mode = mode; + return ret; +} + +int amebaz_wl_set_country(FAR struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + const char *country = iwr->u.essid.pointer; + int32_t cc = RTW_COUNTRY_WORLD1; + int ret; + if (!strncmp(country, "CN", 2)) + { + } + + else if (!strncmp(country, "CA", 2)) + { + cc = RTW_COUNTRY_CA; + } + + else if (!strncmp(country, "CO", 2)) + { + cc = RTW_COUNTRY_CO; + } + + else if (!strncmp(country, "DO", 2)) + { + cc = RTW_COUNTRY_DO; + } + + else if (!strncmp(country, "GT", 2)) + { + cc = RTW_COUNTRY_GT; + } + + else if (!strncmp(country, "MX", 2)) + { + cc = RTW_COUNTRY_MX; + } + + else if (!strncmp(country, "PA", 2)) + { + cc = RTW_COUNTRY_PA; + } + + else if (!strncmp(country, "PR", 2)) + { + cc = RTW_COUNTRY_PR; + } + + else if (!strncmp(country, "US", 2)) + { + cc = RTW_COUNTRY_US; + } + + else if (!strncmp(country, "TW", 2)) + { + cc = RTW_COUNTRY_TW; + } + + else if (!strncmp(country, "JP", 2)) + { + cc = RTW_COUNTRY_JP; + } + + else if (!strncmp(country, "IL", 2)) + { + cc = RTW_COUNTRY_IL; + } + + iwr->u.essid.pointer = NULL; + iwr->u.param.value = cc; + ret = rltk_wlan_control(SIOCSIWPRIVCOUNTRY, iwr); + if (ret == 0) + { + memcpy(priv->country, country, 2); + } + + iwr->u.essid.pointer = (void *)country; + return ret; +} + +int amebaz_wl_set_freq(FAR struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + priv->assoc.channel = iwr->u.freq.m; + priv->assoc.mask |= AMEBAZ_ASSOCIATE_CHANNEL; + return 0; +} + +int amebaz_wl_get_freq(FAR struct amebaz_dev_s *priv, struct iwreq *iwr) +{ + int ret; + ret = rltk_wlan_control(SIOCGIWFREQ, iwr); + if (ret == 0) + { + iwr->u.freq.m = iwr->u.freq.i; + } + + return ret; +} + +static struct amebaz_dev_s *amebaz_allocate_device(int devnum) +{ + FAR struct amebaz_dev_s *priv; + int ret; + priv = (FAR struct amebaz_dev_s *)kmm_zalloc(sizeof(*priv)); + if (!priv) + { + return NULL; + } + + ret = amebaz_state_init(&priv->scan); + ret |= amebaz_state_init(&priv->conn); + if (ret) + { + kmm_free(priv); + return NULL; + } + + memcpy(priv->country, AMEBAZ_DEFAULT_COUNTRY, 2); + priv->devnum = devnum; + return priv; +} + +static void amebaz_free_device(FAR struct amebaz_dev_s *priv) +{ + amebaz_state_deinit(&priv->scan); + amebaz_state_deinit(&priv->conn); + kmm_free(priv); +} + +static int amebaz_wl_on(int mode) +{ + int ret = -1; + for (int i = 0; i < 2; i++) + { + ret = rltk_wlan_init(i, mode); + if (ret < 0) + { + return ret; + } + } + + extern void up_irq_attach_workaround(void); + up_irq_attach_workaround(); + for (int i = 0; i < 2; i++) + { + ret = rltk_wlan_start(i); + if (ret < 0) + { + return ret; + } + + while (!rltk_wlan_running(gp_wlan_dev[i]->devnum)) + { + usleep(1000); + } + } + + ret = amebaz_wl_disable_powersave(0); + return ret; +} + +int amebaz_wl_initialize(unsigned char mode) +{ + FAR struct amebaz_dev_s *priv; + struct iwreq wrq = + { + }; + + int ret; + int i; + for (i = 0; i < 2; i++) + { + priv = amebaz_allocate_device(i); + if (!priv) + { + ret = -ENOMEM; + goto free_dev; + } + + ret = amebaz_netdev_register(priv); + if (ret < 0) + { + amebaz_free_device(priv); + goto free_dev; + } + + gp_wlan_dev[i] = priv; + } + + if (mode == RTW_MODE_STA_AP) + { + return amebaz_wl_on(RTW_MODE_STA_AP); + } + + else + { + strncpy(wrq.ifr_name, "wlan0", IFNAMSIZ); + wrq.u.mode = IW_MODE_INFRA; + return amebaz_wl_set_mode(gp_wlan_dev[0], &wrq); + } + +free_dev: + for (i = 0; gp_wlan_dev[i]; i++) + { + netdev_unregister(&gp_wlan_dev[i]->dev); + amebaz_free_device(gp_wlan_dev[i]); + gp_wlan_dev[i] = NULL; + } + + return ret; +} + diff --git a/arch/arm/src/rtl8720c/amebaz_driver.h b/arch/arm/src/rtl8720c/amebaz_driver.h new file mode 100644 index 00000000000..ed97f0b681f --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_driver.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_driver.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_DRIVER_H +#define __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_DRIVER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "amebaz_wlan.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AMEBAZ_SCAN_AP_COUNT (10) +enum +{ + AMEBAZ_STATUS_DONE = 0, + AMEBAZ_STATUS_DISABLED, + AMEBAZ_STATUS_RUN, + AMEBAZ_STATUS_TIMEOUT, +}; + +enum +{ + AMEBAZ_ASSOCIATE_SSID = 0x1, + AMEBAZ_ASSOCIATE_BSSID = 0x2, + AMEBAZ_ASSOCIATE_ALG = 0x4, + AMEBAZ_ASSOCIATE_CHANNEL = 0x8, + AMEBAZ_ASSOCIATE_MASK = 0xf, +}; + +struct amebaz_state_s +{ + sem_t mutex; + struct wdog_s timeout; + int status; +}; + +struct amebaz_associate_s +{ + rtw_ssid_t ssid; + rtw_mac_t mac; + uint8_t alg; + unsigned int channel; + uint8_t mask; +}; + +struct amebaz_dev_s +{ + struct net_driver_s dev; + int devnum; + struct amebaz_state_s scan; + struct amebaz_state_s conn; + struct work_s pollwork; + struct wdog_s txpoll; + struct sk_buff *curr; + int mode; + struct amebaz_associate_s assoc; + rtw_scan_result_t scan_data[AMEBAZ_SCAN_AP_COUNT]; + unsigned int scan_count; + unsigned char country[2]; +}; + +int amebaz_wl_start_scan(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_get_scan_results(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_set_encode_ext(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_get_encode_ext(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_set_ssid(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_set_bssid(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_set_mode(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_set_country(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_get_freq(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_set_freq(FAR struct amebaz_dev_s *priv, + struct iwreq *iwr); +int amebaz_wl_process_command(FAR struct amebaz_dev_s *priv, + int cmd, void *req); +void amebaz_wl_connection_handler(int index, + union iwreq_data *wrqu, char *extra); +void amebaz_wl_scan_handler(int index, + union iwreq_data *wrqu, char *extra); +void amebaz_wl_netif_info_handler(int index, void *dev, + unsigned char *addr); +void amebaz_wl_notify_rx_handler(int index, unsigned int len); + +#endif /* __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_DRIVER_H */ diff --git a/arch/arm/src/rtl8720c/amebaz_firmware.c b/arch/arm/src/rtl8720c/amebaz_firmware.c new file mode 100644 index 00000000000..8a1b1eb4fb1 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_firmware.c @@ -0,0 +1,1405 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_firmware.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_ARCH_CHIP_AMEBAZ_D_CUT +const unsigned char rtl_vendor_command[] = +{ + 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, 0x64, 0xb2, 0x40, 0x9a, + 0x64, 0xb3, 0x65, 0xb0, 0x42, 0x34, 0x82, 0x34, 0x80, 0xcb, 0x64, 0xb3, + 0x40, 0xcb, 0x64, 0xb2, 0x40, 0xea, 0x00, 0x69, 0x63, 0xb3, 0x64, 0xb2, + 0x60, 0xda, 0x64, 0xb3, 0x64, 0xb2, 0x60, 0xda, 0x64, 0xb3, 0x65, 0xb2, + 0x60, 0xda, 0x65, 0xb3, 0x65, 0xb2, 0x60, 0xda, 0x65, 0xb3, 0x66, 0xb2, + 0x60, 0xda, 0x66, 0xb3, 0x66, 0xb2, 0x60, 0xda, 0x66, 0xb3, 0x67, 0xb2, + 0x60, 0xda, 0x67, 0xb3, 0x67, 0xb2, 0x60, 0xda, 0xa0, 0xf0, 0x4b, 0xa0, + 0xa0, 0xf0, 0x6a, 0xa0, 0x40, 0x32, 0x6d, 0xea, 0xa0, 0xf0, 0x6c, 0xa0, + 0x60, 0x33, 0x60, 0x33, 0x4d, 0xeb, 0xa0, 0xf0, 0x4d, 0xa0, 0x00, 0xf6, + 0x40, 0x32, 0x6d, 0xea, 0x08, 0xf0, 0x01, 0x6b, 0x6b, 0xeb, 0x6c, 0xea, + 0x42, 0x33, 0xa0, 0xf0, 0x4a, 0xc0, 0xa0, 0xf0, 0x6b, 0xc0, 0x00, 0xf6, + 0x42, 0x32, 0x62, 0x33, 0xa0, 0xf0, 0x6c, 0xc0, 0xa0, 0xf0, 0x4d, 0xc0, + 0x57, 0xb3, 0x58, 0xb2, 0x60, 0xda, 0x58, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x57, 0xb3, 0x58, 0xb2, 0x60, 0xda, 0x58, 0xb3, 0x58, 0xb2, 0x60, 0xda, + 0x58, 0xb3, 0x59, 0xb2, 0x66, 0xda, 0x59, 0xb2, 0x20, 0xc2, 0x59, 0xb3, + 0x59, 0xb2, 0x60, 0xda, 0x59, 0xb3, 0x5a, 0xb2, 0x65, 0xda, 0x5a, 0xb3, + 0x5a, 0xb2, 0x62, 0xda, 0x5a, 0xb3, 0x5b, 0xb2, 0x60, 0xda, 0x5b, 0xb3, + 0x5b, 0xb2, 0x60, 0xda, 0x40, 0xf1, 0x45, 0xa0, 0x40, 0xf1, 0x64, 0xa0, + 0x40, 0x32, 0x6d, 0xea, 0x02, 0x6b, 0x6b, 0xeb, 0x6c, 0xea, 0x40, 0xf1, + 0x44, 0xc0, 0x42, 0x32, 0x40, 0xf1, 0x45, 0xc0, 0x54, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x54, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x53, 0xb3, 0x54, 0xb2, + 0x60, 0xda, 0x54, 0xb2, 0x54, 0xb3, 0x60, 0xda, 0xe0, 0xf0, 0x23, 0xc0, + 0x51, 0x67, 0x44, 0x33, 0x52, 0xb4, 0x01, 0x4a, 0x6d, 0xe4, 0x18, 0x52, + 0x00, 0x6c, 0x80, 0xcb, 0xf8, 0x61, 0x50, 0xb3, 0x50, 0xb2, 0x60, 0xda, + 0x50, 0xb3, 0x51, 0xb2, 0x60, 0xda, 0x1f, 0xb2, 0xa0, 0xf0, 0x61, 0xa2, + 0xa0, 0xf0, 0x80, 0xa2, 0x60, 0x33, 0x8d, 0xeb, 0xef, 0xf7, 0x1f, 0x6c, + 0x8c, 0xeb, 0xa0, 0xf0, 0x60, 0xc2, 0x62, 0x33, 0xa0, 0xf0, 0x61, 0xc2, + 0xa0, 0xf0, 0x6f, 0xa2, 0xa0, 0xf0, 0x8e, 0xa2, 0x60, 0x33, 0x8d, 0xeb, + 0xa0, 0xf0, 0x90, 0xa2, 0x80, 0x34, 0x80, 0x34, 0x6d, 0xec, 0xa0, 0xf0, + 0x71, 0xa2, 0x00, 0xf6, 0x60, 0x33, 0x8d, 0xeb, 0x01, 0x6c, 0x8d, 0xeb, + 0x62, 0x34, 0xa0, 0xf0, 0x6e, 0xc2, 0xa0, 0xf0, 0x8f, 0xc2, 0x00, 0xf6, + 0x62, 0x33, 0x82, 0x34, 0xa0, 0xf0, 0x71, 0xc2, 0xa0, 0xf0, 0x90, 0xc2, + 0x3a, 0xb3, 0x23, 0xb2, 0x7f, 0xda, 0x3a, 0xb2, 0x00, 0x6b, 0x60, 0xca, + 0x07, 0x97, 0x06, 0x91, 0x05, 0x90, 0x00, 0xef, 0x04, 0x63, 0x00, 0x65, + 0xb4, 0x3f, 0x10, 0x80, 0x32, 0x01, 0x12, 0x80, 0x38, 0x01, 0x12, 0x80, + 0x30, 0x01, 0x12, 0x80, 0x9d, 0x3b, 0x10, 0x80, 0x45, 0x32, 0x10, 0x80, + 0xd0, 0x08, 0x12, 0x80, 0x51, 0x36, 0x10, 0x80, 0xcc, 0x05, 0x12, 0x80, + 0xf1, 0x35, 0x10, 0x80, 0xd8, 0x03, 0x12, 0x80, 0xad, 0x35, 0x10, 0x80, + 0xdc, 0x03, 0x12, 0x80, 0xbd, 0x34, 0x10, 0x80, 0x04, 0x06, 0x12, 0x80, + 0x6d, 0x33, 0x10, 0x80, 0xf0, 0x06, 0x12, 0x80, 0x71, 0x22, 0x10, 0x80, + 0xf8, 0x06, 0x12, 0x80, 0x4d, 0x33, 0x10, 0x80, 0xec, 0x05, 0x12, 0x80, + 0xe1, 0x37, 0x10, 0x80, 0x08, 0x07, 0x12, 0x80, 0xa1, 0x36, 0x10, 0x80, + 0x21, 0x2f, 0x10, 0x80, 0xe8, 0x08, 0x12, 0x80, 0xa1, 0x2f, 0x10, 0x80, + 0xcc, 0x04, 0x12, 0x80, 0x95, 0x2d, 0x10, 0x80, 0x38, 0x03, 0x12, 0x80, + 0x00, 0x3c, 0x12, 0x80, 0xed, 0x27, 0x10, 0x80, 0x8c, 0x08, 0x12, 0x80, + 0x49, 0x28, 0x10, 0x80, 0xe4, 0x03, 0x12, 0x80, 0x01, 0x3e, 0x10, 0x80, + 0x4c, 0x04, 0x12, 0x80, 0x55, 0x3c, 0x10, 0x80, 0xe0, 0x28, 0x12, 0x80, + 0xe5, 0x3c, 0x10, 0x80, 0xe0, 0x08, 0x12, 0x80, 0x25, 0x35, 0x10, 0x80, + 0xa9, 0x30, 0x00, 0x80, 0xe9, 0x22, 0x10, 0x80, 0xa4, 0x08, 0x12, 0x80, + 0xb8, 0x08, 0x12, 0x80, 0x01, 0x29, 0x10, 0x80, 0x04, 0x3c, 0x12, 0x80, + 0x59, 0x2b, 0x10, 0x80, 0xf0, 0x05, 0x12, 0x80, 0x6d, 0x3e, 0x10, 0x80, + 0xdc, 0x28, 0x12, 0x80, 0x31, 0x26, 0x10, 0x80, 0x3a, 0x3c, 0x12, 0x80, + 0x64, 0xa4, 0x43, 0xa4, 0xe0, 0xa5, 0x60, 0x33, 0x4d, 0xe3, 0xff, 0xf7, + 0x1f, 0x6a, 0x4c, 0xeb, 0x9f, 0xf5, 0x00, 0x73, 0x00, 0x6a, 0x0c, 0x61, + 0x1f, 0xf7, 0x00, 0x6b, 0xcc, 0xeb, 0xe9, 0xe4, 0x62, 0x33, 0x62, 0xc2, + 0x41, 0x47, 0xff, 0x6b, 0x6c, 0xea, 0x41, 0xc4, 0x40, 0xc5, 0x01, 0x6a, + 0x20, 0xe8, 0x00, 0x65, 0xff, 0x6b, 0x8c, 0xeb, 0x09, 0x5b, 0x12, 0x6a, + 0x19, 0x61, 0x0c, 0x73, 0x0a, 0x60, 0x0d, 0x73, 0x0f, 0x60, 0x0b, 0x6a, + 0x4e, 0xeb, 0x01, 0x5b, 0x78, 0x67, 0x0a, 0x6a, 0x6b, 0xeb, 0x20, 0xe8, + 0x6c, 0xea, 0x08, 0xb2, 0x00, 0xf1, 0x40, 0xaa, 0xa1, 0x5a, 0x08, 0x61, + 0x20, 0xe8, 0xa0, 0x6a, 0x04, 0xb2, 0x40, 0xf0, 0x48, 0xaa, 0x1f, 0x5a, + 0x01, 0x61, 0x1e, 0x6a, 0x20, 0xe8, 0x00, 0x65, 0x10, 0x23, 0x12, 0x80, + 0x20, 0xe8, 0x01, 0x6a, 0xff, 0xf7, 0x1f, 0x6a, 0x4c, 0xed, 0x8c, 0xea, + 0x09, 0x10, 0x01, 0x4a, 0x09, 0x6b, 0x7a, 0xea, 0x01, 0x2b, 0xe5, 0xe8, + 0xff, 0xf7, 0x1f, 0x6b, 0x10, 0xea, 0x6c, 0xea, 0x08, 0xb3, 0x80, 0xf0, + 0x92, 0xa3, 0x4e, 0xec, 0x09, 0x24, 0x48, 0x34, 0x8d, 0xe3, 0x60, 0x9b, + 0x80, 0xab, 0xe1, 0xf7, 0x1f, 0x6b, 0x8c, 0xeb, 0xae, 0xeb, 0xe9, 0x23, + 0x20, 0xe8, 0x00, 0x65, 0x4c, 0x0a, 0x12, 0x80, 0xff, 0xf7, 0x1f, 0x6a, + 0x4c, 0xed, 0x8c, 0xea, 0x09, 0x10, 0x01, 0x4a, 0x09, 0x6b, 0x7a, 0xea, + 0x01, 0x2b, 0xe5, 0xe8, 0xff, 0xf7, 0x1f, 0x6b, 0x10, 0xea, 0x6c, 0xea, + 0x08, 0xb3, 0x80, 0xf0, 0x92, 0xa3, 0x4e, 0xec, 0x09, 0x24, 0x48, 0x34, + 0x8d, 0xe3, 0x60, 0x9b, 0x80, 0xab, 0xe1, 0xf7, 0x1f, 0x6b, 0x8c, 0xeb, + 0xae, 0xeb, 0xe9, 0x2b, 0x20, 0xe8, 0x00, 0x65, 0x4c, 0x0a, 0x12, 0x80, + 0xff, 0xf7, 0x1f, 0x6a, 0x8c, 0xea, 0x09, 0x10, 0x01, 0x4a, 0x09, 0x6b, + 0x7a, 0xea, 0x01, 0x2b, 0xe5, 0xe8, 0xff, 0xf7, 0x1f, 0x6b, 0x10, 0xea, + 0x6c, 0xea, 0x07, 0xb3, 0x80, 0xf0, 0x92, 0xa3, 0x4e, 0xec, 0x06, 0x24, + 0x87, 0x42, 0x13, 0x4c, 0x88, 0x34, 0x8d, 0xe3, 0x61, 0x9b, 0xec, 0x2b, + 0x20, 0xe8, 0x00, 0x65, 0x4c, 0x0a, 0x12, 0x80, 0xfe, 0x63, 0x03, 0xd1, + 0x02, 0xd0, 0xff, 0x6a, 0x8c, 0xea, 0x28, 0xb6, 0x28, 0xb5, 0x29, 0xb0, + 0x29, 0xb4, 0x2a, 0xb7, 0x28, 0x22, 0x40, 0xae, 0xff, 0xf7, 0x1d, 0x6b, + 0x0a, 0x65, 0x28, 0x67, 0x2c, 0xeb, 0x60, 0xce, 0x26, 0xb6, 0xc0, 0xae, + 0x60, 0xad, 0xff, 0xf7, 0x1f, 0x6a, 0x0e, 0x65, 0xc0, 0xa0, 0x08, 0x67, + 0x4c, 0xeb, 0xd9, 0xe0, 0x00, 0xf4, 0x00, 0x68, 0xe0, 0xf3, 0x1f, 0x69, + 0x0b, 0xe8, 0x2c, 0xee, 0x0c, 0xeb, 0xcd, 0xeb, 0xdd, 0x67, 0x60, 0xce, + 0x60, 0xae, 0x60, 0xcd, 0x60, 0xac, 0xa8, 0x67, 0x6c, 0xea, 0x60, 0xa7, + 0x0c, 0xea, 0x6d, 0xe5, 0x2c, 0xeb, 0x6d, 0xea, 0x40, 0xce, 0x40, 0xae, + 0x1b, 0x10, 0x60, 0xae, 0xff, 0xf7, 0x1f, 0x6a, 0x02, 0x69, 0x4c, 0xeb, + 0x2d, 0xeb, 0x4c, 0xeb, 0x60, 0xce, 0x60, 0xad, 0x00, 0xa0, 0x00, 0xf4, + 0x00, 0x6e, 0x4c, 0xeb, 0xcb, 0xee, 0xcc, 0xeb, 0x0d, 0xeb, 0x1d, 0x67, + 0x60, 0xc8, 0x60, 0xa8, 0x60, 0xcd, 0x60, 0xac, 0x6c, 0xea, 0x60, 0xa7, + 0xcc, 0xea, 0x6d, 0xea, 0x40, 0xc8, 0x40, 0xa8, 0x40, 0xcc, 0x03, 0x91, + 0x02, 0x90, 0x20, 0xe8, 0x02, 0x63, 0x00, 0x65, 0x58, 0x12, 0x00, 0xb6, + 0x10, 0x12, 0x00, 0xb6, 0x34, 0x3c, 0x12, 0x80, 0x12, 0x12, 0x00, 0xb6, + 0x35, 0x3c, 0x12, 0x80, 0x36, 0x3c, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x04, 0xd0, 0x83, 0xa4, 0x05, 0x67, 0x12, 0x6a, 0x02, 0x5c, 0x0f, 0x60, + 0x0a, 0xb2, 0x20, 0xf0, 0x68, 0xa2, 0x01, 0x6a, 0x6c, 0xea, 0x03, 0x22, + 0x01, 0x74, 0x0c, 0x6a, 0x06, 0x60, 0x07, 0xb2, 0x80, 0xca, 0x07, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x00, 0x6a, 0x40, 0xc0, 0x05, 0x97, 0x04, 0x90, + 0x00, 0xef, 0x03, 0x63, 0x10, 0x23, 0x12, 0x80, 0x38, 0x3c, 0x12, 0x80, + 0xa5, 0x23, 0x10, 0x80, 0x62, 0xa4, 0x43, 0xa4, 0x01, 0x73, 0x13, 0x61, + 0x08, 0x5a, 0x11, 0x60, 0x0a, 0xb3, 0x40, 0xc3, 0x0a, 0xb4, 0x40, 0xf0, + 0xa4, 0xac, 0x07, 0x6b, 0x4c, 0xeb, 0x80, 0xf3, 0x01, 0x6a, 0x4b, 0xea, + 0x7c, 0x33, 0xac, 0xea, 0x6d, 0xea, 0x40, 0xf0, 0x44, 0xcc, 0x20, 0xe8, + 0x00, 0x6a, 0x20, 0xe8, 0x12, 0x6a, 0x00, 0x65, 0x34, 0x03, 0x12, 0x80, + 0x10, 0x23, 0x12, 0x80, 0xf7, 0x63, 0x11, 0x62, 0x10, 0xd1, 0x0f, 0xd0, + 0xff, 0x6a, 0x24, 0x67, 0x4c, 0xe9, 0x4c, 0xed, 0x47, 0x41, 0x4b, 0x4a, + 0x48, 0x32, 0x2f, 0xb3, 0x49, 0xe3, 0x02, 0x75, 0x00, 0x9a, 0x4f, 0x61, + 0xc3, 0xa0, 0x01, 0x6b, 0x46, 0x67, 0x6c, 0xea, 0x4a, 0x22, 0x24, 0x32, + 0x2a, 0xb4, 0x51, 0xe4, 0x41, 0xa4, 0x02, 0x72, 0x44, 0x61, 0x02, 0x6a, + 0x4b, 0xea, 0xcc, 0xea, 0x43, 0xc0, 0x40, 0xa4, 0x0f, 0x6d, 0x2c, 0xed, + 0xb4, 0x35, 0xc0, 0xf4, 0x40, 0x32, 0x6d, 0xed, 0x4d, 0xed, 0x7d, 0x67, + 0x60, 0xf2, 0x0f, 0x6a, 0x54, 0xcb, 0x21, 0xb2, 0x80, 0x9a, 0x0b, 0x92, + 0x09, 0x96, 0x0a, 0x97, 0x08, 0xd5, 0x04, 0xd2, 0x1e, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x1e, 0xb2, 0x40, 0xea, 0x0c, 0x04, 0x7d, 0x67, 0x20, 0xf0, + 0x50, 0x83, 0x2a, 0xea, 0x0e, 0x60, 0x02, 0x6b, 0x04, 0xd3, 0x1a, 0xb3, + 0x06, 0xd2, 0x05, 0xd3, 0x07, 0xd1, 0x02, 0x6c, 0xc1, 0xf7, 0x19, 0x6e, + 0x01, 0xf5, 0x0b, 0x6f, 0x16, 0xb2, 0x40, 0xea, 0xfa, 0x6d, 0x59, 0x98, + 0x01, 0x4a, 0x04, 0x22, 0x87, 0x40, 0x14, 0xb2, 0x40, 0xea, 0x5d, 0x4c, + 0x58, 0x98, 0x01, 0x4a, 0x04, 0x22, 0x87, 0x40, 0x10, 0xb2, 0x40, 0xea, + 0x59, 0x4c, 0x09, 0xb2, 0x24, 0x31, 0x25, 0xe2, 0x00, 0x6a, 0x41, 0xc1, + 0x03, 0x10, 0x0d, 0xb2, 0x40, 0xea, 0x91, 0x67, 0x11, 0x97, 0x10, 0x91, + 0x0f, 0x90, 0x00, 0xef, 0x09, 0x63, 0x00, 0x65, 0x10, 0x23, 0x12, 0x80, + 0x44, 0x3c, 0x12, 0x80, 0x50, 0x0c, 0x12, 0x80, 0x2d, 0xdb, 0x00, 0x80, + 0xcd, 0xa8, 0x01, 0x80, 0xc0, 0x3e, 0x10, 0x80, 0xd1, 0x27, 0x01, 0x80, + 0x1d, 0xdd, 0x00, 0x80, 0x09, 0x12, 0x00, 0x80, 0xfc, 0x63, 0x07, 0x62, + 0x06, 0xd1, 0x05, 0xd0, 0x12, 0xb3, 0xff, 0xf7, 0x1f, 0x6c, 0x0e, 0xf0, + 0x01, 0x6a, 0x20, 0xab, 0x4b, 0xea, 0x00, 0x68, 0x8c, 0xe9, 0x2c, 0xea, + 0x8c, 0xea, 0x40, 0xcb, 0x08, 0x6a, 0x2c, 0xea, 0x08, 0x22, 0x87, 0x40, + 0xff, 0x6a, 0x01, 0x4c, 0x07, 0x6d, 0x4c, 0xec, 0x09, 0xb2, 0x40, 0xea, + 0x2c, 0xed, 0x01, 0x48, 0xff, 0x6a, 0x4c, 0xe8, 0x03, 0x58, 0x02, 0x60, + 0x32, 0x31, 0xee, 0x17, 0x07, 0x97, 0x06, 0x91, 0x05, 0x90, 0x00, 0xef, + 0x04, 0x63, 0x00, 0x65, 0x4a, 0x12, 0x00, 0xb6, 0xe5, 0x24, 0x10, 0x80, + 0xf6, 0x63, 0x13, 0x62, 0x12, 0xd1, 0x11, 0xd0, 0x14, 0xd4, 0x4d, 0xb4, + 0x42, 0xa4, 0x4d, 0xb3, 0xff, 0xf7, 0x1f, 0x6d, 0x0e, 0xd2, 0x40, 0xab, + 0x02, 0x6e, 0xcb, 0xee, 0xac, 0xea, 0xcc, 0xea, 0x40, 0xcb, 0x0e, 0x93, + 0x02, 0x73, 0x2f, 0x61, 0x47, 0xb2, 0x60, 0xaa, 0x47, 0xb2, 0xac, 0xeb, + 0x60, 0xca, 0x80, 0xf1, 0xf1, 0xa4, 0x01, 0x6a, 0xc7, 0x67, 0x4c, 0xee, + 0x2a, 0x26, 0x44, 0xb6, 0xff, 0x68, 0xc0, 0xae, 0xac, 0xee, 0xcc, 0xed, + 0xa2, 0x35, 0xbe, 0x35, 0x0c, 0xed, 0xac, 0xea, 0x44, 0x30, 0x03, 0x6a, + 0x4b, 0xea, 0xec, 0xea, 0x0d, 0xea, 0x80, 0xf1, 0x51, 0xc4, 0x02, 0x6c, + 0x8c, 0xea, 0x17, 0x22, 0x3b, 0xb2, 0x04, 0xd4, 0x05, 0xd2, 0x06, 0xd5, + 0x07, 0xd6, 0x0f, 0xd3, 0x01, 0xf7, 0x1d, 0x6e, 0x42, 0xf2, 0x0b, 0x6f, + 0x37, 0xb2, 0x40, 0xea, 0xfa, 0x6d, 0x00, 0x6c, 0x24, 0x67, 0x0f, 0x93, + 0x08, 0x10, 0x80, 0xf1, 0x2c, 0xac, 0x00, 0x6b, 0x80, 0xf1, 0x8e, 0xac, + 0x02, 0x10, 0x00, 0x6c, 0x24, 0x67, 0x00, 0x6d, 0x29, 0xb2, 0xa2, 0xc2, + 0x2f, 0xb5, 0xff, 0xf7, 0x1f, 0x68, 0x04, 0xf0, 0x01, 0x6e, 0x40, 0xad, + 0xcb, 0xee, 0xc1, 0xf4, 0x19, 0x6f, 0x0c, 0xea, 0xcc, 0xea, 0xe3, 0xf7, + 0x00, 0x4e, 0xcc, 0xea, 0x10, 0x4e, 0xcc, 0xea, 0x0c, 0xea, 0x40, 0xcd, + 0x27, 0xb5, 0xef, 0xf7, 0x1f, 0x6a, 0xc0, 0xad, 0xcc, 0xea, 0x0c, 0xea, + 0x40, 0xcd, 0x05, 0x6a, 0x04, 0xd2, 0x20, 0xb2, 0x05, 0xd2, 0x0e, 0x92, + 0x08, 0xd1, 0x09, 0xd3, 0x06, 0xd2, 0x00, 0x6a, 0x07, 0xd2, 0x0a, 0xd4, + 0x41, 0xf7, 0x07, 0x6e, 0x06, 0x6c, 0x1b, 0xb2, 0x40, 0xea, 0xfa, 0x6d, + 0x14, 0xb3, 0x01, 0x6c, 0x40, 0xab, 0x0c, 0xea, 0x8d, 0xea, 0x0c, 0xea, + 0x40, 0xcb, 0x19, 0xb3, 0x0c, 0x00, 0xb0, 0x67, 0x40, 0x9b, 0x8d, 0xea, + 0x40, 0xdb, 0x14, 0x93, 0x16, 0xb2, 0x40, 0xea, 0x80, 0xab, 0x5d, 0x67, + 0x00, 0x6b, 0x20, 0xf0, 0x34, 0xc2, 0x22, 0x31, 0x20, 0xf0, 0x73, 0xc2, + 0x20, 0xf0, 0x35, 0xc2, 0xb0, 0x67, 0x0e, 0x6c, 0x10, 0xb2, 0x40, 0xea, + 0x06, 0x6e, 0x13, 0x97, 0x12, 0x91, 0x11, 0x90, 0x00, 0x6a, 0x00, 0xef, + 0x0a, 0x63, 0x00, 0x65, 0x10, 0x23, 0x12, 0x80, 0x56, 0x10, 0x00, 0xb6, + 0x0e, 0x11, 0x00, 0xb6, 0x3a, 0x3c, 0x12, 0x80, 0x12, 0x11, 0x00, 0xb6, + 0xc0, 0x3e, 0x10, 0x80, 0xd1, 0x27, 0x01, 0x80, 0x34, 0x11, 0x00, 0xb6, + 0x38, 0x11, 0x00, 0xb6, 0x10, 0xa3, 0x00, 0xb0, 0x95, 0x2b, 0x01, 0x80, + 0x01, 0x4b, 0x00, 0x80, 0x00, 0x6a, 0x40, 0xc5, 0x41, 0xc5, 0x42, 0xc5, + 0x43, 0xc5, 0x44, 0xc5, 0x00, 0x6a, 0x10, 0xb3, 0x4d, 0xe3, 0xc0, 0xa3, + 0xff, 0x6b, 0x07, 0x6f, 0xc4, 0x36, 0x6c, 0xee, 0xce, 0x33, 0x6d, 0xe4, + 0x60, 0xa3, 0xec, 0xee, 0x67, 0xee, 0x03, 0x6e, 0xcc, 0xeb, 0x03, 0x73, + 0x08, 0x61, 0x4e, 0x36, 0xd9, 0xe5, 0x4c, 0xef, 0x01, 0x6b, 0x64, 0xef, + 0xe0, 0xa6, 0xed, 0xeb, 0x60, 0xc6, 0x01, 0x4a, 0xff, 0x6b, 0x6c, 0xea, + 0x25, 0x5a, 0xe3, 0x61, 0x20, 0xe8, 0x00, 0x65, 0xd8, 0xee, 0x01, 0x80, + 0xfb, 0x63, 0x09, 0x62, 0x08, 0xd1, 0x07, 0xd0, 0xff, 0x6a, 0x4c, 0xed, + 0x20, 0xa4, 0x0f, 0x25, 0x14, 0x6b, 0x78, 0xe9, 0x10, 0xb3, 0x04, 0xd3, + 0x12, 0xe9, 0x4c, 0xe9, 0x81, 0x41, 0x40, 0xeb, 0x4c, 0xec, 0x04, 0x93, + 0x42, 0x30, 0x91, 0x67, 0x40, 0xeb, 0x02, 0x30, 0x0b, 0x10, 0x1e, 0x6b, + 0xf8, 0x49, 0x78, 0xe9, 0x12, 0xec, 0x01, 0x4c, 0x4c, 0xec, 0x08, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x42, 0x30, 0x02, 0x30, 0x01, 0x58, 0x09, 0x97, + 0x08, 0x91, 0x07, 0x90, 0x58, 0x67, 0x00, 0xef, 0x05, 0x63, 0x00, 0x65, + 0x81, 0xa9, 0x01, 0x80, 0xd9, 0xa9, 0x01, 0x80, 0xfb, 0x63, 0x09, 0x62, + 0x08, 0xd1, 0x07, 0xd0, 0x1d, 0xa4, 0x3c, 0xa4, 0x7d, 0x67, 0x00, 0x30, + 0x2d, 0xe8, 0xff, 0xf7, 0x1f, 0x6a, 0x65, 0x58, 0xac, 0xea, 0x20, 0xf0, + 0xb8, 0xa3, 0x20, 0xf0, 0x7c, 0xa3, 0x04, 0x60, 0x64, 0x68, 0x1c, 0xc4, + 0x00, 0x68, 0x1d, 0xc4, 0x04, 0xd5, 0xa2, 0x67, 0x04, 0xb2, 0x40, 0xea, + 0x05, 0xd3, 0x09, 0x97, 0x08, 0x91, 0x07, 0x90, 0x00, 0xef, 0x05, 0x63, + 0xd9, 0x6d, 0x01, 0x80, 0xfd, 0x63, 0x05, 0x62, 0xff, 0x6a, 0x4c, 0xec, + 0x03, 0x24, 0x01, 0x74, 0x08, 0x60, 0x0f, 0x10, 0x09, 0xb3, 0xa0, 0xa3, + 0x04, 0x6c, 0xad, 0xec, 0x4c, 0xec, 0x80, 0xc3, 0x05, 0x10, 0x06, 0xb2, + 0x80, 0xa2, 0xfb, 0x6b, 0x6c, 0xec, 0x80, 0xc2, 0x04, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x3e, 0x3c, 0x12, 0x80, + 0x55, 0x1e, 0x01, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x0a, 0xb2, 0x60, 0xaa, + 0xff, 0xf7, 0x1f, 0x6a, 0x6c, 0xea, 0x42, 0x32, 0x3f, 0x6b, 0x6c, 0xea, + 0x09, 0x5a, 0x06, 0x61, 0x06, 0xb2, 0x40, 0xaa, 0x03, 0x22, 0x06, 0xb2, + 0x40, 0xea, 0x00, 0x6c, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, + 0xc8, 0x10, 0x00, 0xb6, 0x38, 0x3c, 0x12, 0x80, 0x8d, 0x28, 0x10, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x04, 0xd0, 0x60, 0xa4, 0x02, 0x6a, 0x05, 0x67, + 0x6c, 0xea, 0x03, 0x22, 0x0e, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x61, 0xa0, + 0x40, 0x6a, 0x6c, 0xea, 0x06, 0x22, 0x0c, 0xb2, 0x40, 0xaa, 0x03, 0x22, + 0x0b, 0xb2, 0x40, 0xea, 0x01, 0x6c, 0x60, 0xa0, 0x80, 0x6a, 0x4b, 0xea, + 0x6c, 0xea, 0xff, 0x6b, 0x6c, 0xea, 0x03, 0x22, 0x07, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x05, 0x97, 0x04, 0x90, 0x00, 0x6a, 0x00, 0xef, 0x03, 0x63, + 0xc9, 0x28, 0x10, 0x80, 0x38, 0x3c, 0x12, 0x80, 0x8d, 0x28, 0x10, 0x80, + 0xd9, 0x25, 0x10, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x04, 0xd0, 0xff, 0x6a, + 0xff, 0xf7, 0x1f, 0x68, 0xac, 0xea, 0x8c, 0xe8, 0x0b, 0x22, 0x14, 0xb3, + 0x08, 0x32, 0x49, 0xe3, 0x13, 0xb3, 0xa0, 0x9a, 0x13, 0xb2, 0x40, 0xea, + 0x87, 0x9b, 0x13, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0e, 0xb3, 0x08, 0x34, + 0x00, 0x6a, 0x91, 0xe3, 0x40, 0xdc, 0x87, 0x40, 0x25, 0x4c, 0x84, 0x34, + 0x91, 0xe3, 0x41, 0xcc, 0x87, 0x40, 0x01, 0x4c, 0x88, 0x34, 0x91, 0xe3, + 0x41, 0xdc, 0x87, 0x40, 0x1d, 0x4c, 0x1a, 0x48, 0x08, 0x30, 0x84, 0x34, + 0x91, 0xe3, 0x0d, 0xe3, 0x40, 0xcc, 0x41, 0xdb, 0x05, 0x97, 0x04, 0x90, + 0x00, 0xef, 0x03, 0x63, 0x4c, 0x0a, 0x12, 0x80, 0x1c, 0x0b, 0x12, 0x80, + 0xe1, 0xdd, 0x00, 0x80, 0x1d, 0xda, 0x00, 0x80, 0xfb, 0x63, 0x09, 0x62, + 0x08, 0xd1, 0x07, 0xd0, 0xff, 0xf7, 0x1f, 0x6b, 0x6c, 0xec, 0x04, 0xd4, + 0x04, 0x95, 0x59, 0xb4, 0x59, 0xb1, 0xa4, 0x32, 0x59, 0xb5, 0x49, 0xe5, + 0xc0, 0xaa, 0xa2, 0xac, 0xb5, 0xe6, 0xa2, 0xcc, 0x00, 0x6c, 0x80, 0xca, + 0x80, 0xf0, 0x93, 0xa1, 0x55, 0xb2, 0x40, 0xea, 0x05, 0xd3, 0x82, 0x67, + 0x54, 0xb2, 0x40, 0xea, 0x04, 0x95, 0x02, 0x67, 0x05, 0x93, 0x80, 0xf0, + 0x52, 0xa1, 0x4c, 0xeb, 0x0e, 0xeb, 0x80, 0xf0, 0x0f, 0x23, 0x04, 0x95, + 0x4f, 0xb2, 0x40, 0xea, 0x90, 0x67, 0x22, 0x67, 0x57, 0x10, 0x08, 0x32, + 0x4d, 0xe3, 0x40, 0x9b, 0x60, 0xaa, 0xe1, 0xf7, 0x1f, 0x6a, 0x6c, 0xea, + 0x04, 0x93, 0x4e, 0xeb, 0x49, 0xb2, 0x03, 0x2b, 0x90, 0x67, 0x01, 0x6d, + 0x02, 0x10, 0x90, 0x67, 0x00, 0x6d, 0x40, 0xea, 0x00, 0x65, 0x87, 0x41, + 0x13, 0x4c, 0x3f, 0xb2, 0x88, 0x34, 0x67, 0x40, 0x91, 0xe2, 0x81, 0x9c, + 0x13, 0x4b, 0x68, 0x33, 0x6d, 0xe2, 0x81, 0xdb, 0x28, 0x34, 0x91, 0xe2, + 0x80, 0x9c, 0x08, 0x33, 0x6d, 0xe2, 0x80, 0xdb, 0x87, 0x41, 0x25, 0x4c, + 0x84, 0x34, 0x67, 0x40, 0x91, 0xe2, 0x81, 0xac, 0x25, 0x4b, 0x64, 0x33, + 0x6d, 0xe2, 0x81, 0xcb, 0x87, 0x41, 0x01, 0x4c, 0x88, 0x34, 0x67, 0x40, + 0x91, 0xe2, 0x81, 0x9c, 0x01, 0x4b, 0x68, 0x33, 0x6d, 0xe2, 0x81, 0xdb, + 0x67, 0x40, 0x87, 0x41, 0x1d, 0x4b, 0x1d, 0x4c, 0x84, 0x34, 0x64, 0x33, + 0x6d, 0xe2, 0x89, 0xe2, 0x40, 0xaa, 0x01, 0x49, 0x04, 0x95, 0x40, 0xcb, + 0x09, 0x6a, 0x5a, 0xe9, 0x01, 0x2a, 0xe5, 0xe8, 0xff, 0xf7, 0x1f, 0x6b, + 0x05, 0xd3, 0x28, 0xb2, 0x01, 0x48, 0x10, 0xec, 0x40, 0xea, 0x6c, 0xec, + 0x09, 0x6c, 0x9a, 0xe8, 0x01, 0x2c, 0xe5, 0xe8, 0x05, 0x93, 0x22, 0x67, + 0x10, 0xe8, 0x6c, 0xe8, 0x1d, 0xb3, 0x80, 0xf0, 0x52, 0xa3, 0x4a, 0xe9, + 0xa4, 0x61, 0x0b, 0xe2, 0x00, 0x52, 0x01, 0x60, 0x09, 0x4a, 0x19, 0xb3, + 0x80, 0xf0, 0x90, 0xab, 0x30, 0x67, 0x4b, 0xe4, 0x80, 0xf0, 0x50, 0xcb, + 0x1a, 0x10, 0x28, 0x33, 0x69, 0xe2, 0x40, 0x9a, 0x60, 0xaa, 0xe1, 0xf7, + 0x1f, 0x6a, 0x6c, 0xea, 0x04, 0x93, 0x4e, 0xeb, 0x15, 0xb2, 0x03, 0x2b, + 0x91, 0x67, 0x01, 0x6d, 0x02, 0x10, 0x91, 0x67, 0x00, 0x6d, 0x40, 0xea, + 0x01, 0x49, 0x09, 0x6a, 0x5a, 0xe9, 0x01, 0x2a, 0xe5, 0xe8, 0xff, 0xf7, + 0x1f, 0x6a, 0x10, 0xe9, 0x4c, 0xe9, 0x08, 0xb2, 0x80, 0xf0, 0x72, 0xa2, + 0x2e, 0xeb, 0xe1, 0x2b, 0x80, 0xf0, 0x12, 0xc2, 0x09, 0x97, 0x08, 0x91, + 0x07, 0x90, 0x00, 0xef, 0x05, 0x63, 0x00, 0x65, 0x70, 0x0c, 0x12, 0x80, + 0x4c, 0x0a, 0x12, 0x80, 0x04, 0x3c, 0x12, 0x80, 0x6d, 0x23, 0x10, 0x80, + 0x2d, 0x23, 0x10, 0x80, 0xed, 0x22, 0x10, 0x80, 0x59, 0x29, 0x10, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x40, 0xa4, 0x05, 0x72, 0x0d, 0x61, 0x09, 0xb2, + 0x20, 0xf0, 0x4c, 0xa2, 0x61, 0xa5, 0x82, 0xa5, 0x01, 0x72, 0x02, 0x60, + 0x03, 0x72, 0x04, 0x61, 0x80, 0x34, 0x05, 0xb2, 0x40, 0xea, 0x6d, 0xec, + 0x05, 0x97, 0x00, 0x6a, 0x00, 0xef, 0x03, 0x63, 0x78, 0x0c, 0x12, 0x80, + 0xc9, 0x29, 0x10, 0x80, 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, + 0x44, 0xb2, 0x80, 0xf0, 0x73, 0xa2, 0xff, 0x69, 0x8c, 0xe9, 0x1a, 0x4b, + 0x68, 0x33, 0x6d, 0xe2, 0x00, 0x6c, 0x81, 0xdb, 0x40, 0xb3, 0x20, 0xf0, + 0x6c, 0xa3, 0x01, 0x73, 0x09, 0x60, 0x03, 0x73, 0x07, 0x60, 0x80, 0xf0, + 0x73, 0xa2, 0x2c, 0x4b, 0x64, 0x33, 0x69, 0xe2, 0x41, 0xaa, 0x19, 0x2a, + 0x38, 0xb2, 0x80, 0xf0, 0x53, 0xa2, 0x39, 0xb3, 0xe1, 0xf7, 0x1f, 0x68, + 0x48, 0x32, 0x69, 0xe2, 0x40, 0xaa, 0x4c, 0xe8, 0x36, 0xb2, 0x40, 0xea, + 0x90, 0x67, 0x05, 0x2a, 0x35, 0xb2, 0x62, 0xaa, 0x01, 0x4b, 0x62, 0xca, + 0x06, 0x10, 0x34, 0xb2, 0x04, 0x30, 0x01, 0xe2, 0x40, 0xa8, 0x01, 0x4a, + 0x40, 0xc8, 0x2d, 0xb2, 0x20, 0xf0, 0x4c, 0xa2, 0x0a, 0x22, 0x02, 0x72, + 0x08, 0x60, 0x29, 0xb2, 0x80, 0xf0, 0x73, 0xa2, 0x2c, 0x4b, 0x64, 0x33, + 0x69, 0xe2, 0x41, 0xaa, 0x30, 0x2a, 0x05, 0x71, 0x24, 0xb4, 0x2a, 0xb5, + 0x2a, 0xb2, 0x09, 0x61, 0x80, 0xf0, 0x73, 0xa4, 0x68, 0x33, 0x6d, 0xe4, + 0x87, 0x9d, 0x40, 0xea, 0xa0, 0x9b, 0x27, 0xb2, 0x08, 0x10, 0x80, 0xf0, + 0x73, 0xa4, 0x68, 0x33, 0x6d, 0xe4, 0x83, 0x9d, 0x40, 0xea, 0xa0, 0x9b, + 0x23, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x19, 0xb2, 0x80, 0xf0, 0x73, 0xa2, + 0x00, 0x6c, 0x68, 0x33, 0x6d, 0xe2, 0x80, 0xdb, 0x80, 0xf0, 0x73, 0xa2, + 0xff, 0x6c, 0x01, 0x4b, 0x8c, 0xeb, 0x09, 0x6c, 0x9b, 0xeb, 0x01, 0x2c, + 0xe5, 0xe8, 0x10, 0xeb, 0x80, 0xf0, 0x73, 0xc2, 0x80, 0xf0, 0x70, 0xaa, + 0xff, 0x4b, 0x80, 0xf0, 0x70, 0xca, 0x0e, 0xb2, 0x20, 0xf0, 0x4c, 0xa2, + 0x01, 0x72, 0x02, 0x60, 0x03, 0x72, 0x0c, 0x61, 0x09, 0xb2, 0x80, 0xf0, + 0x73, 0xa2, 0x1a, 0x4b, 0x68, 0x33, 0x69, 0xe2, 0x41, 0x9a, 0x04, 0x2a, + 0x0f, 0xb2, 0x40, 0x9a, 0x40, 0xea, 0x00, 0x65, 0x07, 0x97, 0x06, 0x91, + 0x05, 0x90, 0x00, 0xef, 0x04, 0x63, 0x00, 0x65, 0x4c, 0x0a, 0x12, 0x80, + 0x78, 0x0c, 0x12, 0x80, 0x70, 0x0a, 0x12, 0x80, 0x75, 0xca, 0x01, 0x80, + 0x70, 0x0c, 0x12, 0x80, 0x04, 0x3c, 0x12, 0x80, 0x1c, 0x0b, 0x12, 0x80, + 0xe1, 0xdd, 0x00, 0x80, 0x1d, 0xda, 0x00, 0x80, 0x89, 0xda, 0x00, 0x80, + 0x30, 0x00, 0x12, 0x80, 0xfa, 0x63, 0x0b, 0x62, 0x0a, 0xd1, 0x09, 0xd0, + 0x2b, 0xb2, 0x20, 0xf0, 0x4c, 0xa2, 0x04, 0x67, 0x49, 0x22, 0xa3, 0xa4, + 0x01, 0x69, 0x00, 0x6b, 0x16, 0x10, 0x82, 0xa0, 0x01, 0x4b, 0x68, 0x32, + 0x01, 0x4a, 0x42, 0xec, 0x41, 0x61, 0x29, 0xe0, 0x84, 0xa2, 0x43, 0xa2, + 0x06, 0xd3, 0x80, 0x34, 0x4d, 0xec, 0x22, 0xb2, 0x40, 0xea, 0x05, 0xd5, + 0x06, 0x93, 0x05, 0x95, 0x35, 0x22, 0xff, 0x6a, 0x04, 0x49, 0x4c, 0xe9, + 0x4c, 0xeb, 0xa3, 0xeb, 0xe8, 0x61, 0xa3, 0xa0, 0x01, 0x69, 0x00, 0x6a, + 0x27, 0x10, 0x2d, 0xe0, 0xff, 0x6c, 0x02, 0x49, 0x8c, 0xe9, 0x39, 0xe0, + 0x84, 0xa6, 0xc3, 0xa6, 0xe3, 0xa3, 0x80, 0x34, 0xcd, 0xec, 0x14, 0xb6, + 0x20, 0xf0, 0xcc, 0xa6, 0x64, 0xa3, 0x01, 0x76, 0x02, 0x60, 0x03, 0x76, + 0x08, 0x61, 0x60, 0x33, 0xed, 0xeb, 0x11, 0xb6, 0x64, 0x33, 0x6d, 0xe6, + 0xc0, 0xab, 0x9b, 0xe6, 0xc0, 0xcb, 0xff, 0x6b, 0x04, 0xd2, 0x06, 0xd3, + 0x05, 0xd5, 0x02, 0x49, 0x0c, 0xb6, 0x40, 0xee, 0x6c, 0xe9, 0x04, 0x92, + 0x06, 0x93, 0x05, 0x95, 0x01, 0x4a, 0x6c, 0xea, 0xa3, 0xea, 0xd7, 0x61, + 0x00, 0x6a, 0x01, 0x10, 0x12, 0x6a, 0x0b, 0x97, 0x0a, 0x91, 0x09, 0x90, + 0x00, 0xef, 0x06, 0x63, 0x78, 0x0c, 0x12, 0x80, 0x75, 0xca, 0x01, 0x80, + 0x04, 0x3c, 0x12, 0x80, 0x65, 0x55, 0x00, 0x80, 0xfa, 0x63, 0x0b, 0x62, + 0x0a, 0xd1, 0x09, 0xd0, 0x04, 0xa4, 0x43, 0xa4, 0xe6, 0x44, 0x00, 0x30, + 0x20, 0xa7, 0x67, 0xa4, 0x4d, 0xe8, 0x45, 0x44, 0x6a, 0x65, 0x40, 0xa2, + 0x20, 0x31, 0x01, 0x73, 0x4d, 0xe9, 0x06, 0xd3, 0x1b, 0x60, 0x03, 0xe9, + 0x19, 0x61, 0x20, 0x58, 0x17, 0x60, 0x00, 0x6d, 0x20, 0x6e, 0xa4, 0xc4, + 0xc3, 0xc4, 0x18, 0xb2, 0x60, 0xa2, 0x0d, 0x65, 0x01, 0x6d, 0x4b, 0x65, + 0x65, 0x67, 0xaa, 0x67, 0xad, 0xeb, 0x20, 0x59, 0x60, 0xc2, 0x08, 0x60, + 0xab, 0x67, 0x68, 0x67, 0x60, 0xc7, 0xc0, 0xc5, 0xc0, 0xa2, 0x02, 0x6d, + 0xcd, 0xed, 0xa0, 0xc2, 0x0f, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0f, 0x2a, + 0x06, 0x93, 0x01, 0x73, 0x0c, 0x60, 0x0b, 0xb3, 0x80, 0xa3, 0x01, 0x6b, + 0x8c, 0xeb, 0x02, 0x23, 0x0a, 0xb3, 0x16, 0xcb, 0x02, 0x6b, 0x8c, 0xeb, + 0x02, 0x23, 0x08, 0xb3, 0x37, 0xcb, 0x00, 0x6c, 0x04, 0xb3, 0x80, 0xc3, + 0x0b, 0x97, 0x0a, 0x91, 0x09, 0x90, 0x00, 0xef, 0x06, 0x63, 0x00, 0x65, + 0x01, 0x3c, 0x12, 0x80, 0x45, 0x4d, 0x01, 0x80, 0x10, 0x23, 0x12, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x04, 0xd0, 0x33, 0xb3, 0x20, 0xf0, 0xc8, 0xa3, + 0x05, 0x67, 0x01, 0x6d, 0xac, 0xee, 0x0c, 0x6a, 0x59, 0x2e, 0x30, 0xb2, + 0xc0, 0x9a, 0x20, 0xf1, 0x4c, 0xa3, 0x20, 0xf1, 0xea, 0xab, 0x24, 0x22, + 0x01, 0xf7, 0x00, 0x6a, 0xec, 0xea, 0xa4, 0xee, 0x43, 0x32, 0xff, 0x4d, + 0xa2, 0xea, 0x1c, 0x61, 0x20, 0xf0, 0x49, 0xa3, 0x1c, 0x6b, 0x6c, 0xea, + 0x04, 0x72, 0x01, 0x60, 0x15, 0x2a, 0x24, 0xb3, 0xb4, 0xab, 0x80, 0xf3, + 0x01, 0x6a, 0x4b, 0xea, 0xac, 0xea, 0xff, 0x6d, 0x01, 0x4d, 0xad, 0xea, + 0xff, 0xf7, 0x1f, 0x6d, 0x4c, 0xed, 0x54, 0xcb, 0x1d, 0x6a, 0xa2, 0x35, + 0x4b, 0xea, 0xac, 0xea, 0x0c, 0x6d, 0xad, 0xea, 0x20, 0xf0, 0x49, 0xc3, + 0x43, 0xa4, 0x01, 0x72, 0x00, 0x6a, 0x2a, 0x61, 0x17, 0xb2, 0x20, 0xf0, + 0x8a, 0xa2, 0x40, 0x6b, 0x8d, 0xeb, 0x20, 0xf0, 0x88, 0xa2, 0x20, 0xf0, + 0x6a, 0xc2, 0x01, 0x6b, 0x8d, 0xeb, 0x20, 0xf0, 0x68, 0xc2, 0x20, 0xf0, + 0x49, 0xa2, 0x07, 0x6b, 0x4a, 0x32, 0x6c, 0xea, 0x10, 0xb3, 0x49, 0xe3, + 0x80, 0xa2, 0x10, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x01, 0x72, 0x09, 0x61, + 0x0e, 0xb2, 0x40, 0xea, 0x00, 0x6c, 0xff, 0x72, 0x04, 0x60, 0x82, 0x67, + 0x0c, 0xb2, 0x40, 0xea, 0x01, 0x6d, 0x0c, 0xb2, 0x40, 0x9a, 0x40, 0xea, + 0x00, 0x65, 0x00, 0x6a, 0x40, 0xc0, 0x00, 0x6a, 0x05, 0x97, 0x04, 0x90, + 0x00, 0xef, 0x03, 0x63, 0x10, 0x23, 0x12, 0x80, 0xc8, 0x03, 0x12, 0x80, + 0x90, 0xee, 0x01, 0x80, 0xfd, 0xd0, 0x01, 0x80, 0x6d, 0xe6, 0x01, 0x80, + 0xa9, 0xe6, 0x01, 0x80, 0xd4, 0x04, 0x12, 0x80, 0xfc, 0x63, 0x07, 0x62, + 0x06, 0xd0, 0x19, 0xb0, 0x20, 0xf0, 0x4a, 0xa0, 0x40, 0x6b, 0x4c, 0xeb, + 0x00, 0x6a, 0x26, 0x23, 0x82, 0x67, 0x16, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x20, 0xf0, 0x68, 0xa0, 0x02, 0x6a, 0x4b, 0xea, 0x6c, 0xea, 0x20, 0xf0, + 0x6a, 0xa0, 0x20, 0xf0, 0x48, 0xc0, 0x41, 0x6a, 0x4b, 0xea, 0x6c, 0xea, + 0x20, 0xf0, 0x4a, 0xc0, 0x0e, 0xb2, 0x80, 0xa2, 0x02, 0x6d, 0x0e, 0xb2, + 0x40, 0xea, 0x04, 0x00, 0x9f, 0xf4, 0x07, 0x6c, 0x0c, 0xb2, 0x40, 0xea, + 0xb0, 0x67, 0x00, 0x6a, 0x7d, 0x67, 0x53, 0xc3, 0x0e, 0x6c, 0xb0, 0x67, + 0x09, 0xb2, 0x40, 0xea, 0x04, 0x6e, 0x01, 0x6a, 0x07, 0x97, 0x06, 0x90, + 0x00, 0xef, 0x04, 0x63, 0x10, 0x23, 0x12, 0x80, 0x91, 0x40, 0x00, 0x80, + 0x38, 0x05, 0x12, 0x80, 0xa9, 0xe6, 0x01, 0x80, 0x95, 0x2b, 0x01, 0x80, + 0x01, 0x4b, 0x00, 0x80, 0xfd, 0x63, 0x05, 0x62, 0xff, 0x6a, 0x8c, 0xea, + 0x05, 0x72, 0x21, 0x61, 0x14, 0xb3, 0x74, 0xab, 0x80, 0xf3, 0x00, 0x6c, + 0x8c, 0xeb, 0x03, 0x23, 0x00, 0xf3, 0x00, 0x73, 0x09, 0x61, 0x11, 0xb4, + 0xe0, 0xf1, 0x1f, 0x6b, 0xa0, 0xac, 0xac, 0xeb, 0x00, 0xf6, 0x00, 0x6d, + 0xad, 0xeb, 0x60, 0xcc, 0x0b, 0xb3, 0x20, 0xf0, 0x8a, 0xa3, 0x40, 0x6b, + 0x8c, 0xeb, 0x09, 0x23, 0x0a, 0xb4, 0xff, 0xf7, 0x1f, 0x6d, 0x10, 0x6e, + 0x60, 0xac, 0xac, 0xeb, 0xcd, 0xeb, 0xac, 0xeb, 0x60, 0xcc, 0x82, 0x67, + 0x06, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, + 0x10, 0x23, 0x12, 0x80, 0x40, 0x10, 0x00, 0xb6, 0x8e, 0x12, 0x00, 0xb6, + 0x71, 0xac, 0x01, 0x80, 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, + 0x14, 0xb2, 0x40, 0x9a, 0x09, 0xd5, 0x40, 0xea, 0x24, 0x67, 0x40, 0xd9, + 0x09, 0x92, 0x02, 0x2a, 0x19, 0x10, 0x40, 0xd9, 0x10, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x02, 0x67, 0x0d, 0xb2, 0x40, 0x9a, 0x40, 0xea, 0x00, 0x65, + 0x60, 0x99, 0x4e, 0xeb, 0xf4, 0x2b, 0x60, 0xf2, 0x11, 0x58, 0x05, 0x61, + 0x9f, 0xf5, 0x10, 0x48, 0xff, 0xf7, 0x1f, 0x6a, 0x4c, 0xe8, 0x60, 0xf2, + 0x10, 0x6a, 0x03, 0xe2, 0x09, 0x92, 0x00, 0xda, 0x07, 0x97, 0x06, 0x91, + 0x05, 0x90, 0x00, 0xef, 0x04, 0x63, 0x00, 0x65, 0x14, 0x00, 0x12, 0x80, + 0xa9, 0x38, 0x00, 0x80, 0xf9, 0x63, 0x0d, 0x62, 0x0c, 0xd1, 0x0b, 0xd0, + 0xff, 0x6a, 0xac, 0xea, 0x06, 0xd2, 0x00, 0x6a, 0x40, 0xdc, 0x4e, 0xa4, + 0x04, 0x67, 0x0f, 0x72, 0x5e, 0x60, 0x1d, 0x4a, 0x32, 0xb3, 0x50, 0x32, + 0x49, 0xe3, 0x21, 0x9a, 0x04, 0x04, 0x31, 0xb2, 0x40, 0xea, 0x00, 0x6d, + 0x04, 0x92, 0x30, 0xb4, 0xb1, 0x67, 0x0a, 0x6e, 0x4c, 0xec, 0x86, 0x34, + 0x2e, 0xb2, 0x40, 0xea, 0x04, 0xd4, 0x22, 0x67, 0x04, 0x92, 0x40, 0xd8, + 0x4f, 0xa0, 0x02, 0x72, 0x03, 0x60, 0x2b, 0xb2, 0x2e, 0xea, 0x01, 0x2a, + 0x00, 0x69, 0x25, 0xb3, 0xc0, 0xf1, 0xa2, 0xa3, 0x0c, 0x75, 0x10, 0x61, + 0x08, 0xd3, 0x07, 0xd5, 0x26, 0xb2, 0x40, 0xea, 0x0c, 0x6c, 0x43, 0xe9, + 0x08, 0x93, 0x07, 0x95, 0x07, 0x60, 0x4e, 0xa0, 0x0c, 0x72, 0x31, 0x61, + 0x01, 0x6a, 0xc0, 0xf1, 0x43, 0xc3, 0x27, 0x10, 0x8e, 0xa0, 0x8e, 0xed, + 0x11, 0x2d, 0x1e, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x23, 0xea, 0x25, 0x61, + 0x06, 0x94, 0x16, 0xb2, 0x90, 0x33, 0x6d, 0xe2, 0xc0, 0xf1, 0x46, 0x8a, + 0xc0, 0xf1, 0x6c, 0x8b, 0x01, 0x4a, 0x62, 0xea, 0x10, 0x60, 0x19, 0x10, + 0x06, 0x95, 0x10, 0xb2, 0x90, 0x34, 0xb0, 0x33, 0x6d, 0xe2, 0x91, 0xe2, + 0xc0, 0xf1, 0xae, 0x8b, 0xc0, 0xf1, 0x6e, 0x8c, 0xa2, 0xeb, 0x0d, 0x61, + 0x0f, 0x6b, 0xc0, 0xf1, 0x62, 0xc2, 0x01, 0x6b, 0x08, 0xb2, 0xc0, 0xf1, + 0x63, 0xc2, 0x0d, 0xb2, 0x0f, 0x6c, 0x40, 0xea, 0x01, 0x6d, 0x01, 0x6a, + 0x01, 0x10, 0x00, 0x6a, 0x0d, 0x97, 0x0c, 0x91, 0x0b, 0x90, 0x00, 0xef, + 0x07, 0x63, 0x00, 0x65, 0x10, 0x23, 0x12, 0x80, 0x0d, 0x30, 0x10, 0x80, + 0xff, 0xff, 0x07, 0x00, 0x55, 0x65, 0x00, 0x80, 0xff, 0xff, 0x03, 0x00, + 0xa5, 0x22, 0x10, 0x80, 0x6d, 0xa2, 0x01, 0x80, 0xfc, 0x63, 0x07, 0x62, + 0x06, 0xd1, 0x05, 0xd0, 0x00, 0x69, 0x04, 0x67, 0x01, 0x6c, 0x8b, 0xec, + 0x51, 0x67, 0x18, 0x10, 0x4d, 0xe0, 0x72, 0xa3, 0x70, 0x36, 0xd9, 0xe5, + 0xc0, 0xf1, 0xf0, 0xa6, 0x01, 0x4f, 0xc0, 0xf1, 0xf0, 0xc6, 0xe7, 0x43, + 0x16, 0x4f, 0xf0, 0x37, 0xf5, 0xe5, 0xe2, 0x98, 0xe2, 0xdd, 0xc0, 0xf1, + 0xac, 0x8e, 0xa2, 0xec, 0x02, 0x60, 0x85, 0x67, 0x23, 0x67, 0x01, 0x4a, + 0xff, 0x6b, 0x6c, 0xea, 0x20, 0xf0, 0x60, 0xa0, 0x21, 0xb5, 0x63, 0xea, + 0xe3, 0x61, 0x30, 0x32, 0x55, 0xe5, 0xc0, 0xf1, 0x4c, 0x8d, 0x00, 0xf4, + 0x00, 0x52, 0x09, 0x60, 0x90, 0x67, 0x1d, 0xb2, 0x40, 0xea, 0xb1, 0x67, + 0x04, 0x22, 0x20, 0xf0, 0x61, 0xa0, 0x08, 0x6a, 0x27, 0x10, 0x18, 0xb2, + 0x30, 0x33, 0x6d, 0xe2, 0xc0, 0xf1, 0x90, 0xa3, 0xc0, 0xf1, 0x84, 0xc2, + 0xc0, 0xf1, 0x8c, 0xab, 0xc0, 0xf1, 0x86, 0xca, 0x87, 0x41, 0x16, 0x4c, + 0x90, 0x34, 0x91, 0xe2, 0xa1, 0x9c, 0xc0, 0xf1, 0x22, 0xc2, 0xc0, 0xf1, + 0xa8, 0xda, 0x02, 0x6d, 0xc0, 0xf1, 0xa3, 0xc2, 0x00, 0x6a, 0xc0, 0xf1, + 0x50, 0xc3, 0xc0, 0xf1, 0x4e, 0xab, 0x02, 0x6d, 0xc0, 0xf1, 0x4c, 0xcb, + 0x42, 0x98, 0x41, 0xdc, 0x09, 0xb2, 0x40, 0xea, 0x91, 0x67, 0x20, 0xf0, + 0x61, 0xa0, 0x10, 0x6a, 0x6d, 0xea, 0x20, 0xf0, 0x41, 0xc0, 0x07, 0x97, + 0x06, 0x91, 0x05, 0x90, 0x00, 0xef, 0x04, 0x63, 0x10, 0x23, 0x12, 0x80, + 0x6d, 0x30, 0x10, 0x80, 0x6d, 0xa2, 0x01, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x04, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x05, 0x97, 0x01, 0x6a, 0x00, 0xef, + 0x03, 0x63, 0x00, 0x65, 0x6d, 0x31, 0x10, 0x80, 0xfa, 0x63, 0x0b, 0x62, + 0x0a, 0xd0, 0x00, 0x6b, 0x28, 0xb2, 0x60, 0xc2, 0x28, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x28, 0xb2, 0x40, 0xa2, 0x03, 0x2a, 0x27, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x27, 0xb2, 0x60, 0xaa, 0x27, 0xb2, 0x60, 0xc2, 0x27, 0xb2, + 0x60, 0xaa, 0x27, 0xb2, 0x60, 0xc2, 0xa0, 0xf1, 0x03, 0x6b, 0x26, 0xb2, + 0x60, 0xca, 0x26, 0xb2, 0x00, 0x6b, 0x60, 0xca, 0x00, 0x6a, 0x25, 0xb4, + 0x51, 0xe4, 0x80, 0xa4, 0x04, 0x00, 0x4d, 0xe0, 0x88, 0xc3, 0x01, 0x4a, + 0xff, 0x6b, 0x6c, 0xea, 0x0a, 0x5a, 0xf5, 0x61, 0x06, 0x04, 0x20, 0xb2, + 0x40, 0xea, 0xb0, 0x67, 0x1f, 0xb4, 0xb0, 0x67, 0x1f, 0xb2, 0x40, 0xea, + 0x05, 0x6e, 0x1f, 0xb2, 0x00, 0x6b, 0x80, 0xf1, 0x65, 0xc2, 0x00, 0x6a, + 0x44, 0x33, 0x1d, 0xb4, 0x01, 0x4a, 0x6d, 0xe4, 0x09, 0x52, 0x00, 0x6c, + 0x81, 0xc3, 0xf8, 0x61, 0x1a, 0xb2, 0x40, 0xf1, 0x44, 0xa2, 0x01, 0x6b, + 0xff, 0xf7, 0x1f, 0x6c, 0x6c, 0xea, 0x08, 0x22, 0x17, 0xb3, 0x00, 0xf4, + 0x00, 0x6d, 0x40, 0xab, 0x8c, 0xea, 0xad, 0xea, 0x8c, 0xea, 0x40, 0xcb, + 0x0b, 0x97, 0x0a, 0x90, 0x00, 0xef, 0x06, 0x63, 0x01, 0x3c, 0x12, 0x80, + 0x19, 0x37, 0x10, 0x80, 0x00, 0x3c, 0x12, 0x80, 0xbd, 0x3b, 0x10, 0x80, + 0x10, 0x12, 0x00, 0xb6, 0x34, 0x3c, 0x12, 0x80, 0x12, 0x12, 0x00, 0xb6, + 0x35, 0x3c, 0x12, 0x80, 0x36, 0x3c, 0x12, 0x80, 0x38, 0x3c, 0x12, 0x80, + 0xc4, 0x3e, 0x10, 0x80, 0x9d, 0x27, 0x10, 0x80, 0x27, 0x24, 0x12, 0x80, + 0x19, 0xc3, 0x00, 0x80, 0x10, 0x23, 0x12, 0x80, 0x44, 0x3c, 0x12, 0x80, + 0x38, 0x01, 0x12, 0x80, 0x34, 0x11, 0x00, 0xb6, 0xfd, 0x63, 0x05, 0x62, + 0x40, 0xac, 0x01, 0xf4, 0x03, 0x72, 0x03, 0x61, 0x04, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x05, 0x97, 0x00, 0x6a, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, + 0x5d, 0x32, 0x10, 0x80, 0xfa, 0x63, 0x0b, 0x62, 0x0a, 0xd1, 0x09, 0xd0, + 0x01, 0x6b, 0x5d, 0x67, 0x70, 0xc2, 0x40, 0xac, 0x04, 0x67, 0x26, 0x67, + 0xbf, 0xf4, 0x0e, 0x72, 0x10, 0x60, 0xbf, 0xf4, 0x0f, 0x6c, 0x83, 0xea, + 0x04, 0x60, 0x9f, 0xf4, 0x07, 0x72, 0x20, 0x60, 0x41, 0x10, 0x9f, 0xf5, + 0x00, 0x6f, 0x4e, 0xef, 0x21, 0x27, 0x9f, 0xf5, 0x12, 0x72, 0x2a, 0x60, + 0x39, 0x10, 0x62, 0xa4, 0x43, 0xa4, 0x01, 0x73, 0x3f, 0x61, 0x08, 0x5a, + 0x3d, 0x60, 0x23, 0xb3, 0x40, 0xc3, 0x23, 0xb4, 0x40, 0xf0, 0xa4, 0xac, + 0x07, 0x6b, 0x4c, 0xeb, 0x80, 0xf3, 0x01, 0x6a, 0x4b, 0xea, 0xac, 0xea, + 0x7c, 0x33, 0x6d, 0xea, 0x40, 0xf0, 0x44, 0xcc, 0x00, 0x6d, 0x2d, 0x10, + 0x04, 0x05, 0x1c, 0xb2, 0x40, 0xea, 0x90, 0x67, 0xa2, 0x67, 0x27, 0x10, + 0xc3, 0xa0, 0x06, 0xd7, 0x9f, 0xf5, 0x00, 0x6c, 0x12, 0x6d, 0x18, 0xb2, + 0x40, 0xea, 0xc0, 0x36, 0x06, 0x97, 0x7d, 0x67, 0xf0, 0xc3, 0x1a, 0x10, + 0xa6, 0x67, 0x15, 0xb2, 0x06, 0xd3, 0x40, 0xea, 0x90, 0x67, 0x06, 0x93, + 0x5d, 0x67, 0xa0, 0xa1, 0x70, 0xc2, 0x11, 0x10, 0x80, 0xa8, 0x0f, 0xb2, + 0x40, 0xea, 0x00, 0x6e, 0x01, 0x6a, 0x05, 0x10, 0x01, 0x6a, 0x40, 0xc5, + 0x00, 0x6a, 0x40, 0xc1, 0x00, 0x6a, 0x0b, 0x97, 0x0a, 0x91, 0x09, 0x90, + 0x00, 0xef, 0x06, 0x63, 0x12, 0x6d, 0x7d, 0x67, 0x50, 0xa3, 0x01, 0x72, + 0x01, 0x6a, 0xf5, 0x61, 0xe9, 0x17, 0x00, 0x65, 0x34, 0x03, 0x12, 0x80, + 0x10, 0x23, 0x12, 0x80, 0x35, 0x2e, 0x10, 0x80, 0x85, 0xab, 0x00, 0x80, + 0x65, 0x24, 0x10, 0x80, 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, + 0x44, 0xac, 0x04, 0x67, 0xe0, 0xf1, 0x16, 0x72, 0x17, 0x60, 0x40, 0xf4, + 0x12, 0x72, 0x17, 0x61, 0x40, 0x9c, 0x60, 0xa2, 0x3e, 0x73, 0x13, 0x61, + 0x42, 0xa2, 0x02, 0x72, 0x10, 0x61, 0x0d, 0xb1, 0x0d, 0xb2, 0x40, 0xea, + 0x81, 0x99, 0xff, 0x6b, 0x4c, 0xeb, 0x03, 0x5b, 0x08, 0x60, 0x81, 0x99, + 0x0a, 0xb2, 0x40, 0xea, 0xa0, 0x98, 0x07, 0x10, 0x80, 0xa4, 0x09, 0xb2, + 0x02, 0x10, 0x90, 0x67, 0x08, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x07, 0x97, + 0x06, 0x91, 0x05, 0x90, 0x00, 0xef, 0x04, 0x63, 0x1c, 0x0b, 0x12, 0x80, + 0xd1, 0xdd, 0x00, 0x80, 0xe1, 0xdd, 0x00, 0x80, 0x8d, 0x2b, 0x10, 0x80, + 0x21, 0x5b, 0x00, 0x80, 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd0, 0x04, 0x67, + 0x80, 0xac, 0x21, 0xf4, 0x15, 0x74, 0x0a, 0x61, 0x0f, 0xb2, 0x40, 0xea, + 0x90, 0x67, 0xa2, 0x67, 0x01, 0x6a, 0x13, 0x25, 0x80, 0xa8, 0x04, 0xd2, + 0x00, 0x6e, 0x0b, 0x10, 0xeb, 0xf7, 0x40, 0x44, 0xff, 0xf7, 0x1f, 0x6b, + 0x6c, 0xea, 0xe0, 0x5a, 0x00, 0x6a, 0x07, 0x60, 0x04, 0xd2, 0x01, 0x6d, + 0xc2, 0x67, 0x06, 0xb2, 0x40, 0xea, 0xe6, 0x67, 0x01, 0x6a, 0x07, 0x97, + 0x06, 0x90, 0x00, 0xef, 0x04, 0x63, 0x00, 0x65, 0xd1, 0x2c, 0x10, 0x80, + 0xed, 0x4d, 0x00, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x03, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x61, 0x94, 0x00, 0x80, + 0xfb, 0x63, 0x09, 0x62, 0x08, 0xd1, 0x07, 0xd0, 0x18, 0xb3, 0x19, 0xb2, + 0x43, 0xeb, 0x26, 0x61, 0x18, 0xb2, 0x80, 0x9a, 0x18, 0xb3, 0x8e, 0xeb, + 0x21, 0x2b, 0x02, 0xaa, 0x17, 0xb5, 0x1d, 0x10, 0x42, 0x45, 0x17, 0xb4, + 0x43, 0xec, 0x1a, 0x61, 0xc0, 0xa2, 0xff, 0xf7, 0x1f, 0x6f, 0x43, 0x46, + 0x43, 0xe8, 0x14, 0x61, 0x45, 0xe5, 0x23, 0xec, 0x11, 0x61, 0x81, 0xa5, + 0x60, 0xa5, 0x80, 0x34, 0x6d, 0xec, 0xec, 0xec, 0xe0, 0xf1, 0x04, 0x5c, + 0x09, 0x60, 0x43, 0xe0, 0x0d, 0xb2, 0x91, 0xe2, 0x03, 0x4d, 0x0d, 0xb2, + 0x40, 0xea, 0xec, 0xe8, 0xb1, 0x67, 0xe2, 0x28, 0x09, 0x97, 0x08, 0x91, + 0x07, 0x90, 0x00, 0xef, 0x05, 0x63, 0x00, 0x65, 0xf0, 0xbf, 0x10, 0x80, + 0xb4, 0x3f, 0x10, 0x80, 0xb8, 0x3f, 0x10, 0x80, 0x55, 0xab, 0x23, 0x87, + 0xbe, 0x3f, 0x10, 0x80, 0xff, 0xbf, 0x10, 0x80, 0x38, 0x01, 0x12, 0x80, + 0x19, 0xc3, 0x00, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x0e, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x0e, 0xb3, 0xff, 0xf7, 0x1f, 0x6c, 0x02, 0xf0, 0x00, 0x6d, + 0x40, 0xab, 0xab, 0xed, 0x8c, 0xea, 0xad, 0xea, 0x3f, 0x4d, 0xac, 0xea, + 0x02, 0xf1, 0x01, 0x4d, 0xad, 0xea, 0x9f, 0xf6, 0x00, 0x4d, 0xac, 0xea, + 0x05, 0x6d, 0xad, 0xea, 0x8c, 0xea, 0x40, 0xcb, 0x05, 0x97, 0x00, 0xef, + 0x03, 0x63, 0x00, 0x65, 0x39, 0x72, 0x01, 0x80, 0x28, 0x12, 0x00, 0xb6, + 0xfd, 0x63, 0x05, 0x62, 0x15, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x15, 0xb2, + 0x20, 0xf0, 0x8a, 0xa2, 0x01, 0x6b, 0x8d, 0xeb, 0xa0, 0xf1, 0x95, 0xa2, + 0x20, 0xf0, 0x6a, 0xc2, 0x07, 0x6b, 0x6b, 0xeb, 0x8c, 0xeb, 0xa0, 0xf1, + 0x75, 0xc2, 0x00, 0x6a, 0x50, 0x35, 0x0d, 0xb3, 0xb5, 0xe3, 0x00, 0xf4, + 0x00, 0x6c, 0xc0, 0xf1, 0x8e, 0xcd, 0x01, 0x4a, 0xff, 0x6d, 0xac, 0xea, + 0x0b, 0x5a, 0xf4, 0x61, 0x00, 0xf1, 0x00, 0x6a, 0x60, 0xf2, 0x5e, 0xcb, + 0x00, 0x6a, 0x80, 0xf2, 0x8e, 0xcb, 0x80, 0xf2, 0x5e, 0xcb, 0x05, 0x97, + 0x00, 0xef, 0x03, 0x63, 0xc9, 0x76, 0x01, 0x80, 0x10, 0x23, 0x12, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x0d, 0xb2, 0x0e, 0xb3, 0x72, 0xda, 0x0e, 0xb3, + 0x6c, 0xda, 0x0e, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0d, 0xb2, 0xff, 0xf7, + 0x1f, 0x6b, 0xff, 0x6c, 0xa0, 0xaa, 0x08, 0xf0, 0x00, 0x6a, 0x7b, 0x4c, + 0x6c, 0xed, 0x4d, 0xed, 0x09, 0xb2, 0x40, 0x9a, 0x40, 0xea, 0x6c, 0xed, + 0x05, 0x97, 0x00, 0x6a, 0x00, 0xef, 0x03, 0x63, 0xa4, 0x19, 0x12, 0x80, + 0x11, 0x35, 0x10, 0x80, 0x51, 0x34, 0x10, 0x80, 0xd5, 0x38, 0x10, 0x80, + 0x7a, 0x01, 0x00, 0xb6, 0x10, 0x00, 0x12, 0x80, 0x15, 0xb3, 0x16, 0xb2, + 0x60, 0xda, 0x16, 0xb3, 0x16, 0xb2, 0x60, 0xda, 0x16, 0xb2, 0xa0, 0xf0, + 0x6f, 0xa2, 0xa0, 0xf0, 0x8e, 0xa2, 0x60, 0x33, 0x8d, 0xeb, 0xa0, 0xf0, + 0x90, 0xa2, 0x80, 0x34, 0x80, 0x34, 0x6d, 0xec, 0xa0, 0xf0, 0x71, 0xa2, + 0x00, 0xf6, 0x60, 0x33, 0x8d, 0xeb, 0x0f, 0xb4, 0x8d, 0xeb, 0x62, 0x34, + 0xa0, 0xf0, 0x6e, 0xc2, 0xa0, 0xf0, 0x8f, 0xc2, 0x00, 0xf6, 0x62, 0x33, + 0x82, 0x34, 0xa0, 0xf0, 0x71, 0xc2, 0xa0, 0xf0, 0x90, 0xc2, 0x09, 0xb3, + 0x09, 0xb2, 0x20, 0xe8, 0x60, 0xda, 0x00, 0x65, 0xe5, 0x3a, 0x10, 0x80, + 0x04, 0x07, 0x12, 0x80, 0x11, 0x38, 0x10, 0x80, 0x00, 0x08, 0x12, 0x80, + 0x38, 0x01, 0x12, 0x80, 0x00, 0x00, 0x00, 0x80, 0x7d, 0x3a, 0x10, 0x80, + 0x00, 0x07, 0x12, 0x80, 0x20, 0xe8, 0x00, 0x65, 0x08, 0xb2, 0x40, 0x9a, + 0x61, 0x42, 0x09, 0x23, 0x03, 0x6b, 0x78, 0xea, 0x06, 0xb3, 0x12, 0xea, + 0x01, 0x4a, 0x4c, 0x32, 0x49, 0xe3, 0x05, 0xb3, 0x61, 0xda, 0x20, 0xe8, + 0x00, 0x65, 0x00, 0x65, 0xfc, 0x00, 0x12, 0x80, 0x6c, 0x1a, 0x12, 0x80, + 0xed, 0x39, 0x10, 0x80, 0x08, 0xb2, 0x20, 0xf1, 0x6c, 0xa2, 0x61, 0xc4, + 0x00, 0x6b, 0x60, 0xc4, 0x40, 0xf0, 0xa4, 0xa2, 0x01, 0x6b, 0x6c, 0xed, + 0xa2, 0xc4, 0xe0, 0xf0, 0x5c, 0xa2, 0x4c, 0xeb, 0x20, 0xe8, 0x63, 0xc4, + 0x10, 0x23, 0x12, 0x80, 0x11, 0xb2, 0xa1, 0xa4, 0x20, 0xf0, 0x42, 0xa2, + 0x00, 0x6b, 0xae, 0xea, 0x01, 0x22, 0x01, 0x6b, 0x01, 0x6a, 0x6c, 0xea, + 0x0d, 0xb3, 0xc2, 0xa4, 0x60, 0xa3, 0x00, 0x6d, 0xce, 0xeb, 0x01, 0x23, + 0x01, 0x6d, 0x01, 0x6b, 0xac, 0xeb, 0x74, 0x33, 0x4d, 0xeb, 0x08, 0xb2, + 0x83, 0xa4, 0x41, 0xa2, 0x00, 0x6d, 0x8e, 0xea, 0x01, 0x22, 0x01, 0x6d, + 0x01, 0x6a, 0xac, 0xea, 0x40, 0x32, 0x4c, 0x32, 0x20, 0xe8, 0x6d, 0xea, + 0x44, 0x0d, 0x12, 0x80, 0x3c, 0x3c, 0x12, 0x80, 0x61, 0xa4, 0x05, 0xb2, + 0x20, 0xf0, 0x62, 0xc2, 0x62, 0xa4, 0x04, 0xb2, 0x60, 0xc2, 0x63, 0xa4, + 0x20, 0xe8, 0x61, 0xc2, 0x44, 0x0d, 0x12, 0x80, 0x3c, 0x3c, 0x12, 0x80, + 0x20, 0xe8, 0x00, 0x6a, 0x20, 0xe8, 0x00, 0x6a, 0x20, 0xe8, 0x00, 0x6a, + 0x20, 0xe8, 0x7f, 0x6a, 0x06, 0xb2, 0x20, 0xf0, 0x47, 0xa2, 0x03, 0x22, + 0xe9, 0xf7, 0x1a, 0x6a, 0x01, 0x10, 0x40, 0xac, 0x40, 0xcd, 0x20, 0xe8, + 0x00, 0x6a, 0x00, 0x65, 0x44, 0x0d, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x03, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, + 0x59, 0x17, 0x01, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x60, 0x9c, 0x10, 0xf0, + 0x00, 0x6a, 0x6c, 0xea, 0x0c, 0x22, 0x09, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x08, 0xb3, 0xff, 0x6c, 0x80, 0x6d, 0x40, 0xa3, 0xab, 0xed, 0x8c, 0xea, + 0xad, 0xea, 0x8c, 0xea, 0x40, 0xc3, 0x05, 0x97, 0x01, 0x6a, 0x00, 0xef, + 0x03, 0x63, 0x00, 0x65, 0xe5, 0xc0, 0x00, 0x80, 0xbc, 0xa0, 0x00, 0xb0, + 0xfa, 0x63, 0x0b, 0x62, 0x0a, 0xd1, 0x09, 0xd0, 0x1b, 0xb2, 0x1c, 0xb1, + 0x20, 0xf0, 0x67, 0xa1, 0xe0, 0xaa, 0x1b, 0xb4, 0xff, 0xf7, 0x1f, 0x68, + 0x0c, 0xef, 0x40, 0xa4, 0xc1, 0xa4, 0x1b, 0x23, 0x05, 0xd2, 0x06, 0xd3, + 0x04, 0xd6, 0x17, 0xb4, 0x40, 0xec, 0x07, 0xd7, 0x16, 0xb4, 0xa0, 0xac, + 0x01, 0x6c, 0x0c, 0xed, 0x8d, 0xed, 0x15, 0xb4, 0x80, 0x9c, 0x0c, 0xed, + 0x0c, 0x65, 0x08, 0x67, 0x00, 0xf2, 0x1a, 0x6c, 0x40, 0xe8, 0x00, 0x65, + 0x00, 0x6c, 0x20, 0xf0, 0x87, 0xc1, 0x07, 0x97, 0x04, 0x96, 0x06, 0x93, + 0x05, 0x92, 0x64, 0x33, 0x54, 0x32, 0x6d, 0xea, 0xf6, 0x37, 0x01, 0x6b, + 0xd8, 0x36, 0x6c, 0xef, 0xcd, 0xea, 0xec, 0x37, 0xed, 0xea, 0x0b, 0x97, + 0x0a, 0x91, 0x09, 0x90, 0x00, 0xef, 0x06, 0x63, 0xa6, 0x01, 0x00, 0xb6, + 0x44, 0x0d, 0x12, 0x80, 0x3c, 0x3c, 0x12, 0x80, 0xe5, 0xc0, 0x00, 0x80, + 0x1a, 0x02, 0x00, 0xb6, 0x10, 0x00, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x0b, 0xb3, 0x0c, 0xb2, 0x7b, 0xda, 0x0c, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x0b, 0xb2, 0xff, 0xf7, 0x1f, 0x6b, 0x00, 0xf2, 0x1a, 0x6c, 0xa0, 0xaa, + 0x01, 0x6a, 0x6c, 0xed, 0x4d, 0xed, 0x08, 0xb2, 0x40, 0x9a, 0x40, 0xea, + 0x6c, 0xed, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0xfd, 0x37, 0x10, 0x80, + 0xa4, 0x19, 0x12, 0x80, 0xe5, 0xc0, 0x00, 0x80, 0x1a, 0x02, 0x00, 0xb6, + 0x10, 0x00, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x04, 0xd0, 0x09, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x08, 0xb3, 0x20, 0xf0, 0x02, 0xa3, 0x82, 0x67, + 0x07, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0b, 0xea, 0x05, 0x97, 0x04, 0x90, + 0xc0, 0xf7, 0x42, 0x32, 0x00, 0xef, 0x03, 0x63, 0xe0, 0x2b, 0x00, 0x80, + 0x44, 0x0d, 0x12, 0x80, 0xfc, 0x2b, 0x00, 0x80, 0xf8, 0x63, 0x0f, 0x62, + 0x0e, 0xd1, 0x0d, 0xd0, 0xff, 0x69, 0x8c, 0xe9, 0x5d, 0x67, 0x9d, 0x67, + 0x38, 0xc2, 0x06, 0x6a, 0x59, 0xc4, 0x00, 0x6a, 0x5a, 0xc4, 0x5b, 0xc4, + 0x5c, 0xc4, 0x5d, 0xc4, 0x5e, 0xc4, 0x5f, 0xc4, 0x00, 0x68, 0x1c, 0xb3, + 0x08, 0x32, 0x49, 0xe3, 0x40, 0x9a, 0x40, 0xea, 0x00, 0x65, 0x9d, 0x67, + 0x0d, 0xe4, 0x5a, 0xc3, 0x01, 0x48, 0xff, 0x6a, 0x4c, 0xe8, 0x06, 0x58, + 0xf2, 0x61, 0xba, 0xa4, 0x02, 0x6a, 0x54, 0xcc, 0x5b, 0xa4, 0xa0, 0x35, + 0xa0, 0x35, 0x00, 0xf6, 0x40, 0x32, 0x4d, 0xed, 0x00, 0xf6, 0x00, 0x6a, + 0x4d, 0xed, 0x2d, 0xed, 0x08, 0xd5, 0x5e, 0xa4, 0xdd, 0xa4, 0x0a, 0x97, + 0x40, 0x32, 0x40, 0x32, 0xc0, 0x36, 0x4d, 0xee, 0x5c, 0xa4, 0x4d, 0xee, + 0x5f, 0xa4, 0x00, 0xf6, 0x40, 0x32, 0x4d, 0xee, 0x09, 0xd6, 0x08, 0xb2, + 0x80, 0x9a, 0x0b, 0x92, 0x04, 0xd2, 0x07, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x0f, 0x97, 0x0e, 0x91, 0x0d, 0x90, 0x00, 0xef, 0x08, 0x63, 0x00, 0x65, + 0xd0, 0x3e, 0x10, 0x80, 0x38, 0x1d, 0x12, 0x80, 0x2d, 0xdb, 0x00, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x1e, 0xb2, 0x60, 0xaa, 0x28, 0x73, 0x01, 0x4b, + 0x01, 0x61, 0x01, 0x6b, 0x60, 0xca, 0x1c, 0xb2, 0x40, 0xf0, 0xc4, 0xa2, + 0xe0, 0xf0, 0x9c, 0xa2, 0x01, 0x6b, 0x6c, 0xee, 0x6c, 0xec, 0x19, 0xb3, + 0x20, 0xf1, 0xec, 0xa2, 0x20, 0xf0, 0x62, 0xa3, 0x00, 0x6a, 0xee, 0xeb, + 0x01, 0x23, 0x01, 0x6a, 0x01, 0x6b, 0x4c, 0xeb, 0x14, 0xb2, 0x40, 0xa2, + 0x00, 0x6d, 0xce, 0xea, 0x01, 0x22, 0x01, 0x6d, 0x01, 0x6a, 0xac, 0xea, + 0x10, 0xb5, 0xa1, 0xa5, 0x54, 0x32, 0x6d, 0xea, 0x8e, 0xed, 0x00, 0x6b, + 0x01, 0x25, 0x01, 0x6b, 0x01, 0x6d, 0x6c, 0xed, 0xa0, 0x35, 0xac, 0x35, + 0x4d, 0xed, 0x09, 0xb2, 0x20, 0xf0, 0xe2, 0xc2, 0x08, 0xb2, 0xc0, 0xc2, + 0x81, 0xc2, 0x03, 0x25, 0x07, 0xb2, 0x40, 0xea, 0x27, 0x6c, 0x05, 0x97, + 0x00, 0xef, 0x03, 0x63, 0x40, 0x3c, 0x12, 0x80, 0x10, 0x23, 0x12, 0x80, + 0x44, 0x0d, 0x12, 0x80, 0x3c, 0x3c, 0x12, 0x80, 0x4d, 0x39, 0x10, 0x80, + 0xfb, 0x63, 0x09, 0x62, 0x08, 0xd0, 0x16, 0xb0, 0x40, 0x98, 0xa0, 0xf1, + 0x06, 0x6c, 0x20, 0xf2, 0x00, 0x6d, 0x40, 0xea, 0x00, 0x65, 0x40, 0x98, + 0xa0, 0xf1, 0x12, 0x6c, 0x40, 0xea, 0xff, 0x6d, 0x40, 0x98, 0xfa, 0x6c, + 0x40, 0xea, 0x32, 0x6d, 0x40, 0x98, 0xf4, 0x6c, 0x40, 0xea, 0x01, 0x6d, + 0x40, 0x98, 0xa0, 0xf1, 0x0a, 0x6c, 0x40, 0xea, 0x03, 0x6d, 0x00, 0x6a, + 0x09, 0xb3, 0x04, 0xd2, 0x06, 0xd2, 0x05, 0xd3, 0x05, 0x6c, 0x20, 0xf3, + 0x1e, 0x6e, 0x81, 0xf1, 0x12, 0x6f, 0x06, 0xb2, 0x40, 0xea, 0xfe, 0x6d, + 0x09, 0x97, 0x08, 0x90, 0x00, 0xef, 0x05, 0x63, 0x10, 0x00, 0x12, 0x80, + 0xc0, 0x3e, 0x10, 0x80, 0xd1, 0x27, 0x01, 0x80, 0xfb, 0x63, 0x09, 0x62, + 0x08, 0xd0, 0x21, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x20, 0xb2, 0xa0, 0xf0, + 0x83, 0xa2, 0xa0, 0xf0, 0x62, 0xa2, 0x80, 0x34, 0x6d, 0xec, 0xa0, 0xf0, + 0x64, 0xa2, 0xa0, 0xf0, 0x45, 0xa2, 0x60, 0x33, 0x60, 0x33, 0x8d, 0xeb, + 0x00, 0xf6, 0x40, 0x32, 0x6d, 0xea, 0x19, 0xb3, 0x6c, 0xea, 0x26, 0x22, + 0x18, 0xb4, 0x40, 0x9c, 0x01, 0x4a, 0x03, 0x22, 0x17, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x00, 0x6a, 0xe2, 0x67, 0x16, 0xb6, 0x04, 0xd2, 0x13, 0xb5, + 0x15, 0xb2, 0x40, 0xea, 0x01, 0x6c, 0x11, 0xb0, 0x14, 0xb2, 0xa4, 0x9a, + 0x14, 0xb2, 0x40, 0xea, 0x80, 0x98, 0x01, 0x6a, 0x04, 0xd2, 0x13, 0xb2, + 0x05, 0xd2, 0x40, 0x98, 0x02, 0x6c, 0x06, 0xd2, 0xe0, 0xf1, 0x0d, 0x6e, + 0xe5, 0xf6, 0x05, 0x6f, 0x0f, 0xb2, 0x40, 0xea, 0xfe, 0x6d, 0x0f, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x09, 0x97, 0x08, 0x90, 0x00, 0xef, 0x05, 0x63, + 0xe5, 0xc1, 0x00, 0x80, 0x38, 0x01, 0x12, 0x80, 0x00, 0x00, 0x00, 0x40, + 0xfc, 0x00, 0x12, 0x80, 0x1d, 0xdd, 0x00, 0x80, 0xed, 0x39, 0x10, 0x80, + 0x71, 0xdd, 0x00, 0x80, 0x44, 0x0d, 0x12, 0x80, 0xc1, 0xdc, 0x00, 0x80, + 0xc0, 0x3e, 0x10, 0x80, 0xd1, 0x27, 0x01, 0x80, 0x71, 0xc1, 0x00, 0x80, + 0x04, 0xb3, 0x05, 0xb2, 0x60, 0xda, 0x05, 0xb3, 0x05, 0xb2, 0x20, 0xe8, + 0x60, 0xda, 0x00, 0x65, 0x21, 0x3c, 0x10, 0x80, 0x78, 0x00, 0x12, 0x80, + 0xdd, 0x3b, 0x10, 0x80, 0xc8, 0x00, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x05, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x01, 0x6b, 0x04, 0xb2, 0x60, 0xc2, + 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, 0xad, 0x98, 0x00, 0x80, + 0x00, 0x3c, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x00, 0xf6, 0x80, 0x34, + 0x00, 0xf6, 0x83, 0x34, 0x0a, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0a, 0xb2, + 0x67, 0xa2, 0x86, 0xa2, 0x60, 0x33, 0x8d, 0xeb, 0x08, 0xb4, 0x60, 0xcc, + 0x65, 0xa2, 0x44, 0xa2, 0x60, 0x33, 0x4d, 0xeb, 0x06, 0xb2, 0x60, 0xca, + 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, 0x9d, 0x9d, 0x00, 0x80, + 0xac, 0x0c, 0x12, 0x80, 0xea, 0x10, 0x00, 0xb6, 0xf0, 0x10, 0x00, 0xb6, + 0xfd, 0x63, 0x05, 0x62, 0x08, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x08, 0xb2, + 0x08, 0xb3, 0x66, 0xda, 0x18, 0x6b, 0x6e, 0xca, 0x07, 0xb3, 0x60, 0xda, + 0x4a, 0x6b, 0x62, 0xca, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, + 0x01, 0xa0, 0x00, 0x80, 0xc8, 0x0c, 0x12, 0x80, 0xe8, 0x3e, 0x10, 0x80, + 0x18, 0x3f, 0x10, 0x80, 0xf9, 0x63, 0x0d, 0x62, 0x0c, 0xd1, 0x0b, 0xd0, + 0x1c, 0xb2, 0x40, 0xf1, 0x44, 0xa2, 0x01, 0x6b, 0xff, 0x68, 0x6c, 0xea, + 0x8c, 0xe8, 0x29, 0x22, 0x47, 0x40, 0x4b, 0x4a, 0x48, 0x32, 0x18, 0xb3, + 0x49, 0xe3, 0x80, 0x9a, 0x44, 0xad, 0xc0, 0xf4, 0x40, 0x32, 0x80, 0xf5, + 0x42, 0x32, 0x1d, 0x2a, 0x04, 0x32, 0x14, 0xb1, 0x45, 0xe1, 0x41, 0xa1, + 0x01, 0x72, 0x17, 0x61, 0x02, 0x6a, 0x41, 0xc1, 0x11, 0xb2, 0x40, 0x9a, + 0x40, 0xea, 0xa0, 0xa1, 0x03, 0x6a, 0x04, 0xd2, 0x0f, 0xb2, 0x05, 0xd2, + 0x06, 0xd0, 0x40, 0xa1, 0x01, 0x6c, 0x07, 0xd2, 0x41, 0xa1, 0xa1, 0xf7, + 0x14, 0x6e, 0x49, 0xf6, 0x1c, 0x6f, 0x08, 0xd2, 0x0a, 0xb2, 0x40, 0xea, + 0xfa, 0x6d, 0x0d, 0x97, 0x0c, 0x91, 0x0b, 0x90, 0x00, 0x6a, 0x00, 0xef, + 0x07, 0x63, 0x00, 0x65, 0x38, 0x01, 0x12, 0x80, 0x10, 0x23, 0x12, 0x80, + 0x44, 0x3c, 0x12, 0x80, 0x04, 0x05, 0x12, 0x80, 0xc0, 0x3e, 0x10, 0x80, + 0xd1, 0x27, 0x01, 0x80, 0xf5, 0x63, 0x15, 0x62, 0x14, 0xd1, 0x13, 0xd0, + 0x21, 0xa4, 0x3d, 0xb3, 0x2a, 0x31, 0x47, 0x41, 0x4b, 0x4a, 0x48, 0x32, + 0x49, 0xe3, 0x60, 0xac, 0x00, 0x9a, 0x80, 0xf3, 0x00, 0x6a, 0x6c, 0xea, + 0x00, 0xf1, 0x00, 0x72, 0x65, 0x61, 0x43, 0xa0, 0x01, 0x6b, 0x6c, 0xea, + 0x61, 0x22, 0x24, 0x32, 0x34, 0xb3, 0x49, 0xe3, 0x10, 0xd2, 0x41, 0xa2, + 0x02, 0x72, 0x5a, 0x61, 0x10, 0x93, 0x03, 0x6a, 0x04, 0xd2, 0x31, 0xb2, + 0x05, 0xd2, 0x06, 0xd1, 0x40, 0xa3, 0x01, 0x6c, 0xfa, 0x6d, 0x07, 0xd2, + 0x02, 0x6a, 0x02, 0xf0, 0x15, 0x6e, 0x29, 0xf6, 0x10, 0x6f, 0x2c, 0xb3, + 0x40, 0xeb, 0x08, 0xd2, 0x83, 0xa0, 0x02, 0x6a, 0x4b, 0xea, 0x8c, 0xea, + 0x43, 0xc0, 0x10, 0x93, 0x0f, 0x6d, 0x2c, 0xed, 0x40, 0xa3, 0xb4, 0x35, + 0x01, 0x6b, 0xc0, 0xf4, 0x40, 0x32, 0x6d, 0xed, 0x4d, 0xed, 0x7d, 0x67, + 0x60, 0xf2, 0x0f, 0x6a, 0x58, 0xcb, 0x22, 0xb2, 0x80, 0x9a, 0x0d, 0x92, + 0x0b, 0x96, 0x0c, 0x97, 0x0a, 0xd5, 0x04, 0xd2, 0x1f, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x1f, 0xb2, 0x40, 0xea, 0x0e, 0x04, 0x7d, 0x67, 0x20, 0xf0, + 0x58, 0x83, 0x2a, 0xea, 0x0e, 0x60, 0x02, 0x6b, 0x04, 0xd3, 0x16, 0xb3, + 0x05, 0xd3, 0x06, 0xd2, 0x07, 0xd1, 0x02, 0x6c, 0x22, 0xf0, 0x07, 0x6e, + 0x01, 0xf5, 0x0b, 0x6f, 0x12, 0xb3, 0x40, 0xeb, 0xfa, 0x6d, 0x59, 0x98, + 0x01, 0x4a, 0x04, 0x22, 0x87, 0x40, 0x13, 0xb2, 0x40, 0xea, 0x5d, 0x4c, + 0x58, 0x98, 0x01, 0x4a, 0x04, 0x22, 0x87, 0x40, 0x0f, 0xb2, 0x40, 0xea, + 0x59, 0x4c, 0x08, 0xb2, 0x24, 0x31, 0x25, 0xe2, 0x00, 0x6a, 0x41, 0xc1, + 0x01, 0x6a, 0x01, 0x10, 0x00, 0x6a, 0x15, 0x97, 0x14, 0x91, 0x13, 0x90, + 0x00, 0xef, 0x0b, 0x63, 0x10, 0x23, 0x12, 0x80, 0x44, 0x3c, 0x12, 0x80, + 0xc0, 0x3e, 0x10, 0x80, 0xd1, 0x27, 0x01, 0x80, 0x50, 0x0c, 0x12, 0x80, + 0x2d, 0xdb, 0x00, 0x80, 0xcd, 0xa8, 0x01, 0x80, 0x1d, 0xdd, 0x00, 0x80, + 0xfa, 0x63, 0x0b, 0x62, 0xff, 0x6a, 0x4c, 0xed, 0x4c, 0xee, 0x14, 0xb2, + 0x40, 0xf1, 0x64, 0xa2, 0x40, 0xf1, 0x45, 0xa2, 0x40, 0x32, 0x6d, 0xea, + 0x01, 0x6b, 0x6c, 0xea, 0x16, 0x22, 0x41, 0xa4, 0x0f, 0xb5, 0xc4, 0x34, + 0x91, 0xe5, 0x61, 0xc4, 0x40, 0xc4, 0x03, 0x6c, 0x04, 0xd4, 0x0d, 0xb4, + 0x05, 0xd4, 0x06, 0xd6, 0x07, 0xd2, 0x08, 0xd3, 0x83, 0x67, 0x81, 0xf7, + 0x1c, 0x6e, 0x49, 0xf6, 0x1b, 0x6f, 0x09, 0xb2, 0x40, 0xea, 0xfa, 0x6d, + 0x03, 0x10, 0x08, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0b, 0x97, 0x00, 0xef, + 0x06, 0x63, 0x00, 0x65, 0x38, 0x01, 0x12, 0x80, 0x44, 0x3c, 0x12, 0x80, + 0xc0, 0x3e, 0x10, 0x80, 0xd1, 0x27, 0x01, 0x80, 0xa1, 0x86, 0x01, 0x80, + 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, 0xff, 0x6a, 0x24, 0x67, + 0x4c, 0xe9, 0x67, 0x41, 0x4b, 0x4b, 0x0e, 0xb4, 0x68, 0x33, 0x6d, 0xe4, + 0x00, 0x9b, 0x04, 0x6b, 0x85, 0xa0, 0x8c, 0xeb, 0x4c, 0xeb, 0x0b, 0x23, + 0x0a, 0xb2, 0x40, 0x9a, 0x02, 0x6c, 0x78, 0x6d, 0x40, 0xea, 0x01, 0x6e, + 0x40, 0xf0, 0x5c, 0xc8, 0x07, 0xb2, 0x40, 0xea, 0x91, 0x67, 0x07, 0x97, + 0x06, 0x91, 0x05, 0x90, 0x00, 0x6a, 0x00, 0xef, 0x04, 0x63, 0x00, 0x65, + 0x10, 0x23, 0x12, 0x80, 0x50, 0x00, 0x12, 0x80, 0x75, 0xd4, 0x01, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x07, 0x00, 0xf8, 0x03, 0x00, 0xe0, 0x07, 0x00, + 0xc0, 0x7f, 0x00, 0x00, 0x19, 0x39, 0x10, 0x80, 0xd1, 0x37, 0x10, 0x80, + 0xd5, 0x37, 0x10, 0x80, 0x49, 0x38, 0x10, 0x80, 0xd9, 0x37, 0x10, 0x80, + 0xdd, 0x37, 0x10, 0x80, 0x00, 0xf0, 0x20, 0x00, 0x00, 0x90, 0x4f, 0x03, + 0x00, 0xf0, 0x20, 0x00, 0x00, 0x90, 0x6f, 0x03, 0x00, 0xf0, 0x08, 0x00, + 0x02, 0x90, 0x17, 0xf8, 0x34, 0x00, 0x03, 0x10, 0x36, 0x00, 0x04, 0xe2, + 0x38, 0x00, 0x01, 0x31, 0x3a, 0x00, 0xe0, 0x05, 0x64, 0x00, 0x40, 0x2e, + 0x1a, 0x01, 0x16, 0x36, 0x42, 0x02, 0xff, 0x04, 0x44, 0x02, 0x33, 0x64, + 0x16, 0x03, 0x53, 0x76, 0x14, 0x03, 0x00, 0x00, 0x74, 0x03, 0x86, 0x06, + 0x72, 0x03, 0xd1, 0x04, 0x70, 0x03, 0x57, 0x04, 0x6e, 0x03, 0xde, 0x03, + 0x6c, 0x03, 0x6b, 0x03, 0x6a, 0x03, 0x3f, 0x00, 0x68, 0x03, 0x3f, 0x00, + 0x66, 0x03, 0x3f, 0x00, 0x16, 0x00, 0xb8, 0xa6, 0x40, 0x03, 0x8a, 0x03, + 0x3a, 0x02, 0xa6, 0x00, 0x3c, 0x02, 0x7e, 0xc0, 0x60, 0x02, 0x36, 0x21, + 0x62, 0x02, 0xce, 0x17, 0x08, 0x03, 0x29, 0x29, 0x42, 0x03, 0x01, 0x09, + 0x56, 0x03, 0x0d, 0x33, 0x5a, 0x03, 0x45, 0x00, 0x30, 0x06, 0x26, 0x67, + 0x32, 0x06, 0x12, 0x5d, 0x34, 0x06, 0x7f, 0xe8, 0x36, 0x06, 0xc8, 0x36, + 0x34, 0x01, 0x00, 0x00, 0x64, 0x01, 0x44, 0x3b, 0x66, 0x01, 0xd2, 0x76, + 0x08, 0x00, 0xb0, 0x00, 0x66, 0x00, 0x59, 0x40, 0x0a, 0x06, 0xdb, 0x50, + 0x0c, 0x06, 0xe2, 0x7b, 0x0e, 0x06, 0x6a, 0xc0, 0x10, 0x06, 0x8c, 0x55, + 0x12, 0x06, 0x0a, 0x28, 0x14, 0x06, 0x27, 0x01, 0x02, 0x02, 0x6a, 0x7c, + 0x6d, 0x61, 0x00, 0x00, 0xa4, 0x54, 0xa8, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x10, 0x01, 0x00, 0x51, 0x04, 0xfd, 0x77 +}; + +unsigned int rtl_vendor_command_size = sizeof(rtl_vendor_command); +#endif + +#ifdef CONFIG_ARCH_CHIP_AMEBAZ_C_CUT +const unsigned char rtl_vendor_command[] = +{ + 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, 0x55, 0xb2, 0x40, 0x9a, + 0x55, 0xb3, 0x56, 0xb0, 0x42, 0x34, 0x82, 0x34, 0x80, 0xcb, 0x55, 0xb3, + 0x40, 0xcb, 0x55, 0xb2, 0x40, 0xea, 0x00, 0x69, 0x54, 0xb3, 0x55, 0xb2, + 0x60, 0xda, 0x55, 0xb3, 0x55, 0xb2, 0x60, 0xda, 0x55, 0xb3, 0x56, 0xb2, + 0x60, 0xda, 0x56, 0xb3, 0x56, 0xb2, 0x60, 0xda, 0x56, 0xb3, 0x57, 0xb2, + 0x60, 0xda, 0x57, 0xb3, 0x57, 0xb2, 0x60, 0xda, 0x57, 0xb3, 0x58, 0xb2, + 0x60, 0xda, 0xa0, 0xf0, 0x4b, 0xa0, 0xa0, 0xf0, 0x6a, 0xa0, 0x40, 0x32, + 0x6d, 0xea, 0xa0, 0xf0, 0x6c, 0xa0, 0x60, 0x33, 0x60, 0x33, 0x4d, 0xeb, + 0xa0, 0xf0, 0x4d, 0xa0, 0x00, 0xf6, 0x40, 0x32, 0x6d, 0xea, 0x08, 0xf0, + 0x01, 0x6b, 0x6b, 0xeb, 0x6c, 0xea, 0x42, 0x33, 0xa0, 0xf0, 0x4a, 0xc0, + 0xa0, 0xf0, 0x6b, 0xc0, 0x00, 0xf6, 0x42, 0x32, 0x62, 0x33, 0xa0, 0xf0, + 0x6c, 0xc0, 0xa0, 0xf0, 0x4d, 0xc0, 0x48, 0xb3, 0x48, 0xb2, 0x60, 0xda, + 0x48, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x48, 0xb3, 0x48, 0xb2, 0x60, 0xda, + 0x48, 0xb3, 0x49, 0xb2, 0x60, 0xda, 0x49, 0xb3, 0x49, 0xb2, 0x66, 0xda, + 0x49, 0xb2, 0x20, 0xc2, 0x49, 0xb3, 0x4a, 0xb2, 0x60, 0xda, 0x4a, 0xb3, + 0x4a, 0xb2, 0x65, 0xda, 0x4a, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x4a, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x49, 0xb3, 0x4a, 0xb2, 0x60, 0xda, 0x4a, 0xb3, + 0x4a, 0xb2, 0x60, 0xda, 0x4a, 0xb2, 0x02, 0x6b, 0x60, 0xda, 0xe0, 0xf0, + 0x23, 0xc0, 0x51, 0x67, 0x44, 0x33, 0x48, 0xb4, 0x01, 0x4a, 0x6d, 0xe4, + 0x18, 0x52, 0x00, 0x6c, 0x80, 0xcb, 0xf8, 0x61, 0x45, 0xb3, 0x46, 0xb2, + 0x60, 0xda, 0x46, 0xb3, 0x46, 0xb2, 0x60, 0xda, 0x1b, 0xb2, 0xa0, 0xf0, + 0x61, 0xa2, 0xa0, 0xf0, 0x80, 0xa2, 0x60, 0x33, 0x8d, 0xeb, 0xef, 0xf7, + 0x1f, 0x6c, 0x8c, 0xeb, 0xa0, 0xf0, 0x60, 0xc2, 0x62, 0x33, 0xa0, 0xf0, + 0x61, 0xc2, 0xa0, 0xf0, 0x6f, 0xa2, 0xa0, 0xf0, 0x8e, 0xa2, 0x60, 0x33, + 0x8d, 0xeb, 0xa0, 0xf0, 0x90, 0xa2, 0x80, 0x34, 0x80, 0x34, 0x6d, 0xec, + 0xa0, 0xf0, 0x71, 0xa2, 0x00, 0xf6, 0x60, 0x33, 0x8d, 0xeb, 0x01, 0x6c, + 0x8d, 0xeb, 0x62, 0x34, 0xa0, 0xf0, 0x6e, 0xc2, 0xa0, 0xf0, 0x8f, 0xc2, + 0x00, 0xf6, 0x62, 0x33, 0x82, 0x34, 0xa0, 0xf0, 0x90, 0xc2, 0xa0, 0xf0, + 0x71, 0xc2, 0x07, 0x97, 0x06, 0x91, 0x05, 0x90, 0x00, 0xef, 0x04, 0x63, + 0xb4, 0x3f, 0x10, 0x80, 0x12, 0x01, 0x12, 0x80, 0x18, 0x01, 0x12, 0x80, + 0x10, 0x01, 0x12, 0x80, 0x7d, 0x3a, 0x10, 0x80, 0x9d, 0x32, 0x10, 0x80, + 0x8c, 0x05, 0x12, 0x80, 0x69, 0x32, 0x10, 0x80, 0xac, 0x03, 0x12, 0x80, + 0x25, 0x32, 0x10, 0x80, 0xb0, 0x03, 0x12, 0x80, 0x35, 0x31, 0x10, 0x80, + 0xc0, 0x05, 0x12, 0x80, 0x2d, 0x2f, 0x10, 0x80, 0xb0, 0x06, 0x12, 0x80, + 0x11, 0x22, 0x10, 0x80, 0xb8, 0x06, 0x12, 0x80, 0x0d, 0x2f, 0x10, 0x80, + 0xac, 0x05, 0x12, 0x80, 0x75, 0x34, 0x10, 0x80, 0xc8, 0x06, 0x12, 0x80, + 0xed, 0x32, 0x10, 0x80, 0x31, 0x2d, 0x10, 0x80, 0x94, 0x08, 0x12, 0x80, + 0xb1, 0x2d, 0x10, 0x80, 0x9c, 0x04, 0x12, 0x80, 0xa5, 0x2b, 0x10, 0x80, + 0x18, 0x03, 0x12, 0x80, 0x0a, 0x3c, 0x12, 0x80, 0x19, 0x26, 0x10, 0x80, + 0x40, 0x08, 0x12, 0x80, 0x75, 0x26, 0x10, 0x80, 0xb8, 0x03, 0x12, 0x80, + 0x9d, 0x31, 0x10, 0x80, 0x65, 0x2f, 0x00, 0x80, 0xf9, 0x23, 0x10, 0x80, + 0x58, 0x08, 0x12, 0x80, 0x2d, 0x27, 0x10, 0x80, 0x6c, 0x08, 0x12, 0x80, + 0xa4, 0x03, 0x12, 0x80, 0x1c, 0x3c, 0x12, 0x80, 0x6d, 0x29, 0x10, 0x80, + 0xb0, 0x05, 0x12, 0x80, 0x71, 0x3e, 0x10, 0x80, 0x48, 0x28, 0x12, 0x80, + 0x44, 0xa4, 0x63, 0xa4, 0xe0, 0xa5, 0x40, 0x32, 0x69, 0xe2, 0xff, 0xf7, + 0x1f, 0x6b, 0x6c, 0xea, 0x9f, 0xf4, 0x17, 0x72, 0x0c, 0x60, 0x9f, 0xf5, + 0x00, 0x72, 0x00, 0x6a, 0x39, 0x61, 0x1f, 0xf7, 0x00, 0x6a, 0xcc, 0xea, + 0x42, 0x32, 0xed, 0xe4, 0x42, 0xc3, 0x41, 0x47, 0x2c, 0x10, 0x1a, 0xb3, + 0xc7, 0xab, 0xe9, 0xe4, 0xc2, 0x36, 0xc2, 0xc2, 0xc7, 0xab, 0xc3, 0xc2, + 0xc6, 0xab, 0xc2, 0x36, 0xc4, 0xc2, 0xc6, 0xab, 0xc5, 0xc2, 0xc5, 0xab, + 0xc2, 0x36, 0xc6, 0xc2, 0xc5, 0xab, 0xc7, 0xc2, 0xc4, 0xab, 0xc2, 0x36, + 0xc8, 0xc2, 0xc4, 0xab, 0xc9, 0xc2, 0xc3, 0xab, 0xc2, 0x36, 0xca, 0xc2, + 0xc3, 0xab, 0xcb, 0xc2, 0xc2, 0xab, 0xc2, 0x36, 0xcc, 0xc2, 0xc2, 0xab, + 0xcd, 0xc2, 0xc1, 0xab, 0xc2, 0x36, 0xce, 0xc2, 0xc1, 0xab, 0xcf, 0xc2, + 0xc0, 0xab, 0xc2, 0x36, 0xd0, 0xc2, 0x60, 0xab, 0x71, 0xc2, 0x47, 0x47, + 0x09, 0x4a, 0xff, 0x6b, 0x6c, 0xea, 0x41, 0xc4, 0x40, 0xc5, 0x01, 0x6a, + 0x20, 0xe8, 0x00, 0x65, 0x0c, 0x3c, 0x12, 0x80, 0x65, 0xa4, 0xa4, 0xa4, + 0x0d, 0x73, 0x04, 0x60, 0x21, 0x73, 0x02, 0x60, 0x2a, 0x73, 0x46, 0x61, + 0x02, 0x5d, 0x43, 0x67, 0x0c, 0x60, 0x24, 0xb6, 0x4b, 0xa6, 0x63, 0xea, + 0x08, 0x61, 0xcc, 0xa6, 0xff, 0x6a, 0xcc, 0xea, 0x63, 0xea, 0x01, 0x60, + 0xc3, 0x67, 0xff, 0x6a, 0xcc, 0xea, 0x62, 0xa4, 0x03, 0x5b, 0x34, 0x61, + 0x1d, 0xb3, 0x01, 0x75, 0x80, 0xab, 0xff, 0xf7, 0x1f, 0x6b, 0x8c, 0xeb, + 0x10, 0x60, 0x08, 0x25, 0x02, 0x6a, 0xae, 0xea, 0x10, 0x22, 0x03, 0x6a, + 0x4e, 0xed, 0x0c, 0x6a, 0x26, 0x2d, 0x15, 0x10, 0x16, 0xb4, 0x01, 0x6d, + 0xa0, 0xc4, 0xff, 0x6c, 0x01, 0x4c, 0x8b, 0xec, 0x14, 0x10, 0x01, 0x6d, + 0x13, 0xb4, 0xa0, 0xc4, 0x0e, 0x10, 0x11, 0xb4, 0x40, 0xc4, 0xff, 0x6a, + 0x01, 0x4a, 0x4b, 0xea, 0x6c, 0xea, 0x0c, 0xb3, 0x70, 0xa3, 0x6d, 0xea, + 0x08, 0x10, 0x0d, 0xb2, 0xa0, 0xc2, 0x09, 0xb2, 0x51, 0xa2, 0x40, 0x32, + 0xff, 0x6c, 0x6c, 0xec, 0x8d, 0xea, 0xff, 0xf7, 0x1f, 0x6b, 0x4c, 0xeb, + 0x05, 0xb2, 0x60, 0xca, 0x20, 0xe8, 0x00, 0x6a, 0x12, 0x6a, 0x20, 0xe8, + 0x00, 0x65, 0x00, 0x65, 0x2c, 0x0c, 0x12, 0x80, 0xe8, 0x10, 0x00, 0xb6, + 0x08, 0x3c, 0x12, 0x80, 0x09, 0x3c, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x04, 0xd0, 0xa4, 0xa4, 0x05, 0xa4, 0x66, 0xa4, 0x47, 0xa4, 0x82, 0xa4, + 0x05, 0x5c, 0x35, 0x61, 0x00, 0x30, 0xad, 0xe8, 0x18, 0x58, 0x31, 0x60, + 0x0f, 0x58, 0x2f, 0x61, 0x0d, 0x72, 0x04, 0x60, 0x21, 0x72, 0x02, 0x60, + 0x2a, 0x72, 0x29, 0x61, 0xf1, 0x48, 0xff, 0x6c, 0x8c, 0xe8, 0x0e, 0x23, + 0x15, 0xb2, 0x09, 0xe2, 0x00, 0x6b, 0x60, 0xc2, 0x14, 0xb2, 0x40, 0x9a, + 0x40, 0xea, 0x90, 0x67, 0x13, 0xb3, 0x60, 0x9b, 0x90, 0x67, 0x40, 0xeb, + 0xa2, 0x67, 0x15, 0x10, 0x11, 0xb3, 0xab, 0xa3, 0x43, 0xed, 0x09, 0x61, + 0x6c, 0xa3, 0xa3, 0x67, 0x8c, 0xed, 0x4c, 0xec, 0x83, 0xed, 0x01, 0x60, + 0x62, 0x67, 0xff, 0x6d, 0x6c, 0xed, 0x08, 0xb2, 0x09, 0xe2, 0x01, 0x6b, + 0x60, 0xc2, 0x0a, 0xb2, 0x40, 0x9a, 0x40, 0xea, 0x90, 0x67, 0x00, 0x6a, + 0x01, 0x10, 0x12, 0x6a, 0x05, 0x97, 0x04, 0x90, 0x00, 0xef, 0x03, 0x63, + 0x00, 0x3c, 0x12, 0x80, 0xb8, 0x00, 0x12, 0x80, 0xc4, 0x00, 0x12, 0x80, + 0x2c, 0x0c, 0x12, 0x80, 0x94, 0x04, 0x12, 0x80, 0x42, 0xa4, 0x04, 0xb3, + 0x49, 0xe3, 0x00, 0x6b, 0x60, 0xc2, 0x20, 0xe8, 0x01, 0x6a, 0x00, 0x65, + 0x00, 0x3c, 0x12, 0x80, 0xff, 0xf7, 0x1f, 0x6a, 0x4c, 0xed, 0x8c, 0xea, + 0x09, 0x10, 0x01, 0x4a, 0x09, 0x6b, 0x7a, 0xea, 0x01, 0x2b, 0xe5, 0xe8, + 0xff, 0xf7, 0x1f, 0x6b, 0x10, 0xea, 0x6c, 0xea, 0x08, 0xb3, 0x80, 0xf0, + 0x92, 0xa3, 0x4e, 0xec, 0x09, 0x24, 0x48, 0x34, 0x8d, 0xe3, 0x60, 0x9b, + 0x80, 0xab, 0xe1, 0xf7, 0x1f, 0x6b, 0x8c, 0xeb, 0xae, 0xeb, 0xe9, 0x23, + 0x20, 0xe8, 0x00, 0x65, 0xf8, 0x09, 0x12, 0x80, 0xff, 0xf7, 0x1f, 0x6a, + 0x4c, 0xed, 0x8c, 0xea, 0x09, 0x10, 0x01, 0x4a, 0x09, 0x6b, 0x7a, 0xea, + 0x01, 0x2b, 0xe5, 0xe8, 0xff, 0xf7, 0x1f, 0x6b, 0x10, 0xea, 0x6c, 0xea, + 0x08, 0xb3, 0x80, 0xf0, 0x92, 0xa3, 0x4e, 0xec, 0x09, 0x24, 0x48, 0x34, + 0x8d, 0xe3, 0x60, 0x9b, 0x80, 0xab, 0xe1, 0xf7, 0x1f, 0x6b, 0x8c, 0xeb, + 0xae, 0xeb, 0xe9, 0x2b, 0x20, 0xe8, 0x00, 0x65, 0xf8, 0x09, 0x12, 0x80, + 0xff, 0xf7, 0x1f, 0x6a, 0x8c, 0xea, 0x09, 0x10, 0x01, 0x4a, 0x09, 0x6b, + 0x7a, 0xea, 0x01, 0x2b, 0xe5, 0xe8, 0xff, 0xf7, 0x1f, 0x6b, 0x10, 0xea, + 0x6c, 0xea, 0x07, 0xb3, 0x80, 0xf0, 0x92, 0xa3, 0x4e, 0xec, 0x06, 0x24, + 0x87, 0x42, 0x13, 0x4c, 0x88, 0x34, 0x8d, 0xe3, 0x61, 0x9b, 0xec, 0x2b, + 0x20, 0xe8, 0x00, 0x65, 0xf8, 0x09, 0x12, 0x80, 0xfe, 0x63, 0x03, 0xd1, + 0x02, 0xd0, 0xff, 0x6a, 0x8c, 0xea, 0x28, 0xb6, 0x28, 0xb5, 0x29, 0xb0, + 0x29, 0xb4, 0x2a, 0xb7, 0x28, 0x22, 0x40, 0xae, 0xff, 0xf7, 0x1d, 0x6b, + 0x0a, 0x65, 0x28, 0x67, 0x2c, 0xeb, 0x60, 0xce, 0x26, 0xb6, 0xc0, 0xae, + 0x60, 0xad, 0xff, 0xf7, 0x1f, 0x6a, 0x0e, 0x65, 0xc0, 0xa0, 0x08, 0x67, + 0x4c, 0xeb, 0xd9, 0xe0, 0x00, 0xf4, 0x00, 0x68, 0xe0, 0xf3, 0x1f, 0x69, + 0x0b, 0xe8, 0x2c, 0xee, 0x0c, 0xeb, 0xcd, 0xeb, 0xdd, 0x67, 0x60, 0xce, + 0x60, 0xae, 0x60, 0xcd, 0x60, 0xac, 0xa8, 0x67, 0x6c, 0xea, 0x60, 0xa7, + 0x0c, 0xea, 0x6d, 0xe5, 0x2c, 0xeb, 0x6d, 0xea, 0x40, 0xce, 0x40, 0xae, + 0x1b, 0x10, 0x60, 0xae, 0xff, 0xf7, 0x1f, 0x6a, 0x02, 0x69, 0x4c, 0xeb, + 0x2d, 0xeb, 0x4c, 0xeb, 0x60, 0xce, 0x60, 0xad, 0x00, 0xa0, 0x00, 0xf4, + 0x00, 0x6e, 0x4c, 0xeb, 0xcb, 0xee, 0xcc, 0xeb, 0x0d, 0xeb, 0x1d, 0x67, + 0x60, 0xc8, 0x60, 0xa8, 0x60, 0xcd, 0x60, 0xac, 0x6c, 0xea, 0x60, 0xa7, + 0xcc, 0xea, 0x6d, 0xea, 0x40, 0xc8, 0x40, 0xa8, 0x40, 0xcc, 0x03, 0x91, + 0x02, 0x90, 0x20, 0xe8, 0x02, 0x63, 0x00, 0x65, 0x58, 0x12, 0x00, 0xb6, + 0x10, 0x12, 0x00, 0xb6, 0x4c, 0x3c, 0x12, 0x80, 0x12, 0x12, 0x00, 0xb6, + 0x4d, 0x3c, 0x12, 0x80, 0x4e, 0x3c, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x04, 0xd0, 0x83, 0xa4, 0x05, 0x67, 0x12, 0x6a, 0x02, 0x5c, 0x0f, 0x60, + 0x0a, 0xb2, 0x20, 0xf0, 0x68, 0xa2, 0x01, 0x6a, 0x6c, 0xea, 0x03, 0x22, + 0x01, 0x74, 0x0c, 0x6a, 0x06, 0x60, 0x07, 0xb2, 0x80, 0xca, 0x07, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x00, 0x6a, 0x40, 0xc0, 0x05, 0x97, 0x04, 0x90, + 0x00, 0xef, 0x03, 0x63, 0x80, 0x22, 0x12, 0x80, 0x50, 0x3c, 0x12, 0x80, + 0xc5, 0x24, 0x10, 0x80, 0x00, 0x6a, 0x40, 0xc5, 0x41, 0xc5, 0x42, 0xc5, + 0x43, 0xc5, 0x44, 0xc5, 0x00, 0x6a, 0x10, 0xb3, 0x4d, 0xe3, 0xc0, 0xa3, + 0xff, 0x6b, 0x07, 0x6f, 0xc4, 0x36, 0x6c, 0xee, 0xce, 0x33, 0x6d, 0xe4, + 0x60, 0xa3, 0xec, 0xee, 0x67, 0xee, 0x03, 0x6e, 0xcc, 0xeb, 0x03, 0x73, + 0x08, 0x61, 0x4e, 0x36, 0xd9, 0xe5, 0x4c, 0xef, 0x01, 0x6b, 0x64, 0xef, + 0xe0, 0xa6, 0xed, 0xeb, 0x60, 0xc6, 0x01, 0x4a, 0xff, 0x6b, 0x6c, 0xea, + 0x25, 0x5a, 0xe3, 0x61, 0x20, 0xe8, 0x00, 0x65, 0x90, 0xe9, 0x01, 0x80, + 0xfb, 0x63, 0x09, 0x62, 0x08, 0xd1, 0x07, 0xd0, 0xff, 0x6a, 0x4c, 0xed, + 0x20, 0xa4, 0x0f, 0x25, 0x14, 0x6b, 0x78, 0xe9, 0x10, 0xb3, 0x04, 0xd3, + 0x12, 0xe9, 0x4c, 0xe9, 0x81, 0x41, 0x40, 0xeb, 0x4c, 0xec, 0x04, 0x93, + 0x42, 0x30, 0x91, 0x67, 0x40, 0xeb, 0x02, 0x30, 0x0b, 0x10, 0x1e, 0x6b, + 0xf8, 0x49, 0x78, 0xe9, 0x12, 0xec, 0x01, 0x4c, 0x4c, 0xec, 0x08, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x42, 0x30, 0x02, 0x30, 0x01, 0x58, 0x09, 0x97, + 0x08, 0x91, 0x07, 0x90, 0x58, 0x67, 0x00, 0xef, 0x05, 0x63, 0x00, 0x65, + 0x59, 0xa7, 0x01, 0x80, 0xb1, 0xa7, 0x01, 0x80, 0xfb, 0x63, 0x09, 0x62, + 0x08, 0xd1, 0x07, 0xd0, 0x1d, 0xa4, 0x3c, 0xa4, 0x7d, 0x67, 0x00, 0x30, + 0x2d, 0xe8, 0xff, 0xf7, 0x1f, 0x6a, 0x65, 0x58, 0xac, 0xea, 0x20, 0xf0, + 0xb8, 0xa3, 0x20, 0xf0, 0x7c, 0xa3, 0x04, 0x60, 0x64, 0x68, 0x1c, 0xc4, + 0x00, 0x68, 0x1d, 0xc4, 0x04, 0xd5, 0xa2, 0x67, 0x04, 0xb2, 0x40, 0xea, + 0x05, 0xd3, 0x09, 0x97, 0x08, 0x91, 0x07, 0x90, 0x00, 0xef, 0x05, 0x63, + 0xc1, 0x6a, 0x01, 0x80, 0xfd, 0x63, 0x05, 0x62, 0xff, 0x6a, 0x4c, 0xec, + 0x03, 0x24, 0x01, 0x74, 0x08, 0x60, 0x0f, 0x10, 0x09, 0xb3, 0xa0, 0xa3, + 0x04, 0x6c, 0xad, 0xec, 0x4c, 0xec, 0x80, 0xc3, 0x05, 0x10, 0x06, 0xb2, + 0x80, 0xa2, 0xfb, 0x6b, 0x6c, 0xec, 0x80, 0xc2, 0x04, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x56, 0x3c, 0x12, 0x80, + 0xd1, 0x1c, 0x01, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x0a, 0xb2, 0x60, 0xaa, + 0xff, 0xf7, 0x1f, 0x6a, 0x6c, 0xea, 0x42, 0x32, 0x3f, 0x6b, 0x6c, 0xea, + 0x09, 0x5a, 0x06, 0x61, 0x06, 0xb2, 0x40, 0xaa, 0x03, 0x22, 0x06, 0xb2, + 0x40, 0xea, 0x00, 0x6c, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, + 0xc8, 0x10, 0x00, 0xb6, 0x50, 0x3c, 0x12, 0x80, 0xb9, 0x26, 0x10, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x04, 0xd0, 0x60, 0xa4, 0x02, 0x6a, 0x05, 0x67, + 0x6c, 0xea, 0x03, 0x22, 0x09, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x61, 0xa0, + 0x40, 0x6a, 0x6c, 0xea, 0x06, 0x22, 0x07, 0xb2, 0x40, 0xaa, 0x03, 0x22, + 0x06, 0xb2, 0x40, 0xea, 0x01, 0x6c, 0x05, 0x97, 0x04, 0x90, 0x00, 0x6a, + 0x00, 0xef, 0x03, 0x63, 0xf5, 0x26, 0x10, 0x80, 0x50, 0x3c, 0x12, 0x80, + 0xb9, 0x26, 0x10, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x04, 0xd0, 0xff, 0x6a, + 0xff, 0xf7, 0x1f, 0x68, 0xac, 0xea, 0x8c, 0xe8, 0x0b, 0x22, 0x14, 0xb3, + 0x08, 0x32, 0x49, 0xe3, 0x13, 0xb3, 0xa0, 0x9a, 0x13, 0xb2, 0x40, 0xea, + 0x87, 0x9b, 0x13, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0e, 0xb3, 0x08, 0x34, + 0x00, 0x6a, 0x91, 0xe3, 0x40, 0xdc, 0x87, 0x40, 0x25, 0x4c, 0x84, 0x34, + 0x91, 0xe3, 0x41, 0xcc, 0x87, 0x40, 0x01, 0x4c, 0x88, 0x34, 0x91, 0xe3, + 0x41, 0xdc, 0x87, 0x40, 0x1d, 0x4c, 0x1a, 0x48, 0x08, 0x30, 0x84, 0x34, + 0x91, 0xe3, 0x0d, 0xe3, 0x40, 0xcc, 0x41, 0xdb, 0x05, 0x97, 0x04, 0x90, + 0x00, 0xef, 0x03, 0x63, 0xf8, 0x09, 0x12, 0x80, 0x98, 0x0a, 0x12, 0x80, + 0x45, 0xdb, 0x00, 0x80, 0x81, 0xd7, 0x00, 0x80, 0xfb, 0x63, 0x09, 0x62, + 0x08, 0xd1, 0x07, 0xd0, 0xff, 0xf7, 0x1f, 0x6b, 0x6c, 0xec, 0x04, 0xd4, + 0x04, 0x95, 0x59, 0xb4, 0x59, 0xb1, 0xa4, 0x32, 0x59, 0xb5, 0x49, 0xe5, + 0xc0, 0xaa, 0xa2, 0xac, 0xb5, 0xe6, 0xa2, 0xcc, 0x00, 0x6c, 0x80, 0xca, + 0x80, 0xf0, 0x93, 0xa1, 0x55, 0xb2, 0x40, 0xea, 0x05, 0xd3, 0x82, 0x67, + 0x54, 0xb2, 0x40, 0xea, 0x04, 0x95, 0x02, 0x67, 0x05, 0x93, 0x80, 0xf0, + 0x52, 0xa1, 0x4c, 0xeb, 0x0e, 0xeb, 0x80, 0xf0, 0x0f, 0x23, 0x04, 0x95, + 0x4f, 0xb2, 0x40, 0xea, 0x90, 0x67, 0x22, 0x67, 0x57, 0x10, 0x08, 0x32, + 0x4d, 0xe3, 0x40, 0x9b, 0x60, 0xaa, 0xe1, 0xf7, 0x1f, 0x6a, 0x6c, 0xea, + 0x04, 0x93, 0x4e, 0xeb, 0x49, 0xb2, 0x03, 0x2b, 0x90, 0x67, 0x01, 0x6d, + 0x02, 0x10, 0x90, 0x67, 0x00, 0x6d, 0x40, 0xea, 0x00, 0x65, 0x87, 0x41, + 0x13, 0x4c, 0x3f, 0xb2, 0x88, 0x34, 0x67, 0x40, 0x91, 0xe2, 0x81, 0x9c, + 0x13, 0x4b, 0x68, 0x33, 0x6d, 0xe2, 0x81, 0xdb, 0x28, 0x34, 0x91, 0xe2, + 0x80, 0x9c, 0x08, 0x33, 0x6d, 0xe2, 0x80, 0xdb, 0x87, 0x41, 0x25, 0x4c, + 0x84, 0x34, 0x67, 0x40, 0x91, 0xe2, 0x81, 0xac, 0x25, 0x4b, 0x64, 0x33, + 0x6d, 0xe2, 0x81, 0xcb, 0x87, 0x41, 0x01, 0x4c, 0x88, 0x34, 0x67, 0x40, + 0x91, 0xe2, 0x81, 0x9c, 0x01, 0x4b, 0x68, 0x33, 0x6d, 0xe2, 0x81, 0xdb, + 0x67, 0x40, 0x87, 0x41, 0x1d, 0x4b, 0x1d, 0x4c, 0x84, 0x34, 0x64, 0x33, + 0x6d, 0xe2, 0x89, 0xe2, 0x40, 0xaa, 0x01, 0x49, 0x04, 0x95, 0x40, 0xcb, + 0x09, 0x6a, 0x5a, 0xe9, 0x01, 0x2a, 0xe5, 0xe8, 0xff, 0xf7, 0x1f, 0x6b, + 0x05, 0xd3, 0x28, 0xb2, 0x01, 0x48, 0x10, 0xec, 0x40, 0xea, 0x6c, 0xec, + 0x09, 0x6c, 0x9a, 0xe8, 0x01, 0x2c, 0xe5, 0xe8, 0x05, 0x93, 0x22, 0x67, + 0x10, 0xe8, 0x6c, 0xe8, 0x1d, 0xb3, 0x80, 0xf0, 0x52, 0xa3, 0x4a, 0xe9, + 0xa4, 0x61, 0x0b, 0xe2, 0x00, 0x52, 0x01, 0x60, 0x09, 0x4a, 0x19, 0xb3, + 0x80, 0xf0, 0x90, 0xab, 0x30, 0x67, 0x4b, 0xe4, 0x80, 0xf0, 0x50, 0xcb, + 0x1a, 0x10, 0x28, 0x33, 0x69, 0xe2, 0x40, 0x9a, 0x60, 0xaa, 0xe1, 0xf7, + 0x1f, 0x6a, 0x6c, 0xea, 0x04, 0x93, 0x4e, 0xeb, 0x15, 0xb2, 0x03, 0x2b, + 0x91, 0x67, 0x01, 0x6d, 0x02, 0x10, 0x91, 0x67, 0x00, 0x6d, 0x40, 0xea, + 0x01, 0x49, 0x09, 0x6a, 0x5a, 0xe9, 0x01, 0x2a, 0xe5, 0xe8, 0xff, 0xf7, + 0x1f, 0x6a, 0x10, 0xe9, 0x4c, 0xe9, 0x08, 0xb2, 0x80, 0xf0, 0x72, 0xa2, + 0x2e, 0xeb, 0xe1, 0x2b, 0x80, 0xf0, 0x12, 0xc2, 0x09, 0x97, 0x08, 0x91, + 0x07, 0x90, 0x00, 0xef, 0x05, 0x63, 0x00, 0x65, 0xf0, 0x0b, 0x12, 0x80, + 0xf8, 0x09, 0x12, 0x80, 0x1c, 0x3c, 0x12, 0x80, 0x8d, 0x24, 0x10, 0x80, + 0x4d, 0x24, 0x10, 0x80, 0x0d, 0x24, 0x10, 0x80, 0x6d, 0x27, 0x10, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x40, 0xa4, 0x05, 0x72, 0x0d, 0x61, 0x09, 0xb2, + 0x20, 0xf0, 0x4c, 0xa2, 0x61, 0xa5, 0x82, 0xa5, 0x01, 0x72, 0x02, 0x60, + 0x03, 0x72, 0x04, 0x61, 0x80, 0x34, 0x05, 0xb2, 0x40, 0xea, 0x6d, 0xec, + 0x05, 0x97, 0x00, 0x6a, 0x00, 0xef, 0x03, 0x63, 0xf8, 0x0b, 0x12, 0x80, + 0xdd, 0x27, 0x10, 0x80, 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, + 0x43, 0xb2, 0x80, 0xf0, 0x73, 0xa2, 0xff, 0x69, 0x8c, 0xe9, 0x1a, 0x4b, + 0x68, 0x33, 0x6d, 0xe2, 0x00, 0x6c, 0x81, 0xdb, 0x3f, 0xb3, 0x20, 0xf0, + 0x6c, 0xa3, 0x01, 0x73, 0x09, 0x60, 0x03, 0x73, 0x07, 0x60, 0x80, 0xf0, + 0x73, 0xa2, 0x2c, 0x4b, 0x64, 0x33, 0x69, 0xe2, 0x41, 0xaa, 0x19, 0x2a, + 0x37, 0xb2, 0x80, 0xf0, 0x53, 0xa2, 0x38, 0xb3, 0xe1, 0xf7, 0x1f, 0x68, + 0x48, 0x32, 0x69, 0xe2, 0x40, 0xaa, 0x4c, 0xe8, 0x35, 0xb2, 0x40, 0xea, + 0x90, 0x67, 0x05, 0x2a, 0x34, 0xb2, 0x62, 0xaa, 0x01, 0x4b, 0x62, 0xca, + 0x06, 0x10, 0x33, 0xb2, 0x04, 0x30, 0x01, 0xe2, 0x40, 0xa8, 0x01, 0x4a, + 0x40, 0xc8, 0x2c, 0xb2, 0x20, 0xf0, 0x4c, 0xa2, 0x0a, 0x22, 0x02, 0x72, + 0x08, 0x60, 0x28, 0xb2, 0x80, 0xf0, 0x73, 0xa2, 0x2c, 0x4b, 0x64, 0x33, + 0x69, 0xe2, 0x41, 0xaa, 0x30, 0x2a, 0x05, 0x71, 0x23, 0xb4, 0x29, 0xb5, + 0x29, 0xb2, 0x09, 0x61, 0x80, 0xf0, 0x73, 0xa4, 0x68, 0x33, 0x6d, 0xe4, + 0x87, 0x9d, 0x40, 0xea, 0xa0, 0x9b, 0x26, 0xb2, 0x08, 0x10, 0x80, 0xf0, + 0x73, 0xa4, 0x68, 0x33, 0x6d, 0xe4, 0x83, 0x9d, 0x40, 0xea, 0xa0, 0x9b, + 0x22, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x18, 0xb2, 0x80, 0xf0, 0x73, 0xa2, + 0x00, 0x6c, 0x68, 0x33, 0x6d, 0xe2, 0x80, 0xdb, 0x80, 0xf0, 0x73, 0xa2, + 0xff, 0x6c, 0x01, 0x4b, 0x8c, 0xeb, 0x09, 0x6c, 0x9b, 0xeb, 0x01, 0x2c, + 0xe5, 0xe8, 0x10, 0xeb, 0x80, 0xf0, 0x73, 0xc2, 0x80, 0xf0, 0x70, 0xaa, + 0xff, 0x4b, 0x80, 0xf0, 0x70, 0xca, 0x0d, 0xb2, 0x20, 0xf0, 0x4c, 0xa2, + 0x01, 0x72, 0x02, 0x60, 0x03, 0x72, 0x0b, 0x61, 0x08, 0xb2, 0x80, 0xf0, + 0x73, 0xa2, 0x1a, 0x4b, 0x68, 0x33, 0x69, 0xe2, 0x41, 0x9a, 0x03, 0x2a, + 0x0e, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x07, 0x97, 0x06, 0x91, 0x05, 0x90, + 0x00, 0xef, 0x04, 0x63, 0xf8, 0x09, 0x12, 0x80, 0xf8, 0x0b, 0x12, 0x80, + 0x1c, 0x0a, 0x12, 0x80, 0x51, 0xc8, 0x01, 0x80, 0xf0, 0x0b, 0x12, 0x80, + 0x1c, 0x3c, 0x12, 0x80, 0x98, 0x0a, 0x12, 0x80, 0x45, 0xdb, 0x00, 0x80, + 0x81, 0xd7, 0x00, 0x80, 0xed, 0xd7, 0x00, 0x80, 0xc5, 0x53, 0x00, 0x80, + 0xfa, 0x63, 0x0b, 0x62, 0x0a, 0xd1, 0x09, 0xd0, 0x2b, 0xb2, 0x20, 0xf0, + 0x4c, 0xa2, 0x04, 0x67, 0x49, 0x22, 0xa3, 0xa4, 0x01, 0x69, 0x00, 0x6b, + 0x16, 0x10, 0x82, 0xa0, 0x01, 0x4b, 0x68, 0x32, 0x01, 0x4a, 0x42, 0xec, + 0x41, 0x61, 0x29, 0xe0, 0x84, 0xa2, 0x43, 0xa2, 0x06, 0xd3, 0x80, 0x34, + 0x4d, 0xec, 0x22, 0xb2, 0x40, 0xea, 0x05, 0xd5, 0x06, 0x93, 0x05, 0x95, + 0x35, 0x22, 0xff, 0x6a, 0x04, 0x49, 0x4c, 0xe9, 0x4c, 0xeb, 0xa3, 0xeb, + 0xe8, 0x61, 0xa3, 0xa0, 0x01, 0x69, 0x00, 0x6a, 0x27, 0x10, 0x2d, 0xe0, + 0xff, 0x6c, 0x02, 0x49, 0x8c, 0xe9, 0x39, 0xe0, 0x84, 0xa6, 0xc3, 0xa6, + 0xe3, 0xa3, 0x80, 0x34, 0xcd, 0xec, 0x14, 0xb6, 0x20, 0xf0, 0xcc, 0xa6, + 0x64, 0xa3, 0x01, 0x76, 0x02, 0x60, 0x03, 0x76, 0x08, 0x61, 0x60, 0x33, + 0xed, 0xeb, 0x11, 0xb6, 0x64, 0x33, 0x6d, 0xe6, 0xc0, 0xab, 0x9b, 0xe6, + 0xc0, 0xcb, 0xff, 0x6b, 0x04, 0xd2, 0x06, 0xd3, 0x05, 0xd5, 0x02, 0x49, + 0x0c, 0xb6, 0x40, 0xee, 0x6c, 0xe9, 0x04, 0x92, 0x06, 0x93, 0x05, 0x95, + 0x01, 0x4a, 0x6c, 0xea, 0xa3, 0xea, 0xd7, 0x61, 0x00, 0x6a, 0x01, 0x10, + 0x12, 0x6a, 0x0b, 0x97, 0x0a, 0x91, 0x09, 0x90, 0x00, 0xef, 0x06, 0x63, + 0xf8, 0x0b, 0x12, 0x80, 0x51, 0xc8, 0x01, 0x80, 0x1c, 0x3c, 0x12, 0x80, + 0xdd, 0x54, 0x00, 0x80, 0xfa, 0x63, 0x0b, 0x62, 0x0a, 0xd1, 0x09, 0xd0, + 0x04, 0xa4, 0x43, 0xa4, 0xe6, 0x44, 0x00, 0x30, 0x20, 0xa7, 0x67, 0xa4, + 0x4d, 0xe8, 0x45, 0x44, 0x6a, 0x65, 0x40, 0xa2, 0x20, 0x31, 0x01, 0x73, + 0x4d, 0xe9, 0x06, 0xd3, 0x1b, 0x60, 0x03, 0xe9, 0x19, 0x61, 0x20, 0x58, + 0x17, 0x60, 0x00, 0x6d, 0x20, 0x6e, 0xa4, 0xc4, 0xc3, 0xc4, 0x18, 0xb2, + 0x60, 0xa2, 0x0d, 0x65, 0x01, 0x6d, 0x4b, 0x65, 0x65, 0x67, 0xaa, 0x67, + 0xad, 0xeb, 0x20, 0x59, 0x60, 0xc2, 0x08, 0x60, 0xab, 0x67, 0x68, 0x67, + 0x60, 0xc7, 0xc0, 0xc5, 0xc0, 0xa2, 0x02, 0x6d, 0xcd, 0xed, 0xa0, 0xc2, + 0x0f, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0f, 0x2a, 0x06, 0x93, 0x01, 0x73, + 0x0c, 0x60, 0x0b, 0xb3, 0x80, 0xa3, 0x01, 0x6b, 0x8c, 0xeb, 0x02, 0x23, + 0x0a, 0xb3, 0x16, 0xcb, 0x02, 0x6b, 0x8c, 0xeb, 0x02, 0x23, 0x08, 0xb3, + 0x37, 0xcb, 0x00, 0x6c, 0x04, 0xb3, 0x80, 0xc3, 0x0b, 0x97, 0x0a, 0x91, + 0x09, 0x90, 0x00, 0xef, 0x06, 0x63, 0x00, 0x65, 0x0b, 0x3c, 0x12, 0x80, + 0xb1, 0x4b, 0x01, 0x80, 0x80, 0x22, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x04, 0xd0, 0x33, 0xb3, 0x20, 0xf0, 0xc8, 0xa3, 0x05, 0x67, 0x01, 0x6d, + 0xac, 0xee, 0x0c, 0x6a, 0x59, 0x2e, 0x30, 0xb2, 0xc0, 0x9a, 0x20, 0xf1, + 0x4c, 0xa3, 0x20, 0xf1, 0xea, 0xab, 0x24, 0x22, 0x01, 0xf7, 0x00, 0x6a, + 0xec, 0xea, 0xa4, 0xee, 0x43, 0x32, 0xff, 0x4d, 0xa2, 0xea, 0x1c, 0x61, + 0x20, 0xf0, 0x49, 0xa3, 0x1c, 0x6b, 0x6c, 0xea, 0x04, 0x72, 0x01, 0x60, + 0x15, 0x2a, 0x24, 0xb3, 0xb4, 0xab, 0x80, 0xf3, 0x01, 0x6a, 0x4b, 0xea, + 0xac, 0xea, 0xff, 0x6d, 0x01, 0x4d, 0xad, 0xea, 0xff, 0xf7, 0x1f, 0x6d, + 0x4c, 0xed, 0x54, 0xcb, 0x1d, 0x6a, 0xa2, 0x35, 0x4b, 0xea, 0xac, 0xea, + 0x0c, 0x6d, 0xad, 0xea, 0x20, 0xf0, 0x49, 0xc3, 0x43, 0xa4, 0x01, 0x72, + 0x00, 0x6a, 0x2a, 0x61, 0x17, 0xb2, 0x20, 0xf0, 0x8a, 0xa2, 0x40, 0x6b, + 0x8d, 0xeb, 0x20, 0xf0, 0x88, 0xa2, 0x20, 0xf0, 0x6a, 0xc2, 0x01, 0x6b, + 0x8d, 0xeb, 0x20, 0xf0, 0x68, 0xc2, 0x20, 0xf0, 0x49, 0xa2, 0x07, 0x6b, + 0x4a, 0x32, 0x6c, 0xea, 0x10, 0xb3, 0x49, 0xe3, 0x80, 0xa2, 0x10, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x01, 0x72, 0x09, 0x61, 0x0e, 0xb2, 0x40, 0xea, + 0x00, 0x6c, 0xff, 0x72, 0x04, 0x60, 0x82, 0x67, 0x0c, 0xb2, 0x40, 0xea, + 0x01, 0x6d, 0x0c, 0xb2, 0x40, 0x9a, 0x40, 0xea, 0x00, 0x65, 0x00, 0x6a, + 0x40, 0xc0, 0x00, 0x6a, 0x05, 0x97, 0x04, 0x90, 0x00, 0xef, 0x03, 0x63, + 0x80, 0x22, 0x12, 0x80, 0xa8, 0x03, 0x12, 0x80, 0x50, 0xe9, 0x01, 0x80, + 0xd9, 0xce, 0x01, 0x80, 0xe5, 0xdf, 0x01, 0x80, 0x21, 0xe0, 0x01, 0x80, + 0xa4, 0x04, 0x12, 0x80, 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd0, 0x19, 0xb0, + 0x20, 0xf0, 0x4a, 0xa0, 0x40, 0x6b, 0x4c, 0xeb, 0x00, 0x6a, 0x26, 0x23, + 0x82, 0x67, 0x16, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x20, 0xf0, 0x68, 0xa0, + 0x02, 0x6a, 0x4b, 0xea, 0x6c, 0xea, 0x20, 0xf0, 0x6a, 0xa0, 0x20, 0xf0, + 0x48, 0xc0, 0x41, 0x6a, 0x4b, 0xea, 0x6c, 0xea, 0x20, 0xf0, 0x4a, 0xc0, + 0x0e, 0xb2, 0x80, 0xa2, 0x02, 0x6d, 0x0e, 0xb2, 0x40, 0xea, 0x04, 0x00, + 0x9f, 0xf4, 0x07, 0x6c, 0x0c, 0xb2, 0x40, 0xea, 0xb0, 0x67, 0x00, 0x6a, + 0x7d, 0x67, 0x53, 0xc3, 0x0e, 0x6c, 0xb0, 0x67, 0x09, 0xb2, 0x40, 0xea, + 0x04, 0x6e, 0x01, 0x6a, 0x07, 0x97, 0x06, 0x90, 0x00, 0xef, 0x04, 0x63, + 0x80, 0x22, 0x12, 0x80, 0x4d, 0x3f, 0x00, 0x80, 0xf0, 0x04, 0x12, 0x80, + 0x21, 0xe0, 0x01, 0x80, 0x11, 0x2a, 0x01, 0x80, 0xbd, 0x49, 0x00, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0xff, 0x6a, 0x8c, 0xea, 0x05, 0x72, 0x21, 0x61, + 0x14, 0xb3, 0x74, 0xab, 0x80, 0xf3, 0x00, 0x6c, 0x8c, 0xeb, 0x03, 0x23, + 0x00, 0xf3, 0x00, 0x73, 0x09, 0x61, 0x11, 0xb4, 0xe0, 0xf1, 0x1f, 0x6b, + 0xa0, 0xac, 0xac, 0xeb, 0x00, 0xf6, 0x00, 0x6d, 0xad, 0xeb, 0x60, 0xcc, + 0x0b, 0xb3, 0x20, 0xf0, 0x8a, 0xa3, 0x40, 0x6b, 0x8c, 0xeb, 0x09, 0x23, + 0x0a, 0xb4, 0xff, 0xf7, 0x1f, 0x6d, 0x10, 0x6e, 0x60, 0xac, 0xac, 0xeb, + 0xcd, 0xeb, 0xac, 0xeb, 0x60, 0xcc, 0x82, 0x67, 0x06, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x80, 0x22, 0x12, 0x80, + 0x40, 0x10, 0x00, 0xb6, 0x8e, 0x12, 0x00, 0xb6, 0x49, 0xaa, 0x01, 0x80, + 0xfa, 0x63, 0x0b, 0x62, 0x0a, 0xd0, 0x00, 0x6b, 0x26, 0xb2, 0x60, 0xc2, + 0x26, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x26, 0xb2, 0x40, 0xa2, 0x03, 0x2a, + 0x25, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x00, 0x6a, 0x24, 0xb3, 0x40, 0xc3, + 0x24, 0xb3, 0x40, 0xc3, 0x00, 0x6a, 0x24, 0xb3, 0x4d, 0xe3, 0x01, 0x4a, + 0x00, 0x6c, 0x08, 0x52, 0x80, 0xc3, 0xf9, 0x61, 0x21, 0xb3, 0x51, 0xa3, + 0x70, 0xa3, 0x40, 0x32, 0x6d, 0xea, 0x20, 0xb3, 0x40, 0xcb, 0x20, 0xb2, + 0x60, 0xaa, 0x20, 0xb2, 0x60, 0xc2, 0x20, 0xb2, 0x60, 0xaa, 0x20, 0xb2, + 0x60, 0xc2, 0xa0, 0xf1, 0x03, 0x6b, 0x1f, 0xb2, 0x60, 0xca, 0x1f, 0xb2, + 0x00, 0x6b, 0x60, 0xca, 0x00, 0x6a, 0x1e, 0xb4, 0x51, 0xe4, 0x80, 0xa4, + 0x04, 0x00, 0x4d, 0xe0, 0x88, 0xc3, 0x01, 0x4a, 0xff, 0x6b, 0x6c, 0xea, + 0x0a, 0x5a, 0xf5, 0x61, 0x06, 0x04, 0x19, 0xb2, 0x40, 0xea, 0xb0, 0x67, + 0xb0, 0x67, 0x18, 0xb4, 0x18, 0xb2, 0x40, 0xea, 0x05, 0x6e, 0x00, 0x6b, + 0x17, 0xb2, 0x80, 0xf1, 0x65, 0xc2, 0x0b, 0x97, 0x0a, 0x90, 0x00, 0xef, + 0x06, 0x63, 0x00, 0x65, 0x0b, 0x3c, 0x12, 0x80, 0x65, 0x33, 0x10, 0x80, + 0x0a, 0x3c, 0x12, 0x80, 0x0d, 0x3b, 0x10, 0x80, 0x08, 0x3c, 0x12, 0x80, + 0x09, 0x3c, 0x12, 0x80, 0x00, 0x3c, 0x12, 0x80, 0x2c, 0x0c, 0x12, 0x80, + 0xe8, 0x10, 0x00, 0xb6, 0x10, 0x12, 0x00, 0xb6, 0x4c, 0x3c, 0x12, 0x80, + 0x12, 0x12, 0x00, 0xb6, 0x4d, 0x3c, 0x12, 0x80, 0x4e, 0x3c, 0x12, 0x80, + 0x50, 0x3c, 0x12, 0x80, 0xc8, 0x3e, 0x10, 0x80, 0xc9, 0x25, 0x10, 0x80, + 0x97, 0x23, 0x12, 0x80, 0x7d, 0xc0, 0x00, 0x80, 0x80, 0x22, 0x12, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x40, 0xac, 0x01, 0xf4, 0x03, 0x72, 0x03, 0x61, + 0x04, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x05, 0x97, 0x00, 0x6a, 0x00, 0xef, + 0x03, 0x63, 0x00, 0x65, 0x1d, 0x2e, 0x10, 0x80, 0xf6, 0x63, 0x13, 0x62, + 0x12, 0xd1, 0x11, 0xd0, 0x01, 0x6a, 0x7d, 0x67, 0x50, 0xc3, 0x60, 0xac, + 0x04, 0x67, 0x9f, 0xf4, 0x17, 0x6c, 0x6e, 0xec, 0x26, 0x67, 0x2b, 0x24, + 0x9f, 0xf4, 0x18, 0x6c, 0x83, 0xeb, 0x04, 0x60, 0x9f, 0xf4, 0x07, 0x73, + 0x08, 0x60, 0x94, 0x10, 0x9f, 0xf5, 0x00, 0x73, 0x0a, 0x60, 0x9f, 0xf5, + 0x12, 0x73, 0x7d, 0x60, 0x8d, 0x10, 0x90, 0x67, 0x4e, 0xb2, 0x40, 0xea, + 0x04, 0x05, 0x22, 0x67, 0x91, 0x10, 0xc3, 0xa0, 0x04, 0x26, 0x0c, 0x76, + 0x12, 0x69, 0x0a, 0x61, 0x03, 0x10, 0x90, 0x67, 0x49, 0xb2, 0x02, 0x10, + 0x90, 0x67, 0x49, 0xb2, 0x40, 0xea, 0x0e, 0xd6, 0x0e, 0x96, 0x22, 0x67, + 0x80, 0xa8, 0xb1, 0x67, 0x46, 0xb2, 0x40, 0xea, 0xc0, 0x36, 0x00, 0x6a, + 0x67, 0x10, 0x45, 0xb6, 0x80, 0xde, 0x81, 0xde, 0x63, 0x40, 0xae, 0xa3, + 0xef, 0xa3, 0x00, 0x69, 0xa0, 0x35, 0xed, 0xed, 0xfd, 0x67, 0xb2, 0xcf, + 0xac, 0xa3, 0xf0, 0xa0, 0xa0, 0x35, 0xed, 0xed, 0xfd, 0x67, 0xb3, 0xcf, + 0xaa, 0xa3, 0xeb, 0xa3, 0xa0, 0x35, 0xed, 0xed, 0xfd, 0x67, 0xb4, 0xcf, + 0xa8, 0xa3, 0xec, 0xa0, 0xa0, 0x35, 0xed, 0xed, 0xfd, 0x67, 0xb5, 0xcf, + 0xa6, 0xa3, 0xe7, 0xa3, 0xa0, 0x35, 0xed, 0xed, 0xfd, 0x67, 0xb6, 0xcf, + 0xa4, 0xa3, 0xe8, 0xa0, 0xa0, 0x35, 0xed, 0xed, 0xfd, 0x67, 0xb7, 0xcf, + 0xa2, 0xa3, 0x63, 0xa3, 0xa0, 0x35, 0x6d, 0xed, 0xb8, 0xcf, 0x63, 0xa0, + 0xa4, 0xa0, 0x60, 0x33, 0xad, 0xeb, 0x79, 0xcf, 0x2c, 0xb3, 0xc0, 0xf1, + 0xb9, 0xa3, 0xc0, 0xf1, 0xf8, 0xa3, 0xa0, 0x35, 0xed, 0xed, 0xfd, 0x67, + 0xb1, 0xcf, 0xc0, 0xf1, 0xb7, 0xa3, 0xc0, 0xf1, 0xf6, 0xa3, 0xa0, 0x35, + 0xed, 0xed, 0xfd, 0x67, 0xb0, 0xcf, 0xc0, 0xf1, 0xb5, 0xa3, 0xc0, 0xf1, + 0x74, 0xa3, 0xa0, 0x35, 0x6d, 0xed, 0xaf, 0xcf, 0x21, 0xb3, 0x22, 0xb5, + 0xa0, 0xad, 0x60, 0xab, 0x8a, 0xcf, 0xad, 0xcf, 0x6e, 0xcf, 0xae, 0xeb, + 0x6c, 0xcf, 0x01, 0x6b, 0x6b, 0xeb, 0x6b, 0xcf, 0x05, 0x04, 0x1d, 0xb3, + 0x0e, 0xd2, 0x40, 0xeb, 0x09, 0x05, 0x0e, 0x92, 0x7d, 0x67, 0x50, 0xc3, + 0x1b, 0x10, 0x0e, 0xd2, 0x90, 0x67, 0x19, 0xb3, 0x40, 0xeb, 0xa6, 0x67, + 0x20, 0xa1, 0x0e, 0x92, 0xbd, 0x67, 0x50, 0xc5, 0x11, 0x10, 0x80, 0xa8, + 0xb1, 0x67, 0x0e, 0xb2, 0x40, 0xea, 0x00, 0x6e, 0x01, 0x6a, 0x05, 0x10, + 0x01, 0x6a, 0x40, 0xc5, 0x00, 0x6a, 0x40, 0xc1, 0x00, 0x6a, 0x13, 0x97, + 0x12, 0x91, 0x11, 0x90, 0x00, 0xef, 0x0a, 0x63, 0xfd, 0x67, 0x50, 0xa7, + 0x01, 0x72, 0x01, 0x6a, 0xf6, 0x61, 0xe9, 0x17, 0x45, 0x2c, 0x10, 0x80, + 0xa9, 0x22, 0x10, 0x80, 0x5d, 0x23, 0x10, 0x80, 0xa9, 0xaa, 0x00, 0x80, + 0x0c, 0x3c, 0x12, 0x80, 0x18, 0x01, 0x12, 0x80, 0x12, 0x01, 0x12, 0x80, + 0x10, 0x01, 0x12, 0x80, 0x41, 0xa9, 0x01, 0x80, 0x85, 0x25, 0x10, 0x80, + 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, 0x44, 0xac, 0x04, 0x67, + 0xe0, 0xf1, 0x16, 0x72, 0x17, 0x60, 0x40, 0xf4, 0x12, 0x72, 0x17, 0x61, + 0x40, 0x9c, 0x60, 0xa2, 0x3e, 0x73, 0x13, 0x61, 0x42, 0xa2, 0x02, 0x72, + 0x10, 0x61, 0x0d, 0xb1, 0x0d, 0xb2, 0x40, 0xea, 0x81, 0x99, 0xff, 0x6b, + 0x4c, 0xeb, 0x03, 0x5b, 0x08, 0x60, 0x81, 0x99, 0x0a, 0xb2, 0x40, 0xea, + 0xa0, 0x98, 0x07, 0x10, 0x80, 0xa4, 0x09, 0xb2, 0x02, 0x10, 0x90, 0x67, + 0x08, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x07, 0x97, 0x06, 0x91, 0x05, 0x90, + 0x00, 0xef, 0x04, 0x63, 0x98, 0x0a, 0x12, 0x80, 0x35, 0xdb, 0x00, 0x80, + 0x45, 0xdb, 0x00, 0x80, 0xa1, 0x29, 0x10, 0x80, 0x2d, 0x59, 0x00, 0x80, + 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd0, 0x04, 0x67, 0x80, 0xac, 0x21, 0xf4, + 0x15, 0x74, 0x0a, 0x61, 0x0f, 0xb2, 0x40, 0xea, 0x90, 0x67, 0xa2, 0x67, + 0x01, 0x6a, 0x13, 0x25, 0x80, 0xa8, 0x04, 0xd2, 0x00, 0x6e, 0x0b, 0x10, + 0xeb, 0xf7, 0x40, 0x44, 0xff, 0xf7, 0x1f, 0x6b, 0x6c, 0xea, 0xe0, 0x5a, + 0x00, 0x6a, 0x07, 0x60, 0x04, 0xd2, 0x01, 0x6d, 0xc2, 0x67, 0x06, 0xb2, + 0x40, 0xea, 0xe6, 0x67, 0x01, 0x6a, 0x07, 0x97, 0x06, 0x90, 0x00, 0xef, + 0x04, 0x63, 0x00, 0x65, 0xe1, 0x2a, 0x10, 0x80, 0x81, 0x4c, 0x00, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x03, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x05, 0x97, + 0x00, 0xef, 0x03, 0x63, 0x7d, 0x92, 0x00, 0x80, 0xfb, 0x63, 0x09, 0x62, + 0x08, 0xd1, 0x07, 0xd0, 0x18, 0xb3, 0x19, 0xb2, 0x43, 0xeb, 0x26, 0x61, + 0x18, 0xb2, 0x80, 0x9a, 0x18, 0xb3, 0x8e, 0xeb, 0x21, 0x2b, 0x02, 0xaa, + 0x17, 0xb5, 0x1d, 0x10, 0x42, 0x45, 0x17, 0xb4, 0x43, 0xec, 0x1a, 0x61, + 0xc0, 0xa2, 0xff, 0xf7, 0x1f, 0x6f, 0x43, 0x46, 0x43, 0xe8, 0x14, 0x61, + 0x45, 0xe5, 0x23, 0xec, 0x11, 0x61, 0x81, 0xa5, 0x60, 0xa5, 0x80, 0x34, + 0x6d, 0xec, 0xec, 0xec, 0xe0, 0xf1, 0x04, 0x5c, 0x09, 0x60, 0x43, 0xe0, + 0x0d, 0xb2, 0x91, 0xe2, 0x03, 0x4d, 0x0d, 0xb2, 0x40, 0xea, 0xec, 0xe8, + 0xb1, 0x67, 0xe2, 0x28, 0x09, 0x97, 0x08, 0x91, 0x07, 0x90, 0x00, 0xef, + 0x05, 0x63, 0x00, 0x65, 0xf0, 0xbf, 0x10, 0x80, 0xb4, 0x3f, 0x10, 0x80, + 0xb8, 0x3f, 0x10, 0x80, 0x55, 0xab, 0x23, 0x87, 0xbe, 0x3f, 0x10, 0x80, + 0xff, 0xbf, 0x10, 0x80, 0x18, 0x01, 0x12, 0x80, 0x7d, 0xc0, 0x00, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x0e, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0e, 0xb3, + 0xff, 0xf7, 0x1f, 0x6c, 0x02, 0xf0, 0x00, 0x6d, 0x40, 0xab, 0xab, 0xed, + 0x8c, 0xea, 0xad, 0xea, 0x3f, 0x4d, 0xac, 0xea, 0x02, 0xf1, 0x01, 0x4d, + 0xad, 0xea, 0x9f, 0xf6, 0x00, 0x4d, 0xac, 0xea, 0x05, 0x6d, 0xad, 0xea, + 0x8c, 0xea, 0x40, 0xcb, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, + 0x21, 0x6f, 0x01, 0x80, 0x28, 0x12, 0x00, 0xb6, 0xfd, 0x63, 0x05, 0x62, + 0x0a, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0a, 0xb2, 0x20, 0xf0, 0x8a, 0xa2, + 0x01, 0x6b, 0x8d, 0xeb, 0xa0, 0xf1, 0x95, 0xa2, 0x20, 0xf0, 0x6a, 0xc2, + 0x07, 0x6b, 0x6b, 0xeb, 0x8c, 0xeb, 0xa0, 0xf1, 0x75, 0xc2, 0x05, 0x97, + 0x00, 0xef, 0x03, 0x63, 0xb1, 0x73, 0x01, 0x80, 0x80, 0x22, 0x12, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x0d, 0xb2, 0x0e, 0xb3, 0x72, 0xda, 0x0e, 0xb3, + 0x6c, 0xda, 0x0e, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0d, 0xb2, 0xff, 0xf7, + 0x1f, 0x6b, 0xff, 0x6c, 0xa0, 0xaa, 0x08, 0xf0, 0x00, 0x6a, 0x7b, 0x4c, + 0x6c, 0xed, 0x4d, 0xed, 0x09, 0xb2, 0x40, 0x9a, 0x40, 0xea, 0x6c, 0xed, + 0x05, 0x97, 0x00, 0x6a, 0x00, 0xef, 0x03, 0x63, 0x10, 0x19, 0x12, 0x80, + 0x89, 0x31, 0x10, 0x80, 0xc9, 0x30, 0x10, 0x80, 0x69, 0x35, 0x10, 0x80, + 0x7a, 0x01, 0x00, 0xb6, 0x0c, 0x00, 0x12, 0x80, 0x15, 0xb3, 0x16, 0xb2, + 0x60, 0xda, 0x16, 0xb3, 0x16, 0xb2, 0x60, 0xda, 0x16, 0xb2, 0xa0, 0xf0, + 0x6f, 0xa2, 0xa0, 0xf0, 0x8e, 0xa2, 0x60, 0x33, 0x8d, 0xeb, 0xa0, 0xf0, + 0x90, 0xa2, 0x80, 0x34, 0x80, 0x34, 0x6d, 0xec, 0xa0, 0xf0, 0x71, 0xa2, + 0x00, 0xf6, 0x60, 0x33, 0x8d, 0xeb, 0x0f, 0xb4, 0x8d, 0xeb, 0x62, 0x34, + 0xa0, 0xf0, 0x6e, 0xc2, 0xa0, 0xf0, 0x8f, 0xc2, 0x00, 0xf6, 0x62, 0x33, + 0x82, 0x34, 0xa0, 0xf0, 0x71, 0xc2, 0xa0, 0xf0, 0x90, 0xc2, 0x09, 0xb3, + 0x09, 0xb2, 0x20, 0xe8, 0x60, 0xda, 0x00, 0x65, 0x11, 0x37, 0x10, 0x80, + 0xc4, 0x06, 0x12, 0x80, 0xa5, 0x34, 0x10, 0x80, 0xc0, 0x07, 0x12, 0x80, + 0x18, 0x01, 0x12, 0x80, 0x00, 0x00, 0x00, 0x80, 0x1d, 0x34, 0x10, 0x80, + 0xc0, 0x06, 0x12, 0x80, 0x20, 0xe8, 0x00, 0x65, 0x08, 0xb2, 0x40, 0x9a, + 0x61, 0x42, 0x09, 0x23, 0x03, 0x6b, 0x78, 0xea, 0x06, 0xb3, 0x12, 0xea, + 0x01, 0x4a, 0x4c, 0x32, 0x49, 0xe3, 0x05, 0xb3, 0x61, 0xda, 0x20, 0xe8, + 0x00, 0x65, 0x00, 0x65, 0xdc, 0x00, 0x12, 0x80, 0xd8, 0x19, 0x12, 0x80, + 0x81, 0x36, 0x10, 0x80, 0x08, 0xb2, 0x20, 0xf1, 0x6c, 0xa2, 0x61, 0xc4, + 0x00, 0x6b, 0x60, 0xc4, 0x40, 0xf0, 0xa4, 0xa2, 0x01, 0x6b, 0x6c, 0xed, + 0xa2, 0xc4, 0xe0, 0xf0, 0x5c, 0xa2, 0x4c, 0xeb, 0x20, 0xe8, 0x63, 0xc4, + 0x80, 0x22, 0x12, 0x80, 0x11, 0xb2, 0xa1, 0xa4, 0x20, 0xf0, 0x42, 0xa2, + 0x00, 0x6b, 0xae, 0xea, 0x01, 0x22, 0x01, 0x6b, 0x01, 0x6a, 0x6c, 0xea, + 0x0d, 0xb3, 0xc2, 0xa4, 0x60, 0xa3, 0x00, 0x6d, 0xce, 0xeb, 0x01, 0x23, + 0x01, 0x6d, 0x01, 0x6b, 0xac, 0xeb, 0x74, 0x33, 0x4d, 0xeb, 0x08, 0xb2, + 0x83, 0xa4, 0x41, 0xa2, 0x00, 0x6d, 0x8e, 0xea, 0x01, 0x22, 0x01, 0x6d, + 0x01, 0x6a, 0xac, 0xea, 0x40, 0x32, 0x4c, 0x32, 0x20, 0xe8, 0x6d, 0xea, + 0xb0, 0x0c, 0x12, 0x80, 0x54, 0x3c, 0x12, 0x80, 0x61, 0xa4, 0x05, 0xb2, + 0x20, 0xf0, 0x62, 0xc2, 0x62, 0xa4, 0x04, 0xb2, 0x60, 0xc2, 0x63, 0xa4, + 0x20, 0xe8, 0x61, 0xc2, 0xb0, 0x0c, 0x12, 0x80, 0x54, 0x3c, 0x12, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x04, 0xd0, 0x10, 0xb0, 0x40, 0x98, 0xa0, 0xf1, + 0x06, 0x6c, 0x20, 0xf2, 0x00, 0x6d, 0x40, 0xea, 0x00, 0x65, 0x40, 0x98, + 0xa0, 0xf1, 0x12, 0x6c, 0x40, 0xea, 0xff, 0x6d, 0x40, 0x98, 0xfa, 0x6c, + 0x40, 0xea, 0x32, 0x6d, 0x40, 0x98, 0xf4, 0x6c, 0x40, 0xea, 0x01, 0x6d, + 0x40, 0x98, 0xa0, 0xf1, 0x0a, 0x6c, 0x40, 0xea, 0x03, 0x6d, 0x05, 0x97, + 0x04, 0x90, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, 0x0c, 0x00, 0x12, 0x80, + 0x20, 0xe8, 0x00, 0x6a, 0x20, 0xe8, 0x00, 0x6a, 0x20, 0xe8, 0x00, 0x6a, + 0x20, 0xe8, 0x7f, 0x6a, 0x06, 0xb2, 0x20, 0xf0, 0x47, 0xa2, 0x03, 0x22, + 0xe9, 0xf7, 0x1a, 0x6a, 0x01, 0x10, 0x40, 0xac, 0x40, 0xcd, 0x20, 0xe8, + 0x00, 0x6a, 0x00, 0x65, 0xb0, 0x0c, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x03, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, + 0xd5, 0x15, 0x01, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x60, 0x9c, 0x10, 0xf0, + 0x00, 0x6a, 0x6c, 0xea, 0x0c, 0x22, 0x09, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x08, 0xb3, 0xff, 0x6c, 0x80, 0x6d, 0x40, 0xa3, 0xab, 0xed, 0x8c, 0xea, + 0xad, 0xea, 0x8c, 0xea, 0x40, 0xc3, 0x05, 0x97, 0x01, 0x6a, 0x00, 0xef, + 0x03, 0x63, 0x00, 0x65, 0x49, 0xbe, 0x00, 0x80, 0xbc, 0xa0, 0x00, 0xb0, + 0xfa, 0x63, 0x0b, 0x62, 0x0a, 0xd1, 0x09, 0xd0, 0x1b, 0xb2, 0x1c, 0xb1, + 0x20, 0xf0, 0x67, 0xa1, 0xe0, 0xaa, 0x1b, 0xb4, 0xff, 0xf7, 0x1f, 0x68, + 0x0c, 0xef, 0x40, 0xa4, 0xc1, 0xa4, 0x1b, 0x23, 0x05, 0xd2, 0x06, 0xd3, + 0x04, 0xd6, 0x17, 0xb4, 0x40, 0xec, 0x07, 0xd7, 0x16, 0xb4, 0xa0, 0xac, + 0x01, 0x6c, 0x0c, 0xed, 0x8d, 0xed, 0x15, 0xb4, 0x80, 0x9c, 0x0c, 0xed, + 0x0c, 0x65, 0x08, 0x67, 0x00, 0xf2, 0x1a, 0x6c, 0x40, 0xe8, 0x00, 0x65, + 0x00, 0x6c, 0x20, 0xf0, 0x87, 0xc1, 0x07, 0x97, 0x04, 0x96, 0x06, 0x93, + 0x05, 0x92, 0x64, 0x33, 0x54, 0x32, 0x6d, 0xea, 0xf6, 0x37, 0x01, 0x6b, + 0xd8, 0x36, 0x6c, 0xef, 0xcd, 0xea, 0xec, 0x37, 0xed, 0xea, 0x0b, 0x97, + 0x0a, 0x91, 0x09, 0x90, 0x00, 0xef, 0x06, 0x63, 0xa6, 0x01, 0x00, 0xb6, + 0xb0, 0x0c, 0x12, 0x80, 0x54, 0x3c, 0x12, 0x80, 0x49, 0xbe, 0x00, 0x80, + 0x1a, 0x02, 0x00, 0xb6, 0x0c, 0x00, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x0b, 0xb3, 0x0c, 0xb2, 0x7b, 0xda, 0x0c, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x0b, 0xb2, 0xff, 0xf7, 0x1f, 0x6b, 0x00, 0xf2, 0x1a, 0x6c, 0xa0, 0xaa, + 0x01, 0x6a, 0x6c, 0xed, 0x4d, 0xed, 0x08, 0xb2, 0x40, 0x9a, 0x40, 0xea, + 0x6c, 0xed, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x91, 0x34, 0x10, 0x80, + 0x10, 0x19, 0x12, 0x80, 0x49, 0xbe, 0x00, 0x80, 0x1a, 0x02, 0x00, 0xb6, + 0x0c, 0x00, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x04, 0xd0, 0x09, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x08, 0xb3, 0x20, 0xf0, 0x02, 0xa3, 0x82, 0x67, + 0x07, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0b, 0xea, 0x05, 0x97, 0x04, 0x90, + 0xc0, 0xf7, 0x42, 0x32, 0x00, 0xef, 0x03, 0x63, 0x00, 0x2b, 0x00, 0x80, + 0xb0, 0x0c, 0x12, 0x80, 0x1c, 0x2b, 0x00, 0x80, 0xf8, 0x63, 0x0f, 0x62, + 0x0e, 0xd1, 0x0d, 0xd0, 0xff, 0x69, 0x8c, 0xe9, 0x5d, 0x67, 0x9d, 0x67, + 0x38, 0xc2, 0x06, 0x6a, 0x59, 0xc4, 0x00, 0x6a, 0x5a, 0xc4, 0x5b, 0xc4, + 0x5c, 0xc4, 0x5d, 0xc4, 0x5e, 0xc4, 0x5f, 0xc4, 0x00, 0x68, 0x1c, 0xb3, + 0x08, 0x32, 0x49, 0xe3, 0x40, 0x9a, 0x40, 0xea, 0x00, 0x65, 0x9d, 0x67, + 0x0d, 0xe4, 0x5a, 0xc3, 0x01, 0x48, 0xff, 0x6a, 0x4c, 0xe8, 0x06, 0x58, + 0xf2, 0x61, 0xba, 0xa4, 0x02, 0x6a, 0x54, 0xcc, 0x5b, 0xa4, 0xa0, 0x35, + 0xa0, 0x35, 0x00, 0xf6, 0x40, 0x32, 0x4d, 0xed, 0x00, 0xf6, 0x00, 0x6a, + 0x4d, 0xed, 0x2d, 0xed, 0x08, 0xd5, 0x5e, 0xa4, 0xdd, 0xa4, 0x0a, 0x97, + 0x40, 0x32, 0x40, 0x32, 0xc0, 0x36, 0x4d, 0xee, 0x5c, 0xa4, 0x4d, 0xee, + 0x5f, 0xa4, 0x00, 0xf6, 0x40, 0x32, 0x4d, 0xee, 0x09, 0xd6, 0x08, 0xb2, + 0x80, 0x9a, 0x0b, 0x92, 0x04, 0xd2, 0x07, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x0f, 0x97, 0x0e, 0x91, 0x0d, 0x90, 0x00, 0xef, 0x08, 0x63, 0x00, 0x65, + 0xd4, 0x3e, 0x10, 0x80, 0xa4, 0x1c, 0x12, 0x80, 0x91, 0xd8, 0x00, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x1e, 0xb2, 0x60, 0xaa, 0x28, 0x73, 0x01, 0x4b, + 0x01, 0x61, 0x01, 0x6b, 0x60, 0xca, 0x1c, 0xb2, 0x40, 0xf0, 0xc4, 0xa2, + 0xe0, 0xf0, 0x9c, 0xa2, 0x01, 0x6b, 0x6c, 0xee, 0x6c, 0xec, 0x19, 0xb3, + 0x20, 0xf1, 0xec, 0xa2, 0x20, 0xf0, 0x62, 0xa3, 0x00, 0x6a, 0xee, 0xeb, + 0x01, 0x23, 0x01, 0x6a, 0x01, 0x6b, 0x4c, 0xeb, 0x14, 0xb2, 0x40, 0xa2, + 0x00, 0x6d, 0xce, 0xea, 0x01, 0x22, 0x01, 0x6d, 0x01, 0x6a, 0xac, 0xea, + 0x10, 0xb5, 0xa1, 0xa5, 0x54, 0x32, 0x6d, 0xea, 0x8e, 0xed, 0x00, 0x6b, + 0x01, 0x25, 0x01, 0x6b, 0x01, 0x6d, 0x6c, 0xed, 0xa0, 0x35, 0xac, 0x35, + 0x4d, 0xed, 0x09, 0xb2, 0x20, 0xf0, 0xe2, 0xc2, 0x08, 0xb2, 0xc0, 0xc2, + 0x81, 0xc2, 0x03, 0x25, 0x07, 0xb2, 0x40, 0xea, 0x27, 0x6c, 0x05, 0x97, + 0x00, 0xef, 0x03, 0x63, 0x58, 0x3c, 0x12, 0x80, 0x80, 0x22, 0x12, 0x80, + 0xb0, 0x0c, 0x12, 0x80, 0x54, 0x3c, 0x12, 0x80, 0xe1, 0x35, 0x10, 0x80, + 0xfc, 0x63, 0x07, 0x62, 0x1a, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x1a, 0xb2, + 0xa0, 0xf0, 0x83, 0xa2, 0xa0, 0xf0, 0x62, 0xa2, 0x80, 0x34, 0x6d, 0xec, + 0xa0, 0xf0, 0x64, 0xa2, 0xa0, 0xf0, 0x45, 0xa2, 0x60, 0x33, 0x60, 0x33, + 0x8d, 0xeb, 0x00, 0xf6, 0x40, 0x32, 0x6d, 0xea, 0x12, 0xb3, 0x6c, 0xea, + 0x19, 0x22, 0x12, 0xb4, 0x40, 0x9c, 0x01, 0x4a, 0x03, 0x22, 0x11, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x00, 0x6a, 0xe2, 0x67, 0x04, 0xd2, 0x0d, 0xb5, + 0x0e, 0xb6, 0x0f, 0xb2, 0x40, 0xea, 0x01, 0x6c, 0x0a, 0xb2, 0x80, 0x9a, + 0x0d, 0xb2, 0xa4, 0x9a, 0x0d, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0d, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x07, 0x97, 0x00, 0xef, 0x04, 0x63, 0x00, 0x65, + 0x49, 0xbf, 0x00, 0x80, 0x18, 0x01, 0x12, 0x80, 0x00, 0x00, 0x00, 0x40, + 0xdc, 0x00, 0x12, 0x80, 0x81, 0xda, 0x00, 0x80, 0x81, 0x36, 0x10, 0x80, + 0xd5, 0xda, 0x00, 0x80, 0xb0, 0x0c, 0x12, 0x80, 0x25, 0xda, 0x00, 0x80, + 0xd5, 0xbe, 0x00, 0x80, 0xff, 0xf7, 0x1f, 0x6a, 0x8c, 0xea, 0x00, 0x6b, + 0x68, 0x34, 0xc2, 0x67, 0xc7, 0xec, 0x86, 0x67, 0x0f, 0x6e, 0xcc, 0xec, + 0x8e, 0x37, 0x79, 0xe5, 0x03, 0x27, 0x10, 0x6f, 0xeb, 0xef, 0xee, 0xec, + 0x80, 0xc6, 0x01, 0x4b, 0xff, 0x6c, 0x8c, 0xeb, 0x04, 0x5b, 0xee, 0x61, + 0x20, 0xe8, 0x00, 0x65, 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd0, 0xff, 0xf7, + 0x1f, 0x6a, 0x8c, 0xea, 0x00, 0x6b, 0x68, 0x34, 0xa2, 0x67, 0xa7, 0xec, + 0x85, 0x67, 0x0f, 0x6d, 0xac, 0xec, 0x8e, 0x35, 0x04, 0x06, 0x05, 0x25, + 0x10, 0x6d, 0xab, 0xed, 0x79, 0xe6, 0xae, 0xec, 0x01, 0x10, 0x79, 0xe6, + 0x80, 0xc6, 0x01, 0x4b, 0xff, 0x6e, 0xcc, 0xeb, 0x04, 0x5b, 0xeb, 0x61, + 0x36, 0xb2, 0xa0, 0xa2, 0x01, 0x75, 0x1e, 0x61, 0x35, 0xb4, 0x79, 0xa4, + 0x3e, 0x6f, 0x1d, 0x67, 0x6a, 0x32, 0xec, 0xea, 0xcc, 0xea, 0x03, 0x6e, + 0x48, 0x37, 0xcc, 0xeb, 0xed, 0xeb, 0x79, 0xc4, 0xf0, 0x80, 0x03, 0x57, + 0x0f, 0x60, 0xf1, 0x80, 0x03, 0x57, 0x0c, 0x60, 0xf2, 0x80, 0x03, 0x57, + 0x09, 0x60, 0xf3, 0x80, 0x03, 0x57, 0x06, 0x60, 0x01, 0x6f, 0x4d, 0xef, + 0xe8, 0x37, 0xcc, 0xeb, 0xed, 0xeb, 0x79, 0xc4, 0x00, 0x6a, 0x9d, 0x67, + 0x4d, 0xe4, 0x01, 0x75, 0x70, 0x83, 0x0b, 0x61, 0x23, 0xb4, 0x99, 0xa4, + 0x01, 0x6e, 0x8a, 0x34, 0xcc, 0xec, 0x05, 0x24, 0x02, 0x4b, 0x00, 0xf6, + 0x60, 0x33, 0x00, 0xf6, 0x63, 0x33, 0x07, 0x73, 0x01, 0x61, 0x06, 0x6b, + 0x01, 0x6c, 0x6c, 0xec, 0x04, 0x06, 0x03, 0x24, 0x59, 0xe6, 0x04, 0x6b, + 0x02, 0x10, 0x59, 0xe6, 0x05, 0x6b, 0x64, 0xc6, 0x01, 0x4a, 0xff, 0x6b, + 0x6c, 0xea, 0x04, 0x5a, 0xde, 0x61, 0x16, 0xb2, 0x40, 0x9a, 0x03, 0x6c, + 0x59, 0x6d, 0x40, 0xea, 0x01, 0x6e, 0x02, 0xf0, 0x00, 0x6f, 0xbd, 0x67, + 0xeb, 0xef, 0x4c, 0xef, 0x57, 0xa5, 0x76, 0xa5, 0x03, 0x6c, 0x40, 0x32, + 0x78, 0x33, 0x44, 0x32, 0x6d, 0xea, 0x74, 0xa5, 0x01, 0x6e, 0x6d, 0xea, + 0x75, 0xa5, 0x59, 0x6d, 0x6c, 0x33, 0x6d, 0xea, 0xe1, 0xf7, 0x1f, 0x6b, + 0x6c, 0xea, 0x4d, 0xef, 0x08, 0xb2, 0x60, 0x9a, 0xff, 0xf7, 0x1f, 0x6a, + 0x40, 0xeb, 0x4c, 0xef, 0x07, 0x97, 0x06, 0x90, 0x00, 0xef, 0x04, 0x63, + 0x5c, 0x3c, 0x12, 0x80, 0x2c, 0x0c, 0x12, 0x80, 0x44, 0x00, 0x12, 0x80, + 0x48, 0x00, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, 0x10, 0xb2, 0x80, 0xf1, + 0x94, 0xa2, 0x04, 0x6b, 0x8c, 0xeb, 0x08, 0x23, 0x80, 0xf1, 0x97, 0xa2, + 0x80, 0xf1, 0x76, 0xa2, 0x80, 0x34, 0x6d, 0xec, 0x01, 0x6b, 0x09, 0x10, + 0x0a, 0xb5, 0x41, 0xa5, 0x01, 0x6b, 0xff, 0x6c, 0x6c, 0xea, 0x8c, 0xea, + 0x00, 0x6c, 0x03, 0x22, 0x86, 0xad, 0x07, 0xb2, 0x60, 0xc2, 0x07, 0xb2, + 0x40, 0xea, 0x00, 0x65, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, + 0x18, 0x01, 0x12, 0x80, 0x7c, 0x0c, 0x12, 0x80, 0x5c, 0x3c, 0x12, 0x80, + 0xd5, 0x37, 0x10, 0x80, 0x0a, 0x6a, 0x5a, 0xed, 0x01, 0x2a, 0xe5, 0xe8, + 0x64, 0x6a, 0x12, 0xeb, 0x58, 0xec, 0x04, 0xf7, 0x10, 0x6c, 0x12, 0xea, + 0x3e, 0xf6, 0x1c, 0x4a, 0x58, 0xeb, 0x12, 0xeb, 0x9a, 0xeb, 0x01, 0x2c, + 0xe5, 0xe8, 0x04, 0xb3, 0xc0, 0xf1, 0xbc, 0xa3, 0x12, 0xea, 0x20, 0xe8, + 0xa9, 0xe2, 0x00, 0x65, 0x18, 0x01, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x04, 0xd0, 0x23, 0xb0, 0x23, 0xb2, 0xc0, 0xf1, 0x9c, 0xa0, 0x40, 0x9a, + 0x40, 0xea, 0x00, 0x65, 0x80, 0xf1, 0x74, 0xa0, 0x02, 0x6c, 0x6c, 0xec, + 0x04, 0x24, 0xa0, 0xf1, 0x63, 0xa0, 0xff, 0x73, 0x07, 0x61, 0x1b, 0xb3, + 0xc0, 0xf1, 0x7c, 0xa3, 0xff, 0xf7, 0x1f, 0x6c, 0x68, 0x33, 0x8c, 0xeb, + 0x19, 0xb4, 0x88, 0xa4, 0x98, 0xea, 0x12, 0xec, 0x58, 0xeb, 0x04, 0xf7, + 0x10, 0x6b, 0x12, 0xea, 0x4a, 0x32, 0x4b, 0xe4, 0x40, 0x32, 0x40, 0x32, + 0x43, 0x32, 0x43, 0x32, 0xe0, 0xf2, 0x15, 0x6c, 0x98, 0xea, 0x12, 0xea, + 0x01, 0xf0, 0x18, 0x4a, 0x7a, 0xea, 0x01, 0x2b, 0xe5, 0xe8, 0x12, 0xea, + 0x40, 0x32, 0x40, 0x32, 0x43, 0x32, 0x43, 0x32, 0x00, 0x52, 0x02, 0x61, + 0x32, 0x4a, 0x01, 0x10, 0xce, 0x4a, 0x64, 0x6b, 0x7a, 0xea, 0x01, 0x2b, + 0xe5, 0xe8, 0x05, 0x97, 0x04, 0x90, 0x12, 0xea, 0x00, 0xf6, 0x40, 0x32, + 0x00, 0xf6, 0x43, 0x32, 0x00, 0xef, 0x03, 0x63, 0x18, 0x01, 0x12, 0x80, + 0x7c, 0x00, 0x12, 0x80, 0x68, 0x0c, 0x12, 0x80, 0x0b, 0xb3, 0x80, 0xf1, + 0x94, 0xa3, 0x02, 0x6a, 0x8c, 0xea, 0x04, 0x22, 0x80, 0xf1, 0x55, 0x83, + 0x20, 0xe8, 0x00, 0x65, 0x07, 0xb4, 0x40, 0xa4, 0x40, 0x6b, 0x4c, 0xeb, + 0xff, 0x6a, 0x4c, 0xeb, 0x00, 0x6a, 0x01, 0x23, 0x4b, 0x84, 0x20, 0xe8, + 0x00, 0x65, 0x00, 0x65, 0x18, 0x01, 0x12, 0x80, 0x7c, 0x0c, 0x12, 0x80, + 0x0b, 0xb3, 0xab, 0xa3, 0x4c, 0xa3, 0x79, 0xa3, 0x01, 0x6e, 0x6a, 0x33, + 0xcc, 0xeb, 0x03, 0x23, 0x60, 0xa4, 0xfe, 0x4b, 0x60, 0xc4, 0x60, 0xa4, + 0x63, 0xed, 0x02, 0x60, 0x20, 0xe8, 0xa0, 0xc4, 0x43, 0xeb, 0x01, 0x60, + 0x40, 0xc4, 0x20, 0xe8, 0x00, 0x65, 0x00, 0x65, 0x2c, 0x0c, 0x12, 0x80, + 0x10, 0xb3, 0x11, 0xb2, 0x60, 0xda, 0x11, 0xb3, 0x11, 0xb2, 0x60, 0xda, + 0x11, 0xb3, 0x12, 0xb2, 0x60, 0xda, 0x12, 0xb3, 0x12, 0xb2, 0x60, 0xda, + 0x12, 0xb3, 0x13, 0xb2, 0x60, 0xda, 0x13, 0xb3, 0x13, 0xb2, 0x60, 0xda, + 0x13, 0xb3, 0x14, 0xb2, 0x60, 0xda, 0x14, 0xb3, 0x14, 0xb2, 0x60, 0xda, + 0x14, 0xb3, 0x15, 0xb2, 0x60, 0xda, 0x15, 0xb3, 0x15, 0xb2, 0x20, 0xe8, + 0x60, 0xda, 0x00, 0x65, 0x2d, 0x3e, 0x10, 0x80, 0x6c, 0x00, 0x12, 0x80, + 0x51, 0x3e, 0x10, 0x80, 0x58, 0x00, 0x12, 0x80, 0xdd, 0x3d, 0x10, 0x80, + 0x5c, 0x00, 0x12, 0x80, 0x61, 0x3c, 0x10, 0x80, 0xa8, 0x00, 0x12, 0x80, + 0x7d, 0x39, 0x10, 0x80, 0xb0, 0x00, 0x12, 0x80, 0x19, 0x3a, 0x10, 0x80, + 0x90, 0x00, 0x12, 0x80, 0x5d, 0x3b, 0x10, 0x80, 0x9c, 0x00, 0x12, 0x80, + 0x91, 0x3d, 0x10, 0x80, 0xc4, 0x00, 0x12, 0x80, 0x2d, 0x3b, 0x10, 0x80, + 0x94, 0x00, 0x12, 0x80, 0x4d, 0x3a, 0x10, 0x80, 0xa0, 0x00, 0x12, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x05, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x01, 0x6b, + 0x04, 0xb2, 0x60, 0xc2, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, + 0xa1, 0x96, 0x00, 0x80, 0x0a, 0x3c, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x09, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x09, 0xb2, 0x62, 0xa2, 0xff, 0x73, + 0x02, 0x61, 0x2a, 0x6b, 0x62, 0xc2, 0x06, 0xb2, 0x63, 0xa2, 0xff, 0x73, + 0x02, 0x61, 0x2a, 0x6b, 0x62, 0xc2, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, + 0x41, 0x98, 0x00, 0x80, 0x2c, 0x0c, 0x12, 0x80, 0xf7, 0x63, 0x11, 0x62, + 0x10, 0xd1, 0x0f, 0xd0, 0x39, 0xb2, 0x40, 0xa2, 0x00, 0xf6, 0x80, 0x31, + 0x00, 0xf6, 0x23, 0x31, 0x1a, 0x2a, 0x37, 0xb0, 0x37, 0xb3, 0x40, 0x9b, + 0x82, 0xa0, 0x00, 0x6d, 0xc5, 0x67, 0xf1, 0x67, 0x40, 0xea, 0x0c, 0xd3, + 0x0c, 0x93, 0x50, 0xc0, 0x84, 0xa0, 0x40, 0x9b, 0x00, 0x6d, 0xc5, 0x67, + 0x40, 0xea, 0xf1, 0x67, 0x0c, 0x93, 0x52, 0xc0, 0x85, 0xa0, 0x40, 0x9b, + 0x00, 0x6d, 0xc5, 0x67, 0x40, 0xea, 0xf1, 0x67, 0x53, 0xc0, 0x2c, 0xb2, + 0x40, 0xa2, 0x1a, 0x2a, 0x28, 0xb0, 0x29, 0xb3, 0x40, 0x9b, 0x83, 0xa0, + 0x00, 0x6d, 0xc5, 0x67, 0xf1, 0x67, 0x40, 0xea, 0x0c, 0xd3, 0x0c, 0x93, + 0x51, 0xc0, 0x86, 0xa0, 0x40, 0x9b, 0x00, 0x6d, 0xc5, 0x67, 0x40, 0xea, + 0xf1, 0x67, 0x0c, 0x93, 0x54, 0xc0, 0x87, 0xa0, 0x40, 0x9b, 0x00, 0x6d, + 0xc5, 0x67, 0x40, 0xea, 0xf1, 0x67, 0x55, 0xc0, 0x1b, 0xb0, 0x1c, 0xb3, + 0x40, 0x9b, 0x88, 0xa0, 0x00, 0x6d, 0xc5, 0x67, 0xf1, 0x67, 0x40, 0xea, + 0x0c, 0xd3, 0x0c, 0x93, 0x56, 0xc0, 0x89, 0xa0, 0x40, 0x9b, 0x00, 0x6d, + 0xc5, 0x67, 0x40, 0xea, 0xf1, 0x67, 0x79, 0xa0, 0x57, 0xc0, 0x02, 0x6a, + 0x6c, 0xea, 0x18, 0x22, 0x06, 0x6a, 0x04, 0xd2, 0x12, 0xb2, 0x05, 0xd2, + 0x50, 0xa0, 0x04, 0x6c, 0x06, 0xd2, 0x51, 0xa0, 0x60, 0xf2, 0x0f, 0x6e, + 0x29, 0xf6, 0x13, 0x6f, 0x07, 0xd2, 0x52, 0xa0, 0x08, 0xd2, 0x53, 0xa0, + 0x09, 0xd2, 0x54, 0xa0, 0x0a, 0xd2, 0x55, 0xa0, 0x0b, 0xd2, 0x0a, 0xb2, + 0x40, 0xea, 0xfd, 0x6d, 0x11, 0x97, 0x10, 0x91, 0x0f, 0x90, 0x00, 0xef, + 0x09, 0x63, 0x00, 0x65, 0x08, 0x3c, 0x12, 0x80, 0x2c, 0x0c, 0x12, 0x80, + 0x98, 0x00, 0x12, 0x80, 0x09, 0x3c, 0x12, 0x80, 0xc4, 0x3e, 0x10, 0x80, + 0x4d, 0x26, 0x01, 0x80, 0xf7, 0x63, 0x11, 0x62, 0x10, 0xd1, 0x0f, 0xd0, + 0x00, 0xf6, 0x80, 0x31, 0x38, 0xb4, 0x79, 0xa4, 0x02, 0x6a, 0x00, 0xf6, + 0x23, 0x31, 0x6c, 0xea, 0x1f, 0x22, 0x36, 0xb2, 0x08, 0xa2, 0x36, 0xb2, + 0xc0, 0xf1, 0x7c, 0xa2, 0xa1, 0x84, 0x35, 0xb2, 0x40, 0x9a, 0x02, 0x6c, + 0x0d, 0xd3, 0x40, 0xea, 0x0c, 0xd5, 0x0c, 0x95, 0x0d, 0x93, 0x05, 0x6c, + 0x04, 0xd4, 0x31, 0xb4, 0x05, 0xd4, 0x09, 0xd5, 0x0a, 0xd2, 0x06, 0xd0, + 0x07, 0xd3, 0x08, 0xd1, 0x01, 0x6c, 0xa0, 0xf1, 0x14, 0x6e, 0x29, 0xf6, + 0x12, 0x6f, 0x2c, 0xb2, 0x40, 0xea, 0xfd, 0x6d, 0x25, 0xb0, 0x4f, 0x80, + 0x2e, 0xea, 0x40, 0x22, 0x29, 0xb2, 0x40, 0x9a, 0x40, 0xea, 0x2f, 0xc0, + 0x28, 0xb2, 0x40, 0x9a, 0x40, 0xea, 0x91, 0x67, 0x27, 0xb2, 0x40, 0x9a, + 0x40, 0xea, 0x00, 0x65, 0x51, 0xa0, 0x70, 0xa0, 0x40, 0x32, 0x6d, 0xea, + 0x24, 0xb3, 0x40, 0xcb, 0x47, 0xa0, 0x66, 0xa0, 0x40, 0x32, 0x6d, 0xea, + 0x22, 0xb3, 0x40, 0xcb, 0x45, 0xa0, 0x64, 0xa0, 0x40, 0x32, 0x6d, 0xea, + 0x20, 0xb3, 0x40, 0xcb, 0x20, 0xb2, 0x40, 0xf1, 0x04, 0x9a, 0x0f, 0x10, + 0x63, 0xa0, 0x01, 0x6a, 0x6c, 0xea, 0x09, 0x22, 0x1d, 0xb2, 0x40, 0x9a, + 0x40, 0xea, 0x82, 0xa0, 0x1c, 0xb3, 0x60, 0x9b, 0x82, 0xa0, 0x40, 0xeb, + 0xa2, 0x67, 0x00, 0xf1, 0x14, 0x48, 0x1a, 0xb2, 0x60, 0x9a, 0x1a, 0xb2, + 0x40, 0x9a, 0x49, 0xe3, 0xff, 0x6b, 0x15, 0x4b, 0x78, 0xea, 0x13, 0xb3, + 0x40, 0xf1, 0x64, 0x9b, 0x12, 0xea, 0x49, 0xe3, 0x43, 0xe8, 0xe2, 0x61, + 0x11, 0x97, 0x10, 0x91, 0x0f, 0x90, 0x00, 0xef, 0x09, 0x63, 0x00, 0x65, + 0x2c, 0x0c, 0x12, 0x80, 0x68, 0x0c, 0x12, 0x80, 0x18, 0x01, 0x12, 0x80, + 0x3c, 0x00, 0x12, 0x80, 0xc4, 0x3e, 0x10, 0x80, 0x4d, 0x26, 0x01, 0x80, + 0x94, 0x00, 0x12, 0x80, 0x9c, 0x00, 0x12, 0x80, 0xa4, 0x00, 0x12, 0x80, + 0xe8, 0x10, 0x00, 0xb6, 0xea, 0x10, 0x00, 0xb6, 0xf0, 0x10, 0x00, 0xb6, + 0x80, 0x22, 0x12, 0x80, 0xb8, 0x00, 0x12, 0x80, 0xc4, 0x00, 0x12, 0x80, + 0xa8, 0x03, 0x12, 0x80, 0xa4, 0x03, 0x12, 0x80, 0xfb, 0x63, 0x09, 0x62, + 0xff, 0x6a, 0x4c, 0xec, 0x4c, 0xed, 0x0d, 0xb2, 0x89, 0xe2, 0x40, 0xa2, + 0x0f, 0x22, 0x02, 0x6a, 0x04, 0xd2, 0x0b, 0xb2, 0x05, 0xd2, 0x06, 0xd4, + 0x07, 0xd5, 0x02, 0x6c, 0x60, 0xf2, 0x1a, 0x6e, 0x49, 0xf6, 0x16, 0x6f, + 0x07, 0xb2, 0x40, 0xea, 0xfd, 0x6d, 0x03, 0x10, 0x06, 0xb2, 0x40, 0xea, + 0x00, 0x65, 0x09, 0x97, 0x00, 0xef, 0x05, 0x63, 0x00, 0x3c, 0x12, 0x80, + 0xc4, 0x3e, 0x10, 0x80, 0x4d, 0x26, 0x01, 0x80, 0xe1, 0x9a, 0x00, 0x80, + 0xfd, 0x63, 0x05, 0x62, 0x0d, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x0d, 0xb2, + 0x04, 0x6b, 0x65, 0xca, 0x61, 0xf4, 0x01, 0x6b, 0x66, 0xca, 0x21, 0x6b, + 0x0a, 0xb2, 0xe0, 0xf1, 0x63, 0xc2, 0x0a, 0xb2, 0x0a, 0xb3, 0x60, 0xda, + 0x48, 0x6b, 0x62, 0xca, 0x09, 0xb3, 0x66, 0xda, 0x18, 0x6b, 0x6e, 0xca, + 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, 0x8d, 0x9d, 0x00, 0x80, + 0x68, 0x0c, 0x12, 0x80, 0x18, 0x01, 0x12, 0x80, 0x48, 0x0c, 0x12, 0x80, + 0x1c, 0x3f, 0x10, 0x80, 0xec, 0x3e, 0x10, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x06, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x6c, 0x6b, 0x6b, 0xeb, 0x05, 0xb2, + 0x20, 0xf1, 0x71, 0xc2, 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, + 0x05, 0x96, 0x00, 0x80, 0x18, 0x01, 0x12, 0x80, 0xfd, 0x63, 0x05, 0x62, + 0x05, 0xb2, 0x40, 0xea, 0x00, 0x65, 0x05, 0xb2, 0x40, 0xea, 0x00, 0x65, + 0x05, 0x97, 0x00, 0xef, 0x03, 0x63, 0x00, 0x65, 0x81, 0x96, 0x00, 0x80, + 0xf5, 0x38, 0x10, 0x80, 0xfc, 0x63, 0x07, 0x62, 0x06, 0xd1, 0x05, 0xd0, + 0xff, 0x6a, 0x24, 0x67, 0x4c, 0xe9, 0x67, 0x41, 0x4b, 0x4b, 0x0e, 0xb4, + 0x68, 0x33, 0x6d, 0xe4, 0x00, 0x9b, 0x04, 0x6b, 0x85, 0xa0, 0x8c, 0xeb, + 0x4c, 0xeb, 0x0b, 0x23, 0x0a, 0xb2, 0x40, 0x9a, 0x02, 0x6c, 0x78, 0x6d, + 0x40, 0xea, 0x01, 0x6e, 0x40, 0xf0, 0x5c, 0xc8, 0x07, 0xb2, 0x40, 0xea, + 0x91, 0x67, 0x07, 0x97, 0x06, 0x91, 0x05, 0x90, 0x00, 0x6a, 0x00, 0xef, + 0x04, 0x63, 0x00, 0x65, 0x80, 0x22, 0x12, 0x80, 0x44, 0x00, 0x12, 0x80, + 0xe9, 0xce, 0x01, 0x80, 0x41, 0x00, 0x00, 0x00, 0x07, 0x00, 0xf8, 0x03, + 0x00, 0xe0, 0x07, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xad, 0x35, 0x10, 0x80, + 0x65, 0x34, 0x10, 0x80, 0x69, 0x34, 0x10, 0x80, 0xdd, 0x34, 0x10, 0x80, + 0x6d, 0x34, 0x10, 0x80, 0x71, 0x34, 0x10, 0x80, 0x00, 0xf0, 0x20, 0x00, + 0x00, 0x90, 0x4f, 0x03, 0x00, 0xf0, 0x20, 0x00, 0x00, 0x90, 0x6f, 0x03, + 0x00, 0xf0, 0x08, 0x00, 0x02, 0x90, 0x17, 0xf8, 0x34, 0x00, 0x03, 0x10, + 0x36, 0x00, 0x04, 0xe2, 0x38, 0x00, 0x01, 0x31, 0x3a, 0x00, 0xe0, 0x05, + 0x64, 0x00, 0x40, 0x2e, 0x1a, 0x01, 0x16, 0x36, 0x42, 0x02, 0xff, 0x04, + 0x44, 0x02, 0x33, 0x64, 0x16, 0x03, 0x53, 0x76, 0x14, 0x03, 0x00, 0x00, + 0x74, 0x03, 0x86, 0x06, 0x72, 0x03, 0xd1, 0x04, 0x70, 0x03, 0x57, 0x04, + 0x6e, 0x03, 0xde, 0x03, 0x6c, 0x03, 0x6b, 0x03, 0x6a, 0x03, 0x3f, 0x00, + 0x68, 0x03, 0x3f, 0x00, 0x66, 0x03, 0x3f, 0x00, 0x16, 0x00, 0xbe, 0xa6, + 0x40, 0x03, 0x8a, 0x03, 0x3a, 0x02, 0xa6, 0x00, 0x3c, 0x02, 0x7e, 0xc0, + 0x60, 0x02, 0x36, 0x21, 0x62, 0x02, 0xce, 0x17, 0x08, 0x03, 0x29, 0x29, + 0x42, 0x03, 0x01, 0x09, 0x56, 0x03, 0x0d, 0x33, 0x5a, 0x03, 0x45, 0x00, + 0x30, 0x06, 0x26, 0x67, 0x32, 0x06, 0x12, 0x5d, 0x34, 0x06, 0x7f, 0xe8, + 0x36, 0x06, 0xc8, 0x36, 0x34, 0x01, 0x00, 0x00, 0x64, 0x01, 0x44, 0x3b, + 0x66, 0x01, 0xd2, 0x76, 0x08, 0x00, 0xb0, 0x00, 0x66, 0x00, 0x59, 0x40, + 0x0a, 0x06, 0xdb, 0x50, 0x0c, 0x06, 0xf2, 0x7b, 0x10, 0x06, 0x8c, 0x55, + 0x12, 0x06, 0x0a, 0x28, 0x14, 0x06, 0x27, 0x01, 0x02, 0x02, 0x6a, 0x7c, + 0x6d, 0x61, 0x00, 0x00, 0xa4, 0x54, 0xa8, 0x42 +}; + +unsigned int rtl_vendor_command_size = sizeof(rtl_vendor_command); +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ diff --git a/arch/arm/src/rtl8720c/amebaz_hci_board.c b/arch/arm/src/rtl8720c/amebaz_hci_board.c new file mode 100644 index 00000000000..0015c4df843 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_hci_board.c @@ -0,0 +1,832 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_hci_board.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include "amebaz_hci_board.h" +#include "ameba_efuse.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BT_LGC_EFUSE_LEN 0x20 +#define BT_PHY_EFUSE_LEN 0x12 +#define BT_PHY_EFUSE_BASE 0x100 +#define BT_LGC_EFUSE_OFFSET 0x190 +#define BT_MAC_ADDR_LEN 6 +#define BT_CONFIG_SIGNATURE 0x8723ab55 +#define BT_CONFIG_HEADER_LEN 6 +#define EFUSE_SW_USE_FLASH_PATCH BIT0 +#define EFUSE_SW_BT_FW_LOG BIT1 +#define EFUSE_SW_RSVD BIT2 +#define EFUSE_SW_IQK_HCI_OUT BIT3 +#define EFUSE_SW_UPPERSTACK_SWITCH BIT4 +#define EFUSE_SW_TRACE_SWITCH BIT5 +#define EFUSE_SW_DRIVER_DEBUG_LOG BIT6 +#define EFUSE_SW_RSVD2 BIT7 +#define LEFUSE(x) (x-0x190) +#define FLASH_BT_PARA_ADDR (SYS_DATA_FLASH_BASE + 0xff0) +#define CHECK_SW(x) (HAL_READ32(SPI_FLASH_BASE, FLASH_BT_PARA_ADDR) &x) +#define MERGE_PATCH_ADDRESS 0x110000 +#define LE_ARRAY_TO_UINT16(u16, a) { \ + u16 = ((uint16_t)(*(a + 0)) << 0) + \ + ((uint16_t)(*(a + 1)) << 8); \ + } + +#define LE_ARRAY_TO_UINT32(u32, a) { \ + u32 = ((uint32_t)(*(a + 0)) << 0)+ \ + ((uint32_t)(*(a + 1)) << 8)+ \ + ((uint32_t)(*(a + 2)) << 16)+ \ + ((uint32_t)(*(a + 3)) << 24); \ + } + +#define LE_UINT32_TO_ARRAY(a, u32) { \ + *((uint8_t *)(a) + 0) = (uint8_t)((u32) >> 0); \ + *((uint8_t *)(a) + 1) = (uint8_t)((u32) >> 8); \ + *((uint8_t *)(a) + 2) = (uint8_t)((u32) >> 16); \ + *((uint8_t *)(a) + 3) = (uint8_t)((u32) >> 24); \ + } + +#define LE_STREAM_TO_UINT8(u8, s) { \ + u8 = (uint8_t)(*s); \ + s += 1; \ +} + +#define LE_STREAM_TO_UINT16(u16, s) { \ + u16 = ((uint16_t)(*(s + 0)) << 0) + \ + ((uint16_t)(*(s + 1)) << 8); \ + s += 2; \ +} + +#define LE_UINT16_TO_STREAM(s, u16) { \ + *s++ = (uint8_t)((u16) >> 0); \ + *s++ = (uint8_t)((u16) >> 8); \ +} + +#define LE_STREAM_TO_UINT32(u32, s) { \ + u32 = ((uint32_t)(*(s + 0)) << 0) + \ + ((uint32_t)(*(s + 1)) << 8) + \ + ((uint32_t)(*(s + 2)) << 16) + \ + ((uint32_t)(*(s + 3)) << 24); \ + s += 4; \ +} + +enum _RT_DEV_LOCK_E +{ + RT_DEV_LOCK_EFUSE = 0, + RT_DEV_LOCK_FLASH = 1, + RT_DEV_LOCK_CRYPTO = 2, + RT_DEV_LOCK_PTA = 3, + RT_DEV_LOCK_WLAN = 4, + RT_DEV_LOCK_MAX = 5 +}; + +typedef struct +{ + uint32_t IQK_XX; + uint32_t IQK_YY; + uint16_t IDAC; + uint16_t QDAC; + uint16_t IDAC2; + uint16_t QDAC2; +} IQK_T; + +extern void rtw_msleep_os(int ms); +extern void rtw_mfree(uint8_t *pbuf, uint32_t n); +extern void device_mutex_lock(uint32_t device); +extern void device_mutex_unlock(uint32_t device); +extern uint32_t bt_lok_write(uint16_t idac, + uint16_t qdac, uint16_t idac2, uint16_t qdac2); +extern uint32_t bt_dck_write(uint8_t q_dck, uint8_t i_dck); +extern uint32_t bt_iqk_8710c(IQK_T *cal_data, uint8_t store); +extern uint32_t bt_flatk_8710c(uint16_t txgain_flatk); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t hci_phy_efuse[BT_PHY_EFUSE_LEN] = +{ + 0 +}; + +static uint8_t hci_lgc_efuse[BT_LGC_EFUSE_LEN] = +{ + 0 +}; + +static IQK_T hci_iqk_data = +{ + 0x100, + 0x00, + 0x20, + 0x20, + 0x20, + 0x20 +}; + +static uint8_t *rtl_actual_command = NULL; +static uint32_t rtl_actual_command_size; +extern const uint8_t rtl_vendor_command[]; +extern uint32_t rtl_vendor_command_size; +static uint32_t hci_cfg_baudrate; +static uint8_t rtl_vendor_init_config[] = +{ + 0x55, 0xab, 0x23, 0x87, /* header */ + + 0x32, 0x00, /* Config length: header + len + preload */ + + 0x30, 0x00, 0x06, 0x99, 0x88, 0x77, 0x44, 0x55, 0x66, /* BT MAC address */ + + 0x0c, 0x00, 0x04, 0x04, 0x50, 0xf7, 0x05, /* Baudrate 921600 */ + + 0x18, 0x00, 0x01, 0x5c, /* flow control */ + + 0x94, 0x01, 0x06, 0x0a, 0x08, 0x00, 0x00, 0x2e, 0x07, /* phy flatk */ + + 0x9f, 0x01, 0x05, 0x2a, 0x2a, 0x2a, 0x2a, 0x1c, /* unknow 1 */ + + 0xa4, 0x01, 0x04, 0xfe, 0xfe, 0xfe, 0xfe, /* unknow 2 */ +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +static uint32_t cal_bit_shift(uint32_t mask) +{ + uint32_t i; + for (i = 0; i < 31; i++) + { + if ((mask >> i) & 0x1) + { + break; + } + } + + return i; +} + +static void set_reg_val(uint32_t reg, uint32_t mask, uint32_t val) +{ + if (reg % 4) + { + return; + } + + uint32_t data = HAL_READ32(reg, 0); + data = ((data & (~mask)) | (val << cal_bit_shift(mask))); + HAL_WRITE32(reg, 0, data); +} + +static int hci_iqk_phy_efuse_valid(FAR IQK_T *iqk_data) +{ + if ((hci_phy_efuse[3] == 0xff) && + (hci_phy_efuse[4] == 0xff) && + (hci_phy_efuse[5] == 0xff) && + (hci_phy_efuse[6] == 0xff)) + { + /* No Phy Efuse Data */ + + return -EIO; + } + + else + { + /* Phy Efuse Has Data */ + + iqk_data->IQK_XX = hci_phy_efuse[3] | hci_phy_efuse[4] << 8; + iqk_data->IQK_YY = hci_phy_efuse[5] | hci_phy_efuse[6] << 8; + iqk_data->QDAC = hci_phy_efuse[0x0c]; + iqk_data->IDAC = hci_phy_efuse[0x0d]; + iqk_data->QDAC2 = hci_phy_efuse[0x0e]; + iqk_data->IDAC2 = hci_phy_efuse[0x0f]; + return 0; + } +} + +static int hci_iqk_lgc_efuse_valid(FAR IQK_T *iqk_data) +{ + if ((hci_lgc_efuse[0x16] == 0xff) && + (hci_lgc_efuse[0x17] == 0xff) && + (hci_lgc_efuse[0x18] == 0xff) && + (hci_lgc_efuse[0x19] == 0xff)) + { + /* No Lgc Efuse Data */ + + return -EIO; + } + else + { + /* Lgc Efuse Has Data */ + + iqk_data->IQK_XX = (uint32_t)(((uint32_t)hci_lgc_efuse[0x17]) << 8) | + hci_lgc_efuse[0x16]; + iqk_data->IQK_YY = (uint32_t)(((uint32_t)hci_lgc_efuse[0x19]) << 8) | + hci_lgc_efuse[0x18]; + iqk_data->QDAC = hci_lgc_efuse[0x1a]; + iqk_data->IDAC = hci_lgc_efuse[0x1b]; + iqk_data->QDAC2 = hci_lgc_efuse[0x1c]; + iqk_data->IDAC2 = hci_lgc_efuse[0x1d]; + return 0; + } +} + +int hci_check_iqk(void) +{ + IQK_T iqk_data; + + if (!hci_lgc_efuse[LEFUSE(0x1a1)] & BIT0) + { + /* Use Fix Logic Efuse */ + + if (0 == hci_iqk_lgc_efuse_valid(&iqk_data)) + { + bt_lok_write(iqk_data.IDAC, iqk_data.QDAC, iqk_data.IDAC2, + iqk_data.QDAC2); + hci_phy_efuse[0] = 0; + hci_phy_efuse[1] = hci_phy_efuse[1] & (~BIT0); + hci_phy_efuse[3] = iqk_data.IQK_XX & 0xff; + hci_phy_efuse[4] = (iqk_data.IQK_XX >> 8) & 0xff; + hci_phy_efuse[5] = iqk_data.IQK_YY & 0xff; + hci_phy_efuse[6] = (iqk_data.IQK_YY >> 8) & 0xff; + return 0; + } + + /* No Logic Efuse Data */ + + return -EIO; + } + + if (0 == hci_iqk_phy_efuse_valid(&iqk_data)) + { + if (hci_phy_efuse[0] != 0) + { + bt_dck_write(hci_phy_efuse[0x0e], hci_phy_efuse[0x0f]); + } + + bt_lok_write(iqk_data.IDAC, iqk_data.QDAC, iqk_data.IDAC2, + iqk_data.QDAC2); + return 0; + } + + else if (0 == hci_iqk_lgc_efuse_valid(&iqk_data)) + { + bt_lok_write(iqk_data.IDAC, iqk_data.QDAC, iqk_data.IDAC2, + iqk_data.QDAC2); + hci_phy_efuse[0] = 0; + hci_phy_efuse[1] = hci_phy_efuse[1] & (~BIT0); + hci_phy_efuse[3] = iqk_data.IQK_XX & 0xff; + hci_phy_efuse[4] = (iqk_data.IQK_XX >> 8) & 0xff; + hci_phy_efuse[5] = iqk_data.IQK_YY & 0xff; + hci_phy_efuse[6] = (iqk_data.IQK_YY >> 8) & 0xff; + hci_phy_efuse[0x0e] = hci_lgc_efuse[0x1e]; + hci_phy_efuse[0x0f] = hci_lgc_efuse[0x1f]; + bt_dck_write(hci_phy_efuse[0x0e], hci_phy_efuse[0x0f]); + return 0; + } + + else + { + /* No IQK LOK Data, Need Start LOK */ + + return -EIO; + } +} + +int hci_start_iqk(void) +{ + if (_FAIL == bt_iqk_8710c(&hci_iqk_data, 0)) + { + /* IQK Fail, Ensure Connected */ + + return -EIO; + } + + bt_lok_write(hci_iqk_data.IDAC, hci_iqk_data.QDAC, hci_iqk_data.IDAC2, + hci_iqk_data.QDAC2); + hci_phy_efuse[0] = 0; + hci_phy_efuse[1] = hci_phy_efuse[1] & (~BIT0); + hci_phy_efuse[3] = hci_iqk_data.IQK_XX & 0xff; + hci_phy_efuse[4] = (hci_iqk_data.IQK_XX >> 8) & 0xff; + hci_phy_efuse[5] = hci_iqk_data.IQK_YY & 0xff; + hci_phy_efuse[6] = (hci_iqk_data.IQK_YY >> 8) & 0xff; + return 0; +} + +int hci_set_init_config_mac(FAR uint8_t *addr, uint8_t diffvalue) +{ + for (uint8_t i = 0; i < BT_MAC_ADDR_LEN; i++) + { + rtl_vendor_init_config[9 + i] = addr[(BT_MAC_ADDR_LEN - 1) - i]; + } + + rtl_vendor_init_config[9] -= diffvalue; + return 0; +} + +int hci_get_baudrate(FAR uint32_t *bt_baudrate, FAR uint32_t *uart_baudrate) +{ + typedef struct + { + uint32_t bt_baudrate; + uint32_t uart_baudrate; + }baudrate_map; + + const baudrate_map maps[] = + { + {0x0000701d, 115200}, + {0x0252c00a, 230400}, + {0x05f75004, 921600}, + {0x00005004, 1000000}, + {0x04928002, 1500000}, + {0x00005002, 2000000}, + {0x0000b001, 2500000}, + {0x04928001, 3000000}, + {0x052a6001, 3500000}, + {0x00005001, 4000000}, + }; + + uint32_t i; + *bt_baudrate = hci_cfg_baudrate; + for (i = 0; i < sizeof(maps); i++) + { + if (*bt_baudrate == maps[i].bt_baudrate) + { + break; + } + } + + if (i == sizeof(maps)) + { + return -EINVAL; + } + + *uart_baudrate = maps[i].uart_baudrate; + return 0; +} + +int hci_find_fw_patch(uint8_t chipid) +{ +#if 0 + const uint8_t single_patch_signature[4] = + { + 0xfd, + 0x63, + 0x05, + 0x62 + }; + + const uint8_t merged_patch_signature[8] = + { + 0x52, + 0x65, + 0x61, + 0x6c, + 0x74, + 0x65, + 0x63, + 0x68 + }; + + phal_spic_adaptor_t flash; + + /* FIXME: Distiguish Normal and MP Ptach (rltk_bt_get_patch_code) */ + + const uint8_t *fw_patch = rtl_vendor_command; + uint32_t fw_patch_len = rtl_vendor_command_size; + uint32_t fw_patch_offset = 0; + uint32_t lmp_subversion = 0; + uint16_t num_of_patch = 0; + uint16_t chipid_in_fw = 0; + uint8_t i; + if (!CHECK_SW(EFUSE_SW_USE_FLASH_PATCH)) + { + /* Check flash img */ + + uint8_t tmp_patch_head[8]; + hal_flash_stream_read(&flash, MERGE_PATCH_ADDRESS, 8, tmp_patch_head); + if (!memcmp(tmp_patch_head, merged_patch_signature, + sizeof(merged_patch_signature))) + { + /* use the changed patch */ + + hal_flash_stream_read(&flash, MERGE_PATCH_ADDRESS + 8, 4, + (uint8_t *)&lmp_subversion); + hal_flash_stream_read(&flash, MERGE_PATCH_ADDRESS + 12, 2, + (uint8_t *)&num_of_patch); + for (i = 0 ; i < num_of_patch; i++) + { + hal_flash_stream_read(&flash, + MERGE_PATCH_ADDRESS + 0x0e + 2 * i, 2, + (uint8_t *)&chipid_in_fw); + if (chipid_in_fw == chipid) + { + hal_flash_stream_read(&flash, + MERGE_PATCH_ADDRESS + 0x0e \ + + 2 * num_of_patch + 2 * i, + 2, (uint8_t *)&fw_patch_len); + hal_flash_stream_read(&flash, + MERGE_PATCH_ADDRESS + 0x0e \ + + 4 * num_of_patch + 4 * i, + 4, (uint8_t *)&fw_patch_offset); + break; + } + } + + rtl_actual_command = (uint8_t *)rtw_zmalloc(fw_patch_len); + if (!rtl_actual_command) + { + return -EIO; + } + + hal_flash_stream_read(&flash, + MERGE_PATCH_ADDRESS + fw_patch_offset, + fw_patch_len, rtl_actual_command); + LE_UINT32_TO_ARRAY(rtl_actual_command + fw_patch_len - 4, + lmp_subversion); + return 0; + } + } + + if (!memcmp(fw_patch, single_patch_signature, + sizeof(single_patch_signature))) + { + /* Use Single Patch, Do Nothing */ + + rtl_actual_command = fw_patch; + rtl_actual_command_size = fw_patch_len; + } + + else if (!memcmp(fw_patch, merged_patch_signature, + sizeof(merged_patch_signature))) + { + /* Use Merged Patch */ + + LE_ARRAY_TO_UINT32(lmp_subversion, fw_patch + 0x08); + LE_ARRAY_TO_UINT16(num_of_patch, fw_patch + 0x0c); + for (i = 0; i < num_of_patch; i++) + { + LE_ARRAY_TO_UINT16(chipid_in_fw, fw_patch + 0x0e + 2 * i); + if (chipid_in_fw == chipid) + { + LE_ARRAY_TO_UINT16(fw_patch_len, + fw_patch + 0x0e + 2 * num_of_patch + 2 * i); + LE_ARRAY_TO_UINT32(fw_patch_offset, + fw_patch + 0x0e + 4 * num_of_patch + 4 * i); + break; + } + } + + if (i >= num_of_patch) + { + /* No Match Patch Found */ + + return -EIO; + } + + else + { + rtl_actual_command = (uint8_t *)rtw_zmalloc(fw_patch_len); + rtl_actual_command_size = fw_patch_len; + if (!rtl_actual_command) + { + /* Malloc rtl_actual_command failed */ + + return -EIO; + } + + else + { + rtw_memcpy(rtl_actual_command, fw_patch + fw_patch_offset, + fw_patch_len); + LE_UINT32_TO_ARRAY(rtl_actual_command + fw_patch_len - 4, + lmp_subversion); + } + } + } + + else + { + /* Something is Wrong with the Patch */ + + return -EIO; + } + +#else + + /* FIXME: Dummy Here */ + + rtl_actual_command = (uint8_t *)&rtl_vendor_command[0]; + rtl_actual_command_size = rtl_vendor_command_size; +#endif + return 0; +} + +int hci_fetch_command(FAR uint8_t *command) +{ + unsigned int config_size = sizeof(rtl_vendor_init_config); + static unsigned int command_offset; + int fragment_size = 0; + int index; + if (command_offset >= config_size + rtl_actual_command_size) + { + if (rtl_actual_command && rtl_actual_command != rtl_vendor_command) + { + rtw_mfree(rtl_actual_command, rtl_actual_command_size); + } + + return AMEBAZ_COMMAND_DONE; + } + + if (command_offset < rtl_actual_command_size) + { + if (command_offset + AMEBAZ_COMMAND_FRAGMENT_SIZE + > rtl_actual_command_size) + { + fragment_size = rtl_actual_command_size - command_offset; + } + + else + { + fragment_size = AMEBAZ_COMMAND_FRAGMENT_SIZE; + } + + memcpy(command + 5, rtl_actual_command + command_offset, + fragment_size); + command_offset += fragment_size; + } + + if (command_offset >= rtl_actual_command_size) + { + int config_offset = command_offset - rtl_actual_command_size; + int config_len = config_size - config_offset; + if (fragment_size < AMEBAZ_COMMAND_FRAGMENT_SIZE) + { + int free = AMEBAZ_COMMAND_FRAGMENT_SIZE - fragment_size; + int copy_size; + if (config_len > free) + { + copy_size = free; + } + + else + { + copy_size = config_len; + } + + memcpy(command + 5 + fragment_size, + rtl_vendor_init_config + config_offset, copy_size); + command_offset += copy_size; + fragment_size += copy_size; + } + } + + index = (command_offset / AMEBAZ_COMMAND_FRAGMENT_SIZE) - 1; + if (command_offset % AMEBAZ_COMMAND_FRAGMENT_SIZE > 0) + { + index++; + } + + if (command_offset >= config_size + rtl_actual_command_size) + { + index |= 0x80; + } + + command[3] = fragment_size + 1; + command[4] = index; + return AMEBAZ_COMMAND_VALID; +} + +int hci_get_efuse_iqk_data(uint8_t *data) +{ + data[0] = 0x0c; + uint8_t *iqk_data = data + 1; + memcpy(iqk_data, hci_phy_efuse, data[0]); + return 0; +} + +static void hci_read_efuse(void) +{ + uint16_t bt_phy_efuse_base = 0x100; + device_mutex_lock(RT_DEV_LOCK_EFUSE); + + /* Read Phy Efuse */ + + for (int i = 0; i < 16; i++) + { + hal_efuse_read(bt_phy_efuse_base + i, hci_phy_efuse + i, + LDO_OUT_DEFAULT_VOLT); + } + + hal_efuse_read(0xf8, hci_phy_efuse + 16, LDO_OUT_DEFAULT_VOLT); + hal_efuse_read(0xf9, hci_phy_efuse + 17, LDO_OUT_DEFAULT_VOLT); + + /* Read Logic Efuse */ + + ameba_efuse_logical_read(BT_LGC_EFUSE_OFFSET, BT_LGC_EFUSE_LEN, + hci_lgc_efuse); + + device_mutex_unlock(RT_DEV_LOCK_EFUSE); +} + +static int hci_parse_config(void) +{ + uint32_t signature; + uint16_t payload_len; + uint16_t entry_offset; + uint16_t entry_len; + uint8_t *p_entry; + uint8_t *p; + uint8_t *p_len; + uint8_t i; + uint16_t tx_flatk; + p = rtl_vendor_init_config; + p_len = rtl_vendor_init_config + 4; + LE_STREAM_TO_UINT32(signature, p); + LE_STREAM_TO_UINT16(payload_len, p); + if (signature != BT_CONFIG_SIGNATURE) + { + /* Invalid Signature */ + + return -EIO; + } + + if (payload_len != sizeof(rtl_vendor_init_config) - BT_CONFIG_HEADER_LEN) + { + /* Fix the len, just avoid the length is not corect */ + + LE_UINT16_TO_STREAM(p_len, + sizeof(rtl_vendor_init_config) - BT_CONFIG_HEADER_LEN); + } + + p_entry = rtl_vendor_init_config + BT_CONFIG_HEADER_LEN; + while (p_entry < rtl_vendor_init_config + sizeof(rtl_vendor_init_config)) + { + p = p_entry; + LE_STREAM_TO_UINT16(entry_offset, p); + LE_STREAM_TO_UINT8(entry_len, p); + p_entry = p + entry_len; + switch (entry_offset) + { + case 0x000c: + + /* FIXME: MP (If use mp, Set badurate 115200 + * in rtl_vendor_init_config) + */ + + LE_STREAM_TO_UINT32(hci_cfg_baudrate, p); + break; + case 0x0018: + + /* FIXME: MP (If use mp, Clear flowctl in rtl_vendor_init_config) */ + + break; + case 0x0030: + + /* FIXME: Customer use Wi-Fi MAC - 1 as BT ADDR, + * so ignore action here + */ + +#if 0 + if (entry_len == 6) + { + if ((hci_lgc_efuse[0] != 0xff) && (hci_lgc_efuse[1] != 0xff)) + { + for (uint8_t i = 0 ; i < 6; i++) + { + p[i] = hci_lgc_efuse[5 - i]; + } + } + } + +#endif + break; + case 0x194: + if (hci_lgc_efuse[LEFUSE(0x196)] == 0xff) + { + if (!(hci_phy_efuse[2] & BIT0)) + { + tx_flatk = hci_phy_efuse[0xa] | hci_phy_efuse[0xb] << 8; + bt_flatk_8710c(tx_flatk); + } + + break; + } + + else + { + p[0] = hci_lgc_efuse[LEFUSE(0x196)]; + if (hci_lgc_efuse[LEFUSE(0x196)] & BIT1) + { + p[1] = hci_lgc_efuse[LEFUSE(0x197)]; + } + + if (hci_lgc_efuse[LEFUSE(0x196)] & BIT2) + { + p[2] = hci_lgc_efuse[LEFUSE(0x198)]; + p[3] = hci_lgc_efuse[LEFUSE(0x199)]; + tx_flatk = hci_lgc_efuse[LEFUSE(0x198)] + | hci_lgc_efuse[LEFUSE(0x199)] << 8; + bt_flatk_8710c(tx_flatk); + } + + else + { + if (!(hci_phy_efuse[2] & BIT0)) + { + tx_flatk = hci_phy_efuse[0xa] + | hci_phy_efuse[0xb] << 8; + bt_flatk_8710c(tx_flatk); + } + } + + if (hci_lgc_efuse[LEFUSE(0x196)] & BIT5) + { + p[4] = hci_lgc_efuse[LEFUSE(0x19a)]; + p[5] = hci_lgc_efuse[LEFUSE(0x19b)]; + } + } + + break; + case 0x19f: + for (i = 0; i < entry_len; i ++) + { + if (hci_lgc_efuse[LEFUSE(0x19c + i)] != 0xff) + { + p[i] = hci_lgc_efuse[LEFUSE(0x19c + i)]; + } + } + + break; + case 0x1a4: + for (i = 0; i < entry_len; i ++) + { + if (hci_lgc_efuse[LEFUSE(0x1a2 + i)] != 0xff) + { + p[i] = hci_lgc_efuse[LEFUSE(0x1a2 + i)]; + } + } + + break; + default: + break; + } + } + + return 0; +} + +int hci_board_init(void) +{ + /* FIXME: Wi-Fi Coexist, MP, Trace_Setting */ + + hci_read_efuse(); + if (!CHECK_SW(EFUSE_SW_BT_FW_LOG)) + { + set_reg_val(0x400000cc, BIT2 | BIT1 | BIT0, 6); + rtw_msleep_os(5); + set_reg_val(0x400000cc, BIT8, 1); + rtw_msleep_os(5); + } + + if (hci_parse_config()) + { + return -EIO; + } + + return 0; +} + +int hci_board_init_done(void) +{ + /* FIXME: MP */ + + return 0; +} + diff --git a/arch/arm/src/rtl8720c/amebaz_hci_board.h b/arch/arm/src/rtl8720c/amebaz_hci_board.h new file mode 100644 index 00000000000..96133870f69 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_hci_board.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_hci_board.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_AMEBA_HCI_BOARD_H +#define __INCLUDE_AMEBA_HCI_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define HCI_START_IQK +#define AMEBAZ_COMMAND_FRAGMENT_SIZE (252) +#define AMEBAZ_COMMAND_DONE (0) +#define AMEBAZ_COMMAND_VALID (1) +#define BT_DEFAUT_LMP_SUBVER 0x8710 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int hci_check_iqk(void); +int hci_start_iqk(void); +int hci_set_init_config_mac(FAR uint8_t *addr, uint8_t diffvalue); +int hci_get_baudrate(FAR uint32_t *bt_baudrate, + FAR uint32_t *uart_baudrate); +int hci_find_fw_patch(uint8_t chipid); +int hci_get_efuse_iqk_data(uint8_t *data); +int hci_board_init(void); +int hci_board_init_done(void); + +#endif /* __INCLUDE_AMEBA_FLASH_H */ + diff --git a/arch/arm/src/rtl8720c/amebaz_netdev.c b/arch/arm/src/rtl8720c/amebaz_netdev.c new file mode 100644 index 00000000000..43f30ebf4ce --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_netdev.c @@ -0,0 +1,432 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_netdev.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "amebaz_netdev.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define WDDELAY (1 * CLK_TCK / 2) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +static void amebaz_poll_work(FAR void *arg); +static void amebaz_netdev_notify_tx_done(FAR struct amebaz_dev_s *priv) +{ + work_queue(LPWORK, &priv->pollwork, amebaz_poll_work, priv, 0); +} + +static int amebaz_txpoll(FAR struct net_driver_s *dev) +{ + FAR struct amebaz_dev_s *priv = (FAR struct amebaz_dev_s *)dev->d_private; + if (priv->dev.d_len > 0) + { +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } + +#endif /* CONFIG_NET_IPv4 */ +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->dev); + } + +#endif /* CONFIG_NET_IPv6 */ + if (!devif_loopback(&priv->dev)) + { + net_lock(); + if (!priv->curr) + { + net_unlock(); + amebaz_netdev_notify_tx_done(priv); + return false; + } + + DEBUGASSERT(priv->curr->tail == priv->dev.d_buf); + skb_put(priv->curr, priv->dev.d_len); + rltk_wlan_send_skb(priv->devnum, priv->curr); + priv->dev.d_buf = NULL; + priv->curr = NULL; + net_unlock(); + NETDEV_TXPACKETS(&priv->dev); + amebaz_netdev_notify_tx_done(priv); + return true; + } + } + + return false; +} + +static int amebaz_transmit(FAR struct amebaz_dev_s *priv) +{ + struct sk_buff *skb; + skb = rltk_wlan_alloc_skb(priv->dev.d_len); + if (!skb) + { + NETDEV_TXERRORS(&priv->dev); + return -ENOMEM; + } + + NETDEV_TXPACKETS(&priv->dev); + memcpy(skb->tail, priv->dev.d_buf, priv->dev.d_len); + skb_put(skb, priv->dev.d_len); + rltk_wlan_send_skb(priv->devnum, skb); + NETDEV_TXDONE(&priv->dev); + return OK; +} + +static void amebaz_reply(FAR struct amebaz_dev_s *priv) +{ + if (priv->dev.d_len > 0) + { +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->dev.d_flags)) +#endif + { + arp_out(&priv->dev); + } + +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&priv->dev); + } + +#endif + amebaz_transmit(priv); + } +} + +void amebaz_netdev_notify_receive(FAR struct amebaz_dev_s *priv, + int index, unsigned int len) +{ + FAR struct net_driver_s *dev = &priv->dev; + FAR struct eth_hdr_s *hdr; + FAR struct sk_buff *skb; + FAR void *oldbuf; + skb = rltk_wlan_get_recv_skb(index); + if (skb == NULL) + { + return; + } + + if (!IFF_IS_UP(dev->d_flags)) + { + skb_pull(skb, len); + return; + } + + NETDEV_RXPACKETS(&priv->dev); + net_lock(); + oldbuf = priv->dev.d_buf; + hdr = (struct eth_hdr_s *)skb->data; + priv->dev.d_buf = (void *)skb->data; + priv->dev.d_len = len; +#ifdef CONFIG_NET_PKT + pkt_input(&priv->dev); +#endif + if (hdr->type == HTONS(TPID_8021QVLAN)) + { + uint8_t temp_buffer[12]; + memcpy(temp_buffer, skb->data, 12); + memcpy(skb->data + 4, temp_buffer, 12); + priv->dev.d_buf = skb->data = skb->data + 4; + priv->dev.d_len -= 4; + } + +#ifdef CONFIG_NET_IPv4 + if (hdr->type == HTONS(ETHTYPE_IP)) + { + NETDEV_RXIPV4(&priv->dev); + arp_ipin(&priv->dev); + ipv4_input(&priv->dev); + amebaz_reply(priv); + } + + else + { +#endif +#ifdef CONFIG_NET_IPv6 + if (hdr->type == HTONS(ETHTYPE_IP6)) + { + NETDEV_RXIPV6(&priv->dev); + ipv6_input(&priv->dev); + amebaz_reply(priv); + } + + else + { +#endif +#ifdef CONFIG_NET_ARP + if (hdr->type == htons(ETHTYPE_ARP)) + { + arp_arpin(&priv->dev); + NETDEV_RXARP(&priv->dev); + if (priv->dev.d_len > 0) + { + amebaz_transmit(priv); + } + } + + else +#endif + { + NETDEV_RXDROPPED(&priv->dev); + } +#ifdef CONFIG_NET_IPv6 + } +#endif +#ifdef CONFIG_NET_IPv4 + } +#endif + + skb_pull(skb, len); + priv->dev.d_buf = oldbuf; + net_unlock(); +} + +static void amebaz_poll_expiry(wdparm_t arg) +{ + FAR struct amebaz_dev_s *priv = (FAR struct amebaz_dev_s *)arg; + work_queue(LPWORK, &priv->pollwork, amebaz_poll_work, priv, 0); +} + +static void amebaz_txavail_work(FAR void *arg) +{ + FAR struct amebaz_dev_s *priv = (FAR struct amebaz_dev_s *)arg; + FAR struct net_driver_s *dev = &priv->dev; + net_lock(); + if (IFF_IS_UP(dev->d_flags)) + { + if (!priv->curr && rltk_wlan_check_isup(priv->devnum)) + { + priv->curr = rltk_wlan_alloc_skb(MAX_NETDEV_PKTSIZE); + if (priv->curr) + { + priv->dev.d_buf = priv->curr->tail; + priv->dev.d_len = 0; + } + } + + if (priv->dev.d_buf) + { + devif_timer(&priv->dev, 0, amebaz_txpoll); + } + } + + net_unlock(); +} + +static void amebaz_poll_work(FAR void *arg) +{ + FAR struct amebaz_dev_s *priv = (FAR struct amebaz_dev_s *)arg; + FAR struct net_driver_s *dev = &priv->dev; + net_lock(); + if (IFF_IS_UP(dev->d_flags)) + { + if (!priv->curr && rltk_wlan_check_isup(priv->devnum)) + { + priv->curr = rltk_wlan_alloc_skb(MAX_NETDEV_PKTSIZE); + if (priv->curr) + { + priv->dev.d_buf = priv->curr->tail; + priv->dev.d_len = 0; + } + } + + if (priv->dev.d_buf) + { + devif_timer(&priv->dev, WDDELAY, amebaz_txpoll); + } + } + + wd_start(&priv->txpoll, WDDELAY, amebaz_poll_expiry, (wdparm_t)priv); + net_unlock(); +} + +static int amebaz_txavail(FAR struct net_driver_s *dev) +{ + FAR struct amebaz_dev_s *priv = (FAR struct amebaz_dev_s *)dev->d_private; + if (work_available(&priv->pollwork)) + { + work_queue(LPWORK, &priv->pollwork, amebaz_txavail_work, priv, 0); + } + + return OK; +} + +int amebaz_ioctl(FAR struct net_driver_s *dev, int cmd, + unsigned long arg) +{ + FAR struct amebaz_dev_s *priv = (struct amebaz_dev_s *)dev->d_private; + int ret; + if (!IFF_IS_UP(dev->d_flags) || + (!rltk_wlan_running(priv->devnum) && cmd != SIOCSIWMODE)) + { + return -EINVAL; + } + + switch (cmd) + { + case SIOCSIWSCAN: + ret = amebaz_wl_start_scan(priv, (void *)arg); + break; + case SIOCGIWSCAN: + ret = amebaz_wl_get_scan_results(priv, (void *)arg); + break; + case SIOCSIWENCODEEXT: + ret = amebaz_wl_set_encode_ext(priv, (void *)arg); + break; + case SIOCGIWENCODEEXT: + ret = amebaz_wl_get_encode_ext(priv, (void *)arg); + break; + case SIOCSIWESSID: + ret = amebaz_wl_set_ssid(priv, (void *)arg); + break; + case SIOCSIWAP: + ret = amebaz_wl_set_bssid(priv, (void *)arg); + break; + case SIOCSIWMODE: + ret = amebaz_wl_set_mode(priv, (void *)arg); + break; + case SIOCSIWCOUNTRY: + ret = amebaz_wl_set_country(priv, (void *)arg); + break; + case SIOCGIWFREQ: + ret = amebaz_wl_get_freq(priv, (void *)arg); + break; + case SIOCSIWFREQ: + ret = amebaz_wl_set_freq(priv, (void *)arg); + break; + case SIOCGIWAP: + case SIOCGIWMODE: + case SIOCGIWESSID: + case SIOCGIWSENS: + case SIOCSIWAUTH: + case SIOCGIWAUTH: + case SIOCSIFHWADDR: + case SIOCGIFHWADDR: + case SIOCSIWRATE: + case SIOCGIWRATE: + case SIOCSIWTXPOW: + case SIOCGIWTXPOW: + ret = amebaz_wl_process_command(priv, cmd, (void *)arg); + break; + default: + wlwarn("ERROR: Unrecognized IOCTL command: %d\n", cmd); + ret = -ENOTTY; /* Special return value for this case */ + break; + } + + return ret; +} + +static int amebaz_ifup(FAR struct net_driver_s *dev) +{ + FAR struct amebaz_dev_s *priv = (FAR struct amebaz_dev_s *)dev->d_private; + if (!IFF_IS_UP(dev->d_flags)) + { + priv->mode = RTW_MODE_NONE; + priv->conn.status = AMEBAZ_STATUS_DISABLED; + wd_start(&priv->txpoll, WDDELAY, amebaz_poll_expiry, (wdparm_t)dev); + } + + return OK; +} + +static int amebaz_ifdown(FAR struct net_driver_s *dev) +{ + int ret = 0; + FAR struct amebaz_dev_s *priv = (FAR struct amebaz_dev_s *)dev->d_private; + irqstate_t flags; + if (priv->devnum == 0 && rltk_wlan_running(1)) + { + printf("must ifdown wlan 1 first\r\n"); + return ERROR; + } + + flags = enter_critical_section(); + if (IFF_IS_UP(dev->d_flags)) + { + if (priv->curr) + { + skb_put(priv->curr, 0); + rltk_wlan_send_skb(priv->devnum, priv->curr); + + priv->curr = NULL; + } + + wd_cancel(&priv->txpoll); + if (priv->devnum == 0) + { + rltk_wlan_deinit(); + } + + else if (priv->mode == RTW_MODE_STA_AP) + { + ret = rltk_set_mode_prehandle(RTW_MODE_STA_AP, + RTW_MODE_STA, "wlan0"); + rtw_msleep_os(50); + ret = rltk_set_mode_posthandle(RTW_MODE_STA_AP, + RTW_MODE_STA, "wlan0"); + while (rltk_wlan_running(1)) + { + rtw_msleep_os(50); + } + } + } + + leave_critical_section(flags); + return ret; +} + +int amebaz_netdev_register(FAR struct amebaz_dev_s *priv) +{ + struct net_driver_s *dev = &priv->dev; + dev->d_ifup = amebaz_ifup; + dev->d_ifdown = amebaz_ifdown; + dev->d_txavail = amebaz_txavail; +#ifdef CONFIG_NETDEV_IOCTL + dev->d_ioctl = amebaz_ioctl; +#endif + dev->d_private = priv; + return netdev_register(dev, NET_LL_IEEE80211); +} + diff --git a/arch/arm/src/rtl8720c/amebaz_netdev.h b/arch/arm/src/rtl8720c/amebaz_netdev.h new file mode 100644 index 00000000000..7aa45706035 --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_netdev.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_netdev.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_NETDEV_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_NETDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "amebaz_driver.h" +#include "amebaz_wlan.h" + +int amebaz_netdev_register(FAR struct amebaz_dev_s *priv); +void amebaz_netdev_notify_receive(FAR struct amebaz_dev_s *priv, + int index, unsigned int len); +#endif /* __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_NETDEV_H */ diff --git a/arch/arm/src/rtl8720c/amebaz_wlan.c b/arch/arm/src/rtl8720c/amebaz_wlan.c new file mode 100644 index 00000000000..8446a1c8c8a --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_wlan.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_wlan.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "amebaz_netdev.h" + +enum _WIFI_EVENT_INDICATE +{ + WIFI_EVENT_CONNECT = 0, + WIFI_EVENT_DISCONNECT = 1, + WIFI_EVENT_FOURWAY_HANDSHAKE_DONE = 2, + WIFI_EVENT_SCAN_RESULT_REPORT = 3, + WIFI_EVENT_SCAN_DONE = 4, + WIFI_EVENT_RECONNECTION_FAIL = 5, + WIFI_EVENT_SEND_ACTION_DONE = 6, + WIFI_EVENT_RX_MGNT = 7, + WIFI_EVENT_STA_ASSOC = 8, + WIFI_EVENT_STA_DISASSOC = 9, + WIFI_EVENT_STA_WPS_START = 10, + WIFI_EVENT_WPS_FINISH = 11, + WIFI_EVENT_EAPOL_START = 12, + WIFI_EVENT_EAPOL_RECVD = 13, + WIFI_EVENT_NO_NETWORK = 14, + WIFI_EVENT_BEACON_AFTER_DHCP = 15, + WIFI_EVENT_IP_CHANGED = 16, + WIFI_EVENT_ICV_ERROR = 17, + WIFI_EVENT_CHALLENGE_FAIL = 18, + WIFI_EVENT_STA_START = 19, + WIFI_EVENT_STA_STOP = 20, + WIFI_EVENT_AP_START = 21, + WIFI_EVENT_AP_STOP = 22, + WIFI_EVENT_STA_GOT_IP = 23, + WIFI_EVENT_STA_LOST_IP = 24, + WIFI_EVENT_MAX, +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void wifi_set_country_code(void) +{ + /* wifi_set_country(RTW_COUNTRY_US); */ +} + +void wifi_indication(unsigned long event, char *buf, int buf_len, int flags) +{ + if (event != WIFI_EVENT_BEACON_AFTER_DHCP) + { + syslog(1, "%s: %d, event: %x\n", __func__, __LINE__, event); + } +} + +void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, + char *extra) +{ + int index = 0; + if (cmd == IWEVCUSTOM) + { + amebaz_wl_connection_handler(index, wrqu, extra); + } + + else if (cmd == SIOCGIWAP) + { + amebaz_wl_connection_handler(index, wrqu, extra); + } + + else if (cmd == SIOCGIWSCAN) + { + amebaz_wl_scan_handler(index, wrqu, extra); + } + + else + { + syslog(1, "%s: %d, event: %x\n", __func__, __LINE__, cmd); + } +} + +void netif_post_sleep_processing(void) +{ +} + +int netif_is_valid_ip(int index, unsigned char *ip_dest) +{ + return true; +} + +unsigned char *rltk_wlan_get_ip(int index) +{ + return NULL; +} + +void netif_rx(int index, unsigned int len) +{ + amebaz_wl_notify_rx_handler(index, len); +} + +void rltk_wlan_set_netif_info(int index, void *dev, unsigned char *addr) +{ + amebaz_wl_netif_info_handler(index, dev, addr); +} + diff --git a/arch/arm/src/rtl8720c/amebaz_wlan.h b/arch/arm/src/rtl8720c/amebaz_wlan.h new file mode 100644 index 00000000000..57bc670e57c --- /dev/null +++ b/arch/arm/src/rtl8720c/amebaz_wlan.h @@ -0,0 +1,416 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/amebaz_wlan.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_WLAN_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_WLAN_H +#define WEP_ENABLED 0x0001 +#define TKIP_ENABLED 0x0002 +#define AES_ENABLED 0x0004 +#define WSEC_SWFLAG 0x0008 +#define AES_CMAC_ENABLED 0x0010 +#define SHARED_ENABLED 0x00008000 +#define WPA_SECURITY 0x00200000 +#define WPA2_SECURITY 0x00400000 +#define WPS_ENABLED 0x10000000 +#define PSCAN_ENABLE 0x01 /* enable for partial channel scan */ +#define PSCAN_FAST_SURVEY 0x02 /* set to select scan time to FAST_SURVEY_TO, otherwise SURVEY_TO */ +#define PSCAN_SIMPLE_CONFIG 0x04 /* set to select scan time to FAST_SURVEY_TO and resend probe request */ + +enum +{ + /* CHANNEL PLAN */ + + RTW_COUNTRY_WORLD1, /* 0x20 */ + RTW_COUNTRY_ETSI1, /* 0x21 */ + RTW_COUNTRY_FCC1, /* 0x22 */ + RTW_COUNTRY_MKK1, /* 0x23 */ + RTW_COUNTRY_ETSI2, /* 0x24 */ + RTW_COUNTRY_FCC2, /* 0x2a */ + RTW_COUNTRY_WORLD2, /* 0x47 */ + RTW_COUNTRY_MKK2, /* 0x58 */ + RTW_COUNTRY_GLOBAL, /* 0x41 */ + + /* SPECIAL */ + + RTW_COUNTRY_WORLD, /* WORLD1 */ + RTW_COUNTRY_EU, /* ETSI1 */ + + /* JAPANESE */ + + RTW_COUNTRY_JP, /* MKK1 */ + + /* FCC , 19 countries */ + + RTW_COUNTRY_AS, /* FCC2 */ + RTW_COUNTRY_BM, + RTW_COUNTRY_CA, + RTW_COUNTRY_DM, + RTW_COUNTRY_DO, + RTW_COUNTRY_FM, + RTW_COUNTRY_GD, + RTW_COUNTRY_GT, + RTW_COUNTRY_GU, + RTW_COUNTRY_HT, + RTW_COUNTRY_MH, + RTW_COUNTRY_MP, + RTW_COUNTRY_NI, + RTW_COUNTRY_PA, + RTW_COUNTRY_PR, + RTW_COUNTRY_PW, + RTW_COUNTRY_TW, + RTW_COUNTRY_US, + RTW_COUNTRY_VI, + + /* others, ETSI */ + + RTW_COUNTRY_AD, /* ETSI1 */ + RTW_COUNTRY_AE, + RTW_COUNTRY_AF, + RTW_COUNTRY_AI, + RTW_COUNTRY_AL, + RTW_COUNTRY_AM, + RTW_COUNTRY_AN, + RTW_COUNTRY_AR, + RTW_COUNTRY_AT, + RTW_COUNTRY_AU, + RTW_COUNTRY_AW, + RTW_COUNTRY_AZ, + RTW_COUNTRY_BA, + RTW_COUNTRY_BB, + RTW_COUNTRY_BD, + RTW_COUNTRY_BE, + RTW_COUNTRY_BF, + RTW_COUNTRY_BG, + RTW_COUNTRY_BH, + RTW_COUNTRY_BL, + RTW_COUNTRY_BN, + RTW_COUNTRY_BO, + RTW_COUNTRY_BR, + RTW_COUNTRY_BS, + RTW_COUNTRY_BT, + RTW_COUNTRY_BY, + RTW_COUNTRY_BZ, + RTW_COUNTRY_CF, + RTW_COUNTRY_CH, + RTW_COUNTRY_CI, + RTW_COUNTRY_CL, + RTW_COUNTRY_CN, + RTW_COUNTRY_CO, + RTW_COUNTRY_CR, + RTW_COUNTRY_CX, + RTW_COUNTRY_CY, + RTW_COUNTRY_CZ, + RTW_COUNTRY_DE, + RTW_COUNTRY_DK, + RTW_COUNTRY_DZ, + RTW_COUNTRY_EC, + RTW_COUNTRY_EE, + RTW_COUNTRY_EG, + RTW_COUNTRY_ES, + RTW_COUNTRY_ET, + RTW_COUNTRY_FI, + RTW_COUNTRY_FR, + RTW_COUNTRY_GB, + RTW_COUNTRY_GE, + RTW_COUNTRY_GF, + RTW_COUNTRY_GH, + RTW_COUNTRY_GL, + RTW_COUNTRY_GP, + RTW_COUNTRY_GR, + RTW_COUNTRY_GY, + RTW_COUNTRY_HK, + RTW_COUNTRY_HN, + RTW_COUNTRY_HR, + RTW_COUNTRY_HU, + RTW_COUNTRY_ID, + RTW_COUNTRY_IE, + RTW_COUNTRY_IL, + RTW_COUNTRY_IN, + RTW_COUNTRY_IQ, + RTW_COUNTRY_IR, + RTW_COUNTRY_IS, + RTW_COUNTRY_IT, + RTW_COUNTRY_JM, + RTW_COUNTRY_JO, + RTW_COUNTRY_KE, + RTW_COUNTRY_KH, + RTW_COUNTRY_KN, + RTW_COUNTRY_KP, + RTW_COUNTRY_KR, + RTW_COUNTRY_KW, + RTW_COUNTRY_KY, + RTW_COUNTRY_KZ, + RTW_COUNTRY_LA, + RTW_COUNTRY_LB, + RTW_COUNTRY_LC, + RTW_COUNTRY_LI, + RTW_COUNTRY_LK, + RTW_COUNTRY_LR, + RTW_COUNTRY_LS, + RTW_COUNTRY_LT, + RTW_COUNTRY_LU, + RTW_COUNTRY_LV, + RTW_COUNTRY_MA, + RTW_COUNTRY_MC, + RTW_COUNTRY_MD, + RTW_COUNTRY_ME, + RTW_COUNTRY_MF, + RTW_COUNTRY_MK, + RTW_COUNTRY_MN, + RTW_COUNTRY_MO, + RTW_COUNTRY_MQ, + RTW_COUNTRY_MR, + RTW_COUNTRY_MT, + RTW_COUNTRY_MU, + RTW_COUNTRY_MV, + RTW_COUNTRY_MW, + RTW_COUNTRY_MX, + RTW_COUNTRY_MY, + RTW_COUNTRY_NG, + RTW_COUNTRY_NL, + RTW_COUNTRY_NO, + RTW_COUNTRY_NP, + RTW_COUNTRY_NZ, + RTW_COUNTRY_OM, + RTW_COUNTRY_PE, + RTW_COUNTRY_PF, + RTW_COUNTRY_PG, + RTW_COUNTRY_PH, + RTW_COUNTRY_PK, + RTW_COUNTRY_PL, + RTW_COUNTRY_PM, + RTW_COUNTRY_PT, + RTW_COUNTRY_PY, + RTW_COUNTRY_QA, + RTW_COUNTRY_RS, + RTW_COUNTRY_RU, + RTW_COUNTRY_RW, + RTW_COUNTRY_SA, + RTW_COUNTRY_SE, + RTW_COUNTRY_SG, + RTW_COUNTRY_SI, + RTW_COUNTRY_SK, + RTW_COUNTRY_SN, + RTW_COUNTRY_SR, + RTW_COUNTRY_SV, + RTW_COUNTRY_SY, + RTW_COUNTRY_TC, + RTW_COUNTRY_TD, + RTW_COUNTRY_TG, + RTW_COUNTRY_TH, + RTW_COUNTRY_TN, + RTW_COUNTRY_TR, + RTW_COUNTRY_TT, + RTW_COUNTRY_TZ, + RTW_COUNTRY_UA, + RTW_COUNTRY_UG, + RTW_COUNTRY_UY, + RTW_COUNTRY_UZ, + RTW_COUNTRY_VC, + RTW_COUNTRY_VE, + RTW_COUNTRY_VN, + RTW_COUNTRY_VU, + RTW_COUNTRY_WF, + RTW_COUNTRY_WS, + RTW_COUNTRY_YE, + RTW_COUNTRY_YT, + RTW_COUNTRY_ZA, + RTW_COUNTRY_ZW, + RTW_COUNTRY_MAX +}; + +enum +{ + RTW_BSS_TYPE_INFRASTRUCTURE = 0, /* *< Denotes infrastructure network */ + RTW_BSS_TYPE_ADHOC = 1, /* *< Denotes an 802.11 ad-hoc IBSS network */ + RTW_BSS_TYPE_ANY = 2, /* *< Denotes either infrastructure or ad-hoc network */ + RTW_BSS_TYPE_UNKNOWN = -1 /* *< May be returned by scan function if BSS type is unknown. Do not pass this to the Join function */ +}; + +enum +{ + RTW_SECURITY_OPEN = 0, /* *< Open security */ + RTW_SECURITY_WEP_PSK = WEP_ENABLED, /* *< WEP Security with open authentication */ + RTW_SECURITY_WEP_SHARED = (WEP_ENABLED | SHARED_ENABLED), /* *< WEP Security with shared authentication */ + RTW_SECURITY_WPA_TKIP_PSK = (WPA_SECURITY | TKIP_ENABLED), /* *< WPA Security with TKIP */ + RTW_SECURITY_WPA_AES_PSK = (WPA_SECURITY | AES_ENABLED), /* *< WPA Security with AES */ + RTW_SECURITY_WPA2_AES_PSK = (WPA2_SECURITY | AES_ENABLED), /* *< WPA2 Security with AES */ + RTW_SECURITY_WPA2_TKIP_PSK = (WPA2_SECURITY | TKIP_ENABLED), /* *< WPA2 Security with TKIP */ + RTW_SECURITY_WPA2_MIXED_PSK = (WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED), /* *< WPA2 Security with AES & TKIP */ + RTW_SECURITY_WPA_WPA2_MIXED = (WPA_SECURITY | WPA2_SECURITY), /* *< WPA/WPA2 Security */ + RTW_SECURITY_WPA2_AES_CMAC = (WPA2_SECURITY | AES_CMAC_ENABLED), /* *< WPA2 Security with AES and Management Frame Protection */ + RTW_SECURITY_WPS_OPEN = WPS_ENABLED, /* *< WPS with open security */ + RTW_SECURITY_WPS_SECURE = (WPS_ENABLED | AES_ENABLED), /* *< WPS with AES security */ + RTW_SECURITY_UNKNOWN = -1, /* *< May be returned by scan function if security is unknown. Do not pass this to the join function! */ + RTW_SECURITY_FORCE_32_BIT = 0x7fffffff /* *< Exists only to force rtw_security_t type to 32 bits */ +}; + +enum +{ + RTW_WPS_TYPE_DEFAULT = 0x0000, + RTW_WPS_TYPE_USER_SPECIFIED = 0x0001, + RTW_WPS_TYPE_MACHINE_SPECIFIED = 0x0002, + RTW_WPS_TYPE_REKEY = 0x0003, + RTW_WPS_TYPE_PUSHBUTTON = 0x0004, + RTW_WPS_TYPE_REGISTRAR_SPECIFIED = 0x0005, + RTW_WPS_TYPE_NONE = 0x0006, + RTW_WPS_TYPE_WSC = 0x0007 +}; + +enum +{ + RTW_802_11_BAND_5GHZ = 0, /* *< Denotes 5GHz radio band */ + RTW_802_11_BAND_2_4GHZ = 1 /* *< Denotes 2.4GHz radio band */ +}; + +begin_packed_struct struct rtw_ssid +{ + unsigned char len; /* *< SSID length */ + unsigned char val[33]; /* *< SSID name (AP name) */ +} end_packed_struct; + +begin_packed_struct struct rtw_mac +{ + unsigned char octet[6]; /* *< Unique 6-byte MAC address */ +} end_packed_struct; + +typedef unsigned long rtw_bss_type_t; +typedef unsigned long rtw_security_t; +typedef unsigned long rtw_wps_type_t; +typedef unsigned long rtw_802_11_band_t; +typedef struct rtw_ssid rtw_ssid_t; +typedef struct rtw_mac rtw_mac_t; +typedef struct rtw_scan_result rtw_scan_result_t; +typedef struct rtw_network_info rtw_network_info_t; +typedef struct rtw_scan_ap_result rtw_scan_ap_result_t; + +begin_packed_struct struct rtw_network_info +{ + rtw_ssid_t ssid; + rtw_mac_t bssid; + rtw_security_t security_type; + unsigned char *password; + int password_len; + int key_id; +} end_packed_struct; + +begin_packed_struct struct rtw_scan_result +{ + rtw_ssid_t SSID; /* *< Service Set Identification (i.e. Name of Access Point) */ + rtw_mac_t BSSID; /* *< Basic Service Set Identification (i.e. MAC address of Access Point) */ + signed short signal_strength; /* *< Receive Signal Strength Indication in dBm. <-90=Very poor, >-30=Excellent */ + rtw_bss_type_t bss_type; /* *< Network type */ + rtw_security_t security; /* *< Security type */ + rtw_wps_type_t wps_type; /* *< WPS type */ + unsigned int channel; /* *< Radio channel that the AP beacon was received on */ + rtw_802_11_band_t band; /* *< Radio band */ +} end_packed_struct; + +begin_packed_struct struct rtw_scan_ap_result +{ + char len; + uint8_t BSSID[IFHWADDRLEN]; + int signal_strength; + char security; + char wps_type; + char channel; + char SSID[0]; +} end_packed_struct; + +enum +{ + RTW_MODE_NONE = 0, + RTW_MODE_STA, + RTW_MODE_AP, + RTW_MODE_STA_AP, + RTW_MODE_PROMISC, + RTW_MODE_P2P +}; + +struct sk_buff_head +{ + struct list_head *next; + struct list_head *prev; + unsigned int qlen; +}; + +struct sk_buff +{ + struct sk_buff *next; + struct sk_buff *prev; + struct sk_buff_head *list; + unsigned char *head; + unsigned char *data; + unsigned char *tail; + unsigned char *end; + void *dev; + unsigned int len; + int dyalloc_flag; +}; + +unsigned char *skb_put(struct sk_buff *skb, + unsigned int len); +unsigned char *skb_pull(struct sk_buff *skb, + unsigned int len); +int rltk_wlan_init(int index, unsigned long mode); +void rltk_wlan_deinit(void); +void rltk_wlan_deinit_fastly(void); +int rltk_wlan_start(int index); +void rltk_wlan_statistic(unsigned char index); +unsigned char rltk_wlan_running(unsigned char index); +int rltk_wlan_control(unsigned long cmd, void *data); +int rltk_wlan_handshake_done(void); +int rltk_wlan_rf_on(void); +int rltk_wlan_rf_off(void); +int rltk_wlan_check_bus(void); +int rltk_wlan_wireless_mode(unsigned char mode); +int rltk_wlan_get_wireless_mode(unsigned char *pmode); +int rltk_wlan_set_wps_phase(unsigned char is_trigger_wps); +int rtw_ps_enable(int enable); +int rltk_wlan_is_connected_to_ap(void); +int rltk_set_mode_prehandle(unsigned char curr_mode, + unsigned char next_mode, + const char *ifname); +int rltk_set_mode_posthandle(unsigned char curr_mode, + unsigned char next_mode, + const char *ifname); +int rltk_remove_softap_in_concurrent_mode(const char *ifname); +unsigned char rltk_wlan_check_isup(int index); +void rltk_wlan_tx_inc(int index); +void rltk_wlan_tx_dec(int index); +struct sk_buff *rltk_wlan_get_recv_skb(int index); +struct sk_buff *rltk_wlan_alloc_skb(unsigned int len); +void rltk_wlan_set_netif_info(int index_wlan, void *dev, + unsigned char *addr); +void rltk_wlan_send_skb(int index, struct sk_buff *skb); +unsigned char *rltk_wlan_get_ip(int index); +int netif_is_valid_ip(int index, unsigned char *ip_dest); +unsigned char *netif_get_hwaddr(int index); +void netif_rx(int index, unsigned int len); +void netif_post_sleep_processing(void); +void netif_pre_sleep_processing(void); + +#endif /* __DRIVERS_WIRELESS_IEEE80211_AMEBAZ_AMEBAZ_WLAN_H */ + diff --git a/arch/arm/src/rtl8720c/chip.h b/arch/arm/src/rtl8720c/chip.h new file mode 100644 index 00000000000..072d37d4631 --- /dev/null +++ b/arch/arm/src/rtl8720c/chip.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/chip.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_AMEBA_CHIP_H +#define __ARCH_ARM_SRC_AMEBA_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +# include +# include +#endif +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif +/* If the common ARMv7-M vector handling logic is used, + * then it expects the following + * definition in this file that provides the number of + * supported external interrupts. + */ +#define ARMV8M_PERIPHERAL_INTERRUPTS (CONFIG_AMEBA_NR_IRQS - 16) + +#endif /* __ARCH_ARM_SRC_AMEBA_CHIP_H */ diff --git a/arch/arm/src/rtl8720c/include/chip.h b/arch/arm/src/rtl8720c/include/chip.h new file mode 100644 index 00000000000..ef9a8249dae --- /dev/null +++ b/arch/arm/src/rtl8720c/include/chip.h @@ -0,0 +1,20 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/include/chip.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + diff --git a/arch/arm/src/rtl8720c/include/irq.h b/arch/arm/src/rtl8720c/include/irq.h new file mode 100644 index 00000000000..cd0992457ee --- /dev/null +++ b/arch/arm/src/rtl8720c/include/irq.h @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/arm/src/rtl8720c/include/irq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, + * only indirectly through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_SONG_IRQ_H +#define __ARCH_ARM_INCLUDE_SONG_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Exception/interrupt vector numbers */ + +/* Vector 0: Reset stack pointer value */ + +/* Vector 1: Reset */ + +#define NVIC_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ + +#define NVIC_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ + +#define NVIC_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */ + +#define NVIC_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */ + +#define NVIC_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */ + +/* Vectors 7-10: Reserved */ + +#define NVIC_IRQ_SVCALL (11) /* Vector 11: SVC call */ + +#define NVIC_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */ + +/* Vector 13: Reserved */ + +#define NVIC_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ + +#define NVIC_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16). These definitions are chip-specific */ + +#define NVIC_IRQ_FIRST (16) /* Vector number of the first interrupt */ + +#define NVIC_IRQ_WLAN (28) /* Vector 28: Wireless Lan */ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the INTC. This does, however, waste several + * words of memory in the IRQ to handle mapping tables. + */ + +#define NR_IRQS CONFIG_AMEBA_NR_IRQS + +/* NVIC priority levels */ + +#define NVIC_SYSH_PRIORITY_MIN 0xff /* All bits set in minimum priority */ + +#define NVIC_SYSH_PRIORITY_DEFAULT 0x40 /* Midpoint is the default */ + +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ + +#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Three bits priority used, bits[7-6] as group */ + +#define NVIC_SYSH_PRIORITY_SUBSTEP 0x20 /* Three bits priority used, bit[5] as sub */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN + +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_SONG_IRQ_H */ +